/*
 * 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.
 */

/*
 * Generic driver for Freescale DDR/DDR2/DDR3 memory controller.
 * Based on code from spd_sdram.c
 * Author: James Yang [at freescale.com]
 */

#include <common.h>
#include <asm/fsl_ddr_sdram.h>

#include "ddr.h"

extern void fsl_ddr_set_lawbar(
		const common_timing_params_t *memctl_common_params,
		unsigned int memctl_interleaved,
		unsigned int ctrl_num);

/* processor specific function */
extern void fsl_ddr_set_memctl_regs(const fsl_ddr_cfg_regs_t *regs,
				   unsigned int ctrl_num);

/* Board-specific functions defined in each board's ddr.c */
extern void fsl_ddr_get_spd(generic_spd_eeprom_t *ctrl_dimms_spd,
			   unsigned int ctrl_num);

/*
 * ASSUMPTIONS:
 *    - Same number of CONFIG_DIMM_SLOTS_PER_CTLR on each controller
 *    - Same memory data bus width on all controllers
 *
 * NOTES:
 *
 * The memory controller and associated documentation use confusing
 * terminology when referring to the orgranization of DRAM.
 *
 * Here is a terminology translation table:
 *
 * memory controller/documention  |industry   |this code  |signals
 * -------------------------------|-----------|-----------|-----------------
 * physical bank/bank		  |rank       |rank	  |chip select (CS)
 * logical bank/sub-bank	  |bank       |bank	  |bank address (BA)
 * page/row			  |row	      |page	  |row address
 * ???				  |column     |column	  |column address
 *
 * The naming confusion is further exacerbated by the descriptions of the
 * memory controller interleaving feature, where accesses are interleaved
 * _BETWEEN_ two seperate memory controllers.  This is configured only in
 * CS0_CONFIG[INTLV_CTL] of each memory controller.
 *
 * memory controller documentation | number of chip selects
 *				   | per memory controller supported
 * --------------------------------|-----------------------------------------
 * cache line interleaving	   | 1 (CS0 only)
 * page interleaving		   | 1 (CS0 only)
 * bank interleaving		   | 1 (CS0 only)
 * superbank interleraving	   | depends on bank (chip select)
 *				   |   interleraving [rank interleaving]
 *				   |   mode used on every memory controller
 *
 * Even further confusing is the existence of the interleaving feature
 * _WITHIN_ each memory controller.  The feature is referred to in
 * documentation as chip select interleaving or bank interleaving,
 * although it is configured in the DDR_SDRAM_CFG field.
 *
 * Name of field		| documentation name	| this code
 * -----------------------------|-----------------------|------------------
 * DDR_SDRAM_CFG[BA_INTLV_CTL]	| Bank (chip select)	| rank interleaving
 *				|  interleaving
 */

#ifdef DEBUG
const char *step_string_tbl[] = {
	"STEP_GET_SPD",
	"STEP_COMPUTE_DIMM_PARMS",
	"STEP_COMPUTE_COMMON_PARMS",
	"STEP_GATHER_OPTS",
	"STEP_ASSIGN_ADDRESSES",
	"STEP_COMPUTE_REGS",
	"STEP_PROGRAM_REGS",
	"STEP_ALL"
};

const char * step_to_string(unsigned int step) {

	unsigned int s = __ilog2(step);

	if ((1 << s) != step)
		return step_string_tbl[7];

	return step_string_tbl[s];
}
#endif

