[U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 SoC and K2HK EVM

This patch series add support for keystone2 SoC and K2HK EVM
Change history: v2 - Review comments incorporated. Following are major comments addressed - split network driver to navigator driver + ethernet driver - replaced register base + offset implemenation with struct based register access implementation - Added Readme for NAND no subpage write option - re-use code for davinci i2c driver on keystone2 with updates - clock-k2hk.c merged to clock.c - currently keeping board specific getclk() command. See the thread for the rational. - Added update to davinci spi driver to re-use on keystone
v1 - added separate patch for sorting tools/Makefile entries - reworked gpimage patch to allow more re-use across omapimage/gpimage - dropped patch related to ubifs file size - added keystone SoC and K2HK EVM support
v0 - preparatory patch for keystone
Murali Karicheri (5): tools: sort the entries in Makefile tools: mkimage: add support for gpimage format NAND: DaVinci: allow forced disable of subpage writes i2c, davinci: move i2c_defs.h to the drivers/i2c directory k2hk-evm: add configuration for spi1 and spi2 support
Rex Chang (1): spi: davinci: add support for multiple bus and chip select
Vitaly Andrianov (6): fdt: call ft_board_setup_ex() at the end of image_setup_libfdt() arm: add support for arch timer i2c, davinci: add support for multiple i2c buses k2hk: add support for k2hk SOC and EVM keystone2: add keystone multicore navigator driver keystone2: net: add keystone ethernet driver
Makefile | 19 + README | 5 + arch/arm/cpu/armv7/keystone/Makefile | 18 + arch/arm/cpu/armv7/keystone/aemif.c | 71 ++ arch/arm/cpu/armv7/keystone/clock.c | 313 +++++++ arch/arm/cpu/armv7/keystone/cmd_clock.c | 124 +++ arch/arm/cpu/armv7/keystone/cmd_mon.c | 131 +++ arch/arm/cpu/armv7/keystone/config.mk | 15 + arch/arm/cpu/armv7/keystone/ddr3.c | 69 ++ arch/arm/cpu/armv7/keystone/init.c | 56 ++ arch/arm/cpu/armv7/keystone/keystone_nav.c | 376 +++++++++ arch/arm/cpu/armv7/keystone/msmc.c | 68 ++ arch/arm/cpu/armv7/keystone/psc.c | 238 ++++++ arch/arm/cpu/armv7/keystone/spl.c | 45 + arch/arm/include/asm/arch-davinci/i2c_defs.h | 71 +- arch/arm/include/asm/arch-keystone/clock-k2hk.h | 109 +++ arch/arm/include/asm/arch-keystone/clock.h | 17 + arch/arm/include/asm/arch-keystone/clock_defs.h | 121 +++ arch/arm/include/asm/arch-keystone/emac_defs.h | 250 ++++++ arch/arm/include/asm/arch-keystone/emif_defs.h | 73 ++ arch/arm/include/asm/arch-keystone/hardware-k2hk.h | 145 ++++ arch/arm/include/asm/arch-keystone/hardware.h | 175 ++++ arch/arm/include/asm/arch-keystone/i2c_defs.h | 17 + arch/arm/include/asm/arch-keystone/keystone_nav.h | 193 +++++ arch/arm/include/asm/arch-keystone/nand_defs.h | 25 + arch/arm/include/asm/arch-keystone/psc_defs.h | 90 ++ arch/arm/include/asm/arch-keystone/spl.h | 12 + arch/arm/lib/Makefile | 1 + arch/arm/lib/arch_timer.c | 58 ++ board/ti/k2hk_evm/Makefile | 9 + board/ti/k2hk_evm/README | 56 ++ board/ti/k2hk_evm/board.c | 301 +++++++ board/ti/k2hk_evm/ddr3.c | 269 ++++++ boards.cfg | 1 + common/image-fdt.c | 5 + common/image.c | 1 + drivers/i2c/davinci_i2c.c | 345 ++++---- drivers/i2c/davinci_i2c.h | 78 ++ drivers/mtd/nand/davinci_nand.c | 3 + drivers/net/Makefile | 1 + drivers/net/keystone_net.c | 859 ++++++++++++++++++++ drivers/serial/ns16550.c | 8 + drivers/spi/davinci_spi.c | 62 +- drivers/spi/davinci_spi.h | 33 + include/configs/k2hk_evm.h | 268 ++++++ include/fdt_support.h | 1 + include/image.h | 1 + tools/Makefile | 20 +- tools/gpheader.h | 40 + tools/gpimage-common.c | 80 ++ tools/gpimage.c | 77 ++ tools/imagetool.c | 2 + tools/imagetool.h | 1 + tools/omapimage.c | 104 +-- tools/omapimage.h | 5 - 55 files changed, 5222 insertions(+), 313 deletions(-) create mode 100644 arch/arm/cpu/armv7/keystone/Makefile create mode 100644 arch/arm/cpu/armv7/keystone/aemif.c create mode 100644 arch/arm/cpu/armv7/keystone/clock.c create mode 100644 arch/arm/cpu/armv7/keystone/cmd_clock.c create mode 100644 arch/arm/cpu/armv7/keystone/cmd_mon.c create mode 100644 arch/arm/cpu/armv7/keystone/config.mk create mode 100644 arch/arm/cpu/armv7/keystone/ddr3.c create mode 100644 arch/arm/cpu/armv7/keystone/init.c create mode 100644 arch/arm/cpu/armv7/keystone/keystone_nav.c create mode 100644 arch/arm/cpu/armv7/keystone/msmc.c create mode 100644 arch/arm/cpu/armv7/keystone/psc.c create mode 100644 arch/arm/cpu/armv7/keystone/spl.c create mode 100644 arch/arm/include/asm/arch-keystone/clock-k2hk.h create mode 100644 arch/arm/include/asm/arch-keystone/clock.h create mode 100644 arch/arm/include/asm/arch-keystone/clock_defs.h create mode 100644 arch/arm/include/asm/arch-keystone/emac_defs.h create mode 100644 arch/arm/include/asm/arch-keystone/emif_defs.h create mode 100644 arch/arm/include/asm/arch-keystone/hardware-k2hk.h create mode 100644 arch/arm/include/asm/arch-keystone/hardware.h create mode 100644 arch/arm/include/asm/arch-keystone/i2c_defs.h create mode 100644 arch/arm/include/asm/arch-keystone/keystone_nav.h create mode 100644 arch/arm/include/asm/arch-keystone/nand_defs.h create mode 100644 arch/arm/include/asm/arch-keystone/psc_defs.h create mode 100644 arch/arm/include/asm/arch-keystone/spl.h create mode 100644 arch/arm/lib/arch_timer.c create mode 100644 board/ti/k2hk_evm/Makefile create mode 100644 board/ti/k2hk_evm/README create mode 100644 board/ti/k2hk_evm/board.c create mode 100644 board/ti/k2hk_evm/ddr3.c create mode 100644 drivers/i2c/davinci_i2c.h create mode 100644 drivers/net/keystone_net.c create mode 100644 include/configs/k2hk_evm.h create mode 100644 tools/gpheader.h create mode 100644 tools/gpimage-common.c create mode 100644 tools/gpimage.c

From: Vitaly Andrianov vitalya@ti.com
The keystone2 SOC requires to fix all 32 bit aliased addresses to their 36 physical format. This has to happen after all fdt nodes are added or modified.
Signed-off-by: Vitaly Andrianov vitalya@ti.com --- - no update since v1 common/image-fdt.c | 5 +++++ include/fdt_support.h | 1 + 2 files changed, 6 insertions(+)
diff --git a/common/image-fdt.c b/common/image-fdt.c index 6f9ce7d..ee4dd6f 100644 --- a/common/image-fdt.c +++ b/common/image-fdt.c @@ -487,5 +487,10 @@ int image_setup_libfdt(bootm_headers_t *images, void *blob, if (!ft_verify_fdt(blob)) return -1;
+#ifdef CONFIG_SOC_K2HK + if (IMAAGE_OF_BOARD_SETUP) + ft_board_setup_ex(blob, gd->bd); +#endif + return 0; } diff --git a/include/fdt_support.h b/include/fdt_support.h index 9871e2f..4c1416d 100644 --- a/include/fdt_support.h +++ b/include/fdt_support.h @@ -63,6 +63,7 @@ int fdt_pci_dma_ranges(void *blob, int phb_off, struct pci_controller *hose); #endif
void ft_board_setup(void *blob, bd_t *bd); +void ft_board_setup_ex(void *blob, bd_t *bd); void ft_cpu_setup(void *blob, bd_t *bd); void ft_pci_setup(void *blob, bd_t *bd);

On Thu, Feb 20, 2014 at 12:55:03PM -0500, Murali Karicheri wrote:
From: Vitaly Andrianov vitalya@ti.com
The keystone2 SOC requires to fix all 32 bit aliased addresses to their 36 physical format. This has to happen after all fdt nodes are added or modified.
Signed-off-by: Vitaly Andrianov vitalya@ti.com
Acked-by: Tom Rini trini@ti.com

The NOPED_OBJ_FILES, dumpimage and mkimage object file entries are to be kept sorted. This patch fix this issue.
Signed-off-by: Murali Karicheri m-karicheri2@ti.com --- - No update since v1 tools/Makefile | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/tools/Makefile b/tools/Makefile index 328cea3..3c719b3 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -77,10 +77,10 @@ NOPED_OBJ_FILES-y += aisimage.o NOPED_OBJ_FILES-y += default_image.o NOPED_OBJ_FILES-y += dumpimage.o NOPED_OBJ_FILES-y += fit_image.o +NOPED_OBJ_FILES-y += imagetool.o NOPED_OBJ_FILES-y += image-host.o NOPED_OBJ_FILES-y += imximage.o NOPED_OBJ_FILES-y += kwbimage.o -NOPED_OBJ_FILES-y += imagetool.o NOPED_OBJ_FILES-y += mkenvimage.o NOPED_OBJ_FILES-y += mkimage.o NOPED_OBJ_FILES-y += mxsimage.o @@ -88,8 +88,8 @@ NOPED_OBJ_FILES-y += omapimage.o NOPED_OBJ_FILES-y += os_support.o NOPED_OBJ_FILES-y += pblimage.o NOPED_OBJ_FILES-y += proftool.o -NOPED_OBJ_FILES-y += ublimage.o NOPED_OBJ_FILES-y += relocate-rela.o +NOPED_OBJ_FILES-y += ublimage.o OBJ_FILES-$(CONFIG_BUILD_ENVCRC) += envcrc.o OBJ_FILES-$(CONFIG_CMD_LOADS) += img2srec.o OBJ_FILES-$(CONFIG_CMD_NET) += gen_eth_addr.o @@ -209,14 +209,14 @@ $(obj)dumpimage$(SFX): $(obj)aisimage.o \ $(FIT_SIG_OBJS) \ $(obj)crc32.o \ $(obj)default_image.o \ + $(obj)dumpimage.o \ $(obj)fit_image.o \ - $(obj)image-fit.o \ $(obj)image.o \ - $(obj)image-host.o \ $(obj)imagetool.o \ + $(obj)image-fit.o \ + $(obj)image-host.o \ $(obj)imximage.o \ $(obj)kwbimage.o \ - $(obj)dumpimage.o \ $(obj)md5.o \ $(obj)mxsimage.o \ $(obj)omapimage.o \ @@ -239,10 +239,10 @@ $(obj)mkimage$(SFX): $(obj)aisimage.o \ $(obj)crc32.o \ $(obj)default_image.o \ $(obj)fit_image.o \ - $(obj)image-fit.o \ - $(obj)image-host.o \ $(obj)image.o \ $(obj)imagetool.o \ + $(obj)image-host.o \ + $(obj)image-fit.o \ $(obj)imximage.o \ $(obj)kwbimage.o \ $(obj)md5.o \

On Thu, Feb 20, 2014 at 12:55:04PM -0500, Murali Karicheri wrote:
The NOPED_OBJ_FILES, dumpimage and mkimage object file entries are to be kept sorted. This patch fix this issue.
Signed-off-by: Murali Karicheri m-karicheri2@ti.com
Acked-by: Tom Rini trini@ti.com

This patch add support for gpimage format as a preparatory patch for porting u-boot for keystone2 devices and is based on omapimage format. It re-uses gph header to store the size and loadaddr as done in omapimage.c
Signed-off-by: Vitaly Andrianov vitalya@ti.com Signed-off-by: Murali Karicheri m-karicheri2@ti.com --- - No update since v1 common/image.c | 1 + include/image.h | 1 + tools/Makefile | 6 +++ tools/gpheader.h | 40 +++++++++++++++++++ tools/gpimage-common.c | 80 +++++++++++++++++++++++++++++++++++++ tools/gpimage.c | 77 +++++++++++++++++++++++++++++++++++ tools/imagetool.c | 2 + tools/imagetool.h | 1 + tools/omapimage.c | 104 ++++++++---------------------------------------- tools/omapimage.h | 5 --- 10 files changed, 224 insertions(+), 93 deletions(-) create mode 100644 tools/gpheader.h create mode 100644 tools/gpimage-common.c create mode 100644 tools/gpimage.c
diff --git a/common/image.c b/common/image.c index ae95c3f..cb5c656 100644 --- a/common/image.c +++ b/common/image.c @@ -124,6 +124,7 @@ static const table_entry_t uimage_type[] = { { IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image", }, { IH_TYPE_FIRMWARE, "firmware", "Firmware", }, { IH_TYPE_FLATDT, "flat_dt", "Flat Device Tree", }, + { IH_TYPE_GPIMAGE, "gpimage", "TI Keystone SPL Image",}, { IH_TYPE_KERNEL, "kernel", "Kernel Image", }, { IH_TYPE_KERNEL_NOLOAD, "kernel_noload", "Kernel Image (no loading done)", }, { IH_TYPE_KWBIMAGE, "kwbimage", "Kirkwood Boot Image",}, diff --git a/include/image.h b/include/image.h index 7de2bb2..0a3d346 100644 --- a/include/image.h +++ b/include/image.h @@ -214,6 +214,7 @@ struct lmb; #define IH_TYPE_KERNEL_NOLOAD 14 /* OS Kernel Image, can run from any load address */ #define IH_TYPE_PBLIMAGE 15 /* Freescale PBL Boot Image */ #define IH_TYPE_MXSIMAGE 16 /* Freescale MXSBoot Image */ +#define IH_TYPE_GPIMAGE 17 /* TI Keystone GPHeader Image */
/* * Compression Types diff --git a/tools/Makefile b/tools/Makefile index 3c719b3..421aba5 100644 --- a/tools/Makefile +++ b/tools/Makefile @@ -77,6 +77,8 @@ NOPED_OBJ_FILES-y += aisimage.o NOPED_OBJ_FILES-y += default_image.o NOPED_OBJ_FILES-y += dumpimage.o NOPED_OBJ_FILES-y += fit_image.o +NOPED_OBJ_FILES-y += gpimage.o +NOPED_OBJ_FILES-y += gpimage-common.o NOPED_OBJ_FILES-y += imagetool.o NOPED_OBJ_FILES-y += image-host.o NOPED_OBJ_FILES-y += imximage.o @@ -211,6 +213,8 @@ $(obj)dumpimage$(SFX): $(obj)aisimage.o \ $(obj)default_image.o \ $(obj)dumpimage.o \ $(obj)fit_image.o \ + $(obj)gpimage.o \ + $(obj)gpimage-common.o \ $(obj)image.o \ $(obj)imagetool.o \ $(obj)image-fit.o \ @@ -239,6 +243,8 @@ $(obj)mkimage$(SFX): $(obj)aisimage.o \ $(obj)crc32.o \ $(obj)default_image.o \ $(obj)fit_image.o \ + $(obj)gpimage.o \ + $(obj)gpimage-common.o \ $(obj)image.o \ $(obj)imagetool.o \ $(obj)image-host.o \ diff --git a/tools/gpheader.h b/tools/gpheader.h new file mode 100644 index 0000000..63a28a2 --- /dev/null +++ b/tools/gpheader.h @@ -0,0 +1,40 @@ +/* + * (C) Copyright 2014 + * Texas Instruments Incorporated + * Refactored common functions in to gpimage-common.c. Include this common + * header file + * + * (C) Copyright 2010 + * Linaro LTD, www.linaro.org + * Author: John Rigby john.rigby@linaro.org + * Based on TI's signGP.c + * + * (C) Copyright 2009 + * Stefano Babic, DENX Software Engineering, sbabic@denx.de. + * + * (C) Copyright 2008 + * Marvell Semiconductor <www.marvell.com> + * Written-by: Prafulla Wadaskar prafulla@marvell.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _GPIMAGE_H_ +#define _GPIMAGE_H_ + +/* common headers for gpimage and omapimage formats */ +struct gp_header { + uint32_t size; + uint32_t load_addr; +}; +#define GPIMAGE_HDR_SIZE (sizeof(struct gp_header)) + +/* common functions across gpimage and omapimage handlers */ +int valid_gph_size(uint32_t size); +int valid_gph_load_addr(uint32_t load_addr); +int gph_verify_header(struct gp_header *gph, int be); +void gph_print_header(const struct gp_header *gph, int be); +void gph_set_header(struct gp_header *gph, uint32_t size, uint32_t load_addr, + int be); +int gpimage_check_params(struct image_tool_params *params); +#endif diff --git a/tools/gpimage-common.c b/tools/gpimage-common.c new file mode 100644 index 0000000..b343a3a --- /dev/null +++ b/tools/gpimage-common.c @@ -0,0 +1,80 @@ +/* + * (C) Copyright 2014 + * Texas Instruments Incorporated + * Refactored common functions in to gpimage-common.c. + * + * (C) Copyright 2010 + * Linaro LTD, www.linaro.org + * Author: John Rigby john.rigby@linaro.org + * Based on TI's signGP.c + * + * (C) Copyright 2009 + * Stefano Babic, DENX Software Engineering, sbabic@denx.de. + * + * (C) Copyright 2008 + * Marvell Semiconductor <www.marvell.com> + * Written-by: Prafulla Wadaskar prafulla@marvell.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include "imagetool.h" +#include <compiler.h> +#include <image.h> +#include "gpheader.h" + +/* Helper to convert size and load_addr to big endian */ +void to_be32(uint32_t *gph_size, uint32_t *gph_load_addr) +{ + *gph_size = cpu_to_be32(*gph_size); + *gph_load_addr = cpu_to_be32(*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; + + if (be) + to_be32(&gph_size, &gph_load_addr); + + if (!gph_size || !gph_load_addr) + return -1; + + return 0; +} + +void gph_print_header(const struct gp_header *gph, int be) +{ + uint32_t gph_size = gph->size, gph_load_addr = gph->load_addr; + + if (be) + to_be32(&gph_size, &gph_load_addr); + + if (!gph_size) { + fprintf(stderr, "Error: invalid image size %x\n", gph_size); + exit(EXIT_FAILURE); + } + + if (!gph_load_addr) { + fprintf(stderr, "Error: invalid image load address %x\n", + gph_load_addr); + exit(EXIT_FAILURE); + } + printf("GP Header: Size %x LoadAddr %x\n", gph_size, gph_load_addr); +} + +void gph_set_header(struct gp_header *gph, uint32_t size, uint32_t load_addr, + int be) +{ + gph->size = size; + gph->load_addr = load_addr; + if (be) + to_be32(&gph->size, &gph->load_addr); +} + +int gpimage_check_params(struct image_tool_params *params) +{ + return (params->dflag && (params->fflag || params->lflag)) || + (params->fflag && (params->dflag || params->lflag)) || + (params->lflag && (params->dflag || params->fflag)); +} diff --git a/tools/gpimage.c b/tools/gpimage.c new file mode 100644 index 0000000..1cabb5b --- /dev/null +++ b/tools/gpimage.c @@ -0,0 +1,77 @@ +/* + * (C) Copyright 2014 + * Texas Instruments Incorporated + * Add gpimage format for keystone devices to format spl image. This is + * Based on omapimage.c + * + * (C) Copyright 2010 + * Linaro LTD, www.linaro.org + * Author: John Rigby john.rigby@linaro.org + * Based on TI's signGP.c + * + * (C) Copyright 2009 + * Stefano Babic, DENX Software Engineering, sbabic@denx.de. + * + * (C) Copyright 2008 + * Marvell Semiconductor <www.marvell.com> + * Written-by: Prafulla Wadaskar prafulla@marvell.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include "imagetool.h" +#include <compiler.h> +#include <image.h> +#include "gpheader.h" + +static uint8_t gpimage_header[GPIMAGE_HDR_SIZE]; + +/* to be in keystone gpimage */ +static int gpimage_check_image_types(uint8_t type) +{ + if (type == IH_TYPE_GPIMAGE) + return EXIT_SUCCESS; + return EXIT_FAILURE; +} + +static int gpimage_verify_header(unsigned char *ptr, int image_size, + struct image_tool_params *params) +{ + struct gp_header *gph = (struct gp_header *)ptr; + + return gph_verify_header(gph, 1); +} + +static void gpimage_print_header(const void *ptr) +{ + const struct gp_header *gph = (struct gp_header *)ptr; + + gph_print_header(gph, 1); +} + +static void gpimage_set_header(void *ptr, struct stat *sbuf, int ifd, + struct image_tool_params *params) +{ + struct gp_header *gph = (struct gp_header *)ptr; + + gph_set_header(gph, sbuf->st_size - GPIMAGE_HDR_SIZE, params->addr, 1); +} + +/* + * 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); +} diff --git a/tools/imagetool.c b/tools/imagetool.c index 29d2189..da72115 100644 --- a/tools/imagetool.c +++ b/tools/imagetool.c @@ -45,6 +45,8 @@ void register_image_tool(imagetool_register_t image_register) init_ubl_image_type(); /* Init Davinci AIS support */ init_ais_image_type(); + /* Init TI Keystone boot image generation/list support */ + init_gpimage_type(); }
/* diff --git a/tools/imagetool.h b/tools/imagetool.h index c2c9aea..a3e9d30 100644 --- a/tools/imagetool.h +++ b/tools/imagetool.h @@ -167,6 +167,7 @@ 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_gpimage_type(void);
void pbl_load_uboot(int fd, struct image_tool_params *mparams);
diff --git a/tools/omapimage.c b/tools/omapimage.c index d59bc4d..1e0c164 100644 --- a/tools/omapimage.c +++ b/tools/omapimage.c @@ -15,57 +15,24 @@ */
#include "imagetool.h" +#include <compiler.h> #include <image.h> +#include "gpheader.h" #include "omapimage.h"
/* Header size is CH header rounded up to 512 bytes plus GP header */ #define OMAP_CH_HDR_SIZE 512 -#define OMAP_GP_HDR_SIZE (sizeof(struct gp_header)) -#define OMAP_FILE_HDR_SIZE (OMAP_CH_HDR_SIZE+OMAP_GP_HDR_SIZE) +#define OMAP_FILE_HDR_SIZE (OMAP_CH_HDR_SIZE + GPIMAGE_HDR_SIZE)
static int do_swap32 = 0;
-static uint32_t omapimage_swap32(uint32_t data) -{ - uint32_t result = 0; - result = (data & 0xFF000000) >> 24; - result |= (data & 0x00FF0000) >> 8; - result |= (data & 0x0000FF00) << 8; - result |= (data & 0x000000FF) << 24; - return result; -} - static uint8_t omapimage_header[OMAP_FILE_HDR_SIZE];
static int omapimage_check_image_types(uint8_t type) { if (type == IH_TYPE_OMAPIMAGE) return EXIT_SUCCESS; - else { - return EXIT_FAILURE; - } -} - -/* - * Only the simplest image type is currently supported: - * TOC pointing to CHSETTINGS - * TOC terminator - * CHSETTINGS - * - * padding to OMAP_CH_HDR_SIZE bytes - * - * gp header - * size - * load_addr - */ -static int valid_gph_size(uint32_t size) -{ - return size; -} - -static int valid_gph_load_addr(uint32_t load_addr) -{ - return load_addr; + return EXIT_FAILURE; }
static int omapimage_verify_header(unsigned char *ptr, int image_size, @@ -73,13 +40,13 @@ static int omapimage_verify_header(unsigned char *ptr, int image_size, { struct ch_toc *toc = (struct ch_toc *)ptr; struct gp_header *gph = (struct gp_header *)(ptr+OMAP_CH_HDR_SIZE); - uint32_t offset, size, gph_size, gph_load_addr; + uint32_t offset, size;
while (toc->section_offset != 0xffffffff && toc->section_size != 0xffffffff) { if (do_swap32) { - offset = omapimage_swap32(toc->section_offset); - size = omapimage_swap32(toc->section_size); + offset = cpu_to_be32(toc->section_offset); + size = cpu_to_be32(toc->section_size); } else { offset = toc->section_offset; size = toc->section_size; @@ -92,20 +59,7 @@ static int omapimage_verify_header(unsigned char *ptr, int image_size, toc++; }
- if (do_swap32) { - gph_size = omapimage_swap32(gph->size); - gph_load_addr = omapimage_swap32(gph->load_addr); - } else { - gph_size = gph->size; - gph_load_addr = gph->load_addr; - } - - if (!valid_gph_size(gph_size)) - return -1; - if (!valid_gph_load_addr(gph_load_addr)) - return -1; - - return 0; + return gph_verify_header(gph, do_swap32); }
static void omapimage_print_section(struct ch_settings *chs) @@ -135,13 +89,13 @@ static void omapimage_print_header(const void *ptr) const struct ch_toc *toc = (struct ch_toc *)ptr; const struct gp_header *gph = (struct gp_header *)(ptr+OMAP_CH_HDR_SIZE); - uint32_t offset, size, gph_size, gph_load_addr; + uint32_t offset, size;
while (toc->section_offset != 0xffffffff && toc->section_size != 0xffffffff) { if (do_swap32) { - offset = omapimage_swap32(toc->section_offset); - size = omapimage_swap32(toc->section_size); + offset = cpu_to_be32(toc->section_offset); + size = cpu_to_be32(toc->section_size); } else { offset = toc->section_offset; size = toc->section_size; @@ -160,26 +114,7 @@ static void omapimage_print_header(const void *ptr) toc++; }
- if (do_swap32) { - gph_size = omapimage_swap32(gph->size); - gph_load_addr = omapimage_swap32(gph->load_addr); - } else { - gph_size = gph->size; - gph_load_addr = gph->load_addr; - } - - if (!valid_gph_size(gph_size)) { - fprintf(stderr, "Error: invalid image size %x\n", gph_size); - exit(EXIT_FAILURE); - } - - if (!valid_gph_load_addr(gph_load_addr)) { - fprintf(stderr, "Error: invalid image load address %x\n", - gph_load_addr); - exit(EXIT_FAILURE); - } - - printf("GP Header: Size %x LoadAddr %x\n", gph_size, gph_load_addr); + gph_print_header(gph, do_swap32); }
static int toc_offset(void *hdr, void *member) @@ -208,8 +143,8 @@ static void omapimage_set_header(void *ptr, struct stat *sbuf, int ifd, toc++; memset(toc, 0xff, sizeof(*toc));
- gph->size = sbuf->st_size - OMAP_FILE_HDR_SIZE; - gph->load_addr = params->addr; + gph_set_header(gph, sbuf->st_size - OMAP_FILE_HDR_SIZE, + params->addr, 0);
if (strncmp(params->imagename, "byteswap", 8) == 0) { do_swap32 = 1; @@ -217,20 +152,13 @@ static void omapimage_set_header(void *ptr, struct stat *sbuf, int ifd, uint32_t *data = (uint32_t *)ptr;
while (swapped <= (sbuf->st_size / sizeof(uint32_t))) { - *data = omapimage_swap32(*data); + *data = cpu_to_be32(*data); swapped++; data++; } } }
-int omapimage_check_params(struct image_tool_params *params) -{ - return (params->dflag && (params->fflag || params->lflag)) || - (params->fflag && (params->dflag || params->lflag)) || - (params->lflag && (params->dflag || params->fflag)); -} - /* * omapimage parameters */ @@ -242,7 +170,7 @@ static struct image_type_params omapimage_params = { .verify_header = omapimage_verify_header, .print_header = omapimage_print_header, .set_header = omapimage_set_header, - .check_params = omapimage_check_params, + .check_params = gpimage_check_params, };
void init_omap_image_type(void) diff --git a/tools/omapimage.h b/tools/omapimage.h index 45d14ea..8744ae7 100644 --- a/tools/omapimage.h +++ b/tools/omapimage.h @@ -25,10 +25,5 @@ struct ch_settings { uint32_t flags; };
-struct gp_header { - uint32_t size; - uint32_t load_addr; -}; - #define KEY_CHSETTINGS 0xC0C0C0C1 #endif /* _OMAPIMAGE_H_ */

On Thu, Feb 20, 2014 at 12:55:05PM -0500, Murali Karicheri wrote:
This patch add support for gpimage format as a preparatory patch for porting u-boot for keystone2 devices and is based on omapimage format. It re-uses gph header to store the size and loadaddr as done in omapimage.c
Signed-off-by: Vitaly Andrianov vitalya@ti.com Signed-off-by: Murali Karicheri m-karicheri2@ti.com
Acked-by: Tom Rini trini@ti.com

From: Vitaly Andrianov vitalya@ti.com
This patch add basic support for the architecture timer found on recent ARMv7 based SoCs.
Signed-off-by: Vitaly Andrianov vitalya@ti.com Signed-off-by: Murali Karicheri m-karicheri2@ti.com --- - No update since v1 arch/arm/lib/Makefile | 1 + arch/arm/lib/arch_timer.c | 58 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 arch/arm/lib/arch_timer.c
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 321997c..726f229 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -42,6 +42,7 @@ obj-$(CONFIG_USE_ARCH_MEMCPY) += memcpy.o else obj-$(CONFIG_SPL_FRAMEWORK) += spl.o endif +obj-$(CONFIG_SYS_ARCH_TIMER) += arch_timer.o
ifdef CONFIG_ARM64 obj-y += interrupts_64.o diff --git a/arch/arm/lib/arch_timer.c b/arch/arm/lib/arch_timer.c new file mode 100644 index 0000000..0588e2b --- /dev/null +++ b/arch/arm/lib/arch_timer.c @@ -0,0 +1,58 @@ +/* + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <div64.h> + +DECLARE_GLOBAL_DATA_PTR; + +int timer_init(void) +{ + gd->arch.tbl = 0; + gd->arch.tbu = 0; + + gd->arch.timer_rate_hz = CONFIG_SYS_HZ_CLOCK / CONFIG_SYS_HZ; + + return 0; +} + +unsigned long long get_ticks(void) +{ + ulong nowl, nowu; + + asm volatile("mrrc p15, 0, %0, %1, c14" : "=r" (nowl), "=r" (nowu)); + + gd->arch.tbl = nowl; + gd->arch.tbu = nowu; + + return (((unsigned long long)gd->arch.tbu) << 32) | gd->arch.tbl; +} + + +ulong get_timer(ulong base) +{ + return lldiv(get_ticks(), gd->arch.timer_rate_hz) - base; +} + +void __udelay(unsigned long usec) +{ + unsigned long long endtime; + + endtime = lldiv((unsigned long long)usec * gd->arch.timer_rate_hz, + 1000UL); + + endtime += get_ticks(); + + while (get_ticks() < endtime) + ; +} + +ulong get_tbclk(void) +{ + return gd->arch.timer_rate_hz; +}

On Thu, Feb 20, 2014 at 12:55:06PM -0500, Murali Karicheri wrote:
From: Vitaly Andrianov vitalya@ti.com
This patch add basic support for the architecture timer found on recent ARMv7 based SoCs.
Signed-off-by: Vitaly Andrianov vitalya@ti.com Signed-off-by: Murali Karicheri m-karicheri2@ti.com
Acked-by: Tom Rini trini@ti.com

This patch introduces a configurable mechanism to disable subpage writes in the DaVinci NAND driver.
Signed-off-by: Vitaly Andrianov vitalya@ti.com Signed-off-by: Murali Karicheri m-karicheri2@ti.com --- - Added README README | 5 +++++ drivers/mtd/nand/davinci_nand.c | 3 +++ 2 files changed, 8 insertions(+)
diff --git a/README b/README index aea82be..caf60a2 100644 --- a/README +++ b/README @@ -4427,6 +4427,11 @@ Low Level (hardware related) configuration options: - CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC: Enables the RTC32K OSC on AM33xx based plattforms
+- CONFIG_SYS_NAND_NO_SUBPAGE_WRITE + Option to disable subpage write in NAND driver + Example driver that use this: + drivers/mtd/nand/davinci_nand.c + Freescale QE/FMAN Firmware Support: -----------------------------------
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index 5b17d7b..75b03a7 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c @@ -609,6 +609,9 @@ void davinci_nand_init(struct nand_chip *nand) #ifdef CONFIG_SYS_NAND_USE_FLASH_BBT nand->bbt_options |= NAND_BBT_USE_FLASH; #endif +#ifdef CONFIG_SYS_NAND_NO_SUBPAGE_WRITE + nand->options |= NAND_NO_SUBPAGE_WRITE; +#endif #ifdef CONFIG_SYS_NAND_HW_ECC nand->ecc.mode = NAND_ECC_HW; nand->ecc.size = 512;

On Thu, Feb 20, 2014 at 12:55:07PM -0500, Murali Karicheri wrote:
This patch introduces a configurable mechanism to disable subpage writes in the DaVinci NAND driver.
Signed-off-by: Vitaly Andrianov vitalya@ti.com Signed-off-by: Murali Karicheri m-karicheri2@ti.com
Acked-by: Tom Rini trini@ti.com

On Thu, 2014-02-20 at 12:55 -0500, Murali Karicheri wrote:
This patch introduces a configurable mechanism to disable subpage writes in the DaVinci NAND driver.
Signed-off-by: Vitaly Andrianov vitalya@ti.com Signed-off-by: Murali Karicheri m-karicheri2@ti.com
- Added README
README | 5 +++++ drivers/mtd/nand/davinci_nand.c | 3 +++ 2 files changed, 8 insertions(+)
diff --git a/README b/README index aea82be..caf60a2 100644 --- a/README +++ b/README @@ -4427,6 +4427,11 @@ Low Level (hardware related) configuration options:
- CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC: Enables the RTC32K OSC on AM33xx based plattforms
+- CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
Option to disable subpage write in NAND driver
Example driver that use this:
drivers/mtd/nand/davinci_nand.c
I'd rather this be a full list of drivers that use it, not an example.
-Scott

On 2/25/2014 11:01 PM, Scott Wood wrote:
On Thu, 2014-02-20 at 12:55 -0500, Murali Karicheri wrote:
This patch introduces a configurable mechanism to disable subpage writes in the DaVinci NAND driver.
Signed-off-by: Vitaly Andrianov vitalya@ti.com Signed-off-by: Murali Karicheri m-karicheri2@ti.com
- Added README
README | 5 +++++ drivers/mtd/nand/davinci_nand.c | 3 +++ 2 files changed, 8 insertions(+)
diff --git a/README b/README index aea82be..caf60a2 100644 --- a/README +++ b/README @@ -4427,6 +4427,11 @@ Low Level (hardware related) configuration options:
- CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC: Enables the RTC32K OSC on AM33xx based plattforms
+- CONFIG_SYS_NAND_NO_SUBPAGE_WRITE
Option to disable subpage write in NAND driver
Example driver that use this:
drivers/mtd/nand/davinci_nand.c
I'd rather this be a full list of drivers that use it, not an example.
There are 3 nand drivers that disable sub page write using NAND_NO_SUBPAGE_WRITE by default.
nand/docg4.c nand/fsl_ifc_nand.c nand/mxs_nand.c
nand/davinci_nand.c is used across many of ti's existing davinci platforms and some of them do enable sub page write. In Keystone platform, we want to disable this option. So to answer your question, davinci_nand.c is the only user driver using this configuration option, but that doesn't prevent anyone from using the option. So I want to keep this configuration option as a generic option.
Hope this clarifies.
Murali
-Scott

This patch moves the davinci i2c_defs.h file to drivers.i2c directory. It will allow to reuse the davinci_i2c driver for TI Keystone2 SOCs.
Not used "git mv" command to move the file because small part of it with definitions specific for Davinci SOCs has to remain in the arch/arm/include/asm/arch-davinci.
Signed-off-by: Vitaly Andrianov vitalya@ti.com --- - updated based on review comments arch/arm/include/asm/arch-davinci/i2c_defs.h | 71 ++---------------------- drivers/i2c/davinci_i2c.c | 1 + drivers/i2c/davinci_i2c.h | 75 ++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 68 deletions(-) create mode 100644 drivers/i2c/davinci_i2c.h
diff --git a/arch/arm/include/asm/arch-davinci/i2c_defs.h b/arch/arm/include/asm/arch-davinci/i2c_defs.h index c388dc0..06da894 100644 --- a/arch/arm/include/asm/arch-davinci/i2c_defs.h +++ b/arch/arm/include/asm/arch-davinci/i2c_defs.h @@ -1,16 +1,13 @@ /* - * (C) Copyright 2004 + * (C) Copyright 2004-2014 * Texas Instruments, <www.ti.com> * * Some changes copyright (C) 2007 Sergey Kubushyn ksi@koi8.net * * SPDX-License-Identifier: GPL-2.0+ */ -#ifndef _DAVINCI_I2C_H_ -#define _DAVINCI_I2C_H_ - -#define I2C_WRITE 0 -#define I2C_READ 1 +#ifndef _I2C_DEFS_H_ +#define _I2C_DEFS_H_
#ifndef CONFIG_SOC_DA8XX #define I2C_BASE 0x01c21000 @@ -18,66 +15,4 @@ #define I2C_BASE 0x01c22000 #endif
-#define I2C_OA (I2C_BASE + 0x00) -#define I2C_IE (I2C_BASE + 0x04) -#define I2C_STAT (I2C_BASE + 0x08) -#define I2C_SCLL (I2C_BASE + 0x0c) -#define I2C_SCLH (I2C_BASE + 0x10) -#define I2C_CNT (I2C_BASE + 0x14) -#define I2C_DRR (I2C_BASE + 0x18) -#define I2C_SA (I2C_BASE + 0x1c) -#define I2C_DXR (I2C_BASE + 0x20) -#define I2C_CON (I2C_BASE + 0x24) -#define I2C_IV (I2C_BASE + 0x28) -#define I2C_PSC (I2C_BASE + 0x30) - -/* I2C masks */ - -/* I2C Interrupt Enable Register (I2C_IE): */ -#define I2C_IE_SCD_IE (1 << 5) /* Stop condition detect interrupt enable */ -#define I2C_IE_XRDY_IE (1 << 4) /* Transmit data ready interrupt enable */ -#define I2C_IE_RRDY_IE (1 << 3) /* Receive data ready interrupt enable */ -#define I2C_IE_ARDY_IE (1 << 2) /* Register access ready interrupt enable */ -#define I2C_IE_NACK_IE (1 << 1) /* No acknowledgment interrupt enable */ -#define I2C_IE_AL_IE (1 << 0) /* Arbitration lost interrupt enable */ - -/* I2C Status Register (I2C_STAT): */ - -#define I2C_STAT_BB (1 << 12) /* Bus busy */ -#define I2C_STAT_ROVR (1 << 11) /* Receive overrun */ -#define I2C_STAT_XUDF (1 << 10) /* Transmit underflow */ -#define I2C_STAT_AAS (1 << 9) /* Address as slave */ -#define I2C_STAT_SCD (1 << 5) /* Stop condition detect */ -#define I2C_STAT_XRDY (1 << 4) /* Transmit data ready */ -#define I2C_STAT_RRDY (1 << 3) /* Receive data ready */ -#define I2C_STAT_ARDY (1 << 2) /* Register access ready */ -#define I2C_STAT_NACK (1 << 1) /* No acknowledgment interrupt enable */ -#define I2C_STAT_AL (1 << 0) /* Arbitration lost interrupt enable */ - - -/* I2C Interrupt Code Register (I2C_INTCODE): */ - -#define I2C_INTCODE_MASK 7 -#define I2C_INTCODE_NONE 0 -#define I2C_INTCODE_AL 1 /* Arbitration lost */ -#define I2C_INTCODE_NAK 2 /* No acknowledgement/general call */ -#define I2C_INTCODE_ARDY 3 /* Register access ready */ -#define I2C_INTCODE_RRDY 4 /* Rcv data ready */ -#define I2C_INTCODE_XRDY 5 /* Xmit data ready */ -#define I2C_INTCODE_SCD 6 /* Stop condition detect */ - - -/* I2C Configuration Register (I2C_CON): */ - -#define I2C_CON_EN (1 << 5) /* I2C module enable */ -#define I2C_CON_STB (1 << 4) /* Start byte mode (master mode only) */ -#define I2C_CON_MST (1 << 10) /* Master/slave mode */ -#define I2C_CON_TRX (1 << 9) /* Transmitter/receiver mode (master mode only) */ -#define I2C_CON_XA (1 << 8) /* Expand address */ -#define I2C_CON_STP (1 << 11) /* Stop condition (master mode only) */ -#define I2C_CON_STT (1 << 13) /* Start condition (master mode only) */ -#define I2C_CON_FREE (1 << 14) /* Free run on emulation */ - -#define I2C_TIMEOUT 0xffff0000 /* Timeout mask for poll_i2c_irq() */ - #endif diff --git a/drivers/i2c/davinci_i2c.c b/drivers/i2c/davinci_i2c.c index e56fe75..6e5260c 100644 --- a/drivers/i2c/davinci_i2c.c +++ b/drivers/i2c/davinci_i2c.c @@ -12,6 +12,7 @@ #include <i2c.h> #include <asm/arch/hardware.h> #include <asm/arch/i2c_defs.h> +#include "davinci_i2c.h"
#define CHECK_NACK() \ do {\ diff --git a/drivers/i2c/davinci_i2c.h b/drivers/i2c/davinci_i2c.h new file mode 100644 index 0000000..79ff7a3 --- /dev/null +++ b/drivers/i2c/davinci_i2c.h @@ -0,0 +1,75 @@ +/* + * (C) Copyright 2004-2014 + * Texas Instruments, <www.ti.com> + * + * Some changes copyright (C) 2007 Sergey Kubushyn ksi@koi8.net + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _DAVINCI_I2C_H_ +#define _DAVINCI_I2C_H_ + +#define I2C_WRITE 0 +#define I2C_READ 1 + +#define I2C_OA (I2C_BASE + 0x00) +#define I2C_IE (I2C_BASE + 0x04) +#define I2C_STAT (I2C_BASE + 0x08) +#define I2C_SCLL (I2C_BASE + 0x0c) +#define I2C_SCLH (I2C_BASE + 0x10) +#define I2C_CNT (I2C_BASE + 0x14) +#define I2C_DRR (I2C_BASE + 0x18) +#define I2C_SA (I2C_BASE + 0x1c) +#define I2C_DXR (I2C_BASE + 0x20) +#define I2C_CON (I2C_BASE + 0x24) +#define I2C_IV (I2C_BASE + 0x28) +#define I2C_PSC (I2C_BASE + 0x30) + +/* I2C masks */ + +/* I2C Interrupt Enable Register (I2C_IE): */ +#define I2C_IE_SCD_IE (1 << 5) /* Stop condition detect interrupt enable */ +#define I2C_IE_XRDY_IE (1 << 4) /* Transmit data ready interrupt enable */ +#define I2C_IE_RRDY_IE (1 << 3) /* Receive data ready interrupt enable */ +#define I2C_IE_ARDY_IE (1 << 2) /* Register access ready interrupt enable */ +#define I2C_IE_NACK_IE (1 << 1) /* No acknowledgment interrupt enable */ +#define I2C_IE_AL_IE (1 << 0) /* Arbitration lost interrupt enable */ + +/* I2C Status Register (I2C_STAT): */ + +#define I2C_STAT_BB (1 << 12) /* Bus busy */ +#define I2C_STAT_ROVR (1 << 11) /* Receive overrun */ +#define I2C_STAT_XUDF (1 << 10) /* Transmit underflow */ +#define I2C_STAT_AAS (1 << 9) /* Address as slave */ +#define I2C_STAT_SCD (1 << 5) /* Stop condition detect */ +#define I2C_STAT_XRDY (1 << 4) /* Transmit data ready */ +#define I2C_STAT_RRDY (1 << 3) /* Receive data ready */ +#define I2C_STAT_ARDY (1 << 2) /* Register access ready */ +#define I2C_STAT_NACK (1 << 1) /* No acknowledgment interrupt enable */ +#define I2C_STAT_AL (1 << 0) /* Arbitration lost interrupt enable */ + +/* I2C Interrupt Code Register (I2C_INTCODE): */ + +#define I2C_INTCODE_MASK 7 +#define I2C_INTCODE_NONE 0 +#define I2C_INTCODE_AL 1 /* Arbitration lost */ +#define I2C_INTCODE_NAK 2 /* No acknowledgement/general call */ +#define I2C_INTCODE_ARDY 3 /* Register access ready */ +#define I2C_INTCODE_RRDY 4 /* Rcv data ready */ +#define I2C_INTCODE_XRDY 5 /* Xmit data ready */ +#define I2C_INTCODE_SCD 6 /* Stop condition detect */ + +/* I2C Configuration Register (I2C_CON): */ + +#define I2C_CON_EN (1 << 5) /* I2C module enable */ +#define I2C_CON_STB (1 << 4) /* Start byte mode (master mode only) */ +#define I2C_CON_MST (1 << 10) /* Master/slave mode */ +#define I2C_CON_TRX (1 << 9) /* Tx/Rx mode (master mode only) */ +#define I2C_CON_XA (1 << 8) /* Expand address */ +#define I2C_CON_STP (1 << 11) /* Stop condition (master mode only) */ +#define I2C_CON_STT (1 << 13) /* Start condition (master mode only) */ +#define I2C_CON_FREE (1 << 14) /* Free run on emulation */ + +#define I2C_TIMEOUT 0xffff0000 /* Timeout mask for poll_i2c_irq() */ + +#endif

On Thu, Feb 20, 2014 at 12:55:08PM -0500, Murali Karicheri wrote:
This patch moves the davinci i2c_defs.h file to drivers.i2c directory. It will allow to reuse the davinci_i2c driver for TI Keystone2 SOCs.
Not used "git mv" command to move the file because small part of it with definitions specific for Davinci SOCs has to remain in the arch/arm/include/asm/arch-davinci.
Signed-off-by: Vitaly Andrianov vitalya@ti.com
Acked-by: Tom Rini trini@ti.com

From: Vitaly Andrianov vitalya@ti.com
Signed-off-by: Vitaly Andrianov vitalya@ti.com --- drivers/i2c/davinci_i2c.c | 344 ++++++++++++++++++++++++++------------------- drivers/i2c/davinci_i2c.h | 27 ++-- 2 files changed, 218 insertions(+), 153 deletions(-)
diff --git a/drivers/i2c/davinci_i2c.c b/drivers/i2c/davinci_i2c.c index 6e5260c..c584a11 100644 --- a/drivers/i2c/davinci_i2c.c +++ b/drivers/i2c/davinci_i2c.c @@ -1,25 +1,37 @@ /* * TI DaVinci (TMS320DM644x) I2C driver. * - * Copyright (C) 2007 Sergey Kubushyn ksi@koi8.net + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * (C) Copyright 2007 Sergey Kubushyn ksi@koi8.net * - * -------------------------------------------------------- - * - * SPDX-License-Identifier: GPL-2.0+ + * SPDX-License-Identifier: GPL-2.0+ */
#include <common.h> #include <i2c.h> #include <asm/arch/hardware.h> #include <asm/arch/i2c_defs.h> +#include <asm/io.h> #include "davinci_i2c.h"
+DECLARE_GLOBAL_DATA_PTR; + +static struct i2c_regs __attribute__((section(".data"))) *i2c_base = + (struct i2c_regs *)I2C_BASE; + +#ifdef CONFIG_I2C_MULTI_BUS +static unsigned int __attribute__((section(".data"))) + bus_initialized[I2C_BUS_MAX] = { [0 ... (I2C_BUS_MAX-1)] = 0 }; +static unsigned int __attribute__((section(".data"))) current_bus; +#endif + #define CHECK_NACK() \ do {\ if (tmp & (I2C_TIMEOUT | I2C_STAT_NACK)) {\ - REG(I2C_CON) = 0;\ - return(1);\ - }\ + REG(&(i2c_base->i2c_con)) = 0;\ + return 1;\ + } \ } while (0)
@@ -27,20 +39,21 @@ static int wait_for_bus(void) { int stat, timeout;
- REG(I2C_STAT) = 0xffff; + REG(&(i2c_base->i2c_stat)) = 0xffff;
for (timeout = 0; timeout < 10; timeout++) { - if (!((stat = REG(I2C_STAT)) & I2C_STAT_BB)) { - REG(I2C_STAT) = 0xffff; - return(0); + stat = REG(&(i2c_base->i2c_stat)); + if (!((stat) & I2C_STAT_BB)) { + REG(&(i2c_base->i2c_stat)) = 0xffff; + return 0; }
- REG(I2C_STAT) = stat; + REG(&(i2c_base->i2c_stat)) = stat; udelay(50000); }
- REG(I2C_STAT) = 0xffff; - return(1); + REG(&(i2c_base->i2c_stat)) = 0xffff; + return 1; }
@@ -50,25 +63,24 @@ static int poll_i2c_irq(int mask)
for (timeout = 0; timeout < 10; timeout++) { udelay(1000); - stat = REG(I2C_STAT); - if (stat & mask) { - return(stat); - } + stat = REG(&(i2c_base->i2c_stat)); + if (stat & mask) + return stat; }
- REG(I2C_STAT) = 0xffff; - return(stat | I2C_TIMEOUT); + REG(&(i2c_base->i2c_stat)) = 0xffff; + return stat | I2C_TIMEOUT; }
void flush_rx(void) { while (1) { - if (!(REG(I2C_STAT) & I2C_STAT_RRDY)) + if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_RRDY)) break;
- REG(I2C_DRR); - REG(I2C_STAT) = I2C_STAT_RRDY; + REG(&(i2c_base->i2c_drr)); + REG(&(i2c_base->i2c_stat)) = I2C_STAT_RRDY; udelay(1000); } } @@ -78,28 +90,33 @@ void i2c_init(int speed, int slaveadd) { u_int32_t div, psc;
- if (REG(I2C_CON) & I2C_CON_EN) { - REG(I2C_CON) = 0; - udelay (50000); + if (REG(&(i2c_base->i2c_con)) & I2C_CON_EN) { + REG(&(i2c_base->i2c_con)) = 0; + udelay(50000); }
psc = 2; - div = (CONFIG_SYS_HZ_CLOCK / ((psc + 1) * speed)) - 10; /* SCLL + SCLH */ - REG(I2C_PSC) = psc; /* 27MHz / (2 + 1) = 9MHz */ - REG(I2C_SCLL) = (div * 50) / 100; /* 50% Duty */ - REG(I2C_SCLH) = div - REG(I2C_SCLL); + div = (CONFIG_SYS_HZ_CLOCK / ((psc + 1) * speed)) - 10; + REG(&(i2c_base->i2c_psc)) = psc; + REG(&(i2c_base->i2c_scll)) = (div * 50) / 100; + REG(&(i2c_base->i2c_sclh)) = div - REG(&(i2c_base->i2c_scll));
- REG(I2C_OA) = slaveadd; - REG(I2C_CNT) = 0; + REG(&(i2c_base->i2c_oa)) = slaveadd; + REG(&(i2c_base->i2c_cnt)) = 0;
/* Interrupts must be enabled or I2C module won't work */ - REG(I2C_IE) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE | + REG(&(i2c_base->i2c_ie)) = I2C_IE_SCD_IE | I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE | I2C_IE_NACK_IE;
/* Now enable I2C controller (get it out of reset) */ - REG(I2C_CON) = I2C_CON_EN; + REG(&(i2c_base->i2c_con)) = I2C_CON_EN;
udelay(1000); + +#ifdef CONFIG_I2C_MULTI_BUS + if (gd->flags & GD_FLG_RELOC) + bus_initialized[current_bus] = 1; +#endif }
int i2c_set_bus_speed(unsigned int speed) @@ -112,34 +129,36 @@ int i2c_probe(u_int8_t chip) { int rc = 1;
- if (chip == REG(I2C_OA)) { - return(rc); - } + if (chip == REG(&(i2c_base->i2c_oa))) + return rc;
- REG(I2C_CON) = 0; - if (wait_for_bus()) {return(1);} + REG(&(i2c_base->i2c_con)) = 0; + if (wait_for_bus()) + return 1;
/* try to read one byte from current (or only) address */ - REG(I2C_CNT) = 1; - REG(I2C_SA) = chip; - REG(I2C_CON) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP); - udelay (50000); + REG(&(i2c_base->i2c_cnt)) = 1; + REG(&(i2c_base->i2c_sa)) = chip; + REG(&(i2c_base->i2c_con)) = (I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | + I2C_CON_STP); + udelay(50000);
- if (!(REG(I2C_STAT) & I2C_STAT_NACK)) { + if (!(REG(&(i2c_base->i2c_stat)) & I2C_STAT_NACK)) { rc = 0; flush_rx(); - REG(I2C_STAT) = 0xffff; + REG(&(i2c_base->i2c_stat)) = 0xffff; } else { - REG(I2C_STAT) = 0xffff; - REG(I2C_CON) |= I2C_CON_STP; + REG(&(i2c_base->i2c_stat)) = 0xffff; + REG(&(i2c_base->i2c_con)) |= I2C_CON_STP; udelay(20000); - if (wait_for_bus()) {return(1);} + if (wait_for_bus()) + return 1; }
flush_rx(); - REG(I2C_STAT) = 0xffff; - REG(I2C_CNT) = 0; - return(rc); + REG(&(i2c_base->i2c_stat)) = 0xffff; + REG(&(i2c_base->i2c_cnt)) = 0; + return rc; }
@@ -149,73 +168,76 @@ int i2c_read(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len) int i;
if ((alen < 0) || (alen > 2)) { - printf("%s(): bogus address length %x\n", __FUNCTION__, alen); - return(1); + printf("%s(): bogus address length %x\n", __func__, alen); + return 1; }
- if (wait_for_bus()) {return(1);} + if (wait_for_bus()) + return 1;
if (alen != 0) { /* Start address phase */ tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX; - REG(I2C_CNT) = alen; - REG(I2C_SA) = chip; - REG(I2C_CON) = tmp; + REG(&(i2c_base->i2c_cnt)) = alen; + REG(&(i2c_base->i2c_sa)) = chip; + REG(&(i2c_base->i2c_con)) = tmp;
tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
CHECK_NACK();
switch (alen) { - case 2: - /* Send address MSByte */ - if (tmp & I2C_STAT_XRDY) { - REG(I2C_DXR) = (addr >> 8) & 0xff; - } else { - REG(I2C_CON) = 0; - return(1); - } - - tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK); - - CHECK_NACK(); - /* No break, fall through */ - case 1: - /* Send address LSByte */ - if (tmp & I2C_STAT_XRDY) { - REG(I2C_DXR) = addr & 0xff; - } else { - REG(I2C_CON) = 0; - return(1); - } - - tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK | I2C_STAT_ARDY); - - CHECK_NACK(); - - if (!(tmp & I2C_STAT_ARDY)) { - REG(I2C_CON) = 0; - return(1); - } + case 2: + /* Send address MSByte */ + if (tmp & I2C_STAT_XRDY) { + REG(&(i2c_base->i2c_dxr)) = (addr >> 8) & 0xff; + } else { + REG(&(i2c_base->i2c_con)) = 0; + return 1; + } + + tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK); + + CHECK_NACK(); + /* No break, fall through */ + case 1: + /* Send address LSByte */ + if (tmp & I2C_STAT_XRDY) { + REG(&(i2c_base->i2c_dxr)) = addr & 0xff; + } else { + REG(&(i2c_base->i2c_con)) = 0; + return 1; + } + + tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK | + I2C_STAT_ARDY); + + CHECK_NACK(); + + if (!(tmp & I2C_STAT_ARDY)) { + REG(&(i2c_base->i2c_con)) = 0; + return 1; + } } }
/* Address phase is over, now read 'len' bytes and stop */ tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP; - REG(I2C_CNT) = len & 0xffff; - REG(I2C_SA) = chip; - REG(I2C_CON) = tmp; + REG(&(i2c_base->i2c_cnt)) = len & 0xffff; + REG(&(i2c_base->i2c_sa)) = chip; + REG(&(i2c_base->i2c_con)) = tmp;
for (i = 0; i < len; i++) { - tmp = poll_i2c_irq(I2C_STAT_RRDY | I2C_STAT_NACK | I2C_STAT_ROVR); + tmp = poll_i2c_irq(I2C_STAT_RRDY | I2C_STAT_NACK | + I2C_STAT_ROVR);
CHECK_NACK();
if (tmp & I2C_STAT_RRDY) { - buf[i] = REG(I2C_DRR); + buf[i] = REG(&(i2c_base->i2c_drr)); } else { - REG(I2C_CON) = 0; - return(1); + REG(&(i2c_base->i2c_con)) = 0; + return 1; } }
@@ -224,16 +246,16 @@ int i2c_read(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len) CHECK_NACK();
if (!(tmp & I2C_STAT_SCD)) { - REG(I2C_CON) = 0; - return(1); + REG(&(i2c_base->i2c_con)) = 0; + return 1; }
flush_rx(); - REG(I2C_STAT) = 0xffff; - REG(I2C_CNT) = 0; - REG(I2C_CON) = 0; + REG(&(i2c_base->i2c_stat)) = 0xffff; + REG(&(i2c_base->i2c_cnt)) = 0; + REG(&(i2c_base->i2c_con)) = 0;
- return(0); + return 0; }
@@ -243,48 +265,51 @@ int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len) int i;
if ((alen < 0) || (alen > 2)) { - printf("%s(): bogus address length %x\n", __FUNCTION__, alen); - return(1); + printf("%s(): bogus address length %x\n", __func__, alen); + return 1; } if (len < 0) { - printf("%s(): bogus length %x\n", __FUNCTION__, len); - return(1); + printf("%s(): bogus length %x\n", __func__, len); + return 1; }
- if (wait_for_bus()) {return(1);} + if (wait_for_bus()) + return 1;
/* Start address phase */ - tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX | I2C_CON_STP; - REG(I2C_CNT) = (alen == 0) ? len & 0xffff : (len & 0xffff) + alen; - REG(I2C_SA) = chip; - REG(I2C_CON) = tmp; + tmp = I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | + I2C_CON_TRX | I2C_CON_STP; + REG(&(i2c_base->i2c_cnt)) = (alen == 0) ? + len & 0xffff : (len & 0xffff) + alen; + REG(&(i2c_base->i2c_sa)) = chip; + REG(&(i2c_base->i2c_con)) = tmp;
switch (alen) { - case 2: - /* Send address MSByte */ - tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK); + case 2: + /* Send address MSByte */ + tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
- CHECK_NACK(); + CHECK_NACK();
- if (tmp & I2C_STAT_XRDY) { - REG(I2C_DXR) = (addr >> 8) & 0xff; - } else { - REG(I2C_CON) = 0; - return(1); - } - /* No break, fall through */ - case 1: - /* Send address LSByte */ - tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK); + if (tmp & I2C_STAT_XRDY) { + REG(&(i2c_base->i2c_dxr)) = (addr >> 8) & 0xff; + } else { + REG(&(i2c_base->i2c_con)) = 0; + return 1; + } + /* No break, fall through */ + case 1: + /* Send address LSByte */ + tmp = poll_i2c_irq(I2C_STAT_XRDY | I2C_STAT_NACK);
- CHECK_NACK(); + CHECK_NACK();
- if (tmp & I2C_STAT_XRDY) { - REG(I2C_DXR) = addr & 0xff; - } else { - REG(I2C_CON) = 0; - return(1); - } + if (tmp & I2C_STAT_XRDY) { + REG(&(i2c_base->i2c_dxr)) = addr & 0xff; + } else { + REG(&(i2c_base->i2c_con)) = 0; + return 1; + } }
for (i = 0; i < len; i++) { @@ -292,11 +317,10 @@ int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len)
CHECK_NACK();
- if (tmp & I2C_STAT_XRDY) { - REG(I2C_DXR) = buf[i]; - } else { - return(1); - } + if (tmp & I2C_STAT_XRDY) + REG(&(i2c_base->i2c_dxr)) = buf[i]; + else + return 1; }
tmp = poll_i2c_irq(I2C_STAT_SCD | I2C_STAT_NACK); @@ -304,14 +328,52 @@ int i2c_write(u_int8_t chip, u_int32_t addr, int alen, u_int8_t *buf, int len) CHECK_NACK();
if (!(tmp & I2C_STAT_SCD)) { - REG(I2C_CON) = 0; - return(1); + REG(&(i2c_base->i2c_con)) = 0; + return 1; }
flush_rx(); - REG(I2C_STAT) = 0xffff; - REG(I2C_CNT) = 0; - REG(I2C_CON) = 0; + REG(&(i2c_base->i2c_stat)) = 0xffff; + REG(&(i2c_base->i2c_cnt)) = 0; + REG(&(i2c_base->i2c_con)) = 0; + + return 0; +} + +#ifdef CONFIG_I2C_MULTI_BUS +int i2c_set_bus_num(unsigned int bus) +{ + if ((bus < 0) || (bus >= I2C_BUS_MAX)) { + printf("Bad bus: %d\n", bus); + return -1; + }
- return(0); + switch (bus) { +#if I2C_BUS_MAX == 3 + case 2: + i2c_base = (struct i2c_regs *)I2C2_BASE; + break; +#endif +#if I2C_BUS_MAX >= 2 + case 1: + i2c_base = (struct i2c_regs *)I2C1_BASE; + break; +#endif + default: + i2c_base = (struct i2c_regs *)I2C0_BASE; + bus = 0; + } + + current_bus = bus; + + if (!bus_initialized[current_bus]) + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + + return 0; +} + +unsigned int i2c_get_bus_num(void) +{ + return (int) current_bus; } +#endif diff --git a/drivers/i2c/davinci_i2c.h b/drivers/i2c/davinci_i2c.h index 79ff7a3..20d4342 100644 --- a/drivers/i2c/davinci_i2c.h +++ b/drivers/i2c/davinci_i2c.h @@ -12,18 +12,21 @@ #define I2C_WRITE 0 #define I2C_READ 1
-#define I2C_OA (I2C_BASE + 0x00) -#define I2C_IE (I2C_BASE + 0x04) -#define I2C_STAT (I2C_BASE + 0x08) -#define I2C_SCLL (I2C_BASE + 0x0c) -#define I2C_SCLH (I2C_BASE + 0x10) -#define I2C_CNT (I2C_BASE + 0x14) -#define I2C_DRR (I2C_BASE + 0x18) -#define I2C_SA (I2C_BASE + 0x1c) -#define I2C_DXR (I2C_BASE + 0x20) -#define I2C_CON (I2C_BASE + 0x24) -#define I2C_IV (I2C_BASE + 0x28) -#define I2C_PSC (I2C_BASE + 0x30) +struct i2c_regs { + u32 i2c_oa; + u32 i2c_ie; + u32 i2c_stat; + u32 i2c_scll; + u32 i2c_sclh; + u32 i2c_cnt; + u32 i2c_drr; + u32 i2c_sa; + u32 i2c_dxr; + u32 i2c_con; + u32 i2c_iv; + u32 res_2c; + u32 i2c_psc; +};
/* I2C masks */

On Thu, Feb 20, 2014 at 12:55:09PM -0500, Murali Karicheri wrote:
From: Vitaly Andrianov vitalya@ti.com
Signed-off-by: Vitaly Andrianov vitalya@ti.com
[snip]
- SPDX-License-Identifier: GPL-2.0+
- SPDX-License-Identifier: GPL-2.0+
Don't change whitespace.
+static struct i2c_regs __attribute__((section(".data"))) *i2c_base =
(struct i2c_regs *)I2C_BASE;
So you're going to need the i2c driver in SPL?
[snip]
- div = (CONFIG_SYS_HZ_CLOCK / ((psc + 1) * speed)) - 10; /* SCLL + SCLH */
- REG(I2C_PSC) = psc; /* 27MHz / (2 + 1) = 9MHz */
- REG(I2C_SCLL) = (div * 50) / 100; /* 50% Duty */
- REG(I2C_SCLH) = div - REG(I2C_SCLL);
- div = (CONFIG_SYS_HZ_CLOCK / ((psc + 1) * speed)) - 10;
- REG(&(i2c_base->i2c_psc)) = psc;
- REG(&(i2c_base->i2c_scll)) = (div * 50) / 100;
- REG(&(i2c_base->i2c_sclh)) = div - REG(&(i2c_base->i2c_scll));
Code is equivalent but we lost the comments about what's being done, please fix. I think this is the only place but please double check, thanks!

From: Vitaly Andrianov vitalya@ti.com
k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler SoC. Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please refer the ti/k2hk_evm/README for details on the board, build and other information.
This patch add support for keystone architecture and k2hk evm.
Signed-off-by: Vitaly Andrianov vitalya@ti.com Signed-off-by: Murali Karicheri m-karicheri2@ti.com Signed-off-by: WingMan Kwok w-kwok2@ti.com Signed-off-by: Sandeep Nair sandeep_n@ti.com --- - Updated based on review comments Makefile | 19 ++ arch/arm/cpu/armv7/keystone/Makefile | 17 ++ arch/arm/cpu/armv7/keystone/aemif.c | 71 +++++ arch/arm/cpu/armv7/keystone/clock.c | 313 ++++++++++++++++++++ arch/arm/cpu/armv7/keystone/cmd_clock.c | 124 ++++++++ arch/arm/cpu/armv7/keystone/cmd_mon.c | 131 ++++++++ arch/arm/cpu/armv7/keystone/config.mk | 15 + arch/arm/cpu/armv7/keystone/ddr3.c | 69 +++++ arch/arm/cpu/armv7/keystone/init.c | 56 ++++ arch/arm/cpu/armv7/keystone/msmc.c | 68 +++++ arch/arm/cpu/armv7/keystone/psc.c | 238 +++++++++++++++ arch/arm/cpu/armv7/keystone/spl.c | 45 +++ arch/arm/include/asm/arch-keystone/clock-k2hk.h | 109 +++++++ arch/arm/include/asm/arch-keystone/clock.h | 17 ++ arch/arm/include/asm/arch-keystone/clock_defs.h | 121 ++++++++ arch/arm/include/asm/arch-keystone/emif_defs.h | 73 +++++ arch/arm/include/asm/arch-keystone/hardware-k2hk.h | 145 +++++++++ arch/arm/include/asm/arch-keystone/hardware.h | 175 +++++++++++ arch/arm/include/asm/arch-keystone/i2c_defs.h | 17 ++ arch/arm/include/asm/arch-keystone/nand_defs.h | 25 ++ arch/arm/include/asm/arch-keystone/psc_defs.h | 90 ++++++ arch/arm/include/asm/arch-keystone/spl.h | 12 + board/ti/k2hk_evm/Makefile | 9 + board/ti/k2hk_evm/README | 56 ++++ board/ti/k2hk_evm/board.c | 236 +++++++++++++++ board/ti/k2hk_evm/ddr3.c | 269 +++++++++++++++++ boards.cfg | 1 + drivers/serial/ns16550.c | 8 + include/configs/k2hk_evm.h | 221 ++++++++++++++ 29 files changed, 2750 insertions(+) create mode 100644 arch/arm/cpu/armv7/keystone/Makefile create mode 100644 arch/arm/cpu/armv7/keystone/aemif.c create mode 100644 arch/arm/cpu/armv7/keystone/clock.c create mode 100644 arch/arm/cpu/armv7/keystone/cmd_clock.c create mode 100644 arch/arm/cpu/armv7/keystone/cmd_mon.c create mode 100644 arch/arm/cpu/armv7/keystone/config.mk create mode 100644 arch/arm/cpu/armv7/keystone/ddr3.c create mode 100644 arch/arm/cpu/armv7/keystone/init.c create mode 100644 arch/arm/cpu/armv7/keystone/msmc.c create mode 100644 arch/arm/cpu/armv7/keystone/psc.c create mode 100644 arch/arm/cpu/armv7/keystone/spl.c create mode 100644 arch/arm/include/asm/arch-keystone/clock-k2hk.h create mode 100644 arch/arm/include/asm/arch-keystone/clock.h create mode 100644 arch/arm/include/asm/arch-keystone/clock_defs.h create mode 100644 arch/arm/include/asm/arch-keystone/emif_defs.h create mode 100644 arch/arm/include/asm/arch-keystone/hardware-k2hk.h create mode 100644 arch/arm/include/asm/arch-keystone/hardware.h create mode 100644 arch/arm/include/asm/arch-keystone/i2c_defs.h create mode 100644 arch/arm/include/asm/arch-keystone/nand_defs.h create mode 100644 arch/arm/include/asm/arch-keystone/psc_defs.h create mode 100644 arch/arm/include/asm/arch-keystone/spl.h create mode 100644 board/ti/k2hk_evm/Makefile create mode 100644 board/ti/k2hk_evm/README create mode 100644 board/ti/k2hk_evm/board.c create mode 100644 board/ti/k2hk_evm/ddr3.c create mode 100644 include/configs/k2hk_evm.h
diff --git a/Makefile b/Makefile index 47a03e3..ea2a387 100644 --- a/Makefile +++ b/Makefile @@ -491,6 +491,23 @@ $(obj)u-boot.spr: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin --pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0xff $@ cat $(obj)u-boot.img >> $@
+$(obj)u-boot-spi.gph: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin + $(obj)tools/mkimage -A $(ARCH) -T gpimage -C none \ + -a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) \ + -n SPL -d $(obj)spl/u-boot-spl.bin $(obj)spl/u-boot-spl.gph + $(OBJCOPY) ${OBJCFLAGS} -I binary \ + --pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0 -O binary \ + $(obj)spl/u-boot-spl.gph $(obj)spl/u-boot-spl-pad.gph + cat $(obj)spl/u-boot-spl-pad.gph $(obj)u-boot.img > $@ + +$(obj)u-boot-nand.gph: $(obj)u-boot.bin + $(obj)tools/mkimage -A $(ARCH) -T gpimage -C none \ + -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) \ + -n U-Boot -d $(obj)u-boot.bin $(obj)gph-u-boot.bin + @dd if=/dev/zero of=$(obj)zero.bin bs=8 count=1 2>/dev/null + @cat $(obj)gph-u-boot.bin $(obj)zero.bin > $@ + @rm $(obj)zero.bin + ifneq ($(CONFIG_TEGRA),) $(obj)u-boot-nodtb-tegra.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.bin $(OBJCOPY) ${OBJCFLAGS} --pad-to=$(CONFIG_SYS_TEXT_BASE) -O binary $(obj)spl/u-boot-spl $(obj)spl/u-boot-spl-pad.bin @@ -841,12 +858,14 @@ clobber: tidy @rm -f $(obj)u-boot.dtb @rm -f $(obj)u-boot.sb @rm -f $(obj)u-boot.spr + @rm -f $(obj)u-boot-*.gph @rm -f $(obj)nand_spl/{u-boot.{lds,lst},System.map} @rm -f $(obj)nand_spl/{u-boot-nand_spl.lds,u-boot-spl,u-boot-spl.map} @rm -f $(obj)spl/{u-boot-spl,u-boot-spl.bin,u-boot-spl.map} @rm -f $(obj)spl/u-boot-spl.lds @rm -f $(obj)tpl/{u-boot-tpl,u-boot-tpl.bin,u-boot-tpl.map} @rm -f $(obj)tpl/u-boot-spl.lds + @rm -f $(obj)spl/{u-boot-spl.gph,u-boot-spl-pad.gph} @rm -f $(obj)MLO MLO.byteswap @rm -f $(obj)SPL @rm -f $(obj)tools/xway-swap-bytes diff --git a/arch/arm/cpu/armv7/keystone/Makefile b/arch/arm/cpu/armv7/keystone/Makefile new file mode 100644 index 0000000..7924cfa --- /dev/null +++ b/arch/arm/cpu/armv7/keystone/Makefile @@ -0,0 +1,17 @@ +# +# (C) Copyright 2012-2014 +# Texas Instruments Incorporated, <www.ti.com> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += aemif.o +obj-y += init.o +obj-y += psc.o +obj-y += clock.o +obj-y += cmd_clock.o +obj-y += cmd_mon.o +obj-y += msmc.o +obj-$(CONFIG_SPL_BUILD) += spl.o +obj-y += ddr3.o + diff --git a/arch/arm/cpu/armv7/keystone/aemif.c b/arch/arm/cpu/armv7/keystone/aemif.c new file mode 100644 index 0000000..9b26886 --- /dev/null +++ b/arch/arm/cpu/armv7/keystone/aemif.c @@ -0,0 +1,71 @@ +/* + * Keystone2: Asynchronous EMIF Configuration + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/emif_defs.h> + +#define AEMIF_CFG_SELECT_STROBE(v) ((v) ? 1 << 31 : 0) +#define AEMIF_CFG_EXTEND_WAIT(v) ((v) ? 1 << 30 : 0) +#define AEMIF_CFG_WR_SETUP(v) (((v) & 0x0f) << 26) +#define AEMIF_CFG_WR_STROBE(v) (((v) & 0x3f) << 20) +#define AEMIF_CFG_WR_HOLD(v) (((v) & 0x07) << 17) +#define AEMIF_CFG_RD_SETUP(v) (((v) & 0x0f) << 13) +#define AEMIF_CFG_RD_STROBE(v) (((v) & 0x3f) << 7) +#define AEMIF_CFG_RD_HOLD(v) (((v) & 0x07) << 4) +#define AEMIF_CFG_TURN_AROUND(v) (((v) & 0x03) << 2) +#define AEMIF_CFG_WIDTH(v) (((v) & 0x03) << 0) + +#define set_config_field(reg, field, val) \ + do { \ + if (val != -1) { \ + reg &= ~AEMIF_CFG_##field(0xffffffff); \ + reg |= AEMIF_CFG_##field(val); \ + } \ + } while (0) + +void configure_async_emif(int cs, struct async_emif_config *cfg) +{ + unsigned long tmp; + + if (cfg->mode == ASYNC_EMIF_MODE_NAND) { + tmp = __raw_readl(&davinci_emif_regs->nandfcr); + tmp |= (1 << cs); + __raw_writel(tmp, &davinci_emif_regs->nandfcr); + + } else if (cfg->mode == ASYNC_EMIF_MODE_ONENAND) { + tmp = __raw_readl(&davinci_emif_regs->one_nand_cr); + tmp |= (1 << cs); + __raw_writel(tmp, &davinci_emif_regs->one_nand_cr); + } + + tmp = __raw_readl(&davinci_emif_regs->abncr[cs]); + + set_config_field(tmp, SELECT_STROBE, cfg->select_strobe); + set_config_field(tmp, EXTEND_WAIT, cfg->extend_wait); + set_config_field(tmp, WR_SETUP, cfg->wr_setup); + set_config_field(tmp, WR_STROBE, cfg->wr_strobe); + set_config_field(tmp, WR_HOLD, cfg->wr_hold); + set_config_field(tmp, RD_SETUP, cfg->rd_setup); + set_config_field(tmp, RD_STROBE, cfg->rd_strobe); + set_config_field(tmp, RD_HOLD, cfg->rd_hold); + set_config_field(tmp, TURN_AROUND, cfg->turn_around); + set_config_field(tmp, WIDTH, cfg->width); + + __raw_writel(tmp, &davinci_emif_regs->abncr[cs]); +} + +void init_async_emif(int num_cs, struct async_emif_config *config) +{ + int cs; + + for (cs = 0; cs < num_cs; cs++) + configure_async_emif(cs, config + cs); +} diff --git a/arch/arm/cpu/armv7/keystone/clock.c b/arch/arm/cpu/armv7/keystone/clock.c new file mode 100644 index 0000000..87d7c7f --- /dev/null +++ b/arch/arm/cpu/armv7/keystone/clock.c @@ -0,0 +1,313 @@ +/* + * Keystone2: pll initialization + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm-generic/errno.h> +#include <asm/io.h> +#include <asm/processor.h> +#include <asm/arch/clock.h> +#include <asm/arch/clock_defs.h> + +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; + } +} + +struct pll_regs { + u32 reg0, reg1; +}; + +static const struct pll_regs pll_regs[] = { + [CORE_PLL] = { K2HK_MAINPLLCTL0, K2HK_MAINPLLCTL1}, + [PASS_PLL] = { K2HK_PASSPLLCTL0, K2HK_PASSPLLCTL1}, + [TETRIS_PLL] = { K2HK_ARMPLLCTL0, K2HK_ARMPLLCTL1}, + [DDR3A_PLL] = { K2HK_DDR3APLLCTL0, K2HK_DDR3APLLCTL1}, + [DDR3B_PLL] = { K2HK_DDR3BPLLCTL0, K2HK_DDR3BPLLCTL1}, +}; + +/* Fout = Fref * NF(mult) / NR(prediv) / OD */ +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(K2HK_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 = K2HK_PASSPLLCTL0; + break; + case TETRIS_PLL: + ret = external_clk[tetris_clk]; + reg = K2HK_ARMPLLCTL0; + break; + case DDR3A_PLL: + ret = external_clk[ddr3a_clk]; + reg = K2HK_DDR3APLLCTL0; + break; + case DDR3B_PLL: + ret = external_clk[ddr3b_clk]; + reg = K2HK_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; +} + +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) { + sdelay(210000); + + tmp = pllctl_reg_read(data->pll, secctl); + + if (tmp & (PLLCTL_BYPASS)) { + reg_setbits(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); + + reg_rmw(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 */ + reg_rmw(pll_regs[data->pll].reg0, PLL_BWADJ_LO_SMASK, + (tmp_ctl << PLL_BWADJ_LO_SHIFT)); + reg_rmw(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 + */ + reg_rmw(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); + + } else if (data->pll == TETRIS_PLL) { + bwadj = pllm >> 1; + /* 1.5 Set PLLCTL0[BYPASS] =1 (enable bypass), */ + reg_setbits(pll_regs[data->pll].reg0, PLLCTL_BYPASS); + /* + * Set CHIPMISCCTL1[13] = 0 (enable glitchfree bypass) + * only applicable for Kepler + */ + reg_clrbits(K2HK_MISC_CTRL, ARM_PLL_EN); + /* 2 In PLLCTL1, write PLLRST = 1 (PLL is reset) */ + reg_setbits(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, pll_regs[data->pll].reg0); + + /* Set BWADJ[11:8] bits */ + tmp = __raw_readl(pll_regs[data->pll].reg1); + tmp &= ~(PLL_BWADJ_HI_MASK); + tmp |= ((bwadj>>8) & PLL_BWADJ_HI_MASK); + __raw_writel(tmp, 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) */ + reg_clrbits(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 */ + reg_clrbits(pll_regs[data->pll].reg0, PLLCTL_BYPASS); + /* + * 9 Set CHIPMISCCTL1[13] = 1 (disable glitchfree bypass) + * only applicable for Kepler + */ + reg_setbits(K2HK_MISC_CTRL, ARM_PLL_EN); + } else { + reg_setbits(pll_regs[data->pll].reg1, PLLCTL_ENSAT); + /* + * process keeps state of Bypass bit while programming + * all other DDR PLL settings + */ + tmp = __raw_readl(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_SHIFT) << PLL_BWADJ_LO_SHIFT) | + (pllm << PLL_MULT_SHIFT) | + (plld & PLL_DIV_MASK) | + (pllod << PLL_CLKOD_SHIFT); + __raw_writel(tmp, pll_regs[data->pll].reg0); + + /* Set BWADJ[11:8] bits */ + tmp = __raw_readl(pll_regs[data->pll].reg1); + tmp &= ~(PLL_BWADJ_HI_MASK); + tmp |= ((bwadj >> 8) & PLL_BWADJ_HI_MASK); + + /* set PLL Select (bit 13) for PASS PLL */ + if (data->pll == PASS_PLL) + tmp |= PLLCTL_PAPLL; + + __raw_writel(tmp, pll_regs[data->pll].reg1); + + /* Reset bit: bit 14 for both DDR3 & PASS PLL */ + tmp = PLL_PLLRST; + /* Set RESET bit = 1 */ + reg_setbits(pll_regs[data->pll].reg1, tmp); + /* Wait for a minimum of 7 us*/ + sdelay(21000); + /* Clear RESET bit */ + reg_clrbits(pll_regs[data->pll].reg1, tmp); + sdelay(105000); + + /* clear BYPASS (Enable PLL Mode) */ + reg_clrbits(pll_regs[data->pll].reg0, PLLCTL_BYPASS); + sdelay(21000); /* Wait for a minimum of 7 us*/ + } + + 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]); +} diff --git a/arch/arm/cpu/armv7/keystone/cmd_clock.c b/arch/arm/cpu/armv7/keystone/cmd_clock.c new file mode 100644 index 0000000..afd30f3 --- /dev/null +++ b/arch/arm/cpu/armv7/keystone/cmd_clock.c @@ -0,0 +1,124 @@ +/* + * keystone2: commands for clocks + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +#include <asm/arch/hardware.h> +#include <asm/arch/clock.h> +#include <asm/arch/psc_defs.h> + +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; + else if (strncmp(argv[1], "arm", 3) == 0) + cmd_pll_data.pll = TETRIS_PLL; + 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 + 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", + "<pa|arm|ddr3a|ddr3b> <mult> <div> <OD>\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", + "<clk index>\n" + "See the 'enum clk_e' in the k2hk clock.h for clk indexes\n" +); + +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, + "<enable/disable psc module os disable domain>", + "<mod/domain index> <en|di|domain>\n" + "See the hardware.h for Power and Sleep Controller (PSC) Domains\n" +); diff --git a/arch/arm/cpu/armv7/keystone/cmd_mon.c b/arch/arm/cpu/armv7/keystone/cmd_mon.c new file mode 100644 index 0000000..f9f58a3 --- /dev/null +++ b/arch/arm/cpu/armv7/keystone/cmd_mon.c @@ -0,0 +1,131 @@ +/* + * K2HK: secure kernel command file + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <command.h> +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 <coreid> <oper>\n" + "- coreid (1-3) and oper (1 - ON, 0 - OFF)\n" + "" +); diff --git a/arch/arm/cpu/armv7/keystone/config.mk b/arch/arm/cpu/armv7/keystone/config.mk new file mode 100644 index 0000000..1c8769c --- /dev/null +++ b/arch/arm/cpu/armv7/keystone/config.mk @@ -0,0 +1,15 @@ +# (C) Copyright 2012-2014 +# Texas Instruments Incorporated, <www.ti.com> +# SPDX-License-Identifier: GPL-2.0+ +# + +PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float + +# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +PF_CPPFLAGS_SLB +=$(call cc-option,-mshort-load-bytes,\ + $(call cc-option,-malignment-traps,)) +PLATFORM_RELFLAGS += $(PF_CPPFLAGS_SLB) diff --git a/arch/arm/cpu/armv7/keystone/ddr3.c b/arch/arm/cpu/armv7/keystone/ddr3.c new file mode 100644 index 0000000..4875db7 --- /dev/null +++ b/arch/arm/cpu/armv7/keystone/ddr3.c @@ -0,0 +1,69 @@ +/* + * Keystone2: DDR3 initialization + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <asm/arch/hardware.h> +#include <asm/io.h> + +void 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 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); +} diff --git a/arch/arm/cpu/armv7/keystone/init.c b/arch/arm/cpu/armv7/keystone/init.c new file mode 100644 index 0000000..1b7e52a --- /dev/null +++ b/arch/arm/cpu/armv7/keystone/init.c @@ -0,0 +1,56 @@ +/* + * Keystone2: Architecture initialization + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/hardware.h> + +void chip_configuration_unlock(void) +{ + __raw_writel(KEYSTONE_KICK0_MAGIC, KEYSTONE_KICK0); + __raw_writel(KEYSTONE_KICK1_MAGIC, KEYSTONE_KICK1); +} + +int arch_cpu_init(void) +{ + chip_configuration_unlock(); + icache_enable(); + +#ifdef CONFIG_SOC_K2HK + share_all_segments(8); + share_all_segments(9); + share_all_segments(10); /* QM PDSP */ + share_all_segments(11); /* PCIE */ +#endif + + return 0; +} + +void reset_cpu(ulong addr) +{ + volatile u32 *rstctrl = (volatile u32 *)(CLOCK_BASE + 0xe8); + u32 tmp; + + tmp = *rstctrl & 0xffff0000; + *rstctrl = tmp | 0x5a69; + + *rstctrl &= 0xfffe0000; + + 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/msmc.c b/arch/arm/cpu/armv7/keystone/msmc.c new file mode 100644 index 0000000..f3f1621 --- /dev/null +++ b/arch/arm/cpu/armv7/keystone/msmc.c @@ -0,0 +1,68 @@ +/* + * MSMC controller utilities + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/hardware.h> + +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 share_all_segments(int priv_id) +{ + struct msms_regs *msmc = (struct msms_regs *)K2HK_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; + } +} diff --git a/arch/arm/cpu/armv7/keystone/psc.c b/arch/arm/cpu/armv7/keystone/psc.c new file mode 100644 index 0000000..fecf918 --- /dev/null +++ b/arch/arm/cpu/armv7/keystone/psc.c @@ -0,0 +1,238 @@ +/* + * Keystone: PSC configuration module + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm-generic/errno.h> +#include <asm/io.h> +#include <asm/processor.h> +#include <asm/arch/psc_defs.h> + +#define DEVICE_REG32_R(addr) __raw_readl((u32 *)(addr)) +#define DEVICE_REG32_W(addr, val) __raw_writel(val, (u32 *)(addr)) + +#ifdef CONFIG_SOC_K2HK +#define DEVICE_PSC_BASE K2HK_PSC_BASE +#endif + +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 = DEVICE_REG32_R(DEVICE_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 = DEVICE_REG32_R(DEVICE_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 = DEVICE_REG32_R(DEVICE_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 = DEVICE_REG32_R(DEVICE_PSC_BASE + + PSC_REG_PDCTL(domain_num)); + pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl, + PSC_REG_VAL_PDCTL_NEXT_ON); + DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_PDCTL(domain_num), + pdctl); + } + + /* Set the next state for the module to enabled/disabled */ + mdctl = DEVICE_REG32_R(DEVICE_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); + DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num), mdctl); + + /* Trigger the enable */ + ptcmd = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_PTCMD); + ptcmd |= (u32)(1<<domain_num); + DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_PTCMD, ptcmd); + + /* Wait on the complete */ + return psc_wait(domain_num); +} + +/* + * FUNCTION PURPOSE: Power up a module + * + * DESCRIPTION: Powers up the requested module and the associated power domain + * if required. No action is taken it the module is already + * powered up. + * + * 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_enable_module(u32 mod_num) +{ + u32 mdctl; + + /* Set the bit to apply reset */ + mdctl = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num)); + if ((mdctl & 0x3f) == PSC_REG_VAL_MDSTAT_STATE_ON) + return 0; + + return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_ON); +} + +/* + * FUNCTION PURPOSE: Power down a module + * + * DESCRIPTION: Powers down the requested module. + * + * Returns 0 on success, -1 on failure or timeout. + */ +int psc_disable_module(u32 mod_num) +{ + u32 mdctl; + + /* Set the bit to apply reset */ + mdctl = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num)); + if ((mdctl & 0x3f) == 0) + return 0; + mdctl = PSC_REG_MDCTL_SET_LRSTZ(mdctl, 0); + DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num), mdctl); + + return psc_set_state(mod_num, PSC_REG_VAL_MDCTL_NEXT_SWRSTDISABLE); +} + +/* + * FUNCTION PURPOSE: Set the reset isolation bit in mdctl + * + * DESCRIPTION: The reset isolation enable bit is set. The state of the module + * is not changed. Returns 0 if the module config showed that + * reset isolation is supported. Returns 1 otherwise. This is not + * an error, but setting the bit in mdctl has no effect. + */ +int psc_set_reset_iso(u32 mod_num) +{ + u32 v; + u32 mdctl; + + /* Set the reset isolation bit */ + mdctl = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num)); + mdctl = PSC_REG_MDCTL_SET_RESET_ISO(mdctl, 1); + DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_MDCTL(mod_num), mdctl); + + v = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_MDCFG(mod_num)); + if (PSC_REG_MDCFG_GET_RESET_ISO(v) == 1) + return 0; + + return 1; +} + +/* + * FUNCTION PURPOSE: Disable a power domain + * + * DESCRIPTION: The power domain is disabled + */ +int psc_disable_domain(u32 domain_num) +{ + u32 pdctl; + u32 ptcmd; + + pdctl = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_PDCTL(domain_num)); + pdctl = PSC_REG_PDCTL_SET_NEXT(pdctl, PSC_REG_VAL_PDCTL_NEXT_OFF); + pdctl = PSC_REG_PDCTL_SET_PDMODE(pdctl, PSC_REG_VAL_PDCTL_PDMODE_SLEEP); + DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_PDCTL(domain_num), pdctl); + + ptcmd = DEVICE_REG32_R(DEVICE_PSC_BASE + PSC_REG_PTCMD); + ptcmd |= (u32)(1 << domain_num); + DEVICE_REG32_W(DEVICE_PSC_BASE + PSC_REG_PTCMD, ptcmd); + + return psc_wait(domain_num); +} + diff --git a/arch/arm/cpu/armv7/keystone/spl.c b/arch/arm/cpu/armv7/keystone/spl.c new file mode 100644 index 0000000..e07b64d --- /dev/null +++ b/arch/arm/cpu/armv7/keystone/spl.c @@ -0,0 +1,45 @@ +/* + * common spl init code + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <config.h> +#include <ns16550.h> +#include <malloc.h> +#include <spl.h> +#include <spi_flash.h> + +#include <asm/u-boot.h> +#include <asm/utils.h> + +DECLARE_GLOBAL_DATA_PTR; + +static struct pll_init_data spl_pll_config[] = { + CORE_PLL_799, + TETRIS_PLL_500, +}; + +void spl_init_keystone_plls(void) +{ + init_plls(ARRAY_SIZE(spl_pll_config), spl_pll_config); +} + +void spl_board_init(void) +{ + spl_init_keystone_plls(); + preloader_console_init(); +} + +u32 spl_boot_device(void) +{ +#if defined(CONFIG_SPL_SPI_LOAD) + return BOOT_DEVICE_SPI; +#else + puts("Unknown boot device\n"); + hang(); +#endif +} diff --git a/arch/arm/include/asm/arch-keystone/clock-k2hk.h b/arch/arm/include/asm/arch-keystone/clock-k2hk.h new file mode 100644 index 0000000..6721939 --- /dev/null +++ b/arch/arm/include/asm/arch-keystone/clock-k2hk.h @@ -0,0 +1,109 @@ +/* + * K2HK: Clock management APIs + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARCH_CLOCK_K2HK_H +#define __ASM_ARCH_CLOCK_K2HK_H + +#include <asm/arch/hardware.h> + +#ifndef __ASSEMBLY__ + +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]; + +enum clk_e { + core_pll_clk, + pass_pll_clk, + tetris_pll_clk, + ddr3a_pll_clk, + ddr3b_pll_clk, + sys_clk0_clk, + sys_clk0_1_clk, + sys_clk0_2_clk, + sys_clk0_3_clk, + sys_clk0_4_clk, + sys_clk0_6_clk, + sys_clk0_8_clk, + sys_clk0_12_clk, + sys_clk0_24_clk, + sys_clk1_clk, + sys_clk1_3_clk, + sys_clk1_4_clk, + sys_clk1_6_clk, + sys_clk1_12_clk, + sys_clk2_clk, + sys_clk3_clk +}; + +#define K2HK_CLK1_6 sys_clk0_6_clk + +/* PLL identifiers */ +enum pll_type_e { + CORE_PLL, + PASS_PLL, + TETRIS_PLL, + DDR3A_PLL, + DDR3B_PLL, +}; +#define MAIN_PLL CORE_PLL + +/* 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 */ +}; + +#define CORE_PLL_799 {CORE_PLL, 13, 1, 2} +#define CORE_PLL_983 {CORE_PLL, 16, 1, 2} +#define CORE_PLL_1167 {CORE_PLL, 19, 1, 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_500 {TETRIS_PLL, 8, 1, 2} +#define TETRIS_PLL_750 {TETRIS_PLL, 12, 1, 2} +#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_1188 {TETRIS_PLL, 19, 2, 1} +#define TETRIS_PLL_1200 {TETRIS_PLL, 48, 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} + +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); + +#endif + +#endif diff --git a/arch/arm/include/asm/arch-keystone/clock.h b/arch/arm/include/asm/arch-keystone/clock.h new file mode 100644 index 0000000..324501b --- /dev/null +++ b/arch/arm/include/asm/arch-keystone/clock.h @@ -0,0 +1,17 @@ +/* + * keystone2: common clock header file + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __ASM_ARCH_CLOCK_H +#define __ASM_ARCH_CLOCK_H + +#ifdef CONFIG_SOC_K2HK +#include <asm/arch/clock-k2hk.h> +#endif + +#endif diff --git a/arch/arm/include/asm/arch-keystone/clock_defs.h b/arch/arm/include/asm/arch-keystone/clock_defs.h new file mode 100644 index 0000000..61b6b62 --- /dev/null +++ b/arch/arm/include/asm/arch-keystone/clock_defs.h @@ -0,0 +1,121 @@ +/* + * keystone2: common pll clock definitions + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _CLOCK_DEFS_H_ +#define _CLOCK_DEFS_H_ + +#include <asm/arch/hardware.h> + +#define BIT(x) (1 << (x)) + +/* PLL Control Registers */ +struct pllctl_regs { + u32 ctl; /* 00 */ + u32 ocsel; /* 04 */ + u32 secctl; /* 08 */ + u32 __pad0; + u32 mult; /* 10 */ + u32 prediv; /* 14 */ + u32 div1; /* 18 */ + u32 div2; /* 1c */ + u32 div3; /* 20 */ + u32 oscdiv1; /* 24 */ + u32 __pad1; /* 28 */ + u32 bpdiv; /* 2c */ + u32 wakeup; /* 30 */ + u32 __pad2; + 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 __pad3[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 *)(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 reg_rmw(reg, mask, val) \ + __raw_writel((__raw_readl((reg)) & ~(mask)) | ((val) & (mask)) , \ + (reg)); + +#define reg_setbits(reg, bits) \ + __raw_writel((__raw_readl(reg) | (bits)) , (reg)); + +#define reg_clrbits(reg, bits) \ + __raw_writel((__raw_readl(reg) & ~(bits)) , (reg)); + +#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 | 0) +#define PLLM_RATIO_DIV2 (PLLDIV_ENABLE | 0) +#define PLLM_RATIO_DIV3 (PLLDIV_ENABLE | 1) +#define PLLM_RATIO_DIV4 (PLLDIV_ENABLE | 4) +#define PLLM_RATIO_DIV5 (PLLDIV_ENABLE | 17) + +#endif /* _CLOCK_DEFS_H_ */ diff --git a/arch/arm/include/asm/arch-keystone/emif_defs.h b/arch/arm/include/asm/arch-keystone/emif_defs.h new file mode 100644 index 0000000..4e88ae6 --- /dev/null +++ b/arch/arm/include/asm/arch-keystone/emif_defs.h @@ -0,0 +1,73 @@ +/* + * emif definitions to re-use davinci emif driver on Keystone2 + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * (C) Copyright 2007 Sergey Kubushyn ksi@koi8.net + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _EMIF_DEFS_H_ +#define _EMIF_DEFS_H_ + +#include <asm/arch/hardware.h> + +struct davinci_emif_regs { + u_int32_t ercsr; + u_int32_t awccr; + u_int32_t sdbcr; + u_int32_t sdrcr; + u_int32_t abncr[4]; + u_int32_t sdtimr; + u_int32_t ddrsr; + u_int32_t ddrphycr; + u_int32_t ddrphysr; + u_int32_t totar; + u_int32_t totactr; + u_int32_t ddrphyid_rev; + u_int32_t sdsretr; + u_int32_t eirr; + u_int32_t eimr; + u_int32_t eimsr; + u_int32_t eimcr; + u_int32_t ioctrlr; + u_int32_t iostatr; + u_int32_t rsvd0; + u_int32_t one_nand_cr; + u_int32_t nandfcr; + u_int32_t nandfsr; + u_int32_t rsvd1[2]; + u_int32_t nandfecc[4]; + u_int32_t rsvd2[15]; + u_int32_t nand4biteccload; + u_int32_t nand4bitecc[4]; + u_int32_t nanderradd1; + u_int32_t nanderradd2; + u_int32_t nanderrval1; + u_int32_t nanderrval2; +}; + +#define davinci_emif_regs \ + ((struct davinci_emif_regs *)DAVINCI_ASYNC_EMIF_CNTRL_BASE) + +#define DAVINCI_NANDFCR_NAND_ENABLE(n) (1 << ((n) - 2)) +#define DAVINCI_NANDFCR_4BIT_ECC_SEL_MASK (3 << 4) +#define DAVINCI_NANDFCR_4BIT_ECC_SEL(n) (((n) - 2) << 4) +#define DAVINCI_NANDFCR_1BIT_ECC_START(n) (1 << (8 + ((n) - 2))) +#define DAVINCI_NANDFCR_4BIT_ECC_START (1 << 12) +#define DAVINCI_NANDFCR_4BIT_CALC_START (1 << 13) + +/* Chip Select setup */ +#define DAVINCI_ABCR_STROBE_SELECT (1 << 31) +#define DAVINCI_ABCR_EXT_WAIT (1 << 30) +#define DAVINCI_ABCR_WSETUP(n) ((n) << 26) +#define DAVINCI_ABCR_WSTROBE(n) ((n) << 20) +#define DAVINCI_ABCR_WHOLD(n) ((n) << 17) +#define DAVINCI_ABCR_RSETUP(n) ((n) << 13) +#define DAVINCI_ABCR_RSTROBE(n) ((n) << 7) +#define DAVINCI_ABCR_RHOLD(n) ((n) << 4) +#define DAVINCI_ABCR_TA(n) ((n) << 2) +#define DAVINCI_ABCR_ASIZE_16BIT 1 +#define DAVINCI_ABCR_ASIZE_8BIT 0 + +#endif diff --git a/arch/arm/include/asm/arch-keystone/hardware-k2hk.h b/arch/arm/include/asm/arch-keystone/hardware-k2hk.h new file mode 100644 index 0000000..034b655 --- /dev/null +++ b/arch/arm/include/asm/arch-keystone/hardware-k2hk.h @@ -0,0 +1,145 @@ +/* + * K2HK: SoC definitions + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef __ASM_ARCH_HARDWARE_K2HK_H +#define __ASM_ARCH_HARDWARE_K2HK_H + +#define K2HK_ASYNC_EMIF_CNTRL_BASE 0x21000a00 +#define DAVINCI_ASYNC_EMIF_CNTRL_BASE K2HK_ASYNC_EMIF_CNTRL_BASE +#define K2HK_ASYNC_EMIF_DATA_CE0_BASE 0x30000000 +#define K2HK_ASYNC_EMIF_DATA_CE1_BASE 0x34000000 +#define K2HK_ASYNC_EMIF_DATA_CE2_BASE 0x38000000 +#define K2HK_ASYNC_EMIF_DATA_CE3_BASE 0x3c000000 + +#define K2HK_PLL_CNTRL_BASE 0x02310000 +#define CLOCK_BASE K2HK_PLL_CNTRL_BASE +#define K2HK_PSC_BASE 0x02350000 +#define KS2_DEVICE_STATE_CTRL_BASE 0x02620000 +#define JTAG_ID_REG (KS2_DEVICE_STATE_CTRL_BASE + 0x18) +#define K2HK_DEVSTAT (KS2_DEVICE_STATE_CTRL_BASE + 0x20) + +#define K2HK_MISC_CTRL (KS2_DEVICE_STATE_CTRL_BASE + 0xc7c) + +#define ARM_PLL_EN BIT(13) + +#define K2HK_SPI0_BASE 0x21000400 +#define K2HK_SPI1_BASE 0x21000600 +#define K2HK_SPI2_BASE 0x21000800 +#define K2HK_SPI_BASE K2HK_SPI0_BASE + +/* Chip configuration unlock codes and registers */ +#define KEYSTONE_KICK0 (KS2_DEVICE_STATE_CTRL_BASE+0x38) +#define KEYSTONE_KICK1 (KS2_DEVICE_STATE_CTRL_BASE+0x3c) +#define KEYSTONE_KICK0_MAGIC 0x83e70b13 +#define KEYSTONE_KICK1_MAGIC 0x95a4f1e0 + +/* PA SS Registers */ +#define KS2_PASS_BASE 0x02000000 + +/* PLL control registers */ +#define K2HK_MAINPLLCTL0 (KS2_DEVICE_STATE_CTRL_BASE+0x350) +#define K2HK_MAINPLLCTL1 (KS2_DEVICE_STATE_CTRL_BASE+0x354) +#define K2HK_PASSPLLCTL0 (KS2_DEVICE_STATE_CTRL_BASE+0x358) +#define K2HK_PASSPLLCTL1 (KS2_DEVICE_STATE_CTRL_BASE+0x35C) +#define K2HK_DDR3APLLCTL0 (KS2_DEVICE_STATE_CTRL_BASE+0x360) +#define K2HK_DDR3APLLCTL1 (KS2_DEVICE_STATE_CTRL_BASE+0x364) +#define K2HK_DDR3BPLLCTL0 (KS2_DEVICE_STATE_CTRL_BASE+0x368) +#define K2HK_DDR3BPLLCTL1 (KS2_DEVICE_STATE_CTRL_BASE+0x36C) +#define K2HK_ARMPLLCTL0 (KS2_DEVICE_STATE_CTRL_BASE+0x370) +#define K2HK_ARMPLLCTL1 (KS2_DEVICE_STATE_CTRL_BASE+0x374) + +/* Power and Sleep Controller (PSC) Domains */ +#define K2HK_LPSC_MOD 0 +#define K2HK_LPSC_DUMMY1 1 +#define K2HK_LPSC_USB 2 +#define K2HK_LPSC_EMIF25_SPI 3 +#define K2HK_LPSC_TSIP 4 +#define K2HK_LPSC_DEBUGSS_TRC 5 +#define K2HK_LPSC_TETB_TRC 6 +#define K2HK_LPSC_PKTPROC 7 +#define KS2_LPSC_PA K2HK_LPSC_PKTPROC +#define K2HK_LPSC_SGMII 8 +#define KS2_LPSC_CPGMAC K2HK_LPSC_SGMII +#define K2HK_LPSC_CRYPTO 9 +#define K2HK_LPSC_PCIE 10 +#define K2HK_LPSC_SRIO 11 +#define K2HK_LPSC_VUSR0 12 +#define K2HK_LPSC_CHIP_SRSS 13 +#define K2HK_LPSC_MSMC 14 +#define K2HK_LPSC_GEM_0 15 +#define K2HK_LPSC_GEM_1 16 +#define K2HK_LPSC_GEM_2 17 +#define K2HK_LPSC_GEM_3 18 +#define K2HK_LPSC_GEM_4 19 +#define K2HK_LPSC_GEM_5 20 +#define K2HK_LPSC_GEM_6 21 +#define K2HK_LPSC_GEM_7 22 +#define K2HK_LPSC_EMIF4F_DDR3A 23 +#define K2HK_LPSC_EMIF4F_DDR3B 24 +#define K2HK_LPSC_TAC 25 +#define K2HK_LPSC_RAC 26 +#define K2HK_LPSC_RAC_1 27 +#define K2HK_LPSC_FFTC_A 28 +#define K2HK_LPSC_FFTC_B 29 +#define K2HK_LPSC_FFTC_C 30 +#define K2HK_LPSC_FFTC_D 31 +#define K2HK_LPSC_FFTC_E 32 +#define K2HK_LPSC_FFTC_F 33 +#define K2HK_LPSC_AI2 34 +#define K2HK_LPSC_TCP3D_0 35 +#define K2HK_LPSC_TCP3D_1 36 +#define K2HK_LPSC_TCP3D_2 37 +#define K2HK_LPSC_TCP3D_3 38 +#define K2HK_LPSC_VCP2X4_A 39 +#define K2HK_LPSC_CP2X4_B 40 +#define K2HK_LPSC_VCP2X4_C 41 +#define K2HK_LPSC_VCP2X4_D 42 +#define K2HK_LPSC_VCP2X4_E 43 +#define K2HK_LPSC_VCP2X4_F 44 +#define K2HK_LPSC_VCP2X4_G 45 +#define K2HK_LPSC_VCP2X4_H 46 +#define K2HK_LPSC_BCP 47 +#define K2HK_LPSC_DXB 48 +#define K2HK_LPSC_VUSR1 49 +#define K2HK_LPSC_XGE 50 +#define K2HK_LPSC_ARM_SREFLEX 51 +#define K2HK_LPSC_TETRIS 52 + +#define K2HK_UART0_BASE 0x02530c00 + +/* DDR3A definitions */ +#define K2HK_DDR3A_EMIF_CTRL_BASE 0x21010000 +#define K2HK_DDR3A_EMIF_DATA_BASE 0x80000000 +#define K2HK_DDR3A_DDRPHYC 0x02329000 +/* DDR3B definitions */ +#define K2HK_DDR3B_EMIF_CTRL_BASE 0x21020000 +#define K2HK_DDR3B_EMIF_DATA_BASE 0x60000000 +#define K2HK_DDR3B_DDRPHYC 0x02328000 + +/* Queue manager */ +#define DEVICE_QM_MANAGER_BASE 0x02a02000 +#define DEVICE_QM_DESC_SETUP_BASE 0x02a03000 +#define DEVICE_QM_MANAGER_QUEUES_BASE 0x02a80000 +#define DEVICE_QM_MANAGER_Q_PROXY_BASE 0x02ac0000 +#define DEVICE_QM_QUEUE_STATUS_BASE 0x02a40000 +#define DEVICE_QM_NUM_LINKRAMS 2 +#define DEVICE_QM_NUM_MEMREGIONS 20 + +#define DEVICE_PA_CDMA_GLOBAL_CFG_BASE 0x02004000 +#define DEVICE_PA_CDMA_TX_CHAN_CFG_BASE 0x02004400 +#define DEVICE_PA_CDMA_RX_CHAN_CFG_BASE 0x02004800 +#define DEVICE_PA_CDMA_RX_FLOW_CFG_BASE 0x02005000 + +#define DEVICE_PA_CDMA_RX_NUM_CHANNELS 24 +#define DEVICE_PA_CDMA_RX_NUM_FLOWS 32 +#define DEVICE_PA_CDMA_TX_NUM_CHANNELS 9 + +/* MSMC control */ +#define K2HK_MSMC_CTRL_BASE 0x0bc00000 + +#endif /* __ASM_ARCH_HARDWARE_H */ diff --git a/arch/arm/include/asm/arch-keystone/hardware.h b/arch/arm/include/asm/arch-keystone/hardware.h new file mode 100644 index 0000000..a72686d --- /dev/null +++ b/arch/arm/include/asm/arch-keystone/hardware.h @@ -0,0 +1,175 @@ +/* + * Keystone2: Common SoC definitions, structures etc. + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef __ASM_ARCH_HARDWARE_H +#define __ASM_ARCH_HARDWARE_H + +#include <config.h> + +#ifndef __ASSEMBLY__ + +#include <asm/sizes.h> +#include <asm/io.h> + +#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; + +#define ASYNC_EMIF_NUM_CS 4 +#define ASYNC_EMIF_MODE_NOR 0 +#define ASYNC_EMIF_MODE_NAND 1 +#define ASYNC_EMIF_MODE_ONENAND 2 +#define ASYNC_EMIF_PRESERVE -1 + +struct async_emif_config { + unsigned mode; + unsigned select_strobe; + unsigned extend_wait; + unsigned wr_setup; + unsigned wr_strobe; + unsigned wr_hold; + unsigned rd_setup; + unsigned rd_strobe; + unsigned rd_hold; + unsigned turn_around; + enum { + ASYNC_EMIF_8 = 0, + ASYNC_EMIF_16 = 1, + ASYNC_EMIF_32 = 2, + } width; +}; + +void init_async_emif(int num_cs, struct async_emif_config *config); + +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; +}; + +#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 + +#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 + +#ifdef CONFIG_SOC_K2HK +#include <asm/arch/hardware-k2hk.h> +#endif + +#ifndef __ASSEMBLY__ +static inline int cpu_is_k2hk(void) +{ + unsigned int jtag_id = __raw_readl(JTAG_ID_REG); + unsigned int part_no = (jtag_id >> 12) & 0xffff; + + return ((part_no == 0xb981) ? 1 : 0); +} + +static inline int cpu_revision(void) +{ + unsigned int jtag_id = __raw_readl(JTAG_ID_REG); + unsigned int rev = (jtag_id >> 28) & 0xf; + + return rev; +} + +void share_all_segments(int priv_id); +int cpu_to_bus(u32 *ptr, u32 length); +void init_ddrphy(u32 base, struct ddr3_phy_config *phy_cfg); +void init_ddremif(u32 base, struct ddr3_emif_config *emif_cfg); +void init_ddr3(void); +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 new file mode 100644 index 0000000..d425652 --- /dev/null +++ b/arch/arm/include/asm/arch-keystone/i2c_defs.h @@ -0,0 +1,17 @@ +/* + * keystone: i2c driver definitions + * + * (C) Copyright 2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * 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/nand_defs.h b/arch/arm/include/asm/arch-keystone/nand_defs.h new file mode 100644 index 0000000..6d6f846 --- /dev/null +++ b/arch/arm/include/asm/arch-keystone/nand_defs.h @@ -0,0 +1,25 @@ +/* + * nand driver definitions to re-use davinci nand driver on Keystone2 + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * (C) Copyright 2007 Sergey Kubushyn ksi@koi8.net + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _NAND_DEFS_H_ +#define _NAND_DEFS_H_ + +#include <asm/arch/hardware.h> +#include <linux/mtd/nand.h> + +#define MASK_CLE 0x4000 +#define MASK_ALE 0x2000 + +#define NAND_READ_START 0x00 +#define NAND_READ_END 0x30 +#define NAND_STATUS 0x70 + +extern void davinci_nand_init(struct nand_chip *nand); + +#endif diff --git a/arch/arm/include/asm/arch-keystone/psc_defs.h b/arch/arm/include/asm/arch-keystone/psc_defs.h new file mode 100644 index 0000000..e0095d9 --- /dev/null +++ b/arch/arm/include/asm/arch-keystone/psc_defs.h @@ -0,0 +1,90 @@ +/* + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _PSC_DEFS_H_ +#define _PSC_DEFS_H_ + +#include <asm/arch/hardware.h> + +/* + * 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/spl.h b/arch/arm/include/asm/arch-keystone/spl.h new file mode 100644 index 0000000..eb0b3ed --- /dev/null +++ b/arch/arm/include/asm/arch-keystone/spl.h @@ -0,0 +1,12 @@ +/* + * (C) Copyright 2012-2014 + * Texas Instruments, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef _ASM_ARCH_SPL_H_ +#define _ASM_SPL_H_ + +#define BOOT_DEVICE_SPI 2 + +#endif diff --git a/board/ti/k2hk_evm/Makefile b/board/ti/k2hk_evm/Makefile new file mode 100644 index 0000000..3645f2f --- /dev/null +++ b/board/ti/k2hk_evm/Makefile @@ -0,0 +1,9 @@ +# +# K2HK-EVM: board Makefile +# (C) Copyright 2012-2014 +# Texas Instruments Incorporated, <www.ti.com> +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += board.o +obj-y += ddr3.o diff --git a/board/ti/k2hk_evm/README b/board/ti/k2hk_evm/README new file mode 100644 index 0000000..6ab660b --- /dev/null +++ b/board/ti/k2hk_evm/README @@ -0,0 +1,56 @@ +U-Boot port for Texas Instruments XTCIEVMK2X +============================================ + +Author: Murali Karicheri m-karicheri2@ti.com + +This README has information on the u-boot port for XTCIEVMK2X EVM board. +Documentation for this board can be found at + http://www.advantech.com/Support/TI-EVM/EVMK2HX_sd.aspx + +The board is based on Texas Instruments Keystone2 family of SoCs : K2H, K2K. +More details on these SoCs are available at company websites + K2K: http://www.ti.com/product/tci6638k2k + K2H: http://www.ti.com/product/tci6638k2h + +Board configuration: +==================== + +Some of the peripherals that are configured by u-boot are:- + +1. 2GB DDR3 (can support 8GB SO DIMM as well) +2. 512M NAND (over ti emif16 bus) +3. 6MB MSM SRAM (part of the SoC) +4. two 1GBit Ethernet ports (SoC supports upto 4) +5. two UART ports +6. three i2c interfaces +7. three spi interfaces (only 1 interface supported in driver) + +There are seperate PLLs to drive clocks to Tetris ARM and Peripherals. +To bring up SMP Linux on this board, there is a boot monitor +code that will be installed in MSMC SRAM. There is command available +to install this image from u-boot. + +The port related files can be found at following folders + keystone2 SoC related files: arch/arm/cpu/armv7/keystone/ + K2HK evm board files: board/ti/k2hk_evm/ + +board configuration file: include/configs/k2hk_evm.h + +Supported boot modes: + - SPI NOR boot + +Supported image formats:- + - u-boot.bin: for loading and running u-boot.bin through Texas instruments + code composure studio (CCS) + - u-boot-spi.gph: gpimage for programming SPI NOR flash for SPI NOR boot + +Build instructions: +=================== + +To build u-boot.bin + >make k2hk_evm_config + >make u-boot-spi.gph + +To build u-boot-spi.gph + >make k2hk_evm_config + >make u-boot-spi.gph diff --git a/board/ti/k2hk_evm/board.c b/board/ti/k2hk_evm/board.c new file mode 100644 index 0000000..14dc7e4 --- /dev/null +++ b/board/ti/k2hk_evm/board.c @@ -0,0 +1,236 @@ +/* + * K2HK EVM : Board initialization + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <exports.h> +#include <fdt_support.h> +#include <libfdt.h> + +#include <asm/arch/hardware.h> +#include <asm/arch/clock.h> +#include <asm/io.h> +#include <asm/mach-types.h> +#include <asm/arch/nand_defs.h> +#include <asm/arch/psc_defs.h> + +DECLARE_GLOBAL_DATA_PTR; + +u32 device_big_endian; + +unsigned int external_clk[ext_clk_count] = { + [sys_clk] = 122880000, + [alt_core_clk] = 125000000, + [pa_clk] = 122880000, + [tetris_clk] = 125000000, + [ddr3a_clk] = 100000000, + [ddr3b_clk] = 100000000, + [mcm_clk] = 312500000, + [pcie_clk] = 100000000, + [sgmii_srio_clk] = 156250000, + [xgmii_clk] = 156250000, + [usb_clk] = 100000000, + [rp1_clk] = 123456789 /* TODO: cannot find + what is that */ +}; + +static struct async_emif_config async_emif_config[ASYNC_EMIF_NUM_CS] = { + { /* CS0 */ + .mode = ASYNC_EMIF_MODE_NAND, + .wr_setup = 0xf, + .wr_strobe = 0x3f, + .wr_hold = 7, + .rd_setup = 0xf, + .rd_strobe = 0x3f, + .rd_hold = 7, + .turn_around = 3, + .width = ASYNC_EMIF_8, + }, + +}; + +static struct pll_init_data pll_config[] = { + CORE_PLL_1228, + PASS_PLL_983, + TETRIS_PLL_1200, +}; + +int dram_init(void) +{ + init_ddr3(); + + gd->ram_size = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, + CONFIG_MAX_RAM_BANK_SIZE); + init_async_emif(ARRAY_SIZE(async_emif_config), async_emif_config); + return 0; +} + +/* Byte swap the 32-bit data if the device is BE */ +int cpu_to_bus(u32 *ptr, u32 length) +{ + u32 i; + + if (device_big_endian) + for (i = 0; i < length; i++, ptr++) + *ptr = __swab32(*ptr); + + return 0; +} + +#if defined(CONFIG_BOARD_EARLY_INIT_F) +int board_early_init_f(void) +{ + init_plls(ARRAY_SIZE(pll_config), pll_config); + return 0; +} +#endif + +int board_init(void) +{ + gd->bd->bi_boot_params = LINUX_BOOT_PARAM_ADDR; + + return 0; +} + +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) +#define K2_DDR3_START_ADDR 0x80000000 +void ft_board_setup(void *blob, bd_t *bd) +{ + u64 start[2]; + u64 size[2]; + char name[32], *env, *endp; + int lpae, nodeoffset; + u32 ddr3a_size; + int nbanks; + + env = getenv("mem_lpae"); + lpae = env && simple_strtol(env, NULL, 0); + + ddr3a_size = 0; + if (lpae) { + env = getenv("ddr3a_size"); + if (env) + ddr3a_size = simple_strtol(env, NULL, 10); + if ((ddr3a_size != 8) && (ddr3a_size != 4)) + ddr3a_size = 0; + } + + nbanks = 1; + start[0] = bd->bi_dram[0].start; + size[0] = bd->bi_dram[0].size; + + /* adjust memory start address for LPAE */ + if (lpae) { + start[0] -= K2_DDR3_START_ADDR; + start[0] += CONFIG_SYS_LPAE_SDRAM_BASE; + } + + if ((size[0] == 0x80000000) && (ddr3a_size != 0)) { + size[1] = ((u64)ddr3a_size - 2) << 30; + start[1] = 0x880000000; + nbanks++; + } + + /* reserve memory at start of bank */ + sprintf(name, "mem_reserve_head"); + env = getenv(name); + if (env) { + start[0] += ustrtoul(env, &endp, 0); + size[0] -= ustrtoul(env, &endp, 0); + } + + sprintf(name, "mem_reserve"); + env = getenv(name); + if (env) + size[0] -= ustrtoul(env, &endp, 0); + + fdt_fixup_memory_banks(blob, start, size, nbanks); + + /* Fix up the initrd */ + if (lpae) { + u64 initrd_start, initrd_end; + u32 *prop1, *prop2; + int err; + nodeoffset = fdt_path_offset(blob, "/chosen"); + if (nodeoffset >= 0) { + prop1 = (u32 *)fdt_getprop(blob, nodeoffset, + "linux,initrd-start", NULL); + prop2 = (u32 *)fdt_getprop(blob, nodeoffset, + "linux,initrd-end", NULL); + if (prop1 && prop2) { + initrd_start = __be32_to_cpu(*prop1); + initrd_start -= K2_DDR3_START_ADDR; + initrd_start += CONFIG_SYS_LPAE_SDRAM_BASE; + initrd_start = __cpu_to_be64(initrd_start); + initrd_end = __be32_to_cpu(*prop2); + initrd_end -= K2_DDR3_START_ADDR; + initrd_end += CONFIG_SYS_LPAE_SDRAM_BASE; + initrd_end = __cpu_to_be64(initrd_end); + + err = fdt_delprop(blob, nodeoffset, + "linux,initrd-start"); + if (err < 0) + printf("error deleting linux,initrd-start\n"); + + err = fdt_delprop(blob, nodeoffset, + "linux,initrd-end"); + if (err < 0) + printf("error deleting linux,initrd-end\n"); + + err = fdt_setprop(blob, nodeoffset, + "linux,initrd-start", + &initrd_start, + sizeof(initrd_start)); + if (err < 0) + printf("error adding linux,initrd-start\n"); + + err = fdt_setprop(blob, nodeoffset, + "linux,initrd-end", + &initrd_end, + sizeof(initrd_end)); + if (err < 0) + printf("error adding linux,initrd-end\n"); + } + } + } +} + +void ft_board_setup_ex(void *blob, bd_t *bd) +{ + int lpae; + char *env; + u64 *reserve_start, size; + + env = getenv("mem_lpae"); + lpae = env && simple_strtol(env, NULL, 0); + + if (lpae) { + /* + * the initrd and other reserved memory areas are + * embedded in in the DTB itslef. fix up these addresses + * to 36 bit format + */ + reserve_start = (u64 *)((char *)blob + + fdt_off_mem_rsvmap(blob)); + while (1) { + *reserve_start = __cpu_to_be64(*reserve_start); + size = __cpu_to_be64(*(reserve_start + 1)); + if (size) { + *reserve_start -= K2_DDR3_START_ADDR; + *reserve_start += + CONFIG_SYS_LPAE_SDRAM_BASE; + *reserve_start = + __cpu_to_be64(*reserve_start); + } else { + break; + } + reserve_start += 2; + } + } +} +#endif diff --git a/board/ti/k2hk_evm/ddr3.c b/board/ti/k2hk_evm/ddr3.c new file mode 100644 index 0000000..973c35d --- /dev/null +++ b/board/ti/k2hk_evm/ddr3.c @@ -0,0 +1,269 @@ +/* + * Keystone2: DDR3 initialization + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/hardware.h> +#include <asm/io.h> +#include <i2c.h> + +/************************* *****************************/ +static struct ddr3_phy_config ddr3phy_1600_64A = { + .pllcr = 0x0001C000ul, + .pgcr1_mask = (IODDRM_MASK | ZCKSEL_MASK), + .pgcr1_val = ((1 << 2) | (1 << 7) | (1 << 23)), + .ptr0 = 0x42C21590ul, + .ptr1 = 0xD05612C0ul, + .ptr2 = 0, /* not set in gel */ + .ptr3 = 0x0D861A80ul, + .ptr4 = 0x0C827100ul, + .dcr_mask = (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK | NOSRA_MASK), + .dcr_val = ((1 << 10) | (1 << 27)), + .dtpr0 = 0xA19DBB66ul, + .dtpr1 = 0x12868300ul, + .dtpr2 = 0x50035200ul, + .mr0 = 0x00001C70ul, + .mr1 = 0x00000006ul, + .mr2 = 0x00000018ul, + .dtcr = 0x730035C7ul, + .pgcr2 = 0x00F07A12ul, + .zq0cr1 = 0x0000005Dul, + .zq1cr1 = 0x0000005Bul, + .zq2cr1 = 0x0000005Bul, + .pir_v1 = 0x00000033ul, + .pir_v2 = 0x0000FF81ul, +}; + +static struct ddr3_emif_config ddr3_1600_64 = { + .sdcfg = 0x6200CE6aul, + .sdtim1 = 0x16709C55ul, + .sdtim2 = 0x00001D4Aul, + .sdtim3 = 0x435DFF54ul, + .sdtim4 = 0x553F0CFFul, + .zqcfg = 0xF0073200ul, + .sdrfc = 0x00001869ul, +}; + +static struct ddr3_phy_config ddr3phy_1600_32 = { + .pllcr = 0x0001C000ul, + .pgcr1_mask = (IODDRM_MASK | ZCKSEL_MASK), + .pgcr1_val = ((1 << 2) | (1 << 7) | (1 << 23)), + .ptr0 = 0x42C21590ul, + .ptr1 = 0xD05612C0ul, + .ptr2 = 0, /* not set in gel */ + .ptr3 = 0x0D861A80ul, + .ptr4 = 0x0C827100ul, + .dcr_mask = (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK | NOSRA_MASK), + .dcr_val = ((1 << 10) | (1 << 27)), + .dtpr0 = 0xA19DBB66ul, + .dtpr1 = 0x12868300ul, + .dtpr2 = 0x50035200ul, + .mr0 = 0x00001C70ul, + .mr1 = 0x00000006ul, + .mr2 = 0x00000018ul, + .dtcr = 0x730035C7ul, + .pgcr2 = 0x00F07A12ul, + .zq0cr1 = 0x0000005Dul, + .zq1cr1 = 0x0000005Bul, + .zq2cr1 = 0x0000005Bul, + .pir_v1 = 0x00000033ul, + .pir_v2 = 0x0000FF81ul, +}; + +static struct ddr3_emif_config ddr3_1600_32 = { + .sdcfg = 0x6200DE6aul, + .sdtim1 = 0x16709C55ul, + .sdtim2 = 0x00001D4Aul, + .sdtim3 = 0x435DFF54ul, + .sdtim4 = 0x553F0CFFul, + .zqcfg = 0x70073200ul, + .sdrfc = 0x00001869ul, +}; + +/************************* *****************************/ +static struct ddr3_phy_config ddr3phy_1333_64A = { + .pllcr = 0x0005C000ul, + .pgcr1_mask = (IODDRM_MASK | ZCKSEL_MASK), + .pgcr1_val = ((1 << 2) | (1 << 7) | (1 << 23)), + .ptr0 = 0x42C21590ul, + .ptr1 = 0xD05612C0ul, + .ptr2 = 0, /* not set in gel */ + .ptr3 = 0x0B4515C2ul, + .ptr4 = 0x0A6E08B4ul, + .dcr_mask = (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK | + NOSRA_MASK | UDIMM_MASK), + .dcr_val = ((1 << 10) | (1 << 27) | (1 << 29)), + .dtpr0 = 0x8558AA55ul, + .dtpr1 = 0x12857280ul, + .dtpr2 = 0x5002C200ul, + .mr0 = 0x00001A60ul, + .mr1 = 0x00000006ul, + .mr2 = 0x00000010ul, + .dtcr = 0x710035C7ul, + .pgcr2 = 0x00F065B8ul, + .zq0cr1 = 0x0000005Dul, + .zq1cr1 = 0x0000005Bul, + .zq2cr1 = 0x0000005Bul, + .pir_v1 = 0x00000033ul, + .pir_v2 = 0x0000FF81ul, +}; + +static struct ddr3_emif_config ddr3_1333_64 = { + .sdcfg = 0x62008C62ul, + .sdtim1 = 0x125C8044ul, + .sdtim2 = 0x00001D29ul, + .sdtim3 = 0x32CDFF43ul, + .sdtim4 = 0x543F0ADFul, + .zqcfg = 0xF0073200ul, + .sdrfc = 0x00001457ul, +}; + +static struct ddr3_phy_config ddr3phy_1333_32 = { + .pllcr = 0x0005C000ul, + .pgcr1_mask = (IODDRM_MASK | ZCKSEL_MASK), + .pgcr1_val = ((1 << 2) | (1 << 7) | (1 << 23)), + .ptr0 = 0x42C21590ul, + .ptr1 = 0xD05612C0ul, + .ptr2 = 0, /* not set in gel */ + .ptr3 = 0x0B4515C2ul, + .ptr4 = 0x0A6E08B4ul, + .dcr_mask = (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK | + NOSRA_MASK | UDIMM_MASK), + .dcr_val = ((1 << 10) | (1 << 27) | (1 << 29)), + .dtpr0 = 0x8558AA55ul, + .dtpr1 = 0x12857280ul, + .dtpr2 = 0x5002C200ul, + .mr0 = 0x00001A60ul, + .mr1 = 0x00000006ul, + .mr2 = 0x00000010ul, + .dtcr = 0x710035C7ul, + .pgcr2 = 0x00F065B8ul, + .zq0cr1 = 0x0000005Dul, + .zq1cr1 = 0x0000005Bul, + .zq2cr1 = 0x0000005Bul, + .pir_v1 = 0x00000033ul, + .pir_v2 = 0x0000FF81ul, +}; + +static struct ddr3_emif_config ddr3_1333_32 = { + .sdcfg = 0x62009C62ul, + .sdtim1 = 0x125C8044ul, + .sdtim2 = 0x00001D29ul, + .sdtim3 = 0x32CDFF43ul, + .sdtim4 = 0x543F0ADFul, + .zqcfg = 0xf0073200ul, + .sdrfc = 0x00001457ul, +}; + +/************************* *****************************/ +static struct ddr3_phy_config ddr3phy_1333_64 = { + .pllcr = 0x0005C000ul, + .pgcr1_mask = (IODDRM_MASK | ZCKSEL_MASK), + .pgcr1_val = ((1 << 2) | (1 << 7) | (1 << 23)), + .ptr0 = 0x42C21590ul, + .ptr1 = 0xD05612C0ul, + .ptr2 = 0, /* not set in gel */ + .ptr3 = 0x0B4515C2ul, + .ptr4 = 0x0A6E08B4ul, + .dcr_mask = (PDQ_MASK | MPRDQ_MASK | BYTEMASK_MASK | NOSRA_MASK), + .dcr_val = ((1 << 10) | (1 << 27)), + .dtpr0 = 0x8558AA55ul, + .dtpr1 = 0x12857280ul, + .dtpr2 = 0x5002C200ul, + .mr0 = 0x00001A60ul, + .mr1 = 0x00000006ul, + .mr2 = 0x00000010ul, + .dtcr = 0x710035C7ul, + .pgcr2 = 0x00F065B8ul, + .zq0cr1 = 0x0000005Dul, + .zq1cr1 = 0x0000005Bul, + .zq2cr1 = 0x0000005Bul, + .pir_v1 = 0x00000033ul, + .pir_v2 = 0x0000FF81ul, +}; +/******************************************************/ +int get_dimm_params(char *dimm_name) +{ + u8 spd_params[256]; + int ret; + int old_bus; + + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + + old_bus = i2c_get_bus_num(); + i2c_set_bus_num(1); + + ret = i2c_read(0x53, 0, 1, spd_params, 256); + + i2c_set_bus_num(old_bus); + + dimm_name[0] = '\0'; + + if (ret) { + puts("Cannot read DIMM params\n"); + return 1; + } + + /* + * We need to convert spd data to dimm parameters + * and to DDR3 EMIF and PHY regirsters values. + * For now we just return DIMM type string value. + * Caller may use this value to choose appropriate + * a pre-set DDR3 configuration + */ + + strncpy(dimm_name, (char *)&spd_params[0x80], 18); + dimm_name[18] = '\0'; + + return 0; +} + +struct pll_init_data ddr3a_333 = DDR3_PLL_333(A); +struct pll_init_data ddr3b_333 = DDR3_PLL_333(B); +struct pll_init_data ddr3a_400 = DDR3_PLL_400(A); +struct pll_init_data ddr3b_400 = DDR3_PLL_400(B); + +void init_ddr3(void) +{ + char dimm_name[32]; + + get_dimm_params(dimm_name); + + printf("Detected SO-DIMM [%s]\n", dimm_name); + + if (!strcmp(dimm_name, "18KSF1G72HZ-1G6E2 ")) { + init_pll(&ddr3a_400); + if (cpu_revision() > 0) { + init_ddrphy(K2HK_DDR3A_DDRPHYC, &ddr3phy_1600_64A); + init_ddremif(K2HK_DDR3A_EMIF_CTRL_BASE, &ddr3_1600_64); + printf("DRAM: Capacity 8 GiB (includes reported below)\n"); + } else { + init_ddrphy(K2HK_DDR3A_DDRPHYC, &ddr3phy_1600_32); + init_ddremif(K2HK_DDR3A_EMIF_CTRL_BASE, &ddr3_1600_32); + printf("DRAM: Capacity 4 GiB (includes reported below)\n"); + } + } else if (!strcmp(dimm_name, "SQR-SD3T-2G1333SED")) { + init_pll(&ddr3a_333); + if (cpu_revision() > 0) { + init_ddrphy(K2HK_DDR3A_DDRPHYC, &ddr3phy_1333_64A); + init_ddremif(K2HK_DDR3A_EMIF_CTRL_BASE, &ddr3_1333_64); + } else { + init_ddrphy(K2HK_DDR3A_DDRPHYC, &ddr3phy_1333_32); + init_ddremif(K2HK_DDR3A_EMIF_CTRL_BASE, &ddr3_1333_32); + } + } else { + printf("Unknown SO-DIMM. Cannot configure DDR3\n"); + while (1) + ; + } + + init_pll(&ddr3b_333); + init_ddrphy(K2HK_DDR3B_DDRPHYC, &ddr3phy_1333_64); + init_ddremif(K2HK_DDR3B_EMIF_CTRL_BASE, &ddr3_1333_64); +} + diff --git a/boards.cfg b/boards.cfg index a8336cc..1690315 100644 --- a/boards.cfg +++ b/boards.cfg @@ -362,6 +362,7 @@ Active arm armv7 zynq xilinx zynq zynq_microzed - Active arm armv7 zynq xilinx zynq zynq_zc770_xm010 zynq_zc770:ZC770_XM010 Michal Simek monstr@monstr.eu:Jagannadha Sutradharudu Teki jaganna@xilinx.com Active arm armv7 zynq xilinx zynq zynq_zc770_xm012 zynq_zc770:ZC770_XM012 Michal Simek monstr@monstr.eu:Jagannadha Sutradharudu Teki jaganna@xilinx.com Active arm armv7 zynq xilinx zynq zynq_zc770_xm013 zynq_zc770:ZC770_XM013 Michal Simek monstr@monstr.eu:Jagannadha Sutradharudu Teki jaganna@xilinx.com +Active arm armv7 keystone ti k2hk_evm k2hk_evm - Vitaly Andrianov vitalya@ti.com Active arm armv7:arm720t tegra114 nvidia dalmore dalmore - Tom Warren twarren@nvidia.com Active arm armv7:arm720t tegra20 avionic-design medcom-wide medcom-wide - Alban Bedel alban.bedel@avionic-design.de Active arm armv7:arm720t tegra20 avionic-design plutux plutux - Alban Bedel alban.bedel@avionic-design.de diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c index fbc37b2..8a13454 100644 --- a/drivers/serial/ns16550.c +++ b/drivers/serial/ns16550.c @@ -30,6 +30,11 @@ #define serial_in(y) readb(y) #endif
+#if defined(CONFIG_K2HK_EVM) +#define UART_REG_VAL_PWREMU_MGMT_UART_DISABLE 0 +#define UART_REG_VAL_PWREMU_MGMT_UART_ENABLE ((1 << 14) | (1 << 13) | (1 << 0)) +#endif + #ifndef CONFIG_SYS_NS16550_IER #define CONFIG_SYS_NS16550_IER 0x00 #endif /* CONFIG_SYS_NS16550_IER */ @@ -77,6 +82,9 @@ void NS16550_init(NS16550_t com_port, int baud_divisor) /* /16 is proper to hit 115200 with 48MHz */ serial_out(0, &com_port->mdr1); #endif /* CONFIG_OMAP */ +#if defined(CONFIG_K2HK_EVM) + serial_out(UART_REG_VAL_PWREMU_MGMT_UART_ENABLE, &com_port->regC); +#endif }
#ifndef CONFIG_NS16550_MIN_FUNCTIONS diff --git a/include/configs/k2hk_evm.h b/include/configs/k2hk_evm.h new file mode 100644 index 0000000..985db8e --- /dev/null +++ b/include/configs/k2hk_evm.h @@ -0,0 +1,221 @@ +/* + * Configuration header file for TI's k2hk-evm + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +/* Platform type */ +#define CONFIG_SOC_K2HK +#define CONFIG_K2HK_EVM + +/* U-Boot Build Configuration */ +#define CONFIG_SKIP_LOWLEVEL_INIT /* U-Boot is a 2nd stage loader */ +#define CONFIG_SYS_NO_FLASH /* that is, no *NOR* flash */ +#define CONFIG_SYS_CONSOLE_INFO_QUIET +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_SYS_THUMB_BUILD + +/* SoC Configuration */ +#define CONFIG_ARMV7 +#define CONFIG_ARCH_CPU_INIT +#define CONFIG_SYS_ARCH_TIMER +#define CONFIG_SYS_HZ 1000 +#define CONFIG_SYS_TEXT_BASE 0x0c001000 +#define CONFIG_OF_LIBFDT 1 +#define CONFIG_OF_BOARD_SETUP +#define CONFIG_SYS_DCACHE_OFF + +/* Memory Configuration */ +#define CONFIG_NR_DRAM_BANKS 2 +#define CONFIG_SYS_SDRAM_BASE 0x80000000 +#define CONFIG_SYS_LPAE_SDRAM_BASE 0x800000000 +#define CONFIG_MAX_RAM_BANK_SIZE (2 << 30) /* 2GB */ +#define CONFIG_STACKSIZE (512 << 10) /* 512 KiB */ +#define CONFIG_SYS_MALLOC_LEN (1024 << 10) /* 1 MiB */ +#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 32 << 20) +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_TEXT_BASE - \ + GENERATED_GBL_DATA_SIZE) + +/* SPL SPI Loader Configuration */ +#define CONFIG_SPL_TEXT_BASE 0x0c200000 +#define CONFIG_SPL_PAD_TO 65536 +#define CONFIG_SPL_MAX_SIZE (CONFIG_SPL_PAD_TO - 8) +#define CONFIG_SPL_BSS_START_ADDR (CONFIG_SPL_TEXT_BASE + \ + CONFIG_SPL_MAX_SIZE) +#define CONFIG_SPL_BSS_MAX_SIZE (32 * 1024) +#define CONFIG_SYS_SPL_MALLOC_START (CONFIG_SPL_BSS_START_ADDR + \ + CONFIG_SPL_BSS_MAX_SIZE) +#define CONFIG_SYS_SPL_MALLOC_SIZE (32 * 1024) +#define CONFIG_SPL_STACK_SIZE (8 * 1024) +#define CONFIG_SPL_STACK (CONFIG_SYS_SPL_MALLOC_START + \ + CONFIG_SYS_SPL_MALLOC_SIZE + \ + CONFIG_SPL_STACK_SIZE - 4) +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_SERIAL_SUPPORT +#define CONFIG_SPL_SPI_FLASH_SUPPORT +#define CONFIG_SPL_SPI_SUPPORT +#define CONFIG_SPL_BOARD_INIT +#define CONFIG_SPL_SPI_LOAD +#define CONFIG_SPL_SPI_BUS 0 +#define CONFIG_SPL_SPI_CS 0 +#define CONFIG_SYS_SPI_U_BOOT_OFFS CONFIG_SPL_PAD_TO +#define CONFIG_SPL_FRAMEWORK + +/* UART Configuration */ +#define CONFIG_SYS_NS16550 +#define CONFIG_SYS_NS16550_SERIAL +#define CONFIG_SYS_NS16550_MEM32 +#define CONFIG_SYS_NS16550_REG_SIZE -4 +#define CONFIG_SYS_NS16550_COM1 K2HK_UART0_BASE +#define CONFIG_SYS_NS16550_CLK clk_get_rate(K2HK_CLK1_6) +#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 } +#define CONFIG_CONS_INDEX 1 +#define CONFIG_BAUDRATE 115200 + +/* SPI Configuration */ +#define CONFIG_SPI +#define CONFIG_SPI_FLASH +#define CONFIG_SPI_FLASH_STMICRO +#define CONFIG_DAVINCI_SPI +#define CONFIG_SYS_SPI_BASE K2HK_SPI_BASE +#define CONFIG_SYS_SPI_CLK clk_get_rate(K2HK_LPSC_EMIF25_SPI) +#define CONFIG_SF_DEFAULT_SPEED 30000000 +#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED + +/* I2C Configuration */ +#define CONFIG_HARD_I2C +#define CONFIG_DRIVER_DAVINCI_I2C +#define CONFIG_SYS_I2C_SPEED 100000 +#define CONFIG_SYS_I2C_SLAVE 0x10 /* SMBus host address */ +#define CONFIG_I2C_MULTI_BUS 1 +#define I2C_BUS_MAX 3 + +/* EEPROM definitions */ +#define CONFIG_SYS_I2C_MULTI_EEPROMS +#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2 +#define CONFIG_SYS_I2C_EEPROM_ADDR 0x50 +#define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 6 +#define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 20 +#define CONFIG_ENV_EEPROM_IS_ON_I2C + +/* NAND Configuration */ +#define CONFIG_NAND_DAVINCI +#define CONFIG_SYS_NAND_CS 2 +#define CONFIG_SYS_NAND_USE_FLASH_BBT +#define CONFIG_SYS_NAND_4BIT_HW_ECC_OOBFIRST +#define CONFIG_SYS_NAND_PAGE_2K + +#define CONFIG_SYS_NAND_LARGEPAGE +#define CONFIG_SYS_NAND_BASE_LIST { 0x30000000, } +#define CONFIG_SYS_MAX_NAND_DEVICE 1 +#define CONFIG_SYS_NAND_MAX_CHIPS 1 +#define CONFIG_SYS_NAND_NO_SUBPAGE_WRITE +#define CONFIG_ENV_SIZE (256 << 10) /* 256 KiB */ +#define CONFIG_ENV_IS_IN_NAND +#define CONFIG_ENV_OFFSET 0x100000 +#define CONFIG_MTD_PARTITIONS +#define CONFIG_MTD_DEVICE +#define CONFIG_RBTREE +#define CONFIG_LZO +#define MTDIDS_DEFAULT "nand0=davinci_nand.0" +#define PART_BOOT "1024k(bootloader)ro," +#define PART_PARAMS "512k(params)ro," +#define PART_UBI "-(ubifs)" +#define MTDPARTS_DEFAULT "mtdparts=davinci_nand.0:" \ + PART_BOOT PART_PARAMS PART_UBI + +/* U-Boot command configuration */ +#include <config_cmd_default.h> +#undef CONFIG_CMD_BDI +#undef CONFIG_CMD_FLASH +#undef CONFIG_CMD_FPGA +#undef CONFIG_CMD_SETGETDCR +#define CONFIG_CMD_ASKENV +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_I2C +#define CONFIG_CMD_PING +#define CONFIG_CMD_SAVES +#define CONFIG_CMD_MTDPARTS +#define CONFIG_CMD_NAND +#define CONFIG_CMD_UBI +#define CONFIG_CMD_UBIFS +#define CONFIG_CMD_SF +#define CONFIG_CMD_EEPROM + +/* U-Boot general configuration */ +#define CONFIG_SYS_PROMPT "K2HK EVM # " +#define CONFIG_SYS_CBSIZE 1024 +#define CONFIG_SYS_PBSIZE 2048 +#define CONFIG_SYS_MAXARGS 16 +#define CONFIG_SYS_HUSH_PARSER +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " +#define CONFIG_SYS_LONGHELP +#define CONFIG_CRC32_VERIFY +#define CONFIG_MX_CYCLIC +#define CONFIG_CMDLINE_EDITING +#define CONFIG_VERSION_VARIABLE +#define CONFIG_TIMESTAMP + +#define CONFIG_BOOTDELAY 3 +#define CONFIG_BOOTFILE "uImage" +#define CONFIG_EXTRA_ENV_SETTINGS \ + "boot=ramfs\0" \ + "tftp_root=/\0" \ + "nfs_root=/export\0" \ + "mem_lpae=1\0" \ + "mem_reserve=512M\0" \ + "addr_fdt=0x87000000\0" \ + "addr_kern=0x88000000\0" \ + "addr_mon=0x0c5f0000\0" \ + "addr_uboot=0x87000000\0" \ + "addr_fs=0x82000000\0" \ + "addr_ubi=0x82000000\0" \ + "fdt_high=0xffffffff\0" \ + "run_mon=mon_install ${addr_mon}\0" \ + "run_kern=bootm ${addr_kern} - ${addr_fdt}\0" \ + "init_ubi=run args_all args_ubi; " \ + "ubi part ubifs; ubifsmount boot\0" \ + "get_fdt_ubi=ubifsload ${addr_fdt} ${name_fdt}\0" \ + "get_kern_ubi=ubifsload ${addr_kern} ${name_kern}\0" \ + "get_mon_ubi=ubifsload ${addr_mon} ${name_mon}\0" \ + "burn_uboot=sf probe; sf erase 0 0x100000; " \ + "sf write ${addr_uboot} 0 ${filesize}\0" \ + "args_all=setenv bootargs console=ttyS0,115200n8 rootwait=1\0" \ + "args_ubi=setenv bootargs ${bootargs} rootfstype=ubifs " \ + "root=ubi0:rootfs rootflags=sync rw ubi.mtd=2,2048\0" \ + "burn_ubi=nand erase.part ubifs; " \ + "nand write ${addr_ubi} ubifs ${filesize}\0" \ + "init_ramfs=run args_all args_ramfs get_fs_ramfs\0" \ + "args_ramfs=setenv bootargs ${bootargs} earlyprintk " \ + "rdinit=/sbin/init rw root=/dev/ram0 " \ + "initrd=0x802000000,9M\0" \ + "mtdparts=mtdparts=davinci_nand.0:" \ + "1024k(bootloader)ro,512k(params)ro,522752k(ubifs)\0" +#define CONFIG_BOOTCOMMAND \ + "run init_${boot} get_fdt_${boot} get_mon_${boot} " \ + "get_kern_${boot} run_mon run_kern" +#define CONFIG_BOOTARGS \ + +/* Linux interfacing */ +#define CONFIG_CMDLINE_TAG +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_SYS_BARGSIZE 1024 +#define CONFIG_SYS_LOAD_ADDR (CONFIG_SYS_SDRAM_BASE + 0x08000000) +#define LINUX_BOOT_PARAM_ADDR (CONFIG_SYS_SDRAM_BASE + 0x100) + +#define CONFIG_SUPPORT_RAW_INITRD + +/* we may include files below only after all above definitions */ +#include <asm/arch/hardware.h> +#include <asm/arch/clock.h> +#define CONFIG_SYS_HZ_CLOCK clk_get_rate(K2HK_CLK1_6) + +#endif /* __CONFIG_H */

