diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index b9b355a..fb9b0b8 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile @@ -12,6 +12,7 @@ endif board-$(CONFIG_MACH_PHYCORE_MPC5200B_TINY) := pcm030 +board-$(CONFIG_P1010RDB) := freescale-p1010rdb board-$(CONFIG_P2020RDB) := freescale-p2020rdb board-$(CONFIG_P1022DS) := freescale-p1022ds board-$(CONFIG_DA923RC) := geip-da923rc diff --git a/arch/ppc/boards/freescale-p1010rdb/Makefile b/arch/ppc/boards/freescale-p1010rdb/Makefile new file mode 100644 index 0000000..2a51091 --- /dev/null +++ b/arch/ppc/boards/freescale-p1010rdb/Makefile @@ -0,0 +1,4 @@ +obj-y += p1010rdb.o +obj-y += law.o +obj-y += tlb.o +obj-y += ddr.o \ No newline at end of file diff --git a/arch/ppc/boards/freescale-p1010rdb/config.h b/arch/ppc/boards/freescale-p1010rdb/config.h new file mode 100644 index 0000000..4f67183 --- /dev/null +++ b/arch/ppc/boards/freescale-p1010rdb/config.h @@ -0,0 +1,58 @@ +/* + * Copyright 2009-2011 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#define CFG_SYS_CLK_FREQ 66666666 +#define CFG_DDR_CLK_FREQ 66666666 + +#define CFG_CHIP_SELECTS_PER_CTRL 1 + +/* + * Memory map + * + * 0x0000_0000 0x3fff_ffff DDR 1G cacheable + * + * Localbus non-cacheable + * 0xee0_0000 0xefff_ffff FLASH 32M non-cacheable + * 0xffb0_0000 0xffb0_0fff PIXIS 4K Cacheable + * 0xffd0_0000 0xffd0_3fff L1 for stack 16K Cacheable TLB0 + */ +#define CFG_SDRAM_BASE 0x00000000 + +#define CFG_CCSRBAR_DEFAULT 0xff700000 +#define CFG_CCSRBAR 0xffe00000 +#define CFG_CCSRBAR_PHYS CFG_CCSRBAR +#define CFG_IMMR CFG_CCSRBAR + +#define CFG_INIT_RAM_ADDR 0xffd00000 +#define CFG_INIT_RAM_SIZE 0x00004000 +#define CFG_INIT_BI_SIZE 0x00000100 +#define CFG_INIT_SP_OFFSET (CFG_INIT_RAM_SIZE - CFG_INIT_BI_SIZE) + +#define CFG_BOOT_BLOCK 0xe0000000 +#define CFG_BOOT_BLOCK_PHYS CFG_BOOT_BLOCK +#define CFG_FLASH_BASE 0xee000000 +#define CFG_FLASH_BASE_PHYS CFG_FLASH_BASE +#define CFG_CPLD_BASE 0xffb00000 +#define CFG_CPLD_BASE_PHYS CFG_CPLD_BASE + +#define CFG_IFC_CSPR0 (CSPR_PHYS_ADDR(CFG_FLASH_BASE_PHYS) | \ + CSPR_PORT_SIZE_16 | CSPR_MSEL_NOR | \ + CSPR_V) +#define CFG_IFC_CSOR0 CSOR_NOR_ADM_SHIFT(7) +#define CFG_IFC_AMASK0 IFC_AMASK(32*1024*1024) + +#endif /* __CONFIG_H */ diff --git a/arch/ppc/boards/freescale-p1010rdb/ddr.c b/arch/ppc/boards/freescale-p1010rdb/ddr.c new file mode 100644 index 0000000..18069f4 --- /dev/null +++ b/arch/ppc/boards/freescale-p1010rdb/ddr.c @@ -0,0 +1,60 @@ +/* + * Copyright 2010 Freescale Semiconductor, Inc. + * Authors: Srikanth Srinivasan + * Timur Tabi + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "p1010rdb.h" + +static const u8 spd_addr = 0x52; + +int fsl_ddr_board_info(struct ddr_board_info_s *info) +{ + p1010rdb_early_init(); + + info->fsl_ddr_ver = 0; + info->ddr_base = IOMEM(MPC85xx_DDR_ADDR); + /* Actual number of chip select used */ + info->cs_per_ctrl = CFG_CHIP_SELECTS_PER_CTRL; + info->dimm_slots_per_ctrl = 1; + info->i2c_bus = 1; + info->i2c_slave = 0x7f; + info->i2c_speed = 400000; + info->i2c_base = IOMEM(I2C2_BASE_ADDR); + info->spd_i2c_addr = &spd_addr; + + return 0; +} + +void fsl_ddr_board_options(struct memctl_options_s *popts, + struct dimm_params_s *pdimm) +{ + popts->cs_local_opts[0].odt_rd_cfg = FSL_DDR_ODT_NEVER; + popts->cs_local_opts[0].odt_wr_cfg = FSL_DDR_ODT_CS; + popts->cs_local_opts[0].odt_rtt_norm = DDR3_RTT_40_OHM; + popts->cs_local_opts[0].odt_rtt_wr = DDR3_RTT_OFF; + + popts->clk_adjust = 6; + popts->cpo_override = 0x1f; + popts->write_data_delay = 2; + /* Write leveling override */ + popts->wrlvl_en = 1; + popts->wrlvl_override = 1; + popts->wrlvl_sample = 0xf; + popts->wrlvl_start = 0x8; + popts->trwt_override = 1; + popts->trwt = 0; + popts->dll_rst_dis = 1; +} diff --git a/arch/ppc/boards/freescale-p1010rdb/env/bin/init b/arch/ppc/boards/freescale-p1010rdb/env/bin/init new file mode 100644 index 0000000..c0e04c1 --- /dev/null +++ b/arch/ppc/boards/freescale-p1010rdb/env/bin/init @@ -0,0 +1,2 @@ +#!/bin/sh +source /env/config diff --git a/arch/ppc/boards/freescale-p1010rdb/env/config b/arch/ppc/boards/freescale-p1010rdb/env/config new file mode 100644 index 0000000..bffd868 --- /dev/null +++ b/arch/ppc/boards/freescale-p1010rdb/env/config @@ -0,0 +1,2 @@ +#!/bin/sh +export bootargs="root=/dev/nfs rw ip=bootp console=ttyS0,115200" \ No newline at end of file diff --git a/arch/ppc/boards/freescale-p1010rdb/law.c b/arch/ppc/boards/freescale-p1010rdb/law.c new file mode 100644 index 0000000..6edfbc2 --- /dev/null +++ b/arch/ppc/boards/freescale-p1010rdb/law.c @@ -0,0 +1,24 @@ +/* + * Copyright 2009-2010 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + * + */ + +#include +#include + +struct law_entry law_table[] = { + FSL_SET_LAW(CFG_BOOT_BLOCK_PHYS, LAW_SIZE_256M, LAW_TRGT_IF_IFC), + FSL_SET_LAW(CFG_CPLD_BASE_PHYS, LAW_SIZE_128K, LAW_TRGT_IF_IFC), +}; + +int num_law_entries = ARRAY_SIZE(law_table); diff --git a/arch/ppc/boards/freescale-p1010rdb/p1010rdb.c b/arch/ppc/boards/freescale-p1010rdb/p1010rdb.c new file mode 100644 index 0000000..5bae584 --- /dev/null +++ b/arch/ppc/boards/freescale-p1010rdb/p1010rdb.c @@ -0,0 +1,209 @@ +/* + * Copyright 2014 GE Intelligent Platforms, Inc. + * Copyright 2009-2011 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct gfar_info_struct gfar_info[] = { + { + .phyaddr = 1, + .tbiana = 0, + .tbicr = 0, + .mdiobus_tbi = 0, + }, + { + .phyaddr = 0, + .tbiana = 0x1a0, + .tbicr = 0x9140, + .mdiobus_tbi = 1, + }, + { + .phyaddr = 2, + .tbiana = 0x1a0, + .tbicr = 0x9140, + .mdiobus_tbi = 2, + }, +}; + +struct i2c_platform_data i2cplat[] = { + { .bitrate = 400000, }, + { .bitrate = 400000, }, +}; + +void p1010rdb_early_init(void) +{ + void __iomem *ifc = IFC_BASE_ADDR; + void __iomem *gur = IOMEM(MPC85xx_GUTS_ADDR); + + /* Clock configuration to access CPLD using IFC(GPCM) */ + setbits_be32(ifc + FSL_IFC_GCR_OFFSET, + 1 << IFC_GCR_TBCTL_TRN_TIME_SHIFT); + + /* Erratum A003549 */ + setbits_be32(gur + MPC85xx_GUTS_PMUXCR_OFFSET, + MPC85xx_PMUXCR_LCLK_IFC_CS3); + + /* Update CS0 timings to access boot flash */ + set_ifc_ftim(IFC_CS0, IFC_FTIM0, FTIM0_NOR_TACSE(0x4) | + FTIM0_NOR_TEADC(0x5) | FTIM0_NOR_TEAHC(0x5)); + set_ifc_ftim(IFC_CS0, IFC_FTIM1, FTIM1_NOR_TACO(0x1e) | + FTIM1_NOR_TRAD_NOR(0x0f)); + set_ifc_ftim(IFC_CS0, IFC_FTIM2, FTIM2_NOR_TCS(0x4) | + FTIM2_NOR_TCH(0x4) | FTIM2_NOR_TWP(0x1c)); + set_ifc_ftim(IFC_CS0, IFC_FTIM3, 0); + + /* Map the CPLD */ + set_ifc_cspr(IFC_CS3, CSPR_PHYS_ADDR(CFG_CPLD_BASE_PHYS) | + CSPR_PORT_SIZE_8 | CSPR_MSEL_GPCM | CSPR_V); + set_ifc_csor(IFC_CS3, 0); + set_ifc_amask(IFC_CS3, IFC_AMASK(64*1024)); + set_ifc_ftim(IFC_CS3, IFC_FTIM0, FTIM0_GPCM_TACSE(0xe) | + FTIM0_GPCM_TEADC(0x0e) | FTIM0_GPCM_TEAHC(0x0e)); + set_ifc_ftim(IFC_CS3, IFC_FTIM1, FTIM1_GPCM_TACO(0x1e) | + FTIM1_GPCM_TRAD(0x0f)); + set_ifc_ftim(IFC_CS3, IFC_FTIM2, FTIM2_GPCM_TCS(0xe) | + FTIM2_GPCM_TCH(0) | FTIM2_GPCM_TWP(0x1f)); + set_ifc_ftim(IFC_CS3, IFC_FTIM3, 0); + + /* PCIe reset through GPIO 4 */ + gpio_direction_output(4, 1); +} + +static void board_eth_init(void) +{ + fsl_eth_init(1, &gfar_info[0]); + fsl_eth_init(2, &gfar_info[1]); + fsl_eth_init(3, &gfar_info[2]); +} + +static int p1010rdb_devices_init(void) +{ + add_cfi_flash_device(DEVICE_ID_DYNAMIC, CFG_FLASH_BASE, 32 << 20, 0); + devfs_add_partition("nor0", 0x1f80000, 0x80000, DEVFS_PARTITION_FIXED, + "self0"); + devfs_add_partition("nor0", 0x1f60000, 0x10000, DEVFS_PARTITION_FIXED, + "env0"); + add_generic_device("i2c-fsl", 0, NULL, I2C1_BASE_ADDR, 0x100, + IORESOURCE_MEM, &i2cplat[0]); + add_generic_device("i2c-fsl", 1, NULL, I2C2_BASE_ADDR, 0x100, + IORESOURCE_MEM, &i2cplat[1]); + board_eth_init(); + + return 0; +} + +device_initcall(p1010rdb_devices_init); + +static struct NS16550_plat serial_plat = { + .clock = 0, + .shift = 0, +}; + +static int p1010rdb_console_init(void) +{ + barebox_set_model("Freescale P1010RDB"); + barebox_set_hostname("p1010rdb"); + + serial_plat.clock = fsl_get_bus_freq(0); + add_ns16550_device(1, CFG_IMMR + 0x4500, 16, + IORESOURCE_MEM | IORESOURCE_MEM_8BIT, &serial_plat); + return 0; +} + +console_initcall(p1010rdb_console_init); + +static int p1010rdb_mem_init(void) +{ + barebox_add_memory_bank("ram0", 0x0, fsl_get_effective_memsize()); + return 0; +} + +mem_initcall(p1010rdb_mem_init); + +static int p1010rdb_board_init_r(void) +{ + const uint32_t flashbase = CFG_BOOT_BLOCK; + const u8 flash_esel = e500_find_tlb_idx((void *)flashbase, 1); + + /* Flush d-cache and invalidate i-cache of any FLASH data */ + flush_dcache(); + invalidate_icache(); + + /* invalidate existing TLB entry for flash */ + e500_disable_tlb(flash_esel); + + /* + * Remap Boot flash region to caching-inhibited + * so that flash can be erased properly. + */ + e500_set_tlb(1, flashbase, CFG_BOOT_BLOCK_PHYS, + MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G, + 0, flash_esel, BOOKE_PAGESZ_256M, 1); + + fsl_l2_cache_init(); + + return 0; +} + +core_initcall(p1010rdb_board_init_r); + +static int fdt_board_setup(struct device_node *blob, void *unused) +{ + struct device_node *node; + + node = of_find_compatible_node(blob, NULL, "fsl,esdhc"); + if (node) + of_delete_node(node); + + node = of_find_compatible_node(blob, NULL, "fsl,starlite-tdm"); + if (node) + of_delete_node(node); + + node = of_find_compatible_node(blob, NULL, "fsl,p1010-flexcan"); + if (node) + of_delete_node(node); + + node = of_find_compatible_node(blob, NULL, "fsl,p1010-flexcan"); + if (node) + of_delete_node(node); + + return 0; +} + +static int of_register_p1010rdb_fixup(void) +{ + return of_register_fixup(fdt_board_setup, NULL); +} +late_initcall(of_register_p1010rdb_fixup); diff --git a/arch/ppc/boards/freescale-p1010rdb/p1010rdb.h b/arch/ppc/boards/freescale-p1010rdb/p1010rdb.h new file mode 100644 index 0000000..f325ff4 --- /dev/null +++ b/arch/ppc/boards/freescale-p1010rdb/p1010rdb.h @@ -0,0 +1,14 @@ +/* + * Copyright 2014 GE Intelligent Platforms, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ +void p1010rdb_early_init(void); diff --git a/arch/ppc/boards/freescale-p1010rdb/tlb.c b/arch/ppc/boards/freescale-p1010rdb/tlb.c new file mode 100644 index 0000000..23ef0f2 --- /dev/null +++ b/arch/ppc/boards/freescale-p1010rdb/tlb.c @@ -0,0 +1,59 @@ +/* + * Copyright 2011 Freescale Semiconductor, Inc. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the + * GNU General Public License for more details. + * + */ + +#include +#include + +struct fsl_e_tlb_entry tlb_table[] = { + /* TLB 0 - for temp stack in cache */ + FSL_SET_TLB_ENTRY(0, CFG_INIT_RAM_ADDR, CFG_INIT_RAM_ADDR, + MAS3_SX | MAS3_SW | MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + FSL_SET_TLB_ENTRY(0, CFG_INIT_RAM_ADDR + (4 * 1024), + CFG_INIT_RAM_ADDR + (4 * 1024), + MAS3_SX | MAS3_SW | MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + FSL_SET_TLB_ENTRY(0, CFG_INIT_RAM_ADDR + (8 * 1024), + CFG_INIT_RAM_ADDR + (8 * 1024), + MAS3_SX | MAS3_SW | MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + FSL_SET_TLB_ENTRY(0, CFG_INIT_RAM_ADDR + (12 * 1024), + CFG_INIT_RAM_ADDR + (12 * 1024), + MAS3_SX | MAS3_SW | MAS3_SR, 0, + 0, 0, BOOKE_PAGESZ_4K, 0), + + /* TLB 1 */ + /* *I*** - Covers boot page */ + FSL_SET_TLB_ENTRY(1, 0xfffff000, 0xfffff000, + MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G, + 0, 0, BOOKE_PAGESZ_4K, 1), + + /* *I*G* - CCSRBAR */ + FSL_SET_TLB_ENTRY(1, CFG_CCSRBAR, CFG_CCSRBAR_PHYS, + MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G, + 0, 1, BOOKE_PAGESZ_1M, 1), + + /* W**G* - Flash, localbus */ + /* This will be changed to *I*G* after relocation to RAM. */ + FSL_SET_TLB_ENTRY(1, CFG_BOOT_BLOCK, CFG_BOOT_BLOCK_PHYS, + MAS3_SX | MAS3_SR, MAS2_M | MAS2_W | MAS2_G, + 0, 2, BOOKE_PAGESZ_256M, 1), + + FSL_SET_TLB_ENTRY(1, CFG_CPLD_BASE, CFG_CPLD_BASE_PHYS, + MAS3_SX | MAS3_SW | MAS3_SR, MAS2_I | MAS2_G, + 0, 6, BOOKE_PAGESZ_128K, 1), +}; + +int num_tlb_entries = ARRAY_SIZE(tlb_table); diff --git a/arch/ppc/boards/geip-da923rc/product_data.c b/arch/ppc/boards/geip-da923rc/product_data.c index 09cd84d..0c46006 100644 --- a/arch/ppc/boards/geip-da923rc/product_data.c +++ b/arch/ppc/boards/geip-da923rc/product_data.c @@ -20,12 +20,20 @@ #include #include "product_data.h" +static int ge_pd_header_check(unsigned short header) +{ + if (header != 0xa5a5) + return -1; + else + return 0; +} + static int ge_is_data_valid(struct ge_product_data *v) { int crc, ret = 0; const unsigned char *p = (const unsigned char *)v; - if (v->v1.pdh.tag != 0xa5a5) + if (ge_pd_header_check(v->v1.pdh.tag)) return -1; switch (v->v1.pdh.version) { @@ -51,12 +59,20 @@ { struct i2c_adapter *adapter; struct i2c_client client; + unsigned int width = 0; int ret; adapter = i2c_get_adapter(0); client.addr = 0x51; client.adapter = adapter; ret = i2c_read_reg(&client, 0, (uint8_t *) productp, + sizeof(unsigned short)); + + /* If there is no valid header, it may be a 16-bit eeprom. */ + if (ge_pd_header_check(productp->v1.pdh.tag)) + width = I2C_ADDR_16_BIT; + + ret = i2c_read_reg(&client, width, (uint8_t *) productp, sizeof(struct ge_product_data)); if (ret == sizeof(struct ge_product_data)) diff --git a/arch/ppc/configs/p1010rdb_defconfig b/arch/ppc/configs/p1010rdb_defconfig new file mode 100644 index 0000000..d193940 --- /dev/null +++ b/arch/ppc/configs/p1010rdb_defconfig @@ -0,0 +1,55 @@ +CONFIG_ARCH_MPC85XX=y +CONFIG_P1010RDB=y +CONFIG_P101010=y +CONFIG_LONGHELP=y +CONFIG_GLOB=y +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +CONFIG_CMD_PARTITION=y +CONFIG_CMD_BOOTM_ZLIB=y +CONFIG_CMD_BOOTM_BZLIB=y +CONFIG_CMD_BOOTM_VERBOSE=y +CONFIG_ZLIB=y +CONFIG_BZLIB=y +CONFIG_CMD_EDIT=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_FLASH=y +CONFIG_CMD_RESET=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_GO=y +CONFIG_DEFAULT_ENVIRONMENT_GENERIC=n +CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/ppc/boards/freescale-p1010rdb/env/" +CONFIG_CMD_LOADENV=y +CONFIG_CMD_PRINTENV=y +CONFIG_CMD_SAVEENV=y +CONFIG_DRIVER_CFI=y +CONFIG_DRIVER_CFI_AMD=y +CONFIG_DRIVER_CFI_INTEL=y +CONFIG_DRIVER_CFI_BANK_WIDTH_1=n +CONFIG_DRIVER_CFI_BANK_WIDTH_2=y +CONFIG_DRIVER_CFI_BANK_WIDTH_4=n +CONFIG_CFI_BUFFER_WRITE=y +CONFIG_MTD=y +CONFIG_MTD_WRITE=y +CONFIG_MALLOC_SIZE=0x4000000 +CONFIG_BAUDRATE=115200 +CONFIG_DRIVER_SERIAL_NS16550=y +CONFIG_RELOCATABLE=y +CONFIG_DRIVER_NET_GIANFAR=y +CONFIG_NET=y +CONFIG_NET_PING=y +CONFIG_FS_TFTP=y +CONFIG_NET_TFTP=y +CONFIG_CMD_TFTP=y +CONFIG_PING=y +CONFIG_I2C=y +CONFIG_I2C_IMX=y +CONFIG_CMD_I2C=y +CONFIG_CMD_MIITOOL=y +CONFIG_CMD_EXPORT=y +CONFIG_OFTREE=y +CONFIG_CMD_OFTREE_PROBE=y +CONFIG_CMD_OFTREE=y +CONFIG_CMD_BAREBOX_UPDATE=y +CONFIG_CMD_IOMEM=y +CONFIG_CMD_MEMTEST=y diff --git a/arch/ppc/cpu-85xx/start.S b/arch/ppc/cpu-85xx/start.S index 514fd8c..82c2c0a 100644 --- a/arch/ppc/cpu-85xx/start.S +++ b/arch/ppc/cpu-85xx/start.S @@ -105,6 +105,29 @@ isync .endm + .macro create_tlb0_entry esel ts tsize epn wimg rpn perm phy_high \ + scratch + lis \scratch, FSL_BOOKE_MAS0(0, \esel, 0)@h + ori \scratch, \scratch, FSL_BOOKE_MAS0(0, \esel, 0)@l + mtspr MAS0, \scratch + lis \scratch, FSL_BOOKE_MAS1(1, 0, 0, \ts, \tsize)@h + ori \scratch, \scratch, FSL_BOOKE_MAS1(1, 0, 0, \ts, \tsize)@l + mtspr MAS1, \scratch + lis \scratch, FSL_BOOKE_MAS2(\epn, \wimg)@h + ori \scratch, \scratch, FSL_BOOKE_MAS2(\epn, \wimg)@l + mtspr MAS2, \scratch + lis \scratch, FSL_BOOKE_MAS3(\rpn, 0, \perm)@h + ori \scratch, \scratch, FSL_BOOKE_MAS3(\rpn, 0, \perm)@l + mtspr MAS3, \scratch + lis \scratch, \phy_high@h + ori \scratch, \scratch, \phy_high@l + mtspr MAS7, \scratch + isync + msync + tlbwe + isync + .endm + /* Setup interrupt vectors */ lis r1,TEXT_BASE@h mtspr IVPR,r1 @@ -278,6 +301,89 @@ 0, r6 #endif +/* + * Relocate CCSR, if necessary. We relocate CCSR if (obviously) the default + * location is not where we want it. This typically happens on a 36-bit + * system, where we want to move CCSR to near the top of 36-bit address space. + * + * To move CCSR, we create two temporary TLBs, one for the old location, and + * another for the new location. On CoreNet systems, we also need to create + * a special, temporary LAW. + * + * As a general rule, TLB0 is used for short-term TLBs, and TLB1 is used for + * long-term TLBs, so we use TLB0 here. + */ +#if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR_PHYS) +create_ccsr_new_tlb: + /* + * Create a TLB for the new location of CCSR. Register R8 is reserved + * for the virtual address of this TLB (CFG_CCSRBAR). + */ + lis r8, CFG_CCSRBAR@h + ori r8, r8, CFG_CCSRBAR@l + lis r9, (CFG_CCSRBAR + 0x1000)@h + ori r9, r9, (CFG_CCSRBAR + 0x1000)@l + create_tlb0_entry 0, \ + 0, BOOKE_PAGESZ_4K, \ + CFG_CCSRBAR, MAS2_I|MAS2_G, \ + CFG_CCSRBAR_PHYS, MAS3_SW|MAS3_SR, \ + 0, r3 + + /* + * Create a TLB for the current location of CCSR. Register R9 is + * reserved for the virtual address of this TLB (CFG_CCSRBAR + 0x1000). + */ +create_ccsr_old_tlb: + create_tlb0_entry 1, \ + 0, BOOKE_PAGESZ_4K, \ + CFG_CCSRBAR + 0x1000, MAS2_I|MAS2_G, \ + CFG_CCSRBAR_DEFAULT, MAS3_SW|MAS3_SR, \ + 0, r3 + + /* + * We have a TLB for what we think is the current (old) CCSR. Let's + * verify that, otherwise we won't be able to move it. + * CFG_CCSRBAR_DEFAULT is always a 32-bit number, so we only + * need to compare the lower 32 bits of CCSRBAR on CoreNet systems. + */ +verify_old_ccsr: + lis r0, CFG_CCSRBAR_DEFAULT@h + ori r0, r0, CFG_CCSRBAR_DEFAULT@l + lwz r1, 0(r9) + slwi r1, r1, 12 + cmpl 0, r0, r1 + + /* + * If the value we read from CCSRBAR is not what we expect, then + * enter an infinite loop. This will at least allow a debugger to + * halt execution and examine TLBs, etc. There's no point in going + * on. + */ +infinite_debug_loop: + bne infinite_debug_loop + + /* + * Read the current value of CCSRBAR using a load word instruction + * followed by an isync. This forces all accesses to configuration + * space to complete. + */ +write_new_ccsrbar: + sync + lwz r0, 0(r9) + isync + lis r0, (CFG_CCSRBAR_PHYS >> 12)@h + ori r0, r0, (CFG_CCSRBAR_PHYS >> 12)@l + stw r0, 0(r9) + sync + isync + + /* + * Read the contents of CCSRBAR from its new location, followed by + * another isync. + */ + lwz r0, 0(r8) + isync +#endif /* Enable/invalidate the I-Cache */ lis r2,(L1CSR1_ICFI|L1CSR1_ICLFR)@h diff --git a/arch/ppc/include/asm/fsl_ifc.h b/arch/ppc/include/asm/fsl_ifc.h new file mode 100644 index 0000000..8faff75 --- /dev/null +++ b/arch/ppc/include/asm/fsl_ifc.h @@ -0,0 +1,267 @@ +/* + * Copyright 2010-2011 Freescale Semiconductor, Inc. + * Author: Dipen Dudhat + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __FSL_IFC_H +#define __FSL_IFC_H + +#include +#include + +/* Big-Endian */ +#define ifc_in32(a) in_be32(a) +#define ifc_out32(a, v) out_be32(a, v) +#define ifc_in16(a) in_be16(a) + +/* + * CSPR - Chip Select Property Register + */ +#define CSPR_BA 0xFFFF0000 +#define CSPR_BA_SHIFT 16 +#define CSPR_PORT_SIZE 0x00000180 +#define CSPR_PORT_SIZE_SHIFT 7 +#define CSPR_PORT_SIZE_8 0x00000080 +#define CSPR_PORT_SIZE_16 0x00000100 +#define CSPR_PORT_SIZE_32 0x00000180 +/* Write Protect */ +#define CSPR_WP 0x00000040 +#define CSPR_WP_SHIFT 6 +#define CSPR_MSEL 0x00000006 +#define CSPR_MSEL_SHIFT 1 +#define CSPR_MSEL_NOR 0x00000000 +#define CSPR_MSEL_NAND 0x00000002 +#define CSPR_MSEL_GPCM 0x00000004 +#define CSPR_V 0x00000001 +#define CSPR_V_SHIFT 0 + +/* Convert an address into the right format for the CSPR Registers */ +#define CSPR_PHYS_ADDR(x) (((uint64_t)x) & 0xffff0000) + +/* + * Address Mask Register + */ +#define IFC_AMASK_MASK 0xFFFF0000 +#define IFC_AMASK_SHIFT 16 +#define IFC_AMASK(n) (IFC_AMASK_MASK << \ + (__ilog2(n) - IFC_AMASK_SHIFT)) + +/* + * Chip Select Option Register IFC_NAND Machine + */ +#define CSOR_NAND_ECC_ENC_EN 0x80000000 +#define CSOR_NAND_ECC_MODE_MASK 0x30000000 +/* 4 bit correction per 520 Byte sector */ +#define CSOR_NAND_ECC_MODE_4 0x00000000 +/* 8 bit correction per 528 Byte sector */ +#define CSOR_NAND_ECC_MODE_8 0x10000000 +#define CSOR_NAND_ECC_DEC_EN 0x04000000 +/* Row Address Length */ +#define CSOR_NAND_RAL_MASK 0x01800000 +#define CSOR_NAND_RAL_SHIFT 20 +#define CSOR_NAND_RAL_1 0x00000000 +#define CSOR_NAND_RAL_2 0x00800000 +#define CSOR_NAND_RAL_3 0x01000000 +#define CSOR_NAND_RAL_4 0x01800000 +/* Page Size 512b, 2k, 4k */ +#define CSOR_NAND_PGS_MASK 0x00180000 +#define CSOR_NAND_PGS_SHIFT 16 +#define CSOR_NAND_PGS_512 0x00000000 +#define CSOR_NAND_PGS_2K 0x00080000 +#define CSOR_NAND_PGS_4K 0x00100000 +#define CSOR_NAND_PGS_8K 0x00180000 +/* Spare region Size */ +#define CSOR_NAND_SPRZ_MASK 0x0000E000 +#define CSOR_NAND_SPRZ_SHIFT 13 +#define CSOR_NAND_SPRZ_16 0x00000000 +#define CSOR_NAND_SPRZ_64 0x00002000 +#define CSOR_NAND_SPRZ_128 0x00004000 +#define CSOR_NAND_SPRZ_210 0x00006000 +#define CSOR_NAND_SPRZ_218 0x00008000 +#define CSOR_NAND_SPRZ_224 0x0000A000 +#define CSOR_NAND_SPRZ_CSOR_EXT 0x0000C000 +/* Pages Per Block */ +#define CSOR_NAND_PB_MASK 0x00000700 +#define CSOR_NAND_PB_SHIFT 8 +#define CSOR_NAND_PB(n) ((__ilog2(n) - 5) << CSOR_NAND_PB_SHIFT) +/* Time for Read Enable High to Output High Impedance */ +#define CSOR_NAND_TRHZ_MASK 0x0000001C +#define CSOR_NAND_TRHZ_SHIFT 2 +#define CSOR_NAND_TRHZ_20 0x00000000 +#define CSOR_NAND_TRHZ_40 0x00000004 +#define CSOR_NAND_TRHZ_60 0x00000008 +#define CSOR_NAND_TRHZ_80 0x0000000C +#define CSOR_NAND_TRHZ_100 0x00000010 +/* Buffer control disable */ +#define CSOR_NAND_BCTLD 0x00000001 + +/* + * Chip Select Option Register - NOR Flash Mode + */ +/* Enable Address shift Mode */ +#define CSOR_NOR_ADM_SHFT_MODE_EN 0x80000000 +/* Page Read Enable from NOR device */ +#define CSOR_NOR_PGRD_EN 0x10000000 +/* AVD Toggle Enable during Burst Program */ +#define CSOR_NOR_AVD_TGL_PGM_EN 0x01000000 +/* Address Data Multiplexing Shift */ +#define CSOR_NOR_ADM_MASK 0x0003E000 +#define CSOR_NOR_ADM_SHIFT_SHIFT 13 +#define CSOR_NOR_ADM_SHIFT(n) ((n) << CSOR_NOR_ADM_SHIFT_SHIFT) +/* Type of the NOR device hooked */ +#define CSOR_NOR_NOR_MODE_AYSNC_NOR 0x00000000 +#define CSOR_NOR_NOR_MODE_AVD_NOR 0x00000020 +/* Time for Read Enable High to Output High Impedance */ +#define CSOR_NOR_TRHZ_MASK 0x0000001C +#define CSOR_NOR_TRHZ_SHIFT 2 +#define CSOR_NOR_TRHZ_20 0x00000000 +#define CSOR_NOR_TRHZ_40 0x00000004 +#define CSOR_NOR_TRHZ_60 0x00000008 +#define CSOR_NOR_TRHZ_80 0x0000000C +#define CSOR_NOR_TRHZ_100 0x00000010 +/* Buffer control disable */ +#define CSOR_NOR_BCTLD 0x00000001 + +/* + * Flash Timing Registers (FTIM0 - FTIM2_CSn) + */ + +/* + * FTIM0 - NOR Flash Mode + */ +#define FTIM0_NOR 0xF03F3F3F +#define FTIM0_NOR_TACSE_SHIFT 28 +#define FTIM0_NOR_TACSE(n) ((n) << FTIM0_NOR_TACSE_SHIFT) +#define FTIM0_NOR_TEADC_SHIFT 16 +#define FTIM0_NOR_TEADC(n) ((n) << FTIM0_NOR_TEADC_SHIFT) +#define FTIM0_NOR_TAVDS_SHIFT 8 +#define FTIM0_NOR_TAVDS(n) ((n) << FTIM0_NOR_TAVDS_SHIFT) +#define FTIM0_NOR_TEAHC_SHIFT 0 +#define FTIM0_NOR_TEAHC(n) ((n) << FTIM0_NOR_TEAHC_SHIFT) +/* + * FTIM1 - NOR Flash Mode + */ +#define FTIM1_NOR 0xFF003F3F +#define FTIM1_NOR_TACO_SHIFT 24 +#define FTIM1_NOR_TACO(n) ((n) << FTIM1_NOR_TACO_SHIFT) +#define FTIM1_NOR_TRAD_NOR_SHIFT 8 +#define FTIM1_NOR_TRAD_NOR(n) ((n) << FTIM1_NOR_TRAD_NOR_SHIFT) +#define FTIM1_NOR_TSEQRAD_NOR_SHIFT 0 +#define FTIM1_NOR_TSEQRAD_NOR(n) ((n) << FTIM1_NOR_TSEQRAD_NOR_SHIFT) +/* + * FTIM2 - NOR Flash Mode + */ +#define FTIM2_NOR 0x0F3CFCFF +#define FTIM2_NOR_TCS_SHIFT 24 +#define FTIM2_NOR_TCS(n) ((n) << FTIM2_NOR_TCS_SHIFT) +#define FTIM2_NOR_TCH_SHIFT 18 +#define FTIM2_NOR_TCH(n) ((n) << FTIM2_NOR_TCH_SHIFT) +#define FTIM2_NOR_TWPH_SHIFT 10 +#define FTIM2_NOR_TWPH(n) ((n) << FTIM2_NOR_TWPH_SHIFT) +#define FTIM2_NOR_TWP_SHIFT 0 +#define FTIM2_NOR_TWP(n) ((n) << FTIM2_NOR_TWP_SHIFT) + +/* + * FTIM0 - Normal GPCM Mode + */ +#define FTIM0_GPCM 0xF03F3F3F +#define FTIM0_GPCM_TACSE_SHIFT 28 +#define FTIM0_GPCM_TACSE(n) ((n) << FTIM0_GPCM_TACSE_SHIFT) +#define FTIM0_GPCM_TEADC_SHIFT 16 +#define FTIM0_GPCM_TEADC(n) ((n) << FTIM0_GPCM_TEADC_SHIFT) +#define FTIM0_GPCM_TAVDS_SHIFT 8 +#define FTIM0_GPCM_TAVDS(n) ((n) << FTIM0_GPCM_TAVDS_SHIFT) +#define FTIM0_GPCM_TEAHC_SHIFT 0 +#define FTIM0_GPCM_TEAHC(n) ((n) << FTIM0_GPCM_TEAHC_SHIFT) +/* + * FTIM1 - Normal GPCM Mode + */ +#define FTIM1_GPCM 0xFF003F00 +#define FTIM1_GPCM_TACO_SHIFT 24 +#define FTIM1_GPCM_TACO(n) ((n) << FTIM1_GPCM_TACO_SHIFT) +#define FTIM1_GPCM_TRAD_SHIFT 8 +#define FTIM1_GPCM_TRAD(n) ((n) << FTIM1_GPCM_TRAD_SHIFT) +/* + * FTIM2 - Normal GPCM Mode + */ +#define FTIM2_GPCM 0x0F3C00FF +#define FTIM2_GPCM_TCS_SHIFT 24 +#define FTIM2_GPCM_TCS(n) ((n) << FTIM2_GPCM_TCS_SHIFT) +#define FTIM2_GPCM_TCH_SHIFT 18 +#define FTIM2_GPCM_TCH(n) ((n) << FTIM2_GPCM_TCH_SHIFT) +#define FTIM2_GPCM_TWP_SHIFT 0 +#define FTIM2_GPCM_TWP(n) ((n) << FTIM2_GPCM_TWP_SHIFT) + +/* + * General Control Register (GCR) + */ +#define IFC_GCR_MASK 0x8000F800 +/* reset all IFC hardware */ +#define IFC_GCR_SOFT_RST_ALL 0x80000000 +/* Turnaroud Time of external buffer */ +#define IFC_GCR_TBCTL_TRN_TIME 0x0000F800 +#define IFC_GCR_TBCTL_TRN_TIME_SHIFT 11 + +/* + * Clock Control Register (CCR) + */ +#define IFC_CCR_MASK 0x0F0F8800 +/* Clock division ratio */ +#define IFC_CCR_CLK_DIV_MASK 0x0F000000 +#define IFC_CCR_CLK_DIV_SHIFT 24 +#define IFC_CCR_CLK_DIV(n) ((n-1) << IFC_CCR_CLK_DIV_SHIFT) +/* IFC Clock Delay */ +#define IFC_CCR_CLK_DLY_MASK 0x000F0000 +#define IFC_CCR_CLK_DLY_SHIFT 16 +#define IFC_CCR_CLK_DLY(n) ((n) << IFC_CCR_CLK_DLY_SHIFT) + +#ifndef __ASSEMBLY__ +#include + +#define IFC_BASE_ADDR ((void __iomem *)IFC_ADDR) +#define FSL_IFC_CSPRX(i) (0x10 + ((i) * 0xc)) +#define FSL_IFC_CSORX(i) (0x130 + ((i) * 0xc)) +#define FSL_IFC_AMASKX(i) (0xa0 + ((i) * 0xc)) +#define FSL_IFC_CSX_FTIMY(i, j) ((0x1c0 + ((i) * 0x30)) + ((j) * 4)) + +#define get_ifc_cspr(i) (ifc_in32(IFC_BASE_ADDR + FSL_IFC_CSPRX(i))) +#define get_ifc_csor(i) (ifc_in32(IFC_BASE_ADDR + FSL_IFC_CSORX(i)) +#define get_ifc_amask(i) (ifc_in32(IFC_BASE_ADDR + FSL_IFC_AMASKX(i))) +#define get_ifc_ftim(i, j) (ifc_in32(IFC_BASE_ADDR + FSL_IFC_CSX_FTIMY(i, j))) + +#define set_ifc_cspr(i, v) (ifc_out32(IFC_BASE_ADDR + FSL_IFC_CSPRX(i), v)) +#define set_ifc_csor(i, v) (ifc_out32(IFC_BASE_ADDR + FSL_IFC_CSORX(i), v)) +#define set_ifc_amask(i, v) (ifc_out32(IFC_BASE_ADDR + FSL_IFC_AMASKX(i), v)) +#define set_ifc_ftim(i, j, v) \ + (ifc_out32(IFC_BASE_ADDR + FSL_IFC_CSX_FTIMY(i, j), v)) + +#define FSL_IFC_GCR_OFFSET 0x40c +#define FSL_IFC_CCR_OFFSET 0x44c + +enum ifc_chip_sel { + IFC_CS0, + IFC_CS1, + IFC_CS2, + IFC_CS3, + IFC_CS4, + IFC_CS5, + IFC_CS6, + IFC_CS7, +}; + +enum ifc_ftims { + IFC_FTIM0, + IFC_FTIM1, + IFC_FTIM2, + IFC_FTIM3, +}; + +#ifdef CONFIG_FSL_ERRATUM_IFC_A002769 +#undef CSPR_MSEL_NOR +#define CSPR_MSEL_NOR CSPR_MSEL_GPCM +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __FSL_IFC_H */ diff --git a/arch/ppc/include/asm/fsl_law.h b/arch/ppc/include/asm/fsl_law.h index 813a8ee..7acb63c 100644 --- a/arch/ppc/include/asm/fsl_law.h +++ b/arch/ppc/include/asm/fsl_law.h @@ -69,6 +69,7 @@ #define LAW_TRGT_IF_PCIX LAW_TRGT_IF_PCI #define LAW_TRGT_IF_PCIE_2 LAW_TRGT_IF_PCI_2 #define LAW_TRGT_IF_RIO_1 LAW_TRGT_IF_RIO +#define LAW_TRGT_IF_IFC LAW_TRGT_IF_LBC #if defined(CONFIG_P2020) diff --git a/arch/ppc/include/asm/processor.h b/arch/ppc/include/asm/processor.h index c9633fe..e8a9c14 100644 --- a/arch/ppc/include/asm/processor.h +++ b/arch/ppc/include/asm/processor.h @@ -851,7 +851,7 @@ #define SVR_MIN(svr) (((svr) >> 0) & 0xF) /* Minor revision field*/ /* Some parts define SVR[0:23] as the SOC version */ -#define SVR_SOC_VER(svr) (((svr) >> 8) & 0xFFFFFF) /* SOC Version fields */ +#define SVR_SOC_VER(svr) (((svr) >> 8) & 0xFFF7FF) /* SOC w/o E bit */ #define IS_E_PROCESSOR(svr) ((svr) & 0x80000) /* @@ -867,6 +867,7 @@ #define SVR_8641 0x8090 #define SVR_8544 0x803401 #define SVR_8544_E 0x803C01 +#define SVR_P1010 0x80F100 #define SVR_P1022 0x80E600 #define SVR_P2020 0x80E200 #define SVR_P2020_E 0x80EA00 diff --git a/arch/ppc/mach-mpc85xx/Kconfig b/arch/ppc/mach-mpc85xx/Kconfig index ec5f04c..e29be9c 100644 --- a/arch/ppc/mach-mpc85xx/Kconfig +++ b/arch/ppc/mach-mpc85xx/Kconfig @@ -5,17 +5,17 @@ config BTB bool - default y if P2020RDB || P1022DS || DA923RC + default y config TEXT_BASE hex - default 0xeff80000 if P2020RDB || P1022DS + default 0xeff80000 if P1010RDB || P2020RDB || P1022DS default 0xfff80000 if DA923RC config RESET_VECTOR_ADDRESS hex default 0xfffffffc if DA923RC - default 0xeffffffc if P2020RDB || P1022DS + default 0xeffffffc if P1010RDB || P2020RDB || P1022DS config MPC85xx bool @@ -31,55 +31,78 @@ choice prompt "Select your board" +config P1010RDB + bool "P1010RDB" + select P1010 + select DDR_SPD + select FSL_DDR3 + help + Say Y here if you are using the Freescale P1010RDB config P2020RDB bool "P2020RDB" + select P2020 + select FSL_ELBC help Say Y here if you are using the Freescale P2020RDB config P1022DS bool "P1022DS" + select P1022 + select DDR_SPD + select FSL_DDR3 + select FSL_ELBC help Say Y here if you are using the Freescale P1022DS config DA923RC bool "DA923RC" + select MPC8544 + select DDR_SPD + select FSL_DDR2 help Say Y here if you are using the GE Intelligent Platforms DA923RC endchoice endif -config FSL_ELBC +config P1010 + select FSL_IFC + select FSL_ERRATUM_IFC_A002769 + select FSL_ERRATUM_P1010_A003549 + select FSL_ERRATUM_IFC_A003399 bool - default y if P2020RDB || P1022DS + +config P2020 + bool + +config P1022 + bool + +config MPC8544 + bool config DDR_SPD bool select CRC16 - default y if DA923RC || P1022DS - -if P2020RDB -config P2020 - bool - default y -endif - -if P1022DS -config P1022 - bool - default y - -config FSL_DDR3 - bool - default y -endif - -if DA923RC -config MPC8544 - bool - default y config FSL_DDR2 bool - default y -endif + +config FSL_DDR3 + bool + +config FSL_IFC + bool + +config FSL_ELBC + bool + +config FSL_ERRATUM_IFC_A002769 + bool + +config FSL_ERRATUM_IFC_A003399 + bool + +config FSL_ERRATUM_P1010_A003549 + bool + diff --git a/arch/ppc/mach-mpc85xx/cpu_init.c b/arch/ppc/mach-mpc85xx/cpu_init.c index 7b50cef..003a5f1 100644 --- a/arch/ppc/mach-mpc85xx/cpu_init.c +++ b/arch/ppc/mach-mpc85xx/cpu_init.c @@ -27,29 +27,111 @@ #include #include #include +#include #include +#include #include #include #include -static void fsl_setup_ccsrbar(void) +/* NOR workaround for P1010 erratum A003399 */ +#if defined(CONFIG_FSL_ERRATUM_P1010_A003549) +#define SRAM_BASE_ADDR 0x100 +void setup_ifc(void) { - u32 temp; u32 mas0, mas1, mas2, mas3, mas7; - u32 *ccsr_virt = (u32 *)(CFG_CCSRBAR + 0x1000); + phys_addr_t flash_phys = CFG_FLASH_BASE_PHYS; - mas0 = MAS0_TLBSEL(0) | MAS0_ESEL(1); - mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | MAS1_TSIZE(BOOKE_PAGESZ_4K); - mas2 = FSL_BOOKE_MAS2(CFG_CCSRBAR + 0x1000, MAS2_I|MAS2_G); - mas3 = FSL_BOOKE_MAS3(CFG_CCSRBAR_DEFAULT, 0, MAS3_SW|MAS3_SR); - mas7 = FSL_BOOKE_MAS7(CFG_CCSRBAR_DEFAULT); + /* + * Adjust the TLB we were running out of to match the phys addr of the + * chip select we are adjusting and will return to. + */ + flash_phys += (~CFG_IFC_AMASK0) + 1 - 4*1024*1024; + mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(15); + mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | MAS1_IPROT | + MAS1_TSIZE(BOOKE_PAGESZ_4M); + mas2 = FSL_BOOKE_MAS2(CONFIG_TEXT_BASE, MAS2_I|MAS2_G); + mas3 = FSL_BOOKE_MAS3(flash_phys, 0, MAS3_SW|MAS3_SR|MAS3_SX); + mas7 = FSL_BOOKE_MAS7(flash_phys); + mtspr(MAS0, mas0); + mtspr(MAS1, mas1); + mtspr(MAS2, mas2); + mtspr(MAS3, mas3); + mtspr(MAS7, mas7); + asm volatile("isync;msync;tlbwe;isync"); +#if defined(PPC_E500_DEBUG_TLB) + /* + * TLB entry for debuggging in AS1 + * Create temporary TLB entry in AS0 to handle debug exception + * As on debug exception MSR is cleared i.e. Address space is + * changed to 0. A TLB entry (in AS0) is required to handle + * debug exception generated * in AS1. + * + * TLB entry is created for IVPR + IVOR15 to map on valid OP + * code address because flash's physical address is going to + * change as CFG_FLASH_BASE_PHYS. + */ + mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(PPC_E500_DEBUG_TLB); + mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_IPROT | + MAS1_TSIZE(BOOKE_PAGESZ_4M); + mas2 = FSL_BOOKE_MAS2(CONFIG_TEXT_BASE, MAS2_I|MAS2_G); + mas3 = FSL_BOOKE_MAS3(flash_phys, 0, MAS3_SW|MAS3_SR|MAS3_SX); + mas7 = FSL_BOOKE_MAS7(flash_phys); + + mtspr(MAS0, mas0); + mtspr(MAS1, mas1); + mtspr(MAS2, mas2); + mtspr(MAS3, mas3); + mtspr(MAS7, mas7); + + asm volatile("isync;msync;tlbwe;isync"); +#endif + set_ifc_cspr(0, CFG_IFC_CSPR0); + set_ifc_csor(0, CFG_IFC_CSOR0); + set_ifc_amask(0, CFG_IFC_AMASK0); +} + +void fsl_erratum_ifc_a003399(void) +{ + u32 mas0, mas1, mas2, mas3, mas7; + void __iomem *l2cache = IOMEM(MPC85xx_L2_ADDR); + void (*setup_ifc_sram)(void) = (void *)SRAM_BASE_ADDR; + u32 *dst, *src, ix; + + /* TLB for SRAM */ + mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(9); + mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | + MAS1_TSIZE(BOOKE_PAGESZ_1M); + mas2 = FSL_BOOKE_MAS2(SRAM_BASE_ADDR, MAS2_I); + mas3 = FSL_BOOKE_MAS3(SRAM_BASE_ADDR, 0, + MAS3_SX | MAS3_SW | MAS3_SR); + mas7 = FSL_BOOKE_MAS7(0); e500_write_tlb(mas0, mas1, mas2, mas3, mas7); - temp = in_be32(ccsr_virt); - out_be32(ccsr_virt, CFG_CCSRBAR_PHYS >> 12); - temp = in_be32((u32 *)CFG_CCSRBAR); + out_be32(l2cache + MPC85xx_L2_L2SRBAR0_OFFSET, SRAM_BASE_ADDR); + out_be32(l2cache + MPC85xx_L2_L2ERRDIS_OFFSET, + (MPC85xx_L2ERRDIS_MBECC | MPC85xx_L2ERRDIS_SBECC)); + out_be32(l2cache + MPC85xx_L2_CTL_OFFSET, + (MPC85xx_L2CTL_L2E | MPC85xx_L2CTL_L2SRAM_ENTIRE)); + /* + * Copy the code in setup_ifc to L2SRAM. Do a word copy + * because NOR Flash on P1010 does not support byte + * access (Erratum IFC-A002769) + */ + dst = (u32 *) SRAM_BASE_ADDR; + src = (u32 *) setup_ifc; + for (ix = 0; ix < 1024; ix++) + *dst++ = *src++; + setup_ifc_sram(); + + clrbits_be32(l2cache + MPC85xx_L2_CTL_OFFSET, + (MPC85xx_L2CTL_L2E | MPC85xx_L2CTL_L2SRAM_ENTIRE)); + out_be32(l2cache + MPC85xx_L2_L2SRBAR0_OFFSET, 0x0); } +#else +void fsl_erratum_ifc_a003399(void) {} +#endif int fsl_l2_cache_init(void) { @@ -93,23 +175,35 @@ return 0; } +#if defined(CONFIG_FSL_ERRATUM_P1010_A003549) +void fsl_erratum_p1010_a003549(void) +{ + void __iomem *guts = IOMEM(MPC85xx_GUTS_ADDR); + + setbits_be32(guts + MPC85xx_GUTS_PMUXCR_OFFSET, + MPC85xx_PMUXCR_LCLK_IFC_CS3); +} +#else +void fsl_erratum_p1010_a003549(void) {} +#endif + void cpu_init_early_f(void) { u32 mas0, mas1, mas2, mas3, mas7; - mas0 = MAS0_TLBSEL(0) | MAS0_ESEL(0); - mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | MAS1_TSIZE(BOOKE_PAGESZ_4K); - mas2 = FSL_BOOKE_MAS2(CFG_CCSRBAR, MAS2_I|MAS2_G); - mas3 = FSL_BOOKE_MAS3(CFG_CCSRBAR_PHYS, 0, MAS3_SW|MAS3_SR); + mas0 = MAS0_TLBSEL(1) | MAS0_ESEL(13); + mas1 = MAS1_VALID | MAS1_TID(0) | MAS1_TS | + MAS1_TSIZE(BOOKE_PAGESZ_1M); + mas2 = FSL_BOOKE_MAS2(CFG_CCSRBAR, MAS2_I | MAS2_G); + mas3 = FSL_BOOKE_MAS3(CFG_CCSRBAR_PHYS, 0, MAS3_SW | MAS3_SR); mas7 = FSL_BOOKE_MAS7(CFG_CCSRBAR_PHYS); e500_write_tlb(mas0, mas1, mas2, mas3, mas7); - /* set up CCSR if we want it moved */ - if (CFG_CCSRBAR_DEFAULT != CFG_CCSRBAR_PHYS) - fsl_setup_ccsrbar(); - + fsl_erratum_p1010_a003549(); fsl_init_laws(); + fsl_erratum_ifc_a003399(); + e500_invalidate_tlb(1); e500_init_tlbs(); } diff --git a/arch/ppc/mach-mpc85xx/cpuid.c b/arch/ppc/mach-mpc85xx/cpuid.c index 21892e3..1f54a2b 100644 --- a/arch/ppc/mach-mpc85xx/cpuid.c +++ b/arch/ppc/mach-mpc85xx/cpuid.c @@ -29,6 +29,7 @@ struct cpu_type cpu_type_list[] = { CPU_TYPE_ENTRY(8544, 8544, 1), CPU_TYPE_ENTRY(8544, 8544_E, 1), + CPU_TYPE_ENTRY(P1010, P1010, 1), CPU_TYPE_ENTRY(P1022, P1022, 2), CPU_TYPE_ENTRY(P2020, P2020, 2), CPU_TYPE_ENTRY(P2020, P2020_E, 2), diff --git a/arch/ppc/mach-mpc85xx/fsl_gpio.c b/arch/ppc/mach-mpc85xx/fsl_gpio.c index ca6305a..468c780 100644 --- a/arch/ppc/mach-mpc85xx/fsl_gpio.c +++ b/arch/ppc/mach-mpc85xx/fsl_gpio.c @@ -44,4 +44,23 @@ gpoutdr &= ~MPC85xx_GPIOBIT(gpio); out_be32(gpout, gpoutdr); } +#else +int gpio_direction_output(unsigned gpio, int val) +{ + void __iomem *gpior = IOMEM(MPC85xx_GPIO_ADDR); + + if (gpio >= 16) + return -EINVAL; + + if (val) + setbits_be32(gpior + MPC85xx_GPIO_GPDAT_OFFSET, + 1 << (32 - gpio)); + else + clrbits_be32(gpior + MPC85xx_GPIO_GPDAT_OFFSET, + 1 << (32 - gpio)); + + setbits_be32(gpior + MPC85xx_GPIO_GPDIR_OFFSET, 1 << (32 - gpio)); + + return 0; +} #endif diff --git a/arch/ppc/mach-mpc85xx/include/mach/config_mpc85xx.h b/arch/ppc/mach-mpc85xx/include/mach/config_mpc85xx.h index f9d8299..fad2c47 100644 --- a/arch/ppc/mach-mpc85xx/include/mach/config_mpc85xx.h +++ b/arch/ppc/mach-mpc85xx/include/mach/config_mpc85xx.h @@ -48,6 +48,15 @@ #define FSL_TSECV2 #define FSL_ERRATUM_A005125 +#elif defined(CONFIG_P1010) +#define MAX_CPUS 1 +#define FSL_NUM_LAWS 12 +#define FSL_NUM_TSEC 3 +#define FSL_SEC_COMPAT 4 +#define FSL_ERRATUM_A005125 +#define PPC_E500_DEBUG_TLB 2 +#define FSL_TSECV2 + #else #error Processor type not defined for this platform #endif diff --git a/arch/ppc/mach-mpc85xx/include/mach/immap_85xx.h b/arch/ppc/mach-mpc85xx/include/mach/immap_85xx.h index 87bc5c7..abcdb5c 100644 --- a/arch/ppc/mach-mpc85xx/include/mach/immap_85xx.h +++ b/arch/ppc/mach-mpc85xx/include/mach/immap_85xx.h @@ -26,6 +26,7 @@ #include #include +#include #include #define MPC85xx_LOCAL_OFFSET 0x0000 @@ -35,6 +36,7 @@ #define MPC85xx_PCI1_OFFSET 0x8000 #define MPC85xx_GPIO_OFFSET 0xf000 +#define MPC85xx_IFC_OFFSET 0x1e000 #define MPC85xx_L2_OFFSET 0x20000 #ifdef FSL_TSECV2 #define TSEC1_OFFSET 0xB0000 @@ -50,6 +52,7 @@ #define MPC85xx_GUTS_ADDR (CFG_IMMR + MPC85xx_GUTS_OFFSET) #define MPC85xx_DDR_ADDR (CFG_IMMR + MPC85xx_DDR_OFFSET) #define LBC_ADDR (CFG_IMMR + MPC85xx_LBC_OFFSET) +#define IFC_ADDR (CFG_IMMR + MPC85xx_IFC_OFFSET) #define MPC85xx_GPIO_ADDR (CFG_IMMR + MPC85xx_GPIO_OFFSET) #define MPC85xx_L2_ADDR (CFG_IMMR + MPC85xx_L2_OFFSET) #define MPC8xxx_PIC_ADDR (CFG_IMMR + MPC85xx_PIC_OFFSET) @@ -152,8 +155,13 @@ /* * L2 Cache Register Offsets */ -#define MPC85xx_L2_CTL_OFFSET 0x0 /* L2 configuration 0 */ -#define MPC85xx_L2CTL_L2E 0x80000000 +#define MPC85xx_L2_CTL_OFFSET 0x0 /* L2 configuration 0 */ +#define MPC85xx_L2CTL_L2E 0x80000000 +#define MPC85xx_L2CTL_L2SRAM_ENTIRE 0x00010000 +#define MPC85xx_L2_L2SRBAR0_OFFSET 0x100 +#define MPC85xx_L2_L2ERRDIS_OFFSET 0xe44 +#define MPC85xx_L2ERRDIS_MBECC 0x00000008 +#define MPC85xx_L2ERRDIS_SBECC 0x00000004 /* PIC registers offsets */ #define MPC85xx_PIC_WHOAMI_OFFSET 0x090 @@ -174,6 +182,7 @@ #define MPC85xx_GUTS_PORDEVSR2_OFFSET 0x14 #define MPC85xx_PORDEVSR2_SEC_CFG 0x00000080 #define MPC85xx_GUTS_PMUXCR_OFFSET 0x60 +#define MPC85xx_PMUXCR_LCLK_IFC_CS3 0x000000C0 #define MPC85xx_GUTS_PMUXCR2_OFFSET 0x64 #define MPC85xx_GUTS_DEVDISR_OFFSET 0x70 #define MPC85xx_DEVDISR_TB0 0x00004000 diff --git a/arch/ppc/mach-mpc85xx/speed.c b/arch/ppc/mach-mpc85xx/speed.c index eb9d725..6109494 100644 --- a/arch/ppc/mach-mpc85xx/speed.c +++ b/arch/ppc/mach-mpc85xx/speed.c @@ -33,8 +33,7 @@ void fsl_get_sys_info(struct sys_info *sysInfo) { void __iomem *gur = (void __iomem *)(MPC85xx_GUTS_ADDR); - uint plat_ratio, e500_ratio, half_freqSystemBus; - uint lcrr_div; + uint plat_ratio, e500_ratio, half_freqSystemBus, lcrr_div, ccr; int i; plat_ratio = in_be32(gur + MPC85xx_GUTS_PORPLLSR_OFFSET) & 0x0000003e; @@ -65,22 +64,39 @@ } #endif - lcrr_div = in_be32(LBC_BASE_ADDR + FSL_LBC_LCCR) & LCRR_CLKDIV; + if (IS_ENABLED(CONFIG_FSL_IFC)) { + void __iomem *ifc = IFC_BASE_ADDR; - if (lcrr_div == 2 || lcrr_div == 4 || lcrr_div == 8) { - /* - * The entire PQ38 family use the same bit-representation - * for twice the clock divider values. - */ + ccr = in_be32(ifc + FSL_IFC_CCR_OFFSET); + ccr = ((ccr & IFC_CCR_CLK_DIV_MASK) >> IFC_CCR_CLK_DIV_SHIFT); + sysInfo->freqLocalBus = sysInfo->freqSystemBus / (ccr + 1); + } else { + lcrr_div = in_be32(LBC_BASE_ADDR + FSL_LBC_LCCR) & LCRR_CLKDIV; + + if (lcrr_div == 2 || lcrr_div == 4 || lcrr_div == 8) { + /* + * The entire PQ38 family use the same bit + * representation for twice the clock divider values. + */ lcrr_div *= 2; sysInfo->freqLocalBus = sysInfo->freqSystemBus / lcrr_div; - } else { - /* In case anyone cares what the unknown value is */ - sysInfo->freqLocalBus = lcrr_div; + } else { + /* In case anyone cares what the unknown value is */ + sysInfo->freqLocalBus = lcrr_div; + } } } +unsigned long fsl_get_local_freq(void) +{ + struct sys_info sys_info; + + fsl_get_sys_info(&sys_info); + + return sys_info.freqLocalBus; +} + unsigned long fsl_get_bus_freq(ulong dummy) { struct sys_info sys_info;