diff options
Diffstat (limited to 'arch/mips/generic')
| -rw-r--r-- | arch/mips/generic/Kconfig | 10 | ||||
| -rw-r--r-- | arch/mips/generic/Makefile | 1 | ||||
| -rw-r--r-- | arch/mips/generic/board-ranchu.c | 93 | ||||
| -rw-r--r-- | arch/mips/generic/irq.c | 18 | 
4 files changed, 113 insertions, 9 deletions
| diff --git a/arch/mips/generic/Kconfig b/arch/mips/generic/Kconfig index 52e0286a1612..2ff3b17bfab1 100644 --- a/arch/mips/generic/Kconfig +++ b/arch/mips/generic/Kconfig @@ -49,4 +49,14 @@ config FIT_IMAGE_FDT_XILFPGA  	  Enable this to include the FDT for the MIPSfpga platform  	  from Imagination Technologies in the FIT kernel image. +config VIRT_BOARD_RANCHU +	bool "Support Ranchu platform for Android emulator" +	help +	  This enables support for the platform used by Android emulator. + +	  Ranchu platform consists of a set of virtual devices. This platform +	  enables emulation of variety of virtual configurations while using +	  Android emulator. Android emulator is based on Qemu, and contains +	  the support for the same set of virtual devices. +  endif diff --git a/arch/mips/generic/Makefile b/arch/mips/generic/Makefile index 874967363dbb..5c31e0c4697d 100644 --- a/arch/mips/generic/Makefile +++ b/arch/mips/generic/Makefile @@ -15,3 +15,4 @@ obj-y += proc.o  obj-$(CONFIG_YAMON_DT_SHIM)		+= yamon-dt.o  obj-$(CONFIG_LEGACY_BOARD_SEAD3)	+= board-sead3.o  obj-$(CONFIG_KEXEC)			+= kexec.o +obj-$(CONFIG_VIRT_BOARD_RANCHU)		+= board-ranchu.o diff --git a/arch/mips/generic/board-ranchu.c b/arch/mips/generic/board-ranchu.c new file mode 100644 index 000000000000..59a8c18fa2cc --- /dev/null +++ b/arch/mips/generic/board-ranchu.c @@ -0,0 +1,93 @@ +/* + * Support code for virtual Ranchu board for MIPS. + * + * Author: Miodrag Dinic <[email protected]> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation;  either version 2 of the  License, or (at your + * option) any later version. + */ + +#include <linux/of_address.h> +#include <linux/types.h> + +#include <asm/machine.h> +#include <asm/mipsregs.h> +#include <asm/time.h> + +#define GOLDFISH_TIMER_LOW		0x00 +#define GOLDFISH_TIMER_HIGH		0x04 + +static __init u64 read_rtc_time(void __iomem *base) +{ +	u32 time_low; +	u32 time_high; + +	/* +	 * Reading the low address latches the high value +	 * as well so there is no fear that we may read +	 * inaccurate high value. +	 */ +	time_low = readl(base + GOLDFISH_TIMER_LOW); +	time_high = readl(base + GOLDFISH_TIMER_HIGH); + +	return ((u64)time_high << 32) | time_low; +} + +static __init unsigned int ranchu_measure_hpt_freq(void) +{ +	u64 rtc_start, rtc_current, rtc_delta; +	unsigned int start, count; +	struct device_node *np; +	void __iomem *rtc_base; + +	np = of_find_compatible_node(NULL, NULL, "google,goldfish-rtc"); +	if (!np) +		panic("%s(): Failed to find 'google,goldfish-rtc' dt node!", +		      __func__); + +	rtc_base = of_iomap(np, 0); +	if (!rtc_base) +		panic("%s(): Failed to ioremap Goldfish RTC base!", __func__); + +	/* +	 * Poll the nanosecond resolution RTC for one +	 * second to calibrate the CPU frequency. +	 */ +	rtc_start = read_rtc_time(rtc_base); +	start = read_c0_count(); + +	do { +		rtc_current = read_rtc_time(rtc_base); +		rtc_delta = rtc_current - rtc_start; +	} while (rtc_delta < NSEC_PER_SEC); + +	count = read_c0_count() - start; + +	/* +	 * Make sure the frequency will be a round number. +	 * Without this correction, the returned value may vary +	 * between subsequent emulation executions. +	 * +	 * TODO: Set this value using device tree. +	 */ +	count += 5000; +	count -= count % 10000; + +	iounmap(rtc_base); + +	return count; +} + +static const struct of_device_id ranchu_of_match[] __initconst = { +	{ +		.compatible = "mti,ranchu", +	}, +	{} +}; + +MIPS_MACHINE(ranchu) = { +	.matches = ranchu_of_match, +	.measure_hpt_freq = ranchu_measure_hpt_freq, +}; diff --git a/arch/mips/generic/irq.c b/arch/mips/generic/irq.c index 394f8161e462..cb7fdaeef426 100644 --- a/arch/mips/generic/irq.c +++ b/arch/mips/generic/irq.c @@ -22,10 +22,10 @@ int get_c0_fdc_int(void)  {  	int mips_cpu_fdc_irq; -	if (cpu_has_veic) -		panic("Unimplemented!"); -	else if (mips_gic_present()) +	if (mips_gic_present())  		mips_cpu_fdc_irq = gic_get_c0_fdc_int(); +	else if (cpu_has_veic) +		panic("Unimplemented!");  	else if (cp0_fdc_irq >= 0)  		mips_cpu_fdc_irq = MIPS_CPU_IRQ_BASE + cp0_fdc_irq;  	else @@ -38,10 +38,10 @@ int get_c0_perfcount_int(void)  {  	int mips_cpu_perf_irq; -	if (cpu_has_veic) -		panic("Unimplemented!"); -	else if (mips_gic_present()) +	if (mips_gic_present())  		mips_cpu_perf_irq = gic_get_c0_perfcount_int(); +	else if (cpu_has_veic) +		panic("Unimplemented!");  	else if (cp0_perfcount_irq >= 0)  		mips_cpu_perf_irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq;  	else @@ -54,10 +54,10 @@ unsigned int get_c0_compare_int(void)  {  	int mips_cpu_timer_irq; -	if (cpu_has_veic) -		panic("Unimplemented!"); -	else if (mips_gic_present()) +	if (mips_gic_present())  		mips_cpu_timer_irq = gic_get_c0_compare_int(); +	else if (cpu_has_veic) +		panic("Unimplemented!");  	else  		mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq; |