diff options
Diffstat (limited to 'arch/arm/mach-mxs/imx_lcd_clk.c')
-rw-r--r-- | arch/arm/mach-mxs/imx_lcd_clk.c | 150 |
1 files changed, 0 insertions, 150 deletions
diff --git a/arch/arm/mach-mxs/imx_lcd_clk.c b/arch/arm/mach-mxs/imx_lcd_clk.c deleted file mode 100644 index 455dfcb9c7..0000000000 --- a/arch/arm/mach-mxs/imx_lcd_clk.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * (C) Copyright 2010 Juergen Beisert - Pengutronix <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. - */ - -#include <common.h> -#include <init.h> -#include <mach/imx-regs.h> -#include <mach/clock.h> -#include <io.h> - -#ifdef CONFIG_ARCH_IMX23 - -# define HW_CLKCTRL_DIS_LCDIF 0x060 -# define CLKCTRL_DIS_LCDIF_GATE (1 << 31) -# define CLKCTRL_DIS_LCDIF_BUSY (1 << 29) -# define MASK_DIS_LCDIF_DIV 0xfff -# define SET_DIS_LCDIF_DIV(x) ((x) & MASK_DIS_LCDIF_DIV) -# define GET_DIS_LCDIF_DIV(x) ((x) & MASK_DIS_LCDIF_DIV) - -# define HW_CLKCTRL_FRAC 0xf0 -# define MASK_PIXFRAC 0x3f -# define GET_PIXFRAC(x) (((x) >> 16) & MASK_PIXFRAC) -# define SET_PIXFRAC(x) (((x) & MASK_PIXFRAC) << 16) -# define CLKCTRL_FRAC_CLKGATEPIX (1 << 23) - -# define HW_CLKCTRL_CLKSEQ 0x110 -# define CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF (1 << 1) - -#endif - -#ifdef CONFIG_ARCH_IMX28 - -# define HW_CLKCTRL_DIS_LCDIF 0x120 -# define CLKCTRL_DIS_LCDIF_GATE (1 << 31) -# define CLKCTRL_DIS_LCDIF_BUSY (1 << 29) -# define MASK_DIS_LCDIF_DIV 0x1fff -# define SET_DIS_LCDIF_DIV(x) ((x) & MASK_DIS_LCDIF_DIV) -# define GET_DIS_LCDIF_DIV(x) ((x) & MASK_DIS_LCDIF_DIV) - -/* note: On i.MX28 this is called 'FRAC1' */ -# define HW_CLKCTRL_FRAC 0x1c0 -# define MASK_PIXFRAC 0x3f -# define GET_PIXFRAC(x) ((x) & MASK_PIXFRAC) -# define SET_PIXFRAC(x) ((x) & MASK_PIXFRAC) -# define CLKCTRL_FRAC_CLKGATEPIX (1 << 7) - -# define HW_CLKCTRL_CLKSEQ 0x1d0 -# define CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF (1 << 14) - -#endif - -unsigned imx_get_lcdifclk(void) -{ - unsigned rate = (imx_get_mpllclk() / 1000) * 18U; - unsigned div; - - div = GET_PIXFRAC(readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC)); - if (div != 0U) { - rate /= div; - div = GET_DIS_LCDIF_DIV(readl(IMX_CCM_BASE + - HW_CLKCTRL_DIS_LCDIF)); - if (div != 0U) - rate /= div; - else - pr_debug("LCDIF clock has divisor 0!\n"); - } else - pr_debug("LCDIF clock has frac divisor 0!\n"); - - return rate * 1000; -} - -/* - * The source of the pixel clock can be the external 24 MHz crystal or the - * internal PLL running at 480 MHz. In order to support at least VGA sized - * displays/resolutions this routine forces the PLL as the clock source. - */ -unsigned imx_set_lcdifclk(unsigned nc) -{ - unsigned frac, best_frac = 0, div, best_div = 0, result; - int delta, best_delta = 0xffffff; - unsigned i, parent_rate = imx_get_mpllclk() / 1000; - uint32_t reg; - -#define SH_DIV(NOM, DEN, LSH) ((((NOM) / (DEN)) << (LSH)) + \ - DIV_ROUND_CLOSEST(((NOM) % (DEN)) << (LSH), DEN)) -#define SHIFT 4 - - nc /= 1000; - nc <<= SHIFT; - - for (frac = 18; frac <= 35; ++frac) { - for (div = 1; div <= 255; ++div) { - result = DIV_ROUND_CLOSEST(parent_rate * - SH_DIV(18U, frac, SHIFT), div); - delta = nc - result; - if (abs(delta) < abs(best_delta)) { - best_delta = delta; - best_frac = frac; - best_div = div; - } - } - } - - if (best_delta == 0xffffff) { - pr_debug("Unable to match the pixelclock\n"); - return 0; - } - - pr_debug("Programming PFD=%u,DIV=%u ref_pix=%u MHz PIXCLK=%u kHz\n", - best_frac, best_div, 480 * 18 / best_frac, - 480000 * 18 / best_frac / best_div); - - reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC); - reg &= ~SET_PIXFRAC(MASK_PIXFRAC); - reg |= SET_PIXFRAC(best_frac); - writel(reg, IMX_CCM_BASE + HW_CLKCTRL_FRAC); - writel(reg & ~CLKCTRL_FRAC_CLKGATEPIX, IMX_CCM_BASE + HW_CLKCTRL_FRAC); - - reg = readl(IMX_CCM_BASE + HW_CLKCTRL_DIS_LCDIF) & ~MASK_DIS_LCDIF_DIV; - reg &= ~CLKCTRL_DIS_LCDIF_GATE; - reg |= SET_DIS_LCDIF_DIV(best_div); - writel(reg, IMX_CCM_BASE + HW_CLKCTRL_DIS_LCDIF); - - /* Wait for divider update */ - for (i = 0; i < 10000; i++) { - if (!(readl(IMX_CCM_BASE + HW_CLKCTRL_DIS_LCDIF) & - CLKCTRL_DIS_LCDIF_BUSY)) - break; - } - - if (i >= 10000) { - pr_debug("Setting LCD clock failed\n"); - return 0; - } - - writel(CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF, - IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + BIT_CLR); - - return imx_get_lcdifclk(); -} |