1 // SPDX-License-Identifier: GPL-2.0 2 // 3 // Copyright (c) 2009 Simtec Electronics 4 // http://armlinux.simtec.co.uk/ 5 // Ben Dooks <ben@simtec.co.uk> 6 // 7 // S3C24XX CPU Frequency scaling - utils for S3C2410/S3C2440/S3C2442 8 9 #include <linux/kernel.h> 10 #include <linux/errno.h> 11 #include <linux/cpufreq.h> 12 #include <linux/io.h> 13 #include <linux/clk.h> 14 15 #include "map.h" 16 #include "regs-clock.h" 17 18 #include <linux/soc/samsung/s3c-cpufreq-core.h> 19 20 #include "regs-mem-s3c24xx.h" 21 22 /** 23 * s3c2410_cpufreq_setrefresh - set SDRAM refresh value 24 * @cfg: The frequency configuration 25 * 26 * Set the SDRAM refresh value appropriately for the configured 27 * frequency. 28 */ s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config * cfg)29void s3c2410_cpufreq_setrefresh(struct s3c_cpufreq_config *cfg) 30 { 31 struct s3c_cpufreq_board *board = cfg->board; 32 unsigned long refresh; 33 unsigned long refval; 34 35 /* Reduce both the refresh time (in ns) and the frequency (in MHz) 36 * down to ensure that we do not overflow 32 bit numbers. 37 * 38 * This should work for HCLK up to 133MHz and refresh period up 39 * to 30usec. 40 */ 41 42 refresh = (cfg->freq.hclk / 100) * (board->refresh / 10); 43 refresh = DIV_ROUND_UP(refresh, (1000 * 1000)); /* apply scale */ 44 refresh = (1 << 11) + 1 - refresh; 45 46 s3c_freq_dbg("%s: refresh value %lu\n", __func__, refresh); 47 48 refval = __raw_readl(S3C2410_REFRESH); 49 refval &= ~((1 << 12) - 1); 50 refval |= refresh; 51 __raw_writel(refval, S3C2410_REFRESH); 52 } 53 54 /** 55 * s3c2410_set_fvco - set the PLL value 56 * @cfg: The frequency configuration 57 */ s3c2410_set_fvco(struct s3c_cpufreq_config * cfg)58void s3c2410_set_fvco(struct s3c_cpufreq_config *cfg) 59 { 60 if (!IS_ERR(cfg->mpll)) 61 clk_set_rate(cfg->mpll, cfg->pll.frequency); 62 } 63 64 #if defined(CONFIG_CPU_S3C2440) || defined(CONFIG_CPU_S3C2442) s3c2440_read_camdivn(void)65u32 s3c2440_read_camdivn(void) 66 { 67 return __raw_readl(S3C2440_CAMDIVN); 68 } 69 s3c2440_write_camdivn(u32 camdiv)70void s3c2440_write_camdivn(u32 camdiv) 71 { 72 __raw_writel(camdiv, S3C2440_CAMDIVN); 73 } 74 #endif 75 s3c24xx_read_clkdivn(void)76u32 s3c24xx_read_clkdivn(void) 77 { 78 return __raw_readl(S3C2410_CLKDIVN); 79 } 80 s3c24xx_write_clkdivn(u32 clkdiv)81void s3c24xx_write_clkdivn(u32 clkdiv) 82 { 83 __raw_writel(clkdiv, S3C2410_CLKDIVN); 84 } 85 s3c24xx_read_mpllcon(void)86u32 s3c24xx_read_mpllcon(void) 87 { 88 return __raw_readl(S3C2410_MPLLCON); 89 } 90 s3c24xx_write_locktime(u32 locktime)91void s3c24xx_write_locktime(u32 locktime) 92 { 93 return __raw_writel(locktime, S3C2410_LOCKTIME); 94 } 95