]> git.kernelconcepts.de Git - karo-tx-uboot.git/commitdiff
Merge branch 'master' of git://git.denx.de/u-boot-i2c
authorWolfgang Denk <wd@denx.de>
Wed, 20 Apr 2011 20:48:47 +0000 (22:48 +0200)
committerWolfgang Denk <wd@denx.de>
Wed, 20 Apr 2011 20:48:47 +0000 (22:48 +0200)
81 files changed:
arch/powerpc/config.mk
arch/powerpc/cpu/74xx_7xx/start.S
arch/powerpc/cpu/mpc512x/start.S
arch/powerpc/cpu/mpc5xx/start.S
arch/powerpc/cpu/mpc5xxx/start.S
arch/powerpc/cpu/mpc8220/start.S
arch/powerpc/cpu/mpc824x/start.S
arch/powerpc/cpu/mpc8260/start.S
arch/powerpc/cpu/mpc83xx/start.S
arch/powerpc/cpu/mpc85xx/start.S
arch/powerpc/cpu/mpc86xx/start.S
arch/powerpc/cpu/mpc8xx/start.S
arch/powerpc/cpu/ppc4xx/start.S
board/LEOX/elpt860/u-boot.lds
board/RPXClassic/u-boot.lds
board/RPXlite/u-boot.lds
board/RPXlite_dw/u-boot.lds
board/RRvision/u-boot.lds
board/adder/u-boot.lds
board/amirix/ap1000/u-boot.lds
board/c2mon/u-boot.lds
board/cogent/u-boot.lds
board/dave/PPChameleonEVB/u-boot.lds
board/eltec/mhpc/u-boot.lds
board/emk/top860/u-boot.lds
board/ep88x/u-boot.lds
board/esd/dasa_sim/u-boot.lds
board/esteem192e/u-boot.lds
board/etx094/u-boot.lds
board/evb64260/u-boot.lds
board/fads/u-boot.lds
board/flagadm/u-boot.lds
board/gen860t/u-boot.lds
board/genietv/u-boot.lds
board/hermes/u-boot.lds
board/hymod/u-boot.lds
board/icu862/u-boot.lds
board/ip860/u-boot.lds
board/ivm/u-boot.lds
board/kup/kup4k/u-boot.lds
board/kup/kup4x/u-boot.lds
board/lantec/u-boot.lds
board/lwmon/u-boot.lds
board/manroland/uc100/u-boot.lds
board/matrix_vision/mvsmr/u-boot.lds
board/mbx8xx/u-boot.lds
board/ml2/u-boot.lds
board/mousse/u-boot.lds
board/mvblue/u-boot.lds
board/netphone/u-boot.lds
board/netta/u-boot.lds
board/netta2/u-boot.lds
board/netvia/u-boot.lds
board/nx823/u-boot.lds
board/quantum/u-boot.lds
board/r360mpi/u-boot.lds
board/rbc823/u-boot.lds
board/rmu/u-boot.lds
board/rsdproto/u-boot.lds
board/sandpoint/u-boot.lds
board/sc3/u-boot.lds
board/siemens/IAD210/u-boot.lds
board/sixnet/u-boot.lds
board/snmc/qs850/u-boot.lds
board/snmc/qs860t/u-boot.lds
board/spc1920/u-boot.lds
board/spd8xx/u-boot.lds
board/stx/stxxtc/u-boot.lds
board/svm_sc8xx/u-boot.lds
board/tqc/tqm8xx/u-boot.lds
board/v37/u-boot.lds
board/westel/amx860/u-boot.lds
common/Makefile
common/cmd_mmc.c
common/cmd_mmc_spi.c [new file with mode: 0644]
drivers/mmc/Makefile
drivers/mmc/fsl_esdhc.c
drivers/mmc/mmc.c
drivers/mmc/mmc_spi.c [new file with mode: 0644]
drivers/spi/cf_spi.c
include/mmc.h

index 3afc439e58c575d1d92da994badcbbd1da8dbbc2..e682071bd73f477f957d9863627cf03c7150839b 100644 (file)
@@ -26,8 +26,6 @@ CROSS_COMPILE ?= ppc_8xx-
 CONFIG_STANDALONE_LOAD_ADDR ?= 0x40000
 LDFLAGS_FINAL += --gc-sections
 PLATFORM_RELFLAGS += -fpic -mrelocatable -ffunction-sections -fdata-sections
-PLATFORM_RELFLAGS += $(call cc-option,-msingle-pic-base,)
-PLATFORM_RELFLAGS += $(call cc-option,-fno-jump-tables,)
 PLATFORM_CPPFLAGS += -DCONFIG_PPC -D__powerpc__
 PLATFORM_LDFLAGS  += -n
 
index ab9412ad9e2a1b2d48c096e62c6f4f272fa5898d..f6011fcaa8c1e654ac13edafa012bc8e2296b072 100644 (file)
@@ -274,11 +274,7 @@ in_flash:
        stwu    r0, -4(r1)      /* stack backtraces terminate cleanly   */
 
        GET_GOT                 /* initialize GOT access        */
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
+
        /* run low-level CPU init code     (from Flash) */
        bl      cpu_init_f
        sync
@@ -592,11 +588,6 @@ relocate_code:
        mr      r10, r5         /* Save copy of Destination Address     */
 
        GET_GOT
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
        mr      r3,  r5                         /* Destination Address  */
        lis     r4, CONFIG_SYS_MONITOR_BASE@h           /* Source      Address  */
        ori     r4, r4, CONFIG_SYS_MONITOR_BASE@l
index 632f9674c8e5b00cada62f17a765b3d595de52a4..9c2e4885dedbfdb89ab2515952bda60c1f217cf7 100644 (file)
@@ -255,11 +255,7 @@ in_flash:
        /*------------------------------------------------------*/
 
        GET_GOT                 /* initialize GOT access        */
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
+
        /* r3: IMMR */
        lis     r3, CONFIG_SYS_IMMR@h
        /* run low-level CPU init code (in Flash) */
@@ -490,11 +486,6 @@ relocate_code:
        mr      r10, r5         /* Save copy of Destination Address */
 
        GET_GOT
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
        mr      r3,  r5                         /* Destination Address */
        lis     r4, CONFIG_SYS_MONITOR_BASE@h           /* Source      Address */
        ori     r4, r4, CONFIG_SYS_MONITOR_BASE@l
index 4fb2047da47fec33f7eb8e35dfedf078e6bddabe..cc11c8fc528537a1b4f39dd3d20e7e3f5aca92a3 100644 (file)
@@ -174,11 +174,7 @@ in_flash:
        /*----------------------------------------------------------------------*/
 
        GET_GOT                 /* initialize GOT access                        */
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
+
        /* r3: IMMR */
        bl      cpu_init_f      /* run low-level CPU init code     (from Flash) */
 
@@ -367,11 +363,6 @@ relocate_code:
        mr      r10, r5         /* Save copy of monitor destination Address in SRAM */
 
        GET_GOT
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
        mr      r3,  r5                         /* Destination Address  */
        lis     r4, CONFIG_SYS_MONITOR_BASE@h           /* Source      Address  */
        ori     r4, r4, CONFIG_SYS_MONITOR_BASE@l
index 0a0536119a6428faf418cdf13baa82afe2e8a7e1..192aa506a8883d9c2f7ba117370e245d875fa9b2 100644 (file)
@@ -160,11 +160,7 @@ lowboot_reentry:
        /*--------------------------------------------------------------*/
 
        GET_GOT                 /* initialize GOT access                */
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
+
        /* r3: IMMR */
        bl      cpu_init_f      /* run low-level CPU init code (in Flash)*/
 
@@ -553,11 +549,6 @@ relocate_code:
        mr      r10, r5         /* Save copy of Destination Address     */
 
        GET_GOT
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
        mr      r3,  r5                         /* Destination Address  */
        lis     r4, CONFIG_SYS_MONITOR_BASE@h           /* Source      Address  */
        ori     r4, r4, CONFIG_SYS_MONITOR_BASE@l