On Thu, Feb 20, 2014 at 12:55:10PM -0500, Murali Karicheri wrote:
From: Vitaly Andrianov vitalya@ti.com
k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler SoC. Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please refer the ti/k2hk_evm/README for details on the board, build and other information.
This patch add support for keystone architecture and k2hk evm.
Signed-off-by: Vitaly Andrianov vitalya@ti.com Signed-off-by: Murali Karicheri m-karicheri2@ti.com Signed-off-by: WingMan Kwok w-kwok2@ti.com Signed-off-by: Sandeep Nair sandeep_n@ti.com
[snip]
diff --git a/Makefile b/Makefile index 47a03e3..ea2a387 100644 --- a/Makefile +++ b/Makefile @@ -491,6 +491,23 @@ $(obj)u-boot.spr: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin --pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0xff $@ cat $(obj)u-boot.img >> $@
+$(obj)u-boot-spi.gph: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin
$(obj)tools/mkimage -A $(ARCH) -T gpimage -C none \
-a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) \
-n SPL -d $(obj)spl/u-boot-spl.bin $(obj)spl/u-boot-spl.gph
$(OBJCOPY) ${OBJCFLAGS} -I binary \
--pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0 -O binary \
$(obj)spl/u-boot-spl.gph $(obj)spl/u-boot-spl-pad.gph
cat $(obj)spl/u-boot-spl-pad.gph $(obj)u-boot.img > $@
+$(obj)u-boot-nand.gph: $(obj)u-boot.bin
$(obj)tools/mkimage -A $(ARCH) -T gpimage -C none \
-a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) \
-n U-Boot -d $(obj)u-boot.bin $(obj)gph-u-boot.bin
@dd if=/dev/zero of=$(obj)zero.bin bs=8 count=1 2>/dev/null
@cat $(obj)gph-u-boot.bin $(obj)zero.bin > $@
@rm $(obj)zero.bin
First, these need re-writing for Kbuild. Second, we don't ever use u-boot-nand.gph or talk about it in the README, do we?
[snip]
+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) {
sdelay(210000);
Comments on the delay please.
diff --git a/arch/arm/cpu/armv7/keystone/config.mk b/arch/arm/cpu/armv7/keystone/config.mk new file mode 100644 index 0000000..1c8769c --- /dev/null +++ b/arch/arm/cpu/armv7/keystone/config.mk @@ -0,0 +1,15 @@ +# (C) Copyright 2012-2014 +# Texas Instruments Incorporated, <www.ti.com> +# SPDX-License-Identifier: GPL-2.0+ +#
+PLATFORM_RELFLAGS += -fno-common -ffixed-r8 -msoft-float
This is incorrect and not needed.
+# ========================================================================= +# +# Supply options according to compiler version +# +# ========================================================================= +PF_CPPFLAGS_SLB +=$(call cc-option,-mshort-load-bytes,\
$(call cc-option,-malignment-traps,))
+PLATFORM_RELFLAGS += $(PF_CPPFLAGS_SLB)
Also not needed.
diff --git a/arch/arm/cpu/armv7/keystone/init.c b/arch/arm/cpu/armv7/keystone/init.c new file mode 100644 index 0000000..1b7e52a --- /dev/null +++ b/arch/arm/cpu/armv7/keystone/init.c
[snip]
+void reset_cpu(ulong addr) +{
- volatile u32 *rstctrl = (volatile u32 *)(CLOCK_BASE + 0xe8);
- u32 tmp;
- tmp = *rstctrl & 0xffff0000;
- *rstctrl = tmp | 0x5a69;
- *rstctrl &= 0xfffe0000;
Comments / define these please.
+++ b/arch/arm/cpu/armv7/keystone/psc.c
[snip]
+/*
- 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.
Rewrap these lines please, and anywhere else things are too long.
+++ b/arch/arm/cpu/armv7/keystone/spl.c
[snip]
+u32 spl_boot_device(void) +{ +#if defined(CONFIG_SPL_SPI_LOAD)
- return BOOT_DEVICE_SPI;
+#else
- puts("Unknown boot device\n");
- hang();
+#endif
return -EINVAL (or define and use BOOT_DEVICE_UNKNOWN) and fall back to the common hang() case please.
- u32 __pad0;
General form is resvN.
[snip]
+struct davinci_emif_regs {
- u_int32_t ercsr;
Generally we do uint32_t
[snip]
+#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;
Where are we using this? This looks like older davinci drivers that aren't being proper about using structs to define the hardware and need to be converted as part of this effort. I'm not disagreeable with seeing that be a later part of the initial series, since you'll have to convert davinci stuff too and I realize you might not have easy access to the davinci parts for run time testing of the conversion so having K2 work will be important.
+++ b/board/ti/k2hk_evm/README
[snip]
What's missing here and I'd like to see is flashing instructions.
+Build instructions: +===================
+To build u-boot.bin
make k2hk_evm_config make u-boot-spi.gph+To build u-boot-spi.gph
make k2hk_evm_config make u-boot-spi.gph
We need to use CONFIG_SPL_TARGET so that make all just works.
if (err < 0)
printf("error deleting linux,initrd-start\n");
Here and elsewhere, puts when we aren't using format chars.
diff --git a/boards.cfg b/boards.cfg index a8336cc..1690315 100644 --- a/boards.cfg +++ b/boards.cfg
Please make sure that the entry is correctly sorted, see the top of boards.cfg.
+++ b/include/configs/k2hk_evm.h @@ -0,0 +1,221 @@ +/*
- Configuration header file for TI's k2hk-evm
- (C) Copyright 2012-2014
Texas Instruments Incorporated, <www.ti.com>
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef __CONFIG_H
Please use __CONFIG_K2HK_EVM_H
+/* Platform type */ +#define CONFIG_SOC_K2HK +#define CONFIG_K2HK_EVM
Make sure we use these.
+/* U-Boot Build Configuration */ +#define CONFIG_SKIP_LOWLEVEL_INIT /* U-Boot is a 2nd stage loader */
So there's a level before SPL that is doing a certain amount of init we don't want to re-do?
+#define CONFIG_SYS_DCACHE_OFF
Really?
+#define CONFIG_SYS_MALLOC_LEN (1024 << 10) /* 1 MiB */
This is pretty small, especially since we care about UBI.
+#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 32 << 20)
Please see doc/README.memory-test
+/* SPL SPI Loader Configuration */ +#define CONFIG_SPL_TEXT_BASE 0x0c200000 +#define CONFIG_SPL_PAD_TO 65536 +#define CONFIG_SPL_MAX_SIZE (CONFIG_SPL_PAD_TO - 8)
Please explain this a bit more, esp since SPL_PAD_TO should take into account the header size already...
+#define CONFIG_SPL_BSS_START_ADDR (CONFIG_SPL_TEXT_BASE + \
CONFIG_SPL_MAX_SIZE)
+#define CONFIG_SPL_BSS_MAX_SIZE (32 * 1024)
Do we really want SPL BSS in early ram (I don't want to get the name of the type wrong) rather than DDR?
+#define CONFIG_SYS_SPL_MALLOC_START (CONFIG_SPL_BSS_START_ADDR + \
CONFIG_SPL_BSS_MAX_SIZE)
+#define CONFIG_SYS_SPL_MALLOC_SIZE (32 * 1024)
Same.
+#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
Please use the default table.
+#define PART_BOOT "1024k(bootloader)ro," +#define PART_PARAMS "512k(params)ro," +#define PART_UBI "-(ubifs)" +#define MTDPARTS_DEFAULT "mtdparts=davinci_nand.0:" \
PART_BOOT PART_PARAMS PART_UBI
Please just set these outright.
+/* U-Boot command configuration */ +#include <config_cmd_default.h> +#undef CONFIG_CMD_BDI
Why?
+#undef CONFIG_CMD_FLASH
Shouldn't be needed.
+#undef CONFIG_CMD_FPGA +#undef CONFIG_CMD_SETGETDCR
Same.
+#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
Not needed.
- "fdt_high=0xffffffff\0" \
Please don't do this, set it to the top of kernel low mem.
- "mtdparts=mtdparts=davinci_nand.0:" \
"1024k(bootloader)ro,512k(params)ro,522752k(ubifs)\0"
Now you're not using the mtdparts you define, this shouldn't be needed.
+/* Linux interfacing */ +#define CONFIG_CMDLINE_TAG +#define CONFIG_SETUP_MEMORY_TAGS
OF/FDT things should be down here.
+#define LINUX_BOOT_PARAM_ADDR (CONFIG_SYS_SDRAM_BASE + 0x100)
Just use this in the code.
Thanks!

