aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-07-22 21:31:08 -0400
committerBen Skeggs <bskeggs@redhat.com>2010-07-25 21:42:59 -0400
commitd0875edd9374296af8702d850254809e34a809cd (patch)
treef9870d97129af1a7a941904f38fb60401a65b1b0 /drivers/gpu/drm
parent49eed80ad0cfa5d5d02992e8088463cbf1a5ff85 (diff)
drm/nv50: add function to control GPIO IRQ reporting
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h1
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c20
-rw-r--r--drivers/gpu/drm/nouveau/nv50_gpio.c19
-rw-r--r--drivers/gpu/drm/nouveau/nv50_mc.c13
4 files changed, 35 insertions, 18 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 9d53f3d1487d..6b24186a103f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -1140,6 +1140,7 @@ int nv17_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);
1140/* nv50_gpio.c */ 1140/* nv50_gpio.c */
1141int nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); 1141int nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
1142int nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); 1142int nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);
1143void nv50_gpio_irq_enable(struct drm_device *, enum dcb_gpio_tag, bool on);
1143 1144
1144/* nv50_calc. */ 1145/* nv50_calc. */
1145int nv50_calc_pll(struct drm_device *, struct pll_lims *, int clk, 1146int nv50_calc_pll(struct drm_device *, struct pll_lims *, int clk,
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index c19ed8c8e3b5..fbd91c251ee9 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -184,7 +184,7 @@ nv50_display_init(struct drm_device *dev)
184 struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; 184 struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer;
185 struct nouveau_channel *evo = dev_priv->evo; 185 struct nouveau_channel *evo = dev_priv->evo;
186 struct drm_connector *connector; 186 struct drm_connector *connector;
187 uint32_t val, ram_amount, hpd_en[2]; 187 uint32_t val, ram_amount;
188 uint64_t start; 188 uint64_t start;
189 int ret, i; 189 int ret, i;
190 190
@@ -365,26 +365,10 @@ nv50_display_init(struct drm_device *dev)
365 NV50_PDISPLAY_INTR_EN_CLK_UNK40)); 365 NV50_PDISPLAY_INTR_EN_CLK_UNK40));
366 366
367 /* enable hotplug interrupts */ 367 /* enable hotplug interrupts */
368 hpd_en[0] = hpd_en[1] = 0;
369 list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 368 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
370 struct nouveau_connector *conn = nouveau_connector(connector); 369 struct nouveau_connector *conn = nouveau_connector(connector);
371 struct dcb_gpio_entry *gpio;
372
373 if (conn->dcb->gpio_tag == 0xff)
374 continue;
375
376 gpio = nouveau_bios_gpio_entry(dev, conn->dcb->gpio_tag);
377 if (!gpio)
378 continue;
379 370
380 hpd_en[gpio->line >> 4] |= (0x00010001 << (gpio->line & 0xf)); 371 nv50_gpio_irq_enable(dev, conn->dcb->gpio_tag, true);
381 }
382
383 nv_wr32(dev, 0xe054, 0xffffffff);
384 nv_wr32(dev, 0xe050, hpd_en[0]);
385 if (dev_priv->chipset >= 0x90) {
386 nv_wr32(dev, 0xe074, 0xffffffff);
387 nv_wr32(dev, 0xe070, hpd_en[1]);
388 } 372 }
389 373
390 return 0; 374 return 0;
diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c
index bb47ad737267..88715c5003c1 100644
--- a/drivers/gpu/drm/nouveau/nv50_gpio.c
+++ b/drivers/gpu/drm/nouveau/nv50_gpio.c
@@ -74,3 +74,22 @@ nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state)
74 nv_wr32(dev, r, v); 74 nv_wr32(dev, r, v);
75 return 0; 75 return 0;
76} 76}
77
78void
79nv50_gpio_irq_enable(struct drm_device *dev, enum dcb_gpio_tag tag, bool on)
80{
81 struct dcb_gpio_entry *gpio;
82 u32 reg, mask;
83
84 gpio = nouveau_bios_gpio_entry(dev, tag);
85 if (!gpio) {
86 NV_ERROR(dev, "gpio tag 0x%02x not found\n", tag);
87 return;
88 }
89
90 reg = gpio->line < 16 ? 0xe050 : 0xe070;
91 mask = 0x00010001 << (gpio->line & 0xf);
92
93 nv_wr32(dev, reg + 4, mask);
94 nv_mask(dev, reg + 0, mask, on ? mask : 0);
95}
diff --git a/drivers/gpu/drm/nouveau/nv50_mc.c b/drivers/gpu/drm/nouveau/nv50_mc.c
index e0a9c3faa202..f680e8e121b1 100644
--- a/drivers/gpu/drm/nouveau/nv50_mc.c
+++ b/drivers/gpu/drm/nouveau/nv50_mc.c
@@ -31,7 +31,20 @@
31int 31int
32nv50_mc_init(struct drm_device *dev) 32nv50_mc_init(struct drm_device *dev)
33{ 33{
34 struct drm_nouveau_private *dev_priv = dev->dev_private;
35
34 nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF); 36 nv_wr32(dev, NV03_PMC_ENABLE, 0xFFFFFFFF);
37
38 /* disable, and ack any pending gpio interrupts
39 * XXX doesn't technically belong here, but it'll do for the moment
40 */
41 nv_wr32(dev, 0xe050, 0x00000000);
42 nv_wr32(dev, 0xe054, 0xffffffff);
43 if (dev_priv->chipset >= 0x90) {
44 nv_wr32(dev, 0xe070, 0x00000000);
45 nv_wr32(dev, 0xe074, 0xffffffff);
46 }
47
35 return 0; 48 return 0;
36} 49}
37 50