Merge "aboot: lib: platform: Fix for banned apis"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 973e4a2..e15879d 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -3011,6 +3011,12 @@
normal_boot:
if (!boot_into_fastboot)
{
+#ifdef MDTP_SUPPORT
+ /* Go through Firmware Lock verification before continue with boot process */
+ mdtp_fwlock_verify_lock();
+ display_image_on_screen();
+#endif /* MDTP_SUPPORT */
+
if (target_is_emmc_boot())
{
if(emmc_recovery_init())
@@ -3028,12 +3034,6 @@
}
}
-#ifdef MDTP_SUPPORT
- /* Go through Firmware Lock verification before continue with boot process */
- mdtp_fwlock_verify_lock();
- display_image_on_screen();
-#endif /* MDTP_SUPPORT */
-
boot_linux_from_mmc();
}
else
diff --git a/app/aboot/mdtp.c b/app/aboot/mdtp.c
index 160f6c8..5c5782a 100644
--- a/app/aboot/mdtp.c
+++ b/app/aboot/mdtp.c
@@ -44,10 +44,22 @@
#define DIP_ENCRYPT 0
#define DIP_DECRYPT 1
+#define MDTP_MAJOR_VERSION (0)
+#define MDTP_MINOR_VERSION (2)
+
+/** Extract major version number from complete version. */
+#define MDTP_GET_MAJOR_VERSION(version) ((version) >> 16)
+
+static int is_mdtp_activated = -1;
+
static int mdtp_tzbsp_dec_verify_DIP(DIP_t *enc_dip, DIP_t *dec_dip, uint32_t *verified);
static int mdtp_tzbsp_enc_hash_DIP(DIP_t *dec_dip, DIP_t *enc_dip);
-static int is_mdtp_activated = -1;
+uint32_t g_mdtp_version = (((MDTP_MAJOR_VERSION << 16) & 0xFFFF0000) | (MDTP_MINOR_VERSION & 0x0000FFFF));
+
+int scm_random(uint32_t * rbuf, uint32_t r_len);
+int check_aboot_addr_range_overlap(uint32_t start, uint32_t size);
+
/********************************************************************************/
/* Read the DIP from EMMC */
@@ -102,7 +114,7 @@
if(mmc_write(ptn, ROUNDUP(sizeof(DIP_t), block_size), (void *)dip))
{
- dprintf(CRITICAL, "mdtp: write_DIP: ERROR, cannot read DIP info\n");
+ dprintf(CRITICAL, "mdtp: write_DIP: ERROR, cannot write DIP info\n");
return -1;
}
@@ -136,6 +148,7 @@
memset(dec_dip, 0, sizeof(DIP_t));
dec_dip->status = DIP_STATUS_DEACTIVATED;
+ dec_dip->version = g_mdtp_version;
ret = mdtp_tzbsp_enc_hash_DIP(dec_dip, enc_dip);
if(ret < 0)
@@ -157,19 +170,20 @@
}
/* Validate a hash calculated on entire given partition */
-static int verify_partition_single_hash(char *name, uint32_t size, DIP_hash_table_entry_t *hash_table)
+static int verify_partition_single_hash(char *name, uint64_t size, DIP_hash_table_entry_t *hash_table)
{
- unsigned char digest[32]={0};
+ unsigned char digest[HASH_LEN]={0};
unsigned long long ptn = 0;
int index = INVALID_PTN;
unsigned char *buf = (unsigned char *)target_get_scratch_address();
uint32_t block_size = mmc_get_device_blocksize();
- uint32_t actual_partition_size = ROUNDUP(size, block_size);
+ uint64_t actual_partition_size = ROUNDUP(size, block_size);
- dprintf(SPEW, "mdtp: verify_partition_single_hash: %s, %u\n", name, size);
+ dprintf(SPEW, "mdtp: verify_partition_single_hash: %s, %llu\n", name, size);
ASSERT(name != NULL);
ASSERT(hash_table != NULL);
+ ASSERT(size > 0);
index = partition_get_index(name);
ptn = partition_get_offset(index);
@@ -181,15 +195,15 @@
if (mmc_read(ptn, (void *)buf, actual_partition_size))
{
- dprintf(CRITICAL, "mdtp: verify_partition__single_hash: %s: mmc_read() fail.\n", name);
+ dprintf(CRITICAL, "mdtp: verify_partition_single_hash: %s: mmc_read() fail.\n", name);
return -1;
}
/* calculating the hash value using HW crypto */
target_crypto_init_params();
- hash_find(buf, size, (unsigned char *)&digest, CRYPTO_AUTH_ALG_SHA256);
+ hash_find(buf, size, digest, CRYPTO_AUTH_ALG_SHA256);
- if (memcmp(&digest[0], &(hash_table->hash[0]), HASH_LEN))
+ if (memcmp(digest, hash_table->hash, HASH_LEN))
{
dprintf(CRITICAL, "mdtp: verify_partition_single_hash: %s: Failed partition hash verification\n", name);
@@ -203,23 +217,27 @@
/* Validate a hash table calculated per block of a given partition */
static int verify_partition_block_hash(char *name,
- uint32_t size,
- uint32_t total_num_blocks,
+ uint64_t size,
uint32_t verify_num_blocks,
DIP_hash_table_entry_t *hash_table,
- uint8_t *force_verify_block)
+ uint8_t *force_verify_block)
{
- unsigned char digest[32]={0};
+ unsigned char digest[HASH_LEN]={0};
unsigned long long ptn = 0;
int index = INVALID_PTN;
unsigned char *buf = (unsigned char *)target_get_scratch_address();
uint32_t bytes_to_read;
uint32_t block_num = 0;
+ uint32_t total_num_blocks = ((size - 1) / MDTP_FWLOCK_BLOCK_SIZE) + 1;
+ uint32_t rand_int;
+ uint32_t block_size = mmc_get_device_blocksize();
- dprintf(SPEW, "mdtp: verify_partition_block_hash: %s, %u\n", name, size);
+ dprintf(SPEW, "mdtp: verify_partition_block_hash: %s, %llu\n", name, size);
ASSERT(name != NULL);
ASSERT(hash_table != NULL);
+ ASSERT(size > 0);
+ ASSERT(force_verify_block != NULL);
index = partition_get_index(name);
ptn = partition_get_offset(index);
@@ -231,13 +249,24 @@
/* initiating parameters for hash calculation using HW crypto */
target_crypto_init_params();
+ if (check_aboot_addr_range_overlap((uint32_t)buf, ROUNDUP(MDTP_FWLOCK_BLOCK_SIZE, block_size)))
+ {
+ dprintf(CRITICAL, "mdtp: verify_partition_block_hash: %s: image buffer address overlaps with aboot addresses.\n", name);
+ return -1;
+ }
while (MDTP_FWLOCK_BLOCK_SIZE * block_num < size)
{
if (*force_verify_block == 0)
{
+ if(scm_random((uint32_t *)&rand_int, sizeof(rand_int)))
+ {
+ dprintf(CRITICAL,"mdtp: scm_call for random failed\n");
+ return -1;
+ }
+
/* Skip validation of this block with probability of verify_num_blocks / total_num_blocks */
- if ((rand() % total_num_blocks) >= verify_num_blocks)
+ if ((rand_int % total_num_blocks) >= verify_num_blocks)
{
block_num++;
hash_table += 1;
@@ -255,16 +284,16 @@
bytes_to_read = MDTP_FWLOCK_BLOCK_SIZE;
}
- if (mmc_read(ptn + (MDTP_FWLOCK_BLOCK_SIZE * block_num), (void *)buf, bytes_to_read))
+ if (mmc_read(ptn + (MDTP_FWLOCK_BLOCK_SIZE * block_num), (void *)buf, ROUNDUP(bytes_to_read, block_size)))
{
dprintf(CRITICAL, "mdtp: verify_partition_block_hash: %s: mmc_read() fail.\n", name);
return -1;
}
/* calculating the hash value using HW */
- hash_find(buf, bytes_to_read, (unsigned char *)&digest, CRYPTO_AUTH_ALG_SHA256);
+ hash_find(buf, bytes_to_read, digest, CRYPTO_AUTH_ALG_SHA256);
- if (memcmp(&digest[0], &(hash_table->hash[0]), HASH_LEN))
+ if (memcmp(digest, hash_table->hash, HASH_LEN))
{
dprintf(CRITICAL, "mdtp: verify_partition_block_hash: %s: Failed partition hash[%d] verification\n", name, block_num);
return -1;
@@ -280,42 +309,80 @@
return 0;
}
-/* Verify a given partitinon */
-static int verify_partition(char *name,
- uint32_t size,
+/* Validate the partition parameters read from DIP */
+static int validate_partition_params(uint64_t size,
mdtp_fwlock_mode_t hash_mode,
- uint32_t total_num_blocks,
- uint32_t verify_num_blocks,
- DIP_hash_table_entry_t *hash_table,
- uint8_t *force_verify_block)
+ uint32_t verify_ratio)
{
-
- ASSERT(name != NULL);
- ASSERT(hash_table != NULL);
-
- if (hash_mode == MDTP_FWLOCK_MODE_SINGLE)
+ if (size == 0 || size > (uint64_t)MDTP_FWLOCK_BLOCK_SIZE * (uint64_t)MAX_BLOCKS ||
+ hash_mode >= MDTP_FWLOCK_MODE_SIZE || verify_ratio > 100)
{
- return verify_partition_single_hash(name, size, hash_table);
- } else if (hash_mode == MDTP_FWLOCK_MODE_BLOCK || hash_mode == MDTP_FWLOCK_MODE_FILES)
- {
- return verify_partition_block_hash(name, size, total_num_blocks, verify_num_blocks, hash_table, force_verify_block);
- }
- else
- {
- dprintf(CRITICAL, "mdtp: verify_partition: %s: Wrong DIP partition hash mode\n", name);
+ dprintf(CRITICAL, "mdtp: validate_partition_params: error, size=%llu, hash_mode=%d, verify_ratio=%d\n",
+ size, hash_mode, verify_ratio);
return -1;
}
return 0;
}
+/* Verify a given partitinon */
+static int verify_partition(char *name,
+ uint64_t size,
+ mdtp_fwlock_mode_t hash_mode,
+ uint32_t verify_num_blocks,
+ DIP_hash_table_entry_t *hash_table,
+ uint8_t *force_verify_block)
+{
+ if (hash_mode == MDTP_FWLOCK_MODE_SINGLE)
+ {
+ return verify_partition_single_hash(name, size, hash_table);
+ } else if (hash_mode == MDTP_FWLOCK_MODE_BLOCK || hash_mode == MDTP_FWLOCK_MODE_FILES)
+ {
+ return verify_partition_block_hash(name, size, verify_num_blocks, hash_table, force_verify_block);
+ }
+
+ /* Illegal value of hash_mode */
+ return -1;
+}
+
+static int validate_dip(DIP_t *dip)
+{
+ uint8_t *dip_p;
+
+ ASSERT(dip != NULL);
+
+ /* Make sure DIP version is supported by current SW */
+ if (MDTP_GET_MAJOR_VERSION(dip->version) != MDTP_MAJOR_VERSION)
+ {
+ dprintf(CRITICAL, "mdtp: validate_dip: Wrong DIP version 0x%x\n", dip->version);
+ return -1;
+ }
+
+ /* Make sure that deactivated DIP content is as expected */
+ if (dip->status == DIP_STATUS_DEACTIVATED)
+ {
+ dip_p = (uint8_t*)&dip->mdtp_cfg;
+ while (dip_p < dip->hash)
+ {
+ if (*dip_p != 0)
+ {
+ dprintf(CRITICAL, "mdtp: validate_dip: error in deactivated DIP\n");
+ return -1;
+ }
+ dip_p++;
+ }
+ }
+
+ return 0;
+}
+
/* Display the recovery UI to allow the user to enter the PIN and continue boot */
-static int display_recovery_ui(DIP_t *dip)
+static void display_recovery_ui(DIP_t *dip)
{
uint32_t pin_length = 0;
char entered_pin[MDTP_MAX_PIN_LEN+1] = {0};
uint32_t i;
- uint32_t equal_count = 0, different_count = 0;
+ char pin_mismatch = 0;
if (dip->mdtp_cfg.enable_local_pin_authentication)
{
@@ -326,8 +393,7 @@
if (pin_length > MDTP_MAX_PIN_LEN || pin_length < MDTP_MIN_PIN_LEN)
{
dprintf(CRITICAL, "mdtp: display_recovery_ui: Error, invalid PIN length\n");
- display_error_msg();
- return -1;
+ display_error_msg(); /* This will never return */
}
// Set entered_pin to initial '0' string + null terminator
@@ -340,49 +406,44 @@
// (with INVALID_PIN_DELAY_MSECONDS after each failed attempt)
while (1)
{
- get_pin_from_user(entered_pin, pin_length);
+ get_pin_from_user(entered_pin, pin_length);
- // Go over the entire PIN in any case, to prevent side-channel attacks
- for (i=0; i<pin_length; i++)
- {
- if (dip->mdtp_cfg.mdtp_pin.mdtp_pin[i] == entered_pin[i])
- equal_count++;
- else
- different_count++;
- }
+ // Go over the entire PIN in any case, to prevent side-channel attacks
+ for (i=0; i<pin_length; i++)
+ {
+ pin_mismatch |= dip->mdtp_cfg.mdtp_pin.mdtp_pin[i] ^ entered_pin[i];
+ }
- if (equal_count == pin_length)
- {
- // Valid PIN - deactivate and continue boot
- dprintf(SPEW, "mdtp: display_recovery_ui: valid PIN, continue boot\n");
- write_deactivated_DIP();
- return 0;
- }
- else
- {
- // Invalid PIN - display an appropriate message (which also includes a wait
- // for INVALID_PIN_DELAY_MSECONDS), and allow the user to try again
- dprintf(CRITICAL, "mdtp: display_recovery_ui: ERROR, invalid PIN\n");
- display_invalid_pin_msg();
+ if (0 == pin_mismatch)
+ {
+ // Valid PIN - deactivate and continue boot
+ dprintf(SPEW, "mdtp: display_recovery_ui: valid PIN, continue boot\n");
+ write_deactivated_DIP();
+ return;
+ }
+ else
+ {
+ // Invalid PIN - display an appropriate message (which also includes a wait
+ // for INVALID_PIN_DELAY_MSECONDS), and allow the user to try again
+ dprintf(CRITICAL, "mdtp: display_recovery_ui: ERROR, invalid PIN\n");
+ display_invalid_pin_msg();
- equal_count = 0;
- different_count = 0;
- }
+ pin_mismatch = 0;
+ }
}
}
else
{
dprintf(CRITICAL, "mdtp: display_recovery_ui: Local deactivation disabled, unable to display recovery UI\n");
- display_error_msg();
- return -1;
+ display_error_msg(); /* This will never return */
}
}
/* Verify all protected partitinons according to the DIP */
-static int verify_all_partitions(DIP_t *dip, verify_result_t *verify_result)
+static void verify_all_partitions(DIP_t *dip, verify_result_t *verify_result)
{
int i;
- int verify_failure = 0;
+ bool verify_failure = FALSE;
uint32_t total_num_blocks;
ASSERT(dip != NULL);
@@ -390,40 +451,53 @@
*verify_result = VERIFY_FAILED;
+ if (validate_dip(dip))
+ {
+ dprintf(CRITICAL, "mdtp: verify_all_partitions: failed DIP validation\n");
+ return;
+ }
+
if (dip->status == DIP_STATUS_DEACTIVATED)
{
*verify_result = VERIFY_SKIPPED;
- return 0;
+ return;
}
- else if (dip->status == DIP_STATUS_ACTIVATED)
+ else
{
for(i=0; i<MAX_PARTITIONS; i++)
{
if(dip->partition_cfg[i].lock_enabled && dip->partition_cfg[i].size)
{
total_num_blocks = ((dip->partition_cfg[i].size - 1) / MDTP_FWLOCK_BLOCK_SIZE);
+ if (validate_partition_params(dip->partition_cfg[i].size,
+ dip->partition_cfg[i].hash_mode,
+ dip->partition_cfg[i].verify_ratio))
+ {
+ dprintf(CRITICAL, "mdtp: verify_all_partitions: Wrong partition parameters\n");
+ verify_failure = TRUE;
+ break;
+ }
- verify_failure |= verify_partition(dip->partition_cfg[i].name,
+ verify_failure |= (verify_partition(dip->partition_cfg[i].name,
dip->partition_cfg[i].size,
dip->partition_cfg[i].hash_mode,
- total_num_blocks,
(dip->partition_cfg[i].verify_ratio * total_num_blocks) / 100,
dip->partition_cfg[i].hash_table,
- dip->partition_cfg[i].force_verify_block);
+ dip->partition_cfg[i].force_verify_block) != 0);
}
}
if (verify_failure)
{
dprintf(CRITICAL, "mdtp: verify_all_partitions: Failed partition verification\n");
- return 0;
+ return;
}
is_mdtp_activated = 1;
}
*verify_result = VERIFY_OK;
- return 0;
+ return;
}
/* Verify the DIP and all protected partitions */
@@ -440,7 +514,7 @@
if (enc_dip == NULL)
{
dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot allocate DIP\n");
- return;
+ display_error_msg(); /* This will never return */
}
dec_dip = malloc(ROUNDUP(sizeof(DIP_t), block_size));
@@ -448,7 +522,7 @@
{
dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot allocate DIP\n");
free(enc_dip);
- return;
+ display_error_msg(); /* This will never return */
}
/* Read the DIP holding the MDTP Firmware Lock state from the DIP partition */
@@ -456,7 +530,7 @@
if(ret < 0)
{
dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot read DIP\n");
- goto out;
+ display_error_msg(); /* This will never return */
}
/* Decrypt and verify the integrity of the DIP */
@@ -464,40 +538,35 @@
if(ret < 0)
{
dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot verify DIP\n");
- display_error_msg();
- goto out;
+ display_error_msg(); /* This will never return */
}
/* In case DIP integrity verification fails, notify the user and halt */
if(!verified)
{
dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, corrupted DIP\n");
- display_error_msg();
- goto out;
+ display_error_msg(); /* This will never return */
}
/* Verify the integrity of the partitions which are protectedm, according to the content of the DIP */
- ret = verify_all_partitions(dec_dip, &verify_result);
- if(ret < 0)
- {
- dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, cannot verify firmware\n");
- goto out;
- }
+ verify_all_partitions(dec_dip, &verify_result);
+
+ /* Clear decrypted DIP since we don't need it anymore */
+ memset(dec_dip, 0, sizeof(DIP_t));
if (verify_result == VERIFY_OK)
{
dprintf(SPEW, "mdtp: validate_DIP_and_firmware: Verify OK\n");
}
- else if (verify_result == VERIFY_FAILED)
+ else if (verify_result == VERIFY_SKIPPED)
+ {
+ dprintf(SPEW, "mdtp: validate_DIP_and_firmware: Verify skipped\n");
+ } else /* VERIFY_FAILED */
{
dprintf(CRITICAL, "mdtp: validate_DIP_and_firmware: ERROR, corrupted firmware\n");
display_recovery_ui(dec_dip);
- } else /* VERIFY_SKIPPED */
- {
- dprintf(SPEW, "mdtp: validate_DIP_and_firmware: Verify skipped\n");
}
-out:
free(enc_dip);
free(dec_dip);
@@ -509,7 +578,7 @@
/** Entry point of the MDTP Firmware Lock: If needed, verify the DIP
* and all protected partitions **/
-int mdtp_fwlock_verify_lock()
+void mdtp_fwlock_verify_lock()
{
int ret;
bool enabled;
@@ -521,16 +590,15 @@
if(ret)
{
dprintf(CRITICAL, "mdtp: mdtp_fwlock_verify_lock: ERROR, cannot get enabled fuse\n");
- return -1;
+ display_error_msg(); /* This will never return */
}
/* Continue with Firmware Lock verification only if enabled by eFuse */
if (enabled)
{
+ /* This function will handle firmware verification failure via UI */
validate_DIP_and_firmware();
}
-
- return 0;
}
/********************************************************************************/
@@ -550,7 +618,6 @@
/* Decrypt a given DIP and verify its integrity */
static int mdtp_tzbsp_dec_verify_DIP(DIP_t *enc_dip, DIP_t *dec_dip, uint32_t *verified)
{
- unsigned char *hash_p;
unsigned char hash[HASH_LEN];
SHA256_CTX sha256_ctx;
int ret;
@@ -566,6 +633,7 @@
{
dprintf(CRITICAL, "mdtp: mdtp_tzbsp_dec_verify_DIP: ERROR, cannot cipher DIP\n");
*verified = 0;
+ memset(dec_dip, 0, sizeof(DIP_t));
return -1;
}
@@ -573,11 +641,10 @@
SHA256_Update(&sha256_ctx, dec_dip, sizeof(DIP_t) - HASH_LEN);
SHA256_Final(hash, &sha256_ctx);
- hash_p = (unsigned char*)dec_dip + sizeof(DIP_t) - HASH_LEN;
-
- if (memcmp(hash, hash_p, HASH_LEN))
+ if (memcmp(hash, dec_dip->hash, HASH_LEN))
{
*verified = 0;
+ memset(dec_dip, 0, sizeof(DIP_t));
}
else
{
@@ -589,18 +656,15 @@
static int mdtp_tzbsp_enc_hash_DIP(DIP_t *dec_dip, DIP_t *enc_dip)
{
- unsigned char *hash_p;
SHA256_CTX sha256_ctx;
int ret;
ASSERT(dec_dip != NULL);
ASSERT(enc_dip != NULL);
- hash_p = (unsigned char*)dec_dip + sizeof(DIP_t) - HASH_LEN;
-
SHA256_Init(&sha256_ctx);
SHA256_Update(&sha256_ctx, dec_dip, sizeof(DIP_t) - HASH_LEN);
- SHA256_Final(hash_p, &sha256_ctx);
+ SHA256_Final(dec_dip->hash, &sha256_ctx);
ret = mdtp_cipher_dip_cmd((uint8_t*)dec_dip, sizeof(DIP_t),
(uint8_t*)enc_dip, sizeof(DIP_t),
diff --git a/app/aboot/mdtp.h b/app/aboot/mdtp.h
index 865c791..0f30b54 100644
--- a/app/aboot/mdtp.h
+++ b/app/aboot/mdtp.h
@@ -29,21 +29,21 @@
#ifndef __APP_MDTP_H
#define __APP_MDTP_H
-#define TOKEN_LEN 16
-#define MAX_BLOCKS 512
-#define MAX_PARTITIONS 3
-#define MAX_PARTITION_NAME_LEN 100
-#define HASH_LEN 32
-#define MDTP_MIN_PIN_LEN 5
-#define MDTP_MAX_PIN_LEN 8
-#define DIP_PADDING 11
+#define TOKEN_LEN (16)
+#define MAX_BLOCKS (512)
+#define MAX_PARTITIONS (3)
+#define MAX_PARTITION_NAME_LEN (100)
+#define HASH_LEN (32)
+#define MDTP_MAX_PIN_LEN (8)
+#define MDTP_MIN_PIN_LEN (5)
+#define DIP_PADDING (15)
#define INITIAL_DELAY_MSECONDS 5000
#define INVALID_PIN_DELAY_MSECONDS 5000
#define ROUND_TO_PAGE(x,y) (((x) + (y)) & (~(y)))
-#define MDTP_FWLOCK_BLOCK_SIZE (1024*1024*16)
-#define MDTP_FWLOCK_MAX_FILES (100)
+#define MDTP_FWLOCK_BLOCK_SIZE (1024*1024*16)
+#define MDTP_FWLOCK_MAX_FILES (100)
#define MDTP_FWLOCK_MAX_FILE_NAME_LEN (100)
#pragma pack(push, mdtp, 1)
@@ -66,7 +66,7 @@
} DIP_hash_table_entry_t;
typedef struct DIP_partition_cfg {
- uint32_t size; /* DIP size */
+ uint64_t size; /* Partition size in bytes */
char name[MAX_PARTITION_NAME_LEN]; /* Partition name */
uint8_t lock_enabled; /* Image locked? */
mdtp_fwlock_mode_t hash_mode; /* Hash per IMAGE or BLOCK */
@@ -114,9 +114,9 @@
*
* Start Firmware Lock verification process.
*
- * @return - negative value for an error, 0 for success.
+ * @return - None.
*/
-int mdtp_fwlock_verify_lock();
+void mdtp_fwlock_verify_lock();
/**
* mdtp_fuse_get_enabled
diff --git a/app/aboot/mdtp_fuse.c b/app/aboot/mdtp_fuse.c
index 1487057..239d263 100644
--- a/app/aboot/mdtp_fuse.c
+++ b/app/aboot/mdtp_fuse.c
@@ -36,8 +36,6 @@
#include "mdtp.h"
#include "scm.h"
-#define MAX_EFUSES (8)
-#define EFUSE_END (MDTP_EFUSE_START + MAX_EFUSES - 1)
#define MAX_METADATA_SIZE (0x1000)
#define QFPROM_ADDR_SPACE_RAW (0)
@@ -228,7 +226,7 @@
* Read the Firmware Lock eFuses and return whether the Firmware
* Lock is currently enabled or disabled in HW.
*
- * @param[out] enabled: 0 - enable, 1 - disable.
+ * @param[out] enabled: 0 - disabled, 1 - enabled.
*
* @return - negative value for an error, 0 for success.
*/
@@ -237,6 +235,8 @@
int status;
mdtp_eFuses_t eFuses;
+ *enabled = 1;
+
status = read_fuse(&eFuses.mask);
if (status)
{
@@ -244,14 +244,12 @@
return -1;
}
- if ((eFuses.bitwise.enable1 && !eFuses.bitwise.disable1) ||
- (eFuses.bitwise.enable2 && !eFuses.bitwise.disable2) ||
- (eFuses.bitwise.enable3 && !eFuses.bitwise.disable3))
+ if (!(eFuses.bitwise.enable1 && !eFuses.bitwise.disable1) &&
+ !(eFuses.bitwise.enable2 && !eFuses.bitwise.disable2) &&
+ !(eFuses.bitwise.enable3 && !eFuses.bitwise.disable3))
{
- *enabled = 1;
- }
- else
*enabled = 0;
+ }
return 0;
}
diff --git a/app/aboot/mdtp_ui.c b/app/aboot/mdtp_ui.c
index 48d899e..7a94ad6 100644
--- a/app/aboot/mdtp_ui.c
+++ b/app/aboot/mdtp_ui.c
@@ -78,7 +78,7 @@
#define BITS_PER_BYTE (8)
-#define CENTER_IMAGE_ON_X_AXIS(image_width,screen_width) ((screen_width-image_width)/2)
+#define CENTER_IMAGE_ON_X_AXIS(image_width,screen_width) (((screen_width)-(image_width))/2)
extern void mdelay(unsigned msecs);
extern uint32_t target_volume_up();
@@ -131,8 +131,9 @@
if (fb_config)
{
uint8_t *base = logo->image;
+ unsigned bytes_per_bpp = ((fb_config->bpp) / BITS_PER_BYTE);
- if (mmc_read(ptn+offset, (void*)base, ROUNDUP(width*height*3, block_size))) {
+ if (mmc_read(ptn+offset, (void*)base, ROUNDUP(width*height*bytes_per_bpp, block_size))) {
fbcon_clear();
dprintf(CRITICAL, "ERROR: mdtp image read failed\n");
return NULL;
@@ -180,7 +181,7 @@
else
{
dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
- display_error_msg();
+ display_error_msg(); /* This will never return */
}
}
@@ -218,11 +219,15 @@
if (bytes_per_bpp == 3)
{
if (fbimg->width == fb_config->width && fbimg->height == fb_config->height)
- return;
-
- if (fbimg->width > fb_config->width || fbimg->height > fb_config->height)
{
- dprintf(CRITICAL,"ERROR: invalid image size, larger than the screen\n");
+ dprintf(CRITICAL,"ERROR: full screen image, cannot be displayed\n");
+ return;
+ }
+
+ if (fbimg->width > fb_config->width || fbimg->height > fb_config->height ||
+ (x > (fb_config->width - fbimg->width)) || (y > (fb_config->height - fbimg->height)))
+ {
+ dprintf(CRITICAL,"ERROR: invalid image size, larger than the screen or exceeds its margins\n");
return;
}
@@ -232,6 +237,11 @@
logo_base + ((height - 1 - i) * pitch * bytes_per_bpp), width * bytes_per_bpp);
}
}
+ else
+ {
+ dprintf(CRITICAL,"ERROR: invalid bpp value\n");
+ display_error_msg(); /* This will never return */
+ }
fbcon_flush();
@@ -240,17 +250,6 @@
mipi_dsi_cmd_mode_trigger();
#endif
-#else
- if (bytes_per_bpp == 2)
- {
- for (i = 0; i < fbimg->width; i++)
- {
- memcpy (fb_config->base + ((image_base + (i * (fb_config->width))) * bytes_per_bpp),
- fbimg->image + (i * fbimg->height * bytes_per_bpp),
- fbimg->height * bytes_per_bpp);
- }
- }
- fbcon_flush();
#endif
}
@@ -261,8 +260,6 @@
{
struct mdtp_fbimage *fbimg;
- fb_config = fbcon_display();
-
if (fb_config)
{
uint32_t x = CENTER_IMAGE_ON_X_AXIS(MDTP_ERROR_MSG_WIDTH,fb_config->width);
@@ -300,7 +297,7 @@
if (NULL == fbimg)
{
dprintf(CRITICAL,"ERROR: failed to read image from mmc\n");
- display_error_msg();
+ display_error_msg(); /* This will never return */
}
fbcon_putImage_in_location(fbimg, x, y);
@@ -308,7 +305,7 @@
else
{
dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
- display_error_msg();
+ display_error_msg(); /* This will never return */
}
}
@@ -442,7 +439,7 @@
fbcon_clear();
if (display_error_message())
- display_error_msg();
+ display_error_msg(); /* This will never return */
display_initial_delay();
mdelay(INITIAL_DELAY_MSECONDS);
@@ -452,12 +449,12 @@
uint32_t total_pin_length = pin_length*MDTP_PIN_DIGIT_WIDTH + DIGIT_SPACE*(pin_length - 1);
uint32_t complete_pin_centered = (fb_config->width - total_pin_length)/2;
- for (int i=0; i<(int)pin_length; i++)
+ for (uint32_t i=0; i<pin_length; i++)
{
g_pin_frames_x_location[i] = complete_pin_centered + i*(DIGIT_SPACE+MDTP_PIN_DIGIT_WIDTH);
}
- for (int i=0; i<(int)pin_length; i++)
+ for (uint32_t i=0; i<pin_length; i++)
{
display_digit(g_pin_frames_x_location[i], g_pin_frames_y_location, 0);
}
@@ -469,8 +466,7 @@
else
{
dprintf(CRITICAL,"ERROR: fbcon_config struct is NULL\n");
- display_error_msg();
- return;
+ display_error_msg(); /* This will never return */
}
}
@@ -588,15 +584,17 @@
*/
void display_error_msg()
{
- fbcon_clear();
- display_error_message(); // No point in checking the return value here
+ fb_config = fbcon_display();
+
+ if (fb_config)
+ {
+ fbcon_clear();
+ display_error_message(); // No point in checking the return value here
+ }
// Invalid state. Nothing to be done but contacting the OEM.
// Stop boot process.
dprintf(CRITICAL,"ERROR: blocking boot process\n");
- while(1)
- {
-
- }
+ for(;;);
}
diff --git a/arch/arm/rules.mk b/arch/arm/rules.mk
index a4bf38c..f45a6eb 100644
--- a/arch/arm/rules.mk
+++ b/arch/arm/rules.mk
@@ -132,23 +132,24 @@
-$(BUILDDIR)/trustzone-test-system-onesegment.ld: $(LOCAL_DIR)/trustzone-test-system-onesegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk
+$(BUILDDIR)/trustzone-test-system-onesegment.ld: $(LOCAL_DIR)/trustzone-test-system-onesegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk .FORCE
@echo generating $@
@$(MKDIR)
$(NOECHO)sed "s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/;s/%ROMLITE_PREFLASHED_DATA%/$(ROMLITE_PREFLASHED_DATA)/" < $< > $@
-$(BUILDDIR)/trustzone-system-onesegment.ld: $(LOCAL_DIR)/trustzone-system-onesegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk
+$(BUILDDIR)/trustzone-system-onesegment.ld: $(LOCAL_DIR)/trustzone-system-onesegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk .FORCE
@echo generating $@
@$(MKDIR)
$(NOECHO)sed "s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/" < $< > $@
-$(BUILDDIR)/system-onesegment.ld: $(LOCAL_DIR)/system-onesegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk
+$(BUILDDIR)/system-onesegment.ld: $(LOCAL_DIR)/system-onesegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk .FORCE
@echo generating $@
@$(MKDIR)
$(NOECHO)sed "s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/" < $< > $@
-$(BUILDDIR)/system-twosegment.ld: $(LOCAL_DIR)/system-twosegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk
+$(BUILDDIR)/system-twosegment.ld: $(LOCAL_DIR)/system-twosegment.ld $(LK_TOP_DIR)/target/$(TARGET)/rules.mk .FORCE
@echo generating $@
@$(MKDIR)
$(NOECHO)sed "s/%ROMBASE%/$(ROMBASE)/;s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/" < $< > $@
+.FORCE:
diff --git a/dev/gcdb/display/gcdb_display.c b/dev/gcdb/display/gcdb_display.c
old mode 100755
new mode 100644
index 066fd13..ccc47cd
--- a/dev/gcdb/display/gcdb_display.c
+++ b/dev/gcdb/display/gcdb_display.c
@@ -64,16 +64,18 @@
static uint32_t panel_backlight_ctrl(uint8_t enable)
{
- return target_backlight_ctrl(panelstruct.backlightinfo, enable);
+ uint32_t ret = NO_ERROR;
+ if (panelstruct.backlightinfo)
+ ret = target_backlight_ctrl(panelstruct.backlightinfo, enable);
+ return ret;
}
static uint32_t mdss_dsi_panel_reset(uint8_t enable)
{
uint32_t ret = NO_ERROR;
-
- ret = target_panel_reset(enable, panelstruct.panelresetseq,
- &panel.panel_info);
-
+ if (panelstruct.panelresetseq)
+ ret = target_panel_reset(enable, panelstruct.panelresetseq,
+ &panel.panel_info);
return ret;
}
@@ -422,7 +424,8 @@
arg_size = prefix_string_len + dsi_id_len + panel_node_len +
LK_OVERRIDE_PANEL_LEN + 1;
- if (!strcmp(panelstruct.paneldata->panel_destination, "DISPLAY_2"))
+ if (panelstruct.paneldata &&
+ !strcmp(panelstruct.paneldata->panel_destination, "DISPLAY_2"))
sctl_string = DSI_0_STRING;
else
sctl_string = DSI_1_STRING;
@@ -458,22 +461,6 @@
return ret;
}
-
-static void init_platform_data()
-{
- if (dsi_video_mode_phy_db.pll_type == DSI_PLL_TYPE_THULIUM)
- return;
-
- memcpy(dsi_video_mode_phy_db.regulator, panel_regulator_settings,
- REGULATOR_SIZE);
- memcpy(dsi_video_mode_phy_db.ctrl, panel_physical_ctrl,
- PHYSICAL_SIZE);
- memcpy(dsi_video_mode_phy_db.strength, panel_strength_ctrl,
- STRENGTH_SIZE);
- memcpy(dsi_video_mode_phy_db.bistCtrl, panel_bist_ctrl, BIST_SIZE);
- memcpy(dsi_video_mode_phy_db.laneCfg, panel_lane_config, LANE_SIZE);
-}
-
static void mdss_edp_panel_init(struct msm_panel_info *pinfo)
{
return target_edp_panel_init(pinfo);
@@ -543,6 +530,11 @@
return ret;
}
+static int mdss_dsi2HDMI_config (struct msm_panel_info *pinfo)
+{
+ return target_display_dsi2hdmi_config(pinfo);
+}
+
int gcdb_display_init(const char *panel_name, uint32_t rev, void *base)
{
int ret = NO_ERROR;
@@ -553,7 +545,7 @@
&dsi_video_mode_phy_db);
if (pan_type == PANEL_TYPE_DSI) {
- init_platform_data();
+ target_dsi_phy_config(&dsi_video_mode_phy_db);
if (dsi_panel_init(&(panel.panel_info), &panelstruct)) {
dprintf(CRITICAL, "DSI panel init failed!\n");
ret = ERROR;
@@ -566,6 +558,7 @@
panel.power_func = mdss_dsi_panel_power;
panel.pre_init_func = mdss_dsi_panel_pre_init;
panel.bl_func = mdss_dsi_bl_enable;
+ panel.dsi2HDMI_config = mdss_dsi2HDMI_config;
/*
* If dfps enabled, reserve fb memory to store pll
* codes and pass pll codes values to kernel.
diff --git a/dev/gcdb/display/gcdb_display.h b/dev/gcdb/display/gcdb_display.h
index 0d6f06f..d1f1df5 100755
--- a/dev/gcdb/display/gcdb_display.h
+++ b/dev/gcdb/display/gcdb_display.h
@@ -52,6 +52,8 @@
int target_panel_reset(uint8_t enable, struct panel_reset_sequence *resetseq,
struct msm_panel_info *pinfo);
int target_ldo_ctrl(uint8_t enable, struct msm_panel_info *pinfo);
+int target_display_dsi2hdmi_config(struct msm_panel_info *pinfo);
+int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db);
int gcdb_display_init(const char *panel_name, uint32_t rev, void *base);
int gcdb_display_cmdline_arg(char *panel_name, char *pbuf, uint16_t buf_size);
diff --git a/dev/gcdb/display/include/panel.h b/dev/gcdb/display/include/panel.h
index 913bafb..f75850c 100755
--- a/dev/gcdb/display/include/panel.h
+++ b/dev/gcdb/display/include/panel.h
@@ -38,6 +38,9 @@
#define TOTAL_RESET_GPIO_CTRL 5
+#define ADV7533_MAIN (0x39)
+#define ADV7533_CEC_DSI (0x3c)
+
/*---------------------------------------------------------------------------*/
/* panel type */
/*---------------------------------------------------------------------------*/
diff --git a/dev/gcdb/display/include/panel_adv7533_1080p60.h b/dev/gcdb/display/include/panel_adv7533_1080p60.h
new file mode 100755
index 0000000..ceba5ce
--- /dev/null
+++ b/dev/gcdb/display/include/panel_adv7533_1080p60.h
@@ -0,0 +1,177 @@
+/* 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 _PANEL_ADV7533_1080p60_H_
+#define _PANEL_ADV7533_1080p60_H_
+/*---------------------------------------------------------------------------*/
+/* HEADER files */
+/*---------------------------------------------------------------------------*/
+#include "panel.h"
+
+/*---------------------------------------------------------------------------*/
+/* Panel configuration */
+/*---------------------------------------------------------------------------*/
+static struct panel_config adv7533_1080p_video_panel_data = {
+ "qcom,mdss_dsi_adv7533_1080p60_video", "dsi:0:", "qcom,mdss-dsi-panel",
+ 10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel resolution */
+/*---------------------------------------------------------------------------*/
+static struct panel_resolution adv7533_1080p_video_panel_res = {
+ 1920, 1080, 88, 148, 44, 0, 4, 36, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel color information */
+/*---------------------------------------------------------------------------*/
+static struct color_info adv7533_1080p_video_color = {
+ 24, 0, 0xff, 0, 0, 0
+};
+
+static struct mipi_dsi_i2c_cmd adv7533_1080p_common_cfg[] = {
+ {ADV7533_MAIN, 0xd6, 0x48, 5}, /* HPD overriden */
+ {ADV7533_MAIN, 0x41, 0x10, 5}, /* HDMI normal */
+ {ADV7533_CEC_DSI, 0x03, 0x89, 0}, /* HDMI enabled */
+ {ADV7533_MAIN, 0x16, 0x20, 0},
+ {ADV7533_MAIN, 0x9A, 0xE0, 0},
+ {ADV7533_MAIN, 0xBA, 0x70, 0},
+ {ADV7533_MAIN, 0xDE, 0x82, 0},
+ {ADV7533_MAIN, 0xE4, 0x40, 0},
+ {ADV7533_MAIN, 0xE5, 0x80, 0},
+ {ADV7533_CEC_DSI, 0x15, 0xD0, 0},
+ {ADV7533_CEC_DSI, 0x17, 0xD0, 0},
+ {ADV7533_CEC_DSI, 0x24, 0x20, 0},
+ {ADV7533_CEC_DSI, 0x57, 0x11, 0},
+ /* hdmi or dvi mode: hdmi */
+ {ADV7533_MAIN, 0xAF, 0x06, 0},
+ {ADV7533_MAIN, 0x40, 0x80, 0},
+ {ADV7533_MAIN, 0x4C, 0x04, 0},
+ {ADV7533_MAIN, 0x49, 0x02, 0},
+ {ADV7533_MAIN, 0x0D, 1 << 6, 0},
+ {ADV7533_CEC_DSI, 0x1C, 0x30, 0},
+};
+
+#define ADV7533_1080P_CONFIG_COMMANDS 19
+
+static struct mipi_dsi_i2c_cmd adv7533_1080p_tg_i2c_command[] = {
+ /*4 Lanes*/
+ {ADV7533_CEC_DSI, 0x1C, 0x40},
+ /* hsync and vsync active low */
+ {ADV7533_MAIN, 0x17, 0x02},
+ /* Control for Pixel Clock Divider */
+ {ADV7533_CEC_DSI, 0x16, 0x00},
+ /* Timing Generator Enable */
+ {ADV7533_CEC_DSI, 0x27, 0xCB},
+ /* h_width 0x898 2200*/
+ {ADV7533_CEC_DSI, 0x28, 0x89},
+ {ADV7533_CEC_DSI, 0x29, 0x80},
+ /* hsync_width 0x2c 44*/
+ {ADV7533_CEC_DSI, 0x2A, 0x02},
+ {ADV7533_CEC_DSI, 0x2B, 0xC0},
+ /* hfp 0x58 88 */
+ {ADV7533_CEC_DSI, 0x2C, 0x05},
+ {ADV7533_CEC_DSI, 0x2D, 0x80},
+ /* hbp 0x94 148 */
+ {ADV7533_CEC_DSI, 0x2E, 0x09},
+ {ADV7533_CEC_DSI, 0x2F, 0x40},
+ /* v_total 0x465 1125*/
+ {ADV7533_CEC_DSI, 0x30, 0x46},
+ {ADV7533_CEC_DSI, 0x31, 0x50},
+ /* vsync_width 0x05 5*/
+ {ADV7533_CEC_DSI, 0x32, 0x00},
+ {ADV7533_CEC_DSI, 0x33, 0x50},
+ /* vfp 0x04 4 */
+ {ADV7533_CEC_DSI, 0x34, 0x00},
+ {ADV7533_CEC_DSI, 0x35, 0x40},
+ /* vbp 0x24 36 */
+ {ADV7533_CEC_DSI, 0x36, 0x02},
+ {ADV7533_CEC_DSI, 0x37, 0x40},
+ /* Timing Generator Enable */
+ {ADV7533_CEC_DSI, 0x27, 0xCB},
+ {ADV7533_CEC_DSI, 0x27, 0x8B},
+ {ADV7533_CEC_DSI, 0x27, 0xCB},
+ /* Reset Internal Timing Generator */
+ {ADV7533_MAIN, 0xAF, 0x16},
+ /* HDMI Mode Select */
+ {ADV7533_CEC_DSI, 0x03, 0x89},
+ /* HDMI Output Enable */
+ {ADV7533_MAIN, 0x40, 0x80},
+ /* GC Packet Enable */
+ {ADV7533_MAIN, 0x4C, 0x04},
+ /* Colour Depth 24-bit per pixel */
+ {ADV7533_MAIN, 0x49, 0x00},
+ /* Down Dither Output 8-bit Colour Depth */
+ {ADV7533_CEC_DSI, 0x05, 0xF8},
+ /* ADI Required Write */
+ {ADV7533_CEC_DSI, 0xBE, 0x3D},
+ /* Test Pattern Disable (0x55[7] = 0) */
+ {ADV7533_CEC_DSI, 0x55, 0x00},
+};
+
+#define ADV7533_1080P_TG_COMMANDS 31
+
+static struct command_state adv7533_1080p_video_state = {
+ 0, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Command mode panel information */
+/*---------------------------------------------------------------------------*/
+static struct commandpanel_info adv7533_1080p_video_command_panel = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Video mode panel information */
+/*---------------------------------------------------------------------------*/
+static struct videopanel_info adv7533_1080p_video_video_panel = {
+ 1, 0, 0, 0, 1, 1, 0, 0, 0x9
+};
+
+/*---------------------------------------------------------------------------*/
+/* Lane configuration */
+/*---------------------------------------------------------------------------*/
+static struct lane_configuration adv7533_1080p_video_lane_config = {
+ 4, 0, 1, 1, 1, 1, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel timing */
+/*---------------------------------------------------------------------------*/
+static const uint32_t adv7533_1080p_video_timings[] = {
+ 0xa9, 0x4A, 0x32, 0x00, 0x82, 0x86, 0x38, 0x4e, 0x3d, 0x03, 0x04, 0x00
+};
+
+static struct panel_timing adv7533_1080p_video_timing_info = {
+ 0x0, 0x04, 0x01, 0x27
+};
+
+#endif /*_PANEL_ADV7533_1080p60_H_*/
+
diff --git a/dev/gcdb/display/include/panel_adv7533_720p60.h b/dev/gcdb/display/include/panel_adv7533_720p60.h
new file mode 100644
index 0000000..c56971f
--- /dev/null
+++ b/dev/gcdb/display/include/panel_adv7533_720p60.h
@@ -0,0 +1,162 @@
+/* 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 _PANEL_ADV7533_720p60_H_
+#define _PANEL_ADV7533_720p60_H_
+/*---------------------------------------------------------------------------*/
+/* HEADER files */
+/*---------------------------------------------------------------------------*/
+#include "panel.h"
+
+/*---------------------------------------------------------------------------*/
+/* Panel configuration */
+/*---------------------------------------------------------------------------*/
+static struct panel_config adv7533_720p_video_panel_data = {
+ "qcom,mdss_dsi_adv7533_720p60_video", "dsi:0:", "qcom,mdss-dsi-panel",
+ 10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel resolution */
+/*---------------------------------------------------------------------------*/
+static struct panel_resolution adv7533_720p_video_panel_res = {
+ 1280, 720, 110, 220, 40, 0, 5, 20, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel color information */
+/*---------------------------------------------------------------------------*/
+static struct color_info adv7533_720p_video_color = {
+ 24, 0, 0xff, 0, 0, 0
+};
+
+static struct mipi_dsi_i2c_cmd adv7533_720p_common_cfg[] = {
+ {ADV7533_MAIN, 0xd6, 0x48, 5}, /* HPD overriden */
+ {ADV7533_MAIN, 0x41, 0x10, 5}, /* HDMI normal */
+ {ADV7533_CEC_DSI, 0x03, 0x89, 0}, /* HDMI enabled */
+ {ADV7533_MAIN, 0x16, 0x20, 0},
+ {ADV7533_MAIN, 0x9A, 0xE0, 0},
+ {ADV7533_MAIN, 0xBA, 0x70, 0},
+ {ADV7533_MAIN, 0xDE, 0x82, 0},
+ {ADV7533_MAIN, 0xE4, 0xC0, 0},
+ {ADV7533_MAIN, 0xE5, 0x80, 0},
+ {ADV7533_CEC_DSI, 0x15, 0xD0, 0},
+ {ADV7533_CEC_DSI, 0x17, 0xD0, 0},
+ {ADV7533_CEC_DSI, 0x24, 0x20, 0},
+ {ADV7533_CEC_DSI, 0x57, 0x11, 0},
+ /* hdmi or dvi mode: hdmi */
+ {ADV7533_MAIN, 0xAF, 0x06, 0},
+ {ADV7533_MAIN, 0x40, 0x80, 0},
+ {ADV7533_MAIN, 0x4C, 0x04, 0},
+ {ADV7533_MAIN, 0x49, 0x02, 0},
+ {ADV7533_MAIN, 0x0D, 1 << 6, 0},
+ {ADV7533_CEC_DSI, 0x1C, 0x30, 0},
+};
+
+#define ADV7533_720P_CONFIG_COMMANDS 19
+
+static struct mipi_dsi_i2c_cmd adv7533_720p_tg_i2c_command[] = {
+ /*3 Lanes*/
+ {ADV7533_CEC_DSI, 0x1C, 0x30},
+ /* hsync and vsync active low */
+ {ADV7533_MAIN, 0x17, 0x02},
+ /* Control for Pixel Clock Divider */
+ {ADV7533_CEC_DSI, 0x16, 0x24},
+ /* h_width 0x672 1650*/
+ {ADV7533_CEC_DSI, 0x28, 0x67},
+ {ADV7533_CEC_DSI, 0x29, 0x20},
+ /* hsync_width 0x28 40*/
+ {ADV7533_CEC_DSI, 0x2A, 0x02},
+ {ADV7533_CEC_DSI, 0x2B, 0x80},
+ /* hfp 0x6E 110 */
+ {ADV7533_CEC_DSI, 0x2C, 0x06},
+ {ADV7533_CEC_DSI, 0x2D, 0xE0},
+ /* hbp 0xDC 220 */
+ {ADV7533_CEC_DSI, 0x2E, 0x0D},
+ {ADV7533_CEC_DSI, 0x2F, 0xC0},
+ /* v_total 0x2EE 750*/
+ {ADV7533_CEC_DSI, 0x30, 0x2E},
+ {ADV7533_CEC_DSI, 0x31, 0xE0},
+ /* vsync_width 0x05 5*/
+ {ADV7533_CEC_DSI, 0x32, 0x00},
+ {ADV7533_CEC_DSI, 0x33, 0x50},
+ /* vfp 0x05 5 */
+ {ADV7533_CEC_DSI, 0x34, 0x00},
+ {ADV7533_CEC_DSI, 0x35, 0x50},
+ /* vbp 0x14 20 */
+ {ADV7533_CEC_DSI, 0x36, 0x01},
+ {ADV7533_CEC_DSI, 0x37, 0x40},
+ /* Test Pattern Disable (0x55[7] = 0) */
+ {ADV7533_CEC_DSI, 0x55, 0x00},
+ /* HDMI disabled */
+ {ADV7533_CEC_DSI, 0x03, 0x09},
+ /* HDMI enabled */
+ {ADV7533_CEC_DSI, 0x03, 0x89},
+};
+
+#define ADV7533_720P_TG_COMMANDS 22
+
+static struct command_state adv7533_720p_video_state = {
+ 0, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Command mode panel information */
+/*---------------------------------------------------------------------------*/
+static struct commandpanel_info adv7533_720p_video_command_panel = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Video mode panel information */
+/*---------------------------------------------------------------------------*/
+static struct videopanel_info adv7533_720p_video_video_panel = {
+ 1, 0, 0, 0, 1, 1, 0, 0, 0x9
+};
+
+/*---------------------------------------------------------------------------*/
+/* Lane configuration */
+/*---------------------------------------------------------------------------*/
+static struct lane_configuration adv7533_720p_video_lane_config = {
+ 3, 0, 1, 1, 1, 0, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel timing */
+/*---------------------------------------------------------------------------*/
+static const uint32_t adv7533_720p_video_timings[] = {
+ 0xa4, 0x24, 0x18, 0x00, 0x4e, 0x52, 0x1c, 0x28, 0x1c, 0x03, 0x04, 0x00
+};
+
+static struct panel_timing adv7533_720p_video_timing_info = {
+ 0x0, 0x04, 0x03, 0x20
+};
+
+#endif /*_PANEL_ADV7533_720p60_H_*/
+
diff --git a/dev/gcdb/display/include/panel_jdi_4k_dualdsi_video.h b/dev/gcdb/display/include/panel_jdi_4k_dualdsi_video.h
index 8cfee8e..eedadf6 100644
--- a/dev/gcdb/display/include/panel_jdi_4k_dualdsi_video.h
+++ b/dev/gcdb/display/include/panel_jdi_4k_dualdsi_video.h
@@ -44,9 +44,9 @@
/* Panel configuration */
/*---------------------------------------------------------------------------*/
static struct panel_config jdi_4k_dualdsi_video_panel_data = {
- "qcom,dsi_jdi_4k_video_0", "dsi:0:", "qcom,mdss-dsi-panel",
+ "qcom,dsi_jdi_4k_video", "dsi:0:", "qcom,mdss-dsi-panel",
10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 0, 11, 0, 0,
- "qcom,dsi_jdi_4k_video_1",
+ "qcom,dsi_jdi_4k_video",
};
/*---------------------------------------------------------------------------*/
diff --git a/dev/gcdb/display/include/panel_jdi_qhd_dualdsi_cmd.h b/dev/gcdb/display/include/panel_jdi_qhd_dualdsi_cmd.h
index 4c0f3fc..5bc2e91 100644
--- a/dev/gcdb/display/include/panel_jdi_qhd_dualdsi_cmd.h
+++ b/dev/gcdb/display/include/panel_jdi_qhd_dualdsi_cmd.h
@@ -44,9 +44,9 @@
/* Panel configuration */
/*---------------------------------------------------------------------------*/
static struct panel_config jdi_qhd_dualdsi_cmd_panel_data = {
- "qcom,mdss_dsi_jdi_qhd_dualmipi0_cmd", "dsi:0:", "qcom,mdss-dsi-panel",
+ "qcom,mdss_dsi_jdi_qhd_dualmipi_cmd", "dsi:0:", "qcom,mdss-dsi-panel",
10, 1, "DISPLAY_1", 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 0, 11, 0, 0,
- "qcom,mdss_dsi_jdi_qhd_dualmipi1_cmd"
+ "qcom,mdss_dsi_jdi_qhd_dualmipi_cmd"
};
/*---------------------------------------------------------------------------*/
diff --git a/dev/gcdb/display/include/panel_jdi_qhd_dualdsi_video.h b/dev/gcdb/display/include/panel_jdi_qhd_dualdsi_video.h
index 3ad1e20..a403f31 100644
--- a/dev/gcdb/display/include/panel_jdi_qhd_dualdsi_video.h
+++ b/dev/gcdb/display/include/panel_jdi_qhd_dualdsi_video.h
@@ -44,9 +44,9 @@
/* Panel configuration */
/*---------------------------------------------------------------------------*/
static struct panel_config jdi_qhd_dualdsi_video_panel_data = {
- "qcom,dsi_jdi_qhd_video_0", "dsi:0:", "qcom,mdss-dsi-panel",
+ "qcom,dsi_jdi_qhd_video", "dsi:0:", "qcom,mdss-dsi-panel",
10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 0, 11, 0, 0,
- "qcom,dsi_jdi_qhd_video_1",
+ "qcom,dsi_jdi_qhd_video",
};
/*---------------------------------------------------------------------------*/
diff --git a/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_video.h b/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_video.h
new file mode 100644
index 0000000..9714b26
--- /dev/null
+++ b/dev/gcdb/display/include/panel_nt35597_wqxga_dualdsi_video.h
@@ -0,0 +1,265 @@
+/* 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _PANEL_NT35597_WQXGA_DUALDSI_VIDEO_H_
+#define _PANEL_NT35597_WQXGA_DUALDSI_VIDEO_H_
+/*---------------------------------------------------------------------------*/
+/* HEADER files */
+/*---------------------------------------------------------------------------*/
+#include "panel.h"
+
+/*---------------------------------------------------------------------------*/
+/* Panel configuration */
+/*---------------------------------------------------------------------------*/
+static struct panel_config nt35597_wqxga_dualdsi_video_panel_data = {
+ "qcom,mdss_dsi_nt35597_wqxga_video_0", "dsi:0:", "qcom,mdss-dsi-panel",
+ 10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 0, 25, 1, 0,
+ "qcom,mdss_dsi_nt35597_wqxga_video_1"
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel resolution */
+/*---------------------------------------------------------------------------*/
+static struct panel_resolution nt35597_wqxga_dualdsi_video_panel_res = {
+ 1440, 2560, 100, 32, 16, 0, 8, 7, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel color information */
+/*---------------------------------------------------------------------------*/
+static struct color_info nt35597_wqxga_dualdsi_video_color = {
+ 24, 0, 0xff, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel on/off command information */
+/*---------------------------------------------------------------------------*/
+static char nt35597_wqxga_dualdsi_video_on_cmd0[] = {
+ 0xff, 0x10, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd1[] = {
+ 0xfb, 0x01, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd2[] = {
+ 0xba, 0x03, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd3[] = {
+ 0xe5, 0x01, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd4[] = {
+ 0x35, 0x00, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd5[] = {
+ 0xbb, 0x03, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd6[] = {
+ 0xb0, 0x03, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd7[] = {
+ 0x06, 0x0, 0x39, 0xc0,
+ 0x3b, 0x03, 0x08, 0x08,
+ 0x64, 0x9a, 0xff, 0xff
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd8[] = {
+ 0xff, 0xe0, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd9[] = {
+ 0xfb, 0x01, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd10[] = {
+ 0x6b, 0x3d, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd11[] = {
+ 0x6c, 0x3d, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd12[] = {
+ 0x6d, 0x3d, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd13[] = {
+ 0x6e, 0x3d, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd14[] = {
+ 0x6f, 0x3d, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd15[] = {
+ 0x35, 0x02, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd16[] = {
+ 0x36, 0x72, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd17[] = {
+ 0x37, 0x10, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd18[] = {
+ 0x8, 0xc0, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd19[] = {
+ 0xff, 0x10, 0x15, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd20[] = {
+ 0x11, 0x00, 0x05, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_video_on_cmd21[] = {
+ 0x29, 0x00, 0x05, 0x80
+};
+
+static struct mipi_dsi_cmd nt35597_wqxga_dualdsi_video_on_command[] = {
+ {0x4, nt35597_wqxga_dualdsi_video_on_cmd0, 0x10},
+ {0x4, nt35597_wqxga_dualdsi_video_on_cmd1, 0x10},
+ {0x4, nt35597_wqxga_dualdsi_video_on_cmd2, 0x10},
+ {0x4, nt35597_wqxga_dualdsi_video_on_cmd3, 0x10},
+ {0x4, nt35597_wqxga_dualdsi_video_on_cmd4, 0x10},
+ {0x4, nt35597_wqxga_dualdsi_video_on_cmd5, 0x10},
+ {0x4, nt35597_wqxga_dualdsi_video_on_cmd6, 0x10},
+ {0xc, nt35597_wqxga_dualdsi_video_on_cmd7, 0x10},
+ {0x4, nt35597_wqxga_dualdsi_video_on_cmd8, 0x10},
+ {0x4, nt35597_wqxga_dualdsi_video_on_cmd9, 0x10},
+ {0x4, nt35597_wqxga_dualdsi_video_on_cmd10, 0x10},
+ {0x4, nt35597_wqxga_dualdsi_video_on_cmd11, 0x10},
+ {0x4, nt35597_wqxga_dualdsi_video_on_cmd12, 0x10},
+ {0x4, nt35597_wqxga_dualdsi_video_on_cmd13, 0x10},
+ {0x4, nt35597_wqxga_dualdsi_video_on_cmd14, 0x10},
+ {0x4, nt35597_wqxga_dualdsi_video_on_cmd15, 0x10},
+ {0x4, nt35597_wqxga_dualdsi_video_on_cmd16, 0x10},
+ {0x4, nt35597_wqxga_dualdsi_video_on_cmd17, 0x10},
+ {0x4, nt35597_wqxga_dualdsi_video_on_cmd18, 0x10},
+ {0x4, nt35597_wqxga_dualdsi_video_on_cmd19, 0x10},
+ {0x4, nt35597_wqxga_dualdsi_video_on_cmd20, 0x78},
+ {0x4, nt35597_wqxga_dualdsi_video_on_cmd21, 0x78},
+};
+
+#define NT35597_WQXGA_DUALDSI_VIDEO_ON_COMMAND 22
+
+
+static char nt35597_wqxga_dualdsi_videooff_cmd0[] = {
+ 0x28, 0x00, 0x05, 0x80
+};
+
+static char nt35597_wqxga_dualdsi_videooff_cmd1[] = {
+ 0x10, 0x00, 0x05, 0x80
+};
+
+static struct mipi_dsi_cmd nt35597_wqxga_dualdsi_video_off_command[] = {
+ {0x4, nt35597_wqxga_dualdsi_videooff_cmd0, 0x32},
+ {0x4, nt35597_wqxga_dualdsi_videooff_cmd1, 0x78}
+};
+
+#define NT35597_WQXGA_DUALDSI_VIDEO_OFF_COMMAND 2
+
+static struct command_state nt35597_wqxga_dualdsi_video_state = {
+ 0, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Command mode panel information */
+/*---------------------------------------------------------------------------*/
+static struct commandpanel_info nt35597_wqxga_dualdsi_video_command_panel = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Video mode panel information */
+/*---------------------------------------------------------------------------*/
+static struct videopanel_info nt35597_wqxga_dualdsi_video_video_panel = {
+ 0, 0, 0, 0, 1, 1, 1, 0, 0x9
+};
+
+/*---------------------------------------------------------------------------*/
+/* Lane configuration */
+/*---------------------------------------------------------------------------*/
+static struct lane_configuration nt35597_wqxga_dualdsi_video_lane_config = {
+ 4, 0, 1, 1, 1, 1, 0
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel timing */
+/*---------------------------------------------------------------------------*/
+static const uint32_t nt35597_wqxga_dualdsi_video_timings[] = {
+ 0xe2, 0x36, 0x24, 0x00, 0x66, 0x6a, 0x28, 0x38, 0x2a, 0x03, 0x04, 0x00
+};
+
+static const uint32_t nt35597_wqxga_dualdsi_thulium_video_timings[] = {
+ 0x23, 0x1f, 0x6, 0x8, 0x4, 0x3, 0x4, 0xa,
+ 0x23, 0x1f, 0x6, 0x8, 0x4, 0x3, 0x4, 0xa,
+ 0x23, 0x1f, 0x6, 0x8, 0x4, 0x3, 0x4, 0xa,
+ 0x23, 0x1f, 0x6, 0x8, 0x4, 0x3, 0x4, 0xa,
+ 0x23, 0x2d, 0x6, 0x8, 0x4, 0x3, 0x4, 0xa,
+};
+
+static struct panel_timing nt35597_wqxga_dualdsi_video_timing_info = {
+ 0x0, 0x04, 0x02, 0x2a
+};
+
+/*---------------------------------------------------------------------------*/
+/* Panel reset sequence */
+/*---------------------------------------------------------------------------*/
+static struct panel_reset_sequence nt35597_wqxga_dualdsi_video_reset_seq = {
+ {1, 0, 1, }, {20, 20, 50, }, 2
+};
+
+/*---------------------------------------------------------------------------*/
+/* Backlight setting */
+/*---------------------------------------------------------------------------*/
+static struct backlight nt35597_wqxga_dualdsi_video_backlight = {
+ 1, 1, 4095, 100, 1, "PMIC_8941" /* BL_WLED */
+};
+
+static struct labibb_desc nt35597_wqxga_dualdsi_video_labibb = {
+ 0, 1, 5500000, 5500000, 5500000, 5500000, 3, 3, 1
+};
+
+/*---------------------------------------------------------------------------*/
+/* Dynamic fps supported frequencies by panel */
+/*---------------------------------------------------------------------------*/
+static const struct dfps_panel_info nt35597_wqxga_dualdsi_video_dfps = {
+ 1, 8, {53, 54, 55, 56, 57, 58, 59, 60}
+};
+
+#endif
diff --git a/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h b/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h
index 169e980..ef5bc4c 100644
--- a/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h
+++ b/dev/gcdb/display/include/panel_sharp_wqxga_dualdsi_video.h
@@ -44,9 +44,9 @@
/* Panel configuration */
/*---------------------------------------------------------------------------*/
static struct panel_config sharp_wqxga_dualdsi_video_panel_data = {
- "qcom,mdss_dsi_sharp_wqxga_video_0", "dsi:0:", "qcom,mdss-dsi-panel",
+ "qcom,mdss_dsi_sharp_wqxga_video", "dsi:0:", "qcom,mdss-dsi-panel",
10, 0, "DISPLAY_1", 0, 0, 60, 0, 0, 1, 0, 0, 0, 0, 0, 25, 1, 0,
- "qcom,mdss_dsi_sharp_wqxga_video_1"
+ "qcom,mdss_dsi_sharp_wqxga_video"
};
/*---------------------------------------------------------------------------*/
diff --git a/platform/msm8909/acpuclock.c b/platform/msm8909/acpuclock.c
index b8e0df4..ed2cbfc 100644
--- a/platform/msm8909/acpuclock.c
+++ b/platform/msm8909/acpuclock.c
@@ -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
@@ -37,6 +37,8 @@
#include <platform/clock.h>
#include <blsp_qup.h>
+#define MAX_LOOPS 500
+
void hsusb_clock_init(void)
{
int ret;
@@ -358,6 +360,34 @@
}
}
+static void rcg_update_config(uint32_t reg)
+{
+ int i;
+
+ for (i = 0; i < MAX_LOOPS; i++) {
+ if (!(readl(reg) & BIT(0)))
+ return;
+ udelay(1);
+ }
+
+ dprintf(CRITICAL, "failed to update rcg config for reg = 0x%x\n", reg);
+ ASSERT(0);
+}
+
+static void branch_clk_halt_check(uint32_t reg)
+{
+ int i;
+
+ for (i = 0; i < MAX_LOOPS; i++) {
+ if (!(readl(reg) & BIT(31)))
+ return;
+ udelay(1);
+ }
+
+ dprintf(CRITICAL, "failed to enable branch for reg = 0x%x\n", reg);
+ ASSERT(0);
+}
+
/* Disable all the branch clocks needed by the DSI controller */
void gcc_dsi_clocks_disable(void)
{
@@ -371,20 +401,32 @@
{
int ret;
- /* Configure Byte clock -autopll- This will not change becasue
- byte clock does not need any divider*/
+ /*
+ * Configure Byte clock -autopll- This will not change becasue
+ * byte clock does not need any divider
+ */
+ /* Set the source for DSI0 byte RCG */
writel(0x100, DSI_BYTE0_CFG_RCGR);
+ /* Set the update RCG bit */
writel(0x1, DSI_BYTE0_CMD_RCGR);
+ rcg_update_config(DSI_BYTE0_CMD_RCGR);
+ /* Enable the branch clock */
writel(0x1, DSI_BYTE0_CBCR);
+ branch_clk_halt_check(DSI_BYTE0_CBCR);
/* Configure Pixel clock */
+ /* Set the source for DSI0 pixel RCG */
writel(0x100, DSI_PIXEL0_CFG_RCGR);
- writel(0x1, DSI_PIXEL0_CMD_RCGR);
- writel(0x1, DSI_PIXEL0_CBCR);
-
+ /* Set the MND for DSI0 pixel clock */
writel(pclk0_m, DSI_PIXEL0_M);
writel(pclk0_n, DSI_PIXEL0_N);
writel(pclk0_d, DSI_PIXEL0_D);
+ /* Set the update RCG bit */
+ writel(0x1, DSI_PIXEL0_CMD_RCGR);
+ rcg_update_config(DSI_PIXEL0_CMD_RCGR);
+ /* Enable the branch clock */
+ writel(0x1, DSI_PIXEL0_CBCR);
+ branch_clk_halt_check(DSI_PIXEL0_CBCR);
/* Configure ESC clock */
ret = clk_get_set_enable("mdss_esc0_clk", 0, 1);
diff --git a/platform/msm8916/acpuclock.c b/platform/msm8916/acpuclock.c
index fd365be..158ab39 100644
--- a/platform/msm8916/acpuclock.c
+++ b/platform/msm8916/acpuclock.c
@@ -38,6 +38,8 @@
#include <blsp_qup.h>
#include <platform.h>
+#define MAX_LOOPS 500
+
void hsusb_clock_init(void)
{
int ret;
@@ -262,6 +264,34 @@
}
}
+static void rcg_update_config(uint32_t reg)
+{
+ int i;
+
+ for (i = 0; i < MAX_LOOPS; i++) {
+ if (!(readl(reg) & BIT(0)))
+ return;
+ udelay(1);
+ }
+
+ dprintf(CRITICAL, "failed to update rcg config for reg = 0x%x\n", reg);
+ ASSERT(0);
+}
+
+static void branch_clk_halt_check(uint32_t reg)
+{
+ int i;
+
+ for (i = 0; i < MAX_LOOPS; i++) {
+ if (!(readl(reg) & BIT(31)))
+ return;
+ udelay(1);
+ }
+
+ dprintf(CRITICAL, "failed to enable branch for reg = 0x%x\n", reg);
+ ASSERT(0);
+}
+
/* Disable all the branch clocks needed by the DSI controller */
void gcc_dsi_clocks_disable(uint8_t dual_dsi)
{
@@ -280,20 +310,32 @@
{
int ret;
- /* Configure Byte clock -autopll- This will not change becasue
- byte clock does not need any divider*/
+ /*
+ * Configure Byte clock -autopll- This will not change becasue
+ * byte clock does not need any divider
+ */
+ /* Set the source for DSI0 byte RCG */
writel(0x100, DSI_BYTE0_CFG_RCGR);
+ /* Set the update RCG bit */
writel(0x1, DSI_BYTE0_CMD_RCGR);
+ rcg_update_config(DSI_BYTE0_CMD_RCGR);
+ /* Enable the branch clock */
writel(0x1, DSI_BYTE0_CBCR);
+ branch_clk_halt_check(DSI_BYTE0_CBCR);
/* Configure Pixel clock */
+ /* Set the source for DSI0 pixel RCG */
writel(0x100, DSI_PIXEL0_CFG_RCGR);
- writel(0x1, DSI_PIXEL0_CMD_RCGR);
- writel(0x1, DSI_PIXEL0_CBCR);
-
+ /* Set the MND for DSI0 pixel clock */
writel(pclk0_m, DSI_PIXEL0_M);
writel(pclk0_n, DSI_PIXEL0_N);
writel(pclk0_d, DSI_PIXEL0_D);
+ /* Set the update RCG bit */
+ writel(0x1, DSI_PIXEL0_CMD_RCGR);
+ rcg_update_config(DSI_PIXEL0_CMD_RCGR);
+ /* Enable the branch clock */
+ writel(0x1, DSI_PIXEL0_CBCR);
+ branch_clk_halt_check(DSI_PIXEL0_CBCR);
/* Configure ESC clock */
ret = clk_get_set_enable("mdss_esc0_clk", 0, 1);
@@ -303,20 +345,27 @@
}
if (dual_dsi) {
- /* Configure Byte clock -autopll- This will not change becasue
- byte clock does not need any divider*/
+ /* Set the source for DSI1 byte RCG */
writel(0x100, DSI_BYTE1_CFG_RCGR);
+ /* Set the update RCG bit */
writel(0x1, DSI_BYTE1_CMD_RCGR);
+ rcg_update_config(DSI_BYTE1_CMD_RCGR);
+ /* Enable the branch clock */
writel(0x1, DSI_BYTE1_CBCR);
+ branch_clk_halt_check(DSI_BYTE1_CBCR);
- /* Configure Pixel clock */
+ /* Set the source for DSI1 pixel RCG */
writel(0x100, DSI_PIXEL1_CFG_RCGR);
- writel(0x1, DSI_PIXEL1_CMD_RCGR);
- writel(0x1, DSI_PIXEL1_CBCR);
-
+ /* Set the MND for DSI1 pixel clock */
writel(pclk0_m, DSI_PIXEL1_M);
writel(pclk0_n, DSI_PIXEL1_N);
writel(pclk0_d, DSI_PIXEL1_D);
+ /* Set the update RCG bit */
+ writel(0x1, DSI_PIXEL1_CMD_RCGR);
+ rcg_update_config(DSI_PIXEL1_CMD_RCGR);
+ /* Enable the branch clock */
+ writel(0x1, DSI_PIXEL1_CBCR);
+ branch_clk_halt_check(DSI_PIXEL1_CBCR);
/* Configure ESC clock */
ret = clk_get_set_enable("mdss_esc1_clk", 0, 1);
diff --git a/platform/msm8916/platform.c b/platform/msm8916/platform.c
index 6729667..8d0f033 100644
--- a/platform/msm8916/platform.c
+++ b/platform/msm8916/platform.c
@@ -202,6 +202,11 @@
return ret;
}
+int platform_is_apq8016()
+{
+ return board_platform_id() == APQ8016 ? 1 : 0;
+}
+
/* DYNAMIC SMEM REGION feature enables LK to dynamically
* read the SMEM addr info from TCSR_TZ_WONCE register.
* The first word read, if indicates a MAGIC number, then
diff --git a/platform/msm8952/acpuclock.c b/platform/msm8952/acpuclock.c
index bdd1d6d..87e31dd 100644
--- a/platform/msm8952/acpuclock.c
+++ b/platform/msm8952/acpuclock.c
@@ -36,6 +36,8 @@
#include <platform/clock.h>
#include <platform.h>
+#define MAX_LOOPS 500
+
void hsusb_clock_init(void)
{
int ret;
@@ -265,6 +267,34 @@
}
}
+static void rcg_update_config(uint32_t reg)
+{
+ int i;
+
+ for (i = 0; i < MAX_LOOPS; i++) {
+ if (!(readl(reg) & BIT(0)))
+ return;
+ udelay(1);
+ }
+
+ dprintf(CRITICAL, "failed to update rcg config for reg = 0x%x\n", reg);
+ ASSERT(0);
+}
+
+static void branch_clk_halt_check(uint32_t reg)
+{
+ int i;
+
+ for (i = 0; i < MAX_LOOPS; i++) {
+ if (!(readl(reg) & BIT(31)))
+ return;
+ udelay(1);
+ }
+
+ dprintf(CRITICAL, "failed to enable branch for reg = 0x%x\n", reg);
+ ASSERT(0);
+}
+
/* Disable all the branch clocks needed by the DSI controller */
void gcc_dsi_clocks_disable(void)
{
@@ -278,20 +308,32 @@
{
int ret;
- /* Configure Byte clock -autopll- This will not change becasue
- byte clock does not need any divider*/
+ /*
+ * Configure Byte clock -autopll- This will not change becasue
+ * byte clock does not need any divider
+ */
+ /* Set the source for DSI0 byte RCG */
writel(0x100, DSI_BYTE0_CFG_RCGR);
+ /* Set the update RCG bit */
writel(0x1, DSI_BYTE0_CMD_RCGR);
+ rcg_update_config(DSI_BYTE0_CMD_RCGR);
+ /* Enable the branch clock */
writel(0x1, DSI_BYTE0_CBCR);
+ branch_clk_halt_check(DSI_BYTE0_CBCR);
/* Configure Pixel clock */
+ /* Set the source for DSI0 pixel RCG */
writel(0x100, DSI_PIXEL0_CFG_RCGR);
- writel(0x1, DSI_PIXEL0_CMD_RCGR);
- writel(0x1, DSI_PIXEL0_CBCR);
-
+ /* Set the MND for DSI0 pixel clock */
writel(pclk0_m, DSI_PIXEL0_M);
writel(pclk0_n, DSI_PIXEL0_N);
writel(pclk0_d, DSI_PIXEL0_D);
+ /* Set the update RCG bit */
+ writel(0x1, DSI_PIXEL0_CMD_RCGR);
+ rcg_update_config(DSI_PIXEL0_CMD_RCGR);
+ /* Enable the branch clock */
+ writel(0x1, DSI_PIXEL0_CBCR);
+ branch_clk_halt_check(DSI_PIXEL0_CBCR);
/* Configure ESC clock */
ret = clk_get_set_enable("mdss_esc0_clk", 0, 1);
diff --git a/platform/msm8994/acpuclock.c b/platform/msm8994/acpuclock.c
index 6f4e0f0..533cf47 100644
--- a/platform/msm8994/acpuclock.c
+++ b/platform/msm8994/acpuclock.c
@@ -43,6 +43,8 @@
#define CE2_CLK_ID 0x1
#define RPM_SMD_KEY_RATE 0x007A484B
+#define MAX_LOOPS 500
+
uint32_t CE2_CLK[][8]=
{
{
@@ -455,6 +457,34 @@
clk_disable(clk_get("mmss_mmssnoc_axi_clk"));
}
+static void rcg_update_config(uint32_t reg)
+{
+ int i;
+
+ for (i = 0; i < MAX_LOOPS; i++) {
+ if (!(readl(reg) & BIT(0)))
+ return;
+ udelay(1);
+ }
+
+ dprintf(CRITICAL, "failed to update rcg config for reg = 0x%x\n", reg);
+ ASSERT(0);
+}
+
+static void branch_clk_halt_check(uint32_t reg)
+{
+ int i;
+
+ for (i = 0; i < MAX_LOOPS; i++) {
+ if (!(readl(reg) & BIT(31)))
+ return;
+ udelay(1);
+ }
+
+ dprintf(CRITICAL, "failed to enable branch for reg = 0x%x\n", reg);
+ ASSERT(0);
+}
+
void mmss_dsi_clock_enable(uint32_t cfg_rcgr, uint32_t flags,
uint8_t pclk0_m, uint8_t pclk0_n, uint8_t pclk0_d)
{
@@ -462,17 +492,28 @@
if (flags & MMSS_DSI_CLKS_FLAG_DSI0) {
/* Enable DSI0 branch clocks */
+
+ /* Set the source for DSI0 byte RCG */
writel(cfg_rcgr, DSI_BYTE0_CFG_RCGR);
+ /* Set the update RCG bit */
writel(0x1, DSI_BYTE0_CMD_RCGR);
+ rcg_update_config(DSI_BYTE0_CMD_RCGR);
+ /* Enable the branch clock */
writel(0x1, DSI_BYTE0_CBCR);
+ branch_clk_halt_check(DSI_BYTE0_CBCR);
+ /* Set the source for DSI0 pixel RCG */
writel(cfg_rcgr, DSI_PIXEL0_CFG_RCGR);
- writel(0x1, DSI_PIXEL0_CMD_RCGR);
- writel(0x1, DSI_PIXEL0_CBCR);
-
+ /* Set the MND for DSI0 pixel clock */
writel(pclk0_m, DSI_PIXEL0_M);
writel(pclk0_n, DSI_PIXEL0_N);
writel(pclk0_d, DSI_PIXEL0_D);
+ /* Set the update RCG bit */
+ writel(0x1, DSI_PIXEL0_CMD_RCGR);
+ rcg_update_config(DSI_PIXEL0_CMD_RCGR);
+ /* Enable the branch clock */
+ writel(0x1, DSI_PIXEL0_CBCR);
+ branch_clk_halt_check(DSI_PIXEL0_CBCR);
ret = clk_get_set_enable("mdss_esc0_clk", 0, 1);
if(ret)
@@ -484,17 +525,28 @@
if (flags & MMSS_DSI_CLKS_FLAG_DSI1) {
/* Enable DSI1 branch clocks */
+
+ /* Set the source for DSI1 byte RCG */
writel(cfg_rcgr, DSI_BYTE1_CFG_RCGR);
+ /* Set the update RCG bit */
writel(0x1, DSI_BYTE1_CMD_RCGR);
+ rcg_update_config(DSI_BYTE1_CMD_RCGR);
+ /* Enable the branch clock */
writel(0x1, DSI_BYTE1_CBCR);
+ branch_clk_halt_check(DSI_BYTE1_CBCR);
+ /* Set the source for DSI1 pixel RCG */
writel(cfg_rcgr, DSI_PIXEL1_CFG_RCGR);
- writel(0x1, DSI_PIXEL1_CMD_RCGR);
- writel(0x1, DSI_PIXEL1_CBCR);
-
+ /* Set the MND for DSI1 pixel clock */
writel(pclk0_m, DSI_PIXEL1_M);
writel(pclk0_n, DSI_PIXEL1_N);
writel(pclk0_d, DSI_PIXEL1_D);
+ /* Set the update RCG bit */
+ writel(0x1, DSI_PIXEL1_CMD_RCGR);
+ rcg_update_config(DSI_PIXEL1_CMD_RCGR);
+ /* Enable the branch clock */
+ writel(0x1, DSI_PIXEL1_CBCR);
+ branch_clk_halt_check(DSI_PIXEL1_CBCR);
ret = clk_get_set_enable("mdss_esc1_clk", 0, 1);
if(ret)
diff --git a/platform/msm8996/include/platform/gpio.h b/platform/msm8996/include/platform/gpio.h
index 5626d50..4d9c650 100644
--- a/platform/msm8996/include/platform/gpio.h
+++ b/platform/msm8996/include/platform/gpio.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
@@ -57,4 +57,7 @@
void gpio_config_uart_dm(uint8_t id);
void gpio_config_blsp_i2c(uint8_t, uint8_t);
+void gpio_set(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/msm8996/include/platform/iomap.h b/platform/msm8996/include/platform/iomap.h
index 16fa8af..e112788 100644
--- a/platform/msm8996/include/platform/iomap.h
+++ b/platform/msm8996/include/platform/iomap.h
@@ -198,4 +198,333 @@
#define MSM_MMSS_CLK_CTL_BASE 0x8C0000
#define MMSS_MISC_AHB_CBCR (MSM_MMSS_CLK_CTL_BASE + 0x5018)
+
+#define MIPI_DSI_BASE (0x994000)
+#define MIPI_DSI0_BASE (MIPI_DSI_BASE)
+#define MIPI_DSI1_BASE (0x996000)
+#define DSI0_PHY_BASE (0x994400)
+#define DSI1_PHY_BASE (0x996400)
+#define DSI0_PLL_BASE (0x994800)
+#define DSI1_PLL_BASE (0x996800)
+#define DSI0_REGULATOR_BASE (0x994000)
+#define DSI1_REGULATOR_BASE (0x996000)
+
+#define MMSS_DSI_PHY_PLL_CORE_VCO_TUNE 0x0160
+#define MMSS_DSI_PHY_PLL_CORE_KVCO_CODE 0x0168
+
+#define MDP_BASE (0x900000)
+
+
+#ifdef MDP_PP_0_BASE
+#undef MDP_PP_0_BASE
+#endif
+#define MDP_PP_0_BASE REG_MDP(0x71000)
+
+#ifdef MDP_PP_1_BASE
+#undef MDP_PP_1_BASE
+#endif
+#define MDP_PP_1_BASE REG_MDP(0x71800)
+
+#define REG_MDP(off) (MDP_BASE + (off))
+
+#ifdef MDP_HW_REV
+#undef MDP_HW_REV
+#endif
+#define MDP_HW_REV REG_MDP(0x1000)
+
+#ifdef MDP_INTR_EN
+#undef MDP_INTR_EN
+#endif
+#define MDP_INTR_EN REG_MDP(0x1010)
+
+#ifdef MDP_INTR_CLEAR
+#undef MDP_INTR_CLEAR
+#endif
+#define MDP_INTR_CLEAR REG_MDP(0x1018)
+
+#ifdef MDP_HIST_INTR_EN
+#undef MDP_HIST_INTR_EN
+#endif
+#define MDP_HIST_INTR_EN REG_MDP(0x101C)
+
+#ifdef MDP_DISP_INTF_SEL
+#undef MDP_DISP_INTF_SEL
+#endif
+#define MDP_DISP_INTF_SEL REG_MDP(0x1004)
+
+#ifdef MDP_VIDEO_INTF_UNDERFLOW_CTL
+#undef MDP_VIDEO_INTF_UNDERFLOW_CTL
+#endif
+#define MDP_VIDEO_INTF_UNDERFLOW_CTL REG_MDP(0x12E0)
+
+#ifdef MDP_UPPER_NEW_ROI_PRIOR_RO_START
+#undef MDP_UPPER_NEW_ROI_PRIOR_RO_START
+#endif
+#define MDP_UPPER_NEW_ROI_PRIOR_RO_START REG_MDP(0x11EC)
+
+#ifdef MDP_LOWER_NEW_ROI_PRIOR_TO_START
+#undef MDP_LOWER_NEW_ROI_PRIOR_TO_START
+#endif
+#define MDP_LOWER_NEW_ROI_PRIOR_TO_START REG_MDP(0x13F8)
+
+#ifdef MDP_INTF_0_TIMING_ENGINE_EN
+#undef MDP_INTF_0_TIMING_ENGINE_EN
+#endif
+#define MDP_INTF_0_TIMING_ENGINE_EN REG_MDP(0x6b000)
+
+#ifdef MDP_INTF_1_TIMING_ENGINE_EN
+#undef MDP_INTF_1_TIMING_ENGINE_EN
+#endif
+#define MDP_INTF_1_TIMING_ENGINE_EN REG_MDP(0x6b800)
+
+#ifdef MDP_INTF_2_TIMING_ENGINE_EN
+#undef MDP_INTF_2_TIMING_ENGINE_EN
+#endif
+#define MDP_INTF_2_TIMING_ENGINE_EN REG_MDP(0x6C000)
+
+#ifdef MDP_CTL_0_BASE
+#undef MDP_CTL_0_BASE
+#endif
+#define MDP_CTL_0_BASE REG_MDP(0x2000)
+
+#ifdef MDP_CTL_1_BASE
+#undef MDP_CTL_1_BASE
+#endif
+#define MDP_CTL_1_BASE REG_MDP(0x2200)
+
+#ifdef MDP_REG_SPLIT_DISPLAY_EN
+#undef MDP_REG_SPLIT_DISPLAY_EN
+#endif
+#define MDP_REG_SPLIT_DISPLAY_EN REG_MDP(0x12F4)
+
+#ifdef MDP_REG_SPLIT_DISPLAY_UPPER_PIPE_CTL
+#undef MDP_REG_SPLIT_DISPLAY_UPPER_PIPE_CTL
+#endif
+#define MDP_REG_SPLIT_DISPLAY_UPPER_PIPE_CTL REG_MDP(0x12F8)
+
+#ifdef MDP_REG_SPLIT_DISPLAY_LOWER_PIPE_CTL
+#undef MDP_REG_SPLIT_DISPLAY_LOWER_PIPE_CTL
+#endif
+#define MDP_REG_SPLIT_DISPLAY_LOWER_PIPE_CTL REG_MDP(0x13F0)
+
+#ifdef MDP_INTF_0_BASE
+#undef MDP_INTF_0_BASE
+#endif
+#define MDP_INTF_0_BASE REG_MDP(0x6b000)
+
+#ifdef MDP_INTF_1_BASE
+#undef MDP_INTF_1_BASE
+#endif
+#define MDP_INTF_1_BASE REG_MDP(0x6b800)
+
+#ifdef MDP_INTF_2_BASE
+#undef MDP_INTF_2_BASE
+#endif
+#define MDP_INTF_2_BASE REG_MDP(0x6c000)
+
+#ifdef MDP_CLK_CTRL0
+#undef MDP_CLK_CTRL0
+#endif
+#define MDP_CLK_CTRL0 REG_MDP(0x12AC)
+
+#ifdef MDP_CLK_CTRL1
+#undef MDP_CLK_CTRL1
+#endif
+#define MDP_CLK_CTRL1 REG_MDP(0x12B4)
+
+#ifdef MDP_CLK_CTRL2
+#undef MDP_CLK_CTRL2
+#endif
+#define MDP_CLK_CTRL2 REG_MDP(0x12BC)
+
+#ifdef MDP_CLK_CTRL3
+#undef MDP_CLK_CTRL3
+#endif
+#define MDP_CLK_CTRL3 REG_MDP(0x13A8)
+
+#ifdef MDP_CLK_CTRL4
+#undef MDP_CLK_CTRL4
+#endif
+#define MDP_CLK_CTRL4 REG_MDP(0x13B0)
+
+#ifdef MDP_CLK_CTRL5
+#undef MDP_CLK_CTRL5
+#endif
+#define MDP_CLK_CTRL5 REG_MDP(0x13B8)
+
+#ifdef MDP_CLK_CTRL6
+#undef MDP_CLK_CTRL6
+#endif
+#define MDP_CLK_CTRL6 REG_MDP(0x12C4)
+
+#ifdef MDP_CLK_CTRL7
+#undef MDP_CLK_CTRL7
+#endif
+#define MDP_CLK_CTRL7 REG_MDP(0x13D0)
+
+#ifdef MMSS_MDP_SMP_ALLOC_W_BASE
+#undef MMSS_MDP_SMP_ALLOC_W_BASE
+#endif
+#define MMSS_MDP_SMP_ALLOC_W_BASE REG_MDP(0x1080)
+
+#ifdef MMSS_MDP_SMP_ALLOC_R_BASE
+#undef MMSS_MDP_SMP_ALLOC_R_BASE
+#endif
+#define MMSS_MDP_SMP_ALLOC_R_BASE REG_MDP(0x1130)
+
+#ifdef MDP_QOS_REMAPPER_CLASS_0
+#undef MDP_QOS_REMAPPER_CLASS_0
+#endif
+#define MDP_QOS_REMAPPER_CLASS_0 REG_MDP(0x11E0)
+
+#ifdef MDP_QOS_REMAPPER_CLASS_1
+#undef MDP_QOS_REMAPPER_CLASS_1
+#endif
+#define MDP_QOS_REMAPPER_CLASS_1 REG_MDP(0x11E4)
+
+#ifdef VBIF_VBIF_DDR_FORCE_CLK_ON
+#undef VBIF_VBIF_DDR_FORCE_CLK_ON
+#endif
+#define VBIF_VBIF_DDR_FORCE_CLK_ON REG_MDP(0xb0004)
+
+#ifdef VBIF_VBIF_DDR_OUT_MAX_BURST
+#undef VBIF_VBIF_DDR_OUT_MAX_BURST
+#endif
+#define VBIF_VBIF_DDR_OUT_MAX_BURST REG_MDP(0xb00D8)
+
+#ifdef VBIF_VBIF_DDR_ARB_CTRL
+#undef VBIF_VBIF_DDR_ARB_CTRL
+#endif
+#define VBIF_VBIF_DDR_ARB_CTRL REG_MDP(0xb00F0)
+
+#ifdef VBIF_VBIF_DDR_RND_RBN_QOS_ARB
+#undef VBIF_VBIF_DDR_RND_RBN_QOS_ARB
+#endif
+#define VBIF_VBIF_DDR_RND_RBN_QOS_ARB REG_MDP(0xb0124)
+
+#ifdef VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF0
+#undef VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF0
+#endif
+#define VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF0 REG_MDP(0xb0160)
+
+#ifdef VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF1
+#undef VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF1
+#endif
+#define VBIF_VBIF_DDR_AXI_AMEMTYPE_CONF1 REG_MDP(0xb0164)
+
+#ifdef VBIF_VBIF_DDR_OUT_AOOO_AXI_EN
+#undef VBIF_VBIF_DDR_OUT_AOOO_AXI_EN
+#endif
+#define VBIF_VBIF_DDR_OUT_AOOO_AXI_EN REG_MDP(0xb0178)
+
+#ifdef VBIF_VBIF_DDR_OUT_AX_AOOO
+#undef VBIF_VBIF_DDR_OUT_AX_AOOO
+#endif
+#define VBIF_VBIF_DDR_OUT_AX_AOOO REG_MDP(0xb017C)
+
+#ifdef VBIF_VBIF_IN_RD_LIM_CONF0
+#undef VBIF_VBIF_IN_RD_LIM_CONF0
+#endif
+#define VBIF_VBIF_IN_RD_LIM_CONF0 REG_MDP(0xb00B0)
+
+#ifdef VBIF_VBIF_IN_RD_LIM_CONF1
+#undef VBIF_VBIF_IN_RD_LIM_CONF1
+#endif
+#define VBIF_VBIF_IN_RD_LIM_CONF1 REG_MDP(0xb00B4)
+
+#ifdef VBIF_VBIF_IN_RD_LIM_CONF2
+#undef VBIF_VBIF_IN_RD_LIM_CONF2
+#endif
+#define VBIF_VBIF_IN_RD_LIM_CONF2 REG_MDP(0xb00B8)
+
+#ifdef VBIF_VBIF_IN_RD_LIM_CONF3
+#undef VBIF_VBIF_IN_RD_LIM_CONF3
+#endif
+#define VBIF_VBIF_IN_RD_LIM_CONF3 REG_MDP(0xb00BC)
+
+#ifdef VBIF_VBIF_IN_WR_LIM_CONF0
+#undef VBIF_VBIF_IN_WR_LIM_CONF0
+#endif
+#define VBIF_VBIF_IN_WR_LIM_CONF0 REG_MDP(0xb00C0)
+
+#ifdef VBIF_VBIF_IN_WR_LIM_CONF1
+#undef VBIF_VBIF_IN_WR_LIM_CONF1
+#endif
+#define VBIF_VBIF_IN_WR_LIM_CONF1 REG_MDP(0xb00C4)
+
+#ifdef VBIF_VBIF_IN_WR_LIM_CONF2
+#undef VBIF_VBIF_IN_WR_LIM_CONF2
+#endif
+#define VBIF_VBIF_IN_WR_LIM_CONF2 REG_MDP(0xb00C8)
+
+#ifdef VBIF_VBIF_IN_WR_LIM_CONF3
+#undef VBIF_VBIF_IN_WR_LIM_CONF3
+#endif
+#define VBIF_VBIF_IN_WR_LIM_CONF3 REG_MDP(0xb00CC)
+
+#ifdef VBIF_VBIF_ABIT_SHORT
+#undef VBIF_VBIF_ABIT_SHORT
+#endif
+#define VBIF_VBIF_ABIT_SHORT REG_MDP(0xb0070)
+
+#ifdef VBIF_VBIF_ABIT_SHORT_CONF
+#undef VBIF_VBIF_ABIT_SHORT_CONF
+#endif
+#define VBIF_VBIF_ABIT_SHORT_CONF REG_MDP(0xb0074)
+
+#ifdef VBIF_VBIF_GATE_OFF_WRREQ_EN
+#undef VBIF_VBIF_GATE_OFF_WRREQ_EN
+#endif
+#define VBIF_VBIF_GATE_OFF_WRREQ_EN REG_MDP(0xb00A8)
+
+#define MDP_VP_0_VIG_0_BASE REG_MDP(0x5000)
+#define MDP_VP_0_VIG_1_BASE REG_MDP(0x7000)
+#define MDP_VP_0_RGB_0_BASE REG_MDP(0x15000)
+#define MDP_VP_0_RGB_1_BASE REG_MDP(0x17000)
+#define MDP_VP_0_DMA_0_BASE REG_MDP(0x25000)
+#define MDP_VP_0_DMA_1_BASE REG_MDP(0x27000)
+#define MDP_VP_0_MIXER_0_BASE REG_MDP(0x45000)
+#define MDP_VP_0_MIXER_1_BASE REG_MDP(0x46000)
+
+#define DMA_CMD_OFFSET 0x048
+#define DMA_CMD_LENGTH 0x04C
+
+#define INT_CTRL 0x110
+#define CMD_MODE_DMA_SW_TRIGGER 0x090
+
+#define EOT_PACKET_CTRL 0x0CC
+#define MISR_CMD_CTRL 0x0A0
+#define MISR_VIDEO_CTRL 0x0A4
+#define VIDEO_MODE_CTRL 0x010
+#define HS_TIMER_CTRL 0x0BC
+
+#define SOFT_RESET 0x118
+#define CLK_CTRL 0x11C
+#define TRIG_CTRL 0x084
+#define CTRL 0x004
+#define COMMAND_MODE_DMA_CTRL 0x03C
+#define COMMAND_MODE_MDP_CTRL 0x040
+#define COMMAND_MODE_MDP_DCS_CMD_CTRL 0x044
+#define COMMAND_MODE_MDP_STREAM0_CTRL 0x058
+#define COMMAND_MODE_MDP_STREAM0_TOTAL 0x05C
+#define COMMAND_MODE_MDP_STREAM1_CTRL 0x060
+#define COMMAND_MODE_MDP_STREAM1_TOTAL 0x064
+#define ERR_INT_MASK0 0x10C
+
+#define LANE_CTL 0x0AC
+#define LANE_SWAP_CTL 0x0B0
+#define TIMING_CTL 0x0C4
+
+#define VIDEO_MODE_ACTIVE_H 0x024
+#define VIDEO_MODE_ACTIVE_V 0x028
+#define VIDEO_MODE_TOTAL 0x02C
+#define VIDEO_MODE_HSYNC 0x030
+#define VIDEO_MODE_VSYNC 0x034
+#define VIDEO_MODE_VSYNC_VPOS 0x038
+
+#define QPNP_LED_CTRL_BASE 0xD000
+#define QPNP_BLUE_LPG_CTRL_BASE 0xB100
+#define QPNP_GREEN_LPG_CTRL_BASE 0xB200
+#define QPNP_RED_LPG_CTRL_BASE 0xB300
+
#endif
diff --git a/platform/msm_shared/dev_tree.c b/platform/msm_shared/dev_tree.c
index 27296b4..5cd6576 100755
--- a/platform/msm_shared/dev_tree.c
+++ b/platform/msm_shared/dev_tree.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-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
@@ -502,6 +502,11 @@
dprintf(CRITICAL, "DTB offset is incorrect, kernel image does not have appended DTB\n");
+ dprintf(INFO, "Device info 0x%08x/%08x/0x%08x/%u, pmic 0x%0x/0x%x/0x%x/0x%0x\n",
+ board_platform_id(), board_soc_version(),
+ board_target_id(), board_hardware_subtype(),
+ board_pmic_target(0), board_pmic_target(1),
+ board_pmic_target(2), board_pmic_target(3));
return NULL;
}
diff --git a/platform/msm_shared/display.c b/platform/msm_shared/display.c
index 0897b58..3bf5621 100644
--- a/platform/msm_shared/display.c
+++ b/platform/msm_shared/display.c
@@ -331,6 +331,12 @@
fbcon_setup(&(panel->fb));
display_image_on_screen();
+
+ if (panel->dsi2HDMI_config)
+ ret = panel->dsi2HDMI_config(&(panel->panel_info));
+ if (ret)
+ goto msm_display_init_out;
+
ret = msm_display_config();
if (ret)
goto msm_display_init_out;
diff --git a/platform/msm_shared/glink/glink_api.c b/platform/msm_shared/glink/glink_api.c
index 24f777d..fe5fd92 100644
--- a/platform/msm_shared/glink/glink_api.c
+++ b/platform/msm_shared/glink/glink_api.c
@@ -43,7 +43,7 @@
#define GLINK_INITIALIZED 1
/*===========================================================================
- GLOBAL DATA DECLARATIONS
+ GLOBAL DATA DECLARATIONS
===========================================================================*/
int glink_core_status = GLINK_NOT_INITIALIZED;
@@ -74,174 +74,249 @@
/*===========================================================================
LOCAL FUNCTION DEFINITIONS
===========================================================================*/
-
+/*===========================================================================
+ FUNCTION glinki_add_ch_to_xport
+===========================================================================*/
+/**
+ * Add remote/local channel context to xport open channel queue
+ *
+ * @param[in] if_ptr Pointer to xport if on which channel is to
+ * be opened
+ * @param[in] req_if_ptr Pointer to xport if on which channel
+ * actually wants to open
+ * @param[in] ch_ctx channel context
+ * @param[out] allocated_ch_ctx Pointer to channel context pointer
+ * @param[in] local_open flag to determine if channel is opened
+ * locally or remotely
+ * @param[in] prio negotiated xport priority
+ * (used to send priority via remote_open_ack to
+ * remote side)
+ *
+ * @return pointer to glink_transport_if_type struct
+ *
+ * @sideeffects NONE
+ */
+/*=========================================================================*/
glink_err_type glinki_add_ch_to_xport
(
glink_transport_if_type *if_ptr,
glink_transport_if_type *req_if_ptr,
glink_channel_ctx_type *ch_ctx,
- glink_channel_ctx_type **allocated_ch_ctx,
+ glink_channel_ctx_type **allocated_ch_ctx,
unsigned int local_open,
- boolean migration_state,
glink_xport_priority migrated_ch_prio
)
{
- glink_err_type status = 0;
+ glink_err_type status;
glink_channel_ctx_type *open_ch_ctx;
glink_core_xport_ctx_type *xport_ctx = if_ptr->glink_core_priv;
/* See if channel already exists in open_list */
glink_os_cs_acquire(&xport_ctx->channel_q_cs);
- open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
- while(open_ch_ctx != NULL)
+
+ for( open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
+ open_ch_ctx;
+ open_ch_ctx = smem_list_next(open_ch_ctx) )
{
- if (strcmp(open_ch_ctx->name, ch_ctx->name) == 0)
+ if( 0 != glink_os_string_compare( open_ch_ctx->name, ch_ctx->name ) )
{
- /* We've found a channel name is already in the list of open channel */
- /* increase reference open count for channel */
- *allocated_ch_ctx = open_ch_ctx;
- open_ch_ctx->ref_count++;
+ continue;
+ }
+ /* grab lock to avoid race condition for channel state change */
+ glink_os_cs_acquire(&open_ch_ctx->ch_state_cs);
- /* Case A: Channel was opened before on the same host */
- if((open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN) && local_open) {
-
- open_ch_ctx->req_if_ptr = req_if_ptr;
-
- /* Copy local open ctx params */
- open_ch_ctx->notify_rx = ch_ctx->notify_rx;
- open_ch_ctx->notify_rxv = ch_ctx->notify_rxv;
- open_ch_ctx->notify_tx_done = ch_ctx->notify_tx_done;
- open_ch_ctx->notify_state = ch_ctx->notify_state;
- open_ch_ctx->notify_rx_intent_req = ch_ctx->notify_rx_intent_req;
- open_ch_ctx->notify_rx_intent = ch_ctx->notify_rx_intent;
- open_ch_ctx->notify_rx_sigs = ch_ctx->notify_rx_sigs;
- open_ch_ctx->priv = ch_ctx->priv;
- open_ch_ctx->ch_open_options = ch_ctx->ch_open_options;
-
- /* release lock before context switch otherwise it is causing
- * deadlock */
- glink_os_cs_release(&xport_ctx->channel_q_cs);
-
- /* Send open cmd to transport */
- status = if_ptr->tx_cmd_ch_open(if_ptr,
- open_ch_ctx->lcid, open_ch_ctx->name,
- open_ch_ctx->req_if_ptr->glink_priority);
- }
- else if ((open_ch_ctx->state == GLINK_CH_STATE_LOCAL_OPEN) &&
- (!local_open))
- {
- /* Case B: Channel was opened on this end and we got a remote open */
- open_ch_ctx->rcid = ch_ctx->rcid;
-
- status = xport_ctx->channel_init(open_ch_ctx);
-
- /* release lock before context switch otherwise it is causing deadlock */
- glink_os_cs_release(&xport_ctx->channel_q_cs);
-
- if (status == GLINK_STATUS_SUCCESS)
- {
- /* Send ACK to transport */
- if_ptr->tx_cmd_ch_remote_open_ack(if_ptr, open_ch_ctx->rcid, migrated_ch_prio);
- }
- } else if ((open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN_LOCAL_CLOSE)
- && (local_open)) {
- /* Allocate new channel context */
- break; /* code would break out of loop and create new ch ctx */
- } else {
- /* Can't handle this state */
- ASSERT(0);
- }
-
- break;
- } /* end if match found */
- open_ch_ctx = smem_list_next(open_ch_ctx);
- }/* end while */
-
- if (open_ch_ctx != NULL)
- {
- glink_os_free(ch_ctx);
-
- /* connect channel here if state is local open and remote open request
- * comes up and channel migration is done; channel will be connected in
- * remote_open_ack if channel state is remote open and local open
- * request comes up */
- if(open_ch_ctx->state == GLINK_CH_STATE_LOCAL_OPEN &&
- migration_state == FALSE && status == GLINK_STATUS_SUCCESS)
+ if( local_open )
{
- /* Set the channel state to OPEN */
- open_ch_ctx->state = GLINK_CH_STATE_OPEN;
- /* Inform the client */
- open_ch_ctx->notify_state(open_ch_ctx, open_ch_ctx->priv,
- GLINK_CONNECTED);
- }
- }
- else
- {
- /* Channel not in the list - it was not previously opened */
- ch_ctx->if_ptr = if_ptr;
- *allocated_ch_ctx = ch_ctx;
+ /* LOCAL OPEN REQUEST */
+ ASSERT( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSED );
- /* Set channel state */
- if (local_open) {
- /* This is a local open */
- ch_ctx->state = GLINK_CH_STATE_LOCAL_OPEN;
- ch_ctx->req_if_ptr = req_if_ptr;
- }
- else {
- ch_ctx->state = GLINK_CH_STATE_REMOTE_OPEN;
- }
+ glink_os_cs_init( &ch_ctx->tx_cs );
+ glink_os_cs_init( &ch_ctx->ch_state_cs );
- glink_os_cs_init(&ch_ctx->tx_cs);
+ ch_ctx->rcid = open_ch_ctx->rcid;
+ ch_ctx->lcid = open_ch_ctx->lcid;
+ ch_ctx->pintents = open_ch_ctx->pintents;
+ ch_ctx->if_ptr = open_ch_ctx->if_ptr;
+ ch_ctx->req_if_ptr = req_if_ptr;
- /* Append the channel to the transport interface's open_list */
- ch_ctx->ref_count++;
- ch_ctx->lcid = xport_ctx->free_lcid;
- xport_ctx->free_lcid++;
- smem_list_append(&if_ptr->glink_core_priv->open_list, ch_ctx);
+ ch_ctx->remote_state = open_ch_ctx->remote_state;
+ ch_ctx->local_state = GLINK_LOCAL_CH_OPENING;
- /* release lock before context switch otherwise it is causing deadlock */
- glink_os_cs_release(&xport_ctx->channel_q_cs);
+ /* release lock before context switch otherwise it is causing
+ * deadlock */
+ smem_list_delete( &xport_ctx->open_list, open_ch_ctx );
+ smem_list_append( &xport_ctx->open_list, ch_ctx );
- /* Send the OPEN command to transport */
- if (local_open)
- {
- status = if_ptr->tx_cmd_ch_open(if_ptr, ch_ctx->lcid,
- ch_ctx->name,
- ch_ctx->req_if_ptr->glink_priority);
+ glink_os_cs_release(&open_ch_ctx->ch_state_cs);
+ glink_os_cs_release(&xport_ctx->channel_q_cs);
+
+ glink_os_free( open_ch_ctx );
+ *allocated_ch_ctx = ch_ctx;
+ /* Send open cmd to transport */
+ status = if_ptr->tx_cmd_ch_open( if_ptr,
+ ch_ctx->lcid,
+ ch_ctx->name,
+ ch_ctx->req_if_ptr->glink_priority );
}
else
{
- /* initialize channel resources */
- status = xport_ctx->channel_init(ch_ctx);
+ /* REMOTE OPEN REQUEST */
- /* ACK the transport for remote open */
- if (status == GLINK_STATUS_SUCCESS)
- {
- if_ptr->tx_cmd_ch_remote_open_ack(if_ptr, ch_ctx->rcid,
- migrated_ch_prio);
+ if( open_ch_ctx->remote_state == GLINK_REMOTE_CH_SSR_RESET )
+ {/* During SSR previous channel ctx needs to be destroyed
+ * new remote/local open request will create new context */
+ glink_os_cs_release( &open_ch_ctx->ch_state_cs );
+ continue;
}
- }
- if (status != GLINK_STATUS_SUCCESS)
- {
- /* Remove the channel from the transport interface's open_list */
- xport_ctx->free_lcid--;
+ ASSERT( open_ch_ctx->remote_state == GLINK_REMOTE_CH_CLOSED );
- glink_os_cs_acquire(&xport_ctx->channel_q_cs);
- smem_list_delete(&if_ptr->glink_core_priv->open_list, ch_ctx);
+ open_ch_ctx->rcid = ch_ctx->rcid;
+ *allocated_ch_ctx = open_ch_ctx;
+ status = xport_ctx->channel_init(open_ch_ctx);
+
+ if( status == GLINK_STATUS_SUCCESS )
+ {
+ open_ch_ctx->remote_state = GLINK_REMOTE_CH_OPENED;
+ }
+
+ /* release lock before context switch otherwise it is causing deadlock */
+ glink_os_cs_release(&open_ch_ctx->ch_state_cs);
glink_os_cs_release(&xport_ctx->channel_q_cs);
- /* free the ch_ctx structure and return */
- xport_ctx->channel_cleanup(ch_ctx);
+
+ if ( status == GLINK_STATUS_SUCCESS )
+ {
+ /* Send ACK to transport */
+ if_ptr->tx_cmd_ch_remote_open_ack( if_ptr,
+ open_ch_ctx->rcid,
+ migrated_ch_prio );
+
+ /* Inform the client */
+ if( open_ch_ctx->local_state == GLINK_LOCAL_CH_OPENED )
+ {
+ open_ch_ctx->notify_state( open_ch_ctx,
+ open_ch_ctx->priv,
+ GLINK_CONNECTED );
+ }
+ }
+
glink_os_free(ch_ctx);
+ } /* end If - else (local_open) */
+
+ return status;
+ } /* end for */
+
+ ASSERT( open_ch_ctx == NULL );
+
+ /* Channel not in the list - it was not previously opened */
+ ch_ctx->if_ptr = if_ptr;
+ *allocated_ch_ctx = ch_ctx;
+
+ /* Set channel state */
+ if (local_open)
+ {
+ /* This is a local open */
+ ch_ctx->local_state = GLINK_LOCAL_CH_OPENING;
+ ch_ctx->req_if_ptr = req_if_ptr;
+ }
+ else
+ {
+ ch_ctx->remote_state = GLINK_REMOTE_CH_OPENED;
+ }
+
+ glink_os_cs_init(&ch_ctx->tx_cs);
+ glink_os_cs_init(&ch_ctx->ch_state_cs);
+
+ /* Append the channel to the transport interface's open_list */
+ ch_ctx->lcid = xport_ctx->free_lcid;
+ xport_ctx->free_lcid++;
+ smem_list_append(&if_ptr->glink_core_priv->open_list, ch_ctx);
+
+ /* release lock before context switch otherwise it is causing deadlock */
+ glink_os_cs_release(&xport_ctx->channel_q_cs);
+
+ /* Send the OPEN command to transport */
+ if ( local_open )
+ {
+ status = if_ptr->tx_cmd_ch_open( if_ptr, ch_ctx->lcid,
+ ch_ctx->name,
+ ch_ctx->req_if_ptr->glink_priority );
+ }
+ else
+ {
+ /* initialize channel resources */
+ status = xport_ctx->channel_init(ch_ctx);
+
+ /* ACK the transport for remote open */
+ if (status == GLINK_STATUS_SUCCESS)
+ {
+ if_ptr->tx_cmd_ch_remote_open_ack( if_ptr, ch_ctx->rcid,
+ migrated_ch_prio );
}
}
+ if (status != GLINK_STATUS_SUCCESS)
+ {
+ /* Remove the channel from the transport interface's open_list */
+ xport_ctx->free_lcid--;
+ glink_os_cs_acquire(&xport_ctx->channel_q_cs);
+ smem_list_delete(&if_ptr->glink_core_priv->open_list, ch_ctx);
+ glink_os_cs_release(&xport_ctx->channel_q_cs);
+
+ /* free the ch_ctx structure and return */
+ xport_ctx->channel_cleanup(ch_ctx);
+ glink_os_free(ch_ctx);
+ }
+
return status;
}
-/** Default implementation of optional callbacks */
+/*===========================================================================
+ FUNCTION glink_is_channel_fully_opened
+===========================================================================*/
+/**
+ * Check whether this channel is fully opened or not (local & remote)
+ * This also checks transport status
+ *
+ * @param[in] handle glink channel handle
+ * @param[in] xport_ctx glink transport core private
+ *
+ * @return TRUE, if channel is fully opened
+ * FASLE, otherwise
+ *
+ * @sideeffects NONE
+ */
+/*=========================================================================*/
+static boolean glink_is_channel_fully_opened
+(
+ glink_handle_type handle,
+ glink_core_xport_ctx_type *xport_ctx
+)
+{
+ boolean ch_fully_opened = TRUE;
+ glink_os_cs_acquire( &handle->ch_state_cs );
+
+ if( handle->local_state != GLINK_LOCAL_CH_OPENED ||
+ handle->remote_state != GLINK_REMOTE_CH_OPENED )
+ {
+ ch_fully_opened = FALSE;
+ }
+
+ glink_os_cs_acquire( &xport_ctx->status_cs );
+ if( xport_ctx->status != GLINK_XPORT_LINK_UP )
+ {
+ ch_fully_opened = FALSE;
+ }
+
+ glink_os_cs_release( &xport_ctx->status_cs );
+ glink_os_cs_release( &handle->ch_state_cs );
+
+ return ch_fully_opened;
+}
+
+/** Default implementation of optional callbacks */
static void glink_default_notify_rx_sigs
(
glink_handle_type handle,
@@ -271,7 +346,7 @@
link_notif_data->link_notifier(&link_info, link_notif_data->priv);
}
-static uint32 glinki_find_remote_host
+uint32 glinki_find_remote_host
(
const char *remote_ss
)
@@ -279,10 +354,11 @@
uint32 remote_host;
ASSERT(remote_ss);
- for(remote_host = 0;
- remote_host < sizeof(glink_hosts_supported)/sizeof(char *);
- remote_host++) {
- if( 0 == strcmp(glink_hosts_supported[remote_host], remote_ss) ) {
+ for(remote_host = 0; remote_host < GLINK_NUM_HOSTS; remote_host++)
+ {
+ if( 0 == glink_os_string_compare( glink_hosts_supported[remote_host],
+ remote_ss ) )
+ {
/* Match found, break out of loop */
break;
}
@@ -297,24 +373,18 @@
glink_link_state_type state
)
{
- glink_link_info_type link_info;
-
ASSERT(xport_ctx);
ASSERT(link_notif_data);
- link_info.xport = xport_ctx->xport;
- link_info.remote_ss = xport_ctx->remote_ss;
- link_info.link_state = state;
-
- if(link_notif_data->xport == NULL ||
- 0 == strcmp(xport_ctx->xport, link_notif_data->xport)) {
+ if( link_notif_data->xport == NULL ||
+ 0 == glink_os_string_compare( xport_ctx->xport, link_notif_data->xport ) )
+ {
/* xport not specified, or it is specified and matches the current xport */
/* Invoke registered callback */
- link_notif_data->link_notifier(&link_info, link_notif_data->priv);
+ glinki_call_link_notifier(link_notif_data, xport_ctx, state);
}
}
-
static void glinki_scan_xports_and_notify
(
glink_link_notif_data_type *link_notif_data
@@ -327,82 +397,33 @@
ASSERT(link_notif_data);
/* Find matching subsystem */
- if(link_notif_data->remote_ss) {
- remote_host = glinki_find_remote_host(link_notif_data->remote_ss);
+ for(remote_host = 0;
+ remote_host < sizeof(glink_hosts_supported)/sizeof(char *);
+ remote_host++)
+ {
+ if ( link_notif_data->remote_ss != NULL &&
+ 0 != glink_os_string_compare( glink_hosts_supported[remote_host],
+ link_notif_data->remote_ss ) )
+ {
+ /* client is not interested in this remote SS */
+ continue;
+ }
/* Find the xport and give link UP notification */
- if_ptr = smem_list_first(&glink_registered_transports[remote_host]);
- if(if_ptr == NULL) {
- /* No registered xports at this time, return without doing anything */
- return;
- }
+ for (if_ptr = smem_list_first(&glink_registered_transports[remote_host]);
+ if_ptr != NULL;
+ if_ptr = smem_list_next(if_ptr))
+ {
+ xport_ctx = if_ptr->glink_core_priv;
- if(link_notif_data->xport) {
- do {
- xport_ctx = if_ptr->glink_core_priv;
- if( 0 == strcmp(xport_ctx->xport, link_notif_data->xport) ) {
- /* Match found, break out of loop */
- break;
- }
- }while ((if_ptr = smem_list_next(if_ptr)) != NULL);
-
- if((if_ptr != NULL) && (xport_ctx->status == GLINK_XPORT_LINK_UP)) {
+ if (xport_ctx->status == GLINK_XPORT_LINK_UP)
+ {
/* Invoke registered callback */
- glinki_call_link_notifier(link_notif_data, xport_ctx,
- GLINK_LINK_STATE_UP);
+ glinki_check_xport_and_notify( link_notif_data, xport_ctx,
+ GLINK_LINK_STATE_UP );
}
- } else {
- /* No xport has been specified, invoke notifier for all registered
- * xports */
- do {
- xport_ctx = if_ptr->glink_core_priv;
- if(xport_ctx->status == GLINK_XPORT_LINK_UP) {
- /* Invoke registered callback */
- glinki_call_link_notifier(link_notif_data, xport_ctx,
- GLINK_LINK_STATE_UP);
- }
- }while ((if_ptr = smem_list_next(if_ptr)) != NULL);
}
- } else {
- /* No remote ss is specified, invoke notifier for all remote_ss */
- for(remote_host = 0;
- remote_host < sizeof(glink_hosts_supported)/sizeof(char *);
- remote_host++) {
- /* Find the xport and give link UP notification */
- if_ptr = smem_list_first(&glink_registered_transports[remote_host]);
- if(if_ptr == NULL) {
- /* No registered xports at this time, continue with next remote_ss */
- continue;
- }
-
- if(link_notif_data->xport) {
- do {
- xport_ctx = if_ptr->glink_core_priv;
- if( 0 == strcmp(xport_ctx->xport, link_notif_data->xport) ) {
- /* Match found, break out of loop */
- break;
- }
- }while ((if_ptr = smem_list_next(if_ptr)) != NULL);
-
- if((if_ptr != NULL) && (xport_ctx->status == GLINK_XPORT_LINK_UP)) {
- /* Invoke registered callback */
- glinki_call_link_notifier(link_notif_data, xport_ctx,
- GLINK_LINK_STATE_UP);
- }
- } else {
- /* No xport has been specified, invoke notifier for all registered
- * xports */
- do {
- xport_ctx = if_ptr->glink_core_priv;
- if(xport_ctx->status == GLINK_XPORT_LINK_UP) {
- /* Invoke registered callback */
- glinki_call_link_notifier(link_notif_data, xport_ctx,
- GLINK_LINK_STATE_UP);
- }
- }while ((if_ptr = smem_list_next(if_ptr)) != NULL);
- }
- } /* end for remote_host */
- }/* end if else (link_notif_data->remote_ss) */
+ } /* end for remote_host */
} /* glinki_scan_xports_and_notify */
void glinki_scan_notif_list_and_notify
@@ -414,26 +435,17 @@
glink_link_notif_data_type *link_notif_data;
glink_core_xport_ctx_type *xport_ctx = if_ptr->glink_core_priv;
- link_notif_data = smem_list_first(&glink_link_notif_list);
-
- if(link_notif_data == NULL) {
- /* list empty */
- return;
+ for (link_notif_data = smem_list_first(&glink_link_notif_list);
+ link_notif_data != NULL;
+ link_notif_data = smem_list_next(link_notif_data))
+ {
+ if( link_notif_data->remote_ss == NULL ||
+ 0 == glink_os_string_compare( xport_ctx->remote_ss,
+ link_notif_data->remote_ss ) )
+ {
+ glinki_check_xport_and_notify(link_notif_data, xport_ctx, state);
+ }
}
-
- do {
- if(link_notif_data->remote_ss &&
- 0 == strcmp(xport_ctx->remote_ss, link_notif_data->remote_ss)) {
- /* remote_ss specified and matches */
- glinki_check_xport_and_notify(link_notif_data, xport_ctx, state);
- } else if(link_notif_data->remote_ss == NULL) {
- /* remote_ss not specified, invoke link notif for any remote_ss */
- if(link_notif_data->xport) {
- glinki_check_xport_and_notify(link_notif_data, xport_ctx, state);
- } /* if else link_notif_data->xport */
- } /* if else link_notif_data->remote_ss */
- } while ( (link_notif_data = smem_list_next(link_notif_data)) != NULL);
-
} /* glinki_scan_notif_list_and_notify */
void glinki_scan_channels_and_notify_discon
@@ -441,7 +453,7 @@
glink_transport_if_type *if_ptr
)
{
- glink_channel_ctx_type *open_ch_ctx;
+ glink_channel_ctx_type *open_ch_ctx, *dummy_open_ch_ctx;
glink_core_xport_ctx_type *xport_ctx;
ASSERT(if_ptr != NULL);
@@ -451,27 +463,46 @@
/* Find channel in the open_list */
glink_os_cs_acquire(&xport_ctx->channel_q_cs);
open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
- while(open_ch_ctx != NULL)
+ while( open_ch_ctx )
{
- /* Found channel, transition it to appropriate state based
- * on current state */
- if(open_ch_ctx->state == GLINK_CH_STATE_OPEN) {
- open_ch_ctx->state = GLINK_CH_STATE_LOCAL_OPEN;
+ glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
+ open_ch_ctx->remote_state = GLINK_REMOTE_CH_SSR_RESET;
+ glink_os_cs_release( &open_ch_ctx->ch_state_cs );
- /* Inform the client */
- open_ch_ctx->notify_state(open_ch_ctx, open_ch_ctx->priv,
- GLINK_REMOTE_DISCONNECTED);
- } else if (open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN) {
- /* Local side never opened the channel */
- /* Free channel resources */
- xport_ctx->channel_cleanup(open_ch_ctx);
+ dummy_open_ch_ctx = smem_list_next( open_ch_ctx );
- smem_list_delete(&if_ptr->glink_core_priv->open_list, open_ch_ctx);
+ switch( open_ch_ctx->local_state )
+ {
+ case GLINK_LOCAL_CH_OPENED:
+ case GLINK_LOCAL_CH_OPENING:
+ /* local channel has called open at the moment. */
+ open_ch_ctx->notify_state( open_ch_ctx,
+ open_ch_ctx->priv,
+ GLINK_REMOTE_DISCONNECTED );
+ break;
- glink_os_free(open_ch_ctx);
+ case GLINK_LOCAL_CH_CLOSING:
+ /* Case when local client already closed channel
+ * but has not received ack yet */
+ if_ptr->glink_core_if_ptr->rx_cmd_ch_close_ack( if_ptr,
+ open_ch_ctx->lcid );
+ break;
+
+ case GLINK_LOCAL_CH_CLOSED:
+ /* Channel fully closed - local, remote */
+ xport_ctx->channel_cleanup(open_ch_ctx);
+ smem_list_delete(&if_ptr->glink_core_priv->open_list, open_ch_ctx);
+ glink_os_free(open_ch_ctx);
+ break;
+
+ default:
+ /* invalid local channel state */
+ ASSERT(0);
}
- open_ch_ctx = smem_list_next(open_ch_ctx);
- }/* end while */
+
+ open_ch_ctx = dummy_open_ch_ctx;
+
+ } /* end while */
glink_os_cs_release(&xport_ctx->channel_q_cs);
}
@@ -487,15 +518,22 @@
notification followed by REMOTE_DISCONNECT */
if_ptr = smem_list_first(&glink_registered_transports[remote_host]);
- while(if_ptr != NULL) {
+ while(if_ptr != NULL)
+ {
+ /* xport is down. change the xport state */
+ glink_os_cs_acquire(&if_ptr->glink_core_priv->status_cs);
+ if_ptr->glink_core_priv->status = GLINK_XPORT_REGISTERED;
+
+ /* Let the xport know about ssr */
+ if_ptr->ssr( if_ptr );
+
/* Invoke LINK_DOWN notification for any registered notifiers */
glinki_scan_notif_list_and_notify(if_ptr, GLINK_LINK_STATE_DOWN);
/* Invoke REMOTE_DISCONNECT for all channels associated with if_ptr */
glinki_scan_channels_and_notify_discon(if_ptr);
- /* Let the xport know about ssr */
- if_ptr->ssr(if_ptr);
+ glink_os_cs_release(&if_ptr->glink_core_priv->status_cs);
if_ptr = smem_list_next(if_ptr);
}
@@ -597,32 +635,19 @@
return GLINK_STATUS_INVALID_PARAM;;
}
+ remote_host = glinki_find_remote_host(cfg->remote_ss);
- /* Allocate/fill out the GLink Core interface structure */
- {
- glink_core_if_type *core_if = glink_os_calloc(sizeof(glink_core_if_type));
- if(core_if == NULL) {
- GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, cfg->name,
- cfg->remote_ss, GLINK_STATUS_OUT_OF_RESOURCES);
- return GLINK_STATUS_OUT_OF_RESOURCES;
- }
- core_if->link_up = glink_link_up;
- core_if->rx_cmd_version = glink_rx_cmd_version;
- core_if->rx_cmd_version_ack = glink_rx_cmd_version_ack;
- core_if->rx_cmd_ch_remote_open = glink_rx_cmd_ch_remote_open;
- core_if->rx_cmd_ch_open_ack = glink_rx_cmd_ch_open_ack;
- core_if->rx_cmd_ch_close_ack = glink_rx_cmd_ch_close_ack;
- core_if->rx_cmd_ch_remote_close = glink_rx_cmd_ch_remote_close;
- core_if->ch_state_local_trans = glink_ch_state_local_trans;
- core_if->rx_put_pkt_ctx = glink_rx_put_pkt_ctx;
- core_if->rx_cmd_remote_sigs = glink_rx_cmd_remote_sigs;
- core_if->tx_resume = glink_tx_resume;
- core_if->set_core_version = glink_set_core_version;
+ if(remote_host == GLINK_NUM_HOSTS ) {
+ /* Unknown transport name trying to register with GLink */
+ GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, cfg->name,
+ cfg->remote_ss, GLINK_STATUS_INVALID_PARAM);
- /* Set the glink_core_if_ptr to point to the allocated structure */
- if_ptr->glink_core_if_ptr = core_if;
+ return GLINK_STATUS_INVALID_PARAM;
}
+ /* Set the glink_core_if_ptr to point to the default interface */
+ if_ptr->glink_core_if_ptr = glink_core_get_default_interface();
+
/* Allocate/fill out the GLink private context data */
{
xport_ctx = glink_os_calloc(sizeof(glink_core_xport_ctx_type));
@@ -636,16 +661,15 @@
return GLINK_STATUS_OUT_OF_RESOURCES;
}
- glink_os_string_copy(xport_ctx->xport, cfg->name,
- sizeof(xport_ctx->xport));
- glink_os_string_copy(xport_ctx->remote_ss, cfg->remote_ss,
- sizeof(xport_ctx->xport));
+ xport_ctx->xport = cfg->name;
+ xport_ctx->remote_ss = cfg->remote_ss;
xport_ctx->free_lcid = 1; /* lcid 0 is reserved for invalid channel */
xport_ctx->version_array = cfg->version;
xport_ctx->version_indx = cfg->version_count - 1;
glink_os_cs_init(&xport_ctx->channel_q_cs);
glink_os_cs_init(&xport_ctx->liid_cs);
+ glink_os_cs_init(&xport_ctx->status_cs);
glink_os_cs_acquire(&xport_ctx->channel_q_cs);
smem_list_init(&xport_ctx->open_list);
@@ -657,15 +681,6 @@
}
/* Push the transport interface into appropriate queue */
- remote_host = glinki_find_remote_host(cfg->remote_ss);
-
- if(remote_host == GLINK_NUM_HOSTS ) {
- /* Unknown transport name trying to register with GLink */
- GLINK_LOG_EVENT(GLINK_EVENT_REGISTER_XPORT, NULL, xport_ctx->xport,
- xport_ctx->remote_ss, GLINK_STATUS_INVALID_PARAM);
-
- return GLINK_STATUS_INVALID_PARAM;
- }
glink_os_cs_acquire(glink_transport_q_cs);
smem_list_append(&glink_registered_transports[remote_host], if_ptr);
glink_os_cs_release(glink_transport_q_cs);
@@ -732,6 +747,8 @@
/* Append the request to the list for link UP/DOWN notifications */
smem_list_append(&glink_link_notif_list, link_notif_data);
+ link_id->handle = (glink_link_handle_type)link_notif_data;
+
/* Scan the list of available transport to see if this link is already up */
glinki_scan_xports_and_notify(link_notif_data);
@@ -755,7 +772,12 @@
glink_link_handle_type handle
)
{
- ASSERT(handle);
+ /* check if glink handle is NULL and return appropriate
+ return code */
+ if(handle == NULL)
+ {
+ return GLINK_STATUS_INVALID_PARAM;
+ }
smem_list_delete(&glink_link_notif_list,
(glink_link_notif_data_type*)handle);
@@ -789,18 +811,17 @@
while(if_ptr != NULL)
{
+ xport_ctx = if_ptr->glink_core_priv;
/* check if priority of current transport is higher than
* current highest priority (0 = highest priority)
*/
- xport_ctx = if_ptr->glink_core_priv;
if( xport_ctx->status == GLINK_XPORT_LINK_UP &&
if_ptr->glink_priority < priority )
{
best_if_ptr = if_ptr;
priority = if_ptr->glink_priority;
}
-
- if_ptr = smem_list_next(if_ptr);
+ if_ptr = smem_list_next(if_ptr);
} /* end while() */
return best_if_ptr;
@@ -924,14 +945,15 @@
ch_ctx,
&allocated_ch_ctx,
TRUE,
- TRUE,
if_ptr->glink_priority );
- if (status == GLINK_STATUS_SUCCESS) {
+ if( status == GLINK_STATUS_SUCCESS )
+ {
/* Set the handle and return */
*handle = allocated_ch_ctx;
}
- else {
+ else
+ {
*handle = NULL;
}
@@ -967,37 +989,61 @@
)
{
glink_err_type status;
- glink_core_xport_ctx_type *xport_ctx = handle->if_ptr->glink_core_priv;
- glink_ch_state_type ch_state;
+ glink_core_xport_ctx_type *xport_ctx = NULL;
- if(handle == NULL) {
+ if(handle == NULL)
+ {
GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, NULL, "",
"", GLINK_STATUS_INVALID_PARAM);
return GLINK_STATUS_INVALID_PARAM;
}
- ch_state = handle->state;
+ /* get xport context after NULL check */
+ xport_ctx = handle->if_ptr->glink_core_priv;
- /* Check to see if channel is in open/opening state */
- if (ch_state != GLINK_CH_STATE_OPEN &&
- ch_state != GLINK_CH_STATE_LOCAL_OPEN &&
- ch_state != GLINK_CH_STATE_LOCAL_OPEN_REMOTE_CLOSE &&
- ch_state != GLINK_CH_STATE_REMOTE_OPEN)
+ /* grab lock to change/check channel state atomically */
+ glink_os_cs_acquire( &handle->ch_state_cs );
+
+ /* Check to see if closed called again for same channel */
+ if ( handle->local_state == GLINK_LOCAL_CH_CLOSING ||
+ handle->local_state == GLINK_LOCAL_CH_CLOSED )
{
GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, handle->name, xport_ctx->xport,
- xport_ctx->remote_ss, ch_state);
+ xport_ctx->remote_ss, handle->local_state);
+
+ glink_os_cs_release(&handle->ch_state_cs);
+
return GLINK_STATUS_FAILURE;
}
- /* Transition to closing */
- //handle->state = GLINK_CH_STATE_CLOSING;
+ handle->local_state = GLINK_LOCAL_CH_CLOSING;
- /* Send CLOSE cmd to the transport interface */
- status = handle->if_ptr->tx_cmd_ch_close(handle->if_ptr, handle->lcid);
- GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, handle->name, xport_ctx->xport,
- xport_ctx->remote_ss, status);
+ glink_os_cs_acquire( &xport_ctx->status_cs );
+
+ if( GLINK_XPORT_LINK_UP != xport_ctx->status ||
+ handle->remote_state == GLINK_REMOTE_CH_SSR_RESET )
+ {
+ /* SSR happened on remote-SS. Fake close_ack from here */
+ glink_os_cs_release( &xport_ctx->status_cs );
+ glink_os_cs_release( &handle->ch_state_cs );
+
+ handle->if_ptr->glink_core_if_ptr->rx_cmd_ch_close_ack( handle->if_ptr,
+ handle->lcid );
+
+ status = GLINK_STATUS_SUCCESS;
+ }
+ else
+ {
+ glink_os_cs_release( &xport_ctx->status_cs );
+ glink_os_cs_release( &handle->ch_state_cs );
+
+ status = handle->if_ptr->tx_cmd_ch_close(handle->if_ptr, handle->lcid);
+
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, handle->name, xport_ctx->xport,
+ xport_ctx->remote_ss, status);
+ }
+
return status;
-
}
/**
@@ -1066,9 +1112,10 @@
)
{
glink_err_type status;
- glink_core_tx_pkt_type pctx;
+ glink_core_tx_pkt_type *pctx;
boolean req_intent = options & GLINK_TX_REQ_INTENT;
- glink_core_xport_ctx_type *xport_ctx = handle->if_ptr->glink_core_priv;
+
+ glink_core_xport_ctx_type *xport_ctx;
/* Input validation */
if(handle == NULL || iovec == NULL || size == 0 ||
@@ -1078,42 +1125,51 @@
return GLINK_STATUS_INVALID_PARAM;
}
- /* Make sure channel is in OPEN state */
- if(handle->state != GLINK_CH_STATE_OPEN )
+ xport_ctx = handle->if_ptr->glink_core_priv;
+
+ if( !glink_is_channel_fully_opened( handle, xport_ctx ) )
+ {
+ GLINK_LOG_EVENT( GLINK_EVENT_CH_TX,
+ handle->name,
+ xport_ctx->xport,
+ xport_ctx->remote_ss,
+ GLINK_STATUS_FAILURE );
+
+ return GLINK_STATUS_FAILURE;
+ }
+
+ pctx = glink_os_calloc( sizeof( glink_core_tx_pkt_type ) );
+
+ if (pctx == NULL)
{
GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE, handle->name, xport_ctx->xport,
- xport_ctx->remote_ss, GLINK_STATUS_FAILURE);
- return GLINK_STATUS_FAILURE;
+ xport_ctx->remote_ss, GLINK_STATUS_OUT_OF_RESOURCES);
+ return GLINK_STATUS_OUT_OF_RESOURCES;
}
/* Protect the entire tx operation under a lock as a client may call
tx in different thread context */
glink_os_cs_acquire(&handle->tx_cs);
- pctx.pkt_priv = pkt_priv;
- pctx.size = size;
- pctx.size_remaining = size;
- pctx.vprovider = vprovider;
- pctx.pprovider = pprovider;
+ pctx->pkt_priv = pkt_priv;
+ pctx->size = size;
+ pctx->size_remaining = size;
+ pctx->vprovider = vprovider;
+ pctx->pprovider = pprovider;
if (vprovider == &glink_dummy_tx_vprovider)
{
- pctx.data = (void*)iovec;
- pctx.iovec = &pctx;
+ pctx->data = (void*)iovec;
+ pctx->iovec = pctx;
}
else
{
- pctx.data = (void*)iovec;
- pctx.iovec = iovec;
+ pctx->data = (void*)iovec;
+ pctx->iovec = iovec;
}
- status = xport_ctx->use_rm_intent(handle, &pctx, req_intent);
- /* Call transport API to transmit data */
- while (pctx.size_remaining != 0 && status == GLINK_STATUS_SUCCESS)
- {
- status = handle->if_ptr->tx(handle->if_ptr, handle->lcid, &pctx);
- }
+ status = xport_ctx->channel_submit_pkt(handle, pctx, req_intent);
GLINK_LOG_EVENT(GLINK_EVENT_CH_TX, handle->name, xport_ctx->xport,
xport_ctx->remote_ss, status);
@@ -1159,11 +1215,14 @@
return GLINK_STATUS_FAILURE;
}
- /* Make sure channel is in OPEN state */
- if(handle->state != GLINK_CH_STATE_OPEN)
+ if( !glink_is_channel_fully_opened( handle, xport_ctx ) )
{
- GLINK_LOG_EVENT(GLINK_EVENT_CH_Q_RX_INTENT, handle->name, xport_ctx->xport,
- xport_ctx->remote_ss, GLINK_STATUS_FAILURE);
+ GLINK_LOG_EVENT( GLINK_EVENT_CH_Q_RX_INTENT,
+ handle->name,
+ xport_ctx->xport,
+ xport_ctx->remote_ss,
+ GLINK_STATUS_FAILURE );
+
return GLINK_STATUS_FAILURE;
}
@@ -1271,11 +1330,14 @@
return GLINK_STATUS_SUCCESS;
}
- /* Make sure channel is in OPEN state */
- if(handle->state != GLINK_CH_STATE_OPEN)
+ if( !glink_is_channel_fully_opened( handle, xport_ctx ) )
{
- GLINK_LOG_EVENT(GLINK_EVENT_CH_RX_DONE, handle->name, xport_ctx->xport,
- xport_ctx->remote_ss, GLINK_STATUS_FAILURE);
+ GLINK_LOG_EVENT( GLINK_EVENT_CH_RX_DONE,
+ handle->name,
+ xport_ctx->xport,
+ xport_ctx->remote_ss,
+ GLINK_STATUS_FAILURE );
+
return GLINK_STATUS_FAILURE;
}
@@ -1353,7 +1415,7 @@
uint32 sig_value
)
{
- glink_core_xport_ctx_type *xport_ctx = handle->if_ptr->glink_core_priv;
+ glink_core_xport_ctx_type *xport_ctx;
glink_err_type status;
/* Input validation */
@@ -1363,11 +1425,16 @@
return GLINK_STATUS_INVALID_PARAM;
}
- /* Make sure channel is in OPEN state */
- if(handle->state != GLINK_CH_STATE_OPEN)
+ xport_ctx = handle->if_ptr->glink_core_priv;
+
+ if( !glink_is_channel_fully_opened( handle, xport_ctx ) )
{
- GLINK_LOG_EVENT(GLINK_EVENT_CH_SIG_SET, handle->name, xport_ctx->xport,
- xport_ctx->remote_ss, GLINK_STATUS_FAILURE);
+ GLINK_LOG_EVENT( GLINK_EVENT_CH_SIG_SET,
+ handle->name,
+ xport_ctx->xport,
+ xport_ctx->remote_ss,
+ GLINK_STATUS_FAILURE );
+
return GLINK_STATUS_FAILURE;
}
diff --git a/platform/msm_shared/glink/glink_core_if.c b/platform/msm_shared/glink/glink_core_if.c
index 3c66369..5e3abd5 100644
--- a/platform/msm_shared/glink/glink_core_if.c
+++ b/platform/msm_shared/glink/glink_core_if.c
@@ -34,28 +34,26 @@
#include "glink_os_utils.h"
#include "glink.h"
#include "glink_internal.h"
-#include "glink_core_if.h"
#include "smem_list.h"
#include "glink_channel_migration.h"
-
#define FEATURE_CH_MIGRATION_FREE
-void glinki_scan_notif_list_and_notify
+/*===========================================================================
+ GLOBAL FUNCTION DECLARATIONS
+==========================================================================*/
+extern void glinki_scan_notif_list_and_notify
(
glink_transport_if_type *if_ptr,
glink_link_state_type state
);
-/*===========================================================================
- GLOBAL DATA DECLARATIONS
-===========================================================================*/
/*===========================================================================
LOCAL FUNCTION DEFINITIONS
===========================================================================*/
/*===========================================================================
-FUNCTION glink_process_negotiation_complete
+ FUNCTION glink_process_negotiation_complete
===========================================================================*/
/**
@@ -79,20 +77,26 @@
/*=========================================================================*/
static void glink_process_negotiation_complete
(
- glink_core_xport_ctx_type *xport_ctx,
glink_transport_if_type *if_ptr,
uint32 version,
uint32 features
)
{
+ glink_core_xport_ctx_type *xport_ctx = if_ptr->glink_core_priv;
/* Version/Feautre can be negotiated both in ver_req and ver_ack
* Only go through process once in case they are negotiated
* in ver_req before receiving ver_ack */
+
+ glink_os_cs_acquire( &xport_ctx->status_cs );
+
if( xport_ctx->status == GLINK_XPORT_LINK_UP )
{
+ glink_os_cs_release( &xport_ctx->status_cs );
return;
}
+ glink_os_cs_release(&if_ptr->glink_core_priv->status_cs);
+
/* setup core based on transport capabilities*/
xport_ctx->xport_capabilities = if_ptr->set_version( if_ptr,
version,
@@ -100,38 +104,70 @@
glink_core_setup(if_ptr);
/* transport is ready to open channels */
+ glink_os_cs_acquire( &xport_ctx->status_cs );
if_ptr->glink_core_priv->status = GLINK_XPORT_LINK_UP;
+ glink_os_cs_release(&if_ptr->glink_core_priv->status_cs);
/* Scan the notification list to check is we have to let any registered
- * clients know that link came online */
+ * clients know that link came online */
glinki_scan_notif_list_and_notify(if_ptr, GLINK_LINK_STATE_UP);
}
-static void glink_dummy_ch_migration_notification_cb
+
+/*===========================================================================
+ FUNCTION glink_clean_channel_ctx
+===========================================================================*/
+/**
+
+ This is called when channel is fully closed
+ Clean up the context and redeem channel id if possible
+
+ @param[in] xport_ctx transport context
+ @param[in] channel_ctx channel context
+
+
+ @return None
+ @sideeffects None.
+ @dependencies This function needs to be called in safe context
+ which is critical sections locked - channel_q_cs
+*/
+/*=========================================================================*/
+static void glink_clean_channel_ctx
(
- glink_handle_type handle,
- const void *priv,
- glink_channel_event_type event
+ glink_core_xport_ctx_type *xport_ctx,
+ glink_channel_ctx_type *channel_ctx
)
{
+ xport_ctx->channel_cleanup( channel_ctx );
+
+ if( channel_ctx->lcid == ( xport_ctx->free_lcid - 1 ) )
+ {
+ /* If channel being closed is the last opened channel
+ re-use the lcid of this channel for any new channels */
+ xport_ctx->free_lcid--;
+ }
+
+ smem_list_delete(&xport_ctx->open_list, channel_ctx);
}
/*===========================================================================
EXTERNAL FUNCTION DEFINITIONS
===========================================================================*/
/*===========================================================================
-FUNCTION glink_link_up
-
-DESCRIPTION Indicates that transport is now ready to start negotiation
- using the v0 configuration
-
-ARGUMENTS *if_ptr Pointer to interface instance; must be unique
- for each edge
-
-RETURN VALUE None.
-
-SIDE EFFECTS None
+ FUNCTION glink_link_up
===========================================================================*/
+/**
+ Indicates that transport is now ready to start negotiation
+ using the v0 configuration
+
+ @param[in] if_ptr Pointer to interface instance; must be unique
+ for each edge
+
+ @return None
+ @sideeffects None.
+ @dependencies None.
+*/
+/*=========================================================================*/
void glink_link_up
(
glink_transport_if_type *if_ptr
@@ -147,7 +183,9 @@
version_array = xport_ctx->version_array;
/* Update the transport state */
+ glink_os_cs_acquire(&if_ptr->glink_core_priv->status_cs);
if_ptr->glink_core_priv->status = GLINK_XPORT_NEGOTIATING;
+ glink_os_cs_release(&if_ptr->glink_core_priv->status_cs);
/* Start the negtiation */
if_ptr->tx_cmd_version(if_ptr, version_array->version,
@@ -207,8 +245,7 @@
/* send version ack before allowing to open channels */
if_ptr->tx_cmd_version_ack(if_ptr, version, features);
- glink_process_negotiation_complete( xport_ctx, if_ptr,
- version, features );
+ glink_process_negotiation_complete( if_ptr, version, features );
return;
}
else
@@ -277,8 +314,7 @@
}
else
{
- glink_process_negotiation_complete( xport_ctx, if_ptr,
- version, features );
+ glink_process_negotiation_complete( if_ptr, version, features );
}
}
else
@@ -323,64 +359,22 @@
glink_xport_priority priority
)
{
- glink_channel_ctx_type *remote_ch_ctx;
- glink_channel_ctx_type *allocated_ch_ctx;
+ glink_channel_ctx_type *remote_ch_ctx = NULL;
+ glink_channel_ctx_type *allocated_ch_ctx;
+
+ glink_xport_priority negotiated_xport_priority;
glink_core_xport_ctx_type *xport_ctx;
- glink_err_type status;
- glink_xport_priority negotiated_prio;
- boolean migration_state = TRUE;
+ glink_err_type status;
- ASSERT(if_ptr != NULL);
- ASSERT(name != NULL);
-
-#ifndef FEATURE_CH_MIGRATION_FREE
- glink_transport_if_type *present_if_ptr = NULL;
- boolean channel_exist = FALSE;
- glink_channel_ctx_type *present_ch_ctx = NULL;
- /* search if channel with given name exists locally */
- channel_exist = glinki_local_channel_exists(if_ptr, &present_if_ptr, name, &present_ch_ctx, TRUE);
-
- /* start channel migration negotiation only if channel exists on local side
- * for negotiation AND channel is willing to migrate */
- if(channel_exist &&
- (present_ch_ctx->ch_open_options & GLINK_OPT_INITIAL_XPORT))
- {
- /* channel exists on one of the xports for given remote ss */
- current_prio = present_ch_ctx->req_if_ptr->glink_priority;
- negotiated_prio = glinki_negotiate_ch_migration(priority, current_prio);
-
- /* if current channel is open in same xport as negotiated xport
- * local side wont migrate. Set migration flag to FALSE */
- if(negotiated_prio == present_if_ptr->glink_priority)
- {
- migration_state = FALSE;
- }
- }
- else if(channel_exist)
- {
- /* channel exists but channel does not want to be moved to another xport.
- channel is set in stone */
- negotiated_prio = present_if_ptr->glink_priority;
- migration_state = FALSE;
- }
- else
- {
- /* channel does not exist on local side as yet
- * return negotiated prio as current xport prio on which
- * remote open request is received */
- negotiated_prio = if_ptr->glink_priority;
- migration_state = FALSE;
- }
-#else
- negotiated_prio = if_ptr->glink_priority;
- migration_state = FALSE;
-#endif
+ ASSERT( if_ptr != NULL );
+ ASSERT( name != NULL );
xport_ctx = if_ptr->glink_core_priv;
/* Allocate and initialize channel info structure */
- remote_ch_ctx = glink_os_calloc(sizeof(glink_channel_ctx_type));
- if(remote_ch_ctx == NULL) {
+ remote_ch_ctx = glink_os_calloc( sizeof( glink_channel_ctx_type ) );
+ if(remote_ch_ctx == NULL)
+ {
GLINK_LOG_EVENT(GLINK_EVENT_RM_CH_OPEN, name, xport_ctx->xport,
xport_ctx->remote_ss, GLINK_STATUS_OUT_OF_RESOURCES);
ASSERT(0);
@@ -390,61 +384,113 @@
glink_os_string_copy(remote_ch_ctx->name, name, sizeof(remote_ch_ctx->name));
remote_ch_ctx->rcid = rcid;
- status = glinki_add_ch_to_xport(if_ptr, NULL, remote_ch_ctx,
- &allocated_ch_ctx, FALSE,
- migration_state, negotiated_prio);
- ASSERT(status == GLINK_STATUS_SUCCESS);
+#ifndef FEATURE_CH_MIGRATION_FREE
+ glink_channel_ctx_type *present_ch_ctx = NULL;
+ glink_transport_if_type *negotiated_xport;
+ glink_channel_ctx_type *dummy_ch_ctx;
- GLINK_LOG_EVENT(GLINK_EVENT_RM_CH_OPEN, name, xport_ctx->xport,
+ /* search if channel with given name exists locally */
+
+ glink_os_cs_acquire( &xport_ctx->channel_q_cs );
+ present_ch_ctx = glinki_local_channel_exists( if_ptr, name );
+
+ if( !present_ch_ctx )
+ {
+ // channel doesn't exists yet and migration will not happen here
+ status = glinki_add_ch_to_xport( if_ptr,
+ if_ptr,
+ remote_ch_ctx,
+ &allocated_ch_ctx,
+ FALSE,
+ if_ptr->glink_priority );
+ ASSERT(status == GLINK_STATUS_SUCCESS);
+
+ GLINK_LOG_EVENT(GLINK_EVENT_RM_CH_OPEN, name, xport_ctx->xport,
xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
-#ifndef FEATURE_CH_MIGRATION_FREE
-
- /* We are done with channel migration negotiation at this stage
- * Tag all channels with given name on xports other than negotiated
- * xport for deletion */
- glinki_tag_ch_for_deletion(if_ptr, name, negotiated_prio);
-
- if(migration_state == TRUE)
- {
- glink_channel_ctx_type *new_ch_ctx;
-
- /* create a new channel context as current channel will be migrated */
- new_ch_ctx = (glink_channel_ctx_type *)
- glink_os_calloc(sizeof(glink_channel_ctx_type));
-
- /* Fill in the channel info structure */
- new_ch_ctx->req_if_ptr =
- glinki_get_xport_from_prio(negotiated_prio,
- if_ptr->glink_core_priv->remote_ss);
- glink_os_string_copy(new_ch_ctx->name, present_ch_ctx->name,
- sizeof(present_ch_ctx->name));
- new_ch_ctx->priv = present_ch_ctx->priv;
- new_ch_ctx->notify_rx = present_ch_ctx->notify_rx;
- new_ch_ctx->notify_rxv = present_ch_ctx->notify_rxv;
- new_ch_ctx->notify_tx_done = present_ch_ctx->notify_tx_done;
- new_ch_ctx->notify_state = present_ch_ctx->notify_state;
- new_ch_ctx->notify_rx_intent_req = present_ch_ctx->notify_rx_intent_req;
- new_ch_ctx->notify_rx_intent = present_ch_ctx->notify_rx_intent;
- new_ch_ctx->notify_rx_sigs = present_ch_ctx->notify_rx_sigs;
- new_ch_ctx->ch_open_options = present_ch_ctx->ch_open_options;
-
-// glink_os_cs_init(&new_ch_ctx->intent_q_cs);
-
- /* close current channel */
- present_ch_ctx->notify_state = glink_dummy_ch_migration_notification_cb;
- if_ptr->tx_cmd_ch_close( if_ptr, present_ch_ctx->lcid );
-
- /* add new channel context on negotiated xport */
- glinki_add_ch_to_xport(new_ch_ctx->req_if_ptr,
- new_ch_ctx->req_if_ptr,
- new_ch_ctx,
- &allocated_ch_ctx,
- TRUE,
- TRUE,
- new_ch_ctx->req_if_ptr->glink_priority);
+ glink_os_cs_release( &xport_ctx->channel_q_cs );
+ return;
}
+
+ glink_os_cs_release( &xport_ctx->channel_q_cs );
+
+ present_ch_ctx->rcid = rcid;
+
+ if( present_ch_ctx->tag_ch_for_close )
+ {
+ // Migration already started.
+ GLINK_LOG_EVENT(GLINK_EVENT_CH_MIGRATION_IN_PROGRESS, name, xport_ctx->xport,
+ xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
+
+ return;
+ }
+
+ /* Negotiate the priority for migration if needed */
+ if( priority < present_ch_ctx->req_if_ptr->glink_priority )
+ {
+ negotiated_xport_priority = present_ch_ctx->req_if_ptr->glink_priority;
+ }
+ else
+ {
+ negotiated_xport_priority = priority;
+ }
+
+ negotiated_xport = glinki_get_xport_from_prio( negotiated_xport_priority,
+ xport_ctx->remote_ss );
+
+ if( if_ptr == negotiated_xport )
+ {
+ /* Current transport is best one. No need to migrate */
+
+ status = glinki_add_ch_to_xport( if_ptr,
+ if_ptr,
+ remote_ch_ctx,
+ &allocated_ch_ctx,
+ FALSE,
+ negotiated_xport_priority );
+
+ ASSERT(status == GLINK_STATUS_SUCCESS);
+ GLINK_LOG_EVENT( GLINK_EVENT_CH_NO_MIGRATION, name, xport_ctx->xport,
+ xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
+
+ return;
+ }
+
+ /* Need to migrate to new transport */
+ if_ptr->tx_cmd_ch_remote_open_ack( if_ptr,
+ rcid,
+ negotiated_xport_priority );
+
+ glink_create_dummy_ch_ctx( &dummy_ch_ctx, present_ch_ctx );
+ glink_close_dummy_ch_for_migration( if_ptr, dummy_ch_ctx );
+ glink_init_ch_migrate_candidate( present_ch_ctx );
+
+ status = glinki_add_ch_to_xport( negotiated_xport,
+ negotiated_xport,
+ present_ch_ctx,
+ &allocated_ch_ctx,
+ TRUE,
+ negotiated_xport_priority );
+
+ ASSERT( status == GLINK_STATUS_SUCCESS );
+
+ glink_os_free( remote_ch_ctx );
+
+#else
+ negotiated_xport_priority = if_ptr->glink_priority;
+
+ status = glinki_add_ch_to_xport( if_ptr,
+ NULL,
+ remote_ch_ctx,
+ &allocated_ch_ctx,
+ FALSE,
+ negotiated_xport_priority );
+
+ ASSERT(status == GLINK_STATUS_SUCCESS);
#endif
+
+ GLINK_LOG_EVENT(GLINK_EVENT_RM_CH_OPEN, name, xport_ctx->xport,
+ xport_ctx->remote_ss, GLINK_STATUS_SUCCESS);
}
/*===========================================================================
@@ -467,11 +513,11 @@
void glink_rx_cmd_ch_open_ack
(
glink_transport_if_type *if_ptr,
- uint32 lcid,
- glink_xport_priority migrated_ch_prio
+ uint32 lcid,
+ glink_xport_priority migrated_ch_prio
)
{
- glink_channel_ctx_type *open_ch_ctx;
+ glink_channel_ctx_type *open_ch_ctx;
glink_core_xport_ctx_type *xport_ctx;
ASSERT(if_ptr != NULL);
@@ -480,121 +526,92 @@
/* Move to closed state. Implies we clean up the channel from the
* open list */
-
+ glink_os_cs_acquire(&xport_ctx->channel_q_cs);
/* Find channel in the open_list */
open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
while(open_ch_ctx != NULL)
{
- if(open_ch_ctx->lcid == lcid) {
+ if(open_ch_ctx->lcid == lcid)
+ {
#ifndef FEATURE_CH_MIGRATION_FREE
- glink_transport_if_type *present_if_ptr = NULL;
- glink_channel_ctx_type *present_ch_ctx = NULL;
- boolean channel_exist;
- /* find the channel in all xport list */
- channel_exist = glinki_local_channel_exists(if_ptr,
- &present_if_ptr,
- open_ch_ctx->name,
- &present_ch_ctx,
- FALSE);
+ glink_transport_if_type *negotiated_xport = NULL;
+ negotiated_xport = glinki_get_xport_from_prio( migrated_ch_prio,
+ xport_ctx->remote_ss );
- if(if_ptr->glink_priority == migrated_ch_prio && !channel_exist)
+ if( negotiated_xport != if_ptr &&
+ !open_ch_ctx->tag_ch_for_close &&
+ ( open_ch_ctx->ch_open_options & GLINK_OPT_INITIAL_XPORT ) )
{
- /* only local side has opened the channel. Remote side has not come up yet
- * which implies negotiation did not take place on remote side */
- /* DO NOTHING */
- }
- else if(if_ptr->glink_priority == migrated_ch_prio)
- {
- /* remote channel exists. channel migration negotiation happened
- * on remote side and negotitated xport is same as current xport */
- if(present_ch_ctx->ref_count == 1)
- {
- /* remote channel is present on different xport than negotiated one.
- * remote side will migrate its channel to negotiated xport */
- /* DO NOTHING */
- }
- else if(present_ch_ctx->ref_count == 2)
- {
- /* remote channel is open on same xport as current xport.
- * change channel state to GLINK_CH_STATE_OPEN and notify client */
- open_ch_ctx->state = GLINK_CH_STATE_OPEN;
- open_ch_ctx->notify_state(open_ch_ctx, open_ch_ctx->priv,
- GLINK_CONNECTED);
- }
- else
- {
- /* something went wrong in updating ref_count of channel */
- ASSERT(0);
- }
+ glink_channel_ctx_type *dummy_ch_ctx;
+ glink_err_type status;
+
+ glink_create_dummy_ch_ctx( &dummy_ch_ctx, open_ch_ctx );
+ glink_close_dummy_ch_for_migration( if_ptr, dummy_ch_ctx );
+
+ glink_init_ch_migrate_candidate( open_ch_ctx );
+ dummy_ch_ctx = NULL;
+
+ status = glinki_add_ch_to_xport( negotiated_xport,
+ negotiated_xport,
+ open_ch_ctx,
+ &dummy_ch_ctx,
+ TRUE,
+ negotiated_xport->glink_priority );
+
+ ASSERT( status == GLINK_STATUS_SUCCESS );
}
else
{
+ glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
- /* migrated xport priority <> current xport priority */
- /* check if remote channel is opened on negotiated xport already */
- if(migrated_ch_prio == present_if_ptr->glink_priority &&
- (open_ch_ctx->ch_open_options & GLINK_OPT_INITIAL_XPORT))
- {
- /* remote channel is already on negotiated xport. remote channel
- * will not migrate. Local side should migrate */
-
- glink_channel_ctx_type *new_ch_ctx =
- (glink_channel_ctx_type *)glink_os_calloc(
- sizeof(glink_channel_ctx_type));
-
- /* Fill in the channel info structure */
- glink_os_string_copy(new_ch_ctx->name,
- open_ch_ctx->name,
- sizeof(open_ch_ctx->name));
- new_ch_ctx->priv = open_ch_ctx->priv;
- new_ch_ctx->notify_rx = open_ch_ctx->notify_rx;
- new_ch_ctx->notify_rxv = open_ch_ctx->notify_rxv;
- new_ch_ctx->notify_tx_done = open_ch_ctx->notify_tx_done;
- new_ch_ctx->notify_state = open_ch_ctx->notify_state;
- new_ch_ctx->notify_rx_intent_req =
- open_ch_ctx->notify_rx_intent_req;
- new_ch_ctx->notify_rx_intent = open_ch_ctx->notify_rx_intent;
- new_ch_ctx->notify_rx_sigs = open_ch_ctx->notify_rx_sigs;
- new_ch_ctx->ch_open_options = open_ch_ctx->ch_open_options;
-
- present_ch_ctx->notify_state = glink_dummy_ch_migration_notification_cb;
- if_ptr->tx_cmd_ch_close( if_ptr, present_ch_ctx->lcid );
-
- /* migrate to negotiated xport */
- glinki_add_ch_to_xport(present_if_ptr,
- present_if_ptr,
- new_ch_ctx,
- NULL,
- TRUE,
- TRUE,
- present_if_ptr->glink_priority);
- }
- else
- {
- /* Either our transport is "set in stone" OR */
- /* remote side will migrate to negotiated xport and will call
- * remote open on this side which will cause channel migration
- * negotiation and this side will ultimately migrate */
- /* DO NOTHING */
- }
- }
-#else
- if(open_ch_ctx->ref_count == 2)
+ if( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSING )
{
- /* remote channel is open on same xport as current xport.
- * change channel state to GLINK_CH_STATE_OPEN and notify client */
- open_ch_ctx->state = GLINK_CH_STATE_OPEN;
- open_ch_ctx->notify_state(open_ch_ctx, open_ch_ctx->priv,
- GLINK_CONNECTED);
+ /* Local client called glink_close
+ * before local channel is fully opened */
+ glink_os_cs_release( &open_ch_ctx->ch_state_cs );
+ glink_os_cs_release( &xport_ctx->channel_q_cs );
+ return;
}
+
+ open_ch_ctx->local_state = GLINK_LOCAL_CH_OPENED;
+
+ if( open_ch_ctx->remote_state == GLINK_REMOTE_CH_OPENED )
+ {
+ glink_os_cs_release( &open_ch_ctx->ch_state_cs );
+ open_ch_ctx->notify_state( open_ch_ctx,
+ open_ch_ctx->priv,
+ GLINK_CONNECTED );
+ }
+ else
+ {
+ glink_os_cs_release( &open_ch_ctx->ch_state_cs );
+ }
+ }
+
+#else
+ /* This is same code as above. once core capability code is done copy
+ * issue should be resolved */
+ glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
+ open_ch_ctx->local_state = GLINK_LOCAL_CH_OPENED;
+ if( open_ch_ctx->remote_state == GLINK_REMOTE_CH_OPENED )
+ {
+ /* remote channel is open on same xport as current xport.
+ * change channel state to GLINK_CH_STATE_OPEN and notify client */
+ glink_os_cs_release( &open_ch_ctx->ch_state_cs );
+ open_ch_ctx->notify_state( open_ch_ctx,
+ open_ch_ctx->priv,
+ GLINK_CONNECTED);
+ }
#endif
GLINK_LOG_EVENT(GLINK_EVENT_CH_OPEN_ACK, open_ch_ctx->name,
xport_ctx->xport, xport_ctx->remote_ss, lcid);
+ glink_os_cs_release(&xport_ctx->channel_q_cs);
return;
}
open_ch_ctx = smem_list_next(open_ch_ctx);
}
+ glink_os_cs_release(&xport_ctx->channel_q_cs);
/* We are here in case we could not find the channel in the open list. */
ASSERT(0);
}
@@ -632,55 +649,49 @@
/* Find channel in the open_list */
glink_os_cs_acquire(&xport_ctx->channel_q_cs);
- open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
- while(open_ch_ctx != NULL)
+ open_ch_ctx = smem_list_first(&xport_ctx->open_list);
+ while( open_ch_ctx )
{
- if(open_ch_ctx->lcid == lcid) {
+ if( open_ch_ctx->lcid == lcid )
+ {
/* Found channel */
- open_ch_ctx->ref_count--;
+ glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
+
+
GLINK_LOG_EVENT(GLINK_EVENT_CH_CLOSE_ACK, open_ch_ctx->name,
xport_ctx->xport, xport_ctx->remote_ss, lcid);
- /* Transition state */
- if(open_ch_ctx->state == GLINK_CH_STATE_OPEN) {
- /* this side initiated close procedure */
- open_ch_ctx->state = GLINK_CH_STATE_REMOTE_OPEN_LOCAL_CLOSE;
- } else if(open_ch_ctx->state == GLINK_CH_STATE_LOCAL_OPEN ||
- open_ch_ctx->state == GLINK_CH_STATE_LOCAL_OPEN_REMOTE_CLOSE ||
- open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN) {
- /* Other side never opened the port, or closed from its end */
- /* Clear everything */
- if(open_ch_ctx->ref_count == 0)
- {
- xport_ctx->channel_cleanup(open_ch_ctx);
- /* re-use channel id if it can be done */
- if(lcid == (xport_ctx->free_lcid-1)) {
- /* If channel being closed is the last opened channel
- re-use the lcid of this channel for any new channels */
- xport_ctx->free_lcid--;
- }
- smem_list_delete(&if_ptr->glink_core_priv->open_list, open_ch_ctx);
+ ASSERT( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSING );
- /* Notify the client */
- open_ch_ctx->notify_state( open_ch_ctx, open_ch_ctx->priv,
- GLINK_LOCAL_DISCONNECTED);
- glink_os_free(open_ch_ctx);
- }
- } else {
- /* Unsupported state */
- ASSERT(0);
+ open_ch_ctx->local_state = GLINK_LOCAL_CH_CLOSED;
+
+ if( open_ch_ctx->remote_state == GLINK_REMOTE_CH_CLOSED ||
+ open_ch_ctx->remote_state == GLINK_REMOTE_CH_SSR_RESET )
+ {
+ glink_clean_channel_ctx( xport_ctx, open_ch_ctx );
}
+ glink_os_cs_release(&open_ch_ctx->ch_state_cs);
glink_os_cs_release(&xport_ctx->channel_q_cs);
+
+ open_ch_ctx->notify_state( open_ch_ctx,
+ open_ch_ctx->priv,
+ GLINK_LOCAL_DISCONNECTED );
+
+ if( open_ch_ctx->remote_state == GLINK_REMOTE_CH_CLOSED ||
+ open_ch_ctx->remote_state == GLINK_REMOTE_CH_SSR_RESET )
+ {
+ glink_os_free( open_ch_ctx );
+ }
+
return;
}
open_ch_ctx = smem_list_next(open_ch_ctx);
}/* end while */
+ glink_os_cs_release(&xport_ctx->channel_q_cs);
/* We are here in case we could not find the channel in the open list. */
ASSERT(0);
-
- glink_os_cs_release(&xport_ctx->channel_q_cs);
}
/*===========================================================================
@@ -712,124 +723,53 @@
xport_ctx = if_ptr->glink_core_priv;
/* Find channel in the open_list */
- glink_os_cs_acquire(&xport_ctx->channel_q_cs);
- open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
+ glink_os_cs_acquire( &xport_ctx->channel_q_cs );
+
+ open_ch_ctx = smem_list_first( &if_ptr->glink_core_priv->open_list );
while(open_ch_ctx != NULL)
{
- if(open_ch_ctx->rcid == rcid) {
- GLINK_LOG_EVENT(GLINK_EVENT_CH_REMOTE_CLOSE, open_ch_ctx->name,
- xport_ctx->xport, xport_ctx->remote_ss, rcid);
- /* Found channel, transition it to appropriate state based
- * on current state */
- open_ch_ctx->ref_count--;
+ if( open_ch_ctx->rcid == rcid )
+ {
+ GLINK_LOG_EVENT( GLINK_EVENT_CH_REMOTE_CLOSE, open_ch_ctx->name,
+ xport_ctx->xport, xport_ctx->remote_ss, rcid);
+ /* Found channel, transition to appropriate state based on current state
+ * grab lock to perform channel state related operations */
+ glink_os_cs_acquire(&open_ch_ctx->ch_state_cs);
- if(open_ch_ctx->state == GLINK_CH_STATE_OPEN) {
- open_ch_ctx->state = GLINK_CH_STATE_LOCAL_OPEN_REMOTE_CLOSE;
+ ASSERT( open_ch_ctx->remote_state == GLINK_REMOTE_CH_OPENED );
+ open_ch_ctx->remote_state = GLINK_REMOTE_CH_CLOSED;
+
+ if( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSED )
+ {
+ /* Local side never opened the channel OR it opened it but closed it */
+ /* Free channel resources */
+ glink_clean_channel_ctx( xport_ctx, open_ch_ctx );
+ }
+
+ glink_os_cs_release(&open_ch_ctx->ch_state_cs);
+ glink_os_cs_release(&xport_ctx->channel_q_cs);
+
+ /* Send the remote close ACK back to the other side */
+ if_ptr->tx_cmd_ch_remote_close_ack(if_ptr, open_ch_ctx->rcid);
+
+ if( open_ch_ctx->local_state == GLINK_LOCAL_CH_CLOSED )
+ {
+ glink_os_free(open_ch_ctx);
+ }
+ else
+ {
/* Inform the client */
open_ch_ctx->notify_state( open_ch_ctx, open_ch_ctx->priv,
GLINK_REMOTE_DISCONNECTED);
-
- /* Send the remote close ACK back to the other side */
- if_ptr->tx_cmd_ch_remote_close_ack(if_ptr, open_ch_ctx->rcid);
-
- /* Free channel resources */
- xport_ctx->channel_cleanup(open_ch_ctx);
-
- GLINK_LOG_EVENT(GLINK_EVENT_CH_REMOTE_CLOSE, open_ch_ctx->name,
- xport_ctx->xport, xport_ctx->remote_ss, rcid);
- glink_os_cs_release(&xport_ctx->channel_q_cs);
-
- return;
- } else if (open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN ||
- open_ch_ctx->state == GLINK_CH_STATE_REMOTE_OPEN_LOCAL_CLOSE) {
- /* Local side never opened the channel OR it opened it but closed it */
- /* Free channel resources */
- xport_ctx->channel_cleanup(open_ch_ctx);
-
- /* Send the remote close ACK back to the other side */
- if_ptr->tx_cmd_ch_remote_close_ack(if_ptr, open_ch_ctx->rcid);
-
- if(open_ch_ctx->ref_count == 0)
- {
- /* re-use channel id if it can be done */
- if (open_ch_ctx->lcid == (xport_ctx->free_lcid - 1)) {
- /* If channel being closed is the last opened channel
- re-use the lcid of this channel for any new channels */
- xport_ctx->free_lcid--;
- }
- smem_list_delete(&if_ptr->glink_core_priv->open_list, open_ch_ctx);
- glink_os_free(open_ch_ctx);
- }
-
- glink_os_cs_release(&xport_ctx->channel_q_cs);
-
- return;
- } else {
- /* SHould not get this callback for a channel in any other state */
-
- //OS_LOG_ERROR(3, "GLINK_RX_CMD_CH_REMOTE_CLOSE: received close cmd for invalid state"
- // "[channel ctx: 0x%x][current channel state: %d]",
- // open_ch_ctx, open_ch_ctx->state );
- glink_os_cs_release(&xport_ctx->channel_q_cs);
- if_ptr->tx_cmd_ch_remote_close_ack(if_ptr, open_ch_ctx->rcid);
- return;
}
+
+ return;
}
open_ch_ctx = smem_list_next(open_ch_ctx);
}/* end while */
- /* We are here in case we could not find the channel in the open list
- * or OPEN state. */
- ASSERT(0);
-
- glink_os_cs_release(&xport_ctx->channel_q_cs);
-}
-
-/*===========================================================================
-FUNCTION glink_ch_state_local_trans
-
-DESCRIPTION Process local state transition
-
-ARGUMENTS *if_ptr Pointer to interface instance; must be unique
- for each edge
-
- rcid Remote Channel ID
-
-RETURN VALUE None.
-
-SIDE EFFECTS None
-===========================================================================*/
-void glink_ch_state_local_trans
-(
- glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
- uint32 lcid, /* Local channel ID */
- glink_ch_state_type new_state /* New local channel state */
-)
-{
- glink_channel_ctx_type *open_ch_ctx;
- glink_core_xport_ctx_type *xport_ctx;
-
- ASSERT(if_ptr != NULL);
-
- xport_ctx = if_ptr->glink_core_priv;
-
- /* Find channel in the open_list */
- open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
- while(open_ch_ctx != NULL)
- {
- if(open_ch_ctx->lcid == lcid) {
- /* Found channel, transition it to appropriate state */
- open_ch_ctx->state = new_state;
- }
- open_ch_ctx = smem_list_next(open_ch_ctx);
- GLINK_LOG_EVENT(GLINK_EVENT_CH_STATE_TRANS, open_ch_ctx->name,
- xport_ctx->xport, xport_ctx->remote_ss, new_state);
- return;
- }/* end while */
-
- /* We are here in case we could not find the channel in the open list
- * or OPEN state. */
+ glink_os_cs_release( &xport_ctx->channel_q_cs );
ASSERT(0);
}
@@ -920,7 +860,16 @@
open_ch_ctx = smem_list_first(&if_ptr->glink_core_priv->open_list);
while(open_ch_ctx != NULL)
{
- if(open_ch_ctx->rcid == rcid) {
+ if(open_ch_ctx->rcid == rcid ) {
+ glink_os_cs_acquire( &open_ch_ctx->ch_state_cs );
+ if( open_ch_ctx->local_state != GLINK_LOCAL_CH_OPENED &&
+ open_ch_ctx->remote_state != GLINK_REMOTE_CH_OPENED )
+ {
+ glink_os_cs_release( &open_ch_ctx->ch_state_cs );
+ ASSERT(0);
+ return;
+ }
+ glink_os_cs_release( &open_ch_ctx->ch_state_cs );
/* Found channel, let client know of new remote signal state */
prev_sigs = open_ch_ctx->remote_sigs;
open_ch_ctx->remote_sigs = remote_sigs;
@@ -937,29 +886,6 @@
/*===========================================================================
-FUNCTION glink_tx_resume
-
-DESCRIPTION If transport was full and could not continue a transmit
- operation, then it will call this function to notify the core
- that it is ready to resume transmission.
-
-ARGUMENTS *if_ptr Pointer to interface instance; must be unique
- for each edge
-
-RETURN VALUE None.
-
-SIDE EFFECTS None
-===========================================================================*/
-void glink_tx_resume
-(
- glink_transport_if_type *if_ptr /* Pointer to the interface instance */
-)
-{
- /* Not sure what to do here */
-}
-
-
-/*===========================================================================
FUNCTION glink_set_core_version
DESCRIPTION Sets the core version used by the transport; called after
diff --git a/platform/msm_shared/glink/glink_core_intentless_xport.c b/platform/msm_shared/glink/glink_core_intentless_xport.c
index 289ef18..98ced24 100644
--- a/platform/msm_shared/glink/glink_core_intentless_xport.c
+++ b/platform/msm_shared/glink/glink_core_intentless_xport.c
@@ -33,6 +33,55 @@
#include "glink.h"
#include "glink_internal.h"
+glink_core_if_type glink_core_intentless_interface =
+{
+ /** Indicates that transport is now ready to start negotiation using the
+ * v0 configuration. */
+ glink_link_up,
+ /** Receive transport version for remote-initiated version negotiation */
+ glink_rx_cmd_version,
+ /** Receive ACK to previous glink_transport_if_type::tx_cmd_version command */
+ glink_rx_cmd_version_ack,
+ /** Sets the core version used by the transport; called after completing
+ * negotiation.*/
+ glink_set_core_version,
+ /** Receive remote channel open request; expected response is
+ * glink_transport_if_type:: tx_cmd_ch_remote_open_ack */
+ glink_rx_cmd_ch_remote_open,
+ /** This function is invoked by the transport in response to
+ * glink_transport_if_type:: tx_cmd_ch_open */
+ glink_rx_cmd_ch_open_ack,
+ /** This function is invoked by the transport in response to
+ * glink_transport_if_type:: tx_cmd_ch_close */
+ glink_rx_cmd_ch_close_ack,
+ /** Remote channel close request; will result in sending
+ * glink_transport_if_type:: tx_cmd_ch_remote_close_ack */
+ glink_rx_cmd_ch_remote_close,
+ /** Transport invokes this call on receiving remote RX intent */
+ NULL,
+ /** Get receive packet context (if successful, should be followed by call to
+ rx_put_pkt_ctx) */
+ NULL,
+ /** Receive a packet fragment (must have previously received an rx_cmd_rx_data
+ packet). */
+ glink_rx_put_pkt_ctx,
+ /** Transport invokes this call to inform GLink that remote side is
+ * done with previous transmitted packet. */
+ NULL,
+ /** Remote side is requesting an RX intent */
+ NULL,
+ /** ACK to RX Intent Request */
+ NULL,
+ /** Received 32-bit signals value from remote side. It is passed on to
+ * the client */
+ glink_rx_cmd_remote_sigs,
+ /** If transport was full and could not continue a transmit operation,
+ * then it will call this function to notify the core that it is ready to
+ * resume transmission. */
+ NULL
+};
+
+
/*===========================================================================
LOCAL FUNCTION DEFINITIONS
===========================================================================*/
@@ -104,10 +153,58 @@
}
/*===========================================================================
+FUNCTION glink_channel_submit_pkt
+===========================================================================*/
+/**
+
+ Invokes intentless transport Tx function to transmit a packet
+
+ @param[in] open_ch_ctx Channel context.
+ @param[in] pctx_ctx Packet context.
+ @param[in] req_intent Request intent flag
+
+ @return Error code.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+static glink_err_type glink_channel_submit_pkt_intentless
+(
+ glink_channel_ctx_type *open_ch_ctx,
+ glink_core_tx_pkt_type *pctx,
+ boolean req_intent
+)
+{
+ glink_transport_if_type *if_ptr = open_ch_ctx->if_ptr;
+ glink_err_type status = if_ptr->tx(if_ptr, open_ch_ctx->lcid, pctx);
+
+ glink_os_free(pctx);
+
+ return status;
+}
+
+/*===========================================================================
EXTERNAL FUNCTION DEFINITIONS
===========================================================================*/
/*===========================================================================
+ FUNCTION glink_core_get_intentless_interface
+===========================================================================*/
+/**
+
+ Provides core interface for the intentless transport.
+
+ @return Pointer to the core intentless interface.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+glink_core_if_type* glink_core_get_intentless_interface(void)
+{
+ return &glink_core_intentless_interface;
+}
+
+/*===========================================================================
FUNCTION glink_core_setup_intentless_xport
===========================================================================*/
/**
@@ -123,9 +220,10 @@
/*=========================================================================*/
void glink_core_setup_intentless_xport(glink_transport_if_type *if_ptr)
{
+ if_ptr->glink_core_if_ptr = glink_core_get_intentless_interface();
if_ptr->glink_core_priv->verify_open_cfg = glink_verify_open_cfg_intentless;
if_ptr->glink_core_priv->channel_init = (channel_init_fn)glink_core_stub_intentless;
if_ptr->glink_core_priv->channel_cleanup = (channel_cleanup_fn)glink_core_stub_intentless;
- if_ptr->glink_core_priv->use_rm_intent = (use_rm_intent_fn)glink_core_stub_intentless;
+ if_ptr->glink_core_priv->channel_submit_pkt = glink_channel_submit_pkt_intentless;
if_ptr->glink_core_priv->channel_receive_pkt = glink_channel_receive_pkt_intentless;
}
diff --git a/platform/msm_shared/glink/glink_os_utils_dal.c b/platform/msm_shared/glink/glink_os_utils_dal.c
index 7ad6fb7..311890e 100644
--- a/platform/msm_shared/glink/glink_os_utils_dal.c
+++ b/platform/msm_shared/glink/glink_os_utils_dal.c
@@ -56,6 +56,7 @@
void *param;
}glink_os_thread_info_type;
+static uint32 cs_variable = 1;
/*===========================================================================
EXTERNAL FUNCTION DEFINITIONS
===========================================================================*/
@@ -102,6 +103,23 @@
}
/*===========================================================================
+FUNCTION glink_os_cs_create
+===========================================================================*/
+/**
+ Create and initializesa Critical Section
+
+ @return The critical section.
+*/
+/*=========================================================================*/
+os_cs_type *glink_os_cs_create( void )
+{
+ /* Create the new critical section */
+
+ return ( os_cs_type * )cs_variable;
+}
+
+
+/*===========================================================================
FUNCTION glink_os_cs_acquire
===========================================================================*/
/**
@@ -248,15 +266,14 @@
@param[in] s1 String 1
@param[in] s2 String 2
- @param[in] size The maximum number of characters to compare
@return
0 if strings are identical (up to size characters), non-zero otherwise
*/
/*==========================================================================*/
-long glink_os_string_compare( const char *s1, const char *s2, uint32 size )
+long glink_os_string_compare( const char *s1, const char *s2 )
{
- return strncmp( s1, s2, size );
+ return strcmp( s1, s2 );
}
/*===========================================================================
diff --git a/platform/msm_shared/glink/glink_rpmcore_setup.c b/platform/msm_shared/glink/glink_rpmcore_setup.c
index a206afa..573d68d 100644
--- a/platform/msm_shared/glink/glink_rpmcore_setup.c
+++ b/platform/msm_shared/glink/glink_rpmcore_setup.c
@@ -34,11 +34,30 @@
#include "glink_internal.h"
+glink_core_if_type* glink_core_get_intentless_interface(void);
+
/*===========================================================================
EXTERNAL FUNCTION DEFINITIONS
===========================================================================*/
/*===========================================================================
+FUNCTION glink_core_get_default_interface
+===========================================================================*/
+/**
+
+ Provides default core interface.
+
+ @return Pointer to the default core interface.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+glink_core_if_type* glink_core_get_default_interface(void)
+{
+ return glink_core_get_intentless_interface();
+}
+
+/*===========================================================================
FUNCTION glink_core_setup
===========================================================================*/
/**
diff --git a/platform/msm_shared/glink/xport_rpm.c b/platform/msm_shared/glink/xport_rpm.c
index 05329f9..68a6c80 100644
--- a/platform/msm_shared/glink/xport_rpm.c
+++ b/platform/msm_shared/glink/xport_rpm.c
@@ -135,7 +135,7 @@
}
last = ctx_ptr->rx_fifo_size - ctx_ptr->pkt_start_ind;
-
+
if (offset >= last)
{
*size = ctx_ptr->pkt_size - offset;
@@ -235,7 +235,7 @@
*write_ptr++ = *buffer++;
}
- return (char*)write_ptr - &ctx_ptr->tx_fifo[0];
+ return (uint32)((char*)write_ptr - &ctx_ptr->tx_fifo[0]);
}
/*===========================================================================
@@ -271,12 +271,19 @@
glink_os_cs_acquire(ctx_ptr->tx_link_lock);
+ /* Transport is in reset */
+ if( ctx_ptr->reset )
+ {
+ glink_os_cs_release(ctx_ptr->tx_link_lock);
+ return GLINK_STATUS_SUCCESS;
+ }
+
write_ind = ctx_ptr->tx_desc->write_ind;
read_ind = ctx_ptr->tx_desc->read_ind;
avail_size = write_ind < read_ind ? read_ind - write_ind :
ctx_ptr->tx_fifo_size - write_ind + read_ind;
- if (reserve_size + sizeof(uint64_t) > avail_size)
+ if (reserve_size + sizeof(uint64) > avail_size)
{
glink_os_cs_release(ctx_ptr->tx_link_lock);
return GLINK_STATUS_OUT_OF_RESOURCES;
@@ -449,7 +456,7 @@
cmd[0] = XPORT_RPM_SET_CMD_ID(XPORT_RPM_CMD_OPEN_CHANNEL);
cmd[0] |= XPORT_RPM_SET_CHANNEL_ID(lcid);
- cmd[1] = strlen(name) + 1;
+ cmd[1] = (uint32)strlen(name) + 1;
return xport_rpm_send_cmd(ctx_ptr, &cmd[0], sizeof(cmd), (void*)name, cmd[1]);
}
@@ -584,12 +591,12 @@
cmd[0] = XPORT_RPM_SET_CMD_ID(XPORT_RPM_CMD_TX_DATA);
cmd[0] |= XPORT_RPM_SET_CHANNEL_ID(lcid);
cmd[1] = 0;
- cmd[2] = pctx->size;
+ cmd[2] = (uint32)pctx->size;
cmd[3] = 0;
pctx->size_remaining = 0;
- return xport_rpm_send_cmd(ctx_ptr, &cmd[0], sizeof(cmd), (void*)pctx->data, pctx->size);
+ return xport_rpm_send_cmd(ctx_ptr, &cmd[0], sizeof(cmd), (void*)pctx->data, (uint32)pctx->size);
}
/*===========================================================================
@@ -652,11 +659,11 @@
}
/*===========================================================================
-FUNCTION xport_rpm_poll
+FUNCTION xport_rpm_isr
===========================================================================*/
/**
- Poll of RPM transport.
+ ISR of RPM transport.
@param[in] ctx_ptr Pointer to transport context.
@@ -667,7 +674,7 @@
@dependencies None.
*/
/*=========================================================================*/
-glink_err_type xport_rpm_poll( xport_rpm_ctx_type *ctx_ptr )
+glink_err_type xport_rpm_isr( xport_rpm_ctx_type *ctx_ptr )
{
uint32 write_ind, read_ind;
boolean stop_processing = FALSE;
@@ -712,7 +719,7 @@
cmd_arg = MSGRAM_READ32(ctx_ptr, read_ind);
- /* no need to incerment read_ind here since it will be rounded up */
+ /* no need to increment read_ind here since it will be rounded up */
ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_version(
(glink_transport_if_type *)ctx_ptr,
@@ -744,56 +751,53 @@
}
else
{
- char tmpstr[ROUNDUP64(GLINK_CH_NAME_LEN)] = {0};
- uint32 curr = 0;
- uint32* string_ptr;
- string_ptr = (uint32 *)&tmpstr[0];
- while (curr < cmd_arg && curr < sizeof(tmpstr))
+ char temp_string[ROUNDUP64(GLINK_CH_NAME_LEN)] = {0};
+ uint32 num_copied_chars = 0;
+ uint32 *string_ptr;
+
+ string_ptr = ( uint32 * )&temp_string[0];
+ while( ( num_copied_chars < cmd_arg ) && ( num_copied_chars < sizeof( temp_string ) ) )
{
- CHECK_INDEX_WRAP_AROUND(read_ind, ctx_ptr->rx_fifo_size);
- *(string_ptr++) = MSGRAM_READ32(ctx_ptr, read_ind);
- curr += sizeof(uint32);
- read_ind += sizeof(uint32);
+ CHECK_INDEX_WRAP_AROUND( read_ind, ctx_ptr->rx_fifo_size );
+ *( string_ptr++ ) = MSGRAM_READ32( ctx_ptr, read_ind );
+
+ num_copied_chars += sizeof( uint32 );
+ read_ind += sizeof( uint32 );
}
/* add all the unread stuff */
- read_ind += cmd_arg - curr;
+ read_ind += cmd_arg - num_copied_chars;
/* make sure the last character is NULL */
- tmpstr[sizeof(tmpstr) - 1] = 0;
+ temp_string[ sizeof( temp_string ) - 1 ] = 0;
ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_ch_remote_open(
- (glink_transport_if_type *)ctx_ptr, cid, tmpstr, GLINK_XPORT_RPM);
+ (glink_transport_if_type *)ctx_ptr, cid, temp_string, GLINK_XPORT_RPM);
}
break;
case XPORT_RPM_CMD_CLOSE_CHANNEL:
+ /* no need to increment read_ind here since it will be rounded up */
ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_ch_remote_close(
- //(glink_transport_if_type *)ctx_ptr, XPORT_RPM_GET_CHANNEL_ID(cmd));
(glink_transport_if_type *)ctx_ptr, cid);
- /* no need to increment read_ind here since it would be rounded up */
-
break;
case XPORT_RPM_CMD_OPEN_CHANNEL_ACK:
- /* no need to increment read_ind here since it would be rounded up */
-
+ /* no need to increment read_ind here since it will be rounded up */
ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_ch_open_ack(
(glink_transport_if_type *)ctx_ptr, cid, GLINK_XPORT_RPM);
break;
case XPORT_RPM_CMD_CLOSE_CHANNEL_ACK:
-
+ /* no need to increment read_ind here since it will be rounded up */
ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_ch_close_ack(
(glink_transport_if_type *)ctx_ptr, cid);
- /* no need to increment read_ind here since it would be rounded up */
-
break;
case XPORT_RPM_CMD_TX_DATA:
@@ -843,7 +847,7 @@
cmd_arg = MSGRAM_READ32(ctx_ptr, read_ind);
- /* no need to incerement read_ind here since it will be rounded up */
+ /* no need to increment read_ind here since it will be rounded up */
ctx_ptr->xport_if.glink_core_if_ptr->rx_cmd_remote_sigs(
(glink_transport_if_type *)ctx_ptr,
@@ -851,20 +855,28 @@
break;
default:
- dprintf(CRITICAL, "%s:%d: Invalid Command: %u\n",__func__, __LINE__, cmd);
- ASSERT(0);
+ dprintf(CRITICAL, "%s:%d: Invalid Command: %u\n",__func__, __LINE__, cmd);
+ ASSERT(0);
break;
}
- read_ind = ROUNDUP64(read_ind);
-
- if (read_ind >= ctx_ptr->rx_fifo_size)
+ /* Update read index only if transport has not been reset */
+ if( !ctx_ptr->reset )
{
- read_ind -= ctx_ptr->rx_fifo_size;
- }
+ read_ind = ROUNDUP64(read_ind);
- /* Update the shared read index */
- ctx_ptr->rx_desc->read_ind = read_ind;
+ if (read_ind >= ctx_ptr->rx_fifo_size)
+ {
+ read_ind -= ctx_ptr->rx_fifo_size;
+ }
+
+ /* Update the shared read index */
+ ctx_ptr->rx_desc->read_ind = read_ind;
+ }
+ else
+ {
+ stop_processing = TRUE;
+ }
}
glink_os_cs_release(ctx_ptr->rx_link_lock);
@@ -872,51 +884,6 @@
return GLINK_STATUS_SUCCESS;
}
-#ifdef GLINK_RPM_PROC
-/*===========================================================================
-FUNCTION xport_rpm_isr
-===========================================================================*/
-/**
-
- ISR of RPM transport.
-
- @return Returns error code.
-
- @sideeffects None.
-
- @dependencies None.
-*/
-/*=========================================================================*/
-glink_err_type xport_rpm_isr( void )
-{
- xport_rpm_ctx_type *ctx_ptr = xport_rpm_get_context();
-
- return xport_rpm_poll( ctx_ptr );
-}
-#else
-/*===========================================================================
-FUNCTION xport_rpm_isr
-===========================================================================*/
-/**
-
- ISR of RPM transport.
-
- @param[in] ctx_ptr Pointer to transport context.
-
- @return Returns error code.
-
- @sideeffects None.
-
- @dependencies None.
-*/
-/*=========================================================================*/
-glink_err_type xport_rpm_isr( xport_rpm_ctx_type *ctx_ptr )
-{
- return xport_rpm_poll( ctx_ptr );
-}
-#endif
-
-
/*===========================================================================
FUNCTION xport_rpm_ssr
===========================================================================*/
@@ -935,9 +902,15 @@
{
xport_rpm_ctx_type *ctx_ptr = (xport_rpm_ctx_type *)if_ptr;
+ glink_os_cs_acquire(ctx_ptr->tx_link_lock);
+ glink_os_cs_acquire(ctx_ptr->rx_link_lock);
ctx_ptr->tx_desc->write_ind = 0;
+ ctx_ptr->tx_desc->read_ind = 0;
+ ctx_ptr->rx_desc->write_ind = 0;
ctx_ptr->rx_desc->read_ind = 0;
ctx_ptr->reset = TRUE;
+ glink_os_cs_release(ctx_ptr->rx_link_lock);
+ glink_os_cs_release(ctx_ptr->tx_link_lock);
return GLINK_STATUS_SUCCESS;
}
@@ -1004,6 +977,25 @@
}
/*===========================================================================
+FUNCTION xport_rpm_is_toc_present
+===========================================================================*/
+/**
+
+ Checks RPM MSG RAM for ToC presence.
+
+ @return TRUE if ToC is detected, FALSE otherwise.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+boolean xport_rpm_is_toc_present(void)
+{
+ uint32 *msg_ram_toc = (uint32*)xport_rpm_msg_ram_toc;
+
+ return msg_ram_toc[XPORT_RPM_TOC_MAGIC_IDX] == XPORT_RPM_TOC_MAGIC;
+}
+
+/*===========================================================================
FUNCTION xport_rpm_init
===========================================================================*/
/**
@@ -1033,8 +1025,9 @@
return GLINK_STATUS_SUCCESS;
}
- if (msg_ram_toc[XPORT_RPM_TOC_MAGIC_IDX] != XPORT_RPM_TOC_MAGIC)
+ if (!xport_rpm_is_toc_present())
{
+ /* switch to err fatal once RPM side is integrated */
dprintf(CRITICAL, "%s:%d: RPM Transport Failure: Invalid ToC cookie\n", __func__, __LINE__);
return GLINK_STATUS_FAILURE;
}
@@ -1076,14 +1069,12 @@
if (entry->fifo_id == xport_rpm_ctx[ind].pcfg->tx_fifo_id)
{
xport_rpm_ctx[ind].tx_desc = (xport_rpm_ind_type*)&xport_rpm_msg_ram[entry->fifo_offset];
- xport_rpm_ctx[ind].tx_desc->write_ind = 0;
xport_rpm_ctx[ind].tx_fifo = (char*)(xport_rpm_ctx[ind].tx_desc + 1);
xport_rpm_ctx[ind].tx_fifo_size = entry->fifo_size;
}
else if (entry->fifo_id == xport_rpm_ctx[ind].pcfg->rx_fifo_id)
{
xport_rpm_ctx[ind].rx_desc =(xport_rpm_ind_type*)&xport_rpm_msg_ram[entry->fifo_offset];
- xport_rpm_ctx[ind].rx_desc->read_ind = 0;
xport_rpm_ctx[ind].rx_fifo = (char*)(xport_rpm_ctx[ind].rx_desc + 1);
xport_rpm_ctx[ind].rx_fifo_size = entry->fifo_size;
}
@@ -1096,9 +1087,13 @@
continue;
}
+ /* Rx read index should be cleared last */
+ xport_rpm_ctx[ind].tx_desc->write_ind = 0;
+ xport_rpm_ctx[ind].rx_desc->read_ind = 0;
+
/* Initialize context */
- xport_rpm_ctx[ind].tx_link_lock = NULL;
- xport_rpm_ctx[ind].rx_link_lock = NULL;
+ xport_rpm_ctx[ind].tx_link_lock = glink_os_cs_create();
+ xport_rpm_ctx[ind].rx_link_lock = glink_os_cs_create();
/* Initialize GLink transport interface */
xport_rpm_ctx[ind].xport_if.tx_cmd_version = &xport_rpm_tx_cmd_version;
@@ -1112,7 +1107,7 @@
xport_rpm_ctx[ind].xport_if.tx_cmd_set_sigs = &xport_rpm_tx_cmd_set_sigs;
xport_rpm_ctx[ind].xport_if.ssr = &xport_rpm_ssr;
xport_rpm_ctx[ind].xport_if.mask_rx_irq = &xport_rpm_mask_interrupt;
- xport_rpm_ctx[ind].xport_if.poll = (poll_fn)&xport_rpm_poll;
+ xport_rpm_ctx[ind].xport_if.poll = (poll_fn)&xport_rpm_isr;
xport_rpm_ctx[ind].xport_if.wait_link_down = &xport_rpm_wait_link_down;
/* TODO: glink transport priority */
@@ -1125,6 +1120,7 @@
xport_rpm_cfg.version_count = 1;
xport_rpm_cfg.max_cid = 0xFF;
xport_rpm_cfg.max_iid = 0;
+
if (glink_core_register_transport(&xport_rpm_ctx[ind].xport_if, &xport_rpm_cfg) !=
GLINK_STATUS_SUCCESS)
{
@@ -1137,7 +1133,8 @@
(os_isr_cb_fn)xport_rpm_isr,
&xport_rpm_ctx[ind]) )
{
- /* ISR registration failed, set index to invalid. */
+ /* ISR registration failed, set index to invalid.
+ * It will never fail */
xport_rpm_ctx[ind].pcfg = NULL;
continue;
}
diff --git a/platform/msm_shared/include/glink.h b/platform/msm_shared/include/glink.h
index fe5b823..b36fba0 100644
--- a/platform/msm_shared/include/glink.h
+++ b/platform/msm_shared/include/glink.h
@@ -102,6 +102,9 @@
(link_id).version = GLINK_LINK_ID_VER;
/* GLink tx options */
+/* Flag for no options */
+#define GLINK_TX_NO_OPTIONS ( 0 )
+
/* Whether to block and request for remote rx intent in
* case it is not available for this pkt tx */
#define GLINK_TX_REQ_INTENT 0x00000001
@@ -111,6 +114,9 @@
* it is not able to do so */
#define GLINK_TX_SINGLE_THREADED 0x00000002
+/* This option is to turn on tracer packet */
+#define GLINK_TX_TRACER_PKT 0x00000004
+
/* ======================= glink open cfg options ==================*/
/* Specified transport is just the initial transport and migration is possible
@@ -205,6 +211,17 @@
size_t intent_used /* size of the intent used for this packet */
);
+/** Data receive notification callback type*/
+typedef void (*glink_rx_tracer_pkt_notification_cb)
+(
+ glink_handle_type handle, /* handle for the glink channel */
+ const void *priv, /* priv client data passed in glink_open */
+ const void *pkt_priv, /* private client data assiciated with the
+ rx intent that client queued earlier */
+ const void *ptr, /* pointer to the received buffer */
+ size_t size /* size of the packet */
+);
+
/** Vector receive notification callback type*/
typedef void (*glink_rxv_notification_cb)
(
@@ -295,54 +312,58 @@
*/
typedef struct {
/** string name for the transport to use (Optional)*/
- const char *transport;
+ const char *transport;
/** string name for the remote subsystem to which the user wants to
connect */
- const char *remote_ss;
+ const char *remote_ss;
/** string name for the channel */
- const char *name;
+ const char *name;
/** bitfield for specifying various options */
- unsigned options;
+ unsigned options;
/** Private data for client to maintain context. This data is passed back
to client in the notification callbacks */
- const void *priv;
+ const void *priv;
/** Data receive notification callback. Optional if notify_rxv is provided */
- glink_rx_notification_cb notify_rx;
+ glink_rx_notification_cb notify_rx;
+
+ /** Tracer packet receive notification callback.
+ * Optional if user doesn't need to use this */
+ glink_rx_tracer_pkt_notification_cb notify_rx_tracer_pkt;
/** Vector receive notification callback. Optional if notify_rx is provided */
- glink_rxv_notification_cb notify_rxv;
+ glink_rxv_notification_cb notify_rxv;
/** Data transmit notification callback */
- glink_tx_notification_cb notify_tx_done;
+ glink_tx_notification_cb notify_tx_done;
/** GLink channel state notification callback */
- glink_state_notification_cb notify_state;
+ glink_state_notification_cb notify_state;
/** Intent request from the remote side. Optional */
- glink_notify_rx_intent_req_cb notify_rx_intent_req;
+ glink_notify_rx_intent_req_cb notify_rx_intent_req;
/** New intent arrival from the remote side */
- glink_notify_rx_intent_cb notify_rx_intent;
+ glink_notify_rx_intent_cb notify_rx_intent;
/** Control signal change notification - Invoked when remote side
* alters its control signals. Optional */
- glink_notify_rx_sigs_cb notify_rx_sigs;
+ glink_notify_rx_sigs_cb notify_rx_sigs;
/** rx_intent abort notification. This callback would be invoked for
* every rx_intent that is queued with GLink core at the time the
* remote side or local side decides to close the port. Optional */
- glink_notify_rx_abort_cb notify_rx_abort;
+ glink_notify_rx_abort_cb notify_rx_abort;
/** tx abort notification. This callback would be invoked if client
* had queued a tx buffer with glink and it had not been transmitted i.e.
* tx_done callback has not been called for this buffer and remote side
* or local side closed the port. Optional */
- glink_notify_tx_abort_cb notify_tx_abort;
+ glink_notify_tx_abort_cb notify_tx_abort;
}glink_open_config_type;
diff --git a/platform/msm_shared/include/glink_core_if.h b/platform/msm_shared/include/glink_core_if.h
index 040bf31..67cd106 100644
--- a/platform/msm_shared/include/glink_core_if.h
+++ b/platform/msm_shared/include/glink_core_if.h
@@ -57,9 +57,6 @@
===========================================================================*/
typedef struct glink_core_version glink_core_version_type;
-struct glink_channel_ctx;
-typedef struct glink_channel_ctx glink_channel_ctx_type;
-
/**
* Transport status
*/
@@ -81,45 +78,48 @@
size_t pkt_sz; /* Size of the packet */
uint32 iid; /* Intent ID */
void *iovec; /* Pointer to the data buffer to be transmitted */
+ boolean tracer_pkt; /* Specify if this intent is for tracer packet */
glink_buffer_provider_fn vprovider; /* Buffer provider for virtual space */
glink_buffer_provider_fn pprovider; /* Buffer provider for physical space */
};
-/** GLink channel states*/
-typedef enum {
- /** GLink channel state during initialization. No resources have been
- * allocated for this channel as neither GLink end has actually opened
- * the channel */
- GLINK_CH_STATE_CLOSED,
- /** GLink channel state when the local side has opened the channel. GLink
- * core is waiting for the other end of the channel to open */
- GLINK_CH_STATE_LOCAL_OPEN,
+/** Context of Tx activity for a transport */
+typedef struct glink_tx_xport_ctx_s {
+ os_event_type event; /* Event to signal Tx thread */
+ os_cs_type tx_q_cs; /* Lock to protect Tx queue */
+ smem_list_type tx_q; /* Tx channel queue */
+} glink_tx_xport_ctx_type;
- /** GLink channel state when it is fully open. This implies that both ends
- * of the GLink channel are now open. Data transfer can now take place */
- GLINK_CH_STATE_OPEN,
+/** G-Link Local channel states */
+typedef enum
+{
+ /** Local G-Link channel is fully closed */
+ GLINK_LOCAL_CH_CLOSED,
- /** GLink channel state when remote side has initiated a OPEN operation. */
- GLINK_CH_STATE_REMOTE_OPEN,
+ /** Local G-Link channel opened channel and waiting for ACK from remote */
+ GLINK_LOCAL_CH_OPENING,
- /** GLink channel state when remote side has initiated a CLOSE operation.
- * Data cannot be transmitted/received any further on this channel */
- GLINK_CH_STATE_LOCAL_OPEN_REMOTE_CLOSE,
+ /** Local G-Link channel is fully opened */
+ GLINK_LOCAL_CH_OPENED,
- /** GLink channel state when the local side has initiated a CLOSE. This
- * would be followed by a GLINK_STATE_CLOSE state transition after
- * the remote side has acknowledged the CLOSE request */
- GLINK_CH_STATE_REMOTE_OPEN_LOCAL_CLOSE,
+ /** Local G-Link channel closed the channel and waiting for ACK from remote */
+ GLINK_LOCAL_CH_CLOSING
- /** GLink channel state would transition to SLEEP if the underlying
- * transport supports low power mode and decides to go into sleep
- * due to inactivity for some time or any other reason. */
- GLINK_CH_STATE_SLEEP,
+}glink_local_state_type;
- /** GLink channel state would transition to AWAKE state when underlying
- * transport layer has powered up the hardware */
- GLINK_CH_STATE_AWAKE
-}glink_ch_state_type;
+/** G-Link Remote channel states */
+typedef enum
+{
+ /** Remote G-Link channel is closed */
+ GLINK_REMOTE_CH_CLOSED,
+
+ /** Remote G-Link channel is opened */
+ GLINK_REMOTE_CH_OPENED,
+
+ /* Glink channel state when SSR is received from remote sub-system */
+ GLINK_REMOTE_CH_SSR_RESET
+
+}glink_remote_state_type;
/** Indicates that transport is now ready to start negotiation using the
* v0 configuration. */
@@ -187,14 +187,6 @@
uint32 rcid /* Remote channel ID */
);
-/** Process local state transition */
-typedef void (*ch_state_local_trans_fn)
-(
- glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
- uint32 lcid, /* Local channel ID */
- glink_ch_state_type new_state /* New local channel state */
-);
-
/** Transport invokes this call on receiving remote RX intent */
typedef void (*rx_cmd_remote_rx_intent_put_fn)
(
@@ -246,7 +238,7 @@
(
glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
uint32 rcid, /* Remote channel ID */
- boolean granted /* True if RX Intent will be queued, FALSE
+ boolean granted /* True if RX Intent will be queued, false
if request will not be granted. */
);
@@ -292,8 +284,8 @@
glink_rx_intent_type *intent_ptr /* Pointer to the intent context */
);
-/** Use remote intent */
-typedef glink_err_type(*use_rm_intent_fn)
+/** Channel submit pkt */
+typedef glink_err_type(*channel_submit_pkt_fn)
(
glink_channel_ctx_type *open_ch_ctx, /* Pointer to the channel context */
glink_core_tx_pkt_type *pctx, /* Pointer to the packet context */
@@ -306,10 +298,10 @@
struct glink_core_xport_ctx
{
/* Transport name */
- char xport[32];
+ const char *xport;
/* Remote subsystem name */
- char remote_ss[32];
+ const char *remote_ss;
/** Keep track of version array index in use */
const glink_core_version_type *version_array;
@@ -320,6 +312,10 @@
/* Keeps track of the current status of the transport */
glink_transport_status_type status;
+ /* critical section to change/access xport status
+ * automically */
+ os_cs_type status_cs;
+
/* Transport's capabilities */
uint32 xport_capabilities;
@@ -339,6 +335,9 @@
/* Critical section to protect access to liid allocation */
os_cs_type liid_cs;
+ /* Context of Tx activity for a transport */
+ glink_tx_xport_ctx_type *tx_ctx;
+
/* channel open config verification */
verify_open_cfg_fn verify_open_cfg;
@@ -351,8 +350,8 @@
/* channel receive pkt */
channel_receive_pkt_fn channel_receive_pkt;
- /** Use remote intent */
- use_rm_intent_fn use_rm_intent;
+ /* channel submit pkt */
+ channel_submit_pkt_fn channel_submit_pkt;
};
/**
@@ -381,26 +380,18 @@
* glink_transport_if_type:: tx_cmd_ch_remote_open_ack */
rx_cmd_ch_remote_open_fn rx_cmd_ch_remote_open;
-
/** This function is invoked by the transport in response to
* glink_transport_if_type:: tx_cmd_ch_open */
rx_cmd_ch_open_ack_fn rx_cmd_ch_open_ack;
-
/** This function is invoked by the transport in response to
* glink_transport_if_type:: tx_cmd_ch_close */
rx_cmd_ch_close_ack_fn rx_cmd_ch_close_ack;
-
/** Remote channel close request; will result in sending
* glink_transport_if_type:: tx_cmd_ch_remote_close_ack */
rx_cmd_ch_remote_close_fn rx_cmd_ch_remote_close;
-
- /** Process local state transition */
- ch_state_local_trans_fn ch_state_local_trans;
-
-
/** Transport invokes this call on receiving remote RX intent */
rx_cmd_remote_rx_intent_put_fn rx_cmd_remote_rx_intent_put;
diff --git a/platform/msm_shared/include/glink_internal.h b/platform/msm_shared/include/glink_internal.h
index 96b0a59..bdd434c 100644
--- a/platform/msm_shared/include/glink_internal.h
+++ b/platform/msm_shared/include/glink_internal.h
@@ -45,7 +45,6 @@
#include "glink_os_utils.h"
#include "glink_core_if.h"
-
#ifdef __cplusplus
extern "C" {
#endif
@@ -92,10 +91,18 @@
GLINK_EVENT_CH_SIG_SET,
GLINK_EVENT_CH_SIG_L_GET,
GLINK_EVENT_CH_SIG_R_GET,
+ GLINK_EVENT_CH_NO_MIGRATION,
+ GLINK_EVENT_CH_MIGRATION_IN_PROGRESS,
GLINK_EVENT_XPORT_INTERNAL,
+ GLINK_EVENT_TRACER_PKT_FAILURE,
+ GLINK_EVENT_TXV_INVALID_BUFFER
}glink_log_event_type;
typedef struct _glink_channel_intents_type {
+
+ /* Link for a channel in Tx queue */
+ struct _glink_channel_intents_type* next;
+
/* Critical section to protest access to intent queues */
os_cs_type intent_q_cs;
@@ -124,81 +131,91 @@
/* Read intent being gathered */
glink_rx_intent_type *cur_read_intent;
+ /* Linked list of Tx packets in the order they where submitted by
+ * the channel owner */
+ smem_list_type tx_pkt_q;
+
} glink_channel_intents_type;
struct glink_channel_ctx {
/* Link needed for use with list APIs. Must be at the head of the struct */
- smem_list_link_type link;
+ smem_list_link_type link;
/* Channel name */
- char name[GLINK_CH_NAME_LEN];
+ char name[GLINK_CH_NAME_LEN];
/* Local channel ID */
- uint32 lcid;
+ uint32 lcid;
/* Remote Channel ID */
- uint32 rcid;
+ uint32 rcid;
- /* Channel state */
- glink_ch_state_type state;
+ /* Local Channel state */
+ glink_local_state_type local_state;
+
+ /* Remote channel state */
+ glink_remote_state_type remote_state;
+
+ /* Critical section to protect channel states */
+ os_cs_type ch_state_cs;
/* Channel local control signal state */
- uint32 local_sigs;
+ uint32 local_sigs;
/* Channel remote control signal state */
- uint32 remote_sigs;
+ uint32 remote_sigs;
/* Critical section to protect tx operations */
- os_cs_type tx_cs;
+ os_cs_type tx_cs;
/* channel intent collection */
- glink_channel_intents_type *pintents;
+ glink_channel_intents_type *pintents;
/* Interface pointer with with this channel is registered */
- glink_transport_if_type *if_ptr;
+ glink_transport_if_type *if_ptr;
/** Private data for client to maintain context. This data is passed back
* to client in the notification callbacks */
- const void *priv;
+ const void *priv;
/** Data receive notification callback */
- glink_rx_notification_cb notify_rx;
+ glink_rx_notification_cb notify_rx;
+
+ /** Tracer Packet data receive notification callback */
+ glink_rx_tracer_pkt_notification_cb notify_rx_tracer_pkt;
/** Vector receive notification callback */
- glink_rxv_notification_cb notify_rxv;
+ glink_rxv_notification_cb notify_rxv;
/** Data transmit notification callback */
- glink_tx_notification_cb notify_tx_done;
+ glink_tx_notification_cb notify_tx_done;
/** GLink channel state notification callback */
- glink_state_notification_cb notify_state;
+ glink_state_notification_cb notify_state;
/** Intent request from the remote side */
- glink_notify_rx_intent_req_cb notify_rx_intent_req;
+ glink_notify_rx_intent_req_cb notify_rx_intent_req;
/** New intent arrival from the remote side */
- glink_notify_rx_intent_cb notify_rx_intent;
+ glink_notify_rx_intent_cb notify_rx_intent;
/** Control signal change notification - Invoked when remote side
* alters its control signals */
- glink_notify_rx_sigs_cb notify_rx_sigs;
+ glink_notify_rx_sigs_cb notify_rx_sigs;
/** rx_intent abort notification. This callback would be invoked for
* every rx_intent that is queued with GLink core at the time the
* remote side or local side decides to close the port. Optional */
- glink_notify_rx_abort_cb notify_rx_abort;
+ glink_notify_rx_abort_cb notify_rx_abort;
/** tx abort notification. This callback would be invoked if client
* had queued a tx buffer with glink and it had not been transmitted i.e.
* tx_done callback has not been called for this buffer and remote side
* or local side closed the port. Optional */
- glink_notify_tx_abort_cb notify_tx_abort;
+ glink_notify_tx_abort_cb notify_tx_abort;
/* glink transport if pointer for preferred channel */
- glink_transport_if_type *req_if_ptr;
-
- /* reference count for no of times channel open/close has been called */
- uint32 ref_count;
+ glink_transport_if_type *req_if_ptr;
/* flag to check if channel is marked for deletion
* This is workaround to prevent channel migration algorithm from finding channel
@@ -207,10 +224,10 @@
* This may lead to remote side opening channel on neogitated xport from which local side
* will get remote open again. In this case channel to be closed will be found for negotiation
* on initial xport again and channel migration algorithm will be triggered(again) */
- boolean tag_ch_for_close;
+ boolean tag_ch_for_close;
/* save glink open config options */
- uint32 ch_open_options;
+ uint32 ch_open_options;
};
@@ -235,7 +252,6 @@
void *priv; /* Notification priv ptr */
} glink_link_notif_data_type;
-
/*===========================================================================
GLOBAL DATA DECLARATIONS
===========================================================================*/
@@ -411,27 +427,6 @@
);
/*===========================================================================
-FUNCTION glink_ch_state_local_trans
-
-DESCRIPTION Process local state transition
-
-ARGUMENTS *if_ptr Pointer to interface instance; must be unique
- for each edge
-
- rcid Remote Channel ID
-
-RETURN VALUE None.
-
-SIDE EFFECTS None
-===========================================================================*/
-void glink_ch_state_local_trans
-(
- glink_transport_if_type *if_ptr, /* Pointer to the interface instance */
- uint32 lcid, /* Local channel ID */
- glink_ch_state_type new_state /* New local channel state */
-);
-
-/*===========================================================================
FUNCTION glink_rx_put_pkt_ctx
DESCRIPTION Transport invokes this call to receive a packet fragment (must
@@ -483,25 +478,6 @@
);
/*===========================================================================
-FUNCTION glink_tx_resume
-
-DESCRIPTION If transport was full and could not continue a transmit
- operation, then it will call this function to notify the core
- that it is ready to resume transmission.
-
-ARGUMENTS *if_ptr Pointer to interface instance; must be unique
- for each edge
-
-RETURN VALUE None.
-
-SIDE EFFECTS None
-===========================================================================*/
-void glink_tx_resume
-(
- glink_transport_if_type *if_ptr /* Pointer to the interface instance */
-);
-
-/*===========================================================================
FUNCTION glink_set_core_version
DESCRIPTION Sets the core version used by the transport; called after
@@ -534,7 +510,7 @@
ARGUMENTS *cfg_ptr - Pointer to channel context
-RETURN VALUE True if fully opened, FALSE otherwise.
+RETURN VALUE True if fully opened, false otherwise.
SIDE EFFECTS None
===========================================================================*/
@@ -746,41 +722,36 @@
);
/*===========================================================================
-FUNCTION glinki_add_ch_to_xport
-
-DESCRIPTION Add remote/local channel context to xport open channel queue
-
-ARGUMENTS *if_ptr - Pointer to xport if on which channel is to
- be opened
- *req_if_ptr - Pointer to xport if on which channel
- actually wants to open
- *ch_ctx - channel context
- **allocated_ch_ctx - Pointer to channel context pointer
- local_open - flag to determine if channel is opened
- locally or remotely
- migration state - flag to identify whether channel migration
- negotiation is done
- TRUE - negotiation is not complete
- FALSE - negotiation is complete.
- channel is being opened on same xport as negotiated
- prio - negotiated xport priority
- (used to send priority via remote_open_ack to
- remote side)
- *tx_pkt - Pointer to the packet context to remove
-
-RETURN VALUE None
-
-SIDE EFFECTS None
+ FUNCTION glinki_add_ch_to_xport
===========================================================================*/
+/**
+ * Add remote/local channel context to xport open channel queue
+ *
+ * @param[in] if_ptr Pointer to xport if on which channel is to
+ * be opened
+ * @param[in] req_if_ptr Pointer to xport if on which channel
+ * actually wants to open
+ * @param[in] ch_ctx channel context
+ * @param[out] allocated_ch_ctx Pointer to channel context pointer
+ * @param[in] local_open flag to determine if channel is opened
+ * locally or remotely
+ * @param[in] prio negotiated xport priority
+ * (used to send priority via remote_open_ack to
+ * remote side)
+ *
+ * @return pointer to glink_transport_if_type struct
+ *
+ * @sideeffects NONE
+ */
+/*=========================================================================*/
glink_err_type glinki_add_ch_to_xport
(
glink_transport_if_type *if_ptr,
glink_transport_if_type *req_if_ptr,
glink_channel_ctx_type *ch_ctx,
- glink_channel_ctx_type **allocated_ch_ctx,
+ glink_channel_ctx_type **allocated_ch_ctx,
unsigned int local_open,
- boolean migration_state,
- glink_xport_priority prio
+ glink_xport_priority prio
);
void glink_mem_log
@@ -811,6 +782,20 @@
void glink_core_setup(glink_transport_if_type *if_ptr);
/*===========================================================================
+FUNCTION glink_core_get_default_interface
+===========================================================================*/
+/**
+
+ Provides default core interface.
+
+ @return Pointer to the default core interface.
+
+ @sideeffects None.
+*/
+/*=========================================================================*/
+glink_core_if_type* glink_core_get_default_interface(void);
+
+/*===========================================================================
FUNCTION glink_core_setup_full_xport
===========================================================================*/
/**
diff --git a/platform/msm_shared/include/glink_os_utils.h b/platform/msm_shared/include/glink_os_utils.h
index e0a1613..ad8f0d1 100644
--- a/platform/msm_shared/include/glink_os_utils.h
+++ b/platform/msm_shared/include/glink_os_utils.h
@@ -175,13 +175,12 @@
@param[in] s1 String 1
@param[in] s2 String 2
- @param[in] size The maximum number of characters to compare
@return
0 if strings are identical (up to size characters), non-zero otherwise
*/
/*==========================================================================*/
-long glink_os_string_compare( const char *s1, const char *s2, uint32_t size );
+long glink_os_string_compare( const char *s1, const char *s2 );
/*===========================================================================
FUNCTION glink_os_copy_mem
diff --git a/platform/msm_shared/include/glink_transport_if.h b/platform/msm_shared/include/glink_transport_if.h
index da9e2bd..84056b0 100644
--- a/platform/msm_shared/include/glink_transport_if.h
+++ b/platform/msm_shared/include/glink_transport_if.h
@@ -51,9 +51,13 @@
/* GLink transport capability bit definitions */
/* Whether transport supports signalling */
#define GLINK_CAPABILITY_SIG_SUPPORT 0x00000001
+
/* Intentless mode of operation */
#define GLINK_CAPABILITY_INTENTLESS 0x00000002
+/* Tracer packet support */
+#define GLINK_CAPABILITY_TRACER_PKT 0x00000004
+
/*===========================================================================
TYPE DECLARATIONS
===========================================================================*/
@@ -70,6 +74,9 @@
struct glink_rx_intent;
typedef struct glink_rx_intent glink_rx_intent_type;
+struct glink_channel_ctx;
+typedef struct glink_channel_ctx glink_channel_ctx_type;
+
/* Priority of transports registered with glink */
typedef enum {
GLINK_XPORT_SMEM = 100,
@@ -81,13 +88,17 @@
} glink_xport_priority;
/** Glink core -> Xport pkt type definition */
-typedef struct {
+typedef struct glink_core_tx_pkt_s {
+ struct glink_core_tx_pkt_s *next; /* pointer to the next packet in list */
+
void *data; /* Pointer to the data buffer to be transmitted */
const void *pkt_priv; /* Per packet private data */
+ uint32 cid; /* Local channel ID being used to transmit data */
uint32 iid; /* Remote intent ID being used to transmit data */
size_t size; /* Size of data buffer */
size_t size_remaining; /* Size left to transmit */
void *iovec; /* Pointer to the data buffer to be transmitted */
+ boolean tracer_pkt; /* specify if this intent is for tracer packet */
glink_buffer_provider_fn vprovider; /* Buffer provider for virtual space */
glink_buffer_provider_fn pprovider; /* Buffer provider for physical space */
}glink_core_tx_pkt_type;
@@ -317,7 +328,7 @@
* channel */
tx_fn tx;
- /** Send request to the remote to queue more rx intents */
+ /** Send request to the remote to queue more rx intents */
tx_cmd_rx_intent_req_fn tx_cmd_rx_intent_req;
/** Send ACK to the remote side's request to queue more rx intents */
diff --git a/platform/msm_shared/include/mipi_dsi.h b/platform/msm_shared/include/mipi_dsi.h
index b4d81a4..81c4612 100644
--- a/platform/msm_shared/include/mipi_dsi.h
+++ b/platform/msm_shared/include/mipi_dsi.h
@@ -201,6 +201,13 @@
int wait;
};
+struct mipi_dsi_i2c_cmd {
+ uint8_t i2c_addr;
+ uint8_t reg;
+ uint8_t val;
+ int sleep_in_ms;
+};
+
struct mipi_dsi_panel_config {
char mode;
char num_of_lanes;
diff --git a/platform/msm_shared/include/mipi_dsi_i2c.h b/platform/msm_shared/include/mipi_dsi_i2c.h
new file mode 100644
index 0000000..b67b977
--- /dev/null
+++ b/platform/msm_shared/include/mipi_dsi_i2c.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 __MIPI_DSI_I2C_H__
+#define __MIPI_DSI_I2C_H__
+
+#include <stdint.h>
+
+int mipi_dsi_i2c_read_byte(uint8_t addr, uint8_t reg, uint8_t *buf);
+int mipi_dsi_i2c_write_byte(uint8_t addr, uint8_t reg, uint8_t val);
+int mipi_dsi_i2c_read(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len);
+int mipi_dsi_i2c_device_init();
+
+#endif /* __MIPI_DSI_I2C_H__ */
diff --git a/platform/msm_shared/include/msm_panel.h b/platform/msm_shared/include/msm_panel.h
index ff99ba3..7a3b014 100755
--- a/platform/msm_shared/include/msm_panel.h
+++ b/platform/msm_shared/include/msm_panel.h
@@ -267,6 +267,13 @@
unsigned long max_link_clk;
};
+struct dsi2HDMI_panel_info {
+ struct mipi_dsi_i2c_cmd *dsi_tg_i2c_cmd;
+ struct mipi_dsi_i2c_cmd *dsi_setup_cfg_i2c_cmd;
+ int num_of_tg_i2c_cmds;
+ int num_of_cfg_i2c_cmds;
+};
+
enum lvds_mode {
LVDS_SINGLE_CHANNEL_MODE,
LVDS_DUAL_CHANNEL_MODE,
@@ -315,6 +322,7 @@
struct lvds_panel_info lvds;
struct hdmi_panel_info hdmi;
struct edp_panel_info edp;
+ struct dsi2HDMI_panel_info adv7533;
struct dfps_info dfps;
@@ -345,6 +353,7 @@
int (*post_power_func)(int enable);
int (*pre_init_func)(void);
int (*update_panel_info) (void);
+ int (*dsi2HDMI_config) (struct msm_panel_info *);
};
#endif
diff --git a/platform/msm_shared/include/xport_rpm.h b/platform/msm_shared/include/xport_rpm.h
index 2566172..8282766 100644
--- a/platform/msm_shared/include/xport_rpm.h
+++ b/platform/msm_shared/include/xport_rpm.h
@@ -39,7 +39,7 @@
INCLUDE FILES
===========================================================================*/
#include "glink_transport_if.h"
-#include <glink.h>
+
/*===========================================================================
MACRO DECLARATIONS
===========================================================================*/
@@ -67,10 +67,6 @@
#define XPORT_RPM_GET_CHANNEL_ID(c) (((c) >> 16) & 0xFFFF)
#define XPORT_RPM_SET_CHANNEL_ID(cid) (((cid) << 16) & 0xFFFF0000)
-#define XPORT_RPM_GET_STR_LEN(c) (((c) >> 16) & 0xFFFF)
-#define XPORT_RPM_SET_STR_LEN(c) (((c) << 16) & 0xFFFF0000)
-#define XPORT_RPM_GET_PRIO(c) ((c) & 0xFFFF)
-#define XPORT_RPM_SET_PRIO(c) ((c) & 0xFFFF)
#define XPORT_RPM_GET_VERSION(c) (((c) >> 16) & 0xFFFF)
#define XPORT_RPM_SET_VERSION(v) (((v) << 16) & 0xFFFF0000)
diff --git a/platform/msm_shared/mdp5.c b/platform/msm_shared/mdp5.c
index baed08b..d67b5c8 100755
--- a/platform/msm_shared/mdp5.c
+++ b/platform/msm_shared/mdp5.c
@@ -107,12 +107,18 @@
if (mdss_mdp_rev == MDSS_MDP_HW_REV_110)
return 0xB0020;
+ else if (MDSS_IS_MAJOR_MINOR_MATCHING(mdss_mdp_rev, MDSS_MDP_HW_REV_107))
+ return 0xB0000;
else
return 0xC8020;
}
void mdp_clk_gating_ctrl(void)
{
+ uint32_t mdss_mdp_rev = readl(MDP_HW_REV);
+ if (MDSS_IS_MAJOR_MINOR_MATCHING(mdss_mdp_rev, MDSS_MDP_HW_REV_107))
+ return;
+
writel(0x40000000, MDP_CLK_CTRL0);
udelay(20);
writel(0x40000040, MDP_CLK_CTRL0);
@@ -277,8 +283,10 @@
static void mdss_vbif_setup()
{
- int access_secure = restore_secure_cfg(SECURE_DEVICE_MDSS);
uint32_t mdp_hw_rev = readl(MDP_HW_REV);
+ int access_secure = false;
+ if (!MDSS_IS_MAJOR_MINOR_MATCHING(mdp_hw_rev, MDSS_MDP_HW_REV_107))
+ access_secure = restore_secure_cfg(SECURE_DEVICE_MDSS);
if (!access_secure) {
dprintf(SPEW, "MDSS VBIF registers unlocked by TZ.\n");
@@ -464,6 +472,7 @@
uint32_t hsync_start_x, hsync_end_x;
uint32_t display_hctl, hsync_ctl, display_vstart, display_vend;
uint32_t adjust_xres = 0;
+ uint32_t upper = 0, lower = 0;
struct lcdc_panel_info *lcdc = NULL;
struct intf_timing_params itp = {0};
@@ -479,8 +488,15 @@
if (pinfo->lcdc.split_display) {
adjust_xres /= 2;
if (intf_base == (MDP_INTF_1_BASE + mdss_mdp_intf_offset())) {
- writel(BIT(8), MDP_REG_SPLIT_DISPLAY_LOWER_PIPE_CTL);
- writel(BIT(8), MDP_REG_SPLIT_DISPLAY_UPPER_PIPE_CTL);
+ if (pinfo->lcdc.pipe_swap) {
+ lower |= BIT(4);
+ upper |= BIT(8);
+ } else {
+ lower |= BIT(8);
+ upper |= BIT(4);
+ }
+ writel(lower, MDP_REG_SPLIT_DISPLAY_LOWER_PIPE_CTL);
+ writel(upper, MDP_REG_SPLIT_DISPLAY_UPPER_PIPE_CTL);
writel(0x1, MDP_REG_SPLIT_DISPLAY_EN);
}
}
diff --git a/platform/msm_shared/mipi_dsi_i2c.c b/platform/msm_shared/mipi_dsi_i2c.c
new file mode 100644
index 0000000..b8b690e
--- /dev/null
+++ b/platform/msm_shared/mipi_dsi_i2c.c
@@ -0,0 +1,99 @@
+/* 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 <mipi_dsi_i2c.h>
+#include <blsp_qup.h>
+#include <i2c_qup.h>
+#include <gsbi.h>
+#include <err.h>
+#include <debug.h>
+
+#define I2C_CLK_FREQ 100000
+#define I2C_SRC_CLK_FREQ 50000000
+
+static struct qup_i2c_dev *i2c_dev;
+
+int mipi_dsi_i2c_read(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t len)
+{
+ if (!buf)
+ return ERR_INVALID_ARGS;
+
+ if(!i2c_dev)
+ return ERR_NOT_VALID;
+
+ struct i2c_msg rd_buf[] = {
+ {addr, I2C_M_WR, 1, ®},
+ {addr, I2C_M_RD, len, buf}
+ };
+
+ int err = qup_i2c_xfer(i2c_dev, rd_buf, 2);
+ if (err < 0) {
+ dprintf(CRITICAL, "Read reg %x failed\n", reg);
+ return err;
+ }
+
+ return NO_ERROR;
+}
+
+int mipi_dsi_i2c_read_byte(uint8_t addr, uint8_t reg, uint8_t *buf)
+{
+ if (!buf)
+ return ERR_INVALID_ARGS;
+
+ return mipi_dsi_i2c_read(addr, reg, buf, 1);
+}
+
+int mipi_dsi_i2c_write_byte(uint8_t addr, uint8_t reg, uint8_t val)
+{
+ if (!i2c_dev)
+ return ERR_NOT_VALID;
+
+ unsigned char buf[2] = {reg, val};
+ struct i2c_msg msg_buf[] = {
+ {addr, I2C_M_WR, 2, buf},
+ };
+
+ int err = qup_i2c_xfer(i2c_dev, msg_buf, 1);
+ if (err < 0) {
+ dprintf(CRITICAL, "Write reg %x failed\n", reg);
+ return err;
+ }
+ return NO_ERROR;
+}
+
+int mipi_dsi_i2c_device_init()
+{
+ i2c_dev = qup_blsp_i2c_init(BLSP_ID_1, QUP_ID_3,
+ I2C_CLK_FREQ, I2C_SRC_CLK_FREQ);
+ if(!i2c_dev) {
+ dprintf(CRITICAL, "mipi_dsi_i2c_device_init() failed\n");
+ return ERR_NOT_VALID;
+ }
+ return NO_ERROR;
+}
diff --git a/platform/msm_shared/qmp_usb30_phy.c b/platform/msm_shared/qmp_usb30_phy.c
index a2c21cf..54a8831 100644
--- a/platform/msm_shared/qmp_usb30_phy.c
+++ b/platform/msm_shared/qmp_usb30_phy.c
@@ -47,17 +47,33 @@
static bool hsonly_mode;
-struct qmp_reg qmp_settings[] =
+/* Override values for QMP 2.0 V1 devices */
+struct qmp_reg qmp_override_pll_rev2[] =
+{
+ {0x124, 0x1C}, /* USB3PHY_QSERDES_COM_VCO_TUNE_CTRL */
+ {0x12C, 0x3F}, /* USB3PHY_QSERDES_COM_VCO_TUNE1_MODE0 */
+ {0x130, 0x01}, /* USB3PHY_QSERDES_COM_VCO_TUNE2_MODE0 */
+ {0x6c4, 0x13}, /* USB3_PHY_FLL_CNTRL2 */
+};
+
+/* QMP settings for 2.0 QMP V2 HW */
+struct qmp_reg qmp_settings_rev2[] =
{
{0xAC, 0x14}, /* QSERDES_COM_SYSCLK_EN_SEL */
{0x34, 0x08}, /* QSERDES_COM_BIAS_EN_CLKBUFLR_EN */
{0x174, 0x30}, /* QSERDES_COM_CLK_SELECT */
- {0x3C, 0x06}, /* QSERDES_COM_SYS_CLK_CTRL */
- {0xb4, 0x00}, /* QSERDES_COM_RESETSM_CNTRL */
- {0xb8, 0x08}, /* QSERDES_COM_RESETSM_CNTRL2 */
{0x194, 0x06}, /* QSERDES_COM_CMN_CONFIG */
{0x19c, 0x01}, /* QSERDES_COM_SVS_MODE_CLK_SEL */
{0x178, 0x01}, /* QSERDES_COM_HSCLK_SEL */
+ {0x70, 0x0F}, /* USB3PHY_QSERDES_COM_BG_TRIM */
+ {0x48, 0x0F}, /* USB3PHY_QSERDES_COM_PLL_IVCO */
+ {0x3C, 0x04}, /* QSERDES_COM_SYS_CLK_CTRL */
+
+ /* Res_code Settings */
+ {0xC4, 0x15}, /* USB3PHY_QSERDES_COM_RESCODE_DIV_NUM */
+ {0x1B8, 0x1F}, /* QSERDES_COM_CMN_MISC2 */
+
+ /* PLL & Loop filter settings */
{0xd0, 0x82}, /* QSERDES_COM_DEC_START_MODE0 */
{0xdc, 0x55}, /* QSERDES_COM_DIV_FRAC_START1_MODE0 */
{0xe0, 0x55}, /* QSERDES_COM_DIV_FRAC_START2_MODE0 */
@@ -66,20 +82,17 @@
{0x84, 0x16}, /* QSERDES_COM_PLL_RCTRL_MODE0 */
{0x90, 0x28}, /* QSERDES_COM_PLL_CCTRL_MODE0 */
{0x108, 0x80}, /* QSERDES_COM_INTEGLOOP_GAIN0_MODE0 */
- {0x10c, 0x00}, /* QSERDES_COM_INTEGLOOP_GAIN1_MODE0 */
- {0x124, 0x1c}, /* QSERDES_COM_VCO_TUNE_CTRL */
- {0x12c, 0x3f}, /* QSERDES_COM_VCO_TUNE1_MODE0 */
- {0x130, 0x01}, /* QSERDES_COM_VCO_TUNE2_MODE0 */
- {0x184, 0x0a}, /* QSERDES_COM_CORECLK_DIV */
+ {0x124, 0x00}, /* QSERDES_COM_VCO_TUNE_CTRL */
{0x4c, 0x15}, /* QSERDES_COM_LOCK_CMP1_MODE0 */
{0x50, 0x34}, /* QSERDES_COM_LOCK_CMP2_MODE0 */
{0x54, 0x00}, /* QSERDES_COM_LOCK_CMP3_MODE0 */
- {0xc8, 0x00}, /* QSERDES_COM_LOCK_CMP_EN */
{0x18c, 0x00}, /* QSERDES_COM_CORE_CLK_EN */
- {0xc4, 0x15}, /*QSERDES_COM_RESCODE_DIV_NUM */
{0xcc, 0x00}, /* QSERDES_COM_LOCK_CMP_CFG */
+ {0x0C, 0x0A}, /* QSERDES_COM_BG_TIMER */
{0x128, 0x00}, /* QSERDES_COM_VCO_TUNE_MAP */
{0xc, 0x0a}, /* QSERDES_COM_BG_TIMER */
+
+ /* SSC settings */
{0x10, 0x01}, /* QSERDES_COM_SSC_EN_CENTER */
{0x1c, 0x31}, /* QSERDES_COM_SSC_PER1 */
{0x20, 0x01}, /* QSERDES_COM_SSC_PER2 */
@@ -87,31 +100,38 @@
{0x18, 0x00}, /* QSERDES_COM_SSC_ADJ_PER2 */
{0x24, 0xde}, /* QSERDES_COM_SSC_STEP_SIZE1 */
{0x28, 0x07}, /* QSERDES_COM_SSC_STEP_SIZE2 */
+
+ /* Rx Settings */
{0x440, 0x0b}, /* QSERDES_RX_UCDR_FASTLOCK_FO_GAIN */
- {0x4d8, 0x03}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2 */
- {0x4dc, 0x6c}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3 */
- {0x70, 0xf}, /* QSERDES_COM_BG_TRIM */
- {0x48, 0xf}, /* QSERDES_COM_PLL_IVCO */
- {0x4e0, 0xb8}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4 */
+ {0x41C, 0x04}, /* QSERDES_RX_UCDR_SO_GAIN */
+ {0x4d8, 0x02}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL2 */
+ {0x4dc, 0x4c}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL3 */
+ {0x4e0, 0xbb}, /* QSERDES_RX_RX_EQU_ADAPTOR_CNTRL4 */
{0x508, 0x77}, /* QSERDES_RX_RX_EQ_OFFSET_ADAPTOR_CNTRL1 */
{0x50c, 0x80}, /* QSERDES_RX_RX_OFFSET_ADAPTOR_CNTRL2 */
- {0x514, 0x04}, /* QSERDES_RX_SIGDET_CNTRL */
+ {0x514, 0x03}, /* QSERDES_RX_SIGDET_CNTRL */
{0x518, 0x1b}, /* QSERDES_RX_SIGDET_LVL */
{0x51c, 0x16}, /* QSERDES_RX_SIGDET_DEGLITCH_CNTRL */
+
+ /* Tx settings */
{0x268, 0x45}, /* QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN */
{0x2ac, 0x12}, /* QSERDES_TX_RCV_DETECT_LVL_2 */
+ {0x294, 0x06}, /* QSERDES_TX_LANE_MODE */
+
+ /* FLL settings */
{0x6c4, 0x03}, /* USB3_PHY_FLL_CNTRL2 */
{0x6c0, 0x02}, /* USB3_PHY_FLL_CNTRL1 */
{0x6c8, 0x09}, /* USB3_PHY_FLL_CNT_VAL_L */
{0x6cc, 0x42}, /* USB3_PHY_FLL_CNT_VAL_H_TOL */
{0x6d0, 0x85}, /* USB3_PHY_FLL_MAN_CODE */
- {0x294, 0x02}, /* QSERDES_TX_LANE_MODE */
+
+ /* Lock Det Settings */
{0x680, 0xd1}, /* USB3_PHY_LOCK_DETECT_CONFIG1 */
{0x684, 0x1f}, /* USB3_PHY_LOCK_DETECT_CONFIG2 */
{0x688, 0x47}, /* USB3_PHY_LOCK_DETECT_CONFIG3 */
{0x664, 0x08}, /* USB3_PHY_POWER_STATE_CONFIG2 */
- {0x600, 0x00}, /* USB3_PHY_SW_RESET */
{0x608, 0x03}, /* USB3_PHY_START_CONTROL */
+ {0x600, 0x00}, /* USB3_PHY_SW_RESET */
};
__WEAK uint32_t target_override_pll()
@@ -241,9 +261,16 @@
if (rev_id >= 0x20000000)
{
- qmp_reg_size = sizeof(qmp_settings) / sizeof(struct qmp_reg);
+ qmp_reg_size = sizeof(qmp_settings_rev2) / sizeof(struct qmp_reg);
for (i = 0 ; i < qmp_reg_size; i++)
- writel(qmp_settings[i].val, QMP_PHY_BASE + qmp_settings[i].off);
+ writel(qmp_settings_rev2[i].val, QMP_PHY_BASE + qmp_settings_rev2[i].off);
+
+ if (target_override_pll())
+ {
+ qmp_reg_size = sizeof(qmp_override_pll_rev2) / sizeof(struct qmp_reg);
+ for (i = 0 ; i < qmp_reg_size; i++)
+ writel(qmp_override_pll_rev2[i].val, QMP_PHY_BASE + qmp_override_pll_rev2[i].off);
+ }
}
else
{
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index a098c00..dd024f8 100644
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -199,7 +199,8 @@
$(LOCAL_DIR)/crypto_hash.o \
$(LOCAL_DIR)/crypto5_eng.o \
$(LOCAL_DIR)/crypto5_wrapper.o \
- $(LOCAL_DIR)/i2c_qup.o
+ $(LOCAL_DIR)/i2c_qup.o \
+ $(LOCAL_DIR)/mipi_dsi_i2c.o
endif
@@ -503,6 +504,7 @@
endif
ifeq ($(PLATFORM),msm8996)
+DEFINES += DISPLAY_TYPE_MDSS=1
OBJS += $(LOCAL_DIR)/qtimer.o \
$(LOCAL_DIR)/qtimer_mmap.o \
$(LOCAL_DIR)/interrupts.o \
@@ -525,7 +527,12 @@
$(LOCAL_DIR)/image_verify.o \
$(LOCAL_DIR)/crypto_hash.o \
$(LOCAL_DIR)/crypto5_eng.o \
- $(LOCAL_DIR)/crypto5_wrapper.o
+ $(LOCAL_DIR)/crypto5_wrapper.o \
+ $(LOCAL_DIR)/mdp5.o \
+ $(LOCAL_DIR)/display.o \
+ $(LOCAL_DIR)/mipi_dsi.o \
+ $(LOCAL_DIR)/mipi_dsi_phy.o \
+ $(LOCAL_DIR)/mipi_dsi_autopll_thulium.o
endif
ifeq ($(ENABLE_UFS_SUPPORT), 1)
diff --git a/project/msm8996.mk b/project/msm8996.mk
index 664c0ae..2a8ef25 100644
--- a/project/msm8996.mk
+++ b/project/msm8996.mk
@@ -21,6 +21,7 @@
ENABLE_PARTIAL_GOODS_SUPPORT := 1
ENABLE_RPMB_SUPPORT := 1
ENABLE_GLINK_SUPPORT := 1
+ENABLE_PWM_SUPPORT := true
DEFINES +=VIRTIO=1
diff --git a/target/apq8084/target_display.c b/target/apq8084/target_display.c
index 20e4d03..9ae3ea1 100755
--- a/target/apq8084/target_display.c
+++ b/target/apq8084/target_display.c
@@ -261,6 +261,16 @@
return NO_ERROR;
}
+int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db)
+{
+ memcpy(phy_db->regulator, panel_regulator_settings, REGULATOR_SIZE);
+ memcpy(phy_db->ctrl, panel_physical_ctrl, PHYSICAL_SIZE);
+ memcpy(phy_db->strength, panel_strength_ctrl, STRENGTH_SIZE);
+ memcpy(phy_db->bistCtrl, panel_bist_ctrl, BIST_SIZE);
+ memcpy(phy_db->laneCfg, panel_lane_config, LANE_SIZE);
+ return NO_ERROR;
+}
+
int target_display_pre_on()
{
writel(0x000000FA, MDP_QOS_REMAPPER_CLASS_0);
diff --git a/target/mdm9615/atags.c b/target/mdm9615/atags.c
index 8d02808..76f46b3 100755
--- a/target/mdm9615/atags.c
+++ b/target/mdm9615/atags.c
@@ -63,7 +63,7 @@
*ptr++ = 4;
*ptr++ = 0x54410002;
- *ptr++ = SIZE_23M;
+ *ptr++ = (SIZE_23M-SIZE_1M);
*ptr++ = ram_ptable.parts[i].start + SIZE_88M;
if(ram_ptable.parts[i].size == 0x10000000) {
diff --git a/target/msm8226/target_display.c b/target/msm8226/target_display.c
index fe2e6d5..0bc1173 100755
--- a/target/msm8226/target_display.c
+++ b/target/msm8226/target_display.c
@@ -390,6 +390,16 @@
return ret;
}
+int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db)
+{
+ memcpy(phy_db->regulator, panel_regulator_settings, REGULATOR_SIZE);
+ memcpy(phy_db->ctrl, panel_physical_ctrl, PHYSICAL_SIZE);
+ memcpy(phy_db->strength, panel_strength_ctrl, STRENGTH_SIZE);
+ memcpy(phy_db->bistCtrl, panel_bist_ctrl, BIST_SIZE);
+ memcpy(phy_db->laneCfg, panel_lane_config, LANE_SIZE);
+ return NO_ERROR;
+}
+
bool target_display_panel_node(char *panel_name, char *pbuf, uint16_t buf_size)
{
return gcdb_display_cmdline_arg(panel_name, pbuf, buf_size);
diff --git a/target/msm8610/target_display.c b/target/msm8610/target_display.c
index f87b2ed..1213bd3 100755
--- a/target/msm8610/target_display.c
+++ b/target/msm8610/target_display.c
@@ -183,6 +183,16 @@
return 0;
}
+int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db)
+{
+ memcpy(phy_db->regulator, panel_regulator_settings, REGULATOR_SIZE);
+ memcpy(phy_db->ctrl, panel_physical_ctrl, PHYSICAL_SIZE);
+ memcpy(phy_db->strength, panel_strength_ctrl, STRENGTH_SIZE);
+ memcpy(phy_db->bistCtrl, panel_bist_ctrl, BIST_SIZE);
+ memcpy(phy_db->laneCfg, panel_lane_config, LANE_SIZE);
+ return NO_ERROR;
+}
+
bool target_display_panel_node(char *panel_name, char *pbuf, uint16_t buf_size)
{
return gcdb_display_cmdline_arg(panel_name, pbuf, buf_size);
diff --git a/target/msm8909/target_display.c b/target/msm8909/target_display.c
index e949547..085dc00 100755
--- a/target/msm8909/target_display.c
+++ b/target/msm8909/target_display.c
@@ -232,6 +232,16 @@
return NO_ERROR;
}
+int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db)
+{
+ memcpy(phy_db->regulator, panel_regulator_settings, REGULATOR_SIZE);
+ memcpy(phy_db->ctrl, panel_physical_ctrl, PHYSICAL_SIZE);
+ memcpy(phy_db->strength, panel_strength_ctrl, STRENGTH_SIZE);
+ memcpy(phy_db->bistCtrl, panel_bist_ctrl, BIST_SIZE);
+ memcpy(phy_db->laneCfg, panel_lane_config, LANE_SIZE);
+ return NO_ERROR;
+}
+
bool target_display_panel_node(char *panel_name, char *pbuf, uint16_t buf_size)
{
return gcdb_display_cmdline_arg(panel_name, pbuf, buf_size);
diff --git a/target/msm8916/include/target/display.h b/target/msm8916/include/target/display.h
index 27b4a5d..e27432f 100644
--- a/target/msm8916/include/target/display.h
+++ b/target/msm8916/include/target/display.h
@@ -99,6 +99,10 @@
"msmgpio", 22, 3, 1, 0, 1
};
+static struct gpio_pin dsi2HDMI_switch_gpio = {
+ "msmgpio", 32, 3, 1, 0, 1
+};
+
/*---------------------------------------------------------------------------*/
/* Target Physical configuration */
/*---------------------------------------------------------------------------*/
@@ -179,6 +183,8 @@
R61318_HD_VIDEO_PANEL,
R63417_1080P_VIDEO_PANEL,
JDI_A216_FHD_VIDEO_PANEL,
+ ADV7533_1080P_VIDEO_PANEL,
+ ADV7533_720P_VIDEO_PANEL,
UNKNOWN_PANEL
};
diff --git a/target/msm8916/oem_panel.c b/target/msm8916/oem_panel.c
index 4c51fcb..0562017 100644
--- a/target/msm8916/oem_panel.c
+++ b/target/msm8916/oem_panel.c
@@ -34,6 +34,7 @@
#include <board.h>
#include <mipi_dsi.h>
#include <target/display.h>
+#include <mipi_dsi_i2c.h>
#include "include/panel.h"
#include "panel_display.h"
@@ -58,6 +59,8 @@
#include "include/panel_r61318_hd_video.h"
#include "include/panel_r63417_1080p_video.h"
#include "include/panel_jdi_a216_fhd_video.h"
+#include "include/panel_adv7533_1080p60.h"
+#include "include/panel_adv7533_720p60.h"
#define DISPLAY_MAX_PANEL_DETECTION 2
#define OTM8019A_FWVGA_VIDEO_PANEL_ON_DELAY 50
@@ -97,6 +100,8 @@
{"r61318_hd_video", R61318_HD_VIDEO_PANEL},
{"r63417_1080p_video", R63417_1080P_VIDEO_PANEL},
{"jdi_a216_fhd_video", JDI_A216_FHD_VIDEO_PANEL},
+ {"adv7533_1080p_video", ADV7533_1080P_VIDEO_PANEL},
+ {"adv7533_720p_video", ADV7533_720P_VIDEO_PANEL},
};
static uint32_t panel_id;
@@ -554,6 +559,41 @@
memcpy(phy_db->timing,
jdi_a216_fhd_video_timings, TIMING_SIZE);
break;
+ case ADV7533_1080P_VIDEO_PANEL:
+ panelstruct->paneldata = &adv7533_1080p_video_panel_data;
+ panelstruct->panelres = &adv7533_1080p_video_panel_res;
+ panelstruct->color = &adv7533_1080p_video_color;
+ panelstruct->videopanel = &adv7533_1080p_video_video_panel;
+ panelstruct->commandpanel = &adv7533_1080p_video_command_panel;
+ panelstruct->state = &adv7533_1080p_video_state;
+ panelstruct->laneconfig = &adv7533_1080p_video_lane_config;
+ panelstruct->paneltiminginfo
+ = &adv7533_1080p_video_timing_info;
+ pinfo->adv7533.dsi_tg_i2c_cmd = &adv7533_1080p_tg_i2c_command;
+ pinfo->adv7533.num_of_tg_i2c_cmds = ADV7533_1080P_TG_COMMANDS;
+ pinfo->adv7533.dsi_setup_cfg_i2c_cmd = &adv7533_1080p_common_cfg;
+ pinfo->adv7533.num_of_cfg_i2c_cmds = ADV7533_1080P_CONFIG_COMMANDS;
+ memcpy(phy_db->timing,
+ adv7533_1080p_video_timings, TIMING_SIZE);
+ break;
+
+ case ADV7533_720P_VIDEO_PANEL:
+ panelstruct->paneldata = &adv7533_720p_video_panel_data;
+ panelstruct->panelres = &adv7533_720p_video_panel_res;
+ panelstruct->color = &adv7533_720p_video_color;
+ panelstruct->videopanel = &adv7533_720p_video_video_panel;
+ panelstruct->commandpanel = &adv7533_720p_video_command_panel;
+ panelstruct->state = &adv7533_720p_video_state;
+ panelstruct->laneconfig = &adv7533_720p_video_lane_config;
+ panelstruct->paneltiminginfo
+ = &adv7533_720p_video_timing_info;
+ pinfo->adv7533.dsi_tg_i2c_cmd = &adv7533_720p_tg_i2c_command;
+ pinfo->adv7533.num_of_tg_i2c_cmds = ADV7533_720P_TG_COMMANDS;
+ pinfo->adv7533.dsi_setup_cfg_i2c_cmd = &adv7533_720p_common_cfg;
+ pinfo->adv7533.num_of_cfg_i2c_cmds = ADV7533_720P_CONFIG_COMMANDS;
+ memcpy(phy_db->timing,
+ adv7533_720p_video_timings, TIMING_SIZE);
+ break;
case UNKNOWN_PANEL:
default:
memset(panelstruct, 0, sizeof(struct panel_struct));
@@ -584,6 +624,7 @@
uint32_t hw_subtype = board_hardware_subtype();
int32_t panel_override_id;
uint32_t target_id, plat_hw_ver_major;
+ uint8_t rev = 0;
if (panel_name) {
panel_override_id = panel_name_to_id(supp_panels,
@@ -702,6 +743,22 @@
}
}
break;
+ case HW_PLATFORM_SBC:
+ if (platform_is_apq8016()) {
+ /* Set Switch GPIO to DSI2HDMI mode */
+ target_set_switch_gpio(1);
+ /* ADV7533 DSI to HDMI Bridge Chip Connected */
+ mipi_dsi_i2c_device_init();
+ /* Read ADV Chip ID */
+ if (!mipi_dsi_i2c_read_byte(ADV7533_MAIN, 0x00, &rev)) {
+ dprintf(INFO, "ADV7533 Rev ID: 0x%x\n",rev);
+ } else {
+ dprintf(CRITICAL, "error reading Rev ID from bridge chip\n");
+ return PANEL_TYPE_UNKNOWN;
+ }
+ panel_id = ADV7533_720P_VIDEO_PANEL;
+ }
+ break;
default:
dprintf(CRITICAL, "Display not enabled for %d HW type\n",
hw_id);
diff --git a/target/msm8916/target_display.c b/target/msm8916/target_display.c
index 42693d6..56ee921 100644
--- a/target/msm8916/target_display.c
+++ b/target/msm8916/target_display.c
@@ -42,6 +42,7 @@
#include <target/display.h>
#include <i2c_qup.h>
#include <blsp_qup.h>
+#include <mipi_dsi_i2c.h>
#include "include/panel.h"
#include "include/display_resource.h"
@@ -298,6 +299,51 @@
return 0;
}
+static int dsi2HDMI_i2c_write_regs(struct mipi_dsi_i2c_cmd *cfg, int size)
+{
+ int ret = NO_ERROR;
+ int i;
+
+ if (!cfg)
+ return ERR_INVALID_ARGS;
+
+ for (i = 0; i < size; i++) {
+ ret = mipi_dsi_i2c_write_byte(cfg[i].i2c_addr, cfg[i].reg,
+ cfg[i].val);
+ if (ret) {
+ dprintf(CRITICAL, "mipi_dsi reg writes failed\n");
+ goto w_regs_fail;
+ }
+ if (cfg[i].sleep_in_ms) {
+ udelay(cfg[i].sleep_in_ms*1000);
+ }
+ }
+w_regs_fail:
+ return ret;
+}
+
+int target_display_dsi2hdmi_config(struct msm_panel_info *pinfo)
+{
+ int ret = NO_ERROR;
+
+ if (!pinfo)
+ return ERR_INVALID_ARGS;
+
+ /*
+ * If dsi to HDMI bridge chip connected then
+ * send I2c commands to the chip
+ */
+ if (pinfo->adv7533.dsi_setup_cfg_i2c_cmd)
+ ret = dsi2HDMI_i2c_write_regs(pinfo->adv7533.dsi_setup_cfg_i2c_cmd,
+ pinfo->adv7533.num_of_cfg_i2c_cmds);
+
+ if (pinfo->adv7533.dsi_tg_i2c_cmd)
+ ret = dsi2HDMI_i2c_write_regs(pinfo->adv7533.dsi_tg_i2c_cmd,
+ pinfo->adv7533.num_of_tg_i2c_cmds);
+
+ return ret;
+}
+
static int target_panel_reset_skuh(uint8_t enable)
{
int ret = NO_ERROR;
@@ -501,6 +547,16 @@
return ret;
}
+int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db)
+{
+ memcpy(phy_db->regulator, panel_regulator_settings, REGULATOR_SIZE);
+ memcpy(phy_db->ctrl, panel_physical_ctrl, PHYSICAL_SIZE);
+ memcpy(phy_db->strength, panel_strength_ctrl, STRENGTH_SIZE);
+ memcpy(phy_db->bistCtrl, panel_bist_ctrl, BIST_SIZE);
+ memcpy(phy_db->laneCfg, panel_lane_config, LANE_SIZE);
+ return NO_ERROR;
+}
+
int target_ldo_ctrl(uint8_t enable, struct msm_panel_info *pinfo)
{
/*
@@ -515,6 +571,20 @@
return gcdb_display_cmdline_arg(panel_name, pbuf, buf_size);
}
+void target_set_switch_gpio(int enable_dsi2HdmiBridge)
+{
+ gpio_tlmm_config(dsi2HDMI_switch_gpio.pin_id, 0,
+ dsi2HDMI_switch_gpio.pin_direction,
+ dsi2HDMI_switch_gpio.pin_pull,
+ dsi2HDMI_switch_gpio.pin_strength,
+ dsi2HDMI_switch_gpio.pin_state);
+ gpio_set_dir(enable_gpio.pin_id, 2);
+ if (enable_dsi2HdmiBridge)
+ gpio_set_dir(enable_gpio.pin_id, 0); /* DSI2HDMI Bridge */
+ else
+ gpio_set_dir(enable_gpio.pin_id, 2); /* Normal DSI operation */
+}
+
void target_display_init(const char *panel_name)
{
uint32_t panel_loop = 0;
diff --git a/target/msm8952/target_display.c b/target/msm8952/target_display.c
index 9a86cd9..2a908d6 100644
--- a/target/msm8952/target_display.c
+++ b/target/msm8952/target_display.c
@@ -362,6 +362,16 @@
qpnp_wled_init(&config);
}
+int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db)
+{
+ memcpy(phy_db->regulator, panel_regulator_settings, REGULATOR_SIZE);
+ memcpy(phy_db->ctrl, panel_physical_ctrl, PHYSICAL_SIZE);
+ memcpy(phy_db->strength, panel_strength_ctrl, STRENGTH_SIZE);
+ memcpy(phy_db->bistCtrl, panel_bist_ctrl, BIST_SIZE);
+ memcpy(phy_db->laneCfg, panel_lane_config, LANE_SIZE);
+ return NO_ERROR;
+}
+
int target_ldo_ctrl(uint8_t enable, struct msm_panel_info *pinfo)
{
diff --git a/target/msm8974/target_display.c b/target/msm8974/target_display.c
index 73319ea..eae18f0 100755
--- a/target/msm8974/target_display.c
+++ b/target/msm8974/target_display.c
@@ -263,6 +263,16 @@
return NO_ERROR;
}
+int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db)
+{
+ memcpy(phy_db->regulator, panel_regulator_settings, REGULATOR_SIZE);
+ memcpy(phy_db->ctrl, panel_physical_ctrl, PHYSICAL_SIZE);
+ memcpy(phy_db->strength, panel_strength_ctrl, STRENGTH_SIZE);
+ memcpy(phy_db->bistCtrl, panel_bist_ctrl, BIST_SIZE);
+ memcpy(phy_db->laneCfg, panel_lane_config, LANE_SIZE);
+ return NO_ERROR;
+}
+
/* Pull DISP_RST_N high to get panel out of reset */
int target_panel_reset(uint8_t enable, struct panel_reset_sequence *resetseq,
struct msm_panel_info *pinfo)
diff --git a/target/msm8994/target_display.c b/target/msm8994/target_display.c
index 1779ea5..bb3fa2f 100644
--- a/target/msm8994/target_display.c
+++ b/target/msm8994/target_display.c
@@ -576,6 +576,16 @@
return NO_ERROR;
}
+int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db)
+{
+ memcpy(phy_db->regulator, panel_regulator_settings, REGULATOR_SIZE);
+ memcpy(phy_db->ctrl, panel_physical_ctrl, PHYSICAL_SIZE);
+ memcpy(phy_db->strength, panel_strength_ctrl, STRENGTH_SIZE);
+ memcpy(phy_db->bistCtrl, panel_bist_ctrl, BIST_SIZE);
+ memcpy(phy_db->laneCfg, panel_lane_config, LANE_SIZE);
+ return NO_ERROR;
+}
+
int target_display_get_base_offset(uint32_t base)
{
if(platform_is_msm8992()) {
diff --git a/target/msm8996/include/target/display.h b/target/msm8996/include/target/display.h
new file mode 100644
index 0000000..eddc0c8
--- /dev/null
+++ b/target/msm8996/include/target/display.h
@@ -0,0 +1,96 @@
+/* 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 _TARGET_DISPLAY_H
+#define _TARGET_DISPLAY_H
+
+/*---------------------------------------------------------------------------*/
+/* HEADER files */
+/*---------------------------------------------------------------------------*/
+#include <display_resource.h>
+
+/*---------------------------------------------------------------------------*/
+/* Target Physical configuration */
+/*---------------------------------------------------------------------------*/
+
+static const uint32_t panel_strength_ctrl[] = {
+ 0xFF, 0x06,
+ 0xFF, 0x06,
+ 0xFF, 0x06,
+ 0xFF, 0x06,
+ 0xFF, 0x00
+};
+
+static const uint32_t panel_regulator_settings[] = {
+ 0x1d, 0x1d, 0x1d, 0x1d, 0x1d
+};
+
+static const char panel_lane_config[] = {
+ 0x00, 0x00, 0x10, 0x0f,
+ 0x00, 0x00, 0x10, 0x0f,
+ 0x00, 0x00, 0x10, 0x0f,
+ 0x00, 0x00, 0x10, 0x0f,
+ 0x00, 0x00, 0x10, 0x8f,
+};
+
+static const char panel_bist_ctrl[] = { };
+
+static const uint32_t panel_physical_ctrl[] = { };
+/*---------------------------------------------------------------------------*/
+/* Other Configuration */
+/*---------------------------------------------------------------------------*/
+#define DISPLAY_CMDLINE_PREFIX " mdss_mdp.panel="
+
+#define MIPI_FB_ADDR 0x82400000
+
+#define MIPI_HSYNC_PULSE_WIDTH 16
+#define MIPI_HSYNC_BACK_PORCH_DCLK 32
+#define MIPI_HSYNC_FRONT_PORCH_DCLK 76
+
+#define MIPI_VSYNC_PULSE_WIDTH 2
+#define MIPI_VSYNC_BACK_PORCH_LINES 2
+#define MIPI_VSYNC_FRONT_PORCH_LINES 4
+
+#define PWM_BL_LPG_CHAN_ID 4 /* lpg_out<3> */
+
+#define HDMI_PANEL_NAME "hdmi"
+#define HDMI_CONTROLLER_STRING "hdmi:0"
+
+/*---------------------------------------------------------------------------*/
+/* Functions */
+/*---------------------------------------------------------------------------*/
+int target_display_pre_on();
+int target_display_pre_off();
+int target_display_post_on();
+int target_display_post_off();
+int target_cont_splash_screen();
+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();
+
+#endif
diff --git a/target/msm8996/init.c b/target/msm8996/init.c
index 57695d8..6667314 100644
--- a/target/msm8996/init.c
+++ b/target/msm8996/init.c
@@ -282,6 +282,33 @@
/* This is filled from board.c */
}
+static uint8_t splash_override;
+/* Returns 1 if target supports continuous splash screen. */
+int target_cont_splash_screen()
+{
+ uint8_t splash_screen = 0;
+ if(!splash_override) {
+ switch(board_hardware_id())
+ {
+ case HW_PLATFORM_SURF:
+ case HW_PLATFORM_MTP:
+ case HW_PLATFORM_FLUID:
+ dprintf(SPEW, "Target_cont_splash=1\n");
+ splash_screen = 1;
+ break;
+ default:
+ dprintf(SPEW, "Target_cont_splash=0\n");
+ splash_screen = 0;
+ }
+ }
+ return splash_screen;
+}
+
+void target_force_cont_splash_disable(uint8_t override)
+{
+ splash_override = override;
+}
+
/* Detect the modem type */
void target_baseband_detect(struct board_data *board)
{
@@ -385,7 +412,10 @@
uint32_t target_override_pll()
{
- return 1;
+ if (board_soc_version() >= 0x20000)
+ return 0;
+ else
+ return 1;
}
crypto_engine_type board_ce_type(void)
diff --git a/target/msm8996/oem_panel.c b/target/msm8996/oem_panel.c
new file mode 100644
index 0000000..4e86448
--- /dev/null
+++ b/target/msm8996/oem_panel.c
@@ -0,0 +1,288 @@
+/* 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
+ * 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <debug.h>
+#include <string.h>
+#include <err.h>
+#include <smem.h>
+#include <msm_panel.h>
+#include <board.h>
+#include <mipi_dsi.h>
+#include <qtimer.h>
+#include <platform.h>
+
+#include "include/panel.h"
+#include "target/display.h"
+#include "panel_display.h"
+#include <mipi_dsi.h>
+
+/*---------------------------------------------------------------------------*/
+/* GCDB Panel Database */
+/*---------------------------------------------------------------------------*/
+#include "include/panel_nt35597_wqxga_dualdsi_video.h"
+#include "include/panel_sharp_wqxga_dualdsi_video.h"
+#include "include/panel_jdi_qhd_dualdsi_video.h"
+#include "include/panel_jdi_qhd_dualdsi_cmd.h"
+
+/*---------------------------------------------------------------------------*/
+/* static panel selection variable */
+/*---------------------------------------------------------------------------*/
+enum {
+ NT35597_WQXGA_DUALDSI_VIDEO_PANEL,
+ SHARP_WQXGA_DUALDSI_VIDEO_PANEL,
+ JDI_QHD_DUALDSI_VIDEO_PANEL,
+ JDI_QHD_DUALDSI_CMD_PANEL,
+ UNKNOWN_PANEL
+};
+
+/*
+ * The list of panels that are supported on this target.
+ * Any panel in this list can be selected using fastboot oem command.
+ */
+static struct panel_list supp_panels[] = {
+ {"nt35597_wqxga_dualdsi_video", NT35597_WQXGA_DUALDSI_VIDEO_PANEL},
+ {"sharp_wqxga_dualdsi_video", SHARP_WQXGA_DUALDSI_VIDEO_PANEL},
+ {"jdi_qhd_dualdsi_video", JDI_QHD_DUALDSI_VIDEO_PANEL},
+ {"jdi_qhd_dualdsi_cmd", JDI_QHD_DUALDSI_CMD_PANEL},
+};
+
+static uint32_t panel_id;
+
+int oem_panel_rotation()
+{
+ return NO_ERROR;
+}
+
+int oem_panel_on()
+{
+ if (panel_id == JDI_QHD_DUALDSI_CMD_PANEL) {
+ /* needs extra delay to avoid unexpected artifacts */
+ mdelay(JDI_QHD_DUALDSI_CMD_PANEL_ON_DELAY);
+
+ }
+ return NO_ERROR;
+}
+
+int oem_panel_off()
+{
+ return NO_ERROR;
+}
+
+static bool init_panel_data(struct panel_struct *panelstruct,
+ struct msm_panel_info *pinfo,
+ struct mdss_dsi_phy_ctrl *phy_db)
+{
+ int pan_type;
+
+ switch (panel_id) {
+ case SHARP_WQXGA_DUALDSI_VIDEO_PANEL:
+ pan_type = PANEL_TYPE_DSI;
+ pinfo->lcd_reg_en = 0;
+ panelstruct->paneldata = &sharp_wqxga_dualdsi_video_panel_data;
+ panelstruct->paneldata->panel_node_id =
+ "qcom,mdss_dsi_sharp_wqxga_video_0";
+ panelstruct->paneldata->slave_panel_node_id =
+ "qcom,mdss_dsi_sharp_wqxga_video_1";
+ panelstruct->paneldata->panel_operating_mode = 11;
+ panelstruct->paneldata->panel_with_enable_gpio = 0;
+
+ panelstruct->panelres = &sharp_wqxga_dualdsi_video_panel_res;
+ panelstruct->color = &sharp_wqxga_dualdsi_video_color;
+ panelstruct->videopanel = &sharp_wqxga_dualdsi_video_video_panel;
+ panelstruct->commandpanel = &sharp_wqxga_dualdsi_video_command_panel;
+ panelstruct->state = &sharp_wqxga_dualdsi_video_state;
+ panelstruct->laneconfig = &sharp_wqxga_dualdsi_video_lane_config;
+ panelstruct->paneltiminginfo
+ = &sharp_wqxga_dualdsi_video_timing_info;
+ panelstruct->panelresetseq
+ = &sharp_wqxga_dualdsi_video_reset_seq;
+ panelstruct->backlightinfo = &sharp_wqxga_dualdsi_video_backlight;
+
+ pinfo->labibb = &sharp_wqxga_dualdsi_video_labibb;
+
+ pinfo->mipi.panel_on_cmds
+ = sharp_wqxga_dualdsi_video_on_command;
+ pinfo->mipi.num_of_panel_on_cmds
+ = SHARP_WQXGA_DUALDSI_VIDEO_ON_COMMAND;
+ pinfo->mipi.panel_off_cmds
+ = sharp_wqxga_dualdsi_video_off_command;
+ pinfo->mipi.num_of_panel_off_cmds
+ = SHARP_WQXGA_DUALDSI_VIDEO_OFF_COMMAND;
+ memcpy(phy_db->timing,
+ sharp_wqxga_dualdsi_thulium_video_timings,
+ MAX_TIMING_CONFIG * sizeof(uint32_t));
+ pinfo->mipi.tx_eot_append = true;
+ break;
+ case NT35597_WQXGA_DUALDSI_VIDEO_PANEL:
+ pan_type = PANEL_TYPE_DSI;
+ pinfo->lcd_reg_en = 0;
+ panelstruct->paneldata = &nt35597_wqxga_dualdsi_video_panel_data;
+ panelstruct->paneldata->panel_operating_mode = 11;
+ panelstruct->paneldata->panel_with_enable_gpio = 0;
+
+ panelstruct->panelres = &nt35597_wqxga_dualdsi_video_panel_res;
+ panelstruct->color = &nt35597_wqxga_dualdsi_video_color;
+ panelstruct->videopanel = &nt35597_wqxga_dualdsi_video_video_panel;
+ panelstruct->commandpanel = &nt35597_wqxga_dualdsi_video_command_panel;
+ panelstruct->state = &nt35597_wqxga_dualdsi_video_state;
+ panelstruct->laneconfig = &nt35597_wqxga_dualdsi_video_lane_config;
+ panelstruct->paneltiminginfo
+ = &nt35597_wqxga_dualdsi_video_timing_info;
+ panelstruct->panelresetseq
+ = &nt35597_wqxga_dualdsi_video_reset_seq;
+ panelstruct->backlightinfo = &nt35597_wqxga_dualdsi_video_backlight;
+
+ pinfo->labibb = &nt35597_wqxga_dualdsi_video_labibb;
+
+ pinfo->mipi.panel_on_cmds
+ = nt35597_wqxga_dualdsi_video_on_command;
+ pinfo->mipi.num_of_panel_on_cmds
+ = NT35597_WQXGA_DUALDSI_VIDEO_ON_COMMAND;
+ pinfo->mipi.panel_off_cmds
+ = nt35597_wqxga_dualdsi_video_off_command;
+ pinfo->mipi.num_of_panel_off_cmds
+ = NT35597_WQXGA_DUALDSI_VIDEO_OFF_COMMAND;
+ memcpy(phy_db->timing,
+ nt35597_wqxga_dualdsi_thulium_video_timings,
+ MAX_TIMING_CONFIG * sizeof(uint32_t));
+ pinfo->mipi.tx_eot_append = true;
+ break;
+ case JDI_QHD_DUALDSI_VIDEO_PANEL:
+ pan_type = PANEL_TYPE_DSI;
+ pinfo->lcd_reg_en = 1;
+ panelstruct->paneldata->panel_node_id =
+ "qcom,dsi_jdi_qhd_video_0";
+ panelstruct->paneldata->slave_panel_node_id =
+ "qcom,dsi_jdi_qhd_video_1";
+ panelstruct->paneldata = &jdi_qhd_dualdsi_video_panel_data;
+
+ panelstruct->panelres = &jdi_qhd_dualdsi_video_panel_res;
+ panelstruct->color = &jdi_qhd_dualdsi_video_color;
+ panelstruct->videopanel = &jdi_qhd_dualdsi_video_video_panel;
+ panelstruct->commandpanel = &jdi_qhd_dualdsi_video_command_panel;
+ panelstruct->state = &jdi_qhd_dualdsi_video_state;
+ panelstruct->laneconfig = &jdi_qhd_dualdsi_video_lane_config;
+ panelstruct->paneltiminginfo
+ = &jdi_qhd_dualdsi_video_timing_info;
+ panelstruct->panelresetseq
+ = &jdi_qhd_dualdsi_video_reset_seq;
+ panelstruct->backlightinfo = &jdi_qhd_dualdsi_video_backlight;
+ pinfo->mipi.panel_on_cmds
+ = jdi_qhd_dualdsi_video_on_command;
+ pinfo->mipi.num_of_panel_on_cmds
+ = JDI_QHD_DUALDSI_VIDEO_ON_COMMAND;
+ pinfo->mipi.panel_off_cmds
+ = jdi_qhd_dualdsi_video_off_command;
+ pinfo->mipi.num_of_panel_off_cmds
+ = JDI_QHD_DUALDSI_VIDEO_OFF_COMMAND;
+ memcpy(phy_db->timing,
+ jdi_qhd_dualdsi_thulium_cmd_timings,
+ MAX_TIMING_CONFIG * sizeof(uint32_t));
+ break;
+ case JDI_QHD_DUALDSI_CMD_PANEL:
+ pan_type = PANEL_TYPE_DSI;
+ pinfo->lcd_reg_en = 1;
+ panelstruct->paneldata = &jdi_qhd_dualdsi_cmd_panel_data;
+ panelstruct->paneldata->panel_node_id =
+ "qcom,mdss_dsi_jdi_qhd_dualmipi0_cmd";
+ panelstruct->paneldata->slave_panel_node_id =
+ "qcom,mdss_dsi_jdi_qhd_dualmipi1_cmd";
+
+ panelstruct->panelres = &jdi_qhd_dualdsi_cmd_panel_res;
+ panelstruct->color = &jdi_qhd_dualdsi_cmd_color;
+ panelstruct->videopanel = &jdi_qhd_dualdsi_cmd_video_panel;
+ panelstruct->commandpanel = &jdi_qhd_dualdsi_cmd_command_panel;
+ panelstruct->state = &jdi_qhd_dualdsi_cmd_state;
+ panelstruct->laneconfig = &jdi_qhd_dualdsi_cmd_lane_config;
+ panelstruct->paneltiminginfo
+ = &jdi_qhd_dualdsi_cmd_timing_info;
+ panelstruct->panelresetseq
+ = &jdi_qhd_dualdsi_cmd_reset_seq;
+ panelstruct->backlightinfo = &jdi_qhd_dualdsi_cmd_backlight;
+ pinfo->mipi.panel_on_cmds
+ = jdi_qhd_dualdsi_cmd_on_command;
+ pinfo->mipi.num_of_panel_on_cmds
+ = JDI_QHD_DUALDSI_CMD_ON_COMMAND;
+ pinfo->mipi.panel_off_cmds
+ = jdi_qhd_dualdsi_cmd_off_command;
+ pinfo->mipi.num_of_panel_off_cmds
+ = JDI_QHD_DUALDSI_CMD_OFF_COMMAND;
+ memcpy(phy_db->timing,
+ jdi_qhd_dualdsi_thulium_video_timings,
+ MAX_TIMING_CONFIG * sizeof(uint32_t));
+ break;
+ default:
+ case UNKNOWN_PANEL:
+ pan_type = PANEL_TYPE_UNKNOWN;
+ break;
+ }
+ return pan_type;
+}
+
+int oem_panel_select(const char *panel_name, struct panel_struct *panelstruct,
+ struct msm_panel_info *pinfo,
+ struct mdss_dsi_phy_ctrl *phy_db)
+{
+ uint32_t hw_id = board_hardware_id();
+ int32_t panel_override_id;
+
+ phy_db->pll_type = DSI_PLL_TYPE_THULIUM;
+
+ if (panel_name) {
+ panel_override_id = panel_name_to_id(supp_panels,
+ ARRAY_SIZE(supp_panels), panel_name);
+
+ if (panel_override_id < 0) {
+ dprintf(CRITICAL, "Not able to search the panel:%s\n",
+ panel_name + strspn(panel_name, " "));
+ } else if (panel_override_id < UNKNOWN_PANEL) {
+ /* panel override using fastboot oem command */
+ panel_id = panel_override_id;
+
+ dprintf(INFO, "OEM panel override:%s\n",
+ panel_name + strspn(panel_name, " "));
+ goto panel_init;
+ }
+ }
+
+ switch (hw_id) {
+ case HW_PLATFORM_MTP:
+ case HW_PLATFORM_FLUID:
+ case HW_PLATFORM_SURF:
+ panel_id = SHARP_WQXGA_DUALDSI_VIDEO_PANEL;
+ break;
+ default:
+ dprintf(CRITICAL, "Display not enabled for %d HW type\n"
+ , hw_id);
+ return PANEL_TYPE_UNKNOWN;
+ }
+
+panel_init:
+ return init_panel_data(panelstruct, pinfo, phy_db);
+}
diff --git a/target/msm8996/rules.mk b/target/msm8996/rules.mk
index 2326ff0..2544635 100644
--- a/target/msm8996/rules.mk
+++ b/target/msm8996/rules.mk
@@ -1,6 +1,7 @@
LOCAL_DIR := $(GET_LOCAL_DIR)
INCLUDES += -I$(LOCAL_DIR)/include -I$(LK_TOP_DIR)/platform/msm_shared
+INCLUDES += -I$(LK_TOP_DIR)/dev/gcdb/display -I$(LK_TOP_DIR)/dev/gcdb/display/include
PLATFORM := msm8996
@@ -14,13 +15,16 @@
KERNEL_ADDR := 0x80000000
KERNEL_SIZE := 62
-DEFINES += DISPLAY_SPLASH_SCREEN=0
+DEFINES += DISPLAY_SPLASH_SCREEN=1
DEFINES += DISPLAY_TYPE_MIPI=1
DEFINES += DISPLAY_TYPE_DSI6G=1
MODULES += \
dev/keys \
dev/pmic/pm8x41 \
+ dev/qpnp_wled \
+ dev/qpnp_led \
+ dev/gcdb/display \
lib/ptable \
lib/libfdt
@@ -38,7 +42,9 @@
OBJS += \
$(LOCAL_DIR)/init.o \
- $(LOCAL_DIR)/meminfo.o
+ $(LOCAL_DIR)/meminfo.o \
+ $(LOCAL_DIR)/target_display.o \
+ $(LOCAL_DIR)/oem_panel.o \
ifeq ($(ENABLE_GLINK_SUPPORT),1)
OBJS += \
diff --git a/target/msm8996/target_display.c b/target/msm8996/target_display.c
new file mode 100644
index 0000000..f9f3a5b
--- /dev/null
+++ b/target/msm8996/target_display.c
@@ -0,0 +1,515 @@
+/* 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 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <debug.h>
+#include <string.h>
+#include <smem.h>
+#include <err.h>
+#include <msm_panel.h>
+#include <mipi_dsi.h>
+#include <pm8x41.h>
+#include <pm8x41_wled.h>
+#include <qpnp_wled.h>
+#include <board.h>
+#include <mdp5.h>
+#include <endian.h>
+#include <regulator.h>
+#include <qtimer.h>
+#include <arch/defines.h>
+#include <platform/gpio.h>
+#include <platform/clock.h>
+#include <platform/iomap.h>
+#include <target/display.h>
+#include <mipi_dsi_autopll_thulium.h>
+
+#include "include/panel.h"
+#include "include/display_resource.h"
+#include "gcdb_display.h"
+
+#define GPIO_STATE_LOW 0
+#define GPIO_STATE_HIGH 2
+#define RESET_GPIO_SEQ_LEN 3
+
+#define PWM_DUTY_US 13
+#define PWM_PERIOD_US 27
+#define PMIC_WLED_SLAVE_ID 3
+#define PMIC_MPP_SLAVE_ID 2
+
+#define MAX_POLL_READS 15
+#define POLL_TIMEOUT_US 1000
+
+#define STRENGTH_SIZE_IN_BYTES_8996 10
+#define REGULATOR_SIZE_IN_BYTES_8996 5
+#define LANE_SIZE_IN_BYTES_8996 20
+
+/*---------------------------------------------------------------------------*/
+/* GPIO configuration */
+/*---------------------------------------------------------------------------*/
+static struct gpio_pin reset_gpio = {
+ "msmgpio", 8, 3, 1, 0, 1
+};
+
+static struct gpio_pin lcd_reg_en = { /* boost regulator */
+ "pmi8994_gpios", 8, 3, 1, 0, 1
+};
+
+static struct gpio_pin bklt_gpio = { /* lcd_bklt_reg_en */
+ "pm8994_gpios", 14, 3, 1, 0, 1
+};
+
+static uint32_t thulium_dsi_pll_lock_status(uint32_t pll_base, uint32_t off,
+ uint32_t bit)
+{
+ uint32_t cnt, status;
+
+ /* check pll lock first */
+ for (cnt = 0; cnt < MAX_POLL_READS; cnt++) {
+ status = readl(pll_base + off);
+ dprintf(SPEW, "%s: pll_base=%x cnt=%d status=%x\n",
+ __func__, pll_base, cnt, status);
+ status &= BIT(bit); /* bit 5 */
+ if (status)
+ break;
+ udelay(POLL_TIMEOUT_US);
+ }
+
+ return status;
+}
+
+static uint32_t thulium_dsi_pll_enable_seq(uint32_t phy_base, uint32_t pll_base)
+{
+ uint32_t pll_locked;
+
+ writel(0x01, phy_base + 0x48);
+ dmb();
+
+ pll_locked = thulium_dsi_pll_lock_status(pll_base, 0xcc, 5);
+ if (pll_locked)
+ pll_locked = thulium_dsi_pll_lock_status(pll_base, 0xcc, 0);
+
+ if (!pll_locked)
+ dprintf(ERROR, "%s: DSI PLL lock failed\n", __func__);
+ else
+ dprintf(SPEW, "%s: DSI PLL lock Success\n", __func__);
+
+ return pll_locked;
+}
+
+static int thulium_wled_backlight_ctrl(uint8_t enable)
+{
+ qpnp_wled_enable_backlight(enable);
+ qpnp_ibb_enable(enable);
+ return NO_ERROR;
+}
+
+static int thulium_pwm_backlight_ctrl(uint8_t enable)
+{
+ uint8_t slave_id = 3; /* lpg at pmi */
+
+ if (enable) {
+ /* lpg channel 4 */
+
+ /* LPG_ENABLE_CONTROL */
+ pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x46, 0x0);
+ mdelay(100);
+
+ /* LPG_VALUE_LSB, duty cycle = 0x80/0x200 = 1/4 */
+ pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x44, 0x80);
+ /* LPG_VALUE_MSB */
+ pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x45, 0x00);
+ /* LPG_PWM_SYNC */
+ pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x47, 0x01);
+
+ /* LPG_PWM_SIZE_CLK, */
+ pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x41, 0x13);
+ /* LPG_PWM_FREQ_PREDIV */
+ pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x42, 0x02);
+ /* LPG_PWM_TYPE_CONFIG */
+ pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x43, 0x20);
+ /* LPG_ENABLE_CONTROL */
+ pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x46, 0x04);
+
+ /* SEC_ACCESS */
+ pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0xD0, 0xA5);
+ /* DTEST4, OUT_HI */
+ pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0xE5, 0x01);
+ /* LPG_ENABLE_CONTROL */
+ pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x46, 0xA4);
+ } else {
+ /* LPG_ENABLE_CONTROL */
+ pm8x41_lpg_write_sid(slave_id, PWM_BL_LPG_CHAN_ID, 0x46, 0x0);
+ }
+
+ return NO_ERROR;
+}
+
+static void lcd_reg_enable(void)
+{
+ uint8_t slave_id = 2; /* gpio at pmi */
+
+ struct pm8x41_gpio gpio = {
+ .direction = PM_GPIO_DIR_OUT,
+ .function = PM_GPIO_FUNC_HIGH,
+ .vin_sel = 2, /* VIN_2 */
+ .output_buffer = PM_GPIO_OUT_CMOS,
+ .out_strength = PM_GPIO_OUT_DRIVE_MED,
+ };
+
+ pm8x41_gpio_config_sid(slave_id, lcd_reg_en.pin_id, &gpio);
+ pm8x41_gpio_set_sid(slave_id, lcd_reg_en.pin_id, 1);
+}
+
+static void lcd_reg_disable(void)
+{
+ uint8_t slave_id = 2; /* gpio at pmi */
+
+ pm8x41_gpio_set_sid(slave_id, lcd_reg_en.pin_id, 0);
+}
+
+static void lcd_bklt_reg_enable(void)
+{
+ struct pm8x41_gpio gpio = {
+ .direction = PM_GPIO_DIR_OUT,
+ .function = PM_GPIO_FUNC_HIGH,
+ .vin_sel = 2, /* VIN_2 */
+ .output_buffer = PM_GPIO_OUT_CMOS,
+ .out_strength = PM_GPIO_OUT_DRIVE_LOW,
+ };
+
+ pm8x41_gpio_config(bklt_gpio.pin_id, &gpio);
+ pm8x41_gpio_set(bklt_gpio.pin_id, 1);
+}
+
+static void lcd_bklt_reg_disable(void)
+{
+ pm8x41_gpio_set(bklt_gpio.pin_id, 0);
+}
+
+int target_backlight_ctrl(struct backlight *bl, uint8_t enable)
+{
+ uint32_t ret = NO_ERROR;
+ struct pm8x41_mpp mpp;
+ int rc;
+
+ if (!bl) {
+ dprintf(CRITICAL, "backlight structure is not available\n");
+ return ERR_INVALID_ARGS;
+ }
+
+ switch (bl->bl_interface_type) {
+ case BL_WLED:
+ /* Enable MPP4 */
+ pmi8994_config_mpp_slave_id(PMIC_MPP_SLAVE_ID);
+ mpp.base = PM8x41_MMP4_BASE;
+ mpp.vin = MPP_VIN2;
+ if (enable) {
+ pm_pwm_enable(false);
+ rc = pm_pwm_config(PWM_DUTY_US, PWM_PERIOD_US);
+ if (rc < 0) {
+ mpp.mode = MPP_HIGH;
+ } else {
+ mpp.mode = MPP_DTEST1;
+ pm_pwm_enable(true);
+ }
+ pm8x41_config_output_mpp(&mpp);
+ pm8x41_enable_mpp(&mpp, MPP_ENABLE);
+ } else {
+ pm_pwm_enable(false);
+ pm8x41_enable_mpp(&mpp, MPP_DISABLE);
+ }
+ /* Need delay before power on regulators */
+ mdelay(20);
+ /* Enable WLED backlight control */
+ ret = thulium_wled_backlight_ctrl(enable);
+ break;
+ case BL_PWM:
+ /* Enable MPP1 */
+ pmi8994_config_mpp_slave_id(PMIC_MPP_SLAVE_ID);
+ mpp.base = PM8x41_MMP1_BASE;
+ mpp.vin = MPP_VIN2;
+ mpp.mode = MPP_DTEST4;
+ if (enable) {
+ pm8x41_config_output_mpp(&mpp);
+ pm8x41_enable_mpp(&mpp, MPP_ENABLE);
+ } else {
+ pm8x41_enable_mpp(&mpp, MPP_DISABLE);
+ }
+ /* Need delay before power on regulators */
+ mdelay(20);
+ ret = thulium_pwm_backlight_ctrl(enable);
+ break;
+ default:
+ dprintf(CRITICAL, "backlight type:%d not supported\n",
+ bl->bl_interface_type);
+ return ERR_NOT_SUPPORTED;
+ }
+
+ return ret;
+}
+
+int target_panel_clock(uint8_t enable, struct msm_panel_info *pinfo)
+{
+ uint32_t flags;
+ uint32_t ret = NO_ERROR;
+ uint32_t board_version = board_soc_version();
+
+ if (pinfo->dest == DISPLAY_2) {
+ flags = MMSS_DSI_CLKS_FLAG_DSI1;
+ if (pinfo->mipi.dual_dsi)
+ flags |= MMSS_DSI_CLKS_FLAG_DSI0;
+ } else {
+ flags = MMSS_DSI_CLKS_FLAG_DSI0;
+ if (pinfo->mipi.dual_dsi)
+ flags |= MMSS_DSI_CLKS_FLAG_DSI1;
+ }
+
+ if (!enable) {
+ /* stop pll */
+ writel(0x0, pinfo->mipi.phy_base + 0x48);
+ dmb();
+
+ mmss_dsi_clock_disable(flags);
+ goto clks_disable;
+ }
+
+ if (board_version == 0x20000 || board_version == 0x20001)
+ video_gdsc_enable();
+ mmss_gdsc_enable();
+ mmss_bus_clock_enable();
+ mdp_clock_enable();
+ mdss_dsi_auto_pll_thulium_config(pinfo);
+
+ if (!thulium_dsi_pll_enable_seq(pinfo->mipi.phy_base,
+ pinfo->mipi.pll_base)) {
+ ret = ERROR;
+ dprintf(CRITICAL, "PLL failed to lock!\n");
+ goto clks_disable;
+ }
+ mmss_dsi_clock_enable(DSI0_PHY_PLL_OUT, flags);
+ return NO_ERROR;
+
+clks_disable:
+ mdp_clock_disable();
+ mmss_bus_clock_disable();
+ mmss_gdsc_disable();
+ if (board_version == 0x20000 || board_version == 0x20001)
+ video_gdsc_disable();
+
+ return ret;
+}
+
+int target_panel_reset(uint8_t enable, struct panel_reset_sequence *resetseq,
+ struct msm_panel_info *pinfo)
+{
+ uint32_t i = 0;
+
+ if (enable) {
+ gpio_tlmm_config(reset_gpio.pin_id, 0,
+ reset_gpio.pin_direction, reset_gpio.pin_pull,
+ reset_gpio.pin_strength, reset_gpio.pin_state);
+ /* reset */
+ for (i = 0; i < RESET_GPIO_SEQ_LEN; i++) {
+ if (resetseq->pin_state[i] == GPIO_STATE_LOW)
+ gpio_set(reset_gpio.pin_id, GPIO_STATE_LOW);
+ else
+ gpio_set(reset_gpio.pin_id, GPIO_STATE_HIGH);
+ mdelay(resetseq->sleep[i]);
+ }
+ lcd_bklt_reg_enable();
+ } else {
+ lcd_bklt_reg_disable();
+ gpio_set(reset_gpio.pin_id, 0);
+ }
+
+ return NO_ERROR;
+}
+
+static void wled_init(struct msm_panel_info *pinfo)
+{
+ struct qpnp_wled_config_data config = {0};
+ struct labibb_desc *labibb;
+ int display_type = 0;
+
+ labibb = pinfo->labibb;
+
+ if (labibb)
+ display_type = labibb->amoled_panel;
+
+ config.display_type = display_type;
+ config.lab_init_volt = 4600000; /* fixed, see pmi register */
+ config.ibb_init_volt = 1400000; /* fixed, see pmi register */
+
+ if (labibb && labibb->force_config) {
+ config.lab_min_volt = labibb->lab_min_volt;
+ config.lab_max_volt = labibb->lab_max_volt;
+ config.ibb_min_volt = labibb->ibb_min_volt;
+ config.ibb_max_volt = labibb->ibb_max_volt;
+ config.pwr_up_delay = labibb->pwr_up_delay;
+ config.pwr_down_delay = labibb->pwr_down_delay;
+ config.ibb_discharge_en = labibb->ibb_discharge_en;
+ } else {
+ /* default */
+ config.pwr_up_delay = 3;
+ config.pwr_down_delay = 3;
+ config.ibb_discharge_en = 1;
+ if (display_type) { /* amoled */
+ config.lab_min_volt = 4600000;
+ config.lab_max_volt = 4600000;
+ config.ibb_min_volt = 4000000;
+ config.ibb_max_volt = 4000000;
+ } else { /* lcd */
+ config.lab_min_volt = 5500000;
+ config.lab_max_volt = 5500000;
+ config.ibb_min_volt = 5500000;
+ config.ibb_max_volt = 5500000;
+ }
+ }
+
+ dprintf(SPEW, "%s: %d %d %d %d %d %d %d %d %d %d\n", __func__,
+ config.display_type,
+ config.lab_min_volt, config.lab_max_volt,
+ config.ibb_min_volt, config.ibb_max_volt,
+ config.lab_init_volt, config.ibb_init_volt,
+ config.pwr_up_delay, config.pwr_down_delay,
+ config.ibb_discharge_en);
+
+
+ /* QPNP WLED init for display backlight */
+ pm8x41_wled_config_slave_id(PMIC_WLED_SLAVE_ID);
+
+ qpnp_wled_init(&config);
+}
+
+int target_ldo_ctrl(uint8_t enable, struct msm_panel_info *pinfo)
+{
+ uint32_t val = BIT(1) | BIT(13) | BIT(27);
+
+ if (enable) {
+ regulator_enable(val);
+ mdelay(10);
+ wled_init(pinfo);
+ qpnp_ibb_enable(true); /* +5V and -5V */
+ mdelay(50);
+
+ if (pinfo->lcd_reg_en)
+ lcd_reg_enable();
+ } else {
+ if (pinfo->lcd_reg_en)
+ lcd_reg_disable();
+
+ regulator_disable(val);
+ }
+
+ return NO_ERROR;
+}
+
+int target_display_pre_on()
+{
+ writel(0xC0000CCC, MDP_CLK_CTRL0);
+ writel(0xC0000CCC, MDP_CLK_CTRL1);
+ writel(0x00CCCCCC, MDP_CLK_CTRL2);
+ writel(0x000000CC, MDP_CLK_CTRL6);
+ writel(0x0CCCC0C0, MDP_CLK_CTRL3);
+ writel(0xCCCCC0C0, MDP_CLK_CTRL4);
+ writel(0xCCCCC0C0, MDP_CLK_CTRL5);
+ writel(0x00CCC000, MDP_CLK_CTRL7);
+
+ return NO_ERROR;
+}
+
+int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db)
+{
+ memcpy(phy_db->strength, panel_strength_ctrl, STRENGTH_SIZE_IN_BYTES_8996 *
+ sizeof(uint32_t));
+ memcpy(phy_db->regulator, panel_regulator_settings,
+ REGULATOR_SIZE_IN_BYTES_8996 * sizeof(uint32_t));
+ memcpy(phy_db->laneCfg, panel_lane_config, LANE_SIZE_IN_BYTES_8996);
+ return NO_ERROR;
+}
+
+
+bool target_display_panel_node(char *panel_name, char *pbuf, uint16_t buf_size)
+{
+ int prefix_string_len = strlen(DISPLAY_CMDLINE_PREFIX);
+ bool ret = true;
+
+ panel_name += strspn(panel_name, " ");
+
+ if (!strcmp(panel_name, HDMI_PANEL_NAME)) {
+ if (buf_size < (prefix_string_len + LK_OVERRIDE_PANEL_LEN +
+ strlen(HDMI_CONTROLLER_STRING))) {
+ dprintf(CRITICAL, "command line argument is greater than buffer size\n");
+ return false;
+ }
+
+ strlcpy(pbuf, DISPLAY_CMDLINE_PREFIX, buf_size);
+ buf_size -= prefix_string_len;
+ strlcat(pbuf, LK_OVERRIDE_PANEL, buf_size);
+ buf_size -= LK_OVERRIDE_PANEL_LEN;
+ strlcat(pbuf, HDMI_CONTROLLER_STRING, buf_size);
+ } else {
+ ret = gcdb_display_cmdline_arg(panel_name, pbuf, buf_size);
+ }
+
+ return ret;
+}
+
+void target_display_init(const char *panel_name)
+{
+ char cont_splash = '\0';
+
+ set_panel_cmd_string(panel_name, &cont_splash);
+ panel_name += strspn(panel_name, " ");
+ if (!strcmp(panel_name, NO_PANEL_CONFIG)
+ || !strcmp(panel_name, SIM_VIDEO_PANEL)
+ || !strcmp(panel_name, SIM_DUALDSI_VIDEO_PANEL)
+ || !strcmp(panel_name, SIM_CMD_PANEL)
+ || !strcmp(panel_name, SIM_DUALDSI_CMD_PANEL)) {
+ dprintf(INFO, "Selected panel: %s\nSkip panel configuration\n",
+ panel_name);
+ return;
+ } else if (!strcmp(panel_name, HDMI_PANEL_NAME)) {
+ return;
+ }
+
+ if (gcdb_display_init(panel_name, MDP_REV_50, (void *)MIPI_FB_ADDR)) {
+ target_force_cont_splash_disable(true);
+ msm_display_off();
+ }
+
+ if (cont_splash == '0') {
+ dprintf(INFO, "Forcing continuous splash disable\n");
+ target_force_cont_splash_disable(true);
+ }
+}
+
+void target_display_shutdown(void)
+{
+ gcdb_display_shutdown();
+}
diff --git a/target/target_display.c b/target/target_display.c
index fb96638..6904825 100644
--- a/target/target_display.c
+++ b/target/target_display.c
@@ -78,6 +78,11 @@
return;
}
+__WEAK int target_dsi_phy_config(struct mdss_dsi_phy_ctrl *phy_db)
+{
+ return 0;
+}
+
__WEAK int target_edp_panel_clock(uint8_t enable, struct msm_panel_info *pinfo)
{
return 0;
@@ -121,3 +126,8 @@
{
return 0;
}
+
+__WEAK int target_display_dsi2hdmi_config(struct msm_panel_info *pinfo)
+{
+ return 0;
+}