[U-Boot] [PATCH 0/5] *** Qualcomm chipset support patches ***

From: Shrinivas Sahukar shrinivas.sahukar@lntinfotech.com
*** This patch series contains the following support for Qualcomm chipsets ***
* MSM7630: USB Gadget support * MSM 7x27a: Add support for qualcomm msm 7x27a SOC * MSM 7x27a: Add support for qualcomm msm7x27a surf board * MSM7x27a: USB Gadget support * Fix for MMC Write Issue
Shrinivas Sahukar (1): fix for MMC write issue
Srikanth Reddy Vintha (4): MSM7630: USB Gadget support MSM 7x27a: Add support for qualcomm msm 7x27a SOC MSM 7x27a: Add support for qualcomm msm7x27a surf board MSM7x27a: USB Gadget support
arch/arm/cpu/armv7/msm7x27a/Makefile | 53 +++ arch/arm/cpu/armv7/msm7x27a/acpuclock.c | 258 +++++++++++ arch/arm/cpu/armv7/msm7x27a/board.c | 66 +++ arch/arm/cpu/armv7/msm7x27a/config.mk | 21 + arch/arm/cpu/armv7/msm7x27a/gpio.c | 287 +++++++++++++ arch/arm/cpu/armv7/msm7x27a/lowlevel_init.S | 118 +++++ arch/arm/cpu/armv7/msm7x27a/timer.c | 127 ++++++ arch/arm/include/asm/arch-msm7630/irqs.h | 162 +++++++ arch/arm/include/asm/arch-msm7x27a/gpio.h | 47 ++ arch/arm/include/asm/arch-msm7x27a/iomap.h | 106 +++++ arch/arm/include/asm/arch-msm7x27a/irqs.h | 138 ++++++ arch/arm/include/asm/arch-msm7x27a/mmc.h | 399 +++++++++++++++++ arch/arm/include/asm/arch-msm7x27a/proc_comm.h | 42 ++ arch/arm/include/asm/arch-msm7x27a/sys_proto.h | 27 ++ board/qcom/msm7x27a_surf/Makefile | 56 +++ board/qcom/msm7x27a_surf/msm7x27a_surf.c | 126 ++++++ board/qcom/msm7x27a_surf/msm7x27a_surf.h | 27 ++ boards.cfg | 1 + drivers/mmc/qc_mmc.c | 71 +++- drivers/serial/usbtty.h | 2 + drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/msm_udc.c | 540 ++++++++++++++++++++++++ include/configs/msm7630_surf.h | 11 +- include/configs/msm7x27a_surf.h | 127 ++++++ include/usb/msm_udc.h | 178 ++++++++ 25 files changed, 2985 insertions(+), 6 deletions(-) create mode 100644 arch/arm/cpu/armv7/msm7x27a/Makefile create mode 100644 arch/arm/cpu/armv7/msm7x27a/acpuclock.c create mode 100644 arch/arm/cpu/armv7/msm7x27a/board.c create mode 100644 arch/arm/cpu/armv7/msm7x27a/config.mk create mode 100644 arch/arm/cpu/armv7/msm7x27a/gpio.c create mode 100644 arch/arm/cpu/armv7/msm7x27a/lowlevel_init.S create mode 100644 arch/arm/cpu/armv7/msm7x27a/timer.c create mode 100644 arch/arm/include/asm/arch-msm7630/irqs.h create mode 100644 arch/arm/include/asm/arch-msm7x27a/gpio.h create mode 100644 arch/arm/include/asm/arch-msm7x27a/iomap.h create mode 100644 arch/arm/include/asm/arch-msm7x27a/irqs.h create mode 100644 arch/arm/include/asm/arch-msm7x27a/mmc.h create mode 100644 arch/arm/include/asm/arch-msm7x27a/proc_comm.h create mode 100644 arch/arm/include/asm/arch-msm7x27a/sys_proto.h create mode 100644 board/qcom/msm7x27a_surf/Makefile create mode 100644 board/qcom/msm7x27a_surf/msm7x27a_surf.c create mode 100644 board/qcom/msm7x27a_surf/msm7x27a_surf.h create mode 100644 drivers/usb/gadget/msm_udc.c create mode 100644 include/configs/msm7x27a_surf.h create mode 100644 include/usb/msm_udc.h

