mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-08-05 16:54:27 +00:00
drm/nouveau: No need to lock/unlock the VGA CRTC regs all the time.
Locking only makes sense in the VBIOS parsing code as it's executed before CRTC init. Signed-off-by: Francisco Jerez <currojerez@riseup.net> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
d06ab841d1
commit
03cd06ca90
5 changed files with 23 additions and 85 deletions
|
@ -6607,7 +6607,6 @@ static bool
|
||||||
nouveau_bios_posted(struct drm_device *dev)
|
nouveau_bios_posted(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||||
bool was_locked;
|
|
||||||
unsigned htotal;
|
unsigned htotal;
|
||||||
|
|
||||||
if (dev_priv->chipset >= NV_50) {
|
if (dev_priv->chipset >= NV_50) {
|
||||||
|
@ -6617,13 +6616,14 @@ nouveau_bios_posted(struct drm_device *dev)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
was_locked = NVLockVgaCrtcs(dev, false);
|
NVLockVgaCrtcs(dev, false);
|
||||||
htotal = NVReadVgaCrtc(dev, 0, 0x06);
|
htotal = NVReadVgaCrtc(dev, 0, 0x06);
|
||||||
htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8;
|
htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8;
|
||||||
htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4;
|
htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4;
|
||||||
htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10;
|
htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10;
|
||||||
htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11;
|
htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11;
|
||||||
NVLockVgaCrtcs(dev, was_locked);
|
NVLockVgaCrtcs(dev, true);
|
||||||
|
|
||||||
return (htotal != 0);
|
return (htotal != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6632,7 +6632,6 @@ nouveau_bios_init(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||||
struct nvbios *bios = &dev_priv->vbios;
|
struct nvbios *bios = &dev_priv->vbios;
|
||||||
bool was_locked;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!NVInitVBIOS(dev))
|
if (!NVInitVBIOS(dev))
|
||||||
|
@ -6667,14 +6666,14 @@ nouveau_bios_init(struct drm_device *dev)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* feature_byte on BMP is poor, but init always sets CR4B */
|
/* feature_byte on BMP is poor, but init always sets CR4B */
|
||||||
was_locked = NVLockVgaCrtcs(dev, false);
|
NVLockVgaCrtcs(dev, false);
|
||||||
if (bios->major_version < 5)
|
if (bios->major_version < 5)
|
||||||
bios->is_mobile = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_4B) & 0x40;
|
bios->is_mobile = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_4B) & 0x40;
|
||||||
|
|
||||||
/* all BIT systems need p_f_m_t for digital_min_front_porch */
|
/* all BIT systems need p_f_m_t for digital_min_front_porch */
|
||||||
if (bios->is_mobile || bios->major_version >= 5)
|
if (bios->is_mobile || bios->major_version >= 5)
|
||||||
ret = parse_fp_mode_table(dev, bios);
|
ret = parse_fp_mode_table(dev, bios);
|
||||||
NVLockVgaCrtcs(dev, was_locked);
|
NVLockVgaCrtcs(dev, true);
|
||||||
|
|
||||||
/* allow subsequent scripts to execute */
|
/* allow subsequent scripts to execute */
|
||||||
bios->execute = true;
|
bios->execute = true;
|
||||||
|
|
|
@ -102,44 +102,12 @@ nouveau_connector_destroy(struct drm_connector *drm_connector)
|
||||||
kfree(drm_connector);
|
kfree(drm_connector);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
nouveau_connector_ddc_prepare(struct drm_connector *connector, int *flags)
|
|
||||||
{
|
|
||||||
struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
|
|
||||||
|
|
||||||
if (dev_priv->card_type >= NV_50)
|
|
||||||
return;
|
|
||||||
|
|
||||||
*flags = 0;
|
|
||||||
if (NVLockVgaCrtcs(dev_priv->dev, false))
|
|
||||||
*flags |= 1;
|
|
||||||
if (nv_heads_tied(dev_priv->dev))
|
|
||||||
*flags |= 2;
|
|
||||||
|
|
||||||
if (*flags & 2)
|
|
||||||
NVSetOwner(dev_priv->dev, 0); /* necessary? */
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
nouveau_connector_ddc_finish(struct drm_connector *connector, int flags)
|
|
||||||
{
|
|
||||||
struct drm_nouveau_private *dev_priv = connector->dev->dev_private;
|
|
||||||
|
|
||||||
if (dev_priv->card_type >= NV_50)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (flags & 2)
|
|
||||||
NVSetOwner(dev_priv->dev, 4);
|
|
||||||
if (flags & 1)
|
|
||||||
NVLockVgaCrtcs(dev_priv->dev, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct nouveau_i2c_chan *
|
static struct nouveau_i2c_chan *
|
||||||
nouveau_connector_ddc_detect(struct drm_connector *connector,
|
nouveau_connector_ddc_detect(struct drm_connector *connector,
|
||||||
struct nouveau_encoder **pnv_encoder)
|
struct nouveau_encoder **pnv_encoder)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = connector->dev;
|
struct drm_device *dev = connector->dev;
|
||||||
int ret, flags, i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
|
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
|
||||||
struct nouveau_i2c_chan *i2c;
|
struct nouveau_i2c_chan *i2c;
|
||||||
|
@ -155,17 +123,9 @@ nouveau_connector_ddc_detect(struct drm_connector *connector,
|
||||||
if (!obj)
|
if (!obj)
|
||||||
continue;
|
continue;
|
||||||
nv_encoder = nouveau_encoder(obj_to_encoder(obj));
|
nv_encoder = nouveau_encoder(obj_to_encoder(obj));
|
||||||
|
i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
|
||||||
|
|
||||||
if (nv_encoder->dcb->i2c_index < 0xf)
|
if (i2c && nouveau_probe_i2c_addr(i2c, 0x50)) {
|
||||||
i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index);
|
|
||||||
if (!i2c)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
nouveau_connector_ddc_prepare(connector, &flags);
|
|
||||||
ret = nouveau_probe_i2c_addr(i2c, 0x50);
|
|
||||||
nouveau_connector_ddc_finish(connector, flags);
|
|
||||||
|
|
||||||
if (ret) {
|
|
||||||
*pnv_encoder = nv_encoder;
|
*pnv_encoder = nv_encoder;
|
||||||
return i2c;
|
return i2c;
|
||||||
}
|
}
|
||||||
|
@ -218,7 +178,7 @@ nouveau_connector_detect(struct drm_connector *connector)
|
||||||
struct nouveau_connector *nv_connector = nouveau_connector(connector);
|
struct nouveau_connector *nv_connector = nouveau_connector(connector);
|
||||||
struct nouveau_encoder *nv_encoder = NULL;
|
struct nouveau_encoder *nv_encoder = NULL;
|
||||||
struct nouveau_i2c_chan *i2c;
|
struct nouveau_i2c_chan *i2c;
|
||||||
int type, flags;
|
int type;
|
||||||
|
|
||||||
/* Cleanup the previous EDID block. */
|
/* Cleanup the previous EDID block. */
|
||||||
if (nv_connector->edid) {
|
if (nv_connector->edid) {
|
||||||
|
@ -229,9 +189,7 @@ nouveau_connector_detect(struct drm_connector *connector)
|
||||||
|
|
||||||
i2c = nouveau_connector_ddc_detect(connector, &nv_encoder);
|
i2c = nouveau_connector_ddc_detect(connector, &nv_encoder);
|
||||||
if (i2c) {
|
if (i2c) {
|
||||||
nouveau_connector_ddc_prepare(connector, &flags);
|
|
||||||
nv_connector->edid = drm_get_edid(connector, &i2c->adapter);
|
nv_connector->edid = drm_get_edid(connector, &i2c->adapter);
|
||||||
nouveau_connector_ddc_finish(connector, flags);
|
|
||||||
drm_mode_connector_update_edid_property(connector,
|
drm_mode_connector_update_edid_property(connector,
|
||||||
nv_connector->edid);
|
nv_connector->edid);
|
||||||
if (!nv_connector->edid) {
|
if (!nv_connector->edid) {
|
||||||
|
|
|
@ -321,10 +321,9 @@ nouveau_pci_resume(struct pci_dev *pdev)
|
||||||
NV_ERROR(dev, "Could not pin/map cursor.\n");
|
NV_ERROR(dev, "Could not pin/map cursor.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dev_priv->card_type < NV_50) {
|
if (dev_priv->card_type < NV_50)
|
||||||
nv04_display_restore(dev);
|
nv04_display_restore(dev);
|
||||||
NVLockVgaCrtcs(dev, false);
|
else
|
||||||
} else
|
|
||||||
nv50_display_init(dev);
|
nv50_display_init(dev);
|
||||||
|
|
||||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||||
|
|
|
@ -32,8 +32,6 @@
|
||||||
#include "nouveau_encoder.h"
|
#include "nouveau_encoder.h"
|
||||||
#include "nouveau_connector.h"
|
#include "nouveau_connector.h"
|
||||||
|
|
||||||
#define MULTIPLE_ENCODERS(e) (e & (e - 1))
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
nv04_display_store_initial_head_owner(struct drm_device *dev)
|
nv04_display_store_initial_head_owner(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
|
@ -41,7 +39,7 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
|
||||||
|
|
||||||
if (dev_priv->chipset != 0x11) {
|
if (dev_priv->chipset != 0x11) {
|
||||||
dev_priv->crtc_owner = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44);
|
dev_priv->crtc_owner = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_44);
|
||||||
goto ownerknown;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* reading CR44 is broken on nv11, so we attempt to infer it */
|
/* reading CR44 is broken on nv11, so we attempt to infer it */
|
||||||
|
@ -52,8 +50,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
|
||||||
bool tvA = false;
|
bool tvA = false;
|
||||||
bool tvB = false;
|
bool tvB = false;
|
||||||
|
|
||||||
NVLockVgaCrtcs(dev, false);
|
|
||||||
|
|
||||||
slaved_on_B = NVReadVgaCrtc(dev, 1, NV_CIO_CRE_PIXEL_INDEX) &
|
slaved_on_B = NVReadVgaCrtc(dev, 1, NV_CIO_CRE_PIXEL_INDEX) &
|
||||||
0x80;
|
0x80;
|
||||||
if (slaved_on_B)
|
if (slaved_on_B)
|
||||||
|
@ -66,8 +62,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
|
||||||
tvA = !(NVReadVgaCrtc(dev, 0, NV_CIO_CRE_LCD__INDEX) &
|
tvA = !(NVReadVgaCrtc(dev, 0, NV_CIO_CRE_LCD__INDEX) &
|
||||||
MASK(NV_CIO_CRE_LCD_LCD_SELECT));
|
MASK(NV_CIO_CRE_LCD_LCD_SELECT));
|
||||||
|
|
||||||
NVLockVgaCrtcs(dev, true);
|
|
||||||
|
|
||||||
if (slaved_on_A && !tvA)
|
if (slaved_on_A && !tvA)
|
||||||
dev_priv->crtc_owner = 0x0;
|
dev_priv->crtc_owner = 0x0;
|
||||||
else if (slaved_on_B && !tvB)
|
else if (slaved_on_B && !tvB)
|
||||||
|
@ -79,12 +73,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
|
||||||
else
|
else
|
||||||
dev_priv->crtc_owner = 0x0;
|
dev_priv->crtc_owner = 0x0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ownerknown:
|
|
||||||
/* we need to ensure the heads are not tied henceforth, or reading any
|
|
||||||
* 8 bit reg on head B will fail
|
|
||||||
* setting a single arbitrary head solves that */
|
|
||||||
NVSetOwner(dev, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -99,8 +87,13 @@ nv04_display_create(struct drm_device *dev)
|
||||||
|
|
||||||
NV_DEBUG_KMS(dev, "\n");
|
NV_DEBUG_KMS(dev, "\n");
|
||||||
|
|
||||||
if (nv_two_heads(dev))
|
NVLockVgaCrtcs(dev, false);
|
||||||
|
|
||||||
|
if (nv_two_heads(dev)) {
|
||||||
nv04_display_store_initial_head_owner(dev);
|
nv04_display_store_initial_head_owner(dev);
|
||||||
|
NVSetOwner(dev, 0);
|
||||||
|
}
|
||||||
|
|
||||||
nouveau_hw_save_vga_fonts(dev, 1);
|
nouveau_hw_save_vga_fonts(dev, 1);
|
||||||
|
|
||||||
drm_mode_config_init(dev);
|
drm_mode_config_init(dev);
|
||||||
|
@ -168,8 +161,6 @@ nv04_display_create(struct drm_device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save previous state */
|
/* Save previous state */
|
||||||
NVLockVgaCrtcs(dev, false);
|
|
||||||
|
|
||||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
|
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
|
||||||
crtc->funcs->save(crtc);
|
crtc->funcs->save(crtc);
|
||||||
|
|
||||||
|
@ -185,6 +176,7 @@ nv04_display_create(struct drm_device *dev)
|
||||||
void
|
void
|
||||||
nv04_display_destroy(struct drm_device *dev)
|
nv04_display_destroy(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
|
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
||||||
struct drm_encoder *encoder;
|
struct drm_encoder *encoder;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
|
|
||||||
|
@ -200,8 +192,6 @@ nv04_display_destroy(struct drm_device *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore state */
|
/* Restore state */
|
||||||
NVLockVgaCrtcs(dev, false);
|
|
||||||
|
|
||||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||||
struct drm_encoder_helper_funcs *func = encoder->helper_private;
|
struct drm_encoder_helper_funcs *func = encoder->helper_private;
|
||||||
|
|
||||||
|
@ -214,12 +204,15 @@ nv04_display_destroy(struct drm_device *dev)
|
||||||
drm_mode_config_cleanup(dev);
|
drm_mode_config_cleanup(dev);
|
||||||
|
|
||||||
nouveau_hw_save_vga_fonts(dev, 0);
|
nouveau_hw_save_vga_fonts(dev, 0);
|
||||||
|
|
||||||
|
if (nv_two_heads(dev))
|
||||||
|
NVSetOwner(dev, dev_priv->crtc_owner);
|
||||||
|
NVLockVgaCrtcs(dev, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nv04_display_restore(struct drm_device *dev)
|
nv04_display_restore(struct drm_device *dev)
|
||||||
{
|
{
|
||||||
struct drm_nouveau_private *dev_priv = dev->dev_private;
|
|
||||||
struct drm_encoder *encoder;
|
struct drm_encoder *encoder;
|
||||||
struct drm_crtc *crtc;
|
struct drm_crtc *crtc;
|
||||||
|
|
||||||
|
@ -241,10 +234,5 @@ nv04_display_restore(struct drm_device *dev)
|
||||||
|
|
||||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
|
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
|
||||||
crtc->funcs->restore(crtc);
|
crtc->funcs->restore(crtc);
|
||||||
|
|
||||||
if (nv_two_heads(dev))
|
|
||||||
NVSetOwner(dev, dev_priv->crtc_owner);
|
|
||||||
|
|
||||||
NVLockVgaCrtcs(dev, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -194,7 +194,6 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
|
||||||
struct nouveau_i2c_chan *i2c =
|
struct nouveau_i2c_chan *i2c =
|
||||||
nouveau_i2c_find(dev, entry->i2c_index);
|
nouveau_i2c_find(dev, entry->i2c_index);
|
||||||
int type, ret;
|
int type, ret;
|
||||||
bool was_locked;
|
|
||||||
|
|
||||||
/* Ensure that we can talk to this encoder */
|
/* Ensure that we can talk to this encoder */
|
||||||
type = nv04_tv_identify(dev, entry->i2c_index);
|
type = nv04_tv_identify(dev, entry->i2c_index);
|
||||||
|
@ -224,13 +223,8 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
|
||||||
nv_encoder->or = ffs(entry->or) - 1;
|
nv_encoder->or = ffs(entry->or) - 1;
|
||||||
|
|
||||||
/* Run the slave-specific initialization */
|
/* Run the slave-specific initialization */
|
||||||
was_locked = NVLockVgaCrtcs(dev, false);
|
|
||||||
|
|
||||||
ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder),
|
ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder),
|
||||||
&i2c->adapter, &nv04_tv_encoder_info[type]);
|
&i2c->adapter, &nv04_tv_encoder_info[type]);
|
||||||
|
|
||||||
NVLockVgaCrtcs(dev, was_locked);
|
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto fail_cleanup;
|
goto fail_cleanup;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue