diff options
| author | Dave Airlie <airlied@linux.ie> | 2008-07-26 08:38:59 +1000 | 
|---|---|---|
| committer | Dave Airlie <airlied@linux.ie> | 2008-07-26 08:38:59 +1000 | 
| commit | fb05c4d621084d7a3fb3dd52d7d9c888eac852d0 (patch) | |
| tree | bca43a3c777984e0eb962d55817541801377d3c4 /linux-core/nv50_dac.c | |
| parent | 2556341f8baf0e0b7b5f7843135e43e662751af0 (diff) | |
| parent | 53428453758621da70d9608c9baec58b4b9383ec (diff) | |
Merge remote branch 'origin/modesetting-101' into modesetting-gem
Diffstat (limited to 'linux-core/nv50_dac.c')
| -rw-r--r-- | linux-core/nv50_dac.c | 42 | 
1 files changed, 41 insertions, 1 deletions
| diff --git a/linux-core/nv50_dac.c b/linux-core/nv50_dac.c index ca4bb5e1..5dddb469 100644 --- a/linux-core/nv50_dac.c +++ b/linux-core/nv50_dac.c @@ -133,6 +133,46 @@ static int nv50_dac_set_power_mode(struct nv50_output *output, int mode)  	return 0;  } +static int nv50_dac_detect(struct nv50_output *output) +{ +	struct drm_nouveau_private *dev_priv = output->dev->dev_private; +	int or = nv50_output_or_offset(output); +	bool present = 0; +	uint32_t dpms_state, load_pattern, load_state; + +	NV_WRITE(NV50_PDISPLAY_DAC_REGS_CLK_CTRL1(or), 0x00000001); +	dpms_state = NV_READ(NV50_PDISPLAY_DAC_REGS_DPMS_CTRL(or)); + +	NV_WRITE(NV50_PDISPLAY_DAC_REGS_DPMS_CTRL(or), 0x00150000 | NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_PENDING); +	while (NV_READ(NV50_PDISPLAY_DAC_REGS_DPMS_CTRL(or)) & NV50_PDISPLAY_DAC_REGS_DPMS_CTRL_PENDING); + +	/* Use bios provided value if possible. */ +	if (dev_priv->bios.dactestval) { +		load_pattern = dev_priv->bios.dactestval; +		NV50_DEBUG("Using bios provided load_pattern of %d\n", load_pattern); +	} else { +		load_pattern = 340; +		NV50_DEBUG("Using default load_pattern of %d\n", load_pattern); +	} + +	NV_WRITE(NV50_PDISPLAY_DAC_REGS_LOAD_CTRL(or), NV50_PDISPLAY_DAC_REGS_LOAD_CTRL_ACTIVE | load_pattern); +	udelay(10000); /* give it some time to process */ +	load_state = NV_READ(NV50_PDISPLAY_DAC_REGS_LOAD_CTRL(or)); + +	NV_WRITE(NV50_PDISPLAY_DAC_REGS_LOAD_CTRL(or), 0); +	NV_WRITE(NV50_PDISPLAY_DAC_REGS_DPMS_CTRL(or), dpms_state); + +	if ((load_state & NV50_PDISPLAY_DAC_REGS_LOAD_CTRL_PRESENT) == NV50_PDISPLAY_DAC_REGS_LOAD_CTRL_PRESENT) +		present = 1; + +	if (present) +		NV50_DEBUG("Load was detected on output with or %d\n", or); +	else +		NV50_DEBUG("Load was not detected on output with or %d\n", or); + +	return present; +} +  static int nv50_dac_destroy(struct nv50_output *output)  {  	struct drm_device *dev = output->dev; @@ -210,7 +250,7 @@ int nv50_dac_create(struct drm_device *dev, int dcb_entry)  	output->execute_mode = nv50_dac_execute_mode;  	output->set_clock_mode = nv50_dac_set_clock_mode;  	output->set_power_mode = nv50_dac_set_power_mode; -	output->detect = NULL; /* TODO */ +	output->detect = nv50_dac_detect;  	output->destroy = nv50_dac_destroy;  	return 0; | 
