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