Exemple #1
0
static void board_configure_analogix(void)
{
	int node, ret;
	struct fdt_gpio_state reset_gpio;
	struct fdt_gpio_state powerdown_gpio;

	node = fdtdec_next_compatible(gd->fdt_blob, 0,
		COMPAT_ANALOGIX_ANX7805);
	if (node <= 0)
		return;

	/* Configure Analogix 780x bridge in USB pass-through mode */
	ret = fdtdec_decode_gpio(gd->fdt_blob, node, "reset-gpio",
				&reset_gpio);
	if (ret < 0) {
		debug("%s: Could not find reset-gpio", __func__);
		return;
	}

	ret = fdtdec_decode_gpio(gd->fdt_blob, node, "powerdown-gpio",
				&powerdown_gpio);
	if (ret < 0) {
		debug("%s: Could not find powerdown-gpio", __func__);
		return;
	}

	fdtdec_setup_gpio(&powerdown_gpio);
	fdtdec_setup_gpio(&reset_gpio);
	gpio_direction_output(powerdown_gpio.gpio, 1);
	gpio_direction_output(reset_gpio.gpio, 1);
}
Exemple #2
0
static int board_i2c_arb_init(const void *blob)
{
	int node;

	local.arbitrate_node = -1;
	node = fdtdec_next_compatible(blob, 0, COMPAT_GOOGLE_ARBITRATOR);
	if (node < 0) {
		debug("Cannot find bus arbitrator node\n");
		return 0;
	}

	if (fdtdec_decode_gpio(blob, node, "google,ap-claim-gpios",
				&local.ap_claim) ||
			fdtdec_decode_gpio(blob, node, "google,ec-claim-gpios",
				&local.ec_claim)) {
		debug("Cannot find bus arbitrator GPIOs\n");
		return 0;
	}

	if (fdtdec_setup_gpio(&local.ap_claim) ||
			fdtdec_setup_gpio(&local.ec_claim)) {
		debug("Cannot claim arbitration GPIOs\n");
		return -1;
	}

	/* We are currently not claiming the bus */
	gpio_direction_output(local.ap_claim.gpio, 1);
	gpio_direction_input(local.ec_claim.gpio);
	gpio_set_pull(local.ec_claim.gpio, EXYNOS_GPIO_PULL_UP);

	local.arbitrate_node = fdtdec_lookup_phandle(blob, node,
						     "google,arbitrate-bus");
	if (local.arbitrate_node < 0) {
		debug("Cannot find bus to arbitrate\n");
		return -1;
	}

	local.slew_delay_us = fdtdec_get_int(blob, node,
					     "google,slew-delay-us", 10);
	local.wait_retry_ms = fdtdec_get_int(blob, node,
					     "google,wait-retry-us", 2000);
	local.wait_retry_ms = DIV_ROUND_UP(local.wait_retry_ms, 1000);
	local.wait_free_ms = fdtdec_get_int(blob, node,
					    "google,wait-free-us", 50000);
	local.wait_free_ms = DIV_ROUND_UP(local.wait_free_ms, 1000);
	debug("Bus arbitration ready on fdt node %d\n", local.arbitrate_node);

	return 0;
}
Exemple #3
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;
}
Exemple #4
0
/*
 * This functions disable the USB3.0 PLL to save power
 */
static void disable_usb30_pll(void)
{
	int node, ret;
	struct fdt_gpio_state en_gpio;

	node = fdtdec_next_compatible(gd->fdt_blob, 0,
		COMPAT_SAMSUNG_EXYNOS_USB);
	if (node < 0)
		return;

	ret = fdtdec_decode_gpio(gd->fdt_blob, node, "usb3-pll-gpio", &en_gpio);
	if (ret)
		return;

	fdtdec_setup_gpio(&en_gpio);
	gpio_direction_output(en_gpio.gpio, en_gpio.flags);
}
Exemple #5
0
/* 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);
		}
	}
}
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;
}
/*
 * 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;
}
Exemple #8
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");
	}
}
Exemple #9
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;
}
Exemple #10
0
/**
 * 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;
}
Exemple #11
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;
}