platform: msm8909: Add SPI panel init function to support msm8909w
Add changes to:
1.add SPI panel transfer function
2.add SPI panel display config.
Change-Id: Id8387ee8dcd281af57bbec731a9fa009b5b0cb45
Signed-off-by: Wenjun Zhang <wjzhan@codeaurora.org>
diff --git a/platform/msm_shared/display.c b/platform/msm_shared/display.c
index 8733afa..cf4db48 100644
--- a/platform/msm_shared/display.c
+++ b/platform/msm_shared/display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2016, 2018 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
@@ -125,6 +125,15 @@
if (ret)
goto msm_display_config_out;
break;
+ case SPI_PANEL:
+ dprintf(INFO, "Config SPI PANEL.\n");
+ ret = mdss_spi_init();
+ if (ret)
+ goto msm_display_config_out;
+ ret = mdss_spi_panel_init(pinfo);
+ if (ret)
+ goto msm_display_config_out;
+ break;
case HDMI_PANEL:
dprintf(INFO, "Config HDMI PANEL.\n");
ret = mdss_hdmi_config(pinfo, &(panel->fb));
@@ -243,6 +252,12 @@
if (ret)
goto msm_display_on_out;
break;
+ case SPI_PANEL:
+ dprintf(INFO, "Turn on SPI_PANEL.\n");
+ ret = mdss_spi_on(pinfo, &(panel->fb));
+ if (ret)
+ goto msm_display_on_out;
+ break;
#endif
#ifdef DISPLAY_TYPE_QPIC
case QPIC_PANEL:
diff --git a/platform/msm_shared/include/mdp4.h b/platform/msm_shared/include/mdp4.h
index e463302..8bbb3a7 100644
--- a/platform/msm_shared/include/mdp4.h
+++ b/platform/msm_shared/include/mdp4.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011-2016, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2011-2016, 2018 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
@@ -124,4 +124,8 @@
int mdss_hdmi_on(struct msm_panel_info *pinfo);
int mdss_hdmi_off(struct msm_panel_info *pinfo);
int mdss_hdmi_config(struct msm_panel_info *pinfo, struct fbcon_config *fb);
+
+int mdss_spi_init(void);
+int mdss_spi_panel_init(struct msm_panel_info *pinfo);
+int mdss_spi_on(struct msm_panel_info *pinfo, struct fbcon_config *fb);
#endif
diff --git a/platform/msm_shared/include/qup.h b/platform/msm_shared/include/qup.h
index 8a1a825..5253b4c 100755
--- a/platform/msm_shared/include/qup.h
+++ b/platform/msm_shared/include/qup.h
@@ -31,6 +31,9 @@
#include <stdint.h>
+#define MAX_READ_SPEED_HZ 9600000
+#define MAX_SPEED_HZ 50000000
+
/* QUP_IO_MODES fields */
#define QUP_IO_MODES_OUTPUT_BIT_SHIFT_EN 0x00010000
#define QUP_IO_MODES_PACK_EN 0x00008000
@@ -89,6 +92,7 @@
* And make the count be multiple of max bytes per word.
*/
#define MAX_QUP_MX_OUTPUT_COUNT 0xFFF8
+#define MAX_QUP_MX_TRANSFER_COUNT 0xFFF8
/* QUP Registers */
enum {
@@ -104,6 +108,7 @@
QUP_HW_VERSION = 0x30,
QUP_MX_READ_CNT = 0x208,
QUP_MX_INPUT_CNT = 0x200,
+ QUP_MX_INPUT_CNT_CURRENT = 0x204,
QUP_MX_OUTPUT_CNT = 0x100,
QUP_MX_OUTPUT_CNT_CURRENT = 0x104,
QUP_OUTPUT_DEBUG = 0x108,
diff --git a/platform/msm_shared/include/spi_qup.h b/platform/msm_shared/include/spi_qup.h
index 27731d7..b91ab5c 100755
--- a/platform/msm_shared/include/spi_qup.h
+++ b/platform/msm_shared/include/spi_qup.h
@@ -64,6 +64,7 @@
#define SPI_IO_C_CS0_ACTIVE_HIGH BIT(4)
#define SPI_IO_C_CS_SELECT_CS0 00 << 2
#define SPI_IO_C_CLK_IDLE_HIGH BIT(10)
+#define SPI_IO_C_FORCE_CS BIT(11)
/* SPI_CONFIG fields */
#define SPI_CONFIG_HS_MODE BIT(10)
@@ -85,6 +86,8 @@
struct spi_transfer {
const unsigned char *tx_buf;
int len;
+ unsigned char *rx_buf;
+ unsigned int speed_hz;
};
/**
@@ -99,10 +102,14 @@
unsigned int qup_base;
int qup_irq;
int tx_bytes;
+ int rx_bytes;
unsigned int bytes_per_word;
unsigned int bit_shift_en;
unsigned int unpack_en;
struct spi_transfer *xfer;
+ unsigned int max_speed_hz;
+ uint8_t blsp_id;
+ uint8_t qup_id;
};
/* Function Definitions */
diff --git a/platform/msm_shared/mdss_spi.c b/platform/msm_shared/mdss_spi.c
new file mode 100644
index 0000000..4819478
--- /dev/null
+++ b/platform/msm_shared/mdss_spi.c
@@ -0,0 +1,173 @@
+/* Copyright (c) 2017-2018 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 <spi_qup.h>
+#include <msm_panel.h>
+#include <target/display.h>
+#include <platform/gpio.h>
+
+#define SUCCESS 0
+#define FAIL 1
+
+static struct qup_spi_dev *dev = NULL;
+
+static int mdss_spi_write_cmd(const char *buf)
+{
+ int ret = 0;
+
+ if (!dev) {
+ dprintf(CRITICAL, "SPI has not been initialized\n");
+ return -ENODEV;
+ }
+
+ dev->bytes_per_word = 1;
+ dev->bit_shift_en = 1;
+
+ gpio_set(spi_dc_gpio.pin_id, 0);
+ ret = spi_qup_transfer(dev, buf, 1);
+ gpio_set(spi_dc_gpio.pin_id, 2);
+ if (ret)
+ dprintf(CRITICAL, "Send SPI command to panel failed\n");
+
+ return ret;
+}
+
+static int mdss_spi_write_data(const char *buf, size_t len)
+{
+ int ret = 0;
+
+ if (!dev) {
+ dprintf(CRITICAL, "SPI has not been initialized\n");
+ return -ENODEV;
+ }
+
+ dev->bytes_per_word = 1;
+ dev->bit_shift_en = 1;
+
+ gpio_set(spi_dc_gpio.pin_id, 2);
+ ret = spi_qup_transfer(dev, buf, len);
+ if (ret)
+ dprintf(CRITICAL, "Send SPI parameters to panel failed\n");
+
+ return ret;
+}
+
+static int mdss_spi_write_frame(const char *buf, size_t len)
+{
+ int ret = 0;
+
+ if (!dev) {
+ dprintf(CRITICAL, "SPI has not been initialized\n");
+ return -ENODEV;
+ }
+
+ dev->bytes_per_word = 2;
+ dev->bit_shift_en = 1;
+ dev->unpack_en = 0;
+
+ gpio_set(spi_dc_gpio.pin_id, 2);
+ ret = spi_qup_transfer(dev, buf, len);
+
+ return ret;
+}
+
+static void spi_read_panel_data(unsigned char *buf, int len)
+{
+ int ret = 0;
+
+ if (!dev) {
+ dprintf(CRITICAL, "SPI has not been initialized\n");
+ return -ENODEV;
+ }
+ dev->bytes_per_word = 1;
+ dev->bit_shift_en = 1;
+
+ gpio_set(spi_dc_gpio.pin_id, 0);
+ ret = spi_qup_transfer(dev, buf, len);
+ gpio_set(spi_dc_gpio.pin_id, 2);
+
+ if (ret)
+ dprintf(CRITICAL, "Send SPI command to panel failed\n");
+
+ return;
+}
+
+int mdss_spi_init(void)
+{
+ if (!dev) {
+ dev = qup_blsp_spi_init(SPI_BLSP_ID, SPI_QUP_ID);
+ if (!dev) {
+ dprintf(CRITICAL, "Failed initializing SPI\n");
+ return -ENODEV;
+ }
+ }
+
+ gpio_tlmm_config(spi_dc_gpio.pin_id, 0, spi_dc_gpio.pin_direction,
+ spi_dc_gpio.pin_pull, spi_dc_gpio.pin_strength,
+ spi_dc_gpio.pin_state);
+ return SUCCESS;
+}
+
+int mdss_spi_panel_init(struct msm_panel_info *pinfo)
+{
+ int cmd_count = 0;
+ int ret = 0;
+
+ while (cmd_count < pinfo->spi.num_of_panel_cmds) {
+ if (pinfo->spi.panel_cmds[cmd_count].cmds_post_tg){
+ cmd_count ++;
+ continue;
+ }
+
+ mdss_spi_write_cmd(pinfo->spi.panel_cmds[cmd_count].payload);
+ if (pinfo->spi.panel_cmds[cmd_count].size > 1)
+ mdss_spi_write_data(
+ pinfo->spi.panel_cmds[cmd_count].payload + 1,
+ pinfo->spi.panel_cmds[cmd_count].size - 1);
+
+ if (pinfo->spi.panel_cmds[cmd_count].wait)
+ mdelay(pinfo->spi.panel_cmds[cmd_count].wait);
+
+ cmd_count ++;
+ }
+ return SUCCESS;
+}
+
+int mdss_spi_on(struct msm_panel_info *pinfo, struct fbcon_config *fb)
+{
+ int buf_size = 0;
+ int ret = 0;
+
+ buf_size = fb->width * fb->height * (fb->bpp / 8);
+ ret = mdss_spi_write_frame(fb->base, buf_size);
+ if (ret)
+ dprintf(CRITICAL, "Send SPI frame data to panel failed\n");
+
+ return ret;
+}
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index 69a0b15..f8460ff 100755
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -531,7 +531,8 @@
$(LOCAL_DIR)/mipi_dsi.o \
$(LOCAL_DIR)/mipi_dsi_phy.o \
$(LOCAL_DIR)/flash-ubi.o \
- $(LOCAL_DIR)/mipi_dsi_autopll.o
+ $(LOCAL_DIR)/mipi_dsi_autopll.o\
+ $(LOCAL_DIR)/mdss_spi.o
endif
ifeq ($(PLATFORM),mdm9607)
diff --git a/target/target_display.c b/target/target_display.c
index 6904825..d32e90d 100644
--- a/target/target_display.c
+++ b/target/target_display.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2015,2018 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
@@ -131,3 +131,18 @@
{
return 0;
}
+
+__WEAK int mdss_spi_init(void)
+{
+ return 0;
+}
+
+__WEAK int mdss_spi_panel_init(struct msm_panel_info *pinfo)
+{
+ return 0;
+}
+
+__WEAK int mdss_spi_on(struct msm_panel_info *pinfo, struct fbcon_config *fb)
+{
+ return 0;
+}