Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d10e025f authored by Atsushi Nemoto's avatar Atsushi Nemoto Committed by Ralf Baechle
Browse files

MIPS: TXx9: Cache fixup



TX39/TX49 can enable/disable I/D cache at runtime.  Add kernel options
to control them.  This is useful to debug some cache-related issues,
such as aliasing or I/D coherency.  Also enable CWF bit for TX49 SoCs.

Signed-off-by: default avatarAtsushi Nemoto <anemo@mba.ocn.ne.jp>
Signed-off-by: default avatarRalf Baechle <ralf@linux-mips.org>
parent 860e546c
Loading
Loading
Loading
Loading
+113 −0
Original line number Original line Diff line number Diff line
@@ -25,6 +25,7 @@
#include <asm/bootinfo.h>
#include <asm/bootinfo.h>
#include <asm/time.h>
#include <asm/time.h>
#include <asm/reboot.h>
#include <asm/reboot.h>
#include <asm/r4kcache.h>
#include <asm/txx9/generic.h>
#include <asm/txx9/generic.h>
#include <asm/txx9/pci.h>
#include <asm/txx9/pci.h>
#ifdef CONFIG_CPU_TX49XX
#ifdef CONFIG_CPU_TX49XX
@@ -186,6 +187,110 @@ static void __init prom_init_cmdline(void)
	}
	}
}
}


static int txx9_ic_disable __initdata;
static int txx9_dc_disable __initdata;

#if defined(CONFIG_CPU_TX49XX)
/* flush all cache on very early stage (before 4k_cache_init) */
static void __init early_flush_dcache(void)
{
	unsigned int conf = read_c0_config();
	unsigned int dc_size = 1 << (12 + ((conf & CONF_DC) >> 6));
	unsigned int linesz = 32;
	unsigned long addr, end;

	end = INDEX_BASE + dc_size / 4;
	/* 4way, waybit=0 */
	for (addr = INDEX_BASE; addr < end; addr += linesz) {
		cache_op(Index_Writeback_Inv_D, addr | 0);
		cache_op(Index_Writeback_Inv_D, addr | 1);
		cache_op(Index_Writeback_Inv_D, addr | 2);
		cache_op(Index_Writeback_Inv_D, addr | 3);
	}
}

static void __init txx9_cache_fixup(void)
{
	unsigned int conf;

	conf = read_c0_config();
	/* flush and disable */
	if (txx9_ic_disable) {
		conf |= TX49_CONF_IC;
		write_c0_config(conf);
	}
	if (txx9_dc_disable) {
		early_flush_dcache();
		conf |= TX49_CONF_DC;
		write_c0_config(conf);
	}

	/* enable cache */
	conf = read_c0_config();
	if (!txx9_ic_disable)
		conf &= ~TX49_CONF_IC;
	if (!txx9_dc_disable)
		conf &= ~TX49_CONF_DC;
	write_c0_config(conf);

	if (conf & TX49_CONF_IC)
		pr_info("TX49XX I-Cache disabled.\n");
	if (conf & TX49_CONF_DC)
		pr_info("TX49XX D-Cache disabled.\n");
}
#elif defined(CONFIG_CPU_TX39XX)
/* flush all cache on very early stage (before tx39_cache_init) */
static void __init early_flush_dcache(void)
{
	unsigned int conf = read_c0_config();
	unsigned int dc_size = 1 << (10 + ((conf & TX39_CONF_DCS_MASK) >>
					   TX39_CONF_DCS_SHIFT));
	unsigned int linesz = 16;
	unsigned long addr, end;

	end = INDEX_BASE + dc_size / 2;
	/* 2way, waybit=0 */
	for (addr = INDEX_BASE; addr < end; addr += linesz) {
		cache_op(Index_Writeback_Inv_D, addr | 0);
		cache_op(Index_Writeback_Inv_D, addr | 1);
	}
}

static void __init txx9_cache_fixup(void)
{
	unsigned int conf;

	conf = read_c0_config();
	/* flush and disable */
	if (txx9_ic_disable) {
		conf &= ~TX39_CONF_ICE;
		write_c0_config(conf);
	}
	if (txx9_dc_disable) {
		early_flush_dcache();
		conf &= ~TX39_CONF_DCE;
		write_c0_config(conf);
	}

	/* enable cache */
	conf = read_c0_config();
	if (!txx9_ic_disable)
		conf |= TX39_CONF_ICE;
	if (!txx9_dc_disable)
		conf |= TX39_CONF_DCE;
	write_c0_config(conf);

	if (!(conf & TX39_CONF_ICE))
		pr_info("TX39XX I-Cache disabled.\n");
	if (!(conf & TX39_CONF_DCE))
		pr_info("TX39XX D-Cache disabled.\n");
}
#else
static inline void txx9_cache_fixup(void)
{
}
#endif

static void __init preprocess_cmdline(void)
static void __init preprocess_cmdline(void)
{
{
	char cmdline[CL_SIZE];
	char cmdline[CL_SIZE];
@@ -204,11 +309,19 @@ static void __init preprocess_cmdline(void)
			if (strict_strtoul(str + 10, 10, &val) == 0)
			if (strict_strtoul(str + 10, 10, &val) == 0)
				txx9_master_clock = val;
				txx9_master_clock = val;
			continue;
			continue;
		} else if (strcmp(str, "icdisable") == 0) {
			txx9_ic_disable = 1;
			continue;
		} else if (strcmp(str, "dcdisable") == 0) {
			txx9_dc_disable = 1;
			continue;
		}
		}
		if (arcs_cmdline[0])
		if (arcs_cmdline[0])
			strcat(arcs_cmdline, " ");
			strcat(arcs_cmdline, " ");
		strcat(arcs_cmdline, str);
		strcat(arcs_cmdline, str);
	}
	}

	txx9_cache_fixup();
}
}


