Commit 0dd9075e authored by Nicolas Pitre's avatar Nicolas Pitre Committed by Russell King

[ARM PATCH] 1896/2: distinguish between memory and LCD clock on PXA

Patch from Nicolas Pitre

[patch rediffed]

On PXA27x the memory and LCd clocks are different.
Also clean the PXA27x clock code a bit.
parent 9f574064
......@@ -83,12 +83,21 @@ unsigned int get_clk_frequency_khz(int info)
EXPORT_SYMBOL(get_clk_frequency_khz);
/*
* Return the current lclk requency in units of 10kHz
* Return the current memory clock frequency in units of 10kHz
*/
unsigned int get_lclk_frequency_10khz(void)
unsigned int get_memclk_frequency_10khz(void)
{
return L_clk_mult[(CCCR >> 0) & 0x1f] * BASE_CLK / 10000;
}
EXPORT_SYMBOL(get_lclk_frequency_10khz);
EXPORT_SYMBOL(get_memclk_frequency_10khz);
/*
* Return the current LCD clock frequency in units of 10kHz
*/
unsigned int get_lcdclk_frequency_10khz(void)
{
return get_memclk_frequency_10khz();
}
EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
......@@ -21,100 +21,98 @@
#include "generic.h"
/* Crystal clock : 13-MHZ*/
/* Crystal clock: 13MHz */
#define BASE_CLK 13000000
/*
* Get the clock frequency as reflected by CCSR and the turbo flag.
* We assume these values have been applied via a fcs.
* If info is not 0 we also display the current settings.
*
* For more details, refer to Bulverde Manual, section 3.8.2.1
*/
unsigned int get_clk_frequency_khz( int info)
{
unsigned long ccsr, turbo, b, ht;
unsigned int l, L, m, M, n2, N, S, cccra;
unsigned long ccsr, clkcfg;
unsigned int l, L, m, M, n2, N, S;
int cccr_a, t, ht, b;
ccsr = CCSR;
cccra = CCCR & (0x1 << 25);
cccr_a = CCCR & (1 << 25);
/* Read clkcfg register: it has turbo, b, half-turbo (and f) */
asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (turbo) );
b = (turbo & (0x1 << 3));
ht = (turbo & (0x1 << 2));
asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) );
t = clkcfg & (1 << 1);
ht = clkcfg & (1 << 2);
b = clkcfg & (1 << 3);
l = ccsr & 0x1f;
n2 = (ccsr>>7) & 0xf;
if (l == 31) {
/* The calculation from the Yellow Book is incorrect:
it says M=4 for L=21-30 (which is easy to calculate
by subtracting 1 and then dividing by 10, but not
with 31, so we'll do it manually */
m = 1 << 2;
} else {
m = 1 << ((l-1)/10);
}
m = (l <= 10) ? 1 : (l <= 20) ? 2 : 4;
L = l * BASE_CLK;
N = (n2 * L) / 2;
S = (b) ? L : (L/2);
if (cccra == 0)
M = L/m;
else
M = (b) ? L : (L/2);
L = l * BASE_CLK;
N = (L * n2) / 2;
M = (!cccr_a) ? (L/m) : ((b) ? L : (L/2));
S = (b) ? L : (L/2);
if (info) {
printk( KERN_INFO "Run Mode clock: %d.%02dMHz (*%d)\n",
L / 1000000, (L % 1000000) / 10000, l );
printk( KERN_INFO "Memory clock: %d.%02dMHz (/%d)\n",
M / 1000000, (M % 1000000) / 10000, m );
printk( KERN_INFO "Turbo Mode clock: %d.%02dMHz (*%d.%d, %sactive)\n",
N / 1000000, (N % 1000000)/10000, n2 / 2, (n2 % 2)*5,
(turbo & 1) ? "" : "in" );
(t) ? "" : "in" );
printk( KERN_INFO "Memory clock: %d.%02dMHz (/%d)\n",
M / 1000000, (M % 1000000) / 10000, m );
printk( KERN_INFO "System bus clock: %d.%02dMHz \n",
S / 1000000, (S % 1000000) / 10000 );
}
return (turbo & 1) ? (N/1000) : (L/1000);
return (t) ? (N/1000) : (L/1000);
}
/*
* Return the current mem clock frequency in units of 10kHz as
* reflected by CCCR[A], B, and L
*/
unsigned int get_lclk_frequency_10khz(void)
unsigned int get_memclk_frequency_10khz(void)
{
unsigned long ccsr, clkcfg, b;
unsigned int l, L, m, M, cccra;
unsigned long ccsr, clkcfg;
unsigned int l, L, m, M;
int cccr_a, b;
cccra = CCCR & (0x1 << 25);
ccsr = CCSR;
cccr_a = CCCR & (1 << 25);
/* Read clkcfg register to obtain b */
/* Read clkcfg register: it has turbo, b, half-turbo (and f) */
asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) );
b = (clkcfg & (0x1 << 3));
b = clkcfg & (1 << 3);
ccsr = CCSR;
l = ccsr & 0x1f;
if (l == 31) {
/* The calculation from the Yellow Book is incorrect:
it says M=4 for L=21-30 (which is easy to calculate
by subtracting 1 and then dividing by 10, but not
with 31, so we'll do it manually */
m = 1 << 2;
} else {
m = 1 << ((l-1)/10);
}
l = ccsr & 0x1f;
m = (l <= 10) ? 1 : (l <= 20) ? 2 : 4;
L = l * BASE_CLK;
if (cccra == 0)
M = L/m;
else
M = (b) ? L : L/2;
M = (!cccr_a) ? (L/m) : ((b) ? L : (L/2));
return (M / 10000);
}
EXPORT_SYMBOL(get_clk_frequency_khz);
EXPORT_SYMBOL(get_lclk_frequency_10khz);
/*
* Return the current LCD clock frequency in units of 10kHz as
*/
unsigned int get_lcdclk_frequency_10khz(void)
{
unsigned long ccsr;
unsigned int l, L, k, K;
ccsr = CCSR;
l = ccsr & 0x1f;
k = (l <= 7) ? 1 : (l <= 16) ? 2 : 4;
L = l * BASE_CLK;
K = L / k;
return (K / 10000);
}
EXPORT_SYMBOL(get_clk_frequency_khz);
EXPORT_SYMBOL(get_memclk_frequency_10khz);
EXPORT_SYMBOL(get_lcdclk_frequency_10khz);
......@@ -113,24 +113,24 @@ static int pxa2xx_pcmcia_set_mcatt( int sock, int speed, int clock )
return 0;
}
static int pxa2xx_pcmcia_set_mcxx(struct soc_pcmcia_socket *skt, unsigned int lclk)
static int pxa2xx_pcmcia_set_mcxx(struct soc_pcmcia_socket *skt, unsigned int clk)
{
struct soc_pcmcia_timing timing;
int sock = skt->nr;
soc_common_pcmcia_get_timing(skt, &timing);
pxa2xx_pcmcia_set_mcmem(sock, timing.mem, lclk);
pxa2xx_pcmcia_set_mcatt(sock, timing.attr, lclk);
pxa2xx_pcmcia_set_mcio(sock, timing.io, lclk);
pxa2xx_pcmcia_set_mcmem(sock, timing.mem, clk);
pxa2xx_pcmcia_set_mcatt(sock, timing.attr, clk);
pxa2xx_pcmcia_set_mcio(sock, timing.io, clk);
return 0;
}
static int pxa2xx_pcmcia_set_timing(struct soc_pcmcia_socket *skt)
{
unsigned int lclk = get_lclk_frequency_10khz();
return pxa2xx_pcmcia_set_mcxx(skt, lclk);
unsigned int clk = get_memclk_frequency_10khz();
return pxa2xx_pcmcia_set_mcxx(skt, clk);
}
int pxa2xx_drv_pcmcia_probe(struct device *dev)
......
......@@ -432,7 +432,7 @@ static inline unsigned int get_pcd(unsigned int pixclock)
* (DPC) bit? or perhaps set it based on the various clock
* speeds */
pcd = (unsigned long long)get_lclk_frequency_10khz() * (unsigned long long)pixclock;
pcd = (unsigned long long)get_lcdclk_frequency_10khz() * pixclock;
pcd /= 100000000 * 2;
/* no need for this, since we should subtract 1 anyway. they cancel */
/* pcd += 1; */ /* make up for integer math truncations */
......
......@@ -83,9 +83,10 @@ typedef struct { volatile u32 offset[4096]; } __regbase;
extern void pxa_gpio_mode( int gpio_mode );
/*
* return current lclk frequency in units of 10kHz
* return current memory and LCD clock frequency in units of 10kHz
*/
extern unsigned int get_lclk_frequency_10khz(void);
extern unsigned int get_memclk_frequency_10khz(void);
extern unsigned int get_lcdclk_frequency_10khz(void);
#endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment