// SPDX-License-Identifier: GPL-2.0-only /* * linux/arch/arm/mach-sa1100/cpu-sa1110.c * * Copyright (C) 2001 Russell King * * Note: there are two erratas that apply to the SA1110 here: * 7 - SDRAM auto-power-up failure (rev A0) * 13 - Corruption of internal register reads/writes following * SDRAM reads (rev A0, B0, B1) * * We ignore rev. A0 and B0 devices; I don't think they're worth supporting. * * The SDRAM type can be passed on the command line as cpu_sa1110.sdram=type
*/ #include <linux/cpufreq.h> #include <linux/delay.h> #include <linux/init.h> #include <linux/io.h> #include <linux/kernel.h> #include <linux/moduleparam.h> #include <linux/types.h>
/* * Given a period in ns and frequency in khz, calculate the number of * cycles of frequency in period. Note that we round up to the next * cycle, even if we are only slightly over.
*/ staticinline u_int ns_to_cycles(u_int ns, u_int khz)
{ return (ns * khz + 999999) / 1000000;
}
/* * Create the MDCAS register bit pattern.
*/ staticinlinevoid set_mdcas(u_int *mdcas, int delayed, u_int rcd)
{
u_int shift;
/* * If SDCLK would invalidate the SDRAM timings, * run SDCLK at half speed. * * CPU steppings prior to B2 must either run the memory at * half speed or use delayed read latching (errata 13).
*/ if ((ns_to_cycles(sdram->tck, sd_khz) > 1) ||
(read_cpuid_revision() < ARM_CPU_REV_SA1110_B2 && sd_khz < 62000))
sd_khz /= 2;
sd->mdcnfg = MDCNFG & 0x007f007f;
twr = ns_to_cycles(sdram->twr, mem_khz);
/* trp should always be >1 */
trp = ns_to_cycles(sdram->trp, mem_khz) - 1; if (trp < 1)
trp = 1;
/* * Update the refresh period. We do this such that we always refresh * the SDRAMs within their permissible period. The refresh period is * always a multiple of the memory clock (fixed at cpu_clock / 2). * * FIXME: we don't currently take account of burst accesses here, * but neither do Intels DM nor Angel.
*/ staticvoid
sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram)
{
u_int ns_row = (sdram->refresh * 1000) >> sdram->rows;
u_int dri = ns_to_cycles(ns_row, cpu_khz / 2) / 32;
#ifdef DEBUG
mdelay(250);
printk(KERN_DEBUG "new dri value = %d\n", dri); #endif
sdram_set_refresh(dri);
}
/* * Ok, set the CPU frequency.
*/ staticint sa1110_target(struct cpufreq_policy *policy, unsignedint ppcr)
{ struct sdram_params *sdram = &sdram_params; struct sdram_info sd; unsignedlong flags; unsignedint unused;
#if 0 /* * These values are wrong according to the SA1110 documentation * and errata, but they seem to work. Need to get a storage * scope on to the SDRAM signals to work out why.
*/ if (policy->max < 147500) {
sd.mdrefr |= MDREFR_K1DB2;
sd.mdcas[0] = 0xaaaaaa7f;
} else {
sd.mdrefr &= ~MDREFR_K1DB2;
sd.mdcas[0] = 0xaaaaaa9f;
}
sd.mdcas[1] = 0xaaaaaaaa;
sd.mdcas[2] = 0xaaaaaaaa; #endif
/* * The clock could be going away for some time. Set the SDRAMs * to refresh rapidly (every 64 memory clock cycles). To get * through the whole array, we need to wait 262144 mclk cycles. * We wait 20ms to be safe.
*/
sdram_set_refresh(2); if (!irqs_disabled())
msleep(20); else
mdelay(20);
/* * Reprogram the DRAM timings with interrupts disabled, and * ensure that we are doing this within a complete cache line. * This means that we won't access SDRAM for the duration of * the programming.
*/
local_irq_save(flags); asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
udelay(10);
__asm__ __volatile__("\n\
b 2f \n\
.align 5 \n\
1: str %3, [%1, #0] @ MDCNFG \n\
str %4, [%1, #28] @ MDREFR \n\
str %5, [%1, #4] @ MDCAS0 \n\
str %6, [%1, #8] @ MDCAS1 \n\
str %7, [%1, #12] @ MDCAS2 \n\
str %8, [%2, #0] @ PPCR \n\
ldr %0, [%1, #0] \n\
b 3f \n\
2: b 1b \n\
3: nop \n\
nop"
: "=&r" (unused)
: "r" (&MDCNFG), "r" (&PPCR), "0" (sd.mdcnfg), "r" (sd.mdrefr), "r" (sd.mdcas[0]), "r" (sd.mdcas[1]), "r" (sd.mdcas[2]), "r" (ppcr));
local_irq_restore(flags);
/* * Now, return the SDRAM refresh back to normal.
*/
sdram_update_refresh(sa11x0_freq_table[ppcr].frequency, sdram);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.