uboot/arch/arm/cpu/arm1176/tnetv107x/aemif.c
<<
>>
Prefs
   1/*
   2 * TNETV107X: Asynchronous EMIF Configuration
   3 *
   4 * See file CREDITS for list of people who contributed to this
   5 * project.
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation; either version 2 of the License, or
  10 * (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20 */
  21
  22#include <common.h>
  23#include <asm/io.h>
  24#include <asm/arch/clock.h>
  25#include <asm/arch/mux.h>
  26
  27#define ASYNC_EMIF_BASE                 TNETV107X_ASYNC_EMIF_CNTRL_BASE
  28#define ASYNC_EMIF_CONFIG(cs)           (ASYNC_EMIF_BASE+0x10+(cs)*4)
  29#define ASYNC_EMIF_ONENAND_CONTROL      (ASYNC_EMIF_BASE+0x5c)
  30#define ASYNC_EMIF_NAND_CONTROL         (ASYNC_EMIF_BASE+0x60)
  31#define ASYNC_EMIF_WAITCYCLE_CONFIG     (ASYNC_EMIF_BASE+0x4)
  32
  33#define CONFIG_SELECT_STROBE(v)         ((v) ? 1 << 31 : 0)
  34#define CONFIG_EXTEND_WAIT(v)           ((v) ? 1 << 30 : 0)
  35#define CONFIG_WR_SETUP(v)              (((v) & 0x0f) << 26)
  36#define CONFIG_WR_STROBE(v)             (((v) & 0x3f) << 20)
  37#define CONFIG_WR_HOLD(v)               (((v) & 0x07) << 17)
  38#define CONFIG_RD_SETUP(v)              (((v) & 0x0f) << 13)
  39#define CONFIG_RD_STROBE(v)             (((v) & 0x3f) << 7)
  40#define CONFIG_RD_HOLD(v)               (((v) & 0x07) << 4)
  41#define CONFIG_TURN_AROUND(v)           (((v) & 0x03) << 2)
  42#define CONFIG_WIDTH(v)                 (((v) & 0x03) << 0)
  43
  44#define NUM_CS                          4
  45
  46#define set_config_field(reg, field, val)                       \
  47        do {                                                    \
  48                if (val != -1) {                                \
  49                        reg &= ~CONFIG_##field(0xffffffff);     \
  50                        reg |=  CONFIG_##field(val);            \
  51                }                                               \
  52        } while (0)
  53
  54void configure_async_emif(int cs, struct async_emif_config *cfg)
  55{
  56        unsigned long tmp;
  57
  58        if (cfg->mode == ASYNC_EMIF_MODE_NAND) {
  59                tmp = __raw_readl(ASYNC_EMIF_NAND_CONTROL);
  60                tmp |= (1 << cs);
  61                __raw_writel(tmp, ASYNC_EMIF_NAND_CONTROL);
  62
  63        } else if (cfg->mode == ASYNC_EMIF_MODE_ONENAND) {
  64                tmp = __raw_readl(ASYNC_EMIF_ONENAND_CONTROL);
  65                tmp |= (1 << cs);
  66                __raw_writel(tmp, ASYNC_EMIF_ONENAND_CONTROL);
  67        }
  68
  69        tmp = __raw_readl(ASYNC_EMIF_CONFIG(cs));
  70
  71        set_config_field(tmp, SELECT_STROBE,    cfg->select_strobe);
  72        set_config_field(tmp, EXTEND_WAIT,      cfg->extend_wait);
  73        set_config_field(tmp, WR_SETUP,         cfg->wr_setup);
  74        set_config_field(tmp, WR_STROBE,        cfg->wr_strobe);
  75        set_config_field(tmp, WR_HOLD,          cfg->wr_hold);
  76        set_config_field(tmp, RD_SETUP,         cfg->rd_setup);
  77        set_config_field(tmp, RD_STROBE,        cfg->rd_strobe);
  78        set_config_field(tmp, RD_HOLD,          cfg->rd_hold);
  79        set_config_field(tmp, TURN_AROUND,      cfg->turn_around);
  80        set_config_field(tmp, WIDTH,            cfg->width);
  81
  82        __raw_writel(tmp, ASYNC_EMIF_CONFIG(cs));
  83}
  84
  85void init_async_emif(int num_cs, struct async_emif_config *config)
  86{
  87        int cs;
  88
  89        clk_enable(TNETV107X_LPSC_AEMIF);
  90
  91        for (cs = 0; cs < num_cs; cs++)
  92                configure_async_emif(cs, config + cs);
  93}
  94