Пример #1
0
/** Configure the data transmission format
 *
 *  @param mode Clock polarity and phase mode (0 - 3)
 *
 */
static void sps_configure(enum sps_mode mode, enum spi_clock_mode clk_mode)
{
	/* Disable All Interrupts */
	GREG32(SPS, ICTRL) = 0;

	GWRITE_FIELD(SPS, CTRL, MODE, mode);
	GWRITE_FIELD(SPS, CTRL, IDLE_LVL, 0);
	GWRITE_FIELD(SPS, CTRL, CPHA, clk_mode & 1);
	GWRITE_FIELD(SPS, CTRL, CPOL, (clk_mode >> 1) & 1);
	GWRITE_FIELD(SPS, CTRL, TXBITOR, 1); /* MSB first */
	GWRITE_FIELD(SPS, CTRL, RXBITOR, 1); /* MSB first */
	/* xfer 0xff when tx fifo is empty */
	GREG32(SPS, DUMMY_WORD) = GC_SPS_DUMMY_WORD_DEFAULT;

	/* [5,4,3]           [2,1,0]
	 * RX{DIS, EN, RST} TX{DIS, EN, RST}
	 */
	GREG32(SPS, FIFO_CTRL) = 0x9;

	/* wait for reset to self clear. */
	while (GREG32(SPS, FIFO_CTRL) & 9)
		;

	/* Do not enable TX FIFO until we have something to send. */
	GWRITE_FIELD(SPS, FIFO_CTRL, RXFIFO_EN, 1);

	GREG32(SPS, RXFIFO_THRESHOLD) = 8;

	GWRITE_FIELD(SPS, ICTRL, RXFIFO_LVL, 1);

	/* Use CS_DEASSERT to retrieve all remaining bytes from RX FIFO. */
	GWRITE_FIELD(SPS, ISTATE_CLR, CS_DEASSERT, 1);
	GWRITE_FIELD(SPS, ICTRL, CS_DEASSERT, 1);
}
Пример #2
0
static void usb_load_serialno(void)
{
	char devid_str[20];

	snprintf(devid_str, 20, "%08X-%08X", GREG32(FUSE, DEV_ID0),
		GREG32(FUSE, DEV_ID1));

	usb_set_serial(devid_str);
}
Пример #3
0
static void init_timers(void)
{
	/* Cancel low speed timers that may have
	 * been initialized prior to soft reset. */
	GREG32(TIMELS, TIMER0_CONTROL) = 0;
	GREG32(TIMELS, TIMER0_LOAD) = 0;
	GREG32(TIMELS, TIMER1_CONTROL) = 0;
	GREG32(TIMELS, TIMER1_LOAD) = 0;
}
Пример #4
0
void flash_info_write_enable(void)
{
	/* Enable R/W access to INFO. */
	GREG32(GLOBALSEC, FLASH_REGION3_BASE_ADDR) = FLASH_INFO_MEMORY_BASE +
		FLASH_INFO_MANUFACTURE_STATE_OFFSET;
	GREG32(GLOBALSEC, FLASH_REGION3_SIZE) =
		FLASH_INFO_MANUFACTURE_STATE_SIZE - 1;
	GREG32(GLOBALSEC, FLASH_REGION3_CTRL) =
		GC_GLOBALSEC_FLASH_REGION3_CTRL_EN_MASK |
		GC_GLOBALSEC_FLASH_REGION3_CTRL_WR_EN_MASK |
		GC_GLOBALSEC_FLASH_REGION3_CTRL_RD_EN_MASK;
}
Пример #5
0
/* When the calibration under runs, it means the fine trim code
 * has reached 0, but the clock is still too slow.  Thus,
 * software must reduce the coarse trim code by 1 */