Signed-off-by: Srikanth Reddy Vintha srikanth.reddy@lntinfotech.com --- arch/arm/include/asm/arch-msm7630/irqs.h | 162 +++++++++ drivers/serial/usbtty.h | 2 + drivers/usb/gadget/Makefile | 1 + drivers/usb/gadget/msm_udc.c | 540 ++++++++++++++++++++++++++++++ include/configs/msm7630_surf.h | 11 +- include/usb/msm_udc.h | 178 ++++++++++ 6 files changed, 891 insertions(+), 3 deletions(-) create mode 100644 arch/arm/include/asm/arch-msm7630/irqs.h create mode 100644 drivers/usb/gadget/msm_udc.c create mode 100644 include/usb/msm_udc.h
diff --git a/arch/arm/include/asm/arch-msm7630/irqs.h b/arch/arm/include/asm/arch-msm7630/irqs.h new file mode 100644 index 0000000..b0c011f --- /dev/null +++ b/arch/arm/include/asm/arch-msm7630/irqs.h @@ -0,0 +1,162 @@ +/* + * (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 __ASM_ARCH_MSM_IRQS_7X30_H +#define __ASM_ARCH_MSM_IRQS_7X30_H + +/* MSM ACPU Interrupt Numbers */ + +#define INT_DEBUG_TIMER_EXP 0 +#define INT_GPT0_TIMER_EXP 1 +#define INT_GPT1_TIMER_EXP 2 +#define INT_WDT0_ACCSCSSBARK 3 +#define INT_WDT1_ACCSCSSBARK 4 +#define INT_AVS_SVIC 5 +#define INT_AVS_SVIC_SW_DONE 6 +#define INT_SC_DBG_RX_FULL 7 +#define INT_SC_DBG_TX_EMPTY 8 +#define INT_SC_PERF_MON 9 +#define INT_AVS_REQ_DOWN 10 +#define INT_AVS_REQ_UP 11 +#define INT_SC_ACG 12 +/* SCSS_VICFIQSTS1[13:15] are RESERVED */ +#define INT_L2_SVICCPUIRPTREQ 16 +#define INT_L2_SVICDMANSIRPTREQ 17 +#define INT_L2_SVICDMASIRPTREQ 18 +#define INT_L2_SVICSLVIRPTREQ 19 +#define INT_AD5A_MPROC_APPS_0 20 +#define INT_AD5A_MPROC_APPS_1 21 +#define INT_A9_M2A_0 22 +#define INT_A9_M2A_1 23 +#define INT_A9_M2A_2 24 +#define INT_A9_M2A_3 25 +#define INT_A9_M2A_4 26 +#define INT_A9_M2A_5 27 +#define INT_A9_M2A_6 28 +#define INT_A9_M2A_7 29 +#define INT_A9_M2A_8 30 +#define INT_A9_M2A_9 31 + +#define INT_AXI_EBI1_SC (32 + 0) +#define INT_IMEM_ERR (32 + 1) +#define INT_AXI_EBI0_SC (32 + 2) +#define INT_PBUS_SC_IRQC (32 + 3) +#define INT_PERPH_BUS_BPM (32 + 4) +#define INT_CC_TEMP_SENSE (32 + 5) +#define INT_UXMC_EBI0 (32 + 6) +#define INT_UXMC_EBI1 (32 + 7) +#define INT_EBI2_OP_DONE (32 + 8) +#define INT_EBI2_WR_ER_DONE (32 + 9) +#define INT_TCSR_SPSS_CE (32 + 10) +#define INT_EMDH (32 + 11) +#define INT_PMDH (32 + 12) +#define INT_MDC (32 + 13) +#define INT_MIDI_TO_SUPSS (32 + 14) +#define INT_LPA_2 (32 + 15) +#define INT_GPIO_GROUP1_SECURE (32 + 16) +#define INT_GPIO_GROUP2_SECURE (32 + 17) +#define INT_GPIO_GROUP1 (32 + 18) +#define INT_GPIO_GROUP2 (32 + 19) +#define INT_MPRPH_SOFTRESET (32 + 20) +#define INT_PWB_I2C (32 + 21) +#define INT_PWB_I2C_2 (32 + 22) +#define INT_TSSC_SAMPLE (32 + 23) +#define INT_TSSC_PENUP (32 + 24) +#define INT_TCHSCRN_SSBI (32 + 25) +#define INT_FM_RDS (32 + 26) +#define INT_KEYSENSE (32 + 27) +#define INT_USB_OTG_HS (32 + 28) +#define INT_USB_OTG_HS2 (32 + 29) +#define INT_USB_OTG_HS3 (32 + 30) +#define INT_RESERVED_BIT31 (32 + 31) + +#define INT_SPI_OUTPUT (64 + 0) +#define INT_SPI_INPUT (64 + 1) +#define INT_SPI_ERROR (64 + 2) +#define INT_UART1 (64 + 3) +#define INT_UART1_RX (64 + 4) +#define INT_UART2 (64 + 5) +#define INT_UART2_RX (64 + 6) +#define INT_UART3 (64 + 7) +#define INT_UART3_RX (64 + 8) +#define INT_UART1DM_IRQ (64 + 9) +#define INT_UART1DM_RX (64 + 10) +#define INT_UART2DM_IRQ (64 + 11) +#define INT_UART2DM_RX (64 + 12) +#define INT_TSIF (64 + 13) +#define INT_ADM_SC1 (64 + 14) +#define INT_ADM_SC2 (64 + 15) +#define INT_MDP (64 + 16) +#define INT_VPE (64 + 17) +#define INT_GRP_2D (64 + 18) +#define INT_GRP_3D (64 + 19) +#define INT_ROTATOR (64 + 20) +#define INT_MFC720 (64 + 21) +#define INT_JPEG (64 + 22) +#define INT_VFE (64 + 23) +#define INT_TV_ENC (64 + 24) +#define INT_PMIC_SSBI (64 + 25) +#define INT_MPM_1 (64 + 26) +#define INT_TCSR_SPSS_SAMPLE (64 + 27) +#define INT_TCSR_SPSS_PENUP (64 + 28) +#define INT_MPM_2 (64 + 29) +#define INT_SDC1_0 (64 + 30) +#define INT_SDC1_1 (64 + 31) + +#define INT_SDC3_0 (96 + 0) +#define INT_SDC3_1 (96 + 1) +#define INT_SDC2_0 (96 + 2) +#define INT_SDC2_1 (96 + 3) +#define INT_SDC4_0 (96 + 4) +#define INT_SDC4_1 (96 + 5) +#define INT_PWB_QUP_IN (96 + 6) +#define INT_PWB_QUP_OUT (96 + 7) +#define INT_PWB_QUP_ERR (96 + 8) +/* SCSS_VICFIQSTS3[6:31] are RESERVED */ + +/* Retrofit universal macro names */ +#define INT_ADM_AARM INT_ADM_SC2 +#define INT_USB_HS INT_USB_OTG_HS +#define INT_USB_OTG INT_USB_OTG_HS +#define INT_TCHSCRN1 INT_TSSC_SAMPLE +#define INT_TCHSCRN2 INT_TSSC_PENUP +#define INT_GP_TIMER_EXP INT_GPT0_TIMER_EXP +#define INT_ADSP_A11 INT_AD5A_MPROC_APPS_0 +#define INT_ADSP_A9_A11 INT_AD5A_MPROC_APPS_1 +#define INT_MDDI_EXT INT_EMDH +#define INT_MDDI_PRI INT_PMDH +#define INT_MDDI_CLIENT INT_MDC +#define INT_NAND_WR_ER_DONE INT_EBI2_WR_ER_DONE +#define INT_NAND_OP_DONE INT_EBI2_OP_DONE + +#define NR_MSM_IRQS 128 +#define NR_GPIO_IRQS 182 +#define PMIC8058_IRQ_BASE (NR_MSM_IRQS + NR_GPIO_IRQS) +#define NR_PMIC8058_GPIO_IRQS 40 +#define NR_PMIC8058_MPP_IRQS 12 +#define NR_PMIC8058_MISC_IRQS 8 +#define NR_PMIC8058_IRQS (NR_PMIC8058_GPIO_IRQS +\ + NR_PMIC8058_MPP_IRQS +\ + NR_PMIC8058_MISC_IRQS) +#define NR_BOARD_IRQS NR_PMIC8058_IRQS + +#define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + NR_BOARD_IRQS) + +#endif /* __ASM_ARCH_MSM_IRQS_7X30_H */ diff --git a/drivers/serial/usbtty.h b/drivers/serial/usbtty.h index e449cd7..8321447 100644 --- a/drivers/serial/usbtty.h +++ b/drivers/serial/usbtty.h @@ -35,6 +35,8 @@ #include <usb/pxa27x_udc.h> #elif defined(CONFIG_SPEAR3XX) || defined(CONFIG_SPEAR600) #include <usb/spr_udc.h> +#elif defined(CONFIG_MSM_UDC) +#include <usb/msm_udc.h> #endif
#include <version.h> diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile index 64b091f..44ffa8a 100644 --- a/drivers/usb/gadget/Makefile +++ b/drivers/usb/gadget/Makefile @@ -44,6 +44,7 @@ COBJS-$(CONFIG_OMAP1610) += omap1510_udc.o COBJS-$(CONFIG_MPC885_FAMILY) += mpc8xx_udc.o COBJS-$(CONFIG_CPU_PXA27X) += pxa27x_udc.o COBJS-$(CONFIG_SPEARUDC) += spr_udc.o +COBJS-$(CONFIG_MSM_UDC) += msm_udc.o endif endif
diff --git a/drivers/usb/gadget/msm_udc.c b/drivers/usb/gadget/msm_udc.c new file mode 100644 index 0000000..35e9b20 --- /dev/null +++ b/drivers/usb/gadget/msm_udc.c @@ -0,0 +1,540 @@ +/* + * (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 <common.h> +#include <asm/io.h> +#include <malloc.h> +#include <usbdevice.h> +#include <usb/msm_udc.h> +#include <asm/arch/irqs.h> +#include "ep0.h" + +#define mdelay(ms) udelay((ms) * 1000) +#define USB_EP_NUM(ep) ((ep)->endpoint_address & USB_ENDPOINT_NUMBER_MASK) +#define USB_EP_DIR(ep) ((ep)->endpoint_address & USB_ENDPOINT_DIR_MASK) +#define USB_EP_MAX_PKT(ep) (USB_EP_DIR(ep) ? (ep)->tx_packetSize : \ + (ep)->rcv_packetSize) +#ifdef DEBUG +/* Debug output must not use stdout as that can cause an infinite loop when + * stdout is usbtty */ +#define udcdbg serial_printf +#else +#define udcdbg(fmt, args...) +#endif + +static struct ept_queue_head *dQHs; +static int usb_highspeed; /* Binary value indicating supported speed */ +static struct usb_device_instance *udc_device; +volatile static struct ept_queue_item *dTD_list[USB_MAX_EPTS]; + +static struct urb *msm_udc_get_urb_by_dir(unsigned num, unsigned direction) +{ + struct usb_endpoint_instance *epi = + &udc_device->bus->endpoint_array[num]; + struct urb **urb = (direction == USB_DIR_IN) ? &epi->tx_urb : + &epi->rcv_urb; + + if (!*urb) { + *urb = usbd_alloc_urb(udc_device, epi); + udcdbg("ep%i%s allocating new URB %#08x\n", num, + USB_EP_DIR(epi) ? "in" : "out", (unsigned) *urb); + } + + return *urb; +} + +static struct urb *msm_udc_get_urb(unsigned num) +{ + struct usb_endpoint_instance *epi = + &udc_device->bus->endpoint_array[num]; + return msm_udc_get_urb_by_dir(num, USB_EP_DIR(epi)); +} + +/** + * Returns the dQH from the list + * @param num 0..15 where 0 is the control endpoint + * @param direction = [USB_DIR_IN, USB_DIR_OUT] + */ +static struct ept_queue_head *msm_udc_get_dQH(unsigned num, unsigned direction) +{ + /* Even elements of dQHs are for RX and odd for TX */ + return (struct ept_queue_head *) (dQHs + (num * 2) + + ((direction == USB_DIR_IN) ? 1 : 0)); +} + +static void msm_udc_ep_enable(unsigned num, unsigned enable) +{ + unsigned n = readl(USB_ENDPTCTRL(num)); + + if (enable) { + struct usb_endpoint_instance *epi = + &udc_device->bus->endpoint_array[num]; + unsigned direction = USB_EP_DIR(epi); + + if (direction == USB_DIR_IN) + n |= (CTRL_TXE | CTRL_TXR | CTRL_TXT_BULK); + else + n |= (CTRL_RXE | CTRL_RXR | CTRL_RXT_BULK); + + if (num != 0) { + struct ept_queue_head *dQH = + msm_udc_get_dQH(num, direction); + unsigned highspeed = + (((readl(USB_PORTSC) >> 26) & 3) == 2) ? 1 : 0; + unsigned max_packet = highspeed ? 512 : 64; + /* The Mult field is 0 for all but isochronous EPs */ + dQH->config = CONFIG_MAX_PKT(max_packet) | CONFIG_ZLT; + } + } + writel(n, USB_ENDPTCTRL(num)); +} + +static void msm_udc_ep0_send_ack(void) +{ + struct usb_endpoint_instance *epi = + &udc_device->bus->endpoint_array[0]; + struct urb *urb; + + /* Send ACK in opposite direction to request */ + epi->endpoint_address = USB_EP_DIR(epi) ? USB_DIR_OUT : USB_DIR_IN; + urb = msm_udc_get_urb(0); + urb->actual_length = 0; + udc_endpoint_write(epi); +} + +#define SETUP(type, request) (((type) << 8) | (request)) +static void msm_udc_handle_setup(void) +{ + int err; + struct usb_device_request s; + struct ept_queue_head *dQH = msm_udc_get_dQH(0, USB_DIR_OUT); + struct usb_endpoint_instance *epi = + &udc_device->bus->endpoint_array[0]; + struct urb *urb; + + /* Setup Packet Handling (if Setup Lockout is used): + * - Backup dQH.SsetupBuffer + * - Write a 1 to USB_ENDPTSETUPSTAT which deactivates Setup Lockout + * - Process the packet using the copy (flush/dealloc stale handshake + * phases) + * - Before priming for handshake phase, wait for ENDPTSETUPSTAT to + * transition to zero */ + memcpy(&s, dQH->setup_data, sizeof(struct usb_device_request)); + writel(EPT_RX(0), USB_ENDPTSETUPSTAT); + + epi->endpoint_address = s.bmRequestType & USB_REQ_DIRECTION_MASK; + urb = msm_udc_get_urb(0); /* URB is dependent on EP direction */ + urb->device_request = s; + + print_usb_device_request(&s); + + /* Handle gadget internals and for IN requests setup urb */ + err = ep0_recv_setup(urb); + if (err) + return; + + switch (SETUP(s.bmRequestType, s.bRequest)) { + case SETUP(USB_REQ_RECIPIENT_DEVICE, USB_REQ_SET_CONFIGURATION): + udcdbg("set config\n"); + if (s.wValue == 1) { /* Online */ + unsigned i; + for (i = 1; i < udc_device->bus->max_endpoints; i++) + msm_udc_ep_enable(i, s.wValue); + usbd_device_event_irq(udc_device, + DEVICE_CONFIGURED, 0); + } else { /* Offline */ + writel(0, USB_ENDPTCTRL(1)); + usbd_device_event_irq(udc_device, + DEVICE_DE_CONFIGURED, 0); + } + msm_udc_ep0_send_ack(); + break; + case SETUP(USB_REQ_RECIPIENT_ENDPOINT, USB_REQ_CLEAR_FEATURE): + udcdbg("clear feature\n"); + if ((s.wValue == 0) && (s.wLength == 0)) { + unsigned num = s.wIndex & USB_ENDPOINT_NUMBER_MASK; + unsigned direction = s.wIndex & USB_ENDPOINT_DIR_MASK; + + udcdbg("Clear feature ep%i%s\n", num, direction ? + "in" : "out"); + msm_udc_ep_enable(num, 1); + msm_udc_ep0_send_ack(); + } else { + err = -1; /* stall */ + } + break; + case SETUP(USB_REQ_RECIPIENT_DEVICE, USB_REQ_SET_ADDRESS): + udcdbg("set address\n"); + writel((s.wValue << 25) | (1 << 24), USB_DEVICEADDR); + usbd_device_event_irq(udc_device, DEVICE_ADDRESS_ASSIGNED, 0); + msm_udc_ep0_send_ack(); + break; + case SETUP(USB_REQ_RECIPIENT_INTERFACE, USB_REQ_SET_INTERFACE): + udcdbg("set interface\n"); + err = -1; /* stall */ + break; + case SETUP(USB_REQ_RECIPIENT_DEVICE, USB_REQ_SET_FEATURE): + udcdbg("set feature\n"); + if (s.wIndex == 0x400) { + udcdbg("Entering test mode for TST_PKT\n"); + unsigned mode = readl(USB_PORTSC) & (~PORTSC_PTC); + writel(mode | PORTSC_PTC_TST_PKT, USB_PORTSC); + } + msm_udc_ep0_send_ack(); + break; + } + + if (!err) { + if ((s.bmRequestType & USB_REQ_DIRECTION_MASK) == + USB_REQ_DEVICE2HOST) + udc_endpoint_write(epi); /* Request returns data */ + /* else we already sent ACK as needed */ + } else { + udcdbg("STALL\n"); + writel((1<<16) | (1 << 0), USB_ENDPTCTRL(0)); + } +} + +static void msm_udc_ep_complete(unsigned num, unsigned direction) +{ + struct ept_queue_item *dTD = (struct ept_queue_item *)dTD_list[num]; + struct usb_endpoint_instance *epi = + &udc_device->bus->endpoint_array[num]; + struct urb *urb = msm_udc_get_urb_by_dir(num, direction); + unsigned left; + unsigned actual; /* urb->actual_length modified by _complete() */ + int urb_bad = 0; + + udcdbg("ep%i%s complete dTD=%p ", num, direction ? "in" : "out", dTD); + if (dTD_list[num] == NULL) { + udcdbg("FAIL no xfer has been queued\n"); + return; + } else if (dTD->info & INFO_ACTIVE) { + udcdbg("BAIL transfer descriptor is active\n"); + return; + } else if (dTD_list[num]->next == (struct ept_queue_item *) TERMINATE) + dTD_list[num] = NULL; + else { + udcdbg("popping dTD "); + dTD_list[num] = dTD_list[num]->next; + } + + left = UDC_DTD_TOTAL_BYTES(dTD->info); + actual = ((num != 0) && (direction == USB_DIR_OUT)) ? + urb->buffer_length : urb->actual_length; + epi->last = actual - left; + + if (dTD->info & (INFO_HALTED | INFO_BUFFER_ERROR | INFO_TX_ERROR)) { + udcdbg("FAIL info=%x,page0=%x\n", dTD->info, dTD->page0); + urb_bad = 1; + } else + udcdbg("SUCCESS left=%i,sent=%i,last=%i,len=%i\n", left, + epi->sent, epi->last, urb->actual_length); + + if (direction == USB_DIR_OUT) + usbd_rcv_complete(epi, epi->last, urb_bad); + else + usbd_tx_complete(epi); + + if (!urb_bad && (num == 0) && (actual != 0)) + msm_udc_ep0_send_ack(); + free(dTD); +} + +static void msm_udc_handle_usbsts(unsigned status) +{ + if (status & STS_SLI) { + udcdbg("STS_SLI = Suspend\n"); + /* Could keep track and subsequently use Resume signalling but + * this is optional */ + } + if (status & STS_URI) { + unsigned num; + udcdbg("STS_URI = Reset\n"); + /* Clear setup token semaphores */ + writel(readl(USB_ENDPTSETUPSTAT), USB_ENDPTSETUPSTAT); + /* Clear endpoint complete status bits */ + writel(readl(USB_ENDPTCOMPLETE), USB_ENDPTCOMPLETE); + writel(0xffffffff, USB_ENDPTFLUSH); + /* After reset, all EPs but ep0 are uninit and disabled */ + writel(0, USB_ENDPTCTRL(1)); + /* error out any pending reqs */ + for (num = 0; num < udc_device->bus->max_endpoints; num++) { + while (dTD_list[num] != NULL) { + struct usb_endpoint_instance *epi = + &udc_device->bus->endpoint_array[num]; + dTD_list[num]->info = INFO_HALTED; + msm_udc_ep_complete(num, USB_EP_DIR(epi)); + } + } + } + if (status & STS_PCI) { + /* Comes after a Reset to indicate the transition into the + * Default state and comes as part of the Reset process. The + * device speed can now be read out of PORTSC */ + usb_highspeed = (((readl(USB_PORTSC) >> 26) & 3) == 2) ? 1 : 0; + udcdbg("STS_PCI = Port Change Detect HS=%i\n", usb_highspeed); + usbd_device_event_irq(udc_device, DEVICE_RESET, 0); + } + if ((status & STS_UI) || (status & STS_UEI)) { + unsigned n, num; + /* USB Interrupt and USB Error Interrupt */ + udcdbg("STS_UI and STS_UEI = TX(s) Done\n"); + if (status & STS_UEI) + udcdbg("Error %#x\n", readl(USB_ENDPTCOMPLETE)); + + n = readl(USB_ENDPTSETUPSTAT); + if (n & EPT_RX(0)) /* Handle setup first */ + msm_udc_handle_setup(); + + n = readl(USB_ENDPTCOMPLETE); + writel(n, USB_ENDPTCOMPLETE); + udcdbg("USB_ENDPTCOMPLETE = %#x\n", n); + for (num = 0; num < udc_device->bus->max_endpoints; num++) { + if (EPT_TX(num) & n) + msm_udc_ep_complete(num, USB_DIR_IN); + if (EPT_RX(num) & n) + msm_udc_ep_complete(num, USB_DIR_OUT); + } + } +} + +int udc_endpoint_write(struct usb_endpoint_instance *epi) +{ + unsigned num = USB_EP_NUM(epi); + unsigned direction = USB_EP_DIR(epi); + struct urb *urb = msm_udc_get_urb(num); + struct ept_queue_head *dQH = msm_udc_get_dQH(num, direction); + struct ept_queue_item *dTD = memalign(sizeof(*dTD), sizeof(*dTD)); + unsigned length = ((num == 0) | (direction == USB_DIR_IN)) ? + urb->actual_length : urb->buffer_length; + + udcdbg("ep%i%sWrite buffer=%p,length=%i,actual_length=%i,dTD=%p", + num, direction ? "in" : "out", urb->buffer, length, + urb->actual_length, dTD); + + if (length > 0x4000) + return -1; + + epi->sent = 0; + /* From 6.6.2 Building a Transfer Descriptor: + * 1. Initialize first 7 DWords to 0. + * 2. Set the terminate bit to 1 + * 3. Fill in total bytes with transfer size. + * 4. Set the interrupt on complete if desired. + * 5. Initialize the status field with the active bit set to 1 and + * all remaining status bits set to 0 + * 6. Fill in buffer pointer page 0 and the current offset to + * point to the start of the data buffer. + * 7. Initialize buffer pointer page 1 through page 4 to be one + * greater than each of the previous buffer pointer. */ + memset(dTD, 0, sizeof(*dTD)); + dTD->next = (struct ept_queue_item *) TERMINATE; + dTD->info = INFO_BYTES(length) | INFO_IOC | INFO_ACTIVE; + dTD->page0 = (unsigned) urb->buffer; + dTD->page1 = ((unsigned) urb->buffer & 0xfffff000) + 0x1000; + dTD->page2 = ((unsigned) urb->buffer & 0xfffff000) + 0x2000; + dTD->page3 = ((unsigned) urb->buffer & 0xfffff000) + 0x3000; + + /* To Prime: + * 1. Fetch the dTD for the transaction pointed to by dQH + * 2. Store the dTD in the dQH + * 3. Indicate primed in ENDPTPRIME */ + /* Handle the case where there are completed dTDs waiting */ + if (dTD_list[num] != NULL) { + struct ept_queue_item *dTDlast = + (struct ept_queue_item *)dTD_list[num]; + unsigned qDepth = 1; + while (dTDlast->next != (struct ept_queue_item *) TERMINATE) { + dTDlast = dTDlast->next; + qDepth++; + } + udcdbg(",qing size=%i", qDepth); + dTDlast->next = dTD; + } else /* dQH only references active and queued dTDs */ + dTD_list[num] = dTD; + if ((dQH->next != TERMINATE) && (dQH->next != 0)) + udcdbg(",dQH busy\n"); + else { + int bit = direction ? EPT_TX(num) : EPT_RX(num); + dQH->next = (unsigned) dTD; + dQH->info = 0; + udcdbg(",bit=%x,dQH=%p\n", bit, dQH); + writel(bit, USB_ENDPTPRIME); + } + + return 0; +} + +void udc_irq(void) /* Handle any USB events */ +{ + unsigned num; + unsigned waited = 0; + unsigned sts = readl(USB_USBSTS); + writel(sts, USB_USBSTS); + sts &= (STS_SLI | STS_URI | STS_PCI | STS_UI | STS_UEI); + udcdbg("\nmsm_udc_interrupt_handler(USBSTS=%#0x):\n", sts); + + while (sts != 0) { + msm_udc_handle_usbsts(sts); + sts = readl(USB_USBSTS); + writel(sts, USB_USBSTS); + sts &= (STS_SLI | STS_URI | STS_PCI | STS_UI | STS_UEI); + udcdbg("USBSTS = %#x\n", sts); + } + /* OUT endpoints must be primed to receive data from the host */ + if (udc_device && (udc_device->device_state == STATE_CONFIGURED)) { + for (num = 1; num < udc_device->bus->max_endpoints; num++) { + struct usb_endpoint_instance *epi = + &udc_device->bus->endpoint_array[num]; + if ((USB_EP_DIR(epi) == USB_DIR_OUT) && + (dTD_list[num] == NULL)) { + struct urb *urb = msm_udc_get_urb(num); + + if (urb->actual_length == 0) + udc_endpoint_write(epi); + } + } + } + /* Actual packet processing handled in IRQs */ + /* Delay the main thread so only one TX can be queued at a tuime */ + for (num = 0; num < udc_device->bus->max_endpoints; num++) { + struct usb_endpoint_instance *epi = + &udc_device->bus->endpoint_array[num]; + if ((USB_EP_DIR(epi) == USB_DIR_IN) && + (dTD_list[num] != NULL)) { + udcdbg("Waiting on epIn dTD_list[%i]=%p\n", num, + dTD_list[num]); + waited = 1; + while (dTD_list[num] != NULL) + /* Wait for interrupt to run */; + num = 0; /* Reset loop */ + } + } + if (waited) + udcdbg("Done waiting\n"); +} + +void udc_set_nak(int epid) +{ + /* TODO */ +} + +void udc_unset_nak(int epid) +{ + /* TODO */ +} + +void udc_disconnect(void) +{ + udcdbg("Disconnect USB\n"); + writel(0x00080000, USB_USBCMD); /* disable pullup */ + mdelay(10); +} + +void udc_connect(void) +{ + udcdbg("Connect USB\n"); + /* Enable the Run/Stop bit (D+ pullup enable): this initiates a restart + * that the DCD must monitor for. ep0 q heads must be setup */ + writel(0x00080001, USB_USBCMD); + usbd_device_event_irq(udc_device, DEVICE_HUB_CONFIGURED, 0); +} + +void udc_startup_events(struct usb_device_instance *device) +{ + udcdbg("Startup events\n"); + usbd_device_event_irq(device, DEVICE_INIT, 0); + usbd_device_event_irq(device, DEVICE_CREATE, 0); + udc_device = device; +} + +void udc_setup_ep(struct usb_device_instance *device, + unsigned int num, struct usb_endpoint_instance *epi) +{ + unsigned direction = USB_EP_DIR(epi); + struct ept_queue_head *dQH; + int cfg = CONFIG_MAX_PKT(USB_EP_MAX_PKT(epi)) | CONFIG_ZLT; + + if (num >= USB_MAX_EPTS) { + udcdbg("ERROR DC only supports %i endpoints!\n", USB_MAX_EPTS); + return; + } + + udcdbg("Init ep%i%s max=%i,", num, direction ? "in" : "out", + USB_EP_MAX_PKT(epi)); + + if (num == 0) { + /* For EP0 both directions must be setup */ + direction = USB_DIR_IN; + dQH = msm_udc_get_dQH(num, direction); + udcdbg("dQH0in=%#08x,", (unsigned) dQH); + dQH->config = cfg; + direction = USB_DIR_OUT; + cfg |= CONFIG_IOS; + } + dQH = msm_udc_get_dQH(num, direction); + udcdbg("dQH%i%s=%#08x\n", num, direction ? "in" : "out", + (unsigned) dQH); + dQH->config = cfg; +} + +int udc_init(void) +{ + hsusb_clock_init(); + writel(0x81000000, USB_PORTSC); /* select ULPI phy */ + + udcdbg("udc_init():Read USB_ID %#010x from %#010x\n", + readl(USB_ID), USB_ID); + + /* Init globals */ + dQHs = NULL; + usb_highspeed = 0; + udc_device = NULL; + memset(dTD_list, 0, sizeof(dTD_list)); + + /* Reset */ + writel(0x00080002, USB_USBCMD); + mdelay(20); + + writel(0, USB_AHB_MODE); + writel(0, USB_AHB_BURST); + + /* According to the CI13611 Programmers Guide, the software must ensure + * that no interface data-structure reachable by the Device Controller + * spans a 4K page boundary */ + dQHs = memalign(4096, 4096); + if (dQHs == NULL) + return -1; + memset(dQHs, 0, 4096); + /* ENDPOINTLISTADDR must point to a contiguous chunk of memory where + * the even numbered addresses are RX endpoints and odd TX endpoints. + * The UDC indexes into this list based on the endpoint number. + * Eg. Offset Queue-Head + * 0 0 - Out + * 4 0 - In + * 8 1 - Out + * etc. etc. */ + writel((unsigned) dQHs, USB_ENDPOINTLISTADDR); + writel(0x02, USB_USBMODE); /* select DEVICE mode */ + writel(0xffffffff, USB_ENDPTFLUSH); + mdelay(20); + return 0; +} diff --git a/include/configs/msm7630_surf.h b/include/configs/msm7630_surf.h index 5aa6be0..0539748 100644 --- a/include/configs/msm7630_surf.h +++ b/include/configs/msm7630_surf.h @@ -36,8 +36,12 @@ /* * Size of malloc() pool */ -#define CONFIG_SYS_MALLOC_LEN (4 * 1024) /* 4KB */ -#define CONFIG_MSM7630 +#define CONFIG_SYS_MALLOC_LEN (4 * 1024) /* 4KB */ + +/* Enable USB */ +#define CONFIG_MSM_UDC +#define CONFIG_USB_TTY +#define CONFIG_USB_DEVICE
/* * select serial console configuration @@ -62,8 +66,9 @@ #undef CONFIG_SYS_MAX_FLASH_SECT #define CONFIG_EXTRA_ENV_SETTINGS \ "console=ttyS0,115200n8\0" \ + "usbtty=cdc_acm\0"
-#define CONFIG_BOOTDELAY 2 /* -1 to disable auto boot */ +#define CONFIG_BOOTDELAY -1 /* -1 to disable auto boot */
/* * Miscellaneous configurable options diff --git a/include/usb/msm_udc.h b/include/usb/msm_udc.h new file mode 100644 index 0000000..782f9ac --- /dev/null +++ b/include/usb/msm_udc.h @@ -0,0 +1,178 @@ +/* + * (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 <usbdevice.h> +#include <asm/arch/iomap.h> + +#define USB_MAX_EPTS 16 + +/* Define the EP number and packet sizes */ +#define EP0_MAX_PACKET_SIZE 64 +#define UDC_INT_ENDPOINT 1 +#define UDC_INT_PACKET_SIZE 64 +#define UDC_OUT_ENDPOINT 2 +#define UDC_OUT_PACKET_SIZE 512 +#define UDC_IN_ENDPOINT 3 +#define UDC_IN_PACKET_SIZE 512 +#define UDC_BULK_PACKET_SIZE 512 + +#ifndef MSM_USB_BASE +#error Must define base address of USB controller MSM_USB_BASE +#endif + +#define USB_ID (MSM_USB_BASE + 0x0000) +#define USB_HWGENERAL (MSM_USB_BASE + 0x0004) +#define USB_HWHOST (MSM_USB_BASE + 0x0008) +#define USB_HWDEVICE (MSM_USB_BASE + 0x000C) +#define USB_HWTXBUF (MSM_USB_BASE + 0x0010) +#define USB_HWRXBUF (MSM_USB_BASE + 0x0014) +#define USB_SBUSCFG (MSM_USB_BASE + 0x0090) + +#define USB_AHB_BURST (MSM_USB_BASE + 0x0090) +#define USB_AHB_MODE (MSM_USB_BASE + 0x0098) +#define USB_CAPLENGTH (MSM_USB_BASE + 0x0100) /* 8 bit */ +#define USB_HCIVERSION (MSM_USB_BASE + 0x0102) /* 16 bit */ +#define USB_HCSPARAMS (MSM_USB_BASE + 0x0104) +#define USB_HCCPARAMS (MSM_USB_BASE + 0x0108) +#define USB_DCIVERSION (MSM_USB_BASE + 0x0120) /* 16 bit */ +#define USB_USBCMD (MSM_USB_BASE + 0x0140) +#define USB_USBSTS (MSM_USB_BASE + 0x0144) +#define USB_USBINTR (MSM_USB_BASE + 0x0148) +#define USB_FRINDEX (MSM_USB_BASE + 0x014C) +#define USB_DEVICEADDR (MSM_USB_BASE + 0x0154) +#define USB_ENDPOINTLISTADDR (MSM_USB_BASE + 0x0158) +#define USB_BURSTSIZE (MSM_USB_BASE + 0x0160) +#define USB_TXFILLTUNING (MSM_USB_BASE + 0x0164) +#define USB_ULPI_VIEWPORT (MSM_USB_BASE + 0x0170) +#define USB_ENDPTNAK (MSM_USB_BASE + 0x0178) +#define USB_ENDPTNAKEN (MSM_USB_BASE + 0x017C) +#define USB_PORTSC (MSM_USB_BASE + 0x0184) +#define USB_OTGSC (MSM_USB_BASE + 0x01A4) +#define USB_USBMODE (MSM_USB_BASE + 0x01A8) +#define USB_ENDPTSETUPSTAT (MSM_USB_BASE + 0x01AC) +#define USB_ENDPTPRIME (MSM_USB_BASE + 0x01B0) +#define USB_ENDPTFLUSH (MSM_USB_BASE + 0x01B4) +#define USB_ENDPTSTAT (MSM_USB_BASE + 0x01B8) +#define USB_ENDPTCOMPLETE (MSM_USB_BASE + 0x01BC) +#define USB_ENDPTCTRL(n) (MSM_USB_BASE + 0x01C0 + (4 * (n))) + +#define USBCMD_RESET 2 +#define USBCMD_ATTACH 1 + +#define USBMODE_DEVICE 2 +#define USBMODE_HOST 3 + + +/* Endpoint Txfer Descriptor dTD as defined by DC */ +struct ept_queue_item { + struct ept_queue_item *next; +#define UDC_DTD_TOTAL_BYTES(info) (((info) >> 16) & 0x7FFF) + unsigned info; /* 30:16-Total Bytes,7:0-Status */ + unsigned page0; + unsigned page1; + unsigned page2; + unsigned page3; + unsigned page4; + unsigned reserved; +}; +/* Endpoint Queue Head (dQH) as defined by the DC must take up 64K. + * There must be one dQH for every endpoint and direction. */ +struct ept_queue_head { + unsigned config; + unsigned current; /* read-only */ + unsigned next; + unsigned info; + unsigned page0; + unsigned page1; + unsigned page2; + unsigned page3; + unsigned page4; + unsigned reserved_0; + unsigned char setup_data[8]; + unsigned reserved_1; + unsigned reserved_2; + unsigned reserved_3; + unsigned reserved_4; +}; + +#define CONFIG_MAX_PKT(n) ((n) << 16) +#define CONFIG_ZLT (1 << 29) /* stop on zero-len xfer */ +#define CONFIG_IOS (1 << 15) /* IRQ on setup */ + +#define INFO_BYTES(n) ((n) << 16) +#define TERMINATE 1 + +#define INFO_IOC (1 << 15) +#define INFO_ACTIVE (1 << 7) +#define INFO_HALTED (1 << 6) +#define INFO_BUFFER_ERROR (1 << 5) +#define INFO_TX_ERROR (1 << 3) + +#define STS_NAKI (1 << 16) /* */ +#define STS_SLI (1 << 8) /* R/WC - suspend state entered */ +#define STS_SRI (1 << 7) /* R/WC - SOF recv'd */ +#define STS_URI (1 << 6) /* R/WC - RESET recv'd - write to clear */ +#define STS_FRI (1 << 3) /* R/WC - Frame List Rollover */ +#define STS_PCI (1 << 2) /* R/WC - Port Change Detect */ +#define STS_UEI (1 << 1) /* R/WC - USB Error */ +#define STS_UI (1 << 0) /* R/WC - USB Transaction Complete */ + +/* bits used in all the endpoint status registers */ +#define EPT_TX(n) (1 << ((n) + 16)) +#define EPT_RX(n) (1 << (n)) + +#define CTRL_TXE (1 << 23) /* TX Endpoint Enable */ +#define CTRL_TXR (1 << 22) /* TX Data Toggle Reset */ +#define CTRL_TXI (1 << 21) /* TX Data Toggle Inhibit */ +#define CTRL_TXT(n) ((n) << 18) /* TX Endpoint Type */ +#define CTRL_TXD (1 << 17) /* TX Endpoint Data Source */ +#define CTRL_TXS (1 << 16) /* TX Endpoint Stall */ +#define CTRL_RXE (1 << 7) /* RX Endpoint Enable */ +#define CTRL_RXR (1 << 6) /* RX Data Toggle Reset */ +#define CTRL_RXI (1 << 5) /* RX Data Toggle Inhibit */ +#define CTRL_RXT(n) ((n) << 2) /* RX Endpoint Type */ +#define CTRL_RXD (1 << 1) /* RX Endpoint Data Source */ +#define CTRL_RXS (1 << 0) /* RX Endpint Stall */ + +#define CTRL_TXT_CTRL (0 << 18) +#define CTRL_TXT_ISOCH (1 << 18) +#define CTRL_TXT_BULK (2 << 18) +#define CTRL_TXT_INT (3 << 18) + +#define CTRL_RXT_CTRL (0 << 2) +#define CTRL_RXT_ISOCH (1 << 2) +#define CTRL_RXT_BULK (2 << 2) +#define CTRL_RXT_INT (3 << 2) + +#define PORTSC_PTC (0xF << 16) +#define PORTSC_PTC_TST_PKT (0x4 << 16) + +extern void hsusb_clock_init(void); + +int udc_endpoint_write(struct usb_endpoint_instance *endpoint); +void udc_irq(void); +void udc_set_nak(int epid); +void udc_unset_nak(int epid); +void udc_disconnect(void); +void udc_connect(void); +void udc_startup_events(struct usb_device_instance *device); +void udc_setup_ep(struct usb_device_instance *device, + unsigned int epid, struct usb_endpoint_instance *ep); +int udc_init(void);

