U-Boot
Threads by month
- ----- 2025 -----
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2000 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
May 2012
- 175 participants
- 506 discussions

11 May '12
Dear Otavio Salvador,
please keep the ML on Cc: - thanks.
In message <CAP9ODKq=MEe0UxZmJyFEdkocn0cW+RzkZDnVSjmdTeHfU67auQ(a)mail.gmail.com> you wrote:
>
> > I have to admit that I have other ideas what the environment on the
> > M28 boards should look like. I don't want to see this style enforced
> > (or even encouraged) for this board.
>
> Can you explain what do you have in mind?
Over the years we have developed our own style for the default
environment of DENX maintained boards, and I want to keep this
consistently used, especially for our own products. The (Frescale
originating?) style you are using here does not fit. [The cuurent
default env is not much better, agreed; this needs fixing. But when
changing the environment for M28, then in the "right" direction.]
Thanks.
Best regards,
Wolfgang Denk
--
DENX Software Engineering GmbH, MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd(a)denx.de
The sight of death frightens them [Earthers].
-- Kras the Klingon, "Friday's Child", stardate 3497.2
2
1

11 May '12
The environment has been based on mx53loco but keeping the possibility
to easy change the default console device as Freescale and mainline
kernels differ on the device name and inclusing m28evk update commands.
Signed-off-by: Otavio Salvador <otavio(a)ossystems.com.br>
Cc: Fabio Estevam <fabio.estevam(a)freescale.com>
Cc: Stefano Babic <sbabic(a)denx.de>
---
include/configs/m28evk.h | 57 +-----------------
include/configs/mx28-common.h | 129 +++++++++++++++++++++++++++++++++++++++++
include/configs/mx28evk.h | 26 +--------
3 files changed, 133 insertions(+), 79 deletions(-)
create mode 100644 include/configs/mx28-common.h
diff --git a/include/configs/m28evk.h b/include/configs/m28evk.h
index ebf7e39..ed8166a 100644
--- a/include/configs/m28evk.h
+++ b/include/configs/m28evk.h
@@ -271,60 +271,7 @@
#endif
#endif
-/*
- * Boot Linux
- */
-#define CONFIG_CMDLINE_TAG
-#define CONFIG_SETUP_MEMORY_TAGS
-#define CONFIG_BOOTDELAY 3
-#define CONFIG_BOOTFILE "uImage"
-#define CONFIG_BOOTARGS "console=ttyAM0,115200n8 "
-#define CONFIG_BOOTCOMMAND "run bootcmd_net"
-#define CONFIG_LOADADDR 0x42000000
-#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
-#define CONFIG_OF_LIBFDT
-
-/*
- * Extra Environments
- */
-#define CONFIG_EXTRA_ENV_SETTINGS \
- "update_nand_full_filename=u-boot.nand\0" \
- "update_nand_firmware_filename=u-boot.sb\0" \
- "update_sd_firmware_filename=u-boot.sd\0" \
- "update_nand_firmware_maxsz=0x100000\0" \
- "update_nand_stride=0x40\0" /* MX28 datasheet ch. 12.12 */ \
- "update_nand_count=0x4\0" /* MX28 datasheet ch. 12.12 */ \
- "update_nand_get_fcb_size=" /* Get size of FCB blocks */ \
- "nand device 0 ; " \
- "nand info ; " \
- "setexpr fcb_sz ${update_nand_stride} * ${update_nand_count};" \
- "setexpr update_nand_fcb ${fcb_sz} * ${nand_writesize}\0" \
- "update_nand_full=" /* Update FCB, DBBT and FW */ \
- "if tftp ${update_nand_full_filename} ; then " \
- "run update_nand_get_fcb_size ; " \
- "nand scrub -y 0x0 ${filesize} ; " \
- "nand write.raw ${loadaddr} 0x0 ${update_nand_fcb} ; " \
- "setexpr update_off ${loadaddr} + ${update_nand_fcb} ; " \
- "setexpr update_sz ${filesize} - ${update_nand_fcb} ; " \
- "nand write ${update_off} ${update_nand_fcb} ${update_sz} ; " \
- "fi\0" \
- "update_nand_firmware=" /* Update only firmware */ \
- "if tftp ${update_nand_firmware_filename} ; then " \
- "run update_nand_get_fcb_size ; " \
- "setexpr fcb_sz ${update_nand_fcb} * 2 ; " /* FCB + DBBT */ \
- "setexpr fw_sz ${update_nand_firmware_maxsz} * 2 ; " \
- "setexpr fw_off ${fcb_sz} + ${update_nand_firmware_maxsz};" \
- "nand erase ${fcb_sz} ${fw_sz} ; " \
- "nand write ${loadaddr} ${fcb_sz} ${filesize} ; " \
- "nand write ${loadaddr} ${fw_off} ${filesize} ; " \
- "fi\0" \
- "update_sd_firmware=" /* Update the SD firmware partition */ \
- "if mmc rescan ; then " \
- "if tftp ${update_sd_firmware_filename} ; then " \
- "setexpr fw_sz ${filesize} / 0x200 ; " /* SD block size */ \
- "setexpr fw_sz ${fw_sz} + 1 ; " \
- "mmc write ${loadaddr} 0x800 ${fw_sz} ; " \
- "fi ; " \
- "fi\0"
+/* Boot configuration and environemnt */
+#include "mx28-common.h"
#endif /* __M28_H__ */
diff --git a/include/configs/mx28-common.h b/include/configs/mx28-common.h
new file mode 100644
index 0000000..2fd436c
--- /dev/null
+++ b/include/configs/mx28-common.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2012 Otavio Salvador <otavio(a)ossystems.com.br>
+ * on behalf of O.S. Systems Software LTDA.
+ *
+ * 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
+ */
+#ifndef __MX28_COMMON_H__
+#define __MX28_COMMON_H__
+
+/*
+ * Boot Linux
+ */
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_BOOTDELAY 3
+#define CONFIG_BOOTFILE "uImage"
+
+#define CONFIG_LOADADDR 0x42000000
+#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
+#define CONFIG_OF_LIBFDT
+
+/*
+ * Extra Environments
+ */
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ /* Update NAND command set */ \
+ "update_nand_full_filename=u-boot.nand\0" \
+ "update_nand_firmware_filename=u-boot.sb\0" \
+ "update_nand_firmware_maxsz=0x100000\0" \
+ "update_nand_stride=0x40\0" /* MX28 datasheet ch. 12.12 */ \
+ "update_nand_count=0x4\0" /* MX28 datasheet ch. 12.12 */ \
+ "update_nand_get_fcb_size=" /* Get size of FCB blocks */ \
+ "nand device 0 ; " \
+ "nand info ; " \
+ "setexpr fcb_sz ${update_nand_stride} * ${update_nand_count};" \
+ "setexpr update_nand_fcb ${fcb_sz} * ${nand_writesize}\0" \
+ "update_nand_full=" /* Update FCB, DBBT and FW */ \
+ "if tftp ${update_nand_full_filename} ; then " \
+ "run update_nand_get_fcb_size ; " \
+ "nand scrub -y 0x0 ${filesize} ; " \
+ "nand write.raw ${loadaddr} 0x0 ${update_nand_fcb} ; " \
+ "setexpr update_off ${loadaddr} + ${update_nand_fcb} ; " \
+ "setexpr update_sz ${filesize} - ${update_nand_fcb} ; " \
+ "nand write ${update_off} ${update_nand_fcb} ${update_sz} ; " \
+ "fi\0" \
+ "update_nand_firmware=" /* Update only firmware */ \
+ "if tftp ${update_nand_firmware_filename} ; then " \
+ "run update_nand_get_fcb_size ; " \
+ "setexpr fcb_sz ${update_nand_fcb} * 2 ; " /* FCB + DBBT */ \
+ "setexpr fw_sz ${update_nand_firmware_maxsz} * 2 ; " \
+ "setexpr fw_off ${fcb_sz} + ${update_nand_firmware_maxsz};" \
+ "nand erase ${fcb_sz} ${fw_sz} ; " \
+ "nand write ${loadaddr} ${fcb_sz} ${filesize} ; " \
+ "nand write ${loadaddr} ${fw_off} ${filesize} ; " \
+ "fi\0" \
+ /* Update SDCard command set */ \
+ "update_sd_firmware_filename=u-boot.sd\0" \
+ "update_sd_firmware=" /* Update the SD firmware partition */ \
+ "if mmc rescan ; then " \
+ "if tftp ${update_sd_firmware_filename} ; then " \
+ "setexpr fw_sz ${filesize} / 0x200 ; " /* SD block size */ \
+ "setexpr fw_sz ${fw_sz} + 1 ; " \
+ "mmc write ${loadaddr} 0x800 ${fw_sz} ; " \
+ "fi ; " \
+ "fi\0" \
+ /* General command set */ \
+ "script=boot.scr\0" \
+ "uimage=uImage\0" \
+ "console_fsl=ttyAM0\0" \
+ "console_mainline=ttyAMA0\0" \
+ "console=${console_mainline}\0" \
+ "baudrate=115200\0" \
+ "mmcdev=0\0" \
+ "mmcpart=2\0" \
+ "mmcroot=/dev/mmcblk0p3 rw\0" \
+ "mmcrootfstype=ext3 rootwait\0" \
+ "mmcargs=" \
+ "setenv bootargs console=${console},${baudrate} " \
+ "root=${mmcroot} " \
+ "rootfstype=${mmcrootfstype}\0" \
+ "loadbootscript=" \
+ "fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
+ "bootscript=" \
+ "echo Running bootscript from mmc ...; " \
+ "source\0" \
+ "loaduimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${uimage}\0" \
+ "mmcboot=" \
+ "echo Booting from mmc ...; " \
+ "run mmcargs; " \
+ "bootm\0" \
+ "netargs=" \
+ "setenv bootargs console=${console},${baudrate} " \
+ "root=/dev/nfs " \
+ "ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \
+ "netboot=" \
+ "echo Booting from net ...; " \
+ "run netargs; " \
+ "dhcp ${uimage}; bootm\0"
+
+/*
+ * Default Boot command
+ */
+#define CONFIG_BOOTCOMMAND \
+ "if mmc rescan ${mmcdev}; then " \
+ "if run loadbootscript; then " \
+ "run bootscript; " \
+ "else " \
+ "if run loaduimage; then " \
+ "run mmcboot; " \
+ "else run netboot; " \
+ "fi; " \
+ "fi; " \
+ "else run netboot; fi"
+
+
+#endif /* __MX28_COMMON_H__ */
diff --git a/include/configs/mx28evk.h b/include/configs/mx28evk.h
index 5ccfe70..5b51d26 100644
--- a/include/configs/mx28evk.h
+++ b/include/configs/mx28evk.h
@@ -227,29 +227,7 @@
#endif
#endif
-/*
- * Boot Linux
- */
-#define CONFIG_CMDLINE_TAG
-#define CONFIG_SETUP_MEMORY_TAGS
-#define CONFIG_BOOTDELAY 3
-#define CONFIG_BOOTFILE "uImage"
-#define CONFIG_BOOTCOMMAND "run bootcmd_net"
-#define CONFIG_LOADADDR 0x42000000
-#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
-#define CONFIG_OF_LIBFDT
-
-/*
- * Extra Environments
- */
-#define CONFIG_EXTRA_ENV_SETTINGS \
- "console_fsl=console=ttyAM0" \
- "console_mainline=console=ttyAMA0" \
- "netargs=setenv bootargs console=${console_mainline}" \
- "root=/dev/nfs " \
- "ip=dhcp nfsroot=${serverip}:${nfsroot}\0" \
- "bootcmd_net=echo Booting from net ...; " \
- "run netargs; " \
- "dhcp ${uimage}; bootm\0" \
+/* Boot configuration and environemnt */
+#include "mx28-common.h"
#endif /* __CONFIG_H */
--
1.7.10
2
1
From: Otavio Salvador <otavio(a)ossystems.com.br>
The environment has been based on mx53loco but keeping the possibility
to easy change the default console device as Freescale and mainline
kernels differ on the device name.
Signed-off-by: Otavio Salvador <otavio(a)ossystems.com.br>
Cc: Fabio Estevam <fabio.estevam(a)freescale.com>
Cc: Stefano Babic <sbabic(a)denx.de>
---
include/configs/mx28evk.h | 44 ++++++++++++++++++++++++++++++++++++++------
1 file changed, 38 insertions(+), 6 deletions(-)
diff --git a/include/configs/mx28evk.h b/include/configs/mx28evk.h
index 02f3366..b165285 100644
--- a/include/configs/mx28evk.h
+++ b/include/configs/mx28evk.h
@@ -222,7 +222,7 @@
#define CONFIG_SETUP_MEMORY_TAGS
#define CONFIG_BOOTDELAY 3
#define CONFIG_BOOTFILE "uImage"
-#define CONFIG_BOOTCOMMAND "run bootcmd_net"
+
#define CONFIG_LOADADDR 0x42000000
#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
@@ -230,13 +230,45 @@
* Extra Environments
*/
#define CONFIG_EXTRA_ENV_SETTINGS \
- "console_fsl=console=ttyAM0" \
- "console_mainline=console=ttyAMA0" \
- "netargs=setenv bootargs console=${console_mainline}" \
+ "script=boot.scr\0" \
+ "uimage=uImage\0" \
+ "console_fsl=ttyAM0\0" \
+ "console_mainline=ttyAMA0\0" \
+ "console=${console_mainline}\0" \
+ "mmcdev=0\0" \
+ "mmcpart=2\0" \
+ "mmcroot=/dev/mmcblk0p3 rw\0" \
+ "mmcrootfstype=ext3 rootwait\0" \
+ "mmcargs=setenv bootargs console=${console},${baudrate} " \
+ "root=${mmcroot} " \
+ "rootfstype=${mmcrootfstype}\0" \
+ "loadbootscript=" \
+ "fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
+ "bootscript=echo Running bootscript from mmc ...; " \
+ "source\0" \
+ "loaduimage=fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${uimage}\0" \
+ "mmcboot=echo Booting from mmc ...; " \
+ "run mmcargs; " \
+ "bootm\0" \
+ "netargs=setenv bootargs console=${console},${baudrate} " \
"root=/dev/nfs " \
- "ip=dhcp nfsroot=${serverip}:${nfsroot}\0" \
- "bootcmd_net=echo Booting from net ...; " \
+ "ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \
+ "netboot=echo Booting from net ...; " \
"run netargs; " \
"dhcp ${uimage}; bootm\0" \
+/*
+ * Default Boot command
+ */
+#define CONFIG_BOOTCOMMAND \
+ "if mmc rescan ${mmcdev}; then " \
+ "if run loadbootscript; then " \
+ "run bootscript; " \
+ "else " \
+ "if run loaduimage; then " \
+ "run mmcboot; " \
+ "else run netboot; " \
+ "fi; " \
+ "fi; " \
+ "else run netboot; fi"
#endif /* __CONFIG_H */
--
1.7.10
4
7
Dear Atul Kumar,
Please CC the mailing list, always.
> Dear Marek,
>
> Thanks for your attention.. After doing "coninfo", i get below
> msg..
>
> OMAP3 beagleboard.org #
>
> coninfo
>
> List of available devices:
>
> serial 80000003 SIO stdin stdout stderr
>
> usbtty 00000
>
> 003 .IO
>
> usbkbd 80000001 SI.
>
> OMAP3 beagleboard.org #
>
> tried to do setenv...
>
> OMAP3 beagleboard.org #
>
> setenv stdin usbkbd
All right, maybe you should fix your method of pasting u-boot output, you have
every second line blank and a few linebreaks here and there, randomly. It'd be
cool to fix it, it'd make it much easier to read. Can you do something about it
please?
>
> OMAP3 beagleboard.org #
>
> After doing this my terminal does not prints any logs but i am able to type
> on console..
You mean with the keyboard? Because "setenv stdin usbkbd" tells the system to
read input from the USB keyboard.
> Once when i reboot the board again the logs starts coming up..
Ah ... so you got no console output. Try typing on the usb keyboard. If you
change stdin to usbkbd, you'd only be able to type with the USB keyboard, it
won't pick input from the UART/serial port or whatever other source you use.
>
> I see on "*stdin name- *serial** " .. if instead of serial "*usbkbd*" is
> there it will be able to register the kbd..
>
> I tried this another way but do not find any change in pri ..
Pri?
[...]
btw it's a good practice in the mailing list to not top-post (aka reply under
the email you're replying to). But if you comment on stuff, you can do it in the
middle of the email (just like I did with this one) to better identify what
you're replying to.
>
> Thanks & Regards
> Atul Kumar
> 9845495793
>
> On Fri, May 11, 2012 at 4:25 PM, Marek Vasut <marex(a)denx.de> wrote:
> > Dear Atul Kumar,
> >
> > > Dear Marek,
> > >
> > > I am tring to bring up USB Keyboard on u-boot with
> > > "Beagle_board
> > >
> > > xM ver B".. found number of post,but the stack is already updated
> > > one.. I am able to find the info of the connected device but some how
> > > keyboard does not works.. can you suggest/guide me were i am making
> > > mistake or where I need to do some device specific changes..
> >
> > Please always CC the U-Boot mailing list (CCed).
> >
> > Did you try running "coninfo" after the "usb reset"/"usb start"? What
> > does it
> > output, do you see "usbkbd" there? Wild guess would be to run "setenv
> > stdin usbkbd" or something after you do "usb reset".
> >
> > > *logs for "usb start"*
> > >
> > > OMAP3 beagleboard.org #
> > >
> > > usb start
> > >
> > > (Re)start USB...
> > >
> > > USB: Initializing OMAP EHCI
> > >
> > > OMAP UHH_REV
> > >
> > > ISION 0x10
> > >
> > > OMAP EHCI init done
> > >
> > > Register 1313 NbrPorts 3
> > >
> > > USB EHCI 1.00
> > >
> > > scanning bus for devices...
> > >
> > > 4 USB Device(s) found
> > >
> > > USB KBD: found set protocol...
> > >
> > > USB KBD: found set idle...
> > >
> > > USB
> > >
> > > KBD: enable interrupt pipe...
> > >
> > > USB KBD: found set up device.
> > >
> > > USB KBD: register.
> > >
> > > usb_kbd_dev.name- usbkbd
> > >
> > > before stdio register
> > >
> > > clone _dev->name-usbkbd,dev->name-usbkbd
> > >
> > > in stdio register,usb_kbd_dev.name- usbkbd
> > >
> > > After stdio register
> > >
> > > before strcmp
> > >
> > > stdin name- *serial*
> > >
> > > scan end
> > >
> > > scanning bus for storage devices... 0 Storage Device(s) found
> > >
> > > scanning bus for ethernet devices... Warning: failed to set MAC address
> > >
> > > 1 Ethernet Device(s) found
> > >
> > > OMAP3 beagleboard.org #
> > >
> > > *logs for "usb info"*
> > >
> > > OMAP3 beagleboard.org #
> > >
> > > usb info
> > >
> > > 1: Hub, USB Revision 2.0
> > >
> > > - u-boot EHCI Host Controller
> > >
> > > - Class: Hub
> > >
> > > - PacketSize: 64 Configurations: 1
> > >
> > > -
> > >
> > > Vendor: 0x0000 Product 0x0000 Version 1.0
> > >
> > > Configuration: 1
> > >
> > > - Interfaces: 1 Self Powered 0mA
> > >
> > > Interface: 0
> > >
> > > - Alternate Setting 0, Endpoints: 1
> > >
> > > - Class Hub
> > >
> > > - Endpoint 1 In Interrupt MaxPacket 8 Interval 255ms
> > >
> > > 2: Hub, USB Revision 2.0
> > >
> > > - Class: Hub
> > >
> > > - PacketSize: 64 Configurations: 1
> > >
> > > - Vendor: 0x0424 Product 0x9514 Version 2.0
> > >
> > > Configuration: 1
> > >
> > > - Interfaces: 1 Self Powered Remote Wakeup 2mA
> > >
> > > Interface: 0
> > >
> > > - Alternate Setting 0, Endpoints: 1
> > >
> > > - Class Hub
> > >
> > > - Endpoint 1 In Interrupt MaxPacket 1 Interval 12ms
> > >
> > > - Endpoint 1 In Interrupt MaxPacket 1 Interval 12ms
> > >
> > > 3: Vendor specific, USB Revision 2.0
> > >
> > > - Class: Vendor specific
> > >
> > > - PacketSize: 64 Configurations: 1
> > >
> > > - Vendor: 0x0424 Product 0xec00 Version 2.0
> > >
> > > Configuration: 1
> > >
> > > - Interfaces: 1 Self Powered Remote Wakeup 2mA
> > >
> > > Interface: 0
> > >
> > > - Alternate Setting 0, Endpoints: 3
> > >
> > > - Class Vendor specific
> > >
> > > - Endpoint 1 In Bulk MaxPacket 512
> > >
> > > - Endpoint 2 Out Bulk MaxPacket 512
> > >
> > > - Endpoint 3 In Interrupt MaxPacket 16 Interval 4ms
> > >
> > > 4: Human Interface, USB Revision 1.10
> > >
> > > - LITEON Technology USB Multimedia Keyboard
> > >
> > > - Class: (from Interface) Human Interface
> > >
> > > - PacketSize: 8 Configurations: 1
> > >
> > > - Vendor: 0x046d Product 0xc312 Version 1.1
> > >
> > > Configuration: 1
> > >
> > > - Interfaces: 1 Bus Powered Remote Wakeup 70mA
> > >
> > > Interface: 0
> > >
> > > - Alternate Setting 0, Endpoints: 1
> > >
> > > - Class Human Interface, Subclass: Boot Keyboard
> > >
> > > - Endpoint 1 In Interrupt MaxPacket 8 Interval 24ms
> > >
> > > OMAP3 beagleboard.org #
> > >
> > >
> > >
> > > Thanks & Regards
> > > Atul Kumar
> > > 9845495793
1
0
Dear Atul Kumar,
> Dear Marek,
>
> I am tring to bring up USB Keyboard on u-boot with "Beagle_board
> xM ver B".. found number of post,but the stack is already updated one..
> I am able to find the info of the connected device but some how keyboard
> does not works.. can you suggest/guide me were i am making mistake or
> where I need to do some device specific changes..
>
Please always CC the U-Boot mailing list (CCed).
Did you try running "coninfo" after the "usb reset"/"usb start"? What does it
output, do you see "usbkbd" there? Wild guess would be to run "setenv stdin
usbkbd" or something after you do "usb reset".
> *logs for "usb start"*
>
> OMAP3 beagleboard.org #
>
> usb start
>
> (Re)start USB...
>
> USB: Initializing OMAP EHCI
>
> OMAP UHH_REV
>
> ISION 0x10
>
> OMAP EHCI init done
>
> Register 1313 NbrPorts 3
>
> USB EHCI 1.00
>
> scanning bus for devices...
>
> 4 USB Device(s) found
>
> USB KBD: found set protocol...
>
> USB KBD: found set idle...
>
> USB
>
> KBD: enable interrupt pipe...
>
> USB KBD: found set up device.
>
> USB KBD: register.
>
> usb_kbd_dev.name- usbkbd
>
> before stdio register
>
> clone _dev->name-usbkbd,dev->name-usbkbd
>
> in stdio register,usb_kbd_dev.name- usbkbd
>
> After stdio register
>
> before strcmp
>
> stdin name- *serial*
>
> scan end
>
> scanning bus for storage devices... 0 Storage Device(s) found
>
> scanning bus for ethernet devices... Warning: failed to set MAC address
>
> 1 Ethernet Device(s) found
>
> OMAP3 beagleboard.org #
>
> *logs for "usb info"*
>
> OMAP3 beagleboard.org #
>
> usb info
>
> 1: Hub, USB Revision 2.0
>
> - u-boot EHCI Host Controller
>
> - Class: Hub
>
> - PacketSize: 64 Configurations: 1
>
> -
>
> Vendor: 0x0000 Product 0x0000 Version 1.0
>
> Configuration: 1
>
> - Interfaces: 1 Self Powered 0mA
>
> Interface: 0
>
> - Alternate Setting 0, Endpoints: 1
>
> - Class Hub
>
> - Endpoint 1 In Interrupt MaxPacket 8 Interval 255ms
>
> 2: Hub, USB Revision 2.0
>
> - Class: Hub
>
> - PacketSize: 64 Configurations: 1
>
> - Vendor: 0x0424 Product 0x9514 Version 2.0
>
> Configuration: 1
>
> - Interfaces: 1 Self Powered Remote Wakeup 2mA
>
> Interface: 0
>
> - Alternate Setting 0, Endpoints: 1
>
> - Class Hub
>
> - Endpoint 1 In Interrupt MaxPacket 1 Interval 12ms
>
> - Endpoint 1 In Interrupt MaxPacket 1 Interval 12ms
>
> 3: Vendor specific, USB Revision 2.0
>
> - Class: Vendor specific
>
> - PacketSize: 64 Configurations: 1
>
> - Vendor: 0x0424 Product 0xec00 Version 2.0
>
> Configuration: 1
>
> - Interfaces: 1 Self Powered Remote Wakeup 2mA
>
> Interface: 0
>
> - Alternate Setting 0, Endpoints: 3
>
> - Class Vendor specific
>
> - Endpoint 1 In Bulk MaxPacket 512
>
> - Endpoint 2 Out Bulk MaxPacket 512
>
> - Endpoint 3 In Interrupt MaxPacket 16 Interval 4ms
>
> 4: Human Interface, USB Revision 1.10
>
> - LITEON Technology USB Multimedia Keyboard
>
> - Class: (from Interface) Human Interface
>
> - PacketSize: 8 Configurations: 1
>
> - Vendor: 0x046d Product 0xc312 Version 1.1
>
> Configuration: 1
>
> - Interfaces: 1 Bus Powered Remote Wakeup 70mA
>
> Interface: 0
>
> - Alternate Setting 0, Endpoints: 1
>
> - Class Human Interface, Subclass: Boot Keyboard
>
> - Endpoint 1 In Interrupt MaxPacket 8 Interval 24ms
>
> OMAP3 beagleboard.org #
>
>
>
> Thanks & Regards
> Atul Kumar
> 9845495793
1
0
Has anyone implemented a command to use lzma and/or bzip to decompress
files in memory like unzip?
-Aaron
--
Aaron Williams
Software Engineer
Cavium, Inc.
(408) 943-7198 (510) 789-8988 (cell)
1
0

