int smem_ram_ptable_init_v1() { uint32_t i; uint32_t ret; uint32_t version; uint32_t smem_ram_ptable_size; struct smem_ram_ptable_hdr *ram_ptable_hdr; /* Check smem ram partition table version and decide on length of ram_ptable */ ret = smem_read_alloc_entry_offset(SMEM_USABLE_RAM_PARTITION_TABLE, &version, sizeof(version), SMEM_RAM_PTABLE_VERSION_OFFSET); if(ret) return 0; if(version == SMEM_RAM_PTABLE_VERSION_1) smem_ram_ptable_size = sizeof(struct smem_ram_ptable_v1); else if(version == SMEM_RAM_PTABLE_VERSION_0) smem_ram_ptable_size = sizeof(struct smem_ram_ptable); else { dprintf(CRITICAL,"ERROR: Wrong smem_ram_ptable version: %u", version); ASSERT(0); } i = smem_read_alloc_entry(SMEM_USABLE_RAM_PARTITION_TABLE, (void*)buffer, smem_ram_ptable_size); if (i != 0) return 0; ram_ptable_hdr = (struct smem_ram_ptable_hdr *)buffer; if (ram_ptable_hdr->magic[0] != _SMEM_RAM_PTABLE_MAGIC_1 || ram_ptable_hdr->magic[1] != _SMEM_RAM_PTABLE_MAGIC_2) return 0; smem_copy_ram_ptable((void*)buffer); dprintf(SPEW, "smem ram ptable found: ver: %u len: %u\n", ram_ptable_hdr->version, ram_ptable_hdr->len); return 1; }
unsigned* target_atag_mem(unsigned* ptr) { struct smem_board_info board_info; unsigned int board_info_struct_len = sizeof(board_info); unsigned smem_status; char *build_type; int enable_lpddr2 = 0; smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION, &board_info, board_info_struct_len ); if(smem_status) { dprintf(CRITICAL, "ERROR: unable to read shared memory for build id\n"); } build_type = (char *)(board_info.build_id) + 8; if (*build_type == 'A') { enable_lpddr2 = 1; } if(enable_lpddr2) { /* ATAG_MEM for 123MB + 67MB setup */ *ptr++ = 4; *ptr++ = 0x54410002; *ptr++ = EBI1_SIZE_123M; *ptr++ = EBI1_ADDR1; /* ATAG_MEM */ *ptr++ = 4; *ptr++ = 0x54410002; *ptr++ = EBI1_SIZE_67M; *ptr++ = EBI1_ADDR2; } else { /* ATAG_MEM for 190MB setup*/ *ptr++ = 4; *ptr++ = 0x54410002; *ptr++ = EBI1_SIZE_190M; *ptr++ = EBI1_ADDR1; } return ptr; }
/** * smem_ptable_init - initializes SMEM partition table * * Initialize partition table from SMEM. */ int smem_ptable_init(void) { unsigned ret; ret = smem_read_alloc_entry(SMEM_AARM_PARTITION_TABLE, &smem_ptable, sizeof(smem_ptable)); if (ret != 0) return -ENOMSG; if (smem_ptable.magic[0] != _SMEM_PTABLE_MAGIC_1 || smem_ptable.magic[1] != _SMEM_PTABLE_MAGIC_2) return -ENOMSG; debug("smem ptable found: ver: %d len: %d\n", smem_ptable.version, smem_ptable.len); return 0; }
/* RAM Partition table from SMEM */ int smem_ram_ptable_init(struct smem_ram_ptable *smem_ram_ptable) { unsigned i; i = smem_read_alloc_entry(SMEM_USABLE_RAM_PARTITION_TABLE, smem_ram_ptable, sizeof(struct smem_ram_ptable)); if (i != 0) return 0; if (smem_ram_ptable->magic[0] != _SMEM_RAM_PTABLE_MAGIC_1 || smem_ram_ptable->magic[1] != _SMEM_RAM_PTABLE_MAGIC_2) return 0; dprintf(INFO, "smem ram ptable found: ver: %d len: %d\n", smem_ram_ptable->version, smem_ram_ptable->len); return 1; }
int smd_init(smd_channel_info_t *ch, uint32_t ch_type) { unsigned ret = 0; int chnl_found = 0; uint64_t timeout = SMD_CHANNEL_ACCESS_RETRY; smd_channel_alloc_entry = (smd_channel_alloc_entry_t*)memalign(CACHE_LINE, SMD_CHANNEL_ALLOC_MAX); ASSERT(smd_channel_alloc_entry); dprintf(INFO, "Waiting for the RPM to populate smd channel table\n"); do { ret = smem_read_alloc_entry(SMEM_CHANNEL_ALLOC_TBL, (void*)smd_channel_alloc_entry, SMD_CHANNEL_ALLOC_MAX); if(ret) { dprintf(CRITICAL,"ERROR reading smem channel alloc tbl\n"); return -1; } chnl_found = smd_get_channel_info(ch, ch_type); timeout--; udelay(10); } while(timeout && chnl_found); if (!timeout) { dprintf(CRITICAL, "Apps timed out waiting for RPM-->APPS channel entry\n"); ASSERT(0); } register_int_handler(SMD_IRQ, smd_irq_handler, ch); smd_set_state(ch, SMD_SS_OPENING, 1); smd_notify_rpm(); unmask_interrupt(SMD_IRQ); return 0; }
int target_is_interleaved_mode(void) { struct smem_board_info_v4 board_info_v4; unsigned int board_info_len = 0; unsigned smem_status; char *build_type; unsigned format = 0; if (interleaved_mode_enabled != -1) { return interleaved_mode_enabled; } smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION, &format, sizeof(format), 0); if(!smem_status) { if ((format == 3) || (format == 4)) { if (format == 4) board_info_len = sizeof(board_info_v4); else board_info_len = sizeof(board_info_v4.board_info_v3); smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION, &board_info_v4, board_info_len); if(!smem_status) { build_type = (char *)(board_info_v4.board_info_v3.build_id) + 9; interleaved_mode_enabled = 0; if (*build_type == 'C') { interleaved_mode_enabled = 1; } } } } return interleaved_mode_enabled; }
uint32_t board_machtype(void) { struct smem_board_info_v6 board_info_v6; uint32_t board_info_len = 0; uint32_t smem_status = 0; uint32_t format = 0; uint32_t id = HW_PLATFORM_UNKNOWN; uint32_t mach_id; smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION, &format, sizeof(format), 0); if(!smem_status) { if (format == 6) { board_info_len = sizeof(board_info_v6); smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION, &board_info_v6, board_info_len); if(!smem_status) { id = board_info_v6.board_info_v3.hw_platform; } } } /* Detect the board we are running on */ switch(id) { /* APQ8064 machine id not yet defined for CDP etc. * default to simulator. */ case HW_PLATFORM_SURF: case HW_PLATFORM_FFA: case HW_PLATFORM_FLUID: default: mach_id = LINUX_MACHTYPE_APQ8064_SIM; }; return mach_id; }
unsigned board_machtype(void) { struct smem_board_info_v2 board_info_v2; unsigned int board_info_len = 0; enum platform platform_type = 0; unsigned smem_status; unsigned format = 0; if(hw_platform_type != -1) return hw_platform_type; smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION, &format, sizeof(format), 0); if(!smem_status) { if(format == 2) { board_info_len = sizeof(board_info_v2); smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION, &board_info_v2, board_info_len); if(!smem_status) { char *build_type = (char *)(board_info_v2.build_id)+ 12; switch (*build_type) { case 'F': hw_platform_type = LINUX_MACHTYPE_7x27_FFA; break; case 'S': hw_platform_type = LINUX_MACHTYPE_7x27_SURF; break; default: hw_platform_type = LINUX_MACHTYPE_7x27_SURF; break; } } } } else { hw_platform_type = LINUX_MACHTYPE_7x27_SURF; } return hw_platform_type; }
int get_boot_info_apps (char type, unsigned int *status) { boot_info_for_apps apps_boot_info; int ret = 0; ret = smem_read_alloc_entry(SMEM_BOOT_INFO_FOR_APPS, &apps_boot_info, sizeof(apps_boot_info)); if (ret) { dprintf(CRITICAL, "ERROR: unable to read shared memory for apps boot info %d\n",ret); return ret; } dprintf(INFO,"boot flag %x update status %x\n",apps_boot_info.boot_flags, apps_boot_info.status.update_status); if(type == BOOT_FLAGS) *status = apps_boot_info.boot_flags; else if(type == UPDATE_STATUS) *status = apps_boot_info.status.update_status; return ret; }
void board_info(void) { struct smem_board_info_v4 board_info_v4; unsigned int board_info_len = 0; unsigned smem_status; unsigned format = 0; unsigned id = 0; if (hw_platform && target_msm_id) return; hw_platform = MSM7X27A_SURF; target_msm_id = MSM7225A; smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION, &format, sizeof(format), 0); if (!smem_status) { if (format == 4) { board_info_len = sizeof(board_info_v4); smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION, &board_info_v4, board_info_len); if (!smem_status) { id = board_info_v4.board_info_v3.hw_platform; target_msm_id = board_info_v4.board_info_v3.msm_id; msm_version = board_info_v4.board_info_v3.msm_version; } } /* Detect SURF v/s FFA v/s QRD */ if (target_msm_id >= MSM8225 && target_msm_id <= MSM8625 || (target_msm_id == MSM8125A)) { switch (id) { case 0x1: hw_platform = MSM8X25_SURF; break; case 0x2: hw_platform = MSM8X25_FFA; break; case 0x10: hw_platform = MSM8X25_EVT; break; case 0xC: hw_platform = MSM8X25_EVB; break; case 0xF: hw_platform = MSM8X25_QRD7; break; default: hw_platform = MSM8X25_SURF; } } else { switch (id) { case 0x1: /* Set the machine type based on msm ID */ if (msm_is_7x25a(target_msm_id)) hw_platform = MSM7X25A_SURF; else hw_platform = MSM7X27A_SURF; break; case 0x2: if (msm_is_7x25a(target_msm_id)) hw_platform = MSM7X25A_FFA; else hw_platform = MSM7X27A_FFA; break; case 0xB: if(target_is_emmc_boot()) hw_platform = MSM7X27A_QRD1; else hw_platform = MSM7X27A_QRD3; break; case 0xC: hw_platform = MSM7X27A_EVB; break; case 0xF: hw_platform = MSM7X27A_QRD3; break; default: if (msm_is_7x25a(target_msm_id)) hw_platform = MSM7X25A_SURF; else hw_platform = MSM7X27A_SURF; }; } /* Set msm ID for target variants based on values read from smem */ switch (target_msm_id) { case MSM7225A: case MSM7625A: case ESM7225A: case MSM7225AA: case MSM7625AA: case ESM7225AA: case MSM7225AB: case MSM7625AB: case ESM7225AB: case MSM7125A: target_msm_id = MSM7625A; break; case MSM8225: case MSM8625: case MSM8125A: target_msm_id = MSM8625; break; default: target_msm_id = MSM7627A; } } return; }
unsigned board_machtype(void) { struct smem_board_info_v5 board_info_v5; struct smem_board_info_v6 board_info_v6; unsigned int board_info_len = 0; unsigned smem_status = 0; unsigned format = 0; unsigned id = 0; unsigned hw_platform = 0; unsigned fused_chip = 0; unsigned platform_subtype = 0; static unsigned mach_id = 0xFFFFFFFF; if (mach_id != 0xFFFFFFFF) return mach_id; /* Detect external msm if this is a "fusion" */ smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION, &format, sizeof(format), 0); if (!smem_status) { if (format == 5) { board_info_len = sizeof(board_info_v5); smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION, &board_info_v5, board_info_len); if (!smem_status) { fused_chip = board_info_v5.fused_chip; id = board_info_v5.board_info_v3.hw_platform; } } else if (format == 6) { board_info_len = sizeof(board_info_v6); smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION, &board_info_v6, board_info_len); if (!smem_status) { fused_chip = board_info_v6.fused_chip; id = board_info_v6.board_info_v3.hw_platform; platform_subtype = board_info_v6.platform_subtype; } } } /* Detect SURF v/s FFA v/s Fluid */ switch (id) { case 0x1: hw_platform = HW_PLATFORM_SURF; break; case 0x2: hw_platform = HW_PLATFORM_FFA; break; case 0x3: hw_platform = HW_PLATFORM_FLUID; break; case 0x6: hw_platform = HW_PLATFORM_QT; break; case 0xA: hw_platform = HW_PLATFORM_DRAGON; break; default: /* Writing to Debug LED register and reading back to auto detect SURF and FFA. If we read back, it is SURF */ debug_led_write(0xA5); if ((debug_led_read() & 0xFF) == 0xA5) { debug_led_write(0); hw_platform = HW_PLATFORM_SURF; } else hw_platform = HW_PLATFORM_FFA; }; /* Use platform_subtype or fused_chip information to determine machine id */ if (format >= 6) { switch (platform_subtype) { case HW_PLATFORM_SUBTYPE_CSFB: case HW_PLATFORM_SUBTYPE_SVLTE2A: if (hw_platform == HW_PLATFORM_SURF) mach_id = LINUX_MACHTYPE_8660_CHARM_SURF; else if (hw_platform == HW_PLATFORM_FFA) mach_id = LINUX_MACHTYPE_8660_CHARM_FFA; break; default: if (hw_platform == HW_PLATFORM_SURF) mach_id = LINUX_MACHTYPE_8660_SURF; else if (hw_platform == HW_PLATFORM_FFA) mach_id = LINUX_MACHTYPE_8660_FFA; else if (hw_platform == HW_PLATFORM_FLUID) mach_id = LINUX_MACHTYPE_8660_FLUID; else if (hw_platform == HW_PLATFORM_QT) mach_id = LINUX_MACHTYPE_8660_QT; else if (hw_platform == HW_PLATFORM_DRAGON) mach_id = LINUX_MACHTYPE_8x60_DRAGON; } } else if (format == 5) { switch (fused_chip) { case UNKNOWN: if (hw_platform == HW_PLATFORM_SURF) mach_id = LINUX_MACHTYPE_8660_SURF; else if (hw_platform == HW_PLATFORM_FFA) mach_id = LINUX_MACHTYPE_8660_FFA; else if (hw_platform == HW_PLATFORM_FLUID) mach_id = LINUX_MACHTYPE_8660_FLUID; else if (hw_platform == HW_PLATFORM_QT) mach_id = LINUX_MACHTYPE_8660_QT; else if (hw_platform == HW_PLATFORM_DRAGON) mach_id = LINUX_MACHTYPE_8x60_DRAGON; break; case MDM9200: case MDM9600: if (hw_platform == HW_PLATFORM_SURF) mach_id = LINUX_MACHTYPE_8660_CHARM_SURF; else if (hw_platform == HW_PLATFORM_FFA) mach_id = LINUX_MACHTYPE_8660_CHARM_FFA; break; default: mach_id = LINUX_MACHTYPE_8660_FFA; } } return mach_id; }
void smem_ptable_init(void) { unsigned i; unsigned ret; unsigned len = 0; /* Read only the header portion of ptable */ ret = smem_read_alloc_entry_offset(SMEM_AARM_PARTITION_TABLE, &smem_ptable, SMEM_PTABLE_HDR_LEN, 0); if (ret) { dprintf(CRITICAL, "Failed to read ptable hdr (%d)", ret); ASSERT(0); } /* Verify ptable magic */ if (smem_ptable.magic[0] != _SMEM_PTABLE_MAGIC_1 || smem_ptable.magic[1] != _SMEM_PTABLE_MAGIC_2) return; /* Ensure that # of partitions is less than the max we have allocated. */ ASSERT(smem_ptable.len <= SMEM_PTABLE_MAX_PARTS); /* Find out length of partition data based on table version. */ if (smem_ptable.version <= 3) { len = SMEM_PTABLE_HDR_LEN + SMEM_PTABLE_MAX_PARTS_V3*sizeof(struct smem_ptn); } else if (smem_ptable.version == 4) { len = SMEM_PTABLE_HDR_LEN + SMEM_PTABLE_MAX_PARTS_V4*sizeof(struct smem_ptn); } else { dprintf(CRITICAL, "Unknown ptable version (%d)", smem_ptable.version); ASSERT(0); } ret = smem_read_alloc_entry(SMEM_AARM_PARTITION_TABLE, &smem_ptable, len); if (ret) { dprintf(CRITICAL, "Failed to read ptable (%d)", ret); ASSERT(0); } dump_smem_ptable(); dprintf(INFO, "smem ptable found: ver: %d len: %d\n", smem_ptable.version, smem_ptable.len); for (i = 0; i < smem_ptable.len; i++) { if (!strcmp(smem_ptable.parts[i].name, "0:APPS")) break; } if (i == smem_ptable.len) return; smem_apps_flash_start = smem_ptable.parts[i].start; }
void board_info(void) { struct smem_board_info_v4 board_info_v4; unsigned int board_info_len = 0; unsigned smem_status; unsigned format = 0; unsigned id = 0; if (hw_platform && target_msm_id) return; hw_platform = MSM7X27A_SURF; target_msm_id = MSM7225A; smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION, &format, sizeof(format), 0); if (!smem_status) { if (format == 4) { board_info_len = sizeof(board_info_v4); smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION, &board_info_v4, board_info_len); if (!smem_status) { id = board_info_v4.board_info_v3.hw_platform; target_msm_id = board_info_v4.board_info_v3.msm_id; msm_version = board_info_v4.board_info_v3.msm_version; platform_version = board_info_v4.platform_version; } } /* Detect SURF v/s FFA v/s QRD */ if (target_msm_id >= MSM8225 && target_msm_id <= MSM8625 || (target_msm_id == MSM8125A) || (target_msm_id == MSM8125)) { switch (id) { case 0x1: hw_platform = MSM8X25_SURF; BOARD_NAME(target_msm_id, "SURF"); break; case 0x2: hw_platform = MSM8X25_FFA; BOARD_NAME(target_msm_id, "FFA"); break; case 0x10: case 0x60000000: /* Linux kernel use the id as the array index, change 0x60000000 to 0xA2 */ case 0xA2: hw_platform = MSM8X25_QRD5; BOARD_NAME(target_msm_id, "QRD5"); break; case 0xC: hw_platform = MSM8X25_EVB; BOARD_NAME(target_msm_id, "EVB"); break; case 0xA0: hw_platform = MSM8X25_SKUA; BOARD_NAME(target_msm_id, "SKUA"); break; case 0xA6: hw_platform = MSM8X25_SKUB; BOARD_NAME(target_msm_id, "SKUB"); break; case 0xA7: hw_platform = MSM8X25Q_SKUD; BOARD_NAME(target_msm_id, "SKUD"); break; case 0xA8: hw_platform = MSM8X25Q_SKUE; BOARD_NAME(target_msm_id, "SKUE"); break; case 0xF: hw_platform = MSM8X25_QRD7; BOARD_NAME(target_msm_id, "QRD7"); break; default: hw_platform = MSM8X25_SURF; BOARD_NAME(target_msm_id, "SURF"); } } else { switch (id) { case 0x1: /* Set the machine type based on msm ID */ if (msm_is_7x25a(target_msm_id)) hw_platform = MSM7X25A_SURF; else hw_platform = MSM7X27A_SURF; BOARD_NAME(target_msm_id, "SURF"); break; case 0x2: if (msm_is_7x25a(target_msm_id)) hw_platform = MSM7X25A_FFA; else hw_platform = MSM7X27A_FFA; BOARD_NAME(target_msm_id, "FFA"); break; case 0xB: if(target_is_emmc_boot()) hw_platform = MSM7X27A_QRD1; BOARD_NAME(target_msm_id, "QRD1"); hw_platform = MSM7X27A_QRD3; break; case 0xC: hw_platform = MSM7X27A_EVB; BOARD_NAME(target_msm_id, "EVB"); break; case 0xF: hw_platform = MSM7X27A_QRD3; BOARD_NAME(target_msm_id, "QRD3"); break; case 0xA2: hw_platform = MSM7X27A_QRD5A; BOARD_NAME(target_msm_id, "QRD5A"); break; default: if (msm_is_7x25a(target_msm_id)) hw_platform = MSM7X25A_SURF; else hw_platform = MSM7X27A_SURF; BOARD_NAME(target_msm_id, "SURF"); }; } /* Set msm ID for target variants based on values read from smem */ switch (target_msm_id) { case MSM7225A: case MSM7625A: case ESM7225A: case MSM7225AA: case MSM7625AA: case ESM7225AA: case MSM7225AB: case MSM7625AB: case ESM7225AB: case MSM7125A: target_msm_id = MSM7625A; break; case MSM8225: case MSM8625: case MSM8125A: case MSM8125: target_msm_id = MSM8625; break; default: target_msm_id = MSM7627A; } } dprintf(INFO, "LK:hardware_id %d,hw_platform %d, target_msm_id %d\n", id, hw_platform, target_msm_id); return; }
void target_detect(void) { struct smem_board_info_v6 board_info_v6; unsigned int board_info_len = 0; unsigned smem_status = 0; unsigned format = 0; unsigned id = HW_PLATFORM_UNKNOWN; smem_status = smem_read_alloc_entry_offset(SMEM_BOARD_INFO_LOCATION, &format, sizeof(format), 0); if (!smem_status) { if (format == 6) { board_info_len = sizeof(board_info_v6); smem_status = smem_read_alloc_entry(SMEM_BOARD_INFO_LOCATION, &board_info_v6, board_info_len); if (!smem_status) { id = board_info_v6.board_info_v3.hw_platform; } } } platform_id = board_info_v6.board_info_v3.msm_id; /* Detect the board we are running on */ if ((platform_id == MSM8960) || (platform_id == MSM8660A) || (platform_id == MSM8260A) || (platform_id == APQ8060A)) { switch (id) { case HW_PLATFORM_SURF: target_id = LINUX_MACHTYPE_8960_CDP; break; case HW_PLATFORM_MTP: target_id = LINUX_MACHTYPE_8960_MTP; break; case HW_PLATFORM_FLUID: target_id = LINUX_MACHTYPE_8960_FLUID; break; case HW_PLATFORM_LIQUID: target_id = LINUX_MACHTYPE_8960_LIQUID; break; default: target_id = LINUX_MACHTYPE_8960_CDP; } } else if ((platform_id == MSM8230) || (platform_id == MSM8630) || (platform_id == MSM8930) || (platform_id == APQ8030)) { switch (id) { case HW_PLATFORM_SURF: target_id = LINUX_MACHTYPE_8930_CDP; break; case HW_PLATFORM_MTP: target_id = LINUX_MACHTYPE_8930_MTP; break; case HW_PLATFORM_FLUID: target_id = LINUX_MACHTYPE_8930_FLUID; break; default: target_id = LINUX_MACHTYPE_8930_CDP; } } else if ((platform_id == MSM8227) || (platform_id == MSM8627)) { switch (id) { case HW_PLATFORM_SURF: target_id = LINUX_MACHTYPE_8627_CDP; break; case HW_PLATFORM_MTP: target_id = LINUX_MACHTYPE_8627_MTP; break; default: target_id = LINUX_MACHTYPE_8627_CDP; } } else if (platform_id == APQ8064) { switch (id) { case HW_PLATFORM_SURF: target_id = LINUX_MACHTYPE_8064_SIM; break; default: target_id = LINUX_MACHTYPE_8064_RUMI3; } } else { dprintf(CRITICAL, "platform_id (%d) is not identified.\n", platform_id); ASSERT(0); } }