Commit afdd548f authored by Dave Airlie's avatar Dave Airlie

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

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

* 'linux-4.10' of git://github.com/skeggsb/linux: (64 commits)
  drm/nouveau/fifo/gf100-: protect channel preempt with subdev mutex
  drm/nouveau/gr: fallback to legacy paths during firmware lookup
  drm/nouveau/kms/nv50: initial support for DP 1.2 multi-stream
  drm/nouveau/kms/nv50: allow encoder update to be called from other modules
  drm/nouveau/kms/nv50: rename remaining nv50_crtc to nv50_head
  drm/nouveau/kms/nv50: remove code to create ctxdma for every framebuffer
  drm/nouveau/kms/nv50: remove code to support non-atomic page flips
  drm/nouveau/kms/nv50: remove code to support non-atomic connector properties
  drm/nouveau/kms/nv50: remove code to support non-atomic dpms
  drm/nouveau/kms/nv50: remove code to support non-atomic modesets
  drm/nouveau/kms/nv50: transition to atomic interfaces internally
  drm/nouveau/kms/nv50: turn mode_set_base_atomic() into a stub
  drm/nouveau/kms/nv50: convert encoder mode_fixup into an atomic_check()
  drm/nouveau/kms/nv50: clean-up encoder functions
  drm/nouveau/kms/nv50: ensure encoder normal power state is enabled at startup
  drm/nouveau/kms/nv50: prepare ctxdma interface to be usable with atomic
  drm/nouveau/kms/nv50: separate out cursor channel commit
  drm/nouveau/kms/nv50: separate out base channel commit
  drm/nouveau/kms/nv50: separate out vblank dmi commit
  drm/nouveau/kms/nv50: separate out procamp commit
  ...