index 1df87a6afd4325c46a29350ba83f19ec7ef226e8..300b35c0c4f55c0a9830132e7281194f31f002e0 100644 (file)
@@ -129,11 +129,7 @@ _start:
        /*--------------------------------------------------------------*/
 
        GET_GOT                 /* initialize GOT access                */
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
+
        /* r3: IMMR */
        bl      cpu_init_f      /* run low-level CPU init code (in Flash)*/
 
@@ -526,11 +522,6 @@ relocate_code:
        mr      r10, r5     /* Save copy of Destination Address */
 
        GET_GOT
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
        mr      r3,  r5     /* Destination Address              */
        lis     r4, CONFIG_SYS_MONITOR_BASE@h   /* Source Address       */
        ori     r4, r4, CONFIG_SYS_MONITOR_BASE@l
index cc988759e0ae02b2c35eebded59db08a9a24e39c..fc4e922d633d15d2f09626223265189fe62cbc24 100644 (file)
@@ -183,11 +183,7 @@ in_flash:
        /*----------------------------------------------------------------------*/
 
        GET_GOT                 /* initialize GOT access                        */
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
+
        /* r3: IMMR */
        bl      cpu_init_f      /* run low-level CPU init code     (from Flash) */
 
@@ -456,11 +452,6 @@ relocate_code:
        mr      r10, r5         /* Save copy of Destination Address     */
 
        GET_GOT
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
        mr      r3,  r5                         /* Destination Address  */
 #ifdef CONFIG_SYS_RAMBOOT
        lis     r4, CONFIG_SYS_SDRAM_BASE@h             /* Source      Address  */
index 23151cdadf7c975fd71ab4faf228c259cf88dc02..702546eec5c566593f784ca6b3e5c38d6b9f1552 100644 (file)
@@ -236,11 +236,7 @@ in_flash:
        /*--------------------------------------------------------------*/
 
        GET_GOT                 /* initialize GOT access                */
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
+
        /* r3: IMMR */
        bl      cpu_init_f      /* run low-level CPU init code (in Flash)*/
 
index a9acb83f0b1cdd4fb55a5375ca6f3b06a6e5f60f..7e60315c3f446fb40f59ac1e2f96fe990de3210b 100644 (file)
@@ -285,11 +285,7 @@ in_flash:
        /*------------------------------------------------------*/
 
        GET_GOT                 /* initialize GOT access        */
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
+
        /* r3: IMMR */
        lis     r3, CONFIG_SYS_IMMR@h
        /* run low-level CPU init code (in Flash)*/
@@ -826,11 +822,6 @@ relocate_code:
        mr      r10, r5         /* Save copy of Destination Address */
 
        GET_GOT
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
        mr      r3,  r5                         /* Destination Address */
        lis     r4, CONFIG_SYS_MONITOR_BASE@h           /* Source      Address */
        ori     r4, r4, CONFIG_SYS_MONITOR_BASE@l
index 36233578f73629094574d925ce79d7e498966861..57774933a3dbe5819d0118336444551aa5c15173 100644 (file)
@@ -421,11 +421,6 @@ _start_cont:
        stw     r0,+12(r1)              /* Save return addr (underflow vect) */
 
        GET_GOT
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
        bl      cpu_init_early_f
 
        /* switch back to AS = 0 */
@@ -926,11 +921,6 @@ relocate_code:
        mr      r10,r5          /* Save copy of Destination Address     */
 
        GET_GOT
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
        mr      r3,r5                           /* Destination Address  */
        lis     r4,CONFIG_SYS_MONITOR_BASE@h            /* Source      Address  */
        ori     r4,r4,CONFIG_SYS_MONITOR_BASE@l
index 2ec7fd46b00cb5a064b2d044aff247b6eb5f8162..3e3c21eefd2d16561bee9308f1cd4e85e940a0ab 100644 (file)
@@ -255,11 +255,7 @@ addr_trans_enabled:
        stwu    r0, -4(r1)      /* stack backtraces terminate cleanly   */
 
        GET_GOT                 /* initialize GOT access        */
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
+
        /* run low-level CPU init code     (from Flash) */
        bl      cpu_init_f
        sync
@@ -624,11 +620,6 @@ relocate_code:
        mr      r10, r5         /* Save copy of Destination Address     */
 
        GET_GOT
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
        mr      r3,  r5                         /* Destination Address  */
        lis     r4, CONFIG_SYS_MONITOR_BASE@h           /* Source      Address  */
        ori     r4, r4, CONFIG_SYS_MONITOR_BASE@l
index f8256bff995683e235e8f4273330878c2db3eb37..fe3daa2b9f79a8e0c62347aec7b59edba7f641ca 100644 (file)
@@ -188,11 +188,7 @@ in_flash:
        /*----------------------------------------------------------------------*/
 
        GET_GOT                 /* initialize GOT access                        */
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
+
        /* r3: IMMR */
        bl      cpu_init_f      /* run low-level CPU init code     (from Flash) */
 
@@ -477,11 +473,6 @@ relocate_code:
        mr      r10, r5         /* Save copy of Destination Address     */
 
        GET_GOT
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
        mr      r3,  r5                         /* Destination Address  */
        lis     r4, CONFIG_SYS_MONITOR_BASE@h           /* Source      Address  */
        ori     r4, r4, CONFIG_SYS_MONITOR_BASE@l
index aa03d9a770c17513170e32e81f8c655dd2b9c2a3..b43e22c8f04d772f52e9d99123b0258828cd5cbf 100644 (file)
        bl      reconfig_tlb0
 #endif
        GET_GOT
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
        bl      cpu_init_f      /* run low-level CPU init code     (from Flash) */
        bl      board_init_f
        /* NOTREACHED - board_init_f() does not return */
@@ -804,11 +799,7 @@ _start:
        ori     r0,r0, RESET_VECTOR@l
        stwu    r1,-8(r1)               /* Save back chain and move SP */
        stw     r0,+12(r1)              /* Save return addr (underflow vect) */
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
+
 #ifdef CONFIG_NAND_SPL
        bl      nand_boot_common        /* will not return */
 #else
@@ -923,11 +914,7 @@ _start:
        stwu    r0, -4(r1)              /* stack backtraces terminate cleanly   */
 
        GET_GOT                 /* initialize GOT access                        */
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
+
        bl      board_init_f    /* run first part of init code (from Flash)     */
        /* NOTREACHED - board_init_f() does not return */
 
@@ -1192,11 +1179,6 @@ _start:
        stw     r0, +12(r1)             /* Save return addr (underflow vect) */
 #endif /* CONFIG_SYS_INIT_DCACHE_CS */
 
-#if defined(__pic__) && __pic__ == 1
-       /* Needed for upcoming -msingle-pic-base */
-       bl      _GLOBAL_OFFSET_TABLE_@local-4
-       mflr    r30
-#endif
 #ifdef CONFIG_NAND_SPL
        bl      nand_boot_common        /* will not return */
 #else
index 45206ca3bd1de0f9acf20fc99592ebc92ff00700..5aaf6b309d8eda7be637e2b352af588d727418fa 100644 (file)
@@ -67,13 +67,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 05cc2338ab609f92188159a24abab86513ba4c22..d0b60cf7c1079f4642fb63a032b0e40d9f9d34b3 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 05cc2338ab609f92188159a24abab86513ba4c22..d0b60cf7c1079f4642fb63a032b0e40d9f9d34b3 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 05cc2338ab609f92188159a24abab86513ba4c22..d0b60cf7c1079f4642fb63a032b0e40d9f9d34b3 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 3e7853a2a07a3a3f10536514826b8fe705381e27..838537375b3fefd55c8cb2359787b2553282d3fb 100644 (file)
@@ -52,13 +52,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 661a94ab153f951664682317e0305014399d3f18..a7627699e76f04cd15cf086b55b28b2aec0465e5 100644 (file)
@@ -43,13 +43,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
 
   .data    :
