Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 /*
0003  * Copyright (c) 2006-2009 Simtec Electronics
0004  *  http://armlinux.simtec.co.uk/
0005  *  Ben Dooks <ben@simtec.co.uk>
0006  *
0007  * S3C CPU frequency scaling support - core support
0008  */
0009 #ifndef __LINUX_SOC_SAMSUNG_S3C_CPUFREQ_CORE_H
0010 #define __LINUX_SOC_SAMSUNG_S3C_CPUFREQ_CORE_H
0011 
0012 #include <linux/soc/samsung/s3c-cpu-freq.h>
0013 
0014 struct seq_file;
0015 
0016 #define MAX_BANKS (8)
0017 #define S3C2412_MAX_IO  (8)
0018 
0019 /**
0020  * struct s3c2410_iobank_timing - IO bank timings for S3C2410 style timings
0021  * @bankcon: The cached version of settings in this structure.
0022  * @tacp:
0023  * @tacs: Time from address valid to nCS asserted.
0024  * @tcos: Time from nCS asserted to nOE or nWE asserted.
0025  * @tacc: Time that nOE or nWE is asserted.
0026  * @tcoh: Time nCS is held after nOE or nWE are released.
0027  * @tcah: Time address is held for after
0028  * @nwait_en: Whether nWAIT is enabled for this bank.
0029  *
0030  * This structure represents the IO timings for a S3C2410 style IO bank
0031  * used by the CPU frequency support if it needs to change the settings
0032  * of the IO.
0033  */
0034 struct s3c2410_iobank_timing {
0035     unsigned long   bankcon;
0036     unsigned int    tacp;
0037     unsigned int    tacs;
0038     unsigned int    tcos;
0039     unsigned int    tacc;
0040     unsigned int    tcoh;       /* nCS hold after nOE/nWE */
0041     unsigned int    tcah;       /* Address hold after nCS */
0042     unsigned char   nwait_en;   /* nWait enabled for bank. */
0043 };
0044 
0045 /**
0046  * struct s3c2412_iobank_timing - io timings for PL092 (S3C2412) style IO
0047  * @idcy: The idle cycle time between transactions.
0048  * @wstrd: nCS release to end of read cycle.
0049  * @wstwr: nCS release to end of write cycle.
0050  * @wstoen: nCS assertion to nOE assertion time.
0051  * @wstwen: nCS assertion to nWE assertion time.
0052  * @wstbrd: Burst ready delay.
0053  * @smbidcyr: Register cache for smbidcyr value.
0054  * @smbwstrd: Register cache for smbwstrd value.
0055  * @smbwstwr: Register cache for smbwstwr value.
0056  * @smbwstoen: Register cache for smbwstoen value.
0057  * @smbwstwen: Register cache for smbwstwen value.
0058  * @smbwstbrd: Register cache for smbwstbrd value.
0059  *
0060  * Timing information for a IO bank on an S3C2412 or similar system which
0061  * uses a PL093 block.
0062  */
0063 struct s3c2412_iobank_timing {
0064     unsigned int    idcy;
0065     unsigned int    wstrd;
0066     unsigned int    wstwr;
0067     unsigned int    wstoen;
0068     unsigned int    wstwen;
0069     unsigned int    wstbrd;
0070 
0071     /* register cache */
0072     unsigned char   smbidcyr;
0073     unsigned char   smbwstrd;
0074     unsigned char   smbwstwr;
0075     unsigned char   smbwstoen;
0076     unsigned char   smbwstwen;
0077     unsigned char   smbwstbrd;
0078 };
0079 
0080 union s3c_iobank {
0081     struct s3c2410_iobank_timing    *io_2410;
0082     struct s3c2412_iobank_timing    *io_2412;
0083 };
0084 
0085 /**
0086  * struct s3c_iotimings - Chip IO timings holder
0087  * @bank: The timings for each IO bank.
0088  */
0089 struct s3c_iotimings {
0090     union s3c_iobank    bank[MAX_BANKS];
0091 };
0092 
0093 /**
0094  * struct s3c_plltab - PLL table information.
0095  * @vals: List of PLL values.
0096  * @size: Size of the PLL table @vals.
0097  */
0098 struct s3c_plltab {
0099     struct s3c_pllval   *vals;
0100     int          size;
0101 };
0102 
0103 /**
0104  * struct s3c_cpufreq_config - current cpu frequency configuration
0105  * @freq: The current settings for the core clocks.
0106  * @max: Maxium settings, derived from core, board and user settings.
0107  * @pll: The PLL table entry for the current PLL settings.
0108  * @divs: The divisor settings for the core clocks.
0109  * @info: The current core driver information.
0110  * @board: The information for the board we are running on.
0111  * @lock_pll: Set if the PLL settings cannot be changed.
0112  *
0113  * This is for the core drivers that need to know information about
0114  * the current settings and values. It should not be needed by any
0115  * device drivers.
0116 */
0117 struct s3c_cpufreq_config {
0118     struct s3c_freq     freq;
0119     struct s3c_freq     max;
0120     struct clk      *mpll;
0121     struct cpufreq_frequency_table pll;
0122     struct s3c_clkdivs  divs;
0123     struct s3c_cpufreq_info *info;  /* for core, not drivers */
0124     struct s3c_cpufreq_board *board;
0125 
0126     unsigned int    lock_pll:1;
0127 };
0128 
0129 /**
0130  * struct s3c_cpufreq_info - Information for the CPU frequency driver.
0131  * @name: The name of this implementation.
0132  * @max: The maximum frequencies for the system.
0133  * @latency: Transition latency to give to cpufreq.
0134  * @locktime_m: The lock-time in uS for the MPLL.
0135  * @locktime_u: The lock-time in uS for the UPLL.
0136  * @locttime_bits: The number of bits each LOCKTIME field.
0137  * @need_pll: Set if this driver needs to change the PLL values to achieve
0138  *  any frequency changes. This is really only need by devices like the
0139  *  S3C2410 where there is no or limited divider between the PLL and the
0140  *  ARMCLK.
0141  * @get_iotiming: Get the current IO timing data, mainly for use at start.
0142  * @set_iotiming: Update the IO timings from the cached copies calculated
0143  *  from the @calc_iotiming entry when changing the frequency.
0144  * @calc_iotiming: Calculate and update the cached copies of the IO timings
0145  *  from the newly calculated frequencies.
0146  * @calc_freqtable: Calculate (fill in) the given frequency table from the
0147  *  current frequency configuration. If the table passed in is NULL,
0148  *  then the return is the number of elements to be filled for allocation
0149  *  of the table.
0150  * @set_refresh: Set the memory refresh configuration.
0151  * @set_fvco: Set the PLL frequencies.
0152  * @set_divs: Update the clock divisors.
0153  * @calc_divs: Calculate the clock divisors.
0154  */
0155 struct s3c_cpufreq_info {
0156     const char      *name;
0157     struct s3c_freq     max;
0158 
0159     unsigned int        latency;
0160 
0161     unsigned int        locktime_m;
0162     unsigned int        locktime_u;
0163     unsigned char       locktime_bits;
0164 
0165     unsigned int        need_pll:1;
0166 
0167     /* driver routines */
0168 
0169     int     (*get_iotiming)(struct s3c_cpufreq_config *cfg,
0170                     struct s3c_iotimings *timings);
0171 
0172     void        (*set_iotiming)(struct s3c_cpufreq_config *cfg,
0173                     struct s3c_iotimings *timings);
0174 
0175     int     (*calc_iotiming)(struct s3c_cpufreq_config *cfg,
0176                      struct s3c_iotimings *timings);
0177 
0178     int     (*calc_freqtable)(struct s3c_cpufreq_config *cfg,
0179                       struct cpufreq_frequency_table *t,
0180                       size_t table_size);
0181 
0182     void        (*debug_io_show)(struct seq_file *seq,
0183                      struct s3c_cpufreq_config *cfg,
0184                      union s3c_iobank *iob);
0185 
0186     void        (*set_refresh)(struct s3c_cpufreq_config *cfg);
0187     void        (*set_fvco)(struct s3c_cpufreq_config *cfg);
0188     void        (*set_divs)(struct s3c_cpufreq_config *cfg);
0189     int     (*calc_divs)(struct s3c_cpufreq_config *cfg);
0190 };
0191 
0192 extern int s3c_cpufreq_register(struct s3c_cpufreq_info *info);
0193 
0194 extern int s3c_plltab_register(struct cpufreq_frequency_table *plls,
0195                    unsigned int plls_no);
0196 
0197 /* exports and utilities for debugfs */
0198 extern struct s3c_cpufreq_config *s3c_cpufreq_getconfig(void);
0199 extern struct s3c_iotimings *s3c_cpufreq_getiotimings(void);
0200 
0201 #ifdef CONFIG_ARM_S3C24XX_CPUFREQ_DEBUGFS
0202 #define s3c_cpufreq_debugfs_call(x) x
0203 #else
0204 #define s3c_cpufreq_debugfs_call(x) NULL
0205 #endif
0206 
0207 /* Useful utility functions. */
0208 
0209 extern struct clk *s3c_cpufreq_clk_get(struct device *, const char *);
0210 
0211 /* S3C2410 and compatible exported functions */
0212 
0213 extern void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg);
0214 extern void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg);
0215 
0216 #ifdef CONFIG_S3C2410_IOTIMING
0217 extern void s3c2410_iotiming_debugfs(struct seq_file *seq,
0218                      struct s3c_cpufreq_config *cfg,
0219                      union s3c_iobank *iob);
0220 
0221 extern int s3c2410_iotiming_calc(struct s3c_cpufreq_config *cfg,
0222                  struct s3c_iotimings *iot);
0223 
0224 extern int s3c2410_iotiming_get(struct s3c_cpufreq_config *cfg,
0225                 struct s3c_iotimings *timings);
0226 
0227 extern void s3c2410_iotiming_set(struct s3c_cpufreq_config *cfg,
0228                  struct s3c_iotimings *iot);
0229 #else
0230 #define s3c2410_iotiming_debugfs NULL
0231 #define s3c2410_iotiming_calc NULL
0232 #define s3c2410_iotiming_get NULL
0233 #define s3c2410_iotiming_set NULL
0234 #endif /* CONFIG_S3C2410_IOTIMING */
0235 
0236 /* S3C2412 compatible routines */
0237 
0238 #ifdef CONFIG_S3C2412_IOTIMING
0239 extern void s3c2412_iotiming_debugfs(struct seq_file *seq,
0240                      struct s3c_cpufreq_config *cfg,
0241                      union s3c_iobank *iob);
0242 
0243 extern int s3c2412_iotiming_get(struct s3c_cpufreq_config *cfg,
0244                 struct s3c_iotimings *timings);
0245 
0246 extern int s3c2412_iotiming_calc(struct s3c_cpufreq_config *cfg,
0247                  struct s3c_iotimings *iot);
0248 
0249 extern void s3c2412_iotiming_set(struct s3c_cpufreq_config *cfg,
0250                  struct s3c_iotimings *iot);
0251 extern void s3c2412_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg);
0252 #else
0253 #define s3c2412_iotiming_debugfs NULL
0254 #define s3c2412_iotiming_calc NULL
0255 #define s3c2412_iotiming_get NULL
0256 #define s3c2412_iotiming_set NULL
0257 #endif /* CONFIG_S3C2412_IOTIMING */
0258 
0259 #ifdef CONFIG_ARM_S3C24XX_CPUFREQ_DEBUG
0260 #define s3c_freq_dbg(x...) printk(KERN_INFO x)
0261 #else
0262 #define s3c_freq_dbg(x...) do { if (0) printk(x); } while (0)
0263 #endif /* CONFIG_ARM_S3C24XX_CPUFREQ_DEBUG */
0264 
0265 #ifdef CONFIG_ARM_S3C24XX_CPUFREQ_IODEBUG
0266 #define s3c_freq_iodbg(x...) printk(KERN_INFO x)
0267 #else
0268 #define s3c_freq_iodbg(x...) do { if (0) printk(x); } while (0)
0269 #endif /* CONFIG_ARM_S3C24XX_CPUFREQ_IODEBUG */
0270 
0271 static inline int s3c_cpufreq_addfreq(struct cpufreq_frequency_table *table,
0272                       int index, size_t table_size,
0273                       unsigned int freq)
0274 {
0275     if (index < 0)
0276         return index;
0277 
0278     if (table) {
0279         if (index >= table_size)
0280             return -ENOMEM;
0281 
0282         s3c_freq_dbg("%s: { %d = %u kHz }\n",
0283                  __func__, index, freq);
0284 
0285         table[index].driver_data = index;
0286         table[index].frequency = freq;
0287     }
0288 
0289     return index + 1;
0290 }
0291 
0292 u32 s3c2440_read_camdivn(void);
0293 void s3c2440_write_camdivn(u32 camdiv);
0294 u32 s3c24xx_read_clkdivn(void);
0295 void s3c24xx_write_clkdivn(u32 clkdiv);
0296 u32 s3c24xx_read_mpllcon(void);
0297 void s3c24xx_write_locktime(u32 locktime);
0298 
0299 #endif