MIPS: Enable L2 prefetching for CM >= 2.5
On systems with CM 2.5 & beyond there may be L2 prefetch units present which are not enabled by default. Detect them, configuring & enabling prefetching when available. Signed-off-by: Paul Burton <paul.burton@imgtec.com> Cc: linux-mips@linux-mips.org Cc: Leonid Yegoshin <Leonid.Yegoshin@imgtec.com> Cc: linux-kernel@vger.kernel.org Cc: James Hogan <james.hogan@imgtec.com> Cc: Markos Chandras <markos.chandras@imgtec.com> Patchwork: https://patchwork.linux-mips.org/patch/11180/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
This commit is contained in:
parent
37f2a174c4
commit
4d03551692
2 changed files with 77 additions and 1 deletions
|
@ -195,6 +195,8 @@ BUILD_CM_R_(gic_status, MIPS_CM_GCB_OFS + 0xd0)
|
|||
BUILD_CM_R_(cpc_status, MIPS_CM_GCB_OFS + 0xf0)
|
||||
BUILD_CM_RW(l2_config, MIPS_CM_GCB_OFS + 0x130)
|
||||
BUILD_CM_RW(sys_config2, MIPS_CM_GCB_OFS + 0x150)
|
||||
BUILD_CM_RW(l2_pft_control, MIPS_CM_GCB_OFS + 0x300)
|
||||
BUILD_CM_RW(l2_pft_control_b, MIPS_CM_GCB_OFS + 0x308)
|
||||
|
||||
/* Core Local & Core Other register accessor functions */
|
||||
BUILD_CM_Cx_RW(reset_release, 0x00)
|
||||
|
@ -245,6 +247,7 @@ BUILD_CM_Cx_R_(tcid_8_priority, 0x80)
|
|||
((minor) << CM_GCR_REV_MINOR_SHF))
|
||||
|
||||
#define CM_REV_CM2 CM_ENCODE_REV(6, 0)
|
||||
#define CM_REV_CM2_5 CM_ENCODE_REV(7, 0)
|
||||
#define CM_REV_CM3 CM_ENCODE_REV(8, 0)
|
||||
|
||||
/* GCR_ERROR_CAUSE register fields */
|
||||
|
@ -321,6 +324,20 @@ BUILD_CM_Cx_R_(tcid_8_priority, 0x80)
|
|||
#define CM_GCR_SYS_CONFIG2_MAXVPW_SHF 0
|
||||
#define CM_GCR_SYS_CONFIG2_MAXVPW_MSK (_ULCAST_(0xf) << 0)
|
||||
|
||||
/* GCR_L2_PFT_CONTROL register fields */
|
||||
#define CM_GCR_L2_PFT_CONTROL_PAGEMASK_SHF 12
|
||||
#define CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK (_ULCAST_(0xfffff) << 12)
|
||||
#define CM_GCR_L2_PFT_CONTROL_PFTEN_SHF 8
|
||||
#define CM_GCR_L2_PFT_CONTROL_PFTEN_MSK (_ULCAST_(0x1) << 8)
|
||||
#define CM_GCR_L2_PFT_CONTROL_NPFT_SHF 0
|
||||
#define CM_GCR_L2_PFT_CONTROL_NPFT_MSK (_ULCAST_(0xff) << 0)
|
||||
|
||||
/* GCR_L2_PFT_CONTROL_B register fields */
|
||||
#define CM_GCR_L2_PFT_CONTROL_B_CEN_SHF 8
|
||||
#define CM_GCR_L2_PFT_CONTROL_B_CEN_MSK (_ULCAST_(0x1) << 8)
|
||||
#define CM_GCR_L2_PFT_CONTROL_B_PORTID_SHF 0
|
||||
#define CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK (_ULCAST_(0xff) << 0)
|
||||
|
||||
/* GCR_Cx_COHERENCE register fields */
|
||||
#define CM_GCR_Cx_COHERENCE_COHDOMAINEN_SHF 0
|
||||
#define CM_GCR_Cx_COHERENCE_COHDOMAINEN_MSK (_ULCAST_(0xff) << 0)
|
||||
|
|
|
@ -51,11 +51,69 @@ static void mips_sc_disable(void)
|
|||
/* L2 cache is permanently enabled */
|
||||
}
|
||||
|
||||
static void mips_sc_prefetch_enable(void)
|
||||
{
|
||||
unsigned long pftctl;
|
||||
|
||||
if (mips_cm_revision() < CM_REV_CM2_5)
|
||||
return;
|
||||
|
||||
/*
|
||||
* If there is one or more L2 prefetch unit present then enable
|
||||
* prefetching for both code & data, for all ports.
|
||||
*/
|
||||
pftctl = read_gcr_l2_pft_control();
|
||||
if (pftctl & CM_GCR_L2_PFT_CONTROL_NPFT_MSK) {
|
||||
pftctl &= ~CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK;
|
||||
pftctl |= PAGE_MASK & CM_GCR_L2_PFT_CONTROL_PAGEMASK_MSK;
|
||||
pftctl |= CM_GCR_L2_PFT_CONTROL_PFTEN_MSK;
|
||||
write_gcr_l2_pft_control(pftctl);
|
||||
|
||||
pftctl = read_gcr_l2_pft_control_b();
|
||||
pftctl |= CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK;
|
||||
pftctl |= CM_GCR_L2_PFT_CONTROL_B_CEN_MSK;
|
||||
write_gcr_l2_pft_control_b(pftctl);
|
||||
}
|
||||
}
|
||||
|
||||
static void mips_sc_prefetch_disable(void)
|
||||
{
|
||||
unsigned long pftctl;
|
||||
|
||||
if (mips_cm_revision() < CM_REV_CM2_5)
|
||||
return;
|
||||
|
||||
pftctl = read_gcr_l2_pft_control();
|
||||
pftctl &= ~CM_GCR_L2_PFT_CONTROL_PFTEN_MSK;
|
||||
write_gcr_l2_pft_control(pftctl);
|
||||
|
||||
pftctl = read_gcr_l2_pft_control_b();
|
||||
pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_PORTID_MSK;
|
||||
pftctl &= ~CM_GCR_L2_PFT_CONTROL_B_CEN_MSK;
|
||||
write_gcr_l2_pft_control_b(pftctl);
|
||||
}
|
||||
|
||||
static bool mips_sc_prefetch_is_enabled(void)
|
||||
{
|
||||
unsigned long pftctl;
|
||||
|
||||
if (mips_cm_revision() < CM_REV_CM2_5)
|
||||
return false;
|
||||
|
||||
pftctl = read_gcr_l2_pft_control();
|
||||
if (!(pftctl & CM_GCR_L2_PFT_CONTROL_NPFT_MSK))
|
||||
return false;
|
||||
return !!(pftctl & CM_GCR_L2_PFT_CONTROL_PFTEN_MSK);
|
||||
}
|
||||
|
||||
static struct bcache_ops mips_sc_ops = {
|
||||
.bc_enable = mips_sc_enable,
|
||||
.bc_disable = mips_sc_disable,
|
||||
.bc_wback_inv = mips_sc_wback_inv,
|
||||
.bc_inv = mips_sc_inv
|
||||
.bc_inv = mips_sc_inv,
|
||||
.bc_prefetch_enable = mips_sc_prefetch_enable,
|
||||
.bc_prefetch_disable = mips_sc_prefetch_disable,
|
||||
.bc_prefetch_is_enabled = mips_sc_prefetch_is_enabled,
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -186,6 +244,7 @@ int mips_sc_init(void)
|
|||
int found = mips_sc_probe();
|
||||
if (found) {
|
||||
mips_sc_enable();
|
||||
mips_sc_prefetch_enable();
|
||||
bcops = &mips_sc_ops;
|
||||
}
|
||||
return found;
|
||||
|
|
Loading…
Reference in a new issue