Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'linux-4.10' of git://github.com/skeggsb/linux into drm-next

- Initial atomic modesetting support. Used for "legacy" KMS interfaces,
ioctl not exposed by default, but there is a commandline option to
enable it.
- Initial DP 1.2 MST support
- Misc other code cleanups + fixes

* 'linux-4.10' of git://github.com/skeggsb/linux: (64 commits)
drm/nouveau/fifo/gf100-: protect channel preempt with subdev mutex
drm/nouveau/gr: fallback to legacy paths during firmware lookup
drm/nouveau/kms/nv50: initial support for DP 1.2 multi-stream
drm/nouveau/kms/nv50: allow encoder update to be called from other modules
drm/nouveau/kms/nv50: rename remaining nv50_crtc to nv50_head
drm/nouveau/kms/nv50: remove code to create ctxdma for every framebuffer
drm/nouveau/kms/nv50: remove code to support non-atomic page flips
drm/nouveau/kms/nv50: remove code to support non-atomic connector properties
drm/nouveau/kms/nv50: remove code to support non-atomic dpms
drm/nouveau/kms/nv50: remove code to support non-atomic modesets
drm/nouveau/kms/nv50: transition to atomic interfaces internally
drm/nouveau/kms/nv50: turn mode_set_base_atomic() into a stub
drm/nouveau/kms/nv50: convert encoder mode_fixup into an atomic_check()
drm/nouveau/kms/nv50: clean-up encoder functions
drm/nouveau/kms/nv50: ensure encoder normal power state is enabled at startup
drm/nouveau/kms/nv50: prepare ctxdma interface to be usable with atomic
drm/nouveau/kms/nv50: separate out cursor channel commit
drm/nouveau/kms/nv50: separate out base channel commit
drm/nouveau/kms/nv50: separate out vblank dmi commit
drm/nouveau/kms/nv50: separate out procamp commit
...

+4252 -1987
+1 -1
drivers/gpu/drm/nouveau/dispnv04/overlay.c
··· 33 33 #include "nouveau_connector.h" 34 34 #include "nouveau_display.h" 35 35 #include "nvreg.h" 36 - 36 + #include "disp.h" 37 37 38 38 struct nouveau_plane { 39 39 struct drm_plane base;
+17
drivers/gpu/drm/nouveau/include/nvif/cl5070.h
··· 34 34 #define NV50_DISP_MTHD_V1_SOR_HDMI_PWR 0x22 35 35 #define NV50_DISP_MTHD_V1_SOR_LVDS_SCRIPT 0x23 36 36 #define NV50_DISP_MTHD_V1_SOR_DP_PWR 0x24 37 + #define NV50_DISP_MTHD_V1_SOR_DP_MST_LINK 0x25 38 + #define NV50_DISP_MTHD_V1_SOR_DP_MST_VCPI 0x26 37 39 #define NV50_DISP_MTHD_V1_PIOR_PWR 0x30 38 40 __u8 method; 39 41 __u16 hasht; ··· 90 88 __u8 version; 91 89 __u8 state; 92 90 __u8 pad02[6]; 91 + }; 92 + 93 + struct nv50_disp_sor_dp_mst_link_v0 { 94 + __u8 version; 95 + __u8 state; 96 + __u8 pad02[6]; 97 + }; 98 + 99 + struct nv50_disp_sor_dp_mst_vcpi_v0 { 100 + __u8 version; 101 + __u8 pad01[1]; 102 + __u8 start_slot; 103 + __u8 num_slots; 104 + __u16 pbn; 105 + __u16 aligned_pbn; 93 106 }; 94 107 95 108 struct nv50_disp_pior_pwr_v0 {
+29
drivers/gpu/drm/nouveau/include/nvif/object.h
··· 66 66 67 67 #define nvif_mthd(a,b,c,d) nvif_object_mthd((a), (b), (c), (d)) 68 68 69 + struct nvif_mclass { 70 + s32 oclass; 71 + int version; 72 + }; 73 + 74 + #define nvif_mclass(o,m) ({ \ 75 + struct nvif_object *object = (o); \ 76 + struct nvif_sclass *sclass; \ 77 + const typeof(m[0]) *mclass = (m); \ 78 + int ret = -ENODEV; \ 79 + int cnt, i, j; \ 80 + \ 81 + cnt = nvif_object_sclass_get(object, &sclass); \ 82 + if (cnt >= 0) { \ 83 + for (i = 0; ret < 0 && mclass[i].oclass; i++) { \ 84 + for (j = 0; j < cnt; j++) { \ 85 + if (mclass[i].oclass == sclass[j].oclass && \ 86 + mclass[i].version >= sclass[j].minver && \ 87 + mclass[i].version <= sclass[j].maxver) { \ 88 + ret = i; \ 89 + break; \ 90 + } \ 91 + } \ 92 + } \ 93 + nvif_object_sclass_put(&sclass); \ 94 + } \ 95 + ret; \ 96 + }) 97 + 69 98 /*XXX*/ 70 99 #include <core/object.h> 71 100 #define nvxx_object(a) ({ \
+3
drivers/gpu/drm/nouveau/include/nvkm/subdev/fb.h
··· 93 93 int gk20a_fb_new(struct nvkm_device *, int, struct nvkm_fb **); 94 94 int gm107_fb_new(struct nvkm_device *, int, struct nvkm_fb **); 95 95 int gm200_fb_new(struct nvkm_device *, int, struct nvkm_fb **); 96 + int gm20b_fb_new(struct nvkm_device *, int, struct nvkm_fb **); 96 97 int gp100_fb_new(struct nvkm_device *, int, struct nvkm_fb **); 97 98 int gp104_fb_new(struct nvkm_device *, int, struct nvkm_fb **); 98 99 ··· 157 156 int (*prog)(struct nvkm_ram *); 158 157 void (*tidy)(struct nvkm_ram *); 159 158 }; 159 + 160 + extern const u8 gf100_pte_storage_type_map[256]; 160 161 #endif
+3
drivers/gpu/drm/nouveau/nouveau_bios.c
··· 333 333 if (bios->major_version < 5 && bios->data[0x48] & 0x4) 334 334 return NVReadVgaCrtc5758(dev, 0, 0xf) & 0xf; 335 335 336 + if (drm->device.info.family >= NV_DEVICE_INFO_V0_MAXWELL) 337 + return nvif_rd32(device, 0x001800) & 0x0000000f; 338 + else 336 339 if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) 337 340 return (nvif_rd32(device, NV_PEXTDEV_BOOT_0) >> 24) & 0xf; 338 341 else
+363 -297
drivers/gpu/drm/nouveau/nouveau_connector.c
··· 30 30 #include <linux/vga_switcheroo.h> 31 31 32 32 #include <drm/drmP.h> 33 + #include <drm/drm_atomic_helper.h> 33 34 #include <drm/drm_edid.h> 34 35 #include <drm/drm_crtc_helper.h> 35 36 ··· 47 46 #include <nvif/class.h> 48 47 #include <nvif/cl0046.h> 49 48 #include <nvif/event.h> 49 + 50 + struct drm_display_mode * 51 + nouveau_conn_native_mode(struct drm_connector *connector) 52 + { 53 + const struct drm_connector_helper_funcs *helper = connector->helper_private; 54 + struct nouveau_drm *drm = nouveau_drm(connector->dev); 55 + struct drm_device *dev = connector->dev; 56 + struct drm_display_mode *mode, *largest = NULL; 57 + int high_w = 0, high_h = 0, high_v = 0; 58 + 59 + list_for_each_entry(mode, &connector->probed_modes, head) { 60 + mode->vrefresh = drm_mode_vrefresh(mode); 61 + if (helper->mode_valid(connector, mode) != MODE_OK || 62 + (mode->flags & DRM_MODE_FLAG_INTERLACE)) 63 + continue; 64 + 65 + /* Use preferred mode if there is one.. */ 66 + if (mode->type & DRM_MODE_TYPE_PREFERRED) { 67 + NV_DEBUG(drm, "native mode from preferred\n"); 68 + return drm_mode_duplicate(dev, mode); 69 + } 70 + 71 + /* Otherwise, take the resolution with the largest width, then 72 + * height, then vertical refresh 73 + */ 74 + if (mode->hdisplay < high_w) 75 + continue; 76 + 77 + if (mode->hdisplay == high_w && mode->vdisplay < high_h) 78 + continue; 79 + 80 + if (mode->hdisplay == high_w && mode->vdisplay == high_h && 81 + mode->vrefresh < high_v) 82 + continue; 83 + 84 + high_w = mode->hdisplay; 85 + high_h = mode->vdisplay; 86 + high_v = mode->vrefresh; 87 + largest = mode; 88 + } 89 + 90 + NV_DEBUG(drm, "native mode from largest: %dx%d@%d\n", 91 + high_w, high_h, high_v); 92 + return largest ? drm_mode_duplicate(dev, largest) : NULL; 93 + } 94 + 95 + int 96 + nouveau_conn_atomic_get_property(struct drm_connector *connector, 97 + const struct drm_connector_state *state, 98 + struct drm_property *property, u64 *val) 99 + { 100 + struct nouveau_conn_atom *asyc = nouveau_conn_atom(state); 101 + struct nouveau_display *disp = nouveau_display(connector->dev); 102 + struct drm_device *dev = connector->dev; 103 + 104 + if (property == dev->mode_config.scaling_mode_property) 105 + *val = asyc->scaler.mode; 106 + else if (property == disp->underscan_property) 107 + *val = asyc->scaler.underscan.mode; 108 + else if (property == disp->underscan_hborder_property) 109 + *val = asyc->scaler.underscan.hborder; 110 + else if (property == disp->underscan_vborder_property) 111 + *val = asyc->scaler.underscan.vborder; 112 + else if (property == disp->dithering_mode) 113 + *val = asyc->dither.mode; 114 + else if (property == disp->dithering_depth) 115 + *val = asyc->dither.depth; 116 + else if (property == disp->vibrant_hue_property) 117 + *val = asyc->procamp.vibrant_hue; 118 + else if (property == disp->color_vibrance_property) 119 + *val = asyc->procamp.color_vibrance; 120 + else 121 + return -EINVAL; 122 + 123 + return 0; 124 + } 125 + 126 + int 127 + nouveau_conn_atomic_set_property(struct drm_connector *connector, 128 + struct drm_connector_state *state, 129 + struct drm_property *property, u64 val) 130 + { 131 + struct drm_device *dev = connector->dev; 132 + struct nouveau_conn_atom *asyc = nouveau_conn_atom(state); 133 + struct nouveau_display *disp = nouveau_display(dev); 134 + 135 + if (property == dev->mode_config.scaling_mode_property) { 136 + switch (val) { 137 + case DRM_MODE_SCALE_NONE: 138 + /* We allow 'None' for EDID modes, even on a fixed 139 + * panel (some exist with support for lower refresh 140 + * rates, which people might want to use for power- 141 + * saving purposes). 142 + * 143 + * Non-EDID modes will force the use of GPU scaling 144 + * to the native mode regardless of this setting. 145 + */ 146 + switch (connector->connector_type) { 147 + case DRM_MODE_CONNECTOR_LVDS: 148 + case DRM_MODE_CONNECTOR_eDP: 149 + /* ... except prior to G80, where the code 150 + * doesn't support such things. 151 + */ 152 + if (disp->disp.oclass < NV50_DISP) 153 + return -EINVAL; 154 + break; 155 + default: 156 + break; 157 + } 158 + case DRM_MODE_SCALE_FULLSCREEN: 159 + case DRM_MODE_SCALE_CENTER: 160 + case DRM_MODE_SCALE_ASPECT: 161 + break; 162 + default: 163 + return -EINVAL; 164 + } 165 + 166 + if (asyc->scaler.mode != val) { 167 + asyc->scaler.mode = val; 168 + asyc->set.scaler = true; 169 + } 170 + } else 171 + if (property == disp->underscan_property) { 172 + if (asyc->scaler.underscan.mode != val) { 173 + asyc->scaler.underscan.mode = val; 174 + asyc->set.scaler = true; 175 + } 176 + } else 177 + if (property == disp->underscan_hborder_property) { 178 + if (asyc->scaler.underscan.hborder != val) { 179 + asyc->scaler.underscan.hborder = val; 180 + asyc->set.scaler = true; 181 + } 182 + } else 183 + if (property == disp->underscan_vborder_property) { 184 + if (asyc->scaler.underscan.vborder != val) { 185 + asyc->scaler.underscan.vborder = val; 186 + asyc->set.scaler = true; 187 + } 188 + } else 189 + if (property == disp->dithering_mode) { 190 + if (asyc->dither.mode != val) { 191 + asyc->dither.mode = val; 192 + asyc->set.dither = true; 193 + } 194 + } else 195 + if (property == disp->dithering_depth) { 196 + if (asyc->dither.mode != val) { 197 + asyc->dither.depth = val; 198 + asyc->set.dither = true; 199 + } 200 + } else 201 + if (property == disp->vibrant_hue_property) { 202 + if (asyc->procamp.vibrant_hue != val) { 203 + asyc->procamp.vibrant_hue = val; 204 + asyc->set.procamp = true; 205 + } 206 + } else 207 + if (property == disp->color_vibrance_property) { 208 + if (asyc->procamp.color_vibrance != val) { 209 + asyc->procamp.color_vibrance = val; 210 + asyc->set.procamp = true; 211 + } 212 + } else { 213 + return -EINVAL; 214 + } 215 + 216 + return 0; 217 + } 218 + 219 + void 220 + nouveau_conn_atomic_destroy_state(struct drm_connector *connector, 221 + struct drm_connector_state *state) 222 + { 223 + struct nouveau_conn_atom *asyc = nouveau_conn_atom(state); 224 + __drm_atomic_helper_connector_destroy_state(&asyc->state); 225 + kfree(asyc); 226 + } 227 + 228 + struct drm_connector_state * 229 + nouveau_conn_atomic_duplicate_state(struct drm_connector *connector) 230 + { 231 + struct nouveau_conn_atom *armc = nouveau_conn_atom(connector->state); 232 + struct nouveau_conn_atom *asyc; 233 + if (!(asyc = kmalloc(sizeof(*asyc), GFP_KERNEL))) 234 + return NULL; 235 + __drm_atomic_helper_connector_duplicate_state(connector, &asyc->state); 236 + asyc->dither = armc->dither; 237 + asyc->scaler = armc->scaler; 238 + asyc->procamp = armc->procamp; 239 + asyc->set.mask = 0; 240 + return &asyc->state; 241 + } 242 + 243 + void 244 + nouveau_conn_reset(struct drm_connector *connector) 245 + { 246 + struct nouveau_conn_atom *asyc; 247 + 248 + if (WARN_ON(!(asyc = kzalloc(sizeof(*asyc), GFP_KERNEL)))) 249 + return; 250 + 251 + if (connector->state) 252 + __drm_atomic_helper_connector_destroy_state(connector->state); 253 + __drm_atomic_helper_connector_reset(connector, &asyc->state); 254 + asyc->dither.mode = DITHERING_MODE_AUTO; 255 + asyc->dither.depth = DITHERING_DEPTH_AUTO; 256 + asyc->scaler.mode = DRM_MODE_SCALE_NONE; 257 + asyc->scaler.underscan.mode = UNDERSCAN_OFF; 258 + asyc->procamp.color_vibrance = 150; 259 + asyc->procamp.vibrant_hue = 90; 260 + 261 + if (nouveau_display(connector->dev)->disp.oclass < NV50_DISP) { 262 + switch (connector->connector_type) { 263 + case DRM_MODE_CONNECTOR_LVDS: 264 + /* See note in nouveau_conn_atomic_set_property(). */ 265 + asyc->scaler.mode = DRM_MODE_SCALE_FULLSCREEN; 266 + break; 267 + default: 268 + break; 269 + } 270 + } 271 + } 272 + 273 + void 274 + nouveau_conn_attach_properties(struct drm_connector *connector) 275 + { 276 + struct drm_device *dev = connector->dev; 277 + struct nouveau_conn_atom *armc = nouveau_conn_atom(connector->state); 278 + struct nouveau_display *disp = nouveau_display(dev); 279 + 280 + /* Init DVI-I specific properties. */ 281 + if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) 282 + drm_object_attach_property(&connector->base, dev->mode_config. 283 + dvi_i_subconnector_property, 0); 284 + 285 + /* Add overscan compensation options to digital outputs. */ 286 + if (disp->underscan_property && 287 + (connector->connector_type == DRM_MODE_CONNECTOR_DVID || 288 + connector->connector_type == DRM_MODE_CONNECTOR_DVII || 289 + connector->connector_type == DRM_MODE_CONNECTOR_HDMIA || 290 + connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort)) { 291 + drm_object_attach_property(&connector->base, 292 + disp->underscan_property, 293 + UNDERSCAN_OFF); 294 + drm_object_attach_property(&connector->base, 295 + disp->underscan_hborder_property, 0); 296 + drm_object_attach_property(&connector->base, 297 + disp->underscan_vborder_property, 0); 298 + } 299 + 300 + /* Add hue and saturation options. */ 301 + if (disp->vibrant_hue_property) 302 + drm_object_attach_property(&connector->base, 303 + disp->vibrant_hue_property, 304 + armc->procamp.vibrant_hue); 305 + if (disp->color_vibrance_property) 306 + drm_object_attach_property(&connector->base, 307 + disp->color_vibrance_property, 308 + armc->procamp.color_vibrance); 309 + 310 + /* Scaling mode property. */ 311 + switch (connector->connector_type) { 312 + case DRM_MODE_CONNECTOR_TV: 313 + break; 314 + case DRM_MODE_CONNECTOR_VGA: 315 + if (disp->disp.oclass < NV50_DISP) 316 + break; /* Can only scale on DFPs. */ 317 + /* Fall-through. */ 318 + default: 319 + drm_object_attach_property(&connector->base, dev->mode_config. 320 + scaling_mode_property, 321 + armc->scaler.mode); 322 + break; 323 + } 324 + 325 + /* Dithering properties. */ 326 + switch (connector->connector_type) { 327 + case DRM_MODE_CONNECTOR_TV: 328 + case DRM_MODE_CONNECTOR_VGA: 329 + break; 330 + default: 331 + if (disp->dithering_mode) { 332 + drm_object_attach_property(&connector->base, 333 + disp->dithering_mode, 334 + armc->dither.mode); 335 + } 336 + if (disp->dithering_depth) { 337 + drm_object_attach_property(&connector->base, 338 + disp->dithering_depth, 339 + armc->dither.depth); 340 + } 341 + break; 342 + } 343 + } 50 344 51 345 MODULE_PARM_DESC(tv_disable, "Disable TV-out detection"); 52 346 int nouveau_tv_disable = 0; ··· 447 151 448 152 if (nv_encoder->dcb->type == DCB_OUTPUT_DP) { 449 153 int ret = nouveau_dp_detect(nv_encoder); 450 - if (ret == 0) 154 + if (ret == NOUVEAU_DP_MST) 155 + return NULL; 156 + if (ret == NOUVEAU_DP_SST) 451 157 break; 452 158 } else 453 159 if ((vga_switcheroo_handler_flags() & ··· 763 465 nouveau_connector_set_property(struct drm_connector *connector, 764 466 struct drm_property *property, uint64_t value) 765 467 { 766 - struct nouveau_display *disp = nouveau_display(connector->dev); 468 + struct nouveau_conn_atom *asyc = nouveau_conn_atom(connector->state); 767 469 struct nouveau_connector *nv_connector = nouveau_connector(connector); 768 470 struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; 769 471 struct drm_encoder *encoder = to_drm_encoder(nv_encoder); 770 - struct drm_device *dev = connector->dev; 771 - struct nouveau_crtc *nv_crtc; 772 472 int ret; 773 473 774 - nv_crtc = NULL; 775 - if (connector->encoder && connector->encoder->crtc) 776 - nv_crtc = nouveau_crtc(connector->encoder->crtc); 474 + if (connector->dev->mode_config.funcs->atomic_commit) 475 + return drm_atomic_helper_connector_set_property(connector, property, value); 777 476 778 - /* Scaling mode */ 779 - if (property == dev->mode_config.scaling_mode_property) { 780 - bool modeset = false; 477 + ret = connector->funcs->atomic_set_property(&nv_connector->base, 478 + &asyc->state, 479 + property, value); 480 + if (ret) { 481 + if (nv_encoder && nv_encoder->dcb->type == DCB_OUTPUT_TV) 482 + return get_slave_funcs(encoder)->set_property( 483 + encoder, connector, property, value); 484 + return ret; 485 + } 781 486 782 - switch (value) { 783 - case DRM_MODE_SCALE_NONE: 784 - /* We allow 'None' for EDID modes, even on a fixed 785 - * panel (some exist with support for lower refresh 786 - * rates, which people might want to use for power 787 - * saving purposes). 788 - * 789 - * Non-EDID modes will force the use of GPU scaling 790 - * to the native mode regardless of this setting. 791 - */ 792 - switch (nv_connector->type) { 793 - case DCB_CONNECTOR_LVDS: 794 - case DCB_CONNECTOR_LVDS_SPWG: 795 - case DCB_CONNECTOR_eDP: 796 - /* ... except prior to G80, where the code 797 - * doesn't support such things. 798 - */ 799 - if (disp->disp.oclass < NV50_DISP) 800 - return -EINVAL; 801 - break; 802 - default: 803 - break; 804 - } 805 - break; 806 - case DRM_MODE_SCALE_FULLSCREEN: 807 - case DRM_MODE_SCALE_CENTER: 808 - case DRM_MODE_SCALE_ASPECT: 809 - break; 810 - default: 487 + nv_connector->scaling_mode = asyc->scaler.mode; 488 + nv_connector->dithering_mode = asyc->dither.mode; 489 + 490 + if (connector->encoder && connector->encoder->crtc) { 491 + ret = drm_crtc_helper_set_mode(connector->encoder->crtc, 492 + &connector->encoder->crtc->mode, 493 + connector->encoder->crtc->x, 494 + connector->encoder->crtc->y, 495 + NULL); 496 + if (!ret) 811 497 return -EINVAL; 812 - } 813 - 814 - /* Changing between GPU and panel scaling requires a full 815 - * modeset 816 - */ 817 - if ((nv_connector->scaling_mode == DRM_MODE_SCALE_NONE) || 818 - (value == DRM_MODE_SCALE_NONE)) 819 - modeset = true; 820 - nv_connector->scaling_mode = value; 821 - 822 - if (!nv_crtc) 823 - return 0; 824 - 825 - if (modeset || !nv_crtc->set_scale) { 826 - ret = drm_crtc_helper_set_mode(&nv_crtc->base, 827 - &nv_crtc->base.mode, 828 - nv_crtc->base.x, 829 - nv_crtc->base.y, NULL); 830 - if (!ret) 831 - return -EINVAL; 832 - } else { 833 - ret = nv_crtc->set_scale(nv_crtc, true); 834 - if (ret) 835 - return ret; 836 - } 837 - 838 - return 0; 839 498 } 840 499 841 - /* Underscan */ 842 - if (property == disp->underscan_property) { 843 - if (nv_connector->underscan != value) { 844 - nv_connector->underscan = value; 845 - if (!nv_crtc || !nv_crtc->set_scale) 846 - return 0; 847 - 848 - return nv_crtc->set_scale(nv_crtc, true); 849 - } 850 - 851 - return 0; 852 - } 853 - 854 - if (property == disp->underscan_hborder_property) { 855 - if (nv_connector->underscan_hborder != value) { 856 - nv_connector->underscan_hborder = value; 857 - if (!nv_crtc || !nv_crtc->set_scale) 858 - return 0; 859 - 860 - return nv_crtc->set_scale(nv_crtc, true); 861 - } 862 - 863 - return 0; 864 - } 865 - 866 - if (property == disp->underscan_vborder_property) { 867 - if (nv_connector->underscan_vborder != value) { 868 - nv_connector->underscan_vborder = value; 869 - if (!nv_crtc || !nv_crtc->set_scale) 870 - return 0; 871 - 872 - return nv_crtc->set_scale(nv_crtc, true); 873 - } 874 - 875 - return 0; 876 - } 877 - 878 - /* Dithering */ 879 - if (property == disp->dithering_mode) { 880 - nv_connector->dithering_mode = value; 881 - if (!nv_crtc || !nv_crtc->set_dither) 882 - return 0; 883 - 884 - return nv_crtc->set_dither(nv_crtc, true); 885 - } 886 - 887 - if (property == disp->dithering_depth) { 888 - nv_connector->dithering_depth = value; 889 - if (!nv_crtc || !nv_crtc->set_dither) 890 - return 0; 891 - 892 - return nv_crtc->set_dither(nv_crtc, true); 893 - } 894 - 895 - if (nv_crtc && nv_crtc->set_color_vibrance) { 896 - /* Hue */ 897 - if (property == disp->vibrant_hue_property) { 898 - nv_crtc->vibrant_hue = value - 90; 899 - return nv_crtc->set_color_vibrance(nv_crtc, true); 900 - } 901 - /* Saturation */ 902 - if (property == disp->color_vibrance_property) { 903 - nv_crtc->color_vibrance = value - 100; 904 - return nv_crtc->set_color_vibrance(nv_crtc, true); 905 - } 906 - } 907 - 908 - if (nv_encoder && nv_encoder->dcb->type == DCB_OUTPUT_TV) 909 - return get_slave_funcs(encoder)->set_property( 910 - encoder, connector, property, value); 911 - 912 - return -EINVAL; 913 - } 914 - 915 - static struct drm_display_mode * 916 - nouveau_connector_native_mode(struct drm_connector *connector) 917 - { 918 - const struct drm_connector_helper_funcs *helper = connector->helper_private; 919 - struct nouveau_drm *drm = nouveau_drm(connector->dev); 920 - struct nouveau_connector *nv_connector = nouveau_connector(connector); 921 - struct drm_device *dev = connector->dev; 922 - struct drm_display_mode *mode, *largest = NULL; 923 - int high_w = 0, high_h = 0, high_v = 0; 924 - 925 - list_for_each_entry(mode, &nv_connector->base.probed_modes, head) { 926 - mode->vrefresh = drm_mode_vrefresh(mode); 927 - if (helper->mode_valid(connector, mode) != MODE_OK || 928 - (mode->flags & DRM_MODE_FLAG_INTERLACE)) 929 - continue; 930 - 931 - /* Use preferred mode if there is one.. */ 932 - if (mode->type & DRM_MODE_TYPE_PREFERRED) { 933 - NV_DEBUG(drm, "native mode from preferred\n"); 934 - return drm_mode_duplicate(dev, mode); 935 - } 936 - 937 - /* Otherwise, take the resolution with the largest width, then 938 - * height, then vertical refresh 939 - */ 940 - if (mode->hdisplay < high_w) 941 - continue; 942 - 943 - if (mode->hdisplay == high_w && mode->vdisplay < high_h) 944 - continue; 945 - 946 - if (mode->hdisplay == high_w && mode->vdisplay == high_h && 947 - mode->vrefresh < high_v) 948 - continue; 949 - 950 - high_w = mode->hdisplay; 951 - high_h = mode->vdisplay; 952 - high_v = mode->vrefresh; 953 - largest = mode; 954 - } 955 - 956 - NV_DEBUG(drm, "native mode from largest: %dx%d@%d\n", 957 - high_w, high_h, high_v); 958 - return largest ? drm_mode_duplicate(dev, largest) : NULL; 500 + return 0; 959 501 } 960 502 961 503 struct moderec { ··· 943 805 * the list of modes. 944 806 */ 945 807 if (!nv_connector->native_mode) 946 - nv_connector->native_mode = 947 - nouveau_connector_native_mode(connector); 808 + nv_connector->native_mode = nouveau_conn_native_mode(connector); 948 809 if (ret == 0 && nv_connector->native_mode) { 949 810 struct drm_display_mode *mode; 950 811 ··· 1071 934 .best_encoder = nouveau_connector_best_encoder, 1072 935 }; 1073 936 1074 - static const struct drm_connector_funcs 1075 - nouveau_connector_funcs = { 1076 - .dpms = drm_helper_connector_dpms, 1077 - .detect = nouveau_connector_detect, 1078 - .destroy = nouveau_connector_destroy, 1079 - .fill_modes = drm_helper_probe_single_connector_modes, 1080 - .set_property = nouveau_connector_set_property, 1081 - .force = nouveau_connector_force 1082 - }; 1083 - 1084 - static const struct drm_connector_funcs 1085 - nouveau_connector_funcs_lvds = { 1086 - .dpms = drm_helper_connector_dpms, 1087 - .detect = nouveau_connector_detect_lvds, 1088 - .destroy = nouveau_connector_destroy, 1089 - .fill_modes = drm_helper_probe_single_connector_modes, 1090 - .set_property = nouveau_connector_set_property, 1091 - .force = nouveau_connector_force 1092 - }; 1093 - 1094 937 static int 1095 - nouveau_connector_dp_dpms(struct drm_connector *connector, int mode) 938 + nouveau_connector_dpms(struct drm_connector *connector, int mode) 1096 939 { 1097 - struct nouveau_encoder *nv_encoder = NULL; 1098 - 1099 - if (connector->encoder) 1100 - nv_encoder = nouveau_encoder(connector->encoder); 1101 - if (nv_encoder && nv_encoder->dcb && 1102 - nv_encoder->dcb->type == DCB_OUTPUT_DP) { 1103 - if (mode == DRM_MODE_DPMS_ON) { 1104 - u8 data = DP_SET_POWER_D0; 1105 - nvkm_wraux(nv_encoder->aux, DP_SET_POWER, &data, 1); 1106 - usleep_range(1000, 2000); 1107 - } else { 1108 - u8 data = DP_SET_POWER_D3; 1109 - nvkm_wraux(nv_encoder->aux, DP_SET_POWER, &data, 1); 1110 - } 1111 - } 1112 - 940 + if (connector->dev->mode_config.funcs->atomic_commit) 941 + return drm_atomic_helper_connector_dpms(connector, mode); 1113 942 return drm_helper_connector_dpms(connector, mode); 1114 943 } 1115 944 1116 945 static const struct drm_connector_funcs 1117 - nouveau_connector_funcs_dp = { 1118 - .dpms = nouveau_connector_dp_dpms, 946 + nouveau_connector_funcs = { 947 + .dpms = nouveau_connector_dpms, 948 + .reset = nouveau_conn_reset, 1119 949 .detect = nouveau_connector_detect, 1120 - .destroy = nouveau_connector_destroy, 950 + .force = nouveau_connector_force, 1121 951 .fill_modes = drm_helper_probe_single_connector_modes, 1122 952 .set_property = nouveau_connector_set_property, 1123 - .force = nouveau_connector_force 953 + .destroy = nouveau_connector_destroy, 954 + .atomic_duplicate_state = nouveau_conn_atomic_duplicate_state, 955 + .atomic_destroy_state = nouveau_conn_atomic_destroy_state, 956 + .atomic_set_property = nouveau_conn_atomic_set_property, 957 + .atomic_get_property = nouveau_conn_atomic_get_property, 958 + }; 959 + 960 + static const struct drm_connector_funcs 961 + nouveau_connector_funcs_lvds = { 962 + .dpms = nouveau_connector_dpms, 963 + .reset = nouveau_conn_reset, 964 + .detect = nouveau_connector_detect_lvds, 965 + .force = nouveau_connector_force, 966 + .fill_modes = drm_helper_probe_single_connector_modes, 967 + .set_property = nouveau_connector_set_property, 968 + .destroy = nouveau_connector_destroy, 969 + .atomic_duplicate_state = nouveau_conn_atomic_duplicate_state, 970 + .atomic_destroy_state = nouveau_conn_atomic_destroy_state, 971 + .atomic_set_property = nouveau_conn_atomic_set_property, 972 + .atomic_get_property = nouveau_conn_atomic_get_property, 1124 973 }; 1125 974 1126 975 static int ··· 1118 995 struct nouveau_drm *drm = nouveau_drm(connector->dev); 1119 996 const struct nvif_notify_conn_rep_v0 *rep = notify->data; 1120 997 const char *name = connector->name; 998 + struct nouveau_encoder *nv_encoder; 1121 999 1122 1000 if (rep->mask & NVIF_NOTIFY_CONN_V0_IRQ) { 1001 + NV_DEBUG(drm, "service %s\n", name); 1002 + if ((nv_encoder = find_encoder(connector, DCB_OUTPUT_DP))) 1003 + nv50_mstm_service(nv_encoder->dp.mstm); 1123 1004 } else { 1124 1005 bool plugged = (rep->mask != NVIF_NOTIFY_CONN_V0_UNPLUG); 1125 1006 1126 1007 NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un", name); 1127 - 1128 - mutex_lock(&drm->dev->mode_config.mutex); 1129 - if (plugged) 1130 - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON); 1131 - else 1132 - drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF); 1133 - mutex_unlock(&drm->dev->mode_config.mutex); 1008 + if ((nv_encoder = find_encoder(connector, DCB_OUTPUT_DP))) { 1009 + if (!plugged) 1010 + nv50_mstm_remove(nv_encoder->dp.mstm); 1011 + } 1134 1012 1135 1013 drm_helper_hpd_irq_event(connector->dev); 1136 1014 } ··· 1312 1188 return ERR_PTR(ret); 1313 1189 } 1314 1190 1315 - funcs = &nouveau_connector_funcs_dp; 1191 + funcs = &nouveau_connector_funcs; 1316 1192 break; 1317 1193 default: 1318 1194 funcs = &nouveau_connector_funcs; ··· 1326 1202 drm_connector_init(dev, connector, funcs, type); 1327 1203 drm_connector_helper_add(connector, &nouveau_connector_helper_funcs); 1328 1204 1329 - /* Init DVI-I specific properties */ 1330 - if (nv_connector->type == DCB_CONNECTOR_DVI_I) 1331 - drm_object_attach_property(&connector->base, dev->mode_config.dvi_i_subconnector_property, 0); 1205 + connector->funcs->reset(connector); 1206 + nouveau_conn_attach_properties(connector); 1332 1207 1333 - /* Add overscan compensation options to digital outputs */ 1334 - if (disp->underscan_property && 1335 - (type == DRM_MODE_CONNECTOR_DVID || 1336 - type == DRM_MODE_CONNECTOR_DVII || 1337 - type == DRM_MODE_CONNECTOR_HDMIA || 1338 - type == DRM_MODE_CONNECTOR_DisplayPort)) { 1339 - drm_object_attach_property(&connector->base, 1340 - disp->underscan_property, 1341 - UNDERSCAN_OFF); 1342 - drm_object_attach_property(&connector->base, 1343 - disp->underscan_hborder_property, 1344 - 0); 1345 - drm_object_attach_property(&connector->base, 1346 - disp->underscan_vborder_property, 1347 - 0); 1348 - } 1349 - 1350 - /* Add hue and saturation options */ 1351 - if (disp->vibrant_hue_property) 1352 - drm_object_attach_property(&connector->base, 1353 - disp->vibrant_hue_property, 1354 - 90); 1355 - if (disp->color_vibrance_property) 1356 - drm_object_attach_property(&connector->base, 1357 - disp->color_vibrance_property, 1358 - 150); 1359 - 1360 - /* default scaling mode */ 1208 + /* Default scaling mode */ 1361 1209 switch (nv_connector->type) { 1362 1210 case DCB_CONNECTOR_LVDS: 1363 1211 case DCB_CONNECTOR_LVDS_SPWG: ··· 1346 1250 break; 1347 1251 } 1348 1252 1349 - /* scaling mode property */ 1350 - switch (nv_connector->type) { 1351 - case DCB_CONNECTOR_TV_0: 1352 - case DCB_CONNECTOR_TV_1: 1353 - case DCB_CONNECTOR_TV_3: 1354 - break; 1355 - case DCB_CONNECTOR_VGA: 1356 - if (disp->disp.oclass < NV50_DISP) 1357 - break; /* can only scale on DFPs */ 1358 - /* fall-through */ 1359 - default: 1360 - drm_object_attach_property(&connector->base, dev->mode_config. 1361 - scaling_mode_property, 1362 - nv_connector->scaling_mode); 1363 - break; 1364 - } 1365 - 1366 1253 /* dithering properties */ 1367 1254 switch (nv_connector->type) { 1368 1255 case DCB_CONNECTOR_TV_0: ··· 1354 1275 case DCB_CONNECTOR_VGA: 1355 1276 break; 1356 1277 default: 1357 - if (disp->dithering_mode) { 1358 - nv_connector->dithering_mode = DITHERING_MODE_AUTO; 1359 - drm_object_attach_property(&connector->base, 1360 - disp->dithering_mode, 1361 - nv_connector-> 1362 - dithering_mode); 1363 - } 1364 - if (disp->dithering_depth) { 1365 - nv_connector->dithering_depth = DITHERING_DEPTH_AUTO; 1366 - drm_object_attach_property(&connector->base, 1367 - disp->dithering_depth, 1368 - nv_connector-> 1369 - dithering_depth); 1370 - } 1278 + nv_connector->dithering_mode = DITHERING_MODE_AUTO; 1371 1279 break; 1372 1280 } 1373 1281
+69 -29
drivers/gpu/drm/nouveau/nouveau_connector.h
··· 35 35 36 36 struct nvkm_i2c_port; 37 37 38 - enum nouveau_underscan_type { 39 - UNDERSCAN_OFF, 40 - UNDERSCAN_ON, 41 - UNDERSCAN_AUTO, 42 - }; 43 - 44 - /* the enum values specifically defined here match nv50/nvd0 hw values, and 45 - * the code relies on this 46 - */ 47 - enum nouveau_dithering_mode { 48 - DITHERING_MODE_OFF = 0x00, 49 - DITHERING_MODE_ON = 0x01, 50 - DITHERING_MODE_DYNAMIC2X2 = 0x10 | DITHERING_MODE_ON, 51 - DITHERING_MODE_STATIC2X2 = 0x18 | DITHERING_MODE_ON, 52 - DITHERING_MODE_TEMPORAL = 0x20 | DITHERING_MODE_ON, 53 - DITHERING_MODE_AUTO 54 - }; 55 - 56 - enum nouveau_dithering_depth { 57 - DITHERING_DEPTH_6BPC = 0x00, 58 - DITHERING_DEPTH_8BPC = 0x02, 59 - DITHERING_DEPTH_AUTO 60 - }; 61 - 62 38 struct nouveau_connector { 63 39 struct drm_connector base; 64 40 enum dcb_connector_type type; ··· 46 70 struct drm_dp_aux aux; 47 71 48 72 int dithering_mode; 49 - int dithering_depth; 50 73 int scaling_mode; 51 - bool scaling_full; 52 - enum nouveau_underscan_type underscan; 53 - u32 underscan_hborder; 54 - u32 underscan_vborder; 55 74 56 75 struct nouveau_encoder *detected_encoder; 57 76 struct edid *edid; ··· 80 109 extern int nouveau_tv_disable; 81 110 extern int nouveau_ignorelid; 82 111 extern int nouveau_duallink; 112 + extern int nouveau_hdmimhz; 83 113 114 + #include <drm/drm_crtc.h> 115 + #define nouveau_conn_atom(p) \ 116 + container_of((p), struct nouveau_conn_atom, state) 117 + 118 + struct nouveau_conn_atom { 119 + struct drm_connector_state state; 120 + 121 + struct { 122 + /* The enum values specifically defined here match nv50/gf119 123 + * hw values, and the code relies on this. 124 + */ 125 + enum { 126 + DITHERING_MODE_OFF = 0x00, 127 + DITHERING_MODE_ON = 0x01, 128 + DITHERING_MODE_DYNAMIC2X2 = 0x10 | DITHERING_MODE_ON, 129 + DITHERING_MODE_STATIC2X2 = 0x18 | DITHERING_MODE_ON, 130 + DITHERING_MODE_TEMPORAL = 0x20 | DITHERING_MODE_ON, 131 + DITHERING_MODE_AUTO 132 + } mode; 133 + enum { 134 + DITHERING_DEPTH_6BPC = 0x00, 135 + DITHERING_DEPTH_8BPC = 0x02, 136 + DITHERING_DEPTH_AUTO 137 + } depth; 138 + } dither; 139 + 140 + struct { 141 + int mode; /* DRM_MODE_SCALE_* */ 142 + struct { 143 + enum { 144 + UNDERSCAN_OFF, 145 + UNDERSCAN_ON, 146 + UNDERSCAN_AUTO, 147 + } mode; 148 + u32 hborder; 149 + u32 vborder; 150 + } underscan; 151 + bool full; 152 + } scaler; 153 + 154 + struct { 155 + int color_vibrance; 156 + int vibrant_hue; 157 + } procamp; 158 + 159 + union { 160 + struct { 161 + bool dither:1; 162 + bool scaler:1; 163 + bool procamp:1; 164 + }; 165 + u8 mask; 166 + } set; 167 + }; 168 + 169 + void nouveau_conn_attach_properties(struct drm_connector *); 170 + void nouveau_conn_reset(struct drm_connector *); 171 + struct drm_connector_state * 172 + nouveau_conn_atomic_duplicate_state(struct drm_connector *); 173 + void nouveau_conn_atomic_destroy_state(struct drm_connector *, 174 + struct drm_connector_state *); 175 + int nouveau_conn_atomic_set_property(struct drm_connector *, 176 + struct drm_connector_state *, 177 + struct drm_property *, u64); 178 + int nouveau_conn_atomic_get_property(struct drm_connector *, 179 + const struct drm_connector_state *, 180 + struct drm_property *, u64 *); 181 + struct drm_display_mode *nouveau_conn_native_mode(struct drm_connector *); 84 182 #endif /* __NOUVEAU_CONNECTOR_H__ */
-7
drivers/gpu/drm/nouveau/nouveau_crtc.h
··· 38 38 uint32_t dpms_saved_fp_control; 39 39 uint32_t fp_users; 40 40 int saturation; 41 - int color_vibrance; 42 - int vibrant_hue; 43 41 int sharpness; 44 42 int last_dpms; 45 43 ··· 52 54 53 55 struct { 54 56 struct nouveau_bo *nvbo; 55 - bool visible; 56 57 uint32_t offset; 57 58 void (*set_offset)(struct nouveau_crtc *, uint32_t offset); 58 59 void (*set_pos)(struct nouveau_crtc *, int x, int y); ··· 66 69 uint16_t b[256]; 67 70 int depth; 68 71 } lut; 69 - 70 - int (*set_dither)(struct nouveau_crtc *crtc, bool update); 71 - int (*set_scale)(struct nouveau_crtc *crtc, bool update); 72 - int (*set_color_vibrance)(struct nouveau_crtc *crtc, bool update); 73 72 74 73 void (*save)(struct drm_crtc *crtc); 75 74 void (*restore)(struct drm_crtc *crtc);
+193 -83
drivers/gpu/drm/nouveau/nouveau_display.c
··· 25 25 */ 26 26 27 27 #include <drm/drmP.h> 28 + #include <drm/drm_atomic.h> 29 + #include <drm/drm_atomic_helper.h> 28 30 #include <drm/drm_crtc_helper.h> 29 31 30 32 #include <nvif/class.h> ··· 94 92 return line; 95 93 } 96 94 97 - int 95 + static int 98 96 nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos, 99 97 ktime_t *stime, ktime_t *etime) 100 98 { ··· 160 158 161 159 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 162 160 if (nouveau_crtc(crtc)->index == pipe) { 161 + struct drm_display_mode *mode; 162 + if (dev->mode_config.funcs->atomic_commit) 163 + mode = &crtc->state->adjusted_mode; 164 + else 165 + mode = &crtc->hwmode; 163 166 return drm_calc_vbltimestamp_from_scanoutpos(dev, 164 - pipe, max_error, time, flags, 165 - &crtc->hwmode); 167 + pipe, max_error, time, flags, mode); 166 168 } 167 169 } 168 170 ··· 223 217 nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb) 224 218 { 225 219 struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); 226 - struct nouveau_display *disp = nouveau_display(drm_fb->dev); 227 - 228 - if (disp->fb_dtor) 229 - disp->fb_dtor(drm_fb); 230 220 231 221 if (fb->nvbo) 232 222 drm_gem_object_unreference_unlocked(&fb->nvbo->gem); ··· 247 245 }; 248 246 249 247 int 250 - nouveau_framebuffer_init(struct drm_device *dev, 251 - struct nouveau_framebuffer *nv_fb, 252 - const struct drm_mode_fb_cmd2 *mode_cmd, 253 - struct nouveau_bo *nvbo) 248 + nouveau_framebuffer_new(struct drm_device *dev, 249 + const struct drm_mode_fb_cmd2 *mode_cmd, 250 + struct nouveau_bo *nvbo, 251 + struct nouveau_framebuffer **pfb) 254 252 { 255 - struct nouveau_display *disp = nouveau_display(dev); 256 - struct drm_framebuffer *fb = &nv_fb->base; 253 + struct nouveau_framebuffer *fb; 257 254 int ret; 258 255 259 - drm_helper_mode_fill_fb_struct(fb, mode_cmd); 260 - nv_fb->nvbo = nvbo; 256 + if (!(fb = *pfb = kzalloc(sizeof(*fb), GFP_KERNEL))) 257 + return -ENOMEM; 261 258 262 - ret = drm_framebuffer_init(dev, fb, &nouveau_framebuffer_funcs); 259 + drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd); 260 + fb->nvbo = nvbo; 261 + 262 + ret = drm_framebuffer_init(dev, &fb->base, &nouveau_framebuffer_funcs); 263 263 if (ret) 264 - return ret; 265 - 266 - if (disp->fb_ctor) { 267 - ret = disp->fb_ctor(fb); 268 - if (ret) 269 - disp->fb_dtor(fb); 270 - } 271 - 264 + kfree(fb); 272 265 return ret; 273 266 } 274 267 275 - static struct drm_framebuffer * 268 + struct drm_framebuffer * 276 269 nouveau_user_framebuffer_create(struct drm_device *dev, 277 270 struct drm_file *file_priv, 278 271 const struct drm_mode_fb_cmd2 *mode_cmd) 279 272 { 280 - struct nouveau_framebuffer *nouveau_fb; 273 + struct nouveau_framebuffer *fb; 274 + struct nouveau_bo *nvbo; 281 275 struct drm_gem_object *gem; 282 - int ret = -ENOMEM; 276 + int ret; 283 277 284 278 gem = drm_gem_object_lookup(file_priv, mode_cmd->handles[0]); 285 279 if (!gem) 286 280 return ERR_PTR(-ENOENT); 281 + nvbo = nouveau_gem_object(gem); 287 282 288 - nouveau_fb = kzalloc(sizeof(struct nouveau_framebuffer), GFP_KERNEL); 289 - if (!nouveau_fb) 290 - goto err_unref; 283 + ret = nouveau_framebuffer_new(dev, mode_cmd, nvbo, &fb); 284 + if (ret == 0) 285 + return &fb->base; 291 286 292 - ret = nouveau_framebuffer_init(dev, nouveau_fb, mode_cmd, nouveau_gem_object(gem)); 293 - if (ret) 294 - goto err; 295 - 296 - return &nouveau_fb->base; 297 - 298 - err: 299 - kfree(nouveau_fb); 300 - err_unref: 301 287 drm_gem_object_unreference_unlocked(gem); 302 288 return ERR_PTR(ret); 303 289 } ··· 375 385 } 376 386 377 387 void 378 - nouveau_display_fini(struct drm_device *dev) 388 + nouveau_display_fini(struct drm_device *dev, bool suspend) 379 389 { 380 390 struct nouveau_display *disp = nouveau_display(dev); 381 391 struct nouveau_drm *drm = nouveau_drm(dev); 382 392 struct drm_connector *connector; 383 393 int head; 394 + 395 + if (!suspend) 396 + drm_crtc_force_disable_all(dev); 384 397 385 398 /* Make sure that drm and hw vblank irqs get properly disabled. */ 386 399 for (head = 0; head < dev->mode_config.num_crtc; head++) ··· 523 530 if (ret) 524 531 goto disp_create_err; 525 532 533 + drm_mode_config_reset(dev); 534 + 526 535 if (dev->mode_config.num_crtc) { 527 536 ret = nouveau_display_vblank_init(dev); 528 537 if (ret) ··· 551 556 nouveau_display_vblank_fini(dev); 552 557 553 558 drm_kms_helper_poll_fini(dev); 554 - drm_crtc_force_disable_all(dev); 555 559 drm_mode_config_cleanup(dev); 556 560 557 561 if (disp->dtor) ··· 562 568 kfree(disp); 563 569 } 564 570 571 + static int 572 + nouveau_atomic_disable_connector(struct drm_atomic_state *state, 573 + struct drm_connector *connector) 574 + { 575 + struct drm_connector_state *connector_state; 576 + struct drm_crtc *crtc; 577 + struct drm_crtc_state *crtc_state; 578 + struct drm_plane_state *plane_state; 579 + struct drm_plane *plane; 580 + int ret; 581 + 582 + if (!(crtc = connector->state->crtc)) 583 + return 0; 584 + 585 + connector_state = drm_atomic_get_connector_state(state, connector); 586 + if (IS_ERR(connector_state)) 587 + return PTR_ERR(connector_state); 588 + 589 + ret = drm_atomic_set_crtc_for_connector(connector_state, NULL); 590 + if (ret) 591 + return ret; 592 + 593 + crtc_state = drm_atomic_get_crtc_state(state, crtc); 594 + if (IS_ERR(crtc_state)) 595 + return PTR_ERR(crtc_state); 596 + 597 + ret = drm_atomic_set_mode_for_crtc(crtc_state, NULL); 598 + if (ret) 599 + return ret; 600 + 601 + crtc_state->active = false; 602 + 603 + drm_for_each_plane_mask(plane, connector->dev, crtc_state->plane_mask) { 604 + plane_state = drm_atomic_get_plane_state(state, plane); 605 + if (IS_ERR(plane_state)) 606 + return PTR_ERR(plane_state); 607 + 608 + ret = drm_atomic_set_crtc_for_plane(plane_state, NULL); 609 + if (ret) 610 + return ret; 611 + 612 + drm_atomic_set_fb_for_plane(plane_state, NULL); 613 + } 614 + 615 + return 0; 616 + } 617 + 618 + static int 619 + nouveau_atomic_disable(struct drm_device *dev, 620 + struct drm_modeset_acquire_ctx *ctx) 621 + { 622 + struct drm_atomic_state *state; 623 + struct drm_connector *connector; 624 + int ret; 625 + 626 + state = drm_atomic_state_alloc(dev); 627 + if (!state) 628 + return -ENOMEM; 629 + 630 + state->acquire_ctx = ctx; 631 + 632 + drm_for_each_connector(connector, dev) { 633 + ret = nouveau_atomic_disable_connector(state, connector); 634 + if (ret) 635 + break; 636 + } 637 + 638 + if (ret == 0) 639 + ret = drm_atomic_commit(state); 640 + drm_atomic_state_put(state); 641 + return ret; 642 + } 643 + 644 + static struct drm_atomic_state * 645 + nouveau_atomic_suspend(struct drm_device *dev) 646 + { 647 + struct drm_modeset_acquire_ctx ctx; 648 + struct drm_atomic_state *state; 649 + int ret; 650 + 651 + drm_modeset_acquire_init(&ctx, 0); 652 + 653 + retry: 654 + ret = drm_modeset_lock_all_ctx(dev, &ctx); 655 + if (ret < 0) { 656 + state = ERR_PTR(ret); 657 + goto unlock; 658 + } 659 + 660 + state = drm_atomic_helper_duplicate_state(dev, &ctx); 661 + if (IS_ERR(state)) 662 + goto unlock; 663 + 664 + ret = nouveau_atomic_disable(dev, &ctx); 665 + if (ret < 0) { 666 + drm_atomic_state_put(state); 667 + state = ERR_PTR(ret); 668 + goto unlock; 669 + } 670 + 671 + unlock: 672 + if (PTR_ERR(state) == -EDEADLK) { 673 + drm_modeset_backoff(&ctx); 674 + goto retry; 675 + } 676 + 677 + drm_modeset_drop_locks(&ctx); 678 + drm_modeset_acquire_fini(&ctx); 679 + return state; 680 + } 681 + 565 682 int 566 683 nouveau_display_suspend(struct drm_device *dev, bool runtime) 567 684 { 685 + struct nouveau_display *disp = nouveau_display(dev); 568 686 struct drm_crtc *crtc; 569 687 570 - nouveau_display_fini(dev); 688 + if (dev->mode_config.funcs->atomic_commit) { 689 + if (!runtime) { 690 + disp->suspend = nouveau_atomic_suspend(dev); 691 + if (IS_ERR(disp->suspend)) { 692 + int ret = PTR_ERR(disp->suspend); 693 + disp->suspend = NULL; 694 + return ret; 695 + } 696 + } 697 + 698 + nouveau_display_fini(dev, true); 699 + return 0; 700 + } 701 + 702 + nouveau_display_fini(dev, true); 571 703 572 704 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 573 705 struct nouveau_framebuffer *nouveau_fb; ··· 720 600 void 721 601 nouveau_display_resume(struct drm_device *dev, bool runtime) 722 602 { 603 + struct nouveau_display *disp = nouveau_display(dev); 723 604 struct nouveau_drm *drm = nouveau_drm(dev); 724 605 struct drm_crtc *crtc; 725 606 int ret, head; 607 + 608 + if (dev->mode_config.funcs->atomic_commit) { 609 + nouveau_display_init(dev); 610 + if (disp->suspend) { 611 + drm_atomic_helper_resume(dev, disp->suspend); 612 + disp->suspend = NULL; 613 + } 614 + return; 615 + } 726 616 727 617 /* re-pin fb/cursors */ 728 618 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { ··· 822 692 if (ret) 823 693 goto fail; 824 694 825 - if (drm->device.info.family < NV_DEVICE_INFO_V0_FERMI) 826 - BEGIN_NV04(chan, NvSubSw, NV_SW_PAGE_FLIP, 1); 827 - else 828 - BEGIN_NVC0(chan, FermiSw, NV_SW_PAGE_FLIP, 1); 695 + BEGIN_NV04(chan, NvSubSw, NV_SW_PAGE_FLIP, 1); 829 696 OUT_RING (chan, 0x00000000); 830 697 FIRE_RING (chan); 831 698 ··· 851 724 struct nouveau_channel *chan; 852 725 struct nouveau_cli *cli; 853 726 struct nouveau_fence *fence; 727 + struct nv04_display *dispnv04 = nv04_display(dev); 728 + int head = nouveau_crtc(crtc)->index; 854 729 int ret; 855 730 856 731 chan = drm->channel; ··· 899 770 drm_crtc_vblank_get(crtc); 900 771 901 772 /* Emit a page flip */ 902 - if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) { 903 - ret = nv50_display_flip_next(crtc, fb, chan, swap_interval); 773 + if (swap_interval) { 774 + ret = RING_SPACE(chan, 8); 904 775 if (ret) 905 776 goto fail_unreserve; 906 - } else { 907 - struct nv04_display *dispnv04 = nv04_display(dev); 908 - int head = nouveau_crtc(crtc)->index; 909 777 910 - if (swap_interval) { 911 - ret = RING_SPACE(chan, 8); 912 - if (ret) 913 - goto fail_unreserve; 914 - 915 - BEGIN_NV04(chan, NvSubImageBlit, 0x012c, 1); 916 - OUT_RING (chan, 0); 917 - BEGIN_NV04(chan, NvSubImageBlit, 0x0134, 1); 918 - OUT_RING (chan, head); 919 - BEGIN_NV04(chan, NvSubImageBlit, 0x0100, 1); 920 - OUT_RING (chan, 0); 921 - BEGIN_NV04(chan, NvSubImageBlit, 0x0130, 1); 922 - OUT_RING (chan, 0); 923 - } 924 - 925 - nouveau_bo_ref(new_bo, &dispnv04->image[head]); 778 + BEGIN_NV04(chan, NvSubImageBlit, 0x012c, 1); 779 + OUT_RING (chan, 0); 780 + BEGIN_NV04(chan, NvSubImageBlit, 0x0134, 1); 781 + OUT_RING (chan, head); 782 + BEGIN_NV04(chan, NvSubImageBlit, 0x0100, 1); 783 + OUT_RING (chan, 0); 784 + BEGIN_NV04(chan, NvSubImageBlit, 0x0130, 1); 785 + OUT_RING (chan, 0); 926 786 } 787 + 788 + nouveau_bo_ref(new_bo, &dispnv04->image[head]); 927 789 928 790 ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence); 929 791 if (ret) ··· 963 843 964 844 s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head); 965 845 if (s->event) { 966 - if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) { 967 - drm_crtc_arm_vblank_event(s->crtc, s->event); 968 - } else { 969 - drm_crtc_send_vblank_event(s->crtc, s->event); 970 - 971 - /* Give up ownership of vblank for page-flipped crtc */ 972 - drm_crtc_vblank_put(s->crtc); 973 - } 974 - } 975 - else { 846 + drm_crtc_arm_vblank_event(s->crtc, s->event); 847 + } else { 976 848 /* Give up ownership of vblank for page-flipped crtc */ 977 849 drm_crtc_vblank_put(s->crtc); 978 850 } ··· 986 874 struct nouveau_page_flip_state state; 987 875 988 876 if (!nouveau_finish_page_flip(chan, &state)) { 989 - if (drm->device.info.family < NV_DEVICE_INFO_V0_TESLA) { 990 - nv_set_crtc_base(drm->dev, drm_crtc_index(state.crtc), 991 - state.offset + state.crtc->y * 992 - state.pitch + state.crtc->x * 993 - state.bpp / 8); 994 - } 877 + nv_set_crtc_base(drm->dev, drm_crtc_index(state.crtc), 878 + state.offset + state.crtc->y * 879 + state.pitch + state.crtc->x * 880 + state.bpp / 8); 995 881 } 996 882 997 883 return NVIF_NOTIFY_KEEP;
+9 -6
drivers/gpu/drm/nouveau/nouveau_display.h
··· 22 22 return container_of(fb, struct nouveau_framebuffer, base); 23 23 } 24 24 25 - int nouveau_framebuffer_init(struct drm_device *, struct nouveau_framebuffer *, 26 - const struct drm_mode_fb_cmd2 *, struct nouveau_bo *); 25 + int nouveau_framebuffer_new(struct drm_device *, 26 + const struct drm_mode_fb_cmd2 *, 27 + struct nouveau_bo *, struct nouveau_framebuffer **); 27 28 28 29 struct nouveau_page_flip_state { 29 30 struct list_head head; ··· 40 39 int (*init)(struct drm_device *); 41 40 void (*fini)(struct drm_device *); 42 41 43 - int (*fb_ctor)(struct drm_framebuffer *); 44 - void (*fb_dtor)(struct drm_framebuffer *); 45 - 46 42 struct nvif_object disp; 47 43 48 44 struct drm_property *dithering_mode; ··· 50 52 /* not really hue and saturation: */ 51 53 struct drm_property *vibrant_hue_property; 52 54 struct drm_property *color_vibrance_property; 55 + 56 + struct drm_atomic_state *suspend; 53 57 }; 54 58 55 59 static inline struct nouveau_display * ··· 63 63 int nouveau_display_create(struct drm_device *dev); 64 64 void nouveau_display_destroy(struct drm_device *dev); 65 65 int nouveau_display_init(struct drm_device *dev); 66 - void nouveau_display_fini(struct drm_device *dev); 66 + void nouveau_display_fini(struct drm_device *dev, bool suspend); 67 67 int nouveau_display_suspend(struct drm_device *dev, bool runtime); 68 68 void nouveau_display_resume(struct drm_device *dev, bool runtime); 69 69 int nouveau_display_vblank_enable(struct drm_device *, unsigned int); ··· 103 103 } 104 104 #endif 105 105 106 + struct drm_framebuffer * 107 + nouveau_user_framebuffer_create(struct drm_device *, struct drm_file *, 108 + const struct drm_mode_fb_cmd2 *); 106 109 #endif
+16 -3
drivers/gpu/drm/nouveau/nouveau_dp.c
··· 30 30 #include "nouveau_encoder.h" 31 31 #include "nouveau_crtc.h" 32 32 33 + #include <nvif/class.h> 34 + #include <nvif/cl5070.h> 35 + 36 + MODULE_PARM_DESC(mst, "Enable DisplayPort multi-stream (default: enabled)"); 37 + static int nouveau_mst = 1; 38 + module_param_named(mst, nouveau_mst, int, 0400); 39 + 33 40 static void 34 41 nouveau_dp_probe_oui(struct drm_device *dev, struct nvkm_i2c_aux *aux, u8 *dpcd) 35 42 { ··· 62 55 struct drm_device *dev = nv_encoder->base.base.dev; 63 56 struct nouveau_drm *drm = nouveau_drm(dev); 64 57 struct nvkm_i2c_aux *aux; 65 - u8 *dpcd = nv_encoder->dp.dpcd; 58 + u8 dpcd[8]; 66 59 int ret; 67 60 68 61 aux = nv_encoder->aux; 69 62 if (!aux) 70 63 return -ENODEV; 71 64 72 - ret = nvkm_rdaux(aux, DP_DPCD_REV, dpcd, 8); 65 + ret = nvkm_rdaux(aux, DP_DPCD_REV, dpcd, sizeof(dpcd)); 73 66 if (ret) 74 67 return ret; 75 68 ··· 91 84 nv_encoder->dp.link_nr, nv_encoder->dp.link_bw); 92 85 93 86 nouveau_dp_probe_oui(dev, aux, dpcd); 94 - return 0; 87 + 88 + ret = nv50_mstm_detect(nv_encoder->dp.mstm, dpcd, nouveau_mst); 89 + if (ret == 1) 90 + return NOUVEAU_DP_MST; 91 + if (ret == 0) 92 + return NOUVEAU_DP_SST; 93 + return ret; 95 94 }
+2 -1
drivers/gpu/drm/nouveau/nouveau_drm.c
··· 519 519 nouveau_debugfs_fini(drm); 520 520 521 521 if (dev->mode_config.num_crtc) 522 - nouveau_display_fini(dev); 522 + nouveau_display_fini(dev, false); 523 523 nouveau_display_destroy(dev); 524 524 525 525 nouveau_bios_takedown(dev); ··· 1037 1037 DRM_DEBUG_DRIVER("... modeset : %d\n", nouveau_modeset); 1038 1038 DRM_DEBUG_DRIVER("... runpm : %d\n", nouveau_runtime_pm); 1039 1039 DRM_DEBUG_DRIVER("... vram_pushbuf : %d\n", nouveau_vram_pushbuf); 1040 + DRM_DEBUG_DRIVER("... hdmimhz : %d\n", nouveau_hdmimhz); 1040 1041 } 1041 1042 1042 1043 static const struct dev_pm_ops nouveau_pm_ops = {
+4
drivers/gpu/drm/nouveau/nouveau_drv.h
··· 204 204 if (unlikely(drm_debug & DRM_UT_DRIVER)) \ 205 205 NV_PRINTK(info, &(drm)->client, f, ##a); \ 206 206 } while(0) 207 + #define NV_ATOMIC(drm,f,a...) do { \ 208 + if (unlikely(drm_debug & DRM_UT_ATOMIC)) \ 209 + NV_PRINTK(info, &(drm)->client, f, ##a); \ 210 + } while(0) 207 211 208 212 extern int nouveau_modeset; 209 213
+12 -2
drivers/gpu/drm/nouveau/nouveau_encoder.h
··· 30 30 #include <subdev/bios/dcb.h> 31 31 32 32 #include <drm/drm_encoder_slave.h> 33 + #include <drm/drm_dp_mst_helper.h> 33 34 #include "dispnv04/disp.h" 34 35 35 36 #define NV_DPMS_CLEARED 0x80 ··· 58 57 59 58 union { 60 59 struct { 61 - u8 dpcd[8]; 60 + struct nv50_mstm *mstm; 62 61 int link_nr; 63 62 int link_bw; 64 - u32 datarate; 65 63 } dp; 66 64 }; 67 65 68 66 void (*enc_save)(struct drm_encoder *encoder); 69 67 void (*enc_restore)(struct drm_encoder *encoder); 68 + void (*update)(struct nouveau_encoder *, u8 head, 69 + struct drm_display_mode *, u8 proto, u8 depth); 70 70 }; 71 71 72 72 struct nouveau_encoder * ··· 92 90 } 93 91 94 92 /* nouveau_dp.c */ 93 + enum nouveau_dp_status { 94 + NOUVEAU_DP_SST, 95 + NOUVEAU_DP_MST, 96 + }; 97 + 95 98 int nouveau_dp_detect(struct nouveau_encoder *); 96 99 97 100 struct nouveau_connector * 98 101 nouveau_encoder_connector_get(struct nouveau_encoder *encoder); 99 102 103 + int nv50_mstm_detect(struct nv50_mstm *, u8 dpcd[8], int allow); 104 + void nv50_mstm_remove(struct nv50_mstm *); 105 + void nv50_mstm_service(struct nv50_mstm *); 100 106 #endif /* __NOUVEAU_ENCODER_H__ */
+36 -45
drivers/gpu/drm/nouveau/nouveau_fbcon.c
··· 58 58 nouveau_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 59 59 { 60 60 struct nouveau_fbdev *fbcon = info->par; 61 - struct nouveau_drm *drm = nouveau_drm(fbcon->dev); 61 + struct nouveau_drm *drm = nouveau_drm(fbcon->helper.dev); 62 62 struct nvif_device *device = &drm->device; 63 63 int ret; 64 64 ··· 90 90 nouveau_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *image) 91 91 { 92 92 struct nouveau_fbdev *fbcon = info->par; 93 - struct nouveau_drm *drm = nouveau_drm(fbcon->dev); 93 + struct nouveau_drm *drm = nouveau_drm(fbcon->helper.dev); 94 94 struct nvif_device *device = &drm->device; 95 95 int ret; 96 96 ··· 122 122 nouveau_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) 123 123 { 124 124 struct nouveau_fbdev *fbcon = info->par; 125 - struct nouveau_drm *drm = nouveau_drm(fbcon->dev); 125 + struct nouveau_drm *drm = nouveau_drm(fbcon->helper.dev); 126 126 struct nvif_device *device = &drm->device; 127 127 int ret; 128 128 ··· 154 154 nouveau_fbcon_sync(struct fb_info *info) 155 155 { 156 156 struct nouveau_fbdev *fbcon = info->par; 157 - struct nouveau_drm *drm = nouveau_drm(fbcon->dev); 157 + struct nouveau_drm *drm = nouveau_drm(fbcon->helper.dev); 158 158 struct nouveau_channel *chan = drm->channel; 159 159 int ret; 160 160 ··· 181 181 nouveau_fbcon_open(struct fb_info *info, int user) 182 182 { 183 183 struct nouveau_fbdev *fbcon = info->par; 184 - struct nouveau_drm *drm = nouveau_drm(fbcon->dev); 184 + struct nouveau_drm *drm = nouveau_drm(fbcon->helper.dev); 185 185 int ret = pm_runtime_get_sync(drm->dev->dev); 186 186 if (ret < 0 && ret != -EACCES) 187 187 return ret; ··· 192 192 nouveau_fbcon_release(struct fb_info *info, int user) 193 193 { 194 194 struct nouveau_fbdev *fbcon = info->par; 195 - struct nouveau_drm *drm = nouveau_drm(fbcon->dev); 195 + struct nouveau_drm *drm = nouveau_drm(fbcon->helper.dev); 196 196 pm_runtime_put(drm->dev->dev); 197 197 return 0; 198 198 } ··· 333 333 { 334 334 struct nouveau_fbdev *fbcon = 335 335 container_of(helper, struct nouveau_fbdev, helper); 336 - struct drm_device *dev = fbcon->dev; 336 + struct drm_device *dev = fbcon->helper.dev; 337 337 struct nouveau_drm *drm = nouveau_drm(dev); 338 338 struct nvif_device *device = &drm->device; 339 339 struct fb_info *info; 340 - struct drm_framebuffer *fb; 341 - struct nouveau_framebuffer *nouveau_fb; 340 + struct nouveau_framebuffer *fb; 342 341 struct nouveau_channel *chan; 343 342 struct nouveau_bo *nvbo; 344 343 struct drm_mode_fb_cmd2 mode_cmd; 345 - int size, ret; 344 + int ret; 346 345 347 346 mode_cmd.width = sizes->surface_width; 348 347 mode_cmd.height = sizes->surface_height; ··· 352 353 mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp, 353 354 sizes->surface_depth); 354 355 355 - size = mode_cmd.pitches[0] * mode_cmd.height; 356 - size = roundup(size, PAGE_SIZE); 357 - 358 - ret = nouveau_gem_new(dev, size, 0, NOUVEAU_GEM_DOMAIN_VRAM, 359 - 0, 0x0000, &nvbo); 356 + ret = nouveau_gem_new(dev, mode_cmd.pitches[0] * mode_cmd.height, 357 + 0, NOUVEAU_GEM_DOMAIN_VRAM, 0, 0x0000, &nvbo); 360 358 if (ret) { 361 359 NV_ERROR(drm, "failed to allocate framebuffer\n"); 362 360 goto out; 363 361 } 362 + 363 + ret = nouveau_framebuffer_new(dev, &mode_cmd, nvbo, &fb); 364 + if (ret) 365 + goto out_unref; 364 366 365 367 ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM, false); 366 368 if (ret) { ··· 377 377 378 378 chan = nouveau_nofbaccel ? NULL : drm->channel; 379 379 if (chan && device->info.family >= NV_DEVICE_INFO_V0_TESLA) { 380 - ret = nouveau_bo_vma_add(nvbo, drm->client.vm, 381 - &fbcon->nouveau_fb.vma); 380 + ret = nouveau_bo_vma_add(nvbo, drm->client.vm, &fb->vma); 382 381 if (ret) { 383 382 NV_ERROR(drm, "failed to map fb into chan: %d\n", ret); 384 383 chan = NULL; ··· 393 394 394 395 info->par = fbcon; 395 396 396 - nouveau_framebuffer_init(dev, &fbcon->nouveau_fb, &mode_cmd, nvbo); 397 - 398 - nouveau_fb = &fbcon->nouveau_fb; 399 - fb = &nouveau_fb->base; 400 - 401 397 /* setup helper */ 402 - fbcon->helper.fb = fb; 398 + fbcon->helper.fb = &fb->base; 403 399 404 400 strcpy(info->fix.id, "nouveaufb"); 405 401 if (!chan) ··· 405 411 FBINFO_HWACCEL_IMAGEBLIT; 406 412 info->flags |= FBINFO_CAN_FORCE_OUTPUT; 407 413 info->fbops = &nouveau_fbcon_sw_ops; 408 - info->fix.smem_start = nvbo->bo.mem.bus.base + 409 - nvbo->bo.mem.bus.offset; 410 - info->fix.smem_len = size; 414 + info->fix.smem_start = fb->nvbo->bo.mem.bus.base + 415 + fb->nvbo->bo.mem.bus.offset; 416 + info->fix.smem_len = fb->nvbo->bo.mem.num_pages << PAGE_SHIFT; 411 417 412 - info->screen_base = nvbo_kmap_obj_iovirtual(nouveau_fb->nvbo); 413 - info->screen_size = size; 418 + info->screen_base = nvbo_kmap_obj_iovirtual(fb->nvbo); 419 + info->screen_size = fb->nvbo->bo.mem.num_pages << PAGE_SHIFT; 414 420 415 - drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); 421 + drm_fb_helper_fill_fix(info, fb->base.pitches[0], fb->base.depth); 416 422 drm_fb_helper_fill_var(info, &fbcon->helper, sizes->fb_width, sizes->fb_height); 417 423 418 424 /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ ··· 423 429 424 430 /* To allow resizeing without swapping buffers */ 425 431 NV_INFO(drm, "allocated %dx%d fb: 0x%llx, bo %p\n", 426 - nouveau_fb->base.width, nouveau_fb->base.height, 427 - nvbo->bo.offset, nvbo); 432 + fb->base.width, fb->base.height, fb->nvbo->bo.offset, nvbo); 428 433 429 434 vga_switcheroo_client_fb_set(dev->pdev, info); 430 435 return 0; 431 436 432 437 out_unlock: 433 438 if (chan) 434 - nouveau_bo_vma_del(nvbo, &fbcon->nouveau_fb.vma); 435 - nouveau_bo_unmap(nvbo); 439 + nouveau_bo_vma_del(fb->nvbo, &fb->vma); 440 + nouveau_bo_unmap(fb->nvbo); 436 441 out_unpin: 437 - nouveau_bo_unpin(nvbo); 442 + nouveau_bo_unpin(fb->nvbo); 438 443 out_unref: 439 - nouveau_bo_ref(NULL, &nvbo); 444 + nouveau_bo_ref(NULL, &fb->nvbo); 440 445 out: 441 446 return ret; 442 447 } ··· 451 458 static int 452 459 nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *fbcon) 453 460 { 454 - struct nouveau_framebuffer *nouveau_fb = &fbcon->nouveau_fb; 461 + struct nouveau_framebuffer *nouveau_fb = nouveau_framebuffer(fbcon->helper.fb); 455 462 456 463 drm_fb_helper_unregister_fbi(&fbcon->helper); 457 464 drm_fb_helper_release_fbi(&fbcon->helper); 465 + drm_fb_helper_fini(&fbcon->helper); 458 466 459 467 if (nouveau_fb->nvbo) { 460 - nouveau_bo_unmap(nouveau_fb->nvbo); 461 468 nouveau_bo_vma_del(nouveau_fb->nvbo, &nouveau_fb->vma); 469 + nouveau_bo_unmap(nouveau_fb->nvbo); 462 470 nouveau_bo_unpin(nouveau_fb->nvbo); 463 - drm_gem_object_unreference_unlocked(&nouveau_fb->nvbo->gem); 464 - nouveau_fb->nvbo = NULL; 471 + drm_framebuffer_unreference(&nouveau_fb->base); 465 472 } 466 - drm_fb_helper_fini(&fbcon->helper); 467 - drm_framebuffer_unregister_private(&nouveau_fb->base); 468 - drm_framebuffer_cleanup(&nouveau_fb->base); 473 + 469 474 return 0; 470 475 } 471 476 472 477 void nouveau_fbcon_gpu_lockup(struct fb_info *info) 473 478 { 474 479 struct nouveau_fbdev *fbcon = info->par; 475 - struct nouveau_drm *drm = nouveau_drm(fbcon->dev); 480 + struct nouveau_drm *drm = nouveau_drm(fbcon->helper.dev); 476 481 477 482 NV_ERROR(drm, "GPU lockup - switching to software fbcon\n"); 478 483 info->flags |= FBINFO_HWACCEL_DISABLED; ··· 513 522 if (!fbcon) 514 523 return -ENOMEM; 515 524 516 - fbcon->dev = dev; 517 525 drm->fbcon = fbcon; 518 526 519 527 drm_fb_helper_prepare(dev, &fbcon->helper, &nouveau_fbcon_helper_funcs); ··· 535 545 preferred_bpp = 32; 536 546 537 547 /* disable all the possible outputs/crtcs before entering KMS mode */ 538 - drm_helper_disable_unused_functions(dev); 548 + if (!dev->mode_config.funcs->atomic_commit) 549 + drm_helper_disable_unused_functions(dev); 539 550 540 551 ret = drm_fb_helper_initial_config(&fbcon->helper, preferred_bpp); 541 552 if (ret)
-2
drivers/gpu/drm/nouveau/nouveau_fbcon.h
··· 33 33 34 34 struct nouveau_fbdev { 35 35 struct drm_fb_helper helper; 36 - struct nouveau_framebuffer nouveau_fb; 37 - struct drm_device *dev; 38 36 unsigned int saved_flags; 39 37 struct nvif_object surf2d; 40 38 struct nvif_object clip;
+1 -1
drivers/gpu/drm/nouveau/nouveau_fence.c
··· 586 586 .enable_signaling = nouveau_fence_enable_signaling, 587 587 .signaled = nouveau_fence_is_signaled, 588 588 .wait = dma_fence_default_wait, 589 - .release = NULL 589 + .release = nouveau_fence_release 590 590 };
-2
drivers/gpu/drm/nouveau/nouveau_fence.h
··· 92 92 struct nouveau_fence_chan base; 93 93 struct nvkm_vma vma; 94 94 struct nvkm_vma vma_gart; 95 - struct nvkm_vma dispc_vma[4]; 96 95 }; 97 96 98 97 struct nv84_fence_priv { ··· 101 102 u32 *suspend; 102 103 }; 103 104 104 - u64 nv84_fence_crtc(struct nouveau_channel *, int); 105 105 int nv84_fence_context_new(struct nouveau_channel *); 106 106 107 107 #endif
+1 -1
drivers/gpu/drm/nouveau/nouveau_gem.c
··· 369 369 { 370 370 struct nouveau_cli *cli = nouveau_cli(file_priv); 371 371 int trycnt = 0; 372 - int ret, i; 372 + int ret = -EINVAL, i; 373 373 struct nouveau_bo *res_bo = NULL; 374 374 LIST_HEAD(gart_list); 375 375 LIST_HEAD(vram_list);
+4 -4
drivers/gpu/drm/nouveau/nv04_fbcon.c
··· 30 30 nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) 31 31 { 32 32 struct nouveau_fbdev *nfbdev = info->par; 33 - struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); 33 + struct nouveau_drm *drm = nouveau_drm(nfbdev->helper.dev); 34 34 struct nouveau_channel *chan = drm->channel; 35 35 int ret; 36 36 ··· 50 50 nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 51 51 { 52 52 struct nouveau_fbdev *nfbdev = info->par; 53 - struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); 53 + struct nouveau_drm *drm = nouveau_drm(nfbdev->helper.dev); 54 54 struct nouveau_channel *chan = drm->channel; 55 55 int ret; 56 56 ··· 77 77 nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) 78 78 { 79 79 struct nouveau_fbdev *nfbdev = info->par; 80 - struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); 80 + struct nouveau_drm *drm = nouveau_drm(nfbdev->helper.dev); 81 81 struct nouveau_channel *chan = drm->channel; 82 82 uint32_t fg; 83 83 uint32_t bg; ··· 133 133 nv04_fbcon_accel_init(struct fb_info *info) 134 134 { 135 135 struct nouveau_fbdev *nfbdev = info->par; 136 - struct drm_device *dev = nfbdev->dev; 136 + struct drm_device *dev = nfbdev->helper.dev; 137 137 struct nouveau_drm *drm = nouveau_drm(dev); 138 138 struct nouveau_channel *chan = drm->channel; 139 139 struct nvif_device *device = &drm->device;
+1 -4
drivers/gpu/drm/nouveau/nv10_fence.c
··· 57 57 nv10_fence_context_del(struct nouveau_channel *chan) 58 58 { 59 59 struct nv10_fence_chan *fctx = chan->fence; 60 - int i; 61 60 nouveau_fence_context_del(&fctx->base); 62 - for (i = 0; i < ARRAY_SIZE(fctx->head); i++) 63 - nvif_object_fini(&fctx->head[i]); 64 61 nvif_object_fini(&fctx->sema); 65 62 chan->fence = NULL; 66 63 nouveau_fence_context_free(&fctx->base); 67 64 } 68 65 69 - int 66 + static int 70 67 nv10_fence_context_new(struct nouveau_channel *chan) 71 68 { 72 69 struct nv10_fence_chan *fctx;
-1
drivers/gpu/drm/nouveau/nv10_fence.h
··· 7 7 struct nv10_fence_chan { 8 8 struct nouveau_fence_chan base; 9 9 struct nvif_object sema; 10 - struct nvif_object head[4]; 11 10 }; 12 11 13 12 struct nv10_fence_priv {
+3156 -1256
drivers/gpu/drm/nouveau/nv50_display.c
··· 25 25 #include <linux/dma-mapping.h> 26 26 27 27 #include <drm/drmP.h> 28 + #include <drm/drm_atomic.h> 29 + #include <drm/drm_atomic_helper.h> 28 30 #include <drm/drm_crtc_helper.h> 29 - #include <drm/drm_plane_helper.h> 30 31 #include <drm/drm_dp_helper.h> 31 32 #include <drm/drm_fb_helper.h> 33 + #include <drm/drm_plane_helper.h> 32 34 33 35 #include <nvif/class.h> 34 36 #include <nvif/cl0002.h> ··· 40 38 #include <nvif/cl507c.h> 41 39 #include <nvif/cl507d.h> 42 40 #include <nvif/cl507e.h> 41 + #include <nvif/event.h> 43 42 44 43 #include "nouveau_drv.h" 45 44 #include "nouveau_dma.h" ··· 49 46 #include "nouveau_encoder.h" 50 47 #include "nouveau_crtc.h" 51 48 #include "nouveau_fence.h" 49 + #include "nouveau_fbcon.h" 52 50 #include "nv50_display.h" 53 51 54 52 #define EVO_DMA_NR 9 ··· 65 61 #define EVO_MAST_NTFY EVO_SYNC( 0, 0x00) 66 62 #define EVO_FLIP_SEM0(c) EVO_SYNC((c) + 1, 0x00) 67 63 #define EVO_FLIP_SEM1(c) EVO_SYNC((c) + 1, 0x10) 64 + #define EVO_FLIP_NTFY0(c) EVO_SYNC((c) + 1, 0x20) 65 + #define EVO_FLIP_NTFY1(c) EVO_SYNC((c) + 1, 0x30) 66 + 67 + /****************************************************************************** 68 + * Atomic state 69 + *****************************************************************************/ 70 + #define nv50_atom(p) container_of((p), struct nv50_atom, state) 71 + 72 + struct nv50_atom { 73 + struct drm_atomic_state state; 74 + 75 + struct list_head outp; 76 + bool lock_core; 77 + bool flush_disable; 78 + }; 79 + 80 + struct nv50_outp_atom { 81 + struct list_head head; 82 + 83 + struct drm_encoder *encoder; 84 + bool flush_disable; 85 + 86 + union { 87 + struct { 88 + bool ctrl:1; 89 + }; 90 + u8 mask; 91 + } clr; 92 + 93 + union { 94 + struct { 95 + bool ctrl:1; 96 + }; 97 + u8 mask; 98 + } set; 99 + }; 100 + 101 + #define nv50_head_atom(p) container_of((p), struct nv50_head_atom, state) 102 + 103 + struct nv50_head_atom { 104 + struct drm_crtc_state state; 105 + 106 + struct { 107 + u16 iW; 108 + u16 iH; 109 + u16 oW; 110 + u16 oH; 111 + } view; 112 + 113 + struct nv50_head_mode { 114 + bool interlace; 115 + u32 clock; 116 + struct { 117 + u16 active; 118 + u16 synce; 119 + u16 blanke; 120 + u16 blanks; 121 + } h; 122 + struct { 123 + u32 active; 124 + u16 synce; 125 + u16 blanke; 126 + u16 blanks; 127 + u16 blank2s; 128 + u16 blank2e; 129 + u16 blankus; 130 + } v; 131 + } mode; 132 + 133 + struct { 134 + u32 handle; 135 + u64 offset:40; 136 + } lut; 137 + 138 + struct { 139 + bool visible; 140 + u32 handle; 141 + u64 offset:40; 142 + u8 format; 143 + u8 kind:7; 144 + u8 layout:1; 145 + u8 block:4; 146 + u32 pitch:20; 147 + u16 x; 148 + u16 y; 149 + u16 w; 150 + u16 h; 151 + } core; 152 + 153 + struct { 154 + bool visible; 155 + u32 handle; 156 + u64 offset:40; 157 + u8 layout:1; 158 + u8 format:1; 159 + } curs; 160 + 161 + struct { 162 + u8 depth; 163 + u8 cpp; 164 + u16 x; 165 + u16 y; 166 + u16 w; 167 + u16 h; 168 + } base; 169 + 170 + struct { 171 + u8 cpp; 172 + } ovly; 173 + 174 + struct { 175 + bool enable:1; 176 + u8 bits:2; 177 + u8 mode:4; 178 + } dither; 179 + 180 + struct { 181 + struct { 182 + u16 cos:12; 183 + u16 sin:12; 184 + } sat; 185 + } procamp; 186 + 187 + union { 188 + struct { 189 + bool core:1; 190 + bool curs:1; 191 + }; 192 + u8 mask; 193 + } clr; 194 + 195 + union { 196 + struct { 197 + bool core:1; 198 + bool curs:1; 199 + bool view:1; 200 + bool mode:1; 201 + bool base:1; 202 + bool ovly:1; 203 + bool dither:1; 204 + bool procamp:1; 205 + }; 206 + u16 mask; 207 + } set; 208 + }; 209 + 210 + static inline struct nv50_head_atom * 211 + nv50_head_atom_get(struct drm_atomic_state *state, struct drm_crtc *crtc) 212 + { 213 + struct drm_crtc_state *statec = drm_atomic_get_crtc_state(state, crtc); 214 + if (IS_ERR(statec)) 215 + return (void *)statec; 216 + return nv50_head_atom(statec); 217 + } 218 + 219 + #define nv50_wndw_atom(p) container_of((p), struct nv50_wndw_atom, state) 220 + 221 + struct nv50_wndw_atom { 222 + struct drm_plane_state state; 223 + u8 interval; 224 + 225 + struct drm_rect clip; 226 + 227 + struct { 228 + u32 handle; 229 + u16 offset:12; 230 + bool awaken:1; 231 + } ntfy; 232 + 233 + struct { 234 + u32 handle; 235 + u16 offset:12; 236 + u32 acquire; 237 + u32 release; 238 + } sema; 239 + 240 + struct { 241 + u8 enable:2; 242 + } lut; 243 + 244 + struct { 245 + u8 mode:2; 246 + u8 interval:4; 247 + 248 + u8 format; 249 + u8 kind:7; 250 + u8 layout:1; 251 + u8 block:4; 252 + u32 pitch:20; 253 + u16 w; 254 + u16 h; 255 + 256 + u32 handle; 257 + u64 offset; 258 + } image; 259 + 260 + struct { 261 + u16 x; 262 + u16 y; 263 + } point; 264 + 265 + union { 266 + struct { 267 + bool ntfy:1; 268 + bool sema:1; 269 + bool image:1; 270 + }; 271 + u8 mask; 272 + } clr; 273 + 274 + union { 275 + struct { 276 + bool ntfy:1; 277 + bool sema:1; 278 + bool image:1; 279 + bool lut:1; 280 + bool point:1; 281 + }; 282 + u8 mask; 283 + } set; 284 + }; 68 285 69 286 /****************************************************************************** 70 287 * EVO channel ··· 358 133 } 359 134 360 135 /****************************************************************************** 361 - * Cursor Immediate 362 - *****************************************************************************/ 363 - 364 - struct nv50_curs { 365 - struct nv50_pioc base; 366 - }; 367 - 368 - static int 369 - nv50_curs_create(struct nvif_device *device, struct nvif_object *disp, 370 - int head, struct nv50_curs *curs) 371 - { 372 - struct nv50_disp_cursor_v0 args = { 373 - .head = head, 374 - }; 375 - static const s32 oclass[] = { 376 - GK104_DISP_CURSOR, 377 - GF110_DISP_CURSOR, 378 - GT214_DISP_CURSOR, 379 - G82_DISP_CURSOR, 380 - NV50_DISP_CURSOR, 381 - 0 382 - }; 383 - 384 - return nv50_pioc_create(device, disp, oclass, head, &args, sizeof(args), 385 - &curs->base); 386 - } 387 - 388 - /****************************************************************************** 389 136 * Overlay Immediate 390 137 *****************************************************************************/ 391 138 ··· 389 192 * DMA EVO channel 390 193 *****************************************************************************/ 391 194 195 + struct nv50_dmac_ctxdma { 196 + struct list_head head; 197 + struct nvif_object object; 198 + }; 199 + 392 200 struct nv50_dmac { 393 201 struct nv50_chan base; 394 202 dma_addr_t handle; ··· 401 199 402 200 struct nvif_object sync; 403 201 struct nvif_object vram; 202 + struct list_head ctxdma; 404 203 405 204 /* Protects against concurrent pushbuf access to this channel, lock is 406 205 * grabbed by evo_wait (if the pushbuf reservation is successful) and ··· 410 207 }; 411 208 412 209 static void 210 + nv50_dmac_ctxdma_del(struct nv50_dmac_ctxdma *ctxdma) 211 + { 212 + nvif_object_fini(&ctxdma->object); 213 + list_del(&ctxdma->head); 214 + kfree(ctxdma); 215 + } 216 + 217 + static struct nv50_dmac_ctxdma * 218 + nv50_dmac_ctxdma_new(struct nv50_dmac *dmac, struct nouveau_framebuffer *fb) 219 + { 220 + struct nouveau_drm *drm = nouveau_drm(fb->base.dev); 221 + struct nv50_dmac_ctxdma *ctxdma; 222 + const u8 kind = (fb->nvbo->tile_flags & 0x0000ff00) >> 8; 223 + const u32 handle = 0xfb000000 | kind; 224 + struct { 225 + struct nv_dma_v0 base; 226 + union { 227 + struct nv50_dma_v0 nv50; 228 + struct gf100_dma_v0 gf100; 229 + struct gf119_dma_v0 gf119; 230 + }; 231 + } args = {}; 232 + u32 argc = sizeof(args.base); 233 + int ret; 234 + 235 + list_for_each_entry(ctxdma, &dmac->ctxdma, head) { 236 + if (ctxdma->object.handle == handle) 237 + return ctxdma; 238 + } 239 + 240 + if (!(ctxdma = kzalloc(sizeof(*ctxdma), GFP_KERNEL))) 241 + return ERR_PTR(-ENOMEM); 242 + list_add(&ctxdma->head, &dmac->ctxdma); 243 + 244 + args.base.target = NV_DMA_V0_TARGET_VRAM; 245 + args.base.access = NV_DMA_V0_ACCESS_RDWR; 246 + args.base.start = 0; 247 + args.base.limit = drm->device.info.ram_user - 1; 248 + 249 + if (drm->device.info.chipset < 0x80) { 250 + args.nv50.part = NV50_DMA_V0_PART_256; 251 + argc += sizeof(args.nv50); 252 + } else 253 + if (drm->device.info.chipset < 0xc0) { 254 + args.nv50.part = NV50_DMA_V0_PART_256; 255 + args.nv50.kind = kind; 256 + argc += sizeof(args.nv50); 257 + } else 258 + if (drm->device.info.chipset < 0xd0) { 259 + args.gf100.kind = kind; 260 + argc += sizeof(args.gf100); 261 + } else { 262 + args.gf119.page = GF119_DMA_V0_PAGE_LP; 263 + args.gf119.kind = kind; 264 + argc += sizeof(args.gf119); 265 + } 266 + 267 + ret = nvif_object_init(&dmac->base.user, handle, NV_DMA_IN_MEMORY, 268 + &args, argc, &ctxdma->object); 269 + if (ret) { 270 + nv50_dmac_ctxdma_del(ctxdma); 271 + return ERR_PTR(ret); 272 + } 273 + 274 + return ctxdma; 275 + } 276 + 277 + static void 413 278 nv50_dmac_destroy(struct nv50_dmac *dmac, struct nvif_object *disp) 414 279 { 415 280 struct nvif_device *device = dmac->base.device; 281 + struct nv50_dmac_ctxdma *ctxdma, *ctxtmp; 282 + 283 + list_for_each_entry_safe(ctxdma, ctxtmp, &dmac->ctxdma, head) { 284 + nv50_dmac_ctxdma_del(ctxdma); 285 + } 416 286 417 287 nvif_object_fini(&dmac->vram); 418 288 nvif_object_fini(&dmac->sync); ··· 554 278 if (ret) 555 279 return ret; 556 280 281 + INIT_LIST_HEAD(&dmac->ctxdma); 557 282 return ret; 558 283 } 559 284 ··· 658 381 659 382 struct nv50_head { 660 383 struct nouveau_crtc base; 661 - struct nouveau_bo *image; 662 - struct nv50_curs curs; 663 - struct nv50_sync sync; 664 384 struct nv50_ovly ovly; 665 385 struct nv50_oimm oimm; 666 386 }; 667 387 668 388 #define nv50_head(c) ((struct nv50_head *)nouveau_crtc(c)) 669 - #define nv50_curs(c) (&nv50_head(c)->curs) 670 - #define nv50_sync(c) (&nv50_head(c)->sync) 671 389 #define nv50_ovly(c) (&nv50_head(c)->ovly) 672 390 #define nv50_oimm(c) (&nv50_head(c)->oimm) 673 391 #define nv50_chan(c) (&(c)->base.base) 674 392 #define nv50_vers(c) nv50_chan(c)->user.oclass 675 393 676 - struct nv50_fbdma { 677 - struct list_head head; 678 - struct nvif_object core; 679 - struct nvif_object base[4]; 680 - }; 681 - 682 394 struct nv50_disp { 683 395 struct nvif_object *disp; 684 396 struct nv50_mast mast; 685 397 686 - struct list_head fbdma; 687 - 688 398 struct nouveau_bo *sync; 399 + 400 + struct mutex mutex; 689 401 }; 690 402 691 403 static struct nv50_disp * ··· 684 418 } 685 419 686 420 #define nv50_mast(d) (&nv50_disp(d)->mast) 687 - 688 - static struct drm_crtc * 689 - nv50_display_crtc_get(struct drm_encoder *encoder) 690 - { 691 - return nouveau_encoder(encoder)->crtc; 692 - } 693 421 694 422 /****************************************************************************** 695 423 * EVO channel helpers ··· 723 463 mutex_unlock(&dmac->lock); 724 464 } 725 465 726 - #if 1 727 - #define evo_mthd(p,m,s) *((p)++) = (((s) << 18) | (m)) 728 - #define evo_data(p,d) *((p)++) = (d) 729 - #else 730 466 #define evo_mthd(p,m,s) do { \ 731 467 const u32 _m = (m), _s = (s); \ 732 - printk(KERN_ERR "%04x %d %s\n", _m, _s, __func__); \ 468 + if (drm_debug & DRM_UT_KMS) \ 469 + printk(KERN_ERR "%04x %d %s\n", _m, _s, __func__); \ 733 470 *((p)++) = ((_s << 18) | _m); \ 734 471 } while(0) 472 + 735 473 #define evo_data(p,d) do { \ 736 474 const u32 _d = (d); \ 737 - printk(KERN_ERR "\t%08x\n", _d); \ 475 + if (drm_debug & DRM_UT_KMS) \ 476 + printk(KERN_ERR "\t%08x\n", _d); \ 738 477 *((p)++) = _d; \ 739 478 } while(0) 740 - #endif 741 479 742 - static bool 743 - evo_sync_wait(void *data) 480 + /****************************************************************************** 481 + * Plane 482 + *****************************************************************************/ 483 + #define nv50_wndw(p) container_of((p), struct nv50_wndw, plane) 484 + 485 + struct nv50_wndw { 486 + const struct nv50_wndw_func *func; 487 + struct nv50_dmac *dmac; 488 + 489 + struct drm_plane plane; 490 + 491 + struct nvif_notify notify; 492 + u16 ntfy; 493 + u16 sema; 494 + u32 data; 495 + }; 496 + 497 + struct nv50_wndw_func { 498 + void *(*dtor)(struct nv50_wndw *); 499 + int (*acquire)(struct nv50_wndw *, struct nv50_wndw_atom *asyw, 500 + struct nv50_head_atom *asyh); 501 + void (*release)(struct nv50_wndw *, struct nv50_wndw_atom *asyw, 502 + struct nv50_head_atom *asyh); 503 + void (*prepare)(struct nv50_wndw *, struct nv50_head_atom *asyh, 504 + struct nv50_wndw_atom *asyw); 505 + 506 + void (*sema_set)(struct nv50_wndw *, struct nv50_wndw_atom *); 507 + void (*sema_clr)(struct nv50_wndw *); 508 + void (*ntfy_set)(struct nv50_wndw *, struct nv50_wndw_atom *); 509 + void (*ntfy_clr)(struct nv50_wndw *); 510 + int (*ntfy_wait_begun)(struct nv50_wndw *, struct nv50_wndw_atom *); 511 + void (*image_set)(struct nv50_wndw *, struct nv50_wndw_atom *); 512 + void (*image_clr)(struct nv50_wndw *); 513 + void (*lut)(struct nv50_wndw *, struct nv50_wndw_atom *); 514 + void (*point)(struct nv50_wndw *, struct nv50_wndw_atom *); 515 + 516 + u32 (*update)(struct nv50_wndw *, u32 interlock); 517 + }; 518 + 519 + static int 520 + nv50_wndw_wait_armed(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) 744 521 { 745 - if (nouveau_bo_rd32(data, EVO_MAST_NTFY) != 0x00000000) 746 - return true; 747 - usleep_range(1, 2); 748 - return false; 522 + if (asyw->set.ntfy) 523 + return wndw->func->ntfy_wait_begun(wndw, asyw); 524 + return 0; 525 + } 526 + 527 + static u32 528 + nv50_wndw_flush_clr(struct nv50_wndw *wndw, u32 interlock, bool flush, 529 + struct nv50_wndw_atom *asyw) 530 + { 531 + if (asyw->clr.sema && (!asyw->set.sema || flush)) 532 + wndw->func->sema_clr(wndw); 533 + if (asyw->clr.ntfy && (!asyw->set.ntfy || flush)) 534 + wndw->func->ntfy_clr(wndw); 535 + if (asyw->clr.image && (!asyw->set.image || flush)) 536 + wndw->func->image_clr(wndw); 537 + 538 + return flush ? wndw->func->update(wndw, interlock) : 0; 539 + } 540 + 541 + static u32 542 + nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 interlock, 543 + struct nv50_wndw_atom *asyw) 544 + { 545 + if (interlock) { 546 + asyw->image.mode = 0; 547 + asyw->image.interval = 1; 548 + } 549 + 550 + if (asyw->set.sema ) wndw->func->sema_set (wndw, asyw); 551 + if (asyw->set.ntfy ) wndw->func->ntfy_set (wndw, asyw); 552 + if (asyw->set.image) wndw->func->image_set(wndw, asyw); 553 + if (asyw->set.lut ) wndw->func->lut (wndw, asyw); 554 + if (asyw->set.point) wndw->func->point (wndw, asyw); 555 + 556 + return wndw->func->update(wndw, interlock); 557 + } 558 + 559 + static void 560 + nv50_wndw_atomic_check_release(struct nv50_wndw *wndw, 561 + struct nv50_wndw_atom *asyw, 562 + struct nv50_head_atom *asyh) 563 + { 564 + struct nouveau_drm *drm = nouveau_drm(wndw->plane.dev); 565 + NV_ATOMIC(drm, "%s release\n", wndw->plane.name); 566 + wndw->func->release(wndw, asyw, asyh); 567 + asyw->ntfy.handle = 0; 568 + asyw->sema.handle = 0; 749 569 } 750 570 751 571 static int 752 - evo_sync(struct drm_device *dev) 572 + nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, 573 + struct nv50_wndw_atom *asyw, 574 + struct nv50_head_atom *asyh) 753 575 { 754 - struct nvif_device *device = &nouveau_drm(dev)->device; 755 - struct nv50_disp *disp = nv50_disp(dev); 756 - struct nv50_mast *mast = nv50_mast(dev); 757 - u32 *push = evo_wait(mast, 8); 758 - if (push) { 759 - nouveau_bo_wr32(disp->sync, EVO_MAST_NTFY, 0x00000000); 760 - evo_mthd(push, 0x0084, 1); 761 - evo_data(push, 0x80000000 | EVO_MAST_NTFY); 762 - evo_mthd(push, 0x0080, 2); 763 - evo_data(push, 0x00000000); 764 - evo_data(push, 0x00000000); 765 - evo_kick(push, mast); 766 - if (nvif_msec(device, 2000, 767 - if (evo_sync_wait(disp->sync)) 768 - break; 769 - ) >= 0) 770 - return 0; 576 + struct nouveau_framebuffer *fb = nouveau_framebuffer(asyw->state.fb); 577 + struct nouveau_drm *drm = nouveau_drm(wndw->plane.dev); 578 + int ret; 579 + 580 + NV_ATOMIC(drm, "%s acquire\n", wndw->plane.name); 581 + asyw->clip.x1 = 0; 582 + asyw->clip.y1 = 0; 583 + asyw->clip.x2 = asyh->state.mode.hdisplay; 584 + asyw->clip.y2 = asyh->state.mode.vdisplay; 585 + 586 + asyw->image.w = fb->base.width; 587 + asyw->image.h = fb->base.height; 588 + asyw->image.kind = (fb->nvbo->tile_flags & 0x0000ff00) >> 8; 589 + if (asyw->image.kind) { 590 + asyw->image.layout = 0; 591 + if (drm->device.info.chipset >= 0xc0) 592 + asyw->image.block = fb->nvbo->tile_mode >> 4; 593 + else 594 + asyw->image.block = fb->nvbo->tile_mode; 595 + asyw->image.pitch = (fb->base.pitches[0] / 4) << 4; 596 + } else { 597 + asyw->image.layout = 1; 598 + asyw->image.block = 0; 599 + asyw->image.pitch = fb->base.pitches[0]; 771 600 } 772 601 773 - return -EBUSY; 602 + ret = wndw->func->acquire(wndw, asyw, asyh); 603 + if (ret) 604 + return ret; 605 + 606 + if (asyw->set.image) { 607 + if (!(asyw->image.mode = asyw->interval ? 0 : 1)) 608 + asyw->image.interval = asyw->interval; 609 + else 610 + asyw->image.interval = 0; 611 + } 612 + 613 + return 0; 614 + } 615 + 616 + static int 617 + nv50_wndw_atomic_check(struct drm_plane *plane, struct drm_plane_state *state) 618 + { 619 + struct nouveau_drm *drm = nouveau_drm(plane->dev); 620 + struct nv50_wndw *wndw = nv50_wndw(plane); 621 + struct nv50_wndw_atom *armw = nv50_wndw_atom(wndw->plane.state); 622 + struct nv50_wndw_atom *asyw = nv50_wndw_atom(state); 623 + struct nv50_head_atom *harm = NULL, *asyh = NULL; 624 + bool varm = false, asyv = false, asym = false; 625 + int ret; 626 + 627 + NV_ATOMIC(drm, "%s atomic_check\n", plane->name); 628 + if (asyw->state.crtc) { 629 + asyh = nv50_head_atom_get(asyw->state.state, asyw->state.crtc); 630 + if (IS_ERR(asyh)) 631 + return PTR_ERR(asyh); 632 + asym = drm_atomic_crtc_needs_modeset(&asyh->state); 633 + asyv = asyh->state.active; 634 + } 635 + 636 + if (armw->state.crtc) { 637 + harm = nv50_head_atom_get(asyw->state.state, armw->state.crtc); 638 + if (IS_ERR(harm)) 639 + return PTR_ERR(harm); 640 + varm = harm->state.crtc->state->active; 641 + } 642 + 643 + if (asyv) { 644 + asyw->point.x = asyw->state.crtc_x; 645 + asyw->point.y = asyw->state.crtc_y; 646 + if (memcmp(&armw->point, &asyw->point, sizeof(asyw->point))) 647 + asyw->set.point = true; 648 + 649 + if (!varm || asym || armw->state.fb != asyw->state.fb) { 650 + ret = nv50_wndw_atomic_check_acquire(wndw, asyw, asyh); 651 + if (ret) 652 + return ret; 653 + } 654 + } else 655 + if (varm) { 656 + nv50_wndw_atomic_check_release(wndw, asyw, harm); 657 + } else { 658 + return 0; 659 + } 660 + 661 + if (!asyv || asym) { 662 + asyw->clr.ntfy = armw->ntfy.handle != 0; 663 + asyw->clr.sema = armw->sema.handle != 0; 664 + if (wndw->func->image_clr) 665 + asyw->clr.image = armw->image.handle != 0; 666 + asyw->set.lut = wndw->func->lut && asyv; 667 + } 668 + 669 + return 0; 670 + } 671 + 672 + static void 673 + nv50_wndw_cleanup_fb(struct drm_plane *plane, struct drm_plane_state *old_state) 674 + { 675 + struct nouveau_framebuffer *fb = nouveau_framebuffer(old_state->fb); 676 + struct nouveau_drm *drm = nouveau_drm(plane->dev); 677 + 678 + NV_ATOMIC(drm, "%s cleanup: %p\n", plane->name, old_state->fb); 679 + if (!old_state->fb) 680 + return; 681 + 682 + nouveau_bo_unpin(fb->nvbo); 683 + } 684 + 685 + static int 686 + nv50_wndw_prepare_fb(struct drm_plane *plane, struct drm_plane_state *state) 687 + { 688 + struct nouveau_framebuffer *fb = nouveau_framebuffer(state->fb); 689 + struct nouveau_drm *drm = nouveau_drm(plane->dev); 690 + struct nv50_wndw *wndw = nv50_wndw(plane); 691 + struct nv50_wndw_atom *asyw = nv50_wndw_atom(state); 692 + struct nv50_head_atom *asyh; 693 + struct nv50_dmac_ctxdma *ctxdma; 694 + int ret; 695 + 696 + NV_ATOMIC(drm, "%s prepare: %p\n", plane->name, state->fb); 697 + if (!asyw->state.fb) 698 + return 0; 699 + 700 + ret = nouveau_bo_pin(fb->nvbo, TTM_PL_FLAG_VRAM, true); 701 + if (ret) 702 + return ret; 703 + 704 + ctxdma = nv50_dmac_ctxdma_new(wndw->dmac, fb); 705 + if (IS_ERR(ctxdma)) { 706 + nouveau_bo_unpin(fb->nvbo); 707 + return PTR_ERR(ctxdma); 708 + } 709 + 710 + asyw->state.fence = reservation_object_get_excl_rcu(fb->nvbo->bo.resv); 711 + asyw->image.handle = ctxdma->object.handle; 712 + asyw->image.offset = fb->nvbo->bo.offset; 713 + 714 + if (wndw->func->prepare) { 715 + asyh = nv50_head_atom_get(asyw->state.state, asyw->state.crtc); 716 + if (IS_ERR(asyh)) 717 + return PTR_ERR(asyh); 718 + 719 + wndw->func->prepare(wndw, asyh, asyw); 720 + } 721 + 722 + return 0; 723 + } 724 + 725 + static const struct drm_plane_helper_funcs 726 + nv50_wndw_helper = { 727 + .prepare_fb = nv50_wndw_prepare_fb, 728 + .cleanup_fb = nv50_wndw_cleanup_fb, 729 + .atomic_check = nv50_wndw_atomic_check, 730 + }; 731 + 732 + static void 733 + nv50_wndw_atomic_destroy_state(struct drm_plane *plane, 734 + struct drm_plane_state *state) 735 + { 736 + struct nv50_wndw_atom *asyw = nv50_wndw_atom(state); 737 + __drm_atomic_helper_plane_destroy_state(&asyw->state); 738 + dma_fence_put(asyw->state.fence); 739 + kfree(asyw); 740 + } 741 + 742 + static struct drm_plane_state * 743 + nv50_wndw_atomic_duplicate_state(struct drm_plane *plane) 744 + { 745 + struct nv50_wndw_atom *armw = nv50_wndw_atom(plane->state); 746 + struct nv50_wndw_atom *asyw; 747 + if (!(asyw = kmalloc(sizeof(*asyw), GFP_KERNEL))) 748 + return NULL; 749 + __drm_atomic_helper_plane_duplicate_state(plane, &asyw->state); 750 + asyw->state.fence = NULL; 751 + asyw->interval = 1; 752 + asyw->sema = armw->sema; 753 + asyw->ntfy = armw->ntfy; 754 + asyw->image = armw->image; 755 + asyw->point = armw->point; 756 + asyw->lut = armw->lut; 757 + asyw->clr.mask = 0; 758 + asyw->set.mask = 0; 759 + return &asyw->state; 760 + } 761 + 762 + static void 763 + nv50_wndw_reset(struct drm_plane *plane) 764 + { 765 + struct nv50_wndw_atom *asyw; 766 + 767 + if (WARN_ON(!(asyw = kzalloc(sizeof(*asyw), GFP_KERNEL)))) 768 + return; 769 + 770 + if (plane->state) 771 + plane->funcs->atomic_destroy_state(plane, plane->state); 772 + plane->state = &asyw->state; 773 + plane->state->plane = plane; 774 + plane->state->rotation = DRM_ROTATE_0; 775 + } 776 + 777 + static void 778 + nv50_wndw_destroy(struct drm_plane *plane) 779 + { 780 + struct nv50_wndw *wndw = nv50_wndw(plane); 781 + void *data; 782 + nvif_notify_fini(&wndw->notify); 783 + data = wndw->func->dtor(wndw); 784 + drm_plane_cleanup(&wndw->plane); 785 + kfree(data); 786 + } 787 + 788 + static const struct drm_plane_funcs 789 + nv50_wndw = { 790 + .update_plane = drm_atomic_helper_update_plane, 791 + .disable_plane = drm_atomic_helper_disable_plane, 792 + .destroy = nv50_wndw_destroy, 793 + .reset = nv50_wndw_reset, 794 + .set_property = drm_atomic_helper_plane_set_property, 795 + .atomic_duplicate_state = nv50_wndw_atomic_duplicate_state, 796 + .atomic_destroy_state = nv50_wndw_atomic_destroy_state, 797 + }; 798 + 799 + static void 800 + nv50_wndw_fini(struct nv50_wndw *wndw) 801 + { 802 + nvif_notify_put(&wndw->notify); 803 + } 804 + 805 + static void 806 + nv50_wndw_init(struct nv50_wndw *wndw) 807 + { 808 + nvif_notify_get(&wndw->notify); 809 + } 810 + 811 + static int 812 + nv50_wndw_ctor(const struct nv50_wndw_func *func, struct drm_device *dev, 813 + enum drm_plane_type type, const char *name, int index, 814 + struct nv50_dmac *dmac, const u32 *format, int nformat, 815 + struct nv50_wndw *wndw) 816 + { 817 + int ret; 818 + 819 + wndw->func = func; 820 + wndw->dmac = dmac; 821 + 822 + ret = drm_universal_plane_init(dev, &wndw->plane, 0, &nv50_wndw, format, 823 + nformat, type, "%s-%d", name, index); 824 + if (ret) 825 + return ret; 826 + 827 + drm_plane_helper_add(&wndw->plane, &nv50_wndw_helper); 828 + return 0; 774 829 } 775 830 776 831 /****************************************************************************** 777 - * Page flipping channel 832 + * Cursor plane 778 833 *****************************************************************************/ 779 - struct nouveau_bo * 780 - nv50_display_crtc_sema(struct drm_device *dev, int crtc) 781 - { 782 - return nv50_disp(dev)->sync; 783 - } 834 + #define nv50_curs(p) container_of((p), struct nv50_curs, wndw) 784 835 785 - struct nv50_display_flip { 786 - struct nv50_disp *disp; 787 - struct nv50_sync *chan; 836 + struct nv50_curs { 837 + struct nv50_wndw wndw; 838 + struct nvif_object chan; 788 839 }; 789 840 790 - static bool 791 - nv50_display_flip_wait(void *data) 841 + static u32 842 + nv50_curs_update(struct nv50_wndw *wndw, u32 interlock) 792 843 { 793 - struct nv50_display_flip *flip = data; 794 - if (nouveau_bo_rd32(flip->disp->sync, flip->chan->addr / 4) == 795 - flip->chan->data) 796 - return true; 797 - usleep_range(1, 2); 798 - return false; 844 + struct nv50_curs *curs = nv50_curs(wndw); 845 + nvif_wr32(&curs->chan, 0x0080, 0x00000000); 846 + return 0; 799 847 } 800 848 801 - void 802 - nv50_display_flip_stop(struct drm_crtc *crtc) 849 + static void 850 + nv50_curs_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) 803 851 { 804 - struct nvif_device *device = &nouveau_drm(crtc->dev)->device; 805 - struct nv50_display_flip flip = { 806 - .disp = nv50_disp(crtc->dev), 807 - .chan = nv50_sync(crtc), 808 - }; 809 - u32 *push; 852 + struct nv50_curs *curs = nv50_curs(wndw); 853 + nvif_wr32(&curs->chan, 0x0084, (asyw->point.y << 16) | asyw->point.x); 854 + } 810 855 811 - push = evo_wait(flip.chan, 8); 812 - if (push) { 856 + static void 857 + nv50_curs_prepare(struct nv50_wndw *wndw, struct nv50_head_atom *asyh, 858 + struct nv50_wndw_atom *asyw) 859 + { 860 + asyh->curs.handle = nv50_disp(wndw->plane.dev)->mast.base.vram.handle; 861 + asyh->curs.offset = asyw->image.offset; 862 + asyh->set.curs = asyh->curs.visible; 863 + } 864 + 865 + static void 866 + nv50_curs_release(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, 867 + struct nv50_head_atom *asyh) 868 + { 869 + asyh->curs.visible = false; 870 + } 871 + 872 + static int 873 + nv50_curs_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, 874 + struct nv50_head_atom *asyh) 875 + { 876 + int ret; 877 + 878 + ret = drm_plane_helper_check_state(&asyw->state, &asyw->clip, 879 + DRM_PLANE_HELPER_NO_SCALING, 880 + DRM_PLANE_HELPER_NO_SCALING, 881 + true, true); 882 + asyh->curs.visible = asyw->state.visible; 883 + if (ret || !asyh->curs.visible) 884 + return ret; 885 + 886 + switch (asyw->state.fb->width) { 887 + case 32: asyh->curs.layout = 0; break; 888 + case 64: asyh->curs.layout = 1; break; 889 + default: 890 + return -EINVAL; 891 + } 892 + 893 + if (asyw->state.fb->width != asyw->state.fb->height) 894 + return -EINVAL; 895 + 896 + switch (asyw->state.fb->pixel_format) { 897 + case DRM_FORMAT_ARGB8888: asyh->curs.format = 1; break; 898 + default: 899 + WARN_ON(1); 900 + return -EINVAL; 901 + } 902 + 903 + return 0; 904 + } 905 + 906 + static void * 907 + nv50_curs_dtor(struct nv50_wndw *wndw) 908 + { 909 + struct nv50_curs *curs = nv50_curs(wndw); 910 + nvif_object_fini(&curs->chan); 911 + return curs; 912 + } 913 + 914 + static const u32 915 + nv50_curs_format[] = { 916 + DRM_FORMAT_ARGB8888, 917 + }; 918 + 919 + static const struct nv50_wndw_func 920 + nv50_curs = { 921 + .dtor = nv50_curs_dtor, 922 + .acquire = nv50_curs_acquire, 923 + .release = nv50_curs_release, 924 + .prepare = nv50_curs_prepare, 925 + .point = nv50_curs_point, 926 + .update = nv50_curs_update, 927 + }; 928 + 929 + static int 930 + nv50_curs_new(struct nouveau_drm *drm, struct nv50_head *head, 931 + struct nv50_curs **pcurs) 932 + { 933 + static const struct nvif_mclass curses[] = { 934 + { GK104_DISP_CURSOR, 0 }, 935 + { GF110_DISP_CURSOR, 0 }, 936 + { GT214_DISP_CURSOR, 0 }, 937 + { G82_DISP_CURSOR, 0 }, 938 + { NV50_DISP_CURSOR, 0 }, 939 + {} 940 + }; 941 + struct nv50_disp_cursor_v0 args = { 942 + .head = head->base.index, 943 + }; 944 + struct nv50_disp *disp = nv50_disp(drm->dev); 945 + struct nv50_curs *curs; 946 + int cid, ret; 947 + 948 + cid = nvif_mclass(disp->disp, curses); 949 + if (cid < 0) { 950 + NV_ERROR(drm, "No supported cursor immediate class\n"); 951 + return cid; 952 + } 953 + 954 + if (!(curs = *pcurs = kzalloc(sizeof(*curs), GFP_KERNEL))) 955 + return -ENOMEM; 956 + 957 + ret = nv50_wndw_ctor(&nv50_curs, drm->dev, DRM_PLANE_TYPE_CURSOR, 958 + "curs", head->base.index, &disp->mast.base, 959 + nv50_curs_format, ARRAY_SIZE(nv50_curs_format), 960 + &curs->wndw); 961 + if (ret) { 962 + kfree(curs); 963 + return ret; 964 + } 965 + 966 + ret = nvif_object_init(disp->disp, 0, curses[cid].oclass, &args, 967 + sizeof(args), &curs->chan); 968 + if (ret) { 969 + NV_ERROR(drm, "curs%04x allocation failed: %d\n", 970 + curses[cid].oclass, ret); 971 + return ret; 972 + } 973 + 974 + return 0; 975 + } 976 + 977 + /****************************************************************************** 978 + * Primary plane 979 + *****************************************************************************/ 980 + #define nv50_base(p) container_of((p), struct nv50_base, wndw) 981 + 982 + struct nv50_base { 983 + struct nv50_wndw wndw; 984 + struct nv50_sync chan; 985 + int id; 986 + }; 987 + 988 + static int 989 + nv50_base_notify(struct nvif_notify *notify) 990 + { 991 + return NVIF_NOTIFY_KEEP; 992 + } 993 + 994 + static void 995 + nv50_base_lut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) 996 + { 997 + struct nv50_base *base = nv50_base(wndw); 998 + u32 *push; 999 + if ((push = evo_wait(&base->chan, 2))) { 1000 + evo_mthd(push, 0x00e0, 1); 1001 + evo_data(push, asyw->lut.enable << 30); 1002 + evo_kick(push, &base->chan); 1003 + } 1004 + } 1005 + 1006 + static void 1007 + nv50_base_image_clr(struct nv50_wndw *wndw) 1008 + { 1009 + struct nv50_base *base = nv50_base(wndw); 1010 + u32 *push; 1011 + if ((push = evo_wait(&base->chan, 4))) { 813 1012 evo_mthd(push, 0x0084, 1); 814 - evo_data(push, 0x00000000); 815 - evo_mthd(push, 0x0094, 1); 816 1013 evo_data(push, 0x00000000); 817 1014 evo_mthd(push, 0x00c0, 1); 818 1015 evo_data(push, 0x00000000); 819 - evo_mthd(push, 0x0080, 1); 820 - evo_data(push, 0x00000000); 821 - evo_kick(push, flip.chan); 1016 + evo_kick(push, &base->chan); 822 1017 } 823 - 824 - nvif_msec(device, 2000, 825 - if (nv50_display_flip_wait(&flip)) 826 - break; 827 - ); 828 1018 } 829 1019 830 - int 831 - nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, 832 - struct nouveau_channel *chan, u32 swap_interval) 1020 + static void 1021 + nv50_base_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) 833 1022 { 834 - struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb); 835 - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 836 - struct nv50_head *head = nv50_head(crtc); 837 - struct nv50_sync *sync = nv50_sync(crtc); 1023 + struct nv50_base *base = nv50_base(wndw); 1024 + const s32 oclass = base->chan.base.base.user.oclass; 838 1025 u32 *push; 1026 + if ((push = evo_wait(&base->chan, 10))) { 1027 + evo_mthd(push, 0x0084, 1); 1028 + evo_data(push, (asyw->image.mode << 8) | 1029 + (asyw->image.interval << 4)); 1030 + evo_mthd(push, 0x00c0, 1); 1031 + evo_data(push, asyw->image.handle); 1032 + if (oclass < G82_DISP_BASE_CHANNEL_DMA) { 1033 + evo_mthd(push, 0x0800, 5); 1034 + evo_data(push, asyw->image.offset >> 8); 1035 + evo_data(push, 0x00000000); 1036 + evo_data(push, (asyw->image.h << 16) | asyw->image.w); 1037 + evo_data(push, (asyw->image.layout << 20) | 1038 + asyw->image.pitch | 1039 + asyw->image.block); 1040 + evo_data(push, (asyw->image.kind << 16) | 1041 + (asyw->image.format << 8)); 1042 + } else 1043 + if (oclass < GF110_DISP_BASE_CHANNEL_DMA) { 1044 + evo_mthd(push, 0x0800, 5); 1045 + evo_data(push, asyw->image.offset >> 8); 1046 + evo_data(push, 0x00000000); 1047 + evo_data(push, (asyw->image.h << 16) | asyw->image.w); 1048 + evo_data(push, (asyw->image.layout << 20) | 1049 + asyw->image.pitch | 1050 + asyw->image.block); 1051 + evo_data(push, asyw->image.format << 8); 1052 + } else { 1053 + evo_mthd(push, 0x0400, 5); 1054 + evo_data(push, asyw->image.offset >> 8); 1055 + evo_data(push, 0x00000000); 1056 + evo_data(push, (asyw->image.h << 16) | asyw->image.w); 1057 + evo_data(push, (asyw->image.layout << 24) | 1058 + asyw->image.pitch | 1059 + asyw->image.block); 1060 + evo_data(push, asyw->image.format << 8); 1061 + } 1062 + evo_kick(push, &base->chan); 1063 + } 1064 + } 1065 + 1066 + static void 1067 + nv50_base_ntfy_clr(struct nv50_wndw *wndw) 1068 + { 1069 + struct nv50_base *base = nv50_base(wndw); 1070 + u32 *push; 1071 + if ((push = evo_wait(&base->chan, 2))) { 1072 + evo_mthd(push, 0x00a4, 1); 1073 + evo_data(push, 0x00000000); 1074 + evo_kick(push, &base->chan); 1075 + } 1076 + } 1077 + 1078 + static void 1079 + nv50_base_ntfy_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) 1080 + { 1081 + struct nv50_base *base = nv50_base(wndw); 1082 + u32 *push; 1083 + if ((push = evo_wait(&base->chan, 3))) { 1084 + evo_mthd(push, 0x00a0, 2); 1085 + evo_data(push, (asyw->ntfy.awaken << 30) | asyw->ntfy.offset); 1086 + evo_data(push, asyw->ntfy.handle); 1087 + evo_kick(push, &base->chan); 1088 + } 1089 + } 1090 + 1091 + static void 1092 + nv50_base_sema_clr(struct nv50_wndw *wndw) 1093 + { 1094 + struct nv50_base *base = nv50_base(wndw); 1095 + u32 *push; 1096 + if ((push = evo_wait(&base->chan, 2))) { 1097 + evo_mthd(push, 0x0094, 1); 1098 + evo_data(push, 0x00000000); 1099 + evo_kick(push, &base->chan); 1100 + } 1101 + } 1102 + 1103 + static void 1104 + nv50_base_sema_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) 1105 + { 1106 + struct nv50_base *base = nv50_base(wndw); 1107 + u32 *push; 1108 + if ((push = evo_wait(&base->chan, 5))) { 1109 + evo_mthd(push, 0x0088, 4); 1110 + evo_data(push, asyw->sema.offset); 1111 + evo_data(push, asyw->sema.acquire); 1112 + evo_data(push, asyw->sema.release); 1113 + evo_data(push, asyw->sema.handle); 1114 + evo_kick(push, &base->chan); 1115 + } 1116 + } 1117 + 1118 + static u32 1119 + nv50_base_update(struct nv50_wndw *wndw, u32 interlock) 1120 + { 1121 + struct nv50_base *base = nv50_base(wndw); 1122 + u32 *push; 1123 + 1124 + if (!(push = evo_wait(&base->chan, 2))) 1125 + return 0; 1126 + evo_mthd(push, 0x0080, 1); 1127 + evo_data(push, interlock); 1128 + evo_kick(push, &base->chan); 1129 + 1130 + if (base->chan.base.base.user.oclass < GF110_DISP_BASE_CHANNEL_DMA) 1131 + return interlock ? 2 << (base->id * 8) : 0; 1132 + return interlock ? 2 << (base->id * 4) : 0; 1133 + } 1134 + 1135 + static int 1136 + nv50_base_ntfy_wait_begun(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw) 1137 + { 1138 + struct nouveau_drm *drm = nouveau_drm(wndw->plane.dev); 1139 + struct nv50_disp *disp = nv50_disp(wndw->plane.dev); 1140 + if (nvif_msec(&drm->device, 2000ULL, 1141 + u32 data = nouveau_bo_rd32(disp->sync, asyw->ntfy.offset / 4); 1142 + if ((data & 0xc0000000) == 0x40000000) 1143 + break; 1144 + usleep_range(1, 2); 1145 + ) < 0) 1146 + return -ETIMEDOUT; 1147 + return 0; 1148 + } 1149 + 1150 + static void 1151 + nv50_base_release(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, 1152 + struct nv50_head_atom *asyh) 1153 + { 1154 + asyh->base.cpp = 0; 1155 + } 1156 + 1157 + static int 1158 + nv50_base_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, 1159 + struct nv50_head_atom *asyh) 1160 + { 1161 + const u32 format = asyw->state.fb->pixel_format; 1162 + const struct drm_format_info *info; 839 1163 int ret; 840 1164 841 - if (crtc->primary->fb->width != fb->width || 842 - crtc->primary->fb->height != fb->height) 1165 + info = drm_format_info(format); 1166 + if (!info || !info->depth) 843 1167 return -EINVAL; 844 1168 845 - swap_interval <<= 4; 846 - if (swap_interval == 0) 847 - swap_interval |= 0x100; 848 - if (chan == NULL) 849 - evo_sync(crtc->dev); 1169 + ret = drm_plane_helper_check_state(&asyw->state, &asyw->clip, 1170 + DRM_PLANE_HELPER_NO_SCALING, 1171 + DRM_PLANE_HELPER_NO_SCALING, 1172 + false, true); 1173 + if (ret) 1174 + return ret; 850 1175 851 - push = evo_wait(sync, 128); 852 - if (unlikely(push == NULL)) 853 - return -EBUSY; 1176 + asyh->base.depth = info->depth; 1177 + asyh->base.cpp = info->cpp[0]; 1178 + asyh->base.x = asyw->state.src.x1 >> 16; 1179 + asyh->base.y = asyw->state.src.y1 >> 16; 1180 + asyh->base.w = asyw->state.fb->width; 1181 + asyh->base.h = asyw->state.fb->height; 854 1182 855 - if (chan && chan->user.oclass < G82_CHANNEL_GPFIFO) { 856 - ret = RING_SPACE(chan, 8); 857 - if (ret) 858 - return ret; 859 - 860 - BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 2); 861 - OUT_RING (chan, NvEvoSema0 + nv_crtc->index); 862 - OUT_RING (chan, sync->addr ^ 0x10); 863 - BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_RELEASE, 1); 864 - OUT_RING (chan, sync->data + 1); 865 - BEGIN_NV04(chan, 0, NV11_SUBCHAN_SEMAPHORE_OFFSET, 2); 866 - OUT_RING (chan, sync->addr); 867 - OUT_RING (chan, sync->data); 868 - } else 869 - if (chan && chan->user.oclass < FERMI_CHANNEL_GPFIFO) { 870 - u64 addr = nv84_fence_crtc(chan, nv_crtc->index) + sync->addr; 871 - ret = RING_SPACE(chan, 12); 872 - if (ret) 873 - return ret; 874 - 875 - BEGIN_NV04(chan, 0, NV11_SUBCHAN_DMA_SEMAPHORE, 1); 876 - OUT_RING (chan, chan->vram.handle); 877 - BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); 878 - OUT_RING (chan, upper_32_bits(addr ^ 0x10)); 879 - OUT_RING (chan, lower_32_bits(addr ^ 0x10)); 880 - OUT_RING (chan, sync->data + 1); 881 - OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG); 882 - BEGIN_NV04(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); 883 - OUT_RING (chan, upper_32_bits(addr)); 884 - OUT_RING (chan, lower_32_bits(addr)); 885 - OUT_RING (chan, sync->data); 886 - OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL); 887 - } else 888 - if (chan) { 889 - u64 addr = nv84_fence_crtc(chan, nv_crtc->index) + sync->addr; 890 - ret = RING_SPACE(chan, 10); 891 - if (ret) 892 - return ret; 893 - 894 - BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); 895 - OUT_RING (chan, upper_32_bits(addr ^ 0x10)); 896 - OUT_RING (chan, lower_32_bits(addr ^ 0x10)); 897 - OUT_RING (chan, sync->data + 1); 898 - OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_WRITE_LONG | 899 - NVC0_SUBCHAN_SEMAPHORE_TRIGGER_YIELD); 900 - BEGIN_NVC0(chan, 0, NV84_SUBCHAN_SEMAPHORE_ADDRESS_HIGH, 4); 901 - OUT_RING (chan, upper_32_bits(addr)); 902 - OUT_RING (chan, lower_32_bits(addr)); 903 - OUT_RING (chan, sync->data); 904 - OUT_RING (chan, NV84_SUBCHAN_SEMAPHORE_TRIGGER_ACQUIRE_EQUAL | 905 - NVC0_SUBCHAN_SEMAPHORE_TRIGGER_YIELD); 1183 + switch (format) { 1184 + case DRM_FORMAT_C8 : asyw->image.format = 0x1e; break; 1185 + case DRM_FORMAT_RGB565 : asyw->image.format = 0xe8; break; 1186 + case DRM_FORMAT_XRGB1555 : 1187 + case DRM_FORMAT_ARGB1555 : asyw->image.format = 0xe9; break; 1188 + case DRM_FORMAT_XRGB8888 : 1189 + case DRM_FORMAT_ARGB8888 : asyw->image.format = 0xcf; break; 1190 + case DRM_FORMAT_XBGR2101010: 1191 + case DRM_FORMAT_ABGR2101010: asyw->image.format = 0xd1; break; 1192 + case DRM_FORMAT_XBGR8888 : 1193 + case DRM_FORMAT_ABGR8888 : asyw->image.format = 0xd5; break; 1194 + default: 1195 + WARN_ON(1); 1196 + return -EINVAL; 906 1197 } 907 1198 908 - if (chan) { 909 - sync->addr ^= 0x10; 910 - sync->data++; 911 - FIRE_RING (chan); 912 - } 913 - 914 - /* queue the flip */ 915 - evo_mthd(push, 0x0100, 1); 916 - evo_data(push, 0xfffe0000); 917 - evo_mthd(push, 0x0084, 1); 918 - evo_data(push, swap_interval); 919 - if (!(swap_interval & 0x00000100)) { 920 - evo_mthd(push, 0x00e0, 1); 921 - evo_data(push, 0x40000000); 922 - } 923 - evo_mthd(push, 0x0088, 4); 924 - evo_data(push, sync->addr); 925 - evo_data(push, sync->data++); 926 - evo_data(push, sync->data); 927 - evo_data(push, sync->base.sync.handle); 928 - evo_mthd(push, 0x00a0, 2); 929 - evo_data(push, 0x00000000); 930 - evo_data(push, 0x00000000); 931 - evo_mthd(push, 0x00c0, 1); 932 - evo_data(push, nv_fb->r_handle); 933 - evo_mthd(push, 0x0110, 2); 934 - evo_data(push, 0x00000000); 935 - evo_data(push, 0x00000000); 936 - if (nv50_vers(sync) < GF110_DISP_BASE_CHANNEL_DMA) { 937 - evo_mthd(push, 0x0800, 5); 938 - evo_data(push, nv_fb->nvbo->bo.offset >> 8); 939 - evo_data(push, 0); 940 - evo_data(push, (fb->height << 16) | fb->width); 941 - evo_data(push, nv_fb->r_pitch); 942 - evo_data(push, nv_fb->r_format); 943 - } else { 944 - evo_mthd(push, 0x0400, 5); 945 - evo_data(push, nv_fb->nvbo->bo.offset >> 8); 946 - evo_data(push, 0); 947 - evo_data(push, (fb->height << 16) | fb->width); 948 - evo_data(push, nv_fb->r_pitch); 949 - evo_data(push, nv_fb->r_format); 950 - } 951 - evo_mthd(push, 0x0080, 1); 952 - evo_data(push, 0x00000000); 953 - evo_kick(push, sync); 954 - 955 - nouveau_bo_ref(nv_fb->nvbo, &head->image); 1199 + asyw->lut.enable = 1; 1200 + asyw->set.image = true; 956 1201 return 0; 1202 + } 1203 + 1204 + static void * 1205 + nv50_base_dtor(struct nv50_wndw *wndw) 1206 + { 1207 + struct nv50_disp *disp = nv50_disp(wndw->plane.dev); 1208 + struct nv50_base *base = nv50_base(wndw); 1209 + nv50_dmac_destroy(&base->chan.base, disp->disp); 1210 + return base; 1211 + } 1212 + 1213 + static const u32 1214 + nv50_base_format[] = { 1215 + DRM_FORMAT_C8, 1216 + DRM_FORMAT_RGB565, 1217 + DRM_FORMAT_XRGB1555, 1218 + DRM_FORMAT_ARGB1555, 1219 + DRM_FORMAT_XRGB8888, 1220 + DRM_FORMAT_ARGB8888, 1221 + DRM_FORMAT_XBGR2101010, 1222 + DRM_FORMAT_ABGR2101010, 1223 + DRM_FORMAT_XBGR8888, 1224 + DRM_FORMAT_ABGR8888, 1225 + }; 1226 + 1227 + static const struct nv50_wndw_func 1228 + nv50_base = { 1229 + .dtor = nv50_base_dtor, 1230 + .acquire = nv50_base_acquire, 1231 + .release = nv50_base_release, 1232 + .sema_set = nv50_base_sema_set, 1233 + .sema_clr = nv50_base_sema_clr, 1234 + .ntfy_set = nv50_base_ntfy_set, 1235 + .ntfy_clr = nv50_base_ntfy_clr, 1236 + .ntfy_wait_begun = nv50_base_ntfy_wait_begun, 1237 + .image_set = nv50_base_image_set, 1238 + .image_clr = nv50_base_image_clr, 1239 + .lut = nv50_base_lut, 1240 + .update = nv50_base_update, 1241 + }; 1242 + 1243 + static int 1244 + nv50_base_new(struct nouveau_drm *drm, struct nv50_head *head, 1245 + struct nv50_base **pbase) 1246 + { 1247 + struct nv50_disp *disp = nv50_disp(drm->dev); 1248 + struct nv50_base *base; 1249 + int ret; 1250 + 1251 + if (!(base = *pbase = kzalloc(sizeof(*base), GFP_KERNEL))) 1252 + return -ENOMEM; 1253 + base->id = head->base.index; 1254 + base->wndw.ntfy = EVO_FLIP_NTFY0(base->id); 1255 + base->wndw.sema = EVO_FLIP_SEM0(base->id); 1256 + base->wndw.data = 0x00000000; 1257 + 1258 + ret = nv50_wndw_ctor(&nv50_base, drm->dev, DRM_PLANE_TYPE_PRIMARY, 1259 + "base", base->id, &base->chan.base, 1260 + nv50_base_format, ARRAY_SIZE(nv50_base_format), 1261 + &base->wndw); 1262 + if (ret) { 1263 + kfree(base); 1264 + return ret; 1265 + } 1266 + 1267 + ret = nv50_base_create(&drm->device, disp->disp, base->id, 1268 + disp->sync->bo.offset, &base->chan); 1269 + if (ret) 1270 + return ret; 1271 + 1272 + return nvif_notify_init(&base->chan.base.base.user, nv50_base_notify, 1273 + false, 1274 + NV50_DISP_BASE_CHANNEL_DMA_V0_NTFY_UEVENT, 1275 + &(struct nvif_notify_uevent_req) {}, 1276 + sizeof(struct nvif_notify_uevent_req), 1277 + sizeof(struct nvif_notify_uevent_rep), 1278 + &base->wndw.notify); 957 1279 } 958 1280 959 1281 /****************************************************************************** 960 - * CRTC 1282 + * Head 961 1283 *****************************************************************************/ 962 - static int 963 - nv50_crtc_set_dither(struct nouveau_crtc *nv_crtc, bool update) 1284 + static void 1285 + nv50_head_procamp(struct nv50_head *head, struct nv50_head_atom *asyh) 964 1286 { 965 - struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev); 966 - struct nouveau_connector *nv_connector; 967 - struct drm_connector *connector; 968 - u32 *push, mode = 0x00; 1287 + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; 1288 + u32 *push; 1289 + if ((push = evo_wait(core, 2))) { 1290 + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) 1291 + evo_mthd(push, 0x08a8 + (head->base.index * 0x400), 1); 1292 + else 1293 + evo_mthd(push, 0x0498 + (head->base.index * 0x300), 1); 1294 + evo_data(push, (asyh->procamp.sat.sin << 20) | 1295 + (asyh->procamp.sat.cos << 8)); 1296 + evo_kick(push, core); 1297 + } 1298 + } 969 1299 970 - nv_connector = nouveau_crtc_connector_get(nv_crtc); 971 - connector = &nv_connector->base; 972 - if (nv_connector->dithering_mode == DITHERING_MODE_AUTO) { 973 - if (nv_crtc->base.primary->fb->depth > connector->display_info.bpc * 3) 974 - mode = DITHERING_MODE_DYNAMIC2X2; 975 - } else { 976 - mode = nv_connector->dithering_mode; 1300 + static void 1301 + nv50_head_dither(struct nv50_head *head, struct nv50_head_atom *asyh) 1302 + { 1303 + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; 1304 + u32 *push; 1305 + if ((push = evo_wait(core, 2))) { 1306 + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) 1307 + evo_mthd(push, 0x08a0 + (head->base.index * 0x0400), 1); 1308 + else 1309 + if (core->base.user.oclass < GK104_DISP_CORE_CHANNEL_DMA) 1310 + evo_mthd(push, 0x0490 + (head->base.index * 0x0300), 1); 1311 + else 1312 + evo_mthd(push, 0x04a0 + (head->base.index * 0x0300), 1); 1313 + evo_data(push, (asyh->dither.mode << 3) | 1314 + (asyh->dither.bits << 1) | 1315 + asyh->dither.enable); 1316 + evo_kick(push, core); 1317 + } 1318 + } 1319 + 1320 + static void 1321 + nv50_head_ovly(struct nv50_head *head, struct nv50_head_atom *asyh) 1322 + { 1323 + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; 1324 + u32 bounds = 0; 1325 + u32 *push; 1326 + 1327 + if (asyh->base.cpp) { 1328 + switch (asyh->base.cpp) { 1329 + case 8: bounds |= 0x00000500; break; 1330 + case 4: bounds |= 0x00000300; break; 1331 + case 2: bounds |= 0x00000100; break; 1332 + default: 1333 + WARN_ON(1); 1334 + break; 1335 + } 1336 + bounds |= 0x00000001; 977 1337 } 978 1338 979 - if (nv_connector->dithering_depth == DITHERING_DEPTH_AUTO) { 1339 + if ((push = evo_wait(core, 2))) { 1340 + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) 1341 + evo_mthd(push, 0x0904 + head->base.index * 0x400, 1); 1342 + else 1343 + evo_mthd(push, 0x04d4 + head->base.index * 0x300, 1); 1344 + evo_data(push, bounds); 1345 + evo_kick(push, core); 1346 + } 1347 + } 1348 + 1349 + static void 1350 + nv50_head_base(struct nv50_head *head, struct nv50_head_atom *asyh) 1351 + { 1352 + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; 1353 + u32 bounds = 0; 1354 + u32 *push; 1355 + 1356 + if (asyh->base.cpp) { 1357 + switch (asyh->base.cpp) { 1358 + case 8: bounds |= 0x00000500; break; 1359 + case 4: bounds |= 0x00000300; break; 1360 + case 2: bounds |= 0x00000100; break; 1361 + case 1: bounds |= 0x00000000; break; 1362 + default: 1363 + WARN_ON(1); 1364 + break; 1365 + } 1366 + bounds |= 0x00000001; 1367 + } 1368 + 1369 + if ((push = evo_wait(core, 2))) { 1370 + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) 1371 + evo_mthd(push, 0x0900 + head->base.index * 0x400, 1); 1372 + else 1373 + evo_mthd(push, 0x04d0 + head->base.index * 0x300, 1); 1374 + evo_data(push, bounds); 1375 + evo_kick(push, core); 1376 + } 1377 + } 1378 + 1379 + static void 1380 + nv50_head_curs_clr(struct nv50_head *head) 1381 + { 1382 + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; 1383 + u32 *push; 1384 + if ((push = evo_wait(core, 4))) { 1385 + if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) { 1386 + evo_mthd(push, 0x0880 + head->base.index * 0x400, 1); 1387 + evo_data(push, 0x05000000); 1388 + } else 1389 + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { 1390 + evo_mthd(push, 0x0880 + head->base.index * 0x400, 1); 1391 + evo_data(push, 0x05000000); 1392 + evo_mthd(push, 0x089c + head->base.index * 0x400, 1); 1393 + evo_data(push, 0x00000000); 1394 + } else { 1395 + evo_mthd(push, 0x0480 + head->base.index * 0x300, 1); 1396 + evo_data(push, 0x05000000); 1397 + evo_mthd(push, 0x048c + head->base.index * 0x300, 1); 1398 + evo_data(push, 0x00000000); 1399 + } 1400 + evo_kick(push, core); 1401 + } 1402 + } 1403 + 1404 + static void 1405 + nv50_head_curs_set(struct nv50_head *head, struct nv50_head_atom *asyh) 1406 + { 1407 + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; 1408 + u32 *push; 1409 + if ((push = evo_wait(core, 5))) { 1410 + if (core->base.user.oclass < G82_DISP_BASE_CHANNEL_DMA) { 1411 + evo_mthd(push, 0x0880 + head->base.index * 0x400, 2); 1412 + evo_data(push, 0x80000000 | (asyh->curs.layout << 26) | 1413 + (asyh->curs.format << 24)); 1414 + evo_data(push, asyh->curs.offset >> 8); 1415 + } else 1416 + if (core->base.user.oclass < GF110_DISP_BASE_CHANNEL_DMA) { 1417 + evo_mthd(push, 0x0880 + head->base.index * 0x400, 2); 1418 + evo_data(push, 0x80000000 | (asyh->curs.layout << 26) | 1419 + (asyh->curs.format << 24)); 1420 + evo_data(push, asyh->curs.offset >> 8); 1421 + evo_mthd(push, 0x089c + head->base.index * 0x400, 1); 1422 + evo_data(push, asyh->curs.handle); 1423 + } else { 1424 + evo_mthd(push, 0x0480 + head->base.index * 0x300, 2); 1425 + evo_data(push, 0x80000000 | (asyh->curs.layout << 26) | 1426 + (asyh->curs.format << 24)); 1427 + evo_data(push, asyh->curs.offset >> 8); 1428 + evo_mthd(push, 0x048c + head->base.index * 0x300, 1); 1429 + evo_data(push, asyh->curs.handle); 1430 + } 1431 + evo_kick(push, core); 1432 + } 1433 + } 1434 + 1435 + static void 1436 + nv50_head_core_clr(struct nv50_head *head) 1437 + { 1438 + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; 1439 + u32 *push; 1440 + if ((push = evo_wait(core, 2))) { 1441 + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) 1442 + evo_mthd(push, 0x0874 + head->base.index * 0x400, 1); 1443 + else 1444 + evo_mthd(push, 0x0474 + head->base.index * 0x300, 1); 1445 + evo_data(push, 0x00000000); 1446 + evo_kick(push, core); 1447 + } 1448 + } 1449 + 1450 + static void 1451 + nv50_head_core_set(struct nv50_head *head, struct nv50_head_atom *asyh) 1452 + { 1453 + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; 1454 + u32 *push; 1455 + if ((push = evo_wait(core, 9))) { 1456 + if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) { 1457 + evo_mthd(push, 0x0860 + head->base.index * 0x400, 1); 1458 + evo_data(push, asyh->core.offset >> 8); 1459 + evo_mthd(push, 0x0868 + head->base.index * 0x400, 4); 1460 + evo_data(push, (asyh->core.h << 16) | asyh->core.w); 1461 + evo_data(push, asyh->core.layout << 20 | 1462 + (asyh->core.pitch >> 8) << 8 | 1463 + asyh->core.block); 1464 + evo_data(push, asyh->core.kind << 16 | 1465 + asyh->core.format << 8); 1466 + evo_data(push, asyh->core.handle); 1467 + evo_mthd(push, 0x08c0 + head->base.index * 0x400, 1); 1468 + evo_data(push, (asyh->core.y << 16) | asyh->core.x); 1469 + } else 1470 + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { 1471 + evo_mthd(push, 0x0860 + head->base.index * 0x400, 1); 1472 + evo_data(push, asyh->core.offset >> 8); 1473 + evo_mthd(push, 0x0868 + head->base.index * 0x400, 4); 1474 + evo_data(push, (asyh->core.h << 16) | asyh->core.w); 1475 + evo_data(push, asyh->core.layout << 20 | 1476 + (asyh->core.pitch >> 8) << 8 | 1477 + asyh->core.block); 1478 + evo_data(push, asyh->core.format << 8); 1479 + evo_data(push, asyh->core.handle); 1480 + evo_mthd(push, 0x08c0 + head->base.index * 0x400, 1); 1481 + evo_data(push, (asyh->core.y << 16) | asyh->core.x); 1482 + } else { 1483 + evo_mthd(push, 0x0460 + head->base.index * 0x300, 1); 1484 + evo_data(push, asyh->core.offset >> 8); 1485 + evo_mthd(push, 0x0468 + head->base.index * 0x300, 4); 1486 + evo_data(push, (asyh->core.h << 16) | asyh->core.w); 1487 + evo_data(push, asyh->core.layout << 24 | 1488 + (asyh->core.pitch >> 8) << 8 | 1489 + asyh->core.block); 1490 + evo_data(push, asyh->core.format << 8); 1491 + evo_data(push, asyh->core.handle); 1492 + evo_mthd(push, 0x04b0 + head->base.index * 0x300, 1); 1493 + evo_data(push, (asyh->core.y << 16) | asyh->core.x); 1494 + } 1495 + evo_kick(push, core); 1496 + } 1497 + } 1498 + 1499 + static void 1500 + nv50_head_lut_clr(struct nv50_head *head) 1501 + { 1502 + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; 1503 + u32 *push; 1504 + if ((push = evo_wait(core, 4))) { 1505 + if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) { 1506 + evo_mthd(push, 0x0840 + (head->base.index * 0x400), 1); 1507 + evo_data(push, 0x40000000); 1508 + } else 1509 + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { 1510 + evo_mthd(push, 0x0840 + (head->base.index * 0x400), 1); 1511 + evo_data(push, 0x40000000); 1512 + evo_mthd(push, 0x085c + (head->base.index * 0x400), 1); 1513 + evo_data(push, 0x00000000); 1514 + } else { 1515 + evo_mthd(push, 0x0440 + (head->base.index * 0x300), 1); 1516 + evo_data(push, 0x03000000); 1517 + evo_mthd(push, 0x045c + (head->base.index * 0x300), 1); 1518 + evo_data(push, 0x00000000); 1519 + } 1520 + evo_kick(push, core); 1521 + } 1522 + } 1523 + 1524 + static void 1525 + nv50_head_lut_set(struct nv50_head *head, struct nv50_head_atom *asyh) 1526 + { 1527 + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; 1528 + u32 *push; 1529 + if ((push = evo_wait(core, 7))) { 1530 + if (core->base.user.oclass < G82_DISP_CORE_CHANNEL_DMA) { 1531 + evo_mthd(push, 0x0840 + (head->base.index * 0x400), 2); 1532 + evo_data(push, 0xc0000000); 1533 + evo_data(push, asyh->lut.offset >> 8); 1534 + } else 1535 + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { 1536 + evo_mthd(push, 0x0840 + (head->base.index * 0x400), 2); 1537 + evo_data(push, 0xc0000000); 1538 + evo_data(push, asyh->lut.offset >> 8); 1539 + evo_mthd(push, 0x085c + (head->base.index * 0x400), 1); 1540 + evo_data(push, asyh->lut.handle); 1541 + } else { 1542 + evo_mthd(push, 0x0440 + (head->base.index * 0x300), 4); 1543 + evo_data(push, 0x83000000); 1544 + evo_data(push, asyh->lut.offset >> 8); 1545 + evo_data(push, 0x00000000); 1546 + evo_data(push, 0x00000000); 1547 + evo_mthd(push, 0x045c + (head->base.index * 0x300), 1); 1548 + evo_data(push, asyh->lut.handle); 1549 + } 1550 + evo_kick(push, core); 1551 + } 1552 + } 1553 + 1554 + static void 1555 + nv50_head_mode(struct nv50_head *head, struct nv50_head_atom *asyh) 1556 + { 1557 + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; 1558 + struct nv50_head_mode *m = &asyh->mode; 1559 + u32 *push; 1560 + if ((push = evo_wait(core, 14))) { 1561 + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { 1562 + evo_mthd(push, 0x0804 + (head->base.index * 0x400), 2); 1563 + evo_data(push, 0x00800000 | m->clock); 1564 + evo_data(push, m->interlace ? 0x00000002 : 0x00000000); 1565 + evo_mthd(push, 0x0810 + (head->base.index * 0x400), 7); 1566 + evo_data(push, 0x00000000); 1567 + evo_data(push, (m->v.active << 16) | m->h.active ); 1568 + evo_data(push, (m->v.synce << 16) | m->h.synce ); 1569 + evo_data(push, (m->v.blanke << 16) | m->h.blanke ); 1570 + evo_data(push, (m->v.blanks << 16) | m->h.blanks ); 1571 + evo_data(push, (m->v.blank2e << 16) | m->v.blank2s); 1572 + evo_data(push, asyh->mode.v.blankus); 1573 + evo_mthd(push, 0x082c + (head->base.index * 0x400), 1); 1574 + evo_data(push, 0x00000000); 1575 + } else { 1576 + evo_mthd(push, 0x0410 + (head->base.index * 0x300), 6); 1577 + evo_data(push, 0x00000000); 1578 + evo_data(push, (m->v.active << 16) | m->h.active ); 1579 + evo_data(push, (m->v.synce << 16) | m->h.synce ); 1580 + evo_data(push, (m->v.blanke << 16) | m->h.blanke ); 1581 + evo_data(push, (m->v.blanks << 16) | m->h.blanks ); 1582 + evo_data(push, (m->v.blank2e << 16) | m->v.blank2s); 1583 + evo_mthd(push, 0x042c + (head->base.index * 0x300), 2); 1584 + evo_data(push, 0x00000000); /* ??? */ 1585 + evo_data(push, 0xffffff00); 1586 + evo_mthd(push, 0x0450 + (head->base.index * 0x300), 3); 1587 + evo_data(push, m->clock * 1000); 1588 + evo_data(push, 0x00200000); /* ??? */ 1589 + evo_data(push, m->clock * 1000); 1590 + } 1591 + evo_kick(push, core); 1592 + } 1593 + } 1594 + 1595 + static void 1596 + nv50_head_view(struct nv50_head *head, struct nv50_head_atom *asyh) 1597 + { 1598 + struct nv50_dmac *core = &nv50_disp(head->base.base.dev)->mast.base; 1599 + u32 *push; 1600 + if ((push = evo_wait(core, 10))) { 1601 + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { 1602 + evo_mthd(push, 0x08a4 + (head->base.index * 0x400), 1); 1603 + evo_data(push, 0x00000000); 1604 + evo_mthd(push, 0x08c8 + (head->base.index * 0x400), 1); 1605 + evo_data(push, (asyh->view.iH << 16) | asyh->view.iW); 1606 + evo_mthd(push, 0x08d8 + (head->base.index * 0x400), 2); 1607 + evo_data(push, (asyh->view.oH << 16) | asyh->view.oW); 1608 + evo_data(push, (asyh->view.oH << 16) | asyh->view.oW); 1609 + } else { 1610 + evo_mthd(push, 0x0494 + (head->base.index * 0x300), 1); 1611 + evo_data(push, 0x00000000); 1612 + evo_mthd(push, 0x04b8 + (head->base.index * 0x300), 1); 1613 + evo_data(push, (asyh->view.iH << 16) | asyh->view.iW); 1614 + evo_mthd(push, 0x04c0 + (head->base.index * 0x300), 3); 1615 + evo_data(push, (asyh->view.oH << 16) | asyh->view.oW); 1616 + evo_data(push, (asyh->view.oH << 16) | asyh->view.oW); 1617 + evo_data(push, (asyh->view.oH << 16) | asyh->view.oW); 1618 + } 1619 + evo_kick(push, core); 1620 + } 1621 + } 1622 + 1623 + static void 1624 + nv50_head_flush_clr(struct nv50_head *head, struct nv50_head_atom *asyh, bool y) 1625 + { 1626 + if (asyh->clr.core && (!asyh->set.core || y)) 1627 + nv50_head_lut_clr(head); 1628 + if (asyh->clr.core && (!asyh->set.core || y)) 1629 + nv50_head_core_clr(head); 1630 + if (asyh->clr.curs && (!asyh->set.curs || y)) 1631 + nv50_head_curs_clr(head); 1632 + } 1633 + 1634 + static void 1635 + nv50_head_flush_set(struct nv50_head *head, struct nv50_head_atom *asyh) 1636 + { 1637 + if (asyh->set.view ) nv50_head_view (head, asyh); 1638 + if (asyh->set.mode ) nv50_head_mode (head, asyh); 1639 + if (asyh->set.core ) nv50_head_lut_set (head, asyh); 1640 + if (asyh->set.core ) nv50_head_core_set(head, asyh); 1641 + if (asyh->set.curs ) nv50_head_curs_set(head, asyh); 1642 + if (asyh->set.base ) nv50_head_base (head, asyh); 1643 + if (asyh->set.ovly ) nv50_head_ovly (head, asyh); 1644 + if (asyh->set.dither ) nv50_head_dither (head, asyh); 1645 + if (asyh->set.procamp) nv50_head_procamp (head, asyh); 1646 + } 1647 + 1648 + static void 1649 + nv50_head_atomic_check_procamp(struct nv50_head_atom *armh, 1650 + struct nv50_head_atom *asyh, 1651 + struct nouveau_conn_atom *asyc) 1652 + { 1653 + const int vib = asyc->procamp.color_vibrance - 100; 1654 + const int hue = asyc->procamp.vibrant_hue - 90; 1655 + const int adj = (vib > 0) ? 50 : 0; 1656 + asyh->procamp.sat.cos = ((vib * 2047 + adj) / 100) & 0xfff; 1657 + asyh->procamp.sat.sin = ((hue * 2047) / 100) & 0xfff; 1658 + asyh->set.procamp = true; 1659 + } 1660 + 1661 + static void 1662 + nv50_head_atomic_check_dither(struct nv50_head_atom *armh, 1663 + struct nv50_head_atom *asyh, 1664 + struct nouveau_conn_atom *asyc) 1665 + { 1666 + struct drm_connector *connector = asyc->state.connector; 1667 + u32 mode = 0x00; 1668 + 1669 + if (asyc->dither.mode == DITHERING_MODE_AUTO) { 1670 + if (asyh->base.depth > connector->display_info.bpc * 3) 1671 + mode = DITHERING_MODE_DYNAMIC2X2; 1672 + } else { 1673 + mode = asyc->dither.mode; 1674 + } 1675 + 1676 + if (asyc->dither.depth == DITHERING_DEPTH_AUTO) { 980 1677 if (connector->display_info.bpc >= 8) 981 1678 mode |= DITHERING_DEPTH_8BPC; 982 1679 } else { 983 - mode |= nv_connector->dithering_depth; 1680 + mode |= asyc->dither.depth; 984 1681 } 985 1682 986 - push = evo_wait(mast, 4); 987 - if (push) { 988 - if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { 989 - evo_mthd(push, 0x08a0 + (nv_crtc->index * 0x0400), 1); 990 - evo_data(push, mode); 991 - } else 992 - if (nv50_vers(mast) < GK104_DISP_CORE_CHANNEL_DMA) { 993 - evo_mthd(push, 0x0490 + (nv_crtc->index * 0x0300), 1); 994 - evo_data(push, mode); 995 - } else { 996 - evo_mthd(push, 0x04a0 + (nv_crtc->index * 0x0300), 1); 997 - evo_data(push, mode); 998 - } 999 - 1000 - if (update) { 1001 - evo_mthd(push, 0x0080, 1); 1002 - evo_data(push, 0x00000000); 1003 - } 1004 - evo_kick(push, mast); 1005 - } 1006 - 1007 - return 0; 1683 + asyh->dither.enable = mode; 1684 + asyh->dither.bits = mode >> 1; 1685 + asyh->dither.mode = mode >> 3; 1686 + asyh->set.dither = true; 1008 1687 } 1009 1688 1010 - static int 1011 - nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update) 1689 + static void 1690 + nv50_head_atomic_check_view(struct nv50_head_atom *armh, 1691 + struct nv50_head_atom *asyh, 1692 + struct nouveau_conn_atom *asyc) 1012 1693 { 1013 - struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev); 1014 - struct drm_display_mode *omode, *umode = &nv_crtc->base.mode; 1015 - struct drm_crtc *crtc = &nv_crtc->base; 1016 - struct nouveau_connector *nv_connector; 1017 - int mode = DRM_MODE_SCALE_NONE; 1018 - u32 oX, oY, *push; 1694 + struct drm_connector *connector = asyc->state.connector; 1695 + struct drm_display_mode *omode = &asyh->state.adjusted_mode; 1696 + struct drm_display_mode *umode = &asyh->state.mode; 1697 + int mode = asyc->scaler.mode; 1698 + struct edid *edid; 1019 1699 1020 - /* start off at the resolution we programmed the crtc for, this 1021 - * effectively handles NONE/FULL scaling 1022 - */ 1023 - nv_connector = nouveau_crtc_connector_get(nv_crtc); 1024 - if (nv_connector && nv_connector->native_mode) { 1025 - mode = nv_connector->scaling_mode; 1026 - if (nv_connector->scaling_full) /* non-EDID LVDS/eDP mode */ 1027 - mode = DRM_MODE_SCALE_FULLSCREEN; 1700 + if (connector->edid_blob_ptr) 1701 + edid = (struct edid *)connector->edid_blob_ptr->data; 1702 + else 1703 + edid = NULL; 1704 + 1705 + if (!asyc->scaler.full) { 1706 + if (mode == DRM_MODE_SCALE_NONE) 1707 + omode = umode; 1708 + } else { 1709 + /* Non-EDID LVDS/eDP mode. */ 1710 + mode = DRM_MODE_SCALE_FULLSCREEN; 1028 1711 } 1029 1712 1030 - if (mode != DRM_MODE_SCALE_NONE) 1031 - omode = nv_connector->native_mode; 1032 - else 1033 - omode = umode; 1034 - 1035 - oX = omode->hdisplay; 1036 - oY = omode->vdisplay; 1713 + asyh->view.iW = umode->hdisplay; 1714 + asyh->view.iH = umode->vdisplay; 1715 + asyh->view.oW = omode->hdisplay; 1716 + asyh->view.oH = omode->vdisplay; 1037 1717 if (omode->flags & DRM_MODE_FLAG_DBLSCAN) 1038 - oY *= 2; 1718 + asyh->view.oH *= 2; 1039 1719 1040 - /* add overscan compensation if necessary, will keep the aspect 1720 + /* Add overscan compensation if necessary, will keep the aspect 1041 1721 * ratio the same as the backend mode unless overridden by the 1042 1722 * user setting both hborder and vborder properties. 1043 1723 */ 1044 - if (nv_connector && ( nv_connector->underscan == UNDERSCAN_ON || 1045 - (nv_connector->underscan == UNDERSCAN_AUTO && 1046 - drm_detect_hdmi_monitor(nv_connector->edid)))) { 1047 - u32 bX = nv_connector->underscan_hborder; 1048 - u32 bY = nv_connector->underscan_vborder; 1049 - u32 aspect = (oY << 19) / oX; 1724 + if ((asyc->scaler.underscan.mode == UNDERSCAN_ON || 1725 + (asyc->scaler.underscan.mode == UNDERSCAN_AUTO && 1726 + drm_detect_hdmi_monitor(edid)))) { 1727 + u32 bX = asyc->scaler.underscan.hborder; 1728 + u32 bY = asyc->scaler.underscan.vborder; 1729 + u32 r = (asyh->view.oH << 19) / asyh->view.oW; 1050 1730 1051 1731 if (bX) { 1052 - oX -= (bX * 2); 1053 - if (bY) oY -= (bY * 2); 1054 - else oY = ((oX * aspect) + (aspect / 2)) >> 19; 1732 + asyh->view.oW -= (bX * 2); 1733 + if (bY) asyh->view.oH -= (bY * 2); 1734 + else asyh->view.oH = ((asyh->view.oW * r) + (r / 2)) >> 19; 1055 1735 } else { 1056 - oX -= (oX >> 4) + 32; 1057 - if (bY) oY -= (bY * 2); 1058 - else oY = ((oX * aspect) + (aspect / 2)) >> 19; 1736 + asyh->view.oW -= (asyh->view.oW >> 4) + 32; 1737 + if (bY) asyh->view.oH -= (bY * 2); 1738 + else asyh->view.oH = ((asyh->view.oW * r) + (r / 2)) >> 19; 1059 1739 } 1060 1740 } 1061 1741 1062 - /* handle CENTER/ASPECT scaling, taking into account the areas 1063 - * removed already for overscan compensation 1742 + /* Handle CENTER/ASPECT scaling, taking into account the areas 1743 + * removed already for overscan compensation. 1064 1744 */ 1065 1745 switch (mode) { 1066 1746 case DRM_MODE_SCALE_CENTER: 1067 - oX = min((u32)umode->hdisplay, oX); 1068 - oY = min((u32)umode->vdisplay, oY); 1747 + asyh->view.oW = min((u16)umode->hdisplay, asyh->view.oW); 1748 + asyh->view.oH = min((u16)umode->vdisplay, asyh->view.oH); 1069 1749 /* fall-through */ 1070 1750 case DRM_MODE_SCALE_ASPECT: 1071 - if (oY < oX) { 1072 - u32 aspect = (umode->hdisplay << 19) / umode->vdisplay; 1073 - oX = ((oY * aspect) + (aspect / 2)) >> 19; 1751 + if (asyh->view.oH < asyh->view.oW) { 1752 + u32 r = (asyh->view.iW << 19) / asyh->view.iH; 1753 + asyh->view.oW = ((asyh->view.oH * r) + (r / 2)) >> 19; 1074 1754 } else { 1075 - u32 aspect = (umode->vdisplay << 19) / umode->hdisplay; 1076 - oY = ((oX * aspect) + (aspect / 2)) >> 19; 1755 + u32 r = (asyh->view.iH << 19) / asyh->view.iW; 1756 + asyh->view.oH = ((asyh->view.oW * r) + (r / 2)) >> 19; 1077 1757 } 1078 1758 break; 1079 1759 default: 1080 1760 break; 1081 1761 } 1082 1762 1083 - push = evo_wait(mast, 8); 1084 - if (push) { 1085 - if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { 1086 - /*XXX: SCALE_CTRL_ACTIVE??? */ 1087 - evo_mthd(push, 0x08d8 + (nv_crtc->index * 0x400), 2); 1088 - evo_data(push, (oY << 16) | oX); 1089 - evo_data(push, (oY << 16) | oX); 1090 - evo_mthd(push, 0x08a4 + (nv_crtc->index * 0x400), 1); 1091 - evo_data(push, 0x00000000); 1092 - evo_mthd(push, 0x08c8 + (nv_crtc->index * 0x400), 1); 1093 - evo_data(push, umode->vdisplay << 16 | umode->hdisplay); 1094 - } else { 1095 - evo_mthd(push, 0x04c0 + (nv_crtc->index * 0x300), 3); 1096 - evo_data(push, (oY << 16) | oX); 1097 - evo_data(push, (oY << 16) | oX); 1098 - evo_data(push, (oY << 16) | oX); 1099 - evo_mthd(push, 0x0494 + (nv_crtc->index * 0x300), 1); 1100 - evo_data(push, 0x00000000); 1101 - evo_mthd(push, 0x04b8 + (nv_crtc->index * 0x300), 1); 1102 - evo_data(push, umode->vdisplay << 16 | umode->hdisplay); 1103 - } 1104 - 1105 - evo_kick(push, mast); 1106 - 1107 - if (update) { 1108 - nv50_display_flip_stop(crtc); 1109 - nv50_display_flip_next(crtc, crtc->primary->fb, 1110 - NULL, 1); 1111 - } 1112 - } 1113 - 1114 - return 0; 1115 - } 1116 - 1117 - static int 1118 - nv50_crtc_set_raster_vblank_dmi(struct nouveau_crtc *nv_crtc, u32 usec) 1119 - { 1120 - struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev); 1121 - u32 *push; 1122 - 1123 - push = evo_wait(mast, 8); 1124 - if (!push) 1125 - return -ENOMEM; 1126 - 1127 - evo_mthd(push, 0x0828 + (nv_crtc->index * 0x400), 1); 1128 - evo_data(push, usec); 1129 - evo_kick(push, mast); 1130 - return 0; 1131 - } 1132 - 1133 - static int 1134 - nv50_crtc_set_color_vibrance(struct nouveau_crtc *nv_crtc, bool update) 1135 - { 1136 - struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev); 1137 - u32 *push, hue, vib; 1138 - int adj; 1139 - 1140 - adj = (nv_crtc->color_vibrance > 0) ? 50 : 0; 1141 - vib = ((nv_crtc->color_vibrance * 2047 + adj) / 100) & 0xfff; 1142 - hue = ((nv_crtc->vibrant_hue * 2047) / 100) & 0xfff; 1143 - 1144 - push = evo_wait(mast, 16); 1145 - if (push) { 1146 - if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { 1147 - evo_mthd(push, 0x08a8 + (nv_crtc->index * 0x400), 1); 1148 - evo_data(push, (hue << 20) | (vib << 8)); 1149 - } else { 1150 - evo_mthd(push, 0x0498 + (nv_crtc->index * 0x300), 1); 1151 - evo_data(push, (hue << 20) | (vib << 8)); 1152 - } 1153 - 1154 - if (update) { 1155 - evo_mthd(push, 0x0080, 1); 1156 - evo_data(push, 0x00000000); 1157 - } 1158 - evo_kick(push, mast); 1159 - } 1160 - 1161 - return 0; 1162 - } 1163 - 1164 - static int 1165 - nv50_crtc_set_image(struct nouveau_crtc *nv_crtc, struct drm_framebuffer *fb, 1166 - int x, int y, bool update) 1167 - { 1168 - struct nouveau_framebuffer *nvfb = nouveau_framebuffer(fb); 1169 - struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev); 1170 - u32 *push; 1171 - 1172 - push = evo_wait(mast, 16); 1173 - if (push) { 1174 - if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { 1175 - evo_mthd(push, 0x0860 + (nv_crtc->index * 0x400), 1); 1176 - evo_data(push, nvfb->nvbo->bo.offset >> 8); 1177 - evo_mthd(push, 0x0868 + (nv_crtc->index * 0x400), 3); 1178 - evo_data(push, (fb->height << 16) | fb->width); 1179 - evo_data(push, nvfb->r_pitch); 1180 - evo_data(push, nvfb->r_format); 1181 - evo_mthd(push, 0x08c0 + (nv_crtc->index * 0x400), 1); 1182 - evo_data(push, (y << 16) | x); 1183 - if (nv50_vers(mast) > NV50_DISP_CORE_CHANNEL_DMA) { 1184 - evo_mthd(push, 0x0874 + (nv_crtc->index * 0x400), 1); 1185 - evo_data(push, nvfb->r_handle); 1186 - } 1187 - } else { 1188 - evo_mthd(push, 0x0460 + (nv_crtc->index * 0x300), 1); 1189 - evo_data(push, nvfb->nvbo->bo.offset >> 8); 1190 - evo_mthd(push, 0x0468 + (nv_crtc->index * 0x300), 4); 1191 - evo_data(push, (fb->height << 16) | fb->width); 1192 - evo_data(push, nvfb->r_pitch); 1193 - evo_data(push, nvfb->r_format); 1194 - evo_data(push, nvfb->r_handle); 1195 - evo_mthd(push, 0x04b0 + (nv_crtc->index * 0x300), 1); 1196 - evo_data(push, (y << 16) | x); 1197 - } 1198 - 1199 - if (update) { 1200 - evo_mthd(push, 0x0080, 1); 1201 - evo_data(push, 0x00000000); 1202 - } 1203 - evo_kick(push, mast); 1204 - } 1205 - 1206 - nv_crtc->fb.handle = nvfb->r_handle; 1207 - return 0; 1763 + asyh->set.view = true; 1208 1764 } 1209 1765 1210 1766 static void 1211 - nv50_crtc_cursor_show(struct nouveau_crtc *nv_crtc) 1767 + nv50_head_atomic_check_mode(struct nv50_head *head, struct nv50_head_atom *asyh) 1212 1768 { 1213 - struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev); 1214 - u32 *push = evo_wait(mast, 16); 1215 - if (push) { 1216 - if (nv50_vers(mast) < G82_DISP_CORE_CHANNEL_DMA) { 1217 - evo_mthd(push, 0x0880 + (nv_crtc->index * 0x400), 2); 1218 - evo_data(push, 0x85000000); 1219 - evo_data(push, nv_crtc->cursor.nvbo->bo.offset >> 8); 1220 - } else 1221 - if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { 1222 - evo_mthd(push, 0x0880 + (nv_crtc->index * 0x400), 2); 1223 - evo_data(push, 0x85000000); 1224 - evo_data(push, nv_crtc->cursor.nvbo->bo.offset >> 8); 1225 - evo_mthd(push, 0x089c + (nv_crtc->index * 0x400), 1); 1226 - evo_data(push, mast->base.vram.handle); 1227 - } else { 1228 - evo_mthd(push, 0x0480 + (nv_crtc->index * 0x300), 2); 1229 - evo_data(push, 0x85000000); 1230 - evo_data(push, nv_crtc->cursor.nvbo->bo.offset >> 8); 1231 - evo_mthd(push, 0x048c + (nv_crtc->index * 0x300), 1); 1232 - evo_data(push, mast->base.vram.handle); 1233 - } 1234 - evo_kick(push, mast); 1235 - } 1236 - nv_crtc->cursor.visible = true; 1237 - } 1769 + struct drm_display_mode *mode = &asyh->state.adjusted_mode; 1770 + u32 ilace = (mode->flags & DRM_MODE_FLAG_INTERLACE) ? 2 : 1; 1771 + u32 vscan = (mode->flags & DRM_MODE_FLAG_DBLSCAN) ? 2 : 1; 1772 + u32 hbackp = mode->htotal - mode->hsync_end; 1773 + u32 vbackp = (mode->vtotal - mode->vsync_end) * vscan / ilace; 1774 + u32 hfrontp = mode->hsync_start - mode->hdisplay; 1775 + u32 vfrontp = (mode->vsync_start - mode->vdisplay) * vscan / ilace; 1776 + struct nv50_head_mode *m = &asyh->mode; 1238 1777 1239 - static void 1240 - nv50_crtc_cursor_hide(struct nouveau_crtc *nv_crtc) 1241 - { 1242 - struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev); 1243 - u32 *push = evo_wait(mast, 16); 1244 - if (push) { 1245 - if (nv50_vers(mast) < G82_DISP_CORE_CHANNEL_DMA) { 1246 - evo_mthd(push, 0x0880 + (nv_crtc->index * 0x400), 1); 1247 - evo_data(push, 0x05000000); 1248 - } else 1249 - if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { 1250 - evo_mthd(push, 0x0880 + (nv_crtc->index * 0x400), 1); 1251 - evo_data(push, 0x05000000); 1252 - evo_mthd(push, 0x089c + (nv_crtc->index * 0x400), 1); 1253 - evo_data(push, 0x00000000); 1254 - } else { 1255 - evo_mthd(push, 0x0480 + (nv_crtc->index * 0x300), 1); 1256 - evo_data(push, 0x05000000); 1257 - evo_mthd(push, 0x048c + (nv_crtc->index * 0x300), 1); 1258 - evo_data(push, 0x00000000); 1259 - } 1260 - evo_kick(push, mast); 1261 - } 1262 - nv_crtc->cursor.visible = false; 1263 - } 1778 + m->h.active = mode->htotal; 1779 + m->h.synce = mode->hsync_end - mode->hsync_start - 1; 1780 + m->h.blanke = m->h.synce + hbackp; 1781 + m->h.blanks = mode->htotal - hfrontp - 1; 1264 1782 1265 - static void 1266 - nv50_crtc_cursor_show_hide(struct nouveau_crtc *nv_crtc, bool show, bool update) 1267 - { 1268 - struct nv50_mast *mast = nv50_mast(nv_crtc->base.dev); 1783 + m->v.active = mode->vtotal * vscan / ilace; 1784 + m->v.synce = ((mode->vsync_end - mode->vsync_start) * vscan / ilace) - 1; 1785 + m->v.blanke = m->v.synce + vbackp; 1786 + m->v.blanks = m->v.active - vfrontp - 1; 1269 1787 1270 - if (show && nv_crtc->cursor.nvbo && nv_crtc->base.enabled) 1271 - nv50_crtc_cursor_show(nv_crtc); 1272 - else 1273 - nv50_crtc_cursor_hide(nv_crtc); 1274 - 1275 - if (update) { 1276 - u32 *push = evo_wait(mast, 2); 1277 - if (push) { 1278 - evo_mthd(push, 0x0080, 1); 1279 - evo_data(push, 0x00000000); 1280 - evo_kick(push, mast); 1281 - } 1282 - } 1283 - } 1284 - 1285 - static void 1286 - nv50_crtc_dpms(struct drm_crtc *crtc, int mode) 1287 - { 1288 - } 1289 - 1290 - static void 1291 - nv50_crtc_prepare(struct drm_crtc *crtc) 1292 - { 1293 - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 1294 - struct nv50_mast *mast = nv50_mast(crtc->dev); 1295 - u32 *push; 1296 - 1297 - nv50_display_flip_stop(crtc); 1298 - 1299 - push = evo_wait(mast, 6); 1300 - if (push) { 1301 - if (nv50_vers(mast) < G82_DISP_CORE_CHANNEL_DMA) { 1302 - evo_mthd(push, 0x0874 + (nv_crtc->index * 0x400), 1); 1303 - evo_data(push, 0x00000000); 1304 - evo_mthd(push, 0x0840 + (nv_crtc->index * 0x400), 1); 1305 - evo_data(push, 0x40000000); 1306 - } else 1307 - if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { 1308 - evo_mthd(push, 0x0874 + (nv_crtc->index * 0x400), 1); 1309 - evo_data(push, 0x00000000); 1310 - evo_mthd(push, 0x0840 + (nv_crtc->index * 0x400), 1); 1311 - evo_data(push, 0x40000000); 1312 - evo_mthd(push, 0x085c + (nv_crtc->index * 0x400), 1); 1313 - evo_data(push, 0x00000000); 1314 - } else { 1315 - evo_mthd(push, 0x0474 + (nv_crtc->index * 0x300), 1); 1316 - evo_data(push, 0x00000000); 1317 - evo_mthd(push, 0x0440 + (nv_crtc->index * 0x300), 1); 1318 - evo_data(push, 0x03000000); 1319 - evo_mthd(push, 0x045c + (nv_crtc->index * 0x300), 1); 1320 - evo_data(push, 0x00000000); 1321 - } 1322 - 1323 - evo_kick(push, mast); 1324 - } 1325 - 1326 - nv50_crtc_cursor_show_hide(nv_crtc, false, false); 1327 - } 1328 - 1329 - static void 1330 - nv50_crtc_commit(struct drm_crtc *crtc) 1331 - { 1332 - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 1333 - struct nv50_mast *mast = nv50_mast(crtc->dev); 1334 - u32 *push; 1335 - 1336 - push = evo_wait(mast, 32); 1337 - if (push) { 1338 - if (nv50_vers(mast) < G82_DISP_CORE_CHANNEL_DMA) { 1339 - evo_mthd(push, 0x0874 + (nv_crtc->index * 0x400), 1); 1340 - evo_data(push, nv_crtc->fb.handle); 1341 - evo_mthd(push, 0x0840 + (nv_crtc->index * 0x400), 2); 1342 - evo_data(push, 0xc0000000); 1343 - evo_data(push, nv_crtc->lut.nvbo->bo.offset >> 8); 1344 - } else 1345 - if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { 1346 - evo_mthd(push, 0x0874 + (nv_crtc->index * 0x400), 1); 1347 - evo_data(push, nv_crtc->fb.handle); 1348 - evo_mthd(push, 0x0840 + (nv_crtc->index * 0x400), 2); 1349 - evo_data(push, 0xc0000000); 1350 - evo_data(push, nv_crtc->lut.nvbo->bo.offset >> 8); 1351 - evo_mthd(push, 0x085c + (nv_crtc->index * 0x400), 1); 1352 - evo_data(push, mast->base.vram.handle); 1353 - } else { 1354 - evo_mthd(push, 0x0474 + (nv_crtc->index * 0x300), 1); 1355 - evo_data(push, nv_crtc->fb.handle); 1356 - evo_mthd(push, 0x0440 + (nv_crtc->index * 0x300), 4); 1357 - evo_data(push, 0x83000000); 1358 - evo_data(push, nv_crtc->lut.nvbo->bo.offset >> 8); 1359 - evo_data(push, 0x00000000); 1360 - evo_data(push, 0x00000000); 1361 - evo_mthd(push, 0x045c + (nv_crtc->index * 0x300), 1); 1362 - evo_data(push, mast->base.vram.handle); 1363 - evo_mthd(push, 0x0430 + (nv_crtc->index * 0x300), 1); 1364 - evo_data(push, 0xffffff00); 1365 - } 1366 - 1367 - evo_kick(push, mast); 1368 - } 1369 - 1370 - nv50_crtc_cursor_show_hide(nv_crtc, true, true); 1371 - nv50_display_flip_next(crtc, crtc->primary->fb, NULL, 1); 1372 - } 1373 - 1374 - static bool 1375 - nv50_crtc_mode_fixup(struct drm_crtc *crtc, const struct drm_display_mode *mode, 1376 - struct drm_display_mode *adjusted_mode) 1377 - { 1378 - drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V); 1379 - return true; 1380 - } 1381 - 1382 - static int 1383 - nv50_crtc_swap_fbs(struct drm_crtc *crtc, struct drm_framebuffer *old_fb) 1384 - { 1385 - struct nouveau_framebuffer *nvfb = nouveau_framebuffer(crtc->primary->fb); 1386 - struct nv50_head *head = nv50_head(crtc); 1387 - int ret; 1388 - 1389 - ret = nouveau_bo_pin(nvfb->nvbo, TTM_PL_FLAG_VRAM, true); 1390 - if (ret == 0) { 1391 - if (head->image) 1392 - nouveau_bo_unpin(head->image); 1393 - nouveau_bo_ref(nvfb->nvbo, &head->image); 1394 - } 1395 - 1396 - return ret; 1397 - } 1398 - 1399 - static int 1400 - nv50_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *umode, 1401 - struct drm_display_mode *mode, int x, int y, 1402 - struct drm_framebuffer *old_fb) 1403 - { 1404 - struct nv50_mast *mast = nv50_mast(crtc->dev); 1405 - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 1406 - struct nouveau_connector *nv_connector; 1407 - u32 ilace = (mode->flags & DRM_MODE_FLAG_INTERLACE) ? 2 : 1; 1408 - u32 vscan = (mode->flags & DRM_MODE_FLAG_DBLSCAN) ? 2 : 1; 1409 - u32 hactive, hsynce, hbackp, hfrontp, hblanke, hblanks; 1410 - u32 vactive, vsynce, vbackp, vfrontp, vblanke, vblanks; 1411 - u32 vblan2e = 0, vblan2s = 1, vblankus = 0; 1412 - u32 *push; 1413 - int ret; 1414 - 1415 - hactive = mode->htotal; 1416 - hsynce = mode->hsync_end - mode->hsync_start - 1; 1417 - hbackp = mode->htotal - mode->hsync_end; 1418 - hblanke = hsynce + hbackp; 1419 - hfrontp = mode->hsync_start - mode->hdisplay; 1420 - hblanks = mode->htotal - hfrontp - 1; 1421 - 1422 - vactive = mode->vtotal * vscan / ilace; 1423 - vsynce = ((mode->vsync_end - mode->vsync_start) * vscan / ilace) - 1; 1424 - vbackp = (mode->vtotal - mode->vsync_end) * vscan / ilace; 1425 - vblanke = vsynce + vbackp; 1426 - vfrontp = (mode->vsync_start - mode->vdisplay) * vscan / ilace; 1427 - vblanks = vactive - vfrontp - 1; 1428 - /* XXX: Safe underestimate, even "0" works */ 1429 - vblankus = (vactive - mode->vdisplay - 2) * hactive; 1430 - vblankus *= 1000; 1431 - vblankus /= mode->clock; 1788 + /*XXX: Safe underestimate, even "0" works */ 1789 + m->v.blankus = (m->v.active - mode->vdisplay - 2) * m->h.active; 1790 + m->v.blankus *= 1000; 1791 + m->v.blankus /= mode->clock; 1432 1792 1433 1793 if (mode->flags & DRM_MODE_FLAG_INTERLACE) { 1434 - vblan2e = vactive + vsynce + vbackp; 1435 - vblan2s = vblan2e + (mode->vdisplay * vscan / ilace); 1436 - vactive = (vactive * 2) + 1; 1794 + m->v.blank2e = m->v.active + m->v.synce + vbackp; 1795 + m->v.blank2s = m->v.blank2e + (mode->vdisplay * vscan / ilace); 1796 + m->v.active = (m->v.active * 2) + 1; 1797 + m->interlace = true; 1798 + } else { 1799 + m->v.blank2e = 0; 1800 + m->v.blank2s = 1; 1801 + m->interlace = false; 1437 1802 } 1803 + m->clock = mode->clock; 1438 1804 1439 - ret = nv50_crtc_swap_fbs(crtc, old_fb); 1440 - if (ret) 1441 - return ret; 1442 - 1443 - push = evo_wait(mast, 64); 1444 - if (push) { 1445 - if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { 1446 - evo_mthd(push, 0x0804 + (nv_crtc->index * 0x400), 2); 1447 - evo_data(push, 0x00800000 | mode->clock); 1448 - evo_data(push, (ilace == 2) ? 2 : 0); 1449 - evo_mthd(push, 0x0810 + (nv_crtc->index * 0x400), 6); 1450 - evo_data(push, 0x00000000); 1451 - evo_data(push, (vactive << 16) | hactive); 1452 - evo_data(push, ( vsynce << 16) | hsynce); 1453 - evo_data(push, (vblanke << 16) | hblanke); 1454 - evo_data(push, (vblanks << 16) | hblanks); 1455 - evo_data(push, (vblan2e << 16) | vblan2s); 1456 - evo_mthd(push, 0x082c + (nv_crtc->index * 0x400), 1); 1457 - evo_data(push, 0x00000000); 1458 - evo_mthd(push, 0x0900 + (nv_crtc->index * 0x400), 2); 1459 - evo_data(push, 0x00000311); 1460 - evo_data(push, 0x00000100); 1461 - } else { 1462 - evo_mthd(push, 0x0410 + (nv_crtc->index * 0x300), 6); 1463 - evo_data(push, 0x00000000); 1464 - evo_data(push, (vactive << 16) | hactive); 1465 - evo_data(push, ( vsynce << 16) | hsynce); 1466 - evo_data(push, (vblanke << 16) | hblanke); 1467 - evo_data(push, (vblanks << 16) | hblanks); 1468 - evo_data(push, (vblan2e << 16) | vblan2s); 1469 - evo_mthd(push, 0x042c + (nv_crtc->index * 0x300), 1); 1470 - evo_data(push, 0x00000000); /* ??? */ 1471 - evo_mthd(push, 0x0450 + (nv_crtc->index * 0x300), 3); 1472 - evo_data(push, mode->clock * 1000); 1473 - evo_data(push, 0x00200000); /* ??? */ 1474 - evo_data(push, mode->clock * 1000); 1475 - evo_mthd(push, 0x04d0 + (nv_crtc->index * 0x300), 2); 1476 - evo_data(push, 0x00000311); 1477 - evo_data(push, 0x00000100); 1478 - } 1479 - 1480 - evo_kick(push, mast); 1481 - } 1482 - 1483 - nv_connector = nouveau_crtc_connector_get(nv_crtc); 1484 - nv50_crtc_set_dither(nv_crtc, false); 1485 - nv50_crtc_set_scale(nv_crtc, false); 1486 - 1487 - /* G94 only accepts this after setting scale */ 1488 - if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) 1489 - nv50_crtc_set_raster_vblank_dmi(nv_crtc, vblankus); 1490 - 1491 - nv50_crtc_set_color_vibrance(nv_crtc, false); 1492 - nv50_crtc_set_image(nv_crtc, crtc->primary->fb, x, y, false); 1493 - return 0; 1805 + drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); 1806 + asyh->set.mode = true; 1494 1807 } 1495 1808 1496 1809 static int 1497 - nv50_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, 1498 - struct drm_framebuffer *old_fb) 1810 + nv50_head_atomic_check(struct drm_crtc *crtc, struct drm_crtc_state *state) 1499 1811 { 1500 1812 struct nouveau_drm *drm = nouveau_drm(crtc->dev); 1501 - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 1502 - int ret; 1813 + struct nv50_disp *disp = nv50_disp(crtc->dev); 1814 + struct nv50_head *head = nv50_head(crtc); 1815 + struct nv50_head_atom *armh = nv50_head_atom(crtc->state); 1816 + struct nv50_head_atom *asyh = nv50_head_atom(state); 1817 + struct nouveau_conn_atom *asyc = NULL; 1818 + struct drm_connector_state *conns; 1819 + struct drm_connector *conn; 1820 + int i; 1503 1821 1504 - if (!crtc->primary->fb) { 1505 - NV_DEBUG(drm, "No FB bound\n"); 1506 - return 0; 1822 + NV_ATOMIC(drm, "%s atomic_check %d\n", crtc->name, asyh->state.active); 1823 + if (asyh->state.active) { 1824 + for_each_connector_in_state(asyh->state.state, conn, conns, i) { 1825 + if (conns->crtc == crtc) { 1826 + asyc = nouveau_conn_atom(conns); 1827 + break; 1828 + } 1829 + } 1830 + 1831 + if (armh->state.active) { 1832 + if (asyc) { 1833 + if (asyh->state.mode_changed) 1834 + asyc->set.scaler = true; 1835 + if (armh->base.depth != asyh->base.depth) 1836 + asyc->set.dither = true; 1837 + } 1838 + } else { 1839 + asyc->set.mask = ~0; 1840 + asyh->set.mask = ~0; 1841 + } 1842 + 1843 + if (asyh->state.mode_changed) 1844 + nv50_head_atomic_check_mode(head, asyh); 1845 + 1846 + if (asyc) { 1847 + if (asyc->set.scaler) 1848 + nv50_head_atomic_check_view(armh, asyh, asyc); 1849 + if (asyc->set.dither) 1850 + nv50_head_atomic_check_dither(armh, asyh, asyc); 1851 + if (asyc->set.procamp) 1852 + nv50_head_atomic_check_procamp(armh, asyh, asyc); 1853 + } 1854 + 1855 + if ((asyh->core.visible = (asyh->base.cpp != 0))) { 1856 + asyh->core.x = asyh->base.x; 1857 + asyh->core.y = asyh->base.y; 1858 + asyh->core.w = asyh->base.w; 1859 + asyh->core.h = asyh->base.h; 1860 + } else 1861 + if ((asyh->core.visible = asyh->curs.visible)) { 1862 + /*XXX: We need to either find some way of having the 1863 + * primary base layer appear black, while still 1864 + * being able to display the other layers, or we 1865 + * need to allocate a dummy black surface here. 1866 + */ 1867 + asyh->core.x = 0; 1868 + asyh->core.y = 0; 1869 + asyh->core.w = asyh->state.mode.hdisplay; 1870 + asyh->core.h = asyh->state.mode.vdisplay; 1871 + } 1872 + asyh->core.handle = disp->mast.base.vram.handle; 1873 + asyh->core.offset = 0; 1874 + asyh->core.format = 0xcf; 1875 + asyh->core.kind = 0; 1876 + asyh->core.layout = 1; 1877 + asyh->core.block = 0; 1878 + asyh->core.pitch = ALIGN(asyh->core.w, 64) * 4; 1879 + asyh->lut.handle = disp->mast.base.vram.handle; 1880 + asyh->lut.offset = head->base.lut.nvbo->bo.offset; 1881 + asyh->set.base = armh->base.cpp != asyh->base.cpp; 1882 + asyh->set.ovly = armh->ovly.cpp != asyh->ovly.cpp; 1883 + } else { 1884 + asyh->core.visible = false; 1885 + asyh->curs.visible = false; 1886 + asyh->base.cpp = 0; 1887 + asyh->ovly.cpp = 0; 1507 1888 } 1508 1889 1509 - ret = nv50_crtc_swap_fbs(crtc, old_fb); 1510 - if (ret) 1511 - return ret; 1890 + if (!drm_atomic_crtc_needs_modeset(&asyh->state)) { 1891 + if (asyh->core.visible) { 1892 + if (memcmp(&armh->core, &asyh->core, sizeof(asyh->core))) 1893 + asyh->set.core = true; 1894 + } else 1895 + if (armh->core.visible) { 1896 + asyh->clr.core = true; 1897 + } 1512 1898 1513 - nv50_display_flip_stop(crtc); 1514 - nv50_crtc_set_image(nv_crtc, crtc->primary->fb, x, y, true); 1515 - nv50_display_flip_next(crtc, crtc->primary->fb, NULL, 1); 1516 - return 0; 1517 - } 1899 + if (asyh->curs.visible) { 1900 + if (memcmp(&armh->curs, &asyh->curs, sizeof(asyh->curs))) 1901 + asyh->set.curs = true; 1902 + } else 1903 + if (armh->curs.visible) { 1904 + asyh->clr.curs = true; 1905 + } 1906 + } else { 1907 + asyh->clr.core = armh->core.visible; 1908 + asyh->clr.curs = armh->curs.visible; 1909 + asyh->set.core = asyh->core.visible; 1910 + asyh->set.curs = asyh->curs.visible; 1911 + } 1518 1912 1519 - static int 1520 - nv50_crtc_mode_set_base_atomic(struct drm_crtc *crtc, 1521 - struct drm_framebuffer *fb, int x, int y, 1522 - enum mode_set_atomic state) 1523 - { 1524 - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 1525 - nv50_display_flip_stop(crtc); 1526 - nv50_crtc_set_image(nv_crtc, fb, x, y, true); 1913 + if (asyh->clr.mask || asyh->set.mask) 1914 + nv50_atom(asyh->state.state)->lock_core = true; 1527 1915 return 0; 1528 1916 } 1529 1917 1530 1918 static void 1531 - nv50_crtc_lut_load(struct drm_crtc *crtc) 1919 + nv50_head_lut_load(struct drm_crtc *crtc) 1532 1920 { 1533 1921 struct nv50_disp *disp = nv50_disp(crtc->dev); 1534 1922 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ··· 2200 1292 } 2201 1293 } 2202 1294 2203 - static void 2204 - nv50_crtc_disable(struct drm_crtc *crtc) 2205 - { 2206 - struct nv50_head *head = nv50_head(crtc); 2207 - evo_sync(crtc->dev); 2208 - if (head->image) 2209 - nouveau_bo_unpin(head->image); 2210 - nouveau_bo_ref(NULL, &head->image); 2211 - } 2212 - 2213 1295 static int 2214 - nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, 2215 - uint32_t handle, uint32_t width, uint32_t height) 1296 + nv50_head_mode_set_base_atomic(struct drm_crtc *crtc, 1297 + struct drm_framebuffer *fb, int x, int y, 1298 + enum mode_set_atomic state) 2216 1299 { 2217 - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 2218 - struct drm_gem_object *gem = NULL; 2219 - struct nouveau_bo *nvbo = NULL; 2220 - int ret = 0; 2221 - 2222 - if (handle) { 2223 - if (width != 64 || height != 64) 2224 - return -EINVAL; 2225 - 2226 - gem = drm_gem_object_lookup(file_priv, handle); 2227 - if (unlikely(!gem)) 2228 - return -ENOENT; 2229 - nvbo = nouveau_gem_object(gem); 2230 - 2231 - ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM, true); 2232 - } 2233 - 2234 - if (ret == 0) { 2235 - if (nv_crtc->cursor.nvbo) 2236 - nouveau_bo_unpin(nv_crtc->cursor.nvbo); 2237 - nouveau_bo_ref(nvbo, &nv_crtc->cursor.nvbo); 2238 - } 2239 - drm_gem_object_unreference_unlocked(gem); 2240 - 2241 - nv50_crtc_cursor_show_hide(nv_crtc, true, true); 2242 - return ret; 2243 - } 2244 - 2245 - static int 2246 - nv50_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) 2247 - { 2248 - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 2249 - struct nv50_curs *curs = nv50_curs(crtc); 2250 - struct nv50_chan *chan = nv50_chan(curs); 2251 - nvif_wr32(&chan->user, 0x0084, (y << 16) | (x & 0xffff)); 2252 - nvif_wr32(&chan->user, 0x0080, 0x00000000); 2253 - 2254 - nv_crtc->cursor_saved_x = x; 2255 - nv_crtc->cursor_saved_y = y; 1300 + WARN_ON(1); 2256 1301 return 0; 2257 1302 } 2258 1303 1304 + static const struct drm_crtc_helper_funcs 1305 + nv50_head_help = { 1306 + .mode_set_base_atomic = nv50_head_mode_set_base_atomic, 1307 + .load_lut = nv50_head_lut_load, 1308 + .atomic_check = nv50_head_atomic_check, 1309 + }; 1310 + 1311 + /* This is identical to the version in the atomic helpers, except that 1312 + * it supports non-vblanked ("async") page flips. 1313 + */ 2259 1314 static int 2260 - nv50_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, 1315 + nv50_head_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, 1316 + struct drm_pending_vblank_event *event, u32 flags) 1317 + { 1318 + struct drm_plane *plane = crtc->primary; 1319 + struct drm_atomic_state *state; 1320 + struct drm_plane_state *plane_state; 1321 + struct drm_crtc_state *crtc_state; 1322 + int ret = 0; 1323 + 1324 + state = drm_atomic_state_alloc(plane->dev); 1325 + if (!state) 1326 + return -ENOMEM; 1327 + 1328 + state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc); 1329 + retry: 1330 + crtc_state = drm_atomic_get_crtc_state(state, crtc); 1331 + if (IS_ERR(crtc_state)) { 1332 + ret = PTR_ERR(crtc_state); 1333 + goto fail; 1334 + } 1335 + crtc_state->event = event; 1336 + 1337 + plane_state = drm_atomic_get_plane_state(state, plane); 1338 + if (IS_ERR(plane_state)) { 1339 + ret = PTR_ERR(plane_state); 1340 + goto fail; 1341 + } 1342 + 1343 + ret = drm_atomic_set_crtc_for_plane(plane_state, crtc); 1344 + if (ret != 0) 1345 + goto fail; 1346 + drm_atomic_set_fb_for_plane(plane_state, fb); 1347 + 1348 + /* Make sure we don't accidentally do a full modeset. */ 1349 + state->allow_modeset = false; 1350 + if (!crtc_state->active) { 1351 + DRM_DEBUG_ATOMIC("[CRTC:%d] disabled, rejecting legacy flip\n", 1352 + crtc->base.id); 1353 + ret = -EINVAL; 1354 + goto fail; 1355 + } 1356 + 1357 + if (flags & DRM_MODE_PAGE_FLIP_ASYNC) 1358 + nv50_wndw_atom(plane_state)->interval = 0; 1359 + 1360 + ret = drm_atomic_nonblocking_commit(state); 1361 + fail: 1362 + if (ret == -EDEADLK) 1363 + goto backoff; 1364 + 1365 + drm_atomic_state_put(state); 1366 + return ret; 1367 + 1368 + backoff: 1369 + drm_atomic_state_clear(state); 1370 + drm_atomic_legacy_backoff(state); 1371 + 1372 + /* 1373 + * Someone might have exchanged the framebuffer while we dropped locks 1374 + * in the backoff code. We need to fix up the fb refcount tracking the 1375 + * core does for us. 1376 + */ 1377 + plane->old_fb = plane->fb; 1378 + 1379 + goto retry; 1380 + } 1381 + 1382 + static int 1383 + nv50_head_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, 2261 1384 uint32_t size) 2262 1385 { 2263 1386 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); ··· 2300 1361 nv_crtc->lut.b[i] = b[i]; 2301 1362 } 2302 1363 2303 - nv50_crtc_lut_load(crtc); 2304 - 1364 + nv50_head_lut_load(crtc); 2305 1365 return 0; 2306 1366 } 2307 1367 2308 1368 static void 2309 - nv50_crtc_cursor_restore(struct nouveau_crtc *nv_crtc, int x, int y) 1369 + nv50_head_atomic_destroy_state(struct drm_crtc *crtc, 1370 + struct drm_crtc_state *state) 2310 1371 { 2311 - nv50_crtc_cursor_move(&nv_crtc->base, x, y); 1372 + struct nv50_head_atom *asyh = nv50_head_atom(state); 1373 + __drm_atomic_helper_crtc_destroy_state(&asyh->state); 1374 + kfree(asyh); 1375 + } 2312 1376 2313 - nv50_crtc_cursor_show_hide(nv_crtc, true, true); 1377 + static struct drm_crtc_state * 1378 + nv50_head_atomic_duplicate_state(struct drm_crtc *crtc) 1379 + { 1380 + struct nv50_head_atom *armh = nv50_head_atom(crtc->state); 1381 + struct nv50_head_atom *asyh; 1382 + if (!(asyh = kmalloc(sizeof(*asyh), GFP_KERNEL))) 1383 + return NULL; 1384 + __drm_atomic_helper_crtc_duplicate_state(crtc, &asyh->state); 1385 + asyh->view = armh->view; 1386 + asyh->mode = armh->mode; 1387 + asyh->lut = armh->lut; 1388 + asyh->core = armh->core; 1389 + asyh->curs = armh->curs; 1390 + asyh->base = armh->base; 1391 + asyh->ovly = armh->ovly; 1392 + asyh->dither = armh->dither; 1393 + asyh->procamp = armh->procamp; 1394 + asyh->clr.mask = 0; 1395 + asyh->set.mask = 0; 1396 + return &asyh->state; 2314 1397 } 2315 1398 2316 1399 static void 2317 - nv50_crtc_destroy(struct drm_crtc *crtc) 1400 + __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc, 1401 + struct drm_crtc_state *state) 1402 + { 1403 + if (crtc->state) 1404 + crtc->funcs->atomic_destroy_state(crtc, crtc->state); 1405 + crtc->state = state; 1406 + crtc->state->crtc = crtc; 1407 + } 1408 + 1409 + static void 1410 + nv50_head_reset(struct drm_crtc *crtc) 1411 + { 1412 + struct nv50_head_atom *asyh; 1413 + 1414 + if (WARN_ON(!(asyh = kzalloc(sizeof(*asyh), GFP_KERNEL)))) 1415 + return; 1416 + 1417 + __drm_atomic_helper_crtc_reset(crtc, &asyh->state); 1418 + } 1419 + 1420 + static void 1421 + nv50_head_destroy(struct drm_crtc *crtc) 2318 1422 { 2319 1423 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 2320 1424 struct nv50_disp *disp = nv50_disp(crtc->dev); 2321 1425 struct nv50_head *head = nv50_head(crtc); 2322 - struct nv50_fbdma *fbdma; 2323 - 2324 - list_for_each_entry(fbdma, &disp->fbdma, head) { 2325 - nvif_object_fini(&fbdma->base[nv_crtc->index]); 2326 - } 2327 1426 2328 1427 nv50_dmac_destroy(&head->ovly.base, disp->disp); 2329 1428 nv50_pioc_destroy(&head->oimm.base); 2330 - nv50_dmac_destroy(&head->sync.base, disp->disp); 2331 - nv50_pioc_destroy(&head->curs.base); 2332 - 2333 - /*XXX: this shouldn't be necessary, but the core doesn't call 2334 - * disconnect() during the cleanup paths 2335 - */ 2336 - if (head->image) 2337 - nouveau_bo_unpin(head->image); 2338 - nouveau_bo_ref(NULL, &head->image); 2339 - 2340 - /*XXX: ditto */ 2341 - if (nv_crtc->cursor.nvbo) 2342 - nouveau_bo_unpin(nv_crtc->cursor.nvbo); 2343 - nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo); 2344 1429 2345 1430 nouveau_bo_unmap(nv_crtc->lut.nvbo); 2346 1431 if (nv_crtc->lut.nvbo) ··· 2375 1412 kfree(crtc); 2376 1413 } 2377 1414 2378 - static const struct drm_crtc_helper_funcs nv50_crtc_hfunc = { 2379 - .dpms = nv50_crtc_dpms, 2380 - .prepare = nv50_crtc_prepare, 2381 - .commit = nv50_crtc_commit, 2382 - .mode_fixup = nv50_crtc_mode_fixup, 2383 - .mode_set = nv50_crtc_mode_set, 2384 - .mode_set_base = nv50_crtc_mode_set_base, 2385 - .mode_set_base_atomic = nv50_crtc_mode_set_base_atomic, 2386 - .load_lut = nv50_crtc_lut_load, 2387 - .disable = nv50_crtc_disable, 2388 - }; 2389 - 2390 - static const struct drm_crtc_funcs nv50_crtc_func = { 2391 - .cursor_set = nv50_crtc_cursor_set, 2392 - .cursor_move = nv50_crtc_cursor_move, 2393 - .gamma_set = nv50_crtc_gamma_set, 2394 - .set_config = nouveau_crtc_set_config, 2395 - .destroy = nv50_crtc_destroy, 2396 - .page_flip = nouveau_crtc_page_flip, 1415 + static const struct drm_crtc_funcs 1416 + nv50_head_func = { 1417 + .reset = nv50_head_reset, 1418 + .gamma_set = nv50_head_gamma_set, 1419 + .destroy = nv50_head_destroy, 1420 + .set_config = drm_atomic_helper_set_config, 1421 + .page_flip = nv50_head_page_flip, 1422 + .set_property = drm_atomic_helper_crtc_set_property, 1423 + .atomic_duplicate_state = nv50_head_atomic_duplicate_state, 1424 + .atomic_destroy_state = nv50_head_atomic_destroy_state, 2397 1425 }; 2398 1426 2399 1427 static int 2400 - nv50_crtc_create(struct drm_device *dev, int index) 1428 + nv50_head_create(struct drm_device *dev, int index) 2401 1429 { 2402 1430 struct nouveau_drm *drm = nouveau_drm(dev); 2403 1431 struct nvif_device *device = &drm->device; 2404 1432 struct nv50_disp *disp = nv50_disp(dev); 2405 1433 struct nv50_head *head; 1434 + struct nv50_base *base; 1435 + struct nv50_curs *curs; 2406 1436 struct drm_crtc *crtc; 2407 1437 int ret, i; 2408 1438 ··· 2404 1448 return -ENOMEM; 2405 1449 2406 1450 head->base.index = index; 2407 - head->base.set_dither = nv50_crtc_set_dither; 2408 - head->base.set_scale = nv50_crtc_set_scale; 2409 - head->base.set_color_vibrance = nv50_crtc_set_color_vibrance; 2410 - head->base.color_vibrance = 50; 2411 - head->base.vibrant_hue = 0; 2412 - head->base.cursor.set_pos = nv50_crtc_cursor_restore; 2413 1451 for (i = 0; i < 256; i++) { 2414 1452 head->base.lut.r[i] = i << 8; 2415 1453 head->base.lut.g[i] = i << 8; 2416 1454 head->base.lut.b[i] = i << 8; 2417 1455 } 2418 1456 1457 + ret = nv50_base_new(drm, head, &base); 1458 + if (ret == 0) 1459 + ret = nv50_curs_new(drm, head, &curs); 1460 + if (ret) { 1461 + kfree(head); 1462 + return ret; 1463 + } 1464 + 2419 1465 crtc = &head->base.base; 2420 - drm_crtc_init(dev, crtc, &nv50_crtc_func); 2421 - drm_crtc_helper_add(crtc, &nv50_crtc_hfunc); 1466 + drm_crtc_init_with_planes(dev, crtc, &base->wndw.plane, 1467 + &curs->wndw.plane, &nv50_head_func, 1468 + "head-%d", head->base.index); 1469 + drm_crtc_helper_add(crtc, &nv50_head_help); 2422 1470 drm_mode_crtc_set_gamma_size(crtc, 256); 2423 1471 2424 1472 ret = nouveau_bo_new(dev, 8192, 0x100, TTM_PL_FLAG_VRAM, ··· 2441 1481 if (ret) 2442 1482 goto out; 2443 1483 2444 - /* allocate cursor resources */ 2445 - ret = nv50_curs_create(device, disp->disp, index, &head->curs); 2446 - if (ret) 2447 - goto out; 2448 - 2449 - /* allocate page flip / sync resources */ 2450 - ret = nv50_base_create(device, disp->disp, index, disp->sync->bo.offset, 2451 - &head->sync); 2452 - if (ret) 2453 - goto out; 2454 - 2455 - head->sync.addr = EVO_FLIP_SEM0(index); 2456 - head->sync.data = 0x00000000; 2457 - 2458 1484 /* allocate overlay resources */ 2459 1485 ret = nv50_oimm_create(device, disp->disp, index, &head->oimm); 2460 1486 if (ret) ··· 2453 1507 2454 1508 out: 2455 1509 if (ret) 2456 - nv50_crtc_destroy(crtc); 1510 + nv50_head_destroy(crtc); 2457 1511 return ret; 2458 1512 } 2459 1513 2460 1514 /****************************************************************************** 2461 - * Encoder helpers 1515 + * Output path helpers 2462 1516 *****************************************************************************/ 2463 - static bool 2464 - nv50_encoder_mode_fixup(struct drm_encoder *encoder, 2465 - const struct drm_display_mode *mode, 2466 - struct drm_display_mode *adjusted_mode) 1517 + static int 1518 + nv50_outp_atomic_check_view(struct drm_encoder *encoder, 1519 + struct drm_crtc_state *crtc_state, 1520 + struct drm_connector_state *conn_state, 1521 + struct drm_display_mode *native_mode) 2467 1522 { 2468 - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 2469 - struct nouveau_connector *nv_connector; 1523 + struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode; 1524 + struct drm_display_mode *mode = &crtc_state->mode; 1525 + struct drm_connector *connector = conn_state->connector; 1526 + struct nouveau_conn_atom *asyc = nouveau_conn_atom(conn_state); 1527 + struct nouveau_drm *drm = nouveau_drm(encoder->dev); 2470 1528 2471 - nv_connector = nouveau_encoder_connector_get(nv_encoder); 2472 - if (nv_connector && nv_connector->native_mode) { 2473 - nv_connector->scaling_full = false; 2474 - if (nv_connector->scaling_mode == DRM_MODE_SCALE_NONE) { 2475 - switch (nv_connector->type) { 2476 - case DCB_CONNECTOR_LVDS: 2477 - case DCB_CONNECTOR_LVDS_SPWG: 2478 - case DCB_CONNECTOR_eDP: 2479 - /* force use of scaler for non-edid modes */ 2480 - if (adjusted_mode->type & DRM_MODE_TYPE_DRIVER) 2481 - return true; 2482 - nv_connector->scaling_full = true; 1529 + NV_ATOMIC(drm, "%s atomic_check\n", encoder->name); 1530 + asyc->scaler.full = false; 1531 + if (!native_mode) 1532 + return 0; 1533 + 1534 + if (asyc->scaler.mode == DRM_MODE_SCALE_NONE) { 1535 + switch (connector->connector_type) { 1536 + case DRM_MODE_CONNECTOR_LVDS: 1537 + case DRM_MODE_CONNECTOR_eDP: 1538 + /* Force use of scaler for non-EDID modes. */ 1539 + if (adjusted_mode->type & DRM_MODE_TYPE_DRIVER) 2483 1540 break; 2484 - default: 2485 - return true; 2486 - } 1541 + mode = native_mode; 1542 + asyc->scaler.full = true; 1543 + break; 1544 + default: 1545 + break; 2487 1546 } 2488 - 2489 - drm_mode_copy(adjusted_mode, nv_connector->native_mode); 1547 + } else { 1548 + mode = native_mode; 2490 1549 } 2491 1550 2492 - return true; 1551 + if (!drm_mode_equal(adjusted_mode, mode)) { 1552 + drm_mode_copy(adjusted_mode, mode); 1553 + crtc_state->mode_changed = true; 1554 + } 1555 + 1556 + return 0; 1557 + } 1558 + 1559 + static int 1560 + nv50_outp_atomic_check(struct drm_encoder *encoder, 1561 + struct drm_crtc_state *crtc_state, 1562 + struct drm_connector_state *conn_state) 1563 + { 1564 + struct nouveau_connector *nv_connector = 1565 + nouveau_connector(conn_state->connector); 1566 + return nv50_outp_atomic_check_view(encoder, crtc_state, conn_state, 1567 + nv_connector->native_mode); 2493 1568 } 2494 1569 2495 1570 /****************************************************************************** ··· 2541 1574 } 2542 1575 2543 1576 static void 2544 - nv50_dac_commit(struct drm_encoder *encoder) 1577 + nv50_dac_disable(struct drm_encoder *encoder) 2545 1578 { 1579 + struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 1580 + struct nv50_mast *mast = nv50_mast(encoder->dev); 1581 + const int or = nv_encoder->or; 1582 + u32 *push; 1583 + 1584 + if (nv_encoder->crtc) { 1585 + push = evo_wait(mast, 4); 1586 + if (push) { 1587 + if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { 1588 + evo_mthd(push, 0x0400 + (or * 0x080), 1); 1589 + evo_data(push, 0x00000000); 1590 + } else { 1591 + evo_mthd(push, 0x0180 + (or * 0x020), 1); 1592 + evo_data(push, 0x00000000); 1593 + } 1594 + evo_kick(push, mast); 1595 + } 1596 + } 1597 + 1598 + nv_encoder->crtc = NULL; 2546 1599 } 2547 1600 2548 1601 static void 2549 - nv50_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, 2550 - struct drm_display_mode *adjusted_mode) 1602 + nv50_dac_enable(struct drm_encoder *encoder) 2551 1603 { 2552 1604 struct nv50_mast *mast = nv50_mast(encoder->dev); 2553 1605 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 2554 1606 struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); 1607 + struct drm_display_mode *mode = &nv_crtc->base.state->adjusted_mode; 2555 1608 u32 *push; 2556 - 2557 - nv50_dac_dpms(encoder, DRM_MODE_DPMS_ON); 2558 1609 2559 1610 push = evo_wait(mast, 8); 2560 1611 if (push) { ··· 2612 1627 nv_encoder->crtc = encoder->crtc; 2613 1628 } 2614 1629 2615 - static void 2616 - nv50_dac_disconnect(struct drm_encoder *encoder) 2617 - { 2618 - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 2619 - struct nv50_mast *mast = nv50_mast(encoder->dev); 2620 - const int or = nv_encoder->or; 2621 - u32 *push; 2622 - 2623 - if (nv_encoder->crtc) { 2624 - nv50_crtc_prepare(nv_encoder->crtc); 2625 - 2626 - push = evo_wait(mast, 4); 2627 - if (push) { 2628 - if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { 2629 - evo_mthd(push, 0x0400 + (or * 0x080), 1); 2630 - evo_data(push, 0x00000000); 2631 - } else { 2632 - evo_mthd(push, 0x0180 + (or * 0x020), 1); 2633 - evo_data(push, 0x00000000); 2634 - } 2635 - evo_kick(push, mast); 2636 - } 2637 - } 2638 - 2639 - nv_encoder->crtc = NULL; 2640 - } 2641 - 2642 1630 static enum drm_connector_status 2643 1631 nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) 2644 1632 { ··· 2639 1681 return connector_status_connected; 2640 1682 } 2641 1683 1684 + static const struct drm_encoder_helper_funcs 1685 + nv50_dac_help = { 1686 + .dpms = nv50_dac_dpms, 1687 + .atomic_check = nv50_outp_atomic_check, 1688 + .enable = nv50_dac_enable, 1689 + .disable = nv50_dac_disable, 1690 + .detect = nv50_dac_detect 1691 + }; 1692 + 2642 1693 static void 2643 1694 nv50_dac_destroy(struct drm_encoder *encoder) 2644 1695 { ··· 2655 1688 kfree(encoder); 2656 1689 } 2657 1690 2658 - static const struct drm_encoder_helper_funcs nv50_dac_hfunc = { 2659 - .dpms = nv50_dac_dpms, 2660 - .mode_fixup = nv50_encoder_mode_fixup, 2661 - .prepare = nv50_dac_disconnect, 2662 - .commit = nv50_dac_commit, 2663 - .mode_set = nv50_dac_mode_set, 2664 - .disable = nv50_dac_disconnect, 2665 - .get_crtc = nv50_display_crtc_get, 2666 - .detect = nv50_dac_detect 2667 - }; 2668 - 2669 - static const struct drm_encoder_funcs nv50_dac_func = { 1691 + static const struct drm_encoder_funcs 1692 + nv50_dac_func = { 2670 1693 .destroy = nv50_dac_destroy, 2671 1694 }; 2672 1695 ··· 2683 1726 encoder = to_drm_encoder(nv_encoder); 2684 1727 encoder->possible_crtcs = dcbe->heads; 2685 1728 encoder->possible_clones = 0; 2686 - drm_encoder_init(connector->dev, encoder, &nv50_dac_func, type, NULL); 2687 - drm_encoder_helper_add(encoder, &nv50_dac_hfunc); 1729 + drm_encoder_init(connector->dev, encoder, &nv50_dac_func, type, 1730 + "dac-%04x-%04x", dcbe->hasht, dcbe->hashm); 1731 + drm_encoder_helper_add(encoder, &nv50_dac_help); 2688 1732 2689 1733 drm_mode_connector_attach_encoder(connector, encoder); 2690 1734 return 0; ··· 2695 1737 * Audio 2696 1738 *****************************************************************************/ 2697 1739 static void 2698 - nv50_audio_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) 1740 + nv50_audio_disable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc) 1741 + { 1742 + struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 1743 + struct nv50_disp *disp = nv50_disp(encoder->dev); 1744 + struct { 1745 + struct nv50_disp_mthd_v1 base; 1746 + struct nv50_disp_sor_hda_eld_v0 eld; 1747 + } args = { 1748 + .base.version = 1, 1749 + .base.method = NV50_DISP_MTHD_V1_SOR_HDA_ELD, 1750 + .base.hasht = nv_encoder->dcb->hasht, 1751 + .base.hashm = (0xf0ff & nv_encoder->dcb->hashm) | 1752 + (0x0100 << nv_crtc->index), 1753 + }; 1754 + 1755 + nvif_mthd(disp->disp, 0, &args, sizeof(args)); 1756 + } 1757 + 1758 + static void 1759 + nv50_audio_enable(struct drm_encoder *encoder, struct drm_display_mode *mode) 2699 1760 { 2700 1761 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 2701 1762 struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); ··· 2745 1768 sizeof(args.base) + drm_eld_size(args.data)); 2746 1769 } 2747 1770 1771 + /****************************************************************************** 1772 + * HDMI 1773 + *****************************************************************************/ 2748 1774 static void 2749 - nv50_audio_disconnect(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc) 1775 + nv50_hdmi_disable(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc) 2750 1776 { 2751 1777 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 2752 1778 struct nv50_disp *disp = nv50_disp(encoder->dev); 2753 1779 struct { 2754 1780 struct nv50_disp_mthd_v1 base; 2755 - struct nv50_disp_sor_hda_eld_v0 eld; 1781 + struct nv50_disp_sor_hdmi_pwr_v0 pwr; 2756 1782 } args = { 2757 1783 .base.version = 1, 2758 - .base.method = NV50_DISP_MTHD_V1_SOR_HDA_ELD, 2759 - .base.hasht = nv_encoder->dcb->hasht, 2760 - .base.hashm = (0xf0ff & nv_encoder->dcb->hashm) | 2761 - (0x0100 << nv_crtc->index), 1784 + .base.method = NV50_DISP_MTHD_V1_SOR_HDMI_PWR, 1785 + .base.hasht = nv_encoder->dcb->hasht, 1786 + .base.hashm = (0xf0ff & nv_encoder->dcb->hashm) | 1787 + (0x0100 << nv_crtc->index), 2762 1788 }; 2763 1789 2764 1790 nvif_mthd(disp->disp, 0, &args, sizeof(args)); 2765 1791 } 2766 1792 2767 - /****************************************************************************** 2768 - * HDMI 2769 - *****************************************************************************/ 2770 1793 static void 2771 - nv50_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) 1794 + nv50_hdmi_enable(struct drm_encoder *encoder, struct drm_display_mode *mode) 2772 1795 { 2773 1796 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 2774 1797 struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); ··· 2798 1821 args.pwr.max_ac_packet = max_ac_packet / 32; 2799 1822 2800 1823 nvif_mthd(disp->disp, 0, &args, sizeof(args)); 2801 - nv50_audio_mode_set(encoder, mode); 1824 + nv50_audio_enable(encoder, mode); 1825 + } 1826 + 1827 + /****************************************************************************** 1828 + * MST 1829 + *****************************************************************************/ 1830 + #define nv50_mstm(p) container_of((p), struct nv50_mstm, mgr) 1831 + #define nv50_mstc(p) container_of((p), struct nv50_mstc, connector) 1832 + #define nv50_msto(p) container_of((p), struct nv50_msto, encoder) 1833 + 1834 + struct nv50_mstm { 1835 + struct nouveau_encoder *outp; 1836 + 1837 + struct drm_dp_mst_topology_mgr mgr; 1838 + struct nv50_msto *msto[4]; 1839 + 1840 + bool modified; 1841 + }; 1842 + 1843 + struct nv50_mstc { 1844 + struct nv50_mstm *mstm; 1845 + struct drm_dp_mst_port *port; 1846 + struct drm_connector connector; 1847 + 1848 + struct drm_display_mode *native; 1849 + struct edid *edid; 1850 + 1851 + int pbn; 1852 + }; 1853 + 1854 + struct nv50_msto { 1855 + struct drm_encoder encoder; 1856 + 1857 + struct nv50_head *head; 1858 + struct nv50_mstc *mstc; 1859 + bool disabled; 1860 + }; 1861 + 1862 + static struct drm_dp_payload * 1863 + nv50_msto_payload(struct nv50_msto *msto) 1864 + { 1865 + struct nouveau_drm *drm = nouveau_drm(msto->encoder.dev); 1866 + struct nv50_mstc *mstc = msto->mstc; 1867 + struct nv50_mstm *mstm = mstc->mstm; 1868 + int vcpi = mstc->port->vcpi.vcpi, i; 1869 + 1870 + NV_ATOMIC(drm, "%s: vcpi %d\n", msto->encoder.name, vcpi); 1871 + for (i = 0; i < mstm->mgr.max_payloads; i++) { 1872 + struct drm_dp_payload *payload = &mstm->mgr.payloads[i]; 1873 + NV_ATOMIC(drm, "%s: %d: vcpi %d start 0x%02x slots 0x%02x\n", 1874 + mstm->outp->base.base.name, i, payload->vcpi, 1875 + payload->start_slot, payload->num_slots); 1876 + } 1877 + 1878 + for (i = 0; i < mstm->mgr.max_payloads; i++) { 1879 + struct drm_dp_payload *payload = &mstm->mgr.payloads[i]; 1880 + if (payload->vcpi == vcpi) 1881 + return payload; 1882 + } 1883 + 1884 + return NULL; 2802 1885 } 2803 1886 2804 1887 static void 2805 - nv50_hdmi_disconnect(struct drm_encoder *encoder, struct nouveau_crtc *nv_crtc) 1888 + nv50_msto_cleanup(struct nv50_msto *msto) 2806 1889 { 2807 - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 2808 - struct nv50_disp *disp = nv50_disp(encoder->dev); 1890 + struct nouveau_drm *drm = nouveau_drm(msto->encoder.dev); 1891 + struct nv50_mstc *mstc = msto->mstc; 1892 + struct nv50_mstm *mstm = mstc->mstm; 1893 + 1894 + NV_ATOMIC(drm, "%s: msto cleanup\n", msto->encoder.name); 1895 + if (mstc->port && mstc->port->vcpi.vcpi > 0 && !nv50_msto_payload(msto)) 1896 + drm_dp_mst_deallocate_vcpi(&mstm->mgr, mstc->port); 1897 + if (msto->disabled) { 1898 + msto->mstc = NULL; 1899 + msto->head = NULL; 1900 + msto->disabled = false; 1901 + } 1902 + } 1903 + 1904 + static void 1905 + nv50_msto_prepare(struct nv50_msto *msto) 1906 + { 1907 + struct nouveau_drm *drm = nouveau_drm(msto->encoder.dev); 1908 + struct nv50_mstc *mstc = msto->mstc; 1909 + struct nv50_mstm *mstm = mstc->mstm; 2809 1910 struct { 2810 1911 struct nv50_disp_mthd_v1 base; 2811 - struct nv50_disp_sor_hdmi_pwr_v0 pwr; 1912 + struct nv50_disp_sor_dp_mst_vcpi_v0 vcpi; 2812 1913 } args = { 2813 1914 .base.version = 1, 2814 - .base.method = NV50_DISP_MTHD_V1_SOR_HDMI_PWR, 2815 - .base.hasht = nv_encoder->dcb->hasht, 2816 - .base.hashm = (0xf0ff & nv_encoder->dcb->hashm) | 2817 - (0x0100 << nv_crtc->index), 1915 + .base.method = NV50_DISP_MTHD_V1_SOR_DP_MST_VCPI, 1916 + .base.hasht = mstm->outp->dcb->hasht, 1917 + .base.hashm = (0xf0ff & mstm->outp->dcb->hashm) | 1918 + (0x0100 << msto->head->base.index), 2818 1919 }; 2819 1920 2820 - nvif_mthd(disp->disp, 0, &args, sizeof(args)); 1921 + NV_ATOMIC(drm, "%s: msto prepare\n", msto->encoder.name); 1922 + if (mstc->port && mstc->port->vcpi.vcpi > 0) { 1923 + struct drm_dp_payload *payload = nv50_msto_payload(msto); 1924 + if (payload) { 1925 + args.vcpi.start_slot = payload->start_slot; 1926 + args.vcpi.num_slots = payload->num_slots; 1927 + args.vcpi.pbn = mstc->port->vcpi.pbn; 1928 + args.vcpi.aligned_pbn = mstc->port->vcpi.aligned_pbn; 1929 + } 1930 + } 1931 + 1932 + NV_ATOMIC(drm, "%s: %s: %02x %02x %04x %04x\n", 1933 + msto->encoder.name, msto->head->base.base.name, 1934 + args.vcpi.start_slot, args.vcpi.num_slots, 1935 + args.vcpi.pbn, args.vcpi.aligned_pbn); 1936 + nvif_mthd(&drm->display->disp, 0, &args, sizeof(args)); 1937 + } 1938 + 1939 + static int 1940 + nv50_msto_atomic_check(struct drm_encoder *encoder, 1941 + struct drm_crtc_state *crtc_state, 1942 + struct drm_connector_state *conn_state) 1943 + { 1944 + struct nv50_mstc *mstc = nv50_mstc(conn_state->connector); 1945 + struct nv50_mstm *mstm = mstc->mstm; 1946 + int bpp = conn_state->connector->display_info.bpc * 3; 1947 + int slots; 1948 + 1949 + mstc->pbn = drm_dp_calc_pbn_mode(crtc_state->adjusted_mode.clock, bpp); 1950 + 1951 + slots = drm_dp_find_vcpi_slots(&mstm->mgr, mstc->pbn); 1952 + if (slots < 0) 1953 + return slots; 1954 + 1955 + return nv50_outp_atomic_check_view(encoder, crtc_state, conn_state, 1956 + mstc->native); 1957 + } 1958 + 1959 + static void 1960 + nv50_msto_enable(struct drm_encoder *encoder) 1961 + { 1962 + struct nv50_head *head = nv50_head(encoder->crtc); 1963 + struct nv50_msto *msto = nv50_msto(encoder); 1964 + struct nv50_mstc *mstc = NULL; 1965 + struct nv50_mstm *mstm = NULL; 1966 + struct drm_connector *connector; 1967 + u8 proto, depth; 1968 + int slots; 1969 + bool r; 1970 + 1971 + drm_for_each_connector(connector, encoder->dev) { 1972 + if (connector->state->best_encoder == &msto->encoder) { 1973 + mstc = nv50_mstc(connector); 1974 + mstm = mstc->mstm; 1975 + break; 1976 + } 1977 + } 1978 + 1979 + if (WARN_ON(!mstc)) 1980 + return; 1981 + 1982 + r = drm_dp_mst_allocate_vcpi(&mstm->mgr, mstc->port, mstc->pbn, &slots); 1983 + WARN_ON(!r); 1984 + 1985 + if (mstm->outp->dcb->sorconf.link & 1) 1986 + proto = 0x8; 1987 + else 1988 + proto = 0x9; 1989 + 1990 + switch (mstc->connector.display_info.bpc) { 1991 + case 6: depth = 0x2; break; 1992 + case 8: depth = 0x5; break; 1993 + case 10: 1994 + default: depth = 0x6; break; 1995 + } 1996 + 1997 + mstm->outp->update(mstm->outp, head->base.index, 1998 + &head->base.base.state->adjusted_mode, proto, depth); 1999 + 2000 + msto->head = head; 2001 + msto->mstc = mstc; 2002 + mstm->modified = true; 2003 + } 2004 + 2005 + static void 2006 + nv50_msto_disable(struct drm_encoder *encoder) 2007 + { 2008 + struct nv50_msto *msto = nv50_msto(encoder); 2009 + struct nv50_mstc *mstc = msto->mstc; 2010 + struct nv50_mstm *mstm = mstc->mstm; 2011 + 2012 + if (mstc->port) 2013 + drm_dp_mst_reset_vcpi_slots(&mstm->mgr, mstc->port); 2014 + 2015 + mstm->outp->update(mstm->outp, msto->head->base.index, NULL, 0, 0); 2016 + mstm->modified = true; 2017 + msto->disabled = true; 2018 + } 2019 + 2020 + static const struct drm_encoder_helper_funcs 2021 + nv50_msto_help = { 2022 + .disable = nv50_msto_disable, 2023 + .enable = nv50_msto_enable, 2024 + .atomic_check = nv50_msto_atomic_check, 2025 + }; 2026 + 2027 + static void 2028 + nv50_msto_destroy(struct drm_encoder *encoder) 2029 + { 2030 + struct nv50_msto *msto = nv50_msto(encoder); 2031 + drm_encoder_cleanup(&msto->encoder); 2032 + kfree(msto); 2033 + } 2034 + 2035 + static const struct drm_encoder_funcs 2036 + nv50_msto = { 2037 + .destroy = nv50_msto_destroy, 2038 + }; 2039 + 2040 + static int 2041 + nv50_msto_new(struct drm_device *dev, u32 heads, const char *name, int id, 2042 + struct nv50_msto **pmsto) 2043 + { 2044 + struct nv50_msto *msto; 2045 + int ret; 2046 + 2047 + if (!(msto = *pmsto = kzalloc(sizeof(*msto), GFP_KERNEL))) 2048 + return -ENOMEM; 2049 + 2050 + ret = drm_encoder_init(dev, &msto->encoder, &nv50_msto, 2051 + DRM_MODE_ENCODER_DPMST, "%s-mst-%d", name, id); 2052 + if (ret) { 2053 + kfree(*pmsto); 2054 + *pmsto = NULL; 2055 + return ret; 2056 + } 2057 + 2058 + drm_encoder_helper_add(&msto->encoder, &nv50_msto_help); 2059 + msto->encoder.possible_crtcs = heads; 2060 + return 0; 2061 + } 2062 + 2063 + static struct drm_encoder * 2064 + nv50_mstc_atomic_best_encoder(struct drm_connector *connector, 2065 + struct drm_connector_state *connector_state) 2066 + { 2067 + struct nv50_head *head = nv50_head(connector_state->crtc); 2068 + struct nv50_mstc *mstc = nv50_mstc(connector); 2069 + if (mstc->port) { 2070 + struct nv50_mstm *mstm = mstc->mstm; 2071 + return &mstm->msto[head->base.index]->encoder; 2072 + } 2073 + return NULL; 2074 + } 2075 + 2076 + static struct drm_encoder * 2077 + nv50_mstc_best_encoder(struct drm_connector *connector) 2078 + { 2079 + struct nv50_mstc *mstc = nv50_mstc(connector); 2080 + if (mstc->port) { 2081 + struct nv50_mstm *mstm = mstc->mstm; 2082 + return &mstm->msto[0]->encoder; 2083 + } 2084 + return NULL; 2085 + } 2086 + 2087 + static enum drm_mode_status 2088 + nv50_mstc_mode_valid(struct drm_connector *connector, 2089 + struct drm_display_mode *mode) 2090 + { 2091 + return MODE_OK; 2092 + } 2093 + 2094 + static int 2095 + nv50_mstc_get_modes(struct drm_connector *connector) 2096 + { 2097 + struct nv50_mstc *mstc = nv50_mstc(connector); 2098 + int ret = 0; 2099 + 2100 + mstc->edid = drm_dp_mst_get_edid(&mstc->connector, mstc->port->mgr, mstc->port); 2101 + drm_mode_connector_update_edid_property(&mstc->connector, mstc->edid); 2102 + if (mstc->edid) { 2103 + ret = drm_add_edid_modes(&mstc->connector, mstc->edid); 2104 + drm_edid_to_eld(&mstc->connector, mstc->edid); 2105 + } 2106 + 2107 + if (!mstc->connector.display_info.bpc) 2108 + mstc->connector.display_info.bpc = 8; 2109 + 2110 + if (mstc->native) 2111 + drm_mode_destroy(mstc->connector.dev, mstc->native); 2112 + mstc->native = nouveau_conn_native_mode(&mstc->connector); 2113 + return ret; 2114 + } 2115 + 2116 + static const struct drm_connector_helper_funcs 2117 + nv50_mstc_help = { 2118 + .get_modes = nv50_mstc_get_modes, 2119 + .mode_valid = nv50_mstc_mode_valid, 2120 + .best_encoder = nv50_mstc_best_encoder, 2121 + .atomic_best_encoder = nv50_mstc_atomic_best_encoder, 2122 + }; 2123 + 2124 + static enum drm_connector_status 2125 + nv50_mstc_detect(struct drm_connector *connector, bool force) 2126 + { 2127 + struct nv50_mstc *mstc = nv50_mstc(connector); 2128 + if (!mstc->port) 2129 + return connector_status_disconnected; 2130 + return drm_dp_mst_detect_port(connector, mstc->port->mgr, mstc->port); 2131 + } 2132 + 2133 + static void 2134 + nv50_mstc_destroy(struct drm_connector *connector) 2135 + { 2136 + struct nv50_mstc *mstc = nv50_mstc(connector); 2137 + drm_connector_cleanup(&mstc->connector); 2138 + kfree(mstc); 2139 + } 2140 + 2141 + static const struct drm_connector_funcs 2142 + nv50_mstc = { 2143 + .dpms = drm_atomic_helper_connector_dpms, 2144 + .reset = nouveau_conn_reset, 2145 + .detect = nv50_mstc_detect, 2146 + .fill_modes = drm_helper_probe_single_connector_modes, 2147 + .set_property = drm_atomic_helper_connector_set_property, 2148 + .destroy = nv50_mstc_destroy, 2149 + .atomic_duplicate_state = nouveau_conn_atomic_duplicate_state, 2150 + .atomic_destroy_state = nouveau_conn_atomic_destroy_state, 2151 + .atomic_set_property = nouveau_conn_atomic_set_property, 2152 + .atomic_get_property = nouveau_conn_atomic_get_property, 2153 + }; 2154 + 2155 + static int 2156 + nv50_mstc_new(struct nv50_mstm *mstm, struct drm_dp_mst_port *port, 2157 + const char *path, struct nv50_mstc **pmstc) 2158 + { 2159 + struct drm_device *dev = mstm->outp->base.base.dev; 2160 + struct nv50_mstc *mstc; 2161 + int ret, i; 2162 + 2163 + if (!(mstc = *pmstc = kzalloc(sizeof(*mstc), GFP_KERNEL))) 2164 + return -ENOMEM; 2165 + mstc->mstm = mstm; 2166 + mstc->port = port; 2167 + 2168 + ret = drm_connector_init(dev, &mstc->connector, &nv50_mstc, 2169 + DRM_MODE_CONNECTOR_DisplayPort); 2170 + if (ret) { 2171 + kfree(*pmstc); 2172 + *pmstc = NULL; 2173 + return ret; 2174 + } 2175 + 2176 + drm_connector_helper_add(&mstc->connector, &nv50_mstc_help); 2177 + 2178 + mstc->connector.funcs->reset(&mstc->connector); 2179 + nouveau_conn_attach_properties(&mstc->connector); 2180 + 2181 + for (i = 0; i < ARRAY_SIZE(mstm->msto) && mstm->msto; i++) 2182 + drm_mode_connector_attach_encoder(&mstc->connector, &mstm->msto[i]->encoder); 2183 + 2184 + drm_object_attach_property(&mstc->connector.base, dev->mode_config.path_property, 0); 2185 + drm_object_attach_property(&mstc->connector.base, dev->mode_config.tile_property, 0); 2186 + drm_mode_connector_set_path_property(&mstc->connector, path); 2187 + return 0; 2188 + } 2189 + 2190 + static void 2191 + nv50_mstm_cleanup(struct nv50_mstm *mstm) 2192 + { 2193 + struct nouveau_drm *drm = nouveau_drm(mstm->outp->base.base.dev); 2194 + struct drm_encoder *encoder; 2195 + int ret; 2196 + 2197 + NV_ATOMIC(drm, "%s: mstm cleanup\n", mstm->outp->base.base.name); 2198 + ret = drm_dp_check_act_status(&mstm->mgr); 2199 + 2200 + ret = drm_dp_update_payload_part2(&mstm->mgr); 2201 + 2202 + drm_for_each_encoder(encoder, mstm->outp->base.base.dev) { 2203 + if (encoder->encoder_type == DRM_MODE_ENCODER_DPMST) { 2204 + struct nv50_msto *msto = nv50_msto(encoder); 2205 + struct nv50_mstc *mstc = msto->mstc; 2206 + if (mstc && mstc->mstm == mstm) 2207 + nv50_msto_cleanup(msto); 2208 + } 2209 + } 2210 + 2211 + mstm->modified = false; 2212 + } 2213 + 2214 + static void 2215 + nv50_mstm_prepare(struct nv50_mstm *mstm) 2216 + { 2217 + struct nouveau_drm *drm = nouveau_drm(mstm->outp->base.base.dev); 2218 + struct drm_encoder *encoder; 2219 + int ret; 2220 + 2221 + NV_ATOMIC(drm, "%s: mstm prepare\n", mstm->outp->base.base.name); 2222 + ret = drm_dp_update_payload_part1(&mstm->mgr); 2223 + 2224 + drm_for_each_encoder(encoder, mstm->outp->base.base.dev) { 2225 + if (encoder->encoder_type == DRM_MODE_ENCODER_DPMST) { 2226 + struct nv50_msto *msto = nv50_msto(encoder); 2227 + struct nv50_mstc *mstc = msto->mstc; 2228 + if (mstc && mstc->mstm == mstm) 2229 + nv50_msto_prepare(msto); 2230 + } 2231 + } 2232 + } 2233 + 2234 + static void 2235 + nv50_mstm_hotplug(struct drm_dp_mst_topology_mgr *mgr) 2236 + { 2237 + struct nv50_mstm *mstm = nv50_mstm(mgr); 2238 + drm_kms_helper_hotplug_event(mstm->outp->base.base.dev); 2239 + } 2240 + 2241 + static void 2242 + nv50_mstm_destroy_connector(struct drm_dp_mst_topology_mgr *mgr, 2243 + struct drm_connector *connector) 2244 + { 2245 + struct nouveau_drm *drm = nouveau_drm(connector->dev); 2246 + struct nv50_mstc *mstc = nv50_mstc(connector); 2247 + 2248 + drm_connector_unregister(&mstc->connector); 2249 + 2250 + drm_modeset_lock_all(drm->dev); 2251 + drm_fb_helper_remove_one_connector(&drm->fbcon->helper, &mstc->connector); 2252 + mstc->port = NULL; 2253 + drm_modeset_unlock_all(drm->dev); 2254 + 2255 + drm_connector_unreference(&mstc->connector); 2256 + } 2257 + 2258 + static void 2259 + nv50_mstm_register_connector(struct drm_connector *connector) 2260 + { 2261 + struct nouveau_drm *drm = nouveau_drm(connector->dev); 2262 + 2263 + drm_modeset_lock_all(drm->dev); 2264 + drm_fb_helper_add_one_connector(&drm->fbcon->helper, connector); 2265 + drm_modeset_unlock_all(drm->dev); 2266 + 2267 + drm_connector_register(connector); 2268 + } 2269 + 2270 + static struct drm_connector * 2271 + nv50_mstm_add_connector(struct drm_dp_mst_topology_mgr *mgr, 2272 + struct drm_dp_mst_port *port, const char *path) 2273 + { 2274 + struct nv50_mstm *mstm = nv50_mstm(mgr); 2275 + struct nv50_mstc *mstc; 2276 + int ret; 2277 + 2278 + ret = nv50_mstc_new(mstm, port, path, &mstc); 2279 + if (ret) { 2280 + if (mstc) 2281 + mstc->connector.funcs->destroy(&mstc->connector); 2282 + return NULL; 2283 + } 2284 + 2285 + return &mstc->connector; 2286 + } 2287 + 2288 + static const struct drm_dp_mst_topology_cbs 2289 + nv50_mstm = { 2290 + .add_connector = nv50_mstm_add_connector, 2291 + .register_connector = nv50_mstm_register_connector, 2292 + .destroy_connector = nv50_mstm_destroy_connector, 2293 + .hotplug = nv50_mstm_hotplug, 2294 + }; 2295 + 2296 + void 2297 + nv50_mstm_service(struct nv50_mstm *mstm) 2298 + { 2299 + struct drm_dp_aux *aux = mstm->mgr.aux; 2300 + bool handled = true; 2301 + int ret; 2302 + u8 esi[8] = {}; 2303 + 2304 + while (handled) { 2305 + ret = drm_dp_dpcd_read(aux, DP_SINK_COUNT_ESI, esi, 8); 2306 + if (ret != 8) { 2307 + drm_dp_mst_topology_mgr_set_mst(&mstm->mgr, false); 2308 + return; 2309 + } 2310 + 2311 + drm_dp_mst_hpd_irq(&mstm->mgr, esi, &handled); 2312 + if (!handled) 2313 + break; 2314 + 2315 + drm_dp_dpcd_write(aux, DP_SINK_COUNT_ESI + 1, &esi[1], 3); 2316 + } 2317 + } 2318 + 2319 + void 2320 + nv50_mstm_remove(struct nv50_mstm *mstm) 2321 + { 2322 + if (mstm) 2323 + drm_dp_mst_topology_mgr_set_mst(&mstm->mgr, false); 2324 + } 2325 + 2326 + static int 2327 + nv50_mstm_enable(struct nv50_mstm *mstm, u8 dpcd, int state) 2328 + { 2329 + struct nouveau_encoder *outp = mstm->outp; 2330 + struct { 2331 + struct nv50_disp_mthd_v1 base; 2332 + struct nv50_disp_sor_dp_mst_link_v0 mst; 2333 + } args = { 2334 + .base.version = 1, 2335 + .base.method = NV50_DISP_MTHD_V1_SOR_DP_MST_LINK, 2336 + .base.hasht = outp->dcb->hasht, 2337 + .base.hashm = outp->dcb->hashm, 2338 + .mst.state = state, 2339 + }; 2340 + struct nouveau_drm *drm = nouveau_drm(outp->base.base.dev); 2341 + struct nvif_object *disp = &drm->display->disp; 2342 + int ret; 2343 + 2344 + if (dpcd >= 0x12) { 2345 + ret = drm_dp_dpcd_readb(mstm->mgr.aux, DP_MSTM_CTRL, &dpcd); 2346 + if (ret < 0) 2347 + return ret; 2348 + 2349 + dpcd &= ~DP_MST_EN; 2350 + if (state) 2351 + dpcd |= DP_MST_EN; 2352 + 2353 + ret = drm_dp_dpcd_writeb(mstm->mgr.aux, DP_MSTM_CTRL, dpcd); 2354 + if (ret < 0) 2355 + return ret; 2356 + } 2357 + 2358 + return nvif_mthd(disp, 0, &args, sizeof(args)); 2359 + } 2360 + 2361 + int 2362 + nv50_mstm_detect(struct nv50_mstm *mstm, u8 dpcd[8], int allow) 2363 + { 2364 + int ret, state = 0; 2365 + 2366 + if (!mstm) 2367 + return 0; 2368 + 2369 + if (dpcd[0] >= 0x12 && allow) { 2370 + ret = drm_dp_dpcd_readb(mstm->mgr.aux, DP_MSTM_CAP, &dpcd[1]); 2371 + if (ret < 0) 2372 + return ret; 2373 + 2374 + state = dpcd[1] & DP_MST_CAP; 2375 + } 2376 + 2377 + ret = nv50_mstm_enable(mstm, dpcd[0], state); 2378 + if (ret) 2379 + return ret; 2380 + 2381 + ret = drm_dp_mst_topology_mgr_set_mst(&mstm->mgr, state); 2382 + if (ret) 2383 + return nv50_mstm_enable(mstm, dpcd[0], 0); 2384 + 2385 + return mstm->mgr.mst_state; 2386 + } 2387 + 2388 + static void 2389 + nv50_mstm_fini(struct nv50_mstm *mstm) 2390 + { 2391 + if (mstm && mstm->mgr.mst_state) 2392 + drm_dp_mst_topology_mgr_suspend(&mstm->mgr); 2393 + } 2394 + 2395 + static void 2396 + nv50_mstm_init(struct nv50_mstm *mstm) 2397 + { 2398 + if (mstm && mstm->mgr.mst_state) 2399 + drm_dp_mst_topology_mgr_resume(&mstm->mgr); 2400 + } 2401 + 2402 + static void 2403 + nv50_mstm_del(struct nv50_mstm **pmstm) 2404 + { 2405 + struct nv50_mstm *mstm = *pmstm; 2406 + if (mstm) { 2407 + kfree(*pmstm); 2408 + *pmstm = NULL; 2409 + } 2410 + } 2411 + 2412 + static int 2413 + nv50_mstm_new(struct nouveau_encoder *outp, struct drm_dp_aux *aux, int aux_max, 2414 + int conn_base_id, struct nv50_mstm **pmstm) 2415 + { 2416 + const int max_payloads = hweight8(outp->dcb->heads); 2417 + struct drm_device *dev = outp->base.base.dev; 2418 + struct nv50_mstm *mstm; 2419 + int ret, i; 2420 + u8 dpcd; 2421 + 2422 + /* This is a workaround for some monitors not functioning 2423 + * correctly in MST mode on initial module load. I think 2424 + * some bad interaction with the VBIOS may be responsible. 2425 + * 2426 + * A good ol' off and on again seems to work here ;) 2427 + */ 2428 + ret = drm_dp_dpcd_readb(aux, DP_DPCD_REV, &dpcd); 2429 + if (ret >= 0 && dpcd >= 0x12) 2430 + drm_dp_dpcd_writeb(aux, DP_MSTM_CTRL, 0); 2431 + 2432 + if (!(mstm = *pmstm = kzalloc(sizeof(*mstm), GFP_KERNEL))) 2433 + return -ENOMEM; 2434 + mstm->outp = outp; 2435 + mstm->mgr.cbs = &nv50_mstm; 2436 + 2437 + ret = drm_dp_mst_topology_mgr_init(&mstm->mgr, dev->dev, aux, aux_max, 2438 + max_payloads, conn_base_id); 2439 + if (ret) 2440 + return ret; 2441 + 2442 + for (i = 0; i < max_payloads; i++) { 2443 + ret = nv50_msto_new(dev, outp->dcb->heads, outp->base.base.name, 2444 + i, &mstm->msto[i]); 2445 + if (ret) 2446 + return ret; 2447 + } 2448 + 2449 + return 0; 2821 2450 } 2822 2451 2823 2452 /****************************************************************************** ··· 3444 1861 .base.hashm = nv_encoder->dcb->hashm, 3445 1862 .pwr.state = mode == DRM_MODE_DPMS_ON, 3446 1863 }; 3447 - struct { 3448 - struct nv50_disp_mthd_v1 base; 3449 - struct nv50_disp_sor_dp_pwr_v0 pwr; 3450 - } link = { 3451 - .base.version = 1, 3452 - .base.method = NV50_DISP_MTHD_V1_SOR_DP_PWR, 3453 - .base.hasht = nv_encoder->dcb->hasht, 3454 - .base.hashm = nv_encoder->dcb->hashm, 3455 - .pwr.state = mode == DRM_MODE_DPMS_ON, 3456 - }; 3457 - struct drm_device *dev = encoder->dev; 3458 - struct drm_encoder *partner; 3459 1864 3460 - nv_encoder->last_dpms = mode; 3461 - 3462 - list_for_each_entry(partner, &dev->mode_config.encoder_list, head) { 3463 - struct nouveau_encoder *nv_partner = nouveau_encoder(partner); 3464 - 3465 - if (partner->encoder_type != DRM_MODE_ENCODER_TMDS) 3466 - continue; 3467 - 3468 - if (nv_partner != nv_encoder && 3469 - nv_partner->dcb->or == nv_encoder->dcb->or) { 3470 - if (nv_partner->last_dpms == DRM_MODE_DPMS_ON) 3471 - return; 3472 - break; 3473 - } 3474 - } 3475 - 3476 - if (nv_encoder->dcb->type == DCB_OUTPUT_DP) { 3477 - args.pwr.state = 1; 3478 - nvif_mthd(disp->disp, 0, &args, sizeof(args)); 3479 - nvif_mthd(disp->disp, 0, &link, sizeof(link)); 3480 - } else { 3481 - nvif_mthd(disp->disp, 0, &args, sizeof(args)); 3482 - } 1865 + nvif_mthd(disp->disp, 0, &args, sizeof(args)); 3483 1866 } 3484 1867 3485 1868 static void 3486 - nv50_sor_ctrl(struct nouveau_encoder *nv_encoder, u32 mask, u32 data) 1869 + nv50_sor_update(struct nouveau_encoder *nv_encoder, u8 head, 1870 + struct drm_display_mode *mode, u8 proto, u8 depth) 3487 1871 { 3488 - struct nv50_mast *mast = nv50_mast(nv_encoder->base.base.dev); 3489 - u32 temp = (nv_encoder->ctrl & ~mask) | (data & mask), *push; 3490 - if (temp != nv_encoder->ctrl && (push = evo_wait(mast, 2))) { 3491 - if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { 1872 + struct nv50_dmac *core = &nv50_mast(nv_encoder->base.base.dev)->base; 1873 + u32 *push; 1874 + 1875 + if (!mode) { 1876 + nv_encoder->ctrl &= ~BIT(head); 1877 + if (!(nv_encoder->ctrl & 0x0000000f)) 1878 + nv_encoder->ctrl = 0; 1879 + } else { 1880 + nv_encoder->ctrl |= proto << 8; 1881 + nv_encoder->ctrl |= BIT(head); 1882 + } 1883 + 1884 + if ((push = evo_wait(core, 6))) { 1885 + if (core->base.user.oclass < GF110_DISP_CORE_CHANNEL_DMA) { 1886 + if (mode) { 1887 + if (mode->flags & DRM_MODE_FLAG_NHSYNC) 1888 + nv_encoder->ctrl |= 0x00001000; 1889 + if (mode->flags & DRM_MODE_FLAG_NVSYNC) 1890 + nv_encoder->ctrl |= 0x00002000; 1891 + nv_encoder->ctrl |= depth << 16; 1892 + } 3492 1893 evo_mthd(push, 0x0600 + (nv_encoder->or * 0x40), 1); 3493 - evo_data(push, (nv_encoder->ctrl = temp)); 3494 1894 } else { 1895 + if (mode) { 1896 + u32 magic = 0x31ec6000 | (head << 25); 1897 + u32 syncs = 0x00000001; 1898 + if (mode->flags & DRM_MODE_FLAG_NHSYNC) 1899 + syncs |= 0x00000008; 1900 + if (mode->flags & DRM_MODE_FLAG_NVSYNC) 1901 + syncs |= 0x00000010; 1902 + if (mode->flags & DRM_MODE_FLAG_INTERLACE) 1903 + magic |= 0x00000001; 1904 + 1905 + evo_mthd(push, 0x0404 + (head * 0x300), 2); 1906 + evo_data(push, syncs | (depth << 6)); 1907 + evo_data(push, magic); 1908 + } 3495 1909 evo_mthd(push, 0x0200 + (nv_encoder->or * 0x20), 1); 3496 - evo_data(push, (nv_encoder->ctrl = temp)); 3497 1910 } 3498 - evo_kick(push, mast); 1911 + evo_data(push, nv_encoder->ctrl); 1912 + evo_kick(push, core); 3499 1913 } 3500 1914 } 3501 1915 3502 1916 static void 3503 - nv50_sor_disconnect(struct drm_encoder *encoder) 1917 + nv50_sor_disable(struct drm_encoder *encoder) 3504 1918 { 3505 1919 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 3506 1920 struct nouveau_crtc *nv_crtc = nouveau_crtc(nv_encoder->crtc); 3507 1921 3508 - nv_encoder->last_dpms = DRM_MODE_DPMS_OFF; 3509 1922 nv_encoder->crtc = NULL; 3510 1923 3511 1924 if (nv_crtc) { 3512 - nv50_crtc_prepare(&nv_crtc->base); 3513 - nv50_sor_ctrl(nv_encoder, 1 << nv_crtc->index, 0); 3514 - nv50_audio_disconnect(encoder, nv_crtc); 3515 - nv50_hdmi_disconnect(&nv_encoder->base.base, nv_crtc); 1925 + struct nvkm_i2c_aux *aux = nv_encoder->aux; 1926 + u8 pwr; 1927 + 1928 + if (aux) { 1929 + int ret = nvkm_rdaux(aux, DP_SET_POWER, &pwr, 1); 1930 + if (ret == 0) { 1931 + pwr &= ~DP_SET_POWER_MASK; 1932 + pwr |= DP_SET_POWER_D3; 1933 + nvkm_wraux(aux, DP_SET_POWER, &pwr, 1); 1934 + } 1935 + } 1936 + 1937 + nv_encoder->update(nv_encoder, nv_crtc->index, NULL, 0, 0); 1938 + nv50_audio_disable(encoder, nv_crtc); 1939 + nv50_hdmi_disable(&nv_encoder->base.base, nv_crtc); 3516 1940 } 3517 1941 } 3518 1942 3519 1943 static void 3520 - nv50_sor_commit(struct drm_encoder *encoder) 3521 - { 3522 - } 3523 - 3524 - static void 3525 - nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, 3526 - struct drm_display_mode *mode) 1944 + nv50_sor_enable(struct drm_encoder *encoder) 3527 1945 { 3528 1946 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 3529 1947 struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); 1948 + struct drm_display_mode *mode = &nv_crtc->base.state->adjusted_mode; 3530 1949 struct { 3531 1950 struct nv50_disp_mthd_v1 base; 3532 1951 struct nv50_disp_sor_lvds_script_v0 lvds; ··· 3539 1954 .base.hashm = nv_encoder->dcb->hashm, 3540 1955 }; 3541 1956 struct nv50_disp *disp = nv50_disp(encoder->dev); 3542 - struct nv50_mast *mast = nv50_mast(encoder->dev); 3543 1957 struct drm_device *dev = encoder->dev; 3544 1958 struct nouveau_drm *drm = nouveau_drm(dev); 3545 1959 struct nouveau_connector *nv_connector; 3546 1960 struct nvbios *bios = &drm->vbios; 3547 - u32 mask, ctrl; 3548 - u8 owner = 1 << nv_crtc->index; 3549 1961 u8 proto = 0xf; 3550 1962 u8 depth = 0x0; 3551 1963 ··· 3567 1985 proto = 0x2; 3568 1986 } 3569 1987 3570 - nv50_hdmi_mode_set(&nv_encoder->base.base, mode); 1988 + nv50_hdmi_enable(&nv_encoder->base.base, mode); 3571 1989 break; 3572 1990 case DCB_OUTPUT_LVDS: 3573 1991 proto = 0x0; ··· 3601 2019 nvif_mthd(disp->disp, 0, &lvds, sizeof(lvds)); 3602 2020 break; 3603 2021 case DCB_OUTPUT_DP: 3604 - if (nv_connector->base.display_info.bpc == 6) { 3605 - nv_encoder->dp.datarate = mode->clock * 18 / 8; 2022 + if (nv_connector->base.display_info.bpc == 6) 3606 2023 depth = 0x2; 3607 - } else 3608 - if (nv_connector->base.display_info.bpc == 8) { 3609 - nv_encoder->dp.datarate = mode->clock * 24 / 8; 2024 + else 2025 + if (nv_connector->base.display_info.bpc == 8) 3610 2026 depth = 0x5; 3611 - } else { 3612 - nv_encoder->dp.datarate = mode->clock * 30 / 8; 2027 + else 3613 2028 depth = 0x6; 3614 - } 3615 2029 3616 2030 if (nv_encoder->dcb->sorconf.link & 1) 3617 2031 proto = 0x8; 3618 2032 else 3619 2033 proto = 0x9; 3620 - nv50_audio_mode_set(encoder, mode); 2034 + 2035 + nv50_audio_enable(encoder, mode); 3621 2036 break; 3622 2037 default: 3623 2038 BUG_ON(1); 3624 2039 break; 3625 2040 } 3626 2041 3627 - nv50_sor_dpms(&nv_encoder->base.base, DRM_MODE_DPMS_ON); 3628 - 3629 - if (nv50_vers(mast) >= GF110_DISP) { 3630 - u32 *push = evo_wait(mast, 3); 3631 - if (push) { 3632 - u32 magic = 0x31ec6000 | (nv_crtc->index << 25); 3633 - u32 syncs = 0x00000001; 3634 - 3635 - if (mode->flags & DRM_MODE_FLAG_NHSYNC) 3636 - syncs |= 0x00000008; 3637 - if (mode->flags & DRM_MODE_FLAG_NVSYNC) 3638 - syncs |= 0x00000010; 3639 - 3640 - if (mode->flags & DRM_MODE_FLAG_INTERLACE) 3641 - magic |= 0x00000001; 3642 - 3643 - evo_mthd(push, 0x0404 + (nv_crtc->index * 0x300), 2); 3644 - evo_data(push, syncs | (depth << 6)); 3645 - evo_data(push, magic); 3646 - evo_kick(push, mast); 3647 - } 3648 - 3649 - ctrl = proto << 8; 3650 - mask = 0x00000f00; 3651 - } else { 3652 - ctrl = (depth << 16) | (proto << 8); 3653 - if (mode->flags & DRM_MODE_FLAG_NHSYNC) 3654 - ctrl |= 0x00001000; 3655 - if (mode->flags & DRM_MODE_FLAG_NVSYNC) 3656 - ctrl |= 0x00002000; 3657 - mask = 0x000f3f00; 3658 - } 3659 - 3660 - nv50_sor_ctrl(nv_encoder, mask | owner, ctrl | owner); 2042 + nv_encoder->update(nv_encoder, nv_crtc->index, mode, proto, depth); 3661 2043 } 2044 + 2045 + static const struct drm_encoder_helper_funcs 2046 + nv50_sor_help = { 2047 + .dpms = nv50_sor_dpms, 2048 + .atomic_check = nv50_outp_atomic_check, 2049 + .enable = nv50_sor_enable, 2050 + .disable = nv50_sor_disable, 2051 + }; 3662 2052 3663 2053 static void 3664 2054 nv50_sor_destroy(struct drm_encoder *encoder) 3665 2055 { 2056 + struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 2057 + nv50_mstm_del(&nv_encoder->dp.mstm); 3666 2058 drm_encoder_cleanup(encoder); 3667 2059 kfree(encoder); 3668 2060 } 3669 2061 3670 - static const struct drm_encoder_helper_funcs nv50_sor_hfunc = { 3671 - .dpms = nv50_sor_dpms, 3672 - .mode_fixup = nv50_encoder_mode_fixup, 3673 - .prepare = nv50_sor_disconnect, 3674 - .commit = nv50_sor_commit, 3675 - .mode_set = nv50_sor_mode_set, 3676 - .disable = nv50_sor_disconnect, 3677 - .get_crtc = nv50_display_crtc_get, 3678 - }; 3679 - 3680 - static const struct drm_encoder_funcs nv50_sor_func = { 2062 + static const struct drm_encoder_funcs 2063 + nv50_sor_func = { 3681 2064 .destroy = nv50_sor_destroy, 3682 2065 }; 3683 2066 3684 2067 static int 3685 2068 nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe) 3686 2069 { 2070 + struct nouveau_connector *nv_connector = nouveau_connector(connector); 3687 2071 struct nouveau_drm *drm = nouveau_drm(connector->dev); 3688 2072 struct nvkm_i2c *i2c = nvxx_i2c(&drm->device); 3689 2073 struct nouveau_encoder *nv_encoder; 3690 2074 struct drm_encoder *encoder; 3691 - int type; 2075 + int type, ret; 3692 2076 3693 2077 switch (dcbe->type) { 3694 2078 case DCB_OUTPUT_LVDS: type = DRM_MODE_ENCODER_LVDS; break; ··· 3670 2122 return -ENOMEM; 3671 2123 nv_encoder->dcb = dcbe; 3672 2124 nv_encoder->or = ffs(dcbe->or) - 1; 3673 - nv_encoder->last_dpms = DRM_MODE_DPMS_OFF; 2125 + nv_encoder->update = nv50_sor_update; 2126 + 2127 + encoder = to_drm_encoder(nv_encoder); 2128 + encoder->possible_crtcs = dcbe->heads; 2129 + encoder->possible_clones = 0; 2130 + drm_encoder_init(connector->dev, encoder, &nv50_sor_func, type, 2131 + "sor-%04x-%04x", dcbe->hasht, dcbe->hashm); 2132 + drm_encoder_helper_add(encoder, &nv50_sor_help); 2133 + 2134 + drm_mode_connector_attach_encoder(connector, encoder); 3674 2135 3675 2136 if (dcbe->type == DCB_OUTPUT_DP) { 3676 2137 struct nvkm_i2c_aux *aux = ··· 3688 2131 nv_encoder->i2c = &aux->i2c; 3689 2132 nv_encoder->aux = aux; 3690 2133 } 2134 + 2135 + /*TODO: Use DP Info Table to check for support. */ 2136 + if (nv50_disp(encoder->dev)->disp->oclass >= GF110_DISP) { 2137 + ret = nv50_mstm_new(nv_encoder, &nv_connector->aux, 16, 2138 + nv_connector->base.base.id, 2139 + &nv_encoder->dp.mstm); 2140 + if (ret) 2141 + return ret; 2142 + } 3691 2143 } else { 3692 2144 struct nvkm_i2c_bus *bus = 3693 2145 nvkm_i2c_bus_find(i2c, dcbe->i2c_index); ··· 3704 2138 nv_encoder->i2c = &bus->i2c; 3705 2139 } 3706 2140 3707 - encoder = to_drm_encoder(nv_encoder); 3708 - encoder->possible_crtcs = dcbe->heads; 3709 - encoder->possible_clones = 0; 3710 - drm_encoder_init(connector->dev, encoder, &nv50_sor_func, type, NULL); 3711 - drm_encoder_helper_add(encoder, &nv50_sor_hfunc); 3712 - 3713 - drm_mode_connector_attach_encoder(connector, encoder); 3714 2141 return 0; 3715 2142 } 3716 2143 3717 2144 /****************************************************************************** 3718 2145 * PIOR 3719 2146 *****************************************************************************/ 3720 - 3721 2147 static void 3722 2148 nv50_pior_dpms(struct drm_encoder *encoder, int mode) 3723 2149 { ··· 3730 2172 nvif_mthd(disp->disp, 0, &args, sizeof(args)); 3731 2173 } 3732 2174 3733 - static bool 3734 - nv50_pior_mode_fixup(struct drm_encoder *encoder, 3735 - const struct drm_display_mode *mode, 3736 - struct drm_display_mode *adjusted_mode) 2175 + static int 2176 + nv50_pior_atomic_check(struct drm_encoder *encoder, 2177 + struct drm_crtc_state *crtc_state, 2178 + struct drm_connector_state *conn_state) 3737 2179 { 3738 - if (!nv50_encoder_mode_fixup(encoder, mode, adjusted_mode)) 3739 - return false; 3740 - adjusted_mode->clock *= 2; 3741 - return true; 2180 + int ret = nv50_outp_atomic_check(encoder, crtc_state, conn_state); 2181 + if (ret) 2182 + return ret; 2183 + crtc_state->adjusted_mode.clock *= 2; 2184 + return 0; 3742 2185 } 3743 2186 3744 2187 static void 3745 - nv50_pior_commit(struct drm_encoder *encoder) 2188 + nv50_pior_disable(struct drm_encoder *encoder) 3746 2189 { 2190 + struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 2191 + struct nv50_mast *mast = nv50_mast(encoder->dev); 2192 + const int or = nv_encoder->or; 2193 + u32 *push; 2194 + 2195 + if (nv_encoder->crtc) { 2196 + push = evo_wait(mast, 4); 2197 + if (push) { 2198 + if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { 2199 + evo_mthd(push, 0x0700 + (or * 0x040), 1); 2200 + evo_data(push, 0x00000000); 2201 + } 2202 + evo_kick(push, mast); 2203 + } 2204 + } 2205 + 2206 + nv_encoder->crtc = NULL; 3747 2207 } 3748 2208 3749 2209 static void 3750 - nv50_pior_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, 3751 - struct drm_display_mode *adjusted_mode) 2210 + nv50_pior_enable(struct drm_encoder *encoder) 3752 2211 { 3753 2212 struct nv50_mast *mast = nv50_mast(encoder->dev); 3754 2213 struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 3755 2214 struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); 3756 2215 struct nouveau_connector *nv_connector; 2216 + struct drm_display_mode *mode = &nv_crtc->base.state->adjusted_mode; 3757 2217 u8 owner = 1 << nv_crtc->index; 3758 2218 u8 proto, depth; 3759 2219 u32 *push; ··· 3794 2218 break; 3795 2219 } 3796 2220 3797 - nv50_pior_dpms(encoder, DRM_MODE_DPMS_ON); 3798 - 3799 2221 push = evo_wait(mast, 8); 3800 2222 if (push) { 3801 2223 if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { ··· 3812 2238 nv_encoder->crtc = encoder->crtc; 3813 2239 } 3814 2240 3815 - static void 3816 - nv50_pior_disconnect(struct drm_encoder *encoder) 3817 - { 3818 - struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); 3819 - struct nv50_mast *mast = nv50_mast(encoder->dev); 3820 - const int or = nv_encoder->or; 3821 - u32 *push; 3822 - 3823 - if (nv_encoder->crtc) { 3824 - nv50_crtc_prepare(nv_encoder->crtc); 3825 - 3826 - push = evo_wait(mast, 4); 3827 - if (push) { 3828 - if (nv50_vers(mast) < GF110_DISP_CORE_CHANNEL_DMA) { 3829 - evo_mthd(push, 0x0700 + (or * 0x040), 1); 3830 - evo_data(push, 0x00000000); 3831 - } 3832 - evo_kick(push, mast); 3833 - } 3834 - } 3835 - 3836 - nv_encoder->crtc = NULL; 3837 - } 2241 + static const struct drm_encoder_helper_funcs 2242 + nv50_pior_help = { 2243 + .dpms = nv50_pior_dpms, 2244 + .atomic_check = nv50_pior_atomic_check, 2245 + .enable = nv50_pior_enable, 2246 + .disable = nv50_pior_disable, 2247 + }; 3838 2248 3839 2249 static void 3840 2250 nv50_pior_destroy(struct drm_encoder *encoder) ··· 3827 2269 kfree(encoder); 3828 2270 } 3829 2271 3830 - static const struct drm_encoder_helper_funcs nv50_pior_hfunc = { 3831 - .dpms = nv50_pior_dpms, 3832 - .mode_fixup = nv50_pior_mode_fixup, 3833 - .prepare = nv50_pior_disconnect, 3834 - .commit = nv50_pior_commit, 3835 - .mode_set = nv50_pior_mode_set, 3836 - .disable = nv50_pior_disconnect, 3837 - .get_crtc = nv50_display_crtc_get, 3838 - }; 3839 - 3840 - static const struct drm_encoder_funcs nv50_pior_func = { 2272 + static const struct drm_encoder_funcs 2273 + nv50_pior_func = { 3841 2274 .destroy = nv50_pior_destroy, 3842 2275 }; 3843 2276 ··· 3870 2321 encoder = to_drm_encoder(nv_encoder); 3871 2322 encoder->possible_crtcs = dcbe->heads; 3872 2323 encoder->possible_clones = 0; 3873 - drm_encoder_init(connector->dev, encoder, &nv50_pior_func, type, NULL); 3874 - drm_encoder_helper_add(encoder, &nv50_pior_hfunc); 2324 + drm_encoder_init(connector->dev, encoder, &nv50_pior_func, type, 2325 + "pior-%04x-%04x", dcbe->hasht, dcbe->hashm); 2326 + drm_encoder_helper_add(encoder, &nv50_pior_help); 3875 2327 3876 2328 drm_mode_connector_attach_encoder(connector, encoder); 3877 2329 return 0; 3878 2330 } 3879 2331 3880 2332 /****************************************************************************** 3881 - * Framebuffer 2333 + * Atomic 3882 2334 *****************************************************************************/ 3883 2335 3884 2336 static void 3885 - nv50_fbdma_fini(struct nv50_fbdma *fbdma) 2337 + nv50_disp_atomic_commit_core(struct nouveau_drm *drm, u32 interlock) 3886 2338 { 3887 - int i; 3888 - for (i = 0; i < ARRAY_SIZE(fbdma->base); i++) 3889 - nvif_object_fini(&fbdma->base[i]); 3890 - nvif_object_fini(&fbdma->core); 3891 - list_del(&fbdma->head); 3892 - kfree(fbdma); 3893 - } 2339 + struct nv50_disp *disp = nv50_disp(drm->dev); 2340 + struct nv50_dmac *core = &disp->mast.base; 2341 + struct nv50_mstm *mstm; 2342 + struct drm_encoder *encoder; 2343 + u32 *push; 3894 2344 3895 - static int 3896 - nv50_fbdma_init(struct drm_device *dev, u32 name, u64 offset, u64 length, u8 kind) 3897 - { 3898 - struct nouveau_drm *drm = nouveau_drm(dev); 3899 - struct nv50_disp *disp = nv50_disp(dev); 3900 - struct nv50_mast *mast = nv50_mast(dev); 3901 - struct __attribute__ ((packed)) { 3902 - struct nv_dma_v0 base; 3903 - union { 3904 - struct nv50_dma_v0 nv50; 3905 - struct gf100_dma_v0 gf100; 3906 - struct gf119_dma_v0 gf119; 3907 - }; 3908 - } args = {}; 3909 - struct nv50_fbdma *fbdma; 3910 - struct drm_crtc *crtc; 3911 - u32 size = sizeof(args.base); 3912 - int ret; 2345 + NV_ATOMIC(drm, "commit core %08x\n", interlock); 3913 2346 3914 - list_for_each_entry(fbdma, &disp->fbdma, head) { 3915 - if (fbdma->core.handle == name) 3916 - return 0; 3917 - } 3918 - 3919 - fbdma = kzalloc(sizeof(*fbdma), GFP_KERNEL); 3920 - if (!fbdma) 3921 - return -ENOMEM; 3922 - list_add(&fbdma->head, &disp->fbdma); 3923 - 3924 - args.base.target = NV_DMA_V0_TARGET_VRAM; 3925 - args.base.access = NV_DMA_V0_ACCESS_RDWR; 3926 - args.base.start = offset; 3927 - args.base.limit = offset + length - 1; 3928 - 3929 - if (drm->device.info.chipset < 0x80) { 3930 - args.nv50.part = NV50_DMA_V0_PART_256; 3931 - size += sizeof(args.nv50); 3932 - } else 3933 - if (drm->device.info.chipset < 0xc0) { 3934 - args.nv50.part = NV50_DMA_V0_PART_256; 3935 - args.nv50.kind = kind; 3936 - size += sizeof(args.nv50); 3937 - } else 3938 - if (drm->device.info.chipset < 0xd0) { 3939 - args.gf100.kind = kind; 3940 - size += sizeof(args.gf100); 3941 - } else { 3942 - args.gf119.page = GF119_DMA_V0_PAGE_LP; 3943 - args.gf119.kind = kind; 3944 - size += sizeof(args.gf119); 3945 - } 3946 - 3947 - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 3948 - struct nv50_head *head = nv50_head(crtc); 3949 - int ret = nvif_object_init(&head->sync.base.base.user, name, 3950 - NV_DMA_IN_MEMORY, &args, size, 3951 - &fbdma->base[head->base.index]); 3952 - if (ret) { 3953 - nv50_fbdma_fini(fbdma); 3954 - return ret; 2347 + drm_for_each_encoder(encoder, drm->dev) { 2348 + if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) { 2349 + mstm = nouveau_encoder(encoder)->dp.mstm; 2350 + if (mstm && mstm->modified) 2351 + nv50_mstm_prepare(mstm); 3955 2352 } 3956 2353 } 3957 2354 3958 - ret = nvif_object_init(&mast->base.base.user, name, NV_DMA_IN_MEMORY, 3959 - &args, size, &fbdma->core); 3960 - if (ret) { 3961 - nv50_fbdma_fini(fbdma); 2355 + if ((push = evo_wait(core, 5))) { 2356 + evo_mthd(push, 0x0084, 1); 2357 + evo_data(push, 0x80000000); 2358 + evo_mthd(push, 0x0080, 2); 2359 + evo_data(push, interlock); 2360 + evo_data(push, 0x00000000); 2361 + nouveau_bo_wr32(disp->sync, 0, 0x00000000); 2362 + evo_kick(push, core); 2363 + if (nvif_msec(&drm->device, 2000ULL, 2364 + if (nouveau_bo_rd32(disp->sync, 0)) 2365 + break; 2366 + usleep_range(1, 2); 2367 + ) < 0) 2368 + NV_ERROR(drm, "EVO timeout\n"); 2369 + } 2370 + 2371 + drm_for_each_encoder(encoder, drm->dev) { 2372 + if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) { 2373 + mstm = nouveau_encoder(encoder)->dp.mstm; 2374 + if (mstm && mstm->modified) 2375 + nv50_mstm_cleanup(mstm); 2376 + } 2377 + } 2378 + } 2379 + 2380 + static void 2381 + nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) 2382 + { 2383 + struct drm_device *dev = state->dev; 2384 + struct drm_crtc_state *crtc_state; 2385 + struct drm_crtc *crtc; 2386 + struct drm_plane_state *plane_state; 2387 + struct drm_plane *plane; 2388 + struct nouveau_drm *drm = nouveau_drm(dev); 2389 + struct nv50_disp *disp = nv50_disp(dev); 2390 + struct nv50_atom *atom = nv50_atom(state); 2391 + struct nv50_outp_atom *outp, *outt; 2392 + u32 interlock_core = 0; 2393 + u32 interlock_chan = 0; 2394 + int i; 2395 + 2396 + NV_ATOMIC(drm, "commit %d %d\n", atom->lock_core, atom->flush_disable); 2397 + drm_atomic_helper_wait_for_fences(dev, state, false); 2398 + drm_atomic_helper_wait_for_dependencies(state); 2399 + drm_atomic_helper_update_legacy_modeset_state(dev, state); 2400 + 2401 + if (atom->lock_core) 2402 + mutex_lock(&disp->mutex); 2403 + 2404 + /* Disable head(s). */ 2405 + for_each_crtc_in_state(state, crtc, crtc_state, i) { 2406 + struct nv50_head_atom *asyh = nv50_head_atom(crtc->state); 2407 + struct nv50_head *head = nv50_head(crtc); 2408 + 2409 + NV_ATOMIC(drm, "%s: clr %04x (set %04x)\n", crtc->name, 2410 + asyh->clr.mask, asyh->set.mask); 2411 + 2412 + if (asyh->clr.mask) { 2413 + nv50_head_flush_clr(head, asyh, atom->flush_disable); 2414 + interlock_core |= 1; 2415 + } 2416 + } 2417 + 2418 + /* Disable plane(s). */ 2419 + for_each_plane_in_state(state, plane, plane_state, i) { 2420 + struct nv50_wndw_atom *asyw = nv50_wndw_atom(plane->state); 2421 + struct nv50_wndw *wndw = nv50_wndw(plane); 2422 + 2423 + NV_ATOMIC(drm, "%s: clr %02x (set %02x)\n", plane->name, 2424 + asyw->clr.mask, asyw->set.mask); 2425 + if (!asyw->clr.mask) 2426 + continue; 2427 + 2428 + interlock_chan |= nv50_wndw_flush_clr(wndw, interlock_core, 2429 + atom->flush_disable, 2430 + asyw); 2431 + } 2432 + 2433 + /* Disable output path(s). */ 2434 + list_for_each_entry(outp, &atom->outp, head) { 2435 + const struct drm_encoder_helper_funcs *help; 2436 + struct drm_encoder *encoder; 2437 + 2438 + encoder = outp->encoder; 2439 + help = encoder->helper_private; 2440 + 2441 + NV_ATOMIC(drm, "%s: clr %02x (set %02x)\n", encoder->name, 2442 + outp->clr.mask, outp->set.mask); 2443 + 2444 + if (outp->clr.mask) { 2445 + help->disable(encoder); 2446 + interlock_core |= 1; 2447 + if (outp->flush_disable) { 2448 + nv50_disp_atomic_commit_core(drm, interlock_chan); 2449 + interlock_core = 0; 2450 + interlock_chan = 0; 2451 + } 2452 + } 2453 + } 2454 + 2455 + /* Flush disable. */ 2456 + if (interlock_core) { 2457 + if (atom->flush_disable) { 2458 + nv50_disp_atomic_commit_core(drm, interlock_chan); 2459 + interlock_core = 0; 2460 + interlock_chan = 0; 2461 + } 2462 + } 2463 + 2464 + /* Update output path(s). */ 2465 + list_for_each_entry_safe(outp, outt, &atom->outp, head) { 2466 + const struct drm_encoder_helper_funcs *help; 2467 + struct drm_encoder *encoder; 2468 + 2469 + encoder = outp->encoder; 2470 + help = encoder->helper_private; 2471 + 2472 + NV_ATOMIC(drm, "%s: set %02x (clr %02x)\n", encoder->name, 2473 + outp->set.mask, outp->clr.mask); 2474 + 2475 + if (outp->set.mask) { 2476 + help->enable(encoder); 2477 + interlock_core = 1; 2478 + } 2479 + 2480 + list_del(&outp->head); 2481 + kfree(outp); 2482 + } 2483 + 2484 + /* Update head(s). */ 2485 + for_each_crtc_in_state(state, crtc, crtc_state, i) { 2486 + struct nv50_head_atom *asyh = nv50_head_atom(crtc->state); 2487 + struct nv50_head *head = nv50_head(crtc); 2488 + 2489 + NV_ATOMIC(drm, "%s: set %04x (clr %04x)\n", crtc->name, 2490 + asyh->set.mask, asyh->clr.mask); 2491 + 2492 + if (asyh->set.mask) { 2493 + nv50_head_flush_set(head, asyh); 2494 + interlock_core = 1; 2495 + } 2496 + } 2497 + 2498 + /* Update plane(s). */ 2499 + for_each_plane_in_state(state, plane, plane_state, i) { 2500 + struct nv50_wndw_atom *asyw = nv50_wndw_atom(plane->state); 2501 + struct nv50_wndw *wndw = nv50_wndw(plane); 2502 + 2503 + NV_ATOMIC(drm, "%s: set %02x (clr %02x)\n", plane->name, 2504 + asyw->set.mask, asyw->clr.mask); 2505 + if ( !asyw->set.mask && 2506 + (!asyw->clr.mask || atom->flush_disable)) 2507 + continue; 2508 + 2509 + interlock_chan |= nv50_wndw_flush_set(wndw, interlock_core, asyw); 2510 + } 2511 + 2512 + /* Flush update. */ 2513 + if (interlock_core) { 2514 + if (!interlock_chan && atom->state.legacy_cursor_update) { 2515 + u32 *push = evo_wait(&disp->mast, 2); 2516 + if (push) { 2517 + evo_mthd(push, 0x0080, 1); 2518 + evo_data(push, 0x00000000); 2519 + evo_kick(push, &disp->mast); 2520 + } 2521 + } else { 2522 + nv50_disp_atomic_commit_core(drm, interlock_chan); 2523 + } 2524 + } 2525 + 2526 + if (atom->lock_core) 2527 + mutex_unlock(&disp->mutex); 2528 + 2529 + /* Wait for HW to signal completion. */ 2530 + for_each_plane_in_state(state, plane, plane_state, i) { 2531 + struct nv50_wndw_atom *asyw = nv50_wndw_atom(plane->state); 2532 + struct nv50_wndw *wndw = nv50_wndw(plane); 2533 + int ret = nv50_wndw_wait_armed(wndw, asyw); 2534 + if (ret) 2535 + NV_ERROR(drm, "%s: timeout\n", plane->name); 2536 + } 2537 + 2538 + for_each_crtc_in_state(state, crtc, crtc_state, i) { 2539 + if (crtc->state->event) { 2540 + unsigned long flags; 2541 + spin_lock_irqsave(&crtc->dev->event_lock, flags); 2542 + drm_crtc_send_vblank_event(crtc, crtc->state->event); 2543 + spin_unlock_irqrestore(&crtc->dev->event_lock, flags); 2544 + crtc->state->event = NULL; 2545 + } 2546 + } 2547 + 2548 + drm_atomic_helper_commit_hw_done(state); 2549 + drm_atomic_helper_cleanup_planes(dev, state); 2550 + drm_atomic_helper_commit_cleanup_done(state); 2551 + drm_atomic_state_put(state); 2552 + } 2553 + 2554 + static void 2555 + nv50_disp_atomic_commit_work(struct work_struct *work) 2556 + { 2557 + struct drm_atomic_state *state = 2558 + container_of(work, typeof(*state), commit_work); 2559 + nv50_disp_atomic_commit_tail(state); 2560 + } 2561 + 2562 + static int 2563 + nv50_disp_atomic_commit(struct drm_device *dev, 2564 + struct drm_atomic_state *state, bool nonblock) 2565 + { 2566 + struct nouveau_drm *drm = nouveau_drm(dev); 2567 + struct nv50_disp *disp = nv50_disp(dev); 2568 + struct drm_plane_state *plane_state; 2569 + struct drm_plane *plane; 2570 + struct drm_crtc *crtc; 2571 + bool active = false; 2572 + int ret, i; 2573 + 2574 + ret = pm_runtime_get_sync(dev->dev); 2575 + if (ret < 0 && ret != -EACCES) 3962 2576 return ret; 2577 + 2578 + ret = drm_atomic_helper_setup_commit(state, nonblock); 2579 + if (ret) 2580 + goto done; 2581 + 2582 + INIT_WORK(&state->commit_work, nv50_disp_atomic_commit_work); 2583 + 2584 + ret = drm_atomic_helper_prepare_planes(dev, state); 2585 + if (ret) 2586 + goto done; 2587 + 2588 + if (!nonblock) { 2589 + ret = drm_atomic_helper_wait_for_fences(dev, state, true); 2590 + if (ret) 2591 + goto done; 2592 + } 2593 + 2594 + for_each_plane_in_state(state, plane, plane_state, i) { 2595 + struct nv50_wndw_atom *asyw = nv50_wndw_atom(plane_state); 2596 + struct nv50_wndw *wndw = nv50_wndw(plane); 2597 + if (asyw->set.image) { 2598 + asyw->ntfy.handle = wndw->dmac->sync.handle; 2599 + asyw->ntfy.offset = wndw->ntfy; 2600 + asyw->ntfy.awaken = false; 2601 + asyw->set.ntfy = true; 2602 + nouveau_bo_wr32(disp->sync, wndw->ntfy / 4, 0x00000000); 2603 + wndw->ntfy ^= 0x10; 2604 + } 2605 + } 2606 + 2607 + drm_atomic_helper_swap_state(state, true); 2608 + drm_atomic_state_get(state); 2609 + 2610 + if (nonblock) 2611 + queue_work(system_unbound_wq, &state->commit_work); 2612 + else 2613 + nv50_disp_atomic_commit_tail(state); 2614 + 2615 + drm_for_each_crtc(crtc, dev) { 2616 + if (crtc->state->enable) { 2617 + if (!drm->have_disp_power_ref) { 2618 + drm->have_disp_power_ref = true; 2619 + return ret; 2620 + } 2621 + active = true; 2622 + break; 2623 + } 2624 + } 2625 + 2626 + if (!active && drm->have_disp_power_ref) { 2627 + pm_runtime_put_autosuspend(dev->dev); 2628 + drm->have_disp_power_ref = false; 2629 + } 2630 + 2631 + done: 2632 + pm_runtime_put_autosuspend(dev->dev); 2633 + return ret; 2634 + } 2635 + 2636 + static struct nv50_outp_atom * 2637 + nv50_disp_outp_atomic_add(struct nv50_atom *atom, struct drm_encoder *encoder) 2638 + { 2639 + struct nv50_outp_atom *outp; 2640 + 2641 + list_for_each_entry(outp, &atom->outp, head) { 2642 + if (outp->encoder == encoder) 2643 + return outp; 2644 + } 2645 + 2646 + outp = kzalloc(sizeof(*outp), GFP_KERNEL); 2647 + if (!outp) 2648 + return ERR_PTR(-ENOMEM); 2649 + 2650 + list_add(&outp->head, &atom->outp); 2651 + outp->encoder = encoder; 2652 + return outp; 2653 + } 2654 + 2655 + static int 2656 + nv50_disp_outp_atomic_check_clr(struct nv50_atom *atom, 2657 + struct drm_connector *connector) 2658 + { 2659 + struct drm_encoder *encoder = connector->state->best_encoder; 2660 + struct drm_crtc_state *crtc_state; 2661 + struct drm_crtc *crtc; 2662 + struct nv50_outp_atom *outp; 2663 + 2664 + if (!(crtc = connector->state->crtc)) 2665 + return 0; 2666 + 2667 + crtc_state = drm_atomic_get_existing_crtc_state(&atom->state, crtc); 2668 + if (crtc->state->active && drm_atomic_crtc_needs_modeset(crtc_state)) { 2669 + outp = nv50_disp_outp_atomic_add(atom, encoder); 2670 + if (IS_ERR(outp)) 2671 + return PTR_ERR(outp); 2672 + 2673 + if (outp->encoder->encoder_type == DRM_MODE_ENCODER_DPMST) { 2674 + outp->flush_disable = true; 2675 + atom->flush_disable = true; 2676 + } 2677 + outp->clr.ctrl = true; 2678 + atom->lock_core = true; 2679 + } 2680 + 2681 + return 0; 2682 + } 2683 + 2684 + static int 2685 + nv50_disp_outp_atomic_check_set(struct nv50_atom *atom, 2686 + struct drm_connector_state *connector_state) 2687 + { 2688 + struct drm_encoder *encoder = connector_state->best_encoder; 2689 + struct drm_crtc_state *crtc_state; 2690 + struct drm_crtc *crtc; 2691 + struct nv50_outp_atom *outp; 2692 + 2693 + if (!(crtc = connector_state->crtc)) 2694 + return 0; 2695 + 2696 + crtc_state = drm_atomic_get_existing_crtc_state(&atom->state, crtc); 2697 + if (crtc_state->active && drm_atomic_crtc_needs_modeset(crtc_state)) { 2698 + outp = nv50_disp_outp_atomic_add(atom, encoder); 2699 + if (IS_ERR(outp)) 2700 + return PTR_ERR(outp); 2701 + 2702 + outp->set.ctrl = true; 2703 + atom->lock_core = true; 2704 + } 2705 + 2706 + return 0; 2707 + } 2708 + 2709 + static int 2710 + nv50_disp_atomic_check(struct drm_device *dev, struct drm_atomic_state *state) 2711 + { 2712 + struct nv50_atom *atom = nv50_atom(state); 2713 + struct drm_connector_state *connector_state; 2714 + struct drm_connector *connector; 2715 + int ret, i; 2716 + 2717 + ret = drm_atomic_helper_check(dev, state); 2718 + if (ret) 2719 + return ret; 2720 + 2721 + for_each_connector_in_state(state, connector, connector_state, i) { 2722 + ret = nv50_disp_outp_atomic_check_clr(atom, connector); 2723 + if (ret) 2724 + return ret; 2725 + 2726 + ret = nv50_disp_outp_atomic_check_set(atom, connector_state); 2727 + if (ret) 2728 + return ret; 3963 2729 } 3964 2730 3965 2731 return 0; 3966 2732 } 3967 2733 3968 2734 static void 3969 - nv50_fb_dtor(struct drm_framebuffer *fb) 2735 + nv50_disp_atomic_state_clear(struct drm_atomic_state *state) 3970 2736 { 3971 - } 2737 + struct nv50_atom *atom = nv50_atom(state); 2738 + struct nv50_outp_atom *outp, *outt; 3972 2739 3973 - static int 3974 - nv50_fb_ctor(struct drm_framebuffer *fb) 3975 - { 3976 - struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb); 3977 - struct nouveau_drm *drm = nouveau_drm(fb->dev); 3978 - struct nouveau_bo *nvbo = nv_fb->nvbo; 3979 - struct nv50_disp *disp = nv50_disp(fb->dev); 3980 - u8 kind = nouveau_bo_tile_layout(nvbo) >> 8; 3981 - u8 tile = nvbo->tile_mode; 3982 - 3983 - if (drm->device.info.chipset >= 0xc0) 3984 - tile >>= 4; /* yep.. */ 3985 - 3986 - switch (fb->depth) { 3987 - case 8: nv_fb->r_format = 0x1e00; break; 3988 - case 15: nv_fb->r_format = 0xe900; break; 3989 - case 16: nv_fb->r_format = 0xe800; break; 3990 - case 24: 3991 - case 32: nv_fb->r_format = 0xcf00; break; 3992 - case 30: nv_fb->r_format = 0xd100; break; 3993 - default: 3994 - NV_ERROR(drm, "unknown depth %d\n", fb->depth); 3995 - return -EINVAL; 2740 + list_for_each_entry_safe(outp, outt, &atom->outp, head) { 2741 + list_del(&outp->head); 2742 + kfree(outp); 3996 2743 } 3997 2744 3998 - if (disp->disp->oclass < G82_DISP) { 3999 - nv_fb->r_pitch = kind ? (((fb->pitches[0] / 4) << 4) | tile) : 4000 - (fb->pitches[0] | 0x00100000); 4001 - nv_fb->r_format |= kind << 16; 4002 - } else 4003 - if (disp->disp->oclass < GF110_DISP) { 4004 - nv_fb->r_pitch = kind ? (((fb->pitches[0] / 4) << 4) | tile) : 4005 - (fb->pitches[0] | 0x00100000); 4006 - } else { 4007 - nv_fb->r_pitch = kind ? (((fb->pitches[0] / 4) << 4) | tile) : 4008 - (fb->pitches[0] | 0x01000000); 4009 - } 4010 - nv_fb->r_handle = 0xffff0000 | kind; 4011 - 4012 - return nv50_fbdma_init(fb->dev, nv_fb->r_handle, 0, 4013 - drm->device.info.ram_user, kind); 2745 + drm_atomic_state_default_clear(state); 4014 2746 } 2747 + 2748 + static void 2749 + nv50_disp_atomic_state_free(struct drm_atomic_state *state) 2750 + { 2751 + struct nv50_atom *atom = nv50_atom(state); 2752 + drm_atomic_state_default_release(&atom->state); 2753 + kfree(atom); 2754 + } 2755 + 2756 + static struct drm_atomic_state * 2757 + nv50_disp_atomic_state_alloc(struct drm_device *dev) 2758 + { 2759 + struct nv50_atom *atom; 2760 + if (!(atom = kzalloc(sizeof(*atom), GFP_KERNEL)) || 2761 + drm_atomic_state_init(dev, &atom->state) < 0) { 2762 + kfree(atom); 2763 + return NULL; 2764 + } 2765 + INIT_LIST_HEAD(&atom->outp); 2766 + return &atom->state; 2767 + } 2768 + 2769 + static const struct drm_mode_config_funcs 2770 + nv50_disp_func = { 2771 + .fb_create = nouveau_user_framebuffer_create, 2772 + .output_poll_changed = nouveau_fbcon_output_poll_changed, 2773 + .atomic_check = nv50_disp_atomic_check, 2774 + .atomic_commit = nv50_disp_atomic_commit, 2775 + .atomic_state_alloc = nv50_disp_atomic_state_alloc, 2776 + .atomic_state_clear = nv50_disp_atomic_state_clear, 2777 + .atomic_state_free = nv50_disp_atomic_state_free, 2778 + }; 4015 2779 4016 2780 /****************************************************************************** 4017 2781 * Init ··· 4333 2471 void 4334 2472 nv50_display_fini(struct drm_device *dev) 4335 2473 { 2474 + struct nouveau_encoder *nv_encoder; 2475 + struct drm_encoder *encoder; 2476 + struct drm_plane *plane; 2477 + 2478 + drm_for_each_plane(plane, dev) { 2479 + struct nv50_wndw *wndw = nv50_wndw(plane); 2480 + if (plane->funcs != &nv50_wndw) 2481 + continue; 2482 + nv50_wndw_fini(wndw); 2483 + } 2484 + 2485 + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 2486 + if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) { 2487 + nv_encoder = nouveau_encoder(encoder); 2488 + nv50_mstm_fini(nv_encoder->dp.mstm); 2489 + } 2490 + } 4336 2491 } 4337 2492 4338 2493 int 4339 2494 nv50_display_init(struct drm_device *dev) 4340 2495 { 4341 - struct nv50_disp *disp = nv50_disp(dev); 2496 + struct drm_encoder *encoder; 2497 + struct drm_plane *plane; 4342 2498 struct drm_crtc *crtc; 4343 2499 u32 *push; 4344 2500 ··· 4364 2484 if (!push) 4365 2485 return -EBUSY; 4366 2486 4367 - list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 4368 - struct nv50_sync *sync = nv50_sync(crtc); 4369 - 4370 - nv50_crtc_lut_load(crtc); 4371 - nouveau_bo_wr32(disp->sync, sync->addr / 4, sync->data); 4372 - } 4373 - 4374 2487 evo_mthd(push, 0x0088, 1); 4375 2488 evo_data(push, nv50_mast(dev)->base.sync.handle); 4376 2489 evo_kick(push, nv50_mast(dev)); 2490 + 2491 + list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { 2492 + if (encoder->encoder_type != DRM_MODE_ENCODER_DPMST) { 2493 + const struct drm_encoder_helper_funcs *help; 2494 + struct nouveau_encoder *nv_encoder; 2495 + 2496 + nv_encoder = nouveau_encoder(encoder); 2497 + help = encoder->helper_private; 2498 + if (help && help->dpms) 2499 + help->dpms(encoder, DRM_MODE_DPMS_ON); 2500 + 2501 + nv50_mstm_init(nv_encoder->dp.mstm); 2502 + } 2503 + } 2504 + 2505 + drm_for_each_crtc(crtc, dev) { 2506 + nv50_head_lut_load(crtc); 2507 + } 2508 + 2509 + drm_for_each_plane(plane, dev) { 2510 + struct nv50_wndw *wndw = nv50_wndw(plane); 2511 + if (plane->funcs != &nv50_wndw) 2512 + continue; 2513 + nv50_wndw_init(wndw); 2514 + } 2515 + 4377 2516 return 0; 4378 2517 } 4379 2518 ··· 4400 2501 nv50_display_destroy(struct drm_device *dev) 4401 2502 { 4402 2503 struct nv50_disp *disp = nv50_disp(dev); 4403 - struct nv50_fbdma *fbdma, *fbtmp; 4404 - 4405 - list_for_each_entry_safe(fbdma, fbtmp, &disp->fbdma, head) { 4406 - nv50_fbdma_fini(fbdma); 4407 - } 4408 2504 4409 2505 nv50_dmac_destroy(&disp->mast.base, disp->disp); 4410 2506 ··· 4411 2517 nouveau_display(dev)->priv = NULL; 4412 2518 kfree(disp); 4413 2519 } 2520 + 2521 + MODULE_PARM_DESC(atomic, "Expose atomic ioctl (default: disabled)"); 2522 + static int nouveau_atomic = 0; 2523 + module_param_named(atomic, nouveau_atomic, int, 0400); 4414 2524 4415 2525 int 4416 2526 nv50_display_create(struct drm_device *dev) ··· 4430 2532 disp = kzalloc(sizeof(*disp), GFP_KERNEL); 4431 2533 if (!disp) 4432 2534 return -ENOMEM; 4433 - INIT_LIST_HEAD(&disp->fbdma); 2535 + 2536 + mutex_init(&disp->mutex); 4434 2537 4435 2538 nouveau_display(dev)->priv = disp; 4436 2539 nouveau_display(dev)->dtor = nv50_display_destroy; 4437 2540 nouveau_display(dev)->init = nv50_display_init; 4438 2541 nouveau_display(dev)->fini = nv50_display_fini; 4439 - nouveau_display(dev)->fb_ctor = nv50_fb_ctor; 4440 - nouveau_display(dev)->fb_dtor = nv50_fb_dtor; 4441 2542 disp->disp = &nouveau_display(dev)->disp; 2543 + dev->mode_config.funcs = &nv50_disp_func; 2544 + if (nouveau_atomic) 2545 + dev->driver->driver_features |= DRIVER_ATOMIC; 4442 2546 4443 2547 /* small shared memory area we use for notifiers and semaphores */ 4444 2548 ret = nouveau_bo_new(dev, 4096, 0x1000, TTM_PL_FLAG_VRAM, ··· 4472 2572 crtcs = 2; 4473 2573 4474 2574 for (i = 0; i < crtcs; i++) { 4475 - ret = nv50_crtc_create(dev, i); 2575 + ret = nv50_head_create(dev, i); 4476 2576 if (ret) 4477 2577 goto out; 4478 2578 }
-7
drivers/gpu/drm/nouveau/nv50_display.h
··· 35 35 void nv50_display_destroy(struct drm_device *); 36 36 int nv50_display_init(struct drm_device *); 37 37 void nv50_display_fini(struct drm_device *); 38 - 39 - void nv50_display_flip_stop(struct drm_crtc *); 40 - int nv50_display_flip_next(struct drm_crtc *, struct drm_framebuffer *, 41 - struct nouveau_channel *, u32 swap_interval); 42 - 43 - struct nouveau_bo *nv50_display_crtc_sema(struct drm_device *, int head); 44 - 45 38 #endif /* __NV50_DISPLAY_H__ */
+5 -5
drivers/gpu/drm/nouveau/nv50_fbcon.c
··· 30 30 nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 31 31 { 32 32 struct nouveau_fbdev *nfbdev = info->par; 33 - struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); 33 + struct nouveau_drm *drm = nouveau_drm(nfbdev->helper.dev); 34 34 struct nouveau_channel *chan = drm->channel; 35 35 int ret; 36 36 ··· 65 65 nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) 66 66 { 67 67 struct nouveau_fbdev *nfbdev = info->par; 68 - struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); 68 + struct nouveau_drm *drm = nouveau_drm(nfbdev->helper.dev); 69 69 struct nouveau_channel *chan = drm->channel; 70 70 int ret; 71 71 ··· 93 93 nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) 94 94 { 95 95 struct nouveau_fbdev *nfbdev = info->par; 96 - struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); 96 + struct nouveau_drm *drm = nouveau_drm(nfbdev->helper.dev); 97 97 struct nouveau_channel *chan = drm->channel; 98 98 uint32_t dwords, *data = (uint32_t *)image->data; 99 99 uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); ··· 148 148 nv50_fbcon_accel_init(struct fb_info *info) 149 149 { 150 150 struct nouveau_fbdev *nfbdev = info->par; 151 - struct nouveau_framebuffer *fb = &nfbdev->nouveau_fb; 152 - struct drm_device *dev = nfbdev->dev; 151 + struct nouveau_framebuffer *fb = nouveau_framebuffer(nfbdev->helper.fb); 152 + struct drm_device *dev = nfbdev->helper.dev; 153 153 struct nouveau_drm *drm = nouveau_drm(dev); 154 154 struct nouveau_channel *chan = drm->channel; 155 155 int ret, format;
+1 -19
drivers/gpu/drm/nouveau/nv50_fence.c
··· 35 35 static int 36 36 nv50_fence_context_new(struct nouveau_channel *chan) 37 37 { 38 - struct drm_device *dev = chan->drm->dev; 39 38 struct nv10_fence_priv *priv = chan->drm->fence; 40 39 struct nv10_fence_chan *fctx; 41 40 struct ttm_mem_reg *mem = &priv->bo->bo.mem; 42 41 u32 start = mem->start * PAGE_SIZE; 43 42 u32 limit = start + mem->size - 1; 44 - int ret, i; 43 + int ret; 45 44 46 45 fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); 47 46 if (!fctx) ··· 59 60 .limit = limit, 60 61 }, sizeof(struct nv_dma_v0), 61 62 &fctx->sema); 62 - 63 - /* dma objects for display sync channel semaphore blocks */ 64 - for (i = 0; !ret && i < dev->mode_config.num_crtc; i++) { 65 - struct nouveau_bo *bo = nv50_display_crtc_sema(dev, i); 66 - u32 start = bo->bo.mem.start * PAGE_SIZE; 67 - u32 limit = start + bo->bo.mem.size - 1; 68 - 69 - ret = nvif_object_init(&chan->user, NvEvoSema0 + i, 70 - NV_DMA_IN_MEMORY, &(struct nv_dma_v0) { 71 - .target = NV_DMA_V0_TARGET_VRAM, 72 - .access = NV_DMA_V0_ACCESS_RDWR, 73 - .start = start, 74 - .limit = limit, 75 - }, sizeof(struct nv_dma_v0), 76 - &fctx->head[i]); 77 - } 78 - 79 63 if (ret) 80 64 nv10_fence_context_del(chan); 81 65 return ret;
+1 -21
drivers/gpu/drm/nouveau/nv84_fence.c
··· 28 28 29 29 #include "nv50_display.h" 30 30 31 - u64 32 - nv84_fence_crtc(struct nouveau_channel *chan, int crtc) 33 - { 34 - struct nv84_fence_chan *fctx = chan->fence; 35 - return fctx->dispc_vma[crtc].offset; 36 - } 37 - 38 31 static int 39 32 nv84_fence_emit32(struct nouveau_channel *chan, u64 virtual, u32 sequence) 40 33 { ··· 103 110 static void 104 111 nv84_fence_context_del(struct nouveau_channel *chan) 105 112 { 106 - struct drm_device *dev = chan->drm->dev; 107 113 struct nv84_fence_priv *priv = chan->drm->fence; 108 114 struct nv84_fence_chan *fctx = chan->fence; 109 - int i; 110 - 111 - for (i = 0; i < dev->mode_config.num_crtc; i++) { 112 - struct nouveau_bo *bo = nv50_display_crtc_sema(dev, i); 113 - nouveau_bo_vma_del(bo, &fctx->dispc_vma[i]); 114 - } 115 115 116 116 nouveau_bo_wr32(priv->bo, chan->chid * 16 / 4, fctx->base.sequence); 117 117 nouveau_bo_vma_del(priv->bo, &fctx->vma_gart); ··· 120 134 struct nouveau_cli *cli = (void *)chan->user.client; 121 135 struct nv84_fence_priv *priv = chan->drm->fence; 122 136 struct nv84_fence_chan *fctx; 123 - int ret, i; 137 + int ret; 124 138 125 139 fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL); 126 140 if (!fctx) ··· 138 152 if (ret == 0) { 139 153 ret = nouveau_bo_vma_add(priv->bo_gart, cli->vm, 140 154 &fctx->vma_gart); 141 - } 142 - 143 - /* map display semaphore buffers into channel's vm */ 144 - for (i = 0; !ret && i < chan->drm->dev->mode_config.num_crtc; i++) { 145 - struct nouveau_bo *bo = nv50_display_crtc_sema(chan->drm->dev, i); 146 - ret = nouveau_bo_vma_add(bo, cli->vm, &fctx->dispc_vma[i]); 147 155 } 148 156 149 157 if (ret)
+5 -5
drivers/gpu/drm/nouveau/nvc0_fbcon.c
··· 30 30 nvc0_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 31 31 { 32 32 struct nouveau_fbdev *nfbdev = info->par; 33 - struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); 33 + struct nouveau_drm *drm = nouveau_drm(nfbdev->helper.dev); 34 34 struct nouveau_channel *chan = drm->channel; 35 35 int ret; 36 36 ··· 65 65 nvc0_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) 66 66 { 67 67 struct nouveau_fbdev *nfbdev = info->par; 68 - struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); 68 + struct nouveau_drm *drm = nouveau_drm(nfbdev->helper.dev); 69 69 struct nouveau_channel *chan = drm->channel; 70 70 int ret; 71 71 ··· 93 93 nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) 94 94 { 95 95 struct nouveau_fbdev *nfbdev = info->par; 96 - struct nouveau_drm *drm = nouveau_drm(nfbdev->dev); 96 + struct nouveau_drm *drm = nouveau_drm(nfbdev->helper.dev); 97 97 struct nouveau_channel *chan = drm->channel; 98 98 uint32_t dwords, *data = (uint32_t *)image->data; 99 99 uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); ··· 148 148 nvc0_fbcon_accel_init(struct fb_info *info) 149 149 { 150 150 struct nouveau_fbdev *nfbdev = info->par; 151 - struct drm_device *dev = nfbdev->dev; 152 - struct nouveau_framebuffer *fb = &nfbdev->nouveau_fb; 151 + struct drm_device *dev = nfbdev->helper.dev; 152 + struct nouveau_framebuffer *fb = nouveau_framebuffer(nfbdev->helper.fb); 153 153 struct nouveau_drm *drm = nouveau_drm(dev); 154 154 struct nouveau_channel *chan = drm->channel; 155 155 int ret, format;
+1 -1
drivers/gpu/drm/nouveau/nvif/client.c
··· 55 55 } 56 56 } 57 57 58 - const struct nvif_driver * 58 + static const struct nvif_driver * 59 59 nvif_drivers[] = { 60 60 #ifdef __KERNEL__ 61 61 &nvif_driver_nvkm,
+2 -4
drivers/gpu/drm/nouveau/nvif/notify.c
··· 155 155 int ret = nvif_notify_put(notify); 156 156 if (ret >= 0 && object) { 157 157 ret = nvif_object_ioctl(object, &args, sizeof(args), NULL); 158 - if (ret == 0) { 159 - notify->object = NULL; 160 - kfree((void *)notify->data); 161 - } 158 + notify->object = NULL; 159 + kfree((void *)notify->data); 162 160 } 163 161 return ret; 164 162 }
+2 -2
drivers/gpu/drm/nouveau/nvkm/engine/ce/fuc/gf100.fuc3.h
··· 1 - uint32_t gf100_ce_data[] = { 1 + static uint32_t gf100_ce_data[] = { 2 2 /* 0x0000: ctx_object */ 3 3 0x00000000, 4 4 /* 0x0004: ctx_query_address_high */ ··· 171 171 0x00000800, 172 172 }; 173 173 174 - uint32_t gf100_ce_code[] = { 174 + static uint32_t gf100_ce_code[] = { 175 175 /* 0x0000: main */ 176 176 0x04fe04bd, 177 177 0x3517f000,
+2 -2
drivers/gpu/drm/nouveau/nvkm/engine/ce/fuc/gt215.fuc3.h
··· 1 - uint32_t gt215_ce_data[] = { 1 + static uint32_t gt215_ce_data[] = { 2 2 /* 0x0000: ctx_object */ 3 3 0x00000000, 4 4 /* 0x0004: ctx_dma */ ··· 183 183 0x00000800, 184 184 }; 185 185 186 - uint32_t gt215_ce_code[] = { 186 + static uint32_t gt215_ce_code[] = { 187 187 /* 0x0000: main */ 188 188 0x04fe04bd, 189 189 0x3517f000,
+4 -4
drivers/gpu/drm/nouveau/nvkm/engine/device/base.c
··· 1852 1852 .fb = gk104_fb_new, 1853 1853 .fuse = gf100_fuse_new, 1854 1854 .gpio = gk104_gpio_new, 1855 - .i2c = gf119_i2c_new, 1855 + .i2c = gk104_i2c_new, 1856 1856 .ibus = gk104_ibus_new, 1857 1857 .iccsense = gf100_iccsense_new, 1858 1858 .imem = nv50_instmem_new, ··· 1966 1966 .fb = gm107_fb_new, 1967 1967 .fuse = gm107_fuse_new, 1968 1968 .gpio = gk104_gpio_new, 1969 - .i2c = gf119_i2c_new, 1969 + .i2c = gk104_i2c_new, 1970 1970 .ibus = gk104_ibus_new, 1971 1971 .iccsense = gf100_iccsense_new, 1972 1972 .imem = nv50_instmem_new, ··· 2000 2000 .fb = gm107_fb_new, 2001 2001 .fuse = gm107_fuse_new, 2002 2002 .gpio = gk104_gpio_new, 2003 - .i2c = gf119_i2c_new, 2003 + .i2c = gk104_i2c_new, 2004 2004 .ibus = gk104_ibus_new, 2005 2005 .iccsense = gf100_iccsense_new, 2006 2006 .imem = nv50_instmem_new, ··· 2131 2131 .bar = gk20a_bar_new, 2132 2132 .bus = gf100_bus_new, 2133 2133 .clk = gm20b_clk_new, 2134 - .fb = gk20a_fb_new, 2134 + .fb = gm20b_fb_new, 2135 2135 .fuse = gm107_fuse_new, 2136 2136 .ibus = gk20a_ibus_new, 2137 2137 .imem = gk20a_instmem_new,
+1 -1
drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c
··· 102 102 103 103 if (iommu_present(&platform_bus_type)) { 104 104 tdev->iommu.domain = iommu_domain_alloc(&platform_bus_type); 105 - if (IS_ERR(tdev->iommu.domain)) 105 + if (!tdev->iommu.domain) 106 106 goto error; 107 107 108 108 /*
+1 -1
drivers/gpu/drm/nouveau/nvkm/engine/device/user.c
··· 326 326 .sclass = nvkm_udevice_child_get, 327 327 }; 328 328 329 - int 329 + static int 330 330 nvkm_udevice_new(const struct nvkm_oclass *oclass, void *data, u32 size, 331 331 struct nvkm_object **pobject) 332 332 {
+4 -4
drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c
··· 153 153 .fini = nv50_disp_chan_uevent_fini, 154 154 }; 155 155 156 - int 156 + static int 157 157 nv50_disp_chan_rd32(struct nvkm_object *object, u64 addr, u32 *data) 158 158 { 159 159 struct nv50_disp_chan *chan = nv50_disp_chan(object); ··· 163 163 return 0; 164 164 } 165 165 166 - int 166 + static int 167 167 nv50_disp_chan_wr32(struct nvkm_object *object, u64 addr, u32 data) 168 168 { 169 169 struct nv50_disp_chan *chan = nv50_disp_chan(object); ··· 173 173 return 0; 174 174 } 175 175 176 - int 176 + static int 177 177 nv50_disp_chan_ntfy(struct nvkm_object *object, u32 type, 178 178 struct nvkm_event **pevent) 179 179 { ··· 189 189 return -EINVAL; 190 190 } 191 191 192 - int 192 + static int 193 193 nv50_disp_chan_map(struct nvkm_object *object, u64 *addr, u32 *size) 194 194 { 195 195 struct nv50_disp_chan *chan = nv50_disp_chan(object);
+3 -3
drivers/gpu/drm/nouveau/nvkm/engine/disp/coreg94.c
··· 26 26 27 27 #include <nvif/class.h> 28 28 29 - const struct nv50_disp_mthd_list 29 + static const struct nv50_disp_mthd_list 30 30 g94_disp_core_mthd_sor = { 31 31 .mthd = 0x0040, 32 32 .addr = 0x000008, ··· 43 43 .prev = 0x000004, 44 44 .data = { 45 45 { "Global", 1, &nv50_disp_core_mthd_base }, 46 - { "DAC", 3, &g84_disp_core_mthd_dac }, 47 - { "SOR", 4, &g94_disp_core_mthd_sor }, 46 + { "DAC", 3, &g84_disp_core_mthd_dac }, 47 + { "SOR", 4, &g94_disp_core_mthd_sor }, 48 48 { "PIOR", 3, &nv50_disp_core_mthd_pior }, 49 49 { "HEAD", 2, &g84_disp_core_mthd_head }, 50 50 {}
+1 -1
drivers/gpu/drm/nouveau/nvkm/engine/disp/coregp104.c
··· 59 59 return 0; 60 60 } 61 61 62 - const struct nv50_disp_dmac_func 62 + static const struct nv50_disp_dmac_func 63 63 gp104_disp_core_func = { 64 64 .init = gp104_disp_core_init, 65 65 .fini = gf119_disp_core_fini,
+1 -8
drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.c
··· 319 319 }; 320 320 321 321 void 322 - nvkm_dp_train(struct work_struct *w) 322 + nvkm_dp_train(struct nvkm_output_dp *outp) 323 323 { 324 - struct nvkm_output_dp *outp = container_of(w, typeof(*outp), lt.work); 325 324 struct nv50_disp *disp = nv50_disp(outp->base.disp); 326 325 const struct dp_rates *cfg = nvkm_dp_rates; 327 326 struct dp_state _dp = { ··· 351 352 cfg++; 352 353 } 353 354 cfg--; 354 - 355 - /* disable link interrupt handling during link training */ 356 - nvkm_notify_put(&outp->irq); 357 355 358 356 /* ensure sink is not in a low-power state */ 359 357 if (!nvkm_rdaux(outp->aux, DPCD_SC00, &pwr, 1)) { ··· 396 400 397 401 dp_link_train_fini(dp); 398 402 399 - /* signal completion and enable link interrupt handling */ 400 403 OUTP_DBG(&outp->base, "training complete"); 401 404 atomic_set(&outp->lt.done, 1); 402 - wake_up(&outp->lt.wait); 403 - nvkm_notify_get(&outp->irq); 404 405 }
+2 -2
drivers/gpu/drm/nouveau/nvkm/engine/disp/dport.h
··· 1 1 #ifndef __NVKM_DISP_DPORT_H__ 2 2 #define __NVKM_DISP_DPORT_H__ 3 - #include <core/os.h> 3 + struct nvkm_output_dp; 4 4 5 5 /* DPCD Receiver Capabilities */ 6 6 #define DPCD_RC00_DPCD_REV 0x00000 ··· 77 77 #define DPCD_SC00_SET_POWER_D0 0x01 78 78 #define DPCD_SC00_SET_POWER_D3 0x03 79 79 80 - void nvkm_dp_train(struct work_struct *); 80 + void nvkm_dp_train(struct nvkm_output_dp *); 81 81 #endif
+14 -11
drivers/gpu/drm/nouveau/nvkm/engine/disp/gf119.c
··· 203 203 /* see note in nv50_disp_intr_unk20_0() */ 204 204 if (outp && outp->info.type == DCB_OUTPUT_DP) { 205 205 struct nvkm_output_dp *outpdp = nvkm_output_dp(outp); 206 - struct nvbios_init init = { 207 - .subdev = subdev, 208 - .bios = subdev->device->bios, 209 - .outp = &outp->info, 210 - .crtc = head, 211 - .offset = outpdp->info.script[4], 212 - .execute = 1, 213 - }; 206 + if (!outpdp->lt.mst) { 207 + struct nvbios_init init = { 208 + .subdev = subdev, 209 + .bios = subdev->device->bios, 210 + .outp = &outp->info, 211 + .crtc = head, 212 + .offset = outpdp->info.script[4], 213 + .execute = 1, 214 + }; 214 215 215 - nvbios_exec(&init); 216 - atomic_set(&outpdp->lt.done, 0); 216 + nvkm_notify_put(&outpdp->irq); 217 + nvbios_exec(&init); 218 + atomic_set(&outpdp->lt.done, 0); 219 + } 217 220 } 218 221 } 219 222 ··· 317 314 break; 318 315 } 319 316 320 - if (nvkm_output_dp_train(outp, pclk, true)) 317 + if (nvkm_output_dp_train(outp, pclk)) 321 318 OUTP_ERR(outp, "link not trained before attach"); 322 319 } else { 323 320 if (disp->func->sor.magic)
+2 -1
drivers/gpu/drm/nouveau/nvkm/engine/disp/nv50.c
··· 590 590 .execute = 1, 591 591 }; 592 592 593 + nvkm_notify_put(&outpdp->irq); 593 594 nvbios_exec(&init); 594 595 atomic_set(&outpdp->lt.done, 0); 595 596 } ··· 780 779 break; 781 780 } 782 781 783 - if (nvkm_output_dp_train(outp, datarate / soff, true)) 782 + if (nvkm_output_dp_train(outp, datarate / soff)) 784 783 OUTP_ERR(outp, "link not trained before attach"); 785 784 } 786 785
+12 -21
drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.c
··· 31 31 #include <nvif/event.h> 32 32 33 33 int 34 - nvkm_output_dp_train(struct nvkm_output *base, u32 datarate, bool wait) 34 + nvkm_output_dp_train(struct nvkm_output *base, u32 datarate) 35 35 { 36 36 struct nvkm_output_dp *outp = nvkm_output_dp(base); 37 37 bool retrain = true; 38 38 u8 link[2], stat[3]; 39 39 u32 linkrate; 40 40 int ret, i; 41 + 42 + mutex_lock(&outp->mutex); 41 43 42 44 /* check that the link is trained at a high enough rate */ 43 45 ret = nvkm_rdaux(outp->aux, DPCD_LC00_LINK_BW_SET, link, 2); ··· 90 88 outp->dpcd[DPCD_RC02] = 91 89 outp->base.info.dpconf.link_nr; 92 90 } 93 - atomic_set(&outp->lt.done, 0); 94 - schedule_work(&outp->lt.work); 95 - } else { 96 - nvkm_notify_get(&outp->irq); 91 + nvkm_dp_train(outp); 97 92 } 98 93 99 - if (wait) { 100 - if (!wait_event_timeout(outp->lt.wait, 101 - atomic_read(&outp->lt.done), 102 - msecs_to_jiffies(2000))) 103 - ret = -ETIMEDOUT; 104 - } 105 - 94 + mutex_unlock(&outp->mutex); 106 95 return ret; 107 96 } 108 97 ··· 111 118 112 119 if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dpcd, 113 120 sizeof(outp->dpcd))) { 114 - nvkm_output_dp_train(&outp->base, 0, true); 121 + nvkm_output_dp_train(&outp->base, 0); 115 122 return; 116 123 } 117 124 } ··· 158 165 }; 159 166 160 167 OUTP_DBG(&outp->base, "IRQ: %d", line->mask); 161 - nvkm_output_dp_train(&outp->base, 0, true); 168 + nvkm_output_dp_train(&outp->base, 0); 162 169 163 170 nvkm_event_send(&disp->hpd, rep.mask, conn->index, &rep, sizeof(rep)); 164 - return NVKM_NOTIFY_DROP; 171 + return NVKM_NOTIFY_KEEP; 165 172 } 166 173 167 174 static void ··· 170 177 struct nvkm_output_dp *outp = nvkm_output_dp(base); 171 178 nvkm_notify_put(&outp->hpd); 172 179 nvkm_notify_put(&outp->irq); 173 - flush_work(&outp->lt.work); 174 180 nvkm_output_dp_enable(outp, false); 175 181 } 176 182 ··· 179 187 struct nvkm_output_dp *outp = nvkm_output_dp(base); 180 188 nvkm_notify_put(&outp->base.conn->hpd); 181 189 nvkm_output_dp_enable(outp, true); 190 + nvkm_notify_get(&outp->irq); 182 191 nvkm_notify_get(&outp->hpd); 183 192 } 184 193 ··· 231 238 OUTP_DBG(&outp->base, "bios dp %02x %02x %02x %02x", 232 239 outp->version, hdr, cnt, len); 233 240 234 - /* link training */ 235 - INIT_WORK(&outp->lt.work, nvkm_dp_train); 236 - init_waitqueue_head(&outp->lt.wait); 237 - atomic_set(&outp->lt.done, 0); 238 - 239 241 /* link maintenance */ 240 242 ret = nvkm_notify_init(NULL, &i2c->event, nvkm_output_dp_irq, true, 241 243 &(struct nvkm_i2c_ntfy_req) { ··· 244 256 OUTP_ERR(&outp->base, "error monitoring aux irq: %d", ret); 245 257 return ret; 246 258 } 259 + 260 + mutex_init(&outp->mutex); 261 + atomic_set(&outp->lt.done, 0); 247 262 248 263 /* hotplug detect, replaces gpio-based mechanism with aux events */ 249 264 ret = nvkm_notify_init(NULL, &i2c->event, nvkm_output_dp_hpd, true,
+6 -3
drivers/gpu/drm/nouveau/nvkm/engine/disp/outpdp.h
··· 29 29 bool present; 30 30 u8 dpcd[16]; 31 31 32 + struct mutex mutex; 32 33 struct { 33 - struct work_struct work; 34 - wait_queue_head_t wait; 35 34 atomic_t done; 35 + bool mst; 36 36 } lt; 37 37 }; 38 38 ··· 41 41 int (*lnk_pwr)(struct nvkm_output_dp *, int nr); 42 42 int (*lnk_ctl)(struct nvkm_output_dp *, int nr, int bw, bool ef); 43 43 int (*drv_ctl)(struct nvkm_output_dp *, int ln, int vs, int pe, int pc); 44 + void (*vcpi)(struct nvkm_output_dp *, int head, u8 start_slot, 45 + u8 num_slots, u16 pbn, u16 aligned_pbn); 44 46 }; 45 47 46 - int nvkm_output_dp_train(struct nvkm_output *, u32 rate, bool wait); 48 + int nvkm_output_dp_train(struct nvkm_output *, u32 rate); 47 49 48 50 int nvkm_output_dp_ctor(const struct nvkm_output_dp_func *, struct nvkm_disp *, 49 51 int index, struct dcb_output *, struct nvkm_i2c_aux *, ··· 65 63 struct nvkm_output **); 66 64 int gf119_sor_dp_lnk_ctl(struct nvkm_output_dp *, int, int, bool); 67 65 int gf119_sor_dp_drv_ctl(struct nvkm_output_dp *, int, int, int, int); 66 + void gf119_sor_dp_vcpi(struct nvkm_output_dp *, int, u8, u8, u16, u16); 68 67 69 68 int gm107_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *, 70 69 struct nvkm_output **);
+45 -2
drivers/gpu/drm/nouveau/nvkm/engine/disp/rootnv50.c
··· 66 66 return 0; 67 67 } 68 68 69 - int 69 + static int 70 70 nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size) 71 71 { 72 72 union { ··· 173 173 return 0; 174 174 } else 175 175 if (args->v0.state != 0) { 176 - nvkm_output_dp_train(&outpdp->base, 0, true); 176 + nvkm_output_dp_train(&outpdp->base, 0); 177 177 return 0; 178 178 } 179 + } else 180 + return ret; 181 + } 182 + break; 183 + case NV50_DISP_MTHD_V1_SOR_DP_MST_LINK: { 184 + struct nvkm_output_dp *outpdp = nvkm_output_dp(outp); 185 + union { 186 + struct nv50_disp_sor_dp_mst_link_v0 v0; 187 + } *args = data; 188 + int ret = -ENOSYS; 189 + nvif_ioctl(object, "disp sor dp mst link size %d\n", size); 190 + if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { 191 + nvif_ioctl(object, "disp sor dp mst link vers %d state %d\n", 192 + args->v0.version, args->v0.state); 193 + if (outpdp->lt.mst != !!args->v0.state) { 194 + outpdp->lt.mst = !!args->v0.state; 195 + atomic_set(&outpdp->lt.done, 0); 196 + nvkm_output_dp_train(&outpdp->base, 0); 197 + } 198 + return 0; 199 + } else 200 + return ret; 201 + } 202 + break; 203 + case NV50_DISP_MTHD_V1_SOR_DP_MST_VCPI: { 204 + struct nvkm_output_dp *outpdp = nvkm_output_dp(outp); 205 + union { 206 + struct nv50_disp_sor_dp_mst_vcpi_v0 v0; 207 + } *args = data; 208 + int ret = -ENOSYS; 209 + nvif_ioctl(object, "disp sor dp mst vcpi size %d\n", size); 210 + if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) { 211 + nvif_ioctl(object, "disp sor dp mst vcpi vers %d " 212 + "slot %02x/%02x pbn %04x/%04x\n", 213 + args->v0.version, args->v0.start_slot, 214 + args->v0.num_slots, args->v0.pbn, 215 + args->v0.aligned_pbn); 216 + if (!outpdp->func->vcpi) 217 + return -ENODEV; 218 + outpdp->func->vcpi(outpdp, head, args->v0.start_slot, 219 + args->v0.num_slots, args->v0.pbn, 220 + args->v0.aligned_pbn); 221 + return 0; 179 222 } else 180 223 return ret; 181 224 }
+15 -1
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgf119.c
··· 56 56 57 57 clksor |= bw << 18; 58 58 dpctrl |= ((1 << nr) - 1) << 16; 59 + if (outp->lt.mst) 60 + dpctrl |= 0x40000000; 59 61 if (ef) 60 62 dpctrl |= 0x00004000; 61 63 62 64 nvkm_mask(device, 0x612300 + soff, 0x007c0000, clksor); 63 - nvkm_mask(device, 0x61c10c + loff, 0x001f4000, dpctrl); 65 + nvkm_mask(device, 0x61c10c + loff, 0x401f4000, dpctrl); 64 66 return 0; 65 67 } 66 68 ··· 103 101 return 0; 104 102 } 105 103 104 + void 105 + gf119_sor_dp_vcpi(struct nvkm_output_dp *outp, int head, u8 slot, 106 + u8 slot_nr, u16 pbn, u16 aligned) 107 + { 108 + struct nvkm_device *device = outp->base.disp->engine.subdev.device; 109 + const u32 hoff = head * 0x800; 110 + 111 + nvkm_mask(device, 0x616588 + hoff, 0x00003f3f, (slot_nr << 8) | slot); 112 + nvkm_mask(device, 0x61658c + hoff, 0xffffffff, (aligned << 16) | pbn); 113 + } 114 + 106 115 static const struct nvkm_output_dp_func 107 116 gf119_sor_dp_func = { 108 117 .pattern = gf119_sor_dp_pattern, 109 118 .lnk_pwr = g94_sor_dp_lnk_pwr, 110 119 .lnk_ctl = gf119_sor_dp_lnk_ctl, 111 120 .drv_ctl = gf119_sor_dp_drv_ctl, 121 + .vcpi = gf119_sor_dp_vcpi, 112 122 }; 113 123 114 124 int
+1
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm107.c
··· 43 43 .lnk_pwr = g94_sor_dp_lnk_pwr, 44 44 .lnk_ctl = gf119_sor_dp_lnk_ctl, 45 45 .drv_ctl = gf119_sor_dp_drv_ctl, 46 + .vcpi = gf119_sor_dp_vcpi, 46 47 }; 47 48 48 49 int
+1
drivers/gpu/drm/nouveau/nvkm/engine/disp/sorgm200.c
··· 120 120 .lnk_pwr = gm200_sor_dp_lnk_pwr, 121 121 .lnk_ctl = gf119_sor_dp_lnk_ctl, 122 122 .drv_ctl = gm200_sor_dp_drv_ctl, 123 + .vcpi = gf119_sor_dp_vcpi, 123 124 }; 124 125 125 126 int
+2 -2
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chang84.c
··· 129 129 } 130 130 131 131 132 - int 132 + static int 133 133 g84_fifo_chan_engine_init(struct nvkm_fifo_chan *base, 134 134 struct nvkm_engine *engine) 135 135 { ··· 170 170 return nvkm_object_bind(object, NULL, 0, &chan->engn[engn]); 171 171 } 172 172 173 - int 173 + static int 174 174 g84_fifo_chan_object_ctor(struct nvkm_fifo_chan *base, 175 175 struct nvkm_object *object) 176 176 {
+6 -3
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c
··· 60 60 struct nvkm_gpuobj *inst = chan->base.inst; 61 61 int ret = 0; 62 62 63 + mutex_lock(&subdev->mutex); 63 64 nvkm_wr32(device, 0x002634, chan->base.chid); 64 65 if (nvkm_msec(device, 2000, 65 66 if (nvkm_rd32(device, 0x002634) == chan->base.chid) ··· 68 67 ) < 0) { 69 68 nvkm_error(subdev, "channel %d [%s] kick timeout\n", 70 69 chan->base.chid, chan->base.object.client->name); 71 - ret = -EBUSY; 72 - if (suspend) 73 - return ret; 70 + ret = -ETIMEDOUT; 74 71 } 72 + mutex_unlock(&subdev->mutex); 73 + 74 + if (ret && suspend) 75 + return ret; 75 76 76 77 if (offset) { 77 78 nvkm_kmap(inst);
+5 -3
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c
··· 40 40 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 41 41 struct nvkm_device *device = subdev->device; 42 42 struct nvkm_client *client = chan->base.object.client; 43 + int ret = 0; 43 44 45 + mutex_lock(&subdev->mutex); 44 46 nvkm_wr32(device, 0x002634, chan->base.chid); 45 47 if (nvkm_msec(device, 2000, 46 48 if (!(nvkm_rd32(device, 0x002634) & 0x00100000)) ··· 50 48 ) < 0) { 51 49 nvkm_error(subdev, "channel %d [%s] kick timeout\n", 52 50 chan->base.chid, client->name); 53 - return -EBUSY; 51 + ret = -ETIMEDOUT; 54 52 } 55 - 56 - return 0; 53 + mutex_unlock(&subdev->mutex); 54 + return ret; 57 55 } 58 56 59 57 static u32
+1 -1
drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgf117.c
··· 218 218 } 219 219 } 220 220 221 - void 221 + static void 222 222 gf117_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info) 223 223 { 224 224 struct nvkm_device *device = gr->base.engine.subdev.device;
+1 -1
drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxgm107.c
··· 933 933 } 934 934 } 935 935 936 - void 936 + static void 937 937 gm107_grctx_generate_tpcid(struct gf100_gr *gr) 938 938 { 939 939 struct nvkm_device *device = gr->base.engine.subdev.device;
+1
drivers/gpu/drm/nouveau/nvkm/engine/gr/ctxnv50.c
··· 106 106 #define CP_SEEK_2 0x00c800ff 107 107 108 108 #include "ctxnv40.h" 109 + #include "nv50.h" 109 110 110 111 #include <subdev/fb.h> 111 112
+2 -2
drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf100.fuc3.h
··· 1 - uint32_t gf100_grgpc_data[] = { 1 + static uint32_t gf100_grgpc_data[] = { 2 2 /* 0x0000: gpc_mmio_list_head */ 3 3 0x00000064, 4 4 /* 0x0004: gpc_mmio_list_tail */ ··· 36 36 0x00000000, 37 37 }; 38 38 39 - uint32_t gf100_grgpc_code[] = { 39 + static uint32_t gf100_grgpc_code[] = { 40 40 0x03a10ef5, 41 41 /* 0x0004: queue_put */ 42 42 0x9800d898,
+2 -2
drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgf117.fuc3.h
··· 1 - uint32_t gf117_grgpc_data[] = { 1 + static uint32_t gf117_grgpc_data[] = { 2 2 /* 0x0000: gpc_mmio_list_head */ 3 3 0x0000006c, 4 4 /* 0x0004: gpc_mmio_list_tail */ ··· 40 40 0x00000000, 41 41 }; 42 42 43 - uint32_t gf117_grgpc_code[] = { 43 + static uint32_t gf117_grgpc_code[] = { 44 44 0x03a10ef5, 45 45 /* 0x0004: queue_put */ 46 46 0x9800d898,
+2 -2
drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk104.fuc3.h
··· 1 - uint32_t gk104_grgpc_data[] = { 1 + static uint32_t gk104_grgpc_data[] = { 2 2 /* 0x0000: gpc_mmio_list_head */ 3 3 0x0000006c, 4 4 /* 0x0004: gpc_mmio_list_tail */ ··· 40 40 0x00000000, 41 41 }; 42 42 43 - uint32_t gk104_grgpc_code[] = { 43 + static uint32_t gk104_grgpc_code[] = { 44 44 0x03a10ef5, 45 45 /* 0x0004: queue_put */ 46 46 0x9800d898,
+2 -2
drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk110.fuc3.h
··· 1 - uint32_t gk110_grgpc_data[] = { 1 + static uint32_t gk110_grgpc_data[] = { 2 2 /* 0x0000: gpc_mmio_list_head */ 3 3 0x0000006c, 4 4 /* 0x0004: gpc_mmio_list_tail */ ··· 40 40 0x00000000, 41 41 }; 42 42 43 - uint32_t gk110_grgpc_code[] = { 43 + static uint32_t gk110_grgpc_code[] = { 44 44 0x03a10ef5, 45 45 /* 0x0004: queue_put */ 46 46 0x9800d898,
+2 -2
drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgk208.fuc5.h
··· 1 - uint32_t gk208_grgpc_data[] = { 1 + static uint32_t gk208_grgpc_data[] = { 2 2 /* 0x0000: gpc_mmio_list_head */ 3 3 0x0000006c, 4 4 /* 0x0004: gpc_mmio_list_tail */ ··· 40 40 0x00000000, 41 41 }; 42 42 43 - uint32_t gk208_grgpc_code[] = { 43 + static uint32_t gk208_grgpc_code[] = { 44 44 0x03140ef5, 45 45 /* 0x0004: queue_put */ 46 46 0x9800d898,
+2 -2
drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/gpcgm107.fuc5.h
··· 1 - uint32_t gm107_grgpc_data[] = { 1 + static uint32_t gm107_grgpc_data[] = { 2 2 /* 0x0000: gpc_mmio_list_head */ 3 3 0x0000006c, 4 4 /* 0x0004: gpc_mmio_list_tail */ ··· 40 40 0x00000000, 41 41 }; 42 42 43 - uint32_t gm107_grgpc_code[] = { 43 + static uint32_t gm107_grgpc_code[] = { 44 44 0x03410ef5, 45 45 /* 0x0004: queue_put */ 46 46 0x9800d898,
+2 -2
drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf100.fuc3.h
··· 1 - uint32_t gf100_grhub_data[] = { 1 + static uint32_t gf100_grhub_data[] = { 2 2 /* 0x0000: hub_mmio_list_head */ 3 3 0x00000300, 4 4 /* 0x0004: hub_mmio_list_tail */ ··· 205 205 0x0417e91c, 206 206 }; 207 207 208 - uint32_t gf100_grhub_code[] = { 208 + static uint32_t gf100_grhub_code[] = { 209 209 0x039b0ef5, 210 210 /* 0x0004: queue_put */ 211 211 0x9800d898,
+2 -2
drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgf117.fuc3.h
··· 1 - uint32_t gf117_grhub_data[] = { 1 + static uint32_t gf117_grhub_data[] = { 2 2 /* 0x0000: hub_mmio_list_head */ 3 3 0x00000300, 4 4 /* 0x0004: hub_mmio_list_tail */ ··· 205 205 0x0417e91c, 206 206 }; 207 207 208 - uint32_t gf117_grhub_code[] = { 208 + static uint32_t gf117_grhub_code[] = { 209 209 0x039b0ef5, 210 210 /* 0x0004: queue_put */ 211 211 0x9800d898,
+2 -2
drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk104.fuc3.h
··· 1 - uint32_t gk104_grhub_data[] = { 1 + static uint32_t gk104_grhub_data[] = { 2 2 /* 0x0000: hub_mmio_list_head */ 3 3 0x00000300, 4 4 /* 0x0004: hub_mmio_list_tail */ ··· 205 205 0x0417e91c, 206 206 }; 207 207 208 - uint32_t gk104_grhub_code[] = { 208 + static uint32_t gk104_grhub_code[] = { 209 209 0x039b0ef5, 210 210 /* 0x0004: queue_put */ 211 211 0x9800d898,
+2 -2
drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk110.fuc3.h
··· 1 - uint32_t gk110_grhub_data[] = { 1 + static uint32_t gk110_grhub_data[] = { 2 2 /* 0x0000: hub_mmio_list_head */ 3 3 0x00000300, 4 4 /* 0x0004: hub_mmio_list_tail */ ··· 205 205 0x0417e91c, 206 206 }; 207 207 208 - uint32_t gk110_grhub_code[] = { 208 + static uint32_t gk110_grhub_code[] = { 209 209 0x039b0ef5, 210 210 /* 0x0004: queue_put */ 211 211 0x9800d898,
+2 -2
drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgk208.fuc5.h
··· 1 - uint32_t gk208_grhub_data[] = { 1 + static uint32_t gk208_grhub_data[] = { 2 2 /* 0x0000: hub_mmio_list_head */ 3 3 0x00000300, 4 4 /* 0x0004: hub_mmio_list_tail */ ··· 205 205 0x0417e91c, 206 206 }; 207 207 208 - uint32_t gk208_grhub_code[] = { 208 + static uint32_t gk208_grhub_code[] = { 209 209 0x030e0ef5, 210 210 /* 0x0004: queue_put */ 211 211 0x9800d898,
+2 -2
drivers/gpu/drm/nouveau/nvkm/engine/gr/fuc/hubgm107.fuc5.h
··· 1 - uint32_t gm107_grhub_data[] = { 1 + static uint32_t gm107_grhub_data[] = { 2 2 /* 0x0000: hub_mmio_list_head */ 3 3 0x00000300, 4 4 /* 0x0004: hub_mmio_list_tail */ ··· 205 205 0x0417e91c, 206 206 }; 207 207 208 - uint32_t gm107_grhub_code[] = { 208 + static uint32_t gm107_grhub_code[] = { 209 209 0x030e0ef5, 210 210 /* 0x0004: queue_put */ 211 211 0x9800d898,
+48 -6
drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c
··· 1384 1384 nvkm_fifo_chan_put(device->fifo, flags, &chan); 1385 1385 } 1386 1386 1387 - void 1387 + static void 1388 1388 gf100_gr_init_fw(struct gf100_gr *gr, u32 fuc_base, 1389 1389 struct gf100_gr_fuc *code, struct gf100_gr_fuc *data) 1390 1390 { ··· 1701 1701 return 0; 1702 1702 } 1703 1703 1704 - int 1704 + static int 1705 1705 gf100_gr_init_(struct nvkm_gr *base) 1706 1706 { 1707 1707 struct gf100_gr *gr = gf100_gr(base); ··· 1756 1756 }; 1757 1757 1758 1758 int 1759 + gf100_gr_ctor_fw_legacy(struct gf100_gr *gr, const char *fwname, 1760 + struct gf100_gr_fuc *fuc, int ret) 1761 + { 1762 + struct nvkm_subdev *subdev = &gr->base.engine.subdev; 1763 + struct nvkm_device *device = subdev->device; 1764 + const struct firmware *fw; 1765 + char f[32]; 1766 + 1767 + /* see if this firmware has a legacy path */ 1768 + if (!strcmp(fwname, "fecs_inst")) 1769 + fwname = "fuc409c"; 1770 + else if (!strcmp(fwname, "fecs_data")) 1771 + fwname = "fuc409d"; 1772 + else if (!strcmp(fwname, "gpccs_inst")) 1773 + fwname = "fuc41ac"; 1774 + else if (!strcmp(fwname, "gpccs_data")) 1775 + fwname = "fuc41ad"; 1776 + else { 1777 + /* nope, let's just return the error we got */ 1778 + nvkm_error(subdev, "failed to load %s\n", fwname); 1779 + return ret; 1780 + } 1781 + 1782 + /* yes, try to load from the legacy path */ 1783 + nvkm_debug(subdev, "%s: falling back to legacy path\n", fwname); 1784 + 1785 + snprintf(f, sizeof(f), "nouveau/nv%02x_%s", device->chipset, fwname); 1786 + ret = request_firmware(&fw, f, device->dev); 1787 + if (ret) { 1788 + snprintf(f, sizeof(f), "nouveau/%s", fwname); 1789 + ret = request_firmware(&fw, f, device->dev); 1790 + if (ret) { 1791 + nvkm_error(subdev, "failed to load %s\n", fwname); 1792 + return ret; 1793 + } 1794 + } 1795 + 1796 + fuc->size = fw->size; 1797 + fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL); 1798 + release_firmware(fw); 1799 + return (fuc->data != NULL) ? 0 : -ENOMEM; 1800 + } 1801 + 1802 + int 1759 1803 gf100_gr_ctor_fw(struct gf100_gr *gr, const char *fwname, 1760 1804 struct gf100_gr_fuc *fuc) 1761 1805 { ··· 1809 1765 int ret; 1810 1766 1811 1767 ret = nvkm_firmware_get(device, fwname, &fw); 1812 - if (ret) { 1813 - nvkm_error(subdev, "failed to load %s\n", fwname); 1814 - return ret; 1815 - } 1768 + if (ret) 1769 + return gf100_gr_ctor_fw_legacy(gr, fwname, fuc, ret); 1816 1770 1817 1771 fuc->size = fw->size; 1818 1772 fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);
+2 -2
drivers/gpu/drm/nouveau/nvkm/engine/gr/gf117.c
··· 102 102 103 103 #include "fuc/hubgf117.fuc3.h" 104 104 105 - struct gf100_gr_ucode 105 + static struct gf100_gr_ucode 106 106 gf117_gr_fecs_ucode = { 107 107 .code.data = gf117_grhub_code, 108 108 .code.size = sizeof(gf117_grhub_code), ··· 112 112 113 113 #include "fuc/gpcgf117.fuc3.h" 114 114 115 - struct gf100_gr_ucode 115 + static struct gf100_gr_ucode 116 116 gf117_gr_gpccs_ucode = { 117 117 .code.data = gf117_grgpc_code, 118 118 .code.size = sizeof(gf117_grgpc_code),
+1 -1
drivers/gpu/drm/nouveau/nvkm/engine/gr/gm107.c
··· 308 308 } 309 309 } 310 310 311 - int 311 + static int 312 312 gm107_gr_init(struct gf100_gr *gr) 313 313 { 314 314 struct nvkm_device *device = gr->base.engine.subdev.device;
+2 -2
drivers/gpu/drm/nouveau/nvkm/engine/pm/base.c
··· 71 71 return NULL; 72 72 } 73 73 74 - struct nvkm_perfsig * 74 + static struct nvkm_perfsig * 75 75 nvkm_perfsig_find(struct nvkm_pm *pm, u8 di, u8 si, struct nvkm_perfdom **pdom) 76 76 { 77 77 struct nvkm_perfdom *dom = *pdom; ··· 699 699 return 1; 700 700 } 701 701 702 - int 702 + static int 703 703 nvkm_perfsrc_new(struct nvkm_pm *pm, struct nvkm_perfsig *sig, 704 704 const struct nvkm_specsrc *spec) 705 705 {
+1 -1
drivers/gpu/drm/nouveau/nvkm/engine/pm/gf100.c
··· 102 102 {} 103 103 }; 104 104 105 - const struct nvkm_specdom 105 + static const struct nvkm_specdom 106 106 gf100_pm_part[] = { 107 107 { 0xe0, (const struct nvkm_specsig[]) { 108 108 { 0x0f, "part00_pbfb_00", gf100_pbfb_sources },
+2 -2
drivers/gpu/drm/nouveau/nvkm/engine/sec/fuc/g98.fuc0s.h
··· 1 - uint32_t g98_sec_data[] = { 1 + static uint32_t g98_sec_data[] = { 2 2 /* 0x0000: ctx_dma */ 3 3 /* 0x0000: ctx_dma_query */ 4 4 0x00000000, ··· 150 150 0x00000000, 151 151 }; 152 152 153 - uint32_t g98_sec_code[] = { 153 + static uint32_t g98_sec_code[] = { 154 154 0x17f004bd, 155 155 0x0010fe35, 156 156 0xf10004fe,
+2 -2
drivers/gpu/drm/nouveau/nvkm/subdev/bios/fan.c
··· 25 25 #include <subdev/bios/bit.h> 26 26 #include <subdev/bios/fan.h> 27 27 28 - u16 28 + static u16 29 29 nvbios_fan_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) 30 30 { 31 31 struct bit_entry bit_P; ··· 52 52 return 0x0000; 53 53 } 54 54 55 - u16 55 + static u16 56 56 nvbios_fan_entry(struct nvkm_bios *bios, int idx, u8 *ver, u8 *hdr, 57 57 u8 *cnt, u8 *len) 58 58 {
+1
drivers/gpu/drm/nouveau/nvkm/subdev/bios/priv.h
··· 12 12 bool rw; 13 13 bool ignore_checksum; 14 14 bool no_pcir; 15 + bool require_checksum; 15 16 }; 16 17 17 18 int nvbios_extend(struct nvkm_bios *, u32 length);
+5 -2
drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadow.c
··· 86 86 nvbios_checksum(&bios->data[image.base], image.size)) { 87 87 nvkm_debug(subdev, "%08x: checksum failed\n", 88 88 image.base); 89 - if (mthd->func->rw) 89 + if (!mthd->func->require_checksum) { 90 + if (mthd->func->rw) 91 + score += 1; 90 92 score += 1; 91 - score += 1; 93 + } else 94 + return 0; 92 95 } else { 93 96 score += 3; 94 97 }
+1
drivers/gpu/drm/nouveau/nvkm/subdev/bios/shadowacpi.c
··· 99 99 .init = acpi_init, 100 100 .read = acpi_read_fast, 101 101 .rw = false, 102 + .require_checksum = true, 102 103 }; 103 104 104 105 const struct nvbios_source
+1 -1
drivers/gpu/drm/nouveau/nvkm/subdev/clk/gt215.c
··· 180 180 return 0; 181 181 } 182 182 183 - int 183 + static int 184 184 gt215_clk_info(struct nvkm_clk *base, int idx, u32 khz, 185 185 struct gt215_clk_info *info) 186 186 {
+1
drivers/gpu/drm/nouveau/nvkm/subdev/fb/Kbuild
··· 24 24 nvkm-y += nvkm/subdev/fb/gk20a.o 25 25 nvkm-y += nvkm/subdev/fb/gm107.o 26 26 nvkm-y += nvkm/subdev/fb/gm200.o 27 + nvkm-y += nvkm/subdev/fb/gm20b.o 27 28 nvkm-y += nvkm/subdev/fb/gp100.o 28 29 nvkm-y += nvkm/subdev/fb/gp104.o 29 30
+4
drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.h
··· 16 16 void gf100_fb_intr(struct nvkm_fb *); 17 17 18 18 void gp100_fb_init(struct nvkm_fb *); 19 + 20 + void gm200_fb_init_page(struct nvkm_fb *fb); 21 + void gm200_fb_init(struct nvkm_fb *base); 22 + 19 23 #endif
+7 -13
drivers/gpu/drm/nouveau/nvkm/subdev/fb/gk20a.c
··· 1 1 /* 2 - * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. 2 + * Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved. 3 3 * 4 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 5 * copy of this software and associated documentation files (the "Software"), ··· 20 20 * DEALINGS IN THE SOFTWARE. 21 21 */ 22 22 #include "priv.h" 23 + #include "gf100.h" 23 24 24 - #include <core/memory.h> 25 - 26 - static void 27 - gk20a_fb_init(struct nvkm_fb *fb) 28 - { 29 - struct nvkm_device *device = fb->subdev.device; 30 - nvkm_wr32(device, 0x100cc8, nvkm_memory_addr(fb->mmu_wr) >> 8); 31 - nvkm_wr32(device, 0x100ccc, nvkm_memory_addr(fb->mmu_rd) >> 8); 32 - } 33 - 25 + /* GK20A's FB is similar to GF100's, but without the ability to allocate VRAM */ 34 26 static const struct nvkm_fb_func 35 27 gk20a_fb = { 28 + .dtor = gf100_fb_dtor, 36 29 .oneinit = gf100_fb_oneinit, 37 - .init = gk20a_fb_init, 30 + .init = gf100_fb_init, 38 31 .init_page = gf100_fb_init_page, 32 + .intr = gf100_fb_intr, 39 33 .memtype_valid = gf100_fb_memtype_valid, 40 34 }; 41 35 42 36 int 43 37 gk20a_fb_new(struct nvkm_device *device, int index, struct nvkm_fb **pfb) 44 38 { 45 - return nvkm_fb_new_(&gk20a_fb, device, index, pfb); 39 + return gf100_fb_new_(&gk20a_fb, device, index, pfb); 46 40 }
+1 -1
drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm200.c
··· 44 44 } 45 45 } 46 46 47 - static void 47 + void 48 48 gm200_fb_init(struct nvkm_fb *base) 49 49 { 50 50 struct gf100_fb *fb = gf100_fb(base);
+40
drivers/gpu/drm/nouveau/nvkm/subdev/fb/gm20b.c
··· 1 + /* 2 + * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. 3 + * 4 + * Permission is hereby granted, free of charge, to any person obtaining a 5 + * copy of this software and associated documentation files (the "Software"), 6 + * to deal in the Software without restriction, including without limitation 7 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 + * and/or sell copies of the Software, and to permit persons to whom the 9 + * Software is furnished to do so, subject to the following conditions: 10 + * 11 + * The above copyright notice and this permission notice shall be included in 12 + * all copies or substantial portions of the Software. 13 + * 14 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 + * DEALINGS IN THE SOFTWARE. 21 + */ 22 + #include "priv.h" 23 + #include "gf100.h" 24 + 25 + /* GM20B's FB is similar to GM200, but without the ability to allocate VRAM */ 26 + static const struct nvkm_fb_func 27 + gm20b_fb = { 28 + .dtor = gf100_fb_dtor, 29 + .oneinit = gf100_fb_oneinit, 30 + .init = gm200_fb_init, 31 + .init_page = gm200_fb_init_page, 32 + .intr = gf100_fb_intr, 33 + .memtype_valid = gf100_fb_memtype_valid, 34 + }; 35 + 36 + int 37 + gm20b_fb_new(struct nvkm_device *device, int index, struct nvkm_fb **pfb) 38 + { 39 + return gf100_fb_new_(&gm20b_fb, device, index, pfb); 40 + }
-2
drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgf100.c
··· 420 420 ram_exec(&ram->fuc, false); 421 421 } 422 422 423 - extern const u8 gf100_pte_storage_type_map[256]; 424 - 425 423 void 426 424 gf100_ram_put(struct nvkm_ram *ram, struct nvkm_mem **pmem) 427 425 {
+4 -4
drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramgt215.c
··· 95 95 struct gt215_ltrain ltrain; 96 96 }; 97 97 98 - void 98 + static void 99 99 gt215_link_train_calc(u32 *vals, struct gt215_ltrain *train) 100 100 { 101 101 int i, lo, hi; ··· 149 149 /* 150 150 * Link training for (at least) DDR3 151 151 */ 152 - int 152 + static int 153 153 gt215_link_train(struct gt215_ram *ram) 154 154 { 155 155 struct gt215_ltrain *train = &ram->ltrain; ··· 267 267 return ret; 268 268 } 269 269 270 - int 270 + static int 271 271 gt215_link_train_init(struct gt215_ram *ram) 272 272 { 273 273 static const u32 pattern[16] = { ··· 333 333 return 0; 334 334 } 335 335 336 - void 336 + static void 337 337 gt215_link_train_fini(struct gt215_ram *ram) 338 338 { 339 339 if (ram->ltrain.mem)
+1
drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr2.c
··· 23 23 * Ben Skeggs 24 24 */ 25 25 #include "priv.h" 26 + #include "ram.h" 26 27 27 28 struct ramxlat { 28 29 int id;
+1
drivers/gpu/drm/nouveau/nvkm/subdev/fb/sddr3.c
··· 23 23 * Roy Spliet <rspliet@eclipso.eu> 24 24 */ 25 25 #include "priv.h" 26 + #include "ram.h" 26 27 27 28 struct ramxlat { 28 29 int id;
+1 -1
drivers/gpu/drm/nouveau/nvkm/subdev/gpio/gk104.c
··· 37 37 nvkm_wr32(device, 0x00dc80, intr1); 38 38 } 39 39 40 - void 40 + static void 41 41 gk104_gpio_intr_mask(struct nvkm_gpio *gpio, u32 type, u32 mask, u32 data) 42 42 { 43 43 struct nvkm_device *device = gpio->subdev.device;
+1 -1
drivers/gpu/drm/nouveau/nvkm/subdev/i2c/aux.c
··· 74 74 return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; 75 75 } 76 76 77 - const struct i2c_algorithm 77 + static const struct i2c_algorithm 78 78 nvkm_i2c_aux_i2c_algo = { 79 79 .master_xfer = nvkm_i2c_aux_i2c_xfer, 80 80 .functionality = nvkm_i2c_aux_i2c_func
+5 -5
drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxg94.c
··· 79 79 struct g94_i2c_aux *aux = g94_i2c_aux(obj); 80 80 struct nvkm_device *device = aux->base.pad->i2c->subdev.device; 81 81 const u32 base = aux->ch * 0x50; 82 - u32 ctrl, stat, timeout, retries; 82 + u32 ctrl, stat, timeout, retries = 0; 83 83 u32 xbuf[4] = {}; 84 84 int ret, i; 85 85 ··· 111 111 nvkm_wr32(device, 0x00e4e0 + base, addr); 112 112 113 113 /* (maybe) retry transaction a number of times on failure... */ 114 - for (retries = 0; !ret && retries < 32; retries++) { 114 + do { 115 115 /* reset, and delay a while if this is a retry */ 116 116 nvkm_wr32(device, 0x00e4e4 + base, 0x80000000 | ctrl); 117 117 nvkm_wr32(device, 0x00e4e4 + base, 0x00000000 | ctrl); ··· 131 131 goto out; 132 132 } 133 133 } while (ctrl & 0x00010000); 134 - ret = 1; 134 + ret = 0; 135 135 136 136 /* read status, and check if transaction completed ok */ 137 137 stat = nvkm_mask(device, 0x00e4e8 + base, 0, 0); 138 138 if ((stat & 0x000f0000) == 0x00080000 || 139 139 (stat & 0x000f0000) == 0x00020000) 140 - ret = retry ? 0 : 1; 140 + ret = 1; 141 141 if ((stat & 0x00000100)) 142 142 ret = -ETIMEDOUT; 143 143 if ((stat & 0x00000e00)) 144 144 ret = -EIO; 145 145 146 146 AUX_TRACE(&aux->base, "%02d %08x %08x", retries, ctrl, stat); 147 - } 147 + } while (ret && retry && retries++ < 32); 148 148 149 149 if (type & 1) { 150 150 for (i = 0; i < 16; i += 4) {
+5 -5
drivers/gpu/drm/nouveau/nvkm/subdev/i2c/auxgm200.c
··· 79 79 struct gm200_i2c_aux *aux = gm200_i2c_aux(obj); 80 80 struct nvkm_device *device = aux->base.pad->i2c->subdev.device; 81 81 const u32 base = aux->ch * 0x50; 82 - u32 ctrl, stat, timeout, retries; 82 + u32 ctrl, stat, timeout, retries = 0; 83 83 u32 xbuf[4] = {}; 84 84 int ret, i; 85 85 ··· 111 111 nvkm_wr32(device, 0x00d950 + base, addr); 112 112 113 113 /* (maybe) retry transaction a number of times on failure... */ 114 - for (retries = 0; !ret && retries < 32; retries++) { 114 + do { 115 115 /* reset, and delay a while if this is a retry */ 116 116 nvkm_wr32(device, 0x00d954 + base, 0x80000000 | ctrl); 117 117 nvkm_wr32(device, 0x00d954 + base, 0x00000000 | ctrl); ··· 131 131 goto out; 132 132 } 133 133 } while (ctrl & 0x00010000); 134 - ret = 1; 134 + ret = 0; 135 135 136 136 /* read status, and check if transaction completed ok */ 137 137 stat = nvkm_mask(device, 0x00d958 + base, 0, 0); 138 138 if ((stat & 0x000f0000) == 0x00080000 || 139 139 (stat & 0x000f0000) == 0x00020000) 140 - ret = retry ? 0 : 1; 140 + ret = 1; 141 141 if ((stat & 0x00000100)) 142 142 ret = -ETIMEDOUT; 143 143 if ((stat & 0x00000e00)) 144 144 ret = -EIO; 145 145 146 146 AUX_TRACE(&aux->base, "%02d %08x %08x", retries, ctrl, stat); 147 - } 147 + } while (ret && retry && retries++ < 32); 148 148 149 149 if (type & 1) { 150 150 for (i = 0; i < 16; i += 4) {
+2 -1
drivers/gpu/drm/nouveau/nvkm/subdev/iccsense/base.c
··· 288 288 return 0; 289 289 } 290 290 291 - struct nvkm_subdev_func iccsense_func = { 291 + static const struct nvkm_subdev_func 292 + iccsense_func = { 292 293 .oneinit = nvkm_iccsense_oneinit, 293 294 .init = nvkm_iccsense_init, 294 295 .dtor = nvkm_iccsense_dtor,
+2 -2
drivers/gpu/drm/nouveau/nvkm/subdev/instmem/base.c
··· 104 104 return iobj; 105 105 } 106 106 107 - const struct nvkm_memory_func 107 + static const struct nvkm_memory_func 108 108 nvkm_instobj_func = { 109 109 .dtor = nvkm_instobj_dtor, 110 110 .target = nvkm_instobj_target, ··· 156 156 return nvkm_wo32(iobj->parent, offset, data); 157 157 } 158 158 159 - const struct nvkm_memory_func 159 + static const struct nvkm_memory_func 160 160 nvkm_instobj_func_slow = { 161 161 .dtor = nvkm_instobj_dtor, 162 162 .target = nvkm_instobj_target,
+1 -1
drivers/gpu/drm/nouveau/nvkm/subdev/mc/g84.c
··· 34 34 {} 35 35 }; 36 36 37 - const struct nvkm_mc_map 37 + static const struct nvkm_mc_map 38 38 g84_mc_intr[] = { 39 39 { 0x04000000, NVKM_ENGINE_DISP }, 40 40 { 0x00020000, NVKM_ENGINE_VP },
+4
drivers/gpu/drm/nouveau/nvkm/subdev/mxm/base.c
··· 250 250 } 251 251 252 252 nvkm_info(&mxm->subdev, "BIOS version %d.%d\n", ver >> 4, ver & 0x0f); 253 + nvkm_debug(&mxm->subdev, "module flags: %02x\n", 254 + nvbios_rd08(bios, data + 0x01)); 255 + nvkm_debug(&mxm->subdev, "config flags: %02x\n", 256 + nvbios_rd08(bios, data + 0x02)); 253 257 254 258 if (mxm_shadow(mxm, ver)) { 255 259 nvkm_warn(&mxm->subdev, "failed to locate valid SIS\n");
+2 -2
drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf100.fuc3.h
··· 1 - uint32_t gf100_pmu_data[] = { 1 + static uint32_t gf100_pmu_data[] = { 2 2 /* 0x0000: proc_kern */ 3 3 0x52544e49, 4 4 0x00000000, ··· 916 916 0x00000000, 917 917 }; 918 918 919 - uint32_t gf100_pmu_code[] = { 919 + static uint32_t gf100_pmu_code[] = { 920 920 0x03920ef5, 921 921 /* 0x0004: rd32 */ 922 922 0x07a007f1,
+2 -2
drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gf119.fuc4.h
··· 1 - uint32_t gf119_pmu_data[] = { 1 + static uint32_t gf119_pmu_data[] = { 2 2 /* 0x0000: proc_kern */ 3 3 0x52544e49, 4 4 0x00000000, ··· 915 915 0x00000000, 916 916 }; 917 917 918 - uint32_t gf119_pmu_code[] = { 918 + static uint32_t gf119_pmu_code[] = { 919 919 0x03410ef5, 920 920 /* 0x0004: rd32 */ 921 921 0x07a007f1,
+2 -2
drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gk208.fuc5.h
··· 1 - uint32_t gk208_pmu_data[] = { 1 + static uint32_t gk208_pmu_data[] = { 2 2 /* 0x0000: proc_kern */ 3 3 0x52544e49, 4 4 0x00000000, ··· 915 915 0x00000000, 916 916 }; 917 917 918 - uint32_t gk208_pmu_code[] = { 918 + static uint32_t gk208_pmu_code[] = { 919 919 0x02f90ef5, 920 920 /* 0x0004: rd32 */ 921 921 0xf607a040,
+2 -2
drivers/gpu/drm/nouveau/nvkm/subdev/pmu/fuc/gt215.fuc3.h
··· 1 - uint32_t gt215_pmu_data[] = { 1 + static uint32_t gt215_pmu_data[] = { 2 2 /* 0x0000: proc_kern */ 3 3 0x52544e49, 4 4 0x00000000, ··· 916 916 0x00000000, 917 917 }; 918 918 919 - uint32_t gt215_pmu_code[] = { 919 + static uint32_t gt215_pmu_code[] = { 920 920 0x03920ef5, 921 921 /* 0x0004: rd32 */ 922 922 0x07a007f1,
-9
drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gt215.c
··· 24 24 #include "priv.h" 25 25 #include "fuc/gt215.fuc3.h" 26 26 27 - static void 28 - gt215_pmu_reset(struct nvkm_pmu *pmu) 29 - { 30 - struct nvkm_device *device = pmu->subdev.device; 31 - nvkm_mask(device, 0x022210, 0x00000001, 0x00000000); 32 - nvkm_mask(device, 0x022210, 0x00000001, 0x00000001); 33 - } 34 - 35 27 static const struct nvkm_pmu_func 36 28 gt215_pmu = { 37 - .reset = gt215_pmu_reset, 38 29 .code.data = gt215_pmu_code, 39 30 .code.size = sizeof(gt215_pmu_code), 40 31 .data.data = gt215_pmu_data,
-2
drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h
··· 8 8 int index, struct nvkm_pmu **); 9 9 10 10 struct nvkm_pmu_func { 11 - void (*reset)(struct nvkm_pmu *); 12 - 13 11 struct { 14 12 u32 *data; 15 13 u32 size;
+1 -1
drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.c
··· 1364 1364 return 0; 1365 1365 } 1366 1366 1367 - int 1367 + static int 1368 1368 gm200_secboot_fini(struct nvkm_secboot *sb, bool suspend) 1369 1369 { 1370 1370 struct gm200_secboot *gsb = gm200_secboot(sb);
+2 -2
drivers/gpu/drm/nouveau/nvkm/subdev/volt/gk104.c
··· 35 35 struct nvbios_volt bios; 36 36 }; 37 37 38 - int 38 + static int 39 39 gk104_volt_get(struct nvkm_volt *base) 40 40 { 41 41 struct nvbios_volt *bios = &gk104_volt(base)->bios; ··· 48 48 return bios->base + bios->pwm_range * duty / div; 49 49 } 50 50 51 - int 51 + static int 52 52 gk104_volt_set(struct nvkm_volt *base, u32 uv) 53 53 { 54 54 struct nvbios_volt *bios = &gk104_volt(base)->bios;
+2 -2
drivers/gpu/drm/nouveau/nvkm/subdev/volt/gm20b.c
··· 25 25 26 26 #include <core/tegra.h> 27 27 28 - const struct cvb_coef gm20b_cvb_coef[] = { 28 + static const struct cvb_coef gm20b_cvb_coef[] = { 29 29 /* KHz, c0, c1, c2 */ 30 30 /* 76800 */ { 1786666, -85625, 1632 }, 31 31 /* 153600 */ { 1846729, -87525, 1632 }, ··· 58 58 /* 998400 */ { 1316991, 8144, -940, 808, -21583, 226 }, 59 59 }; 60 60 61 - const u32 speedo_to_vmin[] = { 61 + static const u32 speedo_to_vmin[] = { 62 62 /* 0, 1, 2, 3, 4, */ 63 63 950000, 840000, 818750, 840000, 810000, 64 64 };
+1
drivers/gpu/drm/nouveau/nvkm/subdev/volt/gpio.c
··· 25 25 #include <subdev/bios.h> 26 26 #include <subdev/bios/gpio.h> 27 27 #include <subdev/gpio.h> 28 + #include "priv.h" 28 29 29 30 static const u8 tags[] = { 30 31 DCB_GPIO_VID0, DCB_GPIO_VID1, DCB_GPIO_VID2, DCB_GPIO_VID3,