From 0412d6c9271811b84568fcea3237e2193e21866a Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 25 Mar 2009 19:46:48 +0100 Subject: [PATCH 1/6] i.MX1: remove fb support from mach-imx The lack of an include file currently breaks compilation of mx1ads_defconfig. As framebuffer support is not actively used for mach-imx and the whole architecture will be replaced by mach-mx1 soon, just remove fb support. Signed-off-by: Sascha Hauer --- arch/arm/mach-imx/generic.c | 36 ------------------------------------ 1 file changed, 36 deletions(-) diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c index 887cb21f75b0..05f1739ee127 100644 --- a/arch/arm/mach-imx/generic.c +++ b/arch/arm/mach-imx/generic.c @@ -29,7 +29,6 @@ #include #include -#include #include #include @@ -245,43 +244,8 @@ void __init imx_set_mmc_info(struct imxmmc_platform_data *info) imx_mmc_device.dev.platform_data = info; } -static struct imx_fb_platform_data imx_fb_info; - -void __init set_imx_fb_info(struct imx_fb_platform_data *hard_imx_fb_info) -{ - memcpy(&imx_fb_info,hard_imx_fb_info,sizeof(struct imx_fb_platform_data)); -} - -static struct resource imxfb_resources[] = { - [0] = { - .start = 0x00205000, - .end = 0x002050FF, - .flags = IORESOURCE_MEM, - }, - [1] = { - .start = LCDC_INT, - .end = LCDC_INT, - .flags = IORESOURCE_IRQ, - }, -}; - -static u64 fb_dma_mask = ~(u64)0; - -static struct platform_device imxfb_device = { - .name = "imx-fb", - .id = 0, - .dev = { - .platform_data = &imx_fb_info, - .dma_mask = &fb_dma_mask, - .coherent_dma_mask = 0xffffffff, - }, - .num_resources = ARRAY_SIZE(imxfb_resources), - .resource = imxfb_resources, -}; - static struct platform_device *devices[] __initdata = { &imx_mmc_device, - &imxfb_device, }; static struct map_desc imx_io_desc[] __initdata = { From 05fd8e73e1357feaea9c48938d937eae76b4aef4 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Sat, 7 Mar 2009 12:55:49 +0100 Subject: [PATCH 2/6] clkdev: add possibility to get a clock based on the device name This adds clk_get_sys to get a clock without the associated struct device. Signed-off-by: Sascha Hauer --- arch/arm/common/clkdev.c | 11 +++++++++-- include/linux/clk.h | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/arch/arm/common/clkdev.c b/arch/arm/common/clkdev.c index 1037bba18329..5589444ff437 100644 --- a/arch/arm/common/clkdev.c +++ b/arch/arm/common/clkdev.c @@ -62,9 +62,8 @@ static struct clk *clk_find(const char *dev_id, const char *con_id) return clk; } -struct clk *clk_get(struct device *dev, const char *con_id) +struct clk *clk_get_sys(const char *dev_id, const char *con_id) { - const char *dev_id = dev ? dev_name(dev) : NULL; struct clk *clk; mutex_lock(&clocks_mutex); @@ -75,6 +74,14 @@ struct clk *clk_get(struct device *dev, const char *con_id) return clk ? clk : ERR_PTR(-ENOENT); } +EXPORT_SYMBOL(clk_get_sys); + +struct clk *clk_get(struct device *dev, const char *con_id) +{ + const char *dev_id = dev ? dev_name(dev) : NULL; + + return clk_get_sys(dev_id, con_id); +} EXPORT_SYMBOL(clk_get); void clk_put(struct clk *clk) diff --git a/include/linux/clk.h b/include/linux/clk.h index 778777316ea4..1db9bbf444a3 100644 --- a/include/linux/clk.h +++ b/include/linux/clk.h @@ -125,4 +125,21 @@ int clk_set_parent(struct clk *clk, struct clk *parent); */ struct clk *clk_get_parent(struct clk *clk); +/** + * clk_get_sys - get a clock based upon the device name + * @dev_id: device name + * @con_id: connection ID + * + * Returns a struct clk corresponding to the clock producer, or + * valid IS_ERR() condition containing errno. The implementation + * uses @dev_id and @con_id to determine the clock consumer, and + * thereby the clock producer. In contrast to clk_get() this function + * takes the device name instead of the device itself for identification. + * + * Drivers must assume that the clock source is not enabled. + * + * clk_get_sys should not be called from within interrupt context. + */ +struct clk *clk_get_sys(const char *dev_id, const char *con_id); + #endif From 74bef9a4fa978669b234c4454daa596c0494c09a Mon Sep 17 00:00:00 2001 From: Ilya Yanok Date: Tue, 3 Mar 2009 02:49:23 +0300 Subject: [PATCH 3/6] 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/plat-mxc/Makefile | 2 +- arch/arm/plat-mxc/include/mach/system.h | 5 +-- arch/arm/{mach-mx2 => plat-mxc}/system.c | 50 +++++++++++++----------- 4 files changed, 30 insertions(+), 29 deletions(-) rename arch/arm/{mach-mx2 => plat-mxc}/system.c (62%) 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/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/mach-mx2/system.c b/arch/arm/plat-mxc/system.c similarity index 62% rename from arch/arm/mach-mx2/system.c rename to arch/arm/plat-mxc/system.c index 92c79d4bd162..79c37577c916 100644 --- a/arch/arm/mach-mx2/system.c +++ b/arch/arm/plat-mxc/system.c @@ -3,6 +3,7 @@ * 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 @@ -22,42 +23,45 @@ #include #include #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) +#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) { - struct clk *clk; + if (!cpu_is_mx1()) { + struct clk *clk; - clk = clk_get(NULL, "wdog_clk"); - if (!clk) { - printk(KERN_ERR"Cannot activate the watchdog. Giving up\n"); - return; + clk = clk_get_sys("imx-wdt.0", NULL); + if (!IS_ERR(clk)) + clk_enable(clk); } - clk_enable(clk); - /* Assert SRS signal */ - __raw_writew(__raw_readw(WDOG_WCR_REG) & ~WDOG_WCR_SRS, WDOG_WCR_REG); + __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); } From f909ef6437a8388e3f1272c67ee29071f930bd6b Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 15 Jan 2009 15:21:00 +0100 Subject: [PATCH 4/6] imxfb: add clock support v2: Added change from Martin Fuzzey: pixclock should be in pico seconds instead of MHz. Signed-off-by: Sascha Hauer --- drivers/video/imxfb.c | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index bd1cb75cd14b..8f7a2b2c78e7 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -26,9 +26,11 @@ #include #include #include +#include #include #include #include +#include #include @@ -141,6 +143,7 @@ struct imxfb_rgb { struct imxfb_info { struct platform_device *pdev; void __iomem *regs; + struct clk *clk; u_int max_bpp; u_int max_xres; @@ -403,6 +406,8 @@ static void imxfb_enable_controller(struct imxfb_info *fbi) writel(RMCR_LCDC_EN, fbi->regs + LCDC_RMCR); + clk_enable(fbi->clk); + if (fbi->backlight_power) fbi->backlight_power(1); if (fbi->lcd_power) @@ -418,6 +423,8 @@ static void imxfb_disable_controller(struct imxfb_info *fbi) if (fbi->lcd_power) fbi->lcd_power(0); + clk_disable(fbi->clk); + writel(0, fbi->regs + LCDC_RMCR); } @@ -461,6 +468,9 @@ static struct fb_ops imxfb_ops = { static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info) { struct imxfb_info *fbi = info->par; + unsigned int pcr, lcd_clk; + unsigned long long tmp; + pr_debug("var: xres=%d hslen=%d lm=%d rm=%d\n", var->xres, var->hsync_len, var->left_margin, var->right_margin); @@ -507,7 +517,23 @@ static int imxfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *inf writel(SIZE_XMAX(var->xres) | SIZE_YMAX(var->yres), fbi->regs + LCDC_SIZE); - writel(fbi->pcr, fbi->regs + LCDC_PCR); + + lcd_clk = clk_get_rate(fbi->clk); + tmp = var->pixclock * (unsigned long long)lcd_clk; + do_div(tmp, 1000000); + if (do_div(tmp, 1000000) > 500000) + tmp++; + pcr = (unsigned int)tmp; + if (--pcr > 0x3F) { + pcr = 0x3F; + printk(KERN_WARNING "Must limit pixel clock to %uHz\n", + lcd_clk / pcr); + } + + /* add sync polarities */ + pcr |= fbi->pcr & ~0x3F; + + writel(pcr, fbi->regs + LCDC_PCR); writel(fbi->pwmr, fbi->regs + LCDC_PWMR); writel(fbi->lscr1, fbi->regs + LCDC_LSCR1); writel(fbi->dmacr, fbi->regs + LCDC_DMACR); @@ -649,6 +675,13 @@ static int __init imxfb_probe(struct platform_device *pdev) goto failed_req; } + fbi->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(fbi->clk)) { + ret = PTR_ERR(fbi->clk);; + dev_err(&pdev->dev, "unable to get clock: %d\n", ret); + goto failed_getclock; + } + fbi->regs = ioremap(res->start, resource_size(res)); if (fbi->regs == NULL) { printk(KERN_ERR"Cannot map frame buffer registers\n"); @@ -717,6 +750,8 @@ failed_platform_init: dma_free_writecombine(&pdev->dev,fbi->map_size,fbi->map_cpu, fbi->map_dma); failed_map: + clk_put(fbi->clk); +failed_getclock: iounmap(fbi->regs); failed_ioremap: release_mem_region(res->start, res->end - res->start); @@ -751,6 +786,9 @@ static int __devexit imxfb_remove(struct platform_device *pdev) iounmap(fbi->regs); release_mem_region(res->start, res->end - res->start + 1); + clk_disable(fbi->clk); + clk_put(fbi->clk); + platform_set_drvdata(pdev, NULL); return 0; From ec621699031b298eadd7e364f65281291b19ea37 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 26 Mar 2009 12:23:23 +0100 Subject: [PATCH 5/6] i.MX21/27: remove ifdef CONFIG_FB_IMX Compile in the framebuffer device unconditionally to fix pcm038 compilation without framebuffer support. Signed-off-by: Sascha Hauer --- arch/arm/mach-mx2/devices.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/mach-mx2/devices.c b/arch/arm/mach-mx2/devices.c index f81aa8a8fbb4..a0f1b3674327 100644 --- a/arch/arm/mach-mx2/devices.c +++ b/arch/arm/mach-mx2/devices.c @@ -229,7 +229,6 @@ struct platform_device mxc_nand_device = { .resource = mxc_nand_resources, }; -#ifdef CONFIG_FB_IMX /* * lcdc: * - i.MX1: the basic controller @@ -259,7 +258,6 @@ struct platform_device mxc_fb_device = { .coherent_dma_mask = 0xFFFFFFFF, }, }; -#endif #ifdef CONFIG_MACH_MX27 static struct resource mxc_fec_resources[] = { From 4d1e4e5a6387aad97590e2da9c6db1350f22f63a Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 26 Mar 2009 12:38:26 +0100 Subject: [PATCH 6/6] imxfb: Fix TFT mode We read from the PCR reg to determine whether to use TFT mode or not. This is not possible because it may not have been initialized with the correct value yet. Select it using fbi->pcr instead. Signed-off-by: Sascha Hauer --- drivers/video/imxfb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c index 8f7a2b2c78e7..15a0ee6d8e23 100644 --- a/drivers/video/imxfb.c +++ b/drivers/video/imxfb.c @@ -327,7 +327,7 @@ static int imxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) break; case 16: default: - if (readl(fbi->regs + LCDC_PCR) & PCR_TFT) + if (fbi->pcr & PCR_TFT) rgb = &def_rgb_16_tft; else rgb = &def_rgb_16_stn;