Skip to content

Commit

Permalink
drm/nouveau: No need to lock/unlock the VGA CRTC regs all the time.
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Francisco Jerez authored and Ben Skeggs committed Jul 26, 2010
1 parent d06ab84 commit 03cd06c
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 85 deletions.
11 changes: 5 additions & 6 deletions drivers/gpu/drm/nouveau/nouveau_bios.c
Original file line number Diff line number Diff line change
Expand Up @@ -6607,7 +6607,6 @@ static bool
nouveau_bios_posted(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
bool was_locked;
unsigned htotal;

if (dev_priv->chipset >= NV_50) {
Expand All @@ -6617,13 +6616,14 @@ nouveau_bios_posted(struct drm_device *dev)
return true;
}

was_locked = NVLockVgaCrtcs(dev, false);
NVLockVgaCrtcs(dev, false);
htotal = NVReadVgaCrtc(dev, 0, 0x06);
htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x01) << 8;
htotal |= (NVReadVgaCrtc(dev, 0, 0x07) & 0x20) << 4;
htotal |= (NVReadVgaCrtc(dev, 0, 0x25) & 0x01) << 10;
htotal |= (NVReadVgaCrtc(dev, 0, 0x41) & 0x01) << 11;
NVLockVgaCrtcs(dev, was_locked);
NVLockVgaCrtcs(dev, true);

return (htotal != 0);
}

