コード例 #1
0
ファイル: dev_tree.c プロジェクト: Heart-travel/lk
static uint32_t dev_tree_compatible(void *dtb)
{
	int root_offset;
	const void *prop;
	char model[128];
	struct msm_id msm_id;
	int len;

	root_offset = fdt_path_offset(dtb, "/");
	if (root_offset < 0)
		return false;

	prop = fdt_getprop(dtb, root_offset, "model", &len);
	if (prop && len > 0) {
		memcpy(model, prop, MIN((int)sizeof(model), len));
		model[sizeof(model) - 1] = '\0';
	} else {
		model[0] = '\0';
	}

	prop = fdt_getprop(dtb, root_offset, "qcom,msm-id", &len);
	if (!prop || len <= 0) {
		dprintf(INFO, "qcom,msm-id entry not found\n");
		return false;
	} else if (len < (int)sizeof(struct msm_id)) {
		dprintf(INFO, "qcom,msm-id entry size mismatch (%d != %d)\n",
			len, sizeof(struct msm_id));
		return false;
	}
	msm_id.platform_id = fdt32_to_cpu(((const struct msm_id *)prop)->platform_id);
	msm_id.hardware_id = fdt32_to_cpu(((const struct msm_id *)prop)->hardware_id);
	msm_id.soc_rev = fdt32_to_cpu(((const struct msm_id *)prop)->soc_rev);

	dprintf(INFO, "Found an appended flattened device tree (%s - %d %d 0x%x)\n",
		*model ? model : "unknown",
		msm_id.platform_id, msm_id.hardware_id, msm_id.soc_rev);

	if (msm_id.platform_id != board_platform_id() ||
		msm_id.hardware_id != board_hardware_id()) {
		dprintf(INFO, "Device tree's msm_id doesn't match the board: <%d %d 0x%x> != <%d %d 0x%x>\n",
			msm_id.platform_id,
			msm_id.hardware_id,
			msm_id.soc_rev,
			board_platform_id(),
			board_hardware_id(),
			board_soc_version());
		return INVALID_SOC_REV_ID;
	}

	dprintf(INFO, "Device tree's msm_id matches the board: <%d %d 0x%x> == <%d %d 0x%x>\n",
		msm_id.platform_id,
		msm_id.hardware_id,
		msm_id.soc_rev,
		board_platform_id(),
		board_hardware_id(),
		board_soc_version());
	return msm_id.soc_rev;
}
コード例 #2
0
ファイル: init.c プロジェクト: nx511j-multirom/bootloader_lk
void reboot_device(unsigned reboot_reason)
{
	uint32_t soc_ver = 0;
	uint8_t reset_type = 0;

	soc_ver = board_soc_version();

	/* Write the reboot reason */
	if (platform_is_8974() && BOARD_SOC_VERSION1(soc_ver))
		writel(reboot_reason, RESTART_REASON_ADDR);
	else
		writel(reboot_reason, RESTART_REASON_ADDR_V2);

	if(reboot_reason == FASTBOOT_MODE)
		reset_type = PON_PSHOLD_WARM_RESET;
	else
		reset_type = PON_PSHOLD_HARD_RESET;

	/* Configure PMIC for warm reset */
	if (platform_is_8974() && (pmic_ver == PM8X41_VERSION_V2))
		pm8x41_v2_reset_configure(reset_type);
	else
		pm8x41_reset_configure(reset_type);

	/* Drop PS_HOLD for MSM */
	writel(0x00, MPM2_MPM_PS_HOLD);

	mdelay(5000);

	dprintf(CRITICAL, "Rebooting failed\n");
}
コード例 #3
0
/*
 * Function to set the capabilities for the host
 */
