brintos

brintos / linux-shallow public Read only

0
0
Text · 15.8 KiB · d5924ca Raw
589 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (c) 2006 Intel Corporation4 *5 * Authors:6 *    Eric Anholt <eric@anholt.net>7 */8 9#include <drm/display/drm_dp_helper.h>10#include <drm/drm.h>11 12#include "intel_bios.h"13#include "psb_drv.h"14#include "psb_intel_drv.h"15#include "psb_intel_reg.h"16 17#define	TARGET_ADDR1	0x7018#define	TARGET_ADDR2	0x7219 20static void *find_section(struct bdb_header *bdb, int section_id)21{22	u8 *base = (u8 *)bdb;23	int index = 0;24	u16 total, current_size;25	u8 current_id;26 27	/* skip to first section */28	index += bdb->header_size;29	total = bdb->bdb_size;30 31	/* walk the sections looking for section_id */32	while (index < total) {33		current_id = *(base + index);34		index++;35		current_size = *((u16 *)(base + index));36		index += 2;37		if (current_id == section_id)38			return base + index;39		index += current_size;40	}41 42	return NULL;43}44 45static void46parse_edp(struct drm_psb_private *dev_priv, struct bdb_header *bdb)47{48	struct bdb_edp *edp;49	struct edp_power_seq *edp_pps;50	struct edp_link_params *edp_link_params;51	uint8_t	panel_type;52 53	edp = find_section(bdb, BDB_EDP);54 55	dev_priv->edp.bpp = 18;56	if (!edp) {57		if (dev_priv->edp.support) {58			DRM_DEBUG_KMS("No eDP BDB found but eDP panel supported, assume %dbpp panel color depth.\n",59				      dev_priv->edp.bpp);60		}61		return;62	}63 64	panel_type = dev_priv->panel_type;65	switch ((edp->color_depth >> (panel_type * 2)) & 3) {66	case EDP_18BPP:67		dev_priv->edp.bpp = 18;68		break;69	case EDP_24BPP:70		dev_priv->edp.bpp = 24;71		break;72	case EDP_30BPP:73		dev_priv->edp.bpp = 30;74		break;75	}76 77	/* Get the eDP sequencing and link info */78	edp_pps = &edp->power_seqs[panel_type];79	edp_link_params = &edp->link_params[panel_type];80 81	dev_priv->edp.pps = *edp_pps;82 83	DRM_DEBUG_KMS("EDP timing in vbt t1_t3 %d t8 %d t9 %d t10 %d t11_t12 %d\n",84				dev_priv->edp.pps.t1_t3, dev_priv->edp.pps.t8,85				dev_priv->edp.pps.t9, dev_priv->edp.pps.t10,86				dev_priv->edp.pps.t11_t12);87 88	dev_priv->edp.rate = edp_link_params->rate ? DP_LINK_BW_2_7 :89		DP_LINK_BW_1_62;90	switch (edp_link_params->lanes) {91	case 0:92		dev_priv->edp.lanes = 1;93		break;94	case 1:95		dev_priv->edp.lanes = 2;96		break;97	case 3:98	default:99		dev_priv->edp.lanes = 4;100		break;101	}102	DRM_DEBUG_KMS("VBT reports EDP: Lane_count %d, Lane_rate %d, Bpp %d\n",103			dev_priv->edp.lanes, dev_priv->edp.rate, dev_priv->edp.bpp);104 105	switch (edp_link_params->preemphasis) {106	case 0:107		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_0;108		break;109	case 1:110		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_1;111		break;112	case 2:113		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_2;114		break;115	case 3:116		dev_priv->edp.preemphasis = DP_TRAIN_PRE_EMPH_LEVEL_3;117		break;118	}119	switch (edp_link_params->vswing) {120	case 0:121		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_0;122		break;123	case 1:124		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_1;125		break;126	case 2:127		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_2;128		break;129	case 3:130		dev_priv->edp.vswing = DP_TRAIN_VOLTAGE_SWING_LEVEL_3;131		break;132	}133	DRM_DEBUG_KMS("VBT reports EDP: VSwing  %d, Preemph %d\n",134			dev_priv->edp.vswing, dev_priv->edp.preemphasis);135}136 137static u16138get_blocksize(void *p)139{140	u16 *block_ptr, block_size;141 142	block_ptr = (u16 *)((char *)p - 2);143	block_size = *block_ptr;144	return block_size;145}146 147static void fill_detail_timing_data(struct drm_display_mode *panel_fixed_mode,148			struct lvds_dvo_timing *dvo_timing)149{150	panel_fixed_mode->hdisplay = (dvo_timing->hactive_hi << 8) |151		dvo_timing->hactive_lo;152	panel_fixed_mode->hsync_start = panel_fixed_mode->hdisplay +153		((dvo_timing->hsync_off_hi << 8) | dvo_timing->hsync_off_lo);154	panel_fixed_mode->hsync_end = panel_fixed_mode->hsync_start +155		dvo_timing->hsync_pulse_width;156	panel_fixed_mode->htotal = panel_fixed_mode->hdisplay +157		((dvo_timing->hblank_hi << 8) | dvo_timing->hblank_lo);158 159	panel_fixed_mode->vdisplay = (dvo_timing->vactive_hi << 8) |160		dvo_timing->vactive_lo;161	panel_fixed_mode->vsync_start = panel_fixed_mode->vdisplay +162		dvo_timing->vsync_off;163	panel_fixed_mode->vsync_end = panel_fixed_mode->vsync_start +164		dvo_timing->vsync_pulse_width;165	panel_fixed_mode->vtotal = panel_fixed_mode->vdisplay +166		((dvo_timing->vblank_hi << 8) | dvo_timing->vblank_lo);167	panel_fixed_mode->clock = dvo_timing->clock * 10;168	panel_fixed_mode->type = DRM_MODE_TYPE_PREFERRED;169 170	if (dvo_timing->hsync_positive)171		panel_fixed_mode->flags |= DRM_MODE_FLAG_PHSYNC;172	else173		panel_fixed_mode->flags |= DRM_MODE_FLAG_NHSYNC;174 175	if (dvo_timing->vsync_positive)176		panel_fixed_mode->flags |= DRM_MODE_FLAG_PVSYNC;177	else178		panel_fixed_mode->flags |= DRM_MODE_FLAG_NVSYNC;179 180	/* Some VBTs have bogus h/vtotal values */181	if (panel_fixed_mode->hsync_end > panel_fixed_mode->htotal)182		panel_fixed_mode->htotal = panel_fixed_mode->hsync_end + 1;183	if (panel_fixed_mode->vsync_end > panel_fixed_mode->vtotal)184		panel_fixed_mode->vtotal = panel_fixed_mode->vsync_end + 1;185 186	drm_mode_set_name(panel_fixed_mode);187}188 189static void parse_backlight_data(struct drm_psb_private *dev_priv,190				struct bdb_header *bdb)191{192	struct bdb_lvds_backlight *vbt_lvds_bl = NULL;193	struct bdb_lvds_backlight *lvds_bl;194	u8 p_type = 0;195	void *bl_start = NULL;196	struct bdb_lvds_options *lvds_opts197				= find_section(bdb, BDB_LVDS_OPTIONS);198 199	dev_priv->lvds_bl = NULL;200 201	if (lvds_opts)202		p_type = lvds_opts->panel_type;203	else204		return;205 206	bl_start = find_section(bdb, BDB_LVDS_BACKLIGHT);207	vbt_lvds_bl = (struct bdb_lvds_backlight *)(bl_start + 1) + p_type;208 209	lvds_bl = kmemdup(vbt_lvds_bl, sizeof(*vbt_lvds_bl), GFP_KERNEL);210	if (!lvds_bl) {211		dev_err(dev_priv->dev.dev, "out of memory for backlight data\n");212		return;213	}214	dev_priv->lvds_bl = lvds_bl;215}216 217/* Try to find integrated panel data */218static void parse_lfp_panel_data(struct drm_psb_private *dev_priv,219			    struct bdb_header *bdb)220{221	struct bdb_lvds_options *lvds_options;222	struct bdb_lvds_lfp_data *lvds_lfp_data;223	struct bdb_lvds_lfp_data_entry *entry;224	struct lvds_dvo_timing *dvo_timing;225	struct drm_display_mode *panel_fixed_mode;226 227	/* Defaults if we can't find VBT info */228	dev_priv->lvds_dither = 0;229	dev_priv->lvds_vbt = 0;230 231	lvds_options = find_section(bdb, BDB_LVDS_OPTIONS);232	if (!lvds_options)233		return;234 235	dev_priv->lvds_dither = lvds_options->pixel_dither;236	dev_priv->panel_type = lvds_options->panel_type;237 238	if (lvds_options->panel_type == 0xff)239		return;240 241	lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);242	if (!lvds_lfp_data)243		return;244 245 246	entry = &lvds_lfp_data->data[lvds_options->panel_type];247	dvo_timing = &entry->dvo_timing;248 249	panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode),250				      GFP_KERNEL);251	if (panel_fixed_mode == NULL) {252		dev_err(dev_priv->dev.dev, "out of memory for fixed panel mode\n");253		return;254	}255 256	dev_priv->lvds_vbt = 1;257	fill_detail_timing_data(panel_fixed_mode, dvo_timing);258 259	if (panel_fixed_mode->htotal > 0 && panel_fixed_mode->vtotal > 0) {260		dev_priv->lfp_lvds_vbt_mode = panel_fixed_mode;261		drm_mode_debug_printmodeline(panel_fixed_mode);262	} else {263		dev_dbg(dev_priv->dev.dev, "ignoring invalid LVDS VBT\n");264		dev_priv->lvds_vbt = 0;265		kfree(panel_fixed_mode);266	}267	return;268}269 270/* Try to find sdvo panel data */271static void parse_sdvo_panel_data(struct drm_psb_private *dev_priv,272		      struct bdb_header *bdb)273{274	struct bdb_sdvo_lvds_options *sdvo_lvds_options;275	struct lvds_dvo_timing *dvo_timing;276	struct drm_display_mode *panel_fixed_mode;277 278	dev_priv->sdvo_lvds_vbt_mode = NULL;279 280	sdvo_lvds_options = find_section(bdb, BDB_SDVO_LVDS_OPTIONS);281	if (!sdvo_lvds_options)282		return;283 284	dvo_timing = find_section(bdb, BDB_SDVO_PANEL_DTDS);285	if (!dvo_timing)286		return;287 288	panel_fixed_mode = kzalloc(sizeof(*panel_fixed_mode), GFP_KERNEL);289 290	if (!panel_fixed_mode)291		return;292 293	fill_detail_timing_data(panel_fixed_mode,294			dvo_timing + sdvo_lvds_options->panel_type);295 296	dev_priv->sdvo_lvds_vbt_mode = panel_fixed_mode;297 298	return;299}300 301static void parse_general_features(struct drm_psb_private *dev_priv,302		       struct bdb_header *bdb)303{304	struct bdb_general_features *general;305 306	/* Set sensible defaults in case we can't find the general block */307	dev_priv->int_tv_support = 1;308	dev_priv->int_crt_support = 1;309 310	general = find_section(bdb, BDB_GENERAL_FEATURES);311	if (general) {312		dev_priv->int_tv_support = general->int_tv_support;313		dev_priv->int_crt_support = general->int_crt_support;314		dev_priv->lvds_use_ssc = general->enable_ssc;315 316		if (dev_priv->lvds_use_ssc) {317			dev_priv->lvds_ssc_freq318				= general->ssc_freq ? 100 : 96;319		}320	}321}322 323static void324parse_sdvo_device_mapping(struct drm_psb_private *dev_priv,325			  struct bdb_header *bdb)326{327	struct sdvo_device_mapping *p_mapping;328	struct bdb_general_definitions *p_defs;329	struct child_device_config *p_child;330	int i, child_device_num, count;331	u16	block_size;332 333	p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);334	if (!p_defs) {335		DRM_DEBUG_KMS("No general definition block is found, unable to construct sdvo mapping.\n");336		return;337	}338	/* judge whether the size of child device meets the requirements.339	 * If the child device size obtained from general definition block340	 * is different with sizeof(struct child_device_config), skip the341	 * parsing of sdvo device info342	 */343	if (p_defs->child_dev_size != sizeof(*p_child)) {344		/* different child dev size . Ignore it */345		DRM_DEBUG_KMS("different child size is found. Invalid.\n");346		return;347	}348	/* get the block size of general definitions */349	block_size = get_blocksize(p_defs);350	/* get the number of child device */351	child_device_num = (block_size - sizeof(*p_defs)) /352				sizeof(*p_child);353	count = 0;354	for (i = 0; i < child_device_num; i++) {355		p_child = &(p_defs->devices[i]);356		if (!p_child->device_type) {357			/* skip the device block if device type is invalid */358			continue;359		}360		if (p_child->target_addr != TARGET_ADDR1 &&361			p_child->target_addr != TARGET_ADDR2) {362			/*363			 * If the target address is neither 0x70 nor 0x72,364			 * it is not a SDVO device. Skip it.365			 */366			continue;367		}368		if (p_child->dvo_port != DEVICE_PORT_DVOB &&369			p_child->dvo_port != DEVICE_PORT_DVOC) {370			/* skip the incorrect SDVO port */371			DRM_DEBUG_KMS("Incorrect SDVO port. Skip it\n");372			continue;373		}374		DRM_DEBUG_KMS("the SDVO device with target addr %2x is found on"375				" %s port\n",376				p_child->target_addr,377				(p_child->dvo_port == DEVICE_PORT_DVOB) ?378					"SDVOB" : "SDVOC");379		p_mapping = &(dev_priv->sdvo_mappings[p_child->dvo_port - 1]);380		if (!p_mapping->initialized) {381			p_mapping->dvo_port = p_child->dvo_port;382			p_mapping->target_addr = p_child->target_addr;383			p_mapping->dvo_wiring = p_child->dvo_wiring;384			p_mapping->ddc_pin = p_child->ddc_pin;385			p_mapping->i2c_pin = p_child->i2c_pin;386			p_mapping->initialized = 1;387			DRM_DEBUG_KMS("SDVO device: dvo=%x, addr=%x, wiring=%d, ddc_pin=%d, i2c_pin=%d\n",388				      p_mapping->dvo_port,389				      p_mapping->target_addr,390				      p_mapping->dvo_wiring,391				      p_mapping->ddc_pin,392				      p_mapping->i2c_pin);393		} else {394			DRM_DEBUG_KMS("Maybe one SDVO port is shared by "395					 "two SDVO device.\n");396		}397		if (p_child->target2_addr) {398			/* Maybe this is a SDVO device with multiple inputs */399			/* And the mapping info is not added */400			DRM_DEBUG_KMS("there exists the target2_addr. Maybe this"401				" is a SDVO device with multiple inputs.\n");402		}403		count++;404	}405 406	if (!count) {407		/* No SDVO device info is found */408		DRM_DEBUG_KMS("No SDVO device info is found in VBT\n");409	}410	return;411}412 413 414static void415parse_driver_features(struct drm_psb_private *dev_priv,416		      struct bdb_header *bdb)417{418	struct bdb_driver_features *driver;419 420	driver = find_section(bdb, BDB_DRIVER_FEATURES);421	if (!driver)422		return;423 424	if (driver->lvds_config == BDB_DRIVER_FEATURE_EDP)425		dev_priv->edp.support = 1;426 427	dev_priv->lvds_enabled_in_vbt = driver->lvds_config != 0;428	DRM_DEBUG_KMS("LVDS VBT config bits: 0x%x\n", driver->lvds_config);429 430	/* This bit means to use 96Mhz for DPLL_A or not */431	if (driver->primary_lfp_id)432		dev_priv->dplla_96mhz = true;433	else434		dev_priv->dplla_96mhz = false;435}436 437static void438parse_device_mapping(struct drm_psb_private *dev_priv,439		       struct bdb_header *bdb)440{441	struct bdb_general_definitions *p_defs;442	struct child_device_config *p_child, *child_dev_ptr;443	int i, child_device_num, count;444	u16	block_size;445 446	p_defs = find_section(bdb, BDB_GENERAL_DEFINITIONS);447	if (!p_defs) {448		DRM_DEBUG_KMS("No general definition block is found, no devices defined.\n");449		return;450	}451	/* judge whether the size of child device meets the requirements.452	 * If the child device size obtained from general definition block453	 * is different with sizeof(struct child_device_config), skip the454	 * parsing of sdvo device info455	 */456	if (p_defs->child_dev_size != sizeof(*p_child)) {457		/* different child dev size . Ignore it */458		DRM_DEBUG_KMS("different child size is found. Invalid.\n");459		return;460	}461	/* get the block size of general definitions */462	block_size = get_blocksize(p_defs);463	/* get the number of child device */464	child_device_num = (block_size - sizeof(*p_defs)) /465				sizeof(*p_child);466	count = 0;467	/* get the number of child devices that are present */468	for (i = 0; i < child_device_num; i++) {469		p_child = &(p_defs->devices[i]);470		if (!p_child->device_type) {471			/* skip the device block if device type is invalid */472			continue;473		}474		count++;475	}476	if (!count) {477		DRM_DEBUG_KMS("no child dev is parsed from VBT\n");478		return;479	}480	dev_priv->child_dev = kcalloc(count, sizeof(*p_child), GFP_KERNEL);481	if (!dev_priv->child_dev) {482		DRM_DEBUG_KMS("No memory space for child devices\n");483		return;484	}485 486	dev_priv->child_dev_num = count;487	count = 0;488	for (i = 0; i < child_device_num; i++) {489		p_child = &(p_defs->devices[i]);490		if (!p_child->device_type) {491			/* skip the device block if device type is invalid */492			continue;493		}494		child_dev_ptr = dev_priv->child_dev + count;495		count++;496		memcpy((void *)child_dev_ptr, (void *)p_child,497					sizeof(*p_child));498	}499	return;500}501 502 503/**504 * psb_intel_init_bios - initialize VBIOS settings & find VBT505 * @dev: DRM device506 *507 * Loads the Video BIOS and checks that the VBT exists.  Sets scratch registers508 * to appropriate values.509 *510 * VBT existence is a sanity check that is relied on by other i830_bios.c code.511 * Note that it would be better to use a BIOS call to get the VBT, as BIOSes may512 * feed an updated VBT back through that, compared to what we'll fetch using513 * this method of groping around in the BIOS data.514 *515 * Returns 0 on success, nonzero on failure.516 */517int psb_intel_init_bios(struct drm_device *dev)518{519	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);520	struct pci_dev *pdev = to_pci_dev(dev->dev);521	struct vbt_header *vbt = NULL;522	struct bdb_header *bdb = NULL;523	u8 __iomem *bios = NULL;524	size_t size;525	int i;526 527 528	dev_priv->panel_type = 0xff;529 530	/* XXX Should this validation be moved to intel_opregion.c? */531	if (dev_priv->opregion.vbt) {532		struct vbt_header *vbt = dev_priv->opregion.vbt;533		if (memcmp(vbt->signature, "$VBT", 4) == 0) {534			DRM_DEBUG_KMS("Using VBT from OpRegion: %20s\n",535					 vbt->signature);536			bdb = (struct bdb_header *)((char *)vbt + vbt->bdb_offset);537		} else538			dev_priv->opregion.vbt = NULL;539	}540 541	if (bdb == NULL) {542		bios = pci_map_rom(pdev, &size);543		if (!bios)544			return -1;545 546		/* Scour memory looking for the VBT signature */547		for (i = 0; i + 4 < size; i++) {548			if (!memcmp(bios + i, "$VBT", 4)) {549				vbt = (struct vbt_header *)(bios + i);550				break;551			}552		}553 554		if (!vbt) {555			dev_err(dev->dev, "VBT signature missing\n");556			pci_unmap_rom(pdev, bios);557			return -1;558		}559		bdb = (struct bdb_header *)(bios + i + vbt->bdb_offset);560	}561 562	/* Grab useful general dxefinitions */563	parse_general_features(dev_priv, bdb);564	parse_driver_features(dev_priv, bdb);565	parse_lfp_panel_data(dev_priv, bdb);566	parse_sdvo_panel_data(dev_priv, bdb);567	parse_sdvo_device_mapping(dev_priv, bdb);568	parse_device_mapping(dev_priv, bdb);569	parse_backlight_data(dev_priv, bdb);570	parse_edp(dev_priv, bdb);571 572	if (bios)573		pci_unmap_rom(pdev, bios);574 575	return 0;576}577 578/*579 * Destroy and free VBT data580 */581void psb_intel_destroy_bios(struct drm_device *dev)582{583	struct drm_psb_private *dev_priv = to_drm_psb_private(dev);584 585	kfree(dev_priv->sdvo_lvds_vbt_mode);586	kfree(dev_priv->lfp_lvds_vbt_mode);587	kfree(dev_priv->lvds_bl);588}589