Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.13.7.
  1/*
  2 * linux/arch/arm/mach-w90x900/cpu.c
  3 *
  4 * Copyright (c) 2009 Nuvoton corporation.
  5 *
  6 * Wan ZongShun <mcuos.com@gmail.com>
  7 *
  8 * NUC900 series cpu common support
  9 *
 10 * This program is free software; you can redistribute it and/or modify
 11 * it under the terms of the GNU General Public License as published by
 12 * the Free Software Foundation;version 2 of the License.
 13 *
 14 */
 15
 16#include <linux/kernel.h>
 17#include <linux/types.h>
 18#include <linux/interrupt.h>
 19#include <linux/list.h>
 20#include <linux/timer.h>
 21#include <linux/init.h>
 22#include <linux/platform_device.h>
 23#include <linux/io.h>
 24#include <linux/serial_8250.h>
 25#include <linux/delay.h>
 26
 27#include <asm/mach/arch.h>
 28#include <asm/mach/map.h>
 29#include <asm/mach/irq.h>
 30#include <asm/irq.h>
 31#include <asm/system_misc.h>
 32
 33#include <mach/hardware.h>
 34#include <mach/regs-serial.h>
 35#include <mach/regs-clock.h>
 36#include "regs-ebi.h"
 37#include "regs-timer.h"
 38
 39#include "cpu.h"
 40#include "clock.h"
 41#include "nuc9xx.h"
 42
 43/* Initial IO mappings */
 44
 45static struct map_desc nuc900_iodesc[] __initdata = {
 46	IODESC_ENT(IRQ),
 47	IODESC_ENT(GCR),
 48	IODESC_ENT(UART),
 49	IODESC_ENT(TIMER),
 50	IODESC_ENT(EBI),
 51	IODESC_ENT(GPIO),
 52};
 53
 54/* Initial clock declarations. */
 55static DEFINE_CLK(lcd, 0);
 56static DEFINE_CLK(audio, 1);
 57static DEFINE_CLK(fmi, 4);
 58static DEFINE_SUBCLK(ms, 0);
 59static DEFINE_SUBCLK(sd, 1);
 60static DEFINE_CLK(dmac, 5);
 61static DEFINE_CLK(atapi, 6);
 62static DEFINE_CLK(emc, 7);
 63static DEFINE_SUBCLK(rmii, 2);
 64static DEFINE_CLK(usbd, 8);
 65static DEFINE_CLK(usbh, 9);
 66static DEFINE_CLK(g2d, 10);
 67static DEFINE_CLK(pwm, 18);
 68static DEFINE_CLK(ps2, 24);
 69static DEFINE_CLK(kpi, 25);
 70static DEFINE_CLK(wdt, 26);
 71static DEFINE_CLK(gdma, 27);
 72static DEFINE_CLK(adc, 28);
 73static DEFINE_CLK(usi, 29);
 74static DEFINE_CLK(ext, 0);
 75static DEFINE_CLK(timer0, 19);
 76static DEFINE_CLK(timer1, 20);
 77static DEFINE_CLK(timer2, 21);
 78static DEFINE_CLK(timer3, 22);
 79static DEFINE_CLK(timer4, 23);
 80
 81static struct clk_lookup nuc900_clkregs[] = {
 82	DEF_CLKLOOK(&clk_lcd, "nuc900-lcd", NULL),
 83	DEF_CLKLOOK(&clk_audio, "nuc900-ac97", NULL),
 84	DEF_CLKLOOK(&clk_fmi, "nuc900-fmi", NULL),
 85	DEF_CLKLOOK(&clk_ms, "nuc900-fmi", "MS"),
 86	DEF_CLKLOOK(&clk_sd, "nuc900-fmi", "SD"),
 87	DEF_CLKLOOK(&clk_dmac, "nuc900-dmac", NULL),
 88	DEF_CLKLOOK(&clk_atapi, "nuc900-atapi", NULL),
 89	DEF_CLKLOOK(&clk_emc, "nuc900-emc", NULL),
 90	DEF_CLKLOOK(&clk_rmii, "nuc900-emc", "RMII"),
 91	DEF_CLKLOOK(&clk_usbd, "nuc900-usbd", NULL),
 92	DEF_CLKLOOK(&clk_usbh, "nuc900-usbh", NULL),
 93	DEF_CLKLOOK(&clk_g2d, "nuc900-g2d", NULL),
 94	DEF_CLKLOOK(&clk_pwm, "nuc900-pwm", NULL),
 95	DEF_CLKLOOK(&clk_ps2, "nuc900-ps2", NULL),
 96	DEF_CLKLOOK(&clk_kpi, "nuc900-kpi", NULL),
 97	DEF_CLKLOOK(&clk_wdt, "nuc900-wdt", NULL),
 98	DEF_CLKLOOK(&clk_gdma, "nuc900-gdma", NULL),
 99	DEF_CLKLOOK(&clk_adc, "nuc900-ts", NULL),
100	DEF_CLKLOOK(&clk_usi, "nuc900-spi", NULL),
101	DEF_CLKLOOK(&clk_ext, NULL, "ext"),
102	DEF_CLKLOOK(&clk_timer0, NULL, "timer0"),
103	DEF_CLKLOOK(&clk_timer1, NULL, "timer1"),
104	DEF_CLKLOOK(&clk_timer2, NULL, "timer2"),
105	DEF_CLKLOOK(&clk_timer3, NULL, "timer3"),
106	DEF_CLKLOOK(&clk_timer4, NULL, "timer4"),
107};
108
109/* Initial serial platform data */
110
111struct plat_serial8250_port nuc900_uart_data[] = {
112	NUC900_8250PORT(UART0),
113	{},
114};
115
116struct platform_device nuc900_serial_device = {
117	.name			= "serial8250",
118	.id			= PLAT8250_DEV_PLATFORM,
119	.dev			= {
120		.platform_data	= nuc900_uart_data,
121	},
122};
123
124/*Set NUC900 series cpu frequence*/
125static int __init nuc900_set_clkval(unsigned int cpufreq)
126{
127	unsigned int pllclk, ahbclk, apbclk, val;
128
129	pllclk = 0;
130	ahbclk = 0;
131	apbclk = 0;
132
133	switch (cpufreq) {
134	case 66:
135		pllclk = PLL_66MHZ;
136		ahbclk = AHB_CPUCLK_1_1;
137		apbclk = APB_AHB_1_2;
138		break;
139
140	case 100:
141		pllclk = PLL_100MHZ;
142		ahbclk = AHB_CPUCLK_1_1;
143		apbclk = APB_AHB_1_2;
144		break;
145
146	case 120:
147		pllclk = PLL_120MHZ;
148		ahbclk = AHB_CPUCLK_1_2;
149		apbclk = APB_AHB_1_2;
150		break;
151
152	case 166:
153		pllclk = PLL_166MHZ;
154		ahbclk = AHB_CPUCLK_1_2;
155		apbclk = APB_AHB_1_2;
156		break;
157
158	case 200:
159		pllclk = PLL_200MHZ;
160		ahbclk = AHB_CPUCLK_1_2;
161		apbclk = APB_AHB_1_2;
162		break;
163	}
164
165	__raw_writel(pllclk, REG_PLLCON0);
166
167	val = __raw_readl(REG_CLKDIV);
168	val &= ~(0x03 << 24 | 0x03 << 26);
169	val |= (ahbclk << 24 | apbclk << 26);
170	__raw_writel(val, REG_CLKDIV);
171
172	return 	0;
173}
174static int __init nuc900_set_cpufreq(char *str)
175{
176	unsigned long cpufreq, val;
177
178	if (!*str)
179		return 0;
180
181	if (kstrtoul(str, 0, &cpufreq))
182		return 0;
183
184	nuc900_clock_source(NULL, "ext");
185
186	nuc900_set_clkval(cpufreq);
187
188	mdelay(1);
189
190	val = __raw_readl(REG_CKSKEW);
191	val &= ~0xff;
192	val |= DEFAULTSKEW;
193	__raw_writel(val, REG_CKSKEW);
194
195	nuc900_clock_source(NULL, "pll0");
196
197	return 1;
198}
199
200__setup("cpufreq=", nuc900_set_cpufreq);
201
202/*Init NUC900 evb io*/
203
204void __init nuc900_map_io(struct map_desc *mach_desc, int mach_size)
205{
206	unsigned long idcode = 0x0;
207
208	iotable_init(mach_desc, mach_size);
209	iotable_init(nuc900_iodesc, ARRAY_SIZE(nuc900_iodesc));
210
211	idcode = __raw_readl(NUC900PDID);
212	if (idcode == NUC910_CPUID)
213		printk(KERN_INFO "CPU type 0x%08lx is NUC910\n", idcode);
214	else if (idcode == NUC920_CPUID)
215		printk(KERN_INFO "CPU type 0x%08lx is NUC920\n", idcode);
216	else if (idcode == NUC950_CPUID)
217		printk(KERN_INFO "CPU type 0x%08lx is NUC950\n", idcode);
218	else if (idcode == NUC960_CPUID)
219		printk(KERN_INFO "CPU type 0x%08lx is NUC960\n", idcode);
220}
221
222/*Init NUC900 clock*/
223
224void __init nuc900_init_clocks(void)
225{
226	clkdev_add_table(nuc900_clkregs, ARRAY_SIZE(nuc900_clkregs));
227}
228
229#define	WTCR	(TMR_BA + 0x1C)
230#define	WTCLK	(1 << 10)
231#define	WTE	(1 << 7)
232#define	WTRE	(1 << 1)
233
234void nuc9xx_restart(enum reboot_mode mode, const char *cmd)
235{
236	if (mode == REBOOT_SOFT) {
237		/* Jump into ROM at address 0 */
238		soft_restart(0);
239	} else {
240		__raw_writel(WTE | WTRE | WTCLK, WTCR);
241	}
242}