index 57fe1d9ce0861397db3d28672c0d1a8322316877..cd8f5cebab5a6b88a82ede61525587f24d9cadf3 100644 (file)
@@ -49,13 +49,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 524c36eb4b490d8f8d82e3d07a1284d7af384c3f..b9b8e3c727420129f506cac912430025c8f78756 100644 (file)
@@ -55,13 +55,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index e324f5c1e66ce12208383de78af0ce3157054140..2393d8d8af67d02e351d843cd2f31483048561d0 100644 (file)
@@ -51,13 +51,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 20c32b73e3cb6a8925a025a6bc7fd0aacd966889..3b1011435405e3ff2dfe96aa7912248349b6e91b 100644 (file)
@@ -55,9 +55,10 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
index 2fac727b84f6933997ccffe91eed55c185098cf6..fd4e8a50d543a62df0422cdb6c30af81e7cd8752 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 32dcbd3ef51304fa9b27f7f60c0a9f837c75c318..fb066486633a8b184ccd5a503ee19a64169e5d43 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index e2dd1c20f2c4242309993664e8cd8f62a516564f..332b35a57d68bba3be2dd450bac71168348813ed 100644 (file)
@@ -43,9 +43,10 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
index 2bf60f5804a0cb670d39652b11a7772f7187d1cf..b15948d34c7d3a58d469171ab17005efd3bf856f 100644 (file)
@@ -54,13 +54,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 8455f0b9f4098b252d8a01c8ac92cdfa51b092ff..163b83d8199d0fc4941407c2760b711a3f823dc1 100644 (file)
@@ -56,13 +56,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 04233d86a1d3d824e22fb83a6a3dc43c552e213c..b68d9eadcc4deb380b5b75767948ccc1765ec374 100644 (file)
@@ -56,13 +56,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 0648f62feb8be65ba6b6048ee5d0d38062f7a103..2d031efc4e93fde4868428ff775c7fba6f65a9cb 100644 (file)
@@ -51,13 +51,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 63d0ea112100736defc502caa41d27b4c74fac0a..9ea0674b887a40b588821eb4c8082984a986c164 100644 (file)
@@ -49,13 +49,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 2fac727b84f6933997ccffe91eed55c185098cf6..fd4e8a50d543a62df0422cdb6c30af81e7cd8752 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 8e854db22d81f3a62637cd1dbbc23e8a68421ee0..be99b512088fc0a84425efcb73e7894dc79731b3 100644 (file)
@@ -52,13 +52,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 3e396e4fae75a711135ad6f7a0155490de582563..1d66a9b2bda15f129b7480b5d3a121c12f72ec87 100644 (file)
@@ -61,13 +61,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index d50c5865b175959174fcf316a7424772c123bb9d..ca9711575d31af81e7d6a07533bac77b389d8045 100644 (file)
@@ -53,13 +53,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 1592f4f6e8ceeb6a9c2c1c82fb97794298e9106f..1efa8b3237d35b54a24db68d378b04bbd1446813 100644 (file)
@@ -93,7 +93,7 @@ SECTIONS
     _FIXUP_TABLE_ = .;
     *(.fixup)
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index cb5afc113b804418c42f01bc4201012b40193622..93c79a64b4eddb5d8ef1865ac40f4086f3cf01ab 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 05cc2338ab609f92188159a24abab86513ba4c22..d0b60cf7c1079f4642fb63a032b0e40d9f9d34b3 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index ff7012afbc230d766971babdef87464afd9a8dd1..1e843eb24ed300f6845cc4410e73649a97cb5f97 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 05cc2338ab609f92188159a24abab86513ba4c22..d0b60cf7c1079f4642fb63a032b0e40d9f9d34b3 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 05cc2338ab609f92188159a24abab86513ba4c22..d0b60cf7c1079f4642fb63a032b0e40d9f9d34b3 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 25e7a4def20fda10e7a21748122e32d7214f5bd0..de0b355a6287a6ecb69c62a62ec4cf22a4215cf7 100644 (file)
@@ -56,13 +56,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index d02db17ccb50d6b9c474aee5bf41bb139b5381a6..8bf7324f37a240d4c111c2d8690e5c84ff97261c 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 344cbde3b0774f77b21a03a5c7b7506dcb47d643..731cec9af70bc3d67f1942c885656ac9a6299832 100644 (file)
@@ -50,13 +50,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index f3d01e73f0450ad798b882dd01115309f42d861d..bf2ed0485212642c7c4aa0976df677144c7216bc 100644 (file)
@@ -55,9 +55,10 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
index 05cc2338ab609f92188159a24abab86513ba4c22..d0b60cf7c1079f4642fb63a032b0e40d9f9d34b3 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 0f2593de89096db713ec0e19d19a157d25c240cf..9f9ddb8bf0166c617603c9ae80e21e6c79a09913 100644 (file)
@@ -44,13 +44,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index ef73e2b53ababd90b3c797bcadea44b75b4d9db8..dae2cfc7dae8b6dbd11b88ca2e851b52c72a639c 100644 (file)
@@ -41,13 +41,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
 
   .data    :
index 03ba15578bdd40738bd4c97a2d4c740dba6346b9..11624d21f5412c85461bf2530488fa5fc5d81e50 100644 (file)
@@ -51,13 +51,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
 
   .data    :
index b7b6c1aa14aeb286ad40d92c46a264f40a1225f1..a949e4f59201a000a805c9ae0746ca767246344d 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index b7b6c1aa14aeb286ad40d92c46a264f40a1225f1..a949e4f59201a000a805c9ae0746ca767246344d 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index b7b6c1aa14aeb286ad40d92c46a264f40a1225f1..a949e4f59201a000a805c9ae0746ca767246344d 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index b7b6c1aa14aeb286ad40d92c46a264f40a1225f1..a949e4f59201a000a805c9ae0746ca767246344d 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 2fac727b84f6933997ccffe91eed55c185098cf6..fd4e8a50d543a62df0422cdb6c30af81e7cd8752 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 05cc2338ab609f92188159a24abab86513ba4c22..d0b60cf7c1079f4642fb63a032b0e40d9f9d34b3 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 60b3cbfaca2fd37d93e894c7e9ae5a8933da61e7..2fa085a3d9bf90698167952f0c514d41c82d6be9 100644 (file)
@@ -49,13 +49,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 7b790ab9fd570d961ea0a5caf6eadcf4782e388a..d943fb6de73860b15070fcfa27b593e0f7770e39 100644 (file)
@@ -58,13 +58,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 05cc2338ab609f92188159a24abab86513ba4c22..d0b60cf7c1079f4642fb63a032b0e40d9f9d34b3 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index b36047ad5e8a5d4f7a982337e6c85846cdbe4724..81728db25c3118ca13d48d5a46731c38fc9cd1f4 100644 (file)
@@ -80,7 +80,7 @@ SECTIONS
     _FIXUP_TABLE_ = .;
     *(.fixup)
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 841a29b60c85ee7ad4af1df52a01f30f34d623ea..e382fd1a1e667de44ba416e0f03337d6de51da74 100644 (file)
@@ -49,13 +49,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >> 2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_) >> 2;
 
   .data    :
index 2cbbca50e5c87a7a6b1010624904c8f9f9ed98ab..4db46cacf2a76e9173432fed1701266ca3fed44b 100644 (file)
@@ -96,13 +96,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    *(.got)
     _GOT2_TABLE_ = .;
     *(.got2)
+    *(.got)
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     *(.fixup)
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 725bef8293c1768643ee15c8bc09278513583da8..0e78e4fd477ce6ca1fb69f620b407a8b6776fc24 100644 (file)
@@ -56,13 +56,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 2711f2c4087d396b167e53008c0ecdcb0fc26a7e..02d198001fd5d368ee8bff736aa624fe99ced201 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 007ae00f46e89e9cf9caa579e428b3d03cac1763..9ab248a4e97f8ad12f2aefcb165360d217935c34 100644 (file)
@@ -50,13 +50,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 05cc2338ab609f92188159a24abab86513ba4c22..d0b60cf7c1079f4642fb63a032b0e40d9f9d34b3 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 05cc2338ab609f92188159a24abab86513ba4c22..d0b60cf7c1079f4642fb63a032b0e40d9f9d34b3 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 796c283b344cc56441b8874f0a3e36c059132fc7..950e1e6e2cb8af441c37015cab6392fc794ef77d 100644 (file)
@@ -57,13 +57,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index b7b6c1aa14aeb286ad40d92c46a264f40a1225f1..a949e4f59201a000a805c9ae0746ca767246344d 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index c4ce968735c403dbd303e6288585c14a793d5b08..c65f0228c3fd6f8e86b5e4164ced2476a9383d59 100644 (file)
@@ -63,13 +63,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 83a09b047168fd007cbf4c82f4d641205673e13f..f625c3dbdf3dfd7200c87e440279c52bfcafe982 100644 (file)
@@ -63,13 +63,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 578a49b04bc640f7b094c462399c1b6ff3f46569..e62d53db54fa048d4c0966f06dde05b6bbfb29f5 100644 (file)
@@ -47,13 +47,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 3514a66d6872fe5438db7c6d72f98eef5f0edff1..3470b437e82583a8e7b39f62451c357d488585d7 100644 (file)
@@ -56,13 +56,14 @@ SECTIONS
   PROVIDE (erotext = .);
   .reloc   :
   {
-    KEEP(*(.got))
     _GOT2_TABLE_ = .;
     KEEP(*(.got2))
+    KEEP(*(.got))
+    PROVIDE(_GLOBAL_OFFSET_TABLE_ = . + 4);
     _FIXUP_TABLE_ = .;
     KEEP(*(.fixup))
   }
