Add support for the L3CR to 2.6
Kumar Gala
kumar.gala at freescale.com
Thu Jun 24 09:23:14 EST 2004
Paul, Ben
Here is a patch from Jacob Pan that adds 'proper' support for the L3CR
on 745x parts.
- kumar
diff -Nru a/arch/ppc/kernel/l2cr.S b/arch/ppc/kernel/l2cr.S
--- a/arch/ppc/kernel/l2cr.S Thu Jun 24 00:04:09 2004
+++ b/arch/ppc/kernel/l2cr.S Thu Jun 24 00:04:09 2004
@@ -36,7 +36,9 @@
several months. The L2CR is similar, but I'm going
to assume the user of this functions knows what they
are doing.
-
+ June 17, 2004.
+ - JPAN: Fixed 745X L3 cache enablement routine, also use HW flush
assist.
+
Author: Terry Greeniaus (tgree at phys.ualberta.ca)
Please e-mail updates to this file to me, thanks!
*/
@@ -292,17 +294,18 @@
/* Flush the cache.
*/
-
- /* TODO: use HW flush assist */
-
- lis r4,0x0008
- mtctr r4
- li r4,0
-1:
- lwzx r0,r0,r4
- dcbf 0,r4
- addi r4,r4,32 /* Go to start of next cache line */
- bdnz 1b
+ /* use HW flush assist. (UM 3.6.3.1.5) */
+ mfspr r4, SPRN_L3CR
+ oris r4,r4,0x0040 /* Set L3CR[L3IO/9] = 1. */
+ ori r4,r4,0x0040 /* Set L3CR[L3DO/29] = 1.*/
+ mtspr 1018,r4 /* Lock the L3 by making IONLY and DONLY */
+ ori r4,r4,0x0800 /* Set L3CR[L3HWF/20] for hardware flush */
+ mtspr SPRN_L3CR,r4
+flush_745x_L3_poll:
+ mfspr r4,SPRN_L3CR
+ rlwinm. r4,r4,0,20,20
+ bne flush_745x_L3_poll
+ sync /* Clear the store queues per procedure (UM step 8) */
2:
/* Set up the L3CR configuration bits (and switch L3 off) */
@@ -348,8 +351,8 @@
cmplwi r5,0
beq 4f
- /* Enable the cache */
- oris r3,r3,(L3CR_L3E | L3CR_L3CLKEN)@h
+ /* enable L3 clock */
+ oris r3,r3,(L3CR_L3CLKEN)@h
mtspr SPRN_L3CR,r3
sync
@@ -357,6 +360,15 @@
li r0,256
mtctr r0
1: bdnz 1b
+
+ /* Clear MSSSR0 which may cause parity error */
+ xor r5,r5,r5
+ mtspr 1015, r5
+
+ /* Enable L3 cache */
+ oris r3,r3,(L3CR_L3E)@h
+ mtspr SPRN_L3CR,r3
+ sync
/* Restore MSR (restores EE and DR bits to original state) */
4: SYNC
diff -Nru a/arch/ppc/kernel/ppc_htab.c b/arch/ppc/kernel/ppc_htab.c
--- a/arch/ppc/kernel/ppc_htab.c Thu Jun 24 00:04:09 2004
+++ b/arch/ppc/kernel/ppc_htab.c Thu Jun 24 00:04:09 2004
@@ -37,6 +37,8 @@
static long long ppc_htab_lseek(struct file * file, loff_t offset, int
orig);
int proc_dol2crvec(ctl_table *table, int write, struct file *filp,
void __user *buffer, size_t *lenp);
+int proc_dol3crvec(ctl_table *table, int write, struct file *filp,
+ void __user *buffer, size_t *lenp);
extern PTE *Hash, *Hash_end;
extern unsigned long Hash_size, Hash_mask;
@@ -469,3 +471,173 @@
filp->f_pos += *lenp;
return 0;
}
+/* JPAN: external L3CACHE is supported by MPC745X processors. L3
timing parameters
+ * are both CPU and platform dependent, so we do not enable L3 during
boot time, but rather
+ * allow user to enable via sysctl via /proc/sys/kernel/l3cr. Prior to
booting
+ * the kernel, correct L3 SRAM AC timing can be adjusted by L3IDCR0-3,
+ * - MPC7450 UM 2.1.5.5.4
+ */
+int proc_dol3crvec(ctl_table *table, int write, struct file *filp,
+ void __user *buffer_arg, size_t *lenp)
+{
+ int vleft, first=1, len, left, val;
+ char __user *buffer = (char __user *) buffer_arg;
+ char buf[TMPBUFLEN], *p;
+ static const char *sizestrings[2] = {
+ "1MB", "2MB"
+ };
+ static const char *clockstrings[8] = {
+ "divided by 6",
+ "reserved (1)",
+ "divided by 2",
+ "divided by 2.5",
+ "divided by 3",
+ "divided by 3.5",
+ "divided by 4",
+ "divided by 5"
+ };
+ /* 7457 only */
+ static const char *clockstrings_ext[8] = {
+ "divided by 7",
+ "divided by 8",
+ "divided by 4.5",
+ "divided by 5.5",
+ "divided by 6.5",
+ "divided by 7.5",
+ "reserved (6)",
+ "reserved (7)"
+ };
+ static const char *clocksamplepoint[4] = {
+ "2 clocks",
+ "3 clocks",
+ "4 clocks",
+ "5 clocks"
+ };
+ /* 7457 only */
+ static const char *clocksamplepoint_ext[4] = {
+ "6 clocks",
+ "7 clocks",
+ "8 clocks",
+ "9 clocks"
+ };
+ static const char* p_clocksamplepoint[8] ={
+ "0 clocks",
+ "1 clocks",
+ "2 clocks",
+ "3 clocks",
+ "4 clocks",
+ "5 clocks",
+ "reserved (6)",
+ "reserved (7)"
+ };
+
+ static const char* typestrings[4] = {
+ "MSUG2 DDR SRAM",
+ "pipelined sync late-write SRAM",
+ "reserved type (2)",
+ "PB2 SRAM",
+ };
+
+ if (!(cur_cpu_spec[0]->cpu_features & CPU_FTR_L3CR))
+ return -EFAULT;
+
+ if ( /*!table->maxlen ||*/ (filp->f_pos && !write)) {
+ *lenp = 0;
+ return 0;
+ }
+
+ vleft = table->maxlen / sizeof(int);
+ left = *lenp;
+
+ for (; left /*&& vleft--*/; first=0) {
+ if (write) {
+ while (left) {
+ char c;
+ if(get_user(c, buffer))
+ return -EFAULT;
+ if (!isspace(c))
+ break;
+ left--;
+ buffer++;
+ }
+ if (!left)
+ break;
+ len = left;
+ if (len > TMPBUFLEN-1)
+ len = TMPBUFLEN-1;
+ if(copy_from_user(buf, buffer, len))
+ return -EFAULT;
+ buf[len] = 0;
+ p = buf;
+ if (*p < '0' || *p > '9')
+ break;
+ val = simple_strtoul(p, &p, 0);
+ len = p-buf;
+ if ((len < left) && *p && !isspace(*p))
+ break;
+ buffer += len;
+ left -= len;
+ _set_L3CR(val);
+ } else {
+ p = buf;
+ if (!first)
+ *p++ = '\t';
+ val = _get_L3CR();
+ p += sprintf(p, "0x%08x: ", val);
+ p += sprintf(p, " %s", (val >> 31) & 1 ? "enabled" :
+ "disabled");
+ p += sprintf(p, ", %sparity", (val>>30)&1 ? "" : "no ");
+ p += sprintf(p, ", %s address parity", (val>>29)&1 ? "" : "no ");
+ p += sprintf(p, ", %s", sizestrings[(val >> 28) & 1]);
+ if(val & (1<<21)) //clock ext
+ p += sprintf(p, ", %s", clockstrings_ext[(val >> 23) & 7]);
+ else
+ p += sprintf(p, ", %s", clockstrings[(val >> 23) & 7]);
+ p += sprintf(p, ", %s", typestrings[(val >> 8) & 3]);//SRAM type
+ p += sprintf(p,"\n");
+ if(val & (1<<20)) //clock sp ext
+ p += sprintf(p, ", %s sample point (ext)",
clocksamplepoint_ext[(val>>16)&3]);
+ else
+ p += sprintf(p, ", %s sample point",
clocksamplepoint[(val>>16)&3]);
+
+ p += sprintf(p, ", %s p-sample point",
p_clocksamplepoint[(val>>13)&7]);
+ p += sprintf(p, "%s", (val>>6)&1 ? ", data only" : ", unified");
+
+ p += sprintf(p, ", %s", (val>>12)&1 ? "8-bit running counter
replacement":\
+ "default replacement");
+ p += sprintf(p,"\n");
+
+ len = strlen(buf);
+ if (len > left)
+ len = left;
+ if (copy_to_user(buffer, buf, len))
+ return -EFAULT;
+ left -= len;
+ buffer += len;
+ break;
+ }
+ }
+
+ if (!write && !first && left) {
+ if(put_user('\n', (char *) buffer))
+ return -EFAULT;
+ left--, buffer++;
+ }
+ if (write) {
+ p = (char *) buffer;
+ while (left) {
+ char c;
+ if(get_user(c, p++))
+ return -EFAULT;
+ if (!isspace(c))
+ break;
+ left--;
+ }
+ }
+ if (write && first)
+ return -EINVAL;
+ *lenp -= left;
+ filp->f_pos += *lenp;
+ return 0;
+}
+
diff -Nru a/include/linux/sysctl.h b/include/linux/sysctl.h
--- a/include/linux/sysctl.h Thu Jun 24 00:04:09 2004
+++ b/include/linux/sysctl.h Thu Jun 24 00:04:09 2004
@@ -133,6 +133,7 @@
KERN_NGROUPS_MAX=63, /* int: NGROUPS_MAX */
KERN_SPARC_SCONS_PWROFF=64, /* int: serial console power-off halt */
KERN_HZ_TIMER=65, /* int: hz timer on or off */
+ KERN_PPC_L3CR=66, /* int: control L3 cache on/off */
};
diff -Nru a/kernel/sysctl.c b/kernel/sysctl.c
--- a/kernel/sysctl.c Thu Jun 24 00:04:09 2004
+++ b/kernel/sysctl.c Thu Jun 24 00:04:09 2004
@@ -114,6 +114,9 @@
extern unsigned long powersave_nap;
int proc_dol2crvec(ctl_table *table, int write, struct file *filp,
void *buffer, size_t *lenp);
+int proc_dol3crvec(ctl_table *table, int write, struct file *filp,
+ void *buffer, size_t *lenp);
+
#endif
#ifdef CONFIG_BSD_PROCESS_ACCT
@@ -369,6 +372,12 @@
.procname = "l2cr",
.mode = 0644,
.proc_handler = &proc_dol2crvec,
+ },
+ {
+ .ctl_name = KERN_PPC_L3CR,
+ .procname = "l3cr",
+ .mode = 0644,
+ .proc_handler = &proc_dol3crvec,
},
#endif
{
Signed-off-by: Jacob Pan <Jacob.Pan at freescale.com>
Signed-off-by: Kumar Gala <kumar.gala at freescale.com>
** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/
More information about the Linuxppc-dev
mailing list