diff --git a/Makefile b/Makefile index 47a03e3..ea2a387 100644 --- a/Makefile +++ b/Makefile @@ -491,6 +491,23 @@ $(obj)u-boot.spr: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin --pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0xff $@ cat $(obj)u-boot.img >> $@
+$(obj)u-boot-spi.gph: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin + $(obj)tools/mkimage -A $(ARCH) -T gpimage -C none \ + -a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) \ + -n SPL -d $(obj)spl/u-boot-spl.bin $(obj)spl/u-boot-spl.gph + $(OBJCOPY) ${OBJCFLAGS} -I binary \ + --pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0 -O binary \ + $(obj)spl/u-boot-spl.gph $(obj)spl/u-boot-spl-pad.gph + cat $(obj)spl/u-boot-spl-pad.gph $(obj)u-boot.img > $@ + +$(obj)u-boot-nand.gph: $(obj)u-boot.bin + $(obj)tools/mkimage -A $(ARCH) -T gpimage -C none \ + -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) \ + -n U-Boot -d $(obj)u-boot.bin $(obj)gph-u-boot.bin + @dd if=/dev/zero of=$(obj)zero.bin bs=8 count=1 2>/dev/null + @cat $(obj)gph-u-boot.bin $(obj)zero.bin > $@ + @rm $(obj)zero.bin
First, these need re-writing for Kbuild. Second, we don't ever use u-boot-nand.gph or talk about it in the README, do we?
Tom,
Will remove remove u-boot-nand.gph for time being as we didn't verify nand boot in this series. What you mean by re-writing for kbuild. The u-boot-spi.gph target is added similar to existing u-boot-spr (see just above this target). Could you provide an example?
Murali

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 03/03/2014 01:20 PM, Murali Karicheri wrote:
diff --git a/Makefile b/Makefile index 47a03e3..ea2a387 100644 --- a/Makefile +++ b/Makefile @@ -491,6 +491,23 @@ $(obj)u-boot.spr: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin --pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0xff $@ cat $(obj)u-boot.img >> $@
+$(obj)u-boot-spi.gph: $(obj)u-boot.img $(obj)spl/u-boot-spl.bin
$(obj)tools/mkimage -A $(ARCH) -T gpimage -C none \
-a $(CONFIG_SPL_TEXT_BASE) -e $(CONFIG_SPL_TEXT_BASE) \
-n SPL -d $(obj)spl/u-boot-spl.bin $(obj)spl/u-boot-spl.gph
$(OBJCOPY) ${OBJCFLAGS} -I binary \
--pad-to=$(CONFIG_SPL_PAD_TO) --gap-fill=0 -O binary \
$(obj)spl/u-boot-spl.gph $(obj)spl/u-boot-spl-pad.gph
cat $(obj)spl/u-boot-spl-pad.gph $(obj)u-boot.img > $@
+$(obj)u-boot-nand.gph: $(obj)u-boot.bin
$(obj)tools/mkimage -A $(ARCH) -T gpimage -C none \
-a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_TEXT_BASE) \
-n U-Boot -d $(obj)u-boot.bin $(obj)gph-u-boot.bin
@dd if=/dev/zero of=$(obj)zero.bin bs=8 count=1 2>/dev/null
@cat $(obj)gph-u-boot.bin $(obj)zero.bin > $@
@rm $(obj)zero.bin
First, these need re-writing for Kbuild. Second, we don't ever use u-boot-nand.gph or talk about it in the README, do we?
Tom,
Will remove remove u-boot-nand.gph for time being as we didn't verify nand boot in this series. What you mean by re-writing for kbuild. The u-boot-spi.gph target is added similar to existing u-boot-spr (see just above this target). Could you provide an example?
Yes, look at how u-boot.spr looks on master now. Things have changed a good bit and this needs updating again.
- -- Tom

