linux/arch/arm/mach-at91/sam9_smc.c
<<
>>
Prefs
   1/*
   2 * linux/arch/arm/mach-at91/sam9_smc.c
   3 *
   4 * Copyright (C) 2008 Andrew Victor
   5 * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
   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 version 2 as
   9 * published by the Free Software Foundation.
  10 */
  11
  12#include <linux/module.h>
  13#include <linux/io.h>
  14#include <linux/of.h>
  15#include <linux/of_address.h>
  16
  17#include <mach/at91sam9_smc.h>
  18
  19#include "sam9_smc.h"
  20
  21
  22#define AT91_SMC_CS(id, n)      (smc_base_addr[id] + ((n) * 0x10))
  23
  24static void __iomem *smc_base_addr[2];
  25
  26static void sam9_smc_cs_write_mode(void __iomem *base,
  27                                        struct sam9_smc_config *config)
  28{
  29        __raw_writel(config->mode
  30                   | AT91_SMC_TDF_(config->tdf_cycles),
  31                   base + AT91_SMC_MODE);
  32}
  33
  34void sam9_smc_write_mode(int id, int cs,
  35                                        struct sam9_smc_config *config)
  36{
  37        sam9_smc_cs_write_mode(AT91_SMC_CS(id, cs), config);
  38}
  39
  40static void sam9_smc_cs_configure(void __iomem *base,
  41                                        struct sam9_smc_config *config)
  42{
  43
  44        /* Setup register */
  45        __raw_writel(AT91_SMC_NWESETUP_(config->nwe_setup)
  46                   | AT91_SMC_NCS_WRSETUP_(config->ncs_write_setup)
  47                   | AT91_SMC_NRDSETUP_(config->nrd_setup)
  48                   | AT91_SMC_NCS_RDSETUP_(config->ncs_read_setup),
  49                   base + AT91_SMC_SETUP);
  50
  51        /* Pulse register */
  52        __raw_writel(AT91_SMC_NWEPULSE_(config->nwe_pulse)
  53                   | AT91_SMC_NCS_WRPULSE_(config->ncs_write_pulse)
  54                   | AT91_SMC_NRDPULSE_(config->nrd_pulse)
  55                   | AT91_SMC_NCS_RDPULSE_(config->ncs_read_pulse),
  56                   base + AT91_SMC_PULSE);
  57
  58        /* Cycle register */
  59        __raw_writel(AT91_SMC_NWECYCLE_(config->write_cycle)
  60                   | AT91_SMC_NRDCYCLE_(config->read_cycle),
  61                   base + AT91_SMC_CYCLE);
  62
  63        /* Mode register */
  64        sam9_smc_cs_write_mode(base, config);
  65}
  66
  67void sam9_smc_configure(int id, int cs,
  68                                        struct sam9_smc_config *config)
  69{
  70        sam9_smc_cs_configure(AT91_SMC_CS(id, cs), config);
  71}
  72
  73static void sam9_smc_cs_read_mode(void __iomem *base,
  74                                        struct sam9_smc_config *config)
  75{
  76        u32 val = __raw_readl(base + AT91_SMC_MODE);
  77
  78        config->mode = (val & ~AT91_SMC_NWECYCLE);
  79        config->tdf_cycles = (val & AT91_SMC_NWECYCLE) >> 16 ;
  80}
  81
  82void sam9_smc_read_mode(int id, int cs,
  83                                        struct sam9_smc_config *config)
  84{
  85        sam9_smc_cs_read_mode(AT91_SMC_CS(id, cs), config);
  86}
  87
  88static void sam9_smc_cs_read(void __iomem *base,
  89                                        struct sam9_smc_config *config)
  90{
  91        u32 val;
  92
  93        /* Setup register */
  94        val = __raw_readl(base + AT91_SMC_SETUP);
  95
  96        config->nwe_setup = val & AT91_SMC_NWESETUP;
  97        config->ncs_write_setup = (val & AT91_SMC_NCS_WRSETUP) >> 8;
  98        config->nrd_setup = (val & AT91_SMC_NRDSETUP) >> 16;
  99        config->ncs_read_setup = (val & AT91_SMC_NCS_RDSETUP) >> 24;
 100
 101        /* Pulse register */
 102        val = __raw_readl(base + AT91_SMC_PULSE);
 103
 104        config->nwe_setup = val & AT91_SMC_NWEPULSE;
 105        config->ncs_write_pulse = (val & AT91_SMC_NCS_WRPULSE) >> 8;
 106        config->nrd_pulse = (val & AT91_SMC_NRDPULSE) >> 16;
 107        config->ncs_read_pulse = (val & AT91_SMC_NCS_RDPULSE) >> 24;
 108
 109        /* Cycle register */
 110        val = __raw_readl(base + AT91_SMC_CYCLE);
 111
 112        config->write_cycle = val & AT91_SMC_NWECYCLE;
 113        config->read_cycle = (val & AT91_SMC_NRDCYCLE) >> 16;
 114
 115        /* Mode register */
 116        sam9_smc_cs_read_mode(base, config);
 117}
 118
 119void sam9_smc_read(int id, int cs, struct sam9_smc_config *config)
 120{
 121        sam9_smc_cs_read(AT91_SMC_CS(id, cs), config);
 122}
 123
 124void __init at91sam9_ioremap_smc(int id, u32 addr)
 125{
 126        if (id > 1) {
 127                pr_warn("%s: id > 2\n", __func__);
 128                return;
 129        }
 130        smc_base_addr[id] = ioremap(addr, 512);
 131        if (!smc_base_addr[id])
 132                pr_warn("Impossible to ioremap smc.%d 0x%x\n", id, addr);
 133}
 134