static void __init select_board(void)
static void __init select_board(void)
+8 −10
Original line number Original line Diff line number Diff line
@@ -99,16 +99,14 @@ void __init tx3927_setup(void)
	txx9_gpio_init(TX3927_PIO_REG, 0, 16);
	txx9_gpio_init(TX3927_PIO_REG, 0, 16);


	conf = read_c0_conf();
	conf = read_c0_conf();
	if (!(conf & TX39_CONF_ICE))
	if (conf & TX39_CONF_DCE) {
		printk(KERN_INFO "TX3927 I-Cache disabled.\n");
		if (!(conf & TX39_CONF_WBON))
	if (!(conf & TX39_CONF_DCE))
			pr_info("TX3927 D-Cache WriteThrough.\n");
		printk(KERN_INFO "TX3927 D-Cache disabled.\n");
	else if (!(conf & TX39_CONF_WBON))
		printk(KERN_INFO "TX3927 D-Cache WriteThrough.\n");
		else if (!(conf & TX39_CONF_CWFON))
		else if (!(conf & TX39_CONF_CWFON))
		printk(KERN_INFO "TX3927 D-Cache WriteBack.\n");
			pr_info("TX3927 D-Cache WriteBack.\n");
		else
		else
		printk(KERN_INFO "TX3927 D-Cache WriteBack (CWF) .\n");
			pr_info("TX3927 D-Cache WriteBack (CWF) .\n");
	}
}
}


void __init tx3927_time_init(unsigned int evt_tmrnr, unsigned int src_tmrnr)
void __init tx3927_time_init(unsigned int evt_tmrnr, unsigned int src_tmrnr)
+1 −0
Original line number Original line Diff line number Diff line
@@ -44,6 +44,7 @@ void __init tx4927_setup(void)


	txx9_reg_res_init(TX4927_REV_PCODE(), TX4927_REG_BASE,
	txx9_reg_res_init(TX4927_REV_PCODE(), TX4927_REG_BASE,
			  TX4927_REG_SIZE);
			  TX4927_REG_SIZE);
	set_c0_config(TX49_CONF_CWFON);


	/* SDRAMC,EBUSC are configured by PROM */
	/* SDRAMC,EBUSC are configured by PROM */
	for (i = 0; i < 8; i++) {
	for (i = 0; i < 8; i++) {
+1 −0
Original line number Original line Diff line number Diff line
@@ -47,6 +47,7 @@ void __init tx4938_setup(void)


	txx9_reg_res_init(TX4938_REV_PCODE(), TX4938_REG_BASE,
	txx9_reg_res_init(TX4938_REV_PCODE(), TX4938_REG_BASE,
			  TX4938_REG_SIZE);
			  TX4938_REG_SIZE);
	set_c0_config(TX49_CONF_CWFON);


	/* SDRAMC,EBUSC are configured by PROM */
	/* SDRAMC,EBUSC are configured by PROM */
	for (i = 0; i < 8; i++) {
	for (i = 0; i < 8; i++) {
+1 −10
Original line number Original line Diff line number Diff line
@@ -62,7 +62,6 @@ static void __init jmr3927_time_init(void)
}
}


#define DO_WRITE_THROUGH
#define DO_WRITE_THROUGH
#define DO_ENABLE_CACHE


static void jmr3927_board_init(void);
static void jmr3927_board_init(void);


@@ -77,11 +76,6 @@ static void __init jmr3927_mem_setup(void)
	/* cache setup */
	/* cache setup */
	{
	{
		unsigned int conf;
		unsigned int conf;
#ifdef DO_ENABLE_CACHE
		int mips_ic_disable = 0, mips_dc_disable = 0;
#else
		int mips_ic_disable = 1, mips_dc_disable = 1;
#endif
#ifdef DO_WRITE_THROUGH
#ifdef DO_WRITE_THROUGH
		int mips_config_cwfon = 0;
		int mips_config_cwfon = 0;
		int mips_config_wbon = 0;
		int mips_config_wbon = 0;
@@ -91,10 +85,7 @@ static void __init jmr3927_mem_setup(void)
#endif
#endif


		conf = read_c0_conf();
		conf = read_c0_conf();
		conf &= ~(TX39_CONF_ICE | TX39_CONF_DCE |
		conf &= ~(TX39_CONF_WBON | TX39_CONF_CWFON);
			  TX39_CONF_WBON | TX39_CONF_CWFON);
		conf |= mips_ic_disable ? 0 : TX39_CONF_ICE;
		conf |= mips_dc_disable ? 0 : TX39_CONF_DCE;
		conf |= mips_config_wbon ? TX39_CONF_WBON : 0;
		conf |= mips_config_wbon ? TX39_CONF_WBON : 0;
		conf |= mips_config_cwfon ? TX39_CONF_CWFON : 0;
		conf |= mips_config_cwfon ? TX39_CONF_CWFON : 0;


Loading