-  __got2_entries = (_FIXUP_TABLE_ - _GOT2_TABLE_) >>2;
+  __got2_entries = ((_GLOBAL_OFFSET_TABLE_ - _GOT2_TABLE_) >> 2) - 1;
   __fixup_entries = (. - _FIXUP_TABLE_)>>2;
 
   .data    :
index 4555716108262abd8fc14463c91e5f1e9a399e74..6f41ce4397d7a4a791aeca4c567e3fa5c6965edc 100644 (file)
@@ -118,6 +118,7 @@ COBJS-$(CONFIG_CMD_MII) += miiphyutil.o
 COBJS-$(CONFIG_CMD_MII) += cmd_mii.o
 COBJS-$(CONFIG_CMD_MISC) += cmd_misc.o
 COBJS-$(CONFIG_CMD_MMC) += cmd_mmc.o
+COBJS-$(CONFIG_CMD_MMC_SPI) += cmd_mmc_spi.o
 COBJS-$(CONFIG_MP) += cmd_mp.o
 COBJS-$(CONFIG_CMD_MTDPARTS) += cmd_mtdparts.o
 COBJS-$(CONFIG_CMD_NAND) += cmd_nand.o
index 4323f76b30549cb0a83b19c8c95b755259d2af14..6166749ad5a5c81d85585bae5976bcfdc97a6681 100644 (file)
@@ -104,7 +104,8 @@ static void print_mmcinfo(struct mmc *mmc)
                        (mmc->version >> 4) & 0xf, mmc->version & 0xf);
 
        printf("High Capacity: %s\n", mmc->high_capacity ? "Yes" : "No");
-       printf("Capacity: %lld\n", mmc->capacity);
+       puts("Capacity: ");
+       print_size(mmc->capacity, "\n");
 
        printf("Bus Width: %d-bit\n", mmc->bus_width);
 }
diff --git a/common/cmd_mmc_spi.c b/common/cmd_mmc_spi.c
new file mode 100644 (file)
index 0000000..63fe313
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Command for mmc_spi setup.
+ *
+ * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw>
+ * Licensed under the GPL-2 or later.
+ */
+
+#include <common.h>
+#include <mmc.h>
+#include <spi.h>
+
+#ifndef CONFIG_MMC_SPI_BUS
+# define CONFIG_MMC_SPI_BUS 0
+#endif
+#ifndef CONFIG_MMC_SPI_CS
+# define CONFIG_MMC_SPI_CS 1
+#endif
+/* in SPI mode, MMC speed limit is 20MHz, while SD speed limit is 25MHz */
+#ifndef CONFIG_MMC_SPI_SPEED
+# define CONFIG_MMC_SPI_SPEED 25000000
+#endif
+/* MMC and SD specs only seem to care that sampling is on the
+ * rising edge ... meaning SPI modes 0 or 3.  So either SPI mode
+ * should be legit.  We'll use mode 0 since the steady state is 0,
+ * which is appropriate for hotplugging, unless the platform data
+ * specify mode 3 (if hardware is not compatible to mode 0).
+ */
+#ifndef CONFIG_MMC_SPI_MODE
+# define CONFIG_MMC_SPI_MODE SPI_MODE_0
+#endif
+
+static int do_mmc_spi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+       uint bus = CONFIG_MMC_SPI_BUS;
+       uint cs = CONFIG_MMC_SPI_CS;
+       uint speed = CONFIG_MMC_SPI_SPEED;
+       uint mode = CONFIG_MMC_SPI_MODE;
+       char *endp;
+       struct mmc *mmc;
+
+       if (argc < 2)
+               goto usage;
+
+       cs = simple_strtoul(argv[1], &endp, 0);
+       if (*argv[1] == 0 || (*endp != 0 && *endp != ':'))
+               goto usage;
+       if (*endp == ':') {
+               if (endp[1] == 0)
+                       goto usage;
+               bus = cs;
+               cs = simple_strtoul(endp + 1, &endp, 0);
+               if (*endp != 0)
+                       goto usage;
+       }
+       if (argc >= 3) {
+               speed = simple_strtoul(argv[2], &endp, 0);
+               if (*argv[2] == 0 || *endp != 0)
+                       goto usage;
+       }
+       if (argc >= 4) {
+               mode = simple_strtoul(argv[3], &endp, 16);
+               if (*argv[3] == 0 || *endp != 0)
+                       goto usage;
+       }
+       if (!spi_cs_is_valid(bus, cs)) {
+               printf("Invalid SPI bus %u cs %u\n", bus, cs);
+               return 1;
+       }
+
+       mmc = mmc_spi_init(bus, cs, speed, mode);
+       if (!mmc) {
+               printf("Failed to create MMC Device\n");
+               return 1;
+       }
+       printf("%s: %d at %u:%u hz %u mode %u\n", mmc->name, mmc->block_dev.dev,
+              bus, cs, speed, mode);
+       return 0;
+
+usage:
+       cmd_usage(cmdtp);
+       return 1;
+}
+
+U_BOOT_CMD(
+       mmc_spi,        4,      0,      do_mmc_spi,
+       "mmc_spi setup",
+       "[bus:]cs [hz] [mode]   - setup mmc_spi device"
+);
index 3496f0aa0feea3bf649f3904d8ac52690fbcb3db..9aca3a2bd6c1fb319edc45b54e138c0d16e75942 100644 (file)
@@ -31,6 +31,7 @@ COBJS-$(CONFIG_DAVINCI_MMC) += davinci_mmc.o
 COBJS-$(CONFIG_FSL_ESDHC) += fsl_esdhc.o
 COBJS-$(CONFIG_GENERIC_MMC) += mmc.o
 COBJS-$(CONFIG_GENERIC_ATMEL_MCI) += gen_atmel_mci.o
+COBJS-$(CONFIG_MMC_SPI) += mmc_spi.o
 COBJS-$(CONFIG_MXC_MMC) += mxcmmc.o
 COBJS-$(CONFIG_OMAP3_MMC) += omap3_mmc.o
 COBJS-$(CONFIG_OMAP_HSMMC) += omap_hsmmc.o
index 4f1b5150c942b7d64d435c677a58aed75cfef051..2838795febf9111f92aed0b7b4b7224e5296a5bc 100644 (file)
@@ -332,11 +332,11 @@ esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
                do {
                        irqstat = esdhc_read32(&regs->irqstat);
 
-                       if (irqstat & DATA_ERR)
-                               return COMM_ERR;
-
                        if (irqstat & IRQSTAT_DTOE)
                                return TIMEOUT;
+
+                       if (irqstat & DATA_ERR)
+                               return COMM_ERR;
                } while (!(irqstat & IRQSTAT_TC) &&
                                (esdhc_read32(&regs->prsstat) & PRSSTAT_DLA));
 #endif
index 6805b33f7a13285256c3a71f363e08fdb03d0199..f27b7c79e50e310fc047fbcbf6e4bd19bb03698c 100644 (file)
 #include <part.h>
 #include <malloc.h>
 #include <linux/list.h>
-#include <mmc.h>
 #include <div64.h>
 
+/* Set block count limit because of 16 bit register limit on some hardware*/
+#ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT
+#define CONFIG_SYS_MMC_MAX_BLK_COUNT 65535
+#endif
+
 static struct list_head mmc_devices;
 static int cur_dev_num = -1;
 
