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) ...@@ -83,12 +83,21 @@ unsigned int get_clk_frequency_khz(int info)
EXPORT_SYMBOL(get_clk_frequency_khz); 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; 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 @@ ...@@ -21,100 +21,98 @@
#include "generic.h" #include "generic.h"
/* Crystal clock : 13-MHZ*/ /* Crystal clock: 13MHz */
#define BASE_CLK 13000000 #define BASE_CLK 13000000
/* /*
* Get the clock frequency as reflected by CCSR and the turbo flag. * Get the clock frequency as reflected by CCSR and the turbo flag.
* We assume these values have been applied via a fcs. * We assume these values have been applied via a fcs.
* If info is not 0 we also display the current settings. * 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 int get_clk_frequency_khz( int info)
{ {
unsigned long ccsr, turbo, b, ht; unsigned long ccsr, clkcfg;
unsigned int l, L, m, M, n2, N, S, cccra; unsigned int l, L, m, M, n2, N, S;
int cccr_a, t, ht, b;
ccsr = CCSR; ccsr = CCSR;
cccra = CCCR & (0x1 << 25); cccr_a = CCCR & (1 << 25);
/* Read clkcfg register: it has turbo, b, half-turbo (and f) */ /* Read clkcfg register: it has turbo, b, half-turbo (and f) */
asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (turbo) ); asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) );
b = (turbo & (0x1 << 3)); t = clkcfg & (1 << 1);
ht = (turbo & (0x1 << 2)); ht = clkcfg & (1 << 2);
b = clkcfg & (1 << 3);
l = ccsr & 0x1f; l = ccsr & 0x1f;
n2 = (ccsr>>7) & 0xf; n2 = (ccsr>>7) & 0xf;
if (l == 31) { m = (l <= 10) ? 1 : (l <= 20) ? 2 : 4;
/* 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 = l * BASE_CLK; L = l * BASE_CLK;
N = (n2 * L) / 2; N = (L * n2) / 2;
M = (!cccr_a) ? (L/m) : ((b) ? L : (L/2));
S = (b) ? L : (L/2); S = (b) ? L : (L/2);
if (cccra == 0)
M = L/m;
else
M = (b) ? L : (L/2);
if (info) { if (info) {
printk( KERN_INFO "Run Mode clock: %d.%02dMHz (*%d)\n", printk( KERN_INFO "Run Mode clock: %d.%02dMHz (*%d)\n",
L / 1000000, (L % 1000000) / 10000, l ); 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", printk( KERN_INFO "Turbo Mode clock: %d.%02dMHz (*%d.%d, %sactive)\n",
N / 1000000, (N % 1000000)/10000, n2 / 2, (n2 % 2)*5, 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", printk( KERN_INFO "System bus clock: %d.%02dMHz \n",
S / 1000000, (S % 1000000) / 10000 ); 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 * Return the current mem clock frequency in units of 10kHz as
* reflected by CCCR[A], B, and L * 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 long ccsr, clkcfg;
unsigned int l, L, m, M, cccra; 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) ); asm( "mrc\tp14, 0, %0, c6, c0, 0" : "=r" (clkcfg) );
b = (clkcfg & (0x1 << 3)); b = clkcfg & (1 << 3);
ccsr = CCSR;
l = ccsr & 0x1f; l = ccsr & 0x1f;
if (l == 31) { m = (l <= 10) ? 1 : (l <= 20) ? 2 : 4;
/* 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 = l * BASE_CLK; L = l * BASE_CLK;
if (cccra == 0) M = (!cccr_a) ? (L/m) : ((b) ? L : (L/2));
M = L/m;
else
M = (b) ? L : L/2;
return (M / 10000); 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 ) ...@@ -113,24 +113,24 @@ static int pxa2xx_pcmcia_set_mcatt( int sock, int speed, int clock )
return 0; 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; struct soc_pcmcia_timing timing;
int sock = skt->nr; int sock = skt->nr;
soc_common_pcmcia_get_timing(skt, &timing); soc_common_pcmcia_get_timing(skt, &timing);
pxa2xx_pcmcia_set_mcmem(sock, timing.mem, lclk); pxa2xx_pcmcia_set_mcmem(sock, timing.mem, clk);
pxa2xx_pcmcia_set_mcatt(sock, timing.attr, lclk); pxa2xx_pcmcia_set_mcatt(sock, timing.attr, clk);
pxa2xx_pcmcia_set_mcio(sock, timing.io, lclk); pxa2xx_pcmcia_set_mcio(sock, timing.io, clk);
return 0; return 0;
} }
static int pxa2xx_pcmcia_set_timing(struct soc_pcmcia_socket *skt) static int pxa2xx_pcmcia_set_timing(struct soc_pcmcia_socket *skt)
{ {
unsigned int lclk = get_lclk_frequency_10khz(); unsigned int clk = get_memclk_frequency_10khz();
return pxa2xx_pcmcia_set_mcxx(skt, lclk); return pxa2xx_pcmcia_set_mcxx(skt, clk);
} }
int pxa2xx_drv_pcmcia_probe(struct device *dev) int pxa2xx_drv_pcmcia_probe(struct device *dev)
......
...@@ -432,7 +432,7 @@ static inline unsigned int get_pcd(unsigned int pixclock) ...@@ -432,7 +432,7 @@ static inline unsigned int get_pcd(unsigned int pixclock)
* (DPC) bit? or perhaps set it based on the various clock * (DPC) bit? or perhaps set it based on the various clock
* speeds */ * 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; pcd /= 100000000 * 2;
/* no need for this, since we should subtract 1 anyway. they cancel */ /* no need for this, since we should subtract 1 anyway. they cancel */
/* pcd += 1; */ /* make up for integer math truncations */ /* pcd += 1; */ /* make up for integer math truncations */
......
...@@ -83,9 +83,10 @@ typedef struct { volatile u32 offset[4096]; } __regbase; ...@@ -83,9 +83,10 @@ typedef struct { volatile u32 offset[4096]; } __regbase;
extern void pxa_gpio_mode( int gpio_mode ); 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 #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