/* * Copyright 2017 Scalys B.V. * opensource@scalys.com * * SPDX-License-Identifier: GPL-2.0+ */ #include #include #include #include #include #include #include DECLARE_GLOBAL_DATA_PTR; /* MT41K512M8RH-125 */ dimm_params_t ddr_raw_timing = { .n_ranks = 2, .rank_density = 0x100000000ULL, .capacity = 0x200000000ULL, .primary_sdram_width = 64, .ec_sdram_width = 8, .registered_dimm = 0, .mirrored_dimm = 1, .n_row_addr = 16, .n_col_addr = 10, .n_banks_per_sdram_device = 8, .edc_config = EDC_ECC, .burst_lengths_bitmask = 0x0c, .tckmin_x_ps = 1250, .tckmax_ps = 1499, .caslat_x = (1 << 11), .taa_ps = 13750, .trcd_ps = 13750, .trp_ps = 13750, .tras_ps = 35000, .trc_ps = 48750, .tfaw_ps = 30000, .twr_ps = 15000, .trfc_ps = 260000, .trrd_ps = 5000, //1Kb page size! .twtr_ps = 7500, .trtp_ps = 7500, .refresh_rate_ps = 70200000, }; void fsl_ddr_board_options(memctl_options_t *popts, dimm_params_t *pdimm, unsigned int ctrl_num) { int i; if (ctrl_num != 0) { printf("Only 1 memory controller supported, but %i requested\n", ctrl_num); return; } if (pdimm == NULL ) { printf("Error, no valid dimm pararmeter supplied\n"); return; } if (!pdimm->n_ranks) { printf("No ranks in dimm parameters. Configuration error?\n"); return; } /* set odt_rd_cfg and odt_wr_cfg. */ for (i = 0; i < CONFIG_CHIP_SELECTS_PER_CTRL; i++) { popts->cs_local_opts[i].odt_wr_cfg = 4; } popts->wrlvl_en = 1; popts->wrlvl_override = 1; popts->wrlvl_sample = 13; popts->wrlvl_start = 7; /* 7/8 clock delay */ popts->wrlvl_ctl_2 = 0x06070809; popts->wrlvl_ctl_3 = 0x0d0f0a09; popts->ddr_cdr1 = 0x800c0000; popts->ddr_cdr2 = 0x00000001; /* Clock is launched 1/2 applied cycle after address/command */ popts->clk_adjust = 8; /* Optimized cpo */ popts->cpo_sample = 0x46; } int fsl_ddr_get_dimm_params(dimm_params_t *pdimm, unsigned int controller_number, unsigned int dimm_number) { const char dimm_model[] = "Soldered-down discrete DDR3"; if (((controller_number == 0) && (dimm_number == 0)) || ((controller_number == 1) && (dimm_number == 0))) { memcpy(pdimm, &ddr_raw_timing, sizeof(dimm_params_t)); memset(pdimm->mpart, 0, sizeof(pdimm->mpart)); memcpy(pdimm->mpart, dimm_model, sizeof(dimm_model) - 1); } return 0; } int dram_init(void) { phys_size_t dram_size; #if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_RAMBOOT_PBL) uint32_t regval; /* Remove reset of DDR using GPIO pin. We do this manually since * we have not yet access to the DM gpio at this time */ /* DDR_RST_N => IFC_CS3_B => GPIO2_12 */ #define CONFIG_SYS_MPC85XX_GPIO2_ADDR (CONFIG_SYS_IMMR + 0x131000) #define DDR_RST_N (12) /* DDR_RST_N => IFC_CS3_B => GPIO2_12 */ /* #define DDR_RST_N MPC85XX_GPIO_NR(2, 12) */ /* Set output */ regval = in_be32((size_t*)CONFIG_SYS_MPC85XX_GPIO2_ADDR+0x8); regval |= (0x80000000 >> 12); out_be32((size_t*)CONFIG_SYS_MPC85XX_GPIO2_ADDR+0x8, regval); /* Set direction to acivate gpio pin */ regval = in_be32((size_t*)CONFIG_SYS_MPC85XX_GPIO2_ADDR); regval |= (0x80000000 >> 12); out_be32((size_t*)CONFIG_SYS_MPC85XX_GPIO2_ADDR, regval); dram_size = fsl_ddr_sdram(); dram_size = setup_ddr_tlbs(dram_size / 0x100000); dram_size *= 0x100000; #else /* DDR has been initialised by SPL loader */ dram_size = fsl_ddr_sdram_size(); #endif gd->ram_size = dram_size; return 0; }