Signed-off-by: Srikanth Reddy Vintha srikanth.reddy@lntinfotech.com --- arch/arm/cpu/armv7/msm7x27a/Makefile | 53 ++++ arch/arm/cpu/armv7/msm7x27a/acpuclock.c | 252 +++++++++++++++ arch/arm/cpu/armv7/msm7x27a/board.c | 66 ++++ arch/arm/cpu/armv7/msm7x27a/config.mk | 21 ++ arch/arm/cpu/armv7/msm7x27a/gpio.c | 287 +++++++++++++++++ arch/arm/cpu/armv7/msm7x27a/lowlevel_init.S | 118 +++++++ arch/arm/cpu/armv7/msm7x27a/timer.c | 127 ++++++++ arch/arm/include/asm/arch-msm7x27a/gpio.h | 47 +++ arch/arm/include/asm/arch-msm7x27a/iomap.h | 105 +++++++ arch/arm/include/asm/arch-msm7x27a/mmc.h | 399 ++++++++++++++++++++++++ arch/arm/include/asm/arch-msm7x27a/proc_comm.h | 42 +++ arch/arm/include/asm/arch-msm7x27a/sys_proto.h | 27 ++ 12 files changed, 1544 insertions(+), 0 deletions(-) create mode 100644 arch/arm/cpu/armv7/msm7x27a/Makefile create mode 100644 arch/arm/cpu/armv7/msm7x27a/acpuclock.c create mode 100644 arch/arm/cpu/armv7/msm7x27a/board.c create mode 100644 arch/arm/cpu/armv7/msm7x27a/config.mk create mode 100644 arch/arm/cpu/armv7/msm7x27a/gpio.c create mode 100644 arch/arm/cpu/armv7/msm7x27a/lowlevel_init.S create mode 100644 arch/arm/cpu/armv7/msm7x27a/timer.c create mode 100644 arch/arm/include/asm/arch-msm7x27a/gpio.h create mode 100644 arch/arm/include/asm/arch-msm7x27a/iomap.h create mode 100644 arch/arm/include/asm/arch-msm7x27a/mmc.h create mode 100644 arch/arm/include/asm/arch-msm7x27a/proc_comm.h create mode 100644 arch/arm/include/asm/arch-msm7x27a/sys_proto.h
diff --git a/arch/arm/cpu/armv7/msm7x27a/Makefile b/arch/arm/cpu/armv7/msm7x27a/Makefile new file mode 100644 index 0000000..5f493d7 --- /dev/null +++ b/arch/arm/cpu/armv7/msm7x27a/Makefile @@ -0,0 +1,53 @@ +# +# (C) Copyright 2012 +# Larsen & Toubro Infotech Ltd. <www.lntinfotech.com> +# +# (C) Copyright 2010,2011 Nvidia Corporation. +# +# (C) Copyright 2000-2003 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# 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 $(TOPDIR)/config.mk + +LIB = $(obj)lib$(SOC).o + +SOBJS-y := lowlevel_init.o +COBJS-y := board.o +COBJS-y += timer.o +COBJS-y += acpuclock.o +COBJS-y += gpio.o + +SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS-y) $(SOBJS-y)) + +all: $(obj).depend $(LIB) + +$(LIB): $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/arch/arm/cpu/armv7/msm7x27a/acpuclock.c b/arch/arm/cpu/armv7/msm7x27a/acpuclock.c new file mode 100644 index 0000000..c144233 --- /dev/null +++ b/arch/arm/cpu/armv7/msm7x27a/acpuclock.c @@ -0,0 +1,252 @@ +/* + * (C) Copyright 2012 + * Larsen & Toubro Infotech Ltd. <www.lntinfotech.com> + * + * This source code is dual-licensed. You may use it under the terms of the + * GNU General Public License version 2, or under the license below. + * + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <asm/arch/iomap.h> +#include <asm/io.h> +#include <common.h> +#include <asm/arch/mmc.h> +#include <asm/arch/proc_comm.h> + +#define BIT(x) (1 << (x)) + +#define A11S_CLK_CNTL_ADDR (MSM_CSR_BASE + 0x100) +#define A11S_CLK_SEL_ADDR (MSM_CSR_BASE + 0x104) +#define VDD_SVS_PLEVEL_ADDR (MSM_CSR_BASE + 0x124) + +#define PLL2_MODE_ADDR (MSM_CLK_CTL_BASE + 0x338) +#define PLL4_MODE_ADDR (MSM_CLK_CTL_BASE + 0x374) + +#define PLL_RESET_N BIT(2) +#define PLL_BYPASSNL BIT(1) +#define PLL_OUTCTRL BIT(0) + +#define SRC_SEL_TCX0 0 /* TCXO */ +#define SRC_SEL_PLL1 1 /* PLL1: modem_pll */ +#define SRC_SEL_PLL2 2 /* PLL2: backup_pll_0 */ +#define SRC_SEL_PLL3 3 /* PLL3: backup_pll_1 */ +#define SRC_SEL_PLL4 6 /* PLL4: sparrow_pll */ + +#define DIV_1 0 +#define DIV_2 1 +#define DIV_3 2 +#define DIV_4 3 +#define DIV_5 4 +#define DIV_6 5 +#define DIV_7 6 +#define DIV_8 7 +#define DIV_9 8 +#define DIV_10 9 +#define DIV_11 10 +#define DIV_12 11 +#define DIV_13 12 +#define DIV_14 13 +#define DIV_15 14 +#define DIV_16 15 + +#define WAIT_CNT 100 +#define VDD_LEVEL 7 +#define MIN_AXI_HZ 120000000 +#define ACPU_800MHZ 41 + +#define A11S_CLK_SEL_MASK 0x7 /* bits 2:0 */ + +/* The stepping frequencies have been choosen to make sure the step + * is <= 256 MHz for both 7x27a and 7x25a targets. The + * table also assumes the ACPU is running at TCXO freq and AHB div is + * set to DIV_1. + * + * To use the tables: + * - Start at location 0/1 depending on clock source sel bit. + * - Set values till end of table skipping every other entry. + * - When you reach the end of the table, you are done scaling. + */ + +uint32_t const clk_cntl_reg_val_7627A[] = { + (WAIT_CNT << 16) | (SRC_SEL_PLL2 << 4) | DIV_16, + (WAIT_CNT << 16) | (SRC_SEL_PLL2 << 12) | (DIV_8 << 8), + (WAIT_CNT << 16) | (SRC_SEL_PLL2 << 4) | DIV_4, + (WAIT_CNT << 16) | (SRC_SEL_PLL2 << 12) | (DIV_2 << 8), + + /* TODO: Fix it for 800MHz */ +#if 0 + (WAIT_CNT << 16) | (SRC_SEL_PLL4 << 4) | DIV_1, +#endif +}; + + +/* Using DIV_1 for all cases to avoid worrying about turbo vs. normal + * mode. Able to use DIV_1 for all steps because it's the largest AND + * the final value. */ +uint32_t const clk_sel_reg_val[] = { + DIV_1 << 1 | 1, /* Switch to src1 */ + DIV_1 << 1 | 0, /* Switch to src0 */ +}; + +/* + * Mask to make sure current selected src frequency doesn't change. + */ +uint32_t const clk_cntl_mask[] = { + 0x0000FF00, /* Mask to read src0 */ + 0x000000FF /* Mask to read src1 */ +}; + +/* enum for SDC CLK IDs */ +enum { + SDC1_CLK = 19, + SDC1_PCLK = 20, + SDC2_CLK = 21, + SDC2_PCLK = 22, + SDC3_CLK = 23, + SDC3_PCLK = 24, + SDC4_CLK = 25, + SDC4_PCLK = 26 +}; +static uint8_t sdc_clk[] = {0, SDC1_CLK, SDC2_CLK, SDC3_CLK, SDC4_CLK}; +static uint8_t sdc_pclk[] = {0, SDC1_PCLK, SDC2_PCLK, SDC3_PCLK, SDC4_PCLK}; + + +void pll_enable(void *pll_mode_addr) +{ + uint32_t nVal; + /* Check status */ + nVal = readl(pll_mode_addr); + if (nVal & PLL_OUTCTRL) + return; + + /* Put the PLL in reset mode */ + nVal = 0; + nVal &= ~PLL_RESET_N; + nVal &= ~PLL_BYPASSNL; + nVal &= ~PLL_OUTCTRL; + writel(nVal, pll_mode_addr); + + /* Put the PLL in warm-up mode */ + nVal |= PLL_RESET_N; + nVal |= PLL_BYPASSNL; + writel(nVal, pll_mode_addr); + + /* Wait for the PLL warm-up time */ + udelay(50); + + /* Put the PLL in active mode */ + nVal |= PLL_RESET_N; + nVal |= PLL_BYPASSNL; + nVal |= PLL_OUTCTRL; + writel(nVal, pll_mode_addr); +} + +void pll_request(unsigned pll, unsigned enable) +{ + if (!enable) { + /* Disable not supported */ + return; + } + switch (pll) { + case 2: + pll_enable((void *)PLL2_MODE_ADDR); + return; + case 4: + pll_enable((void *)PLL4_MODE_ADDR); + return; + default: + return; + }; +} + +void acpu_clock_init(void) +{ + uint32_t i; + uint32_t val; + uint32_t size; + + /* Increase VDD level to the final value. */ + writel((1 << 7) | (VDD_LEVEL << 3), VDD_SVS_PLEVEL_ADDR); + + udelay(1000); + const uint32_t *clk_cntl_reg_val = clk_cntl_reg_val_7627A; + size = ARRAY_SIZE(clk_cntl_reg_val_7627A); + pll_request(2, 1); + /* Read clock source select bit. */ + val = readl(A11S_CLK_SEL_ADDR); + i = val & 1; + + /* Jump into table and set every entry. */ + for (; i < size; i++) { + + val = readl(A11S_CLK_CNTL_ADDR); + + /* Make sure not to disturb already used src */ + val &= clk_cntl_mask[i%2]; + val += clk_cntl_reg_val[i]; + writel(val, A11S_CLK_CNTL_ADDR); + + /* Would need a dmb() here but the whole address space is + * strongly ordered, so it should be fine. + */ + val = readl(A11S_CLK_SEL_ADDR); + val &= ~(A11S_CLK_SEL_MASK); + val |= (A11S_CLK_SEL_MASK & clk_sel_reg_val[i%2]); + writel(val, A11S_CLK_SEL_ADDR); + udelay(1000); + } +} + +#ifdef CONFIG_QC_MMC +/* Configure MMC clock */ +void clock_config_mmc(uint32_t interface, uint32_t freq) +{ + uint32_t reg = 0; + if (mmc_clock_set_rate(sdc_clk[interface], freq) < 0) + printf("Failure setting clock rate for MCLK-" + "clk_rate : %d\n", freq); + + /* enable clock */ + if (mmc_clock_enable_disable(sdc_clk[interface], MMC_CLK_ENABLE) < 0) + printf("Failure enabling MMC Clock!\n"); + + reg |= MMC_BOOT_MCI_CLK_ENABLE; + reg |= MMC_BOOT_MCI_CLK_ENA_FLOW; + reg |= MMC_BOOT_MCI_CLK_IN_FEEDBACK; + writel(reg, MMC_BOOT_MCI_CLK); +} + +/* Intialize MMC clock */ +void clock_init_mmc(uint32_t interface) +{ + if (mmc_clock_enable_disable(sdc_pclk[interface], MMC_CLK_ENABLE) < 0) + printf("Failure enabling PCLK!\n"); +} +#endif + diff --git a/arch/arm/cpu/armv7/msm7x27a/board.c b/arch/arm/cpu/armv7/msm7x27a/board.c new file mode 100644 index 0000000..46fc2ea --- /dev/null +++ b/arch/arm/cpu/armv7/msm7x27a/board.c @@ -0,0 +1,66 @@ +/* + * (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 <common.h> +#include <asm/io.h> +#include <asm/types.h> +#include <asm/arch/iomap.h> +#include <asm/arch/sys_proto.h> + + +DECLARE_GLOBAL_DATA_PTR; + + +void set_vector_base(unsigned long addr) +{ + __asm__ volatile ("mcr p15, 0, %0, c12, c0, 0" : : "r" (addr)); +} + +int dram_init(void) +{ + /*TODO: Memory size will change for booting kernel*/ + gd->ram_size = 0x00100000; + return 0; +} + +void dram_init_banksize(void) +{ + /* TODO: Memory layout will change for booting kernel + * This is intial bring up setup + */ + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; + +} +#ifdef CONFIG_DISPLAY_BOARDINFO +int checkboard(void) +{ + printf("Board: %s\n", sysinfo.board_string); + return 0; +} +#endif /* CONFIG_DISPLAY_BOARDINFO */ + +#ifdef CONFIG_ARCH_CPU_INIT +int arch_cpu_init() +{ + __cpu_early_init(); + return 0; +} +#endif diff --git a/arch/arm/cpu/armv7/msm7x27a/config.mk b/arch/arm/cpu/armv7/msm7x27a/config.mk new file mode 100644 index 0000000..f350c2b --- /dev/null +++ b/arch/arm/cpu/armv7/msm7x27a/config.mk @@ -0,0 +1,21 @@ +# +# (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 +# +# + +PLATFORM_CPPFLAGS += -march=armv7-a diff --git a/arch/arm/cpu/armv7/msm7x27a/gpio.c b/arch/arm/cpu/armv7/msm7x27a/gpio.c new file mode 100644 index 0000000..f5975e3 --- /dev/null +++ b/arch/arm/cpu/armv7/msm7x27a/gpio.c @@ -0,0 +1,287 @@ +/* + * (C) Copyright 2012 + * Larsen & Toubro Infotech Ltd. <www.lntinfotech.com> + * + * This source code is dual-licensed. You may use it under the terms of the + * GNU General Public License version 2, or under the license below. + * + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <common.h> +#include <asm/io.h> +#include <asm/arch/iomap.h> +#include <asm/arch/gpio.h> +#include <asm/arch/proc_comm.h> + +#define GPIO1_REG(off) (MSM_GPIO1_BASE + 0x800 + (off)) +#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0xC00 + (off)) + +/* output value */ +#define GPIO_OUT_0 GPIO1_REG(0x00) /* gpio 15-0 */ +#define GPIO_OUT_1 GPIO2_REG(0x00) /* gpio 42-16 */ +#define GPIO_OUT_2 GPIO1_REG(0x04) /* gpio 67-43 */ +#define GPIO_OUT_3 GPIO1_REG(0x08) /* gpio 94-68 */ +#define GPIO_OUT_4 GPIO1_REG(0x0C) /* gpio 106-95 */ +#define GPIO_OUT_5 GPIO1_REG(0x50) /* gpio 132-107 */ + +/* same pin map as above, output enable */ +#define GPIO_OE_0 GPIO1_REG(0x10) +#define GPIO_OE_1 GPIO2_REG(0x08) +#define GPIO_OE_2 GPIO1_REG(0x14) +#define GPIO_OE_3 GPIO1_REG(0x18) +#define GPIO_OE_4 GPIO1_REG(0x1C) +#define GPIO_OE_5 GPIO1_REG(0x54) + +/* same pin map as above, input read */ +#define GPIO_IN_0 GPIO1_REG(0x34) +#define GPIO_IN_1 GPIO2_REG(0x20) +#define GPIO_IN_2 GPIO1_REG(0x38) +#define GPIO_IN_3 GPIO1_REG(0x3C) +#define GPIO_IN_4 GPIO1_REG(0x40) +#define GPIO_IN_5 GPIO1_REG(0x44) + +/* same pin map as above, 1=edge 0=level interrup */ +#define GPIO_INT_EDGE_0 GPIO1_REG(0x60) +#define GPIO_INT_EDGE_1 GPIO2_REG(0x50) +#define GPIO_INT_EDGE_2 GPIO1_REG(0x64) +#define GPIO_INT_EDGE_3 GPIO1_REG(0x68) +#define GPIO_INT_EDGE_4 GPIO1_REG(0x6C) +#define GPIO_INT_EDGE_5 GPIO1_REG(0xC0) + +/* same pin map as above, 1=positive 0=negative */ +#define GPIO_INT_POS_0 GPIO1_REG(0x70) +#define GPIO_INT_POS_1 GPIO2_REG(0x58) +#define GPIO_INT_POS_2 GPIO1_REG(0x74) +#define GPIO_INT_POS_3 GPIO1_REG(0x78) +#define GPIO_INT_POS_4 GPIO1_REG(0x7C) +#define GPIO_INT_POS_5 GPIO1_REG(0xBC) + +/* same pin map as above, interrupt enable */ +#define GPIO_INT_EN_0 GPIO1_REG(0x80) +#define GPIO_INT_EN_1 GPIO2_REG(0x60) +#define GPIO_INT_EN_2 GPIO1_REG(0x84) +#define GPIO_INT_EN_3 GPIO1_REG(0x88) +#define GPIO_INT_EN_4 GPIO1_REG(0x8C) +#define GPIO_INT_EN_5 GPIO1_REG(0xB8) + +/* same pin map as above, write 1 to clear interrupt */ +#define GPIO_INT_CLEAR_0 GPIO1_REG(0x90) +#define GPIO_INT_CLEAR_1 GPIO2_REG(0x68) +#define GPIO_INT_CLEAR_2 GPIO1_REG(0x94) +#define GPIO_INT_CLEAR_3 GPIO1_REG(0x98) +#define GPIO_INT_CLEAR_4 GPIO1_REG(0x9C) +#define GPIO_INT_CLEAR_5 GPIO1_REG(0xB4) + +/* same pin map as above, 1=interrupt pending */ +#define GPIO_INT_STATUS_0 GPIO1_REG(0xA0) +#define GPIO_INT_STATUS_1 GPIO2_REG(0x70) +#define GPIO_INT_STATUS_2 GPIO1_REG(0xA4) +#define GPIO_INT_STATUS_3 GPIO1_REG(0xA8) +#define GPIO_INT_STATUS_4 GPIO1_REG(0xAC) +#define GPIO_INT_STATUS_5 GPIO1_REG(0xB0) + +typedef struct gpioregs gpioregs; + +struct gpioregs { + unsigned out; + unsigned in; + unsigned int_status; + unsigned int_clear; + unsigned int_en; + unsigned int_edge; + unsigned int_pos; + unsigned oe; +}; + +static gpioregs GPIO_REGS[] = { + { + .out = GPIO_OUT_0, + .in = GPIO_IN_0, + .int_status = GPIO_INT_STATUS_0, + .int_clear = GPIO_INT_CLEAR_0, + .int_en = GPIO_INT_EN_0, + .int_edge = GPIO_INT_EDGE_0, + .int_pos = GPIO_INT_POS_0, + .oe = GPIO_OE_0, + }, + { + .out = GPIO_OUT_1, + .in = GPIO_IN_1, + .int_status = GPIO_INT_STATUS_1, + .int_clear = GPIO_INT_CLEAR_1, + .int_en = GPIO_INT_EN_1, + .int_edge = GPIO_INT_EDGE_1, + .int_pos = GPIO_INT_POS_1, + .oe = GPIO_OE_1, + }, + { + .out = GPIO_OUT_2, + .in = GPIO_IN_2, + .int_status = GPIO_INT_STATUS_2, + .int_clear = GPIO_INT_CLEAR_2, + .int_en = GPIO_INT_EN_2, + .int_edge = GPIO_INT_EDGE_2, + .int_pos = GPIO_INT_POS_2, + .oe = GPIO_OE_2, + }, + { + .out = GPIO_OUT_3, + .in = GPIO_IN_3, + .int_status = GPIO_INT_STATUS_3, + .int_clear = GPIO_INT_CLEAR_3, + .int_en = GPIO_INT_EN_3, + .int_edge = GPIO_INT_EDGE_3, + .int_pos = GPIO_INT_POS_3, + .oe = GPIO_OE_3, + }, + { + .out = GPIO_OUT_4, + .in = GPIO_IN_4, + .int_status = GPIO_INT_STATUS_4, + .int_clear = GPIO_INT_CLEAR_4, + .int_en = GPIO_INT_EN_4, + .int_edge = GPIO_INT_EDGE_4, + .int_pos = GPIO_INT_POS_4, + .oe = GPIO_OE_4, + }, + { + .out = GPIO_OUT_5, + .in = GPIO_IN_5, + .int_status = GPIO_INT_STATUS_5, + .int_clear = GPIO_INT_CLEAR_5, + .int_en = GPIO_INT_EN_5, + .int_edge = GPIO_INT_EDGE_5, + .int_pos = GPIO_INT_POS_5, + .oe = GPIO_OE_5, + }, +}; + +static gpioregs *find_gpio(unsigned n, unsigned *bit) +{ + if (n > 132) + return 0; + if (n > 106) { + *bit = 1 << (n - 107); + return GPIO_REGS + 5; + } + if (n > 94) { + *bit = 1 << (n - 95); + return GPIO_REGS + 4; + } + if (n > 67) { + *bit = 1 << (n - 68); + return GPIO_REGS + 3; + } + if (n > 42) { + *bit = 1 << (n - 43); + return GPIO_REGS + 2; + } + if (n > 15) { + *bit = 1 << (n - 16); + return GPIO_REGS + 1; + } + *bit = 1 << n; + return GPIO_REGS + 0; +} + +int gpio_config(unsigned n, unsigned flags) +{ + gpioregs *r; + unsigned b; + unsigned v; + r = find_gpio(n, &b); + if (!r) + return -1; + + v = readl(r->oe); + if (flags & GPIO_OUTPUT) + writel(v | b, r->oe); + else + writel(v & (~b), r->oe); + return 0; +} + +void gpio_set(unsigned n, unsigned on) +{ + gpioregs *r; + unsigned b; + unsigned v; + + r = find_gpio(n, &b); + if (r == 0) + return; + + v = readl(r->out); + if (on) + writel(v | b, r->out); + else + writel(v & (~b), r->out); + +} + +int gpio_get(unsigned n) +{ + gpioregs *r; + unsigned b; + r = find_gpio(n, &b); + if (r == 0) + return 0; + return (readl(r->in) & b) ? 1 : 0; +} + +#if 0 +void platform_config_interleaved_mode_gpios(void) +{ + /* configure EB2_CS1 through GPIO86 */ + writel(GPIO_ALT_FUNC_PAGE_REG, 0x56); + writel(GPIO_ALT_FUNC_CFG_REG, 0x04); + /* configure the EBI2_BUSY1_N through GPIO115 */ + writel(GPIO_ALT_FUNC_PAGE_REG, 0x73); + writel(GPIO_ALT_FUNC_CFG_REG, 0x08); +} + +/* Enables all gpios passed in table*/ +int platform_gpios_enable(const struct msm_gpio *table, int size) +{ + int rc; + int i; + const struct msm_gpio *g; + for (i = 0; i < size; i++) { + g = table + i; + /* Enable gpio */ + rc = gpio_tlmm_config(g->gpio_cfg, GPIO_ENABLE); + if (rc) + goto err; + } + return 0; +err: + return rc; +} +#endif + + diff --git a/arch/arm/cpu/armv7/msm7x27a/lowlevel_init.S b/arch/arm/cpu/armv7/msm7x27a/lowlevel_init.S new file mode 100644 index 0000000..e6c4ac1 --- /dev/null +++ b/arch/arm/cpu/armv7/msm7x27a/lowlevel_init.S @@ -0,0 +1,118 @@ +/* + * (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 <config.h> +#include <version.h> + +.text +.code 32 + +#define DSB .byte 0x4f, 0xf0, 0x7f, 0xf5 +#define ISB .byte 0x6f, 0xf0, 0x7f, 0xf5 + + + + +_TEXT_BASE: + .word CONFIG_SYS_TEXT_BASE @ sdram load addr from config file + +.global invalidate_dcache +invalidate_dcache: + mov pc, lr + + .align 5 +.globl lowlevel_init +lowlevel_init: + mov pc, lr @ back to arch calling code + +.global reset_cpu +reset_cpu: +_loop_forever: + b _loop_forever + + + +.globl __cpu_early_init +__cpu_early_init: + + //; Zero out r0 for use throughout this code. All other GPRs + //; (r1-r3) are set throughout this code to help establish + //; a consistent startup state for any code that follows. + //; Users should add code at the end of this routine to establish + //; their own stack address (r13), add translation page tables, enable + //; the caches, etc. + push {r5-r12,r14} + mov r0, #0x0 + //; Initialize ASID to zero + mcr p15, 0, r0, c13, c0, 1 //; WCP15_CONTEXTIDR r0 + + //; ICIALL to invalidate entire I-Cache + mcr p15, 0, r0, c7, c5, 0 //; ICIALLU + + //; Initialize ADFSR to zero + mcr p15, 0, r0, c5, c1, 0 //; ADFSR r0 + + //; Ensure the MCR's above have completed their operation before + //; continuing + DSB + ISB + + //;------------------------------------------------------------------- + //; There are a number of registers that must be set prior to enabling + //; the MMU. The DCAR is one of these registers. We are setting + //; it to zero (no access) to easily detect improper setup in subsequent + //; code sequences + //;------------------------------------------------------------------- + //; Setup DACR (Domain Access Control Register) to zero + mcr p15, 0, r0, c3, c0, 0 //; WCP15_DACR r0 + + //;Make sure TLBLKCR is complete before continuing + ISB + + //; Invalidate the UTLB + mcr p15, 0, r0, c8, c7, 0 //; UTLBIALL + + //; Make sure UTLB request has been presented to macro before continuing + ISB + +SYSI2: + //; Enable Z bit to enable branch prediction (default is off) + mrc p15, 0, r2, c1, c0, 0 //; RCP15_SCTLR r2 + orr r2, r2, #0x00000800 + mcr p15, 0, r2, c1, c0, 0 //; WCP15_SCTLR r2 + + //; Make sure Link stack is initialized with branch and links to + //; sequential addresses + //; This aids in creating a predictable startup environment + bl SEQ1 +SEQ1: bl SEQ2 +SEQ2: bl SEQ3 +SEQ3: bl SEQ4 +SEQ4: bl SEQ5 +SEQ5: bl SEQ6 +SEQ6: bl SEQ7 +SEQ7: bl SEQ8 +SEQ8: + + ISB + pop {r5-r12,pc} + + +.ltorg diff --git a/arch/arm/cpu/armv7/msm7x27a/timer.c b/arch/arm/cpu/armv7/msm7x27a/timer.c new file mode 100644 index 0000000..0eb4ece --- /dev/null +++ b/arch/arm/cpu/armv7/msm7x27a/timer.c @@ -0,0 +1,127 @@ +/* + * (C) Copyright 2012 + * Larsen & Toubro Infotech Ltd. <www.lntinfotech.com> + * + * (C) Copyright 2010,2011 + * NVIDIA Corporation <www.nvidia.com> + * + * (C) Copyright 2008 + * Texas Instruments + * + * Richard Woodruff r-woodruff2@ti.com + * Syed Moahmmed Khasim khasim@ti.com + * + * (C) Copyright 2002 + * Sysgo Real-Time Solutions, GmbH <www.elinos.com> + * Marius Groeger mgroeger@sysgo.de + * Alex Zuepke azu@sysgo.de + * + * (C) Copyright 2002 + * Gary Jennejohn, DENX Software Engineering, garyj@denx.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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 <asm/arch/iomap.h> +#include <asm/io.h> +#include <common.h> +#include <asm/types.h> +#define TIMER_LOAD_VAL 0x21 + +#define GPT_ENABLE_CLR_ON_MATCH_EN 2 +#define GPT_ENABLE_EN 1 +#define DGT_ENABLE_CLR_ON_MATCH_EN 2 +#define DGT_ENABLE_EN 1 + +#define SPSS_TIMER_STATUS_DGT_EN (1 << 0) + + +#define READ_TIMER readl(GPT_COUNT_VAL) + +static ulong timestamp; +static ulong lastinc; +#define DGT_HZ 6750000 /* Uses LPXO/4 (27.0 MHz / 4) */ + +/* nothing really to do with interrupts, just starts up a counter. */ +int timer_init(void) +{ + writel(0, DGT_ENABLE); + return 0; +} +/* timer without interrupts */ +ulong get_timer(ulong base) +{ + return get_timer_masked() - base; +} + +/* delay x useconds */ +void __udelay(unsigned long usec) +{ + unsigned int val; + usec = (usec * 33 + 1000 - 33) / 1000; + + writel(0, GPT_CLEAR); + writel(0, GPT_ENABLE); + do { + val = 0; + val = readl(GPT_COUNT_VAL); + } while (val != 0); + + writel(GPT_ENABLE_EN, GPT_ENABLE); + do { + val = 0; + val = readl(GPT_COUNT_VAL); + } while (val < usec) ; + + writel(0, GPT_ENABLE); + writel(0, GPT_CLEAR); +} + +ulong get_timer_masked(void) +{ + ulong now = READ_TIMER; /* current tick value */ + + if (lastinc <= now) { /* normal mode (non roll) */ + /* normal mode */ + timestamp += now - lastinc; + /* move stamp forward with absolute diff ticks */ + } else { /* we have overflow of the count down timer */ + timestamp += now + (TIMER_LOAD_VAL - lastinc); + } + lastinc = now; + + return timestamp; +} + +/* + * This function is derived from PowerPC code (read timebase as long long). + * On ARM it just returns the timer value. + */ +unsigned long long get_ticks(void) +{ + return get_timer(0); +} + +/* + * This function is derived from PowerPC code (timebase clock frequency). + * On ARM it returns the number of timer ticks per second. + */ +ulong get_tbclk(void) +{ + return CONFIG_SYS_HZ; +} diff --git a/arch/arm/include/asm/arch-msm7x27a/gpio.h b/arch/arm/include/asm/arch-msm7x27a/gpio.h new file mode 100644 index 0000000..ca8c4af --- /dev/null +++ b/arch/arm/include/asm/arch-msm7x27a/gpio.h @@ -0,0 +1,47 @@ +/* + * (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 __GPIO_H +#define __GPIO_H + +#ifndef GPIO_INPUT +#define GPIO_INPUT 0x0000 +#endif +#ifndef GPIO_OUTPUT +#define GPIO_OUTPUT 0x0001 +#endif + +#define GPIO_LEVEL 0x0000 +#define GPIO_EDGE 0x0010 + +#define GPIO_RISING 0x0020 +#define GPIO_FALLING 0x0040 + +#define GPIO_HIGH 0x0020 +#define GPIO_LOW 0x0040 + +#define GPIO_PULLUP 0x0100 +#define GPIO_PULLDOWN 0x0200 + +int gpio_config(unsigned nr, unsigned flags); +void gpio_set(unsigned nr, unsigned on); +int gpio_get(unsigned nr); + +#endif diff --git a/arch/arm/include/asm/arch-msm7x27a/iomap.h b/arch/arm/include/asm/arch-msm7x27a/iomap.h new file mode 100644 index 0000000..4c9d434 --- /dev/null +++ b/arch/arm/include/asm/arch-msm7x27a/iomap.h @@ -0,0 +1,105 @@ +/* + * (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 _PLATFORM_MSM7627A_IOMAP_H_ +#define _PLATFORM_MSM7627A_IOMAP_H_ + +#define MSM_GPIO1_BASE 0xA9200000 +#define MSM_GPIO2_BASE 0xA9300000 + +#define MSM_UART1_BASE 0xA9A00000 +#define MSM_UART2_BASE 0xA9B00000 +#define MSM_UART3_BASE 0xA9C00000 + +#define MSM_VIC_BASE 0xC0000000 +#define MSM_GPT_BASE 0xC0100000 + +#define GPT_REG(off) (MSM_GPT_BASE + (off)) + +#define GPT_MATCH_VAL GPT_REG(0x0000) +#define GPT_COUNT_VAL GPT_REG(0x0004) +#define GPT_ENABLE GPT_REG(0x0008) +#define GPT_CLEAR GPT_REG(0x000C) +#define DGT_MATCH_VAL GPT_REG(0x0010) +#define DGT_COUNT_VAL GPT_REG(0x0014) +#define DGT_ENABLE GPT_REG(0x0018) +#define DGT_CLEAR GPT_REG(0x001C) +#define SPSS_TIMER_STATUS GPT_REG(0x0034) + +#define MSM_CSR_BASE 0xC0100000 +#define MSM_CLK_CTL_BASE 0xA8600000 + +#define MSM_SHARED_BASE 0x00100000 + +#define MSM_SDC1_BASE 0xA0400000 +#define MSM_SDC3_BASE 0xA0600000 + +#define MIPI_DSI_BASE (0xA1100000) +#define DSI_PHY_SW_RESET (0xA1100128) +#define REG_DSI(off) (MIPI_DSI_BASE + (off)) +#define MDP_BASE (0xAA200000) +#define REG_MDP(off) (MDP_BASE + (off)) +#define DSIPHY_REGULATOR_BASE (0x2CC) +#define DSIPHY_TIMING_BASE (0x260) +#define DSIPHY_CTRL_BASE (0x290) +#define DSIPHY_PLL_BASE (0x200) +#define DSIPHY_STRENGTH_BASE (0x2A0) + +/* Range 0 - 4 */ +#define DSIPHY_REGULATOR_CTRL(x) REG_DSI(DSIPHY_REGULATOR_BASE + (x) * 4) +/* Range 0 - 11 */ +#define DSIPHY_TIMING_CTRL(x) REG_DSI(DSIPHY_TIMING_BASE + (x) * 4) +/* Range 0 - 3 */ +#define DSIPHY_CTRL(x) REG_DSI(DSIPHY_CTRL_BASE + (x) * 4) +/* Range 0 - 2 */ +#define DSIPHY_STRENGTH_CTRL(x) REG_DSI(DSIPHY_STRENGTH_BASE + (x) * 4) +/* Range 0 - 19 */ +#define DSIPHY_PLL_CTRL(x) REG_DSI(DSIPHY_PLL_BASE + (x) * 4) + +#define MDP_DMA_P_CONFIG (0xAA290000) +#define MDP_DMA_P_OUT_XY (0xAA290010) +#define MDP_DMA_P_SIZE (0xAA290004) +#define MDP_DMA_P_BUF_ADDR (0xAA290008) +#define MDP_DMA_P_BUF_Y_STRIDE (0xAA29000C) + +#define MDP_DSI_VIDEO_EN (0xAA2F0000) +#define MDP_DSI_VIDEO_HSYNC_CTL (0xAA2F0004) +#define MDP_DSI_VIDEO_VSYNC_PERIOD (0xAA2F0008) +#define MDP_DSI_VIDEO_VSYNC_PULSE_WIDTH (0xAA2F000C) +#define MDP_DSI_VIDEO_DISPLAY_HCTL (0xAA2F0010) +#define MDP_DSI_VIDEO_DISPLAY_V_START (0xAA2F0014) +#define MDP_DSI_VIDEO_DISPLAY_V_END (0xAA2F0018) +#define MDP_DSI_VIDEO_BORDER_CLR (0xAA2F0028) +#define MDP_DSI_VIDEO_HSYNC_SKEW (0xAA2F0030) +#define MDP_DSI_VIDEO_CTL_POLARITY (0xAA2F0038) +#define MDP_DSI_VIDEO_TEST_CTL (0xAA2F0034) + +#define MDP_DMA_P_START REG_MDP(0x0000C) +#define MDP_DMA_S_START REG_MDP(0x00010) +#define MDP_DISP_INTF_SEL REG_MDP(0x00038) +#define MDP_MAX_RD_PENDING_CMD_CONFIG REG_MDP(0x0004C) +#define MDP_INTR_ENABLE REG_MDP(0x00020) +#define MDP_INTR_CLEAR REG_MDP(0x00028) +#define MDP_DSI_CMD_MODE_ID_MAP REG_MDP(0x000A0) +#define MDP_DSI_CMD_MODE_TRIGGER_EN REG_MDP(0x000A4) + +#define MDP_TEST_MODE_CLK REG_MDP(0xF0000) +#define MDP_INTR_STATUS REG_MDP(0x00054) +#endif diff --git a/arch/arm/include/asm/arch-msm7x27a/mmc.h b/arch/arm/include/asm/arch-msm7x27a/mmc.h new file mode 100644 index 0000000..15a8cd4 --- /dev/null +++ b/arch/arm/include/asm/arch-msm7x27a/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/arch/arm/include/asm/arch-msm7x27a/proc_comm.h b/arch/arm/include/asm/arch-msm7x27a/proc_comm.h new file mode 100644 index 0000000..e919794 --- /dev/null +++ b/arch/arm/include/asm/arch-msm7x27a/proc_comm.h @@ -0,0 +1,42 @@ +/* + * (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 __PROC_COMM_H_ +#define __PROC_COMM_H_ + +void usb_clock_init(void); +void lcdc_clock_init(unsigned rate); +void mdp_clock_init(unsigned rate); +void uart3_clock_init(void); +void uart2_clock_init(void); +void uart1_clock_init(void); +void mddi_clock_init(unsigned num, unsigned rate); +void reboot(unsigned reboot_reason); +int mmc_clock_enable_disable(unsigned id, unsigned enable); +int mmc_clock_set_rate(unsigned id, unsigned rate); +int mmc_clock_get_rate(unsigned id); +int gpio_tlmm_config(unsigned config, unsigned disable); +int vreg_set_level(unsigned id, unsigned mv); +int vreg_enable(unsigned id); +int vreg_disable(unsigned id); + +#endif + + diff --git a/arch/arm/include/asm/arch-msm7x27a/sys_proto.h b/arch/arm/include/asm/arch-msm7x27a/sys_proto.h new file mode 100644 index 0000000..d5d5125 --- /dev/null +++ b/arch/arm/include/asm/arch-msm7x27a/sys_proto.h @@ -0,0 +1,27 @@ +/* + * (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 _SYS_PROTO_H_ +#define _SYS_PROTO_H_ +void pll8_enable(void); +void clock_init(void); +void __cpu_early_init(void); +#endif +

