diff options
author | Dave Airlie <airlied@redhat.com> | 2015-10-11 23:59:04 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2015-10-11 23:59:04 -0400 |
commit | 7b98040a7718663903bb25c06c7aed9801abbd9d (patch) | |
tree | 8920d665e9ef2016fe0c378f30e16ac17cea8283 | |
parent | 621bd0f6982badd6483acb191eb7b6226a578328 (diff) | |
parent | 25d295882a1adfcdaaad85369289677b87c7c8f0 (diff) |
Merge branch 'linux-4.3' of git://anongit.freedesktop.org/git/nouveau/linux-2.6 into drm-fixes
Nothing too crazy here, a couple of regression fixes + runpm/fbcon
race fix.
* 'linux-4.3' of git://anongit.freedesktop.org/git/nouveau/linux-2.6:
drm/nouveau/bios: fix OF loading
drm/nouveau/fbcon: take runpm reference when userspace has an open fd
drm/nouveau/nouveau: Disable AGP for SiS 761
drm/nouveau/display: allow up to 16k width/height for fermi+
drm/nouveau/bios: translate devinit pri/sec i2c bus to internal identifiers
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_display.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_fbcon.c | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/bios/priv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c | 27 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowof.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/subdev/pci/agp.c | 8 |
7 files changed, 77 insertions, 14 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index cc6c228e11c8..e905c00acf1a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c | |||
@@ -469,9 +469,13 @@ nouveau_display_create(struct drm_device *dev) | |||
469 | if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) { | 469 | if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) { |
470 | dev->mode_config.max_width = 4096; | 470 | dev->mode_config.max_width = 4096; |
471 | dev->mode_config.max_height = 4096; | 471 | dev->mode_config.max_height = 4096; |
472 | } else { | 472 | } else |
473 | if (drm->device.info.family < NV_DEVICE_INFO_V0_FERMI) { | ||
473 | dev->mode_config.max_width = 8192; | 474 | dev->mode_config.max_width = 8192; |
474 | dev->mode_config.max_height = 8192; | 475 | dev->mode_config.max_height = 8192; |
476 | } else { | ||
477 | dev->mode_config.max_width = 16384; | ||
478 | dev->mode_config.max_height = 16384; | ||
475 | } | 479 | } |
476 | 480 | ||
477 | dev->mode_config.preferred_depth = 24; | 481 | dev->mode_config.preferred_depth = 24; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 2791701685dc..59f27e774acb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
@@ -178,8 +178,30 @@ nouveau_fbcon_sync(struct fb_info *info) | |||
178 | return 0; | 178 | return 0; |
179 | } | 179 | } |
180 | 180 | ||
181 | static int | ||
182 | nouveau_fbcon_open(struct fb_info *info, int user) | ||
183 | { | ||
184 | struct nouveau_fbdev *fbcon = info->par; | ||
185 | struct nouveau_drm *drm = nouveau_drm(fbcon->dev); | ||
186 | int ret = pm_runtime_get_sync(drm->dev->dev); | ||
187 | if (ret < 0 && ret != -EACCES) | ||
188 | return ret; | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | static int | ||
193 | nouveau_fbcon_release(struct fb_info *info, int user) | ||
194 | { | ||
195 | struct nouveau_fbdev *fbcon = info->par; | ||
196 | struct nouveau_drm *drm = nouveau_drm(fbcon->dev); | ||
197 | pm_runtime_put(drm->dev->dev); | ||
198 | return 0; | ||
199 | } | ||
200 | |||
181 | static struct fb_ops nouveau_fbcon_ops = { | 201 | static struct fb_ops nouveau_fbcon_ops = { |
182 | .owner = THIS_MODULE, | 202 | .owner = THIS_MODULE, |
203 | .fb_open = nouveau_fbcon_open, | ||
204 | .fb_release = nouveau_fbcon_release, | ||
183 | .fb_check_var = drm_fb_helper_check_var, | 205 | .fb_check_var = drm_fb_helper_check_var, |
184 | .fb_set_par = drm_fb_helper_set_par, | 206 | .fb_set_par = drm_fb_helper_set_par, |
185 | .fb_fillrect = nouveau_fbcon_fillrect, | 207 | .fb_fillrect = nouveau_fbcon_fillrect, |
@@ -195,6 +217,8 @@ static struct fb_ops nouveau_fbcon_ops = { | |||
195 | 217 | ||
196 | static struct fb_ops nouveau_fbcon_sw_ops = { | 218 | static struct fb_ops nouveau_fbcon_sw_ops = { |
197 | .owner = THIS_MODULE, | 219 | .owner = THIS_MODULE, |
220 | .fb_open = nouveau_fbcon_open, | ||
221 | .fb_release = nouveau_fbcon_release, | ||
198 | .fb_check_var = drm_fb_helper_check_var, | 222 | .fb_check_var = drm_fb_helper_check_var, |
199 | .fb_set_par = drm_fb_helper_set_par, | 223 | .fb_set_par = drm_fb_helper_set_par, |
200 | .fb_fillrect = drm_fb_helper_cfb_fillrect, | 224 | .fb_fillrect = drm_fb_helper_cfb_fillrect, |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c index 65af31441e9c..a7d69ce7abc1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/init.c | |||
@@ -267,6 +267,12 @@ init_i2c(struct nvbios_init *init, int index) | |||
267 | index = NVKM_I2C_BUS_PRI; | 267 | index = NVKM_I2C_BUS_PRI; |
268 | if (init->outp && init->outp->i2c_upper_default) | 268 | if (init->outp && init->outp->i2c_upper_default) |
269 | index = NVKM_I2C_BUS_SEC; | 269 | index = NVKM_I2C_BUS_SEC; |
270 | } else | ||
271 | if (index == 0x80) { | ||
272 | index = NVKM_I2C_BUS_PRI; | ||
273 | } else | ||
274 | if (index == 0x81) { | ||
275 | index = NVKM_I2C_BUS_SEC; | ||
270 | } | 276 | } |
271 | 277 | ||
272 | bus = nvkm_i2c_bus_find(i2c, index); | 278 | bus = nvkm_i2c_bus_find(i2c, index); |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/priv.h index e0ec2a6b7b79..212800ecdce9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/priv.h | |||
@@ -8,7 +8,10 @@ struct nvbios_source { | |||
8 | void *(*init)(struct nvkm_bios *, const char *); | 8 | void *(*init)(struct nvkm_bios *, const char *); |
9 | void (*fini)(void *); | 9 | void (*fini)(void *); |
10 | u32 (*read)(void *, u32 offset, u32 length, struct nvkm_bios *); | 10 | u32 (*read)(void *, u32 offset, u32 length, struct nvkm_bios *); |
11 | u32 (*size)(void *); | ||
11 | bool rw; | 12 | bool rw; |
13 | bool ignore_checksum; | ||
14 | bool no_pcir; | ||
12 | }; | 15 | }; |
13 | 16 | ||
14 | int nvbios_extend(struct nvkm_bios *, u32 length); | 17 | int nvbios_extend(struct nvkm_bios *, u32 length); |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c index 792f017525f6..b2557e87afdd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c | |||
@@ -45,7 +45,7 @@ shadow_fetch(struct nvkm_bios *bios, struct shadow *mthd, u32 upto) | |||
45 | u32 read = mthd->func->read(data, start, limit - start, bios); | 45 | u32 read = mthd->func->read(data, start, limit - start, bios); |
46 | bios->size = start + read; | 46 | bios->size = start + read; |
47 | } | 47 | } |
48 | return bios->size >= limit; | 48 | return bios->size >= upto; |
49 | } | 49 | } |
50 | 50 | ||
51 | static int | 51 | static int |
@@ -55,14 +55,22 @@ shadow_image(struct nvkm_bios *bios, int idx, u32 offset, struct shadow *mthd) | |||
55 | struct nvbios_image image; | 55 | struct nvbios_image image; |
56 | int score = 1; | 56 | int score = 1; |
57 | 57 | ||
58 | if (!shadow_fetch(bios, mthd, offset + 0x1000)) { | 58 | if (mthd->func->no_pcir) { |
59 | nvkm_debug(subdev, "%08x: header fetch failed\n", offset); | 59 | image.base = 0; |
60 | return 0; | 60 | image.type = 0; |
61 | } | 61 | image.size = mthd->func->size(mthd->data); |
62 | image.last = 1; | ||
63 | } else { | ||
64 | if (!shadow_fetch(bios, mthd, offset + 0x1000)) { | ||
65 | nvkm_debug(subdev, "%08x: header fetch failed\n", | ||
66 | offset); | ||
67 | return 0; | ||
68 | } | ||
62 | 69 | ||
63 | if (!nvbios_image(bios, idx, &image)) { | 70 | if (!nvbios_image(bios, idx, &image)) { |
64 | nvkm_debug(subdev, "image %d invalid\n", idx); | 71 | nvkm_debug(subdev, "image %d invalid\n", idx); |
65 | return 0; | 72 | return 0; |
73 | } | ||
66 | } | 74 | } |
67 | nvkm_debug(subdev, "%08x: type %02x, %d bytes\n", | 75 | nvkm_debug(subdev, "%08x: type %02x, %d bytes\n", |
68 | image.base, image.type, image.size); | 76 | image.base, image.type, image.size); |
@@ -74,7 +82,8 @@ shadow_image(struct nvkm_bios *bios, int idx, u32 offset, struct shadow *mthd) | |||
74 | 82 | ||
75 | switch (image.type) { | 83 | switch (image.type) { |
76 | case 0x00: | 84 | case 0x00: |
77 | if (nvbios_checksum(&bios->data[image.base], image.size)) { | 85 | if (!mthd->func->ignore_checksum && |
86 | nvbios_checksum(&bios->data[image.base], image.size)) { | ||
78 | nvkm_debug(subdev, "%08x: checksum failed\n", | 87 | nvkm_debug(subdev, "%08x: checksum failed\n", |
79 | image.base); | 88 | image.base); |
80 | if (mthd->func->rw) | 89 | if (mthd->func->rw) |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowof.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowof.c index bd60d7dd09f5..4bf486b57101 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowof.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowof.c | |||
@@ -21,6 +21,7 @@ | |||
21 | * | 21 | * |
22 | */ | 22 | */ |
23 | #include "priv.h" | 23 | #include "priv.h" |
24 | |||
24 | #include <core/pci.h> | 25 | #include <core/pci.h> |
25 | 26 | ||
26 | #if defined(__powerpc__) | 27 | #if defined(__powerpc__) |
@@ -33,17 +34,26 @@ static u32 | |||
33 | of_read(void *data, u32 offset, u32 length, struct nvkm_bios *bios) | 34 | of_read(void *data, u32 offset, u32 length, struct nvkm_bios *bios) |
34 | { | 35 | { |
35 | struct priv *priv = data; | 36 | struct priv *priv = data; |
36 | if (offset + length <= priv->size) { | 37 | if (offset < priv->size) { |
38 | length = min_t(u32, length, priv->size - offset); | ||
37 | memcpy_fromio(bios->data + offset, priv->data + offset, length); | 39 | memcpy_fromio(bios->data + offset, priv->data + offset, length); |
38 | return length; | 40 | return length; |
39 | } | 41 | } |
40 | return 0; | 42 | return 0; |
41 | } | 43 | } |
42 | 44 | ||
45 | static u32 | ||
46 | of_size(void *data) | ||
47 | { | ||
48 | struct priv *priv = data; | ||
49 | return priv->size; | ||
50 | } | ||
51 | |||
43 | static void * | 52 | static void * |
44 | of_init(struct nvkm_bios *bios, const char *name) | 53 | of_init(struct nvkm_bios *bios, const char *name) |
45 | { | 54 | { |
46 | struct pci_dev *pdev = bios->subdev.device->func->pci(bios->subdev.device)->pdev; | 55 | struct nvkm_device *device = bios->subdev.device; |
56 | struct pci_dev *pdev = device->func->pci(device)->pdev; | ||
47 | struct device_node *dn; | 57 | struct device_node *dn; |
48 | struct priv *priv; | 58 | struct priv *priv; |
49 | if (!(dn = pci_device_to_OF_node(pdev))) | 59 | if (!(dn = pci_device_to_OF_node(pdev))) |
@@ -62,7 +72,10 @@ nvbios_of = { | |||
62 | .init = of_init, | 72 | .init = of_init, |
63 | .fini = (void(*)(void *))kfree, | 73 | .fini = (void(*)(void *))kfree, |
64 | .read = of_read, | 74 | .read = of_read, |
75 | .size = of_size, | ||
65 | .rw = false, | 76 | .rw = false, |
77 | .ignore_checksum = true, | ||
78 | .no_pcir = true, | ||
66 | }; | 79 | }; |
67 | #else | 80 | #else |
68 | const struct nvbios_source | 81 | const struct nvbios_source |
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/agp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/agp.c index 814cb51cc873..385a90f91ed6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/agp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/agp.c | |||
@@ -35,6 +35,8 @@ static const struct nvkm_device_agp_quirk | |||
35 | nvkm_device_agp_quirks[] = { | 35 | nvkm_device_agp_quirks[] = { |
36 | /* VIA Apollo PRO133x / GeForce FX 5600 Ultra - fdo#20341 */ | 36 | /* VIA Apollo PRO133x / GeForce FX 5600 Ultra - fdo#20341 */ |
37 | { PCI_VENDOR_ID_VIA, 0x0691, PCI_VENDOR_ID_NVIDIA, 0x0311, 2 }, | 37 | { PCI_VENDOR_ID_VIA, 0x0691, PCI_VENDOR_ID_NVIDIA, 0x0311, 2 }, |
38 | /* SiS 761 does not support AGP cards, use PCI mode */ | ||
39 | { PCI_VENDOR_ID_SI, 0x0761, PCI_ANY_ID, PCI_ANY_ID, 0 }, | ||
38 | {}, | 40 | {}, |
39 | }; | 41 | }; |
40 | 42 | ||
@@ -137,8 +139,10 @@ nvkm_agp_ctor(struct nvkm_pci *pci) | |||
137 | while (quirk->hostbridge_vendor) { | 139 | while (quirk->hostbridge_vendor) { |
138 | if (info.device->vendor == quirk->hostbridge_vendor && | 140 | if (info.device->vendor == quirk->hostbridge_vendor && |
139 | info.device->device == quirk->hostbridge_device && | 141 | info.device->device == quirk->hostbridge_device && |
140 | pci->pdev->vendor == quirk->chip_vendor && | 142 | (quirk->chip_vendor == (u16)PCI_ANY_ID || |
141 | pci->pdev->device == quirk->chip_device) { | 143 | pci->pdev->vendor == quirk->chip_vendor) && |
144 | (quirk->chip_device == (u16)PCI_ANY_ID || | ||
145 | pci->pdev->device == quirk->chip_device)) { | ||
142 | nvkm_info(subdev, "forcing default agp mode to %dX, " | 146 | nvkm_info(subdev, "forcing default agp mode to %dX, " |
143 | "use NvAGP=<mode> to override\n", | 147 | "use NvAGP=<mode> to override\n", |
144 | quirk->mode); | 148 | quirk->mode); |