void target_mmc_caps(struct mmc_host *host)
{
	uint32_t soc_ver = 0;

	soc_ver = board_soc_version();

	/*
	 * 8974 v1 fluid devices, have a hardware bug
	 * which limits the bus width to 4 bit.
	 */
	switch(board_hardware_id())
	{
		case HW_PLATFORM_FLUID:
			if (soc_ver >= BOARD_SOC_VERSION2)
				host->caps.bus_width = MMC_BOOT_BUS_WIDTH_8_BIT;
			else
				host->caps.bus_width = MMC_BOOT_BUS_WIDTH_4_BIT;
			break;
		default:
			host->caps.bus_width = MMC_BOOT_BUS_WIDTH_8_BIT;
	};

	host->caps.ddr_mode = 1;
	host->caps.hs200_mode = 1;
	host->caps.hs_clk_rate = MMC_CLK_96MHZ;
}
コード例 #4
0
void reboot_device(unsigned reboot_reason)
{
	uint32_t soc_ver = 0;

	soc_ver = board_soc_version();

	/* Write the reboot reason */
	if (soc_ver >= BOARD_SOC_VERSION2)
		writel(reboot_reason, RESTART_REASON_ADDR_V2);
	else
		writel(reboot_reason, RESTART_REASON_ADDR);

	/* Configure PMIC for warm reset */
	pm8x41_reset_configure(PON_PSHOLD_WARM_RESET);

	/* Disable Watchdog Debug.
	 * Required becuase of a H/W bug which causes the system to
	 * reset partially even for non watchdog resets.
	 */
	writel(readl(GCC_WDOG_DEBUG) & ~(1 << WDOG_DEBUG_DISABLE_BIT), GCC_WDOG_DEBUG);

	dsb();

	/* Wait until the write takes effect. */
	while(readl(GCC_WDOG_DEBUG) & (1 << WDOG_DEBUG_DISABLE_BIT));

	/* Drop PS_HOLD for MSM */
	writel(0x00, MPM2_MPM_PS_HOLD);

	mdelay(5000);

	dprintf(CRITICAL, "Rebooting failed\n");
}
コード例 #5
0
/* workaround_12 as described in HPG */
void dwc_ss_phy_workaround_12(dwc_dev_t *dev)
{
	/* 12. */
	if ( platform_is_8974() &&
		 (board_soc_version() < BOARD_SOC_VERSION2))
	{
		REG_WRITEI(dev, GUSB3PIPECTL, 0, 0x30C0003);
	}
}
コード例 #6
0
void usb_wrapper_workaround_10(usb_wrapper_dev_t *dev)
{
	/* 10. */
	if ( (board_platform_id() == MSM8974) &&
		 (board_soc_version() < BOARD_SOC_VERSION2))
	{
		REG_WRITE(dev, GENERAL_CFG, 0x78);
	}
}
コード例 #7
0
ファイル: platform.c プロジェクト: KortanZ/linux
uint32_t platform_is_msm8976_v_1_1()
{
	uint32_t soc_ver = board_soc_version();
	uint32_t ret = 0;

	if(soc_ver == MSM8976_SOC_V11)
		ret = 1;

	return ret;
}
コード例 #8
0
addr_t get_bs_info_addr()
{
	uint32_t soc_ver = board_soc_version();

	if (soc_ver < BOARD_SOC_VERSION2)
		return ((addr_t)BS_INFO_ADDR_V1);
	else
		return ((addr_t)BS_INFO_ADDR_V2);

}
コード例 #9
0
ファイル: dev_tree.c プロジェクト: Heart-travel/lk
static int platform_dt_match(struct dt_entry *cur_dt_entry, uint32_t target_variant_id, uint32_t subtype_mask)
{
	/* 1. must match the platform_id, hardware_id, platform_version
	*  2. soc rev number equal then return 0
	*  3. dt soc rev number less than cdt return -1
	*  4. otherwise return 1
	*/
	uint32_t cur_dt_target_id ;

	cur_dt_target_id  = cur_dt_entry->variant_id | ((cur_dt_entry->board_hw_subtype & subtype_mask & 0xff) << 24);

	if((cur_dt_entry->platform_id == board_platform_id()) &&
		(cur_dt_target_id == target_variant_id)) {
		if(cur_dt_entry->soc_rev == board_soc_version()) {
			return 0;
		} else if(cur_dt_entry->soc_rev < board_soc_version()) {
			return -1;
		}
	}

	return 1;
}
コード例 #10
0
/* Function to return the pointer to the start of the correct device tree
 *  based on the platform data.
 */
struct dt_entry * dev_tree_get_entry_ptr(struct dt_table *table)
{
	uint32_t i;
	struct dt_entry *dt_entry_ptr;
	struct dt_entry *latest_dt_entry = NULL;

	dt_entry_ptr = (struct dt_entry *)((char *)table + DEV_TREE_HEADER_SIZE);

