1*4f1d1b7dSMingkai Hu /* 2*4f1d1b7dSMingkai Hu * Copyright 2011 Freescale Semiconductor, Inc. 3*4f1d1b7dSMingkai Hu * 4*4f1d1b7dSMingkai Hu * This program is free software; you can redistribute it and/or 5*4f1d1b7dSMingkai Hu * modify it under the terms of the GNU General Public License 6*4f1d1b7dSMingkai Hu * Version 2 as published by the Free Software Foundation. 7*4f1d1b7dSMingkai Hu */ 8*4f1d1b7dSMingkai Hu 9*4f1d1b7dSMingkai Hu #include <common.h> 10*4f1d1b7dSMingkai Hu #include <i2c.h> 11*4f1d1b7dSMingkai Hu #include <hwconfig.h> 12*4f1d1b7dSMingkai Hu #include <asm/mmu.h> 13*4f1d1b7dSMingkai Hu #include <asm/fsl_ddr_sdram.h> 14*4f1d1b7dSMingkai Hu #include <asm/fsl_ddr_dimm_params.h> 15*4f1d1b7dSMingkai Hu #include <asm/fsl_law.h> 16*4f1d1b7dSMingkai Hu 17*4f1d1b7dSMingkai Hu typedef struct { 18*4f1d1b7dSMingkai Hu u32 datarate_mhz_low; 19*4f1d1b7dSMingkai Hu u32 datarate_mhz_high; 20*4f1d1b7dSMingkai Hu u32 n_ranks; 21*4f1d1b7dSMingkai Hu u32 clk_adjust; 22*4f1d1b7dSMingkai Hu u32 wrlvl_start; 23*4f1d1b7dSMingkai Hu u32 cpo; 24*4f1d1b7dSMingkai Hu u32 write_data_delay; 25*4f1d1b7dSMingkai Hu u32 force_2T; 26*4f1d1b7dSMingkai Hu } board_specific_parameters_t; 27*4f1d1b7dSMingkai Hu 28*4f1d1b7dSMingkai Hu /* 29*4f1d1b7dSMingkai Hu * ranges for parameters: 30*4f1d1b7dSMingkai Hu * wr_data_delay = 0-6 31*4f1d1b7dSMingkai Hu * clk adjust = 0-8 32*4f1d1b7dSMingkai Hu * cpo 2-0x1E (30) 33*4f1d1b7dSMingkai Hu */ 34*4f1d1b7dSMingkai Hu const board_specific_parameters_t board_specific_parameters[] = { 35*4f1d1b7dSMingkai Hu /* 36*4f1d1b7dSMingkai Hu * memory controller 0 37*4f1d1b7dSMingkai Hu * lo| hi| num| clk| wrlvl | cpo |wrdata|2T 38*4f1d1b7dSMingkai Hu * mhz| mhz|ranks|adjst| start | delay| 39*4f1d1b7dSMingkai Hu */ 40*4f1d1b7dSMingkai Hu { 1017, 1116, 2, 4, 6, 0xff, 2, 0}, 41*4f1d1b7dSMingkai Hu }; 42*4f1d1b7dSMingkai Hu 43*4f1d1b7dSMingkai Hu void fsl_ddr_board_options(memctl_options_t *popts, 44*4f1d1b7dSMingkai Hu dimm_params_t *pdimm, 45*4f1d1b7dSMingkai Hu unsigned int ctrl_num) 46*4f1d1b7dSMingkai Hu { 47*4f1d1b7dSMingkai Hu const board_specific_parameters_t *pbsp = 48*4f1d1b7dSMingkai Hu &board_specific_parameters[0]; 49*4f1d1b7dSMingkai Hu u32 num_params = ARRAY_SIZE(board_specific_parameters); 50*4f1d1b7dSMingkai Hu u32 i; 51*4f1d1b7dSMingkai Hu ulong ddr_freq; 52*4f1d1b7dSMingkai Hu 53*4f1d1b7dSMingkai Hu /* 54*4f1d1b7dSMingkai Hu * Get clk_adjust, cpo, write_data_delay,2T, according to the board ddr 55*4f1d1b7dSMingkai Hu * freqency and n_banks specified in board_specific_parameters table. 56*4f1d1b7dSMingkai Hu */ 57*4f1d1b7dSMingkai Hu ddr_freq = get_ddr_freq(0) / 1000000; 58*4f1d1b7dSMingkai Hu for (i = 0; i < num_params; i++) { 59*4f1d1b7dSMingkai Hu if (ddr_freq >= pbsp->datarate_mhz_low && 60*4f1d1b7dSMingkai Hu ddr_freq <= pbsp->datarate_mhz_high && 61*4f1d1b7dSMingkai Hu pdimm[0].n_ranks == pbsp->n_ranks) { 62*4f1d1b7dSMingkai Hu popts->cpo_override = pbsp->cpo; 63*4f1d1b7dSMingkai Hu popts->write_data_delay = pbsp->write_data_delay; 64*4f1d1b7dSMingkai Hu popts->clk_adjust = pbsp->clk_adjust; 65*4f1d1b7dSMingkai Hu popts->wrlvl_start = pbsp->wrlvl_start; 66*4f1d1b7dSMingkai Hu popts->twoT_en = pbsp->force_2T; 67*4f1d1b7dSMingkai Hu break; 68*4f1d1b7dSMingkai Hu } 69*4f1d1b7dSMingkai Hu pbsp++; 70*4f1d1b7dSMingkai Hu } 71*4f1d1b7dSMingkai Hu 72*4f1d1b7dSMingkai Hu if (i == num_params) { 73*4f1d1b7dSMingkai Hu printf("Warning: board specific timing not found " 74*4f1d1b7dSMingkai Hu "for data rate %lu MT/s!\n", ddr_freq); 75*4f1d1b7dSMingkai Hu } 76*4f1d1b7dSMingkai Hu 77*4f1d1b7dSMingkai Hu /* 78*4f1d1b7dSMingkai Hu * Factors to consider for half-strength driver enable: 79*4f1d1b7dSMingkai Hu * - number of DIMMs installed 80*4f1d1b7dSMingkai Hu */ 81*4f1d1b7dSMingkai Hu popts->half_strength_driver_enable = 0; 82*4f1d1b7dSMingkai Hu /* Write leveling override */ 83*4f1d1b7dSMingkai Hu popts->wrlvl_override = 1; 84*4f1d1b7dSMingkai Hu popts->wrlvl_sample = 0xf; 85*4f1d1b7dSMingkai Hu 86*4f1d1b7dSMingkai Hu /* Rtt and Rtt_WR override */ 87*4f1d1b7dSMingkai Hu popts->rtt_override = 0; 88*4f1d1b7dSMingkai Hu 89*4f1d1b7dSMingkai Hu /* Enable ZQ calibration */ 90*4f1d1b7dSMingkai Hu popts->zq_en = 1; 91*4f1d1b7dSMingkai Hu 92*4f1d1b7dSMingkai Hu /* DHC_EN =1, ODT = 60 Ohm */ 93*4f1d1b7dSMingkai Hu popts->ddr_cdr1 = DDR_CDR1_DHC_EN; 94*4f1d1b7dSMingkai Hu } 95*4f1d1b7dSMingkai Hu 96*4f1d1b7dSMingkai Hu phys_size_t initdram(int board_type) 97*4f1d1b7dSMingkai Hu { 98*4f1d1b7dSMingkai Hu phys_size_t dram_size = 0; 99*4f1d1b7dSMingkai Hu 100*4f1d1b7dSMingkai Hu puts("Initializing...."); 101*4f1d1b7dSMingkai Hu 102*4f1d1b7dSMingkai Hu if (fsl_use_spd()) { 103*4f1d1b7dSMingkai Hu puts("using SPD\n"); 104*4f1d1b7dSMingkai Hu dram_size = fsl_ddr_sdram(); 105*4f1d1b7dSMingkai Hu } else { 106*4f1d1b7dSMingkai Hu puts("no SPD and fixed parameters\n"); 107*4f1d1b7dSMingkai Hu return dram_size; 108*4f1d1b7dSMingkai Hu } 109*4f1d1b7dSMingkai Hu 110*4f1d1b7dSMingkai Hu dram_size = setup_ddr_tlbs(dram_size / 0x100000); 111*4f1d1b7dSMingkai Hu dram_size *= 0x100000; 112*4f1d1b7dSMingkai Hu 113*4f1d1b7dSMingkai Hu puts(" DDR: "); 114*4f1d1b7dSMingkai Hu return dram_size; 115*4f1d1b7dSMingkai Hu } 116