示例#1
0
static int do_sdhci_init(struct sdhci_host *host)
{
	int dev_id, flag;
	int err = 0;

	flag = host->bus_width == 8 ? PINMUX_FLAG_8BIT_MODE : PINMUX_FLAG_NONE;
	dev_id = host->index + PERIPH_ID_SDMMC0;

	if (fdt_gpio_isvalid(&host->pwr_gpio)) {
		gpio_direction_output(host->pwr_gpio.gpio, 1);
		err = exynos_pinmux_config(dev_id, flag);
		if (err) {
			debug("MMC not configured\n");
			return err;
		}
	}

	if (fdt_gpio_isvalid(&host->cd_gpio)) {
		gpio_direction_output(host->cd_gpio.gpio, 0xf);
		if (gpio_get_value(host->cd_gpio.gpio))
			return -ENODEV;

		err = exynos_pinmux_config(dev_id, flag);
		if (err) {
			printf("external SD not configured\n");
			return err;
		}
	}

	return s5p_sdhci_core_init(host);
}
示例#2
0
int fdtdec_set_gpio(struct fdt_gpio_state *gpio, int val)
{
	if (!fdt_gpio_isvalid(gpio))
		return -1;

	val = gpio->flags & FDT_GPIO_ACTIVE_LOW ? val ^ 1 : val;
	return gpio_set_value(gpio->gpio, val);
}
示例#3
0
int cros_ec_interrupt_pending(struct cros_ec_dev *dev)
{
	/* no interrupt support : always poll */
	if (!fdt_gpio_isvalid(&dev->ec_int))
		return -ENOENT;

	return !gpio_get_value(dev->ec_int.gpio);
}
示例#4
0
void fdt_setup_gpio(struct fdt_gpio_state *gpio)
{
	if (!fdt_gpio_isvalid(gpio))
		return;

	if (gpio->flags & FDT_GPIO_OUTPUT)
		gpio_direction_output(gpio->gpio, gpio->flags & FDT_GPIO_HIGH);
	else
		gpio_direction_input(gpio->gpio);
}
示例#5
0
int fdtdec_setup_gpio(struct fdt_gpio_state *gpio)
{
	/*
	 * Return success if there is no GPIO defined. This is used for
	 * optional GPIOs)
	 */
	if (!fdt_gpio_isvalid(gpio))
		return 0;

	if (gpio_request(gpio->gpio, gpio->name))
		return -1;
	return 0;
}
示例#6
0
void fdt_setup_gpios(struct fdt_gpio_state *gpio_list)
{
	struct fdt_gpio_state *gpio;
	int i;

	for (i = 0, gpio = gpio_list; fdt_gpio_isvalid(gpio); i++, gpio++) {
		if (i > FDT_GPIO_MAX) {
			/* Something may have gone horribly wrong */
			printf("FDT: fdt_setup_gpios: too many GPIOs\n");
			return;
		}
		fdt_setup_gpio(gpio);
	}
}
示例#7
0
文件: usb.c 项目: AshishNamdev/u-boot
/* Put the port into host mode (this only works for OTG ports) */
static void set_host_mode(struct fdt_usb *config)
{
	if (config->dr_mode == DR_MODE_OTG) {
		/* Check whether remote host from USB1 is driving VBus */
		if (readl(&config->reg->phy_vbus_sensors) & VBUS_VLD_STS)
			return;

		/*
		 * If not driving, we set the GPIO to enable VBUS. We assume
		 * that the pinmux is set up correctly for this.
		 */
		if (fdt_gpio_isvalid(&config->vbus_gpio)) {
			fdtdec_setup_gpio(&config->vbus_gpio);
			gpio_direction_output(config->vbus_gpio.gpio, 1);
			debug("set_host_mode: GPIO %d high\n",
			      config->vbus_gpio.gpio);
		}
	}
}
示例#8
0
int board_dp_bridge_setup(const void *blob, unsigned *wait_ms)
{
	int ret;

	ret = board_dp_fill_gpios(blob);
	if (ret)
		return ret;

	/* Mux HPHPD to the special hotplug detect mode */
	exynos_pinmux_config(PERIPH_ID_DPHPD, 0);

	/* Setup the GPIOs */
	ret = fdtdec_setup_gpio(&local.dp_pd);
	if (ret) {
		debug("%s: Could not setup pd gpio (%d)\n", __func__, ret);
		return ret;
	}
	ret = fdtdec_setup_gpio(&local.dp_rst);
	if (ret) {
		debug("%s: Could not setup rst gpio (%d)\n", __func__, ret);
		return ret;
	}
	ret = fdtdec_setup_gpio(&local.dp_hpd);
	if (ret) {
		debug("%s: Could not setup hpd gpio (%d)\n", __func__, ret);
		return ret;
	}

	fdtdec_set_gpio(&local.dp_pd, 0);
	gpio_cfg_pin(local.dp_pd.gpio, EXYNOS_GPIO_OUTPUT);
	gpio_set_pull(local.dp_pd.gpio, EXYNOS_GPIO_PULL_NONE);
	if (fdt_gpio_isvalid(&local.dp_rst)) {
		fdtdec_set_gpio(&local.dp_rst, 1);
		gpio_cfg_pin(local.dp_rst.gpio, EXYNOS_GPIO_OUTPUT);
		gpio_set_pull(local.dp_rst.gpio, EXYNOS_GPIO_PULL_NONE);
		udelay(10);
		fdtdec_set_gpio(&local.dp_rst, 0);
	}

	*wait_ms = 0;
	return 0;
}
示例#9
0
int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor)
{
	struct exynos_xhci *ctx = &exynos;
	int ret;

#ifdef CONFIG_OF_CONTROL
	exynos_usb3_parse_dt(gd->fdt_blob, ctx);
#else
	ctx->usb3_phy = (struct exynos_usb3_phy *)samsung_get_base_usb3_phy();
	ctx->hcd = (struct xhci_hccr *)samsung_get_base_usb_xhci();
#endif

	ctx->dwc3_reg = (struct dwc3 *)((char *)(ctx->hcd) + DWC3_REG_OFFSET);

#ifdef CONFIG_OF_CONTROL
	/* setup the Vbus gpio here */
	if (fdt_gpio_isvalid(&ctx->vbus_gpio) &&
	    !fdtdec_setup_gpio(&ctx->vbus_gpio))
		gpio_direction_output(ctx->vbus_gpio.gpio, 1);
#endif

	ret = exynos_xhci_core_init(ctx);
	if (ret) {
		puts("XHCI: failed to initialize controller\n");
		return -EINVAL;
	}

	*hccr = (ctx->hcd);
	*hcor = (struct xhci_hcor *)((uint32_t) *hccr
				+ HC_LENGTH(xhci_readl(&(*hccr)->cr_capbase)));

	debug("Exynos5-xhci: init hccr %x and hcor %x hc_length %d\n",
		(uint32_t)*hccr, (uint32_t)*hcor,
		(uint32_t)HC_LENGTH(xhci_readl(&(*hccr)->cr_capbase)));

	return 0;
}
示例#10
0
/*
 * EHCI-initialization
 * Create the appropriate control structures to manage
 * a new EHCI host controller.
 */
