1
0
mirror of git://projects.qi-hardware.com/gmenu2x.git synced 2024-11-29 09:09:43 +02:00

Set CPU frequency through sysfs.

No more poking into registers via /dev/mem.
If there is no cpufreq support in the kernel, when trying to change the frequency a message will be printed on stderr that the required sysfs file cannot be opened.
This commit is contained in:
Maarten ter Huurne 2010-07-04 03:04:42 +02:00
parent ac2fa73962
commit 7fb67ba1cc
5 changed files with 30 additions and 5336 deletions

View File

@ -14,7 +14,7 @@ gmenu2x_SOURCES = asfont.cpp button.cpp cpu.cpp dirdialog.cpp filedialog.cpp \
noinst_HEADERS = asfont.h button.h cpu.h dirdialog.h FastDelegate.h \
filedialog.h filelister.h gmenu2x.h gp2x.h iconbutton.h imagedialog.h \
inputdialog.h inputmanager.h jz4740.h linkaction.h linkapp.h link.h \
inputdialog.h inputmanager.h linkaction.h linkapp.h link.h \
menu.h menusettingbool.h menusettingdir.h \
menusettingfile.h menusetting.h menusettingimage.h menusettingint.h \
menusettingmultistring.h menusettingrgba.h menusettingstring.h \

View File

@ -1,98 +1,33 @@
#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#include "cpu.h"
#include "jz4740.h"
inline int sdram_convert(unsigned int pllin,unsigned int *sdram_freq)
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#define SYSFS_CPUFREQ_DIR "/sys/devices/system/cpu/cpu0/cpufreq"
#define SYSFS_CPUFREQ_MAX SYSFS_CPUFREQ_DIR "/scaling_max_freq"
#define SYSFS_CPUFREQ_SET SYSFS_CPUFREQ_DIR "/scaling_setspeed"
void writeStringToFile(const char *path, const char *content)
{
register unsigned int ns, tmp;
ns = 1000000000 / pllin;
/* Set refresh registers */
tmp = SDRAM_TREF/ns;
tmp = tmp/64 + 1;
if (tmp > 0xff) tmp = 0xff;
*sdram_freq = tmp;
return 0;
int fd = open(path, O_RDWR);
if (fd == -1) {
fprintf(stderr, "Failed to open \"%s\": %s\n", path, strerror(errno));
} else {
ssize_t written = write(fd, content, strlen(content));
if (written == -1) {
fprintf(stderr, "Error writing \"%s\": %s\n", path, strerror(errno));
}
close(fd);
}
}
void pll_init(unsigned int clock)
{
register unsigned int cfcr, plcr1;
unsigned int sdramclock = 0;
int n2FR[33] = {
0, 0, 1, 2, 3, 0, 4, 0, 5, 0, 0, 0, 6, 0, 0, 0,
7, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0,
9
};
//int div[5] = {1, 4, 4, 4, 4}; /* divisors of I:S:P:L:M */
int div[5] = {1, 3, 3, 3, 3}; /* divisors of I:S:P:L:M */
int nf, pllout2;
cfcr = CPM_CPCCR_CLKOEN |
(n2FR[div[0]] << CPM_CPCCR_CDIV_BIT) |
(n2FR[div[1]] << CPM_CPCCR_HDIV_BIT) |
(n2FR[div[2]] << CPM_CPCCR_PDIV_BIT) |
(n2FR[div[3]] << CPM_CPCCR_MDIV_BIT) |
(n2FR[div[4]] << CPM_CPCCR_LDIV_BIT);
pllout2 = (cfcr & CPM_CPCCR_PCS) ? clock : (clock / 2);
/* Init UHC clock */
// REG_CPM_UHCCDR = pllout2 / 48000000 - 1;
jz_cpmregl[0x6C>>2] = pllout2 / 48000000 - 1;
nf = clock * 2 / CFG_EXTAL;
plcr1 = ((nf - 2) << CPM_CPPCR_PLLM_BIT) | /* FD */
(0 << CPM_CPPCR_PLLN_BIT) | /* RD=0, NR=2 */
(0 << CPM_CPPCR_PLLOD_BIT) | /* OD=0, NO=1 */
(0x20 << CPM_CPPCR_PLLST_BIT) | /* PLL stable time */
CPM_CPPCR_PLLEN; /* enable PLL */
/* init PLL */
// REG_CPM_CPCCR = cfcr;
// REG_CPM_CPPCR = plcr1;
jz_cpmregl[0] = cfcr;
jz_cpmregl[0x10>>2] = plcr1;
sdram_convert(clock,&sdramclock);
if(sdramclock > 0)
{
// REG_EMC_RTCOR = sdramclock;
// REG_EMC_RTCNT = sdramclock;
jz_emcregs[0x8C>>1] = sdramclock;
jz_emcregs[0x88>>1] = sdramclock;
}else
{
printf("sdram init fail!\n");
while(1) {}
}
}
void jz_cpuspeed(unsigned clockspeed)
{
if (clockspeed >= 200 && clockspeed <= 430)
{
jz_dev = open("/dev/mem", O_RDWR);
if(jz_dev)
{
jz_cpmregl=(unsigned long *)mmap(0, 0x80, PROT_READ|PROT_WRITE, MAP_SHARED, jz_dev, 0x10000000);
jz_emcregl=(unsigned long *)mmap(0, 0x90, PROT_READ|PROT_WRITE, MAP_SHARED, jz_dev, 0x13010000);
jz_emcregs=(unsigned short *)jz_emcregl;
pll_init(clockspeed*1000000);
munmap((void *)jz_cpmregl, 0x80);
munmap((void *)jz_emcregl, 0x90);
close(jz_dev);
}
else
printf("failed opening /dev/mem \n");
}
char freq[10];
sprintf(freq, "%d", clockspeed * 1000);
writeStringToFile(SYSFS_CPUFREQ_MAX, freq);
writeStringToFile(SYSFS_CPUFREQ_SET, freq);
}

