mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-17 10:18:38 +00:00
e7563aff17
The ddr code computes most things as 64-bit quantities and had some places in the middle that it was using phy_addr_t and phys_size_t. Instead we use unsigned long long through out and only at the last stage of setting the LAWs and reporting the amount of memory to the board code do we truncate down to what we can cover via phys_size_t. This has the added benefit that the DDR controller itself is always setup the same way regardless of how much memory we have. Its only the LAW setup that limits what is visible to the system. Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
109 lines
2.6 KiB
C
109 lines
2.6 KiB
C
/*
|
|
* 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 <asm/fsl_law.h>
|
|
|
|
#include "ddr.h"
|
|
|
|
unsigned int fsl_ddr_get_mem_data_rate(void);
|
|
|
|
/*
|
|
* Round mclk_ps to nearest 10 ps in memory controller code.
|
|
*
|
|
* If an imprecise data rate is too high due to rounding error
|
|
* propagation, compute a suitably rounded mclk_ps to compute
|
|
* a working memory controller configuration.
|
|
*/
|
|
unsigned int get_memory_clk_period_ps(void)
|
|
{
|
|
unsigned int mclk_ps;
|
|
|
|
mclk_ps = 2000000000000ULL / fsl_ddr_get_mem_data_rate();
|
|
/* round to nearest 10 ps */
|
|
return 10 * ((mclk_ps + 5) / 10);
|
|
}
|
|
|
|
/* Convert picoseconds into DRAM clock cycles (rounding up if needed). */
|
|
unsigned int picos_to_mclk(unsigned int picos)
|
|
{
|
|
const unsigned long long ULL_2e12 = 2000000000000ULL;
|
|
const unsigned long long ULL_8Fs = 0xFFFFFFFFULL;
|
|
unsigned long long clks;
|
|
unsigned long long clks_temp;
|
|
|
|
if (!picos)
|
|
return 0;
|
|
|
|
clks = fsl_ddr_get_mem_data_rate() * (unsigned long long) picos;
|
|
clks_temp = clks;
|
|
clks = clks / ULL_2e12;
|
|
if (clks_temp % ULL_2e12) {
|
|
clks++;
|
|
}
|
|
|
|
if (clks > ULL_8Fs) {
|
|
clks = ULL_8Fs;
|
|
}
|
|
|
|
return (unsigned int) clks;
|
|
}
|
|
|
|
unsigned int mclk_to_picos(unsigned int mclk)
|
|
{
|
|
return get_memory_clk_period_ps() * mclk;
|
|
}
|
|
|
|
void
|
|
__fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params,
|
|
unsigned int memctl_interleaved,
|
|
unsigned int ctrl_num)
|
|
{
|
|
unsigned long long base = memctl_common_params->base_address;
|
|
unsigned long long size = memctl_common_params->total_mem;
|
|
|
|
/*
|
|
* If no DIMMs on this controller, do not proceed any further.
|
|
*/
|
|
if (!memctl_common_params->ndimms_present) {
|
|
return;
|
|
}
|
|
|
|
#if !defined(CONFIG_PHYS_64BIT)
|
|
if (base >= CONFIG_MAX_MEM_MAPPED)
|
|
return;
|
|
if ((base + size) >= CONFIG_MAX_MEM_MAPPED)
|
|
size = CONFIG_MAX_MEM_MAPPED - base;
|
|
#endif
|
|
|
|
if (ctrl_num == 0) {
|
|
/*
|
|
* Set up LAW for DDR controller 1 space.
|
|
*/
|
|
unsigned int lawbar1_target_id = memctl_interleaved
|
|
? LAW_TRGT_IF_DDR_INTRLV : LAW_TRGT_IF_DDR_1;
|
|
|
|
if (set_ddr_laws(base, size, lawbar1_target_id) < 0) {
|
|
printf("ERROR\n");
|
|
return ;
|
|
}
|
|
} else if (ctrl_num == 1) {
|
|
if (set_ddr_laws(base, size, LAW_TRGT_IF_DDR_2) < 0) {
|
|
printf("ERROR\n");
|
|
return ;
|
|
}
|
|
} else {
|
|
printf("unexpected controller number %u in %s\n",
|
|
ctrl_num, __FUNCTION__);
|
|
}
|
|
}
|
|
|
|
__attribute__((weak, alias("__fsl_ddr_set_lawbar"))) void
|
|
fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params,
|
|
unsigned int memctl_interleaved,
|
|
unsigned int ctrl_num);
|