Hi Tom,
-----Original Message----- From: u-boot-bounces@lists.denx.de [mailto:u-boot- bounces@lists.denx.de] On Behalf Of Rini, Tom Sent: Tuesday, February 25, 2014 5:12 PM To: Karicheri, Muralidharan Cc: Kwok, WingMan; u-boot@lists.denx.de; Nair, Sandeep Subject: Re: [U-Boot] [U-Boot PATCH v2 08/12] k2hk: add support for k2hk SOC and EVM
On Thu, Feb 20, 2014 at 12:55:10PM -0500, Murali Karicheri wrote:
From: Vitaly Andrianov vitalya@ti.com
k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler SoC. Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please refer
the
ti/k2hk_evm/README for details on the board, build and other information.
This patch add support for keystone architecture and k2hk evm.
Signed-off-by: Vitaly Andrianov vitalya@ti.com Signed-off-by: Murali Karicheri m-karicheri2@ti.com Signed-off-by: WingMan Kwok w-kwok2@ti.com Signed-off-by: Sandeep Nair sandeep_n@ti.com
[snip]
- "fdt_high=0xffffffff\0" \
Please don't do this, set it to the top of kernel low mem.
The EVM may have up to 8GB of DDR and u-boot can see the first 2GB with physical address range 0x80000000-0xffffffff. If we don't use the "fdt_high" environment variable, u-boot relocates the dtb to the end of that memory, which is outside of the lowmem.
Here is the part of bootlog: ------------------------------------------------------------- ## Flattened Device Tree blob at 87000000 Booting using the fdt blob at 0x87000000 Loading Kernel Image ... OK OK Loading Device Tree to ffff1000, end fffffcab ... OK --------------------------------------------------------------
But K2 lowmem VA starts from 0xc0000000 and has size ~760MB. That corresponds to the physical range 0x80000000-0xaf800000. That is why we have to use the "fdt_high=0xffffffff" environment variable.
Have I missed something I u-boot memory configuration? Is there a way to tell u-boot to relocate fdt to the end lowmem?
Thanks, Vitaly

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 03/06/2014 02:09 PM, Andrianov, Vitaly wrote:
Hi Tom,
-----Original Message----- From: u-boot-bounces@lists.denx.de [mailto:u-boot- bounces@lists.denx.de] On Behalf Of Rini, Tom Sent: Tuesday, February 25, 2014 5:12 PM To: Karicheri, Muralidharan Cc: Kwok, WingMan; u-boot@lists.denx.de; Nair, Sandeep Subject: Re: [U-Boot] [U-Boot PATCH v2 08/12] k2hk: add support for k2hk SOC and EVM
On Thu, Feb 20, 2014 at 12:55:10PM -0500, Murali Karicheri wrote:
From: Vitaly Andrianov vitalya@ti.com
k2hk EVM is based on Texas Instruments Keystone2 Hawking/Kepler SoC. Keystone2 SoC has ARM v7 Cortex-A15 MPCore processor. Please refer
the
ti/k2hk_evm/README for details on the board, build and other information.
This patch add support for keystone architecture and k2hk evm.
Signed-off-by: Vitaly Andrianov vitalya@ti.com Signed-off-by: Murali Karicheri m-karicheri2@ti.com Signed-off-by: WingMan Kwok w-kwok2@ti.com Signed-off-by: Sandeep Nair sandeep_n@ti.com
[snip]
- "fdt_high=0xffffffff\0" \
Please don't do this, set it to the top of kernel low mem.
The EVM may have up to 8GB of DDR and u-boot can see the first 2GB with physical address range 0x80000000-0xffffffff. If we don't use the "fdt_high" environment variable, u-boot relocates the dtb to the end of that memory, which is outside of the lowmem.
Right.
Here is the part of bootlog:
## Flattened Device Tree blob at 87000000 Booting using the fdt blob at 0x87000000 Loading Kernel Image ... OK OK Loading Device Tree to ffff1000, end fffffcab ... OK
But K2 lowmem VA starts from 0xc0000000 and has size ~760MB. That corresponds to the physical range 0x80000000-0xaf800000. That is why we have to use the "fdt_high=0xffffffff" environment variable.
Have I missed something I u-boot memory configuration? Is there a way to tell u-boot to relocate fdt to the end lowmem?
Yes, set fdt_high to 0xaf800000 instead :)
- -- Tom

