Ejemplo n.º 1
0
static void bochs_init_linear_fb(struct device *dev)
{
	struct edid edid;
	int id, mem, bar;
	u32 addr;

	/* bochs dispi detection */
	id = bochs_read(VBE_DISPI_INDEX_ID);
	if ((id & 0xfff0) != VBE_DISPI_ID0) {
		printk(BIOS_DEBUG, "QEMU VGA: bochs dispi: ID mismatch.\n");
		return;
	}
	mem = bochs_read(VBE_DISPI_INDEX_VIDEO_MEMORY_64K) * 64 * 1024;

	/* find lfb pci bar */
	addr = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
	if ((addr & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY) {
		/* qemu -vga {std,qxl} */
		bar = 0;
	} else {
		/* qemu -vga vmware */
		addr = pci_read_config32(dev, PCI_BASE_ADDRESS_1);
		bar = 1;
	}
	addr &= ~PCI_BASE_ADDRESS_MEM_ATTR_MASK;

	if (!addr)
		return;

	printk(BIOS_DEBUG, "QEMU VGA: bochs dispi interface found, "
	       "%d MiB video memory\n", mem / (1024 * 1024));
	printk(BIOS_DEBUG, "QEMU VGA: framebuffer @ %x (pci bar %d)\n",
	       addr, bar);

	/* setup video mode */
	bochs_write(VBE_DISPI_INDEX_ENABLE,	 0);
	bochs_write(VBE_DISPI_INDEX_BANK,	 0);
	bochs_write(VBE_DISPI_INDEX_BPP,	 32);
	bochs_write(VBE_DISPI_INDEX_XRES,	 width);
	bochs_write(VBE_DISPI_INDEX_YRES,	 height);
	bochs_write(VBE_DISPI_INDEX_VIRT_WIDTH,	 width);
	bochs_write(VBE_DISPI_INDEX_VIRT_HEIGHT, height);
	bochs_write(VBE_DISPI_INDEX_X_OFFSET,	 0);
	bochs_write(VBE_DISPI_INDEX_Y_OFFSET,	 0);
	bochs_write(VBE_DISPI_INDEX_ENABLE,
		    VBE_DISPI_ENABLED | VBE_DISPI_LFB_ENABLED);

	outb(0x20, 0x3c0); /* disable blanking */

	/* setup coreboot framebuffer */
	edid.mode.ha = width;
	edid.mode.va = height;
	edid.panel_bits_per_color = 8;
	edid.panel_bits_per_pixel = 24;
	edid_set_framebuffer_bits_per_pixel(&edid, 32, 0);
	set_vbe_mode_info_valid(&edid, addr);
}
Ejemplo n.º 2
0
/* this happens after cpu_init where exynos resources are set */
static void mainboard_init(device_t dev)
{
	/* we'll stick with the crummy u-boot struct for now.*/
	/* doing this as an auto since the struct has to be writeable */
	struct edp_device_info device_info;

	void *fb_addr = (void *)(get_fb_base_kb() * KiB);

	gpio_init();
	tmu_init(&exynos5420_tmu_info);

	/* Clock Gating all the unused IP's to save power */
	clock_gate();

	/* Disable USB3.0 PLL to save 250mW of power */
	disable_usb30_pll();

	set_vbe_mode_info_valid(&edid, (uintptr_t)fb_addr);

	/*
	 * The reset value for FIMD SYSMMU register MMU_CTRL:0x14640000
	 * should be 0 according to the datasheet, but has experimentally
	 * been found to come up as 3. This means FIMD SYSMMU is on by
	 * default on Exynos5420. For now we are disabling FIMD SYSMMU.
	 */
	writel(0x0, (void *)0x14640000);
	writel(0x0, (void *)0x14680000);

	lcd_vdd();

	/* Start the fimd running before you do the phy and lcd setup.
	 * why do fimd before training etc?
	 * because we need a data stream from
	 * the fimd or the clock recovery step fails.
	 */
	vidinfo.screen_base = fb_addr;
	exynos_fimd_lcd_init(&vidinfo);

	parade_dp_bridge_setup();

	/* this might get more dynamic in future ... */
	memset(&device_info, 0, sizeof(device_info));
	device_info.disp_info.name = (char *)"Pit display";
	device_info.disp_info.h_total = 1366;
	device_info.disp_info.v_total = 768;
	device_info.video_info = dp_video_info;
	device_info.raw_edid = panel_edid;
	exynos_init_dp(&device_info);

	udelay(LCD_T3_DELAY_MS * 1000);

	backlight_vdd();
	backlight_pwm();
	backlight_en();
}
Ejemplo n.º 3
0
/*
 * Save mode to cb tables
 */
void pass_mode_info_to_payload(
			struct soc_nvidia_tegra132_config *config)
{
	struct edid edid;
	/* Align bytes_per_line to 64 bytes as required by dc */
	edid.bytes_per_line = ALIGN_UP((config->display_xres *
				config->framebuffer_bits_per_pixel / 8), 64);
	edid.x_resolution = edid.bytes_per_line /
				(config->framebuffer_bits_per_pixel / 8);
	edid.y_resolution = config->display_yres;
	edid.framebuffer_bits_per_pixel = config->framebuffer_bits_per_pixel;

	printk(BIOS_INFO, "%s: bytes_per_line: %d, bits_per_pixel: %d\n "
			"               x_res x y_res: %d x %d, size: %d\n",
			 __func__, edid.bytes_per_line,
			edid.framebuffer_bits_per_pixel,
			edid.x_resolution, edid.y_resolution,
			(edid.bytes_per_line * edid.y_resolution));

	set_vbe_mode_info_valid(&edid, 0);
}
Ejemplo n.º 4
0
void rk_display_init(device_t dev, u32 lcdbase,
		unsigned long fb_size)
{
	struct edid edid;
	struct soc_rockchip_rk3288_config *conf = dev->chip_info;
	uint32_t lower = ALIGN_DOWN(lcdbase, MiB);
	uint32_t upper = ALIGN_UP(lcdbase + fb_size, MiB);
	enum vop_modes detected_mode = VOP_MODE_UNKNOWN;

	printk(BIOS_SPEW, "LCD framebuffer @%p\n", (void *)(lcdbase));
	memset((void *)lcdbase, 0, fb_size);	/* clear the framebuffer */
	dcache_clean_invalidate_by_mva((void *)lower, upper - lower);
	mmu_config_range(lower / MiB, (upper - lower) / MiB, DCACHE_OFF);

	switch (conf->vop_mode) {
	case VOP_MODE_NONE:
		return;
	case VOP_MODE_AUTO_DETECT:
		/* try EDP first, then HDMI */
	case VOP_MODE_EDP:
		printk(BIOS_DEBUG, "Attempting to setup EDP display.\n");
		rkclk_configure_edp();
		rkclk_configure_vop_aclk(conf->vop_id, 192 * MHz);
		rk_edp_init(conf->vop_id);

		if (rk_edp_get_edid(&edid) == 0) {
			detected_mode = VOP_MODE_EDP;
			break;
		} else {
			printk(BIOS_WARNING, "Cannot get EDID from EDP.\n");
			if (conf->vop_mode == VOP_MODE_EDP)
				return;
		}
		/* fall thru */
	case VOP_MODE_HDMI:
		printk(BIOS_DEBUG, "Attempting to setup HDMI display.\n");
		rkclk_configure_hdmi();
		rkclk_configure_vop_aclk(conf->vop_id, 384 * MHz);
		rk_hdmi_init(conf->vop_id);

		if (rk_hdmi_get_edid(&edid) == 0) {
			detected_mode = VOP_MODE_HDMI;
			break;
		} else {
			printk(BIOS_WARNING, "Cannot get EDID from HDMI.\n");
			if (conf->vop_mode == VOP_MODE_HDMI)
				return;
		}
		/* fall thru */
	default:
		printk(BIOS_WARNING, "Cannot read any edid info, aborting.\n");
		return;
	}

	if (rkclk_configure_vop_dclk(conf->vop_id, edid.pixel_clock * KHz)) {
		printk(BIOS_WARNING, "config vop err\n");
		return;
	}

	edid.framebuffer_bits_per_pixel = conf->framebuffer_bits_per_pixel;
	edid.bytes_per_line = edid.ha * conf->framebuffer_bits_per_pixel / 8;
	edid.x_resolution = edid.ha;
	edid.y_resolution = edid.va;
	rkvop_mode_set(conf->vop_id, &edid, detected_mode);

	rkvop_enable(conf->vop_id, lcdbase, &edid);

	switch (detected_mode) {
	case VOP_MODE_HDMI:
		if (rk_hdmi_enable(&edid)) {
			printk(BIOS_WARNING, "hdmi enable err\n");
			return;
		}

		/*
		 * HACK: if we do remove this delay, HDMI TV may not show
		 * anythings. So we make an delay here, ensure TV have
		 * enough time to respond.
		 */
		mdelay(2000);
		break;

	case VOP_MODE_EDP:
	default:
		if (rk_edp_enable()) {
			printk(BIOS_WARNING, "edp enable err\n");
			return;
		}
		mainboard_power_on_backlight();
		break;
	}

	set_vbe_mode_info_valid(&edid, (uintptr_t)lcdbase);
}
Ejemplo n.º 5
0
/* this is really aimed at the lcd panel. That said, there are two display
 * devices on this part and we may someday want to extend it for other boards.
 */
void display_startup(device_t dev)
{
	struct soc_nvidia_tegra124_config *config = dev->chip_info;
	struct display_controller *disp_ctrl = (void *)config->display_controller;
	struct pwm_controller 	*pwm = (void *)TEGRA_PWM_BASE;
	struct tegra_dc		*dc = &dc_data;
	u32 plld_rate;

	/* init dc */
	dc->base = (void *)TEGRA_ARM_DISPLAYA;
	dc->config = config;
	config->dc_data = dc;

	/* Note dp_init may read EDID and change some config values. */
	dp_init(config);

	/* should probably just make it all MiB ... in future */
	u32 framebuffer_size_mb = config->framebuffer_size / MiB;
	u32 framebuffer_base_mb= config->framebuffer_base / MiB;

	/* light it all up */
	/* This one may have been done in romstage but that's ok for now. */
	if (config->panel_vdd_gpio){
		gpio_output(config->panel_vdd_gpio, 1);
		printk(BIOS_SPEW,"%s: panel_vdd setting gpio %08x to %d\n",
			__func__, config->panel_vdd_gpio, 1);
	}
	udelay(config->vdd_delay_ms * 1000);
	if (config->backlight_vdd_gpio){
		gpio_output(config->backlight_vdd_gpio, 1);
		printk(BIOS_SPEW,"%s: backlight vdd setting gpio %08x to %d\n",
			__func__, config->backlight_vdd_gpio, 1);
	}
	if (config->lvds_shutdown_gpio){
		gpio_output(config->lvds_shutdown_gpio, 0);
		printk(BIOS_SPEW,"%s: lvds shutdown setting gpio %08x to %d\n",
			__func__, config->lvds_shutdown_gpio, 0);
	}

	if (framebuffer_size_mb == 0){
		framebuffer_size_mb = ALIGN_UP(config->xres * config->yres *
			(config->framebuffer_bits_per_pixel / 8), MiB)/MiB;
	}

	if (! framebuffer_base_mb)
		framebuffer_base_mb = fb_base_mb();

	config->framebuffer_size = framebuffer_size_mb * MiB;
	config->framebuffer_base = framebuffer_base_mb * MiB;

	mmu_config_range(framebuffer_base_mb, framebuffer_size_mb,
		config->cache_policy);

	printk(BIOS_SPEW, "LCD frame buffer at %dMiB to %dMiB\n", framebuffer_base_mb,
		   framebuffer_base_mb + framebuffer_size_mb);

	/* GPIO magic here if needed to start powering up things. You
	 * really only want to enable vdd, wait a bit, and then enable
	 * the panel. However ... the timings in the tegra20 dts make
	 * no sense to me. I'm pretty sure they're wrong.
	 * The panel_vdd is done in the romstage, so we need only
	 * light things up here once we're sure it's all working.
	 */

	/* 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_display(config->pixel_clock * 2);
	if (plld_rate == 0) {
		printk(BIOS_ERR, "dc: clock init failed\n");
		return;
	} else if (plld_rate != config->pixel_clock * 2) {
		printk(BIOS_WARNING, "dc: plld rounded to %u\n", plld_rate);
		config->pixel_clock = plld_rate / 2;
	}

	/* Init dc */
	if (tegra_dc_init(disp_ctrl)) {
		printk(BIOS_ERR, "dc: init failed\n");
		return;
	}

	/* Configure dc mode */
	if (update_display_mode(disp_ctrl, config)) {
		printk(BIOS_ERR, "dc: failed to configure display mode.\n");
		return;
	}

	/* Enable dp */
	dp_enable(dc->out);

	/* Init frame buffer */
	memset((void *)(framebuffer_base_mb*MiB), 0x00,
			framebuffer_size_mb*MiB);

	update_window(disp_ctrl, config);

	/* Set up Tegra PWM n (where n is specified in config->pwm) to drive the
	 * panel backlight.
	 */
	printk(BIOS_SPEW, "%s: enable panel backlight pwm\n", __func__);
	WRITEL(((1 << NV_PWM_CSR_ENABLE_SHIFT) |
		(220 << NV_PWM_CSR_PULSE_WIDTH_SHIFT) | /* 220/256 */
		0x02e), /* frequency divider */
	       &pwm->pwm[config->pwm].csr);

	udelay(config->pwm_to_bl_delay_ms * 1000);
	if (config->backlight_en_gpio){
		gpio_output(config->backlight_en_gpio, 1);
		printk(BIOS_SPEW,"%s: backlight enable setting gpio %08x to %d\n",
			__func__, config->backlight_en_gpio, 1);
	}

	printk(BIOS_INFO, "%s: display init done.\n", __func__);

	/* tell depthcharge ...
	 */
	struct edid edid;
	edid.bytes_per_line = ((config->xres * config->framebuffer_bits_per_pixel / 8 + 31) /
				32 * 32);
	edid.x_resolution = edid.bytes_per_line / (config->framebuffer_bits_per_pixel / 8);
	edid.y_resolution = config->yres;
	edid.framebuffer_bits_per_pixel = config->framebuffer_bits_per_pixel;
	set_vbe_mode_info_valid(&edid, (uintptr_t)(framebuffer_base_mb*MiB));
}
Ejemplo n.º 6
0
static void intel_gma_init(const struct northbridge_intel_gm45_config *info,
			   u8 *mmio, u32 physbase, u16 piobase, u32 lfb)
{

	int i;
	u8 edid_data[128];
	struct edid edid;
	struct edid_mode *mode;
	u32 hactive, vactive, right_border, bottom_border;
	int hpolarity, vpolarity;
	u32 vsync, hsync, vblank, hblank, hfront_porch, vfront_porch;
	u32 candp1, candn;
	u32 best_delta = 0xffffffff;
	u32 target_frequency;
	u32 pixel_p1 = 1;
	u32 pixel_n = 1;
	u32 pixel_m1 = 1;
	u32 pixel_m2 = 1;
	u32 link_frequency = info->gfx.link_frequency_270_mhz ? 270000 : 162000;
	u32 data_m1;
	u32 data_n1 = 0x00800000;
	u32 link_m1;
	u32 link_n1 = 0x00080000;

	vga_gr_write(0x18, 0);

	/* Setup GTT.  */
	for (i = 0; i < 0x2000; i++)
	{
		outl((i << 2) | 1, piobase);
		outl(physbase + (i << 12) + 1, piobase + 4);
	}

	write32(mmio + ADPA, 0x40008c18);
	write32(mmio + 0x7041c, 0x0);
	write32(mmio + _DPLL_B_MD, 0x3);

	vga_misc_write(0x67);

	const u8 cr[] = { 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
		    0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
		    0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
		    0xff
	};
	vga_cr_write(0x11, 0);

	for (i = 0; i <= 0x18; i++)
		vga_cr_write(i, cr[i]);

	power_port(mmio);

	intel_gmbus_read_edid(mmio + GMBUS0, 3, 0x50, edid_data, 128);
	decode_edid(edid_data,
		    sizeof(edid_data), &edid);
	mode = &edid.mode;

	/* Disable screen memory to prevent garbage from appearing.  */
	vga_sr_write(1, vga_sr_read(1) | 0x20);

	hactive = edid.x_resolution;
	vactive = edid.y_resolution;
	right_border = mode->hborder;
	bottom_border = mode->vborder;
	hpolarity = (mode->phsync == '-');
	vpolarity = (mode->pvsync == '-');
	vsync = mode->vspw;
	hsync = mode->hspw;
	vblank = mode->vbl;
	hblank = mode->hbl;
	hfront_porch = mode->hso;
	vfront_porch = mode->vso;

	target_frequency = mode->lvds_dual_channel ? mode->pixel_clock
		: (2 * mode->pixel_clock);
	if (IS_ENABLED(CONFIG_FRAMEBUFFER_KEEP_VESA_MODE)) {
		vga_sr_write(1, 1);
		vga_sr_write(0x2, 0xf);
		vga_sr_write(0x3, 0x0);
		vga_sr_write(0x4, 0xe);
		vga_gr_write(0, 0x0);
		vga_gr_write(1, 0x0);
		vga_gr_write(2, 0x0);
		vga_gr_write(3, 0x0);
		vga_gr_write(4, 0x0);
		vga_gr_write(5, 0x0);
		vga_gr_write(6, 0x5);
		vga_gr_write(7, 0xf);
		vga_gr_write(0x10, 0x1);
		vga_gr_write(0x11, 0);

		edid.bytes_per_line = (edid.bytes_per_line + 63) & ~63;

		write32(mmio + DSPCNTR(0), DISPPLANE_BGRX888);
		write32(mmio + DSPADDR(0), 0);
		write32(mmio + DSPSTRIDE(0), edid.bytes_per_line);
		write32(mmio + DSPSURF(0), 0);
		for (i = 0; i < 0x100; i++)
			write32(mmio + LGC_PALETTE(0) + 4 * i, i * 0x010101);
	} else {
		vga_textmode_init();
	}

	/* Find suitable divisors.  */
	for (candp1 = 1; candp1 <= 8; candp1++) {
		for (candn = 5; candn <= 10; candn++) {
			u32 cur_frequency;
			u32 m; /* 77 - 131.  */
			u32 denom; /* 35 - 560.  */
			u32 current_delta;

			denom = candn * candp1 * 7;
			/* Doesnt overflow for up to
			   5000000 kHz = 5 GHz.  */
			m = (target_frequency * denom + 60000) / 120000;

			if (m < 77 || m > 131)
				continue;

			cur_frequency = (120000 * m) / denom;
			if (target_frequency > cur_frequency)
				current_delta = target_frequency - cur_frequency;
			else
				current_delta = cur_frequency - target_frequency;


			if (best_delta > current_delta) {
				best_delta = current_delta;
				pixel_n = candn;
				pixel_p1 = candp1;
				pixel_m2 = ((m + 3) % 5) + 7;
				pixel_m1 = (m - pixel_m2) / 5;
			}
		}
	}

	if (best_delta == 0xffffffff) {
		printk (BIOS_ERR, "Couldn't find GFX clock divisors\n");
		return;
	}

	link_m1 = ((uint64_t)link_n1 * mode->pixel_clock) / link_frequency;
	data_m1 = ((uint64_t)data_n1 * 18 * mode->pixel_clock)
		/ (link_frequency * 8 * 4);

	printk(BIOS_INFO, "bringing up panel at resolution %d x %d\n",
	       hactive, vactive);
	printk(BIOS_DEBUG, "Borders %d x %d\n",
	       right_border, bottom_border);
	printk(BIOS_DEBUG, "Blank %d x %d\n",
	       hblank, vblank);
	printk(BIOS_DEBUG, "Sync %d x %d\n",
	       hsync, vsync);
	printk(BIOS_DEBUG, "Front porch %d x %d\n",
	       hfront_porch, vfront_porch);
	printk(BIOS_DEBUG, (info->gfx.use_spread_spectrum_clock
			    ? "Spread spectrum clock\n" : "DREF clock\n"));
	printk(BIOS_DEBUG,
	       mode->lvds_dual_channel ? "Dual channel\n" : "Single channel\n");
	printk(BIOS_DEBUG, "Polarities %d, %d\n",
	       hpolarity, vpolarity);
	printk(BIOS_DEBUG, "Data M1=%d, N1=%d\n",
	       data_m1, data_n1);
	printk(BIOS_DEBUG, "Link frequency %d kHz\n",
	       link_frequency);
	printk(BIOS_DEBUG, "Link M1=%d, N1=%d\n",
	       link_m1, link_n1);
	printk(BIOS_DEBUG, "Pixel N=%d, M1=%d, M2=%d, P1=%d\n",
	       pixel_n, pixel_m1, pixel_m2, pixel_p1);
	printk(BIOS_DEBUG, "Pixel clock %d kHz\n",
	       120000 * (5 * pixel_m1 + pixel_m2) / pixel_n
	       / (pixel_p1 * 7));

	write32(mmio + LVDS,
		(hpolarity << 20) | (vpolarity << 21)
		| (mode->lvds_dual_channel ? LVDS_CLOCK_B_POWERUP_ALL
		   | LVDS_CLOCK_BOTH_POWERUP_ALL : 0)
		| LVDS_BORDER_ENABLE | LVDS_CLOCK_A_POWERUP_ALL);
	mdelay(1);
	write32(mmio + PP_CONTROL, PANEL_UNLOCK_REGS
		| (read32(mmio + PP_CONTROL) & ~PANEL_UNLOCK_MASK));
	write32(mmio + FP0(0),
		((pixel_n - 2) << 16)
		| ((pixel_m1 - 2) << 8) | pixel_m2);
	write32(mmio + DPLL(0),
		DPLL_VCO_ENABLE | DPLLB_MODE_LVDS
		| (mode->lvds_dual_channel ? DPLLB_LVDS_P2_CLOCK_DIV_7
		   : DPLLB_LVDS_P2_CLOCK_DIV_14)
		| (0x10000 << (pixel_p1 - 1))
		| ((info->gfx.use_spread_spectrum_clock ? 3 : 0) << 13)
		| (0x1 << (pixel_p1 - 1)));
	mdelay(1);
	write32(mmio + DPLL(0),
		DPLL_VCO_ENABLE | DPLLB_MODE_LVDS
		| (mode->lvds_dual_channel ? DPLLB_LVDS_P2_CLOCK_DIV_7
		   : DPLLB_LVDS_P2_CLOCK_DIV_14)
		| (0x10000 << (pixel_p1 - 1))
		| ((info->gfx.use_spread_spectrum_clock ? 3 : 0) << 13)
		| (0x1 << (pixel_p1 - 1)));
	/* Re-lock the registers.  */
	write32(mmio + PP_CONTROL,
		(read32(mmio + PP_CONTROL) & ~PANEL_UNLOCK_MASK));

	write32(mmio + LVDS,
		(hpolarity << 20) | (vpolarity << 21)
		| (mode->lvds_dual_channel ? LVDS_CLOCK_B_POWERUP_ALL
		   | LVDS_CLOCK_BOTH_POWERUP_ALL : 0)
		| LVDS_BORDER_ENABLE | LVDS_CLOCK_A_POWERUP_ALL);

	write32(mmio + HTOTAL(0),
		((hactive + right_border + hblank - 1) << 16)
		| (hactive - 1));
	write32(mmio + HBLANK(0),
		((hactive + right_border + hblank - 1) << 16)
		| (hactive + right_border - 1));
	write32(mmio + HSYNC(0),
		((hactive + right_border + hfront_porch + hsync - 1) << 16)
		| (hactive + right_border + hfront_porch - 1));

	write32(mmio + VTOTAL(0), ((vactive + bottom_border + vblank - 1) << 16)
		| (vactive - 1));
	write32(mmio + VBLANK(0), ((vactive + bottom_border + vblank - 1) << 16)
		| (vactive + bottom_border - 1));
	write32(mmio + VSYNC(0),
		(vactive + bottom_border + vfront_porch + vsync - 1)
		| (vactive + bottom_border + vfront_porch - 1));

	write32(mmio + PIPECONF(0), PIPECONF_DISABLE);

	write32(mmio + PF_WIN_POS(0), 0);
	if (IS_ENABLED(CONFIG_FRAMEBUFFER_KEEP_VESA_MODE)) {
		write32(mmio + PIPESRC(0), ((hactive - 1) << 16)
			| (vactive - 1));
		write32(mmio + PF_CTL(0), 0);
		write32(mmio + PF_WIN_SZ(0), 0);
		write32(mmio + PFIT_CONTROL, 0x20000000);
	} else {
		write32(mmio + PIPESRC(0), (639 << 16) | 399);
		write32(mmio + PF_CTL(0), PF_ENABLE | PF_FILTER_MED_3x3);
		write32(mmio + PF_WIN_SZ(0), vactive | (hactive << 16));
		write32(mmio + PFIT_CONTROL, 0xa0000000);
	}

	mdelay(1);

	write32(mmio + PIPE_DATA_M1(0), 0x7e000000 | data_m1);
	write32(mmio + PIPE_DATA_N1(0), data_n1);
	write32(mmio + PIPE_LINK_M1(0), link_m1);
	write32(mmio + PIPE_LINK_N1(0), link_n1);

	write32(mmio + 0x000f000c, 0x00002040);
	mdelay(1);
	write32(mmio + 0x000f000c, 0x00002050);
	write32(mmio + 0x00060100, 0x00044000);
	mdelay(1);
	write32(mmio + PIPECONF(0), PIPECONF_BPP_6);
	write32(mmio + 0x000f0008, 0x00000040);
	write32(mmio + 0x000f000c, 0x00022050);
	write32(mmio + PIPECONF(0), PIPECONF_BPP_6 | PIPECONF_DITHER_EN);
	write32(mmio + PIPECONF(0), PIPECONF_ENABLE | PIPECONF_BPP_6 | PIPECONF_DITHER_EN);

	if (IS_ENABLED(CONFIG_FRAMEBUFFER_KEEP_VESA_MODE)) {
		write32(mmio + VGACNTRL, 0x22c4008e | VGA_DISP_DISABLE);
		write32(mmio + DSPCNTR(0), DISPLAY_PLANE_ENABLE
			| DISPPLANE_BGRX888);
		mdelay(1);
	} else {
		write32(mmio + VGACNTRL, 0x22c4008e);
	}

	write32(mmio + TRANS_HTOTAL(0),
		((hactive + right_border + hblank - 1) << 16)
		| (hactive - 1));
	write32(mmio + TRANS_HBLANK(0),
		((hactive + right_border + hblank - 1) << 16)
		| (hactive + right_border - 1));
	write32(mmio + TRANS_HSYNC(0),
		((hactive + right_border + hfront_porch + hsync - 1) << 16)
		| (hactive + right_border + hfront_porch - 1));

	write32(mmio + TRANS_VTOTAL(0),
		((vactive + bottom_border + vblank - 1) << 16)
		| (vactive - 1));
	write32(mmio + TRANS_VBLANK(0),
		((vactive + bottom_border + vblank - 1) << 16)
		| (vactive + bottom_border - 1));
	write32(mmio + TRANS_VSYNC(0),
		(vactive + bottom_border + vfront_porch + vsync - 1)
		| (vactive + bottom_border + vfront_porch - 1));

	write32(mmio + 0x00060100, 0xb01c4000);
	write32(mmio + 0x000f000c, 0xb01a2050);
	mdelay(1);
	write32(mmio + TRANSCONF(0), TRANS_ENABLE | TRANS_6BPC
		);
	write32(mmio + LVDS,
		LVDS_PORT_ENABLE
		| (hpolarity << 20) | (vpolarity << 21)
		| (mode->lvds_dual_channel ? LVDS_CLOCK_B_POWERUP_ALL
		   | LVDS_CLOCK_BOTH_POWERUP_ALL : 0)
		| LVDS_BORDER_ENABLE | LVDS_CLOCK_A_POWERUP_ALL);

	write32(mmio + PP_CONTROL, PANEL_POWER_ON | PANEL_POWER_RESET);

	/* Enable screen memory.  */
	vga_sr_write(1, vga_sr_read(1) & ~0x20);

	/* Clear interrupts. */
	write32(mmio + DEIIR, 0xffffffff);
	write32(mmio + SDEIIR, 0xffffffff);

	if (IS_ENABLED(CONFIG_FRAMEBUFFER_KEEP_VESA_MODE)) {
		memset((void *) lfb, 0,
		       edid.x_resolution * edid.y_resolution * 4);
		set_vbe_mode_info_valid(&edid, lfb);
	}
}
Ejemplo n.º 7
0
/* this happens after cpu_init where exynos resources are set */
static void mainboard_init(device_t dev)
{
	int dp_tries;
	struct s5p_dp_device dp_device = {
		.base = exynos_dp1,
		.video_info = &dp_video_info,
	};
	void *fb_addr = (void *)(get_fb_base_kb() * KiB);

	prepare_usb();
	gpio_init();
	setup_storage();

	i2c_init(TPS65090_BUS, I2C_0_SPEED, I2C_SLAVE);
	i2c_init(7, I2C_0_SPEED, I2C_SLAVE);

	tmu_init(&exynos5250_tmu_info);

	/* Clock Gating all the unused IP's to save power */
	clock_gate();

	/* Disable USB3.0 PLL to save 250mW of power */
	disable_usb30_pll();

	sdmmc_vdd();

	set_vbe_mode_info_valid(&edid, (uintptr_t)fb_addr);

	lcd_vdd();

	// FIXME: should timeout
	do {
		udelay(50);
	} while (!exynos_dp_hotplug());

	exynos_dp_bridge_setup();
	for (dp_tries = 1; dp_tries <= MAX_DP_TRIES; dp_tries++) {
		exynos_dp_bridge_init();
		if (exynos_dp_hotplug()) {
			exynos_dp_reset();
			continue;
		}

		if (dp_controller_init(&dp_device))
			continue;

		udelay(LCD_T3_DELAY_MS * 1000);

		backlight_vdd();
		backlight_pwm();
		backlight_en();
		/* if we're here, we're successful */
		break;
	}

	if (dp_tries > MAX_DP_TRIES)
		printk(BIOS_ERR, "%s: Failed to set up displayport\n", __func__);

	setup_usb();

	// Uncomment to get excessive GPIO output:
	// gpio_info();
}
Ejemplo n.º 8
0
int panel_lightup(struct intel_dp *dp, unsigned int init_fb)
{
	int i;
	int edid_ok;
	int pixels = FRAME_BUFFER_BYTES/64;

	void runio(struct intel_dp *dp);

	dp->gen = 8; // This is gen 8 which we believe is Haswell
	dp->is_haswell = 1;
	dp->DP = 0x2;
	/* These values are used for training the link */
	dp->lane_count = 2;
	dp->link_bw = DP_LINK_BW_2_7;
	dp->pipe = PIPE_A;
	dp->port = PORT_A;
	dp->plane = PLANE_A;
	dp->clock = 160000;
	dp->pipe_bits_per_pixel = 32;
	dp->type = INTEL_OUTPUT_EDP;
	dp->output_reg = DP_A;
	/* observed from YABEL. */
	dp->aux_clock_divider = 0xe1;
	dp->precharge = 3;

	/* 1. Normal mode: Set the first page to zero and make
	   all GTT entries point to the same page
	   2. Developer/Recovery mode: We do not zero out all
	   the pages pointed to by GTT in order to avoid wasting time */
        if (init_fb){
		set_translation_table(0, FRAME_BUFFER_PAGES, dp->physbase, 4096);
		memset((void *)dp->graphics, 0x55, FRAME_BUFFER_PAGES*4096);
        } else {
                set_translation_table(0, FRAME_BUFFER_PAGES, dp->physbase, 0);
                memset((void*)dp->graphics, 0, 4096);
        }

	dp->address = 0x50;

	if ( !intel_dp_get_dpcd(dp) )
		goto fail;

	intel_dp_i2c_aux_ch(dp, MODE_I2C_WRITE, 0, NULL);
	for(dp->edidlen = i = 0; i < sizeof(dp->rawedid); i++){
		if (intel_dp_i2c_aux_ch(dp, MODE_I2C_READ,
					0x50, &dp->rawedid[i]) < 0)
			break;
		dp->edidlen++;
	}

	edid_ok = decode_edid(dp->rawedid, dp->edidlen, &dp->edid);
	printk(BIOS_SPEW, "decode edid returns %d\n", edid_ok);

	compute_display_params(dp);

	intel_ddi_set_pipe_settings(dp);

	runio(dp);

	palette();

	pixels = dp->edid.ha * (dp->edid.va-4) * 4;
	printk(BIOS_SPEW, "ha=%d, va=%d\n",dp->edid.ha, dp->edid.va);

	test_gfx(dp);

	set_vbe_mode_info_valid(&dp->edid, (uintptr_t)dp->graphics);
	i915_init_done = 1;
	return i915_init_done;

fail:
	printk(BIOS_SPEW, "Graphics could not be started;");
	printk(BIOS_SPEW, "Returning.\n");
	return 0;
}
Ejemplo n.º 9
0
int i915lightup(unsigned int pphysbase, unsigned int piobase,
		unsigned int pmmio, unsigned int pgfx)
{
	static struct edid edid;

	int index;
	unsigned long temp;
	mmio = (void *)pmmio;
	addrport = piobase;
	dataport = addrport + 4;
	physbase = pphysbase;
	graphics = pgfx;
	printk(BIOS_SPEW,
		"i915lightup: graphics %p mmio %p addrport %04x physbase %08x\n",
		(void *)graphics, mmio, addrport, physbase);
	globalstart = rdtscll();


	decode_edid((unsigned char *)&x60_edid_data,
		    sizeof(x60_edid_data), &edid);

	htotal = (edid.ha - 1) | ((edid.ha + edid.hbl - 1) << 16);
	printk(BIOS_SPEW, "I915_WRITE(HTOTAL(pipe), %08x)\n", htotal);

	hblank = (edid.ha  - 1) | ((edid.ha + edid.hbl - 1) << 16);
	printk(BIOS_SPEW, "I915_WRITE(HBLANK(pipe),0x%08x)\n", hblank);

	hsync = (edid.ha + edid.hso  - 1) |
		((edid.ha + edid.hso + edid.hspw - 1) << 16);
	printk(BIOS_SPEW, "I915_WRITE(HSYNC(pipe),0x%08x)\n", hsync);

	vtotal = (edid.va - 1) | ((edid.va + edid.vbl - 1) << 16);
	printk(BIOS_SPEW, "I915_WRITE(VTOTAL(pipe), %08x)\n", vtotal);

	vblank = (edid.va  - 1) | ((edid.va + edid.vbl - 1) << 16);
	printk(BIOS_SPEW, "I915_WRITE(VBLANK(pipe),0x%08x)\n", vblank);

	vsync = (edid.va + edid.vso  - 1) |
		((edid.va + edid.vso + edid.vspw - 1) << 16);
	printk(BIOS_SPEW, "I915_WRITE(VSYNC(pipe),0x%08x)\n", vsync);

	printk(BIOS_SPEW, "Table has %d elements\n", niodefs);

	index = run(0);
	printk(BIOS_SPEW, "Run returns %d\n", index);

	verbose = 0;
	/* GTT is the Global Translation Table for the graphics pipeline.
	 * It is used to translate graphics addresses to physical
	 * memory addresses. As in the CPU, GTTs map 4K pages.
	 * There are 32 bits per pixel, or 4 bytes,
	 * which means 1024 pixels per page.
	 * There are 4250 GTTs on Link:
	 * 2650 (X) * 1700 (Y) pixels / 1024 pixels per page.
	 * The setgtt function adds a further bit of flexibility:
	 * it allows you to set a range (the first two parameters) to point
	 * to a physical address (third parameter);the physical address is
	 * incremented by a count (fourth parameter) for each GTT in the
	 * range.
	 * Why do it this way? For ultrafast startup,
	 * we can point all the GTT entries to point to one page,
	 * and set that page to 0s:
	 * memset(physbase, 0, 4096);
	 * setgtt(0, 4250, physbase, 0);
	 * this takes about 2 ms, and is a win because zeroing
	 * the page takes a up to 200 ms. We will be exploiting this
	 * trick in a later rev of this code.
	 * This call sets the GTT to point to a linear range of pages
	 * starting at physbase.
	 */

	if (gtt_setup(pmmio)) {
		printk(BIOS_ERR, "ERROR: GTT Setup Failed!!!\n");
		return 0;
	}

	setgtt(0, 800 , physbase, 4096);

	temp = READ32(PGETLB_CTL);
	printk(BIOS_INFO, "GTT PGETLB_CTL register: 0x%lx\n", temp);

	if (temp & 1)
		printk(BIOS_INFO, "GTT Enabled\n");
	else
		printk(BIOS_ERR, "ERROR: GTT is still Disabled!!!\n");

	printk(BIOS_SPEW, "memset %p to 0x00 for %d bytes\n",
		(void *)graphics, FRAME_BUFFER_BYTES);
	memset((void *)graphics, 0x00, FRAME_BUFFER_BYTES);

	printk(BIOS_SPEW, "%ld microseconds\n", globalmicroseconds());

	set_vbe_mode_info_valid(&edid, graphics);

	return 1;
}
Ejemplo n.º 10
0
static void intel_gma_init(const struct northbridge_intel_x4x_config *info,
			u8 *mmio, u32 physbase, u16 piobase, u32 lfb)
{


	int i;
	u8 edid_data[128];
	struct edid edid;
	struct edid_mode *mode;
	u8 edid_is_found;

	/* Initialise mode variables for 640 x 480 @ 60Hz */
	u32 hactive = 640, vactive = 480;
	u32 right_border = 0, bottom_border = 0;
	int hpolarity = 0, vpolarity = 0;
	u32 hsync = 96, vsync = 2;
	u32 hblank = 160, vblank = 45;
	u32 hfront_porch = 16, vfront_porch = 10;
	u32 target_frequency = 25175;

	u32 err_most = 0xffffffff;
	u32 pixel_p1 = 1;
	u32 pixel_p2;
	u32 pixel_n = 1;
	u32 pixel_m1 = 1;
	u32 pixel_m2 = 1;

	vga_gr_write(0x18, 0);

	/* Set up GTT */
	for (i = 0; i < 0x1000; i++) {
		outl((i << 2) | 1, piobase);
		outl(physbase + (i << 12) + 1, piobase + 4);
	}

	write32(mmio + VGA0, 0x31108);
	write32(mmio + VGA1, 0x31406);

	write32(mmio + ADPA, ADPA_DAC_ENABLE
			| ADPA_PIPE_A_SELECT
			| ADPA_CRT_HOTPLUG_MONITOR_COLOR
			| ADPA_CRT_HOTPLUG_ENABLE
			| ADPA_USE_VGA_HVPOLARITY
			| ADPA_VSYNC_CNTL_ENABLE
			| ADPA_HSYNC_CNTL_ENABLE
			| ADPA_DPMS_ON
			);

	write32(mmio + 0x7041c, 0x0);
	write32(mmio + DPLL_MD(0), 0x3);
	write32(mmio + DPLL_MD(1), 0x3);

	vga_misc_write(0x67);

	const u8 cr[] = { 0x5f, 0x4f, 0x50, 0x82, 0x55, 0x81, 0xbf, 0x1f,
		    0x00, 0x4f, 0x0d, 0x0e, 0x00, 0x00, 0x00, 0x00,
		    0x9c, 0x8e, 0x8f, 0x28, 0x1f, 0x96, 0xb9, 0xa3,
		    0xff
	};
	vga_cr_write(0x11, 0);

	for (i = 0; i <= 0x18; i++)
		vga_cr_write(i, cr[i]);

	udelay(1);

	intel_gmbus_read_edid(mmio + GMBUS0, 2, 0x50, edid_data,
			sizeof(edid_data));
	intel_gmbus_stop(mmio + GMBUS0);
	decode_edid(edid_data,
		    sizeof(edid_data), &edid);
	mode = &edid.mode;


	/* Disable screen memory to prevent garbage from appearing.  */
	vga_sr_write(1, vga_sr_read(1) | 0x20);

	edid_is_found = edid_is_present(edid_data, sizeof(edid_data));
	if (edid_is_found) {
		printk(BIOS_DEBUG, "EDID is not null");
		hactive = edid.x_resolution;
		vactive = edid.y_resolution;
		right_border = mode->hborder;
		bottom_border = mode->vborder;
		hpolarity = (mode->phsync == '-');
		vpolarity = (mode->pvsync == '-');
		vsync = mode->vspw;
		hsync = mode->hspw;
		vblank = mode->vbl;
		hblank = mode->hbl;
		hfront_porch = mode->hso;
		vfront_porch = mode->vso;
		target_frequency = mode->pixel_clock;
	} else
		printk(BIOS_DEBUG, "EDID is null, using 640 x 480 @ 60Hz mode");

	if (IS_ENABLED(CONFIG_FRAMEBUFFER_KEEP_VESA_MODE)) {
		vga_sr_write(1, 1);
		vga_sr_write(0x2, 0xf);
		vga_sr_write(0x3, 0x0);
		vga_sr_write(0x4, 0xe);
		vga_gr_write(0, 0x0);
		vga_gr_write(1, 0x0);
		vga_gr_write(2, 0x0);
		vga_gr_write(3, 0x0);
		vga_gr_write(4, 0x0);
		vga_gr_write(5, 0x0);
		vga_gr_write(6, 0x5);
		vga_gr_write(7, 0xf);
		vga_gr_write(0x10, 0x1);
		vga_gr_write(0x11, 0);

		edid.bytes_per_line = (edid.bytes_per_line + 63) & ~63;

		write32(mmio + DSPCNTR(0), DISPLAY_PLANE_ENABLE
			| DISPPLANE_BGRX888);
		write32(mmio + DSPADDR(0), 0);
		write32(mmio + DSPSTRIDE(0), edid.bytes_per_line);
		write32(mmio + DSPSURF(0), 0);
		for (i = 0; i < 0x100; i++)
			write32(mmio + LGC_PALETTE(0) + 4 * i, i * 0x010101);
	} else {
		vga_textmode_init();
	}

	pixel_p2 = target_frequency <= 225000 ? 10 : 5;

	u32 candn, candm1, candm2, candp1;
	for (candn = 1; candn <= 4; candn++) {
		for (candm1 = 23; candm1 >= 16; candm1--) {
			for (candm2 = 11; candm2 >= 5; candm2--) {
				for (candp1 = 8; candp1 >= 1; candp1--) {
					u32 m = 5 * (candm1 + 2) + (candm2 + 2);
					u32 p = candp1 * pixel_p2;
					u32 vco = DIV_ROUND_CLOSEST(
						BASE_FREQUENCY * m, candn + 2);
					u32 dot = DIV_ROUND_CLOSEST(vco, p);
					u32 this_err = MAX(dot, target_frequency) -
						MIN(dot, target_frequency);
					if (this_err < err_most) {
						err_most = this_err;
						pixel_n = candn;
						pixel_m1 = candm1;
						pixel_m2 = candm2;
						pixel_p1 = candp1;
					}
				}
			}
		}
	}

	if (err_most == 0xffffffff) {
		printk(BIOS_ERR, "Couldn't find GFX clock divisors\n");
		return;
	}

	printk(BIOS_INFO, "bringing up panel at resolution %d x %d\n",
	       hactive, vactive);
	printk(BIOS_DEBUG, "Borders %d x %d\n",
	       right_border, bottom_border);
	printk(BIOS_DEBUG, "Blank %d x %d\n",
	       hblank, vblank);
	printk(BIOS_DEBUG, "Sync %d x %d\n",
	       hsync, vsync);
	printk(BIOS_DEBUG, "Front porch %d x %d\n",
	       hfront_porch, vfront_porch);
	printk(BIOS_DEBUG, (info->gfx.use_spread_spectrum_clock
			    ? "Spread spectrum clock\n" : "DREF clock\n"));
	printk(BIOS_DEBUG, "Polarities %d, %d\n",
	       hpolarity, vpolarity);
	printk(BIOS_DEBUG, "Pixel N=%d, M1=%d, M2=%d, P1=%d, P2=%d\n",
		pixel_n, pixel_m1, pixel_m2, pixel_p1, pixel_p2);
	printk(BIOS_DEBUG, "Pixel clock %d kHz\n",
	       BASE_FREQUENCY * (5 * (pixel_m1 + 2) + (pixel_m2 + 2)) /
		(pixel_n + 2) / (pixel_p1 * pixel_p2));

	mdelay(1);
	write32(mmio + FP0(0), (pixel_n << 16)
		| (pixel_m1 << 8) | pixel_m2);
	write32(mmio + DPLL(0), DPLL_VCO_ENABLE
		| DPLL_VGA_MODE_DIS | DPLLB_MODE_DAC_SERIAL
		| (pixel_p2 == 10 ? DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 :
			DPLL_DAC_SERIAL_P2_CLOCK_DIV_5)
		| (0x10000 << (pixel_p1 - 1))
		| (6 << 9));

	mdelay(1);
	write32(mmio + DPLL(0), DPLL_VCO_ENABLE
		| DPLL_VGA_MODE_DIS | DPLLB_MODE_DAC_SERIAL
		| (pixel_p2 == 10 ? DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 :
			DPLL_DAC_SERIAL_P2_CLOCK_DIV_5)
		| (0x10000 << (pixel_p1 - 1))
		| (6 << 9));

	write32(mmio + ADPA, ADPA_DAC_ENABLE
			| ADPA_PIPE_A_SELECT
			| ADPA_CRT_HOTPLUG_MONITOR_COLOR
			| ADPA_CRT_HOTPLUG_ENABLE
			| ADPA_VSYNC_CNTL_ENABLE
			| ADPA_HSYNC_CNTL_ENABLE
			| ADPA_DPMS_ON
			| (vpolarity ? ADPA_VSYNC_ACTIVE_LOW :
			   ADPA_VSYNC_ACTIVE_HIGH)
			| (hpolarity ? ADPA_HSYNC_ACTIVE_LOW :
			   ADPA_HSYNC_ACTIVE_HIGH));

	write32(mmio + HTOTAL(0),
		((hactive + right_border + hblank - 1) << 16)
		| (hactive - 1));
	write32(mmio + HBLANK(0),
		((hactive + right_border + hblank - 1) << 16)
		| (hactive + right_border - 1));
	write32(mmio + HSYNC(0),
		((hactive + right_border + hfront_porch + hsync - 1) << 16)
		| (hactive + right_border + hfront_porch - 1));

	write32(mmio + VTOTAL(0), ((vactive + bottom_border + vblank - 1) << 16)
		| (vactive - 1));
	write32(mmio + VBLANK(0), ((vactive + bottom_border + vblank - 1) << 16)
		| (vactive + bottom_border - 1));
	write32(mmio + VSYNC(0),
		((vactive + bottom_border + vfront_porch + vsync - 1) << 16)
		| (vactive + bottom_border + vfront_porch - 1));

	write32(mmio + PIPECONF(0), PIPECONF_DISABLE);

	write32(mmio + PF_WIN_POS(0), 0);
	if (IS_ENABLED(CONFIG_FRAMEBUFFER_KEEP_VESA_MODE)) {
		write32(mmio + PIPESRC(0), ((hactive - 1) << 16)
			| (vactive - 1));
		write32(mmio + PF_CTL(0), 0);
		write32(mmio + PF_WIN_SZ(0), 0);
		write32(mmio + PFIT_CONTROL, 0);
	} else {
		write32(mmio + PIPESRC(0), (639 << 16) | 399);
		write32(mmio + PF_CTL(0), PF_ENABLE | PF_FILTER_MED_3x3);
		write32(mmio + PF_WIN_SZ(0), vactive | (hactive << 16));
		write32(mmio + PFIT_CONTROL, 0x80000000);
	}

	mdelay(1);
	write32(mmio + PIPECONF(0), PIPECONF_BPP_6);
	write32(mmio + PIPECONF(0), PIPECONF_BPP_6 | PIPECONF_DITHER_EN);
	write32(mmio + PIPECONF(0), PIPECONF_ENABLE
			| PIPECONF_BPP_6 | PIPECONF_DITHER_EN);

	if (IS_ENABLED(CONFIG_FRAMEBUFFER_KEEP_VESA_MODE)) {
		write32(mmio + VGACNTRL, VGA_DISP_DISABLE);
		write32(mmio + DSPCNTR(0), DISPLAY_PLANE_ENABLE
			| DISPPLANE_BGRX888);
		mdelay(1);
	} else {
		write32(mmio + VGACNTRL, 0xc4008e);
	}

	write32(mmio + ADPA, ADPA_DAC_ENABLE
			| ADPA_PIPE_A_SELECT
			| ADPA_CRT_HOTPLUG_MONITOR_COLOR
			| ADPA_CRT_HOTPLUG_ENABLE
			| ADPA_VSYNC_CNTL_ENABLE
			| ADPA_HSYNC_CNTL_ENABLE
			| ADPA_DPMS_ON
			| (vpolarity ? ADPA_VSYNC_ACTIVE_LOW :
			   ADPA_VSYNC_ACTIVE_HIGH)
			| (hpolarity ? ADPA_HSYNC_ACTIVE_LOW :
			   ADPA_HSYNC_ACTIVE_HIGH));

	write32(mmio + PP_CONTROL, PANEL_POWER_ON | PANEL_POWER_RESET);

	/* Enable screen memory. */
	vga_sr_write(1, vga_sr_read(1) & ~0x20);

	/* Clear interrupts. */
	write32(mmio + DEIIR, 0xffffffff);
	write32(mmio + SDEIIR, 0xffffffff);

	if (IS_ENABLED(CONFIG_FRAMEBUFFER_KEEP_VESA_MODE)) {
		memset((void *) lfb, 0,
			hactive * vactive * 4);
		set_vbe_mode_info_valid(&edid, lfb);
	}
}
Ejemplo n.º 11
0
/* this happens after cpu_init where exynos resources are set */
static void mainboard_init(device_t dev)
{
	int dp_tries;
	struct s5p_dp_device dp_device = {
		.base = (struct exynos5_dp *)EXYNOS5250_DP1_BASE,
		.video_info = &dp_video_info,
	};
	void *fb_addr = (void *)(get_fb_base_kb() * KiB);

	gpio_init();

	i2c_init(TPS65090_BUS, I2C_0_SPEED, I2C_SLAVE);
	i2c_init(7, I2C_0_SPEED, I2C_SLAVE);

	tmu_init(&exynos5250_tmu_info);

	/* Clock Gating all the unused IP's to save power */
	clock_gate();

	/* Disable USB3.0 PLL to save 250mW of power */
	disable_usb30_pll();

	set_vbe_mode_info_valid(&edid, (uintptr_t)fb_addr);

	lcd_vdd();

	// FIXME: should timeout
	do {
		udelay(50);
	} while (!exynos_dp_hotplug());

	exynos_dp_bridge_setup();
	for (dp_tries = 1; dp_tries <= MAX_DP_TRIES; dp_tries++) {
		exynos_dp_bridge_init();
		if (exynos_dp_hotplug()) {
			exynos_dp_reset();
			continue;
		}

		if (dp_controller_init(&dp_device))
			continue;

		udelay(LCD_T3_DELAY_MS * 1000);

		backlight_vdd();
		backlight_pwm();
		backlight_en();
		/* if we're here, we're successful */
		break;
	}

	if (dp_tries > MAX_DP_TRIES)
		printk(BIOS_ERR, "%s: Failed to set up displayport\n", __func__);

	// Uncomment to get excessive GPIO output:
	// gpio_info();
}

static void mainboard_enable(device_t dev)
{
	dev->ops->init = &mainboard_init;

	/* set up dcache and MMU */
	/* FIXME: this should happen via resource allocator */
	exynos5250_config_l2_cache();
	mmu_init();
	mmu_config_range(0, DRAM_START, DCACHE_OFF);
	mmu_config_range(DRAM_START, DRAM_SIZE, DCACHE_WRITEBACK);
	mmu_config_range(DRAM_END, 4096 - DRAM_END, DCACHE_OFF);
	dcache_invalidate_all();
	dcache_mmu_enable();

	/* this is going to move, but we must have it now and we're
	 * not sure where */
	exception_init();

	const unsigned epll_hz = 192000000;
	const unsigned sample_rate = 48000;
	const unsigned lr_frame_size = 256;
	clock_epll_set_rate(epll_hz);
	clock_select_i2s_clk_source();
	clock_set_i2s_clk_prescaler(epll_hz, sample_rate * lr_frame_size);

	power_enable_xclkout();
}
Ejemplo n.º 12
0
int i915lightup_sandy(const struct i915_gpu_controller_info *info,
		      u32 pphysbase, u16 piobase, u32 pmmio, u32 pgfx)
{
	static struct edid edid;
	int edid_ok;

	int index;
	u32 auxin[16], auxout[16];
	mmio = (void *)pmmio;
	addrport = piobase;
	dataport = addrport + 4;
	physbase = pphysbase;
	graphics = pgfx;
	printk(BIOS_SPEW, "i915lightup: graphics %p mmio %p"
		"addrport %04x physbase %08x\n",
		(void *)graphics, mmio, addrport, physbase);
	globalstart = rdtscll();


	edid_ok = decode_edid((unsigned char *)&link_edid_data,
			      sizeof(link_edid_data), &edid);
	printk(BIOS_SPEW, "decode edid returns %d\n", edid_ok);
	edid.framebuffer_bits_per_pixel = 32;

	htotal = (edid.ha - 1) | ((edid.ha + edid.hbl- 1) << 16);
	printk(BIOS_SPEW, "I915_WRITE(HTOTAL(pipe), %08x)\n", htotal);

	hblank = (edid.ha  - 1) | ((edid.ha + edid.hbl- 1) << 16);
	printk(BIOS_SPEW, "I915_WRITE(HBLANK(pipe),0x%08x)\n", hblank);

	hsync = (edid.ha + edid.hso  - 1) |
		((edid.ha + edid.hso + edid.hspw- 1) << 16);
	printk(BIOS_SPEW, "I915_WRITE(HSYNC(pipe),0x%08x)\n", hsync);

	vtotal = (edid.va - 1) | ((edid.va + edid.vbl- 1) << 16);
	printk(BIOS_SPEW, "I915_WRITE(VTOTAL(pipe), %08x)\n", vtotal);

	vblank = (edid.va  - 1) | ((edid.va + edid.vbl- 1) << 16);
	printk(BIOS_SPEW, "I915_WRITE(VBLANK(pipe),0x%08x)\n", vblank);

	vsync = (edid.va + edid.vso  - 1) |((edid.va + edid.vso + edid.vspw- 1) << 16);
	printk(BIOS_SPEW, "I915_WRITE(VSYNC(pipe),0x%08x)\n", vsync);

	printk(BIOS_SPEW, "Table has %d elements\n", niodefs);

	index = run(0);
	printk(BIOS_SPEW, "Run returns %d\n", index);
	auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_DPCD_REV<<8|0xe;
	intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 4, auxin, 14);
	auxout[0] = 0<<31 /* i2c */|1<<30|0x0<<28/*W*/|0x0<<8|0x0;
	intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 3, auxin, 0);
	index = run(index);
	printk(BIOS_SPEW, "Run returns %d\n", index);
	auxout[0] = 0<<31 /* i2c */|0<<30|0x0<<28/*W*/|0x0<<8|0x0;
	intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 3, auxin, 0);
	index = run(index);
	printk(BIOS_SPEW, "Run returns %d\n", index);
	auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_SET_POWER<<8|0x0;
	auxout[1] = 0x01000000;
	/* DP_SET_POWER_D0 | DP_PSR_SINK_INACTIVE */
	intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 5, auxin, 0);
	index = run(index);
	auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_LINK_BW_SET<<8|0x8;
	auxout[1] = 0x0a840000;
	/*( DP_LINK_BW_2_7 &0xa)|0x0000840a*/
	auxout[2] = 0x00000000;
	auxout[3] = 0x01000000;
	intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 13, auxin, 0);
	index = run(index);
	auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_PATTERN_SET<<8|0x0;
	auxout[1] = 0x21000000;
	/* DP_TRAINING_PATTERN_1 | DP_LINK_SCRAMBLING_DISABLE |
	 * 	DP_SYMBOL_ERROR_COUNT_BOTH |0x00000021*/
	intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 5, auxin, 0);
	index = run(index);
	auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_LANE0_SET<<8|0x3;
	auxout[1] = 0x00000000;
	/* DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0 |0x00000000*/
	intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 8, auxin, 0);
	index = run(index);
	auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_LANE0_1_STATUS<<8|0x5;
	intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 4, auxin, 5);
	index = run(index);
	auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_PATTERN_SET<<8|0x0;
	auxout[1] = 0x22000000;
	/* DP_TRAINING_PATTERN_2 | DP_LINK_SCRAMBLING_DISABLE |
	 * 	DP_SYMBOL_ERROR_COUNT_BOTH |0x00000022*/
	intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 5, auxin, 0);
	index = run(index);
	auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_LANE0_SET<<8|0x3;
	auxout[1] = 0x00000000;
	/* DP_TRAIN_VOLTAGE_SWING_400 | DP_TRAIN_PRE_EMPHASIS_0 |0x00000000*/
	intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 8, auxin, 0);
	index = run(index);
	auxout[0] = 1<<31 /* dp */|0x1<<28/*R*/|DP_LANE0_1_STATUS<<8|0x5;
	intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 4, auxin, 5);
	index = run(index);
	auxout[0] = 1<<31 /* dp */|0x0<<28/*W*/|DP_TRAINING_PATTERN_SET<<8|0x0;
	auxout[1] = 0x00000000;
	/* DP_TRAINING_PATTERN_DISABLE | DP_LINK_QUAL_PATTERN_DISABLE |
	 * 	DP_SYMBOL_ERROR_COUNT_BOTH |0x00000000*/
	intel_dp_aux_ch(DPA_AUX_CH_CTL, DPA_AUX_CH_DATA1, auxout, 5, auxin, 0);
	index = run(index);

	if (index != niodefs)
		printk(BIOS_ERR, "Left over IO work in i915_lightup"
			" -- this is likely a table error. "
			"Only %d of %d were done.\n", index, niodefs);
	printk(BIOS_SPEW, "DONE startup\n");
	verbose = 0;
	/* GTT is the Global Translation Table for the graphics pipeline.
	 * It is used to translate graphics addresses to physical
	 * memory addresses. As in the CPU, GTTs map 4K pages.
	 * There are 32 bits per pixel, or 4 bytes,
	 * which means 1024 pixels per page.
	 * There are 4250 GTTs on Link:
	 * 2650 (X) * 1700 (Y) pixels / 1024 pixels per page.
	 * The setgtt function adds a further bit of flexibility:
	 * it allows you to set a range (the first two parameters) to point
	 * to a physical address (third parameter);the physical address is
	 * incremented by a count (fourth parameter) for each GTT in the
	 * range.
	 * Why do it this way? For ultrafast startup,
	 * we can point all the GTT entries to point to one page,
	 * and set that page to 0s:
	 * memset(physbase, 0, 4096);
	 * setgtt(0, 4250, physbase, 0);
	 * this takes about 2 ms, and is a win because zeroing
	 * the page takes a up to 200 ms. We will be exploiting this
	 * trick in a later rev of this code.
	 * This call sets the GTT to point to a linear range of pages
	 * starting at physbase.
	 */
	setgtt(0, FRAME_BUFFER_PAGES, physbase, 4096);
	printk(BIOS_SPEW, "memset %p to 0 for %d bytes\n",
		(void *)graphics, FRAME_BUFFER_BYTES);
	memset((void *)graphics, 0, FRAME_BUFFER_BYTES);
	printk(BIOS_SPEW, "%ld microseconds\n", globalmicroseconds());
	set_vbe_mode_info_valid(&edid, (uintptr_t)graphics);
	i915_init_done = 1;
	return i915_init_done;
}