int step_assign_addresses(fsl_ddr_info_t *pinfo,
			  unsigned int dbw_cap_adj[],
			  unsigned int *memctl_interleaving,
			  unsigned int *rank_interleaving)
{
	int i, j;

	/*
	 * If a reduced data width is requested, but the SPD
	 * specifies a physically wider device, adjust the
	 * computed dimm capacities accordingly before
	 * assigning addresses.
	 */
	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
		unsigned int found = 0;

		switch (pinfo->memctl_opts[i].data_bus_width) {
		case 2:
			/* 16-bit */
			printf("can't handle 16-bit mode yet\n");
			break;

		case 1:
			/* 32-bit */
			for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
				unsigned int dw;
				dw = pinfo->dimm_params[i][j].data_width;
				if (pinfo->dimm_params[i][j].n_ranks
				    && (dw == 72 || dw == 64)) {
					/*
					 * FIXME: can't really do it
					 * like this because this just
					 * further reduces the memory
					 */
					found = 1;
					break;
				}
			}
			if (found) {
				dbw_cap_adj[i] = 1;
			}
			break;

		case 0:
			/* 64-bit */
			break;

		default:
			printf("unexpected data bus width "
				"specified controller %u\n", i);
			return 1;
		}
	}

	/*
	 * Check if all controllers are configured for memory
	 * controller interleaving.
	 */
	j = 0;
	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
		if (pinfo->memctl_opts[i].memctl_interleaving) {
			j++;
		}
	}
	if (j == 2)
		*memctl_interleaving = 1;

	/* Check that all controllers are rank interleaving. */
	j = 0;
	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
		if (pinfo->memctl_opts[i].ba_intlv_ctl) {
			j++;
		}
	}
	if (j == 2)
		*rank_interleaving = 1;

	if (*memctl_interleaving) {
		unsigned long long addr, total_mem_per_ctlr = 0;
		/*
		 * If interleaving between memory controllers,
		 * make each controller start at a base address
		 * of 0.
		 *
		 * Also, if bank interleaving (chip select
		 * interleaving) is enabled on each memory
		 * controller, CS0 needs to be programmed to
		 * cover the entire memory range on that memory
		 * controller
		 *
		 * Bank interleaving also implies that each
		 * addressed chip select is identical in size.
		 */

		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
			addr = 0;
			pinfo->common_timing_params[i].base_address = 0ull;
			for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
				unsigned long long cap
					= pinfo->dimm_params[i][j].capacity;

				pinfo->dimm_params[i][j].base_address = addr;
				addr += cap >> dbw_cap_adj[i];
				total_mem_per_ctlr += cap >> dbw_cap_adj[i];
			}
		}
		pinfo->common_timing_params[0].total_mem = total_mem_per_ctlr;
	} else {
		/*
		 * Simple linear assignment if memory
		 * controllers are not interleaved.
		 */
		unsigned long long cur_memsize = 0;
		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
			u64 total_mem_per_ctlr = 0;
			pinfo->common_timing_params[i].base_address =
						cur_memsize;
			for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
				/* Compute DIMM base addresses. */
				unsigned long long cap =
					pinfo->dimm_params[i][j].capacity;
				pinfo->dimm_params[i][j].base_address =
					cur_memsize;
				cur_memsize += cap >> dbw_cap_adj[i];
				total_mem_per_ctlr += cap >> dbw_cap_adj[i];
			}
			pinfo->common_timing_params[i].total_mem =
							total_mem_per_ctlr;
		}
	}

	return 0;
}

unsigned long long
fsl_ddr_compute(fsl_ddr_info_t *pinfo, unsigned int start_step)
{
	unsigned int i, j;
	unsigned int all_controllers_memctl_interleaving = 0;
	unsigned int all_controllers_rank_interleaving = 0;
	unsigned long long total_mem = 0;

	fsl_ddr_cfg_regs_t *ddr_reg = pinfo->fsl_ddr_config_reg;
	common_timing_params_t *timing_params = pinfo->common_timing_params;

	/* data bus width capacity adjust shift amount */
	unsigned int dbw_capacity_adjust[CONFIG_NUM_DDR_CONTROLLERS];

	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
		dbw_capacity_adjust[i] = 0;
	}

	debug("starting at step %u (%s)\n",
	      start_step, step_to_string(start_step));

	switch (start_step) {
	case STEP_GET_SPD:
		/* STEP 1:  Gather all DIMM SPD data */
		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
			fsl_ddr_get_spd(pinfo->spd_installed_dimms[i], i);
		}

	case STEP_COMPUTE_DIMM_PARMS:
		/* STEP 2:  Compute DIMM parameters from SPD data */

		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
			for (j = 0; j < CONFIG_DIMM_SLOTS_PER_CTLR; j++) {
				unsigned int retval;
				generic_spd_eeprom_t *spd =
					&(pinfo->spd_installed_dimms[i][j]);
				dimm_params_t *pdimm =
					&(pinfo->dimm_params[i][j]);

				retval = compute_dimm_parameters(spd, pdimm, i);
				if (retval == 2) {
					printf("Error: compute_dimm_parameters"
					" non-zero returned FATAL value "
					"for memctl=%u dimm=%u\n", i, j);
					return 0;
				}
				if (retval) {
					debug("Warning: compute_dimm_parameters"
					" non-zero return value for memctl=%u "
					"dimm=%u\n", i, j);
				}
			}
		}

	case STEP_COMPUTE_COMMON_PARMS:
		/*
		 * STEP 3: Compute a common set of timing parameters
		 * suitable for all of the DIMMs on each memory controller
		 */
		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
			debug("Computing lowest common DIMM"
				" parameters for memctl=%u\n", i);
			compute_lowest_common_dimm_parameters(
				pinfo->dimm_params[i],
				&timing_params[i],
				CONFIG_DIMM_SLOTS_PER_CTLR);
		}

	case STEP_GATHER_OPTS:
		/* STEP 4:  Gather configuration requirements from user */
		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
			debug("Reloading memory controller "
				"configuration options for memctl=%u\n", i);
			/*
			 * This "reloads" the memory controller options
			 * to defaults.  If the user "edits" an option,
			 * next_step points to the step after this,
			 * which is currently STEP_ASSIGN_ADDRESSES.
			 */
			populate_memctl_options(
					timing_params[i].all_DIMMs_registered,
					&pinfo->memctl_opts[i],
					pinfo->dimm_params[i], i);
		}

	case STEP_ASSIGN_ADDRESSES:
		/* STEP 5:  Assign addresses to chip selects */
		step_assign_addresses(pinfo,
				dbw_capacity_adjust,
				&all_controllers_memctl_interleaving,
				&all_controllers_rank_interleaving);

	case STEP_COMPUTE_REGS:
		/* STEP 6:  compute controller register values */
		debug("FSL Memory ctrl cg register computation\n");
		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
			if (timing_params[i].ndimms_present == 0) {
				memset(&ddr_reg[i], 0,
					sizeof(fsl_ddr_cfg_regs_t));
				continue;
			}

			compute_fsl_memctl_config_regs(
					&pinfo->memctl_opts[i],
					&ddr_reg[i], &timing_params[i],
					pinfo->dimm_params[i],
					dbw_capacity_adjust[i]);
		}

	default:
		break;
	}

	/* Compute the total amount of memory. */

	/*
	 * If bank interleaving but NOT memory controller interleaving
	 * CS_BNDS describe the quantity of memory on each memory
	 * controller, so the total is the sum across.
	 */
	if (!all_controllers_memctl_interleaving
	    && all_controllers_rank_interleaving) {
		total_mem = 0;
		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
			total_mem += timing_params[i].total_mem;
		}

	} else {
		/*
		 * Compute the amount of memory available just by
		 * looking for the highest valid CSn_BNDS value.
		 * This allows us to also experiment with using
		 * only CS0 when using dual-rank DIMMs.
		 */
		unsigned int max_end = 0;

		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
			for (j = 0; j < CONFIG_CHIP_SELECTS_PER_CTRL; j++) {
				fsl_ddr_cfg_regs_t *reg = &ddr_reg[i];
				if (reg->cs[j].config & 0x80000000) {
					unsigned int end;
					end = reg->cs[j].bnds & 0xFFF;
					if (end > max_end) {
						max_end = end;
					}
				}
			}
		}

		total_mem = 1 + (((unsigned long long)max_end << 24ULL)
				    | 0xFFFFFFULL);
	}

	return total_mem;
}

