/*
 * Copyright 2008 Freescale Semiconductor, Inc.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * Version 2 as published by the Free Software Foundation.
 */

#include <common.h>

#include <fsl_ddr_sdram.h>
#include <fsl_ddr_dimm_params.h>

struct board_specific_parameters {
	u32 n_ranks;
	u32 datarate_mhz_high;
	u32 clk_adjust;
	u32 cpo;
	u32 write_data_delay;
	u32 force_2t;
};

/*
 * This table contains all valid speeds we want to override with board
 * specific parameters. datarate_mhz_high values need to be in ascending order
 * for each n_ranks group.
 *
 * For DDR2 DIMM, all combinations of clk_adjust and write_data_delay have been
 * tested. For RDIMM, clk_adjust = 4 and write_data_delay = 3 is optimized for
 * all clocks from 400MT/s to 800MT/s, verified with Kingston KVR800D2D8P6/2G.
 * For UDIMM, clk_adjust = 8 and write_delay = 5 is optimized for all clocks
 * from 400MT/s to 800MT/s, verified with Micron MT18HTF25672AY-800E1.
 *
 * CPO value doesn't matter if workaround for errata 111 and 134 enabled.
 */
static const struct board_specific_parameters udimm0[] = {
	/*
	 * memory controller 0
	 *   num|  hi|  clk| cpo|wrdata|2T
	 * ranks| mhz|adjst|    | delay|
	 */
	{2,  333,    8,   7,    5,  0},
	{2,  400,    8,   9,    5,  0},
	{2,  549,    8,  11,    5,  0},
	{2,  680,    8,  10,    5,  0},
	{2,  850,    8,  12,    5,  1},
	{1,  333,    6,   7,    3,  0},
	{1,  400,    6,   9,    3,  0},
	{1,  549,    6,  11,    3,  0},
	{1,  680,    1,  10,    5,  0},
	{1,  850,    1,  12,    5,  0},
	{}
};

static const struct board_specific_parameters udimm1[] = {
	/*
	 * memory controller 1
	 *   num|  hi|  clk| cpo|wrdata|2T
	 * ranks| mhz|adjst|    | delay|
	 */
	{2,  333,    8,  7,    5,  0},
	{2,  400,    8,  9,    5,  0},
	{2,  549,    8, 11,    5,  0},
	{2,  680,    8, 11,    5,  0},
	{2,  850,    8, 13,    5,  1},
	{1,  333,    6,  7,    3,  0},
	{1,  400,    6,  9,    3,  0},
	{1,  549,    6, 11,    3,  0},
	{1,  680,    1, 11,    6,  0},
	{1,  850,    1, 13,    6,  0},
	{}
};

static const struct board_specific_parameters *udimms[] = {
	udimm0,
	udimm1,
};

static const struct board_specific_parameters rdimm0[] = {
	/*
	 * memory controller 0
	 *   num|  hi|  clk| cpo|wrdata|2T
	 * ranks| mhz|adjst|    | delay|
	 */
	{2,  333,    4,   7,    3,  0},
	{2,  400,    4,   9,    3,  0},
	{2,  549,    4,  11,    3,  0},
	{2,  680,    4,  10,    3,  0},
	{2,  850,    4,  12,    3,  1},
	{}
};

static const struct board_specific_parameters rdimm1[] = {
	/*
	 * memory controller 1
	 *   num|  hi|  clk| cpo|wrdata|2T
	 * ranks| mhz|adjst|    | delay|
	 */
	{2,  333,     4,  7,    3,  0},
	{2,  400,     4,  9,    3,  0},
	{2,  549,     4, 11,    3,  0},
	{2,  680,     4, 11,    3,  0},
	{2,  850,     4, 13,    3,  1},
	{}
};

static const struct board_specific_parameters *rdimms[] = {
	rdimm0,
	rdimm1,
};

void fsl_ddr_board_options(memctl_options_t *popts,
				dimm_params_t *pdimm,
				unsigned int ctrl_num)
{
	const struct board_specific_parameters *pbsp, *pbsp_highest = NULL;
	ulong ddr_freq;

	if (ctrl_num > 1) {
		printf("Wrong parameter for controller number %d", ctrl_num);
		return;
	}
	if (!pdimm->n_ranks)
		return;

	if (popts->registered_dimm_en)
		pbsp = rdimms[ctrl_num];
	else
		pbsp = udimms[ctrl_num];

	/* Get clk_adjust, cpo, write_data_delay,2T, according to the board ddr
	 * freqency and n_banks specified in board_specific_parameters table.
	 */
	ddr_freq = get_ddr_freq(0) / 1000000;
	while (pbsp->datarate_mhz_high) {
		if (pbsp->n_ranks == pdimm->n_ranks) {
			if (ddr_freq <= pbsp->datarate_mhz_high) {
				popts->clk_adjust = pbsp->clk_adjust;
				popts->cpo_override = pbsp->cpo;
				popts->write_data_delay =
					pbsp->write_data_delay;
				popts->twot_en = pbsp->force_2t;
				goto found;
			}
			pbsp_highest = pbsp;
		}
		pbsp++;
	}

	if (pbsp_highest) {
		printf("Error: board specific timing not found "
			"for data rate %lu MT/s!\n"
			"Trying to use the highest speed (%u) parameters\n",
			ddr_freq, pbsp_highest->datarate_mhz_high);
		popts->clk_adjust = pbsp->clk_adjust;
		popts->cpo_override = pbsp->cpo;
		popts->write_data_delay = pbsp->write_data_delay;
		popts->twot_en = pbsp->force_2t;
	} else {
		panic("DIMM is not supported by this board");
	}

found:
	/*
	 * Factors to consider for half-strength driver enable:
	 *	- number of DIMMs installed
	 */
	popts->half_strength_driver_enable = 0;
}