Expand All @@ -6632,7 +6632,6 @@ nouveau_bios_init(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nvbios *bios = &dev_priv->vbios;
bool was_locked;
int ret;

if (!NVInitVBIOS(dev))
Expand Down Expand Up @@ -6667,14 +6666,14 @@ nouveau_bios_init(struct drm_device *dev)
return ret;

/* feature_byte on BMP is poor, but init always sets CR4B */
was_locked = NVLockVgaCrtcs(dev, false);
NVLockVgaCrtcs(dev, false);
if (bios->major_version < 5)
bios->is_mobile = NVReadVgaCrtc(dev, 0, NV_CIO_CRE_4B) & 0x40;

/* all BIT systems need p_f_m_t for digital_min_front_porch */
if (bios->is_mobile || bios->major_version >= 5)
ret = parse_fp_mode_table(dev, bios);
NVLockVgaCrtcs(dev, was_locked);
NVLockVgaCrtcs(dev, true);

/* allow subsequent scripts to execute */
bios->execute = true;
Expand Down
50 changes: 4 additions & 46 deletions drivers/gpu/drm/nouveau/nouveau_connector.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,44 +102,12 @@ nouveau_connector_destroy(struct drm_connector *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 *
nouveau_connector_ddc_detect(struct drm_connector *connector,
struct nouveau_encoder **pnv_encoder)
{
struct drm_device *dev = connector->dev;
int ret, flags, i;
int i;

for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
struct nouveau_i2c_chan *i2c;
Expand All @@ -155,17 +123,9 @@ nouveau_connector_ddc_detect(struct drm_connector *connector,
if (!obj)
continue;
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)
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) {
if (i2c && nouveau_probe_i2c_addr(i2c, 0x50)) {
*pnv_encoder = nv_encoder;
return i2c;
}
Expand Down Expand Up @@ -218,7 +178,7 @@ nouveau_connector_detect(struct drm_connector *connector)
struct nouveau_connector *nv_connector = nouveau_connector(connector);
struct nouveau_encoder *nv_encoder = NULL;
struct nouveau_i2c_chan *i2c;
int type, flags;
int type;

/* Cleanup the previous EDID block. */
if (nv_connector->edid) {
Expand All @@ -229,9 +189,7 @@ nouveau_connector_detect(struct drm_connector *connector)

i2c = nouveau_connector_ddc_detect(connector, &nv_encoder);
if (i2c) {
nouveau_connector_ddc_prepare(connector, &flags);
nv_connector->edid = drm_get_edid(connector, &i2c->adapter);
nouveau_connector_ddc_finish(connector, flags);
drm_mode_connector_update_edid_property(connector,
nv_connector->edid);
if (!nv_connector->edid) {
Expand Down
5 changes: 2 additions & 3 deletions drivers/gpu/drm/nouveau/nouveau_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -321,10 +321,9 @@ nouveau_pci_resume(struct pci_dev *pdev)
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);
NVLockVgaCrtcs(dev, false);
} else
else
nv50_display_init(dev);

list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
Expand Down
36 changes: 12 additions & 24 deletions drivers/gpu/drm/nouveau/nv04_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,14 @@
#include "nouveau_encoder.h"
#include "nouveau_connector.h"

#define MULTIPLE_ENCODERS(e) (e & (e - 1))

static void
nv04_display_store_initial_head_owner(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;

if (dev_priv->chipset != 0x11) {
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 */
Expand All @@ -52,8 +50,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
bool tvA = false;
bool tvB = false;

NVLockVgaCrtcs(dev, false);

slaved_on_B = NVReadVgaCrtc(dev, 1, NV_CIO_CRE_PIXEL_INDEX) &
0x80;
if (slaved_on_B)
Expand All @@ -66,8 +62,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
tvA = !(NVReadVgaCrtc(dev, 0, NV_CIO_CRE_LCD__INDEX) &
MASK(NV_CIO_CRE_LCD_LCD_SELECT));

NVLockVgaCrtcs(dev, true);

if (slaved_on_A && !tvA)
dev_priv->crtc_owner = 0x0;
else if (slaved_on_B && !tvB)
Expand All @@ -79,12 +73,6 @@ nv04_display_store_initial_head_owner(struct drm_device *dev)
else
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
Expand All @@ -99,8 +87,13 @@ nv04_display_create(struct drm_device *dev)

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);
NVSetOwner(dev, 0);
}

nouveau_hw_save_vga_fonts(dev, 1);

drm_mode_config_init(dev);
Expand Down Expand Up @@ -168,8 +161,6 @@ nv04_display_create(struct drm_device *dev)
}

/* Save previous state */
NVLockVgaCrtcs(dev, false);

list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
crtc->funcs->save(crtc);

Expand All @@ -185,6 +176,7 @@ nv04_display_create(struct drm_device *dev)
void
nv04_display_destroy(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct drm_encoder *encoder;
struct drm_crtc *crtc;

Expand All @@ -200,8 +192,6 @@ nv04_display_destroy(struct drm_device *dev)
}

/* Restore state */
NVLockVgaCrtcs(dev, false);

list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
struct drm_encoder_helper_funcs *func = encoder->helper_private;

Expand All @@ -214,12 +204,15 @@ nv04_display_destroy(struct drm_device *dev)
drm_mode_config_cleanup(dev);

nouveau_hw_save_vga_fonts(dev, 0);

if (nv_two_heads(dev))
NVSetOwner(dev, dev_priv->crtc_owner);
NVLockVgaCrtcs(dev, true);
}

void
nv04_display_restore(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct drm_encoder *encoder;
struct drm_crtc *crtc;

Expand All @@ -241,10 +234,5 @@ nv04_display_restore(struct drm_device *dev)

list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
crtc->funcs->restore(crtc);

if (nv_two_heads(dev))
NVSetOwner(dev, dev_priv->crtc_owner);

NVLockVgaCrtcs(dev, true);
}

6 changes: 0 additions & 6 deletions drivers/gpu/drm/nouveau/nv04_tv.c
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,6 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
struct nouveau_i2c_chan *i2c =
nouveau_i2c_find(dev, entry->i2c_index);
int type, ret;
bool was_locked;

/* Ensure that we can talk to this encoder */
type = nv04_tv_identify(dev, entry->i2c_index);
Expand Down Expand Up @@ -224,13 +223,8 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_entry *entry)
nv_encoder->or = ffs(entry->or) - 1;

/* Run the slave-specific initialization */
was_locked = NVLockVgaCrtcs(dev, false);

ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder),
&i2c->adapter, &nv04_tv_encoder_info[type]);

NVLockVgaCrtcs(dev, was_locked);

if (ret < 0)
goto fail_cleanup;

Expand Down

0 comments on commit 03cd06c

Please sign in to comment.