diff options
author | Dave Airlie <airlied@redhat.com> | 2017-08-23 05:32:26 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2017-08-23 05:32:26 +1000 |
commit | 7c0059dd832cc686bf0febefdcf8295cdd93007f (patch) | |
tree | 7f1e9e8fc879d1013136b7b88fa609bd4f6da065 | |
parent | 6b9dfb5991a3fda1ced9062f6c86d8798416ea31 (diff) | |
parent | 27a451e83e78e1167f58cddba189fae4b4fa0d5b (diff) |
Merge branch 'linux-4.14' of git://github.com/skeggsb/linux into drm-next
Not a lot that's ready to be included this round for Nouveau. GP108
modesetting support, and misc other fixes.
* 'linux-4.14' of git://github.com/skeggsb/linux:
drm/nouveau/kms/nv50: perform null check on msto[i] rathern than msto
drm/nouveau/pci/msi: disable MSI on big-endian platforms by default
drm/nouveau: silence suspend/resume debugging messages
drm/nouveau/kms/nv04-nv4x: fix exposed format list
drm/nouveau/kms/nv10-nv40: add NV21 support to overlay
drm/nouveau/kms/nv04-nv40: improve overlay error detection, fix pitch setting
drm/nouveau/kms/nv04-nv40: prevent undisplayable framebuffers from creation
drm/nouveau/mpeg: print more debug info when rejecting dma objects
drm/nouveau/fb/gf100-: zero mmu debug buffers
drm/nouveau/bar/gf100: add config option to limit BAR2 to 16MiB
initial support (display-only) for GP108
drm/nouveau/falcon: use a more reasonable msgqueue timeout value
drm/nouveau/disp: Silence DCB warnings.
drm/nouveau/bios: Demote missing fp table message to NV_DEBUG.
drm/nouveau/pmu/gt215-: abstract detection of whether reset is needed
drm/nouveau/pmu/gt215: fix reset
drm/nouveau/mc/gf100: add pmu to reset mask
drm/nouveau/disp/gf119-: avoid creating non-existent heads
drm/nouveau/therm/gm200: Added
drm/nouveau/therm: fix spelling mistake on array thresolds
39 files changed, 287 insertions, 75 deletions
diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c index 8f689f1f6122..6aa6ee16dcbd 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c +++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c @@ -1096,6 +1096,38 @@ static const struct drm_crtc_helper_funcs nv04_crtc_helper_funcs = { .disable = nv_crtc_disable, }; +static const uint32_t modeset_formats[] = { + DRM_FORMAT_XRGB8888, + DRM_FORMAT_RGB565, + DRM_FORMAT_XRGB1555, +}; + +static struct drm_plane * +create_primary_plane(struct drm_device *dev) +{ + struct drm_plane *primary; + int ret; + + primary = kzalloc(sizeof(*primary), GFP_KERNEL); + if (primary == NULL) { + DRM_DEBUG_KMS("Failed to allocate primary plane\n"); + return NULL; + } + + /* possible_crtc's will be filled in later by crtc_init */ + ret = drm_universal_plane_init(dev, primary, 0, + &drm_primary_helper_funcs, + modeset_formats, + ARRAY_SIZE(modeset_formats), NULL, + DRM_PLANE_TYPE_PRIMARY, NULL); + if (ret) { + kfree(primary); + primary = NULL; + } + + return primary; +} + int nv04_crtc_create(struct drm_device *dev, int crtc_num) { @@ -1114,7 +1146,9 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num) nv_crtc->save = nv_crtc_save; nv_crtc->restore = nv_crtc_restore; - drm_crtc_init(dev, &nv_crtc->base, &nv04_crtc_funcs); + drm_crtc_init_with_planes(dev, &nv_crtc->base, + create_primary_plane(dev), NULL, + &nv04_crtc_funcs, NULL); drm_crtc_helper_add(&nv_crtc->base, &nv04_crtc_helper_funcs); drm_mode_crtc_set_gamma_size(&nv_crtc->base, 256); diff --git a/drivers/gpu/drm/nouveau/dispnv04/overlay.c b/drivers/gpu/drm/nouveau/dispnv04/overlay.c index e54944d23268..c8c2333f24ee 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/overlay.c +++ b/drivers/gpu/drm/nouveau/dispnv04/overlay.c @@ -63,6 +63,7 @@ static uint32_t formats[] = { DRM_FORMAT_YUYV, DRM_FORMAT_UYVY, DRM_FORMAT_NV12, + DRM_FORMAT_NV21, }; /* Sine can be approximated with @@ -90,6 +91,26 @@ cos_mul(int degrees, int factor) } static int +verify_scaling(const struct drm_framebuffer *fb, uint8_t shift, + uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h, + uint32_t crtc_w, uint32_t crtc_h) +{ + if (crtc_w < (src_w >> shift) || crtc_h < (src_h >> shift)) { + DRM_DEBUG_KMS("Unsuitable framebuffer scaling: %dx%d -> %dx%d\n", + src_w, src_h, crtc_w, crtc_h); + return -ERANGE; + } + + if (src_x != 0 || src_y != 0) { + DRM_DEBUG_KMS("Unsuitable framebuffer offset: %d,%d\n", + src_x, src_y); + return -ERANGE; + } + + return 0; +} + +static int nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, struct drm_framebuffer *fb, int crtc_x, int crtc_y, unsigned int crtc_w, unsigned int crtc_h, @@ -107,7 +128,9 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, bool flip = nv_plane->flip; int soff = NV_PCRTC0_SIZE * nv_crtc->index; int soff2 = NV_PCRTC0_SIZE * !nv_crtc->index; - int format, ret; + unsigned shift = drm->client.device.info.chipset >= 0x30 ? 1 : 3; + unsigned format = 0; + int ret; /* Source parameters given in 16.16 fixed point, ignore fractional. */ src_x >>= 16; @@ -115,18 +138,9 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, src_w >>= 16; src_h >>= 16; - format = ALIGN(src_w * 4, 0x100); - - if (format > 0xffff) - return -ERANGE; - - if (drm->client.device.info.chipset >= 0x30) { - if (crtc_w < (src_w >> 1) || crtc_h < (src_h >> 1)) - return -ERANGE; - } else { - if (crtc_w < (src_w >> 3) || crtc_h < (src_h >> 3)) - return -ERANGE; - } + ret = verify_scaling(fb, shift, 0, 0, src_w, src_h, crtc_w, crtc_h); + if (ret) + return ret; ret = nouveau_bo_pin(nv_fb->nvbo, TTM_PL_FLAG_VRAM, false); if (ret) @@ -146,21 +160,23 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, nvif_wr32(dev, NV_PVIDEO_POINT_OUT(flip), crtc_y << 16 | crtc_x); nvif_wr32(dev, NV_PVIDEO_SIZE_OUT(flip), crtc_h << 16 | crtc_w); - if (fb->format->format != DRM_FORMAT_UYVY) + if (fb->format->format == DRM_FORMAT_YUYV || + fb->format->format == DRM_FORMAT_NV12) format |= NV_PVIDEO_FORMAT_COLOR_LE_CR8YB8CB8YA8; - if (fb->format->format == DRM_FORMAT_NV12) + if (fb->format->format == DRM_FORMAT_NV12 || + fb->format->format == DRM_FORMAT_NV21) format |= NV_PVIDEO_FORMAT_PLANAR; if (nv_plane->iturbt_709) format |= NV_PVIDEO_FORMAT_MATRIX_ITURBT709; if (nv_plane->colorkey & (1 << 24)) format |= NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY; - if (fb->format->format == DRM_FORMAT_NV12) { + if (format & NV_PVIDEO_FORMAT_PLANAR) { nvif_wr32(dev, NV_PVIDEO_UVPLANE_BASE(flip), 0); nvif_wr32(dev, NV_PVIDEO_UVPLANE_OFFSET_BUFF(flip), nv_fb->nvbo->bo.offset + fb->offsets[1]); } - nvif_wr32(dev, NV_PVIDEO_FORMAT(flip), format); + nvif_wr32(dev, NV_PVIDEO_FORMAT(flip), format | fb->pitches[0]); nvif_wr32(dev, NV_PVIDEO_STOP, 0); /* TODO: wait for vblank? */ nvif_wr32(dev, NV_PVIDEO_BUFFER, flip ? 0x10 : 0x1); @@ -357,7 +373,7 @@ nv04_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, struct nouveau_bo *cur = nv_plane->cur; uint32_t overlay = 1; int brightness = (nv_plane->brightness - 512) * 62 / 512; - int pitch, ret, i; + int ret, i; /* Source parameters given in 16.16 fixed point, ignore fractional. */ src_x >>= 16; @@ -365,17 +381,9 @@ nv04_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, src_w >>= 16; src_h >>= 16; - pitch = ALIGN(src_w * 4, 0x100); - - if (pitch > 0xffff) - return -ERANGE; - - /* TODO: Compute an offset? Not sure how to do this for YUYV. */ - if (src_x != 0 || src_y != 0) - return -ERANGE; - - if (crtc_w < src_w || crtc_h < src_h) - return -ERANGE; + ret = verify_scaling(fb, 0, src_x, src_y, src_w, src_h, crtc_w, crtc_h); + if (ret) + return ret; ret = nouveau_bo_pin(nv_fb->nvbo, TTM_PL_FLAG_VRAM, false); if (ret) @@ -389,8 +397,9 @@ nv04_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, for (i = 0; i < 2; i++) { nvif_wr32(dev, NV_PVIDEO_BUFF0_START_ADDRESS + 4 * i, - nv_fb->nvbo->bo.offset); - nvif_wr32(dev, NV_PVIDEO_BUFF0_PITCH_LENGTH + 4 * i, pitch); + nv_fb->nvbo->bo.offset); + nvif_wr32(dev, NV_PVIDEO_BUFF0_PITCH_LENGTH + 4 * i, + fb->pitches[0]); nvif_wr32(dev, NV_PVIDEO_BUFF0_OFFSET + 4 * i, 0); } nvif_wr32(dev, NV_PVIDEO_WINDOW_START, crtc_y << 16 | crtc_x); diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h index e8e77ee24776..deb477282dde 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/conn.h @@ -18,6 +18,7 @@ enum dcb_connector_type { DCB_CONNECTOR_HDMI_C = 0x63, DCB_CONNECTOR_DMS59_DP0 = 0x64, DCB_CONNECTOR_DMS59_DP1 = 0x65, + DCB_CONNECTOR_WFD = 0x70, DCB_CONNECTOR_NONE = 0xff }; diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dcb.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dcb.h index 4892a65ddd48..903d117603d8 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dcb.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/bios/dcb.h @@ -6,6 +6,7 @@ enum dcb_output_type { DCB_OUTPUT_TMDS = 0x2, DCB_OUTPUT_LVDS = 0x3, DCB_OUTPUT_DP = 0x6, + DCB_OUTPUT_WFD = 0x8, DCB_OUTPUT_EOL = 0xe, DCB_OUTPUT_UNUSED = 0xf, DCB_OUTPUT_ANY = -1, diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h index b268b96faece..1bfd93b85575 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/therm.h @@ -96,4 +96,5 @@ int g84_therm_new(struct nvkm_device *, int, struct nvkm_therm **); int gt215_therm_new(struct nvkm_device *, int, struct nvkm_therm **); int gf119_therm_new(struct nvkm_device *, int, struct nvkm_therm **); int gm107_therm_new(struct nvkm_device *, int, struct nvkm_therm **); +int gm200_therm_new(struct nvkm_device *, int, struct nvkm_therm **); #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index b998c33af18a..dd6fba55ad5d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -351,11 +351,8 @@ static int parse_fp_mode_table(struct drm_device *dev, struct nvbios *bios) struct lvdstableheader lth; if (bios->fp.fptablepointer == 0x0) { - /* Apple cards don't have the fp table; the laptops use DDC */ - /* The table is also missing on some x86 IGPs */ -#ifndef __powerpc__ - NV_ERROR(drm, "Pointer to flat panel table invalid\n"); -#endif + /* Most laptop cards lack an fp table. They use DDC. */ + NV_DEBUG(drm, "Pointer to flat panel table invalid\n"); bios->digital_min_front_porch = 0x4b; return 0; } diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 5137155bf3c0..70d8e0d69ad5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -1184,6 +1184,7 @@ drm_conntype_from_dcb(enum dcb_connector_type dcb) case DCB_CONNECTOR_HDMI_0 : case DCB_CONNECTOR_HDMI_1 : case DCB_CONNECTOR_HDMI_C : return DRM_MODE_CONNECTOR_HDMIA; + case DCB_CONNECTOR_WFD : return DRM_MODE_CONNECTOR_VIRTUAL; default: break; } diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index d66640047913..2e7785f49e6d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -231,9 +231,30 @@ nouveau_framebuffer_new(struct drm_device *dev, struct nouveau_bo *nvbo, struct nouveau_framebuffer **pfb) { + struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_framebuffer *fb; int ret; + /* YUV overlays have special requirements pre-NV50 */ + if (drm->client.device.info.family < NV_DEVICE_INFO_V0_TESLA && + + (mode_cmd->pixel_format == DRM_FORMAT_YUYV || + mode_cmd->pixel_format == DRM_FORMAT_UYVY || + mode_cmd->pixel_format == DRM_FORMAT_NV12 || + mode_cmd->pixel_format == DRM_FORMAT_NV21) && + (mode_cmd->pitches[0] & 0x3f || /* align 64 */ + mode_cmd->pitches[0] >= 0x10000 || /* at most 64k pitch */ + (mode_cmd->pitches[1] && /* pitches for planes must match */ + mode_cmd->pitches[0] != mode_cmd->pitches[1]))) { + struct drm_format_name_buf format_name; + DRM_DEBUG_KMS("Unsuitable framebuffer: format: %s; pitches: 0x%x\n 0x%x\n", + drm_get_format_name(mode_cmd->pixel_format, + &format_name), + mode_cmd->pitches[0], + mode_cmd->pitches[1]); + return -EINVAL; + } + if (!(fb = *pfb = kzalloc(sizeof(*fb), GFP_KERNEL))) return -ENOMEM; diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index df7e2037031a..595630d1fb9e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -585,18 +585,18 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime) nouveau_led_suspend(dev); if (dev->mode_config.num_crtc) { - NV_INFO(drm, "suspending console...\n"); + NV_DEBUG(drm, "suspending console...\n"); nouveau_fbcon_set_suspend(dev, 1); - NV_INFO(drm, "suspending display...\n"); + NV_DEBUG(drm, "suspending display...\n"); ret = nouveau_display_suspend(dev, runtime); if (ret) return ret; } - NV_INFO(drm, "evicting buffers...\n"); + NV_DEBUG(drm, "evicting buffers...\n"); ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM); - NV_INFO(drm, "waiting for kernel channels to go idle...\n"); + NV_DEBUG(drm, "waiting for kernel channels to go idle...\n"); if (drm->cechan) { ret = nouveau_channel_idle(drm->cechan); if (ret) @@ -609,7 +609,7 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime) goto fail_display; } - NV_INFO(drm, "suspending fence...\n"); + NV_DEBUG(drm, "suspending fence...\n"); if (drm->fence && nouveau_fence(drm)->suspend) { if (!nouveau_fence(drm)->suspend(drm)) { ret = -ENOMEM; @@ -617,7 +617,7 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime) } } - NV_INFO(drm, "suspending object tree...\n"); + NV_DEBUG(drm, "suspending object tree...\n"); ret = nvif_client_suspend(&drm->client.base); if (ret) goto fail_client; @@ -630,7 +630,7 @@ fail_client: fail_display: if (dev->mode_config.num_crtc) { - NV_INFO(drm, "resuming display...\n"); + NV_DEBUG(drm, "resuming display...\n"); nouveau_display_resume(dev, runtime); } return ret; @@ -641,19 +641,19 @@ nouveau_do_resume(struct drm_device *dev, bool runtime) { struct nouveau_drm *drm = nouveau_drm(dev); - NV_INFO(drm, "resuming object tree...\n"); + NV_DEBUG(drm, "resuming object tree...\n"); nvif_client_resume(&drm->client.base); - NV_INFO(drm, "resuming fence...\n"); + NV_DEBUG(drm, "resuming fence...\n"); if (drm->fence && nouveau_fence(drm)->resume) nouveau_fence(drm)->resume(drm); nouveau_run_vbios_init(dev); if (dev->mode_config.num_crtc) { - NV_INFO(drm, "resuming display...\n"); + NV_DEBUG(drm, "resuming display...\n"); nouveau_display_resume(dev, runtime); - NV_INFO(drm, "resuming console...\n"); + NV_DEBUG(drm, "resuming console...\n"); nouveau_fbcon_set_suspend(dev, 0); } diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index f7b4326a4641..2dbf62a2ac41 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -3141,7 +3141,7 @@ nv50_mstc_new(struct nv50_mstm *mstm, struct drm_dp_mst_port *port, mstc->connector.funcs->reset(&mstc->connector); nouveau_conn_attach_properties(&mstc->connector); - for (i = 0; i < ARRAY_SIZE(mstm->msto) && mstm->msto; i++) + for (i = 0; i < ARRAY_SIZE(mstm->msto) && mstm->msto[i]; i++) drm_mode_connector_attach_encoder(&mstc->connector, &mstm->msto[i]->encoder); drm_object_attach_property(&mstc->connector.base, dev->mode_config.path_property, 0); @@ -4451,11 +4451,13 @@ nv50_display_create(struct drm_device *dev) /* create crtc objects to represent the hw heads */ if (disp->disp->oclass >= GF110_DISP) - crtcs = nvif_rd32(&device->object, 0x022448); + crtcs = nvif_rd32(&device->object, 0x612004) & 0xf; else - crtcs = 2; + crtcs = 0x3; - for (i = 0; i < crtcs; i++) { + for (i = 0; i < fls(crtcs); i++) { + if (!(crtcs & (1 << i))) + continue; ret = nv50_head_create(dev, i); if (ret) goto out; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c index 7bdc7a5ae723..e096a5d9c292 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2043,6 +2043,7 @@ nv120_chipset = { .mxm = nv50_mxm_new, .pci = gk104_pci_new, .pmu = gm107_pmu_new, + .therm = gm200_therm_new, .secboot = gm200_secboot_new, .timer = gk20a_timer_new, .top = gk104_top_new, @@ -2077,6 +2078,7 @@ nv124_chipset = { .mxm = nv50_mxm_new, .pci = gk104_pci_new, .pmu = gm107_pmu_new, + .therm = gm200_therm_new, .secboot = gm200_secboot_new, .timer = gk20a_timer_new, .top = gk104_top_new, @@ -2111,6 +2113,7 @@ nv126_chipset = { .mxm = nv50_mxm_new, .pci = gk104_pci_new, .pmu = gm107_pmu_new, + .therm = gm200_therm_new, .secboot = gm200_secboot_new, .timer = gk20a_timer_new, .top = gk104_top_new, @@ -2321,6 +2324,35 @@ nv137_chipset = { }; static const struct nvkm_device_chip +nv138_chipset = { + .name = "GP108", + .bar = gf100_bar_new, + .bios = nvkm_bios_new, + .bus = gf100_bus_new, + .devinit = gm200_devinit_new, + .fb = gp102_fb_new, + .fuse = gm107_fuse_new, + .gpio = gk104_gpio_new, + .i2c = gm200_i2c_new, + .ibus = gm200_ibus_new, + .imem = nv50_instmem_new, + .ltc = gp100_ltc_new, + .mc = gp100_mc_new, + .mmu = gf100_mmu_new, + .pci = gp100_pci_new, + .pmu = gp102_pmu_new, + .timer = gk20a_timer_new, + .top = gk104_top_new, + .ce[0] = gp102_ce_new, + .ce[1] = gp102_ce_new, + .ce[2] = gp102_ce_new, + .ce[3] = gp102_ce_new, + .disp = gp102_disp_new, + .dma = gf119_dma_new, + .fifo = gp100_fifo_new, +}; + +static const struct nvkm_device_chip nv13b_chipset = { .name = "GP10B", .bar = gk20a_bar_new, @@ -2782,6 +2814,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, case 0x134: device->chip = &nv134_chipset; break; case 0x136: device->chip = &nv136_chipset; break; case 0x137: device->chip = &nv137_chipset; break; + case 0x138: device->chip = &nv138_chipset; break; case 0x13b: device->chip = &nv13b_chipset; break; default: nvdev_error(device, "unknown chipset (%08x)\n", boot0); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c index 88582af8bd89..93a75e5b2791 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c @@ -285,6 +285,10 @@ nvkm_disp_oneinit(struct nvkm_engine *engine) case DCB_OUTPUT_DP: ret = nvkm_dp_new(disp, i, &dcbE, &outp); break; + case DCB_OUTPUT_WFD: + /* No support for WFD yet. */ + ret = -ENODEV; + continue; default: nvkm_warn(subdev, "dcb %d type %d unknown\n", i, dcbE.type); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c index b33552757647..9fd7ae331308 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c @@ -92,5 +92,8 @@ gf119_head = { int gf119_head_new(struct nvkm_disp *disp, int id) { + struct nvkm_device *device = disp->engine.subdev.device; + if (!(nvkm_rd32(device, 0x612004) & (0x00000001 << id))) + return 0; return nvkm_head_new_(&gf119_head, disp, id); } diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c index 8a8895246d26..7fea7d45202f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv31.c @@ -124,6 +124,8 @@ nv31_mpeg_tile(struct nvkm_engine *engine, int i, struct nvkm_fb_tile *tile) static bool nv31_mpeg_mthd_dma(struct nvkm_device *device, u32 mthd, u32 data) { + struct nv31_mpeg *mpeg = nv31_mpeg(device->mpeg); + struct nvkm_subdev *subdev = &mpeg->engine.subdev; u32 inst = data << 4; u32 dma0 = nvkm_rd32(device, 0x700000 + inst); u32 dma1 = nvkm_rd32(device, 0x700004 + inst); @@ -132,8 +134,11 @@ nv31_mpeg_mthd_dma(struct nvkm_device *device, u32 mthd, u32 data) u32 size = dma1 + 1; /* only allow linear DMA objects */ - if (!(dma0 & 0x00002000)) + if (!(dma0 & 0x00002000)) { + nvkm_error(subdev, "inst %08x dma0 %08x dma1 %08x dma2 %08x\n", + inst, dma0, dma1, dma2); return false; + } if (mthd == 0x0190) { /* DMA_CMD */ diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv40.c index 16de5bd94b14..b5ec7c504dc6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv40.c @@ -31,6 +31,8 @@ bool nv40_mpeg_mthd_dma(struct nvkm_device *device, u32 mthd, u32 data) { struct nvkm_instmem *imem = device->imem; + struct nv31_mpeg *mpeg = nv31_mpeg(device->mpeg); + struct nvkm_subdev *subdev = &mpeg->engine.subdev; u32 inst = data << 4; u32 dma0 = nvkm_instmem_rd32(imem, inst + 0); u32 dma1 = nvkm_instmem_rd32(imem, inst + 4); @@ -39,8 +41,11 @@ nv40_mpeg_mthd_dma(struct nvkm_device *device, u32 mthd, u32 data) u32 size = dma1 + 1; /* only allow linear DMA objects */ - if (!(dma0 & 0x00002000)) + if (!(dma0 & 0x00002000)) { + nvkm_error(subdev, "inst %08x dma0 %08x dma1 %08x dma2 %08x\n", + inst, dma0, dma1, dma2); return false; + } if (mthd == 0x0190) { /* DMA_CMD */ diff --git a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c index d45d7947a964..77273b53672c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c +++ b/drivers/gpu/drm/nouveau/nvkm/falcon/msgqueue.c @@ -251,7 +251,7 @@ cmd_write(struct nvkm_msgqueue *priv, struct nvkm_msgqueue_hdr *cmd, struct nvkm_msgqueue_queue *queue) { const struct nvkm_subdev *subdev = priv->falcon->owner; - static unsigned long timeout = ~0; + static unsigned timeout = 2000; unsigned long end_jiffies = jiffies + msecs_to_jiffies(timeout); int ret = -EAGAIN; bool commit = true; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c index 6d8f21290aa2..676c167c95b9 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.c @@ -24,6 +24,7 @@ #include "gf100.h" #include <core/gpuobj.h> +#include <core/option.h> #include <subdev/fb.h> #include <subdev/mmu.h> @@ -59,6 +60,8 @@ gf100_bar_ctor_vm(struct gf100_bar *bar, struct gf100_bar_vm *bar_vm, return ret; bar_len = device->func->resource_size(device, bar_nr); + if (bar_nr == 3 && bar->bar2_halve) + bar_len >>= 1; ret = nvkm_vm_new(device, 0, bar_len, 0, key, &vm); if (ret) @@ -129,6 +132,8 @@ gf100_bar_init(struct nvkm_bar *base) if (bar->bar[0].mem) { addr = nvkm_memory_addr(bar->bar[0].mem) >> 12; + if (bar->bar2_halve) + addr |= 0x40000000; nvkm_wr32(device, 0x001714, 0x80000000 | addr); } @@ -161,6 +166,7 @@ gf100_bar_new_(const struct nvkm_bar_func *func, struct nvkm_device *device, if (!(bar = kzalloc(sizeof(*bar), GFP_KERNEL))) return -ENOMEM; nvkm_bar_ctor(func, device, index, &bar->base); + bar->bar2_halve = nvkm_boolopt(device->cfgopt, "NvBar2Halve", false); *pbar = &bar->base; return 0; } diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h index f7dea69640d8..20a5255362ba 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/bar/gf100.h @@ -11,6 +11,7 @@ struct gf100_bar_vm { struct gf100_bar { struct nvkm_bar base; + bool bar2_halve; struct gf100_bar_vm bar[2]; }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c index 3841ad6be99e..a239e73562c8 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/gf100.c @@ -60,12 +60,12 @@ gf100_fb_oneinit(struct nvkm_fb *base) size = min(size, 0x1000); ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, size, 0x1000, - false, &fb->base.mmu_rd); + true, &fb->base.mmu_rd); if (ret) return ret; ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, size, 0x1000, - false, &fb->base.mmu_wr); + true, &fb->base.mmu_wr); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c index d2c4d6033abb..f93766418056 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mc/gf100.c @@ -27,6 +27,7 @@ static const struct nvkm_mc_map gf100_mc_reset[] = { { 0x00020000, NVKM_ENGINE_MSPDEC }, { 0x00008000, NVKM_ENGINE_MSVLD }, + { 0x00002000, NVKM_SUBDEV_PMU, true }, { 0x00001000, NVKM_ENGINE_GR }, { 0x00000100, NVKM_ENGINE_FIFO }, { 0x00000080, NVKM_ENGINE_CE1 }, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c index eb9b278198b2..a4cb82495cee 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pci/base.c @@ -192,6 +192,10 @@ nvkm_pci_new_(const struct nvkm_pci_func *func, struct nvkm_device *device, } } +#ifdef __BIG_ENDIAN + pci->msi = false; +#endif + pci->msi = nvkm_boolopt(device->cfgopt, "NvMSI", pci->msi); if (pci->msi && func->msi_rearm) { pci->msi = pci_enable_msi(pci->pdev) == 0; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c index 3306f9fe7140..ce70a193caa7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c @@ -75,7 +75,7 @@ nvkm_pmu_reset(struct nvkm_pmu *pmu) { struct nvkm_device *device = pmu->subdev.device; - if (!(nvkm_rd32(device, 0x000200) & 0x00002000)) + if (!pmu->func->enabled(pmu)) return 0; /* Inhibit interrupts, and wait for idle. */ diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf100.c index 0e36d4cb7201..0b458656e870 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf100.c @@ -24,13 +24,30 @@ #include "priv.h" #include "fuc/gf100.fuc3.h" +#include <subdev/mc.h> + +void +gf100_pmu_reset(struct nvkm_pmu *pmu) +{ + struct nvkm_device *device = pmu->subdev.device; + nvkm_mc_disable(device, NVKM_SUBDEV_PMU); + nvkm_mc_enable(device, NVKM_SUBDEV_PMU); +} + +bool +gf100_pmu_enabled(struct nvkm_pmu *pmu) +{ + return nvkm_mc_enabled(pmu->subdev.device, NVKM_SUBDEV_PMU); +} + static const struct nvkm_pmu_func gf100_pmu = { .code.data = gf100_pmu_code, .code.size = sizeof(gf100_pmu_code), .data.data = gf100_pmu_data, .data.size = sizeof(gf100_pmu_data), - .reset = gt215_pmu_reset, + .enabled = gf100_pmu_enabled, + .reset = gf100_pmu_reset, .init = gt215_pmu_init, .fini = gt215_pmu_fini, .intr = gt215_pmu_intr, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf119.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf119.c index 0e4ba4248b15..3dfa79d4fb13 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf119.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gf119.c @@ -30,7 +30,8 @@ gf119_pmu = { .code.size = sizeof(gf119_pmu_code), .data.data = gf119_pmu_data, .data.size = sizeof(gf119_pmu_data), - .reset = gt215_pmu_reset, + .enabled = gf100_pmu_enabled, + .reset = gf100_pmu_reset, .init = gt215_pmu_init, .fini = gt215_pmu_fini, .intr = gt215_pmu_intr, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c index 2ad858d825ac..8f7ec10fd2a4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk104.c @@ -109,7 +109,8 @@ gk104_pmu = { .code.size = sizeof(gk104_pmu_code), .data.data = gk104_pmu_data, .data.size = sizeof(gk104_pmu_data), - .reset = gt215_pmu_reset, + .enabled = gf100_pmu_enabled, + .reset = gf100_pmu_reset, .init = gt215_pmu_init, .fini = gt215_pmu_fini, .intr = gt215_pmu_intr, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk110.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk110.c index fc4b8ecfdaeb..345741d55a56 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk110.c @@ -88,7 +88,8 @@ gk110_pmu = { .code.size = sizeof(gk110_pmu_code), .data.data = gk110_pmu_data, .data.size = sizeof(gk110_pmu_data), - .reset = gt215_pmu_reset, + .enabled = gf100_pmu_enabled, + .reset = gf100_pmu_reset, .init = gt215_pmu_init, .fini = gt215_pmu_fini, .intr = gt215_pmu_intr, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk208.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk208.c index e9a91277683a..e4acf7876ea1 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk208.c @@ -30,7 +30,8 @@ gk208_pmu = { .code.size = sizeof(gk208_pmu_code), .data.data = gk208_pmu_data, .data.size = sizeof(gk208_pmu_data), - .reset = gt215_pmu_reset, + .enabled = gf100_pmu_enabled, + .reset = gf100_pmu_reset, .init = gt215_pmu_init, .fini = gt215_pmu_fini, .intr = gt215_pmu_intr, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c index 978aae3c1001..05e81855c367 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gk20a.c @@ -196,9 +196,10 @@ gk20a_dvfs_data= { static const struct nvkm_pmu_func gk20a_pmu = { + .enabled = gf100_pmu_enabled, .init = gk20a_pmu_init, .fini = gk20a_pmu_fini, - .reset = gt215_pmu_reset, + .reset = gf100_pmu_reset, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm107.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm107.c index 9a248ed75f09..459df1ef9e70 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm107.c @@ -32,7 +32,8 @@ gm107_pmu = { .code.size = sizeof(gm107_pmu_code), .data.data = gm107_pmu_data, .data.size = sizeof(gm107_pmu_data), - .reset = gt215_pmu_reset, + .enabled = gf100_pmu_enabled, + .reset = gf100_pmu_reset, .init = gt215_pmu_init, .fini = gt215_pmu_fini, .intr = gt215_pmu_intr, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c index 44bef22bce52..31c843145c7a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gm20b.c @@ -38,6 +38,7 @@ gm20b_pmu_recv(struct nvkm_pmu *pmu) static const struct nvkm_pmu_func gm20b_pmu = { + .enabled = gf100_pmu_enabled, .intr = gt215_pmu_intr, .recv = gm20b_pmu_recv, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp100.c index 6c41c20c85a7..e210cd6af816 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp100.c @@ -25,7 +25,8 @@ static const struct nvkm_pmu_func gp100_pmu = { - .reset = gt215_pmu_reset, + .enabled = gf100_pmu_enabled, + .reset = gf100_pmu_reset, }; int diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp102.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp102.c index f017352206c9..98c7a2a8afc4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp102.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gp102.c @@ -31,8 +31,15 @@ gp102_pmu_reset(struct nvkm_pmu *pmu) nvkm_mask(device, 0x10a3c0, 0x00000001, 0x00000000); } +static bool +gp102_pmu_enabled(struct nvkm_pmu *pmu) +{ + return !(nvkm_rd32(pmu->subdev.device, 0x10a3c0) & 0x00000001); +} + static const struct nvkm_pmu_func gp102_pmu = { + .enabled = gp102_pmu_enabled, .reset = gp102_pmu_reset, }; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gt215.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gt215.c index 90d428b3be97..e04216daea58 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gt215.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/gt215.c @@ -180,13 +180,19 @@ gt215_pmu_fini(struct nvkm_pmu *pmu) nvkm_wr32(pmu->subdev.device, 0x10a014, 0x00000060); } -void +static void gt215_pmu_reset(struct nvkm_pmu *pmu) { struct nvkm_device *device = pmu->subdev.device; - nvkm_mask(device, 0x000200, 0x00002000, 0x00000000); - nvkm_mask(device, 0x000200, 0x00002000, 0x00002000); - nvkm_rd32(device, 0x000200); + nvkm_mask(device, 0x022210, 0x00000001, 0x00000000); + nvkm_mask(device, 0x022210, 0x00000001, 0x00000001); + nvkm_rd32(device, 0x022210); +} + +static bool +gt215_pmu_enabled(struct nvkm_pmu *pmu) +{ + return nvkm_rd32(pmu->subdev.device, 0x022210) & 0x00000001; } int @@ -241,6 +247,7 @@ gt215_pmu = { .code.size = sizeof(gt215_pmu_code), .data.data = gt215_pmu_data, .data.size = sizeof(gt215_pmu_data), + .enabled = gt215_pmu_enabled, .reset = gt215_pmu_reset, .init = gt215_pmu_init, .fini = gt215_pmu_fini, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h index 096cba069f72..a4c48a10cd47 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/priv.h @@ -20,6 +20,7 @@ struct nvkm_pmu_func { u32 size; } data; + bool (*enabled)(struct nvkm_pmu *); void (*reset)(struct nvkm_pmu *); int (*init)(struct nvkm_pmu *); void (*fini)(struct nvkm_pmu *); @@ -30,12 +31,14 @@ struct nvkm_pmu_func { void (*pgob)(struct nvkm_pmu *, bool); }; -void gt215_pmu_reset(struct nvkm_pmu *); int gt215_pmu_init(struct nvkm_pmu *); void gt215_pmu_fini(struct nvkm_pmu *); void gt215_pmu_intr(struct nvkm_pmu *); void gt215_pmu_recv(struct nvkm_pmu *); int gt215_pmu_send(struct nvkm_pmu *, u32[2], u32, u32, u32, u32); +bool gf100_pmu_enabled(struct nvkm_pmu *); +void gf100_pmu_reset(struct nvkm_pmu *); + void gk110_pmu_pgob(struct nvkm_pmu *, bool); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild index 135758ba3e28..2bafcc1d1818 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/Kbuild @@ -11,3 +11,4 @@ nvkm-y += nvkm/subdev/therm/g84.o nvkm-y += nvkm/subdev/therm/gt215.o nvkm-y += nvkm/subdev/therm/gf119.o nvkm-y += nvkm/subdev/therm/gm107.o +nvkm-y += nvkm/subdev/therm/gm200.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/g84.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/g84.c index 86e81930d8ee..96f8da40ac82 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/g84.c @@ -203,7 +203,7 @@ g84_therm_fini(struct nvkm_therm *therm) nvkm_wr32(device, 0x1100, 0x10000); /* PBUS */ } -static void +void g84_therm_init(struct nvkm_therm *therm) { g84_sensor_setup(therm); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gm200.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gm200.c new file mode 100644 index 000000000000..73dc78093d5d --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/gm200.c @@ -0,0 +1,39 @@ +/* + * Copyright 2017 Karol Herbst + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Karol Herbst + */ +#include "priv.h" + +static const struct nvkm_therm_func +gm200_therm = { + .init = g84_therm_init, + .fini = g84_therm_fini, + .temp_get = g84_temp_get, + .program_alarms = nvkm_therm_program_alarms_polling, +}; + +int +gm200_therm_new(struct nvkm_device *device, int index, + struct nvkm_therm **ptherm) +{ + return nvkm_therm_new_(&gm200_therm, device, index, ptherm); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h index 235a5d8daff6..1f46e371d7c4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/priv.h @@ -111,6 +111,7 @@ void g84_therm_fini(struct nvkm_therm *); int gt215_therm_fan_sense(struct nvkm_therm *); +void g84_therm_init(struct nvkm_therm *); void gf119_therm_init(struct nvkm_therm *); int nvkm_fanpwm_create(struct nvkm_therm *, struct dcb_gpio_func *); diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c index e93b2410c38b..ddb2b2c600ca 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/therm/temp.c @@ -83,7 +83,7 @@ nvkm_therm_sensor_event(struct nvkm_therm *therm, enum nvkm_therm_thrs thrs, { struct nvkm_subdev *subdev = &therm->subdev; bool active; - const char *thresolds[] = { + static const char * const thresholds[] = { "fanboost", "downclock", "critical", "shutdown" }; int temperature = therm->func->temp_get(therm); @@ -94,10 +94,10 @@ nvkm_therm_sensor_event(struct nvkm_therm *therm, enum nvkm_therm_thrs thrs, if (dir == NVKM_THERM_THRS_FALLING) nvkm_info(subdev, "temperature (%i C) went below the '%s' threshold\n", - temperature, thresolds[thrs]); + temperature, thresholds[thrs]); else nvkm_info(subdev, "temperature (%i C) hit the '%s' threshold\n", - temperature, thresolds[thrs]); + temperature, thresholds[thrs]); active = (dir == NVKM_THERM_THRS_RISING); switch (thrs) { |