View File

@ -1,24 +1,6 @@
#ifndef CPU_H
#define CPU_H
/* Define this to the CPU frequency */
#define CPU_FREQ 336000000 /* CPU clock: 336 MHz */
#define CFG_EXTAL 12000000 /* EXT clock: 12 Mhz */
// SDRAM Timings, unit: ns
#define SDRAM_TRAS 45 /* RAS# Active Time */
#define SDRAM_RCD 20 /* RAS# to CAS# Delay */
#define SDRAM_TPC 20 /* RAS# Precharge Time */
#define SDRAM_TRWL 7 /* Write Latency Time */
#define SDRAM_TREF 15625 /* Refresh period: 4096 refresh cycles/64ms */
//#define SDRAM_TREF 7812 /* Refresh period: 8192 refresh cycles/64ms */
static unsigned long jz_dev;
static volatile unsigned long *jz_cpmregl, *jz_emcregl;
volatile unsigned short *jz_emcregs;
void jz_cpuspeed(unsigned clockspeed);
void pll_init(unsigned int clock);
inline int sdram_convert(unsigned int pllin,unsigned int *sdram_freq);
#endif

View File

@ -526,8 +526,8 @@ void GMenu2X::readConfig() {
if (confStr["skin"].empty() || !fileExists("skins/"+confStr["skin"])) confStr["skin"] = "Default";
evalIntConf( &confInt["outputLogs"], 0, 0,1 );
evalIntConf( &confInt["maxClock"], 430, 200,430 );
evalIntConf( &confInt["menuClock"], 200, 200,430 );
evalIntConf( &confInt["maxClock"], 430, 30, 500 );
evalIntConf( &confInt["menuClock"], 200, 30, 430 );
evalIntConf( &confInt["globalVolume"], 67, 0,100 );
evalIntConf( &confInt["backlight"], 100, 5,100 );
evalIntConf( &confInt["videoBpp"], 32,32,32 ); // 8,16
@ -1799,20 +1799,9 @@ void GMenu2X::applyDefaultTimings() {
void GMenu2X::setClock(unsigned mhz) {
mhz = constrain(mhz,200,confInt["maxClock"]);
mhz = constrain(mhz, 30, confInt["maxClock"]);
#ifdef TARGET_GP2X
/* if (gp2x_mem!=0) {
unsigned v;
unsigned mdiv,pdiv=3,scale=0;
mhz*=1000000;
mdiv=(mhz*pdiv)/GP2X_CLK_FREQ;
mdiv=((mdiv-8)<<8) & 0xff00;
pdiv=((pdiv-2)<<2) & 0xfc;
scale&=3;
v=mdiv | pdiv | scale;
MEM_REG[0x910>>1]=v;
}*/
/*jz_cpuspeed(mhz);*/
jz_cpuspeed(mhz);
#endif
}

File diff suppressed because it is too large Load Diff