2014-12-15 18:05:55

by Aleksey Makarov

[permalink] [raw]
Subject: [PATCH 00/14] MIPS: OCTEON: Some partial support for Octeon III

These patches fix some issues in the Cavium Octeon code and
introduce some partial support for Octeon III and little-endian.

Aleksey Makarov (1):
MIPS: OCTEON: Delete unused COP2 saving code

Chandrakala Chavva (1):
MIPS: OCTEON: Use correct instruction to read 64-bit COP0 register

David Daney (12):
MIPS: OCTEON: Save/Restore wider multiply registers in OCTEON III CPUs
MIPS: OCTEON: Fix FP context save.
MIPS: OCTEON: Save and restore CP2 SHA3 state
MIPS: Remove unneeded #ifdef __KERNEL__ from asm/processor.h
MIPS: OCTEON: Implement the core-16057 workaround
MIPS: OCTEON: Don't do acknowledge operations for level triggered
irqs.
MIPS: OCTEON: Add ability to used an initrd from a named memory block.
MIPS: OCTEON: Add little-endian support to asm/octeon/octeon.h
MIPS: OCTEON: Implement DCache errata workaround for all CN6XXX
MIPS: OCTEON: Update octeon-model.h code for new SoCs.
MIPS: OCTEON: Add register definitions for OCTEON III reset unit.
MIPS: OCTEON: Handle OCTEON III in csrc-octeon.

arch/mips/cavium-octeon/csrc-octeon.c | 10 +
arch/mips/cavium-octeon/octeon-irq.c | 45 ++-
arch/mips/cavium-octeon/setup.c | 81 +++-
arch/mips/include/asm/bootinfo.h | 1 +
.../asm/mach-cavium-octeon/kernel-entry-init.h | 22 +
arch/mips/include/asm/mach-cavium-octeon/war.h | 3 +
arch/mips/include/asm/octeon/cvmx-rst-defs.h | 441 +++++++++++++++++++++
arch/mips/include/asm/octeon/octeon-model.h | 65 ++-
arch/mips/include/asm/octeon/octeon.h | 148 +++++--
arch/mips/include/asm/processor.h | 8 +-
arch/mips/include/asm/ptrace.h | 4 +-
arch/mips/kernel/asm-offsets.c | 1 +
arch/mips/kernel/octeon_switch.S | 218 ++++++----
arch/mips/kernel/setup.c | 19 +-
arch/mips/mm/uasm.c | 2 +-
15 files changed, 935 insertions(+), 133 deletions(-)
create mode 100644 arch/mips/include/asm/octeon/cvmx-rst-defs.h

--
2.1.3


2014-12-15 18:06:07

by Aleksey Makarov

[permalink] [raw]
Subject: [PATCH 01/14] MIPS: OCTEON: Save/Restore wider multiply registers in OCTEON III CPUs

From: David Daney <[email protected]>

The wide multiplier is twice as wide, so we need to save twice as much
state. Detect the multiplier type (CPU type) at start up and install
model specific handlers.

Signed-off-by: David Daney <[email protected]>
Signed-off-by: Leonid Rosenboim <[email protected]>
[[email protected]:
conflict resolution,
support for old compilers]
Signed-off-by: Aleksey Makarov <[email protected]>
---
arch/mips/cavium-octeon/setup.c | 37 ++++++++++
arch/mips/include/asm/octeon/octeon.h | 13 ++++
arch/mips/include/asm/ptrace.h | 4 +-
arch/mips/kernel/octeon_switch.S | 128 ++++++++++++++++++++++++++--------
4 files changed, 150 insertions(+), 32 deletions(-)

diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index 5ebdb32..627f9e8 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -615,6 +615,7 @@ void __init prom_init(void)
const char *arg;
char *p;
int i;
+ u64 t;
int argc;
#ifdef CONFIG_CAVIUM_RESERVE32
int64_t addr = -1;
@@ -663,6 +664,42 @@ void __init prom_init(void)
octeon_io_clock_rate = sysinfo->cpu_clock_hz;
}

+ t = read_c0_cvmctl();
+ if ((t & (1ull << 27)) == 0) {
+ /*
+ * Setup the multiplier save/restore code if
+ * CvmCtl[NOMUL] clear.
+ */
+ void *save;
+ void *save_end;
+ void *restore;
+ void *restore_end;
+ int save_len;
+ int restore_len;
+ int save_max = (char *)octeon_mult_save_end -
+ (char *)octeon_mult_save;
+ int restore_max = (char *)octeon_mult_restore_end -
+ (char *)octeon_mult_restore;
+ if (current_cpu_data.cputype == CPU_CAVIUM_OCTEON3) {
+ save = octeon_mult_save3;
+ save_end = octeon_mult_save3_end;
+ restore = octeon_mult_restore3;
+ restore_end = octeon_mult_restore3_end;
+ } else {
+ save = octeon_mult_save2;
+ save_end = octeon_mult_save2_end;
+ restore = octeon_mult_restore2;
+ restore_end = octeon_mult_restore2_end;
+ }
+ save_len = (char *)save_end - (char *)save;
+ restore_len = (char *)restore_end - (char *)restore;
+ if (!WARN_ON(save_len > save_max ||
+ restore_len > restore_max)) {
+ memcpy(octeon_mult_save, save, save_len);
+ memcpy(octeon_mult_restore, restore, restore_len);
+ }
+ }
+
/*
* Only enable the LED controller if we're running on a CN38XX, CN58XX,
* or CN56XX. The CN30XX and CN31XX don't have an LED controller.
diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h
index d781f9e..3e505a2 100644
--- a/arch/mips/include/asm/octeon/octeon.h
+++ b/arch/mips/include/asm/octeon/octeon.h
@@ -229,6 +229,19 @@ static inline void octeon_npi_write32(uint64_t address, uint32_t val)
cvmx_read64_uint32(address ^ 4);
}

+/* Octeon multiplier save/restore routines from octeon_switch.S */
+void octeon_mult_save(void);
+void octeon_mult_restore(void);
+void octeon_mult_save_end(void);
+void octeon_mult_restore_end(void);
+void octeon_mult_save3(void);
+void octeon_mult_save3_end(void);
+void octeon_mult_save2(void);
+void octeon_mult_save2_end(void);
+void octeon_mult_restore3(void);
+void octeon_mult_restore3_end(void);
+void octeon_mult_restore2(void);
+void octeon_mult_restore2_end(void);

/**
* Read a 32bit value from the Octeon NPI register space
diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h
index fc783f8..ffc3203 100644
--- a/arch/mips/include/asm/ptrace.h
+++ b/arch/mips/include/asm/ptrace.h
@@ -40,8 +40,8 @@ struct pt_regs {
unsigned long cp0_cause;
unsigned long cp0_epc;
#ifdef CONFIG_CPU_CAVIUM_OCTEON
- unsigned long long mpl[3]; /* MTM{0,1,2} */
- unsigned long long mtp[3]; /* MTP{0,1,2} */
+ unsigned long long mpl[6]; /* MTM{0-5} */
+ unsigned long long mtp[6]; /* MTP{0-5} */
#endif
} __aligned(8);

diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S
index f654768..3dec1e8 100644
--- a/arch/mips/kernel/octeon_switch.S
+++ b/arch/mips/kernel/octeon_switch.S
@@ -450,18 +450,23 @@ done_restore:
* void octeon_mult_save()
* sp is assumed to point to a struct pt_regs
*
- * NOTE: This is called in SAVE_SOME in stackframe.h. It can only
- * safely modify k0 and k1.
+ * NOTE: This is called in SAVE_TEMP in stackframe.h. It can
+ * safely modify v1,k0, k1,$10-$15, and $24. It will
+ * be overwritten with a processor specific version of the code.
*/
- .align 7
+ .p2align 7
.set push
.set noreorder
LEAF(octeon_mult_save)
- dmfc0 k0, $9,7 /* CvmCtl register. */
- bbit1 k0, 27, 1f /* Skip CvmCtl[NOMUL] */
+ jr ra
nop
+ .space 30 * 4, 0
+octeon_mult_save_end:
+ EXPORT(octeon_mult_save_end)
+ END(octeon_mult_save)

- /* Save the multiplier state */
+ LEAF(octeon_mult_save2)
+ /* Save the multiplier state OCTEON II and earlier*/
v3mulu k0, $0, $0
v3mulu k1, $0, $0
sd k0, PT_MTP(sp) /* PT_MTP has P0 */
@@ -476,44 +481,107 @@ done_restore:
sd k0, PT_MPL+8(sp) /* PT_MPL+8 has MPL1 */
jr ra
sd k1, PT_MPL+16(sp) /* PT_MPL+16 has MPL2 */
-
-1: /* Resume here if CvmCtl[NOMUL] */
+octeon_mult_save2_end:
+ EXPORT(octeon_mult_save2_end)
+ END(octeon_mult_save2)
+
+ LEAF(octeon_mult_save3)
+ /* Save the multiplier state OCTEON III */
+ v3mulu $10, $0, $0 /* read P0 */
+ v3mulu $11, $0, $0 /* read P1 */
+ v3mulu $12, $0, $0 /* read P2 */
+ sd $10, PT_MTP+(0*8)(sp) /* store P0 */
+ v3mulu $10, $0, $0 /* read P3 */
+ sd $11, PT_MTP+(1*8)(sp) /* store P1 */
+ v3mulu $11, $0, $0 /* read P4 */
+ sd $12, PT_MTP+(2*8)(sp) /* store P2 */
+ ori $13, $0, 1
+ v3mulu $12, $0, $0 /* read P5 */
+ sd $10, PT_MTP+(3*8)(sp) /* store P3 */
+ v3mulu $13, $13, $0 /* P4-P0 = MPL5-MPL1, $13 = MPL0 */
+ sd $11, PT_MTP+(4*8)(sp) /* store P4 */
+ v3mulu $10, $0, $0 /* read MPL1 */
+ sd $12, PT_MTP+(5*8)(sp) /* store P5 */
+ v3mulu $11, $0, $0 /* read MPL2 */
+ sd $13, PT_MPL+(0*8)(sp) /* store MPL0 */
+ v3mulu $12, $0, $0 /* read MPL3 */
+ sd $10, PT_MPL+(1*8)(sp) /* store MPL1 */
+ v3mulu $10, $0, $0 /* read MPL4 */
+ sd $11, PT_MPL+(2*8)(sp) /* store MPL2 */
+ v3mulu $11, $0, $0 /* read MPL5 */
+ sd $12, PT_MPL+(3*8)(sp) /* store MPL3 */
+ sd $10, PT_MPL+(4*8)(sp) /* store MPL4 */
jr ra
- END(octeon_mult_save)
+ sd $11, PT_MPL+(5*8)(sp) /* store MPL5 */
+octeon_mult_save3_end:
+ EXPORT(octeon_mult_save3_end)
+ END(octeon_mult_save3)
.set pop

/*
* void octeon_mult_restore()
* sp is assumed to point to a struct pt_regs
*
- * NOTE: This is called in RESTORE_SOME in stackframe.h.
+ * NOTE: This is called in RESTORE_TEMP in stackframe.h.
*/
- .align 7
+ .p2align 7
.set push
.set noreorder
LEAF(octeon_mult_restore)
- dmfc0 k1, $9,7 /* CvmCtl register. */
- ld v0, PT_MPL(sp) /* MPL0 */
- ld v1, PT_MPL+8(sp) /* MPL1 */
- ld k0, PT_MPL+16(sp) /* MPL2 */
- bbit1 k1, 27, 1f /* Skip CvmCtl[NOMUL] */
- /* Normally falls through, so no time wasted here */
- nop
+ jr ra
+ nop
+ .space 30 * 4, 0
+octeon_mult_restore_end:
+ EXPORT(octeon_mult_restore_end)
+ END(octeon_mult_restore)