	for(i = 0; i < table->num_entries; i++)
	{
		/* DTBs are stored in the ascending order of soc revision.
		 * For eg: Rev0..Rev1..Rev2 & so on.
		 * we pickup the DTB with highest soc rev number which is less
		 * than or equal to actual hardware
		 */
		if((dt_entry_ptr->platform_id == board_platform_id()) &&
		   (dt_entry_ptr->variant_id == board_hardware_id()) &&
		   (dt_entry_ptr->soc_rev == board_soc_version()))
			{
				return dt_entry_ptr;
			}
		/* if the exact match not found, return the closest match
		 * assuming it to be the nearest soc version
		 */
		if((dt_entry_ptr->platform_id == board_platform_id()) &&
		  (dt_entry_ptr->variant_id == board_hardware_id()) &&
		  (dt_entry_ptr->soc_rev <= board_soc_version())) {
			latest_dt_entry = dt_entry_ptr;
		}
		dt_entry_ptr++;
	}

	if (latest_dt_entry) {
		dprintf(SPEW, "Loading DTB with SOC version:%x\n", latest_dt_entry->soc_rev);
		return latest_dt_entry;
	}

	return NULL;
}
コード例 #11
0
ファイル: platform.c プロジェクト: KortanZ/linux
uint32_t platform_boot_config()
{
	uint32_t boot_config;

	if (platform_is_mdmcalifornium())
		boot_config = BOOT_CONFIG_REG_V2;
	/* Else the platform is 9x45 */
	else if (board_soc_version() >= 0x20000)
		boot_config = BOOT_CONFIG_REG_V2;
	else
		boot_config = BOOT_CONFIG_REG_V1;

	return boot_config;
}
コード例 #12
0
/*  AXI master config */
void dwc_axi_master_config(dwc_dev_t *dev)
{
	uint32_t reg = 0;

	/* 17. */
	if ( platform_is_8974() &&
		 (board_soc_version() < BOARD_SOC_VERSION2))
	{
		reg = (DWC_GSBUSCFG0_INCR4BRSTENA_BMSK |
			   DWC_GSBUSCFG0_INCR8BRSTENA_BMSK |
			   DWC_GSBUSCFG0_INCR16BRSTENA_BMSK);

		REG_WRITE(dev, GSBUSCFG0, reg);
	}
}
コード例 #13
0
/* configure SS phy as specified in HPG */
void usb_wrapper_ss_phy_configure(usb_wrapper_dev_t *dev)
{
	/* 4.a */
	REG_WRITE_FIELD(dev, SS_PHY_CTRL, REF_USE_PAD, 1);
	/* .b */
	REG_WRITE_FIELD(dev, SS_PHY_CTRL, LANE0_PWR_PRESENT, 1);
	/* .c */
	REG_WRITE_FIELD(dev, SS_PHY_CTRL, REF_SS_PHY_EN, 1);

	/* For Aragorn V1, reset value fix is required.*/
	if ( (board_platform_id() == MSM8974) &&
		 (board_soc_version() < BOARD_SOC_VERSION2))
	{
		REG_WRITE_FIELD(dev, SS_PHY_CTRL, SSC_REF_CLK_SEL, 0x108);
	}
}
コード例 #14
0
unsigned check_reboot_mode(void)
{
	uint32_t restart_reason = 0;
	uint32_t soc_ver = 0;
	uint32_t restart_reason_addr;

	soc_ver = board_soc_version();

	if (soc_ver >= BOARD_SOC_VERSION2)
		restart_reason_addr = RESTART_REASON_ADDR_V2;
	else
		restart_reason_addr = RESTART_REASON_ADDR;

	/* Read reboot reason and scrub it */
	restart_reason = readl(restart_reason_addr);
	writel(0x00, restart_reason_addr);

	return restart_reason;
}
コード例 #15
0
static target_mmc_sdhci_init()
{
	struct mmc_config_data config;
	uint32_t soc_ver = 0;

	/* Enable sdhci mode */
	sdhci_mode_enable(1);

	soc_ver = board_soc_version();

	/*
	 * 8974 v1 fluid devices, have a hardware bug
	 * which limits the bus width to 4 bit.
	 */
	switch(board_hardware_id())
	{
		case HW_PLATFORM_FLUID:
			if (soc_ver >= BOARD_SOC_VERSION2)
				config.bus_width = DATA_BUS_WIDTH_8BIT;
			else
				config.bus_width = DATA_BUS_WIDTH_4BIT;
			break;
		default:
			config.bus_width = DATA_BUS_WIDTH_8BIT;
	};

	config.max_clk_rate = MMC_CLK_200MHZ;

	/* Trying Slot 1*/
	config.slot = 1;
	config.base = mmc_sdhci_base[config.slot - 1];

	if (!(dev = mmc_init(&config))) {
		/* Trying Slot 2 next */
		config.slot = 2;
		config.base = mmc_sdhci_base[config.slot - 1];
		if (!(dev = mmc_init(&config))) {
			dprintf(CRITICAL, "mmc init failed!");
			ASSERT(0);
		}
	}
}
コード例 #16
0
ファイル: dev_tree.c プロジェクト: Heart-travel/lk
/*
 * Will relocate the DTB to the tags addr if the device tree is found and return
 * its address
 *
 * Arguments:    kernel - Start address of the kernel loaded in RAM
 *               tags - Start address of the tags loaded in RAM
 *               kernel_size - Size of the kernel in bytes
 *
 * Return Value: DTB address : If appended device tree is found
 *               'NULL'         : Otherwise
 */
