1*e84a324bSAshish Kumar /* 2*e84a324bSAshish Kumar * Copyright 2017 NXP 3*e84a324bSAshish Kumar * 4*e84a324bSAshish Kumar * SPDX-License-Identifier: GPL-2.0+ 5*e84a324bSAshish Kumar */ 6*e84a324bSAshish Kumar #include <common.h> 7*e84a324bSAshish Kumar #include <i2c.h> 8*e84a324bSAshish Kumar #include <malloc.h> 9*e84a324bSAshish Kumar #include <errno.h> 10*e84a324bSAshish Kumar #include <netdev.h> 11*e84a324bSAshish Kumar #include <fsl_ifc.h> 12*e84a324bSAshish Kumar #include <fsl_ddr.h> 13*e84a324bSAshish Kumar #include <fsl_sec.h> 14*e84a324bSAshish Kumar #include <asm/io.h> 15*e84a324bSAshish Kumar #include <fdt_support.h> 16*e84a324bSAshish Kumar #include <libfdt.h> 17*e84a324bSAshish Kumar #include <fsl-mc/fsl_mc.h> 18*e84a324bSAshish Kumar #include <environment.h> 19*e84a324bSAshish Kumar #include <asm/arch-fsl-layerscape/soc.h> 20*e84a324bSAshish Kumar #include <asm/arch/ppa.h> 21*e84a324bSAshish Kumar 22*e84a324bSAshish Kumar #include "../common/qixis.h" 23*e84a324bSAshish Kumar #include "ls1088a_qixis.h" 24*e84a324bSAshish Kumar 25*e84a324bSAshish Kumar DECLARE_GLOBAL_DATA_PTR; 26*e84a324bSAshish Kumar 27*e84a324bSAshish Kumar unsigned long long get_qixis_addr(void) 28*e84a324bSAshish Kumar { 29*e84a324bSAshish Kumar unsigned long long addr; 30*e84a324bSAshish Kumar 31*e84a324bSAshish Kumar if (gd->flags & GD_FLG_RELOC) 32*e84a324bSAshish Kumar addr = QIXIS_BASE_PHYS; 33*e84a324bSAshish Kumar else 34*e84a324bSAshish Kumar addr = QIXIS_BASE_PHYS_EARLY; 35*e84a324bSAshish Kumar 36*e84a324bSAshish Kumar /* 37*e84a324bSAshish Kumar * IFC address under 256MB is mapped to 0x30000000, any address above 38*e84a324bSAshish Kumar * is mapped to 0x5_10000000 up to 4GB. 39*e84a324bSAshish Kumar */ 40*e84a324bSAshish Kumar addr = addr > 0x10000000 ? addr + 0x500000000ULL : addr + 0x30000000; 41*e84a324bSAshish Kumar 42*e84a324bSAshish Kumar return addr; 43*e84a324bSAshish Kumar } 44*e84a324bSAshish Kumar 45*e84a324bSAshish Kumar int checkboard(void) 46*e84a324bSAshish Kumar { 47*e84a324bSAshish Kumar char buf[64]; 48*e84a324bSAshish Kumar u8 sw; 49*e84a324bSAshish Kumar static const char *const freq[] = {"100", "125", "156.25", 50*e84a324bSAshish Kumar "100 separate SSCG"}; 51*e84a324bSAshish Kumar int clock; 52*e84a324bSAshish Kumar 53*e84a324bSAshish Kumar 54*e84a324bSAshish Kumar printf("Board: LS1088A-RDB, "); 55*e84a324bSAshish Kumar 56*e84a324bSAshish Kumar sw = QIXIS_READ(arch); 57*e84a324bSAshish Kumar printf("Board Arch: V%d, ", sw >> 4); 58*e84a324bSAshish Kumar 59*e84a324bSAshish Kumar printf("Board version: %c, boot from ", (sw & 0xf) + 'A'); 60*e84a324bSAshish Kumar 61*e84a324bSAshish Kumar 62*e84a324bSAshish Kumar memset((u8 *)buf, 0x00, ARRAY_SIZE(buf)); 63*e84a324bSAshish Kumar 64*e84a324bSAshish Kumar sw = QIXIS_READ(brdcfg[0]); 65*e84a324bSAshish Kumar sw = (sw & QIXIS_LBMAP_MASK) >> QIXIS_LBMAP_SHIFT; 66*e84a324bSAshish Kumar 67*e84a324bSAshish Kumar #ifdef CONFIG_SD_BOOT 68*e84a324bSAshish Kumar puts("SD card\n"); 69*e84a324bSAshish Kumar #endif 70*e84a324bSAshish Kumar switch (sw) { 71*e84a324bSAshish Kumar case 0: 72*e84a324bSAshish Kumar 73*e84a324bSAshish Kumar puts("QSPI:"); 74*e84a324bSAshish Kumar sw = QIXIS_READ(brdcfg[0]); 75*e84a324bSAshish Kumar sw = (sw & QIXIS_QMAP_MASK) >> QIXIS_QMAP_SHIFT; 76*e84a324bSAshish Kumar if (sw == 0 || sw == 4) 77*e84a324bSAshish Kumar puts("0\n"); 78*e84a324bSAshish Kumar else if (sw == 1) 79*e84a324bSAshish Kumar puts("1\n"); 80*e84a324bSAshish Kumar else 81*e84a324bSAshish Kumar puts("EMU\n"); 82*e84a324bSAshish Kumar break; 83*e84a324bSAshish Kumar 84*e84a324bSAshish Kumar default: 85*e84a324bSAshish Kumar printf("invalid setting of SW%u\n", QIXIS_LBMAP_SWITCH); 86*e84a324bSAshish Kumar break; 87*e84a324bSAshish Kumar } 88*e84a324bSAshish Kumar 89*e84a324bSAshish Kumar 90*e84a324bSAshish Kumar printf("CPLD: v%d.%d\n", QIXIS_READ(scver), QIXIS_READ(tagdata)); 91*e84a324bSAshish Kumar 92*e84a324bSAshish Kumar 93*e84a324bSAshish Kumar /* 94*e84a324bSAshish Kumar * Display the actual SERDES reference clocks as configured by the 95*e84a324bSAshish Kumar * dip switches on the board. Note that the SWx registers could 96*e84a324bSAshish Kumar * technically be set to force the reference clocks to match the 97*e84a324bSAshish Kumar * values that the SERDES expects (or vice versa). For now, however, 98*e84a324bSAshish Kumar * we just display both values and hope the user notices when they 99*e84a324bSAshish Kumar * don't match. 100*e84a324bSAshish Kumar */ 101*e84a324bSAshish Kumar puts("SERDES1 Reference : "); 102*e84a324bSAshish Kumar sw = QIXIS_READ(brdcfg[2]); 103*e84a324bSAshish Kumar clock = (sw >> 6) & 3; 104*e84a324bSAshish Kumar printf("Clock1 = %sMHz ", freq[clock]); 105*e84a324bSAshish Kumar clock = (sw >> 4) & 3; 106*e84a324bSAshish Kumar printf("Clock2 = %sMHz", freq[clock]); 107*e84a324bSAshish Kumar 108*e84a324bSAshish Kumar puts("\nSERDES2 Reference : "); 109*e84a324bSAshish Kumar clock = (sw >> 2) & 3; 110*e84a324bSAshish Kumar printf("Clock1 = %sMHz ", freq[clock]); 111*e84a324bSAshish Kumar clock = (sw >> 0) & 3; 112*e84a324bSAshish Kumar printf("Clock2 = %sMHz\n", freq[clock]); 113*e84a324bSAshish Kumar 114*e84a324bSAshish Kumar return 0; 115*e84a324bSAshish Kumar } 116*e84a324bSAshish Kumar 117*e84a324bSAshish Kumar bool if_board_diff_clk(void) 118*e84a324bSAshish Kumar { 119*e84a324bSAshish Kumar u8 diff_conf = QIXIS_READ(dutcfg[11]); 120*e84a324bSAshish Kumar return diff_conf & 0x80; 121*e84a324bSAshish Kumar } 122*e84a324bSAshish Kumar 123*e84a324bSAshish Kumar unsigned long get_board_sys_clk(void) 124*e84a324bSAshish Kumar { 125*e84a324bSAshish Kumar u8 sysclk_conf = QIXIS_READ(brdcfg[1]); 126*e84a324bSAshish Kumar 127*e84a324bSAshish Kumar switch (sysclk_conf & 0x0f) { 128*e84a324bSAshish Kumar case QIXIS_SYSCLK_83: 129*e84a324bSAshish Kumar return 83333333; 130*e84a324bSAshish Kumar case QIXIS_SYSCLK_100: 131*e84a324bSAshish Kumar return 100000000; 132*e84a324bSAshish Kumar case QIXIS_SYSCLK_125: 133*e84a324bSAshish Kumar return 125000000; 134*e84a324bSAshish Kumar case QIXIS_SYSCLK_133: 135*e84a324bSAshish Kumar return 133333333; 136*e84a324bSAshish Kumar case QIXIS_SYSCLK_150: 137*e84a324bSAshish Kumar return 150000000; 138*e84a324bSAshish Kumar case QIXIS_SYSCLK_160: 139*e84a324bSAshish Kumar return 160000000; 140*e84a324bSAshish Kumar case QIXIS_SYSCLK_166: 141*e84a324bSAshish Kumar return 166666666; 142*e84a324bSAshish Kumar } 143*e84a324bSAshish Kumar 144*e84a324bSAshish Kumar return 66666666; 145*e84a324bSAshish Kumar } 146*e84a324bSAshish Kumar 147*e84a324bSAshish Kumar unsigned long get_board_ddr_clk(void) 148*e84a324bSAshish Kumar { 149*e84a324bSAshish Kumar u8 ddrclk_conf = QIXIS_READ(brdcfg[1]); 150*e84a324bSAshish Kumar 151*e84a324bSAshish Kumar if (if_board_diff_clk()) 152*e84a324bSAshish Kumar return get_board_sys_clk(); 153*e84a324bSAshish Kumar switch ((ddrclk_conf & 0x30) >> 4) { 154*e84a324bSAshish Kumar case QIXIS_DDRCLK_100: 155*e84a324bSAshish Kumar return 100000000; 156*e84a324bSAshish Kumar case QIXIS_DDRCLK_125: 157*e84a324bSAshish Kumar return 125000000; 158*e84a324bSAshish Kumar case QIXIS_DDRCLK_133: 159*e84a324bSAshish Kumar return 133333333; 160*e84a324bSAshish Kumar } 161*e84a324bSAshish Kumar 162*e84a324bSAshish Kumar return 66666666; 163*e84a324bSAshish Kumar } 164*e84a324bSAshish Kumar 165*e84a324bSAshish Kumar int select_i2c_ch_pca9547(u8 ch) 166*e84a324bSAshish Kumar { 167*e84a324bSAshish Kumar int ret; 168*e84a324bSAshish Kumar 169*e84a324bSAshish Kumar ret = i2c_write(I2C_MUX_PCA_ADDR_PRI, 0, 1, &ch, 1); 170*e84a324bSAshish Kumar if (ret) { 171*e84a324bSAshish Kumar puts("PCA: failed to select proper channel\n"); 172*e84a324bSAshish Kumar return ret; 173*e84a324bSAshish Kumar } 174*e84a324bSAshish Kumar 175*e84a324bSAshish Kumar return 0; 176*e84a324bSAshish Kumar } 177*e84a324bSAshish Kumar 178*e84a324bSAshish Kumar void board_retimer_init(void) 179*e84a324bSAshish Kumar { 180*e84a324bSAshish Kumar u8 reg; 181*e84a324bSAshish Kumar 182*e84a324bSAshish Kumar /* Retimer is connected to I2C1_CH5 */ 183*e84a324bSAshish Kumar select_i2c_ch_pca9547(I2C_MUX_CH5); 184*e84a324bSAshish Kumar 185*e84a324bSAshish Kumar /* Access to Control/Shared register */ 186*e84a324bSAshish Kumar reg = 0x0; 187*e84a324bSAshish Kumar i2c_write(I2C_RETIMER_ADDR, 0xff, 1, ®, 1); 188*e84a324bSAshish Kumar 189*e84a324bSAshish Kumar /* Read device revision and ID */ 190*e84a324bSAshish Kumar i2c_read(I2C_RETIMER_ADDR, 1, 1, ®, 1); 191*e84a324bSAshish Kumar debug("Retimer version id = 0x%x\n", reg); 192*e84a324bSAshish Kumar 193*e84a324bSAshish Kumar /* Enable Broadcast. All writes target all channel register sets */ 194*e84a324bSAshish Kumar reg = 0x0c; 195*e84a324bSAshish Kumar i2c_write(I2C_RETIMER_ADDR, 0xff, 1, ®, 1); 196*e84a324bSAshish Kumar 197*e84a324bSAshish Kumar /* Reset Channel Registers */ 198*e84a324bSAshish Kumar i2c_read(I2C_RETIMER_ADDR, 0, 1, ®, 1); 199*e84a324bSAshish Kumar reg |= 0x4; 200*e84a324bSAshish Kumar i2c_write(I2C_RETIMER_ADDR, 0, 1, ®, 1); 201*e84a324bSAshish Kumar 202*e84a324bSAshish Kumar /* Set data rate as 10.3125 Gbps */ 203*e84a324bSAshish Kumar reg = 0x90; 204*e84a324bSAshish Kumar i2c_write(I2C_RETIMER_ADDR, 0x60, 1, ®, 1); 205*e84a324bSAshish Kumar reg = 0xb3; 206*e84a324bSAshish Kumar i2c_write(I2C_RETIMER_ADDR, 0x61, 1, ®, 1); 207*e84a324bSAshish Kumar reg = 0x90; 208*e84a324bSAshish Kumar i2c_write(I2C_RETIMER_ADDR, 0x62, 1, ®, 1); 209*e84a324bSAshish Kumar reg = 0xb3; 210*e84a324bSAshish Kumar i2c_write(I2C_RETIMER_ADDR, 0x63, 1, ®, 1); 211*e84a324bSAshish Kumar reg = 0xcd; 212*e84a324bSAshish Kumar i2c_write(I2C_RETIMER_ADDR, 0x64, 1, ®, 1); 213*e84a324bSAshish Kumar 214*e84a324bSAshish Kumar /* Select VCO Divider to full rate (000) */ 215*e84a324bSAshish Kumar i2c_read(I2C_RETIMER_ADDR, 0x2F, 1, ®, 1); 216*e84a324bSAshish Kumar reg &= 0x0f; 217*e84a324bSAshish Kumar reg |= 0x70; 218*e84a324bSAshish Kumar i2c_write(I2C_RETIMER_ADDR, 0x2F, 1, ®, 1); 219*e84a324bSAshish Kumar 220*e84a324bSAshish Kumar 221*e84a324bSAshish Kumar /*return the default channel*/ 222*e84a324bSAshish Kumar select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT); 223*e84a324bSAshish Kumar } 224*e84a324bSAshish Kumar 225*e84a324bSAshish Kumar int board_init(void) 226*e84a324bSAshish Kumar { 227*e84a324bSAshish Kumar init_final_memctl_regs(); 228*e84a324bSAshish Kumar #if defined(CONFIG_TARGET_LS1088ARDB) && defined(CONFIG_FSL_MC_ENET) 229*e84a324bSAshish Kumar u32 __iomem *irq_ccsr = (u32 __iomem *)ISC_BASE; 230*e84a324bSAshish Kumar #endif 231*e84a324bSAshish Kumar 232*e84a324bSAshish Kumar select_i2c_ch_pca9547(I2C_MUX_CH_DEFAULT); 233*e84a324bSAshish Kumar board_retimer_init(); 234*e84a324bSAshish Kumar 235*e84a324bSAshish Kumar #ifdef CONFIG_ENV_IS_NOWHERE 236*e84a324bSAshish Kumar gd->env_addr = (ulong)&default_environment[0]; 237*e84a324bSAshish Kumar #endif 238*e84a324bSAshish Kumar 239*e84a324bSAshish Kumar #if defined(CONFIG_TARGET_LS1088ARDB) && defined(CONFIG_FSL_MC_ENET) 240*e84a324bSAshish Kumar /* invert AQR105 IRQ pins polarity */ 241*e84a324bSAshish Kumar out_le32(irq_ccsr + IRQCR_OFFSET / 4, AQR105_IRQ_MASK); 242*e84a324bSAshish Kumar #endif 243*e84a324bSAshish Kumar 244*e84a324bSAshish Kumar #ifdef CONFIG_FSL_LS_PPA 245*e84a324bSAshish Kumar ppa_init(); 246*e84a324bSAshish Kumar #endif 247*e84a324bSAshish Kumar return 0; 248*e84a324bSAshish Kumar } 249*e84a324bSAshish Kumar 250*e84a324bSAshish Kumar int board_early_init_f(void) 251*e84a324bSAshish Kumar { 252*e84a324bSAshish Kumar fsl_lsch3_early_init_f(); 253*e84a324bSAshish Kumar return 0; 254*e84a324bSAshish Kumar } 255*e84a324bSAshish Kumar 256*e84a324bSAshish Kumar void detail_board_ddr_info(void) 257*e84a324bSAshish Kumar { 258*e84a324bSAshish Kumar puts("\nDDR "); 259*e84a324bSAshish Kumar print_size(gd->bd->bi_dram[0].size + gd->bd->bi_dram[1].size, ""); 260*e84a324bSAshish Kumar print_ddr_info(0); 261*e84a324bSAshish Kumar } 262*e84a324bSAshish Kumar 263*e84a324bSAshish Kumar #if defined(CONFIG_ARCH_MISC_INIT) 264*e84a324bSAshish Kumar int arch_misc_init(void) 265*e84a324bSAshish Kumar { 266*e84a324bSAshish Kumar #ifdef CONFIG_FSL_CAAM 267*e84a324bSAshish Kumar sec_init(); 268*e84a324bSAshish Kumar #endif 269*e84a324bSAshish Kumar return 0; 270*e84a324bSAshish Kumar } 271*e84a324bSAshish Kumar #endif 272*e84a324bSAshish Kumar 273*e84a324bSAshish Kumar #ifdef CONFIG_FSL_MC_ENET 274*e84a324bSAshish Kumar void fdt_fixup_board_enet(void *fdt) 275*e84a324bSAshish Kumar { 276*e84a324bSAshish Kumar int offset; 277*e84a324bSAshish Kumar 278*e84a324bSAshish Kumar offset = fdt_path_offset(fdt, "/fsl-mc"); 279*e84a324bSAshish Kumar 280*e84a324bSAshish Kumar if (offset < 0) 281*e84a324bSAshish Kumar offset = fdt_path_offset(fdt, "/fsl,dprc@0"); 282*e84a324bSAshish Kumar 283*e84a324bSAshish Kumar if (offset < 0) { 284*e84a324bSAshish Kumar printf("%s: ERROR: fsl-mc node not found in device tree (error %d)\n", 285*e84a324bSAshish Kumar __func__, offset); 286*e84a324bSAshish Kumar return; 287*e84a324bSAshish Kumar } 288*e84a324bSAshish Kumar 289*e84a324bSAshish Kumar if (get_mc_boot_status() == 0) 290*e84a324bSAshish Kumar fdt_status_okay(fdt, offset); 291*e84a324bSAshish Kumar else 292*e84a324bSAshish Kumar fdt_status_fail(fdt, offset); 293*e84a324bSAshish Kumar } 294*e84a324bSAshish Kumar #endif 295*e84a324bSAshish Kumar 296*e84a324bSAshish Kumar #ifdef CONFIG_OF_BOARD_SETUP 297*e84a324bSAshish Kumar int ft_board_setup(void *blob, bd_t *bd) 298*e84a324bSAshish Kumar { 299*e84a324bSAshish Kumar int err, i; 300*e84a324bSAshish Kumar u64 base[CONFIG_NR_DRAM_BANKS]; 301*e84a324bSAshish Kumar u64 size[CONFIG_NR_DRAM_BANKS]; 302*e84a324bSAshish Kumar 303*e84a324bSAshish Kumar ft_cpu_setup(blob, bd); 304*e84a324bSAshish Kumar 305*e84a324bSAshish Kumar /* fixup DT for the two GPP DDR banks */ 306*e84a324bSAshish Kumar for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { 307*e84a324bSAshish Kumar base[i] = gd->bd->bi_dram[i].start; 308*e84a324bSAshish Kumar size[i] = gd->bd->bi_dram[i].size; 309*e84a324bSAshish Kumar } 310*e84a324bSAshish Kumar 311*e84a324bSAshish Kumar #ifdef CONFIG_RESV_RAM 312*e84a324bSAshish Kumar /* reduce size if reserved memory is within this bank */ 313*e84a324bSAshish Kumar if (gd->arch.resv_ram >= base[0] && 314*e84a324bSAshish Kumar gd->arch.resv_ram < base[0] + size[0]) 315*e84a324bSAshish Kumar size[0] = gd->arch.resv_ram - base[0]; 316*e84a324bSAshish Kumar else if (gd->arch.resv_ram >= base[1] && 317*e84a324bSAshish Kumar gd->arch.resv_ram < base[1] + size[1]) 318*e84a324bSAshish Kumar size[1] = gd->arch.resv_ram - base[1]; 319*e84a324bSAshish Kumar #endif 320*e84a324bSAshish Kumar 321*e84a324bSAshish Kumar fdt_fixup_memory_banks(blob, base, size, CONFIG_NR_DRAM_BANKS); 322*e84a324bSAshish Kumar 323*e84a324bSAshish Kumar #ifdef CONFIG_FSL_MC_ENET 324*e84a324bSAshish Kumar fdt_fixup_board_enet(blob); 325*e84a324bSAshish Kumar err = fsl_mc_ldpaa_exit(bd); 326*e84a324bSAshish Kumar if (err) 327*e84a324bSAshish Kumar return err; 328*e84a324bSAshish Kumar #endif 329*e84a324bSAshish Kumar 330*e84a324bSAshish Kumar return 0; 331*e84a324bSAshish Kumar } 332*e84a324bSAshish Kumar #endif 333