|  | @@ -0,0 +1,123 @@
 | 
	
		
			
				|  |  | +/*
 | 
	
		
			
				|  |  | + * Copyright (C) 2005-2006 Atmel Corporation
 | 
	
		
			
				|  |  | + *
 | 
	
		
			
				|  |  | + * This program is free software; you can redistribute it and/or modify
 | 
	
		
			
				|  |  | + * it under the terms of the GNU General Public License version 2 as
 | 
	
		
			
				|  |  | + * published by the Free Software Foundation.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +#include <linux/clk.h>
 | 
	
		
			
				|  |  | +#include <linux/delay.h>
 | 
	
		
			
				|  |  | +#include <linux/dw_dmac.h>
 | 
	
		
			
				|  |  | +#include <linux/fb.h>
 | 
	
		
			
				|  |  | +#include <linux/init.h>
 | 
	
		
			
				|  |  | +#include <linux/platform_device.h>
 | 
	
		
			
				|  |  | +#include <linux/dma-mapping.h>
 | 
	
		
			
				|  |  | +#include <linux/slab.h>
 | 
	
		
			
				|  |  | +#include <linux/gpio.h>
 | 
	
		
			
				|  |  | +#include <linux/spi/spi.h>
 | 
	
		
			
				|  |  | +#include <linux/usb/atmel_usba_udc.h>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#include <mach/atmel-mci.h>
 | 
	
		
			
				|  |  | +#include <linux/atmel-mci.h>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#include <asm/io.h>
 | 
	
		
			
				|  |  | +#include <asm/irq.h>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#include <mach/at32ap700x.h>
 | 
	
		
			
				|  |  | +#include <mach/board.h>
 | 
	
		
			
				|  |  | +#include <mach/hmatrix.h>
 | 
	
		
			
				|  |  | +#include <mach/portmux.h>
 | 
	
		
			
				|  |  | +#include <mach/sram.h>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#include <sound/atmel-abdac.h>
 | 
	
		
			
				|  |  | +#include <sound/atmel-ac97c.h>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#include <video/atmel_lcdc.h>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#include "clock.h"
 | 
	
		
			
				|  |  | +#include "pio.h"
 | 
	
		
			
				|  |  | +#include "pm.h"
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#define PBMEM(base)					\
 | 
	
		
			
				|  |  | +	{						\
 | 
	
		
			
				|  |  | +		.start		= base,			\
 | 
	
		
			
				|  |  | +		.end		= base + 0x3ff,		\
 | 
	
		
			
				|  |  | +		.flags		= IORESOURCE_MEM,	\
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +#define IRQ(num)					\
 | 
	
		
			
				|  |  | +	{						\
 | 
	
		
			
				|  |  | +		.start		= num,			\
 | 
	
		
			
				|  |  | +		.end		= num,			\
 | 
	
		
			
				|  |  | +		.flags		= IORESOURCE_IRQ,	\
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +#define NAMED_IRQ(num, _name)				\
 | 
	
		
			
				|  |  | +	{						\
 | 
	
		
			
				|  |  | +		.start		= num,			\
 | 
	
		
			
				|  |  | +		.end		= num,			\
 | 
	
		
			
				|  |  | +		.name		= _name,		\
 | 
	
		
			
				|  |  | +		.flags		= IORESOURCE_IRQ,	\
 | 
	
		
			
				|  |  | +	}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/* REVISIT these assume *every* device supports DMA, but several
 | 
	
		
			
				|  |  | + * don't ... tc, smc, pio, rtc, watchdog, pwm, ps2, and more.
 | 
	
		
			
				|  |  | + */
 | 
	
		
			
				|  |  | +#define DEFINE_DEV(_name, _id)					\
 | 
	
		
			
				|  |  | +static u64 _name##_id##_dma_mask = DMA_BIT_MASK(32);		\
 | 
	
		
			
				|  |  | +static struct platform_device _name##_id##_device = {		\
 | 
	
		
			
				|  |  | +	.name		= #_name,				\
 | 
	
		
			
				|  |  | +	.id		= _id,					\
 | 
	
		
			
				|  |  | +	.dev		= {					\
 | 
	
		
			
				|  |  | +		.dma_mask = &_name##_id##_dma_mask,		\
 | 
	
		
			
				|  |  | +		.coherent_dma_mask = DMA_BIT_MASK(32),		\
 | 
	
		
			
				|  |  | +	},							\
 | 
	
		
			
				|  |  | +	.resource	= _name##_id##_resource,		\
 | 
	
		
			
				|  |  | +	.num_resources	= ARRAY_SIZE(_name##_id##_resource),	\
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +#define DEFINE_DEV_DATA(_name, _id)				\
 | 
	
		
			
				|  |  | +static u64 _name##_id##_dma_mask = DMA_BIT_MASK(32);		\
 | 
	
		
			
				|  |  | +static struct platform_device _name##_id##_device = {		\
 | 
	
		
			
				|  |  | +	.name		= #_name,				\
 | 
	
		
			
				|  |  | +	.id		= _id,					\
 | 
	
		
			
				|  |  | +	.dev		= {					\
 | 
	
		
			
				|  |  | +		.dma_mask = &_name##_id##_dma_mask,		\
 | 
	
		
			
				|  |  | +		.platform_data	= &_name##_id##_data,		\
 | 
	
		
			
				|  |  | +		.coherent_dma_mask = DMA_BIT_MASK(32),		\
 | 
	
		
			
				|  |  | +	},							\
 | 
	
		
			
				|  |  | +	.resource	= _name##_id##_resource,		\
 | 
	
		
			
				|  |  | +	.num_resources	= ARRAY_SIZE(_name##_id##_resource),	\
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#define select_peripheral(port, pin_mask, periph, flags)	\
 | 
	
		
			
				|  |  | +	at32_select_periph(GPIO_##port##_BASE, pin_mask,	\
 | 
	
		
			
				|  |  | +			   GPIO_##periph, flags)
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +#define DEV_CLK(_name, devname, bus, _index)			\
 | 
	
		
			
				|  |  | +static struct clk devname##_##_name = {				\
 | 
	
		
			
				|  |  | +	.name		= #_name,				\
 | 
	
		
			
				|  |  | +	.dev		= &devname##_device.dev,		\
 | 
	
		
			
				|  |  | +	.parent		= &bus##_clk,				\
 | 
	
		
			
				|  |  | +	.mode		= bus##_clk_mode,			\
 | 
	
		
			
				|  |  | +	.get_rate	= bus##_clk_get_rate,			\
 | 
	
		
			
				|  |  | +	.index		= _index,				\
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static DEFINE_SPINLOCK(pm_lock);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static struct clk osc0;
 | 
	
		
			
				|  |  | +static struct clk osc1;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static unsigned long osc_get_rate(struct clk *clk)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	return at32_board_osc_rates[clk->index];
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +static unsigned long pll_get_rate(struct clk *clk, unsigned long control)
 | 
	
		
			
				|  |  | +{
 | 
	
		
			
				|  |  | +	unsigned long div, mul, rate;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	div = PM_BFEXT(PLLDIV, control) + 1;
 | 
	
		
			
				|  |  | +	mul = PM_BFEXT(PLLMUL, control) + 1;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	rate = clk->parent->get_rate(clk->parent);
 | 
	
		
			
				|  |  | +	rate = (rate + div / 2) / div;
 |