Hi Tom,
[snip]
- "fdt_high=0xffffffff\0" \
Please don't do this, set it to the top of kernel low mem.
The EVM may have up to 8GB of DDR and u-boot can see the first 2GB with physical address range 0x80000000-0xffffffff. If we don't use the "fdt_high" environment variable, u-boot relocates the dtb to the end of that memory, which is outside of the lowmem.
[snip]
But K2 lowmem VA starts from 0xc0000000 and has size ~760MB. That corresponds to the physical range 0x80000000-0xaf800000. That is why we have to use the "fdt_high=0xffffffff" environment
variable.
Have I missed something I u-boot memory configuration? Is there a way to tell u-boot to relocate fdt to the end lowmem?
Yes, set fdt_high to 0xaf800000 instead :)
I think there is a bug in the lmb_alloc_base() and this approach doesn't work.
else if (lmbbase < max_addr) { base = min(lmbbase + lmbsize, max_addr); base = lmb_align_down(base - size, align); } else
For boards that have DDR at the end of 32 bit address space the (lmbbase + lmbsize) = 0 which is < max_addr. So, base becomes 0, and moved to the "end of DDR" - size on the next line.
I tried a quick fix in the __lmb_alloc_base() and got the fdt relocated correctly. As I'm not sure that is only one buggy place in the lmb.c I don't want to commit the quick fix. Let's leave the "fdt_high=0xffffffff" in the Keystone2 for awhile and change it later when we fix the bug.
Thanks, Vitaly

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 03/07/2014 11:41 AM, Andrianov, Vitaly wrote:
Hi Tom,
[snip]
- "fdt_high=0xffffffff\0" \
Please don't do this, set it to the top of kernel low mem.
The EVM may have up to 8GB of DDR and u-boot can see the first 2GB with physical address range 0x80000000-0xffffffff. If we don't use the "fdt_high" environment variable, u-boot relocates the dtb to the end of that memory, which is outside of the lowmem.
[snip]
But K2 lowmem VA starts from 0xc0000000 and has size ~760MB. That corresponds to the physical range 0x80000000-0xaf800000. That is why we have to use the "fdt_high=0xffffffff" environment
variable.
Have I missed something I u-boot memory configuration? Is there a way to tell u-boot to relocate fdt to the end lowmem?
Yes, set fdt_high to 0xaf800000 instead :)
I think there is a bug in the lmb_alloc_base() and this approach doesn't work.
else if (lmbbase < max_addr) { base = min(lmbbase + lmbsize, max_addr); base = lmb_align_down(base - size, align); } else
For boards that have DDR at the end of 32 bit address space the (lmbbase + lmbsize) = 0 which is < max_addr. So, base becomes 0, and moved to the "end of DDR" - size on the next line.
I tried a quick fix in the __lmb_alloc_base() and got the fdt relocated correctly. As I'm not sure that is only one buggy place in the lmb.c I don't want to commit the quick fix. Let's leave the "fdt_high=0xffffffff" in the Keystone2 for awhile and change it later when we fix the bug.
If you're committing to look at this later then yes.
- -- Tom

[snip]
+Build instructions: +===================
+To build u-boot.bin
make k2hk_evm_config make u-boot-spi.gph+To build u-boot-spi.gph
make k2hk_evm_config make u-boot-spi.gphWe need to use CONFIG_SPL_TARGET so that make all just works.
I am assuming we need to do
#define CONFIG_SPL_TARGET "u-boot-spi.gph"
and then
./MAKEALL -a arm
will build this image as well. Is that right?
Murali
if (err < 0)
printf("error deleting linux,initrd-start\n");
Here and elsewhere, puts when we aren't using format chars.
diff --git a/boards.cfg b/boards.cfg index a8336cc..1690315 100644 --- a/boards.cfg +++ b/boards.cfg
Please make sure that the entry is correctly sorted, see the top of boards.cfg.
+++ b/include/configs/k2hk_evm.h @@ -0,0 +1,221 @@ +/*
- Configuration header file for TI's k2hk-evm
- (C) Copyright 2012-2014
Texas Instruments Incorporated, <www.ti.com>
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef __CONFIG_H
Please use __CONFIG_K2HK_EVM_H
+/* Platform type */ +#define CONFIG_SOC_K2HK +#define CONFIG_K2HK_EVM
Make sure we use these.
+/* U-Boot Build Configuration */ +#define CONFIG_SKIP_LOWLEVEL_INIT /* U-Boot is a 2nd stage loader */
So there's a level before SPL that is doing a certain amount of init we don't want to re-do?
+#define CONFIG_SYS_DCACHE_OFF
Really?
+#define CONFIG_SYS_MALLOC_LEN (1024 << 10) /* 1 MiB */
This is pretty small, especially since we care about UBI.
+#define CONFIG_SYS_MEMTEST_START CONFIG_SYS_SDRAM_BASE +#define CONFIG_SYS_MEMTEST_END (CONFIG_SYS_SDRAM_BASE + 32 << 20)
Please see doc/README.memory-test
+/* SPL SPI Loader Configuration */ +#define CONFIG_SPL_TEXT_BASE 0x0c200000 +#define CONFIG_SPL_PAD_TO 65536 +#define CONFIG_SPL_MAX_SIZE (CONFIG_SPL_PAD_TO - 8)
Please explain this a bit more, esp since SPL_PAD_TO should take into account the header size already...
+#define CONFIG_SPL_BSS_START_ADDR (CONFIG_SPL_TEXT_BASE + \
CONFIG_SPL_MAX_SIZE)
+#define CONFIG_SPL_BSS_MAX_SIZE (32 * 1024)
Do we really want SPL BSS in early ram (I don't want to get the name of the type wrong) rather than DDR?
+#define CONFIG_SYS_SPL_MALLOC_START (CONFIG_SPL_BSS_START_ADDR + \
CONFIG_SPL_BSS_MAX_SIZE)
+#define CONFIG_SYS_SPL_MALLOC_SIZE (32 * 1024)
Same.
+#define CONFIG_SYS_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
Please use the default table.
+#define PART_BOOT "1024k(bootloader)ro," +#define PART_PARAMS "512k(params)ro," +#define PART_UBI "-(ubifs)" +#define MTDPARTS_DEFAULT "mtdparts=davinci_nand.0:" \
PART_BOOT PART_PARAMS PART_UBI
Please just set these outright.
+/* U-Boot command configuration */ +#include <config_cmd_default.h> +#undef CONFIG_CMD_BDI
Why?
+#undef CONFIG_CMD_FLASH
Shouldn't be needed.
+#undef CONFIG_CMD_FPGA +#undef CONFIG_CMD_SETGETDCR
Same.
+#define CONFIG_SYS_PROMPT_HUSH_PS2 "> "
Not needed.
- "fdt_high=0xffffffff\0" \
Please don't do this, set it to the top of kernel low mem.
- "mtdparts=mtdparts=davinci_nand.0:" \
"1024k(bootloader)ro,512k(params)ro,522752k(ubifs)\0"
Now you're not using the mtdparts you define, this shouldn't be needed.
+/* Linux interfacing */ +#define CONFIG_CMDLINE_TAG +#define CONFIG_SETUP_MEMORY_TAGS
OF/FDT things should be down here.
+#define LINUX_BOOT_PARAM_ADDR (CONFIG_SYS_SDRAM_BASE + 0x100)
Just use this in the code.
Thanks!

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 03/07/2014 04:21 PM, Murali Karicheri wrote:
[snip]
+Build instructions: +===================
+To build u-boot.bin
make k2hk_evm_config make u-boot-spi.gph+To build u-boot-spi.gph
make k2hk_evm_config make u-boot-spi.gphWe need to use CONFIG_SPL_TARGET so that make all just works.
I am assuming we need to do
#define CONFIG_SPL_TARGET "u-boot-spi.gph"
and then
./MAKEALL -a arm
will build this image as well. Is that right?
Yes.
- -- Tom