Signed-off-by: Srikanth Reddy Vintha srikanth.reddy@lntinfotech.com --- board/qcom/msm7x27a_surf/Makefile | 56 +++++++++++++ board/qcom/msm7x27a_surf/msm7x27a_surf.c | 126 +++++++++++++++++++++++++++++ board/qcom/msm7x27a_surf/msm7x27a_surf.h | 27 ++++++ boards.cfg | 1 + include/configs/msm7x27a_surf.h | 128 ++++++++++++++++++++++++++++++ 5 files changed, 338 insertions(+), 0 deletions(-) create mode 100644 board/qcom/msm7x27a_surf/Makefile create mode 100644 board/qcom/msm7x27a_surf/msm7x27a_surf.c create mode 100644 board/qcom/msm7x27a_surf/msm7x27a_surf.h create mode 100644 include/configs/msm7x27a_surf.h
diff --git a/board/qcom/msm7x27a_surf/Makefile b/board/qcom/msm7x27a_surf/Makefile new file mode 100644 index 0000000..123099d --- /dev/null +++ b/board/qcom/msm7x27a_surf/Makefile @@ -0,0 +1,56 @@ +# +# (C) Copyright 2012 +# Larsen & Toubro Infotech Ltd. <www.lntinfotech.com> +# +# (C) Copyright 2010,2011 +# NVIDIA Corporation <www.nvidia.com> +# +# +# See file CREDITS for list of people who contributed to this +# project. +# +# 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 $(TOPDIR)/config.mk + +ifneq ($(OBJTREE),$(SRCTREE)) +$(shell mkdir -p $(obj)../../qcom/msm7x27a_surf/) +endif + +LIB = $(obj)lib$(BOARD).o + +COBJS := $(BOARD).o +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +$(LIB): $(obj).depend $(OBJS) + $(call cmd_link_o_target, $(OBJS)) + +clean: + rm -f $(OBJS) + +distclean: + rm -f $(LIB) core *.bak $(obj).depend + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/board/qcom/msm7x27a_surf/msm7x27a_surf.c b/board/qcom/msm7x27a_surf/msm7x27a_surf.c new file mode 100644 index 0000000..9199f48 --- /dev/null +++ b/board/qcom/msm7x27a_surf/msm7x27a_surf.c @@ -0,0 +1,126 @@ +/* + * (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 <common.h> +#include <asm/arch/iomap.h> +#include <asm/arch/sys_proto.h> +#include <asm/io.h> +#include <malloc.h> +#include <asm/arch/mmc.h> +#include <linux/string.h> +#include <asm/mach-types.h> +#include <asm/arch/proc_comm.h> +#include "msm7x27a_surf.h" + +DECLARE_GLOBAL_DATA_PTR; + +#ifdef CONFIG_BOARD_EARLY_INIT_F +int board_early_init_f() +{ + uart1_clock_init(); + return 0; +} +#endif +int board_init() +{ + unsigned long new_addr; + unsigned long offset; + offset = gd->relocaddr - CONFIG_SYS_TEXT_BASE; + new_addr = CONFIG_SYS_TEXT_BASE + offset; + set_vector_base(new_addr); + acpu_clock_init(); + bd_t *bd = gd->bd; + bd->bi_arch_number = MACH_TYPE_MSM7X27_SURF; + return 0; +} + +#ifdef CONFIG_QC_MMC + +/* called during the scan of each mmc device */ +int qc_board_mmc_init(struct mmc *mmc) +{ + + struct mmc_priv *sd = (struct mmc_priv *)mmc->priv; + u32 smem_val; + do { + smem_val = 0; + smem_val = readl(MSM_SHARED_BASE + 0x14); + } while (smem_val != 1); + + if (sd->instance == 3 || sd->instance == 4) { + mmc_boot_main(mmc); + return 0; + } else + /* this board does not have an sd/mmc card on this interface. */ + return 1; + } +int board_mmc_init(bd_t *bis) +{ +#ifdef QC_SD + struct mmc *mmc_4; + struct mmc_priv *sdcc_4; + mmc_4 = (struct mmc *) malloc(sizeof(struct mmc)); + if (!mmc_4) + return 1; + sdcc_4 = (struct mmc_priv *) malloc(sizeof(struct mmc_priv)); + if (!sdcc_4) { + free(mmc_4); + return 1; + } + sdcc_4->instance = 4; + sdcc_4->base = MSM_SDC4_BASE; + mmc_4->priv = sdcc_4; + mmc_4->send_cmd = mmc_boot_send_command_map; + mmc_4->set_ios = mmc_boot_set_ios; + mmc_4->init = qc_board_mmc_init; + mmc_4->voltages = MMC_VDD_29_30|MMC_VDD_165_195; + mmc_4->host_caps = MMC_MODE_4BIT|MMC_MODE_HS; + mmc_4->f_min = MMC_CLK_400KHZ; + mmc_4->f_max = MMC_CLK_48MHZ; + sprintf(mmc_4->name, "External_Card"); + mmc_register(mmc_4); +#else + struct mmc *mmc_3; + struct mmc_priv *sdcc_3; + mmc_3 = (struct mmc *) malloc(sizeof(struct mmc)); + if (!mmc_3) + return 1; + sdcc_3 = (struct mmc_priv *) malloc(sizeof(struct mmc_priv)); + if (!sdcc_3) { + free(mmc_3); + return 1; + } + sdcc_3->instance = 3; + sdcc_3->base = MSM_SDC3_BASE; + mmc_3->priv = sdcc_3; + mmc_3->send_cmd = mmc_boot_send_command_map; + mmc_3->set_ios = mmc_boot_set_ios; + mmc_3->init = qc_board_mmc_init; + mmc_3->voltages = MMC_VDD_29_30|MMC_VDD_165_195; + mmc_3->host_caps = MMC_MODE_4BIT|MMC_MODE_HS|MMC_MODE_8BIT| + MMC_MODE_HS_52MHz|MMC_MODE_HC; + mmc_3->f_min = MMC_CLK_400KHZ; + mmc_3->f_max = MMC_CLK_48MHZ; + sprintf(mmc_3->name, "Internal_Card"); + mmc_register(mmc_3); +#endif + return 0; +} +#endif diff --git a/board/qcom/msm7x27a_surf/msm7x27a_surf.h b/board/qcom/msm7x27a_surf/msm7x27a_surf.h new file mode 100644 index 0000000..8bbe614 --- /dev/null +++ b/board/qcom/msm7x27a_surf/msm7x27a_surf.h @@ -0,0 +1,27 @@ +/* + * (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 __MSM7X27A_H_ +#define __MSM7X27A_H_ + +extern void set_vector_base(unsigned long); +extern void acpu_clock_init(void); +extern void uart1_clock_init(void); +#endif diff --git a/boards.cfg b/boards.cfg index 6fd8e34..318ba56 100644 --- a/boards.cfg +++ b/boards.cfg @@ -185,6 +185,7 @@ integratorcp_cm946es arm arm946es integrator armltd ca9x4_ct_vxp arm armv7 vexpress armltd am335x_evm arm armv7 am335x ti am33xx highbank arm armv7 highbank - highbank +msm7x27a_surf arm armv7 msm7x27a_surf qcom msm7x27a msm7630_surf arm armv7 msm7630_surf qcom msm7630 efikamx arm armv7 efikamx - mx5 efikamx:MACH_TYPE=MACH_TYPE_MX51_EFIKAMX,IMX_CONFIG=board/efikamx/imximage_mx.cfg efikasb arm armv7 efikamx - mx5 efikamx:MACH_TYPE=MACH_TYPE_MX51_EFIKASB,IMX_CONFIG=board/efikamx/imximage_sb.cfg diff --git a/include/configs/msm7x27a_surf.h b/include/configs/msm7x27a_surf.h new file mode 100644 index 0000000..a82ba59 --- /dev/null +++ b/include/configs/msm7x27a_surf.h @@ -0,0 +1,128 @@ +/* + * (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 __CONFIG_H +#define __CONFIG_H + +#include <asm/sizes.h> +#define PLATFORM_MSM7X27A 1 +#define CONFIG_MSM_UART +#define CONFIG_SYS_NO_FLASH +#define CONFIG_L2_OFF +#define CONFIG_SKIP_LOWLEVEL_INIT +/* Environment */ +#define CONFIG_ENV_IS_NOWHERE +#define CONFIG_ENV_SIZE 0x20000 /* Total Size Environment */ +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_MSM_PCOMM +#define CONFIG_ARCH_CPU_INIT +/* + * Size of malloc() pool + */ +#define CONFIG_SYS_MALLOC_LEN (2 * 1024) /* 2KB */ + +/* + * select serial console configuration + */ +#define CONFIG_CONS_INDEX 1 + +/* allow to overwrite serial and ethaddr */ +#define CONFIG_ENV_OVERWRITE +#define CONFIG_BAUDRATE 115200 +#define CONFIG_SYS_BAUDRATE_TABLE {4800, 9600, 19200, 38400, 57600,\ + 115200} + +#include <config_cmd_default.h> + +/* remove unused commands */ +#undef CONFIG_CMD_FLASH /* flinfo, erase, protect */ +#undef CONFIG_CMD_FPGA /* FPGA configuration support */ +#undef CONFIG_CMD_IMI +#undef CONFIG_CMD_IMLS +#undef CONFIG_CMD_NFS /* NFS support */ +#undef CONFIG_CMD_NET /* network support */ +#undef CONFIG_SYS_MAX_FLASH_SECT +#define CONFIG_EXTRA_ENV_SETTINGS \ + "console=ttyS0,115200n8\0" \ + +#define CONFIG_BOOTDELAY -1 + +/* + * Miscellaneous configurable options + */ +#define CONFIG_SYS_LONGHELP /* undef to save memory */ +#define CONFIG_SYS_HUSH_PARSER /* use "hush" command parser */ +#define CONFIG_SYS_PROMPT_HUSH_PS2 "> " +#define V_PROMPT "(MSM 7x27A) # " +#define CONFIG_SYS_PROMPT V_PROMPT +/* + * Increasing the size of the IO buffer as default nfsargs size is more + * than 256 and so it is not possible to edit it + */ +#define CONFIG_SYS_CBSIZE (256 * 2) /* Console I/O Buffer Size */ +/* Print Buffer Size */ +#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + \ + sizeof(CONFIG_SYS_PROMPT) + 16) +#define CONFIG_SYS_MAXARGS 16 /* max number of command args */ +/* Boot Argument Buffer Size */ +#define CONFIG_SYS_BARGSIZE (CONFIG_SYS_CBSIZE) + +#define CONFIG_SYS_HZ 1000 +#define CONFIG_SYS_LOAD_ADDR 0x00208000 +#define CONFIG_SYS_MEMTEST_START 0x08008000 +#define CONFIG_SYS_MEMTEST_END 0x08008001 + +#define CONFIG_DOS_PARTITION +#define CONFIG_MMC +#define CONFIG_CMD_MMC + +#define CONFIG_GENERIC_MMC +#define CONFIG_QC_MMC +/*--------------------------------------------------------------------- + * IRQ Settings + */ + +#define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */ +#define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */ + +/*----------------------------------------------------------------------- + * Physical Memory Map + */ + +#if 0 +#define CONFIG_BOOTDELAY 0 +#define CONFIG_BOOTCOMMAND "mmc part" +#endif +#define CONFIG_NR_DRAM_BANKS 1 + +#define PHYS_SDRAM_1 0x00000000 +#define PHYS_SDRAM_1_SIZE (1*1024*1024) /* 512M */ + +#define CONFIG_SYS_TEXT_BASE 0x00000000 +#define CONFIG_SYS_INIT_RAM_ADDR 0x00000000 +#define CONFIG_SYS_INIT_RAM_SIZE 0x00100000 + + +#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM_1 +#define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_INIT_RAM_ADDR + \ + CONFIG_SYS_INIT_RAM_SIZE - \ + GENERATED_GBL_DATA_SIZE) + +#endif

