[PATCH] at91rm9200 static memory controller initialization
Guido Classen
clagix at gmail.com
Tue Jun 15 14:26:24 EDT 2010
Hello mailing list,
This patch adds AT91RM9200 static memory controller initialization based
on a structure 'at91rm9200_smc_config'. It is simlar to a patch provided
by Andrew Victor for the AT91SAM9 family (sam9_smc.[ch]).
The code can be used like this:
/*
* Setup static memory controller chip select for external quad UART
*
*/
static const struct __initdata at91rm9200_smc_config
quad_uart_cs_config = {
.wait_states = 16,
.data_float_time = 0,
.byte_access_type = AT91RM9200_BAT_8_BIT,
.data_bus_width = AT91RM9200_DATA_BUS_WIDTH_8,
.data_read_protocol = AT91RM9200_DRP_STANDARD,
.address_to_cs_setup = AT91RM9200_ACSS_STANDARD,
.rw_setup = 2,
.rw_hold = 2
};
if (at91rm9200_smc_configure(CCM2200_QUAD_UART_CS,
&quad_uart_cs_config ) != 0 ) {
printk( KERN_ERR
"Unable to configure static memory controller\n" );
return -EIO;
}
I am new at ARM linux and not familiar with the naming conventions.
Please review the patch and give comments.
Best regards
Guido Classen
Signed-off-by: Guido Classen <clagix at gmail.com>
diff -Nrub '--exclude=*~'
linux-2.6.35-ccm2200/arch/arm/mach-at91/at91rm9200_smc.c
linux-2.6.35-rm9200_smc//arch/arm/mach-at91/at91rm9200_smc.c
--- linux-2.6.35-ccm2200/arch/arm/mach-at91/at91rm9200_smc.c 1970-01-01
01:00:00.000000000 +0100
+++ linux-2.6.35-rm9200_smc//arch/arm/mach-at91/at91rm9200_smc.c 2010-06-14
19:58:48.000000000 +0200
@@ -0,0 +1,88 @@
+/*
+ * linux/arch/arm/mach-at91/at91rm9200_smc.c
+ *
+ * Copyright (C) 2010 Guido Classen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/io.h>
+
+#include <mach/at91rm9200_mc.h>
+#include <mach/at91_pio.h>
+
+#include "at91rm9200_smc.h"
+
+int __init at91rm9200_smc_configure(int chip_select,
+ struct at91rm9200_smc_config *config)
+{
+ unsigned int mask;
+
+ /* check parameters */
+ if (chip_select < 0 || chip_select > 7
+ || config->wait_states > 128
+ || config->data_float_time > 15
+ || (config->byte_access_type != AT91RM9200_BAT_TWO_8_BIT
+ && config->byte_access_type != AT91RM9200_BAT_16_BIT)
+ || (config->data_read_protocol != AT91RM9200_DRP_STANDARD
+ && config->data_read_protocol != AT91RM9200_DRP_EARLY)
+ || config->address_to_cs_setup < AT91RM9200_ACSS_STANDARD
+ || config->address_to_cs_setup > AT91RM9200_ACSS_3_CYCLES
+ || config->rw_setup > 7
+ || config->rw_hold > 7)
+ return -EINVAL;
+
+
+ // configure gpios, if necessary
+ if (chip_select > 3)
+ {
+#define AT91C_PC10_NCS4_CFCS (1<<10)
+#define AT91C_PC11_NCS5_CFCE1 (1<<11)
+#define AT91C_PC12_NCS6_CFCE2 (1<<12)
+#define AT91C_PC13_NCS7 (1<<13)
+ switch (chip_select)
+ {
+ case 4: mask = AT91C_PC10_NCS4_CFCS; break;
+ case 5: mask = AT91C_PC11_NCS5_CFCE1; break;
+ case 6: mask = AT91C_PC12_NCS6_CFCE2; break;
+ case 7: mask = AT91C_PC13_NCS7; break;
+ default: mask = 0;
+ }
+ /* select peripheral a function */
+ at91_sys_write(AT91_PIOC + PIO_ASR, mask);
+
+ /* disable pio controller and enable peripheral */
+ at91_sys_write(AT91_PIOC + PIO_PDR, mask);
+ }
+
+ /* write the new configuration to SMC chip select register */
+ at91_sys_write(AT91_SMC_CSR(chip_select),
+ (config->wait_states > 0
+ ? (AT91_SMC_NWS & (config->wait_states-1))
+ | AT91_SMC_WSEN
+ : 0)
+ | AT91_SMC_TDF_(config->data_float_time)
+ | (config->byte_access_type == AT91RM9200_BAT_16_BIT
+ ? AT91_SMC_BAT : 0)
+ | ((int)config->data_bus_width << 13)
+ | (config->data_read_protocol == AT91RM9200_DRP_EARLY
+ ? AT91_SMC_DPR : 0)
+ | ((int)config->address_to_cs_setup << 16)
+ | AT91_SMC_RWSETUP_(config->rw_setup)
+ | AT91_SMC_RWHOLD_(config->rw_hold) );
+ return 0;
+}
diff -Nrub '--exclude=*~'
linux-2.6.35-ccm2200/arch/arm/mach-at91/at91rm9200_smc.h
linux-2.6.35-rm9200_smc//arch/arm/mach-at91/at91rm9200_smc.h
--- linux-2.6.35-ccm2200/arch/arm/mach-at91/at91rm9200_smc.h 1970-01-01
01:00:00.000000000 +0100
+++ linux-2.6.35-rm9200_smc//arch/arm/mach-at91/at91rm9200_smc.h 2010-06-14
19:51:15.000000000 +0200
@@ -0,0 +1,66 @@
+/*
+ * linux/arch/arm/mach-at91/at91rm9200_smc.h
+ *
+ * Copyright (C) 2010 Guido Classen
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+struct at91rm9200_smc_config {
+ /* wait states 0...128 (0 = no wait states) */
+ u8 wait_states;
+ /* 0...15 wait states after memory read cycle */
+ u8 data_float_time;
+
+ /* only valid for data_bus_width=AT91RM9200_DATA_BUS_WIDTH_16 */
+ enum byte_access_type {
+ /* dummy value for 8 bit device (ignored) */
+ AT91RM9200_BAT_8_BIT = 0,
+ /* chip select is connected to two/four 8-bit
+ * devices */
+ AT91RM9200_BAT_TWO_8_BIT = 0,
+ /* chip select is connected too a 16 bit device */
+ AT91RM9200_BAT_16_BIT = 1
+ } byte_access_type;
+
+ enum data_bus_width {
+ AT91RM9200_DATA_BUS_WIDTH_8 = 2, /* 8 bit data bus */
+ AT91RM9200_DATA_BUS_WIDTH_16 = 1, /* 16 bit data bus */
+ } data_bus_width;
+ enum data_read_protocol {
+ AT91RM9200_DRP_STANDARD = 0, /* standard data read protocol */
+ AT91RM9200_DRP_EARLY = 1 /* early data read protocol */
+ } data_read_protocol;
+
+ enum address_to_cs_setup {
+ /* standard: address asserted at the beginning of the
+ * access and deasserted at the end */
+ AT91RM9200_ACSS_STANDARD = 0,
+ /* one cycle less at the beginning and end */
+ AT91RM9200_ACSS_1_CYCLE = 1,
+ /* two cycles less at the beginning and end */
+ AT91RM9200_ACSS_2_CYCLES = 2,
+ /* three cycles less at the beginning and end */
+ AT91RM9200_ACSS_3_CYCLES = 3
+ } address_to_cs_setup;
+ /* 0...7 number of read/write setup cycles */
+ u8 rw_setup;
+ /* 0...7 number of read/write hold cycles */
+ u8 rw_hold;
+};
+
+extern int __init at91rm9200_smc_configure(int chip_select,
+ struct at91rm9200_smc_config *config);
diff -Nrub '--exclude=*~'
linux-2.6.35-ccm2200/arch/arm/mach-at91/Makefile
linux-2.6.35-rm9200_smc//arch/arm/mach-at91/Makefile
--- linux-2.6.35-ccm2200/arch/arm/mach-at91/Makefile 2010-06-14
16:31:35.000000000 +0200
+++ linux-2.6.35-rm9200_smc//arch/arm/mach-at91/Makefile 2010-06-14
19:45:24.000000000 +0200
@@ -10,7 +10,7 @@
obj-$(CONFIG_AT91_PMC_UNIT) += clock.o
# CPU-specific support
-obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o
at91rm9200_devices.o
+obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o
at91rm9200_devices.o at91rm9200_smc.o
obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o
at91sam9260_devices.o sam9_smc.o
obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o
at91sam9261_devices.o sam9_smc.o
obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam926x_time.o
at91sam9261_devices.o sam9_smc.o
More information about the linux-arm-kernel
mailing list