2 * Static Memory Controller for AT32 chips
4 * Copyright (C) 2006 Atmel Corporation
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
11 #include <linux/clk.h>
12 #include <linux/err.h>
13 #include <linux/init.h>
14 #include <linux/module.h>
15 #include <linux/platform_device.h>
18 #include <asm/arch/smc.h>
22 #define NR_CHIP_SELECTS 6
30 static struct hsmc
*hsmc
;
32 int smc_set_configuration(int cs
, const struct smc_config
*config
)
36 u32 setup
, pulse
, cycle
, mode
;
40 if (cs
>= NR_CHIP_SELECTS
)
44 * cycles = x / T = x * f
45 * = ((x * 1000000000) * ((f * 65536) / 1000000000)) / 65536
46 * = ((x * 1000000000) * (((f / 10000) * 65536) / 100000)) / 65536
48 mul
= (clk_get_rate(hsmc
->mck
) / 10000) << 16;
51 #define ns2cyc(x) ((((x) * mul) + 65535) >> 16)
53 setup
= (HSMC_BF(NWE_SETUP
, ns2cyc(config
->nwe_setup
))
54 | HSMC_BF(NCS_WR_SETUP
, ns2cyc(config
->ncs_write_setup
))
55 | HSMC_BF(NRD_SETUP
, ns2cyc(config
->nrd_setup
))
56 | HSMC_BF(NCS_RD_SETUP
, ns2cyc(config
->ncs_read_setup
)));
57 pulse
= (HSMC_BF(NWE_PULSE
, ns2cyc(config
->nwe_pulse
))
58 | HSMC_BF(NCS_WR_PULSE
, ns2cyc(config
->ncs_write_pulse
))
59 | HSMC_BF(NRD_PULSE
, ns2cyc(config
->nrd_pulse
))
60 | HSMC_BF(NCS_RD_PULSE
, ns2cyc(config
->ncs_read_pulse
)));
61 cycle
= (HSMC_BF(NWE_CYCLE
, ns2cyc(config
->write_cycle
))
62 | HSMC_BF(NRD_CYCLE
, ns2cyc(config
->read_cycle
)));
64 switch (config
->bus_width
) {
66 mode
= HSMC_BF(DBW
, HSMC_DBW_8_BITS
);
69 mode
= HSMC_BF(DBW
, HSMC_DBW_16_BITS
);
72 mode
= HSMC_BF(DBW
, HSMC_DBW_32_BITS
);
78 switch (config
->nwait_mode
) {
80 mode
|= HSMC_BF(EXNW_MODE
, HSMC_EXNW_MODE_DISABLED
);
83 mode
|= HSMC_BF(EXNW_MODE
, HSMC_EXNW_MODE_RESERVED
);
86 mode
|= HSMC_BF(EXNW_MODE
, HSMC_EXNW_MODE_FROZEN
);
89 mode
|= HSMC_BF(EXNW_MODE
, HSMC_EXNW_MODE_READY
);
95 if (config
->tdf_cycles
) {
96 mode
|= HSMC_BF(TDF_CYCLES
, config
->tdf_cycles
);
99 if (config
->nrd_controlled
)
100 mode
|= HSMC_BIT(READ_MODE
);
101 if (config
->nwe_controlled
)
102 mode
|= HSMC_BIT(WRITE_MODE
);
103 if (config
->byte_write
)
104 mode
|= HSMC_BIT(BAT
);
105 if (config
->tdf_mode
)
106 mode
|= HSMC_BIT(TDF_MODE
);
108 pr_debug("smc cs%d: setup/%08x pulse/%08x cycle/%08x mode/%08x\n",
109 cs
, setup
, pulse
, cycle
, mode
);
112 hsmc_writel(hsmc
, SETUP0
+ offset
, setup
);
113 hsmc_writel(hsmc
, PULSE0
+ offset
, pulse
);
114 hsmc_writel(hsmc
, CYCLE0
+ offset
, cycle
);
115 hsmc_writel(hsmc
, MODE0
+ offset
, mode
);
116 hsmc_readl(hsmc
, MODE0
); /* I/O barrier */
120 EXPORT_SYMBOL(smc_set_configuration
);
122 static int hsmc_probe(struct platform_device
*pdev
)
124 struct resource
*regs
;
125 struct clk
*pclk
, *mck
;
131 regs
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
134 pclk
= clk_get(&pdev
->dev
, "pclk");
136 return PTR_ERR(pclk
);
137 mck
= clk_get(&pdev
->dev
, "mck");
144 hsmc
= kzalloc(sizeof(struct hsmc
), GFP_KERNEL
);
153 hsmc
->regs
= ioremap(regs
->start
, regs
->end
- regs
->start
+ 1);
155 goto out_disable_clocks
;
157 dev_info(&pdev
->dev
, "Atmel Static Memory Controller at 0x%08lx\n",
158 (unsigned long)regs
->start
);
160 platform_set_drvdata(pdev
, hsmc
);
176 static struct platform_driver hsmc_driver
= {
183 static int __init
hsmc_init(void)
185 return platform_driver_register(&hsmc_driver
);
187 arch_initcall(hsmc_init
);