static int atmel_hlcdc_ofdata_to_platdata(struct udevice *dev)
{
	struct atmel_hlcdc_priv *priv = dev_get_priv(dev);
	const void *blob = gd->fdt_blob;
	int node = dev_of_offset(dev);

	priv->regs = (struct atmel_hlcd_regs *)devfdt_get_addr(dev);
	if (!priv->regs) {
		debug("%s: No display controller address\n", __func__);
		return -EINVAL;
	}

	if (fdtdec_decode_display_timing(blob, dev_of_offset(dev),
					 0, &priv->timing)) {
		debug("%s: Failed to decode display timing\n", __func__);
		return -EINVAL;
	}

	if (priv->timing.hactive.typ > LCD_MAX_WIDTH)
		priv->timing.hactive.typ = LCD_MAX_WIDTH;

	if (priv->timing.vactive.typ > LCD_MAX_HEIGHT)
		priv->timing.vactive.typ = LCD_MAX_HEIGHT;

	priv->vl_bpix = fdtdec_get_int(blob, node, "atmel,vl-bpix", 0);
	if (!priv->vl_bpix) {
		debug("%s: Failed to get bits per pixel\n", __func__);
		return -EINVAL;
	}

	priv->output_mode = fdtdec_get_int(blob, node, "atmel,output-mode", 24);
	priv->guard_time = fdtdec_get_int(blob, node, "atmel,guard-time", 1);

	return 0;
}
int rk_lvds_read_timing(struct udevice *dev, struct display_timing *timing)
{
	if (fdtdec_decode_display_timing
	    (gd->fdt_blob, dev->of_offset, 0, timing)) {
		debug("%s: Failed to decode display timing\n", __func__);
		return -EINVAL;
	}

	return 0;
}
Beispiel #3
0
int display_init(void *lcdbase, int fb_bits_per_pixel,
		 struct display_timing *timing)
{
	struct dc_ctlr *dc_ctlr;
	const void *blob = gd->fdt_blob;
	struct udevice *dp_dev;
	const int href_to_sync = 1, vref_to_sync = 1;
	int panel_bpp = 18;	/* default 18 bits per pixel */
	u32 plld_rate;
	struct gpio_desc vdd_gpio, enable_gpio;
	int pwm;
	int node;
	int ret;

	ret = uclass_get_device(UCLASS_DISPLAY, 0, &dp_dev);
	if (ret)
		return ret;

	node = fdtdec_next_compatible(blob, 0, COMPAT_NVIDIA_TEGRA124_DC);
	if (node < 0)
		return -ENOENT;
	dc_ctlr = (struct dc_ctlr *)fdtdec_get_addr(blob, node, "reg");
	if (fdtdec_decode_display_timing(blob, node, 0, timing))
		return -EINVAL;

	ret = display_update_config_from_edid(dp_dev, &panel_bpp, timing);
	if (ret) {
		debug("%s: Failed to decode EDID, using defaults\n", __func__);
		dump_config(panel_bpp, timing);
	}

	if (!get_backlight_info(blob, &vdd_gpio, &enable_gpio, &pwm)) {
		dm_gpio_set_value(&vdd_gpio, 1);
		debug("%s: backlight vdd setting gpio %08x to %d\n",
		      __func__, gpio_get_number(&vdd_gpio), 1);
	}

	/*
	 * The plld is programmed with the assumption of the SHIFT_CLK_DIVIDER
	 * and PIXEL_CLK_DIVIDER are zero (divide by 1). See the
	 * update_display_mode() for detail.
	 */
	plld_rate = clock_set_display_rate(timing->pixelclock.typ * 2);
	if (plld_rate == 0) {
		printf("dc: clock init failed\n");
		return -EIO;
	} else if (plld_rate != timing->pixelclock.typ * 2) {
		debug("dc: plld rounded to %u\n", plld_rate);
		timing->pixelclock.typ = plld_rate / 2;
	}

	/* Init dc */
	ret = tegra_dc_init(dc_ctlr);
	if (ret) {
		debug("dc: init failed\n");
		return ret;
	}

