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 4004ae4489SMarek Vasut static struct socfpga_sdram_config { 4104ae4489SMarek Vasut u32 ctrl_cfg; 4204ae4489SMarek Vasut u32 dram_timing1; 4304ae4489SMarek Vasut u32 dram_timing2; 4404ae4489SMarek Vasut u32 dram_timing3; 4504ae4489SMarek Vasut u32 dram_timing4; 4604ae4489SMarek Vasut u32 lowpwr_timing; 47*dc3b91d9SMarek Vasut u32 dram_odt; 4804ae4489SMarek Vasut u32 dram_addrw; 49*dc3b91d9SMarek Vasut u32 dram_if_width; 50*dc3b91d9SMarek Vasut u32 dram_dev_width; 51*dc3b91d9SMarek Vasut u32 dram_intr; 52*dc3b91d9SMarek Vasut u32 lowpwr_eq; 5304ae4489SMarek Vasut u32 static_cfg; 54*dc3b91d9SMarek Vasut u32 ctrl_width; 55*dc3b91d9SMarek Vasut u32 cport_width; 56*dc3b91d9SMarek Vasut u32 cport_wmap; 57*dc3b91d9SMarek Vasut u32 cport_rmap; 58*dc3b91d9SMarek Vasut u32 rfifo_cmap; 59*dc3b91d9SMarek Vasut u32 wfifo_cmap; 60*dc3b91d9SMarek Vasut u32 cport_rdwr; 61*dc3b91d9SMarek Vasut u32 port_cfg; 62*dc3b91d9SMarek Vasut u32 fpgaport_rst; 6304ae4489SMarek Vasut u32 fifo_cfg; 64*dc3b91d9SMarek Vasut u32 mp_priority; 6504ae4489SMarek Vasut u32 mp_weight0; 6604ae4489SMarek Vasut u32 mp_weight1; 6704ae4489SMarek Vasut u32 mp_weight2; 6804ae4489SMarek Vasut u32 mp_weight3; 6904ae4489SMarek Vasut u32 mp_pacing0; 7004ae4489SMarek Vasut u32 mp_pacing1; 7104ae4489SMarek Vasut u32 mp_pacing2; 7204ae4489SMarek Vasut u32 mp_pacing3; 7304ae4489SMarek Vasut u32 mp_threshold0; 7404ae4489SMarek Vasut u32 mp_threshold1; 7504ae4489SMarek Vasut u32 mp_threshold2; 76*dc3b91d9SMarek Vasut u32 phy_ctrl0; 7704ae4489SMarek Vasut } sdram_config = { 7804ae4489SMarek Vasut .ctrl_cfg = 7904ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_MEMTYPE << 8004ae4489SMarek Vasut SDR_CTRLGRP_CTRLCFG_MEMTYPE_LSB) | 8104ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_MEMBL << 8204ae4489SMarek Vasut SDR_CTRLGRP_CTRLCFG_MEMBL_LSB) | 8304ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ECCEN << 8404ae4489SMarek Vasut SDR_CTRLGRP_CTRLCFG_ECCEN_LSB) | 8504ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ECCCORREN << 8604ae4489SMarek Vasut SDR_CTRLGRP_CTRLCFG_ECCCORREN_LSB) | 8704ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_REORDEREN << 8804ae4489SMarek Vasut SDR_CTRLGRP_CTRLCFG_REORDEREN_LSB) | 8904ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_STARVELIMIT << 9004ae4489SMarek Vasut SDR_CTRLGRP_CTRLCFG_STARVELIMIT_LSB) | 9104ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_DQSTRKEN << 9204ae4489SMarek Vasut SDR_CTRLGRP_CTRLCFG_DQSTRKEN_LSB) | 9304ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_NODMPINS << 9404ae4489SMarek Vasut SDR_CTRLGRP_CTRLCFG_NODMPINS_LSB), 9504ae4489SMarek Vasut .dram_timing1 = 9604ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCWL << 9704ae4489SMarek Vasut SDR_CTRLGRP_DRAMTIMING1_TCWL_LSB) | 9804ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_AL << 9904ae4489SMarek Vasut SDR_CTRLGRP_DRAMTIMING1_TAL_LSB) | 10004ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TCL << 10104ae4489SMarek Vasut SDR_CTRLGRP_DRAMTIMING1_TCL_LSB) | 10204ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRRD << 10304ae4489SMarek Vasut SDR_CTRLGRP_DRAMTIMING1_TRRD_LSB) | 10404ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TFAW << 10504ae4489SMarek Vasut SDR_CTRLGRP_DRAMTIMING1_TFAW_LSB) | 10604ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING1_TRFC << 10704ae4489SMarek Vasut SDR_CTRLGRP_DRAMTIMING1_TRFC_LSB), 10804ae4489SMarek Vasut .dram_timing2 = 10904ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TREFI << 11004ae4489SMarek Vasut SDR_CTRLGRP_DRAMTIMING2_TREFI_LSB) | 11104ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRCD << 11204ae4489SMarek Vasut SDR_CTRLGRP_DRAMTIMING2_TRCD_LSB) | 11304ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TRP << 11404ae4489SMarek Vasut SDR_CTRLGRP_DRAMTIMING2_TRP_LSB) | 11504ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWR << 11604ae4489SMarek Vasut SDR_CTRLGRP_DRAMTIMING2_TWR_LSB) | 11704ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING2_IF_TWTR << 11804ae4489SMarek Vasut SDR_CTRLGRP_DRAMTIMING2_TWTR_LSB), 11904ae4489SMarek Vasut .dram_timing3 = 12004ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRTP << 12104ae4489SMarek Vasut SDR_CTRLGRP_DRAMTIMING3_TRTP_LSB) | 12204ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRAS << 12304ae4489SMarek Vasut SDR_CTRLGRP_DRAMTIMING3_TRAS_LSB) | 12404ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TRC << 12504ae4489SMarek Vasut SDR_CTRLGRP_DRAMTIMING3_TRC_LSB) | 12604ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TMRD << 12704ae4489SMarek Vasut SDR_CTRLGRP_DRAMTIMING3_TMRD_LSB) | 12804ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING3_TCCD << 12904ae4489SMarek Vasut SDR_CTRLGRP_DRAMTIMING3_TCCD_LSB), 13004ae4489SMarek Vasut .dram_timing4 = 13104ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING4_SELFRFSHEXIT << 13204ae4489SMarek Vasut SDR_CTRLGRP_DRAMTIMING4_SELFRFSHEXIT_LSB) | 13304ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMTIMING4_PWRDOWNEXIT << 13404ae4489SMarek Vasut SDR_CTRLGRP_DRAMTIMING4_PWRDOWNEXIT_LSB), 13504ae4489SMarek Vasut .lowpwr_timing = 13604ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_LOWPWRTIMING_AUTOPDCYCLES << 13704ae4489SMarek Vasut SDR_CTRLGRP_LOWPWRTIMING_AUTOPDCYCLES_LSB) | 13804ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_LOWPWRTIMING_CLKDISABLECYCLES << 13904ae4489SMarek Vasut SDR_CTRLGRP_LOWPWRTIMING_CLKDISABLECYCLES_LSB), 140*dc3b91d9SMarek Vasut .dram_odt = 141*dc3b91d9SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMODT_READ << 142*dc3b91d9SMarek Vasut SDR_CTRLGRP_DRAMODT_READ_LSB) | 143*dc3b91d9SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMODT_WRITE << 144*dc3b91d9SMarek Vasut SDR_CTRLGRP_DRAMODT_WRITE_LSB), 14504ae4489SMarek Vasut .dram_addrw = 14604ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_COLBITS << 14704ae4489SMarek Vasut SDR_CTRLGRP_DRAMADDRW_COLBITS_LSB) | 14804ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_BANKBITS << 14904ae4489SMarek Vasut SDR_CTRLGRP_DRAMADDRW_BANKBITS_LSB) | 15004ae4489SMarek Vasut ((CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS - 1) << 15104ae4489SMarek Vasut SDR_CTRLGRP_DRAMADDRW_CSBITS_LSB), 152*dc3b91d9SMarek Vasut .dram_if_width = 153*dc3b91d9SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMIFWIDTH_IFWIDTH << 154*dc3b91d9SMarek Vasut SDR_CTRLGRP_DRAMIFWIDTH_IFWIDTH_LSB), 155*dc3b91d9SMarek Vasut .dram_dev_width = 156*dc3b91d9SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMDEVWIDTH_DEVWIDTH << 157*dc3b91d9SMarek Vasut SDR_CTRLGRP_DRAMDEVWIDTH_DEVWIDTH_LSB), 158*dc3b91d9SMarek Vasut .dram_intr = 159*dc3b91d9SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_DRAMINTR_INTREN << 160*dc3b91d9SMarek Vasut SDR_CTRLGRP_DRAMINTR_INTREN_LSB), 161*dc3b91d9SMarek Vasut .lowpwr_eq = 162*dc3b91d9SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_LOWPWREQ_SELFRFSHMASK << 163*dc3b91d9SMarek Vasut SDR_CTRLGRP_LOWPWREQ_SELFRFSHMASK_LSB), 16404ae4489SMarek Vasut .static_cfg = 16504ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_STATICCFG_MEMBL << 16604ae4489SMarek Vasut SDR_CTRLGRP_STATICCFG_MEMBL_LSB) | 16704ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_STATICCFG_USEECCASDATA << 16804ae4489SMarek Vasut SDR_CTRLGRP_STATICCFG_USEECCASDATA_LSB), 169*dc3b91d9SMarek Vasut .ctrl_width = 170*dc3b91d9SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_CTRLWIDTH_CTRLWIDTH << 171*dc3b91d9SMarek Vasut SDR_CTRLGRP_CTRLWIDTH_CTRLWIDTH_LSB), 172*dc3b91d9SMarek Vasut .cport_width = 173*dc3b91d9SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_CPORTWIDTH_CPORTWIDTH << 174*dc3b91d9SMarek Vasut SDR_CTRLGRP_CPORTWIDTH_CMDPORTWIDTH_LSB), 175*dc3b91d9SMarek Vasut .cport_wmap = 176*dc3b91d9SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_CPORTWMAP_CPORTWMAP << 177*dc3b91d9SMarek Vasut SDR_CTRLGRP_CPORTWMAP_CPORTWFIFOMAP_LSB), 178*dc3b91d9SMarek Vasut .cport_rmap = 179*dc3b91d9SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_CPORTRMAP_CPORTRMAP << 180*dc3b91d9SMarek Vasut SDR_CTRLGRP_CPORTRMAP_CPORTRFIFOMAP_LSB), 181*dc3b91d9SMarek Vasut .rfifo_cmap = 182*dc3b91d9SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_RFIFOCMAP_RFIFOCMAP << 183*dc3b91d9SMarek Vasut SDR_CTRLGRP_RFIFOCMAP_RFIFOCPORTMAP_LSB), 184*dc3b91d9SMarek Vasut .wfifo_cmap = 185*dc3b91d9SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_WFIFOCMAP_WFIFOCMAP << 186*dc3b91d9SMarek Vasut SDR_CTRLGRP_WFIFOCMAP_WFIFOCPORTMAP_LSB), 187*dc3b91d9SMarek Vasut .cport_rdwr = 188*dc3b91d9SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_CPORTRDWR_CPORTRDWR << 189*dc3b91d9SMarek Vasut SDR_CTRLGRP_CPORTRDWR_CPORTRDWR_LSB), 190*dc3b91d9SMarek Vasut .port_cfg = 191*dc3b91d9SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_PORTCFG_AUTOPCHEN << 192*dc3b91d9SMarek Vasut SDR_CTRLGRP_PORTCFG_AUTOPCHEN_LSB), 193*dc3b91d9SMarek Vasut .fpgaport_rst = CONFIG_HPS_SDR_CTRLCFG_FPGAPORTRST, 19404ae4489SMarek Vasut .fifo_cfg = 19504ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_FIFOCFG_SYNCMODE << 19604ae4489SMarek Vasut SDR_CTRLGRP_FIFOCFG_SYNCMODE_LSB) | 19704ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_FIFOCFG_INCSYNC << 19804ae4489SMarek Vasut SDR_CTRLGRP_FIFOCFG_INCSYNC_LSB), 199*dc3b91d9SMarek Vasut .mp_priority = 200*dc3b91d9SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_MPPRIORITY_USERPRIORITY << 201*dc3b91d9SMarek Vasut SDR_CTRLGRP_MPPRIORITY_USERPRIORITY_LSB), 20204ae4489SMarek Vasut .mp_weight0 = 20304ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_0_STATICWEIGHT_31_0 << 20404ae4489SMarek Vasut SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_0_STATICWEIGHT_31_0_LSB), 20504ae4489SMarek Vasut .mp_weight1 = 20604ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_STATICWEIGHT_49_32 << 20704ae4489SMarek Vasut SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_1_STATICWEIGHT_49_32_LSB) | 20804ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_1_SUMOFWEIGHT_13_0 << 20904ae4489SMarek Vasut SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_1_SUMOFWEIGHTS_13_0_LSB), 21004ae4489SMarek Vasut .mp_weight2 = 21104ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_2_SUMOFWEIGHT_45_14 << 21204ae4489SMarek Vasut SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_2_SUMOFWEIGHTS_45_14_LSB), 21304ae4489SMarek Vasut .mp_weight3 = 21404ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_MPWIEIGHT_3_SUMOFWEIGHT_63_46 << 21504ae4489SMarek Vasut SDR_CTRLGRP_MPWEIGHT_MPWEIGHT_3_SUMOFWEIGHTS_63_46_LSB), 21604ae4489SMarek Vasut .mp_pacing0 = 21704ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_MPPACING_0_THRESHOLD1_31_0 << 21804ae4489SMarek Vasut SDR_CTRLGRP_MPPACING_MPPACING_0_THRESHOLD1_31_0_LSB), 21904ae4489SMarek Vasut .mp_pacing1 = 22004ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD1_59_32 << 22104ae4489SMarek Vasut SDR_CTRLGRP_MPPACING_MPPACING_1_THRESHOLD1_59_32_LSB) | 22204ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_MPPACING_1_THRESHOLD2_3_0 << 22304ae4489SMarek Vasut SDR_CTRLGRP_MPPACING_MPPACING_1_THRESHOLD2_3_0_LSB), 22404ae4489SMarek Vasut .mp_pacing2 = 22504ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_MPPACING_2_THRESHOLD2_35_4 << 22604ae4489SMarek Vasut SDR_CTRLGRP_MPPACING_MPPACING_2_THRESHOLD2_35_4_LSB), 22704ae4489SMarek Vasut .mp_pacing3 = 22804ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_MPPACING_3_THRESHOLD2_59_36 << 22904ae4489SMarek Vasut SDR_CTRLGRP_MPPACING_MPPACING_3_THRESHOLD2_59_36_LSB), 23004ae4489SMarek Vasut .mp_threshold0 = 23104ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_0_THRESHOLDRSTCYCLES_31_0 << 23204ae4489SMarek Vasut SDR_CTRLGRP_MPTHRESHOLDRST_0_THRESHOLDRSTCYCLES_31_0_LSB), 23304ae4489SMarek Vasut .mp_threshold1 = 23404ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_1_THRESHOLDRSTCYCLES_63_32 << 23504ae4489SMarek Vasut SDR_CTRLGRP_MPTHRESHOLDRST_1_THRESHOLDRSTCYCLES_63_32_LSB), 23604ae4489SMarek Vasut .mp_threshold2 = 23704ae4489SMarek Vasut (CONFIG_HPS_SDR_CTRLCFG_MPTHRESHOLDRST_2_THRESHOLDRSTCYCLES_79_64 << 23804ae4489SMarek Vasut SDR_CTRLGRP_MPTHRESHOLDRST_2_THRESHOLDRSTCYCLES_79_64_LSB), 239*dc3b91d9SMarek Vasut .phy_ctrl0 = CONFIG_HPS_SDR_CTRLCFG_PHYCTRL_PHYCTRL_0, 24004ae4489SMarek Vasut }; 24104ae4489SMarek Vasut 242f3671697SMarek Vasut /** 243f3671697SMarek Vasut * get_errata_rows() - Up the number of DRAM rows to cover entire address space 244f3671697SMarek Vasut * 245f3671697SMarek Vasut * SDRAM Failure happens when accessing non-existent memory. Artificially 246f3671697SMarek Vasut * increase the number of rows so that the memory controller thinks it has 247f3671697SMarek Vasut * 4GB of RAM. This function returns such amount of rows. 248f3671697SMarek Vasut */ 249f3671697SMarek Vasut static int get_errata_rows(void) 2509bbd2132SDinh Nguyen { 251f3671697SMarek Vasut /* Define constant for 4G memory - used for SDRAM errata workaround */ 252f3671697SMarek Vasut #define MEMSIZE_4G (4ULL * 1024ULL * 1024ULL * 1024ULL) 253f3671697SMarek Vasut const unsigned long long memsize = MEMSIZE_4G; 254f3671697SMarek Vasut const unsigned int cs = CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS; 255f3671697SMarek Vasut const unsigned int rows = CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS; 256f3671697SMarek Vasut const unsigned int banks = CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_BANKBITS; 257f3671697SMarek Vasut const unsigned int cols = CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_COLBITS; 258f3671697SMarek Vasut const unsigned int width = 8; 259f3671697SMarek Vasut 2609bbd2132SDinh Nguyen unsigned long long newrows; 261f3671697SMarek Vasut int bits, inewrowslog2; 2629bbd2132SDinh Nguyen 2639bbd2132SDinh Nguyen debug("workaround rows - memsize %lld\n", memsize); 2649bbd2132SDinh Nguyen debug("workaround rows - cs %d\n", cs); 2659bbd2132SDinh Nguyen debug("workaround rows - width %d\n", width); 2669bbd2132SDinh Nguyen debug("workaround rows - rows %d\n", rows); 2679bbd2132SDinh Nguyen debug("workaround rows - banks %d\n", banks); 2689bbd2132SDinh Nguyen debug("workaround rows - cols %d\n", cols); 2699bbd2132SDinh Nguyen 270791d20e1SMarek Vasut newrows = lldiv(memsize, cs * (width / 8)); 2719bbd2132SDinh Nguyen debug("rows workaround - term1 %lld\n", newrows); 2729bbd2132SDinh Nguyen 273791d20e1SMarek Vasut newrows = lldiv(newrows, (1 << banks) * (1 << cols)); 2749bbd2132SDinh Nguyen debug("rows workaround - term2 %lld\n", newrows); 2759bbd2132SDinh Nguyen 276791d20e1SMarek Vasut /* 277791d20e1SMarek Vasut * Compute the hamming weight - same as number of bits set. 2789bbd2132SDinh Nguyen * Need to see if result is ordinal power of 2 before 2799bbd2132SDinh Nguyen * attempting log2 of result. 2809bbd2132SDinh Nguyen */ 28158d86144SMarek Vasut bits = generic_hweight32(newrows); 2829bbd2132SDinh Nguyen 2839bbd2132SDinh Nguyen debug("rows workaround - bits %d\n", bits); 2849bbd2132SDinh Nguyen 2859bbd2132SDinh Nguyen if (bits != 1) { 2869bbd2132SDinh Nguyen printf("SDRAM workaround failed, bits set %d\n", bits); 2879bbd2132SDinh Nguyen return rows; 2889bbd2132SDinh Nguyen } 2899bbd2132SDinh Nguyen 2909bbd2132SDinh Nguyen if (newrows > UINT_MAX) { 2919bbd2132SDinh Nguyen printf("SDRAM workaround rangecheck failed, %lld\n", newrows); 2929bbd2132SDinh Nguyen return rows; 2939bbd2132SDinh Nguyen } 2949bbd2132SDinh Nguyen 295791d20e1SMarek Vasut inewrowslog2 = __ilog2(newrows); 2969bbd2132SDinh Nguyen 297791d20e1SMarek Vasut debug("rows workaround - ilog2 %d, %lld\n", inewrowslog2, newrows); 2989bbd2132SDinh Nguyen 2999bbd2132SDinh Nguyen if (inewrowslog2 == -1) { 300791d20e1SMarek Vasut printf("SDRAM workaround failed, newrows %lld\n", newrows); 3019bbd2132SDinh Nguyen return rows; 3029bbd2132SDinh Nguyen } 3039bbd2132SDinh Nguyen 3049bbd2132SDinh Nguyen return inewrowslog2; 3059bbd2132SDinh Nguyen } 3069bbd2132SDinh Nguyen 3079bbd2132SDinh Nguyen /* SDRAM protection rules vary from 0-19, a total of 20 rules. */ 3089bbd2132SDinh Nguyen static void sdram_set_rule(struct sdram_prot_rule *prule) 3099bbd2132SDinh Nguyen { 3109bbd2132SDinh Nguyen uint32_t lo_addr_bits; 3119bbd2132SDinh Nguyen uint32_t hi_addr_bits; 3129bbd2132SDinh Nguyen int ruleno = prule->rule; 3139bbd2132SDinh Nguyen 3149bbd2132SDinh Nguyen /* Select the rule */ 3159bbd2132SDinh Nguyen writel(ruleno, &sdr_ctrl->prot_rule_rdwr); 3169bbd2132SDinh Nguyen 3179bbd2132SDinh Nguyen /* Obtain the address bits */ 3189bbd2132SDinh Nguyen lo_addr_bits = (uint32_t)(((prule->sdram_start) >> 20ULL) & 0xFFF); 3199bbd2132SDinh Nguyen hi_addr_bits = (uint32_t)((((prule->sdram_end-1) >> 20ULL)) & 0xFFF); 3209bbd2132SDinh Nguyen 3219bbd2132SDinh Nguyen debug("sdram set rule start %x, %lld\n", lo_addr_bits, 3229bbd2132SDinh Nguyen prule->sdram_start); 3239bbd2132SDinh Nguyen debug("sdram set rule end %x, %lld\n", hi_addr_bits, 3249bbd2132SDinh Nguyen prule->sdram_end); 3259bbd2132SDinh Nguyen 3269bbd2132SDinh Nguyen /* Set rule addresses */ 3279bbd2132SDinh Nguyen writel(lo_addr_bits | (hi_addr_bits << 12), &sdr_ctrl->prot_rule_addr); 3289bbd2132SDinh Nguyen 3299bbd2132SDinh Nguyen /* Set rule protection ids */ 3309bbd2132SDinh Nguyen writel(prule->lo_prot_id | (prule->hi_prot_id << 12), 3319bbd2132SDinh Nguyen &sdr_ctrl->prot_rule_id); 3329bbd2132SDinh Nguyen 3339bbd2132SDinh Nguyen /* Set the rule data */ 3349bbd2132SDinh Nguyen writel(prule->security | (prule->valid << 2) | 3359bbd2132SDinh Nguyen (prule->portmask << 3) | (prule->result << 13), 3369bbd2132SDinh Nguyen &sdr_ctrl->prot_rule_data); 3379bbd2132SDinh Nguyen 3389bbd2132SDinh Nguyen /* write the rule */ 3399bbd2132SDinh Nguyen writel(ruleno | (1L << 5), &sdr_ctrl->prot_rule_rdwr); 3409bbd2132SDinh Nguyen 3419bbd2132SDinh Nguyen /* Set rule number to 0 by default */ 3429bbd2132SDinh Nguyen writel(0, &sdr_ctrl->prot_rule_rdwr); 3439bbd2132SDinh Nguyen } 3449bbd2132SDinh Nguyen 3459bbd2132SDinh Nguyen static void sdram_get_rule(struct sdram_prot_rule *prule) 3469bbd2132SDinh Nguyen { 3479bbd2132SDinh Nguyen uint32_t addr; 3489bbd2132SDinh Nguyen uint32_t id; 3499bbd2132SDinh Nguyen uint32_t data; 3509bbd2132SDinh Nguyen int ruleno = prule->rule; 3519bbd2132SDinh Nguyen 3529bbd2132SDinh Nguyen /* Read the rule */ 3539bbd2132SDinh Nguyen writel(ruleno, &sdr_ctrl->prot_rule_rdwr); 3549bbd2132SDinh Nguyen writel(ruleno | (1L << 6), &sdr_ctrl->prot_rule_rdwr); 3559bbd2132SDinh Nguyen 3569bbd2132SDinh Nguyen /* Get the addresses */ 3579bbd2132SDinh Nguyen addr = readl(&sdr_ctrl->prot_rule_addr); 3589bbd2132SDinh Nguyen prule->sdram_start = (addr & 0xFFF) << 20; 3599bbd2132SDinh Nguyen prule->sdram_end = ((addr >> 12) & 0xFFF) << 20; 3609bbd2132SDinh Nguyen 3619bbd2132SDinh Nguyen /* Get the configured protection IDs */ 3629bbd2132SDinh Nguyen id = readl(&sdr_ctrl->prot_rule_id); 3639bbd2132SDinh Nguyen prule->lo_prot_id = id & 0xFFF; 3649bbd2132SDinh Nguyen prule->hi_prot_id = (id >> 12) & 0xFFF; 3659bbd2132SDinh Nguyen 3669bbd2132SDinh Nguyen /* Get protection data */ 3679bbd2132SDinh Nguyen data = readl(&sdr_ctrl->prot_rule_data); 3689bbd2132SDinh Nguyen 3699bbd2132SDinh Nguyen prule->security = data & 0x3; 3709bbd2132SDinh Nguyen prule->valid = (data >> 2) & 0x1; 3719bbd2132SDinh Nguyen prule->portmask = (data >> 3) & 0x3FF; 3729bbd2132SDinh Nguyen prule->result = (data >> 13) & 0x1; 3739bbd2132SDinh Nguyen } 3749bbd2132SDinh Nguyen 3759bbd2132SDinh Nguyen static void sdram_set_protection_config(uint64_t sdram_start, uint64_t sdram_end) 3769bbd2132SDinh Nguyen { 3779bbd2132SDinh Nguyen struct sdram_prot_rule rule; 3789bbd2132SDinh Nguyen int rules; 3799bbd2132SDinh Nguyen 3809bbd2132SDinh Nguyen /* Start with accepting all SDRAM transaction */ 3819bbd2132SDinh Nguyen writel(0x0, &sdr_ctrl->protport_default); 3829bbd2132SDinh Nguyen 3839bbd2132SDinh Nguyen /* Clear all protection rules for warm boot case */ 3849bbd2132SDinh Nguyen memset(&rule, 0, sizeof(struct sdram_prot_rule)); 3859bbd2132SDinh Nguyen 3869bbd2132SDinh Nguyen for (rules = 0; rules < 20; rules++) { 3879bbd2132SDinh Nguyen rule.rule = rules; 3889bbd2132SDinh Nguyen sdram_set_rule(&rule); 3899bbd2132SDinh Nguyen } 3909bbd2132SDinh Nguyen 3919bbd2132SDinh Nguyen /* new rule: accept SDRAM */ 3929bbd2132SDinh Nguyen rule.sdram_start = sdram_start; 3939bbd2132SDinh Nguyen rule.sdram_end = sdram_end; 3949bbd2132SDinh Nguyen rule.lo_prot_id = 0x0; 3959bbd2132SDinh Nguyen rule.hi_prot_id = 0xFFF; 3969bbd2132SDinh Nguyen rule.portmask = 0x3FF; 3979bbd2132SDinh Nguyen rule.security = 0x3; 3989bbd2132SDinh Nguyen rule.result = 0; 3999bbd2132SDinh Nguyen rule.valid = 1; 4009bbd2132SDinh Nguyen rule.rule = 0; 4019bbd2132SDinh Nguyen 4029bbd2132SDinh Nguyen /* set new rule */ 4039bbd2132SDinh Nguyen sdram_set_rule(&rule); 4049bbd2132SDinh Nguyen 4059bbd2132SDinh Nguyen /* default rule: reject everything */ 4069bbd2132SDinh Nguyen writel(0x3ff, &sdr_ctrl->protport_default); 4079bbd2132SDinh Nguyen } 4089bbd2132SDinh Nguyen 4099bbd2132SDinh Nguyen static void sdram_dump_protection_config(void) 4109bbd2132SDinh Nguyen { 4119bbd2132SDinh Nguyen struct sdram_prot_rule rule; 4129bbd2132SDinh Nguyen int rules; 4139bbd2132SDinh Nguyen 4149bbd2132SDinh Nguyen debug("SDRAM Prot rule, default %x\n", 4159bbd2132SDinh Nguyen readl(&sdr_ctrl->protport_default)); 4169bbd2132SDinh Nguyen 4179bbd2132SDinh Nguyen for (rules = 0; rules < 20; rules++) { 4189bbd2132SDinh Nguyen sdram_get_rule(&rule); 4199bbd2132SDinh Nguyen debug("Rule %d, rules ...\n", rules); 4209bbd2132SDinh Nguyen debug(" sdram start %llx\n", rule.sdram_start); 4219bbd2132SDinh Nguyen debug(" sdram end %llx\n", rule.sdram_end); 4229bbd2132SDinh Nguyen debug(" low prot id %d, hi prot id %d\n", 4239bbd2132SDinh Nguyen rule.lo_prot_id, 4249bbd2132SDinh Nguyen rule.hi_prot_id); 4259bbd2132SDinh Nguyen debug(" portmask %x\n", rule.portmask); 4269bbd2132SDinh Nguyen debug(" security %d\n", rule.security); 4279bbd2132SDinh Nguyen debug(" result %d\n", rule.result); 4289bbd2132SDinh Nguyen debug(" valid %d\n", rule.valid); 4299bbd2132SDinh Nguyen } 4309bbd2132SDinh Nguyen } 4319bbd2132SDinh Nguyen 4329bbd2132SDinh Nguyen /* Function to write to register and verify the write */ 4339bbd2132SDinh Nguyen static unsigned sdram_write_verify(unsigned int *addr, unsigned reg_value) 4349bbd2132SDinh Nguyen { 4359bbd2132SDinh Nguyen #ifndef SDRAM_MMR_SKIP_VERIFY 4369bbd2132SDinh Nguyen unsigned reg_value1; 4379bbd2132SDinh Nguyen #endif 4389bbd2132SDinh Nguyen debug(" Write - Address "); 4399bbd2132SDinh Nguyen debug("0x%08x Data 0x%08x\n", (u32)addr, reg_value); 4409bbd2132SDinh Nguyen /* Write to register */ 4419bbd2132SDinh Nguyen writel(reg_value, addr); 4429bbd2132SDinh Nguyen #ifndef SDRAM_MMR_SKIP_VERIFY 4439bbd2132SDinh Nguyen debug(" Read and verify..."); 4449bbd2132SDinh Nguyen /* Read back the wrote value */ 4459bbd2132SDinh Nguyen reg_value1 = readl(addr); 4469bbd2132SDinh Nguyen /* Indicate failure if value not matched */ 4479bbd2132SDinh Nguyen if (reg_value1 != reg_value) { 4489bbd2132SDinh Nguyen debug("FAIL - Address 0x%08x Expected 0x%08x Data 0x%08x\n", 4499bbd2132SDinh Nguyen (u32)addr, reg_value, reg_value1); 4509bbd2132SDinh Nguyen return 1; 4519bbd2132SDinh Nguyen } 4529bbd2132SDinh Nguyen debug("correct!\n"); 4539bbd2132SDinh Nguyen #endif /* SDRAM_MMR_SKIP_VERIFY */ 4549bbd2132SDinh Nguyen return 0; 4559bbd2132SDinh Nguyen } 4569bbd2132SDinh Nguyen 45704ae4489SMarek Vasut static void set_sdr_ctrlcfg(struct socfpga_sdram_config *cfg) 4589bbd2132SDinh Nguyen { 459067c853fSMarek Vasut u32 addrorder; 46004ae4489SMarek Vasut u32 ctrl_cfg = cfg->ctrl_cfg; 4619bbd2132SDinh Nguyen 4629bbd2132SDinh Nguyen debug("\nConfiguring CTRLCFG\n"); 4639bbd2132SDinh Nguyen 464067c853fSMarek Vasut /* 465067c853fSMarek Vasut * SDRAM Failure When Accessing Non-Existent Memory 4669bbd2132SDinh Nguyen * Set the addrorder field of the SDRAM control register 4679bbd2132SDinh Nguyen * based on the CSBITs setting. 4689bbd2132SDinh Nguyen */ 4699bbd2132SDinh Nguyen switch (CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS) { 4709bbd2132SDinh Nguyen case 1: 4719bbd2132SDinh Nguyen addrorder = 0; /* chip, row, bank, column */ 4729bbd2132SDinh Nguyen if (CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ADDRORDER != 0) 473067c853fSMarek Vasut debug("INFO: Changing address order to 0 (chip, row, bank, column)\n"); 4749bbd2132SDinh Nguyen break; 4759bbd2132SDinh Nguyen case 2: 4769bbd2132SDinh Nguyen addrorder = 2; /* row, chip, bank, column */ 4779bbd2132SDinh Nguyen if (CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ADDRORDER != 2) 478067c853fSMarek Vasut debug("INFO: Changing address order to 2 (row, chip, bank, column)\n"); 4799bbd2132SDinh Nguyen break; 4809bbd2132SDinh Nguyen default: 4819bbd2132SDinh Nguyen addrorder = CONFIG_HPS_SDR_CTRLCFG_CTRLCFG_ADDRORDER; 4829bbd2132SDinh Nguyen break; 4839bbd2132SDinh Nguyen } 4849bbd2132SDinh Nguyen 485067c853fSMarek Vasut ctrl_cfg |= addrorder << SDR_CTRLGRP_CTRLCFG_ADDRORDER_LSB; 4869bbd2132SDinh Nguyen 487067c853fSMarek Vasut writel(ctrl_cfg, &sdr_ctrl->ctrl_cfg); 4889bbd2132SDinh Nguyen } 4899bbd2132SDinh Nguyen 49004ae4489SMarek Vasut static void set_sdr_dram_timing(struct socfpga_sdram_config *cfg) 4919bbd2132SDinh Nguyen { 49260bd0df0SMarek Vasut debug("Configuring DRAMTIMING1\n"); 49304ae4489SMarek Vasut writel(cfg->dram_timing1, &sdr_ctrl->dram_timing1); 49460bd0df0SMarek Vasut 49560bd0df0SMarek Vasut debug("Configuring DRAMTIMING2\n"); 49604ae4489SMarek Vasut writel(cfg->dram_timing2, &sdr_ctrl->dram_timing2); 49760bd0df0SMarek Vasut 49860bd0df0SMarek Vasut debug("Configuring DRAMTIMING3\n"); 49904ae4489SMarek Vasut writel(cfg->dram_timing3, &sdr_ctrl->dram_timing3); 50060bd0df0SMarek Vasut 50160bd0df0SMarek Vasut debug("Configuring DRAMTIMING4\n"); 50204ae4489SMarek Vasut writel(cfg->dram_timing4, &sdr_ctrl->dram_timing4); 50360bd0df0SMarek Vasut 50460bd0df0SMarek Vasut debug("Configuring LOWPWRTIMING\n"); 50504ae4489SMarek Vasut writel(cfg->lowpwr_timing, &sdr_ctrl->lowpwr_timing); 5069bbd2132SDinh Nguyen } 5079bbd2132SDinh Nguyen 50804ae4489SMarek Vasut static void set_sdr_addr_rw(struct socfpga_sdram_config *cfg) 5099bbd2132SDinh Nguyen { 5109bbd2132SDinh Nguyen /* 5119bbd2132SDinh Nguyen * SDRAM Failure When Accessing Non-Existent Memory 5129bbd2132SDinh Nguyen * Set SDR_CTRLGRP_DRAMADDRW_CSBITS_LSB to 5139bbd2132SDinh Nguyen * log2(number of chip select bits). Since there's only 5149bbd2132SDinh Nguyen * 1 or 2 chip selects, log2(1) => 0, and log2(2) => 1, 5159bbd2132SDinh Nguyen * which is the same as "chip selects" - 1. 5169bbd2132SDinh Nguyen */ 5170ef88300SMarek Vasut const int rows = get_errata_rows(); 51804ae4489SMarek Vasut 5190ef88300SMarek Vasut debug("Configuring DRAMADDRW\n"); 52004ae4489SMarek Vasut writel(cfg->dram_addrw | (rows << SDR_CTRLGRP_DRAMADDRW_ROWBITS_LSB), 52104ae4489SMarek Vasut &sdr_ctrl->dram_addrw); 5229bbd2132SDinh Nguyen } 5239bbd2132SDinh Nguyen 52404ae4489SMarek Vasut static void set_sdr_static_cfg(struct socfpga_sdram_config *cfg) 5259bbd2132SDinh Nguyen { 526b3bdb220SMarek Vasut debug("Configuring STATICCFG\n"); 52704ae4489SMarek Vasut writel(cfg->static_cfg, &sdr_ctrl->static_cfg); 5289bbd2132SDinh Nguyen } 5299bbd2132SDinh Nguyen 53004ae4489SMarek Vasut static void set_sdr_fifo_cfg(struct socfpga_sdram_config *cfg) 5319bbd2132SDinh Nguyen { 5321009e396SMarek Vasut debug("Configuring FIFOCFG\n"); 53304ae4489SMarek Vasut writel(cfg->fifo_cfg, &sdr_ctrl->fifo_cfg); 5349bbd2132SDinh Nguyen } 5359bbd2132SDinh Nguyen 53604ae4489SMarek Vasut static void set_sdr_mp_weight(struct socfpga_sdram_config *cfg) 5379bbd2132SDinh Nguyen { 538a5ba9296SMarek Vasut debug("Configuring MPWEIGHT_MPWEIGHT_0\n"); 53904ae4489SMarek Vasut writel(cfg->mp_weight0, &sdr_ctrl->mp_weight0); 54004ae4489SMarek Vasut writel(cfg->mp_weight1, &sdr_ctrl->mp_weight1); 54104ae4489SMarek Vasut writel(cfg->mp_weight2, &sdr_ctrl->mp_weight2); 54204ae4489SMarek Vasut writel(cfg->mp_weight3, &sdr_ctrl->mp_weight3); 5439bbd2132SDinh Nguyen } 5449bbd2132SDinh Nguyen 54504ae4489SMarek Vasut static void set_sdr_mp_pacing(struct socfpga_sdram_config *cfg) 5469bbd2132SDinh Nguyen { 547ad2ba5d6SMarek Vasut debug("Configuring MPPACING_MPPACING_0\n"); 54804ae4489SMarek Vasut writel(cfg->mp_pacing0, &sdr_ctrl->mp_pacing0); 54904ae4489SMarek Vasut writel(cfg->mp_pacing1, &sdr_ctrl->mp_pacing1); 55004ae4489SMarek Vasut writel(cfg->mp_pacing2, &sdr_ctrl->mp_pacing2); 55104ae4489SMarek Vasut writel(cfg->mp_pacing3, &sdr_ctrl->mp_pacing3); 5529bbd2132SDinh Nguyen } 5539bbd2132SDinh Nguyen 55404ae4489SMarek Vasut static void set_sdr_mp_threshold(struct socfpga_sdram_config *cfg) 5559bbd2132SDinh Nguyen { 5569a48a9acSMarek Vasut debug("Configuring MPTHRESHOLDRST_MPTHRESHOLDRST_0\n"); 55704ae4489SMarek Vasut writel(cfg->mp_threshold0, &sdr_ctrl->mp_threshold0); 55804ae4489SMarek Vasut writel(cfg->mp_threshold1, &sdr_ctrl->mp_threshold1); 55904ae4489SMarek Vasut writel(cfg->mp_threshold2, &sdr_ctrl->mp_threshold2); 5609a48a9acSMarek Vasut } 5619bbd2132SDinh Nguyen 5629bbd2132SDinh Nguyen /* Function to initialize SDRAM MMR */ 5639bbd2132SDinh Nguyen unsigned sdram_mmr_init_full(unsigned int sdr_phy_reg) 5649bbd2132SDinh Nguyen { 5659bbd2132SDinh Nguyen unsigned long status = 0; 56604ae4489SMarek Vasut struct socfpga_sdram_config *cfg = &sdram_config; 5679bbd2132SDinh Nguyen 5689bbd2132SDinh Nguyen #if defined(CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS) && \ 5699bbd2132SDinh Nguyen defined(CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS) && \ 5709bbd2132SDinh Nguyen defined(CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_BANKBITS) && \ 5719bbd2132SDinh Nguyen defined(CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_COLBITS) && \ 5729bbd2132SDinh Nguyen defined(CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS) 5739bbd2132SDinh Nguyen 5749bbd2132SDinh Nguyen writel(CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS, 5759bbd2132SDinh Nguyen &sysmgr_regs->iswgrp_handoff[4]); 5769bbd2132SDinh Nguyen #endif 57704ae4489SMarek Vasut set_sdr_ctrlcfg(cfg); 57804ae4489SMarek Vasut set_sdr_dram_timing(cfg); 57904ae4489SMarek Vasut set_sdr_addr_rw(cfg); 5809bbd2132SDinh Nguyen 5819bbd2132SDinh Nguyen debug("Configuring DRAMIFWIDTH\n"); 582*dc3b91d9SMarek Vasut writel(cfg->dram_if_width, &sdr_ctrl->dram_if_width); 5839bbd2132SDinh Nguyen 5849bbd2132SDinh Nguyen debug("Configuring DRAMDEVWIDTH\n"); 585*dc3b91d9SMarek Vasut writel(cfg->dram_dev_width, &sdr_ctrl->dram_dev_width); 5869bbd2132SDinh Nguyen 5879bbd2132SDinh Nguyen debug("Configuring LOWPWREQ\n"); 588*dc3b91d9SMarek Vasut writel(cfg->lowpwr_eq, &sdr_ctrl->lowpwr_eq); 5899bbd2132SDinh Nguyen 5909bbd2132SDinh Nguyen debug("Configuring DRAMINTR\n"); 591*dc3b91d9SMarek Vasut writel(cfg->dram_intr, &sdr_ctrl->dram_intr); 5929bbd2132SDinh Nguyen 59304ae4489SMarek Vasut set_sdr_static_cfg(cfg); 5949bbd2132SDinh Nguyen 5959bbd2132SDinh Nguyen debug("Configuring CTRLWIDTH\n"); 596*dc3b91d9SMarek Vasut writel(cfg->ctrl_width, &sdr_ctrl->ctrl_width); 5979bbd2132SDinh Nguyen 5989bbd2132SDinh Nguyen debug("Configuring PORTCFG\n"); 599*dc3b91d9SMarek Vasut writel(cfg->port_cfg, &sdr_ctrl->port_cfg); 6009bbd2132SDinh Nguyen 60104ae4489SMarek Vasut set_sdr_fifo_cfg(cfg); 6029bbd2132SDinh Nguyen 6039bbd2132SDinh Nguyen debug("Configuring MPPRIORITY\n"); 604*dc3b91d9SMarek Vasut writel(cfg->mp_priority, &sdr_ctrl->mp_priority); 6059bbd2132SDinh Nguyen 60604ae4489SMarek Vasut set_sdr_mp_weight(cfg); 60704ae4489SMarek Vasut set_sdr_mp_pacing(cfg); 60804ae4489SMarek Vasut set_sdr_mp_threshold(cfg); 6099bbd2132SDinh Nguyen 6109bbd2132SDinh Nguyen debug("Configuring PHYCTRL_PHYCTRL_0\n"); 611*dc3b91d9SMarek Vasut writel(cfg->phy_ctrl0, &sdr_ctrl->phy_ctrl0); 6129bbd2132SDinh Nguyen 6139bbd2132SDinh Nguyen debug("Configuring CPORTWIDTH\n"); 614*dc3b91d9SMarek Vasut writel(cfg->cport_width, &sdr_ctrl->cport_width); 6159bbd2132SDinh Nguyen 6169bbd2132SDinh Nguyen debug("Configuring CPORTWMAP\n"); 617*dc3b91d9SMarek Vasut writel(cfg->cport_wmap, &sdr_ctrl->cport_wmap); 6189bbd2132SDinh Nguyen 6199bbd2132SDinh Nguyen debug("Configuring CPORTRMAP\n"); 620*dc3b91d9SMarek Vasut writel(cfg->cport_rmap, &sdr_ctrl->cport_rmap); 6219bbd2132SDinh Nguyen 6229bbd2132SDinh Nguyen debug("Configuring RFIFOCMAP\n"); 623*dc3b91d9SMarek Vasut writel(cfg->rfifo_cmap, &sdr_ctrl->rfifo_cmap); 6249bbd2132SDinh Nguyen 6259bbd2132SDinh Nguyen debug("Configuring WFIFOCMAP\n"); 626*dc3b91d9SMarek Vasut writel(cfg->wfifo_cmap, &sdr_ctrl->wfifo_cmap); 6279bbd2132SDinh Nguyen 6289bbd2132SDinh Nguyen debug("Configuring CPORTRDWR\n"); 629*dc3b91d9SMarek Vasut writel(cfg->cport_rdwr, &sdr_ctrl->cport_rdwr); 6309bbd2132SDinh Nguyen 6319bbd2132SDinh Nguyen debug("Configuring DRAMODT\n"); 632*dc3b91d9SMarek Vasut writel(cfg->dram_odt, &sdr_ctrl->dram_odt); 6339bbd2132SDinh Nguyen 6349bbd2132SDinh Nguyen /* saving this value to SYSMGR.ISWGRP.HANDOFF.FPGA2SDR */ 635*dc3b91d9SMarek Vasut writel(cfg->fpgaport_rst, &sysmgr_regs->iswgrp_handoff[3]); 6369bbd2132SDinh Nguyen 6379bbd2132SDinh Nguyen /* only enable if the FPGA is programmed */ 6389bbd2132SDinh Nguyen if (fpgamgr_test_fpga_ready()) { 6399bbd2132SDinh Nguyen if (sdram_write_verify(&sdr_ctrl->fpgaport_rst, 640*dc3b91d9SMarek Vasut cfg->fpgaport_rst) == 1) { 6419bbd2132SDinh Nguyen status = 1; 6429bbd2132SDinh Nguyen return 1; 6439bbd2132SDinh Nguyen } 6449bbd2132SDinh Nguyen } 6459bbd2132SDinh Nguyen 6469bbd2132SDinh Nguyen /* Restore the SDR PHY Register if valid */ 6479bbd2132SDinh Nguyen if (sdr_phy_reg != 0xffffffff) 6489bbd2132SDinh Nguyen writel(sdr_phy_reg, &sdr_ctrl->phy_ctrl0); 6499bbd2132SDinh Nguyen 650*dc3b91d9SMarek Vasut /* Final step - apply configuration changes */ 651*dc3b91d9SMarek Vasut debug("Configuring STATICCFG\n"); 652*dc3b91d9SMarek Vasut clrsetbits_le32(&sdr_ctrl->static_cfg, 653*dc3b91d9SMarek Vasut SDR_CTRLGRP_STATICCFG_APPLYCFG_MASK, 6549bbd2132SDinh Nguyen 1 << SDR_CTRLGRP_STATICCFG_APPLYCFG_LSB); 6559bbd2132SDinh Nguyen 6569bbd2132SDinh Nguyen sdram_set_protection_config(0, sdram_calculate_size()); 6579bbd2132SDinh Nguyen 6589bbd2132SDinh Nguyen sdram_dump_protection_config(); 6599bbd2132SDinh Nguyen 6609bbd2132SDinh Nguyen return status; 6619bbd2132SDinh Nguyen } 6629bbd2132SDinh Nguyen 6639bbd2132SDinh Nguyen /* 6649bbd2132SDinh Nguyen * To calculate SDRAM device size based on SDRAM controller parameters. 6659bbd2132SDinh Nguyen * Size is specified in bytes. 6669bbd2132SDinh Nguyen * 6679bbd2132SDinh Nguyen * NOTE: 6689bbd2132SDinh Nguyen * This function is compiled and linked into the preloader and 6699bbd2132SDinh Nguyen * Uboot (there may be others). So if this function changes, the Preloader 6709bbd2132SDinh Nguyen * and UBoot must be updated simultaneously. 6719bbd2132SDinh Nguyen */ 6729bbd2132SDinh Nguyen unsigned long sdram_calculate_size(void) 6739bbd2132SDinh Nguyen { 6749bbd2132SDinh Nguyen unsigned long temp; 6759bbd2132SDinh Nguyen unsigned long row, bank, col, cs, width; 6769bbd2132SDinh Nguyen 6779bbd2132SDinh Nguyen temp = readl(&sdr_ctrl->dram_addrw); 6789bbd2132SDinh Nguyen col = (temp & SDR_CTRLGRP_DRAMADDRW_COLBITS_MASK) >> 6799bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMADDRW_COLBITS_LSB; 6809bbd2132SDinh Nguyen 6819bbd2132SDinh Nguyen /* SDRAM Failure When Accessing Non-Existent Memory 6829bbd2132SDinh Nguyen * Use ROWBITS from Quartus/QSys to calculate SDRAM size 6839bbd2132SDinh Nguyen * since the FB specifies we modify ROWBITs to work around SDRAM 6849bbd2132SDinh Nguyen * controller issue. 6859bbd2132SDinh Nguyen * 6869bbd2132SDinh Nguyen * If the stored handoff value for rows is 0, it probably means 6879bbd2132SDinh Nguyen * the preloader is older than UBoot. Use the 6889bbd2132SDinh Nguyen * #define from the SOCEDS Tools per Crucible review 6899bbd2132SDinh Nguyen * uboot-socfpga-204. Note that this is not a supported 6909bbd2132SDinh Nguyen * configuration and is not tested. The customer 6919bbd2132SDinh Nguyen * should be using preloader and uboot built from the 6929bbd2132SDinh Nguyen * same tag. 6939bbd2132SDinh Nguyen */ 6949bbd2132SDinh Nguyen row = readl(&sysmgr_regs->iswgrp_handoff[4]); 6959bbd2132SDinh Nguyen if (row == 0) 6969bbd2132SDinh Nguyen row = CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS; 6979bbd2132SDinh Nguyen /* If the stored handoff value for rows is greater than 6989bbd2132SDinh Nguyen * the field width in the sdr.dramaddrw register then 6999bbd2132SDinh Nguyen * something is very wrong. Revert to using the the #define 7009bbd2132SDinh Nguyen * value handed off by the SOCEDS tool chain instead of 7019bbd2132SDinh Nguyen * using a broken value. 7029bbd2132SDinh Nguyen */ 7039bbd2132SDinh Nguyen if (row > 31) 7049bbd2132SDinh Nguyen row = CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_ROWBITS; 7059bbd2132SDinh Nguyen 7069bbd2132SDinh Nguyen bank = (temp & SDR_CTRLGRP_DRAMADDRW_BANKBITS_MASK) >> 7079bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMADDRW_BANKBITS_LSB; 7089bbd2132SDinh Nguyen 7099bbd2132SDinh Nguyen /* SDRAM Failure When Accessing Non-Existent Memory 7109bbd2132SDinh Nguyen * Use CSBITs from Quartus/QSys to calculate SDRAM size 7119bbd2132SDinh Nguyen * since the FB specifies we modify CSBITs to work around SDRAM 7129bbd2132SDinh Nguyen * controller issue. 7139bbd2132SDinh Nguyen */ 7149bbd2132SDinh Nguyen cs = (temp & SDR_CTRLGRP_DRAMADDRW_CSBITS_MASK) >> 7159bbd2132SDinh Nguyen SDR_CTRLGRP_DRAMADDRW_CSBITS_LSB; 7169bbd2132SDinh Nguyen cs += 1; 7179bbd2132SDinh Nguyen 7189bbd2132SDinh Nguyen cs = CONFIG_HPS_SDR_CTRLCFG_DRAMADDRW_CSBITS; 7199bbd2132SDinh Nguyen 7209bbd2132SDinh Nguyen width = readl(&sdr_ctrl->dram_if_width); 7219bbd2132SDinh Nguyen /* ECC would not be calculated as its not addressible */ 7229bbd2132SDinh Nguyen if (width == SDRAM_WIDTH_32BIT_WITH_ECC) 7239bbd2132SDinh Nguyen width = 32; 7249bbd2132SDinh Nguyen if (width == SDRAM_WIDTH_16BIT_WITH_ECC) 7259bbd2132SDinh Nguyen width = 16; 7269bbd2132SDinh Nguyen 7279bbd2132SDinh Nguyen /* calculate the SDRAM size base on this info */ 7289bbd2132SDinh Nguyen temp = 1 << (row + bank + col); 7299bbd2132SDinh Nguyen temp = temp * cs * (width / 8); 7309bbd2132SDinh Nguyen 7319bbd2132SDinh Nguyen debug("sdram_calculate_memory returns %ld\n", temp); 7329bbd2132SDinh Nguyen 7339bbd2132SDinh Nguyen return temp; 7349bbd2132SDinh Nguyen } 735