static void timer_sof_calibration_underrun_int(void)
{
	unsigned coarseTrimValue = GREG32(XO, CLK_TIMER_RC_COARSE_ATE_TRIM);

	CPRINTS("%s: 0x%02x", __func__, coarseTrimValue);

	if (coarseTrimValue > 0x00)
		GREG32(XO, CLK_TIMER_RC_COARSE_ATE_TRIM) = coarseTrimValue - 1;

	GREG32(XO, DXO_INT_STATE) =
		GC_XO_DXO_INT_STATE_SLOW_CALIB_UNDERRUN_MASK;
}
Пример #6
0
static void sps_cs_deassert_interrupt(uint32_t port)
{
	/* Make sure the receive FIFO is drained. */
	sps_rx_interrupt(port, 1);
	GWRITE_FIELD(SPS, ISTATE_CLR, CS_DEASSERT, 1);
	GWRITE_FIELD(SPS, FIFO_CTRL, TXFIFO_EN, 0);

	/*
	 * And transmit FIFO is emptied, so the next transaction doesn't start
	 * by clocking out any bytes left over from this one.
	 */
	GREG32(SPS, TXFIFO_WPTR) = GREG32(SPS, TXFIFO_RPTR);
}
Пример #7
0
/* Initialize board. */
static void board_init(void)
{
	init_pmu();
	init_timers();
	init_interrupts();
	init_trng();
	init_runlevel(PERMISSION_MEDIUM);

	/* TODO(crosbug.com/p/49959): For now, leave flash WP unlocked */
	GREG32(RBOX, EC_WP_L) = 1;

	/* Indication that firmware is running, for debug purposes. */
	GREG32(PMU, PWRDN_SCRATCH16) = 0xCAFECAFE;
}
Пример #8
0
void unlockFlashForRW(void)
{
	uint32_t text_end = ((uint32_t)(&__ro_end) +
			     (uint32_t)(&__data_end) -
			     (uint32_t)(&__data_start) +
			     CONFIG_FLASH_BANK_SIZE)
		& ~(CONFIG_FLASH_BANK_SIZE - 1);

	GREG32(GLOBALSEC, FLASH_REGION1_BASE_ADDR) = text_end;
	GREG32(GLOBALSEC, FLASH_REGION1_SIZE) =
		CONFIG_FLASH_SIZE - text_end - 1;
	GWRITE_FIELD(GLOBALSEC, FLASH_REGION1_CTRL, EN, 1);
	GWRITE_FIELD(GLOBALSEC, FLASH_REGION1_CTRL, RD_EN, 1);
	GWRITE_FIELD(GLOBALSEC, FLASH_REGION1_CTRL, WR_EN, 0);
}
/* Verify the flash controller is awake. */
static int _check_flash_is_awake(void)
{
	int retval;

	GREG32(FLASH, FSH_TRANS) = 0xFFFFFFFF;
	retval = GREG32(FLASH, FSH_TRANS);
	GREG32(FLASH, FSH_TRANS) =  0x0;

	if (retval == 0) {
		debug_printf("ERROR:FLASH Controller seems unresponsive. ");
		debug_printf("Did you make sure to run 'reseth'?\n");
		return E_FL_NOT_AWAKE;
	}

	return 0;
}
int flash_info_read(uint32_t offset, uint32_t *dst)
{
	int retval;

	/* Make sure flash controller is awake. */
	retval = _check_flash_is_awake();
	if (retval)
		return retval;

	GWRITE_FIELD(FLASH, FSH_TRANS, OFFSET, offset);
	GWRITE_FIELD(FLASH, FSH_TRANS, MAINB, 1);
	GWRITE_FIELD(FLASH, FSH_TRANS, SIZE, 1);

	retval = _flash_cmd(1, FSH_OP_READ);
	if (retval)
		return retval;

	if (_flash_error())
		return E_FL_ERROR;

	if (!retval)
		*dst = GREG32(FLASH, FSH_DOUT_VAL1);

	return retval;
}
Пример #11
0
static void init_pmu(void)
{
	/* This boot sequence may be a result of previous soft reset,
	 * in which case the PMU low power sequence register needs to
	 * be reset. */
	GREG32(PMU, LOW_POWER_DIS) = 0;
}
Пример #12
0
/* When the calibration overflows, it means the fine trim code
 * has reached 0x1F, but the clock is still too fast.  Thus,
 * software must increase the coarse trim code by 1 */
