Ejemplo n.º 1
0
void usb_spi_board_disable(struct usb_spi_config const *config)
{
	CPRINTS("usb_spi disable");
	spi_enable(CONFIG_SPI_FLASH_PORT, 0);
	disable_ec_ap_spi();

	/* Disconnect SPI peripheral to tri-state pads */
	/* Disable internal pull up */
	GWRITE_FIELD(PINMUX, DIOA14_CTL, PU, 0);
	/* TODO: Implement way to get the gpio */
	ASSERT(GREAD(PINMUX, GPIO0_GPIO7_SEL) == GC_PINMUX_DIOA4_SEL);
	ASSERT(GREAD(PINMUX, GPIO0_GPIO8_SEL) == GC_PINMUX_DIOA8_SEL);
	ASSERT(GREAD(PINMUX, GPIO0_GPIO9_SEL) == GC_PINMUX_DIOA14_SEL);

	/* Set SPI MOSI, CLK, and CS_L as inputs */
	GWRITE(PINMUX, DIOA4_SEL, GC_PINMUX_GPIO0_GPIO7_SEL);
	GWRITE(PINMUX, DIOA8_SEL, GC_PINMUX_GPIO0_GPIO8_SEL);
	GWRITE(PINMUX, DIOA14_SEL, GC_PINMUX_GPIO0_GPIO9_SEL);

	/*
	 * TODO(crosbug.com/p/52366): remove once sys_rst just resets the TPM
	 * instead of cr50.
	 * Resetting the EC and AP cause sys_rst to be asserted currently that
	 * will cause cr50 to do a soft reset. Delay the end of the transaction
	 * to prevent cr50 from resetting during a series of usb_spi calls.
	 */
	hook_call_deferred(&update_finished_data, 1 * SECOND);
}
Ejemplo n.º 2
0
void usb_spi_board_enable(struct usb_spi_config const *config)
{
	hook_call_deferred(&update_finished_data, -1);
	update_in_progress = 1;

	disable_ec_ap_spi();

	if (config->state->enabled_host == USB_SPI_EC)
		enable_ec_spi();
	else if (config->state->enabled_host == USB_SPI_AP)
		enable_ap_spi();
	else {
		CPRINTS("DEVICE NOT SUPPORTED");
		return;
	}

	/* Connect DIO A4, A8, and A14 to the SPI peripheral */
	GWRITE(PINMUX, DIOA4_SEL, 0); /* SPI_MOSI */
	GWRITE(PINMUX, DIOA8_SEL, 0); /* SPI_CS_L */
	GWRITE(PINMUX, DIOA14_SEL, 0); /* SPI_CLK */
	/* Set SPI_CS to be an internal pull up */
	GWRITE_FIELD(PINMUX, DIOA14_CTL, PU, 1);

	CPRINTS("usb_spi enable %s",
		gpio_get_level(GPIO_AP_FLASH_SELECT) ? "AP" : "EC");

	spi_enable(CONFIG_SPI_FLASH_PORT, 1);
}
Ejemplo n.º 3
0
void rbox_init(void)
{
	/* Enable RBOX */
	clock_enable_module(MODULE_RBOX, 1);

	/* Clear existing interrupts */
	GWRITE(RBOX, WAKEUP_CLEAR, 1);
	GWRITE(RBOX, INT_STATE, 1);

	/* Make sure fuse override is not already enabled */
	GWRITE(RBOX, FUSE_CTRL, 0);

	/* Block output from key0 and 1 when power button is pressed */
	GWRITE_FIELD(RBOX, DEBUG_BLOCK_OUTPUT, KEY0_SEL, 1);
	GWRITE_FIELD(RBOX, DEBUG_BLOCK_OUTPUT, KEY1_SEL, 1);

	/* Increase debounce */
	GWRITE_FIELD(RBOX, DEBUG_DEBOUNCE, PERIOD, 15);

	/* Enable debug override */
	GWRITE_FIELD(RBOX, FUSE_CTRL, OVERRIDE_FUSE, 1);
	GWRITE_FIELD(RBOX, FUSE_CTRL, OVERRIDE_FUSE_READY, 1);

#ifdef CONFIG_RBOX_DEBUG
	enable_interrupts();
#endif
}
Ejemplo n.º 4
0
void PIMPTBLWR(Word C, Word R, Word V)
{
       Word R1,Rp,T,V1,Vp,d,i,j,l,m,n,v;
       /* hide d,i,j,m,n; */

Step1: /* Draw the column heading. */
       m = LENGTH(C); n = LENGTH(R);
       if (m >= 1000 || n >= 1000)
         { SWRITE("PIMPTBLWR: Sorry the table is too big.\n"); goto Return; }
       SWRITE("=======");
       for (i = 1; i <= m; i++)
         { if (LELTI(C,i) == ALIVE) CWRITE('='); }
       SWRITE("\n       ");
       for (i = 1; i <= m; i++)
         { if (LELTI(C,i) == ALIVE) { d = i / 100; CWRITE(d + '0'); } }
       SWRITE("\n       ");
       for (i = 1; i <= m; i++)
         { if (LELTI(C,i) == ALIVE) { d = REM(i,100) / 10; CWRITE(d + '0'); } }
       SWRITE("\n       ");
       for (i = 1; i <= m; i++)
         { if (LELTI(C,i) == ALIVE) { d = REM(i,10); CWRITE(d + '0'); } }
       SWRITE("\n       ");
       for (i = 1; i <= m; i++)
         { if (LELTI(C,i) == ALIVE) CWRITE('-'); }
       SWRITE("\n");

Step2: /* Draw each rows. */
       Vp = V; Rp = R;
       for (j = 1; j <= n; j++)
         {
         ADV(Rp,&R1,&Rp); ADV(Vp,&V1,&Vp);
         if (R1 == ALIVE)
           {
           FIRST3(V1,&v,&l,&T);
           GWRITE(l); TAB(3);
           GWRITE(j); TAB(6); CWRITE('|');
           for (i = 1; i <= m; i++)
             {
             if (LELTI(C,i) == ALIVE)
               {
               if (INSET(T,i))
                 CWRITE('X');
               else
                 CWRITE('.');
               }
             }
           SWRITE("\n");
           }
         }

Step3: /* Draw the final line. */
       SWRITE("=======");
       for (i = 1; i <= m; i++)
         { if (LELTI(C,i) == ALIVE) CWRITE('='); }
       SWRITE("\n");

Return: /* Prepare for return. */
       return;
}
Ejemplo n.º 5
0
void PCADWR(Word c)
{
    Word M,cb,cp,p,s;
    /* hide p; */

Step1: /* common. */
    LWRITE(LELTI(c,INDX));
    if (LELTI(c,LEVEL) > 0)
    {
        s = LELTI(c,SAMPLE);
        if (ISPRIMIT(s)) CWRITE('p');
        else CWRITE('e');
        GWRITE(CELLDEG(c));
    }
    cb = LELTI(c,CHILD);

Step2: /* c is a leaf. */
    if (cb == NIL)
    {
        SWRITE(" ");
        TRUTHWR(LELTI(c,TRUTH));
        SWRITE("\n");
        goto Return;
    }

Step3: /* c is not a leaf. */
    p = OPOS;
    ADV(cb,&cp,&cb);
    SWRITE("---");
    PCADWR(cp);
    while (cb != NIL)
    {
        TAB(p);
        ADV(cb,&cp,&cb);
        SWRITE("---");
        PCADWR(cp);
    }

Return: /* Prepare for return. */
    return;
}
Ejemplo n.º 6
0
void SAMPLEWR(Word k, Word s, Word PCNUMDEC)
{
       Word I,Ip,M,Mp,b,bp,F,j,Ms,Is;
       Word M1;

Step2: /* Extended representation. */
       if (ISPRIMIT(s)) goto Step3;
       FIRST5(s,&M,&I,&Mp,&Ip,&bp);
       SWRITE("The sample point is in an EXTENDED representation.\n\n");

       SWRITE("alpha = "); IUPRWR(LFS("x"),Mp,Ip); SWRITE("\n");
       SWRITE("      = "); ANDWRITE(Mp,Ip,PCNUMDEC); SWRITE("\n\n"); 

       AFLWR(Mp,Ip,LFS("Coordinate "),LFS("alpha"),bp,PCNUMDEC);

       SWRITE("Coordinate "); GWRITE(k); SWRITE(" = ");
       AFUPRWR(LFS("alpha"),LFS("x"),M,I);  SWRITE("\n");
       F = AFPNIP(Mp,M);  
       M = AFPICR(1,M);
       IPSRP(2,M,&M1,&M);
       AMUPMPR(Mp,Ip,M,I,F,&Is,&j);
       Ms = LELTI(F,j); 
       Is = IPSIFI(Ms,Is);  
       SWRITE("             = "); 
       IUPRWR(LFS("x"),Ms,Is);  SWRITE("\n");
       SWRITE("             = "); 
       ANDWRITE(Ms,Is,PCNUMDEC); SWRITE("\n");
       goto Return;

Step3: /* Primitive representation. */
       FIRST3(s,&M,&I,&b);
       SWRITE("The sample point is in a PRIMITIVE representation.\n\n");

       SWRITE("alpha = "); IUPRWR(LFS("x"),M,I); SWRITE("\n");
       SWRITE("      = "); ANDWRITE(M,I,PCNUMDEC); SWRITE("\n\n"); 

       AFLWR(M,I,LFS("Coordinate "),LFS("alpha"),b,PCNUMDEC);  SWRITE("\n");

Return: /* Prepare for return. */
       return;
}
Ejemplo n.º 7
0
void QepcadCls::CELLWR(Word c)
{
       Word S,S1,k,t,i,D,M;
       /* hide t; */

Step1: /* Heading. */
       k = LELTI(c,LEVEL);
       SWRITE("---------- Information about the cell "); LWRITE(LELTI(c,INDX));
       SWRITE(" ----------\n\n");

Step2: /* Level. */
       SWRITE("Level                       : ");
       GWRITE(LELTI(c,LEVEL)); SWRITE("\n");

Step3: /* Dimension. */
       if (k == 0) goto Step4;
       SWRITE("Dimension                   : ");
       GWRITE(CELLDIM(c)); SWRITE("\n");

Step4: /* Number of children. */
       SWRITE("Number of children          : ");
       GWRITE(LENGTH(LELTI(c,CHILD))); SWRITE("\n");

Step5: /* Truth value. */
       SWRITE("Truth value                 : ");
       TRUTHWR(LELTI(c,TRUTH)); 
       t = LELTI(c,HOWTV);
       if (t == BYPRP)
         SWRITE("    by propagation.");
       else if (t == BYTEV)
         SWRITE("    by trial evaluation.");
       else if (t == BYEQC)
         SWRITE("    by equational constraint.");
       SWRITE("\n");

Step6: /* Degrees of the substituted polys. */
       SWRITE("Degrees after substitution  : ");
       D = LELTI(c,DEGSUB);
       if (D == NIL) 
         SWRITE("Not known yet or No polynomial.");
       else
         LWRITE(D);
       SWRITE("\n");

Step7: /* Multiplicities of the projection factors. */
       SWRITE("Multiplicities              : ");
       M = LELTI(c,MULSUB);
       LWRITE(M);
       SWRITE("\n");

Step8: /* Signs of Projection Factors. */
       SWRITE("Signs of Projection Factors\n");
       S = LELTI(c,SIGNPF);
       for (i = 1; i <= k; i++)
         {
         S1 = LELTI(S,k-i+1);
         SWRITE("Level "); GWRITE(i); SWRITE("  : ");
         if (S1 == 0)
           SWRITE("Not determined");
         else
           SIGNLWR(S1);
         SWRITE("\n");
         }

Step9: /* Sample point. */
       if (k == 0) goto Step10;
       SWRITE("----------   Sample point  ---------- \n");
       SAMPLEWR(c);

Step10: /* Finish. */
       SWRITE("\n----------------------------------------------------\n");
       goto Return;

Return: /* Prepare for return. */
       return;
}
Ejemplo n.º 8
0
static int do_flash_op(enum flash_op op, int is_info_bank,
		       int byte_offset, int words)
{
	volatile uint32_t *fsh_pe_control;
	uint32_t opcode, tmp, errors;
	int retry_count, max_attempts, extra_prog_pulse, i;
	int timedelay_us = 100;
	uint32_t prev_error = 0;

	/* Make sure the smart program/erase algorithms are enabled. */
	if (!GREAD(FLASH, FSH_TIMING_PROG_SMART_ALGO_ON) ||
	    !GREAD(FLASH, FSH_TIMING_ERASE_SMART_ALGO_ON)) {
		CPRINTF("%s:%d\n", __func__, __LINE__);
		return EC_ERROR_UNIMPLEMENTED;
	}

	/* Error status is self-clearing. Read it until it does (we hope). */
	for (i = 0; i < 50; i++) {
		tmp = GREAD(FLASH, FSH_ERROR);
		if (!tmp)
			break;
		usleep(timedelay_us);
	}
	/* If we can't clear the error status register then something is wrong.
	 */
	if (tmp) {
		CPRINTF("%s:%d\n", __func__, __LINE__);
		return EC_ERROR_UNKNOWN;
	}

	/* We have two flash banks. Adjust offset and registers accordingly. */
	if (is_info_bank) {
		/* Only INFO bank operations are supported. */
		fsh_pe_control = GREG32_ADDR(FLASH, FSH_PE_CONTROL1);
	} else if (byte_offset >= CFG_FLASH_HALF) {
		byte_offset -= CFG_FLASH_HALF;
		fsh_pe_control = GREG32_ADDR(FLASH, FSH_PE_CONTROL1);
	} else {
		fsh_pe_control = GREG32_ADDR(FLASH, FSH_PE_CONTROL0);
	}

	/* What are we doing? */
	switch (op) {
	case OP_ERASE_BLOCK:
		if (is_info_bank)
			/* Erasing the INFO bank from the RW section is
			 * unsupported. */
			return EC_ERROR_INVAL;
		opcode = 0x31415927;
		words = 0;			/* don't care, really */
		/* This number is based on the TSMC spec Nme=Terase/Tsme */
		max_attempts = 45;
		break;
	case OP_WRITE_BLOCK:
		opcode = 0x27182818;
		words--;		     /* count register is zero-based */
		/* This number is based on the TSMC spec Nmp=Tprog/Tsmp */
		max_attempts = 9;
		break;
	case OP_READ_BLOCK:
		if (!is_info_bank)
			/* This code path only supports reading from
			 * the INFO bank.
			 */
			return EC_ERROR_INVAL;
		opcode = 0x16021765;
		words = 1;
		max_attempts = 9;
		break;
	default:
		return EC_ERROR_INVAL;
	}

	/*
	 * Set the parameters. For writes, we assume the write buffer is
	 * already filled before we call this function.
	 */
	GWRITE_FIELD(FLASH, FSH_TRANS, OFFSET,
		     byte_offset / 4);		  /* word offset */
	GWRITE_FIELD(FLASH, FSH_TRANS, MAINB, is_info_bank ? 1 : 0);
	GWRITE_FIELD(FLASH, FSH_TRANS, SIZE, words);

	/* TODO: Make sure this function isn't getting called "too often" in
	 * between erases.
	 */
	extra_prog_pulse = 0;
	for (retry_count = 0; retry_count < max_attempts; retry_count++) {
		/* Kick it off */
		GWRITE(FLASH, FSH_PE_EN, 0xb11924e1);
		*fsh_pe_control = opcode;

		/* Wait for completion. 150ms should be enough
		 * (crosbug.com/p/45366).
		 */
		for (i = 0; i < 1500; i++) {
			tmp = *fsh_pe_control;
			if (!tmp)
				break;
			usleep(timedelay_us);
		}

		/* Timed out waiting for control register to clear */
		if (tmp) {
			CPRINTF("%s:%d\n", __func__, __LINE__);
			return EC_ERROR_UNKNOWN;
		}
		/* Check error status */
		errors = GREAD(FLASH, FSH_ERROR);

		if (errors && (errors != prev_error)) {
			prev_error = errors;
			CPRINTF("%s:%d errors %x fsh_pe_control %p\n",
				__func__, __LINE__, errors, fsh_pe_control);
		}
		/* Error status is self-clearing. Read it until it does
		 * (we hope).
		 */
		for (i = 0; i < 50; i++) {
			tmp = GREAD(FLASH, FSH_ERROR);
			if (!tmp)
				break;
			usleep(timedelay_us);
		}
		/* If we can't clear the error status register then something
		 * is wrong.
		 */
		if (tmp) {
			CPRINTF("%s:%d\n", __func__, __LINE__);
			return EC_ERROR_UNKNOWN;
		}
		/* The operation was successful. */
		if (!errors) {
			/* From the spec:
			 * "In addition, one more program pulse is needed after
			 * program verification is passed."
			 */
			if (op == OP_WRITE_BLOCK && !extra_prog_pulse) {
				extra_prog_pulse = 1;
				max_attempts++;
				continue;
			}
			return EC_SUCCESS;
		}
		/* If there were errors after completion retry. */
		watchdog_reload();
	}
	CPRINTF("%s:%d, retry count %d\n", __func__, __LINE__, retry_count);
	return EC_ERROR_UNKNOWN;
}