/*
 * fsl_ddr_sdram() -- this is the main function to be called by
 *	initdram() in the board file.
 *
 * It returns amount of memory configured in bytes.
 */
phys_size_t fsl_ddr_sdram(void)
{
	unsigned int i;
	unsigned int memctl_interleaved;
	unsigned long long total_memory;
	fsl_ddr_info_t info;

	/* Reset info structure. */
	memset(&info, 0, sizeof(fsl_ddr_info_t));

	/* Compute it once normally. */
	total_memory = fsl_ddr_compute(&info, STEP_GET_SPD);

	/* Check for memory controller interleaving. */
	memctl_interleaved = 0;
	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
		memctl_interleaved +=
			info.memctl_opts[i].memctl_interleaving;
	}

	if (memctl_interleaved) {
		if (memctl_interleaved == CONFIG_NUM_DDR_CONTROLLERS) {
			debug("memctl interleaving\n");
			/*
			 * Change the meaning of memctl_interleaved
			 * to be "boolean".
			 */
			memctl_interleaved = 1;
		} else {
			printf("Warning: memctl interleaving not "
				"properly configured on all controllers\n");
			memctl_interleaved = 0;
			for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++)
				info.memctl_opts[i].memctl_interleaving = 0;
			debug("Recomputing with memctl_interleaving off.\n");
			total_memory = fsl_ddr_compute(&info,
						       STEP_ASSIGN_ADDRESSES);
		}
	}

	/* Program configuration registers. */
	for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
		debug("Programming controller %u\n", i);
		if (info.common_timing_params[i].ndimms_present == 0) {
			debug("No dimms present on controller %u; "
					"skipping programming\n", i);
			continue;
		}

		fsl_ddr_set_memctl_regs(&(info.fsl_ddr_config_reg[i]), i);
	}

	if (memctl_interleaved) {
		const unsigned int ctrl_num = 0;

		/* Only set LAWBAR1 if memory controller interleaving is on. */
		fsl_ddr_set_lawbar(&info.common_timing_params[0],
					 memctl_interleaved, ctrl_num);
	} else {
		/*
		 * Memory controller interleaving is NOT on;
		 * set each lawbar individually.
		 */
		for (i = 0; i < CONFIG_NUM_DDR_CONTROLLERS; i++) {
			fsl_ddr_set_lawbar(&info.common_timing_params[i],
						 0, i);
		}
	}

	debug("total_memory = %llu\n", total_memory);

#if !defined(CONFIG_PHYS_64BIT)
	/* Check for 4G or more.  Bad. */
	if (total_memory >= (1ull << 32)) {
		printf("Detected %lld MB of memory\n", total_memory >> 20);
		printf("This U-Boot only supports < 4G of DDR\n");
		printf("You could rebuild it with CONFIG_PHYS_64BIT\n");
		total_memory = CONFIG_MAX_MEM_MAPPED;
	}
#endif

	return total_memory;
}