10 May '12
This macro is generally useful to make it available in common.
Signed-off-by: Simon Glass <sjg(a)chromium.org>
---
Changes in v3:
- Add new patch to put abs() in common.h
Changes in v6:
- Update x86emu and omap4 to use the abs() macro
arch/arm/cpu/armv7/omap4/clocks.c | 2 --
drivers/bios_emulator/x86emu/prim_ops.c | 5 -----
include/common.h | 13 +++++++++++++
3 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap4/clocks.c b/arch/arm/cpu/armv7/omap4/clocks.c
index e2189f7..ce3f59c 100644
--- a/arch/arm/cpu/armv7/omap4/clocks.c
+++ b/arch/arm/cpu/armv7/omap4/clocks.c
@@ -46,8 +46,6 @@
#define puts(s)
#endif
-#define abs(x) (((x) < 0) ? ((x)*-1) : (x))
-
struct omap4_prcm_regs *const prcm = (struct omap4_prcm_regs *)0x4A004100;
const u32 sys_clk_array[8] = {
diff --git a/drivers/bios_emulator/x86emu/prim_ops.c b/drivers/bios_emulator/x86emu/prim_ops.c
index 7553087..5f6c795 100644
--- a/drivers/bios_emulator/x86emu/prim_ops.c
+++ b/drivers/bios_emulator/x86emu/prim_ops.c
@@ -118,11 +118,6 @@ static u32 x86emu_parity_tab[8] =
#define PARITY(x) (((x86emu_parity_tab[(x) / 32] >> ((x) % 32)) & 1) == 0)
#define XOR2(x) (((x) ^ ((x)>>1)) & 0x1)
-/*----------------------------- Implementation ----------------------------*/
-int abs(int v)
-{
- return (v>0)?v:-v;
-}
/*----------------------------- Implementation ----------------------------*/
diff --git a/include/common.h b/include/common.h
index 74d9704..92eac2c 100644
--- a/include/common.h
+++ b/include/common.h
@@ -229,6 +229,19 @@ ulong timer_get_boot_us(void);
#define MIN(x, y) min(x, y)
#define MAX(x, y) max(x, y)
+/*
+ * Return the absolute value of a number. This handles unsigned ints, shorts
+ * and chars and returns a signed long.
+ */
+#define abs(x) ({ \
+ long ret; \
+ { \
+ typeof((x)) __x = (x); \
+ ret = (__x < 0) ? -__x : __x; \
+ } \
+ ret; \
+ })
+
#if defined(CONFIG_ENV_IS_EMBEDDED)
#define TOTAL_MALLOC_LEN CONFIG_SYS_MALLOC_LEN
#elif ( ((CONFIG_ENV_ADDR+CONFIG_ENV_SIZE) < CONFIG_SYS_MONITOR_BASE) || \
--
1.7.7.3
3
5