+ LEAF(octeon_mult_restore2)
+ ld v0, PT_MPL(sp) /* MPL0 */
+ ld v1, PT_MPL+8(sp) /* MPL1 */
+ ld k0, PT_MPL+16(sp) /* MPL2 */
/* Restore the multiplier state */
- ld k1, PT_MTP+16(sp) /* P2 */
- MTM0 v0 /* MPL0 */
+ ld k1, PT_MTP+16(sp) /* P2 */
+ mtm0 v0 /* MPL0 */
ld v0, PT_MTP+8(sp) /* P1 */
- MTM1 v1 /* MPL1 */
- ld v1, PT_MTP(sp) /* P0 */
- MTM2 k0 /* MPL2 */
- MTP2 k1 /* P2 */
- MTP1 v0 /* P1 */
+ mtm1 v1 /* MPL1 */
+ ld v1, PT_MTP(sp) /* P0 */
+ mtm2 k0 /* MPL2 */
+ mtp2 k1 /* P2 */
+ mtp1 v0 /* P1 */
jr ra
- MTP0 v1 /* P0 */
-
-1: /* Resume here if CvmCtl[NOMUL] */
+ mtp0 v1 /* P0 */
+octeon_mult_restore2_end:
+ EXPORT(octeon_mult_restore2_end)
+ END(octeon_mult_restore2)
+
+ LEAF(octeon_mult_restore3)
+ ld $12, PT_MPL+(0*8)(sp) /* read MPL0 */
+ ld $13, PT_MPL+(3*8)(sp) /* read MPL3 */
+ ld $10, PT_MPL+(1*8)(sp) /* read MPL1 */
+ ld $11, PT_MPL+(4*8)(sp) /* read MPL4 */
+ .word 0x718d0008
+ /* mtm0 $12, $13 restore MPL0 and MPL3 */
+ ld $12, PT_MPL+(2*8)(sp) /* read MPL2 */
+ .word 0x714b000c
+ /* mtm1 $10, $11 restore MPL1 and MPL4 */
+ ld $13, PT_MPL+(5*8)(sp) /* read MPL5 */
+ ld $10, PT_MTP+(0*8)(sp) /* read P0 */
+ ld $11, PT_MTP+(3*8)(sp) /* read P3 */
+ .word 0x718d000d
+ /* mtm2 $12, $13 restore MPL2 and MPL5 */
+ ld $12, PT_MTP+(1*8)(sp) /* read P1 */
+ .word 0x714b0009
+ /* mtp0 $10, $11 restore P0 and P3 */
+ ld $13, PT_MTP+(4*8)(sp) /* read P4 */
+ ld $10, PT_MTP+(2*8)(sp) /* read P2 */
+ ld $11, PT_MTP+(5*8)(sp) /* read P5 */
+ .word 0x718d000a
+ /* mtp1 $12, $13 restore P1 and P4 */
jr ra
- nop
- END(octeon_mult_restore)
+ .word 0x714b000b
+ /* mtp2 $10, $11 restore P2 and P5 */
+
+octeon_mult_restore3_end:
+ EXPORT(octeon_mult_restore3_end)
+ END(octeon_mult_restore3)
.set pop
--
2.1.3

2014-12-15 18:06:17

by Aleksey Makarov

[permalink] [raw]
Subject: [PATCH 02/14] MIPS: OCTEON: Fix FP context save.

From: David Daney <[email protected]>

It wasn't being saved on task switch.

Signed-off-by: David Daney <[email protected]>
Signed-off-by: Aleksey Makarov <[email protected]>
---
arch/mips/kernel/octeon_switch.S | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)

diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S
index 3dec1e8..2787c01 100644
--- a/arch/mips/kernel/octeon_switch.S
+++ b/arch/mips/kernel/octeon_switch.S
@@ -31,15 +31,11 @@
/*
* check if we need to save FPU registers
*/
- PTR_L t3, TASK_THREAD_INFO(a0)
- LONG_L t0, TI_FLAGS(t3)
- li t1, _TIF_USEDFPU
- and t2, t0, t1
- beqz t2, 1f
- nor t1, zero, t1
-
- and t0, t0, t1
- LONG_S t0, TI_FLAGS(t3)
+ .set push
+ .set noreorder
+ beqz a3, 1f
+ PTR_L t3, TASK_THREAD_INFO(a0)
+ .set pop

/*
* clear saved user stack CU1 bit
@@ -57,14 +53,13 @@
1:

/* check if we need to save COP2 registers */
- PTR_L t2, TASK_THREAD_INFO(a0)
- LONG_L t0, ST_OFF(t2)
+ LONG_L t0, ST_OFF(t3)
bbit0 t0, 30, 1f

/* Disable COP2 in the stored process state */
li t1, ST0_CU2
xor t0, t1
- LONG_S t0, ST_OFF(t2)
+ LONG_S t0, ST_OFF(t3)

/* Enable COP2 so we can save it */
mfc0 t0, CP0_STATUS
--
2.1.3

2014-12-15 18:06:33

by Aleksey Makarov

[permalink] [raw]
Subject: [PATCH 04/14] MIPS: OCTEON: Use correct instruction to read 64-bit COP0 register

From: Chandrakala Chavva <[email protected]>

Use dmfc0/dmtc0 instructions for reading CvmMemCtl COP0 register,
its a 64-bit wide.

Signed-off-by: Chandrakala Chavva <[email protected]>
Signed-off-by: Aleksey Makarov <[email protected]>
---
arch/mips/kernel/octeon_switch.S | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S
index 590ca2d..f0a699d 100644
--- a/arch/mips/kernel/octeon_switch.S
+++ b/arch/mips/kernel/octeon_switch.S
@@ -80,7 +80,7 @@
1:
#if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
/* Check if we need to store CVMSEG state */
- mfc0 t0, $11,7 /* CvmMemCtl */
+ dmfc0 t0, $11,7 /* CvmMemCtl */
bbit0 t0, 6, 3f /* Is user access enabled? */

/* Store the CVMSEG state */
@@ -104,9 +104,9 @@
.set reorder

/* Disable access to CVMSEG */
- mfc0 t0, $11,7 /* CvmMemCtl */
+ dmfc0 t0, $11,7 /* CvmMemCtl */
xori t0, t0, 0x40 /* Bit 6 is CVMSEG user enable */
- mtc0 t0, $11,7 /* CvmMemCtl */
+ dmtc0 t0, $11,7 /* CvmMemCtl */
#endif
3:

--
2.1.3

2014-12-15 18:06:23

by Aleksey Makarov

[permalink] [raw]
Subject: [PATCH 03/14] MIPS: OCTEON: Save and restore CP2 SHA3 state

From: David Daney <[email protected]>

Allocate new save space, and then save/restore the registers if
OCTEON III.

Signed-off-by: David Daney <[email protected]>
Signed-off-by: Aleksey Makarov <[email protected]>
---
arch/mips/include/asm/processor.h | 2 ++
arch/mips/kernel/asm-offsets.c | 1 +
arch/mips/kernel/octeon_switch.S | 43 +++++++++++++++++++++++++++++----------
3 files changed, 35 insertions(+), 11 deletions(-)

diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index f1df4cb..a5b8a7f 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -211,6 +211,8 @@ struct octeon_cop2_state {
unsigned long cop2_gfm_poly;
/* DMFC2 rt, 0x025A; DMFC2 rt, 0x025B - Pass2 */
unsigned long cop2_gfm_result[2];
+ /* DMFC2 rt, 0x24F, DMFC2 rt, 0x50, OCTEON III */
+ unsigned long cop2_sha3[2];
};
#define COP2_INIT \
.cp2 = {0,},
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index b1d84bd..537e6f4 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -382,6 +382,7 @@ void output_octeon_cop2_state_defines(void)
OFFSET(OCTEON_CP2_GFM_RESULT, octeon_cop2_state, cop2_gfm_result);
OFFSET(OCTEON_CP2_HSH_DATW, octeon_cop2_state, cop2_hsh_datw);
OFFSET(OCTEON_CP2_HSH_IVW, octeon_cop2_state, cop2_hsh_ivw);
+ OFFSET(OCTEON_CP2_SHA3, octeon_cop2_state, cop2_sha3);
OFFSET(THREAD_CP2, task_struct, thread.cp2);
OFFSET(THREAD_CVMSEG, task_struct, thread.cvmseg.cvmseg);
BLANK();
diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S
index 2787c01..590ca2d 100644
--- a/arch/mips/kernel/octeon_switch.S
+++ b/arch/mips/kernel/octeon_switch.S
@@ -142,6 +142,8 @@
* void octeon_cop2_save(struct octeon_cop2_state *a0)
*/
.align 7
+ .set push
+ .set noreorder
LEAF(octeon_cop2_save)

dmfc0 t9, $9,7 /* CvmCtl register. */
@@ -152,17 +154,17 @@
dmfc2 t2, 0x0200
sd t0, OCTEON_CP2_CRC_IV(a0)
sd t1, OCTEON_CP2_CRC_LENGTH(a0)
- sd t2, OCTEON_CP2_CRC_POLY(a0)
/* Skip next instructions if CvmCtl[NODFA_CP2] set */
bbit1 t9, 28, 1f
+ sd t2, OCTEON_CP2_CRC_POLY(a0)

/* Save the LLM state */
dmfc2 t0, 0x0402
dmfc2 t1, 0x040A
sd t0, OCTEON_CP2_LLM_DAT(a0)
- sd t1, OCTEON_CP2_LLM_DAT+8(a0)

1: bbit1 t9, 26, 3f /* done if CvmCtl[NOCRYPTO] set */
+ sd t1, OCTEON_CP2_LLM_DAT+8(a0)

/* Save the COP2 crypto state */
/* this part is mostly common to both pass 1 and later revisions */
@@ -193,18 +195,20 @@
sd t2, OCTEON_CP2_AES_KEY+16(a0)
dmfc2 t2, 0x0101
sd t3, OCTEON_CP2_AES_KEY+24(a0)
- mfc0 t3, $15,0 /* Get the processor ID register */
+ mfc0 v0, $15,0 /* Get the processor ID register */
sd t0, OCTEON_CP2_AES_KEYLEN(a0)
- li t0, 0x000d0000 /* This is the processor ID of Octeon Pass1 */
+ li v1, 0x000d0000 /* This is the processor ID of Octeon Pass1 */
sd t1, OCTEON_CP2_AES_RESULT(a0)
- sd t2, OCTEON_CP2_AES_RESULT+8(a0)
/* Skip to the Pass1 version of the remainder of the COP2 state */
- beq t3, t0, 2f
+ beq v0, v1, 2f
+ sd t2, OCTEON_CP2_AES_RESULT+8(a0)

/* the non-pass1 state when !CvmCtl[NOCRYPTO] */
dmfc2 t1, 0x0240
dmfc2 t2, 0x0241
+ ori v1, v1, 0x9500 /* lowest OCTEON III PrId*/
dmfc2 t3, 0x0242
+ subu v1, v0, v1 /* prid - lowest OCTEON III PrId */
dmfc2 t0, 0x0243
sd t1, OCTEON_CP2_HSH_DATW(a0)
dmfc2 t1, 0x0244
@@ -257,8 +261,16 @@
sd t1, OCTEON_CP2_GFM_MULT+8(a0)
sd t2, OCTEON_CP2_GFM_POLY(a0)
sd t3, OCTEON_CP2_GFM_RESULT(a0)
- sd t0, OCTEON_CP2_GFM_RESULT+8(a0)
+ bltz v1, 4f
+ sd t0, OCTEON_CP2_GFM_RESULT+8(a0)
+ /* OCTEON III things*/
+ dmfc2 t0, 0x024F
+ dmfc2 t1, 0x0050
+ sd t0, OCTEON_CP2_SHA3(a0)
+ sd t1, OCTEON_CP2_SHA3+8(a0)
+4:
jr ra
+ nop

