linux/arch/arm/mach-lpc32xx/phy3250.c
<<
>>
Prefs
   1/*
   2 * Platform support for LPC32xx SoC
   3 *
   4 * Author: Kevin Wells <kevin.wells@nxp.com>
   5 *
   6 * Copyright (C) 2012 Roland Stigge <stigge@antcom.de>
   7 * Copyright (C) 2010 NXP Semiconductors
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License as published by
  11 * the Free Software Foundation; either version 2 of the License, or
  12 * (at your option) any later version.
  13 *
  14 * This program is distributed in the hope that it will be useful,
  15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17 * GNU General Public License for more details.
  18 */
  19
  20#include <linux/init.h>
  21#include <linux/platform_device.h>
  22#include <linux/device.h>
  23#include <linux/interrupt.h>
  24#include <linux/irq.h>
  25#include <linux/dma-mapping.h>
  26#include <linux/gpio.h>
  27#include <linux/amba/bus.h>
  28#include <linux/amba/clcd.h>
  29#include <linux/amba/pl08x.h>
  30#include <linux/amba/mmci.h>
  31#include <linux/of.h>
  32#include <linux/of_address.h>
  33#include <linux/of_irq.h>
  34#include <linux/of_platform.h>
  35#include <linux/clk.h>
  36#include <linux/mtd/lpc32xx_slc.h>
  37#include <linux/mtd/lpc32xx_mlc.h>
  38
  39#include <asm/setup.h>
  40#include <asm/mach-types.h>
  41#include <asm/mach/arch.h>
  42
  43#include <mach/hardware.h>
  44#include <mach/platform.h>
  45#include <mach/board.h>
  46#include "common.h"
  47
  48/*
  49 * AMBA LCD controller
  50 */
  51static struct clcd_panel conn_lcd_panel = {
  52        .mode           = {
  53                .name           = "QVGA portrait",
  54                .refresh        = 60,
  55                .xres           = 240,
  56                .yres           = 320,
  57                .pixclock       = 191828,
  58                .left_margin    = 22,
  59                .right_margin   = 11,
  60                .upper_margin   = 2,
  61                .lower_margin   = 1,
  62                .hsync_len      = 5,
  63                .vsync_len      = 2,
  64                .sync           = 0,
  65                .vmode          = FB_VMODE_NONINTERLACED,
  66        },
  67        .width          = -1,
  68        .height         = -1,
  69        .tim2           = (TIM2_IVS | TIM2_IHS),
  70        .cntl           = (CNTL_BGR | CNTL_LCDTFT | CNTL_LCDVCOMP(1) |
  71                                CNTL_LCDBPP16_565),
  72        .bpp            = 16,
  73};
  74#define PANEL_SIZE (3 * SZ_64K)
  75
  76static int lpc32xx_clcd_setup(struct clcd_fb *fb)
  77{
  78        dma_addr_t dma;
  79
  80        fb->fb.screen_base = dma_alloc_wc(&fb->dev->dev, PANEL_SIZE, &dma,
  81                                          GFP_KERNEL);
  82        if (!fb->fb.screen_base) {
  83                printk(KERN_ERR "CLCD: unable to map framebuffer\n");
  84                return -ENOMEM;
  85        }
  86
  87        fb->fb.fix.smem_start = dma;
  88        fb->fb.fix.smem_len = PANEL_SIZE;
  89        fb->panel = &conn_lcd_panel;
  90
  91        return 0;
  92}
  93
  94static int lpc32xx_clcd_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
  95{
  96        return dma_mmap_wc(&fb->dev->dev, vma, fb->fb.screen_base,
  97                           fb->fb.fix.smem_start, fb->fb.fix.smem_len);
  98}
  99
 100static void lpc32xx_clcd_remove(struct clcd_fb *fb)
 101{
 102        dma_free_wc(&fb->dev->dev, fb->fb.fix.smem_len, fb->fb.screen_base,
 103                    fb->fb.fix.smem_start);
 104}
 105
 106static struct clcd_board lpc32xx_clcd_data = {
 107        .name           = "Phytec LCD",
 108        .check          = clcdfb_check,
 109        .decode         = clcdfb_decode,
 110        .setup          = lpc32xx_clcd_setup,
 111        .mmap           = lpc32xx_clcd_mmap,
 112        .remove         = lpc32xx_clcd_remove,
 113};
 114
 115static struct pl08x_channel_data pl08x_slave_channels[] = {
 116        {
 117                .bus_id = "nand-slc",
 118                .min_signal = 1, /* SLC NAND Flash */
 119                .max_signal = 1,
 120                .periph_buses = PL08X_AHB1,
 121        },
 122        {
 123                .bus_id = "nand-mlc",
 124                .min_signal = 12, /* MLC NAND Flash */
 125                .max_signal = 12,
 126                .periph_buses = PL08X_AHB1,
 127        },
 128};
 129
 130static int pl08x_get_signal(const struct pl08x_channel_data *cd)
 131{
 132        return cd->min_signal;
 133}
 134
 135static void pl08x_put_signal(const struct pl08x_channel_data *cd, int ch)
 136{
 137}
 138
 139static struct pl08x_platform_data pl08x_pd = {
 140        /* Some reasonable memcpy defaults */
 141        .memcpy_burst_size = PL08X_BURST_SZ_256,
 142        .memcpy_bus_width = PL08X_BUS_WIDTH_32_BITS,
 143        .slave_channels = &pl08x_slave_channels[0],
 144        .num_slave_channels = ARRAY_SIZE(pl08x_slave_channels),
 145        .get_xfer_signal = pl08x_get_signal,
 146        .put_xfer_signal = pl08x_put_signal,
 147        .lli_buses = PL08X_AHB1,
 148        .mem_buses = PL08X_AHB1,
 149};
 150
 151static struct mmci_platform_data lpc32xx_mmci_data = {
 152        .ocr_mask       = MMC_VDD_30_31 | MMC_VDD_31_32 |
 153                          MMC_VDD_32_33 | MMC_VDD_33_34,
 154};
 155
 156static struct lpc32xx_slc_platform_data lpc32xx_slc_data = {
 157        .dma_filter = pl08x_filter_id,
 158};
 159
 160static struct lpc32xx_mlc_platform_data lpc32xx_mlc_data = {
 161        .dma_filter = pl08x_filter_id,
 162};
 163
 164static const struct of_dev_auxdata lpc32xx_auxdata_lookup[] __initconst = {
 165        OF_DEV_AUXDATA("arm,pl022", 0x20084000, "dev:ssp0", NULL),
 166        OF_DEV_AUXDATA("arm,pl022", 0x2008C000, "dev:ssp1", NULL),
 167        OF_DEV_AUXDATA("arm,pl110", 0x31040000, "dev:clcd", &lpc32xx_clcd_data),
 168        OF_DEV_AUXDATA("arm,pl080", 0x31000000, "pl08xdmac", &pl08x_pd),
 169        OF_DEV_AUXDATA("arm,pl18x", 0x20098000, "20098000.sd",
 170                       &lpc32xx_mmci_data),
 171        OF_DEV_AUXDATA("nxp,lpc3220-slc", 0x20020000, "20020000.flash",
 172                       &lpc32xx_slc_data),
 173        OF_DEV_AUXDATA("nxp,lpc3220-mlc", 0x200a8000, "200a8000.flash",
 174                       &lpc32xx_mlc_data),
 175        { }
 176};
 177
 178static void __init lpc3250_machine_init(void)
 179{
 180        u32 tmp;
 181
 182        /* Setup LCD muxing to RGB565 */
 183        tmp = __raw_readl(LPC32XX_CLKPWR_LCDCLK_CTRL) &
 184                ~(LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_MSK |
 185                LPC32XX_CLKPWR_LCDCTRL_PSCALE_MSK);
 186        tmp |= LPC32XX_CLKPWR_LCDCTRL_LCDTYPE_TFT16;
 187        __raw_writel(tmp, LPC32XX_CLKPWR_LCDCLK_CTRL);
 188
 189        lpc32xx_serial_init();
 190
 191        /* Test clock needed for UDA1380 initial init */
 192        __raw_writel(LPC32XX_CLKPWR_TESTCLK2_SEL_MOSC |
 193                LPC32XX_CLKPWR_TESTCLK_TESTCLK2_EN,
 194                LPC32XX_CLKPWR_TEST_CLK_SEL);
 195
 196        of_platform_default_populate(NULL, lpc32xx_auxdata_lookup, NULL);
 197}
 198
 199static const char *const lpc32xx_dt_compat[] __initconst = {
 200        "nxp,lpc3220",
 201        "nxp,lpc3230",
 202        "nxp,lpc3240",
 203        "nxp,lpc3250",
 204        NULL
 205};
 206
 207DT_MACHINE_START(LPC32XX_DT, "LPC32XX SoC (Flattened Device Tree)")
 208        .atag_offset    = 0x100,
 209        .map_io         = lpc32xx_map_io,
 210        .init_machine   = lpc3250_machine_init,
 211        .dt_compat      = lpc32xx_dt_compat,
 212MACHINE_END
 213