Exemplo n.º 1
0
static enum switch_state get_switch_state(void)
{
	struct stopwatch sw;
	int sampled_value;
	uint8_t rec_sw;
	static enum switch_state saved_state = not_probed;

	if (saved_state != not_probed)
		return saved_state;

	rec_sw = get_rec_sw_gpio_pin();
	sampled_value = read_gpio(rec_sw) ^ !REC_POL;

	if (!sampled_value) {
		saved_state = no_req;
		display_pattern(WWR_NORMAL_BOOT);
		return saved_state;
	}

	display_pattern(WWR_RECOVERY_PUSHED);
	printk(BIOS_INFO, "recovery button pressed\n");

	stopwatch_init_msecs_expire(&sw, WIPEOUT_MODE_DELAY_MS);

	do {
		sampled_value = read_gpio(rec_sw) ^ !REC_POL;
		if (!sampled_value)
			break;
	} while (!stopwatch_expired(&sw));

	if (sampled_value) {
		display_pattern(WWR_WIPEOUT_REQUEST);
		printk(BIOS_INFO, "wipeout requested, checking recovery\n");
		stopwatch_init_msecs_expire(&sw, RECOVERY_MODE_EXTRA_DELAY_MS);
		do {
			sampled_value = read_gpio(rec_sw) ^ !REC_POL;
			if (!sampled_value)
				break;
		} while (!stopwatch_expired(&sw));

		if (sampled_value) {
			saved_state = recovery_req;
			display_pattern(WWR_RECOVERY_REQUEST);
			printk(BIOS_INFO, "recovery requested\n");
		} else {
			saved_state = wipeout_req;
		}
	} else {
		saved_state = no_req;
		display_pattern(WWR_NORMAL_BOOT);
	}

	return saved_state;
}
Exemplo n.º 2
0
/* cr50 uses bytes 3:2 of status register for burst count and
 * all 4 bytes must be read */