Signed-off-by: Srikanth Reddy Vintha srikanth.reddy@lntinfotech.com --- arch/arm/cpu/armv7/msm7x27a/acpuclock.c | 6 + arch/arm/include/asm/arch-msm7x27a/iomap.h | 1 + arch/arm/include/asm/arch-msm7x27a/irqs.h | 138 ++++++++++++++++++++++++++++ include/configs/msm7x27a_surf.h | 13 +-- 4 files changed, 151 insertions(+), 7 deletions(-) create mode 100644 arch/arm/include/asm/arch-msm7x27a/irqs.h
diff --git a/arch/arm/cpu/armv7/msm7x27a/acpuclock.c b/arch/arm/cpu/armv7/msm7x27a/acpuclock.c index c144233..7af80ef 100644 --- a/arch/arm/cpu/armv7/msm7x27a/acpuclock.c +++ b/arch/arm/cpu/armv7/msm7x27a/acpuclock.c @@ -222,6 +222,12 @@ void acpu_clock_init(void) udelay(1000); } } +void hsusb_clock_init(void) +{ + /* USB local clock control not enabled; use proc comm */ + usb_clock_init(); +} +
#ifdef CONFIG_QC_MMC /* Configure MMC clock */ diff --git a/arch/arm/include/asm/arch-msm7x27a/iomap.h b/arch/arm/include/asm/arch-msm7x27a/iomap.h index 4c9d434..bc875ff 100644 --- a/arch/arm/include/asm/arch-msm7x27a/iomap.h +++ b/arch/arm/include/asm/arch-msm7x27a/iomap.h @@ -48,6 +48,7 @@
#define MSM_SHARED_BASE 0x00100000
+#define MSM_USB_BASE 0xA0800000 #define MSM_SDC1_BASE 0xA0400000 #define MSM_SDC3_BASE 0xA0600000
diff --git a/arch/arm/include/asm/arch-msm7x27a/irqs.h b/arch/arm/include/asm/arch-msm7x27a/irqs.h new file mode 100644 index 0000000..798fd43 --- /dev/null +++ b/arch/arm/include/asm/arch-msm7x27a/irqs.h @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2008, Google Inc. + * All rights reserved. + * + * (C) Copyright 2012 + * Larsen & Toubro Infotech Ltd. <www.lntinfotech.com> + * + * This source code is dual-licensed. You may use it under the terms of the + * GNU General Public License version 2, or under the license below. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google, Inc. nor the names of its contributors + * may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _PLATFORM_MSM7K_IRQS_H_ +#define _PLATFORM_MSM7K_IRQS_H_ + +#define VIC_REG(off) (MSM_VIC_BASE + (off)) + +#define VIC_INT_SELECT0 VIC_REG(0x0000) /* 1: FIQ, 0: IRQ */ +#define VIC_INT_SELECT1 VIC_REG(0x0004) /* 1: FIQ, 0: IRQ */ +#define VIC_INT_EN0 VIC_REG(0x0010) +#define VIC_INT_EN1 VIC_REG(0x0014) +#define VIC_INT_ENCLEAR0 VIC_REG(0x0020) +#define VIC_INT_ENCLEAR1 VIC_REG(0x0024) +#define VIC_INT_ENSET0 VIC_REG(0x0030) +#define VIC_INT_ENSET1 VIC_REG(0x0034) +#define VIC_INT_TYPE0 VIC_REG(0x0040) /* 1: EDGE, 0: LEVEL */ +#define VIC_INT_TYPE1 VIC_REG(0x0044) /* 1: EDGE, 0: LEVEL */ +#define VIC_INT_POLARITY0 VIC_REG(0x0050) /* 1: NEG, 0: POS */ +#define VIC_INT_POLARITY1 VIC_REG(0x0054) /* 1: NEG, 0: POS */ +#define VIC_NO_PEND_VAL VIC_REG(0x0060) +#define VIC_INT_MASTEREN VIC_REG(0x0064) /* 1: IRQ, 2: FIQ */ +#define VIC_PROTECTION VIC_REG(0x006C) /* 1: ENABLE */ +#define VIC_CONFIG VIC_REG(0x0068) /* 1: USE ARM1136 VIC */ +#define VIC_IRQ_STATUS0 VIC_REG(0x0080) +#define VIC_IRQ_STATUS1 VIC_REG(0x0084) +#define VIC_FIQ_STATUS0 VIC_REG(0x0090) +#define VIC_FIQ_STATUS1 VIC_REG(0x0094) +#define VIC_RAW_STATUS0 VIC_REG(0x00A0) +#define VIC_RAW_STATUS1 VIC_REG(0x00A4) +#define VIC_INT_CLEAR0 VIC_REG(0x00B0) +#define VIC_INT_CLEAR1 VIC_REG(0x00B4) +#define VIC_SOFTINT0 VIC_REG(0x00C0) +#define VIC_SOFTINT1 VIC_REG(0x00C4) +#define VIC_IRQ_VEC_RD VIC_REG(0x00D0) /* pending int # */ +#define VIC_IRQ_VEC_PEND_RD VIC_REG(0x00D4) /* pending vector addr */ +#define VIC_IRQ_VEC_WR VIC_REG(0x00D8) +#define VIC_IRQ_IN_SERVICE VIC_REG(0x00E0) +#define VIC_IRQ_IN_STACK VIC_REG(0x00E4) +#define VIC_TEST_BUS_SEL VIC_REG(0x00E8) + + +#define INT_A9_M2A_0 0 +#define INT_A9_M2A_1 1 +#define INT_A9_M2A_2 2 +#define INT_A9_M2A_3 3 +#define INT_A9_M2A_4 4 +#define INT_A9_M2A_5 5 +#define INT_A9_M2A_6 6 +#define INT_GP_TIMER_EXP 7 +#define INT_DEBUG_TIMER_EXP 8 +#define INT_UART1 9 +#define INT_UART2 10 +#define INT_UART3 11 +#define INT_UART1_RX 12 +#define INT_UART2_RX 13 +#define INT_UART3_RX 14 +#define INT_USB_OTG 15 +#define INT_MDDI_PRI 16 +#define INT_MDDI_EXT 17 +#define INT_MDDI_CLIENT 18 +#define INT_MDP 19 +#define INT_GRAPHICS 20 +#define INT_ADM_AARM 21 +#define INT_ADSP_A11 22 +#define INT_ADSP_A9_A11 23 +#define INT_SDC1_0 24 +#define INT_SDC1_1 25 +#define INT_SDC2_0 26 +#define INT_SDC2_1 27 +#define INT_KEYSENSE 28 +#define INT_TCHSCRN_SSBI 29 +#define INT_TCHSCRN1 30 +#define INT_TCHSCRN2 31 + +#define INT_GPIO_GROUP1 (32 + 0) +#define INT_GPIO_GROUP2 (32 + 1) +#define INT_PWB_I2C (32 + 2) +#define INT_NAND_WR_ER_DONE (32 + 3) +#define INT_NAND_OP_DONE (32 + 4) +#define INT_SOFTRESET (32 + 5) +#define INT_PBUS_ARM11 (32 + 6) +#define INT_AXI_MPU_SMI (32 + 7) +#define INT_AXI_MPU_EBI1 (32 + 8) +#define INT_AD_HSSD (32 + 9) +#define INT_ARM11_PM (32 + 10) +#define INT_ARM11_DMA (32 + 11) +#define INT_TSIF_IRQ (32 + 12) +#define INT_UART1DM_IRQ (32 + 13) +#define INT_UART1DM_RX (32 + 14) +#define INT_USB_HS (32 + 15) +#define INT_SDC3_0 (32 + 16) +#define INT_SDC3_1 (32 + 17) +#define INT_SDC4_0 (32 + 18) +#define INT_SDC4_1 (32 + 19) +#define INT_UART2DM_RX (32 + 20) +#define INT_UART2DM_IRQ (32 + 21) + +#define MSM_IRQ_BIT(irq) (1 << ((irq) & 31)) + +#define NR_IRQS 54 + + +#endif diff --git a/include/configs/msm7x27a_surf.h b/include/configs/msm7x27a_surf.h index a82ba59..78d6252 100644 --- a/include/configs/msm7x27a_surf.h +++ b/include/configs/msm7x27a_surf.h @@ -38,6 +38,11 @@ */ #define CONFIG_SYS_MALLOC_LEN (2 * 1024) /* 2KB */
+/* Enable USB */ +#define CONFIG_MSM_UDC +#define CONFIG_USB_TTY +#define CONFIG_USB_DEVICE + /* * select serial console configuration */ @@ -60,8 +65,7 @@ #undef CONFIG_CMD_NET /* network support */ #undef CONFIG_SYS_MAX_FLASH_SECT #define CONFIG_EXTRA_ENV_SETTINGS \ - "console=ttyS0,115200n8\0" \ - + "usbtty=cdc_acm\0" #define CONFIG_BOOTDELAY -1
/* @@ -98,7 +102,6 @@ /*--------------------------------------------------------------------- * IRQ Settings */ - #define CONFIG_STACKSIZE_IRQ (4*1024) /* IRQ stack */ #define CONFIG_STACKSIZE_FIQ (4*1024) /* FIQ stack */
@@ -106,10 +109,6 @@ * Physical Memory Map */
-#if 0 -#define CONFIG_BOOTDELAY 0 -#define CONFIG_BOOTCOMMAND "mmc part" -#endif #define CONFIG_NR_DRAM_BANKS 1
#define PHYS_SDRAM_1 0x00000000