int ehci_hcd_init(int index, enum usb_init_type init,
		struct ehci_hccr **hccr, struct ehci_hcor **hcor)
{
	struct exynos_ehci *ctx = &exynos;

#ifdef CONFIG_OF_CONTROL
	if (exynos_usb_parse_dt(gd->fdt_blob, ctx)) {
		debug("Unable to parse device tree for ehci-exynos\n");
		return -ENODEV;
	}
#else
	ctx->usb = (struct exynos_usb_phy *)samsung_get_base_usb_phy();
	ctx->hcd = (struct ehci_hccr *)samsung_get_base_usb_ehci();
#endif

#ifdef CONFIG_OF_CONTROL
	/* setup the Vbus gpio here */
	if (fdt_gpio_isvalid(&ctx->vbus_gpio) &&
	    !fdtdec_setup_gpio(&ctx->vbus_gpio))
		gpio_direction_output(ctx->vbus_gpio.gpio, 1);
#endif

	setup_usb_phy(ctx->usb);

	board_usb_init(index, init);

	*hccr = ctx->hcd;
	*hcor = (struct ehci_hcor *)((uint32_t) *hccr
				+ HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));

	debug("Exynos5-ehci: init hccr %x and hcor %x hc_length %d\n",
		(uint32_t)*hccr, (uint32_t)*hcor,
		(uint32_t)HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));

	return 0;
}
示例#11
0
/* Put the port into host mode */
static void set_host_mode(struct fdt_usb *config)
{
	/*
	 * If we are an OTG port, check if remote host is driving VBus and
	 * bail out in this case.
	 */
	if (config->dr_mode == DR_MODE_OTG &&
		(readl(&config->reg->phy_vbus_sensors) & VBUS_VLD_STS))
		return;

	/*
	 * If not driving, we set the GPIO to enable VBUS. We assume
	 * that the pinmux is set up correctly for this.
	 */
	if (fdt_gpio_isvalid(&config->vbus_gpio)) {
		fdtdec_setup_gpio(&config->vbus_gpio);
		gpio_direction_output(config->vbus_gpio.gpio,
			(config->vbus_gpio.flags & FDT_GPIO_ACTIVE_LOW) ?
				 0 : 1);
		debug("set_host_mode: GPIO %d %s\n", config->vbus_gpio.gpio,
			(config->vbus_gpio.flags & FDT_GPIO_ACTIVE_LOW) ?
				"low" : "high");
	}
}
示例#12
0
int fdt_get_gpio_num(struct fdt_gpio_state *gpio)
{
	return fdt_gpio_isvalid(gpio) ? gpio->gpio : -1;
}
示例#13
0
/* set up the ULPI USB controller with the parameters provided */
static int init_ulpi_usb_controller(struct fdt_usb *config,
				struct usb_ctlr *usbctlr)
{
	u32 val;
	int loop_count;
	struct ulpi_viewport ulpi_vp;