[U-Boot] [PATCH v3 4/5] Add support for qc_mmc MMC Controller
by mohamed.haneef@lntinfotech.com 10 May '12
by mohamed.haneef@lntinfotech.com 10 May '12
10 May '12
From: Mohamed Haneef <mohamed.haneef(a)lntinfotech.com>
* Support for qc_mmc MMC Controller
Signed-off-by: Mohamed Haneef <mohamed.haneef(a)lntinfotech.com>
changes for v2:
- changed the patch title to support for qc_mmc MMC Controller
changes for v3:
- removed the unnecessary type casting
- simplified the code by making use of struct mmc_priv *priv variable.
- removed unused defines.
---
arch/arm/include/asm/arch-msm7630/mmc.h | 390 +++++++++++++++++++++
drivers/mmc/Makefile | 1 +
drivers/mmc/qc_mmc.c | 581 +++++++++++++++++++++++++++++++
3 files changed, 972 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/include/asm/arch-msm7630/mmc.h
create mode 100644 drivers/mmc/qc_mmc.c
diff --git a/arch/arm/include/asm/arch-msm7630/mmc.h b/arch/arm/include/asm/arch-msm7630/mmc.h
new file mode 100644
index 0000000..75beffc
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/mmc.h
@@ -0,0 +1,390 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN AND TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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
+ *
+ */
+
+#ifndef __MMC_H__
+#define __MMC_H__
+
+
+#include <common.h>
+#include <part.h>
+#include <mmc.h>
+
+/*
+ * Define Macros for SDCC Registers
+ */
+/* 8 bit */
+#define MMC_BOOT_MCI_POWER 0x000
+
+/* MCICMD output control - 6th bit */
+#ifdef PLATFORM_MSM7X30
+#define MMC_BOOT_MCI_OPEN_DRAIN (1 << 6)
+#define MMC_BOOT_MCI_PWR_OFF 0x00
+#define MMC_BOOT_MCI_PWR_UP 0x01
+#define MMC_BOOT_MCI_PWR_ON 0x01
+#else
+#define MMC_BOOT_MCI_OPEN_DRAIN (1 << 6)
+#define MMC_BOOT_MCI_PWR_OFF 0x00
+#define MMC_BOOT_MCI_PWR_UP 0x02
+#define MMC_BOOT_MCI_PWR_ON 0x03
+#endif
+
+/* 16 bits */
+#define MMC_BOOT_MCI_CLK 0x004
+/* Enable MCI bus clock - 0: clock disabled 1: enabled */
+#define MMC_BOOT_MCI_CLK_ENABLE (1 << 8)
+/* Disable clk o/p when bus idle- 0:always enabled 1:enabled when bus active */
+#define MMC_BOOT_MCI_CLK_PWRSAVE (1 << 9)
+/* Enable Widebus mode - 00: 1 bit mode 10:4 bit mode 01/11: 8 bit mode */
+#define MMC_BOOT_MCI_CLK_WIDEBUS_MODE (3 << 10)
+#define MMC_BOOT_MCI_CLK_WIDEBUS_1_BIT 0
+#define MMC_BOOT_MCI_CLK_WIDEBUS_4_BIT (2 << 10)
+#define MMC_BOOT_MCI_CLK_WIDEBUS_8_BIT (1 << 10)
+/* Enable flow control- 0: disable 1: enable */
+#define MMC_BOOT_MCI_CLK_ENA_FLOW (1 << 12)
+/* Set/clear to select rising/falling edge for data/cmd output */
+#define MMC_BOOT_MCI_CLK_INVERT_OUT (1 << 13)
+/* Select to lach data/cmd coming in falling/rising/feedbk/loopbk of MCIclk */
+#define MMC_BOOT_MCI_CLK_IN_FALLING 0x0
+#define MMC_BOOT_MCI_CLK_IN_RISING (1 << 14)
+#define MMC_BOOT_MCI_CLK_IN_FEEDBACK (2 << 14)
+#define MMC_BOOT_MCI_CLK_IN_LOOPBACK (3 << 14)
+
+/* Bus Width */
+#define MMC_BOOT_BUS_WIDTH_1_BIT 0
+#define MMC_BOOT_BUS_WIDTH_4_BIT 2
+#define MMC_BOOT_BUS_WIDTH_8_BIT 3
+
+/* 32 bits */
+#define MMC_BOOT_MCI_ARGUMENT 0x008
+
+/* 16 bits */
+#define MMC_BOOT_MCI_CMD 0x00C
+/* Command Index: 0 -5 */
+/* Waits for response if set */
+#define MMC_BOOT_MCI_CMD_RESPONSE (1 << 6)
+/* Receives a 136-bit long response if set */
+#define MMC_BOOT_MCI_CMD_LONGRSP (1 << 7)
+/* If set, CPSM disables command timer and waits for interrupt */
+#define MMC_BOOT_MCI_CMD_INTERRUPT (1 << 8)
+/* If set waits for CmdPend before starting to send a command */
+#define MMC_BOOT_MCI_CMD_PENDING (1 << 9)
+/* CPSM is enabled if set */
+#define MMC_BOOT_MCI_CMD_ENABLE (1 << 10)
+/* If set PROG_DONE status bit asserted when busy is de-asserted */
+#define MMC_BOOT_MCI_CMD_PROG_ENA (1 << 11)
+/* To indicate that this is a Command with Data (for SDIO interrupts) */
+#define MMC_BOOT_MCI_CMD_DAT_CMD (1 << 12)
+/* Signals the next command to be an abort (stop) command. Always read 0 */
+#define MMC_BOOT_MCI_CMD_MCIABORT (1 << 13)
+/* Waits for Command Completion Signal if set */
+#define MMC_BOOT_MCI_CMD_CCS_ENABLE (1 << 14)
+/* If set sends CCS disable sequence */
+#define MMC_BOOT_MCI_CMD_CCS_DISABLE (1 << 15)
+
+#define MMC_BOOT_MCI_RESP_CMD 0x010
+
+#define MMC_BOOT_MCI_RESP_0 0x014
+#define MMC_BOOT_MCI_RESP_1 0x018
+#define MMC_BOOT_MCI_RESP_2 0x01C
+#define MMC_BOOT_MCI_RESP_3 0x020
+
+#define MMC_BOOT_MCI_DATA_TIMER 0x024
+#define MMC_BOOT_MCI_DATA_LENGTH 0x028
+/* 16 bits */
+#define MMC_BOOT_MCI_DATA_CTL 0x02C
+/* Data transfer enabled */
+#define MMC_BOOT_MCI_DATA_ENABLE (1 << 0)
+/* Data transfer direction - 0: controller to card 1:card to controller */
+#define MMC_BOOT_MCI_DATA_DIR (1 << 1)
+/* Data transfer mode - 0: block data transfer 1: stream data transfer */
+#define MMC_BOOT_MCI_DATA_MODE (1 << 2)
+/* Enable DM interface - 0: DM disabled 1: DM enabled */
+#define MMC_BOOT_MCI_DATA_DM_ENABLE (1 << 3)
+/* Data block length in bytes (1-4096) */
+#define MMC_BOOT_MCI_BLKSIZE_POS 4
+#define MMC_BOOT_MCI_DATA_COUNT 0x030
+#define MMC_BOOT_MCI_STATUS 0x034
+/* Command response received - CRC check failed */
+#define MMC_BOOT_MCI_STAT_CMD_CRC_FAIL (1 << 0)
+/* Data block sent/received - CRC check failed */
+#define MMC_BOOT_MCI_STAT_DATA_CRC_FAIL (1 << 1)
+/* Command resonse timeout */
+#define MMC_BOOT_MCI_STAT_CMD_TIMEOUT (1 << 2)
+/* Data timeout */
+#define MMC_BOOT_MCI_STAT_DATA_TIMEOUT (1 << 3)
+/* Transmit FIFO underrun error */
+#define MMC_BOOT_MCI_STAT_TX_UNDRUN (1 << 4)
+/* Receive FIFO overrun error */
+#define MMC_BOOT_MCI_STAT_RX_OVRRUN (1 << 5)
+/* Command response received - CRC check passed */
+#define MMC_BOOT_MCI_STAT_CMD_RESP_END (1 << 6)
+/* Command sent - no response required */
+#define MMC_BOOT_MCI_STAT_CMD_SENT (1 << 7)
+/* Data end - data counter zero */
+#define MMC_BOOT_MCI_STAT_DATA_END (1 << 8)
+/* Start bit not detected on all data signals in wide bus mode */
+#define MMC_BOOT_MCI_STAT_START_BIT_ERR (1 << 9)
+/* Data block sent/received - CRC check passed */
+#define MMC_BOOT_MCI_STAT_DATA_BLK_END (1 << 10)
+/* Command transfer in progress */
+#define MMC_BOOT_MCI_STAT_CMD_ACTIVE (1 << 11)
+/* Data transmit in progress */
+#define MMC_BOOT_MCI_STAT_TX_ACTIVE (1 << 12)
+/* Data receive in progress */
+#define MMC_BOOT_MCI_STAT_RX_ACTIVE (1 << 13)
+/* Transmit FIFO half full */
+#define MMC_BOOT_MCI_STAT_TX_FIFO_HFULL (1 << 14)
+/* Receive FIFO half full */
+#define MMC_BOOT_MCI_STAT_RX_FIFO_HFULL (1 << 15)
+/* Transmit FIFO full */
+#define MMC_BOOT_MCI_STAT_TX_FIFO_FULL (1 << 16)
+/* Receive FIFO full */
+#define MMC_BOOT_MCI_STAT_RX_FIFO_FULL (1 << 17)
+/* Transmit FIFO empty */
+#define MMC_BOOT_MCI_STAT_TX_FIFO_EMPTY (1 << 18)
+/* Receive FIFO empty */
+#define MMC_BOOT_MCI_STAT_RX_FIFO_EMPTY (1 << 19)
+/* Data available in transmit FIFO */
+#define MMC_BOOT_MCI_STAT_TX_DATA_AVLBL (1 << 20)
+/* Data available in receive FIFO */
+#define MMC_BOOT_MCI_STAT_RX_DATA_AVLBL (1 << 21)
+/* SDIO interrupt indicator for wake-up */
+#define MMC_BOOT_MCI_STAT_SDIO_INTR (1 << 22)
+/* Programming done */
+#define MMC_BOOT_MCI_STAT_PROG_DONE (1 << 23)
+/* CE-ATA command completion signal detected */
+#define MMC_BOOT_MCI_STAT_ATA_CMD_CMPL (1 << 24)
+/* SDIO interrupt indicator for normal operation */
+#define MMC_BOOT_MCI_STAT_SDIO_INTR_OP (1 << 25)
+/* Commpand completion signal timeout */
+#define MMC_BOOT_MCI_STAT_CCS_TIMEOUT (1 << 26)
+
+#define MMC_BOOT_MCI_STATIC_STATUS (MMC_BOOT_MCI_STAT_CMD_CRC_FAIL| \
+ MMC_BOOT_MCI_STAT_DATA_CRC_FAIL| \
+ MMC_BOOT_MCI_STAT_CMD_TIMEOUT| \
+ MMC_BOOT_MCI_STAT_DATA_TIMEOUT| \
+ MMC_BOOT_MCI_STAT_TX_UNDRUN| \
+ MMC_BOOT_MCI_STAT_RX_OVRRUN| \
+ MMC_BOOT_MCI_STAT_CMD_RESP_END| \
+ MMC_BOOT_MCI_STAT_CMD_SENT| \
+ MMC_BOOT_MCI_STAT_DATA_END| \
+ MMC_BOOT_MCI_STAT_START_BIT_ERR| \
+ MMC_BOOT_MCI_STAT_DATA_BLK_END| \
+ MMC_BOOT_MCI_SDIO_INTR_CLR| \
+ MMC_BOOT_MCI_STAT_PROG_DONE| \
+ MMC_BOOT_MCI_STAT_ATA_CMD_CMPL |\
+ MMC_BOOT_MCI_STAT_CCS_TIMEOUT)
+
+#define MMC_BOOT_MCI_CLEAR 0x038
+#define MMC_BOOT_MCI_CMD_CRC_FAIL_CLR (1 << 0)
+#define MMC_BOOT_MCI_DATA_CRC_FAIL_CLR (1 << 1)
+#define MMC_BOOT_MCI_CMD_TIMEOUT_CLR (1 << 2)
+#define MMC_BOOT_MCI_DATA_TIMEOUT_CLR (1 << 3)
+#define MMC_BOOT_MCI_TX_UNDERRUN_CLR (1 << 4)
+#define MMC_BOOT_MCI_RX_OVERRUN_CLR (1 << 5)
+#define MMC_BOOT_MCI_CMD_RESP_END_CLR (1 << 6)
+#define MMC_BOOT_MCI_CMD_SENT_CLR (1 << 7)
+#define MMC_BOOT_MCI_DATA_END_CLR (1 << 8)
+#define MMC_BOOT_MCI_START_BIT_ERR_CLR (1 << 9)
+#define MMC_BOOT_MCI_DATA_BLK_END_CLR (1 << 10)
+#define MMC_BOOT_MCI_SDIO_INTR_CLR (1 << 22)
+#define MMC_BOOT_MCI_PROG_DONE_CLR (1 << 23)
+#define MMC_BOOT_MCI_ATA_CMD_COMPLR_CLR (1 << 24)
+#define MMC_BOOT_MCI_CCS_TIMEOUT_CLR (1 << 25)
+
+#define MMC_BOOT_MCI_INT_MASK0 0x03C
+#define MMC_BOOT_MCI_CMD_CRC_FAIL_MASK (1 << 0)
+#define MMC_BOOT_MCI_DATA_CRC_FAIL_MASK (1 << 1)
+#define MMC_BOOT_MCI_CMD_TIMEOUT_MASK (1 << 2)
+#define MMC_BOOT_MCI_DATA_TIMEOUT_MASK (1 << 3)
+#define MMC_BOOT_MCI_TX_OVERRUN_MASK (1 << 4)
+#define MMC_BOOT_MCI_RX_OVERRUN_MASK (1 << 5)
+#define MMC_BOOT_MCI_CMD_RESP_END_MASK (1 << 6)
+#define MMC_BOOT_MCI_CMD_SENT_MASK (1 << 7)
+#define MMC_BOOT_MCI_DATA_END_MASK (1 << 8)
+#define MMC_BOOT_MCI_START_BIT_ERR_MASK (1 << 9)
+#define MMC_BOOT_MCI_DATA_BLK_END_MASK (1 << 10)
+#define MMC_BOOT_MCI_CMD_ACTIVE_MASK (1 << 11)
+#define MMC_BOOT_MCI_TX_ACTIVE_MASK (1 << 12)
+#define MMC_BOOT_MCI_RX_ACTIVE_MASK (1 << 13)
+#define MMC_BOOT_MCI_TX_FIFO_HFULL_MASK (1 << 14)
+#define MMC_BOOT_MCI_RX_FIFO_HFULL_MASK (1 << 15)
+#define MMC_BOOT_MCI_TX_FIFO_FULL_MASK (1 << 16)
+#define MMC_BOOT_MCI_RX_FIFO_FULL_MASK (1 << 17)
+#define MMC_BOOT_MCI_TX_FIFO_EMPTY_MASK (1 << 18)
+#define MMC_BOOT_MCI_RX_FIFO_EMPTY_MASK (1 << 19)
+#define MMC_BOOT_MCI_TX_DATA_AVLBL_MASK (1 << 20)
+#define MMC_BOOT_MCI_RX_DATA_AVLBL_MASK (1 << 21)
+#define MMC_BOOT_MCI_SDIO_INT_MASK (1 << 22)
+#define MMC_BOOT_MCI_PROG_DONE_MASK (1 << 23)
+#define MMC_BOOT_MCI_ATA_CMD_COMPL_MASK (1 << 24)
+#define MMC_BOOT_MCI_SDIO_INT_OPER_MASK (1 << 25)
+#define MMC_BOOT_MCI_CCS_TIME_OUT_MASK (1 << 26)
+
+#define MMC_BOOT_MCI_INT_MASK1 0x040
+
+#define MMC_BOOT_MCI_FIFO_COUNT 0x044
+
+#define MMC_BOOT_MCI_CCS_TIMER 0x0058
+
+#define MMC_BOOT_MCI_FIFO 0x080
+
+/* OCR Register */
+#define MMC_BOOT_OCR_17_19 (1 << 7)
+#define MMC_BOOT_OCR_27_36 (0x1FF << 15)
+#define MMC_BOOT_OCR_SEC_MODE (2 << 29)
+#define MMC_BOOT_OCR_BUSY (1 << 31)
+
+/* Commands type */
+#define MMC_BOOT_CMD_BCAST (1 << 0)
+#define MMC_BOOT_CMD_BCAST_W_RESP (1 << 1)
+#define MMC_BOOT_CMD_ADDRESS (1 << 2)
+#define MMC_BOOT_CMD_ADDR_DATA_XFER (1 << 3)
+
+/* Card Status bits (R1 register) */
+#define MMC_BOOT_R1_AKE_SEQ_ERROR (1 << 3)
+#define MMC_BOOT_R1_APP_CMD (1 << 5)
+#define MMC_BOOT_R1_RDY_FOR_DATA (1 << 6)
+#define MMC_BOOT_R1_CURR_STATE_IDLE (0 << 9)
+#define MMC_BOOT_R1_CURR_STATE_RDY (1 << 9)
+#define MMC_BOOT_R1_CURR_STATE_IDENT (2 << 9)
+#define MMC_BOOT_R1_CURR_STATE_STBY (3 << 9)
+#define MMC_BOOT_R1_CURR_STATE_TRAN (4 << 9)
+#define MMC_BOOT_R1_CURR_STATE_DATA (5 << 9)
+#define MMC_BOOT_R1_CURR_STATE_RCV (6 << 9)
+#define MMC_BOOT_R1_CURR_STATE_PRG (7 << 9)
+#define MMC_BOOT_R1_CURR_STATE_DIS (8 << 9)
+#define MMC_BOOT_R1_ERASE_RESET (1 << 13)
+#define MMC_BOOT_R1_CARD_ECC_DISABLED (1 << 14)
+#define MMC_BOOT_R1_WP_ERASE_SKIP (1 << 15)
+#define MMC_BOOT_R1_ERROR (1 << 19)
+#define MMC_BOOT_R1_CC_ERROR (1 << 20)
+#define MMC_BOOT_R1_CARD_ECC_FAILED (1 << 21)
+#define MMC_BOOT_R1_ILLEGAL_CMD (1 << 22)
+#define MMC_BOOT_R1_COM_CRC_ERR (1 << 23)
+#define MMC_BOOT_R1_LOCK_UNLOCK_FAIL (1 << 24)
+#define MMC_BOOT_R1_CARD_IS_LOCKED (1 << 25)
+#define MMC_BOOT_R1_WP_VIOLATION (1 << 26)
+#define MMC_BOOT_R1_ERASE_PARAM (1 << 27)
+#define MMC_BOOT_R1_ERASE_SEQ_ERR (1 << 28)
+#define MMC_BOOT_R1_BLOCK_LEN_ERR (1 << 29)
+#define MMC_BOOT_R1_ADDR_ERR (1 << 30)
+#define MMC_BOOT_R1_OUT_OF_RANGE (1 << 31)
+
+/* Macros for Common Errors */
+#define MMC_BOOT_E_SUCCESS 0
+#define MMC_BOOT_E_FAILURE 1
+/* Not used..use instead TIMEOUT in include/mmc.h */
+#define MMC_BOOT_E_TIMEOUT 2
+#define MMC_BOOT_E_INVAL 3
+#define MMC_BOOT_E_CRC_FAIL 4
+#define MMC_BOOT_E_INIT_FAIL 5
+#define MMC_BOOT_E_CMD_INDX_MISMATCH 6
+#define MMC_BOOT_E_RESP_VERIFY_FAIL 7
+#define MMC_BOOT_E_NOT_SUPPORTED 8
+#define MMC_BOOT_E_CARD_BUSY 9
+#define MMC_BOOT_E_MEM_ALLOC_FAIL 10
+#define MMC_BOOT_E_CLK_ENABLE_FAIL 11
+#define MMC_BOOT_E_CMMC_DECODE_FAIL 12
+#define MMC_BOOT_E_CID_DECODE_FAIL 13
+#define MMC_BOOT_E_BLOCKLEN_ERR 14
+#define MMC_BOOT_E_ADDRESS_ERR 15
+#define MMC_BOOT_E_DATA_CRC_FAIL 16
+#define MMC_BOOT_E_DATA_TIMEOUT 17
+#define MMC_BOOT_E_RX_OVRRUN 18
+#define MMC_BOOT_E_VREG_SET_FAILED 19
+#define MMC_BOOT_E_GPIO_CFG_FAIL 20
+#define MMC_BOOT_E_DATA_ADM_ERR 21
+
+/* EXT_CSD */
+#define MMC_BOOT_ACCESS_WRITE 0x3
+#define MMC_BOOT_EXT_CMMC_HS_TIMING 185
+#define MMC_BOOT_EXT_CMMC_BUS_WIDTH 183
+
+#define MMC_BOOT_EXT_USER_WP 171
+#define MMC_BOOT_EXT_ERASE_GROUP_DEF 175
+#define MMC_BOOT_EXT_HC_WP_GRP_SIZE 221
+#define MMC_BOOT_EXT_HC_ERASE_GRP_SIZE 224
+
+#define MMC_BOOT_US_PERM_WP_EN 2
+#define MMC_BOOT_US_PWR_WP_DIS 3
+
+#define MMC_BOOT_US_PERM_WP_DIS (1<<4)
+#define MMC_BOOT_US_PWR_WP_EN 1
+
+/* For SD */
+#define MMC_BOOT_SD_HC_VOLT_SUPPLIED 0x000001AA
+#define MMC_BOOT_SD_NEG_OCR 0x00FF8000
+#define MMC_BOOT_SD_HC_HCS 0x40000000
+#define MMC_BOOT_SD_DEV_READY 0x80000000
+#define MMC_BOOT_SD_SWITCH_HS 0x80FFFFF1
+
+/* Data structure definitions */
+
+#define MMC_BOOT_XFER_MODE_BLOCK 0
+#define MMC_BOOT_XFER_MODE_STREAM 1
+#define MMC_BOOT_PROGRAM_ENABLED 2
+
+
+#define MMC_RCA 2
+
+#define MMC_BOOT_MAX_COMMAND_RETRY 1000
+#define MMC_BOOT_RD_BLOCK_LEN 512
+#define MMC_BOOT_WR_BLOCK_LEN 512
+
+/* We have 16 32-bits FIFO registers */
+#define MMC_BOOT_MCI_FIFO_DEPTH 16
+#define MMC_BOOT_MCI_HFIFO_COUNT (MMC_BOOT_MCI_FIFO_DEPTH / 2)
+#define MMC_BOOT_MCI_FIFO_SIZE (MMC_BOOT_MCI_FIFO_DEPTH * 4)
+
+#define MAX_PARTITIONS 64
+
+#define MMC_BOOT_CHECK_PATTERN 0xAA /* 10101010b */
+
+#define MMC_CLK_400KHZ 400000
+#define MMC_CLK_144KHZ 144000
+#define MMC_CLK_20MHZ 20000000
+#define MMC_CLK_24MHZ 24000000
+#define MMC_CLK_25MHZ 25000000
+#define MMC_CLK_26MHZ 26000000
+#define MMC_CLK_48MHZ 48000000
+#define MMC_CLK_50MHZ 49152000
+#define MMC_CLK_52MHZ 52000000
+
+#define MMC_CLK_ENABLE 1
+#define MMC_CLK_DISABLE 0
+
+struct mmc_priv {
+ unsigned int instance;
+ unsigned int base;
+ unsigned int rd_timeout_ns; /* for read timeout */
+};
+
+void mmc_boot_set_ios(struct mmc *mmc);
+int mmc_boot_send_command_map(struct mmc *mmc,
+ struct mmc_cmd *cmd,
+ struct mmc_data *data);
+unsigned long int mmc_boot_mci_reg(unsigned long base, unsigned long offset);
+unsigned int mmc_boot_main(struct mmc *mmc);
+
+extern void clock_config_mmc(uint32_t interface, uint32_t freq);
+extern void clock_init_mmc(uint32_t interface);
+#endif
+
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 506f1d6..2d926ec 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -44,6 +44,7 @@ COBJS-$(CONFIG_S5P_MMC) += s5p_mmc.o
COBJS-$(CONFIG_SDHCI) += sdhci.o
COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o
COBJS-$(CONFIG_TEGRA2_MMC) += tegra2_mmc.o
+COBJS-$(CONFIG_QC_MMC) += qc_mmc.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/mmc/qc_mmc.c b/drivers/mmc/qc_mmc.c
new file mode 100644
index 0000000..db7637c
--- /dev/null
+++ b/drivers/mmc/qc_mmc.c
@@ -0,0 +1,581 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN AND TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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/types.h>
+#include <asm/io.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/iomap.h>
+#include <common.h>
+
+#if MMC_BOOT_ADM
+#include "adm.h"
+#endif
+
+
+#define MMC_BOOT_DATA_READ 0
+#define MMC_BOOT_DATA_WRITE 1
+/*
+ * Calculates the address of registers according to the base address
+ */
+unsigned long int mmc_boot_mci_reg(unsigned long base, unsigned long offset)
+{
+ return base + offset;
+}
+
+
+/*
+ * Sets a timeout for read operation.
+ */
+static unsigned int mmc_boot_set_read_timeout(struct mmc *mmc)
+{
+ if (mmc == NULL)
+ return MMC_BOOT_E_INVAL;
+
+ /* todo: Add a check for HC, only if HC do this.
+ * If not, taac and nsac must be taken into account
+ */
+ struct mmc_priv *priv = mmc->priv;
+ priv->rd_timeout_ns = 100000000;
+ debug(" Read timeout set: %d ns\n",
+ priv->rd_timeout_ns);
+
+ return MMC_BOOT_E_SUCCESS;
+}
+
+/*
+ * Check to ensure that there is no alignment or data length errors
+ */
+static unsigned int mmc_boot_check_read_data(struct mmc_cmd *cmd)
+{
+
+ if (cmd->response[0] & MMC_BOOT_R1_BLOCK_LEN_ERR)
+ return MMC_BOOT_E_BLOCKLEN_ERR;
+
+ /* Misaligned address not matching block length */
+ if (cmd->response[0] & MMC_BOOT_R1_ADDR_ERR)
+ return MMC_BOOT_E_ADDRESS_ERR;
+
+ return MMC_BOOT_E_SUCCESS;
+}
+
+/*
+ * Decode type of error caused during read and write
+ */
+static unsigned int mmc_boot_status_error(unsigned mmc_status)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+ /* If DATA_CRC_FAIL bit is set to 1 then CRC error
+ * was detected by card/device during the data transfer
+ */
+ if (mmc_status & MMC_BOOT_MCI_STAT_DATA_CRC_FAIL)
+ mmc_ret = MMC_BOOT_E_DATA_CRC_FAIL;
+ /* If DATA_TIMEOUT bit is set to 1 then the data transfer time
+ * exceeded the data timeout period without completing the
+ * transfer
+ */
+ else if (mmc_status & MMC_BOOT_MCI_STAT_DATA_TIMEOUT)
+ mmc_ret = MMC_BOOT_E_DATA_TIMEOUT;
+ /* If RX_OVERRUN bit is set to 1 then SDCC2 tried to
+ * receive data from the card before empty storage for new
+ * received data was available.
+ * Verify that bit FLOW_ENA in MCI_CLK is set to 1 during
+ * the data xfer.
+ */
+ else if (mmc_status & MMC_BOOT_MCI_STAT_RX_OVRRUN)
+ /* Note: We've set FLOW_ENA bit in MCI_CLK to 1.
+ * so no need to verify for now
+ */
+ mmc_ret = MMC_BOOT_E_RX_OVRRUN;
+ /* If TX_UNDERRUN bit is set to 1 then SDCC2 tried to send
+ * data to the card before new data for sending was available.
+ * Verify that bit FLOW_ENA in MCI_CLK
+ * is set to 1 during the data xfer.
+ */
+ else if (mmc_status & MMC_BOOT_MCI_STAT_TX_UNDRUN)
+ /* Note: We've set FLOW_ENA bit in MCI_CLK to 1.
+ * so skipping it now
+ */
+ mmc_ret = MMC_BOOT_E_RX_OVRRUN;
+
+ return mmc_ret;
+}
+
+/*
+ * Read data to SDC FIFO.
+ */
+static unsigned int mmc_boot_fifo_read(u32 *mmc_ptr,
+ unsigned int data_len,
+ struct mmc *mmc)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+ unsigned int mmc_status = 0;
+ unsigned int mmc_count = 0;
+ unsigned int read_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL | \
+ MMC_BOOT_MCI_STAT_DATA_TIMEOUT | \
+ MMC_BOOT_MCI_STAT_RX_OVRRUN;
+ unsigned int i;
+ struct mmc_priv *priv = mmc->priv;
+ unsigned long reg_status, reg_fifo;
+
+ reg_status = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_STATUS);
+ reg_fifo = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_FIFO);
+
+ /* Read the data from the MCI_FIFO register as long as
+ * RXDATA_AVLBL bit of MCI_STATUS register is set to 1 and bits
+ * DATA_CRC_FAIL, DATA_TIMEOUT, RX_OVERRUN of MCI_STATUS
+ * register are cleared to 0.
+ * Continue the reads until the whole transfer data is received
+ */
+
+ do {
+ mmc_ret = MMC_BOOT_E_SUCCESS;
+ mmc_status = readl(reg_status);
+
+ if (mmc_status & read_error) {
+ mmc_ret = mmc_boot_status_error(mmc_status);
+ break;
+ }
+
+ if (mmc_status & MMC_BOOT_MCI_STAT_RX_DATA_AVLBL) {
+ unsigned read_count = 1;
+ if (mmc_status & MMC_BOOT_MCI_STAT_RX_FIFO_HFULL)
+ read_count = MMC_BOOT_MCI_HFIFO_COUNT;
+
+ for (i = 0; i < read_count; i++) {
+ /* FIFO contains 16 32-bit data buffer
+ * on 16 sequential addresses
+ */
+ *mmc_ptr = readl(reg_fifo +
+ (mmc_count % MMC_BOOT_MCI_FIFO_SIZE));
+ mmc_ptr++;
+ /* increase mmc_count by amount od data read */
+ mmc_count += sizeof(*mmc_ptr);
+ }
+ /* quit if we have read enough of data */
+ if (mmc_count == data_len)
+ break;
+ } else if (mmc_status & MMC_BOOT_MCI_STAT_DATA_END)
+ break;
+ } while (1);
+ return mmc_ret;
+}
+
+static unsigned int mmc_boot_fifo_data_transfer(unsigned int *data_ptr,
+ unsigned int data_len,
+ unsigned char direction,
+ struct mmc *mmc)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+ if (direction == MMC_BOOT_DATA_READ)
+ mmc_ret = mmc_boot_fifo_read(data_ptr, data_len, mmc);
+
+ return mmc_ret;
+}
+
+/*
+ * Sends specified command to a card and waits for a response.
+ */
+static unsigned int mmc_boot_send_command(struct mmc_cmd *cmd,
+ struct mmc *mmc)
+{
+ unsigned int mmc_cmd = 0;
+ unsigned int mmc_status = 0;
+ unsigned int mmc_resp = 0;
+ unsigned int mmc_return = MMC_BOOT_E_SUCCESS;
+ unsigned int cmd_index = 0;
+ int i = 0;
+ unsigned long reg, reg_status, reg_resp_cmd, reg_resp_0;
+ struct mmc_priv *priv = mmc->priv;
+
+ /* basic check */
+ if (cmd == NULL)
+ return MMC_BOOT_E_INVAL;
+
+ /* 1. Write command argument to MMC_BOOT_MCI_ARGUMENT register */
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_ARGUMENT);
+ writel(cmd->cmdarg, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+ /* 2. Set appropriate fields and write MMC_BOOT_MCI_CMD */
+ /* 2a. Write command index in CMD_INDEX field */
+ cmd_index = cmd->cmdidx;
+ mmc_cmd |= cmd->cmdidx;
+ /* 2b. Set RESPONSE bit to 1 for all cmds except CMD0 */
+ if (cmd_index != MMC_CMD_GO_IDLE_STATE)
+ mmc_cmd |= MMC_BOOT_MCI_CMD_RESPONSE;
+
+ /* 2c. Set LONGRESP bit to 1 for CMD2, CMD9 and CMD10 */
+ if (cmd->resp_type & MMC_RSP_136)
+ mmc_cmd |= MMC_BOOT_MCI_CMD_LONGRSP;
+
+ /* 2d. Set INTERRUPT bit to 1 to disable command timeout */
+
+ /* 2e. Set PENDING bit to 1 for CMD12 in the beginning of stream
+ * mode data transfer
+ */
+ if (cmd->flags & MMC_BOOT_XFER_MODE_STREAM)
+ mmc_cmd |= MMC_BOOT_MCI_CMD_PENDING;
+
+ /* 2f. Set ENABLE bit to 1 */
+ mmc_cmd |= MMC_BOOT_MCI_CMD_ENABLE;
+
+ /* 2g. Set PROG_ENA bit to 1 for CMD12, CMD13 issued at the end of
+ * write data transfer
+ */
+ if ((cmd_index == MMC_CMD_STOP_TRANSMISSION ||
+ cmd_index == MMC_CMD_SEND_STATUS) &&
+ (cmd->flags & MMC_BOOT_PROGRAM_ENABLED))
+ mmc_cmd |= MMC_BOOT_MCI_CMD_PROG_ENA;
+
+
+ /* 2h. Set MCIABORT bit to 1 for CMD12 when working with SDIO card */
+ /* 2i. Set CCS_ENABLE bit to 1 for CMD61 when Command Completion Signal
+ * of CE-ATA device is enabled
+ */
+
+ /* 2j. clear all static status bits */
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_CLEAR);
+ writel(MMC_BOOT_MCI_STATIC_STATUS, reg);
+
+ /* 2k. Write to MMC_BOOT_MCI_CMD register */
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_CMD);
+ writel(mmc_cmd, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+ reg_status = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_STATUS);
+ reg_resp_cmd = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_RESP_CMD);
+ reg_resp_0 = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_RESP_0);
+
+ /* 3. Wait for interrupt or poll on the following bits of MCI_STATUS
+ * register
+ */
+ do {
+ /* 3a. Read MCI_STATUS register */
+ mmc_status = readl(reg_status);
+ while (mmc_status & MMC_BOOT_MCI_STAT_CMD_ACTIVE)
+ mmc_status = readl(reg_status);
+
+ /* 3b. CMD_SENT bit supposed to be set to 1 only
+ * after CMD0 is sent -no response required.
+ */
+ if ((cmd->resp_type == MMC_RSP_NONE) &&
+ (mmc_status & MMC_BOOT_MCI_STAT_CMD_SENT))
+ break;
+
+ /* 3c. If CMD_TIMEOUT bit is set then no response
+ * was received */
+ else if (mmc_status & MMC_BOOT_MCI_STAT_CMD_TIMEOUT) {
+ mmc_return = TIMEOUT;
+ break;
+ }
+ /* 3d. If CMD_RESPONSE_END bit is set to 1 then command's
+ * response was received and CRC check passed
+ * Spcial case for ACMD41: it seems to always fail CRC even if
+ * the response is valid
+ */
+ else if ((mmc_status & MMC_BOOT_MCI_STAT_CMD_RESP_END) ||
+ (cmd_index == MMC_CMD_SEND_OP_COND)
+ || (cmd_index == SD_CMD_SEND_IF_COND)) {
+ /* 3i. Read MCI_RESP_CMD register to verify that
+ * response index is equal to command index
+ */
+ mmc_resp = readl(reg_resp_cmd) & 0x3F;
+
+ /* However, long response does not contain the
+ * command index field.
+ * In that case, response index field must be set to
+ * 111111b (0x3F)
+ */
+ if ((mmc_resp == cmd_index) ||
+ (cmd->resp_type == MMC_RSP_R2 ||
+ cmd->resp_type == MMC_RSP_R3 ||
+ cmd->resp_type == MMC_RSP_R6 ||
+ cmd->resp_type == MMC_RSP_R7)){
+ /* 3j. If resp index is equal to cmd index,
+ * read command resp from MCI_RESPn registers
+ * - MCI_RESP0/1/2/3 for CMD2/9/10
+ * - MCI_RESP0 for all other registers
+ */
+ if (cmd->resp_type & MMC_RSP_136) {
+ for (i = 0; i < 4; i++)
+ cmd->response[3-i] =
+ readl(reg_resp_0 + \
+ (i * 4));
+ } else
+ cmd->response[0] = readl(reg_resp_0);
+ } else
+ /* command index mis-match */
+ mmc_return = MMC_BOOT_E_CMD_INDX_MISMATCH;
+
+ break;
+ }
+
+ /* 3e. If CMD_CRC_FAIL bit is set to 1 then cmd's response
+ * was recvd, but CRC check failed.
+ */
+ else if ((mmc_status & MMC_BOOT_MCI_STAT_CMD_CRC_FAIL)) {
+ if (cmd_index == SD_CMD_APP_SEND_OP_COND)
+ cmd->response[0] = readl(reg_resp_0);
+ else
+ mmc_return = MMC_BOOT_E_CRC_FAIL;
+ break;
+ }
+
+ } while (1);
+
+ return mmc_return;
+}
+
+static void mmc_boot_init_data(struct mmc *mmc, struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ uint32_t data_ctrl, mmc_reg, data_len;
+ struct mmc_priv *priv = mmc->priv;
+ unsigned long reg;
+
+ /* Write data timeout period to MCI_DATA_TIMER register. */
+ /* Data timeout period should be in card bus clock periods */
+ mmc_reg = (unsigned long)(priv->rd_timeout_ns /
+ 1000000) * (mmc->clock / 1000);
+ /* add some extra clock cycles to be safe */
+ mmc_reg += 1000;
+ mmc_reg = mmc_reg/2;
+
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_TIMER);
+ writel(mmc_reg, reg);
+
+ /* Write the total size of the transfer data to MCI_DATA_LENGTH
+ * register. For block xfer it must be multiple of the block
+ * size.
+ */
+
+ data_len = data->blocks*data->blocksize;
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_LENGTH);
+ writel(data_len, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+ data_ctrl = MMC_BOOT_MCI_DATA_ENABLE |
+ (data->blocksize << MMC_BOOT_MCI_BLKSIZE_POS);
+
+
+ if (data->flags == MMC_DATA_READ)
+ data_ctrl |= MMC_BOOT_MCI_DATA_DIR;
+
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_CTL);
+ writel(data_ctrl, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+}
+
+/*
+ * Function to map mmc send command to board send command
+ */
+int mmc_boot_send_command_map(struct mmc *mmc,
+ struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+ /* todo: do we need to fill in command type ?? */
+
+ if (cmd->cmdidx == MMC_CMD_SEND_STATUS) {
+ /* u-boot doesn't fill in the correct argument value */
+ cmd->cmdarg = mmc->rca << 16;
+ /* this is to explicitly disable the prg enabled flag */
+ cmd->flags &= ~MMC_BOOT_PROGRAM_ENABLED;
+
+ } else if (cmd->cmdidx == MMC_CMD_READ_SINGLE_BLOCK) {
+ if (mmc->read_bl_len != MMC_BOOT_RD_BLOCK_LEN &&
+ mmc->version & SD_VERSION_SD) {
+ mmc->read_bl_len = MMC_BOOT_RD_BLOCK_LEN;
+ data->blocksize = MMC_BOOT_RD_BLOCK_LEN;
+ }
+ } else if (cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) {
+ if (mmc->read_bl_len != MMC_BOOT_RD_BLOCK_LEN &&
+ mmc->version & SD_VERSION_SD) {
+ mmc->read_bl_len = MMC_BOOT_RD_BLOCK_LEN;
+ data->blocksize = MMC_BOOT_RD_BLOCK_LEN;
+ }
+ } else if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) {
+ /* explicitly disable the prg enabled flag */
+ cmd->flags &= ~MMC_BOOT_PROGRAM_ENABLED;
+ /* set the XFER mode */
+ cmd->flags |= MMC_BOOT_XFER_MODE_BLOCK;
+ }
+
+
+ /* For Data cmd's */
+ if (data != NULL)
+ mmc_boot_init_data(mmc, cmd, data);
+
+ /* send command */
+ mmc_ret = mmc_boot_send_command(cmd, mmc);
+
+ if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+ debug("Return Error = %d\n", mmc_ret);
+ return mmc_ret;
+ }
+
+ if (data != NULL) {
+ mmc_ret = mmc_boot_check_read_data(cmd);
+ if (mmc_ret)
+ return mmc_ret;
+ mmc_boot_fifo_data_transfer((unsigned int *) data->dest,
+ data->blocks * data->blocksize,
+ MMC_BOOT_DATA_READ,
+ mmc);
+ }
+
+ if (cmd->cmdidx == MMC_CMD_SEND_CSD) {
+ /* Set read timeout once csd is received */
+ mmc_ret = mmc_boot_set_read_timeout(mmc);
+ if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+ printf("Error No.%d: Failure setting \
+ write Timeout value!\n",
+ mmc_ret);
+ return mmc_ret;
+ }
+ } else if ((cmd->cmdidx == SD_CMD_SWITCH_FUNC) && (data != NULL)) {
+ /* cmd6 needs at least 8 clocks after the
+ * End Data of Status.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(20);
+ }
+
+ return mmc_ret;
+}
+
+/*
+ * Initialize host structure, set and enable clock-rate and power mode.
+ */
+unsigned int mmc_boot_init(struct mmc *mmc)
+{
+ unsigned int mmc_pwr = 0;
+ struct mmc_priv *priv = mmc->priv;
+ int mmc_slot = priv->instance;
+ unsigned long reg;
+
+ /* Initialize any clocks needed for SDC controller */
+ clock_init_mmc(mmc_slot);
+
+ /* Setup initial freq to 400KHz */
+ clock_config_mmc(mmc_slot, MMC_CLK_400KHZ);
+
+ /* set power mode*/
+ mmc_pwr &= ~MMC_BOOT_MCI_PWR_UP;
+ mmc_pwr |= MMC_BOOT_MCI_PWR_ON;
+ mmc_pwr |= MMC_BOOT_MCI_PWR_UP;
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_POWER);
+ writel(mmc_pwr, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+ return MMC_BOOT_E_SUCCESS;
+}
+
+static unsigned int mmc_boot_set_bus_width(unsigned int width,
+ struct mmc *mmc)
+{
+ unsigned int mmc_reg;
+ struct mmc_priv *priv = mmc->priv;
+ unsigned long reg;
+
+ /* set MCI_CLK accordingly */
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_CLK);
+ mmc_reg = readl(reg);
+ mmc_reg &= ~MMC_BOOT_MCI_CLK_WIDEBUS_MODE;
+ if (width == 1)
+ mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_1_BIT;
+ else if (width == 4)
+ mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_4_BIT;
+ else if (width == 8)
+ mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_8_BIT;
+ else
+ return MMC_BOOT_E_INVAL;
+
+ writel(mmc_reg, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+ debug("Setting bus width to %d\n", width);
+ return MMC_BOOT_E_SUCCESS;
+}
+
+void mmc_boot_set_ios(struct mmc *mmc)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+ struct mmc_priv *priv = mmc->priv;
+ int mmc_slot = priv->instance;
+
+ /* clock frequency should be less than 400KHz in identification mode */
+ clock_config_mmc(mmc_slot, mmc->clock);
+ /*
+ * give atleast 2 MCLK cycles delay for clocks
+ * and SDCC core to stabilize.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(5);
+ mmc_ret = mmc_boot_set_bus_width(mmc->bus_width, mmc);
+ if (mmc_ret != MMC_BOOT_E_SUCCESS)
+ printf("Set bus width error %d\n", mmc_ret);
+}
+
+/*
+ * Board specific initializations
+ */
+unsigned int mmc_boot_main(struct mmc *mmc)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+ /* Initialize necessary data structure and enable/set clock and power */
+ debug(" Initializing MMC host data structure and clock!\n");
+ mmc_ret = mmc_boot_init(mmc);
+ if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+ printf("MMC Boot: Error Initializing MMC Card!!!\n");
+ return MMC_BOOT_E_FAILURE;
+ }
+
+ return MMC_BOOT_E_SUCCESS;
+}
--
1.7.8.3
1
0