@@ -45,7 +49,100 @@ int board_mmc_getcd(u8 *cd, struct mmc *mmc)__attribute__((weak,
 
 int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
 {
+#ifdef CONFIG_MMC_TRACE
+       int ret;
+       int i;
+       u8 *ptr;
+
+       printf("CMD_SEND:%d\n", cmd->cmdidx);
+       printf("\t\tARG\t\t\t 0x%08X\n", cmd->cmdarg);
+       printf("\t\tFLAG\t\t\t %d\n", cmd->flags);
+       ret = mmc->send_cmd(mmc, cmd, data);
+       switch (cmd->resp_type) {
+               case MMC_RSP_NONE:
+                       printf("\t\tMMC_RSP_NONE\n");
+                       break;
+               case MMC_RSP_R1:
+                       printf("\t\tMMC_RSP_R1,5,6,7 \t 0x%08X \n",
+                               cmd->response[0]);
+                       break;
+               case MMC_RSP_R1b:
+                       printf("\t\tMMC_RSP_R1b\t\t 0x%08X \n",
+                               cmd->response[0]);
+                       break;
+               case MMC_RSP_R2:
+                       printf("\t\tMMC_RSP_R2\t\t 0x%08X \n",
+                               cmd->response[0]);
+                       printf("\t\t          \t\t 0x%08X \n",
+                               cmd->response[1]);
+                       printf("\t\t          \t\t 0x%08X \n",
+                               cmd->response[2]);
+                       printf("\t\t          \t\t 0x%08X \n",
+                               cmd->response[3]);
+                       printf("\n");
+                       printf("\t\t\t\t\tDUMPING DATA\n");
+                       for (i = 0; i < 4; i++) {
+                               int j;
+                               printf("\t\t\t\t\t%03d - ", i*4);
+                               ptr = &cmd->response[i];
+                               ptr += 3;
+                               for (j = 0; j < 4; j++)
+                                       printf("%02X ", *ptr--);
+                               printf("\n");
+                       }
+                       break;
+               case MMC_RSP_R3:
+                       printf("\t\tMMC_RSP_R3,4\t\t 0x%08X \n",
+                               cmd->response[0]);
+                       break;
+               default:
+                       printf("\t\tERROR MMC rsp not supported\n");
+                       break;
+       }
+       return ret;
+#else
        return mmc->send_cmd(mmc, cmd, data);
+#endif
+}
+
+int mmc_send_status(struct mmc *mmc, int timeout)
+{
+       struct mmc_cmd cmd;
+       int err;
+#ifdef CONFIG_MMC_TRACE
+       int status;
+#endif
+
+       cmd.cmdidx = MMC_CMD_SEND_STATUS;
+       cmd.resp_type = MMC_RSP_R1;
+       cmd.cmdarg = 0;
+       cmd.flags = 0;
+
+       do {
+               err = mmc_send_cmd(mmc, &cmd, NULL);
+               if (err)
+                       return err;
+               else if (cmd.response[0] & MMC_STATUS_RDY_FOR_DATA)
+                       break;
+
+               udelay(1000);
+
+               if (cmd.response[0] & MMC_STATUS_MASK) {
+                       printf("Status Error: 0x%08X\n", cmd.response[0]);
+                       return COMM_ERR;
+               }
+       } while (timeout--);
+
+#ifdef CONFIG_MMC_TRACE
+       status = (cmd.response[0] & MMC_STATUS_CURR_STATE) >> 9;
+       printf("CURR STATE:%d\n", status);
+#endif
+       if (!timeout) {
+               printf("Timeout waiting card ready\n");
+               return TIMEOUT;
+       }
+
+       return 0;
 }
 
 int mmc_set_blocklen(struct mmc *mmc, int len)
@@ -82,6 +179,7 @@ mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src)
 {
        struct mmc_cmd cmd;
        struct mmc_data data;
+       int timeout = 1000;
 
        if ((start + blkcnt) > mmc->block_dev.lba) {
                printf("MMC: block number 0x%lx exceeds max(0x%lx)\n",
@@ -112,7 +210,10 @@ mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src)
                return 0;
        }
 
-       if (blkcnt > 1) {
+       /* SPI multiblock writes terminate using a special
+        * token, not a STOP_TRANSMISSION request.
+        */
+       if (!mmc_host_is_spi(mmc) && blkcnt > 1) {
                cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
                cmd.cmdarg = 0;
                cmd.resp_type = MMC_RSP_R1b;
@@ -121,6 +222,9 @@ mmc_write_blocks(struct mmc *mmc, ulong start, lbaint_t blkcnt, const void*src)
                        printf("mmc fail to send stop cmd\n");
                        return 0;
                }
+
+               /* Waiting for the ready status */
+               mmc_send_status(mmc, timeout);
        }
 
        return blkcnt;
@@ -139,11 +243,8 @@ mmc_bwrite(int dev_num, ulong start, lbaint_t blkcnt, const void*src)
                return 0;
 
        do {
-               /*
-                * The 65535 constraint comes from some hardware has
-                * only 16 bit width block number counter
-                */
-               cur = (blocks_todo > 65535) ? 65535 : blocks_todo;
+               cur = (blocks_todo > CONFIG_SYS_MMC_MAX_BLK_COUNT) ?
+                      CONFIG_SYS_MMC_MAX_BLK_COUNT : blocks_todo;
                if(mmc_write_blocks(mmc, start, cur, src) != cur)
                        return 0;
                blocks_todo -= cur;
@@ -158,6 +259,7 @@ int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt)
 {
        struct mmc_cmd cmd;
        struct mmc_data data;
+       int timeout = 1000;
 
        if (blkcnt > 1)
                cmd.cmdidx = MMC_CMD_READ_MULTIPLE_BLOCK;
@@ -189,6 +291,9 @@ int mmc_read_blocks(struct mmc *mmc, void *dst, ulong start, lbaint_t blkcnt)
                        printf("mmc fail to send stop cmd\n");
                        return 0;
                }
+
+               /* Waiting for the ready status */
+               mmc_send_status(mmc, timeout);
        }
 
        return blkcnt;
@@ -215,11 +320,8 @@ static ulong mmc_bread(int dev_num, ulong start, lbaint_t blkcnt, void *dst)
                return 0;
 
        do {
-               /*
-                * The 65535 constraint comes from some hardware has
-                * only 16 bit width block number counter
-                */
-               cur = (blocks_todo > 65535) ? 65535 : blocks_todo;
+               cur = (blocks_todo > CONFIG_SYS_MMC_MAX_BLK_COUNT) ?
+                      CONFIG_SYS_MMC_MAX_BLK_COUNT : blocks_todo;
                if(mmc_read_blocks(mmc, dst, start, cur) != cur)
                        return 0;
                blocks_todo -= cur;
@@ -280,7 +382,8 @@ sd_send_op_cond(struct mmc *mmc)
                 * how to manage low voltages SD card is not yet
                 * specified.
                 */
-               cmd.cmdarg = mmc->voltages & 0xff8000;
+               cmd.cmdarg = mmc_host_is_spi(mmc) ? 0 :
+                       (mmc->voltages & 0xff8000);
 
                if (mmc->version == SD_VERSION_2)
                        cmd.cmdarg |= OCR_HCS;
@@ -299,6 +402,18 @@ sd_send_op_cond(struct mmc *mmc)
        if (mmc->version != SD_VERSION_2)
                mmc->version = SD_VERSION_1_0;
 
+       if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
+               cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
+               cmd.resp_type = MMC_RSP_R3;
+               cmd.cmdarg = 0;
+               cmd.flags = 0;
+
+               err = mmc_send_cmd(mmc, &cmd, NULL);
+
+               if (err)
+                       return err;
+       }
+
        mmc->ocr = cmd.response[0];
 
        mmc->high_capacity = ((mmc->ocr & OCR_HCS) == OCR_HCS);
@@ -309,17 +424,33 @@ sd_send_op_cond(struct mmc *mmc)
 
 int mmc_send_op_cond(struct mmc *mmc)
 {
-       int timeout = 1000;
+       int timeout = 10000;
        struct mmc_cmd cmd;
        int err;
 
        /* Some cards seem to need this */
        mmc_go_idle(mmc);
 
+       /* Asking to the card its capabilities */
+       cmd.cmdidx = MMC_CMD_SEND_OP_COND;
+       cmd.resp_type = MMC_RSP_R3;
+       cmd.cmdarg = 0;
+       cmd.flags = 0;
+       err = mmc_send_cmd(mmc, &cmd, NULL);
+       if (err)
+               return err;
+       udelay(1000);
        do {
                cmd.cmdidx = MMC_CMD_SEND_OP_COND;
                cmd.resp_type = MMC_RSP_R3;
-               cmd.cmdarg = OCR_HCS | mmc->voltages;
+               cmd.cmdarg = (mmc_host_is_spi(mmc) ? 0 :
+                               (mmc->voltages &
+                               (cmd.response[0] & OCR_VOLTAGE_MASK)) |
+                               (cmd.response[0] & OCR_ACCESS_MODE));
                cmd.flags = 0;
 
                err = mmc_send_cmd(mmc, &cmd, NULL);
@@ -333,6 +464,18 @@ int mmc_send_op_cond(struct mmc *mmc)
        if (timeout <= 0)
                return UNUSABLE_ERR;
 
+       if (mmc_host_is_spi(mmc)) { /* read OCR for spi */
+               cmd.cmdidx = MMC_CMD_SPI_READ_OCR;
+               cmd.resp_type = MMC_RSP_R3;
+               cmd.cmdarg = 0;
+               cmd.flags = 0;
+
+               err = mmc_send_cmd(mmc, &cmd, NULL);
+
+               if (err)
+                       return err;
+       }
+
        mmc->version = MMC_VERSION_UNKNOWN;
        mmc->ocr = cmd.response[0];
 
@@ -369,15 +512,23 @@ int mmc_send_ext_csd(struct mmc *mmc, char *ext_csd)
 int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)
 {
        struct mmc_cmd cmd;
+       int timeout = 1000;
+       int ret;
 
        cmd.cmdidx = MMC_CMD_SWITCH;
        cmd.resp_type = MMC_RSP_R1b;
        cmd.cmdarg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
-               (index << 16) |
-               (value << 8);
+                                (index << 16) |
+                                (value << 8);
        cmd.flags = 0;
 
-       return mmc_send_cmd(mmc, &cmd, NULL);
+       ret = mmc_send_cmd(mmc, &cmd, NULL);
+
+       /* Waiting for the ready status */
+       mmc_send_status(mmc, timeout);
+
+       return ret;
+
 }
 
 int mmc_change_freq(struct mmc *mmc)
@@ -388,6 +539,9 @@ int mmc_change_freq(struct mmc *mmc)
 
        mmc->card_caps = 0;
 
+       if (mmc_host_is_spi(mmc))
+               return 0;
+
        /* Only version 4 supports high-speed */
        if (mmc->version < MMC_VERSION_4)
                return 0;
@@ -399,9 +553,6 @@ int mmc_change_freq(struct mmc *mmc)
        if (err)
                return err;
 
-       if (ext_csd[212] || ext_csd[213] || ext_csd[214] || ext_csd[215])
-               mmc->high_capacity = 1;
-
        cardtype = ext_csd[196] & 0xf;
 
        err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_HS_TIMING, 1);
@@ -461,6 +612,9 @@ int sd_change_freq(struct mmc *mmc)
 
        mmc->card_caps = 0;
 
+       if (mmc_host_is_spi(mmc))
+               return 0;
+
        /* Read the SCR to find out if this card supports higher speeds */
        cmd.cmdidx = MMC_CMD_APP_CMD;
        cmd.resp_type = MMC_RSP_R1;
@@ -512,6 +666,9 @@ retry_scr:
                        break;
        }
 
