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:
Paul Burton
2015-09-22 10:10:54 -07:00
committed by Ralf Baechle
parent 37f2a174c4
commit 4d03551692
2 changed files with 77 additions and 1 deletions

View File

@@ -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;