void *dev_tree_appended(void *kernel, uint32_t kernel_size, void *tags)
{
	void *kernel_end = kernel + kernel_size;
	uint32_t app_dtb_offset = 0;
	void *dtb;
	void *bestmatch_tag = NULL;
	uint32_t bestmatch_tag_size;
	uint32_t bestmatch_soc_rev_id = INVALID_SOC_REV_ID;

	memcpy((void*) &app_dtb_offset, (void*) (kernel + DTB_OFFSET), sizeof(uint32_t));

	dtb = kernel + app_dtb_offset;
	while (dtb + sizeof(struct fdt_header) < kernel_end) {
		uint32_t dtb_soc_rev_id;
		struct fdt_header dtb_hdr;
		uint32_t dtb_size;

		/* the DTB could be unaligned, so extract the header,
		 * and operate on it separately */
		memcpy(&dtb_hdr, dtb, sizeof(struct fdt_header));
		if (fdt_check_header((const void *)&dtb_hdr) != 0 ||
		    (dtb + fdt_totalsize((const void *)&dtb_hdr) > kernel_end))
			break;
		dtb_size = fdt_totalsize(&dtb_hdr);

		if (check_aboot_addr_range_overlap(tags, dtb_size)) {
			dprintf(CRITICAL, "Tags addresses overlap with aboot addresses.\n");
			return NULL;
		}

		/* now that we know we have a valid DTB, we need to copy
		 * it somewhere aligned, like tags */
		memcpy(tags, dtb, dtb_size);

		dtb_soc_rev_id = dev_tree_compatible(tags);
		if (dtb_soc_rev_id == board_soc_version()) {
			/* clear out the old DTB magic so kernel doesn't find it */
			*((uint32_t *)(kernel + app_dtb_offset)) = 0;
			return tags;
		} else if ((dtb_soc_rev_id != INVALID_SOC_REV_ID) &&
				   (dtb_soc_rev_id < board_soc_version())) {
			/* if current bestmatch is less than new dtb_soc_rev_id then update
			   bestmatch_tag */
			if((bestmatch_soc_rev_id == INVALID_SOC_REV_ID) ||
			   (bestmatch_soc_rev_id < dtb_soc_rev_id)) {
				bestmatch_tag = dtb;
				bestmatch_tag_size = dtb_size;
				bestmatch_soc_rev_id = dtb_soc_rev_id;
			}
		}

		/* goto the next device tree if any */
		dtb += dtb_size;
	}

	if(bestmatch_tag) {
		dprintf(INFO,"DTB found with bestmatch soc rev id 0x%x.Board soc rev id 0x%x\n",
				bestmatch_soc_rev_id, board_soc_version());
		memcpy(tags, bestmatch_tag, bestmatch_tag_size);
		/* clear out the old DTB magic so kernel doesn't find it */
		*((uint32_t *)(kernel + app_dtb_offset)) = 0;
		return tags;
	}

	dprintf(CRITICAL, "DTB offset is incorrect, kernel image does not have appended DTB\n");

	return NULL;
}
コード例 #17
0
ファイル: dev_tree.c プロジェクト: Heart-travel/lk
static int __dev_tree_get_entry_info(struct dt_table *table, struct dt_entry *dt_entry_info,
										uint32_t target_variant_id, uint32_t subtype_mask)
{
	uint32_t i;
	unsigned char *table_ptr;
	struct dt_entry dt_entry_buf_1;
	struct dt_entry dt_entry_buf_2;
	struct dt_entry *cur_dt_entry;
	struct dt_entry *best_match_dt_entry;
	struct dt_entry_v1 *dt_entry_v1;
	uint32_t found = 0;

	if (!dt_entry_info) {
		dprintf(CRITICAL, "ERROR: Bad parameter passed to %s \n",
				__func__);
		return -1;
	}

	table_ptr = (unsigned char *)table + DEV_TREE_HEADER_SIZE;
	cur_dt_entry = &dt_entry_buf_1;
	best_match_dt_entry = NULL;

	for(i = 0; found == 0 && i < table->num_entries; i++)
	{
		memset(cur_dt_entry, 0, sizeof(struct dt_entry));
		switch(table->version) {
		case DEV_TREE_VERSION_V1:
			dt_entry_v1 = (struct dt_entry_v1 *)table_ptr;
			cur_dt_entry->platform_id = dt_entry_v1->platform_id;
			cur_dt_entry->variant_id = dt_entry_v1->variant_id;
			cur_dt_entry->soc_rev = dt_entry_v1->soc_rev;
			cur_dt_entry->board_hw_subtype = board_hardware_subtype();
			cur_dt_entry->offset = dt_entry_v1->offset;
			cur_dt_entry->size = dt_entry_v1->size;
			table_ptr += sizeof(struct dt_entry_v1);
			break;
		case DEV_TREE_VERSION_V2:
			memcpy(cur_dt_entry, (struct dt_entry *)table_ptr,
				   sizeof(struct dt_entry));
			table_ptr += sizeof(struct dt_entry);
			break;
		default:
			dprintf(CRITICAL, "ERROR: Unsupported version (%d) in DT table \n",
					table->version);
			return -1;
		}

		/* DTBs are stored in the ascending order of soc revision.
		 * For eg: Rev0..Rev1..Rev2 & so on.
		 * we pickup the DTB with highest soc rev number which is less
		 * than or equal to actual hardware
		 */
		switch(platform_dt_match(cur_dt_entry, target_variant_id, subtype_mask)) {
		case 0:
			best_match_dt_entry = cur_dt_entry;
			found = 1;
			break;
		case -1:
			if (!best_match_dt_entry) {
				/* copy structure */
				best_match_dt_entry = cur_dt_entry;
				cur_dt_entry = &dt_entry_buf_2;
			} else {
				/* Swap dt_entry buffers */
				struct dt_entry *temp = cur_dt_entry;
				cur_dt_entry = best_match_dt_entry;
				best_match_dt_entry = temp;
			}
		default:
			break;
		}
	}

	if (best_match_dt_entry) {
		*dt_entry_info = *best_match_dt_entry;
		found = 1;
	}

	if (found != 0) {
		dprintf(INFO, "Using DTB entry %u/%08x/%u/%u for device %u/%08x/%u/%u\n",
				dt_entry_info->platform_id, dt_entry_info->soc_rev,
				dt_entry_info->variant_id, dt_entry_info->board_hw_subtype,
				board_platform_id(), board_soc_version(),
				board_hardware_id(), board_hardware_subtype());
		return 0;
	}

	dprintf(CRITICAL, "ERROR: Unable to find suitable device tree for device (%u/0x%08x/%u/%u)\n",
			board_platform_id(), board_soc_version(),
			board_hardware_id(), board_hardware_subtype());
	return -1;
}
コード例 #18
0
ファイル: init.c プロジェクト: nx511j-multirom/bootloader_lk
static void target_mmc_sdhci_init()
{
	struct mmc_config_data config = {0};
	uint32_t soc_ver = 0;

	soc_ver = board_soc_version();

	/*
	 * 8974 v1 fluid devices, have a hardware bug
	 * which limits the bus width to 4 bit.
	 */
	switch(board_hardware_id())
	{
		case HW_PLATFORM_FLUID:
			if (platform_is_8974() && BOARD_SOC_VERSION1(soc_ver))
				config.bus_width = DATA_BUS_WIDTH_4BIT;
			else
				config.bus_width = DATA_BUS_WIDTH_8BIT;
			break;
		default:
			config.bus_width = DATA_BUS_WIDTH_8BIT;
	};

	/* Trying Slot 1*/
	config.slot = 1;
	/*
	 * For 8974 AC platform the software clock
	 * plan recommends to use the following frequencies:
	 * 200 MHz --> 192 MHZ
	 * 400 MHZ --> 384 MHZ
	 * only for emmc slot
	 */
	if (platform_is_8974ac())
		config.max_clk_rate = MMC_CLK_192MHZ;
	else
		config.max_clk_rate = MMC_CLK_200MHZ;
	config.sdhc_base = mmc_sdhci_base[config.slot - 1];
	config.pwrctl_base = mmc_sdc_base[config.slot - 1];
	config.pwr_irq     = mmc_sdc_pwrctl_irq[config.slot - 1];
	config.hs400_support = 1;

	if (!(dev = mmc_init(&config))) {
		/* Trying Slot 2 next */
		config.slot = 2;
		config.max_clk_rate = MMC_CLK_200MHZ;
		config.sdhc_base = mmc_sdhci_base[config.slot - 1];
		config.pwrctl_base = mmc_sdc_base[config.slot - 1];
		config.pwr_irq     = mmc_sdc_pwrctl_irq[config.slot - 1];

		if (!(dev = mmc_init(&config))) {
			dprintf(CRITICAL, "mmc init failed!");
			ASSERT(0);
		}
	}

	/*
	 * MMC initialization is complete, read the partition table info
	 */
	if (partition_read_table()) {
		dprintf(CRITICAL, "Error reading the partition table info\n");
		ASSERT(0);
	}
}
コード例 #19
0
ファイル: dev_tree.c プロジェクト: cancro-dev/bootloader_lk
static int dev_tree_compatible(void *dtb, uint32_t dtb_size, struct dt_entry_node *dtb_list)
{
	int root_offset;
	const void *prop = NULL;
	const char *plat_prop = NULL;
	const char *board_prop = NULL;
	const char *pmic_prop = NULL;
	char *model = NULL;
	struct dt_entry *cur_dt_entry;
	struct dt_entry *dt_entry_array = NULL;
	struct board_id *board_data = NULL;
	struct plat_id *platform_data = NULL;
	struct pmic_id *pmic_data = NULL;
	int len;
	int len_board_id;
	int len_plat_id;
	int min_plat_id_len = 0;
	int len_pmic_id;
	uint32_t dtb_ver;
	uint32_t num_entries = 0;
	uint32_t i, j, k, n;
	uint32_t msm_data_count;
	uint32_t board_data_count;
	uint32_t pmic_data_count;

	root_offset = fdt_path_offset(dtb, "/");
	if (root_offset < 0)
		return false;

	prop = fdt_getprop(dtb, root_offset, "model", &len);
	if (prop && len > 0) {
		model = (char *) malloc(sizeof(char) * len);
		ASSERT(model);
		strlcpy(model, prop, len);
	} else {
		dprintf(INFO, "model does not exist in device tree\n");
	}
	/* Find the pmic-id prop from DTB , if pmic-id is present then
	* the DTB is version 3, otherwise find the board-id prop from DTB ,
	* if board-id is present then the DTB is version 2 */
	pmic_prop = (const char *)fdt_getprop(dtb, root_offset, "qcom,pmic-id", &len_pmic_id);
	board_prop = (const char *)fdt_getprop(dtb, root_offset, "qcom,board-id", &len_board_id);
	if (pmic_prop && (len_pmic_id > 0) && board_prop && (len_board_id > 0)) {
		if ((len_pmic_id % PMIC_ID_SIZE) || (len_board_id % BOARD_ID_SIZE))
		{
			dprintf(CRITICAL, "qcom,pmic-id(%d) or qcom,board-id(%d) in device tree is not a multiple of (%d %d)\n",
				len_pmic_id, len_board_id, PMIC_ID_SIZE, BOARD_ID_SIZE);
			return false;
		}
		dtb_ver = DEV_TREE_VERSION_V3;
		min_plat_id_len = PLAT_ID_SIZE;
	} else if (board_prop && len_board_id > 0) {
		if (len_board_id % BOARD_ID_SIZE)
		{
			dprintf(CRITICAL, "qcom,board-id in device tree is (%d) not a multiple of (%d)\n",
				len_board_id, BOARD_ID_SIZE);
			return false;
		}
		dtb_ver = DEV_TREE_VERSION_V2;
		min_plat_id_len = PLAT_ID_SIZE;
	} else {
		dtb_ver = DEV_TREE_VERSION_V1;
		min_plat_id_len = DT_ENTRY_V1_SIZE;
	}

	/* Get the msm-id prop from DTB */
	plat_prop = (const char *)fdt_getprop(dtb, root_offset, "qcom,msm-id", &len_plat_id);
	if (!plat_prop || len_plat_id <= 0) {
		dprintf(INFO, "qcom,msm-id entry not found\n");
		return false;
	} else if (len_plat_id % min_plat_id_len) {
		dprintf(INFO, "qcom,msm-id in device tree is (%d) not a multiple of (%d)\n",
			len_plat_id, min_plat_id_len);
		return false;
	}

	/*
	 * If DTB version is '1' look for <x y z> pair in the DTB
	 * x: platform_id
	 * y: variant_id
	 * z: SOC rev
	 */
	if (dtb_ver == DEV_TREE_VERSION_V1) {
		cur_dt_entry = (struct dt_entry *)
				malloc(sizeof(struct dt_entry));

		if (!cur_dt_entry) {
			dprintf(CRITICAL, "Out of memory\n");
			return false;
		}
		memset(cur_dt_entry, 0, sizeof(struct dt_entry));

		while (len_plat_id) {
			cur_dt_entry->platform_id = fdt32_to_cpu(((const struct dt_entry_v1 *)plat_prop)->platform_id);
			cur_dt_entry->variant_id = fdt32_to_cpu(((const struct dt_entry_v1 *)plat_prop)->variant_id);
			cur_dt_entry->soc_rev = fdt32_to_cpu(((const struct dt_entry_v1 *)plat_prop)->soc_rev);
			cur_dt_entry->board_hw_subtype =
				fdt32_to_cpu(((const struct dt_entry_v1 *)plat_prop)->variant_id) >> 0x18;
			cur_dt_entry->pmic_rev[0] = board_pmic_target(0);
			cur_dt_entry->pmic_rev[1] = board_pmic_target(1);
			cur_dt_entry->pmic_rev[2] = board_pmic_target(2);
			cur_dt_entry->pmic_rev[3] = board_pmic_target(3);
			cur_dt_entry->offset = (uint32_t)dtb;
			cur_dt_entry->size = dtb_size;

			dprintf(SPEW, "Found an appended flattened device tree (%s - %u %u 0x%x)\n",
				*model ? model : "unknown",
				cur_dt_entry->platform_id, cur_dt_entry->variant_id, cur_dt_entry->soc_rev);

			if (platform_dt_absolute_match(cur_dt_entry, dtb_list)) {
				dprintf(SPEW, "Device tree exact match the board: <%u %u 0x%x> != <%u %u 0x%x>\n",
					cur_dt_entry->platform_id,
					cur_dt_entry->variant_id,
					cur_dt_entry->soc_rev,
					board_platform_id(),
					board_hardware_id(),
					board_soc_version());

			} else {
				dprintf(SPEW, "Device tree's msm_id doesn't match the board: <%u %u 0x%x> != <%u %u 0x%x>\n",
					cur_dt_entry->platform_id,
					cur_dt_entry->variant_id,
					cur_dt_entry->soc_rev,
					board_platform_id(),
					board_hardware_id(),
					board_soc_version());
				plat_prop += DT_ENTRY_V1_SIZE;
				len_plat_id -= DT_ENTRY_V1_SIZE;
				continue;
			}
		}
		free(cur_dt_entry);

	}
コード例 #20
0
static int msm8974_backlight_on()
{
	static struct pm8x41_wled_data wled_ctrl = {
		.mod_scheme      = 0xC3,
		.led1_brightness = (0x0F << 8) | 0xEF,
		.led2_brightness = (0x0F << 8) | 0xEF,
		.led3_brightness = (0x0F << 8) | 0xEF,
		.max_duty_cycle  = 0x01,
	};

	pm8x41_wled_config(&wled_ctrl);
	pm8x41_wled_sink_control(1);
	pm8x41_wled_iled_sync_control(1);
	pm8x41_wled_enable(1);

	return 0;
}

static int msm8974_mdss_dsi_panel_clock(uint8_t enable)
{
	if (enable) {
		mdp_gdsc_ctrl(enable);
		mdp_clock_init();
		mdss_dsi_uniphy_pll_config();
		mmss_clock_init();
	} else if(!target_cont_splash_screen()) {
		// * Add here for continuous splash  *
		mmss_clock_disable();
		mdp_clock_disable();
		mdp_gdsc_ctrl(enable);
	}

	return 0;
}

/* Pull DISP_RST_N high to get panel out of reset */
static void msm8974_mdss_mipi_panel_reset(uint8_t enable)
{
	struct pm8x41_gpio gpio19_param = {
		.direction = PM_GPIO_DIR_OUT,
		.output_buffer = PM_GPIO_OUT_CMOS,
		.out_strength = PM_GPIO_OUT_DRIVE_MED,
	};

	pm8x41_gpio_config(19, &gpio19_param);
	if (enable) {
		gpio_tlmm_config(58, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_8MA, GPIO_DISABLE);

		pm8x41_gpio_set(19, PM_GPIO_FUNC_HIGH);
		mdelay(2);
		pm8x41_gpio_set(19, PM_GPIO_FUNC_LOW);
		mdelay(5);
		pm8x41_gpio_set(19, PM_GPIO_FUNC_HIGH);
		mdelay(2);
		gpio_set(58, 2);
	} else {
		gpio19_param.out_strength = PM_GPIO_OUT_DRIVE_LOW;
		pm8x41_gpio_config(19, &gpio19_param);
		pm8x41_gpio_set(19, PM_GPIO_FUNC_LOW);
		gpio_set(58, 2);
	}
}

static int msm8974_mipi_panel_power(uint8_t enable)
{
	if (enable) {

		/* Enable backlight */
		msm8974_backlight_on();

		/* Turn on LDO8 for lcd1 mipi vdd */
		dprintf(SPEW, " Setting LDO22\n");
		pm8x41_ldo_set_voltage("LDO22", 3000000);
		pm8x41_ldo_control("LDO22", enable);

		dprintf(SPEW, " Setting LDO12\n");
		/* Turn on LDO23 for lcd1 mipi vddio */
		pm8x41_ldo_set_voltage("LDO12", 1800000);
		pm8x41_ldo_control("LDO12", enable);

		dprintf(SPEW, " Setting LDO2\n");
		/* Turn on LDO2 for vdda_mipi_dsi */
		pm8x41_ldo_set_voltage("LDO2", 1200000);
		pm8x41_ldo_control("LDO2", enable);

		dprintf(SPEW, " Panel Reset \n");
		/* Panel Reset */
		msm8974_mdss_mipi_panel_reset(enable);
		dprintf(SPEW, " Panel Reset Done\n");
	} else {
		msm8974_mdss_mipi_panel_reset(enable);
		pm8x41_wled_enable(enable);
		pm8x41_ldo_control("LDO2", enable);
		pm8x41_ldo_control("LDO22", enable);

	}

	return 0;
}

void display_init(void)
{
	uint32_t hw_id = board_hardware_id();
	uint32_t soc_ver = board_soc_version();

	dprintf(INFO, "display_init(),target_id=%d.\n", hw_id);

	switch (hw_id) {
	case HW_PLATFORM_MTP:
	case HW_PLATFORM_FLUID:
	case HW_PLATFORM_SURF:
		mipi_toshiba_video_720p_init(&(panel.panel_info));
		panel.clk_func = msm8974_mdss_dsi_panel_clock;
		panel.power_func = msm8974_mipi_panel_power;
		panel.fb.base = MIPI_FB_ADDR;
		panel.fb.width =  panel.panel_info.xres;
		panel.fb.height =  panel.panel_info.yres;
		panel.fb.stride =  panel.panel_info.xres;
		panel.fb.bpp =  panel.panel_info.bpp;
		panel.fb.format = FB_FORMAT_RGB888;
		panel.mdp_rev = MDP_REV_50;
		break;
	default:
		return;
	};

	if (msm_display_init(&panel)) {
		dprintf(CRITICAL, "Display init failed!\n");
		return;
	}

	display_enable = 1;
}