static int cr50_i2c_wait_burststs(struct tpm_chip *chip, uint8_t mask,
				  size_t *burst, int *status)
{
	uint8_t buf[4];
	struct stopwatch sw;

	stopwatch_init_msecs_expire(&sw, CR50_TIMEOUT_LONG_MS);

	while (!stopwatch_expired(&sw)) {
		if (cr50_i2c_read(chip, TPM_STS(chip->vendor.locality),
				  buf, sizeof(buf)) != 0) {
			mdelay(CR50_TIMEOUT_SHORT_MS);
			continue;
		}

		*status = buf[0];
		*burst = read_le16(&buf[1]);

		/* Check if mask matches and burst is valid */
		if ((*status & mask) == mask &&
		    *burst > 0 && *burst <= CR50_MAX_BUFSIZE)
			return 0;

		mdelay(CR50_TIMEOUT_SHORT_MS);
	}

	printk(BIOS_ERR, "%s: Timeout reading burst and status\n", __func__);
	return -1;
}
Exemplo n.º 3
0
static int rk_edp_hw_link_training(struct rk_edp *edp)
{
	u32 val;
	struct stopwatch sw;

	/* Set link rate and count as you want to establish*/
	write32(&edp->regs->link_bw_set, edp->link_train.link_rate);
	write32(&edp->regs->lane_count_set, edp->link_train.lane_count);

	if (rk_edp_link_train_cr(edp))
		return -1;
	if (rk_edp_link_train_ce(edp))
		return -1;

	write32(&edp->regs->dp_hw_link_training, HW_LT_EN);
	stopwatch_init_msecs_expire(&sw, 10);
	do {
		val = read32(&edp->regs->dp_hw_link_training);
		if (!(val & HW_LT_EN))
			break;
	} while (!stopwatch_expired(&sw));
	if (val & HW_LT_ERR_CODE_MASK) {
		printk(BIOS_ERR, "edp hw link training error: %d\n",
		val >> HW_LT_ERR_CODE_SHIFT);
		return -1;
	}
Exemplo n.º 4
0
void reset_prepare(void)
{
	struct stopwatch sw;

	/*
	 * If CSE state is something else than 'normal', it is probably in some
	 * recovery state. In this case there is no point in  waiting for it to
	 * get ready so we cross fingers and reset.
	 */
	if (!heci_cse_normal()) {
		printk(BIOS_DEBUG, "CSE is not in normal state, resetting\n");
		return;
	}

	/* Reset if CSE is ready */
	if (heci_cse_done())
		return;

	printk(BIOS_SPEW, "CSE is not yet ready, waiting\n");
	stopwatch_init_msecs_expire(&sw, CSE_WAIT_MAX_MS);
	while (!heci_cse_done()) {
		if (stopwatch_expired(&sw)) {
			printk(BIOS_SPEW, "CSE timed out. Resetting\n");
			return;
		}
		mdelay(1);
	}
	printk(BIOS_SPEW, "CSE took %lu ms\n", stopwatch_duration_msecs(&sw));
}
Exemplo n.º 5
0
/*
 * Punit Initialization code. This all isn't documented, but
 * this is the recipe.
 */
static bool punit_init(void)
{
	uint32_t reg;
	uint32_t data;
	struct stopwatch sw;

	/* Thermal throttle activation offset */
	configure_thermal_target();

	/*
	 * Software Core Disable Mask (P_CR_CORE_DISABLE_MASK_0_0_0_MCHBAR).
	 * Enable all cores here.
	 */
	MCHBAR32(CORE_DISABLE_MASK) = 0x0;

	/* P-Unit bring up */
	reg = MCHBAR32(BIOS_RESET_CPL);
	if (reg == 0xffffffff) {
		/* P-unit not found */
		printk(BIOS_DEBUG, "Punit MMIO not available\n");
		return false;
	}
	/* Set Punit interrupt pin IPIN offset 3D */
	pci_write_config8(SA_DEV_PUNIT, PCI_INTERRUPT_PIN, 0x2);

	/* Set PUINT IRQ to 24 and INTPIN LOCK */
	MCHBAR32(PUNIT_THERMAL_DEVICE_IRQ) =
			PUINT_THERMAL_DEVICE_IRQ_VEC_NUMBER |
			PUINT_THERMAL_DEVICE_IRQ_LOCK;

	if (!CONFIG(SOC_INTEL_GLK)) {
		data = MCHBAR32(0x7818);
		data &= 0xFFFFE01F;
		data |= 0x20 | 0x200;
		MCHBAR32(0x7818) = data;
	}

	/* Stage0 BIOS Reset Complete (RST_CPL) */
	enable_bios_reset_cpl();

	/*
	 * Poll for bit 8 to check if PCODE has completed its action
	 * in reponse to BIOS Reset complete.
	 * We wait here till 1 ms for the bit to get set.
	 */
	stopwatch_init_msecs_expire(&sw, 1);
	while (!(MCHBAR32(BIOS_RESET_CPL) & PCODE_INIT_DONE)) {
		if (stopwatch_expired(&sw)) {
			printk(BIOS_DEBUG, "PCODE Init Done Failure\n");
			return false;
		}
		udelay(100);
	}

	return true;
}
Exemplo n.º 6
0
/*
 * Punit Initialization code. This all isn't documented, but
 * this is the recipe.
 */
static bool punit_init(void)
{
	uint32_t reg;
	uint32_t data;
	struct stopwatch sw;

	/*
	 * Software Core Disable Mask (P_CR_CORE_DISABLE_MASK_0_0_0_MCHBAR).
	 * Enable all cores here.
	 */
	write32((void *)(MCH_BASE_ADDR + P_CR_CORE_DISABLE_MASK_0_0_0_MCHBAR),
		0x0);

	void *bios_rest_cpl = (void *)(MCH_BASE_ADDR +
				       P_CR_BIOS_RESET_CPL_0_0_0_MCHBAR);
	/* P-Unit bring up */
	reg = read32(bios_rest_cpl);
	if (reg == 0xffffffff) {
		/* P-unit not found */
		printk(BIOS_DEBUG, "Punit MMIO not available \n");
		return false;
	} else {
		/* Set Punit interrupt pin IPIN offset 3D */
		pci_write_config8(PUNIT_DEVFN, PCI_INTERRUPT_PIN, 0x2);

		/* Set PUINT IRQ to 24 and INTPIN LOCK */
		write32((void *)(MCH_BASE_ADDR + PUNIT_THERMAL_DEVICE_IRQ),
			PUINT_THERMAL_DEVICE_IRQ_VEC_NUMBER |
			PUINT_THERMAL_DEVICE_IRQ_LOCK);

		data = read32((void *)(MCH_BASE_ADDR + 0x7818));
		data &= 0xFFFFE01F;
		data |= 0x20 | 0x200;
		write32((void *)(MCH_BASE_ADDR + 0x7818), data);

		/* Stage0 BIOS Reset Complete (RST_CPL) */
		write32(bios_rest_cpl, 0x1);

		/*
		 * Poll for bit 8 in same reg (RST_CPL).
		 * We wait here till 1 ms for the bit to get set.
		 */
		stopwatch_init_msecs_expire(&sw, 1);
		while (!(read32(bios_rest_cpl) & 0x100)) {
			if (stopwatch_expired(&sw)) {
				printk(BIOS_DEBUG,
				       "Failed to set RST_CPL bit\n");
				return false;
			}
			udelay(100);
		}
	}
	return true;
}
Exemplo n.º 7
0
/*
 * Configure DP in slave mode and wait for video stream.
 *
 * param dp		pointer to main s5p-dp structure
 * param video_info	pointer to main video_info structure.
 * return		status
 */
static int s5p_dp_config_video(struct s5p_dp_device *dp,
			       struct video_info *video_info)
{
	int timeout = 0;
	struct exynos5_dp *base = dp->base;
	struct stopwatch sw;
	s5p_dp_config_video_slave_mode(dp, video_info);

	s5p_dp_set_video_color_format(dp, video_info->color_depth,
				      video_info->color_space,
				      video_info->dynamic_range,
				      video_info->ycbcr_coeff);

	if (s5p_dp_get_pll_lock_status(dp) == PLL_UNLOCKED) {
		printk(BIOS_DEBUG, "PLL is not locked yet.\n");
		return -ERR_PLL_NOT_UNLOCKED;
	}

	stopwatch_init_msecs_expire(&sw, STREAM_ON_TIMEOUT);
	do {
		if (s5p_dp_is_slave_video_stream_clock_on(dp) == 0) {
			timeout++;
			break;
		}
	} while (!stopwatch_expired(&sw));

	if (!timeout) {
		printk(BIOS_ERR, "Video Clock Not ok after %ldus.\n",
				stopwatch_duration_usecs(&sw));
		return -ERR_VIDEO_CLOCK_BAD;
	}

	/* Set to use the register calculated M/N video */
	s5p_dp_set_video_cr_mn(dp, CALCULATED_M, 0, 0);

	clrbits_le32(&base->video_ctl_10, FORMAT_SEL);

	/* Disable video mute */
	clrbits_le32(&base->video_ctl_1, HDCP_VIDEO_MUTE);

	/* Configure video slave mode */
	s5p_dp_enable_video_master(dp);

	/* Enable video */
	setbits_le32(&base->video_ctl_1, VIDEO_EN);
	timeout = s5p_dp_is_video_stream_on(dp);

	if (timeout) {
		printk(BIOS_DEBUG, "Video Stream Not on\n");
		return -ERR_VIDEO_STREAM_BAD;
	}

	return 0;
}
Exemplo n.º 8
0
/* Wait for interrupt to indicate the TPM is ready */
static int cr50_i2c_wait_tpm_ready(struct tpm_chip *chip)
{
	struct stopwatch sw;

	stopwatch_init_msecs_expire(&sw, CR50_TIMEOUT_IRQ_MS);

	while (!tis_plat_irq_status())
		if (stopwatch_expired(&sw))
			return -1;

	return 0;
}
Exemplo n.º 9
0
/*
 * TPM may trigger a IRQ after finish processing previous transfer.
 * Waiting for this IRQ to sync TPM status.
 *
 * Returns 1 on success, 0 on failure (timeout).
 */
static int tpm_sync(void)
{
	struct stopwatch sw;

	stopwatch_init_msecs_expire(&sw, 10);
	while (!tis_plat_irq_status()) {
		if (stopwatch_expired(&sw)) {
			printk(BIOS_ERR, "Timeout wait for TPM IRQ!\n");
			return 0;
		}
	}
	return 1;
}
Exemplo n.º 10
0
static int pcr_wait_for_completion(device_t dev)
{
	struct stopwatch sw;

	stopwatch_init_msecs_expire(&sw, PCR_SBI_CMD_TIMEOUT);
	do {
		if ((pci_read_config16(dev, P2SB_CR_SBI_STATUS) &
			P2SB_CR_SBI_STATUS_BUSY) == 0)
			return 0;
	} while (!stopwatch_expired(&sw));

	return -1;
}
Exemplo n.º 11
0
static int rk_edp_aux_enable(struct rk_edp *edp)
{
	struct stopwatch sw;

	setbits_le32(&edp->regs->aux_ch_ctl_2, AUX_EN);
	stopwatch_init_msecs_expire(&sw, 20);
	do {
		if (!(read32(&edp->regs->aux_ch_ctl_2) & AUX_EN))
			return 0;
	} while (!stopwatch_expired(&sw));

	return -1;

}
Exemplo n.º 12
0
static int rk_edp_is_aux_reply(struct rk_edp *edp)
{
	struct stopwatch sw;

	stopwatch_init_msecs_expire(&sw, 10);

	while (!(read32(&edp->regs->dp_int_sta) & RPLY_RECEIV)) {
		if (stopwatch_expired(&sw))
			return -1;
	}

	write32(&edp->regs->dp_int_sta, RPLY_RECEIV);

	return 0;
}
Exemplo n.º 13
0
static int tpm2_claim_locality(void)
{
	uint8_t access;
	struct stopwatch sw;

	/*
	 * Locality is released by TPM reset.
	 *
	 * If locality is taken at this point, this could be due to the fact
	 * that the TPM is performing a long operation and has not processed
	 * reset request yet. We'll wait up to CR50_TIMEOUT_INIT_MS and see if
	 * it releases locality when reset is processed.
	 */
	stopwatch_init_msecs_expire(&sw, CR50_TIMEOUT_INIT_MS);
	do {
		access = tpm2_read_access_reg();
		if (access & TPM_ACCESS_ACTIVE_LOCALITY) {
			/*
			 * Don't bombard the chip with traffic, let it keep
			 * processing the command.
			 */
			mdelay(2);
			continue;
		}

		/*
		 * Ok, the locality is free, TPM must be reset, let's claim
		 * it.
		 */

		tpm2_write_access_reg(TPM_ACCESS_REQUEST_USE);
		access = tpm2_read_access_reg();
		if (access != (TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY)) {
			break;
		}

		printk(BIOS_INFO, "TPM ready after %ld ms\n",
		       stopwatch_duration_msecs(&sw));

		return 1;
	} while (!stopwatch_expired(&sw));

	printk(BIOS_ERR,
	       "Failed to claim locality 0 after %ld ms, status: %#x\n",
	       stopwatch_duration_msecs(&sw), access);

	return 0;
}
Exemplo n.º 14
0
static bool wilco_ec_response_timed_out(void)
{
	uint8_t mask = EC_CMDR_PENDING | EC_CMDR_BUSY;
	struct stopwatch sw;

	stopwatch_init_msecs_expire(&sw, EC_MAILBOX_TIMEOUT_MS);

	while (inb(CONFIG_EC_BASE_HOST_COMMAND) & mask) {
		if (stopwatch_expired(&sw)) {
			printk(BIOS_ERR, "%s: Command timeout\n", __func__);
			return true; /* Timed out */
		}
		mdelay(1);
	}

	return false; /* Did not time out */
}
Exemplo n.º 15
0
/*
 * Cr50 processes reset requests asynchronously and consceivably could be busy
 * executing a long command and not reacting to the reset pulse for a while.
 *
 * This function will make sure that the AP does not proceed with boot until
 * TPM finished reset processing.
 */
static int process_reset(struct tpm_chip *chip)
{
	struct stopwatch sw;
	int rv = 0;
	uint8_t access;

	/*
	 * Locality is released by TPM reset.
	 *
	 * If locality is taken at this point, this could be due to the fact
	 * that the TPM is performing a long operation and has not processed
	 * reset request yet. We'll wait up to CR50_TIMEOUT_INIT_MS and see if
	 * it releases locality when reset is processed.
	 */
	stopwatch_init_msecs_expire(&sw, CR50_TIMEOUT_INIT_MS);
	do {
		const uint8_t mask =
			TPM_ACCESS_VALID | TPM_ACCESS_ACTIVE_LOCALITY;

		rv = cr50_i2c_read(chip, TPM_ACCESS(0),
				   &access, sizeof(access));
		if (rv || ((access & mask) == mask)) {
			/*
			 * Don't bombard the chip with traffic, let it keep
			 * processing the command.
			 */
			mdelay(2);
			continue;
		}

		printk(BIOS_INFO, "TPM ready after %ld ms\n",
		       stopwatch_duration_msecs(&sw));

		return 0;
	} while (!stopwatch_expired(&sw));

	if (rv)
		printk(BIOS_ERR, "Failed to read TPM\n");
	else
		printk(BIOS_ERR,
			"TPM failed to reset after %ld ms, status: %#x\n",
			stopwatch_duration_msecs(&sw), access);

	return -1;
}
Exemplo n.º 16
0
/**
 * Wait for DisplayPort to be ready
 *
 * @param timeout Wait aborts after <timeout> ms.
 * @return 1: Success or 0: Timeout.
 */
int google_chromeec_wait_for_displayport(long timeout)
{
	struct stopwatch sw;

	printk(BIOS_INFO, "Waiting for DisplayPort\n");
	stopwatch_init_msecs_expire(&sw, timeout);
	while (google_chromeec_pd_get_amode(USB_SID_DISPLAYPORT) != 1) {
		if (stopwatch_expired(&sw)) {
			printk(BIOS_WARNING,
			       "DisplayPort not ready after %ldms. Abort.\n",
			       timeout);
			return 0;
		}
		mdelay(200);
	}
	printk(BIOS_INFO, "DisplayPort ready after %lu ms\n",
	       stopwatch_duration_msecs(&sw));

	return 1;
}
Exemplo n.º 17
0
int ps8640_init(uint8_t bus, uint8_t chip)
{
	u8 set_vdo_done;
	struct stopwatch sw;

	stopwatch_init_msecs_expire(&sw, 350);

	do {
		i2c_readb(bus, chip + 2, PAGE2_GPIO_H, &set_vdo_done);
		if (stopwatch_expired(&sw)) {
			printk(BIOS_INFO, "Failed to init ps8640.\n");
			return -1;
		}
	} while ((set_vdo_done & PS_GPIO9) != PS_GPIO9);

	i2c_writeb(bus, chip + 3, PAGE3_SET_ADD, VDO_CTL_ADD);
	i2c_writeb(bus, chip + 3, PAGE3_SET_VAL, VDO_DIS);
	i2c_writeb(bus, chip + 3, PAGE3_SET_ADD, VDO_CTL_ADD);
	i2c_writeb(bus, chip + 3, PAGE3_SET_VAL, VDO_EN);

	return 0;
}
Exemplo n.º 18
0
static void rk_edp_init_analog_func(struct rk_edp *edp)
{
	struct stopwatch sw;

	write32(&edp->regs->dp_pd, 0x00);

	write32(&edp->regs->common_int_sta_1, PLL_LOCK_CHG);

	clrbits_le32(&edp->regs->dp_debug_ctl, F_PLL_LOCK | PLL_LOCK_CTRL);

	stopwatch_init_msecs_expire(&sw, PLL_LOCK_TIMEOUT);

	while (rk_edp_get_pll_lock_status(edp) == DP_PLL_UNLOCKED) {
		if (stopwatch_expired(&sw)) {
			printk(BIOS_ERR, "%s: PLL is not locked\n", __func__);
			return;
		}
	}

	/* Enable Serdes FIFO function and Link symbol clock domain module */
	clrbits_le32(&edp->regs->func_en_2, SERDES_FIFO_FUNC_EN_N |
				       LS_CLK_DOMAIN_FUNC_EN_N | AUX_FUNC_EN_N |
				       SSC_FUNC_EN_N);
}
Exemplo n.º 19
0
static int ccplex_start(void)
{
	struct stopwatch sw;
	const long timeout_ms = 1500;
	const uint32_t handshake_mask = 1;
	const uint32_t cxreset1_mask = 1 << 21;
	uint32_t reg;
	struct tegra_pmc_regs * const pmc = PMC_REGS;

	/* Set the handshake bit to be knocked down. */
	write32(&pmc->scratch118, handshake_mask);

	/* Assert nCXRSET[1] */
	reg = read32(CLK_RST_REG(rst_cpu_cmplx_set));
	reg |= cxreset1_mask;
	write32(CLK_RST_REG(rst_cpu_cmplx_set), reg);

	stopwatch_init_msecs_expire(&sw, timeout_ms);
	while (1) {
		reg = read32(&pmc->scratch118);

		/* Wait for the bit to be knocked down. */
		if ((reg & handshake_mask) != handshake_mask)
			break;

		if (stopwatch_expired(&sw)) {
			printk(BIOS_DEBUG, "MTS handshake timeout.\n");
			return -1;
		}
	}

	printk(BIOS_DEBUG, "MTS handshake took %ld usecs.\n",
		stopwatch_duration_usecs(&sw));

	return 0;
}
Exemplo n.º 20
0
static void wait_for_legacy_dev(void *unused)
{
	uint32_t legacy_delay, us_since_boot;
	struct stopwatch sw;

	/* Open main hwinfo block. */
	if (hwilib_find_blocks("hwinfo.hex") != CB_SUCCESS)
		return;

	/* Get legacy delay parameter from hwinfo. */
	if (hwilib_get_field(LegacyDelay, (uint8_t *) &legacy_delay,
			      sizeof(legacy_delay)) != sizeof(legacy_delay))
		return;

	us_since_boot = get_us_since_boot();
	/* No need to wait if the time since boot is already long enough.*/
	if (us_since_boot > legacy_delay)
		return;
	stopwatch_init_msecs_expire(&sw, (legacy_delay - us_since_boot) / 1000);
	printk(BIOS_NOTICE, "Wait remaining %d of %d us for legacy devices...",
			legacy_delay - us_since_boot, legacy_delay);
	stopwatch_wait_until_expired(&sw);
	printk(BIOS_NOTICE, "done!\n");
}
Exemplo n.º 21
0
/*
 * DP H/w Link Training. Set DPCD link rate and bandwidth.
 * param dp		pointer to main s5p-dp structure
 * param max_lane	No of lanes
 * param max_rate	bandwidth
 * return status
 */
static int s5p_dp_hw_link_training(struct s5p_dp_device *dp,
				   unsigned int max_lane,
				   unsigned int max_rate)
{
	int pll_is_locked = 0;
	u32 data;
	int lane;
	struct stopwatch sw;
	struct exynos5_dp *base = dp->base;

	/* Stop Video */
	clrbits_le32(&base->video_ctl_1, VIDEO_EN);

	stopwatch_init_msecs_expire(&sw, PLL_LOCK_TIMEOUT);

	while ((pll_is_locked = s5p_dp_get_pll_lock_status(dp)) == PLL_UNLOCKED) {
		if (stopwatch_expired(&sw)) {
			/* Ignore this error, and try to continue */
			printk(BIOS_ERR, "PLL is not locked yet.\n");
			break;
		}
	}
	printk(BIOS_SPEW, "PLL is %slocked\n",
			pll_is_locked == PLL_LOCKED ? "": "not ");
	/* Reset Macro */
	setbits_le32(&base->dp_phy_test, MACRO_RST);

	/* 10 us is the minimum reset time. */
	udelay(10);

	clrbits_le32(&base->dp_phy_test, MACRO_RST);

	/* Set TX pre-emphasis to minimum */
	for (lane = 0; lane < max_lane; lane++)
		if (s5p_dp_set_lane_lane_pre_emphasis(dp,
					      PRE_EMPHASIS_LEVEL_0, lane)) {
			printk(BIOS_DEBUG, "Unable to set pre emphasis level\n");
			return -ERR_PRE_EMPHASIS_LEVELS;
		}

	/* All DP analog module power up */
	writel(0x00, &base->dp_phy_pd);

	/* Initialize by reading RX's DPCD */
	s5p_dp_get_max_rx_bandwidth(dp, &dp->link_train.link_rate);
	s5p_dp_get_max_rx_lane_count(dp, &dp->link_train.lane_count);

	printk(BIOS_SPEW, "%s: rate 0x%x, lane_count %d\n", __func__,
		dp->link_train.link_rate, dp->link_train.lane_count);

	if ((dp->link_train.link_rate != LINK_RATE_1_62GBPS) &&
	    (dp->link_train.link_rate != LINK_RATE_2_70GBPS)) {
		printk(BIOS_DEBUG, "Rx Max Link Rate is abnormal :%x !\n",
		      dp->link_train.link_rate);
		/* Not Retrying */
		return -ERR_LINK_RATE_ABNORMAL;
	}

	if (dp->link_train.lane_count == 0) {
		printk(BIOS_DEBUG, "Rx Max Lane count is abnormal :%x !\n",
		      dp->link_train.lane_count);
		/* Not retrying */
		return -ERR_MAX_LANE_COUNT_ABNORMAL;
	}

	/* Setup TX lane count & rate */
	if (dp->link_train.lane_count > max_lane)
		dp->link_train.lane_count = max_lane;
	if (dp->link_train.link_rate > max_rate)
		dp->link_train.link_rate = max_rate;

	/* Set link rate and count as you want to establish*/
	writel(dp->link_train.lane_count, &base->lane_count_set);
	writel(dp->link_train.link_rate, &base->link_bw_set);

	/* Set sink to D0 (Sink Not Ready) mode. */
	s5p_dp_write_byte_to_dpcd(dp, DPCD_ADDR_SINK_POWER_STATE,
				  DPCD_SET_POWER_STATE_D0);

	/* Start HW link training */
	writel(HW_TRAINING_EN, &base->dp_hw_link_training);

	/* Wait until HW link training done */
	s5p_dp_wait_hw_link_training_done(dp);

	/* Get hardware link training status */
	data = readl(&base->dp_hw_link_training);
	printk(BIOS_SPEW, "hardware link training status: 0x%08x\n", data);
	if (data != 0) {
		printk(BIOS_ERR, " H/W link training failure: 0x%x\n", data);
		return -ERR_LINK_TRAINING_FAILURE;
	}

	/* Get Link Bandwidth */
	data = readl(&base->link_bw_set);

	dp->link_train.link_rate = data;

	data = readl(&base->lane_count_set);
	dp->link_train.lane_count = data;
	printk(BIOS_SPEW, "Done training: Link bandwidth: 0x%x, lane_count: %d\n",
		dp->link_train.link_rate, data);

	return 0;
}
Exemplo n.º 22
0
static int cr50_i2c_tis_send(struct tpm_chip *chip, uint8_t *buf, size_t len)
{
	int status;
	size_t burstcnt, limit, sent = 0;
	uint8_t tpm_go[4] = { TPM_STS_GO };
	struct stopwatch sw;

	stopwatch_init_msecs_expire(&sw, CR50_TIMEOUT_LONG_MS);

	/* Wait until TPM is ready for a command */
	while (!(cr50_i2c_tis_status(chip) & TPM_STS_COMMAND_READY)) {
		if (stopwatch_expired(&sw)) {
			printk(BIOS_ERR, "%s: Command ready timeout\n",
			       __func__);
			return -1;
		}

		cr50_i2c_tis_ready(chip);
	}

	while (len > 0) {
		uint8_t mask = TPM_STS_VALID;

		/* Wait for data if this is not the first chunk */
		if (sent > 0)
			mask |= TPM_STS_DATA_EXPECT;

		/* Read burst count and check status */
		if (cr50_i2c_wait_burststs(chip, mask, &burstcnt, &status) < 0)
			goto out_err;

		/* Use burstcnt - 1 to account for the address byte
		 * that is inserted by cr50_i2c_write() */
		limit = min(burstcnt - 1, len);
		if (cr50_i2c_write(chip, TPM_DATA_FIFO(chip->vendor.locality),
				   &buf[sent], limit) != 0) {
			printk(BIOS_ERR, "%s: Write failed\n", __func__);
			goto out_err;
		}

		sent += limit;
		len -= limit;
	}

	/* Ensure TPM is not expecting more data */
	if (cr50_i2c_wait_burststs(chip, TPM_STS_VALID, &burstcnt, &status) < 0)
		goto out_err;
	if (status & TPM_STS_DATA_EXPECT) {
		printk(BIOS_ERR, "%s: Data still expected\n", __func__);
		goto out_err;
	}

	/* Start the TPM command */
	if (cr50_i2c_write(chip, TPM_STS(chip->vendor.locality), tpm_go,
			   sizeof(tpm_go)) < 0) {
		printk(BIOS_ERR, "%s: Start command failed\n", __func__);
		goto out_err;
	}
	return sent;

out_err:
	/* Abort current transaction if still pending */
	if (cr50_i2c_tis_status(chip) & TPM_STS_COMMAND_READY)
		cr50_i2c_tis_ready(chip);
	return -1;
}
Exemplo n.º 23
0
static uint32_t mtk_i2c_transfer(uint8_t bus, struct i2c_msg *seg,
				 enum i2c_modes read)
{
	uint32_t ret_code = I2C_OK;
	uint16_t status;
	uint32_t time_out_val = 0;
	uint8_t  addr;
	uint32_t write_len = 0;
	uint32_t read_len = 0;
	uint8_t *write_buffer = NULL;
	uint8_t *read_buffer = NULL;
	struct mt8173_i2c_regs *regs;
	struct mt8173_i2c_dma_regs *dma_regs;
	struct stopwatch sw;

	regs = i2c[bus].i2c_regs;
	dma_regs = i2c[bus].i2c_dma_regs;

	addr = seg[0].slave;

	switch (read) {
	case I2C_WRITE_MODE:
		assert(seg[0].len > 0 && seg[0].len <= 255);
		write_len = seg[0].len;
		write_buffer = seg[0].buf;
		break;

	case I2C_READ_MODE:
		assert(seg[0].len > 0 && seg[0].len <= 255);
		read_len = seg[0].len;
		read_buffer = seg[0].buf;
		break;

	/* Must use special write-then-read mode for repeated starts. */
	case I2C_WRITE_READ_MODE:
		assert(seg[0].len > 0 && seg[0].len <= 255);
		assert(seg[1].len > 0 && seg[1].len <= 255);
		write_len = seg[0].len;
		read_len = seg[1].len;
		write_buffer = seg[0].buf;
		read_buffer = seg[1].buf;
		break;
	}

	/* Clear interrupt status */
	write32(&regs->intr_stat, I2C_TRANSAC_COMP | I2C_ACKERR |
		I2C_HS_NACKERR);

	write32(&regs->fifo_addr_clr, 0x1);

	/* Enable interrupt */
	write32(&regs->intr_mask, I2C_HS_NACKERR | I2C_ACKERR |
		I2C_TRANSAC_COMP);

	switch (read) {
	case I2C_WRITE_MODE:
		memcpy(_dma_coherent, write_buffer, write_len);

		/* control registers */
		write32(&regs->control, ACK_ERR_DET_EN | DMA_EN | CLK_EXT |
			REPEATED_START_FLAG);

		/* Set transfer and transaction len */
		write32(&regs->transac_len, 1);
		write32(&regs->transfer_len, write_len);

		/* set i2c write slave address*/
		write32(&regs->slave_addr, addr << 1);

		/* Prepare buffer data to start transfer */
		write32(&dma_regs->dma_con, I2C_DMA_CON_TX);
		write32(&dma_regs->dma_tx_mem_addr, (uintptr_t)_dma_coherent);
		write32(&dma_regs->dma_tx_len, write_len);
		break;

	case I2C_READ_MODE:
		/* control registers */
		write32(&regs->control, ACK_ERR_DET_EN | DMA_EN | CLK_EXT |
			REPEATED_START_FLAG);

		/* Set transfer and transaction len */
		write32(&regs->transac_len, 1);
		write32(&regs->transfer_len, read_len);

		/* set i2c read slave address*/
		write32(&regs->slave_addr, (addr << 1 | 0x1));

		/* Prepare buffer data to start transfer */
		write32(&dma_regs->dma_con, I2C_DMA_CON_RX);
		write32(&dma_regs->dma_rx_mem_addr, (uintptr_t)_dma_coherent);
		write32(&dma_regs->dma_rx_len, read_len);
		break;

	case I2C_WRITE_READ_MODE:
		memcpy(_dma_coherent, write_buffer, write_len);

		/* control registers */
		write32(&regs->control, DIR_CHG | ACK_ERR_DET_EN | DMA_EN |
			CLK_EXT | REPEATED_START_FLAG);

		/* Set transfer and transaction len */
		write32(&regs->transfer_len, write_len);
		write32(&regs->transfer_aux_len, read_len);
		write32(&regs->transac_len, 2);

		/* set i2c write slave address*/
		write32(&regs->slave_addr, addr << 1);

		/* Prepare buffer data to start transfer */
		write32(&dma_regs->dma_con, I2C_DMA_CLR_FLAG);
		write32(&dma_regs->dma_tx_mem_addr, (uintptr_t)_dma_coherent);
		write32(&dma_regs->dma_tx_len, write_len);
		write32(&dma_regs->dma_rx_mem_addr, (uintptr_t)_dma_coherent);
		write32(&dma_regs->dma_rx_len, read_len);
		break;
	}

	write32(&dma_regs->dma_int_flag, I2C_DMA_CLR_FLAG);
	write32(&dma_regs->dma_en, I2C_DMA_START_EN);

	/* start transfer transaction */
	write32(&regs->start, 0x1);

	stopwatch_init_msecs_expire(&sw, 100);

	/* polling mode : see if transaction complete */
	while (1) {
		status = read32(&regs->intr_stat);
		if (status & I2C_HS_NACKERR) {
			ret_code = I2C_TRANSFER_FAIL_HS_NACKERR;
			I2CERR("[i2c%d transfer] transaction NACK error\n",
			       bus);
			mtk_i2c_dump_info(bus);
			break;
		} else if (status & I2C_ACKERR) {
			ret_code = I2C_TRANSFER_FAIL_ACKERR;
			I2CERR("[i2c%d transfer] transaction ACK error\n", bus);
			mtk_i2c_dump_info(bus);
			break;
		} else if (status & I2C_TRANSAC_COMP) {
			ret_code = I2C_OK;
			memcpy(read_buffer, _dma_coherent, read_len);
			break;
		}

		if (stopwatch_expired(&sw)) {
			ret_code = I2C_TRANSFER_FAIL_TIMEOUT;
			I2CERR("[i2c%d transfer] transaction timeout:%d\n", bus,
			       time_out_val);
			mtk_i2c_dump_info(bus);
			break;
		}
	}

	write32(&regs->intr_stat, I2C_TRANSAC_COMP | I2C_ACKERR |
		I2C_HS_NACKERR);

	/* clear bit mask */
	write32(&regs->intr_mask, I2C_HS_NACKERR | I2C_ACKERR |
		I2C_TRANSAC_COMP);

	/* reset the i2c controller for next i2c transfer. */
	write32(&regs->softreset, 0x1);

	i2c_dma_reset(dma_regs);

	return ret_code;
}
Exemplo n.º 24
0
void arch_initialize_cpus(device_t cluster, struct cpu_control_ops *cntrl_ops)
{
	size_t max_cpus;
	size_t i;
	struct cpu_info *ci;
	void (*entry)(void);
	struct bus *bus;

	if (cluster->path.type != DEVICE_PATH_CPU_CLUSTER) {
		printk(BIOS_ERR,
			"CPU init failed. Device is not a CPU_CLUSTER: %s\n",
			dev_path(cluster));
		return;
	}

	bus = cluster->link_list;

	/* Check if no children under this device. */
	if (bus == NULL)
		return;

	/*
	 * el3_init must be performed prior to prepare_secondary_cpu_startup.
	 * This is important since el3_init initializes SCR values on BSP CPU
	 * and then prepare_secondary_cpu_startup reads the initialized SCR
	 * value and saves it for use by non-BSP CPUs.
	 */
	el3_init();
	/* Mark current cpu online. */
	cpu_mark_online(cpu_info());
	entry = prepare_secondary_cpu_startup();

	/* Initialize the cpu_info structures. */
	init_cpu_info(bus);
	max_cpus = cntrl_ops->total_cpus();

	if (max_cpus > CONFIG_MAX_CPUS) {
		printk(BIOS_WARNING,
			"max_cpus (%zu) exceeds CONFIG_MAX_CPUS (%zu).\n",
			max_cpus, (size_t)CONFIG_MAX_CPUS);
		max_cpus = CONFIG_MAX_CPUS;
	}

	for (i = 0; i < max_cpus; i++) {
		device_t dev;
		struct cpu_action action;
		struct stopwatch sw;

		ci = cpu_info_for_cpu(i);
		dev = ci->cpu;

		/* Disregard CPUs not in device tree. */
		if (dev == NULL)
			continue;

		/* Skip disabled CPUs. */
		if (!dev->enabled)
			continue;

		if (!cpu_online(ci)) {
			/* Start the CPU. */
			printk(BIOS_DEBUG, "Starting CPU%x\n", ci->id);

			if (cntrl_ops->start_cpu(ci->id, entry)) {
				printk(BIOS_ERR,
					"Failed to start CPU%x\n", ci->id);
				continue;
			}
			stopwatch_init_msecs_expire(&sw, 1000);
			/* Wait for CPU to come online. */
			while (!stopwatch_expired(&sw)) {
				if (!cpu_online(ci))
					continue;
				printk(BIOS_DEBUG,
					"CPU%x online in %ld usecs.\n",
					ci->id, stopwatch_duration_usecs(&sw));
				break;
			}
		}

		if (!cpu_online(ci)) {
			printk(BIOS_DEBUG,
				"CPU%x failed to come online in %ld usecs.\n",
				ci->id, stopwatch_duration_usecs(&sw));
			continue;
		}

		/* Send it the init action. */
		action.run = init_this_cpu;
		action.arg = ci;
		arch_run_on_cpu(ci->id, &action);
	}
}
Exemplo n.º 25
0
/*
 * Each TPM2 SPI transaction starts the same: CS is asserted, the 4 byte
 * header is sent to the TPM, the master waits til TPM is ready to continue.
 *
 * Returns 1 on success, 0 on failure (TPM SPI flow control timeout.)
 */
static int start_transaction(int read_write, size_t bytes, unsigned addr)
{
	spi_frame_header header;
	uint8_t byte;
	int i;
	struct stopwatch sw;
	static int tpm_sync_needed CAR_GLOBAL;
	static struct stopwatch wake_up_sw CAR_GLOBAL;
	struct spi_slave *spi_slave = car_get_var_ptr(&g_spi_slave);
	/*
	 * First Cr50 access in each coreboot stage where TPM is used will be
	 * prepended by a wake up pulse on the CS line.
	 */
	int wakeup_needed = 1;

	/* Wait for TPM to finish previous transaction if needed */
	if (car_get_var(tpm_sync_needed)) {
		tpm_sync();
		/*
		 * During the first invocation of this function on each stage
		 * this if () clause code does not run (as tpm_sync_needed
		 * value is zero), during all following invocations the
		 * stopwatch below is guaranteed to be started.
		 */
		if (!stopwatch_expired(car_get_var_ptr(&wake_up_sw)))
			wakeup_needed = 0;
	} else {
		car_set_var(tpm_sync_needed, 1);
	}

	if (wakeup_needed) {
		/* Just in case Cr50 is asleep. */
		spi_claim_bus(spi_slave);
		udelay(1);
		spi_release_bus(spi_slave);
		udelay(100);
	}

	/*
	 * The Cr50 on H1 does not go to sleep for 1 second after any
	 * SPI slave activity, let's be conservative and limit the
	 * window to 900 ms.
	 */
	stopwatch_init_msecs_expire(car_get_var_ptr(&wake_up_sw), 900);

	/*
	 * The first byte of the frame header encodes the transaction type
	 * (read or write) and transfer size (set to lentgh - 1), limited to
	 * 64 bytes.
	 */
	header.body[0] = (read_write ? 0x80 : 0) | 0x40 | (bytes - 1);

	/* The rest of the frame header is the TPM register address. */
	for (i = 0; i < 3; i++)
		header.body[i + 1] = (addr >> (8 * (2 - i))) & 0xff;

	/* CS assert wakes up the slave. */
	spi_claim_bus(spi_slave);

	/*
	 * The TCG TPM over SPI specification introduces the notion of SPI
	 * flow control (Section "6.4.5 Flow Control").
	 *
	 * Again, the slave (TPM device) expects each transaction to start
	 * with a 4 byte header trasmitted by master. The header indicates if
	 * the master needs to read or write a register, and the register
	 * address.
	 *
	 * If the slave needs to stall the transaction (for instance it is not
	 * ready to send the register value to the master), it sets the MOSI
	 * line to 0 during the last clock of the 4 byte header. In this case
	 * the master is supposed to start polling the SPI bus, one byte at
	 * time, until the last bit in the received byte (transferred during
	 * the last clock of the byte) is set to 1.
	 *
	 * Due to some SPI controllers' shortcomings (Rockchip comes to
	 * mind...) we trasmit the 4 byte header without checking the byte
	 * transmitted by the TPM during the transaction's last byte.
	 *
	 * We know that cr50 is guaranteed to set the flow control bit to 0
	 * during the header transfer, but real TPM2 might be fast enough not
	 * to require to stall the master, this would present an issue.
	 * crosbug.com/p/52132 has been opened to track this.
	 */
	spi_xfer(spi_slave, header.body, sizeof(header.body), NULL, 0);

	/*
	 * Now poll the bus until TPM removes the stall bit. Give it up to 100
	 * ms to sort it out - it could be saving stuff in nvram at some
	 * point.
	 */
	stopwatch_init_msecs_expire(&sw, 100);
	do {
		if (stopwatch_expired(&sw)) {
			printk(BIOS_ERR, "TPM flow control failure\n");
			spi_release_bus(spi_slave);
			return 0;
		}
		spi_xfer(spi_slave, NULL, 0, &byte, 1);
	} while (!(byte & 1));
	return 1;
}