	/* set up ULPI reference clock on pllp_out4 */
	clock_enable(PERIPH_ID_DEV2_OUT);
	clock_set_pllout(CLOCK_ID_PERIPH, PLL_OUT4, CONFIG_ULPI_REF_CLK);

	/* reset ULPI phy */
	if (fdt_gpio_isvalid(&config->phy_reset_gpio)) {
		fdtdec_setup_gpio(&config->phy_reset_gpio);
		gpio_direction_output(config->phy_reset_gpio.gpio, 0);
		mdelay(5);
		gpio_set_value(config->phy_reset_gpio.gpio, 1);
	}

	/* Reset the usb controller */
	clock_enable(config->periph_id);
	usbf_reset_controller(config, usbctlr);

	/* enable pinmux bypass */
	setbits_le32(&usbctlr->ulpi_timing_ctrl_0,
			ULPI_CLKOUT_PINMUX_BYP | ULPI_OUTPUT_PINMUX_BYP);

	/* Select ULPI parallel interface */
	clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK, PTS_ULPI << PTS_SHIFT);

	/* enable ULPI transceiver */
	setbits_le32(&usbctlr->susp_ctrl, ULPI_PHY_ENB);

	/* configure ULPI transceiver timings */
	val = 0;
	writel(val, &usbctlr->ulpi_timing_ctrl_1);

	val |= ULPI_DATA_TRIMMER_SEL(4);
	val |= ULPI_STPDIRNXT_TRIMMER_SEL(4);
	val |= ULPI_DIR_TRIMMER_SEL(4);
	writel(val, &usbctlr->ulpi_timing_ctrl_1);
	udelay(10);

	val |= ULPI_DATA_TRIMMER_LOAD;
	val |= ULPI_STPDIRNXT_TRIMMER_LOAD;
	val |= ULPI_DIR_TRIMMER_LOAD;
	writel(val, &usbctlr->ulpi_timing_ctrl_1);

	/* set up phy for host operation with external vbus supply */
	ulpi_vp.port_num = 0;
	ulpi_vp.viewport_addr = (u32)&usbctlr->ulpi_viewport;

	if (ulpi_init(&ulpi_vp)) {
		printf("Tegra ULPI viewport init failed\n");
		return -1;
	}

	ulpi_set_vbus(&ulpi_vp, 1, 1);
	ulpi_set_vbus_indicator(&ulpi_vp, 1, 1, 0);

	/* enable wakeup events */
	setbits_le32(&usbctlr->port_sc1, WKCN | WKDS | WKOC);

	/* Enable and wait for the phy clock to become valid in 100 ms */
	setbits_le32(&usbctlr->susp_ctrl, USB_SUSP_CLR);
	for (loop_count = 100000; loop_count != 0; loop_count--) {
		if (readl(&usbctlr->susp_ctrl) & USB_PHY_CLK_VALID)
			break;
		udelay(1);
	}
	if (!loop_count)
		return -1;
	clrbits_le32(&usbctlr->susp_ctrl, USB_SUSP_CLR);

	return 0;
}
示例#14
0
/* set up the UTMI USB controller with the parameters provided */
static int init_utmi_usb_controller(struct fdt_usb *config,
				struct usb_ctlr *usbctlr, const u32 timing[])
{
	u32 val;
	int loop_count;

	clock_enable(config->periph_id);

	/* Reset the usb controller */
	usbf_reset_controller(config, usbctlr);

	/* Stop crystal clock by setting UTMIP_PHY_XTAL_CLOCKEN low */
	clrbits_le32(&usbctlr->utmip_misc_cfg1, UTMIP_PHY_XTAL_CLOCKEN);

	/* Follow the crystal clock disable by >100ns delay */
	udelay(1);