[U-Boot] [PATCH 4/5] Add support for mmc read and writes
by mohamed.haneef@lntinfotech.com 10 May '12
by mohamed.haneef@lntinfotech.com 10 May '12
10 May '12
From: Mohamed Haneef <mohamed.haneef(a)lntinfotech.com>
*Support for msm7x30 mmc read and writes
Signed-off-by: Mohamed Haneef <mohamed.haneef(a)lntinfotech.com>
---
arch/arm/include/asm/arch-msm7630/mmc.h | 399 +++++++++++++++++++++
drivers/mmc/Makefile | 1 +
drivers/mmc/qc_mmc.c | 584 +++++++++++++++++++++++++++++++
3 files changed, 984 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/include/asm/arch-msm7630/mmc.h
create mode 100644 drivers/mmc/qc_mmc.c
diff --git a/arch/arm/include/asm/arch-msm7630/mmc.h b/arch/arm/include/asm/arch-msm7630/mmc.h
new file mode 100644
index 0000000..949e43c
--- /dev/null
+++ b/arch/arm/include/asm/arch-msm7630/mmc.h
@@ -0,0 +1,399 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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
+ *
+ */
+
+#ifndef __MMC_H__
+#define __MMC_H__
+
+#ifndef MMC_SLOT
+#define MMC_SLOT 0
+#endif
+
+#include <common.h>
+#include <part.h>
+#include <mmc.h>
+
+/*
+ * Define Macros for SDCC Registers
+ */
+/* 8 bit */
+#define MMC_BOOT_MCI_POWER 0x000
+
+/* MCICMD output control - 6th bit */
+#ifdef PLATFORM_MSM7X30
+#define MMC_BOOT_MCI_OPEN_DRAIN (1 << 6)
+#define MMC_BOOT_MCI_PWR_OFF 0x00
+#define MMC_BOOT_MCI_PWR_UP 0x01
+#define MMC_BOOT_MCI_PWR_ON 0x01
+#else
+#define MMC_BOOT_MCI_OPEN_DRAIN (1 << 6)
+#define MMC_BOOT_MCI_PWR_OFF 0x00
+#define MMC_BOOT_MCI_PWR_UP 0x02
+#define MMC_BOOT_MCI_PWR_ON 0x03
+#endif
+
+/* 16 bits */
+#define MMC_BOOT_MCI_CLK 0x004
+/* Enable MCI bus clock - 0: clock disabled 1: enabled */
+#define MMC_BOOT_MCI_CLK_ENABLE (1 << 8)
+/* Disable clk o/p when bus idle- 0:always enabled 1:enabled when bus active */
+#define MMC_BOOT_MCI_CLK_PWRSAVE (1 << 9)
+/* Enable Widebus mode - 00: 1 bit mode 10:4 bit mode 01/11: 8 bit mode */
+#define MMC_BOOT_MCI_CLK_WIDEBUS_MODE (3 << 10)
+#define MMC_BOOT_MCI_CLK_WIDEBUS_1_BIT 0
+#define MMC_BOOT_MCI_CLK_WIDEBUS_4_BIT (2 << 10)
+#define MMC_BOOT_MCI_CLK_WIDEBUS_8_BIT (1 << 10)
+/* Enable flow control- 0: disable 1: enable */
+#define MMC_BOOT_MCI_CLK_ENA_FLOW (1 << 12)
+/* Set/clear to select rising/falling edge for data/cmd output */
+#define MMC_BOOT_MCI_CLK_INVERT_OUT (1 << 13)
+/* Select to lach data/cmd coming in falling/rising/feedbk/loopbk of MCIclk */
+#define MMC_BOOT_MCI_CLK_IN_FALLING 0x0
+#define MMC_BOOT_MCI_CLK_IN_RISING (1 << 14)
+#define MMC_BOOT_MCI_CLK_IN_FEEDBACK (2 << 14)
+#define MMC_BOOT_MCI_CLK_IN_LOOPBACK (3 << 14)
+
+/* Bus Width */
+#define MMC_BOOT_BUS_WIDTH_1_BIT 0
+#define MMC_BOOT_BUS_WIDTH_4_BIT 2
+#define MMC_BOOT_BUS_WIDTH_8_BIT 3
+
+/* 32 bits */
+#define MMC_BOOT_MCI_ARGUMENT 0x008
+
+/* 16 bits */
+#define MMC_BOOT_MCI_CMD 0x00C
+/* Command Index: 0 -5 */
+/* Waits for response if set */
+#define MMC_BOOT_MCI_CMD_RESPONSE (1 << 6)
+/* Receives a 136-bit long response if set */
+#define MMC_BOOT_MCI_CMD_LONGRSP (1 << 7)
+/* If set, CPSM disables command timer and waits for interrupt */
+#define MMC_BOOT_MCI_CMD_INTERRUPT (1 << 8)
+/* If set waits for CmdPend before starting to send a command */
+#define MMC_BOOT_MCI_CMD_PENDING (1 << 9)
+/* CPSM is enabled if set */
+#define MMC_BOOT_MCI_CMD_ENABLE (1 << 10)
+/* If set PROG_DONE status bit asserted when busy is de-asserted */
+#define MMC_BOOT_MCI_CMD_PROG_ENA (1 << 11)
+/* To indicate that this is a Command with Data (for SDIO interrupts) */
+#define MMC_BOOT_MCI_CMD_DAT_CMD (1 << 12)
+/* Signals the next command to be an abort (stop) command. Always read 0 */
+#define MMC_BOOT_MCI_CMD_MCIABORT (1 << 13)
+/* Waits for Command Completion Signal if set */
+#define MMC_BOOT_MCI_CMD_CCS_ENABLE (1 << 14)
+/* If set sends CCS disable sequence */
+#define MMC_BOOT_MCI_CMD_CCS_DISABLE (1 << 15)
+
+#define MMC_BOOT_MCI_RESP_CMD 0x010
+
+#define MMC_BOOT_MCI_RESP_0 0x014
+#define MMC_BOOT_MCI_RESP_1 0x018
+#define MMC_BOOT_MCI_RESP_2 0x01C
+#define MMC_BOOT_MCI_RESP_3 0x020
+
+#define MMC_BOOT_MCI_DATA_TIMER 0x024
+#define MMC_BOOT_MCI_DATA_LENGTH 0x028
+/* 16 bits */
+#define MMC_BOOT_MCI_DATA_CTL 0x02C
+/* Data transfer enabled */
+#define MMC_BOOT_MCI_DATA_ENABLE (1 << 0)
+/* Data transfer direction - 0: controller to card 1:card to controller */
+#define MMC_BOOT_MCI_DATA_DIR (1 << 1)
+/* Data transfer mode - 0: block data transfer 1: stream data transfer */
+#define MMC_BOOT_MCI_DATA_MODE (1 << 2)
+/* Enable DM interface - 0: DM disabled 1: DM enabled */
+#define MMC_BOOT_MCI_DATA_DM_ENABLE (1 << 3)
+/* Data block length in bytes (1-4096) */
+#define MMC_BOOT_MCI_BLKSIZE_POS 4
+#define MMC_BOOT_MCI_DATA_COUNT 0x030
+#define MMC_BOOT_MCI_STATUS 0x034
+/* Command response received - CRC check failed */
+#define MMC_BOOT_MCI_STAT_CMD_CRC_FAIL (1 << 0)
+/* Data block sent/received - CRC check failed */
+#define MMC_BOOT_MCI_STAT_DATA_CRC_FAIL (1 << 1)
+/* Command resonse timeout */
+#define MMC_BOOT_MCI_STAT_CMD_TIMEOUT (1 << 2)
+/* Data timeout */
+#define MMC_BOOT_MCI_STAT_DATA_TIMEOUT (1 << 3)
+/* Transmit FIFO underrun error */
+#define MMC_BOOT_MCI_STAT_TX_UNDRUN (1 << 4)
+/* Receive FIFO overrun error */
+#define MMC_BOOT_MCI_STAT_RX_OVRRUN (1 << 5)
+/* Command response received - CRC check passed */
+#define MMC_BOOT_MCI_STAT_CMD_RESP_END (1 << 6)
+/* Command sent - no response required */
+#define MMC_BOOT_MCI_STAT_CMD_SENT (1 << 7)
+/* Data end - data counter zero */
+#define MMC_BOOT_MCI_STAT_DATA_END (1 << 8)
+/* Start bit not detected on all data signals in wide bus mode */
+#define MMC_BOOT_MCI_STAT_START_BIT_ERR (1 << 9)
+/* Data block sent/received - CRC check passed */
+#define MMC_BOOT_MCI_STAT_DATA_BLK_END (1 << 10)
+/* Command transfer in progress */
+#define MMC_BOOT_MCI_STAT_CMD_ACTIVE (1 << 11)
+/* Data transmit in progress */
+#define MMC_BOOT_MCI_STAT_TX_ACTIVE (1 << 12)
+/* Data receive in progress */
+#define MMC_BOOT_MCI_STAT_RX_ACTIVE (1 << 13)
+/* Transmit FIFO half full */
+#define MMC_BOOT_MCI_STAT_TX_FIFO_HFULL (1 << 14)
+/* Receive FIFO half full */
+#define MMC_BOOT_MCI_STAT_RX_FIFO_HFULL (1 << 15)
+/* Transmit FIFO full */
+#define MMC_BOOT_MCI_STAT_TX_FIFO_FULL (1 << 16)
+/* Receive FIFO full */
+#define MMC_BOOT_MCI_STAT_RX_FIFO_FULL (1 << 17)
+/* Transmit FIFO empty */
+#define MMC_BOOT_MCI_STAT_TX_FIFO_EMPTY (1 << 18)
+/* Receive FIFO empty */
+#define MMC_BOOT_MCI_STAT_RX_FIFO_EMPTY (1 << 19)
+/* Data available in transmit FIFO */
+#define MMC_BOOT_MCI_STAT_TX_DATA_AVLBL (1 << 20)
+/* Data available in receive FIFO */
+#define MMC_BOOT_MCI_STAT_RX_DATA_AVLBL (1 << 21)
+/* SDIO interrupt indicator for wake-up */
+#define MMC_BOOT_MCI_STAT_SDIO_INTR (1 << 22)
+/* Programming done */
+#define MMC_BOOT_MCI_STAT_PROG_DONE (1 << 23)
+/* CE-ATA command completion signal detected */
+#define MMC_BOOT_MCI_STAT_ATA_CMD_CMPL (1 << 24)
+/* SDIO interrupt indicator for normal operation */
+#define MMC_BOOT_MCI_STAT_SDIO_INTR_OP (1 << 25)
+/* Commpand completion signal timeout */
+#define MMC_BOOT_MCI_STAT_CCS_TIMEOUT (1 << 26)
+
+#define MMC_BOOT_MCI_STATIC_STATUS (MMC_BOOT_MCI_STAT_CMD_CRC_FAIL| \
+ MMC_BOOT_MCI_STAT_DATA_CRC_FAIL| \
+ MMC_BOOT_MCI_STAT_CMD_TIMEOUT| \
+ MMC_BOOT_MCI_STAT_DATA_TIMEOUT| \
+ MMC_BOOT_MCI_STAT_TX_UNDRUN| \
+ MMC_BOOT_MCI_STAT_RX_OVRRUN| \
+ MMC_BOOT_MCI_STAT_CMD_RESP_END| \
+ MMC_BOOT_MCI_STAT_CMD_SENT| \
+ MMC_BOOT_MCI_STAT_DATA_END| \
+ MMC_BOOT_MCI_STAT_START_BIT_ERR| \
+ MMC_BOOT_MCI_STAT_DATA_BLK_END| \
+ MMC_BOOT_MCI_SDIO_INTR_CLR| \
+ MMC_BOOT_MCI_STAT_PROG_DONE| \
+ MMC_BOOT_MCI_STAT_ATA_CMD_CMPL |\
+ MMC_BOOT_MCI_STAT_CCS_TIMEOUT)
+
+#define MMC_BOOT_MCI_CLEAR 0x038
+#define MMC_BOOT_MCI_CMD_CRC_FAIL_CLR (1 << 0)
+#define MMC_BOOT_MCI_DATA_CRC_FAIL_CLR (1 << 1)
+#define MMC_BOOT_MCI_CMD_TIMEOUT_CLR (1 << 2)
+#define MMC_BOOT_MCI_DATA_TIMEOUT_CLR (1 << 3)
+#define MMC_BOOT_MCI_TX_UNDERRUN_CLR (1 << 4)
+#define MMC_BOOT_MCI_RX_OVERRUN_CLR (1 << 5)
+#define MMC_BOOT_MCI_CMD_RESP_END_CLR (1 << 6)
+#define MMC_BOOT_MCI_CMD_SENT_CLR (1 << 7)
+#define MMC_BOOT_MCI_DATA_END_CLR (1 << 8)
+#define MMC_BOOT_MCI_START_BIT_ERR_CLR (1 << 9)
+#define MMC_BOOT_MCI_DATA_BLK_END_CLR (1 << 10)
+#define MMC_BOOT_MCI_SDIO_INTR_CLR (1 << 22)
+#define MMC_BOOT_MCI_PROG_DONE_CLR (1 << 23)
+#define MMC_BOOT_MCI_ATA_CMD_COMPLR_CLR (1 << 24)
+#define MMC_BOOT_MCI_CCS_TIMEOUT_CLR (1 << 25)
+
+#define MMC_BOOT_MCI_INT_MASK0 0x03C
+#define MMC_BOOT_MCI_CMD_CRC_FAIL_MASK (1 << 0)
+#define MMC_BOOT_MCI_DATA_CRC_FAIL_MASK (1 << 1)
+#define MMC_BOOT_MCI_CMD_TIMEOUT_MASK (1 << 2)
+#define MMC_BOOT_MCI_DATA_TIMEOUT_MASK (1 << 3)
+#define MMC_BOOT_MCI_TX_OVERRUN_MASK (1 << 4)
+#define MMC_BOOT_MCI_RX_OVERRUN_MASK (1 << 5)
+#define MMC_BOOT_MCI_CMD_RESP_END_MASK (1 << 6)
+#define MMC_BOOT_MCI_CMD_SENT_MASK (1 << 7)
+#define MMC_BOOT_MCI_DATA_END_MASK (1 << 8)
+#define MMC_BOOT_MCI_START_BIT_ERR_MASK (1 << 9)
+#define MMC_BOOT_MCI_DATA_BLK_END_MASK (1 << 10)
+#define MMC_BOOT_MCI_CMD_ACTIVE_MASK (1 << 11)
+#define MMC_BOOT_MCI_TX_ACTIVE_MASK (1 << 12)
+#define MMC_BOOT_MCI_RX_ACTIVE_MASK (1 << 13)
+#define MMC_BOOT_MCI_TX_FIFO_HFULL_MASK (1 << 14)
+#define MMC_BOOT_MCI_RX_FIFO_HFULL_MASK (1 << 15)
+#define MMC_BOOT_MCI_TX_FIFO_FULL_MASK (1 << 16)
+#define MMC_BOOT_MCI_RX_FIFO_FULL_MASK (1 << 17)
+#define MMC_BOOT_MCI_TX_FIFO_EMPTY_MASK (1 << 18)
+#define MMC_BOOT_MCI_RX_FIFO_EMPTY_MASK (1 << 19)
+#define MMC_BOOT_MCI_TX_DATA_AVLBL_MASK (1 << 20)
+#define MMC_BOOT_MCI_RX_DATA_AVLBL_MASK (1 << 21)
+#define MMC_BOOT_MCI_SDIO_INT_MASK (1 << 22)
+#define MMC_BOOT_MCI_PROG_DONE_MASK (1 << 23)
+#define MMC_BOOT_MCI_ATA_CMD_COMPL_MASK (1 << 24)
+#define MMC_BOOT_MCI_SDIO_INT_OPER_MASK (1 << 25)
+#define MMC_BOOT_MCI_CCS_TIME_OUT_MASK (1 << 26)
+
+#define MMC_BOOT_MCI_INT_MASK1 0x040
+
+#define MMC_BOOT_MCI_FIFO_COUNT 0x044
+
+#define MMC_BOOT_MCI_CCS_TIMER 0x0058
+
+#define MMC_BOOT_MCI_FIFO 0x080
+
+/* OCR Register */
+#define MMC_BOOT_OCR_17_19 (1 << 7)
+#define MMC_BOOT_OCR_27_36 (0x1FF << 15)
+#define MMC_BOOT_OCR_SEC_MODE (2 << 29)
+#define MMC_BOOT_OCR_BUSY (1 << 31)
+
+/* Commands type */
+#define MMC_BOOT_CMD_BCAST (1 << 0)
+#define MMC_BOOT_CMD_BCAST_W_RESP (1 << 1)
+#define MMC_BOOT_CMD_ADDRESS (1 << 2)
+#define MMC_BOOT_CMD_ADDR_DATA_XFER (1 << 3)
+
+/* Card Status bits (R1 register) */
+#define MMC_BOOT_R1_AKE_SEQ_ERROR (1 << 3)
+#define MMC_BOOT_R1_APP_CMD (1 << 5)
+#define MMC_BOOT_R1_RDY_FOR_DATA (1 << 6)
+#define MMC_BOOT_R1_CURR_STATE_IDLE (0 << 9)
+#define MMC_BOOT_R1_CURR_STATE_RDY (1 << 9)
+#define MMC_BOOT_R1_CURR_STATE_IDENT (2 << 9)
+#define MMC_BOOT_R1_CURR_STATE_STBY (3 << 9)
+#define MMC_BOOT_R1_CURR_STATE_TRAN (4 << 9)
+#define MMC_BOOT_R1_CURR_STATE_DATA (5 << 9)
+#define MMC_BOOT_R1_CURR_STATE_RCV (6 << 9)
+#define MMC_BOOT_R1_CURR_STATE_PRG (7 << 9)
+#define MMC_BOOT_R1_CURR_STATE_DIS (8 << 9)
+#define MMC_BOOT_R1_ERASE_RESET (1 << 13)
+#define MMC_BOOT_R1_CARD_ECC_DISABLED (1 << 14)
+#define MMC_BOOT_R1_WP_ERASE_SKIP (1 << 15)
+#define MMC_BOOT_R1_ERROR (1 << 19)
+#define MMC_BOOT_R1_CC_ERROR (1 << 20)
+#define MMC_BOOT_R1_CARD_ECC_FAILED (1 << 21)
+#define MMC_BOOT_R1_ILLEGAL_CMD (1 << 22)
+#define MMC_BOOT_R1_COM_CRC_ERR (1 << 23)
+#define MMC_BOOT_R1_LOCK_UNLOCK_FAIL (1 << 24)
+#define MMC_BOOT_R1_CARD_IS_LOCKED (1 << 25)
+#define MMC_BOOT_R1_WP_VIOLATION (1 << 26)
+#define MMC_BOOT_R1_ERASE_PARAM (1 << 27)
+#define MMC_BOOT_R1_ERASE_SEQ_ERR (1 << 28)
+#define MMC_BOOT_R1_BLOCK_LEN_ERR (1 << 29)
+#define MMC_BOOT_R1_ADDR_ERR (1 << 30)
+#define MMC_BOOT_R1_OUT_OF_RANGE (1 << 31)
+
+/* Macros for Common Errors */
+#define MMC_BOOT_E_SUCCESS 0
+#define MMC_BOOT_E_FAILURE 1
+/* Not used..use instead TIMEOUT in include/mmc.h */
+#define MMC_BOOT_E_TIMEOUT 2
+#define MMC_BOOT_E_INVAL 3
+#define MMC_BOOT_E_CRC_FAIL 4
+#define MMC_BOOT_E_INIT_FAIL 5
+#define MMC_BOOT_E_CMD_INDX_MISMATCH 6
+#define MMC_BOOT_E_RESP_VERIFY_FAIL 7
+#define MMC_BOOT_E_NOT_SUPPORTED 8
+#define MMC_BOOT_E_CARD_BUSY 9
+#define MMC_BOOT_E_MEM_ALLOC_FAIL 10
+#define MMC_BOOT_E_CLK_ENABLE_FAIL 11
+#define MMC_BOOT_E_CMMC_DECODE_FAIL 12
+#define MMC_BOOT_E_CID_DECODE_FAIL 13
+#define MMC_BOOT_E_BLOCKLEN_ERR 14
+#define MMC_BOOT_E_ADDRESS_ERR 15
+#define MMC_BOOT_E_DATA_CRC_FAIL 16
+#define MMC_BOOT_E_DATA_TIMEOUT 17
+#define MMC_BOOT_E_RX_OVRRUN 18
+#define MMC_BOOT_E_VREG_SET_FAILED 19
+#define MMC_BOOT_E_GPIO_CFG_FAIL 20
+#define MMC_BOOT_E_DATA_ADM_ERR 21
+
+/* EXT_CSD */
+#define MMC_BOOT_ACCESS_WRITE 0x3
+#define MMC_BOOT_EXT_CMMC_HS_TIMING 185
+#define MMC_BOOT_EXT_CMMC_BUS_WIDTH 183
+
+#define MMC_BOOT_EXT_USER_WP 171
+#define MMC_BOOT_EXT_ERASE_GROUP_DEF 175
+#define MMC_BOOT_EXT_HC_WP_GRP_SIZE 221
+#define MMC_BOOT_EXT_HC_ERASE_GRP_SIZE 224
+
+#define MMC_BOOT_US_PERM_WP_EN 2
+#define MMC_BOOT_US_PWR_WP_DIS 3
+
+#define MMC_BOOT_US_PERM_WP_DIS (1<<4)
+#define MMC_BOOT_US_PWR_WP_EN 1
+
+/* For SD */
+#define MMC_BOOT_SD_HC_VOLT_SUPPLIED 0x000001AA
+#define MMC_BOOT_SD_NEG_OCR 0x00FF8000
+#define MMC_BOOT_SD_HC_HCS 0x40000000
+#define MMC_BOOT_SD_DEV_READY 0x80000000
+#define MMC_BOOT_SD_SWITCH_HS 0x80FFFFF1
+
+/* Data structure definitions */
+
+#define MMC_BOOT_XFER_MODE_BLOCK 0
+#define MMC_BOOT_XFER_MODE_STREAM 1
+#define MMC_BOOT_PROGRAM_ENABLED 2
+
+
+#define MMC_RCA 2
+
+#define MMC_BOOT_MAX_COMMAND_RETRY 1000
+#define MMC_BOOT_RD_BLOCK_LEN 512
+#define MMC_BOOT_WR_BLOCK_LEN 512
+
+/* We have 16 32-bits FIFO registers */
+#define MMC_BOOT_MCI_FIFO_DEPTH 16
+#define MMC_BOOT_MCI_HFIFO_COUNT (MMC_BOOT_MCI_FIFO_DEPTH / 2)
+#define MMC_BOOT_MCI_FIFO_SIZE (MMC_BOOT_MCI_FIFO_DEPTH * 4)
+
+#define MAX_PARTITIONS 64
+
+#define MMC_BOOT_CHECK_PATTERN 0xAA /* 10101010b */
+
+#define MMC_CLK_400KHZ 400000
+#define MMC_CLK_144KHZ 144000
+#define MMC_CLK_20MHZ 20000000
+#define MMC_CLK_24MHZ 24000000
+#define MMC_CLK_25MHZ 25000000
+#define MMC_CLK_26MHZ 26000000
+#define MMC_CLK_48MHZ 48000000
+#define MMC_CLK_50MHZ 49152000
+#define MMC_CLK_52MHZ 52000000
+
+#define MMC_CLK_ENABLE 1
+#define MMC_CLK_DISABLE 0
+
+#if 0
+#define MSM_SDC1_BASE 0x12400000
+#define MSM_SDC2_BASE 0x12140000
+#define MSM_SDC3_BASE 0x12180000
+#define MSM_SDC4_BASE 0x121C0000
+#endif
+struct mmc_priv {
+ unsigned int instance;
+ unsigned int base;
+ unsigned int rd_timeout_ns; /* for read timeout */
+};
+
+void mmc_boot_set_ios(struct mmc *mmc);
+int mmc_boot_send_command_map(struct mmc *mmc,
+ struct mmc_cmd *cmd,
+ struct mmc_data *data);
+unsigned long int mmc_boot_mci_reg(unsigned long base, unsigned long offset);
+unsigned int mmc_boot_main(struct mmc *mmc);
+
+extern void clock_config_mmc(uint32_t interface, uint32_t freq);
+extern void clock_init_mmc(uint32_t interface);
+#endif
+
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index 506f1d6..2d926ec 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -44,6 +44,7 @@ COBJS-$(CONFIG_S5P_MMC) += s5p_mmc.o
COBJS-$(CONFIG_SDHCI) += sdhci.o
COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o
COBJS-$(CONFIG_TEGRA2_MMC) += tegra2_mmc.o
+COBJS-$(CONFIG_QC_MMC) += qc_mmc.o
COBJS := $(COBJS-y)
SRCS := $(COBJS:.o=.c)
diff --git a/drivers/mmc/qc_mmc.c b/drivers/mmc/qc_mmc.c
new file mode 100644
index 0000000..7b7a1ed
--- /dev/null
+++ b/drivers/mmc/qc_mmc.c
@@ -0,0 +1,584 @@
+/*
+ * (C) Copyright 2012
+ * LARSEN & TOUBRO INFOTECH LTD <www.lntinfotech.com>
+ *
+ * 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/types.h>
+#include <asm/io.h>
+#include <asm/arch/mmc.h>
+#include <asm/arch/iomap.h>
+#include <common.h>
+
+#if MMC_BOOT_ADM
+#include "adm.h"
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+#define MMC_BOOT_DATA_READ 0
+#define MMC_BOOT_DATA_WRITE 1
+/*
+ * Calculates the address of registers according to the base address
+ */
+unsigned long int mmc_boot_mci_reg(unsigned long base, unsigned long offset)
+{
+ return base + offset;
+}
+
+
+/*
+ * Sets a timeout for read operation.
+ */
+static unsigned int mmc_boot_set_read_timeout(struct mmc *mmc)
+{
+ if (mmc == NULL)
+ return MMC_BOOT_E_INVAL;
+
+ /* todo: Add a check for HC, only if HC do this.
+ * If not, taac and nsac must be taken into account
+ */
+ ((struct mmc_priv *)(mmc->priv))->rd_timeout_ns = 100000000;
+ debug(" Read timeout set: %d ns\n",
+ ((struct mmc_priv *)(mmc->priv))->rd_timeout_ns);
+
+ return MMC_BOOT_E_SUCCESS;
+}
+
+/*
+ * Check to ensure that there is no alignment or data length errors
+ */
+static unsigned int mmc_boot_check_read_data(struct mmc_cmd *cmd)
+{
+
+ if (cmd->response[0] & MMC_BOOT_R1_BLOCK_LEN_ERR)
+ return MMC_BOOT_E_BLOCKLEN_ERR;
+
+ /* Misaligned address not matching block length */
+ if (cmd->response[0] & MMC_BOOT_R1_ADDR_ERR)
+ return MMC_BOOT_E_ADDRESS_ERR;
+
+ return MMC_BOOT_E_SUCCESS;
+}
+
+/*
+ * Decode type of error caused during read and write
+ */
+static unsigned int mmc_boot_status_error(unsigned mmc_status)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+ /* If DATA_CRC_FAIL bit is set to 1 then CRC error
+ * was detected by card/device during the data transfer
+ */
+ if (mmc_status & MMC_BOOT_MCI_STAT_DATA_CRC_FAIL)
+ mmc_ret = MMC_BOOT_E_DATA_CRC_FAIL;
+ /* If DATA_TIMEOUT bit is set to 1 then the data transfer time
+ * exceeded the data timeout period without completing the
+ * transfer
+ */
+ else if (mmc_status & MMC_BOOT_MCI_STAT_DATA_TIMEOUT)
+ mmc_ret = MMC_BOOT_E_DATA_TIMEOUT;
+ /* If RX_OVERRUN bit is set to 1 then SDCC2 tried to
+ * receive data from the card before empty storage for new
+ * received data was available.
+ * Verify that bit FLOW_ENA in MCI_CLK is set to 1 during
+ * the data xfer.
+ */
+ else if (mmc_status & MMC_BOOT_MCI_STAT_RX_OVRRUN)
+ /* Note: We've set FLOW_ENA bit in MCI_CLK to 1.
+ * so no need to verify for now
+ */
+ mmc_ret = MMC_BOOT_E_RX_OVRRUN;
+ /* If TX_UNDERRUN bit is set to 1 then SDCC2 tried to send
+ * data to the card before new data for sending was available.
+ * Verify that bit FLOW_ENA in MCI_CLK
+ * is set to 1 during the data xfer.
+ */
+ else if (mmc_status & MMC_BOOT_MCI_STAT_TX_UNDRUN)
+ /* Note: We've set FLOW_ENA bit in MCI_CLK to 1.
+ * so skipping it now
+ */
+ mmc_ret = MMC_BOOT_E_RX_OVRRUN;
+
+ return mmc_ret;
+}
+
+/*
+ * Read data to SDC FIFO.
+ */
+static unsigned int mmc_boot_fifo_read(unsigned int *mmc_ptr,
+ unsigned int data_len,
+ struct mmc *mmc)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+ unsigned int mmc_status = 0;
+ unsigned int mmc_count = 0;
+ unsigned int read_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL | \
+ MMC_BOOT_MCI_STAT_DATA_TIMEOUT | \
+ MMC_BOOT_MCI_STAT_RX_OVRRUN;
+ unsigned int i;
+ struct mmc_priv *priv = (struct mmc_priv *)mmc->priv;
+ unsigned long reg_status, reg_fifo;
+
+ reg_status = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_STATUS);
+ reg_fifo = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_FIFO);
+
+ /* Read the data from the MCI_FIFO register as long as
+ * RXDATA_AVLBL bit of MCI_STATUS register is set to 1 and bits
+ * DATA_CRC_FAIL, DATA_TIMEOUT, RX_OVERRUN of MCI_STATUS
+ * register are cleared to 0.
+ * Continue the reads until the whole transfer data is received
+ */
+
+ do {
+ mmc_ret = MMC_BOOT_E_SUCCESS;
+ mmc_status = readl(reg_status);
+
+ if (mmc_status & read_error) {
+ mmc_ret = mmc_boot_status_error(mmc_status);
+ break;
+ }
+
+ if (mmc_status & MMC_BOOT_MCI_STAT_RX_DATA_AVLBL) {
+ unsigned read_count = 1;
+ if (mmc_status & MMC_BOOT_MCI_STAT_RX_FIFO_HFULL)
+ read_count = MMC_BOOT_MCI_HFIFO_COUNT;
+
+ for (i = 0; i < read_count; i++) {
+ /* FIFO contains 16 32-bit data buffer
+ * on 16 sequential addresses
+ */
+ *mmc_ptr = readl(reg_fifo +
+ (mmc_count % MMC_BOOT_MCI_FIFO_SIZE));
+ mmc_ptr++;
+ /* increase mmc_count by word size */
+ mmc_count += sizeof(unsigned int);
+ }
+ /* quit if we have read enough of data */
+ if (mmc_count == data_len)
+ break;
+ } else if (mmc_status & MMC_BOOT_MCI_STAT_DATA_END)
+ break;
+ } while (1);
+ return mmc_ret;
+}
+
+static unsigned int mmc_boot_fifo_data_transfer(unsigned int *data_ptr,
+ unsigned int data_len,
+ unsigned char direction,
+ struct mmc *mmc)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+ if (direction == MMC_BOOT_DATA_READ)
+ mmc_ret = mmc_boot_fifo_read(data_ptr, data_len, mmc);
+
+ return mmc_ret;
+}
+
+/*
+ * Sends specified command to a card and waits for a response.
+ */
+static unsigned int mmc_boot_send_command(struct mmc_cmd *cmd,
+ struct mmc *mmc)
+{
+ unsigned int mmc_cmd = 0;
+ unsigned int mmc_status = 0;
+ unsigned int mmc_resp = 0;
+ unsigned int mmc_return = MMC_BOOT_E_SUCCESS;
+ unsigned int cmd_index = 0;
+ int i = 0;
+ unsigned long reg, reg_status, reg_resp_cmd, reg_resp_0;
+ struct mmc_priv *priv = (struct mmc_priv *)mmc->priv;
+
+ /* basic check */
+ if (cmd == NULL)
+ return MMC_BOOT_E_INVAL;
+
+ /* 1. Write command argument to MMC_BOOT_MCI_ARGUMENT register */
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_ARGUMENT);
+ writel(cmd->cmdarg, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+ /* 2. Set appropriate fields and write MMC_BOOT_MCI_CMD */
+ /* 2a. Write command index in CMD_INDEX field */
+ cmd_index = cmd->cmdidx;
+ mmc_cmd |= cmd->cmdidx;
+ /* 2b. Set RESPONSE bit to 1 for all cmds except CMD0 */
+ if (cmd_index != MMC_CMD_GO_IDLE_STATE)
+ mmc_cmd |= MMC_BOOT_MCI_CMD_RESPONSE;
+
+ /* 2c. Set LONGRESP bit to 1 for CMD2, CMD9 and CMD10 */
+ if (cmd->resp_type & MMC_RSP_136)
+ mmc_cmd |= MMC_BOOT_MCI_CMD_LONGRSP;
+
+ /* 2d. Set INTERRUPT bit to 1 to disable command timeout */
+
+ /* 2e. Set PENDING bit to 1 for CMD12 in the beginning of stream
+ * mode data transfer
+ */
+ if (cmd->flags & MMC_BOOT_XFER_MODE_STREAM)
+ mmc_cmd |= MMC_BOOT_MCI_CMD_PENDING;
+
+ /* 2f. Set ENABLE bit to 1 */
+ mmc_cmd |= MMC_BOOT_MCI_CMD_ENABLE;
+
+ /* 2g. Set PROG_ENA bit to 1 for CMD12, CMD13 issued at the end of
+ * write data transfer
+ */
+ if ((cmd_index == MMC_CMD_STOP_TRANSMISSION ||
+ cmd_index == MMC_CMD_SEND_STATUS) &&
+ (cmd->flags & MMC_BOOT_PROGRAM_ENABLED))
+ mmc_cmd |= MMC_BOOT_MCI_CMD_PROG_ENA;
+
+
+ /* 2h. Set MCIABORT bit to 1 for CMD12 when working with SDIO card */
+ /* 2i. Set CCS_ENABLE bit to 1 for CMD61 when Command Completion Signal
+ * of CE-ATA device is enabled
+ */
+
+ /* 2j. clear all static status bits */
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_CLEAR);
+ writel(MMC_BOOT_MCI_STATIC_STATUS, reg);
+
+ /* 2k. Write to MMC_BOOT_MCI_CMD register */
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_CMD);
+ writel(mmc_cmd, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+ reg_status = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_STATUS);
+ reg_resp_cmd = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_RESP_CMD);
+ reg_resp_0 = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_RESP_0);
+
+ /* 3. Wait for interrupt or poll on the following bits of MCI_STATUS
+ * register
+ */
+ do {
+ /* 3a. Read MCI_STATUS register */
+ mmc_status = readl(reg_status);
+ while (mmc_status & MMC_BOOT_MCI_STAT_CMD_ACTIVE)
+ mmc_status = readl(reg_status);
+
+ /* 3b. CMD_SENT bit supposed to be set to 1 only
+ * after CMD0 is sent -no response required.
+ */
+ if ((cmd->resp_type == MMC_RSP_NONE) &&
+ (mmc_status & MMC_BOOT_MCI_STAT_CMD_SENT))
+ break;
+
+ /* 3c. If CMD_TIMEOUT bit is set then no response
+ * was received */
+ else if (mmc_status & MMC_BOOT_MCI_STAT_CMD_TIMEOUT) {
+ mmc_return = TIMEOUT;
+ break;
+ }
+ /* 3d. If CMD_RESPONSE_END bit is set to 1 then command's
+ * response was received and CRC check passed
+ * Spcial case for ACMD41: it seems to always fail CRC even if
+ * the response is valid
+ */
+ else if ((mmc_status & MMC_BOOT_MCI_STAT_CMD_RESP_END) ||
+ (cmd_index == MMC_CMD_SEND_OP_COND)
+ || (cmd_index == SD_CMD_SEND_IF_COND)) {
+ /* 3i. Read MCI_RESP_CMD register to verify that
+ * response index is equal to command index
+ */
+ mmc_resp = readl(reg_resp_cmd) & 0x3F;
+
+ /* However, long response does not contain the
+ * command index field.
+ * In that case, response index field must be set to
+ * 111111b (0x3F)
+ */
+ if ((mmc_resp == cmd_index) ||
+ (cmd->resp_type == MMC_RSP_R2 ||
+ cmd->resp_type == MMC_RSP_R3 ||
+ cmd->resp_type == MMC_RSP_R6 ||
+ cmd->resp_type == MMC_RSP_R7)){
+ /* 3j. If resp index is equal to cmd index,
+ * read command resp from MCI_RESPn registers
+ * - MCI_RESP0/1/2/3 for CMD2/9/10
+ * - MCI_RESP0 for all other registers
+ */
+ if (cmd->resp_type & MMC_RSP_136) {
+ for (i = 0; i < 4; i++)
+ cmd->response[3-i] =
+ readl(reg_resp_0 + \
+ (i * 4));
+ } else
+ cmd->response[0] = readl(reg_resp_0);
+ } else
+ /* command index mis-match */
+ mmc_return = MMC_BOOT_E_CMD_INDX_MISMATCH;
+
+ break;
+ }
+
+ /* 3e. If CMD_CRC_FAIL bit is set to 1 then cmd's response
+ * was recvd, but CRC check failed.
+ */
+ else if ((mmc_status & MMC_BOOT_MCI_STAT_CMD_CRC_FAIL)) {
+ if (cmd_index == SD_CMD_APP_SEND_OP_COND)
+ cmd->response[0] = readl(reg_resp_0);
+ else
+ mmc_return = MMC_BOOT_E_CRC_FAIL;
+ break;
+ }
+
+ } while (1);
+
+ return mmc_return;
+}
+
+static void mmc_boot_init_data(struct mmc *mmc, struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ uint32_t data_ctrl, mmc_reg, data_len;
+ struct mmc_priv *priv = (struct mmc_priv *)mmc->priv;
+ unsigned long reg;
+
+ /* Write data timeout period to MCI_DATA_TIMER register. */
+ /* Data timeout period should be in card bus clock periods */
+ mmc_reg = (unsigned long)(((struct mmc_priv *)
+ (mmc->priv))->rd_timeout_ns /
+ 1000000) * (mmc->clock / 1000);
+ /* add some extra clock cycles to be safe */
+ mmc_reg += 1000;
+ mmc_reg = mmc_reg/2;
+
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_TIMER);
+ writel(mmc_reg, reg);
+
+ /* Write the total size of the transfer data to MCI_DATA_LENGTH
+ * register. For block xfer it must be multiple of the block
+ * size.
+ */
+
+ data_len = data->blocks*data->blocksize;
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_LENGTH);
+ writel(data_len, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+ data_ctrl = MMC_BOOT_MCI_DATA_ENABLE |
+ (data->blocksize << MMC_BOOT_MCI_BLKSIZE_POS);
+
+
+ if (data->flags == MMC_DATA_READ)
+ data_ctrl |= MMC_BOOT_MCI_DATA_DIR;
+
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_DATA_CTL);
+ writel(data_ctrl, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+}
+
+/*
+ * Function to map mmc send command to board send command
+ */
+int mmc_boot_send_command_map(struct mmc *mmc,
+ struct mmc_cmd *cmd,
+ struct mmc_data *data)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+ /* todo: do we need to fill in command type ?? */
+
+ if (cmd->cmdidx == MMC_CMD_SEND_STATUS) {
+ /* u-boot doesn't fill in the correct argument value */
+ cmd->cmdarg = mmc->rca << 16;
+ /* this is to explicitly disable the prg enabled flag */
+ cmd->flags &= ~MMC_BOOT_PROGRAM_ENABLED;
+
+ } else if (cmd->cmdidx == MMC_CMD_READ_SINGLE_BLOCK) {
+ if (mmc->read_bl_len != MMC_BOOT_RD_BLOCK_LEN &&
+ mmc->version & SD_VERSION_SD) {
+ mmc->read_bl_len = MMC_BOOT_RD_BLOCK_LEN;
+ data->blocksize = MMC_BOOT_RD_BLOCK_LEN;
+ }
+ } else if (cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK) {
+ if (mmc->read_bl_len != MMC_BOOT_RD_BLOCK_LEN &&
+ mmc->version & SD_VERSION_SD) {
+ mmc->read_bl_len = MMC_BOOT_RD_BLOCK_LEN;
+ data->blocksize = MMC_BOOT_RD_BLOCK_LEN;
+ }
+ } else if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) {
+ /* explicitly disable the prg enabled flag */
+ cmd->flags &= ~MMC_BOOT_PROGRAM_ENABLED;
+ /* set the XFER mode */
+ cmd->flags |= MMC_BOOT_XFER_MODE_BLOCK;
+ }
+
+
+ /* For Data cmd's */
+ if (data != NULL)
+ mmc_boot_init_data(mmc, cmd, data);
+
+ /* send command */
+ mmc_ret = mmc_boot_send_command(cmd, mmc);
+
+ if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+ debug("Return Error = %d\n", mmc_ret);
+ return mmc_ret;
+ }
+
+ if (data != NULL) {
+ mmc_ret = mmc_boot_check_read_data(cmd);
+ if (mmc_ret)
+ return mmc_ret;
+ mmc_boot_fifo_data_transfer((unsigned int *) data->dest,
+ data->blocks * data->blocksize,
+ MMC_BOOT_DATA_READ,
+ mmc);
+ }
+
+ if (cmd->cmdidx == MMC_CMD_SEND_CSD) {
+ /* Set read timeout once csd is received */
+ mmc_ret = mmc_boot_set_read_timeout(mmc);
+ if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+ printf("Error No.%d: Failure setting \
+ write Timeout value!\n",
+ mmc_ret);
+ return mmc_ret;
+ }
+ } else if ((cmd->cmdidx == SD_CMD_SWITCH_FUNC) && (data != NULL)) {
+ /* cmd6 needs at least 8 clocks after the
+ * End Data of Status.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(20);
+ }
+
+ return mmc_ret;
+}
+
+/*
+ * Initialize host structure, set and enable clock-rate and power mode.
+ */
+unsigned int mmc_boot_init(struct mmc *mmc)
+{
+ unsigned int mmc_pwr = 0;
+ struct mmc_priv *priv = (struct mmc_priv *) mmc->priv;
+ int mmc_slot = priv->instance;
+ unsigned long reg;
+
+ /* Initialize any clocks needed for SDC controller */
+ clock_init_mmc(mmc_slot);
+
+ /* Setup initial freq to 400KHz */
+ clock_config_mmc(mmc_slot, MMC_CLK_400KHZ);
+
+ /* set power mode*/
+ mmc_pwr &= ~MMC_BOOT_MCI_PWR_UP;
+ mmc_pwr |= MMC_BOOT_MCI_PWR_ON;
+ mmc_pwr |= MMC_BOOT_MCI_PWR_UP;
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_POWER);
+ writel(mmc_pwr, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+ return MMC_BOOT_E_SUCCESS;
+}
+
+static unsigned int mmc_boot_set_bus_width(unsigned int width,
+ struct mmc *mmc)
+{
+ unsigned int mmc_reg;
+ struct mmc_priv *priv = (struct mmc_priv *)mmc->priv;
+ unsigned long reg;
+
+ /* set MCI_CLK accordingly */
+ reg = mmc_boot_mci_reg(priv->base, MMC_BOOT_MCI_CLK);
+ mmc_reg = readl(reg);
+ mmc_reg &= ~MMC_BOOT_MCI_CLK_WIDEBUS_MODE;
+ if (width == 1)
+ mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_1_BIT;
+ else if (width == 4)
+ mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_4_BIT;
+ else if (width == 8)
+ mmc_reg |= MMC_BOOT_MCI_CLK_WIDEBUS_8_BIT;
+ else
+ return MMC_BOOT_E_INVAL;
+
+ writel(mmc_reg, reg);
+
+ /* Writes to MCI port are not effective for 3 ticks of PCLK.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(8);
+
+ debug("Setting bus width to %d\n", width);
+ return MMC_BOOT_E_SUCCESS;
+}
+
+void mmc_boot_set_ios(struct mmc *mmc)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+ struct mmc_priv *priv = (struct mmc_priv *)mmc->priv;
+ int mmc_slot = priv->instance;
+
+ /* clock frequency should be less than 400KHz in identification mode */
+ clock_config_mmc(mmc_slot, mmc->clock);
+ /*
+ * give atleast 2 MCLK cycles delay for clocks
+ * and SDCC core to stabilize.
+ * ticks calculated using 400KHz clock speed
+ */
+ udelay(5);
+ mmc_ret = mmc_boot_set_bus_width(mmc->bus_width, mmc);
+ if (mmc_ret != MMC_BOOT_E_SUCCESS)
+ printf("Set bus width error %d\n", mmc_ret);
+}
+
+/*
+ * Board specific initializations
+ */
+unsigned int mmc_boot_main(struct mmc *mmc)
+{
+ unsigned int mmc_ret = MMC_BOOT_E_SUCCESS;
+
+ /* Initialize necessary data structure and enable/set clock and power */
+ debug(" Initializing MMC host data structure and clock!\n");
+ mmc_ret = mmc_boot_init(mmc);
+ if (mmc_ret != MMC_BOOT_E_SUCCESS) {
+ printf("MMC Boot: Error Initializing MMC Card!!!\n");
+ return MMC_BOOT_E_FAILURE;
+ }
+
+ return MMC_BOOT_E_SUCCESS;
+}
--
1.7.1
The contents of this e-mail and any attachment(s) may contain confidential or privileged information for the intended recipient(s). Unintended recipients are prohibited from taking action on the basis of information in this e-mail and using or disseminating the information, and must notify the sender and delete it from their system. L&T Infotech will not accept responsibility or liability for the accuracy or completeness of, or the presence of any virus or disabling code in this e-mail"
5
4

10 May '12
This patch set supports 32bpp bitmap image drwaing and TIZEN logo.
LCD: display 32bpp decompressed bitmap image
create lib/tizen directory
EXYNOS: display 32bpp bitmap TIZEN logo
Thank you,
Donghwa Lee
1
0