mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-04 01:20:01 -04:00
Merge branch 'linux-5.4' of git://github.com/skeggsb/linux into drm-next
This is mostly just the stuff I missed last round. Various cleanup patches + fixes, improvements to display colour management, and some code to avoid loading when power cables aren't properly attached. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Ben Skeggs <skeggsb@gmail.com> Link: https://patchwork.freedesktop.org/patch/msgid/CACAvsv7hqj9_VHq+YiGL8Z8XsU2vPbqbNPC=LeN1Rb0XxMQypQ@mail.gmail.com
This commit is contained in:
@@ -21,8 +21,6 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <drm/drmP.h>
|
||||
|
||||
#include "nouveau_drv.h"
|
||||
#include "nouveau_reg.h"
|
||||
#include "hw.h"
|
||||
|
||||
@@ -22,11 +22,10 @@
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include <linux/pm_runtime.h>
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
#include <drm/drm_plane_helper.h>
|
||||
#include <drm/drm_vblank.h>
|
||||
|
||||
#include "nouveau_drv.h"
|
||||
#include "nouveau_reg.h"
|
||||
@@ -1031,53 +1030,6 @@ nv04_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nouveau_crtc_set_config(struct drm_mode_set *set,
|
||||
struct drm_modeset_acquire_ctx *ctx)
|
||||
{
|
||||
struct drm_device *dev;
|
||||
struct nouveau_drm *drm;
|
||||
int ret;
|
||||
struct drm_crtc *crtc;
|
||||
bool active = false;
|
||||
if (!set || !set->crtc)
|
||||
return -EINVAL;
|
||||
|
||||
dev = set->crtc->dev;
|
||||
|
||||
/* get a pm reference here */
|
||||
ret = pm_runtime_get_sync(dev->dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
return ret;
|
||||
|
||||
ret = drm_crtc_helper_set_config(set, ctx);
|
||||
|
||||
drm = nouveau_drm(dev);
|
||||
|
||||
/* if we get here with no crtcs active then we can drop a reference */
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
if (crtc->enabled)
|
||||
active = true;
|
||||
}
|
||||
|
||||
pm_runtime_mark_last_busy(dev->dev);
|
||||
/* if we have active crtcs and we don't have a power ref,
|
||||
take the current one */
|
||||
if (active && !drm->have_disp_power_ref) {
|
||||
drm->have_disp_power_ref = true;
|
||||
return ret;
|
||||
}
|
||||
/* if we have no active crtcs, then drop the power ref
|
||||
we got before */
|
||||
if (!active && drm->have_disp_power_ref) {
|
||||
pm_runtime_put_autosuspend(dev->dev);
|
||||
drm->have_disp_power_ref = false;
|
||||
}
|
||||
/* drop the power reference we got coming in here */
|
||||
pm_runtime_put_autosuspend(dev->dev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct nv04_page_flip_state {
|
||||
struct list_head head;
|
||||
struct drm_pending_vblank_event *event;
|
||||
@@ -1293,7 +1245,7 @@ static const struct drm_crtc_funcs nv04_crtc_funcs = {
|
||||
.cursor_set = nv04_crtc_cursor_set,
|
||||
.cursor_move = nv04_crtc_cursor_move,
|
||||
.gamma_set = nv_crtc_gamma_set,
|
||||
.set_config = nouveau_crtc_set_config,
|
||||
.set_config = drm_crtc_helper_set_config,
|
||||
.page_flip = nv04_crtc_page_flip,
|
||||
.destroy = nv_crtc_destroy,
|
||||
};
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_mode.h>
|
||||
#include "nouveau_drv.h"
|
||||
#include "nouveau_reg.h"
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
|
||||
#include "nouveau_drv.h"
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
|
||||
#include "nouveau_drv.h"
|
||||
#include "nouveau_reg.h"
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
* Author: Ben Skeggs
|
||||
*/
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
|
||||
#include "nouveau_drv.h"
|
||||
@@ -210,7 +209,7 @@ nv04_display_create(struct drm_device *dev)
|
||||
nouveau_display(dev)->fini = nv04_display_fini;
|
||||
|
||||
/* Pre-nv50 doesn't support atomic, so don't expose the ioctls */
|
||||
dev->driver->driver_features &= ~DRIVER_ATOMIC;
|
||||
dev->driver_features &= ~DRIVER_ATOMIC;
|
||||
|
||||
/* Request page flip completion event. */
|
||||
if (drm->nvsw.client) {
|
||||
|
||||
@@ -161,7 +161,6 @@ nv_match_device(struct drm_device *dev, unsigned device,
|
||||
dev->pdev->subsystem_device == sub_device;
|
||||
}
|
||||
|
||||
#include <subdev/bios.h>
|
||||
#include <subdev/bios/init.h>
|
||||
|
||||
static inline void
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include "nouveau_drv.h"
|
||||
#include "hw.h"
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#ifndef __NOUVEAU_HW_H__
|
||||
#define __NOUVEAU_HW_H__
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include "disp.h"
|
||||
#include "nvreg.h"
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
* written by Arthur Huillet.
|
||||
*/
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_crtc.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include "nouveau_drv.h"
|
||||
#include "nouveau_encoder.h"
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include "nouveau_drv.h"
|
||||
#include "nouveau_reg.h"
|
||||
#include "nouveau_encoder.h"
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
#include "nouveau_drv.h"
|
||||
|
||||
@@ -184,6 +184,11 @@ struct nv50_wndw_atom {
|
||||
} i;
|
||||
} xlut;
|
||||
|
||||
struct {
|
||||
u32 matrix[12];
|
||||
bool valid;
|
||||
} csc;
|
||||
|
||||
struct {
|
||||
u8 mode:2;
|
||||
u8 interval:4;
|
||||
@@ -216,14 +221,23 @@ struct nv50_wndw_atom {
|
||||
u16 y;
|
||||
} point;
|
||||
|
||||
struct {
|
||||
u8 depth;
|
||||
u8 k1;
|
||||
u8 src_color:4;
|
||||
u8 dst_color:4;
|
||||
} blend;
|
||||
|
||||
union nv50_wndw_atom_mask {
|
||||
struct {
|
||||
bool ntfy:1;
|
||||
bool sema:1;
|
||||
bool xlut:1;
|
||||
bool csc:1;
|
||||
bool image:1;
|
||||
bool scale:1;
|
||||
bool point:1;
|
||||
bool blend:1;
|
||||
};
|
||||
u8 mask;
|
||||
} set, clr;
|
||||
|
||||
@@ -25,7 +25,9 @@
|
||||
#include <nvif/event.h>
|
||||
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
#include <drm/drm_plane_helper.h>
|
||||
|
||||
#include "nouveau_bo.h"
|
||||
|
||||
void
|
||||
@@ -56,12 +58,21 @@ static void
|
||||
base507c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
{
|
||||
u32 *push;
|
||||
if ((push = evo_wait(&wndw->wndw, 10))) {
|
||||
if ((push = evo_wait(&wndw->wndw, 13))) {
|
||||
evo_mthd(push, 0x0084, 1);
|
||||
evo_data(push, asyw->image.mode << 8 |
|
||||
asyw->image.interval << 4);
|
||||
evo_mthd(push, 0x00c0, 1);
|
||||
evo_data(push, asyw->image.handle[0]);
|
||||
if (asyw->image.format == 0xca) {
|
||||
evo_mthd(push, 0x0110, 2);
|
||||
evo_data(push, 1);
|
||||
evo_data(push, 0x6400);
|
||||
} else {
|
||||
evo_mthd(push, 0x0110, 2);
|
||||
evo_data(push, 0);
|
||||
evo_data(push, 0);
|
||||
}
|
||||
evo_mthd(push, 0x0800, 5);
|
||||
evo_data(push, asyw->image.offset[0] >> 8);
|
||||
evo_data(push, 0x00000000);
|
||||
@@ -179,9 +190,6 @@ base507c_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
|
||||
const struct drm_framebuffer *fb = asyw->state.fb;
|
||||
int ret;
|
||||
|
||||
if (!fb->format->depth)
|
||||
return -EINVAL;
|
||||
|
||||
ret = drm_atomic_helper_check_plane_state(&asyw->state, &asyh->state,
|
||||
DRM_PLANE_HELPER_NO_SCALING,
|
||||
DRM_PLANE_HELPER_NO_SCALING,
|
||||
@@ -200,6 +208,14 @@ base507c_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
|
||||
asyh->base.y = asyw->state.src.y1 >> 16;
|
||||
asyh->base.w = asyw->state.fb->width;
|
||||
asyh->base.h = asyw->state.fb->height;
|
||||
|
||||
/* Some newer formats, esp FP16 ones, don't have a
|
||||
* "depth". There's nothing that really makes sense there
|
||||
* either, so just set it to the implicit bit count.
|
||||
*/
|
||||
if (!asyh->base.depth)
|
||||
asyh->base.depth = asyh->base.cpp * 8;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -215,6 +231,8 @@ base507c_format[] = {
|
||||
DRM_FORMAT_ABGR2101010,
|
||||
DRM_FORMAT_XBGR8888,
|
||||
DRM_FORMAT_ABGR8888,
|
||||
DRM_FORMAT_XBGR16161616F,
|
||||
DRM_FORMAT_ABGR16161616F,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
@@ -25,12 +25,21 @@ static void
|
||||
base827c_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
{
|
||||
u32 *push;
|
||||
if ((push = evo_wait(&wndw->wndw, 10))) {
|
||||
if ((push = evo_wait(&wndw->wndw, 13))) {
|
||||
evo_mthd(push, 0x0084, 1);
|
||||
evo_data(push, asyw->image.mode << 8 |
|
||||
asyw->image.interval << 4);
|
||||
evo_mthd(push, 0x00c0, 1);
|
||||
evo_data(push, asyw->image.handle[0]);
|
||||
if (asyw->image.format == 0xca) {
|
||||
evo_mthd(push, 0x0110, 2);
|
||||
evo_data(push, 1);
|
||||
evo_data(push, 0x6400);
|
||||
} else {
|
||||
evo_mthd(push, 0x0110, 2);
|
||||
evo_data(push, 0);
|
||||
evo_data(push, 0);
|
||||
}
|
||||
evo_mthd(push, 0x0800, 5);
|
||||
evo_data(push, asyw->image.offset[0] >> 8);
|
||||
evo_data(push, 0x00000000);
|
||||
|
||||
@@ -83,6 +83,68 @@ base907c_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
asyw->xlut.i.load = head907d_olut_load;
|
||||
}
|
||||
|
||||
static inline u32
|
||||
csc_drm_to_base(u64 in)
|
||||
{
|
||||
/* base takes a 19-bit 2's complement value in S3.16 format */
|
||||
bool sign = in & BIT_ULL(63);
|
||||
u32 integer = (in >> 32) & 0x7fffffff;
|
||||
u32 fraction = in & 0xffffffff;
|
||||
|
||||
if (integer >= 4) {
|
||||
return (1 << 18) - (sign ? 0 : 1);
|
||||
} else {
|
||||
u32 ret = (integer << 16) | (fraction >> 16);
|
||||
if (sign)
|
||||
ret = -ret;
|
||||
return ret & GENMASK(18, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
base907c_csc(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
|
||||
const struct drm_color_ctm *ctm)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (j = 0; j < 3; j++) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
u32 *val = &asyw->csc.matrix[j * 4 + i];
|
||||
/* DRM does not support constant offset, while
|
||||
* HW CSC does. Skip it. */
|
||||
if (i == 3) {
|
||||
*val = 0;
|
||||
} else {
|
||||
*val = csc_drm_to_base(ctm->matrix[j * 3 + i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
base907c_csc_clr(struct nv50_wndw *wndw)
|
||||
{
|
||||
u32 *push;
|
||||
if ((push = evo_wait(&wndw->wndw, 2))) {
|
||||
evo_mthd(push, 0x0140, 1);
|
||||
evo_data(push, 0x00000000);
|
||||
evo_kick(push, &wndw->wndw);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
base907c_csc_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
{
|
||||
u32 *push, i;
|
||||
if ((push = evo_wait(&wndw->wndw, 13))) {
|
||||
evo_mthd(push, 0x0140, 12);
|
||||
evo_data(push, asyw->csc.matrix[0] | 0x80000000);
|
||||
for (i = 1; i < 12; i++)
|
||||
evo_data(push, asyw->csc.matrix[i]);
|
||||
evo_kick(push, &wndw->wndw);
|
||||
}
|
||||
}
|
||||
|
||||
const struct nv50_wndw_func
|
||||
base907c = {
|
||||
.acquire = base507c_acquire,
|
||||
@@ -94,6 +156,9 @@ base907c = {
|
||||
.ntfy_clr = base507c_ntfy_clr,
|
||||
.ntfy_wait_begun = base507c_ntfy_wait_begun,
|
||||
.ilut = base907c_ilut,
|
||||
.csc = base907c_csc,
|
||||
.csc_set = base907c_csc_set,
|
||||
.csc_clr = base907c_csc_clr,
|
||||
.olut_core = true,
|
||||
.xlut_set = base907c_xlut_set,
|
||||
.xlut_clr = base907c_xlut_clr,
|
||||
|
||||
@@ -36,6 +36,8 @@ base917c_format[] = {
|
||||
DRM_FORMAT_ABGR8888,
|
||||
DRM_FORMAT_XRGB2101010,
|
||||
DRM_FORMAT_ARGB2101010,
|
||||
DRM_FORMAT_XBGR16161616F,
|
||||
DRM_FORMAT_ABGR16161616F,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ corec37d_init(struct nv50_core *core)
|
||||
for (i = 0; i < windows; i++) {
|
||||
evo_mthd(push, 0x1000 + (i * 0x080), 3);
|
||||
evo_data(push, i >> 1);
|
||||
evo_data(push, 0x00000017);
|
||||
evo_data(push, 0x0000001f);
|
||||
evo_data(push, 0x00000000);
|
||||
evo_mthd(push, 0x1010 + (i * 0x080), 1);
|
||||
evo_data(push, 0x00127fff);
|
||||
|
||||
@@ -30,14 +30,14 @@
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/hdmi.h>
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_dp_helper.h>
|
||||
#include <drm/drm_edid.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
#include <drm/drm_plane_helper.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
#include <drm/drm_scdc_helper.h>
|
||||
#include <drm/drm_edid.h>
|
||||
#include <drm/drm_vblank.h>
|
||||
|
||||
#include <nvif/class.h>
|
||||
#include <nvif/cl0002.h>
|
||||
@@ -1826,8 +1826,11 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
|
||||
|
||||
NV_ATOMIC(drm, "%s: clr %04x (set %04x)\n", crtc->name,
|
||||
asyh->clr.mask, asyh->set.mask);
|
||||
if (old_crtc_state->active && !new_crtc_state->active)
|
||||
|
||||
if (old_crtc_state->active && !new_crtc_state->active) {
|
||||
pm_runtime_put_noidle(dev->dev);
|
||||
drm_crtc_vblank_off(crtc);
|
||||
}
|
||||
|
||||
if (asyh->clr.mask) {
|
||||
nv50_head_flush_clr(head, asyh, atom->flush_disable);
|
||||
@@ -1913,8 +1916,10 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
|
||||
}
|
||||
|
||||
if (new_crtc_state->active) {
|
||||
if (!old_crtc_state->active)
|
||||
if (!old_crtc_state->active) {
|
||||
drm_crtc_vblank_on(crtc);
|
||||
pm_runtime_get_noresume(dev->dev);
|
||||
}
|
||||
if (new_crtc_state->event)
|
||||
drm_crtc_vblank_get(crtc);
|
||||
}
|
||||
@@ -1979,6 +1984,10 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
|
||||
drm_atomic_helper_cleanup_planes(dev, state);
|
||||
drm_atomic_helper_commit_cleanup_done(state);
|
||||
drm_atomic_state_put(state);
|
||||
|
||||
/* Drop the RPM ref we got from nv50_disp_atomic_commit() */
|
||||
pm_runtime_mark_last_busy(dev->dev);
|
||||
pm_runtime_put_autosuspend(dev->dev);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -1993,11 +2002,8 @@ static int
|
||||
nv50_disp_atomic_commit(struct drm_device *dev,
|
||||
struct drm_atomic_state *state, bool nonblock)
|
||||
{
|
||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||
struct drm_plane_state *new_plane_state;
|
||||
struct drm_plane *plane;
|
||||
struct drm_crtc *crtc;
|
||||
bool active = false;
|
||||
int ret, i;
|
||||
|
||||
ret = pm_runtime_get_sync(dev->dev);
|
||||
@@ -2034,27 +2040,17 @@ nv50_disp_atomic_commit(struct drm_device *dev,
|
||||
|
||||
drm_atomic_state_get(state);
|
||||
|
||||
/*
|
||||
* Grab another RPM ref for the commit tail, which will release the
|
||||
* ref when it's finished
|
||||
*/
|
||||
pm_runtime_get_noresume(dev->dev);
|
||||
|
||||
if (nonblock)
|
||||
queue_work(system_unbound_wq, &state->commit_work);
|
||||
else
|
||||
nv50_disp_atomic_commit_tail(state);
|
||||
|
||||
drm_for_each_crtc(crtc, dev) {
|
||||
if (crtc->state->active) {
|
||||
if (!drm->have_disp_power_ref) {
|
||||
drm->have_disp_power_ref = true;
|
||||
return 0;
|
||||
}
|
||||
active = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!active && drm->have_disp_power_ref) {
|
||||
pm_runtime_put_autosuspend(dev->dev);
|
||||
drm->have_disp_power_ref = false;
|
||||
}
|
||||
|
||||
err_cleanup:
|
||||
if (ret)
|
||||
drm_atomic_helper_cleanup_planes(dev, state);
|
||||
@@ -2316,6 +2312,7 @@ nv50_display_create(struct drm_device *dev)
|
||||
disp->disp = &nouveau_display(dev)->disp;
|
||||
dev->mode_config.funcs = &nv50_disp_func;
|
||||
dev->mode_config.quirk_addfb_prefer_xbgr_30bpp = true;
|
||||
dev->mode_config.normalize_zpos = true;
|
||||
|
||||
/* small shared memory area we use for notifiers and semaphores */
|
||||
ret = nouveau_bo_new(&drm->client, 4096, 0x1000, TTM_PL_FLAG_VRAM,
|
||||
|
||||
@@ -480,7 +480,7 @@ nv50_head_create(struct drm_device *dev, int index)
|
||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||
struct nv50_disp *disp = nv50_disp(dev);
|
||||
struct nv50_head *head;
|
||||
struct nv50_wndw *curs, *wndw;
|
||||
struct nv50_wndw *base, *ovly, *curs;
|
||||
struct drm_crtc *crtc;
|
||||
int ret;
|
||||
|
||||
@@ -492,13 +492,13 @@ nv50_head_create(struct drm_device *dev, int index)
|
||||
head->base.index = index;
|
||||
|
||||
if (disp->disp->object.oclass < GV100_DISP) {
|
||||
ret = nv50_ovly_new(drm, head->base.index, &wndw);
|
||||
ret = nv50_base_new(drm, head->base.index, &wndw);
|
||||
ret = nv50_base_new(drm, head->base.index, &base);
|
||||
ret = nv50_ovly_new(drm, head->base.index, &ovly);
|
||||
} else {
|
||||
ret = nv50_wndw_new(drm, DRM_PLANE_TYPE_OVERLAY,
|
||||
head->base.index * 2 + 1, &wndw);
|
||||
ret = nv50_wndw_new(drm, DRM_PLANE_TYPE_PRIMARY,
|
||||
head->base.index * 2 + 0, &wndw);
|
||||
head->base.index * 2 + 0, &base);
|
||||
ret = nv50_wndw_new(drm, DRM_PLANE_TYPE_OVERLAY,
|
||||
head->base.index * 2 + 1, &ovly);
|
||||
}
|
||||
if (ret == 0)
|
||||
ret = nv50_curs_new(drm, head->base.index, &curs);
|
||||
@@ -508,10 +508,14 @@ nv50_head_create(struct drm_device *dev, int index)
|
||||
}
|
||||
|
||||
crtc = &head->base.base;
|
||||
drm_crtc_init_with_planes(dev, crtc, &wndw->plane, &curs->plane,
|
||||
drm_crtc_init_with_planes(dev, crtc, &base->plane, &curs->plane,
|
||||
&nv50_head_func, "head-%d", head->base.index);
|
||||
drm_crtc_helper_add(crtc, &nv50_head_help);
|
||||
drm_mode_crtc_set_gamma_size(crtc, 256);
|
||||
if (disp->disp->object.oclass >= GF110_DISP)
|
||||
drm_crtc_enable_color_mgmt(crtc, 256, true, 256);
|
||||
else
|
||||
drm_crtc_enable_color_mgmt(crtc, 0, false, 256);
|
||||
|
||||
if (head->func->olut_set) {
|
||||
ret = nv50_lut_init(disp, &drm->client.mmu, &head->olut);
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "atom.h"
|
||||
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
#include <drm/drm_plane_helper.h>
|
||||
|
||||
#include <nvif/cl507e.h>
|
||||
@@ -160,9 +161,7 @@ ovly507e_format[] = {
|
||||
DRM_FORMAT_YUYV,
|
||||
DRM_FORMAT_UYVY,
|
||||
DRM_FORMAT_XRGB8888,
|
||||
DRM_FORMAT_ARGB8888,
|
||||
DRM_FORMAT_XRGB1555,
|
||||
DRM_FORMAT_ARGB1555,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
@@ -90,11 +90,8 @@ ovly827e_format[] = {
|
||||
DRM_FORMAT_YUYV,
|
||||
DRM_FORMAT_UYVY,
|
||||
DRM_FORMAT_XRGB8888,
|
||||
DRM_FORMAT_ARGB8888,
|
||||
DRM_FORMAT_XRGB1555,
|
||||
DRM_FORMAT_ARGB1555,
|
||||
DRM_FORMAT_XBGR2101010,
|
||||
DRM_FORMAT_ABGR2101010,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
@@ -61,10 +61,21 @@ ovly907e = {
|
||||
.update = ovly507e_update,
|
||||
};
|
||||
|
||||
static const u32
|
||||
ovly907e_format[] = {
|
||||
DRM_FORMAT_YUYV,
|
||||
DRM_FORMAT_UYVY,
|
||||
DRM_FORMAT_XRGB8888,
|
||||
DRM_FORMAT_XRGB1555,
|
||||
DRM_FORMAT_XBGR2101010,
|
||||
DRM_FORMAT_XBGR16161616F,
|
||||
0
|
||||
};
|
||||
|
||||
int
|
||||
ovly907e_new(struct nouveau_drm *drm, int head, s32 oclass,
|
||||
struct nv50_wndw **pwndw)
|
||||
{
|
||||
return ovly507e_new_(&ovly907e, ovly827e_format, drm, head, oclass,
|
||||
return ovly507e_new_(&ovly907e, ovly907e_format, drm, head, oclass,
|
||||
0x00000004 << (head * 4), pwndw);
|
||||
}
|
||||
|
||||
@@ -26,13 +26,10 @@ ovly917e_format[] = {
|
||||
DRM_FORMAT_YUYV,
|
||||
DRM_FORMAT_UYVY,
|
||||
DRM_FORMAT_XRGB8888,
|
||||
DRM_FORMAT_ARGB8888,
|
||||
DRM_FORMAT_XRGB1555,
|
||||
DRM_FORMAT_ARGB1555,
|
||||
DRM_FORMAT_XBGR2101010,
|
||||
DRM_FORMAT_ABGR2101010,
|
||||
DRM_FORMAT_XRGB2101010,
|
||||
DRM_FORMAT_ARGB2101010,
|
||||
DRM_FORMAT_XBGR16161616F,
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
#include <nvif/cl0002.h>
|
||||
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
|
||||
#include "nouveau_bo.h"
|
||||
|
||||
static void
|
||||
@@ -118,6 +120,7 @@ nv50_wndw_flush_clr(struct nv50_wndw *wndw, u32 *interlock, bool flush,
|
||||
if (clr.sema ) wndw->func-> sema_clr(wndw);
|
||||
if (clr.ntfy ) wndw->func-> ntfy_clr(wndw);
|
||||
if (clr.xlut ) wndw->func-> xlut_clr(wndw);
|
||||
if (clr.csc ) wndw->func-> csc_clr(wndw);
|
||||
if (clr.image) wndw->func->image_clr(wndw);
|
||||
|
||||
interlock[wndw->interlock.type] |= wndw->interlock.data;
|
||||
@@ -145,7 +148,9 @@ nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 *interlock,
|
||||
wndw->func->xlut_set(wndw, asyw);
|
||||
}
|
||||
|
||||
if (asyw->set.csc ) wndw->func->csc_set (wndw, asyw);
|
||||
if (asyw->set.scale) wndw->func->scale_set(wndw, asyw);
|
||||
if (asyw->set.blend) wndw->func->blend_set(wndw, asyw);
|
||||
if (asyw->set.point) {
|
||||
if (asyw->set.point = false, asyw->set.mask)
|
||||
interlock[wndw->interlock.type] |= wndw->interlock.data;
|
||||
@@ -202,18 +207,20 @@ static int
|
||||
nv50_wndw_atomic_check_acquire_rgb(struct nv50_wndw_atom *asyw)
|
||||
{
|
||||
switch (asyw->state.fb->format->format) {
|
||||
case DRM_FORMAT_C8 : asyw->image.format = 0x1e; break;
|
||||
case DRM_FORMAT_XRGB8888 :
|
||||
case DRM_FORMAT_ARGB8888 : asyw->image.format = 0xcf; break;
|
||||
case DRM_FORMAT_RGB565 : asyw->image.format = 0xe8; break;
|
||||
case DRM_FORMAT_XRGB1555 :
|
||||
case DRM_FORMAT_ARGB1555 : asyw->image.format = 0xe9; break;
|
||||
case DRM_FORMAT_XBGR2101010:
|
||||
case DRM_FORMAT_ABGR2101010: asyw->image.format = 0xd1; break;
|
||||
case DRM_FORMAT_XBGR8888 :
|
||||
case DRM_FORMAT_ABGR8888 : asyw->image.format = 0xd5; break;
|
||||
case DRM_FORMAT_XRGB2101010:
|
||||
case DRM_FORMAT_ARGB2101010: asyw->image.format = 0xdf; break;
|
||||
case DRM_FORMAT_C8 : asyw->image.format = 0x1e; break;
|
||||
case DRM_FORMAT_XRGB8888 :
|
||||
case DRM_FORMAT_ARGB8888 : asyw->image.format = 0xcf; break;
|
||||
case DRM_FORMAT_RGB565 : asyw->image.format = 0xe8; break;
|
||||
case DRM_FORMAT_XRGB1555 :
|
||||
case DRM_FORMAT_ARGB1555 : asyw->image.format = 0xe9; break;
|
||||
case DRM_FORMAT_XBGR2101010 :
|
||||
case DRM_FORMAT_ABGR2101010 : asyw->image.format = 0xd1; break;
|
||||
case DRM_FORMAT_XBGR8888 :
|
||||
case DRM_FORMAT_ABGR8888 : asyw->image.format = 0xd5; break;
|
||||
case DRM_FORMAT_XRGB2101010 :
|
||||
case DRM_FORMAT_ARGB2101010 : asyw->image.format = 0xdf; break;
|
||||
case DRM_FORMAT_XBGR16161616F:
|
||||
case DRM_FORMAT_ABGR16161616F: asyw->image.format = 0xca; break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -279,6 +286,28 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset,
|
||||
asyw->set.scale = true;
|
||||
}
|
||||
|
||||
if (wndw->func->blend_set) {
|
||||
asyw->blend.depth = 255 - asyw->state.normalized_zpos;
|
||||
asyw->blend.k1 = asyw->state.alpha >> 8;
|
||||
switch (asyw->state.pixel_blend_mode) {
|
||||
case DRM_MODE_BLEND_PREMULTI:
|
||||
asyw->blend.src_color = 2; /* K1 */
|
||||
asyw->blend.dst_color = 7; /* NEG_K1_TIMES_SRC */
|
||||
break;
|
||||
case DRM_MODE_BLEND_COVERAGE:
|
||||
asyw->blend.src_color = 5; /* K1_TIMES_SRC */
|
||||
asyw->blend.dst_color = 7; /* NEG_K1_TIMES_SRC */
|
||||
break;
|
||||
case DRM_MODE_BLEND_PIXEL_NONE:
|
||||
default:
|
||||
asyw->blend.src_color = 2; /* K1 */
|
||||
asyw->blend.dst_color = 4; /* NEG_K1 */
|
||||
break;
|
||||
}
|
||||
if (memcmp(&armw->blend, &asyw->blend, sizeof(asyw->blend)))
|
||||
asyw->set.blend = true;
|
||||
}
|
||||
|
||||
if (wndw->immd) {
|
||||
asyw->point.x = asyw->state.crtc_x;
|
||||
asyw->point.y = asyw->state.crtc_y;
|
||||
@@ -320,7 +349,9 @@ nv50_wndw_atomic_check_lut(struct nv50_wndw *wndw,
|
||||
asyh->wndw.olut &= ~BIT(wndw->id);
|
||||
}
|
||||
|
||||
if (!ilut && wndw->func->ilut_identity) {
|
||||
if (!ilut && wndw->func->ilut_identity &&
|
||||
asyw->state.fb->format->format != DRM_FORMAT_XBGR16161616F &&
|
||||
asyw->state.fb->format->format != DRM_FORMAT_ABGR16161616F) {
|
||||
static struct drm_property_blob dummy = {};
|
||||
ilut = &dummy;
|
||||
}
|
||||
@@ -332,6 +363,8 @@ nv50_wndw_atomic_check_lut(struct nv50_wndw *wndw,
|
||||
asyw->xlut.handle = wndw->wndw.vram.handle;
|
||||
asyw->xlut.i.buffer = !asyw->xlut.i.buffer;
|
||||
asyw->set.xlut = true;
|
||||
} else {
|
||||
asyw->clr.xlut = armw->xlut.handle != 0;
|
||||
}
|
||||
|
||||
/* Handle setting base SET_OUTPUT_LUT_LO_ENABLE_USE_CORE_LUT. */
|
||||
@@ -339,6 +372,16 @@ nv50_wndw_atomic_check_lut(struct nv50_wndw *wndw,
|
||||
(!armw->visible || (armw->xlut.handle && !asyw->xlut.handle)))
|
||||
asyw->set.xlut = true;
|
||||
|
||||
if (wndw->func->csc && asyh->state.ctm) {
|
||||
const struct drm_color_ctm *ctm = asyh->state.ctm->data;
|
||||
wndw->func->csc(wndw, asyw, ctm);
|
||||
asyw->csc.valid = true;
|
||||
asyw->set.csc = true;
|
||||
} else {
|
||||
asyw->csc.valid = false;
|
||||
asyw->clr.csc = armw->csc.valid;
|
||||
}
|
||||
|
||||
/* Can't do an immediate flip while changing the LUT. */
|
||||
asyh->state.pageflip_flags &= ~DRM_MODE_PAGE_FLIP_ASYNC;
|
||||
}
|
||||
@@ -408,6 +451,7 @@ nv50_wndw_atomic_check(struct drm_plane *plane, struct drm_plane_state *state)
|
||||
asyw->clr.ntfy = armw->ntfy.handle != 0;
|
||||
asyw->clr.sema = armw->sema.handle != 0;
|
||||
asyw->clr.xlut = armw->xlut.handle != 0;
|
||||
asyw->clr.csc = armw->csc.valid;
|
||||
if (wndw->func->image_clr)
|
||||
asyw->clr.image = armw->image.handle[0] != 0;
|
||||
}
|
||||
@@ -499,6 +543,7 @@ nv50_wndw_atomic_duplicate_state(struct drm_plane *plane)
|
||||
asyw->ntfy = armw->ntfy;
|
||||
asyw->ilut = NULL;
|
||||
asyw->xlut = armw->xlut;
|
||||
asyw->csc = armw->csc;
|
||||
asyw->image = armw->image;
|
||||
asyw->point = armw->point;
|
||||
asyw->clr.mask = 0;
|
||||
@@ -506,6 +551,13 @@ nv50_wndw_atomic_duplicate_state(struct drm_plane *plane)
|
||||
return &asyw->state;
|
||||
}
|
||||
|
||||
static int
|
||||
nv50_wndw_zpos_default(struct drm_plane *plane)
|
||||
{
|
||||
return (plane->type == DRM_PLANE_TYPE_PRIMARY) ? 0 :
|
||||
(plane->type == DRM_PLANE_TYPE_OVERLAY) ? 1 : 255;
|
||||
}
|
||||
|
||||
static void
|
||||
nv50_wndw_reset(struct drm_plane *plane)
|
||||
{
|
||||
@@ -516,9 +568,10 @@ nv50_wndw_reset(struct drm_plane *plane)
|
||||
|
||||
if (plane->state)
|
||||
plane->funcs->atomic_destroy_state(plane, plane->state);
|
||||
plane->state = &asyw->state;
|
||||
plane->state->plane = plane;
|
||||
plane->state->rotation = DRM_MODE_ROTATE_0;
|
||||
|
||||
__drm_atomic_helper_plane_reset(plane, &asyw->state);
|
||||
plane->state->zpos = nv50_wndw_zpos_default(plane);
|
||||
plane->state->normalized_zpos = nv50_wndw_zpos_default(plane);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -613,6 +666,30 @@ nv50_wndw_new_(const struct nv50_wndw_func *func, struct drm_device *dev,
|
||||
}
|
||||
|
||||
wndw->notify.func = nv50_wndw_notify;
|
||||
|
||||
if (wndw->func->blend_set) {
|
||||
ret = drm_plane_create_zpos_property(&wndw->plane,
|
||||
nv50_wndw_zpos_default(&wndw->plane), 0, 254);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = drm_plane_create_alpha_property(&wndw->plane);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = drm_plane_create_blend_mode_property(&wndw->plane,
|
||||
BIT(DRM_MODE_BLEND_PIXEL_NONE) |
|
||||
BIT(DRM_MODE_BLEND_PREMULTI) |
|
||||
BIT(DRM_MODE_BLEND_COVERAGE));
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
ret = drm_plane_create_zpos_immutable_property(&wndw->plane,
|
||||
nv50_wndw_zpos_default(&wndw->plane));
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,6 +65,10 @@ struct nv50_wndw_func {
|
||||
int (*ntfy_wait_begun)(struct nouveau_bo *, u32 offset,
|
||||
struct nvif_device *);
|
||||
void (*ilut)(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||
void (*csc)(struct nv50_wndw *, struct nv50_wndw_atom *,
|
||||
const struct drm_color_ctm *);
|
||||
void (*csc_set)(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||
void (*csc_clr)(struct nv50_wndw *);
|
||||
bool ilut_identity;
|
||||
bool olut_core;
|
||||
void (*xlut_set)(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||
@@ -72,6 +76,7 @@ struct nv50_wndw_func {
|
||||
void (*image_set)(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||
void (*image_clr)(struct nv50_wndw *);
|
||||
void (*scale_set)(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||
void (*blend_set)(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||
|
||||
void (*update)(struct nv50_wndw *, u32 *interlock);
|
||||
};
|
||||
@@ -81,6 +86,9 @@ extern const struct drm_plane_funcs nv50_wndw;
|
||||
void base507c_ntfy_reset(struct nouveau_bo *, u32);
|
||||
int base507c_ntfy_wait_begun(struct nouveau_bo *, u32, struct nvif_device *);
|
||||
|
||||
void base907c_csc(struct nv50_wndw *, struct nv50_wndw_atom *,
|
||||
const struct drm_color_ctm *);
|
||||
|
||||
struct nv50_wimm_func {
|
||||
void (*point)(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||
|
||||
@@ -102,8 +110,8 @@ void wndwc37e_sema_set(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||
void wndwc37e_sema_clr(struct nv50_wndw *);
|
||||
void wndwc37e_ntfy_set(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||
void wndwc37e_ntfy_clr(struct nv50_wndw *);
|
||||
void wndwc37e_image_set(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||
void wndwc37e_image_clr(struct nv50_wndw *);
|
||||
void wndwc37e_blend_set(struct nv50_wndw *, struct nv50_wndw_atom *);
|
||||
void wndwc37e_update(struct nv50_wndw *, u32 *);
|
||||
|
||||
int wndwc57e_new(struct nouveau_drm *, enum drm_plane_type, int, s32,
|
||||
|
||||
@@ -28,6 +28,23 @@
|
||||
|
||||
#include <nvif/clc37e.h>
|
||||
|
||||
static void
|
||||
wndwc37e_csc_clr(struct nv50_wndw *wndw)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
wndwc37e_csc_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
{
|
||||
u32 *push, i;
|
||||
if ((push = evo_wait(&wndw->wndw, 13))) {
|
||||
evo_mthd(push, 0x02bc, 12);
|
||||
for (i = 0; i < 12; i++)
|
||||
evo_data(push, asyw->csc.matrix[i]);
|
||||
evo_kick(push, &wndw->wndw);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wndwc37e_ilut_clr(struct nv50_wndw *wndw)
|
||||
{
|
||||
@@ -64,6 +81,26 @@ wndwc37e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
asyw->xlut.i.load = head907d_olut_load;
|
||||
}
|
||||
|
||||
void
|
||||
wndwc37e_blend_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
{
|
||||
u32 *push;
|
||||
if ((push = evo_wait(&wndw->wndw, 8))) {
|
||||
evo_mthd(push, 0x02ec, 7);
|
||||
evo_data(push, asyw->blend.depth << 4);
|
||||
evo_data(push, asyw->blend.k1);
|
||||
evo_data(push, asyw->blend.dst_color << 12 |
|
||||
asyw->blend.dst_color << 8 |
|
||||
asyw->blend.src_color << 4 |
|
||||
asyw->blend.src_color);
|
||||
evo_data(push, 0xffff0000);
|
||||
evo_data(push, 0xffff0000);
|
||||
evo_data(push, 0xffff0000);
|
||||
evo_data(push, 0xffff0000);
|
||||
evo_kick(push, &wndw->wndw);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
wndwc37e_image_clr(struct nv50_wndw *wndw)
|
||||
{
|
||||
@@ -77,12 +114,12 @@ wndwc37e_image_clr(struct nv50_wndw *wndw)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
wndwc37e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
{
|
||||
u32 *push;
|
||||
|
||||
if (!(push = evo_wait(&wndw->wndw, 25)))
|
||||
if (!(push = evo_wait(&wndw->wndw, 17)))
|
||||
return;
|
||||
|
||||
evo_mthd(push, 0x0308, 1);
|
||||
@@ -90,7 +127,9 @@ wndwc37e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
evo_mthd(push, 0x0224, 4);
|
||||
evo_data(push, asyw->image.h << 16 | asyw->image.w);
|
||||
evo_data(push, asyw->image.layout << 4 | asyw->image.blockh);
|
||||
evo_data(push, asyw->image.colorspace << 8 | asyw->image.format);
|
||||
evo_data(push, asyw->csc.valid << 17 |
|
||||
asyw->image.colorspace << 8 |
|
||||
asyw->image.format);
|
||||
evo_data(push, asyw->image.blocks[0] | (asyw->image.pitch[0] >> 6));
|
||||
evo_mthd(push, 0x0240, 1);
|
||||
evo_data(push, asyw->image.handle[0]);
|
||||
@@ -105,16 +144,6 @@ wndwc37e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
evo_mthd(push, 0x02a4, 1);
|
||||
evo_data(push, asyw->state.crtc_h << 16 |
|
||||
asyw->state.crtc_w);
|
||||
|
||||
/*XXX: Composition-related stuff. Need to implement properly. */
|
||||
evo_mthd(push, 0x02ec, 1);
|
||||
evo_data(push, (2 - (wndw->id & 1)) << 4);
|
||||
evo_mthd(push, 0x02f4, 5);
|
||||
evo_data(push, 0x00000011);
|
||||
evo_data(push, 0xffff0000);
|
||||
evo_data(push, 0xffff0000);
|
||||
evo_data(push, 0xffff0000);
|
||||
evo_data(push, 0xffff0000);
|
||||
evo_kick(push, &wndw->wndw);
|
||||
}
|
||||
|
||||
@@ -216,6 +245,8 @@ wndwc37e_format[] = {
|
||||
DRM_FORMAT_ABGR8888,
|
||||
DRM_FORMAT_XRGB2101010,
|
||||
DRM_FORMAT_ARGB2101010,
|
||||
DRM_FORMAT_XBGR16161616F,
|
||||
DRM_FORMAT_ABGR16161616F,
|
||||
0
|
||||
};
|
||||
|
||||
@@ -232,8 +263,12 @@ wndwc37e = {
|
||||
.ilut = wndwc37e_ilut,
|
||||
.xlut_set = wndwc37e_ilut_set,
|
||||
.xlut_clr = wndwc37e_ilut_clr,
|
||||
.csc = base907c_csc,
|
||||
.csc_set = wndwc37e_csc_set,
|
||||
.csc_clr = wndwc37e_csc_clr,
|
||||
.image_set = wndwc37e_image_set,
|
||||
.image_clr = wndwc37e_image_clr,
|
||||
.blend_set = wndwc37e_blend_set,
|
||||
.update = wndwc37e_update,
|
||||
};
|
||||
|
||||
|
||||
@@ -28,6 +28,72 @@
|
||||
|
||||
#include <nvif/clc37e.h>
|
||||
|
||||
static void
|
||||
wndwc57e_image_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
{
|
||||
u32 *push;
|
||||
|
||||
if (!(push = evo_wait(&wndw->wndw, 17)))
|
||||
return;
|
||||
|
||||
evo_mthd(push, 0x0308, 1);
|
||||
evo_data(push, asyw->image.mode << 4 | asyw->image.interval);
|
||||
evo_mthd(push, 0x0224, 4);
|
||||
evo_data(push, asyw->image.h << 16 | asyw->image.w);
|
||||
evo_data(push, asyw->image.layout << 4 | asyw->image.blockh);
|
||||
evo_data(push, asyw->image.colorspace << 8 |
|
||||
asyw->image.format);
|
||||
evo_data(push, asyw->image.blocks[0] | (asyw->image.pitch[0] >> 6));
|
||||
evo_mthd(push, 0x0240, 1);
|
||||
evo_data(push, asyw->image.handle[0]);
|
||||
evo_mthd(push, 0x0260, 1);
|
||||
evo_data(push, asyw->image.offset[0] >> 8);
|
||||
evo_mthd(push, 0x0290, 1);
|
||||
evo_data(push, (asyw->state.src_y >> 16) << 16 |
|
||||
(asyw->state.src_x >> 16));
|
||||
evo_mthd(push, 0x0298, 1);
|
||||
evo_data(push, (asyw->state.src_h >> 16) << 16 |
|
||||
(asyw->state.src_w >> 16));
|
||||
evo_mthd(push, 0x02a4, 1);
|
||||
evo_data(push, asyw->state.crtc_h << 16 |
|
||||
asyw->state.crtc_w);
|
||||
evo_kick(push, &wndw->wndw);
|
||||
}
|
||||
|
||||
static void
|
||||
wndwc57e_csc_clr(struct nv50_wndw *wndw)
|
||||
{
|
||||
u32 *push;
|
||||
if ((push = evo_wait(&wndw->wndw, 13))) {
|
||||
evo_mthd(push, 0x0400, 12);
|
||||
evo_data(push, 0x00010000);
|
||||
evo_data(push, 0x00000000);
|
||||
evo_data(push, 0x00000000);
|
||||
evo_data(push, 0x00000000);
|
||||
evo_data(push, 0x00000000);
|
||||
evo_data(push, 0x00010000);
|
||||
evo_data(push, 0x00000000);
|
||||
evo_data(push, 0x00000000);
|
||||
evo_data(push, 0x00000000);
|
||||
evo_data(push, 0x00000000);
|
||||
evo_data(push, 0x00010000);
|
||||
evo_data(push, 0x00000000);
|
||||
evo_kick(push, &wndw->wndw);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wndwc57e_csc_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
|
||||
{
|
||||
u32 *push, i;
|
||||
if ((push = evo_wait(&wndw->wndw, 13))) {
|
||||
evo_mthd(push, 0x0400, 12);
|
||||
for (i = 0; i < 12; i++)
|
||||
evo_data(push, asyw->csc.matrix[i]);
|
||||
evo_kick(push, &wndw->wndw);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
wndwc57e_ilut_clr(struct nv50_wndw *wndw)
|
||||
{
|
||||
@@ -119,8 +185,12 @@ wndwc57e = {
|
||||
.ilut_identity = true,
|
||||
.xlut_set = wndwc57e_ilut_set,
|
||||
.xlut_clr = wndwc57e_ilut_clr,
|
||||
.image_set = wndwc37e_image_set,
|
||||
.csc = base907c_csc,
|
||||
.csc_set = wndwc57e_csc_set,
|
||||
.csc_clr = wndwc57e_csc_clr,
|
||||
.image_set = wndwc57e_image_set,
|
||||
.image_clr = wndwc37e_image_clr,
|
||||
.blend_set = wndwc37e_blend_set,
|
||||
.update = wndwc37e_update,
|
||||
};
|
||||
|
||||
|
||||
@@ -26,4 +26,6 @@ nvbios_extdev_parse(struct nvkm_bios *, int, struct nvbios_extdev_func *);
|
||||
int
|
||||
nvbios_extdev_find(struct nvkm_bios *, enum nvbios_extdev_type,
|
||||
struct nvbios_extdev_func *);
|
||||
|
||||
bool nvbios_extdev_skip_probe(struct nvkm_bios *);
|
||||
#endif
|
||||
|
||||
@@ -3,10 +3,13 @@
|
||||
#define __NVBIOS_GPIO_H__
|
||||
enum dcb_gpio_func_name {
|
||||
DCB_GPIO_PANEL_POWER = 0x01,
|
||||
DCB_GPIO_TVDAC0 = 0x0c,
|
||||
DCB_GPIO_TVDAC1 = 0x2d,
|
||||
DCB_GPIO_FAN = 0x09,
|
||||
DCB_GPIO_TVDAC0 = 0x0c,
|
||||
DCB_GPIO_THERM_EXT_POWER_EVENT = 0x10,
|
||||
DCB_GPIO_TVDAC1 = 0x2d,
|
||||
DCB_GPIO_FAN_SENSE = 0x3d,
|
||||
DCB_GPIO_POWER_ALERT = 0x4c,
|
||||
DCB_GPIO_EXT_POWER_LOW = 0x79,
|
||||
DCB_GPIO_LOGO_LED_PWM = 0x84,
|
||||
DCB_GPIO_UNUSED = 0xff,
|
||||
DCB_GPIO_VID0 = 0x04,
|
||||
|
||||
@@ -30,6 +30,7 @@ struct nvkm_pmu {
|
||||
int nvkm_pmu_send(struct nvkm_pmu *, u32 reply[2], u32 process,
|
||||
u32 message, u32 data0, u32 data1);
|
||||
void nvkm_pmu_pgob(struct nvkm_pmu *, bool enable);
|
||||
bool nvkm_pmu_fan_controlled(struct nvkm_device *);
|
||||
|
||||
int gt215_pmu_new(struct nvkm_device *, int, struct nvkm_pmu **);
|
||||
int gf100_pmu_new(struct nvkm_device *, int, struct nvkm_pmu **);
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <drm/drmP.h>
|
||||
|
||||
#include "nouveau_drv.h"
|
||||
#include "nouveau_reg.h"
|
||||
#include "dispnv04/hw.h"
|
||||
@@ -935,7 +933,7 @@ static int parse_bit_tmds_tbl_entry(struct drm_device *dev, struct nvbios *bios,
|
||||
|
||||
tmdstableptr = ROM16(bios->data[bitentry->offset]);
|
||||
if (!tmdstableptr) {
|
||||
NV_ERROR(drm, "Pointer to TMDS table invalid\n");
|
||||
NV_INFO(drm, "Pointer to TMDS table not found\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/vga_switcheroo.h>
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_edid.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#ifndef __NOUVEAU_CRTC_H__
|
||||
#define __NOUVEAU_CRTC_H__
|
||||
|
||||
#include <drm/drm_crtc.h>
|
||||
|
||||
#include <nvif/notify.h>
|
||||
|
||||
struct nouveau_crtc {
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#ifndef __NOUVEAU_DEBUGFS_H__
|
||||
#define __NOUVEAU_DEBUGFS_H__
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_debugfs.h>
|
||||
|
||||
#if defined(CONFIG_DEBUG_FS)
|
||||
|
||||
|
||||
@@ -25,12 +25,14 @@
|
||||
*/
|
||||
|
||||
#include <acpi/video.h>
|
||||
#include <drm/drmP.h>
|
||||
|
||||
#include <drm/drm_atomic.h>
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
#include <drm/drm_vblank.h>
|
||||
|
||||
#include "nouveau_fbcon.h"
|
||||
#include "nouveau_crtc.h"
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
/* SPDX-License-Identifier: MIT */
|
||||
#ifndef __NOUVEAU_DISPLAY_H__
|
||||
#define __NOUVEAU_DISPLAY_H__
|
||||
|
||||
#include "nouveau_drv.h"
|
||||
|
||||
#include <nvif/disp.h>
|
||||
|
||||
#include <drm/drm_framebuffer.h>
|
||||
|
||||
struct nouveau_framebuffer {
|
||||
struct drm_framebuffer base;
|
||||
struct nouveau_bo *nvbo;
|
||||
|
||||
@@ -118,7 +118,7 @@ nv50_dma_push_wait(struct nouveau_channel *chan, int count)
|
||||
}
|
||||
|
||||
if ((++cnt & 0xff) == 0) {
|
||||
DRM_UDELAY(1);
|
||||
udelay(1);
|
||||
if (cnt > 100000)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_dp_helper.h>
|
||||
|
||||
#include "nouveau_drv.h"
|
||||
|
||||
@@ -29,8 +29,9 @@
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/vga_switcheroo.h>
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/drm_ioctl.h>
|
||||
#include <drm/drm_vblank.h>
|
||||
|
||||
#include <core/gpuobj.h>
|
||||
#include <core/option.h>
|
||||
|
||||
@@ -46,7 +46,10 @@
|
||||
#include <nvif/mmu.h>
|
||||
#include <nvif/vmm.h>
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_connector.h>
|
||||
#include <drm/drm_device.h>
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_file.h>
|
||||
|
||||
#include <drm/ttm/ttm_bo_api.h>
|
||||
#include <drm/ttm/ttm_bo_driver.h>
|
||||
@@ -127,7 +130,6 @@ nouveau_cli(struct drm_file *fpriv)
|
||||
}
|
||||
|
||||
#include <nvif/object.h>
|
||||
#include <nvif/device.h>
|
||||
|
||||
struct nouveau_drm {
|
||||
struct nouveau_cli master;
|
||||
@@ -204,9 +206,6 @@ struct nouveau_drm {
|
||||
/* led management */
|
||||
struct nouveau_led *led;
|
||||
|
||||
/* display power reference */
|
||||
bool have_disp_power_ref;
|
||||
|
||||
struct dev_pm_domain vga_pm_domain;
|
||||
|
||||
struct nouveau_svm *svm;
|
||||
|
||||
@@ -37,10 +37,10 @@
|
||||
#include <linux/vga_switcheroo.h>
|
||||
#include <linux/console.h>
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_crtc.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
#include <drm/drm_atomic.h>
|
||||
|
||||
#include "nouveau_drv.h"
|
||||
|
||||
@@ -24,10 +24,9 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <drm/drmP.h>
|
||||
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/sched/signal.h>
|
||||
#include <trace/events/dma_fence.h>
|
||||
|
||||
#include <nvif/cl826e.h>
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
#ifndef __NOUVEAU_GEM_H__
|
||||
#define __NOUVEAU_GEM_H__
|
||||
|
||||
#include <drm/drmP.h>
|
||||
|
||||
#include "nouveau_drv.h"
|
||||
#include "nouveau_bo.h"
|
||||
|
||||
|
||||
@@ -29,8 +29,6 @@
|
||||
#include <linux/hwmon.h>
|
||||
#include <linux/hwmon-sysfs.h>
|
||||
|
||||
#include <drm/drmP.h>
|
||||
|
||||
#include "nouveau_drv.h"
|
||||
#include "nouveau_hwmon.h"
|
||||
|
||||
|
||||
@@ -33,7 +33,8 @@
|
||||
|
||||
#include <linux/compat.h>
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm.h>
|
||||
#include <drm/drm_ioctl.h>
|
||||
|
||||
#include "nouveau_ioctl.h"
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
* Authors: Dave Airlie
|
||||
*/
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <linux/dma-buf.h>
|
||||
|
||||
#include "nouveau_drv.h"
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include <linux/vgaarb.h>
|
||||
#include <linux/vga_switcheroo.h>
|
||||
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/drm_fb_helper.h>
|
||||
|
||||
|
||||
@@ -110,7 +110,7 @@ nvif_mmu_init(struct nvif_object *parent, s32 oclass, struct nvif_mmu *mmu)
|
||||
|
||||
if (mmu->kind_nr) {
|
||||
struct nvif_mmu_kind_v0 *kind;
|
||||
u32 argc = sizeof(*kind) + sizeof(*kind->data) * mmu->kind_nr;
|
||||
size_t argc = struct_size(kind, data, mmu->kind_nr);
|
||||
|
||||
if (ret = -ENOMEM, !(kind = kmalloc(argc, GFP_KERNEL)))
|
||||
goto done;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <core/enum.h>
|
||||
#include <core/gpuobj.h>
|
||||
#include <subdev/bar.h>
|
||||
#include <subdev/fault.h>
|
||||
#include <engine/sw.h>
|
||||
|
||||
#include <nvif/class.h>
|
||||
@@ -193,6 +194,119 @@ gf100_fifo_recover(struct gf100_fifo *fifo, struct nvkm_engine *engine,
|
||||
nvkm_fifo_kevent(&fifo->base, chid);
|
||||
}
|
||||
|
||||
static const struct nvkm_enum
|
||||
gf100_fifo_fault_engine[] = {
|
||||
{ 0x00, "PGRAPH", NULL, NVKM_ENGINE_GR },
|
||||
{ 0x03, "PEEPHOLE", NULL, NVKM_ENGINE_IFB },
|
||||
{ 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR },
|
||||
{ 0x05, "BAR3", NULL, NVKM_SUBDEV_INSTMEM },
|
||||
{ 0x07, "PFIFO", NULL, NVKM_ENGINE_FIFO },
|
||||
{ 0x10, "PMSVLD", NULL, NVKM_ENGINE_MSVLD },
|
||||
{ 0x11, "PMSPPP", NULL, NVKM_ENGINE_MSPPP },
|
||||
{ 0x13, "PCOUNTER" },
|
||||
{ 0x14, "PMSPDEC", NULL, NVKM_ENGINE_MSPDEC },
|
||||
{ 0x15, "PCE0", NULL, NVKM_ENGINE_CE0 },
|
||||
{ 0x16, "PCE1", NULL, NVKM_ENGINE_CE1 },
|
||||
{ 0x17, "PMU" },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct nvkm_enum
|
||||
gf100_fifo_fault_reason[] = {
|
||||
{ 0x00, "PT_NOT_PRESENT" },
|
||||
{ 0x01, "PT_TOO_SHORT" },
|
||||
{ 0x02, "PAGE_NOT_PRESENT" },
|
||||
{ 0x03, "VM_LIMIT_EXCEEDED" },
|
||||
{ 0x04, "NO_CHANNEL" },
|
||||
{ 0x05, "PAGE_SYSTEM_ONLY" },
|
||||
{ 0x06, "PAGE_READ_ONLY" },
|
||||
{ 0x0a, "COMPRESSED_SYSRAM" },
|
||||
{ 0x0c, "INVALID_STORAGE_TYPE" },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct nvkm_enum
|
||||
gf100_fifo_fault_hubclient[] = {
|
||||
{ 0x01, "PCOPY0" },
|
||||
{ 0x02, "PCOPY1" },
|
||||
{ 0x04, "DISPATCH" },
|
||||
{ 0x05, "CTXCTL" },
|
||||
{ 0x06, "PFIFO" },
|
||||
{ 0x07, "BAR_READ" },
|
||||
{ 0x08, "BAR_WRITE" },
|
||||
{ 0x0b, "PVP" },
|
||||
{ 0x0c, "PMSPPP" },
|
||||
{ 0x0d, "PMSVLD" },
|
||||
{ 0x11, "PCOUNTER" },
|
||||
{ 0x12, "PMU" },
|
||||
{ 0x14, "CCACHE" },
|
||||
{ 0x15, "CCACHE_POST" },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct nvkm_enum
|
||||
gf100_fifo_fault_gpcclient[] = {
|
||||
{ 0x01, "TEX" },
|
||||
{ 0x0c, "ESETUP" },
|
||||
{ 0x0e, "CTXCTL" },
|
||||
{ 0x0f, "PROP" },
|
||||
{}
|
||||
};
|
||||
|
||||
static void
|
||||
gf100_fifo_fault(struct nvkm_fifo *base, struct nvkm_fault_data *info)
|
||||
{
|
||||
struct gf100_fifo *fifo = gf100_fifo(base);
|
||||
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
const struct nvkm_enum *er, *eu, *ec;
|
||||
struct nvkm_engine *engine = NULL;
|
||||
struct nvkm_fifo_chan *chan;
|
||||
unsigned long flags;
|
||||
char gpcid[8] = "";
|
||||
|
||||
er = nvkm_enum_find(gf100_fifo_fault_reason, info->reason);
|
||||
eu = nvkm_enum_find(gf100_fifo_fault_engine, info->engine);
|
||||
if (info->hub) {
|
||||
ec = nvkm_enum_find(gf100_fifo_fault_hubclient, info->client);
|
||||
} else {
|
||||
ec = nvkm_enum_find(gf100_fifo_fault_gpcclient, info->client);
|
||||
snprintf(gpcid, sizeof(gpcid), "GPC%d/", info->gpc);
|
||||
}
|
||||
|
||||
if (eu && eu->data2) {
|
||||
switch (eu->data2) {
|
||||
case NVKM_SUBDEV_BAR:
|
||||
nvkm_bar_bar1_reset(device);
|
||||
break;
|
||||
case NVKM_SUBDEV_INSTMEM:
|
||||
nvkm_bar_bar2_reset(device);
|
||||
break;
|
||||
case NVKM_ENGINE_IFB:
|
||||
nvkm_mask(device, 0x001718, 0x00000000, 0x00000000);
|
||||
break;
|
||||
default:
|
||||
engine = nvkm_device_engine(device, eu->data2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
chan = nvkm_fifo_chan_inst(&fifo->base, info->inst, &flags);
|
||||
|
||||
nvkm_error(subdev,
|
||||
"%s fault at %010llx engine %02x [%s] client %02x [%s%s] "
|
||||
"reason %02x [%s] on channel %d [%010llx %s]\n",
|
||||
info->access ? "write" : "read", info->addr,
|
||||
info->engine, eu ? eu->name : "",
|
||||
info->client, gpcid, ec ? ec->name : "",
|
||||
info->reason, er ? er->name : "", chan ? chan->chid : -1,
|
||||
info->inst, chan ? chan->object.client->name : "unknown");
|
||||
|
||||
if (engine && chan)
|
||||
gf100_fifo_recover(fifo, engine, (void *)chan);
|
||||
nvkm_fifo_chan_put(&fifo->base, flags, &chan);
|
||||
}
|
||||
|
||||
static const struct nvkm_enum
|
||||
gf100_fifo_sched_reason[] = {
|
||||
{ 0x0a, "CTXSW_TIMEOUT" },
|
||||
@@ -255,125 +369,28 @@ gf100_fifo_intr_sched(struct gf100_fifo *fifo)
|
||||
}
|
||||
}
|
||||
|
||||
static const struct nvkm_enum
|
||||
gf100_fifo_fault_engine[] = {
|
||||
{ 0x00, "PGRAPH", NULL, NVKM_ENGINE_GR },
|
||||
{ 0x03, "PEEPHOLE", NULL, NVKM_ENGINE_IFB },
|
||||
{ 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR },
|
||||
{ 0x05, "BAR3", NULL, NVKM_SUBDEV_INSTMEM },
|
||||
{ 0x07, "PFIFO", NULL, NVKM_ENGINE_FIFO },
|
||||
{ 0x10, "PMSVLD", NULL, NVKM_ENGINE_MSVLD },
|
||||
{ 0x11, "PMSPPP", NULL, NVKM_ENGINE_MSPPP },
|
||||
{ 0x13, "PCOUNTER" },
|
||||
{ 0x14, "PMSPDEC", NULL, NVKM_ENGINE_MSPDEC },
|
||||
{ 0x15, "PCE0", NULL, NVKM_ENGINE_CE0 },
|
||||
{ 0x16, "PCE1", NULL, NVKM_ENGINE_CE1 },
|
||||
{ 0x17, "PMU" },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct nvkm_enum
|
||||
gf100_fifo_fault_reason[] = {
|
||||
{ 0x00, "PT_NOT_PRESENT" },
|
||||
{ 0x01, "PT_TOO_SHORT" },
|
||||
{ 0x02, "PAGE_NOT_PRESENT" },
|
||||
{ 0x03, "VM_LIMIT_EXCEEDED" },
|
||||
{ 0x04, "NO_CHANNEL" },
|
||||
{ 0x05, "PAGE_SYSTEM_ONLY" },
|
||||
{ 0x06, "PAGE_READ_ONLY" },
|
||||
{ 0x0a, "COMPRESSED_SYSRAM" },
|
||||
{ 0x0c, "INVALID_STORAGE_TYPE" },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct nvkm_enum
|
||||
gf100_fifo_fault_hubclient[] = {
|
||||
{ 0x01, "PCOPY0" },
|
||||
{ 0x02, "PCOPY1" },
|
||||
{ 0x04, "DISPATCH" },
|
||||
{ 0x05, "CTXCTL" },
|
||||
{ 0x06, "PFIFO" },
|
||||
{ 0x07, "BAR_READ" },
|
||||
{ 0x08, "BAR_WRITE" },
|
||||
{ 0x0b, "PVP" },
|
||||
{ 0x0c, "PMSPPP" },
|
||||
{ 0x0d, "PMSVLD" },
|
||||
{ 0x11, "PCOUNTER" },
|
||||
{ 0x12, "PMU" },
|
||||
{ 0x14, "CCACHE" },
|
||||
{ 0x15, "CCACHE_POST" },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct nvkm_enum
|
||||
gf100_fifo_fault_gpcclient[] = {
|
||||
{ 0x01, "TEX" },
|
||||
{ 0x0c, "ESETUP" },
|
||||
{ 0x0e, "CTXCTL" },
|
||||
{ 0x0f, "PROP" },
|
||||
{}
|
||||
};
|
||||
|
||||
static void
|
||||
gf100_fifo_intr_fault(struct gf100_fifo *fifo, int unit)
|
||||
void
|
||||
gf100_fifo_intr_fault(struct nvkm_fifo *fifo, int unit)
|
||||
{
|
||||
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
struct nvkm_device *device = fifo->engine.subdev.device;
|
||||
u32 inst = nvkm_rd32(device, 0x002800 + (unit * 0x10));
|
||||
u32 valo = nvkm_rd32(device, 0x002804 + (unit * 0x10));
|
||||
u32 vahi = nvkm_rd32(device, 0x002808 + (unit * 0x10));
|
||||
u32 stat = nvkm_rd32(device, 0x00280c + (unit * 0x10));
|
||||
u32 gpc = (stat & 0x1f000000) >> 24;
|
||||
u32 client = (stat & 0x00001f00) >> 8;
|
||||
u32 write = (stat & 0x00000080);
|
||||
u32 hub = (stat & 0x00000040);
|
||||
u32 reason = (stat & 0x0000000f);
|
||||
const struct nvkm_enum *er, *eu, *ec;
|
||||
struct nvkm_engine *engine = NULL;
|
||||
struct nvkm_fifo_chan *chan;
|
||||
unsigned long flags;
|
||||
char gpcid[8] = "";
|
||||
u32 type = nvkm_rd32(device, 0x00280c + (unit * 0x10));
|
||||
struct nvkm_fault_data info;
|
||||
|
||||
er = nvkm_enum_find(gf100_fifo_fault_reason, reason);
|
||||
eu = nvkm_enum_find(gf100_fifo_fault_engine, unit);
|
||||
if (hub) {
|
||||
ec = nvkm_enum_find(gf100_fifo_fault_hubclient, client);
|
||||
} else {
|
||||
ec = nvkm_enum_find(gf100_fifo_fault_gpcclient, client);
|
||||
snprintf(gpcid, sizeof(gpcid), "GPC%d/", gpc);
|
||||
}
|
||||
info.inst = (u64)inst << 12;
|
||||
info.addr = ((u64)vahi << 32) | valo;
|
||||
info.time = 0;
|
||||
info.engine = unit;
|
||||
info.valid = 1;
|
||||
info.gpc = (type & 0x1f000000) >> 24;
|
||||
info.client = (type & 0x00001f00) >> 8;
|
||||
info.access = (type & 0x00000080) >> 7;
|
||||
info.hub = (type & 0x00000040) >> 6;
|
||||
info.reason = (type & 0x0000000f);
|
||||
|
||||
if (eu && eu->data2) {
|
||||
switch (eu->data2) {
|
||||
case NVKM_SUBDEV_BAR:
|
||||
nvkm_bar_bar1_reset(device);
|
||||
break;
|
||||
case NVKM_SUBDEV_INSTMEM:
|
||||
nvkm_bar_bar2_reset(device);
|
||||
break;
|
||||
case NVKM_ENGINE_IFB:
|
||||
nvkm_mask(device, 0x001718, 0x00000000, 0x00000000);
|
||||
break;
|
||||
default:
|
||||
engine = nvkm_device_engine(device, eu->data2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
chan = nvkm_fifo_chan_inst(&fifo->base, (u64)inst << 12, &flags);
|
||||
|
||||
nvkm_error(subdev,
|
||||
"%s fault at %010llx engine %02x [%s] client %02x [%s%s] "
|
||||
"reason %02x [%s] on channel %d [%010llx %s]\n",
|
||||
write ? "write" : "read", (u64)vahi << 32 | valo,
|
||||
unit, eu ? eu->name : "", client, gpcid, ec ? ec->name : "",
|
||||
reason, er ? er->name : "", chan ? chan->chid : -1,
|
||||
(u64)inst << 12,
|
||||
chan ? chan->object.client->name : "unknown");
|
||||
|
||||
if (engine && chan)
|
||||
gf100_fifo_recover(fifo, engine, (void *)chan);
|
||||
nvkm_fifo_chan_put(&fifo->base, flags, &chan);
|
||||
nvkm_fifo_fault(fifo, &info);
|
||||
}
|
||||
|
||||
static const struct nvkm_bitfield
|
||||
@@ -518,7 +535,7 @@ gf100_fifo_intr(struct nvkm_fifo *base)
|
||||
u32 mask = nvkm_rd32(device, 0x00259c);
|
||||
while (mask) {
|
||||
u32 unit = __ffs(mask);
|
||||
gf100_fifo_intr_fault(fifo, unit);
|
||||
gf100_fifo_intr_fault(&fifo->base, unit);
|
||||
nvkm_wr32(device, 0x00259c, (1 << unit));
|
||||
mask &= ~(1 << unit);
|
||||
}
|
||||
@@ -655,6 +672,7 @@ gf100_fifo = {
|
||||
.init = gf100_fifo_init,
|
||||
.fini = gf100_fifo_fini,
|
||||
.intr = gf100_fifo_intr,
|
||||
.fault = gf100_fifo_fault,
|
||||
.uevent_init = gf100_fifo_uevent_init,
|
||||
.uevent_fini = gf100_fifo_uevent_fini,
|
||||
.chan = {
|
||||
|
||||
@@ -646,31 +646,6 @@ gk104_fifo_intr_dropped_fault(struct gk104_fifo *fifo)
|
||||
nvkm_error(subdev, "DROPPED_MMU_FAULT %08x\n", stat);
|
||||
}
|
||||
|
||||
static void
|
||||
gk104_fifo_intr_fault(struct gk104_fifo *fifo, int unit)
|
||||
{
|
||||
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
|
||||
struct nvkm_device *device = subdev->device;
|
||||
u32 inst = nvkm_rd32(device, 0x002800 + (unit * 0x10));
|
||||
u32 valo = nvkm_rd32(device, 0x002804 + (unit * 0x10));
|
||||
u32 vahi = nvkm_rd32(device, 0x002808 + (unit * 0x10));
|
||||
u32 type = nvkm_rd32(device, 0x00280c + (unit * 0x10));
|
||||
struct nvkm_fault_data info;
|
||||
|
||||
info.inst = (u64)inst << 12;
|
||||
info.addr = ((u64)vahi << 32) | valo;
|
||||
info.time = 0;
|
||||
info.engine = unit;
|
||||
info.valid = 1;
|
||||
info.gpc = (type & 0x1f000000) >> 24;
|
||||
info.client = (type & 0x00001f00) >> 8;
|
||||
info.access = (type & 0x00000080) >> 7;
|
||||
info.hub = (type & 0x00000040) >> 6;
|
||||
info.reason = (type & 0x000000ff);
|
||||
|
||||
nvkm_fifo_fault(&fifo->base, &info);
|
||||
}
|
||||
|
||||
static const struct nvkm_bitfield gk104_fifo_pbdma_intr_0[] = {
|
||||
{ 0x00000001, "MEMREQ" },
|
||||
{ 0x00000002, "MEMACK_TIMEOUT" },
|
||||
@@ -849,7 +824,7 @@ gk104_fifo_intr(struct nvkm_fifo *base)
|
||||
u32 mask = nvkm_rd32(device, 0x00259c);
|
||||
while (mask) {
|
||||
u32 unit = __ffs(mask);
|
||||
gk104_fifo_intr_fault(fifo, unit);
|
||||
fifo->func->intr.fault(&fifo->base, unit);
|
||||
nvkm_wr32(device, 0x00259c, (1 << unit));
|
||||
mask &= ~(1 << unit);
|
||||
}
|
||||
@@ -1204,6 +1179,7 @@ gk104_fifo_fault_gpcclient[] = {
|
||||
|
||||
static const struct gk104_fifo_func
|
||||
gk104_fifo = {
|
||||
.intr.fault = gf100_fifo_intr_fault,
|
||||
.pbdma = &gk104_fifo_pbdma,
|
||||
.fault.access = gk104_fifo_fault_access,
|
||||
.fault.engine = gk104_fifo_fault_engine,
|
||||
|
||||
@@ -45,6 +45,10 @@ struct gk104_fifo {
|
||||
};
|
||||
|
||||
struct gk104_fifo_func {
|
||||
struct {
|
||||
void (*fault)(struct nvkm_fifo *, int unit);
|
||||
} intr;
|
||||
|
||||
const struct gk104_fifo_pbdma_func {
|
||||
int (*nr)(struct gk104_fifo *);
|
||||
void (*init)(struct gk104_fifo *);
|
||||
@@ -110,12 +114,14 @@ void gk110_fifo_runlist_cgrp(struct nvkm_fifo_cgrp *,
|
||||
extern const struct gk104_fifo_pbdma_func gk208_fifo_pbdma;
|
||||
void gk208_fifo_pbdma_init_timeout(struct gk104_fifo *);
|
||||
|
||||
void gm107_fifo_intr_fault(struct nvkm_fifo *, int);
|
||||
extern const struct nvkm_enum gm107_fifo_fault_engine[];
|
||||
extern const struct gk104_fifo_runlist_func gm107_fifo_runlist;
|
||||
|
||||
extern const struct gk104_fifo_pbdma_func gm200_fifo_pbdma;
|
||||
int gm200_fifo_pbdma_nr(struct gk104_fifo *);
|
||||
|
||||
void gp100_fifo_intr_fault(struct nvkm_fifo *, int);
|
||||
extern const struct nvkm_enum gp100_fifo_fault_engine[];
|
||||
|
||||
extern const struct nvkm_enum gv100_fifo_fault_access[];
|
||||
|
||||
@@ -48,6 +48,7 @@ gk110_fifo_runlist = {
|
||||
|
||||
static const struct gk104_fifo_func
|
||||
gk110_fifo = {
|
||||
.intr.fault = gf100_fifo_intr_fault,
|
||||
.pbdma = &gk104_fifo_pbdma,
|
||||
.fault.access = gk104_fifo_fault_access,
|
||||
.fault.engine = gk104_fifo_fault_engine,
|
||||
|
||||
@@ -45,6 +45,7 @@ gk208_fifo_pbdma = {
|
||||
|
||||
static const struct gk104_fifo_func
|
||||
gk208_fifo = {
|
||||
.intr.fault = gf100_fifo_intr_fault,
|
||||
.pbdma = &gk208_fifo_pbdma,
|
||||
.fault.access = gk104_fifo_fault_access,
|
||||
.fault.engine = gk104_fifo_fault_engine,
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
static const struct gk104_fifo_func
|
||||
gk20a_fifo = {
|
||||
.intr.fault = gf100_fifo_intr_fault,
|
||||
.pbdma = &gk208_fifo_pbdma,
|
||||
.fault.access = gk104_fifo_fault_access,
|
||||
.fault.engine = gk104_fifo_fault_engine,
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#include "changk104.h"
|
||||
|
||||
#include <core/gpuobj.h>
|
||||
#include <subdev/fault.h>
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
@@ -67,8 +68,33 @@ gm107_fifo_fault_engine[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
void
|
||||
gm107_fifo_intr_fault(struct nvkm_fifo *fifo, int unit)
|
||||
{
|
||||
struct nvkm_device *device = fifo->engine.subdev.device;
|
||||
u32 inst = nvkm_rd32(device, 0x002800 + (unit * 0x10));
|
||||
u32 valo = nvkm_rd32(device, 0x002804 + (unit * 0x10));
|
||||
u32 vahi = nvkm_rd32(device, 0x002808 + (unit * 0x10));
|
||||
u32 type = nvkm_rd32(device, 0x00280c + (unit * 0x10));
|
||||
struct nvkm_fault_data info;
|
||||
|
||||
info.inst = (u64)inst << 12;
|
||||
info.addr = ((u64)vahi << 32) | valo;
|
||||
info.time = 0;
|
||||
info.engine = unit;
|
||||
info.valid = 1;
|
||||
info.gpc = (type & 0x1f000000) >> 24;
|
||||
info.client = (type & 0x00003f00) >> 8;
|
||||
info.access = (type & 0x00000080) >> 7;
|
||||
info.hub = (type & 0x00000040) >> 6;
|
||||
info.reason = (type & 0x0000000f);
|
||||
|
||||
nvkm_fifo_fault(fifo, &info);
|
||||
}
|
||||
|
||||
static const struct gk104_fifo_func
|
||||
gm107_fifo = {
|
||||
.intr.fault = gm107_fifo_intr_fault,
|
||||
.pbdma = &gk208_fifo_pbdma,
|
||||
.fault.access = gk104_fifo_fault_access,
|
||||
.fault.engine = gm107_fifo_fault_engine,
|
||||
|
||||
@@ -42,6 +42,7 @@ gm200_fifo_pbdma = {
|
||||
|
||||
static const struct gk104_fifo_func
|
||||
gm200_fifo = {
|
||||
.intr.fault = gm107_fifo_intr_fault,
|
||||
.pbdma = &gm200_fifo_pbdma,
|
||||
.fault.access = gk104_fifo_fault_access,
|
||||
.fault.engine = gm107_fifo_fault_engine,
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
static const struct gk104_fifo_func
|
||||
gm20b_fifo = {
|
||||
.intr.fault = gm107_fifo_intr_fault,
|
||||
.pbdma = &gm200_fifo_pbdma,
|
||||
.fault.access = gk104_fifo_fault_access,
|
||||
.fault.engine = gm107_fifo_fault_engine,
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
#include "gk104.h"
|
||||
#include "changk104.h"
|
||||
|
||||
#include <subdev/fault.h>
|
||||
|
||||
#include <nvif/class.h>
|
||||
|
||||
const struct nvkm_enum
|
||||
@@ -50,8 +52,33 @@ gp100_fifo_fault_engine[] = {
|
||||
{}
|
||||
};
|
||||
|
||||
void
|
||||
gp100_fifo_intr_fault(struct nvkm_fifo *fifo, int unit)
|
||||
{
|
||||
struct nvkm_device *device = fifo->engine.subdev.device;
|
||||
u32 inst = nvkm_rd32(device, 0x002800 + (unit * 0x10));
|
||||
u32 valo = nvkm_rd32(device, 0x002804 + (unit * 0x10));
|
||||
u32 vahi = nvkm_rd32(device, 0x002808 + (unit * 0x10));
|
||||
u32 type = nvkm_rd32(device, 0x00280c + (unit * 0x10));
|
||||
struct nvkm_fault_data info;
|
||||
|
||||
info.inst = (u64)inst << 12;
|
||||
info.addr = ((u64)vahi << 32) | valo;
|
||||
info.time = 0;
|
||||
info.engine = unit;
|
||||
info.valid = 1;
|
||||
info.gpc = (type & 0x1f000000) >> 24;
|
||||
info.hub = (type & 0x00100000) >> 20;
|
||||
info.access = (type & 0x00070000) >> 16;
|
||||
info.client = (type & 0x00007f00) >> 8;
|
||||
info.reason = (type & 0x0000001f);
|
||||
|
||||
nvkm_fifo_fault(fifo, &info);
|
||||
}
|
||||
|
||||
static const struct gk104_fifo_func
|
||||
gp100_fifo = {
|
||||
.intr.fault = gp100_fifo_intr_fault,
|
||||
.pbdma = &gm200_fifo_pbdma,
|
||||
.fault.access = gk104_fifo_fault_access,
|
||||
.fault.engine = gp100_fifo_fault_engine,
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
static const struct gk104_fifo_func
|
||||
gp10b_fifo = {
|
||||
.intr.fault = gp100_fifo_intr_fault,
|
||||
.pbdma = &gm200_fifo_pbdma,
|
||||
.fault.access = gk104_fifo_fault_access,
|
||||
.fault.engine = gp100_fifo_fault_engine,
|
||||
|
||||
@@ -37,4 +37,6 @@ struct nvkm_fifo_func {
|
||||
void nv04_fifo_intr(struct nvkm_fifo *);
|
||||
void nv04_fifo_pause(struct nvkm_fifo *, unsigned long *);
|
||||
void nv04_fifo_start(struct nvkm_fifo *, unsigned long *);
|
||||
|
||||
void gf100_fifo_intr_fault(struct nvkm_fifo *, int);
|
||||
#endif
|
||||
|
||||
@@ -46,6 +46,19 @@ extdev_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *len, u8 *cnt)
|
||||
return extdev + *hdr;
|
||||
}
|
||||
|
||||
bool
|
||||
nvbios_extdev_skip_probe(struct nvkm_bios *bios)
|
||||
{
|
||||
u8 ver, hdr, len, cnt;
|
||||
u16 data = extdev_table(bios, &ver, &hdr, &len, &cnt);
|
||||
if (data && ver == 0x40 && hdr >= 5) {
|
||||
u8 flags = nvbios_rd08(bios, data - hdr + 4);
|
||||
if (flags & 1)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static u16
|
||||
nvbios_extdev_entry(struct nvkm_bios *bios, int idx, u8 *ver, u8 *len)
|
||||
{
|
||||
|
||||
@@ -834,7 +834,7 @@ init_generic_condition(struct nvbios_init *init)
|
||||
init_exec_set(init, false);
|
||||
break;
|
||||
default:
|
||||
warn("INIT_GENERIC_CONDITON: unknown 0x%02x\n", cond);
|
||||
warn("INIT_GENERIC_CONDITION: unknown 0x%02x\n", cond);
|
||||
init->offset += size;
|
||||
break;
|
||||
}
|
||||
@@ -1934,6 +1934,28 @@ init_ram_restrict_pll(struct nvbios_init *init)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* INIT_RESET_BEGUN - opcode 0x8c
|
||||
*
|
||||
*/
|
||||
static void
|
||||
init_reset_begun(struct nvbios_init *init)
|
||||
{
|
||||
trace("RESET_BEGUN\n");
|
||||
init->offset += 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* INIT_RESET_END - opcode 0x8d
|
||||
*
|
||||
*/
|
||||
static void
|
||||
init_reset_end(struct nvbios_init *init)
|
||||
{
|
||||
trace("RESET_END\n");
|
||||
init->offset += 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* INIT_GPIO - opcode 0x8e
|
||||
*
|
||||
@@ -2260,8 +2282,8 @@ static struct nvbios_init_opcode {
|
||||
[0x79] = { init_pll },
|
||||
[0x7a] = { init_zm_reg },
|
||||
[0x87] = { init_ram_restrict_pll },
|
||||
[0x8c] = { init_reserved },
|
||||
[0x8d] = { init_reserved },
|
||||
[0x8c] = { init_reset_begun },
|
||||
[0x8d] = { init_reset_end },
|
||||
[0x8e] = { init_gpio },
|
||||
[0x8f] = { init_ram_restrict_zm_reg_group },
|
||||
[0x90] = { init_copy_zm_reg },
|
||||
|
||||
@@ -96,6 +96,8 @@ nvbios_volt_parse(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
|
||||
info->min = min(info->base,
|
||||
info->base + info->step * info->vidmask);
|
||||
info->max = nvbios_rd32(bios, volt + 0x0e);
|
||||
if (!info->max)
|
||||
info->max = max(info->base, info->base + info->step * info->vidmask);
|
||||
break;
|
||||
case 0x50:
|
||||
info->min = nvbios_rd32(bios, volt + 0x0a);
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
*/
|
||||
#include "priv.h"
|
||||
|
||||
#include <core/option.h>
|
||||
#include <core/notify.h>
|
||||
|
||||
static int
|
||||
@@ -182,12 +183,43 @@ static const struct dmi_system_id gpio_reset_ids[] = {
|
||||
{ }
|
||||
};
|
||||
|
||||
static enum dcb_gpio_func_name power_checks[] = {
|
||||
DCB_GPIO_THERM_EXT_POWER_EVENT,
|
||||
DCB_GPIO_POWER_ALERT,
|
||||
DCB_GPIO_EXT_POWER_LOW,
|
||||
};
|
||||
|
||||
static int
|
||||
nvkm_gpio_init(struct nvkm_subdev *subdev)
|
||||
{
|
||||
struct nvkm_gpio *gpio = nvkm_gpio(subdev);
|
||||
struct dcb_gpio_func func;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
if (dmi_check_system(gpio_reset_ids))
|
||||
nvkm_gpio_reset(gpio, DCB_GPIO_UNUSED);
|
||||
|
||||
if (nvkm_boolopt(subdev->device->cfgopt, "NvPowerChecks", true)) {
|
||||
for (i = 0; i < ARRAY_SIZE(power_checks); ++i) {
|
||||
ret = nvkm_gpio_find(gpio, 0, power_checks[i],
|
||||
DCB_GPIO_UNUSED, &func);
|
||||
if (ret)
|
||||
continue;
|
||||
|
||||
ret = nvkm_gpio_get(gpio, 0, func.func, func.line);
|
||||
if (!ret)
|
||||
continue;
|
||||
|
||||
nvkm_error(&gpio->subdev,
|
||||
"GPU is missing power, check its power "
|
||||
"cables. Boot with "
|
||||
"nouveau.config=NvPowerChecks=0 to "
|
||||
"disable.\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -26,6 +26,24 @@
|
||||
#include <core/msgqueue.h>
|
||||
#include <subdev/timer.h>
|
||||
|
||||
bool
|
||||
nvkm_pmu_fan_controlled(struct nvkm_device *device)
|
||||
{
|
||||
struct nvkm_pmu *pmu = device->pmu;
|
||||
|
||||
/* Internal PMU FW does not currently control fans in any way,
|
||||
* allow SW control of fans instead.
|
||||
*/
|
||||
if (pmu && pmu->func->code.size)
|
||||
return false;
|
||||
|
||||
/* Default (board-loaded, or VBIOS PMU/PREOS) PMU FW on Fermi
|
||||
* and newer automatically control the fan speed, which would
|
||||
* interfere with SW control.
|
||||
*/
|
||||
return (device->chipset >= 0xc0);
|
||||
}
|
||||
|
||||
void
|
||||
nvkm_pmu_pgob(struct nvkm_pmu *pmu, bool enable)
|
||||
{
|
||||
|
||||
@@ -1088,7 +1088,7 @@ acr_r352_ls_gpccs_func_0 = {
|
||||
.lhdr_flags = LSF_FLAG_FORCE_PRIV_LOAD,
|
||||
};
|
||||
|
||||
const struct acr_r352_ls_func
|
||||
static const struct acr_r352_ls_func
|
||||
acr_r352_ls_gpccs_func = {
|
||||
.load = acr_ls_ucode_load_gpccs,
|
||||
.version_max = 0,
|
||||
|
||||
@@ -21,9 +21,11 @@
|
||||
*
|
||||
* Authors: Martin Peres
|
||||
*/
|
||||
#include <nvkm/core/option.h>
|
||||
#include "priv.h"
|
||||
|
||||
#include <core/option.h>
|
||||
#include <subdev/pmu.h>
|
||||
|
||||
int
|
||||
nvkm_therm_temp_get(struct nvkm_therm *therm)
|
||||
{
|
||||
@@ -192,8 +194,7 @@ nvkm_therm_fan_mode(struct nvkm_therm *therm, int mode)
|
||||
|
||||
/* The default PPWR ucode on fermi interferes with fan management */
|
||||
if ((mode >= ARRAY_SIZE(name)) ||
|
||||
(mode != NVKM_THERM_CTRL_NONE && device->card_type >= NV_C0 &&
|
||||
!device->pmu))
|
||||
(mode != NVKM_THERM_CTRL_NONE && nvkm_pmu_fan_controlled(device)))
|
||||
return -EINVAL;
|
||||
|
||||
/* do not allow automatic fan management if the thermal sensor is
|
||||
|
||||
@@ -116,6 +116,9 @@ nvkm_therm_ic_ctor(struct nvkm_therm *therm)
|
||||
return;
|
||||
}
|
||||
|
||||
if (nvbios_extdev_skip_probe(bios))
|
||||
return;
|
||||
|
||||
/* The vbios doesn't provide the address of an exisiting monitoring
|
||||
device. Let's try our static list.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user