2: /* pass 1 special stuff when !CvmCtl[NOCRYPTO] */
dmfc2 t3, 0x0040
@@ -284,7 +296,9 @@

3: /* pass 1 or CvmCtl[NOCRYPTO] set */
jr ra
+ nop
END(octeon_cop2_save)
+ .set pop

/*
* void octeon_cop2_restore(struct octeon_cop2_state *a0)
@@ -349,9 +363,9 @@
ld t2, OCTEON_CP2_AES_RESULT+8(a0)
mfc0 t3, $15,0 /* Get the processor ID register */
dmtc2 t0, 0x0110
- li t0, 0x000d0000 /* This is the processor ID of Octeon Pass1 */
+ li v0, 0x000d0000 /* This is the processor ID of Octeon Pass1 */
dmtc2 t1, 0x0100
- bne t0, t3, 3f /* Skip the next stuff for non-pass1 */
+ bne v0, t3, 3f /* Skip the next stuff for non-pass1 */
dmtc2 t2, 0x0101

/* this code is specific for pass 1 */
@@ -379,6 +393,7 @@

3: /* this is post-pass1 code */
ld t2, OCTEON_CP2_HSH_DATW(a0)
+ ori v0, v0, 0x9500 /* lowest OCTEON III PrId*/
ld t0, OCTEON_CP2_HSH_DATW+8(a0)
ld t1, OCTEON_CP2_HSH_DATW+16(a0)
dmtc2 t2, 0x0240
@@ -432,9 +447,15 @@
dmtc2 t2, 0x0259
ld t2, OCTEON_CP2_GFM_RESULT+8(a0)
dmtc2 t0, 0x025E
+ subu v0, t3, v0 /* prid - lowest OCTEON III PrId */
dmtc2 t1, 0x025A
- dmtc2 t2, 0x025B
-
+ bltz v0, done_restore
+ dmtc2 t2, 0x025B
+ /* OCTEON III things*/
+ ld t0, OCTEON_CP2_SHA3(a0)
+ ld t1, OCTEON_CP2_SHA3+8(a0)
+ dmtc2 t0, 0x0051
+ dmtc2 t1, 0x0050
done_restore:
jr ra
nop
--
2.1.3

2014-12-15 18:06:36

by Aleksey Makarov

[permalink] [raw]
Subject: [PATCH 05/14] MIPS: OCTEON: Delete unused COP2 saving code

Commit 2c952e06e4f5 ("MIPS: Move cop2 save/restore to switch_to()")
removes assembler code to store COP2 registers. Commit
a36d8225bceb ("MIPS: OCTEON: Enable use of FPU") mistakenly
restores it

Fixes: a36d8225bceb ("MIPS: OCTEON: Enable use of FPU")
Signed-off-by: Aleksey Makarov <[email protected]>
---
arch/mips/kernel/octeon_switch.S | 26 --------------------------
1 file changed, 26 deletions(-)

diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S
index f0a699d..423ae83 100644
--- a/arch/mips/kernel/octeon_switch.S
+++ b/arch/mips/kernel/octeon_switch.S
@@ -52,32 +52,6 @@
.set pop
1:

- /* check if we need to save COP2 registers */
- LONG_L t0, ST_OFF(t3)
- bbit0 t0, 30, 1f
-
- /* Disable COP2 in the stored process state */
- li t1, ST0_CU2
- xor t0, t1
- LONG_S t0, ST_OFF(t3)
-
- /* Enable COP2 so we can save it */
- mfc0 t0, CP0_STATUS
- or t0, t1
- mtc0 t0, CP0_STATUS
-
- /* Save COP2 */
- daddu a0, THREAD_CP2
- jal octeon_cop2_save
- dsubu a0, THREAD_CP2
-
- /* Disable COP2 now that we are done */
- mfc0 t0, CP0_STATUS
- li t1, ST0_CU2
- xor t0, t1
- mtc0 t0, CP0_STATUS
-
-1:
#if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
/* Check if we need to store CVMSEG state */
dmfc0 t0, $11,7 /* CvmMemCtl */
--
2.1.3

2014-12-15 18:06:46

by Aleksey Makarov

[permalink] [raw]
Subject: [PATCH 08/14] MIPS: OCTEON: Don't do acknowledge operations for level triggered irqs.

From: David Daney <[email protected]>

The acknowledge bits don't exist for level triggered irqs, so setting
them causes the simulator to terminate.

Signed-off-by: David Daney <[email protected]>
Signed-off-by: Leonid Rosenboim <[email protected]>
Signed-off-by: Aleksey Makarov <[email protected]>
---
arch/mips/cavium-octeon/octeon-irq.c | 45 ++++++++++++++++++++++++++++++++++--
1 file changed, 43 insertions(+), 2 deletions(-)

diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index 2bc4aa9..5df70c5 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -752,6 +752,18 @@ static struct irq_chip octeon_irq_chip_ciu_v2 = {
.name = "CIU",
.irq_enable = octeon_irq_ciu_enable_v2,
.irq_disable = octeon_irq_ciu_disable_all_v2,
+ .irq_mask = octeon_irq_ciu_disable_local_v2,
+ .irq_unmask = octeon_irq_ciu_enable_v2,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = octeon_irq_ciu_set_affinity_v2,
+ .irq_cpu_offline = octeon_irq_cpu_offline_ciu,
+#endif
+};
+
+static struct irq_chip octeon_irq_chip_ciu_v2_edge = {
+ .name = "CIU",
+ .irq_enable = octeon_irq_ciu_enable_v2,
+ .irq_disable = octeon_irq_ciu_disable_all_v2,
.irq_ack = octeon_irq_ciu_ack,
.irq_mask = octeon_irq_ciu_disable_local_v2,
.irq_unmask = octeon_irq_ciu_enable_v2,
@@ -765,6 +777,18 @@ static struct irq_chip octeon_irq_chip_ciu = {
.name = "CIU",
.irq_enable = octeon_irq_ciu_enable,
.irq_disable = octeon_irq_ciu_disable_all,
+ .irq_mask = octeon_irq_ciu_disable_local,
+ .irq_unmask = octeon_irq_ciu_enable,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = octeon_irq_ciu_set_affinity,
+ .irq_cpu_offline = octeon_irq_cpu_offline_ciu,
+#endif
+};
+
+static struct irq_chip octeon_irq_chip_ciu_edge = {
+ .name = "CIU",
+ .irq_enable = octeon_irq_ciu_enable,
+ .irq_disable = octeon_irq_ciu_disable_all,
.irq_ack = octeon_irq_ciu_ack,
.irq_mask = octeon_irq_ciu_disable_local,
.irq_unmask = octeon_irq_ciu_enable,
@@ -984,6 +1008,7 @@ static int octeon_irq_ciu_xlat(struct irq_domain *d,
}

static struct irq_chip *octeon_irq_ciu_chip;
+static struct irq_chip *octeon_irq_ciu_chip_edge;
static struct irq_chip *octeon_irq_gpio_chip;

static bool octeon_irq_virq_in_range(unsigned int virq)
@@ -1014,7 +1039,7 @@ static int octeon_irq_ciu_map(struct irq_domain *d,

if (octeon_irq_ciu_is_edge(line, bit))
octeon_irq_set_ciu_mapping(virq, line, bit, 0,
- octeon_irq_ciu_chip,
+ octeon_irq_ciu_chip_edge,
handle_edge_irq);
else
octeon_irq_set_ciu_mapping(virq, line, bit, 0,
@@ -1196,6 +1221,7 @@ static void __init octeon_irq_init_ciu(void)
{
unsigned int i;
struct irq_chip *chip;
+ struct irq_chip *chip_edge;
struct irq_chip *chip_mbox;
struct irq_chip *chip_wd;
struct device_node *gpio_node;
@@ -1212,16 +1238,19 @@ static void __init octeon_irq_init_ciu(void)
OCTEON_IS_MODEL(OCTEON_CN52XX_PASS2_X) ||
OCTEON_IS_MODEL(OCTEON_CN6XXX)) {
chip = &octeon_irq_chip_ciu_v2;
+ chip_edge = &octeon_irq_chip_ciu_v2_edge;
chip_mbox = &octeon_irq_chip_ciu_mbox_v2;
chip_wd = &octeon_irq_chip_ciu_wd_v2;
octeon_irq_gpio_chip = &octeon_irq_chip_ciu_gpio_v2;
} else {
chip = &octeon_irq_chip_ciu;
+ chip_edge = &octeon_irq_chip_ciu_edge;
chip_mbox = &octeon_irq_chip_ciu_mbox;
chip_wd = &octeon_irq_chip_ciu_wd;
octeon_irq_gpio_chip = &octeon_irq_chip_ciu_gpio;
}
octeon_irq_ciu_chip = chip;
+ octeon_irq_ciu_chip_edge = chip_edge;
octeon_irq_ip4 = octeon_irq_ip4_mask;

/* Mips internal */
@@ -1473,6 +1502,18 @@ static struct irq_chip octeon_irq_chip_ciu2 = {
.name = "CIU2-E",
.irq_enable = octeon_irq_ciu2_enable,
.irq_disable = octeon_irq_ciu2_disable_all,
+ .irq_mask = octeon_irq_ciu2_disable_local,
+ .irq_unmask = octeon_irq_ciu2_enable,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = octeon_irq_ciu2_set_affinity,
+ .irq_cpu_offline = octeon_irq_cpu_offline_ciu,
+#endif
+};
+
+static struct irq_chip octeon_irq_chip_ciu2_edge = {
+ .name = "CIU2-E",
+ .irq_enable = octeon_irq_ciu2_enable,
+ .irq_disable = octeon_irq_ciu2_disable_all,
.irq_ack = octeon_irq_ciu2_ack,
.irq_mask = octeon_irq_ciu2_disable_local,
.irq_unmask = octeon_irq_ciu2_enable,
@@ -1582,7 +1623,7 @@ static int octeon_irq_ciu2_map(struct irq_domain *d,

if (octeon_irq_ciu2_is_edge(line, bit))
octeon_irq_set_ciu_mapping(virq, line, bit, 0,
- &octeon_irq_chip_ciu2,
+ &octeon_irq_chip_ciu2_edge,
handle_edge_irq);
else
octeon_irq_set_ciu_mapping(virq, line, bit, 0,
--
2.1.3

2014-12-15 18:06:52

by Aleksey Makarov

[permalink] [raw]
Subject: [PATCH 10/14] MIPS: OCTEON: Add little-endian support to asm/octeon/octeon.h

From: David Daney <[email protected]>

Also update union octeon_cvmemctl with new OCTEON II fields.

Signed-off-by: David Daney <[email protected]>
[[email protected]: use __BITFIELD_FIELD]
Signed-off-by: Aleksey Makarov <[email protected]>
---
arch/mips/include/asm/octeon/octeon.h | 135 ++++++++++++++++++++++++++--------
1 file changed, 105 insertions(+), 30 deletions(-)

diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h
index 3e505a2..ba5df50 100644
--- a/arch/mips/include/asm/octeon/octeon.h
+++ b/arch/mips/include/asm/octeon/octeon.h
@@ -9,6 +9,7 @@
#define __ASM_OCTEON_OCTEON_H

#include <asm/octeon/cvmx.h>
+#include <asm/bitfield.h>

extern uint64_t octeon_bootmem_alloc_range_phys(uint64_t size,
uint64_t alignment,
@@ -58,6 +59,7 @@ extern void octeon_io_clk_delay(unsigned long);
#define OCTOEN_SERIAL_LEN 20

struct octeon_boot_descriptor {
+#ifdef __BIG_ENDIAN_BITFIELD
/* Start of block referenced by assembly code - do not change! */
uint32_t desc_version;
uint32_t desc_size;
@@ -109,77 +111,149 @@ struct octeon_boot_descriptor {
uint8_t mac_addr_base[6];
uint8_t mac_addr_count;
uint64_t cvmx_desc_vaddr;
+#else
+ uint32_t desc_size;
+ uint32_t desc_version;
+ uint64_t stack_top;
+ uint64_t heap_base;
+ uint64_t heap_end;
+ /* Only used by bootloader */
+ uint64_t entry_point;
+ uint64_t desc_vaddr;
+ /* End of This block referenced by assembly code - do not change! */
+ uint32_t stack_size;
+ uint32_t exception_base_addr;
+ uint32_t argc;
+ uint32_t heap_size;
+ /*
+ * Argc count for application.
+ * Warning low bit scrambled in little-endian.
+ */
+ uint32_t argv[OCTEON_ARGV_MAX_ARGS];
+
+#define BOOT_FLAG_INIT_CORE (1 << 0)
+#define OCTEON_BL_FLAG_DEBUG (1 << 1)
+#define OCTEON_BL_FLAG_NO_MAGIC (1 << 2)
+ /* If set, use uart1 for console */
+#define OCTEON_BL_FLAG_CONSOLE_UART1 (1 << 3)
+ /* If set, use PCI console */
+#define OCTEON_BL_FLAG_CONSOLE_PCI (1 << 4)
+ /* Call exit on break on serial port */
+#define OCTEON_BL_FLAG_BREAK (1 << 5)
+
+ uint32_t core_mask;
+ uint32_t flags;
+ /* physical address of free memory descriptor block. */
+ uint32_t phy_mem_desc_addr;
+ /* DRAM size in megabyes. */
+ uint32_t dram_size;
+ /* CPU clock speed, in hz. */
+ uint32_t eclock_hz;
+ /* used to pass flags from app to debugger. */
+ uint32_t debugger_flags_base_addr;
+ /* SPI4 clock in hz. */
+ uint32_t spi_clock_hz;
+ /* DRAM clock speed, in hz. */
+ uint32_t dclock_hz;
+ uint8_t chip_rev_minor;
+ uint8_t chip_rev_major;
+ uint16_t chip_type;
+ uint8_t board_rev_minor;
+ uint8_t board_rev_major;
+ uint16_t board_type;
+
+ uint64_t unused1[4]; /* Not even filled in by bootloader. */
+
+ uint64_t cvmx_desc_vaddr;
+#endif
};

union octeon_cvmemctl {
uint64_t u64;
struct {
/* RO 1 = BIST fail, 0 = BIST pass */
- uint64_t tlbbist:1;
+ __BITFIELD_FIELD(uint64_t tlbbist:1,
/* RO 1 = BIST fail, 0 = BIST pass */
- uint64_t l1cbist:1;
+ __BITFIELD_FIELD(uint64_t l1cbist:1,
/* RO 1 = BIST fail, 0 = BIST pass */
- uint64_t l1dbist:1;
+ __BITFIELD_FIELD(uint64_t l1dbist:1,
/* RO 1 = BIST fail, 0 = BIST pass */
- uint64_t dcmbist:1;
+ __BITFIELD_FIELD(uint64_t dcmbist:1,
/* RO 1 = BIST fail, 0 = BIST pass */
- uint64_t ptgbist:1;
+ __BITFIELD_FIELD(uint64_t ptgbist:1,
/* RO 1 = BIST fail, 0 = BIST pass */
- uint64_t wbfbist:1;
+ __BITFIELD_FIELD(uint64_t wbfbist:1,
/* Reserved */
- uint64_t reserved:22;
+ __BITFIELD_FIELD(uint64_t reserved:17,
+ /* OCTEON II - TLB replacement policy: 0 = bitmask LRU; 1 = NLU.
+ * This field selects between the TLB replacement policies:
+ * bitmask LRU or NLU. Bitmask LRU maintains a mask of
+ * recently used TLB entries and avoids them as new entries
+ * are allocated. NLU simply guarantees that the next
+ * allocation is not the last used TLB entry. */
+ __BITFIELD_FIELD(uint64_t tlbnlu:1,
+ /* OCTEON II - Selects the bit in the counter used for
+ * releasing a PAUSE. This counter trips every 2(8+PAUSETIME)
+ * cycles. If not already released, the cnMIPS II core will
+ * always release a given PAUSE instruction within
+ * 2(8+PAUSETIME). If the counter trip happens to line up,
+ * the cnMIPS II core may release the PAUSE instantly. */
+ __BITFIELD_FIELD(uint64_t pausetime:3,
+ /* OCTEON II - This field is an extension of
+ * CvmMemCtl[DIDTTO] */
+ __BITFIELD_FIELD(uint64_t didtto2:1,
/* R/W If set, marked write-buffer entries time out
* the same as as other entries; if clear, marked
* write-buffer entries use the maximum timeout. */
- uint64_t dismarkwblongto:1;
+ __BITFIELD_FIELD(uint64_t dismarkwblongto:1,
/* R/W If set, a merged store does not clear the
* write-buffer entry timeout state. */
- uint64_t dismrgclrwbto:1;
+ __BITFIELD_FIELD(uint64_t dismrgclrwbto:1,
/* R/W Two bits that are the MSBs of the resultant
* CVMSEG LM word location for an IOBDMA. The other 8
* bits come from the SCRADDR field of the IOBDMA. */
- uint64_t iobdmascrmsb:2;
+ __BITFIELD_FIELD(uint64_t iobdmascrmsb:2,
/* R/W If set, SYNCWS and SYNCS only order marked
* stores; if clear, SYNCWS and SYNCS only order
* unmarked stores. SYNCWSMARKED has no effect when
* DISSYNCWS is set. */
- uint64_t syncwsmarked:1;
+ __BITFIELD_FIELD(uint64_t syncwsmarked:1,
/* R/W If set, SYNCWS acts as SYNCW and SYNCS acts as
* SYNC. */
- uint64_t dissyncws:1;
+ __BITFIELD_FIELD(uint64_t dissyncws:1,
/* R/W If set, no stall happens on write buffer
* full. */
- uint64_t diswbfst:1;
+ __BITFIELD_FIELD(uint64_t diswbfst:1,
/* R/W If set (and SX set), supervisor-level
* loads/stores can use XKPHYS addresses with
* VA<48>==0 */
- uint64_t xkmemenas:1;
+ __BITFIELD_FIELD(uint64_t xkmemenas:1,
/* R/W If set (and UX set), user-level loads/stores
* can use XKPHYS addresses with VA<48>==0 */
- uint64_t xkmemenau:1;
+ __BITFIELD_FIELD(uint64_t xkmemenau:1,
/* R/W If set (and SX set), supervisor-level
* loads/stores can use XKPHYS addresses with
* VA<48>==1 */
- uint64_t xkioenas:1;
+ __BITFIELD_FIELD(uint64_t xkioenas:1,
/* R/W If set (and UX set), user-level loads/stores
* can use XKPHYS addresses with VA<48>==1 */
- uint64_t xkioenau:1;
+ __BITFIELD_FIELD(uint64_t xkioenau:1,
/* R/W If set, all stores act as SYNCW (NOMERGE must
* be set when this is set) RW, reset to 0. */
- uint64_t allsyncw:1;
+ __BITFIELD_FIELD(uint64_t allsyncw:1,
/* R/W If set, no stores merge, and all stores reach
* the coherent bus in order. */
- uint64_t nomerge:1;
+ __BITFIELD_FIELD(uint64_t nomerge:1,
/* R/W Selects the bit in the counter used for DID
* time-outs 0 = 231, 1 = 230, 2 = 229, 3 =
* 214. Actual time-out is between 1x and 2x this
* interval. For example, with DIDTTO=3, expiration
* interval is between 16K and 32K. */
- uint64_t didtto:2;
+ __BITFIELD_FIELD(uint64_t didtto:2,
/* R/W If set, the (mem) CSR clock never turns off. */
- uint64_t csrckalwys:1;
+ __BITFIELD_FIELD(uint64_t csrckalwys:1,
/* R/W If set, mclk never turns off. */
- uint64_t mclkalwys:1;
+ __BITFIELD_FIELD(uint64_t mclkalwys:1,
/* R/W Selects the bit in the counter used for write
* buffer flush time-outs (WBFLT+11) is the bit
* position in an internal counter used to determine
@@ -187,25 +261,26 @@ union octeon_cvmemctl {
* 2x this interval. For example, with WBFLT = 0, a
* write buffer expires between 2K and 4K cycles after
* the write buffer entry is allocated. */
- uint64_t wbfltime:3;
+ __BITFIELD_FIELD(uint64_t wbfltime:3,
/* R/W If set, do not put Istream in the L2 cache. */
- uint64_t istrnol2:1;
+ __BITFIELD_FIELD(uint64_t istrnol2:1,
/* R/W The write buffer threshold. */
- uint64_t wbthresh:4;
+ __BITFIELD_FIELD(uint64_t wbthresh:4,
/* Reserved */
- uint64_t reserved2:2;
+ __BITFIELD_FIELD(uint64_t reserved2:2,
/* R/W If set, CVMSEG is available for loads/stores in
* kernel/debug mode. */
- uint64_t cvmsegenak:1;
+ __BITFIELD_FIELD(uint64_t cvmsegenak:1,
/* R/W If set, CVMSEG is available for loads/stores in
* supervisor mode. */
- uint64_t cvmsegenas:1;
+ __BITFIELD_FIELD(uint64_t cvmsegenas:1,
/* R/W If set, CVMSEG is available for loads/stores in
* user mode. */
- uint64_t cvmsegenau:1;
+ __BITFIELD_FIELD(uint64_t cvmsegenau:1,
/* R/W Size of local memory in cache blocks, 54 (6912
* bytes) is max legal value. */
- uint64_t lmemsz:6;
+ __BITFIELD_FIELD(uint64_t lmemsz:6,
+ ;)))))))))))))))))))))))))))))))))
} s;
};

--
2.1.3

2014-12-15 18:07:05

by Aleksey Makarov

[permalink] [raw]
Subject: [PATCH 13/14] MIPS: OCTEON: Add register definitions for OCTEON III reset unit.

From: David Daney <[email protected]>

Needed by follow-on patches.

Signed-off-by: David Daney <[email protected]>
Signed-off-by: Aleksey Makarov <[email protected]>
---
arch/mips/include/asm/octeon/cvmx-rst-defs.h | 441 +++++++++++++++++++++++++++
1 file changed, 441 insertions(+)
create mode 100644 arch/mips/include/asm/octeon/cvmx-rst-defs.h

diff --git a/arch/mips/include/asm/octeon/cvmx-rst-defs.h b/arch/mips/include/asm/octeon/cvmx-rst-defs.h
new file mode 100644
index 0000000..724dedb
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-rst-defs.h
@@ -0,0 +1,441 @@
+/***********************license start***************
+ * Author: Cavium Inc.
+ *
+ * Contact: [email protected]
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2014 Cavium Inc.
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Inc. for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_RST_DEFS_H__
+#define __CVMX_RST_DEFS_H__
+
+#define CVMX_RST_BIST_TIMER (CVMX_ADD_IO_SEG(0x0001180006001760ull))
+#define CVMX_RST_BOOT (CVMX_ADD_IO_SEG(0x0001180006001600ull))
+#define CVMX_RST_CFG (CVMX_ADD_IO_SEG(0x0001180006001610ull))
+#define CVMX_RST_CKILL (CVMX_ADD_IO_SEG(0x0001180006001638ull))
+#define CVMX_RST_COLD_DATAX(offset) (CVMX_ADD_IO_SEG(0x00011800060017C0ull) + \
+ ((offset) & 3) * 8)
+#define CVMX_RST_CTLX(offset) (CVMX_ADD_IO_SEG(0x0001180006001640ull) + \
+ ((offset) & 3) * 8)
+#define CVMX_RST_DELAY (CVMX_ADD_IO_SEG(0x0001180006001608ull))
+#define CVMX_RST_ECO (CVMX_ADD_IO_SEG(0x00011800060017B8ull))
+#define CVMX_RST_INT (CVMX_ADD_IO_SEG(0x0001180006001628ull))
+#define CVMX_RST_INT_W1S (CVMX_ADD_IO_SEG(0x0001180006001630ull))
+#define CVMX_RST_OCX (CVMX_ADD_IO_SEG(0x0001180006001618ull))
+#define CVMX_RST_OUT_CTL (CVMX_ADD_IO_SEG(0x0001180006001688ull))
+#define CVMX_RST_POWER_DBG (CVMX_ADD_IO_SEG(0x0001180006001708ull))
+#define CVMX_RST_PP_POWER (CVMX_ADD_IO_SEG(0x0001180006001700ull))
+#define CVMX_RST_REF_CNTR (CVMX_ADD_IO_SEG(0x0001180006001758ull))
+#define CVMX_RST_SOFT_PRSTX(offset) (CVMX_ADD_IO_SEG(0x00011800060016C0ull) + \
+ ((offset) & 3) * 8)
+#define CVMX_RST_SOFT_RST (CVMX_ADD_IO_SEG(0x0001180006001680ull))
+#define CVMX_RST_THERMAL_ALERT (CVMX_ADD_IO_SEG(0x0001180006001690ull))
+
+union cvmx_rst_bist_timer {
+ uint64_t u64;
+ struct cvmx_rst_bist_timer_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_29_63 : 35;
+ uint64_t count : 29;
+#else
+ uint64_t count : 29;
+ uint64_t reserved_29_63 : 35;
+#endif
+ } s;
+ struct cvmx_rst_bist_timer_s cn73xx;
+};
+
+union cvmx_rst_boot {
+ uint64_t u64;
+ struct cvmx_rst_boot_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t chipkill : 1;
+ uint64_t jtcsrdis : 1;
+ uint64_t ejtagdis : 1;
+ uint64_t romen : 1;
+ uint64_t ckill_ppdis : 1;
+ uint64_t jt_tstmode : 1;
+ uint64_t vrm_err : 1;
+ uint64_t reserved_37_56 : 20;
+ uint64_t c_mul : 7;
+ uint64_t pnr_mul : 6;
+ uint64_t reserved_21_23 : 3;
+ uint64_t lboot_oci : 3;
+ uint64_t lboot_ext : 6;
+ uint64_t lboot : 10;
+ uint64_t rboot : 1;
+ uint64_t rboot_pin : 1;
+#else
+ uint64_t rboot_pin : 1;
+ uint64_t rboot : 1;
+ uint64_t lboot : 10;
+ uint64_t lboot_ext : 6;
+ uint64_t lboot_oci : 3;
+ uint64_t reserved_21_23 : 3;
+ uint64_t pnr_mul : 6;
+ uint64_t c_mul : 7;
+ uint64_t reserved_37_56 : 20;
+ uint64_t vrm_err : 1;
+ uint64_t jt_tstmode : 1;
+ uint64_t ckill_ppdis : 1;
+ uint64_t romen : 1;
+ uint64_t ejtagdis : 1;
+ uint64_t jtcsrdis : 1;
+ uint64_t chipkill : 1;
+#endif
+ } s;
+ struct cvmx_rst_boot_s cn70xx;
+ struct cvmx_rst_boot_s cn70xxp1;
+ struct cvmx_rst_boot_s cn73xx;
+ struct cvmx_rst_boot_s cn78xx;
+};
+
+union cvmx_rst_cfg {
+ uint64_t u64;
+ struct cvmx_rst_cfg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bist_delay : 58;
+ uint64_t reserved_3_5 : 3;
+ uint64_t cntl_clr_bist : 1;
+ uint64_t warm_clr_bist : 1;
+ uint64_t reserved_0_0 : 1;
+#else
+ uint64_t reserved_0_0 : 1;
+ uint64_t warm_clr_bist : 1;
+ uint64_t cntl_clr_bist : 1;
+ uint64_t reserved_3_5 : 3;
+ uint64_t bist_delay : 58;
+#endif
+ } s;
+ struct cvmx_rst_cfg_cn70xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bist_delay : 58;
+ uint64_t reserved_3_5 : 3;
+ uint64_t cntl_clr_bist : 1;
+ uint64_t warm_clr_bist : 1;
+ uint64_t soft_clr_bist : 1;
+#else
+ uint64_t soft_clr_bist : 1;
+ uint64_t warm_clr_bist : 1;
+ uint64_t cntl_clr_bist : 1;
+ uint64_t reserved_3_5 : 3;
+ uint64_t bist_delay : 58;
+#endif
+ } cn70xx;
+ struct cvmx_rst_cfg_cn70xx cn70xxp1;
+ struct cvmx_rst_cfg_cn73xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t bist_delay : 58;
+ uint64_t reserved_1_5 : 5;
+ uint64_t clr_bist : 1;
+#else
+ uint64_t clr_bist : 1;
+ uint64_t reserved_1_5 : 5;
+ uint64_t bist_delay : 58;
+#endif
+ } cn73xx;
+ struct cvmx_rst_cfg_cn70xx cn78xx;
+};
+
+union cvmx_rst_ckill {
+ uint64_t u64;
+ struct cvmx_rst_ckill_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_47_63 : 17;
+ uint64_t timer : 47;
+#else
+ uint64_t timer : 47;
+ uint64_t reserved_47_63 : 17;
+#endif
+ } s;
+ struct cvmx_rst_ckill_s cn70xx;
+ struct cvmx_rst_ckill_s cn70xxp1;
+ struct cvmx_rst_ckill_s cn73xx;
+ struct cvmx_rst_ckill_s cn78xx;
+};
+
+union cvmx_rst_cold_datax {
+ uint64_t u64;
+ struct cvmx_rst_cold_datax_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t data : 64;
+#else
+ uint64_t data : 64;
+#endif
+ } s;
+ struct cvmx_rst_cold_datax_s cn73xx;
+};
+
+union cvmx_rst_ctlx {
+ uint64_t u64;
+ struct cvmx_rst_ctlx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_10_63 : 54;
+ uint64_t prst_link : 1;
+ uint64_t rst_done : 1;
+ uint64_t rst_link : 1;
+ uint64_t host_mode : 1;
+ uint64_t reserved_4_5 : 2;
+ uint64_t rst_drv : 1;
+ uint64_t rst_rcv : 1;
+ uint64_t rst_chip : 1;
+ uint64_t rst_val : 1;
+#else
+ uint64_t rst_val : 1;
+ uint64_t rst_chip : 1;
+ uint64_t rst_rcv : 1;
+ uint64_t rst_drv : 1;
+ uint64_t reserved_4_5 : 2;
+ uint64_t host_mode : 1;
+ uint64_t rst_link : 1;
+ uint64_t rst_done : 1;
+ uint64_t prst_link : 1;
+ uint64_t reserved_10_63 : 54;
+#endif
+ } s;
+ struct cvmx_rst_ctlx_s cn70xx;
+ struct cvmx_rst_ctlx_s cn70xxp1;
+ struct cvmx_rst_ctlx_s cn73xx;
+ struct cvmx_rst_ctlx_s cn78xx;
+};
+
+union cvmx_rst_delay {
+ uint64_t u64;
+ struct cvmx_rst_delay_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63 : 32;
+ uint64_t warm_rst_dly : 16;
+ uint64_t soft_rst_dly : 16;
+#else
+ uint64_t soft_rst_dly : 16;
+ uint64_t warm_rst_dly : 16;
+ uint64_t reserved_32_63 : 32;
+#endif
+ } s;
+ struct cvmx_rst_delay_s cn70xx;
+ struct cvmx_rst_delay_s cn70xxp1;
+ struct cvmx_rst_delay_s cn73xx;
+ struct cvmx_rst_delay_s cn78xx;
+};
+
+union cvmx_rst_eco {
+ uint64_t u64;
+ struct cvmx_rst_eco_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_32_63 : 32;
+ uint64_t eco_rw : 32;
+#else
+ uint64_t eco_rw : 32;
+ uint64_t reserved_32_63 : 32;
+#endif
+ } s;
+ struct cvmx_rst_eco_s cn73xx;
+ struct cvmx_rst_eco_s cn78xx;
+};
+
+union cvmx_rst_int {
+ uint64_t u64;
+ struct cvmx_rst_int_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_12_63 : 52;
+ uint64_t perst : 4;
+ uint64_t reserved_4_7 : 4;
+ uint64_t rst_link : 4;
+#else
+ uint64_t rst_link : 4;
+ uint64_t reserved_4_7 : 4;
+ uint64_t perst : 4;
+ uint64_t reserved_12_63 : 52;
+#endif
+ } s;
+ struct cvmx_rst_int_cn70xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_11_63 : 53;
+ uint64_t perst : 3;
+ uint64_t reserved_3_7 : 5;
+ uint64_t rst_link : 3;
+#else
+ uint64_t rst_link : 3;
+ uint64_t reserved_3_7 : 5;
+ uint64_t perst : 3;
+ uint64_t reserved_11_63 : 53;
+#endif
+ } cn70xx;
+ struct cvmx_rst_int_cn70xx cn70xxp1;
+ struct cvmx_rst_int_s cn73xx;
+ struct cvmx_rst_int_s cn78xx;
+};
+
+union cvmx_rst_int_w1s {
+ uint64_t u64;
+ struct cvmx_rst_int_w1s_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_12_63 : 52;
+ uint64_t perst : 4;
+ uint64_t reserved_4_7 : 4;
+ uint64_t rst_link : 4;
+#else
+ uint64_t rst_link : 4;
+ uint64_t reserved_4_7 : 4;
+ uint64_t perst : 4;
+ uint64_t reserved_12_63 : 52;
+#endif
+ } s;
+ struct cvmx_rst_int_w1s_s cn73xx;
+};
+
+union cvmx_rst_ocx {
+ uint64_t u64;
+ struct cvmx_rst_ocx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_3_63 : 61;
+ uint64_t rst_link : 3;
+#else
+ uint64_t rst_link : 3;
+ uint64_t reserved_3_63 : 61;
+#endif
+ } s;
+ struct cvmx_rst_ocx_s cn78xx;
+};
+
+union cvmx_rst_out_ctl {
+ uint64_t u64;
+ struct cvmx_rst_out_ctl_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_1_63 : 63;
+ uint64_t soft_rst : 1;
+#else
+ uint64_t soft_rst : 1;
+ uint64_t reserved_1_63 : 63;
+#endif
+ } s;
+ struct cvmx_rst_out_ctl_s cn73xx;
+};
+
+union cvmx_rst_power_dbg {
+ uint64_t u64;
+ struct cvmx_rst_power_dbg_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_3_63 : 61;
+ uint64_t str : 3;
+#else
+ uint64_t str : 3;
+ uint64_t reserved_3_63 : 61;
+#endif
+ } s;
+ struct cvmx_rst_power_dbg_s cn73xx;
+ struct cvmx_rst_power_dbg_s cn78xx;
+};
+
+union cvmx_rst_pp_power {
+ uint64_t u64;
+ struct cvmx_rst_pp_power_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_48_63 : 16;
+ uint64_t gate : 48;
+#else
+ uint64_t gate : 48;
+ uint64_t reserved_48_63 : 16;
+#endif
+ } s;
+ struct cvmx_rst_pp_power_cn70xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_4_63 : 60;
+ uint64_t gate : 4;
+#else
+ uint64_t gate : 4;
+ uint64_t reserved_4_63 : 60;
+#endif
+ } cn70xx;
+ struct cvmx_rst_pp_power_cn70xx cn70xxp1;
+ struct cvmx_rst_pp_power_cn73xx {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_16_63 : 48;
+ uint64_t gate : 16;
+#else
+ uint64_t gate : 16;
+ uint64_t reserved_16_63 : 48;
+#endif
+ } cn73xx;
+ struct cvmx_rst_pp_power_s cn78xx;
+};
+
+union cvmx_rst_ref_cntr {
+ uint64_t u64;
+ struct cvmx_rst_ref_cntr_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t cnt : 64;
+#else
+ uint64_t cnt : 64;
+#endif
+ } s;
+ struct cvmx_rst_ref_cntr_s cn73xx;
+};
+
+union cvmx_rst_soft_prstx {
+ uint64_t u64;
+ struct cvmx_rst_soft_prstx_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_1_63 : 63;
+ uint64_t soft_prst : 1;
+#else
+ uint64_t soft_prst : 1;
+ uint64_t reserved_1_63 : 63;
+#endif
+ } s;
+ struct cvmx_rst_soft_prstx_s cn70xx;
+ struct cvmx_rst_soft_prstx_s cn70xxp1;
+ struct cvmx_rst_soft_prstx_s cn73xx;
+ struct cvmx_rst_soft_prstx_s cn78xx;
+};
+
+union cvmx_rst_soft_rst {
+ uint64_t u64;
+ struct cvmx_rst_soft_rst_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_1_63 : 63;
+ uint64_t soft_rst : 1;
+#else
+ uint64_t soft_rst : 1;
+ uint64_t reserved_1_63 : 63;
+#endif
+ } s;
+ struct cvmx_rst_soft_rst_s cn70xx;
+ struct cvmx_rst_soft_rst_s cn70xxp1;
+ struct cvmx_rst_soft_rst_s cn73xx;
+ struct cvmx_rst_soft_rst_s cn78xx;
+};
+
+union cvmx_rst_thermal_alert {
+ uint64_t u64;
+ struct cvmx_rst_thermal_alert_s {
+#ifdef __BIG_ENDIAN_BITFIELD
+ uint64_t reserved_9_63 : 55;
+ uint64_t trip : 1;
+ uint64_t reserved_1_7 : 7;
+ uint64_t alert : 1;
+#else
+ uint64_t alert : 1;
+ uint64_t reserved_1_7 : 7;
+ uint64_t trip : 1;
+ uint64_t reserved_9_63 : 55;
+#endif
+ } s;
+ struct cvmx_rst_thermal_alert_s cn73xx;
+};
+
+#endif
--
2.1.3

2014-12-15 18:06:59

by Aleksey Makarov

[permalink] [raw]
Subject: [PATCH 12/14] MIPS: OCTEON: Update octeon-model.h code for new SoCs.

From: David Daney <[email protected]>

Add coverage for OCTEON III models.

Signed-off-by: David Daney <[email protected]>
Signed-off-by: Aleksey Makarov <[email protected]>
---
arch/mips/include/asm/octeon/octeon-model.h | 65 ++++++++++++++++++++++++++++-
1 file changed, 63 insertions(+), 2 deletions(-)

diff --git a/arch/mips/include/asm/octeon/octeon-model.h b/arch/mips/include/asm/octeon/octeon-model.h
index e2c122c..35d7cbd 100644
--- a/arch/mips/include/asm/octeon/octeon-model.h
+++ b/arch/mips/include/asm/octeon/octeon-model.h
@@ -45,6 +45,7 @@
*/

#define OCTEON_FAMILY_MASK 0x00ffff00
+#define OCTEON_PRID_MASK 0x00ffffff

/* Flag bits in top byte */
/* Ignores revision in model checks */
@@ -63,6 +64,46 @@
#define OM_MATCH_6XXX_FAMILY_MODELS 0x40000000
/* Match all cnf7XXX Octeon models. */
#define OM_MATCH_F7XXX_FAMILY_MODELS 0x80000000
+/* Match all cn7XXX Octeon models. */
+#define OM_MATCH_7XXX_FAMILY_MODELS 0x10000000
+#define OM_MATCH_FAMILY_MODELS (OM_MATCH_5XXX_FAMILY_MODELS | \
+ OM_MATCH_6XXX_FAMILY_MODELS | \
+ OM_MATCH_F7XXX_FAMILY_MODELS | \
+ OM_MATCH_7XXX_FAMILY_MODELS)
+/*
+ * CN7XXX models with new revision encoding
+ */
+
+#define OCTEON_CN73XX_PASS1_0 0x000d9700
+#define OCTEON_CN73XX (OCTEON_CN73XX_PASS1_0 | OM_IGNORE_REVISION)
+#define OCTEON_CN73XX_PASS1_X (OCTEON_CN73XX_PASS1_0 | \
+ OM_IGNORE_MINOR_REVISION)
+
+#define OCTEON_CN70XX_PASS1_0 0x000d9600
+#define OCTEON_CN70XX_PASS1_1 0x000d9601
+#define OCTEON_CN70XX_PASS1_2 0x000d9602
+
+#define OCTEON_CN70XX_PASS2_0 0x000d9608
+
+#define OCTEON_CN70XX (OCTEON_CN70XX_PASS1_0 | OM_IGNORE_REVISION)
+#define OCTEON_CN70XX_PASS1_X (OCTEON_CN70XX_PASS1_0 | \
+ OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN70XX_PASS2_X (OCTEON_CN70XX_PASS2_0 | \
+ OM_IGNORE_MINOR_REVISION)
+
+#define OCTEON_CN71XX OCTEON_CN70XX
+
+#define OCTEON_CN78XX_PASS1_0 0x000d9500
+#define OCTEON_CN78XX_PASS1_1 0x000d9501
+#define OCTEON_CN78XX_PASS2_0 0x000d9508
+
+#define OCTEON_CN78XX (OCTEON_CN78XX_PASS1_0 | OM_IGNORE_REVISION)
+#define OCTEON_CN78XX_PASS1_X (OCTEON_CN78XX_PASS1_0 | \
+ OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN78XX_PASS2_X (OCTEON_CN78XX_PASS2_0 | \
+ OM_IGNORE_MINOR_REVISION)
+
+#define OCTEON_CN76XX (0x000d9540 | OM_CHECK_SUBMODEL)

/*
* CNF7XXX models with new revision encoding
@@ -217,6 +258,10 @@
#define OCTEON_CN3XXX (OCTEON_CN58XX_PASS1_0 | OM_MATCH_PREVIOUS_MODELS | OM_IGNORE_REVISION)
#define OCTEON_CN5XXX (OCTEON_CN58XX_PASS1_0 | OM_MATCH_5XXX_FAMILY_MODELS)
#define OCTEON_CN6XXX (OCTEON_CN63XX_PASS1_0 | OM_MATCH_6XXX_FAMILY_MODELS)
+#define OCTEON_CNF7XXX (OCTEON_CNF71XX_PASS1_0 | \
+ OM_MATCH_F7XXX_FAMILY_MODELS)
+#define OCTEON_CN7XXX (OCTEON_CN78XX_PASS1_0 | \
+ OM_MATCH_7XXX_FAMILY_MODELS)

/* These are used to cover entire families of OCTEON processors */
#define OCTEON_FAM_1 (OCTEON_CN3XXX)
@@ -288,9 +333,16 @@ static inline uint64_t cvmx_read_csr(uint64_t csr_addr);
((((arg_model) & (OM_FLAG_MASK)) == OM_CHECK_SUBMODEL) \
&& __OCTEON_MATCH_MASK__((chip_model), (arg_model), OCTEON_58XX_MODEL_REV_MASK)) || \
((((arg_model) & (OM_MATCH_5XXX_FAMILY_MODELS)) == OM_MATCH_5XXX_FAMILY_MODELS) \
- && ((chip_model) >= OCTEON_CN58XX_PASS1_0) && ((chip_model) < OCTEON_CN63XX_PASS1_0)) || \
+ && ((chip_model & OCTEON_PRID_MASK) >= OCTEON_CN58XX_PASS1_0) \
+ && ((chip_model & OCTEON_PRID_MASK) < OCTEON_CN63XX_PASS1_0)) || \
((((arg_model) & (OM_MATCH_6XXX_FAMILY_MODELS)) == OM_MATCH_6XXX_FAMILY_MODELS) \
- && ((chip_model) >= OCTEON_CN63XX_PASS1_0)) || \
+ && ((chip_model & OCTEON_PRID_MASK) >= OCTEON_CN63XX_PASS1_0) \
+ && ((chip_model & OCTEON_PRID_MASK) < OCTEON_CNF71XX_PASS1_0)) || \
+ ((((arg_model) & (OM_MATCH_F7XXX_FAMILY_MODELS)) == OM_MATCH_F7XXX_FAMILY_MODELS) \
+ && ((chip_model & OCTEON_PRID_MASK) >= OCTEON_CNF71XX_PASS1_0) \
+ && ((chip_model & OCTEON_PRID_MASK) < OCTEON_CN78XX_PASS1_0)) || \
+ ((((arg_model) & (OM_MATCH_7XXX_FAMILY_MODELS)) == OM_MATCH_7XXX_FAMILY_MODELS) \
+ && ((chip_model & OCTEON_PRID_MASK) >= OCTEON_CN78XX_PASS1_0)) || \
((((arg_model) & (OM_MATCH_PREVIOUS_MODELS)) == OM_MATCH_PREVIOUS_MODELS) \
&& (((chip_model) & OCTEON_58XX_MODEL_MASK) < ((arg_model) & OCTEON_58XX_MODEL_MASK))) \
)))
@@ -326,6 +378,15 @@ static inline int __octeon_is_model_runtime__(uint32_t model)
#define OCTEON_IS_COMMON_BINARY() 1
#undef OCTEON_MODEL

+#define OCTEON_IS_OCTEON1() OCTEON_IS_MODEL(OCTEON_CN3XXX)
+#define OCTEON_IS_OCTEONPLUS() OCTEON_IS_MODEL(OCTEON_CN5XXX)
+#define OCTEON_IS_OCTEON2() \
+ (OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF71XX))
+
+#define OCTEON_IS_OCTEON3() OCTEON_IS_MODEL(OCTEON_CN7XXX)
+
+#define OCTEON_IS_OCTEON1PLUS() (OCTEON_IS_OCTEON1() || OCTEON_IS_OCTEONPLUS())
+
const char *octeon_model_get_string(uint32_t chip_id);
const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer);

--
2.1.3

2014-12-15 18:07:24

by Aleksey Makarov

[permalink] [raw]
Subject: [PATCH 14/14] MIPS: OCTEON: Handle OCTEON III in csrc-octeon.

From: David Daney <[email protected]>

The clock divisors are kept in different registers on OCTEON III.

Signed-off-by: David Daney <[email protected]>
Signed-off-by: Aleksey Makarov <[email protected]>
---
arch/mips/cavium-octeon/csrc-octeon.c | 10 ++++++++++
1 file changed, 10 insertions(+)

diff --git a/arch/mips/cavium-octeon/csrc-octeon.c b/arch/mips/cavium-octeon/csrc-octeon.c
index b752c4e..d270082 100644
--- a/arch/mips/cavium-octeon/csrc-octeon.c
+++ b/arch/mips/cavium-octeon/csrc-octeon.c
@@ -18,6 +18,7 @@
#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-ipd-defs.h>
#include <asm/octeon/cvmx-mio-defs.h>
+#include <asm/octeon/cvmx-rst-defs.h>


static u64 f;
@@ -39,11 +40,20 @@ void __init octeon_setup_delays(void)

if (current_cpu_type() == CPU_CAVIUM_OCTEON2) {
union cvmx_mio_rst_boot rst_boot;
+
rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT);
rdiv = rst_boot.s.c_mul; /* CPU clock */
sdiv = rst_boot.s.pnr_mul; /* I/O clock */
f = (0x8000000000000000ull / sdiv) * 2;
+ } else if (current_cpu_type() == CPU_CAVIUM_OCTEON3) {
+ union cvmx_rst_boot rst_boot;
+
+ rst_boot.u64 = cvmx_read_csr(CVMX_RST_BOOT);
+ rdiv = rst_boot.s.c_mul; /* CPU clock */
+ sdiv = rst_boot.s.pnr_mul; /* I/O clock */
+ f = (0x8000000000000000ull / sdiv) * 2;
}
+
}