From: Vitaly Andrianov vitalya@ti.com
Multicore navigator consists of Network Coprocessor (NetCP) and Queue Manager sub system. More details on the hardware can be obtained from the following links:-
Network Coprocessor: http://www.ti.com/lit/pdf/sprugz6 Multicore Navigator: http://www.ti.com/lit/pdf/sprugr9
Multicore navigator driver implements APIs to configure the Queue Manager and NetCP Pkt DMA.
Signed-off-by: Vitaly Andrianov vitalya@ti.com Signed-off-by: Murali Karicheri m-karicheri2@ti.com Signed-off-by: WingMan Kwok w-kwok2@ti.com --- - Updated based on review comments arch/arm/cpu/armv7/keystone/Makefile | 1 + arch/arm/cpu/armv7/keystone/keystone_nav.c | 376 +++++++++++++++++++++ arch/arm/include/asm/arch-keystone/keystone_nav.h | 193 +++++++++++ 3 files changed, 570 insertions(+) create mode 100644 arch/arm/cpu/armv7/keystone/keystone_nav.c create mode 100644 arch/arm/include/asm/arch-keystone/keystone_nav.h
diff --git a/arch/arm/cpu/armv7/keystone/Makefile b/arch/arm/cpu/armv7/keystone/Makefile index 7924cfa..7d0374b 100644 --- a/arch/arm/cpu/armv7/keystone/Makefile +++ b/arch/arm/cpu/armv7/keystone/Makefile @@ -11,6 +11,7 @@ obj-y += psc.o obj-y += clock.o obj-y += cmd_clock.o obj-y += cmd_mon.o +obj-y += keystone_nav.o obj-y += msmc.o obj-$(CONFIG_SPL_BUILD) += spl.o obj-y += ddr3.o diff --git a/arch/arm/cpu/armv7/keystone/keystone_nav.c b/arch/arm/cpu/armv7/keystone/keystone_nav.c new file mode 100644 index 0000000..39d6f99 --- /dev/null +++ b/arch/arm/cpu/armv7/keystone/keystone_nav.c @@ -0,0 +1,376 @@ +/* + * Multicore Navigator driver for TI Keystone 2 devices. + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <asm/io.h> +#include <asm/arch/keystone_nav.h> + +static int soc_type = +#ifdef CONFIG_SOC_K2HK + k2hk; +#endif + +struct qm_config k2hk_qm_memmap = { + .stat_cfg = 0x02a40000, + .queue = (struct qm_reg_queue *)0x02a80000, + .mngr_vbusm = 0x23a80000, + .i_lram = 0x00100000, + .proxy = (struct qm_reg_queue *)0x02ac0000, + .status_ram = 0x02a06000, + .mngr_cfg = (struct qm_cfg_reg *)0x02a02000, + .intd_cfg = 0x02a0c000, + .desc_mem = (struct descr_mem_setup_reg *)0x02a03000, + .region_num = 64, + .pdsp_cmd = 0x02a20000, + .pdsp_ctl = 0x02a0f000, + .pdsp_iram = 0x02a10000, + .qpool_num = 4000, +}; + +/* + * We are going to use only one type of descriptors - host packet + * descriptors. We staticaly allocate memory for them here + */ +struct qm_host_desc desc_pool[HDESC_NUM] __aligned(sizeof(struct qm_host_desc)); + +static struct qm_config *qm_cfg; + +inline int num_of_desc_to_reg(int num_descr) +{ + int j, num; + + for (j = 0, num = 32; j < 15; j++, num *= 2) { + if (num_descr <= num) + return j; + } + + return 15; +} + +static int _qm_init(struct qm_config *cfg) +{ + u32 j; + + if (cfg == NULL) + return QM_ERR; + + qm_cfg = cfg; + + qm_cfg->mngr_cfg->link_ram_base0 = qm_cfg->i_lram; + qm_cfg->mngr_cfg->link_ram_size0 = HDESC_NUM * 8; + qm_cfg->mngr_cfg->link_ram_base1 = 0; + qm_cfg->mngr_cfg->link_ram_size1 = 0; + qm_cfg->mngr_cfg->link_ram_base2 = 0; + + qm_cfg->desc_mem[0].base_addr = (u32)desc_pool; + qm_cfg->desc_mem[0].start_idx = 0; + qm_cfg->desc_mem[0].desc_reg_size = + (((sizeof(struct qm_host_desc) >> 4) - 1) << 16) | + num_of_desc_to_reg(HDESC_NUM); + + memset(desc_pool, 0, sizeof(desc_pool)); + for (j = 0; j < HDESC_NUM; j++) + qm_push(&desc_pool[j], qm_cfg->qpool_num); + + return QM_OK; +} + +int qm_init(void) +{ + switch (soc_type) { + case k2hk: + return _qm_init(&k2hk_qm_memmap); + } + + return QM_ERR; +} + +void qm_close(void) +{ + u32 j; + + if (qm_cfg == NULL) + return; + + queue_close(qm_cfg->qpool_num); + + qm_cfg->mngr_cfg->link_ram_base0 = 0; + qm_cfg->mngr_cfg->link_ram_size0 = 0; + qm_cfg->mngr_cfg->link_ram_base1 = 0; + qm_cfg->mngr_cfg->link_ram_size1 = 0; + qm_cfg->mngr_cfg->link_ram_base2 = 0; + + for (j = 0; j < qm_cfg->region_num; j++) { + qm_cfg->desc_mem[j].base_addr = 0; + qm_cfg->desc_mem[j].start_idx = 0; + qm_cfg->desc_mem[j].desc_reg_size = 0; + } + + qm_cfg = NULL; +} + +void qm_push(struct qm_host_desc *hd, u32 qnum) +{ + u32 regd; + + if (!qm_cfg) + return; + + cpu_to_bus((u32 *)hd, sizeof(struct qm_host_desc)/4); + regd = (u32)hd | ((sizeof(struct qm_host_desc) >> 4) - 1); + writel(regd, &qm_cfg->queue[qnum].ptr_size_thresh); +} + +void qm_buff_push(struct qm_host_desc *hd, u32 qnum, + void *buff_ptr, u32 buff_len) +{ + hd->orig_buff_len = buff_len; + hd->buff_len = buff_len; + hd->orig_buff_ptr = (u32)buff_ptr; + hd->buff_ptr = (u32)buff_ptr; + qm_push(hd, qnum); +} + +struct qm_host_desc *qm_pop(u32 qnum) +{ + u32 uhd; + + if (!qm_cfg) + return NULL; + + uhd = readl(&qm_cfg->queue[qnum].ptr_size_thresh) & ~0xf; + if (uhd) + cpu_to_bus((u32 *)uhd, sizeof(struct qm_host_desc)/4); + + return (struct qm_host_desc *)uhd; +} + +struct qm_host_desc *qm_pop_from_free_pool(void) +{ + if (!qm_cfg) + return NULL; + + return qm_pop(qm_cfg->qpool_num); +} + +void queue_close(u32 qnum) +{ + struct qm_host_desc *hd; + + while ((hd = qm_pop(qnum))) + ; +} + +/* + * DMA API + */ + +struct pktdma_cfg k2hk_netcp_pktdma = { + .global = (struct global_ctl_regs *)0x02004000, + .tx_ch = (struct tx_chan_regs *)0x02004400, + .tx_ch_num = 9, + .rx_ch = (struct rx_chan_regs *)0x02004800, + .rx_ch_num = 26, + .tx_sched = (u32 *)0x02004c00, + .rx_flows = (struct rx_flow_regs *)0x02005000, + .rx_flow_num = 32, + .rx_free_q = 4001, + .rx_rcv_q = 4002, + .tx_snd_q = 648, +}; + +struct pktdma_cfg *netcp; + +static int netcp_rx_disable(void) +{ + u32 j, v, k; + + for (j = 0; j < netcp->rx_ch_num; j++) { + v = readl(&netcp->rx_ch[j].cfg_a); + if (!(v & CPDMA_CHAN_A_ENABLE)) + continue; + + writel(v | CPDMA_CHAN_A_TDOWN, &netcp->rx_ch[j].cfg_a); + for (k = 0; k < TDOWN_TIMEOUT_COUNT; k++) { + udelay(100); + v = readl(&netcp->rx_ch[j].cfg_a); + if (!(v & CPDMA_CHAN_A_ENABLE)) + continue; + } + /* TODO: teardown error on if TDOWN_TIMEOUT_COUNT is reached */ + } + + /* Clear all of the flow registers */ + for (j = 0; j < netcp->rx_flow_num; j++) { + writel(0, &netcp->rx_flows[j].control); + writel(0, &netcp->rx_flows[j].tags); + writel(0, &netcp->rx_flows[j].tag_sel); + writel(0, &netcp->rx_flows[j].fdq_sel[0]); + writel(0, &netcp->rx_flows[j].fdq_sel[1]); + writel(0, &netcp->rx_flows[j].thresh[0]); + writel(0, &netcp->rx_flows[j].thresh[1]); + writel(0, &netcp->rx_flows[j].thresh[2]); + } + + return QM_OK; +} + +static int netcp_tx_disable(void) +{ + u32 j, v, k; + + for (j = 0; j < netcp->tx_ch_num; j++) { + v = readl(&netcp->tx_ch[j].cfg_a); + if (!(v & CPDMA_CHAN_A_ENABLE)) + continue; + + writel(v | CPDMA_CHAN_A_TDOWN, &netcp->tx_ch[j].cfg_a); + for (k = 0; k < TDOWN_TIMEOUT_COUNT; k++) { + udelay(100); + v = readl(&netcp->tx_ch[j].cfg_a); + if (!(v & CPDMA_CHAN_A_ENABLE)) + continue; + } + /* TODO: teardown error on if TDOWN_TIMEOUT_COUNT is reached */ + } + + return QM_OK; +} + +static int _netcp_init(struct pktdma_cfg *netcp_cfg, + struct rx_buff_desc *rx_buffers) +{ + u32 j, v; + struct qm_host_desc *hd; + u8 *rx_ptr; + + if (netcp_cfg == NULL || rx_buffers == NULL || + rx_buffers->buff_ptr == NULL || qm_cfg == NULL) + return QM_ERR; + + netcp = netcp_cfg; + netcp->rx_flow = rx_buffers->rx_flow; + + /* init rx queue */ + rx_ptr = rx_buffers->buff_ptr; + + for (j = 0; j < rx_buffers->num_buffs; j++) { + hd = qm_pop(qm_cfg->qpool_num); + if (hd == NULL) + return QM_ERR; + + qm_buff_push(hd, netcp->rx_free_q, + rx_ptr, rx_buffers->buff_len); + + rx_ptr += rx_buffers->buff_len; + } + + netcp_rx_disable(); + + /* configure rx channels */ + v = CPDMA_REG_VAL_MAKE_RX_FLOW_A(1, 1, 0, 0, 0, 0, 0, netcp->rx_rcv_q); + writel(v, &netcp->rx_flows[netcp->rx_flow].control); + writel(0, &netcp->rx_flows[netcp->rx_flow].tags); + writel(0, &netcp->rx_flows[netcp->rx_flow].tag_sel); + + v = CPDMA_REG_VAL_MAKE_RX_FLOW_D(0, netcp->rx_free_q, 0, + netcp->rx_free_q); + + writel(v, &netcp->rx_flows[netcp->rx_flow].fdq_sel[0]); + writel(v, &netcp->rx_flows[netcp->rx_flow].fdq_sel[1]); + writel(0, &netcp->rx_flows[netcp->rx_flow].thresh[0]); + writel(0, &netcp->rx_flows[netcp->rx_flow].thresh[1]); + writel(0, &netcp->rx_flows[netcp->rx_flow].thresh[2]); + + for (j = 0; j < netcp->rx_ch_num; j++) + writel(CPDMA_CHAN_A_ENABLE, &netcp->rx_ch[j].cfg_a); + + /* configure tx channels */ + /* Disable loopback in the tx direction */ + writel(0, &netcp->global->emulation_control); + +/* TODO: make it dependend on a soc type variable */ +#ifdef CONFIG_SOC_K2HK + /* Set QM base address, only for K2x devices */ + writel(0x23a80000, &netcp->global->qm_base_addr[0]); +#endif + + /* Enable all channels. The current state isn't important */ + for (j = 0; j < netcp->tx_ch_num; j++) { + writel(0, &netcp->tx_ch[j].cfg_b); + writel(CPDMA_CHAN_A_ENABLE, &netcp->tx_ch[j].cfg_a); + } + + return QM_OK; +} + +int netcp_init(struct rx_buff_desc *rx_buffers) +{ + switch (soc_type) { + case k2hk: + _netcp_init(&k2hk_netcp_pktdma, rx_buffers); + return QM_OK; + } + return QM_ERR; +} + +int netcp_close(void) +{ + if (!netcp) + return QM_ERR; + + netcp_tx_disable(); + netcp_rx_disable(); + + queue_close(netcp->rx_free_q); + queue_close(netcp->rx_rcv_q); + queue_close(netcp->tx_snd_q); + + return QM_OK; +} + +int netcp_send(u32 *pkt, int num_bytes, u32 swinfo2) +{ + struct qm_host_desc *hd; + + hd = qm_pop(qm_cfg->qpool_num); + if (hd == NULL) + return QM_ERR; + + hd->desc_info = num_bytes; + hd->swinfo[2] = swinfo2; + hd->packet_info = qm_cfg->qpool_num; + + qm_buff_push(hd, netcp->tx_snd_q, pkt, num_bytes); + + return QM_OK; +} + +void *netcp_recv(u32 **pkt, int *num_bytes) +{ + struct qm_host_desc *hd; + + hd = qm_pop(netcp->rx_rcv_q); + if (!hd) + return NULL; + + *pkt = (u32 *)hd->buff_ptr; + *num_bytes = hd->desc_info & 0x3fffff; + + return hd; +} + +void netcp_release_rxhd(void *hd) +{ + struct qm_host_desc *_hd = (struct qm_host_desc *)hd; + + _hd->buff_len = _hd->orig_buff_len; + _hd->buff_ptr = _hd->orig_buff_ptr; + + qm_push(_hd, netcp->rx_free_q); +} diff --git a/arch/arm/include/asm/arch-keystone/keystone_nav.h b/arch/arm/include/asm/arch-keystone/keystone_nav.h new file mode 100644 index 0000000..d422bff --- /dev/null +++ b/arch/arm/include/asm/arch-keystone/keystone_nav.h @@ -0,0 +1,193 @@ +/* + * Multicore Navigator definitions + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _KEYSTONE_NAV_H_ +#define _KEYSTONE_NAV_H_ + +#include <asm/arch/hardware.h> +#include <asm/io.h> + +enum soc_type_t { + k2hk +}; + +#define QM_OK 0 +#define QM_ERR -1 +#define QM_DESC_TYPE_HOST 0 +#define QM_DESC_PSINFO_IN_DESCR 0 +#define QM_DESC_DEFAULT_DESCINFO (QM_DESC_TYPE_HOST << 30) | \ + (QM_DESC_PSINFO_IN_DESCR << 22) + +/* Packet Info */ +#define QM_DESC_PINFO_EPIB 1 +#define QM_DESC_PINFO_RETURN_OWN 1 +#define QM_DESC_DEFAULT_PINFO (QM_DESC_PINFO_EPIB << 31) | \ + (QM_DESC_PINFO_RETURN_OWN << 15) + +struct qm_cfg_reg { + u32 revision; + u32 __pad1; + u32 divert; + u32 link_ram_base0; + u32 link_ram_size0; + u32 link_ram_base1; + u32 link_ram_size1; + u32 link_ram_base2; + u32 starvation[0]; +}; + +struct descr_mem_setup_reg { + u32 base_addr; + u32 start_idx; + u32 desc_reg_size; + u32 _res0; +}; + +struct qm_reg_queue { + u32 entry_count; + u32 byte_count; + u32 packet_size; + u32 ptr_size_thresh; +}; + +struct qm_config { + /* QM module addresses */ + u32 stat_cfg; /* status and config */ + struct qm_reg_queue *queue; /* management region */ + u32 mngr_vbusm; /* management region (VBUSM) */ + u32 i_lram; /* internal linking RAM */ + struct qm_reg_queue *proxy; + u32 status_ram; + struct qm_cfg_reg *mngr_cfg; + /* Queue manager config region */ + u32 intd_cfg; /* QMSS INTD config region */ + struct descr_mem_setup_reg *desc_mem; + /* descritor memory setup region*/ + u32 region_num; + u32 pdsp_cmd; /* PDSP1 command interface */ + u32 pdsp_ctl; /* PDSP1 control registers */ + u32 pdsp_iram; + /* QM configuration parameters */ + + u32 qpool_num; /* */ +}; + +struct qm_host_desc { + u32 desc_info; + u32 tag_info; + u32 packet_info; + u32 buff_len; + u32 buff_ptr; + u32 next_bdptr; + u32 orig_buff_len; + u32 orig_buff_ptr; + u32 timestamp; + u32 swinfo[3]; + u32 ps_data[20]; +}; + +#define HDESC_NUM 256 + +int qm_init(void); +void qm_close(void); +void qm_push(struct qm_host_desc *hd, u32 qnum); +struct qm_host_desc *qm_pop(u32 qnum); + +void qm_buff_push(struct qm_host_desc *hd, u32 qnum, + void *buff_ptr, u32 buff_len); + +struct qm_host_desc *qm_pop_from_free_pool(void); +void queue_close(u32 qnum); + +/* + * DMA API + */ +#define CPDMA_REG_VAL_MAKE_RX_FLOW_A(einfo, psinfo, rxerr, desc, \ + psloc, sopoff, qmgr, qnum) \ + (((einfo & 1) << 30) | \ + ((psinfo & 1) << 29) | \ + ((rxerr & 1) << 28) | \ + ((desc & 3) << 26) | \ + ((psloc & 1) << 25) | \ + ((sopoff & 0x1ff) << 16) | \ + ((qmgr & 3) << 12) | \ + ((qnum & 0xfff) << 0)) + +#define CPDMA_REG_VAL_MAKE_RX_FLOW_D(fd0qm, fd0qnum, fd1qm, fd1qnum) \ + (((fd0qm & 3) << 28) | \ + ((fd0qnum & 0xfff) << 16) | \ + ((fd1qm & 3) << 12) | \ + ((fd1qnum & 0xfff) << 0)) + +#define CPDMA_CHAN_A_ENABLE ((u32)1 << 31) +#define CPDMA_CHAN_A_TDOWN (1 << 30) +#define TDOWN_TIMEOUT_COUNT 100 + +struct global_ctl_regs { + u32 revision; + u32 perf_control; + u32 emulation_control; + u32 priority_control; + u32 qm_base_addr[4]; +}; + +struct tx_chan_regs { + u32 cfg_a; + u32 cfg_b; + u32 res[6]; +}; + +struct rx_chan_regs { + u32 cfg_a; + u32 res[7]; +}; + +struct rx_flow_regs { + u32 control; + u32 tags; + u32 tag_sel; + u32 fdq_sel[2]; + u32 thresh[3]; +}; + +struct pktdma_cfg { + struct global_ctl_regs *global; + struct tx_chan_regs *tx_ch; + u32 tx_ch_num; + struct rx_chan_regs *rx_ch; + u32 rx_ch_num; + u32 *tx_sched; + struct rx_flow_regs *rx_flows; + u32 rx_flow_num; + + u32 rx_free_q; + u32 rx_rcv_q; + u32 tx_snd_q; + + u32 rx_flow; /* flow that is used for RX */ +}; + +/* + * packet dma user allocates memory for rx buffers + * and describe it in the following structure + */ +struct rx_buff_desc { + u8 *buff_ptr; + u32 num_buffs; + u32 buff_len; + u32 rx_flow; +}; + +int netcp_close(void); +int netcp_init(struct rx_buff_desc *rx_buffers); +int netcp_send(u32 *pkt, int num_bytes, u32 swinfo2); +void *netcp_recv(u32 **pkt, int *num_bytes); +void netcp_release_rxhd(void *hd); + +#endif /* _KEYSTONE_NAV_H_ */

On Thu, Feb 20, 2014 at 12:55:11PM -0500, Murali Karicheri wrote:
From: Vitaly Andrianov vitalya@ti.com
Multicore navigator consists of Network Coprocessor (NetCP) and Queue Manager sub system. More details on the hardware can be obtained from the following links:-
Network Coprocessor: http://www.ti.com/lit/pdf/sprugz6 Multicore Navigator: http://www.ti.com/lit/pdf/sprugr9
Multicore navigator driver implements APIs to configure the Queue Manager and NetCP Pkt DMA.
Signed-off-by: Vitaly Andrianov vitalya@ti.com Signed-off-by: Murali Karicheri m-karicheri2@ti.com Signed-off-by: WingMan Kwok w-kwok2@ti.com
Acked-by: Tom Rini trini@ti.com

From: Vitaly Andrianov vitalya@ti.com
Ethernet driver configures the CPSW, SGMI and Phy and uses the the Navigator APIs. The driver supports 4 Ethernet ports and can work with only one port at a time.
Port configurations are defined in board.c.
Signed-off-by: Vitaly Andrianov vitalya@ti.com Signed-off-by: Murali Karicheri m-karicheri2@ti.com Signed-off-by: WingMan Kwok w-kwok2@ti.com --- - updated based on review comments arch/arm/include/asm/arch-keystone/emac_defs.h | 250 +++++++ board/ti/k2hk_evm/board.c | 65 ++ drivers/net/Makefile | 1 + drivers/net/keystone_net.c | 859 ++++++++++++++++++++++++ include/configs/k2hk_evm.h | 38 ++ 5 files changed, 1213 insertions(+) create mode 100644 arch/arm/include/asm/arch-keystone/emac_defs.h create mode 100644 drivers/net/keystone_net.c
diff --git a/arch/arm/include/asm/arch-keystone/emac_defs.h b/arch/arm/include/asm/arch-keystone/emac_defs.h new file mode 100644 index 0000000..9c1c5bc --- /dev/null +++ b/arch/arm/include/asm/arch-keystone/emac_defs.h @@ -0,0 +1,250 @@ +/* + * emac definitions for keystone2 devices + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _EMAC_DEFS_H_ +#define _EMAC_DEFS_H_ + +#include <asm/arch/hardware.h> +#include <asm/io.h> + +#define DEVICE_REG32_R(a) readl(a) +#define DEVICE_REG32_W(a, v) writel(v, a) + +/*#define chipLmbd(x,y) _lmbd(x,y) */ + +#define EMAC_EMACSL_BASE_ADDR (KS2_PASS_BASE + 0x00090900) +#define EMAC_MDIO_BASE_ADDR (KS2_PASS_BASE + 0x00090300) +#define EMAC_SGMII_BASE_ADDR (KS2_PASS_BASE + 0x00090100) + +#define KEYSTONE2_EMAC_GIG_ENABLE + +#define MAC_ID_BASE_ADDR (KS2_DEVICE_STATE_CTRL_BASE + 0x110) + +#ifdef CONFIG_SOC_K2HK +/* MDIO module input frequency */ +#define EMAC_MDIO_BUS_FREQ (clk_get_rate(pass_pll_clk)) +/* MDIO clock output frequency */ +#define EMAC_MDIO_CLOCK_FREQ 1000000 /* 1.0 MHz */ +#endif + +/* MII Status Register */ +#define MII_STATUS_REG 1 +#define MII_STATUS_LINK_MASK (0x4) + +/* Marvell 88E1111 PHY ID */ +#define PHY_MARVELL_88E1111 (0x01410cc0) + +#define MDIO_CONTROL_IDLE (0x80000000) +#define MDIO_CONTROL_ENABLE (0x40000000) +#define MDIO_CONTROL_FAULT_ENABLE (0x40000) +#define MDIO_CONTROL_FAULT (0x80000) +#define MDIO_USERACCESS0_GO (0x80000000) +#define MDIO_USERACCESS0_WRITE_READ (0x0) +#define MDIO_USERACCESS0_WRITE_WRITE (0x40000000) +#define MDIO_USERACCESS0_ACK (0x20000000) + +#define EMAC_MACCONTROL_MIIEN_ENABLE (0x20) +#define EMAC_MACCONTROL_FULLDUPLEX_ENABLE (0x1) +#define EMAC_MACCONTROL_GIGABIT_ENABLE (1 << 7) +#define EMAC_MACCONTROL_GIGFORCE (1 << 17) +#define EMAC_MACCONTROL_RMIISPEED_100 (1 << 15) + +#define EMAC_MIN_ETHERNET_PKT_SIZE 60 + +struct mac_sl_cfg { + u_int32_t max_rx_len; /* Maximum receive packet length. */ + u_int32_t ctl; /* Control bitfield */ +}; + +/* + * Definition: Control bitfields used in the ctl field of hwGmacSlCfg_t + */ +#define GMACSL_RX_ENABLE_RCV_CONTROL_FRAMES (1 << 24) +#define GMACSL_RX_ENABLE_RCV_SHORT_FRAMES (1 << 23) +#define GMACSL_RX_ENABLE_RCV_ERROR_FRAMES (1 << 22) +#define GMACSL_RX_ENABLE_EXT_CTL (1 << 18) +#define GMACSL_RX_ENABLE_GIG_FORCE (1 << 17) +#define GMACSL_RX_ENABLE_IFCTL_B (1 << 16) +#define GMACSL_RX_ENABLE_IFCTL_A (1 << 15) +#define GMACSL_RX_ENABLE_CMD_IDLE (1 << 11) +#define GMACSL_TX_ENABLE_SHORT_GAP (1 << 10) +#define GMACSL_ENABLE_GIG_MODE (1 << 7) +#define GMACSL_TX_ENABLE_PACE (1 << 6) +#define GMACSL_ENABLE (1 << 5) +#define GMACSL_TX_ENABLE_FLOW_CTL (1 << 4) +#define GMACSL_RX_ENABLE_FLOW_CTL (1 << 3) +#define GMACSL_ENABLE_LOOPBACK (1 << 1) +#define GMACSL_ENABLE_FULL_DUPLEX (1 << 0) + +/* + * DEFINTITION: function return values + */ +#define GMACSL_RET_OK 0 +#define GMACSL_RET_INVALID_PORT -1 +#define GMACSL_RET_WARN_RESET_INCOMPLETE -2 +#define GMACSL_RET_WARN_MAXLEN_TOO_BIG -3 +#define GMACSL_RET_CONFIG_FAIL_RESET_ACTIVE -4 + +/* Register offsets */ +#define CPGMACSL_REG_ID 0x00 +#define CPGMACSL_REG_CTL 0x04 +#define CPGMACSL_REG_STATUS 0x08 +#define CPGMACSL_REG_RESET 0x0c +#define CPGMACSL_REG_MAXLEN 0x10 +#define CPGMACSL_REG_BOFF 0x14 +#define CPGMACSL_REG_RX_PAUSE 0x18 +#define CPGMACSL_REG_TX_PAURSE 0x1c +#define CPGMACSL_REG_EM_CTL 0x20 +#define CPGMACSL_REG_PRI 0x24 + +/* Soft reset register values */ +#define CPGMAC_REG_RESET_VAL_RESET_MASK (1 << 0) +#define CPGMAC_REG_RESET_VAL_RESET (1 << 0) + +/* Maxlen register values */ +#define CPGMAC_REG_MAXLEN_LEN 0x3fff + +/* Control bitfields */ +#define CPSW_CTL_P2_PASS_PRI_TAGGED (1 << 5) +#define CPSW_CTL_P1_PASS_PRI_TAGGED (1 << 4) +#define CPSW_CTL_P0_PASS_PRI_TAGGED (1 << 3) +#define CPSW_CTL_P0_ENABLE (1 << 2) +#define CPSW_CTL_VLAN_AWARE (1 << 1) +#define CPSW_CTL_FIFO_LOOPBACK (1 << 0) + +#define DEVICE_CPSW_NUM_PORTS 5 /* 5 switch ports */ +#define DEVICE_CPSW_BASE (0x02090800) +#define target_get_switch_ctl() CPSW_CTL_P0_ENABLE /* Enable port 0 */ +#define SWITCH_MAX_PKT_SIZE 9000 + +/* Register offsets */ +#define CPSW_REG_CTL 0x004 +#define CPSW_REG_STAT_PORT_EN 0x00c +#define CPSW_REG_MAXLEN 0x040 +#define CPSW_REG_ALE_CONTROL 0x608 +#define CPSW_REG_ALE_PORTCTL(x) (0x640 + (x)*4) + +/* Register values */ +#define CPSW_REG_VAL_STAT_ENABLE_ALL 0xf +#define CPSW_REG_VAL_ALE_CTL_RESET_AND_ENABLE ((u_int32_t)0xc0000000) +#define CPSW_REG_VAL_ALE_CTL_BYPASS ((u_int32_t)0x00000010) +#define CPSW_REG_VAL_PORTCTL_FORWARD_MODE 0x3 + +#define SGMII_REG_STATUS_LOCK BIT(4) +#define SGMII_REG_STATUS_LINK BIT(0) +#define SGMII_REG_STATUS_AUTONEG BIT(2) +#define SGMII_REG_CONTROL_AUTONEG BIT(0) +#define SGMII_REG_CONTROL_MASTER BIT(5) +#define SGMII_REG_MR_ADV_ENABLE BIT(0) +#define SGMII_REG_MR_ADV_LINK BIT(15) +#define SGMII_REG_MR_ADV_FULL_DUPLEX BIT(12) +#define SGMII_REG_MR_ADV_GIG_MODE BIT(11) + +#define SGMII_LINK_MAC_MAC_AUTONEG 0 +#define SGMII_LINK_MAC_PHY 1 +#define SGMII_LINK_MAC_MAC_FORCED 2 +#define SGMII_LINK_MAC_FIBER 3 +#define SGMII_LINK_MAC_PHY_FORCED 4 + +#define TARGET_SGMII_BASE KS2_PASS_BASE + 0x00090100 +#define TARGET_SGMII_BASE_ADDRESSES {KS2_PASS_BASE+0x00090100, \ + KS2_PASS_BASE+0x00090200, \ + KS2_PASS_BASE+0x00090400, \ + KS2_PASS_BASE+0x00090500 } + +#define SGMII_OFFSET(x) ((x <= 1) ? (x * 0x100) : ((x * 0x100) + 0x100)) + +/* + * SGMII registers + */ +#define SGMII_IDVER_REG(x) (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x000) +#define SGMII_SRESET_REG(x) (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x004) +#define SGMII_CTL_REG(x) (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x010) +#define SGMII_STATUS_REG(x) (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x014) +#define SGMII_MRADV_REG(x) (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x018) +#define SGMII_LPADV_REG(x) (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x020) +#define SGMII_TXCFG_REG(x) (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x030) +#define SGMII_RXCFG_REG(x) (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x034) +#define SGMII_AUXCFG_REG(x) (TARGET_SGMII_BASE + SGMII_OFFSET(x) + 0x038) + +#define DEVICE_EMACSL_BASE(x) (KS2_PASS_BASE + 0x00090900 + (x)*0x040) +#define DEVICE_N_GMACSL_PORTS 4 +#define DEVICE_EMACSL_RESET_POLL_COUNT 100 + +#define DEVICE_PSTREAM_CFG_REG_ADDR (KS2_PASS_BASE + 0x604) + +#ifdef CONFIG_SOC_K2HK +#define DEVICE_PSTREAM_CFG_REG_VAL_ROUTE_CPPI 0x06060606 +#endif + +#define hw_config_streaming_switch() \ + DEVICE_REG32_W(DEVICE_PSTREAM_CFG_REG_ADDR, \ + DEVICE_PSTREAM_CFG_REG_VAL_ROUTE_CPPI); + +/* EMAC MDIO Registers Structure */ +struct mdio_regs { + dv_reg VERSION; + dv_reg CONTROL; + dv_reg ALIVE; + dv_reg LINK; + dv_reg LINKINTRAW; + dv_reg LINKINTMASKED; + u_int8_t RSVD0[8]; + dv_reg USERINTRAW; + dv_reg USERINTMASKED; + dv_reg USERINTMASKSET; + dv_reg USERINTMASKCLEAR; + u_int8_t RSVD1[80]; + dv_reg USERACCESS0; + dv_reg USERPHYSEL0; + dv_reg USERACCESS1; + dv_reg USERPHYSEL1; +}; + +/* Ethernet MAC Registers Structure */ +struct emac_regs { + dv_reg IDVER; + dv_reg MACCONTROL; + dv_reg MACSTATUS; + dv_reg SOFT_RESET; + dv_reg RX_MAXLEN; + u32 RSVD0; + dv_reg RX_PAUSE; + dv_reg TX_PAUSE; + dv_reg EMCONTROL; + dv_reg PRI_MAP; + u32 RSVD1[6]; +}; + +struct phy_t { + char name[64]; + int (*init)(int phy_addr); + int (*is_phy_connected)(int phy_addr); + int (*get_link_speed)(int phy_addr); + int (*auto_negotiate)(int phy_addr); +}; + +#define SGMII_ACCESS(port, reg) \ + *((volatile unsigned int *)(sgmiis[port] + reg)) + +struct eth_priv_t { + char int_name[32]; + int rx_flow; + int phy_addr; + int slave_port; + int sgmii_link_type; +}; + +extern struct eth_priv_t eth_priv_cfg[]; + +int keystone2_emac_initialize(struct eth_priv_t *eth_priv); +void sgmii_serdes_setup_156p25mhz(void); +void sgmii_serdes_shutdown(void); + +#endif /* _EMAC_DEFS_H_ */ diff --git a/board/ti/k2hk_evm/board.c b/board/ti/k2hk_evm/board.c index 14dc7e4..81f5ca4 100644 --- a/board/ti/k2hk_evm/board.c +++ b/board/ti/k2hk_evm/board.c @@ -17,6 +17,7 @@ #include <asm/io.h> #include <asm/mach-types.h> #include <asm/arch/nand_defs.h> +#include <asm/arch/emac_defs.h> #include <asm/arch/psc_defs.h>
DECLARE_GLOBAL_DATA_PTR; @@ -70,6 +71,70 @@ int dram_init(void) return 0; }
+#ifdef CONFIG_DRIVER_TI_KEYSTONE_NET +struct eth_priv_t eth_priv_cfg[] = { + { + .int_name = "K2HK_EMAC", + .rx_flow = 22, + .phy_addr = 0, + .slave_port = 1, + .sgmii_link_type = SGMII_LINK_MAC_PHY, + }, + { + .int_name = "K2HK_EMAC1", + .rx_flow = 23, + .phy_addr = 1, + .slave_port = 2, + .sgmii_link_type = SGMII_LINK_MAC_PHY, + }, + { + .int_name = "K2HK_EMAC2", + .rx_flow = 24, + .phy_addr = 2, + .slave_port = 3, + .sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED, + }, + { + .int_name = "K2HK_EMAC3", + .rx_flow = 25, + .phy_addr = 3, + .slave_port = 4, + .sgmii_link_type = SGMII_LINK_MAC_MAC_FORCED, + }, +}; + +int get_eth_env_param(char *env_name) +{ + char *env; + int res = -1; + + env = getenv(env_name); + if (env) + res = simple_strtol(env, NULL, 0); + + return res; +} + +int board_eth_init(bd_t *bis) +{ + int j; + int res; + char link_type_name[32]; + + for (j = 0; j < (sizeof(eth_priv_cfg) / sizeof(struct eth_priv_t)); + j++) { + sprintf(link_type_name, "sgmii%d_link_type", j); + res = get_eth_env_param(link_type_name); + if (res >= 0) + eth_priv_cfg[j].sgmii_link_type = res; + + keystone2_emac_initialize(ð_priv_cfg[j]); + } + + return 0; +} +#endif + /* Byte swap the 32-bit data if the device is BE */ int cpu_to_bus(u32 *ptr, u32 length) { diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 7f9ce90..6005f7e 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_FTMAC110) += ftmac110.o obj-$(CONFIG_FTMAC100) += ftmac100.o obj-$(CONFIG_GRETH) += greth.o obj-$(CONFIG_INCA_IP_SWITCH) += inca-ip_sw.o +obj-$(CONFIG_DRIVER_TI_KEYSTONE_NET) += keystone_net.o obj-$(CONFIG_DRIVER_KS8695ETH) += ks8695eth.o obj-$(CONFIG_KS8851_MLL) += ks8851_mll.o obj-$(CONFIG_LAN91C96) += lan91c96.o diff --git a/drivers/net/keystone_net.c b/drivers/net/keystone_net.c new file mode 100644 index 0000000..473a4b1 --- /dev/null +++ b/drivers/net/keystone_net.c @@ -0,0 +1,859 @@ +/* + * Ethernet driver for TI K2HK EVM. + * + * (C) Copyright 2012-2014 + * Texas Instruments Incorporated, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <command.h> + +#include <net.h> +#include <miiphy.h> +#include <malloc.h> +#include <asm/arch/emac_defs.h> +#include <asm/arch/psc_defs.h> +#include <asm/arch/keystone_nav.h> + +unsigned int emac_dbg; +#define debug_emac(fmt, args...) if (emac_dbg) printf(fmt, ##args) + +unsigned int emac_open; +static unsigned int sys_has_mdio = 1; + +#ifdef KEYSTONE2_EMAC_GIG_ENABLE +#define emac_gigabit_enable(x) keystone2_eth_gigabit_enable(x) +#else +#define emac_gigabit_enable(x) /* no gigabit to enable */ +#endif + +#define RX_BUFF_NUMS 24 +#define RX_BUFF_LEN 1520 +#define MAX_SIZE_STREAM_BUFFER RX_BUFF_LEN + +static u8 rx_buffs[RX_BUFF_NUMS * RX_BUFF_LEN] __aligned(16); + +struct rx_buff_desc net_rx_buffs = { + .buff_ptr = rx_buffs, + .num_buffs = RX_BUFF_NUMS, + .buff_len = RX_BUFF_LEN, + .rx_flow = 22, +}; + +static void keystone2_eth_mdio_enable(void); + +static int gen_init_phy(int phy_addr); +static int gen_is_phy_connected(int phy_addr); +static int gen_get_link_speed(int phy_addr); +static int gen_auto_negotiate(int phy_addr); + +static int marvell_88e1111_init_phy(int phy_addr); +static int marvell_88e1111_is_phy_connected(int phy_addr); +static int marvell_88e1111_get_link_speed(int phy_addr); +static int marvell_88e1111_auto_negotiate(int phy_addr); + +/* EMAC Addresses */ +static volatile struct emac_regs *adap_emac = + (struct emac_regs *)EMAC_EMACSL_BASE_ADDR; +static volatile struct mdio_regs *adap_mdio = + (struct mdio_regs *)EMAC_MDIO_BASE_ADDR; + +struct phy_t phy; + +static void chip_delay(u32 del) +{ + volatile unsigned int i; + + for (i = 0; i < (del / 8); i++) + ; +} + +int keystone2_eth_read_mac_addr(struct eth_device *dev) +{ + struct eth_priv_t *eth_priv; + u32 maca = 0; + u32 macb = 0; + + eth_priv = (struct eth_priv_t *)dev->priv; + + /* Read the e-fuse mac address */ + if (eth_priv->slave_port == 1) { + maca = __raw_readl(MAC_ID_BASE_ADDR); + macb = __raw_readl(MAC_ID_BASE_ADDR + 4); + } + + dev->enetaddr[0] = (macb >> 8) & 0xff; + dev->enetaddr[1] = (macb >> 0) & 0xff; + dev->enetaddr[2] = (maca >> 24) & 0xff; + dev->enetaddr[3] = (maca >> 16) & 0xff; + dev->enetaddr[4] = (maca >> 8) & 0xff; + dev->enetaddr[5] = (maca >> 0) & 0xff; + + return 0; +} + +static void keystone2_eth_mdio_enable(void) +{ + u_int32_t clkdiv; + + clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1; + + writel((clkdiv & 0xffff) | + MDIO_CONTROL_ENABLE | + MDIO_CONTROL_FAULT | + MDIO_CONTROL_FAULT_ENABLE, + &adap_mdio->CONTROL); + + while (readl(&adap_mdio->CONTROL) & MDIO_CONTROL_IDLE) + ; +} + +/* Read a PHY register via MDIO inteface. Returns 1 on success, 0 otherwise */ +int keystone2_eth_phy_read(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t *data) +{ + int tmp; + + while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO) + ; + + writel(MDIO_USERACCESS0_GO | + MDIO_USERACCESS0_WRITE_READ | + ((reg_num & 0x1f) << 21) | + ((phy_addr & 0x1f) << 16), + &adap_mdio->USERACCESS0); + + /* Wait for command to complete */ + while ((tmp = readl(&adap_mdio->USERACCESS0)) & MDIO_USERACCESS0_GO) + ; + + if (tmp & MDIO_USERACCESS0_ACK) { + *data = tmp & 0xffff; + return 0; + } + + *data = -1; + return -1; +} + +/* + * Write to a PHY register via MDIO inteface. + * Blocks until operation is complete. + */ +int keystone2_eth_phy_write(u_int8_t phy_addr, u_int8_t reg_num, u_int16_t data) +{ + while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO) + ; + + writel(MDIO_USERACCESS0_GO | + MDIO_USERACCESS0_WRITE_WRITE | + ((reg_num & 0x1f) << 21) | + ((phy_addr & 0x1f) << 16) | + (data & 0xffff), + &adap_mdio->USERACCESS0); + + /* Wait for command to complete */ + while (readl(&adap_mdio->USERACCESS0) & MDIO_USERACCESS0_GO) + ; + + return 0; +} + +/* PHY functions for a generic PHY */ +static int __attribute__((unused)) gen_init_phy(int phy_addr) +{ + int ret = -1; + + if (!gen_get_link_speed(phy_addr)) { + /* Try another time */ + ret = gen_get_link_speed(phy_addr); + } + + return ret; +} + +static int __attribute__((unused)) gen_is_phy_connected(int phy_addr) +{ + u_int16_t dummy; + + return keystone2_eth_phy_read(phy_addr, MII_PHYSID1, &dummy); +} + +static int gen_get_link_speed(int phy_addr) +{ + u_int16_t tmp; + + if ((!keystone2_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp)) && + (tmp & 0x04)) { + return 0; + } + + return -1; +} + +static int __attribute__((unused)) gen_auto_negotiate(int phy_addr) +{ + u_int16_t tmp; + + if (keystone2_eth_phy_read(phy_addr, MII_BMCR, &tmp)) + return -1; + + /* Restart Auto_negotiation */ + tmp |= BMCR_ANENABLE; + keystone2_eth_phy_write(phy_addr, MII_BMCR, tmp); + + /*check AutoNegotiate complete */ + udelay(10000); + if (keystone2_eth_phy_read(phy_addr, MII_BMSR, &tmp)) + return -1; + + if (!(tmp & BMSR_ANEGCOMPLETE)) + return 0; + + return gen_get_link_speed(phy_addr); +} + +/* PHY functions for Marvell 88E1111 PHY */ +static int marvell_88e1111_init_phy(int phy_addr) +{ + int ret = -1; + + if (!marvell_88e1111_get_link_speed(phy_addr)) { + /* Try another time */ + ret = marvell_88e1111_get_link_speed(phy_addr); + } + + return ret; +} + +static int marvell_88e1111_is_phy_connected(int phy_addr) +{ + u_int16_t dummy; + + return keystone2_eth_phy_read(phy_addr, MII_PHYSID1, &dummy); +} + +static int marvell_88e1111_get_link_speed(int phy_addr) +{ + u_int16_t tmp; + + if ((!keystone2_eth_phy_read(phy_addr, MII_STATUS_REG, &tmp)) && + (tmp & MII_STATUS_LINK_MASK)) { + return 0; + } + + return -1; +} + +static int marvell_88e1111_auto_negotiate(int phy_addr) +{ + u_int16_t tmp; + + if (keystone2_eth_phy_read(phy_addr, MII_BMCR, &tmp)) + return -1; + + /* Restart Auto_negotiation */ + tmp |= BMCR_ANENABLE; + keystone2_eth_phy_write(phy_addr, MII_BMCR, tmp); + + /*check AutoNegotiate complete */ + udelay(10000); + if (keystone2_eth_phy_read(phy_addr, MII_BMSR, &tmp)) + return -1; + + if (!(tmp & BMSR_ANEGCOMPLETE)) + return 0; + + return marvell_88e1111_get_link_speed(phy_addr); +} + +#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) +static int keystone2_mii_phy_read(const char *devname, unsigned char addr, + unsigned char reg, unsigned short *value) +{ + return keystone2_eth_phy_read(addr, reg, value) ? -1 : 0; +} + +static int keystone2_mii_phy_write(const char *devname, unsigned char addr, + unsigned char reg, unsigned short value) +{ + return keystone2_eth_phy_write(addr, reg, value) ? -1 : 0; +} +#endif + +static void __attribute__((unused)) + keystone2_eth_gigabit_enable(struct eth_device *dev) +{ + u_int16_t data; + struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; + + if (sys_has_mdio) { + if (keystone2_eth_phy_read(eth_priv->phy_addr, 0, &data) || + !(data & (1 << 6))) /* speed selection MSB */ + return; + } + + /* + * Check if link detected is giga-bit + * If Gigabit mode detected, enable gigbit in MAC + */ + writel(readl(&(adap_emac[eth_priv->slave_port - 1].MACCONTROL)) | + EMAC_MACCONTROL_GIGFORCE | EMAC_MACCONTROL_GIGABIT_ENABLE, + &(adap_emac[eth_priv->slave_port - 1].MACCONTROL)) + ; +} + +int keystone_sgmii_link_status(int port) +{ + u32 status = 0; + + status = __raw_readl(SGMII_STATUS_REG(port)); + + return status & SGMII_REG_STATUS_LINK; +} + + +int keystone_get_link_status(struct eth_device *dev) +{ + struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; + int sgmii_link; + int link_state = 0; +#if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1 + int j; + + for (j = 0; (j < CONFIG_GET_LINK_STATUS_ATTEMPTS) && (link_state == 0); + j++) { +#endif + sgmii_link = + keystone_sgmii_link_status(eth_priv->slave_port - 1); + + if (sgmii_link) { + link_state = 1; + + if (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) + if (phy.get_link_speed(eth_priv->phy_addr)) + link_state = 0; + } +#if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1 + } +#endif + return link_state; +} + +int keystone_sgmii_config(int port, int interface) +{ + unsigned int i, status, mask; + unsigned int mr_adv_ability, control; + + switch (interface) { + case SGMII_LINK_MAC_MAC_AUTONEG: + mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE | + SGMII_REG_MR_ADV_LINK | + SGMII_REG_MR_ADV_FULL_DUPLEX | + SGMII_REG_MR_ADV_GIG_MODE); + control = (SGMII_REG_CONTROL_MASTER | + SGMII_REG_CONTROL_AUTONEG); + + break; + case SGMII_LINK_MAC_PHY: + case SGMII_LINK_MAC_PHY_FORCED: + mr_adv_ability = SGMII_REG_MR_ADV_ENABLE; + control = SGMII_REG_CONTROL_AUTONEG; + + break; + case SGMII_LINK_MAC_MAC_FORCED: + mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE | + SGMII_REG_MR_ADV_LINK | + SGMII_REG_MR_ADV_FULL_DUPLEX | + SGMII_REG_MR_ADV_GIG_MODE); + control = SGMII_REG_CONTROL_MASTER; + + break; + case SGMII_LINK_MAC_FIBER: + mr_adv_ability = 0x20; + control = SGMII_REG_CONTROL_AUTONEG; + + break; + default: + mr_adv_ability = SGMII_REG_MR_ADV_ENABLE; + control = SGMII_REG_CONTROL_AUTONEG; + } + + __raw_writel(0, SGMII_CTL_REG(port)); + + /* + * Wait for the SerDes pll to lock, + * but don't trap if lock is never read + */ + for (i = 0; i < 1000; i++) { + udelay(2000); + status = __raw_readl(SGMII_STATUS_REG(port)); + if ((status & SGMII_REG_STATUS_LOCK) != 0) + break; + } + + __raw_writel(mr_adv_ability, SGMII_MRADV_REG(port)); + __raw_writel(control, SGMII_CTL_REG(port)); + + + mask = SGMII_REG_STATUS_LINK; + + if (control & SGMII_REG_CONTROL_AUTONEG) + mask |= SGMII_REG_STATUS_AUTONEG; + + for (i = 0; i < 1000; i++) { + status = __raw_readl(SGMII_STATUS_REG(port)); + if ((status & mask) == mask) + break; + } + + return 0; +} + +int mac_sl_reset(u32 port) +{ + u32 i, v; + + if (port >= DEVICE_N_GMACSL_PORTS) + return GMACSL_RET_INVALID_PORT; + + /* Set the soft reset bit */ + DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) + + CPGMACSL_REG_RESET, CPGMAC_REG_RESET_VAL_RESET); + + /* Wait for the bit to clear */ + for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) { + v = DEVICE_REG32_R(DEVICE_EMACSL_BASE(port) + + CPGMACSL_REG_RESET); + if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) != + CPGMAC_REG_RESET_VAL_RESET) + return GMACSL_RET_OK; + } + + /* Timeout on the reset */ + return GMACSL_RET_WARN_RESET_INCOMPLETE; +} + +int mac_sl_config(u_int16_t port, struct mac_sl_cfg *cfg) +{ + u32 v, i; + int ret = GMACSL_RET_OK; + + if (port >= DEVICE_N_GMACSL_PORTS) + return GMACSL_RET_INVALID_PORT; + + if (cfg->max_rx_len > CPGMAC_REG_MAXLEN_LEN) { + cfg->max_rx_len = CPGMAC_REG_MAXLEN_LEN; + ret = GMACSL_RET_WARN_MAXLEN_TOO_BIG; + } + + /* Must wait if the device is undergoing reset */ + for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) { + v = DEVICE_REG32_R(DEVICE_EMACSL_BASE(port) + + CPGMACSL_REG_RESET); + if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) != + CPGMAC_REG_RESET_VAL_RESET) + break; + } + + if (i == DEVICE_EMACSL_RESET_POLL_COUNT) + return GMACSL_RET_CONFIG_FAIL_RESET_ACTIVE; + + DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_MAXLEN, + cfg->max_rx_len); + + DEVICE_REG32_W(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_CTL, + cfg->ctl); + + return ret; +} + +int ethss_config(u32 ctl, u32 max_pkt_size) +{ + u32 i; + + /* Max length register */ + DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_MAXLEN, max_pkt_size); + + /* Control register */ + DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_CTL, ctl); + + /* All statistics enabled by default */ + DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_STAT_PORT_EN, + CPSW_REG_VAL_STAT_ENABLE_ALL); + + /* Reset and enable the ALE */ + DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_ALE_CONTROL, + CPSW_REG_VAL_ALE_CTL_RESET_AND_ENABLE | + CPSW_REG_VAL_ALE_CTL_BYPASS); + + /* All ports put into forward mode */ + for (i = 0; i < DEVICE_CPSW_NUM_PORTS; i++) + DEVICE_REG32_W(DEVICE_CPSW_BASE + CPSW_REG_ALE_PORTCTL(i), + CPSW_REG_VAL_PORTCTL_FORWARD_MODE); + + return 0; +} + +int ethss_start(void) +{ + int i; + struct mac_sl_cfg cfg; + + cfg.max_rx_len = MAX_SIZE_STREAM_BUFFER; + cfg.ctl = GMACSL_ENABLE | GMACSL_RX_ENABLE_EXT_CTL; + + for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++) { + mac_sl_reset(i); + mac_sl_config(i, &cfg); + } + + return 0; +} + +int ethss_stop(void) +{ + int i; + + for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++) + mac_sl_reset(i); + + return 0; +} + +int32_t cpmac_drv_send(u32 *buffer, int num_bytes, int slave_port_num) +{ + if (num_bytes < EMAC_MIN_ETHERNET_PKT_SIZE) + num_bytes = EMAC_MIN_ETHERNET_PKT_SIZE; + + return netcp_send(buffer, num_bytes, (slave_port_num) << 16); +} + +/* Eth device open */ +static int keystone2_eth_open(struct eth_device *dev, bd_t *bis) +{ + u_int32_t clkdiv; + int link; + struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; + + debug_emac("+ emac_open\n"); + + net_rx_buffs.rx_flow = eth_priv->rx_flow; + + sys_has_mdio = + (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) ? 1 : 0; + + psc_enable_module(KS2_LPSC_PA); + psc_enable_module(KS2_LPSC_CPGMAC); + + sgmii_serdes_setup_156p25mhz(); + + if (sys_has_mdio) + keystone2_eth_mdio_enable(); + + keystone_sgmii_config(eth_priv->slave_port - 1, + eth_priv->sgmii_link_type); + + udelay(10000); + + /* On chip switch configuration */ + ethss_config(target_get_switch_ctl(), SWITCH_MAX_PKT_SIZE); + + /* TODO: add error handling code */ + if (qm_init()) { + printf("ERROR: qm_init()\n"); + return -1; + } + if (netcp_init(&net_rx_buffs)) { + qm_close(); + printf("ERROR: netcp_init()\n"); + return -1; + } + + /* + * Streaming switch configuration. If not present this + * statement is defined to void in target.h. + * If present this is usually defined to a series of register writes + */ + hw_config_streaming_switch(); + + if (sys_has_mdio) { + /* Init MDIO & get link state */ + clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1; + writel((clkdiv & 0xff) | MDIO_CONTROL_ENABLE | + MDIO_CONTROL_FAULT, &adap_mdio->CONTROL) + ; + + /* We need to wait for MDIO to start */ + udelay(1000); + + link = keystone_get_link_status(dev); + if (link == 0) { + netcp_close(); + qm_close(); + return -1; + } + } + + emac_gigabit_enable(dev); + + ethss_start(); + + debug_emac("- emac_open\n"); + + emac_open = 1; + + return 0; +} + +/* Eth device close */ +void keystone2_eth_close(struct eth_device *dev) +{ + debug_emac("+ emac_close\n"); + + if (!emac_open) + return; + + ethss_stop(); + + netcp_close(); + qm_close(); + + emac_open = 0; + + debug_emac("- emac_close\n"); +} + +static int tx_send_loop; + +/* + * This function sends a single packet on the network and returns + * positive number (number of bytes transmitted) or negative for error + */ +static int keystone2_eth_send_packet(struct eth_device *dev, + void *packet, int length) +{ + int ret_status = -1; + struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; + + tx_send_loop = 0; + + if (keystone_get_link_status(dev) == 0) + return -1; + + emac_gigabit_enable(dev); + + if (cpmac_drv_send((u32 *)packet, length, eth_priv->slave_port) != 0) + return ret_status; + + if (keystone_get_link_status(dev) == 0) + return -1; + + emac_gigabit_enable(dev); + + return length; +} + +/* + * This function handles receipt of a packet from the network + */ +static int keystone2_eth_rcv_packet(struct eth_device *dev) +{ + void *hd; + int pkt_size; + u32 *pkt; + + hd = netcp_recv(&pkt, &pkt_size); + if (hd == NULL) + return 0; + + NetReceive((uchar *)pkt, pkt_size); + + netcp_release_rxhd(hd); + + return pkt_size; +} + +/* + * This function initializes the EMAC hardware. It does NOT initialize + * EMAC modules power or pin multiplexors, that is done by board_init() + * much earlier in bootup process. Returns 1 on success, 0 otherwise. + */ +int keystone2_emac_initialize(struct eth_priv_t *eth_priv) +{ + struct eth_device *dev; + static int phy_registered; + + dev = malloc(sizeof(struct eth_device)); + if (dev == NULL) + return -1; + + memset(dev, 0, sizeof(struct eth_device)); + + strcpy(dev->name, eth_priv->int_name); + dev->priv = eth_priv; + + keystone2_eth_read_mac_addr(dev); + + dev->iobase = 0; + dev->init = keystone2_eth_open; + dev->halt = keystone2_eth_close; + dev->send = keystone2_eth_send_packet; + dev->recv = keystone2_eth_rcv_packet; + + eth_register(dev); + + if (sys_has_mdio && !phy_registered) { + phy_registered = 1; +#ifdef CONFIG_ETH_PHY_MARVEL_88E1111 + sprintf(phy.name, "88E1111"); + phy.init = marvell_88e1111_init_phy; + phy.is_phy_connected = marvell_88e1111_is_phy_connected; + phy.get_link_speed = marvell_88e1111_get_link_speed; + phy.auto_negotiate = marvell_88e1111_auto_negotiate; +#else + sprintf(phy.name, "GENERIC"); + phy.init = gen_init_phy; + phy.is_phy_connected = gen_is_phy_connected; + phy.get_link_speed = gen_get_link_speed; + phy.auto_negotiate = gen_auto_negotiate; +#endif + miiphy_register(phy.name, keystone2_mii_phy_read, + keystone2_mii_phy_write); + } + + return 0; +} + +#define reg_rmw(addr, value, mask) \ + writel(((readl(addr) & (~(mask))) | (value)), (addr)) + +void sgmii_serdes_setup_156p25mhz() +{ + unsigned int cnt; + + reg_rmw(0x0232a000, 0x00800000, 0xffff0000); + reg_rmw(0x0232a014, 0x00008282, 0x0000ffff); + reg_rmw(0x0232a060, 0x00142438, 0x00ffffff); + reg_rmw(0x0232a064, 0x00c3c700, 0x00ffff00); + reg_rmw(0x0232a078, 0x0000c000, 0x0000ff00); + + reg_rmw(0x0232a204, 0x38000080, 0xff0000ff); + reg_rmw(0x0232a208, 0x00000000, 0x000000ff); + reg_rmw(0x0232a20c, 0x02000000, 0xff000000); + reg_rmw(0x0232a210, 0x1b000000, 0xff000000); + reg_rmw(0x0232a214, 0x00006fb8, 0x0000ffff); + reg_rmw(0x0232a218, 0x758000e4, 0xffff00ff); + reg_rmw(0x0232a2ac, 0x00004400, 0x0000ff00); + reg_rmw(0x0232a22c, 0x00200800, 0x00ffff00); + reg_rmw(0x0232a280, 0x00820082, 0x00ff00ff); + reg_rmw(0x0232a284, 0x1d0f0385, 0xffffffff); + + reg_rmw(0x0232a404, 0x38000080, 0xff0000ff); + reg_rmw(0x0232a408, 0x00000000, 0x000000ff); + reg_rmw(0x0232a40c, 0x02000000, 0xff000000); + reg_rmw(0x0232a410, 0x1b000000, 0xff000000); + reg_rmw(0x0232a414, 0x00006fb8, 0x0000ffff); + reg_rmw(0x0232a418, 0x758000e4, 0xffff00ff); + reg_rmw(0x0232a4ac, 0x00004400, 0x0000ff00); + reg_rmw(0x0232a42c, 0x00200800, 0x00ffff00); + reg_rmw(0x0232a480, 0x00820082, 0x00ff00ff); + reg_rmw(0x0232a484, 0x1d0f0385, 0xffffffff); + + reg_rmw(0x0232a604, 0x38000080, 0xff0000ff); + reg_rmw(0x0232a608, 0x00000000, 0x000000ff); + reg_rmw(0x0232a60c, 0x02000000, 0xff000000); + reg_rmw(0x0232a610, 0x1b000000, 0xff000000); + reg_rmw(0x0232a614, 0x00006fb8, 0x0000ffff); + reg_rmw(0x0232a618, 0x758000e4, 0xffff00ff); + reg_rmw(0x0232a6ac, 0x00004400, 0x0000ff00); + reg_rmw(0x0232a62c, 0x00200800, 0x00ffff00); + reg_rmw(0x0232a680, 0x00820082, 0x00ff00ff); + reg_rmw(0x0232a684, 0x1d0f0385, 0xffffffff); + + reg_rmw(0x0232a804, 0x38000080, 0xff0000ff); + reg_rmw(0x0232a808, 0x00000000, 0x000000ff); + reg_rmw(0x0232a80c, 0x02000000, 0xff000000); + reg_rmw(0x0232a810, 0x1b000000, 0xff000000); + reg_rmw(0x0232a814, 0x00006fb8, 0x0000ffff); + reg_rmw(0x0232a818, 0x758000e4, 0xffff00ff); + reg_rmw(0x0232a8ac, 0x00004400, 0x0000ff00); + reg_rmw(0x0232a82c, 0x00200800, 0x00ffff00); + reg_rmw(0x0232a880, 0x00820082, 0x00ff00ff); + reg_rmw(0x0232a884, 0x1d0f0385, 0xffffffff); + + reg_rmw(0x0232aa00, 0x00000800, 0x0000ff00); + reg_rmw(0x0232aa08, 0x38a20000, 0xffff0000); + reg_rmw(0x0232aa30, 0x008a8a00, 0x00ffff00); + reg_rmw(0x0232aa84, 0x00000600, 0x0000ff00); + reg_rmw(0x0232aa94, 0x10000000, 0xff000000); + reg_rmw(0x0232aaa0, 0x81000000, 0xff000000); + reg_rmw(0x0232aabc, 0xff000000, 0xff000000); + reg_rmw(0x0232aac0, 0x0000008b, 0x000000ff); + reg_rmw(0x0232ab08, 0x583f0000, 0xffff0000); + reg_rmw(0x0232ab0c, 0x0000004e, 0x000000ff); + reg_rmw(0x0232a000, 0x00000003, 0x000000ff); + reg_rmw(0x0232aa00, 0x0000005f, 0x000000ff); + + reg_rmw(0x0232aa48, 0x00fd8c00, 0x00ffff00); + reg_rmw(0x0232aa54, 0x002fec72, 0x00ffffff); + reg_rmw(0x0232aa58, 0x00f92100, 0xffffff00); + reg_rmw(0x0232aa5c, 0x00040060, 0xffffffff); + reg_rmw(0x0232aa60, 0x00008000, 0xffffffff); + reg_rmw(0x0232aa64, 0x0c581220, 0xffffffff); + reg_rmw(0x0232aa68, 0xe13b0602, 0xffffffff); + reg_rmw(0x0232aa6c, 0xb8074cc1, 0xffffffff); + reg_rmw(0x0232aa70, 0x3f02e989, 0xffffffff); + reg_rmw(0x0232aa74, 0x00000001, 0x000000ff); + reg_rmw(0x0232ab20, 0x00370000, 0x00ff0000); + reg_rmw(0x0232ab1c, 0x37000000, 0xff000000); + reg_rmw(0x0232ab20, 0x0000005d, 0x000000ff); + + /*Bring SerDes out of Reset if SerDes is Shutdown & is in Reset Mode*/ + reg_rmw(0x0232a010, 0x00000000, 1 << 28); + + /* Enable TX and RX via the LANExCTL_STS 0x0000 + x*4 */ + reg_rmw(0x0232a228, 0x00000000, 1 << 29); + writel(0xF800F8C0, 0x0232bfe0); + reg_rmw(0x0232a428, 0x00000000, 1 << 29); + writel(0xF800F8C0, 0x0232bfe4); + reg_rmw(0x0232a628, 0x00000000, 1 << 29); + writel(0xF800F8C0, 0x0232bfe8); + reg_rmw(0x0232a828, 0x00000000, 1 << 29); + writel(0xF800F8C0, 0x0232bfec); + + /*Enable pll via the pll_ctrl 0x0014*/ + writel(0xe0000000, 0x0232bff4) + ; + + /*Waiting for SGMII Serdes PLL lock.*/ + for (cnt = 10000; cnt > 0 && ((readl(0x02090114) & 0x10) == 0); cnt--) + ; + + for (cnt = 10000; cnt > 0 && ((readl(0x02090214) & 0x10) == 0); cnt--) + ; + + for (cnt = 10000; cnt > 0 && ((readl(0x02090414) & 0x10) == 0); cnt--) + ; + + for (cnt = 10000; cnt > 0 && ((readl(0x02090514) & 0x10) == 0); cnt--) + ; + + chip_delay(45000); +} + +void sgmii_serdes_shutdown() +{ + reg_rmw(0x0232bfe0, 0, 3 << 29 | 3 << 13); + reg_rmw(0x02320228, 1 << 29, 1 << 29); + reg_rmw(0x0232bfe4, 0, 3 << 29 | 3 << 13); + reg_rmw(0x02320428, 1 << 29, 1 << 29); + reg_rmw(0x0232bfe8, 0, 3 << 29 | 3 << 13); + reg_rmw(0x02320628, 1 << 29, 1 << 29); + reg_rmw(0x0232bfec, 0, 3 << 29 | 3 << 13); + reg_rmw(0x02320828, 1 << 29, 1 << 29); + + reg_rmw(0x02320034, 0, 3 << 29); + reg_rmw(0x02320010, 1 << 28, 1 << 28); +} + diff --git a/include/configs/k2hk_evm.h b/include/configs/k2hk_evm.h index 985db8e..33c7551 100644 --- a/include/configs/k2hk_evm.h +++ b/include/configs/k2hk_evm.h @@ -106,6 +106,23 @@ #define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 20 #define CONFIG_ENV_EEPROM_IS_ON_I2C
+/* Network Configuration */ +#define CONFIG_ETH_PHY_MARVEL_88E1111 + +#define CONFIG_DRIVER_TI_KEYSTONE_NET +#define CONFIG_MII +#define CONFIG_BOOTP_DEFAULT +#define CONFIG_BOOTP_DNS +#define CONFIG_BOOTP_DNS2 +#define CONFIG_BOOTP_SEND_HOSTNAME +#define CONFIG_NET_RETRY_COUNT 32 +#define CONFIG_NET_MULTI +#define CONFIG_GET_LINK_STATUS_ATTEMPTS 5 + +#define CONFIG_SYS_SGMII_REFCLK_MHZ 312 +#define CONFIG_SYS_SGMII_LINERATE_MHZ 1250 +#define CONFIG_SYS_SGMII_RATESCALE 2 + /* NAND Configuration */ #define CONFIG_NAND_DAVINCI #define CONFIG_SYS_NAND_CS 2 @@ -179,24 +196,45 @@ "addr_fs=0x82000000\0" \ "addr_ubi=0x82000000\0" \ "fdt_high=0xffffffff\0" \ + "name_fdt=uImage-k2hk-evm.dtb\0" \ + "name_fs=arago-console-image.cpio.gz\0" \ + "name_kern=uImage-keystone-evm.bin\0" \ + "name_mon=skern-keystone-evm.bin\0" \ + "name_uboot=u-boot-spi-keystone-evm.gph\0" \ + "name_ubi=keystone-evm-ubifs.ubi\0" \ "run_mon=mon_install ${addr_mon}\0" \ "run_kern=bootm ${addr_kern} - ${addr_fdt}\0" \ + "init_net=run args_all args_net\0" \ "init_ubi=run args_all args_ubi; " \ "ubi part ubifs; ubifsmount boot\0" \ + "get_fdt_net=dhcp ${addr_fdt} ${tftp_root}/${name_fdt}\0" \ "get_fdt_ubi=ubifsload ${addr_fdt} ${name_fdt}\0" \ + "get_kern_net=dhcp ${addr_kern} ${tftp_root}/${name_kern}\0" \ "get_kern_ubi=ubifsload ${addr_kern} ${name_kern}\0" \ + "get_mon_net=dhcp ${addr_mon} ${tftp_root}/${name_mon}\0" \ "get_mon_ubi=ubifsload ${addr_mon} ${name_mon}\0" \ + "get_uboot_net=dhcp ${addr_uboot} ${tftp_root}/${name_uboot}\0" \ "burn_uboot=sf probe; sf erase 0 0x100000; " \ "sf write ${addr_uboot} 0 ${filesize}\0" \ "args_all=setenv bootargs console=ttyS0,115200n8 rootwait=1\0" \ "args_ubi=setenv bootargs ${bootargs} rootfstype=ubifs " \ "root=ubi0:rootfs rootflags=sync rw ubi.mtd=2,2048\0" \ + "args_net=setenv bootargs ${bootargs} rootfstype=nfs " \ + "root=/dev/nfs rw nfsroot=${serverip}:${nfs_root}," \ + "${nfs_options} ip=dhcp\0" \ + "nfs_options=v3,tcp,rsize=4096,wsize=4096\0" \ + "get_fdt_ramfs=dhcp ${addr_fdt} ${tftp_root}/${name_fdt}\0" \ + "get_kern_ramfs=dhcp ${addr_kern} ${tftp_root}/${name_kern}\0" \ + "get_mon_ramfs=dhcp ${addr_mon} ${tftp_root}/${name_mon}\0" \ + "get_fs_ramfs=dhcp ${addr_fs} ${tftp_root}/${name_fs}\0" \ + "get_ubi_net=dhcp ${addr_ubi} ${tftp_root}/${name_ubi}\0" \ "burn_ubi=nand erase.part ubifs; " \ "nand write ${addr_ubi} ubifs ${filesize}\0" \ "init_ramfs=run args_all args_ramfs get_fs_ramfs\0" \ "args_ramfs=setenv bootargs ${bootargs} earlyprintk " \ "rdinit=/sbin/init rw root=/dev/ram0 " \ "initrd=0x802000000,9M\0" \ + "no_post=1\0" \ "mtdparts=mtdparts=davinci_nand.0:" \ "1024k(bootloader)ro,512k(params)ro,522752k(ubifs)\0" #define CONFIG_BOOTCOMMAND \

