Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  linux/arch/arm/mach-sa1100/cpu-sa1110.c
0004  *
0005  *  Copyright (C) 2001 Russell King
0006  *
0007  * Note: there are two erratas that apply to the SA1110 here:
0008  *  7 - SDRAM auto-power-up failure (rev A0)
0009  * 13 - Corruption of internal register reads/writes following
0010  *      SDRAM reads (rev A0, B0, B1)
0011  *
0012  * We ignore rev. A0 and B0 devices; I don't think they're worth supporting.
0013  *
0014  * The SDRAM type can be passed on the command line as cpu_sa1110.sdram=type
0015  */
0016 #include <linux/cpufreq.h>
0017 #include <linux/delay.h>
0018 #include <linux/init.h>
0019 #include <linux/io.h>
0020 #include <linux/kernel.h>
0021 #include <linux/moduleparam.h>
0022 #include <linux/types.h>
0023 
0024 #include <asm/cputype.h>
0025 #include <asm/mach-types.h>
0026 
0027 #include <mach/generic.h>
0028 #include <mach/hardware.h>
0029 
0030 #undef DEBUG
0031 
0032 struct sdram_params {
0033     const char name[20];
0034     u_char  rows;       /* bits              */
0035     u_char  cas_latency;    /* cycles            */
0036     u_char  tck;        /* clock cycle time (ns)     */
0037     u_char  trcd;       /* activate to r/w (ns)      */
0038     u_char  trp;        /* precharge to activate (ns)    */
0039     u_char  twr;        /* write recovery time (ns)  */
0040     u_short refresh;    /* refresh time for array (us)   */
0041 };
0042 
0043 struct sdram_info {
0044     u_int   mdcnfg;
0045     u_int   mdrefr;
0046     u_int   mdcas[3];
0047 };
0048 
0049 static struct sdram_params sdram_tbl[] __initdata = {
0050     {   /* Toshiba TC59SM716 CL2 */
0051         .name       = "TC59SM716-CL2",
0052         .rows       = 12,
0053         .tck        = 10,
0054         .trcd       = 20,
0055         .trp        = 20,
0056         .twr        = 10,
0057         .refresh    = 64000,
0058         .cas_latency    = 2,
0059     }, {    /* Toshiba TC59SM716 CL3 */
0060         .name       = "TC59SM716-CL3",
0061         .rows       = 12,
0062         .tck        = 8,
0063         .trcd       = 20,
0064         .trp        = 20,
0065         .twr        = 8,
0066         .refresh    = 64000,
0067         .cas_latency    = 3,
0068     }, {    /* Samsung K4S641632D TC75 */
0069         .name       = "K4S641632D",
0070         .rows       = 14,
0071         .tck        = 9,
0072         .trcd       = 27,
0073         .trp        = 20,
0074         .twr        = 9,
0075         .refresh    = 64000,
0076         .cas_latency    = 3,
0077     }, {    /* Samsung K4S281632B-1H */
0078         .name           = "K4S281632B-1H",
0079         .rows       = 12,
0080         .tck        = 10,
0081         .trp        = 20,
0082         .twr        = 10,
0083         .refresh    = 64000,
0084         .cas_latency    = 3,
0085     }, {    /* Samsung KM416S4030CT */
0086         .name       = "KM416S4030CT",
0087         .rows       = 13,
0088         .tck        = 8,
0089         .trcd       = 24,   /* 3 CLKs */
0090         .trp        = 24,   /* 3 CLKs */
0091         .twr        = 16,   /* Trdl: 2 CLKs */
0092         .refresh    = 64000,
0093         .cas_latency    = 3,
0094     }, {    /* Winbond W982516AH75L CL3 */
0095         .name       = "W982516AH75L",
0096         .rows       = 16,
0097         .tck        = 8,
0098         .trcd       = 20,
0099         .trp        = 20,
0100         .twr        = 8,
0101         .refresh    = 64000,
0102         .cas_latency    = 3,
0103     }, {    /* Micron MT48LC8M16A2TG-75 */
0104         .name       = "MT48LC8M16A2TG-75",
0105         .rows       = 12,
0106         .tck        = 8,
0107         .trcd       = 20,
0108         .trp        = 20,
0109         .twr        = 8,
0110         .refresh    = 64000,
0111         .cas_latency    = 3,
0112     },
0113 };
0114 
0115 static struct sdram_params sdram_params;
0116 
0117 /*
0118  * Given a period in ns and frequency in khz, calculate the number of
0119  * cycles of frequency in period.  Note that we round up to the next
0120  * cycle, even if we are only slightly over.
0121  */
0122 static inline u_int ns_to_cycles(u_int ns, u_int khz)
0123 {
0124     return (ns * khz + 999999) / 1000000;
0125 }
0126 
0127 /*
0128  * Create the MDCAS register bit pattern.
0129  */
0130 static inline void set_mdcas(u_int *mdcas, int delayed, u_int rcd)
0131 {
0132     u_int shift;
0133 
0134     rcd = 2 * rcd - 1;
0135     shift = delayed + 1 + rcd;
0136 
0137     mdcas[0]  = (1 << rcd) - 1;
0138     mdcas[0] |= 0x55555555 << shift;
0139     mdcas[1]  = mdcas[2] = 0x55555555 << (shift & 1);
0140 }
0141 
0142 static void
0143 sdram_calculate_timing(struct sdram_info *sd, u_int cpu_khz,
0144                struct sdram_params *sdram)
0145 {
0146     u_int mem_khz, sd_khz, trp, twr;
0147 
0148     mem_khz = cpu_khz / 2;
0149     sd_khz = mem_khz;
0150 
0151     /*
0152      * If SDCLK would invalidate the SDRAM timings,
0153      * run SDCLK at half speed.
0154      *
0155      * CPU steppings prior to B2 must either run the memory at
0156      * half speed or use delayed read latching (errata 13).
0157      */
0158     if ((ns_to_cycles(sdram->tck, sd_khz) > 1) ||
0159         (read_cpuid_revision() < ARM_CPU_REV_SA1110_B2 && sd_khz < 62000))
0160         sd_khz /= 2;
0161 
0162     sd->mdcnfg = MDCNFG & 0x007f007f;
0163 
0164     twr = ns_to_cycles(sdram->twr, mem_khz);
0165 
0166     /* trp should always be >1 */
0167     trp = ns_to_cycles(sdram->trp, mem_khz) - 1;
0168     if (trp < 1)
0169         trp = 1;
0170 
0171     sd->mdcnfg |= trp << 8;
0172     sd->mdcnfg |= trp << 24;
0173     sd->mdcnfg |= sdram->cas_latency << 12;
0174     sd->mdcnfg |= sdram->cas_latency << 28;
0175     sd->mdcnfg |= twr << 14;
0176     sd->mdcnfg |= twr << 30;
0177 
0178     sd->mdrefr = MDREFR & 0xffbffff0;
0179     sd->mdrefr |= 7;
0180 
0181     if (sd_khz != mem_khz)
0182         sd->mdrefr |= MDREFR_K1DB2;
0183 
0184     /* initial number of '1's in MDCAS + 1 */
0185     set_mdcas(sd->mdcas, sd_khz >= 62000,
0186         ns_to_cycles(sdram->trcd, mem_khz));
0187 
0188 #ifdef DEBUG
0189     printk(KERN_DEBUG "MDCNFG: %08x MDREFR: %08x MDCAS0: %08x MDCAS1: %08x MDCAS2: %08x\n",
0190         sd->mdcnfg, sd->mdrefr, sd->mdcas[0], sd->mdcas[1],
0191         sd->mdcas[2]);
0192 #endif
0193 }
0194 
0195 /*
0196  * Set the SDRAM refresh rate.
0197  */
0198 static inline void sdram_set_refresh(u_int dri)
0199 {
0200     MDREFR = (MDREFR & 0xffff000f) | (dri << 4);
0201     (void) MDREFR;
0202 }
0203 
0204 /*
0205  * Update the refresh period.  We do this such that we always refresh
0206  * the SDRAMs within their permissible period.  The refresh period is
0207  * always a multiple of the memory clock (fixed at cpu_clock / 2).
0208  *
0209  * FIXME: we don't currently take account of burst accesses here,
0210  * but neither do Intels DM nor Angel.
0211  */
0212 static void
0213 sdram_update_refresh(u_int cpu_khz, struct sdram_params *sdram)
0214 {
0215     u_int ns_row = (sdram->refresh * 1000) >> sdram->rows;
0216     u_int dri = ns_to_cycles(ns_row, cpu_khz / 2) / 32;
0217 
0218 #ifdef DEBUG
0219     mdelay(250);
0220     printk(KERN_DEBUG "new dri value = %d\n", dri);
0221 #endif
0222 
0223     sdram_set_refresh(dri);
0224 }
0225 
0226 /*
0227  * Ok, set the CPU frequency.
0228  */
0229 static int sa1110_target(struct cpufreq_policy *policy, unsigned int ppcr)
0230 {
0231     struct sdram_params *sdram = &sdram_params;
0232     struct sdram_info sd;
0233     unsigned long flags;
0234     unsigned int unused;
0235 
0236     sdram_calculate_timing(&sd, sa11x0_freq_table[ppcr].frequency, sdram);
0237 
0238 #if 0
0239     /*
0240      * These values are wrong according to the SA1110 documentation
0241      * and errata, but they seem to work.  Need to get a storage
0242      * scope on to the SDRAM signals to work out why.
0243      */
0244     if (policy->max < 147500) {
0245         sd.mdrefr |= MDREFR_K1DB2;
0246         sd.mdcas[0] = 0xaaaaaa7f;
0247     } else {
0248         sd.mdrefr &= ~MDREFR_K1DB2;
0249         sd.mdcas[0] = 0xaaaaaa9f;
0250     }
0251     sd.mdcas[1] = 0xaaaaaaaa;
0252     sd.mdcas[2] = 0xaaaaaaaa;
0253 #endif
0254 
0255     /*
0256      * The clock could be going away for some time.  Set the SDRAMs
0257      * to refresh rapidly (every 64 memory clock cycles).  To get
0258      * through the whole array, we need to wait 262144 mclk cycles.
0259      * We wait 20ms to be safe.
0260      */
0261     sdram_set_refresh(2);
0262     if (!irqs_disabled())
0263         msleep(20);
0264     else
0265         mdelay(20);
0266 
0267     /*
0268      * Reprogram the DRAM timings with interrupts disabled, and
0269      * ensure that we are doing this within a complete cache line.
0270      * This means that we won't access SDRAM for the duration of
0271      * the programming.
0272      */
0273     local_irq_save(flags);
0274     asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (0));
0275     udelay(10);
0276     __asm__ __volatile__("\n\
0277         b   2f                  \n\
0278         .align  5                   \n\
0279 1:      str %3, [%1, #0]        @ MDCNFG    \n\
0280         str %4, [%1, #28]       @ MDREFR    \n\
0281         str %5, [%1, #4]        @ MDCAS0    \n\
0282         str %6, [%1, #8]        @ MDCAS1    \n\
0283         str %7, [%1, #12]       @ MDCAS2    \n\
0284         str %8, [%2, #0]        @ PPCR      \n\
0285         ldr %0, [%1, #0]                \n\
0286         b   3f                  \n\
0287 2:      b   1b                  \n\
0288 3:      nop                     \n\
0289         nop"
0290         : "=&r" (unused)
0291         : "r" (&MDCNFG), "r" (&PPCR), "0" (sd.mdcnfg),
0292           "r" (sd.mdrefr), "r" (sd.mdcas[0]),
0293           "r" (sd.mdcas[1]), "r" (sd.mdcas[2]), "r" (ppcr));
0294     local_irq_restore(flags);
0295 
0296     /*
0297      * Now, return the SDRAM refresh back to normal.
0298      */
0299     sdram_update_refresh(sa11x0_freq_table[ppcr].frequency, sdram);
0300 
0301     return 0;
0302 }
0303 
0304 static int __init sa1110_cpu_init(struct cpufreq_policy *policy)
0305 {
0306     cpufreq_generic_init(policy, sa11x0_freq_table, 0);
0307     return 0;
0308 }
0309 
0310 /* sa1110_driver needs __refdata because it must remain after init registers
0311  * it with cpufreq_register_driver() */
0312 static struct cpufreq_driver sa1110_driver __refdata = {
0313     .flags      = CPUFREQ_NEED_INITIAL_FREQ_CHECK |
0314               CPUFREQ_NO_AUTO_DYNAMIC_SWITCHING,
0315     .verify     = cpufreq_generic_frequency_table_verify,
0316     .target_index   = sa1110_target,
0317     .get        = sa11x0_getspeed,
0318     .init       = sa1110_cpu_init,
0319     .name       = "sa1110",
0320 };
0321 
0322 static struct sdram_params *sa1110_find_sdram(const char *name)
0323 {
0324     struct sdram_params *sdram;
0325 
0326     for (sdram = sdram_tbl; sdram < sdram_tbl + ARRAY_SIZE(sdram_tbl);
0327          sdram++)
0328         if (strcmp(name, sdram->name) == 0)
0329             return sdram;
0330 
0331     return NULL;
0332 }
0333 
0334 static char sdram_name[16];
0335 
0336 static int __init sa1110_clk_init(void)
0337 {
0338     struct sdram_params *sdram;
0339     const char *name = sdram_name;
0340 
0341     if (!cpu_is_sa1110())
0342         return -ENODEV;
0343 
0344     if (!name[0]) {
0345         if (machine_is_assabet())
0346             name = "TC59SM716-CL3";
0347         if (machine_is_pt_system3())
0348             name = "K4S641632D";
0349         if (machine_is_h3100())
0350             name = "KM416S4030CT";
0351         if (machine_is_jornada720() || machine_is_h3600())
0352             name = "K4S281632B-1H";
0353         if (machine_is_nanoengine())
0354             name = "MT48LC8M16A2TG-75";
0355     }
0356 
0357     sdram = sa1110_find_sdram(name);
0358     if (sdram) {
0359         printk(KERN_DEBUG "SDRAM: tck: %d trcd: %d trp: %d"
0360             " twr: %d refresh: %d cas_latency: %d\n",
0361             sdram->tck, sdram->trcd, sdram->trp,
0362             sdram->twr, sdram->refresh, sdram->cas_latency);
0363 
0364         memcpy(&sdram_params, sdram, sizeof(sdram_params));
0365 
0366         return cpufreq_register_driver(&sa1110_driver);
0367     }
0368 
0369     return 0;
0370 }
0371 
0372 module_param_string(sdram, sdram_name, sizeof(sdram_name), 0);
0373 arch_initcall(sa1110_clk_init);