Merge "dev: pm8x41: Re-write the enable mpp as ADC api"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 42b2179..0b9fd12 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -177,6 +177,8 @@
static device_info device = {DEVICE_MAGIC, 0, 0, 0, 0, {0}, {0},{0}};
static bool is_allow_unlock = 0;
+static char frp_ptns[2][8] = {"config","frp"};
+
struct atag_ptbl_entry
{
char name[16];
@@ -1586,7 +1588,6 @@
static int read_allow_oem_unlock(device_info *dev)
{
- const char *ptn_name = "frp";
unsigned offset;
int index;
unsigned long long ptn;
@@ -1594,11 +1595,15 @@
unsigned blocksize = mmc_get_device_blocksize();
char buf[blocksize];
- index = partition_get_index(ptn_name);
+ index = partition_get_index(frp_ptns[0]);
if (index == INVALID_PTN)
{
- dprintf(CRITICAL, "No '%s' partition found\n", ptn_name);
- return -1;
+ index = partition_get_index(frp_ptns[1]);
+ if (index == INVALID_PTN)
+ {
+ dprintf(CRITICAL, "Neither '%s' nor '%s' partition found\n", frp_ptns[0],frp_ptns[1]);
+ return -1;
+ }
}
ptn = partition_get_offset(index);
@@ -1618,20 +1623,22 @@
static int write_allow_oem_unlock(bool allow_unlock)
{
- const char *ptn_name = "frp";
unsigned offset;
-
int index;
unsigned long long ptn;
unsigned long long ptn_size;
unsigned blocksize = mmc_get_device_blocksize();
char buf[blocksize];
- index = partition_get_index(ptn_name);
+ index = partition_get_index(frp_ptns[0]);
if (index == INVALID_PTN)
{
- dprintf(CRITICAL, "No '%s' partition found\n", ptn_name);
- return -1;
+ index = partition_get_index(frp_ptns[1]);
+ if (index == INVALID_PTN)
+ {
+ dprintf(CRITICAL, "Neither '%s' nor '%s' partition found\n", frp_ptns[0],frp_ptns[1]);
+ return -1;
+ }
}
ptn = partition_get_offset(index);
@@ -1753,7 +1760,7 @@
if (is_secure_boot_enable())
info->is_unlocked = 0;
else
- info->is_verified = 1;
+ info->is_unlocked = 1;
info->is_tampered = 0;
info->charger_screen_enabled = 0;
write_device_info(info);
diff --git a/arch/arm/include/arch/defines.h b/arch/arm/include/arch/defines.h
index 6f0985a..ffa766f 100644
--- a/arch/arm/include/arch/defines.h
+++ b/arch/arm/include/arch/defines.h
@@ -1,7 +1,7 @@
/*
* Copyright (c) 2008 Travis Geiselbrecht
*
- * Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files
@@ -36,6 +36,8 @@
#define CACHE_LINE 32
#elif defined(ARM_CPU_CORE_KRAIT) || defined(ARM_CPU_CORE_A7)
#define CACHE_LINE 64
+#elif defined(ARM_CPU_CORE_KRYO)
+ #define CACHE_LINE 128
#else
#error unknown cpu
#endif
diff --git a/dev/gcdb/display/fastboot_oem_display.h b/dev/gcdb/display/fastboot_oem_display.h
index 7492d2f..9dd8b5c 100644
--- a/dev/gcdb/display/fastboot_oem_display.h
+++ b/dev/gcdb/display/fastboot_oem_display.h
@@ -30,9 +30,14 @@
#ifndef _FASTBOOT_OEM_DISPLAY_H_
#define _FASTBOOT_OEM_DISPLAY_H_
-/*---------------------------------------------------------------------------*/
-/* Lookup table for skip panels */
-/*---------------------------------------------------------------------------*/
+#define SIM_OVERRIDE_LEN 10
+
+enum {
+ SIM_NONE,
+ SIM_MODE,
+ SIM_SWTE,
+ SIM_HWTE,
+};
struct panel_lookup_list {
char name[MAX_PANEL_ID_LEN];
@@ -40,6 +45,15 @@
bool is_split_dsi;
};
+struct sim_lookup_list {
+ uint32_t sim_mode;
+ char override_string[SIM_OVERRIDE_LEN];
+};
+
+/*---------------------------------------------------------------------------*/
+/* Lookup table for skip panels */
+/*---------------------------------------------------------------------------*/
+
struct panel_lookup_list lookup_skip_panels[] = {
{"adv7533_1080p_video", "qcom,mdss_dsi_adv7533_1080p60_video", false},
{"adv7533_720p_video", "qcom,mdss_dsi_adv7533_720p60_video", false},
@@ -89,4 +103,10 @@
{"truly_wvga_video", "qcom,mdss_dsi_truly_wvga_video", false},
};
+struct sim_lookup_list lookup_sim[] = {
+ {SIM_MODE, "sim"},
+ {SIM_SWTE, "sim-swte"},
+ {SIM_HWTE, "sim-hwte"},
+};
+
#endif /*_FASTBOOT_OEM_DISPLAY_H_ */
diff --git a/dev/gcdb/display/gcdb_display.c b/dev/gcdb/display/gcdb_display.c
index bfb1153..d4fe865 100644
--- a/dev/gcdb/display/gcdb_display.c
+++ b/dev/gcdb/display/gcdb_display.c
@@ -408,6 +408,45 @@
return panelstruct;
}
+static void mdss_dsi_set_pll_src(void)
+{
+ struct oem_panel_data *oem_data = mdss_dsi_get_oem_data_ptr();
+
+ if (panelstruct.paneldata->panel_operating_mode & USE_DSI1_PLL_FLAG)
+ oem_data->dsi_pll_src = DSI_PLL1;
+
+ if (strcmp(oem_data->sec_panel, "")) {
+ if (oem_data->dsi_pll_src != DSI_PLL_DEFAULT) {
+ dprintf(CRITICAL, "Dual DSI config detected!"
+ "Use default PLL\n");
+ oem_data->dsi_pll_src = DSI_PLL_DEFAULT;
+ }
+ } else if (panelstruct.paneldata->slave_panel_node_id) {
+ if((dsi_video_mode_phy_db.pll_type != DSI_PLL_TYPE_THULIUM)
+ && (oem_data->dsi_pll_src == DSI_PLL1)) {
+ dprintf(CRITICAL, "Split DSI on 28nm/20nm!"
+ "Use DSI PLL0\n");
+ oem_data->dsi_pll_src = DSI_PLL0;
+ }
+ } else {
+ if ((dsi_video_mode_phy_db.pll_type != DSI_PLL_TYPE_THULIUM)
+ && !strcmp(panelstruct.paneldata->panel_destination,
+ "DISPLAY_1") && (oem_data->dsi_pll_src == DSI_PLL1)) {
+ dprintf(CRITICAL, "Single DSI with DSI-0 on 28nm/20nm!"
+ "Use DSI PLL0\n");
+ oem_data->dsi_pll_src = DSI_PLL0;
+ }
+ }
+
+ if (oem_data->dsi_pll_src == DSI_PLL1)
+ panelstruct.paneldata->panel_operating_mode |=
+ USE_DSI1_PLL_FLAG;
+ else
+ panelstruct.paneldata->panel_operating_mode &=
+ ~USE_DSI1_PLL_FLAG;
+
+}
+
int gcdb_display_init(const char *panel_name, uint32_t rev, void *base)
{
int ret = NO_ERROR;
@@ -419,6 +458,7 @@
if (pan_type == PANEL_TYPE_DSI) {
target_dsi_phy_config(&dsi_video_mode_phy_db);
+ mdss_dsi_set_pll_src();
if (dsi_panel_init(&(panel.panel_info), &panelstruct)) {
dprintf(CRITICAL, "DSI panel init failed!\n");
ret = ERROR;
diff --git a/dev/gcdb/display/gcdb_display.h b/dev/gcdb/display/gcdb_display.h
index 1fbc2f7..088aa05 100755
--- a/dev/gcdb/display/gcdb_display.h
+++ b/dev/gcdb/display/gcdb_display.h
@@ -43,6 +43,8 @@
#define BIST_SIZE 6
#define LANE_SIZE 45
+#define DSI_CFG_SIZE 15
+
/*---------------------------------------------------------------------------*/
/* API */
/*---------------------------------------------------------------------------*/
@@ -62,12 +64,23 @@
struct msm_panel_info *pinfo, struct mdss_dsi_phy_ctrl *phy_db);
void set_panel_cmd_string(const char *panel_name);
struct oem_panel_data mdss_dsi_get_oem_data(void);
+struct oem_panel_data *mdss_dsi_get_oem_data_ptr(void);
struct panel_struct mdss_dsi_get_panel_data(void);
struct oem_panel_data {
char panel[MAX_PANEL_ID_LEN];
+ char sec_panel[MAX_PANEL_ID_LEN];
bool cont_splash;
bool skip;
+ uint32_t sim_mode;
+ char dsi_config[DSI_CFG_SIZE];
+ uint32_t dsi_pll_src;
+};
+
+enum {
+ DSI_PLL_DEFAULT,
+ DSI_PLL0,
+ DSI_PLL1,
};
#endif /*_GCDB_DISPLAY_H_ */
diff --git a/dev/gcdb/display/gcdb_display_param.c b/dev/gcdb/display/gcdb_display_param.c
index 027207c..ce98cf0 100644
--- a/dev/gcdb/display/gcdb_display_param.c
+++ b/dev/gcdb/display/gcdb_display_param.c
@@ -37,38 +37,47 @@
#include "target/display.h"
#include "fastboot_oem_display.h"
-struct oem_panel_data oem_data = {{'\0'}, false, false};
+struct oem_panel_data oem_data = {{'\0'}, {'\0'}, false, false, SIM_NONE, "single_dsi", DSI_PLL_DEFAULT};
-void panel_name_to_dt_string(struct panel_lookup_list supp_panels[],
+static int panel_name_to_dt_string(struct panel_lookup_list supp_panels[],
uint32_t supp_panels_size,
- const char *panel_name, char **panel_node,
- char **slave_panel_node, int *panel_mode)
+ const char *panel_name, char **panel_node)
{
uint32_t i;
if (!panel_name) {
dprintf(CRITICAL, "Invalid panel name\n");
- return;
+ return ERR_NOT_VALID;
}
for (i = 0; i < supp_panels_size; i++) {
if (!strncmp(panel_name, supp_panels[i].name,
MAX_PANEL_ID_LEN)) {
*panel_node = supp_panels[i].panel_dt_string;
- if (supp_panels[i].is_split_dsi) {
- *slave_panel_node =
- supp_panels[i].panel_dt_string;
- *panel_mode = DUAL_DSI_FLAG;
- } else {
- *panel_mode = 0;
- }
+ return supp_panels[i].is_split_dsi;
+ }
+ }
+
+ dprintf(CRITICAL, "Panel_name:%s not found in lookup table\n",
+ panel_name);
+ return ERR_NOT_FOUND;
+}
+
+void sim_override_to_cmdline(struct sim_lookup_list sim[],
+ uint32_t sim_size, uint32_t sim_mode,
+ char **sim_string)
+{
+ uint32_t i;
+
+ for (i = 0; i < sim_size; i++) {
+ if (sim_mode == sim[i].sim_mode) {
+ *sim_string = sim[i].override_string;
break;
}
}
- if (i == supp_panels_size)
- dprintf(CRITICAL, "Panel_name:%s not found in lookup table\n",
- panel_name);
+ if (i == sim_size)
+ dprintf(CRITICAL, "Sim_mode not found in lookup table\n");
}
struct oem_panel_data mdss_dsi_get_oem_data(void)
@@ -76,21 +85,106 @@
return oem_data;
}
+struct oem_panel_data *mdss_dsi_get_oem_data_ptr(void)
+{
+ return &oem_data;
+}
+
+static char *get_panel_token_end(const char *string)
+{
+ char *ch_hash = NULL, *ch_col = NULL;
+
+ /* ':' and '#' are delimiters in the string */
+ ch_col = strchr((char *) string, ':');
+ ch_hash = strchr((char *) string, '#');
+
+ if (ch_col && ch_hash)
+ return ((ch_col < ch_hash) ? ch_col : ch_hash);
+ else if (ch_col)
+ return ch_col;
+ else if (ch_hash)
+ return ch_hash;
+ return NULL;
+}
+
void set_panel_cmd_string(const char *panel_name)
{
- char *ch = NULL;
+ char *ch = NULL, *ch_tmp = NULL;
int i;
panel_name += strspn(panel_name, " ");
- /* Panel string */
- ch = strchr((char *) panel_name, ':');
+ /* Primary panel string */
+ ch = strstr((char *) panel_name, "prim:");
if (ch) {
- for (i = 0; (panel_name + i) < ch; i++)
- oem_data.panel[i] = *(panel_name + i);
+ /*
+ * Parse the primary panel for cases where 'prim' prefix
+ * is present in the fastboot oem command before primary
+ * panel string.
+ * Examples:
+ * 1.) fastboot oem select-display-panel prim:jdi_1080p_video:sec:sharp_1080p_cmd
+ * 2.) fastboot oem select-display-panel prim:jdi_1080p_video:skip:sec:sharp_1080p_cmd
+ * 3.) fastboot oem select-display-panel prim:jdi_1080p_video:disable:sec:sharp_1080p_cmd
+ * 4.) fastboot oem select-display-panel prim:jdi_1080p_video:skip#sim:sec:sharp_1080p_cmd
+ */
+ ch += 5;
+ ch_tmp = get_panel_token_end((const char*) ch);
+ if (!ch_tmp)
+ ch_tmp = ch + strlen(ch);
+ for (i = 0; (ch + i) < ch_tmp; i++)
+ oem_data.panel[i] = *(ch + i);
oem_data.panel[i] = '\0';
} else {
- strlcpy(oem_data.panel, panel_name, MAX_PANEL_ID_LEN);
+ /*
+ * Check if secondary panel string is present.
+ * The 'prim' prefix definitely needs to be present
+ * to specify primary panel for cases where secondary panel
+ * is also specified in fastboot oem command. Otherwise, it
+ * becomes tough to parse the fastboot oem command for primary
+ * panel. If 'sec' prefix is used without 'prim' prefix, it
+ * means the default panel needs to be picked as primary panel.
+ * Example:
+ * fastboot oem select-display-panel sec:sharp_1080p_cmd
+ */
+ ch = strstr((char *) panel_name, "sec:");
+ if (!ch) {
+ /*
+ * This code will be executed for cases where the
+ * secondary panel is not specified i.e., single/split
+ * DSI cases.
+ * Examples:
+ * 1.) fastboot oem select-display-panel jdi_1080p_video
+ * 2.) fastboot oem select-display-panel sharp_1080p_cmd:skip
+ * 3.) fastboot oem select-display-panel sharp_1080p_cmd:disable
+ * 4.) fastboot oem select-display-panel sim_cmd_panel#sim-swte
+ */
+ ch = get_panel_token_end(panel_name);
+ if (ch) {
+ for (i = 0; (panel_name + i) < ch; i++)
+ oem_data.panel[i] =
+ *(panel_name + i);
+ oem_data.panel[i] = '\0';
+ } else {
+ strlcpy(oem_data.panel, panel_name,
+ MAX_PANEL_ID_LEN);
+ }
+ }
+ }
+
+ /*
+ * Secondary panel string.
+ * This is relatively simple. The secondary panel string gets
+ * parsed if the 'sec' prefix is present.
+ */
+ ch = strstr((char *) panel_name, "sec:");
+ if (ch) {
+ ch += 4;
+ ch_tmp = get_panel_token_end((const char*) ch);
+ if (!ch_tmp)
+ ch_tmp = ch + strlen(ch);
+ for (i = 0; (ch + i) < ch_tmp; i++)
+ oem_data.sec_panel[i] = *(ch + i);
+ oem_data.sec_panel[i] = '\0';
}
/* Skip LK configuration */
@@ -100,11 +194,33 @@
/* Cont. splash status */
ch = strstr((char *) panel_name, ":disable");
oem_data.cont_splash = ch ? false : true;
+
+ /* DSI PLL source */
+ ch = strstr((char *) panel_name, ":pll0");
+ if (ch) {
+ oem_data.dsi_pll_src = DSI_PLL0;
+ } else {
+ ch = strstr((char *) panel_name, ":pll1");
+ if (ch)
+ oem_data.dsi_pll_src = DSI_PLL1;
+ }
+
+ /* Simulator status */
+ oem_data.sim_mode = SIM_NONE;
+ if (strstr((char *) panel_name, "#sim-hwte"))
+ oem_data.sim_mode = SIM_HWTE;
+ else if (strstr((char *) panel_name, "#sim-swte"))
+ oem_data.sim_mode = SIM_SWTE;
+ else if (strstr((char *) panel_name, "#sim"))
+ oem_data.sim_mode = SIM_MODE;
+
}
static bool mdss_dsi_set_panel_node(char *panel_name, char **dsi_id,
char **panel_node, char **slave_panel_node, int *panel_mode)
{
+ int rc = 0;
+
if (!strcmp(panel_name, SIM_VIDEO_PANEL)) {
*dsi_id = SIM_DSI_ID;
*panel_node = SIM_VIDEO_PANEL_NODE;
@@ -126,12 +242,21 @@
} else if (oem_data.skip) {
/* For skip panel case, check the lookup table */
*dsi_id = SIM_DSI_ID;
- panel_name_to_dt_string(lookup_skip_panels,
+ rc = panel_name_to_dt_string(lookup_skip_panels,
ARRAY_SIZE(lookup_skip_panels), panel_name,
- panel_node, slave_panel_node, panel_mode);
+ panel_node);
+ if (rc < 0) {
+ return false;
+ } else if (rc == 1) {
+ *slave_panel_node = *panel_node;
+ *panel_mode = DUAL_DSI_FLAG;
+ } else {
+ *panel_mode = 0;
+ }
} else {
return false;
}
+
return true;
}
@@ -140,15 +265,16 @@
char *dsi_id = NULL;
char *panel_node = NULL;
char *slave_panel_node = NULL;
+ char *sim_mode_string = NULL;
uint16_t dsi_id_len = 0, panel_node_len = 0, slave_panel_node_len = 0;
uint32_t arg_size = 0;
- bool ret = true;
- bool rc;
+ bool ret = true, rc;
+ int ret_val;
char *default_str;
struct panel_struct panelstruct;
int panel_mode = SPLIT_DISPLAY_FLAG | DUAL_PIPE_FLAG | DST_SPLIT_FLAG;
int prefix_string_len = strlen(DISPLAY_CMDLINE_PREFIX);
- char *sctl_string;
+ char *sctl_string, *pll_src_string = NULL;
panelstruct = mdss_dsi_get_panel_data();
@@ -196,13 +322,44 @@
return false;
}
+ if (oem_data.sec_panel) {
+ if (panel_mode & (DUAL_DSI_FLAG | SPLIT_DISPLAY_FLAG |
+ DST_SPLIT_FLAG)) {
+ dprintf(CRITICAL, "Invalid config: Primary panel is"
+ "split DSI and still secondary panel passed\n");
+ } else {
+ ret_val = panel_name_to_dt_string(lookup_skip_panels,
+ ARRAY_SIZE(lookup_skip_panels), oem_data.sec_panel,
+ &slave_panel_node);
+ if (ret_val < 0) {
+ dprintf(CRITICAL, "Sec. panel not found."
+ " Continue with primary panel\n");
+ } else if (ret_val == 1) {
+ dprintf(CRITICAL, "Invalid config: Secondary panel cant"
+ "be split DSI. Continue with primary panel\n");
+ slave_panel_node = NULL;
+ }
+ }
+ }
+
+ /* Check for the DSI configuration */
+ if (slave_panel_node && (panel_mode & (DUAL_DSI_FLAG |
+ SPLIT_DISPLAY_FLAG | DST_SPLIT_FLAG)))
+ strcpy(oem_data.dsi_config, "split_dsi");
+ else if (slave_panel_node)
+ strcpy(oem_data.dsi_config, "dual_dsi");
+ else
+ strcpy(oem_data.dsi_config, "single_dsi");
+
+ arg_size = DSI_CFG_STRING_LEN + strlen(oem_data.dsi_config);
+
dsi_id_len = strlen(dsi_id);
panel_node_len = strlen(panel_node);
if (!slave_panel_node || !strcmp(slave_panel_node, ""))
slave_panel_node = NO_PANEL_CONFIG;
slave_panel_node_len = strlen(slave_panel_node);
- arg_size = prefix_string_len + dsi_id_len + panel_node_len +
+ arg_size += prefix_string_len + dsi_id_len + panel_node_len +
LK_OVERRIDE_PANEL_LEN + 1;
if (panelstruct.paneldata &&
@@ -213,6 +370,35 @@
arg_size += strlen(sctl_string) + slave_panel_node_len;
+ if (oem_data.skip && !strcmp(oem_data.dsi_config, "dual_dsi") &&
+ (oem_data.dsi_pll_src != DSI_PLL_DEFAULT)) {
+ dprintf(CRITICAL, "Dual DSI config detected!"
+ " Use default PLL\n");
+ oem_data.dsi_pll_src = DSI_PLL_DEFAULT;
+ }
+
+ if (oem_data.dsi_pll_src != DSI_PLL_DEFAULT) {
+ if (oem_data.dsi_pll_src == DSI_PLL0)
+ pll_src_string = DSI_PLL0_STRING;
+ else
+ pll_src_string = DSI_PLL1_STRING;
+
+ arg_size += strlen(pll_src_string);
+ }
+
+ if (oem_data.sim_mode != SIM_NONE) {
+ sim_override_to_cmdline(lookup_sim,
+ ARRAY_SIZE(lookup_sim), oem_data.sim_mode,
+ &sim_mode_string);
+ if (sim_mode_string) {
+ arg_size += LK_SIM_OVERRIDE_LEN +
+ strlen(sim_mode_string);
+ } else {
+ dprintf(CRITICAL, "SIM string NULL but mode is not NONE\n");
+ return false;
+ }
+ }
+
if (buf_size < arg_size) {
dprintf(CRITICAL, "display command line buffer is small\n");
ret = false;
@@ -230,14 +416,40 @@
buf_size -= dsi_id_len;
strlcpy(pbuf, panel_node, buf_size);
-
pbuf += panel_node_len;
buf_size -= panel_node_len;
strlcpy(pbuf, sctl_string, buf_size);
pbuf += strlen(sctl_string);
buf_size -= strlen(sctl_string);
+
strlcpy(pbuf, slave_panel_node, buf_size);
+ pbuf += slave_panel_node_len;
+ buf_size -= slave_panel_node_len;
+
+ strlcpy(pbuf, DSI_CFG_STRING, buf_size);
+ pbuf += DSI_CFG_STRING_LEN;
+ buf_size -= DSI_CFG_STRING_LEN;
+
+ strlcpy(pbuf, oem_data.dsi_config, buf_size);
+ pbuf += strlen(oem_data.dsi_config);
+ buf_size -= strlen(oem_data.dsi_config);
+
+ if (pll_src_string) {
+ strlcpy(pbuf, pll_src_string, buf_size);
+ pbuf += strlen(pll_src_string);
+ buf_size -= strlen(pll_src_string);
+ }
+
+ if (sim_mode_string) {
+ strlcpy(pbuf, LK_SIM_OVERRIDE, buf_size);
+ pbuf += LK_SIM_OVERRIDE_LEN;
+ buf_size -= LK_SIM_OVERRIDE_LEN;
+
+ strlcpy(pbuf, sim_mode_string, buf_size);
+ pbuf += strlen(sim_mode_string);
+ buf_size -= strlen(sim_mode_string);
+ }
}
return ret;
}
diff --git a/dev/gcdb/display/include/display_resource.h b/dev/gcdb/display/include/display_resource.h
index 6fc177a..12437aa 100755
--- a/dev/gcdb/display/include/display_resource.h
+++ b/dev/gcdb/display/include/display_resource.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2015, 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
@@ -42,11 +42,20 @@
#define LK_OVERRIDE_PANEL "1:"
#define LK_OVERRIDE_PANEL_LEN 2
+#define LK_SIM_OVERRIDE "#override:"
+#define LK_SIM_OVERRIDE_LEN 10
+
#define DSI_0_STRING ":0:"
#define DSI_0_STRING_LEN 3
#define DSI_1_STRING ":1:"
#define DSI_1_STRING_LEN 3
+#define DSI_CFG_STRING ":cfg:"
+#define DSI_CFG_STRING_LEN 5
+
+#define DSI_PLL0_STRING ":pll0"
+#define DSI_PLL1_STRING ":pll1"
+
#define NO_PANEL_CONFIG "none"
#define SIM_VIDEO_PANEL "sim_video_panel"
#define SIM_DUALDSI_VIDEO_PANEL "sim_dualdsi_video_panel"
diff --git a/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_cmd.h b/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_cmd.h
index b2bf27f..b01752a 100644
--- a/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_cmd.h
+++ b/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_cmd.h
@@ -230,7 +230,7 @@
/* Panel timing */
/*---------------------------------------------------------------------------*/
static const uint32_t nt35597_wqxga_dualdsi_cmd_timings[] = {
- 0xe2, 0x36, 0x24, 0x00, 0x66, 0x6a, 0x28, 0x38, 0x2a, 0x03, 0x04, 0x00
+ 0xd5, 0x32, 0x22, 0x00, 0x60, 0x64, 0x26, 0x36, 0x29, 0x03, 0x04, 0x00
};
static const uint32_t nt35597_wqxga_dualdsi_thulium_cmd_timings[] = {
diff --git a/dev/pmic/pm8x41/include/pm8x41_hw.h b/dev/pmic/pm8x41/include/pm8x41_hw.h
index 0a8e2e8..2bae818 100644
--- a/dev/pmic/pm8x41/include/pm8x41_hw.h
+++ b/dev/pmic/pm8x41/include/pm8x41_hw.h
@@ -94,6 +94,9 @@
/* USB Peripheral registers */
#define SMBCHGL_USB_ICL_STS_2 0x1309
+/* PMI8950 slave id */
+#define PMI8950_SLAVE_ID 0x20000
+
/* USB Peripheral register bits */
#define USBIN_ACTIVE_PWR_SRC BIT(0)
#define DCIN_ACTIVE_PWR_SRC BIT(1)
diff --git a/dev/pmic/pm8x41/pm8x41.c b/dev/pmic/pm8x41/pm8x41.c
index 6733656..0a43bff 100644
--- a/dev/pmic/pm8x41/pm8x41.c
+++ b/dev/pmic/pm8x41/pm8x41.c
@@ -545,7 +545,7 @@
{
uint8_t pon_reason = 0;
- pon_reason = REG_READ(SMBCHGL_USB_ICL_STS_2);
+ pon_reason = REG_READ(SMBCHGL_USB_ICL_STS_2|PMI8950_SLAVE_ID);
/* check usbin/dcin status on pmi and set the corresponding bits for pon */
pon_reason = (pon_reason & (USBIN_ACTIVE_PWR_SRC|DCIN_ACTIVE_PWR_SRC)) << 3 ;
pon_reason |= REG_READ(PON_PON_REASON1);
diff --git a/dev/qpnp_wled/include/qpnp_wled.h b/dev/qpnp_wled/include/qpnp_wled.h
index a04680d..dcd4a8a 100644
--- a/dev/qpnp_wled/include/qpnp_wled.h
+++ b/dev/qpnp_wled/include/qpnp_wled.h
@@ -58,6 +58,7 @@
#define QPNP_WLED_ILIM_MAX_MA 1980
#define QPNP_WLED_ILIM_STEP_MA 280
#define QPNP_WLED_DFLT_ILIM_MA 980
+#define QPNP_WLED_ILIM_OVERWRITE 0x80
#define QPNP_WLED_BOOST_DUTY_MASK 0xFC
#define QPNP_WLED_BOOST_DUTY_STEP_NS 52
#define QPNP_WLED_BOOST_DUTY_MIN_NS 26
diff --git a/dev/qpnp_wled/qpnp_wled.c b/dev/qpnp_wled/qpnp_wled.c
index a0e101d..0ae44a3 100644
--- a/dev/qpnp_wled/qpnp_wled.c
+++ b/dev/qpnp_wled/qpnp_wled.c
@@ -223,9 +223,13 @@
reg = pm8x41_wled_reg_read(
QPNP_WLED_ILIM_REG(wled->ctrl_base));
- reg &= QPNP_WLED_ILIM_MASK;
- reg |= (wled->ilim_ma / QPNP_WLED_ILIM_STEP_MA);
- pm8x41_wled_reg_write(QPNP_WLED_ILIM_REG(wled->ctrl_base), reg);
+ temp = (wled->ilim_ma / QPNP_WLED_ILIM_STEP_MA);
+ if (temp != (reg & ~QPNP_WLED_ILIM_MASK)) {
+ reg &= QPNP_WLED_ILIM_MASK;
+ reg |= temp;
+ reg |= QPNP_WLED_ILIM_OVERWRITE;
+ pm8x41_wled_reg_write(QPNP_WLED_ILIM_REG(wled->ctrl_base), reg);
+ }
/* Configure the MAX BOOST DUTY register */
if (wled->boost_duty_ns < QPNP_WLED_BOOST_DUTY_MIN_NS)
diff --git a/platform/mdmfermium/acpuclock.c b/platform/mdmfermium/acpuclock.c
new file mode 100644
index 0000000..7463222
--- /dev/null
+++ b/platform/mdmfermium/acpuclock.c
@@ -0,0 +1,47 @@
+/* Copyright (c) 2015, 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 <err.h>
+#include <assert.h>
+#include <debug.h>
+#include <reg.h>
+#include <platform/timer.h>
+#include <platform/iomap.h>
+#include <clock.h>
+#include <platform/clock.h>
+#include <platform.h>
+
+void hsusb_clock_init(void)
+{
+
+}
+
+/* Configure UART clock based on the UART block id*/
+void clock_config_uart_dm(uint8_t id)
+{
+
+}
diff --git a/platform/mdmfermium/gpio.c b/platform/mdmfermium/gpio.c
new file mode 100644
index 0000000..fba2c76
--- /dev/null
+++ b/platform/mdmfermium/gpio.c
@@ -0,0 +1,77 @@
+/* Copyright (c) 2015, 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 <platform/iomap.h>
+#include <platform/gpio.h>
+#include <blsp_qup.h>
+
+void gpio_tlmm_config(uint32_t gpio, uint8_t func,
+ uint8_t dir, uint8_t pull,
+ uint8_t drvstr, uint32_t enable)
+{
+ uint32_t val = 0;
+
+ val |= pull;
+ val |= func << 2;
+ val |= drvstr << 6;
+ val |= enable << 9;
+
+ writel(val, (uint32_t *)GPIO_CONFIG_ADDR(gpio));
+ return;
+}
+
+void gpio_set_dir(uint32_t gpio, uint32_t dir)
+{
+ writel(dir, (uint32_t *)GPIO_IN_OUT_ADDR(gpio));
+
+ return;
+}
+
+uint32_t gpio_get_state(uint32_t gpio)
+{
+ return readl(GPIO_IN_OUT_ADDR(gpio));
+}
+
+uint32_t gpio_status(uint32_t gpio)
+{
+ return readl(GPIO_IN_OUT_ADDR(gpio)) & GPIO_IN;
+}
+
+/* Configure gpio for blsp uart 2 */
+void gpio_config_uart_dm(uint8_t id)
+{
+ /* configure rx gpio */
+ gpio_tlmm_config(5, 2, GPIO_INPUT, GPIO_NO_PULL,
+ GPIO_8MA, GPIO_DISABLE);
+
+ /* configure tx gpio */
+ gpio_tlmm_config(4, 2, GPIO_OUTPUT, GPIO_NO_PULL,
+ GPIO_8MA, GPIO_DISABLE);
+}
diff --git a/platform/mdmfermium/include/platform/clock.h b/platform/mdmfermium/include/platform/clock.h
new file mode 100644
index 0000000..e3811ff
--- /dev/null
+++ b/platform/mdmfermium/include/platform/clock.h
@@ -0,0 +1,41 @@
+/* Copyright (c) 2015, 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 __MDMFERMIUM_CLOCK_H
+#define __MDMFERMIUM_CLOCK_H
+
+#include <clock.h>
+#include <clock_lib2.h>
+
+#define UART_DM_CLK_RX_TX_BIT_RATE 0xCC
+
+void platform_clock_init(void);
+
+void clock_config_uart_dm(uint8_t id);
+void hsusb_clock_init(void);
+#endif
diff --git a/platform/mdmfermium/include/platform/gpio.h b/platform/mdmfermium/include/platform/gpio.h
new file mode 100644
index 0000000..aa3a38e
--- /dev/null
+++ b/platform/mdmfermium/include/platform/gpio.h
@@ -0,0 +1,72 @@
+/* Copyright (c) 2015, 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 __PLATFORM_MDMFERMIUM_GPIO_H
+#define __PLATFORM_MDMFERMIUM_GPIO_H
+
+#include <bits.h>
+#include <gpio.h>
+
+/* GPIO TLMM: Direction */
+#define GPIO_INPUT 0
+#define GPIO_OUTPUT 1
+
+/* GPIO TLMM: Pullup/Pulldown */
+#define GPIO_NO_PULL 0
+#define GPIO_PULL_DOWN 1
+#define GPIO_KEEPER 2
+#define GPIO_PULL_UP 3
+
+/* GPIO TLMM: Drive Strength */
+#define GPIO_2MA 0
+#define GPIO_4MA 1
+#define GPIO_6MA 2
+#define GPIO_8MA 3
+#define GPIO_10MA 4
+#define GPIO_12MA 5
+#define GPIO_14MA 6
+#define GPIO_16MA 7
+
+/* GPIO TLMM: Status */
+#define GPIO_ENABLE 0
+#define GPIO_DISABLE 1
+
+/* GPIO_IN_OUT register shifts. */
+#define GPIO_IN BIT(0)
+#define GPIO_OUT BIT(1)
+
+void gpio_config_uart_dm(uint8_t id);
+uint32_t gpio_status(uint32_t gpio);
+void gpio_set_dir(uint32_t gpio, uint32_t dir);
+void gpio_tlmm_config(uint32_t gpio,
+ uint8_t func,
+ uint8_t dir,
+ uint8_t pull,
+ uint8_t drvstr,
+ uint32_t enable);
+#endif
diff --git a/platform/mdmfermium/include/platform/iomap.h b/platform/mdmfermium/include/platform/iomap.h
new file mode 100644
index 0000000..852e5a9
--- /dev/null
+++ b/platform/mdmfermium/include/platform/iomap.h
@@ -0,0 +1,112 @@
+/* Copyright (c) 2015, 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 _PLATFORM_MDMFERMIUM_IOMAP_H_
+#define _PLATFORM_MDMFERMIUM_IOMAP_H_
+
+#define MSM_IOMAP_BASE 0x00000000
+#define MSM_IOMAP_END 0x08000000
+
+#define A7_SS_BASE 0x0B000000
+#define A7_SS_END 0x0B200000
+
+#define SDRAM_START_ADDR 0x80000000
+
+#define SYSTEM_IMEM_BASE 0x08600000
+#define MSM_SHARED_BASE 0x87D00000
+#define MSM_SHARED_IMEM_BASE 0x08600000
+
+#define BS_INFO_OFFSET (0x6B0)
+#define BS_INFO_ADDR (MSM_SHARED_IMEM_BASE + BS_INFO_OFFSET)
+
+#define RESTART_REASON_ADDR (MSM_SHARED_IMEM_BASE + 0x65C)
+
+#define MSM_NAND_BASE 0x79B0000
+/* NAND BAM */
+#define MSM_NAND_BAM_BASE 0x7984000
+
+#define APPS_SS_BASE 0x0B000000
+
+#define MSM_GIC_DIST_BASE APPS_SS_BASE
+#define MSM_GIC_CPU_BASE (APPS_SS_BASE + 0x2000)
+#define APPS_APCS_QTMR_AC_BASE (APPS_SS_BASE + 0x00020000)
+#define APPS_APCS_F0_QTMR_V1_BASE (APPS_SS_BASE + 0x00021000)
+#define APCS_ALIAS0_IPC_INTERRUPT (APPS_SS_BASE + 0x00011008)
+#define QTMR_BASE APPS_APCS_F0_QTMR_V1_BASE
+
+#define PERIPH_SS_BASE 0x07800000
+
+
+#define BLSP1_UART0_BASE (PERIPH_SS_BASE + 0x000AF000)
+#define BLSP1_UART1_BASE (PERIPH_SS_BASE + 0x000B0000)
+#define MSM_USB_BASE (PERIPH_SS_BASE + 0x000D9000)
+
+#define CLK_CTL_BASE 0x1800000
+
+#define SPMI_BASE 0x02000000
+#define SPMI_GENI_BASE (SPMI_BASE + 0xA000)
+#define SPMI_PIC_BASE (SPMI_BASE + 0x01800000)
+#define PMIC_ARB_CORE 0x200F000
+
+#define TLMM_BASE_ADDR 0x1000000
+#define GPIO_CONFIG_ADDR(x) (TLMM_BASE_ADDR + (x)*0x1000)
+#define GPIO_IN_OUT_ADDR(x) (TLMM_BASE_ADDR + 0x00000004 + (x)*0x1000)
+
+#define MPM2_MPM_CTRL_BASE 0x004A0000
+#define MPM2_MPM_PS_HOLD 0x004AB000
+#define MPM2_MPM_SLEEP_TIMETICK_COUNT_VAL 0x004A3000
+
+/* CRYPTO ENGINE */
+#define MSM_CE1_BASE 0x073A000
+#define MSM_CE1_BAM_BASE 0x0704000
+
+
+/* GPLL */
+#define GPLL0_STATUS (CLK_CTL_BASE + 0x21024)
+#define APCS_GPLL_ENA_VOTE (CLK_CTL_BASE + 0x45000)
+#define APCS_CLOCK_BRANCH_ENA_VOTE (CLK_CTL_BASE + 0x45004)
+
+/* UART */
+#define BLSP1_AHB_CBCR (CLK_CTL_BASE + 0x1008)
+#define BLSP1_UART2_APPS_CBCR (CLK_CTL_BASE + 0x302C)
+#define BLSP1_UART2_APPS_CMD_RCGR (CLK_CTL_BASE + 0x3034)
+#define BLSP1_UART2_APPS_CFG_RCGR (CLK_CTL_BASE + 0x3038)
+#define BLSP1_UART2_APPS_M (CLK_CTL_BASE + 0x303C)
+#define BLSP1_UART2_APPS_N (CLK_CTL_BASE + 0x3040)
+#define BLSP1_UART2_APPS_D (CLK_CTL_BASE + 0x3044)
+
+/* USB */
+#define USB_HS_BCR (CLK_CTL_BASE + 0x41000)
+#define USB_HS_SYSTEM_CBCR (CLK_CTL_BASE + 0x41004)
+#define USB_HS_AHB_CBCR (CLK_CTL_BASE + 0x41008)
+#define USB_HS_SYSTEM_CMD_RCGR (CLK_CTL_BASE + 0x41010)
+#define USB_HS_SYSTEM_CFG_RCGR (CLK_CTL_BASE + 0x41014)
+
+#define TCSR_TZ_WONCE 0x193D000
+#define TCSR_BOOT_MISC_DETECT 0x193D100
+#endif
diff --git a/platform/mdmfermium/include/platform/irqs.h b/platform/mdmfermium/include/platform/irqs.h
new file mode 100644
index 0000000..8738b97
--- /dev/null
+++ b/platform/mdmfermium/include/platform/irqs.h
@@ -0,0 +1,64 @@
+/* Copyright (c) 2015, 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 __IRQS_MDMFERMIUM_H
+#define __IRQS_MDMFERMIUM_H
+
+/* MSM ACPU Interrupt Numbers */
+
+/* 0-15: STI/SGI (software triggered/generated interrupts)
+ * 16-31: PPI (private peripheral interrupts)
+ * 32+: SPI (shared peripheral interrupts)
+ */
+
+#define GIC_PPI_START 16
+#define GIC_SPI_START 32
+
+#define INT_QTMR_NON_SECURE_PHY_TIMER_EXP (GIC_PPI_START + 3)
+#define INT_QTMR_VIRTUAL_TIMER_EXP (GIC_PPI_START + 4)
+
+#define INT_QTMR_FRM_0_PHYSICAL_TIMER_EXP (GIC_SPI_START + 7)
+
+#define USB1_HS_BAM_IRQ (GIC_SPI_START + 135)
+#define USB1_HS_IRQ (GIC_SPI_START + 134)
+
+/* Retrofit universal macro names */
+#define INT_USB_HS USB1_HS_IRQ
+
+#define EE0_KRAIT_HLOS_SPMI_PERIPH_IRQ (GIC_SPI_START + 190)
+
+#define SMD_IRQ (GIC_SPI_START + 168)
+
+#define NR_MSM_IRQS 256
+#define NR_GPIO_IRQS 173
+#define NR_BOARD_IRQS 0
+
+#define NR_IRQS (NR_MSM_IRQS + NR_GPIO_IRQS + \
+ NR_BOARD_IRQS)
+
+#endif /* __IRQS_MDMFERMIUM_H */
diff --git a/platform/mdmfermium/mdmfermium-clock.c b/platform/mdmfermium/mdmfermium-clock.c
new file mode 100644
index 0000000..235d40f
--- /dev/null
+++ b/platform/mdmfermium/mdmfermium-clock.c
@@ -0,0 +1,233 @@
+/* Copyright (c) 2015, 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 <assert.h>
+#include <reg.h>
+#include <err.h>
+#include <clock.h>
+#include <clock_pll.h>
+#include <clock_lib2.h>
+#include <platform/clock.h>
+#include <platform/iomap.h>
+#include <platform.h>
+
+/* Mux source select values */
+#define cxo_source_val 0
+#define gpll0_source_val 1
+#define gpll4_source_val 2
+#define cxo_mm_source_val 0
+#define gpll0_mm_source_val 1
+
+struct clk_freq_tbl rcg_dummy_freq = F_END;
+
+
+/* Clock Operations */
+static struct clk_ops clk_ops_branch =
+{
+ .enable = clock_lib2_branch_clk_enable,
+ .disable = clock_lib2_branch_clk_disable,
+ .set_rate = clock_lib2_branch_set_rate,
+};
+
+static struct clk_ops clk_ops_rcg_mnd =
+{
+ .enable = clock_lib2_rcg_enable,
+ .set_rate = clock_lib2_rcg_set_rate,
+};
+
+static struct clk_ops clk_ops_rcg =
+{
+ .enable = clock_lib2_rcg_enable,
+ .set_rate = clock_lib2_rcg_set_rate,
+};
+
+static struct clk_ops clk_ops_cxo =
+{
+ .enable = cxo_clk_enable,
+ .disable = cxo_clk_disable,
+};
+
+static struct clk_ops clk_ops_pll_vote =
+{
+ .enable = pll_vote_clk_enable,
+ .disable = pll_vote_clk_disable,
+ .auto_off = pll_vote_clk_disable,
+ .is_enabled = pll_vote_clk_is_enabled,
+};
+
+static struct clk_ops clk_ops_vote =
+{
+ .enable = clock_lib2_vote_clk_enable,
+ .disable = clock_lib2_vote_clk_disable,
+};
+
+/* Clock Sources */
+static struct fixed_clk cxo_clk_src =
+{
+ .c = {
+ .rate = 19200000,
+ .dbg_name = "cxo_clk_src",
+ .ops = &clk_ops_cxo,
+ },
+};
+
+static struct pll_vote_clk gpll0_clk_src =
+{
+ .en_reg = (void *) APCS_GPLL_ENA_VOTE,
+ .en_mask = BIT(0),
+ .status_reg = (void *) GPLL0_STATUS,
+ .status_mask = BIT(17),
+ .parent = &cxo_clk_src.c,
+
+ .c = {
+ .rate = 800000000,
+ .dbg_name = "gpll0_clk_src",
+ .ops = &clk_ops_pll_vote,
+ },
+};
+
+/* UART Clocks */
+static struct clk_freq_tbl ftbl_gcc_blsp1_2_uart1_2_apps_clk[] =
+{
+ F( 3686400, gpll0, 1, 72, 15625),
+ F( 7372800, gpll0, 1, 144, 15625),
+ F(14745600, gpll0, 1, 288, 15625),
+ F(16000000, gpll0, 10, 1, 5),
+ F(19200000, cxo, 1, 0, 0),
+ F(24000000, gpll0, 1, 3, 100),
+ F(25000000, gpll0, 16, 1, 2),
+ F(32000000, gpll0, 1, 1, 25),
+ F(40000000, gpll0, 1, 1, 20),
+ F(46400000, gpll0, 1, 29, 500),
+ F(48000000, gpll0, 1, 3, 50),
+ F(51200000, gpll0, 1, 8, 125),
+ F(56000000, gpll0, 1, 7, 100),
+ F(58982400, gpll0, 1,1152, 15625),
+ F(60000000, gpll0, 1, 3, 40),
+ F_END
+};
+
+static struct rcg_clk blsp1_uart2_apps_clk_src =
+{
+ .cmd_reg = (uint32_t *) BLSP1_UART2_APPS_CMD_RCGR,
+ .cfg_reg = (uint32_t *) BLSP1_UART2_APPS_CFG_RCGR,
+ .m_reg = (uint32_t *) BLSP1_UART2_APPS_M,
+ .n_reg = (uint32_t *) BLSP1_UART2_APPS_N,
+ .d_reg = (uint32_t *) BLSP1_UART2_APPS_D,
+
+ .set_rate = clock_lib2_rcg_set_rate_mnd,
+ .freq_tbl = ftbl_gcc_blsp1_2_uart1_2_apps_clk,
+ .current_freq = &rcg_dummy_freq,
+
+ .c = {
+ .dbg_name = "blsp1_uart2_apps_clk",
+ .ops = &clk_ops_rcg_mnd,
+ },
+};
+
+static struct branch_clk gcc_blsp1_uart2_apps_clk =
+{
+ .cbcr_reg = (uint32_t *) BLSP1_UART2_APPS_CBCR,
+ .parent = &blsp1_uart2_apps_clk_src.c,
+
+ .c = {
+ .dbg_name = "gcc_blsp1_uart2_apps_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
+static struct vote_clk gcc_blsp1_ahb_clk = {
+ .cbcr_reg = (uint32_t *) BLSP1_AHB_CBCR,
+ .vote_reg = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+ .en_mask = BIT(10),
+
+ .c = {
+ .dbg_name = "gcc_blsp1_ahb_clk",
+ .ops = &clk_ops_vote,
+ },
+};
+
+/* USB Clocks */
+static struct clk_freq_tbl ftbl_gcc_usb_hs_system_clk[] =
+{
+ F(133330000, gpll0, 6, 0, 0),
+ F_END
+};
+
+static struct rcg_clk usb_hs_system_clk_src =
+{
+ .cmd_reg = (uint32_t *) USB_HS_SYSTEM_CMD_RCGR,
+ .cfg_reg = (uint32_t *) USB_HS_SYSTEM_CFG_RCGR,
+
+ .set_rate = clock_lib2_rcg_set_rate_hid,
+ .freq_tbl = ftbl_gcc_usb_hs_system_clk,
+ .current_freq = &rcg_dummy_freq,
+
+ .c = {
+ .dbg_name = "usb_hs_system_clk",
+ .ops = &clk_ops_rcg,
+ },
+};
+
+static struct branch_clk gcc_usb_hs_system_clk =
+{
+ .cbcr_reg = (uint32_t *) USB_HS_SYSTEM_CBCR,
+ .parent = &usb_hs_system_clk_src.c,
+
+ .c = {
+ .dbg_name = "gcc_usb_hs_system_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
+static struct branch_clk gcc_usb_hs_ahb_clk =
+{
+ .cbcr_reg = (uint32_t *) USB_HS_AHB_CBCR,
+ .has_sibling = 1,
+
+ .c = {
+ .dbg_name = "gcc_usb_hs_ahb_clk",
+ .ops = &clk_ops_branch,
+ },
+};
+
+/* Clock lookup table */
+static struct clk_lookup mdm_clocks_fermium[] =
+{
+ CLK_LOOKUP("uart2_iface_clk", gcc_blsp1_ahb_clk.c),
+ CLK_LOOKUP("uart2_core_clk", gcc_blsp1_uart2_apps_clk.c),
+
+ CLK_LOOKUP("usb_iface_clk", gcc_usb_hs_ahb_clk.c),
+ CLK_LOOKUP("usb_core_clk", gcc_usb_hs_system_clk.c),
+
+};
+
+void platform_clock_init(void)
+{
+ clk_init(mdm_clocks_fermium, ARRAY_SIZE(mdm_clocks_fermium));
+}
diff --git a/platform/mdmfermium/platform.c b/platform/mdmfermium/platform.c
new file mode 100644
index 0000000..7d05f04
--- /dev/null
+++ b/platform/mdmfermium/platform.c
@@ -0,0 +1,69 @@
+/* Copyright (c) 2015, 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 <platform/iomap.h>
+#include <qgic.h>
+#include <qtimer.h>
+#include <mmu.h>
+#include <arch/arm/mmu.h>
+#include <smem.h>
+
+void platform_early_init(void)
+{
+ qgic_init();
+ qtimer_init();
+// scm_init();
+}
+
+void platform_init(void)
+{
+ dprintf(INFO, "platform_init()\n");
+}
+
+void platform_uninit(void)
+{
+ qtimer_uninit();
+}
+
+uint32_t platform_get_sclk_count(void)
+{
+ return readl(MPM2_MPM_SLEEP_TIMETICK_COUNT_VAL);
+}
+
+addr_t get_bs_info_addr()
+{
+ return ((addr_t)BS_INFO_ADDR);
+}
+
+int platform_use_identity_mmu_mappings(void)
+{
+ /* Use only the mappings specified in this file. */
+ return 1;
+}
diff --git a/platform/mdmfermium/rules.mk b/platform/mdmfermium/rules.mk
new file mode 100644
index 0000000..d5f789a
--- /dev/null
+++ b/platform/mdmfermium/rules.mk
@@ -0,0 +1,23 @@
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+ARCH := arm
+ARM_CPU := cortex-a8
+CPU := generic
+
+DEFINES += ARM_CPU_CORE_A7
+
+
+DEFINES += PERIPH_BLK_BLSP=1
+DEFINES += WITH_CPU_EARLY_INIT=0 WITH_CPU_WARM_BOOT=0
+
+INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared/include
+
+OBJS += \
+ $(LOCAL_DIR)/platform.o \
+ $(LOCAL_DIR)/acpuclock.o \
+ $(LOCAL_DIR)/gpio.o \
+ $(LOCAL_DIR)/mdmfermium-clock.o
+
+LINKER_SCRIPT += $(BUILDDIR)/system-onesegment.ld
+
+include platform/msm_shared/rules.mk
diff --git a/platform/msm8996/include/platform/iomap.h b/platform/msm8996/include/platform/iomap.h
index 2244632..ea2a0bf 100644
--- a/platform/msm8996/include/platform/iomap.h
+++ b/platform/msm8996/include/platform/iomap.h
@@ -161,7 +161,7 @@
/* QSEECOM: Secure app region notification */
#define APP_REGION_ADDR 0x86600000
-#define APP_REGION_SIZE 0xd00000
+#define APP_REGION_SIZE 0x2200000
/* DRV strength for sdcc */
#define SDC1_HDRV_PULL_CTL (TLMM_BASE_ADDR + 0x0012C000)
@@ -527,9 +527,4 @@
#define QPNP_GREEN_LPG_CTRL_BASE 0xB200
#define QPNP_RED_LPG_CTRL_BASE 0xB300
-#define APSS_WDOG_BASE 0x9830000
-#define APPS_WDOG_BARK_VAL_REG (APSS_WDOG_BASE + 0x10)
-#define APPS_WDOG_BITE_VAL_REG (APSS_WDOG_BASE + 0x14)
-#define APPS_WDOG_RESET_REG (APSS_WDOG_BASE + 0x04)
-#define APPS_WDOG_CTL_REG (APSS_WDOG_BASE + 0x08)
#endif
diff --git a/platform/msm8996/platform.c b/platform/msm8996/platform.c
index 6e04abf..8bdfff0 100644
--- a/platform/msm8996/platform.c
+++ b/platform/msm8996/platform.c
@@ -36,6 +36,7 @@
#include <mmu.h>
#include <smem.h>
#include <board.h>
+#include <target/display.h>
#define MSM_IOMAP_SIZE ((MSM_IOMAP_END - MSM_IOMAP_BASE)/MB)
#define MSM_SHARED_SIZE 2
@@ -60,8 +61,10 @@
static mmu_section_t default_mmu_section_table[] =
{
/* Physical addr, Virtual addr, Mapping type , Size (in MB), Flags */
- { 0x00000000, 0x00000000, MMU_L1_NS_SECTION_MAPPING, 1024, IOMAP_MEMORY},
- { KERNEL_ADDR, KERNEL_ADDR, MMU_L2_NS_SECTION_MAPPING, KERNEL_SIZE, COMMON_MEMORY},
+ { 0x00000000, 0x00000000, MMU_L2_NS_SECTION_MAPPING, 512, IOMAP_MEMORY},
+ { KERNEL_ADDR, KERNEL_ADDR, MMU_L2_NS_SECTION_MAPPING, KERNEL_SIZE, COMMON_MEMORY},
+ { 0x40000000, 0x40000000, MMU_L1_NS_SECTION_MAPPING, 1024 , COMMON_MEMORY},
+ { 0x80000000, 0x80000000, MMU_L2_NS_SECTION_MAPPING, 88 , COMMON_MEMORY},
{ MEMBASE, MEMBASE, MMU_L2_NS_SECTION_MAPPING, (MEMSIZE / MB), LK_MEMORY},
{ SCRATCH_ADDR, SCRATCH_ADDR, MMU_L2_NS_SECTION_MAPPING, SCRATCH_SIZE, SCRATCH_MEMORY},
{ MSM_SHARED_BASE, MSM_SHARED_BASE, MMU_L2_NS_SECTION_MAPPING, MSM_SHARED_SIZE, COMMON_MEMORY},
diff --git a/platform/msm_shared/include/mmc_sdhci.h b/platform/msm_shared/include/mmc_sdhci.h
index 6ef404b..54f09ee 100644
--- a/platform/msm_shared/include/mmc_sdhci.h
+++ b/platform/msm_shared/include/mmc_sdhci.h
@@ -89,6 +89,7 @@
#define MMC_EXT_CSD_RST_N_FUNC 162
#define MMC_EXT_MMC_BUS_WIDTH 183
#define MMC_EXT_MMC_HS_TIMING 185
+#define MMC_EXT_CSD_REV 192
#define MMC_DEVICE_TYPE 196
#define MMC_EXT_MMC_DRV_STRENGTH 197
#define MMC_EXT_HC_WP_GRP_SIZE 221
@@ -102,6 +103,7 @@
#define MMC_ERASE_TIMEOUT_MULT 223
#define MMC_HC_ERASE_GRP_SIZE 224
#define MMC_PARTITION_CONFIG 179
+#define MMC_EXT_CSD_EN_RPMB_REL_WR 166 //emmc 5.1 and above
/* Values for ext csd fields */
#define MMC_HS_TIMING 0x1
diff --git a/platform/msm_shared/include/rpmb.h b/platform/msm_shared/include/rpmb.h
index 6cd7ecd..f954dfb 100644
--- a/platform/msm_shared/include/rpmb.h
+++ b/platform/msm_shared/include/rpmb.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2014-2015, 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
@@ -147,15 +147,15 @@
int write_device_info_rpmb(void *info, uint32_t sz);
/* Function Prototypes */
-int rpmb_write_emmc(struct mmc_device *dev, uint32_t *req_buf, uint32_t blk_cnt, uint32_t *resp_buf, uint32_t *resp_len);
+int rpmb_write_emmc(struct mmc_device *dev, uint32_t *req_buf, uint32_t blk_cnt, uint32_t rel_wr_count, uint32_t *resp_buf, uint32_t *resp_len);
int rpmb_read_emmc(struct mmc_device *dev, uint32_t *req_buf, uint32_t blk_cnt, uint32_t *resp_buf, uint32_t *resp_len);
-int rpmb_write_ufs(struct ufs_dev *dev, uint32_t *req_buf, uint32_t blk_cnt, uint32_t *resp_buf, uint32_t *resp_len);
+int rpmb_write_ufs(struct ufs_dev *dev, uint32_t *req_buf, uint32_t blk_cnt, uint32_t rel_wr_count, uint32_t *resp_buf, uint32_t *resp_len);
int rpmb_read_ufs(struct ufs_dev *dev, uint32_t *req_buf, uint32_t blk_cnt, uint32_t *resp_buf, uint32_t *resp_len);
/* APIs exposed to applications */
int rpmb_init();
int rpmb_uninit();
-int rpmb_write(uint32_t *req_buf, uint32_t blk_cnt, uint32_t *resp_buf, uint32_t *resp_len);
+int rpmb_write(uint32_t *req_buf, uint32_t blk_cnt, uint32_t rel_wr_count, uint32_t *resp_buf, uint32_t *resp_len);
int rpmb_read(uint32_t *req_buf, uint32_t blk_cnt, uint32_t *resp_buf, uint32_t *resp_len);
struct rpmb_init_info *rpmb_get_init_info();
int rpmb_get_app_handle();
diff --git a/platform/msm_shared/include/sdhci.h b/platform/msm_shared/include/sdhci.h
index c0b484d..64fb2b0 100644
--- a/platform/msm_shared/include/sdhci.h
+++ b/platform/msm_shared/include/sdhci.h
@@ -102,6 +102,7 @@
uint64_t cmd_timeout; /* Command timeout in us */
bool write_flag; /* Write flag, for reliable write cases */
struct mmc_data data; /* Data pointer */
+ uint8_t rel_write; /* Reliable write enable flag */
};
/*
diff --git a/platform/msm_shared/rpmb/rpmb.c b/platform/msm_shared/rpmb/rpmb.c
index 36bacab..29d72e3 100644
--- a/platform/msm_shared/rpmb/rpmb.c
+++ b/platform/msm_shared/rpmb/rpmb.c
@@ -50,7 +50,30 @@
{
struct mmc_device *mmc_dev = (struct mmc_device *) dev;
info.size = mmc_dev->card.rpmb_size / RPMB_MIN_BLK_SZ;
- info.rel_wr_count = mmc_dev->card.rel_wr_count;
+ if (mmc_dev->card.ext_csd[MMC_EXT_CSD_REV] < 8)
+ {
+ dprintf(SPEW, "EMMC Version < 5.1\n");
+ info.rel_wr_count = mmc_dev->card.rel_wr_count;
+ }
+ else
+ {
+ if (mmc_dev->card.ext_csd[MMC_EXT_CSD_EN_RPMB_REL_WR] == 0)
+ {
+ dprintf(SPEW, "EMMC Version >= 5.1 EN_RPMB_REL_WR = 0\n");
+ // according to emmc version 5.1 and above if EN_RPMB_REL_WR in extended
+ // csd is not set the maximum number of frames that can be reliably written
+ // to emmc would be 2
+ info.rel_wr_count = 2;
+ }
+ else
+ {
+ dprintf(SPEW, "EMMC Version >= 5.1 EN_RPMB_REL_WR = 1\n");
+ // according to emmc version 5.1 and above if EN_RPMB_REL_WR in extended
+ // csd is set the maximum number of frames that can be reliably written
+ // to emmc would be 32
+ info.rel_wr_count = 32;
+ }
+ }
info.dev_type = EMMC_RPMB;
}
else
@@ -105,12 +128,12 @@
return rpmb_read_ufs(dev, req, req_len, resp, resp_len);
}
-int rpmb_write(uint32_t *req, uint32_t req_len, uint32_t *resp, uint32_t *resp_len)
+int rpmb_write(uint32_t *req, uint32_t req_len, uint32_t rel_wr_count, uint32_t *resp, uint32_t *resp_len)
{
if (platform_boot_dev_isemmc())
- return rpmb_write_emmc(dev, req, req_len, resp, resp_len);
+ return rpmb_write_emmc(dev, req, req_len, rel_wr_count, resp, resp_len);
else
- return rpmb_write_ufs(dev, req, req_len, resp, resp_len);
+ return rpmb_write_ufs(dev, req, req_len, rel_wr_count, resp, resp_len);
}
/* This API calls into TZ app to read device_info */
diff --git a/platform/msm_shared/rpmb/rpmb_emmc.c b/platform/msm_shared/rpmb/rpmb_emmc.c
index 2bfa545..3b00e09 100644
--- a/platform/msm_shared/rpmb/rpmb_emmc.c
+++ b/platform/msm_shared/rpmb/rpmb_emmc.c
@@ -47,17 +47,36 @@
.requestresponse[1] = READ_RESULT_FLAG,
};
-int rpmb_write_emmc(struct mmc_device *dev,uint32_t *req_buf, uint32_t blk_cnt, uint32_t *resp_buf, uint32_t *resp_len)
+int rpmb_write_emmc(struct mmc_device *dev,uint32_t *req_buf, uint32_t blk_cnt, uint32_t rel_wr_count, uint32_t *resp_buf, uint32_t *resp_len)
{
- uint32_t i;
+ uint32_t i, num_trans;
int ret = 0;
struct mmc_command cmd[3] = {{0},{0},{0}};
struct rpmb_frame *result = (struct rpmb_frame *)resp_buf;
- for (i = 0; i < blk_cnt; i++)
+ dprintf(INFO, "rpmb write command called with blk_cnt: 0x%x\n", blk_cnt);
+ if (rel_wr_count == 0x2)
+ {
+ // if reliable write count reported by secure app is 2 then we can
+ // send two half sectors in one transaction. So overall number of
+ // transactions would be total block count by 2.
+ num_trans = blk_cnt / 2;
+ }
+ else if(rel_wr_count == 0x1)
+ {
+ num_trans = blk_cnt; // rel_rw_count = 1 for emmc 5.0 and below
+ }
+ else
+ {
+ dprintf(CRITICAL, "Reliable write count > 2 is not supported\n");
+ return -1;
+ }
+
+ for (i = 0; i < num_trans; i++)
{
#if DEBUG_RPMB
- dump_rpmb_frame((uint8_t *)req_buf, "request");
+ for(uint8_t j = 0; j < rel_wr_count; j++)
+ dump_rpmb_frame((uint8_t *)req_buf + (j * 512), "request");
#endif
/* CMD25 program data packet */
@@ -69,8 +88,16 @@
cmd[0].trans_mode = SDHCI_MMC_WRITE;
cmd[0].data_present = 0x1;
cmd[0].data.data_ptr = (void *)req_buf;
- cmd[0].data.num_blocks = RPMB_MIN_BLK_CNT;
-
+ if (rel_wr_count == 0x1)
+ {
+ cmd[0].rel_write = 0;
+ cmd[0].data.num_blocks = RPMB_MIN_BLK_CNT;
+ }
+ else if(rel_wr_count == 0x2)
+ {
+ cmd[0].rel_write = 1;
+ cmd[0].data.num_blocks = 0x2;
+ }
/* CMD25 Result Register Read Request Packet */
cmd[1].write_flag = false;
cmd[1].cmd_index = CMD25_WRITE_MULTIPLE_BLOCK;
@@ -101,6 +128,9 @@
break;
}
+#if DEBUG_RPMB
+ dump_rpmb_frame((uint8_t *)resp_buf, "response");
+#endif
if (result->result[0] == 0x80)
{
dprintf(CRITICAL, "Max write counter reached: \n");
@@ -112,12 +142,11 @@
dprintf(CRITICAL, "%s\n", str_err[result->result[1]]);
break;
}
+ if (rel_wr_count == 0x1)
+ req_buf = (uint32_t*) ((uint8_t*)req_buf + (RPMB_BLK_SIZE));
+ else if(rel_wr_count == 0x2)
+ req_buf = (uint32_t*) ((uint8_t*)req_buf + (RPMB_BLK_SIZE * 0x2));
- req_buf = (uint32_t*) ((uint8_t*)req_buf + RPMB_BLK_SIZE);
-
-#if DEBUG_RPMB
- dump_rpmb_frame((uint8_t *)resp_buf, "response");
-#endif
}
*resp_len = RPMB_MIN_BLK_CNT * RPMB_BLK_SIZE;
diff --git a/platform/msm_shared/rpmb/rpmb_listener.c b/platform/msm_shared/rpmb/rpmb_listener.c
index 7cf0b79..c9623e2 100644
--- a/platform/msm_shared/rpmb/rpmb_listener.c
+++ b/platform/msm_shared/rpmb/rpmb_listener.c
@@ -67,6 +67,8 @@
uint32_t num_sectors;
uint32_t req_buff_len;
uint32_t req_buff_offset;
+ uint32_t version;
+ uint32_t rel_wr_count;
}__PACKED;
struct tz_rpmb_rw_resp
@@ -75,6 +77,7 @@
int32_t status;
uint32_t res_buff_len;
uint32_t res_buff_offset;
+ uint32_t version;
}__PACKED;
typedef int (*ListenerCallback)(void*, uint32_t);
@@ -113,14 +116,16 @@
case TZ_CM_CMD_RPMB_READ:
#if DEBUG_RPMB
dprintf(INFO, "Read Request received\n");
+ dprintf(INFO, "READ: RPMB_REL_RW_COUNT 0x%x\n", req_p->rel_wr_count);
#endif
resp_p->status = rpmb_read(req_buf, req_p->num_sectors, resp_buf, &resp_p->res_buff_len);
break;
case TZ_CM_CMD_RPMB_WRITE:
#if DEBUG_RPMB
dprintf(INFO, "Write Request received\n");
+ dprintf(INFO, "WRITE: RPMB_REL_RW_COUNT 0x%x\n", req_p->rel_wr_count);
#endif
- resp_p->status = rpmb_write(req_buf, req_p->num_sectors, resp_buf, &resp_p->res_buff_len);
+ resp_p->status = rpmb_write(req_buf, req_p->num_sectors, req_p->rel_wr_count, resp_buf, &resp_p->res_buff_len);
break;
default:
dprintf(CRITICAL, "Unsupported request command request: %u\n", req_p->cmd_id);
@@ -174,7 +179,7 @@
rpmb_listener.service_name = "RPMB system services";
rpmb_listener.id = RPMB_LSTNR_ID;
- rpmb_listener.sb_size = 20 * 1024;
+ rpmb_listener.sb_size = 25 * 1024;
rpmb_listener.service_cmd_handler = rpmb_cmd_handler;
ret = qseecom_register_listener(&rpmb_listener);
diff --git a/platform/msm_shared/rpmb/rpmb_ufs.c b/platform/msm_shared/rpmb/rpmb_ufs.c
index 3cc4d91..17cfc56 100644
--- a/platform/msm_shared/rpmb/rpmb_ufs.c
+++ b/platform/msm_shared/rpmb/rpmb_ufs.c
@@ -36,6 +36,18 @@
#include <endian.h>
#include <arch/defines.h>
+static const char *str_err[] =
+{
+ "Operation Ok",
+ "General failure",
+ "Authentication error (MAC comparison not matching, MAC calculation failure)",
+ "Counter failure (counters not matching in comparison, counter incrementing failure)",
+ "Address failure (address out of range, wrong address alignment)",
+ "Write failure (data/counter/result write failure)",
+ "Read failure (data/counter/result read failure)",
+ "Authentication Key not yet programmed",
+};
+
static struct rpmb_frame read_result_reg =
{
.requestresponse[1] = READ_RESULT_FLAG,
@@ -71,8 +83,8 @@
return -UFS_FAILURE;
}
#ifdef DEBUG_RPMB
- dprintf(SPEW, "rpmb_read: req_buf: 0x%x blk_count: 0x%x\n", *req_buf, blk_cnt);
- dprintf(INFO, "rpmb_read: bytes_to_transfer: 0x%x blks_to_transfer: 0x%x\n",
+ dprintf(INFO, "rpmb_read: req_buf: 0x%x blk_count: 0x%x\n", *req_buf, blk_cnt);
+ dprintf(INFO, "rpmb_read: bytes_to_transfer: 0x%llx blks_to_transfer: 0x%x\n",
bytes_to_transfer, blks_to_transfer);
#endif
// send the request
@@ -138,15 +150,18 @@
dprintf(CRITICAL, "%s:%d ucs_do_scsi_rpmb_read: failed\n", __func__, __LINE__);
return -UFS_FAILURE;
}
+ // invalidate response buffer before reading response as this is part of request
+ // buffer overwritten
+ arch_clean_invalidate_cache_range((addr_t) resp_buf, RPMB_FRAME_SIZE);
#ifdef DEBUG_RPMB
- dprintf(SPEW, "Sending RPMB Read response complete\n");
+ dprintf(INFO, "Sending RPMB Read response complete\n");
dump_rpmb_frame((uint8_t *)resp_buf, "response");
#endif
*resp_len = bytes_to_transfer;
return UFS_SUCCESS;
}
-int rpmb_write_ufs(struct ufs_dev *dev, uint32_t *req_buf, uint32_t blk_cnt, uint32_t *resp_buf, uint32_t *resp_len)
+int rpmb_write_ufs(struct ufs_dev *dev, uint32_t *req_buf, uint32_t blk_cnt, uint32_t rel_wr_count, uint32_t *resp_buf, uint32_t *resp_len)
{
// validate input parameters
ASSERT(req_buf);
@@ -156,12 +171,14 @@
STACKBUF_DMA_ALIGN(cdb, sizeof(struct scsi_sec_protocol_cdb));
struct scsi_req_build_type req_upiu;
struct scsi_sec_protocol_cdb *cdb_out_param, *cdb_in_param;
+ struct rpmb_frame *result = (struct rpmb_frame *)resp_buf;
uint32_t blks_remaining;
uint32_t blks_to_transfer;
uint64_t bytes_to_transfer;
uint64_t max_size;
uint32_t result_frame_bytes = RPMB_FRAME_SIZE;
uint32_t i;
+ uint32_t num_trans;
blks_remaining = blk_cnt;
blks_to_transfer = blks_remaining;
@@ -176,13 +193,31 @@
}
#ifdef DEBUG_RPMB
dprintf(INFO, "%s: req_buf: 0x%x blk_count: 0x%x\n", __func__,*req_buf, blk_cnt);
- dprintf(INFO, "%s: bytes_to_transfer: 0x%x blks_to_transfer: 0x%x\n", __func__
- bytes_to_transfer, blk_cnt);
- dump_rpmb_frame((uint8_t *)req_buf, "request");
+ dprintf(INFO, "%s: bytes_to_transfer: 0x%llx blks_to_transfer: 0x%x\n", __func__, bytes_to_transfer, blk_cnt);
#endif
-
- for (i = 0; i < blk_cnt; i++)
+ if (bytes_to_transfer <= (rel_wr_count * RPMB_FRAME_SIZE))
{
+ num_trans = 1;
+ }
+ else
+ {
+ // send uptop rel_wr_count number of frames in one shot + anything pending
+ num_trans = blk_cnt/rel_wr_count;
+ if (num_trans % rel_wr_count) // if anymore frames still pending
+ num_trans++;
+ }
+ for (i = 0; i < num_trans; i++)
+ {
+ if ((num_trans - i) == 1) // last loop or one and only loop
+ {
+ // last loop will contain a max of rel_wr_count number of frames or less
+ bytes_to_transfer = RPMB_FRAME_SIZE * blks_remaining;
+ }
+ else
+ {
+ bytes_to_transfer = RPMB_FRAME_SIZE * rel_wr_count;
+ }
+
// send the request
cdb_out_param = (struct scsi_sec_protocol_cdb*) cdb;
memset(cdb_out_param, 0, sizeof(struct scsi_sec_protocol_cdb));
@@ -190,6 +225,44 @@
cdb_out_param->opcode = SCSI_CMD_SECPROT_OUT;
cdb_out_param->cdb1 = SCSI_SEC_PROT;
cdb_out_param->sec_protocol_specific = BE16(SCSI_SEC_UFS_PROT_ID);
+ cdb_out_param->alloc_tlen = BE32(bytes_to_transfer);
+
+ // Flush CDB to memory
+ dsb();
+ arch_clean_invalidate_cache_range((addr_t) cdb_out_param, sizeof(struct scsi_sec_protocol_cdb));
+
+ memset(&req_upiu, 0, sizeof(struct scsi_req_build_type));
+
+ req_upiu.cdb = (addr_t) cdb_out_param;
+ req_upiu.data_buffer_addr = (addr_t) req_buf;
+ req_upiu.data_len = bytes_to_transfer;
+ req_upiu.flags = UPIU_FLAGS_WRITE;
+ req_upiu.lun = UFS_WLUN_RPMB;
+ req_upiu.dd = UTRD_TARGET_TO_SYSTEM;
+
+#ifdef DEBUG_RPMB
+ dprintf(INFO, "Sending RPMB write request: Start\n");
+ for(uint8_t j = 0; j < (bytes_to_transfer/RPMB_FRAME_SIZE); j++)
+ {
+ dprintf(INFO, "request buffer address: %p\n", (req_buf + (j * RPMB_FRAME_SIZE)));
+ dump_rpmb_frame((uint8_t *)req_buf + (j * RPMB_FRAME_SIZE), "request");
+ }
+#endif
+ if (ucs_do_scsi_cmd(dev, &req_upiu))
+ {
+ dprintf(CRITICAL, "%s:%d ucs_do_scsi_rpmb_read: failed\n", __func__, __LINE__);
+ return -UFS_FAILURE;
+ }
+#ifdef DEBUG_RPMB
+ dprintf(INFO, "Sending RPMB write request: Done\n");
+#endif
+ // Result Read
+ cdb_out_param = (struct scsi_sec_protocol_cdb*) cdb;
+ memset(cdb_out_param, 0, sizeof(struct scsi_sec_protocol_cdb));
+
+ cdb_out_param->opcode = SCSI_CMD_SECPROT_OUT;
+ cdb_out_param->cdb1 = SCSI_SEC_PROT;
+ cdb_out_param->sec_protocol_specific = BE16(SCSI_SEC_UFS_PROT_ID);
cdb_out_param->alloc_tlen = BE32(RPMB_FRAME_SIZE);
// Flush CDB to memory
@@ -199,39 +272,6 @@
memset(&req_upiu, 0, sizeof(struct scsi_req_build_type));
req_upiu.cdb = (addr_t) cdb_out_param;
- req_upiu.data_buffer_addr = (addr_t) req_buf;
- req_upiu.data_len = RPMB_FRAME_SIZE;
- req_upiu.flags = UPIU_FLAGS_WRITE;
- req_upiu.lun = UFS_WLUN_RPMB;
- req_upiu.dd = UTRD_TARGET_TO_SYSTEM;
-
-#ifdef DEBUG_RPMB
- dprintf(INFO, "Sending RPMB write request: Start\n");
-#endif
- if (ucs_do_scsi_cmd(dev, &req_upiu))
- {
- dprintf(CRITICAL, "%s:%d ucs_do_scsi_rpmb_read: failed\n", __func__, __LINE__);
- return -UFS_FAILURE;
- }
-#ifdef DEBUG_RPMB
- dprintf(INFO, "Sending RPMB write request: Done\n");
-#endif
- // Result Read
- cdb_in_param = (struct scsi_sec_protocol_cdb*) cdb;
- memset(cdb_in_param, 0, sizeof(struct scsi_sec_protocol_cdb));
-
- cdb_in_param->opcode = SCSI_CMD_SECPROT_OUT;
- cdb_in_param->cdb1 = SCSI_SEC_PROT;
- cdb_in_param->sec_protocol_specific = BE16(SCSI_SEC_UFS_PROT_ID);
- cdb_in_param->alloc_tlen = BE32(RPMB_FRAME_SIZE);
-
- // Flush CDB to memory
- dsb();
- arch_clean_invalidate_cache_range((addr_t) cdb_in_param, sizeof(struct scsi_sec_protocol_cdb));
-
- memset(&req_upiu, 0, sizeof(struct scsi_req_build_type));
-
- req_upiu.cdb = (addr_t) cdb_in_param;
req_upiu.data_buffer_addr = (addr_t) &read_result_reg ;
req_upiu.data_len = result_frame_bytes;
req_upiu.flags = UPIU_FLAGS_WRITE;
@@ -247,7 +287,7 @@
return -UFS_FAILURE;
}
#ifdef DEBUG_RPMB
- dprintf(SPEW, "Sending RPMB Result Read Register: Done\n");
+ dprintf(INFO, "Sending RPMB Result Read Register: Done\n");
#endif
// Retrieve verification result
@@ -280,12 +320,34 @@
dprintf(CRITICAL, "%s:%d ucs_do_scsi_rpmb_read: failed\n", __func__, __LINE__);
return -UFS_FAILURE;
}
+ // invalidate response buffer before reading response as this is part of request
+ // buffer overwritten
+ arch_clean_invalidate_cache_range((addr_t) resp_buf, result_frame_bytes);
#ifdef DEBUG_RPMB
- dprintf(SPEW, "Sending RPMB Response for Result Read Register: Done\n");
+ dprintf(INFO, "Sending RPMB Response for Result Read Register: Done\n");
dump_rpmb_frame((uint8_t *)resp_buf, "response");
#endif
- req_buf = (uint32_t*) ((uint8_t*)req_buf + RPMB_BLK_SIZE);
+ if (result->result[0] == 0x80)
+ {
+ dprintf(CRITICAL, "Max write counter reached: \n");
+ break;
+ }
+
+ if (result->result[1])
+ {
+ dprintf(CRITICAL, "UFS RPMB write error: %s\n", str_err[result->result[1]]);
+ break;
+ }
+ if ((num_trans - i) == 1)
+ continue; // last frame no need to increment
+ else
+ {
+ req_buf = (uint32_t*) ((uint8_t*)req_buf + (RPMB_BLK_SIZE * rel_wr_count));
+ // If more than 1 transaction, then until the last loop, we will be transfering
+ // rel_wr_count number of half sections in one transaction
+ blks_remaining = blks_remaining - rel_wr_count;
+ }
}
*resp_len = RPMB_MIN_BLK_CNT * RPMB_BLK_SIZE;
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index d19df24..d1ebd05 100644
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -508,6 +508,23 @@
$(LOCAL_DIR)/mipi_dsi_autopll.o
endif
+ifeq ($(PLATFORM),mdmfermium)
+ OBJS += $(LOCAL_DIR)/qgic.o \
+ $(LOCAL_DIR)/qtimer.o \
+ $(LOCAL_DIR)/qtimer_mmap.o \
+ $(LOCAL_DIR)/interrupts.o \
+ $(LOCAL_DIR)/clock.o \
+ $(LOCAL_DIR)/clock_pll.o \
+ $(LOCAL_DIR)/clock_lib2.o \
+ $(LOCAL_DIR)/uart_dm.o \
+ $(LOCAL_DIR)/board.o \
+ $(LOCAL_DIR)/spmi.o \
+ $(LOCAL_DIR)/bam.o \
+ $(LOCAL_DIR)/qpic_nand.o \
+ $(LOCAL_DIR)/scm.o \
+ $(LOCAL_DIR)/dev_tree.o
+endif
+
ifeq ($(PLATFORM),msm8996)
DEFINES += DISPLAY_TYPE_MDSS=1
OBJS += $(LOCAL_DIR)/qtimer.o \
diff --git a/platform/msm_shared/sdhci.c b/platform/msm_shared/sdhci.c
index 72126bf..bfab9f1 100644
--- a/platform/msm_shared/sdhci.c
+++ b/platform/msm_shared/sdhci.c
@@ -863,7 +863,7 @@
/* Enable auto cmd23 or cmd12 for multi block transfer
* based on what command card supports
*/
- if (cmd->data.num_blocks > 1) {
+ if ((cmd->data.num_blocks > 1) && !cmd->rel_write) {
if (cmd->cmd23_support) {
trans_mode |= SDHCI_TRANS_MULTI | SDHCI_AUTO_CMD23_EN | SDHCI_BLK_CNT_EN;
REG_WRITE32(host, cmd->data.num_blocks, SDHCI_ARG2_REG);
@@ -871,6 +871,9 @@
else
trans_mode |= SDHCI_TRANS_MULTI | SDHCI_AUTO_CMD12_EN | SDHCI_BLK_CNT_EN;
}
+ else if ((cmd->data.num_blocks > 1) && cmd->rel_write) {
+ trans_mode |= SDHCI_TRANS_MULTI | SDHCI_BLK_CNT_EN;
+ }
}
/* Write to transfer mode register */
diff --git a/platform/msm_shared/smem.h b/platform/msm_shared/smem.h
index 5067b8a..aa8cd1f 100644
--- a/platform/msm_shared/smem.h
+++ b/platform/msm_shared/smem.h
@@ -428,6 +428,7 @@
APQ8076 = 277,
MSM8976 = 278,
APQ8052 = 289,
+ MDMFERMIUM = 290,
APQ8096 = 291,
};
diff --git a/project/mdmfermium.mk b/project/mdmfermium.mk
new file mode 100644
index 0000000..970594c
--- /dev/null
+++ b/project/mdmfermium.mk
@@ -0,0 +1,28 @@
+# top level project rules for the fermium project
+#
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+TARGET := mdmfermium
+
+MODULES += app/aboot
+
+ifeq ($(TARGET_BUILD_VARIANT),user)
+DEBUG := 0
+else
+DEBUG := 1
+endif
+
+DEFINES += WITH_DEBUG_UART=1
+DEFINES += DEVICE_TREE=1
+
+DEFINES += BAM_V170=1
+#Disable thumb mode
+ENABLE_THUMB := false
+
+#Override linker for mdm targets
+LD := $(TOOLCHAIN_PREFIX)ld.bfd
+
+ENABLE_SMD_SUPPORT := 1
+ifeq ($(ENABLE_SMD_SUPPORT),1)
+DEFINES += SMD_SUPPORT=1
+endif
diff --git a/project/msm8996.mk b/project/msm8996.mk
index eecf740..9dd510b 100644
--- a/project/msm8996.mk
+++ b/project/msm8996.mk
@@ -36,10 +36,10 @@
DEFINES += ABOOT_IGNORE_BOOT_HEADER_ADDRS=1
-DEFINES += ABOOT_FORCE_KERNEL_ADDR=0x80008000
-DEFINES += ABOOT_FORCE_RAMDISK_ADDR=0x82200000
-DEFINES += ABOOT_FORCE_TAGS_ADDR=0x82000000
-DEFINES += ABOOT_FORCE_KERNEL64_ADDR=0x80080000
+DEFINES += ABOOT_FORCE_KERNEL_ADDR=0x20008000
+DEFINES += ABOOT_FORCE_RAMDISK_ADDR=0x22200000
+DEFINES += ABOOT_FORCE_TAGS_ADDR=0x22000000
+DEFINES += ABOOT_FORCE_KERNEL64_ADDR=0x20080000
DEFINES += USB_RESET_FROM_CLK=1
DEFINES += USE_BOOTDEV_CMDLINE=1
DEFINES += USE_RPMB_FOR_DEVINFO=1
@@ -77,11 +77,6 @@
DEFINES += MDTP_EFUSE_START=0
endif
-ENABLE_WDOG_SUPPORT := 1
-ifeq ($(ENABLE_WDOG_SUPPORT),1)
-DEFINES += WDOG_SUPPORT=1
-endif
-
ifeq ($(ENABLE_LPAE_SUPPORT),1)
DEFINES += LPAE=1
endif
diff --git a/target/mdm9640/init.c b/target/mdm9640/init.c
index 567ccde..2d2bb4b 100644
--- a/target/mdm9640/init.c
+++ b/target/mdm9640/init.c
@@ -84,7 +84,7 @@
#define LAST_NAND_PTN_LEN_PATTERN 0xFFFFFFFF
#define EXT4_CMDLINE " rootwait rootfstype=ext4 root=/dev/mmcblk0p"
-#define UBI_CMDLINE " rootfstype=ubifs rootflags=bulk_read ubi.fm_autoconvert=1"
+#define UBI_CMDLINE " rootfstype=ubifs rootflags=bulk_read"
struct qpic_nand_init_config config;
@@ -135,6 +135,8 @@
{
dprintf(INFO, "target_init()\n");
+ pmic_info_populate();
+
spmi_init(PMIC_ARB_CHANNEL_NUM, PMIC_ARB_OWNER_ID);
if (platform_boot_dev_isemmc()) {
diff --git a/target/mdmfermium/init.c b/target/mdmfermium/init.c
new file mode 100644
index 0000000..7e32f52
--- /dev/null
+++ b/target/mdmfermium/init.c
@@ -0,0 +1,279 @@
+/* Copyright (c) 2015, 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 <platform/iomap.h>
+#include <reg.h>
+#include <target.h>
+#include <platform.h>
+#include <uart_dm.h>
+#include <platform/gpio.h>
+#include <lib/ptable.h>
+#include <qpic_nand.h>
+#include <dev/keys.h>
+#include <spmi_v2.h>
+#include <pm8x41.h>
+#include <board.h>
+#include <baseband.h>
+#include <hsusb.h>
+#include <scm.h>
+#include <platform/gpio.h>
+#include <platform/gpio.h>
+#include <platform/irqs.h>
+#include <platform/clock.h>
+#include <crypto5_wrapper.h>
+#include <partition_parser.h>
+#include <stdlib.h>
+
+#if LONG_PRESS_POWER_ON
+#include <shutdown_detect.h>
+#endif
+
+#define FASTBOOT_MODE 0x77665500
+#define PON_SOFT_RB_SPARE 0x88F
+
+extern void smem_ptable_init(void);
+extern void smem_add_modem_partitions(struct ptable *flash_ptable);
+
+static struct ptable flash_ptable;
+
+/* PMIC config data */
+#define PMIC_ARB_CHANNEL_NUM 0
+#define PMIC_ARB_OWNER_ID 0
+
+/* NANDc BAM pipe numbers */
+#define DATA_CONSUMER_PIPE 0
+#define DATA_PRODUCER_PIPE 1
+#define CMD_PIPE 2
+
+/* NANDc BAM pipe groups */
+#define DATA_PRODUCER_PIPE_GRP 0
+#define DATA_CONSUMER_PIPE_GRP 0
+#define CMD_PIPE_GRP 1
+
+/* NANDc EE */
+#define QPIC_NAND_EE 0
+
+/* NANDc max desc length. */
+#define QPIC_NAND_MAX_DESC_LEN 0x7FFF
+
+#define LAST_NAND_PTN_LEN_PATTERN 0xFFFFFFFF
+
+struct qpic_nand_init_config config;
+
+void update_ptable_names(void)
+{
+ uint32_t ptn_index;
+ struct ptentry *ptentry_ptr = flash_ptable.parts;
+ struct ptentry *boot_ptn;
+ unsigned i;
+ uint32_t len;
+
+ /* Change all names to lower case. */
+ for (ptn_index = 0; ptn_index != (uint32_t)flash_ptable.count; ptn_index++)
+ {
+ len = strlen(ptentry_ptr[ptn_index].name);
+ for (i = 0; i < len; i++)
+ {
+ if (isupper(ptentry_ptr[ptn_index].name[i]))
+ {
+ ptentry_ptr[ptn_index].name[i] = tolower(ptentry_ptr[ptn_index].name[i]);
+ }
+ }
+ /* SBL fills in the last partition length as 0xFFFFFFFF.
+ * Update the length field based on the number of blocks on the flash.*/
+ if ((uint32_t)(ptentry_ptr[ptn_index].length) == LAST_NAND_PTN_LEN_PATTERN)
+ {
+ ptentry_ptr[ptn_index].length = flash_num_blocks() - ptentry_ptr[ptn_index].start;
+ }
+ }
+}
+
+void target_early_init(void)
+{
+#if WITH_DEBUG_UART
+ uart_dm_init(1, 0, BLSP1_UART1_BASE);
+#endif
+}
+
+/* Configure PMIC and Drop PS_HOLD for shutdown */
+void shutdown_device()
+{
+ dprintf(CRITICAL, "Going down for shutdown.\n");
+
+ /* Configure PMIC for shutdown */
+ pm8x41_reset_configure(PON_PSHOLD_SHUTDOWN);
+
+ /* Drop PS_HOLD for MSM */
+ writel(0x00, MPM2_MPM_PS_HOLD);
+
+ mdelay(5000);
+
+ dprintf(CRITICAL, "shutdown failed\n");
+
+ ASSERT(0);
+}
+
+
+void target_init(void)
+{
+ uint32_t base_addr;
+ uint8_t slot;
+
+ dprintf(INFO, "target_init()\n");
+
+ spmi_init(PMIC_ARB_CHANNEL_NUM, PMIC_ARB_OWNER_ID);
+
+ config.pipes.read_pipe = DATA_PRODUCER_PIPE;
+ config.pipes.write_pipe = DATA_CONSUMER_PIPE;
+ config.pipes.cmd_pipe = CMD_PIPE;
+
+ config.pipes.read_pipe_grp = DATA_PRODUCER_PIPE_GRP;
+ config.pipes.write_pipe_grp = DATA_CONSUMER_PIPE_GRP;
+ config.pipes.cmd_pipe_grp = CMD_PIPE_GRP;
+
+ config.bam_base = MSM_NAND_BAM_BASE;
+ config.nand_base = MSM_NAND_BASE;
+ config.ee = QPIC_NAND_EE;
+ config.max_desc_len = QPIC_NAND_MAX_DESC_LEN;
+
+ qpic_nand_init(&config);
+
+ ptable_init(&flash_ptable);
+ //smem_ptable_init();
+ //smem_add_modem_partitions(&flash_ptable);
+
+ update_ptable_names();
+ flash_set_ptable(&flash_ptable);
+}
+
+/* Identify the current target */
+void target_detect(struct board_data *board)
+{
+ /* This property is filled as part of board.c */
+}
+
+unsigned board_machtype(void)
+{
+}
+
+/* Identify the baseband being used */
+void target_baseband_detect(struct board_data *board)
+{
+ uint32_t platform = board->platform;
+
+ switch(platform)
+ {
+ case MDMFERMIUM:
+ board->baseband = BASEBAND_MDM;
+ break;
+ default:
+ dprintf(CRITICAL, "Platform type: %u is not supported\n", platform);
+ ASSERT(0);
+ };
+}
+
+unsigned check_reboot_mode(void)
+{
+ uint32_t restart_reason = 0;
+
+ /* Read reboot reason and scrub it */
+ restart_reason = readl(RESTART_REASON_ADDR);
+ writel(0x00, RESTART_REASON_ADDR);
+
+ return restart_reason;
+}
+
+int get_target_boot_params(const char *cmdline, const char *part, char *buf,int buflen)
+{
+ struct ptable *ptable;
+ int system_ptn_index = -1;
+
+ ptable = flash_get_ptable();
+ if (!ptable) {
+ dprintf(CRITICAL,"WARN: Cannot get flash partition table\n");
+ return -1;
+ }
+
+ system_ptn_index = ptable_get_index(ptable, part);
+ if (system_ptn_index < 0) {
+ dprintf(CRITICAL,"WARN: Cannot get partition index for %s\n", part);
+ return -1;
+ }
+ /*check if cmdline contains "root=" at the beginning of buffer or
+ * " root=" in the middle of buffer.
+ */
+ if (((!strncmp(cmdline, "root=", strlen("root="))) ||
+ (strstr(cmdline, " root="))))
+ dprintf(DEBUG, "DEBUG: cmdline has root=\n");
+ else
+ snprintf(buf, buflen, " root=/dev/mtdblock%d",system_ptn_index);
+ return 0;
+}
+
+void target_usb_init(void)
+{
+ uint32_t val;
+
+ /* Select and enable external configuration with USB PHY */
+ //ulpi_write(ULPI_MISC_A_VBUSVLDEXTSEL | ULPI_MISC_A_VBUSVLDEXT, ULPI_MISC_A_SET);
+
+ /* Enable sess_vld */
+ val = readl(USB_GENCONFIG_2) | GEN2_SESS_VLD_CTRL_EN;
+ writel(val, USB_GENCONFIG_2);
+
+ /* Enable external vbus configuration in the LINK */
+ val = readl(USB_USBCMD);
+ val |= SESS_VLD_CTRL;
+ writel(val, USB_USBCMD);
+}
+
+void target_uninit(void)
+{
+}
+
+void reboot_device(unsigned reboot_reason)
+{
+ /* Write the reboot reason */
+ writel(reboot_reason, RESTART_REASON_ADDR);
+
+ /* Configure PMIC for warm reset */
+ /* PM 8019 v1 aligns with PM8941 v2.
+ * This call should be based on the pmic version
+ * when PM8019 v2 is available.
+ */
+ pm8x41_v2_reset_configure(PON_PSHOLD_WARM_RESET);
+
+ /* Drop PS_HOLD for MSM */
+ writel(0x00, MPM2_MPM_PS_HOLD);
+
+ mdelay(5000);
+
+ dprintf(CRITICAL, "Rebooting failed\n");
+ return;
+}
diff --git a/target/mdmfermium/keypad.c b/target/mdmfermium/keypad.c
new file mode 100644
index 0000000..a57a2f8
--- /dev/null
+++ b/target/mdmfermium/keypad.c
@@ -0,0 +1,63 @@
+/* Copyright (c) 2015, 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 <reg.h>
+#include <platform/gpio.h>
+#include <platform/iomap.h>
+
+/* GPIO that controls the button
+ * for FASTBOOT.
+ */
+#define FASTBOOT_KEY_GPIO_ID 37
+
+/*
+ * Returns fastboot button state.
+ * Returns 0 if button is not pressed, 1 when pressed.
+ */
+int get_fastboot_key_state(void)
+{
+ int ret;
+
+ gpio_tlmm_config(FASTBOOT_KEY_GPIO_ID, 0, GPIO_INPUT, GPIO_PULL_DOWN, GPIO_2MA, GPIO_ENABLE);
+
+ ret = gpio_get_state(FASTBOOT_KEY_GPIO_ID);
+
+ return ret;
+}
+
+/*
+* Return 1 to trigger to fastboot
+*/
+int fastboot_trigger(void)
+{
+ int ret;
+
+ ret = get_fastboot_key_state();
+
+ return (ret);
+}
diff --git a/target/mdmfermium/meminfo.c b/target/mdmfermium/meminfo.c
new file mode 100644
index 0000000..b66166e
--- /dev/null
+++ b/target/mdmfermium/meminfo.c
@@ -0,0 +1,95 @@
+/* Copyright (c) 2015, 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 <reg.h>
+#include <debug.h>
+#include <malloc.h>
+#include <smem.h>
+#include <stdint.h>
+#include <libfdt.h>
+#include <platform/iomap.h>
+#include <dev_tree.h>
+
+#define SIZE_1M (1024 * 1024)
+static struct smem_ram_ptable ram_ptable;
+struct smem_ram_ptable* target_smem_ram_ptable_init()
+{
+ /* Make sure RAM partition table is initialized */
+ ASSERT(smem_ram_ptable_init(&ram_ptable));
+ return &ram_ptable;
+}
+
+uint32_t target_dev_tree_mem(void *fdt, uint32_t memory_node_offset)
+{
+ ram_partition ptn_entry;
+ unsigned int index;
+ int ret = 0;
+ uint32_t len = 0;
+
+ /* Make sure RAM partition table is initialized */
+ ASSERT(smem_ram_ptable_init_v1());
+
+ len = smem_get_ram_ptable_len();
+
+ /* Calculating the size of the mem_info_ptr */
+ for (index = 0 ; index < len; index++)
+ {
+ smem_get_ram_ptable_entry(&ptn_entry, index);
+
+ if((ptn_entry.category == SDRAM) &&
+ (ptn_entry.type == SYS_MEMORY))
+ {
+
+ /* Pass along all other usable memory regions to Linux */
+ ret = dev_tree_add_mem_info(fdt,
+ memory_node_offset,
+ ptn_entry.start,
+ ptn_entry.size);
+
+ if (ret)
+ {
+ dprintf(CRITICAL, "Failed to add secondary banks memory addresses\n");
+ goto target_dev_tree_mem_err;
+ }
+ }
+ }
+target_dev_tree_mem_err:
+
+ return ret;
+}
+
+void *target_get_scratch_address(void)
+{
+ return ((void *)SCRATCH_ADDR);
+}
+
+unsigned target_get_max_flash_size(void)
+{
+ /*24.5MB*/
+ return (SCRATCH_REGION1_SIZE + SCRATCH_REGION2_SIZE);
+}
diff --git a/target/mdmfermium/rules.mk b/target/mdmfermium/rules.mk
new file mode 100644
index 0000000..ed3553f
--- /dev/null
+++ b/target/mdmfermium/rules.mk
@@ -0,0 +1,45 @@
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared
+
+PLATFORM := mdmfermium
+
+MEMBASE := 0x87A00000 # SDRAM
+MEMSIZE := 0x00100000 # 1MB
+
+SCRATCH_ADDR := 0x81200000
+SCRATCH_REGION1 := 0x81200000
+SCRATCH_REGION1_SIZE := 0x1800000 # 24MB
+SCRATCH_REGION2 := 0x87F80000
+SCRATCH_REGION2_SIZE := 0x80000 # 512KB
+
+KERNEL_REGION := 0x80000000
+KERNEL_REGION_SIZE := 0x1200000 # 18MB
+
+BASE_ADDR := 0x80000000
+
+DEFINES += NO_KEYPAD_DRIVER=1
+
+MODULES += \
+ dev/keys \
+ dev/vib \
+ lib/ptable \
+ dev/pmic/pm8x41 \
+ lib/libfdt
+
+DEFINES += \
+ MEMSIZE=$(MEMSIZE) \
+ MEMBASE=$(MEMBASE) \
+ BASE_ADDR=$(BASE_ADDR) \
+ SCRATCH_ADDR=$(SCRATCH_ADDR) \
+ SCRATCH_REGION1=$(SCRATCH_REGION1) \
+ SCRATCH_REGION2=$(SCRATCH_REGION2) \
+ SCRATCH_REGION1_SIZE=$(SCRATCH_REGION1_SIZE) \
+ SCRATCH_REGION2_SIZE=$(SCRATCH_REGION2_SIZE) \
+ KERNEL_REGION=$(KERNEL_REGION) \
+ KERNEL_REGION_SIZE=$(KERNEL_REGION_SIZE)
+
+OBJS += \
+ $(LOCAL_DIR)/init.o \
+ $(LOCAL_DIR)/meminfo.o \
+ $(LOCAL_DIR)/keypad.o
diff --git a/target/mdmfermium/tools/makefile b/target/mdmfermium/tools/makefile
new file mode 100644
index 0000000..8486761
--- /dev/null
+++ b/target/mdmfermium/tools/makefile
@@ -0,0 +1,14 @@
+#Makefile to generate appsboot.mbn
+
+ifeq ($(BOOTLOADER_OUT),.)
+APPSBOOTOUT_DIR := $(BUILDDIR)
+else
+APPSBOOTOUT_DIR := $(BOOTLOADER_OUT)/../..
+endif
+
+ABOOTMBN := appsboot.mbn
+APPSBOOTHEADER: $(ABOOTMBN)
+
+$(ABOOTMBN): $(OUTELF_STRIP) $(OUTBIN)
+ cp $(OUTBIN) $(APPSBOOTOUT_DIR)/appsboot.raw
+ $(hide) cp -f $(OUTELF_STRIP) $(APPSBOOTOUT_DIR)/$(ABOOTMBN)
diff --git a/target/msm8952/include/target/display.h b/target/msm8952/include/target/display.h
index 5c02765..87cbc3a 100644
--- a/target/msm8952/include/target/display.h
+++ b/target/msm8952/include/target/display.h
@@ -91,8 +91,6 @@
#define MIPI_VSYNC_BACK_PORCH_LINES 3
#define MIPI_VSYNC_FRONT_PORCH_LINES 9
-#endif
-
/*---------------------------------------------------------------------------*/
/* Functions */
/*---------------------------------------------------------------------------*/
@@ -104,3 +102,6 @@
int target_display_get_base_offset(uint32_t base);
void target_force_cont_splash_disable(uint8_t override);
uint8_t target_panel_auto_detect_enabled();
+uint32_t oem_panel_max_auto_detect_panels();
+
+#endif
diff --git a/target/msm8952/init.c b/target/msm8952/init.c
index 99550f5..e1a61c4 100644
--- a/target/msm8952/init.c
+++ b/target/msm8952/init.c
@@ -503,6 +503,23 @@
splash_override = override;
}
+uint8_t target_panel_auto_detect_enabled()
+{
+ uint8_t ret = 0;
+
+ switch(board_hardware_id())
+ {
+ case HW_PLATFORM_QRD:
+ ret = platform_is_msm8956() ? 1 : 0;
+ break;
+ case HW_PLATFORM_SURF:
+ case HW_PLATFORM_MTP:
+ default:
+ ret = 0;
+ }
+ return ret;
+}
+
/* Do any target specific intialization needed before entering fastboot mode */
void target_fastboot_init(void)
{
diff --git a/target/msm8952/oem_panel.c b/target/msm8952/oem_panel.c
index b64ac32..603f990 100644
--- a/target/msm8952/oem_panel.c
+++ b/target/msm8952/oem_panel.c
@@ -49,6 +49,7 @@
#include "include/panel_sharp_1080p_cmd.h"
#include "include/panel_nt35597_wqxga_dualdsi_video.h"
#include "include/panel_nt35597_wqxga_dualdsi_cmd.h"
+#include "include/panel_hx8399a_1080p_video.h"
/*---------------------------------------------------------------------------*/
/* static panel selection variable */
@@ -60,6 +61,7 @@
SHARP_1080P_CMD_PANEL,
NT35597_WQXGA_DUALDSI_VIDEO_PANEL,
NT35597_WQXGA_DUALDSI_CMD_PANEL,
+ HX8399A_1080P_VIDEO_PANEL,
UNKNOWN_PANEL
};
@@ -77,6 +79,8 @@
{"sharp_1080p_cmd", SHARP_1080P_CMD_PANEL},
{"nt35597_wqxga_dualdsi_video", NT35597_WQXGA_DUALDSI_VIDEO_PANEL},
{"nt35597_wqxga_dualdsi_cmd", NT35597_WQXGA_DUALDSI_CMD_PANEL},
+ {"otm1906c_1080p_cmd", OTM1906C_1080P_CMD_PANEL},
+ {"hx8399a_1080p_video", HX8399A_1080P_VIDEO_PANEL},
};
static uint32_t panel_id;
@@ -198,6 +202,31 @@
otm1906c_1080p_cmd_timings, TIMING_SIZE);
pinfo->mipi.signature = OTM1906C_1080P_CMD_SIGNATURE;
break;
+ case HX8399A_1080P_VIDEO_PANEL:
+ panelstruct->paneldata = &hx8399a_1080p_video_panel_data;
+ panelstruct->panelres = &hx8399a_1080p_video_panel_res;
+ panelstruct->color = &hx8399a_1080p_video_color;
+ panelstruct->videopanel = &hx8399a_1080p_video_video_panel;
+ panelstruct->commandpanel = &hx8399a_1080p_video_command_panel;
+ panelstruct->state = &hx8399a_1080p_video_state;
+ panelstruct->laneconfig = &hx8399a_1080p_video_lane_config;
+ panelstruct->paneltiminginfo
+ = &hx8399a_1080p_video_timing_info;
+ panelstruct->panelresetseq
+ = &hx8399a_1080p_video_reset_seq;
+ panelstruct->backlightinfo = &hx8399a_1080p_video_backlight;
+ pinfo->mipi.panel_on_cmds
+ = hx8399a_1080p_video_on_command;
+ pinfo->mipi.num_of_panel_on_cmds
+ = HX8399A_1080P_VIDEO_ON_COMMAND;
+ pinfo->mipi.panel_off_cmds
+ = hx8399a_1080p_video_off_command;
+ pinfo->mipi.num_of_panel_off_cmds
+ = HX8399A_1080P_VIDEO_OFF_COMMAND;
+ memcpy(phy_db->timing,
+ hx8399a_1080p_video_timings, TIMING_SIZE);
+ pinfo->mipi.signature = HX8399A_1080P_VIDEO_SIGNATURE;
+ break;
case SHARP_1080P_CMD_PANEL:
panelstruct->paneldata = &sharp_1080p_cmd_panel_data;
panelstruct->panelres = &sharp_1080p_cmd_panel_res;
@@ -268,6 +297,9 @@
panelstruct->laneconfig = &nt35597_wqxga_dualdsi_cmd_lane_config;
panelstruct->paneltiminginfo
= &nt35597_wqxga_dualdsi_cmd_timing_info;
+ /* Clkout timings are different for this panel on 8956 */
+ panelstruct->paneltiminginfo->tclk_post = 0x2b;
+ panelstruct->paneltiminginfo->tclk_pre = 0x28;
panelstruct->panelresetseq
= &nt35597_wqxga_dualdsi_cmd_reset_seq;
panelstruct->backlightinfo = &nt35597_wqxga_dualdsi_cmd_backlight;
@@ -302,6 +334,15 @@
return pan_type;
}
+#define DISPLAY_MAX_PANEL_DETECTION 2
+static uint32_t auto_pan_loop = 0;
+
+uint32_t oem_panel_max_auto_detect_panels()
+{
+ return target_panel_auto_detect_enabled() ?
+ DISPLAY_MAX_PANEL_DETECTION : 0;
+}
+
int oem_panel_select(const char *panel_name, struct panel_struct *panelstruct,
struct msm_panel_info *pinfo,
struct mdss_dsi_phy_ctrl *phy_db)
@@ -341,6 +382,24 @@
break;
case HW_PLATFORM_QRD:
panel_id = OTM1906C_1080P_CMD_PANEL;
+
+ /* QRD EVT1 uses OTM1906C, and EVT2 uses HX8399A */
+ if (platform_is_msm8956()) {
+ switch (auto_pan_loop) {
+ case 0:
+ panel_id = HX8399A_1080P_VIDEO_PANEL;
+ break;
+ case 1:
+ panel_id = OTM1906C_1080P_CMD_PANEL;
+ break;
+ default:
+ panel_id = UNKNOWN_PANEL;
+ dprintf(CRITICAL, "Unknown panel\n");
+ return PANEL_TYPE_UNKNOWN;
+ }
+ auto_pan_loop++;
+ }
+
break;
default:
dprintf(CRITICAL, "Display not enabled for %d HW type\n",
diff --git a/target/msm8952/target_display.c b/target/msm8952/target_display.c
index e89beb5..adc5815 100644
--- a/target/msm8952/target_display.c
+++ b/target/msm8952/target_display.c
@@ -522,6 +522,8 @@
void target_display_init(const char *panel_name)
{
struct oem_panel_data oem;
+ int32_t ret = 0;
+ uint32_t panel_loop = 0;
set_panel_cmd_string(panel_name);
oem = mdss_dsi_get_oem_data();
@@ -535,10 +537,16 @@
return;
}
- if (gcdb_display_init(oem.panel, MDP_REV_50, (void *)MIPI_FB_ADDR)) {
- target_force_cont_splash_disable(true);
- msm_display_off();
- }
+ do {
+ target_force_cont_splash_disable(false);
+ ret = gcdb_display_init(oem.panel, MDP_REV_50, (void *)MIPI_FB_ADDR);
+ if (!ret || ret == ERR_NOT_SUPPORTED) {
+ break;
+ } else {
+ target_force_cont_splash_disable(true);
+ msm_display_off();
+ }
+ } while (++panel_loop <= oem_panel_max_auto_detect_panels());
if (!oem.cont_splash) {
dprintf(INFO, "Forcing continuous splash disable\n");
diff --git a/target/msm8996/rules.mk b/target/msm8996/rules.mk
index 57e3c4a..8966c0a 100644
--- a/target/msm8996/rules.mk
+++ b/target/msm8996/rules.mk
@@ -12,12 +12,11 @@
SCRATCH_ADDR := 0x91100000
SCRATCH_SIZE := 750
-KERNEL_ADDR := 0x80000000
-KERNEL_SIZE := 88
+KERNEL_ADDR := 0x20000000
+KERNEL_SIZE := 512
# LPAE supports only 32 virtual address, L1 pt size is 4
L1_PT_SZ := 4
-L2_PT_SZ := 2
-
+L2_PT_SZ := 3
DEFINES += DISPLAY_SPLASH_SCREEN=1
DEFINES += DISPLAY_TYPE_MIPI=1