/*
--
2.1.3

2014-12-15 18:08:19

by Aleksey Makarov

[permalink] [raw]
Subject: [PATCH 09/14] MIPS: OCTEON: Add ability to used an initrd from a named memory block.

From: David Daney <[email protected]>

If 'rd_name=xxx' is passed to the kernel, the named block with name
'xxx' is used for the initrd.

Signed-off-by: David Daney <[email protected]>
Signed-off-by: Leonid Rosenboim <[email protected]>
[[email protected]: conflict resolution]
Signed-off-by: Aleksey Makarov <[email protected]>
---
arch/mips/cavium-octeon/setup.c | 37 +++++++++++++++++++++++++++++++++----
arch/mips/include/asm/bootinfo.h | 1 +
arch/mips/kernel/setup.c | 19 ++++++++++++++++---
3 files changed, 50 insertions(+), 7 deletions(-)

diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index 627f9e8..8bba56f 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -28,6 +28,7 @@
#include <linux/of_fdt.h>
#include <linux/libfdt.h>
#include <linux/kexec.h>
+#include <linux/initrd.h>

#include <asm/processor.h>
#include <asm/reboot.h>
@@ -264,6 +265,9 @@ static int octeon_uart;

extern asmlinkage void handle_int(void);

+/* If an initrd named block is specified, its name goes here. */
+static char rd_name[64] __initdata;
+
/**
* Return non zero if we are currently running in the Octeon simulator
*
@@ -812,6 +816,10 @@ void __init prom_init(void)
MAX_MEMORY = 32ull << 30;
if (*p == '@')
RESERVE_LOW_MEM = memparse(p + 1, &p);
+ } else if (strncmp(arg, "rd_name=", 8) == 0) {
+ strncpy(rd_name, arg + 8, sizeof(rd_name));
+ rd_name[sizeof(rd_name) - 1] = 0;
+ goto append_arg;
#ifdef CONFIG_KEXEC
} else if (strncmp(arg, "crashkernel=", 12) == 0) {
crashk_size = memparse(arg+12, &p);
@@ -824,11 +832,15 @@ void __init prom_init(void)
* parse_crashkernel(arg, sysinfo->system_dram_size,
* &crashk_size, &crashk_base);
*/
+ goto append_arg;
#endif
- } else if (strlen(arcs_cmdline) + strlen(arg) + 1 <
- sizeof(arcs_cmdline) - 1) {
- strcat(arcs_cmdline, " ");
- strcat(arcs_cmdline, arg);
+ } else {
+append_arg:
+ if (strlen(arcs_cmdline) + strlen(arg) + 1
+ < sizeof(arcs_cmdline) - 1) {
+ strcat(arcs_cmdline, " ");
+ strcat(arcs_cmdline, arg);
+ }
}
}

