From 4e57ea9a2e8e807e20f64d5b53fbee2c7c9e87ae Mon Sep 17 00:00:00 2001 From: Russell King Date: Fri, 2 Jan 2009 12:34:31 +0000 Subject: [ARM] dma: remove usage of dmamode_t from MXC platform support Signed-off-by: Russell King --- arch/arm/plat-mxc/dma-mx1-mx2.c | 6 +++--- arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/plat-mxc/dma-mx1-mx2.c b/arch/arm/plat-mxc/dma-mx1-mx2.c index 214274344442..92bc4f6bd019 100644 --- a/arch/arm/plat-mxc/dma-mx1-mx2.c +++ b/arch/arm/plat-mxc/dma-mx1-mx2.c @@ -114,7 +114,7 @@ struct imx_dma_channel { void (*err_handler) (int, void *, int errcode); void (*prog_handler) (int, void *, struct scatterlist *); void *data; - dmamode_t dma_mode; + unsigned int dma_mode; struct scatterlist *sg; unsigned int resbytes; int dma_num; @@ -193,7 +193,7 @@ static inline int imx_dma_sg_next(int channel, struct scatterlist *sg) int imx_dma_setup_single(int channel, dma_addr_t dma_address, unsigned int dma_length, unsigned int dev_addr, - dmamode_t dmamode) + unsigned int dmamode) { struct imx_dma_channel *imxdma = &imx_dma_channels[channel]; @@ -288,7 +288,7 @@ int imx_dma_setup_sg(int channel, struct scatterlist *sg, unsigned int sgcount, unsigned int dma_length, unsigned int dev_addr, - dmamode_t dmamode) + unsigned int dmamode) { struct imx_dma_channel *imxdma = &imx_dma_channels[channel]; diff --git a/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h b/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h index 6cc6f0c8cb25..c162920b13a9 100644 --- a/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h +++ b/arch/arm/plat-mxc/include/mach/dma-mx1-mx2.h @@ -54,12 +54,12 @@ imx_dma_config_burstlen(int channel, unsigned int burstlen); int imx_dma_setup_single(int channel, dma_addr_t dma_address, unsigned int dma_length, unsigned int dev_addr, - dmamode_t dmamode); + unsigned int dmamode); int imx_dma_setup_sg(int channel, struct scatterlist *sg, unsigned int sgcount, unsigned int dma_length, - unsigned int dev_addr, dmamode_t dmamode); + unsigned int dev_addr, unsigned int dmamode); int imx_dma_setup_handlers(int channel, -- cgit v1.2.3 From 1febd91acff907152e61eb5ad0a82dd8d7db21c6 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Thu, 26 Feb 2009 13:58:37 -0700 Subject: Revert "i.MX31: framebuffer driver" This reverts commit 86528da229a448577a8401a17c295883640d336c. This version of the patch was tab-to-space corrupted before application. Signed-off-by: Dan Williams --- arch/arm/plat-mxc/include/mach/mx3fb.h | 38 - drivers/video/Kconfig | 12 - drivers/video/Makefile | 1 - drivers/video/mx3fb.c | 1555 -------------------------------- 4 files changed, 1606 deletions(-) delete mode 100644 arch/arm/plat-mxc/include/mach/mx3fb.h delete mode 100644 drivers/video/mx3fb.c (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/plat-mxc/include/mach/mx3fb.h b/arch/arm/plat-mxc/include/mach/mx3fb.h deleted file mode 100644 index e391a76ca87d..000000000000 --- a/arch/arm/plat-mxc/include/mach/mx3fb.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2008 - * Guennadi Liakhovetski, DENX Software Engineering, - * - * 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. - */ - -#ifndef __ASM_ARCH_MX3FB_H__ -#define __ASM_ARCH_MX3FB_H__ - -#include -#include - -/* Proprietary FB_SYNC_ flags */ -#define FB_SYNC_OE_ACT_HIGH 0x80000000 -#define FB_SYNC_CLK_INVERT 0x40000000 -#define FB_SYNC_DATA_INVERT 0x20000000 -#define FB_SYNC_CLK_IDLE_EN 0x10000000 -#define FB_SYNC_SHARP_MODE 0x08000000 -#define FB_SYNC_SWAP_RGB 0x04000000 -#define FB_SYNC_CLK_SEL_EN 0x02000000 - -/** - * struct mx3fb_platform_data - mx3fb platform data - * - * @dma_dev: pointer to the dma-device, used for dma-slave connection - * @mode: pointer to a platform-provided per mxc_register_fb() videomode - */ -struct mx3fb_platform_data { - struct device *dma_dev; - const char *name; - const struct fb_videomode *mode; - int num_modes; -}; - -#endif diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index bf0af660df8a..6f3f3bff3832 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -2125,18 +2125,6 @@ config FB_PRE_INIT_FB Select this option if display contents should be inherited as set by the bootloader. -config FB_MX3 - tristate "MX3 Framebuffer support" - depends on FB && MX3_IPU - select FB_CFB_FILLRECT - select FB_CFB_COPYAREA - select FB_CFB_IMAGEBLIT - default y - help - This is a framebuffer device for the i.MX31 LCD Controller. So - far only synchronous displays are supported. If you plan to use - an LCD display with your i.MX31 system, say Y here. - source "drivers/video/omap/Kconfig" source "drivers/video/backlight/Kconfig" diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 2a998ca6181d..be2b657546ef 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -132,7 +132,6 @@ obj-$(CONFIG_FB_VGA16) += vga16fb.o obj-$(CONFIG_FB_OF) += offb.o obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o -obj-$(CONFIG_FB_MX3) += mx3fb.o # the test framebuffer is last obj-$(CONFIG_FB_VIRTUAL) += vfb.o diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c deleted file mode 100644 index 8a75d05f4334..000000000000 --- a/drivers/video/mx3fb.c +++ /dev/null @@ -1,1555 +0,0 @@ -/* - * Copyright (C) 2008 - * Guennadi Liakhovetski, DENX Software Engineering, - * - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. - * - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#define MX3FB_NAME "mx3_sdc_fb" - -#define MX3FB_REG_OFFSET 0xB4 - -/* SDC Registers */ -#define SDC_COM_CONF (0xB4 - MX3FB_REG_OFFSET) -#define SDC_GW_CTRL (0xB8 - MX3FB_REG_OFFSET) -#define SDC_FG_POS (0xBC - MX3FB_REG_OFFSET) -#define SDC_BG_POS (0xC0 - MX3FB_REG_OFFSET) -#define SDC_CUR_POS (0xC4 - MX3FB_REG_OFFSET) -#define SDC_PWM_CTRL (0xC8 - MX3FB_REG_OFFSET) -#define SDC_CUR_MAP (0xCC - MX3FB_REG_OFFSET) -#define SDC_HOR_CONF (0xD0 - MX3FB_REG_OFFSET) -#define SDC_VER_CONF (0xD4 - MX3FB_REG_OFFSET) -#define SDC_SHARP_CONF_1 (0xD8 - MX3FB_REG_OFFSET) -#define SDC_SHARP_CONF_2 (0xDC - MX3FB_REG_OFFSET) - -/* Register bits */ -#define SDC_COM_TFT_COLOR 0x00000001UL -#define SDC_COM_FG_EN 0x00000010UL -#define SDC_COM_GWSEL 0x00000020UL -#define SDC_COM_GLB_A 0x00000040UL -#define SDC_COM_KEY_COLOR_G 0x00000080UL -#define SDC_COM_BG_EN 0x00000200UL -#define SDC_COM_SHARP 0x00001000UL - -#define SDC_V_SYNC_WIDTH_L 0x00000001UL - -/* Display Interface registers */ -#define DI_DISP_IF_CONF (0x0124 - MX3FB_REG_OFFSET) -#define DI_DISP_SIG_POL (0x0128 - MX3FB_REG_OFFSET) -#define DI_SER_DISP1_CONF (0x012C - MX3FB_REG_OFFSET) -#define DI_SER_DISP2_CONF (0x0130 - MX3FB_REG_OFFSET) -#define DI_HSP_CLK_PER (0x0134 - MX3FB_REG_OFFSET) -#define DI_DISP0_TIME_CONF_1 (0x0138 - MX3FB_REG_OFFSET) -#define DI_DISP0_TIME_CONF_2 (0x013C - MX3FB_REG_OFFSET) -#define DI_DISP0_TIME_CONF_3 (0x0140 - MX3FB_REG_OFFSET) -#define DI_DISP1_TIME_CONF_1 (0x0144 - MX3FB_REG_OFFSET) -#define DI_DISP1_TIME_CONF_2 (0x0148 - MX3FB_REG_OFFSET) -#define DI_DISP1_TIME_CONF_3 (0x014C - MX3FB_REG_OFFSET) -#define DI_DISP2_TIME_CONF_1 (0x0150 - MX3FB_REG_OFFSET) -#define DI_DISP2_TIME_CONF_2 (0x0154 - MX3FB_REG_OFFSET) -#define DI_DISP2_TIME_CONF_3 (0x0158 - MX3FB_REG_OFFSET) -#define DI_DISP3_TIME_CONF (0x015C - MX3FB_REG_OFFSET) -#define DI_DISP0_DB0_MAP (0x0160 - MX3FB_REG_OFFSET) -#define DI_DISP0_DB1_MAP (0x0164 - MX3FB_REG_OFFSET) -#define DI_DISP0_DB2_MAP (0x0168 - MX3FB_REG_OFFSET) -#define DI_DISP0_CB0_MAP (0x016C - MX3FB_REG_OFFSET) -#define DI_DISP0_CB1_MAP (0x0170 - MX3FB_REG_OFFSET) -#define DI_DISP0_CB2_MAP (0x0174 - MX3FB_REG_OFFSET) -#define DI_DISP1_DB0_MAP (0x0178 - MX3FB_REG_OFFSET) -#define DI_DISP1_DB1_MAP (0x017C - MX3FB_REG_OFFSET) -#define DI_DISP1_DB2_MAP (0x0180 - MX3FB_REG_OFFSET) -#define DI_DISP1_CB0_MAP (0x0184 - MX3FB_REG_OFFSET) -#define DI_DISP1_CB1_MAP (0x0188 - MX3FB_REG_OFFSET) -#define DI_DISP1_CB2_MAP (0x018C - MX3FB_REG_OFFSET) -#define DI_DISP2_DB0_MAP (0x0190 - MX3FB_REG_OFFSET) -#define DI_DISP2_DB1_MAP (0x0194 - MX3FB_REG_OFFSET) -#define DI_DISP2_DB2_MAP (0x0198 - MX3FB_REG_OFFSET) -#define DI_DISP2_CB0_MAP (0x019C - MX3FB_REG_OFFSET) -#define DI_DISP2_CB1_MAP (0x01A0 - MX3FB_REG_OFFSET) -#define DI_DISP2_CB2_MAP (0x01A4 - MX3FB_REG_OFFSET) -#define DI_DISP3_B0_MAP (0x01A8 - MX3FB_REG_OFFSET) -#define DI_DISP3_B1_MAP (0x01AC - MX3FB_REG_OFFSET) -#define DI_DISP3_B2_MAP (0x01B0 - MX3FB_REG_OFFSET) -#define DI_DISP_ACC_CC (0x01B4 - MX3FB_REG_OFFSET) -#define DI_DISP_LLA_CONF (0x01B8 - MX3FB_REG_OFFSET) -#define DI_DISP_LLA_DATA (0x01BC - MX3FB_REG_OFFSET) - -/* DI_DISP_SIG_POL bits */ -#define DI_D3_VSYNC_POL_SHIFT 28 -#define DI_D3_HSYNC_POL_SHIFT 27 -#define DI_D3_DRDY_SHARP_POL_SHIFT 26 -#define DI_D3_CLK_POL_SHIFT 25 -#define DI_D3_DATA_POL_SHIFT 24 - -/* DI_DISP_IF_CONF bits */ -#define DI_D3_CLK_IDLE_SHIFT 26 -#define DI_D3_CLK_SEL_SHIFT 25 -#define DI_D3_DATAMSK_SHIFT 24 - -enum ipu_panel { - IPU_PANEL_SHARP_TFT, - IPU_PANEL_TFT, -}; - -struct ipu_di_signal_cfg { - unsigned datamask_en:1; - unsigned clksel_en:1; - unsigned clkidle_en:1; - unsigned data_pol:1; /* true = inverted */ - unsigned clk_pol:1; /* true = rising edge */ - unsigned enable_pol:1; - unsigned Hsync_pol:1; /* true = active high */ - unsigned Vsync_pol:1; -}; - -static const struct fb_videomode mx3fb_modedb[] = { - { - /* 240x320 @ 60 Hz */ - .name = "Sharp-QVGA", - .refresh = 60, - .xres = 240, - .yres = 320, - .pixclock = 185925, - .left_margin = 9, - .right_margin = 16, - .upper_margin = 7, - .lower_margin = 9, - .hsync_len = 1, - .vsync_len = 1, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE | - FB_SYNC_CLK_INVERT | FB_SYNC_DATA_INVERT | - FB_SYNC_CLK_IDLE_EN, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - }, { - /* 240x33 @ 60 Hz */ - .name = "Sharp-CLI", - .refresh = 60, - .xres = 240, - .yres = 33, - .pixclock = 185925, - .left_margin = 9, - .right_margin = 16, - .upper_margin = 7, - .lower_margin = 9 + 287, - .hsync_len = 1, - .vsync_len = 1, - .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE | - FB_SYNC_CLK_INVERT | FB_SYNC_DATA_INVERT | - FB_SYNC_CLK_IDLE_EN, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - }, { - /* 640x480 @ 60 Hz */ - .name = "NEC-VGA", - .refresh = 60, - .xres = 640, - .yres = 480, - .pixclock = 38255, - .left_margin = 144, - .right_margin = 0, - .upper_margin = 34, - .lower_margin = 40, - .hsync_len = 1, - .vsync_len = 1, - .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - }, { - /* NTSC TV output */ - .name = "TV-NTSC", - .refresh = 60, - .xres = 640, - .yres = 480, - .pixclock = 37538, - .left_margin = 38, - .right_margin = 858 - 640 - 38 - 3, - .upper_margin = 36, - .lower_margin = 518 - 480 - 36 - 1, - .hsync_len = 3, - .vsync_len = 1, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - }, { - /* PAL TV output */ - .name = "TV-PAL", - .refresh = 50, - .xres = 640, - .yres = 480, - .pixclock = 37538, - .left_margin = 38, - .right_margin = 960 - 640 - 38 - 32, - .upper_margin = 32, - .lower_margin = 555 - 480 - 32 - 3, - .hsync_len = 32, - .vsync_len = 3, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - }, { - /* TV output VGA mode, 640x480 @ 65 Hz */ - .name = "TV-VGA", - .refresh = 60, - .xres = 640, - .yres = 480, - .pixclock = 40574, - .left_margin = 35, - .right_margin = 45, - .upper_margin = 9, - .lower_margin = 1, - .hsync_len = 46, - .vsync_len = 5, - .sync = 0, - .vmode = FB_VMODE_NONINTERLACED, - .flag = 0, - }, -}; - -struct mx3fb_data { - struct fb_info *fbi; - int backlight_level; - void __iomem *reg_base; - spinlock_t lock; - struct device *dev; - - uint32_t h_start_width; - uint32_t v_start_width; -}; - -struct dma_chan_request { - struct mx3fb_data *mx3fb; - enum ipu_channel id; -}; - -/* MX3 specific framebuffer information. */ -struct mx3fb_info { - int blank; - enum ipu_channel ipu_ch; - uint32_t cur_ipu_buf; - - u32 pseudo_palette[16]; - - struct completion flip_cmpl; - struct mutex mutex; /* Protects fb-ops */ - struct mx3fb_data *mx3fb; - struct idmac_channel *idmac_channel; - struct dma_async_tx_descriptor *txd; - dma_cookie_t cookie; - struct scatterlist sg[2]; - - u32 sync; /* preserve var->sync flags */ -}; - -static void mx3fb_dma_done(void *); - -/* Used fb-mode and bpp. Can be set on kernel command line, therefore file-static. */ -static const char *fb_mode; -static unsigned long default_bpp = 16; - -static u32 mx3fb_read_reg(struct mx3fb_data *mx3fb, unsigned long reg) -{ - return __raw_readl(mx3fb->reg_base + reg); -} - -static void mx3fb_write_reg(struct mx3fb_data *mx3fb, u32 value, unsigned long reg) -{ - __raw_writel(value, mx3fb->reg_base + reg); -} - -static const uint32_t di_mappings[] = { - 0x1600AAAA, 0x00E05555, 0x00070000, 3, /* RGB888 */ - 0x0005000F, 0x000B000F, 0x0011000F, 1, /* RGB666 */ - 0x0011000F, 0x000B000F, 0x0005000F, 1, /* BGR666 */ - 0x0004003F, 0x000A000F, 0x000F003F, 1 /* RGB565 */ -}; - -static void sdc_fb_init(struct mx3fb_info *fbi) -{ - struct mx3fb_data *mx3fb = fbi->mx3fb; - uint32_t reg; - - reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); - - mx3fb_write_reg(mx3fb, reg | SDC_COM_BG_EN, SDC_COM_CONF); -} - -/* Returns enabled flag before uninit */ -static uint32_t sdc_fb_uninit(struct mx3fb_info *fbi) -{ - struct mx3fb_data *mx3fb = fbi->mx3fb; - uint32_t reg; - - reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); - - mx3fb_write_reg(mx3fb, reg & ~SDC_COM_BG_EN, SDC_COM_CONF); - - return reg & SDC_COM_BG_EN; -} - -static void sdc_enable_channel(struct mx3fb_info *mx3_fbi) -{ - struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; - struct idmac_channel *ichan = mx3_fbi->idmac_channel; - struct dma_chan *dma_chan = &ichan->dma_chan; - unsigned long flags; - dma_cookie_t cookie; - - dev_dbg(mx3fb->dev, "mx3fbi %p, desc %p, sg %p\n", mx3_fbi, - to_tx_desc(mx3_fbi->txd), to_tx_desc(mx3_fbi->txd)->sg); - - /* This enables the channel */ - if (mx3_fbi->cookie < 0) { - mx3_fbi->txd = dma_chan->device->device_prep_slave_sg(dma_chan, - &mx3_fbi->sg[0], 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT); - if (!mx3_fbi->txd) { - dev_err(mx3fb->dev, "Cannot allocate descriptor on %d\n", - dma_chan->chan_id); - return; - } - - mx3_fbi->txd->callback_param = mx3_fbi->txd; - mx3_fbi->txd->callback = mx3fb_dma_done; - - cookie = mx3_fbi->txd->tx_submit(mx3_fbi->txd); - dev_dbg(mx3fb->dev, "%d: Submit %p #%d [%c]\n", __LINE__, - mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+'); - } else { - if (!mx3_fbi->txd || !mx3_fbi->txd->tx_submit) { - dev_err(mx3fb->dev, "Cannot enable channel %d\n", - dma_chan->chan_id); - return; - } - - /* Just re-activate the same buffer */ - dma_async_issue_pending(dma_chan); - cookie = mx3_fbi->cookie; - dev_dbg(mx3fb->dev, "%d: Re-submit %p #%d [%c]\n", __LINE__, - mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+'); - } - - if (cookie >= 0) { - spin_lock_irqsave(&mx3fb->lock, flags); - sdc_fb_init(mx3_fbi); - mx3_fbi->cookie = cookie; - spin_unlock_irqrestore(&mx3fb->lock, flags); - } - - /* - * Attention! Without this msleep the channel keeps generating - * interrupts. Next sdc_set_brightness() is going to be called - * from mx3fb_blank(). - */ - msleep(2); -} - -static void sdc_disable_channel(struct mx3fb_info *mx3_fbi) -{ - struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; - uint32_t enabled; - unsigned long flags; - - spin_lock_irqsave(&mx3fb->lock, flags); - - enabled = sdc_fb_uninit(mx3_fbi); - - spin_unlock_irqrestore(&mx3fb->lock, flags); - - mx3_fbi->txd->chan->device->device_terminate_all(mx3_fbi->txd->chan); - mx3_fbi->txd = NULL; - mx3_fbi->cookie = -EINVAL; -} - -/** - * sdc_set_window_pos() - set window position of the respective plane. - * @mx3fb: mx3fb context. - * @channel: IPU DMAC channel ID. - * @x_pos: X coordinate relative to the top left corner to place window at. - * @y_pos: Y coordinate relative to the top left corner to place window at. - * @return: 0 on success or negative error code on failure. - */ -static int sdc_set_window_pos(struct mx3fb_data *mx3fb, enum ipu_channel channel, - int16_t x_pos, int16_t y_pos) -{ - x_pos += mx3fb->h_start_width; - y_pos += mx3fb->v_start_width; - - if (channel != IDMAC_SDC_0) - return -EINVAL; - - mx3fb_write_reg(mx3fb, (x_pos << 16) | y_pos, SDC_BG_POS); - return 0; -} - -/** - * sdc_init_panel() - initialize a synchronous LCD panel. - * @mx3fb: mx3fb context. - * @panel: panel type. - * @pixel_clk: desired pixel clock frequency in Hz. - * @width: width of panel in pixels. - * @height: height of panel in pixels. - * @pixel_fmt: pixel format of buffer as FOURCC ASCII code. - * @h_start_width: number of pixel clocks between the HSYNC signal pulse - * and the start of valid data. - * @h_sync_width: width of the HSYNC signal in units of pixel clocks. - * @h_end_width: number of pixel clocks between the end of valid data - * and the HSYNC signal for next line. - * @v_start_width: number of lines between the VSYNC signal pulse and the - * start of valid data. - * @v_sync_width: width of the VSYNC signal in units of lines - * @v_end_width: number of lines between the end of valid data and the - * VSYNC signal for next frame. - * @sig: bitfield of signal polarities for LCD interface. - * @return: 0 on success or negative error code on failure. - */ -static int sdc_init_panel(struct mx3fb_data *mx3fb, enum ipu_panel panel, - uint32_t pixel_clk, - uint16_t width, uint16_t height, - enum pixel_fmt pixel_fmt, - uint16_t h_start_width, uint16_t h_sync_width, - uint16_t h_end_width, uint16_t v_start_width, - uint16_t v_sync_width, uint16_t v_end_width, - struct ipu_di_signal_cfg sig) -{ - unsigned long lock_flags; - uint32_t reg; - uint32_t old_conf; - uint32_t div; - struct clk *ipu_clk; - - dev_dbg(mx3fb->dev, "panel size = %d x %d", width, height); - - if (v_sync_width == 0 || h_sync_width == 0) - return -EINVAL; - - /* Init panel size and blanking periods */ - reg = ((uint32_t) (h_sync_width - 1) << 26) | - ((uint32_t) (width + h_start_width + h_end_width - 1) << 16); - mx3fb_write_reg(mx3fb, reg, SDC_HOR_CONF); - -#ifdef DEBUG - printk(KERN_CONT " hor_conf %x,", reg); -#endif - - reg = ((uint32_t) (v_sync_width - 1) << 26) | SDC_V_SYNC_WIDTH_L | - ((uint32_t) (height + v_start_width + v_end_width - 1) << 16); - mx3fb_write_reg(mx3fb, reg, SDC_VER_CONF); - -#ifdef DEBUG - printk(KERN_CONT " ver_conf %x\n", reg); -#endif - - mx3fb->h_start_width = h_start_width; - mx3fb->v_start_width = v_start_width; - - switch (panel) { - case IPU_PANEL_SHARP_TFT: - mx3fb_write_reg(mx3fb, 0x00FD0102L, SDC_SHARP_CONF_1); - mx3fb_write_reg(mx3fb, 0x00F500F4L, SDC_SHARP_CONF_2); - mx3fb_write_reg(mx3fb, SDC_COM_SHARP | SDC_COM_TFT_COLOR, SDC_COM_CONF); - break; - case IPU_PANEL_TFT: - mx3fb_write_reg(mx3fb, SDC_COM_TFT_COLOR, SDC_COM_CONF); - break; - default: - return -EINVAL; - } - - /* Init clocking */ - - /* - * Calculate divider: fractional part is 4 bits so simply multiple by - * 24 to get fractional part, as long as we stay under ~250MHz and on - * i.MX31 it (HSP_CLK) is <= 178MHz. Currently 128.267MHz - */ - dev_dbg(mx3fb->dev, "pixel clk = %d\n", pixel_clk); - - ipu_clk = clk_get(mx3fb->dev, "ipu_clk"); - div = clk_get_rate(ipu_clk) * 16 / pixel_clk; - clk_put(ipu_clk); - - if (div < 0x40) { /* Divider less than 4 */ - dev_dbg(mx3fb->dev, - "InitPanel() - Pixel clock divider less than 4\n"); - div = 0x40; - } - - spin_lock_irqsave(&mx3fb->lock, lock_flags); - - /* - * DISP3_IF_CLK_DOWN_WR is half the divider value and 2 fraction bits - * fewer. Subtract 1 extra from DISP3_IF_CLK_DOWN_WR based on timing - * debug. DISP3_IF_CLK_UP_WR is 0 - */ - mx3fb_write_reg(mx3fb, (((div / 8) - 1) << 22) | div, DI_DISP3_TIME_CONF); - - /* DI settings */ - old_conf = mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF) & 0x78FFFFFF; - old_conf |= sig.datamask_en << DI_D3_DATAMSK_SHIFT | - sig.clksel_en << DI_D3_CLK_SEL_SHIFT | - sig.clkidle_en << DI_D3_CLK_IDLE_SHIFT; - mx3fb_write_reg(mx3fb, old_conf, DI_DISP_IF_CONF); - - old_conf = mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL) & 0xE0FFFFFF; - old_conf |= sig.data_pol << DI_D3_DATA_POL_SHIFT | - sig.clk_pol << DI_D3_CLK_POL_SHIFT | - sig.enable_pol << DI_D3_DRDY_SHARP_POL_SHIFT | - sig.Hsync_pol << DI_D3_HSYNC_POL_SHIFT | - sig.Vsync_pol << DI_D3_VSYNC_POL_SHIFT; - mx3fb_write_reg(mx3fb, old_conf, DI_DISP_SIG_POL); - - switch (pixel_fmt) { - case IPU_PIX_FMT_RGB24: - mx3fb_write_reg(mx3fb, di_mappings[0], DI_DISP3_B0_MAP); - mx3fb_write_reg(mx3fb, di_mappings[1], DI_DISP3_B1_MAP); - mx3fb_write_reg(mx3fb, di_mappings[2], DI_DISP3_B2_MAP); - mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) | - ((di_mappings[3] - 1) << 12), DI_DISP_ACC_CC); - break; - case IPU_PIX_FMT_RGB666: - mx3fb_write_reg(mx3fb, di_mappings[4], DI_DISP3_B0_MAP); - mx3fb_write_reg(mx3fb, di_mappings[5], DI_DISP3_B1_MAP); - mx3fb_write_reg(mx3fb, di_mappings[6], DI_DISP3_B2_MAP); - mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) | - ((di_mappings[7] - 1) << 12), DI_DISP_ACC_CC); - break; - case IPU_PIX_FMT_BGR666: - mx3fb_write_reg(mx3fb, di_mappings[8], DI_DISP3_B0_MAP); - mx3fb_write_reg(mx3fb, di_mappings[9], DI_DISP3_B1_MAP); - mx3fb_write_reg(mx3fb, di_mappings[10], DI_DISP3_B2_MAP); - mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) | - ((di_mappings[11] - 1) << 12), DI_DISP_ACC_CC); - break; - default: - mx3fb_write_reg(mx3fb, di_mappings[12], DI_DISP3_B0_MAP); - mx3fb_write_reg(mx3fb, di_mappings[13], DI_DISP3_B1_MAP); - mx3fb_write_reg(mx3fb, di_mappings[14], DI_DISP3_B2_MAP); - mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) | - ((di_mappings[15] - 1) << 12), DI_DISP_ACC_CC); - break; - } - - spin_unlock_irqrestore(&mx3fb->lock, lock_flags); - - dev_dbg(mx3fb->dev, "DI_DISP_IF_CONF = 0x%08X\n", - mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF)); - dev_dbg(mx3fb->dev, "DI_DISP_SIG_POL = 0x%08X\n", - mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL)); - dev_dbg(mx3fb->dev, "DI_DISP3_TIME_CONF = 0x%08X\n", - mx3fb_read_reg(mx3fb, DI_DISP3_TIME_CONF)); - - return 0; -} - -/** - * sdc_set_color_key() - set the transparent color key for SDC graphic plane. - * @mx3fb: mx3fb context. - * @channel: IPU DMAC channel ID. - * @enable: boolean to enable or disable color keyl. - * @color_key: 24-bit RGB color to use as transparent color key. - * @return: 0 on success or negative error code on failure. - */ -static int sdc_set_color_key(struct mx3fb_data *mx3fb, enum ipu_channel channel, - bool enable, uint32_t color_key) -{ - uint32_t reg, sdc_conf; - unsigned long lock_flags; - - spin_lock_irqsave(&mx3fb->lock, lock_flags); - - sdc_conf = mx3fb_read_reg(mx3fb, SDC_COM_CONF); - if (channel == IDMAC_SDC_0) - sdc_conf &= ~SDC_COM_GWSEL; - else - sdc_conf |= SDC_COM_GWSEL; - - if (enable) { - reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0xFF000000L; - mx3fb_write_reg(mx3fb, reg | (color_key & 0x00FFFFFFL), - SDC_GW_CTRL); - - sdc_conf |= SDC_COM_KEY_COLOR_G; - } else { - sdc_conf &= ~SDC_COM_KEY_COLOR_G; - } - mx3fb_write_reg(mx3fb, sdc_conf, SDC_COM_CONF); - - spin_unlock_irqrestore(&mx3fb->lock, lock_flags); - - return 0; -} - -/** - * sdc_set_global_alpha() - set global alpha blending modes. - * @mx3fb: mx3fb context. - * @enable: boolean to enable or disable global alpha blending. If disabled, - * per pixel blending is used. - * @alpha: global alpha value. - * @return: 0 on success or negative error code on failure. - */ -static int sdc_set_global_alpha(struct mx3fb_data *mx3fb, bool enable, uint8_t alpha) -{ - uint32_t reg; - unsigned long lock_flags; - - spin_lock_irqsave(&mx3fb->lock, lock_flags); - - if (enable) { - reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0x00FFFFFFL; - mx3fb_write_reg(mx3fb, reg | ((uint32_t) alpha << 24), SDC_GW_CTRL); - - reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); - mx3fb_write_reg(mx3fb, reg | SDC_COM_GLB_A, SDC_COM_CONF); - } else { - reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); - mx3fb_write_reg(mx3fb, reg & ~SDC_COM_GLB_A, SDC_COM_CONF); - } - - spin_unlock_irqrestore(&mx3fb->lock, lock_flags); - - return 0; -} - -static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value) -{ - /* This might be board-specific */ - mx3fb_write_reg(mx3fb, 0x03000000UL | value << 16, SDC_PWM_CTRL); - return; -} - -static uint32_t bpp_to_pixfmt(int bpp) -{ - uint32_t pixfmt = 0; - switch (bpp) { - case 24: - pixfmt = IPU_PIX_FMT_BGR24; - break; - case 32: - pixfmt = IPU_PIX_FMT_BGR32; - break; - case 16: - pixfmt = IPU_PIX_FMT_RGB565; - break; - } - return pixfmt; -} - -static int mx3fb_blank(int blank, struct fb_info *fbi); -static int mx3fb_map_video_memory(struct fb_info *fbi); -static int mx3fb_unmap_video_memory(struct fb_info *fbi); - -/** - * mx3fb_set_fix() - set fixed framebuffer parameters from variable settings. - * @info: framebuffer information pointer - * @return: 0 on success or negative error code on failure. - */ -static int mx3fb_set_fix(struct fb_info *fbi) -{ - struct fb_fix_screeninfo *fix = &fbi->fix; - struct fb_var_screeninfo *var = &fbi->var; - - strncpy(fix->id, "DISP3 BG", 8); - - fix->line_length = var->xres_virtual * var->bits_per_pixel / 8; - - fix->type = FB_TYPE_PACKED_PIXELS; - fix->accel = FB_ACCEL_NONE; - fix->visual = FB_VISUAL_TRUECOLOR; - fix->xpanstep = 1; - fix->ypanstep = 1; - - return 0; -} - -static void mx3fb_dma_done(void *arg) -{ - struct idmac_tx_desc *tx_desc = to_tx_desc(arg); - struct dma_chan *chan = tx_desc->txd.chan; - struct idmac_channel *ichannel = to_idmac_chan(chan); - struct mx3fb_data *mx3fb = ichannel->client; - struct mx3fb_info *mx3_fbi = mx3fb->fbi->par; - - dev_dbg(mx3fb->dev, "irq %d callback\n", ichannel->eof_irq); - - /* We only need one interrupt, it will be re-enabled as needed */ - disable_irq(ichannel->eof_irq); - - complete(&mx3_fbi->flip_cmpl); -} - -/** - * mx3fb_set_par() - set framebuffer parameters and change the operating mode. - * @fbi: framebuffer information pointer. - * @return: 0 on success or negative error code on failure. - */ -static int mx3fb_set_par(struct fb_info *fbi) -{ - u32 mem_len; - struct ipu_di_signal_cfg sig_cfg; - enum ipu_panel mode = IPU_PANEL_TFT; - struct mx3fb_info *mx3_fbi = fbi->par; - struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; - struct idmac_channel *ichan = mx3_fbi->idmac_channel; - struct idmac_video_param *video = &ichan->params.video; - struct scatterlist *sg = mx3_fbi->sg; - size_t screen_size; - - dev_dbg(mx3fb->dev, "%s [%c]\n", __func__, list_empty(&ichan->queue) ? '-' : '+'); - - mutex_lock(&mx3_fbi->mutex); - - /* Total cleanup */ - if (mx3_fbi->txd) - sdc_disable_channel(mx3_fbi); - - mx3fb_set_fix(fbi); - - mem_len = fbi->var.yres_virtual * fbi->fix.line_length; - if (mem_len > fbi->fix.smem_len) { - if (fbi->fix.smem_start) - mx3fb_unmap_video_memory(fbi); - - fbi->fix.smem_len = mem_len; - if (mx3fb_map_video_memory(fbi) < 0) { - mutex_unlock(&mx3_fbi->mutex); - return -ENOMEM; - } - } - - screen_size = fbi->fix.line_length * fbi->var.yres; - - sg_init_table(&sg[0], 1); - sg_init_table(&sg[1], 1); - - sg_dma_address(&sg[0]) = fbi->fix.smem_start; - sg_set_page(&sg[0], virt_to_page(fbi->screen_base), - fbi->fix.smem_len, - offset_in_page(fbi->screen_base)); - - if (mx3_fbi->ipu_ch == IDMAC_SDC_0) { - memset(&sig_cfg, 0, sizeof(sig_cfg)); - if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT) - sig_cfg.Hsync_pol = true; - if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT) - sig_cfg.Vsync_pol = true; - if (fbi->var.sync & FB_SYNC_CLK_INVERT) - sig_cfg.clk_pol = true; - if (fbi->var.sync & FB_SYNC_DATA_INVERT) - sig_cfg.data_pol = true; - if (fbi->var.sync & FB_SYNC_OE_ACT_HIGH) - sig_cfg.enable_pol = true; - if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN) - sig_cfg.clkidle_en = true; - if (fbi->var.sync & FB_SYNC_CLK_SEL_EN) - sig_cfg.clksel_en = true; - if (fbi->var.sync & FB_SYNC_SHARP_MODE) - mode = IPU_PANEL_SHARP_TFT; - - dev_dbg(fbi->device, "pixclock = %ul Hz\n", - (u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL)); - - if (sdc_init_panel(mx3fb, mode, - (PICOS2KHZ(fbi->var.pixclock)) * 1000UL, - fbi->var.xres, fbi->var.yres, - (fbi->var.sync & FB_SYNC_SWAP_RGB) ? - IPU_PIX_FMT_BGR666 : IPU_PIX_FMT_RGB666, - fbi->var.left_margin, - fbi->var.hsync_len, - fbi->var.right_margin + - fbi->var.hsync_len, - fbi->var.upper_margin, - fbi->var.vsync_len, - fbi->var.lower_margin + - fbi->var.vsync_len, sig_cfg) != 0) { - mutex_unlock(&mx3_fbi->mutex); - dev_err(fbi->device, - "mx3fb: Error initializing panel.\n"); - return -EINVAL; - } - } - - sdc_set_window_pos(mx3fb, mx3_fbi->ipu_ch, 0, 0); - - mx3_fbi->cur_ipu_buf = 0; - - video->out_pixel_fmt = bpp_to_pixfmt(fbi->var.bits_per_pixel); - video->out_width = fbi->var.xres; - video->out_height = fbi->var.yres; - video->out_stride = fbi->var.xres_virtual; - - if (mx3_fbi->blank == FB_BLANK_UNBLANK) - sdc_enable_channel(mx3_fbi); - - mutex_unlock(&mx3_fbi->mutex); - - return 0; -} - -/** - * mx3fb_check_var() - check and adjust framebuffer variable parameters. - * @var: framebuffer variable parameters - * @fbi: framebuffer information pointer - */ -static int mx3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi) -{ - struct mx3fb_info *mx3_fbi = fbi->par; - u32 vtotal; - u32 htotal; - - dev_dbg(fbi->device, "%s\n", __func__); - - if (var->xres_virtual < var->xres) - var->xres_virtual = var->xres; - if (var->yres_virtual < var->yres) - var->yres_virtual = var->yres; - - if ((var->bits_per_pixel != 32) && (var->bits_per_pixel != 24) && - (var->bits_per_pixel != 16)) - var->bits_per_pixel = default_bpp; - - switch (var->bits_per_pixel) { - case 16: - var->red.length = 5; - var->red.offset = 11; - var->red.msb_right = 0; - - var->green.length = 6; - var->green.offset = 5; - var->green.msb_right = 0; - - var->blue.length = 5; - var->blue.offset = 0; - var->blue.msb_right = 0; - - var->transp.length = 0; - var->transp.offset = 0; - var->transp.msb_right = 0; - break; - case 24: - var->red.length = 8; - var->red.offset = 16; - var->red.msb_right = 0; - - var->green.length = 8; - var->green.offset = 8; - var->green.msb_right = 0; - - var->blue.length = 8; - var->blue.offset = 0; - var->blue.msb_right = 0; - - var->transp.length = 0; - var->transp.offset = 0; - var->transp.msb_right = 0; - break; - case 32: - var->red.length = 8; - var->red.offset = 16; - var->red.msb_right = 0; - - var->green.length = 8; - var->green.offset = 8; - var->green.msb_right = 0; - - var->blue.length = 8; - var->blue.offset = 0; - var->blue.msb_right = 0; - - var->transp.length = 8; - var->transp.offset = 24; - var->transp.msb_right = 0; - break; - } - - if (var->pixclock < 1000) { - htotal = var->xres + var->right_margin + var->hsync_len + - var->left_margin; - vtotal = var->yres + var->lower_margin + var->vsync_len + - var->upper_margin; - var->pixclock = (vtotal * htotal * 6UL) / 100UL; - var->pixclock = KHZ2PICOS(var->pixclock); - dev_dbg(fbi->device, "pixclock set for 60Hz refresh = %u ps\n", - var->pixclock); - } - - var->height = -1; - var->width = -1; - var->grayscale = 0; - - /* Preserve sync flags */ - var->sync |= mx3_fbi->sync; - mx3_fbi->sync |= var->sync; - - return 0; -} - -static u32 chan_to_field(unsigned int chan, struct fb_bitfield *bf) -{ - chan &= 0xffff; - chan >>= 16 - bf->length; - return chan << bf->offset; -} - -static int mx3fb_setcolreg(unsigned int regno, unsigned int red, - unsigned int green, unsigned int blue, - unsigned int trans, struct fb_info *fbi) -{ - struct mx3fb_info *mx3_fbi = fbi->par; - u32 val; - int ret = 1; - - dev_dbg(fbi->device, "%s\n", __func__); - - mutex_lock(&mx3_fbi->mutex); - /* - * If greyscale is true, then we convert the RGB value - * to greyscale no matter what visual we are using. - */ - if (fbi->var.grayscale) - red = green = blue = (19595 * red + 38470 * green + - 7471 * blue) >> 16; - switch (fbi->fix.visual) { - case FB_VISUAL_TRUECOLOR: - /* - * 16-bit True Colour. We encode the RGB value - * according to the RGB bitfield information. - */ - if (regno < 16) { - u32 *pal = fbi->pseudo_palette; - - val = chan_to_field(red, &fbi->var.red); - val |= chan_to_field(green, &fbi->var.green); - val |= chan_to_field(blue, &fbi->var.blue); - - pal[regno] = val; - - ret = 0; - } - break; - - case FB_VISUAL_STATIC_PSEUDOCOLOR: - case FB_VISUAL_PSEUDOCOLOR: - break; - } - mutex_unlock(&mx3_fbi->mutex); - - return ret; -} - -/** - * mx3fb_blank() - blank the display. - */ -static int mx3fb_blank(int blank, struct fb_info *fbi) -{ - struct mx3fb_info *mx3_fbi = fbi->par; - struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; - - dev_dbg(fbi->device, "%s\n", __func__); - - dev_dbg(fbi->device, "blank = %d\n", blank); - - if (mx3_fbi->blank == blank) - return 0; - - mutex_lock(&mx3_fbi->mutex); - mx3_fbi->blank = blank; - - switch (blank) { - case FB_BLANK_POWERDOWN: - case FB_BLANK_VSYNC_SUSPEND: - case FB_BLANK_HSYNC_SUSPEND: - case FB_BLANK_NORMAL: - sdc_disable_channel(mx3_fbi); - sdc_set_brightness(mx3fb, 0); - break; - case FB_BLANK_UNBLANK: - sdc_enable_channel(mx3_fbi); - sdc_set_brightness(mx3fb, mx3fb->backlight_level); - break; - } - mutex_unlock(&mx3_fbi->mutex); - - return 0; -} - -/** - * mx3fb_pan_display() - pan or wrap the display - * @var: variable screen buffer information. - * @info: framebuffer information pointer. - * - * We look only at xoffset, yoffset and the FB_VMODE_YWRAP flag - */ -static int mx3fb_pan_display(struct fb_var_screeninfo *var, - struct fb_info *fbi) -{ - struct mx3fb_info *mx3_fbi = fbi->par; - u32 y_bottom; - unsigned long base; - off_t offset; - dma_cookie_t cookie; - struct scatterlist *sg = mx3_fbi->sg; - struct dma_chan *dma_chan = &mx3_fbi->idmac_channel->dma_chan; - struct dma_async_tx_descriptor *txd; - int ret; - - dev_dbg(fbi->device, "%s [%c]\n", __func__, - list_empty(&mx3_fbi->idmac_channel->queue) ? '-' : '+'); - - if (var->xoffset > 0) { - dev_dbg(fbi->device, "x panning not supported\n"); - return -EINVAL; - } - - if (fbi->var.xoffset == var->xoffset && - fbi->var.yoffset == var->yoffset) - return 0; /* No change, do nothing */ - - y_bottom = var->yoffset; - - if (!(var->vmode & FB_VMODE_YWRAP)) - y_bottom += var->yres; - - if (y_bottom > fbi->var.yres_virtual) - return -EINVAL; - - mutex_lock(&mx3_fbi->mutex); - - offset = (var->yoffset * var->xres_virtual + var->xoffset) * - (var->bits_per_pixel / 8); - base = fbi->fix.smem_start + offset; - - dev_dbg(fbi->device, "Updating SDC BG buf %d address=0x%08lX\n", - mx3_fbi->cur_ipu_buf, base); - - /* - * We enable the End of Frame interrupt, which will free a tx-descriptor, - * which we will need for the next device_prep_slave_sg(). The - * IRQ-handler will disable the IRQ again. - */ - init_completion(&mx3_fbi->flip_cmpl); - enable_irq(mx3_fbi->idmac_channel->eof_irq); - - ret = wait_for_completion_timeout(&mx3_fbi->flip_cmpl, HZ / 10); - if (ret <= 0) { - mutex_unlock(&mx3_fbi->mutex); - dev_info(fbi->device, "Panning failed due to %s\n", ret < 0 ? - "user interrupt" : "timeout"); - return ret ? : -ETIMEDOUT; - } - - mx3_fbi->cur_ipu_buf = !mx3_fbi->cur_ipu_buf; - - sg_dma_address(&sg[mx3_fbi->cur_ipu_buf]) = base; - sg_set_page(&sg[mx3_fbi->cur_ipu_buf], - virt_to_page(fbi->screen_base + offset), fbi->fix.smem_len, - offset_in_page(fbi->screen_base + offset)); - - txd = dma_chan->device->device_prep_slave_sg(dma_chan, sg + - mx3_fbi->cur_ipu_buf, 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT); - if (!txd) { - dev_err(fbi->device, - "Error preparing a DMA transaction descriptor.\n"); - mutex_unlock(&mx3_fbi->mutex); - return -EIO; - } - - txd->callback_param = txd; - txd->callback = mx3fb_dma_done; - - /* - * Emulate original mx3fb behaviour: each new call to idmac_tx_submit() - * should switch to another buffer - */ - cookie = txd->tx_submit(txd); - dev_dbg(fbi->device, "%d: Submit %p #%d\n", __LINE__, txd, cookie); - if (cookie < 0) { - dev_err(fbi->device, - "Error updating SDC buf %d to address=0x%08lX\n", - mx3_fbi->cur_ipu_buf, base); - mutex_unlock(&mx3_fbi->mutex); - return -EIO; - } - - if (mx3_fbi->txd) - async_tx_ack(mx3_fbi->txd); - mx3_fbi->txd = txd; - - fbi->var.xoffset = var->xoffset; - fbi->var.yoffset = var->yoffset; - - if (var->vmode & FB_VMODE_YWRAP) - fbi->var.vmode |= FB_VMODE_YWRAP; - else - fbi->var.vmode &= ~FB_VMODE_YWRAP; - - mutex_unlock(&mx3_fbi->mutex); - - dev_dbg(fbi->device, "Update complete\n"); - - return 0; -} - -/* - * This structure contains the pointers to the control functions that are - * invoked by the core framebuffer driver to perform operations like - * blitting, rectangle filling, copy regions and cursor definition. - */ -static struct fb_ops mx3fb_ops = { - .owner = THIS_MODULE, - .fb_set_par = mx3fb_set_par, - .fb_check_var = mx3fb_check_var, - .fb_setcolreg = mx3fb_setcolreg, - .fb_pan_display = mx3fb_pan_display, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, - .fb_blank = mx3fb_blank, -}; - -#ifdef CONFIG_PM -/* - * Power management hooks. Note that we won't be called from IRQ context, - * unlike the blank functions above, so we may sleep. - */ - -/* - * Suspends the framebuffer and blanks the screen. Power management support - */ -static int mx3fb_suspend(struct platform_device *pdev, pm_message_t state) -{ - struct mx3fb_data *drv_data = platform_get_drvdata(pdev); - struct mx3fb_info *mx3_fbi = drv_data->fbi->par; - - acquire_console_sem(); - fb_set_suspend(drv_data->fbi, 1); - release_console_sem(); - - if (mx3_fbi->blank == FB_BLANK_UNBLANK) { - sdc_disable_channel(mx3_fbi); - sdc_set_brightness(mx3fb, 0); - - } - return 0; -} - -/* - * Resumes the framebuffer and unblanks the screen. Power management support - */ -static int mx3fb_resume(struct platform_device *pdev) -{ - struct mx3fb_data *drv_data = platform_get_drvdata(pdev); - struct mx3fb_info *mx3_fbi = drv_data->fbi->par; - - if (mx3_fbi->blank == FB_BLANK_UNBLANK) { - sdc_enable_channel(mx3_fbi); - sdc_set_brightness(mx3fb, drv_data->backlight_level); - } - - acquire_console_sem(); - fb_set_suspend(drv_data->fbi, 0); - release_console_sem(); - - return 0; -} -#else -#define mx3fb_suspend NULL -#define mx3fb_resume NULL -#endif - -/* - * Main framebuffer functions - */ - -/** - * mx3fb_map_video_memory() - allocates the DRAM memory for the frame buffer. - * @fbi: framebuffer information pointer - * @return: Error code indicating success or failure - * - * This buffer is remapped into a non-cached, non-buffered, memory region to - * allow palette and pixel writes to occur without flushing the cache. Once this - * area is remapped, all virtual memory access to the video memory should occur - * at the new region. - */ -static int mx3fb_map_video_memory(struct fb_info *fbi) -{ - int retval = 0; - dma_addr_t addr; - - fbi->screen_base = dma_alloc_writecombine(fbi->device, - fbi->fix.smem_len, - &addr, GFP_DMA); - - if (!fbi->screen_base) { - dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n", - fbi->fix.smem_len); - retval = -EBUSY; - goto err0; - } - - fbi->fix.smem_start = addr; - - dev_dbg(fbi->device, "allocated fb @ p=0x%08x, v=0x%p, size=%d.\n", - (uint32_t) fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len); - - fbi->screen_size = fbi->fix.smem_len; - - /* Clear the screen */ - memset((char *)fbi->screen_base, 0, fbi->fix.smem_len); - - return 0; - -err0: - fbi->fix.smem_len = 0; - fbi->fix.smem_start = 0; - fbi->screen_base = NULL; - return retval; -} - -/** - * mx3fb_unmap_video_memory() - de-allocate frame buffer memory. - * @fbi: framebuffer information pointer - * @return: error code indicating success or failure - */ -static int mx3fb_unmap_video_memory(struct fb_info *fbi) -{ - dma_free_writecombine(fbi->device, fbi->fix.smem_len, - fbi->screen_base, fbi->fix.smem_start); - - fbi->screen_base = 0; - fbi->fix.smem_start = 0; - fbi->fix.smem_len = 0; - return 0; -} - -/** - * mx3fb_init_fbinfo() - initialize framebuffer information object. - * @return: initialized framebuffer structure. - */ -static struct fb_info *mx3fb_init_fbinfo(struct device *dev, struct fb_ops *ops) -{ - struct fb_info *fbi; - struct mx3fb_info *mx3fbi; - int ret; - - /* Allocate sufficient memory for the fb structure */ - fbi = framebuffer_alloc(sizeof(struct mx3fb_info), dev); - if (!fbi) - return NULL; - - mx3fbi = fbi->par; - mx3fbi->cookie = -EINVAL; - mx3fbi->cur_ipu_buf = 0; - - fbi->var.activate = FB_ACTIVATE_NOW; - - fbi->fbops = ops; - fbi->flags = FBINFO_FLAG_DEFAULT; - fbi->pseudo_palette = mx3fbi->pseudo_palette; - - mutex_init(&mx3fbi->mutex); - - /* Allocate colormap */ - ret = fb_alloc_cmap(&fbi->cmap, 16, 0); - if (ret < 0) { - framebuffer_release(fbi); - return NULL; - } - - return fbi; -} - -static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan) -{ - struct device *dev = mx3fb->dev; - struct mx3fb_platform_data *mx3fb_pdata = dev->platform_data; - const char *name = mx3fb_pdata->name; - unsigned int irq; - struct fb_info *fbi; - struct mx3fb_info *mx3fbi; - const struct fb_videomode *mode; - int ret, num_modes; - - ichan->client = mx3fb; - irq = ichan->eof_irq; - - if (ichan->dma_chan.chan_id != IDMAC_SDC_0) - return -EINVAL; - - fbi = mx3fb_init_fbinfo(dev, &mx3fb_ops); - if (!fbi) - return -ENOMEM; - - if (!fb_mode) - fb_mode = name; - - if (!fb_mode) { - ret = -EINVAL; - goto emode; - } - - if (mx3fb_pdata->mode && mx3fb_pdata->num_modes) { - mode = mx3fb_pdata->mode; - num_modes = mx3fb_pdata->num_modes; - } else { - mode = mx3fb_modedb; - num_modes = ARRAY_SIZE(mx3fb_modedb); - } - - if (!fb_find_mode(&fbi->var, fbi, fb_mode, mode, - num_modes, NULL, default_bpp)) { - ret = -EBUSY; - goto emode; - } - - fb_videomode_to_modelist(mode, num_modes, &fbi->modelist); - - /* Default Y virtual size is 2x panel size */ - fbi->var.yres_virtual = fbi->var.yres * 2; - - mx3fb->fbi = fbi; - - /* set Display Interface clock period */ - mx3fb_write_reg(mx3fb, 0x00100010L, DI_HSP_CLK_PER); - /* Might need to trigger HSP clock change - see 44.3.3.8.5 */ - - sdc_set_brightness(mx3fb, 255); - sdc_set_global_alpha(mx3fb, true, 0xFF); - sdc_set_color_key(mx3fb, IDMAC_SDC_0, false, 0); - - mx3fbi = fbi->par; - mx3fbi->idmac_channel = ichan; - mx3fbi->ipu_ch = ichan->dma_chan.chan_id; - mx3fbi->mx3fb = mx3fb; - mx3fbi->blank = FB_BLANK_NORMAL; - - init_completion(&mx3fbi->flip_cmpl); - disable_irq(ichan->eof_irq); - dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq); - ret = mx3fb_set_par(fbi); - if (ret < 0) - goto esetpar; - - mx3fb_blank(FB_BLANK_UNBLANK, fbi); - - dev_info(dev, "mx3fb: fb registered, using mode %s\n", fb_mode); - - ret = register_framebuffer(fbi); - if (ret < 0) - goto erfb; - - return 0; - -erfb: -esetpar: -emode: - fb_dealloc_cmap(&fbi->cmap); - framebuffer_release(fbi); - - return ret; -} - -static bool chan_filter(struct dma_chan *chan, void *arg) -{ - struct dma_chan_request *rq = arg; - struct device *dev; - struct mx3fb_platform_data *mx3fb_pdata; - - if (!rq) - return false; - - dev = rq->mx3fb->dev; - mx3fb_pdata = dev->platform_data; - - return rq->id == chan->chan_id && - mx3fb_pdata->dma_dev == chan->device->dev; -} - -static void release_fbi(struct fb_info *fbi) -{ - mx3fb_unmap_video_memory(fbi); - - fb_dealloc_cmap(&fbi->cmap); - - unregister_framebuffer(fbi); - framebuffer_release(fbi); -} - -static int mx3fb_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - int ret; - struct resource *sdc_reg; - struct mx3fb_data *mx3fb; - dma_cap_mask_t mask; - struct dma_chan *chan; - struct dma_chan_request rq; - - /* - * Display Interface (DI) and Synchronous Display Controller (SDC) - * registers - */ - sdc_reg = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!sdc_reg) - return -EINVAL; - - mx3fb = kzalloc(sizeof(*mx3fb), GFP_KERNEL); - if (!mx3fb) - return -ENOMEM; - - spin_lock_init(&mx3fb->lock); - - mx3fb->reg_base = ioremap(sdc_reg->start, resource_size(sdc_reg)); - if (!mx3fb->reg_base) { - ret = -ENOMEM; - goto eremap; - } - - pr_debug("Remapped %x to %x at %p\n", sdc_reg->start, sdc_reg->end, - mx3fb->reg_base); - - /* IDMAC interface */ - dmaengine_get(); - - mx3fb->dev = dev; - platform_set_drvdata(pdev, mx3fb); - - rq.mx3fb = mx3fb; - - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - dma_cap_set(DMA_PRIVATE, mask); - rq.id = IDMAC_SDC_0; - chan = dma_request_channel(mask, chan_filter, &rq); - if (!chan) { - ret = -EBUSY; - goto ersdc0; - } - - ret = init_fb_chan(mx3fb, to_idmac_chan(chan)); - if (ret < 0) - goto eisdc0; - - mx3fb->backlight_level = 255; - - return 0; - -eisdc0: - dma_release_channel(chan); -ersdc0: - dmaengine_put(); - iounmap(mx3fb->reg_base); -eremap: - kfree(mx3fb); - dev_err(dev, "mx3fb: failed to register fb\n"); - return ret; -} - -static int mx3fb_remove(struct platform_device *dev) -{ - struct mx3fb_data *mx3fb = platform_get_drvdata(dev); - struct fb_info *fbi = mx3fb->fbi; - struct mx3fb_info *mx3_fbi = fbi->par; - struct dma_chan *chan; - - chan = &mx3_fbi->idmac_channel->dma_chan; - release_fbi(fbi); - - dma_release_channel(chan); - dmaengine_put(); - - iounmap(mx3fb->reg_base); - kfree(mx3fb); - return 0; -} - -static struct platform_driver mx3fb_driver = { - .driver = { - .name = MX3FB_NAME, - }, - .probe = mx3fb_probe, - .remove = mx3fb_remove, - .suspend = mx3fb_suspend, - .resume = mx3fb_resume, -}; - -/* - * Parse user specified options (`video=mx3fb:') - * example: - * video=mx3fb:bpp=16 - */ -static int mx3fb_setup(void) -{ -#ifndef MODULE - char *opt, *options = NULL; - - if (fb_get_options("mx3fb", &options)) - return -ENODEV; - - if (!options || !*options) - return 0; - - while ((opt = strsep(&options, ",")) != NULL) { - if (!*opt) - continue; - if (!strncmp(opt, "bpp=", 4)) - default_bpp = simple_strtoul(opt + 4, NULL, 0); - else - fb_mode = opt; - } -#endif - - return 0; -} - -static int __init mx3fb_init(void) -{ - int ret = mx3fb_setup(); - - if (ret < 0) - return ret; - - ret = platform_driver_register(&mx3fb_driver); - return ret; -} - -static void __exit mx3fb_exit(void) -{ - platform_driver_unregister(&mx3fb_driver); -} - -module_init(mx3fb_init); -module_exit(mx3fb_exit); - -MODULE_AUTHOR("Freescale Semiconductor, Inc."); -MODULE_DESCRIPTION("MX3 framebuffer driver"); -MODULE_ALIAS("platform:" MX3FB_NAME); -MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 6e1588cbd88590273300403648aef70e6bdaf5af Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 26 Feb 2009 21:34:28 +0100 Subject: i.MX31: framebuffer driver This is a framebuffer driver for i.MX31 SoCs. It only supports synchronous displays, vertical panning supported, no overlay support. Signed-off-by: Guennadi Liakhovetski Acked-by: Sascha Hauer Signed-off-by: Dan Williams --- arch/arm/plat-mxc/include/mach/mx3fb.h | 38 + drivers/video/Kconfig | 12 + drivers/video/Makefile | 1 + drivers/video/mx3fb.c | 1555 ++++++++++++++++++++++++++++++++ 4 files changed, 1606 insertions(+) create mode 100644 arch/arm/plat-mxc/include/mach/mx3fb.h create mode 100644 drivers/video/mx3fb.c (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/plat-mxc/include/mach/mx3fb.h b/arch/arm/plat-mxc/include/mach/mx3fb.h new file mode 100644 index 000000000000..ac24c5c4bc83 --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/mx3fb.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2008 + * Guennadi Liakhovetski, DENX Software Engineering, + * + * 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. + */ + +#ifndef __ASM_ARCH_MX3FB_H__ +#define __ASM_ARCH_MX3FB_H__ + +#include +#include + +/* Proprietary FB_SYNC_ flags */ +#define FB_SYNC_OE_ACT_HIGH 0x80000000 +#define FB_SYNC_CLK_INVERT 0x40000000 +#define FB_SYNC_DATA_INVERT 0x20000000 +#define FB_SYNC_CLK_IDLE_EN 0x10000000 +#define FB_SYNC_SHARP_MODE 0x08000000 +#define FB_SYNC_SWAP_RGB 0x04000000 +#define FB_SYNC_CLK_SEL_EN 0x02000000 + +/** + * struct mx3fb_platform_data - mx3fb platform data + * + * @dma_dev: pointer to the dma-device, used for dma-slave connection + * @mode: pointer to a platform-provided per mxc_register_fb() videomode + */ +struct mx3fb_platform_data { + struct device *dma_dev; + const char *name; + const struct fb_videomode *mode; + int num_modes; +}; + +#endif diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 6f3f3bff3832..5c5e3fe090ea 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -2125,6 +2125,18 @@ config FB_PRE_INIT_FB Select this option if display contents should be inherited as set by the bootloader. +config FB_MX3 + tristate "MX3 Framebuffer support" + depends on FB && MX3_IPU + select FB_CFB_FILLRECT + select FB_CFB_COPYAREA + select FB_CFB_IMAGEBLIT + default y + help + This is a framebuffer device for the i.MX31 LCD Controller. So + far only synchronous displays are supported. If you plan to use + an LCD display with your i.MX31 system, say Y here. + source "drivers/video/omap/Kconfig" source "drivers/video/backlight/Kconfig" diff --git a/drivers/video/Makefile b/drivers/video/Makefile index be2b657546ef..a5564a513a5e 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -132,6 +132,7 @@ obj-$(CONFIG_FB_VGA16) += vga16fb.o obj-$(CONFIG_FB_OF) += offb.o obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o +obj-$(CONFIG_FB_MX3) += mx3fb.o # the test framebuffer is last obj-$(CONFIG_FB_VIRTUAL) += vfb.o diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c new file mode 100644 index 000000000000..3e8463562dee --- /dev/null +++ b/drivers/video/mx3fb.c @@ -0,0 +1,1555 @@ +/* + * Copyright (C) 2008 + * Guennadi Liakhovetski, DENX Software Engineering, + * + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#define MX3FB_NAME "mx3_sdc_fb" + +#define MX3FB_REG_OFFSET 0xB4 + +/* SDC Registers */ +#define SDC_COM_CONF (0xB4 - MX3FB_REG_OFFSET) +#define SDC_GW_CTRL (0xB8 - MX3FB_REG_OFFSET) +#define SDC_FG_POS (0xBC - MX3FB_REG_OFFSET) +#define SDC_BG_POS (0xC0 - MX3FB_REG_OFFSET) +#define SDC_CUR_POS (0xC4 - MX3FB_REG_OFFSET) +#define SDC_PWM_CTRL (0xC8 - MX3FB_REG_OFFSET) +#define SDC_CUR_MAP (0xCC - MX3FB_REG_OFFSET) +#define SDC_HOR_CONF (0xD0 - MX3FB_REG_OFFSET) +#define SDC_VER_CONF (0xD4 - MX3FB_REG_OFFSET) +#define SDC_SHARP_CONF_1 (0xD8 - MX3FB_REG_OFFSET) +#define SDC_SHARP_CONF_2 (0xDC - MX3FB_REG_OFFSET) + +/* Register bits */ +#define SDC_COM_TFT_COLOR 0x00000001UL +#define SDC_COM_FG_EN 0x00000010UL +#define SDC_COM_GWSEL 0x00000020UL +#define SDC_COM_GLB_A 0x00000040UL +#define SDC_COM_KEY_COLOR_G 0x00000080UL +#define SDC_COM_BG_EN 0x00000200UL +#define SDC_COM_SHARP 0x00001000UL + +#define SDC_V_SYNC_WIDTH_L 0x00000001UL + +/* Display Interface registers */ +#define DI_DISP_IF_CONF (0x0124 - MX3FB_REG_OFFSET) +#define DI_DISP_SIG_POL (0x0128 - MX3FB_REG_OFFSET) +#define DI_SER_DISP1_CONF (0x012C - MX3FB_REG_OFFSET) +#define DI_SER_DISP2_CONF (0x0130 - MX3FB_REG_OFFSET) +#define DI_HSP_CLK_PER (0x0134 - MX3FB_REG_OFFSET) +#define DI_DISP0_TIME_CONF_1 (0x0138 - MX3FB_REG_OFFSET) +#define DI_DISP0_TIME_CONF_2 (0x013C - MX3FB_REG_OFFSET) +#define DI_DISP0_TIME_CONF_3 (0x0140 - MX3FB_REG_OFFSET) +#define DI_DISP1_TIME_CONF_1 (0x0144 - MX3FB_REG_OFFSET) +#define DI_DISP1_TIME_CONF_2 (0x0148 - MX3FB_REG_OFFSET) +#define DI_DISP1_TIME_CONF_3 (0x014C - MX3FB_REG_OFFSET) +#define DI_DISP2_TIME_CONF_1 (0x0150 - MX3FB_REG_OFFSET) +#define DI_DISP2_TIME_CONF_2 (0x0154 - MX3FB_REG_OFFSET) +#define DI_DISP2_TIME_CONF_3 (0x0158 - MX3FB_REG_OFFSET) +#define DI_DISP3_TIME_CONF (0x015C - MX3FB_REG_OFFSET) +#define DI_DISP0_DB0_MAP (0x0160 - MX3FB_REG_OFFSET) +#define DI_DISP0_DB1_MAP (0x0164 - MX3FB_REG_OFFSET) +#define DI_DISP0_DB2_MAP (0x0168 - MX3FB_REG_OFFSET) +#define DI_DISP0_CB0_MAP (0x016C - MX3FB_REG_OFFSET) +#define DI_DISP0_CB1_MAP (0x0170 - MX3FB_REG_OFFSET) +#define DI_DISP0_CB2_MAP (0x0174 - MX3FB_REG_OFFSET) +#define DI_DISP1_DB0_MAP (0x0178 - MX3FB_REG_OFFSET) +#define DI_DISP1_DB1_MAP (0x017C - MX3FB_REG_OFFSET) +#define DI_DISP1_DB2_MAP (0x0180 - MX3FB_REG_OFFSET) +#define DI_DISP1_CB0_MAP (0x0184 - MX3FB_REG_OFFSET) +#define DI_DISP1_CB1_MAP (0x0188 - MX3FB_REG_OFFSET) +#define DI_DISP1_CB2_MAP (0x018C - MX3FB_REG_OFFSET) +#define DI_DISP2_DB0_MAP (0x0190 - MX3FB_REG_OFFSET) +#define DI_DISP2_DB1_MAP (0x0194 - MX3FB_REG_OFFSET) +#define DI_DISP2_DB2_MAP (0x0198 - MX3FB_REG_OFFSET) +#define DI_DISP2_CB0_MAP (0x019C - MX3FB_REG_OFFSET) +#define DI_DISP2_CB1_MAP (0x01A0 - MX3FB_REG_OFFSET) +#define DI_DISP2_CB2_MAP (0x01A4 - MX3FB_REG_OFFSET) +#define DI_DISP3_B0_MAP (0x01A8 - MX3FB_REG_OFFSET) +#define DI_DISP3_B1_MAP (0x01AC - MX3FB_REG_OFFSET) +#define DI_DISP3_B2_MAP (0x01B0 - MX3FB_REG_OFFSET) +#define DI_DISP_ACC_CC (0x01B4 - MX3FB_REG_OFFSET) +#define DI_DISP_LLA_CONF (0x01B8 - MX3FB_REG_OFFSET) +#define DI_DISP_LLA_DATA (0x01BC - MX3FB_REG_OFFSET) + +/* DI_DISP_SIG_POL bits */ +#define DI_D3_VSYNC_POL_SHIFT 28 +#define DI_D3_HSYNC_POL_SHIFT 27 +#define DI_D3_DRDY_SHARP_POL_SHIFT 26 +#define DI_D3_CLK_POL_SHIFT 25 +#define DI_D3_DATA_POL_SHIFT 24 + +/* DI_DISP_IF_CONF bits */ +#define DI_D3_CLK_IDLE_SHIFT 26 +#define DI_D3_CLK_SEL_SHIFT 25 +#define DI_D3_DATAMSK_SHIFT 24 + +enum ipu_panel { + IPU_PANEL_SHARP_TFT, + IPU_PANEL_TFT, +}; + +struct ipu_di_signal_cfg { + unsigned datamask_en:1; + unsigned clksel_en:1; + unsigned clkidle_en:1; + unsigned data_pol:1; /* true = inverted */ + unsigned clk_pol:1; /* true = rising edge */ + unsigned enable_pol:1; + unsigned Hsync_pol:1; /* true = active high */ + unsigned Vsync_pol:1; +}; + +static const struct fb_videomode mx3fb_modedb[] = { + { + /* 240x320 @ 60 Hz */ + .name = "Sharp-QVGA", + .refresh = 60, + .xres = 240, + .yres = 320, + .pixclock = 185925, + .left_margin = 9, + .right_margin = 16, + .upper_margin = 7, + .lower_margin = 9, + .hsync_len = 1, + .vsync_len = 1, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE | + FB_SYNC_CLK_INVERT | FB_SYNC_DATA_INVERT | + FB_SYNC_CLK_IDLE_EN, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, + }, { + /* 240x33 @ 60 Hz */ + .name = "Sharp-CLI", + .refresh = 60, + .xres = 240, + .yres = 33, + .pixclock = 185925, + .left_margin = 9, + .right_margin = 16, + .upper_margin = 7, + .lower_margin = 9 + 287, + .hsync_len = 1, + .vsync_len = 1, + .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_SHARP_MODE | + FB_SYNC_CLK_INVERT | FB_SYNC_DATA_INVERT | + FB_SYNC_CLK_IDLE_EN, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, + }, { + /* 640x480 @ 60 Hz */ + .name = "NEC-VGA", + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = 38255, + .left_margin = 144, + .right_margin = 0, + .upper_margin = 34, + .lower_margin = 40, + .hsync_len = 1, + .vsync_len = 1, + .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_OE_ACT_HIGH, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, + }, { + /* NTSC TV output */ + .name = "TV-NTSC", + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = 37538, + .left_margin = 38, + .right_margin = 858 - 640 - 38 - 3, + .upper_margin = 36, + .lower_margin = 518 - 480 - 36 - 1, + .hsync_len = 3, + .vsync_len = 1, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, + }, { + /* PAL TV output */ + .name = "TV-PAL", + .refresh = 50, + .xres = 640, + .yres = 480, + .pixclock = 37538, + .left_margin = 38, + .right_margin = 960 - 640 - 38 - 32, + .upper_margin = 32, + .lower_margin = 555 - 480 - 32 - 3, + .hsync_len = 32, + .vsync_len = 3, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, + }, { + /* TV output VGA mode, 640x480 @ 65 Hz */ + .name = "TV-VGA", + .refresh = 60, + .xres = 640, + .yres = 480, + .pixclock = 40574, + .left_margin = 35, + .right_margin = 45, + .upper_margin = 9, + .lower_margin = 1, + .hsync_len = 46, + .vsync_len = 5, + .sync = 0, + .vmode = FB_VMODE_NONINTERLACED, + .flag = 0, + }, +}; + +struct mx3fb_data { + struct fb_info *fbi; + int backlight_level; + void __iomem *reg_base; + spinlock_t lock; + struct device *dev; + + uint32_t h_start_width; + uint32_t v_start_width; +}; + +struct dma_chan_request { + struct mx3fb_data *mx3fb; + enum ipu_channel id; +}; + +/* MX3 specific framebuffer information. */ +struct mx3fb_info { + int blank; + enum ipu_channel ipu_ch; + uint32_t cur_ipu_buf; + + u32 pseudo_palette[16]; + + struct completion flip_cmpl; + struct mutex mutex; /* Protects fb-ops */ + struct mx3fb_data *mx3fb; + struct idmac_channel *idmac_channel; + struct dma_async_tx_descriptor *txd; + dma_cookie_t cookie; + struct scatterlist sg[2]; + + u32 sync; /* preserve var->sync flags */ +}; + +static void mx3fb_dma_done(void *); + +/* Used fb-mode and bpp. Can be set on kernel command line, therefore file-static. */ +static const char *fb_mode; +static unsigned long default_bpp = 16; + +static u32 mx3fb_read_reg(struct mx3fb_data *mx3fb, unsigned long reg) +{ + return __raw_readl(mx3fb->reg_base + reg); +} + +static void mx3fb_write_reg(struct mx3fb_data *mx3fb, u32 value, unsigned long reg) +{ + __raw_writel(value, mx3fb->reg_base + reg); +} + +static const uint32_t di_mappings[] = { + 0x1600AAAA, 0x00E05555, 0x00070000, 3, /* RGB888 */ + 0x0005000F, 0x000B000F, 0x0011000F, 1, /* RGB666 */ + 0x0011000F, 0x000B000F, 0x0005000F, 1, /* BGR666 */ + 0x0004003F, 0x000A000F, 0x000F003F, 1 /* RGB565 */ +}; + +static void sdc_fb_init(struct mx3fb_info *fbi) +{ + struct mx3fb_data *mx3fb = fbi->mx3fb; + uint32_t reg; + + reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); + + mx3fb_write_reg(mx3fb, reg | SDC_COM_BG_EN, SDC_COM_CONF); +} + +/* Returns enabled flag before uninit */ +static uint32_t sdc_fb_uninit(struct mx3fb_info *fbi) +{ + struct mx3fb_data *mx3fb = fbi->mx3fb; + uint32_t reg; + + reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); + + mx3fb_write_reg(mx3fb, reg & ~SDC_COM_BG_EN, SDC_COM_CONF); + + return reg & SDC_COM_BG_EN; +} + +static void sdc_enable_channel(struct mx3fb_info *mx3_fbi) +{ + struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; + struct idmac_channel *ichan = mx3_fbi->idmac_channel; + struct dma_chan *dma_chan = &ichan->dma_chan; + unsigned long flags; + dma_cookie_t cookie; + + dev_dbg(mx3fb->dev, "mx3fbi %p, desc %p, sg %p\n", mx3_fbi, + to_tx_desc(mx3_fbi->txd), to_tx_desc(mx3_fbi->txd)->sg); + + /* This enables the channel */ + if (mx3_fbi->cookie < 0) { + mx3_fbi->txd = dma_chan->device->device_prep_slave_sg(dma_chan, + &mx3_fbi->sg[0], 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT); + if (!mx3_fbi->txd) { + dev_err(mx3fb->dev, "Cannot allocate descriptor on %d\n", + dma_chan->chan_id); + return; + } + + mx3_fbi->txd->callback_param = mx3_fbi->txd; + mx3_fbi->txd->callback = mx3fb_dma_done; + + cookie = mx3_fbi->txd->tx_submit(mx3_fbi->txd); + dev_dbg(mx3fb->dev, "%d: Submit %p #%d [%c]\n", __LINE__, + mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+'); + } else { + if (!mx3_fbi->txd || !mx3_fbi->txd->tx_submit) { + dev_err(mx3fb->dev, "Cannot enable channel %d\n", + dma_chan->chan_id); + return; + } + + /* Just re-activate the same buffer */ + dma_async_issue_pending(dma_chan); + cookie = mx3_fbi->cookie; + dev_dbg(mx3fb->dev, "%d: Re-submit %p #%d [%c]\n", __LINE__, + mx3_fbi->txd, cookie, list_empty(&ichan->queue) ? '-' : '+'); + } + + if (cookie >= 0) { + spin_lock_irqsave(&mx3fb->lock, flags); + sdc_fb_init(mx3_fbi); + mx3_fbi->cookie = cookie; + spin_unlock_irqrestore(&mx3fb->lock, flags); + } + + /* + * Attention! Without this msleep the channel keeps generating + * interrupts. Next sdc_set_brightness() is going to be called + * from mx3fb_blank(). + */ + msleep(2); +} + +static void sdc_disable_channel(struct mx3fb_info *mx3_fbi) +{ + struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; + uint32_t enabled; + unsigned long flags; + + spin_lock_irqsave(&mx3fb->lock, flags); + + enabled = sdc_fb_uninit(mx3_fbi); + + spin_unlock_irqrestore(&mx3fb->lock, flags); + + mx3_fbi->txd->chan->device->device_terminate_all(mx3_fbi->txd->chan); + mx3_fbi->txd = NULL; + mx3_fbi->cookie = -EINVAL; +} + +/** + * sdc_set_window_pos() - set window position of the respective plane. + * @mx3fb: mx3fb context. + * @channel: IPU DMAC channel ID. + * @x_pos: X coordinate relative to the top left corner to place window at. + * @y_pos: Y coordinate relative to the top left corner to place window at. + * @return: 0 on success or negative error code on failure. + */ +static int sdc_set_window_pos(struct mx3fb_data *mx3fb, enum ipu_channel channel, + int16_t x_pos, int16_t y_pos) +{ + x_pos += mx3fb->h_start_width; + y_pos += mx3fb->v_start_width; + + if (channel != IDMAC_SDC_0) + return -EINVAL; + + mx3fb_write_reg(mx3fb, (x_pos << 16) | y_pos, SDC_BG_POS); + return 0; +} + +/** + * sdc_init_panel() - initialize a synchronous LCD panel. + * @mx3fb: mx3fb context. + * @panel: panel type. + * @pixel_clk: desired pixel clock frequency in Hz. + * @width: width of panel in pixels. + * @height: height of panel in pixels. + * @pixel_fmt: pixel format of buffer as FOURCC ASCII code. + * @h_start_width: number of pixel clocks between the HSYNC signal pulse + * and the start of valid data. + * @h_sync_width: width of the HSYNC signal in units of pixel clocks. + * @h_end_width: number of pixel clocks between the end of valid data + * and the HSYNC signal for next line. + * @v_start_width: number of lines between the VSYNC signal pulse and the + * start of valid data. + * @v_sync_width: width of the VSYNC signal in units of lines + * @v_end_width: number of lines between the end of valid data and the + * VSYNC signal for next frame. + * @sig: bitfield of signal polarities for LCD interface. + * @return: 0 on success or negative error code on failure. + */ +static int sdc_init_panel(struct mx3fb_data *mx3fb, enum ipu_panel panel, + uint32_t pixel_clk, + uint16_t width, uint16_t height, + enum pixel_fmt pixel_fmt, + uint16_t h_start_width, uint16_t h_sync_width, + uint16_t h_end_width, uint16_t v_start_width, + uint16_t v_sync_width, uint16_t v_end_width, + struct ipu_di_signal_cfg sig) +{ + unsigned long lock_flags; + uint32_t reg; + uint32_t old_conf; + uint32_t div; + struct clk *ipu_clk; + + dev_dbg(mx3fb->dev, "panel size = %d x %d", width, height); + + if (v_sync_width == 0 || h_sync_width == 0) + return -EINVAL; + + /* Init panel size and blanking periods */ + reg = ((uint32_t) (h_sync_width - 1) << 26) | + ((uint32_t) (width + h_start_width + h_end_width - 1) << 16); + mx3fb_write_reg(mx3fb, reg, SDC_HOR_CONF); + +#ifdef DEBUG + printk(KERN_CONT " hor_conf %x,", reg); +#endif + + reg = ((uint32_t) (v_sync_width - 1) << 26) | SDC_V_SYNC_WIDTH_L | + ((uint32_t) (height + v_start_width + v_end_width - 1) << 16); + mx3fb_write_reg(mx3fb, reg, SDC_VER_CONF); + +#ifdef DEBUG + printk(KERN_CONT " ver_conf %x\n", reg); +#endif + + mx3fb->h_start_width = h_start_width; + mx3fb->v_start_width = v_start_width; + + switch (panel) { + case IPU_PANEL_SHARP_TFT: + mx3fb_write_reg(mx3fb, 0x00FD0102L, SDC_SHARP_CONF_1); + mx3fb_write_reg(mx3fb, 0x00F500F4L, SDC_SHARP_CONF_2); + mx3fb_write_reg(mx3fb, SDC_COM_SHARP | SDC_COM_TFT_COLOR, SDC_COM_CONF); + break; + case IPU_PANEL_TFT: + mx3fb_write_reg(mx3fb, SDC_COM_TFT_COLOR, SDC_COM_CONF); + break; + default: + return -EINVAL; + } + + /* Init clocking */ + + /* + * Calculate divider: fractional part is 4 bits so simply multiple by + * 2^4 to get fractional part, as long as we stay under ~250MHz and on + * i.MX31 it (HSP_CLK) is <= 178MHz. Currently 128.267MHz + */ + dev_dbg(mx3fb->dev, "pixel clk = %d\n", pixel_clk); + + ipu_clk = clk_get(mx3fb->dev, "ipu_clk"); + div = clk_get_rate(ipu_clk) * 16 / pixel_clk; + clk_put(ipu_clk); + + if (div < 0x40) { /* Divider less than 4 */ + dev_dbg(mx3fb->dev, + "InitPanel() - Pixel clock divider less than 4\n"); + div = 0x40; + } + + spin_lock_irqsave(&mx3fb->lock, lock_flags); + + /* + * DISP3_IF_CLK_DOWN_WR is half the divider value and 2 fraction bits + * fewer. Subtract 1 extra from DISP3_IF_CLK_DOWN_WR based on timing + * debug. DISP3_IF_CLK_UP_WR is 0 + */ + mx3fb_write_reg(mx3fb, (((div / 8) - 1) << 22) | div, DI_DISP3_TIME_CONF); + + /* DI settings */ + old_conf = mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF) & 0x78FFFFFF; + old_conf |= sig.datamask_en << DI_D3_DATAMSK_SHIFT | + sig.clksel_en << DI_D3_CLK_SEL_SHIFT | + sig.clkidle_en << DI_D3_CLK_IDLE_SHIFT; + mx3fb_write_reg(mx3fb, old_conf, DI_DISP_IF_CONF); + + old_conf = mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL) & 0xE0FFFFFF; + old_conf |= sig.data_pol << DI_D3_DATA_POL_SHIFT | + sig.clk_pol << DI_D3_CLK_POL_SHIFT | + sig.enable_pol << DI_D3_DRDY_SHARP_POL_SHIFT | + sig.Hsync_pol << DI_D3_HSYNC_POL_SHIFT | + sig.Vsync_pol << DI_D3_VSYNC_POL_SHIFT; + mx3fb_write_reg(mx3fb, old_conf, DI_DISP_SIG_POL); + + switch (pixel_fmt) { + case IPU_PIX_FMT_RGB24: + mx3fb_write_reg(mx3fb, di_mappings[0], DI_DISP3_B0_MAP); + mx3fb_write_reg(mx3fb, di_mappings[1], DI_DISP3_B1_MAP); + mx3fb_write_reg(mx3fb, di_mappings[2], DI_DISP3_B2_MAP); + mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) | + ((di_mappings[3] - 1) << 12), DI_DISP_ACC_CC); + break; + case IPU_PIX_FMT_RGB666: + mx3fb_write_reg(mx3fb, di_mappings[4], DI_DISP3_B0_MAP); + mx3fb_write_reg(mx3fb, di_mappings[5], DI_DISP3_B1_MAP); + mx3fb_write_reg(mx3fb, di_mappings[6], DI_DISP3_B2_MAP); + mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) | + ((di_mappings[7] - 1) << 12), DI_DISP_ACC_CC); + break; + case IPU_PIX_FMT_BGR666: + mx3fb_write_reg(mx3fb, di_mappings[8], DI_DISP3_B0_MAP); + mx3fb_write_reg(mx3fb, di_mappings[9], DI_DISP3_B1_MAP); + mx3fb_write_reg(mx3fb, di_mappings[10], DI_DISP3_B2_MAP); + mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) | + ((di_mappings[11] - 1) << 12), DI_DISP_ACC_CC); + break; + default: + mx3fb_write_reg(mx3fb, di_mappings[12], DI_DISP3_B0_MAP); + mx3fb_write_reg(mx3fb, di_mappings[13], DI_DISP3_B1_MAP); + mx3fb_write_reg(mx3fb, di_mappings[14], DI_DISP3_B2_MAP); + mx3fb_write_reg(mx3fb, mx3fb_read_reg(mx3fb, DI_DISP_ACC_CC) | + ((di_mappings[15] - 1) << 12), DI_DISP_ACC_CC); + break; + } + + spin_unlock_irqrestore(&mx3fb->lock, lock_flags); + + dev_dbg(mx3fb->dev, "DI_DISP_IF_CONF = 0x%08X\n", + mx3fb_read_reg(mx3fb, DI_DISP_IF_CONF)); + dev_dbg(mx3fb->dev, "DI_DISP_SIG_POL = 0x%08X\n", + mx3fb_read_reg(mx3fb, DI_DISP_SIG_POL)); + dev_dbg(mx3fb->dev, "DI_DISP3_TIME_CONF = 0x%08X\n", + mx3fb_read_reg(mx3fb, DI_DISP3_TIME_CONF)); + + return 0; +} + +/** + * sdc_set_color_key() - set the transparent color key for SDC graphic plane. + * @mx3fb: mx3fb context. + * @channel: IPU DMAC channel ID. + * @enable: boolean to enable or disable color keyl. + * @color_key: 24-bit RGB color to use as transparent color key. + * @return: 0 on success or negative error code on failure. + */ +static int sdc_set_color_key(struct mx3fb_data *mx3fb, enum ipu_channel channel, + bool enable, uint32_t color_key) +{ + uint32_t reg, sdc_conf; + unsigned long lock_flags; + + spin_lock_irqsave(&mx3fb->lock, lock_flags); + + sdc_conf = mx3fb_read_reg(mx3fb, SDC_COM_CONF); + if (channel == IDMAC_SDC_0) + sdc_conf &= ~SDC_COM_GWSEL; + else + sdc_conf |= SDC_COM_GWSEL; + + if (enable) { + reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0xFF000000L; + mx3fb_write_reg(mx3fb, reg | (color_key & 0x00FFFFFFL), + SDC_GW_CTRL); + + sdc_conf |= SDC_COM_KEY_COLOR_G; + } else { + sdc_conf &= ~SDC_COM_KEY_COLOR_G; + } + mx3fb_write_reg(mx3fb, sdc_conf, SDC_COM_CONF); + + spin_unlock_irqrestore(&mx3fb->lock, lock_flags); + + return 0; +} + +/** + * sdc_set_global_alpha() - set global alpha blending modes. + * @mx3fb: mx3fb context. + * @enable: boolean to enable or disable global alpha blending. If disabled, + * per pixel blending is used. + * @alpha: global alpha value. + * @return: 0 on success or negative error code on failure. + */ +static int sdc_set_global_alpha(struct mx3fb_data *mx3fb, bool enable, uint8_t alpha) +{ + uint32_t reg; + unsigned long lock_flags; + + spin_lock_irqsave(&mx3fb->lock, lock_flags); + + if (enable) { + reg = mx3fb_read_reg(mx3fb, SDC_GW_CTRL) & 0x00FFFFFFL; + mx3fb_write_reg(mx3fb, reg | ((uint32_t) alpha << 24), SDC_GW_CTRL); + + reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); + mx3fb_write_reg(mx3fb, reg | SDC_COM_GLB_A, SDC_COM_CONF); + } else { + reg = mx3fb_read_reg(mx3fb, SDC_COM_CONF); + mx3fb_write_reg(mx3fb, reg & ~SDC_COM_GLB_A, SDC_COM_CONF); + } + + spin_unlock_irqrestore(&mx3fb->lock, lock_flags); + + return 0; +} + +static void sdc_set_brightness(struct mx3fb_data *mx3fb, uint8_t value) +{ + /* This might be board-specific */ + mx3fb_write_reg(mx3fb, 0x03000000UL | value << 16, SDC_PWM_CTRL); + return; +} + +static uint32_t bpp_to_pixfmt(int bpp) +{ + uint32_t pixfmt = 0; + switch (bpp) { + case 24: + pixfmt = IPU_PIX_FMT_BGR24; + break; + case 32: + pixfmt = IPU_PIX_FMT_BGR32; + break; + case 16: + pixfmt = IPU_PIX_FMT_RGB565; + break; + } + return pixfmt; +} + +static int mx3fb_blank(int blank, struct fb_info *fbi); +static int mx3fb_map_video_memory(struct fb_info *fbi); +static int mx3fb_unmap_video_memory(struct fb_info *fbi); + +/** + * mx3fb_set_fix() - set fixed framebuffer parameters from variable settings. + * @info: framebuffer information pointer + * @return: 0 on success or negative error code on failure. + */ +static int mx3fb_set_fix(struct fb_info *fbi) +{ + struct fb_fix_screeninfo *fix = &fbi->fix; + struct fb_var_screeninfo *var = &fbi->var; + + strncpy(fix->id, "DISP3 BG", 8); + + fix->line_length = var->xres_virtual * var->bits_per_pixel / 8; + + fix->type = FB_TYPE_PACKED_PIXELS; + fix->accel = FB_ACCEL_NONE; + fix->visual = FB_VISUAL_TRUECOLOR; + fix->xpanstep = 1; + fix->ypanstep = 1; + + return 0; +} + +static void mx3fb_dma_done(void *arg) +{ + struct idmac_tx_desc *tx_desc = to_tx_desc(arg); + struct dma_chan *chan = tx_desc->txd.chan; + struct idmac_channel *ichannel = to_idmac_chan(chan); + struct mx3fb_data *mx3fb = ichannel->client; + struct mx3fb_info *mx3_fbi = mx3fb->fbi->par; + + dev_dbg(mx3fb->dev, "irq %d callback\n", ichannel->eof_irq); + + /* We only need one interrupt, it will be re-enabled as needed */ + disable_irq(ichannel->eof_irq); + + complete(&mx3_fbi->flip_cmpl); +} + +/** + * mx3fb_set_par() - set framebuffer parameters and change the operating mode. + * @fbi: framebuffer information pointer. + * @return: 0 on success or negative error code on failure. + */ +static int mx3fb_set_par(struct fb_info *fbi) +{ + u32 mem_len; + struct ipu_di_signal_cfg sig_cfg; + enum ipu_panel mode = IPU_PANEL_TFT; + struct mx3fb_info *mx3_fbi = fbi->par; + struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; + struct idmac_channel *ichan = mx3_fbi->idmac_channel; + struct idmac_video_param *video = &ichan->params.video; + struct scatterlist *sg = mx3_fbi->sg; + size_t screen_size; + + dev_dbg(mx3fb->dev, "%s [%c]\n", __func__, list_empty(&ichan->queue) ? '-' : '+'); + + mutex_lock(&mx3_fbi->mutex); + + /* Total cleanup */ + if (mx3_fbi->txd) + sdc_disable_channel(mx3_fbi); + + mx3fb_set_fix(fbi); + + mem_len = fbi->var.yres_virtual * fbi->fix.line_length; + if (mem_len > fbi->fix.smem_len) { + if (fbi->fix.smem_start) + mx3fb_unmap_video_memory(fbi); + + fbi->fix.smem_len = mem_len; + if (mx3fb_map_video_memory(fbi) < 0) { + mutex_unlock(&mx3_fbi->mutex); + return -ENOMEM; + } + } + + screen_size = fbi->fix.line_length * fbi->var.yres; + + sg_init_table(&sg[0], 1); + sg_init_table(&sg[1], 1); + + sg_dma_address(&sg[0]) = fbi->fix.smem_start; + sg_set_page(&sg[0], virt_to_page(fbi->screen_base), + fbi->fix.smem_len, + offset_in_page(fbi->screen_base)); + + if (mx3_fbi->ipu_ch == IDMAC_SDC_0) { + memset(&sig_cfg, 0, sizeof(sig_cfg)); + if (fbi->var.sync & FB_SYNC_HOR_HIGH_ACT) + sig_cfg.Hsync_pol = true; + if (fbi->var.sync & FB_SYNC_VERT_HIGH_ACT) + sig_cfg.Vsync_pol = true; + if (fbi->var.sync & FB_SYNC_CLK_INVERT) + sig_cfg.clk_pol = true; + if (fbi->var.sync & FB_SYNC_DATA_INVERT) + sig_cfg.data_pol = true; + if (fbi->var.sync & FB_SYNC_OE_ACT_HIGH) + sig_cfg.enable_pol = true; + if (fbi->var.sync & FB_SYNC_CLK_IDLE_EN) + sig_cfg.clkidle_en = true; + if (fbi->var.sync & FB_SYNC_CLK_SEL_EN) + sig_cfg.clksel_en = true; + if (fbi->var.sync & FB_SYNC_SHARP_MODE) + mode = IPU_PANEL_SHARP_TFT; + + dev_dbg(fbi->device, "pixclock = %ul Hz\n", + (u32) (PICOS2KHZ(fbi->var.pixclock) * 1000UL)); + + if (sdc_init_panel(mx3fb, mode, + (PICOS2KHZ(fbi->var.pixclock)) * 1000UL, + fbi->var.xres, fbi->var.yres, + (fbi->var.sync & FB_SYNC_SWAP_RGB) ? + IPU_PIX_FMT_BGR666 : IPU_PIX_FMT_RGB666, + fbi->var.left_margin, + fbi->var.hsync_len, + fbi->var.right_margin + + fbi->var.hsync_len, + fbi->var.upper_margin, + fbi->var.vsync_len, + fbi->var.lower_margin + + fbi->var.vsync_len, sig_cfg) != 0) { + mutex_unlock(&mx3_fbi->mutex); + dev_err(fbi->device, + "mx3fb: Error initializing panel.\n"); + return -EINVAL; + } + } + + sdc_set_window_pos(mx3fb, mx3_fbi->ipu_ch, 0, 0); + + mx3_fbi->cur_ipu_buf = 0; + + video->out_pixel_fmt = bpp_to_pixfmt(fbi->var.bits_per_pixel); + video->out_width = fbi->var.xres; + video->out_height = fbi->var.yres; + video->out_stride = fbi->var.xres_virtual; + + if (mx3_fbi->blank == FB_BLANK_UNBLANK) + sdc_enable_channel(mx3_fbi); + + mutex_unlock(&mx3_fbi->mutex); + + return 0; +} + +/** + * mx3fb_check_var() - check and adjust framebuffer variable parameters. + * @var: framebuffer variable parameters + * @fbi: framebuffer information pointer + */ +static int mx3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi) +{ + struct mx3fb_info *mx3_fbi = fbi->par; + u32 vtotal; + u32 htotal; + + dev_dbg(fbi->device, "%s\n", __func__); + + if (var->xres_virtual < var->xres) + var->xres_virtual = var->xres; + if (var->yres_virtual < var->yres) + var->yres_virtual = var->yres; + + if ((var->bits_per_pixel != 32) && (var->bits_per_pixel != 24) && + (var->bits_per_pixel != 16)) + var->bits_per_pixel = default_bpp; + + switch (var->bits_per_pixel) { + case 16: + var->red.length = 5; + var->red.offset = 11; + var->red.msb_right = 0; + + var->green.length = 6; + var->green.offset = 5; + var->green.msb_right = 0; + + var->blue.length = 5; + var->blue.offset = 0; + var->blue.msb_right = 0; + + var->transp.length = 0; + var->transp.offset = 0; + var->transp.msb_right = 0; + break; + case 24: + var->red.length = 8; + var->red.offset = 16; + var->red.msb_right = 0; + + var->green.length = 8; + var->green.offset = 8; + var->green.msb_right = 0; + + var->blue.length = 8; + var->blue.offset = 0; + var->blue.msb_right = 0; + + var->transp.length = 0; + var->transp.offset = 0; + var->transp.msb_right = 0; + break; + case 32: + var->red.length = 8; + var->red.offset = 16; + var->red.msb_right = 0; + + var->green.length = 8; + var->green.offset = 8; + var->green.msb_right = 0; + + var->blue.length = 8; + var->blue.offset = 0; + var->blue.msb_right = 0; + + var->transp.length = 8; + var->transp.offset = 24; + var->transp.msb_right = 0; + break; + } + + if (var->pixclock < 1000) { + htotal = var->xres + var->right_margin + var->hsync_len + + var->left_margin; + vtotal = var->yres + var->lower_margin + var->vsync_len + + var->upper_margin; + var->pixclock = (vtotal * htotal * 6UL) / 100UL; + var->pixclock = KHZ2PICOS(var->pixclock); + dev_dbg(fbi->device, "pixclock set for 60Hz refresh = %u ps\n", + var->pixclock); + } + + var->height = -1; + var->width = -1; + var->grayscale = 0; + + /* Preserve sync flags */ + var->sync |= mx3_fbi->sync; + mx3_fbi->sync |= var->sync; + + return 0; +} + +static u32 chan_to_field(unsigned int chan, struct fb_bitfield *bf) +{ + chan &= 0xffff; + chan >>= 16 - bf->length; + return chan << bf->offset; +} + +static int mx3fb_setcolreg(unsigned int regno, unsigned int red, + unsigned int green, unsigned int blue, + unsigned int trans, struct fb_info *fbi) +{ + struct mx3fb_info *mx3_fbi = fbi->par; + u32 val; + int ret = 1; + + dev_dbg(fbi->device, "%s\n", __func__); + + mutex_lock(&mx3_fbi->mutex); + /* + * If greyscale is true, then we convert the RGB value + * to greyscale no matter what visual we are using. + */ + if (fbi->var.grayscale) + red = green = blue = (19595 * red + 38470 * green + + 7471 * blue) >> 16; + switch (fbi->fix.visual) { + case FB_VISUAL_TRUECOLOR: + /* + * 16-bit True Colour. We encode the RGB value + * according to the RGB bitfield information. + */ + if (regno < 16) { + u32 *pal = fbi->pseudo_palette; + + val = chan_to_field(red, &fbi->var.red); + val |= chan_to_field(green, &fbi->var.green); + val |= chan_to_field(blue, &fbi->var.blue); + + pal[regno] = val; + + ret = 0; + } + break; + + case FB_VISUAL_STATIC_PSEUDOCOLOR: + case FB_VISUAL_PSEUDOCOLOR: + break; + } + mutex_unlock(&mx3_fbi->mutex); + + return ret; +} + +/** + * mx3fb_blank() - blank the display. + */ +static int mx3fb_blank(int blank, struct fb_info *fbi) +{ + struct mx3fb_info *mx3_fbi = fbi->par; + struct mx3fb_data *mx3fb = mx3_fbi->mx3fb; + + dev_dbg(fbi->device, "%s\n", __func__); + + dev_dbg(fbi->device, "blank = %d\n", blank); + + if (mx3_fbi->blank == blank) + return 0; + + mutex_lock(&mx3_fbi->mutex); + mx3_fbi->blank = blank; + + switch (blank) { + case FB_BLANK_POWERDOWN: + case FB_BLANK_VSYNC_SUSPEND: + case FB_BLANK_HSYNC_SUSPEND: + case FB_BLANK_NORMAL: + sdc_disable_channel(mx3_fbi); + sdc_set_brightness(mx3fb, 0); + break; + case FB_BLANK_UNBLANK: + sdc_enable_channel(mx3_fbi); + sdc_set_brightness(mx3fb, mx3fb->backlight_level); + break; + } + mutex_unlock(&mx3_fbi->mutex); + + return 0; +} + +/** + * mx3fb_pan_display() - pan or wrap the display + * @var: variable screen buffer information. + * @info: framebuffer information pointer. + * + * We look only at xoffset, yoffset and the FB_VMODE_YWRAP flag + */ +static int mx3fb_pan_display(struct fb_var_screeninfo *var, + struct fb_info *fbi) +{ + struct mx3fb_info *mx3_fbi = fbi->par; + u32 y_bottom; + unsigned long base; + off_t offset; + dma_cookie_t cookie; + struct scatterlist *sg = mx3_fbi->sg; + struct dma_chan *dma_chan = &mx3_fbi->idmac_channel->dma_chan; + struct dma_async_tx_descriptor *txd; + int ret; + + dev_dbg(fbi->device, "%s [%c]\n", __func__, + list_empty(&mx3_fbi->idmac_channel->queue) ? '-' : '+'); + + if (var->xoffset > 0) { + dev_dbg(fbi->device, "x panning not supported\n"); + return -EINVAL; + } + + if (fbi->var.xoffset == var->xoffset && + fbi->var.yoffset == var->yoffset) + return 0; /* No change, do nothing */ + + y_bottom = var->yoffset; + + if (!(var->vmode & FB_VMODE_YWRAP)) + y_bottom += var->yres; + + if (y_bottom > fbi->var.yres_virtual) + return -EINVAL; + + mutex_lock(&mx3_fbi->mutex); + + offset = (var->yoffset * var->xres_virtual + var->xoffset) * + (var->bits_per_pixel / 8); + base = fbi->fix.smem_start + offset; + + dev_dbg(fbi->device, "Updating SDC BG buf %d address=0x%08lX\n", + mx3_fbi->cur_ipu_buf, base); + + /* + * We enable the End of Frame interrupt, which will free a tx-descriptor, + * which we will need for the next device_prep_slave_sg(). The + * IRQ-handler will disable the IRQ again. + */ + init_completion(&mx3_fbi->flip_cmpl); + enable_irq(mx3_fbi->idmac_channel->eof_irq); + + ret = wait_for_completion_timeout(&mx3_fbi->flip_cmpl, HZ / 10); + if (ret <= 0) { + mutex_unlock(&mx3_fbi->mutex); + dev_info(fbi->device, "Panning failed due to %s\n", ret < 0 ? + "user interrupt" : "timeout"); + return ret ? : -ETIMEDOUT; + } + + mx3_fbi->cur_ipu_buf = !mx3_fbi->cur_ipu_buf; + + sg_dma_address(&sg[mx3_fbi->cur_ipu_buf]) = base; + sg_set_page(&sg[mx3_fbi->cur_ipu_buf], + virt_to_page(fbi->screen_base + offset), fbi->fix.smem_len, + offset_in_page(fbi->screen_base + offset)); + + txd = dma_chan->device->device_prep_slave_sg(dma_chan, sg + + mx3_fbi->cur_ipu_buf, 1, DMA_TO_DEVICE, DMA_PREP_INTERRUPT); + if (!txd) { + dev_err(fbi->device, + "Error preparing a DMA transaction descriptor.\n"); + mutex_unlock(&mx3_fbi->mutex); + return -EIO; + } + + txd->callback_param = txd; + txd->callback = mx3fb_dma_done; + + /* + * Emulate original mx3fb behaviour: each new call to idmac_tx_submit() + * should switch to another buffer + */ + cookie = txd->tx_submit(txd); + dev_dbg(fbi->device, "%d: Submit %p #%d\n", __LINE__, txd, cookie); + if (cookie < 0) { + dev_err(fbi->device, + "Error updating SDC buf %d to address=0x%08lX\n", + mx3_fbi->cur_ipu_buf, base); + mutex_unlock(&mx3_fbi->mutex); + return -EIO; + } + + if (mx3_fbi->txd) + async_tx_ack(mx3_fbi->txd); + mx3_fbi->txd = txd; + + fbi->var.xoffset = var->xoffset; + fbi->var.yoffset = var->yoffset; + + if (var->vmode & FB_VMODE_YWRAP) + fbi->var.vmode |= FB_VMODE_YWRAP; + else + fbi->var.vmode &= ~FB_VMODE_YWRAP; + + mutex_unlock(&mx3_fbi->mutex); + + dev_dbg(fbi->device, "Update complete\n"); + + return 0; +} + +/* + * This structure contains the pointers to the control functions that are + * invoked by the core framebuffer driver to perform operations like + * blitting, rectangle filling, copy regions and cursor definition. + */ +static struct fb_ops mx3fb_ops = { + .owner = THIS_MODULE, + .fb_set_par = mx3fb_set_par, + .fb_check_var = mx3fb_check_var, + .fb_setcolreg = mx3fb_setcolreg, + .fb_pan_display = mx3fb_pan_display, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, + .fb_blank = mx3fb_blank, +}; + +#ifdef CONFIG_PM +/* + * Power management hooks. Note that we won't be called from IRQ context, + * unlike the blank functions above, so we may sleep. + */ + +/* + * Suspends the framebuffer and blanks the screen. Power management support + */ +static int mx3fb_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct mx3fb_data *drv_data = platform_get_drvdata(pdev); + struct mx3fb_info *mx3_fbi = drv_data->fbi->par; + + acquire_console_sem(); + fb_set_suspend(drv_data->fbi, 1); + release_console_sem(); + + if (mx3_fbi->blank == FB_BLANK_UNBLANK) { + sdc_disable_channel(mx3_fbi); + sdc_set_brightness(mx3fb, 0); + + } + return 0; +} + +/* + * Resumes the framebuffer and unblanks the screen. Power management support + */ +static int mx3fb_resume(struct platform_device *pdev) +{ + struct mx3fb_data *drv_data = platform_get_drvdata(pdev); + struct mx3fb_info *mx3_fbi = drv_data->fbi->par; + + if (mx3_fbi->blank == FB_BLANK_UNBLANK) { + sdc_enable_channel(mx3_fbi); + sdc_set_brightness(mx3fb, drv_data->backlight_level); + } + + acquire_console_sem(); + fb_set_suspend(drv_data->fbi, 0); + release_console_sem(); + + return 0; +} +#else +#define mx3fb_suspend NULL +#define mx3fb_resume NULL +#endif + +/* + * Main framebuffer functions + */ + +/** + * mx3fb_map_video_memory() - allocates the DRAM memory for the frame buffer. + * @fbi: framebuffer information pointer + * @return: Error code indicating success or failure + * + * This buffer is remapped into a non-cached, non-buffered, memory region to + * allow palette and pixel writes to occur without flushing the cache. Once this + * area is remapped, all virtual memory access to the video memory should occur + * at the new region. + */ +static int mx3fb_map_video_memory(struct fb_info *fbi) +{ + int retval = 0; + dma_addr_t addr; + + fbi->screen_base = dma_alloc_writecombine(fbi->device, + fbi->fix.smem_len, + &addr, GFP_DMA); + + if (!fbi->screen_base) { + dev_err(fbi->device, "Cannot allocate %u bytes framebuffer memory\n", + fbi->fix.smem_len); + retval = -EBUSY; + goto err0; + } + + fbi->fix.smem_start = addr; + + dev_dbg(fbi->device, "allocated fb @ p=0x%08x, v=0x%p, size=%d.\n", + (uint32_t) fbi->fix.smem_start, fbi->screen_base, fbi->fix.smem_len); + + fbi->screen_size = fbi->fix.smem_len; + + /* Clear the screen */ + memset((char *)fbi->screen_base, 0, fbi->fix.smem_len); + + return 0; + +err0: + fbi->fix.smem_len = 0; + fbi->fix.smem_start = 0; + fbi->screen_base = NULL; + return retval; +} + +/** + * mx3fb_unmap_video_memory() - de-allocate frame buffer memory. + * @fbi: framebuffer information pointer + * @return: error code indicating success or failure + */ +static int mx3fb_unmap_video_memory(struct fb_info *fbi) +{ + dma_free_writecombine(fbi->device, fbi->fix.smem_len, + fbi->screen_base, fbi->fix.smem_start); + + fbi->screen_base = 0; + fbi->fix.smem_start = 0; + fbi->fix.smem_len = 0; + return 0; +} + +/** + * mx3fb_init_fbinfo() - initialize framebuffer information object. + * @return: initialized framebuffer structure. + */ +static struct fb_info *mx3fb_init_fbinfo(struct device *dev, struct fb_ops *ops) +{ + struct fb_info *fbi; + struct mx3fb_info *mx3fbi; + int ret; + + /* Allocate sufficient memory for the fb structure */ + fbi = framebuffer_alloc(sizeof(struct mx3fb_info), dev); + if (!fbi) + return NULL; + + mx3fbi = fbi->par; + mx3fbi->cookie = -EINVAL; + mx3fbi->cur_ipu_buf = 0; + + fbi->var.activate = FB_ACTIVATE_NOW; + + fbi->fbops = ops; + fbi->flags = FBINFO_FLAG_DEFAULT; + fbi->pseudo_palette = mx3fbi->pseudo_palette; + + mutex_init(&mx3fbi->mutex); + + /* Allocate colormap */ + ret = fb_alloc_cmap(&fbi->cmap, 16, 0); + if (ret < 0) { + framebuffer_release(fbi); + return NULL; + } + + return fbi; +} + +static int init_fb_chan(struct mx3fb_data *mx3fb, struct idmac_channel *ichan) +{ + struct device *dev = mx3fb->dev; + struct mx3fb_platform_data *mx3fb_pdata = dev->platform_data; + const char *name = mx3fb_pdata->name; + unsigned int irq; + struct fb_info *fbi; + struct mx3fb_info *mx3fbi; + const struct fb_videomode *mode; + int ret, num_modes; + + ichan->client = mx3fb; + irq = ichan->eof_irq; + + if (ichan->dma_chan.chan_id != IDMAC_SDC_0) + return -EINVAL; + + fbi = mx3fb_init_fbinfo(dev, &mx3fb_ops); + if (!fbi) + return -ENOMEM; + + if (!fb_mode) + fb_mode = name; + + if (!fb_mode) { + ret = -EINVAL; + goto emode; + } + + if (mx3fb_pdata->mode && mx3fb_pdata->num_modes) { + mode = mx3fb_pdata->mode; + num_modes = mx3fb_pdata->num_modes; + } else { + mode = mx3fb_modedb; + num_modes = ARRAY_SIZE(mx3fb_modedb); + } + + if (!fb_find_mode(&fbi->var, fbi, fb_mode, mode, + num_modes, NULL, default_bpp)) { + ret = -EBUSY; + goto emode; + } + + fb_videomode_to_modelist(mode, num_modes, &fbi->modelist); + + /* Default Y virtual size is 2x panel size */ + fbi->var.yres_virtual = fbi->var.yres * 2; + + mx3fb->fbi = fbi; + + /* set Display Interface clock period */ + mx3fb_write_reg(mx3fb, 0x00100010L, DI_HSP_CLK_PER); + /* Might need to trigger HSP clock change - see 44.3.3.8.5 */ + + sdc_set_brightness(mx3fb, 255); + sdc_set_global_alpha(mx3fb, true, 0xFF); + sdc_set_color_key(mx3fb, IDMAC_SDC_0, false, 0); + + mx3fbi = fbi->par; + mx3fbi->idmac_channel = ichan; + mx3fbi->ipu_ch = ichan->dma_chan.chan_id; + mx3fbi->mx3fb = mx3fb; + mx3fbi->blank = FB_BLANK_NORMAL; + + init_completion(&mx3fbi->flip_cmpl); + disable_irq(ichan->eof_irq); + dev_dbg(mx3fb->dev, "disabling irq %d\n", ichan->eof_irq); + ret = mx3fb_set_par(fbi); + if (ret < 0) + goto esetpar; + + mx3fb_blank(FB_BLANK_UNBLANK, fbi); + + dev_info(dev, "mx3fb: fb registered, using mode %s\n", fb_mode); + + ret = register_framebuffer(fbi); + if (ret < 0) + goto erfb; + + return 0; + +erfb: +esetpar: +emode: + fb_dealloc_cmap(&fbi->cmap); + framebuffer_release(fbi); + + return ret; +} + +static bool chan_filter(struct dma_chan *chan, void *arg) +{ + struct dma_chan_request *rq = arg; + struct device *dev; + struct mx3fb_platform_data *mx3fb_pdata; + + if (!rq) + return false; + + dev = rq->mx3fb->dev; + mx3fb_pdata = dev->platform_data; + + return rq->id == chan->chan_id && + mx3fb_pdata->dma_dev == chan->device->dev; +} + +static void release_fbi(struct fb_info *fbi) +{ + mx3fb_unmap_video_memory(fbi); + + fb_dealloc_cmap(&fbi->cmap); + + unregister_framebuffer(fbi); + framebuffer_release(fbi); +} + +static int mx3fb_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + int ret; + struct resource *sdc_reg; + struct mx3fb_data *mx3fb; + dma_cap_mask_t mask; + struct dma_chan *chan; + struct dma_chan_request rq; + + /* + * Display Interface (DI) and Synchronous Display Controller (SDC) + * registers + */ + sdc_reg = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!sdc_reg) + return -EINVAL; + + mx3fb = kzalloc(sizeof(*mx3fb), GFP_KERNEL); + if (!mx3fb) + return -ENOMEM; + + spin_lock_init(&mx3fb->lock); + + mx3fb->reg_base = ioremap(sdc_reg->start, resource_size(sdc_reg)); + if (!mx3fb->reg_base) { + ret = -ENOMEM; + goto eremap; + } + + pr_debug("Remapped %x to %x at %p\n", sdc_reg->start, sdc_reg->end, + mx3fb->reg_base); + + /* IDMAC interface */ + dmaengine_get(); + + mx3fb->dev = dev; + platform_set_drvdata(pdev, mx3fb); + + rq.mx3fb = mx3fb; + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + dma_cap_set(DMA_PRIVATE, mask); + rq.id = IDMAC_SDC_0; + chan = dma_request_channel(mask, chan_filter, &rq); + if (!chan) { + ret = -EBUSY; + goto ersdc0; + } + + ret = init_fb_chan(mx3fb, to_idmac_chan(chan)); + if (ret < 0) + goto eisdc0; + + mx3fb->backlight_level = 255; + + return 0; + +eisdc0: + dma_release_channel(chan); +ersdc0: + dmaengine_put(); + iounmap(mx3fb->reg_base); +eremap: + kfree(mx3fb); + dev_err(dev, "mx3fb: failed to register fb\n"); + return ret; +} + +static int mx3fb_remove(struct platform_device *dev) +{ + struct mx3fb_data *mx3fb = platform_get_drvdata(dev); + struct fb_info *fbi = mx3fb->fbi; + struct mx3fb_info *mx3_fbi = fbi->par; + struct dma_chan *chan; + + chan = &mx3_fbi->idmac_channel->dma_chan; + release_fbi(fbi); + + dma_release_channel(chan); + dmaengine_put(); + + iounmap(mx3fb->reg_base); + kfree(mx3fb); + return 0; +} + +static struct platform_driver mx3fb_driver = { + .driver = { + .name = MX3FB_NAME, + }, + .probe = mx3fb_probe, + .remove = mx3fb_remove, + .suspend = mx3fb_suspend, + .resume = mx3fb_resume, +}; + +/* + * Parse user specified options (`video=mx3fb:') + * example: + * video=mx3fb:bpp=16 + */ +static int mx3fb_setup(void) +{ +#ifndef MODULE + char *opt, *options = NULL; + + if (fb_get_options("mx3fb", &options)) + return -ENODEV; + + if (!options || !*options) + return 0; + + while ((opt = strsep(&options, ",")) != NULL) { + if (!*opt) + continue; + if (!strncmp(opt, "bpp=", 4)) + default_bpp = simple_strtoul(opt + 4, NULL, 0); + else + fb_mode = opt; + } +#endif + + return 0; +} + +static int __init mx3fb_init(void) +{ + int ret = mx3fb_setup(); + + if (ret < 0) + return ret; + + ret = platform_driver_register(&mx3fb_driver); + return ret; +} + +static void __exit mx3fb_exit(void) +{ + platform_driver_unregister(&mx3fb_driver); +} + +module_init(mx3fb_init); +module_exit(mx3fb_exit); + +MODULE_AUTHOR("Freescale Semiconductor, Inc."); +MODULE_DESCRIPTION("MX3 framebuffer driver"); +MODULE_ALIAS("platform:" MX3FB_NAME); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From ccfe30a7c8329e85ae426813a1060e27e2547dd1 Mon Sep 17 00:00:00 2001 From: Holger Schurig Date: Thu, 29 Jan 2009 10:07:50 +0100 Subject: arm/imx2x: new IOMUX definitions * removed iomux-mx1-mx2.h completely * distributes the former contents to four different files (iomux-mx1.h, iomux-mx21.h, iomux-mx27.h and the file iomux-mx2x.h, which is common to both i.MX21 and i.MX27). * adds all documented IOMUX definitions for i.MX21 and i.MX27 * fixes a few that were wrong (PD14_AOUT_FEC_CLR, PE16_AF_RTCK). * don't silenly include * and fixes all collateral damage from above Signed-off-by: Holger Schurig Signed-off-by: Sascha Hauer --- arch/arm/mach-mx1/devices.c | 1 + arch/arm/mach-mx1/mx1ads.c | 2 +- arch/arm/mach-mx2/mx27ads.c | 4 +- arch/arm/mach-mx2/pcm038.c | 7 +- arch/arm/plat-mxc/include/mach/iomux-mx1-mx2.h | 416 ------------------------- arch/arm/plat-mxc/include/mach/iomux-mx1.h | 166 ++++++++++ arch/arm/plat-mxc/include/mach/iomux-mx21.h | 126 ++++++++ arch/arm/plat-mxc/include/mach/iomux-mx27.h | 207 ++++++++++++ arch/arm/plat-mxc/include/mach/iomux-mx2x.h | 237 ++++++++++++++ arch/arm/plat-mxc/include/mach/iomux.h | 127 ++++++++ arch/arm/plat-mxc/iomux-mx1-mx2.c | 2 +- 11 files changed, 872 insertions(+), 423 deletions(-) delete mode 100644 arch/arm/plat-mxc/include/mach/iomux-mx1-mx2.h create mode 100644 arch/arm/plat-mxc/include/mach/iomux-mx1.h create mode 100644 arch/arm/plat-mxc/include/mach/iomux-mx21.h create mode 100644 arch/arm/plat-mxc/include/mach/iomux-mx27.h create mode 100644 arch/arm/plat-mxc/include/mach/iomux-mx2x.h create mode 100644 arch/arm/plat-mxc/include/mach/iomux.h (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/mach-mx1/devices.c b/arch/arm/mach-mx1/devices.c index 686d8d2dbb24..cea8f2c71192 100644 --- a/arch/arm/mach-mx1/devices.c +++ b/arch/arm/mach-mx1/devices.c @@ -23,6 +23,7 @@ #include #include #include +#include #include static struct resource imx_csi_resources[] = { diff --git a/arch/arm/mach-mx1/mx1ads.c b/arch/arm/mach-mx1/mx1ads.c index 2e4b185fe4a9..be7dd75ebbe1 100644 --- a/arch/arm/mach-mx1/mx1ads.c +++ b/arch/arm/mach-mx1/mx1ads.c @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include "devices.h" /* diff --git a/arch/arm/mach-mx2/mx27ads.c b/arch/arm/mach-mx2/mx27ads.c index 2b5c67f54571..7721c470d5ab 100644 --- a/arch/arm/mach-mx2/mx27ads.c +++ b/arch/arm/mach-mx2/mx27ads.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include "devices.h" @@ -196,7 +196,7 @@ static int mxc_fec_pins[] = { PD11_AOUT_FEC_TX_CLK, PD12_AOUT_FEC_RXD0, PD13_AOUT_FEC_RX_DV, - PD14_AOUT_FEC_CLR, + PD14_AOUT_FEC_RX_CLK, PD15_AOUT_FEC_COL, PD16_AIN_FEC_TX_ER, PF23_AIN_FEC_TX_EN diff --git a/arch/arm/mach-mx2/pcm038.c b/arch/arm/mach-mx2/pcm038.c index dfd4156da7d5..534fd9a4ff9f 100644 --- a/arch/arm/mach-mx2/pcm038.c +++ b/arch/arm/mach-mx2/pcm038.c @@ -20,11 +20,12 @@ #include #include #include +#include #include #include #include #include -#include +#include #include #include #include @@ -170,7 +171,7 @@ static int mxc_fec_pins[] = { PD11_AOUT_FEC_TX_CLK, PD12_AOUT_FEC_RXD0, PD13_AOUT_FEC_RX_DV, - PD14_AOUT_FEC_CLR, + PD14_AOUT_FEC_RX_CLK, PD15_AOUT_FEC_COL, PD16_AIN_FEC_TX_ER, PF23_AIN_FEC_TX_EN @@ -217,7 +218,7 @@ static void __init pcm038_init(void) mxc_register_device(&mxc_uart_device1, &uart_pdata[1]); mxc_register_device(&mxc_uart_device2, &uart_pdata[2]); - mxc_gpio_mode(PE16_AF_RTCK); /* OWIRE */ + mxc_gpio_mode(PE16_AF_OWIRE); mxc_register_device(&mxc_nand_device, &pcm038_nand_board_info); platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx1-mx2.h b/arch/arm/plat-mxc/include/mach/iomux-mx1-mx2.h deleted file mode 100644 index 95a383be628e..000000000000 --- a/arch/arm/plat-mxc/include/mach/iomux-mx1-mx2.h +++ /dev/null @@ -1,416 +0,0 @@ -/* - * Copyright (C) 2008 by Sascha Hauer - * - * 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. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#ifndef _MXC_GPIO_MX1_MX2_H -#define _MXC_GPIO_MX1_MX2_H - -#include - -/* - * GPIO Module and I/O Multiplexer - * x = 0..3 for reg_A, reg_B, reg_C, reg_D - */ -#define VA_GPIO_BASE IO_ADDRESS(GPIO_BASE_ADDR) -#define MXC_DDIR(x) (0x00 + ((x) << 8)) -#define MXC_OCR1(x) (0x04 + ((x) << 8)) -#define MXC_OCR2(x) (0x08 + ((x) << 8)) -#define MXC_ICONFA1(x) (0x0c + ((x) << 8)) -#define MXC_ICONFA2(x) (0x10 + ((x) << 8)) -#define MXC_ICONFB1(x) (0x14 + ((x) << 8)) -#define MXC_ICONFB2(x) (0x18 + ((x) << 8)) -#define MXC_DR(x) (0x1c + ((x) << 8)) -#define MXC_GIUS(x) (0x20 + ((x) << 8)) -#define MXC_SSR(x) (0x24 + ((x) << 8)) -#define MXC_ICR1(x) (0x28 + ((x) << 8)) -#define MXC_ICR2(x) (0x2c + ((x) << 8)) -#define MXC_IMR(x) (0x30 + ((x) << 8)) -#define MXC_ISR(x) (0x34 + ((x) << 8)) -#define MXC_GPR(x) (0x38 + ((x) << 8)) -#define MXC_SWR(x) (0x3c + ((x) << 8)) -#define MXC_PUEN(x) (0x40 + ((x) << 8)) - -#ifdef CONFIG_ARCH_MX1 -# define GPIO_PORT_MAX 3 -#endif -#ifdef CONFIG_ARCH_MX2 -# define GPIO_PORT_MAX 5 -#endif - -#ifndef GPIO_PORT_MAX -# error "GPIO config port count unknown!" -#endif - -#define GPIO_PIN_MASK 0x1f - -#define GPIO_PORT_SHIFT 5 -#define GPIO_PORT_MASK (0x7 << GPIO_PORT_SHIFT) - -#define GPIO_PORTA (0 << GPIO_PORT_SHIFT) -#define GPIO_PORTB (1 << GPIO_PORT_SHIFT) -#define GPIO_PORTC (2 << GPIO_PORT_SHIFT) -#define GPIO_PORTD (3 << GPIO_PORT_SHIFT) -#define GPIO_PORTE (4 << GPIO_PORT_SHIFT) -#define GPIO_PORTF (5 << GPIO_PORT_SHIFT) - -#define GPIO_OUT (1 << 8) -#define GPIO_IN (0 << 8) -#define GPIO_PUEN (1 << 9) - -#define GPIO_PF (1 << 10) -#define GPIO_AF (1 << 11) - -#define GPIO_OCR_SHIFT 12 -#define GPIO_OCR_MASK (3 << GPIO_OCR_SHIFT) -#define GPIO_AIN (0 << GPIO_OCR_SHIFT) -#define GPIO_BIN (1 << GPIO_OCR_SHIFT) -#define GPIO_CIN (2 << GPIO_OCR_SHIFT) -#define GPIO_GPIO (3 << GPIO_OCR_SHIFT) - -#define GPIO_AOUT_SHIFT 14 -#define GPIO_AOUT_MASK (3 << GPIO_AOUT_SHIFT) -#define GPIO_AOUT (0 << GPIO_AOUT_SHIFT) -#define GPIO_AOUT_ISR (1 << GPIO_AOUT_SHIFT) -#define GPIO_AOUT_0 (2 << GPIO_AOUT_SHIFT) -#define GPIO_AOUT_1 (3 << GPIO_AOUT_SHIFT) - -#define GPIO_BOUT_SHIFT 16 -#define GPIO_BOUT_MASK (3 << GPIO_BOUT_SHIFT) -#define GPIO_BOUT (0 << GPIO_BOUT_SHIFT) -#define GPIO_BOUT_ISR (1 << GPIO_BOUT_SHIFT) -#define GPIO_BOUT_0 (2 << GPIO_BOUT_SHIFT) -#define GPIO_BOUT_1 (3 << GPIO_BOUT_SHIFT) - -extern void mxc_gpio_mode(int gpio_mode); -extern int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count, - const char *label); -extern void mxc_gpio_release_multiple_pins(const int *pin_list, int count); - -/*-------------------------------------------------------------------------*/ - -/* assignements for GPIO alternate/primary functions */ - -/* FIXME: This list is not completed. The correct directions are - * missing on some (many) pins - */ -#ifdef CONFIG_ARCH_MX1 -#define PA0_AIN_SPI2_CLK (GPIO_PORTA | GPIO_OUT | 0) -#define PA0_AF_ETMTRACESYNC (GPIO_PORTA | GPIO_AF | 0) -#define PA1_AOUT_SPI2_RXD (GPIO_PORTA | GPIO_IN | 1) -#define PA1_PF_TIN (GPIO_PORTA | GPIO_PF | 1) -#define PA2_PF_PWM0 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 2) -#define PA3_PF_CSI_MCLK (GPIO_PORTA | GPIO_PF | 3) -#define PA4_PF_CSI_D0 (GPIO_PORTA | GPIO_PF | 4) -#define PA5_PF_CSI_D1 (GPIO_PORTA | GPIO_PF | 5) -#define PA6_PF_CSI_D2 (GPIO_PORTA | GPIO_PF | 6) -#define PA7_PF_CSI_D3 (GPIO_PORTA | GPIO_PF | 7) -#define PA8_PF_CSI_D4 (GPIO_PORTA | GPIO_PF | 8) -#define PA9_PF_CSI_D5 (GPIO_PORTA | GPIO_PF | 9) -#define PA10_PF_CSI_D6 (GPIO_PORTA | GPIO_PF | 10) -#define PA11_PF_CSI_D7 (GPIO_PORTA | GPIO_PF | 11) -#define PA12_PF_CSI_VSYNC (GPIO_PORTA | GPIO_PF | 12) -#define PA13_PF_CSI_HSYNC (GPIO_PORTA | GPIO_PF | 13) -#define PA14_PF_CSI_PIXCLK (GPIO_PORTA | GPIO_PF | 14) -#define PA15_PF_I2C_SDA (GPIO_PORTA | GPIO_OUT | GPIO_PF | 15) -#define PA16_PF_I2C_SCL (GPIO_PORTA | GPIO_OUT | GPIO_PF | 16) -#define PA17_AF_ETMTRACEPKT4 (GPIO_PORTA | GPIO_AF | 17) -#define PA17_AIN_SPI2_SS (GPIO_PORTA | GPIO_OUT | 17) -#define PA18_AF_ETMTRACEPKT5 (GPIO_PORTA | GPIO_AF | 18) -#define PA19_AF_ETMTRACEPKT6 (GPIO_PORTA | GPIO_AF | 19) -#define PA20_AF_ETMTRACEPKT7 (GPIO_PORTA | GPIO_AF | 20) -#define PA21_PF_A0 (GPIO_PORTA | GPIO_PF | 21) -#define PA22_PF_CS4 (GPIO_PORTA | GPIO_PF | 22) -#define PA23_PF_CS5 (GPIO_PORTA | GPIO_PF | 23) -#define PA24_PF_A16 (GPIO_PORTA | GPIO_PF | 24) -#define PA24_AF_ETMTRACEPKT0 (GPIO_PORTA | GPIO_AF | 24) -#define PA25_PF_A17 (GPIO_PORTA | GPIO_PF | 25) -#define PA25_AF_ETMTRACEPKT1 (GPIO_PORTA | GPIO_AF | 25) -#define PA26_PF_A18 (GPIO_PORTA | GPIO_PF | 26) -#define PA26_AF_ETMTRACEPKT2 (GPIO_PORTA | GPIO_AF | 26) -#define PA27_PF_A19 (GPIO_PORTA | GPIO_PF | 27) -#define PA27_AF_ETMTRACEPKT3 (GPIO_PORTA | GPIO_AF | 27) -#define PA28_PF_A20 (GPIO_PORTA | GPIO_PF | 28) -#define PA28_AF_ETMPIPESTAT0 (GPIO_PORTA | GPIO_AF | 28) -#define PA29_PF_A21 (GPIO_PORTA | GPIO_PF | 29) -#define PA29_AF_ETMPIPESTAT1 (GPIO_PORTA | GPIO_AF | 29) -#define PA30_PF_A22 (GPIO_PORTA | GPIO_PF | 30) -#define PA30_AF_ETMPIPESTAT2 (GPIO_PORTA | GPIO_AF | 30) -#define PA31_PF_A23 (GPIO_PORTA | GPIO_PF | 31) -#define PA31_AF_ETMTRACECLK (GPIO_PORTA | GPIO_AF | 31) -#define PB8_PF_SD_DAT0 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 8) -#define PB8_AF_MS_PIO (GPIO_PORTB | GPIO_AF | 8) -#define PB9_PF_SD_DAT1 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 9) -#define PB9_AF_MS_PI1 (GPIO_PORTB | GPIO_AF | 9) -#define PB10_PF_SD_DAT2 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 10) -#define PB10_AF_MS_SCLKI (GPIO_PORTB | GPIO_AF | 10) -#define PB11_PF_SD_DAT3 (GPIO_PORTB | GPIO_PF | 11) -#define PB11_AF_MS_SDIO (GPIO_PORTB | GPIO_AF | 11) -#define PB12_PF_SD_CLK (GPIO_PORTB | GPIO_PF | 12) -#define PB12_AF_MS_SCLK0 (GPIO_PORTB | GPIO_AF | 12) -#define PB13_PF_SD_CMD (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 13) -#define PB13_AF_MS_BS (GPIO_PORTB | GPIO_AF | 13) -#define PB14_AF_SSI_RXFS (GPIO_PORTB | GPIO_AF | 14) -#define PB15_AF_SSI_RXCLK (GPIO_PORTB | GPIO_AF | 15) -#define PB16_AF_SSI_RXDAT (GPIO_PORTB | GPIO_IN | GPIO_AF | 16) -#define PB17_AF_SSI_TXDAT (GPIO_PORTB | GPIO_OUT | GPIO_AF | 17) -#define PB18_AF_SSI_TXFS (GPIO_PORTB | GPIO_AF | 18) -#define PB19_AF_SSI_TXCLK (GPIO_PORTB | GPIO_AF | 19) -#define PB20_PF_USBD_AFE (GPIO_PORTB | GPIO_PF | 20) -#define PB21_PF_USBD_OE (GPIO_PORTB | GPIO_PF | 21) -#define PB22_PFUSBD_RCV (GPIO_PORTB | GPIO_PF | 22) -#define PB23_PF_USBD_SUSPND (GPIO_PORTB | GPIO_PF | 23) -#define PB24_PF_USBD_VP (GPIO_PORTB | GPIO_PF | 24) -#define PB25_PF_USBD_VM (GPIO_PORTB | GPIO_PF | 25) -#define PB26_PF_USBD_VPO (GPIO_PORTB | GPIO_PF | 26) -#define PB27_PF_USBD_VMO (GPIO_PORTB | GPIO_PF | 27) -#define PB28_PF_UART2_CTS (GPIO_PORTB | GPIO_OUT | GPIO_PF | 28) -#define PB29_PF_UART2_RTS (GPIO_PORTB | GPIO_IN | GPIO_PF | 29) -#define PB30_PF_UART2_TXD (GPIO_PORTB | GPIO_OUT | GPIO_PF | 30) -#define PB31_PF_UART2_RXD (GPIO_PORTB | GPIO_IN | GPIO_PF | 31) -#define PC3_PF_SSI_RXFS (GPIO_PORTC | GPIO_PF | 3) -#define PC4_PF_SSI_RXCLK (GPIO_PORTC | GPIO_PF | 4) -#define PC5_PF_SSI_RXDAT (GPIO_PORTC | GPIO_IN | GPIO_PF | 5) -#define PC6_PF_SSI_TXDAT (GPIO_PORTC | GPIO_OUT | GPIO_PF | 6) -#define PC7_PF_SSI_TXFS (GPIO_PORTC | GPIO_PF | 7) -#define PC8_PF_SSI_TXCLK (GPIO_PORTC | GPIO_PF | 8) -#define PC9_PF_UART1_CTS (GPIO_PORTC | GPIO_OUT | GPIO_PF | 9) -#define PC10_PF_UART1_RTS (GPIO_PORTC | GPIO_IN | GPIO_PF | 10) -#define PC11_PF_UART1_TXD (GPIO_PORTC | GPIO_OUT | GPIO_PF | 11) -#define PC12_PF_UART1_RXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 12) -#define PC13_PF_SPI1_SPI_RDY (GPIO_PORTC | GPIO_PF | 13) -#define PC14_PF_SPI1_SCLK (GPIO_PORTC | GPIO_PF | 14) -#define PC15_PF_SPI1_SS (GPIO_PORTC | GPIO_PF | 15) -#define PC16_PF_SPI1_MISO (GPIO_PORTC | GPIO_PF | 16) -#define PC17_PF_SPI1_MOSI (GPIO_PORTC | GPIO_PF | 17) -#define PC24_BIN_UART3_RI (GPIO_PORTC | GPIO_OUT | GPIO_BIN | 24) -#define PC25_BIN_UART3_DSR (GPIO_PORTC | GPIO_OUT | GPIO_BIN | 25) -#define PC26_AOUT_UART3_DTR (GPIO_PORTC | GPIO_IN | 26) -#define PC27_BIN_UART3_DCD (GPIO_PORTC | GPIO_OUT | GPIO_BIN | 27) -#define PC28_BIN_UART3_CTS (GPIO_PORTC | GPIO_OUT | GPIO_BIN | 28) -#define PC29_AOUT_UART3_RTS (GPIO_PORTC | GPIO_IN | 29) -#define PC30_BIN_UART3_TX (GPIO_PORTC | GPIO_BIN | 30) -#define PC31_AOUT_UART3_RX (GPIO_PORTC | GPIO_IN | 31) -#define PD6_PF_LSCLK (GPIO_PORTD | GPIO_OUT | GPIO_PF | 6) -#define PD7_PF_REV (GPIO_PORTD | GPIO_PF | 7) -#define PD7_AF_UART2_DTR (GPIO_PORTD | GPIO_IN | GPIO_AF | 7) -#define PD7_AIN_SPI2_SCLK (GPIO_PORTD | GPIO_AIN | 7) -#define PD8_PF_CLS (GPIO_PORTD | GPIO_PF | 8) -#define PD8_AF_UART2_DCD (GPIO_PORTD | GPIO_OUT | GPIO_AF | 8) -#define PD8_AIN_SPI2_SS (GPIO_PORTD | GPIO_AIN | 8) -#define PD9_PF_PS (GPIO_PORTD | GPIO_PF | 9) -#define PD9_AF_UART2_RI (GPIO_PORTD | GPIO_OUT | GPIO_AF | 9) -#define PD9_AOUT_SPI2_RXD (GPIO_PORTD | GPIO_IN | 9) -#define PD10_PF_SPL_SPR (GPIO_PORTD | GPIO_OUT | GPIO_PF | 10) -#define PD10_AF_UART2_DSR (GPIO_PORTD | GPIO_OUT | GPIO_AF | 10) -#define PD10_AIN_SPI2_TXD (GPIO_PORTD | GPIO_OUT | 10) -#define PD11_PF_CONTRAST (GPIO_PORTD | GPIO_OUT | GPIO_PF | 11) -#define PD12_PF_ACD_OE (GPIO_PORTD | GPIO_OUT | GPIO_PF | 12) -#define PD13_PF_LP_HSYNC (GPIO_PORTD | GPIO_OUT | GPIO_PF | 13) -#define PD14_PF_FLM_VSYNC (GPIO_PORTD | GPIO_OUT | GPIO_PF | 14) -#define PD15_PF_LD0 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 15) -#define PD16_PF_LD1 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 16) -#define PD17_PF_LD2 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 17) -#define PD18_PF_LD3 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 18) -#define PD19_PF_LD4 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 19) -#define PD20_PF_LD5 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 20) -#define PD21_PF_LD6 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 21) -#define PD22_PF_LD7 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 22) -#define PD23_PF_LD8 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 23) -#define PD24_PF_LD9 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 24) -#define PD25_PF_LD10 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 25) -#define PD26_PF_LD11 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 26) -#define PD27_PF_LD12 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 27) -#define PD28_PF_LD13 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 28) -#define PD29_PF_LD14 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 29) -#define PD30_PF_LD15 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 30) -#define PD31_PF_TMR2OUT (GPIO_PORTD | GPIO_PF | 31) -#define PD31_BIN_SPI2_TXD (GPIO_PORTD | GPIO_BIN | 31) -#endif - -#ifdef CONFIG_ARCH_MX2 -#define PA0_PF_USBH2_CLK (GPIO_PORTA | GPIO_PF | 0) -#define PA1_PF_USBH2_DIR (GPIO_PORTA | GPIO_PF | 1) -#define PA2_PF_USBH2_DATA7 (GPIO_PORTA | GPIO_PF | 2) -#define PA3_PF_USBH2_NXT (GPIO_PORTA | GPIO_PF | 3) -#define PA4_PF_USBH2_STP (GPIO_PORTA | GPIO_PF | 4) -#define PA5_PF_LSCLK (GPIO_PORTA | GPIO_OUT | GPIO_PF | 5) -#define PA6_PF_LD0 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 6) -#define PA7_PF_LD1 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 7) -#define PA8_PF_LD2 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 8) -#define PA9_PF_LD3 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 9) -#define PA10_PF_LD4 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 10) -#define PA11_PF_LD5 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 11) -#define PA12_PF_LD6 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 12) -#define PA13_PF_LD7 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 13) -#define PA14_PF_LD8 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 14) -#define PA15_PF_LD9 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 15) -#define PA16_PF_LD10 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 16) -#define PA17_PF_LD11 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 17) -#define PA18_PF_LD12 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 18) -#define PA19_PF_LD13 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 19) -#define PA20_PF_LD14 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 20) -#define PA21_PF_LD15 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 21) -#define PA22_PF_LD16 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 22) -#define PA23_PF_LD17 (GPIO_PORTA | GPIO_OUT | GPIO_PF | 23) -#define PA24_PF_REV (GPIO_PORTA | GPIO_OUT | GPIO_PF | 24) -#define PA25_PF_CLS (GPIO_PORTA | GPIO_OUT | GPIO_PF | 25) -#define PA26_PF_PS (GPIO_PORTA | GPIO_OUT | GPIO_PF | 26) -#define PA27_PF_SPL_SPR (GPIO_PORTA | GPIO_OUT | GPIO_PF | 27) -#define PA28_PF_HSYNC (GPIO_PORTA | GPIO_OUT | GPIO_PF | 28) -#define PA29_PF_VSYNC (GPIO_PORTA | GPIO_OUT | GPIO_PF | 29) -#define PA30_PF_CONTRAST (GPIO_PORTA | GPIO_OUT | GPIO_PF | 30) -#define PA31_PF_OE_ACD (GPIO_PORTA | GPIO_OUT | GPIO_PF | 31) -#define PB4_PF_SD2_D0 (GPIO_PORTB | GPIO_PF | 4) -#define PB5_PF_SD2_D1 (GPIO_PORTB | GPIO_PF | 5) -#define PB6_PF_SD2_D2 (GPIO_PORTB | GPIO_PF | 6) -#define PB7_PF_SD2_D3 (GPIO_PORTB | GPIO_PF | 7) -#define PB8_PF_SD2_CMD (GPIO_PORTB | GPIO_PF | 8) -#define PB9_PF_SD2_CLK (GPIO_PORTB | GPIO_PF | 9) -#define PB10_PF_CSI_D0 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 10) -#define PB10_AF_UART6_TXD (GPIO_PORTB | GPIO_OUT | GPIO_AF | 10) -#define PB11_PF_CSI_D1 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 11) -#define PB11_AF_UART6_RXD (GPIO_PORTB | GPIO_IN | GPIO_AF | 11) -#define PB12_PF_CSI_D2 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 12) -#define PB12_AF_UART6_CTS (GPIO_PORTB | GPIO_OUT | GPIO_AF | 12) -#define PB13_PF_CSI_D3 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 13) -#define PB13_AF_UART6_RTS (GPIO_PORTB | GPIO_IN | GPIO_AF | 13) -#define PB14_PF_CSI_D4 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 14) -#define PB15_PF_CSI_MCLK (GPIO_PORTB | GPIO_OUT | GPIO_PF | 15) -#define PB16_PF_CSI_PIXCLK (GPIO_PORTB | GPIO_OUT | GPIO_PF | 16) -#define PB17_PF_CSI_D5 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 17) -#define PB18_PF_CSI_D6 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 18) -#define PB18_AF_UART5_TXD (GPIO_PORTB | GPIO_OUT | GPIO_AF | 18) -#define PB19_PF_CSI_D7 (GPIO_PORTB | GPIO_OUT | GPIO_PF | 19) -#define PB19_AF_UART5_RXD (GPIO_PORTB | GPIO_IN | GPIO_AF | 19) -#define PB20_PF_CSI_VSYNC (GPIO_PORTB | GPIO_OUT | GPIO_PF | 20) -#define PB20_AF_UART5_CTS (GPIO_PORTB | GPIO_OUT | GPIO_AF | 20) -#define PB21_PF_CSI_HSYNC (GPIO_PORTB | GPIO_OUT | GPIO_PF | 21) -#define PB21_AF_UART5_RTS (GPIO_PORTB | GPIO_IN | GPIO_AF | 21) -#define PB22_PF_USBH1_SUSP (GPIO_PORTB | GPIO_PF | 22) -#define PB23_PF_USB_PWR (GPIO_PORTB | GPIO_PF | 23) -#define PB24_PF_USB_OC_B (GPIO_PORTB | GPIO_PF | 24) -#define PB25_PF_USBH1_RCV (GPIO_PORTB | GPIO_PF | 25) -#define PB26_PF_USBH1_FS (GPIO_PORTB | GPIO_PF | 26) -#define PB27_PF_USBH1_OE_B (GPIO_PORTB | GPIO_PF | 27) -#define PB28_PF_USBH1_TXDM (GPIO_PORTB | GPIO_PF | 28) -#define PB29_PF_USBH1_TXDP (GPIO_PORTB | GPIO_PF | 29) -#define PB30_PF_USBH1_RXDM (GPIO_PORTB | GPIO_PF | 30) -#define PB31_PF_USBH1_RXDP (GPIO_PORTB | GPIO_PF | 31) -#define PB26_AF_UART4_RTS (GPIO_PORTB | GPIO_IN | GPIO_PF | 26) -#define PB28_AF_UART4_TXD (GPIO_PORTB | GPIO_OUT | GPIO_AF | 28) -#define PB29_AF_UART4_CTS (GPIO_PORTB | GPIO_OUT | GPIO_AF | 29) -#define PB31_AF_UART4_RXD (GPIO_PORTB | GPIO_IN | GPIO_AF | 31) -#define PC5_PF_I2C2_SDA (GPIO_PORTC | GPIO_IN | GPIO_PF | 5) -#define PC6_PF_I2C2_SCL (GPIO_PORTC | GPIO_IN | GPIO_PF | 6) -#define PC7_PF_USBOTG_DATA5 (GPIO_PORTC | GPIO_OUT | GPIO_PF | 7) -#define PC8_PF_USBOTG_DATA6 (GPIO_PORTC | GPIO_OUT | GPIO_PF | 8) -#define PC9_PF_USBOTG_DATA0 (GPIO_PORTC | GPIO_OUT | GPIO_PF | 9) -#define PC10_PF_USBOTG_DATA2 (GPIO_PORTC | GPIO_OUT | GPIO_PF | 10) -#define PC11_PF_USBOTG_DATA1 (GPIO_PORTC | GPIO_OUT | GPIO_PF | 11) -#define PC12_PF_USBOTG_DATA4 (GPIO_PORTC | GPIO_OUT | GPIO_PF | 12) -#define PC13_PF_USBOTG_DATA3 (GPIO_PORTC | GPIO_OUT | GPIO_PF | 13) -#define PC16_PF_SSI4_FS (GPIO_PORTC | GPIO_IN | GPIO_PF | 16) -#define PC17_PF_SSI4_RXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 17) -#define PC18_PF_SSI4_TXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 18) -#define PC19_PF_SSI4_CLK (GPIO_PORTC | GPIO_IN | GPIO_PF | 19) -#define PC20_PF_SSI1_FS (GPIO_PORTC | GPIO_IN | GPIO_PF | 20) -#define PC21_PF_SSI1_RXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 21) -#define PC22_PF_SSI1_TXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 22) -#define PC23_PF_SSI1_CLK (GPIO_PORTC | GPIO_IN | GPIO_PF | 23) -#define PC24_PF_SSI2_FS (GPIO_PORTC | GPIO_IN | GPIO_PF | 24) -#define PC25_PF_SSI2_RXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 25) -#define PC26_PF_SSI2_TXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 26) -#define PC27_PF_SSI2_CLK (GPIO_PORTC | GPIO_IN | GPIO_PF | 27) -#define PC28_PF_SSI3_FS (GPIO_PORTC | GPIO_IN | GPIO_PF | 28) -#define PC29_PF_SSI3_RXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 29) -#define PC30_PF_SSI3_TXD (GPIO_PORTC | GPIO_IN | GPIO_PF | 30) -#define PC31_PF_SSI3_CLK (GPIO_PORTC | GPIO_IN | GPIO_PF | 31) -#define PD0_AIN_FEC_TXD0 (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 0) -#define PD1_AIN_FEC_TXD1 (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 1) -#define PD2_AIN_FEC_TXD2 (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 2) -#define PD3_AIN_FEC_TXD3 (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 3) -#define PD4_AOUT_FEC_RX_ER (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 4) -#define PD5_AOUT_FEC_RXD1 (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 5) -#define PD6_AOUT_FEC_RXD2 (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 6) -#define PD7_AOUT_FEC_RXD3 (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 7) -#define PD8_AF_FEC_MDIO (GPIO_PORTD | GPIO_IN | GPIO_AF | 8) -#define PD9_AIN_FEC_MDC (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 9) -#define PD10_AOUT_FEC_CRS (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 10) -#define PD11_AOUT_FEC_TX_CLK (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 11) -#define PD12_AOUT_FEC_RXD0 (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 12) -#define PD13_AOUT_FEC_RX_DV (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 13) -#define PD14_AOUT_FEC_CLR (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 14) -#define PD15_AOUT_FEC_COL (GPIO_PORTD | GPIO_IN | GPIO_AOUT | 15) -#define PD16_AIN_FEC_TX_ER (GPIO_PORTD | GPIO_OUT | GPIO_AIN | 16) -#define PD17_PF_I2C_DATA (GPIO_PORTD | GPIO_OUT | GPIO_PF | 17) -#define PD18_PF_I2C_CLK (GPIO_PORTD | GPIO_OUT | GPIO_PF | 18) -#define PD19_AF_USBH2_DATA4 (GPIO_PORTD | GPIO_AF | 19) -#define PD20_AF_USBH2_DATA3 (GPIO_PORTD | GPIO_AF | 20) -#define PD21_AF_USBH2_DATA6 (GPIO_PORTD | GPIO_AF | 21) -#define PD22_AF_USBH2_DATA0 (GPIO_PORTD | GPIO_AF | 22) -#define PD23_AF_USBH2_DATA2 (GPIO_PORTD | GPIO_AF | 23) -#define PD24_AF_USBH2_DATA1 (GPIO_PORTD | GPIO_AF | 24) -#define PD25_PF_CSPI1_RDY (GPIO_PORTD | GPIO_OUT | GPIO_PF | 25) -#define PD26_PF_CSPI1_SS2 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 26) -#define PD26_AF_USBH2_DATA5 (GPIO_PORTD | GPIO_AF | 26) -#define PD27_PF_CSPI1_SS1 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 27) -#define PD28_PF_CSPI1_SS0 (GPIO_PORTD | GPIO_OUT | GPIO_PF | 28) -#define PD29_PF_CSPI1_SCLK (GPIO_PORTD | GPIO_OUT | GPIO_PF | 29) -#define PD30_PF_CSPI1_MISO (GPIO_PORTD | GPIO_IN | GPIO_PF | 30) -#define PD31_PF_CSPI1_MOSI (GPIO_PORTD | GPIO_OUT | GPIO_PF | 31) -#define PF23_AIN_FEC_TX_EN (GPIO_PORTF | GPIO_OUT | GPIO_AIN | 23) -#define PE0_PF_USBOTG_NXT (GPIO_PORTE | GPIO_OUT | GPIO_PF | 0) -#define PE1_PF_USBOTG_STP (GPIO_PORTE | GPIO_OUT | GPIO_PF | 1) -#define PE2_PF_USBOTG_DIR (GPIO_PORTE | GPIO_OUT | GPIO_PF | 2) -#define PE3_PF_UART2_CTS (GPIO_PORTE | GPIO_OUT | GPIO_PF | 3) -#define PE4_PF_UART2_RTS (GPIO_PORTE | GPIO_IN | GPIO_PF | 4) -#define PE6_PF_UART2_TXD (GPIO_PORTE | GPIO_OUT | GPIO_PF | 6) -#define PE7_PF_UART2_RXD (GPIO_PORTE | GPIO_IN | GPIO_PF | 7) -#define PE8_PF_UART3_TXD (GPIO_PORTE | GPIO_OUT | GPIO_PF | 8) -#define PE9_PF_UART3_RXD (GPIO_PORTE | GPIO_IN | GPIO_PF | 9) -#define PE10_PF_UART3_CTS (GPIO_PORTE | GPIO_OUT | GPIO_PF | 10) -#define PE11_PF_UART3_RTS (GPIO_PORTE | GPIO_IN | GPIO_PF | 11) -#define PE12_PF_UART1_TXD (GPIO_PORTE | GPIO_OUT | GPIO_PF | 12) -#define PE13_PF_UART1_RXD (GPIO_PORTE | GPIO_IN | GPIO_PF | 13) -#define PE14_PF_UART1_CTS (GPIO_PORTE | GPIO_OUT | GPIO_PF | 14) -#define PE15_PF_UART1_RTS (GPIO_PORTE | GPIO_IN | GPIO_PF | 15) -#define PE16_AF_RTCK (GPIO_PORTE | GPIO_OUT | GPIO_AF | 16) -#define PE16_PF_RTCK (GPIO_PORTE | GPIO_OUT | GPIO_PF | 16) -#define PE18_PF_SDHC1_D0 (GPIO_PORTE | GPIO_PF | 18) -#define PE18_AF_CSPI3_MISO (GPIO_PORTE | GPIO_IN | GPIO_AF | 18) -#define PE19_PF_SDHC1_D1 (GPIO_PORTE | GPIO_PF | 19) -#define PE20_PF_SDHC1_D2 (GPIO_PORTE | GPIO_PF | 20) -#define PE21_PF_SDHC1_D3 (GPIO_PORTE | GPIO_PF | 21) -#define PE21_AF_CSPI3_SS (GPIO_PORTE | GPIO_OUT | GPIO_AF | 21) -#define PE22_PF_SDHC1_CMD (GPIO_PORTE | GPIO_PF | 22) -#define PE22_AF_CSPI3_MOSI (GPIO_PORTE | GPIO_OUT | GPIO_AF | 22) -#define PE22_PF_SDHC1_CLK (GPIO_PORTE | GPIO_PF | 23) -#define PE23_AF_CSPI3_SCLK (GPIO_PORTE | GPIO_OUT | GPIO_AF | 23) -#define PE24_PF_USBOTG_CLK (GPIO_PORTE | GPIO_OUT | GPIO_PF | 24) -#define PE25_PF_USBOTG_DATA7 (GPIO_PORTE | GPIO_OUT | GPIO_PF | 25) -#endif - -/* decode irq number to use with IMR(x), ISR(x) and friends */ -#define IRQ_TO_REG(irq) ((irq - MXC_INTERNAL_IRQS) >> 5) - -#define IRQ_GPIOA(x) (MXC_GPIO_IRQ_START + x) -#define IRQ_GPIOB(x) (IRQ_GPIOA(32) + x) -#define IRQ_GPIOC(x) (IRQ_GPIOB(32) + x) -#define IRQ_GPIOD(x) (IRQ_GPIOC(32) + x) -#define IRQ_GPIOE(x) (IRQ_GPIOD(32) + x) - -#endif /* _MXC_GPIO_MX1_MX2_H */ diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx1.h b/arch/arm/plat-mxc/include/mach/iomux-mx1.h new file mode 100644 index 000000000000..bf23305c19cc --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/iomux-mx1.h @@ -0,0 +1,166 @@ +/* +* Copyright (C) 2008 by Sascha Hauer +* +* 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. +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +* MA 02110-1301, USA. +*/ + +#ifndef _MXC_IOMUX_MX1_H +#define _MXC_IOMUX_MX1_H + +#ifndef GPIO_PORTA +#error Please include mach/iomux.h +#endif + +/* FIXME: This list is not completed. The correct directions are +* missing on some (many) pins +*/ + + +/* Primary GPIO pin functions */ + +#define PA0_AIN_SPI2_CLK (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 0) +#define PA0_AF_ETMTRACESYNC (GPIO_PORTA | GPIO_AF | 0) +#define PA1_AOUT_SPI2_RXD (GPIO_PORTA | GPIO_AOUT | GPIO_IN | 1) +#define PA1_PF_TIN (GPIO_PORTA | GPIO_PF | 1) +#define PA2_PF_PWM0 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 2) +#define PA3_PF_CSI_MCLK (GPIO_PORTA | GPIO_PF | 3) +#define PA4_PF_CSI_D0 (GPIO_PORTA | GPIO_PF | 4) +#define PA5_PF_CSI_D1 (GPIO_PORTA | GPIO_PF | 5) +#define PA6_PF_CSI_D2 (GPIO_PORTA | GPIO_PF | 6) +#define PA7_PF_CSI_D3 (GPIO_PORTA | GPIO_PF | 7) +#define PA8_PF_CSI_D4 (GPIO_PORTA | GPIO_PF | 8) +#define PA9_PF_CSI_D5 (GPIO_PORTA | GPIO_PF | 9) +#define PA10_PF_CSI_D6 (GPIO_PORTA | GPIO_PF | 10) +#define PA11_PF_CSI_D7 (GPIO_PORTA | GPIO_PF | 11) +#define PA12_PF_CSI_VSYNC (GPIO_PORTA | GPIO_PF | 12) +#define PA13_PF_CSI_HSYNC (GPIO_PORTA | GPIO_PF | 13) +#define PA14_PF_CSI_PIXCLK (GPIO_PORTA | GPIO_PF | 14) +#define PA15_PF_I2C_SDA (GPIO_PORTA | GPIO_PF | GPIO_OUT | 15) +#define PA16_PF_I2C_SCL (GPIO_PORTA | GPIO_PF | GPIO_OUT | 16) +#define PA17_AF_ETMTRACEPKT4 (GPIO_PORTA | GPIO_AF | 17) +#define PA17_AIN_SPI2_SS (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 17) +#define PA18_AF_ETMTRACEPKT5 (GPIO_PORTA | GPIO_AF | 18) +#define PA19_AF_ETMTRACEPKT6 (GPIO_PORTA | GPIO_AF | 19) +#define PA20_AF_ETMTRACEPKT7 (GPIO_PORTA | GPIO_AF | 20) +#define PA21_PF_A0 (GPIO_PORTA | GPIO_PF | 21) +#define PA22_PF_CS4 (GPIO_PORTA | GPIO_PF | 22) +#define PA23_PF_CS5 (GPIO_PORTA | GPIO_PF | 23) +#define PA24_PF_A16 (GPIO_PORTA | GPIO_PF | 24) +#define PA24_AF_ETMTRACEPKT0 (GPIO_PORTA | GPIO_AF | 24) +#define PA25_PF_A17 (GPIO_PORTA | GPIO_PF | 25) +#define PA25_AF_ETMTRACEPKT1 (GPIO_PORTA | GPIO_AF | 25) +#define PA26_PF_A18 (GPIO_PORTA | GPIO_PF | 26) +#define PA26_AF_ETMTRACEPKT2 (GPIO_PORTA | GPIO_AF | 26) +#define PA27_PF_A19 (GPIO_PORTA | GPIO_PF | 27) +#define PA27_AF_ETMTRACEPKT3 (GPIO_PORTA | GPIO_AF | 27) +#define PA28_PF_A20 (GPIO_PORTA | GPIO_PF | 28) +#define PA28_AF_ETMPIPESTAT0 (GPIO_PORTA | GPIO_AF | 28) +#define PA29_PF_A21 (GPIO_PORTA | GPIO_PF | 29) +#define PA29_AF_ETMPIPESTAT1 (GPIO_PORTA | GPIO_AF | 29) +#define PA30_PF_A22 (GPIO_PORTA | GPIO_PF | 30) +#define PA30_AF_ETMPIPESTAT2 (GPIO_PORTA | GPIO_AF | 30) +#define PA31_PF_A23 (GPIO_PORTA | GPIO_PF | 31) +#define PA31_AF_ETMTRACECLK (GPIO_PORTA | GPIO_AF | 31) +#define PB8_PF_SD_DAT0 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 8) +#define PB8_AF_MS_PIO (GPIO_PORTB | GPIO_AF | 8) +#define PB9_PF_SD_DAT1 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 9) +#define PB9_AF_MS_PI1 (GPIO_PORTB | GPIO_AF | 9) +#define PB10_PF_SD_DAT2 (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 10) +#define PB10_AF_MS_SCLKI (GPIO_PORTB | GPIO_AF | 10) +#define PB11_PF_SD_DAT3 (GPIO_PORTB | GPIO_PF | 11) +#define PB11_AF_MS_SDIO (GPIO_PORTB | GPIO_AF | 11) +#define PB12_PF_SD_CLK (GPIO_PORTB | GPIO_PF | 12) +#define PB12_AF_MS_SCLK0 (GPIO_PORTB | GPIO_AF | 12) +#define PB13_PF_SD_CMD (GPIO_PORTB | GPIO_PF | GPIO_PUEN | 13) +#define PB13_AF_MS_BS (GPIO_PORTB | GPIO_AF | 13) +#define PB14_AF_SSI_RXFS (GPIO_PORTB | GPIO_AF | 14) +#define PB15_AF_SSI_RXCLK (GPIO_PORTB | GPIO_AF | 15) +#define PB16_AF_SSI_RXDAT (GPIO_PORTB | GPIO_AF | GPIO_IN | 16) +#define PB17_AF_SSI_TXDAT (GPIO_PORTB | GPIO_AF | GPIO_OUT | 17) +#define PB18_AF_SSI_TXFS (GPIO_PORTB | GPIO_AF | 18) +#define PB19_AF_SSI_TXCLK (GPIO_PORTB | GPIO_AF | 19) +#define PB20_PF_USBD_AFE (GPIO_PORTB | GPIO_PF | 20) +#define PB21_PF_USBD_OE (GPIO_PORTB | GPIO_PF | 21) +#define PB22_PF_USBD_RCV (GPIO_PORTB | GPIO_PF | 22) +#define PB23_PF_USBD_SUSPND (GPIO_PORTB | GPIO_PF | 23) +#define PB24_PF_USBD_VP (GPIO_PORTB | GPIO_PF | 24) +#define PB25_PF_USBD_VM (GPIO_PORTB | GPIO_PF | 25) +#define PB26_PF_USBD_VPO (GPIO_PORTB | GPIO_PF | 26) +#define PB27_PF_USBD_VMO (GPIO_PORTB | GPIO_PF | 27) +#define PB28_PF_UART2_CTS (GPIO_PORTB | GPIO_PF | GPIO_OUT | 28) +#define PB29_PF_UART2_RTS (GPIO_PORTB | GPIO_PF | GPIO_IN | 29) +#define PB30_PF_UART2_TXD (GPIO_PORTB | GPIO_PF | GPIO_OUT | 30) +#define PB31_PF_UART2_RXD (GPIO_PORTB | GPIO_PF | GPIO_IN | 31) +#define PC3_PF_SSI_RXFS (GPIO_PORTC | GPIO_PF | 3) +#define PC4_PF_SSI_RXCLK (GPIO_PORTC | GPIO_PF | 4) +#define PC5_PF_SSI_RXDAT (GPIO_PORTC | GPIO_PF | GPIO_IN | 5) +#define PC6_PF_SSI_TXDAT (GPIO_PORTC | GPIO_PF | GPIO_OUT | 6) +#define PC7_PF_SSI_TXFS (GPIO_PORTC | GPIO_PF | 7) +#define PC8_PF_SSI_TXCLK (GPIO_PORTC | GPIO_PF | 8) +#define PC9_PF_UART1_CTS (GPIO_PORTC | GPIO_PF | GPIO_OUT | 9) +#define PC10_PF_UART1_RTS (GPIO_PORTC | GPIO_PF | GPIO_IN | 10) +#define PC11_PF_UART1_TXD (GPIO_PORTC | GPIO_PF | GPIO_OUT | 11) +#define PC12_PF_UART1_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 12) +#define PC13_PF_SPI1_SPI_RDY (GPIO_PORTC | GPIO_PF | 13) +#define PC14_PF_SPI1_SCLK (GPIO_PORTC | GPIO_PF | 14) +#define PC15_PF_SPI1_SS (GPIO_PORTC | GPIO_PF | 15) +#define PC16_PF_SPI1_MISO (GPIO_PORTC | GPIO_PF | 16) +#define PC17_PF_SPI1_MOSI (GPIO_PORTC | GPIO_PF | 17) +#define PC24_BIN_UART3_RI (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 24) +#define PC25_BIN_UART3_DSR (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 25) +#define PC26_AOUT_UART3_DTR (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 26) +#define PC27_BIN_UART3_DCD (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 27) +#define PC28_BIN_UART3_CTS (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 28) +#define PC29_AOUT_UART3_RTS (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 29) +#define PC30_BIN_UART3_TX (GPIO_PORTC | GPIO_BIN | 30) +#define PC31_AOUT_UART3_RX (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 31) +#define PD6_PF_LSCLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 6) +#define PD7_PF_REV (GPIO_PORTD | GPIO_PF | 7) +#define PD7_AF_UART2_DTR (GPIO_PORTD | GPIO_AF | GPIO_IN | 7) +#define PD7_AIN_SPI2_SCLK (GPIO_PORTD | GPIO_AIN | 7) +#define PD8_PF_CLS (GPIO_PORTD | GPIO_PF | 8) +#define PD8_AF_UART2_DCD (GPIO_PORTD | GPIO_AF | GPIO_OUT | 8) +#define PD8_AIN_SPI2_SS (GPIO_PORTD | GPIO_AIN | 8) +#define PD9_PF_PS (GPIO_PORTD | GPIO_PF | 9) +#define PD9_AF_UART2_RI (GPIO_PORTD | GPIO_AF | GPIO_OUT | 9) +#define PD9_AOUT_SPI2_RXD (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 9) +#define PD10_PF_SPL_SPR (GPIO_PORTD | GPIO_PF | GPIO_OUT | 10) +#define PD10_AF_UART2_DSR (GPIO_PORTD | GPIO_AF | GPIO_OUT | 10) +#define PD10_AIN_SPI2_TXD (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 10) +#define PD11_PF_CONTRAST (GPIO_PORTD | GPIO_PF | GPIO_OUT | 11) +#define PD12_PF_ACD_OE (GPIO_PORTD | GPIO_PF | GPIO_OUT | 12) +#define PD13_PF_LP_HSYNC (GPIO_PORTD | GPIO_PF | GPIO_OUT | 13) +#define PD14_PF_FLM_VSYNC (GPIO_PORTD | GPIO_PF | GPIO_OUT | 14) +#define PD15_PF_LD0 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 15) +#define PD16_PF_LD1 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 16) +#define PD17_PF_LD2 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 17) +#define PD18_PF_LD3 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 18) +#define PD19_PF_LD4 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 19) +#define PD20_PF_LD5 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 20) +#define PD21_PF_LD6 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 21) +#define PD22_PF_LD7 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 22) +#define PD23_PF_LD8 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 23) +#define PD24_PF_LD9 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 24) +#define PD25_PF_LD10 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 25) +#define PD26_PF_LD11 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 26) +#define PD27_PF_LD12 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 27) +#define PD28_PF_LD13 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 28) +#define PD29_PF_LD14 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 29) +#define PD30_PF_LD15 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 30) +#define PD31_PF_TMR2OUT (GPIO_PORTD | GPIO_PF | 31) +#define PD31_BIN_SPI2_TXD (GPIO_PORTD | GPIO_BIN | 31) + + +#endif diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx21.h b/arch/arm/plat-mxc/include/mach/iomux-mx21.h new file mode 100644 index 000000000000..63aaa972e275 --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/iomux-mx21.h @@ -0,0 +1,126 @@ +/* +* Copyright (C) 2009 by Holger Schurig +* +* 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. +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +* MA 02110-1301, USA. +*/ + +#ifndef _MXC_IOMUX_MX21_H +#define _MXC_IOMUX_MX21_H + +#ifndef GPIO_PORTA +#error Please include mach/iomux.h +#endif + + +/* Primary GPIO pin functions */ + +#define PB22_PF_USBH1_BYP (GPIO_PORTB | GPIO_PF | 22) +#define PB25_PF_USBH1_ON (GPIO_PORTB | GPIO_PF | 25) +#define PC5_PF_USBOTG_SDA (GPIO_PORTC | GPIO_PF | 5) +#define PC6_PF_USBOTG_SCL (GPIO_PORTC | GPIO_PF | 6) +#define PC7_PF_USBOTG_ON (GPIO_PORTC | GPIO_PF | 7) +#define PC8_PF_USBOTG_FS (GPIO_PORTC | GPIO_PF | 8) +#define PC9_PF_USBOTG_OE (GPIO_PORTC | GPIO_PF | 9) +#define PC10_PF_USBOTG_TXDM (GPIO_PORTC | GPIO_PF | 10) +#define PC11_PF_USBOTG_TXDP (GPIO_PORTC | GPIO_PF | 11) +#define PC12_PF_USBOTG_RXDM (GPIO_PORTC | GPIO_PF | 12) +#define PC13_PF_USBOTG_RXDP (GPIO_PORTC | GPIO_PF | 13) +#define PC16_PF_SAP_FS (GPIO_PORTC | GPIO_PF | 16) +#define PC17_PF_SAP_RXD (GPIO_PORTC | GPIO_PF | 17) +#define PC18_PF_SAP_TXD (GPIO_PORTC | GPIO_PF | 18) +#define PC19_PF_SAP_CLK (GPIO_PORTC | GPIO_PF | 19) +#define PE0_PF_TEST_WB2 (GPIO_PORTE | GPIO_PF | 0) +#define PE1_PF_TEST_WB1 (GPIO_PORTE | GPIO_PF | 1) +#define PE2_PF_TEST_WB0 (GPIO_PORTE | GPIO_PF | 2) +#define PF1_PF_NFCE (GPIO_PORTF | GPIO_PF | 1) +#define PF3_PF_NFCLE (GPIO_PORTF | GPIO_PF | 3) +#define PF7_PF_NFIO0 (GPIO_PORTF | GPIO_PF | 7) +#define PF8_PF_NFIO1 (GPIO_PORTF | GPIO_PF | 8) +#define PF9_PF_NFIO2 (GPIO_PORTF | GPIO_PF | 9) +#define PF10_PF_NFIO3 (GPIO_PORTF | GPIO_PF | 10) +#define PF11_PF_NFIO4 (GPIO_PORTF | GPIO_PF | 11) +#define PF12_PF_NFIO5 (GPIO_PORTF | GPIO_PF | 12) +#define PF13_PF_NFIO6 (GPIO_PORTF | GPIO_PF | 13) +#define PF14_PF_NFIO7 (GPIO_PORTF | GPIO_PF | 14) +#define PF16_PF_RES (GPIO_PORTF | GPIO_PF | 16) + +/* Alternate GPIO pin functions */ + +#define PA5_AF_BMI_CLK_CS (GPIO_PORTA | GPIO_AF | 5) +#define PA6_AF_BMI_D0 (GPIO_PORTA | GPIO_AF | 6) +#define PA7_AF_BMI_D1 (GPIO_PORTA | GPIO_AF | 7) +#define PA8_AF_BMI_D2 (GPIO_PORTA | GPIO_AF | 8) +#define PA9_AF_BMI_D3 (GPIO_PORTA | GPIO_AF | 9) +#define PA10_AF_BMI_D4 (GPIO_PORTA | GPIO_AF | 10) +#define PA11_AF_BMI_D5 (GPIO_PORTA | GPIO_AF | 11) +#define PA12_AF_BMI_D6 (GPIO_PORTA | GPIO_AF | 12) +#define PA13_AF_BMI_D7 (GPIO_PORTA | GPIO_AF | 13) +#define PA14_AF_BMI_D8 (GPIO_PORTA | GPIO_AF | 14) +#define PA15_AF_BMI_D9 (GPIO_PORTA | GPIO_AF | 15) +#define PA16_AF_BMI_D10 (GPIO_PORTA | GPIO_AF | 16) +#define PA17_AF_BMI_D11 (GPIO_PORTA | GPIO_AF | 17) +#define PA18_AF_BMI_D12 (GPIO_PORTA | GPIO_AF | 18) +#define PA19_AF_BMI_D13 (GPIO_PORTA | GPIO_AF | 19) +#define PA20_AF_BMI_D14 (GPIO_PORTA | GPIO_AF | 20) +#define PA21_AF_BMI_D15 (GPIO_PORTA | GPIO_AF | 21) +#define PA22_AF_BMI_READ_REQ (GPIO_PORTA | GPIO_AF | 22) +#define PA23_AF_BMI_WRITE (GPIO_PORTA | GPIO_AF | 23) +#define PA29_AF_BMI_RX_FULL (GPIO_PORTA | GPIO_AF | 29) +#define PA30_AF_BMI_READ (GPIO_PORTA | GPIO_AF | 30) + +/* AIN GPIO pin functions */ + +#define PC14_AIN_SYS_CLK (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 14) +#define PD21_AIN_USBH2_FS (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 21) +#define PD22_AIN_USBH2_OE (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 22) +#define PD23_AIN_USBH2_TXDM (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 23) +#define PD24_AIN_USBH2_TXDP (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 24) +#define PE8_AIN_IR_TXD (GPIO_PORTE | GPIO_AIN | GPIO_OUT | 8) +#define PF0_AIN_PC_RST (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 0) +#define PF1_AIN_PC_CE1 (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 1) +#define PF2_AIN_PC_CE2 (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 2) +#define PF3_AIN_PC_POE (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 3) +#define PF4_AIN_PC_OE (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 4) +#define PF5_AIN_PC_RW (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 5) + +/* BIN GPIO pin functions */ + +#define PC14_BIN_SYS_CLK (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 14) +#define PD27_BIN_EXT_DMA_GRANT (GPIO_PORTD | GPIO_BIN | GPIO_OUT | 27) + +/* CIN GPIO pin functions */ + +#define PB26_CIN_USBH1_RXDAT (GPIO_PORTB | GPIO_CIN | GPIO_OUT | 26) + +/* AOUT GPIO pin functions */ + +#define PA29_AOUT_BMI_WAIT (GPIO_PORTA | GPIO_AOUT | GPIO_IN | 29) +#define PD19_AOUT_USBH2_RXDM (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 19) +#define PD20_AOUT_USBH2_RXDP (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 20) +#define PD25_AOUT_EXT_DMAREQ (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 25) +#define PD26_AOUT_USBOTG_RXDAT (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 26) +#define PE9_AOUT_IR_RXD (GPIO_PORTE | GPIO_AOUT | GPIO_IN | 9) +#define PF6_AOUT_PC_BVD2 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 6) +#define PF7_AOUT_PC_BVD1 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 7) +#define PF8_AOUT_PC_VS2 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 8) +#define PF9_AOUT_PC_VS1 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 9) +#define PF10_AOUT_PC_WP (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 10) +#define PF11_AOUT_PC_READY (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 11) +#define PF12_AOUT_PC_WAIT (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 12) +#define PF13_AOUT_PC_CD2 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 13) +#define PF14_AOUT_PC_CD1 (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 14) + + +#endif diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx27.h b/arch/arm/plat-mxc/include/mach/iomux-mx27.h new file mode 100644 index 000000000000..5ac158b70f61 --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/iomux-mx27.h @@ -0,0 +1,207 @@ +/* +* Copyright (C) 2008 by Sascha Hauer +* Copyright (C) 2009 by Holger Schurig +* +* 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. +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +* MA 02110-1301, USA. +*/ + +#ifndef _MXC_IOMUX_MX27_H +#define _MXC_IOMUX_MX27_H + +#ifndef GPIO_PORTA +#error Please include mach/iomux.h +#endif + + +/* Primary GPIO pin functions */ + +#define PA0_PF_USBH2_CLK (GPIO_PORTA | GPIO_PF | 0) +#define PA1_PF_USBH2_DIR (GPIO_PORTA | GPIO_PF | 1) +#define PA2_PF_USBH2_DATA7 (GPIO_PORTA | GPIO_PF | 2) +#define PA3_PF_USBH2_NXT (GPIO_PORTA | GPIO_PF | 3) +#define PA4_PF_USBH2_STP (GPIO_PORTA | GPIO_PF | 4) +#define PB22_PF_USBH1_SUSP (GPIO_PORTB | GPIO_PF | 22) +#define PB25_PF_USBH1_RCV (GPIO_PORTB | GPIO_PF | 25) +#define PC5_PF_I2C2_SDA (GPIO_PORTC | GPIO_PF | GPIO_IN | 5) +#define PC6_PF_I2C2_SCL (GPIO_PORTC | GPIO_PF | GPIO_IN | 6) +#define PC7_PF_USBOTG_DATA5 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 7) +#define PC8_PF_USBOTG_DATA6 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 8) +#define PC9_PF_USBOTG_DATA0 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 9) +#define PC10_PF_USBOTG_DATA2 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 10) +#define PC11_PF_USBOTG_DATA1 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 11) +#define PC12_PF_USBOTG_DATA4 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 12) +#define PC13_PF_USBOTG_DATA3 (GPIO_PORTC | GPIO_PF | GPIO_OUT | 13) +#define PC16_PF_SSI4_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 16) +#define PC17_PF_SSI4_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 17) +#define PC18_PF_SSI4_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 18) +#define PC19_PF_SSI4_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 19) +#define PC25_AF_GPT5_TIN (GPIO_PORTC | GPIO_AF | 25) +#define PC27_AF_GPT4_TIN (GPIO_PORTC | GPIO_AF | 27) +#define PD0_PF_SD3_CMD (GPIO_PORTD | GPIO_PF | 0) +#define PD1_PF_SD3_CLK (GPIO_PORTD | GPIO_PF | 1) +#define PD2_PF_ATA_DATA0 (GPIO_PORTD | GPIO_PF | 2) +#define PD3_PF_ATA_DATA1 (GPIO_PORTD | GPIO_PF | 3) +#define PD4_PF_ATA_DATA2 (GPIO_PORTD | GPIO_PF | 4) +#define PD5_PF_ATA_DATA3 (GPIO_PORTD | GPIO_PF | 5) +#define PD6_PF_ATA_DATA4 (GPIO_PORTD | GPIO_PF | 6) +#define PD7_PF_ATA_DATA5 (GPIO_PORTD | GPIO_PF | 7) +#define PD8_PF_ATA_DATA6 (GPIO_PORTD | GPIO_PF | 8) +#define PD9_PF_ATA_DATA7 (GPIO_PORTD | GPIO_PF | 9) +#define PD10_PF_ATA_DATA8 (GPIO_PORTD | GPIO_PF | 10) +#define PD11_PF_ATA_DATA9 (GPIO_PORTD | GPIO_PF | 11) +#define PD12_PF_ATA_DATA10 (GPIO_PORTD | GPIO_PF | 12) +#define PD13_PF_ATA_DATA11 (GPIO_PORTD | GPIO_PF | 13) +#define PD14_PF_ATA_DATA12 (GPIO_PORTD | GPIO_PF | 14) +#define PD15_PF_ATA_DATA13 (GPIO_PORTD | GPIO_PF | 15) +#define PD16_PF_ATA_DATA14 (GPIO_PORTD | GPIO_PF | 16) +#define PE0_PF_USBOTG_NXT (GPIO_PORTE | GPIO_PF | GPIO_OUT | 0) +#define PE1_PF_USBOTG_STP (GPIO_PORTE | GPIO_PF | GPIO_OUT | 1) +#define PE2_PF_USBOTG_DIR (GPIO_PORTE | GPIO_PF | GPIO_OUT | 2) +#define PE24_PF_USBOTG_CLK (GPIO_PORTE | GPIO_PF | GPIO_OUT | 24) +#define PE25_PF_USBOTG_DATA7 (GPIO_PORTE | GPIO_PF | GPIO_OUT | 25) +#define PF1_PF_NFCLE (GPIO_PORTF | GPIO_PF | 1) +#define PF3_PF_NFCE (GPIO_PORTF | GPIO_PF | 3) +#define PF7_PF_PC_POE (GPIO_PORTF | GPIO_PF | 7) +#define PF8_PF_PC_RW (GPIO_PORTF | GPIO_PF | 8) +#define PF9_PF_PC_IOIS16 (GPIO_PORTF | GPIO_PF | 9) +#define PF10_PF_PC_RST (GPIO_PORTF | GPIO_PF | 10) +#define PF11_PF_PC_BVD2 (GPIO_PORTF | GPIO_PF | 11) +#define PF12_PF_PC_BVD1 (GPIO_PORTF | GPIO_PF | 12) +#define PF13_PF_PC_VS2 (GPIO_PORTF | GPIO_PF | 13) +#define PF14_PF_PC_VS1 (GPIO_PORTF | GPIO_PF | 14) +#define PF16_PF_PC_PWRON (GPIO_PORTF | GPIO_PF | 16) +#define PF17_PF_PC_READY (GPIO_PORTF | GPIO_PF | 17) +#define PF18_PF_PC_WAIT (GPIO_PORTF | GPIO_PF | 18) +#define PF19_PF_PC_CD2 (GPIO_PORTF | GPIO_PF | 19) +#define PF20_PF_PC_CD1 (GPIO_PORTF | GPIO_PF | 20) +#define PF23_PF_ATA_DATA15 (GPIO_PORTF | GPIO_PF | 23) + +/* Alternate GPIO pin functions */ + +#define PB4_AF_MSHC_DATA0 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 4) +#define PB5_AF_MSHC_DATA1 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 5) +#define PB6_AF_MSHC_DATA2 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 6) +#define PB7_AF_MSHC_DATA4 (GPIO_PORTB | GPIO_AF | GPIO_OUT | 7) +#define PB8_AF_MSHC_BS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 8) +#define PB9_AF_MSHC_SCLK (GPIO_PORTB | GPIO_AF | GPIO_OUT | 9) +#define PB10_AF_UART6_TXD (GPIO_PORTB | GPIO_AF | GPIO_OUT | 10) +#define PB11_AF_UART6_RXD (GPIO_PORTB | GPIO_AF | GPIO_IN | 11) +#define PB12_AF_UART6_CTS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 12) +#define PB13_AF_UART6_RTS (GPIO_PORTB | GPIO_AF | GPIO_IN | 13) +#define PB18_AF_UART5_TXD (GPIO_PORTB | GPIO_AF | GPIO_OUT | 18) +#define PB19_AF_UART5_RXD (GPIO_PORTB | GPIO_AF | GPIO_IN | 19) +#define PB20_AF_UART5_CTS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 20) +#define PB21_AF_UART5_RTS (GPIO_PORTB | GPIO_AF | GPIO_IN | 21) +#define PC8_AF_FEC_MDIO (GPIO_PORTC | GPIO_AF | GPIO_IN | 8) +#define PC24_AF_GPT5_TOUT (GPIO_PORTC | GPIO_AF | 24) +#define PC26_AF_GPT4_TOUT (GPIO_PORTC | GPIO_AF | 26) +#define PD1_AF_ETMTRACE_PKT15 (GPIO_PORTD | GPIO_AF | 1) +#define PD6_AF_ETMTRACE_PKT14 (GPIO_PORTD | GPIO_AF | 6) +#define PD7_AF_ETMTRACE_PKT13 (GPIO_PORTD | GPIO_AF | 7) +#define PD9_AF_ETMTRACE_PKT12 (GPIO_PORTD | GPIO_AF | 9) +#define PD2_AF_SD3_D0 (GPIO_PORTD | GPIO_AF | 2) +#define PD3_AF_SD3_D1 (GPIO_PORTD | GPIO_AF | 3) +#define PD4_AF_SD3_D2 (GPIO_PORTD | GPIO_AF | 4) +#define PD5_AF_SD3_D3 (GPIO_PORTD | GPIO_AF | 5) +#define PD8_AF_FEC_MDIO (GPIO_PORTD | GPIO_AF | GPIO_IN | 8) +#define PD10_AF_ETMTRACE_PKT11 (GPIO_PORTD | GPIO_AF | 10) +#define PD11_AF_ETMTRACE_PKT10 (GPIO_PORTD | GPIO_AF | 11) +#define PD12_AF_ETMTRACE_PKT9 (GPIO_PORTD | GPIO_AF | 12) +#define PD13_AF_ETMTRACE_PKT8 (GPIO_PORTD | GPIO_AF | 13) +#define PD14_AF_ETMTRACE_PKT7 (GPIO_PORTD | GPIO_AF | 14) +#define PD15_AF_ETMTRACE_PKT6 (GPIO_PORTD | GPIO_AF | 15) +#define PD16_AF_ETMTRACE_PKT5 (GPIO_PORTD | GPIO_AF | 16) +#define PF1_AF_ETMTRACE_PKT0 (GPIO_PORTF | GPIO_AF | 1) +#define PF3_AF_ETMTRACE_PKT2 (GPIO_PORTF | GPIO_AF | 3) +#define PF5_AF_ETMPIPESTAT11 (GPIO_PORTF | GPIO_AF | 5) +#define PF7_AF_ATA_BUFFER_EN (GPIO_PORTF | GPIO_AF | 7) +#define PF8_AF_ATA_IORDY (GPIO_PORTF | GPIO_AF | 8) +#define PF9_AF_ATA_INTRQ (GPIO_PORTF | GPIO_AF | 9) +#define PF10_AF_ATA_RESET (GPIO_PORTF | GPIO_AF | 10) +#define PF11_AF_ATA_DMACK (GPIO_PORTF | GPIO_AF | 11) +#define PF12_AF_ATA_DMAREQ (GPIO_PORTF | GPIO_AF | 12) +#define PF13_AF_ATA_DA0 (GPIO_PORTF | GPIO_AF | 13) +#define PF14_AF_ATA_DA1 (GPIO_PORTF | GPIO_AF | 14) +#define PF15_AF_ETMTRACE_SYNC (GPIO_PORTF | GPIO_AF | 15) +#define PF16_AF_ATA_DA2 (GPIO_PORTF | GPIO_AF | 16) +#define PF17_AF_ATA_CS0 (GPIO_PORTF | GPIO_AF | 17) +#define PF18_AF_ATA_CS1 (GPIO_PORTF | GPIO_AF | 18) +#define PF19_AF_ATA_DIOW (GPIO_PORTF | GPIO_AF | 19) +#define PF20_AF_ATA_DIOR (GPIO_PORTF | GPIO_AF | 20) +#define PF22_AF_ETMTRACE_CLK (GPIO_PORTF | GPIO_AF | 22) +#define PF23_AF_ETMTRACE_PKT4 (GPIO_PORTF | GPIO_AF | 23) + +/* AIN GPIO pin functions */ + +#define PC14_AIN_SSI1_MCLK (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 14) +#define PC15_AIN_GPT6_TOUT (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 15) +#define PD0_AIN_FEC_TXD0 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 0) +#define PD1_AIN_FEC_TXD1 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 1) +#define PD2_AIN_FEC_TXD2 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 2) +#define PD3_AIN_FEC_TXD3 (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 3) +#define PD9_AIN_FEC_MDC (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 9) +#define PD16_AIN_FEC_TX_ER (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 16) +#define PD27_AIN_EXT_DMA_GRANT (GPIO_PORTD | GPIO_AIN | GPIO_OUT | 27) +#define PF23_AIN_FEC_TX_EN (GPIO_PORTF | GPIO_AIN | GPIO_OUT | 23) + +/* BIN GPIO pin functions */ + +#define PC14_BIN_SSI2_MCLK (GPIO_PORTC | GPIO_BIN | GPIO_OUT | 14) + +/* CIN GPIO pin functions */ + +#define PD2_CIN_SLCDC1_DAT0 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 2) +#define PD3_CIN_SLCDC1_DAT1 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 3) +#define PD4_CIN_SLCDC1_DAT2 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 4) +#define PD5_CIN_SLCDC1_DAT3 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 5) +#define PD6_CIN_SLCDC1_DAT4 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 6) +#define PD7_CIN_SLCDC1_DAT5 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 7) +#define PD8_CIN_SLCDC1_DAT6 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 8) +#define PD9_CIN_SLCDC1_DAT7 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 9) +#define PD10_CIN_SLCDC1_DAT8 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 10) +#define PD11_CIN_SLCDC1_DAT9 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 11) +#define PD12_CIN_SLCDC1_DAT10 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 12) +#define PD13_CIN_SLCDC1_DAT11 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 13) +#define PD14_CIN_SLCDC1_DAT12 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 14) +#define PD15_CIN_SLCDC1_DAT13 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 15) +#define PD16_CIN_SLCDC1_DAT14 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 16) +#define PD23_CIN_SLCDC1_DAT15 (GPIO_PORTD | GPIO_CIN | GPIO_OUT | 23) +#define PF27_CIN_EXT_DMA_GRANT (GPIO_PORTF | GPIO_CIN | GPIO_OUT | 27) +/* LCDC_TESTx on PBxx omitted, because it's not clear what they do */ + +/* AOUT GPIO pin functions */ + +#define PC14_AOUT_GPT6_TIN (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 14) +#define PD4_AOUT_FEC_RX_ER (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 4) +#define PD5_AOUT_FEC_RXD1 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 5) +#define PD6_AOUT_FEC_RXD2 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 6) +#define PD7_AOUT_FEC_RXD3 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 7) +#define PD10_AOUT_FEC_CRS (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 10) +#define PD11_AOUT_FEC_TX_CLK (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 11) +#define PD12_AOUT_FEC_RXD0 (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 12) +#define PD13_AOUT_FEC_RX_DV (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 13) +#define PD14_AOUT_FEC_RX_CLK (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 14) +#define PD15_AOUT_FEC_COL (GPIO_PORTD | GPIO_AOUT | GPIO_IN | 15) + +#define PC17_BOUT_PC_IOIS16 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 17) +#define PC18_BOUT_PC_BVD2 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 18) +#define PC19_BOUT_PC_BVD1 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 19) +#define PC28_BOUT_PC_BVD2 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 28) +#define PC29_BOUT_PC_VS1 (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 29) +#define PC30_BOUT_PC_READY (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 30) +#define PC31_BOUT_PC_WAIT (GPIO_PORTC | GPIO_BOUT | GPIO_IN | 31) + + +#endif /* _MXC_GPIO_MX1_MX2_H */ diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx2x.h b/arch/arm/plat-mxc/include/mach/iomux-mx2x.h new file mode 100644 index 000000000000..fb5ae638e79f --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/iomux-mx2x.h @@ -0,0 +1,237 @@ +/* +* Copyright (C) 2008 by Sascha Hauer +* Copyright (C) 2009 by Holger Schurig +* +* 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. +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +* MA 02110-1301, USA. +*/ + +#ifndef _MXC_IOMUX_MX2x_H +#define _MXC_IOMUX_MX2x_H + +#ifndef GPIO_PORTA +#error Please include mach/iomux.h +#endif + + +/* Primary GPIO pin functions */ + +#define PA5_PF_LSCLK (GPIO_PORTA | GPIO_PF | GPIO_OUT | 5) +#define PA6_PF_LD0 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 6) +#define PA7_PF_LD1 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 7) +#define PA8_PF_LD2 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 8) +#define PA9_PF_LD3 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 9) +#define PA10_PF_LD4 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 10) +#define PA11_PF_LD5 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 11) +#define PA12_PF_LD6 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 12) +#define PA13_PF_LD7 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 13) +#define PA14_PF_LD8 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 14) +#define PA15_PF_LD9 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 15) +#define PA16_PF_LD10 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 16) +#define PA17_PF_LD11 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 17) +#define PA18_PF_LD12 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 18) +#define PA19_PF_LD13 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 19) +#define PA20_PF_LD14 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 20) +#define PA21_PF_LD15 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 21) +#define PA22_PF_LD16 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 22) +#define PA23_PF_LD17 (GPIO_PORTA | GPIO_PF | GPIO_OUT | 23) +#define PA24_PF_REV (GPIO_PORTA | GPIO_PF | GPIO_OUT | 24) +#define PA25_PF_CLS (GPIO_PORTA | GPIO_PF | GPIO_OUT | 25) +#define PA26_PF_PS (GPIO_PORTA | GPIO_PF | GPIO_OUT | 26) +#define PA27_PF_SPL_SPR (GPIO_PORTA | GPIO_PF | GPIO_OUT | 27) +#define PA28_PF_HSYNC (GPIO_PORTA | GPIO_PF | GPIO_OUT | 28) +#define PA29_PF_VSYNC (GPIO_PORTA | GPIO_PF | GPIO_OUT | 29) +#define PA30_PF_CONTRAST (GPIO_PORTA | GPIO_PF | GPIO_OUT | 30) +#define PA31_PF_OE_ACD (GPIO_PORTA | GPIO_PF | GPIO_OUT | 31) +#define PB4_PF_SD2_D0 (GPIO_PORTB | GPIO_PF | 4) +#define PB5_PF_SD2_D1 (GPIO_PORTB | GPIO_PF | 5) +#define PB6_PF_SD2_D2 (GPIO_PORTB | GPIO_PF | 6) +#define PB7_PF_SD2_D3 (GPIO_PORTB | GPIO_PF | 7) +#define PB8_PF_SD2_CMD (GPIO_PORTB | GPIO_PF | 8) +#define PB9_PF_SD2_CLK (GPIO_PORTB | GPIO_PF | 9) +#define PB10_PF_CSI_D0 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 10) +#define PB11_PF_CSI_D1 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 11) +#define PB12_PF_CSI_D2 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 12) +#define PB13_PF_CSI_D3 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 13) +#define PB14_PF_CSI_D4 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 14) +#define PB15_PF_CSI_MCLK (GPIO_PORTB | GPIO_PF | GPIO_OUT | 15) +#define PB16_PF_CSI_PIXCLK (GPIO_PORTB | GPIO_PF | GPIO_OUT | 16) +#define PB17_PF_CSI_D5 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 17) +#define PB18_PF_CSI_D6 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 18) +#define PB19_PF_CSI_D7 (GPIO_PORTB | GPIO_PF | GPIO_OUT | 19) +#define PB20_PF_CSI_VSYNC (GPIO_PORTB | GPIO_PF | GPIO_OUT | 20) +#define PB21_PF_CSI_HSYNC (GPIO_PORTB | GPIO_PF | GPIO_OUT | 21) +#define PB23_PF_USB_PWR (GPIO_PORTB | GPIO_PF | 23) +#define PB24_PF_USB_OC (GPIO_PORTB | GPIO_PF | 24) +#define PB26_PF_USBH1_FS (GPIO_PORTB | GPIO_PF | 26) +#define PB27_PF_USBH1_OE (GPIO_PORTB | GPIO_PF | 27) +#define PB28_PF_USBH1_TXDM (GPIO_PORTB | GPIO_PF | 28) +#define PB29_PF_USBH1_TXDP (GPIO_PORTB | GPIO_PF | 29) +#define PB30_PF_USBH1_RXDM (GPIO_PORTB | GPIO_PF | 30) +#define PB31_PF_USBH1_RXDP (GPIO_PORTB | GPIO_PF | 31) +#define PC14_PF_TOUT (GPIO_PORTC | GPIO_PF | 14) +#define PC15_PF_TIN (GPIO_PORTC | GPIO_PF | 15) +#define PC20_PF_SSI1_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 20) +#define PC21_PF_SSI1_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 21) +#define PC22_PF_SSI1_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 22) +#define PC23_PF_SSI1_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 23) +#define PC24_PF_SSI2_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 24) +#define PC25_PF_SSI2_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 25) +#define PC26_PF_SSI2_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 26) +#define PC27_PF_SSI2_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 27) +#define PC28_PF_SSI3_FS (GPIO_PORTC | GPIO_PF | GPIO_IN | 28) +#define PC29_PF_SSI3_RXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 29) +#define PC30_PF_SSI3_TXD (GPIO_PORTC | GPIO_PF | GPIO_IN | 30) +#define PC31_PF_SSI3_CLK (GPIO_PORTC | GPIO_PF | GPIO_IN | 31) +#define PD17_PF_I2C_DATA (GPIO_PORTD | GPIO_PF | GPIO_OUT | 17) +#define PD18_PF_I2C_CLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 18) +#define PD19_PF_CSPI2_SS2 (GPIO_PORTD | GPIO_PF | 19) +#define PD20_PF_CSPI2_SS1 (GPIO_PORTD | GPIO_PF | 20) +#define PD21_PF_CSPI2_SS0 (GPIO_PORTD | GPIO_PF | 21) +#define PD22_PF_CSPI2_SCLK (GPIO_PORTD | GPIO_PF | 22) +#define PD23_PF_CSPI2_MISO (GPIO_PORTD | GPIO_PF | 23) +#define PD24_PF_CSPI2_MOSI (GPIO_PORTD | GPIO_PF | 24) +#define PD25_PF_CSPI1_RDY (GPIO_PORTD | GPIO_PF | GPIO_OUT | 25) +#define PD26_PF_CSPI1_SS2 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 26) +#define PD27_PF_CSPI1_SS1 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 27) +#define PD28_PF_CSPI1_SS0 (GPIO_PORTD | GPIO_PF | GPIO_OUT | 28) +#define PD29_PF_CSPI1_SCLK (GPIO_PORTD | GPIO_PF | GPIO_OUT | 29) +#define PD30_PF_CSPI1_MISO (GPIO_PORTD | GPIO_PF | GPIO_IN | 30) +#define PD31_PF_CSPI1_MOSI (GPIO_PORTD | GPIO_PF | GPIO_OUT | 31) +#define PE3_PF_UART2_CTS (GPIO_PORTE | GPIO_PF | GPIO_OUT | 3) +#define PE4_PF_UART2_RTS (GPIO_PORTE | GPIO_PF | GPIO_IN | 4) +#define PE5_PF_PWMO (GPIO_PORTE | GPIO_PF | 5) +#define PE6_PF_UART2_TXD (GPIO_PORTE | GPIO_PF | GPIO_OUT | 6) +#define PE7_PF_UART2_RXD (GPIO_PORTE | GPIO_PF | GPIO_IN | 7) +#define PE8_PF_UART3_TXD (GPIO_PORTE | GPIO_PF | GPIO_OUT | 8) +#define PE9_PF_UART3_RXD (GPIO_PORTE | GPIO_PF | GPIO_IN | 9) +#define PE10_PF_UART3_CTS (GPIO_PORTE | GPIO_PF | GPIO_OUT | 10) +#define PE11_PF_UART3_RTS (GPIO_PORTE | GPIO_PF | GPIO_IN | 11) +#define PE12_PF_UART1_TXD (GPIO_PORTE | GPIO_PF | GPIO_OUT | 12) +#define PE13_PF_UART1_RXD (GPIO_PORTE | GPIO_PF | GPIO_IN | 13) +#define PE14_PF_UART1_CTS (GPIO_PORTE | GPIO_PF | GPIO_OUT | 14) +#define PE15_PF_UART1_RTS (GPIO_PORTE | GPIO_PF | GPIO_IN | 15) +#define PE16_PF_RTCK (GPIO_PORTE | GPIO_PF | GPIO_OUT | 16) +#define PE17_PF_RESET_OUT (GPIO_PORTE | GPIO_PF | 17) +#define PE18_PF_SD1_D0 (GPIO_PORTE | GPIO_PF | 18) +#define PE19_PF_SD1_D1 (GPIO_PORTE | GPIO_PF | 19) +#define PE20_PF_SD1_D2 (GPIO_PORTE | GPIO_PF | 20) +#define PE21_PF_SD1_D3 (GPIO_PORTE | GPIO_PF | 21) +#define PE22_PF_SD1_CMD (GPIO_PORTE | GPIO_PF | 22) +#define PE23_PF_SD1_CLK (GPIO_PORTE | GPIO_PF | 23) +#define PF0_PF_NRFB (GPIO_PORTF | GPIO_PF | 0) +#define PF2_PF_NFWP (GPIO_PORTF | GPIO_PF | 2) +#define PF4_PF_NFALE (GPIO_PORTF | GPIO_PF | 4) +#define PF5_PF_NFRE (GPIO_PORTF | GPIO_PF | 5) +#define PF6_PF_NFWE (GPIO_PORTF | GPIO_PF | 6) +#define PF15_PF_CLKO (GPIO_PORTF | GPIO_PF | 15) +#define PF21_PF_CS4 (GPIO_PORTF | GPIO_PF | 21) +#define PF22_PF_CS5 (GPIO_PORTF | GPIO_PF | 22) + +/* Alternate GPIO pin functions */ + +#define PB26_AF_UART4_RTS (GPIO_PORTB | GPIO_AF | GPIO_IN | 26) +#define PB28_AF_UART4_TXD (GPIO_PORTB | GPIO_AF | GPIO_OUT | 28) +#define PB29_AF_UART4_CTS (GPIO_PORTB | GPIO_AF | GPIO_OUT | 29) +#define PB31_AF_UART4_RXD (GPIO_PORTB | GPIO_AF | GPIO_IN | 31) +#define PC28_AF_SLCDC2_D0 (GPIO_PORTC | GPIO_AF | 28) +#define PC29_AF_SLCDC2_RS (GPIO_PORTC | GPIO_AF | 29) +#define PC30_AF_SLCDC2_CS (GPIO_PORTC | GPIO_AF | 30) +#define PC31_AF_SLCDC2_CLK (GPIO_PORTC | GPIO_AF | 31) +#define PD19_AF_USBH2_DATA4 (GPIO_PORTD | GPIO_AF | 19) +#define PD20_AF_USBH2_DATA3 (GPIO_PORTD | GPIO_AF | 20) +#define PD21_AF_USBH2_DATA6 (GPIO_PORTD | GPIO_AF | 21) +#define PD22_AF_USBH2_DATA0 (GPIO_PORTD | GPIO_AF | 22) +#define PD23_AF_USBH2_DATA2 (GPIO_PORTD | GPIO_AF | 23) +#define PD24_AF_USBH2_DATA1 (GPIO_PORTD | GPIO_AF | 24) +#define PD26_AF_USBH2_DATA5 (GPIO_PORTD | GPIO_AF | 26) +#define PE0_AF_KP_COL6 (GPIO_PORTE | GPIO_AF | 0) +#define PE1_AF_KP_ROW6 (GPIO_PORTE | GPIO_AF | 1) +#define PE2_AF_KP_ROW7 (GPIO_PORTE | GPIO_AF | 2) +#define PE3_AF_KP_COL7 (GPIO_PORTE | GPIO_AF | 3) +#define PE4_AF_KP_ROW7 (GPIO_PORTE | GPIO_AF | 4) +#define PE6_AF_KP_COL6 (GPIO_PORTE | GPIO_AF | 6) +#define PE7_AF_KP_ROW6 (GPIO_PORTE | GPIO_AF | 7) +#define PE16_AF_OWIRE (GPIO_PORTE | GPIO_AF | 16) +#define PE18_AF_CSPI3_MISO (GPIO_PORTE | GPIO_AF | GPIO_IN | 18) +#define PE21_AF_CSPI3_SS (GPIO_PORTE | GPIO_AF | GPIO_OUT | 21) +#define PE22_AF_CSPI3_MOSI (GPIO_PORTE | GPIO_AF | GPIO_OUT | 22) +#define PE23_AF_CSPI3_SCLK (GPIO_PORTE | GPIO_AF | GPIO_OUT | 23) + +/* AIN GPIO pin functions */ + +#define PA6_AIN_SLCDC1_DAT0 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 6) +#define PA7_AIN_SLCDC1_DAT1 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 7) +#define PA8_AIN_SLCDC1_DAT2 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 8) +#define PA0_AIN_SLCDC1_DAT3 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 0) +#define PA11_AIN_SLCDC1_DAT5 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 11) +#define PA13_AIN_SLCDC1_DAT7 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 13) +#define PA15_AIN_SLCDC1_DAT9 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 15) +#define PA17_AIN_SLCDC1_DAT11 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 17) +#define PA19_AIN_SLCDC1_DAT13 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 19) +#define PA21_AIN_SLCDC1_DAT15 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 21) +#define PA22_AIN_EXT_DMAGRANT (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 22) +#define PA24_AIN_SLCDC1_D0 (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 24) +#define PA25_AIN_SLCDC1_RS (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 25) +#define PA26_AIN_SLCDC1_CS (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 26) +#define PA27_AIN_SLCDC1_CLK (GPIO_PORTA | GPIO_AIN | GPIO_OUT | 27) +#define PB6_AIN_SLCDC1_D0 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 6) +#define PB7_AIN_SLCDC1_RS (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 7) +#define PB8_AIN_SLCDC1_CS (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 8) +#define PB9_AIN_SLCDC1_CLK (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 9) +#define PB25_AIN_SLCDC1_DAT0 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 25) +#define PB26_AIN_SLCDC1_DAT1 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 26) +#define PB27_AIN_SLCDC1_DAT2 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 27) +#define PB28_AIN_SLCDC1_DAT3 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 28) +#define PB29_AIN_SLCDC1_DAT4 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 29) +#define PB30_AIN_SLCDC1_DAT5 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 30) +#define PB31_AIN_SLCDC1_DAT6 (GPIO_PORTB | GPIO_AIN | GPIO_OUT | 31) +#define PC5_AIN_SLCDC1_DAT7 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 5) +#define PC6_AIN_SLCDC1_DAT8 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 6) +#define PC7_AIN_SLCDC1_DAT9 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 7) +#define PC8_AIN_SLCDC1_DAT10 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 8) +#define PC9_AIN_SLCDC1_DAT11 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 9) +#define PC10_AIN_SLCDC1_DAT12 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 10) +#define PC11_AIN_SLCDC1_DAT13 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 11) +#define PC12_AIN_SLCDC1_DAT14 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 12) +#define PC13_AIN_SLCDC1_DAT15 (GPIO_PORTC | GPIO_AIN | GPIO_OUT | 13) +#define PE5_AIN_PC_SPKOUT (GPIO_PORTE | GPIO_AIN | GPIO_OUT | 5) + +/* BIN GPIO pin functions */ + +#define PE5_BIN_TOUT2 (GPIO_PORTE | GPIO_BIN | GPIO_OUT | 5) + +/* CIN GPIO pin functions */ + +#define PA14_CIN_SLCDC1_DAT0 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 14) +#define PA15_CIN_SLCDC1_DAT1 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 15) +#define PA16_CIN_SLCDC1_DAT2 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 16) +#define PA17_CIN_SLCDC1_DAT3 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 17) +#define PA18_CIN_SLCDC1_DAT4 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 18) +#define PA19_CIN_SLCDC1_DAT5 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 19) +#define PA20_CIN_SLCDC1_DAT6 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 20) +#define PA21_CIN_SLCDC1_DAT7 (GPIO_PORTA | GPIO_CIN | GPIO_OUT | 21) +#define PB30_CIN_UART4_CTS (GPIO_PORTB | GPIO_CIN | GPIO_OUT | 30) +#define PE5_CIN_TOUT3 (GPIO_PORTE | GPIO_CIN | GPIO_OUT | 5) + +/* AOUT GPIO pin functions */ + +#define PB29_AOUT_UART4_RXD (GPIO_PORTB | GPIO_AOUT | GPIO_IN | 29) +#define PB31_AOUT_UART4_RTS (GPIO_PORTB | GPIO_AOUT | GPIO_IN | 31) +#define PC8_AOUT_USBOTG_TXR_INT (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 8) +#define PC15_AOUT_WKGD (GPIO_PORTC | GPIO_AOUT | GPIO_IN | 15) +#define PF21_AOUT_DTACK (GPIO_PORTF | GPIO_AOUT | GPIO_IN | 21) + + +#endif diff --git a/arch/arm/plat-mxc/include/mach/iomux.h b/arch/arm/plat-mxc/include/mach/iomux.h new file mode 100644 index 000000000000..171f8adc1109 --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/iomux.h @@ -0,0 +1,127 @@ +/* +* Copyright (C) 2008 by Sascha Hauer +* Copyright (C) 2009 by Holger Schurig +* +* 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. +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, +* MA 02110-1301, USA. +*/ + +#ifndef _MXC_IOMUX_H +#define _MXC_IOMUX_H + +/* +* GPIO Module and I/O Multiplexer +* x = 0..3 for reg_A, reg_B, reg_C, reg_D +*/ +#define VA_GPIO_BASE IO_ADDRESS(GPIO_BASE_ADDR) +#define MXC_DDIR(x) (0x00 + ((x) << 8)) +#define MXC_OCR1(x) (0x04 + ((x) << 8)) +#define MXC_OCR2(x) (0x08 + ((x) << 8)) +#define MXC_ICONFA1(x) (0x0c + ((x) << 8)) +#define MXC_ICONFA2(x) (0x10 + ((x) << 8)) +#define MXC_ICONFB1(x) (0x14 + ((x) << 8)) +#define MXC_ICONFB2(x) (0x18 + ((x) << 8)) +#define MXC_DR(x) (0x1c + ((x) << 8)) +#define MXC_GIUS(x) (0x20 + ((x) << 8)) +#define MXC_SSR(x) (0x24 + ((x) << 8)) +#define MXC_ICR1(x) (0x28 + ((x) << 8)) +#define MXC_ICR2(x) (0x2c + ((x) << 8)) +#define MXC_IMR(x) (0x30 + ((x) << 8)) +#define MXC_ISR(x) (0x34 + ((x) << 8)) +#define MXC_GPR(x) (0x38 + ((x) << 8)) +#define MXC_SWR(x) (0x3c + ((x) << 8)) +#define MXC_PUEN(x) (0x40 + ((x) << 8)) + +#ifdef CONFIG_ARCH_MX1 +# define GPIO_PORT_MAX 3 +#endif +#ifdef CONFIG_ARCH_MX2 +# define GPIO_PORT_MAX 5 +#endif + +#ifndef GPIO_PORT_MAX +# error "GPIO config port count unknown!" +#endif + +#define GPIO_PIN_MASK 0x1f + +#define GPIO_PORT_SHIFT 5 +#define GPIO_PORT_MASK (0x7 << GPIO_PORT_SHIFT) + +#define GPIO_PORTA (0 << GPIO_PORT_SHIFT) +#define GPIO_PORTB (1 << GPIO_PORT_SHIFT) +#define GPIO_PORTC (2 << GPIO_PORT_SHIFT) +#define GPIO_PORTD (3 << GPIO_PORT_SHIFT) +#define GPIO_PORTE (4 << GPIO_PORT_SHIFT) +#define GPIO_PORTF (5 << GPIO_PORT_SHIFT) + +#define GPIO_OUT (1 << 8) +#define GPIO_IN (0 << 8) +#define GPIO_PUEN (1 << 9) + +#define GPIO_PF (1 << 10) +#define GPIO_AF (1 << 11) + +#define GPIO_OCR_SHIFT 12 +#define GPIO_OCR_MASK (3 << GPIO_OCR_SHIFT) +#define GPIO_AIN (0 << GPIO_OCR_SHIFT) +#define GPIO_BIN (1 << GPIO_OCR_SHIFT) +#define GPIO_CIN (2 << GPIO_OCR_SHIFT) +#define GPIO_GPIO (3 << GPIO_OCR_SHIFT) + +#define GPIO_AOUT_SHIFT 14 +#define GPIO_AOUT_MASK (3 << GPIO_AOUT_SHIFT) +#define GPIO_AOUT (0 << GPIO_AOUT_SHIFT) +#define GPIO_AOUT_ISR (1 << GPIO_AOUT_SHIFT) +#define GPIO_AOUT_0 (2 << GPIO_AOUT_SHIFT) +#define GPIO_AOUT_1 (3 << GPIO_AOUT_SHIFT) + +#define GPIO_BOUT_SHIFT 16 +#define GPIO_BOUT_MASK (3 << GPIO_BOUT_SHIFT) +#define GPIO_BOUT (0 << GPIO_BOUT_SHIFT) +#define GPIO_BOUT_ISR (1 << GPIO_BOUT_SHIFT) +#define GPIO_BOUT_0 (2 << GPIO_BOUT_SHIFT) +#define GPIO_BOUT_1 (3 << GPIO_BOUT_SHIFT) + + +#ifdef CONFIG_ARCH_MX1 +#include +#endif +#ifdef CONFIG_ARCH_MX2 +#include +#ifdef CONFIG_MACH_MX21 +#include +#endif +#ifdef CONFIG_MACH_MX27 +#include +#endif +#endif + + +/* decode irq number to use with IMR(x), ISR(x) and friends */ +#define IRQ_TO_REG(irq) ((irq - MXC_INTERNAL_IRQS) >> 5) + +#define IRQ_GPIOA(x) (MXC_GPIO_IRQ_START + x) +#define IRQ_GPIOB(x) (IRQ_GPIOA(32) + x) +#define IRQ_GPIOC(x) (IRQ_GPIOB(32) + x) +#define IRQ_GPIOD(x) (IRQ_GPIOC(32) + x) +#define IRQ_GPIOE(x) (IRQ_GPIOD(32) + x) + + +extern void mxc_gpio_mode(int gpio_mode); +extern int mxc_gpio_setup_multiple_pins(const int *pin_list, unsigned count, + const char *label); +extern void mxc_gpio_release_multiple_pins(const int *pin_list, int count); + +#endif diff --git a/arch/arm/plat-mxc/iomux-mx1-mx2.c b/arch/arm/plat-mxc/iomux-mx1-mx2.c index df6f18395686..a37163ce280b 100644 --- a/arch/arm/plat-mxc/iomux-mx1-mx2.c +++ b/arch/arm/plat-mxc/iomux-mx1-mx2.c @@ -32,7 +32,7 @@ #include #include -#include +#include void mxc_gpio_mode(int gpio_mode) { -- cgit v1.2.3 From 5512e88f3a1f1b498fd07181f14596ee117b3471 Mon Sep 17 00:00:00 2001 From: Holger Schurig Date: Mon, 26 Jan 2009 16:34:52 +0100 Subject: arm/imx21: add kbuild support for the Freescale i.MX21 * adds Kconfig variables * specifies different physical address for i.MX21 because of the different memory layouts * disables support for UART5/UART6 in the i.MX serial driver (the i.MX21 doesn't have those modules) Based on code from "Martin Fuzzey" Signed-off-by: Holger Schurig Signed-off-by: Sascha Hauer --- arch/arm/mach-mx2/Kconfig | 13 +++++++++++++ arch/arm/mach-mx2/Makefile.boot | 10 +++++++--- arch/arm/mach-mx2/serial.c | 2 ++ arch/arm/plat-mxc/include/mach/memory.h | 5 +++++ arch/arm/plat-mxc/include/mach/mxc.h | 4 ++++ 5 files changed, 31 insertions(+), 3 deletions(-) (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-mx2/Kconfig index 1eaa97cb716d..412d2d55b08c 100644 --- a/arch/arm/mach-mx2/Kconfig +++ b/arch/arm/mach-mx2/Kconfig @@ -1,12 +1,25 @@ comment "MX2 family CPU support" depends on ARCH_MX2 +choice + prompt "MX2 Type" + depends on ARCH_MX2 + default MACH_MX21 + +config MACH_MX21 + bool "i.MX21 support" + depends on ARCH_MX2 + help + This enables support for Freescale's MX2 based i.MX21 processor. + config MACH_MX27 bool "i.MX27 support" depends on ARCH_MX2 help This enables support for Freescale's MX2 based i.MX27 processor. +endchoice + comment "MX2 Platforms" depends on ARCH_MX2 diff --git a/arch/arm/mach-mx2/Makefile.boot b/arch/arm/mach-mx2/Makefile.boot index 696831dcd485..e867398a8fdb 100644 --- a/arch/arm/mach-mx2/Makefile.boot +++ b/arch/arm/mach-mx2/Makefile.boot @@ -1,3 +1,7 @@ - zreladdr-y := 0xA0008000 -params_phys-y := 0xA0000100 -initrd_phys-y := 0xA0800000 +zreladdr-$(CONFIG_MACH_MX21) := 0xC0008000 +params_phys-$(CONFIG_MACH_MX21) := 0xC0000100 +initrd_phys-$(CONFIG_MACH_MX21) := 0xC0800000 + +zreladdr-$(CONFIG_MACH_MX27) := 0xA0008000 +params_phys-$(CONFIG_MACH_MX27) := 0xA0000100 +initrd_phys-$(CONFIG_MACH_MX27) := 0xA0800000 diff --git a/arch/arm/mach-mx2/serial.c b/arch/arm/mach-mx2/serial.c index 16debc296dad..b9e66fb11860 100644 --- a/arch/arm/mach-mx2/serial.c +++ b/arch/arm/mach-mx2/serial.c @@ -99,6 +99,7 @@ struct platform_device mxc_uart_device3 = { .num_resources = ARRAY_SIZE(uart3), }; +#ifdef CONFIG_MACH_MX27 static struct resource uart4[] = { { .start = UART5_BASE_ADDR, @@ -136,3 +137,4 @@ struct platform_device mxc_uart_device5 = { .resource = uart5, .num_resources = ARRAY_SIZE(uart5), }; +#endif diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h index 0b808399097f..e0783e619580 100644 --- a/arch/arm/plat-mxc/include/mach/memory.h +++ b/arch/arm/plat-mxc/include/mach/memory.h @@ -14,7 +14,12 @@ #if defined CONFIG_ARCH_MX1 #define PHYS_OFFSET UL(0x08000000) #elif defined CONFIG_ARCH_MX2 +#ifdef CONFIG_MACH_MX21 +#define PHYS_OFFSET UL(0xC0000000) +#endif +#ifdef CONFIG_MACH_MX27 #define PHYS_OFFSET UL(0xA0000000) +#endif #elif defined CONFIG_ARCH_MX3 #define PHYS_OFFSET UL(0x80000000) #endif diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h index f6caab062131..bbd848e004d7 100644 --- a/arch/arm/plat-mxc/include/mach/mxc.h +++ b/arch/arm/plat-mxc/include/mach/mxc.h @@ -29,6 +29,10 @@ # define cpu_is_mx31() (0) #endif +#ifndef CONFIG_MACH_MX21 +# define cpu_is_mx21() (0) +#endif + #ifndef CONFIG_MACH_MX27 # define cpu_is_mx27() (0) #endif -- cgit v1.2.3 From a2865197a5dad23c619c84f44b7fdf7fdbef3f9c Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 26 Jan 2009 15:41:16 +0100 Subject: [ARM] MXC: Use a single function for decoding a PLL We had 3 versions of this function in clock support for MX1/2/3 Use a single one instead. I picked the one from the MX3 as it seems to calculate more accurate as the other ones. Also, on MX27 and MX31 mfn can be negative, this hasn't been handled correctly on MX27 since now. This patch has been tested on MX27 and MX31 and produces the same clock frequencies for me. Signed-off-by: Sascha Hauer --- arch/arm/mach-mx1/clock.c | 31 ++---------------------- arch/arm/mach-mx2/clock_imx27.c | 42 ++++++-------------------------- arch/arm/mach-mx3/clock.c | 26 ++------------------ arch/arm/plat-mxc/clock.c | 44 ++++++++++++++++++++++++++++++++++ arch/arm/plat-mxc/include/mach/clock.h | 2 ++ 5 files changed, 57 insertions(+), 88 deletions(-) (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/mach-mx1/clock.c b/arch/arm/mach-mx1/clock.c index 4bcd1ece55f5..3c464331b870 100644 --- a/arch/arm/mach-mx1/clock.c +++ b/arch/arm/mach-mx1/clock.c @@ -87,33 +87,6 @@ static int _clk_parent_set_rate(struct clk *clk, unsigned long rate) return clk->parent->set_rate(clk->parent, rate); } -/* - * get the system pll clock in Hz - * - * mfi + mfn / (mfd +1) - * f = 2 * f_ref * -------------------- - * pd + 1 - */ -static unsigned long mx1_decode_pll(unsigned int pll, u32 f_ref) -{ - unsigned long long ll; - unsigned long quot; - - u32 mfi = (pll >> 10) & 0xf; - u32 mfn = pll & 0x3ff; - u32 mfd = (pll >> 16) & 0x3ff; - u32 pd = (pll >> 26) & 0xf; - - mfi = mfi <= 5 ? 5 : mfi; - - ll = 2 * (unsigned long long)f_ref * - ((mfi << 16) + (mfn << 16) / (mfd + 1)); - quot = (pd + 1) * (1 << 16); - ll += quot / 2; - do_div(ll, quot); - return (unsigned long)ll; -} - static unsigned long clk16m_get_rate(struct clk *clk) { return 16000000; @@ -188,7 +161,7 @@ static struct clk prem_clk = { static unsigned long system_clk_get_rate(struct clk *clk) { - return mx1_decode_pll(__raw_readl(CCM_SPCTL0), + return mxc_decode_pll(__raw_readl(CCM_SPCTL0), clk_get_rate(clk->parent)); } @@ -200,7 +173,7 @@ static struct clk system_clk = { static unsigned long mcu_clk_get_rate(struct clk *clk) { - return mx1_decode_pll(__raw_readl(CCM_MPCTL0), + return mxc_decode_pll(__raw_readl(CCM_MPCTL0), clk_get_rate(clk->parent)); } diff --git a/arch/arm/mach-mx2/clock_imx27.c b/arch/arm/mach-mx2/clock_imx27.c index c69896d011a1..047e71e6ea9a 100644 --- a/arch/arm/mach-mx2/clock_imx27.c +++ b/arch/arm/mach-mx2/clock_imx27.c @@ -486,26 +486,8 @@ static struct clk ckil_clk = { static unsigned long get_mpll_clk(struct clk *clk) { - uint32_t reg; - unsigned long ref_clk; - unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0; - unsigned long long temp; - - ref_clk = clk_get_rate(clk->parent); - - reg = __raw_readl(CCM_MPCTL0); - pdf = (reg & CCM_MPCTL0_PD_MASK) >> CCM_MPCTL0_PD_OFFSET; - mfd = (reg & CCM_MPCTL0_MFD_MASK) >> CCM_MPCTL0_MFD_OFFSET; - mfi = (reg & CCM_MPCTL0_MFI_MASK) >> CCM_MPCTL0_MFI_OFFSET; - mfn = (reg & CCM_MPCTL0_MFN_MASK) >> CCM_MPCTL0_MFN_OFFSET; - - mfi = (mfi <= 5) ? 5 : mfi; - temp = 2LL * ref_clk * mfn; - do_div(temp, mfd + 1); - temp = 2LL * ref_clk * mfi + temp; - do_div(temp, pdf + 1); - - return (unsigned long)temp; + return mxc_decode_pll(__raw_readl(CCM_MPCTL0), + clk_get_rate(clk->parent)); } static struct clk mpll_clk = { @@ -555,28 +537,18 @@ static unsigned long get_spll_clk(struct clk *clk) { uint32_t reg; unsigned long ref_clk; - unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0; - unsigned long long temp; ref_clk = clk_get_rate(clk->parent); reg = __raw_readl(CCM_SPCTL0); - /*TODO: This is TO2 Bug */ + + /* On TO2 we have to write the value back. Otherwise we + * read 0 from this register the next time. + */ if (mx27_revision() >= CHIP_REV_2_0) __raw_writel(reg, CCM_SPCTL0); - pdf = (reg & CCM_SPCTL0_PD_MASK) >> CCM_SPCTL0_PD_OFFSET; - mfd = (reg & CCM_SPCTL0_MFD_MASK) >> CCM_SPCTL0_MFD_OFFSET; - mfi = (reg & CCM_SPCTL0_MFI_MASK) >> CCM_SPCTL0_MFI_OFFSET; - mfn = (reg & CCM_SPCTL0_MFN_MASK) >> CCM_SPCTL0_MFN_OFFSET; - - mfi = (mfi <= 5) ? 5 : mfi; - temp = 2LL * ref_clk * mfn; - do_div(temp, mfd + 1); - temp = 2LL * ref_clk * mfi + temp; - do_div(temp, pdf + 1); - - return (unsigned long)temp; + return mxc_decode_pll(reg, ref_clk); } static struct clk spll_clk = { diff --git a/arch/arm/mach-mx3/clock.c b/arch/arm/mach-mx3/clock.c index b1746aae1f89..8486ea46d6c1 100644 --- a/arch/arm/mach-mx3/clock.c +++ b/arch/arm/mach-mx3/clock.c @@ -158,10 +158,8 @@ static int _clk_pll_set_rate(struct clk *clk, unsigned long rate) static unsigned long _clk_pll_get_rate(struct clk *clk) { - long mfi, mfn, mfd, pdf, ref_clk, mfn_abs; unsigned long reg, ccmr; - s64 temp; - unsigned int prcs; + unsigned int prcs, ref_clk; ccmr = __raw_readl(MXC_CCM_CCMR); prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET; @@ -185,27 +183,7 @@ static unsigned long _clk_pll_get_rate(struct clk *clk) return 0; } - pdf = (reg & MXC_CCM_PCTL_PD_MASK) >> MXC_CCM_PCTL_PD_OFFSET; - mfd = (reg & MXC_CCM_PCTL_MFD_MASK) >> MXC_CCM_PCTL_MFD_OFFSET; - mfi = (reg & MXC_CCM_PCTL_MFI_MASK) >> MXC_CCM_PCTL_MFI_OFFSET; - mfi = (mfi <= 5) ? 5 : mfi; - mfn = mfn_abs = reg & MXC_CCM_PCTL_MFN_MASK; - - if (mfn >= 0x200) { - mfn |= 0xFFFFFE00; - mfn_abs = -mfn; - } - - ref_clk *= 2; - ref_clk /= pdf + 1; - - temp = (u64) ref_clk * mfn_abs; - do_div(temp, mfd + 1); - if (mfn < 0) - temp = -temp; - temp = (ref_clk * mfi) + temp; - - return temp; + return mxc_decode_pll(reg, ref_clk); } static int _clk_usb_pll_enable(struct clk *clk) diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c index 0a38f0b396eb..888dd33abf76 100644 --- a/arch/arm/plat-mxc/clock.c +++ b/arch/arm/plat-mxc/clock.c @@ -328,3 +328,47 @@ static int __init mxc_setup_proc_entry(void) late_initcall(mxc_setup_proc_entry); #endif + +/* + * Get the resulting clock rate from a PLL register value and the input + * frequency. PLLs with this register layout can at least be found on + * MX1, MX21, MX27 and MX31 + * + * mfi + mfn / (mfd + 1) + * f = 2 * f_ref * -------------------- + * pd + 1 + */ +unsigned long mxc_decode_pll(unsigned int reg_val, u32 freq) +{ + long long ll; + int mfn_abs; + unsigned int mfi, mfn, mfd, pd; + + mfi = (reg_val >> 10) & 0xf; + mfn = reg_val & 0x3ff; + mfd = (reg_val >> 16) & 0x3ff; + pd = (reg_val >> 26) & 0xf; + + mfi = mfi <= 5 ? 5 : mfi; + + mfn_abs = mfn; + +#if !defined CONFIG_ARCH_MX1 && !defined CONFIG_ARCH_MX21 + if (mfn >= 0x200) { + mfn |= 0xFFFFFE00; + mfn_abs = -mfn; + } +#endif + + freq *= 2; + freq /= pd + 1; + + ll = (unsigned long long)freq * mfn_abs; + + do_div(ll, mfd + 1); + if (mfn < 0) + ll = -ll; + ll = (freq * mfi) + ll; + + return ll; +} diff --git a/arch/arm/plat-mxc/include/mach/clock.h b/arch/arm/plat-mxc/include/mach/clock.h index d21f78e78819..b830655514eb 100644 --- a/arch/arm/plat-mxc/include/mach/clock.h +++ b/arch/arm/plat-mxc/include/mach/clock.h @@ -63,5 +63,7 @@ struct clk { int clk_register(struct clk *clk); void clk_unregister(struct clk *clk); +unsigned long mxc_decode_pll(unsigned int pll, u32 f_ref); + #endif /* __ASSEMBLY__ */ #endif /* __ASM_ARCH_MXC_CLOCK_H__ */ -- cgit v1.2.3 From 30c730f8f90b08d77a73998d2ee34cf1f56e95cc Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 16 Feb 2009 14:36:49 +0100 Subject: [ARM] MXC: rework timer/clock initialisation - rename mxc_clocks_init to architecture specific versions. This allows us to have more than one architecture compiled in. - call mxc_timer_init from clock initialisation instead from board code Signed-off-by: Sascha Hauer --- arch/arm/mach-mx1/clock.c | 5 ++++- arch/arm/mach-mx1/mx1ads.c | 3 +-- arch/arm/mach-mx2/clock_imx27.c | 5 ++++- arch/arm/mach-mx2/mx27ads.c | 3 +-- arch/arm/mach-mx2/pcm038.c | 3 +-- arch/arm/mach-mx3/clock.c | 5 ++++- arch/arm/mach-mx3/mx31ads.c | 3 +-- arch/arm/mach-mx3/mx31lite.c | 3 +-- arch/arm/mach-mx3/mx31moboard.c | 3 +-- arch/arm/mach-mx3/mx31pdk.c | 3 +-- arch/arm/mach-mx3/pcm037.c | 3 +-- arch/arm/plat-mxc/include/mach/common.h | 7 +++++-- arch/arm/plat-mxc/time.c | 20 +++++--------------- 13 files changed, 30 insertions(+), 36 deletions(-) (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/mach-mx1/clock.c b/arch/arm/mach-mx1/clock.c index 3c464331b870..40a2274380a3 100644 --- a/arch/arm/mach-mx1/clock.c +++ b/arch/arm/mach-mx1/clock.c @@ -25,6 +25,7 @@ #include #include +#include #include "crm_regs.h" static int _clk_enable(struct clk *clk) @@ -594,7 +595,7 @@ static struct clk *mxc_clks[] = { &rtc_clk, }; -int __init mxc_clocks_init(unsigned long fref) +int __init mx1_clocks_init(unsigned long fref) { struct clk **clkp; unsigned int reg; @@ -625,5 +626,7 @@ int __init mxc_clocks_init(unsigned long fref) clk_enable(&hclk); clk_enable(&fclk); + mxc_timer_init(&gpt_clk); + return 0; } diff --git a/arch/arm/mach-mx1/mx1ads.c b/arch/arm/mach-mx1/mx1ads.c index be7dd75ebbe1..09dc77bb4812 100644 --- a/arch/arm/mach-mx1/mx1ads.c +++ b/arch/arm/mach-mx1/mx1ads.c @@ -118,8 +118,7 @@ static void __init mx1ads_init(void) static void __init mx1ads_timer_init(void) { - mxc_clocks_init(32000); - mxc_timer_init("gpt_clk"); + mx1_clocks_init(32000); } struct sys_timer mx1ads_timer = { diff --git a/arch/arm/mach-mx2/clock_imx27.c b/arch/arm/mach-mx2/clock_imx27.c index 047e71e6ea9a..7b2c1122d9ab 100644 --- a/arch/arm/mach-mx2/clock_imx27.c +++ b/arch/arm/mach-mx2/clock_imx27.c @@ -1551,7 +1551,7 @@ static void __init probe_mxc_clocks(void) * must be called very early to get information about the * available clock rate when the timer framework starts */ -int __init mxc_clocks_init(unsigned long fref) +int __init mx27_clocks_init(unsigned long fref) { u32 cscr; struct clk **clkp; @@ -1593,5 +1593,8 @@ int __init mxc_clocks_init(unsigned long fref) #ifdef CONFIG_DEBUG_LL_CONSOLE clk_enable(&uart1_clk[0]); #endif + + mxc_timer_init(&gpt1_clk[0]); + return 0; } diff --git a/arch/arm/mach-mx2/mx27ads.c b/arch/arm/mach-mx2/mx27ads.c index 7721c470d5ab..536bf64bc7c8 100644 --- a/arch/arm/mach-mx2/mx27ads.c +++ b/arch/arm/mach-mx2/mx27ads.c @@ -263,8 +263,7 @@ static void __init mx27ads_timer_init(void) if ((__raw_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0) fref = 27000000; - mxc_clocks_init(fref); - mxc_timer_init("gpt_clk.0"); + mx27_clocks_init(fref); } struct sys_timer mx27ads_timer = { diff --git a/arch/arm/mach-mx2/pcm038.c b/arch/arm/mach-mx2/pcm038.c index 534fd9a4ff9f..63cdef8565db 100644 --- a/arch/arm/mach-mx2/pcm038.c +++ b/arch/arm/mach-mx2/pcm038.c @@ -230,8 +230,7 @@ static void __init pcm038_init(void) static void __init pcm038_timer_init(void) { - mxc_clocks_init(26000000); - mxc_timer_init("gpt_clk.0"); + mx27_clocks_init(26000000); } struct sys_timer pcm038_timer = { diff --git a/arch/arm/mach-mx3/clock.c b/arch/arm/mach-mx3/clock.c index 8486ea46d6c1..8b41facb391b 100644 --- a/arch/arm/mach-mx3/clock.c +++ b/arch/arm/mach-mx3/clock.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "crm_regs.h" @@ -1071,7 +1072,7 @@ static struct clk *mxc_clks[] = { &iim_clk, }; -int __init mxc_clocks_init(unsigned long fref) +int __init mx31_clocks_init(unsigned long fref) { u32 reg; struct clk **clkp; @@ -1121,6 +1122,8 @@ int __init mxc_clocks_init(unsigned long fref) __raw_writel(reg, MXC_CCM_PMCR1); } + mxc_timer_init(&ipg_clk); + return 0; } diff --git a/arch/arm/mach-mx3/mx31ads.c b/arch/arm/mach-mx3/mx31ads.c index f902a7c37c31..f913999eedf0 100644 --- a/arch/arm/mach-mx3/mx31ads.c +++ b/arch/arm/mach-mx3/mx31ads.c @@ -244,8 +244,7 @@ static void __init mxc_board_init(void) static void __init mx31ads_timer_init(void) { - mxc_clocks_init(26000000); - mxc_timer_init("ipg_clk.0"); + mx31_clocks_init(26000000); } struct sys_timer mx31ads_timer = { diff --git a/arch/arm/mach-mx3/mx31lite.c b/arch/arm/mach-mx3/mx31lite.c index c43440070143..e61fad2f60f3 100644 --- a/arch/arm/mach-mx3/mx31lite.c +++ b/arch/arm/mach-mx3/mx31lite.c @@ -82,8 +82,7 @@ static void __init mxc_board_init(void) static void __init mx31lite_timer_init(void) { - mxc_clocks_init(26000000); - mxc_timer_init("ipg_clk.0"); + mx31_clocks_init(26000000); } struct sys_timer mx31lite_timer = { diff --git a/arch/arm/mach-mx3/mx31moboard.c b/arch/arm/mach-mx3/mx31moboard.c index c29098af7394..3d2773e4bc81 100644 --- a/arch/arm/mach-mx3/mx31moboard.c +++ b/arch/arm/mach-mx3/mx31moboard.c @@ -120,8 +120,7 @@ void __init mx31moboard_map_io(void) static void __init mx31moboard_timer_init(void) { - mxc_clocks_init(26000000); - mxc_timer_init("ipg_clk.0"); + mx31_clocks_init(26000000); } struct sys_timer mx31moboard_timer = { diff --git a/arch/arm/mach-mx3/mx31pdk.c b/arch/arm/mach-mx3/mx31pdk.c index d464d068a4a6..ac427edb4db1 100644 --- a/arch/arm/mach-mx3/mx31pdk.c +++ b/arch/arm/mach-mx3/mx31pdk.c @@ -91,8 +91,7 @@ static void __init mxc_board_init(void) static void __init mx31pdk_timer_init(void) { - mxc_clocks_init(26000000); - mxc_timer_init("ipg_clk.0"); + mx31_clocks_init(26000000); } static struct sys_timer mx31pdk_timer = { diff --git a/arch/arm/mach-mx3/pcm037.c b/arch/arm/mach-mx3/pcm037.c index 8cea82587222..3b5ba551cb14 100644 --- a/arch/arm/mach-mx3/pcm037.c +++ b/arch/arm/mach-mx3/pcm037.c @@ -181,8 +181,7 @@ void __init pcm037_map_io(void) static void __init pcm037_timer_init(void) { - mxc_clocks_init(26000000); - mxc_timer_init("ipg_clk.0"); + mx31_clocks_init(26000000); } struct sys_timer pcm037_timer = { diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h index 6350287a59b9..2c08b8e14e39 100644 --- a/arch/arm/plat-mxc/include/mach/common.h +++ b/arch/arm/plat-mxc/include/mach/common.h @@ -12,11 +12,14 @@ #define __ASM_ARCH_MXC_COMMON_H__ struct platform_device; +struct clk; extern void mxc_map_io(void); extern void mxc_init_irq(void); -extern void mxc_timer_init(const char *clk_timer); -extern int mxc_clocks_init(unsigned long fref); +extern void mxc_timer_init(struct clk *timer_clk); +extern int mx1_clocks_init(unsigned long fref); +extern int mx27_clocks_init(unsigned long fref); +extern int mx31_clocks_init(unsigned long fref); extern int mxc_register_gpios(void); extern int mxc_register_device(struct platform_device *pdev, void *data); diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c index 758a1293bcfa..eb93fd1789db 100644 --- a/arch/arm/plat-mxc/time.c +++ b/arch/arm/plat-mxc/time.c @@ -34,9 +34,6 @@ static struct clock_event_device clockevent_mxc; static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED; -/* clock source for the timer */ -static struct clk *timer_clk; - /* clock source */ static cycle_t mxc_get_cycles(void) @@ -53,7 +50,7 @@ static struct clocksource clocksource_mxc = { .flags = CLOCK_SOURCE_IS_CONTINUOUS, }; -static int __init mxc_clocksource_init(void) +static int __init mxc_clocksource_init(struct clk *timer_clk) { unsigned int clock; @@ -177,7 +174,7 @@ static struct clock_event_device clockevent_mxc = { .rating = 200, }; -static int __init mxc_clockevent_init(void) +static int __init mxc_clockevent_init(struct clk *timer_clk) { unsigned int clock; @@ -197,14 +194,8 @@ static int __init mxc_clockevent_init(void) return 0; } -void __init mxc_timer_init(const char *clk_timer) +void __init mxc_timer_init(struct clk *timer_clk) { - timer_clk = clk_get(NULL, clk_timer); - if (!timer_clk) { - printk(KERN_ERR"Cannot determine timer clock. Giving up.\n"); - return; - } - clk_enable(timer_clk); /* @@ -219,10 +210,9 @@ void __init mxc_timer_init(const char *clk_timer) TIMER_BASE + MXC_TCTL); /* init and register the timer to the framework */ - mxc_clocksource_init(); - mxc_clockevent_init(); + mxc_clocksource_init(timer_clk); + mxc_clockevent_init(timer_clk); /* Make irqs happen */ setup_irq(TIMER_INTERRUPT, &mxc_timer_irq); } - -- cgit v1.2.3 From e65fb0099fe4fe82d59ffe84f1e88a489218d7f9 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 16 Feb 2009 14:29:10 +0100 Subject: [ARM] MXC: remove _clk suffix from clock names The context makes it clear already that these are clocks, so there's no need for such a suffix. This patch only changes the clocks actually used in the tree. The remaining clocks are renamed in the subsequent architecture specific patches. Signed-off-by: Sascha Hauer --- arch/arm/mach-mx1/clock.c | 4 ++-- arch/arm/mach-mx2/clock_imx27.c | 18 +++++++++--------- arch/arm/mach-mx3/clock.c | 14 +++++++------- arch/arm/plat-mxc/dma-mx1-mx2.c | 2 +- drivers/mtd/nand/mxc_nand.c | 2 +- drivers/serial/imx.c | 2 +- drivers/w1/masters/mxc_w1.c | 2 +- 7 files changed, 22 insertions(+), 22 deletions(-) (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/mach-mx1/clock.c b/arch/arm/mach-mx1/clock.c index 40a2274380a3..0d0f306851d0 100644 --- a/arch/arm/mach-mx1/clock.c +++ b/arch/arm/mach-mx1/clock.c @@ -462,7 +462,7 @@ static struct clk clko_clk = { }; static struct clk dma_clk = { - .name = "dma_clk", + .name = "dma", .parent = &hclk, .round_rate = _clk_parent_round_rate, .set_rate = _clk_parent_set_rate, @@ -513,7 +513,7 @@ static struct clk gpt_clk = { }; static struct clk uart_clk = { - .name = "uart_clk", + .name = "uart", .parent = &perclk[0], .round_rate = _clk_parent_round_rate, .set_rate = _clk_parent_set_rate, diff --git a/arch/arm/mach-mx2/clock_imx27.c b/arch/arm/mach-mx2/clock_imx27.c index 7b2c1122d9ab..700a22f5ae88 100644 --- a/arch/arm/mach-mx2/clock_imx27.c +++ b/arch/arm/mach-mx2/clock_imx27.c @@ -685,7 +685,7 @@ static struct clk per_clk[] = { struct clk uart1_clk[] = { { - .name = "uart_clk", + .name = "uart", .id = 0, .parent = &per_clk[0], .secondary = &uart1_clk[1], @@ -702,7 +702,7 @@ struct clk uart1_clk[] = { struct clk uart2_clk[] = { { - .name = "uart_clk", + .name = "uart", .id = 1, .parent = &per_clk[0], .secondary = &uart2_clk[1], @@ -719,7 +719,7 @@ struct clk uart2_clk[] = { struct clk uart3_clk[] = { { - .name = "uart_clk", + .name = "uart", .id = 2, .parent = &per_clk[0], .secondary = &uart3_clk[1], @@ -736,7 +736,7 @@ struct clk uart3_clk[] = { struct clk uart4_clk[] = { { - .name = "uart_clk", + .name = "uart", .id = 3, .parent = &per_clk[0], .secondary = &uart4_clk[1], @@ -753,7 +753,7 @@ struct clk uart4_clk[] = { struct clk uart5_clk[] = { { - .name = "uart_clk", + .name = "uart", .id = 4, .parent = &per_clk[0], .secondary = &uart5_clk[1], @@ -770,7 +770,7 @@ struct clk uart5_clk[] = { struct clk uart6_clk[] = { { - .name = "uart_clk", + .name = "uart", .id = 5, .parent = &per_clk[0], .secondary = &uart6_clk[1], @@ -1110,7 +1110,7 @@ static struct clk ssi2_clk[] = { }; static struct clk nfc_clk = { - .name = "nfc_clk", + .name = "nfc", .parent = &cpu_clk, .get_rate = _clk_nfc_recalc, .enable = _clk_enable, @@ -1128,7 +1128,7 @@ static struct clk vpu_clk = { }; static struct clk dma_clk = { - .name = "dma_clk", + .name = "dma", .parent = &ahb_clk, .enable = _clk_dma_enable, .disable = _clk_dma_disable, @@ -1260,7 +1260,7 @@ static struct clk kpp_clk = { }; static struct clk owire_clk = { - .name = "owire_clk", + .name = "owire", .parent = &ipg_clk, .enable = _clk_enable, .enable_reg = CCM_PCCR0, diff --git a/arch/arm/mach-mx3/clock.c b/arch/arm/mach-mx3/clock.c index 8b41facb391b..bc3a3beb9a66 100644 --- a/arch/arm/mach-mx3/clock.c +++ b/arch/arm/mach-mx3/clock.c @@ -593,7 +593,7 @@ static struct clk epit_clk[] = { }; static struct clk nfc_clk = { - .name = "nfc_clk", + .name = "nfc", .parent = &ahb_clk, .get_rate = _clk_nfc_get_rate, }; @@ -667,7 +667,7 @@ static struct clk csi_clk = { static struct clk uart_clk[] = { { - .name = "uart_clk", + .name = "uart", .id = 0, .parent = &perclk_clk, .enable = _clk_enable, @@ -675,7 +675,7 @@ static struct clk uart_clk[] = { .enable_shift = MXC_CCM_CGR0_UART1_OFFSET, .disable = _clk_disable,}, { - .name = "uart_clk", + .name = "uart", .id = 1, .parent = &perclk_clk, .enable = _clk_enable, @@ -683,7 +683,7 @@ static struct clk uart_clk[] = { .enable_shift = MXC_CCM_CGR0_UART2_OFFSET, .disable = _clk_disable,}, { - .name = "uart_clk", + .name = "uart", .id = 2, .parent = &perclk_clk, .enable = _clk_enable, @@ -691,7 +691,7 @@ static struct clk uart_clk[] = { .enable_shift = MXC_CCM_CGR1_UART3_OFFSET, .disable = _clk_disable,}, { - .name = "uart_clk", + .name = "uart", .id = 3, .parent = &perclk_clk, .enable = _clk_enable, @@ -699,7 +699,7 @@ static struct clk uart_clk[] = { .enable_shift = MXC_CCM_CGR1_UART4_OFFSET, .disable = _clk_disable,}, { - .name = "uart_clk", + .name = "uart", .id = 4, .parent = &perclk_clk, .enable = _clk_enable, @@ -736,7 +736,7 @@ static struct clk i2c_clk[] = { }; static struct clk owire_clk = { - .name = "owire_clk", + .name = "owire", .parent = &perclk_clk, .enable_reg = MXC_CCM_CGR1, .enable_shift = MXC_CCM_CGR1_OWIRE_OFFSET, diff --git a/arch/arm/plat-mxc/dma-mx1-mx2.c b/arch/arm/plat-mxc/dma-mx1-mx2.c index 2905ec758758..1d64287c3078 100644 --- a/arch/arm/plat-mxc/dma-mx1-mx2.c +++ b/arch/arm/plat-mxc/dma-mx1-mx2.c @@ -802,7 +802,7 @@ static int __init imx_dma_init(void) int ret = 0; int i; - dma_clk = clk_get(NULL, "dma_clk"); + dma_clk = clk_get(NULL, "dma"); clk_enable(dma_clk); /* reset DMA module */ diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 21fd4f1c4806..bad048aca89a 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -880,7 +880,7 @@ static int __init mxcnd_probe(struct platform_device *pdev) this->read_buf = mxc_nand_read_buf; this->verify_buf = mxc_nand_verify_buf; - host->clk = clk_get(&pdev->dev, "nfc_clk"); + host->clk = clk_get(&pdev->dev, "nfc"); if (IS_ERR(host->clk)) goto eclk; diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c index a50954612b60..9f460b175c50 100644 --- a/drivers/serial/imx.c +++ b/drivers/serial/imx.c @@ -1129,7 +1129,7 @@ static int serial_imx_probe(struct platform_device *pdev) sport->timer.function = imx_timeout; sport->timer.data = (unsigned long)sport; - sport->clk = clk_get(&pdev->dev, "uart_clk"); + sport->clk = clk_get(&pdev->dev, "uart"); if (IS_ERR(sport->clk)) { ret = PTR_ERR(sport->clk); goto unmap; diff --git a/drivers/w1/masters/mxc_w1.c b/drivers/w1/masters/mxc_w1.c index b9d74d0b353e..65244c02551b 100644 --- a/drivers/w1/masters/mxc_w1.c +++ b/drivers/w1/masters/mxc_w1.c @@ -116,7 +116,7 @@ static int __init mxc_w1_probe(struct platform_device *pdev) if (!mdev) return -ENOMEM; - mdev->clk = clk_get(&pdev->dev, "owire_clk"); + mdev->clk = clk_get(&pdev->dev, "owire"); if (!mdev->clk) { err = -ENODEV; goto failed_clk; -- cgit v1.2.3 From d1755e3592305f8866b4d60d63a481959d5e58bf Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 16 Feb 2009 14:27:06 +0100 Subject: [ARM] MXC: add clkdev support This patch only adds general clkdev support without actually switching any MXC architecture to clkdev. Signed-off-by: Sascha Hauer --- arch/arm/plat-mxc/clock.c | 10 ++++++++++ arch/arm/plat-mxc/include/mach/clkdev.h | 7 +++++++ arch/arm/plat-mxc/include/mach/clock.h | 4 ++++ 3 files changed, 21 insertions(+) create mode 100644 arch/arm/plat-mxc/include/mach/clkdev.h (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c index 888dd33abf76..92e13566cd4f 100644 --- a/arch/arm/plat-mxc/clock.c +++ b/arch/arm/plat-mxc/clock.c @@ -47,6 +47,11 @@ static DEFINE_MUTEX(clocks_mutex); * Standard clock functions defined in include/linux/clk.h *-------------------------------------------------------------------------*/ +/* + * All the code inside #ifndef CONFIG_COMMON_CLKDEV can be removed once all + * MXC architectures have switched to using clkdev. + */ +#ifndef CONFIG_COMMON_CLKDEV /* * Retrieve a clock by name. * @@ -110,6 +115,7 @@ found: return clk; } EXPORT_SYMBOL(clk_get); +#endif static void __clk_disable(struct clk *clk) { @@ -187,6 +193,7 @@ unsigned long clk_get_rate(struct clk *clk) } EXPORT_SYMBOL(clk_get_rate); +#ifndef CONFIG_COMMON_CLKDEV /* Decrement the clock's module reference count */ void clk_put(struct clk *clk) { @@ -194,6 +201,7 @@ void clk_put(struct clk *clk) module_put(clk->owner); } EXPORT_SYMBOL(clk_put); +#endif /* Round the requested clock rate to the nearest supported * rate that is less than or equal to the requested rate. @@ -257,6 +265,7 @@ struct clk *clk_get_parent(struct clk *clk) } EXPORT_SYMBOL(clk_get_parent); +#ifndef CONFIG_COMMON_CLKDEV /* * Add a new clock to the clock tree. */ @@ -327,6 +336,7 @@ static int __init mxc_setup_proc_entry(void) } late_initcall(mxc_setup_proc_entry); +#endif /* CONFIG_PROC_FS */ #endif /* diff --git a/arch/arm/plat-mxc/include/mach/clkdev.h b/arch/arm/plat-mxc/include/mach/clkdev.h new file mode 100644 index 000000000000..04b37a89801c --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/clkdev.h @@ -0,0 +1,7 @@ +#ifndef __ASM_MACH_CLKDEV_H +#define __ASM_MACH_CLKDEV_H + +#define __clk_get(clk) ({ 1; }) +#define __clk_put(clk) do { } while (0) + +#endif diff --git a/arch/arm/plat-mxc/include/mach/clock.h b/arch/arm/plat-mxc/include/mach/clock.h index b830655514eb..43a82d0c534d 100644 --- a/arch/arm/plat-mxc/include/mach/clock.h +++ b/arch/arm/plat-mxc/include/mach/clock.h @@ -26,9 +26,13 @@ struct module; struct clk { +#ifndef CONFIG_COMMON_CLKDEV + /* As soon as i.MX1 and i.MX31 switched to clkdev, this + * block can go away */ struct list_head node; struct module *owner; const char *name; +#endif int id; /* Source clock this clk depends on */ struct clk *parent; -- cgit v1.2.3 From edfcea80eb12b43680c4be0f2e31c8f5b1288edd Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 16 Feb 2009 15:13:43 +0100 Subject: [ARM] MX27 Clock rework This changes MX27 to use common clkdev. It also cleans up MX27 clock support to be more readable. Signed-off-by: Sascha Hauer --- arch/arm/mach-mx2/clock_imx27.c | 1613 ++++++++++----------------------------- arch/arm/mach-mx2/cpu_imx27.c | 4 +- arch/arm/mach-mx2/crm_regs.h | 273 ------- arch/arm/plat-mxc/Kconfig | 1 + 4 files changed, 387 insertions(+), 1504 deletions(-) delete mode 100644 arch/arm/mach-mx2/crm_regs.h (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/mach-mx2/clock_imx27.c b/arch/arm/mach-mx2/clock_imx27.c index 700a22f5ae88..3f7280c490f0 100644 --- a/arch/arm/mach-mx2/clock_imx27.c +++ b/arch/arm/mach-mx2/clock_imx27.c @@ -1,6 +1,7 @@ /* * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -20,23 +21,60 @@ #include #include #include -#include -#include -#include +#include #include -#include "crm_regs.h" - -static struct clk ckil_clk; -static struct clk mpll_clk; -static struct clk mpll_main_clk[]; -static struct clk spll_clk; - -static int _clk_enable(struct clk *clk) +#include +#include +#include + +/* Register offsets */ +#define CCM_CSCR (IO_ADDRESS(CCM_BASE_ADDR) + 0x0) +#define CCM_MPCTL0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x4) +#define CCM_MPCTL1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x8) +#define CCM_SPCTL0 (IO_ADDRESS(CCM_BASE_ADDR) + 0xC) +#define CCM_SPCTL1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x10) +#define CCM_OSC26MCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x14) +#define CCM_PCDR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x18) +#define CCM_PCDR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x1c) +#define CCM_PCCR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x20) +#define CCM_PCCR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x24) +#define CCM_CCSR (IO_ADDRESS(CCM_BASE_ADDR) + 0x28) +#define CCM_PMCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x2c) +#define CCM_PMCOUNT (IO_ADDRESS(CCM_BASE_ADDR) + 0x30) +#define CCM_WKGDCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x34) + +#define CCM_CSCR_UPDATE_DIS (1 << 31) +#define CCM_CSCR_SSI2 (1 << 23) +#define CCM_CSCR_SSI1 (1 << 22) +#define CCM_CSCR_VPU (1 << 21) +#define CCM_CSCR_MSHC (1 << 20) +#define CCM_CSCR_SPLLRES (1 << 19) +#define CCM_CSCR_MPLLRES (1 << 18) +#define CCM_CSCR_SP (1 << 17) +#define CCM_CSCR_MCU (1 << 16) +#define CCM_CSCR_OSC26MDIV (1 << 4) +#define CCM_CSCR_OSC26M (1 << 3) +#define CCM_CSCR_FPM (1 << 2) +#define CCM_CSCR_SPEN (1 << 1) +#define CCM_CSCR_MPEN (1 << 0) + +/* i.MX27 TO 2+ */ +#define CCM_CSCR_ARM_SRC (1 << 15) + +#define CCM_SPCTL1_LF (1 << 15) +#define CCM_SPCTL1_BRMO (1 << 6) + +static struct clk mpll_main1_clk, mpll_main2_clk; + +static int clk_pccr_enable(struct clk *clk) { unsigned long reg; + if (!clk->enable_reg) + return 0; + reg = __raw_readl(clk->enable_reg); reg |= 1 << clk->enable_shift; __raw_writel(reg, clk->enable_reg); @@ -44,16 +82,19 @@ static int _clk_enable(struct clk *clk) return 0; } -static void _clk_disable(struct clk *clk) +static void clk_pccr_disable(struct clk *clk) { unsigned long reg; + if (!clk->enable_reg) + return; + reg = __raw_readl(clk->enable_reg); reg &= ~(1 << clk->enable_shift); __raw_writel(reg, clk->enable_reg); } -static int _clk_spll_enable(struct clk *clk) +static int clk_spll_enable(struct clk *clk) { unsigned long reg; @@ -61,13 +102,12 @@ static int _clk_spll_enable(struct clk *clk) reg |= CCM_CSCR_SPEN; __raw_writel(reg, CCM_CSCR); - while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0) - ; + while (!(__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF)); return 0; } -static void _clk_spll_disable(struct clk *clk) +static void clk_spll_disable(struct clk *clk) { unsigned long reg; @@ -76,192 +116,30 @@ static void _clk_spll_disable(struct clk *clk) __raw_writel(reg, CCM_CSCR); } -static void _clk_pccr01_enable(unsigned long mask0, unsigned long mask1) -{ - unsigned long reg; - - reg = __raw_readl(CCM_PCCR0); - reg |= mask0; - __raw_writel(reg, CCM_PCCR0); - - reg = __raw_readl(CCM_PCCR1); - reg |= mask1; - __raw_writel(reg, CCM_PCCR1); - -} - -static void _clk_pccr01_disable(unsigned long mask0, unsigned long mask1) -{ - unsigned long reg; - - reg = __raw_readl(CCM_PCCR0); - reg &= ~mask0; - __raw_writel(reg, CCM_PCCR0); - - reg = __raw_readl(CCM_PCCR1); - reg &= ~mask1; - __raw_writel(reg, CCM_PCCR1); -} - -static void _clk_pccr10_enable(unsigned long mask1, unsigned long mask0) -{ - unsigned long reg; - - reg = __raw_readl(CCM_PCCR1); - reg |= mask1; - __raw_writel(reg, CCM_PCCR1); - - reg = __raw_readl(CCM_PCCR0); - reg |= mask0; - __raw_writel(reg, CCM_PCCR0); -} - -static void _clk_pccr10_disable(unsigned long mask1, unsigned long mask0) -{ - unsigned long reg; - - reg = __raw_readl(CCM_PCCR1); - reg &= ~mask1; - __raw_writel(reg, CCM_PCCR1); - - reg = __raw_readl(CCM_PCCR0); - reg &= ~mask0; - __raw_writel(reg, CCM_PCCR0); -} - -static int _clk_dma_enable(struct clk *clk) -{ - _clk_pccr01_enable(CCM_PCCR0_DMA_MASK, CCM_PCCR1_HCLK_DMA_MASK); - - return 0; -} - -static void _clk_dma_disable(struct clk *clk) -{ - _clk_pccr01_disable(CCM_PCCR0_DMA_MASK, CCM_PCCR1_HCLK_DMA_MASK); -} - -static int _clk_rtic_enable(struct clk *clk) -{ - _clk_pccr01_enable(CCM_PCCR0_RTIC_MASK, CCM_PCCR1_HCLK_RTIC_MASK); - - return 0; -} - -static void _clk_rtic_disable(struct clk *clk) -{ - _clk_pccr01_disable(CCM_PCCR0_RTIC_MASK, CCM_PCCR1_HCLK_RTIC_MASK); -} - -static int _clk_emma_enable(struct clk *clk) -{ - _clk_pccr01_enable(CCM_PCCR0_EMMA_MASK, CCM_PCCR1_HCLK_EMMA_MASK); - - return 0; -} - -static void _clk_emma_disable(struct clk *clk) -{ - _clk_pccr01_disable(CCM_PCCR0_EMMA_MASK, CCM_PCCR1_HCLK_EMMA_MASK); -} - -static int _clk_slcdc_enable(struct clk *clk) -{ - _clk_pccr01_enable(CCM_PCCR0_SLCDC_MASK, CCM_PCCR1_HCLK_SLCDC_MASK); - - return 0; -} - -static void _clk_slcdc_disable(struct clk *clk) -{ - _clk_pccr01_disable(CCM_PCCR0_SLCDC_MASK, CCM_PCCR1_HCLK_SLCDC_MASK); -} - -static int _clk_fec_enable(struct clk *clk) -{ - _clk_pccr01_enable(CCM_PCCR0_FEC_MASK, CCM_PCCR1_HCLK_FEC_MASK); - - return 0; -} - -static void _clk_fec_disable(struct clk *clk) -{ - _clk_pccr01_disable(CCM_PCCR0_FEC_MASK, CCM_PCCR1_HCLK_FEC_MASK); -} - -static int _clk_vpu_enable(struct clk *clk) -{ - unsigned long reg; - - reg = __raw_readl(CCM_PCCR1); - reg |= CCM_PCCR1_VPU_BAUD_MASK | CCM_PCCR1_HCLK_VPU_MASK; - __raw_writel(reg, CCM_PCCR1); - - return 0; -} - -static void _clk_vpu_disable(struct clk *clk) -{ - unsigned long reg; - - reg = __raw_readl(CCM_PCCR1); - reg &= ~(CCM_PCCR1_VPU_BAUD_MASK | CCM_PCCR1_HCLK_VPU_MASK); - __raw_writel(reg, CCM_PCCR1); -} - -static int _clk_sahara2_enable(struct clk *clk) -{ - _clk_pccr01_enable(CCM_PCCR0_SAHARA_MASK, CCM_PCCR1_HCLK_SAHARA_MASK); - - return 0; -} - -static void _clk_sahara2_disable(struct clk *clk) -{ - _clk_pccr01_disable(CCM_PCCR0_SAHARA_MASK, CCM_PCCR1_HCLK_SAHARA_MASK); -} - -static int _clk_mstick1_enable(struct clk *clk) -{ - _clk_pccr10_enable(CCM_PCCR1_MSHC_BAUD_MASK, CCM_PCCR0_MSHC_MASK); - - return 0; -} - -static void _clk_mstick1_disable(struct clk *clk) +static int clk_cpu_set_parent(struct clk *clk, struct clk *parent) { - _clk_pccr10_disable(CCM_PCCR1_MSHC_BAUD_MASK, CCM_PCCR0_MSHC_MASK); -} - -#define CSCR() (__raw_readl(CCM_CSCR)) -#define PCDR0() (__raw_readl(CCM_PCDR0)) -#define PCDR1() (__raw_readl(CCM_PCDR1)) - -static int _clk_cpu_set_parent(struct clk *clk, struct clk *parent) -{ - int cscr = CSCR(); + int cscr = __raw_readl(CCM_CSCR); if (clk->parent == parent) return 0; if (mx27_revision() >= CHIP_REV_2_0) { - if (parent == &mpll_main_clk[0]) { + if (parent == &mpll_main1_clk) { cscr |= CCM_CSCR_ARM_SRC; } else { - if (parent == &mpll_main_clk[1]) + if (parent == &mpll_main2_clk) cscr &= ~CCM_CSCR_ARM_SRC; else return -EINVAL; } __raw_writel(cscr, CCM_CSCR); - } else - return -ENODEV; - - clk->parent = parent; - return 0; + clk->parent = parent; + return 0; + } + return -ENODEV; } -static unsigned long _clk_cpu_round_rate(struct clk *clk, unsigned long rate) +static unsigned long round_rate_cpu(struct clk *clk, unsigned long rate) { int div; unsigned long parent_rate; @@ -278,7 +156,7 @@ static unsigned long _clk_cpu_round_rate(struct clk *clk, unsigned long rate) return parent_rate / div; } -static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate) +static int set_rate_cpu(struct clk *clk, unsigned long rate) { unsigned int div; uint32_t reg; @@ -295,19 +173,18 @@ static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate) reg = __raw_readl(CCM_CSCR); if (mx27_revision() >= CHIP_REV_2_0) { - reg &= ~CCM_CSCR_ARM_MASK; - reg |= div << CCM_CSCR_ARM_OFFSET; - reg &= ~0x06; - __raw_writel(reg | 0x80000000, CCM_CSCR); + reg &= ~(3 << 12); + reg |= div << 12; + reg &= ~(CCM_CSCR_FPM | CCM_CSCR_SPEN); + __raw_writel(reg | CCM_CSCR_UPDATE_DIS, CCM_CSCR); } else { - printk(KERN_ERR "Cant set CPU frequency!\n"); + printk(KERN_ERR "Can't set CPU frequency!\n"); } return 0; } -static unsigned long _clk_perclkx_round_rate(struct clk *clk, - unsigned long rate) +static unsigned long round_rate_per(struct clk *clk, unsigned long rate) { u32 div; unsigned long parent_rate; @@ -324,7 +201,7 @@ static unsigned long _clk_perclkx_round_rate(struct clk *clk, return parent_rate / div; } -static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate) +static int set_rate_per(struct clk *clk, unsigned long rate) { u32 reg; u32 div; @@ -340,84 +217,65 @@ static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate) return -EINVAL; div--; - reg = - __raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK << - (clk->id << 3)); + reg = __raw_readl(CCM_PCDR1) & ~(0x3f << (clk->id << 3)); reg |= div << (clk->id << 3); __raw_writel(reg, CCM_PCDR1); return 0; } -static unsigned long _clk_usb_recalc(struct clk *clk) +static unsigned long get_rate_usb(struct clk *clk) { unsigned long usb_pdf; unsigned long parent_rate; parent_rate = clk_get_rate(clk->parent); - usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET; + usb_pdf = (__raw_readl(CCM_CSCR) >> 28) & 0x7; return parent_rate / (usb_pdf + 1U); } -static unsigned long _clk_ssi1_recalc(struct clk *clk) +static unsigned long get_rate_ssix(struct clk *clk, unsigned long pdf) { - unsigned long ssi1_pdf; unsigned long parent_rate; parent_rate = clk_get_rate(clk->parent); - ssi1_pdf = (PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK) >> - CCM_PCDR0_SSI1BAUDDIV_OFFSET; - if (mx27_revision() >= CHIP_REV_2_0) - ssi1_pdf += 4; + pdf += 4; /* MX27 TO2+ */ else - ssi1_pdf = (ssi1_pdf < 2) ? 124UL : ssi1_pdf; + pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */ - return 2UL * parent_rate / ssi1_pdf; + return 2UL * parent_rate / pdf; } -static unsigned long _clk_ssi2_recalc(struct clk *clk) +static unsigned long get_rate_ssi1(struct clk *clk) { - unsigned long ssi2_pdf; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - ssi2_pdf = (PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >> - CCM_PCDR0_SSI2BAUDDIV_OFFSET; - - if (mx27_revision() >= CHIP_REV_2_0) - ssi2_pdf += 4; - else - ssi2_pdf = (ssi2_pdf < 2) ? 124UL : ssi2_pdf; + return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 16) & 0x3f); +} - return 2UL * parent_rate / ssi2_pdf; +static unsigned long get_rate_ssi2(struct clk *clk) +{ + return get_rate_ssix(clk, (__raw_readl(CCM_PCDR0) >> 26) & 0x3f); } -static unsigned long _clk_nfc_recalc(struct clk *clk) +static unsigned long get_rate_nfc(struct clk *clk) { unsigned long nfc_pdf; unsigned long parent_rate; parent_rate = clk_get_rate(clk->parent); - if (mx27_revision() >= CHIP_REV_2_0) { - nfc_pdf = - (PCDR0() & CCM_PCDR0_NFCDIV2_MASK) >> - CCM_PCDR0_NFCDIV2_OFFSET; - } else { - nfc_pdf = - (PCDR0() & CCM_PCDR0_NFCDIV_MASK) >> - CCM_PCDR0_NFCDIV_OFFSET; - } + if (mx27_revision() >= CHIP_REV_2_0) + nfc_pdf = (__raw_readl(CCM_PCDR0) >> 6) & 0xf; + else + nfc_pdf = (__raw_readl(CCM_PCDR0) >> 12) & 0xf; return parent_rate / (nfc_pdf + 1); } -static unsigned long _clk_vpu_recalc(struct clk *clk) +static unsigned long get_rate_vpu(struct clk *clk) { unsigned long vpu_pdf; unsigned long parent_rate; @@ -425,25 +283,27 @@ static unsigned long _clk_vpu_recalc(struct clk *clk) parent_rate = clk_get_rate(clk->parent); if (mx27_revision() >= CHIP_REV_2_0) { - vpu_pdf = - (PCDR0() & CCM_PCDR0_VPUDIV2_MASK) >> - CCM_PCDR0_VPUDIV2_OFFSET; + vpu_pdf = (__raw_readl(CCM_PCDR0) >> 10) & 0x3f; vpu_pdf += 4; } else { - vpu_pdf = - (PCDR0() & CCM_PCDR0_VPUDIV_MASK) >> - CCM_PCDR0_VPUDIV_OFFSET; + vpu_pdf = (__raw_readl(CCM_PCDR0) >> 8) & 0xf; vpu_pdf = (vpu_pdf < 2) ? 124 : vpu_pdf; } + return 2UL * parent_rate / vpu_pdf; } -static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate) +static unsigned long round_rate_parent(struct clk *clk, unsigned long rate) { return clk->parent->round_rate(clk->parent, rate); } -static int _clk_parent_set_rate(struct clk *clk, unsigned long rate) +static unsigned long get_rate_parent(struct clk *clk) +{ + return clk_get_rate(clk->parent); +} + +static int set_rate_parent(struct clk *clk, unsigned long rate) { return clk->parent->set_rate(clk->parent, rate); } @@ -451,94 +311,52 @@ static int _clk_parent_set_rate(struct clk *clk, unsigned long rate) /* in Hz */ static unsigned long external_high_reference = 26000000; -static unsigned long get_high_reference_clock_rate(struct clk *clk) +static unsigned long get_rate_high_reference(struct clk *clk) { return external_high_reference; } -/* - * the high frequency external clock reference - * Default case is 26MHz. Could be changed at runtime - * with a call to change_external_high_reference() - */ -static struct clk ckih_clk = { - .name = "ckih", - .get_rate = get_high_reference_clock_rate, -}; - /* in Hz */ static unsigned long external_low_reference = 32768; -static unsigned long get_low_reference_clock_rate(struct clk *clk) +static unsigned long get_rate_low_reference(struct clk *clk) { return external_low_reference; } -/* - * the low frequency external clock reference - * Default case is 32.768kHz Could be changed at runtime - * with a call to change_external_low_reference() - */ -static struct clk ckil_clk = { - .name = "ckil", - .get_rate = get_low_reference_clock_rate, -}; +static unsigned long get_rate_fpm(struct clk *clk) +{ + return clk_get_rate(clk->parent) * 1024; +} -static unsigned long get_mpll_clk(struct clk *clk) +static unsigned long get_rate_mpll(struct clk *clk) { return mxc_decode_pll(__raw_readl(CCM_MPCTL0), clk_get_rate(clk->parent)); } -static struct clk mpll_clk = { - .name = "mpll", - .parent = &ckih_clk, - .get_rate = get_mpll_clk, -}; - -static unsigned long _clk_mpll_main_get_rate(struct clk *clk) +static unsigned long get_rate_mpll_main(struct clk *clk) { unsigned long parent_rate; parent_rate = clk_get_rate(clk->parent); /* i.MX27 TO2: - * clk->id == 0: arm clock source path 1 which is from 2*MPLL/DIV_2 - * clk->id == 1: arm clock source path 2 which is from 2*MPLL/DIV_3 + * clk->id == 0: arm clock source path 1 which is from 2 * MPLL / 2 + * clk->id == 1: arm clock source path 2 which is from 2 * MPLL / 3 */ - if (mx27_revision() >= CHIP_REV_2_0 && clk->id == 1) return 2UL * parent_rate / 3UL; return parent_rate; } -static struct clk mpll_main_clk[] = { - { - /* For i.MX27 TO2, it is the MPLL path 1 of ARM core - * It provide the clock source whose rate is same as MPLL - */ - .name = "mpll_main", - .id = 0, - .parent = &mpll_clk, - .get_rate = _clk_mpll_main_get_rate - }, { - /* For i.MX27 TO2, it is the MPLL path 2 of ARM core - * It provide the clock source whose rate is same MPLL * 2/3 - */ - .name = "mpll_main", - .id = 1, - .parent = &mpll_clk, - .get_rate = _clk_mpll_main_get_rate - } -}; - -static unsigned long get_spll_clk(struct clk *clk) +static unsigned long get_rate_spll(struct clk *clk) { uint32_t reg; - unsigned long ref_clk; + unsigned long rate; - ref_clk = clk_get_rate(clk->parent); + rate = clk_get_rate(clk->parent); reg = __raw_readl(CCM_SPCTL0); @@ -548,987 +366,325 @@ static unsigned long get_spll_clk(struct clk *clk) if (mx27_revision() >= CHIP_REV_2_0) __raw_writel(reg, CCM_SPCTL0); - return mxc_decode_pll(reg, ref_clk); + return mxc_decode_pll(reg, rate); } -static struct clk spll_clk = { - .name = "spll", - .parent = &ckih_clk, - .get_rate = get_spll_clk, - .enable = _clk_spll_enable, - .disable = _clk_spll_disable, -}; - -static unsigned long get_cpu_clk(struct clk *clk) +static unsigned long get_rate_cpu(struct clk *clk) { u32 div; unsigned long rate; if (mx27_revision() >= CHIP_REV_2_0) - div = (CSCR() & CCM_CSCR_ARM_MASK) >> CCM_CSCR_ARM_OFFSET; + div = (__raw_readl(CCM_CSCR) >> 12) & 0x3; else - div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET; + div = (__raw_readl(CCM_CSCR) >> 13) & 0x7; rate = clk_get_rate(clk->parent); return rate / (div + 1); } -static struct clk cpu_clk = { - .name = "cpu_clk", - .parent = &mpll_main_clk[1], - .set_parent = _clk_cpu_set_parent, - .round_rate = _clk_cpu_round_rate, - .get_rate = get_cpu_clk, - .set_rate = _clk_cpu_set_rate, -}; - -static unsigned long get_ahb_clk(struct clk *clk) +static unsigned long get_rate_ahb(struct clk *clk) { - unsigned long rate; - unsigned long bclk_pdf; + unsigned long rate, bclk_pdf; if (mx27_revision() >= CHIP_REV_2_0) - bclk_pdf = (CSCR() & CCM_CSCR_AHB_MASK) - >> CCM_CSCR_AHB_OFFSET; + bclk_pdf = (__raw_readl(CCM_CSCR) >> 8) & 0x3; else - bclk_pdf = (CSCR() & CCM_CSCR_BCLK_MASK) - >> CCM_CSCR_BCLK_OFFSET; + bclk_pdf = (__raw_readl(CCM_CSCR) >> 9) & 0xf; rate = clk_get_rate(clk->parent); return rate / (bclk_pdf + 1); } -static struct clk ahb_clk = { - .name = "ahb_clk", - .parent = &mpll_main_clk[1], - .get_rate = get_ahb_clk, -}; - -static unsigned long get_ipg_clk(struct clk *clk) +static unsigned long get_rate_ipg(struct clk *clk) { - unsigned long rate; - unsigned long ipg_pdf; + unsigned long rate, ipg_pdf; if (mx27_revision() >= CHIP_REV_2_0) return clk_get_rate(clk->parent); else - ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET; + ipg_pdf = (__raw_readl(CCM_CSCR) >> 8) & 1; rate = clk_get_rate(clk->parent); return rate / (ipg_pdf + 1); } -static struct clk ipg_clk = { - .name = "ipg_clk", - .parent = &ahb_clk, - .get_rate = get_ipg_clk, -}; - -static unsigned long _clk_perclkx_recalc(struct clk *clk) +static unsigned long get_rate_per(struct clk *clk) { - unsigned long perclk_pdf; - unsigned long parent_rate; + unsigned long perclk_pdf, parent_rate; parent_rate = clk_get_rate(clk->parent); if (clk->id < 0 || clk->id > 3) return 0; - perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK; + perclk_pdf = (__raw_readl(CCM_PCDR1) >> (clk->id << 3)) & 0x3f; return parent_rate / (perclk_pdf + 1); } -static struct clk per_clk[] = { - { - .name = "per_clk", - .id = 0, - .parent = &mpll_main_clk[1], - .get_rate = _clk_perclkx_recalc, - .enable = _clk_enable, - .enable_reg = CCM_PCCR1, - .enable_shift = CCM_PCCR1_PERCLK1_OFFSET, - .disable = _clk_disable, - }, { - .name = "per_clk", - .id = 1, - .parent = &mpll_main_clk[1], - .get_rate = _clk_perclkx_recalc, - .enable = _clk_enable, - .enable_reg = CCM_PCCR1, - .enable_shift = CCM_PCCR1_PERCLK2_OFFSET, - .disable = _clk_disable, - }, { - .name = "per_clk", - .id = 2, - .parent = &mpll_main_clk[1], - .round_rate = _clk_perclkx_round_rate, - .set_rate = _clk_perclkx_set_rate, - .get_rate = _clk_perclkx_recalc, - .enable = _clk_enable, - .enable_reg = CCM_PCCR1, - .enable_shift = CCM_PCCR1_PERCLK3_OFFSET, - .disable = _clk_disable, - }, { - .name = "per_clk", - .id = 3, - .parent = &mpll_main_clk[1], - .round_rate = _clk_perclkx_round_rate, - .set_rate = _clk_perclkx_set_rate, - .get_rate = _clk_perclkx_recalc, - .enable = _clk_enable, - .enable_reg = CCM_PCCR1, - .enable_shift = CCM_PCCR1_PERCLK4_OFFSET, - .disable = _clk_disable, - }, -}; - -struct clk uart1_clk[] = { - { - .name = "uart", - .id = 0, - .parent = &per_clk[0], - .secondary = &uart1_clk[1], - }, { - .name = "uart_ipg_clk", - .id = 0, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR1, - .enable_shift = CCM_PCCR1_UART1_OFFSET, - .disable = _clk_disable, - }, -}; - -struct clk uart2_clk[] = { - { - .name = "uart", - .id = 1, - .parent = &per_clk[0], - .secondary = &uart2_clk[1], - }, { - .name = "uart_ipg_clk", - .id = 1, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR1, - .enable_shift = CCM_PCCR1_UART2_OFFSET, - .disable = _clk_disable, - }, -}; - -struct clk uart3_clk[] = { - { - .name = "uart", - .id = 2, - .parent = &per_clk[0], - .secondary = &uart3_clk[1], - }, { - .name = "uart_ipg_clk", - .id = 2, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR1, - .enable_shift = CCM_PCCR1_UART3_OFFSET, - .disable = _clk_disable, - }, -}; - -struct clk uart4_clk[] = { - { - .name = "uart", - .id = 3, - .parent = &per_clk[0], - .secondary = &uart4_clk[1], - }, { - .name = "uart_ipg_clk", - .id = 3, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR1, - .enable_shift = CCM_PCCR1_UART4_OFFSET, - .disable = _clk_disable, - }, -}; - -struct clk uart5_clk[] = { - { - .name = "uart", - .id = 4, - .parent = &per_clk[0], - .secondary = &uart5_clk[1], - }, { - .name = "uart_ipg_clk", - .id = 4, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR1, - .enable_shift = CCM_PCCR1_UART5_OFFSET, - .disable = _clk_disable, - }, -}; - -struct clk uart6_clk[] = { - { - .name = "uart", - .id = 5, - .parent = &per_clk[0], - .secondary = &uart6_clk[1], - }, { - .name = "uart_ipg_clk", - .id = 5, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR1, - .enable_shift = CCM_PCCR1_UART6_OFFSET, - .disable = _clk_disable, - }, -}; - -static struct clk gpt1_clk[] = { - { - .name = "gpt_clk", - .id = 0, - .parent = &per_clk[0], - .secondary = &gpt1_clk[1], - }, { - .name = "gpt_ipg_clk", - .id = 0, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR0, - .enable_shift = CCM_PCCR0_GPT1_OFFSET, - .disable = _clk_disable, - }, -}; - -static struct clk gpt2_clk[] = { - { - .name = "gpt_clk", - .id = 1, - .parent = &per_clk[0], - .secondary = &gpt2_clk[1], - }, { - .name = "gpt_ipg_clk", - .id = 1, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR0, - .enable_shift = CCM_PCCR0_GPT2_OFFSET, - .disable = _clk_disable, - }, -}; - -static struct clk gpt3_clk[] = { - { - .name = "gpt_clk", - .id = 2, - .parent = &per_clk[0], - .secondary = &gpt3_clk[1], - }, { - .name = "gpt_ipg_clk", - .id = 2, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR0, - .enable_shift = CCM_PCCR0_GPT3_OFFSET, - .disable = _clk_disable, - }, -}; - -static struct clk gpt4_clk[] = { - { - .name = "gpt_clk", - .id = 3, - .parent = &per_clk[0], - .secondary = &gpt4_clk[1], - }, { - .name = "gpt_ipg_clk", - .id = 3, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR0, - .enable_shift = CCM_PCCR0_GPT4_OFFSET, - .disable = _clk_disable, - }, -}; - -static struct clk gpt5_clk[] = { - { - .name = "gpt_clk", - .id = 4, - .parent = &per_clk[0], - .secondary = &gpt5_clk[1], - }, { - .name = "gpt_ipg_clk", - .id = 4, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR0, - .enable_shift = CCM_PCCR0_GPT5_OFFSET, - .disable = _clk_disable, - }, +/* + * the high frequency external clock reference + * Default case is 26MHz. Could be changed at runtime + * with a call to change_external_high_reference() + */ +static struct clk ckih_clk = { + .get_rate = get_rate_high_reference, }; -static struct clk gpt6_clk[] = { - { - .name = "gpt_clk", - .id = 5, - .parent = &per_clk[0], - .secondary = &gpt6_clk[1], - }, { - .name = "gpt_ipg_clk", - .id = 5, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR0, - .enable_shift = CCM_PCCR0_GPT6_OFFSET, - .disable = _clk_disable, - }, +static struct clk mpll_clk = { + .parent = &ckih_clk, + .get_rate = get_rate_mpll, }; -static struct clk pwm_clk[] = { - { - .name = "pwm_clk", - .parent = &per_clk[0], - .secondary = &pwm_clk[1], - }, { - .name = "pwm_clk", - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR0, - .enable_shift = CCM_PCCR0_PWM_OFFSET, - .disable = _clk_disable, - }, +/* For i.MX27 TO2, it is the MPLL path 1 of ARM core + * It provides the clock source whose rate is same as MPLL + */ +static struct clk mpll_main1_clk = { + .id = 0, + .parent = &mpll_clk, + .get_rate = get_rate_mpll_main, }; -static struct clk sdhc1_clk[] = { - { - .name = "sdhc_clk", - .id = 0, - .parent = &per_clk[1], - .secondary = &sdhc1_clk[1], - }, { - .name = "sdhc_ipg_clk", - .id = 0, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR0, - .enable_shift = CCM_PCCR0_SDHC1_OFFSET, - .disable = _clk_disable, - }, +/* For i.MX27 TO2, it is the MPLL path 2 of ARM core + * It provides the clock source whose rate is same MPLL * 2 / 3 + */ +static struct clk mpll_main2_clk = { + .id = 1, + .parent = &mpll_clk, + .get_rate = get_rate_mpll_main, }; -static struct clk sdhc2_clk[] = { - { - .name = "sdhc_clk", - .id = 1, - .parent = &per_clk[1], - .secondary = &sdhc2_clk[1], - }, { - .name = "sdhc_ipg_clk", - .id = 1, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR0, - .enable_shift = CCM_PCCR0_SDHC2_OFFSET, - .disable = _clk_disable, - }, +static struct clk ahb_clk = { + .parent = &mpll_main2_clk, + .get_rate = get_rate_ahb, }; -static struct clk sdhc3_clk[] = { - { - .name = "sdhc_clk", - .id = 2, - .parent = &per_clk[1], - .secondary = &sdhc3_clk[1], - }, { - .name = "sdhc_ipg_clk", - .id = 2, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR0, - .enable_shift = CCM_PCCR0_SDHC3_OFFSET, - .disable = _clk_disable, - }, +static struct clk ipg_clk = { + .parent = &ahb_clk, + .get_rate = get_rate_ipg, }; -static struct clk cspi1_clk[] = { - { - .name = "cspi_clk", - .id = 0, - .parent = &per_clk[1], - .secondary = &cspi1_clk[1], - }, { - .name = "cspi_ipg_clk", - .id = 0, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR0, - .enable_shift = CCM_PCCR0_CSPI1_OFFSET, - .disable = _clk_disable, - }, +static struct clk cpu_clk = { + .parent = &mpll_main2_clk, + .set_parent = clk_cpu_set_parent, + .round_rate = round_rate_cpu, + .get_rate = get_rate_cpu, + .set_rate = set_rate_cpu, }; -static struct clk cspi2_clk[] = { - { - .name = "cspi_clk", - .id = 1, - .parent = &per_clk[1], - .secondary = &cspi2_clk[1], - }, { - .name = "cspi_ipg_clk", - .id = 1, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR0, - .enable_shift = CCM_PCCR0_CSPI2_OFFSET, - .disable = _clk_disable, - }, +static struct clk spll_clk = { + .parent = &ckih_clk, + .get_rate = get_rate_spll, + .enable = clk_spll_enable, + .disable = clk_spll_disable, }; -static struct clk cspi3_clk[] = { - { - .name = "cspi_clk", - .id = 2, - .parent = &per_clk[1], - .secondary = &cspi3_clk[1], - }, { - .name = "cspi_ipg_clk", - .id = 2, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR0, - .enable_shift = CCM_PCCR0_CSPI3_OFFSET, - .disable = _clk_disable, - }, +/* + * the low frequency external clock reference + * Default case is 32.768kHz. + */ +static struct clk ckil_clk = { + .get_rate = get_rate_low_reference, }; -static struct clk lcdc_clk[] = { - { - .name = "lcdc_clk", - .parent = &per_clk[2], - .secondary = &lcdc_clk[1], - .round_rate = _clk_parent_round_rate, - .set_rate = _clk_parent_set_rate, - }, { - .name = "lcdc_ipg_clk", - .parent = &ipg_clk, - .secondary = &lcdc_clk[2], - .enable = _clk_enable, - .enable_reg = CCM_PCCR0, - .enable_shift = CCM_PCCR0_LCDC_OFFSET, - .disable = _clk_disable, - }, { - .name = "lcdc_ahb_clk", - .parent = &ahb_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR1, - .enable_shift = CCM_PCCR1_HCLK_LCDC_OFFSET, - .disable = _clk_disable, - }, +/* Output of frequency pre multiplier */ +static struct clk fpm_clk = { + .parent = &ckil_clk, + .get_rate = get_rate_fpm, }; -static struct clk csi_clk[] = { - { - .name = "csi_perclk", - .parent = &per_clk[3], - .secondary = &csi_clk[1], - .round_rate = _clk_parent_round_rate, - .set_rate = _clk_parent_set_rate, - }, { - .name = "csi_ahb_clk", - .parent = &ahb_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR1, - .enable_shift = CCM_PCCR1_HCLK_CSI_OFFSET, - .disable = _clk_disable, - }, -}; +#define PCCR0 CCM_PCCR0 +#define PCCR1 CCM_PCCR1 -static struct clk usb_clk[] = { - { - .name = "usb_clk", - .parent = &spll_clk, - .get_rate = _clk_usb_recalc, - .enable = _clk_enable, - .enable_reg = CCM_PCCR1, - .enable_shift = CCM_PCCR1_USBOTG_OFFSET, - .disable = _clk_disable, - }, { - .name = "usb_ahb_clk", - .parent = &ahb_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR1, - .enable_shift = CCM_PCCR1_HCLK_USBOTG_OFFSET, - .disable = _clk_disable, +#define DEFINE_CLOCK(name, i, er, es, gr, s, p) \ + static struct clk name = { \ + .id = i, \ + .enable_reg = er, \ + .enable_shift = es, \ + .get_rate = gr, \ + .enable = clk_pccr_enable, \ + .disable = clk_pccr_disable, \ + .secondary = s, \ + .parent = p, \ } -}; - -static struct clk ssi1_clk[] = { - { - .name = "ssi_clk", - .id = 0, - .parent = &mpll_main_clk[1], - .secondary = &ssi1_clk[1], - .get_rate = _clk_ssi1_recalc, - .enable = _clk_enable, - .enable_reg = CCM_PCCR1, - .enable_shift = CCM_PCCR1_SSI1_BAUD_OFFSET, - .disable = _clk_disable, - }, { - .name = "ssi_ipg_clk", - .id = 0, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR0, - .enable_shift = CCM_PCCR0_SSI1_IPG_OFFSET, - .disable = _clk_disable, - }, -}; - -static struct clk ssi2_clk[] = { - { - .name = "ssi_clk", - .id = 1, - .parent = &mpll_main_clk[1], - .secondary = &ssi2_clk[1], - .get_rate = _clk_ssi2_recalc, - .enable = _clk_enable, - .enable_reg = CCM_PCCR1, - .enable_shift = CCM_PCCR1_SSI2_BAUD_OFFSET, - .disable = _clk_disable, - }, { - .name = "ssi_ipg_clk", - .id = 1, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR0, - .enable_shift = CCM_PCCR0_SSI2_IPG_OFFSET, - .disable = _clk_disable, - }, -}; - -static struct clk nfc_clk = { - .name = "nfc", - .parent = &cpu_clk, - .get_rate = _clk_nfc_recalc, - .enable = _clk_enable, - .enable_reg = CCM_PCCR1, - .enable_shift = CCM_PCCR1_NFC_BAUD_OFFSET, - .disable = _clk_disable, -}; - -static struct clk vpu_clk = { - .name = "vpu_clk", - .parent = &mpll_main_clk[1], - .get_rate = _clk_vpu_recalc, - .enable = _clk_vpu_enable, - .disable = _clk_vpu_disable, -}; - -static struct clk dma_clk = { - .name = "dma", - .parent = &ahb_clk, - .enable = _clk_dma_enable, - .disable = _clk_dma_disable, -}; - -static struct clk rtic_clk = { - .name = "rtic_clk", - .parent = &ahb_clk, - .enable = _clk_rtic_enable, - .disable = _clk_rtic_disable, -}; -static struct clk brom_clk = { - .name = "brom_clk", - .parent = &ahb_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR1, - .enable_shift = CCM_PCCR1_HCLK_BROM_OFFSET, - .disable = _clk_disable, -}; - -static struct clk emma_clk = { - .name = "emma_clk", - .parent = &ahb_clk, - .enable = _clk_emma_enable, - .disable = _clk_emma_disable, -}; - -static struct clk slcdc_clk = { - .name = "slcdc_clk", - .parent = &ahb_clk, - .enable = _clk_slcdc_enable, - .disable = _clk_slcdc_disable, -}; - -static struct clk fec_clk = { - .name = "fec_clk", - .parent = &ahb_clk, - .enable = _clk_fec_enable, - .disable = _clk_fec_disable, -}; - -static struct clk emi_clk = { - .name = "emi_clk", - .parent = &ahb_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR1, - .enable_shift = CCM_PCCR1_HCLK_EMI_OFFSET, - .disable = _clk_disable, -}; - -static struct clk sahara2_clk = { - .name = "sahara_clk", - .parent = &ahb_clk, - .enable = _clk_sahara2_enable, - .disable = _clk_sahara2_disable, -}; - -static struct clk ata_clk = { - .name = "ata_clk", - .parent = &ahb_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR1, - .enable_shift = CCM_PCCR1_HCLK_ATA_OFFSET, - .disable = _clk_disable, -}; - -static struct clk mstick1_clk = { - .name = "mstick1_clk", - .parent = &ipg_clk, - .enable = _clk_mstick1_enable, - .disable = _clk_mstick1_disable, -}; - -static struct clk wdog_clk = { - .name = "wdog_clk", - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR1, - .enable_shift = CCM_PCCR1_WDT_OFFSET, - .disable = _clk_disable, -}; - -static struct clk gpio_clk = { - .name = "gpio_clk", - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR1, - .enable_shift = CCM_PCCR0_GPIO_OFFSET, - .disable = _clk_disable, -}; +#define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \ + static struct clk name = { \ + .id = i, \ + .enable_reg = er, \ + .enable_shift = es, \ + .get_rate = get_rate_##getsetround, \ + .set_rate = set_rate_##getsetround, \ + .round_rate = round_rate_##getsetround, \ + .enable = clk_pccr_enable, \ + .disable = clk_pccr_disable, \ + .secondary = s, \ + .parent = p, \ + } -static struct clk i2c_clk[] = { - { - .name = "i2c_clk", - .id = 0, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR0, - .enable_shift = CCM_PCCR0_I2C1_OFFSET, - .disable = _clk_disable, - }, { - .name = "i2c_clk", - .id = 1, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR0, - .enable_shift = CCM_PCCR0_I2C2_OFFSET, - .disable = _clk_disable, +/* Forward declaration to keep the following list in order */ +static struct clk slcdc_clk1, sahara2_clk1, rtic_clk1, fec_clk1, emma_clk1, + dma_clk1, lcdc_clk2, vpu_clk1; + +/* All clocks we can gate through PCCRx in the order of PCCRx bits */ +DEFINE_CLOCK(ssi2_clk1, 1, PCCR0, 0, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(ssi1_clk1, 0, PCCR0, 1, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(slcdc_clk, 0, PCCR0, 2, NULL, &slcdc_clk1, &ahb_clk); +DEFINE_CLOCK(sdhc3_clk1, 0, PCCR0, 3, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(sdhc2_clk1, 0, PCCR0, 4, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(sdhc1_clk1, 0, PCCR0, 5, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(scc_clk, 0, PCCR0, 6, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(sahara2_clk, 0, PCCR0, 7, NULL, &sahara2_clk1, &ahb_clk); +DEFINE_CLOCK(rtic_clk, 0, PCCR0, 8, NULL, &rtic_clk1, &ahb_clk); +DEFINE_CLOCK(rtc_clk, 0, PCCR0, 9, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(pwm_clk1, 0, PCCR0, 11, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(owire_clk, 0, PCCR0, 12, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(mstick_clk1, 0, PCCR0, 13, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(lcdc_clk1, 0, PCCR0, 14, NULL, &lcdc_clk2, &ipg_clk); +DEFINE_CLOCK(kpp_clk, 0, PCCR0, 15, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(iim_clk, 0, PCCR0, 16, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(i2c2_clk, 1, PCCR0, 17, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(i2c1_clk, 0, PCCR0, 18, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(gpt6_clk1, 0, PCCR0, 29, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(gpt5_clk1, 0, PCCR0, 20, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(gpt4_clk1, 0, PCCR0, 21, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(gpt3_clk1, 0, PCCR0, 22, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(gpt2_clk1, 0, PCCR0, 23, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(gpt1_clk1, 0, PCCR0, 24, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(gpio_clk, 0, PCCR0, 25, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(fec_clk, 0, PCCR0, 26, NULL, &fec_clk1, &ahb_clk); +DEFINE_CLOCK(emma_clk, 0, PCCR0, 27, NULL, &emma_clk1, &ahb_clk); +DEFINE_CLOCK(dma_clk, 0, PCCR0, 28, NULL, &dma_clk1, &ahb_clk); +DEFINE_CLOCK(cspi13_clk1, 0, PCCR0, 29, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(cspi2_clk1, 0, PCCR0, 30, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(cspi1_clk1, 0, PCCR0, 31, NULL, NULL, &ipg_clk); + +DEFINE_CLOCK(mstick_clk, 0, PCCR1, 2, NULL, &mstick_clk1, &ipg_clk); +DEFINE_CLOCK(nfc_clk, 0, PCCR1, 3, get_rate_nfc, NULL, &cpu_clk); +DEFINE_CLOCK(ssi2_clk, 1, PCCR1, 4, get_rate_ssi2, &ssi2_clk1, &mpll_main2_clk); +DEFINE_CLOCK(ssi1_clk, 0, PCCR1, 5, get_rate_ssi1, &ssi1_clk1, &mpll_main2_clk); +DEFINE_CLOCK(vpu_clk, 0, PCCR1, 6, get_rate_vpu, &vpu_clk1, &mpll_main2_clk); +DEFINE_CLOCK1(per4_clk, 3, PCCR1, 7, per, NULL, &mpll_main2_clk); +DEFINE_CLOCK1(per3_clk, 2, PCCR1, 8, per, NULL, &mpll_main2_clk); +DEFINE_CLOCK1(per2_clk, 1, PCCR1, 9, per, NULL, &mpll_main2_clk); +DEFINE_CLOCK1(per1_clk, 0, PCCR1, 10, per, NULL, &mpll_main2_clk); +DEFINE_CLOCK(usb_clk1, 0, PCCR1, 11, NULL, NULL, &ahb_clk); +DEFINE_CLOCK(slcdc_clk1, 0, PCCR1, 12, NULL, NULL, &ahb_clk); +DEFINE_CLOCK(sahara2_clk1, 0, PCCR1, 13, NULL, NULL, &ahb_clk); +DEFINE_CLOCK(rtic_clk1, 0, PCCR1, 14, NULL, NULL, &ahb_clk); +DEFINE_CLOCK(lcdc_clk2, 0, PCCR1, 15, NULL, NULL, &ahb_clk); +DEFINE_CLOCK(vpu_clk1, 0, PCCR1, 16, NULL, NULL, &ahb_clk); +DEFINE_CLOCK(fec_clk1, 0, PCCR1, 17, NULL, NULL, &ahb_clk); +DEFINE_CLOCK(emma_clk1, 0, PCCR1, 18, NULL, NULL, &ahb_clk); +DEFINE_CLOCK(emi_clk, 0, PCCR1, 19, NULL, NULL, &ahb_clk); +DEFINE_CLOCK(dma_clk1, 0, PCCR1, 20, NULL, NULL, &ahb_clk); +DEFINE_CLOCK(csi_clk1, 0, PCCR1, 21, NULL, NULL, &ahb_clk); +DEFINE_CLOCK(brom_clk, 0, PCCR1, 22, NULL, NULL, &ahb_clk); +DEFINE_CLOCK(ata_clk, 0, PCCR1, 23, NULL, NULL, &ahb_clk); +DEFINE_CLOCK(wdog_clk, 0, PCCR1, 24, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(usb_clk, 0, PCCR1, 25, get_rate_usb, &usb_clk1, &spll_clk); +DEFINE_CLOCK(uart6_clk1, 0, PCCR1, 26, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(uart5_clk1, 0, PCCR1, 27, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(uart4_clk1, 0, PCCR1, 28, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(uart3_clk1, 0, PCCR1, 29, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(uart2_clk1, 0, PCCR1, 30, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(uart1_clk1, 0, PCCR1, 31, NULL, NULL, &ipg_clk); + +/* Clocks we cannot directly gate, but drivers need their rates */ +DEFINE_CLOCK(cspi1_clk, 0, 0, 0, NULL, &cspi1_clk1, &per2_clk); +DEFINE_CLOCK(cspi2_clk, 1, 0, 0, NULL, &cspi2_clk1, &per2_clk); +DEFINE_CLOCK(cspi3_clk, 2, 0, 0, NULL, &cspi13_clk1, &per2_clk); +DEFINE_CLOCK(sdhc1_clk, 0, 0, 0, NULL, &sdhc1_clk1, &per2_clk); +DEFINE_CLOCK(sdhc2_clk, 1, 0, 0, NULL, &sdhc2_clk1, &per2_clk); +DEFINE_CLOCK(sdhc3_clk, 2, 0, 0, NULL, &sdhc3_clk1, &per2_clk); +DEFINE_CLOCK(pwm_clk, 0, 0, 0, NULL, &pwm_clk1, &per1_clk); +DEFINE_CLOCK(gpt1_clk, 0, 0, 0, NULL, &gpt1_clk1, &per1_clk); +DEFINE_CLOCK(gpt2_clk, 1, 0, 0, NULL, &gpt2_clk1, &per1_clk); +DEFINE_CLOCK(gpt3_clk, 2, 0, 0, NULL, &gpt3_clk1, &per1_clk); +DEFINE_CLOCK(gpt4_clk, 3, 0, 0, NULL, &gpt4_clk1, &per1_clk); +DEFINE_CLOCK(gpt5_clk, 4, 0, 0, NULL, &gpt5_clk1, &per1_clk); +DEFINE_CLOCK(gpt6_clk, 5, 0, 0, NULL, &gpt6_clk1, &per1_clk); +DEFINE_CLOCK(uart1_clk, 0, 0, 0, NULL, &uart1_clk1, &per1_clk); +DEFINE_CLOCK(uart2_clk, 1, 0, 0, NULL, &uart2_clk1, &per1_clk); +DEFINE_CLOCK(uart3_clk, 2, 0, 0, NULL, &uart3_clk1, &per1_clk); +DEFINE_CLOCK(uart4_clk, 3, 0, 0, NULL, &uart4_clk1, &per1_clk); +DEFINE_CLOCK(uart5_clk, 4, 0, 0, NULL, &uart5_clk1, &per1_clk); +DEFINE_CLOCK(uart6_clk, 5, 0, 0, NULL, &uart6_clk1, &per1_clk); +DEFINE_CLOCK1(lcdc_clk, 0, 0, 0, parent, &lcdc_clk1, &per3_clk); +DEFINE_CLOCK1(csi_clk, 0, 0, 0, parent, &csi_clk1, &per4_clk); + +#define _REGISTER_CLOCK(d, n, c) \ + { \ + .dev_id = d, \ + .con_id = n, \ + .clk = &c, \ }, -}; -static struct clk iim_clk = { - .name = "iim_clk", - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR0, - .enable_shift = CCM_PCCR0_IIM_OFFSET, - .disable = _clk_disable, -}; - -static struct clk kpp_clk = { - .name = "kpp_clk", - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR0, - .enable_shift = CCM_PCCR0_KPP_OFFSET, - .disable = _clk_disable, -}; - -static struct clk owire_clk = { - .name = "owire", - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR0, - .enable_shift = CCM_PCCR0_OWIRE_OFFSET, - .disable = _clk_disable, -}; - -static struct clk rtc_clk = { - .name = "rtc_clk", - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR0, - .enable_shift = CCM_PCCR0_RTC_OFFSET, - .disable = _clk_disable, -}; - -static struct clk scc_clk = { - .name = "scc_clk", - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = CCM_PCCR0, - .enable_shift = CCM_PCCR0_SCC_OFFSET, - .disable = _clk_disable, -}; - -static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate) -{ - u32 div; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - div = parent_rate / rate; - if (parent_rate % rate) - div++; - - if (div > 8) - div = 8; - - return parent_rate / div; -} - -static int _clk_clko_set_rate(struct clk *clk, unsigned long rate) -{ - u32 reg; - u32 div; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - div = parent_rate / rate; - - if (div > 8 || div < 1 || ((parent_rate / div) != rate)) - return -EINVAL; - div--; - - reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKODIV_MASK; - reg |= div << CCM_PCDR0_CLKODIV_OFFSET; - __raw_writel(reg, CCM_PCDR0); - - return 0; -} - -static unsigned long _clk_clko_recalc(struct clk *clk) -{ - u32 div; - unsigned long parent_rate; - - parent_rate = clk_get_rate(clk->parent); - - div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_CLKODIV_MASK >> - CCM_PCDR0_CLKODIV_OFFSET; - div++; - - return parent_rate / div; -} - -static int _clk_clko_set_parent(struct clk *clk, struct clk *parent) -{ - u32 reg; - - reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK; - - if (parent == &ckil_clk) - reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &ckih_clk) - reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == mpll_clk.parent) - reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == spll_clk.parent) - reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &mpll_clk) - reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &spll_clk) - reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &cpu_clk) - reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &ahb_clk) - reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &ipg_clk) - reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &per_clk[0]) - reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &per_clk[1]) - reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &per_clk[2]) - reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &per_clk[3]) - reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &ssi1_clk[0]) - reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &ssi2_clk[0]) - reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &nfc_clk) - reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &mstick1_clk) - reg |= 0x11 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &vpu_clk) - reg |= 0x12 << CCM_CCSR_CLKOSEL_OFFSET; - else if (parent == &usb_clk[0]) - reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET; - else - return -EINVAL; - - __raw_writel(reg, CCM_CCSR); - - return 0; -} - -static int _clk_clko_enable(struct clk *clk) -{ - u32 reg; - - reg = __raw_readl(CCM_PCDR0) | CCM_PCDR0_CLKO_EN; - __raw_writel(reg, CCM_PCDR0); - - return 0; -} - -static void _clk_clko_disable(struct clk *clk) -{ - u32 reg; - - reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKO_EN; - __raw_writel(reg, CCM_PCDR0); -} - -static struct clk clko_clk = { - .name = "clko_clk", - .get_rate = _clk_clko_recalc, - .set_rate = _clk_clko_set_rate, - .round_rate = _clk_clko_round_rate, - .set_parent = _clk_clko_set_parent, - .enable = _clk_clko_enable, - .disable = _clk_clko_disable, -}; - -static struct clk *mxc_clks[] = { - &ckih_clk, - &ckil_clk, - &mpll_clk, - &mpll_main_clk[0], - &mpll_main_clk[1], - &spll_clk, - &cpu_clk, - &ahb_clk, - &ipg_clk, - &per_clk[0], - &per_clk[1], - &per_clk[2], - &per_clk[3], - &clko_clk, - &uart1_clk[0], - &uart1_clk[1], - &uart2_clk[0], - &uart2_clk[1], - &uart3_clk[0], - &uart3_clk[1], - &uart4_clk[0], - &uart4_clk[1], - &uart5_clk[0], - &uart5_clk[1], - &uart6_clk[0], - &uart6_clk[1], - &gpt1_clk[0], - &gpt1_clk[1], - &gpt2_clk[0], - &gpt2_clk[1], - &gpt3_clk[0], - &gpt3_clk[1], - &gpt4_clk[0], - &gpt4_clk[1], - &gpt5_clk[0], - &gpt5_clk[1], - &gpt6_clk[0], - &gpt6_clk[1], - &pwm_clk[0], - &pwm_clk[1], - &sdhc1_clk[0], - &sdhc1_clk[1], - &sdhc2_clk[0], - &sdhc2_clk[1], - &sdhc3_clk[0], - &sdhc3_clk[1], - &cspi1_clk[0], - &cspi1_clk[1], - &cspi2_clk[0], - &cspi2_clk[1], - &cspi3_clk[0], - &cspi3_clk[1], - &lcdc_clk[0], - &lcdc_clk[1], - &lcdc_clk[2], - &csi_clk[0], - &csi_clk[1], - &usb_clk[0], - &usb_clk[1], - &ssi1_clk[0], - &ssi1_clk[1], - &ssi2_clk[0], - &ssi2_clk[1], - &nfc_clk, - &vpu_clk, - &dma_clk, - &rtic_clk, - &brom_clk, - &emma_clk, - &slcdc_clk, - &fec_clk, - &emi_clk, - &sahara2_clk, - &ata_clk, - &mstick1_clk, - &wdog_clk, - &gpio_clk, - &i2c_clk[0], - &i2c_clk[1], - &iim_clk, - &kpp_clk, - &owire_clk, - &rtc_clk, - &scc_clk, -}; - -void __init change_external_low_reference(unsigned long new_ref) -{ - external_low_reference = new_ref; -} - -unsigned long __init clk_early_get_timer_rate(void) -{ - return clk_get_rate(&per_clk[0]); -} - -static void __init probe_mxc_clocks(void) -{ - int i; +static struct clk_lookup lookups[] __initdata = { + _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) + _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) + _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) + _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk) + _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk) + _REGISTER_CLOCK("imx-uart.5", NULL, uart6_clk) + _REGISTER_CLOCK(NULL, "gpt1", gpt1_clk) + _REGISTER_CLOCK(NULL, "gpt2", gpt2_clk) + _REGISTER_CLOCK(NULL, "gpt3", gpt3_clk) + _REGISTER_CLOCK(NULL, "gpt4", gpt4_clk) + _REGISTER_CLOCK(NULL, "gpt5", gpt5_clk) + _REGISTER_CLOCK(NULL, "gpt6", gpt6_clk) + _REGISTER_CLOCK("mxc_pwm.0", NULL, pwm_clk) + _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk) + _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk) + _REGISTER_CLOCK("mxc-mmc.2", NULL, sdhc3_clk) + _REGISTER_CLOCK(NULL, "cspi1", cspi1_clk) + _REGISTER_CLOCK(NULL, "cspi2", cspi2_clk) + _REGISTER_CLOCK(NULL, "cspi3", cspi3_clk) + _REGISTER_CLOCK("imx-fb.0", NULL, lcdc_clk) + _REGISTER_CLOCK(NULL, "csi", csi_clk) + _REGISTER_CLOCK(NULL, "usb", usb_clk) + _REGISTER_CLOCK(NULL, "ssi1", ssi1_clk) + _REGISTER_CLOCK(NULL, "ssi2", ssi2_clk) + _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) + _REGISTER_CLOCK(NULL, "vpu", vpu_clk) + _REGISTER_CLOCK(NULL, "dma", dma_clk) + _REGISTER_CLOCK(NULL, "rtic", rtic_clk) + _REGISTER_CLOCK(NULL, "brom", brom_clk) + _REGISTER_CLOCK(NULL, "emma", emma_clk) + _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk) + _REGISTER_CLOCK("fec.0", NULL, fec_clk) + _REGISTER_CLOCK(NULL, "emi", emi_clk) + _REGISTER_CLOCK(NULL, "sahara2", sahara2_clk) + _REGISTER_CLOCK(NULL, "ata", ata_clk) + _REGISTER_CLOCK(NULL, "mstick", mstick_clk) + _REGISTER_CLOCK(NULL, "wdog", wdog_clk) + _REGISTER_CLOCK(NULL, "gpio", gpio_clk) + _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) + _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) + _REGISTER_CLOCK(NULL, "iim", iim_clk) + _REGISTER_CLOCK(NULL, "kpp", kpp_clk) + _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk) + _REGISTER_CLOCK(NULL, "rtc", rtc_clk) + _REGISTER_CLOCK(NULL, "scc", scc_clk) +}; + +/* Adjust the clock path for TO2 and later */ +static void __init to2_adjust_clocks(void) +{ + unsigned long cscr = __raw_readl(CCM_CSCR); if (mx27_revision() >= CHIP_REV_2_0) { - if (CSCR() & 0x8000) - cpu_clk.parent = &mpll_main_clk[0]; + if (cscr & CCM_CSCR_ARM_SRC) + cpu_clk.parent = &mpll_main1_clk; - if (!(CSCR() & 0x00800000)) - ssi2_clk[0].parent = &spll_clk; + if (!(cscr & CCM_CSCR_SSI2)) + ssi1_clk.parent = &spll_clk; - if (!(CSCR() & 0x00400000)) - ssi1_clk[0].parent = &spll_clk; + if (!(cscr & CCM_CSCR_SSI1)) + ssi1_clk.parent = &spll_clk; - if (!(CSCR() & 0x00200000)) + if (!(cscr & CCM_CSCR_VPU)) vpu_clk.parent = &spll_clk; } else { cpu_clk.parent = &mpll_clk; @@ -1537,11 +693,13 @@ static void __init probe_mxc_clocks(void) cpu_clk.set_rate = NULL; ahb_clk.parent = &mpll_clk; - for (i = 0; i < sizeof(per_clk) / sizeof(per_clk[0]); i++) - per_clk[i].parent = &mpll_clk; + per1_clk.parent = &mpll_clk; + per2_clk.parent = &mpll_clk; + per3_clk.parent = &mpll_clk; + per4_clk.parent = &mpll_clk; - ssi1_clk[0].parent = &mpll_clk; - ssi2_clk[0].parent = &mpll_clk; + ssi1_clk.parent = &mpll_clk; + ssi2_clk.parent = &mpll_clk; vpu_clk.parent = &mpll_clk; } @@ -1553,48 +711,45 @@ static void __init probe_mxc_clocks(void) */ int __init mx27_clocks_init(unsigned long fref) { - u32 cscr; - struct clk **clkp; + u32 cscr = __raw_readl(CCM_CSCR); + int i; external_high_reference = fref; - /* detect clock reference for both system PLL */ - cscr = CSCR(); + /* detect clock reference for both system PLLs */ if (cscr & CCM_CSCR_MCU) mpll_clk.parent = &ckih_clk; else - mpll_clk.parent = &ckil_clk; + mpll_clk.parent = &fpm_clk; if (cscr & CCM_CSCR_SP) spll_clk.parent = &ckih_clk; else - spll_clk.parent = &ckil_clk; + spll_clk.parent = &fpm_clk; - probe_mxc_clocks(); + to2_adjust_clocks(); - per_clk[0].enable(&per_clk[0]); - gpt1_clk[1].enable(&gpt1_clk[1]); + for (i = 0; i < ARRAY_SIZE(lookups); i++) + clkdev_add(&lookups[i]); - for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++) - clk_register(*clkp); + /* Turn off all clocks we do not need */ + __raw_writel(0, CCM_PCCR0); + __raw_writel((1 << 10) | (1 << 19), CCM_PCCR1); - /* Turn off all possible clocks */ - __raw_writel(CCM_PCCR0_GPT1_MASK, CCM_PCCR0); - __raw_writel(CCM_PCCR1_PERCLK1_MASK | CCM_PCCR1_HCLK_EMI_MASK, - CCM_PCCR1); spll_clk.disable(&spll_clk); - /* This will propagate to all children and init all the clock rates */ - - clk_enable(&emi_clk); + /* enable basic clocks */ + clk_enable(&per1_clk); clk_enable(&gpio_clk); + clk_enable(&emi_clk); clk_enable(&iim_clk); - clk_enable(&gpt1_clk[0]); + #ifdef CONFIG_DEBUG_LL_CONSOLE - clk_enable(&uart1_clk[0]); + clk_enable(&uart1_clk); #endif - mxc_timer_init(&gpt1_clk[0]); + mxc_timer_init(&gpt1_clk); return 0; } + diff --git a/arch/arm/mach-mx2/cpu_imx27.c b/arch/arm/mach-mx2/cpu_imx27.c index 239308fe6652..d9e3bf9644c9 100644 --- a/arch/arm/mach-mx2/cpu_imx27.c +++ b/arch/arm/mach-mx2/cpu_imx27.c @@ -26,11 +26,11 @@ #include -#include "crm_regs.h" - static int cpu_silicon_rev = -1; static int cpu_partnumber; +#define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */ + static void query_silicon_parameter(void) { u32 val; diff --git a/arch/arm/mach-mx2/crm_regs.h b/arch/arm/mach-mx2/crm_regs.h deleted file mode 100644 index 94644cd0a0fc..000000000000 --- a/arch/arm/mach-mx2/crm_regs.h +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright 2008 Juergen Beisert, kernel@pengutronix.de - * - * 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. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, - * MA 02110-1301, USA. - */ - -#ifndef __ARCH_ARM_MACH_MX2_CRM_REGS_H__ -#define __ARCH_ARM_MACH_MX2_CRM_REGS_H__ - -#include - -/* Register offsets */ -#define CCM_CSCR (IO_ADDRESS(CCM_BASE_ADDR) + 0x0) -#define CCM_MPCTL0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x4) -#define CCM_MPCTL1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x8) -#define CCM_SPCTL0 (IO_ADDRESS(CCM_BASE_ADDR) + 0xC) -#define CCM_SPCTL1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x10) -#define CCM_OSC26MCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x14) -#define CCM_PCDR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x18) -#define CCM_PCDR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x1c) -#define CCM_PCCR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x20) -#define CCM_PCCR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x24) -#define CCM_CCSR (IO_ADDRESS(CCM_BASE_ADDR) + 0x28) -#define CCM_PMCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x2c) -#define CCM_PMCOUNT (IO_ADDRESS(CCM_BASE_ADDR) + 0x30) -#define CCM_WKGDCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x34) - -#define CCM_CSCR_USB_OFFSET 28 -#define CCM_CSCR_USB_MASK (0x7 << 28) -#define CCM_CSCR_SD_OFFSET 24 -#define CCM_CSCR_SD_MASK (0x3 << 24) -#define CCM_CSCR_SSI2 (1 << 23) -#define CCM_CSCR_SSI2_OFFSET 23 -#define CCM_CSCR_SSI1 (1 << 22) -#define CCM_CSCR_SSI1_OFFSET 22 -#define CCM_CSCR_VPU (1 << 21) -#define CCM_CSCR_VPU_OFFSET 21 -#define CCM_CSCR_MSHC (1 << 20) -#define CCM_CSCR_SPLLRES (1 << 19) -#define CCM_CSCR_MPLLRES (1 << 18) -#define CCM_CSCR_SP (1 << 17) -#define CCM_CSCR_MCU (1 << 16) -/* CCM_CSCR_ARM_xxx just be avaliable on i.MX27 TO2*/ -#define CCM_CSCR_ARM_SRC (1 << 15) -#define CCM_CSCR_ARM_OFFSET 12 -#define CCM_CSCR_ARM_MASK (0x3 << 12) -/* CCM_CSCR_ARM_xxx just be avaliable on i.MX27 TO2*/ -#define CCM_CSCR_PRESC_OFFSET 13 -#define CCM_CSCR_PRESC_MASK (0x7 << 13) -#define CCM_CSCR_BCLK_OFFSET 9 -#define CCM_CSCR_BCLK_MASK (0xf << 9) -#define CCM_CSCR_IPDIV_OFFSET 8 -#define CCM_CSCR_IPDIV (1 << 8) -/* CCM_CSCR_AHB_xxx just be avaliable on i.MX27 TO2*/ -#define CCM_CSCR_AHB_OFFSET 8 -#define CCM_CSCR_AHB_MASK (0x3 << 8) -/* CCM_CSCR_AHB_xxx just be avaliable on i.MX27 TO2*/ -#define CCM_CSCR_OSC26MDIV (1 << 4) -#define CCM_CSCR_OSC26M (1 << 3) -#define CCM_CSCR_FPM (1 << 2) -#define CCM_CSCR_SPEN (1 << 1) -#define CCM_CSCR_MPEN 1 - -#define CCM_MPCTL0_CPLM (1 << 31) -#define CCM_MPCTL0_PD_OFFSET 26 -#define CCM_MPCTL0_PD_MASK (0xf << 26) -#define CCM_MPCTL0_MFD_OFFSET 16 -#define CCM_MPCTL0_MFD_MASK (0x3ff << 16) -#define CCM_MPCTL0_MFI_OFFSET 10 -#define CCM_MPCTL0_MFI_MASK (0xf << 10) -#define CCM_MPCTL0_MFN_OFFSET 0 -#define CCM_MPCTL0_MFN_MASK 0x3ff - -#define CCM_MPCTL1_LF (1 << 15) -#define CCM_MPCTL1_BRMO (1 << 6) - -#define CCM_SPCTL0_CPLM (1 << 31) -#define CCM_SPCTL0_PD_OFFSET 26 -#define CCM_SPCTL0_PD_MASK (0xf << 26) -#define CCM_SPCTL0_MFD_OFFSET 16 -#define CCM_SPCTL0_MFD_MASK (0x3ff << 16) -#define CCM_SPCTL0_MFI_OFFSET 10 -#define CCM_SPCTL0_MFI_MASK (0xf << 10) -#define CCM_SPCTL0_MFN_OFFSET 0 -#define CCM_SPCTL0_MFN_MASK 0x3ff - -#define CCM_SPCTL1_LF (1 << 15) -#define CCM_SPCTL1_BRMO (1 << 6) - -#define CCM_OSC26MCTL_PEAK_OFFSET 16 -#define CCM_OSC26MCTL_PEAK_MASK (0x3 << 16) -#define CCM_OSC26MCTL_AGC_OFFSET 8 -#define CCM_OSC26MCTL_AGC_MASK (0x3f << 8) -#define CCM_OSC26MCTL_ANATEST_OFFSET 0 -#define CCM_OSC26MCTL_ANATEST_MASK 0x3f - -#define CCM_PCDR0_SSI2BAUDDIV_OFFSET 26 -#define CCM_PCDR0_SSI2BAUDDIV_MASK (0x3f << 26) -#define CCM_PCDR0_CLKO_EN 25 -#define CCM_PCDR0_CLKODIV_OFFSET 22 -#define CCM_PCDR0_CLKODIV_MASK (0x7 << 22) -#define CCM_PCDR0_SSI1BAUDDIV_OFFSET 16 -#define CCM_PCDR0_SSI1BAUDDIV_MASK (0x3f << 16) -/*The difinition for i.MX27 TO2*/ -#define CCM_PCDR0_VPUDIV2_OFFSET 10 -#define CCM_PCDR0_VPUDIV2_MASK (0x3f << 10) -#define CCM_PCDR0_NFCDIV2_OFFSET 6 -#define CCM_PCDR0_NFCDIV2_MASK (0xf << 6) -#define CCM_PCDR0_MSHCDIV2_MASK 0x3f -/*The difinition for i.MX27 TO2*/ -#define CCM_PCDR0_NFCDIV_OFFSET 12 -#define CCM_PCDR0_NFCDIV_MASK (0xf << 12) -#define CCM_PCDR0_VPUDIV_OFFSET 8 -#define CCM_PCDR0_VPUDIV_MASK (0xf << 8) -#define CCM_PCDR0_MSHCDIV_OFFSET 0 -#define CCM_PCDR0_MSHCDIV_MASK 0x1f - -#define CCM_PCDR1_PERDIV4_OFFSET 24 -#define CCM_PCDR1_PERDIV4_MASK (0x3f << 24) -#define CCM_PCDR1_PERDIV3_OFFSET 16 -#define CCM_PCDR1_PERDIV3_MASK (0x3f << 16) -#define CCM_PCDR1_PERDIV2_OFFSET 8 -#define CCM_PCDR1_PERDIV2_MASK (0x3f << 8) -#define CCM_PCDR1_PERDIV1_OFFSET 0 -#define CCM_PCDR1_PERDIV1_MASK 0x3f - -#define CCM_PCCR0_CSPI1_OFFSET 31 -#define CCM_PCCR0_CSPI1_MASK (1 << 31) -#define CCM_PCCR0_CSPI2_OFFSET 30 -#define CCM_PCCR0_CSPI2_MASK (1 << 30) -#define CCM_PCCR0_CSPI3_OFFSET 29 -#define CCM_PCCR0_CSPI3_MASK (1 << 29) -#define CCM_PCCR0_DMA_OFFSET 28 -#define CCM_PCCR0_DMA_MASK (1 << 28) -#define CCM_PCCR0_EMMA_OFFSET 27 -#define CCM_PCCR0_EMMA_MASK (1 << 27) -#define CCM_PCCR0_FEC_OFFSET 26 -#define CCM_PCCR0_FEC_MASK (1 << 26) -#define CCM_PCCR0_GPIO_OFFSET 25 -#define CCM_PCCR0_GPIO_MASK (1 << 25) -#define CCM_PCCR0_GPT1_OFFSET 24 -#define CCM_PCCR0_GPT1_MASK (1 << 24) -#define CCM_PCCR0_GPT2_OFFSET 23 -#define CCM_PCCR0_GPT2_MASK (1 << 23) -#define CCM_PCCR0_GPT3_OFFSET 22 -#define CCM_PCCR0_GPT3_MASK (1 << 22) -#define CCM_PCCR0_GPT4_OFFSET 21 -#define CCM_PCCR0_GPT4_MASK (1 << 21) -#define CCM_PCCR0_GPT5_OFFSET 20 -#define CCM_PCCR0_GPT5_MASK (1 << 20) -#define CCM_PCCR0_GPT6_OFFSET 19 -#define CCM_PCCR0_GPT6_MASK (1 << 19) -#define CCM_PCCR0_I2C1_OFFSET 18 -#define CCM_PCCR0_I2C1_MASK (1 << 18) -#define CCM_PCCR0_I2C2_OFFSET 17 -#define CCM_PCCR0_I2C2_MASK (1 << 17) -#define CCM_PCCR0_IIM_OFFSET 16 -#define CCM_PCCR0_IIM_MASK (1 << 16) -#define CCM_PCCR0_KPP_OFFSET 15 -#define CCM_PCCR0_KPP_MASK (1 << 15) -#define CCM_PCCR0_LCDC_OFFSET 14 -#define CCM_PCCR0_LCDC_MASK (1 << 14) -#define CCM_PCCR0_MSHC_OFFSET 13 -#define CCM_PCCR0_MSHC_MASK (1 << 13) -#define CCM_PCCR0_OWIRE_OFFSET 12 -#define CCM_PCCR0_OWIRE_MASK (1 << 12) -#define CCM_PCCR0_PWM_OFFSET 11 -#define CCM_PCCR0_PWM_MASK (1 << 11) -#define CCM_PCCR0_RTC_OFFSET 9 -#define CCM_PCCR0_RTC_MASK (1 << 9) -#define CCM_PCCR0_RTIC_OFFSET 8 -#define CCM_PCCR0_RTIC_MASK (1 << 8) -#define CCM_PCCR0_SAHARA_OFFSET 7 -#define CCM_PCCR0_SAHARA_MASK (1 << 7) -#define CCM_PCCR0_SCC_OFFSET 6 -#define CCM_PCCR0_SCC_MASK (1 << 6) -#define CCM_PCCR0_SDHC1_OFFSET 5 -#define CCM_PCCR0_SDHC1_MASK (1 << 5) -#define CCM_PCCR0_SDHC2_OFFSET 4 -#define CCM_PCCR0_SDHC2_MASK (1 << 4) -#define CCM_PCCR0_SDHC3_OFFSET 3 -#define CCM_PCCR0_SDHC3_MASK (1 << 3) -#define CCM_PCCR0_SLCDC_OFFSET 2 -#define CCM_PCCR0_SLCDC_MASK (1 << 2) -#define CCM_PCCR0_SSI1_IPG_OFFSET 1 -#define CCM_PCCR0_SSI1_IPG_MASK (1 << 1) -#define CCM_PCCR0_SSI2_IPG_OFFSET 0 -#define CCM_PCCR0_SSI2_IPG_MASK (1 << 0) - -#define CCM_PCCR1_UART1_OFFSET 31 -#define CCM_PCCR1_UART1_MASK (1 << 31) -#define CCM_PCCR1_UART2_OFFSET 30 -#define CCM_PCCR1_UART2_MASK (1 << 30) -#define CCM_PCCR1_UART3_OFFSET 29 -#define CCM_PCCR1_UART3_MASK (1 << 29) -#define CCM_PCCR1_UART4_OFFSET 28 -#define CCM_PCCR1_UART4_MASK (1 << 28) -#define CCM_PCCR1_UART5_OFFSET 27 -#define CCM_PCCR1_UART5_MASK (1 << 27) -#define CCM_PCCR1_UART6_OFFSET 26 -#define CCM_PCCR1_UART6_MASK (1 << 26) -#define CCM_PCCR1_USBOTG_OFFSET 25 -#define CCM_PCCR1_USBOTG_MASK (1 << 25) -#define CCM_PCCR1_WDT_OFFSET 24 -#define CCM_PCCR1_WDT_MASK (1 << 24) -#define CCM_PCCR1_HCLK_ATA_OFFSET 23 -#define CCM_PCCR1_HCLK_ATA_MASK (1 << 23) -#define CCM_PCCR1_HCLK_BROM_OFFSET 22 -#define CCM_PCCR1_HCLK_BROM_MASK (1 << 22) -#define CCM_PCCR1_HCLK_CSI_OFFSET 21 -#define CCM_PCCR1_HCLK_CSI_MASK (1 << 21) -#define CCM_PCCR1_HCLK_DMA_OFFSET 20 -#define CCM_PCCR1_HCLK_DMA_MASK (1 << 20) -#define CCM_PCCR1_HCLK_EMI_OFFSET 19 -#define CCM_PCCR1_HCLK_EMI_MASK (1 << 19) -#define CCM_PCCR1_HCLK_EMMA_OFFSET 18 -#define CCM_PCCR1_HCLK_EMMA_MASK (1 << 18) -#define CCM_PCCR1_HCLK_FEC_OFFSET 17 -#define CCM_PCCR1_HCLK_FEC_MASK (1 << 17) -#define CCM_PCCR1_HCLK_VPU_OFFSET 16 -#define CCM_PCCR1_HCLK_VPU_MASK (1 << 16) -#define CCM_PCCR1_HCLK_LCDC_OFFSET 15 -#define CCM_PCCR1_HCLK_LCDC_MASK (1 << 15) -#define CCM_PCCR1_HCLK_RTIC_OFFSET 14 -#define CCM_PCCR1_HCLK_RTIC_MASK (1 << 14) -#define CCM_PCCR1_HCLK_SAHARA_OFFSET 13 -#define CCM_PCCR1_HCLK_SAHARA_MASK (1 << 13) -#define CCM_PCCR1_HCLK_SLCDC_OFFSET 12 -#define CCM_PCCR1_HCLK_SLCDC_MASK (1 << 12) -#define CCM_PCCR1_HCLK_USBOTG_OFFSET 11 -#define CCM_PCCR1_HCLK_USBOTG_MASK (1 << 11) -#define CCM_PCCR1_PERCLK1_OFFSET 10 -#define CCM_PCCR1_PERCLK1_MASK (1 << 10) -#define CCM_PCCR1_PERCLK2_OFFSET 9 -#define CCM_PCCR1_PERCLK2_MASK (1 << 9) -#define CCM_PCCR1_PERCLK3_OFFSET 8 -#define CCM_PCCR1_PERCLK3_MASK (1 << 8) -#define CCM_PCCR1_PERCLK4_OFFSET 7 -#define CCM_PCCR1_PERCLK4_MASK (1 << 7) -#define CCM_PCCR1_VPU_BAUD_OFFSET 6 -#define CCM_PCCR1_VPU_BAUD_MASK (1 << 6) -#define CCM_PCCR1_SSI1_BAUD_OFFSET 5 -#define CCM_PCCR1_SSI1_BAUD_MASK (1 << 5) -#define CCM_PCCR1_SSI2_BAUD_OFFSET 4 -#define CCM_PCCR1_SSI2_BAUD_MASK (1 << 4) -#define CCM_PCCR1_NFC_BAUD_OFFSET 3 -#define CCM_PCCR1_NFC_BAUD_MASK (1 << 3) -#define CCM_PCCR1_MSHC_BAUD_OFFSET 2 -#define CCM_PCCR1_MSHC_BAUD_MASK (1 << 2) - -#define CCM_CCSR_32KSR (1 << 15) -#define CCM_CCSR_CLKMODE1 (1 << 9) -#define CCM_CCSR_CLKMODE0 (1 << 8) -#define CCM_CCSR_CLKOSEL_OFFSET 0 -#define CCM_CCSR_CLKOSEL_MASK 0x1f - -#define SYS_FMCR 0x14 /* Functional Muxing Control Reg */ -#define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */ - -#endif /* __ARCH_ARM_MACH_MX2_CRM_REGS_H__ */ diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig index 9cc2b16fdf79..10f65bf27b27 100644 --- a/arch/arm/plat-mxc/Kconfig +++ b/arch/arm/plat-mxc/Kconfig @@ -15,6 +15,7 @@ config ARCH_MX1 config ARCH_MX2 bool "MX2-based" select CPU_ARM926T + select COMMON_CLKDEV help This enables support for systems based on the Freescale i.MX2 family -- cgit v1.2.3 From 058b7a6f465bebd87c1f295afdd56cc6a33dffbd Mon Sep 17 00:00:00 2001 From: Holger Schurig Date: Mon, 26 Jan 2009 16:34:51 +0100 Subject: arm/imx2x: removes a bunch of sparse-warnings Here are some of the warnings that get fixed by this: > 200 times: warning: cast adds address space to expression () twelve times: warning: symbol 'xxx' was not declared. Should it be static two times: warning: symbol 'clock' shadows an earlier one five times: warning: incorrect type in initializer (different address spaces) Signed-off-by: Holger Schurig Signed-off-by: Sascha Hauer --- arch/arm/mach-mx2/devices.c | 15 +++++++++------ arch/arm/mach-mx2/generic.c | 1 + arch/arm/mach-mx2/mx27ads.c | 4 ++-- arch/arm/mach-mx2/pcm038.c | 2 +- arch/arm/mach-mx2/serial.c | 1 + arch/arm/plat-mxc/devices.c | 1 + arch/arm/plat-mxc/include/mach/board-mx27ads.h | 3 ++- arch/arm/plat-mxc/include/mach/mx27.h | 2 +- arch/arm/plat-mxc/time.c | 12 ++++-------- 9 files changed, 22 insertions(+), 19 deletions(-) (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/mach-mx2/devices.c b/arch/arm/mach-mx2/devices.c index 2f9240be1c76..9ddd6d061058 100644 --- a/arch/arm/mach-mx2/devices.c +++ b/arch/arm/mach-mx2/devices.c @@ -34,6 +34,9 @@ #include #include +#include + +#include "devices.h" /* * Resource definition for the MXC IrDA @@ -230,32 +233,32 @@ static struct mxc_gpio_port imx_gpio_ports[] = { [0] = { .chip.label = "gpio-0", .irq = MXC_INT_GPIO, - .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 0), + .base = IO_ADDRESS(GPIO_BASE_ADDR), .virtual_irq_start = MXC_GPIO_IRQ_START, }, [1] = { .chip.label = "gpio-1", - .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 1), + .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x100), .virtual_irq_start = MXC_GPIO_IRQ_START + 32, }, [2] = { .chip.label = "gpio-2", - .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 2), + .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x200), .virtual_irq_start = MXC_GPIO_IRQ_START + 64, }, [3] = { .chip.label = "gpio-3", - .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 3), + .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x300), .virtual_irq_start = MXC_GPIO_IRQ_START + 96, }, [4] = { .chip.label = "gpio-4", - .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 4), + .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x400), .virtual_irq_start = MXC_GPIO_IRQ_START + 128, }, [5] = { .chip.label = "gpio-5", - .base = (void*)(AIPI_BASE_ADDR_VIRT + 0x15000 + 0x100 * 5), + .base = IO_ADDRESS(GPIO_BASE_ADDR + 0x500), .virtual_irq_start = MXC_GPIO_IRQ_START + 160, } }; diff --git a/arch/arm/mach-mx2/generic.c b/arch/arm/mach-mx2/generic.c index dea6521d4d5c..bd51dd04948e 100644 --- a/arch/arm/mach-mx2/generic.c +++ b/arch/arm/mach-mx2/generic.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-mx2/mx27ads.c b/arch/arm/mach-mx2/mx27ads.c index 536bf64bc7c8..4548631eb3ae 100644 --- a/arch/arm/mach-mx2/mx27ads.c +++ b/arch/arm/mach-mx2/mx27ads.c @@ -266,7 +266,7 @@ static void __init mx27ads_timer_init(void) mx27_clocks_init(fref); } -struct sys_timer mx27ads_timer = { +static struct sys_timer mx27ads_timer = { .init = mx27ads_timer_init, }; @@ -279,7 +279,7 @@ static struct map_desc mx27ads_io_desc[] __initdata = { }, }; -void __init mx27ads_map_io(void) +static void __init mx27ads_map_io(void) { mxc_map_io(); iotable_init(mx27ads_io_desc, ARRAY_SIZE(mx27ads_io_desc)); diff --git a/arch/arm/mach-mx2/pcm038.c b/arch/arm/mach-mx2/pcm038.c index 63cdef8565db..2942d59b5709 100644 --- a/arch/arm/mach-mx2/pcm038.c +++ b/arch/arm/mach-mx2/pcm038.c @@ -233,7 +233,7 @@ static void __init pcm038_timer_init(void) mx27_clocks_init(26000000); } -struct sys_timer pcm038_timer = { +static struct sys_timer pcm038_timer = { .init = pcm038_timer_init, }; diff --git a/arch/arm/mach-mx2/serial.c b/arch/arm/mach-mx2/serial.c index b9e66fb11860..40a485cdc10e 100644 --- a/arch/arm/mach-mx2/serial.c +++ b/arch/arm/mach-mx2/serial.c @@ -22,6 +22,7 @@ #include #include #include +#include "devices.h" static struct resource uart0[] = { { diff --git a/arch/arm/plat-mxc/devices.c b/arch/arm/plat-mxc/devices.c index c66748267c45..56f2fb5cc456 100644 --- a/arch/arm/plat-mxc/devices.c +++ b/arch/arm/plat-mxc/devices.c @@ -19,6 +19,7 @@ #include #include #include +#include int __init mxc_register_device(struct platform_device *pdev, void *data) { diff --git a/arch/arm/plat-mxc/include/mach/board-mx27ads.h b/arch/arm/plat-mxc/include/mach/board-mx27ads.h index 8f34a05afc87..1cac9d1135cd 100644 --- a/arch/arm/plat-mxc/include/mach/board-mx27ads.h +++ b/arch/arm/plat-mxc/include/mach/board-mx27ads.h @@ -48,7 +48,8 @@ * Base address of PBC controller, CS4 */ #define PBC_BASE_ADDRESS 0xEB000000 -#define PBC_REG_ADDR(offset) (PBC_BASE_ADDRESS + (offset)) +#define PBC_REG_ADDR(offset) (void __force __iomem *) \ + (PBC_BASE_ADDRESS + (offset)) /* * PBC Interupt name definitions diff --git a/arch/arm/plat-mxc/include/mach/mx27.h b/arch/arm/plat-mxc/include/mach/mx27.h index 0313be720552..9c609d3ba23e 100644 --- a/arch/arm/plat-mxc/include/mach/mx27.h +++ b/arch/arm/plat-mxc/include/mach/mx27.h @@ -129,7 +129,7 @@ * it returns 0xDEADBEEF */ #define IO_ADDRESS(x) \ - (void __iomem *) \ + (void __force __iomem *) \ (((x >= AIPI_BASE_ADDR) && (x < (AIPI_BASE_ADDR + AIPI_SIZE))) ? \ AIPI_IO_ADDRESS(x) : \ ((x >= SAHB1_BASE_ADDR) && (x < (SAHB1_BASE_ADDR + SAHB1_SIZE))) ? \ diff --git a/arch/arm/plat-mxc/time.c b/arch/arm/plat-mxc/time.c index eb93fd1789db..ef1b3cd85bd3 100644 --- a/arch/arm/plat-mxc/time.c +++ b/arch/arm/plat-mxc/time.c @@ -52,11 +52,9 @@ static struct clocksource clocksource_mxc = { static int __init mxc_clocksource_init(struct clk *timer_clk) { - unsigned int clock; + unsigned int c = clk_get_rate(timer_clk); - clock = clk_get_rate(timer_clk); - - clocksource_mxc.mult = clocksource_hz2mult(clock, + clocksource_mxc.mult = clocksource_hz2mult(c, clocksource_mxc.shift); clocksource_register(&clocksource_mxc); @@ -176,11 +174,9 @@ static struct clock_event_device clockevent_mxc = { static int __init mxc_clockevent_init(struct clk *timer_clk) { - unsigned int clock; - - clock = clk_get_rate(timer_clk); + unsigned int c = clk_get_rate(timer_clk); - clockevent_mxc.mult = div_sc(clock, NSEC_PER_SEC, + clockevent_mxc.mult = div_sc(c, NSEC_PER_SEC, clockevent_mxc.shift); clockevent_mxc.max_delta_ns = clockevent_delta2ns(0xfffffffe, &clockevent_mxc); -- cgit v1.2.3 From 260a1fd26c62af482a22c6b31cc7882b4ec980d2 Mon Sep 17 00:00:00 2001 From: Holger Schurig Date: Mon, 26 Jan 2009 16:34:53 +0100 Subject: arm/imx2x: split i.MX21/i.MX27 register definitions * define new CONFIG_ARCH_MX21 (this one is currently mutually exclusive to CONFIG_ARCH_MX27, but this might change) * splits one header file. Memory definitions, interrupt sources, DMA channels are split into common part, i.MX27 specific and i.MX21 specific. * guard access to UART5/UART6, which don't exist on i.MX21 Signed-off-by: Holger Schurig Signed-off-by: Sascha Hauer --- arch/arm/plat-mxc/include/mach/hardware.h | 4 + arch/arm/plat-mxc/include/mach/mx21.h | 81 ++++++++++++ arch/arm/plat-mxc/include/mach/mx27.h | 197 +++-------------------------- arch/arm/plat-mxc/include/mach/mx2x.h | 200 ++++++++++++++++++++++++++++++ arch/arm/plat-mxc/include/mach/mxc.h | 4 + 5 files changed, 306 insertions(+), 180 deletions(-) create mode 100644 arch/arm/plat-mxc/include/mach/mx21.h create mode 100644 arch/arm/plat-mxc/include/mach/mx2x.h (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h index a612d8bb73c8..11f5727ea445 100644 --- a/arch/arm/plat-mxc/include/mach/hardware.h +++ b/arch/arm/plat-mxc/include/mach/hardware.h @@ -27,6 +27,10 @@ #endif #ifdef CONFIG_ARCH_MX2 +# include +# ifdef CONFIG_MACH_MX21 +# include +# endif # ifdef CONFIG_MACH_MX27 # include # endif diff --git a/arch/arm/plat-mxc/include/mach/mx21.h b/arch/arm/plat-mxc/include/mach/mx21.h new file mode 100644 index 000000000000..cfdbe051caf6 --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/mx21.h @@ -0,0 +1,81 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * Copyright 2009 Holger Schurig, hs4233@mail.mn-solutions.de + * + * This contains i.MX21-specific hardware definitions. For those + * hardware pieces that are common between i.MX21 and i.MX27, have a + * look at mx2x.h. + * + * 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. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef __ASM_ARCH_MXC_MX21_H__ +#define __ASM_ARCH_MXC_MX21_H__ + +#ifndef __ASM_ARCH_MXC_HARDWARE_H__ +#error "Do not include directly." +#endif + + +/* Memory regions and CS */ +#define SDRAM_BASE_ADDR 0xC0000000 +#define CSD1_BASE_ADDR 0xC4000000 + +#define CS0_BASE_ADDR 0xC8000000 +#define CS1_BASE_ADDR 0xCC000000 +#define CS2_BASE_ADDR 0xD0000000 +#define CS3_BASE_ADDR 0xD1000000 +#define CS4_BASE_ADDR 0xD2000000 +#define CS5_BASE_ADDR 0xDD000000 +#define PCMCIA_MEM_BASE_ADDR 0xD4000000 + +/* NAND, SDRAM, WEIM etc controllers */ +#define X_MEMC_BASE_ADDR 0xDF000000 +#define X_MEMC_BASE_ADDR_VIRT 0xF4200000 +#define X_MEMC_SIZE SZ_256K + +#define SDRAMC_BASE_ADDR (X_MEMC_BASE_ADDR + 0x0000) +#define EIM_BASE_ADDR (X_MEMC_BASE_ADDR + 0x1000) +#define PCMCIA_CTL_BASE_ADDR (X_MEMC_BASE_ADDR + 0x2000) +#define NFC_BASE_ADDR (X_MEMC_BASE_ADDR + 0x3000) + +#define IRAM_BASE_ADDR 0xFFFFE800 /* internal ram */ + +/* this is an i.MX21 CPU */ +#define cpu_is_mx21() (1) + +/* this CPU supports up to 192 GPIOs (don't forget the baseboard!) */ +#define ARCH_NR_GPIOS (6*32 + 16) + +/* fixed interrupt numbers */ +#define MXC_INT_USBCTRL 58 +#define MXC_INT_USBCTRL 58 +#define MXC_INT_USBMNP 57 +#define MXC_INT_USBFUNC 56 +#define MXC_INT_USBHOST 55 +#define MXC_INT_USBDMA 54 +#define MXC_INT_USBWKUP 53 +#define MXC_INT_EMMADEC 50 +#define MXC_INT_EMMAENC 49 +#define MXC_INT_BMI 30 +#define MXC_INT_FIRI 9 + +/* fixed DMA request numbers */ +#define DMA_REQ_BMI_RX 29 +#define DMA_REQ_BMI_TX 28 +#define DMA_REQ_FIRI_RX 4 + +#endif /* __ASM_ARCH_MXC_MX21_H__ */ diff --git a/arch/arm/plat-mxc/include/mach/mx27.h b/arch/arm/plat-mxc/include/mach/mx27.h index 9c609d3ba23e..5f6a8a7bb19c 100644 --- a/arch/arm/plat-mxc/include/mach/mx27.h +++ b/arch/arm/plat-mxc/include/mach/mx27.h @@ -2,6 +2,10 @@ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. * Copyright 2008 Juergen Beisert, kernel@pengutronix.de * + * This contains i.MX27-specific hardware definitions. For those + * hardware pieces that are common between i.MX21 and i.MX27, have a + * look at mx2x.h. + * * 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 @@ -27,35 +31,6 @@ /* IRAM */ #define IRAM_BASE_ADDR 0xFFFF4C00 /* internal ram */ -/* Register offests */ -#define AIPI_BASE_ADDR 0x10000000 -#define AIPI_BASE_ADDR_VIRT 0xF4000000 -#define AIPI_SIZE SZ_1M - -#define DMA_BASE_ADDR (AIPI_BASE_ADDR + 0x01000) -#define WDOG_BASE_ADDR (AIPI_BASE_ADDR + 0x02000) -#define GPT1_BASE_ADDR (AIPI_BASE_ADDR + 0x03000) -#define GPT2_BASE_ADDR (AIPI_BASE_ADDR + 0x04000) -#define GPT3_BASE_ADDR (AIPI_BASE_ADDR + 0x05000) -#define PWM_BASE_ADDR (AIPI_BASE_ADDR + 0x06000) -#define RTC_BASE_ADDR (AIPI_BASE_ADDR + 0x07000) -#define KPP_BASE_ADDR (AIPI_BASE_ADDR + 0x08000) -#define OWIRE_BASE_ADDR (AIPI_BASE_ADDR + 0x09000) -#define UART1_BASE_ADDR (AIPI_BASE_ADDR + 0x0A000) -#define UART2_BASE_ADDR (AIPI_BASE_ADDR + 0x0B000) -#define UART3_BASE_ADDR (AIPI_BASE_ADDR + 0x0C000) -#define UART4_BASE_ADDR (AIPI_BASE_ADDR + 0x0D000) -#define CSPI1_BASE_ADDR (AIPI_BASE_ADDR + 0x0E000) -#define CSPI2_BASE_ADDR (AIPI_BASE_ADDR + 0x0F000) -#define SSI1_BASE_ADDR (AIPI_BASE_ADDR + 0x10000) -#define SSI2_BASE_ADDR (AIPI_BASE_ADDR + 0x11000) -#define I2C_BASE_ADDR (AIPI_BASE_ADDR + 0x12000) -#define SDHC1_BASE_ADDR (AIPI_BASE_ADDR + 0x13000) -#define SDHC2_BASE_ADDR (AIPI_BASE_ADDR + 0x14000) -#define GPIO_BASE_ADDR (AIPI_BASE_ADDR + 0x15000) -#define AUDMUX_BASE_ADDR (AIPI_BASE_ADDR + 0x16000) - -#define CSPI3_BASE_ADDR (AIPI_BASE_ADDR + 0x17000) #define MSHC_BASE_ADDR (AIPI_BASE_ADDR + 0x18000) #define GPT5_BASE_ADDR (AIPI_BASE_ADDR + 0x19000) #define GPT4_BASE_ADDR (AIPI_BASE_ADDR + 0x1A000) @@ -64,55 +39,24 @@ #define I2C2_BASE_ADDR (AIPI_BASE_ADDR + 0x1D000) #define SDHC3_BASE_ADDR (AIPI_BASE_ADDR + 0x1E000) #define GPT6_BASE_ADDR (AIPI_BASE_ADDR + 0x1F000) - -#define LCDC_BASE_ADDR (AIPI_BASE_ADDR + 0x21000) -#define SLCDC_BASE_ADDR (AIPI_BASE_ADDR + 0x22000) #define VPU_BASE_ADDR (AIPI_BASE_ADDR + 0x23000) -#define USBOTG_BASE_ADDR (AIPI_BASE_ADDR + 0x24000) -/* for mx27*/ #define OTG_BASE_ADDR USBOTG_BASE_ADDR #define SAHARA_BASE_ADDR (AIPI_BASE_ADDR + 0x25000) -#define EMMA_PP_BASE_ADDR (AIPI_BASE_ADDR + 0x26000) -#define EMMA_PRP_BASE_ADDR (AIPI_BASE_ADDR + 0x26400) -#define CCM_BASE_ADDR (AIPI_BASE_ADDR + 0x27000) -#define SYSCTRL_BASE_ADDR (AIPI_BASE_ADDR + 0x27800) #define IIM_BASE_ADDR (AIPI_BASE_ADDR + 0x28000) - #define RTIC_BASE_ADDR (AIPI_BASE_ADDR + 0x2A000) #define FEC_BASE_ADDR (AIPI_BASE_ADDR + 0x2B000) #define SCC_BASE_ADDR (AIPI_BASE_ADDR + 0x2C000) #define ETB_BASE_ADDR (AIPI_BASE_ADDR + 0x3B000) #define ETB_RAM_BASE_ADDR (AIPI_BASE_ADDR + 0x3C000) -#define JAM_BASE_ADDR (AIPI_BASE_ADDR + 0x3E000) -#define MAX_BASE_ADDR (AIPI_BASE_ADDR + 0x3F000) - -/* ROMP and AVIC */ +/* ROM patch */ #define ROMP_BASE_ADDR 0x10041000 -#define AVIC_BASE_ADDR 0x10040000 - -#define SAHB1_BASE_ADDR 0x80000000 -#define SAHB1_BASE_ADDR_VIRT 0xF4100000 -#define SAHB1_SIZE SZ_1M - -#define CSI_BASE_ADDR (SAHB1_BASE_ADDR + 0x0000) #define ATA_BASE_ADDR (SAHB1_BASE_ADDR + 0x1000) -/* NAND, SDRAM, WEIM, M3IF, EMI controllers */ -#define X_MEMC_BASE_ADDR 0xD8000000 -#define X_MEMC_BASE_ADDR_VIRT 0xF4200000 -#define X_MEMC_SIZE SZ_1M - -#define NFC_BASE_ADDR (X_MEMC_BASE_ADDR) -#define SDRAMC_BASE_ADDR (X_MEMC_BASE_ADDR + 0x1000) -#define WEIM_BASE_ADDR (X_MEMC_BASE_ADDR + 0x2000) -#define M3IF_BASE_ADDR (X_MEMC_BASE_ADDR + 0x3000) -#define PCMCIA_CTL_BASE_ADDR (X_MEMC_BASE_ADDR + 0x4000) - /* Memory regions and CS */ -#define SDRAM_BASE_ADDR 0xA0000000 -#define CSD1_BASE_ADDR 0xB0000000 +#define SDRAM_BASE_ADDR 0xA0000000 +#define CSD1_BASE_ADDR 0xB0000000 #define CS0_BASE_ADDR 0xC0000000 #define CS1_BASE_ADDR 0xC8000000 @@ -122,44 +66,20 @@ #define CS5_BASE_ADDR 0xD6000000 #define PCMCIA_MEM_BASE_ADDR 0xDC000000 -/* - * This macro defines the physical to virtual address mapping for all the - * peripheral modules. It is used by passing in the physical address as x - * and returning the virtual address. If the physical address is not mapped, - * it returns 0xDEADBEEF - */ -#define IO_ADDRESS(x) \ - (void __force __iomem *) \ - (((x >= AIPI_BASE_ADDR) && (x < (AIPI_BASE_ADDR + AIPI_SIZE))) ? \ - AIPI_IO_ADDRESS(x) : \ - ((x >= SAHB1_BASE_ADDR) && (x < (SAHB1_BASE_ADDR + SAHB1_SIZE))) ? \ - SAHB1_IO_ADDRESS(x) : \ - ((x >= X_MEMC_BASE_ADDR) && (x < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? \ - X_MEMC_IO_ADDRESS(x) : 0xDEADBEEF) - -/* define the address mapping macros: in physical address order */ -#define AIPI_IO_ADDRESS(x) \ - (((x) - AIPI_BASE_ADDR) + AIPI_BASE_ADDR_VIRT) - -#define AVIC_IO_ADDRESS(x) AIPI_IO_ADDRESS(x) - -#define SAHB1_IO_ADDRESS(x) \ - (((x) - SAHB1_BASE_ADDR) + SAHB1_BASE_ADDR_VIRT) - -#define CS4_IO_ADDRESS(x) \ - (((x) - CS4_BASE_ADDR) + CS4_BASE_ADDR_VIRT) - -#define X_MEMC_IO_ADDRESS(x) \ - (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT) +/* NAND, SDRAM, WEIM, M3IF, EMI controllers */ +#define X_MEMC_BASE_ADDR 0xD8000000 +#define X_MEMC_BASE_ADDR_VIRT 0xF4200000 +#define X_MEMC_SIZE SZ_1M -#define PCMCIA_IO_ADDRESS(x) \ - (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT) +#define NFC_BASE_ADDR (X_MEMC_BASE_ADDR) +#define SDRAMC_BASE_ADDR (X_MEMC_BASE_ADDR + 0x1000) +#define WEIM_BASE_ADDR (X_MEMC_BASE_ADDR + 0x2000) +#define M3IF_BASE_ADDR (X_MEMC_BASE_ADDR + 0x3000) +#define PCMCIA_CTL_BASE_ADDR (X_MEMC_BASE_ADDR + 0x4000) -/* fixed interrput numbers */ +/* fixed interrupt numbers */ #define MXC_INT_CCM 63 #define MXC_INT_IIM 62 -#define MXC_INT_LCDC 61 -#define MXC_INT_SLCDC 60 #define MXC_INT_SAHARA 59 #define MXC_INT_SCC_SCM 58 #define MXC_INT_SCC_SMN 57 @@ -167,54 +87,12 @@ #define MXC_INT_USB2 55 #define MXC_INT_USB1 54 #define MXC_INT_VPU 53 -#define MXC_INT_EMMAPP 52 -#define MXC_INT_EMMAPRP 51 #define MXC_INT_FEC 50 #define MXC_INT_UART5 49 #define MXC_INT_UART6 48 -#define MXC_INT_DMACH15 47 -#define MXC_INT_DMACH14 46 -#define MXC_INT_DMACH13 45 -#define MXC_INT_DMACH12 44 -#define MXC_INT_DMACH11 43 -#define MXC_INT_DMACH10 42 -#define MXC_INT_DMACH9 41 -#define MXC_INT_DMACH8 40 -#define MXC_INT_DMACH7 39 -#define MXC_INT_DMACH6 38 -#define MXC_INT_DMACH5 37 -#define MXC_INT_DMACH4 36 -#define MXC_INT_DMACH3 35 -#define MXC_INT_DMACH2 34 -#define MXC_INT_DMACH1 33 -#define MXC_INT_DMACH0 32 -#define MXC_INT_CSI 31 #define MXC_INT_ATA 30 -#define MXC_INT_NANDFC 29 -#define MXC_INT_PCMCIA 28 -#define MXC_INT_WDOG 27 -#define MXC_INT_GPT1 26 -#define MXC_INT_GPT2 25 -#define MXC_INT_GPT3 24 -#define MXC_INT_GPT INT_GPT1 -#define MXC_INT_PWM 23 -#define MXC_INT_RTC 22 -#define MXC_INT_KPP 21 -#define MXC_INT_UART1 20 -#define MXC_INT_UART2 19 -#define MXC_INT_UART3 18 -#define MXC_INT_UART4 17 -#define MXC_INT_CSPI1 16 -#define MXC_INT_CSPI2 15 -#define MXC_INT_SSI1 14 -#define MXC_INT_SSI2 13 -#define MXC_INT_I2C 12 -#define MXC_INT_SDHC1 11 -#define MXC_INT_SDHC2 10 #define MXC_INT_SDHC3 9 -#define MXC_INT_GPIO 8 #define MXC_INT_SDHC 7 -#define MXC_INT_CSPI3 6 #define MXC_INT_RTIC 5 #define MXC_INT_GPT4 4 #define MXC_INT_GPT5 3 @@ -228,36 +106,9 @@ #define DMA_REQ_UART6_TX 34 #define DMA_REQ_UART5_RX 33 #define DMA_REQ_UART5_TX 32 -#define DMA_REQ_CSI_RX 31 -#define DMA_REQ_CSI_STAT 30 #define DMA_REQ_ATA_RCV 29 #define DMA_REQ_ATA_TX 28 -#define DMA_REQ_UART1_TX 27 -#define DMA_REQ_UART1_RX 26 -#define DMA_REQ_UART2_TX 25 -#define DMA_REQ_UART2_RX 24 -#define DMA_REQ_UART3_TX 23 -#define DMA_REQ_UART3_RX 22 -#define DMA_REQ_UART4_TX 21 -#define DMA_REQ_UART4_RX 20 -#define DMA_REQ_CSPI1_TX 19 -#define DMA_REQ_CSPI1_RX 18 -#define DMA_REQ_CSPI2_TX 17 -#define DMA_REQ_CSPI2_RX 16 -#define DMA_REQ_SSI1_TX1 15 -#define DMA_REQ_SSI1_RX1 14 -#define DMA_REQ_SSI1_TX0 13 -#define DMA_REQ_SSI1_RX0 12 -#define DMA_REQ_SSI2_TX1 11 -#define DMA_REQ_SSI2_RX1 10 -#define DMA_REQ_SSI2_TX0 9 -#define DMA_REQ_SSI2_RX0 8 -#define DMA_REQ_SDHC1 7 -#define DMA_REQ_SDHC2 6 #define DMA_REQ_MSHC 4 -#define DMA_REQ_EXT 3 -#define DMA_REQ_CSPI3_TX 2 -#define DMA_REQ_CSPI3_RX 1 /* silicon revisions specific to i.MX27 */ #define CHIP_REV_1_0 0x00 @@ -267,20 +118,6 @@ extern int mx27_revision(void); #endif -/* gpio and gpio based interrupt handling */ -#define GPIO_DR 0x1C -#define GPIO_GDIR 0x00 -#define GPIO_PSR 0x24 -#define GPIO_ICR1 0x28 -#define GPIO_ICR2 0x2C -#define GPIO_IMR 0x30 -#define GPIO_ISR 0x34 -#define GPIO_INT_LOW_LEV 0x3 -#define GPIO_INT_HIGH_LEV 0x2 -#define GPIO_INT_RISE_EDGE 0x0 -#define GPIO_INT_FALL_EDGE 0x1 -#define GPIO_INT_NONE 0x4 - /* Mandatory defines used globally */ /* this is an i.MX27 CPU */ diff --git a/arch/arm/plat-mxc/include/mach/mx2x.h b/arch/arm/plat-mxc/include/mach/mx2x.h new file mode 100644 index 000000000000..fc40d3ab8c5b --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/mx2x.h @@ -0,0 +1,200 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * This contains hardware definitions that are common between i.MX21 and + * i.MX27. + * + * 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. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef __ASM_ARCH_MXC_MX2x_H__ +#define __ASM_ARCH_MXC_MX2x_H__ + +#ifndef __ASM_ARCH_MXC_HARDWARE_H__ +#error "Do not include directly." +#endif + +/* The following addresses are common between i.MX21 and i.MX27 */ + +/* Register offests */ +#define AIPI_BASE_ADDR 0x10000000 +#define AIPI_BASE_ADDR_VIRT 0xF4000000 +#define AIPI_SIZE SZ_1M + +#define DMA_BASE_ADDR (AIPI_BASE_ADDR + 0x01000) +#define WDOG_BASE_ADDR (AIPI_BASE_ADDR + 0x02000) +#define GPT1_BASE_ADDR (AIPI_BASE_ADDR + 0x03000) +#define GPT2_BASE_ADDR (AIPI_BASE_ADDR + 0x04000) +#define GPT3_BASE_ADDR (AIPI_BASE_ADDR + 0x05000) +#define PWM_BASE_ADDR (AIPI_BASE_ADDR + 0x06000) +#define RTC_BASE_ADDR (AIPI_BASE_ADDR + 0x07000) +#define KPP_BASE_ADDR (AIPI_BASE_ADDR + 0x08000) +#define OWIRE_BASE_ADDR (AIPI_BASE_ADDR + 0x09000) +#define UART1_BASE_ADDR (AIPI_BASE_ADDR + 0x0A000) +#define UART2_BASE_ADDR (AIPI_BASE_ADDR + 0x0B000) +#define UART3_BASE_ADDR (AIPI_BASE_ADDR + 0x0C000) +#define UART4_BASE_ADDR (AIPI_BASE_ADDR + 0x0D000) +#define CSPI1_BASE_ADDR (AIPI_BASE_ADDR + 0x0E000) +#define CSPI2_BASE_ADDR (AIPI_BASE_ADDR + 0x0F000) +#define SSI1_BASE_ADDR (AIPI_BASE_ADDR + 0x10000) +#define SSI2_BASE_ADDR (AIPI_BASE_ADDR + 0x11000) +#define I2C_BASE_ADDR (AIPI_BASE_ADDR + 0x12000) +#define SDHC1_BASE_ADDR (AIPI_BASE_ADDR + 0x13000) +#define SDHC2_BASE_ADDR (AIPI_BASE_ADDR + 0x14000) +#define GPIO_BASE_ADDR (AIPI_BASE_ADDR + 0x15000) +#define AUDMUX_BASE_ADDR (AIPI_BASE_ADDR + 0x16000) +#define CSPI3_BASE_ADDR (AIPI_BASE_ADDR + 0x17000) +#define LCDC_BASE_ADDR (AIPI_BASE_ADDR + 0x21000) +#define SLCDC_BASE_ADDR (AIPI_BASE_ADDR + 0x22000) +#define USBOTG_BASE_ADDR (AIPI_BASE_ADDR + 0x24000) +#define EMMA_PP_BASE_ADDR (AIPI_BASE_ADDR + 0x26000) +#define EMMA_PRP_BASE_ADDR (AIPI_BASE_ADDR + 0x26400) +#define CCM_BASE_ADDR (AIPI_BASE_ADDR + 0x27000) +#define SYSCTRL_BASE_ADDR (AIPI_BASE_ADDR + 0x27800) +#define JAM_BASE_ADDR (AIPI_BASE_ADDR + 0x3E000) +#define MAX_BASE_ADDR (AIPI_BASE_ADDR + 0x3F000) + +#define AVIC_BASE_ADDR 0x10040000 + +#define SAHB1_BASE_ADDR 0x80000000 +#define SAHB1_BASE_ADDR_VIRT 0xF4100000 +#define SAHB1_SIZE SZ_1M + +#define CSI_BASE_ADDR (SAHB1_BASE_ADDR + 0x0000) + +/* + * This macro defines the physical to virtual address mapping for all the + * peripheral modules. It is used by passing in the physical address as x + * and returning the virtual address. If the physical address is not mapped, + * it returns 0xDEADBEEF + */ +#define IO_ADDRESS(x) \ + (void __force __iomem *) \ + (((x >= AIPI_BASE_ADDR) && (x < (AIPI_BASE_ADDR + AIPI_SIZE))) ? \ + AIPI_IO_ADDRESS(x) : \ + ((x >= SAHB1_BASE_ADDR) && (x < (SAHB1_BASE_ADDR + SAHB1_SIZE))) ? \ + SAHB1_IO_ADDRESS(x) : \ + ((x >= X_MEMC_BASE_ADDR) && (x < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? \ + X_MEMC_IO_ADDRESS(x) : 0xDEADBEEF) + +/* define the address mapping macros: in physical address order */ +#define AIPI_IO_ADDRESS(x) \ + (((x) - AIPI_BASE_ADDR) + AIPI_BASE_ADDR_VIRT) + +#define AVIC_IO_ADDRESS(x) AIPI_IO_ADDRESS(x) + +#define SAHB1_IO_ADDRESS(x) \ + (((x) - SAHB1_BASE_ADDR) + SAHB1_BASE_ADDR_VIRT) + +#define CS4_IO_ADDRESS(x) \ + (((x) - CS4_BASE_ADDR) + CS4_BASE_ADDR_VIRT) + +#define X_MEMC_IO_ADDRESS(x) \ + (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT) + +#define PCMCIA_IO_ADDRESS(x) \ + (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT) + +/* fixed interrupt numbers */ +#define MXC_INT_LCDC 61 +#define MXC_INT_SLCDC 60 +#define MXC_INT_EMMAPP 52 +#define MXC_INT_EMMAPRP 51 +#define MXC_INT_DMACH15 47 +#define MXC_INT_DMACH14 46 +#define MXC_INT_DMACH13 45 +#define MXC_INT_DMACH12 44 +#define MXC_INT_DMACH11 43 +#define MXC_INT_DMACH10 42 +#define MXC_INT_DMACH9 41 +#define MXC_INT_DMACH8 40 +#define MXC_INT_DMACH7 39 +#define MXC_INT_DMACH6 38 +#define MXC_INT_DMACH5 37 +#define MXC_INT_DMACH4 36 +#define MXC_INT_DMACH3 35 +#define MXC_INT_DMACH2 34 +#define MXC_INT_DMACH1 33 +#define MXC_INT_DMACH0 32 +#define MXC_INT_CSI 31 +#define MXC_INT_NANDFC 29 +#define MXC_INT_PCMCIA 28 +#define MXC_INT_WDOG 27 +#define MXC_INT_GPT1 26 +#define MXC_INT_GPT2 25 +#define MXC_INT_GPT3 24 +#define MXC_INT_GPT INT_GPT1 +#define MXC_INT_PWM 23 +#define MXC_INT_RTC 22 +#define MXC_INT_KPP 21 +#define MXC_INT_UART1 20 +#define MXC_INT_UART2 19 +#define MXC_INT_UART3 18 +#define MXC_INT_UART4 17 +#define MXC_INT_CSPI1 16 +#define MXC_INT_CSPI2 15 +#define MXC_INT_SSI1 14 +#define MXC_INT_SSI2 13 +#define MXC_INT_I2C 12 +#define MXC_INT_SDHC1 11 +#define MXC_INT_SDHC2 10 +#define MXC_INT_GPIO 8 +#define MXC_INT_CSPI3 6 + +/* gpio and gpio based interrupt handling */ +#define GPIO_DR 0x1C +#define GPIO_GDIR 0x00 +#define GPIO_PSR 0x24 +#define GPIO_ICR1 0x28 +#define GPIO_ICR2 0x2C +#define GPIO_IMR 0x30 +#define GPIO_ISR 0x34 +#define GPIO_INT_LOW_LEV 0x3 +#define GPIO_INT_HIGH_LEV 0x2 +#define GPIO_INT_RISE_EDGE 0x0 +#define GPIO_INT_FALL_EDGE 0x1 +#define GPIO_INT_NONE 0x4 + +/* fixed DMA request numbers */ +#define DMA_REQ_CSI_RX 31 +#define DMA_REQ_CSI_STAT 30 +#define DMA_REQ_UART1_TX 27 +#define DMA_REQ_UART1_RX 26 +#define DMA_REQ_UART2_TX 25 +#define DMA_REQ_UART2_RX 24 +#define DMA_REQ_UART3_TX 23 +#define DMA_REQ_UART3_RX 22 +#define DMA_REQ_UART4_TX 21 +#define DMA_REQ_UART4_RX 20 +#define DMA_REQ_CSPI1_TX 19 +#define DMA_REQ_CSPI1_RX 18 +#define DMA_REQ_CSPI2_TX 17 +#define DMA_REQ_CSPI2_RX 16 +#define DMA_REQ_SSI1_TX1 15 +#define DMA_REQ_SSI1_RX1 14 +#define DMA_REQ_SSI1_TX0 13 +#define DMA_REQ_SSI1_RX0 12 +#define DMA_REQ_SSI2_TX1 11 +#define DMA_REQ_SSI2_RX1 10 +#define DMA_REQ_SSI2_TX0 9 +#define DMA_REQ_SSI2_RX0 8 +#define DMA_REQ_SDHC1 7 +#define DMA_REQ_SDHC2 6 +#define DMA_REQ_EXT 3 +#define DMA_REQ_CSPI3_TX 2 +#define DMA_REQ_CSPI3_RX 1 + +#endif /* __ASM_ARCH_MXC_MX2x_H__ */ diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h index bbd848e004d7..d6b0c472cd97 100644 --- a/arch/arm/plat-mxc/include/mach/mxc.h +++ b/arch/arm/plat-mxc/include/mach/mxc.h @@ -37,6 +37,10 @@ # define cpu_is_mx27() (0) #endif +#ifndef CONFIG_MACH_MX21 +# define cpu_is_mx21() (0) +#endif + #if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX2) #define CSCR_U(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10) #define CSCR_L(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x4) -- cgit v1.2.3 From aa3b0a6f57be50f1009a409e82731a8f9be80fc4 Mon Sep 17 00:00:00 2001 From: Holger Schurig Date: Mon, 26 Jan 2009 16:34:54 +0100 Subject: arm/imx21: clock support for i.MX21 Based on code from "Martin Fuzzey" Signed-off-by: Holger Schurig Signed-off-by: Sascha Hauer --- arch/arm/mach-mx2/Makefile | 2 + arch/arm/mach-mx2/clock_imx21.c | 984 ++++++++++++++++++++++++++++++++ arch/arm/mach-mx2/crm_regs.h | 258 +++++++++ arch/arm/plat-mxc/include/mach/common.h | 1 + 4 files changed, 1245 insertions(+) create mode 100644 arch/arm/mach-mx2/clock_imx21.c create mode 100644 arch/arm/mach-mx2/crm_regs.h (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile index 382d86080e86..6e1a2bffc812 100644 --- a/arch/arm/mach-mx2/Makefile +++ b/arch/arm/mach-mx2/Makefile @@ -6,6 +6,8 @@ obj-y := system.o generic.o devices.o serial.o +obj-$(CONFIG_MACH_MX21) += clock_imx21.o + obj-$(CONFIG_MACH_MX27) += cpu_imx27.o obj-$(CONFIG_MACH_MX27) += clock_imx27.o diff --git a/arch/arm/mach-mx2/clock_imx21.c b/arch/arm/mach-mx2/clock_imx21.c new file mode 100644 index 000000000000..2dee5c87614c --- /dev/null +++ b/arch/arm/mach-mx2/clock_imx21.c @@ -0,0 +1,984 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com + * + * 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. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include "crm_regs.h" + +static int _clk_enable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(clk->enable_reg); + reg |= 1 << clk->enable_shift; + __raw_writel(reg, clk->enable_reg); + return 0; +} + +static void _clk_disable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(clk->enable_reg); + reg &= ~(1 << clk->enable_shift); + __raw_writel(reg, clk->enable_reg); +} + +static int _clk_spll_enable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(CCM_CSCR); + reg |= CCM_CSCR_SPEN; + __raw_writel(reg, CCM_CSCR); + + while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0) + ; + return 0; +} + +static void _clk_spll_disable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(CCM_CSCR); + reg &= ~CCM_CSCR_SPEN; + __raw_writel(reg, CCM_CSCR); +} + + +#define CSCR() (__raw_readl(CCM_CSCR)) +#define PCDR0() (__raw_readl(CCM_PCDR0)) +#define PCDR1() (__raw_readl(CCM_PCDR1)) + +static unsigned long _clk_perclkx_round_rate(struct clk *clk, + unsigned long rate) +{ + u32 div; + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + + div = parent_rate / rate; + if (parent_rate % rate) + div++; + + if (div > 64) + div = 64; + + return parent_rate / div; +} + +static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg; + u32 div; + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + + if (clk->id < 0 || clk->id > 3) + return -EINVAL; + + div = parent_rate / rate; + if (div > 64 || div < 1 || ((parent_rate / div) != rate)) + return -EINVAL; + div--; + + reg = + __raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK << + (clk->id << 3)); + reg |= div << (clk->id << 3); + __raw_writel(reg, CCM_PCDR1); + + return 0; +} + +static unsigned long _clk_usb_recalc(struct clk *clk) +{ + unsigned long usb_pdf; + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + + usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET; + + return parent_rate / (usb_pdf + 1U); +} + +static unsigned long _clk_ssix_recalc(struct clk *clk, unsigned long pdf) +{ + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + + pdf = (pdf < 2) ? 124UL : pdf; /* MX21 & MX27 TO1 */ + + return 2UL * parent_rate / pdf; +} + +static unsigned long _clk_ssi1_recalc(struct clk *clk) +{ + return _clk_ssix_recalc(clk, + (PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK) + >> CCM_PCDR0_SSI1BAUDDIV_OFFSET); +} + +static unsigned long _clk_ssi2_recalc(struct clk *clk) +{ + return _clk_ssix_recalc(clk, + (PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >> + CCM_PCDR0_SSI2BAUDDIV_OFFSET); +} + +static unsigned long _clk_nfc_recalc(struct clk *clk) +{ + unsigned long nfc_pdf; + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + + nfc_pdf = (PCDR0() & CCM_PCDR0_NFCDIV_MASK) + >> CCM_PCDR0_NFCDIV_OFFSET; + + return parent_rate / (nfc_pdf + 1); +} + +static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate) +{ + return clk->parent->round_rate(clk->parent, rate); +} + +static int _clk_parent_set_rate(struct clk *clk, unsigned long rate) +{ + return clk->parent->set_rate(clk->parent, rate); +} + +static unsigned long external_high_reference; /* in Hz */ + +static unsigned long get_high_reference_clock_rate(struct clk *clk) +{ + return external_high_reference; +} + +/* + * the high frequency external clock reference + * Default case is 26MHz. + */ +static struct clk ckih_clk = { + .get_rate = get_high_reference_clock_rate, +}; + +static unsigned long external_low_reference; /* in Hz */ + +static unsigned long get_low_reference_clock_rate(struct clk *clk) +{ + return external_low_reference; +} + +/* + * the low frequency external clock reference + * Default case is 32.768kHz. + */ +static struct clk ckil_clk = { + .get_rate = get_low_reference_clock_rate, +}; + + +static unsigned long _clk_fpm_recalc(struct clk *clk) +{ + return clk_get_rate(clk->parent) * 512; +} + +/* Output of frequency pre multiplier */ +static struct clk fpm_clk = { + .parent = &ckil_clk, + .get_rate = _clk_fpm_recalc, +}; + +static unsigned long get_mpll_clk(struct clk *clk) +{ + uint32_t reg; + unsigned long ref_clk; + unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0; + unsigned long long temp; + + ref_clk = clk_get_rate(clk->parent); + + reg = __raw_readl(CCM_MPCTL0); + pdf = (reg & CCM_MPCTL0_PD_MASK) >> CCM_MPCTL0_PD_OFFSET; + mfd = (reg & CCM_MPCTL0_MFD_MASK) >> CCM_MPCTL0_MFD_OFFSET; + mfi = (reg & CCM_MPCTL0_MFI_MASK) >> CCM_MPCTL0_MFI_OFFSET; + mfn = (reg & CCM_MPCTL0_MFN_MASK) >> CCM_MPCTL0_MFN_OFFSET; + + mfi = (mfi <= 5) ? 5 : mfi; + temp = 2LL * ref_clk * mfn; + do_div(temp, mfd + 1); + temp = 2LL * ref_clk * mfi + temp; + do_div(temp, pdf + 1); + + return (unsigned long)temp; +} + +static struct clk mpll_clk = { + .parent = &ckih_clk, + .get_rate = get_mpll_clk, +}; + +static unsigned long _clk_fclk_get_rate(struct clk *clk) +{ + unsigned long parent_rate; + u32 div; + + div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET; + parent_rate = clk_get_rate(clk->parent); + + return parent_rate / (div+1); +} + +static struct clk fclk_clk = { + .parent = &mpll_clk, + .get_rate = _clk_fclk_get_rate +}; + +static unsigned long get_spll_clk(struct clk *clk) +{ + uint32_t reg; + unsigned long ref_clk; + unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0; + unsigned long long temp; + + ref_clk = clk_get_rate(clk->parent); + + reg = __raw_readl(CCM_SPCTL0); + pdf = (reg & CCM_SPCTL0_PD_MASK) >> CCM_SPCTL0_PD_OFFSET; + mfd = (reg & CCM_SPCTL0_MFD_MASK) >> CCM_SPCTL0_MFD_OFFSET; + mfi = (reg & CCM_SPCTL0_MFI_MASK) >> CCM_SPCTL0_MFI_OFFSET; + mfn = (reg & CCM_SPCTL0_MFN_MASK) >> CCM_SPCTL0_MFN_OFFSET; + + mfi = (mfi <= 5) ? 5 : mfi; + temp = 2LL * ref_clk * mfn; + do_div(temp, mfd + 1); + temp = 2LL * ref_clk * mfi + temp; + do_div(temp, pdf + 1); + + return (unsigned long)temp; +} + +static struct clk spll_clk = { + .parent = &ckih_clk, + .get_rate = get_spll_clk, + .enable = _clk_spll_enable, + .disable = _clk_spll_disable, +}; + +static unsigned long get_hclk_clk(struct clk *clk) +{ + unsigned long rate; + unsigned long bclk_pdf; + + bclk_pdf = (CSCR() & CCM_CSCR_BCLK_MASK) + >> CCM_CSCR_BCLK_OFFSET; + + rate = clk_get_rate(clk->parent); + return rate / (bclk_pdf + 1); +} + +static struct clk hclk_clk = { + .parent = &fclk_clk, + .get_rate = get_hclk_clk, +}; + +static unsigned long get_ipg_clk(struct clk *clk) +{ + unsigned long rate; + unsigned long ipg_pdf; + + ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET; + + rate = clk_get_rate(clk->parent); + return rate / (ipg_pdf + 1); +} + +static struct clk ipg_clk = { + .parent = &hclk_clk, + .get_rate = get_ipg_clk, +}; + +static unsigned long _clk_perclkx_recalc(struct clk *clk) +{ + unsigned long perclk_pdf; + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + + if (clk->id < 0 || clk->id > 3) + return 0; + + perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK; + + return parent_rate / (perclk_pdf + 1); +} + +static struct clk per_clk[] = { + { + .id = 0, + .parent = &mpll_clk, + .get_rate = _clk_perclkx_recalc, + }, { + .id = 1, + .parent = &mpll_clk, + .get_rate = _clk_perclkx_recalc, + }, { + .id = 2, + .parent = &mpll_clk, + .round_rate = _clk_perclkx_round_rate, + .set_rate = _clk_perclkx_set_rate, + .get_rate = _clk_perclkx_recalc, + /* Enable/Disable done via lcd_clkc[1] */ + }, { + .id = 3, + .parent = &mpll_clk, + .round_rate = _clk_perclkx_round_rate, + .set_rate = _clk_perclkx_set_rate, + .get_rate = _clk_perclkx_recalc, + /* Enable/Disable done via csi_clk[1] */ + }, +}; + +static struct clk uart_ipg_clk[]; + +static struct clk uart_clk[] = { + { + .id = 0, + .parent = &per_clk[0], + .secondary = &uart_ipg_clk[0], + }, { + .id = 1, + .parent = &per_clk[0], + .secondary = &uart_ipg_clk[1], + }, { + .id = 2, + .parent = &per_clk[0], + .secondary = &uart_ipg_clk[2], + }, { + .id = 3, + .parent = &per_clk[0], + .secondary = &uart_ipg_clk[3], + }, +}; + +static struct clk uart_ipg_clk[] = { + { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_UART1_REG, + .enable_shift = CCM_PCCR_UART1_OFFSET, + .disable = _clk_disable, + }, { + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_UART2_REG, + .enable_shift = CCM_PCCR_UART2_OFFSET, + .disable = _clk_disable, + }, { + .id = 2, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_UART3_REG, + .enable_shift = CCM_PCCR_UART3_OFFSET, + .disable = _clk_disable, + }, { + .id = 3, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_UART4_REG, + .enable_shift = CCM_PCCR_UART4_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk gpt_ipg_clk[]; + +static struct clk gpt_clk[] = { + { + .id = 0, + .parent = &per_clk[0], + .secondary = &gpt_ipg_clk[0], + }, { + .id = 1, + .parent = &per_clk[0], + .secondary = &gpt_ipg_clk[1], + }, { + .id = 2, + .parent = &per_clk[0], + .secondary = &gpt_ipg_clk[2], + }, +}; + +static struct clk gpt_ipg_clk[] = { + { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_GPT1_REG, + .enable_shift = CCM_PCCR_GPT1_OFFSET, + .disable = _clk_disable, + }, { + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_GPT2_REG, + .enable_shift = CCM_PCCR_GPT2_OFFSET, + .disable = _clk_disable, + }, { + .id = 2, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_GPT3_REG, + .enable_shift = CCM_PCCR_GPT3_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk pwm_clk[] = { + { + .parent = &per_clk[0], + .secondary = &pwm_clk[1], + }, { + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_PWM_REG, + .enable_shift = CCM_PCCR_PWM_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk sdhc_ipg_clk[]; + +static struct clk sdhc_clk[] = { + { + .id = 0, + .parent = &per_clk[1], + .secondary = &sdhc_ipg_clk[0], + }, { + .id = 1, + .parent = &per_clk[1], + .secondary = &sdhc_ipg_clk[1], + }, +}; + +static struct clk sdhc_ipg_clk[] = { + { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_SDHC1_REG, + .enable_shift = CCM_PCCR_SDHC1_OFFSET, + .disable = _clk_disable, + }, { + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_SDHC2_REG, + .enable_shift = CCM_PCCR_SDHC2_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk cspi_ipg_clk[]; + +static struct clk cspi_clk[] = { + { + .id = 0, + .parent = &per_clk[1], + .secondary = &cspi_ipg_clk[0], + }, { + .id = 1, + .parent = &per_clk[1], + .secondary = &cspi_ipg_clk[1], + }, { + .id = 2, + .parent = &per_clk[1], + .secondary = &cspi_ipg_clk[2], + }, +}; + +static struct clk cspi_ipg_clk[] = { + { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_CSPI1_REG, + .enable_shift = CCM_PCCR_CSPI1_OFFSET, + .disable = _clk_disable, + }, { + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_CSPI2_REG, + .enable_shift = CCM_PCCR_CSPI2_OFFSET, + .disable = _clk_disable, + }, { + .id = 3, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_CSPI3_REG, + .enable_shift = CCM_PCCR_CSPI3_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk lcdc_clk[] = { + { + .parent = &per_clk[2], + .secondary = &lcdc_clk[1], + .round_rate = _clk_parent_round_rate, + .set_rate = _clk_parent_set_rate, + }, { + .parent = &ipg_clk, + .secondary = &lcdc_clk[2], + .enable = _clk_enable, + .enable_reg = CCM_PCCR_LCDC_REG, + .enable_shift = CCM_PCCR_LCDC_OFFSET, + .disable = _clk_disable, + }, { + .parent = &hclk_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_HCLK_LCDC_REG, + .enable_shift = CCM_PCCR_HCLK_LCDC_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk csi_clk[] = { + { + .parent = &per_clk[3], + .secondary = &csi_clk[1], + .round_rate = _clk_parent_round_rate, + .set_rate = _clk_parent_set_rate, + }, { + .parent = &hclk_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_HCLK_CSI_REG, + .enable_shift = CCM_PCCR_HCLK_CSI_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk usb_clk[] = { + { + .parent = &spll_clk, + .get_rate = _clk_usb_recalc, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_USBOTG_REG, + .enable_shift = CCM_PCCR_USBOTG_OFFSET, + .disable = _clk_disable, + }, { + .parent = &hclk_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_HCLK_USBOTG_REG, + .enable_shift = CCM_PCCR_HCLK_USBOTG_OFFSET, + .disable = _clk_disable, + } +}; + +static struct clk ssi_ipg_clk[]; + +static struct clk ssi_clk[] = { + { + .id = 0, + .parent = &mpll_clk, + .secondary = &ssi_ipg_clk[0], + .get_rate = _clk_ssi1_recalc, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_SSI1_BAUD_REG, + .enable_shift = CCM_PCCR_SSI1_BAUD_OFFSET, + .disable = _clk_disable, + }, { + .id = 1, + .parent = &mpll_clk, + .secondary = &ssi_ipg_clk[1], + .get_rate = _clk_ssi2_recalc, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_SSI2_BAUD_REG, + .enable_shift = CCM_PCCR_SSI2_BAUD_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk ssi_ipg_clk[] = { + { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_SSI1_REG, + .enable_shift = CCM_PCCR_SSI1_IPG_OFFSET, + .disable = _clk_disable, + }, { + .id = 1, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_SSI2_REG, + .enable_shift = CCM_PCCR_SSI2_IPG_OFFSET, + .disable = _clk_disable, + }, +}; + + +static struct clk nfc_clk = { + .parent = &fclk_clk, + .get_rate = _clk_nfc_recalc, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_NFC_REG, + .enable_shift = CCM_PCCR_NFC_OFFSET, + .disable = _clk_disable, +}; + +static struct clk dma_clk[] = { + { + .parent = &hclk_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_DMA_REG, + .enable_shift = CCM_PCCR_DMA_OFFSET, + .disable = _clk_disable, + .secondary = &dma_clk[1], + }, { + .enable = _clk_enable, + .enable_reg = CCM_PCCR_HCLK_DMA_REG, + .enable_shift = CCM_PCCR_HCLK_DMA_OFFSET, + .disable = _clk_disable, + }, +}; + +static struct clk brom_clk = { + .parent = &hclk_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_HCLK_BROM_REG, + .enable_shift = CCM_PCCR_HCLK_BROM_OFFSET, + .disable = _clk_disable, +}; + +static struct clk emma_clk[] = { + { + .parent = &hclk_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_EMMA_REG, + .enable_shift = CCM_PCCR_EMMA_OFFSET, + .disable = _clk_disable, + .secondary = &emma_clk[1], + }, { + .enable = _clk_enable, + .enable_reg = CCM_PCCR_HCLK_EMMA_REG, + .enable_shift = CCM_PCCR_HCLK_EMMA_OFFSET, + .disable = _clk_disable, + } +}; + +static struct clk slcdc_clk[] = { + { + .parent = &hclk_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_SLCDC_REG, + .enable_shift = CCM_PCCR_SLCDC_OFFSET, + .disable = _clk_disable, + .secondary = &slcdc_clk[1], + }, { + .enable = _clk_enable, + .enable_reg = CCM_PCCR_HCLK_SLCDC_REG, + .enable_shift = CCM_PCCR_HCLK_SLCDC_OFFSET, + .disable = _clk_disable, + } +}; + +static struct clk wdog_clk = { + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_WDT_REG, + .enable_shift = CCM_PCCR_WDT_OFFSET, + .disable = _clk_disable, +}; + +static struct clk gpio_clk = { + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_GPIO_REG, + .enable_shift = CCM_PCCR_GPIO_OFFSET, + .disable = _clk_disable, +}; + +static struct clk i2c_clk = { + .id = 0, + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_I2C1_REG, + .enable_shift = CCM_PCCR_I2C1_OFFSET, + .disable = _clk_disable, +}; + +static struct clk kpp_clk = { + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_KPP_REG, + .enable_shift = CCM_PCCR_KPP_OFFSET, + .disable = _clk_disable, +}; + +static struct clk owire_clk = { + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_OWIRE_REG, + .enable_shift = CCM_PCCR_OWIRE_OFFSET, + .disable = _clk_disable, +}; + +static struct clk rtc_clk = { + .parent = &ipg_clk, + .enable = _clk_enable, + .enable_reg = CCM_PCCR_RTC_REG, + .enable_shift = CCM_PCCR_RTC_OFFSET, + .disable = _clk_disable, +}; + +static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate) +{ + u32 div; + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + div = parent_rate / rate; + if (parent_rate % rate) + div++; + + if (div > 8) + div = 8; + + return parent_rate / div; +} + +static int _clk_clko_set_rate(struct clk *clk, unsigned long rate) +{ + u32 reg; + u32 div; + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + + div = parent_rate / rate; + + if (div > 8 || div < 1 || ((parent_rate / div) != rate)) + return -EINVAL; + div--; + + reg = __raw_readl(CCM_PCDR0); + + if (clk->parent == &usb_clk[0]) { + reg &= ~CCM_PCDR0_48MDIV_MASK; + reg |= div << CCM_PCDR0_48MDIV_OFFSET; + } + __raw_writel(reg, CCM_PCDR0); + + return 0; +} + +static unsigned long _clk_clko_recalc(struct clk *clk) +{ + u32 div = 0; + unsigned long parent_rate; + + parent_rate = clk_get_rate(clk->parent); + + if (clk->parent == &usb_clk[0]) /* 48M */ + div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_48MDIV_MASK + >> CCM_PCDR0_48MDIV_OFFSET; + div++; + + return parent_rate / div; +} + +static struct clk clko_clk; + +static int _clk_clko_set_parent(struct clk *clk, struct clk *parent) +{ + u32 reg; + + reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK; + + if (parent == &ckil_clk) + reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &fpm_clk) + reg |= 1 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &ckih_clk) + reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == mpll_clk.parent) + reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == spll_clk.parent) + reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &mpll_clk) + reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &spll_clk) + reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &fclk_clk) + reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &hclk_clk) + reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &ipg_clk) + reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &per_clk[0]) + reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &per_clk[1]) + reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &per_clk[2]) + reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &per_clk[3]) + reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &ssi_clk[0]) + reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &ssi_clk[1]) + reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &nfc_clk) + reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &usb_clk[0]) + reg |= 0x14 << CCM_CCSR_CLKOSEL_OFFSET; + else if (parent == &clko_clk) + reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET; + else + return -EINVAL; + + __raw_writel(reg, CCM_CCSR); + + return 0; +} + +static struct clk clko_clk = { + .get_rate = _clk_clko_recalc, + .set_rate = _clk_clko_set_rate, + .round_rate = _clk_clko_round_rate, + .set_parent = _clk_clko_set_parent, +}; + + +#define _REGISTER_CLOCK(d, n, c) \ + { \ + .dev_id = d, \ + .con_id = n, \ + .clk = &c, \ + }, +static struct clk_lookup lookups[] __initdata = { +/* It's unlikely that any driver wants one of them directly: + _REGISTER_CLOCK(NULL, "ckih", ckih_clk) + _REGISTER_CLOCK(NULL, "ckil", ckil_clk) + _REGISTER_CLOCK(NULL, "fpm", fpm_clk) + _REGISTER_CLOCK(NULL, "mpll", mpll_clk) + _REGISTER_CLOCK(NULL, "spll", spll_clk) + _REGISTER_CLOCK(NULL, "fclk", fclk_clk) + _REGISTER_CLOCK(NULL, "hclk", hclk_clk) + _REGISTER_CLOCK(NULL, "ipg", ipg_clk) +*/ + _REGISTER_CLOCK(NULL, "perclk1", per_clk[0]) + _REGISTER_CLOCK(NULL, "perclk2", per_clk[1]) + _REGISTER_CLOCK(NULL, "perclk3", per_clk[2]) + _REGISTER_CLOCK(NULL, "perclk4", per_clk[3]) + _REGISTER_CLOCK(NULL, "clko", clko_clk) + _REGISTER_CLOCK("imx-uart.0", NULL, uart_clk[0]) + _REGISTER_CLOCK("imx-uart.1", NULL, uart_clk[1]) + _REGISTER_CLOCK("imx-uart.2", NULL, uart_clk[2]) + _REGISTER_CLOCK("imx-uart.3", NULL, uart_clk[3]) + _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[0]) + _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[1]) + _REGISTER_CLOCK(NULL, "gpt1", gpt_clk[2]) + _REGISTER_CLOCK(NULL, "pwm", pwm_clk[0]) + _REGISTER_CLOCK(NULL, "sdhc1", sdhc_clk[0]) + _REGISTER_CLOCK(NULL, "sdhc2", sdhc_clk[1]) + _REGISTER_CLOCK(NULL, "cspi1", cspi_clk[0]) + _REGISTER_CLOCK(NULL, "cspi2", cspi_clk[1]) + _REGISTER_CLOCK(NULL, "cspi3", cspi_clk[2]) + _REGISTER_CLOCK(NULL, "lcdc", lcdc_clk[0]) + _REGISTER_CLOCK(NULL, "csi", csi_clk[0]) + _REGISTER_CLOCK(NULL, "usb", usb_clk[0]) + _REGISTER_CLOCK(NULL, "ssi1", ssi_clk[0]) + _REGISTER_CLOCK(NULL, "ssi2", ssi_clk[1]) + _REGISTER_CLOCK(NULL, "nfc", nfc_clk) + _REGISTER_CLOCK(NULL, "dma", dma_clk[0]) + _REGISTER_CLOCK(NULL, "brom", brom_clk) + _REGISTER_CLOCK(NULL, "emma", emma_clk[0]) + _REGISTER_CLOCK(NULL, "slcdc", slcdc_clk[0]) + _REGISTER_CLOCK(NULL, "wdog", wdog_clk) + _REGISTER_CLOCK(NULL, "gpio", gpio_clk) + _REGISTER_CLOCK(NULL, "i2c", i2c_clk) + _REGISTER_CLOCK("mxc-keypad", NULL, kpp_clk) + _REGISTER_CLOCK(NULL, "owire", owire_clk) + _REGISTER_CLOCK(NULL, "rtc", rtc_clk) +}; + +/* + * must be called very early to get information about the + * available clock rate when the timer framework starts + */ +int __init mx21_clocks_init(unsigned long lref, unsigned long href) +{ + int i; + u32 cscr; + + external_low_reference = lref; + external_high_reference = href; + + /* detect clock reference for both system PLL */ + cscr = CSCR(); + if (cscr & CCM_CSCR_MCU) + mpll_clk.parent = &ckih_clk; + else + mpll_clk.parent = &fpm_clk; + + if (cscr & CCM_CSCR_SP) + spll_clk.parent = &ckih_clk; + else + spll_clk.parent = &fpm_clk; + + for (i = 0; i < ARRAY_SIZE(lookups); i++) + clkdev_add(&lookups[i]); + + /* Turn off all clock gates */ + __raw_writel(0, CCM_PCCR0); + __raw_writel(CCM_PCCR_GPT1_MASK, CCM_PCCR1); + + /* This turns of the serial PLL as well */ + spll_clk.disable(&spll_clk); + + /* This will propagate to all children and init all the clock rates. */ + clk_enable(&per_clk[0]); + clk_enable(&gpio_clk); + +#ifdef CONFIG_DEBUG_LL_CONSOLE + clk_enable(&uart_clk[0]); +#endif + + mxc_timer_init(&gpt_clk[0]); + return 0; +} diff --git a/arch/arm/mach-mx2/crm_regs.h b/arch/arm/mach-mx2/crm_regs.h new file mode 100644 index 000000000000..749de76b3f95 --- /dev/null +++ b/arch/arm/mach-mx2/crm_regs.h @@ -0,0 +1,258 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * + * 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. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef __ARCH_ARM_MACH_MX2_CRM_REGS_H__ +#define __ARCH_ARM_MACH_MX2_CRM_REGS_H__ + +#include + +/* Register offsets */ +#define CCM_CSCR (IO_ADDRESS(CCM_BASE_ADDR) + 0x0) +#define CCM_MPCTL0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x4) +#define CCM_MPCTL1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x8) +#define CCM_SPCTL0 (IO_ADDRESS(CCM_BASE_ADDR) + 0xC) +#define CCM_SPCTL1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x10) +#define CCM_OSC26MCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x14) +#define CCM_PCDR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x18) +#define CCM_PCDR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x1c) +#define CCM_PCCR0 (IO_ADDRESS(CCM_BASE_ADDR) + 0x20) +#define CCM_PCCR1 (IO_ADDRESS(CCM_BASE_ADDR) + 0x24) +#define CCM_CCSR (IO_ADDRESS(CCM_BASE_ADDR) + 0x28) +#define CCM_PMCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x2c) +#define CCM_PMCOUNT (IO_ADDRESS(CCM_BASE_ADDR) + 0x30) +#define CCM_WKGDCTL (IO_ADDRESS(CCM_BASE_ADDR) + 0x34) + +#define CCM_CSCR_PRESC_OFFSET 29 +#define CCM_CSCR_PRESC_MASK (0x7 << CCM_CSCR_PRESC_OFFSET) + +#define CCM_CSCR_USB_OFFSET 26 +#define CCM_CSCR_USB_MASK (0x7 << CCM_CSCR_USB_OFFSET) +#define CCM_CSCR_SD_OFFSET 24 +#define CCM_CSCR_SD_MASK (0x3 << CCM_CSCR_SD_OFFSET) +#define CCM_CSCR_SPLLRES (1 << 22) +#define CCM_CSCR_MPLLRES (1 << 21) +#define CCM_CSCR_SSI2_OFFSET 20 +#define CCM_CSCR_SSI2 (1 << CCM_CSCR_SSI2_OFFSET) +#define CCM_CSCR_SSI1_OFFSET 19 +#define CCM_CSCR_SSI1 (1 << CCM_CSCR_SSI1_OFFSET) +#define CCM_CSCR_FIR_OFFSET 18 +#define CCM_CSCR_FIR (1 << CCM_CSCR_FIR_OFFSET) +#define CCM_CSCR_SP (1 << 17) +#define CCM_CSCR_MCU (1 << 16) +#define CCM_CSCR_BCLK_OFFSET 10 +#define CCM_CSCR_BCLK_MASK (0xf << CCM_CSCR_BCLK_OFFSET) +#define CCM_CSCR_IPDIV_OFFSET 9 +#define CCM_CSCR_IPDIV (1 << CCM_CSCR_IPDIV_OFFSET) + +#define CCM_CSCR_OSC26MDIV (1 << 4) +#define CCM_CSCR_OSC26M (1 << 3) +#define CCM_CSCR_FPM (1 << 2) +#define CCM_CSCR_SPEN (1 << 1) +#define CCM_CSCR_MPEN 1 + + + +#define CCM_MPCTL0_CPLM (1 << 31) +#define CCM_MPCTL0_PD_OFFSET 26 +#define CCM_MPCTL0_PD_MASK (0xf << 26) +#define CCM_MPCTL0_MFD_OFFSET 16 +#define CCM_MPCTL0_MFD_MASK (0x3ff << 16) +#define CCM_MPCTL0_MFI_OFFSET 10 +#define CCM_MPCTL0_MFI_MASK (0xf << 10) +#define CCM_MPCTL0_MFN_OFFSET 0 +#define CCM_MPCTL0_MFN_MASK 0x3ff + +#define CCM_MPCTL1_LF (1 << 15) +#define CCM_MPCTL1_BRMO (1 << 6) + +#define CCM_SPCTL0_CPLM (1 << 31) +#define CCM_SPCTL0_PD_OFFSET 26 +#define CCM_SPCTL0_PD_MASK (0xf << 26) +#define CCM_SPCTL0_MFD_OFFSET 16 +#define CCM_SPCTL0_MFD_MASK (0x3ff << 16) +#define CCM_SPCTL0_MFI_OFFSET 10 +#define CCM_SPCTL0_MFI_MASK (0xf << 10) +#define CCM_SPCTL0_MFN_OFFSET 0 +#define CCM_SPCTL0_MFN_MASK 0x3ff + +#define CCM_SPCTL1_LF (1 << 15) +#define CCM_SPCTL1_BRMO (1 << 6) + +#define CCM_OSC26MCTL_PEAK_OFFSET 16 +#define CCM_OSC26MCTL_PEAK_MASK (0x3 << 16) +#define CCM_OSC26MCTL_AGC_OFFSET 8 +#define CCM_OSC26MCTL_AGC_MASK (0x3f << 8) +#define CCM_OSC26MCTL_ANATEST_OFFSET 0 +#define CCM_OSC26MCTL_ANATEST_MASK 0x3f + +#define CCM_PCDR0_SSI2BAUDDIV_OFFSET 26 +#define CCM_PCDR0_SSI2BAUDDIV_MASK (0x3f << 26) +#define CCM_PCDR0_SSI1BAUDDIV_OFFSET 16 +#define CCM_PCDR0_SSI1BAUDDIV_MASK (0x3f << 16) +#define CCM_PCDR0_NFCDIV_OFFSET 12 +#define CCM_PCDR0_NFCDIV_MASK (0xf << 12) +#define CCM_PCDR0_48MDIV_OFFSET 5 +#define CCM_PCDR0_48MDIV_MASK (0x7 << CCM_PCDR0_48MDIV_OFFSET) +#define CCM_PCDR0_FIRIDIV_OFFSET 0 +#define CCM_PCDR0_FIRIDIV_MASK 0x1f +#define CCM_PCDR1_PERDIV4_OFFSET 24 +#define CCM_PCDR1_PERDIV4_MASK (0x3f << 24) +#define CCM_PCDR1_PERDIV3_OFFSET 16 +#define CCM_PCDR1_PERDIV3_MASK (0x3f << 16) +#define CCM_PCDR1_PERDIV2_OFFSET 8 +#define CCM_PCDR1_PERDIV2_MASK (0x3f << 8) +#define CCM_PCDR1_PERDIV1_OFFSET 0 +#define CCM_PCDR1_PERDIV1_MASK 0x3f + +#define CCM_PCCR_HCLK_CSI_OFFSET 31 +#define CCM_PCCR_HCLK_CSI_REG CCM_PCCR0 +#define CCM_PCCR_HCLK_DMA_OFFSET 30 +#define CCM_PCCR_HCLK_DMA_REG CCM_PCCR0 +#define CCM_PCCR_HCLK_BROM_OFFSET 28 +#define CCM_PCCR_HCLK_BROM_REG CCM_PCCR0 +#define CCM_PCCR_HCLK_EMMA_OFFSET 27 +#define CCM_PCCR_HCLK_EMMA_REG CCM_PCCR0 +#define CCM_PCCR_HCLK_LCDC_OFFSET 26 +#define CCM_PCCR_HCLK_LCDC_REG CCM_PCCR0 +#define CCM_PCCR_HCLK_SLCDC_OFFSET 25 +#define CCM_PCCR_HCLK_SLCDC_REG CCM_PCCR0 +#define CCM_PCCR_HCLK_USBOTG_OFFSET 24 +#define CCM_PCCR_HCLK_USBOTG_REG CCM_PCCR0 +#define CCM_PCCR_HCLK_BMI_OFFSET 23 +#define CCM_PCCR_BMI_MASK (1 << CCM_PCCR_BMI_MASK) +#define CCM_PCCR_HCLK_BMI_REG CCM_PCCR0 +#define CCM_PCCR_PERCLK4_OFFSET 22 +#define CCM_PCCR_PERCLK4_REG CCM_PCCR0 +#define CCM_PCCR_SLCDC_OFFSET 21 +#define CCM_PCCR_SLCDC_REG CCM_PCCR0 +#define CCM_PCCR_FIRI_BAUD_OFFSET 20 +#define CCM_PCCR_FIRI_BAUD_MASK (1 << CCM_PCCR_FIRI_BAUD_MASK) +#define CCM_PCCR_FIRI_BAUD_REG CCM_PCCR0 +#define CCM_PCCR_NFC_OFFSET 19 +#define CCM_PCCR_NFC_REG CCM_PCCR0 +#define CCM_PCCR_LCDC_OFFSET 18 +#define CCM_PCCR_LCDC_REG CCM_PCCR0 +#define CCM_PCCR_SSI1_BAUD_OFFSET 17 +#define CCM_PCCR_SSI1_BAUD_REG CCM_PCCR0 +#define CCM_PCCR_SSI2_BAUD_OFFSET 16 +#define CCM_PCCR_SSI2_BAUD_REG CCM_PCCR0 +#define CCM_PCCR_EMMA_OFFSET 15 +#define CCM_PCCR_EMMA_REG CCM_PCCR0 +#define CCM_PCCR_USBOTG_OFFSET 14 +#define CCM_PCCR_USBOTG_REG CCM_PCCR0 +#define CCM_PCCR_DMA_OFFSET 13 +#define CCM_PCCR_DMA_REG CCM_PCCR0 +#define CCM_PCCR_I2C1_OFFSET 12 +#define CCM_PCCR_I2C1_REG CCM_PCCR0 +#define CCM_PCCR_GPIO_OFFSET 11 +#define CCM_PCCR_GPIO_REG CCM_PCCR0 +#define CCM_PCCR_SDHC2_OFFSET 10 +#define CCM_PCCR_SDHC2_REG CCM_PCCR0 +#define CCM_PCCR_SDHC1_OFFSET 9 +#define CCM_PCCR_SDHC1_REG CCM_PCCR0 +#define CCM_PCCR_FIRI_OFFSET 8 +#define CCM_PCCR_FIRI_MASK (1 << CCM_PCCR_BAUD_MASK) +#define CCM_PCCR_FIRI_REG CCM_PCCR0 +#define CCM_PCCR_SSI2_IPG_OFFSET 7 +#define CCM_PCCR_SSI2_REG CCM_PCCR0 +#define CCM_PCCR_SSI1_IPG_OFFSET 6 +#define CCM_PCCR_SSI1_REG CCM_PCCR0 +#define CCM_PCCR_CSPI2_OFFSET 5 +#define CCM_PCCR_CSPI2_REG CCM_PCCR0 +#define CCM_PCCR_CSPI1_OFFSET 4 +#define CCM_PCCR_CSPI1_REG CCM_PCCR0 +#define CCM_PCCR_UART4_OFFSET 3 +#define CCM_PCCR_UART4_REG CCM_PCCR0 +#define CCM_PCCR_UART3_OFFSET 2 +#define CCM_PCCR_UART3_REG CCM_PCCR0 +#define CCM_PCCR_UART2_OFFSET 1 +#define CCM_PCCR_UART2_REG CCM_PCCR0 +#define CCM_PCCR_UART1_OFFSET 0 +#define CCM_PCCR_UART1_REG CCM_PCCR0 + +#define CCM_PCCR_OWIRE_OFFSET 31 +#define CCM_PCCR_OWIRE_REG CCM_PCCR1 +#define CCM_PCCR_KPP_OFFSET 30 +#define CCM_PCCR_KPP_REG CCM_PCCR1 +#define CCM_PCCR_RTC_OFFSET 29 +#define CCM_PCCR_RTC_REG CCM_PCCR1 +#define CCM_PCCR_PWM_OFFSET 28 +#define CCM_PCCR_PWM_REG CCM_PCCR1 +#define CCM_PCCR_GPT3_OFFSET 27 +#define CCM_PCCR_GPT3_REG CCM_PCCR1 +#define CCM_PCCR_GPT2_OFFSET 26 +#define CCM_PCCR_GPT2_REG CCM_PCCR1 +#define CCM_PCCR_GPT1_OFFSET 25 +#define CCM_PCCR_GPT1_REG CCM_PCCR1 +#define CCM_PCCR_WDT_OFFSET 24 +#define CCM_PCCR_WDT_REG CCM_PCCR1 +#define CCM_PCCR_CSPI3_OFFSET 23 +#define CCM_PCCR_CSPI3_REG CCM_PCCR1 + +#define CCM_PCCR_CSPI1_MASK (1 << CCM_PCCR_CSPI1_OFFSET) +#define CCM_PCCR_CSPI2_MASK (1 << CCM_PCCR_CSPI2_OFFSET) +#define CCM_PCCR_CSPI3_MASK (1 << CCM_PCCR_CSPI3_OFFSET) +#define CCM_PCCR_DMA_MASK (1 << CCM_PCCR_DMA_OFFSET) +#define CCM_PCCR_EMMA_MASK (1 << CCM_PCCR_EMMA_OFFSET) +#define CCM_PCCR_GPIO_MASK (1 << CCM_PCCR_GPIO_OFFSET) +#define CCM_PCCR_GPT1_MASK (1 << CCM_PCCR_GPT1_OFFSET) +#define CCM_PCCR_GPT2_MASK (1 << CCM_PCCR_GPT2_OFFSET) +#define CCM_PCCR_GPT3_MASK (1 << CCM_PCCR_GPT3_OFFSET) +#define CCM_PCCR_HCLK_BROM_MASK (1 << CCM_PCCR_HCLK_BROM_OFFSET) +#define CCM_PCCR_HCLK_CSI_MASK (1 << CCM_PCCR_HCLK_CSI_OFFSET) +#define CCM_PCCR_HCLK_DMA_MASK (1 << CCM_PCCR_HCLK_DMA_OFFSET) +#define CCM_PCCR_HCLK_EMMA_MASK (1 << CCM_PCCR_HCLK_EMMA_OFFSET) +#define CCM_PCCR_HCLK_LCDC_MASK (1 << CCM_PCCR_HCLK_LCDC_OFFSET) +#define CCM_PCCR_HCLK_SLCDC_MASK (1 << CCM_PCCR_HCLK_SLCDC_OFFSET) +#define CCM_PCCR_HCLK_USBOTG_MASK (1 << CCM_PCCR_HCLK_USBOTG_OFFSET) +#define CCM_PCCR_I2C1_MASK (1 << CCM_PCCR_I2C1_OFFSET) +#define CCM_PCCR_KPP_MASK (1 << CCM_PCCR_KPP_OFFSET) +#define CCM_PCCR_LCDC_MASK (1 << CCM_PCCR_LCDC_OFFSET) +#define CCM_PCCR_NFC_MASK (1 << CCM_PCCR_NFC_OFFSET) +#define CCM_PCCR_OWIRE_MASK (1 << CCM_PCCR_OWIRE_OFFSET) +#define CCM_PCCR_PERCLK4_MASK (1 << CCM_PCCR_PERCLK4_OFFSET) +#define CCM_PCCR_PWM_MASK (1 << CCM_PCCR_PWM_OFFSET) +#define CCM_PCCR_RTC_MASK (1 << CCM_PCCR_RTC_OFFSET) +#define CCM_PCCR_SDHC1_MASK (1 << CCM_PCCR_SDHC1_OFFSET) +#define CCM_PCCR_SDHC2_MASK (1 << CCM_PCCR_SDHC2_OFFSET) +#define CCM_PCCR_SLCDC_MASK (1 << CCM_PCCR_SLCDC_OFFSET) +#define CCM_PCCR_SSI1_BAUD_MASK (1 << CCM_PCCR_SSI1_BAUD_OFFSET) +#define CCM_PCCR_SSI1_IPG_MASK (1 << CCM_PCCR_SSI1_IPG_OFFSET) +#define CCM_PCCR_SSI2_BAUD_MASK (1 << CCM_PCCR_SSI2_BAUD_OFFSET) +#define CCM_PCCR_SSI2_IPG_MASK (1 << CCM_PCCR_SSI2_IPG_OFFSET) +#define CCM_PCCR_UART1_MASK (1 << CCM_PCCR_UART1_OFFSET) +#define CCM_PCCR_UART2_MASK (1 << CCM_PCCR_UART2_OFFSET) +#define CCM_PCCR_UART3_MASK (1 << CCM_PCCR_UART3_OFFSET) +#define CCM_PCCR_UART4_MASK (1 << CCM_PCCR_UART4_OFFSET) +#define CCM_PCCR_USBOTG_MASK (1 << CCM_PCCR_USBOTG_OFFSET) +#define CCM_PCCR_WDT_MASK (1 << CCM_PCCR_WDT_OFFSET) + + +#define CCM_CCSR_32KSR (1 << 15) + +#define CCM_CCSR_CLKMODE1 (1 << 9) +#define CCM_CCSR_CLKMODE0 (1 << 8) + +#define CCM_CCSR_CLKOSEL_OFFSET 0 +#define CCM_CCSR_CLKOSEL_MASK 0x1f + +#define SYS_FMCR 0x14 /* Functional Muxing Control Reg */ +#define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */ + +#endif /* __ARCH_ARM_MACH_MX2_CRM_REGS_H__ */ diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h index 2c08b8e14e39..3051eee99530 100644 --- a/arch/arm/plat-mxc/include/mach/common.h +++ b/arch/arm/plat-mxc/include/mach/common.h @@ -18,6 +18,7 @@ extern void mxc_map_io(void); extern void mxc_init_irq(void); extern void mxc_timer_init(struct clk *timer_clk); extern int mx1_clocks_init(unsigned long fref); +extern int mx21_clocks_init(unsigned long lref, unsigned long fref); extern int mx27_clocks_init(unsigned long fref); extern int mx31_clocks_init(unsigned long fref); extern int mxc_register_gpios(void); -- cgit v1.2.3 From e48135519bd569eed374e0e17ed5233d4105fa97 Mon Sep 17 00:00:00 2001 From: Holger Schurig Date: Mon, 26 Jan 2009 16:34:56 +0100 Subject: arm/imx21: Framebuffer support for i.MX21 This patch mimicks what Martin wrote on the mailing list: * move arch/arm/mach-imx/include/mach/imxfb.h into arch/arm/mach-mxc/include/mach/imxfb.h * changes Kconfig so that CONFIG_FB_IMX is selectable * adds a platform device (copied from some pengutronix patches) Signed-off-by: Holger Schurig Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/include/mach/imxfb.h | 83 ---------------------------------- arch/arm/mach-mx2/devices.c | 33 ++++++++++++++ arch/arm/mach-mx2/devices.h | 2 +- arch/arm/plat-mxc/include/mach/imxfb.h | 83 ++++++++++++++++++++++++++++++++++ drivers/video/Kconfig | 2 +- 5 files changed, 118 insertions(+), 85 deletions(-) delete mode 100644 arch/arm/mach-imx/include/mach/imxfb.h create mode 100644 arch/arm/plat-mxc/include/mach/imxfb.h (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/mach-imx/include/mach/imxfb.h b/arch/arm/mach-imx/include/mach/imxfb.h deleted file mode 100644 index 870d0d939616..000000000000 --- a/arch/arm/mach-imx/include/mach/imxfb.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * This structure describes the machine which we are running on. - */ - -#define PCR_TFT (1 << 31) -#define PCR_COLOR (1 << 30) -#define PCR_PBSIZ_1 (0 << 28) -#define PCR_PBSIZ_2 (1 << 28) -#define PCR_PBSIZ_4 (2 << 28) -#define PCR_PBSIZ_8 (3 << 28) -#define PCR_BPIX_1 (0 << 25) -#define PCR_BPIX_2 (1 << 25) -#define PCR_BPIX_4 (2 << 25) -#define PCR_BPIX_8 (3 << 25) -#define PCR_BPIX_12 (4 << 25) -#define PCR_BPIX_16 (4 << 25) -#define PCR_PIXPOL (1 << 24) -#define PCR_FLMPOL (1 << 23) -#define PCR_LPPOL (1 << 22) -#define PCR_CLKPOL (1 << 21) -#define PCR_OEPOL (1 << 20) -#define PCR_SCLKIDLE (1 << 19) -#define PCR_END_SEL (1 << 18) -#define PCR_END_BYTE_SWAP (1 << 17) -#define PCR_REV_VS (1 << 16) -#define PCR_ACD_SEL (1 << 15) -#define PCR_ACD(x) (((x) & 0x7f) << 8) -#define PCR_SCLK_SEL (1 << 7) -#define PCR_SHARP (1 << 6) -#define PCR_PCD(x) ((x) & 0x3f) - -#define PWMR_CLS(x) (((x) & 0x1ff) << 16) -#define PWMR_LDMSK (1 << 15) -#define PWMR_SCR1 (1 << 10) -#define PWMR_SCR0 (1 << 9) -#define PWMR_CC_EN (1 << 8) -#define PWMR_PW(x) ((x) & 0xff) - -#define LSCR1_PS_RISE_DELAY(x) (((x) & 0x7f) << 26) -#define LSCR1_CLS_RISE_DELAY(x) (((x) & 0x3f) << 16) -#define LSCR1_REV_TOGGLE_DELAY(x) (((x) & 0xf) << 8) -#define LSCR1_GRAY2(x) (((x) & 0xf) << 4) -#define LSCR1_GRAY1(x) (((x) & 0xf)) - -#define DMACR_BURST (1 << 31) -#define DMACR_HM(x) (((x) & 0xf) << 16) -#define DMACR_TM(x) ((x) & 0xf) - -struct imx_fb_platform_data { - u_long pixclock; - - u_short xres; - u_short yres; - - u_int nonstd; - u_char bpp; - u_char hsync_len; - u_char left_margin; - u_char right_margin; - - u_char vsync_len; - u_char upper_margin; - u_char lower_margin; - u_char sync; - - u_int cmap_greyscale:1, - cmap_inverse:1, - cmap_static:1, - unused:29; - - u_int pcr; - u_int pwmr; - u_int lscr1; - u_int dmacr; - - u_char * fixed_screen_cpu; - dma_addr_t fixed_screen_dma; - - void (*lcd_power)(int); - void (*backlight_power)(int); -}; - -void set_imx_fb_info(struct imx_fb_platform_data *); diff --git a/arch/arm/mach-mx2/devices.c b/arch/arm/mach-mx2/devices.c index 9ddd6d061058..07061e644545 100644 --- a/arch/arm/mach-mx2/devices.c +++ b/arch/arm/mach-mx2/devices.c @@ -228,6 +228,39 @@ struct platform_device mxc_nand_device = { .resource = mxc_nand_resources, }; +#ifdef CONFIG_FB_IMX +/* + * lcdc: + * - i.MX1: the basic controller + * - i.MX21: to be checked + * - i.MX27: like i.MX1, with slightly variations + */ +static struct resource mxc_fb[] = { + { + .start = LCDC_BASE_ADDR, + .end = LCDC_BASE_ADDR + 0xFFF, + .flags = IORESOURCE_MEM, + }, + { + .start = MXC_INT_LCDC, + .end = MXC_INT_LCDC, + .flags = IORESOURCE_IRQ, + } +}; + +/* mxc lcd driver */ +struct platform_device mxc_fb_device = { + .name = "imx-fb", + .id = 0, + .num_resources = ARRAY_SIZE(mxc_fb), + .resource = mxc_fb, + .dev = { + .coherent_dma_mask = 0xFFFFFFFF, + }, +}; + +#endif + /* GPIO port description */ static struct mxc_gpio_port imx_gpio_ports[] = { [0] = { diff --git a/arch/arm/mach-mx2/devices.h b/arch/arm/mach-mx2/devices.h index 1e8cb577a642..f4cb0ce29f13 100644 --- a/arch/arm/mach-mx2/devices.h +++ b/arch/arm/mach-mx2/devices.h @@ -1,4 +1,3 @@ - extern struct platform_device mxc_gpt1; extern struct platform_device mxc_gpt2; extern struct platform_device mxc_gpt3; @@ -14,3 +13,4 @@ extern struct platform_device mxc_uart_device4; extern struct platform_device mxc_uart_device5; extern struct platform_device mxc_w1_master_device; extern struct platform_device mxc_nand_device; +extern struct platform_device mxc_fb_device; diff --git a/arch/arm/plat-mxc/include/mach/imxfb.h b/arch/arm/plat-mxc/include/mach/imxfb.h new file mode 100644 index 000000000000..870d0d939616 --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/imxfb.h @@ -0,0 +1,83 @@ +/* + * This structure describes the machine which we are running on. + */ + +#define PCR_TFT (1 << 31) +#define PCR_COLOR (1 << 30) +#define PCR_PBSIZ_1 (0 << 28) +#define PCR_PBSIZ_2 (1 << 28) +#define PCR_PBSIZ_4 (2 << 28) +#define PCR_PBSIZ_8 (3 << 28) +#define PCR_BPIX_1 (0 << 25) +#define PCR_BPIX_2 (1 << 25) +#define PCR_BPIX_4 (2 << 25) +#define PCR_BPIX_8 (3 << 25) +#define PCR_BPIX_12 (4 << 25) +#define PCR_BPIX_16 (4 << 25) +#define PCR_PIXPOL (1 << 24) +#define PCR_FLMPOL (1 << 23) +#define PCR_LPPOL (1 << 22) +#define PCR_CLKPOL (1 << 21) +#define PCR_OEPOL (1 << 20) +#define PCR_SCLKIDLE (1 << 19) +#define PCR_END_SEL (1 << 18) +#define PCR_END_BYTE_SWAP (1 << 17) +#define PCR_REV_VS (1 << 16) +#define PCR_ACD_SEL (1 << 15) +#define PCR_ACD(x) (((x) & 0x7f) << 8) +#define PCR_SCLK_SEL (1 << 7) +#define PCR_SHARP (1 << 6) +#define PCR_PCD(x) ((x) & 0x3f) + +#define PWMR_CLS(x) (((x) & 0x1ff) << 16) +#define PWMR_LDMSK (1 << 15) +#define PWMR_SCR1 (1 << 10) +#define PWMR_SCR0 (1 << 9) +#define PWMR_CC_EN (1 << 8) +#define PWMR_PW(x) ((x) & 0xff) + +#define LSCR1_PS_RISE_DELAY(x) (((x) & 0x7f) << 26) +#define LSCR1_CLS_RISE_DELAY(x) (((x) & 0x3f) << 16) +#define LSCR1_REV_TOGGLE_DELAY(x) (((x) & 0xf) << 8) +#define LSCR1_GRAY2(x) (((x) & 0xf) << 4) +#define LSCR1_GRAY1(x) (((x) & 0xf)) + +#define DMACR_BURST (1 << 31) +#define DMACR_HM(x) (((x) & 0xf) << 16) +#define DMACR_TM(x) ((x) & 0xf) + +struct imx_fb_platform_data { + u_long pixclock; + + u_short xres; + u_short yres; + + u_int nonstd; + u_char bpp; + u_char hsync_len; + u_char left_margin; + u_char right_margin; + + u_char vsync_len; + u_char upper_margin; + u_char lower_margin; + u_char sync; + + u_int cmap_greyscale:1, + cmap_inverse:1, + cmap_static:1, + unused:29; + + u_int pcr; + u_int pwmr; + u_int lscr1; + u_int dmacr; + + u_char * fixed_screen_cpu; + dma_addr_t fixed_screen_dma; + + void (*lcd_power)(int); + void (*backlight_power)(int); +}; + +void set_imx_fb_info(struct imx_fb_platform_data *); diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index fb19803060cf..967ac3d359a6 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -397,7 +397,7 @@ config FB_SA1100 config FB_IMX tristate "Motorola i.MX LCD support" - depends on FB && ARM && ARCH_IMX + depends on FB && (ARCH_IMX || ARCH_MX2) select FB_CFB_FILLRECT select FB_CFB_COPYAREA select FB_CFB_IMAGEBLIT -- cgit v1.2.3 From 4d5f9cdacb74d35b4e435cb66443da203d8be6f0 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 15 Jan 2009 16:14:28 +0000 Subject: mx31ads: Fix build for missing mx31.h Several of the macros in mx31ads.h depend on mx31.h which is no longer included in quite so many standard headers as it once was. Include it directly so we can build. Signed-off-by: Mark Brown Signed-off-by: Sascha Hauer --- arch/arm/plat-mxc/include/mach/board-mx31ads.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/plat-mxc/include/mach/board-mx31ads.h b/arch/arm/plat-mxc/include/mach/board-mx31ads.h index 451d510d08c3..318c72ada13d 100644 --- a/arch/arm/plat-mxc/include/mach/board-mx31ads.h +++ b/arch/arm/plat-mxc/include/mach/board-mx31ads.h @@ -11,6 +11,8 @@ #ifndef __ASM_ARCH_MXC_BOARD_MX31ADS_H__ #define __ASM_ARCH_MXC_BOARD_MX31ADS_H__ +#include + /* Base address of PBC controller */ #define PBC_BASE_ADDRESS IO_ADDRESS(CS4_BASE_ADDR) /* Offsets for the PBC Controller register */ -- cgit v1.2.3 From b7222631c3d0fd26e6d85dd78b1d0aa10dc64929 Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Wed, 28 Jan 2009 15:13:50 +0100 Subject: mx31: rework of iomux support This new implemenatation avoids that two physical pins are claimed by the same driver (also with the the gpr hardware modes). The gpio kernel lib is also called when a capable gpio pin is assigned its gpio function. The mxc_iomux_mode function is still here for backward compatibility but should not be used anymore. V2: In the precendent revision, the iomux code was claiming a pin when its hardware mode was changed. This was uncorrect: when the hardware mode is changed, the pin must still be claimed through the iomux. In order to have a pin working in mode hw2, we must fist issue the mxc_iomux_set_gpr call and then the corresponding mxc_iomux_mode calls with the FUNC mode (usually done with mxc_iomux_setup_multiple_pins). The reverse calls must be done to fee the pins. Signed-off-by: Valentin Longchamp Signed-off-by: Sascha Hauer --- arch/arm/mach-mx3/iomux.c | 88 ++++++++++++++++++++++++++++-- arch/arm/plat-mxc/include/mach/iomux-mx3.h | 45 ++++++++++++--- 2 files changed, 122 insertions(+), 11 deletions(-) (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/mach-mx3/iomux.c b/arch/arm/mach-mx3/iomux.c index 7a5088b519a8..40ffc5a664d9 100644 --- a/arch/arm/mach-mx3/iomux.c +++ b/arch/arm/mach-mx3/iomux.c @@ -1,6 +1,7 @@ /* * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved. * Copyright (C) 2008 by Sascha Hauer + * Copyright (C) 2009 by Valentin Longchamp * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -21,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +40,8 @@ static DEFINE_SPINLOCK(gpio_mux_lock); #define IOMUX_REG_MASK (IOMUX_PADNUM_MASK & ~0x3) + +unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG]; /* * set the mode for a IOMUX pin. */ @@ -50,9 +54,6 @@ int mxc_iomux_mode(unsigned int pin_mode) field = pin_mode & 0x3; mode = (pin_mode & IOMUX_MODE_MASK) >> IOMUX_MODE_SHIFT; - pr_debug("%s: reg offset = 0x%x field = %d mode = 0x%02x\n", - __func__, (pin_mode & IOMUX_REG_MASK), field, mode); - spin_lock(&gpio_mux_lock); l = __raw_readl(reg); @@ -92,6 +93,86 @@ void mxc_iomux_set_pad(enum iomux_pins pin, u32 config) } EXPORT_SYMBOL(mxc_iomux_set_pad); +/* + * setups a single pin: + * - reserves the pin so that it is not claimed by another driver + * - setups the iomux according to the configuration + * - if the pin is configured as a GPIO, we claim it through kernel gpiolib + */ +int mxc_iomux_setup_pin(const unsigned int pin, const char *label) +{ + unsigned pad = pin & IOMUX_PADNUM_MASK; + unsigned gpio; + + if (pad >= (PIN_MAX + 1)) { + printk(KERN_ERR "mxc_iomux: Attempt to request nonexistant pin %u for \"%s\"\n", + pad, label ? label : "?"); + return -EINVAL; + } + + if (test_and_set_bit(pad, mxc_pin_alloc_map)) { + printk(KERN_ERR "mxc_iomux: pin %u already used. Allocation for \"%s\" failed\n", + pad, label ? label : "?"); + return -EINVAL; + } + mxc_iomux_mode(pin); + + /* if we have a gpio, we can allocate it */ + gpio = (pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT; + if (gpio < (GPIO_PORT_MAX + 1) * 32) + if (gpio_request(gpio, label)) + return -EINVAL; + + return 0; +} +EXPORT_SYMBOL(mxc_iomux_setup_pin); + +int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count, + const char *label) +{ + unsigned int *p = pin_list; + int i; + int ret = -EINVAL; + + for (i = 0; i < count; i++) { + if (mxc_iomux_setup_pin(*p, label)) + goto setup_error; + p++; + } + return 0; + +setup_error: + mxc_iomux_release_multiple_pins(pin_list, i); + return ret; +} +EXPORT_SYMBOL(mxc_iomux_setup_multiple_pins); + +void mxc_iomux_release_pin(const unsigned int pin) +{ + unsigned pad = pin & IOMUX_PADNUM_MASK; + unsigned gpio; + + if (pad < (PIN_MAX + 1)) + clear_bit(pad, mxc_pin_alloc_map); + + gpio = (pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT; + if (gpio < (GPIO_PORT_MAX + 1) * 32) + gpio_free(gpio); +} +EXPORT_SYMBOL(mxc_iomux_release_pin); + +void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count) +{ + unsigned int *p = pin_list; + int i; + + for (i = 0; i < count; i++) { + mxc_iomux_release_pin(*p); + p++; + } +} +EXPORT_SYMBOL(mxc_iomux_release_multiple_pins); + /* * This function enables/disables the general purpose function for a particular * signal. @@ -111,4 +192,3 @@ void mxc_iomux_set_gpr(enum iomux_gp_func gp, bool en) spin_unlock(&gpio_mux_lock); } EXPORT_SYMBOL(mxc_iomux_set_gpr); - diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/arch/arm/plat-mxc/include/mach/iomux-mx3.h index c9198c0aea18..4bdc4712be1d 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx3.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx3.h @@ -92,7 +92,7 @@ enum iomux_gp_func { MUX_EXTDMAREQ2_MBX_SEL = 1 << 15, MUX_TAMPER_DETECT_EN = 1 << 16, MUX_PGP_USB_4WIRE = 1 << 17, - MUX_PGB_USB_COMMON = 1 << 18, + MUX_PGP_USB_COMMON = 1 << 18, MUX_SDHC_MEMSTICK1 = 1 << 19, MUX_SDHC_MEMSTICK2 = 1 << 20, MUX_PGP_SPLL_BYP = 1 << 21, @@ -109,21 +109,44 @@ enum iomux_gp_func { }; /* - * This function enables/disables the general purpose function for a particular - * signal. + * setups a single pin: + * - reserves the pin so that it is not claimed by another driver + * - setups the iomux according to the configuration + * - if the pin is configured as a GPIO, we claim it throug kernel gpiolib + */ +int mxc_iomux_setup_pin(const unsigned int pin, const char *label); +/* + * setups mutliple pins + * convenient way to call the above function with tables */ -void iomux_config_gpr(enum iomux_gp_func , bool); +int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count, + const char *label); /* - * set the mode for a IOMUX pin. + * releases a single pin: + * - make it available for a future use by another driver + * - frees the GPIO if the pin was configured as GPIO + * - DOES NOT reconfigure the IOMUX in its reset state */ -int mxc_iomux_mode(unsigned int); +void mxc_iomux_release_pin(const unsigned int pin); +/* + * releases multiple pins + * convenvient way to call the above function with tables + */ +void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count); /* * This function enables/disables the general purpose function for a particular * signal. */ -void mxc_iomux_set_gpr(enum iomux_gp_func, bool); +void mxc_iomux_set_gpr(enum iomux_gp_func, bool en); + +/* + * This function only configures the iomux hardware. + * It is called by the setup functions and should not be called directly anymore. + * It is here visible for backward compatibility + */ +int mxc_iomux_mode(unsigned int pin_mode); #define IOMUX_PADNUM_MASK 0x1ff #define IOMUX_GPIONUM_SHIFT 9 @@ -143,6 +166,11 @@ void mxc_iomux_set_gpr(enum iomux_gp_func, bool); (((iomux_pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT) + \ MXC_GPIO_IRQ_START) +/* + * The number of gpio devices among the pads + */ +#define GPIO_PORT_MAX 3 + /* * This enumeration is constructed based on the Section * "sw_pad_ctl & sw_mux_ctl details" of the MX31 IC Spec. Each enumerated @@ -480,6 +508,9 @@ enum iomux_pins { MX31_PIN_CAPTURE = IOMUX_PIN( 7, 327), }; +#define PIN_MAX 327 +#define NB_PORTS 12 /* NB_PINS/32, we chose 32 pins per "PORT" */ + /* * Convenience values for use with mxc_iomux_mode() * -- cgit v1.2.3 From c0b90a31efe30987ab4bb21298b410913779e62f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 15 Jan 2009 15:37:22 +0100 Subject: imxfb: add platform specific init/exit functions Signed-off-by: Sascha Hauer --- arch/arm/plat-mxc/include/mach/imxfb.h | 3 +++ drivers/video/imxfb.c | 14 ++++++++++++++ 2 files changed, 17 insertions(+) (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/plat-mxc/include/mach/imxfb.h b/arch/arm/plat-mxc/include/mach/imxfb.h index 870d0d939616..762a7b0430e2 100644 --- a/arch/arm/plat-mxc/include/mach/imxfb.h +++ b/arch/arm/plat-mxc/include/mach/imxfb.h @@ -76,6 +76,9 @@ struct imx_fb_platform_data { u_char * fixed_screen_cpu; dma_addr_t fixed_screen_dma; + int (*init)(struct platform_device*); + int (*exit)(struct platform_device*); + void (*lcd_power)(int); void (*backlight_power)(int); }; diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index d58c68cd456e..629d66f32300 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -650,6 +650,12 @@ static int __init imxfb_probe(struct platform_device *pdev) info->fix.smem_start = fbi->screen_dma; } + if (pdata->init) { + ret = pdata->init(fbi->pdev); + if (ret) + goto failed_platform_init; + } + /* * This makes sure that our colour bitfield * descriptors are correctly initialised. @@ -674,6 +680,9 @@ static int __init imxfb_probe(struct platform_device *pdev) failed_register: fb_dealloc_cmap(&info->cmap); failed_cmap: + if (pdata->exit) + pdata->exit(fbi->pdev); +failed_platform_init: if (!pdata->fixed_screen_cpu) dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu, fbi->map_dma); @@ -691,6 +700,7 @@ failed_init: static int __devexit imxfb_remove(struct platform_device *pdev) { + struct imx_fb_platform_data *pdata; struct fb_info *info = platform_get_drvdata(pdev); struct imxfb_info *fbi = info->par; struct resource *res; @@ -701,6 +711,10 @@ static int __devexit imxfb_remove(struct platform_device *pdev) unregister_framebuffer(info); + pdata = pdev->dev.platform_data; + if (pdata->exit) + pdata->exit(fbi->pdev); + fb_dealloc_cmap(&info->cmap); kfree(info->pseudo_palette); framebuffer_release(info); -- cgit v1.2.3 From 166091b1894df3de736f43c649f2e6639f4a31ac Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 16 Jan 2009 15:17:16 +0100 Subject: [ARM] MXC: add pwm driver for i.MX SoCs This driver has been tested on MX27/MX31. It should work on MX1/MX1 aswell, but the actual setting of the PWM is missing so far. Signed-off-by: Sascha Hauer --- arch/arm/plat-mxc/Kconfig | 6 + arch/arm/plat-mxc/Makefile | 1 + arch/arm/plat-mxc/pwm.c | 300 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 307 insertions(+) create mode 100644 arch/arm/plat-mxc/pwm.c (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig index 10f65bf27b27..71c3c848b0e2 100644 --- a/arch/arm/plat-mxc/Kconfig +++ b/arch/arm/plat-mxc/Kconfig @@ -44,4 +44,10 @@ config MXC_IRQ_PRIOR requirements for timing. Say N here, unless you have a specialized requirement. +config MXC_PWM + tristate "Enable PWM driver" + depends on ARCH_MXC + help + Enable support for the i.MX PWM controller(s). + endif diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index db74a929179d..f204192f9b94 100644 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile @@ -7,3 +7,4 @@ obj-y := irq.o clock.o gpio.o time.o devices.o obj-$(CONFIG_ARCH_MX1) += iomux-mx1-mx2.o dma-mx1-mx2.o obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o +obj-$(CONFIG_MXC_PWM) += pwm.o diff --git a/arch/arm/plat-mxc/pwm.c b/arch/arm/plat-mxc/pwm.c new file mode 100644 index 000000000000..9bffbc507cc2 --- /dev/null +++ b/arch/arm/plat-mxc/pwm.c @@ -0,0 +1,300 @@ +/* + * simple driver for PWM (Pulse Width Modulator) controller + * + * 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. + * + * Derived from pxa PWM driver by eric miao + */ + +#include +#include +#include +#include +#include +#include +#include + +#if defined CONFIG_ARCH_MX1 || defined CONFIG_ARCH_MX21 +#define PWM_VER_1 + +#define PWMCR 0x00 /* PWM Control Register */ +#define PWMSR 0x04 /* PWM Sample Register */ +#define PWMPR 0x08 /* PWM Period Register */ +#define PWMCNR 0x0C /* PWM Counter Register */ + +#define PWMCR_HCTR (1 << 18) /* Halfword FIFO Data Swapping */ +#define PWMCR_BCTR (1 << 17) /* Byte FIFO Data Swapping */ +#define PWMCR_SWR (1 << 16) /* Software Reset */ +#define PWMCR_CLKSRC_PERCLK (0 << 15) /* PERCLK Clock Source */ +#define PWMCR_CLKSRC_CLK32 (1 << 15) /* 32KHz Clock Source */ +#define PWMCR_PRESCALER(x) (((x - 1) & 0x7F) << 8) /* PRESCALER */ +#define PWMCR_IRQ (1 << 7) /* Interrupt Request */ +#define PWMCR_IRQEN (1 << 6) /* Interrupt Request Enable */ +#define PWMCR_FIFOAV (1 << 5) /* FIFO Available */ +#define PWMCR_EN (1 << 4) /* Enables/Disables the PWM */ +#define PWMCR_REPEAT(x) (((x) & 0x03) << 2) /* Sample Repeats */ +#define PWMCR_DIV(x) (((x) & 0x03) << 0) /* Clock divider 2/4/8/16 */ + +#define MAX_DIV (128 * 16) +#endif + +#if defined CONFIG_MACH_MX27 || defined CONFIG_ARCH_MX31 +#define PWM_VER_2 + +#define PWMCR 0x00 /* PWM Control Register */ +#define PWMSR 0x04 /* PWM Status Register */ +#define PWMIR 0x08 /* PWM Interrupt Register */ +#define PWMSAR 0x0C /* PWM Sample Register */ +#define PWMPR 0x10 /* PWM Period Register */ +#define PWMCNR 0x14 /* PWM Counter Register */ + +#define PWMCR_EN (1 << 0) /* Enables/Disables the PWM */ +#define PWMCR_REPEAT(x) (((x) & 0x03) << 1) /* Sample Repeats */ +#define PWMCR_SWR (1 << 3) /* Software Reset */ +#define PWMCR_PRESCALER(x) (((x - 1) & 0xFFF) << 4)/* PRESCALER */ +#define PWMCR_CLKSRC(x) (((x) & 0x3) << 16) +#define PWMCR_CLKSRC_OFF (0 << 16) +#define PWMCR_CLKSRC_IPG (1 << 16) +#define PWMCR_CLKSRC_IPG_HIGH (2 << 16) +#define PWMCR_CLKSRC_CLK32 (3 << 16) +#define PWMCR_POUTC +#define PWMCR_HCTR (1 << 20) /* Halfword FIFO Data Swapping */ +#define PWMCR_BCTR (1 << 21) /* Byte FIFO Data Swapping */ +#define PWMCR_DBGEN (1 << 22) /* Debug Mode */ +#define PWMCR_WAITEN (1 << 23) /* Wait Mode */ +#define PWMCR_DOZEN (1 << 24) /* Doze Mode */ +#define PWMCR_STOPEN (1 << 25) /* Stop Mode */ +#define PWMCR_FWM(x) (((x) & 0x3) << 26) /* FIFO Water Mark */ + +#define MAX_DIV 4096 +#endif + +#define PWMS_SAMPLE(x) ((x) & 0xFFFF) /* Contains a two-sample word */ +#define PWMP_PERIOD(x) ((x) & 0xFFFF) /* Represents the PWM's period */ +#define PWMC_COUNTER(x) ((x) & 0xFFFF) /* Represents the current count value */ + +struct pwm_device { + struct list_head node; + struct platform_device *pdev; + + const char *label; + struct clk *clk; + + int clk_enabled; + void __iomem *mmio_base; + + unsigned int use_count; + unsigned int pwm_id; +}; + +int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) +{ + unsigned long long c; + unsigned long period_cycles, duty_cycles, prescale; + + if (pwm == NULL || period_ns == 0 || duty_ns > period_ns) + return -EINVAL; + + c = clk_get_rate(pwm->clk); + c = c * period_ns; + do_div(c, 1000000000); + period_cycles = c; + + prescale = period_cycles / 0x10000 + 1; + + period_cycles /= prescale; + c = (unsigned long long)period_cycles * duty_ns; + do_div(c, period_ns); + duty_cycles = c; + +#ifdef PWM_VER_2 + writel(duty_cycles, pwm->mmio_base + PWMSAR); + writel(period_cycles, pwm->mmio_base + PWMPR); + writel(PWMCR_PRESCALER(prescale - 1) | PWMCR_CLKSRC_IPG_HIGH | PWMCR_EN, + pwm->mmio_base + PWMCR); +#elif defined PWM_VER_1 +#error PWM not yet working on MX1 / MX21 +#endif + + return 0; +} +EXPORT_SYMBOL(pwm_config); + +int pwm_enable(struct pwm_device *pwm) +{ + int rc = 0; + + if (!pwm->clk_enabled) { + rc = clk_enable(pwm->clk); + if (!rc) + pwm->clk_enabled = 1; + } + return rc; +} +EXPORT_SYMBOL(pwm_enable); + +void pwm_disable(struct pwm_device *pwm) +{ + if (pwm->clk_enabled) { + clk_disable(pwm->clk); + pwm->clk_enabled = 0; + } +} +EXPORT_SYMBOL(pwm_disable); + +static DEFINE_MUTEX(pwm_lock); +static LIST_HEAD(pwm_list); + +struct pwm_device *pwm_request(int pwm_id, const char *label) +{ + struct pwm_device *pwm; + int found = 0; + + mutex_lock(&pwm_lock); + + list_for_each_entry(pwm, &pwm_list, node) { + if (pwm->pwm_id == pwm_id) { + found = 1; + break; + } + } + + if (found) { + if (pwm->use_count == 0) { + pwm->use_count++; + pwm->label = label; + } else + pwm = ERR_PTR(-EBUSY); + } else + pwm = ERR_PTR(-ENOENT); + + mutex_unlock(&pwm_lock); + return pwm; +} +EXPORT_SYMBOL(pwm_request); + +void pwm_free(struct pwm_device *pwm) +{ + mutex_lock(&pwm_lock); + + if (pwm->use_count) { + pwm->use_count--; + pwm->label = NULL; + } else + pr_warning("PWM device already freed\n"); + + mutex_unlock(&pwm_lock); +} +EXPORT_SYMBOL(pwm_free); + +static int __devinit mxc_pwm_probe(struct platform_device *pdev) +{ + struct pwm_device *pwm; + struct resource *r; + int ret = 0; + + pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL); + if (pwm == NULL) { + dev_err(&pdev->dev, "failed to allocate memory\n"); + return -ENOMEM; + } + + pwm->clk = clk_get(&pdev->dev, "pwm"); + + if (IS_ERR(pwm->clk)) { + ret = PTR_ERR(pwm->clk); + goto err_free; + } + + pwm->clk_enabled = 0; + + pwm->use_count = 0; + pwm->pwm_id = pdev->id; + pwm->pdev = pdev; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (r == NULL) { + dev_err(&pdev->dev, "no memory resource defined\n"); + ret = -ENODEV; + goto err_free_clk; + } + + r = request_mem_region(r->start, r->end - r->start + 1, pdev->name); + if (r == NULL) { + dev_err(&pdev->dev, "failed to request memory resource\n"); + ret = -EBUSY; + goto err_free_clk; + } + + pwm->mmio_base = ioremap(r->start, r->end - r->start + 1); + if (pwm->mmio_base == NULL) { + dev_err(&pdev->dev, "failed to ioremap() registers\n"); + ret = -ENODEV; + goto err_free_mem; + } + + mutex_lock(&pwm_lock); + list_add_tail(&pwm->node, &pwm_list); + mutex_unlock(&pwm_lock); + + platform_set_drvdata(pdev, pwm); + return 0; + +err_free_mem: + release_mem_region(r->start, r->end - r->start + 1); +err_free_clk: + clk_put(pwm->clk); +err_free: + kfree(pwm); + return ret; +} + +static int __devexit mxc_pwm_remove(struct platform_device *pdev) +{ + struct pwm_device *pwm; + struct resource *r; + + pwm = platform_get_drvdata(pdev); + if (pwm == NULL) + return -ENODEV; + + mutex_lock(&pwm_lock); + list_del(&pwm->node); + mutex_unlock(&pwm_lock); + + iounmap(pwm->mmio_base); + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(r->start, r->end - r->start + 1); + + clk_put(pwm->clk); + + kfree(pwm); + return 0; +} + +static struct platform_driver mxc_pwm_driver = { + .driver = { + .name = "mxc_pwm", + }, + .probe = mxc_pwm_probe, + .remove = __devexit_p(mxc_pwm_remove), +}; + +static int __init mxc_pwm_init(void) +{ + return platform_driver_register(&mxc_pwm_driver); +} +arch_initcall(mxc_pwm_init); + +static void __exit mxc_pwm_exit(void) +{ + platform_driver_unregister(&mxc_pwm_driver); +} +module_exit(mxc_pwm_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Sascha Hauer "); + -- cgit v1.2.3 From c2aaac70cd00cf5d4687cc35f462e3888c9ac76f Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 28 Jan 2009 17:11:02 +0100 Subject: [ARM] iommux mx3: Add pin definitions for I2C Signed-off-by: Sascha Hauer --- arch/arm/plat-mxc/include/mach/iomux-mx3.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/arch/arm/plat-mxc/include/mach/iomux-mx3.h index 4bdc4712be1d..a38aa8510cb4 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx3.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx3.h @@ -538,7 +538,9 @@ enum iomux_pins { #define MX31_PIN_CSPI1_SS1__SS1 IOMUX_MODE(MX31_PIN_CSPI1_SS1, IOMUX_CONFIG_FUNC) #define MX31_PIN_CSPI1_SS2__SS2 IOMUX_MODE(MX31_PIN_CSPI1_SS2, IOMUX_CONFIG_FUNC) #define MX31_PIN_CSPI2_MOSI__MOSI IOMUX_MODE(MX31_PIN_CSPI2_MOSI, IOMUX_CONFIG_FUNC) +#define MX31_PIN_CSPI2_MOSI__SCL IOMUX_MODE(MX31_PIN_CSPI2_MOSI, IOMUX_CONFIG_ALT1) #define MX31_PIN_CSPI2_MISO__MISO IOMUX_MODE(MX31_PIN_CSPI2_MISO, IOMUX_CONFIG_FUNC) +#define MX31_PIN_CSPI2_MISO__SDA IOMUX_MODE(MX31_PIN_CSPI2_MISO, IOMUX_CONFIG_ALT1) #define MX31_PIN_CSPI2_SCLK__SCLK IOMUX_MODE(MX31_PIN_CSPI2_SCLK, IOMUX_CONFIG_FUNC) #define MX31_PIN_CSPI2_SPI_RDY__SPI_RDY IOMUX_MODE(MX31_PIN_CSPI2_SPI_RDY, IOMUX_CONFIG_FUNC) #define MX31_PIN_CSPI2_SS0__SS0 IOMUX_MODE(MX31_PIN_CSPI2_SS0, IOMUX_CONFIG_FUNC) -- cgit v1.2.3 From 6bbdbf2f95771c0a2dbccc423b99b37fde9a5078 Mon Sep 17 00:00:00 2001 From: Holger Schurig Date: Thu, 29 Jan 2009 14:42:25 +0100 Subject: arm/imx: Kconfig beautification Signed-off-by: Holger Schurig Signed-off-by: Sascha Hauer --- arch/arm/mach-mx1/Kconfig | 3 ++- arch/arm/mach-mx2/Kconfig | 13 +++++-------- arch/arm/mach-mx3/Kconfig | 8 ++++---- arch/arm/plat-mxc/Kconfig | 2 +- 4 files changed, 12 insertions(+), 14 deletions(-) (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/mach-mx1/Kconfig b/arch/arm/mach-mx1/Kconfig index f86cfcb60224..eb7660f5d4b7 100644 --- a/arch/arm/mach-mx1/Kconfig +++ b/arch/arm/mach-mx1/Kconfig @@ -1,6 +1,6 @@ if ARCH_MX1 -comment "MX1 Platforms" +comment "MX1 platforms:" config MACH_MXLADS bool @@ -15,4 +15,5 @@ config MACH_SCB9328 bool "Synertronixx scb9328" help Say Y here if you are using a Synertronixx scb9328 board + endif diff --git a/arch/arm/mach-mx2/Kconfig b/arch/arm/mach-mx2/Kconfig index 412d2d55b08c..42a788842f49 100644 --- a/arch/arm/mach-mx2/Kconfig +++ b/arch/arm/mach-mx2/Kconfig @@ -1,27 +1,22 @@ -comment "MX2 family CPU support" - depends on ARCH_MX2 +if ARCH_MX2 choice - prompt "MX2 Type" - depends on ARCH_MX2 + prompt "CPUs:" default MACH_MX21 config MACH_MX21 bool "i.MX21 support" - depends on ARCH_MX2 help This enables support for Freescale's MX2 based i.MX21 processor. config MACH_MX27 bool "i.MX27 support" - depends on ARCH_MX2 help This enables support for Freescale's MX2 based i.MX27 processor. endchoice -comment "MX2 Platforms" - depends on ARCH_MX2 +comment "MX2 platforms:" config MACH_MX27ADS bool "MX27ADS platform" @@ -50,3 +45,5 @@ config MACH_PCM970_BASEBOARD PCM970 evaluation board. endchoice + +endif diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig index 6fea54196324..6933d2d0b568 100644 --- a/arch/arm/mach-mx3/Kconfig +++ b/arch/arm/mach-mx3/Kconfig @@ -1,5 +1,6 @@ -menu "MX3 Options" - depends on ARCH_MX3 +if ARCH_MX3 + +comment "MX3 platforms:" config MACH_MX31ADS bool "Support MX31ADS platforms" @@ -44,5 +45,4 @@ config MACH_MX31MOBOARD Include support for mx31moboard platform. This includes specific configurations for the board and its peripherals. -endmenu - +endif diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig index 71c3c848b0e2..ed5ab8ed7cfa 100644 --- a/arch/arm/plat-mxc/Kconfig +++ b/arch/arm/plat-mxc/Kconfig @@ -3,7 +3,7 @@ if ARCH_MXC menu "Freescale MXC Implementations" choice - prompt "MXC/iMX Base Type" + prompt "Freescale CPU family:" default ARCH_MX3 config ARCH_MX1 -- cgit v1.2.3 From 999981d943e626bff5d031de1bf06435afb10ced Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 12 Feb 2009 14:27:22 +0100 Subject: mxc: first set GPIO level, then switch direction to output Make sure not to create spurious pulses on GPIOs, when configuring them as output: first set required level, then switch direction. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Sascha Hauer --- arch/arm/plat-mxc/gpio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c index ccbd94adc668..c6483bad8a26 100644 --- a/arch/arm/plat-mxc/gpio.c +++ b/arch/arm/plat-mxc/gpio.c @@ -200,8 +200,8 @@ static int mxc_gpio_direction_input(struct gpio_chip *chip, unsigned offset) static int mxc_gpio_direction_output(struct gpio_chip *chip, unsigned offset, int value) { - _set_gpio_direction(chip, offset, 1); mxc_gpio_set(chip, offset, value); + _set_gpio_direction(chip, offset, 1); return 0; } -- cgit v1.2.3 From e180a5c26fae12dcc02244df68a6089cd5522df7 Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Wed, 11 Feb 2009 16:55:17 +0100 Subject: mx31: add pin definition for LCD Signed-off-by: Valentin Longchamp Signed-off-by: Sascha Hauer --- arch/arm/plat-mxc/include/mach/iomux-mx3.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx3.h b/arch/arm/plat-mxc/include/mach/iomux-mx3.h index a38aa8510cb4..ab838cfe94f9 100644 --- a/arch/arm/plat-mxc/include/mach/iomux-mx3.h +++ b/arch/arm/plat-mxc/include/mach/iomux-mx3.h @@ -558,6 +558,33 @@ enum iomux_pins { #define MX31_PIN_SD1_DATA0__SD1_DATA0 IOMUX_MODE(MX31_PIN_SD1_DATA0, IOMUX_CONFIG_FUNC) #define MX31_PIN_SD1_CLK__SD1_CLK IOMUX_MODE(MX31_PIN_SD1_CLK, IOMUX_CONFIG_FUNC) #define MX31_PIN_SD1_CMD__SD1_CMD IOMUX_MODE(MX31_PIN_SD1_CMD, IOMUX_CONFIG_FUNC) +#define MX31_PIN_LD0__LD0 IOMUX_MODE(MX31_PIN_LD0, IOMUX_CONFIG_FUNC) +#define MX31_PIN_LD1__LD1 IOMUX_MODE(MX31_PIN_LD1, IOMUX_CONFIG_FUNC) +#define MX31_PIN_LD2__LD2 IOMUX_MODE(MX31_PIN_LD2, IOMUX_CONFIG_FUNC) +#define MX31_PIN_LD3__LD3 IOMUX_MODE(MX31_PIN_LD3, IOMUX_CONFIG_FUNC) +#define MX31_PIN_LD4__LD4 IOMUX_MODE(MX31_PIN_LD4, IOMUX_CONFIG_FUNC) +#define MX31_PIN_LD5__LD5 IOMUX_MODE(MX31_PIN_LD5, IOMUX_CONFIG_FUNC) +#define MX31_PIN_LD6__LD6 IOMUX_MODE(MX31_PIN_LD6, IOMUX_CONFIG_FUNC) +#define MX31_PIN_LD7__LD7 IOMUX_MODE(MX31_PIN_LD7, IOMUX_CONFIG_FUNC) +#define MX31_PIN_LD8__LD8 IOMUX_MODE(MX31_PIN_LD8, IOMUX_CONFIG_FUNC) +#define MX31_PIN_LD9__LD9 IOMUX_MODE(MX31_PIN_LD9, IOMUX_CONFIG_FUNC) +#define MX31_PIN_LD10__LD10 IOMUX_MODE(MX31_PIN_LD10, IOMUX_CONFIG_FUNC) +#define MX31_PIN_LD11__LD11 IOMUX_MODE(MX31_PIN_LD11, IOMUX_CONFIG_FUNC) +#define MX31_PIN_LD12__LD12 IOMUX_MODE(MX31_PIN_LD12, IOMUX_CONFIG_FUNC) +#define MX31_PIN_LD13__LD13 IOMUX_MODE(MX31_PIN_LD13, IOMUX_CONFIG_FUNC) +#define MX31_PIN_LD14__LD14 IOMUX_MODE(MX31_PIN_LD14, IOMUX_CONFIG_FUNC) +#define MX31_PIN_LD15__LD15 IOMUX_MODE(MX31_PIN_LD15, IOMUX_CONFIG_FUNC) +#define MX31_PIN_LD16__LD16 IOMUX_MODE(MX31_PIN_LD16, IOMUX_CONFIG_FUNC) +#define MX31_PIN_LD17__LD17 IOMUX_MODE(MX31_PIN_LD17, IOMUX_CONFIG_FUNC) +#define MX31_PIN_VSYNC3__VSYNC3 IOMUX_MODE(MX31_PIN_VSYNC3, IOMUX_CONFIG_FUNC) +#define MX31_PIN_HSYNC__HSYNC IOMUX_MODE(MX31_PIN_HSYNC, IOMUX_CONFIG_FUNC) +#define MX31_PIN_FPSHIFT__FPSHIFT IOMUX_MODE(MX31_PIN_FPSHIFT, IOMUX_CONFIG_FUNC) +#define MX31_PIN_DRDY0__DRDY0 IOMUX_MODE(MX31_PIN_DRDY0, IOMUX_CONFIG_FUNC) +#define MX31_PIN_D3_REV__D3_REV IOMUX_MODE(MX31_PIN_D3_REV, IOMUX_CONFIG_FUNC) +#define MX31_PIN_CONTRAST__CONTRAST IOMUX_MODE(MX31_PIN_CONTRAST, IOMUX_CONFIG_FUNC) +#define MX31_PIN_D3_SPL__D3_SPL IOMUX_MODE(MX31_PIN_D3_SPL, IOMUX_CONFIG_FUNC) +#define MX31_PIN_D3_CLS__D3_CLS IOMUX_MODE(MX31_PIN_D3_CLS, IOMUX_CONFIG_FUNC) +#define MX31_PIN_LCS0__GPI03_23 IOMUX_MODE(MX31_PIN_LCS0, IOMUX_CONFIG_GPIO) /*XXX: The SS0, SS1, SS2, SS3 lines of spi3 are multiplexed by cspi2_ss0, cspi2_ss1, cspi1_ss0 * cspi1_ss1*/ -- cgit v1.2.3 From e00f0b4a9316c9de000697e489f6102271e94dc4 Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Mon, 16 Feb 2009 12:47:51 +0100 Subject: mx31moboard: initial support for various baseboards This enables our mx31moboard to be used on the different baseboards that we are developping according to the application needs. There are not many differences between the boards for now, but when other peripherals are available for mx31 the differences are going to grow. v2: takes Sascha's comments into account Signed-off-by: Valentin Longchamp Signed-off-by: Sascha Hauer --- arch/arm/mach-mx3/Makefile | 3 +- arch/arm/mach-mx3/mx31moboard-devboard.c | 48 ++++++++++++++++++++++ arch/arm/mach-mx3/mx31moboard-marxbot.c | 37 +++++++++++++++++ arch/arm/mach-mx3/mx31moboard.c | 39 ++++++++++-------- arch/arm/plat-mxc/include/mach/board-mx31moboard.h | 45 ++++++++++++++++++++ 5 files changed, 154 insertions(+), 18 deletions(-) create mode 100644 arch/arm/mach-mx3/mx31moboard-devboard.c create mode 100644 arch/arm/mach-mx3/mx31moboard-marxbot.c create mode 100644 arch/arm/plat-mxc/include/mach/board-mx31moboard.h (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index 5a151540fe83..d50d9878a654 100644 --- a/arch/arm/mach-mx3/Makefile +++ b/arch/arm/mach-mx3/Makefile @@ -9,4 +9,5 @@ obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o obj-$(CONFIG_MACH_MX31LITE) += mx31lite.o obj-$(CONFIG_MACH_PCM037) += pcm037.o obj-$(CONFIG_MACH_MX31_3DS) += mx31pdk.o -obj-$(CONFIG_MACH_MX31MOBOARD) += mx31moboard.o +obj-$(CONFIG_MACH_MX31MOBOARD) += mx31moboard.o mx31moboard-devboard.o \ + mx31moboard-marxbot.o diff --git a/arch/arm/mach-mx3/mx31moboard-devboard.c b/arch/arm/mach-mx3/mx31moboard-devboard.c new file mode 100644 index 000000000000..d080b4add79c --- /dev/null +++ b/arch/arm/mach-mx3/mx31moboard-devboard.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#include + +#include +#include +#include +#include + +#include "devices.h" + +static struct imxuart_platform_data uart_pdata = { + .flags = IMXUART_HAVE_RTSCTS, +}; + +static int mxc_uart1_pins[] = { + MX31_PIN_CTS2__CTS2, MX31_PIN_RTS2__RTS2, + MX31_PIN_TXD2__TXD2, MX31_PIN_RXD2__RXD2, +}; + +/* + * system init for baseboard usage. Will be called by mx31moboard init. + */ +void __init mx31moboard_devboard_init(void) +{ + printk(KERN_INFO "Initializing mx31devboard peripherals\n"); + mxc_iomux_setup_multiple_pins(mxc_uart1_pins, ARRAY_SIZE(mxc_uart1_pins), "uart1"); + mxc_register_device(&mxc_uart_device1, &uart_pdata); +} diff --git a/arch/arm/mach-mx3/mx31moboard-marxbot.c b/arch/arm/mach-mx3/mx31moboard-marxbot.c new file mode 100644 index 000000000000..9ef9566823fb --- /dev/null +++ b/arch/arm/mach-mx3/mx31moboard-marxbot.c @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include + +#include + +#include +#include +#include +#include + +#include "devices.h" + +/* + * system init for baseboard usage. Will be called by mx31moboard init. + */ +void __init mx31moboard_marxbot_init(void) +{ + printk(KERN_INFO "Initializing mx31marxbot peripherals\n"); +} diff --git a/arch/arm/mach-mx3/mx31moboard.c b/arch/arm/mach-mx3/mx31moboard.c index f29c8782cffb..2d51739e24bf 100644 --- a/arch/arm/mach-mx3/mx31moboard.c +++ b/arch/arm/mach-mx3/mx31moboard.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "devices.h" @@ -64,24 +65,17 @@ static struct platform_device *devices[] __initdata = { }; static int mxc_uart0_pins[] = { - MX31_PIN_CTS1__CTS1, - MX31_PIN_RTS1__RTS1, - MX31_PIN_TXD1__TXD1, - MX31_PIN_RXD1__RXD1 -}; -static int mxc_uart1_pins[] = { - MX31_PIN_CTS2__CTS2, - MX31_PIN_RTS2__RTS2, - MX31_PIN_TXD2__TXD2, - MX31_PIN_RXD2__RXD2 + MX31_PIN_CTS1__CTS1, MX31_PIN_RTS1__RTS1, + MX31_PIN_TXD1__TXD1, MX31_PIN_RXD1__RXD1, }; static int mxc_uart4_pins[] = { - MX31_PIN_PC_RST__CTS5, - MX31_PIN_PC_VS2__RTS5, - MX31_PIN_PC_BVD2__TXD5, - MX31_PIN_PC_BVD1__RXD5 + MX31_PIN_PC_RST__CTS5, MX31_PIN_PC_VS2__RTS5, + MX31_PIN_PC_BVD2__TXD5, MX31_PIN_PC_BVD1__RXD5, }; +static int mx31moboard_baseboard; +core_param(mx31moboard_baseboard, mx31moboard_baseboard, int, 0444); + /* * Board specific initialization. */ @@ -92,11 +86,22 @@ static void __init mxc_board_init(void) mxc_iomux_setup_multiple_pins(mxc_uart0_pins, ARRAY_SIZE(mxc_uart0_pins), "uart0"); mxc_register_device(&mxc_uart_device0, &uart_pdata); - mxc_iomux_setup_multiple_pins(mxc_uart1_pins, ARRAY_SIZE(mxc_uart1_pins), "uart1"); - mxc_register_device(&mxc_uart_device1, &uart_pdata); - mxc_iomux_setup_multiple_pins(mxc_uart4_pins, ARRAY_SIZE(mxc_uart4_pins), "uart4"); mxc_register_device(&mxc_uart_device4, &uart_pdata); + + switch (mx31moboard_baseboard) { + case MX31NOBOARD: + break; + case MX31DEVBOARD: + mx31moboard_devboard_init(); + break; + case MX31MARXBOT: + mx31moboard_marxbot_init(); + break; + default: + printk(KERN_ERR "Illegal mx31moboard_baseboard type %d\n", mx31moboard_baseboard); + } + } /* diff --git a/arch/arm/plat-mxc/include/mach/board-mx31moboard.h b/arch/arm/plat-mxc/include/mach/board-mx31moboard.h new file mode 100644 index 000000000000..f8aef1babb75 --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/board-mx31moboard.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2009 Valentin Longchamp, EPFL Mobots group + * + * 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. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__ +#define __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__ + +/* mandatory for CONFIG_LL_DEBUG */ + +#define MXC_LL_UART_PADDR UART1_BASE_ADDR +#define MXC_LL_UART_VADDR (AIPI_BASE_ADDR_VIRT + 0x0A000) + +#ifndef __ASSEMBLY__ + +enum mx31moboard_boards { + MX31NOBOARD = 0, + MX31DEVBOARD = 1, + MX31MARXBOT = 2, +}; + +/* + * This CPU module needs a baseboard to work. After basic initializing + * its own devices, it calls baseboard's init function. + */ + +extern void mx31moboard_devboard_init(void); +extern void mx31moboard_marxbot_init(void); + +#endif + +#endif /* __ASM_ARCH_MXC_BOARD_MX31MOBOARD_H__ */ -- cgit v1.2.3 From c0a5f85523132dc893916d6059370233fac1cb11 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Mon, 2 Feb 2009 14:11:54 +0100 Subject: [ARM] MX35: Add register definitions for the i.MX35 This patch moves the stuff common to i.MX31 and i.MX35 to mx3x.h and the specifics to mx31.h/mx35.h. We can build a kernel which runs on i.MX31 and i.MX35, so always include mx31.h and mx35.h Signed-off-by: Sascha Hauer --- arch/arm/plat-mxc/include/mach/hardware.h | 4 +- arch/arm/plat-mxc/include/mach/mx31.h | 329 +----------------------------- arch/arm/plat-mxc/include/mach/mx35.h | 29 +++ arch/arm/plat-mxc/include/mach/mx3x.h | 290 ++++++++++++++++++++++++++ 4 files changed, 329 insertions(+), 323 deletions(-) create mode 100644 arch/arm/plat-mxc/include/mach/mx35.h create mode 100644 arch/arm/plat-mxc/include/mach/mx3x.h (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h index 11f5727ea445..42e4ee37ca1f 100644 --- a/arch/arm/plat-mxc/include/mach/hardware.h +++ b/arch/arm/plat-mxc/include/mach/hardware.h @@ -23,7 +23,9 @@ #include #ifdef CONFIG_ARCH_MX3 -# include +#include +#include +#include #endif #ifdef CONFIG_ARCH_MX2 diff --git a/arch/arm/plat-mxc/include/mach/mx31.h b/arch/arm/plat-mxc/include/mach/mx31.h index de026654b00e..0b06941b6139 100644 --- a/arch/arm/plat-mxc/include/mach/mx31.h +++ b/arch/arm/plat-mxc/include/mach/mx31.h @@ -1,360 +1,45 @@ -/* - * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. - */ - -/* - * 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. - */ - -#ifndef __ASM_ARCH_MXC_MX31_H__ -#define __ASM_ARCH_MXC_MX31_H__ - -#ifndef __ASM_ARCH_MXC_HARDWARE_H__ -#error "Do not include directly." -#endif - -/* - * MX31 memory map: - * - * Virt Phys Size What - * --------------------------------------------------------------------------- - * F8000000 1FFC0000 16K IRAM - * F9000000 30000000 256M L2CC - * FC000000 43F00000 1M AIPS 1 - * FC100000 50000000 1M SPBA - * FC200000 53F00000 1M AIPS 2 - * FC500000 60000000 128M ROMPATCH - * FC400000 68000000 128M AVIC - * 70000000 256M IPU (MAX M2) - * 80000000 256M CSD0 SDRAM/DDR - * 90000000 256M CSD1 SDRAM/DDR - * A0000000 128M CS0 Flash - * A8000000 128M CS1 Flash - * B0000000 32M CS2 - * B2000000 32M CS3 - * F4000000 B4000000 32M CS4 - * B6000000 32M CS5 - * FC320000 B8000000 64K NAND, SDRAM, WEIM, M3IF, EMI controllers - * C0000000 64M PCMCIA/CF - */ - -#define CS0_BASE_ADDR 0xA0000000 -#define CS1_BASE_ADDR 0xA8000000 -#define CS2_BASE_ADDR 0xB0000000 -#define CS3_BASE_ADDR 0xB2000000 - -#define CS4_BASE_ADDR 0xB4000000 -#define CS4_BASE_ADDR_VIRT 0xF4000000 -#define CS4_SIZE SZ_32M - -#define CS5_BASE_ADDR 0xB6000000 -#define PCMCIA_MEM_BASE_ADDR 0xBC000000 - /* * IRAM */ -#define IRAM_BASE_ADDR 0x1FFC0000 /* internal ram */ -#define IRAM_BASE_ADDR_VIRT 0xF8000000 -#define IRAM_SIZE SZ_16K - -/* - * L2CC - */ -#define L2CC_BASE_ADDR 0x30000000 -#define L2CC_BASE_ADDR_VIRT 0xF9000000 -#define L2CC_SIZE SZ_1M - -/* - * AIPS 1 - */ -#define AIPS1_BASE_ADDR 0x43F00000 -#define AIPS1_BASE_ADDR_VIRT 0xFC000000 -#define AIPS1_SIZE SZ_1M +#define MX31_IRAM_BASE_ADDR 0x1FFC0000 /* internal ram */ +#define MX31_IRAM_SIZE SZ_16K -#define MAX_BASE_ADDR (AIPS1_BASE_ADDR + 0x00004000) -#define EVTMON_BASE_ADDR (AIPS1_BASE_ADDR + 0x00008000) -#define CLKCTL_BASE_ADDR (AIPS1_BASE_ADDR + 0x0000C000) -#define ETB_SLOT4_BASE_ADDR (AIPS1_BASE_ADDR + 0x00010000) -#define ETB_SLOT5_BASE_ADDR (AIPS1_BASE_ADDR + 0x00014000) -#define ECT_CTIO_BASE_ADDR (AIPS1_BASE_ADDR + 0x00018000) -#define I2C_BASE_ADDR (AIPS1_BASE_ADDR + 0x00080000) -#define I2C3_BASE_ADDR (AIPS1_BASE_ADDR + 0x00084000) #define OTG_BASE_ADDR (AIPS1_BASE_ADDR + 0x00088000) #define ATA_BASE_ADDR (AIPS1_BASE_ADDR + 0x0008C000) -#define UART1_BASE_ADDR (AIPS1_BASE_ADDR + 0x00090000) -#define UART2_BASE_ADDR (AIPS1_BASE_ADDR + 0x00094000) -#define I2C2_BASE_ADDR (AIPS1_BASE_ADDR + 0x00098000) -#define OWIRE_BASE_ADDR (AIPS1_BASE_ADDR + 0x0009C000) -#define SSI1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A0000) -#define CSPI1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A4000) -#define KPP_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A8000) -#define IOMUXC_BASE_ADDR (AIPS1_BASE_ADDR + 0x000AC000) #define UART4_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B0000) #define UART5_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B4000) -#define ECT_IP1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B8000) -#define ECT_IP2_BASE_ADDR (AIPS1_BASE_ADDR + 0x000BC000) - -/* - * SPBA global module enabled #0 - */ -#define SPBA0_BASE_ADDR 0x50000000 -#define SPBA0_BASE_ADDR_VIRT 0xFC100000 -#define SPBA0_SIZE SZ_1M #define MMC_SDHC1_BASE_ADDR (SPBA0_BASE_ADDR + 0x00004000) #define MMC_SDHC2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00008000) -#define UART3_BASE_ADDR (SPBA0_BASE_ADDR + 0x0000C000) -#define CSPI2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00010000) -#define SSI2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00014000) #define SIM1_BASE_ADDR (SPBA0_BASE_ADDR + 0x00018000) #define IIM_BASE_ADDR (SPBA0_BASE_ADDR + 0x0001C000) -#define ATA_DMA_BASE_ADDR (SPBA0_BASE_ADDR + 0x00020000) -#define MSHC1_BASE_ADDR (SPBA0_BASE_ADDR + 0x00024000) -#define MSHC2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00024000) -#define SPBA_CTRL_BASE_ADDR (SPBA0_BASE_ADDR + 0x0003C000) -/* - * AIPS 2 - */ -#define AIPS2_BASE_ADDR 0x53F00000 -#define AIPS2_BASE_ADDR_VIRT 0xFC200000 -#define AIPS2_SIZE SZ_1M -#define CCM_BASE_ADDR (AIPS2_BASE_ADDR + 0x00080000) #define CSPI3_BASE_ADDR (AIPS2_BASE_ADDR + 0x00084000) #define FIRI_BASE_ADDR (AIPS2_BASE_ADDR + 0x0008C000) -#define GPT1_BASE_ADDR (AIPS2_BASE_ADDR + 0x00090000) -#define EPIT1_BASE_ADDR (AIPS2_BASE_ADDR + 0x00094000) -#define EPIT2_BASE_ADDR (AIPS2_BASE_ADDR + 0x00098000) -#define GPIO3_BASE_ADDR (AIPS2_BASE_ADDR + 0x000A4000) -#define SCC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000AC000) #define SCM_BASE_ADDR (AIPS2_BASE_ADDR + 0x000AE000) #define SMN_BASE_ADDR (AIPS2_BASE_ADDR + 0x000AF000) -#define RNGA_BASE_ADDR (AIPS2_BASE_ADDR + 0x000B0000) -#define IPU_CTRL_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C0000) -#define AUDMUX_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C4000) #define MPEG4_ENC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C8000) -#define GPIO1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000CC000) -#define GPIO2_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D0000) -#define SDMA_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D4000) -#define RTC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D8000) -#define WDOG_BASE_ADDR (AIPS2_BASE_ADDR + 0x000DC000) -#define PWM_BASE_ADDR (AIPS2_BASE_ADDR + 0x000E0000) -#define RTIC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000EC000) - -/* - * ROMP and AVIC - */ -#define ROMP_BASE_ADDR 0x60000000 -#define ROMP_BASE_ADDR_VIRT 0xFC500000 -#define ROMP_SIZE SZ_1M - -#define AVIC_BASE_ADDR 0x68000000 -#define AVIC_BASE_ADDR_VIRT 0xFC400000 -#define AVIC_SIZE SZ_1M - -/* - * NAND, SDRAM, WEIM, M3IF, EMI controllers - */ -#define X_MEMC_BASE_ADDR 0xB8000000 -#define X_MEMC_BASE_ADDR_VIRT 0xFC320000 -#define X_MEMC_SIZE SZ_64K -#define NFC_BASE_ADDR (X_MEMC_BASE_ADDR + 0x0000) -#define ESDCTL_BASE_ADDR (X_MEMC_BASE_ADDR + 0x1000) -#define WEIM_BASE_ADDR (X_MEMC_BASE_ADDR + 0x2000) -#define M3IF_BASE_ADDR (X_MEMC_BASE_ADDR + 0x3000) -#define EMI_CTL_BASE_ADDR (X_MEMC_BASE_ADDR + 0x4000) -#define PCMCIA_CTL_BASE_ADDR EMI_CTL_BASE_ADDR +#define MX31_NFC_BASE_ADDR (X_MEMC_BASE_ADDR + 0x0000) -/* - * Memory regions and CS - */ -#define IPU_MEM_BASE_ADDR 0x70000000 -#define CSD0_BASE_ADDR 0x80000000 -#define CSD1_BASE_ADDR 0x90000000 -#define CS0_BASE_ADDR 0xA0000000 -#define CS1_BASE_ADDR 0xA8000000 -#define CS2_BASE_ADDR 0xB0000000 -#define CS3_BASE_ADDR 0xB2000000 - -#define CS4_BASE_ADDR 0xB4000000 -#define CS4_BASE_ADDR_VIRT 0xF4000000 -#define CS4_SIZE SZ_32M - -#define CS5_BASE_ADDR 0xB6000000 -#define PCMCIA_MEM_BASE_ADDR 0xBC000000 - -/*! - * This macro defines the physical to virtual address mapping for all the - * peripheral modules. It is used by passing in the physical address as x - * and returning the virtual address. If the physical address is not mapped, - * it returns 0xDEADBEEF - */ -#define IO_ADDRESS(x) \ - (void __iomem *) \ - (((x >= IRAM_BASE_ADDR) && (x < (IRAM_BASE_ADDR + IRAM_SIZE))) ? IRAM_IO_ADDRESS(x):\ - ((x >= L2CC_BASE_ADDR) && (x < (L2CC_BASE_ADDR + L2CC_SIZE))) ? L2CC_IO_ADDRESS(x):\ - ((x >= AIPS1_BASE_ADDR) && (x < (AIPS1_BASE_ADDR + AIPS1_SIZE))) ? AIPS1_IO_ADDRESS(x):\ - ((x >= SPBA0_BASE_ADDR) && (x < (SPBA0_BASE_ADDR + SPBA0_SIZE))) ? SPBA0_IO_ADDRESS(x):\ - ((x >= AIPS2_BASE_ADDR) && (x < (AIPS2_BASE_ADDR + AIPS2_SIZE))) ? AIPS2_IO_ADDRESS(x):\ - ((x >= ROMP_BASE_ADDR) && (x < (ROMP_BASE_ADDR + ROMP_SIZE))) ? ROMP_IO_ADDRESS(x):\ - ((x >= AVIC_BASE_ADDR) && (x < (AVIC_BASE_ADDR + AVIC_SIZE))) ? AVIC_IO_ADDRESS(x):\ - ((x >= CS4_BASE_ADDR) && (x < (CS4_BASE_ADDR + CS4_SIZE))) ? CS4_IO_ADDRESS(x):\ - ((x >= X_MEMC_BASE_ADDR) && (x < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? X_MEMC_IO_ADDRESS(x):\ - 0xDEADBEEF) - -/* - * define the address mapping macros: in physical address order - */ - -#define IRAM_IO_ADDRESS(x) \ - (((x) - IRAM_BASE_ADDR) + IRAM_BASE_ADDR_VIRT) - -#define L2CC_IO_ADDRESS(x) \ - (((x) - L2CC_BASE_ADDR) + L2CC_BASE_ADDR_VIRT) - -#define AIPS1_IO_ADDRESS(x) \ - (((x) - AIPS1_BASE_ADDR) + AIPS1_BASE_ADDR_VIRT) - -#define SPBA0_IO_ADDRESS(x) \ - (((x) - SPBA0_BASE_ADDR) + SPBA0_BASE_ADDR_VIRT) - -#define AIPS2_IO_ADDRESS(x) \ - (((x) - AIPS2_BASE_ADDR) + AIPS2_BASE_ADDR_VIRT) - -#define ROMP_IO_ADDRESS(x) \ - (((x) - ROMP_BASE_ADDR) + ROMP_BASE_ADDR_VIRT) - -#define AVIC_IO_ADDRESS(x) \ - (((x) - AVIC_BASE_ADDR) + AVIC_BASE_ADDR_VIRT) - -#define CS4_IO_ADDRESS(x) \ - (((x) - CS4_BASE_ADDR) + CS4_BASE_ADDR_VIRT) - -#define X_MEMC_IO_ADDRESS(x) \ - (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT) - -#define PCMCIA_IO_ADDRESS(x) \ - (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT) - -/* - * Interrupt numbers - */ -#define MXC_INT_PEN_ADS7843 0 -#define MXC_INT_RESV1 1 -#define MXC_INT_CS8900A 2 -#define MXC_INT_I2C3 3 -#define MXC_INT_I2C2 4 #define MXC_INT_MPEG4_ENCODER 5 -#define MXC_INT_RTIC 6 #define MXC_INT_FIRI 7 -#define MXC_INT_MMC_SDHC2 8 +#define MX31_INT_MMC_SDHC2 8 #define MXC_INT_MMC_SDHC1 9 -#define MXC_INT_I2C 10 -#define MXC_INT_SSI2 11 -#define MXC_INT_SSI1 12 -#define MXC_INT_CSPI2 13 -#define MXC_INT_CSPI1 14 -#define MXC_INT_ATA 15 +#define MX31_INT_SSI2 11 +#define MX31_INT_SSI1 12 #define MXC_INT_MBX 16 #define MXC_INT_CSPI3 17 -#define MXC_INT_UART3 18 -#define MXC_INT_IIM 19 #define MXC_INT_SIM2 20 #define MXC_INT_SIM1 21 -#define MXC_INT_RNGA 22 -#define MXC_INT_EVTMON 23 -#define MXC_INT_KPP 24 -#define MXC_INT_RTC 25 -#define MXC_INT_PWM 26 -#define MXC_INT_EPIT2 27 -#define MXC_INT_EPIT1 28 -#define MXC_INT_GPT 29 -#define MXC_INT_RESV30 30 -#define MXC_INT_RESV31 31 -#define MXC_INT_UART2 32 -#define MXC_INT_NANDFC 33 -#define MXC_INT_SDMA 34 +#define MXC_INT_CCM_DVFS 31 #define MXC_INT_USB1 35 #define MXC_INT_USB2 36 #define MXC_INT_USB3 37 #define MXC_INT_USB4 38 -#define MXC_INT_MSHC1 39 #define MXC_INT_MSHC2 40 -#define MXC_INT_IPU_ERR 41 -#define MXC_INT_IPU_SYN 42 -#define MXC_INT_RESV43 43 -#define MXC_INT_RESV44 44 -#define MXC_INT_UART1 45 #define MXC_INT_UART4 46 #define MXC_INT_UART5 47 -#define MXC_INT_ECT 48 -#define MXC_INT_SCC_SCM 49 -#define MXC_INT_SCC_SMN 50 -#define MXC_INT_GPIO2 51 -#define MXC_INT_GPIO1 52 #define MXC_INT_CCM 53 #define MXC_INT_PCMCIA 54 -#define MXC_INT_WDOG 55 -#define MXC_INT_GPIO3 56 -#define MXC_INT_RESV57 57 -#define MXC_INT_EXT_POWER 58 -#define MXC_INT_EXT_TEMPER 59 -#define MXC_INT_EXT_SENSOR60 60 -#define MXC_INT_EXT_SENSOR61 61 -#define MXC_INT_EXT_WDOG 62 -#define MXC_INT_EXT_TV 63 - -#define PROD_SIGNATURE 0x1 /* For MX31 */ - -/* silicon revisions specific to i.MX31 */ -#define CHIP_REV_1_0 0x10 -#define CHIP_REV_1_1 0x11 -#define CHIP_REV_1_2 0x12 -#define CHIP_REV_1_3 0x13 -#define CHIP_REV_2_0 0x20 -#define CHIP_REV_2_1 0x21 -#define CHIP_REV_2_2 0x22 -#define CHIP_REV_2_3 0x23 -#define CHIP_REV_3_0 0x30 -#define CHIP_REV_3_1 0x31 -#define CHIP_REV_3_2 0x32 - -#define SYSTEM_REV_MIN CHIP_REV_1_0 -#define SYSTEM_REV_NUM 3 - -/* gpio and gpio based interrupt handling */ -#define GPIO_DR 0x00 -#define GPIO_GDIR 0x04 -#define GPIO_PSR 0x08 -#define GPIO_ICR1 0x0C -#define GPIO_ICR2 0x10 -#define GPIO_IMR 0x14 -#define GPIO_ISR 0x18 -#define GPIO_INT_LOW_LEV 0x0 -#define GPIO_INT_HIGH_LEV 0x1 -#define GPIO_INT_RISE_EDGE 0x2 -#define GPIO_INT_FALL_EDGE 0x3 -#define GPIO_INT_NONE 0x4 - -/* Mandatory defines used globally */ - -/* this CPU supports up to 96 GPIOs */ -#define ARCH_NR_GPIOS 96 - -#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS) - -/* this is a i.MX31 CPU */ -#define cpu_is_mx31() (1) - -extern unsigned int system_rev; - -static inline int mx31_revision(void) -{ - return system_rev; -} -#endif -#endif /* __ASM_ARCH_MXC_MX31_H__ */ diff --git a/arch/arm/plat-mxc/include/mach/mx35.h b/arch/arm/plat-mxc/include/mach/mx35.h new file mode 100644 index 000000000000..6465fefb42e3 --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/mx35.h @@ -0,0 +1,29 @@ +/* + * IRAM + */ +#define MX35_IRAM_BASE_ADDR 0x10000000 /* internal ram */ +#define MX35_IRAM_SIZE SZ_128K + +#define MXC_FEC_BASE_ADDR 0x50038000 +#define MX35_NFC_BASE_ADDR 0xBB000000 + +/* + * Interrupt numbers + */ +#define MXC_INT_OWIRE 2 +#define MX35_INT_MMC_SDHC1 7 +#define MXC_INT_MMC_SDHC2 8 +#define MXC_INT_MMC_SDHC3 9 +#define MX35_INT_SSI1 11 +#define MX35_INT_SSI2 12 +#define MXC_INT_GPU2D 16 +#define MXC_INT_ASRC 17 +#define MXC_INT_USBHS 35 +#define MXC_INT_USBOTG 37 +#define MXC_INT_ESAI 40 +#define MXC_INT_CAN1 43 +#define MXC_INT_CAN2 44 +#define MXC_INT_MLB 46 +#define MXC_INT_SPDIF 47 +#define MXC_INT_FEC 57 + diff --git a/arch/arm/plat-mxc/include/mach/mx3x.h b/arch/arm/plat-mxc/include/mach/mx3x.h new file mode 100644 index 000000000000..83a172b51b05 --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/mx3x.h @@ -0,0 +1,290 @@ +/* + * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved. + */ + +/* + * 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. + */ + +#ifndef __ASM_ARCH_MXC_MX31_H__ +#define __ASM_ARCH_MXC_MX31_H__ + +#ifndef __ASM_ARCH_MXC_HARDWARE_H__ +#error "Do not include directly." +#endif + +/* + * MX31 memory map: + * + * Virt Phys Size What + * --------------------------------------------------------------------------- + * FC000000 43F00000 1M AIPS 1 + * FC100000 50000000 1M SPBA + * FC200000 53F00000 1M AIPS 2 + * FC500000 60000000 128M ROMPATCH + * FC400000 68000000 128M AVIC + * 70000000 256M IPU (MAX M2) + * 80000000 256M CSD0 SDRAM/DDR + * 90000000 256M CSD1 SDRAM/DDR + * A0000000 128M CS0 Flash + * A8000000 128M CS1 Flash + * B0000000 32M CS2 + * B2000000 32M CS3 + * F4000000 B4000000 32M CS4 + * B6000000 32M CS5 + * FC320000 B8000000 64K NAND, SDRAM, WEIM, M3IF, EMI controllers + * C0000000 64M PCMCIA/CF + */ + +#define CS0_BASE_ADDR 0xA0000000 +#define CS1_BASE_ADDR 0xA8000000 +#define CS2_BASE_ADDR 0xB0000000 +#define CS3_BASE_ADDR 0xB2000000 + +#define CS4_BASE_ADDR 0xB4000000 +#define CS4_BASE_ADDR_VIRT 0xF4000000 +#define CS4_SIZE SZ_32M + +#define CS5_BASE_ADDR 0xB6000000 +#define PCMCIA_MEM_BASE_ADDR 0xBC000000 + +/* + * L2CC + */ +#define L2CC_BASE_ADDR 0x30000000 +#define L2CC_SIZE SZ_1M + +/* + * AIPS 1 + */ +#define AIPS1_BASE_ADDR 0x43F00000 +#define AIPS1_BASE_ADDR_VIRT 0xFC000000 +#define AIPS1_SIZE SZ_1M + +#define MAX_BASE_ADDR (AIPS1_BASE_ADDR + 0x00004000) +#define EVTMON_BASE_ADDR (AIPS1_BASE_ADDR + 0x00008000) +#define CLKCTL_BASE_ADDR (AIPS1_BASE_ADDR + 0x0000C000) +#define ETB_SLOT4_BASE_ADDR (AIPS1_BASE_ADDR + 0x00010000) +#define ETB_SLOT5_BASE_ADDR (AIPS1_BASE_ADDR + 0x00014000) +#define ECT_CTIO_BASE_ADDR (AIPS1_BASE_ADDR + 0x00018000) +#define I2C_BASE_ADDR (AIPS1_BASE_ADDR + 0x00080000) +#define I2C3_BASE_ADDR (AIPS1_BASE_ADDR + 0x00084000) +#define UART1_BASE_ADDR (AIPS1_BASE_ADDR + 0x00090000) +#define UART2_BASE_ADDR (AIPS1_BASE_ADDR + 0x00094000) +#define I2C2_BASE_ADDR (AIPS1_BASE_ADDR + 0x00098000) +#define OWIRE_BASE_ADDR (AIPS1_BASE_ADDR + 0x0009C000) +#define SSI1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A0000) +#define CSPI1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A4000) +#define KPP_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A8000) +#define IOMUXC_BASE_ADDR (AIPS1_BASE_ADDR + 0x000AC000) +#define ECT_IP1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B8000) +#define ECT_IP2_BASE_ADDR (AIPS1_BASE_ADDR + 0x000BC000) + +/* + * SPBA global module enabled #0 + */ +#define SPBA0_BASE_ADDR 0x50000000 +#define SPBA0_BASE_ADDR_VIRT 0xFC100000 +#define SPBA0_SIZE SZ_1M + +#define UART3_BASE_ADDR (SPBA0_BASE_ADDR + 0x0000C000) +#define CSPI2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00010000) +#define SSI2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00014000) +#define ATA_DMA_BASE_ADDR (SPBA0_BASE_ADDR + 0x00020000) +#define MSHC1_BASE_ADDR (SPBA0_BASE_ADDR + 0x00024000) +#define SPBA_CTRL_BASE_ADDR (SPBA0_BASE_ADDR + 0x0003C000) + +/* + * AIPS 2 + */ +#define AIPS2_BASE_ADDR 0x53F00000 +#define AIPS2_BASE_ADDR_VIRT 0xFC200000 +#define AIPS2_SIZE SZ_1M +#define CCM_BASE_ADDR (AIPS2_BASE_ADDR + 0x00080000) +#define GPT1_BASE_ADDR (AIPS2_BASE_ADDR + 0x00090000) +#define EPIT1_BASE_ADDR (AIPS2_BASE_ADDR + 0x00094000) +#define EPIT2_BASE_ADDR (AIPS2_BASE_ADDR + 0x00098000) +#define GPIO3_BASE_ADDR (AIPS2_BASE_ADDR + 0x000A4000) +#define SCC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000AC000) +#define RNGA_BASE_ADDR (AIPS2_BASE_ADDR + 0x000B0000) +#define IPU_CTRL_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C0000) +#define AUDMUX_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C4000) +#define GPIO1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000CC000) +#define GPIO2_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D0000) +#define SDMA_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D4000) +#define RTC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D8000) +#define WDOG_BASE_ADDR (AIPS2_BASE_ADDR + 0x000DC000) +#define PWM_BASE_ADDR (AIPS2_BASE_ADDR + 0x000E0000) +#define RTIC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000EC000) + +/* + * ROMP and AVIC + */ +#define ROMP_BASE_ADDR 0x60000000 +#define ROMP_BASE_ADDR_VIRT 0xFC500000 +#define ROMP_SIZE SZ_1M + +#define AVIC_BASE_ADDR 0x68000000 +#define AVIC_BASE_ADDR_VIRT 0xFC400000 +#define AVIC_SIZE SZ_1M + +/* + * NAND, SDRAM, WEIM, M3IF, EMI controllers + */ +#define X_MEMC_BASE_ADDR 0xB8000000 +#define X_MEMC_BASE_ADDR_VIRT 0xFC320000 +#define X_MEMC_SIZE SZ_64K + +#define ESDCTL_BASE_ADDR (X_MEMC_BASE_ADDR + 0x1000) +#define WEIM_BASE_ADDR (X_MEMC_BASE_ADDR + 0x2000) +#define M3IF_BASE_ADDR (X_MEMC_BASE_ADDR + 0x3000) +#define EMI_CTL_BASE_ADDR (X_MEMC_BASE_ADDR + 0x4000) +#define PCMCIA_CTL_BASE_ADDR EMI_CTL_BASE_ADDR + +/* + * Memory regions and CS + */ +#define IPU_MEM_BASE_ADDR 0x70000000 +#define CSD0_BASE_ADDR 0x80000000 +#define CSD1_BASE_ADDR 0x90000000 + +/*! + * This macro defines the physical to virtual address mapping for all the + * peripheral modules. It is used by passing in the physical address as x + * and returning the virtual address. If the physical address is not mapped, + * it returns 0xDEADBEEF + */ +#define IO_ADDRESS(x) \ + (void __iomem *) \ + (((x >= AIPS1_BASE_ADDR) && (x < (AIPS1_BASE_ADDR + AIPS1_SIZE))) ? AIPS1_IO_ADDRESS(x):\ + ((x >= SPBA0_BASE_ADDR) && (x < (SPBA0_BASE_ADDR + SPBA0_SIZE))) ? SPBA0_IO_ADDRESS(x):\ + ((x >= AIPS2_BASE_ADDR) && (x < (AIPS2_BASE_ADDR + AIPS2_SIZE))) ? AIPS2_IO_ADDRESS(x):\ + ((x >= ROMP_BASE_ADDR) && (x < (ROMP_BASE_ADDR + ROMP_SIZE))) ? ROMP_IO_ADDRESS(x):\ + ((x >= AVIC_BASE_ADDR) && (x < (AVIC_BASE_ADDR + AVIC_SIZE))) ? AVIC_IO_ADDRESS(x):\ + ((x >= CS4_BASE_ADDR) && (x < (CS4_BASE_ADDR + CS4_SIZE))) ? CS4_IO_ADDRESS(x):\ + ((x >= X_MEMC_BASE_ADDR) && (x < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? X_MEMC_IO_ADDRESS(x):\ + 0xDEADBEEF) + +/* + * define the address mapping macros: in physical address order + */ +#define L2CC_IO_ADDRESS(x) \ + (((x) - L2CC_BASE_ADDR) + L2CC_BASE_ADDR_VIRT) + +#define AIPS1_IO_ADDRESS(x) \ + (((x) - AIPS1_BASE_ADDR) + AIPS1_BASE_ADDR_VIRT) + +#define SPBA0_IO_ADDRESS(x) \ + (((x) - SPBA0_BASE_ADDR) + SPBA0_BASE_ADDR_VIRT) + +#define AIPS2_IO_ADDRESS(x) \ + (((x) - AIPS2_BASE_ADDR) + AIPS2_BASE_ADDR_VIRT) + +#define ROMP_IO_ADDRESS(x) \ + (((x) - ROMP_BASE_ADDR) + ROMP_BASE_ADDR_VIRT) + +#define AVIC_IO_ADDRESS(x) \ + (((x) - AVIC_BASE_ADDR) + AVIC_BASE_ADDR_VIRT) + +#define CS4_IO_ADDRESS(x) \ + (((x) - CS4_BASE_ADDR) + CS4_BASE_ADDR_VIRT) + +#define X_MEMC_IO_ADDRESS(x) \ + (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT) + +#define PCMCIA_IO_ADDRESS(x) \ + (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT) + +/* + * Interrupt numbers + */ +#define MXC_INT_I2C3 3 +#define MXC_INT_I2C2 4 +#define MXC_INT_RTIC 6 +#define MXC_INT_I2C 10 +#define MXC_INT_CSPI2 13 +#define MXC_INT_CSPI1 14 +#define MXC_INT_ATA 15 +#define MXC_INT_UART3 18 +#define MXC_INT_IIM 19 +#define MXC_INT_RNGA 22 +#define MXC_INT_EVTMON 23 +#define MXC_INT_KPP 24 +#define MXC_INT_RTC 25 +#define MXC_INT_PWM 26 +#define MXC_INT_EPIT2 27 +#define MXC_INT_EPIT1 28 +#define MXC_INT_GPT 29 +#define MXC_INT_POWER_FAIL 30 +#define MXC_INT_UART2 32 +#define MXC_INT_NANDFC 33 +#define MXC_INT_SDMA 34 +#define MXC_INT_MSHC1 39 +#define MXC_INT_IPU_ERR 41 +#define MXC_INT_IPU_SYN 42 +#define MXC_INT_UART1 45 +#define MXC_INT_ECT 48 +#define MXC_INT_SCC_SCM 49 +#define MXC_INT_SCC_SMN 50 +#define MXC_INT_GPIO2 51 +#define MXC_INT_GPIO1 52 +#define MXC_INT_WDOG 55 +#define MXC_INT_GPIO3 56 +#define MXC_INT_EXT_POWER 58 +#define MXC_INT_EXT_TEMPER 59 +#define MXC_INT_EXT_SENSOR60 60 +#define MXC_INT_EXT_SENSOR61 61 +#define MXC_INT_EXT_WDOG 62 +#define MXC_INT_EXT_TV 63 + +#define PROD_SIGNATURE 0x1 /* For MX31 */ + +/* silicon revisions specific to i.MX31 */ +#define CHIP_REV_1_0 0x10 +#define CHIP_REV_1_1 0x11 +#define CHIP_REV_1_2 0x12 +#define CHIP_REV_1_3 0x13 +#define CHIP_REV_2_0 0x20 +#define CHIP_REV_2_1 0x21 +#define CHIP_REV_2_2 0x22 +#define CHIP_REV_2_3 0x23 +#define CHIP_REV_3_0 0x30 +#define CHIP_REV_3_1 0x31 +#define CHIP_REV_3_2 0x32 + +#define SYSTEM_REV_MIN CHIP_REV_1_0 +#define SYSTEM_REV_NUM 3 + +/* gpio and gpio based interrupt handling */ +#define GPIO_DR 0x00 +#define GPIO_GDIR 0x04 +#define GPIO_PSR 0x08 +#define GPIO_ICR1 0x0C +#define GPIO_ICR2 0x10 +#define GPIO_IMR 0x14 +#define GPIO_ISR 0x18 +#define GPIO_INT_LOW_LEV 0x0 +#define GPIO_INT_HIGH_LEV 0x1 +#define GPIO_INT_RISE_EDGE 0x2 +#define GPIO_INT_FALL_EDGE 0x3 +#define GPIO_INT_NONE 0x4 + +/* Mandatory defines used globally */ + +/* this CPU supports up to 96 GPIOs */ +#define ARCH_NR_GPIOS 96 + +#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS) + +extern unsigned int system_rev; + +static inline int mx31_revision(void) +{ + return system_rev; +} +#endif + +#endif /* __ASM_ARCH_MXC_MX31_H__ */ + -- cgit v1.2.3 From 198016e1b12d781ef00aaafbf571775a8e723f54 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 6 Feb 2009 15:38:22 +0100 Subject: [ARM] MXC: add cpu_is_ macros We had hardcoded cpu_is_ macros for mxc architectures till now. As we want to run the same kernel on i.MX31 and i.MX35 this patch adds cpu_is_ macros which expand to 0 or 1 if only one architecture is compiled in and only check for the cpu type if more than one architecture is compiled in. Signed-off-by: Sascha Hauer --- arch/arm/mach-mx3/clock.c | 2 + arch/arm/plat-mxc/Makefile | 2 +- arch/arm/plat-mxc/cpu.c | 11 +++++ arch/arm/plat-mxc/include/mach/common.h | 1 + arch/arm/plat-mxc/include/mach/mx21.h | 3 -- arch/arm/plat-mxc/include/mach/mx27.h | 3 -- arch/arm/plat-mxc/include/mach/mxc.h | 74 +++++++++++++++++++++++++++++---- 7 files changed, 80 insertions(+), 16 deletions(-) create mode 100644 arch/arm/plat-mxc/cpu.c (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/mach-mx3/clock.c b/arch/arm/mach-mx3/clock.c index bc3a3beb9a66..9ab5f8b2bc30 100644 --- a/arch/arm/mach-mx3/clock.c +++ b/arch/arm/mach-mx3/clock.c @@ -1077,6 +1077,8 @@ int __init mx31_clocks_init(unsigned long fref) u32 reg; struct clk **clkp; + mxc_set_cpu_type(MXC_CPU_MX31); + ckih_rate = fref; for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++) diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index f204192f9b94..564fd4ebf38a 100644 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile @@ -3,7 +3,7 @@ # # Common support -obj-y := irq.o clock.o gpio.o time.o devices.o +obj-y := irq.o clock.o gpio.o time.o devices.o cpu.o obj-$(CONFIG_ARCH_MX1) += iomux-mx1-mx2.o dma-mx1-mx2.o obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o diff --git a/arch/arm/plat-mxc/cpu.c b/arch/arm/plat-mxc/cpu.c new file mode 100644 index 000000000000..386e0d52cf58 --- /dev/null +++ b/arch/arm/plat-mxc/cpu.c @@ -0,0 +1,11 @@ + +#include + +unsigned int __mxc_cpu_type; +EXPORT_SYMBOL(__mxc_cpu_type); + +void mxc_set_cpu_type(unsigned int type) +{ + __mxc_cpu_type = type; +} + diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h index 3051eee99530..f467159cbdce 100644 --- a/arch/arm/plat-mxc/include/mach/common.h +++ b/arch/arm/plat-mxc/include/mach/common.h @@ -23,5 +23,6 @@ extern int mx27_clocks_init(unsigned long fref); extern int mx31_clocks_init(unsigned long fref); extern int mxc_register_gpios(void); extern int mxc_register_device(struct platform_device *pdev, void *data); +extern void mxc_set_cpu_type(unsigned int type); #endif diff --git a/arch/arm/plat-mxc/include/mach/mx21.h b/arch/arm/plat-mxc/include/mach/mx21.h index cfdbe051caf6..e8c4cf56c24e 100644 --- a/arch/arm/plat-mxc/include/mach/mx21.h +++ b/arch/arm/plat-mxc/include/mach/mx21.h @@ -54,9 +54,6 @@ #define IRAM_BASE_ADDR 0xFFFFE800 /* internal ram */ -/* this is an i.MX21 CPU */ -#define cpu_is_mx21() (1) - /* this CPU supports up to 192 GPIOs (don't forget the baseboard!) */ #define ARCH_NR_GPIOS (6*32 + 16) diff --git a/arch/arm/plat-mxc/include/mach/mx27.h b/arch/arm/plat-mxc/include/mach/mx27.h index 5f6a8a7bb19c..6e93f2c0b7bb 100644 --- a/arch/arm/plat-mxc/include/mach/mx27.h +++ b/arch/arm/plat-mxc/include/mach/mx27.h @@ -120,9 +120,6 @@ extern int mx27_revision(void); /* Mandatory defines used globally */ -/* this is an i.MX27 CPU */ -#define cpu_is_mx27() (1) - /* this CPU supports up to 192 GPIOs (don't forget the baseboard!) */ #define ARCH_NR_GPIOS (192 + 16) diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h index d6b0c472cd97..5fa2a07f4eaf 100644 --- a/arch/arm/plat-mxc/include/mach/mxc.h +++ b/arch/arm/plat-mxc/include/mach/mxc.h @@ -24,21 +24,74 @@ #error "Do not include directly." #endif -/* clean up all things that are not used */ -#ifndef CONFIG_ARCH_MX3 -# define cpu_is_mx31() (0) +#define MXC_CPU_MX1 1 +#define MXC_CPU_MX21 21 +#define MXC_CPU_MX27 27 +#define MXC_CPU_MX31 31 +#define MXC_CPU_MX35 35 + +#ifndef __ASSEMBLY__ +extern unsigned int __mxc_cpu_type; +#endif + +#ifdef CONFIG_ARCH_MX1 +# ifdef mxc_cpu_type +# undef mxc_cpu_type +# define mxc_cpu_type __mxc_cpu_type +# else +# define mxc_cpu_type MXC_CPU_MX1 +# endif +# define cpu_is_mx1() (mxc_cpu_type == MXC_CPU_MX1) +#else +# define cpu_is_mx1() (0) #endif -#ifndef CONFIG_MACH_MX21 -# define cpu_is_mx21() (0) +#ifdef CONFIG_MACH_MX21 +# ifdef mxc_cpu_type +# undef mxc_cpu_type +# define mxc_cpu_type __mxc_cpu_type +# else +# define mxc_cpu_type MXC_CPU_MX21 +# endif +# define cpu_is_mx21() (mxc_cpu_type == MXC_CPU_MX21) +#else +# define cpu_is_mx21() (0) #endif -#ifndef CONFIG_MACH_MX27 -# define cpu_is_mx27() (0) +#ifdef CONFIG_MACH_MX27 +# ifdef mxc_cpu_type +# undef mxc_cpu_type +# define mxc_cpu_type __mxc_cpu_type +# else +# define mxc_cpu_type MXC_CPU_MX27 +# endif +# define cpu_is_mx27() (mxc_cpu_type == MXC_CPU_MX27) +#else +# define cpu_is_mx27() (0) #endif -#ifndef CONFIG_MACH_MX21 -# define cpu_is_mx21() (0) +#ifdef CONFIG_ARCH_MX31 +# ifdef mxc_cpu_type +# undef mxc_cpu_type +# define mxc_cpu_type __mxc_cpu_type +# else +# define mxc_cpu_type MXC_CPU_MX31 +# endif +# define cpu_is_mx31() (mxc_cpu_type == MXC_CPU_MX31) +#else +# define cpu_is_mx31() (0) +#endif + +#ifdef CONFIG_ARCH_MX35 +# ifdef mxc_cpu_type +# undef mxc_cpu_type +# define mxc_cpu_type __mxc_cpu_type +# else +# define mxc_cpu_type MXC_CPU_MX35 +# endif +# define cpu_is_mx35() (mxc_cpu_type == MXC_CPU_MX35) +#else +# define cpu_is_mx35() (0) #endif #if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX2) @@ -47,4 +100,7 @@ #define CSCR_A(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x8) #endif +#define cpu_is_mx3() (cpu_is_mx31() || cpu_is_mx35()) +#define cpu_is_mx2() (cpu_is_mx21() || cpu_is_mx27()) + #endif /* __ASM_ARCH_MXC_H__ */ -- cgit v1.2.3 From 2cb536d13cf9fbce029055b7603b3ca4ca1cf407 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 6 Feb 2009 17:48:59 +0100 Subject: [ARM] MX35: add clock support This patch adds clock support for i.MX35 SoCs. We do not support setting of clock rates yet, but most interesting clock rates should be reported. I couldn't test all clock rates and the datasheet contains some obvious bugs, so expect some bugs in this code. Signed-off-by: Sascha Hauer --- arch/arm/mach-mx3/Makefile | 1 + arch/arm/mach-mx3/clock-imx35.c | 487 ++++++++++++++++++++++++++++++++ arch/arm/plat-mxc/include/mach/common.h | 1 + 3 files changed, 489 insertions(+) create mode 100644 arch/arm/mach-mx3/clock-imx35.c (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index 68c4837cce6a..ab0bec0a4d92 100644 --- a/arch/arm/mach-mx3/Makefile +++ b/arch/arm/mach-mx3/Makefile @@ -6,6 +6,7 @@ obj-y := mm.o devices.o obj-$(CONFIG_ARCH_MX31) += clock.o iomux.o +obj-$(CONFIG_ARCH_MX35) += clock-imx35.o obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o obj-$(CONFIG_MACH_MX31LITE) += mx31lite.o obj-$(CONFIG_MACH_PCM037) += pcm037.o diff --git a/arch/arm/mach-mx3/clock-imx35.c b/arch/arm/mach-mx3/clock-imx35.c new file mode 100644 index 000000000000..53a112d4e04a --- /dev/null +++ b/arch/arm/mach-mx3/clock-imx35.c @@ -0,0 +1,487 @@ +/* + * Copyright (C) 2009 by Sascha Hauer, Pengutronix + * + * 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. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#define CCM_BASE IO_ADDRESS(CCM_BASE_ADDR) + +#define CCM_CCMR 0x00 +#define CCM_PDR0 0x04 +#define CCM_PDR1 0x08 +#define CCM_PDR2 0x0C +#define CCM_PDR3 0x10 +#define CCM_PDR4 0x14 +#define CCM_RCSR 0x18 +#define CCM_MPCTL 0x1C +#define CCM_PPCTL 0x20 +#define CCM_ACMR 0x24 +#define CCM_COSR 0x28 +#define CCM_CGR0 0x2C +#define CCM_CGR1 0x30 +#define CCM_CGR2 0x34 +#define CCM_CGR3 0x38 + +#ifdef HAVE_SET_RATE_SUPPORT +static void calc_dividers(u32 div, u32 *pre, u32 *post, u32 maxpost) +{ + u32 min_pre, temp_pre, old_err, err; + + min_pre = (div - 1) / maxpost + 1; + old_err = 8; + + for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) { + if (div > (temp_pre * maxpost)) + break; + + if (div < (temp_pre * temp_pre)) + continue; + + err = div % temp_pre; + + if (err == 0) { + *pre = temp_pre; + break; + } + + err = temp_pre - err; + + if (err < old_err) { + old_err = err; + *pre = temp_pre; + } + } + + *post = (div + *pre - 1) / *pre; +} + +/* get the best values for a 3-bit divider combined with a 6-bit divider */ +static void calc_dividers_3_6(u32 div, u32 *pre, u32 *post) +{ + if (div >= 512) { + *pre = 8; + *post = 64; + } else if (div >= 64) { + calc_dividers(div, pre, post, 64); + } else if (div <= 8) { + *pre = div; + *post = 1; + } else { + *pre = 1; + *post = div; + } +} + +/* get the best values for two cascaded 3-bit dividers */ +static void calc_dividers_3_3(u32 div, u32 *pre, u32 *post) +{ + if (div >= 64) { + *pre = *post = 8; + } else if (div > 8) { + calc_dividers(div, pre, post, 8); + } else { + *pre = 1; + *post = div; + } +} +#endif + +static unsigned long get_rate_mpll(void) +{ + ulong mpctl = __raw_readl(CCM_BASE + CCM_MPCTL); + + return mxc_decode_pll(mpctl, 24000000); +} + +static unsigned long get_rate_ppll(void) +{ + ulong ppctl = __raw_readl(CCM_BASE + CCM_PPCTL); + + return mxc_decode_pll(ppctl, 24000000); +} + +struct arm_ahb_div { + unsigned char arm, ahb, sel; +}; + +static struct arm_ahb_div clk_consumer[] = { + { .arm = 1, .ahb = 4, .sel = 0}, + { .arm = 1, .ahb = 3, .sel = 1}, + { .arm = 2, .ahb = 2, .sel = 0}, + { .arm = 0, .ahb = 0, .sel = 0}, + { .arm = 0, .ahb = 0, .sel = 0}, + { .arm = 0, .ahb = 0, .sel = 0}, + { .arm = 4, .ahb = 1, .sel = 0}, + { .arm = 1, .ahb = 5, .sel = 0}, + { .arm = 1, .ahb = 8, .sel = 0}, + { .arm = 1, .ahb = 6, .sel = 1}, + { .arm = 2, .ahb = 4, .sel = 0}, + { .arm = 0, .ahb = 0, .sel = 0}, + { .arm = 0, .ahb = 0, .sel = 0}, + { .arm = 0, .ahb = 0, .sel = 0}, + { .arm = 4, .ahb = 2, .sel = 0}, + { .arm = 0, .ahb = 0, .sel = 0}, +}; + +static struct arm_ahb_div clk_automotive[] = { + { .arm = 1, .ahb = 3, .sel = 0}, + { .arm = 1, .ahb = 2, .sel = 1}, + { .arm = 2, .ahb = 1, .sel = 1}, + { .arm = 0, .ahb = 0, .sel = 0}, + { .arm = 1, .ahb = 6, .sel = 0}, + { .arm = 1, .ahb = 4, .sel = 1}, + { .arm = 2, .ahb = 2, .sel = 1}, + { .arm = 0, .ahb = 0, .sel = 0}, +}; + +static unsigned long get_rate_arm(void) +{ + unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0); + struct arm_ahb_div *aad; + unsigned long fref = get_rate_mpll(); + + if (pdr0 & 1) { + /* consumer path */ + aad = &clk_consumer[(pdr0 >> 16) & 0xf]; + if (aad->sel) + fref = fref * 2 / 3; + } else { + /* auto path */ + aad = &clk_automotive[(pdr0 >> 9) & 0x7]; + if (aad->sel) + fref = fref * 3 / 4; + } + return fref / aad->arm; +} + +static unsigned long get_rate_ahb(struct clk *clk) +{ + unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0); + struct arm_ahb_div *aad; + unsigned long fref = get_rate_mpll(); + + if (pdr0 & 1) + /* consumer path */ + aad = &clk_consumer[(pdr0 >> 16) & 0xf]; + else + /* auto path */ + aad = &clk_automotive[(pdr0 >> 9) & 0x7]; + + return fref / aad->ahb; +} + +static unsigned long get_rate_ipg(struct clk *clk) +{ + return get_rate_ahb(NULL) >> 1; +} + +static unsigned long get_3_3_div(unsigned long in) +{ + return (((in >> 3) & 0x7) + 1) * ((in & 0x7) + 1); +} + +static unsigned long get_rate_uart(struct clk *clk) +{ + unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3); + unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4); + unsigned long div = get_3_3_div(pdr4 >> 10); + + if (pdr3 & (1 << 14)) + return get_rate_arm() / div; + else + return get_rate_ppll() / div; +} + +static unsigned long get_rate_sdhc(struct clk *clk) +{ + unsigned long pdr3 = __raw_readl(CCM_BASE + CCM_PDR3); + unsigned long div, rate; + + if (pdr3 & (1 << 6)) + rate = get_rate_arm(); + else + rate = get_rate_ppll(); + + switch (clk->id) { + default: + case 0: + div = pdr3 & 0x3f; + break; + case 1: + div = (pdr3 >> 8) & 0x3f; + break; + case 2: + div = (pdr3 >> 16) & 0x3f; + break; + } + + return rate / get_3_3_div(div); +} + +static unsigned long get_rate_mshc(struct clk *clk) +{ + unsigned long pdr1 = __raw_readl(CCM_BASE + CCM_PDR1); + unsigned long div1, div2, rate; + + if (pdr1 & (1 << 7)) + rate = get_rate_arm(); + else + rate = get_rate_ppll(); + + div1 = (pdr1 >> 29) & 0x7; + div2 = (pdr1 >> 22) & 0x3f; + + return rate / ((div1 + 1) * (div2 + 1)); +} + +static unsigned long get_rate_ssi(struct clk *clk) +{ + unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2); + unsigned long div1, div2, rate; + + if (pdr2 & (1 << 6)) + rate = get_rate_arm(); + else + rate = get_rate_ppll(); + + switch (clk->id) { + default: + case 0: + div1 = pdr2 & 0x3f; + div2 = (pdr2 >> 24) & 0x7; + break; + case 1: + div1 = (pdr2 >> 8) & 0x3f; + div2 = (pdr2 >> 27) & 0x7; + break; + } + + return rate / ((div1 + 1) * (div2 + 1)); +} + +static unsigned long get_rate_csi(struct clk *clk) +{ + unsigned long pdr2 = __raw_readl(CCM_BASE + CCM_PDR2); + unsigned long rate; + + if (pdr2 & (1 << 7)) + rate = get_rate_arm(); + else + rate = get_rate_ppll(); + + return rate / get_3_3_div((pdr2 >> 16) & 0x3f); +} + +static unsigned long get_rate_ipg_per(struct clk *clk) +{ + unsigned long pdr0 = __raw_readl(CCM_BASE + CCM_PDR0); + unsigned long pdr4 = __raw_readl(CCM_BASE + CCM_PDR4); + unsigned long div1, div2; + + if (pdr0 & (1 << 26)) { + div1 = (pdr4 >> 19) & 0x7; + div2 = (pdr4 >> 16) & 0x7; + return get_rate_arm() / ((div1 + 1) * (div2 + 1)); + } else { + div1 = (pdr0 >> 12) & 0x7; + return get_rate_ahb(NULL) / div1; + } +} + +static int clk_cgr_enable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(clk->enable_reg); + reg |= 3 << clk->enable_shift; + __raw_writel(reg, clk->enable_reg); + + return 0; +} + +static void clk_cgr_disable(struct clk *clk) +{ + u32 reg; + + reg = __raw_readl(clk->enable_reg); + reg &= ~(3 << clk->enable_shift); + __raw_writel(reg, clk->enable_reg); +} + +#define DEFINE_CLOCK(name, i, er, es, gr, sr) \ + static struct clk name = { \ + .id = i, \ + .enable_reg = CCM_BASE + er, \ + .enable_shift = es, \ + .get_rate = gr, \ + .set_rate = sr, \ + .enable = clk_cgr_enable, \ + .disable = clk_cgr_disable, \ + } + +DEFINE_CLOCK(asrc_clk, 0, CCM_CGR0, 0, NULL, NULL); +DEFINE_CLOCK(ata_clk, 0, CCM_CGR0, 2, get_rate_ipg, NULL); +DEFINE_CLOCK(audmux_clk, 0, CCM_CGR0, 4, NULL, NULL); +DEFINE_CLOCK(can1_clk, 0, CCM_CGR0, 6, get_rate_ipg, NULL); +DEFINE_CLOCK(can2_clk, 1, CCM_CGR0, 8, get_rate_ipg, NULL); +DEFINE_CLOCK(cspi1_clk, 0, CCM_CGR0, 10, get_rate_ipg, NULL); +DEFINE_CLOCK(cspi2_clk, 1, CCM_CGR0, 12, get_rate_ipg, NULL); +DEFINE_CLOCK(ect_clk, 0, CCM_CGR0, 14, get_rate_ipg, NULL); +DEFINE_CLOCK(edio_clk, 0, CCM_CGR0, 16, NULL, NULL); +DEFINE_CLOCK(emi_clk, 0, CCM_CGR0, 18, get_rate_ipg, NULL); +DEFINE_CLOCK(epit1_clk, 0, CCM_CGR0, 20, get_rate_ipg_per, NULL); +DEFINE_CLOCK(epit2_clk, 1, CCM_CGR0, 22, get_rate_ipg_per, NULL); +DEFINE_CLOCK(esai_clk, 0, CCM_CGR0, 24, NULL, NULL); +DEFINE_CLOCK(esdhc1_clk, 0, CCM_CGR0, 26, get_rate_sdhc, NULL); +DEFINE_CLOCK(esdhc2_clk, 1, CCM_CGR0, 28, get_rate_sdhc, NULL); +DEFINE_CLOCK(esdhc3_clk, 2, CCM_CGR0, 30, get_rate_sdhc, NULL); + +DEFINE_CLOCK(fec_clk, 0, CCM_CGR1, 0, get_rate_ipg, NULL); +DEFINE_CLOCK(gpio1_clk, 0, CCM_CGR1, 2, NULL, NULL); +DEFINE_CLOCK(gpio2_clk, 1, CCM_CGR1, 4, NULL, NULL); +DEFINE_CLOCK(gpio3_clk, 2, CCM_CGR1, 6, NULL, NULL); +DEFINE_CLOCK(gpt_clk, 0, CCM_CGR1, 8, get_rate_ipg, NULL); +DEFINE_CLOCK(i2c1_clk, 0, CCM_CGR1, 10, get_rate_ipg_per, NULL); +DEFINE_CLOCK(i2c2_clk, 1, CCM_CGR1, 12, get_rate_ipg_per, NULL); +DEFINE_CLOCK(i2c3_clk, 2, CCM_CGR1, 14, get_rate_ipg_per, NULL); +DEFINE_CLOCK(iomuxc_clk, 0, CCM_CGR1, 16, NULL, NULL); +DEFINE_CLOCK(ipu_clk, 0, CCM_CGR1, 18, NULL, NULL); +DEFINE_CLOCK(kpp_clk, 0, CCM_CGR1, 20, get_rate_ipg, NULL); +DEFINE_CLOCK(mlb_clk, 0, CCM_CGR1, 22, get_rate_ahb, NULL); +DEFINE_CLOCK(mshc_clk, 0, CCM_CGR1, 24, get_rate_mshc, NULL); +DEFINE_CLOCK(owire_clk, 0, CCM_CGR1, 26, get_rate_ipg_per, NULL); +DEFINE_CLOCK(pwm_clk, 0, CCM_CGR1, 28, get_rate_ipg_per, NULL); +DEFINE_CLOCK(rngc_clk, 0, CCM_CGR1, 30, get_rate_ipg, NULL); + +DEFINE_CLOCK(rtc_clk, 0, CCM_CGR2, 0, get_rate_ipg, NULL); +DEFINE_CLOCK(rtic_clk, 0, CCM_CGR2, 2, get_rate_ahb, NULL); +DEFINE_CLOCK(scc_clk, 0, CCM_CGR2, 4, get_rate_ipg, NULL); +DEFINE_CLOCK(sdma_clk, 0, CCM_CGR2, 6, NULL, NULL); +DEFINE_CLOCK(spba_clk, 0, CCM_CGR2, 8, get_rate_ipg, NULL); +DEFINE_CLOCK(spdif_clk, 0, CCM_CGR2, 10, NULL, NULL); +DEFINE_CLOCK(ssi1_clk, 0, CCM_CGR2, 12, get_rate_ssi, NULL); +DEFINE_CLOCK(ssi2_clk, 1, CCM_CGR2, 14, get_rate_ssi, NULL); +DEFINE_CLOCK(uart1_clk, 0, CCM_CGR2, 16, get_rate_uart, NULL); +DEFINE_CLOCK(uart2_clk, 1, CCM_CGR2, 18, get_rate_uart, NULL); +DEFINE_CLOCK(uart3_clk, 2, CCM_CGR2, 20, get_rate_uart, NULL); +DEFINE_CLOCK(usbotg_clk, 0, CCM_CGR2, 22, NULL, NULL); +DEFINE_CLOCK(wdog_clk, 0, CCM_CGR2, 24, NULL, NULL); +DEFINE_CLOCK(max_clk, 0, CCM_CGR2, 26, NULL, NULL); +DEFINE_CLOCK(admux_clk, 0, CCM_CGR2, 30, NULL, NULL); + +DEFINE_CLOCK(csi_clk, 0, CCM_CGR3, 0, get_rate_csi, NULL); +DEFINE_CLOCK(iim_clk, 0, CCM_CGR3, 2, NULL, NULL); +DEFINE_CLOCK(gpu2d_clk, 0, CCM_CGR3, 4, NULL, NULL); + +#define _REGISTER_CLOCK(d, n, c) \ + { \ + .dev_id = d, \ + .con_id = n, \ + .clk = &c, \ + }, + +static struct clk_lookup lookups[] __initdata = { + _REGISTER_CLOCK(NULL, "asrc", asrc_clk) + _REGISTER_CLOCK(NULL, "ata", ata_clk) + _REGISTER_CLOCK(NULL, "audmux", audmux_clk) + _REGISTER_CLOCK(NULL, "can", can1_clk) + _REGISTER_CLOCK(NULL, "can", can2_clk) + _REGISTER_CLOCK("spi_imx.0", NULL, cspi1_clk) + _REGISTER_CLOCK("spi_imx.1", NULL, cspi2_clk) + _REGISTER_CLOCK(NULL, "ect", ect_clk) + _REGISTER_CLOCK(NULL, "edio", edio_clk) + _REGISTER_CLOCK(NULL, "emi", emi_clk) + _REGISTER_CLOCK(NULL, "epit", epit1_clk) + _REGISTER_CLOCK(NULL, "epit", epit2_clk) + _REGISTER_CLOCK(NULL, "esai", esai_clk) + _REGISTER_CLOCK(NULL, "sdhc", esdhc1_clk) + _REGISTER_CLOCK(NULL, "sdhc", esdhc2_clk) + _REGISTER_CLOCK(NULL, "sdhc", esdhc3_clk) + _REGISTER_CLOCK("fec.0", NULL, fec_clk) + _REGISTER_CLOCK(NULL, "gpio", gpio1_clk) + _REGISTER_CLOCK(NULL, "gpio", gpio2_clk) + _REGISTER_CLOCK(NULL, "gpio", gpio3_clk) + _REGISTER_CLOCK("gpt.0", NULL, gpt_clk) + _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) + _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) + _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk) + _REGISTER_CLOCK(NULL, "iomuxc", iomuxc_clk) + _REGISTER_CLOCK(NULL, "ipu", ipu_clk) + _REGISTER_CLOCK(NULL, "kpp", kpp_clk) + _REGISTER_CLOCK(NULL, "mlb", mlb_clk) + _REGISTER_CLOCK(NULL, "mshc", mshc_clk) + _REGISTER_CLOCK("mxc_w1", NULL, owire_clk) + _REGISTER_CLOCK(NULL, "pwm", pwm_clk) + _REGISTER_CLOCK(NULL, "rngc", rngc_clk) + _REGISTER_CLOCK(NULL, "rtc", rtc_clk) + _REGISTER_CLOCK(NULL, "rtic", rtic_clk) + _REGISTER_CLOCK(NULL, "scc", scc_clk) + _REGISTER_CLOCK(NULL, "sdma", sdma_clk) + _REGISTER_CLOCK(NULL, "spba", spba_clk) + _REGISTER_CLOCK(NULL, "spdif", spdif_clk) + _REGISTER_CLOCK(NULL, "ssi", ssi1_clk) + _REGISTER_CLOCK(NULL, "ssi", ssi2_clk) + _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) + _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) + _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) + _REGISTER_CLOCK(NULL, "usbotg", usbotg_clk) + _REGISTER_CLOCK("mxc_wdt.0", NULL, wdog_clk) + _REGISTER_CLOCK(NULL, "max", max_clk) + _REGISTER_CLOCK(NULL, "admux", admux_clk) + _REGISTER_CLOCK(NULL, "csi", csi_clk) + _REGISTER_CLOCK(NULL, "iim", iim_clk) + _REGISTER_CLOCK(NULL, "gpu2d", gpu2d_clk) +}; + +int __init mx35_clocks_init() +{ + int i; + unsigned int ll = 0; + + mxc_set_cpu_type(MXC_CPU_MX35); + +#ifdef CONFIG_DEBUG_LL_CONSOLE + ll = (3 << 16); +#endif + + for (i = 0; i < ARRAY_SIZE(lookups); i++) + clkdev_add(&lookups[i]); + + /* Turn off all clocks except the ones we need to survive, namely: + * EMI, GPIO1/2/3, GPT, IOMUX, MAX and eventually uart + */ + __raw_writel((3 << 18), CCM_BASE + CCM_CGR0); + __raw_writel((3 << 2) | (3 << 4) | (3 << 6) | (3 << 8) | (3 << 16), + CCM_BASE + CCM_CGR1); + __raw_writel((3 << 26) | ll, CCM_BASE + CCM_CGR2); + __raw_writel(0, CCM_BASE + CCM_CGR3); + + mxc_timer_init(&gpt_clk); + + return 0; +} + diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h index f467159cbdce..b2f9b72644db 100644 --- a/arch/arm/plat-mxc/include/mach/common.h +++ b/arch/arm/plat-mxc/include/mach/common.h @@ -21,6 +21,7 @@ extern int mx1_clocks_init(unsigned long fref); extern int mx21_clocks_init(unsigned long lref, unsigned long fref); extern int mx27_clocks_init(unsigned long fref); extern int mx31_clocks_init(unsigned long fref); +extern int mx35_clocks_init(void); extern int mxc_register_gpios(void); extern int mxc_register_device(struct platform_device *pdev, void *data); extern void mxc_set_cpu_type(unsigned int type); -- cgit v1.2.3 From 9eb2eb8c40ffd30da322648c4415bae0288eb167 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 18 Feb 2009 11:55:33 +0100 Subject: MX31 clkdev support This patch adds clkdev support for i.MX31. This is done in a similar way done previously for i.MX27 Signed-off-by: Sascha Hauer --- arch/arm/mach-mx3/clock.c | 932 ++++++++++--------------------------------- arch/arm/mach-mx3/crm_regs.h | 153 ------- arch/arm/plat-mxc/Kconfig | 1 + drivers/dma/ipu/ipu_idmac.c | 2 +- drivers/video/mx3fb.c | 2 +- 5 files changed, 206 insertions(+), 884 deletions(-) (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/mach-mx3/clock.c b/arch/arm/mach-mx3/clock.c index 9ab5f8b2bc30..ca46f4801c3d 100644 --- a/arch/arm/mach-mx3/clock.c +++ b/arch/arm/mach-mx3/clock.c @@ -23,10 +23,13 @@ #include #include #include + +#include +#include + #include #include #include -#include #include "crm_regs.h" @@ -65,17 +68,17 @@ static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post) } static struct clk mcu_pll_clk; -static struct clk mcu_main_clk; -static struct clk usb_pll_clk; static struct clk serial_pll_clk; static struct clk ipg_clk; static struct clk ckih_clk; -static struct clk ahb_clk; -static int _clk_enable(struct clk *clk) +static int cgr_enable(struct clk *clk) { u32 reg; + if (!clk->enable_reg) + return 0; + reg = __raw_readl(clk->enable_reg); reg |= 3 << clk->enable_shift; __raw_writel(reg, clk->enable_reg); @@ -83,111 +86,69 @@ static int _clk_enable(struct clk *clk) return 0; } -static void _clk_disable(struct clk *clk) +static void cgr_disable(struct clk *clk) { u32 reg; + if (!clk->enable_reg) + return; + reg = __raw_readl(clk->enable_reg); reg &= ~(3 << clk->enable_shift); + + /* special case for EMI clock */ + if (clk->enable_reg == MXC_CCM_CGR2 && clk->enable_shift == 8) + reg |= (1 << clk->enable_shift); + __raw_writel(reg, clk->enable_reg); } -static void _clk_emi_disable(struct clk *clk) +static unsigned long pll_ref_get_rate(void) { - u32 reg; + unsigned long ccmr; + unsigned int prcs; - reg = __raw_readl(clk->enable_reg); - reg &= ~(3 << clk->enable_shift); - reg |= (1 << clk->enable_shift); - __raw_writel(reg, clk->enable_reg); + ccmr = __raw_readl(MXC_CCM_CCMR); + prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET; + if (prcs == 0x1) + return CKIL_CLK_FREQ * 1024; + else + return clk_get_rate(&ckih_clk); } -static int _clk_pll_set_rate(struct clk *clk, unsigned long rate) +static unsigned long usb_pll_get_rate(struct clk *clk) { - u32 reg; - signed long pd = 1; /* Pre-divider */ - signed long mfi; /* Multiplication Factor (Integer part) */ - signed long mfn; /* Multiplication Factor (Integer part) */ - signed long mfd; /* Multiplication Factor (Denominator Part) */ - signed long tmp; - u32 ref_freq = clk_get_rate(clk->parent); + unsigned long reg; - while (((ref_freq / pd) * 10) > rate) - pd++; + reg = __raw_readl(MXC_CCM_UPCTL); - if ((ref_freq / pd) < PRE_DIV_MIN_FREQ) - return -EINVAL; + return mxc_decode_pll(reg, pll_ref_get_rate()); +} - /* the ref_freq/2 in the following is to round up */ - mfi = (((rate / 2) * pd) + (ref_freq / 2)) / ref_freq; - if (mfi < 5 || mfi > 15) - return -EINVAL; +static unsigned long serial_pll_get_rate(struct clk *clk) +{ + unsigned long reg; - /* pick a mfd value that will work - * then solve for mfn */ - mfd = ref_freq / 50000; - - /* - * pll_freq * pd * mfd - * mfn = -------------------- - (mfi * mfd) - * 2 * ref_freq - */ - /* the tmp/2 is for rounding */ - tmp = ref_freq / 10000; - mfn = - ((((((rate / 2) + (tmp / 2)) / tmp) * pd) * mfd) / 10000) - - (mfi * mfd); - - mfn = mfn & 0x3ff; - pd--; - mfd--; - - /* Change the Pll value */ - reg = (mfi << MXC_CCM_PCTL_MFI_OFFSET) | - (mfn << MXC_CCM_PCTL_MFN_OFFSET) | - (mfd << MXC_CCM_PCTL_MFD_OFFSET) | (pd << MXC_CCM_PCTL_PD_OFFSET); - - if (clk == &mcu_pll_clk) - __raw_writel(reg, MXC_CCM_MPCTL); - else if (clk == &usb_pll_clk) - __raw_writel(reg, MXC_CCM_UPCTL); - else if (clk == &serial_pll_clk) - __raw_writel(reg, MXC_CCM_SRPCTL); + reg = __raw_readl(MXC_CCM_SRPCTL); - return 0; + return mxc_decode_pll(reg, pll_ref_get_rate()); } -static unsigned long _clk_pll_get_rate(struct clk *clk) +static unsigned long mcu_pll_get_rate(struct clk *clk) { unsigned long reg, ccmr; - unsigned int prcs, ref_clk; ccmr = __raw_readl(MXC_CCM_CCMR); - prcs = (ccmr & MXC_CCM_CCMR_PRCS_MASK) >> MXC_CCM_CCMR_PRCS_OFFSET; - if (prcs == 0x1) - ref_clk = CKIL_CLK_FREQ * 1024; - else - ref_clk = clk_get_rate(&ckih_clk); - - if (clk == &mcu_pll_clk) { - if ((ccmr & MXC_CCM_CCMR_MPE) == 0) - return ref_clk; - if ((ccmr & MXC_CCM_CCMR_MDS) != 0) - return ref_clk; - reg = __raw_readl(MXC_CCM_MPCTL); - } else if (clk == &usb_pll_clk) - reg = __raw_readl(MXC_CCM_UPCTL); - else if (clk == &serial_pll_clk) - reg = __raw_readl(MXC_CCM_SRPCTL); - else { - BUG(); - return 0; - } - return mxc_decode_pll(reg, ref_clk); + if (!(ccmr & MXC_CCM_CCMR_MPE) || (ccmr & MXC_CCM_CCMR_MDS)) + return clk_get_rate(&ckih_clk); + + reg = __raw_readl(MXC_CCM_MPCTL); + + return mxc_decode_pll(reg, pll_ref_get_rate()); } -static int _clk_usb_pll_enable(struct clk *clk) +static int usb_pll_enable(struct clk *clk) { u32 reg; @@ -201,7 +162,7 @@ static int _clk_usb_pll_enable(struct clk *clk) return 0; } -static void _clk_usb_pll_disable(struct clk *clk) +static void usb_pll_disable(struct clk *clk) { u32 reg; @@ -210,7 +171,7 @@ static void _clk_usb_pll_disable(struct clk *clk) __raw_writel(reg, MXC_CCM_CCMR); } -static int _clk_serial_pll_enable(struct clk *clk) +static int serial_pll_enable(struct clk *clk) { u32 reg; @@ -224,7 +185,7 @@ static int _clk_serial_pll_enable(struct clk *clk) return 0; } -static void _clk_serial_pll_disable(struct clk *clk) +static void serial_pll_disable(struct clk *clk) { u32 reg; @@ -237,7 +198,7 @@ static void _clk_serial_pll_disable(struct clk *clk) #define PDR1(mask, off) ((__raw_readl(MXC_CCM_PDR1) & mask) >> off) #define PDR2(mask, off) ((__raw_readl(MXC_CCM_PDR2) & mask) >> off) -static unsigned long _clk_mcu_main_get_rate(struct clk *clk) +static unsigned long mcu_main_get_rate(struct clk *clk) { u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0); @@ -247,7 +208,7 @@ static unsigned long _clk_mcu_main_get_rate(struct clk *clk) return clk_get_rate(&mcu_pll_clk); } -static unsigned long _clk_hclk_get_rate(struct clk *clk) +static unsigned long ahb_get_rate(struct clk *clk) { unsigned long max_pdf; @@ -256,7 +217,7 @@ static unsigned long _clk_hclk_get_rate(struct clk *clk) return clk_get_rate(clk->parent) / (max_pdf + 1); } -static unsigned long _clk_ipg_get_rate(struct clk *clk) +static unsigned long ipg_get_rate(struct clk *clk) { unsigned long ipg_pdf; @@ -265,7 +226,7 @@ static unsigned long _clk_ipg_get_rate(struct clk *clk) return clk_get_rate(clk->parent) / (ipg_pdf + 1); } -static unsigned long _clk_nfc_get_rate(struct clk *clk) +static unsigned long nfc_get_rate(struct clk *clk) { unsigned long nfc_pdf; @@ -274,7 +235,7 @@ static unsigned long _clk_nfc_get_rate(struct clk *clk) return clk_get_rate(clk->parent) / (nfc_pdf + 1); } -static unsigned long _clk_hsp_get_rate(struct clk *clk) +static unsigned long hsp_get_rate(struct clk *clk) { unsigned long hsp_pdf; @@ -283,7 +244,7 @@ static unsigned long _clk_hsp_get_rate(struct clk *clk) return clk_get_rate(clk->parent) / (hsp_pdf + 1); } -static unsigned long _clk_usb_get_rate(struct clk *clk) +static unsigned long usb_get_rate(struct clk *clk) { unsigned long usb_pdf, usb_prepdf; @@ -294,7 +255,7 @@ static unsigned long _clk_usb_get_rate(struct clk *clk) return clk_get_rate(clk->parent) / (usb_prepdf + 1) / (usb_pdf + 1); } -static unsigned long _clk_csi_get_rate(struct clk *clk) +static unsigned long csi_get_rate(struct clk *clk) { u32 reg, pre, post; @@ -308,7 +269,7 @@ static unsigned long _clk_csi_get_rate(struct clk *clk) return clk_get_rate(clk->parent) / (pre * post); } -static unsigned long _clk_csi_round_rate(struct clk *clk, unsigned long rate) +static unsigned long csi_round_rate(struct clk *clk, unsigned long rate) { u32 pre, post, parent = clk_get_rate(clk->parent); u32 div = parent / rate; @@ -321,7 +282,7 @@ static unsigned long _clk_csi_round_rate(struct clk *clk, unsigned long rate) return parent / (pre * post); } -static int _clk_csi_set_rate(struct clk *clk, unsigned long rate) +static int csi_set_rate(struct clk *clk, unsigned long rate) { u32 reg, div, pre, post, parent = clk_get_rate(clk->parent); @@ -342,16 +303,7 @@ static int _clk_csi_set_rate(struct clk *clk, unsigned long rate) return 0; } -static unsigned long _clk_per_get_rate(struct clk *clk) -{ - unsigned long per_pdf; - - per_pdf = PDR0(MXC_CCM_PDR0_PER_PODF_MASK, - MXC_CCM_PDR0_PER_PODF_OFFSET); - return clk_get_rate(clk->parent) / (per_pdf + 1); -} - -static unsigned long _clk_ssi1_get_rate(struct clk *clk) +static unsigned long ssi1_get_rate(struct clk *clk) { unsigned long ssi1_pdf, ssi1_prepdf; @@ -362,7 +314,7 @@ static unsigned long _clk_ssi1_get_rate(struct clk *clk) return clk_get_rate(clk->parent) / (ssi1_prepdf + 1) / (ssi1_pdf + 1); } -static unsigned long _clk_ssi2_get_rate(struct clk *clk) +static unsigned long ssi2_get_rate(struct clk *clk) { unsigned long ssi2_pdf, ssi2_prepdf; @@ -373,7 +325,7 @@ static unsigned long _clk_ssi2_get_rate(struct clk *clk) return clk_get_rate(clk->parent) / (ssi2_prepdf + 1) / (ssi2_pdf + 1); } -static unsigned long _clk_firi_get_rate(struct clk *clk) +static unsigned long firi_get_rate(struct clk *clk) { unsigned long firi_pdf, firi_prepdf; @@ -384,7 +336,7 @@ static unsigned long _clk_firi_get_rate(struct clk *clk) return clk_get_rate(clk->parent) / (firi_prepdf + 1) / (firi_pdf + 1); } -static unsigned long _clk_firi_round_rate(struct clk *clk, unsigned long rate) +static unsigned long firi_round_rate(struct clk *clk, unsigned long rate) { u32 pre, post; u32 parent = clk_get_rate(clk->parent); @@ -399,7 +351,7 @@ static unsigned long _clk_firi_round_rate(struct clk *clk, unsigned long rate) } -static int _clk_firi_set_rate(struct clk *clk, unsigned long rate) +static int firi_set_rate(struct clk *clk, unsigned long rate) { u32 reg, div, pre, post, parent = clk_get_rate(clk->parent); @@ -420,12 +372,12 @@ static int _clk_firi_set_rate(struct clk *clk, unsigned long rate) return 0; } -static unsigned long _clk_mbx_get_rate(struct clk *clk) +static unsigned long mbx_get_rate(struct clk *clk) { return clk_get_rate(clk->parent) / 2; } -static unsigned long _clk_mstick1_get_rate(struct clk *clk) +static unsigned long mstick1_get_rate(struct clk *clk) { unsigned long msti_pdf; @@ -434,7 +386,7 @@ static unsigned long _clk_mstick1_get_rate(struct clk *clk) return clk_get_rate(clk->parent) / (msti_pdf + 1); } -static unsigned long _clk_mstick2_get_rate(struct clk *clk) +static unsigned long mstick2_get_rate(struct clk *clk) { unsigned long msti_pdf; @@ -451,663 +403,185 @@ static unsigned long clk_ckih_get_rate(struct clk *clk) } static struct clk ckih_clk = { - .name = "ckih", .get_rate = clk_ckih_get_rate, }; -static unsigned long clk_ckil_get_rate(struct clk *clk) -{ - return CKIL_CLK_FREQ; -} - -static struct clk ckil_clk = { - .name = "ckil", - .get_rate = clk_ckil_get_rate, -}; - static struct clk mcu_pll_clk = { - .name = "mcu_pll", .parent = &ckih_clk, - .set_rate = _clk_pll_set_rate, - .get_rate = _clk_pll_get_rate, + .get_rate = mcu_pll_get_rate, }; static struct clk mcu_main_clk = { - .name = "mcu_main_clk", .parent = &mcu_pll_clk, - .get_rate = _clk_mcu_main_get_rate, + .get_rate = mcu_main_get_rate, }; static struct clk serial_pll_clk = { - .name = "serial_pll", .parent = &ckih_clk, - .set_rate = _clk_pll_set_rate, - .get_rate = _clk_pll_get_rate, - .enable = _clk_serial_pll_enable, - .disable = _clk_serial_pll_disable, + .get_rate = serial_pll_get_rate, + .enable = serial_pll_enable, + .disable = serial_pll_disable, }; static struct clk usb_pll_clk = { - .name = "usb_pll", .parent = &ckih_clk, - .set_rate = _clk_pll_set_rate, - .get_rate = _clk_pll_get_rate, - .enable = _clk_usb_pll_enable, - .disable = _clk_usb_pll_disable, + .get_rate = usb_pll_get_rate, + .enable = usb_pll_enable, + .disable = usb_pll_disable, }; static struct clk ahb_clk = { - .name = "ahb_clk", .parent = &mcu_main_clk, - .get_rate = _clk_hclk_get_rate, -}; - -static struct clk per_clk = { - .name = "per_clk", - .parent = &usb_pll_clk, - .get_rate = _clk_per_get_rate, -}; - -static struct clk perclk_clk = { - .name = "perclk_clk", - .parent = &ipg_clk, -}; - -static struct clk cspi_clk[] = { - { - .name = "cspi_clk", - .id = 0, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR2, - .enable_shift = MXC_CCM_CGR2_CSPI1_OFFSET, - .disable = _clk_disable,}, - { - .name = "cspi_clk", - .id = 1, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR2, - .enable_shift = MXC_CCM_CGR2_CSPI2_OFFSET, - .disable = _clk_disable,}, - { - .name = "cspi_clk", - .id = 2, - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR0, - .enable_shift = MXC_CCM_CGR0_CSPI3_OFFSET, - .disable = _clk_disable,}, -}; - -static struct clk ipg_clk = { - .name = "ipg_clk", - .parent = &ahb_clk, - .get_rate = _clk_ipg_get_rate, -}; - -static struct clk emi_clk = { - .name = "emi_clk", - .parent = &ahb_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR2, - .enable_shift = MXC_CCM_CGR2_EMI_OFFSET, - .disable = _clk_emi_disable, -}; - -static struct clk gpt_clk = { - .name = "gpt_clk", - .parent = &perclk_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR0, - .enable_shift = MXC_CCM_CGR0_GPT_OFFSET, - .disable = _clk_disable, -}; - -static struct clk pwm_clk = { - .name = "pwm_clk", - .parent = &perclk_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR0, - .enable_shift = MXC_CCM_CGR1_PWM_OFFSET, - .disable = _clk_disable, -}; - -static struct clk epit_clk[] = { - { - .name = "epit_clk", - .id = 0, - .parent = &perclk_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR0, - .enable_shift = MXC_CCM_CGR0_EPIT1_OFFSET, - .disable = _clk_disable,}, - { - .name = "epit_clk", - .id = 1, - .parent = &perclk_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR0, - .enable_shift = MXC_CCM_CGR0_EPIT2_OFFSET, - .disable = _clk_disable,}, -}; - -static struct clk nfc_clk = { - .name = "nfc", - .parent = &ahb_clk, - .get_rate = _clk_nfc_get_rate, -}; - -static struct clk scc_clk = { - .name = "scc_clk", - .parent = &ipg_clk, -}; - -static struct clk ipu_clk = { - .name = "ipu_clk", - .parent = &mcu_main_clk, - .get_rate = _clk_hsp_get_rate, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR1, - .enable_shift = MXC_CCM_CGR1_IPU_OFFSET, - .disable = _clk_disable, -}; - -static struct clk kpp_clk = { - .name = "kpp_clk", - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR1, - .enable_shift = MXC_CCM_CGR1_KPP_OFFSET, - .disable = _clk_disable, -}; - -static struct clk wdog_clk = { - .name = "wdog_clk", - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR1, - .enable_shift = MXC_CCM_CGR1_WDOG_OFFSET, - .disable = _clk_disable, -}; -static struct clk rtc_clk = { - .name = "rtc_clk", - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR1, - .enable_shift = MXC_CCM_CGR1_RTC_OFFSET, - .disable = _clk_disable, -}; - -static struct clk usb_clk[] = { - { - .name = "usb_clk", - .parent = &usb_pll_clk, - .get_rate = _clk_usb_get_rate,}, - { - .name = "usb_ahb_clk", - .parent = &ahb_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR1, - .enable_shift = MXC_CCM_CGR1_USBOTG_OFFSET, - .disable = _clk_disable,}, -}; - -static struct clk csi_clk = { - .name = "csi_clk", - .parent = &serial_pll_clk, - .get_rate = _clk_csi_get_rate, - .round_rate = _clk_csi_round_rate, - .set_rate = _clk_csi_set_rate, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR1, - .enable_shift = MXC_CCM_CGR1_CSI_OFFSET, - .disable = _clk_disable, -}; - -static struct clk uart_clk[] = { - { - .name = "uart", - .id = 0, - .parent = &perclk_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR0, - .enable_shift = MXC_CCM_CGR0_UART1_OFFSET, - .disable = _clk_disable,}, - { - .name = "uart", - .id = 1, - .parent = &perclk_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR0, - .enable_shift = MXC_CCM_CGR0_UART2_OFFSET, - .disable = _clk_disable,}, - { - .name = "uart", - .id = 2, - .parent = &perclk_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR1, - .enable_shift = MXC_CCM_CGR1_UART3_OFFSET, - .disable = _clk_disable,}, - { - .name = "uart", - .id = 3, - .parent = &perclk_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR1, - .enable_shift = MXC_CCM_CGR1_UART4_OFFSET, - .disable = _clk_disable,}, - { - .name = "uart", - .id = 4, - .parent = &perclk_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR1, - .enable_shift = MXC_CCM_CGR1_UART5_OFFSET, - .disable = _clk_disable,}, -}; - -static struct clk i2c_clk[] = { - { - .name = "i2c_clk", - .id = 0, - .parent = &perclk_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR0, - .enable_shift = MXC_CCM_CGR0_I2C1_OFFSET, - .disable = _clk_disable,}, - { - .name = "i2c_clk", - .id = 1, - .parent = &perclk_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR0, - .enable_shift = MXC_CCM_CGR0_I2C2_OFFSET, - .disable = _clk_disable,}, - { - .name = "i2c_clk", - .id = 2, - .parent = &perclk_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR0, - .enable_shift = MXC_CCM_CGR0_I2C3_OFFSET, - .disable = _clk_disable,}, -}; - -static struct clk owire_clk = { - .name = "owire", - .parent = &perclk_clk, - .enable_reg = MXC_CCM_CGR1, - .enable_shift = MXC_CCM_CGR1_OWIRE_OFFSET, - .enable = _clk_enable, - .disable = _clk_disable, -}; - -static struct clk sdhc_clk[] = { - { - .name = "sdhc_clk", - .id = 0, - .parent = &perclk_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR0, - .enable_shift = MXC_CCM_CGR0_SD_MMC1_OFFSET, - .disable = _clk_disable,}, - { - .name = "sdhc_clk", - .id = 1, - .parent = &perclk_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR0, - .enable_shift = MXC_CCM_CGR0_SD_MMC2_OFFSET, - .disable = _clk_disable,}, -}; - -static struct clk ssi_clk[] = { - { - .name = "ssi_clk", - .parent = &serial_pll_clk, - .get_rate = _clk_ssi1_get_rate, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR0, - .enable_shift = MXC_CCM_CGR0_SSI1_OFFSET, - .disable = _clk_disable,}, - { - .name = "ssi_clk", - .id = 1, - .parent = &serial_pll_clk, - .get_rate = _clk_ssi2_get_rate, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR2, - .enable_shift = MXC_CCM_CGR2_SSI2_OFFSET, - .disable = _clk_disable,}, -}; - -static struct clk firi_clk = { - .name = "firi_clk", - .parent = &usb_pll_clk, - .round_rate = _clk_firi_round_rate, - .set_rate = _clk_firi_set_rate, - .get_rate = _clk_firi_get_rate, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR2, - .enable_shift = MXC_CCM_CGR2_FIRI_OFFSET, - .disable = _clk_disable, -}; - -static struct clk ata_clk = { - .name = "ata_clk", - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR0, - .enable_shift = MXC_CCM_CGR0_ATA_OFFSET, - .disable = _clk_disable, -}; - -static struct clk mbx_clk = { - .name = "mbx_clk", - .parent = &ahb_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR2, - .enable_shift = MXC_CCM_CGR2_GACC_OFFSET, - .get_rate = _clk_mbx_get_rate, -}; - -static struct clk vpu_clk = { - .name = "vpu_clk", - .parent = &ahb_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR2, - .enable_shift = MXC_CCM_CGR2_GACC_OFFSET, - .get_rate = _clk_mbx_get_rate, -}; - -static struct clk rtic_clk = { - .name = "rtic_clk", - .parent = &ahb_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR2, - .enable_shift = MXC_CCM_CGR2_RTIC_OFFSET, - .disable = _clk_disable, -}; - -static struct clk rng_clk = { - .name = "rng_clk", - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR0, - .enable_shift = MXC_CCM_CGR0_RNG_OFFSET, - .disable = _clk_disable, -}; - -static struct clk sdma_clk[] = { - { - .name = "sdma_ahb_clk", - .parent = &ahb_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR0, - .enable_shift = MXC_CCM_CGR0_SDMA_OFFSET, - .disable = _clk_disable,}, - { - .name = "sdma_ipg_clk", - .parent = &ipg_clk,} -}; - -static struct clk mpeg4_clk = { - .name = "mpeg4_clk", - .parent = &ahb_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR1, - .enable_shift = MXC_CCM_CGR1_HANTRO_OFFSET, - .disable = _clk_disable, -}; - -static struct clk vl2cc_clk = { - .name = "vl2cc_clk", - .parent = &ahb_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR1, - .enable_shift = MXC_CCM_CGR1_HANTRO_OFFSET, - .disable = _clk_disable, -}; - -static struct clk mstick_clk[] = { - { - .name = "mstick_clk", - .id = 0, - .parent = &usb_pll_clk, - .get_rate = _clk_mstick1_get_rate, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR1, - .enable_shift = MXC_CCM_CGR1_MEMSTICK1_OFFSET, - .disable = _clk_disable,}, - { - .name = "mstick_clk", - .id = 1, - .parent = &usb_pll_clk, - .get_rate = _clk_mstick2_get_rate, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR1, - .enable_shift = MXC_CCM_CGR1_MEMSTICK2_OFFSET, - .disable = _clk_disable,}, -}; - -static struct clk iim_clk = { - .name = "iim_clk", - .parent = &ipg_clk, - .enable = _clk_enable, - .enable_reg = MXC_CCM_CGR0, - .enable_shift = MXC_CCM_CGR0_IIM_OFFSET, - .disable = _clk_disable, -}; - -static unsigned long _clk_cko1_round_rate(struct clk *clk, unsigned long rate) -{ - u32 div, parent = clk_get_rate(clk->parent); - - div = parent / rate; - if (parent % rate) - div++; - - if (div > 8) - div = 16; - else if (div > 4) - div = 8; - else if (div > 2) - div = 4; - - return parent / div; -} - -static int _clk_cko1_set_rate(struct clk *clk, unsigned long rate) -{ - u32 reg, div, parent = clk_get_rate(clk->parent); - - div = parent / rate; - - if (div == 16) - div = 4; - else if (div == 8) - div = 3; - else if (div == 4) - div = 2; - else if (div == 2) - div = 1; - else if (div == 1) - div = 0; - else - return -EINVAL; - - reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOUTDIV_MASK; - reg |= div << MXC_CCM_COSR_CLKOUTDIV_OFFSET; - __raw_writel(reg, MXC_CCM_COSR); - - return 0; -} - -static unsigned long _clk_cko1_get_rate(struct clk *clk) -{ - u32 div; - - div = __raw_readl(MXC_CCM_COSR) & MXC_CCM_COSR_CLKOUTDIV_MASK >> - MXC_CCM_COSR_CLKOUTDIV_OFFSET; - - return clk_get_rate(clk->parent) / (1 << div); -} - -static int _clk_cko1_set_parent(struct clk *clk, struct clk *parent) -{ - u32 reg; - - reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOSEL_MASK; - - if (parent == &mcu_main_clk) - reg |= 0 << MXC_CCM_COSR_CLKOSEL_OFFSET; - else if (parent == &ipg_clk) - reg |= 1 << MXC_CCM_COSR_CLKOSEL_OFFSET; - else if (parent == &usb_pll_clk) - reg |= 2 << MXC_CCM_COSR_CLKOSEL_OFFSET; - else if (parent == mcu_main_clk.parent) - reg |= 3 << MXC_CCM_COSR_CLKOSEL_OFFSET; - else if (parent == &ahb_clk) - reg |= 5 << MXC_CCM_COSR_CLKOSEL_OFFSET; - else if (parent == &serial_pll_clk) - reg |= 7 << MXC_CCM_COSR_CLKOSEL_OFFSET; - else if (parent == &ckih_clk) - reg |= 8 << MXC_CCM_COSR_CLKOSEL_OFFSET; - else if (parent == &emi_clk) - reg |= 9 << MXC_CCM_COSR_CLKOSEL_OFFSET; - else if (parent == &ipu_clk) - reg |= 0xA << MXC_CCM_COSR_CLKOSEL_OFFSET; - else if (parent == &nfc_clk) - reg |= 0xB << MXC_CCM_COSR_CLKOSEL_OFFSET; - else if (parent == &uart_clk[0]) - reg |= 0xC << MXC_CCM_COSR_CLKOSEL_OFFSET; - else - return -EINVAL; - - __raw_writel(reg, MXC_CCM_COSR); - - return 0; -} - -static int _clk_cko1_enable(struct clk *clk) -{ - u32 reg; - - reg = __raw_readl(MXC_CCM_COSR) | MXC_CCM_COSR_CLKOEN; - __raw_writel(reg, MXC_CCM_COSR); - - return 0; -} - -static void _clk_cko1_disable(struct clk *clk) -{ - u32 reg; - - reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOEN; - __raw_writel(reg, MXC_CCM_COSR); -} + .get_rate = ahb_get_rate, +}; + +#define DEFINE_CLOCK(name, i, er, es, gr, s, p) \ + static struct clk name = { \ + .id = i, \ + .enable_reg = er, \ + .enable_shift = es, \ + .get_rate = gr, \ + .enable = cgr_enable, \ + .disable = cgr_disable, \ + .secondary = s, \ + .parent = p, \ + } -static struct clk cko1_clk = { - .name = "cko1_clk", - .get_rate = _clk_cko1_get_rate, - .set_rate = _clk_cko1_set_rate, - .round_rate = _clk_cko1_round_rate, - .set_parent = _clk_cko1_set_parent, - .enable = _clk_cko1_enable, - .disable = _clk_cko1_disable, -}; +#define DEFINE_CLOCK1(name, i, er, es, getsetround, s, p) \ + static struct clk name = { \ + .id = i, \ + .enable_reg = er, \ + .enable_shift = es, \ + .get_rate = getsetround##_get_rate, \ + .set_rate = getsetround##_set_rate, \ + .round_rate = getsetround##_round_rate, \ + .enable = cgr_enable, \ + .disable = cgr_disable, \ + .secondary = s, \ + .parent = p, \ + } -static struct clk *mxc_clks[] = { - &ckih_clk, - &ckil_clk, - &mcu_pll_clk, - &usb_pll_clk, - &serial_pll_clk, - &mcu_main_clk, - &ahb_clk, - &per_clk, - &perclk_clk, - &cko1_clk, - &emi_clk, - &cspi_clk[0], - &cspi_clk[1], - &cspi_clk[2], - &ipg_clk, - &gpt_clk, - &pwm_clk, - &wdog_clk, - &rtc_clk, - &epit_clk[0], - &epit_clk[1], - &nfc_clk, - &ipu_clk, - &kpp_clk, - &usb_clk[0], - &usb_clk[1], - &csi_clk, - &uart_clk[0], - &uart_clk[1], - &uart_clk[2], - &uart_clk[3], - &uart_clk[4], - &i2c_clk[0], - &i2c_clk[1], - &i2c_clk[2], - &owire_clk, - &sdhc_clk[0], - &sdhc_clk[1], - &ssi_clk[0], - &ssi_clk[1], - &firi_clk, - &ata_clk, - &rtic_clk, - &rng_clk, - &sdma_clk[0], - &sdma_clk[1], - &mstick_clk[0], - &mstick_clk[1], - &scc_clk, - &iim_clk, +DEFINE_CLOCK(perclk_clk, 0, NULL, 0, NULL, NULL, &ipg_clk); + +DEFINE_CLOCK(sdhc1_clk, 0, MXC_CCM_CGR0, 0, NULL, NULL, &perclk_clk); +DEFINE_CLOCK(sdhc2_clk, 1, MXC_CCM_CGR0, 2, NULL, NULL, &perclk_clk); +DEFINE_CLOCK(gpt_clk, 0, MXC_CCM_CGR0, 4, NULL, NULL, &perclk_clk); +DEFINE_CLOCK(epit1_clk, 0, MXC_CCM_CGR0, 6, NULL, NULL, &perclk_clk); +DEFINE_CLOCK(epit2_clk, 1, MXC_CCM_CGR0, 8, NULL, NULL, &perclk_clk); +DEFINE_CLOCK(iim_clk, 0, MXC_CCM_CGR0, 10, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(ata_clk, 0, MXC_CCM_CGR0, 12, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(sdma_clk1, 0, MXC_CCM_CGR0, 14, NULL, &sdma_clk1, &ahb_clk); +DEFINE_CLOCK(cspi3_clk, 2, MXC_CCM_CGR0, 16, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(rng_clk, 0, MXC_CCM_CGR0, 18, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(uart1_clk, 0, MXC_CCM_CGR0, 20, NULL, NULL, &perclk_clk); +DEFINE_CLOCK(uart2_clk, 1, MXC_CCM_CGR0, 22, NULL, NULL, &perclk_clk); +DEFINE_CLOCK(ssi1_clk, 0, MXC_CCM_CGR0, 24, ssi1_get_rate, NULL, &serial_pll_clk); +DEFINE_CLOCK(i2c1_clk, 0, MXC_CCM_CGR0, 26, NULL, NULL, &perclk_clk); +DEFINE_CLOCK(i2c2_clk, 1, MXC_CCM_CGR0, 28, NULL, NULL, &perclk_clk); +DEFINE_CLOCK(i2c3_clk, 2, MXC_CCM_CGR0, 30, NULL, NULL, &perclk_clk); + +DEFINE_CLOCK(mpeg4_clk, 0, MXC_CCM_CGR1, 0, NULL, NULL, &ahb_clk); +DEFINE_CLOCK(mstick1_clk, 0, MXC_CCM_CGR1, 2, mstick1_get_rate, NULL, &usb_pll_clk); +DEFINE_CLOCK(mstick2_clk, 1, MXC_CCM_CGR1, 4, mstick2_get_rate, NULL, &usb_pll_clk); +DEFINE_CLOCK1(csi_clk, 0, MXC_CCM_CGR1, 6, csi, NULL, &ahb_clk); +DEFINE_CLOCK(rtc_clk, 0, MXC_CCM_CGR1, 8, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(wdog_clk, 0, MXC_CCM_CGR1, 10, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(pwm_clk, 0, MXC_CCM_CGR1, 12, NULL, NULL, &perclk_clk); +DEFINE_CLOCK(usb_clk2, 0, MXC_CCM_CGR1, 18, usb_get_rate, NULL, &ahb_clk); +DEFINE_CLOCK(kpp_clk, 0, MXC_CCM_CGR1, 20, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(ipu_clk, 0, MXC_CCM_CGR1, 22, hsp_get_rate, NULL, &mcu_main_clk); +DEFINE_CLOCK(uart3_clk, 2, MXC_CCM_CGR1, 24, NULL, NULL, &perclk_clk); +DEFINE_CLOCK(uart4_clk, 3, MXC_CCM_CGR1, 26, NULL, NULL, &perclk_clk); +DEFINE_CLOCK(uart5_clk, 4, MXC_CCM_CGR1, 28, NULL, NULL, &perclk_clk); +DEFINE_CLOCK(owire_clk, 0, MXC_CCM_CGR1, 30, NULL, NULL, &perclk_clk); + +DEFINE_CLOCK(ssi2_clk, 1, MXC_CCM_CGR2, 0, ssi2_get_rate, NULL, &serial_pll_clk); +DEFINE_CLOCK(cspi1_clk, 0, MXC_CCM_CGR2, 2, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(cspi2_clk, 1, MXC_CCM_CGR2, 4, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(mbx_clk, 0, MXC_CCM_CGR2, 6, mbx_get_rate, NULL, &ahb_clk); +DEFINE_CLOCK(emi_clk, 0, MXC_CCM_CGR2, 8, NULL, NULL, &ahb_clk); +DEFINE_CLOCK(rtic_clk, 0, MXC_CCM_CGR2, 10, NULL, NULL, &ahb_clk); +DEFINE_CLOCK1(firi_clk, 0, MXC_CCM_CGR2, 12, firi, NULL, &usb_pll_clk); + +DEFINE_CLOCK(sdma_clk2, 0, NULL, 0, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(usb_clk1, 0, NULL, 0, usb_get_rate, NULL, &usb_pll_clk); +DEFINE_CLOCK(nfc_clk, 0, NULL, 0, nfc_get_rate, NULL, &ahb_clk); +DEFINE_CLOCK(scc_clk, 0, NULL, 0, NULL, NULL, &ipg_clk); +DEFINE_CLOCK(ipg_clk, 0, NULL, 0, ipg_get_rate, NULL, &ahb_clk); + +#define _REGISTER_CLOCK(d, n, c) \ + { \ + .dev_id = d, \ + .con_id = n, \ + .clk = &c, \ + }, + +static struct clk_lookup lookups[] __initdata = { + _REGISTER_CLOCK(NULL, "emi", emi_clk) + _REGISTER_CLOCK(NULL, "cspi", cspi1_clk) + _REGISTER_CLOCK(NULL, "cspi", cspi2_clk) + _REGISTER_CLOCK(NULL, "cspi", cspi3_clk) + _REGISTER_CLOCK(NULL, "gpt", gpt_clk) + _REGISTER_CLOCK(NULL, "pwm", pwm_clk) + _REGISTER_CLOCK(NULL, "wdog", wdog_clk) + _REGISTER_CLOCK(NULL, "rtc", rtc_clk) + _REGISTER_CLOCK(NULL, "epit", epit1_clk) + _REGISTER_CLOCK(NULL, "epit", epit2_clk) + _REGISTER_CLOCK("mxc_nand.0", NULL, nfc_clk) + _REGISTER_CLOCK("ipu-core", NULL, ipu_clk) + _REGISTER_CLOCK("mx3_sdc_fb", NULL, ipu_clk) + _REGISTER_CLOCK(NULL, "kpp", kpp_clk) + _REGISTER_CLOCK("fsl-usb2-udc", "usb", usb_clk1) + _REGISTER_CLOCK("fsl-usb2-udc", "usb_ahb", usb_clk2) + _REGISTER_CLOCK("mx3-camera.0", "csi", csi_clk) + _REGISTER_CLOCK("imx-uart.0", NULL, uart1_clk) + _REGISTER_CLOCK("imx-uart.1", NULL, uart2_clk) + _REGISTER_CLOCK("imx-uart.2", NULL, uart3_clk) + _REGISTER_CLOCK("imx-uart.3", NULL, uart4_clk) + _REGISTER_CLOCK("imx-uart.4", NULL, uart5_clk) + _REGISTER_CLOCK("imx-i2c.0", NULL, i2c1_clk) + _REGISTER_CLOCK("imx-i2c.1", NULL, i2c2_clk) + _REGISTER_CLOCK("imx-i2c.2", NULL, i2c3_clk) + _REGISTER_CLOCK("mxc_w1.0", NULL, owire_clk) + _REGISTER_CLOCK("mxc-mmc.0", NULL, sdhc1_clk) + _REGISTER_CLOCK("mxc-mmc.1", NULL, sdhc2_clk) + _REGISTER_CLOCK(NULL, "ssi", ssi1_clk) + _REGISTER_CLOCK(NULL, "ssi", ssi2_clk) + _REGISTER_CLOCK(NULL, "firi", firi_clk) + _REGISTER_CLOCK(NULL, "ata", ata_clk) + _REGISTER_CLOCK(NULL, "rtic", rtic_clk) + _REGISTER_CLOCK(NULL, "rng", rng_clk) + _REGISTER_CLOCK(NULL, "sdma_ahb", sdma_clk1) + _REGISTER_CLOCK(NULL, "sdma_ipg", sdma_clk2) + _REGISTER_CLOCK(NULL, "mstick", mstick1_clk) + _REGISTER_CLOCK(NULL, "mstick", mstick2_clk) + _REGISTER_CLOCK(NULL, "scc", scc_clk) + _REGISTER_CLOCK(NULL, "iim", iim_clk) + _REGISTER_CLOCK(NULL, "mpeg4", mpeg4_clk) + _REGISTER_CLOCK(NULL, "mbx", mbx_clk) }; int __init mx31_clocks_init(unsigned long fref) { u32 reg; - struct clk **clkp; + int i; mxc_set_cpu_type(MXC_CPU_MX31); ckih_rate = fref; - for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++) - clk_register(*clkp); - - if (cpu_is_mx31()) { - clk_register(&mpeg4_clk); - clk_register(&mbx_clk); - } else { - clk_register(&vpu_clk); - clk_register(&vl2cc_clk); - } + for (i = 0; i < ARRAY_SIZE(lookups); i++) + clkdev_add(&lookups[i]); /* Turn off all possible clocks */ - __raw_writel(MXC_CCM_CGR0_GPT_MASK, MXC_CCM_CGR0); + __raw_writel((3 << 4), MXC_CCM_CGR0); __raw_writel(0, MXC_CCM_CGR1); - - __raw_writel(MXC_CCM_CGR2_EMI_MASK | - MXC_CCM_CGR2_IPMUX1_MASK | - MXC_CCM_CGR2_IPMUX2_MASK | - MXC_CCM_CGR2_MXCCLKENSEL_MASK | /* for MX32 */ - MXC_CCM_CGR2_CHIKCAMPEN_MASK | /* for MX32 */ - MXC_CCM_CGR2_OVRVPUBUSY_MASK | /* for MX32 */ + __raw_writel((3 << 8) | (3 << 14) | (3 << 16)| 1 << 27 | 1 << 28, /* Bit 27 and 28 are not defined for MX32, but still required to be set */ MXC_CCM_CGR2); - clk_disable(&cko1_clk); - clk_disable(&usb_pll_clk); + usb_pll_disable(&usb_pll_clk); pr_info("Clock input source is %ld\n", clk_get_rate(&ckih_clk)); diff --git a/arch/arm/mach-mx3/crm_regs.h b/arch/arm/mach-mx3/crm_regs.h index 4a0e0ede23bb..adfa3627ad84 100644 --- a/arch/arm/mach-mx3/crm_regs.h +++ b/arch/arm/mach-mx3/crm_regs.h @@ -91,47 +91,6 @@ #define MXC_CCM_PDR0_MCU_PODF_OFFSET 0 #define MXC_CCM_PDR0_MCU_PODF_MASK 0x7 -#define MXC_CCM_PDR0_HSP_DIV_1 (0x0 << 11) -#define MXC_CCM_PDR0_HSP_DIV_2 (0x1 << 11) -#define MXC_CCM_PDR0_HSP_DIV_3 (0x2 << 11) -#define MXC_CCM_PDR0_HSP_DIV_4 (0x3 << 11) -#define MXC_CCM_PDR0_HSP_DIV_5 (0x4 << 11) -#define MXC_CCM_PDR0_HSP_DIV_6 (0x5 << 11) -#define MXC_CCM_PDR0_HSP_DIV_7 (0x6 << 11) -#define MXC_CCM_PDR0_HSP_DIV_8 (0x7 << 11) - -#define MXC_CCM_PDR0_IPG_DIV_1 (0x0 << 6) -#define MXC_CCM_PDR0_IPG_DIV_2 (0x1 << 6) -#define MXC_CCM_PDR0_IPG_DIV_3 (0x2 << 6) -#define MXC_CCM_PDR0_IPG_DIV_4 (0x3 << 6) - -#define MXC_CCM_PDR0_MAX_DIV_1 (0x0 << 3) -#define MXC_CCM_PDR0_MAX_DIV_2 (0x1 << 3) -#define MXC_CCM_PDR0_MAX_DIV_3 (0x2 << 3) -#define MXC_CCM_PDR0_MAX_DIV_4 (0x3 << 3) -#define MXC_CCM_PDR0_MAX_DIV_5 (0x4 << 3) -#define MXC_CCM_PDR0_MAX_DIV_6 (0x5 << 3) -#define MXC_CCM_PDR0_MAX_DIV_7 (0x6 << 3) -#define MXC_CCM_PDR0_MAX_DIV_8 (0x7 << 3) - -#define MXC_CCM_PDR0_NFC_DIV_1 (0x0 << 8) -#define MXC_CCM_PDR0_NFC_DIV_2 (0x1 << 8) -#define MXC_CCM_PDR0_NFC_DIV_3 (0x2 << 8) -#define MXC_CCM_PDR0_NFC_DIV_4 (0x3 << 8) -#define MXC_CCM_PDR0_NFC_DIV_5 (0x4 << 8) -#define MXC_CCM_PDR0_NFC_DIV_6 (0x5 << 8) -#define MXC_CCM_PDR0_NFC_DIV_7 (0x6 << 8) -#define MXC_CCM_PDR0_NFC_DIV_8 (0x7 << 8) - -#define MXC_CCM_PDR0_MCU_DIV_1 0x0 -#define MXC_CCM_PDR0_MCU_DIV_2 0x1 -#define MXC_CCM_PDR0_MCU_DIV_3 0x2 -#define MXC_CCM_PDR0_MCU_DIV_4 0x3 -#define MXC_CCM_PDR0_MCU_DIV_5 0x4 -#define MXC_CCM_PDR0_MCU_DIV_6 0x5 -#define MXC_CCM_PDR0_MCU_DIV_7 0x6 -#define MXC_CCM_PDR0_MCU_DIV_8 0x7 - #define MXC_CCM_PDR1_USB_PRDF_OFFSET 30 #define MXC_CCM_PDR1_USB_PRDF_MASK (0x3 << 30) #define MXC_CCM_PDR1_USB_PODF_OFFSET 27 @@ -152,118 +111,6 @@ /* Bit definitions for RCSR */ #define MXC_CCM_RCSR_NF16B 0x80000000 -/* Bit definitions for both MCU, USB and SR PLL control registers */ -#define MXC_CCM_PCTL_BRM 0x80000000 -#define MXC_CCM_PCTL_PD_OFFSET 26 -#define MXC_CCM_PCTL_PD_MASK (0xF << 26) -#define MXC_CCM_PCTL_MFD_OFFSET 16 -#define MXC_CCM_PCTL_MFD_MASK (0x3FF << 16) -#define MXC_CCM_PCTL_MFI_OFFSET 10 -#define MXC_CCM_PCTL_MFI_MASK (0xF << 10) -#define MXC_CCM_PCTL_MFN_OFFSET 0 -#define MXC_CCM_PCTL_MFN_MASK 0x3FF - -#define MXC_CCM_CGR0_SD_MMC1_OFFSET 0 -#define MXC_CCM_CGR0_SD_MMC1_MASK (0x3 << 0) -#define MXC_CCM_CGR0_SD_MMC2_OFFSET 2 -#define MXC_CCM_CGR0_SD_MMC2_MASK (0x3 << 2) -#define MXC_CCM_CGR0_GPT_OFFSET 4 -#define MXC_CCM_CGR0_GPT_MASK (0x3 << 4) -#define MXC_CCM_CGR0_EPIT1_OFFSET 6 -#define MXC_CCM_CGR0_EPIT1_MASK (0x3 << 6) -#define MXC_CCM_CGR0_EPIT2_OFFSET 8 -#define MXC_CCM_CGR0_EPIT2_MASK (0x3 << 8) -#define MXC_CCM_CGR0_IIM_OFFSET 10 -#define MXC_CCM_CGR0_IIM_MASK (0x3 << 10) -#define MXC_CCM_CGR0_ATA_OFFSET 12 -#define MXC_CCM_CGR0_ATA_MASK (0x3 << 12) -#define MXC_CCM_CGR0_SDMA_OFFSET 14 -#define MXC_CCM_CGR0_SDMA_MASK (0x3 << 14) -#define MXC_CCM_CGR0_CSPI3_OFFSET 16 -#define MXC_CCM_CGR0_CSPI3_MASK (0x3 << 16) -#define MXC_CCM_CGR0_RNG_OFFSET 18 -#define MXC_CCM_CGR0_RNG_MASK (0x3 << 18) -#define MXC_CCM_CGR0_UART1_OFFSET 20 -#define MXC_CCM_CGR0_UART1_MASK (0x3 << 20) -#define MXC_CCM_CGR0_UART2_OFFSET 22 -#define MXC_CCM_CGR0_UART2_MASK (0x3 << 22) -#define MXC_CCM_CGR0_SSI1_OFFSET 24 -#define MXC_CCM_CGR0_SSI1_MASK (0x3 << 24) -#define MXC_CCM_CGR0_I2C1_OFFSET 26 -#define MXC_CCM_CGR0_I2C1_MASK (0x3 << 26) -#define MXC_CCM_CGR0_I2C2_OFFSET 28 -#define MXC_CCM_CGR0_I2C2_MASK (0x3 << 28) -#define MXC_CCM_CGR0_I2C3_OFFSET 30 -#define MXC_CCM_CGR0_I2C3_MASK (0x3 << 30) - -#define MXC_CCM_CGR1_HANTRO_OFFSET 0 -#define MXC_CCM_CGR1_HANTRO_MASK (0x3 << 0) -#define MXC_CCM_CGR1_MEMSTICK1_OFFSET 2 -#define MXC_CCM_CGR1_MEMSTICK1_MASK (0x3 << 2) -#define MXC_CCM_CGR1_MEMSTICK2_OFFSET 4 -#define MXC_CCM_CGR1_MEMSTICK2_MASK (0x3 << 4) -#define MXC_CCM_CGR1_CSI_OFFSET 6 -#define MXC_CCM_CGR1_CSI_MASK (0x3 << 6) -#define MXC_CCM_CGR1_RTC_OFFSET 8 -#define MXC_CCM_CGR1_RTC_MASK (0x3 << 8) -#define MXC_CCM_CGR1_WDOG_OFFSET 10 -#define MXC_CCM_CGR1_WDOG_MASK (0x3 << 10) -#define MXC_CCM_CGR1_PWM_OFFSET 12 -#define MXC_CCM_CGR1_PWM_MASK (0x3 << 12) -#define MXC_CCM_CGR1_SIM_OFFSET 14 -#define MXC_CCM_CGR1_SIM_MASK (0x3 << 14) -#define MXC_CCM_CGR1_ECT_OFFSET 16 -#define MXC_CCM_CGR1_ECT_MASK (0x3 << 16) -#define MXC_CCM_CGR1_USBOTG_OFFSET 18 -#define MXC_CCM_CGR1_USBOTG_MASK (0x3 << 18) -#define MXC_CCM_CGR1_KPP_OFFSET 20 -#define MXC_CCM_CGR1_KPP_MASK (0x3 << 20) -#define MXC_CCM_CGR1_IPU_OFFSET 22 -#define MXC_CCM_CGR1_IPU_MASK (0x3 << 22) -#define MXC_CCM_CGR1_UART3_OFFSET 24 -#define MXC_CCM_CGR1_UART3_MASK (0x3 << 24) -#define MXC_CCM_CGR1_UART4_OFFSET 26 -#define MXC_CCM_CGR1_UART4_MASK (0x3 << 26) -#define MXC_CCM_CGR1_UART5_OFFSET 28 -#define MXC_CCM_CGR1_UART5_MASK (0x3 << 28) -#define MXC_CCM_CGR1_OWIRE_OFFSET 30 -#define MXC_CCM_CGR1_OWIRE_MASK (0x3 << 30) - -#define MXC_CCM_CGR2_SSI2_OFFSET 0 -#define MXC_CCM_CGR2_SSI2_MASK (0x3 << 0) -#define MXC_CCM_CGR2_CSPI1_OFFSET 2 -#define MXC_CCM_CGR2_CSPI1_MASK (0x3 << 2) -#define MXC_CCM_CGR2_CSPI2_OFFSET 4 -#define MXC_CCM_CGR2_CSPI2_MASK (0x3 << 4) -#define MXC_CCM_CGR2_GACC_OFFSET 6 -#define MXC_CCM_CGR2_GACC_MASK (0x3 << 6) -#define MXC_CCM_CGR2_EMI_OFFSET 8 -#define MXC_CCM_CGR2_EMI_MASK (0x3 << 8) -#define MXC_CCM_CGR2_RTIC_OFFSET 10 -#define MXC_CCM_CGR2_RTIC_MASK (0x3 << 10) -#define MXC_CCM_CGR2_FIRI_OFFSET 12 -#define MXC_CCM_CGR2_FIRI_MASK (0x3 << 12) -#define MXC_CCM_CGR2_IPMUX1_OFFSET 14 -#define MXC_CCM_CGR2_IPMUX1_MASK (0x3 << 14) -#define MXC_CCM_CGR2_IPMUX2_OFFSET 16 -#define MXC_CCM_CGR2_IPMUX2_MASK (0x3 << 16) - -/* These new CGR2 bits are added in MX32 */ -#define MXC_CCM_CGR2_APMSYSCLKSEL_OFFSET 18 -#define MXC_CCM_CGR2_APMSYSCLKSEL_MASK (0x3 << 18) -#define MXC_CCM_CGR2_APMSSICLKSEL_OFFSET 20 -#define MXC_CCM_CGR2_APMSSICLKSEL_MASK (0x3 << 20) -#define MXC_CCM_CGR2_APMPERCLKSEL_OFFSET 22 -#define MXC_CCM_CGR2_APMPERCLKSEL_MASK (0x3 << 22) -#define MXC_CCM_CGR2_MXCCLKENSEL_OFFSET 24 -#define MXC_CCM_CGR2_MXCCLKENSEL_MASK (0x1 << 24) -#define MXC_CCM_CGR2_CHIKCAMPEN_OFFSET 25 -#define MXC_CCM_CGR2_CHIKCAMPEN_MASK (0x1 << 25) -#define MXC_CCM_CGR2_OVRVPUBUSY_OFFSET 26 -#define MXC_CCM_CGR2_OVRVPUBUSY_MASK (0x1 << 26) -#define MXC_CCM_CGR2_APMENA_OFFSET 30 -#define MXC_CCM_CGR2_AOMENA_MASK (0x1 << 30) - /* * LTR0 register offsets */ diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig index ed5ab8ed7cfa..17d0e9906d5f 100644 --- a/arch/arm/plat-mxc/Kconfig +++ b/arch/arm/plat-mxc/Kconfig @@ -22,6 +22,7 @@ config ARCH_MX2 config ARCH_MX3 bool "MX3-based" select CPU_V6 + select COMMON_CLKDEV help This enables support for systems based on the Freescale i.MX3 family diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c index ae50a9d1a4e6..da781d107895 100644 --- a/drivers/dma/ipu/ipu_idmac.c +++ b/drivers/dma/ipu/ipu_idmac.c @@ -1649,7 +1649,7 @@ static int ipu_probe(struct platform_device *pdev) } /* Get IPU clock */ - ipu_data.ipu_clk = clk_get(&pdev->dev, "ipu_clk"); + ipu_data.ipu_clk = clk_get(&pdev->dev, NULL); if (IS_ERR(ipu_data.ipu_clk)) { ret = PTR_ERR(ipu_data.ipu_clk); goto err_clk_get; diff --git a/drivers/video/mx3fb.c b/drivers/video/mx3fb.c index 8a75d05f4334..0c27961e47f2 100644 --- a/drivers/video/mx3fb.c +++ b/drivers/video/mx3fb.c @@ -493,7 +493,7 @@ static int sdc_init_panel(struct mx3fb_data *mx3fb, enum ipu_panel panel, */ dev_dbg(mx3fb->dev, "pixel clk = %d\n", pixel_clk); - ipu_clk = clk_get(mx3fb->dev, "ipu_clk"); + ipu_clk = clk_get(mx3fb->dev, NULL); div = clk_get_rate(ipu_clk) * 16 / pixel_clk; clk_put(ipu_clk); -- cgit v1.2.3 From cc83e4096c6db1f13406c7dedf5516b4b5bcba55 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 19 Feb 2009 12:48:35 +0100 Subject: Use __force in IO_ADDRESS macro to silence sparse Signed-off-by: Sascha Hauer --- arch/arm/plat-mxc/include/mach/mx3x.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/plat-mxc/include/mach/mx3x.h b/arch/arm/plat-mxc/include/mach/mx3x.h index 83a172b51b05..3878c6085d5c 100644 --- a/arch/arm/plat-mxc/include/mach/mx3x.h +++ b/arch/arm/plat-mxc/include/mach/mx3x.h @@ -157,7 +157,7 @@ * it returns 0xDEADBEEF */ #define IO_ADDRESS(x) \ - (void __iomem *) \ + (void __force __iomem *) \ (((x >= AIPS1_BASE_ADDR) && (x < (AIPS1_BASE_ADDR + AIPS1_SIZE))) ? AIPS1_IO_ADDRESS(x):\ ((x >= SPBA0_BASE_ADDR) && (x < (SPBA0_BASE_ADDR + SPBA0_SIZE))) ? SPBA0_IO_ADDRESS(x):\ ((x >= AIPS2_BASE_ADDR) && (x < (AIPS2_BASE_ADDR + AIPS2_SIZE))) ? AIPS2_IO_ADDRESS(x):\ -- cgit v1.2.3 From 148854c65ea8046b045672fd49f4333aefaa3ab5 Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Wed, 11 Mar 2009 03:22:00 +0300 Subject: qong: basic support for Dave/DENX QongEVB-LITE board This patch adds basic support for Dave/DENX QongEVB-LITE i.MX31-based board. It includes support for clocks initialization, UART1, NOR-flash, FPGA-attached NAND flash and DNET ethernet controller (inside FPGA). Signed-off-by: Ilya Yanok Signed-off-by: Sascha Hauer --- arch/arm/mach-mx3/Kconfig | 8 + arch/arm/mach-mx3/Makefile | 1 + arch/arm/mach-mx3/qong.c | 312 +++++++++++++++++++++++++++ arch/arm/plat-mxc/include/mach/board-qong.h | 22 ++ arch/arm/plat-mxc/include/mach/debug-macro.S | 3 + 5 files changed, 346 insertions(+) create mode 100644 arch/arm/mach-mx3/qong.c create mode 100644 arch/arm/plat-mxc/include/mach/board-qong.h (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig index 7c939c69d6df..d6235583e979 100644 --- a/arch/arm/mach-mx3/Kconfig +++ b/arch/arm/mach-mx3/Kconfig @@ -56,4 +56,12 @@ config MACH_MX31MOBOARD Include support for mx31moboard platform. This includes specific configurations for the board and its peripherals. +config MACH_QONG + bool "Support Dave/DENX QongEVB-LITE platform" + select ARCH_MX31 + default n + help + Include support for Dave/DENX QongEVB-LITE platform. This includes + specific configurations for the board and its peripherals. + endif diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile index ab0bec0a4d92..272c8a953b30 100644 --- a/arch/arm/mach-mx3/Makefile +++ b/arch/arm/mach-mx3/Makefile @@ -13,3 +13,4 @@ obj-$(CONFIG_MACH_PCM037) += pcm037.o obj-$(CONFIG_MACH_MX31_3DS) += mx31pdk.o obj-$(CONFIG_MACH_MX31MOBOARD) += mx31moboard.o mx31moboard-devboard.o \ mx31moboard-marxbot.o +obj-$(CONFIG_MACH_QONG) += qong.o diff --git a/arch/arm/mach-mx3/qong.c b/arch/arm/mach-mx3/qong.c new file mode 100644 index 000000000000..6c4283cec6f4 --- /dev/null +++ b/arch/arm/mach-mx3/qong.c @@ -0,0 +1,312 @@ +/* + * Copyright (C) 2009 Ilya Yanok, Emcraft Systems Ltd, + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "devices.h" + +/* FPGA defines */ +#define QONG_FPGA_VERSION(major, minor, rev) \ + (((major & 0xF) << 12) | ((minor & 0xF) << 8) | (rev & 0xFF)) + +#define QONG_FPGA_BASEADDR CS1_BASE_ADDR +#define QONG_FPGA_PERIPH_SIZE (1 << 24) + +#define QONG_FPGA_CTRL_BASEADDR QONG_FPGA_BASEADDR +#define QONG_FPGA_CTRL_SIZE 0x10 +/* FPGA control registers */ +#define QONG_FPGA_CTRL_VERSION 0x00 + +#define QONG_DNET_ID 1 +#define QONG_DNET_BASEADDR \ + (QONG_FPGA_BASEADDR + QONG_DNET_ID * QONG_FPGA_PERIPH_SIZE) +#define QONG_DNET_SIZE 0x00001000 + +#define QONG_FPGA_IRQ IOMUX_TO_IRQ(MX31_PIN_DTR_DCE1) + +/* + * This file contains the board-specific initialization routines. + */ + +static struct imxuart_platform_data uart_pdata = { + .flags = IMXUART_HAVE_RTSCTS, +}; + +static int uart_pins[] = { + MX31_PIN_CTS1__CTS1, + MX31_PIN_RTS1__RTS1, + MX31_PIN_TXD1__TXD1, + MX31_PIN_RXD1__RXD1 +}; + +static inline void mxc_init_imx_uart(void) +{ + mxc_iomux_setup_multiple_pins(uart_pins, ARRAY_SIZE(uart_pins), + "uart-0"); + mxc_register_device(&mxc_uart_device0, &uart_pdata); +} + +static struct resource dnet_resources[] = { + [0] = { + .name = "dnet-memory", + .start = QONG_DNET_BASEADDR, + .end = QONG_DNET_BASEADDR + QONG_DNET_SIZE - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = QONG_FPGA_IRQ, + .end = QONG_FPGA_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device dnet_device = { + .name = "dnet", + .id = -1, + .num_resources = ARRAY_SIZE(dnet_resources), + .resource = dnet_resources, +}; + +static int __init qong_init_dnet(void) +{ + int ret; + + ret = platform_device_register(&dnet_device); + return ret; +} + +/* MTD NOR flash */ + +static struct physmap_flash_data qong_flash_data = { + .width = 2, +}; + +static struct resource qong_flash_resource = { + .start = CS0_BASE_ADDR, + .end = CS0_BASE_ADDR + QONG_NOR_SIZE - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device qong_nor_mtd_device = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &qong_flash_data, + }, + .resource = &qong_flash_resource, + .num_resources = 1, +}; + +static void qong_init_nor_mtd(void) +{ + (void)platform_device_register(&qong_nor_mtd_device); +} + +/* + * Hardware specific access to control-lines + */ +static void qong_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, unsigned int ctrl) +{ + struct nand_chip *nand_chip = mtd->priv; + + if (cmd == NAND_CMD_NONE) + return; + + if (ctrl & NAND_CLE) + writeb(cmd, nand_chip->IO_ADDR_W + (1 << 24)); + else + writeb(cmd, nand_chip->IO_ADDR_W + (1 << 23)); +} + +/* + * Read the Device Ready pin. + */ +static int qong_nand_device_ready(struct mtd_info *mtd) +{ + return gpio_get_value(IOMUX_TO_GPIO(MX31_PIN_NFRB)); +} + +static void qong_nand_select_chip(struct mtd_info *mtd, int chip) +{ + if (chip >= 0) + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0); + else + gpio_set_value(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 1); +} + +static struct platform_nand_data qong_nand_data = { + .chip = { + .chip_delay = 20, + .options = 0, + }, + .ctrl = { + .cmd_ctrl = qong_nand_cmd_ctrl, + .dev_ready = qong_nand_device_ready, + .select_chip = qong_nand_select_chip, + } +}; + +static struct resource qong_nand_resource = { + .start = CS3_BASE_ADDR, + .end = CS3_BASE_ADDR + SZ_32M - 1, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device qong_nand_device = { + .name = "gen_nand", + .id = -1, + .dev = { + .platform_data = &qong_nand_data, + }, + .num_resources = 1, + .resource = &qong_nand_resource, +}; + +static void __init qong_init_nand_mtd(void) +{ + /* init CS */ + __raw_writel(0x00004f00, CSCR_U(3)); + __raw_writel(0x20013b31, CSCR_L(3)); + __raw_writel(0x00020800, CSCR_A(3)); + mxc_iomux_set_gpr(MUX_SDCTL_CSD1_SEL, true); + + /* enable pin */ + mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFCE_B, IOMUX_CONFIG_GPIO)); + if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), "nand_enable")) + gpio_direction_output(IOMUX_TO_GPIO(MX31_PIN_NFCE_B), 0); + + /* ready/busy pin */ + mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFRB, IOMUX_CONFIG_GPIO)); + if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFRB), "nand_rdy")) + gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFRB)); + + /* write protect pin */ + mxc_iomux_mode(IOMUX_MODE(MX31_PIN_NFWP_B, IOMUX_CONFIG_GPIO)); + if (!gpio_request(IOMUX_TO_GPIO(MX31_PIN_NFWP_B), "nand_wp")) + gpio_direction_input(IOMUX_TO_GPIO(MX31_PIN_NFWP_B)); + + platform_device_register(&qong_nand_device); +} + +static void __init qong_init_fpga(void) +{ + void __iomem *regs; + u32 fpga_ver; + + regs = ioremap(QONG_FPGA_CTRL_BASEADDR, QONG_FPGA_CTRL_SIZE); + if (!regs) { + printk(KERN_ERR "%s: failed to map registers, aborting.\n", + __func__); + return; + } + + fpga_ver = readl(regs + QONG_FPGA_CTRL_VERSION); + iounmap(regs); + printk(KERN_INFO "Qong FPGA version %d.%d.%d\n", + (fpga_ver & 0xF000) >> 12, + (fpga_ver & 0x0F00) >> 8, fpga_ver & 0x00FF); + if (fpga_ver < QONG_FPGA_VERSION(0, 8, 7)) { + printk(KERN_ERR "qong: Unexpected FPGA version, FPGA-based " + "devices won't be registered!\n"); + return; + } + + /* register FPGA-based devices */ + qong_init_nand_mtd(); + qong_init_dnet(); +} + +/* + * This structure defines the MX31 memory map. + */ +static struct map_desc qong_io_desc[] __initdata = { + { + .virtual = AIPS1_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(AIPS1_BASE_ADDR), + .length = AIPS1_SIZE, + .type = MT_DEVICE_NONSHARED + }, { + .virtual = AIPS2_BASE_ADDR_VIRT, + .pfn = __phys_to_pfn(AIPS2_BASE_ADDR), + .length = AIPS2_SIZE, + .type = MT_DEVICE_NONSHARED + } +}; + +/* + * Set up static virtual mappings. + */ +static void __init qong_map_io(void) +{ + mxc_map_io(); + iotable_init(qong_io_desc, ARRAY_SIZE(qong_io_desc)); +} + +/* + * Board specific initialization. + */ +static void __init mxc_board_init(void) +{ + mxc_init_imx_uart(); + qong_init_nor_mtd(); + qong_init_fpga(); +} + +static void __init qong_timer_init(void) +{ + mx31_clocks_init(26000000); +} + +static struct sys_timer qong_timer = { + .init = qong_timer_init, +}; + +/* + * The following uses standard kernel macros defined in arch.h in order to + * initialize __mach_desc_QONG data structure. + */ + +MACHINE_START(QONG, "Dave/DENX QongEVB-LITE") + /* Maintainer: DENX Software Engineering GmbH */ + .phys_io = AIPS1_BASE_ADDR, + .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc, + .boot_params = PHYS_OFFSET + 0x100, + .map_io = qong_map_io, + .init_irq = mxc_init_irq, + .init_machine = mxc_board_init, + .timer = &qong_timer, +MACHINE_END diff --git a/arch/arm/plat-mxc/include/mach/board-qong.h b/arch/arm/plat-mxc/include/mach/board-qong.h new file mode 100644 index 000000000000..4ff762dd45cf --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/board-qong.h @@ -0,0 +1,22 @@ +/* + * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, + */ + +/* + * 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. + */ + +#ifndef __ASM_ARCH_MXC_BOARD_QONG_H__ +#define __ASM_ARCH_MXC_BOARD_QONG_H__ + +/* mandatory for CONFIG_LL_DEBUG */ + +#define MXC_LL_UART_PADDR UART1_BASE_ADDR +#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR) + +/* NOR FLASH */ +#define QONG_NOR_SIZE (128*1024*1024) + +#endif /* __ASM_ARCH_MXC_BOARD_QONG_H__ */ diff --git a/arch/arm/plat-mxc/include/mach/debug-macro.S b/arch/arm/plat-mxc/include/mach/debug-macro.S index 602768b427e2..4f773148bc20 100644 --- a/arch/arm/plat-mxc/include/mach/debug-macro.S +++ b/arch/arm/plat-mxc/include/mach/debug-macro.S @@ -30,6 +30,9 @@ #endif #ifdef CONFIG_MACH_MX31_3DS #include +#endif +#ifdef CONFIG_MACH_QONG +#include #endif .macro addruart,rx mrc p15, 0, \rx, c1, c0 -- cgit v1.2.3 From be093beb608edf821b45fe00a8a080fb5c6ed4af Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 19 Mar 2009 16:20:24 +0000 Subject: [ARM] pass reboot command line to arch_reset() OMAP wishes to pass state to the boot loader upon reboot in order to instruct it whether to wait for USB-based reflashing or not. There is already a facility to do this via the reboot() syscall, except we ignore the string passed to machine_restart(). This patch fixes things to pass this string to arch_reset(). This means that we keep the reboot mode limited to telling the kernel _how_ to perform the reboot which should be independent of what we request the boot loader to do. Acked-by: Tony Lindgren Signed-off-by: Russell King --- arch/arm/include/asm/system.h | 4 ++-- arch/arm/kernel/process.c | 10 +++++----- arch/arm/mach-aaec2000/include/mach/system.h | 2 +- arch/arm/mach-at91/include/mach/system.h | 2 +- arch/arm/mach-clps711x/include/mach/system.h | 2 +- arch/arm/mach-davinci/include/mach/system.h | 2 +- arch/arm/mach-ebsa110/include/mach/system.h | 2 +- arch/arm/mach-ep93xx/include/mach/system.h | 2 +- arch/arm/mach-footbridge/include/mach/system.h | 2 +- arch/arm/mach-h720x/include/mach/system.h | 2 +- arch/arm/mach-imx/include/mach/system.h | 2 +- arch/arm/mach-integrator/include/mach/system.h | 2 +- arch/arm/mach-iop13xx/include/mach/system.h | 2 +- arch/arm/mach-iop32x/include/mach/system.h | 2 +- arch/arm/mach-iop33x/include/mach/system.h | 2 +- arch/arm/mach-ixp2000/include/mach/system.h | 2 +- arch/arm/mach-ixp23xx/include/mach/system.h | 2 +- arch/arm/mach-ixp4xx/include/mach/system.h | 2 +- arch/arm/mach-kirkwood/include/mach/system.h | 2 +- arch/arm/mach-ks8695/include/mach/system.h | 2 +- arch/arm/mach-l7200/include/mach/system.h | 2 +- arch/arm/mach-lh7a40x/include/mach/system.h | 2 +- arch/arm/mach-loki/include/mach/system.h | 2 +- arch/arm/mach-msm/include/mach/system.h | 2 +- arch/arm/mach-mv78xx0/include/mach/system.h | 2 +- arch/arm/mach-mx2/system.c | 2 +- arch/arm/mach-netx/include/mach/system.h | 2 +- arch/arm/mach-ns9xxx/include/mach/system.h | 2 +- arch/arm/mach-orion5x/include/mach/system.h | 2 +- arch/arm/mach-orion5x/lsmini-setup.c | 2 +- arch/arm/mach-pnx4008/include/mach/system.h | 2 +- arch/arm/mach-pxa/corgi.c | 6 +++--- arch/arm/mach-pxa/include/mach/system.h | 2 +- arch/arm/mach-pxa/mioa701.c | 6 +++--- arch/arm/mach-pxa/poodle.c | 6 +++--- arch/arm/mach-pxa/reset.c | 2 +- arch/arm/mach-pxa/spitz.c | 4 ++-- arch/arm/mach-pxa/tosa.c | 4 ++-- arch/arm/mach-realview/include/mach/system.h | 2 +- arch/arm/mach-rpc/include/mach/system.h | 2 +- arch/arm/mach-s3c2410/include/mach/system-reset.h | 2 +- arch/arm/mach-s3c6400/include/mach/system.h | 2 +- arch/arm/mach-sa1100/include/mach/system.h | 2 +- arch/arm/mach-shark/core.c | 2 +- arch/arm/mach-shark/include/mach/system.h | 2 +- arch/arm/mach-versatile/include/mach/system.h | 2 +- arch/arm/mach-w90x900/include/mach/system.h | 2 +- arch/arm/plat-mxc/include/mach/system.h | 2 +- arch/arm/plat-omap/include/mach/system.h | 2 +- arch/arm/plat-s3c24xx/cpu.c | 6 +++--- 50 files changed, 65 insertions(+), 65 deletions(-) (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 811be55f338e..0a0d49ae1e6d 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -97,8 +97,8 @@ extern void __show_regs(struct pt_regs *); extern int cpu_architecture(void); extern void cpu_init(void); -void arm_machine_restart(char mode); -extern void (*arm_pm_restart)(char str); +void arm_machine_restart(char mode, const char *cmd); +extern void (*arm_pm_restart)(char str, const char *cmd); #define UDBG_UNDEFINED (1 << 0) #define UDBG_SYSCALL (1 << 1) diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index af377c73d90b..2de14e2afdc5 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -83,7 +83,7 @@ static int __init hlt_setup(char *__unused) __setup("nohlt", nohlt_setup); __setup("hlt", hlt_setup); -void arm_machine_restart(char mode) +void arm_machine_restart(char mode, const char *cmd) { /* * Clean and disable cache, and turn off interrupts @@ -100,7 +100,7 @@ void arm_machine_restart(char mode) /* * Now call the architecture specific reboot code. */ - arch_reset(mode); + arch_reset(mode, cmd); /* * Whoops - the architecture was unable to reboot. @@ -120,7 +120,7 @@ EXPORT_SYMBOL(pm_idle); void (*pm_power_off)(void); EXPORT_SYMBOL(pm_power_off); -void (*arm_pm_restart)(char str) = arm_machine_restart; +void (*arm_pm_restart)(char str, const char *cmd) = arm_machine_restart; EXPORT_SYMBOL_GPL(arm_pm_restart); @@ -195,9 +195,9 @@ void machine_power_off(void) pm_power_off(); } -void machine_restart(char * __unused) +void machine_restart(char *cmd) { - arm_pm_restart(reboot_mode); + arm_pm_restart(reboot_mode, cmd); } void __show_regs(struct pt_regs *regs) diff --git a/arch/arm/mach-aaec2000/include/mach/system.h b/arch/arm/mach-aaec2000/include/mach/system.h index 8f4115d734ce..fe08ca1add6f 100644 --- a/arch/arm/mach-aaec2000/include/mach/system.h +++ b/arch/arm/mach-aaec2000/include/mach/system.h @@ -16,7 +16,7 @@ static inline void arch_idle(void) cpu_do_idle(); } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { cpu_reset(0); } diff --git a/arch/arm/mach-at91/include/mach/system.h b/arch/arm/mach-at91/include/mach/system.h index e712658d966c..5268af3933c2 100644 --- a/arch/arm/mach-at91/include/mach/system.h +++ b/arch/arm/mach-at91/include/mach/system.h @@ -43,7 +43,7 @@ static inline void arch_idle(void) void (*at91_arch_reset)(void); -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { /* call the CPU-specific reset function */ if (at91_arch_reset) diff --git a/arch/arm/mach-clps711x/include/mach/system.h b/arch/arm/mach-clps711x/include/mach/system.h index 24e96159e3e7..f916cd7a477d 100644 --- a/arch/arm/mach-clps711x/include/mach/system.h +++ b/arch/arm/mach-clps711x/include/mach/system.h @@ -32,7 +32,7 @@ static inline void arch_idle(void) mov r0, r0"); } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { cpu_reset(0); } diff --git a/arch/arm/mach-davinci/include/mach/system.h b/arch/arm/mach-davinci/include/mach/system.h index 17ca41dc2c53..b7e7036674fa 100644 --- a/arch/arm/mach-davinci/include/mach/system.h +++ b/arch/arm/mach-davinci/include/mach/system.h @@ -21,7 +21,7 @@ static void arch_idle(void) cpu_do_idle(); } -static void arch_reset(char mode) +static void arch_reset(char mode, const char *cmd) { davinci_watchdog_reset(); } diff --git a/arch/arm/mach-ebsa110/include/mach/system.h b/arch/arm/mach-ebsa110/include/mach/system.h index 350a028997ef..9a26245bf1fc 100644 --- a/arch/arm/mach-ebsa110/include/mach/system.h +++ b/arch/arm/mach-ebsa110/include/mach/system.h @@ -34,6 +34,6 @@ static inline void arch_idle(void) asm volatile ("mcr p15, 0, ip, c15, c1, 2" : : : "cc"); } -#define arch_reset(mode) cpu_reset(0x80000000) +#define arch_reset(mode, cmd) cpu_reset(0x80000000) #endif diff --git a/arch/arm/mach-ep93xx/include/mach/system.h b/arch/arm/mach-ep93xx/include/mach/system.h index 67789d0f329e..ed8f35e4f068 100644 --- a/arch/arm/mach-ep93xx/include/mach/system.h +++ b/arch/arm/mach-ep93xx/include/mach/system.h @@ -9,7 +9,7 @@ static inline void arch_idle(void) cpu_do_idle(); } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { u32 devicecfg; diff --git a/arch/arm/mach-footbridge/include/mach/system.h b/arch/arm/mach-footbridge/include/mach/system.h index 2db7f36bd6ca..0b2931566209 100644 --- a/arch/arm/mach-footbridge/include/mach/system.h +++ b/arch/arm/mach-footbridge/include/mach/system.h @@ -18,7 +18,7 @@ static inline void arch_idle(void) cpu_do_idle(); } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { if (mode == 's') { /* diff --git a/arch/arm/mach-h720x/include/mach/system.h b/arch/arm/mach-h720x/include/mach/system.h index e4a7c760d52a..a708d24ee46d 100644 --- a/arch/arm/mach-h720x/include/mach/system.h +++ b/arch/arm/mach-h720x/include/mach/system.h @@ -25,7 +25,7 @@ static void arch_idle(void) } -static __inline__ void arch_reset(char mode) +static __inline__ void arch_reset(char mode, const char *cmd) { CPU_REG (PMU_BASE, PMU_STAT) |= PMU_WARMRESET; } diff --git a/arch/arm/mach-imx/include/mach/system.h b/arch/arm/mach-imx/include/mach/system.h index adee7e51bab2..46d4ca91af79 100644 --- a/arch/arm/mach-imx/include/mach/system.h +++ b/arch/arm/mach-imx/include/mach/system.h @@ -32,7 +32,7 @@ arch_idle(void) } static inline void -arch_reset(char mode) +arch_reset(char mode, const char *cmd) { cpu_reset(0); } diff --git a/arch/arm/mach-integrator/include/mach/system.h b/arch/arm/mach-integrator/include/mach/system.h index c485345c8c77..e1551b8dab77 100644 --- a/arch/arm/mach-integrator/include/mach/system.h +++ b/arch/arm/mach-integrator/include/mach/system.h @@ -32,7 +32,7 @@ static inline void arch_idle(void) cpu_do_idle(); } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { /* * To reset, we hit the on-board reset register diff --git a/arch/arm/mach-iop13xx/include/mach/system.h b/arch/arm/mach-iop13xx/include/mach/system.h index c7127f416e1f..d0c66ef450a7 100644 --- a/arch/arm/mach-iop13xx/include/mach/system.h +++ b/arch/arm/mach-iop13xx/include/mach/system.h @@ -13,7 +13,7 @@ static inline void arch_idle(void) cpu_do_idle(); } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { /* * Reset the internal bus (warning both cores are reset) diff --git a/arch/arm/mach-iop32x/include/mach/system.h b/arch/arm/mach-iop32x/include/mach/system.h index 32d9e5b0a28d..a4b808fe0d81 100644 --- a/arch/arm/mach-iop32x/include/mach/system.h +++ b/arch/arm/mach-iop32x/include/mach/system.h @@ -16,7 +16,7 @@ static inline void arch_idle(void) cpu_do_idle(); } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { local_irq_disable(); diff --git a/arch/arm/mach-iop33x/include/mach/system.h b/arch/arm/mach-iop33x/include/mach/system.h index 0cb3ad862acd..f192a34be073 100644 --- a/arch/arm/mach-iop33x/include/mach/system.h +++ b/arch/arm/mach-iop33x/include/mach/system.h @@ -14,7 +14,7 @@ static inline void arch_idle(void) cpu_do_idle(); } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { *IOP3XX_PCSR = 0x30; diff --git a/arch/arm/mach-ixp2000/include/mach/system.h b/arch/arm/mach-ixp2000/include/mach/system.h index 2e9c68f95a24..de370992c848 100644 --- a/arch/arm/mach-ixp2000/include/mach/system.h +++ b/arch/arm/mach-ixp2000/include/mach/system.h @@ -17,7 +17,7 @@ static inline void arch_idle(void) cpu_do_idle(); } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { local_irq_disable(); diff --git a/arch/arm/mach-ixp23xx/include/mach/system.h b/arch/arm/mach-ixp23xx/include/mach/system.h index d57c3fc10f1f..8920ff2dff1f 100644 --- a/arch/arm/mach-ixp23xx/include/mach/system.h +++ b/arch/arm/mach-ixp23xx/include/mach/system.h @@ -19,7 +19,7 @@ static inline void arch_idle(void) #endif } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { /* First try machine specific support */ if (machine_is_ixdp2351()) { diff --git a/arch/arm/mach-ixp4xx/include/mach/system.h b/arch/arm/mach-ixp4xx/include/mach/system.h index 92a7e8ddf69a..d2aa26f5acd7 100644 --- a/arch/arm/mach-ixp4xx/include/mach/system.h +++ b/arch/arm/mach-ixp4xx/include/mach/system.h @@ -20,7 +20,7 @@ static inline void arch_idle(void) } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { if ( 1 && mode == 's') { /* Jump into ROM at address 0 */ diff --git a/arch/arm/mach-kirkwood/include/mach/system.h b/arch/arm/mach-kirkwood/include/mach/system.h index 8510f6cfdabf..23a1914c1da8 100644 --- a/arch/arm/mach-kirkwood/include/mach/system.h +++ b/arch/arm/mach-kirkwood/include/mach/system.h @@ -17,7 +17,7 @@ static inline void arch_idle(void) cpu_do_idle(); } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { /* * Enable soft reset to assert RSTOUTn. diff --git a/arch/arm/mach-ks8695/include/mach/system.h b/arch/arm/mach-ks8695/include/mach/system.h index 5a9b032bdbeb..fb1dda9be2d0 100644 --- a/arch/arm/mach-ks8695/include/mach/system.h +++ b/arch/arm/mach-ks8695/include/mach/system.h @@ -27,7 +27,7 @@ static void arch_idle(void) } -static void arch_reset(char mode) +static void arch_reset(char mode, const char *cmd) { unsigned int reg; diff --git a/arch/arm/mach-l7200/include/mach/system.h b/arch/arm/mach-l7200/include/mach/system.h index 5272abee0d0e..e0dd3b6ae4aa 100644 --- a/arch/arm/mach-l7200/include/mach/system.h +++ b/arch/arm/mach-l7200/include/mach/system.h @@ -19,7 +19,7 @@ static inline void arch_idle(void) *(unsigned long *)(IO_BASE + 0x50004) = 1; /* idle mode */ } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { if (mode == 's') { cpu_reset(0); diff --git a/arch/arm/mach-lh7a40x/include/mach/system.h b/arch/arm/mach-lh7a40x/include/mach/system.h index fa46bb1ef07b..45a56d3b93d7 100644 --- a/arch/arm/mach-lh7a40x/include/mach/system.h +++ b/arch/arm/mach-lh7a40x/include/mach/system.h @@ -13,7 +13,7 @@ static inline void arch_idle(void) cpu_do_idle (); } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { cpu_reset (0); } diff --git a/arch/arm/mach-loki/include/mach/system.h b/arch/arm/mach-loki/include/mach/system.h index 8db1147d4ec5..c1de36fe9b37 100644 --- a/arch/arm/mach-loki/include/mach/system.h +++ b/arch/arm/mach-loki/include/mach/system.h @@ -17,7 +17,7 @@ static inline void arch_idle(void) cpu_do_idle(); } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { /* * Enable soft reset to assert RSTOUTn. diff --git a/arch/arm/mach-msm/include/mach/system.h b/arch/arm/mach-msm/include/mach/system.h index f05ad2e0f235..574ccc493daf 100644 --- a/arch/arm/mach-msm/include/mach/system.h +++ b/arch/arm/mach-msm/include/mach/system.h @@ -17,7 +17,7 @@ void arch_idle(void); -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { for (;;) ; /* depends on IPC w/ other core */ } diff --git a/arch/arm/mach-mv78xx0/include/mach/system.h b/arch/arm/mach-mv78xx0/include/mach/system.h index 7d5179408832..1d6350b22d0b 100644 --- a/arch/arm/mach-mv78xx0/include/mach/system.h +++ b/arch/arm/mach-mv78xx0/include/mach/system.h @@ -17,7 +17,7 @@ static inline void arch_idle(void) cpu_do_idle(); } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { /* * Enable soft reset to assert RSTOUTn. diff --git a/arch/arm/mach-mx2/system.c b/arch/arm/mach-mx2/system.c index 7b8269719d11..92c79d4bd162 100644 --- a/arch/arm/mach-mx2/system.c +++ b/arch/arm/mach-mx2/system.c @@ -46,7 +46,7 @@ void arch_idle(void) /* * Reset the system. It is called by machine_restart(). */ -void arch_reset(char mode) +void arch_reset(char mode, const char *cmd) { struct clk *clk; diff --git a/arch/arm/mach-netx/include/mach/system.h b/arch/arm/mach-netx/include/mach/system.h index 6c1023b8a9ab..dc7b4bc003c5 100644 --- a/arch/arm/mach-netx/include/mach/system.h +++ b/arch/arm/mach-netx/include/mach/system.h @@ -28,7 +28,7 @@ static inline void arch_idle(void) cpu_do_idle(); } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { writel(NETX_SYSTEM_RES_CR_FIRMW_RES_EN | NETX_SYSTEM_RES_CR_FIRMW_RES, NETX_SYSTEM_RES_CR); diff --git a/arch/arm/mach-ns9xxx/include/mach/system.h b/arch/arm/mach-ns9xxx/include/mach/system.h index e2068c57415f..1561588ca364 100644 --- a/arch/arm/mach-ns9xxx/include/mach/system.h +++ b/arch/arm/mach-ns9xxx/include/mach/system.h @@ -20,7 +20,7 @@ static inline void arch_idle(void) cpu_do_idle(); } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { #ifdef CONFIG_PROCESSOR_NS9360 if (processor_is_ns9360()) diff --git a/arch/arm/mach-orion5x/include/mach/system.h b/arch/arm/mach-orion5x/include/mach/system.h index 08e430757890..9b8db1dcfa83 100644 --- a/arch/arm/mach-orion5x/include/mach/system.h +++ b/arch/arm/mach-orion5x/include/mach/system.h @@ -19,7 +19,7 @@ static inline void arch_idle(void) cpu_do_idle(); } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { /* * Enable and issue soft reset diff --git a/arch/arm/mach-orion5x/lsmini-setup.c b/arch/arm/mach-orion5x/lsmini-setup.c index e0c43b8beb72..c9bf6b81a80d 100644 --- a/arch/arm/mach-orion5x/lsmini-setup.c +++ b/arch/arm/mach-orion5x/lsmini-setup.c @@ -186,7 +186,7 @@ static struct mv_sata_platform_data lsmini_sata_data = { static void lsmini_power_off(void) { - arch_reset(0); + arch_reset(0, NULL); } diff --git a/arch/arm/mach-pnx4008/include/mach/system.h b/arch/arm/mach-pnx4008/include/mach/system.h index e12e7abfcbcf..5dda2bb55f8d 100644 --- a/arch/arm/mach-pnx4008/include/mach/system.h +++ b/arch/arm/mach-pnx4008/include/mach/system.h @@ -30,7 +30,7 @@ static void arch_idle(void) cpu_do_idle(); } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { cpu_reset(0); } diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index 3b89e5010fb3..cdf21dd135b4 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -635,16 +635,16 @@ static void corgi_poweroff(void) /* Green LED off tells the bootloader to halt */ gpio_set_value(CORGI_GPIO_LED_GREEN, 0); - arm_machine_restart('h'); + arm_machine_restart('h', NULL); } -static void corgi_restart(char mode) +static void corgi_restart(char mode, const char *cmd) { if (!machine_is_corgi()) /* Green LED on tells the bootloader to reboot */ gpio_set_value(CORGI_GPIO_LED_GREEN, 1); - arm_machine_restart('h'); + arm_machine_restart('h', cmd); } static void __init corgi_init(void) diff --git a/arch/arm/mach-pxa/include/mach/system.h b/arch/arm/mach-pxa/include/mach/system.h index 0a587c4ec709..d1fce8b6d105 100644 --- a/arch/arm/mach-pxa/include/mach/system.h +++ b/arch/arm/mach-pxa/include/mach/system.h @@ -20,4 +20,4 @@ static inline void arch_idle(void) } -void arch_reset(char mode); +void arch_reset(char mode, const char *cmd); diff --git a/arch/arm/mach-pxa/mioa701.c b/arch/arm/mach-pxa/mioa701.c index 025772785d36..97c93a7a285c 100644 --- a/arch/arm/mach-pxa/mioa701.c +++ b/arch/arm/mach-pxa/mioa701.c @@ -788,13 +788,13 @@ static void mioa701_machine_exit(void); static void mioa701_poweroff(void) { mioa701_machine_exit(); - arm_machine_restart('s'); + arm_machine_restart('s', NULL); } -static void mioa701_restart(char c) +static void mioa701_restart(char c, const char *cmd) { mioa701_machine_exit(); - arm_machine_restart('s'); + arm_machine_restart('s', cmd); } struct gpio_ress global_gpios[] = { diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index 572ddec2b3e6..036bbde4d221 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -501,12 +501,12 @@ static struct platform_device *devices[] __initdata = { static void poodle_poweroff(void) { - arm_machine_restart('h'); + arm_machine_restart('h', NULL); } -static void poodle_restart(char mode) +static void poodle_restart(char mode, const char *cmd) { - arm_machine_restart('h'); + arm_machine_restart('h', cmd); } static void __init poodle_init(void) diff --git a/arch/arm/mach-pxa/reset.c b/arch/arm/mach-pxa/reset.c index 867c95c09618..df29d45fb4e7 100644 --- a/arch/arm/mach-pxa/reset.c +++ b/arch/arm/mach-pxa/reset.c @@ -81,7 +81,7 @@ static void do_hw_reset(void) OSMR3 = OSCR + 368640; /* ... in 100 ms */ } -void arch_reset(char mode) +void arch_reset(char mode, const char *cmd) { clear_reset_status(RESET_STATUS_ALL); diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c index f697c492b2ab..7a0a430222cf 100644 --- a/arch/arm/mach-pxa/spitz.c +++ b/arch/arm/mach-pxa/spitz.c @@ -701,10 +701,10 @@ static struct platform_device *devices[] __initdata = { static void spitz_poweroff(void) { - arm_machine_restart('g'); + arm_machine_restart('g', NULL); } -static void spitz_restart(char mode) +static void spitz_restart(char mode, const char *cmd) { /* Bootloader magic for a reboot */ if((MSC0 & 0xffff0000) == 0x7ff00000) diff --git a/arch/arm/mach-pxa/tosa.c b/arch/arm/mach-pxa/tosa.c index 66b13802c99d..4f6f5024884e 100644 --- a/arch/arm/mach-pxa/tosa.c +++ b/arch/arm/mach-pxa/tosa.c @@ -876,10 +876,10 @@ static struct platform_device *devices[] __initdata = { static void tosa_poweroff(void) { - arm_machine_restart('g'); + arm_machine_restart('g', NULL); } -static void tosa_restart(char mode) +static void tosa_restart(char mode, const char *cmd) { /* Bootloader magic for a reboot */ if((MSC0 & 0xffff0000) == 0x7ff00000) diff --git a/arch/arm/mach-realview/include/mach/system.h b/arch/arm/mach-realview/include/mach/system.h index a2f61c78adbf..1a15a441e027 100644 --- a/arch/arm/mach-realview/include/mach/system.h +++ b/arch/arm/mach-realview/include/mach/system.h @@ -34,7 +34,7 @@ static inline void arch_idle(void) cpu_do_idle(); } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { void __iomem *hdr_ctrl = __io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_RESETCTL_OFFSET; unsigned int val; diff --git a/arch/arm/mach-rpc/include/mach/system.h b/arch/arm/mach-rpc/include/mach/system.h index bd7268ba17e2..45c7b935dc45 100644 --- a/arch/arm/mach-rpc/include/mach/system.h +++ b/arch/arm/mach-rpc/include/mach/system.h @@ -16,7 +16,7 @@ static inline void arch_idle(void) cpu_do_idle(); } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { iomd_writeb(0, IOMD_ROMCR0); diff --git a/arch/arm/mach-s3c2410/include/mach/system-reset.h b/arch/arm/mach-s3c2410/include/mach/system-reset.h index 7613d0a384ba..b8687f71c304 100644 --- a/arch/arm/mach-s3c2410/include/mach/system-reset.h +++ b/arch/arm/mach-s3c2410/include/mach/system-reset.h @@ -22,7 +22,7 @@ extern void (*s3c24xx_reset_hook)(void); static void -arch_reset(char mode) +arch_reset(char mode, const char *cmd) { struct clk *wdtclk; diff --git a/arch/arm/mach-s3c6400/include/mach/system.h b/arch/arm/mach-s3c6400/include/mach/system.h index 652bbc403f0b..090cfd969bc7 100644 --- a/arch/arm/mach-s3c6400/include/mach/system.h +++ b/arch/arm/mach-s3c6400/include/mach/system.h @@ -16,7 +16,7 @@ static void arch_idle(void) /* nothing here yet */ } -static void arch_reset(char mode) +static void arch_reset(char mode, const char *cmd) { /* nothing here yet */ } diff --git a/arch/arm/mach-sa1100/include/mach/system.h b/arch/arm/mach-sa1100/include/mach/system.h index 63755ca5b1b4..942b153e251d 100644 --- a/arch/arm/mach-sa1100/include/mach/system.h +++ b/arch/arm/mach-sa1100/include/mach/system.h @@ -10,7 +10,7 @@ static inline void arch_idle(void) cpu_do_idle(); } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { if (mode == 's') { /* Jump into ROM at address 0 */ diff --git a/arch/arm/mach-shark/core.c b/arch/arm/mach-shark/core.c index 4f3a26512599..358d875ace14 100644 --- a/arch/arm/mach-shark/core.c +++ b/arch/arm/mach-shark/core.c @@ -26,7 +26,7 @@ #define ROMCARD_SIZE 0x08000000 #define ROMCARD_START 0x10000000 -void arch_reset(char mode) +void arch_reset(char mode, const char *cmd) { short temp; local_irq_disable(); diff --git a/arch/arm/mach-shark/include/mach/system.h b/arch/arm/mach-shark/include/mach/system.h index 0752ca29971a..21c373b30bbc 100644 --- a/arch/arm/mach-shark/include/mach/system.h +++ b/arch/arm/mach-shark/include/mach/system.h @@ -7,7 +7,7 @@ #define __ASM_ARCH_SYSTEM_H /* Found in arch/mach-shark/core.c */ -extern void arch_reset(char mode); +extern void arch_reset(char mode, const char *cmd); static inline void arch_idle(void) { diff --git a/arch/arm/mach-versatile/include/mach/system.h b/arch/arm/mach-versatile/include/mach/system.h index c59e6100c7e3..8ffc12a7cb25 100644 --- a/arch/arm/mach-versatile/include/mach/system.h +++ b/arch/arm/mach-versatile/include/mach/system.h @@ -34,7 +34,7 @@ static inline void arch_idle(void) cpu_do_idle(); } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { u32 val; diff --git a/arch/arm/mach-w90x900/include/mach/system.h b/arch/arm/mach-w90x900/include/mach/system.h index 93753f922618..940640066857 100644 --- a/arch/arm/mach-w90x900/include/mach/system.h +++ b/arch/arm/mach-w90x900/include/mach/system.h @@ -21,7 +21,7 @@ static void arch_idle(void) { } -static void arch_reset(char mode) +static void arch_reset(char mode, const char *cmd) { cpu_reset(0); } diff --git a/arch/arm/plat-mxc/include/mach/system.h b/arch/arm/plat-mxc/include/mach/system.h index bbfc37465fc5..cd03ebaa49bc 100644 --- a/arch/arm/plat-mxc/include/mach/system.h +++ b/arch/arm/plat-mxc/include/mach/system.h @@ -26,7 +26,7 @@ static inline void arch_idle(void) cpu_do_idle(); } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { cpu_reset(0); } diff --git a/arch/arm/plat-omap/include/mach/system.h b/arch/arm/plat-omap/include/mach/system.h index e9b95637f7fc..cb8c0ef30fba 100644 --- a/arch/arm/plat-omap/include/mach/system.h +++ b/arch/arm/plat-omap/include/mach/system.h @@ -38,7 +38,7 @@ static inline void omap1_arch_reset(char mode) omap_writew(1, ARM_RSTCT1); } -static inline void arch_reset(char mode) +static inline void arch_reset(char mode, const char *cmd) { if (!cpu_class_is_omap2()) omap1_arch_reset(mode); diff --git a/arch/arm/plat-s3c24xx/cpu.c b/arch/arm/plat-s3c24xx/cpu.c index 542062f8cbc1..1932b7e0da15 100644 --- a/arch/arm/plat-s3c24xx/cpu.c +++ b/arch/arm/plat-s3c24xx/cpu.c @@ -182,7 +182,7 @@ static unsigned long s3c24xx_read_idcode_v4(void) * with the caches enabled. It seems at least the S3C2440 has a problem * resetting if there is bus activity interrupted by the reset. */ -static void s3c24xx_pm_restart(char mode) +static void s3c24xx_pm_restart(char mode, const char *cmd) { if (mode != 's') { unsigned long flags; @@ -191,12 +191,12 @@ static void s3c24xx_pm_restart(char mode) __cpuc_flush_kern_all(); __cpuc_flush_user_all(); - arch_reset(mode); + arch_reset(mode, cmd); local_irq_restore(flags); } /* fallback, or unhandled */ - arm_machine_restart(mode); + arm_machine_restart(mode, cmd); } void __init s3c24xx_init_io(struct map_desc *mach_desc, int size) -- cgit v1.2.3 From 74bef9a4fa978669b234c4454daa596c0494c09a Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Tue, 3 Mar 2009 02:49:23 +0300 Subject: mxc: add arch_reset() function This patch adds arch_reset() function for all mxc platforms. It also removes (unsused) arch/arm/mach-mx2/system.c file. This patch has been tested on i.MX1/27/31/35 Signed-off-by: Ilya Yanok Signed-off-by: Sascha Hauer --- arch/arm/mach-mx2/Makefile | 2 +- arch/arm/mach-mx2/system.c | 63 ------------------------------- arch/arm/plat-mxc/Makefile | 2 +- arch/arm/plat-mxc/include/mach/system.h | 5 +-- arch/arm/plat-mxc/system.c | 67 +++++++++++++++++++++++++++++++++ 5 files changed, 70 insertions(+), 69 deletions(-) delete mode 100644 arch/arm/mach-mx2/system.c create mode 100644 arch/arm/plat-mxc/system.c (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/mach-mx2/Makefile b/arch/arm/mach-mx2/Makefile index 6e1a2bffc812..950649a91540 100644 --- a/arch/arm/mach-mx2/Makefile +++ b/arch/arm/mach-mx2/Makefile @@ -4,7 +4,7 @@ # Object file lists. -obj-y := system.o generic.o devices.o serial.o +obj-y := generic.o devices.o serial.o obj-$(CONFIG_MACH_MX21) += clock_imx21.o diff --git a/arch/arm/mach-mx2/system.c b/arch/arm/mach-mx2/system.c deleted file mode 100644 index 92c79d4bd162..000000000000 --- a/arch/arm/mach-mx2/system.c +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 1999 ARM Limited - * Copyright (C) 2000 Deep Blue Solutions Ltd - * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved. - * Copyright 2008 Juergen Beisert, kernel@pengutronix.de - * - * 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. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -#include -#include -#include - -#include -#include -#include - -/* - * Put the CPU into idle mode. It is called by default_idle() - * in process.c file. - */ -void arch_idle(void) -{ - /* - * This should do all the clock switching - * and wait for interrupt tricks. - */ - cpu_do_idle(); -} - -#define WDOG_WCR_REG IO_ADDRESS(WDOG_BASE_ADDR) -#define WDOG_WCR_SRS (1 << 4) - -/* - * Reset the system. It is called by machine_restart(). - */ -void arch_reset(char mode, const char *cmd) -{ - struct clk *clk; - - clk = clk_get(NULL, "wdog_clk"); - if (!clk) { - printk(KERN_ERR"Cannot activate the watchdog. Giving up\n"); - return; - } - - clk_enable(clk); - - /* Assert SRS signal */ - __raw_writew(__raw_readw(WDOG_WCR_REG) & ~WDOG_WCR_SRS, WDOG_WCR_REG); -} diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile index 564fd4ebf38a..055406312b69 100644 --- a/arch/arm/plat-mxc/Makefile +++ b/arch/arm/plat-mxc/Makefile @@ -3,7 +3,7 @@ # # Common support -obj-y := irq.o clock.o gpio.o time.o devices.o cpu.o +obj-y := irq.o clock.o gpio.o time.o devices.o cpu.o system.o obj-$(CONFIG_ARCH_MX1) += iomux-mx1-mx2.o dma-mx1-mx2.o obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o diff --git a/arch/arm/plat-mxc/include/mach/system.h b/arch/arm/plat-mxc/include/mach/system.h index cd03ebaa49bc..e56241af870e 100644 --- a/arch/arm/plat-mxc/include/mach/system.h +++ b/arch/arm/plat-mxc/include/mach/system.h @@ -26,9 +26,6 @@ static inline void arch_idle(void) cpu_do_idle(); } -static inline void arch_reset(char mode, const char *cmd) -{ - cpu_reset(0); -} +void arch_reset(char mode, const char *cmd); #endif /* __ASM_ARCH_MXC_SYSTEM_H__ */ diff --git a/arch/arm/plat-mxc/system.c b/arch/arm/plat-mxc/system.c new file mode 100644 index 000000000000..79c37577c916 --- /dev/null +++ b/arch/arm/plat-mxc/system.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 1999 ARM Limited + * Copyright (C) 2000 Deep Blue Solutions Ltd + * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2008 Juergen Beisert, kernel@pengutronix.de + * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok@emcraft.com + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#ifdef CONFIG_ARCH_MX1 +#define WDOG_WCR_REG IO_ADDRESS(WDT_BASE_ADDR) +#define WDOG_WCR_ENABLE (1 << 0) +#else +#define WDOG_WCR_REG IO_ADDRESS(WDOG_BASE_ADDR) +#define WDOG_WCR_ENABLE (1 << 2) +#endif + +/* + * Reset the system. It is called by machine_restart(). + */ +void arch_reset(char mode, const char *cmd) +{ + if (!cpu_is_mx1()) { + struct clk *clk; + + clk = clk_get_sys("imx-wdt.0", NULL); + if (!IS_ERR(clk)) + clk_enable(clk); + } + + /* Assert SRS signal */ + __raw_writew(WDOG_WCR_ENABLE, WDOG_WCR_REG); + + /* wait for reset to assert... */ + mdelay(500); + + printk(KERN_ERR "Watchdog reset failed to assert reset\n"); + + /* delay to allow the serial port to show the message */ + mdelay(50); + + /* we'll take a jump through zero as a poor second */ + cpu_reset(0); +} -- cgit v1.2.3 From 4f67130ad35d6760c27984cf94b13a8cb85e4034 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Mon, 23 Feb 2009 12:13:24 -0300 Subject: V4L/DVB (10674): soc-camera: camera host driver for i.MX3x SoCs Tested with 8 bit Bayer and 8 bit monochrome video. create mode 100644 arch/arm/plat-mxc/include/mach/mx3_camera.h create mode 100644 drivers/media/video/mx3_camera.c Signed-off-by: Guennadi Liakhovetski Signed-off-by: Mauro Carvalho Chehab --- arch/arm/plat-mxc/include/mach/mx3_camera.h | 52 ++ drivers/media/video/Kconfig | 7 + drivers/media/video/Makefile | 5 +- drivers/media/video/mx3_camera.c | 1183 +++++++++++++++++++++++++++ 4 files changed, 1245 insertions(+), 2 deletions(-) create mode 100644 arch/arm/plat-mxc/include/mach/mx3_camera.h create mode 100644 drivers/media/video/mx3_camera.c (limited to 'arch/arm/plat-mxc') diff --git a/arch/arm/plat-mxc/include/mach/mx3_camera.h b/arch/arm/plat-mxc/include/mach/mx3_camera.h new file mode 100644 index 000000000000..36d7ff27b5e2 --- /dev/null +++ b/arch/arm/plat-mxc/include/mach/mx3_camera.h @@ -0,0 +1,52 @@ +/* + * mx3_camera.h - i.MX3x camera driver header file + * + * Copyright (C) 2008, Guennadi Liakhovetski, DENX Software Engineering, + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef _MX3_CAMERA_H_ +#define _MX3_CAMERA_H_ + +#include + +#define MX3_CAMERA_CLK_SRC 1 +#define MX3_CAMERA_EXT_VSYNC 2 +#define MX3_CAMERA_DP 4 +#define MX3_CAMERA_PCP 8 +#define MX3_CAMERA_HSP 0x10 +#define MX3_CAMERA_VSP 0x20 +#define MX3_CAMERA_DATAWIDTH_4 0x40 +#define MX3_CAMERA_DATAWIDTH_8 0x80 +#define MX3_CAMERA_DATAWIDTH_10 0x100 +#define MX3_CAMERA_DATAWIDTH_15 0x200 + +#define MX3_CAMERA_DATAWIDTH_MASK (MX3_CAMERA_DATAWIDTH_4 | MX3_CAMERA_DATAWIDTH_8 | \ + MX3_CAMERA_DATAWIDTH_10 | MX3_CAMERA_DATAWIDTH_15) + +/** + * struct mx3_camera_pdata - i.MX3x camera platform data + * @flags: MX3_CAMERA_* flags + * @mclk_10khz: master clock frequency in 10kHz units + * @dma_dev: IPU DMA device to match against in channel allocation + */ +struct mx3_camera_pdata { + unsigned long flags; + unsigned long mclk_10khz; + struct device *dma_dev; +}; + +#endif diff --git a/drivers/media/video/Kconfig b/drivers/media/video/Kconfig index 19cf3b8f67c4..3e4ce4aade3e 100644 --- a/drivers/media/video/Kconfig +++ b/drivers/media/video/Kconfig @@ -779,6 +779,13 @@ config SOC_CAMERA_OV772X help This is a ov772x camera driver +config VIDEO_MX3 + tristate "i.MX3x Camera Sensor Interface driver" + depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA + select VIDEOBUF_DMA_CONTIG + ---help--- + This is a v4l2 driver for the i.MX3x Camera Sensor Interface + config VIDEO_PXA27x tristate "PXA27x Quick Capture Interface driver" depends on VIDEO_DEV && PXA27x && SOC_CAMERA diff --git a/drivers/media/video/Makefile b/drivers/media/video/Makefile index 72f6d03d2d8f..6e2c69569f97 100644 --- a/drivers/media/video/Makefile +++ b/drivers/media/video/Makefile @@ -134,10 +134,11 @@ obj-$(CONFIG_VIDEO_CX18) += cx18/ obj-$(CONFIG_VIDEO_VIVI) += vivi.o obj-$(CONFIG_VIDEO_CX23885) += cx23885/ -obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o +obj-$(CONFIG_VIDEO_MX3) += mx3_camera.o +obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o obj-$(CONFIG_VIDEO_OMAP2) += omap2cam.o -obj-$(CONFIG_SOC_CAMERA) += soc_camera.o +obj-$(CONFIG_SOC_CAMERA) += soc_camera.o obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o obj-$(CONFIG_SOC_CAMERA_MT9T031) += mt9t031.o diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c new file mode 100644 index 000000000000..f525dc48f6ca --- /dev/null +++ b/drivers/media/video/mx3_camera.c @@ -0,0 +1,1183 @@ +/* + * V4L2 Driver for i.MX3x camera host + * + * Copyright (C) 2008 + * Guennadi Liakhovetski, DENX Software Engineering, + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#define MX3_CAM_DRV_NAME "mx3-camera" + +/* CMOS Sensor Interface Registers */ +#define CSI_REG_START 0x60 + +#define CSI_SENS_CONF (0x60 - CSI_REG_START) +#define CSI_SENS_FRM_SIZE (0x64 - CSI_REG_START) +#define CSI_ACT_FRM_SIZE (0x68 - CSI_REG_START) +#define CSI_OUT_FRM_CTRL (0x6C - CSI_REG_START) +#define CSI_TST_CTRL (0x70 - CSI_REG_START) +#define CSI_CCIR_CODE_1 (0x74 - CSI_REG_START) +#define CSI_CCIR_CODE_2 (0x78 - CSI_REG_START) +#define CSI_CCIR_CODE_3 (0x7C - CSI_REG_START) +#define CSI_FLASH_STROBE_1 (0x80 - CSI_REG_START) +#define CSI_FLASH_STROBE_2 (0x84 - CSI_REG_START) + +#define CSI_SENS_CONF_VSYNC_POL_SHIFT 0 +#define CSI_SENS_CONF_HSYNC_POL_SHIFT 1 +#define CSI_SENS_CONF_DATA_POL_SHIFT 2 +#define CSI_SENS_CONF_PIX_CLK_POL_SHIFT 3 +#define CSI_SENS_CONF_SENS_PRTCL_SHIFT 4 +#define CSI_SENS_CONF_SENS_CLKSRC_SHIFT 7 +#define CSI_SENS_CONF_DATA_FMT_SHIFT 8 +#define CSI_SENS_CONF_DATA_WIDTH_SHIFT 10 +#define CSI_SENS_CONF_EXT_VSYNC_SHIFT 15 +#define CSI_SENS_CONF_DIVRATIO_SHIFT 16 + +#define CSI_SENS_CONF_DATA_FMT_RGB_YUV444 (0UL << CSI_SENS_CONF_DATA_FMT_SHIFT) +#define CSI_SENS_CONF_DATA_FMT_YUV422 (2UL << CSI_SENS_CONF_DATA_FMT_SHIFT) +#define CSI_SENS_CONF_DATA_FMT_BAYER (3UL << CSI_SENS_CONF_DATA_FMT_SHIFT) + +#define MAX_VIDEO_MEM 16 + +struct mx3_camera_buffer { + /* common v4l buffer stuff -- must be first */ + struct videobuf_buffer vb; + const struct soc_camera_data_format *fmt; + + /* One descriptot per scatterlist (per frame) */ + struct dma_async_tx_descriptor *txd; + + /* We have to "build" a scatterlist ourselves - one element per frame */ + struct scatterlist sg; +}; + +/** + * struct mx3_camera_dev - i.MX3x camera (CSI) object + * @dev: camera device, to which the coherent buffer is attached + * @icd: currently attached camera sensor + * @clk: pointer to clock + * @base: remapped register base address + * @pdata: platform data + * @platform_flags: platform flags + * @mclk: master clock frequency in Hz + * @capture: list of capture videobuffers + * @lock: protects video buffer lists + * @active: active video buffer + * @idmac_channel: array of pointers to IPU DMAC DMA channels + * @soc_host: embedded soc_host object + */ +struct mx3_camera_dev { + struct device *dev; + /* + * i.MX3x is only supposed to handle one camera on its Camera Sensor + * Interface. If anyone ever builds hardware to enable more than one + * camera _simultaneously_, they will have to modify this driver too + */ + struct soc_camera_device *icd; + struct clk *clk; + + void __iomem *base; + + struct mx3_camera_pdata *pdata; + + unsigned long platform_flags; + unsigned long mclk; + + struct list_head capture; + spinlock_t lock; /* Protects video buffer lists */ + struct mx3_camera_buffer *active; + + /* IDMAC / dmaengine interface */ + struct idmac_channel *idmac_channel[1]; /* We need one channel */ + + struct soc_camera_host soc_host; +}; + +struct dma_chan_request { + struct mx3_camera_dev *mx3_cam; + enum ipu_channel id; +}; + +static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt); + +static u32 csi_reg_read(struct mx3_camera_dev *mx3, off_t reg) +{ + return __raw_readl(mx3->base + reg); +} + +static void csi_reg_write(struct mx3_camera_dev *mx3, u32 value, off_t reg) +{ + __raw_writel(value, mx3->base + reg); +} + +/* Called from the IPU IDMAC ISR */ +static void mx3_cam_dma_done(void *arg) +{ + struct idmac_tx_desc *desc = to_tx_desc(arg); + struct dma_chan *chan = desc->txd.chan; + struct idmac_channel *ichannel = to_idmac_chan(chan); + struct mx3_camera_dev *mx3_cam = ichannel->client; + struct videobuf_buffer *vb; + + dev_dbg(chan->device->dev, "callback cookie %d, active DMA 0x%08x\n", + desc->txd.cookie, mx3_cam->active ? sg_dma_address(&mx3_cam->active->sg) : 0); + + spin_lock(&mx3_cam->lock); + if (mx3_cam->active) { + vb = &mx3_cam->active->vb; + + list_del_init(&vb->queue); + vb->state = VIDEOBUF_DONE; + do_gettimeofday(&vb->ts); + vb->field_count++; + wake_up(&vb->done); + } + + if (list_empty(&mx3_cam->capture)) { + mx3_cam->active = NULL; + spin_unlock(&mx3_cam->lock); + + /* + * stop capture - without further buffers IPU_CHA_BUF0_RDY will + * not get updated + */ + return; + } + + mx3_cam->active = list_entry(mx3_cam->capture.next, + struct mx3_camera_buffer, vb.queue); + mx3_cam->active->vb.state = VIDEOBUF_ACTIVE; + spin_unlock(&mx3_cam->lock); +} + +static void free_buffer(struct videobuf_queue *vq, struct mx3_camera_buffer *buf) +{ + struct soc_camera_device *icd = vq->priv_data; + struct videobuf_buffer *vb = &buf->vb; + struct dma_async_tx_descriptor *txd = buf->txd; + struct idmac_channel *ichan; + + BUG_ON(in_interrupt()); + + dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__, + vb, vb->baddr, vb->bsize); + + /* + * This waits until this buffer is out of danger, i.e., until it is no + * longer in STATE_QUEUED or STATE_ACTIVE + */ + videobuf_waiton(vb, 0, 0); + if (txd) { + ichan = to_idmac_chan(txd->chan); + async_tx_ack(txd); + } + videobuf_dma_contig_free(vq, vb); + buf->txd = NULL; + + vb->state = VIDEOBUF_NEEDS_INIT; +} + +/* + * Videobuf operations + */ + +/* + * Calculate the __buffer__ (not data) size and number of buffers. + * Called with .vb_lock held + */ +static int mx3_videobuf_setup(struct videobuf_queue *vq, unsigned int *count, + unsigned int *size) +{ + struct soc_camera_device *icd = vq->priv_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct mx3_camera_dev *mx3_cam = ici->priv; + /* + * bits-per-pixel (depth) as specified in camera's pixel format does + * not necessarily match what the camera interface writes to RAM, but + * it should be good enough for now. + */ + unsigned int bpp = DIV_ROUND_UP(icd->current_fmt->depth, 8); + + if (!mx3_cam->idmac_channel[0]) + return -EINVAL; + + *size = icd->width * icd->height * bpp; + + if (!*count) + *count = 32; + + if (*size * *count > MAX_VIDEO_MEM * 1024 * 1024) + *count = MAX_VIDEO_MEM * 1024 * 1024 / *size; + + return 0; +} + +/* Called with .vb_lock held */ +static int mx3_videobuf_prepare(struct videobuf_queue *vq, + struct videobuf_buffer *vb, enum v4l2_field field) +{ + struct soc_camera_device *icd = vq->priv_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct mx3_camera_dev *mx3_cam = ici->priv; + struct mx3_camera_buffer *buf = + container_of(vb, struct mx3_camera_buffer, vb); + /* current_fmt _must_ always be set */ + size_t new_size = icd->width * icd->height * + ((icd->current_fmt->depth + 7) >> 3); + int ret; + + /* + * I think, in buf_prepare you only have to protect global data, + * the actual buffer is yours + */ + + if (buf->fmt != icd->current_fmt || + vb->width != icd->width || + vb->height != icd->height || + vb->field != field) { + buf->fmt = icd->current_fmt; + vb->width = icd->width; + vb->height = icd->height; + vb->field = field; + if (vb->state != VIDEOBUF_NEEDS_INIT) + free_buffer(vq, buf); + } + + if (vb->baddr && vb->bsize < new_size) { + /* User provided buffer, but it is too small */ + ret = -ENOMEM; + goto out; + } + + if (vb->state == VIDEOBUF_NEEDS_INIT) { + struct idmac_channel *ichan = mx3_cam->idmac_channel[0]; + struct scatterlist *sg = &buf->sg; + + /* + * The total size of video-buffers that will be allocated / mapped. + * *size that we calculated in videobuf_setup gets assigned to + * vb->bsize, and now we use the same calculation to get vb->size. + */ + vb->size = new_size; + + /* This actually (allocates and) maps buffers */ + ret = videobuf_iolock(vq, vb, NULL); + if (ret) + goto fail; + + /* + * We will have to configure the IDMAC channel. It has two slots + * for DMA buffers, we shall enter the first two buffers there, + * and then submit new buffers in DMA-ready interrupts + */ + sg_init_table(sg, 1); + sg_dma_address(sg) = videobuf_to_dma_contig(vb); + sg_dma_len(sg) = vb->size; + + buf->txd = ichan->dma_chan.device->device_prep_slave_sg( + &ichan->dma_chan, sg, 1, DMA_FROM_DEVICE, + DMA_PREP_INTERRUPT); + if (!buf->txd) { + ret = -EIO; + goto fail; + } + + buf->txd->callback_param = buf->txd; + buf->txd->callback = mx3_cam_dma_done; + + vb->state = VIDEOBUF_PREPARED; + } + + return 0; + +fail: + free_buffer(vq, buf); +out: + return ret; +} + +static enum pixel_fmt fourcc_to_ipu_pix(__u32 fourcc) +{ + /* Add more formats as need arises and test possibilities appear... */ + switch (fourcc) { + case V4L2_PIX_FMT_RGB565: + return IPU_PIX_FMT_RGB565; + case V4L2_PIX_FMT_RGB24: + return IPU_PIX_FMT_RGB24; + case V4L2_PIX_FMT_RGB332: + return IPU_PIX_FMT_RGB332; + case V4L2_PIX_FMT_YUV422P: + return IPU_PIX_FMT_YVU422P; + default: + return IPU_PIX_FMT_GENERIC; + } +} + +/* Called with .vb_lock held */ +static void mx3_videobuf_queue(struct videobuf_queue *vq, + struct videobuf_buffer *vb) +{ + struct soc_camera_device *icd = vq->priv_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct mx3_camera_dev *mx3_cam = ici->priv; + struct mx3_camera_buffer *buf = + container_of(vb, struct mx3_camera_buffer, vb); + struct dma_async_tx_descriptor *txd = buf->txd; + struct idmac_channel *ichan = to_idmac_chan(txd->chan); + struct idmac_video_param *video = &ichan->params.video; + const struct soc_camera_data_format *data_fmt = icd->current_fmt; + dma_cookie_t cookie; + unsigned long flags; + + /* This is the configuration of one sg-element */ + video->out_pixel_fmt = fourcc_to_ipu_pix(data_fmt->fourcc); + video->out_width = icd->width; + video->out_height = icd->height; + video->out_stride = icd->width; + +#ifdef DEBUG + /* helps to see what DMA actually has written */ + memset((void *)vb->baddr, 0xaa, vb->bsize); +#endif + + spin_lock_irqsave(&mx3_cam->lock, flags); + + list_add_tail(&vb->queue, &mx3_cam->capture); + + if (!mx3_cam->active) { + mx3_cam->active = buf; + vb->state = VIDEOBUF_ACTIVE; + } else { + vb->state = VIDEOBUF_QUEUED; + } + + spin_unlock_irqrestore(&mx3_cam->lock, flags); + + cookie = txd->tx_submit(txd); + dev_dbg(&icd->dev, "Submitted cookie %d DMA 0x%08x\n", cookie, sg_dma_address(&buf->sg)); + if (cookie >= 0) + return; + + /* Submit error */ + vb->state = VIDEOBUF_PREPARED; + + spin_lock_irqsave(&mx3_cam->lock, flags); + + list_del_init(&vb->queue); + + if (mx3_cam->active == buf) + mx3_cam->active = NULL; + + spin_unlock_irqrestore(&mx3_cam->lock, flags); +} + +/* Called with .vb_lock held */ +static void mx3_videobuf_release(struct videobuf_queue *vq, + struct videobuf_buffer *vb) +{ + struct soc_camera_device *icd = vq->priv_data; + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct mx3_camera_dev *mx3_cam = ici->priv; + struct mx3_camera_buffer *buf = + container_of(vb, struct mx3_camera_buffer, vb); + unsigned long flags; + + dev_dbg(&icd->dev, "Release%s DMA 0x%08x (state %d), queue %sempty\n", + mx3_cam->active == buf ? " active" : "", sg_dma_address(&buf->sg), + vb->state, list_empty(&vb->queue) ? "" : "not "); + spin_lock_irqsave(&mx3_cam->lock, flags); + if ((vb->state == VIDEOBUF_ACTIVE || vb->state == VIDEOBUF_QUEUED) && + !list_empty(&vb->queue)) { + vb->state = VIDEOBUF_ERROR; + + list_del_init(&vb->queue); + if (mx3_cam->active == buf) + mx3_cam->active = NULL; + } + spin_unlock_irqrestore(&mx3_cam->lock, flags); + free_buffer(vq, buf); +} + +static struct videobuf_queue_ops mx3_videobuf_ops = { + .buf_setup = mx3_videobuf_setup, + .buf_prepare = mx3_videobuf_prepare, + .buf_queue = mx3_videobuf_queue, + .buf_release = mx3_videobuf_release, +}; + +static void mx3_camera_init_videobuf(struct videobuf_queue *q, + struct soc_camera_device *icd) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct mx3_camera_dev *mx3_cam = ici->priv; + + videobuf_queue_dma_contig_init(q, &mx3_videobuf_ops, mx3_cam->dev, + &mx3_cam->lock, + V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_FIELD_NONE, + sizeof(struct mx3_camera_buffer), icd); +} + +/* First part of ipu_csi_init_interface() */ +static void mx3_camera_activate(struct mx3_camera_dev *mx3_cam, + struct soc_camera_device *icd) +{ + u32 conf; + long rate; + + /* Set default size: ipu_csi_set_window_size() */ + csi_reg_write(mx3_cam, (640 - 1) | ((480 - 1) << 16), CSI_ACT_FRM_SIZE); + /* ...and position to 0:0: ipu_csi_set_window_pos() */ + conf = csi_reg_read(mx3_cam, CSI_OUT_FRM_CTRL) & 0xffff0000; + csi_reg_write(mx3_cam, conf, CSI_OUT_FRM_CTRL); + + /* We use only gated clock synchronisation mode so far */ + conf = 0 << CSI_SENS_CONF_SENS_PRTCL_SHIFT; + + /* Set generic data, platform-biggest bus-width */ + conf |= CSI_SENS_CONF_DATA_FMT_BAYER; + + if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15) + conf |= 3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT; + else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10) + conf |= 2 << CSI_SENS_CONF_DATA_WIDTH_SHIFT; + else if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8) + conf |= 1 << CSI_SENS_CONF_DATA_WIDTH_SHIFT; + else/* if (mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)*/ + conf |= 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT; + + if (mx3_cam->platform_flags & MX3_CAMERA_CLK_SRC) + conf |= 1 << CSI_SENS_CONF_SENS_CLKSRC_SHIFT; + if (mx3_cam->platform_flags & MX3_CAMERA_EXT_VSYNC) + conf |= 1 << CSI_SENS_CONF_EXT_VSYNC_SHIFT; + if (mx3_cam->platform_flags & MX3_CAMERA_DP) + conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT; + if (mx3_cam->platform_flags & MX3_CAMERA_PCP) + conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT; + if (mx3_cam->platform_flags & MX3_CAMERA_HSP) + conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT; + if (mx3_cam->platform_flags & MX3_CAMERA_VSP) + conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT; + + /* ipu_csi_init_interface() */ + csi_reg_write(mx3_cam, conf, CSI_SENS_CONF); + + clk_enable(mx3_cam->clk); + rate = clk_round_rate(mx3_cam->clk, mx3_cam->mclk); + dev_dbg(&icd->dev, "Set SENS_CONF to %x, rate %ld\n", conf, rate); + if (rate) + clk_set_rate(mx3_cam->clk, rate); +} + +/* Called with .video_lock held */ +static int mx3_camera_add_device(struct soc_camera_device *icd) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct mx3_camera_dev *mx3_cam = ici->priv; + int ret; + + if (mx3_cam->icd) { + ret = -EBUSY; + goto ebusy; + } + + mx3_camera_activate(mx3_cam, icd); + ret = icd->ops->init(icd); + if (ret < 0) { + clk_disable(mx3_cam->clk); + goto einit; + } + + mx3_cam->icd = icd; + +einit: +ebusy: + if (!ret) + dev_info(&icd->dev, "MX3 Camera driver attached to camera %d\n", + icd->devnum); + + return ret; +} + +/* Called with .video_lock held */ +static void mx3_camera_remove_device(struct soc_camera_device *icd) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct mx3_camera_dev *mx3_cam = ici->priv; + struct idmac_channel **ichan = &mx3_cam->idmac_channel[0]; + + BUG_ON(icd != mx3_cam->icd); + + if (*ichan) { + dma_release_channel(&(*ichan)->dma_chan); + *ichan = NULL; + } + + icd->ops->release(icd); + + clk_disable(mx3_cam->clk); + + mx3_cam->icd = NULL; + + dev_info(&icd->dev, "MX3 Camera driver detached from camera %d\n", + icd->devnum); +} + +static bool channel_change_requested(struct soc_camera_device *icd, + const struct soc_camera_format_xlate *xlate, + __u32 pixfmt, struct v4l2_rect *rect) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct mx3_camera_dev *mx3_cam = ici->priv; + struct idmac_channel *ichan = mx3_cam->idmac_channel[0]; + + /* So far only one configuration is supported */ + return pixfmt || (ichan && rect->width * rect->height > + icd->width * icd->height); +} + +static int test_platform_param(struct mx3_camera_dev *mx3_cam, + unsigned char buswidth, unsigned long *flags) +{ + /* + * Platform specified synchronization and pixel clock polarities are + * only a recommendation and are only used during probing. MX3x + * camera interface only works in master mode, i.e., uses HSYNC and + * VSYNC signals from the sensor + */ + *flags = SOCAM_MASTER | + SOCAM_HSYNC_ACTIVE_HIGH | + SOCAM_HSYNC_ACTIVE_LOW | + SOCAM_VSYNC_ACTIVE_HIGH | + SOCAM_VSYNC_ACTIVE_LOW | + SOCAM_PCLK_SAMPLE_RISING | + SOCAM_PCLK_SAMPLE_FALLING | + SOCAM_DATA_ACTIVE_HIGH | + SOCAM_DATA_ACTIVE_LOW; + + /* If requested data width is supported by the platform, use it or any + * possible lower value - i.MX31 is smart enough to schift bits */ + switch (buswidth) { + case 15: + if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15)) + return -EINVAL; + *flags |= SOCAM_DATAWIDTH_15 | SOCAM_DATAWIDTH_10 | + SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4; + break; + case 10: + if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10)) + return -EINVAL; + *flags |= SOCAM_DATAWIDTH_10 | SOCAM_DATAWIDTH_8 | + SOCAM_DATAWIDTH_4; + break; + case 8: + if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8)) + return -EINVAL; + *flags |= SOCAM_DATAWIDTH_8 | SOCAM_DATAWIDTH_4; + break; + case 4: + if (!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4)) + return -EINVAL; + *flags |= SOCAM_DATAWIDTH_4; + break; + default: + dev_info(mx3_cam->dev, "Unsupported bus width %d\n", buswidth); + return -EINVAL; + } + + return 0; +} + +static int mx3_camera_try_bus_param(struct soc_camera_device *icd, + const unsigned int depth) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct mx3_camera_dev *mx3_cam = ici->priv; + unsigned long bus_flags, camera_flags; + int ret = test_platform_param(mx3_cam, depth, &bus_flags); + + dev_dbg(&ici->dev, "requested bus width %d bit: %d\n", depth, ret); + + if (ret < 0) + return ret; + + camera_flags = icd->ops->query_bus_param(icd); + + ret = soc_camera_bus_param_compatible(camera_flags, bus_flags); + if (ret < 0) + dev_warn(&icd->dev, "Flags incompatible: camera %lx, host %lx\n", + camera_flags, bus_flags); + + return ret; +} + +static bool chan_filter(struct dma_chan *chan, void *arg) +{ + struct dma_chan_request *rq = arg; + struct mx3_camera_pdata *pdata; + + if (!rq) + return false; + + pdata = rq->mx3_cam->dev->platform_data; + + return rq->id == chan->chan_id && + pdata->dma_dev == chan->device->dev; +} + +static const struct soc_camera_data_format mx3_camera_formats[] = { + { + .name = "Bayer (sRGB) 8 bit", + .depth = 8, + .fourcc = V4L2_PIX_FMT_SBGGR8, + .colorspace = V4L2_COLORSPACE_SRGB, + }, { + .name = "Monochrome 8 bit", + .depth = 8, + .fourcc = V4L2_PIX_FMT_GREY, + .colorspace = V4L2_COLORSPACE_JPEG, + }, +}; + +static bool buswidth_supported(struct soc_camera_host *ici, int depth) +{ + struct mx3_camera_dev *mx3_cam = ici->priv; + + switch (depth) { + case 4: + return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_4); + case 8: + return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_8); + case 10: + return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_10); + case 15: + return !!(mx3_cam->platform_flags & MX3_CAMERA_DATAWIDTH_15); + } + return false; +} + +static int mx3_camera_get_formats(struct soc_camera_device *icd, int idx, + struct soc_camera_format_xlate *xlate) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + int formats = 0, buswidth, ret; + + buswidth = icd->formats[idx].depth; + + if (!buswidth_supported(ici, buswidth)) + return 0; + + ret = mx3_camera_try_bus_param(icd, buswidth); + if (ret < 0) + return 0; + + switch (icd->formats[idx].fourcc) { + case V4L2_PIX_FMT_SGRBG10: + formats++; + if (xlate) { + xlate->host_fmt = &mx3_camera_formats[0]; + xlate->cam_fmt = icd->formats + idx; + xlate->buswidth = buswidth; + xlate++; + dev_dbg(&ici->dev, "Providing format %s using %s\n", + mx3_camera_formats[0].name, + icd->formats[idx].name); + } + goto passthrough; + case V4L2_PIX_FMT_Y16: + formats++; + if (xlate) { + xlate->host_fmt = &mx3_camera_formats[1]; + xlate->cam_fmt = icd->formats + idx; + xlate->buswidth = buswidth; + xlate++; + dev_dbg(&ici->dev, "Providing format %s using %s\n", + mx3_camera_formats[0].name, + icd->formats[idx].name); + } + default: +passthrough: + /* Generic pass-through */ + formats++; + if (xlate) { + xlate->host_fmt = icd->formats + idx; + xlate->cam_fmt = icd->formats + idx; + xlate->buswidth = buswidth; + xlate++; + dev_dbg(&ici->dev, + "Providing format %s in pass-through mode\n", + icd->formats[idx].name); + } + } + + return formats; +} + +static int mx3_camera_set_fmt(struct soc_camera_device *icd, + __u32 pixfmt, struct v4l2_rect *rect) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct mx3_camera_dev *mx3_cam = ici->priv; + const struct soc_camera_format_xlate *xlate; + u32 ctrl, width_field, height_field; + int ret; + + xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); + if (pixfmt && !xlate) { + dev_warn(&ici->dev, "Format %x not found\n", pixfmt); + return -EINVAL; + } + + /* + * We now know pixel formats and can decide upon DMA-channel(s) + * So far only direct camera-to-memory is supported + */ + if (channel_change_requested(icd, xlate, pixfmt, rect)) { + dma_cap_mask_t mask; + struct dma_chan *chan; + struct idmac_channel **ichan = &mx3_cam->idmac_channel[0]; + /* We have to use IDMAC_IC_7 for Bayer / generic data */ + struct dma_chan_request rq = {.mx3_cam = mx3_cam, + .id = IDMAC_IC_7}; + + if (*ichan) { + struct videobuf_buffer *vb, *_vb; + dma_release_channel(&(*ichan)->dma_chan); + *ichan = NULL; + mx3_cam->active = NULL; + list_for_each_entry_safe(vb, _vb, &mx3_cam->capture, queue) { + list_del_init(&vb->queue); + vb->state = VIDEOBUF_ERROR; + wake_up(&vb->done); + } + } + + dma_cap_zero(mask); + dma_cap_set(DMA_SLAVE, mask); + dma_cap_set(DMA_PRIVATE, mask); + chan = dma_request_channel(mask, chan_filter, &rq); + if (!chan) + return -EBUSY; + + *ichan = to_idmac_chan(chan); + (*ichan)->client = mx3_cam; + } + + /* + * Might have to perform a complete interface initialisation like in + * ipu_csi_init_interface() in mxc_v4l2_s_param(). Also consider + * mxc_v4l2_s_fmt() + */ + + /* Setup frame size - this cannot be changed on-the-fly... */ + width_field = rect->width - 1; + height_field = rect->height - 1; + csi_reg_write(mx3_cam, width_field | (height_field << 16), CSI_SENS_FRM_SIZE); + + csi_reg_write(mx3_cam, width_field << 16, CSI_FLASH_STROBE_1); + csi_reg_write(mx3_cam, (height_field << 16) | 0x22, CSI_FLASH_STROBE_2); + + csi_reg_write(mx3_cam, width_field | (height_field << 16), CSI_ACT_FRM_SIZE); + + /* ...and position */ + ctrl = csi_reg_read(mx3_cam, CSI_OUT_FRM_CTRL) & 0xffff0000; + /* Sensor does the cropping */ + csi_reg_write(mx3_cam, ctrl | 0 | (0 << 8), CSI_OUT_FRM_CTRL); + + /* + * No need to free resources here if we fail, we'll see if we need to + * do this next time we are called + */ + + ret = icd->ops->set_fmt(icd, pixfmt ? xlate->cam_fmt->fourcc : 0, rect); + if (pixfmt && !ret) { + icd->buswidth = xlate->buswidth; + icd->current_fmt = xlate->host_fmt; + } + + return ret; +} + +static int mx3_camera_try_fmt(struct soc_camera_device *icd, + struct v4l2_format *f) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + const struct soc_camera_format_xlate *xlate; + struct v4l2_pix_format *pix = &f->fmt.pix; + __u32 pixfmt = pix->pixelformat; + enum v4l2_field field; + int ret; + + xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); + if (pixfmt && !xlate) { + dev_warn(&ici->dev, "Format %x not found\n", pixfmt); + return -EINVAL; + } + + /* limit to MX3 hardware capabilities */ + if (pix->height > 4096) + pix->height = 4096; + if (pix->width > 4096) + pix->width = 4096; + + pix->bytesperline = pix->width * + DIV_ROUND_UP(xlate->host_fmt->depth, 8); + pix->sizeimage = pix->height * pix->bytesperline; + + /* camera has to see its format, but the user the original one */ + pix->pixelformat = xlate->cam_fmt->fourcc; + /* limit to sensor capabilities */ + ret = icd->ops->try_fmt(icd, f); + pix->pixelformat = xlate->host_fmt->fourcc; + + field = pix->field; + + if (field == V4L2_FIELD_ANY) { + pix->field = V4L2_FIELD_NONE; + } else if (field != V4L2_FIELD_NONE) { + dev_err(&icd->dev, "Field type %d unsupported.\n", field); + return -EINVAL; + } + + return ret; +} + +static int mx3_camera_reqbufs(struct soc_camera_file *icf, + struct v4l2_requestbuffers *p) +{ + return 0; +} + +static unsigned int mx3_camera_poll(struct file *file, poll_table *pt) +{ + struct soc_camera_file *icf = file->private_data; + + return videobuf_poll_stream(file, &icf->vb_vidq, pt); +} + +static int mx3_camera_querycap(struct soc_camera_host *ici, + struct v4l2_capability *cap) +{ + /* cap->name is set by the firendly caller:-> */ + strlcpy(cap->card, "i.MX3x Camera", sizeof(cap->card)); + cap->version = KERNEL_VERSION(0, 2, 2); + cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_STREAMING; + + return 0; +} + +static int mx3_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt) +{ + struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent); + struct mx3_camera_dev *mx3_cam = ici->priv; + unsigned long bus_flags, camera_flags, common_flags; + u32 dw, sens_conf; + int ret = test_platform_param(mx3_cam, icd->buswidth, &bus_flags); + const struct soc_camera_format_xlate *xlate; + + xlate = soc_camera_xlate_by_fourcc(icd, pixfmt); + if (!xlate) { + dev_warn(&ici->dev, "Format %x not found\n", pixfmt); + return -EINVAL; + } + + dev_dbg(&ici->dev, "requested bus width %d bit: %d\n", + icd->buswidth, ret); + + if (ret < 0) + return ret; + + camera_flags = icd->ops->query_bus_param(icd); + + common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags); + if (!common_flags) { + dev_dbg(&ici->dev, "no common flags: camera %lx, host %lx\n", + camera_flags, bus_flags); + return -EINVAL; + } + + /* Make choices, based on platform preferences */ + if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) && + (common_flags & SOCAM_HSYNC_ACTIVE_LOW)) { + if (mx3_cam->platform_flags & MX3_CAMERA_HSP) + common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH; + else + common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW; + } + + if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) && + (common_flags & SOCAM_VSYNC_ACTIVE_LOW)) { + if (mx3_cam->platform_flags & MX3_CAMERA_VSP) + common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH; + else + common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW; + } + + if ((common_flags & SOCAM_DATA_ACTIVE_HIGH) && + (common_flags & SOCAM_DATA_ACTIVE_LOW)) { + if (mx3_cam->platform_flags & MX3_CAMERA_DP) + common_flags &= ~SOCAM_DATA_ACTIVE_HIGH; + else + common_flags &= ~SOCAM_DATA_ACTIVE_LOW; + } + + if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) && + (common_flags & SOCAM_PCLK_SAMPLE_FALLING)) { + if (mx3_cam->platform_flags & MX3_CAMERA_PCP) + common_flags &= ~SOCAM_PCLK_SAMPLE_RISING; + else + common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING; + } + + /* Make the camera work in widest common mode, we'll take care of + * the rest */ + if (common_flags & SOCAM_DATAWIDTH_15) + common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) | + SOCAM_DATAWIDTH_15; + else if (common_flags & SOCAM_DATAWIDTH_10) + common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) | + SOCAM_DATAWIDTH_10; + else if (common_flags & SOCAM_DATAWIDTH_8) + common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) | + SOCAM_DATAWIDTH_8; + else + common_flags = (common_flags & ~SOCAM_DATAWIDTH_MASK) | + SOCAM_DATAWIDTH_4; + + ret = icd->ops->set_bus_param(icd, common_flags); + if (ret < 0) + return ret; + + /* + * So far only gated clock mode is supported. Add a line + * (3 << CSI_SENS_CONF_SENS_PRTCL_SHIFT) | + * below and select the required mode when supporting other + * synchronisation protocols. + */ + sens_conf = csi_reg_read(mx3_cam, CSI_SENS_CONF) & + ~((1 << CSI_SENS_CONF_VSYNC_POL_SHIFT) | + (1 << CSI_SENS_CONF_HSYNC_POL_SHIFT) | + (1 << CSI_SENS_CONF_DATA_POL_SHIFT) | + (1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT) | + (3 << CSI_SENS_CONF_DATA_FMT_SHIFT) | + (3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT)); + + /* TODO: Support RGB and YUV formats */ + + /* This has been set in mx3_camera_activate(), but we clear it above */ + sens_conf |= CSI_SENS_CONF_DATA_FMT_BAYER; + + if (common_flags & SOCAM_PCLK_SAMPLE_FALLING) + sens_conf |= 1 << CSI_SENS_CONF_PIX_CLK_POL_SHIFT; + if (common_flags & SOCAM_HSYNC_ACTIVE_LOW) + sens_conf |= 1 << CSI_SENS_CONF_HSYNC_POL_SHIFT; + if (common_flags & SOCAM_VSYNC_ACTIVE_LOW) + sens_conf |= 1 << CSI_SENS_CONF_VSYNC_POL_SHIFT; + if (common_flags & SOCAM_DATA_ACTIVE_LOW) + sens_conf |= 1 << CSI_SENS_CONF_DATA_POL_SHIFT; + + /* Just do what we're asked to do */ + switch (xlate->host_fmt->depth) { + case 4: + dw = 0 << CSI_SENS_CONF_DATA_WIDTH_SHIFT; + break; + case 8: + dw = 1 << CSI_SENS_CONF_DATA_WIDTH_SHIFT; + break; + case 10: + dw = 2 << CSI_SENS_CONF_DATA_WIDTH_SHIFT; + break; + default: + /* + * Actually it can only be 15 now, default is just to silence + * compiler warnings + */ + case 15: + dw = 3 << CSI_SENS_CONF_DATA_WIDTH_SHIFT; + } + + csi_reg_write(mx3_cam, sens_conf | dw, CSI_SENS_CONF); + + dev_dbg(&ici->dev, "Set SENS_CONF to %x\n", sens_conf | dw); + + return 0; +} + +static struct soc_camera_host_ops mx3_soc_camera_host_ops = { + .owner = THIS_MODULE, + .add = mx3_camera_add_device, + .remove = mx3_camera_remove_device, +#ifdef CONFIG_PM + .suspend = mx3_camera_suspend, + .resume = mx3_camera_resume, +#endif + .set_fmt = mx3_camera_set_fmt, + .try_fmt = mx3_camera_try_fmt, + .get_formats = mx3_camera_get_formats, + .init_videobuf = mx3_camera_init_videobuf, + .reqbufs = mx3_camera_reqbufs, + .poll = mx3_camera_poll, + .querycap = mx3_camera_querycap, + .set_bus_param = mx3_camera_set_bus_param, +}; + +static int mx3_camera_probe(struct platform_device *pdev) +{ + struct mx3_camera_dev *mx3_cam; + struct resource *res; + void __iomem *base; + int err = 0; + struct soc_camera_host *soc_host; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + err = -ENODEV; + goto egetres; + } + + mx3_cam = vmalloc(sizeof(*mx3_cam)); + if (!mx3_cam) { + dev_err(&pdev->dev, "Could not allocate mx3 camera object\n"); + err = -ENOMEM; + goto ealloc; + } + memset(mx3_cam, 0, sizeof(*mx3_cam)); + + mx3_cam->clk = clk_get(&pdev->dev, "csi_clk"); + if (IS_ERR(mx3_cam->clk)) { + err = PTR_ERR(mx3_cam->clk); + goto eclkget; + } + + dev_set_drvdata(&pdev->dev, mx3_cam); + + mx3_cam->pdata = pdev->dev.platform_data; + mx3_cam->platform_flags = mx3_cam->pdata->flags; + if (!(mx3_cam->platform_flags & (MX3_CAMERA_DATAWIDTH_4 | + MX3_CAMERA_DATAWIDTH_8 | MX3_CAMERA_DATAWIDTH_10 | + MX3_CAMERA_DATAWIDTH_15))) { + /* Platform hasn't set available data widths. This is bad. + * Warn and use a default. */ + dev_warn(&pdev->dev, "WARNING! Platform hasn't set available " + "data widths, using default 8 bit\n"); + mx3_cam->platform_flags |= MX3_CAMERA_DATAWIDTH_8; + } + + mx3_cam->mclk = mx3_cam->pdata->mclk_10khz * 10000; + if (!mx3_cam->mclk) { + dev_warn(&pdev->dev, + "mclk_10khz == 0! Please, fix your platform data. " + "Using default 20MHz\n"); + mx3_cam->mclk = 20000000; + } + + /* list of video-buffers */ + INIT_LIST_HEAD(&mx3_cam->capture); + spin_lock_init(&mx3_cam->lock); + + base = ioremap(res->start, res->end - res->start + 1); + if (!base) { + err = -ENOMEM; + goto eioremap; + } + + mx3_cam->base = base; + mx3_cam->dev = &pdev->dev; + + soc_host = &mx3_cam->soc_host; + soc_host->drv_name = MX3_CAM_DRV_NAME; + soc_host->ops = &mx3_soc_camera_host_ops; + soc_host->priv = mx3_cam; + soc_host->dev.parent = &pdev->dev; + soc_host->nr = pdev->id; + err = soc_camera_host_register(soc_host); + if (err) + goto ecamhostreg; + + /* IDMAC interface */ + dmaengine_get(); + + return 0; + +ecamhostreg: + iounmap(base); +eioremap: + clk_put(mx3_cam->clk); +eclkget: + vfree(mx3_cam); +ealloc: +egetres: + return err; +} + +static int __devexit mx3_camera_remove(struct platform_device *pdev) +{ + struct mx3_camera_dev *mx3_cam = platform_get_drvdata(pdev); + + clk_put(mx3_cam->clk); + + soc_camera_host_unregister(&mx3_cam->soc_host); + + iounmap(mx3_cam->base); + + /* + * The channel has either not been allocated, + * or should have been released + */ + if (WARN_ON(mx3_cam->idmac_channel[0])) + dma_release_channel(&mx3_cam->idmac_channel[0]->dma_chan); + + vfree(mx3_cam); + + dmaengine_put(); + + dev_info(&pdev->dev, "i.MX3x Camera driver unloaded\n"); + + return 0; +} + +static struct platform_driver mx3_camera_driver = { + .driver = { + .name = MX3_CAM_DRV_NAME, + }, + .probe = mx3_camera_probe, + .remove = __exit_p(mx3_camera_remove), +}; + + +static int __devinit mx3_camera_init(void) +{ + return platform_driver_register(&mx3_camera_driver); +} + +static void __exit mx3_camera_exit(void) +{ + platform_driver_unregister(&mx3_camera_driver); +} + +module_init(mx3_camera_init); +module_exit(mx3_camera_exit); + +MODULE_DESCRIPTION("i.MX3x SoC Camera Host driver"); +MODULE_AUTHOR("Guennadi Liakhovetski "); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3