From: Shrinivas Sahukar shrinivas.sahukar@lntinfotech.com
Signed-off-by: Shrinivas Sahukar shrinivas.sahukar@lntinfotech.com --- drivers/mmc/qc_mmc.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 files changed, 68 insertions(+), 3 deletions(-)
diff --git a/drivers/mmc/qc_mmc.c b/drivers/mmc/qc_mmc.c index 930c410..9949cda 100644 --- a/drivers/mmc/qc_mmc.c +++ b/drivers/mmc/qc_mmc.c @@ -180,6 +180,65 @@ static unsigned int mmc_boot_fifo_read(unsigned int *mmc_ptr, return mmc_ret; }
+/* + * Write data to SDC FIFO. + */ +static unsigned int mmc_boot_fifo_write(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 write_error = MMC_BOOT_MCI_STAT_DATA_CRC_FAIL | + MMC_BOOT_MCI_STAT_DATA_TIMEOUT | MMC_BOOT_MCI_STAT_TX_UNDRUN; + 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); + + /* Write the transfer data to SDCC3 FIFO */ + do { + mmc_ret = MMC_BOOT_E_SUCCESS; + mmc_status = readl(reg_status); + if (mmc_status & write_error) { + mmc_ret = mmc_boot_status_error(mmc_status); + break; + } + /* Write the data in MCI_FIFO register as long as TXFIFO_FULL + bit of MCI_STATUS register is 0. Continue the writes until + the whole transfer data is written. */ + if (((data_len - mmc_count) >= MMC_BOOT_MCI_FIFO_SIZE / 2) && + (mmc_status & MMC_BOOT_MCI_STAT_TX_FIFO_HFULL)) { + unsigned write_count = 1; + write_count = MMC_BOOT_MCI_HFIFO_COUNT; + for (i = 0; i < write_count; i++) { + /* FIFO contains 16 32-bit data buffer + on 16 sequential addresses */ + writel(*mmc_ptr, reg_fifo + + (mmc_count % MMC_BOOT_MCI_FIFO_SIZE)); + mmc_ptr++; + /* increase mmc_count by word size */ + mmc_count += sizeof(unsigned int); + } + + } else if (!(mmc_status & MMC_BOOT_MCI_STAT_TX_FIFO_FULL) + && (mmc_count != data_len)) { + /* FIFO contains 16 32-bit data buffer + on 16 sequential addresses */ + writel(*mmc_ptr, reg_fifo + + (mmc_count % MMC_BOOT_MCI_FIFO_SIZE)); + mmc_ptr++; + /* increase mmc_count by word size */ + mmc_count += sizeof(unsigned int); + } 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, @@ -189,6 +248,8 @@ static unsigned int mmc_boot_fifo_data_transfer(unsigned int *data_ptr,
if (direction == MMC_BOOT_DATA_READ) mmc_ret = mmc_boot_fifo_read(data_ptr, data_len, mmc); + else + mmc_ret = mmc_boot_fifo_write(data_ptr, data_len, mmc);
return mmc_ret; } @@ -350,7 +411,7 @@ static unsigned int mmc_boot_send_command(struct mmc_cmd *cmd, break; }
- } while (1); + } while (1);
return mmc_return; } @@ -413,6 +474,7 @@ int mmc_boot_send_command_map(struct mmc *mmc, struct mmc_data *data) { unsigned int mmc_ret = MMC_BOOT_E_SUCCESS; + unsigned char direction = 0;
/* todo: do we need to fill in command type ?? */
@@ -434,6 +496,10 @@ int mmc_boot_send_command_map(struct mmc *mmc, mmc->read_bl_len = MMC_BOOT_RD_BLOCK_LEN; data->blocksize = MMC_BOOT_RD_BLOCK_LEN; } + direction = MMC_BOOT_DATA_READ; + } else if ((cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK) || + (cmd->cmdidx == MMC_CMD_WRITE_SINGLE_BLOCK)) { + direction = MMC_BOOT_DATA_WRITE; } else if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION) { /* explicitly disable the prg enabled flag */ cmd->flags &= ~MMC_BOOT_PROGRAM_ENABLED; @@ -441,7 +507,6 @@ int mmc_boot_send_command_map(struct mmc *mmc, cmd->flags |= MMC_BOOT_XFER_MODE_BLOCK; }
- /* For Data cmd's */ if (data != NULL) mmc_boot_init_data(mmc, cmd, data); @@ -460,7 +525,7 @@ int mmc_boot_send_command_map(struct mmc *mmc, return mmc_ret; mmc_boot_fifo_data_transfer((unsigned int *) data->dest, data->blocks * data->blocksize, - MMC_BOOT_DATA_READ, + direction, mmc); }

Please copy me on MMC patches.
On Mon, Aug 13, 2012 at 3:13 AM, Srikanth Reddy Vintha srikanth.reddy@lntinfotech.com wrote:
From: Shrinivas Sahukar shrinivas.sahukar@lntinfotech.com
Signed-off-by: Shrinivas Sahukar shrinivas.sahukar@lntinfotech.com
drivers/mmc/qc_mmc.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++--
This driver isn't in the tree, so NAK
Andy
participants (2)
-
Andy Fleming
-
Srikanth Reddy Vintha