@@ -892,6 +904,23 @@ void __init plat_mem_setup(void)
total = 0;
crashk_end = 0;

+#ifdef CONFIG_BLK_DEV_INITRD
+
+ if (rd_name[0]) {
+ const struct cvmx_bootmem_named_block_desc *initrd_block;
+
+ initrd_block = cvmx_bootmem_find_named_block(rd_name);
+ if (initrd_block != NULL) {
+ initrd_start = initrd_block->base_addr + PAGE_OFFSET;
+ initrd_end = initrd_start + initrd_block->size;
+ add_memory_region(initrd_block->base_addr,
+ initrd_block->size, BOOT_MEM_INIT_RAM);
+ initrd_in_reserved = 1;
+ total += initrd_block->size;
+ }
+ }
+#endif
+
/*
* The Mips memory init uses the first memory location for
* some memory vectors. When SPARSEMEM is in use, it doesn't
diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h
index 1f7ca8b..0720562 100644
--- a/arch/mips/include/asm/bootinfo.h
+++ b/arch/mips/include/asm/bootinfo.h
@@ -108,6 +108,7 @@ struct boot_mem_map {
};

extern struct boot_mem_map boot_mem_map;
+extern bool initrd_in_reserved;

extern void add_memory_region(phys_t start, phys_t size, long type);
extern void detect_memory_region(phys_t start, phys_t sz_min, phys_t sz_max);
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c
index f3b635f..b9adfc06 100644
--- a/arch/mips/kernel/setup.c
+++ b/arch/mips/kernel/setup.c
@@ -62,6 +62,7 @@ unsigned long mips_machtype __read_mostly = MACH_UNKNOWN;
EXPORT_SYMBOL(mips_machtype);

struct boot_mem_map boot_mem_map;
+bool initrd_in_reserved;

static char __initdata command_line[COMMAND_LINE_SIZE];
char __initdata arcs_cmdline[COMMAND_LINE_SIZE];
@@ -307,8 +308,14 @@ static void __init bootmem_init(void)
* as our memory range starting point. Once bootmem is inited we
* will reserve the area used for the initrd.
*/
- init_initrd();
- reserved_end = (unsigned long) PFN_UP(__pa_symbol(&_end));
+
+ if (initrd_in_reserved) {
+ init_initrd();
+ reserved_end = (unsigned long) PFN_UP(__pa_symbol(&_end));
+ } else {
+ reserved_end = max_t(unsigned long, init_initrd(),
+ PFN_UP(__pa_symbol(&_end)));
+ }

/*
* max_low_pfn is not a number of pages. The number of pages
@@ -323,8 +330,14 @@ static void __init bootmem_init(void)
for (i = 0; i < boot_mem_map.nr_map; i++) {
unsigned long start, end;

- if (boot_mem_map.map[i].type != BOOT_MEM_RAM)
+ switch (boot_mem_map.map[i].type) {
+ case BOOT_MEM_RAM:
+ case BOOT_MEM_INIT_RAM:
+ break;
+ default:
+ /* Not usable memory */
continue;
+ }

start = PFN_UP(boot_mem_map.map[i].addr);
end = PFN_DOWN(boot_mem_map.map[i].addr
--
2.1.3

2014-12-15 18:06:41

by Aleksey Makarov

[permalink] [raw]
Subject: [PATCH 07/14] MIPS: OCTEON: Implement the core-16057 workaround

From: David Daney <[email protected]>

Disable ICache prefetch for certian Octeon II processors.

Signed-off-by: David Daney <[email protected]>
Signed-off-by: Aleksey Makarov <[email protected]>
---
.../asm/mach-cavium-octeon/kernel-entry-init.h | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)

diff --git a/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h b/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h
index 1668ee5..21732c3 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h
@@ -63,6 +63,28 @@ skip:
li v1, ~(7 << 7)
and v0, v0, v1
ori v0, v0, (6 << 7)
+
+ mfc0 v1, CP0_PRID_REG
+ and t1, v1, 0xfff8
+ xor t1, t1, 0x9000 # 63-P1
+ beqz t1, 4f
+ and t1, v1, 0xfff8
+ xor t1, t1, 0x9008 # 63-P2
+ beqz t1, 4f
+ and t1, v1, 0xfff8
+ xor t1, t1, 0x9100 # 68-P1
+ beqz t1, 4f
+ and t1, v1, 0xff00
+ xor t1, t1, 0x9200 # 66-PX
+ bnez t1, 5f # Skip WAR for others.
+ and t1, v1, 0x00ff
+ slti t1, t1, 2 # 66-P1.2 and later good.
+ beqz t1, 5f
+
+4: # core-16057 work around
+ or v0, v0, 0x2000 # Set IPREF bit.
+
+5: # No core-16057 work around
# Write the cavium control register
dmtc0 v0, CP0_CVMCTL_REG
sync
--
2.1.3

2014-12-15 18:08:53

by Aleksey Makarov

[permalink] [raw]
Subject: [PATCH 06/14] MIPS: Remove unneeded #ifdef __KERNEL__ from asm/processor.h

From: David Daney <[email protected]>

Signed-off-by: David Daney <[email protected]>
Signed-off-by: Aleksey Makarov <[email protected]>
---
arch/mips/include/asm/processor.h | 6 ------
1 file changed, 6 deletions(-)

diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index a5b8a7f..728b05a 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -54,9 +54,7 @@ extern unsigned int vced_count, vcei_count;
#define TASK_SIZE 0x7fff8000UL
#endif

-#ifdef __KERNEL__
#define STACK_TOP_MAX TASK_SIZE
-#endif

#define TASK_IS_32BIT_ADDR 1

@@ -73,11 +71,7 @@ extern unsigned int vced_count, vcei_count;
#define TASK_SIZE32 0x7fff8000UL
#define TASK_SIZE64 0x10000000000UL
#define TASK_SIZE (test_thread_flag(TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE64)
-
-#ifdef __KERNEL__
#define STACK_TOP_MAX TASK_SIZE64
-#endif
-

#define TASK_SIZE_OF(tsk) \
(test_tsk_thread_flag(tsk, TIF_32BIT_ADDR) ? TASK_SIZE32 : TASK_SIZE64)
--
2.1.3

2014-12-15 20:53:27

by Aaro Koskinen

[permalink] [raw]
Subject: Re: [PATCH 09/14] MIPS: OCTEON: Add ability to used an initrd from a named memory block.

On Mon, Dec 15, 2014 at 09:03:15PM +0300, Aleksey Makarov wrote:
> From: David Daney <[email protected]>
>
> If 'rd_name=xxx' is passed to the kernel, the named block with name
> 'xxx' is used for the initrd.

Maybe use "initrd_name" for consistency or even just "initrd"
(if the xxx is not in form of "address,size" you could assume it to refer
to a named block).

A.

2014-12-15 21:01:59

by Aaro Koskinen

[permalink] [raw]
Subject: Re: [PATCH 12/14] MIPS: OCTEON: Update octeon-model.h code for new SoCs.

Hi,

On Mon, Dec 15, 2014 at 09:03:18PM +0300, Aleksey Makarov wrote:
> From: David Daney <[email protected]>
>
> Add coverage for OCTEON III models.

[...]

> +#define OCTEON_IS_OCTEON1() OCTEON_IS_MODEL(OCTEON_CN3XXX)
> +#define OCTEON_IS_OCTEONPLUS() OCTEON_IS_MODEL(OCTEON_CN5XXX)
> +#define OCTEON_IS_OCTEON2() \
> + (OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF71XX))
> +
> +#define OCTEON_IS_OCTEON3() OCTEON_IS_MODEL(OCTEON_CN7XXX)
> +
> +#define OCTEON_IS_OCTEON1PLUS() (OCTEON_IS_OCTEON1() || OCTEON_IS_OCTEONPLUS())

There are no users for these.

A.

2014-12-15 21:09:52

by Aaro Koskinen

[permalink] [raw]
Subject: Re: [PATCH 13/14] MIPS: OCTEON: Add register definitions for OCTEON III reset unit.

