summaryrefslogtreecommitdiffstats
path: root/sys/arm/at91
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2014-05-14 20:31:54 +0000
committerian <ian@FreeBSD.org>2014-05-14 20:31:54 +0000
commitb817c837ca9b5c346e601b0f7de335729c8873dd (patch)
treedd55122a6ff8c3e8ce3bfc4febb09841f07ea4ec /sys/arm/at91
parent15a8c9db44075b3dd6e16714daaee4053182a01e (diff)
downloadFreeBSD-src-b817c837ca9b5c346e601b0f7de335729c8873dd.zip
FreeBSD-src-b817c837ca9b5c346e601b0f7de335729c8873dd.tar.gz
MFC r260695, r260696, r260884, r260885, r260886, r260887
Provide a simplified way to specify GPIO pins for the Atmel port. Add at91 data so we can convert a PIO unit number into a base address. Add at91 standard memory controller helper functions. Generalize AT91 NAND support a bit. Connect NAND for the SAM9260EK eval board, as well as the HotE HL-201. Add nand device and NANDFS into the mix for those at91 boards that have support for it at the moment.
Diffstat (limited to 'sys/arm/at91')
-rw-r--r--sys/arm/at91/at91_gpio.h296
-rw-r--r--sys/arm/at91/at91_smc.c91
-rw-r--r--sys/arm/at91/at91_smc.h116
-rw-r--r--sys/arm/at91/at91rm9200.c9
-rw-r--r--sys/arm/at91/at91sam9260.c8
-rw-r--r--sys/arm/at91/at91sam9g20.c8
-rw-r--r--sys/arm/at91/at91sam9g45.c10
-rw-r--r--sys/arm/at91/at91sam9x5.c9
-rw-r--r--sys/arm/at91/at91var.h12
-rw-r--r--sys/arm/at91/files.at911
10 files changed, 555 insertions, 5 deletions
diff --git a/sys/arm/at91/at91_gpio.h b/sys/arm/at91/at91_gpio.h
new file mode 100644
index 0000000..935e437
--- /dev/null
+++ b/sys/arm/at91/at91_gpio.h
@@ -0,0 +1,296 @@
+/*-
+ * Copyright (c) 2014 M. Warner Losh. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $FreeBSD$ */
+
+#ifndef ARM_AT91_AT91_GPIO_H
+#define ARM_AT91_AT91_GPIO_H
+
+typedef uint32_t at91_pin_t;
+
+#define AT91_PIN_NONE 0xfffffffful /* No pin / Not GPIO controlled */
+
+/*
+ * Map Atmel PIO pins to a unique number. They are just numbered sequentially.
+ */
+
+#define AT91_PIN_PA0 (at91_pin_t)0
+#define AT91_PIN_PA1 (at91_pin_t)1
+#define AT91_PIN_PA2 (at91_pin_t)2
+#define AT91_PIN_PA3 (at91_pin_t)3
+#define AT91_PIN_PA4 (at91_pin_t)4
+#define AT91_PIN_PA5 (at91_pin_t)5
+#define AT91_PIN_PA6 (at91_pin_t)6
+#define AT91_PIN_PA7 (at91_pin_t)7
+#define AT91_PIN_PA8 (at91_pin_t)8
+#define AT91_PIN_PA9 (at91_pin_t)9
+#define AT91_PIN_PA10 (at91_pin_t)10
+#define AT91_PIN_PA11 (at91_pin_t)11
+#define AT91_PIN_PA12 (at91_pin_t)12
+#define AT91_PIN_PA13 (at91_pin_t)13
+#define AT91_PIN_PA14 (at91_pin_t)14
+#define AT91_PIN_PA15 (at91_pin_t)15
+#define AT91_PIN_PA16 (at91_pin_t)16
+#define AT91_PIN_PA17 (at91_pin_t)17
+#define AT91_PIN_PA18 (at91_pin_t)18
+#define AT91_PIN_PA19 (at91_pin_t)19
+#define AT91_PIN_PA20 (at91_pin_t)20
+#define AT91_PIN_PA21 (at91_pin_t)21
+#define AT91_PIN_PA22 (at91_pin_t)22
+#define AT91_PIN_PA23 (at91_pin_t)23
+#define AT91_PIN_PA24 (at91_pin_t)24
+#define AT91_PIN_PA25 (at91_pin_t)25
+#define AT91_PIN_PA26 (at91_pin_t)26
+#define AT91_PIN_PA27 (at91_pin_t)27
+#define AT91_PIN_PA28 (at91_pin_t)28
+#define AT91_PIN_PA29 (at91_pin_t)29
+#define AT91_PIN_PA30 (at91_pin_t)30
+#define AT91_PIN_PA31 (at91_pin_t)31
+#define AT91_PIN_PB0 (at91_pin_t)32
+#define AT91_PIN_PB1 (at91_pin_t)33
+#define AT91_PIN_PB2 (at91_pin_t)34
+#define AT91_PIN_PB3 (at91_pin_t)35
+#define AT91_PIN_PB4 (at91_pin_t)36
+#define AT91_PIN_PB5 (at91_pin_t)37
+#define AT91_PIN_PB6 (at91_pin_t)38
+#define AT91_PIN_PB7 (at91_pin_t)39
+#define AT91_PIN_PB8 (at91_pin_t)40
+#define AT91_PIN_PB9 (at91_pin_t)41
+#define AT91_PIN_PB10 (at91_pin_t)42
+#define AT91_PIN_PB11 (at91_pin_t)43
+#define AT91_PIN_PB12 (at91_pin_t)44
+#define AT91_PIN_PB13 (at91_pin_t)45
+#define AT91_PIN_PB14 (at91_pin_t)46
+#define AT91_PIN_PB15 (at91_pin_t)47
+#define AT91_PIN_PB16 (at91_pin_t)48
+#define AT91_PIN_PB17 (at91_pin_t)49
+#define AT91_PIN_PB18 (at91_pin_t)50
+#define AT91_PIN_PB19 (at91_pin_t)51
+#define AT91_PIN_PB20 (at91_pin_t)52
+#define AT91_PIN_PB21 (at91_pin_t)53
+#define AT91_PIN_PB22 (at91_pin_t)54
+#define AT91_PIN_PB23 (at91_pin_t)55
+#define AT91_PIN_PB24 (at91_pin_t)56
+#define AT91_PIN_PB25 (at91_pin_t)57
+#define AT91_PIN_PB26 (at91_pin_t)58
+#define AT91_PIN_PB27 (at91_pin_t)59
+#define AT91_PIN_PB28 (at91_pin_t)60
+#define AT91_PIN_PB29 (at91_pin_t)61
+#define AT91_PIN_PB30 (at91_pin_t)62
+#define AT91_PIN_PB31 (at91_pin_t)63
+#define AT91_PIN_PC0 (at91_pin_t)64
+#define AT91_PIN_PC1 (at91_pin_t)65
+#define AT91_PIN_PC2 (at91_pin_t)66
+#define AT91_PIN_PC3 (at91_pin_t)67
+#define AT91_PIN_PC4 (at91_pin_t)68
+#define AT91_PIN_PC5 (at91_pin_t)69
+#define AT91_PIN_PC6 (at91_pin_t)70
+#define AT91_PIN_PC7 (at91_pin_t)71
+#define AT91_PIN_PC8 (at91_pin_t)72
+#define AT91_PIN_PC9 (at91_pin_t)73
+#define AT91_PIN_PC10 (at91_pin_t)74
+#define AT91_PIN_PC11 (at91_pin_t)75
+#define AT91_PIN_PC12 (at91_pin_t)76
+#define AT91_PIN_PC13 (at91_pin_t)77
+#define AT91_PIN_PC14 (at91_pin_t)78
+#define AT91_PIN_PC15 (at91_pin_t)79
+#define AT91_PIN_PC16 (at91_pin_t)80
+#define AT91_PIN_PC17 (at91_pin_t)81
+#define AT91_PIN_PC18 (at91_pin_t)82
+#define AT91_PIN_PC19 (at91_pin_t)83
+#define AT91_PIN_PC20 (at91_pin_t)84
+#define AT91_PIN_PC21 (at91_pin_t)85
+#define AT91_PIN_PC22 (at91_pin_t)86
+#define AT91_PIN_PC23 (at91_pin_t)87
+#define AT91_PIN_PC24 (at91_pin_t)88
+#define AT91_PIN_PC25 (at91_pin_t)89
+#define AT91_PIN_PC26 (at91_pin_t)90
+#define AT91_PIN_PC27 (at91_pin_t)91
+#define AT91_PIN_PC28 (at91_pin_t)92
+#define AT91_PIN_PC29 (at91_pin_t)93
+#define AT91_PIN_PC30 (at91_pin_t)94
+#define AT91_PIN_PC31 (at91_pin_t)95
+#define AT91_PIN_PD0 (at91_pin_t)96
+#define AT91_PIN_PD1 (at91_pin_t)97
+#define AT91_PIN_PD2 (at91_pin_t)98
+#define AT91_PIN_PD3 (at91_pin_t)99
+#define AT91_PIN_PD4 (at91_pin_t)100
+#define AT91_PIN_PD5 (at91_pin_t)101
+#define AT91_PIN_PD6 (at91_pin_t)102
+#define AT91_PIN_PD7 (at91_pin_t)103
+#define AT91_PIN_PD8 (at91_pin_t)104
+#define AT91_PIN_PD9 (at91_pin_t)105
+#define AT91_PIN_PD10 (at91_pin_t)106
+#define AT91_PIN_PD11 (at91_pin_t)107
+#define AT91_PIN_PD12 (at91_pin_t)108
+#define AT91_PIN_PD13 (at91_pin_t)109
+#define AT91_PIN_PD14 (at91_pin_t)110
+#define AT91_PIN_PD15 (at91_pin_t)111
+#define AT91_PIN_PD16 (at91_pin_t)112
+#define AT91_PIN_PD17 (at91_pin_t)113
+#define AT91_PIN_PD18 (at91_pin_t)114
+#define AT91_PIN_PD19 (at91_pin_t)115
+#define AT91_PIN_PD20 (at91_pin_t)116
+#define AT91_PIN_PD21 (at91_pin_t)117
+#define AT91_PIN_PD22 (at91_pin_t)118
+#define AT91_PIN_PD23 (at91_pin_t)119
+#define AT91_PIN_PD24 (at91_pin_t)120
+#define AT91_PIN_PD25 (at91_pin_t)121
+#define AT91_PIN_PD26 (at91_pin_t)122
+#define AT91_PIN_PD27 (at91_pin_t)123
+#define AT91_PIN_PD28 (at91_pin_t)124
+#define AT91_PIN_PD29 (at91_pin_t)125
+#define AT91_PIN_PD30 (at91_pin_t)126
+#define AT91_PIN_PD31 (at91_pin_t)127
+#define AT91_PIN_PE0 (at91_pin_t)128
+#define AT91_PIN_PE1 (at91_pin_t)129
+#define AT91_PIN_PE2 (at91_pin_t)130
+#define AT91_PIN_PE3 (at91_pin_t)131
+#define AT91_PIN_PE4 (at91_pin_t)132
+#define AT91_PIN_PE5 (at91_pin_t)133
+#define AT91_PIN_PE6 (at91_pin_t)134
+#define AT91_PIN_PE7 (at91_pin_t)135
+#define AT91_PIN_PE8 (at91_pin_t)136
+#define AT91_PIN_PE9 (at91_pin_t)137
+#define AT91_PIN_PE10 (at91_pin_t)138
+#define AT91_PIN_PE11 (at91_pin_t)139
+#define AT91_PIN_PE12 (at91_pin_t)140
+#define AT91_PIN_PE13 (at91_pin_t)141
+#define AT91_PIN_PE14 (at91_pin_t)142
+#define AT91_PIN_PE15 (at91_pin_t)143
+#define AT91_PIN_PE16 (at91_pin_t)144
+#define AT91_PIN_PE17 (at91_pin_t)145
+#define AT91_PIN_PE18 (at91_pin_t)146
+#define AT91_PIN_PE19 (at91_pin_t)147
+#define AT91_PIN_PE20 (at91_pin_t)148
+#define AT91_PIN_PE21 (at91_pin_t)149
+#define AT91_PIN_PE22 (at91_pin_t)150
+#define AT91_PIN_PE23 (at91_pin_t)151
+#define AT91_PIN_PE24 (at91_pin_t)152
+#define AT91_PIN_PE25 (at91_pin_t)153
+#define AT91_PIN_PE26 (at91_pin_t)154
+#define AT91_PIN_PE27 (at91_pin_t)155
+#define AT91_PIN_PE28 (at91_pin_t)156
+#define AT91_PIN_PE29 (at91_pin_t)157
+#define AT91_PIN_PE30 (at91_pin_t)158
+#define AT91_PIN_PE31 (at91_pin_t)159
+#define AT91_PIN_PF0 (at91_pin_t)160
+#define AT91_PIN_PF1 (at91_pin_t)161
+#define AT91_PIN_PF2 (at91_pin_t)162
+#define AT91_PIN_PF3 (at91_pin_t)163
+#define AT91_PIN_PF4 (at91_pin_t)164
+#define AT91_PIN_PF5 (at91_pin_t)165
+#define AT91_PIN_PF6 (at91_pin_t)166
+#define AT91_PIN_PF7 (at91_pin_t)167
+#define AT91_PIN_PF8 (at91_pin_t)168
+#define AT91_PIN_PF9 (at91_pin_t)169
+#define AT91_PIN_PF10 (at91_pin_t)170
+#define AT91_PIN_PF11 (at91_pin_t)171
+#define AT91_PIN_PF12 (at91_pin_t)172
+#define AT91_PIN_PF13 (at91_pin_t)173
+#define AT91_PIN_PF14 (at91_pin_t)174
+#define AT91_PIN_PF15 (at91_pin_t)175
+#define AT91_PIN_PF16 (at91_pin_t)176
+#define AT91_PIN_PF17 (at91_pin_t)177
+#define AT91_PIN_PF18 (at91_pin_t)178
+#define AT91_PIN_PF19 (at91_pin_t)179
+#define AT91_PIN_PF20 (at91_pin_t)180
+#define AT91_PIN_PF21 (at91_pin_t)181
+#define AT91_PIN_PF22 (at91_pin_t)182
+#define AT91_PIN_PF23 (at91_pin_t)183
+#define AT91_PIN_PF24 (at91_pin_t)184
+#define AT91_PIN_PF25 (at91_pin_t)185
+#define AT91_PIN_PF26 (at91_pin_t)186
+#define AT91_PIN_PF27 (at91_pin_t)187
+#define AT91_PIN_PF28 (at91_pin_t)188
+#define AT91_PIN_PF29 (at91_pin_t)189
+#define AT91_PIN_PF30 (at91_pin_t)190
+#define AT91_PIN_PF31 (at91_pin_t)191
+#define AT91_PIN_PG0 (at91_pin_t)192
+#define AT91_PIN_PG1 (at91_pin_t)193
+#define AT91_PIN_PG2 (at91_pin_t)194
+#define AT91_PIN_PG3 (at91_pin_t)195
+#define AT91_PIN_PG4 (at91_pin_t)196
+#define AT91_PIN_PG5 (at91_pin_t)197
+#define AT91_PIN_PG6 (at91_pin_t)198
+#define AT91_PIN_PG7 (at91_pin_t)199
+#define AT91_PIN_PG8 (at91_pin_t)200
+#define AT91_PIN_PG9 (at91_pin_t)201
+#define AT91_PIN_PG10 (at91_pin_t)202
+#define AT91_PIN_PG11 (at91_pin_t)203
+#define AT91_PIN_PG12 (at91_pin_t)204
+#define AT91_PIN_PG13 (at91_pin_t)205
+#define AT91_PIN_PG14 (at91_pin_t)206
+#define AT91_PIN_PG15 (at91_pin_t)207
+#define AT91_PIN_PG16 (at91_pin_t)208
+#define AT91_PIN_PG17 (at91_pin_t)209
+#define AT91_PIN_PG18 (at91_pin_t)210
+#define AT91_PIN_PG19 (at91_pin_t)211
+#define AT91_PIN_PG20 (at91_pin_t)212
+#define AT91_PIN_PG21 (at91_pin_t)213
+#define AT91_PIN_PG22 (at91_pin_t)214
+#define AT91_PIN_PG23 (at91_pin_t)215
+#define AT91_PIN_PG24 (at91_pin_t)216
+#define AT91_PIN_PG25 (at91_pin_t)217
+#define AT91_PIN_PG26 (at91_pin_t)218
+#define AT91_PIN_PG27 (at91_pin_t)219
+#define AT91_PIN_PG28 (at91_pin_t)220
+#define AT91_PIN_PG29 (at91_pin_t)221
+#define AT91_PIN_PG30 (at91_pin_t)222
+#define AT91_PIN_PG31 (at91_pin_t)223
+#define AT91_PIN_PH0 (at91_pin_t)224
+#define AT91_PIN_PH1 (at91_pin_t)225
+#define AT91_PIN_PH2 (at91_pin_t)226
+#define AT91_PIN_PH3 (at91_pin_t)227
+#define AT91_PIN_PH4 (at91_pin_t)228
+#define AT91_PIN_PH5 (at91_pin_t)229
+#define AT91_PIN_PH6 (at91_pin_t)230
+#define AT91_PIN_PH7 (at91_pin_t)231
+#define AT91_PIN_PH8 (at91_pin_t)232
+#define AT91_PIN_PH9 (at91_pin_t)233
+#define AT91_PIN_PH10 (at91_pin_t)234
+#define AT91_PIN_PH11 (at91_pin_t)235
+#define AT91_PIN_PH12 (at91_pin_t)236
+#define AT91_PIN_PH13 (at91_pin_t)237
+#define AT91_PIN_PH14 (at91_pin_t)238
+#define AT91_PIN_PH15 (at91_pin_t)239
+#define AT91_PIN_PH16 (at91_pin_t)240
+#define AT91_PIN_PH17 (at91_pin_t)241
+#define AT91_PIN_PH18 (at91_pin_t)242
+#define AT91_PIN_PH19 (at91_pin_t)243
+#define AT91_PIN_PH20 (at91_pin_t)244
+#define AT91_PIN_PH21 (at91_pin_t)245
+#define AT91_PIN_PH22 (at91_pin_t)246
+#define AT91_PIN_PH23 (at91_pin_t)247
+#define AT91_PIN_PH24 (at91_pin_t)248
+#define AT91_PIN_PH25 (at91_pin_t)249
+#define AT91_PIN_PH26 (at91_pin_t)250
+#define AT91_PIN_PH27 (at91_pin_t)251
+#define AT91_PIN_PH28 (at91_pin_t)252
+#define AT91_PIN_PH29 (at91_pin_t)253
+#define AT91_PIN_PH30 (at91_pin_t)254
+#define AT91_PIN_PH31 (at91_pin_t)255
+
+#endif /* ARM_AT91_AT91_GPIO_H */
diff --git a/sys/arm/at91/at91_smc.c b/sys/arm/at91/at91_smc.c
new file mode 100644
index 0000000..2d59d16
--- /dev/null
+++ b/sys/arm/at91/at91_smc.c
@@ -0,0 +1,91 @@
+/*-
+ * Copyright (c) 2014 M. Warner Losh. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/types.h>
+
+#include <arm/at91/at91reg.h>
+#include <arm/at91/at91_smc.h>
+#include <arm/at91/at91sam9260reg.h>
+
+/*
+ * RD4HW()/WR4HW() read and write at91 hardware register space directly. They
+ * serve the same purpose as the RD4()/WR4() idiom you see in many drivers,
+ * except that those translate to bus_space calls, but in this code we need to
+ * access some devices before bus_space is ready to use. Of course for this to
+ * work the appropriate static device mappings need to be made in machdep.c.
+ */
+static inline uint32_t
+RD4HW(uint32_t devbase, uint32_t regoff)
+{
+
+ return *(volatile uint32_t *)(AT91_BASE + devbase + regoff);
+}
+
+
+static inline void
+WR4HW(uint32_t devbase, uint32_t regoff, uint32_t val)
+{
+
+ *(volatile uint32_t *)(AT91_BASE + devbase + regoff) = val;
+}
+
+
+void
+at91_smc_setup(int id, int cs, const struct at91_smc_init *smc)
+{
+ // Need a generic way to get this address for all SoCs... Assume 9260 for now...
+ uint32_t base = AT91SAM9260_SMC_BASE + SMC_CS_OFF(cs);
+
+ WR4HW(base, SMC_SETUP, SMC_SETUP_NCS_RD_SETUP(smc->ncs_rd_setup) |
+ SMC_SETUP_NRD_SETUP(smc->nrd_setup) |
+ SMC_SETUP_NCS_WR_SETUP(smc->ncs_wr_setup) |
+ SMC_SETUP_NWE_SETUP(smc->nwe_setup));
+ WR4HW(base, SMC_PULSE, SMC_PULSE_NCS_RD_PULSE(smc->ncs_rd_pulse) |
+ SMC_PULSE_NRD_PULSE(smc->nrd_pulse) |
+ SMC_PULSE_NCS_WR_PULSE(smc->ncs_wr_pulse) |
+ SMC_PULSE_NWE_PULSE(smc->nwe_pulse));
+ WR4HW(base, SMC_CYCLE, SMC_CYCLE_NRD_CYCLE(smc->nrd_cycle) |
+ SMC_CYCLE_NWE_CYCLE(smc->nwe_cycle));
+ WR4HW(base, SMC_MODE, smc->mode | SMC_MODE_TDF_CYCLES(smc->tdf_cycles));
+}
+
+void
+at91_ebi_enable(int bank)
+{
+
+ WR4HW(AT91SAM9260_MATRIX_BASE, AT91SAM9260_EBICSA, (1 << bank) |
+ RD4HW(AT91SAM9260_MATRIX_BASE, AT91SAM9260_EBICSA));
+}
+
+void
+at91_ebi_disable(int bank)
+{
+
+ WR4HW(AT91SAM9260_MATRIX_BASE, AT91SAM9260_EBICSA, ~(1 << bank) &
+ RD4HW(AT91SAM9260_MATRIX_BASE, AT91SAM9260_EBICSA));
+}
diff --git a/sys/arm/at91/at91_smc.h b/sys/arm/at91/at91_smc.h
new file mode 100644
index 0000000..f571c46
--- /dev/null
+++ b/sys/arm/at91/at91_smc.h
@@ -0,0 +1,116 @@
+/*-
+ * Copyright (c) 2014 M. Warner Losh. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $FreeBSD$ */
+
+#ifndef ARM_AT91_AT91_SMC_H
+#define ARM_AT91_AT91_SMC_H
+
+/* Registers */
+#define SMC_SETUP 0x00
+#define SMC_PULSE 0x04
+#define SMC_CYCLE 0x08
+#define SMC_MODE 0x0C
+
+#define SMC_CS_OFF(cs) (0x10 * (cs))
+
+/* Setup */
+#define SMC_SETUP_NCS_RD_SETUP(x) ((x) << 24)
+#define SMC_SETUP_NRD_SETUP(x) ((x) << 16)
+#define SMC_SETUP_NCS_WR_SETUP(x) ((x) << 8)
+#define SMC_SETUP_NWE_SETUP(x) (x)
+
+/* Pulse */
+#define SMC_PULSE_NCS_RD_PULSE(x) ((x) << 24)
+#define SMC_PULSE_NRD_PULSE(x) ((x) << 16)
+#define SMC_PULSE_NCS_WR_PULSE(x) ((x) << 8)
+#define SMC_PULSE_NWE_PULSE(x) (x)
+
+/* Cycle */
+#define SMC_CYCLE_NRD_CYCLE(x) ((x) << 16)
+#define SMC_CYCLE_NWE_CYCLE(x) (x)
+
+/* Mode */
+#define SMC_MODE_READ (1 << 0)
+#define SMC_MODE_WRITE (1 << 1)
+#define SMC_MODE_EXNW_DISABLED (0 << 4)
+#define SMC_MODE_EXNW_FROZEN_MODE (2 << 4)
+#define SMC_MODE_EXNW_READY_MODE (3 << 4)
+#define SMC_MODE_BAT (1 << 8)
+#define SMC_MODE_DBW_8BIT (0 << 12)
+#define SMC_MODE_DBW_16BIT (1 << 12)
+#define SMC_MODE_DBW_32_BIT (2 << 12)
+#define SMC_MODE_TDF_CYCLES(x) ((x) << 16)
+#define SMC_MODE_TDF_MODE (1 << 20)
+#define SMC_MODE_PMEN (1 << 24)
+#define SMC_PS_4BYTE (0 << 28)
+#define SMC_PS_8BYTE (1 << 28)
+#define SMC_PS_16BYTE (2 << 28)
+#define SMC_PS_32BYTE (3 << 28)
+
+/*
+ * structure to ease init. See the SMC chapter in the datasheet for
+ * the appropriate SoC you are using for details.
+ */
+struct at91_smc_init
+{
+ /* Setup register */
+ uint8_t ncs_rd_setup;
+ uint8_t nrd_setup;
+ uint8_t ncs_wr_setup;
+ uint8_t nwe_setup;
+
+ /* Pulse register */
+ uint8_t ncs_rd_pulse;
+ uint8_t nrd_pulse;
+ uint8_t ncs_wr_pulse;
+ uint8_t nwe_pulse;
+
+ /* Cycle register */
+ uint16_t nrd_cycle;
+ uint16_t nwe_cycle;
+
+ /* Mode register */
+ uint8_t mode; /* Combo of READ/WRITE/EXNW fields */
+ uint8_t bat;
+ uint8_t dwb;
+ uint8_t tdf_cycles;
+ uint8_t tdf_mode;
+ uint8_t pmen;
+ uint8_t ps;
+};
+
+/*
+ * Convenience routine to fill in SMC registers for a given chip select.
+ */
+void at91_smc_setup(int id, int cs, const struct at91_smc_init *smc);
+
+/*
+ * Disable/Enable different External Bus Interfaces (EBI)
+ */
+void at91_ebi_enable(int cs);
+void at91_ebi_disable(int cs);
+
+#endif /* ARM_AT91_AT91_SMC_H */
diff --git a/sys/arm/at91/at91rm9200.c b/sys/arm/at91/at91rm9200.c
index 2c6073c..f2ee450 100644
--- a/sys/arm/at91/at91rm9200.c
+++ b/sys/arm/at91/at91rm9200.c
@@ -88,6 +88,13 @@ static const int at91_irq_prio[32] =
0 /* Advanced Interrupt Controller (IRQ6) */
};
+static const uint32_t at91_pio_base[] = {
+ AT91RM92_PIOA_BASE,
+ AT91RM92_PIOB_BASE,
+ AT91RM92_PIOC_BASE,
+ AT91RM92_PIOD_BASE,
+};
+
#define DEVICE(_name, _id, _unit) \
{ \
_name, _unit, \
@@ -195,6 +202,8 @@ static struct at91_soc_data soc_data = {
.soc_clock_init = at91_clock_init,
.soc_irq_prio = at91_irq_prio,
.soc_children = at91_devs,
+ .soc_pio_base = at91_pio_base,
+ .soc_pio_count = nitems(at91_pio_base),
};
AT91_SOC(AT91_T_RM9200, &soc_data);
diff --git a/sys/arm/at91/at91sam9260.c b/sys/arm/at91/at91sam9260.c
index 013c9e4..03ad462 100644
--- a/sys/arm/at91/at91sam9260.c
+++ b/sys/arm/at91/at91sam9260.c
@@ -87,6 +87,12 @@ static const int at91_irq_prio[32] =
0, /* Advanced Interrupt Controller IRQ2 */
};
+static const uint32_t at91_pio_base[] = {
+ AT91SAM9260_PIOA_BASE,
+ AT91SAM9260_PIOB_BASE,
+ AT91SAM9260_PIOC_BASE,
+};
+
#define DEVICE(_name, _id, _unit) \
{ \
_name, _unit, \
@@ -204,6 +210,8 @@ static struct at91_soc_data soc_data = {
.soc_clock_init = at91_clock_init,
.soc_irq_prio = at91_irq_prio,
.soc_children = at91_devs,
+ .soc_pio_base = at91_pio_base,
+ .soc_pio_count = nitems(at91_pio_base),
};
AT91_SOC(AT91_T_SAM9260, &soc_data);
diff --git a/sys/arm/at91/at91sam9g20.c b/sys/arm/at91/at91sam9g20.c
index 4d9907c..d4e6347 100644
--- a/sys/arm/at91/at91sam9g20.c
+++ b/sys/arm/at91/at91sam9g20.c
@@ -87,6 +87,12 @@ static const int at91_irq_prio[32] =
0, /* Advanced Interrupt Controller IRQ2 */
};
+static const uint32_t at91_pio_base[] = {
+ AT91SAM9G20_PIOA_BASE,
+ AT91SAM9G20_PIOB_BASE,
+ AT91SAM9G20_PIOC_BASE,
+};
+
#define DEVICE(_name, _id, _unit) \
{ \
_name, _unit, \
@@ -169,6 +175,8 @@ static struct at91_soc_data soc_data = {
.soc_clock_init = at91_clock_init,
.soc_irq_prio = at91_irq_prio,
.soc_children = at91_devs,
+ .soc_pio_base = at91_pio_base,
+ .soc_pio_count = nitems(at91_pio_base),
};
AT91_SOC(AT91_T_SAM9G20, &soc_data);
diff --git a/sys/arm/at91/at91sam9g45.c b/sys/arm/at91/at91sam9g45.c
index dedc7ce..c3a26d5 100644
--- a/sys/arm/at91/at91sam9g45.c
+++ b/sys/arm/at91/at91sam9g45.c
@@ -88,6 +88,14 @@ static const int at91_irq_prio[32] =
0, /* Advanced Interrupt Controller IRQ0 */
};
+static const uint32_t at91_pio_base[] = {
+ AT91SAM9G45_PIOA_BASE,
+ AT91SAM9G45_PIOB_BASE,
+ AT91SAM9G45_PIOC_BASE,
+ AT91SAM9G45_PIOD_BASE,
+ AT91SAM9G45_PIOE_BASE,
+};
+
#define DEVICE(_name, _id, _unit) \
{ \
_name, _unit, \
@@ -155,6 +163,8 @@ static struct at91_soc_data soc_data = {
.soc_clock_init = at91_clock_init,
.soc_irq_prio = at91_irq_prio,
.soc_children = at91_devs,
+ .soc_pio_base = at91_pio_base,
+ .soc_pio_count = nitems(at91_pio_base),
};
AT91_SOC(AT91_T_SAM9G45, &soc_data);
diff --git a/sys/arm/at91/at91sam9x5.c b/sys/arm/at91/at91sam9x5.c
index dedd135..4e8c3f4 100644
--- a/sys/arm/at91/at91sam9x5.c
+++ b/sys/arm/at91/at91sam9x5.c
@@ -87,6 +87,13 @@ static const int at91_irq_prio[32] =
0, /* Advanced Interrupt Controller (IRQ0) */
};
+static const uint32_t at91_pio_base[] = {
+ AT91SAM9X25_PIOA_BASE,
+ AT91SAM9X25_PIOB_BASE,
+ AT91SAM9X25_PIOC_BASE,
+ AT91SAM9X25_PIOD_BASE,
+};
+
#define DEVICE(_name, _id, _unit) \
{ \
_name, _unit, \
@@ -172,6 +179,8 @@ static struct at91_soc_data soc_data = {
.soc_clock_init = at91_clock_init,
.soc_irq_prio = at91_irq_prio,
.soc_children = at91_devs,
+ .soc_pio_base = at91_pio_base,
+ .soc_pio_count = nitems(at91_pio_base),
};
AT91_SOC_SUB(AT91_T_SAM9X5, AT91_ST_SAM9X25, &soc_data);
diff --git a/sys/arm/at91/at91var.h b/sys/arm/at91/at91var.h
index b149465..240eb74 100644
--- a/sys/arm/at91/at91var.h
+++ b/sys/arm/at91/at91var.h
@@ -107,11 +107,13 @@ typedef void (*cpu_reset_t)(void);
typedef void (*clk_init_t)(void);
struct at91_soc_data {
- DELAY_t soc_delay;
- cpu_reset_t soc_reset;
- clk_init_t soc_clock_init;
- const int *soc_irq_prio;
- const struct cpu_devs *soc_children;
+ DELAY_t soc_delay; /* SoC specific delay function */
+ cpu_reset_t soc_reset; /* SoC specific reset function */
+ clk_init_t soc_clock_init; /* SoC specific clock init function */
+ const int *soc_irq_prio; /* SoC specific IRQ priorities */
+ const struct cpu_devs *soc_children; /* SoC specific children list */
+ const uint32_t *soc_pio_base; /* SoC specific PIO base registers */
+ size_t soc_pio_count; /* Count of PIO units (not pins) in SoC */
};
struct at91_soc_info {
diff --git a/sys/arm/at91/files.at91 b/sys/arm/at91/files.at91
index a83aa7a..5533594 100644
--- a/sys/arm/at91/files.at91
+++ b/sys/arm/at91/files.at91
@@ -12,6 +12,7 @@ arm/at91/at91_pit.c optional at91sam9
arm/at91/at91_reset.S optional at91sam9
arm/at91/at91_rst.c optional at91sam9
arm/at91/at91_rtc.c optional at91_rtc
+arm/at91/at91_smc.c standard
arm/at91/at91_spi.c optional at91_spi \
dependency "spibus_if.h"
arm/at91/at91_ssc.c optional at91_ssc
OpenPOWER on IntegriCloud