static void timer_sof_calibration_overflow_int(void)
{
	unsigned coarseTrimValue = GREG32(XO, CLK_TIMER_RC_COARSE_ATE_TRIM);
	unsigned max;

	CPRINTS("%s: 0x%02x", __func__, coarseTrimValue);

	if (GREAD_FIELD(XO, CLK_TIMER_CALIB_TRIM_CTRL, MAX_TRIM_SEL))
		max = 0x1f;
	else
		max = 0xff;

	if (coarseTrimValue < max)
		GREG32(XO, CLK_TIMER_RC_COARSE_ATE_TRIM) = coarseTrimValue + 1;

	GREG32(XO, DXO_INT_STATE) =
		GC_XO_DXO_INT_STATE_SLOW_CALIB_OVERFLOW_MASK;
}
static int _flash_error(void)
{
	int retval = GREG32(FLASH, FSH_ERROR);

	if (!retval)
		return 0;

	debug_printf("Register FLASH_FSH_ERROR is not zero (found %x).\n");
	debug_printf("Will read again to verify FSH_ERROR was cleared ");
	debug_printf("and then continue...\n", retval);

	retval = GREG32(FLASH, FSH_ERROR);
	if (retval) {
		debug_printf("ERROR: Read to FLASH_FSH_ERROR (%x) ");
		debug_printf("did not clear it\n", retval);
	}

	return retval;
}
Пример #14
0
void dcrypto_sha_wait(enum sha_mode mode, uint32_t *digest)
{
    int i;
    const int digest_len = (mode == SHA1_MODE) ?
                           SHA_DIGEST_SIZE :
                           SHA256_DIGEST_SIZE;

    /* Stop LIVESTREAM mode. */
    GREG32(KEYMGR, SHA_TRIG) = GC_KEYMGR_SHA_TRIG_TRIG_STOP_MASK;

    /* Wait for SHA DONE interrupt. */
    while (!GREG32(KEYMGR, SHA_ITOP))
        ;

    /* Read out final digest. */
    for (i = 0; i < digest_len / 4; ++i)
        *digest++ = GR_KEYMGR_SHA_HASH(i);
    dcrypto_release_sha_hw();
}
Пример #15
0
void checkBuildVersion(void)
{
	uint32_t last_sync = GREG32(SWDP, P4_LAST_SYNC);

	if (last_sync == GC_SWDP_P4_LAST_SYNC_DEFAULT)
		return;

	debug_printf("compiled for %u, not willing to run on %u\n",
		     GC_SWDP_P4_LAST_SYNC_DEFAULT, last_sync);
	halt();
}
Пример #16
0
void init_jittery_clock(int highsec)
{
	unsigned trimfast = GR_FUSE(RC_JTR_OSC60_CC_TRIM);
	unsigned trim48 = GR_FUSE(RC_JTR_OSC48_CC_TRIM);
	unsigned delta = (trim48 - trimfast);
	/* For metastability reasons, avoid clk_jtr ~= clk_timer, make
	 * a keepout region around 24MHz of about 0.75MHz, about 3/16 of the
	 * the delta from trimfast and trim48 */
	unsigned skiplow = (trim48 << 4) - (delta * 6);
	unsigned skiphigh = (trim48 << 4) + (delta * 6);
	unsigned setting = trimfast << 4;
	unsigned stepx16;
	unsigned bankval;
	int bank;

	if (highsec)
		stepx16 = 0xff - trimfast;
	else
		stepx16 = 2 * (trim48 - trimfast);

	for (bank = 0; bank < 16; bank++) {
		/* saturate at 0xff */
		bankval = (setting > 0xfff) ? 0xff : (setting >> 4);

		GR_XO_JTR_JITTERY_TRIM_BANK(bank) = bankval;

		setting += stepx16;
		if ((setting > skiplow) && (setting < skiphigh))
			setting = skiphigh;
	}

	GWRITE_FIELD(XO, CLK_JTR_TRIM_CTRL, RC_COARSE_TRIM_SRC, 2);
	GWRITE_FIELD(XO, CLK_JTR_TRIM_CTRL, RC_INITIAL_TRIM_PERIOD, 100);
	GWRITE_FIELD(XO, CLK_JTR_TRIM_CTRL, RC_TRIM_EN, 1);
	GREG32(XO, CLK_JTR_JITTERY_TRIM_EN) = 1;
	GREG32(XO, CLK_JTR_SYNC_CONTENTS) = 0;

	/* Writing any value locks things until the next hard reboot */
	GREG32(XO, CFG_WR_EN) = 0;
	GREG32(XO, JTR_CTRL_EN) = 0;
}
Пример #17
0
void dcrypto_sha_init(enum sha_mode mode)
{
    int val;

    /* Stop LIVESTREAM mode, in case final() was not called. */
    GREG32(KEYMGR, SHA_TRIG) = GC_KEYMGR_SHA_TRIG_TRIG_STOP_MASK;
    /* Clear interrupt status. */
    GREG32(KEYMGR, SHA_ITOP) = 0;

    /* Enable streaming mode. */
    val = GC_KEYMGR_SHA_CFG_EN_LIVESTREAM_MASK;
    /* Enable SHA DONE interrupt. */
    val |= GC_KEYMGR_SHA_CFG_EN_INT_EN_DONE_MASK;
    /* Select SHA mode. */
    if (mode == SHA1_MODE)
        val |= GC_KEYMGR_SHA_CFG_EN_SHA1_MASK;
    GREG32(KEYMGR, SHA_CFG_EN) = val;

    /* Start SHA engine. */
    GREG32(KEYMGR, SHA_TRIG) = GC_KEYMGR_SHA_TRIG_TRIG_GO_MASK;
}
/* Send cmd to flash controller. */
static int _flash_cmd(uint32_t fidx, uint32_t cmd)
{
	int cnt, retval;

	/* Activate controller. */
	GREG32(FLASH, FSH_PE_EN) = FSH_OP_ENABLE;
	GREG32_ADDR(FLASH, FSH_PE_CONTROL0)[fidx] = cmd;

	/* wait on FSH_PE_EN (means the operation started) */
	cnt = 500;  /* TODO(mschilder): pick sane value. */

	do {
		retval = GREG32(FLASH, FSH_PE_EN);
	} while (retval && cnt--);

	if (retval) {
		debug_printf("ERROR: FLASH_FSH_PE_EN never went to 0, is ");
		debug_printf("0x%x after timeout\n", retval);
		return E_FL_TIMEOUT;
	}

	/*
	 * wait 100us before checking FSH_PE_CONTROL (means the operation
	 * ended)
	 */
	cnt = 1000000;
	do {
		retval = GREG32_ADDR(FLASH, FSH_PE_CONTROL0)[fidx];
	} while (retval && --cnt);

	if (retval) {
		debug_printf
		    ("ERROR: FLASH_FSH_PE_CONTROL%d is 0x%x after timeout\n",
		     fidx, retval);
		GREG32_ADDR(FLASH, FSH_PE_CONTROL0)[fidx] = 0;
		return E_FL_TIMEOUT;
	}

	return 0;
}
Пример #19
0
int flash_physical_info_read_word(int byte_offset, uint32_t *dst)
{
	int ret;

	if (byte_offset % CONFIG_FLASH_WRITE_SIZE)
		return EC_ERROR_INVAL;

	ret = do_flash_op(OP_READ_BLOCK, 1, byte_offset, 1);
	if (ret != EC_SUCCESS)
		return ret;

	*dst = GREG32(FLASH, FSH_DOUT_VAL1);
	return EC_SUCCESS;
}
Пример #20
0
void dcrypto_sha_update(struct HASH_CTX *unused,
                        const void *data, uint32_t n)
{
    const uint8_t *bp = (const uint8_t *) data;
    const uint32_t *wp;

    /* Feed unaligned start bytes. */
    while (n != 0 && ((uint32_t)bp & 3)) {
        GREG8(KEYMGR, SHA_INPUT_FIFO) = *bp++;
        n -= 1;
    }

    /* Feed groups of aligned words. */
    wp = (uint32_t *)bp;
    while (n >= 8*4) {
        GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
        GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
        GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
        GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
        GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
        GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
        GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
        GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
        n -= 8*4;
    }
    /* Feed individual aligned words. */
    while (n >= 4) {
        GREG32(KEYMGR, SHA_INPUT_FIFO) = *wp++;
        n -= 4;
    }

    /* Feed remaing bytes. */
    bp = (uint8_t *) wp;
    while (n != 0) {
        GREG8(KEYMGR, SHA_INPUT_FIFO) = *bp++;
        n -= 1;
    }
}
Пример #21
0
void sps_tx_status(uint8_t byte)
{
	GREG32(SPS, DUMMY_WORD) = byte;
}
Пример #22
0
void usb_init(void)
{
	int i, resume;

	/* USB is in use */
	disable_sleep(SLEEP_MASK_USB_DEVICE);

	/*
	 * Resuming from a deep sleep is a lot like a cold boot, but there are
	 * few things that we need to do slightly differently. However, we ONLY
	 * do them if we're really resuming due to a USB wakeup. If we're woken
	 * for some other reason, we just do a normal USB reset. The host
	 * doesn't mind.
	 */
	resume = ((system_get_reset_flags() & RESET_FLAG_USB_RESUME) &&
		   (GR_USB_GINTSTS & GC_USB_GINTSTS_WKUPINT_MASK));

	/* TODO(crosbug.com/p/46813): Clean this up. Do only what's needed, and
	 * use meaningful constants instead of magic numbers. */
	GREG32(GLOBALSEC, DDMA0_REGION0_CTRL) = 0xffffffff;
	GREG32(GLOBALSEC, DDMA0_REGION1_CTRL) = 0xffffffff;
	GREG32(GLOBALSEC, DDMA0_REGION2_CTRL) = 0xffffffff;
	GREG32(GLOBALSEC, DDMA0_REGION3_CTRL) = 0xffffffff;
	GREG32(GLOBALSEC, DUSB0_REGION0_CTRL) = 0xffffffff;
	GREG32(GLOBALSEC, DUSB0_REGION1_CTRL) = 0xffffffff;
	GREG32(GLOBALSEC, DUSB0_REGION2_CTRL) = 0xffffffff;
	GREG32(GLOBALSEC, DUSB0_REGION3_CTRL) = 0xffffffff;

	/* Enable clocks */
	clock_enable_module(MODULE_USB, 1);

	/* TODO(crbug.com/496888): set up pinmux */
	gpio_config_module(MODULE_USB, 1);

	/* Make sure interrupts are disabled */
	GR_USB_GINTMSK = 0;
	GR_USB_DAINTMSK = 0;
	GR_USB_DIEPMSK = 0;
	GR_USB_DOEPMSK = 0;

	/* Select the correct PHY */
	usb_select_phy(which_phy);

	/* Full-Speed Serial PHY */
	GR_USB_GUSBCFG = GUSBCFG_PHYSEL_FS | GUSBCFG_FSINTF_6PIN
		| GUSBCFG_TOUTCAL(7)
		/* FIXME: Magic number! 14 is for 15MHz! Use 9 for 30MHz */
		| GUSBCFG_USBTRDTIM(14);

	if (!resume)
		/* Don't reset on resume, because some preserved internal state
		 * will be lost and there's no way to restore it. */
		usb_softreset();

	GR_USB_GUSBCFG = GUSBCFG_PHYSEL_FS | GUSBCFG_FSINTF_6PIN
		| GUSBCFG_TOUTCAL(7)
		/* FIXME: Magic number! 14 is for 15MHz! Use 9 for 30MHz */
		| GUSBCFG_USBTRDTIM(14);

	/* Global + DMA configuration */
	/* TODO: What about the AHB Burst Length Field? It's 0 now. */
	GR_USB_GAHBCFG = GAHBCFG_DMA_EN | GAHBCFG_GLB_INTR_EN |
		GAHBCFG_NP_TXF_EMP_LVL;

	/* Be in disconnected state until we are ready */
	if (!resume)
		usb_disconnect();

	if (resume)
		/* DEVADDR is preserved in the USB module during deep sleep,
		 * but it doesn't show up in USB_DCFG on resume. If we don't
		 * restore it manually too, it doesn't work. */
		GR_USB_DCFG = GREG32(PMU, PWRDN_SCRATCH18);
	else
		/* Init: USB2 FS, Scatter/Gather DMA, DEVADDR = 0x00 */
		GR_USB_DCFG |= DCFG_DEVSPD_FS48 | DCFG_DESCDMA;

	/* If we've restored a nonzero device address, update our state. */
	if (GR_USB_DCFG & GC_USB_DCFG_DEVADDR_MASK) {
		/* Caution: We only have one config TODAY, so there's no real
		 * difference between DS_CONFIGURED and DS_ADDRESS. */
		device_state = DS_CONFIGURED;
		configuration_value = 1;
	} else {
		device_state = DS_DEFAULT;
		configuration_value = 0;
	}

	/* Now that DCFG.DesDMA is accurate, prepare the FIFOs */
	setup_data_fifos();

	/* If resuming, reinitialize the endpoints now. For a cold boot we'll
	 * do this as part of handling the host-driven reset. */
	if (resume)
		usb_init_endpoints();

	/* Clear any pending interrupts */
	for (i = 0; i < 16; i++) {
		GR_USB_DIEPINT(i) = 0xffffffff;
		GR_USB_DOEPINT(i) = 0xffffffff;
	}
	GR_USB_GINTSTS = 0xFFFFFFFF;

	/* Unmask some endpoint interrupt causes */
	GR_USB_DIEPMSK = DIEPMSK_EPDISBLDMSK | DIEPMSK_XFERCOMPLMSK;
	GR_USB_DOEPMSK = DOEPMSK_EPDISBLDMSK | DOEPMSK_XFERCOMPLMSK |
		DOEPMSK_SETUPMSK;

	/* Enable interrupt handlers */
	task_enable_irq(GC_IRQNUM_USB0_USBINTR);

	/* Allow USB interrupts to come in */
	GR_USB_GINTMSK =
		/* NAK bits that must be cleared by the DCTL register */
		GINTMSK(GOUTNAKEFF) | GINTMSK(GINNAKEFF) |
		/* Initialization events */
		GINTMSK(USBRST) | GINTMSK(ENUMDONE) |
		/* Endpoint activity, cleared by the DOEPINT/DIEPINT regs */
		GINTMSK(OEPINT) | GINTMSK(IEPINT) |
		/* Reset detected while suspended. Need to wake up. */
		GINTMSK(RESETDET) |		/* TODO: Do we need this? */
		/* Idle, Suspend detected. Should go to sleep. */
		GINTMSK(ERLYSUSP) | GINTMSK(USBSUSP) |
		/* Watch for first SOF */
		GINTMSK(SOF);

	/* Device registers have been setup */
	GR_USB_DCTL |= DCTL_PWRONPRGDONE;
	udelay(10);
	GR_USB_DCTL &= ~DCTL_PWRONPRGDONE;

	/* Clear global NAKs */
	GR_USB_DCTL |= DCTL_CGOUTNAK | DCTL_CGNPINNAK;

#ifndef CONFIG_USB_INHIBIT_CONNECT
	/* Indicate our presence to the USB host */
	if (!resume)
		usb_connect();
#endif
}
Пример #23
0
static int command_sof(int argc, char **argv)
{
	ccprintf("FUSE_RC_TIMER_OSC48_CC_TRIM) 0x%08x\n",
		 GR_FUSE(RC_TIMER_OSC48_CC_TRIM));
	ccprintf("FUSE_RC_TIMER_OSC48_FC_TRIM) 0x%08x\n",
		 GR_FUSE(RC_TIMER_OSC48_FC_TRIM));

	ccprintf("CLK_TIMER_RC_COARSE_ATE_TRIM 0x%08x\n",
		 GREG32(XO, CLK_TIMER_RC_COARSE_ATE_TRIM));
	ccprintf("CLK_TIMER_RC_FINE_ATE_TRIM   0x%08x\n",
		 GREG32(XO, CLK_TIMER_RC_FINE_ATE_TRIM));

	ccprintf("CLK_TIMER_TRIM_CTRL          0x%08x\n",
		 GREG32(XO, CLK_TIMER_TRIM_CTRL));

	ccprintf("CLK_TIMER_CALIB_TRIM_CTRL    0x%08x\n",
		 GREG32(XO, CLK_TIMER_CALIB_TRIM_CTRL));

	ccprintf("DXO_INT_ENABLE               0x%08x\n",
		 GREG32(XO, DXO_INT_ENABLE));

	ccprintf("CLK_TIMER_SLOW_CALIB\n");
	ccprintf("  0: 0x%04x\n", GREG32(XO, CLK_TIMER_SLOW_CALIB0));
	ccprintf("  1: 0x%04x\n", GREG32(XO, CLK_TIMER_SLOW_CALIB1));
	ccprintf("  2: 0x%04x\n", GREG32(XO, CLK_TIMER_SLOW_CALIB2));
	ccprintf("  3: 0x%04x\n", GREG32(XO, CLK_TIMER_SLOW_CALIB3));
	ccprintf("  4: 0x%04x\n", GREG32(XO, CLK_TIMER_SLOW_CALIB4));
	ccprintf("  5: 0x%04x\n", GREG32(XO, CLK_TIMER_SLOW_CALIB5));
	ccprintf("  6: 0x%04x\n", GREG32(XO, CLK_TIMER_SLOW_CALIB6));
	ccprintf("  7: 0x%04x\n", GREG32(XO, CLK_TIMER_SLOW_CALIB7));

	ccprintf("CLK_TIMER_SLOW_CALIB_CTRL\n");
	ccprintf("  0: 0x%02x\n", GREG32(XO, CLK_TIMER_SLOW_CALIB_CTRL0));
	ccprintf("  1: 0x%02x\n", GREG32(XO, CLK_TIMER_SLOW_CALIB_CTRL1));
	ccprintf("  2: 0x%02x\n", GREG32(XO, CLK_TIMER_SLOW_CALIB_CTRL2));
	ccprintf("  3: 0x%02x\n", GREG32(XO, CLK_TIMER_SLOW_CALIB_CTRL3));
	ccprintf("  4: 0x%02x\n", GREG32(XO, CLK_TIMER_SLOW_CALIB_CTRL4));
	ccprintf("  5: 0x%02x\n", GREG32(XO, CLK_TIMER_SLOW_CALIB_CTRL5));
	ccprintf("  6: 0x%02x\n", GREG32(XO, CLK_TIMER_SLOW_CALIB_CTRL6));
	ccprintf("  7: 0x%02x\n", GREG32(XO, CLK_TIMER_SLOW_CALIB_CTRL7));
	ccprintf("  8: 0x%02x\n", GREG32(XO, CLK_TIMER_SLOW_CALIB_CTRL8));

	return EC_SUCCESS;
}
Пример #24
0
void flash_info_write_disable(void)
{
	GREG32(GLOBALSEC, FLASH_REGION3_CTRL) = 0;
}
Пример #25
0
void init_sof_clock(void)
{
	/* Copy fuse value into software registers, both coarse and fine */
	unsigned coarseTrimVal = GR_FUSE(RC_TIMER_OSC48_CC_TRIM);
	unsigned fineTrimVal = GR_FUSE(RC_TIMER_OSC48_FC_TRIM);

	/* We think SOF toggle happens once every mS, or ~24000 clock ticks */
	unsigned targetCnt = PCLK_FREQ / 1000;

	/* The possible operations of a particular calibration bucket */
	unsigned binaryDnOp = 0x1 | 0x1 << 4;
	unsigned binaryUpOp = 0x1 | 0x0 << 4;
	unsigned subOp      = 0x3 | 0x1 << 4;
	unsigned addOp      = 0x2 | 0x1 << 4;
	unsigned nop        = 0;

	GREG32(XO, CLK_TIMER_RC_COARSE_ATE_TRIM) = coarseTrimVal;
	GREG32(XO, CLK_TIMER_RC_FINE_ATE_TRIM) = fineTrimVal;

	/* Coarse trim values come from software */
	GWRITE_FIELD(XO, CLK_TIMER_TRIM_CTRL, RC_COARSE_TRIM_SRC, 0);

	/* enable error interrupts
	 * This enables underrun and overflow interrupts */
	GREG32(XO, DXO_INT_ENABLE) = 0xC;

	/* Setup SOF calibration buckets and associated operations */
	GREG32(XO, CLK_TIMER_SLOW_CALIB0) = targetCnt * 70 / 100;
	GREG32(XO, CLK_TIMER_SLOW_CALIB1) = targetCnt * 80 / 100;
	GREG32(XO, CLK_TIMER_SLOW_CALIB2) = targetCnt * 90 / 100;
	GREG32(XO, CLK_TIMER_SLOW_CALIB3) =
		targetCnt * (1000000 - 1250) / 1000000;
	GREG32(XO, CLK_TIMER_SLOW_CALIB4) = targetCnt;
	GREG32(XO, CLK_TIMER_SLOW_CALIB5) =
		targetCnt * (1000000 + 1250) / 1000000;
	GREG32(XO, CLK_TIMER_SLOW_CALIB6) = targetCnt * 110 / 100;
	GREG32(XO, CLK_TIMER_SLOW_CALIB7) = targetCnt * 120 / 100;

	/* This is a work-around for the screwy SOF */
	GREG32(XO, CLK_TIMER_SLOW_CALIB_CTRL0) = nop;
	GREG32(XO, CLK_TIMER_SLOW_CALIB_CTRL1) = binaryDnOp;
	GREG32(XO, CLK_TIMER_SLOW_CALIB_CTRL2) = binaryDnOp;
	GREG32(XO, CLK_TIMER_SLOW_CALIB_CTRL3) = subOp;
	GREG32(XO, CLK_TIMER_SLOW_CALIB_CTRL4) = nop;
	GREG32(XO, CLK_TIMER_SLOW_CALIB_CTRL5) = nop;
	GREG32(XO, CLK_TIMER_SLOW_CALIB_CTRL6) = addOp;
	GREG32(XO, CLK_TIMER_SLOW_CALIB_CTRL7) = binaryUpOp;
	GREG32(XO, CLK_TIMER_SLOW_CALIB_CTRL8) = binaryUpOp;

	/* Set the calibration mode */
	GWRITE_FIELD(XO, CLK_TIMER_CALIB_TRIM_CTRL, ENABLE_FAST, 0);
	GWRITE_FIELD(XO, CLK_TIMER_CALIB_TRIM_CTRL, ENABLE_SLOW, 1);
	GWRITE_FIELD(XO, CLK_TIMER_CALIB_TRIM_CTRL, SLOW_MODE_SEL, 0); /* SOF */
	GWRITE_FIELD(XO, CLK_TIMER_CALIB_TRIM_CTRL, MAX_TRIM_SEL, 1);
	/* Don't stop when a NOP operation is seen, keep on calibrating */
	GWRITE_FIELD(XO, CLK_TIMER_CALIB_TRIM_CTRL, STOP_ON_NOP, 0);

	/* Set source of trim codes:
	 * coarse trim comes from software
	 * fine trim comes from calibration engine */
	GWRITE_FIELD(XO, CLK_TIMER_TRIM_CTRL, RC_COARSE_TRIM_SRC, 0);
	GWRITE_FIELD(XO, CLK_TIMER_TRIM_CTRL, RC_FINE_TRIM_SRC, 1);

	/* Enable dynamic trim */
	GWRITE_FIELD(XO, CLK_TIMER_TRIM_CTRL, RC_TRIM_EN, 1);

	/* Sync everything! */
	GREG32(XO, CLK_TIMER_SYNC_CONTENTS) = 1;

	/* Enable interrupts */
	task_enable_irq(GC_IRQNUM_XO0_SLOW_CALIB_UNDERRUN_INT);
	task_enable_irq(GC_IRQNUM_XO0_SLOW_CALIB_OVERFLOW_INT);
}