Merge "platform: msm8974: Fix boot time stamp base address"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index f700033..74c0fb9 100755
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -1892,11 +1892,7 @@
|| !strcmp(ptn->name, "userdata")
|| !strcmp(ptn->name, "persist")
|| !strcmp(ptn->name, "recoveryfs")) {
- if (flash_ecc_bch_enabled())
- /* Spare data bytes for 8 bit ECC increased by 4 */
- extra = ((page_size >> 9) * 20);
- else
- extra = ((page_size >> 9) * 16);
+ extra = 1;
} else
sz = ROUND_TO_PAGE(sz, page_mask);
diff --git a/arch/arm/crt0.S b/arch/arm/crt0.S
index 7f1ad16..d58e234 100644
--- a/arch/arm/crt0.S
+++ b/arch/arm/crt0.S
@@ -50,8 +50,8 @@
/* new thumb behavior, low exception vectors, i/d cache disable, mmu disabled */
bic r0, r0, #(1<<15| 1<<13 | 1<<12)
bic r0, r0, #(1<<2 | 1<<0)
- /* enable alignment faults */
- orr r0, r0, #(1<<1)
+ /* disable alignment faults */
+ bic r0, r0, #(1<<1)
/* Write SCTLR */
mcr p15, 0, r0, c1, c0, 0
#ifdef ENABLE_TRUSTZONE
diff --git a/dev/gcdb/display/include/panel_hx8379a_wvga_video.h b/dev/gcdb/display/include/panel_hx8379a_wvga_video.h
index 6bcfc92..acda031 100644
--- a/dev/gcdb/display/include/panel_hx8379a_wvga_video.h
+++ b/dev/gcdb/display/include/panel_hx8379a_wvga_video.h
@@ -98,7 +98,7 @@
static char hx8379a_wvga_video_on_cmd4[] = {
0x20, 0x00, 0x39, 0xC0,
-0xB4, 0x82, 0x08, 0x00,
+0xB4, 0x80, 0x08, 0x00,
0x32, 0x10, 0x03, 0x32,
0x13, 0x70, 0x32, 0x10,
0x08, 0x37, 0x01, 0x28,
diff --git a/dev/gcdb/display/include/panel_ssd2080m_720p_video.h b/dev/gcdb/display/include/panel_ssd2080m_720p_video.h
index f8fc707..66c2b5a 100755
--- a/dev/gcdb/display/include/panel_ssd2080m_720p_video.h
+++ b/dev/gcdb/display/include/panel_ssd2080m_720p_video.h
@@ -54,7 +54,7 @@
/* Panel resolution */
/*---------------------------------------------------------------------------*/
static struct panel_resolution ssd2080m_720p_video_panel_res = {
- 720, 1280, 80, 30, 14, 0, 12, 16, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ 720, 1280, 80, 24, 14, 0, 12, 16, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*---------------------------------------------------------------------------*/
@@ -453,7 +453,7 @@
/*---------------------------------------------------------------------------*/
static struct videopanel_info ssd2080m_720p_video_video_panel = {
- 1, 0, 0, 0, 1, 0, 2, 0, 0x9
+ 1, 0, 0, 0, 1, 0, 2, 0, 0x8
};
/*---------------------------------------------------------------------------*/
diff --git a/include/dev/flash.h b/include/dev/flash.h
index 9fa10bc..6c2402d 100644
--- a/include/dev/flash.h
+++ b/include/dev/flash.h
@@ -68,7 +68,7 @@
int flash_erase(struct ptentry *ptn);
int flash_read_ext(struct ptentry *ptn, unsigned extra_per_page,
unsigned offset, void *data, unsigned bytes);
-int flash_write(struct ptentry *ptn, unsigned extra_per_page, const void *data,
+int flash_write(struct ptentry *ptn, unsigned write_extra_bytes, const void *data,
unsigned bytes);
static inline int flash_read(struct ptentry *ptn, unsigned offset, void *data,
diff --git a/include/endian.h b/include/endian.h
index 34bef6e..fe41a6c 100644
--- a/include/endian.h
+++ b/include/endian.h
@@ -49,6 +49,15 @@
#endif
// define a macro that unconditionally swaps
+#define SWAP_64(x) \
+ ((((x) & 0xff00000000000000ull) >> 56) \
+ | (((x) & 0x00ff000000000000ull) >> 40) \
+ | (((x) & 0x0000ff0000000000ull) >> 24) \
+ | (((x) & 0x000000ff00000000ull) >> 8) \
+ | (((x) & 0x00000000ff000000ull) << 8) \
+ | (((x) & 0x0000000000ff0000ull) << 24) \
+ | (((x) & 0x000000000000ff00ull) << 40) \
+ | (((x) & 0x00000000000000ffull) << 56))
#define SWAP_32(x) \
(((uint32_t)(x) << 24) | (((uint32_t)(x) & 0xff00) << 8) |(((uint32_t)(x) & 0x00ff0000) >> 8) | ((uint32_t)(x) >> 24))
#define SWAP_16(x) \
@@ -56,19 +65,25 @@
// standard swap macros
#if BYTE_ORDER == BIG_ENDIAN
+#define LE64(val) SWAP_64(val)
#define LE32(val) SWAP_32(val)
#define LE16(val) SWAP_16(val)
+#define BE64(val) (val)
#define BE32(val) (val)
#define BE16(val) (val)
#else
+#define LE64(val) (val)
#define LE32(val) (val)
#define LE16(val) (val)
+#define BE64(val) SWAP_64(val)
#define BE32(val) SWAP_32(val)
#define BE16(val) SWAP_16(val)
#endif
+#define LE64SWAP(var) (var) = LE64(var);
#define LE32SWAP(var) (var) = LE32(var);
#define LE16SWAP(var) (var) = LE16(var);
+#define BE64SWAP(var) (var) = BE64(var);
#define BE32SWAP(var) (var) = BE32(var);
#define BE16SWAP(var) (var) = BE16(var);
diff --git a/platform/apq8084/include/platform/iomap.h b/platform/apq8084/include/platform/iomap.h
index ef26cbb..a5d0d41 100644
--- a/platform/apq8084/include/platform/iomap.h
+++ b/platform/apq8084/include/platform/iomap.h
@@ -119,6 +119,8 @@
#define USB_HS_BCR (CLK_CTL_BASE + 0x480)
+#define UFS_BASE (0xFC590000 + 0x00004000)
+
#define SPMI_BASE 0xFC4C0000
#define SPMI_GENI_BASE (SPMI_BASE + 0xA000)
#define SPMI_PIC_BASE (SPMI_BASE + 0xB000)
diff --git a/platform/apq8084/include/platform/irqs.h b/platform/apq8084/include/platform/irqs.h
index 8b25b0c..33e1a12 100644
--- a/platform/apq8084/include/platform/irqs.h
+++ b/platform/apq8084/include/platform/irqs.h
@@ -45,6 +45,8 @@
#define INT_QTMR_FRM_0_PHYSICAL_TIMER_EXP (GIC_SPI_START + 8)
+#define UFS_IRQ (GIC_SPI_START + 28)
+
#define USB1_HS_BAM_IRQ (GIC_SPI_START + 135)
#define USB1_HS_IRQ (GIC_SPI_START + 134)
#define USB2_IRQ (GIC_SPI_START + 141)
diff --git a/platform/msm_shared/dme.c b/platform/msm_shared/dme.c
new file mode 100644
index 0000000..da2f9ec
--- /dev/null
+++ b/platform/msm_shared/dme.c
@@ -0,0 +1,369 @@
+/* Copyright (c) 2013, The Linux Foundation. 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.
+ * * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * 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 <debug.h>
+#include <string.h>
+#include <reg.h>
+#include <arch/defines.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <endian.h>
+#include <ufs.h>
+#include <dme.h>
+#include <uic.h>
+#include <utp.h>
+
+int dme_send_linkstartup_req(struct ufs_dev *dev)
+{
+ struct uic_cmd cmd;
+
+ cmd.uiccmd = UICCMDR_DME_LINKSTARTUP;
+ cmd.num_args = UICCMD_NO_ARGS;
+ cmd.timeout_msecs = DME_LINK_START_TIMEOUT;
+
+ if (uic_send_cmd(dev, &cmd) || cmd.gen_err_code == UICCMD_FAILURE)
+ goto dme_send_linkstartup_req_err;
+
+ return UFS_SUCCESS;
+
+dme_send_linkstartup_req_err:
+ dprintf(CRITICAL, "DME_LINKSTARTUP command failed.\n");
+ return -UFS_FAILURE;
+}
+
+int dme_get_req(struct ufs_dev *dev, struct dme_get_req_type *req)
+{
+ struct uic_cmd cmd;
+
+ cmd.uiccmd = UICCMDR_DME_GET;
+ cmd.num_args = UICCMD_ONE_ARGS;
+ cmd.uiccmdarg1 = req->attribute << 16 | req->index;
+ cmd.timeout_msecs = INFINITE_TIME;
+
+ if (uic_send_cmd(dev, &cmd) || cmd.gen_err_code == UICCMD_FAILURE)
+ goto dme_get_req_err;
+
+ /* Return the result. */
+ *(req->mibval) = cmd.uiccmdarg3;
+
+ return UFS_SUCCESS;
+
+dme_get_req_err:
+ dprintf(CRITICAL, "DME_GET command failed.\n");
+ return -UFS_FAILURE;
+}
+
+static int dme_get_query_resp(struct ufs_dev *dev,
+ struct upiu_req_build_type *req_upiu,
+ addr_t buffer,
+ size_t buf_len)
+{
+ struct upiu_trans_mgmt_query_hdr *resp_upiu;
+
+ resp_upiu = (struct upiu_trans_mgmt_query_hdr *) req_upiu->resp_ptr;
+
+ if (resp_upiu->opcode != req_upiu->opcode)
+ return -UFS_FAILURE;
+ if (resp_upiu->basic_hdr.response != UPIU_QUERY_RESP_SUCCESS)
+ return -UFS_FAILURE;
+
+ switch (resp_upiu->opcode)
+ {
+ case UPIU_QUERY_OP_READ_FLAG:
+ case UPIU_QUERY_OP_SET_FLAG:
+ if (buf_len < sizeof(uint32_t))
+ {
+ dprintf(CRITICAL, "Insufficient buffer space.\n");
+ return -UFS_FAILURE;
+ }
+
+ *((uint32_t *) buffer) = resp_upiu->flag_value;
+ break;
+ case UPIU_QUERY_OP_TOGGLE_FLAG:
+ case UPIU_QUERY_OP_CLEAR_FLAG:
+ case UPIU_QUERY_OP_READ_DESCRIPTOR:
+ break;
+ default: dprintf(CRITICAL, "UPIU query opcode not supported.\n");
+ return -UFS_FAILURE;
+ }
+
+ return UFS_SUCCESS;
+}
+
+static int dme_send_query_upiu(struct ufs_dev *dev, struct utp_query_req_upiu_type *query)
+{
+ struct upiu_trans_mgmt_query_hdr resp_upiu;
+ struct upiu_req_build_type req_upiu;
+ int ret;
+
+ memset(&req_upiu, 0, sizeof(req_upiu));
+
+ req_upiu.opcode = query->opcode;
+ req_upiu.selector = query->selector;
+ req_upiu.index = query->index;
+ req_upiu.idn = query->idn;
+ req_upiu.trans_type = UPIU_TYPE_QUERY_REQ;
+ req_upiu.dd = UTRD_NO_DATA_TRANSFER;
+ req_upiu.resp_ptr = (struct upiu_basic_hdr *) &resp_upiu;
+ req_upiu.resp_len = sizeof(resp_upiu);
+ req_upiu.resp_data_ptr = query->buf;
+ req_upiu.timeout_msecs = UTP_GENERIC_CMD_TIMEOUT;
+
+ if (query->opcode == UPIU_QUERY_OP_READ_DESCRIPTOR)
+ {
+ req_upiu.resp_data_len = query->buf_len;
+ }
+
+ ret = utp_enqueue_upiu(dev, &req_upiu);
+ if (ret)
+ goto utp_send_query_upiu_err;
+
+ ret = dme_get_query_resp(dev, &req_upiu, query->buf, query->buf_len);
+ if (ret)
+ goto utp_send_query_upiu_err;
+
+utp_send_query_upiu_err:
+ return ret;
+}
+
+int dme_set_fdeviceinit(struct ufs_dev *dev)
+{
+ STACKBUF_DMA_ALIGN(result, sizeof(uint32_t));
+ uint32_t try_again = DME_FDEVICEINIT_RETRIES;
+ struct utp_query_req_upiu_type read_query = {UPIU_QUERY_OP_READ_FLAG,
+ UFS_IDX_fDeviceInit,
+ 0,
+ 0,
+ (addr_t) result,
+ sizeof(uint32_t)};
+ struct utp_query_req_upiu_type set_query = {UPIU_QUERY_OP_SET_FLAG,
+ UFS_IDX_fDeviceInit,
+ 0,
+ 0,
+ (addr_t) result,
+ sizeof(uint32_t)};
+
+
+ if (dme_send_query_upiu(dev, &read_query))
+ return -UFS_FAILURE;
+
+ arch_invalidate_cache_range((addr_t) result, sizeof(uint32_t));
+
+ if (*result == 1)
+ goto utp_set_fdeviceinit_done;
+
+ do
+ {
+ try_again--;
+
+ if (dme_send_query_upiu(dev, &set_query))
+ return -UFS_FAILURE;
+
+ if (dme_send_query_upiu(dev, &read_query))
+ return -UFS_FAILURE;
+
+ if (*result == 1)
+ break;
+ } while (try_again);
+
+utp_set_fdeviceinit_done:
+ return UFS_SUCCESS;
+}
+
+int dme_read_string_desc(struct ufs_dev *dev, uint8_t index, struct ufs_string_desc *desc)
+{
+ struct utp_query_req_upiu_type query = {UPIU_QUERY_OP_READ_DESCRIPTOR,
+ UFS_DESC_IDN_STRING,
+ index,
+ 0,
+ (addr_t) desc,
+ sizeof(struct ufs_string_desc)};
+
+ if (dme_send_query_upiu(dev, &query))
+ return -UFS_FAILURE;
+
+ if (desc->desc_len != 0)
+ return UFS_SUCCESS;
+
+ return -UFS_FAILURE;
+}
+
+int dme_read_device_desc(struct ufs_dev *dev)
+{
+ STACKBUF_DMA_ALIGN(dev_desc, sizeof(struct ufs_dev_desc));
+ STACKBUF_DMA_ALIGN(desc, sizeof(struct ufs_string_desc));
+ struct ufs_dev_desc *device_desc = dev_desc;
+ struct ufs_string_desc *str_desc = desc;
+ struct utp_query_req_upiu_type query = {UPIU_QUERY_OP_READ_DESCRIPTOR,
+ UFS_DESC_IDN_DEVICE,
+ 0,
+ 0,
+ (addr_t) dev_desc,
+ sizeof(struct ufs_dev_desc)};
+
+ if (dme_send_query_upiu(dev, &query))
+ return -UFS_FAILURE;
+
+ /* Flush buffer. */
+ arch_invalidate_cache_range((addr_t) device_desc, sizeof(struct ufs_dev_desc));
+
+ /* Store all relevant data */
+ dev->num_lus = device_desc->num_lu;
+
+ /* Get serial number for the device based on the string index. */
+ if (dme_read_string_desc(dev, device_desc->serial_num, desc))
+ return -UFS_FAILURE;
+
+ /* Flush buffer. */
+ arch_invalidate_cache_range((addr_t) str_desc, sizeof(struct ufs_string_desc));
+
+ dev->serial_num = 0;
+
+ return UFS_SUCCESS;
+}
+
+int dme_read_unit_desc(struct ufs_dev *dev, uint8_t index, uint64_t *capacity)
+{
+ STACKBUF_DMA_ALIGN(unit_desc, sizeof(struct ufs_unit_desc));
+ struct ufs_unit_desc *desc = unit_desc;
+ struct utp_query_req_upiu_type query = {UPIU_QUERY_OP_READ_DESCRIPTOR,
+ UFS_DESC_IDN_UNIT,
+ index,
+ 0,
+ (addr_t) unit_desc,
+ sizeof(struct ufs_unit_desc)};
+
+ if (dme_send_query_upiu(dev, &query))
+ return -UFS_FAILURE;
+
+ /* Flush buffer. */
+ arch_invalidate_cache_range((addr_t) desc, sizeof(struct ufs_unit_desc));
+
+ *capacity = BE64(desc->logical_blk_cnt) * dev->block_size;
+
+ return UFS_SUCCESS;
+}
+
+int dme_read_config_desc(struct ufs_dev *dev)
+{
+ STACKBUF_DMA_ALIGN(desc, sizeof(struct ufs_config_desc));
+ struct ufs_config_desc *config_desc = desc;
+ struct utp_query_req_upiu_type query = {UPIU_QUERY_OP_READ_DESCRIPTOR,
+ UFS_DESC_IDN_CONFIGURATION,
+ 0,
+ 0,
+ (addr_t) config_desc,
+ sizeof(struct ufs_config_desc)};
+
+ if (dme_send_query_upiu(dev, &query))
+ return -UFS_FAILURE;
+
+ /* Flush buffer. */
+ arch_invalidate_cache_range((addr_t) config_desc, sizeof(struct ufs_config_desc));
+
+ return UFS_SUCCESS;
+}
+
+int dme_send_nop_query(struct ufs_dev *dev)
+{
+ struct upiu_req_build_type req_upiu;
+ struct upiu_basic_hdr resp_upiu;
+ int ret;
+ unsigned try_again;
+
+ ret = UFS_SUCCESS;
+ try_again = DME_NOP_NUM_RETRIES;
+
+ memset(&req_upiu, 0 , sizeof(struct upiu_req_build_type));
+
+ req_upiu.trans_type = UPIU_TYPE_NOP_OUT;
+ req_upiu.flags = 0;
+ req_upiu.query_mgmt_func = 0;
+ req_upiu.cmd_type = UTRD_DEV_MGMT_FUNC;
+ req_upiu.dd = UTRD_NO_DATA_TRANSFER;
+ req_upiu.resp_ptr = &resp_upiu;
+ req_upiu.resp_len = sizeof(struct upiu_basic_hdr);
+ req_upiu.timeout_msecs = DME_NOP_QUERY_TIMEOUT;
+
+ while (try_again)
+ {
+ try_again--;
+
+ ret = utp_enqueue_upiu(dev, &req_upiu);
+
+ if (ret == -UFS_RETRY)
+ {
+ continue;
+ }
+ else if (ret == -UFS_FAILURE)
+ {
+ dprintf(CRITICAL, "sending nop out failed.\n");
+ goto upiu_send_nop_out_err;
+ }
+
+ /* Check response UPIU */
+ if (resp_upiu.trans_type != UPIU_TYPE_NOP_IN)
+ {
+ dprintf(CRITICAL, "Command failed. command = %x. Invalid response.\n", req_upiu.trans_type);
+ ret = -UFS_FAILURE;
+ goto upiu_send_nop_out_err;
+ }
+ else
+ break;
+ }
+
+upiu_send_nop_out_err:
+ return ret;
+}
+
+int utp_build_query_req_upiu(struct upiu_trans_mgmt_query_hdr *req_upiu,
+ struct upiu_req_build_type *upiu_data)
+{
+ req_upiu->opcode = upiu_data->opcode;
+ req_upiu->idn = upiu_data->idn;
+ req_upiu->index = upiu_data->index;
+ req_upiu->selector = upiu_data->selector;
+ req_upiu->resp_len = BE16(upiu_data->resp_data_len);
+
+ switch (upiu_data->opcode)
+ {
+ case UPIU_QUERY_OP_READ_FLAG:
+ case UPIU_QUERY_OP_READ_DESCRIPTOR:
+ req_upiu->basic_hdr.query_task_mgmt_func = UPIU_QUERY_FUNC_STD_READ_REQ;
+ break;
+ case UPIU_QUERY_OP_TOGGLE_FLAG:
+ case UPIU_QUERY_OP_CLEAR_FLAG:
+ case UPIU_QUERY_OP_SET_FLAG:
+ req_upiu->basic_hdr.query_task_mgmt_func = UPIU_QUERY_FUNC_STD_WRITE_REQ;
+ break;
+ default: dprintf(CRITICAL, "UPIU query opcode not supported.\n");
+ return -UFS_FAILURE;
+ }
+
+ return UFS_SUCCESS;
+}
diff --git a/platform/msm_shared/include/dme.h b/platform/msm_shared/include/dme.h
new file mode 100644
index 0000000..c93e23a
--- /dev/null
+++ b/platform/msm_shared/include/dme.h
@@ -0,0 +1,247 @@
+/* Copyright (c) 2013, The Linux Foundation. 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.
+ * * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * 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 _DME_H_
+#define _DME_H_
+
+#include <sys/types.h>
+#include <upiu.h>
+
+/* Bit field of UFSHCI_UICCMDR register */
+#define UICCMDR_DME_GET 0x01
+#define UICCMDR_DME_SET 0x02
+#define UICCMDR_DME_PEER_GET 0x03
+#define UICCMDR_DME_PEER_SET 0x04
+#define UICCMDR_DME_POWERON 0x10
+#define UICCMDR_DME_POWEROFF 0x11
+#define UICCMDR_DME_ENABLE 0x12
+#define UICCMDR_DME_RESET 0x14
+#define UICCMDR_DME_ENDPOINTRESET 0x15
+#define UICCMDR_DME_LINKSTARTUP 0x16
+#define UICCMDR_DME_HIBERNATE_ENTER 0x17
+#define UICCMDR_DME_HIBERNATE_EXIT 0x18
+#define UICCMDR_DME_TEST_MODE 0x1a
+
+/* Retry value for commands. */
+#define DME_NOP_NUM_RETRIES 20
+#define DME_FDEVICEINIT_RETRIES 20
+
+/* Timeout value for commands. */
+#define DME_NOP_QUERY_TIMEOUT 10
+#define DME_LINK_START_TIMEOUT 1
+
+/* UFS descriptor type ident value */
+enum utp_ufs_desc_type
+{
+ UFS_DESC_IDN_DEVICE = 0x00,
+ UFS_DESC_IDN_CONFIGURATION = 0x01,
+ UFS_DESC_IDN_UNIT = 0x02,
+ UFS_DESC_IDN_INTERCONNECT = 0x04,
+ UFS_DESC_IDN_STRING = 0x05,
+ UFS_DESC_IDN_GEOMETRY = 0x07,
+ UFS_DESC_IDN_POWER = 0x08,
+};
+
+// Attributes definitions
+#define UFS_IDX_bBootLunEn 0x00
+#define UFS_IDX_bCurrentPowerMode 0x01
+#define UFS_IDX_bActiveICCLevel 0x03
+#define UFS_IDX_bRefClkFreq 0x0a
+#define UFS_IDX_bConfigDescrLock 0x0b
+
+enum utp_query_req_upiu_func_type
+{
+ UPIU_QUERY_FUNC_STD_READ_REQ = 0x01,
+ UPIU_QUERY_FUNC_STD_WRITE_REQ = 0x81,
+};
+
+/* Flags definitions */
+#define UFS_IDX_fDeviceInit 0x01
+#define UFS_IDX_fPowerOnWPEn 0x03
+
+enum utp_query_response_upiu_type
+{
+ UPIU_QUERY_RESP_SUCCESS = 0x00,
+ UPIU_QUERY_RESP_PARAM_NOT_READABLE = 0xF6,
+ UPIU_QUERY_RESP_PARAM_NOT_WRITABLE = 0xF7,
+ UPIU_QUERY_RESP_PARAM_ALREADY_WRITTEN = 0xF8,
+ UPIU_QUERY_RESP_INVALID_LEN = 0xF9,
+ UPIU_QUERY_RESP_INVALID_VALUE = 0xFA,
+ UPIU_QUERY_RESP_INVALID_SELECTOR = 0xFB,
+ UPIU_QUERY_RESP_INVALID_IDN = 0xFC,
+ UPIU_QUERY_RESP_INVALID_OPCODE = 0xFD,
+ UPIU_QUERY_RESP_GEN_FAILURE = 0xFE,
+};
+
+struct dme_get_req_type
+{
+ uint16_t attribute;
+ uint16_t index;
+ uint32_t *mibval;
+};
+
+#define DEV_DESC_LEN 0x1F
+
+struct utp_query_req_upiu_type
+{
+ enum upiu_query_opcode_type opcode;
+ uint8_t idn;
+ uint8_t index;
+ uint8_t selector;
+ addr_t buf;
+ size_t buf_len;
+};
+
+struct ufs_dev_desc
+{
+ uint8_t desc_len;
+ uint8_t desc_type;
+ uint8_t dev_type;
+ uint8_t dev_class;
+ uint8_t dev_sub_class;
+ uint8_t protocol;
+ uint8_t num_lu;
+ uint8_t num_wlun;
+ uint8_t boot_en;
+ uint8_t desc_access_en;
+ uint8_t init_pwr_mode;
+ uint8_t high_pior_lun;
+ uint8_t sec_removal_type;
+ uint8_t sec_lun;
+ uint8_t resv_0;
+ uint8_t active_icc_level;
+ uint16_t spec_ver;
+ uint16_t manufacture_date;
+ uint8_t manufacture_name;
+ uint8_t product_name;
+ uint8_t serial_num;
+ uint8_t oem_id;
+ uint16_t manufacture_id;
+ uint8_t ud0_base_offset;
+ uint8_t ud_config_p_len;
+ uint8_t dev_rtt_cap;
+}__PACKED;
+
+struct ufs_unit_desc
+{
+ uint8_t desc_len;
+ uint8_t desc_type;
+ uint8_t unit_index;
+ uint8_t lu_enable;
+ uint8_t boot_lun_id;
+ uint8_t lu_wp;
+ uint8_t lu_queue_depth;
+ uint8_t resv;
+ uint8_t mem_type;
+ uint8_t data_reliability;
+ uint8_t logical_blk_size;
+ uint64_t logical_blk_cnt;
+ uint32_t erase_blk_size;
+ uint8_t provisioning_type;
+ uint8_t phy_mem_resource_cnt[8];
+ uint16_t ctx_capabilities;
+ uint8_t large_unit_size_m1;
+}__PACKED;
+
+struct ufs_geometry_desc
+{
+ uint8_t desc_len;
+ uint8_t desc_type;
+ uint8_t media_tech;
+ uint8_t resv_0;
+ uint8_t raw_dev_capacity[8];
+ uint8_t resv_1;
+ uint32_t segment_size;
+ uint8_t alloc_unit_size;
+ uint8_t min_addr_blk_size;
+ uint8_t optimal_read_blk_size;
+ uint8_t optimal_write_blk_size;
+ uint8_t max_inbuf_size;
+ uint8_t maxoutbuf_size;
+ uint8_t rpmb_rdwr_size;
+ uint8_t resv_2;
+ uint8_t data_ordering;
+ uint8_t resv_3[5];
+ uint8_t max_ctx_id_num;
+ uint8_t sys_data_tag_unit_size;
+ uint8_t sys_data_tag_res_size;
+ uint8_t supp_sec_rt_types;
+ uint16_t supp_mem_types;
+}__PACKED;
+
+struct ufs_dev_desc_config_params
+{
+ uint8_t num_lu;
+ uint8_t boot_enable;
+ uint8_t desc_access_en;
+ uint8_t init_pwr_mode;
+ uint8_t high_pior_lun;
+ uint8_t sec_removal_type;
+ uint8_t active_icc_level;
+ uint16_t dev_rtt_cap;
+ uint8_t resv[5];
+}__PACKED;
+
+struct ufs_unit_desc_config_params
+{
+ uint8_t lu_enable;
+ uint8_t boot_lun_id;
+ uint8_t lu_wp;
+ uint8_t mem_type;
+ uint32_t num_alloc_units;
+ uint8_t data_reliability;
+ uint8_t logical_blk_size;
+ uint8_t provisioning_type;
+ uint16_t ctx_capabilities;
+ uint8_t resv[3];
+}__PACKED;
+
+struct ufs_config_desc
+{
+ uint8_t desc_len;
+ uint8_t desc_type;
+ struct ufs_dev_desc_config_params config_params;
+ struct ufs_unit_desc_config_params unit_params[8];
+}__PACKED;
+
+struct ufs_string_desc
+{
+ uint8_t desc_len;
+ uint8_t desc_type;
+ uint8_t serial_num[128];
+}__PACKED;
+
+int dme_send_linkstartup_req(struct ufs_dev *dev);
+int dme_get_req(struct ufs_dev *dev, struct dme_get_req_type *req);
+int utp_build_query_req_upiu(struct upiu_trans_mgmt_query_hdr *req_upiu,
+ struct upiu_req_build_type *upiu_data);
+int dme_send_nop_query(struct ufs_dev *dev);
+int dme_set_fdeviceinit(struct ufs_dev *dev);
+int dme_read_unit_desc(struct ufs_dev *dev, uint8_t index, uint64_t *capacity);
+
+#endif
diff --git a/platform/msm_shared/include/ucs.h b/platform/msm_shared/include/ucs.h
new file mode 100644
index 0000000..9f02a03
--- /dev/null
+++ b/platform/msm_shared/include/ucs.h
@@ -0,0 +1,129 @@
+/* Copyright (c) 2013, The Linux Foundation. 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.
+ * * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * 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 _UCS_H
+#define _UCS_H
+
+#define SCSI_MAX_DATA_TRANS_BLK_LEN 0x01
+#define UFS_DEFAULT_SECTORE_SIZE 4096
+
+#define SCSI_STATUS_GOOD 0x00
+#define SCSI_STATUS_CHK_COND 0x02
+#define SCSI_STATUS_BUSY 0x08
+#define SCSI_STATUS_TASK_SET_FULL 0x08
+
+#define SCSI_SENSE_BUF_LEN 0x20
+#define SCSI_INQUIRY_LEN 36
+#define SCSI_CDB_PARAM_LEN 16
+
+/* FLAGS for indication of read or write */
+enum scsi_upiu_flags
+{
+ UPIU_FLAGS_READ = 0x40,
+ UPIU_FLAGS_WRITE = 0x20,
+ UPIU_FLAGS_ATTR_SIMPLE = 0x00,
+ UPIU_FLAGS_ATTR_ORDERED = 0x01,
+ UPIU_FLAGS_ATTR_HOQ = 0x02,
+};
+
+#define SCSI_READ_WRITE_10_CDB1(rd_protect, dpo, fua, fua_nv) ((rd_protect) << 5 | (dpo) << 4 | (fua) << 3 | (fua_nv) << 1)
+
+/* SCSI commands */
+enum utp_scsi_cmd_type
+{
+ SCSI_CMD_TEST_UNIT_RDY = 0x00,
+ SCSI_CMD_SENSE_REQ = 0x03,
+ SCSI_CMD_INQUIRY = 0x12,
+ SCSI_CMD_READ10 = 0x28,
+ SCSI_CMD_READ_CAP10 = 0x25, // Read Capacity
+ SCSI_CMD_SYNC_CACHE10 = 0x35,
+ SCSI_CMD_UNMAP = 0x42,
+ SCSI_CMD_WRITE10 = 0x2A,
+ SCSI_CMD_SECPROT_IN = 0xA2, // Security Protocal in
+ SCSI_CMD_SECPROT_OUT = 0xB5, // Security Protocal out
+ SCSI_CMD_REPORT_LUNS = 0xA0,
+};
+
+struct scsi_req_build_type
+{
+ addr_t cdb;
+ uint8_t lun;
+ addr_t data_buffer_addr;
+ uint32_t data_len;
+ enum scsi_upiu_flags flags;
+ enum upiu_dd_type dd;
+};
+
+struct scsi_rdwr_req
+{
+ uint8_t lun;
+ uint32_t start_lba;
+ uint32_t num_blocks;
+ uint32_t data_buffer_base;
+};
+
+struct scsi_rdwr_cdb
+{
+ uint8_t opcode;
+ uint8_t cdb1;
+ uint32_t lba;
+ uint8_t grp_num;
+ uint16_t trans_len;
+ uint8_t control;
+ uint8_t resv[6];
+}__PACKED;
+
+struct scsi_sense_cdb
+{
+ uint8_t opcode;
+ uint8_t desc;
+ uint16_t resv_0;
+ uint8_t alloc_len;
+ uint8_t control;
+ uint8_t resv_1[10];
+}__PACKED;
+
+struct scsi_failure_sense_data
+{
+ uint8_t valid_resp_code;
+ uint8_t obsolete;
+ uint16_t file_mark_eom_ili_resv_sense_key;
+ uint8_t sense_info[4];
+ uint8_t additional_sense_len;
+ uint32_t csi;
+ uint8_t asc;
+ uint8_t ascq;
+ uint8_t fruc;
+ uint8_t sense_key_specific;
+}__PACKED;
+
+int ucs_scsi_send_inquiry(struct ufs_dev *dev);
+int ucs_do_scsi_read(struct ufs_dev *dev, struct scsi_rdwr_req *req);
+int ucs_do_scsi_write(struct ufs_dev *dev, struct scsi_rdwr_req *req);
+
+#endif
diff --git a/platform/msm_shared/include/ufs.h b/platform/msm_shared/include/ufs.h
new file mode 100644
index 0000000..e5578bd
--- /dev/null
+++ b/platform/msm_shared/include/ufs.h
@@ -0,0 +1,96 @@
+/* Copyright (c) 2013, The Linux Foundation. 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.
+ * * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * 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 _UFS_H_
+#define _UFS_H_
+
+#include <sys/types.h>
+#include <kernel/mutex.h>
+#include <kernel/event.h>
+#include <list.h>
+
+enum ufs_err
+{
+ UFS_SUCCESS,
+ UFS_FAILURE,
+ UFS_RETRY,
+};
+
+struct ufs_req_node
+{
+ uint32_t task_id;
+ uint32_t door_bell_bit;
+ event_t *event;
+ struct list_node list_node;
+};
+
+
+struct ufs_utp_req_meta_data
+{
+ mutex_t bitmap_mutex;
+ struct ufs_req_node list_head;
+ uint32_t bitmap;
+ uint32_t task_id;
+ uint64_t list_base_addr;
+};
+
+struct ufs_uic_meta_data
+{
+ mutex_t uic_mutex;
+ event_t uic_event;
+};
+
+struct ufs_dev
+{
+ uint8_t instance;
+ uint32_t base;
+ uint8_t num_lus;
+ uint32_t serial_num;
+ uint32_t block_size;
+
+ /* UTRD maintainance data structures.*/
+ struct ufs_utp_req_meta_data utrd_data;
+ struct ufs_utp_req_meta_data utmrd_data;
+
+ /* UIC maintainance data structures.*/
+ struct ufs_uic_meta_data uic_data;
+};
+
+/* Define all the basic WLUN type */
+#define UFS_WLUN_REPORT 0x81
+#define UFS_UFS_DEVICE 0xD0
+#define UFS_WLUN_BOOT 0xB0
+#define UFS_WLUN_RPMB 0xC4
+
+int ufs_init(struct ufs_dev *dev);
+int ufs_read(struct ufs_dev* dev, uint64_t start_lba, addr_t buffer, uint32_t num_blocks);
+int ufs_write(struct ufs_dev* dev, uint64_t start_lba, addr_t buffer, uint32_t num_blocks);
+uint64_t ufs_get_dev_capacity(struct ufs_dev* dev);
+uint32_t ufs_get_serial_num(struct ufs_dev* dev);
+
+#endif
diff --git a/platform/msm_shared/include/ufs_hci.h b/platform/msm_shared/include/ufs_hci.h
new file mode 100644
index 0000000..b1b76f6
--- /dev/null
+++ b/platform/msm_shared/include/ufs_hci.h
@@ -0,0 +1,53 @@
+/* Copyright (c) 2013, The Linux Foundation. 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.
+ * * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * 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 _UFS_HCI_H
+#define _UFS_HCI_H_
+
+#include <kernel/mutex.h>
+#include <kernel/event.h>
+#include <list.h>
+#include <ufs.h>
+
+#define UFS_HCE_TIMEOUT 100000
+
+struct ufs_req_irq_type
+{
+ struct list_node *list;
+ uint32_t irq_handled;
+ uint32_t door_bell_reg;
+};
+
+int ufs_reg_target_val_timeout_loop(uint32_t reg_addr, uint32_t target_val, uint32_t timeout);
+enum handler_return ufs_irq_handler(void* data);
+void ufs_irq_enable(struct ufs_dev *dev, uint32_t irq);
+int ufs_enable_hci(struct ufs_dev *dev);
+uint64_t ufs_alloc_trans_req_list();
+uint64_t ufs_alloc_task_mgmt_req_list();
+
+#endif
diff --git a/platform/msm_shared/include/ufs_hw.h b/platform/msm_shared/include/ufs_hw.h
new file mode 100644
index 0000000..cf4da12
--- /dev/null
+++ b/platform/msm_shared/include/ufs_hw.h
@@ -0,0 +1,107 @@
+/* Copyright (c) 2013, The Linux Foundation. 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.
+ * * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * 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 _UFS_HW_H_
+#define _UFS_HW_H_
+
+#include <bits.h>
+
+#define UFS_CAP(_base) (_base + 0x00000000)
+#define UFS_VER(_base) (_base + 0x00000008)
+#define UFS_HCDDID(_base) (_base + 0x00000010)
+#define UFS_HCPMID(_base) (_base + 0x00000014)
+#define UFS_IS(_base) (_base + 0x00000020)
+#define UFS_IE(_base) (_base + 0x00000024)
+#define UFS_HCS(_base) (_base + 0x00000030)
+#define UFS_HCE(_base) (_base + 0x00000034)
+#define UFS_UECPA(_base) (_base + 0x00000038)
+#define UFS_UECDL(_base) (_base + 0x0000003C)
+#define UFS_UTRIACR(_base) (_base + 0x0000004C)
+#define UFS_UTRLBA(_base) (_base + 0x00000050)
+#define UFS_UTRLBAU(_base) (_base + 0x00000054)
+#define UFS_UTRLDBR(_base) (_base + 0x00000058)
+#define UFS_UTRLCLR(_base) (_base + 0x0000005C)
+#define UFS_UTRLRSR(_base) (_base + 0x00000060)
+#define UFS_UTMRLBA(_base) (_base + 0x00000070)
+#define UFS_UTMRLBAU(_base) (_base + 0x00000074)
+#define UFS_UTMRLRSR(_base) (_base + 0x00000080)
+#define UFS_UICCMD(_base) (_base + 0x00000090)
+#define UFS_UICCMDARG1(_base) (_base + 0x00000094)
+#define UFS_UICCMDARG2(_base) (_base + 0x00000098)
+#define UFS_UICCMDARG3(_base) (_base + 0x0000009C)
+#define UFS_SYS1CLK_1US(_base) (_base + 0x000000C0)
+#define UFS_TX_SYMBOL_CLK_NS_US(_base) (_base + 0x000000C4)
+#define UFS_REG_PA_LINK_STARTUP_TIMER(_base) (_base + 0x000000D8)
+#define UFS_CFG1(_base) (_base + 0x000000DC)
+
+#define UFS_CFG1_PHY_SOFT_RESET BIT(0)
+
+/* Bit field of UFSHCI_HCS register */
+#define UFS_HCS_DP BIT(0)
+#define UFS_HCS_UTRLRDY BIT(1)
+#define UFS_HCS_UTMRLRDY BIT(2)
+#define UFS_HCS_UCRDY BIT(3)
+
+/* Bit field of UFSHCI_IE register */
+#define UFS_IE_UTRCE BIT(0)
+#define UFS_IE_UDEPRIU BIT(1)
+#define UFS_IE_UEE BIT(2)
+#define UFS_IE_UTMSE BIT(3)
+#define UFS_IE_UPMSE BIT(4)
+#define UFS_IE_UHXSE BIT(5)
+#define UFS_IE_UHESE BIT(6)
+#define UFS_IE_ULLSE BIT(7)
+#define UFS_IE_ULSSE BIT(8)
+#define UFS_IE_UTMRCE BIT(9)
+#define UFS_IE_UCCE BIT(10)
+#define UFS_IE_DFEE BIT(11)
+#define UFS_IE_UTPEE BIT(12)
+#define UFS_IE_HCFEE BIT(16)
+#define UFS_IE_SBFEE BIT(17)
+
+/* Bit field of UFSHCI_IS register */
+#define UFS_IS_UTRCS BIT(0)
+#define UFS_IS_UDEPRI BIT(1)
+#define UFS_IS_UE BIT(2)
+#define UFS_IS_UTMS BIT(3)
+#define UFS_IS_UPMS BIT(4)
+#define UFS_IS_UHXS BIT(5)
+#define UFS_IS_UHES BIT(6)
+#define UFS_IS_ULLS BIT(7)
+#define UFS_IS_ULSS BIT(8)
+#define UFS_IS_UTMRCS BIT(9)
+#define UFS_IS_UCCS BIT(10)
+#define UFS_IS_DFES BIT(11)
+#define UFS_IS_UTPES BIT(12)
+#define UFS_IS_HCFES BIT(16)
+#define UFS_IS_SBFES BIT(17)
+
+/* Bit field for UFS_HCE register. */
+#define UFS_HCE_ENABLE BIT(0)
+
+#endif
diff --git a/platform/msm_shared/include/uic.h b/platform/msm_shared/include/uic.h
new file mode 100644
index 0000000..bc85241
--- /dev/null
+++ b/platform/msm_shared/include/uic.h
@@ -0,0 +1,81 @@
+/* Copyright (c) 2013, The Linux Foundation. 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.
+ * * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * 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 _UIC_H_
+#define _UIC_H_
+
+#include <sys/types.h>
+
+#define HCI_UIC_TIMEOUT 100000
+#define HCI_ENABLE_TIMEOUT 100000
+
+enum uic_error_codes
+{
+ UIC_ERR_UNKNOWN,
+ UIC_ERR_TIMEOUT,
+};
+
+enum uic_gen_err_code
+{
+ UICCMD_SUCCESS,
+ UICCMD_FAILURE,
+};
+
+enum uic_num_cmd_args
+{
+ UICCMD_NO_ARGS = 0,
+ UICCMD_ONE_ARGS = 1,
+ UICCMD_TWO_ARGS = 2,
+ UICCMD_THREE_ARGS = 4,
+};
+
+struct uic_cmd
+{
+ uint32_t uiccmd;
+ uint32_t num_args;
+ uint32_t uiccmdarg1;
+ uint32_t uiccmdarg2;
+ uint32_t uiccmdarg3;
+ uint32_t gen_err_code;
+ uint32_t timeout_msecs;
+};
+
+/* UFS init settings. */
+#define UFS_SYS1CLK_1US_VAL 100
+#define UFS_TX_SYMBOL_CLK_1US_VAL 1
+#define UFS_CLK_NS_REG_VAL 10
+#define UFS_PA_LINK_STARTUP_TIMER_VAL 20000000
+#define UFS_LINK_STARTUP_RETRY 10
+
+#define SHFT_CLK_NS_REG (10)
+
+int uic_init(struct ufs_dev *dev);
+int uic_send_cmd(struct ufs_dev *dev, struct uic_cmd *cmd);
+int uic_reset(struct ufs_dev *dev);
+
+
+#endif
diff --git a/platform/msm_shared/include/upiu.h b/platform/msm_shared/include/upiu.h
new file mode 100644
index 0000000..1c9968d
--- /dev/null
+++ b/platform/msm_shared/include/upiu.h
@@ -0,0 +1,164 @@
+/* Copyright (c) 2013, The Linux Foundation. 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.
+ * * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * 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 _UPIU_H
+#define _UPIU_H
+
+struct upiu_basic_hdr
+{
+ uint8_t trans_type;
+ uint8_t flags;
+ uint8_t lun;
+ uint8_t task_tag;
+ uint8_t cmd_set_type;
+ uint8_t query_task_mgmt_func;
+ uint8_t response;
+ uint8_t status;
+ uint8_t total_ehs_len;
+ uint8_t device_info;
+ uint16_t data_seg_len;
+} __PACKED;
+
+struct upiu_trans_mgmt_query_hdr
+{
+ struct upiu_basic_hdr basic_hdr;
+ uint8_t opcode;
+ uint8_t idn;
+ uint8_t index;
+ uint8_t selector;
+ uint8_t resv_0[2];
+ uint16_t resp_len;
+ uint8_t resv_1[3];
+ uint8_t flag_value;
+ uint8_t resv_2[4];
+}__PACKED;
+
+struct upiu_cmd_hdr
+{
+ struct upiu_basic_hdr basic_hdr;
+ uint32_t data_expected_len; // Requested length
+ uint8_t param[16]; // Payload, operation specefic field
+}__PACKED;
+
+struct upiu_cmd_resp_hdr
+{
+ struct upiu_basic_hdr basic_hdr;
+ uint32_t residual_trans_count;
+ uint8_t resv_0[16];
+}__PACKED;
+
+struct upiu_gen_hdr
+{
+ struct upiu_basic_hdr basic_hdr;
+ uint8_t trans_specific_fields[20];
+}__PACKED;
+
+/* UPIU transaction codes. */
+enum upiu_trans_type
+{
+ UPIU_TYPE_NOP_OUT = 0x00,
+ UPIU_TYPE_COMMAND = 0x01,
+ UPIU_TYPE_TASK_MGMT = 0x04,
+ UPIU_TYPE_QUERY_REQ = 0x16,
+ UPIU_TYPE_NOP_IN = 0x20,
+ UPIU_TYPE_RESPONSE = 0x21,
+ UPIU_TYPE_TASK_MAN_RESP = 0x24,
+ UPIU_TYPE_QUERY_RESP = 0x36,
+ UPIU_TYPE_REJECT = 0x3f,
+};
+
+/* UPIU respones */
+enum upiu_response
+{
+ UPIU_RESPONSE_TARGET_SUCCESS = 0x00,
+ UPIU_RESPONSE_TARGET_FAILURE = 0x01,
+};
+
+enum upiu_cmd_set_type
+{
+ UPIU_SCSI_CMD_SET = 0,
+ UPIU_UFS_SPECIFIC_CMD_SET = 1,
+};
+
+enum upiu_query_opcode_type
+{
+ UPIU_QUERY_OP_NOP = 0x0,
+ UPIU_QUERY_OP_READ_DESCRIPTOR = 0x1,
+ UPIU_QUERY_OP_WRITE_DESCRIPTOR = 0x2,
+ UPIU_QUERY_OP_READ_ATTRIBUTE = 0x3,
+ UPIU_QUERY_OP_WRITE_ATTRIBUTE = 0x4,
+ UPIU_QUERY_OP_READ_FLAG = 0x5,
+ UPIU_QUERY_OP_SET_FLAG = 0x6,
+ UPIU_QUERY_OP_CLEAR_FLAG = 0x7,
+ UPIU_QUERY_OP_TOGGLE_FLAG = 0x8,
+};
+
+enum upiu_cmd_type
+{
+ UTRD_SCSCI_CMD = 0,
+ UTRD_NATIVE_UFS_CMD = 1,
+ UTRD_DEV_MGMT_FUNC = 2,
+};
+
+enum upiu_dd_type
+{
+ UTRD_NO_DATA_TRANSFER = 0,
+ UTRD_SYSTEM_TO_TARGET = 1,
+ UTRD_TARGET_TO_SYSTEM = 2,
+};
+
+struct upiu_req_build_type
+{
+ enum upiu_trans_type trans_type;
+ uint8_t flags;
+ uint8_t lun;
+ enum upiu_cmd_set_type cmd_set_type;
+ uint8_t query_mgmt_func;
+ uint8_t ehs_len;
+ uint16_t data_seg_len;
+ addr_t data_buffer_addr;
+ uint32_t data_buffer_len;
+ addr_t cdb;
+ uint64_t expected_data_len;
+ enum upiu_query_opcode_type opcode;
+ uint8_t idn;
+ uint8_t index;
+ uint8_t selector;
+ struct upiu_basic_hdr *resp_ptr;
+ uint64_t resp_len;
+ uint16_t resp_data_len;
+ addr_t resp_data_ptr;
+
+ /* UTRD properties. */
+ enum upiu_cmd_type cmd_type;
+ enum upiu_dd_type dd;
+ uint64_t timeout_msecs;
+};
+
+
+#endif
diff --git a/platform/msm_shared/include/utp.h b/platform/msm_shared/include/utp.h
new file mode 100644
index 0000000..4d70f16
--- /dev/null
+++ b/platform/msm_shared/include/utp.h
@@ -0,0 +1,149 @@
+/* Copyright (c) 2013, The Linux Foundation. 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.
+ * * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * 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 _UTP_H_
+#define _UTP_H_
+
+#include <ufs_hci.h>
+#include <upiu.h>
+#include <ucs.h>
+#include <dme.h>
+
+/* UPIU general header length without the extra segments. */
+#define UPIU_HDR_LEN 0x20
+
+#define UTP_MAX_PRD_DATA_BYTE_CNT 0x40000
+#define UTP_MAX_PRD_DATA_BYTE_CNT_BYTE_SHIFT 18
+#define UTP_MAX_PRD_TABLE_ENTRIES 1024
+
+#define UTP_CMD_DESC_BASE_ALIGNMENT_SIZE 128
+#define UTP_REQ_BUILD_CMD_DD_IRQ_FIELD(cmd, dd, irq) ((cmd << 4) | (dd << 1) | irq)
+
+#define UTP_MUTEX_ACQUIRE_TIMEOUT 0x100000
+
+#define UTP_GENERIC_CMD_TIMEOUT 10000
+
+struct utp_prdt_entry
+{
+ uint32_t data_base_addr;
+ uint32_t data_upper_addr;
+ uint8_t resv_0[4];
+ uint32_t data_byte_cnt;
+}__PACKED;
+
+struct utp_trans_req_desc
+{
+ uint8_t resv_0[3];
+ uint8_t cmd_type_dd_irq;
+ uint8_t resv_1[4];
+ uint8_t overall_cmd_status;
+ uint8_t resv_2[7];
+ uint8_t cmd_desc_base_addr[4];
+ uint8_t cmd_desc_base_addr_upper[4];
+ uint16_t resp_upiu_len;
+ uint16_t resp_upiu_offset;
+ uint16_t prdt_len;
+ uint16_t prdt_offset;
+}__PACKED;
+
+enum utp_utrd_irq_type
+{
+ UTRD_REGULAR_CMD = 0,
+ UTRD_IRQ_CMD = 1,
+};
+
+enum utp_utrd_overall_status_type
+{
+ UTRD_OCS_SUCCESS = 0x0,
+ UTRD_OCS_INVALID_COM_TABLE_ATTR = 0x1,
+ UTRD_OCS_INVALID_PRDT_ATTR = 0x2,
+ UTRD_OCS_MISMATCH_DATA_BUFFER_SIZE = 0x3,
+ UTRD_OCS_MISMATCH_RESPONSE_UPIU_SIZE = 0x4,
+ UTRD_OCS_COMMUNICATION_FAILURE = 0x5,
+ UTRD_OCS_ABORTED = 0x6,
+ UTRD_OCS_INVALID_OCS_VALUE = 0xf,
+};
+
+struct utp_utrd_req_build_type
+{
+ struct upiu_basic_hdr *req_upiu;
+ uint32_t req_upiu_len;
+ uint32_t resp_upiu_len;
+ enum upiu_cmd_type cmd_type;
+ enum upiu_dd_type dd;
+ enum utp_utrd_irq_type irq;
+ enum utp_utrd_overall_status_type ocs;
+ uint32_t prdt_offset;
+ uint32_t prdt_len;
+ uint32_t timeout;
+};
+
+struct utp_task_mgmt_req_desc
+{
+ uint8_t resv_0[3];
+ uint8_t irq;
+ uint8_t resv_1[4];
+ uint8_t overall_cmd_status;
+ uint8_t resv_2[7];
+}__PACKED;
+
+enum utp_utmrd_irq_type
+{
+ NO_IRQ = 0,
+ ENABLE_IRQ = 1,
+};
+
+enum utp_utmrd_overall_status_type
+{
+ UTMRD_OCS_SUCCESS = 0x0,
+ UTMRD_OCS_TASK_MGMT_FUNC_ATTR = 0x1,
+ UTMRD_OCS_MISMATCH_TASK_MGMT_REQ_SIZE = 0x2,
+ UTMRD_OCS_MISMATCH_TASK_MGMT_RES_SIZE = 0x3,
+ UTMRD_OCS_PEER_COMM_FAILURE = 0x4,
+ UTMRD_OCS_ABORTED = 0x5,
+ UTMRD_OCS_FATAL_ERR = 0x6,
+};
+
+struct utrd_cmd_desc
+{
+ struct upiu_gen_hdr *req_upiu;
+ uint32_t resp_upiu_len;
+ uint32_t num_prdt;
+};
+
+struct utp_bitmap_access_type
+{
+ uint32_t *bitmap;
+ uint32_t door_bell_bit;
+ mutex_t *mutx;
+};
+
+int utp_enqueue_upiu(struct ufs_dev *dev, struct upiu_req_build_type *upiu_data);
+void utp_process_req_completion(struct ufs_req_irq_type *irq);
+
+#endif
diff --git a/platform/msm_shared/mipi_dsi_phy.c b/platform/msm_shared/mipi_dsi_phy.c
index e3a4527..90e541a 100644
--- a/platform/msm_shared/mipi_dsi_phy.c
+++ b/platform/msm_shared/mipi_dsi_phy.c
@@ -213,154 +213,6 @@
udelay(1);
}
-int mdss_dsi_uniphy_pll_config(uint32_t ctl_base)
-{
- mdss_dsi_phy_sw_reset(ctl_base);
-
- /* Configuring the Pll Vco clk to 424 Mhz */
-
- /* Loop filter resistance value */
- writel(0x08, ctl_base + 0x022c);
- /* Loop filter capacitance values : c1 and c2 */
- writel(0x70, ctl_base + 0x0230);
- writel(0x15, ctl_base + 0x0234);
-
- writel(0x02, ctl_base + 0x0208); /* ChgPump */
- writel(0x00, ctl_base + 0x0204); /* postDiv1 */
- writel(0x03, ctl_base + 0x0224); /* postDiv2 */
- writel(0x05, ctl_base + 0x0228); /* postDiv3 */
-
- writel(0x2b, ctl_base + 0x0278); /* Cal CFG3 */
- writel(0x66, ctl_base + 0x027c); /* Cal CFG4 */
- writel(0x05, ctl_base + 0x0264); /* LKDetect CFG2 */
-
- writel(0x0a, ctl_base + 0x023c); /* SDM CFG1 */
- writel(0xab, ctl_base + 0x0240); /* SDM CFG2 */
- writel(0x0a, ctl_base + 0x0244); /* SDM CFG3 */
- writel(0x00, ctl_base + 0x0248); /* SDM CFG4 */
-
- udelay(10);
-
- writel(0x01, ctl_base + 0x0200); /* REFCLK CFG */
- writel(0x00, ctl_base + 0x0214); /* PWRGEN CFG */
- writel(0x71, ctl_base + 0x020c); /* VCOLPF CFG */
- writel(0x02, ctl_base + 0x0210); /* VREG CFG */
- writel(0x00, ctl_base + 0x0238); /* SDM CFG0 */
-
- writel(0x5f, ctl_base + 0x028c); /* CAL CFG8 */
- writel(0xa8, ctl_base + 0x0294); /* CAL CFG10 */
- writel(0x01, ctl_base + 0x0298); /* CAL CFG11 */
- writel(0x0a, ctl_base + 0x026c); /* CAL CFG0 */
- writel(0x30, ctl_base + 0x0284); /* CAL CFG6 */
- writel(0x00, ctl_base + 0x0288); /* CAL CFG7 */
- writel(0x00, ctl_base + 0x0290); /* CAL CFG9 */
- writel(0x20, ctl_base + 0x029c); /* EFUSE CFG */
-
- mdss_dsi_uniphy_pll_sw_reset(ctl_base);
- writel(0x01, ctl_base + 0x0220); /* GLB CFG */
- mdelay(1);
- writel(0x05, ctl_base + 0x0220); /* GLB CFG */
- mdelay(1);
- writel(0x07, ctl_base + 0x0220); /* GLB CFG */
- mdelay(1);
- writel(0x0f, ctl_base + 0x0220); /* GLB CFG */
- mdelay(1);
-
- mdss_dsi_uniphy_pll_lock_detect_setting(ctl_base);
-
- while (!(readl(ctl_base + 0x02c0) & 0x01)) {
- mdss_dsi_uniphy_pll_sw_reset(ctl_base);
- writel(0x01, ctl_base + 0x0220); /* GLB CFG */
- mdelay(1);
- writel(0x05, ctl_base + 0x0220); /* GLB CFG */
- mdelay(1);
- writel(0x07, ctl_base + 0x0220); /* GLB CFG */
- mdelay(1);
- writel(0x05, ctl_base + 0x0220); /* GLB CFG */
- mdelay(1);
- writel(0x07, ctl_base + 0x0220); /* GLB CFG */
- mdelay(1);
- writel(0x0f, ctl_base + 0x0220); /* GLB CFG */
- mdelay(2);
- mdss_dsi_uniphy_pll_lock_detect_setting(ctl_base);
- }
-
-}
-
-int mdss_sharp_dsi_uniphy_pll_config(uint32_t ctl_base)
-{
- mdss_dsi_phy_sw_reset(ctl_base);
-
- /* Configuring the Pll Vco clk to 500 Mhz */
-
- /* Loop filter resistance value */
- writel(0x08, ctl_base + 0x022c);
- /* Loop filter capacitance values : c1 and c2 */
- writel(0x70, ctl_base + 0x0230);
- writel(0x15, ctl_base + 0x0234);
-
- writel(0x02, ctl_base + 0x0208); /* ChgPump */
- writel(0x00, ctl_base + 0x0204); /* postDiv1 */
- writel(0x03, ctl_base + 0x0224); /* postDiv2 */
- writel(0x0b, ctl_base + 0x0228); /* postDiv3 */
-
- writel(0x2b, ctl_base + 0x0278); /* Cal CFG3 */
- writel(0x66, ctl_base + 0x027c); /* Cal CFG4 */
- writel(0x05, ctl_base + 0x0264); /* LKDetect CFG2 */
-
- writel(0x0c, ctl_base + 0x023c); /* SDM CFG1 */
- writel(0x55, ctl_base + 0x0240); /* SDM CFG2 */
- writel(0x05, ctl_base + 0x0244); /* SDM CFG3 */
- writel(0x00, ctl_base + 0x0248); /* SDM CFG4 */
-
- udelay(10);
-
- writel(0x01, ctl_base + 0x0200); /* REFCLK CFG */
- writel(0x00, ctl_base + 0x0214); /* PWRGEN CFG */
- writel(0x01, ctl_base + 0x020c); /* VCOLPF CFG */
- writel(0x02, ctl_base + 0x0210); /* VREG CFG */
- writel(0x00, ctl_base + 0x0238); /* SDM CFG0 */
-
- writel(0x60, ctl_base + 0x028c); /* CAL CFG8 */
- writel(0xf4, ctl_base + 0x0294); /* CAL CFG10 */
- writel(0x01, ctl_base + 0x0298); /* CAL CFG11 */
- writel(0x0a, ctl_base + 0x026c); /* CAL CFG0 */
- writel(0x30, ctl_base + 0x0284); /* CAL CFG6 */
- writel(0x00, ctl_base + 0x0288); /* CAL CFG7 */
- writel(0x00, ctl_base + 0x0290); /* CAL CFG9 */
- writel(0x20, ctl_base + 0x029c); /* EFUSE CFG */
-
- mdss_dsi_uniphy_pll_sw_reset(ctl_base);
- writel(0x01, ctl_base + 0x0220); /* GLB CFG */
- mdelay(1);
- writel(0x05, ctl_base + 0x0220); /* GLB CFG */
- mdelay(1);
- writel(0x07, ctl_base + 0x0220); /* GLB CFG */
- mdelay(1);
- writel(0x0f, ctl_base + 0x0220); /* GLB CFG */
- mdelay(1);
-
- mdss_dsi_uniphy_pll_lock_detect_setting(ctl_base);
-
- while (!(readl(ctl_base + 0x02c0) & 0x01)) {
- mdss_dsi_uniphy_pll_sw_reset(ctl_base);
- writel(0x01, ctl_base + 0x0220); /* GLB CFG */
- mdelay(1);
- writel(0x05, ctl_base + 0x0220); /* GLB CFG */
- mdelay(1);
- writel(0x07, ctl_base + 0x0220); /* GLB CFG */
- mdelay(1);
- writel(0x05, ctl_base + 0x0220); /* GLB CFG */
- mdelay(1);
- writel(0x07, ctl_base + 0x0220); /* GLB CFG */
- mdelay(1);
- writel(0x0f, ctl_base + 0x0220); /* GLB CFG */
- mdelay(2);
- mdss_dsi_uniphy_pll_lock_detect_setting(ctl_base);
- }
-
-}
-
int mdss_dsi_phy_regulator_init(struct mdss_dsi_phy_ctrl *pd)
{
/* DSI0 and DSI1 have a common regulator */
diff --git a/platform/msm_shared/nand.c b/platform/msm_shared/nand.c
index 4030c34..d8df0eb 100644
--- a/platform/msm_shared/nand.c
+++ b/platform/msm_shared/nand.c
@@ -3460,17 +3460,22 @@
}
int
-flash_write(struct ptentry *ptn, unsigned extra_per_page, const void *data,
+flash_write(struct ptentry *ptn, unsigned write_extra_bytes, const void *data,
unsigned bytes)
{
unsigned page = ptn->start * num_pages_per_blk;
unsigned lastpage = (ptn->start + ptn->length) * num_pages_per_blk;
unsigned *spare = (unsigned *)flash_spare;
const unsigned char *image = data;
- unsigned wsize = flash_pagesize + extra_per_page;
+ unsigned wsize;
unsigned n;
int r;
+ if(write_extra_bytes)
+ wsize = flash_pagesize + flash_info.spare_size;
+ else
+ wsize = flash_pagesize;
+
if ((flash_info.type == FLASH_ONENAND_DEVICE)
&& (ptn->type == TYPE_MODEM_PARTITION)) {
dprintf(CRITICAL, "flash_write_image: feature not supported\n");
@@ -3504,7 +3509,7 @@
}
}
- if (extra_per_page) {
+ if (write_extra_bytes) {
r = _flash_write_page(flash_cmdlist, flash_ptrlist,
page, image,
image + flash_pagesize);
diff --git a/platform/msm_shared/qpic_nand.c b/platform/msm_shared/qpic_nand.c
index df8480d..ca3b123 100644
--- a/platform/msm_shared/qpic_nand.c
+++ b/platform/msm_shared/qpic_nand.c
@@ -63,6 +63,7 @@
static struct flash_id supported_flash[] = {
/* Flash ID ID Mask Density(MB) Wid Pgsz Blksz oobsz 8-bit ECCf */
{0x1590AC2C, 0xFFFFFFFF, 0x20000000, 0, 2048, 0x00020000, 0x40, 0},
+ {0x1590AA2C, 0xFFFFFFFF, 0x10000000, 0, 2048, 0x00020000, 0xE0, 1},
{0x2690AC2C, 0xFFFFFFFF, 0x20000000, 0, 4096, 0x00040000, 0xE0, 1},
{0x1590ACAD, 0xFFFFFFFF, 0x20000000, 0, 2048, 0x00020000, 0x80, 0},
/* Note: Width flag is 0 for 8 bit Flash and 1 for 16 bit flash */
@@ -1611,7 +1612,7 @@
int
flash_write(struct ptentry *ptn,
- unsigned extra_per_page,
+ unsigned write_extra_bytes,
const void *data,
unsigned bytes)
{
@@ -1619,9 +1620,14 @@
uint32_t lastpage = (ptn->start + ptn->length) * flash.num_pages_per_blk;
uint32_t *spare = (unsigned *)flash_spare_bytes;
const unsigned char *image = data;
- uint32_t wsize = flash.page_size + extra_per_page;
+ uint32_t wsize;
int r;
+ if(write_extra_bytes)
+ wsize = flash.page_size + flash.spare_size;
+ else
+ wsize = flash.page_size;
+
memset(spare, 0xff, (flash.spare_size / flash.cws_per_page));
while (bytes > 0)
@@ -1656,9 +1662,9 @@
memcpy(rdwr_buf, image, flash.page_size);
- if (extra_per_page)
+ if (write_extra_bytes)
{
- memcpy(rdwr_buf + flash.page_size, image + flash.page_size, extra_per_page);
+ memcpy(rdwr_buf + flash.page_size, image + flash.page_size, flash.spare_size);
r = qpic_nand_write_page(page,
NAND_CFG,
rdwr_buf,
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index 00be808..e20a32d 100755
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -189,7 +189,13 @@
$(LOCAL_DIR)/qpic_nand.o \
$(LOCAL_DIR)/dev_tree.o \
$(LOCAL_DIR)/gpio.o \
- $(LOCAL_DIR)/scm.o
+ $(LOCAL_DIR)/scm.o \
+ $(LOCAL_DIR)/ufs.o \
+ $(LOCAL_DIR)/utp.o \
+ $(LOCAL_DIR)/uic.o \
+ $(LOCAL_DIR)/ucs.o \
+ $(LOCAL_DIR)/ufs_hci.o \
+ $(LOCAL_DIR)/dme.o
endif
ifeq ($(PLATFORM),msm7x27a)
diff --git a/platform/msm_shared/ucs.c b/platform/msm_shared/ucs.c
new file mode 100644
index 0000000..783737f
--- /dev/null
+++ b/platform/msm_shared/ucs.c
@@ -0,0 +1,282 @@
+/* Copyright (c) 2013, The Linux Foundation. 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.
+ * * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * 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 <debug.h>
+#include <stdlib.h>
+#include <endian.h>
+#include <string.h>
+#include <utp.h>
+
+static int ucs_do_request_sense(struct ufs_dev *dev);
+
+int ucs_do_scsi_cmd(struct ufs_dev *dev, struct scsi_req_build_type *req)
+{
+ struct upiu_req_build_type req_upiu;
+ struct upiu_basic_hdr resp_upiu;
+ int ret;
+
+ memset(&req_upiu, 0 , sizeof(struct upiu_req_build_type));
+
+ req_upiu.cmd_set_type = UPIU_SCSI_CMD_SET;
+ req_upiu.trans_type = UPIU_TYPE_COMMAND;
+ req_upiu.data_buffer_addr = req->data_buffer_addr;
+ req_upiu.expected_data_len = req->data_len;
+ req_upiu.data_seg_len = 0;
+ req_upiu.ehs_len = 0;
+ req_upiu.flags = req->flags;
+ req_upiu.lun = req->lun;
+ req_upiu.query_mgmt_func = 0;
+ req_upiu.cdb = req->cdb;
+ req_upiu.cmd_type = UTRD_SCSCI_CMD;
+ req_upiu.dd = req->dd;
+ req_upiu.resp_ptr = &resp_upiu;
+ req_upiu.resp_len = sizeof(resp_upiu);
+ req_upiu.timeout_msecs = UTP_GENERIC_CMD_TIMEOUT;
+
+ if (utp_enqueue_upiu(dev, &req_upiu))
+ {
+ dprintf(CRITICAL, "Data read failed\n");
+ return -UFS_FAILURE;
+ }
+
+ if (resp_upiu.status != SCSI_STATUS_GOOD)
+ {
+ if (resp_upiu.status == SCSI_STATUS_CHK_COND && (*((uint8_t *)(req->cdb)) != SCSI_CMD_SENSE_REQ))
+ {
+ ret = ucs_do_request_sense(dev);
+ if (ret)
+ dprintf(CRITICAL, "SCSI request sense failed.\n");
+ }
+
+ dprintf(CRITICAL, "SCSI read failed. status = %x\n", resp_upiu.status);
+ return -UFS_FAILURE;
+ }
+
+ return UFS_SUCCESS;
+}
+
+int ucs_do_scsi_read(struct ufs_dev *dev, struct scsi_rdwr_req *req)
+{
+ STACKBUF_DMA_ALIGN(cdb, sizeof(struct scsi_rdwr_cdb));
+ struct scsi_req_build_type req_upiu;
+ struct scsi_rdwr_cdb *cdb_param;
+ uint32_t blks_remaining;
+ uint16_t blks_to_transfer;
+ uint64_t bytes_to_transfer;
+ uint32_t start_blk;
+ uint32_t buf;
+
+ blks_remaining = req->num_blocks;
+ buf = req->data_buffer_base;
+ start_blk = req->start_lba;
+
+ cdb_param = (struct scsi_rdwr_cdb*) cdb;
+ while (blks_remaining)
+ {
+ if (blks_remaining <= SCSI_MAX_DATA_TRANS_BLK_LEN)
+ {
+ blks_to_transfer = blks_remaining;
+ blks_remaining = 0;
+ }
+ else
+ {
+ blks_to_transfer = SCSI_MAX_DATA_TRANS_BLK_LEN;
+ blks_remaining -= SCSI_MAX_DATA_TRANS_BLK_LEN;
+ }
+
+ bytes_to_transfer = blks_to_transfer * UFS_DEFAULT_SECTORE_SIZE;
+
+ memset(cdb_param, 0, sizeof(struct scsi_rdwr_cdb));
+ cdb_param->opcode = SCSI_CMD_READ10;
+ cdb_param->cdb1 = SCSI_READ_WRITE_10_CDB1(0, 0, 1, 0);
+ cdb_param->lba = BE32(start_blk);
+ cdb_param->trans_len = BE16(blks_to_transfer);
+
+
+ dsb();
+ arch_clean_invalidate_cache_range((addr_t) cdb_param, sizeof(struct scsi_rdwr_cdb));
+
+ memset(&req_upiu, 0 , sizeof(struct scsi_req_build_type));
+
+ req_upiu.cdb = (addr_t) cdb_param;
+ req_upiu.data_buffer_addr = buf;
+ req_upiu.data_len = bytes_to_transfer;
+ req_upiu.flags = UPIU_FLAGS_READ;
+ req_upiu.lun = req->lun;
+ req_upiu.dd = UTRD_TARGET_TO_SYSTEM;
+
+ if (ucs_do_scsi_cmd(dev, &req_upiu))
+ {
+ dprintf(CRITICAL, "Data read failed\n");
+ return -UFS_FAILURE;
+ }
+
+ buf += bytes_to_transfer;
+ start_blk += SCSI_MAX_DATA_TRANS_BLK_LEN;
+ }
+
+ return UFS_SUCCESS;
+}
+
+int ucs_do_scsi_write(struct ufs_dev *dev, struct scsi_rdwr_req *req)
+{
+ struct scsi_req_build_type req_upiu;
+ STACKBUF_DMA_ALIGN(cdb, sizeof(struct scsi_rdwr_cdb));
+ struct scsi_rdwr_cdb *cdb_param;
+ uint32_t blks_remaining;
+ uint16_t blks_to_transfer;
+ uint64_t bytes_to_transfer;
+ uint32_t start_blk;
+ uint32_t buf;
+
+ blks_remaining = req->num_blocks;
+ buf = req->data_buffer_base;
+ start_blk = req->start_lba;
+
+ cdb_param = (struct scsi_rdwr_cdb*) cdb;
+ while (blks_remaining)
+ {
+ if (blks_remaining <= SCSI_MAX_DATA_TRANS_BLK_LEN)
+ {
+ blks_to_transfer = blks_remaining;
+ blks_remaining = 0;
+ }
+ else
+ {
+ blks_to_transfer = SCSI_MAX_DATA_TRANS_BLK_LEN;
+ blks_remaining -= SCSI_MAX_DATA_TRANS_BLK_LEN;
+ }
+
+ bytes_to_transfer = blks_to_transfer * UFS_DEFAULT_SECTORE_SIZE;
+
+ memset(cdb_param, 0, sizeof(struct scsi_rdwr_cdb));
+ cdb_param->opcode = SCSI_CMD_WRITE10;
+ cdb_param->cdb1 = SCSI_READ_WRITE_10_CDB1(0, 0, 1, 0);
+ cdb_param->lba = BE32(start_blk);
+ cdb_param->trans_len = BE16(blks_to_transfer);
+
+ /* Flush cdb to memory. */
+ dsb();
+ arch_clean_invalidate_cache_range((addr_t) cdb_param, sizeof(struct scsi_rdwr_cdb));
+
+ memset(&req_upiu, 0 , sizeof(struct scsi_req_build_type));
+
+ req_upiu.cdb = (addr_t) cdb_param;
+ req_upiu.data_buffer_addr = buf;
+ req_upiu.data_len = bytes_to_transfer;
+ req_upiu.flags = UPIU_FLAGS_WRITE;
+ req_upiu.lun = req->lun;
+ req_upiu.dd = UTRD_SYSTEM_TO_TARGET;
+
+ if (ucs_do_scsi_cmd(dev, &req_upiu))
+ {
+ dprintf(CRITICAL, "Data read failed\n");
+ return -UFS_FAILURE;
+ }
+
+ buf += bytes_to_transfer;
+ start_blk += SCSI_MAX_DATA_TRANS_BLK_LEN;
+ }
+
+ return UFS_SUCCESS;
+}
+
+int ucs_scsi_send_inquiry(struct ufs_dev *dev)
+{
+ STACKBUF_DMA_ALIGN(cdb_param, SCSI_CDB_PARAM_LEN);
+ STACKBUF_DMA_ALIGN(param, SCSI_INQUIRY_LEN);
+ struct scsi_req_build_type req_upiu;
+
+ memset(cdb_param, 0, SCSI_CDB_PARAM_LEN);
+ cdb_param[0] = SCSI_CMD_INQUIRY;
+ cdb_param[3] = sizeof(param)>> 8;
+ cdb_param[4] = sizeof(param);
+
+ /* Flush cdb to memory. */
+ dsb();
+ arch_invalidate_cache_range((addr_t) cdb_param, SCSI_CDB_PARAM_LEN);
+
+ memset(&req_upiu, 0 , sizeof(struct scsi_req_build_type));
+
+ req_upiu.cdb = (addr_t) cdb_param;
+ req_upiu.data_buffer_addr = (addr_t) param;
+ req_upiu.data_len = SCSI_INQUIRY_LEN;
+ req_upiu.flags = UPIU_FLAGS_READ;
+ req_upiu.lun = 0;
+ req_upiu.dd = UTRD_TARGET_TO_SYSTEM;
+
+ if (ucs_do_scsi_cmd(dev, &req_upiu))
+ {
+ dprintf(CRITICAL, "Failed to send SCSI inquiry\n");
+ return -UFS_FAILURE;
+ }
+
+ /* Flush buffer. */
+ arch_invalidate_cache_range((addr_t) param, SCSI_INQUIRY_LEN);
+
+ return UFS_SUCCESS;
+}
+
+static int ucs_do_request_sense(struct ufs_dev *dev)
+{
+ STACKBUF_DMA_ALIGN(cdb, sizeof(struct scsi_sense_cdb));
+ struct scsi_req_build_type req_upiu;
+ struct scsi_sense_cdb *cdb_param;
+ uint8_t buf[SCSI_SENSE_BUF_LEN];
+
+ cdb_param = cdb;
+
+ memset(cdb, 0, sizeof(struct scsi_sense_cdb));
+
+ cdb_param->opcode = SCSI_CMD_SENSE_REQ;
+ cdb_param->alloc_len = SCSI_SENSE_BUF_LEN;
+
+ /* Flush cdb to memory. */
+ dsb();
+ arch_invalidate_cache_range((addr_t) cdb_param, SCSI_CDB_PARAM_LEN);
+
+ memset(&req_upiu, 0 , sizeof(struct scsi_req_build_type));
+
+ req_upiu.cdb = (addr_t) cdb_param;
+ req_upiu.data_buffer_addr = (addr_t) buf;
+ req_upiu.data_len = SCSI_SENSE_BUF_LEN;
+ req_upiu.flags = UPIU_FLAGS_READ;
+ req_upiu.lun = 0;
+ req_upiu.dd = UTRD_TARGET_TO_SYSTEM;
+
+ if (ucs_do_scsi_cmd(dev, &req_upiu))
+ {
+ dprintf(CRITICAL, "Data read failed\n");
+ return -UFS_FAILURE;
+ }
+
+ /* Flush buffer. */
+ arch_invalidate_cache_range((addr_t) buf, SCSI_INQUIRY_LEN);
+
+ return UFS_SUCCESS;
+}
diff --git a/platform/msm_shared/ufs.c b/platform/msm_shared/ufs.c
new file mode 100644
index 0000000..b0470cd
--- /dev/null
+++ b/platform/msm_shared/ufs.c
@@ -0,0 +1,207 @@
+/* Copyright (c) 2013, The Linux Foundation. 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.
+ * * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * 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 <debug.h>
+#include <reg.h>
+#include <ufs_hw.h>
+#include <utp.h>
+#include <upiu.h>
+#include <uic.h>
+#include <ucs.h>
+#include <dme.h>
+#include <string.h>
+#include <platform/iomap.h>
+#include <kernel/mutex.h>
+
+static int ufs_dev_init(struct ufs_dev *dev)
+{
+ /* Init the mutexes. */
+ mutex_init(&(dev->uic_data.uic_mutex));
+ mutex_init(&(dev->utrd_data.bitmap_mutex));
+ mutex_init(&(dev->utmrd_data.bitmap_mutex));
+
+ /* Initialize wait lists. */
+ list_initialize(&(dev->utrd_data.list_head.list_node));
+ list_initialize(&(dev->utmrd_data.list_head.list_node));
+
+ /* Initialize the bitmaps. */
+ dev->utrd_data.bitmap = 0;
+ dev->utmrd_data.bitmap = 0;
+
+ /* Initialize task ids. */
+ dev->utrd_data.task_id = 0;
+ dev->utmrd_data.task_id = 0;
+
+ /* Allocate memory for lists. */
+ dev->utrd_data.list_base_addr = ufs_alloc_trans_req_list();
+ dev->utmrd_data.list_base_addr = ufs_alloc_task_mgmt_req_list();
+
+ if (!dev->utrd_data.list_base_addr || !dev->utmrd_data.list_base_addr)
+ return -UFS_FAILURE;
+
+ return UFS_SUCCESS;
+}
+
+static void ufs_setup_req_lists(struct ufs_dev *dev)
+{
+ uint32_t val;
+
+ writel(dev->utmrd_data.list_base_addr, UFS_UTMRLBA(dev->base));
+ writel(dev->utmrd_data.list_base_addr << 32, UFS_UTMRLBAU(dev->base));
+
+ writel(dev->utrd_data.list_base_addr, UFS_UTRLBA(dev->base));
+ writel(dev->utrd_data.list_base_addr << 32, UFS_UTRLBAU(dev->base));
+
+ writel(1, UFS_UTMRLRSR(dev->base));
+ writel(1, UFS_UTRLRSR(dev->base));
+
+ /* Enable the required irqs. */
+ val = UFS_IE_UTRCE | UFS_IE_UEE | UFS_IE_UTMRCE | UFS_IE_UCCE ;
+ ufs_irq_enable(dev, val);
+}
+
+int ufs_read(struct ufs_dev* dev, uint64_t start_lba, addr_t buffer, uint32_t num_blocks)
+{
+ struct scsi_rdwr_req req;
+ int ret;
+
+ req.data_buffer_base = buffer;
+ req.lun = 0;
+ req.num_blocks = num_blocks;
+ req.start_lba = start_lba / dev->block_size;
+
+ ret = ucs_do_scsi_read(dev, &req);
+ if (ret)
+ {
+ dprintf(CRITICAL, "UFS read failed.\n");
+ }
+
+ return ret;
+}
+
+int ufs_write(struct ufs_dev* dev, uint64_t start_lba, addr_t buffer, uint32_t num_blocks)
+{
+ struct scsi_rdwr_req req;
+ int ret;
+
+ req.data_buffer_base = buffer;
+ req.lun = 0;
+ req.num_blocks = num_blocks;
+ req.start_lba = start_lba / dev->block_size;
+
+ ret = ucs_do_scsi_write(dev, &req);
+ if (ret)
+ {
+ dprintf(CRITICAL, "UFS write failed.\n");
+ }
+
+ return ret;
+}
+uint64_t ufs_get_dev_capacity(struct ufs_dev* dev)
+{
+ uint64_t capacity;
+ int ret = 0;
+
+ ret = dme_read_unit_desc(dev, 0, &capacity);
+ if (ret)
+ {
+ dprintf(CRITICAL, "Failed to read unit descriptor\n");
+ }
+
+ return capacity;
+}
+
+uint32_t ufs_get_serial_num(struct ufs_dev* dev)
+{
+ int ret;
+
+ ret = dme_read_device_desc(dev);
+ if (ret)
+ {
+ dprintf(CRITICAL, "UFS get serial number failed.\n");
+ }
+
+ return dev->serial_num;
+}
+
+uint32_t ufs_get_page_size(struct ufs_dev* dev)
+{
+ return dev->block_size;
+}
+
+int ufs_init(struct ufs_dev *dev)
+{
+ uint32_t ret = UFS_SUCCESS;
+ uint64_t cap;
+
+ dev->block_size = 4096;
+
+ /* Init dev struct. */
+ ret = ufs_dev_init(dev);
+ if (ret != UFS_SUCCESS)
+ {
+ dprintf(CRITICAL, "UFS init failed\n");
+ goto ufs_init_err;
+ }
+
+ /* Perform Data link init. */
+ ret = uic_init(dev);
+ if (ret != UFS_SUCCESS)
+ {
+ dprintf(CRITICAL, "UFS init failed\n");
+ goto ufs_init_err;
+ }
+
+ /* Setup request lists. */
+ ufs_setup_req_lists(dev);
+
+ /* Send NOP to check if device UTP layer is ready. */
+ ret = dme_send_nop_query(dev);
+ if (ret != UFS_SUCCESS)
+ {
+ dprintf(CRITICAL, "UFS init failed\n");
+ goto ufs_init_err;
+ }
+
+ ret = dme_set_fdeviceinit(dev);
+ if (ret != UFS_SUCCESS)
+ {
+ dprintf(CRITICAL, "UFS init failed\n");
+ goto ufs_init_err;
+ }
+
+ ret = ucs_scsi_send_inquiry(dev);
+ if (ret != UFS_SUCCESS)
+ {
+ dprintf(CRITICAL, "UFS init failed\n");
+ goto ufs_init_err;
+ }
+
+ufs_init_err:
+ return ret;
+}
diff --git a/platform/msm_shared/ufs_hci.c b/platform/msm_shared/ufs_hci.c
new file mode 100644
index 0000000..479c0ff
--- /dev/null
+++ b/platform/msm_shared/ufs_hci.c
@@ -0,0 +1,174 @@
+/* Copyright (c) 2013, The Linux Foundation. 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.
+ * * Neither the name of The Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * 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 <stdlib.h>
+#include <arch/ops.h>
+#include <sys/types.h>
+#include <reg.h>
+#include <platform/interrupts.h>
+#include <platform/iomap.h>
+#include <platform/irqs.h>
+#include <ufs_hw.h>
+#include <utp.h>
+
+uint64_t ufs_alloc_trans_req_list()
+{
+ void *ptr;
+
+ ptr = memalign(lcm(CACHE_LINE, 1024), 32 * sizeof(struct utp_trans_req_desc));
+
+ if (!ptr)
+ {
+ dprintf(CRITICAL, "Failed to allocate utrd list.\n");
+ }
+
+ return (addr_t) ptr;
+}
+
+uint64_t ufs_alloc_task_mgmt_req_list()
+{
+ addr_t ptr = (addr_t) memalign(1024, 1024);
+
+ if (!ptr)
+ {
+ dprintf(CRITICAL, "Failed to allocate memory for Task mamagement request list.\n");
+ }
+
+ return ptr;
+}
+
+int ufs_enable_hci(struct ufs_dev *dev)
+{
+ int ret;
+
+ /* Enable host controller */
+ writel(UFS_HCE_ENABLE, UFS_HCE(dev->base));
+
+ /* Wait until host controller is enabled. */
+ ret = ufs_reg_target_val_timeout_loop(UFS_HCE(dev->base), 1, UFS_HCE_TIMEOUT);
+ if (ret)
+ {
+ dprintf(CRITICAL, "Failed to enable UFS host controller.\n");
+ }
+
+ return ret;
+}
+
+void ufs_irq_enable(struct ufs_dev *dev, uint32_t irq)
+{
+ /* Clear all irqs. */
+ writel(0xFFFFFFFF, UFS_IS(dev->base));
+
+ writel(irq, UFS_IE(dev->base));
+ register_int_handler(UFS_IRQ, ufs_irq_handler, dev);
+ unmask_interrupt(UFS_IRQ);
+}
+
+enum handler_return ufs_irq_handler(void* data)
+{
+ uint32_t val;
+ struct ufs_dev *dev = (struct ufs_dev *) data;
+ struct ufs_req_irq_type irq;
+
+ val = readl(UFS_IS(dev->base));
+
+ if (val & UFS_IS_SBFES || val & UFS_IS_HCFES || val & UFS_IS_UTPES || val & UFS_IS_DFES || val & UFS_IS_UE)
+ {
+ /* Controller might be in a bad state, unrecoverable error. */
+ dprintf(CRITICAL, "UFS error\n");
+ ASSERT(0);
+ }
+
+ while (val)
+ {
+ irq.irq_handled = 0;
+
+ if (val & UFS_IS_UCCS)
+ {
+ /* UIC command */
+ event_signal(&(dev->uic_data.uic_event), false);
+ /* Clear irq. */
+ writel(UFS_IS_UCCS, UFS_IS(dev->base));
+ val &= ~UFS_IS_UCCS;
+ irq.irq_handled = UFS_IS_UCCS;
+ continue;
+ }
+ else if (val & UFS_IS_UTRCS)
+ {
+ /* UTRD completion. */
+ irq.list = &(dev->utrd_data.list_head.list_node);
+ irq.irq_handled = UFS_IS_UTRCS;
+ irq.door_bell_reg = UFS_UTRLDBR(dev->base);
+
+ /* Clear irq. */
+ writel(irq.irq_handled, UFS_IS(dev->base));
+ val &= ~irq.irq_handled;
+
+ utp_process_req_completion(&irq);
+ }
+ else if (val & UFS_IS_UTMRCS)
+ {
+ /* UTMRD completion. */
+ irq.list = &(dev->utmrd_data.list_head.list_node);
+ irq.irq_handled = UFS_IS_UTMRCS;
+ /* TODO: Fill in door bell reg for management requests. */
+
+ /* Clear irq. */
+ writel(irq.irq_handled, UFS_IS(dev->base));
+ val &= ~irq.irq_handled;
+
+ utp_process_req_completion(&irq);
+ }
+ else
+ {
+ dprintf(CRITICAL, "Unknown irq.\n");
+ ASSERT(0);
+ }
+ }
+
+ return INT_NO_RESCHEDULE;
+}
+
+int ufs_reg_target_val_timeout_loop(uint32_t reg_addr, uint32_t target_val, uint32_t timeout)
+{
+ uint32_t try_again;
+ uint32_t val;
+
+ try_again = timeout;
+
+ do
+ {
+ try_again--;
+ val = readl(reg_addr);
+ } while (!(val & target_val) && try_again);
+
+ if (!(val & target_val))
+ return -UFS_FAILURE;
+ else
+ return UFS_SUCCESS;
+}
diff --git a/platform/msm_shared/uic.c b/platform/msm_shared/uic.c
new file mode 100644
index 0000000..3ba35b5
--- /dev/null
+++ b/platform/msm_shared/uic.c
Binary files differ
diff --git a/platform/msm_shared/utp.c b/platform/msm_shared/utp.c
new file mode 100644
index 0000000..c7d30ff
--- /dev/null
+++ b/platform/msm_shared/utp.c
Binary files differ
diff --git a/target/msm8226/include/target/display.h b/target/msm8226/include/target/display.h
index 1121591..62f0eac 100755
--- a/target/msm8226/include/target/display.h
+++ b/target/msm8226/include/target/display.h
@@ -98,7 +98,7 @@
#define msm8226_DSI_FEATURE_ENABLE 0
-#define MIPI_FB_ADDR 0x0F100000
+#define MIPI_FB_ADDR 0x03200000
#define MIPI_HSYNC_PULSE_WIDTH 12
#define MIPI_HSYNC_BACK_PORCH_DCLK 32
@@ -109,5 +109,4 @@
#define MIPI_VSYNC_FRONT_PORCH_LINES 9
extern int mdss_dsi_phy_init(struct mipi_dsi_panel_config *, uint32_t ctl_base);
-extern int mdss_dsi_uniphy_pll_config(uint32_t ctl_base);
#endif
diff --git a/target/msm8974/include/target/display.h b/target/msm8974/include/target/display.h
index ae2b01e..8897239 100644
--- a/target/msm8974/include/target/display.h
+++ b/target/msm8974/include/target/display.h
@@ -89,8 +89,8 @@
/* Other Configuration */
/*---------------------------------------------------------------------------*/
-#define MIPI_FB_ADDR 0x0D200000
-#define EDP_FB_ADDR 0x7EF00000
+#define MIPI_FB_ADDR 0x03200000
+#define EDP_FB_ADDR MIPI_FB_ADDR
#define MIPI_HSYNC_PULSE_WIDTH 12
#define MIPI_HSYNC_BACK_PORCH_DCLK 32
@@ -101,6 +101,5 @@
#define MIPI_VSYNC_FRONT_PORCH_LINES 9
extern int mdss_dsi_phy_init(struct mipi_dsi_panel_config *, uint32_t ctl_base);
-extern int mdss_dsi_uniphy_pll_config(uint32_t ctl_base);
#endif
diff --git a/target/msm8974/target_display.c b/target/msm8974/target_display.c
index 7b35aa0..e02ea22 100644
--- a/target/msm8974/target_display.c
+++ b/target/msm8974/target_display.c
@@ -126,11 +126,11 @@
if (enable) {
mdp_gdsc_ctrl(enable);
mdp_clock_init();
- mdss_dsi_uniphy_pll_config(MIPI_DSI0_BASE);
+ mdss_dsi_auto_pll_config(MIPI_DSI0_BASE, pll_data);
dsi_pll_enable_seq(MIPI_DSI0_BASE);
if (panel.panel_info.mipi.dual_dsi &&
!(panel.panel_info.mipi.broadcast)) {
- mdss_dsi_uniphy_pll_config(MIPI_DSI1_BASE);
+ mdss_dsi_auto_pll_config(MIPI_DSI1_BASE, pll_data);
dsi_pll_enable_seq(MIPI_DSI1_BASE);
}
mmss_clock_auto_pll_init(DSI0_PHY_PLL_OUT, dual_dsi,