	/*
	 * To Use the A Session Valid for cable detection logic, VBUS_WAKEUP
	 * mux must be switched to actually use a_sess_vld threshold.
	 */
	if (fdt_gpio_isvalid(&config->vbus_gpio)) {
		clrsetbits_le32(&usbctlr->usb1_legacy_ctrl,
			VBUS_SENSE_CTL_MASK,
			VBUS_SENSE_CTL_A_SESS_VLD << VBUS_SENSE_CTL_SHIFT);
	}

	/*
	 * PLL Delay CONFIGURATION settings. The following parameters control
	 * the bring up of the plls.
	 */
	val = readl(&usbctlr->utmip_misc_cfg1);
	clrsetbits_le32(&val, UTMIP_PLLU_STABLE_COUNT_MASK,
		timing[PARAM_STABLE_COUNT] << UTMIP_PLLU_STABLE_COUNT_SHIFT);
	clrsetbits_le32(&val, UTMIP_PLL_ACTIVE_DLY_COUNT_MASK,
		timing[PARAM_ACTIVE_DELAY_COUNT] <<
			UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT);
	writel(val, &usbctlr->utmip_misc_cfg1);

	/* Set PLL enable delay count and crystal frequency count */
	val = readl(&usbctlr->utmip_pll_cfg1);
	clrsetbits_le32(&val, UTMIP_PLLU_ENABLE_DLY_COUNT_MASK,
		timing[PARAM_ENABLE_DELAY_COUNT] <<
			UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT);
	clrsetbits_le32(&val, UTMIP_XTAL_FREQ_COUNT_MASK,
		timing[PARAM_XTAL_FREQ_COUNT] <<
			UTMIP_XTAL_FREQ_COUNT_SHIFT);
	writel(val, &usbctlr->utmip_pll_cfg1);

	/* Setting the tracking length time */
	clrsetbits_le32(&usbctlr->utmip_bias_cfg1,
		UTMIP_BIAS_PDTRK_COUNT_MASK,
		timing[PARAM_BIAS_TIME] << UTMIP_BIAS_PDTRK_COUNT_SHIFT);

	/* Program debounce time for VBUS to become valid */
	clrsetbits_le32(&usbctlr->utmip_debounce_cfg0,
		UTMIP_DEBOUNCE_CFG0_MASK,
		timing[PARAM_DEBOUNCE_A_TIME] << UTMIP_DEBOUNCE_CFG0_SHIFT);

	setbits_le32(&usbctlr->utmip_tx_cfg0, UTMIP_FS_PREAMBLE_J);

	/* Disable battery charge enabling bit */
	setbits_le32(&usbctlr->utmip_bat_chrg_cfg0, UTMIP_PD_CHRG);

	clrbits_le32(&usbctlr->utmip_xcvr_cfg0, UTMIP_XCVR_LSBIAS_SE);
	setbits_le32(&usbctlr->utmip_spare_cfg0, FUSE_SETUP_SEL);

	/*
	 * Configure the UTMIP_IDLE_WAIT and UTMIP_ELASTIC_LIMIT
	 * Setting these fields, together with default values of the
	 * other fields, results in programming the registers below as
	 * follows:
	 *         UTMIP_HSRX_CFG0 = 0x9168c000
	 *         UTMIP_HSRX_CFG1 = 0x13
	 */

	/* Set PLL enable delay count and Crystal frequency count */
	val = readl(&usbctlr->utmip_hsrx_cfg0);
	clrsetbits_le32(&val, UTMIP_IDLE_WAIT_MASK,
		utmip_idle_wait_delay << UTMIP_IDLE_WAIT_SHIFT);
	clrsetbits_le32(&val, UTMIP_ELASTIC_LIMIT_MASK,
		utmip_elastic_limit << UTMIP_ELASTIC_LIMIT_SHIFT);
	writel(val, &usbctlr->utmip_hsrx_cfg0);

	/* Configure the UTMIP_HS_SYNC_START_DLY */
	clrsetbits_le32(&usbctlr->utmip_hsrx_cfg1,
		UTMIP_HS_SYNC_START_DLY_MASK,
		utmip_hs_sync_start_delay << UTMIP_HS_SYNC_START_DLY_SHIFT);

	/* Preceed the crystal clock disable by >100ns delay. */
	udelay(1);

	/* Resuscitate crystal clock by setting UTMIP_PHY_XTAL_CLOCKEN */
	setbits_le32(&usbctlr->utmip_misc_cfg1, UTMIP_PHY_XTAL_CLOCKEN);

	/* Finished the per-controller init. */

	/* De-assert UTMIP_RESET to bring out of reset. */
	clrbits_le32(&usbctlr->susp_ctrl, UTMIP_RESET);

	/* Wait for the phy clock to become valid in 100 ms */
	for (loop_count = 100000; loop_count != 0; loop_count--) {
		if (readl(&usbctlr->susp_ctrl) & USB_PHY_CLK_VALID)
			break;
		udelay(1);
	}
	if (!loop_count)
		return -1;