On Thu, Feb 20, 2014 at 12:55:12PM -0500, Murali Karicheri wrote:
From: Vitaly Andrianov vitalya@ti.com
Ethernet driver configures the CPSW, SGMI and Phy and uses the the Navigator APIs. The driver supports 4 Ethernet ports and can work with only one port at a time.
First, can we just use things in a "dumb" mode and use the existing CPSW driver? Or are there use cases we need to worry about here with a bigger / more robust network driver?
Port configurations are defined in board.c.
Signed-off-by: Vitaly Andrianov vitalya@ti.com Signed-off-by: Murali Karicheri m-karicheri2@ti.com Signed-off-by: WingMan Kwok w-kwok2@ti.com
[snip]
+/*#define chipLmbd(x,y) _lmbd(x,y) */
Don't add unused code.
+/* Marvell 88E1111 PHY ID */ +#define PHY_MARVELL_88E1111 (0x01410cc0)
+/* EMAC MDIO Registers Structure */ +struct mdio_regs {
- dv_reg VERSION;
- dv_reg CONTROL;
Why caps?
+++ b/drivers/net/keystone_net.c
Generic problem, please use phylib.
+#define debug_emac(fmt, args...) if (emac_dbg) printf(fmt, ##args)
We have debug() already.
+#ifdef KEYSTONE2_EMAC_GIG_ENABLE +#define emac_gigabit_enable(x) keystone2_eth_gigabit_enable(x) +#else +#define emac_gigabit_enable(x) /* no gigabit to enable */ +#endif
Do we need to do this?
+static void chip_delay(u32 del) +{
- volatile unsigned int i;
- for (i = 0; i < (del / 8); i++)
;
+}
Use one of the generic delays please.
+/* PHY functions for a generic PHY */ +static int __attribute__((unused)) gen_init_phy(int phy_addr)
Why are we adding tons of functions that we mark as unused?
+#if CONFIG_GET_LINK_STATUS_ATTEMPTS > 1
- int j;
- for (j = 0; (j < CONFIG_GET_LINK_STATUS_ATTEMPTS) && (link_state == 0);
j++) {
+#endif
New config option, do we really need this as an option?
+void sgmii_serdes_setup_156p25mhz() +{
- unsigned int cnt;
- reg_rmw(0x0232a000, 0x00800000, 0xffff0000);
Please comment on what we're doing here, and why we aren't using a struct to describe whatever is at 0x0232a000 ?
+void sgmii_serdes_shutdown() +{
- reg_rmw(0x0232bfe0, 0, 3 << 29 | 3 << 13);
Same.
Thanks!

On 2/25/2014 5:11 PM, Rini, Tom wrote:
On Thu, Feb 20, 2014 at 12:55:12PM -0500, Murali Karicheri wrote:
From: Vitaly Andrianov vitalya@ti.com
Ethernet driver configures the CPSW, SGMI and Phy and uses the the Navigator APIs. The driver supports 4 Ethernet ports and can work with only one port at a time.
First, can we just use things in a "dumb" mode and use the existing CPSW driver? Or are there use cases we need to worry about here with a bigger / more robust network driver?
First of all we believe the CPSW driver in u-boot is for tnetv107x CPSW hardware and keystone CPSW is different and more complex. We need to support different modes such as MAC to PHY, MAC to MAC and MAC to MAC forced. Also we are using a SGMII with up to 8 ports in the newer K2 devices. So we don't think we can re-use the CPSW driver.
+++ b/drivers/net/keystone_net.c
Generic problem, please use phylib.
Vitaly has done some prototyping with phy lib and found that this adds tons of code and huge time to change the active port. It doesn't give any advantage of using phylib as the driver make only very few reads from standard generic phy registers.
keystone driver has to support phy-less mode (different modes listed above) and using the phylib just unnecessary complicates the driver. So
Does phylib based drivers have similar scenario as in keystone? How does other platforms that uses phylib solves the above issues? Mainly delayed tftp and handling multiple modes?
We have taken care of all of comments here. So can we go with the current version of the driver and then switch to phylib implementation if the above issues can be solved on a phylib based implementation?
+void sgmii_serdes_setup_156p25mhz() +{
- unsigned int cnt;
- reg_rmw(0x0232a000, 0x00800000, 0xffff0000);
Please comment on what we're doing here, and why we aren't using a struct to describe whatever is at 0x0232a000 ?
+void sgmii_serdes_shutdown() +{
- reg_rmw(0x0232bfe0, 0, 3 << 29 | 3 << 13);
Same.
We will add comment here as we are using third party SERDES IP and the register names are not published by the vendor.
Thanks!

On Wed, Mar 12, 2014 at 03:04:04PM -0400, Murali Karicheri wrote:
On 2/25/2014 5:11 PM, Rini, Tom wrote:
On Thu, Feb 20, 2014 at 12:55:12PM -0500, Murali Karicheri wrote:
From: Vitaly Andrianov vitalya@ti.com
Ethernet driver configures the CPSW, SGMI and Phy and uses the the Navigator APIs. The driver supports 4 Ethernet ports and can work with only one port at a time.
First, can we just use things in a "dumb" mode and use the existing CPSW driver? Or are there use cases we need to worry about here with a bigger / more robust network driver?
First of all we believe the CPSW driver in u-boot is for tnetv107x CPSW hardware and
No, it's for the am335x and DRA7xx HW.
keystone CPSW is different and more complex. We need to support different modes such as MAC to PHY, MAC to MAC and MAC to MAC forced. Also we are using a SGMII with up to 8 ports in the newer K2 devices. So we don't think we can re-use the CPSW driver.
How many of these modes do we actually need to support in U-Boot? What usecase(s) do you have for networking in U-Boot? And I assume you're having similar conversations upstreaming the kernel networking driver (which does support am33xx/dra7xx and tnetv107x)..
+++ b/drivers/net/keystone_net.c
Generic problem, please use phylib.
Vitaly has done some prototyping with phy lib and found that this adds tons of code and huge time to change the active port. It doesn't give any advantage of using phylib as the driver make only very few reads from standard generic phy registers.
OK.
+void sgmii_serdes_setup_156p25mhz() +{
- unsigned int cnt;
- reg_rmw(0x0232a000, 0x00800000, 0xffff0000);
Please comment on what we're doing here, and why we aren't using a struct to describe whatever is at 0x0232a000 ?
+void sgmii_serdes_shutdown() +{
- reg_rmw(0x0232bfe0, 0, 3 << 29 | 3 << 13);
Same.
We will add comment here as we are using third party SERDES IP and the register names are not published by the vendor.
Please check what you are and are not allowed to say. It's usually the case with NDA'd docs that if you can release code based on the docs it doesn't have to be heavily obsucred and you can say what you're doing.

From: Rex Chang rchang@ti.com
Currently davinci spi driver supports only bus 0 cs 0. This patch allows driver to support bus 1 and bus 2 with configurable number of chip selects. Also defaults are selected in a way to avoid regression on other platforms that uses davinci spi driver and has only one spi bus.
Signed-off-by: Rex Chang rchang@ti.com Signed-off-by: Murali Karicheri m-karicheri2@ti.com --- drivers/spi/davinci_spi.c | 62 ++++++++++++++++++++++++++++++++++++++++++--- drivers/spi/davinci_spi.h | 33 ++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 4 deletions(-)
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c index e3fb321..c708a04 100644 --- a/drivers/spi/davinci_spi.c +++ b/drivers/spi/davinci_spi.c @@ -23,7 +23,7 @@ void spi_init() struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, unsigned int max_hz, unsigned int mode) { - struct davinci_spi_slave *ds; + struct davinci_spi_slave *ds;
if (!spi_cs_is_valid(bus, cs)) return NULL; @@ -32,7 +32,27 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, if (!ds) return NULL;
- ds->regs = (struct davinci_spi_regs *)CONFIG_SYS_SPI_BASE; + ds->slave.bus = bus; + ds->slave.cs = cs; + + switch (bus) { + case SPI0_BUS: + ds->regs = (struct davinci_spi_regs *)SPI0_BASE; + break; +#ifdef CONFIG_SYS_SPI1 + case SPI1_BUS: + ds->regs = (struct davinci_spi_regs *)SPI0_BASE; + break; +#endif +#ifdef CONFIG_SYS_SPI2 + case SPI2_BUS: + ds->regs = (struct davinci_spi_regs *)SPI2_BASE; + break; +#endif + default: /* Invalid bus number */ + return NULL; + } + ds->freq = max_hz;
return &ds->slave; @@ -59,7 +79,7 @@ int spi_claim_bus(struct spi_slave *slave) writel(SPIGCR1_MASTER_MASK | SPIGCR1_CLKMOD_MASK, &ds->regs->gcr1);
/* CS, CLK, SIMO and SOMI are functional pins */ - writel((SPIPC0_EN0FUN_MASK | SPIPC0_CLKFUN_MASK | + writel(((1 << slave->cs) | SPIPC0_CLKFUN_MASK | SPIPC0_DOFUN_MASK | SPIPC0_DIFUN_MASK), &ds->regs->pc0);
/* setup format */ @@ -262,9 +282,43 @@ out: return 0; }
+#ifdef CONFIG_SYS_SPI1 +static int bus1_cs_valid(unsigned int bus, unsigned int cs) +{ + if ((bus == SPI1_BUS) && (cs < SPI1_NUM_CS)) + return 1; + return 0; +} +#else +static int bus1_cs_valid(unsigned int bus, unsigned int cs) +{ + return 0; +} +#endif + +#ifdef CONFIG_SYS_SPI2 +static int bus2_cs_valid(unsigned int bus, unsigned int cs) +{ + if ((bus == SPI2_BUS) && (cs < SPI2_NUM_CS)) + return 1; + return 0; +} +#else +static int bus2_cs_valid(unsigned int bus, unsigned int cs) +{ + return 0; +} +#endif + int spi_cs_is_valid(unsigned int bus, unsigned int cs) { - return bus == 0 && cs == 0; + if ((bus == SPI0_BUS) && (cs < SPI0_NUM_CS)) + return 1; + else if (bus1_cs_valid(bus, cs)) + return 1; + else if (bus2_cs_valid(bus, cs)) + return 1; + return 0; }
void spi_cs_activate(struct spi_slave *slave) diff --git a/drivers/spi/davinci_spi.h b/drivers/spi/davinci_spi.h index 33f69b5..d4612d3 100644 --- a/drivers/spi/davinci_spi.h +++ b/drivers/spi/davinci_spi.h @@ -74,6 +74,39 @@ struct davinci_spi_regs { /* SPIDEF */ #define SPIDEF_CSDEF0_MASK BIT(0)
+#define SPI0_BUS 0 +#define SPI0_BASE CONFIG_SYS_SPI_BASE +/* + * Define default SPI0_NUM_CS as 1 for existing platforms that uses this + * driver. Platform can configure number of CS using CONFIG_SYS_SPI0_NUM_CS + * if more than one CS is supported and by defining CONFIG_SYS_SPI0. + */ +#ifndef CONFIG_SYS_SPI0 +#define SPI0_NUM_CS 1 +#else +#define SPI0_NUM_CS CONFIG_SYS_SPI0_NUM_CS +#endif + +/* + * define CONFIG_SYS_SPI1 when platform has spi-1 device (bus #1) and + * CONFIG_SYS_SPI1_NUM_CS defines number of CS on this bus + */ +#ifdef CONFIG_SYS_SPI1 +#define SPI1_BUS 1 +#define SPI1_NUM_CS CONFIG_SYS_SPI1_NUM_CS +#define SPI1_BASE CONFIG_SYS_SPI1_BASE +#endif + +/* + * define CONFIG_SYS_SPI2 when platform has spi-2 device (bus #2) and + * CONFIG_SYS_SPI2_NUM_CS defines number of CS on this bus + */ +#ifdef CONFIG_SYS_SPI2 +#define SPI2_BUS 2 +#define SPI2_NUM_CS CONFIG_SYS_SPI2_NUM_CS +#define SPI2_BASE CONFIG_SYS_SPI2_BASE +#endif + struct davinci_spi_slave { struct spi_slave slave; struct davinci_spi_regs *regs;

On Thu, Feb 20, 2014 at 12:55:13PM -0500, Murali Karicheri wrote:
From: Rex Chang rchang@ti.com
Currently davinci spi driver supports only bus 0 cs 0. This patch allows driver to support bus 1 and bus 2 with configurable number of chip selects. Also defaults are selected in a way to avoid regression on other platforms that uses davinci spi driver and has only one spi bus.
Signed-off-by: Rex Chang rchang@ti.com Signed-off-by: Murali Karicheri m-karicheri2@ti.com
drivers/spi/davinci_spi.c | 62 ++++++++++++++++++++++++++++++++++++++++++--- drivers/spi/davinci_spi.h | 33 ++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 4 deletions(-)
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c index e3fb321..c708a04 100644 --- a/drivers/spi/davinci_spi.c +++ b/drivers/spi/davinci_spi.c @@ -23,7 +23,7 @@ void spi_init() struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, unsigned int max_hz, unsigned int mode) {
- struct davinci_spi_slave *ds;
- struct davinci_spi_slave *ds;
Drop this whitespace change please. Then you can add:
Acked-by: Tom Rini trini@ti.com

currently only spi0 is enabled on k2hk evm. This configuration update is needed to enable spi1 and spi2.
Signed-off-by: Murali Karicheri m-karicheri2@ti.com --- include/configs/k2hk_evm.h | 9 +++++++++ 1 file changed, 9 insertions(+)
diff --git a/include/configs/k2hk_evm.h b/include/configs/k2hk_evm.h index 33c7551..861010a 100644 --- a/include/configs/k2hk_evm.h +++ b/include/configs/k2hk_evm.h @@ -85,7 +85,16 @@ #define CONFIG_SPI_FLASH #define CONFIG_SPI_FLASH_STMICRO #define CONFIG_DAVINCI_SPI +#define CONFIG_SYS_SPI0 #define CONFIG_SYS_SPI_BASE K2HK_SPI_BASE +#define CONFIG_SYS_SPI0_NUM_CS 4 +#define CONFIG_SYS_SPI1 +#define CONFIG_SYS_SPI1_BASE K2HK_SPI1_BASE +#define CONFIG_SYS_SPI1_NUM_CS 4 +#define CONFIG_SYS_SPI2 +#define CONFIG_SYS_SPI2_NUM_CS 4 +#define CONFIG_SYS_SPI2_BASE K2HK_SPI2_BASE +#define CONFIG_CMD_SPI #define CONFIG_SYS_SPI_CLK clk_get_rate(K2HK_LPSC_EMIF25_SPI) #define CONFIG_SF_DEFAULT_SPEED 30000000 #define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED

On Thu, Feb 20, 2014 at 12:55:14PM -0500, Murali Karicheri wrote:
currently only spi0 is enabled on k2hk evm. This configuration update is needed to enable spi1 and spi2.
Signed-off-by: Murali Karicheri m-karicheri2@ti.com
Acked-by: Tom Rini trini@ti.com

On Thu, Feb 20, 2014 at 12:55:02PM -0500, Murali Karicheri wrote:
This patch series add support for keystone2 SoC and K2HK EVM
In general, you ran checkpatch.pl right? I see some '#define<tab>' cases that need manual fixing up as well. Further comments and acks coming.

-----Original Message----- From: Tom Rini [mailto:tom.rini@gmail.com] On Behalf Of Rini, Tom Sent: Tuesday, February 25, 2014 5:11 PM To: Karicheri, Muralidharan Cc: u-boot@lists.denx.de Subject: Re: [U-Boot] [U-Boot PATCH v2 00/12] Add support for keystone2 SoC and K2HK EVM
On Thu, Feb 20, 2014 at 12:55:02PM -0500, Murali Karicheri wrote:
This patch series add support for keystone2 SoC and K2HK EVM
In general, you ran checkpatch.pl right? I see some '#define<tab>' cases that need manual fixing up as well. Further comments and acks coming.
Errors are fixed. However there are some warnings that doesn't make sense and are left as is.
Murali
-- Tom

On 2/25/2014 5:10 PM, Rini, Tom wrote:
On Thu, Feb 20, 2014 at 12:55:02PM -0500, Murali Karicheri wrote:
This patch series add support for keystone2 SoC and K2HK EVM
In general, you ran checkpatch.pl right? I see some '#define<tab>' cases that need manual fixing up as well. Further comments and acks coming.
Tom,
Just want to check with you what you want me to fix for #define <tab>. Generally from my Linux experience, I have seen #define used with tab. I looked at few header files and that have this tab in #define. So where this restriction come from? I looked into the Documentation/CodingStyle in Linux source tree and can't find any rule of not to use #define <tab>.
Murali

On Wed, Mar 12, 2014 at 03:21:26PM -0400, Murali Karicheri wrote:
On 2/25/2014 5:10 PM, Rini, Tom wrote:
On Thu, Feb 20, 2014 at 12:55:02PM -0500, Murali Karicheri wrote:
This patch series add support for keystone2 SoC and K2HK EVM
In general, you ran checkpatch.pl right? I see some '#define<tab>' cases that need manual fixing up as well. Further comments and acks coming.
Tom,
Just want to check with you what you want me to fix for #define <tab>. Generally from my Linux experience, I have seen #define used with tab. I looked at few header files and that have this tab in #define. So where this restriction come from? I looked into the Documentation/CodingStyle in Linux source tree and can't find any rule of not to use #define <tab>.
It's a thing here at least that yes, '#define<space>' only, and we do have a few things that need cleaning up.

-----Original Message----- From: Karicheri, Muralidharan Sent: Thursday, February 20, 2014 12:55 PM To: u-boot@lists.denx.de; Rini, Tom Cc: Karicheri, Muralidharan Subject: [U-Boot PATCH v2 00/12] Add support for keystone2 SoC and K2HK EVM
This patch series add support for keystone2 SoC and K2HK EVM
Change history: v2 - Review comments incorporated. Following are major comments addressed - split network driver to navigator driver + ethernet driver - replaced register base + offset implemenation with struct based register access implementation - Added Readme for NAND no subpage write option - re-use code for davinci i2c driver on keystone2 with updates - clock-k2hk.c merged to clock.c - currently keeping board specific getclk() command. See the thread for the rational. - Added update to davinci spi driver to re-use on keystone
v1 - added separate patch for sorting tools/Makefile entries - reworked gpimage patch to allow more re-use across omapimage/gpimage - dropped patch related to ubifs file size - added keystone SoC and K2HK EVM support
v0 - preparatory patch for keystone
Murali Karicheri (5): tools: sort the entries in Makefile tools: mkimage: add support for gpimage format NAND: DaVinci: allow forced disable of subpage writes i2c, davinci: move i2c_defs.h to the drivers/i2c directory k2hk-evm: add configuration for spi1 and spi2 support
Rex Chang (1): spi: davinci: add support for multiple bus and chip select
Vitaly Andrianov (6): fdt: call ft_board_setup_ex() at the end of image_setup_libfdt() arm: add support for arch timer i2c, davinci: add support for multiple i2c buses k2hk: add support for k2hk SOC and EVM keystone2: add keystone multicore navigator driver keystone2: net: add keystone ethernet driver
Makefile | 19 + README | 5 + arch/arm/cpu/armv7/keystone/Makefile | 18 + arch/arm/cpu/armv7/keystone/aemif.c | 71 ++ arch/arm/cpu/armv7/keystone/clock.c | 313 +++++++ arch/arm/cpu/armv7/keystone/cmd_clock.c | 124 +++ arch/arm/cpu/armv7/keystone/cmd_mon.c | 131 +++ arch/arm/cpu/armv7/keystone/config.mk | 15 + arch/arm/cpu/armv7/keystone/ddr3.c | 69 ++ arch/arm/cpu/armv7/keystone/init.c | 56 ++ arch/arm/cpu/armv7/keystone/keystone_nav.c | 376 +++++++++ arch/arm/cpu/armv7/keystone/msmc.c | 68 ++ arch/arm/cpu/armv7/keystone/psc.c | 238 ++++++ arch/arm/cpu/armv7/keystone/spl.c | 45 + arch/arm/include/asm/arch-davinci/i2c_defs.h | 71 +- arch/arm/include/asm/arch-keystone/clock-k2hk.h | 109 +++ arch/arm/include/asm/arch-keystone/clock.h | 17 + arch/arm/include/asm/arch-keystone/clock_defs.h | 121 +++ arch/arm/include/asm/arch-keystone/emac_defs.h | 250 ++++++ arch/arm/include/asm/arch-keystone/emif_defs.h | 73 ++ arch/arm/include/asm/arch-keystone/hardware-k2hk.h | 145 ++++ arch/arm/include/asm/arch-keystone/hardware.h | 175 ++++ arch/arm/include/asm/arch-keystone/i2c_defs.h | 17 + arch/arm/include/asm/arch-keystone/keystone_nav.h | 193 +++++ arch/arm/include/asm/arch-keystone/nand_defs.h | 25 + arch/arm/include/asm/arch-keystone/psc_defs.h | 90 ++ arch/arm/include/asm/arch-keystone/spl.h | 12 + arch/arm/lib/Makefile | 1 + arch/arm/lib/arch_timer.c | 58 ++ board/ti/k2hk_evm/Makefile | 9 + board/ti/k2hk_evm/README | 56 ++ board/ti/k2hk_evm/board.c | 301 +++++++ board/ti/k2hk_evm/ddr3.c | 269 ++++++ boards.cfg | 1 + common/image-fdt.c | 5 + common/image.c | 1 + drivers/i2c/davinci_i2c.c | 345 ++++---- drivers/i2c/davinci_i2c.h | 78 ++ drivers/mtd/nand/davinci_nand.c | 3 + drivers/net/Makefile | 1 + drivers/net/keystone_net.c | 859 ++++++++++++++++++++ drivers/serial/ns16550.c | 8 + drivers/spi/davinci_spi.c | 62 +- drivers/spi/davinci_spi.h | 33 + include/configs/k2hk_evm.h | 268 ++++++ include/fdt_support.h | 1 + include/image.h | 1 + tools/Makefile | 20 +- tools/gpheader.h | 40 + tools/gpimage-common.c | 80 ++ tools/gpimage.c | 77 ++ tools/imagetool.c | 2 + tools/imagetool.h | 1 + tools/omapimage.c | 104 +-- tools/omapimage.h | 5 - 55 files changed, 5222 insertions(+), 313 deletions(-) create mode 100644 arch/arm/cpu/armv7/keystone/Makefile create mode 100644 arch/arm/cpu/armv7/keystone/aemif.c create mode 100644 arch/arm/cpu/armv7/keystone/clock.c create mode 100644 arch/arm/cpu/armv7/keystone/cmd_clock.c create mode 100644 arch/arm/cpu/armv7/keystone/cmd_mon.c create mode 100644 arch/arm/cpu/armv7/keystone/config.mk create mode 100644 arch/arm/cpu/armv7/keystone/ddr3.c create mode 100644 arch/arm/cpu/armv7/keystone/init.c create mode 100644 arch/arm/cpu/armv7/keystone/keystone_nav.c create mode 100644 arch/arm/cpu/armv7/keystone/msmc.c create mode 100644 arch/arm/cpu/armv7/keystone/psc.c create mode 100644 arch/arm/cpu/armv7/keystone/spl.c create mode 100644 arch/arm/include/asm/arch- keystone/clock-k2hk.h create mode 100644 arch/arm/include/asm/arch-keystone/clock.h create mode 100644 arch/arm/include/asm/arch-keystone/clock_defs.h create mode 100644 arch/arm/include/asm/arch-keystone/emac_defs.h create mode 100644 arch/arm/include/asm/arch-keystone/emif_defs.h create mode 100644 arch/arm/include/asm/arch-keystone/hardware-k2hk.h create mode 100644 arch/arm/include/asm/arch-keystone/hardware.h create mode 100644 arch/arm/include/asm/arch-keystone/i2c_defs.h create mode 100644 arch/arm/include/asm/arch-keystone/keystone_nav.h create mode 100644 arch/arm/include/asm/arch-keystone/nand_defs.h create mode 100644 arch/arm/include/asm/arch-keystone/psc_defs.h create mode 100644 arch/arm/include/asm/arch-keystone/spl.h create mode 100644 arch/arm/lib/arch_timer.c create mode 100644 board/ti/k2hk_evm/Makefile create mode 100644 board/ti/k2hk_evm/README create mode 100644 board/ti/k2hk_evm/board.c create mode 100644 board/ti/k2hk_evm/ddr3.c create mode 100644 drivers/i2c/davinci_i2c.h create mode 100644 drivers/net/keystone_net.c create mode 100644 include/configs/k2hk_evm.h create mode 100644 tools/gpheader.h create mode 100644 tools/gpimage-common.c create mode 100644 tools/gpimage.c
-- 1.7.9.5
Hi,
Please review when you get a chance.
Thanks
Murali Karicheri Linux Kernel, Software Development

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 02/25/2014 05:49 PM, Karicheri, Muralidharan wrote:
-----Original Message----- From: Karicheri, Muralidharan Sent: Thursday, February 20, 2014 12:55 PM To: u-boot@lists.denx.de; Rini, Tom Cc: Karicheri, Muralidharan Subject: [U-Boot PATCH v2 00/12] Add support for keystone2 SoC and K2HK EVM
This patch series add support for keystone2 SoC and K2HK EVM
Change history: v2 - Review comments incorporated. Following are major comments addressed - split network driver to navigator driver + ethernet driver - replaced register base + offset implemenation with struct based register access implementation - Added Readme for NAND no subpage write option - re-use code for davinci i2c driver on keystone2 with updates - clock-k2hk.c merged to clock.c - currently keeping board specific getclk() command. See the thread for the rational. - Added update to davinci spi driver to re-use on keystone
v1 - added separate patch for sorting tools/Makefile entries - reworked gpimage patch to allow more re-use across omapimage/gpimage - dropped patch related to ubifs file size - added keystone SoC and K2HK EVM support
v0 - preparatory patch for keystone
Murali Karicheri (5): tools: sort the entries in Makefile tools: mkimage: add support for gpimage format NAND: DaVinci: allow forced disable of subpage writes i2c, davinci: move i2c_defs.h to the drivers/i2c directory k2hk-evm: add configuration for spi1 and spi2 support
Rex Chang (1): spi: davinci: add support for multiple bus and chip select
Vitaly Andrianov (6): fdt: call ft_board_setup_ex() at the end of image_setup_libfdt() arm: add support for arch timer i2c, davinci: add support for multiple i2c buses k2hk: add support for k2hk SOC and EVM keystone2: add keystone multicore navigator driver keystone2: net: add keystone ethernet driver
Makefile | 19 + README | 5 + arch/arm/cpu/armv7/keystone/Makefile | 18 + arch/arm/cpu/armv7/keystone/aemif.c | 71 ++ arch/arm/cpu/armv7/keystone/clock.c | 313 +++++++ arch/arm/cpu/armv7/keystone/cmd_clock.c | 124 +++ arch/arm/cpu/armv7/keystone/cmd_mon.c | 131 +++ arch/arm/cpu/armv7/keystone/config.mk | 15 + arch/arm/cpu/armv7/keystone/ddr3.c | 69 ++ arch/arm/cpu/armv7/keystone/init.c | 56 ++ arch/arm/cpu/armv7/keystone/keystone_nav.c | 376 +++++++++ arch/arm/cpu/armv7/keystone/msmc.c | 68 ++ arch/arm/cpu/armv7/keystone/psc.c | 238 ++++++ arch/arm/cpu/armv7/keystone/spl.c | 45
- arch/arm/include/asm/arch-davinci/i2c_defs.h | 71 +-
arch/arm/include/asm/arch-keystone/clock-k2hk.h | 109 +++ arch/arm/include/asm/arch-keystone/clock.h | 17 + arch/arm/include/asm/arch-keystone/clock_defs.h | 121 +++ arch/arm/include/asm/arch-keystone/emac_defs.h | 250 ++++++ arch/arm/include/asm/arch-keystone/emif_defs.h | 73 ++ arch/arm/include/asm/arch-keystone/hardware-k2hk.h | 145 ++++ arch/arm/include/asm/arch-keystone/hardware.h | 175 ++++ arch/arm/include/asm/arch-keystone/i2c_defs.h | 17 + arch/arm/include/asm/arch-keystone/keystone_nav.h | 193 +++++ arch/arm/include/asm/arch-keystone/nand_defs.h | 25 + arch/arm/include/asm/arch-keystone/psc_defs.h | 90 ++ arch/arm/include/asm/arch-keystone/spl.h | 12 + arch/arm/lib/Makefile | 1 + arch/arm/lib/arch_timer.c | 58 ++ board/ti/k2hk_evm/Makefile | 9 + board/ti/k2hk_evm/README | 56 ++ board/ti/k2hk_evm/board.c | 301 +++++++ board/ti/k2hk_evm/ddr3.c | 269 ++++++ boards.cfg | 1
- common/image-fdt.c | 5 +
common/image.c | 1 + drivers/i2c/davinci_i2c.c | 345 ++++---- drivers/i2c/davinci_i2c.h | 78 ++ drivers/mtd/nand/davinci_nand.c | 3
- drivers/net/Makefile | 1 +
drivers/net/keystone_net.c | 859 ++++++++++++++++++++ drivers/serial/ns16550.c | 8 + drivers/spi/davinci_spi.c | 62 +- drivers/spi/davinci_spi.h | 33
- include/configs/k2hk_evm.h | 268
++++++ include/fdt_support.h | 1
- include/image.h | 1 +
tools/Makefile | 20 +- tools/gpheader.h | 40 + tools/gpimage-common.c | 80 ++ tools/gpimage.c | 77 ++ tools/imagetool.c | 2 + tools/imagetool.h | 1 + tools/omapimage.c | 104 +-- tools/omapimage.h | 5 - 55 files changed, 5222 insertions(+), 313 deletions(-) create mode 100644 arch/arm/cpu/armv7/keystone/Makefile create mode 100644 arch/arm/cpu/armv7/keystone/aemif.c create mode 100644 arch/arm/cpu/armv7/keystone/clock.c create mode 100644 arch/arm/cpu/armv7/keystone/cmd_clock.c create mode 100644 arch/arm/cpu/armv7/keystone/cmd_mon.c create mode 100644 arch/arm/cpu/armv7/keystone/config.mk create mode 100644 arch/arm/cpu/armv7/keystone/ddr3.c create mode 100644 arch/arm/cpu/armv7/keystone/init.c create mode 100644 arch/arm/cpu/armv7/keystone/keystone_nav.c create mode 100644 arch/arm/cpu/armv7/keystone/msmc.c create mode 100644 arch/arm/cpu/armv7/keystone/psc.c create mode 100644 arch/arm/cpu/armv7/keystone/spl.c create mode 100644 arch/arm/include/asm/arch- keystone/clock-k2hk.h create mode 100644 arch/arm/include/asm/arch-keystone/clock.h create mode 100644 arch/arm/include/asm/arch-keystone/clock_defs.h create mode 100644 arch/arm/include/asm/arch-keystone/emac_defs.h create mode 100644 arch/arm/include/asm/arch-keystone/emif_defs.h create mode 100644 arch/arm/include/asm/arch-keystone/hardware-k2hk.h create mode 100644 arch/arm/include/asm/arch-keystone/hardware.h create mode 100644 arch/arm/include/asm/arch-keystone/i2c_defs.h create mode 100644 arch/arm/include/asm/arch-keystone/keystone_nav.h create mode 100644 arch/arm/include/asm/arch-keystone/nand_defs.h create mode 100644 arch/arm/include/asm/arch-keystone/psc_defs.h create mode 100644 arch/arm/include/asm/arch-keystone/spl.h create mode 100644 arch/arm/lib/arch_timer.c create mode 100644 board/ti/k2hk_evm/Makefile create mode 100644 board/ti/k2hk_evm/README create mode 100644 board/ti/k2hk_evm/board.c create mode 100644 board/ti/k2hk_evm/ddr3.c create mode 100644 drivers/i2c/davinci_i2c.h create mode 100644 drivers/net/keystone_net.c create mode 100644 include/configs/k2hk_evm.h create mode 100644 tools/gpheader.h create mode 100644 tools/gpimage-common.c create mode 100644 tools/gpimage.c
-- 1.7.9.5
Hi,
Please review when you get a chance.
I believe things have crossed in the ether, more or less.
- -- Tom
participants (5)
-
Andrianov, Vitaly
-
Karicheri, Muralidharan
-
Murali Karicheri
-
Scott Wood
-
Tom Rini