+       if (mmc->scr[0] & SD_DATA_4BIT)
+               mmc->card_caps |= MMC_MODE_4BIT;
+
        /* Version 1.0 doesn't support switching */
        if (mmc->version == SD_VERSION_1_0)
                return 0;
@@ -529,9 +686,6 @@ retry_scr:
                        break;
        }
 
-       if (mmc->scr[0] & SD_DATA_4BIT)
-               mmc->card_caps |= MMC_MODE_4BIT;
-
        /* If high-speed isn't supported, we return */
        if (!(__be32_to_cpu(switch_status[3]) & SD_HIGHSPEED_SUPPORTED))
                return 0;
@@ -549,7 +703,7 @@ retry_scr:
 
 /* frequency bases */
 /* divided by 10 to be nice to platforms without floating point */
-int fbase[] = {
+static const int fbase[] = {
        10000,
        100000,
        1000000,
@@ -559,7 +713,7 @@ int fbase[] = {
 /* Multiplier values for TRAN_SPEED.  Multiplied by 10 to be nice
  * to platforms without floating point.
  */
-int multipliers[] = {
+static const int multipliers[] = {
        0,      /* reserved */
        10,
        12,
@@ -610,9 +764,24 @@ int mmc_startup(struct mmc *mmc)
        u64 cmult, csize;
        struct mmc_cmd cmd;
        char ext_csd[512];
+       int timeout = 1000;
+
+#ifdef CONFIG_MMC_SPI_CRC_ON
+       if (mmc_host_is_spi(mmc)) { /* enable CRC check for spi */
+               cmd.cmdidx = MMC_CMD_SPI_CRC_ON_OFF;
+               cmd.resp_type = MMC_RSP_R1;
+               cmd.cmdarg = 1;
+               cmd.flags = 0;
+               err = mmc_send_cmd(mmc, &cmd, NULL);
+
+               if (err)
+                       return err;
+       }
+#endif
 
        /* Put the Card in Identify Mode */
-       cmd.cmdidx = MMC_CMD_ALL_SEND_CID;
+       cmd.cmdidx = mmc_host_is_spi(mmc) ? MMC_CMD_SEND_CID :
+               MMC_CMD_ALL_SEND_CID; /* cmd not supported in spi */
        cmd.resp_type = MMC_RSP_R2;
        cmd.cmdarg = 0;
        cmd.flags = 0;
@@ -629,18 +798,20 @@ int mmc_startup(struct mmc *mmc)
         * For SD cards, get the Relatvie Address.
         * This also puts the cards into Standby State
         */
-       cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
-       cmd.cmdarg = mmc->rca << 16;
-       cmd.resp_type = MMC_RSP_R6;
-       cmd.flags = 0;
+       if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
+               cmd.cmdidx = SD_CMD_SEND_RELATIVE_ADDR;
+               cmd.cmdarg = mmc->rca << 16;
+               cmd.resp_type = MMC_RSP_R6;
+               cmd.flags = 0;
 
-       err = mmc_send_cmd(mmc, &cmd, NULL);
+               err = mmc_send_cmd(mmc, &cmd, NULL);
 
-       if (err)
-               return err;
+               if (err)
+                       return err;
 
-       if (IS_SD(mmc))
-               mmc->rca = (cmd.response[0] >> 16) & 0xffff;
+               if (IS_SD(mmc))
+                       mmc->rca = (cmd.response[0] >> 16) & 0xffff;
+       }
 
        /* Get the Card-Specific Data */
        cmd.cmdidx = MMC_CMD_SEND_CSD;
@@ -650,6 +821,9 @@ int mmc_startup(struct mmc *mmc)
 
        err = mmc_send_cmd(mmc, &cmd, NULL);
 
+       /* Waiting for the ready status */
+       mmc_send_status(mmc, timeout);
+
        if (err)
                return err;
 
@@ -716,14 +890,16 @@ int mmc_startup(struct mmc *mmc)
                mmc->write_bl_len = 512;
 
        /* Select the card, and put it into Transfer Mode */
-       cmd.cmdidx = MMC_CMD_SELECT_CARD;
-       cmd.resp_type = MMC_RSP_R1b;
-       cmd.cmdarg = mmc->rca << 16;
-       cmd.flags = 0;
-       err = mmc_send_cmd(mmc, &cmd, NULL);
+       if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */
+               cmd.cmdidx = MMC_CMD_SELECT_CARD;
+               cmd.resp_type = MMC_RSP_R1b;
+               cmd.cmdarg = mmc->rca << 16;
+               cmd.flags = 0;
+               err = mmc_send_cmd(mmc, &cmd, NULL);
 
-       if (err)
-               return err;
+               if (err)
+                       return err;
+       }
 
        if (!IS_SD(mmc) && (mmc->version >= MMC_VERSION_4)) {
                /* check  ext_csd version and capacity */
diff --git a/drivers/mmc/mmc_spi.c b/drivers/mmc/mmc_spi.c
new file mode 100644 (file)
index 0000000..dc7574c
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * generic mmc spi driver
+ *
+ * Copyright (C) 2010 Thomas Chou <thomas@wytron.com.tw>
+ * Licensed under the GPL-2 or later.
+ */
+#include <common.h>
+#include <malloc.h>
+#include <part.h>
+#include <mmc.h>
+#include <spi.h>
+#include <crc.h>
+#include <linux/crc7.h>
+#include <linux/byteorder/swab.h>
+
+/* MMC/SD in SPI mode reports R1 status always */
+#define R1_SPI_IDLE            (1 << 0)
+#define R1_SPI_ERASE_RESET     (1 << 1)
+#define R1_SPI_ILLEGAL_COMMAND (1 << 2)
+#define R1_SPI_COM_CRC         (1 << 3)
+#define R1_SPI_ERASE_SEQ       (1 << 4)
+#define R1_SPI_ADDRESS         (1 << 5)
+#define R1_SPI_PARAMETER       (1 << 6)
+/* R1 bit 7 is always zero, reuse this bit for error */
+#define R1_SPI_ERROR           (1 << 7)
+
+/* Response tokens used to ack each block written: */
+#define SPI_MMC_RESPONSE_CODE(x)       ((x) & 0x1f)
+#define SPI_RESPONSE_ACCEPTED          ((2 << 1)|1)
+#define SPI_RESPONSE_CRC_ERR           ((5 << 1)|1)
+#define SPI_RESPONSE_WRITE_ERR         ((6 << 1)|1)
+
+/* Read and write blocks start with these tokens and end with crc;
+ * on error, read tokens act like a subset of R2_SPI_* values.
+ */
+#define SPI_TOKEN_SINGLE       0xfe    /* single block r/w, multiblock read */
+#define SPI_TOKEN_MULTI_WRITE  0xfc    /* multiblock write */
+#define SPI_TOKEN_STOP_TRAN    0xfd    /* terminate multiblock write */
+
+/* MMC SPI commands start with a start bit "0" and a transmit bit "1" */
+#define MMC_SPI_CMD(x) (0x40 | (x & 0x3f))
+
+/* bus capability */
+#define MMC_SPI_VOLTAGE (MMC_VDD_32_33 | MMC_VDD_33_34)
+#define MMC_SPI_MIN_CLOCK 400000 /* 400KHz to meet MMC spec */
+
+/* timeout value */
+#define CTOUT 8
+#define RTOUT 3000000 /* 1 sec */
+#define WTOUT 3000000 /* 1 sec */
+
+static uint mmc_spi_sendcmd(struct mmc *mmc, ushort cmdidx, u32 cmdarg)
+{
+       struct spi_slave *spi = mmc->priv;
+       u8 cmdo[7];
+       u8 r1;
+       int i;
+       cmdo[0] = 0xff;
+       cmdo[1] = MMC_SPI_CMD(cmdidx);
+       cmdo[2] = cmdarg >> 24;
+       cmdo[3] = cmdarg >> 16;
+       cmdo[4] = cmdarg >> 8;
+       cmdo[5] = cmdarg;
+       cmdo[6] = (crc7(0, &cmdo[1], 5) << 1) | 0x01;
+       spi_xfer(spi, sizeof(cmdo) * 8, cmdo, NULL, 0);
+       for (i = 0; i < CTOUT; i++) {
+               spi_xfer(spi, 1 * 8, NULL, &r1, 0);
+               if (i && (r1 & 0x80) == 0) /* r1 response */
+                       break;
+       }
+       debug("%s:cmd%d resp%d %x\n", __func__, cmdidx, i, r1);
+       return r1;
+}
+
+static uint mmc_spi_readdata(struct mmc *mmc, void *xbuf,
+                               u32 bcnt, u32 bsize)
+{
+       struct spi_slave *spi = mmc->priv;
+       u8 *buf = xbuf;
+       u8 r1;
+       u16 crc;
+       int i;
+       while (bcnt--) {
+               for (i = 0; i < RTOUT; i++) {
+                       spi_xfer(spi, 1 * 8, NULL, &r1, 0);
+                       if (r1 != 0xff) /* data token */
+                               break;
+               }
+               debug("%s:tok%d %x\n", __func__, i, r1);
+               if (r1 == SPI_TOKEN_SINGLE) {
+                       spi_xfer(spi, bsize * 8, NULL, buf, 0);
+                       spi_xfer(spi, 2 * 8, NULL, &crc, 0);
+#ifdef CONFIG_MMC_SPI_CRC_ON
+                       if (swab16(cyg_crc16(buf, bsize)) != crc) {
+                               debug("%s: CRC error\n", mmc->name);
+                               r1 = R1_SPI_COM_CRC;
+                               break;
+                       }
+#endif
+                       r1 = 0;
+               } else {
+                       r1 = R1_SPI_ERROR;
+                       break;
+               }
+               buf += bsize;
+       }
+       return r1;
+}
+
+static uint mmc_spi_writedata(struct mmc *mmc, const void *xbuf,
+                             u32 bcnt, u32 bsize, int multi)
+{
+       struct spi_slave *spi = mmc->priv;
+       const u8 *buf = xbuf;
+       u8 r1;
+       u16 crc;
+       u8 tok[2];
+       int i;
+       tok[0] = 0xff;
+       tok[1] = multi ? SPI_TOKEN_MULTI_WRITE : SPI_TOKEN_SINGLE;
+       while (bcnt--) {
+#ifdef CONFIG_MMC_SPI_CRC_ON
+               crc = swab16(cyg_crc16((u8 *)buf, bsize));
+#endif
+               spi_xfer(spi, 2 * 8, tok, NULL, 0);
+               spi_xfer(spi, bsize * 8, buf, NULL, 0);
+               spi_xfer(spi, 2 * 8, &crc, NULL, 0);
+               for (i = 0; i < CTOUT; i++) {
+                       spi_xfer(spi, 1 * 8, NULL, &r1, 0);
+                       if ((r1 & 0x10) == 0) /* response token */
+                               break;
+               }
+               debug("%s:tok%d %x\n", __func__, i, r1);
+               if (SPI_MMC_RESPONSE_CODE(r1) == SPI_RESPONSE_ACCEPTED) {
+                       for (i = 0; i < WTOUT; i++) { /* wait busy */
+                               spi_xfer(spi, 1 * 8, NULL, &r1, 0);
+                               if (i && r1 == 0xff) {
+                                       r1 = 0;
+                                       break;
+                               }
+                       }
+                       if (i == WTOUT) {
+                               debug("%s:wtout %x\n", __func__, r1);
+                               r1 = R1_SPI_ERROR;
+                               break;
+                       }
+               } else {
+                       debug("%s: err %x\n", __func__, r1);
+                       r1 = R1_SPI_COM_CRC;
+                       break;
+               }
+               buf += bsize;
+       }
+       if (multi && bcnt == -1) { /* stop multi write */
+               tok[1] = SPI_TOKEN_STOP_TRAN;
+               spi_xfer(spi, 2 * 8, tok, NULL, 0);
+               for (i = 0; i < WTOUT; i++) { /* wait busy */
+                       spi_xfer(spi, 1 * 8, NULL, &r1, 0);
+                       if (i && r1 == 0xff) {
+                               r1 = 0;
+                               break;
+                       }
+               }
+               if (i == WTOUT) {
+                       debug("%s:wstop %x\n", __func__, r1);
+                       r1 = R1_SPI_ERROR;
+               }
+       }
+       return r1;
+}
+
+static int mmc_spi_request(struct mmc *mmc, struct mmc_cmd *cmd,
+               struct mmc_data *data)
+{
+       struct spi_slave *spi = mmc->priv;
+       u8 r1;
+       int i;
+       int ret = 0;
+       debug("%s:cmd%d %x %x %x\n", __func__,
+             cmd->cmdidx, cmd->resp_type, cmd->cmdarg, cmd->flags);
+       spi_claim_bus(spi);
+       spi_cs_activate(spi);
+       r1 = mmc_spi_sendcmd(mmc, cmd->cmdidx, cmd->cmdarg);
+       if (r1 == 0xff) { /* no response */
+               ret = NO_CARD_ERR;
+               goto done;
+       } else if (r1 & R1_SPI_COM_CRC) {
+               ret = COMM_ERR;
+               goto done;
+       } else if (r1 & ~R1_SPI_IDLE) { /* other errors */
+               ret = TIMEOUT;
+               goto done;
+       } else if (cmd->resp_type == MMC_RSP_R2) {
+               r1 = mmc_spi_readdata(mmc, cmd->response, 1, 16);
+               for (i = 0; i < 4; i++)
+                       cmd->response[i] = swab32(cmd->response[i]);
+               debug("r128 %x %x %x %x\n", cmd->response[0], cmd->response[1],
+                     cmd->response[2], cmd->response[3]);
+       } else if (!data) {
+               switch (cmd->cmdidx) {
+               case SD_CMD_APP_SEND_OP_COND:
+               case MMC_CMD_SEND_OP_COND:
+                       cmd->response[0] = (r1 & R1_SPI_IDLE) ? 0 : OCR_BUSY;
+                       break;
+               case SD_CMD_SEND_IF_COND:
+               case MMC_CMD_SPI_READ_OCR:
+                       spi_xfer(spi, 4 * 8, NULL, cmd->response, 0);
+                       cmd->response[0] = swab32(cmd->response[0]);
+                       debug("r32 %x\n", cmd->response[0]);
+                       break;
+               }
+       } else {
+               debug("%s:data %x %x %x\n", __func__,
+                     data->flags, data->blocks, data->blocksize);
+               if (data->flags == MMC_DATA_READ)
+                       r1 = mmc_spi_readdata(mmc, data->dest,
+                               data->blocks, data->blocksize);
+               else if  (data->flags == MMC_DATA_WRITE)
+                       r1 = mmc_spi_writedata(mmc, data->src,
+                               data->blocks, data->blocksize,
+                               (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK));
+               if (r1 & R1_SPI_COM_CRC)
+                       ret = COMM_ERR;
+               else if (r1) /* other errors */
+                       ret = TIMEOUT;
+       }
+done:
+       spi_cs_deactivate(spi);
+       spi_release_bus(spi);
+       return ret;
+}
+
+static void mmc_spi_set_ios(struct mmc *mmc)
+{
+       struct spi_slave *spi = mmc->priv;
+       debug("%s: clock %u\n", __func__, mmc->clock);
+       if (mmc->clock)
+               spi_set_speed(spi, mmc->clock);
+}
+
+static int mmc_spi_init_p(struct mmc *mmc)
+{
+       struct spi_slave *spi = mmc->priv;
+       mmc->clock = 0;
+       spi_set_speed(spi, MMC_SPI_MIN_CLOCK);
+       spi_claim_bus(spi);
+       /* cs deactivated for 100+ clock */
+       spi_xfer(spi, 18 * 8, NULL, NULL, 0);
+       spi_release_bus(spi);
+       return 0;
+}
+
+struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode)
+{
+       struct mmc *mmc;
+
+       mmc = malloc(sizeof(*mmc));
+       if (!mmc)
+               return NULL;
+       memset(mmc, 0, sizeof(*mmc));
+       mmc->priv = spi_setup_slave(bus, cs, speed, mode);
+       if (!mmc->priv) {
+               free(mmc);
+               return NULL;
+       }
+       sprintf(mmc->name, "MMC_SPI");
+       mmc->send_cmd = mmc_spi_request;
+       mmc->set_ios = mmc_spi_set_ios;
+       mmc->init = mmc_spi_init_p;
+       mmc->host_caps = MMC_MODE_SPI;
+
+       mmc->voltages = MMC_SPI_VOLTAGE;
+       mmc->f_max = speed;
+       mmc->f_min = MMC_SPI_MIN_CLOCK;
+       mmc->block_dev.part_type = PART_TYPE_DOS;
+
+       mmc_register(mmc);
+
+       return mmc;
+}
index 722aafc73c35ab1d733338aa3df548d374e50a7f..a883da93688a1bc056b569ab859bdb6dae263dfa 100644 (file)
@@ -49,6 +49,14 @@ extern void cfspi_release_bus(uint bus, uint cs);
 
 DECLARE_GLOBAL_DATA_PTR;
 
+#ifndef CONFIG_SPI_IDLE_VAL
+#if defined(CONFIG_SPI_MMC)
+#define CONFIG_SPI_IDLE_VAL    0xFFFF
+#else
+#define CONFIG_SPI_IDLE_VAL    0x0
+#endif
+#endif
+
 #if defined(CONFIG_CF_DSPI)
 /* DSPI specific mode */
 #define SPI_MODE_MOD   0x00200000
@@ -145,7 +153,7 @@ int cfspi_xfer(struct spi_slave *slave, uint bitlen, const void *dout,
                        }
 
                        if (din != NULL) {
-                               cfspi_tx(ctrl, 0);
+                               cfspi_tx(ctrl, CONFIG_SPI_IDLE_VAL);
                                if (cfslave->charbit == 16)
                                        *spi_rd16++ = cfspi_rx();
                                else
@@ -169,7 +177,7 @@ int cfspi_xfer(struct spi_slave *slave, uint bitlen, const void *dout,
                }
 
                if (din != NULL) {
-                       cfspi_tx(ctrl, 0);
+                       cfspi_tx(ctrl, CONFIG_SPI_IDLE_VAL);
                        if (cfslave->charbit == 16)
                                *spi_rd16 = cfspi_rx();
                        else
@@ -177,7 +185,7 @@ int cfspi_xfer(struct spi_slave *slave, uint bitlen, const void *dout,
                }
        } else {
                /* dummy read */
-               cfspi_tx(ctrl, 0);
+               cfspi_tx(ctrl, CONFIG_SPI_IDLE_VAL);
                cfspi_rx();
        }
 
index fcd0fd1de572c2cf7a54fc0ad1a5414c38c0c549..e0a56d9d23b76501f1d378ce79ec9f2702762cfa 100644 (file)
@@ -44,6 +44,7 @@
 #define MMC_MODE_HS_52MHz      0x010
 #define MMC_MODE_4BIT          0x100
 #define MMC_MODE_8BIT          0x200
+#define MMC_MODE_SPI           0x400
 
 #define SD_DATA_4BIT   0x00040000
 
@@ -75,6 +76,8 @@
 #define MMC_CMD_WRITE_SINGLE_BLOCK     24
 #define MMC_CMD_WRITE_MULTIPLE_BLOCK   25
 #define MMC_CMD_APP_CMD                        55
+#define MMC_CMD_SPI_READ_OCR           58
+#define MMC_CMD_SPI_CRC_ON_OFF         59
 
 #define SD_CMD_SEND_RELATIVE_ADDR      3
 #define SD_CMD_SWITCH_FUNC             6
 
 #define OCR_BUSY       0x80000000
 #define OCR_HCS                0x40000000
+#define OCR_VOLTAGE_MASK       0x007FFF80
+#define OCR_ACCESS_MODE                0x60000000
+
+#define MMC_STATUS_MASK                (~0x0206BF7F)
+#define MMC_STATUS_RDY_FOR_DATA (1<<8)
+#define MMC_STATUS_CURR_STATE  (0xf<<9)
 
 #define MMC_VDD_165_195                0x00000080      /* VDD voltage 1.65 - 1.95 */
 #define MMC_VDD_20_21          0x00000100      /* VDD voltage 2.0 ~ 2.1 */
@@ -291,6 +300,8 @@ int board_mmc_getcd(u8 *cd, struct mmc *mmc);
 
 #ifdef CONFIG_GENERIC_MMC
 int atmel_mci_init(void *regs);
+#define mmc_host_is_spi(mmc)   ((mmc)->host_caps & MMC_MODE_SPI)
+struct mmc *mmc_spi_init(uint bus, uint cs, uint speed, uint mode);
 #else
 int mmc_legacy_init(int verbose);
 #endif