	/* Disable ICUSB FS/LS transceiver */
	clrbits_le32(&usbctlr->icusb_ctrl, IC_ENB1);

	/* Select UTMI parallel interface */
	clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK,
			PTS_UTMI << PTS_SHIFT);
	clrbits_le32(&usbctlr->port_sc1, STS);

	/* Deassert power down state */
	clrbits_le32(&usbctlr->utmip_xcvr_cfg0, UTMIP_FORCE_PD_POWERDOWN |
		UTMIP_FORCE_PD2_POWERDOWN | UTMIP_FORCE_PDZI_POWERDOWN);
	clrbits_le32(&usbctlr->utmip_xcvr_cfg1, UTMIP_FORCE_PDDISC_POWERDOWN |
		UTMIP_FORCE_PDCHRP_POWERDOWN | UTMIP_FORCE_PDDR_POWERDOWN);

	return 0;
}
示例#15
0
文件: tegra.c 项目: JamesAng/ub
/**
 * Handle the next stage of device init
 */
static int handle_stage(const void *blob)
{
	debug("%s: stage %d\n", __func__, stage);

	/* do the things for this stage */
	switch (stage) {
	case STAGE_START:
		/* Initialize the Tegra display controller */
		if (tegra_display_probe(gd->fdt_blob, (void *)gd->fb_base)) {
			printf("%s: Failed to probe display driver\n",
			__func__);
			return -1;
		}

		/* get panel details */
		if (fdt_decode_lcd(blob, &config)) {
			printf("No valid LCD information in device tree\n");
			return -1;
		}

		/*
		 * It is possible that the FDT has requested that the LCD be
		 * disabled. We currently don't support this. It would require
		 * changes to U-Boot LCD subsystem to have LCD support
		 * compiled in but not used. An easier option might be to
		 * still have a frame buffer, but leave the backlight off and
		 * remove all mention of lcd in the stdout environment
		 * variable.
		 */

		funcmux_select(PERIPH_ID_DISP1, FUNCMUX_DEFAULT);

		fdtdec_setup_gpio(&config.panel_vdd);
		fdtdec_setup_gpio(&config.lvds_shutdown);
		fdtdec_setup_gpio(&config.backlight_vdd);
		fdtdec_setup_gpio(&config.backlight_en);

		/*
		 * TODO: If fdt includes output flag we can omit this code
		 * since fdtdec_setup_gpio will do it for us.
		 */
		if (fdt_gpio_isvalid(&config.panel_vdd))
			gpio_direction_output(config.panel_vdd.gpio, 0);
		if (fdt_gpio_isvalid(&config.lvds_shutdown))
			gpio_direction_output(config.lvds_shutdown.gpio, 0);
		if (fdt_gpio_isvalid(&config.backlight_vdd))
			gpio_direction_output(config.backlight_vdd.gpio, 0);
		if (fdt_gpio_isvalid(&config.backlight_en))
			gpio_direction_output(config.backlight_en.gpio, 0);
		break;
	case STAGE_PANEL_VDD:
		if (fdt_gpio_isvalid(&config.panel_vdd))
			gpio_direction_output(config.panel_vdd.gpio, 1);
		break;
	case STAGE_LVDS:
		if (fdt_gpio_isvalid(&config.lvds_shutdown))
			gpio_set_value(config.lvds_shutdown.gpio, 1);
		break;
	case STAGE_BACKLIGHT_VDD:
		if (fdt_gpio_isvalid(&config.backlight_vdd))
			gpio_set_value(config.backlight_vdd.gpio, 1);
		break;
	case STAGE_PWM:
		/* Enable PWM at 15/16 high, 32768 Hz with divider 1 */
		pinmux_set_func(PINGRP_GPU, PMUX_FUNC_PWM);
		pinmux_tristate_disable(PINGRP_GPU);

		pwm_enable(config.pwm_channel, 32768, 0xdf, 1);
		break;
	case STAGE_BACKLIGHT_EN:
		if (fdt_gpio_isvalid(&config.backlight_en))
			gpio_set_value(config.backlight_en.gpio, 1);
		break;
	case STAGE_DONE:
		break;
	}

	/* set up timer for next stage */
	timer_next = timer_get_us();
	if (stage < FDT_LCD_TIMINGS)
		timer_next += config.panel_timings[stage] * 1000;

	/* move to next stage */
	stage++;
	return 0;
}
示例#16
0
int cros_ec_init(const void *blob, struct cros_ec_dev **cros_ecp)
{
	char id[MSG_BYTES];
	struct cros_ec_dev *dev;
	int node = 0;

	*cros_ecp = NULL;
	do {
		node = fdtdec_next_compatible(blob, node,
					      COMPAT_GOOGLE_CROS_EC);
		if (node < 0) {
			debug("%s: Node not found\n", __func__);
			return 0;
		}
	} while (!fdtdec_get_is_enabled(blob, node));

	if (cros_ec_decode_fdt(blob, node, &dev)) {
		debug("%s: Failed to decode device.\n", __func__);
		return -CROS_EC_ERR_FDT_DECODE;
	}

	switch (dev->interface) {
#ifdef CONFIG_CROS_EC_SPI
	case CROS_EC_IF_SPI:
		if (cros_ec_spi_init(dev, blob)) {
			debug("%s: Could not setup SPI interface\n", __func__);
			return -CROS_EC_ERR_DEV_INIT;
		}
		break;
#endif
#ifdef CONFIG_CROS_EC_I2C
	case CROS_EC_IF_I2C:
		if (cros_ec_i2c_init(dev, blob))
			return -CROS_EC_ERR_DEV_INIT;
		break;
#endif
#ifdef CONFIG_CROS_EC_LPC
	case CROS_EC_IF_LPC:
		if (cros_ec_lpc_init(dev, blob))
			return -CROS_EC_ERR_DEV_INIT;
		break;
#endif
#ifdef CONFIG_CROS_EC_SANDBOX
	case CROS_EC_IF_SANDBOX:
		if (cros_ec_sandbox_init(dev, blob))
			return -CROS_EC_ERR_DEV_INIT;
		break;
#endif
	case CROS_EC_IF_NONE:
	default:
		return 0;
	}

	/* we will poll the EC interrupt line */
	fdtdec_setup_gpio(&dev->ec_int);
	if (fdt_gpio_isvalid(&dev->ec_int))
		gpio_direction_input(dev->ec_int.gpio);

	if (cros_ec_check_version(dev)) {
		debug("%s: Could not detect CROS-EC version\n", __func__);
		return -CROS_EC_ERR_CHECK_VERSION;
	}

	if (cros_ec_read_id(dev, id, sizeof(id))) {
		debug("%s: Could not read KBC ID\n", __func__);
		return -CROS_EC_ERR_READ_ID;
	}

	/* Remember this device for use by the cros_ec command */
	last_dev = *cros_ecp = dev;
	debug("Google Chrome EC CROS-EC driver ready, id '%s'\n", id);

	return 0;
}
示例#17
0
/* set up the UTMI USB controller with the parameters provided */
static int init_utmi_usb_controller(struct fdt_usb *config)
{
	u32 val;
	int loop_count;
	const unsigned *timing;
	struct usb_ctlr *usbctlr = config->reg;
	struct clk_rst_ctlr *clkrst;
	struct usb_ctlr *usb1ctlr;

	clock_enable(config->periph_id);

	/* Reset the usb controller */
	usbf_reset_controller(config, usbctlr);

	/* Stop crystal clock by setting UTMIP_PHY_XTAL_CLOCKEN low */
	clrbits_le32(&usbctlr->utmip_misc_cfg1, UTMIP_PHY_XTAL_CLOCKEN);

	/* Follow the crystal clock disable by >100ns delay */
	udelay(1);

	/*
	 * To Use the A Session Valid for cable detection logic, VBUS_WAKEUP
	 * mux must be switched to actually use a_sess_vld threshold.
	 */
	if (config->dr_mode == DR_MODE_OTG &&
	    fdt_gpio_isvalid(&config->vbus_gpio))
		clrsetbits_le32(&usbctlr->usb1_legacy_ctrl,
			VBUS_SENSE_CTL_MASK,
			VBUS_SENSE_CTL_A_SESS_VLD << VBUS_SENSE_CTL_SHIFT);

	/*
	 * PLL Delay CONFIGURATION settings. The following parameters control
	 * the bring up of the plls.
	 */
	timing = get_pll_timing();

	if (!controller->has_hostpc) {
		val = readl(&usbctlr->utmip_misc_cfg1);
		clrsetbits_le32(&val, UTMIP_PLLU_STABLE_COUNT_MASK,
				timing[PARAM_STABLE_COUNT] <<
				UTMIP_PLLU_STABLE_COUNT_SHIFT);
		clrsetbits_le32(&val, UTMIP_PLL_ACTIVE_DLY_COUNT_MASK,
				timing[PARAM_ACTIVE_DELAY_COUNT] <<
				UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT);
		writel(val, &usbctlr->utmip_misc_cfg1);

		/* Set PLL enable delay count and crystal frequency count */
		val = readl(&usbctlr->utmip_pll_cfg1);
		clrsetbits_le32(&val, UTMIP_PLLU_ENABLE_DLY_COUNT_MASK,
				timing[PARAM_ENABLE_DELAY_COUNT] <<
				UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT);
		clrsetbits_le32(&val, UTMIP_XTAL_FREQ_COUNT_MASK,
				timing[PARAM_XTAL_FREQ_COUNT] <<
				UTMIP_XTAL_FREQ_COUNT_SHIFT);
		writel(val, &usbctlr->utmip_pll_cfg1);
	} else {
		clkrst = (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE;

		val = readl(&clkrst->crc_utmip_pll_cfg2);
		clrsetbits_le32(&val, UTMIP_PLLU_STABLE_COUNT_MASK,
				timing[PARAM_STABLE_COUNT] <<
				UTMIP_PLLU_STABLE_COUNT_SHIFT);
		clrsetbits_le32(&val, UTMIP_PLL_ACTIVE_DLY_COUNT_MASK,
				timing[PARAM_ACTIVE_DELAY_COUNT] <<
				UTMIP_PLL_ACTIVE_DLY_COUNT_SHIFT);
		writel(val, &clkrst->crc_utmip_pll_cfg2);

		/* Set PLL enable delay count and crystal frequency count */
		val = readl(&clkrst->crc_utmip_pll_cfg1);
		clrsetbits_le32(&val, UTMIP_PLLU_ENABLE_DLY_COUNT_MASK,
				timing[PARAM_ENABLE_DELAY_COUNT] <<
				UTMIP_PLLU_ENABLE_DLY_COUNT_SHIFT);
		clrsetbits_le32(&val, UTMIP_XTAL_FREQ_COUNT_MASK,
				timing[PARAM_XTAL_FREQ_COUNT] <<
				UTMIP_XTAL_FREQ_COUNT_SHIFT);
		writel(val, &clkrst->crc_utmip_pll_cfg1);

		/* Disable Power Down state for PLL */
		clrbits_le32(&clkrst->crc_utmip_pll_cfg1,
			     PLLU_POWERDOWN | PLL_ENABLE_POWERDOWN |
			     PLL_ACTIVE_POWERDOWN);

		/* Recommended PHY settings for EYE diagram */
		val = readl(&usbctlr->utmip_xcvr_cfg0);
		clrsetbits_le32(&val, UTMIP_XCVR_SETUP_MASK,
				0x4 << UTMIP_XCVR_SETUP_SHIFT);
		clrsetbits_le32(&val, UTMIP_XCVR_SETUP_MSB_MASK,
				0x3 << UTMIP_XCVR_SETUP_MSB_SHIFT);
		clrsetbits_le32(&val, UTMIP_XCVR_HSSLEW_MSB_MASK,
				0x8 << UTMIP_XCVR_HSSLEW_MSB_SHIFT);
		writel(val, &usbctlr->utmip_xcvr_cfg0);
		clrsetbits_le32(&usbctlr->utmip_xcvr_cfg1,
				UTMIP_XCVR_TERM_RANGE_ADJ_MASK,
				0x7 << UTMIP_XCVR_TERM_RANGE_ADJ_SHIFT);

		/* Some registers can be controlled from USB1 only. */
		if (config->periph_id != PERIPH_ID_USBD) {
			clock_enable(PERIPH_ID_USBD);
			/* Disable Reset if in Reset state */
			reset_set_enable(PERIPH_ID_USBD, 0);
		}
		usb1ctlr = (struct usb_ctlr *)
			((u32)config->reg & USB1_ADDR_MASK);
		val = readl(&usb1ctlr->utmip_bias_cfg0);
		setbits_le32(&val, UTMIP_HSDISCON_LEVEL_MSB);
		clrsetbits_le32(&val, UTMIP_HSDISCON_LEVEL_MASK,
				0x1 << UTMIP_HSDISCON_LEVEL_SHIFT);
		clrsetbits_le32(&val, UTMIP_HSSQUELCH_LEVEL_MASK,
				0x2 << UTMIP_HSSQUELCH_LEVEL_SHIFT);
		writel(val, &usb1ctlr->utmip_bias_cfg0);

		/* Miscellaneous setting mentioned in Programming Guide */
		clrbits_le32(&usbctlr->utmip_misc_cfg0,
			     UTMIP_SUSPEND_EXIT_ON_EDGE);
	}

	/* Setting the tracking length time */
	clrsetbits_le32(&usbctlr->utmip_bias_cfg1,
		UTMIP_BIAS_PDTRK_COUNT_MASK,
		timing[PARAM_BIAS_TIME] << UTMIP_BIAS_PDTRK_COUNT_SHIFT);

	/* Program debounce time for VBUS to become valid */
	clrsetbits_le32(&usbctlr->utmip_debounce_cfg0,
		UTMIP_DEBOUNCE_CFG0_MASK,
		timing[PARAM_DEBOUNCE_A_TIME] << UTMIP_DEBOUNCE_CFG0_SHIFT);

	setbits_le32(&usbctlr->utmip_tx_cfg0, UTMIP_FS_PREAMBLE_J);

	/* Disable battery charge enabling bit */
	setbits_le32(&usbctlr->utmip_bat_chrg_cfg0, UTMIP_PD_CHRG);

	clrbits_le32(&usbctlr->utmip_xcvr_cfg0, UTMIP_XCVR_LSBIAS_SE);
	setbits_le32(&usbctlr->utmip_spare_cfg0, FUSE_SETUP_SEL);

	/*
	 * Configure the UTMIP_IDLE_WAIT and UTMIP_ELASTIC_LIMIT
	 * Setting these fields, together with default values of the
	 * other fields, results in programming the registers below as
	 * follows:
	 *         UTMIP_HSRX_CFG0 = 0x9168c000
	 *         UTMIP_HSRX_CFG1 = 0x13
	 */

	/* Set PLL enable delay count and Crystal frequency count */
	val = readl(&usbctlr->utmip_hsrx_cfg0);
	clrsetbits_le32(&val, UTMIP_IDLE_WAIT_MASK,
		utmip_idle_wait_delay << UTMIP_IDLE_WAIT_SHIFT);
	clrsetbits_le32(&val, UTMIP_ELASTIC_LIMIT_MASK,
		utmip_elastic_limit << UTMIP_ELASTIC_LIMIT_SHIFT);
	writel(val, &usbctlr->utmip_hsrx_cfg0);

	/* Configure the UTMIP_HS_SYNC_START_DLY */
	clrsetbits_le32(&usbctlr->utmip_hsrx_cfg1,
		UTMIP_HS_SYNC_START_DLY_MASK,
		utmip_hs_sync_start_delay << UTMIP_HS_SYNC_START_DLY_SHIFT);

	/* Preceed the crystal clock disable by >100ns delay. */
	udelay(1);

	/* Resuscitate crystal clock by setting UTMIP_PHY_XTAL_CLOCKEN */
	setbits_le32(&usbctlr->utmip_misc_cfg1, UTMIP_PHY_XTAL_CLOCKEN);

	if (controller->has_hostpc) {
		if (config->periph_id == PERIPH_ID_USBD)
			clrbits_le32(&clkrst->crc_utmip_pll_cfg2,
				     UTMIP_FORCE_PD_SAMP_A_POWERDOWN);
		if (config->periph_id == PERIPH_ID_USB3)
			clrbits_le32(&clkrst->crc_utmip_pll_cfg2,
				     UTMIP_FORCE_PD_SAMP_C_POWERDOWN);
	}
	/* Finished the per-controller init. */

	/* De-assert UTMIP_RESET to bring out of reset. */
	clrbits_le32(&usbctlr->susp_ctrl, UTMIP_RESET);

	/* Wait for the phy clock to become valid in 100 ms */
	for (loop_count = 100000; loop_count != 0; loop_count--) {
		if (readl(&usbctlr->susp_ctrl) & USB_PHY_CLK_VALID)
			break;
		udelay(1);
	}
	if (!loop_count)
		return -1;

	/* Disable ICUSB FS/LS transceiver */
	clrbits_le32(&usbctlr->icusb_ctrl, IC_ENB1);

	/* Select UTMI parallel interface */
	clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK,
			PTS_UTMI << PTS_SHIFT);
	clrbits_le32(&usbctlr->port_sc1, STS);

	/* Deassert power down state */
	clrbits_le32(&usbctlr->utmip_xcvr_cfg0, UTMIP_FORCE_PD_POWERDOWN |
		UTMIP_FORCE_PD2_POWERDOWN | UTMIP_FORCE_PDZI_POWERDOWN);
	clrbits_le32(&usbctlr->utmip_xcvr_cfg1, UTMIP_FORCE_PDDISC_POWERDOWN |
		UTMIP_FORCE_PDCHRP_POWERDOWN | UTMIP_FORCE_PDDR_POWERDOWN);

	if (controller->has_hostpc) {
		/*
		 * BIAS Pad Power Down is common among all 3 USB
		 * controllers and can be controlled from USB1 only.
		 */
		usb1ctlr = (struct usb_ctlr *)
			((u32)config->reg & USB1_ADDR_MASK);
		clrbits_le32(&usb1ctlr->utmip_bias_cfg0, UTMIP_BIASPD);
		udelay(25);
		clrbits_le32(&usb1ctlr->utmip_bias_cfg1,
			     UTMIP_FORCE_PDTRK_POWERDOWN);
	}
	return 0;
}