See comments inside the code for examples.
Signed-off-by: Holger Schurig <[email protected]>
--- haret.orig/Makefile
+++ haret/Makefile
@@ -98,7 +98,8 @@
HARETOBJS := $(COREOBJS) haret.o gpio.o uart.o wincmds.o \
watch.o irqchain.o irq.o pxatrace.o mmumerge.o l1trace.o arminsns.o \
- network.o terminal.o com_port.o tlhcmds.o memcmds.o pxacmds.o aticmds.o
+ network.o terminal.o com_port.o tlhcmds.o memcmds.o pxacmds.o aticmds.o \
+ imxcmds.o
$(OUT)haret-debug: $(addprefix $(OUT),$(HARETOBJS)) src/haret.lds
--- /dev/null
+++ haret/src/imxcmds.cpp
@@ -0,0 +1,253 @@
+/*
+ Commands specific to the i.MX21 processor
+ Copyright (C) 2009 Holger Schurig
+
+ For conditions of use see file COPYING
+*/
+
+#include "memory.h" // memPhysMap
+#include "output.h" // Output
+#include "script.h" // REG_xxx
+#include "arch-imx.h" // testIMX
+
+
+
+/*
+ * cmd_dump_eim() produces an output like this:
+ *
+ * BCD BCS DOL
+ * nCS addr SP WP DCT RWA PSZ PME SY RWN CNC WSC EW WWS EDC
+ * 0 c8000000 0 0 0 0 0 0 0 0 0 62 0 0 0
+ * 1 cc000000 0 0 0 0 0 0 0 0 0 12 0 0 0
+ * 2 d0000000 0 0 0 0 0 0 0 0 0 0 0 0 0
+ * 3 d1000000 0 0 0 0 0 0 0 0 0 0 0 0 0
+ * 4 d2000000 0 0 0 0 0 0 0 0 0 0 0 0 0
+ * 5 d3000000 0 0 0 0 0 0 0 0 0 63 0 0 0
+ *
+ * nCS addr OEA OEN WEA WEN CSA EBC DSZ CSN PSR CRE WRP EN
+ * 0 c8000000 2 0 0 0 0 1 [31:0] 0 0 0 0 1
+ * 1 cc000000 5 1 4 1 0 1 [23:16] 0 0 0 0 1
+ * 2 d0000000 0 0 0 0 0 0 [31:24] 0 0 0 0 0
+ * 3 d1000000 0 0 0 0 0 0 [31:24] 0 0 0 0 0
+ * 4 d2000000 0 0 0 0 0 0 [31:24] 0 0 0 0 0
+ * 5 d3000000 0 0 0 0 0 0 [31:16] 0 0 0 0 1
+ *
+ * This gives an overview over which external memory areas ("addr")
+ * are enabled ("EN") and use which bus-width ("DSZ"). For the
+ * rest of the column-meanings, refer to the i.MX21 Reference
+ * Manual, Chapter 20 "External Interface Module (EIM)".
+ */
+
+static void
+cmd_dump_eim(const char *cmd, const char *args)
+{
+ uint32 base = 0xdf001000;
+ int cs;
+
+ uint32 addr[6] = {
+ 0xc8000000,
+ 0xcc000000,
+ 0xd0000000,
+ 0xd1000000,
+ 0xd2000000,
+ 0xd3000000
+ };
+
+ Output(" BCD BCS DOL");
+ Output("nCS addr SP WP DCT RWA PSZ PME SY RWN CNC WSC EW WWS EDC");
+ for (cs=0; cs<=5; cs++) {
+ uint32 u = memPhysRead(base + cs*8);
+ Output("%d %08x "
+ "%2d %2d %3d %3d "
+ "%3d %3d %2d %3d "
+ "%3d %4d %2d %3d %3d",
+ cs, addr[cs],
+ (u >> 31) & 1, // SP
+ (u >> 30) & 1, // WP
+ (u >> 28) & 3, // BCD/DCT
+ (u >> 24) & 0xf, // BCS/RWA
+
+ (u >> 22) & 3, // PSZ
+ (u >> 21) & 1, // PME
+ (u >> 20) & 1, // SYNC
+ (u >> 16) & 0xf, // DOL/RWN
+
+ (u >> 14) & 3, // CNC
+ (u >> 8) & 0x3f, // WSC
+ (u >> 7) & 1, // EW
+ (u >> 4) & 7, // WWS
+
+ u & 0xf); // EDC
+ }
+ char* dsz[8] = {
+ "[31:24]", "[23:16]", "[15:8]", "[7:0]", // 8-bit modes
+ "[31:16]", "[15:0]", // 16-bit modes
+ "[31:0]", // 32-bit modes
+ "resrvd", // Reserved
+ };
+
+ Output("\r\nnCS addr OEA OEN WEA WEN CSA EBC DSZ CSN PSR CRE WRP
EN");
+ for (cs=0; cs<=5; cs++) {
+ uint32 l = memPhysRead(base + cs*8 + 4);
+ Output("%d %08x "
+ "%3d %3d %3d %3d "
+ "%3d %3d %7s %3d "
+ "%3d %3d %3d %2d",
+ cs, addr[cs],
+ (l >> 28) & 0xf, // OEA
+ (l >> 24) & 0xf, // OEN
+ (l >> 20) & 0xf, // WEA
+ (l >> 16) & 0xf, // WEN
+
+ (l >> 12) & 0xf, // CSA
+ (l >> 11) & 1, // EBC
+ dsz[(l >> 8) & 7], // DSZ
+ (l >> 4) & 0xf, // CSN
+
+ (l >> 3) & 1, // PSR
+ (l >> 2) & 1, // CRE
+ (l >> 1) & 1, // WRAP
+ l & 1); // CSEN
+ }
+}
+
+REG_DUMP(testIMX, "EIM", cmd_dump_eim,
+ "EIM\n"
+ " Display the configuration of the EIM (External Interface Module)")
+
+
+/*
+ * The i.MX21 has 6 blocks with 32 GPIOs each. So says the manual,
+ * but that is not true, e.g. GPIO A3 doesn't go to any pin :-)
+ * The pins have a quite complex logic with a "IOMUX" and "GPIO"
+ * block, that allow any pin to be connected the GPIO registers
+ * or to internal function lines ("A_IN", "B_IN", "C_IN", "A_OUT"
+ * and "B_OUT").
+ *
+ * I think it's overly complex to find out if a pin has this or
+ * that function ... therefore the extensive dump function here.
+ *
+ *
+ * For more info, refer to chapter 15 "General-Purpose I/O (GPIO)"
+ * as well as to chapter 2.2 "I/O Power Supply and Signal
+ * Multiplexing Scheme". In the example below, you've to look
+ * into chapter 2.2 to find out what the primary function for
+ * pin "PE 9" is.
+ *
+ * An abbreviated sample output of "DUMP EIM" looks like this:
+ *
+ * Pin Function GIUS GPR DDIR OCR A_OUT DR SSR ICR Int PUEN
+ * ...
+ * PE 9 primary mux prim in DR one 0 1 rise dis 1
+ * PE10 GPIO_I GPIO prim in B_IN one 0 0 rise ENA 1
+ * PE11 GPIO_O GPIO ALT OUT B_IN one 0 0 rise dis 0
+ *
+ *
+ * DDIR OCR1 OCR2 ICONFA1 ICONFA2 DR
+ * PFA 80000000 00000000 c0000000 ffffffff ffffffff 80000000
+ * PFB 000003a0 000fcc00 00000000 ffffffff ffffffff 00000190
+ * PFC 01104000 30000000 00030300 fffcffff ffffffff 01100000
+ * PFD 06000000 00000000 003c0000 ffffffff ffffffff 14000000
+ * PFE 00030806 00c00c3c 0000000f ffffffff ffffffff 00030020
+ * PFF 00010000 00000000 00000003 ffffffff fffff3ff 00010000
+ *
+ * GIUS SSR ICR1 ICR2 IMASK GPR PUEN
+ * PFA 00000000 a3c30c00 00000000 00000000 00000000 00000000 ffffffff
+ * PFB fe8003f0 2fd10190 00000000 04340000 26000000 000003a0 cffffcdf
+ * PFC 0ff0c100 17fbab60 00000000 00040000 02000000 01104000 feef811f
+ * PFD 5ff80000 75360000 00000000 3001a780 49f80000 06000000 f1ffffff
+ * PFE 0003cc06 007ff2e0 00200000 00000000 00000400 00030806 ff3cb7f9
+ * PFF 00210000 00617fe7 00000000 00000000 00000000 00010000 fffeffff
+ *
+ */
+
+static void
+cmd_dump_gpio(const char *cmd, const char *args)
+{
+ char* ocr[4] = {"A_IN", "B_IN", "C_IN", "DR" };
+ char* iconf[4] = {"pin", "ISR", "zero", "one" };
+ char* icr[4] = {"rise", "fall", "high", "low"};
+
+ uint32 store[6][15];
+
+ int fb;
+ for (fb=0; fb<6; fb++) {
+ uint32 base = 0x10015000 + 0x100*fb;
+ uint32 ddir = store[fb][ 0] = memPhysRead(base);
+ uint32 ocr1 = store[fb][ 1] = memPhysRead(base+4);
+ uint32 ocr2 = store[fb][ 2] = memPhysRead(base+8);
+ uint32 iconfa1 = store[fb][ 3] = memPhysRead(base+0x0c);
+ uint32 iconfa2 = store[fb][ 4] = memPhysRead(base+0x10);
+ // The i.MX21 has the ICONFB registers, but there's no GPIO
+ // with a B_OUT function according to chapter 2.2 of the
+ // reference manual
+ //uint32 iconfb1 = store[fb][ 5] = memPhysRead(base+0x14);
+ //uint32 iconfb2 = store[fb][ 6] = memPhysRead(base+0x18);
+ uint32 dr = store[fb][ 7] = memPhysRead(base+0x1c);
+ uint32 gius = store[fb][ 8] = memPhysRead(base+0x20);
+ uint32 ssr = store[fb][ 9] = memPhysRead(base+0x24);
+ uint32 icr1 = store[fb][10] = memPhysRead(base+0x28);
+ uint32 icr2 = store[fb][11] = memPhysRead(base+0x2c);
+ uint32 imask = store[fb][12] = memPhysRead(base+0x30);
+ uint32 gpr = store[fb][13] = memPhysRead(base+0x38);
+ uint32 puen = store[fb][14] = memPhysRead(base+0x40);
+
+ Output("\r\nPin Function GIUS GPR DDIR OCR A_OUT DR SSR ICR
Int PUEN");
+ for (int gpio=0; gpio<=31; gpio++) {
+
+ // The following code more or less decodes the IOMUX
part
+ const char *function;
+ int is_out = (ddir >> gpio) & 1;
+ int is_gpio = (gius >> gpio) & 1;
+ int is_alt = (gpr >> gpio) & 1;
+ if (is_gpio)
+ function = is_out ? "GPIO_O" : "GPIO_I";
+ else {
+ function = is_alt ? "alt" : "primary";
+ }
+
+ Output("P%c%2d %7s "
+ "%4s %4s %4s "
+ "%4s %5s "
+ "%2d %3d %4s "
+ "%3s %4d",
+
+ 'A'+fb, gpio, function,
+
+ is_gpio ? "GPIO" : "mux",
+ is_alt ? "ALT" : "prim",
+ is_out ? "OUT" : "in",
+
+ ocr[(gpio < 16 ? ocr1 : ocr2) >> (gpio>>1) & 3],
+ iconf[(gpio < 16 ? iconfa1 : iconfa2) >>
(gpio>>1) & 3],
+ //iconf[(gpio < 16 ? iconfb1 : iconfb2) >>
(gpio>>1) & 3],
+
+ (dr >> gpio) & 1,
+ (ssr >> gpio) & 1,
+ icr[(gpio < 16 ? icr1 : icr2) >> (gpio>>1) & 3],
+
+ (imask >> gpio) & 1 ? "ENA" : "dis",
+ (puen >> gpio) & 1
+ );
+ }
+ }
+
+ Output("\r\n DDIR OCR1 OCR2 ICONFA1 ICONFA2 DR");
+ for (fb=0; fb<6; fb++) {
+ Output("PF%c %08x %08x %08x %08x %08x %08x",
+ 'A'+fb,
+ store[fb][0], store[fb][1], store[fb][2], store[fb][3],
+ store[fb][4], store[fb][7]);
+ }
+ Output("\r\n GIUS SSR ICR1 ICR2 IMASK GPR
PUEN");
+ for (fb=0; fb<6; fb++) {
+ Output("PF%c %08x %08x %08x %08x %08x %08x %08x",
+ 'A'+fb,
+ store[fb][8], store[fb][9], store[fb][10],
store[fb][11],
+ store[fb][12], store[fb][13], store[fb][14]);
+ }
+}
+
+REG_DUMP(testIMX, "GPIO", cmd_dump_gpio,
+ "GPIO\n"
+ " Display the configuration of the GPIOs")
_______________________________________________
Haret mailing list
[email protected]
https://handhelds.org/mailman/listinfo/haret