mirror of
git://projects.qi-hardware.com/gmenu2x.git
synced 2024-11-25 20:21:52 +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 \
|
noinst_HEADERS = asfont.h button.h cpu.h dirdialog.h FastDelegate.h \
|
||||||
filedialog.h filelister.h gmenu2x.h gp2x.h iconbutton.h imagedialog.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 \
|
menu.h menusettingbool.h menusettingdir.h \
|
||||||
menusettingfile.h menusetting.h menusettingimage.h menusettingint.h \
|
menusettingfile.h menusetting.h menusettingimage.h menusettingint.h \
|
||||||
menusettingmultistring.h menusettingrgba.h menusettingstring.h \
|
menusettingmultistring.h menusettingrgba.h menusettingstring.h \
|
||||||
|
111
src/cpu.cpp
111
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 "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;
|
int fd = open(path, O_RDWR);
|
||||||
|
if (fd == -1) {
|
||||||
ns = 1000000000 / pllin;
|
fprintf(stderr, "Failed to open \"%s\": %s\n", path, strerror(errno));
|
||||||
/* Set refresh registers */
|
} else {
|
||||||
tmp = SDRAM_TREF/ns;
|
ssize_t written = write(fd, content, strlen(content));
|
||||||
tmp = tmp/64 + 1;
|
if (written == -1) {
|
||||||
if (tmp > 0xff) tmp = 0xff;
|
fprintf(stderr, "Error writing \"%s\": %s\n", path, strerror(errno));
|
||||||
*sdram_freq = tmp;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
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)
|
void jz_cpuspeed(unsigned clockspeed)
|
||||||
{
|
{
|
||||||
if (clockspeed >= 200 && clockspeed <= 430)
|
char freq[10];
|
||||||
{
|
sprintf(freq, "%d", clockspeed * 1000);
|
||||||
jz_dev = open("/dev/mem", O_RDWR);
|
writeStringToFile(SYSFS_CPUFREQ_MAX, freq);
|
||||||
if(jz_dev)
|
writeStringToFile(SYSFS_CPUFREQ_SET, freq);
|
||||||
{
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
18
src/cpu.h
18
src/cpu.h
@ -1,24 +1,6 @@
|
|||||||
#ifndef CPU_H
|
#ifndef CPU_H
|
||||||
#define 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 jz_cpuspeed(unsigned clockspeed);
|
||||||
void pll_init(unsigned int clock);
|
|
||||||
inline int sdram_convert(unsigned int pllin,unsigned int *sdram_freq);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -526,8 +526,8 @@ void GMenu2X::readConfig() {
|
|||||||
if (confStr["skin"].empty() || !fileExists("skins/"+confStr["skin"])) confStr["skin"] = "Default";
|
if (confStr["skin"].empty() || !fileExists("skins/"+confStr["skin"])) confStr["skin"] = "Default";
|
||||||
|
|
||||||
evalIntConf( &confInt["outputLogs"], 0, 0,1 );
|
evalIntConf( &confInt["outputLogs"], 0, 0,1 );
|
||||||
evalIntConf( &confInt["maxClock"], 430, 200,430 );
|
evalIntConf( &confInt["maxClock"], 430, 30, 500 );
|
||||||
evalIntConf( &confInt["menuClock"], 200, 200,430 );
|
evalIntConf( &confInt["menuClock"], 200, 30, 430 );
|
||||||
evalIntConf( &confInt["globalVolume"], 67, 0,100 );
|
evalIntConf( &confInt["globalVolume"], 67, 0,100 );
|
||||||
evalIntConf( &confInt["backlight"], 100, 5,100 );
|
evalIntConf( &confInt["backlight"], 100, 5,100 );
|
||||||
evalIntConf( &confInt["videoBpp"], 32,32,32 ); // 8,16
|
evalIntConf( &confInt["videoBpp"], 32,32,32 ); // 8,16
|
||||||
@ -1799,20 +1799,9 @@ void GMenu2X::applyDefaultTimings() {
|
|||||||
|
|
||||||
|
|
||||||
void GMenu2X::setClock(unsigned mhz) {
|
void GMenu2X::setClock(unsigned mhz) {
|
||||||
mhz = constrain(mhz,200,confInt["maxClock"]);
|
mhz = constrain(mhz, 30, confInt["maxClock"]);
|
||||||
#ifdef TARGET_GP2X
|
#ifdef TARGET_GP2X
|
||||||
/* if (gp2x_mem!=0) {
|
jz_cpuspeed(mhz);
|
||||||
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);*/
|
|
||||||
#endif
|
#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