Hi,

On Mon, Dec 15, 2014 at 09:03:19PM +0300, Aleksey Makarov wrote:
> From: David Daney <[email protected]>
>
> Needed by follow-on patches.

Looks like only one of the unions was needed (cvmx_rst_boot)...?

A.

2014-12-15 21:24:33

by Aaro Koskinen

[permalink] [raw]
Subject: Re: [PATCH 14/14] MIPS: OCTEON: Handle OCTEON III in csrc-octeon.

Hi,

On Mon, Dec 15, 2014 at 09:03:20PM +0300, Aleksey Makarov wrote:
> if (current_cpu_type() == CPU_CAVIUM_OCTEON2) {
> union cvmx_mio_rst_boot rst_boot;
> +
> rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT);
> rdiv = rst_boot.s.c_mul; /* CPU clock */
> sdiv = rst_boot.s.pnr_mul; /* I/O clock */
> f = (0x8000000000000000ull / sdiv) * 2;
> + } else if (current_cpu_type() == CPU_CAVIUM_OCTEON3) {
> + union cvmx_rst_boot rst_boot;
> +
> + rst_boot.u64 = cvmx_read_csr(CVMX_RST_BOOT);
> + rdiv = rst_boot.s.c_mul; /* CPU clock */
> + sdiv = rst_boot.s.pnr_mul; /* I/O clock */
> + f = (0x8000000000000000ull / sdiv) * 2;
> }

The f = ... part could be moved outside the if blocks to avoid copy paste.

A.

2014-12-15 21:31:38

by David Daney

[permalink] [raw]
Subject: Re: [PATCH 13/14] MIPS: OCTEON: Add register definitions for OCTEON III reset unit.

On 12/15/2014 01:09 PM, Aaro Koskinen wrote:
> Hi,
>
> On Mon, Dec 15, 2014 at 09:03:19PM +0300, Aleksey Makarov wrote:
>> From: David Daney <[email protected]>
>>
>> Needed by follow-on patches.
>
> Looks like only one of the unions was needed (cvmx_rst_boot)...?
>

This follows the form of the other register definition files.

If Ralf requests it, we would consider deleting some of the currently
unused definitions.

David Daney

2014-12-15 21:38:53

by Aaro Koskinen

[permalink] [raw]
Subject: Re: [PATCH 14/14] MIPS: OCTEON: Handle OCTEON III in csrc-octeon.

Hi,

On Mon, Dec 15, 2014 at 01:29:28PM -0800, David Daney wrote:
> On 12/15/2014 01:24 PM, Aaro Koskinen wrote:
> >On Mon, Dec 15, 2014 at 09:03:20PM +0300, Aleksey Makarov wrote:
> >> if (current_cpu_type() == CPU_CAVIUM_OCTEON2) {
> >> union cvmx_mio_rst_boot rst_boot;
> >>+
> >> rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT);
> >> rdiv = rst_boot.s.c_mul; /* CPU clock */
> >> sdiv = rst_boot.s.pnr_mul; /* I/O clock */
> >> f = (0x8000000000000000ull / sdiv) * 2;
> >>+ } else if (current_cpu_type() == CPU_CAVIUM_OCTEON3) {
> >>+ union cvmx_rst_boot rst_boot;
> >>+
> >>+ rst_boot.u64 = cvmx_read_csr(CVMX_RST_BOOT);
> >>+ rdiv = rst_boot.s.c_mul; /* CPU clock */
> >>+ sdiv = rst_boot.s.pnr_mul; /* I/O clock */
> >>+ f = (0x8000000000000000ull / sdiv) * 2;
> >> }
> >
> >The f = ... part could be moved outside the if blocks to avoid copy paste.
> >
>
> No, If you look at the rest of the file, you will find that there are checks
> in the form:
>
> if (f != 0) ...
>
> There is a reason that we leave f with its default value of zero in some of
> the cases.

Right, sorry, I overlooked the fact that both of those if conditions
can be false.

A.

2014-12-15 21:45:12

by David Daney

[permalink] [raw]
Subject: Re: [PATCH 14/14] MIPS: OCTEON: Handle OCTEON III in csrc-octeon.

On 12/15/2014 01:24 PM, Aaro Koskinen wrote:
> Hi,
>
> On Mon, Dec 15, 2014 at 09:03:20PM +0300, Aleksey Makarov wrote:
>> if (current_cpu_type() == CPU_CAVIUM_OCTEON2) {
>> union cvmx_mio_rst_boot rst_boot;
>> +
>> rst_boot.u64 = cvmx_read_csr(CVMX_MIO_RST_BOOT);
>> rdiv = rst_boot.s.c_mul; /* CPU clock */
>> sdiv = rst_boot.s.pnr_mul; /* I/O clock */
>> f = (0x8000000000000000ull / sdiv) * 2;
>> + } else if (current_cpu_type() == CPU_CAVIUM_OCTEON3) {
>> + union cvmx_rst_boot rst_boot;
>> +
>> + rst_boot.u64 = cvmx_read_csr(CVMX_RST_BOOT);
>> + rdiv = rst_boot.s.c_mul; /* CPU clock */
>> + sdiv = rst_boot.s.pnr_mul; /* I/O clock */
>> + f = (0x8000000000000000ull / sdiv) * 2;
>> }
>
> The f = ... part could be moved outside the if blocks to avoid copy paste.
>

No, If you look at the rest of the file, you will find that there are
checks in the form:

if (f != 0) ...

There is a reason that we leave f with its default value of zero in some
of the cases.

David Daney

2014-12-15 22:08:03

by Aaro Koskinen

[permalink] [raw]
Subject: Re: [PATCH 13/14] MIPS: OCTEON: Add register definitions for OCTEON III reset unit.

Hi,

On Mon, Dec 15, 2014 at 01:31:28PM -0800, David Daney wrote:
> On 12/15/2014 01:09 PM, Aaro Koskinen wrote:
> >Hi,
> >
> >On Mon, Dec 15, 2014 at 09:03:19PM +0300, Aleksey Makarov wrote:
> >>From: David Daney <[email protected]>
> >>
> >>Needed by follow-on patches.
> >
> >Looks like only one of the unions was needed (cvmx_rst_boot)...?
>
> This follows the form of the other register definition files.
>
> If Ralf requests it, we would consider deleting some of the currently unused
> definitions.

Most of this stuff looks like machine generated. Can you at least
just make it to minimize the amount of C code it produces?
What's the point of having union definitions like e.g. these:

+ struct cvmx_rst_boot_s cn70xx;
+ struct cvmx_rst_boot_s cn70xxp1;
+ struct cvmx_rst_boot_s cn73xx;
+ struct cvmx_rst_boot_s cn78xx;

etc?

A.

2014-12-16 18:24:47

by David Daney

[permalink] [raw]
Subject: Re: [PATCH 12/14] MIPS: OCTEON: Update octeon-model.h code for new SoCs.

On 12/15/2014 01:01 PM, Aaro Koskinen wrote:
> Hi,
>
> On Mon, Dec 15, 2014 at 09:03:18PM +0300, Aleksey Makarov wrote:
>> From: David Daney <[email protected]>
>>
>> Add coverage for OCTEON III models.
>
> [...]
>
>> +#define OCTEON_IS_OCTEON1() OCTEON_IS_MODEL(OCTEON_CN3XXX)
>> +#define OCTEON_IS_OCTEONPLUS() OCTEON_IS_MODEL(OCTEON_CN5XXX)
>> +#define OCTEON_IS_OCTEON2() \
>> + (OCTEON_IS_MODEL(OCTEON_CN6XXX) || OCTEON_IS_MODEL(OCTEON_CNF71XX))
>> +
>> +#define OCTEON_IS_OCTEON3() OCTEON_IS_MODEL(OCTEON_CN7XXX)
>> +
>> +#define OCTEON_IS_OCTEON1PLUS() (OCTEON_IS_OCTEON1() || OCTEON_IS_OCTEONPLUS())
>
> There are no users for these.
>

True, but we will soon be adding users, so we would like to keep them.

David Daney

> A.
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
>
>

2014-12-16 18:26:30

by David Daney

[permalink] [raw]
Subject: Re: [PATCH 00/14] MIPS: OCTEON: Some partial support for Octeon III

On 12/15/2014 10:03 AM, Aleksey Makarov wrote:
> These patches fix some issues in the Cavium Octeon code and
> introduce some partial support for Octeon III and little-endian.
>

We will be sending a second revision of these to improve the patches as
per some of feedback received.

David Daney


> Aleksey Makarov (1):
> MIPS: OCTEON: Delete unused COP2 saving code
>
> Chandrakala Chavva (1):
> MIPS: OCTEON: Use correct instruction to read 64-bit COP0 register
>
> David Daney (12):
> MIPS: OCTEON: Save/Restore wider multiply registers in OCTEON III CPUs
> MIPS: OCTEON: Fix FP context save.
> MIPS: OCTEON: Save and restore CP2 SHA3 state
> MIPS: Remove unneeded #ifdef __KERNEL__ from asm/processor.h
> MIPS: OCTEON: Implement the core-16057 workaround
> MIPS: OCTEON: Don't do acknowledge operations for level triggered
> irqs.
> MIPS: OCTEON: Add ability to used an initrd from a named memory block.
> MIPS: OCTEON: Add little-endian support to asm/octeon/octeon.h
> MIPS: OCTEON: Implement DCache errata workaround for all CN6XXX
> MIPS: OCTEON: Update octeon-model.h code for new SoCs.
> MIPS: OCTEON: Add register definitions for OCTEON III reset unit.
> MIPS: OCTEON: Handle OCTEON III in csrc-octeon.
>
> arch/mips/cavium-octeon/csrc-octeon.c | 10 +
> arch/mips/cavium-octeon/octeon-irq.c | 45 ++-
> arch/mips/cavium-octeon/setup.c | 81 +++-
> arch/mips/include/asm/bootinfo.h | 1 +
> .../asm/mach-cavium-octeon/kernel-entry-init.h | 22 +
> arch/mips/include/asm/mach-cavium-octeon/war.h | 3 +
> arch/mips/include/asm/octeon/cvmx-rst-defs.h | 441 +++++++++++++++++++++
> arch/mips/include/asm/octeon/octeon-model.h | 65 ++-
> arch/mips/include/asm/octeon/octeon.h | 148 +++++--
> arch/mips/include/asm/processor.h | 8 +-
> arch/mips/include/asm/ptrace.h | 4 +-
> arch/mips/kernel/asm-offsets.c | 1 +
> arch/mips/kernel/octeon_switch.S | 218 ++++++----
> arch/mips/kernel/setup.c | 19 +-
> arch/mips/mm/uasm.c | 2 +-
> 15 files changed, 935 insertions(+), 133 deletions(-)
> create mode 100644 arch/mips/include/asm/octeon/cvmx-rst-defs.h
>

2014-12-17 14:55:26

by Aleksey Makarov

[permalink] [raw]
Subject: Re: [PATCH 09/14] MIPS: OCTEON: Add ability to used an initrd from a named memory block.


On 12/15/2014 11:53 PM, Aaro Koskinen wrote:
> On Mon, Dec 15, 2014 at 09:03:15PM +0300, Aleksey Makarov wrote:
>> From: David Daney <[email protected]>
>>
>> If 'rd_name=xxx' is passed to the kernel, the named block with name
>> 'xxx' is used for the initrd.
>
> Maybe use "initrd_name" for consistency or even just "initrd"
> (if the xxx is not in form of "address,size" you could assume it to refer
> to a named block).

As far as I can see it is already consistent as MIPS Linux uses "rd_start" and "rd_size" instead of "initrd".

Aleksey

>
> A.
> .
>