cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

sa1110-cpufreq.c (9028B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 *  linux/arch/arm/mach-sa1100/cpu-sa1110.c
      4 *
      5 *  Copyright (C) 2001 Russell King
      6 *
      7 * Note: there are two erratas that apply to the SA1110 here:
      8 *  7 - SDRAM auto-power-up failure (rev A0)
      9 * 13 - Corruption of internal register reads/writes following
     10 *      SDRAM reads (rev A0, B0, B1)
     11 *
     12 * We ignore rev. A0 and B0 devices; I don't think they're worth supporting.
     13 *
     14 * The SDRAM type can be passed on the command line as cpu_sa1110.sdram=type
     15 */
     16#include <linux/cpufreq.h>
     17#include <linux/delay.h>
     18#include <linux/init.h>
     19#include <linux/io.h>
     20#include <linux/kernel.h>
     21#include <linux/moduleparam.h>
     22#include <linux/types.h>
     23
     24#include <asm/cputype.h>
     25#include <asm/mach-types.h>
     26
     27#include <mach/generic.h>
     28#include <mach/hardware.h>
     29
     30#undef DEBUG
     31
     32struct sdram_params {
     33	const char name[20];
     34	u_char  rows;		/* bits				 */
     35	u_char  cas_latency;	/* cycles			 */
     36	u_char  tck;		/* clock cycle time (ns)	 */
     37	u_char  trcd;		/* activate to r/w (ns)		 */
     38	u_char  trp;		/* precharge to activate (ns)	 */
     39	u_char  twr;		/* write recovery time (ns)	 */
     40	u_short refresh;	/* refresh time for array (us)	 */
     41};
     42
     43struct sdram_info {
     44	u_int	mdcnfg;
     45	u_int	mdrefr;
     46	u_int	mdcas[3];
     47};
     48
     49static struct sdram_params sdram_tbl[] __initdata = {
     50	{	/* Toshiba TC59SM716 CL2 */
     51		.name		= "TC59SM716-CL2",
     52		.rows		= 12,
     53		.tck		= 10,
     54		.trcd		= 20,
     55		.trp		= 20,
     56		.twr		= 10,
     57		.refresh	= 64000,
     58		.cas_latency	= 2,
     59	}, {	/* Toshiba TC59SM716 CL3 */
     60		.name		= "TC59SM716-CL3",
     61		.rows		= 12,
     62		.tck		= 8,
     63		.trcd		= 20,
     64		.trp		= 20,
     65		.twr		= 8,
     66		.refresh	= 64000,
     67		.cas_latency	= 3,
     68	}, {	/* Samsung K4S641632D TC75 */
     69		.name		= "K4S641632D",
     70		.rows		= 14,
     71		.tck		= 9,
     72		.trcd		= 27,
     73		.trp		= 20,
     74		.twr		= 9,
     75		.refresh	= 64000,
     76		.cas_latency	= 3,
     77	}, {	/* Samsung K4S281632B-1H */
     78		.name           = "K4S281632B-1H",
     79		.rows		= 12,
     80		.tck		= 10,
     81		.trp		= 20,
     82		.twr		= 10,
     83		.refresh	= 64000,
     84		.cas_latency	= 3,
     85	}, {	/* Samsung KM416S4030CT */
     86		.name		= "KM416S4030CT",
     87		.rows		= 13,
     88		.tck		= 8,
     89		.trcd		= 24,	/* 3 CLKs */
     90		.trp		= 24,	/* 3 CLKs */
     91		.twr		= 16,	/* Trdl: 2 CLKs */
     92		.refresh	= 64000,
     93		.cas_latency	= 3,
     94	}, {	/* Winbond W982516AH75L CL3 */
     95		.name		= "W982516AH75L",
     96		.rows		= 16,
     97		.tck		= 8,
     98		.trcd		= 20,
     99		.trp		= 20,
    100		.twr		= 8,
    101		.refresh	= 64000,
    102		.cas_latency	= 3,
    103	}, {	/* Micron MT48LC8M16A2TG-75 */
    104		.name		= "MT48LC8M16A2TG-75",
    105		.rows		= 12,
    106		.tck		= 8,
    107		.trcd		= 20,
    108		.trp		= 20,
    109		.twr		= 8,
    110		.refresh	= 64000,
    111		.cas_latency	= 3,
    112	},
    113};
    114
    115static struct sdram_params sdram_params;
    116
    117/*
    118 * Given a period in ns and frequency in khz, calculate the number of
    119 * cycles of frequency in period.  Note that we round up to the next
    120 * cycle, even if we are only slightly over.
    121 */
    122static inline u_int ns_to_cycles(u_int ns, u_int khz)
    123{
    124	return (ns * khz + 999999) / 1000000;
    125}
    126
    127/*
    128 * Create the MDCAS register bit pattern.
    129 */
    130static inline void set_mdcas(u_int *mdcas, int delayed, u_int rcd)
    131{
    132	u_int shift;
    133
    134	rcd = 2 * rcd - 1;
    135	shift = delayed + 1 + rcd;
    136
    137	mdcas[0]  = (1 << rcd) - 1;
    138	mdcas[0] |= 0x55555555 << shift;
    139	mdcas[1]  = mdcas[2] = 0x55555555 << (shift & 1);
    140}
    141
    142static void
    143sdram_calculate_timing(struct sdram_info *sd, u_int cpu_khz,
    144		       struct sdram_params *sdram)
    145{
    146	u_int mem_khz, sd_khz, trp, twr;
    147
    148	mem_khz = cpu_khz / 2;
    149	sd_khz = mem_khz;
    150
    151	/*
    152	 * If SDCLK would invalidate the SDRAM timings,
    153	 * run SDCLK at half speed.
    154	 *
    155	 * CPU steppings prior to B2 must either run the memory at
    156	 * half speed or use delayed read latching (errata 13).
    157	 */
    158	if ((ns_to_cycles(sdram->tck, sd_khz) > 1) ||
    159	    (read_cpuid_revision() < ARM_CPU_REV_SA1110_B2 && sd_khz < 62000))
    160		sd_khz /= 2;
    161
    162	sd->mdcnfg = MDCNFG & 0x007f007f;
    163
    164	twr = ns_to_cycles(sdram->twr, mem_khz);
    165
    166	/* trp should always be >1 */
    167	trp = ns_to_cycles(sdram->trp, mem_khz) - 1;
    168	if (trp < 1)
    169		trp = 1;
    170
    171	sd->mdcnfg |= trp << 8;
    172	sd->mdcnfg |= trp << 24;
    173	sd->mdcnfg |= sdram->cas_latency << 12;
    174	sd->mdcnfg |= sdram->cas_latency << 28;
    175	sd->mdcnfg |= twr << 14;
    176	sd->mdcnfg |= twr << 30;
    177
    178	sd->mdrefr = MDREFR & 0xffbffff0;
    179	sd->mdrefr |= 7;
    180
    181	if (sd_khz != mem_khz)
    182		sd->mdrefr |= MDREFR_K1DB2;
    183
    184	/* initial number of '1's in MDCAS + 1 */
    185	set_mdcas(sd->mdcas, sd_khz >= 62000,
    186		ns_to_cycles(sdram->trcd, mem_khz));
    187
    188#ifdef DEBUG
    189	printk(KERN_DEBUG "MDCNFG: %08x MDREFR: %08x MDCAS0: %08x MDCAS1: %08x MDCAS2: %08x\n",
    190		sd->mdcnfg, sd->mdrefr, sd->mdcas[0], sd->mdcas[1],
    191		sd->mdcas[2]);
    192#endif
    193}
    194
    195/*
    196 * Set the SDRAM refresh rate.
    197 */
    198static inline void sdram_set_refresh(u_int dri)
    199{
    200	MDREFR = (MDREFR & 0xffff000f) | (dri << 4);
    201	(void) MDREFR;
    202}
    203
    204/*
    205 * Update the refresh period.  We do this such that we always refresh
    206 * the SDRAMs within their permissible period.  The refresh period is
    207 * always a multiple of the memory clock (fixed at cpu_clock / 2).
    208 *
    209 * FIXME: we don't currently take account of burst accesses here,
    210 * but neither do Intels DM nor Angel.
    211 */
    212static void
    213sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram)
    214{
    215	u_int ns_row = (sdram->refresh * 1000) >> sdram->rows;
    216	u_int dri = ns_to_cycles(ns_row, cpu_khz / 2) / 32;
    217
    218#ifdef DEBUG
    219	mdelay(250);
    220	printk(KERN_DEBUG "new dri value = %d\n", dri);
    221#endif
    222
    223	sdram_set_refresh(dri);
    224}
    225
    226/*
    227 * Ok, set the CPU frequency.
    228 */
    229static int sa1110_target(struct cpufreq_policy *policy, unsigned int ppcr)
    230{
    231	struct sdram_params *sdram = &sdram_params;
    232	struct sdram_info sd;
    233	unsigned long flags;
    234	unsigned int unused;
    235
    236	sdram_calculate_timing(&sd, sa11x0_freq_table[ppcr].frequency, sdram);
    237
    238#if 0
    239	/*
    240	 * These values are wrong according to the SA1110 documentation
    241	 * and errata, but they seem to work.  Need to get a storage
    242	 * scope on to the SDRAM signals to work out why.
    243	 */
    244	if (policy->max < 147500) {
    245		sd.mdrefr |= MDREFR_K1DB2;
    246		sd.mdcas[0] = 0xaaaaaa7f;
    247	} else {
    248		sd.mdrefr &= ~MDREFR_K1DB2;
    249		sd.mdcas[0] = 0xaaaaaa9f;
    250	}
    251	sd.mdcas[1] = 0xaaaaaaaa;
    252	sd.mdcas[2] = 0xaaaaaaaa;
    253#endif
    254
    255	/*
    256	 * The clock could be going away for some time.  Set the SDRAMs
    257	 * to refresh rapidly (every 64 memory clock cycles).  To get
    258	 * through the whole array, we need to wait 262144 mclk cycles.
    259	 * We wait 20ms to be safe.
    260	 */
    261	sdram_set_refresh(2);
    262	if (!irqs_disabled())
    263		msleep(20);
    264	else
    265		mdelay(20);
    266
    267	/*
    268	 * Reprogram the DRAM timings with interrupts disabled, and
    269	 * ensure that we are doing this within a complete cache line.
    270	 * This means that we won't access SDRAM for the duration of
    271	 * the programming.
    272	 */
    273	local_irq_save(flags);
    274	asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
    275	udelay(10);
    276	__asm__ __volatile__("\n\
    277		b	2f					\n\
    278		.align	5					\n\
    2791:		str	%3, [%1, #0]		@ MDCNFG	\n\
    280		str	%4, [%1, #28]		@ MDREFR	\n\
    281		str	%5, [%1, #4]		@ MDCAS0	\n\
    282		str	%6, [%1, #8]		@ MDCAS1	\n\
    283		str	%7, [%1, #12]		@ MDCAS2	\n\
    284		str	%8, [%2, #0]		@ PPCR		\n\
    285		ldr	%0, [%1, #0]				\n\
    286		b	3f					\n\
    2872:		b	1b					\n\
    2883:		nop						\n\
    289		nop"
    290		: "=&r" (unused)
    291		: "r" (&MDCNFG), "r" (&PPCR), "0" (sd.mdcnfg),
    292		  "r" (sd.mdrefr), "r" (sd.mdcas[0]),
    293		  "r" (sd.mdcas[1]), "r" (sd.mdcas[2]), "r" (ppcr));
    294	local_irq_restore(flags);
    295
    296	/*
    297	 * Now, return the SDRAM refresh back to normal.
    298	 */
    299	sdram_update_refresh(sa11x0_freq_table[ppcr].frequency, sdram);
    300
    301	return 0;
    302}
    303
    304static int __init sa1110_cpu_init(struct cpufreq_policy *policy)
    305{
    306	cpufreq_generic_init(policy, sa11x0_freq_table, 0);
    307	return 0;
    308}
    309
    310/* sa1110_driver needs __refdata because it must remain after init registers
    311 * it with cpufreq_register_driver() */
    312static struct cpufreq_driver sa1110_driver __refdata = {
    313	.flags		= CPUFREQ_NEED_INITIAL_FREQ_CHECK |
    314			  CPUFREQ_NO_AUTO_DYNAMIC_SWITCHING,
    315	.verify		= cpufreq_generic_frequency_table_verify,
    316	.target_index	= sa1110_target,
    317	.get		= sa11x0_getspeed,
    318	.init		= sa1110_cpu_init,
    319	.name		= "sa1110",
    320};
    321
    322static struct sdram_params *sa1110_find_sdram(const char *name)
    323{
    324	struct sdram_params *sdram;
    325
    326	for (sdram = sdram_tbl; sdram < sdram_tbl + ARRAY_SIZE(sdram_tbl);
    327	     sdram++)
    328		if (strcmp(name, sdram->name) == 0)
    329			return sdram;
    330
    331	return NULL;
    332}
    333
    334static char sdram_name[16];
    335
    336static int __init sa1110_clk_init(void)
    337{
    338	struct sdram_params *sdram;
    339	const char *name = sdram_name;
    340
    341	if (!cpu_is_sa1110())
    342		return -ENODEV;
    343
    344	if (!name[0]) {
    345		if (machine_is_assabet())
    346			name = "TC59SM716-CL3";
    347		if (machine_is_pt_system3())
    348			name = "K4S641632D";
    349		if (machine_is_h3100())
    350			name = "KM416S4030CT";
    351		if (machine_is_jornada720() || machine_is_h3600())
    352			name = "K4S281632B-1H";
    353		if (machine_is_nanoengine())
    354			name = "MT48LC8M16A2TG-75";
    355	}
    356
    357	sdram = sa1110_find_sdram(name);
    358	if (sdram) {
    359		printk(KERN_DEBUG "SDRAM: tck: %d trcd: %d trp: %d"
    360			" twr: %d refresh: %d cas_latency: %d\n",
    361			sdram->tck, sdram->trcd, sdram->trp,
    362			sdram->twr, sdram->refresh, sdram->cas_latency);
    363
    364		memcpy(&sdram_params, sdram, sizeof(sdram_params));
    365
    366		return cpufreq_register_driver(&sa1110_driver);
    367	}
    368
    369	return 0;
    370}
    371
    372module_param_string(sdram, sdram_name, sizeof(sdram_name), 0);
    373arch_initcall(sa1110_clk_init);