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:
parent
ac2fa73962
commit
7fb67ba1cc
@ -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 \
|
||||
|
115
src/cpu.cpp
115
src/cpu.cpp
@ -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);
|
||||
}
|
||||
|
18
src/cpu.h
18
src/cpu.h
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
5212
src/jz4740.h
5212
src/jz4740.h
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user