	/* Configure dc mode */
	ret = update_display_mode(dc_ctlr, timing, href_to_sync, vref_to_sync);
	if (ret) {
		debug("dc: failed to configure display mode\n");
		return ret;
	}

	/* Enable dp */
	ret = display_enable(dp_dev, panel_bpp, timing);
	if (ret)
		return ret;

	ret = update_window(dc_ctlr, (ulong)lcdbase, fb_bits_per_pixel, timing);
	if (ret)
		return ret;

	/* Set up Tegra PWM to drive the panel backlight */
	pwm_enable(pwm, 0, 220, 0x2e);
	udelay(10 * 1000);

	if (dm_gpio_is_valid(&enable_gpio)) {
		dm_gpio_set_value(&enable_gpio, 1);
		debug("%s: backlight enable setting gpio %08x to %d\n",
		      __func__, gpio_get_number(&enable_gpio), 1);
	}

	return 0;
}
Beispiel #4
0
static int display_init(struct udevice *dev, void *lcdbase,
			int fb_bits_per_pixel, struct display_timing *timing)
{
	struct display_plat *disp_uc_plat;
	struct dc_ctlr *dc_ctlr;
	const void *blob = gd->fdt_blob;
	struct udevice *dp_dev;
	const int href_to_sync = 1, vref_to_sync = 1;
	int panel_bpp = 18;	/* default 18 bits per pixel */
	u32 plld_rate;
	int ret;

	/*
	 * Before we probe the display device (eDP), tell it that this device
	 * is are the source of the display data.
	 */
	ret = uclass_find_first_device(UCLASS_DISPLAY, &dp_dev);
	if (ret) {
		debug("%s: device '%s' display not found (ret=%d)\n", __func__,
		      dev->name, ret);
		return ret;
	}

	disp_uc_plat = dev_get_uclass_platdata(dp_dev);
	debug("Found device '%s', disp_uc_priv=%p\n", dp_dev->name,
	      disp_uc_plat);
	disp_uc_plat->src_dev = dev;

	ret = uclass_get_device(UCLASS_DISPLAY, 0, &dp_dev);
	if (ret) {
		debug("%s: Failed to probe eDP, ret=%d\n", __func__, ret);
		return ret;
	}

	dc_ctlr = (struct dc_ctlr *)fdtdec_get_addr(blob, dev->of_offset,
						    "reg");
	if (fdtdec_decode_display_timing(blob, dev->of_offset, 0, timing)) {
		debug("%s: Failed to decode display timing\n", __func__);
		return -EINVAL;
	}

	ret = display_update_config_from_edid(dp_dev, &panel_bpp, timing);
	if (ret) {
		debug("%s: Failed to decode EDID, using defaults\n", __func__);
		dump_config(panel_bpp, timing);
	}

	/*
	 * The plld is programmed with the assumption of the SHIFT_CLK_DIVIDER
	 * and PIXEL_CLK_DIVIDER are zero (divide by 1). See the
	 * update_display_mode() for detail.
	 */
	plld_rate = clock_set_display_rate(timing->pixelclock.typ * 2);
	if (plld_rate == 0) {
		printf("dc: clock init failed\n");
		return -EIO;
	} else if (plld_rate != timing->pixelclock.typ * 2) {
		debug("dc: plld rounded to %u\n", plld_rate);
		timing->pixelclock.typ = plld_rate / 2;
	}

	/* Init dc */
	ret = tegra_dc_init(dc_ctlr);
	if (ret) {
		debug("dc: init failed\n");
		return ret;
	}

	/* Configure dc mode */
	ret = update_display_mode(dc_ctlr, timing, href_to_sync, vref_to_sync);
	if (ret) {
		debug("dc: failed to configure display mode\n");
		return ret;
	}

	/* Enable dp */
	ret = display_enable(dp_dev, panel_bpp, timing);
	if (ret) {
		debug("dc: failed to enable display: ret=%d\n", ret);
		return ret;
	}

	ret = update_window(dc_ctlr, (ulong)lcdbase, fb_bits_per_pixel, timing);
	if (ret) {
		debug("dc: failed to update window\n");
		return ret;
	}

	return 0;
}