19bbd2132SDinh Nguyen /* 29bbd2132SDinh Nguyen * Copyright Altera Corporation (C) 2014-2015 39bbd2132SDinh Nguyen * 49bbd2132SDinh Nguyen * SPDX-License-Identifier: GPL-2.0+ 59bbd2132SDinh Nguyen */ 69bbd2132SDinh Nguyen #include <common.h> 79bbd2132SDinh Nguyen #include <div64.h> 89bbd2132SDinh Nguyen #include <watchdog.h> 99bbd2132SDinh Nguyen #include <asm/arch/fpga_manager.h> 109bbd2132SDinh Nguyen #include <asm/arch/sdram.h> 119bbd2132SDinh Nguyen #include <asm/arch/system_manager.h> 129bbd2132SDinh Nguyen #include <asm/io.h> 139bbd2132SDinh Nguyen 14d04941cfSMarek Vasut /* 15d04941cfSMarek Vasut * FIXME: This path is temporary until the SDRAM driver gets 16d04941cfSMarek Vasut * a proper thorough cleanup. 17d04941cfSMarek Vasut */ 18d04941cfSMarek Vasut #include "../../../board/altera/socfpga/qts/sdram_config.h" 19d04941cfSMarek Vasut 209bbd2132SDinh Nguyen DECLARE_GLOBAL_DATA_PTR; 219bbd2132SDinh Nguyen 2242f7ebb8SMarek Vasut struct sdram_prot_rule { 2342f7ebb8SMarek Vasut u64 sdram_start; /* SDRAM start address */ 2442f7ebb8SMarek Vasut u64 sdram_end; /* SDRAM end address */ 2542f7ebb8SMarek Vasut u32 rule; /* SDRAM protection rule number: 0-19 */ 2642f7ebb8SMarek Vasut int valid; /* Rule valid or not? 1 - valid, 0 not*/ 2742f7ebb8SMarek Vasut 2842f7ebb8SMarek Vasut u32 security; 2942f7ebb8SMarek Vasut u32 portmask; 3042f7ebb8SMarek Vasut u32 result; 3142f7ebb8SMarek Vasut u32 lo_prot_id; 3242f7ebb8SMarek Vasut u32 hi_prot_id; 3342f7ebb8SMarek Vasut }; 3442f7ebb8SMarek Vasut 359bbd2132SDinh Nguyen static struct socfpga_system_manager *sysmgr_regs = 369bbd2132SDinh Nguyen (struct socfpga_system_manager *)SOCFPGA_SYSMGR_ADDRESS; 379bbd2132SDinh Nguyen static struct socfpga_sdr_ctrl *sdr_ctrl = 3817fdc916SMarek Vasut (struct socfpga_sdr_ctrl *)SDR_CTRLGRP_ADDRESS; 399bbd2132SDinh Nguyen 40*f3671697SMarek Vasut /** 41*f3671697SMarek Vasut * get_errata_rows() - Up the number of DRAM rows to cover entire address space 42*f3671697SMarek Vasut * 43*f3671697SMarek Vasut * SDRAM Failure happens when accessing non-existent memory. Artificially 44*f3671697SMarek Vasut * increase the number of rows so that the memory controller thinks it has 45*f3671697SMarek Vasut * 4GB of RAM. This function returns such amount of rows. 46*f3671697SMarek Vasut */ 47*f3671697SMarek Vasut static int get_errata_rows(void) 489bbd2132SDinh Nguyen { 49*f3671697SMarek Vasut /* Define constant for 4G memory - used for SDRAM errata workaround */ 50*f3671697SMarek Vasut #define MEMSIZE_4G (4ULL * 1024ULL * 1024ULL * 1024ULL) 51*f3671697SMarek Vasut const unsigned long long memsize = MEMSIZE_4G; 52*f3671697SMarek Vasut const unsigned int cs = CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS; 53*f3671697SMarek Vasut const unsigned int rows = CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS; 54*f3671697SMarek Vasut const unsigned int banks = CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_BANKBITS; 55*f3671697SMarek Vasut const unsigned int cols = CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_COLBITS; 56*f3671697SMarek Vasut const unsigned int width = 8; 57*f3671697SMarek Vasut 589bbd2132SDinh Nguyen unsigned long long newrows; 59*f3671697SMarek Vasut int bits, inewrowslog2; 609bbd2132SDinh Nguyen 619bbd2132SDinh Nguyen debug("workaround rows - memsize %lld\n", memsize); 629bbd2132SDinh Nguyen debug("workaround rows - cs %d\n", cs); 639bbd2132SDinh Nguyen debug("workaround rows - width %d\n", width); 649bbd2132SDinh Nguyen debug("workaround rows - rows %d\n", rows); 659bbd2132SDinh Nguyen debug("workaround rows - banks %d\n", banks); 669bbd2132SDinh Nguyen debug("workaround rows - cols %d\n", cols); 679bbd2132SDinh Nguyen 68791d20e1SMarek Vasut newrows = lldiv(memsize, cs * (width / 8)); 699bbd2132SDinh Nguyen debug("rows workaround - term1 %lld\n", newrows); 709bbd2132SDinh Nguyen 71791d20e1SMarek Vasut newrows = lldiv(newrows, (1 << banks) * (1 << cols)); 729bbd2132SDinh Nguyen debug("rows workaround - term2 %lld\n", newrows); 739bbd2132SDinh Nguyen 74791d20e1SMarek Vasut /* 75791d20e1SMarek Vasut * Compute the hamming weight - same as number of bits set. 769bbd2132SDinh Nguyen * Need to see if result is ordinal power of 2 before 779bbd2132SDinh Nguyen * attempting log2 of result. 789bbd2132SDinh Nguyen */ 7958d86144SMarek Vasut bits = generic_hweight32(newrows); 809bbd2132SDinh Nguyen 819bbd2132SDinh Nguyen debug("rows workaround - bits %d\n", bits); 829bbd2132SDinh Nguyen 839bbd2132SDinh Nguyen if (bits != 1) { 849bbd2132SDinh Nguyen printf("SDRAM workaround failed, bits set %d\n", bits); 859bbd2132SDinh Nguyen return rows; 869bbd2132SDinh Nguyen } 879bbd2132SDinh Nguyen 889bbd2132SDinh Nguyen if (newrows > UINT_MAX) { 899bbd2132SDinh Nguyen printf("SDRAM workaround rangecheck failed, %lld\n", newrows); 909bbd2132SDinh Nguyen return rows; 919bbd2132SDinh Nguyen } 929bbd2132SDinh Nguyen 93791d20e1SMarek Vasut inewrowslog2 = __ilog2(newrows); 949bbd2132SDinh Nguyen 95791d20e1SMarek Vasut debug("rows workaround - ilog2 %d, %lld\n", inewrowslog2, newrows); 969bbd2132SDinh Nguyen 979bbd2132SDinh Nguyen if (inewrowslog2 == -1) { 98791d20e1SMarek Vasut printf("SDRAM workaround failed, newrows %lld\n", newrows); 999bbd2132SDinh Nguyen return rows; 1009bbd2132SDinh Nguyen } 1019bbd2132SDinh Nguyen 1029bbd2132SDinh Nguyen return inewrowslog2; 1039bbd2132SDinh Nguyen } 1049bbd2132SDinh Nguyen 1059bbd2132SDinh Nguyen /* SDRAM protection rules vary from 0-19, a total of 20 rules. */ 1069bbd2132SDinh Nguyen static void sdram_set_rule(struct sdram_prot_rule *prule) 1079bbd2132SDinh Nguyen { 1089bbd2132SDinh Nguyen uint32_t lo_addr_bits; 1099bbd2132SDinh Nguyen uint32_t hi_addr_bits; 1109bbd2132SDinh Nguyen int ruleno = prule->rule; 1119bbd2132SDinh Nguyen 1129bbd2132SDinh Nguyen /* Select the rule */ 1139bbd2132SDinh Nguyen writel(ruleno, &sdr_ctrl->prot_rule_rdwr); 1149bbd2132SDinh Nguyen 1159bbd2132SDinh Nguyen /* Obtain the address bits */ 1169bbd2132SDinh Nguyen lo_addr_bits = (uint32_t)(((prule->sdram_start) >> 20ULL) & 0xFFF); 1179bbd2132SDinh Nguyen hi_addr_bits = (uint32_t)((((prule->sdram_end-1) >> 20ULL)) & 0xFFF); 1189bbd2132SDinh Nguyen 1199bbd2132SDinh Nguyen debug("sdram set rule start %x, %lld\n", lo_addr_bits, 1209bbd2132SDinh Nguyen prule->sdram_start); 1219bbd2132SDinh Nguyen debug("sdram set rule end %x, %lld\n", hi_addr_bits, 1229bbd2132SDinh Nguyen prule->sdram_end); 1239bbd2132SDinh Nguyen 1249bbd2132SDinh Nguyen /* Set rule addresses */ 1259bbd2132SDinh Nguyen writel(lo_addr_bits | (hi_addr_bits << 12), &sdr_ctrl->prot_rule_addr); 1269bbd2132SDinh Nguyen 1279bbd2132SDinh Nguyen /* Set rule protection ids */ 1289bbd2132SDinh Nguyen writel(prule->lo_prot_id | (prule->hi_prot_id << 12), 1299bbd2132SDinh Nguyen &sdr_ctrl->prot_rule_id); 1309bbd2132SDinh Nguyen 1319bbd2132SDinh Nguyen /* Set the rule data */ 1329bbd2132SDinh Nguyen writel(prule->security | (prule->valid << 2) | 1339bbd2132SDinh Nguyen (prule->portmask << 3) | (prule->result << 13), 1349bbd2132SDinh Nguyen &sdr_ctrl->prot_rule_data); 1359bbd2132SDinh Nguyen 1369bbd2132SDinh Nguyen /* write the rule */ 1379bbd2132SDinh Nguyen writel(ruleno | (1L << 5), &sdr_ctrl->prot_rule_rdwr); 1389bbd2132SDinh Nguyen 1399bbd2132SDinh Nguyen /* Set rule number to 0 by default */ 1409bbd2132SDinh Nguyen writel(0, &sdr_ctrl->prot_rule_rdwr); 1419bbd2132SDinh Nguyen } 1429bbd2132SDinh Nguyen 1439bbd2132SDinh Nguyen static void sdram_get_rule(struct sdram_prot_rule *prule) 1449bbd2132SDinh Nguyen { 1459bbd2132SDinh Nguyen uint32_t addr; 1469bbd2132SDinh Nguyen uint32_t id; 1479bbd2132SDinh Nguyen uint32_t data; 1489bbd2132SDinh Nguyen int ruleno = prule->rule; 1499bbd2132SDinh Nguyen 1509bbd2132SDinh Nguyen /* Read the rule */ 1519bbd2132SDinh Nguyen writel(ruleno, &sdr_ctrl->prot_rule_rdwr); 1529bbd2132SDinh Nguyen writel(ruleno | (1L << 6), &sdr_ctrl->prot_rule_rdwr); 1539bbd2132SDinh Nguyen 1549bbd2132SDinh Nguyen /* Get the addresses */ 1559bbd2132SDinh Nguyen addr = readl(&sdr_ctrl->prot_rule_addr); 1569bbd2132SDinh Nguyen prule->sdram_start = (addr & 0xFFF) << 20; 1579bbd2132SDinh Nguyen prule->sdram_end = ((addr >> 12) & 0xFFF) << 20; 1589bbd2132SDinh Nguyen 1599bbd2132SDinh Nguyen /* Get the configured protection IDs */ 1609bbd2132SDinh Nguyen id = readl(&sdr_ctrl->prot_rule_id); 1619bbd2132SDinh Nguyen prule->lo_prot_id = id & 0xFFF; 1629bbd2132SDinh Nguyen prule->hi_prot_id = (id >> 12) & 0xFFF; 1639bbd2132SDinh Nguyen 1649bbd2132SDinh Nguyen /* Get protection data */ 1659bbd2132SDinh Nguyen data = readl(&sdr_ctrl->prot_rule_data); 1669bbd2132SDinh Nguyen 1679bbd2132SDinh Nguyen prule->security = data & 0x3; 1689bbd2132SDinh Nguyen prule->valid = (data >> 2) & 0x1; 1699bbd2132SDinh Nguyen prule->portmask = (data >> 3) & 0x3FF; 1709bbd2132SDinh Nguyen prule->result = (data >> 13) & 0x1; 1719bbd2132SDinh Nguyen } 1729bbd2132SDinh Nguyen 1739bbd2132SDinh Nguyen static void sdram_set_protection_config(uint64_t sdram_start, uint64_t sdram_end) 1749bbd2132SDinh Nguyen { 1759bbd2132SDinh Nguyen struct sdram_prot_rule rule; 1769bbd2132SDinh Nguyen int rules; 1779bbd2132SDinh Nguyen 1789bbd2132SDinh Nguyen /* Start with accepting all SDRAM transaction */ 1799bbd2132SDinh Nguyen writel(0x0, &sdr_ctrl->protport_default); 1809bbd2132SDinh Nguyen 1819bbd2132SDinh Nguyen /* Clear all protection rules for warm boot case */ 1829bbd2132SDinh Nguyen memset(&rule, 0, sizeof(struct sdram_prot_rule)); 1839bbd2132SDinh Nguyen 1849bbd2132SDinh Nguyen for (rules = 0; rules < 20; rules++) { 1859bbd2132SDinh Nguyen rule.rule = rules; 1869bbd2132SDinh Nguyen sdram_set_rule(&rule); 1879bbd2132SDinh Nguyen } 1889bbd2132SDinh Nguyen 1899bbd2132SDinh Nguyen /* new rule: accept SDRAM */ 1909bbd2132SDinh Nguyen rule.sdram_start = sdram_start; 1919bbd2132SDinh Nguyen rule.sdram_end = sdram_end; 1929bbd2132SDinh Nguyen rule.lo_prot_id = 0x0; 1939bbd2132SDinh Nguyen rule.hi_prot_id = 0xFFF; 1949bbd2132SDinh Nguyen rule.portmask = 0x3FF; 1959bbd2132SDinh Nguyen rule.security = 0x3; 1969bbd2132SDinh Nguyen rule.result = 0; 1979bbd2132SDinh Nguyen rule.valid = 1; 1989bbd2132SDinh Nguyen rule.rule = 0; 1999bbd2132SDinh Nguyen 2009bbd2132SDinh Nguyen /* set new rule */ 2019bbd2132SDinh Nguyen sdram_set_rule(&rule); 2029bbd2132SDinh Nguyen 2039bbd2132SDinh Nguyen /* default rule: reject everything */ 2049bbd2132SDinh Nguyen writel(0x3ff, &sdr_ctrl->protport_default); 2059bbd2132SDinh Nguyen } 2069bbd2132SDinh Nguyen 2079bbd2132SDinh Nguyen static void sdram_dump_protection_config(void) 2089bbd2132SDinh Nguyen { 2099bbd2132SDinh Nguyen struct sdram_prot_rule rule; 2109bbd2132SDinh Nguyen int rules; 2119bbd2132SDinh Nguyen 2129bbd2132SDinh Nguyen debug("SDRAM Prot rule, default %x\n", 2139bbd2132SDinh Nguyen readl(&sdr_ctrl->protport_default)); 2149bbd2132SDinh Nguyen 2159bbd2132SDinh Nguyen for (rules = 0; rules < 20; rules++) { 2169bbd2132SDinh Nguyen sdram_get_rule(&rule); 2179bbd2132SDinh Nguyen debug("Rule %d, rules ...\n", rules); 2189bbd2132SDinh Nguyen debug(" sdram start %llx\n", rule.sdram_start); 2199bbd2132SDinh Nguyen debug(" sdram end %llx\n", rule.sdram_end); 2209bbd2132SDinh Nguyen debug(" low prot id %d, hi prot id %d\n", 2219bbd2132SDinh Nguyen rule.lo_prot_id, 2229bbd2132SDinh Nguyen rule.hi_prot_id); 2239bbd2132SDinh Nguyen debug(" portmask %x\n", rule.portmask); 2249bbd2132SDinh Nguyen debug(" security %d\n", rule.security); 2259bbd2132SDinh Nguyen debug(" result %d\n", rule.result); 2269bbd2132SDinh Nguyen debug(" valid %d\n", rule.valid); 2279bbd2132SDinh Nguyen } 2289bbd2132SDinh Nguyen } 2299bbd2132SDinh Nguyen 2309bbd2132SDinh Nguyen /* Function to write to register and verify the write */ 2319bbd2132SDinh Nguyen static unsigned sdram_write_verify(unsigned int *addr, unsigned reg_value) 2329bbd2132SDinh Nguyen { 2339bbd2132SDinh Nguyen #ifndef SDRAM_MMR_SKIP_VERIFY 2349bbd2132SDinh Nguyen unsigned reg_value1; 2359bbd2132SDinh Nguyen #endif 2369bbd2132SDinh Nguyen debug(" Write - Address "); 2379bbd2132SDinh Nguyen debug("0x%08x Data 0x%08x\n", (u32)addr, reg_value); 2389bbd2132SDinh Nguyen /* Write to register */ 2399bbd2132SDinh Nguyen writel(reg_value, addr); 2409bbd2132SDinh Nguyen #ifndef SDRAM_MMR_SKIP_VERIFY 2419bbd2132SDinh Nguyen debug(" Read and verify..."); 2429bbd2132SDinh Nguyen /* Read back the wrote value */ 2439bbd2132SDinh Nguyen reg_value1 = readl(addr); 2449bbd2132SDinh Nguyen /* Indicate failure if value not matched */ 2459bbd2132SDinh Nguyen if (reg_value1 != reg_value) { 2469bbd2132SDinh Nguyen debug("FAIL - Address 0x%08x Expected 0x%08x Data 0x%08x\n", 2479bbd2132SDinh Nguyen (u32)addr, reg_value, reg_value1); 2489bbd2132SDinh Nguyen return 1; 2499bbd2132SDinh Nguyen } 2509bbd2132SDinh Nguyen debug("correct!\n"); 2519bbd2132SDinh Nguyen #endif /* SDRAM_MMR_SKIP_VERIFY */ 2529bbd2132SDinh Nguyen return 0; 2539bbd2132SDinh Nguyen } 2549bbd2132SDinh Nguyen 2559bbd2132SDinh Nguyen static void set_sdr_ctrlcfg(void) 2569bbd2132SDinh Nguyen { 2579bbd2132SDinh Nguyen int addrorder; 2589bbd2132SDinh Nguyen 2599bbd2132SDinh Nguyen debug("\nConfiguring CTRLCFG\n"); 2609bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->ctrl_cfg, SDR_CTRLGRP_CTRLCFG_MEMTYPE_MASK, 2619bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_MEMTYPE << 2629bbd2132SDinh Nguyen SDR_CTRLGRP_CTRLCFG_MEMTYPE_LSB); 2639bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->ctrl_cfg, SDR_CTRLGRP_CTRLCFG_MEMBL_MASK, 2649bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_MEMBL << 2659bbd2132SDinh Nguyen SDR_CTRLGRP_CTRLCFG_MEMBL_LSB); 2669bbd2132SDinh Nguyen 2679bbd2132SDinh Nguyen 2689bbd2132SDinh Nguyen /* SDRAM Failure When Accessing Non-Existent Memory 2699bbd2132SDinh Nguyen * Set the addrorder field of the SDRAM control register 2709bbd2132SDinh Nguyen * based on the CSBITs setting. 2719bbd2132SDinh Nguyen */ 2729bbd2132SDinh Nguyen switch (CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS) { 2739bbd2132SDinh Nguyen case 1: 2749bbd2132SDinh Nguyen addrorder = 0; /* chip, row, bank, column */ 2759bbd2132SDinh Nguyen if (CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ADDRORDER != 0) 2769bbd2132SDinh Nguyen debug("INFO: Changing address order to 0 (chip, row, \ 2779bbd2132SDinh Nguyen bank, column)\n"); 2789bbd2132SDinh Nguyen break; 2799bbd2132SDinh Nguyen case 2: 2809bbd2132SDinh Nguyen addrorder = 2; /* row, chip, bank, column */ 2819bbd2132SDinh Nguyen if (CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ADDRORDER != 2) 2829bbd2132SDinh Nguyen debug("INFO: Changing address order to 2 (row, chip, \ 2839bbd2132SDinh Nguyen bank, column)\n"); 2849bbd2132SDinh Nguyen break; 2859bbd2132SDinh Nguyen default: 2869bbd2132SDinh Nguyen addrorder = CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ADDRORDER; 2879bbd2132SDinh Nguyen break; 2889bbd2132SDinh Nguyen } 2899bbd2132SDinh Nguyen 2909bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->ctrl_cfg, SDR_CTRLGRP_CTRLCFG_ADDRORDER_MASK, 2919bbd2132SDinh Nguyen addrorder << SDR_CTRLGRP_CTRLCFG_ADDRORDER_LSB); 2929bbd2132SDinh Nguyen 2939bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->ctrl_cfg, SDR_CTRLGRP_CTRLCFG_ECCEN_MASK, 2949bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ECCEN << 2959bbd2132SDinh Nguyen SDR_CTRLGRP_CTRLCFG_ECCEN_LSB); 2969bbd2132SDinh Nguyen 2979bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->ctrl_cfg, SDR_CTRLGRP_CTRLCFG_ECCCORREN_MASK, 2989bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ECCCORREN << 2999bbd2132SDinh Nguyen SDR_CTRLGRP_CTRLCFG_ECCCORREN_LSB); 3009bbd2132SDinh Nguyen 3019bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->ctrl_cfg, SDR_CTRLGRP_CTRLCFG_REORDEREN_MASK, 3029bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_REORDEREN << 3039bbd2132SDinh Nguyen SDR_CTRLGRP_CTRLCFG_REORDEREN_LSB); 3049bbd2132SDinh Nguyen 3059bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->ctrl_cfg, SDR_CTRLGRP_CTRLCFG_STARVELIMIT_MASK, 3069bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_STARVELIMIT << 3079bbd2132SDinh Nguyen SDR_CTRLGRP_CTRLCFG_STARVELIMIT_LSB); 3089bbd2132SDinh Nguyen 3099bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->ctrl_cfg, SDR_CTRLGRP_CTRLCFG_DQSTRKEN_MASK, 3109bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_DQSTRKEN << 3119bbd2132SDinh Nguyen SDR_CTRLGRP_CTRLCFG_DQSTRKEN_LSB); 3129bbd2132SDinh Nguyen 3139bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->ctrl_cfg, SDR_CTRLGRP_CTRLCFG_NODMPINS_MASK, 3149bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_NODMPINS << 3159bbd2132SDinh Nguyen SDR_CTRLGRP_CTRLCFG_NODMPINS_LSB); 3169bbd2132SDinh Nguyen } 3179bbd2132SDinh Nguyen 3189bbd2132SDinh Nguyen static void set_sdr_dram_timing1(void) 3199bbd2132SDinh Nguyen { 3209bbd2132SDinh Nguyen debug("Configuring DRAMTIMING1\n"); 3219bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_timing1, SDR_CTRLGRP_DRAMTIMING1_TCWL_MASK, 3229bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCWL << 3239bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMTIMING1_TCWL_LSB); 3249bbd2132SDinh Nguyen 3259bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_timing1, SDR_CTRLGRP_DRAMTIMING1_TAL_MASK, 3269bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_AL << 3279bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMTIMING1_TAL_LSB); 3289bbd2132SDinh Nguyen 3299bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_timing1, SDR_CTRLGRP_DRAMTIMING1_TCL_MASK, 3309bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCL << 3319bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMTIMING1_TCL_LSB); 3329bbd2132SDinh Nguyen 3339bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_timing1, SDR_CTRLGRP_DRAMTIMING1_TRRD_MASK, 3349bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRRD << 3359bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMTIMING1_TRRD_LSB); 3369bbd2132SDinh Nguyen 3379bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_timing1, SDR_CTRLGRP_DRAMTIMING1_TFAW_MASK, 3389bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TFAW << 3399bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMTIMING1_TFAW_LSB); 3409bbd2132SDinh Nguyen 3419bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_timing1, SDR_CTRLGRP_DRAMTIMING1_TRFC_MASK, 3429bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRFC << 3439bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMTIMING1_TRFC_LSB); 3449bbd2132SDinh Nguyen } 3459bbd2132SDinh Nguyen 3469bbd2132SDinh Nguyen static void set_sdr_dram_timing2(void) 3479bbd2132SDinh Nguyen { 3489bbd2132SDinh Nguyen debug("Configuring DRAMTIMING2\n"); 3499bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_timing2, SDR_CTRLGRP_DRAMTIMING2_TREFI_MASK, 3509bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TREFI << 3519bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMTIMING2_TREFI_LSB); 3529bbd2132SDinh Nguyen 3539bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_timing2, SDR_CTRLGRP_DRAMTIMING2_TRCD_MASK, 3549bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRCD << 3559bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMTIMING2_TRCD_LSB); 3569bbd2132SDinh Nguyen 3579bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_timing2, SDR_CTRLGRP_DRAMTIMING2_TRP_MASK, 3589bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRP << 3599bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMTIMING2_TRP_LSB); 3609bbd2132SDinh Nguyen 3619bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_timing2, SDR_CTRLGRP_DRAMTIMING2_TWR_MASK, 3629bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWR << 3639bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMTIMING2_TWR_LSB); 3649bbd2132SDinh Nguyen 3659bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_timing2, SDR_CTRLGRP_DRAMTIMING2_TWTR_MASK, 3669bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWTR << 3679bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMTIMING2_TWTR_LSB); 3689bbd2132SDinh Nguyen } 3699bbd2132SDinh Nguyen 3709bbd2132SDinh Nguyen static void set_sdr_dram_timing3(void) 3719bbd2132SDinh Nguyen { 3729bbd2132SDinh Nguyen debug("Configuring DRAMTIMING3\n"); 3739bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_timing3, SDR_CTRLGRP_DRAMTIMING3_TRTP_MASK, 3749bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRTP << 3759bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMTIMING3_TRTP_LSB); 3769bbd2132SDinh Nguyen 3779bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_timing3, SDR_CTRLGRP_DRAMTIMING3_TRAS_MASK, 3789bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRAS << 3799bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMTIMING3_TRAS_LSB); 3809bbd2132SDinh Nguyen 3819bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_timing3, SDR_CTRLGRP_DRAMTIMING3_TRC_MASK, 3829bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRC << 3839bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMTIMING3_TRC_LSB); 3849bbd2132SDinh Nguyen 3859bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_timing3, SDR_CTRLGRP_DRAMTIMING3_TMRD_MASK, 3869bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TMRD << 3879bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMTIMING3_TMRD_LSB); 3889bbd2132SDinh Nguyen 3899bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_timing3, SDR_CTRLGRP_DRAMTIMING3_TCCD_MASK, 3909bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TCCD << 3919bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMTIMING3_TCCD_LSB); 3929bbd2132SDinh Nguyen } 3939bbd2132SDinh Nguyen 3949bbd2132SDinh Nguyen static void set_sdr_dram_timing4(void) 3959bbd2132SDinh Nguyen { 3969bbd2132SDinh Nguyen debug("Configuring DRAMTIMING4\n"); 3979bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_timing4, 3989bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMTIMING4_SELFRFSHEXIT_MASK, 3999bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING4_SELFRFSHEXIT << 4009bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMTIMING4_SELFRFSHEXIT_LSB); 4019bbd2132SDinh Nguyen 4029bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_timing4, 4039bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMTIMING4_PWRDOWNEXIT_MASK, 4049bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING4_PWRDOWNEXIT << 4059bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMTIMING4_PWRDOWNEXIT_LSB); 4069bbd2132SDinh Nguyen } 4079bbd2132SDinh Nguyen 4089bbd2132SDinh Nguyen static void set_sdr_dram_lowpwr_timing(void) 4099bbd2132SDinh Nguyen { 4109bbd2132SDinh Nguyen debug("Configuring LOWPWRTIMING\n"); 4119bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->lowpwr_timing, 4129bbd2132SDinh Nguyen SDR_CTRLGRP_LOWPWRTIMING_AUTOPDCYCLES_MASK, 4139bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_LOWPWRTIMING_AUTOPDCYCLES << 4149bbd2132SDinh Nguyen SDR_CTRLGRP_LOWPWRTIMING_AUTOPDCYCLES_LSB); 4159bbd2132SDinh Nguyen 4169bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->lowpwr_timing, 4179bbd2132SDinh Nguyen SDR_CTRLGRP_LOWPWRTIMING_CLKDISABLECYCLES_MASK, 4189bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_LOWPWRTIMING_CLKDISABLECYCLES << 4199bbd2132SDinh Nguyen SDR_CTRLGRP_LOWPWRTIMING_CLKDISABLECYCLES_LSB); 4209bbd2132SDinh Nguyen } 4219bbd2132SDinh Nguyen 4229bbd2132SDinh Nguyen static void set_sdr_addr_rw(void) 4239bbd2132SDinh Nguyen { 424*f3671697SMarek Vasut int rows; 4259bbd2132SDinh Nguyen 4269bbd2132SDinh Nguyen debug("Configuring DRAMADDRW\n"); 4279bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_addrw, SDR_CTRLGRP_DRAMADDRW_COLBITS_MASK, 4289bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_COLBITS << 4299bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMADDRW_COLBITS_LSB); 4309bbd2132SDinh Nguyen /* 4319bbd2132SDinh Nguyen * SDRAM Failure When Accessing Non-Existent Memory 4329bbd2132SDinh Nguyen * Update Preloader to artificially increase the number of rows so 4339bbd2132SDinh Nguyen * that the memory thinks it has 4GB of RAM. 4349bbd2132SDinh Nguyen */ 435*f3671697SMarek Vasut rows = get_errata_rows(); 4369bbd2132SDinh Nguyen 4379bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_addrw, SDR_CTRLGRP_DRAMADDRW_ROWBITS_MASK, 4389bbd2132SDinh Nguyen rows << SDR_CTRLGRP_DRAMADDRW_ROWBITS_LSB); 4399bbd2132SDinh Nguyen 4409bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_addrw, SDR_CTRLGRP_DRAMADDRW_BANKBITS_MASK, 4419bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_BANKBITS << 4429bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMADDRW_BANKBITS_LSB); 4439bbd2132SDinh Nguyen /* SDRAM Failure When Accessing Non-Existent Memory 4449bbd2132SDinh Nguyen * Set SDR_CTRLGRP_DRAMADDRW_CSBITS_LSB to 4459bbd2132SDinh Nguyen * log2(number of chip select bits). Since there's only 4469bbd2132SDinh Nguyen * 1 or 2 chip selects, log2(1) => 0, and log2(2) => 1, 4479bbd2132SDinh Nguyen * which is the same as "chip selects" - 1. 4489bbd2132SDinh Nguyen */ 4499bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_addrw, SDR_CTRLGRP_DRAMADDRW_CSBITS_MASK, 4509bbd2132SDinh Nguyen (CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS - 1) << 4519bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMADDRW_CSBITS_LSB); 4529bbd2132SDinh Nguyen } 4539bbd2132SDinh Nguyen 4549bbd2132SDinh Nguyen static void set_sdr_static_cfg(void) 4559bbd2132SDinh Nguyen { 4569bbd2132SDinh Nguyen debug("Configuring STATICCFG\n"); 4579bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->static_cfg, SDR_CTRLGRP_STATICCFG_MEMBL_MASK, 4589bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_STATICCFG_MEMBL << 4599bbd2132SDinh Nguyen SDR_CTRLGRP_STATICCFG_MEMBL_LSB); 4609bbd2132SDinh Nguyen 4619bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->static_cfg, 4629bbd2132SDinh Nguyen SDR_CTRLGRP_STATICCFG_USEECCASDATA_MASK, 4639bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_STATICCFG_USEECCASDATA << 4649bbd2132SDinh Nguyen SDR_CTRLGRP_STATICCFG_USEECCASDATA_LSB); 4659bbd2132SDinh Nguyen } 4669bbd2132SDinh Nguyen 4679bbd2132SDinh Nguyen static void set_sdr_fifo_cfg(void) 4689bbd2132SDinh Nguyen { 4699bbd2132SDinh Nguyen debug("Configuring FIFOCFG\n"); 4709bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->fifo_cfg, SDR_CTRLGRP_FIFOCFG_SYNCMODE_MASK, 4719bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_FIFOCFG_SYNCMODE << 4729bbd2132SDinh Nguyen SDR_CTRLGRP_FIFOCFG_SYNCMODE_LSB); 4739bbd2132SDinh Nguyen 4749bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->fifo_cfg, SDR_CTRLGRP_FIFOCFG_INCSYNC_MASK, 4759bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_FIFOCFG_INCSYNC << 4769bbd2132SDinh Nguyen SDR_CTRLGRP_FIFOCFG_INCSYNC_LSB); 4779bbd2132SDinh Nguyen } 4789bbd2132SDinh Nguyen 4799bbd2132SDinh Nguyen static void set_sdr_mp_weight(void) 4809bbd2132SDinh Nguyen { 4819bbd2132SDinh Nguyen debug("Configuring MPWEIGHT_MPWEIGHT_0\n"); 4829bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->mp_weight0, 4839bbd2132SDinh Nguyen SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_0_STATICWEIGHT_31_0_MASK, 4849bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_0_STATICWEIGHT_31_0 << 4859bbd2132SDinh Nguyen SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_0_STATICWEIGHT_31_0_LSB); 4869bbd2132SDinh Nguyen 4879bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->mp_weight1, 4889bbd2132SDinh Nguyen SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_1_STATICWEIGHT_49_32_MASK, 4899bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_STATICWEIGHT_49_32 << 4909bbd2132SDinh Nguyen SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_1_STATICWEIGHT_49_32_LSB); 4919bbd2132SDinh Nguyen 4929bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->mp_weight1, 4939bbd2132SDinh Nguyen SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_1_SUMOFWEIGHTS_13_0_MASK, 4949bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_SUMOFWEIGHT_13_0 << 4959bbd2132SDinh Nguyen SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_1_SUMOFWEIGHTS_13_0_LSB); 4969bbd2132SDinh Nguyen 4979bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->mp_weight2, 4989bbd2132SDinh Nguyen SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_2_SUMOFWEIGHTS_45_14_MASK, 4999bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_2_SUMOFWEIGHT_45_14 << 5009bbd2132SDinh Nguyen SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_2_SUMOFWEIGHTS_45_14_LSB); 5019bbd2132SDinh Nguyen 5029bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->mp_weight3, 5039bbd2132SDinh Nguyen SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_3_SUMOFWEIGHTS_63_46_MASK, 5049bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_3_SUMOFWEIGHT_63_46 << 5059bbd2132SDinh Nguyen SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_3_SUMOFWEIGHTS_63_46_LSB); 5069bbd2132SDinh Nguyen } 5079bbd2132SDinh Nguyen 5089bbd2132SDinh Nguyen static void set_sdr_mp_pacing(void) 5099bbd2132SDinh Nguyen { 5109bbd2132SDinh Nguyen debug("Configuring MPPACING_MPPACING_0\n"); 5119bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->mp_pacing0, 5129bbd2132SDinh Nguyen SDR_CTRLGRP_MPPACING_MPPACING_0_THRESHOLD1_31_0_MASK, 5139bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_MPPACING_0_THRESHOLD1_31_0 << 5149bbd2132SDinh Nguyen SDR_CTRLGRP_MPPACING_MPPACING_0_THRESHOLD1_31_0_LSB); 5159bbd2132SDinh Nguyen 5169bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->mp_pacing1, 5179bbd2132SDinh Nguyen SDR_CTRLGRP_MPPACING_MPPACING_1_THRESHOLD1_59_32_MASK, 5189bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD1_59_32 << 5199bbd2132SDinh Nguyen SDR_CTRLGRP_MPPACING_MPPACING_1_THRESHOLD1_59_32_LSB); 5209bbd2132SDinh Nguyen 5219bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->mp_pacing1, 5229bbd2132SDinh Nguyen SDR_CTRLGRP_MPPACING_MPPACING_1_THRESHOLD2_3_0_MASK, 5239bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD2_3_0 << 5249bbd2132SDinh Nguyen SDR_CTRLGRP_MPPACING_MPPACING_1_THRESHOLD2_3_0_LSB); 5259bbd2132SDinh Nguyen 5269bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->mp_pacing2, 5279bbd2132SDinh Nguyen SDR_CTRLGRP_MPPACING_MPPACING_2_THRESHOLD2_35_4_MASK, 5289bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_MPPACING_2_THRESHOLD2_35_4 << 5299bbd2132SDinh Nguyen SDR_CTRLGRP_MPPACING_MPPACING_2_THRESHOLD2_35_4_LSB); 5309bbd2132SDinh Nguyen 5319bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->mp_pacing3, 5329bbd2132SDinh Nguyen SDR_CTRLGRP_MPPACING_MPPACING_3_THRESHOLD2_59_36_MASK, 5339bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_MPPACING_3_THRESHOLD2_59_36 << 5349bbd2132SDinh Nguyen SDR_CTRLGRP_MPPACING_MPPACING_3_THRESHOLD2_59_36_LSB); 5359bbd2132SDinh Nguyen } 5369bbd2132SDinh Nguyen 5379bbd2132SDinh Nguyen static void set_sdr_mp_threshold(void) 5389bbd2132SDinh Nguyen { 5399bbd2132SDinh Nguyen debug("Configuring MPTHRESHOLDRST_MPTHRESHOLDRST_0\n"); 5409bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->mp_threshold0, 5419bbd2132SDinh Nguyen SDR_CTRLGRP_MPTHRESHOLDRST_0_THRESHOLDRSTCYCLES_31_0_MASK, 5429bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_0_THRESHOLDRSTCYCLES_31_0 << 5439bbd2132SDinh Nguyen SDR_CTRLGRP_MPTHRESHOLDRST_0_THRESHOLDRSTCYCLES_31_0_LSB); 5449bbd2132SDinh Nguyen 5459bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->mp_threshold1, 5469bbd2132SDinh Nguyen SDR_CTRLGRP_MPTHRESHOLDRST_1_THRESHOLDRSTCYCLES_63_32_MASK, 547452a81e0SMarek Vasut CONFIG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_1_THRESHOLDRSTCYCLES_63_32 << 5489bbd2132SDinh Nguyen SDR_CTRLGRP_MPTHRESHOLDRST_1_THRESHOLDRSTCYCLES_63_32_LSB); 5499bbd2132SDinh Nguyen 5509bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->mp_threshold2, 5519bbd2132SDinh Nguyen SDR_CTRLGRP_MPTHRESHOLDRST_2_THRESHOLDRSTCYCLES_79_64_MASK, 5529bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_2_THRESHOLDRSTCYCLES_79_64 << 5539bbd2132SDinh Nguyen SDR_CTRLGRP_MPTHRESHOLDRST_2_THRESHOLDRSTCYCLES_79_64_LSB); 5549bbd2132SDinh Nguyen } 5559bbd2132SDinh Nguyen 5569bbd2132SDinh Nguyen 5579bbd2132SDinh Nguyen /* Function to initialize SDRAM MMR */ 5589bbd2132SDinh Nguyen unsigned sdram_mmr_init_full(unsigned int sdr_phy_reg) 5599bbd2132SDinh Nguyen { 5609bbd2132SDinh Nguyen unsigned long reg_value; 5619bbd2132SDinh Nguyen unsigned long status = 0; 5629bbd2132SDinh Nguyen 5639bbd2132SDinh Nguyen #if defined(CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS) && \ 5649bbd2132SDinh Nguyen defined(CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS) && \ 5659bbd2132SDinh Nguyen defined(CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_BANKBITS) && \ 5669bbd2132SDinh Nguyen defined(CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_COLBITS) && \ 5679bbd2132SDinh Nguyen defined(CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS) 5689bbd2132SDinh Nguyen 5699bbd2132SDinh Nguyen writel(CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS, 5709bbd2132SDinh Nguyen &sysmgr_regs->iswgrp_handoff[4]); 5719bbd2132SDinh Nguyen #endif 5729bbd2132SDinh Nguyen set_sdr_ctrlcfg(); 5739bbd2132SDinh Nguyen set_sdr_dram_timing1(); 5749bbd2132SDinh Nguyen set_sdr_dram_timing2(); 5759bbd2132SDinh Nguyen set_sdr_dram_timing3(); 5769bbd2132SDinh Nguyen set_sdr_dram_timing4(); 5779bbd2132SDinh Nguyen set_sdr_dram_lowpwr_timing(); 5789bbd2132SDinh Nguyen set_sdr_addr_rw(); 5799bbd2132SDinh Nguyen 5809bbd2132SDinh Nguyen debug("Configuring DRAMIFWIDTH\n"); 5819bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_if_width, 5829bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMIFWIDTH_IFWIDTH_MASK, 5839bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMIFWIDTH_IFWIDTH << 5849bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMIFWIDTH_IFWIDTH_LSB); 5859bbd2132SDinh Nguyen 5869bbd2132SDinh Nguyen debug("Configuring DRAMDEVWIDTH\n"); 5879bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_dev_width, 5889bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMDEVWIDTH_DEVWIDTH_MASK, 5899bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMDEVWIDTH_DEVWIDTH << 5909bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMDEVWIDTH_DEVWIDTH_LSB); 5919bbd2132SDinh Nguyen 5929bbd2132SDinh Nguyen debug("Configuring LOWPWREQ\n"); 5939bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->lowpwr_eq, 5949bbd2132SDinh Nguyen SDR_CTRLGRP_LOWPWREQ_SELFRFSHMASK_MASK, 5959bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_LOWPWREQ_SELFRFSHMASK << 5969bbd2132SDinh Nguyen SDR_CTRLGRP_LOWPWREQ_SELFRFSHMASK_LSB); 5979bbd2132SDinh Nguyen 5989bbd2132SDinh Nguyen debug("Configuring DRAMINTR\n"); 5999bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_intr, SDR_CTRLGRP_DRAMINTR_INTREN_MASK, 6009bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMINTR_INTREN << 6019bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMINTR_INTREN_LSB); 6029bbd2132SDinh Nguyen 6039bbd2132SDinh Nguyen set_sdr_static_cfg(); 6049bbd2132SDinh Nguyen 6059bbd2132SDinh Nguyen debug("Configuring CTRLWIDTH\n"); 6069bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->ctrl_width, 6079bbd2132SDinh Nguyen SDR_CTRLGRP_CTRLWIDTH_CTRLWIDTH_MASK, 6089bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_CTRLWIDTH_CTRLWIDTH << 6099bbd2132SDinh Nguyen SDR_CTRLGRP_CTRLWIDTH_CTRLWIDTH_LSB); 6109bbd2132SDinh Nguyen 6119bbd2132SDinh Nguyen debug("Configuring PORTCFG\n"); 6129bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->port_cfg, SDR_CTRLGRP_PORTCFG_AUTOPCHEN_MASK, 6139bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_PORTCFG_AUTOPCHEN << 6149bbd2132SDinh Nguyen SDR_CTRLGRP_PORTCFG_AUTOPCHEN_LSB); 6159bbd2132SDinh Nguyen 6169bbd2132SDinh Nguyen set_sdr_fifo_cfg(); 6179bbd2132SDinh Nguyen 6189bbd2132SDinh Nguyen debug("Configuring MPPRIORITY\n"); 6199bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->mp_priority, 6209bbd2132SDinh Nguyen SDR_CTRLGRP_MPPRIORITY_USERPRIORITY_MASK, 6219bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_MPPRIORITY_USERPRIORITY << 6229bbd2132SDinh Nguyen SDR_CTRLGRP_MPPRIORITY_USERPRIORITY_LSB); 6239bbd2132SDinh Nguyen 6249bbd2132SDinh Nguyen set_sdr_mp_weight(); 6259bbd2132SDinh Nguyen set_sdr_mp_pacing(); 6269bbd2132SDinh Nguyen set_sdr_mp_threshold(); 6279bbd2132SDinh Nguyen 6289bbd2132SDinh Nguyen debug("Configuring PHYCTRL_PHYCTRL_0\n"); 6299bbd2132SDinh Nguyen setbits_le32(&sdr_ctrl->phy_ctrl0, 6309bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_PHYCTRL_PHYCTRL_0); 6319bbd2132SDinh Nguyen 6329bbd2132SDinh Nguyen debug("Configuring CPORTWIDTH\n"); 6339bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->cport_width, 6349bbd2132SDinh Nguyen SDR_CTRLGRP_CPORTWIDTH_CMDPORTWIDTH_MASK, 6359bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_CPORTWIDTH_CPORTWIDTH << 6369bbd2132SDinh Nguyen SDR_CTRLGRP_CPORTWIDTH_CMDPORTWIDTH_LSB); 6379bbd2132SDinh Nguyen debug(" Write - Address "); 6389bbd2132SDinh Nguyen debug("0x%08x Data 0x%08x\n", 6399bbd2132SDinh Nguyen (unsigned)(&sdr_ctrl->cport_width), 6409bbd2132SDinh Nguyen (unsigned)reg_value); 6419bbd2132SDinh Nguyen reg_value = readl(&sdr_ctrl->cport_width); 6429bbd2132SDinh Nguyen debug(" Read value without verify 0x%08x\n", (unsigned)reg_value); 6439bbd2132SDinh Nguyen 6449bbd2132SDinh Nguyen debug("Configuring CPORTWMAP\n"); 6459bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->cport_wmap, 6469bbd2132SDinh Nguyen SDR_CTRLGRP_CPORTWMAP_CPORTWFIFOMAP_MASK, 6479bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_CPORTWMAP_CPORTWMAP << 6489bbd2132SDinh Nguyen SDR_CTRLGRP_CPORTWMAP_CPORTWFIFOMAP_LSB); 6499bbd2132SDinh Nguyen debug(" Write - Address "); 6509bbd2132SDinh Nguyen debug("0x%08x Data 0x%08x\n", 6519bbd2132SDinh Nguyen (unsigned)(&sdr_ctrl->cport_wmap), 6529bbd2132SDinh Nguyen (unsigned)reg_value); 6539bbd2132SDinh Nguyen reg_value = readl(&sdr_ctrl->cport_wmap); 6549bbd2132SDinh Nguyen debug(" Read value without verify 0x%08x\n", (unsigned)reg_value); 6559bbd2132SDinh Nguyen 6569bbd2132SDinh Nguyen debug("Configuring CPORTRMAP\n"); 6579bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->cport_rmap, 6589bbd2132SDinh Nguyen SDR_CTRLGRP_CPORTRMAP_CPORTRFIFOMAP_MASK, 6599bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_CPORTRMAP_CPORTRMAP << 6609bbd2132SDinh Nguyen SDR_CTRLGRP_CPORTRMAP_CPORTRFIFOMAP_LSB); 6619bbd2132SDinh Nguyen debug(" Write - Address "); 6629bbd2132SDinh Nguyen debug("0x%08x Data 0x%08x\n", 6639bbd2132SDinh Nguyen (unsigned)(&sdr_ctrl->cport_rmap), 6649bbd2132SDinh Nguyen (unsigned)reg_value); 6659bbd2132SDinh Nguyen reg_value = readl(&sdr_ctrl->cport_rmap); 6669bbd2132SDinh Nguyen debug(" Read value without verify 0x%08x\n", (unsigned)reg_value); 6679bbd2132SDinh Nguyen 6689bbd2132SDinh Nguyen debug("Configuring RFIFOCMAP\n"); 6699bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->rfifo_cmap, 6709bbd2132SDinh Nguyen SDR_CTRLGRP_RFIFOCMAP_RFIFOCPORTMAP_MASK, 6719bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_RFIFOCMAP_RFIFOCMAP << 6729bbd2132SDinh Nguyen SDR_CTRLGRP_RFIFOCMAP_RFIFOCPORTMAP_LSB); 6739bbd2132SDinh Nguyen debug(" Write - Address "); 6749bbd2132SDinh Nguyen debug("0x%08x Data 0x%08x\n", 6759bbd2132SDinh Nguyen (unsigned)(&sdr_ctrl->rfifo_cmap), 6769bbd2132SDinh Nguyen (unsigned)reg_value); 6779bbd2132SDinh Nguyen reg_value = readl(&sdr_ctrl->rfifo_cmap); 6789bbd2132SDinh Nguyen debug(" Read value without verify 0x%08x\n", (unsigned)reg_value); 6799bbd2132SDinh Nguyen 6809bbd2132SDinh Nguyen debug("Configuring WFIFOCMAP\n"); 6819bbd2132SDinh Nguyen reg_value = readl(&sdr_ctrl->wfifo_cmap); 6829bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->wfifo_cmap, 6839bbd2132SDinh Nguyen SDR_CTRLGRP_WFIFOCMAP_WFIFOCPORTMAP_MASK, 6849bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_WFIFOCMAP_WFIFOCMAP << 6859bbd2132SDinh Nguyen SDR_CTRLGRP_WFIFOCMAP_WFIFOCPORTMAP_LSB); 6869bbd2132SDinh Nguyen debug(" Write - Address "); 6879bbd2132SDinh Nguyen debug("0x%08x Data 0x%08x\n", 6889bbd2132SDinh Nguyen (unsigned)(&sdr_ctrl->wfifo_cmap), 6899bbd2132SDinh Nguyen (unsigned)reg_value); 6909bbd2132SDinh Nguyen reg_value = readl(&sdr_ctrl->wfifo_cmap); 6919bbd2132SDinh Nguyen debug(" Read value without verify 0x%08x\n", (unsigned)reg_value); 6929bbd2132SDinh Nguyen 6939bbd2132SDinh Nguyen debug("Configuring CPORTRDWR\n"); 6949bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->cport_rdwr, 6959bbd2132SDinh Nguyen SDR_CTRLGRP_CPORTRDWR_CPORTRDWR_MASK, 6969bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_CPORTRDWR_CPORTRDWR << 6979bbd2132SDinh Nguyen SDR_CTRLGRP_CPORTRDWR_CPORTRDWR_LSB); 6989bbd2132SDinh Nguyen debug(" Write - Address "); 6999bbd2132SDinh Nguyen debug("0x%08x Data 0x%08x\n", 7009bbd2132SDinh Nguyen (unsigned)(&sdr_ctrl->cport_rdwr), 7019bbd2132SDinh Nguyen (unsigned)reg_value); 7029bbd2132SDinh Nguyen reg_value = readl(&sdr_ctrl->cport_rdwr); 7039bbd2132SDinh Nguyen debug(" Read value without verify 0x%08x\n", (unsigned)reg_value); 7049bbd2132SDinh Nguyen 7059bbd2132SDinh Nguyen debug("Configuring DRAMODT\n"); 7069bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_odt, 7079bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMODT_READ_MASK, 7089bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMODT_READ << 7099bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMODT_READ_LSB); 7109bbd2132SDinh Nguyen 7119bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->dram_odt, 7129bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMODT_WRITE_MASK, 7139bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_DRAMODT_WRITE << 7149bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMODT_WRITE_LSB); 7159bbd2132SDinh Nguyen 7169bbd2132SDinh Nguyen /* saving this value to SYSMGR.ISWGRP.HANDOFF.FPGA2SDR */ 7179bbd2132SDinh Nguyen writel(CONFIG_HPS_SDR_CTRLCFG_FPGAPORTRST, 7189bbd2132SDinh Nguyen &sysmgr_regs->iswgrp_handoff[3]); 7199bbd2132SDinh Nguyen 7209bbd2132SDinh Nguyen /* only enable if the FPGA is programmed */ 7219bbd2132SDinh Nguyen if (fpgamgr_test_fpga_ready()) { 7229bbd2132SDinh Nguyen if (sdram_write_verify(&sdr_ctrl->fpgaport_rst, 7239bbd2132SDinh Nguyen CONFIG_HPS_SDR_CTRLCFG_FPGAPORTRST) == 1) { 7249bbd2132SDinh Nguyen status = 1; 7259bbd2132SDinh Nguyen return 1; 7269bbd2132SDinh Nguyen } 7279bbd2132SDinh Nguyen } 7289bbd2132SDinh Nguyen 7299bbd2132SDinh Nguyen /* Restore the SDR PHY Register if valid */ 7309bbd2132SDinh Nguyen if (sdr_phy_reg != 0xffffffff) 7319bbd2132SDinh Nguyen writel(sdr_phy_reg, &sdr_ctrl->phy_ctrl0); 7329bbd2132SDinh Nguyen 7339bbd2132SDinh Nguyen /***** Final step - apply configuration changes *****/ 7349bbd2132SDinh Nguyen debug("Configuring STATICCFG_\n"); 7359bbd2132SDinh Nguyen clrsetbits_le32(&sdr_ctrl->static_cfg, SDR_CTRLGRP_STATICCFG_APPLYCFG_MASK, 7369bbd2132SDinh Nguyen 1 << SDR_CTRLGRP_STATICCFG_APPLYCFG_LSB); 7379bbd2132SDinh Nguyen debug(" Write - Address "); 7389bbd2132SDinh Nguyen debug("0x%08x Data 0x%08x\n", 7399bbd2132SDinh Nguyen (unsigned)(&sdr_ctrl->static_cfg), 7409bbd2132SDinh Nguyen (unsigned)reg_value); 7419bbd2132SDinh Nguyen reg_value = readl(&sdr_ctrl->static_cfg); 7429bbd2132SDinh Nguyen debug(" Read value without verify 0x%08x\n", (unsigned)reg_value); 7439bbd2132SDinh Nguyen 7449bbd2132SDinh Nguyen sdram_set_protection_config(0, sdram_calculate_size()); 7459bbd2132SDinh Nguyen 7469bbd2132SDinh Nguyen sdram_dump_protection_config(); 7479bbd2132SDinh Nguyen 7489bbd2132SDinh Nguyen return status; 7499bbd2132SDinh Nguyen } 7509bbd2132SDinh Nguyen 7519bbd2132SDinh Nguyen /* 7529bbd2132SDinh Nguyen * To calculate SDRAM device size based on SDRAM controller parameters. 7539bbd2132SDinh Nguyen * Size is specified in bytes. 7549bbd2132SDinh Nguyen * 7559bbd2132SDinh Nguyen * NOTE: 7569bbd2132SDinh Nguyen * This function is compiled and linked into the preloader and 7579bbd2132SDinh Nguyen * Uboot (there may be others). So if this function changes, the Preloader 7589bbd2132SDinh Nguyen * and UBoot must be updated simultaneously. 7599bbd2132SDinh Nguyen */ 7609bbd2132SDinh Nguyen unsigned long sdram_calculate_size(void) 7619bbd2132SDinh Nguyen { 7629bbd2132SDinh Nguyen unsigned long temp; 7639bbd2132SDinh Nguyen unsigned long row, bank, col, cs, width; 7649bbd2132SDinh Nguyen 7659bbd2132SDinh Nguyen temp = readl(&sdr_ctrl->dram_addrw); 7669bbd2132SDinh Nguyen col = (temp & SDR_CTRLGRP_DRAMADDRW_COLBITS_MASK) >> 7679bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMADDRW_COLBITS_LSB; 7689bbd2132SDinh Nguyen 7699bbd2132SDinh Nguyen /* SDRAM Failure When Accessing Non-Existent Memory 7709bbd2132SDinh Nguyen * Use ROWBITS from Quartus/QSys to calculate SDRAM size 7719bbd2132SDinh Nguyen * since the FB specifies we modify ROWBITs to work around SDRAM 7729bbd2132SDinh Nguyen * controller issue. 7739bbd2132SDinh Nguyen * 7749bbd2132SDinh Nguyen * If the stored handoff value for rows is 0, it probably means 7759bbd2132SDinh Nguyen * the preloader is older than UBoot. Use the 7769bbd2132SDinh Nguyen * #define from the SOCEDS Tools per Crucible review 7779bbd2132SDinh Nguyen * uboot-socfpga-204. Note that this is not a supported 7789bbd2132SDinh Nguyen * configuration and is not tested. The customer 7799bbd2132SDinh Nguyen * should be using preloader and uboot built from the 7809bbd2132SDinh Nguyen * same tag. 7819bbd2132SDinh Nguyen */ 7829bbd2132SDinh Nguyen row = readl(&sysmgr_regs->iswgrp_handoff[4]); 7839bbd2132SDinh Nguyen if (row == 0) 7849bbd2132SDinh Nguyen row = CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS; 7859bbd2132SDinh Nguyen /* If the stored handoff value for rows is greater than 7869bbd2132SDinh Nguyen * the field width in the sdr.dramaddrw register then 7879bbd2132SDinh Nguyen * something is very wrong. Revert to using the the #define 7889bbd2132SDinh Nguyen * value handed off by the SOCEDS tool chain instead of 7899bbd2132SDinh Nguyen * using a broken value. 7909bbd2132SDinh Nguyen */ 7919bbd2132SDinh Nguyen if (row > 31) 7929bbd2132SDinh Nguyen row = CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS; 7939bbd2132SDinh Nguyen 7949bbd2132SDinh Nguyen bank = (temp & SDR_CTRLGRP_DRAMADDRW_BANKBITS_MASK) >> 7959bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMADDRW_BANKBITS_LSB; 7969bbd2132SDinh Nguyen 7979bbd2132SDinh Nguyen /* SDRAM Failure When Accessing Non-Existent Memory 7989bbd2132SDinh Nguyen * Use CSBITs from Quartus/QSys to calculate SDRAM size 7999bbd2132SDinh Nguyen * since the FB specifies we modify CSBITs to work around SDRAM 8009bbd2132SDinh Nguyen * controller issue. 8019bbd2132SDinh Nguyen */ 8029bbd2132SDinh Nguyen cs = (temp & SDR_CTRLGRP_DRAMADDRW_CSBITS_MASK) >> 8039bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMADDRW_CSBITS_LSB; 8049bbd2132SDinh Nguyen cs += 1; 8059bbd2132SDinh Nguyen 8069bbd2132SDinh Nguyen cs = CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS; 8079bbd2132SDinh Nguyen 8089bbd2132SDinh Nguyen width = readl(&sdr_ctrl->dram_if_width); 8099bbd2132SDinh Nguyen /* ECC would not be calculated as its not addressible */ 8109bbd2132SDinh Nguyen if (width == SDRAM_WIDTH_32BIT_WITH_ECC) 8119bbd2132SDinh Nguyen width = 32; 8129bbd2132SDinh Nguyen if (width == SDRAM_WIDTH_16BIT_WITH_ECC) 8139bbd2132SDinh Nguyen width = 16; 8149bbd2132SDinh Nguyen 8159bbd2132SDinh Nguyen /* calculate the SDRAM size base on this info */ 8169bbd2132SDinh Nguyen temp = 1 << (row + bank + col); 8179bbd2132SDinh Nguyen temp = temp * cs * (width / 8); 8189bbd2132SDinh Nguyen 8199bbd2132SDinh Nguyen debug("sdram_calculate_memory returns %ld\n", temp); 8209bbd2132SDinh Nguyen 8219bbd2132SDinh Nguyen return temp; 8229bbd2132SDinh Nguyen } 823