parents 7b624ad8 b27add13
......@@ -33,7 +33,7 @@
#include "nouveau_connector.h"
#include "nouveau_display.h"
#include "nvreg.h"
#include "disp.h"
struct nouveau_plane {
struct drm_plane base;
......
......@@ -34,6 +34,8 @@ struct nv50_disp_mthd_v1 {
#define NV50_DISP_MTHD_V1_SOR_HDMI_PWR 0x22
#define NV50_DISP_MTHD_V1_SOR_LVDS_SCRIPT 0x23
#define NV50_DISP_MTHD_V1_SOR_DP_PWR 0x24
#define NV50_DISP_MTHD_V1_SOR_DP_MST_LINK 0x25
#define NV50_DISP_MTHD_V1_SOR_DP_MST_VCPI 0x26
#define NV50_DISP_MTHD_V1_PIOR_PWR 0x30
__u8 method;
__u16 hasht;
......@@ -90,6 +92,21 @@ struct nv50_disp_sor_dp_pwr_v0 {
__u8 pad02[6];
};
struct nv50_disp_sor_dp_mst_link_v0 {
__u8 version;
__u8 state;
__u8 pad02[6];
};
struct nv50_disp_sor_dp_mst_vcpi_v0 {
__u8 version;
__u8 pad01[1];
__u8 start_slot;
__u8 num_slots;
__u16 pbn;
__u16 aligned_pbn;
};
struct nv50_disp_pior_pwr_v0 {
__u8 version;
__u8 state;
......
......@@ -66,6 +66,35 @@ void nvif_object_unmap(struct nvif_object *);
#define nvif_mthd(a,b,c,d) nvif_object_mthd((a), (b), (c), (d))
struct nvif_mclass {
s32 oclass;
int version;
};
#define nvif_mclass(o,m) ({ \
struct nvif_object *object = (o); \
struct nvif_sclass *sclass; \
const typeof(m[0]) *mclass = (m); \
int ret = -ENODEV; \
int cnt, i, j; \
\
cnt = nvif_object_sclass_get(object, &sclass); \
if (cnt >= 0) { \
for (i = 0; ret < 0 && mclass[i].oclass; i++) { \
for (j = 0; j < cnt; j++) { \
if (mclass[i].oclass == sclass[j].oclass && \
mclass[i].version >= sclass[j].minver && \
mclass[i].version <= sclass[j].maxver) { \
ret = i; \
break; \
} \
} \
} \
nvif_object_sclass_put(&sclass); \
} \
ret; \
})
/*XXX*/
#include <core/object.h>
#define nvxx_object(a) ({ \
......
......@@ -93,6 +93,7 @@ int gk104_fb_new(struct nvkm_device *, int, struct nvkm_fb **);
int gk20a_fb_new(struct nvkm_device *, int, struct nvkm_fb **);
int gm107_fb_new(struct nvkm_device *, int, struct nvkm_fb **);
int gm200_fb_new(struct nvkm_device *, int, struct nvkm_fb **);
int gm20b_fb_new(struct nvkm_device *, int, struct nvkm_fb **);
int gp100_fb_new(struct nvkm_device *, int, struct nvkm_fb **);
int gp104_fb_new(struct nvkm_device *, int, struct nvkm_fb **);
......@@ -156,4 +157,6 @@ struct nvkm_ram_func {
int (*prog)(struct nvkm_ram *);
void (*tidy)(struct nvkm_ram *);
};
extern const u8 gf100_pte_storage_type_map[256];
#endif
......@@ -333,6 +333,9 @@ get_fp_strap(struct drm_device *dev, struct nvbios *bios)
if (bios->major_version < 5 && bios->data[0x48] & 0x4)
return NVReadVgaCrtc5758(dev, 0, 0xf) & 0xf;
if (drm->device.info.family >= NV_DEVICE_INFO_V0_MAXWELL)
return nvif_rd32(device, 0x001800) & 0x0000000f;
else
if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA)
return (nvif_rd32(device, NV_PEXTDEV_BOOT_0) >> 24) & 0xf;
else
......
This diff is collapsed.
......@@ -35,30 +35,6 @@
struct nvkm_i2c_port;
enum nouveau_underscan_type {
UNDERSCAN_OFF,
UNDERSCAN_ON,
UNDERSCAN_AUTO,
};
/* the enum values specifically defined here match nv50/nvd0 hw values, and
* the code relies on this
*/
enum nouveau_dithering_mode {
DITHERING_MODE_OFF = 0x00,
DITHERING_MODE_ON = 0x01,
DITHERING_MODE_DYNAMIC2X2 = 0x10 | DITHERING_MODE_ON,
DITHERING_MODE_STATIC2X2 = 0x18 | DITHERING_MODE_ON,
DITHERING_MODE_TEMPORAL = 0x20 | DITHERING_MODE_ON,
DITHERING_MODE_AUTO
};
enum nouveau_dithering_depth {
DITHERING_DEPTH_6BPC = 0x00,
DITHERING_DEPTH_8BPC = 0x02,
DITHERING_DEPTH_AUTO
};
struct nouveau_connector {
struct drm_connector base;
enum dcb_connector_type type;
......@@ -70,12 +46,7 @@ struct nouveau_connector {
struct drm_dp_aux aux;
int dithering_mode;
int dithering_depth;
int scaling_mode;
bool scaling_full;
enum nouveau_underscan_type underscan;
u32 underscan_hborder;
u32 underscan_vborder;
struct nouveau_encoder *detected_encoder;
struct edid *edid;
......@@ -109,5 +80,74 @@ nouveau_connector_create(struct drm_device *, int index);
extern int nouveau_tv_disable;
extern int nouveau_ignorelid;
extern int nouveau_duallink;
extern int nouveau_hdmimhz;
#include <drm/drm_crtc.h>
#define nouveau_conn_atom(p) \
container_of((p), struct nouveau_conn_atom, state)
struct nouveau_conn_atom {
struct drm_connector_state state;
struct {
/* The enum values specifically defined here match nv50/gf119
* hw values, and the code relies on this.
*/
enum {
DITHERING_MODE_OFF = 0x00,
DITHERING_MODE_ON = 0x01,
DITHERING_MODE_DYNAMIC2X2 = 0x10 | DITHERING_MODE_ON,
DITHERING_MODE_STATIC2X2 = 0x18 | DITHERING_MODE_ON,
DITHERING_MODE_TEMPORAL = 0x20 | DITHERING_MODE_ON,
DITHERING_MODE_AUTO
} mode;
enum {
DITHERING_DEPTH_6BPC = 0x00,
DITHERING_DEPTH_8BPC = 0x02,
DITHERING_DEPTH_AUTO
} depth;
} dither;
struct {
int mode; /* DRM_MODE_SCALE_* */
struct {
enum {
UNDERSCAN_OFF,
UNDERSCAN_ON,
UNDERSCAN_AUTO,
} mode;
u32 hborder;
u32 vborder;
} underscan;
bool full;
} scaler;
struct {
int color_vibrance;
int vibrant_hue;
} procamp;
union {
struct {
bool dither:1;
bool scaler:1;
bool procamp:1;
};
u8 mask;
} set;
};
void nouveau_conn_attach_properties(struct drm_connector *);
void nouveau_conn_reset(struct drm_connector *);
struct drm_connector_state *
nouveau_conn_atomic_duplicate_state(struct drm_connector *);
void nouveau_conn_atomic_destroy_state(struct drm_connector *,
struct drm_connector_state *);
int nouveau_conn_atomic_set_property(struct drm_connector *,
struct drm_connector_state *,
struct drm_property *, u64);
int nouveau_conn_atomic_get_property(struct drm_connector *,
const struct drm_connector_state *,
struct drm_property *, u64 *);
struct drm_display_mode *nouveau_conn_native_mode(struct drm_connector *);
#endif /* __NOUVEAU_CONNECTOR_H__ */
......@@ -38,8 +38,6 @@ struct nouveau_crtc {
uint32_t dpms_saved_fp_control;
uint32_t fp_users;
int saturation;
int color_vibrance;
int vibrant_hue;
int sharpness;
int last_dpms;
......@@ -54,7 +52,6 @@ struct nouveau_crtc {
struct {
struct nouveau_bo *nvbo;
bool visible;
uint32_t offset;
void (*set_offset)(struct nouveau_crtc *, uint32_t offset);
void (*set_pos)(struct nouveau_crtc *, int x, int y);
......@@ -70,10 +67,6 @@ struct nouveau_crtc {
int depth;
} lut;
int (*set_dither)(struct nouveau_crtc *crtc, bool update);
int (*set_scale)(struct nouveau_crtc *crtc, bool update);
int (*set_color_vibrance)(struct nouveau_crtc *crtc, bool update);
void (*save)(struct drm_crtc *crtc);
void (*restore)(struct drm_crtc *crtc);
};
......
This diff is collapsed.
......@@ -22,8 +22,9 @@ nouveau_framebuffer(struct drm_framebuffer *fb)
return container_of(fb, struct nouveau_framebuffer, base);
}
int nouveau_framebuffer_init(struct drm_device *, struct nouveau_framebuffer *,
const struct drm_mode_fb_cmd2 *, struct nouveau_bo *);
int nouveau_framebuffer_new(struct drm_device *,
const struct drm_mode_fb_cmd2 *,
struct nouveau_bo *, struct nouveau_framebuffer **);
struct nouveau_page_flip_state {
struct list_head head;
......@@ -39,9 +40,6 @@ struct nouveau_display {
int (*init)(struct drm_device *);
void (*fini)(struct drm_device *);
int (*fb_ctor)(struct drm_framebuffer *);
void (*fb_dtor)(struct drm_framebuffer *);
struct nvif_object disp;
struct drm_property *dithering_mode;
......@@ -52,6 +50,8 @@ struct nouveau_display {
/* not really hue and saturation: */
struct drm_property *vibrant_hue_property;
struct drm_property *color_vibrance_property;
struct drm_atomic_state *suspend;
};
static inline struct nouveau_display *
......@@ -63,7 +63,7 @@ nouveau_display(struct drm_device *dev)
int nouveau_display_create(struct drm_device *dev);
void nouveau_display_destroy(struct drm_device *dev);
int nouveau_display_init(struct drm_device *dev);
void nouveau_display_fini(struct drm_device *dev);
void nouveau_display_fini(struct drm_device *dev, bool suspend);
int nouveau_display_suspend(struct drm_device *dev, bool runtime);
void nouveau_display_resume(struct drm_device *dev, bool runtime);
int nouveau_display_vblank_enable(struct drm_device *, unsigned int);
......@@ -103,4 +103,7 @@ nouveau_backlight_exit(struct drm_device *dev) {
}
#endif
struct drm_framebuffer *
nouveau_user_framebuffer_create(struct drm_device *, struct drm_file *,
const struct drm_mode_fb_cmd2 *);
#endif
......@@ -30,6 +30,13 @@
#include "nouveau_encoder.h"
#include "nouveau_crtc.h"
#include <nvif/class.h>
#include <nvif/cl5070.h>
MODULE_PARM_DESC(mst, "Enable DisplayPort multi-stream (default: enabled)");
static int nouveau_mst = 1;
module_param_named(mst, nouveau_mst, int, 0400);
static void
nouveau_dp_probe_oui(struct drm_device *dev, struct nvkm_i2c_aux *aux, u8 *dpcd)
{
......@@ -55,14 +62,14 @@ nouveau_dp_detect(struct nouveau_encoder *nv_encoder)
struct drm_device *dev = nv_encoder->base.base.dev;
struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_i2c_aux *aux;
u8 *dpcd = nv_encoder->dp.dpcd;
u8 dpcd[8];
int ret;
aux = nv_encoder->aux;
if (!aux)
return -ENODEV;
ret = nvkm_rdaux(aux, DP_DPCD_REV, dpcd, 8);
ret = nvkm_rdaux(aux, DP_DPCD_REV, dpcd, sizeof(dpcd));
if (ret)
return ret;
......@@ -84,5 +91,11 @@ nouveau_dp_detect(struct nouveau_encoder *nv_encoder)
nv_encoder->dp.link_nr, nv_encoder->dp.link_bw);
nouveau_dp_probe_oui(dev, aux, dpcd);
return 0;
ret = nv50_mstm_detect(nv_encoder->dp.mstm, dpcd, nouveau_mst);
if (ret == 1)
return NOUVEAU_DP_MST;
if (ret == 0)
return NOUVEAU_DP_SST;
return ret;
}
......@@ -519,7 +519,7 @@ nouveau_drm_unload(struct drm_device *dev)
nouveau_debugfs_fini(drm);
if (dev->mode_config.num_crtc)
nouveau_display_fini(dev);
nouveau_display_fini(dev, false);
nouveau_display_destroy(dev);
nouveau_bios_takedown(dev);
......@@ -1037,6 +1037,7 @@ static void nouveau_display_options(void)
DRM_DEBUG_DRIVER("... modeset : %d\n", nouveau_modeset);
DRM_DEBUG_DRIVER("... runpm : %d\n", nouveau_runtime_pm);
DRM_DEBUG_DRIVER("... vram_pushbuf : %d\n", nouveau_vram_pushbuf);
DRM_DEBUG_DRIVER("... hdmimhz : %d\n", nouveau_hdmimhz);
}
static const struct dev_pm_ops nouveau_pm_ops = {
......
......@@ -204,6 +204,10 @@ void nouveau_drm_device_remove(struct drm_device *dev);
if (unlikely(drm_debug & DRM_UT_DRIVER)) \
NV_PRINTK(info, &(drm)->client, f, ##a); \
} while(0)
#define NV_ATOMIC(drm,f,a...) do { \
if (unlikely(drm_debug & DRM_UT_ATOMIC)) \
NV_PRINTK(info, &(drm)->client, f, ##a); \
} while(0)
extern int nouveau_modeset;
......
......@@ -30,6 +30,7 @@
#include <subdev/bios/dcb.h>
#include <drm/drm_encoder_slave.h>
#include <drm/drm_dp_mst_helper.h>
#include "dispnv04/disp.h"
#define NV_DPMS_CLEARED 0x80
......@@ -57,15 +58,16 @@ struct nouveau_encoder {
union {
struct {
u8 dpcd[8];
struct nv50_mstm *mstm;
int link_nr;
int link_bw;
u32 datarate;
} dp;
};
void (*enc_save)(struct drm_encoder *encoder);
void (*enc_restore)(struct drm_encoder *encoder);
void (*update)(struct nouveau_encoder *, u8 head,
struct drm_display_mode *, u8 proto, u8 depth);
};
struct nouveau_encoder *
......@@ -90,9 +92,17 @@ get_slave_funcs(struct drm_encoder *enc)
}
/* nouveau_dp.c */
enum nouveau_dp_status {
NOUVEAU_DP_SST,
NOUVEAU_DP_MST,
};
int nouveau_dp_detect(struct nouveau_encoder *);
struct nouveau_connector *
nouveau_encoder_connector_get(struct nouveau_encoder *encoder);
int nv50_mstm_detect(struct nv50_mstm *, u8 dpcd[8], int allow);
void nv50_mstm_remove(struct nv50_mstm *);
void nv50_mstm_service(struct nv50_mstm *);
#endif /* __NOUVEAU_ENCODER_H__ */
......@@ -58,7 +58,7 @@ static void
nouveau_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{
struct nouveau_fbdev *fbcon = info->par;
struct nouveau_drm *drm = nouveau_drm(fbcon->dev);
struct nouveau_drm *drm = nouveau_drm(fbcon->helper.dev);
struct nvif_device *device = &drm->device;
int ret;
......@@ -90,7 +90,7 @@ static void
nouveau_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *image)
{
struct nouveau_fbdev *fbcon = info->par;
struct nouveau_drm *drm = nouveau_drm(fbcon->dev);
struct nouveau_drm *drm = nouveau_drm(fbcon->helper.dev);
struct nvif_device *device = &drm->device;
int ret;
......@@ -122,7 +122,7 @@ static void
nouveau_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
{
struct nouveau_fbdev *fbcon = info->par;
struct nouveau_drm *drm = nouveau_drm(fbcon->dev);
struct nouveau_drm *drm = nouveau_drm(fbcon->helper.dev);
struct nvif_device *device = &drm->device;
int ret;
......@@ -154,7 +154,7 @@ static int
nouveau_fbcon_sync(struct fb_info *info)
{
struct nouveau_fbdev *fbcon = info->par;
struct nouveau_drm *drm = nouveau_drm(fbcon->dev);
struct nouveau_drm *drm = nouveau_drm(fbcon->helper.dev);
struct nouveau_channel *chan = drm->channel;
int ret;
......@@ -181,7 +181,7 @@ static int
nouveau_fbcon_open(struct fb_info *info, int user)
{
struct nouveau_fbdev *fbcon = info->par;
struct nouveau_drm *drm = nouveau_drm(fbcon->dev);
struct nouveau_drm *drm = nouveau_drm(fbcon->helper.dev);
int ret = pm_runtime_get_sync(drm->dev->dev);
if (ret < 0 && ret != -EACCES)
return ret;
......@@ -192,7 +192,7 @@ static int
nouveau_fbcon_release(struct fb_info *info, int user)
{
struct nouveau_fbdev *fbcon = info->par;
struct nouveau_drm *drm = nouveau_drm(fbcon->dev);
struct nouveau_drm *drm = nouveau_drm(fbcon->helper.dev);
pm_runtime_put(drm->dev->dev);
return 0;
}
......@@ -333,16 +333,15 @@ nouveau_fbcon_create(struct drm_fb_helper *helper,
{
struct nouveau_fbdev *fbcon =
container_of(helper, struct nouveau_fbdev, helper);
struct drm_device *dev = fbcon->dev;
struct drm_device *dev = fbcon->helper.dev;
struct nouveau_drm *drm = nouveau_drm(dev);
struct nvif_device *device = &drm->device;
struct fb_info *info;
struct drm_framebuffer *fb;
struct nouveau_framebuffer *nouveau_fb;
struct nouveau_framebuffer *fb;
struct nouveau_channel *chan;
struct nouveau_bo *nvbo;
struct drm_mode_fb_cmd2 mode_cmd;
int size, ret;
int ret;
mode_cmd.width = sizes->surface_width;
mode_cmd.height = sizes->surface_height;
......@@ -353,16 +352,17 @@ nouveau_fbcon_create(struct drm_fb_helper *helper,
mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
sizes->surface_depth);
size = mode_cmd.pitches[0] * mode_cmd.height;
size = roundup(size, PAGE_SIZE);
ret = nouveau_gem_new(dev, size, 0, NOUVEAU_GEM_DOMAIN_VRAM,
0, 0x0000, &nvbo);
ret = nouveau_gem_new(dev, mode_cmd.pitches[0] * mode_cmd.height,
0, NOUVEAU_GEM_DOMAIN_VRAM, 0, 0x0000, &nvbo);
if (ret) {
NV_ERROR(drm, "failed to allocate framebuffer\n");
goto out;
}
ret = nouveau_framebuffer_new(dev, &mode_cmd, nvbo, &fb);
if (ret)
goto out_unref;
ret = nouveau_bo_pin(nvbo, TTM_PL_FLAG_VRAM, false);
if (ret) {
NV_ERROR(drm, "failed to pin fb: %d\n", ret);
......@@ -377,8 +377,7 @@ nouveau_fbcon_create(struct drm_fb_helper *helper,
chan = nouveau_nofbaccel ? NULL : drm->channel;
if (chan && device->info.family >= NV_DEVICE_INFO_V0_TESLA) {
ret = nouveau_bo_vma_add(nvbo, drm->client.vm,
&fbcon->nouveau_fb.vma);
ret = nouveau_bo_vma_add(nvbo, drm->client.vm, &fb->vma);
if (ret) {
NV_ERROR(drm, "failed to map fb into chan: %d\n", ret);
chan = NULL;
......@@ -394,13 +393,8 @@ nouveau_fbcon_create(struct drm_fb_helper *helper,
info->par = fbcon;
nouveau_framebuffer_init(dev, &fbcon->nouveau_fb, &mode_cmd, nvbo);
nouveau_fb = &fbcon->nouveau_fb;
fb = &nouveau_fb->base;
/* setup helper */
fbcon->helper.fb = fb;
fbcon->helper.fb = &fb->base;
strcpy(info->fix.id, "nouveaufb");
if (!chan)
......@@ -411,14 +405,14 @@ nouveau_fbcon_create(struct drm_fb_helper *helper,
FBINFO_HWACCEL_IMAGEBLIT;
info->flags |= FBINFO_CAN_FORCE_OUTPUT;
info->fbops = &nouveau_fbcon_sw_ops;
info->fix.smem_start = nvbo->bo.mem.bus.base +
nvbo->bo.mem.bus.offset;
info->fix.smem_len = size;
info->fix.smem_start = fb->nvbo->bo.mem.bus.base +
fb->nvbo->bo.mem.bus.offset;
info->fix.smem_len = fb->nvbo->bo.mem.num_pages << PAGE_SHIFT;
info->screen_base = nvbo_kmap_obj_iovirtual(nouveau_fb->nvbo);
info->screen_size = size;
info->screen_base = nvbo_kmap_obj_iovirtual(fb->nvbo);
info->screen_size = fb->nvbo->bo.mem.num_pages << PAGE_SHIFT;
drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
drm_fb_helper_fill_fix(info, fb->base.pitches[0], fb->base.depth);
drm_fb_helper_fill_var(info, &fbcon->helper, sizes->fb_width, sizes->fb_height);
/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
......@@ -429,20 +423,19 @@ nouveau_fbcon_create(struct drm_fb_helper *helper,
/* To allow resizeing without swapping buffers */
NV_INFO(drm, "allocated %dx%d fb: 0x%llx, bo %p\n",
nouveau_fb->base.width, nouveau_fb->base.height,
nvbo->bo.offset, nvbo);
fb->base.width, fb->base.height, fb->nvbo->bo.offset, nvbo);
vga_switcheroo_client_fb_set(dev->pdev, info);
return 0;
out_unlock:
if (chan)
nouveau_bo_vma_del(nvbo, &fbcon->nouveau_fb.vma);
nouveau_bo_unmap(nvbo);
nouveau_bo_vma_del(fb->nvbo, &fb->vma);
nouveau_bo_unmap(fb->nvbo);
out_unpin:
nouveau_bo_unpin(nvbo);
nouveau_bo_unpin(fb->nvbo);
out_unref:
nouveau_bo_ref(NULL, &nvbo);
nouveau_bo_ref(NULL, &fb->nvbo);
out:
return ret;
}
......@@ -458,28 +451,26 @@ nouveau_fbcon_output_poll_changed(struct drm_device *dev)
static int
nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *fbcon)
{
struct nouveau_framebuffer *nouveau_fb = &fbcon->nouveau_fb;
struct nouveau_framebuffer *nouveau_fb = nouveau_framebuffer(fbcon->helper.fb);
drm_fb_helper_unregister_fbi(&fbcon->helper);
drm_fb_helper_release_fbi(&fbcon->helper);
drm_fb_helper_fini(&fbcon->helper);
if (nouveau_fb->nvbo) {
nouveau_bo_unmap(nouveau_fb->nvbo);
nouveau_bo_vma_del(nouveau_fb->nvbo, &nouveau_fb->vma);
nouveau_bo_unmap(nouveau_fb->nvbo);
nouveau_bo_unpin(nouveau_fb->nvbo);
drm_gem_object_unreference_unlocked(&nouveau_fb->nvbo->gem);
nouveau_fb->nvbo = NULL;
drm_framebuffer_unreference(&nouveau_fb->base);
}
drm_fb_helper_fini(&fbcon->helper);
drm_framebuffer_unregister_private(&nouveau_fb->base);
drm_framebuffer_cleanup(&nouveau_fb->base);
return 0;
}
void nouveau_fbcon_gpu_lockup(struct fb_info *info)
{
struct nouveau_fbdev *fbcon = info->par;
struct nouveau_drm *drm = nouveau_drm(fbcon->dev);
struct nouveau_drm *drm = nouveau_drm(fbcon->helper.dev);
NV_ERROR(drm, "GPU lockup - switching to software fbcon\n");
info->flags |= FBINFO_HWACCEL_DISABLED;
......@@ -522,7 +513,6 @@ nouveau_fbcon_init(struct drm_device *dev)
if (!fbcon)
return -ENOMEM;
fbcon->dev = dev;
drm->fbcon = fbcon;
drm_fb_helper_prepare(dev, &fbcon->helper, &nouveau_fbcon_helper_funcs);
......@@ -545,7 +535,8 @@ nouveau_fbcon_init(struct drm_device *dev)
preferred_bpp = 32;
/* disable all the possible outputs/crtcs before entering KMS mode */
drm_helper_disable_unused_functions(dev);
if (!dev->mode_config.funcs->atomic_commit)
drm_helper_disable_unused_functions(dev);
ret = drm_fb_helper_initial_config(&fbcon->helper, preferred_bpp);
if (ret)
......
......@@ -33,8 +33,6 @@
struct nouveau_fbdev {
struct drm_fb_helper helper;
struct nouveau_framebuffer nouveau_fb;
struct drm_device *dev;
unsigned int saved_flags;
struct nvif_object surf2d;
struct nvif_object clip;
......
......@@ -586,5 +586,5 @@ static const struct dma_fence_ops nouveau_fence_ops_uevent = {
.enable_signaling = nouveau_fence_enable_signaling,
.signaled = nouveau_fence_is_signaled,
.wait = dma_fence_default_wait,
.release = NULL
.release = nouveau_fence_release
};
......@@ -92,7 +92,6 @@ struct nv84_fence_chan {
struct nouveau_fence_chan base;
struct nvkm_vma vma;
struct nvkm_vma vma_gart;
struct nvkm_vma dispc_vma[4];
};
struct nv84_fence_priv {
......@@ -102,7 +101,6 @@ struct nv84_fence_priv {
u32 *suspend;
};
u64 nv84_fence_crtc(struct nouveau_channel *, int);
int nv84_fence_context_new(struct nouveau_channel *);
#endif
......@@ -369,7 +369,7 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv,
{
struct nouveau_cli *cli = nouveau_cli(file_priv);
int trycnt = 0;
int ret, i;
int ret = -EINVAL, i;
struct nouveau_bo *res_bo = NULL;
LIST_HEAD(gart_list);
LIST_HEAD(vram_list);
......
......@@ -30,7 +30,7 @@ int
nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region)
{
struct nouveau_fbdev *nfbdev = info->par;
struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
struct nouveau_drm *drm = nouveau_drm(nfbdev->helper.dev);
struct nouveau_channel *chan = drm->channel;
int ret;
......@@ -50,7 +50,7 @@ int
nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{
struct nouveau_fbdev *nfbdev = info->par;
struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
struct nouveau_drm *drm = nouveau_drm(nfbdev->helper.dev);
struct nouveau_channel *chan = drm->channel;
int ret;
......@@ -77,7 +77,7 @@ int
nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
{
struct nouveau_fbdev *nfbdev = info->par;
struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
struct nouveau_drm *drm = nouveau_drm(nfbdev->helper.dev);
struct nouveau_channel *chan = drm->channel;
uint32_t fg;
uint32_t bg;
......@@ -133,7 +133,7 @@ int
nv04_fbcon_accel_init(struct fb_info *info)
{
struct nouveau_fbdev *nfbdev = info->par;
struct drm_device *dev = nfbdev->dev;
struct drm_device *dev = nfbdev->helper.dev;
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_channel *chan = drm->channel;
struct nvif_device *device = &drm->device;
......
......@@ -57,16 +57,13 @@ void
nv10_fence_context_del(struct nouveau_channel *chan)
{
struct nv10_fence_chan *fctx = chan->fence;
int i;
nouveau_fence_context_del(&fctx->base);
for (i = 0; i < ARRAY_SIZE(fctx->head); i++)
nvif_object_fini(&fctx->head[i]);
nvif_object_fini(&fctx->sema);
chan->fence = NULL;
nouveau_fence_context_free(&fctx->base);
}
int
static int
nv10_fence_context_new(struct nouveau_channel *chan)
{
struct nv10_fence_chan *fctx;
......
......@@ -7,7 +7,6 @@
struct nv10_fence_chan {
struct nouveau_fence_chan base;
struct nvif_object sema;
struct nvif_object head[4];
};
struct nv10_fence_priv {
......
This diff is collapsed.
......@@ -35,11 +35,4 @@ int nv50_display_create(struct drm_device *);
void nv50_display_destroy(struct drm_device *);
int nv50_display_init(struct drm_device *);
void nv50_display_fini(struct drm_device *);
void nv50_display_flip_stop(struct drm_crtc *);
int nv50_display_flip_next(struct drm_crtc *, struct drm_framebuffer *,
struct nouveau_channel *, u32 swap_interval);
struct nouveau_bo *nv50_display_crtc_sema(struct drm_device *, int head);
#endif /* __NV50_DISPLAY_H__ */
......@@ -30,7 +30,7 @@ int
nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{
struct nouveau_fbdev *nfbdev = info->par;
struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
struct nouveau_drm *drm = nouveau_drm(nfbdev->helper.dev);
struct nouveau_channel *chan = drm->channel;
int ret;
......@@ -65,7 +65,7 @@ int
nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region)
{
struct nouveau_fbdev *nfbdev = info->par;
struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
struct nouveau_drm *drm = nouveau_drm(nfbdev->helper.dev);
struct nouveau_channel *chan = drm->channel;
int ret;
......@@ -93,7 +93,7 @@ int
nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
{
struct nouveau_fbdev *nfbdev = info->par;
struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
struct nouveau_drm *drm = nouveau_drm(nfbdev->helper.dev);
struct nouveau_channel *chan = drm->channel;
uint32_t dwords, *data = (uint32_t *)image->data;
uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel));
......@@ -148,8 +148,8 @@ int
nv50_fbcon_accel_init(struct fb_info *info)
{
struct nouveau_fbdev *nfbdev = info->par;
struct nouveau_framebuffer *fb = &nfbdev->nouveau_fb;
struct drm_device *dev = nfbdev->dev;
struct nouveau_framebuffer *fb = nouveau_framebuffer(nfbdev->helper.fb);
struct drm_device *dev = nfbdev->helper.dev;
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_channel *chan = drm->channel;
int ret, format;
......
......@@ -35,13 +35,12 @@
static int
nv50_fence_context_new(struct nouveau_channel *chan)
{
struct drm_device *dev = chan->drm->dev;
struct nv10_fence_priv *priv = chan->drm->fence;
struct nv10_fence_chan *fctx;
struct ttm_mem_reg *mem = &priv->bo->bo.mem;
u32 start = mem->start * PAGE_SIZE;
u32 limit = start + mem->size - 1;
int ret, i;
int ret;
fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL);
if (!fctx)
......@@ -60,23 +59,6 @@ nv50_fence_context_new(struct nouveau_channel *chan)
.limit = limit,
}, sizeof(struct nv_dma_v0),
&fctx->sema);
/* dma objects for display sync channel semaphore blocks */
for (i = 0; !ret && i < dev->mode_config.num_crtc; i++) {
struct nouveau_bo *bo = nv50_display_crtc_sema(dev, i);
u32 start = bo->bo.mem.start * PAGE_SIZE;
u32 limit = start + bo->bo.mem.size - 1;
ret = nvif_object_init(&chan->user, NvEvoSema0 + i,
NV_DMA_IN_MEMORY, &(struct nv_dma_v0) {
.target = NV_DMA_V0_TARGET_VRAM,
.access = NV_DMA_V0_ACCESS_RDWR,
.start = start,
.limit = limit,
}, sizeof(struct nv_dma_v0),
&fctx->head[i]);
}
if (ret)
nv10_fence_context_del(chan);
return ret;
......
......@@ -28,13 +28,6 @@
#include "nv50_display.h"
u64
nv84_fence_crtc(struct nouveau_channel *chan, int crtc)
{
struct nv84_fence_chan *fctx = chan->fence;
return fctx->dispc_vma[crtc].offset;
}
static int
nv84_fence_emit32(struct nouveau_channel *chan, u64 virtual, u32 sequence)
{
......@@ -110,15 +103,8 @@ nv84_fence_read(struct nouveau_channel *chan)
static void
nv84_fence_context_del(struct nouveau_channel *chan)
{
struct drm_device *dev = chan->drm->dev;
struct nv84_fence_priv *priv = chan->drm->fence;
struct nv84_fence_chan *fctx = chan->fence;
int i;
for (i = 0; i < dev->mode_config.num_crtc; i++) {
struct nouveau_bo *bo = nv50_display_crtc_sema(dev, i);
nouveau_bo_vma_del(bo, &fctx->dispc_vma[i]);
}
nouveau_bo_wr32(priv->bo, chan->chid * 16 / 4, fctx->base.sequence);
nouveau_bo_vma_del(priv->bo, &fctx->vma_gart);
......@@ -134,7 +120,7 @@ nv84_fence_context_new(struct nouveau_channel *chan)
struct nouveau_cli *cli = (void *)chan->user.client;
struct nv84_fence_priv *priv = chan->drm->fence;
struct nv84_fence_chan *fctx;
int ret, i;
int ret;
fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL);
if (!fctx)
......@@ -154,12 +140,6 @@ nv84_fence_context_new(struct nouveau_channel *chan)
&fctx->vma_gart);
}
/* map display semaphore buffers into channel's vm */
for (i = 0; !ret && i < chan->drm->dev->mode_config.num_crtc; i++) {
struct nouveau_bo *bo = nv50_display_crtc_sema(chan->drm->dev, i);
ret = nouveau_bo_vma_add(bo, cli->vm, &fctx->dispc_vma[i]);
}
if (ret)
nv84_fence_context_del(chan);
return ret;
......
......@@ -30,7 +30,7 @@ int
nvc0_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{
struct nouveau_fbdev *nfbdev = info->par;
struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
struct nouveau_drm *drm = nouveau_drm(nfbdev->helper.dev);
struct nouveau_channel *chan = drm->channel;
int ret;
......@@ -65,7 +65,7 @@ int
nvc0_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region)
{
struct nouveau_fbdev *nfbdev = info->par;
struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
struct nouveau_drm *drm = nouveau_drm(nfbdev->helper.dev);
struct nouveau_channel *chan = drm->channel;
int ret;
......@@ -93,7 +93,7 @@ int
nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
{
struct nouveau_fbdev *nfbdev = info->par;
struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
struct nouveau_drm *drm = nouveau_drm(nfbdev->helper.dev);
struct nouveau_channel *chan = drm->channel;
uint32_t dwords, *data = (uint32_t *)image->data;
uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel));
......@@ -148,8 +148,8 @@ int
nvc0_fbcon_accel_init(struct fb_info *info)
{
struct nouveau_fbdev *nfbdev = info->par;
struct drm_device *dev = nfbdev->dev;
struct nouveau_framebuffer *fb = &nfbdev->nouveau_fb;
struct drm_device *dev = nfbdev->helper.dev;
struct nouveau_framebuffer *fb = nouveau_framebuffer(nfbdev->helper.fb);
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_channel *chan = drm->channel;
int ret, format;
......
......@@ -55,7 +55,7 @@ nvif_client_fini(struct nvif_client *client)
}
}
const struct nvif_driver *
static const struct nvif_driver *
nvif_drivers[] = {
#ifdef __KERNEL__
&nvif_driver_nvkm,
......
......@@ -155,10 +155,8 @@ nvif_notify_fini(struct nvif_notify *notify)
int ret = nvif_notify_put(notify);
if (ret >= 0 && object) {
ret = nvif_object_ioctl(object, &args, sizeof(args), NULL);
if (ret == 0) {
notify->object = NULL;
kfree((void *)notify->data);
}
notify->object = NULL;
kfree((void *)notify->data);
}
return ret;
}
......
uint32_t gf100_ce_data[] = {
static uint32_t gf100_ce_data[] = {
/* 0x0000: ctx_object */
0x00000000,
/* 0x0004: ctx_query_address_high */
......@@ -171,7 +171,7 @@ uint32_t gf100_ce_data[] = {
0x00000800,
};
uint32_t gf100_ce_code[] = {
static uint32_t gf100_ce_code[] = {
/* 0x0000: main */
0x04fe04bd,
0x3517f000,
......
uint32_t gt215_ce_data[] = {
static uint32_t gt215_ce_data[] = {
/* 0x0000: ctx_object */
0x00000000,
/* 0x0004: ctx_dma */
......@@ -183,7 +183,7 @@ uint32_t gt215_ce_data[] = {
0x00000800,
};
uint32_t gt215_ce_code[] = {
static uint32_t gt215_ce_code[] = {
/* 0x0000: main */
0x04fe04bd,
0x3517f000,
......
......@@ -1852,7 +1852,7 @@ nvf1_chipset = {
.fb = gk104_fb_new,
.fuse = gf100_fuse_new,
.gpio = gk104_gpio_new,
.i2c = gf119_i2c_new,
.i2c = gk104_i2c_new,
.ibus = gk104_ibus_new,
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
......@@ -1966,7 +1966,7 @@ nv117_chipset = {
.fb = gm107_fb_new,
.fuse = gm107_fuse_new,
.gpio = gk104_gpio_new,
.i2c = gf119_i2c_new,
.i2c = gk104_i2c_new,
.ibus = gk104_ibus_new,
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
......@@ -2000,7 +2000,7 @@ nv118_chipset = {
.fb = gm107_fb_new,
.fuse = gm107_fuse_new,
.gpio = gk104_gpio_new,
.i2c = gf119_i2c_new,
.i2c = gk104_i2c_new,
.ibus = gk104_ibus_new,
.iccsense = gf100_iccsense_new,
.imem = nv50_instmem_new,
......@@ -2131,7 +2131,7 @@ nv12b_chipset = {
.bar = gk20a_bar_new,
.bus = gf100_bus_new,
.clk = gm20b_clk_new,
.fb = gk20a_fb_new,
.fb = gm20b_fb_new,
.fuse = gm107_fuse_new,
.ibus = gk20a_ibus_new,
.imem = gk20a_instmem_new,
......
......@@ -102,7 +102,7 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev)
if (iommu_present(&platform_bus_type)) {
tdev->iommu.domain = iommu_domain_alloc(&platform_bus_type);
if (IS_ERR(tdev->iommu.domain))
if (!tdev->iommu.domain)
goto error;
/*
......
......@@ -326,7 +326,7 @@ nvkm_udevice = {
.sclass = nvkm_udevice_child_get,
};
int
static int
nvkm_udevice_new(const struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
{
......
......@@ -153,7 +153,7 @@ nv50_disp_chan_uevent = {
.fini = nv50_disp_chan_uevent_fini,
};
int
static int
nv50_disp_chan_rd32(struct nvkm_object *object, u64 addr, u32 *data)
{
struct nv50_disp_chan *chan = nv50_disp_chan(object);
......@@ -163,7 +163,7 @@ nv50_disp_chan_rd32(struct nvkm_object *object, u64 addr, u32 *data)
return 0;
}
int
static int
nv50_disp_chan_wr32(struct nvkm_object *object, u64 addr, u32 data)
{
struct nv50_disp_chan *chan = nv50_disp_chan(object);
......@@ -173,7 +173,7 @@ nv50_disp_chan_wr32(struct nvkm_object *object, u64 addr, u32 data)
return 0;
}
int
static int
nv50_disp_chan_ntfy(struct nvkm_object *object, u32 type,
struct nvkm_event **pevent)
{
......@@ -189,7 +189,7 @@ nv50_disp_chan_ntfy(struct nvkm_object *object, u32 type,
return -EINVAL;
}
int
static int
nv50_disp_chan_map(struct nvkm_object *object, u64 *addr, u32 *size)
{
struct nv50_disp_chan *chan = nv50_disp_chan(object);
......
......@@ -26,7 +26,7 @@
#include <nvif/class.h>
const struct nv50_disp_mthd_list
static const struct nv50_disp_mthd_list
g94_disp_core_mthd_sor = {
.mthd = 0x0040,
.addr = 0x000008,
......@@ -43,8 +43,8 @@ g94_disp_core_chan_mthd = {
.prev = 0x000004,
.data = {
{ "Global", 1, &nv50_disp_core_mthd_base },
{ "DAC", 3, &g84_disp_core_mthd_dac },
{ "SOR", 4, &g94_disp_core_mthd_sor },
{ "DAC", 3, &g84_disp_core_mthd_dac },
{ "SOR", 4, &g94_disp_core_mthd_sor },
{ "PIOR", 3, &nv50_disp_core_mthd_pior },
{ "HEAD", 2, &g84_disp_core_mthd_head },
{}
......
......@@ -59,7 +59,7 @@ gp104_disp_core_init(struct nv50_disp_dmac *chan)
return 0;
}
const struct nv50_disp_dmac_func
static const struct nv50_disp_dmac_func
gp104_disp_core_func = {
.init = gp104_disp_core_init,
.fini = gf119_disp_core_fini,
......
......@@ -319,9 +319,8 @@ static const struct dp_rates {
};
void
nvkm_dp_train(struct work_struct *w)
nvkm_dp_train(struct nvkm_output_dp *outp)
{
struct nvkm_output_dp *outp = container_of(w, typeof(*outp), lt.work);
struct nv50_disp *disp = nv50_disp(outp->base.disp);
const struct dp_rates *cfg = nvkm_dp_rates;
struct dp_state _dp = {
......@@ -353,9 +352,6 @@ nvkm_dp_train(struct work_struct *w)
}
cfg--;
/* disable link interrupt handling during link training */
nvkm_notify_put(&outp->irq);
/* ensure sink is not in a low-power state */
if (!nvkm_rdaux(outp->aux, DPCD_SC00, &pwr, 1)) {
if ((pwr & DPCD_SC00_SET_POWER) != DPCD_SC00_SET_POWER_D0) {
......@@ -400,9 +396,6 @@ nvkm_dp_train(struct work_struct *w)
dp_link_train_fini(dp);
/* signal completion and enable link interrupt handling */
OUTP_DBG(&outp->base, "training complete");
atomic_set(&outp->lt.done, 1);
wake_up(&outp->lt.wait);
nvkm_notify_get(&outp->irq);
}
#ifndef __NVKM_DISP_DPORT_H__
#define __NVKM_DISP_DPORT_H__
#include <core/os.h>
struct nvkm_output_dp;
/* DPCD Receiver Capabilities */
#define DPCD_RC00_DPCD_REV 0x00000
......@@ -77,5 +77,5 @@
#define DPCD_SC00_SET_POWER_D0 0x01
#define DPCD_SC00_SET_POWER_D3 0x03
void nvkm_dp_train(struct work_struct *);
void nvkm_dp_train(struct nvkm_output_dp *);
#endif
......@@ -203,17 +203,20 @@ gf119_disp_intr_unk2_0(struct nv50_disp *disp, int head)
/* see note in nv50_disp_intr_unk20_0() */
if (outp && outp->info.type == DCB_OUTPUT_DP) {
struct nvkm_output_dp *outpdp = nvkm_output_dp(outp);
struct nvbios_init init = {
.subdev = subdev,
.bios = subdev->device->bios,
.outp = &outp->info,
.crtc = head,
.offset = outpdp->info.script[4],
.execute = 1,
};
if (!outpdp->lt.mst) {
struct nvbios_init init = {
.subdev = subdev,
.bios = subdev->device->bios,
.outp = &outp->info,
.crtc = head,
.offset = outpdp->info.script[4],
.execute = 1,
};
nvbios_exec(&init);
atomic_set(&outpdp->lt.done, 0);
nvkm_notify_put(&outpdp->irq);
nvbios_exec(&init);
atomic_set(&outpdp->lt.done, 0);
}
}
}
......@@ -314,7 +317,7 @@ gf119_disp_intr_unk2_2(struct nv50_disp *disp, int head)
break;
}
if (nvkm_output_dp_train(outp, pclk, true))
if (nvkm_output_dp_train(outp, pclk))
OUTP_ERR(outp, "link not trained before attach");
} else {
if (disp->func->sor.magic)
......
......@@ -590,6 +590,7 @@ nv50_disp_intr_unk20_0(struct nv50_disp *disp, int head)
.execute = 1,
};
nvkm_notify_put(&outpdp->irq);
nvbios_exec(&init);
atomic_set(&outpdp->lt.done, 0);
}
......@@ -779,7 +780,7 @@ nv50_disp_intr_unk20_2(struct nv50_disp *disp, int head)
break;
}
if (nvkm_output_dp_train(outp, datarate / soff, true))
if (nvkm_output_dp_train(outp, datarate / soff))
OUTP_ERR(outp, "link not trained before attach");
}
......
......@@ -31,7 +31,7 @@
#include <nvif/event.h>
int
nvkm_output_dp_train(struct nvkm_output *base, u32 datarate, bool wait)
nvkm_output_dp_train(struct nvkm_output *base, u32 datarate)
{
struct nvkm_output_dp *outp = nvkm_output_dp(base);
bool retrain = true;
......@@ -39,6 +39,8 @@ nvkm_output_dp_train(struct nvkm_output *base, u32 datarate, bool wait)
u32 linkrate;
int ret, i;
mutex_lock(&outp->mutex);
/* check that the link is trained at a high enough rate */
ret = nvkm_rdaux(outp->aux, DPCD_LC00_LINK_BW_SET, link, 2);
if (ret) {
......@@ -88,19 +90,10 @@ nvkm_output_dp_train(struct nvkm_output *base, u32 datarate, bool wait)
outp->dpcd[DPCD_RC02] =
outp->base.info.dpconf.link_nr;
}
atomic_set(&outp->lt.done, 0);
schedule_work(&outp->lt.work);
} else {
nvkm_notify_get(&outp->irq);
}
if (wait) {
if (!wait_event_timeout(outp->lt.wait,
atomic_read(&outp->lt.done),
msecs_to_jiffies(2000)))
ret = -ETIMEDOUT;
nvkm_dp_train(outp);
}
mutex_unlock(&outp->mutex);
return ret;
}
......@@ -118,7 +111,7 @@ nvkm_output_dp_enable(struct nvkm_output_dp *outp, bool enable)
if (!nvkm_rdaux(aux, DPCD_RC00_DPCD_REV, outp->dpcd,
sizeof(outp->dpcd))) {
nvkm_output_dp_train(&outp->base, 0, true);
nvkm_output_dp_train(&outp->base, 0);
return;
}
}
......@@ -165,10 +158,10 @@ nvkm_output_dp_irq(struct nvkm_notify *notify)
};
OUTP_DBG(&outp->base, "IRQ: %d", line->mask);
nvkm_output_dp_train(&outp->base, 0, true);
nvkm_output_dp_train(&outp->base, 0);
nvkm_event_send(&disp->hpd, rep.mask, conn->index, &rep, sizeof(rep));
return NVKM_NOTIFY_DROP;
return NVKM_NOTIFY_KEEP;
}
static void
......@@ -177,7 +170,6 @@ nvkm_output_dp_fini(struct nvkm_output *base)
struct nvkm_output_dp *outp = nvkm_output_dp(base);
nvkm_notify_put(&outp->hpd);
nvkm_notify_put(&outp->irq);
flush_work(&outp->lt.work);
nvkm_output_dp_enable(outp, false);
}
......@@ -187,6 +179,7 @@ nvkm_output_dp_init(struct nvkm_output *base)
struct nvkm_output_dp *outp = nvkm_output_dp(base);
nvkm_notify_put(&outp->base.conn->hpd);
nvkm_output_dp_enable(outp, true);
nvkm_notify_get(&outp->irq);
nvkm_notify_get(&outp->hpd);
}
......@@ -238,11 +231,6 @@ nvkm_output_dp_ctor(const struct nvkm_output_dp_func *func,
OUTP_DBG(&outp->base, "bios dp %02x %02x %02x %02x",
outp->version, hdr, cnt, len);
/* link training */
INIT_WORK(&outp->lt.work, nvkm_dp_train);
init_waitqueue_head(&outp->lt.wait);
atomic_set(&outp->lt.done, 0);
/* link maintenance */
ret = nvkm_notify_init(NULL, &i2c->event, nvkm_output_dp_irq, true,
&(struct nvkm_i2c_ntfy_req) {
......@@ -257,6 +245,9 @@ nvkm_output_dp_ctor(const struct nvkm_output_dp_func *func,
return ret;
}
mutex_init(&outp->mutex);
atomic_set(&outp->lt.done, 0);
/* hotplug detect, replaces gpio-based mechanism with aux events */
ret = nvkm_notify_init(NULL, &i2c->event, nvkm_output_dp_hpd, true,
&(struct nvkm_i2c_ntfy_req) {
......
......@@ -29,10 +29,10 @@ struct nvkm_output_dp {
bool present;
u8 dpcd[16];
struct mutex mutex;
struct {
struct work_struct work;
wait_queue_head_t wait;
atomic_t done;
bool mst;
} lt;
};
......@@ -41,9 +41,11 @@ struct nvkm_output_dp_func {
int (*lnk_pwr)(struct nvkm_output_dp *, int nr);
int (*lnk_ctl)(struct nvkm_output_dp *, int nr, int bw, bool ef);
int (*drv_ctl)(struct nvkm_output_dp *, int ln, int vs, int pe, int pc);
void (*vcpi)(struct nvkm_output_dp *, int head, u8 start_slot,
u8 num_slots, u16 pbn, u16 aligned_pbn);
};
int nvkm_output_dp_train(struct nvkm_output *, u32 rate, bool wait);
int nvkm_output_dp_train(struct nvkm_output *, u32 rate);
int nvkm_output_dp_ctor(const struct nvkm_output_dp_func *, struct nvkm_disp *,
int index, struct dcb_output *, struct nvkm_i2c_aux *,
......@@ -63,6 +65,7 @@ int gf119_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *,
struct nvkm_output **);
int gf119_sor_dp_lnk_ctl(struct nvkm_output_dp *, int, int, bool);
int gf119_sor_dp_drv_ctl(struct nvkm_output_dp *, int, int, int, int);
void gf119_sor_dp_vcpi(struct nvkm_output_dp *, int, u8, u8, u16, u16);
int gm107_sor_dp_new(struct nvkm_disp *, int, struct dcb_output *,
struct nvkm_output **);
......
......@@ -66,7 +66,7 @@ nv50_disp_root_scanoutpos(NV50_DISP_MTHD_V0)
return 0;
}
int
static int
nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
{
union {
......@@ -173,13 +173,56 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
return 0;
} else
if (args->v0.state != 0) {
nvkm_output_dp_train(&outpdp->base, 0, true);
nvkm_output_dp_train(&outpdp->base, 0);
return 0;
}
} else
return ret;
}
break;
case NV50_DISP_MTHD_V1_SOR_DP_MST_LINK: {
struct nvkm_output_dp *outpdp = nvkm_output_dp(outp);
union {
struct nv50_disp_sor_dp_mst_link_v0 v0;
} *args = data;
int ret = -ENOSYS;
nvif_ioctl(object, "disp sor dp mst link size %d\n", size);
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "disp sor dp mst link vers %d state %d\n",
args->v0.version, args->v0.state);
if (outpdp->lt.mst != !!args->v0.state) {
outpdp->lt.mst = !!args->v0.state;
atomic_set(&outpdp->lt.done, 0);
nvkm_output_dp_train(&outpdp->base, 0);
}
return 0;
} else
return ret;
}
break;
case NV50_DISP_MTHD_V1_SOR_DP_MST_VCPI: {
struct nvkm_output_dp *outpdp = nvkm_output_dp(outp);
union {
struct nv50_disp_sor_dp_mst_vcpi_v0 v0;
} *args = data;
int ret = -ENOSYS;
nvif_ioctl(object, "disp sor dp mst vcpi size %d\n", size);
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "disp sor dp mst vcpi vers %d "
"slot %02x/%02x pbn %04x/%04x\n",
args->v0.version, args->v0.start_slot,
args->v0.num_slots, args->v0.pbn,
args->v0.aligned_pbn);
if (!outpdp->func->vcpi)
return -ENODEV;
outpdp->func->vcpi(outpdp, head, args->v0.start_slot,
args->v0.num_slots, args->v0.pbn,
args->v0.aligned_pbn);
return 0;
} else
return ret;
}
break;
case NV50_DISP_MTHD_V1_PIOR_PWR:
if (!func->pior.power)
return -ENODEV;
......
......@@ -56,11 +56,13 @@ gf119_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef)
clksor |= bw << 18;
dpctrl |= ((1 << nr) - 1) << 16;
if (outp->lt.mst)
dpctrl |= 0x40000000;
if (ef)
dpctrl |= 0x00004000;
nvkm_mask(device, 0x612300 + soff, 0x007c0000, clksor);
nvkm_mask(device, 0x61c10c + loff, 0x001f4000, dpctrl);
nvkm_mask(device, 0x61c10c + loff, 0x401f4000, dpctrl);
return 0;
}
......@@ -101,12 +103,24 @@ gf119_sor_dp_drv_ctl(struct nvkm_output_dp *outp,
return 0;
}
void
gf119_sor_dp_vcpi(struct nvkm_output_dp *outp, int head, u8 slot,
u8 slot_nr, u16 pbn, u16 aligned)
{
struct nvkm_device *device = outp->base.disp->engine.subdev.device;
const u32 hoff = head * 0x800;
nvkm_mask(device, 0x616588 + hoff, 0x00003f3f, (slot_nr << 8) | slot);
nvkm_mask(device, 0x61658c + hoff, 0xffffffff, (aligned << 16) | pbn);
}
static const struct nvkm_output_dp_func
gf119_sor_dp_func = {
.pattern = gf119_sor_dp_pattern,
.lnk_pwr = g94_sor_dp_lnk_pwr,
.lnk_ctl = gf119_sor_dp_lnk_ctl,
.drv_ctl = gf119_sor_dp_drv_ctl,
.vcpi = gf119_sor_dp_vcpi,
};
int
......
......@@ -43,6 +43,7 @@ gm107_sor_dp_func = {
.lnk_pwr = g94_sor_dp_lnk_pwr,
.lnk_ctl = gf119_sor_dp_lnk_ctl,
.drv_ctl = gf119_sor_dp_drv_ctl,
.vcpi = gf119_sor_dp_vcpi,
};
int
......
......@@ -120,6 +120,7 @@ gm200_sor_dp_func = {
.lnk_pwr = gm200_sor_dp_lnk_pwr,
.lnk_ctl = gf119_sor_dp_lnk_ctl,
.drv_ctl = gm200_sor_dp_drv_ctl,
.vcpi = gf119_sor_dp_vcpi,
};
int
......
......@@ -129,7 +129,7 @@ g84_fifo_chan_engine_fini(struct nvkm_fifo_chan *base,
}
int
static int
g84_fifo_chan_engine_init(struct nvkm_fifo_chan *base,
struct nvkm_engine *engine)
{
......@@ -170,7 +170,7 @@ g84_fifo_chan_engine_ctor(struct nvkm_fifo_chan *base,
return nvkm_object_bind(object, NULL, 0, &chan->engn[engn]);
}
int
static int
g84_fifo_chan_object_ctor(struct nvkm_fifo_chan *base,
struct nvkm_object *object)
{
......
......@@ -60,6 +60,7 @@ gf100_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan *base,
struct nvkm_gpuobj *inst = chan->base.inst;
int ret = 0;
mutex_lock(&subdev->mutex);
nvkm_wr32(device, 0x002634, chan->base.chid);
if (nvkm_msec(device, 2000,
if (nvkm_rd32(device, 0x002634) == chan->base.chid)
......@@ -67,10 +68,12 @@ gf100_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan *base,
) < 0) {
nvkm_error(subdev, "channel %d [%s] kick timeout\n",
chan->base.chid, chan->base.object.client->name);
ret = -EBUSY;
if (suspend)
return ret;
ret = -ETIMEDOUT;
}
mutex_unlock(&subdev->mutex);
if (ret && suspend)
return ret;
if (offset) {
nvkm_kmap(inst);
......
......@@ -40,7 +40,9 @@ gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *chan)
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
struct nvkm_device *device = subdev->device;
struct nvkm_client *client = chan->base.object.client;
int ret = 0;
mutex_lock(&subdev->mutex);
nvkm_wr32(device, 0x002634, chan->base.chid);
if (nvkm_msec(device, 2000,
if (!(nvkm_rd32(device, 0x002634) & 0x00100000))
......@@ -48,10 +50,10 @@ gk104_fifo_gpfifo_kick(struct gk104_fifo_chan *chan)
) < 0) {
nvkm_error(subdev, "channel %d [%s] kick timeout\n",
chan->base.chid, client->name);
return -EBUSY;
ret = -ETIMEDOUT;
}
return 0;
mutex_unlock(&subdev->mutex);
return ret;
}
static u32
......
......@@ -218,7 +218,7 @@ gf117_grctx_generate_attrib(struct gf100_grctx *info)
}
}
void
static void
gf117_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
......
......@@ -933,7 +933,7 @@ gm107_grctx_generate_attrib(struct gf100_grctx *info)
}
}
void
static void
gm107_grctx_generate_tpcid(struct gf100_gr *gr)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
......
......@@ -106,6 +106,7 @@
#define CP_SEEK_2 0x00c800ff
#include "ctxnv40.h"
#include "nv50.h"
#include <subdev/fb.h>
......
uint32_t gf100_grgpc_data[] = {
static uint32_t gf100_grgpc_data[] = {
/* 0x0000: gpc_mmio_list_head */
0x00000064,
/* 0x0004: gpc_mmio_list_tail */
......@@ -36,7 +36,7 @@ uint32_t gf100_grgpc_data[] = {
0x00000000,
};
uint32_t gf100_grgpc_code[] = {
static uint32_t gf100_grgpc_code[] = {
0x03a10ef5,
/* 0x0004: queue_put */
0x9800d898,
......
uint32_t gf117_grgpc_data[] = {
static uint32_t gf117_grgpc_data[] = {
/* 0x0000: gpc_mmio_list_head */
0x0000006c,
/* 0x0004: gpc_mmio_list_tail */
......@@ -40,7 +40,7 @@ uint32_t gf117_grgpc_data[] = {
0x00000000,
};
uint32_t gf117_grgpc_code[] = {
static uint32_t gf117_grgpc_code[] = {
0x03a10ef5,
/* 0x0004: queue_put */
0x9800d898,
......
uint32_t gk104_grgpc_data[] = {
static uint32_t gk104_grgpc_data[] = {
/* 0x0000: gpc_mmio_list_head */
0x0000006c,
/* 0x0004: gpc_mmio_list_tail */
......@@ -40,7 +40,7 @@ uint32_t gk104_grgpc_data[] = {
0x00000000,
};
uint32_t gk104_grgpc_code[] = {
static uint32_t gk104_grgpc_code[] = {
0x03a10ef5,
/* 0x0004: queue_put */
0x9800d898,
......
uint32_t gk110_grgpc_data[] = {
static uint32_t gk110_grgpc_data[] = {
/* 0x0000: gpc_mmio_list_head */
0x0000006c,
/* 0x0004: gpc_mmio_list_tail */
......@@ -40,7 +40,7 @@ uint32_t gk110_grgpc_data[] = {
0x00000000,
};
uint32_t gk110_grgpc_code[] = {
static uint32_t gk110_grgpc_code[] = {
0x03a10ef5,
/* 0x0004: queue_put */
0x9800d898,
......
uint32_t gk208_grgpc_data[] = {
static uint32_t gk208_grgpc_data[] = {
/* 0x0000: gpc_mmio_list_head */
0x0000006c,
/* 0x0004: gpc_mmio_list_tail */
......@@ -40,7 +40,7 @@ uint32_t gk208_grgpc_data[] = {
0x00000000,
};
uint32_t gk208_grgpc_code[] = {
static uint32_t gk208_grgpc_code[] = {
0x03140ef5,
/* 0x0004: queue_put */
0x9800d898,
......
uint32_t gm107_grgpc_data[] = {
static uint32_t gm107_grgpc_data[] = {
/* 0x0000: gpc_mmio_list_head */
0x0000006c,
/* 0x0004: gpc_mmio_list_tail */
......@@ -40,7 +40,7 @@ uint32_t gm107_grgpc_data[] = {
0x00000000,
};
uint32_t gm107_grgpc_code[] = {
static uint32_t gm107_grgpc_code[] = {
0x03410ef5,
/* 0x0004: queue_put */
0x9800d898,
......
uint32_t gf100_grhub_data[] = {
static uint32_t gf100_grhub_data[] = {
/* 0x0000: hub_mmio_list_head */
0x00000300,
/* 0x0004: hub_mmio_list_tail */
......@@ -205,7 +205,7 @@ uint32_t gf100_grhub_data[] = {
0x0417e91c,
};
uint32_t gf100_grhub_code[] = {
static uint32_t gf100_grhub_code[] = {
0x039b0ef5,
/* 0x0004: queue_put */
0x9800d898,
......
uint32_t gf117_grhub_data[] = {
static uint32_t gf117_grhub_data[] = {
/* 0x0000: hub_mmio_list_head */
0x00000300,
/* 0x0004: hub_mmio_list_tail */
......@@ -205,7 +205,7 @@ uint32_t gf117_grhub_data[] = {
0x0417e91c,
};
uint32_t gf117_grhub_code[] = {
static uint32_t gf117_grhub_code[] = {
0x039b0ef5,
/* 0x0004: queue_put */
0x9800d898,
......
uint32_t gk104_grhub_data[] = {
static uint32_t gk104_grhub_data[] = {
/* 0x0000: hub_mmio_list_head */
0x00000300,
/* 0x0004: hub_mmio_list_tail */
......@@ -205,7 +205,7 @@ uint32_t gk104_grhub_data[] = {
0x0417e91c,
};
uint32_t gk104_grhub_code[] = {
static uint32_t gk104_grhub_code[] = {
0x039b0ef5,
/* 0x0004: queue_put */
0x9800d898,
......
uint32_t gk110_grhub_data[] = {
static uint32_t gk110_grhub_data[] = {
/* 0x0000: hub_mmio_list_head */
0x00000300,
/* 0x0004: hub_mmio_list_tail */
......@@ -205,7 +205,7 @@ uint32_t gk110_grhub_data[] = {
0x0417e91c,
};
uint32_t gk110_grhub_code[] = {
static uint32_t gk110_grhub_code[] = {
0x039b0ef5,
/* 0x0004: queue_put */
0x9800d898,
......
uint32_t gk208_grhub_data[] = {
static uint32_t gk208_grhub_data[] = {
/* 0x0000: hub_mmio_list_head */
0x00000300,
/* 0x0004: hub_mmio_list_tail */
......@@ -205,7 +205,7 @@ uint32_t gk208_grhub_data[] = {
0x0417e91c,
};
uint32_t gk208_grhub_code[] = {
static uint32_t gk208_grhub_code[] = {
0x030e0ef5,
/* 0x0004: queue_put */
0x9800d898,
......
uint32_t gm107_grhub_data[] = {
static uint32_t gm107_grhub_data[] = {
/* 0x0000: hub_mmio_list_head */
0x00000300,
/* 0x0004: hub_mmio_list_tail */
......@@ -205,7 +205,7 @@ uint32_t gm107_grhub_data[] = {
0x0417e91c,
};
uint32_t gm107_grhub_code[] = {
static uint32_t gm107_grhub_code[] = {
0x030e0ef5,
/* 0x0004: queue_put */
0x9800d898,
......
......@@ -1384,7 +1384,7 @@ gf100_gr_intr(struct nvkm_gr *base)
nvkm_fifo_chan_put(device->fifo, flags, &chan);
}
void
static void
gf100_gr_init_fw(struct gf100_gr *gr, u32 fuc_base,
struct gf100_gr_fuc *code, struct gf100_gr_fuc *data)
{
......@@ -1701,7 +1701,7 @@ gf100_gr_oneinit(struct nvkm_gr *base)
return 0;
}
int
static int
gf100_gr_init_(struct nvkm_gr *base)
{
struct gf100_gr *gr = gf100_gr(base);
......@@ -1755,6 +1755,50 @@ gf100_gr_ = {
.object_get = gf100_gr_object_get,
};
int
gf100_gr_ctor_fw_legacy(struct gf100_gr *gr, const char *fwname,
struct gf100_gr_fuc *fuc, int ret)
{
struct nvkm_subdev *subdev = &gr->base.engine.subdev;
struct nvkm_device *device = subdev->device;
const struct firmware *fw;
char f[32];
/* see if this firmware has a legacy path */
if (!strcmp(fwname, "fecs_inst"))
fwname = "fuc409c";
else if (!strcmp(fwname, "fecs_data"))
fwname = "fuc409d";
else if (!strcmp(fwname, "gpccs_inst"))
fwname = "fuc41ac";
else if (!strcmp(fwname, "gpccs_data"))
fwname = "fuc41ad";
else {
/* nope, let's just return the error we got */
nvkm_error(subdev, "failed to load %s\n", fwname);
return ret;
}
/* yes, try to load from the legacy path */
nvkm_debug(subdev, "%s: falling back to legacy path\n", fwname);
snprintf(f, sizeof(f), "nouveau/nv%02x_%s", device->chipset, fwname);
ret = request_firmware(&fw, f, device->dev);
if (ret) {
snprintf(f, sizeof(f), "nouveau/%s", fwname);
ret = request_firmware(&fw, f, device->dev);
if (ret) {
nvkm_error(subdev, "failed to load %s\n", fwname);
return ret;
}
}
fuc->size = fw->size;
fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);
release_firmware(fw);
return (fuc->data != NULL) ? 0 : -ENOMEM;
}
int
gf100_gr_ctor_fw(struct gf100_gr *gr, const char *fwname,
struct gf100_gr_fuc *fuc)
......@@ -1765,10 +1809,8 @@ gf100_gr_ctor_fw(struct gf100_gr *gr, const char *fwname,
int ret;
ret = nvkm_firmware_get(device, fwname, &fw);
if (ret) {
nvkm_error(subdev, "failed to load %s\n", fwname);
return ret;
}
if (ret)
return gf100_gr_ctor_fw_legacy(gr, fwname, fuc, ret);
fuc->size = fw->size;
fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);
......
......@@ -102,7 +102,7 @@ gf117_gr_pack_mmio[] = {
#include "fuc/hubgf117.fuc3.h"
struct gf100_gr_ucode
static struct gf100_gr_ucode
gf117_gr_fecs_ucode = {
.code.data = gf117_grhub_code,
.code.size = sizeof(gf117_grhub_code),
......@@ -112,7 +112,7 @@ gf117_gr_fecs_ucode = {
#include "fuc/gpcgf117.fuc3.h"
struct gf100_gr_ucode
static struct gf100_gr_ucode
gf117_gr_gpccs_ucode = {
.code.data = gf117_grgpc_code,
.code.size = sizeof(gf117_grgpc_code),
......
......@@ -308,7 +308,7 @@ gm107_gr_init_bios(struct gf100_gr *gr)
}
}
int
static int
gm107_gr_init(struct gf100_gr *gr)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
......
......@@ -71,7 +71,7 @@ nvkm_perfdom_find(struct nvkm_pm *pm, int di)
return NULL;
}
struct nvkm_perfsig *
static struct nvkm_perfsig *
nvkm_perfsig_find(struct nvkm_pm *pm, u8 di, u8 si, struct nvkm_perfdom **pdom)
{
struct nvkm_perfdom *dom = *pdom;
......@@ -699,7 +699,7 @@ nvkm_pm_oclass_get(struct nvkm_oclass *oclass, int index,
return 1;
}
int
static int
nvkm_perfsrc_new(struct nvkm_pm *pm, struct nvkm_perfsig *sig,
const struct nvkm_specsrc *spec)
{
......
......@@ -102,7 +102,7 @@ gf100_pm_gpc[] = {
{}
};
const struct nvkm_specdom
static const struct nvkm_specdom
gf100_pm_part[] = {
{ 0xe0, (const struct nvkm_specsig[]) {
{ 0x0f, "part00_pbfb_00", gf100_pbfb_sources },
......
uint32_t g98_sec_data[] = {
static uint32_t g98_sec_data[] = {
/* 0x0000: ctx_dma */
/* 0x0000: ctx_dma_query */
0x00000000,
......@@ -150,7 +150,7 @@ uint32_t g98_sec_data[] = {
0x00000000,
};
uint32_t g98_sec_code[] = {
static uint32_t g98_sec_code[] = {
0x17f004bd,
0x0010fe35,
0xf10004fe,
......
......@@ -25,7 +25,7 @@
#include <subdev/bios/bit.h>
#include <subdev/bios/fan.h>
u16
static u16
nvbios_fan_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
{
struct bit_entry bit_P;
......@@ -52,7 +52,7 @@ nvbios_fan_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
return 0x0000;
}
u16
static u16
nvbios_fan_entry(struct nvkm_bios *bios, int idx, u8 *ver, u8 *hdr,
u8 *cnt, u8 *len)
{
......
......@@ -12,6 +12,7 @@ struct nvbios_source {
bool rw;
bool ignore_checksum;
bool no_pcir;
bool require_checksum;
};
int nvbios_extend(struct nvkm_bios *, u32 length);
......
......@@ -86,9 +86,12 @@ shadow_image(struct nvkm_bios *bios, int idx, u32 offset, struct shadow *mthd)
nvbios_checksum(&bios->data[image.base], image.size)) {
nvkm_debug(subdev, "%08x: checksum failed\n",
image.base);
if (mthd->func->rw)
if (!mthd->func->require_checksum) {
if (mthd->func->rw)
score += 1;
score += 1;
score += 1;
} else
return 0;
} else {
score += 3;
}
......
......@@ -99,6 +99,7 @@ nvbios_acpi_fast = {
.init = acpi_init,
.read = acpi_read_fast,
.rw = false,
.require_checksum = true,
};
const struct nvbios_source
......
......@@ -180,7 +180,7 @@ gt215_clk_read(struct nvkm_clk *base, enum nv_clk_src src)
return 0;
}
int
static int
gt215_clk_info(struct nvkm_clk *base, int idx, u32 khz,
struct gt215_clk_info *info)
{
......
......@@ -24,6 +24,7 @@ nvkm-y += nvkm/subdev/fb/gk104.o
nvkm-y += nvkm/subdev/fb/gk20a.o
nvkm-y += nvkm/subdev/fb/gm107.o
nvkm-y += nvkm/subdev/fb/gm200.o
nvkm-y += nvkm/subdev/fb/gm20b.o
nvkm-y += nvkm/subdev/fb/gp100.o
nvkm-y += nvkm/subdev/fb/gp104.o
......
......@@ -16,4 +16,8 @@ void gf100_fb_init(struct nvkm_fb *);
void gf100_fb_intr(struct nvkm_fb *);
void gp100_fb_init(struct nvkm_fb *);
void gm200_fb_init_page(struct nvkm_fb *fb);
void gm200_fb_init(struct nvkm_fb *base);
#endif
/*
* Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
* Copyright (c) 2014-2016, NVIDIA CORPORATION. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
......@@ -20,27 +20,21 @@
* DEALINGS IN THE SOFTWARE.
*/
#include "priv.h"
#include "gf100.h"
#include <core/memory.h>
static void
gk20a_fb_init(struct nvkm_fb *fb)
{
struct nvkm_device *device = fb->subdev.device;
nvkm_wr32(device, 0x100cc8, nvkm_memory_addr(fb->mmu_wr) >> 8);
nvkm_wr32(device, 0x100ccc, nvkm_memory_addr(fb->mmu_rd) >> 8);
}
/* GK20A's FB is similar to GF100's, but without the ability to allocate VRAM */
static const struct nvkm_fb_func
gk20a_fb = {
.dtor = gf100_fb_dtor,
.oneinit = gf100_fb_oneinit,
.init = gk20a_fb_init,
.init = gf100_fb_init,
.init_page = gf100_fb_init_page,
.intr = gf100_fb_intr,
.memtype_valid = gf100_fb_memtype_valid,
};
int
gk20a_fb_new(struct nvkm_device *device, int index, struct nvkm_fb **pfb)
{
return nvkm_fb_new_(&gk20a_fb, device, index, pfb);
return gf100_fb_new_(&gk20a_fb, device, index, pfb);
}
......@@ -44,7 +44,7 @@ gm200_fb_init_page(struct nvkm_fb *fb)
}
}
static void
void
gm200_fb_init(struct nvkm_fb *base)
{
struct gf100_fb *fb = gf100_fb(base);
......
/*
* Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved.
*
* 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 AUTHORS OR COPYRIGHT HOLDERS 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.
*/
#include "priv.h"
#include "gf100.h"
/* GM20B's FB is similar to GM200, but without the ability to allocate VRAM */
static const struct nvkm_fb_func
gm20b_fb = {
.dtor = gf100_fb_dtor,
.oneinit = gf100_fb_oneinit,
.init = gm200_fb_init,
.init_page = gm200_fb_init_page,
.intr = gf100_fb_intr,
.memtype_valid = gf100_fb_memtype_valid,
};
int
gm20b_fb_new(struct nvkm_device *device, int index, struct nvkm_fb **pfb)
{
return gf100_fb_new_(&gm20b_fb, device, index, pfb);
}
......@@ -420,8 +420,6 @@ gf100_ram_tidy(struct nvkm_ram *base)
ram_exec(&ram->fuc, false);
}
extern const u8 gf100_pte_storage_type_map[256];
void
gf100_ram_put(struct nvkm_ram *ram, struct nvkm_mem **pmem)
{
......
......@@ -95,7 +95,7 @@ struct gt215_ram {
struct gt215_ltrain ltrain;
};
void
static void
gt215_link_train_calc(u32 *vals, struct gt215_ltrain *train)
{
int i, lo, hi;
......@@ -149,7 +149,7 @@ gt215_link_train_calc(u32 *vals, struct gt215_ltrain *train)
/*
* Link training for (at least) DDR3
*/
int
static int
gt215_link_train(struct gt215_ram *ram)
{
struct gt215_ltrain *train = &ram->ltrain;
......@@ -267,7 +267,7 @@ gt215_link_train(struct gt215_ram *ram)
return ret;
}
int
static int
gt215_link_train_init(struct gt215_ram *ram)
{
static const u32 pattern[16] = {
......@@ -333,7 +333,7 @@ gt215_link_train_init(struct gt215_ram *ram)
return 0;
}
void
static void
gt215_link_train_fini(struct gt215_ram *ram)
{
if (ram->ltrain.mem)
......
......@@ -23,6 +23,7 @@
* Ben Skeggs
*/
#include "priv.h"
#include "ram.h"
struct ramxlat {
int id;
......
......@@ -23,6 +23,7 @@
* Roy Spliet <rspliet@eclipso.eu>
*/
#include "priv.h"
#include "ram.h"
struct ramxlat {
int id;
......
......@@ -37,7 +37,7 @@ gk104_gpio_intr_stat(struct nvkm_gpio *gpio, u32 *hi, u32 *lo)
nvkm_wr32(device, 0x00dc80, intr1);
}
void
static void
gk104_gpio_intr_mask(struct nvkm_gpio *gpio, u32 type, u32 mask, u32 data)
{
struct nvkm_device *device = gpio->subdev.device;
......
......@@ -74,7 +74,7 @@ nvkm_i2c_aux_i2c_func(struct i2c_adapter *adap)
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
const struct i2c_algorithm
static const struct i2c_algorithm
nvkm_i2c_aux_i2c_algo = {
.master_xfer = nvkm_i2c_aux_i2c_xfer,
.functionality = nvkm_i2c_aux_i2c_func
......
......@@ -79,7 +79,7 @@ g94_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry,
struct g94_i2c_aux *aux = g94_i2c_aux(obj);
struct nvkm_device *device = aux->base.pad->i2c->subdev.device;
const u32 base = aux->ch * 0x50;
u32 ctrl, stat, timeout, retries;
u32 ctrl, stat, timeout, retries = 0;
u32 xbuf[4] = {};
int ret, i;
......@@ -111,7 +111,7 @@ g94_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry,
nvkm_wr32(device, 0x00e4e0 + base, addr);
/* (maybe) retry transaction a number of times on failure... */
for (retries = 0; !ret && retries < 32; retries++) {
do {
/* reset, and delay a while if this is a retry */
nvkm_wr32(device, 0x00e4e4 + base, 0x80000000 | ctrl);
nvkm_wr32(device, 0x00e4e4 + base, 0x00000000 | ctrl);
......@@ -131,20 +131,20 @@ g94_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry,
goto out;
}
} while (ctrl & 0x00010000);
ret = 1;
ret = 0;
/* read status, and check if transaction completed ok */
stat = nvkm_mask(device, 0x00e4e8 + base, 0, 0);
if ((stat & 0x000f0000) == 0x00080000 ||
(stat & 0x000f0000) == 0x00020000)
ret = retry ? 0 : 1;
ret = 1;
if ((stat & 0x00000100))
ret = -ETIMEDOUT;
if ((stat & 0x00000e00))
ret = -EIO;
AUX_TRACE(&aux->base, "%02d %08x %08x", retries, ctrl, stat);
}
} while (ret && retry && retries++ < 32);
if (type & 1) {
for (i = 0; i < 16; i += 4) {
......
......@@ -79,7 +79,7 @@ gm200_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry,
struct gm200_i2c_aux *aux = gm200_i2c_aux(obj);
struct nvkm_device *device = aux->base.pad->i2c->subdev.device;
const u32 base = aux->ch * 0x50;
u32 ctrl, stat, timeout, retries;
u32 ctrl, stat, timeout, retries = 0;
u32 xbuf[4] = {};
int ret, i;
......@@ -111,7 +111,7 @@ gm200_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry,
nvkm_wr32(device, 0x00d950 + base, addr);
/* (maybe) retry transaction a number of times on failure... */
for (retries = 0; !ret && retries < 32; retries++) {
do {
/* reset, and delay a while if this is a retry */
nvkm_wr32(device, 0x00d954 + base, 0x80000000 | ctrl);
nvkm_wr32(device, 0x00d954 + base, 0x00000000 | ctrl);
......@@ -131,20 +131,20 @@ gm200_i2c_aux_xfer(struct nvkm_i2c_aux *obj, bool retry,
goto out;
}
} while (ctrl & 0x00010000);
ret = 1;
ret = 0;
/* read status, and check if transaction completed ok */
stat = nvkm_mask(device, 0x00d958 + base, 0, 0);
if ((stat & 0x000f0000) == 0x00080000 ||
(stat & 0x000f0000) == 0x00020000)
ret = retry ? 0 : 1;
ret = 1;
if ((stat & 0x00000100))
ret = -ETIMEDOUT;
if ((stat & 0x00000e00))
ret = -EIO;
AUX_TRACE(&aux->base, "%02d %08x %08x", retries, ctrl, stat);
}
} while (ret && retry && retries++ < 32);
if (type & 1) {
for (i = 0; i < 16; i += 4) {
......
......@@ -288,7 +288,8 @@ nvkm_iccsense_init(struct nvkm_subdev *subdev)
return 0;
}
struct nvkm_subdev_func iccsense_func = {
static const struct nvkm_subdev_func
iccsense_func = {
.oneinit = nvkm_iccsense_oneinit,
.init = nvkm_iccsense_init,
.dtor = nvkm_iccsense_dtor,
......
......@@ -104,7 +104,7 @@ nvkm_instobj_dtor(struct nvkm_memory *memory)
return iobj;
}
const struct nvkm_memory_func
static const struct nvkm_memory_func
nvkm_instobj_func = {
.dtor = nvkm_instobj_dtor,
.target = nvkm_instobj_target,
......@@ -156,7 +156,7 @@ nvkm_instobj_wr32_slow(struct nvkm_memory *memory, u64 offset, u32 data)
return nvkm_wo32(iobj->parent, offset, data);
}
const struct nvkm_memory_func
static const struct nvkm_memory_func
nvkm_instobj_func_slow = {
.dtor = nvkm_instobj_dtor,
.target = nvkm_instobj_target,
......
......@@ -34,7 +34,7 @@ g84_mc_reset[] = {
{}
};
const struct nvkm_mc_map
static const struct nvkm_mc_map
g84_mc_intr[] = {
{ 0x04000000, NVKM_ENGINE_DISP },
{ 0x00020000, NVKM_ENGINE_VP },
......
......@@ -250,6 +250,10 @@ nvkm_mxm_new_(struct nvkm_device *device, int index, struct nvkm_mxm **pmxm)
}
nvkm_info(&mxm->subdev, "BIOS version %d.%d\n", ver >> 4, ver & 0x0f);
nvkm_debug(&mxm->subdev, "module flags: %02x\n",
nvbios_rd08(bios, data + 0x01));
nvkm_debug(&mxm->subdev, "config flags: %02x\n",
nvbios_rd08(bios, data + 0x02));
if (mxm_shadow(mxm, ver)) {
nvkm_warn(&mxm->subdev, "failed to locate valid SIS\n");
......
uint32_t gf100_pmu_data[] = {
static uint32_t gf100_pmu_data[] = {
/* 0x0000: proc_kern */
0x52544e49,
0x00000000,
......@@ -916,7 +916,7 @@ uint32_t gf100_pmu_data[] = {
0x00000000,
};
uint32_t gf100_pmu_code[] = {
static uint32_t gf100_pmu_code[] = {
0x03920ef5,
/* 0x0004: rd32 */
0x07a007f1,
......
uint32_t gf119_pmu_data[] = {
static uint32_t gf119_pmu_data[] = {
/* 0x0000: proc_kern */
0x52544e49,
0x00000000,
......@@ -915,7 +915,7 @@ uint32_t gf119_pmu_data[] = {
0x00000000,
};
uint32_t gf119_pmu_code[] = {
static uint32_t gf119_pmu_code[] = {
0x03410ef5,
/* 0x0004: rd32 */
0x07a007f1,
......
uint32_t gk208_pmu_data[] = {
static uint32_t gk208_pmu_data[] = {
/* 0x0000: proc_kern */
0x52544e49,
0x00000000,
......@@ -915,7 +915,7 @@ uint32_t gk208_pmu_data[] = {
0x00000000,
};
uint32_t gk208_pmu_code[] = {
static uint32_t gk208_pmu_code[] = {
0x02f90ef5,
/* 0x0004: rd32 */
0xf607a040,
......
uint32_t gt215_pmu_data[] = {
static uint32_t gt215_pmu_data[] = {
/* 0x0000: proc_kern */
0x52544e49,
0x00000000,
......@@ -916,7 +916,7 @@ uint32_t gt215_pmu_data[] = {
0x00000000,
};
uint32_t gt215_pmu_code[] = {
static uint32_t gt215_pmu_code[] = {
0x03920ef5,
/* 0x0004: rd32 */
0x07a007f1,
......
......@@ -24,17 +24,8 @@
#include "priv.h"
#include "fuc/gt215.fuc3.h"
static void
gt215_pmu_reset(struct nvkm_pmu *pmu)
{
struct nvkm_device *device = pmu->subdev.device;
nvkm_mask(device, 0x022210, 0x00000001, 0x00000000);
nvkm_mask(device, 0x022210, 0x00000001, 0x00000001);
}
static const struct nvkm_pmu_func
gt215_pmu = {
.reset = gt215_pmu_reset,
.code.data = gt215_pmu_code,
.code.size = sizeof(gt215_pmu_code),
.data.data = gt215_pmu_data,
......
......@@ -8,8 +8,6 @@ int nvkm_pmu_new_(const struct nvkm_pmu_func *, struct nvkm_device *,
int index, struct nvkm_pmu **);
struct nvkm_pmu_func {
void (*reset)(struct nvkm_pmu *);
struct {
u32 *data;
u32 size;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment