Commit a143bc51 authored by Dave Airlie's avatar Dave Airlie

Merge branch '00.06-gr-ampere' of https://gitlab.freedesktop.org/skeggsb/nouveau into drm-next

This is the pull request for a whole bunch of fixes and prep-work that
was done to support Ampere acceleration prior to GSP-RM being
available.  It uses the ACR firmware released by NVIDIA in
linux-firmware, as we do on earlier GPUs.  The work to support running
on top of GSP-RM also heavily depends on various pieces of this
series.

In addition to the new HW support, general stability of the driver
should be improved, especially around recovering HW from bugs that can
be generated by userspace driver components.
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Ben Skeggs <bskeggs@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/CABDvA==s+nZD0n7CuRWLPE=Pj+02CN13r+ZQJxoHQ_EmR+o=XQ@mail.gmail.com
parents 49e8e634 c4bdac75
......@@ -54,10 +54,6 @@ nouveau-y += nouveau_bios.o
nouveau-y += nouveau_connector.o
nouveau-y += nouveau_display.o
nouveau-y += nouveau_dp.o
nouveau-y += nouveau_fbcon.o
nouveau-y += nv04_fbcon.o
nouveau-y += nv50_fbcon.o
nouveau-y += nvc0_fbcon.o
include $(src)/dispnv04/Kbuild
include $(src)/dispnv50/Kbuild
......
......@@ -23,6 +23,7 @@
* DEALINGS IN THE SOFTWARE.
*/
#include <drm/drm_crtc_helper.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_plane_helper.h>
#include <drm/drm_vblank.h>
......@@ -37,7 +38,6 @@
#include "nouveau_crtc.h"
#include "hw.h"
#include "nvreg.h"
#include "nouveau_fbcon.h"
#include "disp.h"
#include "nouveau_dma.h"
......@@ -761,7 +761,8 @@ static void nv_crtc_destroy(struct drm_crtc *crtc)
nouveau_bo_unmap(nv_crtc->cursor.nvbo);
nouveau_bo_unpin(nv_crtc->cursor.nvbo);
nouveau_bo_ref(NULL, &nv_crtc->cursor.nvbo);
nvif_notify_dtor(&nv_crtc->vblank);
nvif_event_dtor(&nv_crtc->vblank);
nvif_head_dtor(&nv_crtc->head);
kfree(nv_crtc);
}
......@@ -914,14 +915,6 @@ nv04_crtc_mode_set_base_atomic(struct drm_crtc *crtc,
struct drm_framebuffer *fb,
int x, int y, enum mode_set_atomic state)
{
struct nouveau_drm *drm = nouveau_drm(crtc->dev);
struct drm_device *dev = drm->dev;
if (state == ENTER_ATOMIC_MODE_SET)
nouveau_fbcon_accel_save_disable(dev);
else
nouveau_fbcon_accel_restore(dev);
return nv04_crtc_do_mode_set_base(crtc, fb, x, y, true);
}
......@@ -1080,10 +1073,10 @@ nv04_finish_page_flip(struct nouveau_channel *chan,
}
int
nv04_flip_complete(struct nvif_notify *notify)
nv04_flip_complete(struct nvif_event *event, void *argv, u32 argc)
{
struct nouveau_cli *cli = (void *)notify->object->client;
struct nouveau_drm *drm = cli->drm;
struct nv04_display *disp = container_of(event, typeof(*disp), flip);
struct nouveau_drm *drm = disp->drm;
struct nouveau_channel *chan = drm->channel;
struct nv04_page_flip_state state;
......@@ -1094,7 +1087,7 @@ nv04_flip_complete(struct nvif_notify *notify)
state.bpp / 8);
}
return NVIF_NOTIFY_KEEP;
return NVIF_EVENT_KEEP;
}
static int
......@@ -1279,13 +1272,13 @@ static const struct drm_plane_funcs nv04_primary_plane_funcs = {
DRM_PLANE_NON_ATOMIC_FUNCS,
};
static int nv04_crtc_vblank_handler(struct nvif_notify *notify)
static int
nv04_crtc_vblank_handler(struct nvif_event *event, void *repv, u32 repc)
{
struct nouveau_crtc *nv_crtc =
container_of(notify, struct nouveau_crtc, vblank);
struct nouveau_crtc *nv_crtc = container_of(event, struct nouveau_crtc, vblank);
drm_crtc_handle_vblank(&nv_crtc->base);
return NVIF_NOTIFY_KEEP;
return NVIF_EVENT_KEEP;
}
int
......@@ -1341,14 +1334,10 @@ nv04_crtc_create(struct drm_device *dev, int crtc_num)
nv04_cursor_init(nv_crtc);
ret = nvif_notify_ctor(&disp->disp.object, "kmsVbl", nv04_crtc_vblank_handler,
false, NV04_DISP_NTFY_VBLANK,
&(struct nvif_notify_head_req_v0) {
.head = nv_crtc->index,
},
sizeof(struct nvif_notify_head_req_v0),
sizeof(struct nvif_notify_head_rep_v0),
&nv_crtc->vblank);
ret = nvif_head_ctor(&disp->disp, nv_crtc->base.name, nv_crtc->index, &nv_crtc->head);
if (ret)
return ret;
return ret;
return nvif_head_vblank_event_ctor(&nv_crtc->head, "kmsVbl", nv04_crtc_vblank_handler,
false, &nv_crtc->vblank);
}
......@@ -61,7 +61,7 @@ nv04_display_fini(struct drm_device *dev, bool runtime, bool suspend)
struct drm_crtc *crtc;
/* Disable flip completion events. */
nvif_notify_put(&disp->flip);
nvif_event_block(&disp->flip);
/* Disable vblank interrupts. */
NVWriteCRTC(dev, 0, NV_PCRTC_INTR_EN_0, 0);
......@@ -121,7 +121,7 @@ nv04_display_init(struct drm_device *dev, bool resume, bool runtime)
encoder->enc_save(&encoder->base.base);
/* Enable flip completion events. */
nvif_notify_get(&disp->flip);
nvif_event_allow(&disp->flip);
if (!resume)
return 0;
......@@ -202,7 +202,7 @@ nv04_display_destroy(struct drm_device *dev)
nouveau_hw_save_vga_fonts(dev, 0);
nvif_notify_dtor(&disp->flip);
nvif_event_dtor(&disp->flip);
nouveau_display(dev)->priv = NULL;
vfree(disp);
......@@ -227,6 +227,8 @@ nv04_display_create(struct drm_device *dev)
if (!disp)
return -ENOMEM;
disp->drm = drm;
nvif_object_map(&drm->client.device.object, NULL, 0);
nouveau_display(dev)->priv = disp;
......@@ -239,9 +241,10 @@ nv04_display_create(struct drm_device *dev)
/* Request page flip completion event. */
if (drm->channel) {
nvif_notify_ctor(&drm->channel->nvsw, "kmsFlip", nv04_flip_complete,
false, NV04_NVSW_NTFY_UEVENT,
NULL, 0, 0, &disp->flip);
ret = nvif_event_ctor(&drm->channel->nvsw, "kmsFlip", 0, nv04_flip_complete,
true, NULL, 0, &disp->flip);
if (ret)
return ret;
}
nouveau_hw_save_vga_fonts(dev, 1);
......
......@@ -6,6 +6,8 @@
#include "nouveau_display.h"
#include <nvif/event.h>
struct nouveau_encoder;
enum nv04_fp_display_regs {
......@@ -84,7 +86,8 @@ struct nv04_display {
uint32_t saved_vga_font[4][16384];
uint32_t dac_users[4];
struct nouveau_bo *image[2];
struct nvif_notify flip;
struct nvif_event flip;
struct nouveau_drm *drm;
};
static inline struct nv04_display *
......@@ -179,5 +182,5 @@ nouveau_bios_run_init_table(struct drm_device *dev, u16 table,
);
}
int nv04_flip_complete(struct nvif_notify *);
int nv04_flip_complete(struct nvif_event *, void *, u32);
#endif
......@@ -463,7 +463,7 @@ void nv50_crc_atomic_set(struct nv50_head *head,
if (!outp)
return;
func->set_src(head, outp->or, nv50_crc_source_type(outp, asyh->crc.src),
func->set_src(head, outp->outp.or.id, nv50_crc_source_type(outp, asyh->crc.src),
&crc->ctx[crc->ctx_idx]);
}
......
This diff is collapsed.
......@@ -517,7 +517,8 @@ nv50_head_destroy(struct drm_crtc *crtc)
{
struct nv50_head *head = nv50_head(crtc);
nvif_notify_dtor(&head->base.vblank);
nvif_event_dtor(&head->base.vblank);
nvif_head_dtor(&head->base.head);
nv50_lut_fini(&head->olut);
drm_crtc_cleanup(crtc);
kfree(head);
......@@ -554,15 +555,15 @@ nvd9_head_func = {
.late_register = nv50_head_late_register,
};
static int nv50_head_vblank_handler(struct nvif_notify *notify)
static int
nv50_head_vblank_handler(struct nvif_event *event, void *repv, u32 repc)
{
struct nouveau_crtc *nv_crtc =
container_of(notify, struct nouveau_crtc, vblank);
struct nouveau_crtc *nv_crtc = container_of(event, struct nouveau_crtc, vblank);
if (drm_crtc_handle_vblank(&nv_crtc->base))
nv50_crc_handle_vblank(nv50_head(&nv_crtc->base));
return NVIF_NOTIFY_KEEP;
return NVIF_EVENT_KEEP;
}
struct nv50_head *
......@@ -624,14 +625,12 @@ nv50_head_create(struct drm_device *dev, int index)
}
}
ret = nvif_notify_ctor(&disp->disp->object, "kmsVbl", nv50_head_vblank_handler,
false, NV04_DISP_NTFY_VBLANK,
&(struct nvif_notify_head_req_v0) {
.head = nv_crtc->index,
},
sizeof(struct nvif_notify_head_req_v0),
sizeof(struct nvif_notify_head_rep_v0),
&nv_crtc->vblank);
ret = nvif_head_ctor(disp->disp, head->base.base.name, head->base.index, &head->base.head);
if (ret)
return ERR_PTR(ret);
ret = nvif_head_vblank_event_ctor(&head->base.head, "kmsVbl", nv50_head_vblank_handler,
false, &nv_crtc->vblank);
if (ret)
return ERR_PTR(ret);
......
......@@ -39,6 +39,23 @@ struct wpr_header_v1 {
void wpr_header_v1_dump(struct nvkm_subdev *, const struct wpr_header_v1 *);
struct wpr_generic_header {
#define WPR_GENERIC_HEADER_ID_LSF_UCODE_DESC 1
#define WPR_GENERIC_HEADER_ID_LSF_WPR_HEADER 2
#define WPR_GENERIC_HEADER_ID_LSF_SHARED_SUB_WPR 3
#define WPR_GENERIC_HEADER_ID_LSF_LSB_HEADER 4
u16 identifier;
u16 version;
u32 size;
};
struct wpr_header_v2 {
struct wpr_generic_header hdr;
struct wpr_header_v1 wpr;
};
void wpr_header_v2_dump(struct nvkm_subdev *, const struct wpr_header_v2 *);
struct lsf_signature {
u8 prd_keys[2][16];
u8 dbg_keys[2][16];
......@@ -89,6 +106,74 @@ struct lsb_header_v1 {
void lsb_header_v1_dump(struct nvkm_subdev *, struct lsb_header_v1 *);
struct lsb_header_v2 {
struct wpr_generic_header hdr;
struct lsf_signature_v2 {
struct wpr_generic_header hdr;
u32 falcon_id;
u8 prd_present;
u8 dbg_present;
u16 reserved;
u32 sig_size;
u8 prod_sig[2][384 + 128];
u8 debug_sig[2][384 + 128];
u16 sig_algo_ver;
u16 sig_algo;
u16 hash_algo_ver;
u16 hash_algo;
u32 sig_algo_padding_type;
u8 depmap[11 * 2 * 4];
u32 depmap_count;
u8 supports_versioning;
u8 pad[3];
u32 ls_ucode_version;
u32 ls_ucode_id;
u32 ucode_ls_encrypted;
u32 ls_eng_algo_type;
u32 ls_eng_algo_ver;
u8 ls_enc_iv[16];
u8 rsvd[36];
} signature;
u32 ucode_off;
u32 ucode_size;
u32 data_size;
u32 bl_code_size;
u32 bl_imem_off;
u32 bl_data_off;
u32 bl_data_size;
u32 rsvd0;
u32 app_code_off;
u32 app_code_size;
u32 app_data_off;
u32 app_data_size;
u32 app_imem_offset;
u32 app_dmem_offset;
u32 flags;
u32 monitor_code_offset;
u32 monitor_data_offset;
u32 manifest_offset;
struct hs_fmc_params {
u8 hs_fmc;
u8 padding[3];
u16 pkc_algo;
u16 pkc_algo_version;
u32 engid_mask;
u32 ucode_id;
u32 fuse_ver;
u8 pkc_signature[384 + 128];
u8 pkc_key[2048];
u8 rsvd[4];
} hs_fmc_params;
struct hs_ovl_sig_blob_params {
u8 hs_ovl_sig_blob_present;
u32 hs_ovl_sig_blob_offset;
u32 hs_ovl_sig_blob_size;
} hs_ovl_sig_blob_params;
u8 rsvd[20];
};
void lsb_header_v2_dump(struct nvkm_subdev *, struct lsb_header_v2 *);
struct flcn_acr_desc {
union {
u8 reserved_dmem[0x200];
......
......@@ -17,6 +17,20 @@ struct nvfw_hs_header {
const struct nvfw_hs_header *nvfw_hs_header(struct nvkm_subdev *, const void *);
struct nvfw_hs_header_v2 {
u32 sig_prod_offset;
u32 sig_prod_size;
u32 patch_loc;
u32 patch_sig;
u32 meta_data_offset;
u32 meta_data_size;
u32 num_sig;
u32 header_offset;
u32 header_size;
};
const struct nvfw_hs_header_v2 *nvfw_hs_header_v2(struct nvkm_subdev *, const void *);
struct nvfw_hs_load_header {
u32 non_sec_code_off;
u32 non_sec_code_size;
......@@ -28,4 +42,18 @@ struct nvfw_hs_load_header {
const struct nvfw_hs_load_header *
nvfw_hs_load_header(struct nvkm_subdev *, const void *);
struct nvfw_hs_load_header_v2 {
u32 os_code_offset;
u32 os_code_size;
u32 os_data_offset;
u32 os_data_size;
u32 num_apps;
struct {
u32 offset;
u32 size;
} app[0];
};
const struct nvfw_hs_load_header_v2 *nvfw_hs_load_header_v2(struct nvkm_subdev *, const void *);
#endif
......@@ -50,4 +50,55 @@ struct nvfw_ls_desc_v1 {
const struct nvfw_ls_desc_v1 *
nvfw_ls_desc_v1(struct nvkm_subdev *, const void *);
struct nvfw_ls_desc_v2 {
u32 descriptor_size;
u32 image_size;
u32 tools_version;
u32 app_version;
char date[64];
u32 secure_bootloader;
u32 bootloader_start_offset;
u32 bootloader_size;
u32 bootloader_imem_offset;
u32 bootloader_entry_point;
u32 app_start_offset;
u32 app_size;
u32 app_imem_offset;
u32 app_imem_entry;
u32 app_dmem_offset;
u32 app_resident_code_offset;
u32 app_resident_code_size;
u32 app_resident_data_offset;
u32 app_resident_data_size;
u32 nb_imem_overlays;
u32 nb_dmem_overlays;
struct {
u32 start;
u32 size;
} load_ovl[64];
};
const struct nvfw_ls_desc_v2 *nvfw_ls_desc_v2(struct nvkm_subdev *, const void *);
struct nvfw_ls_hsbl_bin_hdr {
u32 bin_magic;
u32 bin_ver;
u32 bin_size;
u32 header_offset;
};
const struct nvfw_ls_hsbl_bin_hdr *nvfw_ls_hsbl_bin_hdr(struct nvkm_subdev *, const void *);
struct nvfw_ls_hsbl_hdr {
u32 sig_prod_offset;
u32 sig_prod_size;
u32 patch_loc;
u32 patch_sig;
u32 meta_data_offset;
u32 meta_data_size;
u32 num_sig;
};
const struct nvfw_ls_hsbl_hdr *nvfw_ls_hsbl_hdr(struct nvkm_subdev *, const void *);
#endif
......@@ -10,6 +10,7 @@ struct nv_sec2_args {
};
#define NV_SEC2_UNIT_INIT 0x01
#define NV_SEC2_UNIT_UNLOAD 0x06
#define NV_SEC2_UNIT_ACR 0x08
struct nv_sec2_init_msg {
......@@ -33,6 +34,29 @@ struct nv_sec2_init_msg {
u16 sw_managed_area_size;
};
struct nv_sec2_init_msg_v1 {
struct nvfw_falcon_msg hdr;
#define NV_SEC2_INIT_MSG_INIT 0x00
u8 msg_type;
u8 num_queues;
u16 os_debug_entry_point;
struct {
u32 offset;
u16 size;
u8 index;
#define NV_SEC2_INIT_MSG_QUEUE_ID_CMDQ 0x00
#define NV_SEC2_INIT_MSG_QUEUE_ID_MSGQ 0x01
u8 id;
} queue_info[2];
u32 sw_managed_area_offset;
u16 sw_managed_area_size;
u32 unkn[8];
};
struct nv_sec2_acr_cmd {
struct nvfw_falcon_cmd hdr;
#define NV_SEC2_ACR_CMD_BOOTSTRAP_FALCON 0x00
......@@ -57,4 +81,25 @@ struct nv_sec2_acr_bootstrap_falcon_msg {
u32 error_code;
u32 falcon_id;
};
#define NV_SEC2_UNIT_V2_INIT 0x01
#define NV_SEC2_UNIT_V2_UNLOAD 0x05
#define NV_SEC2_UNIT_V2_ACR 0x07
struct nv_sec2_acr_bootstrap_falcon_cmd_v1 {
struct nv_sec2_acr_cmd cmd;
#define NV_SEC2_ACR_BOOTSTRAP_FALCON_FLAGS_RESET_YES 0x00000000
#define NV_SEC2_ACR_BOOTSTRAP_FALCON_FLAGS_RESET_NO 0x00000001
u32 flags;
u32 falcon_id;
u32 unkn08;
u32 unkn0c;
};
struct nv_sec2_acr_bootstrap_falcon_msg_v1 {
struct nv_sec2_acr_msg msg;
u32 error_code;
u32 falcon_id;
u32 unkn08;
};
#endif
......@@ -2,28 +2,5 @@
#ifndef __NVIF_CL0046_H__
#define __NVIF_CL0046_H__
#define NV04_DISP_NTFY_VBLANK 0x00
#define NV04_DISP_NTFY_CONN 0x01
struct nv04_disp_mthd_v0 {
__u8 version;
#define NV04_DISP_SCANOUTPOS 0x00
__u8 method;
__u8 head;
__u8 pad03[5];
};
struct nv04_disp_scanoutpos_v0 {
__u8 version;
__u8 pad01[7];
__s64 time[2];
__u16 vblanks;
__u16 vblanke;
__u16 vtotal;
__u16 vline;
__u16 hblanks;
__u16 hblanke;
__u16 htotal;
__u16 hline;
};
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVIF_CL006B_H__
#define __NVIF_CL006B_H__
struct nv03_channel_dma_v0 {
__u8 version;
__u8 chid;
__u8 pad02[2];
__u32 offset;
__u64 pushbuf;
};
#endif
......@@ -68,7 +68,7 @@ struct nv_device_time_v0 {
/* Returns the number of available runlists. */
#define NV_DEVICE_HOST_RUNLISTS NV_DEVICE_HOST(0x00000000)
/* Returns the number of available channels. */
/* Returns the number of available channels (0 if per-runlist). */
#define NV_DEVICE_HOST_CHANNELS NV_DEVICE_HOST(0x00000001)
/* Returns a mask of available engine types on runlist(data). */
......@@ -90,4 +90,6 @@ struct nv_device_time_v0 {
#define NV_DEVICE_HOST_RUNLIST_ENGINES_SEC2 0x00004000
#define NV_DEVICE_HOST_RUNLIST_ENGINES_NVDEC 0x00008000
#define NV_DEVICE_HOST_RUNLIST_ENGINES_NVENC 0x00010000
/* Returns the number of available channels on runlist(data). */
#define NV_DEVICE_HOST_RUNLIST_CHANNELS NV_DEVICE_HOST(0x00000101)
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVIF_CL506E_H__
#define __NVIF_CL506E_H__
struct nv50_channel_dma_v0 {
__u8 version;
__u8 chid;
__u8 pad02[6];
__u64 vmm;
__u64 pushbuf;
__u64 offset;
};
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVIF_CL506F_H__
#define __NVIF_CL506F_H__
struct nv50_channel_gpfifo_v0 {
__u8 version;
__u8 chid;
__u8 pad02[2];
__u32 ilength;
__u64 ioffset;
__u64 pushbuf;
__u64 vmm;
};
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVIF_CL5070_H__
#define __NVIF_CL5070_H__
#define NV50_DISP_MTHD 0x00
struct nv50_disp_mthd_v0 {
__u8 version;
#define NV50_DISP_SCANOUTPOS 0x00
__u8 method;
__u8 head;
__u8 pad03[5];
};
struct nv50_disp_scanoutpos_v0 {
__u8 version;
__u8 pad01[7];
__s64 time[2];
__u16 vblanks;
__u16 vblanke;
__u16 vtotal;
__u16 vline;
__u16 hblanks;
__u16 hblanke;
__u16 htotal;
__u16 hline;
};
struct nv50_disp_mthd_v1 {
__u8 version;
#define NV50_DISP_MTHD_V1_ACQUIRE 0x01
#define NV50_DISP_MTHD_V1_RELEASE 0x02
#define NV50_DISP_MTHD_V1_SOR_HDA_ELD 0x21
#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_MST_LINK 0x25
#define NV50_DISP_MTHD_V1_SOR_DP_MST_VCPI 0x26
__u8 method;
__u16 hasht;
__u16 hashm;
__u8 pad06[2];
};
struct nv50_disp_acquire_v0 {
__u8 version;
__u8 or;
__u8 link;
__u8 hda;
__u8 pad04[4];
};
struct nv50_disp_sor_hda_eld_v0 {
__u8 version;
__u8 pad01[7];
__u8 data[];
};
struct nv50_disp_sor_hdmi_pwr_v0 {
__u8 version;
__u8 state;
__u8 max_ac_packet;
__u8 rekey;
__u8 avi_infoframe_length;
__u8 vendor_infoframe_length;
#define NV50_DISP_SOR_HDMI_PWR_V0_SCDC_SCRAMBLE (1 << 0)
#define NV50_DISP_SOR_HDMI_PWR_V0_SCDC_DIV_BY_4 (1 << 1)
__u8 scdc;
__u8 pad07[1];
};
struct nv50_disp_sor_lvds_script_v0 {
__u8 version;
__u8 pad01[1];
__u16 script;
__u8 pad04[4];
};
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;
};
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVIF_CL826E_H__
#define __NVIF_CL826E_H__
struct g82_channel_dma_v0 {
__u8 version;
__u8 chid;
__u8 pad02[6];
__u64 vmm;
__u64 pushbuf;
__u64 offset;
};
#define NV826E_V0_NTFY_NON_STALL_INTERRUPT 0x00
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVIF_CL826F_H__
#define __NVIF_CL826F_H__
struct g82_channel_gpfifo_v0 {
__u8 version;
__u8 chid;
__u8 pad02[2];
__u32 ilength;
__u64 ioffset;
__u64 pushbuf;
__u64 vmm;
};
#define NV826F_V0_NTFY_NON_STALL_INTERRUPT 0x00
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVIF_CL906F_H__
#define __NVIF_CL906F_H__
struct fermi_channel_gpfifo_v0 {
__u8 version;
__u8 chid;
__u8 pad02[2];
__u32 ilength;
__u64 ioffset;
__u64 vmm;
};
#define NV906F_V0_NTFY_NON_STALL_INTERRUPT 0x00
#define NV906F_V0_NTFY_KILLED 0x01
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVIF_CLA06F_H__
#define __NVIF_CLA06F_H__
struct kepler_channel_gpfifo_a_v0 {
__u8 version;
__u8 priv;
__u16 chid;
__u32 ilength;
__u64 ioffset;
__u64 runlist;
__u64 vmm;
__u64 inst;
};
#define NVA06F_V0_NTFY_NON_STALL_INTERRUPT 0x00
#define NVA06F_V0_NTFY_KILLED 0x01
#endif
......@@ -32,11 +32,17 @@
#define NVIF_CLASS_VMM_GM200 /* ifb00d.h */ 0x8000b00d
#define NVIF_CLASS_VMM_GP100 /* ifc00d.h */ 0x8000c00d
#define NVIF_CLASS_EVENT /* if000e.h */ 0x8000000e
#define NVIF_CLASS_DISP /* if0010.h */ 0x80000010
#define NVIF_CLASS_CONN /* if0011.h */ 0x80000011
#define NVIF_CLASS_OUTP /* if0012.h */ 0x80000012
#define NVIF_CLASS_HEAD /* if0013.h */ 0x80000013
#define NVIF_CLASS_DISP_CHAN /* if0014.h */ 0x80000014
#define NVIF_CLASS_CHAN /* if0020.h */ 0x80000020
#define NVIF_CLASS_CGRP /* if0021.h */ 0x80000021
/* the below match nvidia-assigned (either in hw, or sw) class numbers */
#define NV_NULL_CLASS 0x00000030
......@@ -58,25 +64,30 @@
#define NV04_DISP /* cl0046.h */ 0x00000046
#define VOLTA_USERMODE_A 0x0000c361
#define TURING_USERMODE_A 0x0000c461
#define AMPERE_USERMODE_A 0x0000c561
#define MAXWELL_FAULT_BUFFER_A /* clb069.h */ 0x0000b069
#define VOLTA_FAULT_BUFFER_A /* clb069.h */ 0x0000c369
#define NV03_CHANNEL_DMA /* cl506b.h */ 0x0000006b
#define NV10_CHANNEL_DMA /* cl506b.h */ 0x0000006e
#define NV17_CHANNEL_DMA /* cl506b.h */ 0x0000176e
#define NV40_CHANNEL_DMA /* cl506b.h */ 0x0000406e
#define NV50_CHANNEL_GPFIFO /* cl506f.h */ 0x0000506f
#define G82_CHANNEL_GPFIFO /* cl826f.h */ 0x0000826f
#define FERMI_CHANNEL_GPFIFO /* cl906f.h */ 0x0000906f
#define KEPLER_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000a06f
#define KEPLER_CHANNEL_GPFIFO_B /* cla06f.h */ 0x0000a16f
#define MAXWELL_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000b06f
#define PASCAL_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000c06f
#define VOLTA_CHANNEL_GPFIFO_A /* clc36f.h */ 0x0000c36f
#define TURING_CHANNEL_GPFIFO_A /* clc36f.h */ 0x0000c46f
#define AMPERE_CHANNEL_GPFIFO_B /* clc36f.h */ 0x0000c76f
#define NV03_CHANNEL_DMA /* if0020.h */ 0x0000006b
#define NV10_CHANNEL_DMA /* if0020.h */ 0x0000006e
#define NV17_CHANNEL_DMA /* if0020.h */ 0x0000176e
#define NV40_CHANNEL_DMA /* if0020.h */ 0x0000406e
#define KEPLER_CHANNEL_GROUP_A /* if0021.h */ 0x0000a06c
#define NV50_CHANNEL_GPFIFO /* if0020.h */ 0x0000506f
#define G82_CHANNEL_GPFIFO /* if0020.h */ 0x0000826f
#define FERMI_CHANNEL_GPFIFO /* if0020.h */ 0x0000906f
#define KEPLER_CHANNEL_GPFIFO_A /* if0020.h */ 0x0000a06f
#define KEPLER_CHANNEL_GPFIFO_B /* if0020.h */ 0x0000a16f
#define MAXWELL_CHANNEL_GPFIFO_A /* if0020.h */ 0x0000b06f
#define PASCAL_CHANNEL_GPFIFO_A /* if0020.h */ 0x0000c06f
#define VOLTA_CHANNEL_GPFIFO_A /* if0020.h */ 0x0000c36f
#define TURING_CHANNEL_GPFIFO_A /* if0020.h */ 0x0000c46f
#define AMPERE_CHANNEL_GPFIFO_A /* if0020.h */ 0x0000c56f
#define AMPERE_CHANNEL_GPFIFO_B /* if0020.h */ 0x0000c76f
#define NV50_DISP /* if0010.h */ 0x00005070
#define G82_DISP /* if0010.h */ 0x00008270
......@@ -179,6 +190,8 @@
#define TURING_A /* cl9097.h */ 0x0000c597
#define AMPERE_B /* cl9097.h */ 0x0000c797
#define NV74_BSP 0x000074b0
#define GT212_MSVLD 0x000085b1
......@@ -206,6 +219,7 @@
#define PASCAL_DMA_COPY_B 0x0000c1b5
#define VOLTA_DMA_COPY_A 0x0000c3b5
#define TURING_DMA_COPY_A 0x0000c5b5
#define AMPERE_DMA_COPY_A 0x0000c6b5
#define AMPERE_DMA_COPY_B 0x0000c7b5
#define FERMI_DECOMPRESS 0x000090b8
......@@ -222,6 +236,7 @@
#define PASCAL_COMPUTE_B 0x0000c1c0
#define VOLTA_COMPUTE_A 0x0000c3c0
#define TURING_COMPUTE_A 0x0000c5c0
#define AMPERE_COMPUTE_B 0x0000c7c0
#define NV74_CIPHER 0x000074c1
#endif
......@@ -8,5 +8,8 @@ struct nvif_clb069_v0 {
__u32 put;
};
#define NVB069_V0_NTFY_FAULT 0x00
union nvif_clb069_event_args {
struct nvif_clb069_event_vn {
} vn;
};
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVIF_CLC36F_H__
#define __NVIF_CLC36F_H__
struct volta_channel_gpfifo_a_v0 {
__u8 version;
__u8 priv;
__u16 chid;
__u32 ilength;
__u64 ioffset;
__u64 runlist;
__u64 vmm;
__u64 inst;
__u32 token;
};
#define NVC36F_V0_NTFY_NON_STALL_INTERRUPT 0x00
#define NVC36F_V0_NTFY_KILLED 0x01
#endif
......@@ -2,6 +2,7 @@
#ifndef __NVIF_CONN_H__
#define __NVIF_CONN_H__
#include <nvif/object.h>
#include <nvif/event.h>
struct nvif_disp;
struct nvif_conn {
......@@ -11,8 +12,17 @@ struct nvif_conn {
int nvif_conn_ctor(struct nvif_disp *, const char *name, int id, struct nvif_conn *);
void nvif_conn_dtor(struct nvif_conn *);
static inline int
nvif_conn_id(struct nvif_conn *conn)
{
return conn->object.handle;
}
#define NVIF_CONN_HPD_STATUS_UNSUPPORTED 0 /* negative if query fails */
#define NVIF_CONN_HPD_STATUS_NOT_PRESENT 1
#define NVIF_CONN_HPD_STATUS_PRESENT 2
int nvif_conn_hpd_status(struct nvif_conn *);
int nvif_conn_event_ctor(struct nvif_conn *, const char *name, nvif_event_func, u8 types,
struct nvif_event *);
#endif
......@@ -7,6 +7,7 @@ struct nvif_disp {
struct nvif_object object;
unsigned long conn_mask;
unsigned long outp_mask;
unsigned long head_mask;
};
int nvif_disp_ctor(struct nvif_device *, const char *name, s32 oclass,
......
/* SPDX-License-Identifier: MIT */
#ifndef __NVIF_EVENT_H__
#define __NVIF_EVENT_H__
struct nvif_notify_req_v0 {
__u8 version;
__u8 reply;
__u8 pad02[5];
#define NVIF_NOTIFY_V0_ROUTE_NVIF 0x00
__u8 route;
__u64 token; /* must be unique */
__u8 data[]; /* request data (below) */
};
struct nvif_notify_rep_v0 {
__u8 version;
__u8 pad01[6];
__u8 route;
__u64 token;
__u8 data[]; /* reply data (below) */
};
struct nvif_notify_head_req_v0 {
/* nvif_notify_req ... */
__u8 version;
__u8 head;
__u8 pad02[6];
};
struct nvif_notify_head_rep_v0 {
/* nvif_notify_rep ... */
__u8 version;
__u8 pad01[7];
};
struct nvif_notify_conn_req_v0 {
/* nvif_notify_req ... */
__u8 version;
#define NVIF_NOTIFY_CONN_V0_PLUG 0x01
#define NVIF_NOTIFY_CONN_V0_UNPLUG 0x02
#define NVIF_NOTIFY_CONN_V0_IRQ 0x04
#define NVIF_NOTIFY_CONN_V0_ANY 0x07
__u8 mask;
__u8 conn;
__u8 pad03[5];
};
struct nvif_notify_conn_rep_v0 {
/* nvif_notify_rep ... */
__u8 version;
__u8 mask;
__u8 pad02[6];
};
struct nvif_notify_uevent_req {
/* nvif_notify_req ... */
};
struct nvif_notify_uevent_rep {
/* nvif_notify_rep ... */
};
#include <nvif/object.h>
#include <nvif/if000e.h>
struct nvif_event;
#define NVIF_EVENT_KEEP 0
#define NVIF_EVENT_DROP 1
typedef int (*nvif_event_func)(struct nvif_event *, void *repv, u32 repc);
struct nvif_event {
struct nvif_object object;
nvif_event_func func;
};
static inline bool
nvif_event_constructed(struct nvif_event *event)
{
return nvif_object_constructed(&event->object);
}
int nvif_event_ctor_(struct nvif_object *, const char *, u32, nvif_event_func, bool,
struct nvif_event_v0 *, u32, bool, struct nvif_event *);
static inline int
nvif_event_ctor(struct nvif_object *parent, const char *name, u32 handle, nvif_event_func func,
bool wait, struct nvif_event_v0 *args, u32 argc, struct nvif_event *event)
{
return nvif_event_ctor_(parent, name, handle, func, wait, args, argc, true, event);
}
void nvif_event_dtor(struct nvif_event *);
int nvif_event_allow(struct nvif_event *);
int nvif_event_block(struct nvif_event *);
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVIF_HEAD_H__
#define __NVIF_HEAD_H__
#include <nvif/object.h>
#include <nvif/event.h>
struct nvif_disp;
struct nvif_head {
struct nvif_object object;
};
int nvif_head_ctor(struct nvif_disp *, const char *name, int id, struct nvif_head *);
void nvif_head_dtor(struct nvif_head *);
static inline int
nvif_head_id(struct nvif_head *head)
{
return head->object.handle;
}
int nvif_head_vblank_event_ctor(struct nvif_head *, const char *name, nvif_event_func, bool wait,
struct nvif_event *);
#endif
......@@ -2,7 +2,10 @@
#ifndef __NVIF_IF0004_H__
#define __NVIF_IF0004_H__
#define NV04_NVSW_NTFY_UEVENT 0x00
union nv04_nvsw_event_args {
struct nv04_nvsw_event_vn {
} vn;
};
#define NV04_NVSW_GET_REF 0x00
......
/* SPDX-License-Identifier: MIT */
#ifndef __NVIF_IF000E_H__
#define __NVIF_IF000E_H__
union nvif_event_args {
struct nvif_event_v0 {
__u8 version;
__u8 wait;
__u8 pad02[6];
__u8 data[];
} v0;
};
#define NVIF_EVENT_V0_ALLOW 0x00
#define NVIF_EVENT_V0_BLOCK 0x01
union nvif_event_allow_args {
struct nvif_event_allow_vn {
} vn;
};
union nvif_event_block_args {
struct nvif_event_block_vn {
} vn;
};
#endif
......@@ -8,6 +8,7 @@ union nvif_disp_args {
__u8 pad01[3];
__u32 conn_mask;
__u32 outp_mask;
__u32 head_mask;
} v0;
};
#endif
......@@ -10,6 +10,17 @@ union nvif_conn_args {
} v0;
};
union nvif_conn_event_args {
struct nvif_conn_event_v0 {
__u8 version;
#define NVIF_CONN_EVENT_V0_PLUG 0x01
#define NVIF_CONN_EVENT_V0_UNPLUG 0x02
#define NVIF_CONN_EVENT_V0_IRQ 0x04
__u8 types;
__u8 pad02[6];
} v0;
};
#define NVIF_CONN_V0_HPD_STATUS 0x00000000
union nvif_conn_hpd_status_args {
......
......@@ -11,6 +11,13 @@ union nvif_outp_args {
};
#define NVIF_OUTP_V0_LOAD_DETECT 0x00
#define NVIF_OUTP_V0_ACQUIRE 0x01
#define NVIF_OUTP_V0_RELEASE 0x02
#define NVIF_OUTP_V0_INFOFRAME 0x03
#define NVIF_OUTP_V0_HDA_ELD 0x04
#define NVIF_OUTP_V0_DP_AUX_PWR 0x05
#define NVIF_OUTP_V0_DP_RETRAIN 0x06
#define NVIF_OUTP_V0_DP_MST_VCPI 0x07
union nvif_outp_load_detect_args {
struct nvif_outp_load_detect_v0 {
......@@ -20,4 +27,95 @@ union nvif_outp_load_detect_args {
__u32 data; /*TODO: move vbios loadval parsing into nvkm */
} v0;
};
union nvif_outp_acquire_args {
struct nvif_outp_acquire_v0 {
__u8 version;
#define NVIF_OUTP_ACQUIRE_V0_RGB_CRT 0x00
#define NVIF_OUTP_ACQUIRE_V0_TV 0x01
#define NVIF_OUTP_ACQUIRE_V0_TMDS 0x02
#define NVIF_OUTP_ACQUIRE_V0_LVDS 0x03
#define NVIF_OUTP_ACQUIRE_V0_DP 0x04
__u8 proto;
__u8 or;
__u8 link;
__u8 pad04[4];
union {
struct {
__u8 head;
__u8 hdmi;
__u8 hdmi_max_ac_packet;
__u8 hdmi_rekey;
#define NVIF_OUTP_ACQUIRE_V0_TMDS_HDMI_SCDC_SCRAMBLE (1 << 0)
#define NVIF_OUTP_ACQUIRE_V0_TMDS_HDMI_SCDC_DIV_BY_4 (1 << 1)
__u8 hdmi_scdc;
__u8 hdmi_hda;
__u8 pad06[2];
} tmds;
struct {
__u8 dual;
__u8 bpc8;
__u8 pad02[6];
} lvds;
struct {
__u8 link_nr; /* 0 = highest possible. */
__u8 link_bw; /* 0 = highest possible, DP BW code otherwise. */
__u8 hda;
__u8 mst;
__u8 pad04[4];
__u8 dpcd[16];
} dp;
};
} v0;
};
union nvif_outp_release_args {
struct nvif_outp_release_vn {
} vn;
};
union nvif_outp_infoframe_args {
struct nvif_outp_infoframe_v0 {
__u8 version;
#define NVIF_OUTP_INFOFRAME_V0_AVI 0
#define NVIF_OUTP_INFOFRAME_V0_VSI 1
__u8 type;
__u8 head;
__u8 pad03[5];
__u8 data[];
} v0;
};
union nvif_outp_hda_eld_args {
struct nvif_outp_hda_eld_v0 {
__u8 version;
__u8 head;
__u8 pad02[6];
__u8 data[];
} v0;
};
union nvif_outp_dp_aux_pwr_args {
struct nvif_outp_dp_aux_pwr_v0 {
__u8 version;
__u8 state;
__u8 pad02[6];
} v0;
};
union nvif_outp_dp_retrain_args {
struct nvif_outp_dp_retrain_vn {
} vn;
};
union nvif_outp_dp_mst_vcpi_args {
struct nvif_outp_dp_mst_vcpi_v0 {
__u8 version;
__u8 head;
__u8 start_slot;
__u8 num_slots;
__u16 pbn;
__u16 aligned_pbn;
} v0;
};
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVIF_IF0013_H__
#define __NVIF_IF0013_H__
union nvif_head_args {
struct nvif_head_v0 {
__u8 version;
__u8 id;
__u8 pad02[6];
} v0;
};
union nvif_head_event_args {
struct nvif_head_event_vn {
} vn;
};
#define NVIF_HEAD_V0_SCANOUTPOS 0x00
union nvif_head_scanoutpos_args {
struct nvif_head_scanoutpos_v0 {
__u8 version;
__u8 pad01[7];
__s64 time[2];
__u16 vblanks;
__u16 vblanke;
__u16 vtotal;
__u16 vline;
__u16 hblanks;
__u16 hblanke;
__u16 htotal;
__u16 hline;
} v0;
};
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVIF_IF0020_H__
#define __NVIF_IF0020_H__
union nvif_chan_args {
struct nvif_chan_v0 {
__u8 version;
__u8 namelen;
__u8 runlist;
__u8 runq;
__u8 priv;
__u8 pad05;
__u16 devm;
__u64 vmm;
__u64 ctxdma;
__u64 offset;
__u64 length;
__u64 huserd;
__u64 ouserd;
__u32 token;
__u16 chid;
__u8 pad3e;
#define NVIF_CHAN_V0_INST_APER_VRAM 0
#define NVIF_CHAN_V0_INST_APER_HOST 1
#define NVIF_CHAN_V0_INST_APER_NCOH 2
#define NVIF_CHAN_V0_INST_APER_INST 0xff
__u8 aper;
__u64 inst;
__u8 name[];
} v0;
};
union nvif_chan_event_args {
struct nvif_chan_event_v0 {
__u8 version;
#define NVIF_CHAN_EVENT_V0_NON_STALL_INTR 0x00
#define NVIF_CHAN_EVENT_V0_KILLED 0x01
__u8 type;
} v0;
};
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVIF_IF0021_H__
#define __NVIF_IF0021_H__
union nvif_cgrp_args {
struct nvif_cgrp_v0 {
__u8 version;
__u8 namelen;
__u8 runlist;
__u8 pad03[3];
__u16 cgid;
__u64 vmm;
__u8 name[];
} v0;
};
#endif
......@@ -15,10 +15,6 @@ struct nvif_ioctl_v0 {
#define NVIF_IOCTL_V0_WR 0x06
#define NVIF_IOCTL_V0_MAP 0x07
#define NVIF_IOCTL_V0_UNMAP 0x08
#define NVIF_IOCTL_V0_NTFY_NEW 0x09
#define NVIF_IOCTL_V0_NTFY_DEL 0x0a
#define NVIF_IOCTL_V0_NTFY_GET 0x0b
#define NVIF_IOCTL_V0_NTFY_PUT 0x0c
__u8 type;
__u8 pad02[4];
#define NVIF_IOCTL_V0_OWNER_NVIF 0x00
......@@ -63,6 +59,14 @@ struct nvif_ioctl_new_v0 {
struct nvif_ioctl_del {
};
struct nvif_ioctl_mthd_v0 {
/* nvif_ioctl ... */
__u8 version;
__u8 method;
__u8 pad02[6];
__u8 data[]; /* method data (class.h) */
};
struct nvif_ioctl_rd_v0 {
/* nvif_ioctl ... */
__u8 version;
......@@ -95,43 +99,4 @@ struct nvif_ioctl_map_v0 {
struct nvif_ioctl_unmap {
};
struct nvif_ioctl_ntfy_new_v0 {
/* nvif_ioctl ... */
__u8 version;
__u8 event;
__u8 index;
__u8 pad03[5];
__u8 data[]; /* event request data (event.h) */
};
struct nvif_ioctl_ntfy_del_v0 {
/* nvif_ioctl ... */
__u8 version;
__u8 index;
__u8 pad02[6];
};
struct nvif_ioctl_ntfy_get_v0 {
/* nvif_ioctl ... */
__u8 version;
__u8 index;
__u8 pad02[6];
};
struct nvif_ioctl_ntfy_put_v0 {
/* nvif_ioctl ... */
__u8 version;
__u8 index;
__u8 pad02[6];
};
struct nvif_ioctl_mthd_v0 {
/* nvif_ioctl ... */
__u8 version;
__u8 method;
__u8 pad02[6];
__u8 data[]; /* method data (class.h) */
};
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVIF_NOTIFY_H__
#define __NVIF_NOTIFY_H__
struct nvif_notify {
struct nvif_object *object;
const char *name;
int index;
#define NVIF_NOTIFY_USER 0
#define NVIF_NOTIFY_WORK 1
unsigned long flags;
atomic_t putcnt;
void (*dtor)(struct nvif_notify *);
#define NVIF_NOTIFY_DROP 0
#define NVIF_NOTIFY_KEEP 1
int (*func)(struct nvif_notify *);
/* this is const for a *very* good reason - the data might be on the
* stack from an irq handler. if you're not nvif/notify.c then you
* should probably think twice before casting it away...
*/
const void *data;
u32 size;
struct work_struct work;
};
int nvif_notify_ctor(struct nvif_object *, const char *name,
int (*func)(struct nvif_notify *), bool work, u8 type,
void *data, u32 size, u32 reply, struct nvif_notify *);
int nvif_notify_dtor(struct nvif_notify *);
int nvif_notify_get(struct nvif_notify *);
int nvif_notify_put(struct nvif_notify *);
int nvif_notify(const void *, u32, const void *, u32);
#endif
......@@ -2,13 +2,32 @@
#ifndef __NVIF_OUTP_H__
#define __NVIF_OUTP_H__
#include <nvif/object.h>
#include <nvif/if0012.h>
struct nvif_disp;
struct nvif_outp {
struct nvif_object object;
struct {
int id;
int link;
} or;
};
int nvif_outp_ctor(struct nvif_disp *, const char *name, int id, struct nvif_outp *);
void nvif_outp_dtor(struct nvif_outp *);
int nvif_outp_load_detect(struct nvif_outp *, u32 loadval);
int nvif_outp_acquire_rgb_crt(struct nvif_outp *);
int nvif_outp_acquire_tmds(struct nvif_outp *, int head,
bool hdmi, u8 max_ac_packet, u8 rekey, u8 scdc, bool hda);
int nvif_outp_acquire_lvds(struct nvif_outp *, bool dual, bool bpc8);
int nvif_outp_acquire_dp(struct nvif_outp *, u8 dpcd[16],
int link_nr, int link_bw, bool hda, bool mst);
void nvif_outp_release(struct nvif_outp *);
int nvif_outp_infoframe(struct nvif_outp *, u8 type, struct nvif_outp_infoframe_v0 *, u32 size);
int nvif_outp_hda_eld(struct nvif_outp *, int head, void *data, u32 size);
int nvif_outp_dp_aux_pwr(struct nvif_outp *, bool enable);
int nvif_outp_dp_retrain(struct nvif_outp *);
int nvif_outp_dp_mst_vcpi(struct nvif_outp *, int head,
u8 start_slot, u8 num_slots, u16 pbn, u16 aligned_pbn);
#endif
......@@ -10,28 +10,19 @@ struct nvkm_client {
u64 device;
u32 debug;
struct nvkm_client_notify *notify[32];
struct rb_root objroot;
void *data;
int (*ntfy)(const void *, u32, const void *, u32);
int (*event)(u64 token, void *argv, u32 argc);
struct list_head umem;
spinlock_t lock;
};
int nvkm_client_new(const char *name, u64 device, const char *cfg,
const char *dbg,
int (*)(const void *, u32, const void *, u32),
struct nvkm_client **);
int nvkm_client_new(const char *name, u64 device, const char *cfg, const char *dbg,
int (*)(u64, void *, u32), struct nvkm_client **);
struct nvkm_client *nvkm_client_search(struct nvkm_client *, u64 handle);
int nvkm_client_notify_new(struct nvkm_object *, struct nvkm_event *,
void *data, u32 size);
int nvkm_client_notify_del(struct nvkm_client *, int index);
int nvkm_client_notify_get(struct nvkm_client *, int index);
int nvkm_client_notify_put(struct nvkm_client *, int index);
/* logging for client-facing objects */
#define nvif_printk(o,l,p,f,a...) do { \
const struct nvkm_object *_object = (o); \
......
......@@ -2,6 +2,7 @@
#ifndef __NVKM_DEVICE_H__
#define __NVKM_DEVICE_H__
#include <core/oclass.h>
#include <core/intr.h>
enum nvkm_subdev_type;
enum nvkm_device_type {
......@@ -60,6 +61,16 @@ struct nvkm_device {
#undef NVKM_LAYOUT_INST
#undef NVKM_LAYOUT_ONCE
struct list_head subdev;
struct {
struct list_head intr;
struct list_head prio[NVKM_INTR_PRIO_NR];
spinlock_t lock;
int irq;
bool alloc;
bool armed;
bool legacy_done;
} intr;
};
struct nvkm_subdev *nvkm_device_subdev(struct nvkm_device *, int type, int inst);
......@@ -72,6 +83,7 @@ struct nvkm_device_func {
int (*preinit)(struct nvkm_device *);
int (*init)(struct nvkm_device *);
void (*fini)(struct nvkm_device *, bool suspend);
int (*irq)(struct nvkm_device *);
resource_size_t (*resource_addr)(struct nvkm_device *, unsigned bar);
resource_size_t (*resource_size)(struct nvkm_device *, unsigned bar);
bool cpu_coherent;
......
......@@ -12,12 +12,6 @@ struct nvkm_engine {
const struct nvkm_engine_func *func;
struct nvkm_subdev subdev;
spinlock_t lock;
struct {
refcount_t refcount;
struct mutex mutex;
bool enabled;
} use;
};
struct nvkm_engine_func {
......@@ -27,6 +21,7 @@ struct nvkm_engine_func {
int (*info)(struct nvkm_engine *, u64 mthd, u64 *data);
int (*init)(struct nvkm_engine *);
int (*fini)(struct nvkm_engine *, bool suspend);
int (*reset)(struct nvkm_engine *);
void (*intr)(struct nvkm_engine *);
void (*tile)(struct nvkm_engine *, int region, struct nvkm_fb_tile *);
bool (*chsw_load)(struct nvkm_engine *);
......@@ -54,6 +49,7 @@ int nvkm_engine_new_(const struct nvkm_engine_func *, struct nvkm_device *,
struct nvkm_engine *nvkm_engine_ref(struct nvkm_engine *);
void nvkm_engine_unref(struct nvkm_engine **);
int nvkm_engine_reset(struct nvkm_engine *);
void nvkm_engine_tile(struct nvkm_engine *, int region);
bool nvkm_engine_chsw_load(struct nvkm_engine *);
#endif
......@@ -2,34 +2,76 @@
#ifndef __NVKM_EVENT_H__
#define __NVKM_EVENT_H__
#include <core/os.h>
struct nvkm_notify;
struct nvkm_object;
struct nvkm_oclass;
struct nvkm_uevent;
struct nvkm_event {
const struct nvkm_event_func *func;
struct nvkm_subdev *subdev;
int types_nr;
int index_nr;
spinlock_t refs_lock;
spinlock_t list_lock;
struct list_head list;
int *refs;
struct list_head ntfy;
};
struct nvkm_event_func {
int (*ctor)(struct nvkm_object *, void *data, u32 size,
struct nvkm_notify *);
void (*send)(void *data, u32 size, struct nvkm_notify *);
void (*init)(struct nvkm_event *, int type, int index);
void (*fini)(struct nvkm_event *, int type, int index);
};
int nvkm_event_init(const struct nvkm_event_func *func, int types_nr,
int index_nr, struct nvkm_event *);
int __nvkm_event_init(const struct nvkm_event_func *func, struct nvkm_subdev *, int types_nr,
int index_nr, struct nvkm_event *);
/* Each nvkm_event needs its own lockdep class due to inter-dependencies, to
* prevent lockdep false-positives.
*
* Inlining the spinlock initialisation ensures each is unique.
*/
static __always_inline int
nvkm_event_init(const struct nvkm_event_func *func, struct nvkm_subdev *subdev,
int types_nr, int index_nr, struct nvkm_event *event)
{
spin_lock_init(&event->refs_lock);
spin_lock_init(&event->list_lock);
return __nvkm_event_init(func, subdev, types_nr, index_nr, event);
}
void nvkm_event_fini(struct nvkm_event *);
void nvkm_event_get(struct nvkm_event *, u32 types, int index);
void nvkm_event_put(struct nvkm_event *, u32 types, int index);
void nvkm_event_send(struct nvkm_event *, u32 types, int index,
void *data, u32 size);
#define NVKM_EVENT_KEEP 0
#define NVKM_EVENT_DROP 1
struct nvkm_event_ntfy;
typedef int (*nvkm_event_func)(struct nvkm_event_ntfy *, u32 bits);
struct nvkm_event_ntfy {
struct nvkm_event *event;
int id;
u32 bits;
bool wait;
nvkm_event_func func;
atomic_t allowed;
bool running;
struct list_head head;
};
void nvkm_event_ntfy(struct nvkm_event *, int id, u32 bits);
bool nvkm_event_ntfy_valid(struct nvkm_event *, int id, u32 bits);
void nvkm_event_ntfy_add(struct nvkm_event *, int id, u32 bits, bool wait, nvkm_event_func,
struct nvkm_event_ntfy *);
void nvkm_event_ntfy_del(struct nvkm_event_ntfy *);
void nvkm_event_ntfy_allow(struct nvkm_event_ntfy *);
void nvkm_event_ntfy_block(struct nvkm_event_ntfy *);
typedef int (*nvkm_uevent_func)(struct nvkm_object *, u64 token, u32 bits);
int nvkm_uevent_new(const struct nvkm_oclass *, void *argv, u32 argc, struct nvkm_object **);
int nvkm_uevent_add(struct nvkm_uevent *, struct nvkm_event *, int id, u32 bits, nvkm_uevent_func);
#endif
#ifndef __NVKM_FALCON_H__
#define __NVKM_FALCON_H__
#include <core/firmware.h>
#include <engine/falcon.h>
enum nvkm_falcon_mem {
IMEM,
DMEM,
EMEM,
};
static inline const char *
nvkm_falcon_mem(enum nvkm_falcon_mem mem)
{
switch (mem) {
case IMEM: return "imem";
case DMEM: return "dmem";
case EMEM: return "emem";
default:
WARN_ON(1);
return "?mem";
}
}
struct nvkm_falcon_func_pio {
int min;
int max;
void (*wr_init)(struct nvkm_falcon *, u8 port, bool sec, u32 mem_base);
void (*wr)(struct nvkm_falcon *, u8 port, const u8 *img, int len, u16 tag);
void (*rd_init)(struct nvkm_falcon *, u8 port, u32 mem_base);
void (*rd)(struct nvkm_falcon *, u8 port, const u8 *img, int len);
};
struct nvkm_falcon_func_dma {
int (*init)(struct nvkm_falcon *, u64 dma_addr, int xfer_len,
enum nvkm_falcon_mem, bool sec, u32 *cmd);
void (*xfer)(struct nvkm_falcon *, u32 mem_base, u32 dma_base, u32 cmd);
bool (*done)(struct nvkm_falcon *);
};
int nvkm_falcon_ctor(const struct nvkm_falcon_func *, struct nvkm_subdev *owner,
const char *name, u32 addr, struct nvkm_falcon *);
void nvkm_falcon_dtor(struct nvkm_falcon *);
int nvkm_falcon_reset(struct nvkm_falcon *);
int nvkm_falcon_pio_wr(struct nvkm_falcon *, const u8 *img, u32 img_base, u8 port,
enum nvkm_falcon_mem mem_type, u32 mem_base, int len, u16 tag, bool sec);
int nvkm_falcon_pio_rd(struct nvkm_falcon *, u8 port, enum nvkm_falcon_mem type, u32 mem_base,
const u8 *img, u32 img_base, int len);
int nvkm_falcon_dma_wr(struct nvkm_falcon *, const u8 *img, u64 dma_addr, u32 dma_base,
enum nvkm_falcon_mem mem_type, u32 mem_base, int len, bool sec);
int gm200_flcn_reset_wait_mem_scrubbing(struct nvkm_falcon *);
int gm200_flcn_disable(struct nvkm_falcon *);
int gm200_flcn_enable(struct nvkm_falcon *);
void gm200_flcn_bind_inst(struct nvkm_falcon *, int, u64);
int gm200_flcn_bind_stat(struct nvkm_falcon *, bool);
extern const struct nvkm_falcon_func_pio gm200_flcn_imem_pio;
extern const struct nvkm_falcon_func_pio gm200_flcn_dmem_pio;
void gm200_flcn_tracepc(struct nvkm_falcon *);
int gp102_flcn_reset_eng(struct nvkm_falcon *);
extern const struct nvkm_falcon_func_pio gp102_flcn_emem_pio;
int ga102_flcn_select(struct nvkm_falcon *);
int ga102_flcn_reset_prep(struct nvkm_falcon *);
int ga102_flcn_reset_wait_mem_scrubbing(struct nvkm_falcon *);
extern const struct nvkm_falcon_func_dma ga102_flcn_dma;
void nvkm_falcon_v1_load_imem(struct nvkm_falcon *,
void *, u32, u32, u16, u8, bool);
void nvkm_falcon_v1_load_dmem(struct nvkm_falcon *, void *, u32, u32, u8);
void nvkm_falcon_v1_read_dmem(struct nvkm_falcon *, u32, u32, u8, void *);
void nvkm_falcon_v1_bind_context(struct nvkm_falcon *, struct nvkm_memory *);
int nvkm_falcon_v1_wait_for_halt(struct nvkm_falcon *, u32);
int nvkm_falcon_v1_clear_interrupt(struct nvkm_falcon *, u32);
void nvkm_falcon_v1_set_start_addr(struct nvkm_falcon *, u32 start_addr);
void nvkm_falcon_v1_start(struct nvkm_falcon *);
int nvkm_falcon_v1_enable(struct nvkm_falcon *);
void nvkm_falcon_v1_disable(struct nvkm_falcon *);
void gp102_sec2_flcn_bind_context(struct nvkm_falcon *, struct nvkm_memory *);
int gp102_sec2_flcn_enable(struct nvkm_falcon *);
#define FLCN_PRINTK(f,l,p,fmt,a...) ({ \
if ((f)->owner->name != (f)->name) \
nvkm_printk___((f)->owner, (f)->user, NV_DBG_##l, p, "%s:"fmt, (f)->name, ##a); \
else \
nvkm_printk___((f)->owner, (f)->user, NV_DBG_##l, p, fmt, ##a); \
})
#define FLCN_DBG(f,fmt,a...) FLCN_PRINTK((f), DEBUG, info, " "fmt"\n", ##a)
#define FLCN_ERR(f,fmt,a...) FLCN_PRINTK((f), ERROR, err, " "fmt"\n", ##a)
#define FLCN_ERRON(f,c,fmt,a...) \
({ bool _cond = (c); _cond ? FLCN_ERR(f, fmt, ##a) : FLCN_DBG(f, fmt, ##a); _cond; })
struct nvkm_falcon_fw {
const struct nvkm_falcon_fw_func {
int (*signature)(struct nvkm_falcon_fw *, u32 *sig_base_src);
int (*reset)(struct nvkm_falcon_fw *);
int (*setup)(struct nvkm_falcon_fw *);
int (*load)(struct nvkm_falcon_fw *);
int (*load_bld)(struct nvkm_falcon_fw *);
int (*boot)(struct nvkm_falcon_fw *,
u32 *mbox0, u32 *mbox1, u32 mbox0_ok, u32 irqsclr);
} *func;
struct nvkm_firmware fw;
u32 sig_base_prd;
u32 sig_base_dbg;
u32 sig_base_img;
u32 sig_size;
int sig_nr;
u8 *sigs;
u32 fuse_ver;
u32 engine_id;
u32 ucode_id;
u32 nmem_base_img;
u32 nmem_base;
u32 nmem_size;
u32 imem_base_img;
u32 imem_base;
u32 imem_size;
u32 dmem_base_img;
u32 dmem_base;
u32 dmem_size;
u32 dmem_sign;
u8 *boot;
u32 boot_size;
u32 boot_addr;
struct nvkm_falcon *falcon;
struct nvkm_memory *inst;
struct nvkm_vmm *vmm;
struct nvkm_vma *vma;
};
int nvkm_falcon_fw_ctor(const struct nvkm_falcon_fw_func *, const char *name, struct nvkm_device *,
bool bl, const void *src, u32 len, struct nvkm_falcon *,
struct nvkm_falcon_fw *);
int nvkm_falcon_fw_ctor_hs(const struct nvkm_falcon_fw_func *, const char *name,
struct nvkm_subdev *, const char *bl, const char *img, int ver,
struct nvkm_falcon *falcon, struct nvkm_falcon_fw *fw);
int nvkm_falcon_fw_ctor_hs_v2(const struct nvkm_falcon_fw_func *, const char *name,
struct nvkm_subdev *, const char *img, int ver, struct nvkm_falcon *,
struct nvkm_falcon_fw *);
int nvkm_falcon_fw_sign(struct nvkm_falcon_fw *, u32 sig_base_img, u32 sig_size, const u8 *sigs,
int sig_nr_prd, u32 sig_base_prd, int sig_nr_dbg, u32 sig_base_dbg);
int nvkm_falcon_fw_patch(struct nvkm_falcon_fw *);
void nvkm_falcon_fw_dtor(struct nvkm_falcon_fw *);
int nvkm_falcon_fw_oneinit(struct nvkm_falcon_fw *, struct nvkm_falcon *, struct nvkm_vmm *,
struct nvkm_memory *inst);
int nvkm_falcon_fw_boot(struct nvkm_falcon_fw *, struct nvkm_subdev *user,
bool release, u32 *pmbox0, u32 *pmbox1, u32 mbox0_ok, u32 irqsclr);
extern const struct nvkm_falcon_fw_func gm200_flcn_fw;
int gm200_flcn_fw_signature(struct nvkm_falcon_fw *, u32 *);
int gm200_flcn_fw_reset(struct nvkm_falcon_fw *);
int gm200_flcn_fw_load(struct nvkm_falcon_fw *);
int gm200_flcn_fw_boot(struct nvkm_falcon_fw *, u32 *, u32 *, u32, u32);
int ga100_flcn_fw_signature(struct nvkm_falcon_fw *, u32 *);
extern const struct nvkm_falcon_fw_func ga102_flcn_fw;
int ga102_flcn_fw_load(struct nvkm_falcon_fw *);
int ga102_flcn_fw_boot(struct nvkm_falcon_fw *, u32 *, u32 *, u32, u32);
#define FLCN_PRINTK(t,f,fmt,a...) do { \
if ((f)->owner->name != (f)->name) \
nvkm_##t((f)->owner, "%s: "fmt"\n", (f)->name, ##a); \
else \
nvkm_##t((f)->owner, fmt"\n", ##a); \
} while(0)
#define FLCN_DBG(f,fmt,a...) FLCN_PRINTK(debug, (f), fmt, ##a)
#define FLCN_ERR(f,fmt,a...) FLCN_PRINTK(error, (f), fmt, ##a)
#define FLCNFW_PRINTK(f,l,p,fmt,a...) FLCN_PRINTK((f)->falcon, l, p, "%s: "fmt, (f)->fw.name, ##a)
#define FLCNFW_DBG(f,fmt,a...) FLCNFW_PRINTK((f), DEBUG, info, fmt"\n", ##a)
#define FLCNFW_ERR(f,fmt,a...) FLCNFW_PRINTK((f), ERROR, err, fmt"\n", ##a)
/**
* struct nvfw_falcon_msg - header for all messages
......@@ -72,6 +204,7 @@ int nvkm_falcon_msgq_new(struct nvkm_falcon_qmgr *, const char *name,
void nvkm_falcon_msgq_del(struct nvkm_falcon_msgq **);
void nvkm_falcon_msgq_init(struct nvkm_falcon_msgq *,
u32 index, u32 offset, u32 size);
bool nvkm_falcon_msgq_empty(struct nvkm_falcon_msgq *);
int nvkm_falcon_msgq_recv_initmsg(struct nvkm_falcon_msgq *, void *, u32 size);
void nvkm_falcon_msgq_recv(struct nvkm_falcon_msgq *);
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_FIRMWARE_H__
#define __NVKM_FIRMWARE_H__
#include <core/memory.h>
#include <core/option.h>
#include <core/subdev.h>
struct nvkm_firmware {
const struct nvkm_firmware_func {
enum nvkm_firmware_type {
NVKM_FIRMWARE_IMG_RAM,
NVKM_FIRMWARE_IMG_DMA,
} type;
} *func;
const char *name;
struct nvkm_device *device;
int len;
u8 *img;
u64 phys;
struct nvkm_firmware_mem {
struct nvkm_memory memory;
struct scatterlist sgl;
} mem;
};
int nvkm_firmware_ctor(const struct nvkm_firmware_func *, const char *name, struct nvkm_device *,
const void *ptr, int len, struct nvkm_firmware *);
void nvkm_firmware_dtor(struct nvkm_firmware *);
int nvkm_firmware_get(const struct nvkm_subdev *, const char *fwname, int ver,
const struct firmware **);
void nvkm_firmware_put(const struct firmware *);
......
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_INTR_H__
#define __NVKM_INTR_H__
#include <core/os.h>
struct nvkm_device;
struct nvkm_subdev;
enum nvkm_intr_prio {
NVKM_INTR_PRIO_VBLANK = 0,
NVKM_INTR_PRIO_NORMAL,
NVKM_INTR_PRIO_NR
};
enum nvkm_intr_type {
NVKM_INTR_SUBDEV = -1, /* lookup vector by requesting subdev, in mapping table. */
NVKM_INTR_VECTOR_0 = 0,
};
struct nvkm_intr {
const struct nvkm_intr_func {
bool (*pending)(struct nvkm_intr *);
void (*unarm)(struct nvkm_intr *);
void (*rearm)(struct nvkm_intr *);
void (*block)(struct nvkm_intr *, int leaf, u32 mask);
void (*allow)(struct nvkm_intr *, int leaf, u32 mask);
void (*reset)(struct nvkm_intr *, int leaf, u32 mask);
} *func;
const struct nvkm_intr_data {
int type; /* enum nvkm_subdev_type (+ve), enum nvkm_intr_type (-ve) */
int inst;
int leaf;
u32 mask; /* 0-terminated. */
bool legacy; /* auto-create "legacy" nvkm_subdev_intr() handler */
} *data;
struct nvkm_subdev *subdev;
int leaves;
u32 *stat;
u32 *mask;
struct list_head head;
};
void nvkm_intr_ctor(struct nvkm_device *);
void nvkm_intr_dtor(struct nvkm_device *);
int nvkm_intr_install(struct nvkm_device *);
void nvkm_intr_unarm(struct nvkm_device *);
void nvkm_intr_rearm(struct nvkm_device *);
int nvkm_intr_add(const struct nvkm_intr_func *, const struct nvkm_intr_data *,
struct nvkm_subdev *, int leaves, struct nvkm_intr *);
void nvkm_intr_block(struct nvkm_subdev *, enum nvkm_intr_type);
void nvkm_intr_allow(struct nvkm_subdev *, enum nvkm_intr_type);
struct nvkm_inth;
typedef irqreturn_t (*nvkm_inth_func)(struct nvkm_inth *);
struct nvkm_inth {
struct nvkm_intr *intr;
int leaf;
u32 mask;
nvkm_inth_func func;
atomic_t allowed;
struct list_head head;
};
int nvkm_inth_add(struct nvkm_intr *, enum nvkm_intr_type, enum nvkm_intr_prio,
struct nvkm_subdev *, nvkm_inth_func, struct nvkm_inth *);
void nvkm_inth_allow(struct nvkm_inth *);
void nvkm_inth_block(struct nvkm_inth *);
#endif
/* SPDX-License-Identifier: MIT */
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_TOP , struct nvkm_top , top)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_GSP , struct nvkm_gsp , gsp)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_VFN , struct nvkm_vfn , vfn)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_PCI , struct nvkm_pci , pci)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_VBIOS , struct nvkm_bios , bios)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_DEVINIT , struct nvkm_devinit , devinit)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_TOP , struct nvkm_top , top)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_PRIVRING, struct nvkm_subdev , privring)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_GPIO , struct nvkm_gpio , gpio)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_I2C , struct nvkm_i2c , i2c)
......@@ -23,7 +25,6 @@ NVKM_LAYOUT_ONCE(NVKM_SUBDEV_VOLT , struct nvkm_volt , volt)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_ICCSENSE, struct nvkm_iccsense, iccsense)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_THERM , struct nvkm_therm , therm)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_CLK , struct nvkm_clk , clk)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_GSP , struct nvkm_gsp , gsp)
NVKM_LAYOUT_INST(NVKM_SUBDEV_IOCTRL , struct nvkm_subdev , ioctrl, 3)
NVKM_LAYOUT_ONCE(NVKM_SUBDEV_FLA , struct nvkm_subdev , fla)
......
......@@ -37,6 +37,7 @@ struct nvkm_memory_func {
void (*release)(struct nvkm_memory *);
int (*map)(struct nvkm_memory *, u64 offset, struct nvkm_vmm *,
struct nvkm_vma *, void *argv, u32 argc);
int (*kmap)(struct nvkm_memory *, struct nvkm_memory **);
};
struct nvkm_memory_ptrs {
......@@ -63,6 +64,7 @@ void nvkm_memory_tags_put(struct nvkm_memory *, struct nvkm_device *,
#define nvkm_memory_boot(p,v) (p)->func->boot((p),(v))
#define nvkm_memory_map(p,o,vm,va,av,ac) \
(p)->func->map((p),(o),(vm),(va),(av),(ac))
#define nvkm_memory_kmap(p,i) ((p)->func->kmap ? (p)->func->kmap((p), (i)) : -ENOSYS)
/* accessor macros - kmap()/done() must bracket use of the other accessor
* macros to guarantee correct behaviour across all chipsets
......
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_NOTIFY_H__
#define __NVKM_NOTIFY_H__
#include <core/os.h>
struct nvkm_object;
struct nvkm_notify {
struct nvkm_event *event;
struct list_head head;
#define NVKM_NOTIFY_USER 0
#define NVKM_NOTIFY_WORK 1
unsigned long flags;
int block;
#define NVKM_NOTIFY_DROP 0
#define NVKM_NOTIFY_KEEP 1
int (*func)(struct nvkm_notify *);
/* set by nvkm_event ctor */
u32 types;
int index;
u32 size;
struct work_struct work;
/* this is const for a *very* good reason - the data might be on the
* stack from an irq handler. if you're not core/notify.c then you
* should probably think twice before casting it away...
*/
const void *data;
};
int nvkm_notify_init(struct nvkm_object *, struct nvkm_event *,
int (*func)(struct nvkm_notify *), bool work,
void *data, u32 size, u32 reply,
struct nvkm_notify *);
void nvkm_notify_fini(struct nvkm_notify *);
void nvkm_notify_get(struct nvkm_notify *);
void nvkm_notify_put(struct nvkm_notify *);
void nvkm_notify_send(struct nvkm_notify *, void *data, u32 size);
#endif
......@@ -4,6 +4,7 @@
#include <core/oclass.h>
struct nvkm_event;
struct nvkm_gpuobj;
struct nvkm_uevent;
struct nvkm_object {
const struct nvkm_object_func *func;
......@@ -43,6 +44,7 @@ struct nvkm_object_func {
int (*bind)(struct nvkm_object *, struct nvkm_gpuobj *, int align,
struct nvkm_gpuobj **);
int (*sclass)(struct nvkm_object *, int index, struct nvkm_oclass *);
int (*uevent)(struct nvkm_object *, void *argv, u32 argc, struct nvkm_uevent *);
};
void nvkm_object_ctor(const struct nvkm_object_func *,
......
......@@ -34,4 +34,24 @@ nvkm_blob_dtor(struct nvkm_blob *blob)
blob->data = NULL;
blob->size = 0;
}
#define nvkm_list_find_next(p,h,m,c) ({ \
typeof(p) _p = NULL; \
list_for_each_entry_continue(p, (h), m) { \
if (c) { \
_p = p; \
break; \
} \
} \
_p; \
})
#define nvkm_list_find(p,h,m,c) \
(p = container_of((h), typeof(*p), m), nvkm_list_find_next(p, (h), m, (c)))
#define nvkm_list_foreach(p,h,m,c) \
for (p = nvkm_list_find(p, (h), m, (c)); p; p = nvkm_list_find_next(p, (h), m, (c)))
/*FIXME: remove after */
#define nvkm_fifo_chan nvkm_chan
#define nvkm_fifo_chan_func nvkm_chan_func
#define nvkm_fifo_cgrp nvkm_cgrp
#endif
......@@ -17,10 +17,19 @@ struct nvkm_subdev {
struct nvkm_device *device;
enum nvkm_subdev_type type;
int inst;
char name[16];
u32 debug;
struct list_head head;
struct {
refcount_t refcount;
struct mutex mutex;
bool enabled;
} use;
struct nvkm_inth inth;
struct list_head head;
void **pself;
bool oneinit;
};
......@@ -38,22 +47,41 @@ struct nvkm_subdev_func {
extern const char *nvkm_subdev_type[NVKM_SUBDEV_NR];
int nvkm_subdev_new_(const struct nvkm_subdev_func *, struct nvkm_device *, enum nvkm_subdev_type,
int inst, struct nvkm_subdev **);
void nvkm_subdev_ctor(const struct nvkm_subdev_func *, struct nvkm_device *,
enum nvkm_subdev_type, int inst, struct nvkm_subdev *);
void __nvkm_subdev_ctor(const struct nvkm_subdev_func *, struct nvkm_device *,
enum nvkm_subdev_type, int inst, struct nvkm_subdev *);
static inline void
nvkm_subdev_ctor(const struct nvkm_subdev_func *func, struct nvkm_device *device,
enum nvkm_subdev_type type, int inst, struct nvkm_subdev *subdev)
{
__nvkm_subdev_ctor(func, device, type, inst, subdev);
mutex_init(&subdev->use.mutex);
}
void nvkm_subdev_disable(struct nvkm_device *, enum nvkm_subdev_type, int inst);
void nvkm_subdev_del(struct nvkm_subdev **);
int nvkm_subdev_ref(struct nvkm_subdev *);
void nvkm_subdev_unref(struct nvkm_subdev *);
int nvkm_subdev_preinit(struct nvkm_subdev *);
int nvkm_subdev_oneinit(struct nvkm_subdev *);
int nvkm_subdev_init(struct nvkm_subdev *);
int nvkm_subdev_fini(struct nvkm_subdev *, bool suspend);
int nvkm_subdev_info(struct nvkm_subdev *, u64, u64 *);
void nvkm_subdev_intr(struct nvkm_subdev *);
/* subdev logging */
#define nvkm_printk_(s,l,p,f,a...) do { \
const struct nvkm_subdev *_subdev = (s); \
if (CONFIG_NOUVEAU_DEBUG >= (l) && _subdev->debug >= (l)) \
dev_##p(_subdev->device->dev, "%s: "f, _subdev->name, ##a); \
#define nvkm_printk_ok(s,u,l) \
((CONFIG_NOUVEAU_DEBUG >= (l)) && ((s)->debug >= (l) || ((u) && (u)->debug >= (l))))
#define nvkm_printk___(s,u,l,p,f,a...) do { \
if (nvkm_printk_ok((s), (u), (l))) { \
if ((u) && (u) != (s)) \
dev_##p((s)->device->dev, "%s(%s):"f, (s)->name, (u)->name, ##a); \
else \
dev_##p((s)->device->dev, "%s:"f, (s)->name, ##a); \
} \
} while(0)
#define nvkm_printk__(s,l,p,f,a...) nvkm_printk___((s), (s), (l), p, f, ##a)
#define nvkm_printk_(s,l,p,f,a...) nvkm_printk__((s), (l), p, " "f, ##a)
#define nvkm_printk(s,l,p,f,a...) nvkm_printk_((s), NV_DBG_##l, p, f, ##a)
#define nvkm_fatal(s,f,a...) nvkm_printk((s), FATAL, crit, f, ##a)
#define nvkm_error(s,f,a...) nvkm_printk((s), ERROR, err, f, ##a)
......
......@@ -8,7 +8,6 @@ struct nvkm_device_tegra {
const struct nvkm_device_tegra_func *func;
struct nvkm_device device;
struct platform_device *pdev;
int irq;
struct reset_control *rst;
struct clk *clk;
......
......@@ -12,4 +12,6 @@ int gp100_ce_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct n
int gp102_ce_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int gv100_ce_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int tu102_ce_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int ga100_ce_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
int ga102_ce_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_engine **);
#endif
......@@ -16,6 +16,7 @@ struct nvkm_disp {
struct list_head conns;
struct nvkm_event hpd;
#define NVKM_DISP_HEAD_EVENT_VBLANK BIT(0)
struct nvkm_event vblank;
struct {
......@@ -31,13 +32,7 @@ struct nvkm_disp {
struct {
unsigned long mask;
int nr;
} wndw, head, dac;
struct {
unsigned long mask;
int nr;
u32 lvdsconf;
} sor;
} wndw, head, dac, sor;
struct {
unsigned long mask;
......
......@@ -16,15 +16,16 @@ enum nvkm_falcon_dmaidx {
struct nvkm_falcon {
const struct nvkm_falcon_func *func;
const struct nvkm_subdev *owner;
struct nvkm_subdev *owner;
const char *name;
u32 addr;
u32 addr2;
struct mutex mutex;
struct mutex dmem_mutex;
bool oneinit;
const struct nvkm_subdev *user;
struct nvkm_subdev *user;
u8 version;
u8 secret;
......@@ -50,13 +51,42 @@ struct nvkm_falcon {
struct nvkm_engine engine;
};
int nvkm_falcon_get(struct nvkm_falcon *, const struct nvkm_subdev *);
void nvkm_falcon_put(struct nvkm_falcon *, const struct nvkm_subdev *);
int nvkm_falcon_get(struct nvkm_falcon *, struct nvkm_subdev *);
void nvkm_falcon_put(struct nvkm_falcon *, struct nvkm_subdev *);
int nvkm_falcon_new_(const struct nvkm_falcon_func *, struct nvkm_device *,
enum nvkm_subdev_type, int inst, bool enable, u32 addr, struct nvkm_engine **);
struct nvkm_falcon_func {
int (*disable)(struct nvkm_falcon *);
int (*enable)(struct nvkm_falcon *);
int (*select)(struct nvkm_falcon *);
u32 addr2;
bool reset_pmc;
int (*reset_eng)(struct nvkm_falcon *);
int (*reset_prep)(struct nvkm_falcon *);
int (*reset_wait_mem_scrubbing)(struct nvkm_falcon *);
u32 debug;
void (*bind_inst)(struct nvkm_falcon *, int target, u64 addr);
int (*bind_stat)(struct nvkm_falcon *, bool intr);
bool bind_intr;
const struct nvkm_falcon_func_pio *imem_pio;
const struct nvkm_falcon_func_dma *imem_dma;
const struct nvkm_falcon_func_pio *dmem_pio;
const struct nvkm_falcon_func_dma *dmem_dma;
u32 emem_addr;
const struct nvkm_falcon_func_pio *emem_pio;
struct {
u32 head;
u32 tail;
u32 stride;
} cmdq, msgq;
struct {
u32 *data;
u32 size;
......@@ -66,29 +96,11 @@ struct nvkm_falcon_func {
u32 size;
} data;
void (*init)(struct nvkm_falcon *);
void (*intr)(struct nvkm_falcon *, struct nvkm_fifo_chan *);
u32 debug;
u32 fbif;
void (*intr)(struct nvkm_falcon *, struct nvkm_chan *);
void (*load_imem)(struct nvkm_falcon *, void *, u32, u32, u16, u8, bool);
void (*load_dmem)(struct nvkm_falcon *, void *, u32, u32, u8);
void (*read_dmem)(struct nvkm_falcon *, u32, u32, u8, void *);
u32 emem_addr;
void (*bind_context)(struct nvkm_falcon *, struct nvkm_memory *);
int (*wait_for_halt)(struct nvkm_falcon *, u32);
int (*clear_interrupt)(struct nvkm_falcon *, u32);
void (*set_start_addr)(struct nvkm_falcon *, u32 start_addr);
void (*start)(struct nvkm_falcon *);
int (*enable)(struct nvkm_falcon *falcon);
void (*disable)(struct nvkm_falcon *falcon);
int (*reset)(struct nvkm_falcon *);
struct {
u32 head;
u32 tail;
u32 stride;
} cmdq, msgq;
struct nvkm_sclass sclass[];
};
......@@ -116,13 +128,5 @@ nvkm_falcon_mask(struct nvkm_falcon *falcon, u32 addr, u32 mask, u32 val)
void nvkm_falcon_load_imem(struct nvkm_falcon *, void *, u32, u32, u16, u8,
bool);
void nvkm_falcon_load_dmem(struct nvkm_falcon *, void *, u32, u32, u8);
void nvkm_falcon_read_dmem(struct nvkm_falcon *, u32, u32, u8, void *);
void nvkm_falcon_bind_context(struct nvkm_falcon *, struct nvkm_memory *);
void nvkm_falcon_set_start_addr(struct nvkm_falcon *, u32);
void nvkm_falcon_start(struct nvkm_falcon *);
int nvkm_falcon_wait_for_halt(struct nvkm_falcon *, u32);
int nvkm_falcon_clear_interrupt(struct nvkm_falcon *, u32);
int nvkm_falcon_enable(struct nvkm_falcon *);
void nvkm_falcon_disable(struct nvkm_falcon *);
int nvkm_falcon_reset(struct nvkm_falcon *);
#endif
......@@ -6,56 +6,76 @@
#include <core/event.h>
struct nvkm_fault_data;
#define NVKM_FIFO_CHID_NR 4096
#define NVKM_FIFO_ENGN_NR 16
struct nvkm_fifo_engn {
struct nvkm_object *object;
int refcount;
int usecount;
};
struct nvkm_fifo_chan {
const struct nvkm_fifo_chan_func *func;
struct nvkm_fifo *fifo;
u32 engm;
struct nvkm_object object;
struct nvkm_chan {
const struct nvkm_chan_func *func;
char name[64];
struct nvkm_cgrp *cgrp;
int runq;
struct list_head head;
u16 chid;
struct nvkm_gpuobj *inst;
struct nvkm_gpuobj *push;
struct nvkm_vmm *vmm;
u64 addr;
u32 size;
struct nvkm_gpuobj *push;
int id;
struct {
struct nvkm_memory *mem;
u32 base;
} userd;
u32 ramfc_offset;
struct nvkm_gpuobj *ramfc;
struct nvkm_gpuobj *cache;
struct nvkm_gpuobj *eng;
struct nvkm_gpuobj *pgd;
struct nvkm_ramht *ramht;
spinlock_t lock;
atomic_t blocked;
atomic_t errored;
struct nvkm_fifo_engn engn[NVKM_FIFO_ENGN_NR];
struct list_head cctxs;
struct list_head head;
};
struct nvkm_chan *nvkm_chan_get_chid(struct nvkm_engine *, int id, unsigned long *irqflags);
struct nvkm_chan *nvkm_chan_get_inst(struct nvkm_engine *, u64 inst, unsigned long *irqflags);
void nvkm_chan_put(struct nvkm_chan **, unsigned long irqflags);
struct nvkm_fifo {
const struct nvkm_fifo_func *func;
struct nvkm_engine engine;
DECLARE_BITMAP(mask, NVKM_FIFO_CHID_NR);
int nr;
struct list_head chan;
struct nvkm_chid *chid;
struct nvkm_chid *cgid;
struct list_head runqs;
struct list_head runls;
struct {
#define NVKM_FIFO_NONSTALL_EVENT BIT(0)
struct nvkm_event event;
struct nvkm_inth intr;
} nonstall;
struct {
u32 chan_msec;
} timeout;
struct {
struct nvkm_memory *mem;
struct nvkm_vma *bar1;
} userd;
spinlock_t lock;
struct mutex mutex;
struct nvkm_event uevent; /* async user trigger */
struct nvkm_event kevent; /* channel killed */
};
void nvkm_fifo_fault(struct nvkm_fifo *, struct nvkm_fault_data *);
void nvkm_fifo_pause(struct nvkm_fifo *, unsigned long *);
void nvkm_fifo_start(struct nvkm_fifo *, unsigned long *);
void nvkm_fifo_chan_put(struct nvkm_fifo *, unsigned long flags,
struct nvkm_fifo_chan **);
struct nvkm_fifo_chan *
nvkm_fifo_chan_inst(struct nvkm_fifo *, u64 inst, unsigned long *flags);
struct nvkm_fifo_chan *
nvkm_fifo_chan_chid(struct nvkm_fifo *, int chid, unsigned long *flags);
bool nvkm_fifo_ctxsw_in_progress(struct nvkm_engine *);
int nv04_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int nv10_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
......@@ -63,6 +83,7 @@ int nv17_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct
int nv40_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int nv50_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int g84_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int g98_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int gf100_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int gk104_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int gk110_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
......@@ -70,10 +91,9 @@ int gk208_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct
int gk20a_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int gm107_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int gm200_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int gm20b_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int gp100_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int gp10b_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int gv100_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int tu102_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int ga100_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
int ga102_fifo_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_fifo **);
#endif
......@@ -54,4 +54,5 @@ int gp108_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct n
int gp10b_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int gv100_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int tu102_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
int ga102_gr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_gr **);
#endif
......@@ -12,4 +12,5 @@ struct nvkm_nvdec {
};
int gm107_nvdec_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvdec **);
int ga102_nvdec_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_nvdec **);
#endif
......@@ -10,15 +10,18 @@ struct nvkm_sec2 {
struct nvkm_engine engine;
struct nvkm_falcon falcon;
atomic_t running;
atomic_t initmsg;
struct nvkm_falcon_qmgr *qmgr;
struct nvkm_falcon_cmdq *cmdq;
struct nvkm_falcon_msgq *msgq;
struct work_struct work;
bool initmsg_received;
};
int gp102_sec2_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_sec2 **);
int gp108_sec2_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_sec2 **);
int tu102_sec2_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_sec2 **);
int ga102_sec2_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_sec2 **);
#endif
......@@ -36,7 +36,7 @@ struct nvkm_acr {
const struct nvkm_acr_func *func;
struct nvkm_subdev subdev;
struct list_head hsfw, hsf;
struct list_head hsfw;
struct list_head lsfw, lsf;
u64 managed_falcons;
......@@ -50,6 +50,7 @@ struct nvkm_acr {
struct nvkm_vmm *vmm;
bool done;
struct nvkm_acr_lsf *rtos;
const struct firmware *wpr_fw;
bool wpr_comp;
......@@ -64,7 +65,9 @@ int gm20b_acr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct
int gp102_acr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_acr **);
int gp108_acr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_acr **);
int gp10b_acr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_acr **);
int gv100_acr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_acr **);
int tu102_acr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_acr **);
int ga102_acr_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_acr **);
struct nvkm_acr_lsfw {
const struct nvkm_acr_lsf_func *func;
......@@ -77,6 +80,7 @@ struct nvkm_acr_lsfw {
const struct firmware *sig;
bool secure_bootloader;
u32 bootloader_size;
u32 bootloader_imem_offset;
......@@ -87,10 +91,19 @@ struct nvkm_acr_lsfw {
u32 app_resident_code_size;
u32 app_resident_data_offset;
u32 app_resident_data_size;
u32 app_imem_offset;
u32 app_dmem_offset;
u32 ucode_size;
u32 data_size;
u32 fuse_ver;
u32 engine_id;
u32 ucode_id;
u32 sig_size;
u32 sig_nr;
u8 *sigs;
struct {
u32 lsb;
u32 img;
......@@ -105,10 +118,10 @@ struct nvkm_acr_lsf_func {
#define NVKM_ACR_LSF_DMACTL_REQ_CTX 0x00000004
#define NVKM_ACR_LSF_FORCE_PRIV_LOAD 0x00000008
u32 flags;
u32 bl_entry;
u32 bld_size;
void (*bld_write)(struct nvkm_acr *, u32 bld, struct nvkm_acr_lsfw *);
void (*bld_patch)(struct nvkm_acr *, u32 bld, s64 adjust);
int (*boot)(struct nvkm_falcon *);
u64 bootstrap_falcons;
int (*bootstrap_falcon)(struct nvkm_falcon *, enum nvkm_acr_lsf_id);
int (*bootstrap_multiple_falcons)(struct nvkm_falcon *, u32 mask);
......@@ -122,8 +135,20 @@ int
nvkm_acr_lsfw_load_sig_image_desc_v1(struct nvkm_subdev *, struct nvkm_falcon *,
enum nvkm_acr_lsf_id, const char *path,
int ver, const struct nvkm_acr_lsf_func *);
int
nvkm_acr_lsfw_load_sig_image_desc_v2(struct nvkm_subdev *, struct nvkm_falcon *,
enum nvkm_acr_lsf_id, const char *path,
int ver, const struct nvkm_acr_lsf_func *);
int
nvkm_acr_lsfw_load_bl_inst_data_sig(struct nvkm_subdev *, struct nvkm_falcon *,
enum nvkm_acr_lsf_id, const char *path,
int ver, const struct nvkm_acr_lsf_func *);
int
nvkm_acr_lsfw_load_bl_sig_net(struct nvkm_subdev *, struct nvkm_falcon *,
enum nvkm_acr_lsf_id, const char *path,
int ver, const struct nvkm_acr_lsf_func *,
const void *, u32, const void *, u32);
#endif
......@@ -2,18 +2,21 @@
#define __NVKM_FAULT_H__
#include <core/subdev.h>
#include <core/event.h>
#include <core/notify.h>
struct nvkm_fault {
const struct nvkm_fault_func *func;
struct nvkm_subdev subdev;
struct nvkm_inth info_fault;
struct nvkm_fault_buffer *buffer[2];
int buffer_nr;
#define NVKM_FAULT_BUFFER_EVENT_PENDING BIT(0)
struct nvkm_event event;
struct nvkm_notify nrpfb;
struct nvkm_event_ntfy nrpfb;
struct work_struct nrpfb_work;
struct nvkm_device_oclass user;
};
......
......@@ -35,6 +35,11 @@ struct nvkm_fb {
struct nvkm_blob vpr_scrubber;
struct {
struct page *flush_page;
dma_addr_t flush_page_addr;
} sysmem;
struct nvkm_ram *ram;
struct {
......@@ -53,6 +58,8 @@ struct nvkm_fb {
struct nvkm_memory *mmu_wr;
};
int nvkm_fb_mem_unlock(struct nvkm_fb *);
void nvkm_fb_tile_init(struct nvkm_fb *, int region, u32 addr, u32 size,
u32 pitch, u32 flags, struct nvkm_fb_tile *);
void nvkm_fb_tile_fini(struct nvkm_fb *, int region, struct nvkm_fb_tile *);
......
......@@ -8,9 +8,6 @@
#include <subdev/bios/gpio.h>
struct nvkm_gpio_ntfy_req {
#define NVKM_GPIO_HI 0x01
#define NVKM_GPIO_LO 0x02
#define NVKM_GPIO_TOGGLED 0x03
u8 mask;
u8 line;
};
......@@ -23,6 +20,9 @@ struct nvkm_gpio {
const struct nvkm_gpio_func *func;
struct nvkm_subdev subdev;
#define NVKM_GPIO_HI BIT(0)
#define NVKM_GPIO_LO BIT(1)
#define NVKM_GPIO_TOGGLED (NVKM_GPIO_HI | NVKM_GPIO_LO)
struct nvkm_event event;
};
......
......@@ -5,9 +5,12 @@
#include <core/falcon.h>
struct nvkm_gsp {
const struct nvkm_gsp_func *func;
struct nvkm_subdev subdev;
struct nvkm_falcon falcon;
};
int gv100_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
int ga102_gsp_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_gsp **);
#endif
......@@ -7,20 +7,6 @@
#include <subdev/bios.h>
#include <subdev/bios/i2c.h>
struct nvkm_i2c_ntfy_req {
#define NVKM_I2C_PLUG 0x01
#define NVKM_I2C_UNPLUG 0x02
#define NVKM_I2C_IRQ 0x04
#define NVKM_I2C_DONE 0x08
#define NVKM_I2C_ANY 0x0f
u8 mask;
u8 port;
};
struct nvkm_i2c_ntfy_rep {
u8 mask;
};
struct nvkm_i2c_bus_probe {
struct i2c_board_info dev;
u8 udelay; /* set to 0 to use the standard delay */
......@@ -79,6 +65,11 @@ struct nvkm_i2c {
struct list_head bus;
struct list_head aux;
#define NVKM_I2C_PLUG BIT(0)
#define NVKM_I2C_UNPLUG BIT(1)
#define NVKM_I2C_IRQ BIT(2)
#define NVKM_I2C_DONE BIT(3)
#define NVKM_I2C_ANY (NVKM_I2C_PLUG | NVKM_I2C_UNPLUG | NVKM_I2C_IRQ | NVKM_I2C_DONE)
struct nvkm_event event;
};
......
......@@ -28,7 +28,7 @@ u32 nvkm_instmem_rd32(struct nvkm_instmem *, u32 addr);
void nvkm_instmem_wr32(struct nvkm_instmem *, u32 addr, u32 data);
int nvkm_instobj_new(struct nvkm_instmem *, u32 size, u32 align, bool zero,
struct nvkm_memory **);
int nvkm_instobj_wrap(struct nvkm_device *, struct nvkm_memory *, struct nvkm_memory **);
int nv04_instmem_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_instmem **);
int nv40_instmem_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_instmem **);
......
......@@ -4,7 +4,8 @@
#include <core/subdev.h>
#include <core/mm.h>
#define NVKM_LTC_MAX_ZBC_CNT 16
#define NVKM_LTC_MAX_ZBC_COLOR_CNT 32
#define NVKM_LTC_MAX_ZBC_DEPTH_CNT 16
struct nvkm_ltc {
const struct nvkm_ltc_func *func;
......@@ -18,11 +19,13 @@ struct nvkm_ltc {
u32 tag_base;
struct nvkm_memory *tag_ram;
int zbc_min;
int zbc_max;
u32 zbc_color[NVKM_LTC_MAX_ZBC_CNT][4];
u32 zbc_depth[NVKM_LTC_MAX_ZBC_CNT];
u32 zbc_stencil[NVKM_LTC_MAX_ZBC_CNT];
int zbc_color_min;
int zbc_color_max;
u32 zbc_color[NVKM_LTC_MAX_ZBC_COLOR_CNT][4];
int zbc_depth_min;
int zbc_depth_max;
u32 zbc_depth[NVKM_LTC_MAX_ZBC_DEPTH_CNT];
u32 zbc_stencil[NVKM_LTC_MAX_ZBC_DEPTH_CNT];
};
void nvkm_ltc_tags_clear(struct nvkm_device *, u32 first, u32 count);
......@@ -41,4 +44,5 @@ int gm200_ltc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct
int gp100_ltc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_ltc **);
int gp102_ltc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_ltc **);
int gp10b_ltc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_ltc **);
int ga102_ltc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_ltc **);
#endif
......@@ -6,15 +6,14 @@
struct nvkm_mc {
const struct nvkm_mc_func *func;
struct nvkm_subdev subdev;
struct nvkm_intr intr;
};
void nvkm_mc_enable(struct nvkm_device *, enum nvkm_subdev_type, int);
void nvkm_mc_disable(struct nvkm_device *, enum nvkm_subdev_type, int);
bool nvkm_mc_enabled(struct nvkm_device *, enum nvkm_subdev_type, int);
void nvkm_mc_reset(struct nvkm_device *, enum nvkm_subdev_type, int);
void nvkm_mc_intr(struct nvkm_device *, bool *handled);
void nvkm_mc_intr_unarm(struct nvkm_device *);
void nvkm_mc_intr_rearm(struct nvkm_device *);
void nvkm_mc_intr_mask(struct nvkm_device *, enum nvkm_subdev_type, int, bool enable);
void nvkm_mc_unk260(struct nvkm_device *, u32 data);
......@@ -31,6 +30,5 @@ int gk104_mc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct n
int gk20a_mc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mc **);
int gp100_mc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mc **);
int gp10b_mc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mc **);
int tu102_mc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mc **);
int ga100_mc_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_mc **);
#endif
......@@ -13,7 +13,6 @@ struct nvkm_pci {
const struct nvkm_pci_func *func;
struct nvkm_subdev subdev;
struct pci_dev *pdev;
int irq;
struct {
struct agp_bridge_data *bridge;
......@@ -38,6 +37,7 @@ void nvkm_pci_wr08(struct nvkm_pci *, u16 addr, u8 data);
void nvkm_pci_wr32(struct nvkm_pci *, u16 addr, u32 data);
u32 nvkm_pci_mask(struct nvkm_pci *, u16 addr, u32 mask, u32 value);
void nvkm_pci_rom_shadow(struct nvkm_pci *, bool shadow);
void nvkm_pci_msi_rearm(struct nvkm_device *);
int nv04_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pci **);
int nv40_pci_new(struct nvkm_device *, enum nvkm_subdev_type, int inst, struct nvkm_pci **);
......
......@@ -21,6 +21,7 @@ struct nvkm_top_device {
struct list_head head;
};
int nvkm_top_parse(struct nvkm_device *);
u32 nvkm_top_addr(struct nvkm_device *, enum nvkm_subdev_type, int);
u32 nvkm_top_reset(struct nvkm_device *, enum nvkm_subdev_type, int);
u32 nvkm_top_intr_mask(struct nvkm_device *, enum nvkm_subdev_type, int);
......
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_VFN_H__
#define __NVKM_VFN_H__
#include <core/subdev.h>
struct nvkm_vfn {
const struct nvkm_vfn_func *func;
struct nvkm_subdev subdev;
struct {
u32 priv;
u32 user;
} addr;
struct nvkm_intr intr;
struct nvkm_device_oclass user;
};
int gv100_vfn_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_vfn **);
int tu102_vfn_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_vfn **);
int ga100_vfn_new(struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_vfn **);
#endif
......@@ -27,7 +27,6 @@
#include <nvif/ioctl.h>
#include <nvif/class.h>
#include <nvif/cl0002.h>
#include <nvif/cla06f.h>
#include <nvif/unpack.h>
#include "nouveau_drv.h"
......@@ -253,7 +252,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv);
struct nouveau_abi16_chan *chan;
struct nvif_device *device;
u64 engine;
u64 engine, runm;
int ret;
if (unlikely(!abi16))
......@@ -263,6 +262,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
return nouveau_abi16_put(abi16, -ENODEV);
device = &abi16->device;
engine = NV_DEVICE_HOST_RUNLIST_ENGINES_GR;
/* hack to allow channel engine type specification on kepler */
if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) {
......@@ -276,19 +276,18 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
default:
return nouveau_abi16_put(abi16, -ENOSYS);
}
} else {
engine = NV_DEVICE_HOST_RUNLIST_ENGINES_GR;
}
if (engine != NV_DEVICE_HOST_RUNLIST_ENGINES_CE)
engine = nvif_fifo_runlist(device, engine);
else
engine = nvif_fifo_runlist_ce(device);
init->fb_ctxdma_handle = engine;
init->tt_ctxdma_handle = 0;
init->fb_ctxdma_handle = 0;
init->tt_ctxdma_handle = 0;
}
}
if (init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0)
if (engine != NV_DEVICE_HOST_RUNLIST_ENGINES_CE)
runm = nvif_fifo_runlist(device, engine);
else
runm = nvif_fifo_runlist_ce(device);
if (!runm || init->fb_ctxdma_handle == ~0 || init->tt_ctxdma_handle == ~0)
return nouveau_abi16_put(abi16, -EINVAL);
/* allocate "abi16 channel" data and make up a handle for it */
......@@ -300,8 +299,8 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
list_add(&chan->head, &abi16->channels);
/* create channel object and initialise dma and fence management */
ret = nouveau_channel_new(drm, device, init->fb_ctxdma_handle,
init->tt_ctxdma_handle, false, &chan->chan);
ret = nouveau_channel_new(drm, device, false, runm, init->fb_ctxdma_handle,
init->tt_ctxdma_handle, &chan->chan);
if (ret)
goto done;
......
......@@ -856,6 +856,9 @@ nouveau_bo_move_init(struct nouveau_drm *drm)
int (*init)(struct nouveau_channel *, u32 handle);
} _methods[] = {
{ "COPY", 4, 0xc7b5, nve0_bo_move_copy, nve0_bo_move_init },
{ "GRCE", 0, 0xc7b5, nve0_bo_move_copy, nvc0_bo_move_init },
{ "COPY", 4, 0xc6b5, nve0_bo_move_copy, nve0_bo_move_init },
{ "GRCE", 0, 0xc6b5, nve0_bo_move_copy, nvc0_bo_move_init },
{ "COPY", 4, 0xc5b5, nve0_bo_move_copy, nve0_bo_move_init },
{ "GRCE", 0, 0xc5b5, nve0_bo_move_copy, nvc0_bo_move_init },
{ "COPY", 4, 0xc3b5, nve0_bo_move_copy, nve0_bo_move_init },
......
This diff is collapsed.
......@@ -2,7 +2,7 @@
#ifndef __NOUVEAU_CHAN_H__
#define __NOUVEAU_CHAN_H__
#include <nvif/object.h>
#include <nvif/notify.h>
#include <nvif/event.h>
#include <nvif/push.h>
struct nvif_device;
......@@ -16,6 +16,10 @@ struct nouveau_channel {
struct nouveau_drm *drm;
struct nouveau_vmm *vmm;
struct nvif_mem mem_userd;
struct nvif_object *userd;
int runlist;
int chid;
u64 inst;
u32 token;
......@@ -50,15 +54,15 @@ struct nouveau_channel {
struct nvif_object user;
struct nvif_notify kill;
struct nvif_event kill;
atomic_t killed;
};
int nouveau_channels_init(struct nouveau_drm *);
void nouveau_channels_fini(struct nouveau_drm *);
int nouveau_channel_new(struct nouveau_drm *, struct nvif_device *,
u32 arg0, u32 arg1, bool priv,
struct nouveau_channel **);
int nouveau_channel_new(struct nouveau_drm *, struct nvif_device *, bool priv, u64 runm,
u32 vram, u32 gart, struct nouveau_channel **);
void nouveau_channel_del(struct nouveau_channel **);
int nouveau_channel_idle(struct nouveau_channel *);
......
......@@ -47,8 +47,7 @@
#include "nouveau_crtc.h"
#include <nvif/class.h>
#include <nvif/cl0046.h>
#include <nvif/event.h>
#include <nvif/if0011.h>
struct drm_display_mode *
nouveau_conn_native_mode(struct drm_connector *connector)
......@@ -396,7 +395,8 @@ static void
nouveau_connector_destroy(struct drm_connector *connector)
{
struct nouveau_connector *nv_connector = nouveau_connector(connector);
nvif_notify_dtor(&nv_connector->hpd);
nvif_event_dtor(&nv_connector->irq);
nvif_event_dtor(&nv_connector->hpd);
kfree(nv_connector->edid);
drm_connector_unregister(connector);
drm_connector_cleanup(connector);
......@@ -1162,39 +1162,38 @@ nouveau_connector_funcs_lvds = {
};
void
nouveau_connector_hpd(struct drm_connector *connector)
nouveau_connector_hpd(struct nouveau_connector *nv_connector, u64 bits)
{
struct nouveau_drm *drm = nouveau_drm(connector->dev);
u32 mask = drm_connector_mask(connector);
struct nouveau_drm *drm = nouveau_drm(nv_connector->base.dev);
u32 mask = drm_connector_mask(&nv_connector->base);
unsigned long flags;
mutex_lock(&drm->hpd_lock);
spin_lock_irqsave(&drm->hpd_lock, flags);
if (!(drm->hpd_pending & mask)) {
nv_connector->hpd_pending |= bits;
drm->hpd_pending |= mask;
schedule_work(&drm->hpd_work);
}
mutex_unlock(&drm->hpd_lock);
spin_unlock_irqrestore(&drm->hpd_lock, flags);
}
static int
nouveau_connector_hotplug(struct nvif_notify *notify)
nouveau_connector_irq(struct nvif_event *event, void *repv, u32 repc)
{
struct nouveau_connector *nv_connector =
container_of(notify, typeof(*nv_connector), hpd);
struct drm_connector *connector = &nv_connector->base;
struct drm_device *dev = connector->dev;
struct nouveau_drm *drm = nouveau_drm(dev);
const struct nvif_notify_conn_rep_v0 *rep = notify->data;
bool plugged = (rep->mask != NVIF_NOTIFY_CONN_V0_UNPLUG);
struct nouveau_connector *nv_connector = container_of(event, typeof(*nv_connector), irq);
if (rep->mask & NVIF_NOTIFY_CONN_V0_IRQ) {
nouveau_dp_irq(drm, nv_connector);
return NVIF_NOTIFY_KEEP;
}
schedule_work(&nv_connector->irq_work);
return NVIF_EVENT_KEEP;
}
NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un", connector->name);
nouveau_connector_hpd(connector);
static int
nouveau_connector_hotplug(struct nvif_event *event, void *repv, u32 repc)
{
struct nouveau_connector *nv_connector = container_of(event, typeof(*nv_connector), hpd);
struct nvif_conn_event_v0 *rep = repv;
return NVIF_NOTIFY_KEEP;
nouveau_connector_hpd(nv_connector, rep->types);
return NVIF_EVENT_KEEP;
}
static ssize_t
......@@ -1290,6 +1289,7 @@ nouveau_connector_create(struct drm_device *dev,
connector = &nv_connector->base;
nv_connector->index = index;
INIT_WORK(&nv_connector->irq_work, nouveau_dp_irq);
/* attempt to parse vbios connector type and hotplug gpio */
nv_connector->dcb = olddcb_conn(dev, index);
......@@ -1401,6 +1401,7 @@ nouveau_connector_create(struct drm_device *dev,
drm_connector_init(dev, connector, funcs, type);
drm_connector_helper_add(connector, &nouveau_connector_helper_funcs);
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
if (nv_connector->dcb && (disp->disp.conn_mask & BIT(nv_connector->index))) {
ret = nvif_conn_ctor(&disp->disp, nv_connector->base.name, nv_connector->index,
......@@ -1409,6 +1410,25 @@ nouveau_connector_create(struct drm_device *dev,
kfree(nv_connector);
return ERR_PTR(ret);
}
ret = nvif_conn_event_ctor(&nv_connector->conn, "kmsHotplug",
nouveau_connector_hotplug,
NVIF_CONN_EVENT_V0_PLUG | NVIF_CONN_EVENT_V0_UNPLUG,
&nv_connector->hpd);
if (ret == 0)
connector->polled = DRM_CONNECTOR_POLL_HPD;
if (nv_connector->aux.transfer) {
ret = nvif_conn_event_ctor(&nv_connector->conn, "kmsDpIrq",
nouveau_connector_irq, NVIF_CONN_EVENT_V0_IRQ,
&nv_connector->irq);
if (ret) {
nvif_event_dtor(&nv_connector->hpd);
nvif_conn_dtor(&nv_connector->conn);
kfree(nv_connector);
return ERR_PTR(ret);
}
}
}
connector->funcs->reset(connector);
......@@ -1452,21 +1472,6 @@ nouveau_connector_create(struct drm_device *dev,
break;
}
ret = nvif_notify_ctor(&disp->disp.object, "kmsHotplug",
nouveau_connector_hotplug,
true, NV04_DISP_NTFY_CONN,
&(struct nvif_notify_conn_req_v0) {
.mask = NVIF_NOTIFY_CONN_V0_ANY,
.conn = index,
},
sizeof(struct nvif_notify_conn_req_v0),
sizeof(struct nvif_notify_conn_rep_v0),
&nv_connector->hpd);
if (ret)
connector->polled = DRM_CONNECTOR_POLL_CONNECT;
else
connector->polled = DRM_CONNECTOR_POLL_HPD;
drm_connector_register(connector);
return connector;
}
......@@ -27,7 +27,7 @@
#ifndef __NOUVEAU_CONNECTOR_H__
#define __NOUVEAU_CONNECTOR_H__
#include <nvif/conn.h>
#include <nvif/notify.h>
#include <nvif/event.h>
#include <nvhw/class/cl507d.h>
#include <nvhw/class/cl907d.h>
......@@ -124,7 +124,10 @@ struct nouveau_connector {
u8 *dcb;
struct nvif_conn conn;
struct nvif_notify hpd;
u64 hpd_pending;
struct nvif_event hpd;
struct nvif_event irq;
struct work_struct irq_work;
struct drm_dp_aux aux;
......@@ -198,7 +201,7 @@ nouveau_crtc_connector_get(struct nouveau_crtc *nv_crtc)
struct drm_connector *
nouveau_connector_create(struct drm_device *, const struct dcb_output *);
void nouveau_connector_hpd(struct drm_connector *connector);
void nouveau_connector_hpd(struct nouveau_connector *, u64 bits);
extern int nouveau_tv_disable;
extern int nouveau_ignorelid;
......
......@@ -26,16 +26,17 @@
#ifndef __NOUVEAU_CRTC_H__
#define __NOUVEAU_CRTC_H__
#include <drm/drm_crtc.h>
#include <nvif/notify.h>
#include <nvif/head.h>
#include <nvif/event.h>
struct nouveau_crtc {
struct drm_crtc base;
struct nvif_head head;
int index;
struct nvif_notify vblank;
struct nvif_event vblank;
uint32_t dpms_saved_fp_control;
uint32_t fp_users;
......
......@@ -35,15 +35,14 @@
#include <drm/drm_probe_helper.h>
#include <drm/drm_vblank.h>
#include "nouveau_fbcon.h"
#include "nouveau_crtc.h"
#include "nouveau_gem.h"
#include "nouveau_connector.h"
#include "nv50_display.h"
#include <nvif/class.h>
#include <nvif/cl0046.h>
#include <nvif/event.h>
#include <nvif/if0011.h>
#include <nvif/if0013.h>
#include <dispnv50/crc.h>
int
......@@ -52,7 +51,7 @@ nouveau_display_vblank_enable(struct drm_crtc *crtc)
struct nouveau_crtc *nv_crtc;
nv_crtc = nouveau_crtc(crtc);
nvif_notify_get(&nv_crtc->vblank);
nvif_event_allow(&nv_crtc->vblank);
return 0;
}
......@@ -63,7 +62,7 @@ nouveau_display_vblank_disable(struct drm_crtc *crtc)
struct nouveau_crtc *nv_crtc;
nv_crtc = nouveau_crtc(crtc);
nvif_notify_put(&nv_crtc->vblank);
nvif_event_block(&nv_crtc->vblank);
}
static inline int
......@@ -84,24 +83,20 @@ static bool
nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos,
ktime_t *stime, ktime_t *etime)
{
struct {
struct nv04_disp_mthd_v0 base;
struct nv04_disp_scanoutpos_v0 scan;
} args = {
.base.method = NV04_DISP_SCANOUTPOS,
.base.head = nouveau_crtc(crtc)->index,
};
struct nouveau_display *disp = nouveau_display(crtc->dev);
struct drm_vblank_crtc *vblank = &crtc->dev->vblank[drm_crtc_index(crtc)];
struct nvif_head *head = &nouveau_crtc(crtc)->head;
struct nvif_head_scanoutpos_v0 args;
int retry = 20;
bool ret = false;
args.version = 0;
do {
ret = nvif_mthd(&disp->disp.object, 0, &args, sizeof(args));
ret = nvif_mthd(&head->object, NVIF_HEAD_V0_SCANOUTPOS, &args, sizeof(args));
if (ret != 0)
return false;
if (args.scan.vline) {
if (args.vline) {
ret = true;
break;
}
......@@ -109,11 +104,10 @@ nouveau_display_scanoutpos_head(struct drm_crtc *crtc, int *vpos, int *hpos,
if (retry) ndelay(vblank->linedur_ns);
} while (retry--);
*hpos = args.scan.hline;
*vpos = calc(args.scan.vblanks, args.scan.vblanke,
args.scan.vtotal, args.scan.vline);
if (stime) *stime = ns_to_ktime(args.scan.time[0]);
if (etime) *etime = ns_to_ktime(args.scan.time[1]);
*hpos = args.hline;
*vpos = calc(args.vblanks, args.vblanke, args.vtotal, args.vline);
if (stime) *stime = ns_to_ktime(args.time[0]);
if (etime) *etime = ns_to_ktime(args.time[1]);
return ret;
}
......@@ -397,7 +391,7 @@ nouveau_user_framebuffer_create(struct drm_device *dev,
static const struct drm_mode_config_funcs nouveau_mode_config_funcs = {
.fb_create = nouveau_user_framebuffer_create,
.output_poll_changed = nouveau_fbcon_output_poll_changed,
.output_poll_changed = drm_fb_helper_output_poll_changed,
};
......@@ -456,9 +450,9 @@ nouveau_display_hpd_resume(struct drm_device *dev)
{
struct nouveau_drm *drm = nouveau_drm(dev);
mutex_lock(&drm->hpd_lock);
spin_lock_irq(&drm->hpd_lock);
drm->hpd_pending = ~0;
mutex_unlock(&drm->hpd_lock);
spin_unlock_irq(&drm->hpd_lock);
schedule_work(&drm->hpd_work);
}
......@@ -475,10 +469,10 @@ nouveau_display_hpd_work(struct work_struct *work)
pm_runtime_get_sync(dev->dev);
mutex_lock(&drm->hpd_lock);
spin_lock_irq(&drm->hpd_lock);
pending = drm->hpd_pending;
drm->hpd_pending = 0;
mutex_unlock(&drm->hpd_lock);
spin_unlock_irq(&drm->hpd_lock);
/* Nothing to do, exit early without updating the last busy counter */
if (!pending)
......@@ -488,14 +482,30 @@ nouveau_display_hpd_work(struct work_struct *work)
drm_connector_list_iter_begin(dev, &conn_iter);
nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) {
struct nouveau_connector *nv_connector = nouveau_connector(connector);
enum drm_connector_status old_status = connector->status;
u64 old_epoch_counter = connector->epoch_counter;
u64 bits, old_epoch_counter = connector->epoch_counter;
if (!(pending & drm_connector_mask(connector)))
continue;
connector->status = drm_helper_probe_detect(connector, NULL,
false);
spin_lock_irq(&drm->hpd_lock);
bits = nv_connector->hpd_pending;
nv_connector->hpd_pending = 0;
spin_unlock_irq(&drm->hpd_lock);
drm_dbg_kms(dev, "[CONNECTOR:%d:%s] plug:%d unplug:%d irq:%d\n",
connector->base.id, connector->name,
!!(bits & NVIF_CONN_EVENT_V0_PLUG),
!!(bits & NVIF_CONN_EVENT_V0_UNPLUG),
!!(bits & NVIF_CONN_EVENT_V0_IRQ));
if (bits & NVIF_CONN_EVENT_V0_IRQ) {
if (nouveau_dp_link_check(nv_connector))
continue;
}
connector->status = drm_helper_probe_detect(connector, NULL, false);
if (old_epoch_counter == connector->epoch_counter)
continue;
......@@ -573,7 +583,8 @@ nouveau_display_init(struct drm_device *dev, bool resume, bool runtime)
drm_connector_list_iter_begin(dev, &conn_iter);
nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) {
struct nouveau_connector *conn = nouveau_connector(connector);
nvif_notify_get(&conn->hpd);
nvif_event_allow(&conn->hpd);
nvif_event_allow(&conn->irq);
}
drm_connector_list_iter_end(&conn_iter);
......@@ -608,7 +619,8 @@ nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime)
drm_connector_list_iter_begin(dev, &conn_iter);
nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) {
struct nouveau_connector *conn = nouveau_connector(connector);
nvif_notify_put(&conn->hpd);
nvif_event_block(&conn->irq);
nvif_event_block(&conn->hpd);
}
drm_connector_list_iter_end(&conn_iter);
......@@ -732,7 +744,7 @@ nouveau_display_create(struct drm_device *dev)
}
INIT_WORK(&drm->hpd_work, nouveau_display_hpd_work);
mutex_init(&drm->hpd_lock);
spin_lock_init(&drm->hpd_lock);
#ifdef CONFIG_ACPI
drm->acpi_nb.notifier_call = nouveau_display_acpi_ntfy;
register_acpi_notifier(&drm->acpi_nb);
......@@ -766,8 +778,7 @@ nouveau_display_destroy(struct drm_device *dev)
nvif_disp_dtor(&disp->disp);
nouveau_drm(dev)->display = NULL;
mutex_destroy(&drm->hpd_lock);
drm->display = NULL;
kfree(disp);
}
......@@ -776,6 +787,9 @@ nouveau_display_suspend(struct drm_device *dev, bool runtime)
{
struct nouveau_display *disp = nouveau_display(dev);
/* Disable console. */
drm_fb_helper_set_suspend_unlocked(dev->fb_helper, true);
if (drm_drv_uses_atomic_modeset(dev)) {
if (!runtime) {
disp->suspend = drm_atomic_helper_suspend(dev);
......@@ -803,8 +817,10 @@ nouveau_display_resume(struct drm_device *dev, bool runtime)
drm_atomic_helper_resume(dev, disp->suspend);
disp->suspend = NULL;
}
return;
}
/* Enable console. */
drm_fb_helper_set_suspend_unlocked(dev->fb_helper, false);
}
int
......
......@@ -42,9 +42,9 @@ READ_GET(struct nouveau_channel *chan, uint64_t *prev_get, int *timeout)
{
uint64_t val;
val = nvif_rd32(&chan->user, chan->user_get);
val = nvif_rd32(chan->userd, chan->user_get);
if (chan->user_get_hi)
val |= (uint64_t)nvif_rd32(&chan->user, chan->user_get_hi) << 32;
val |= (uint64_t)nvif_rd32(chan->userd, chan->user_get_hi) << 32;
/* reset counter as long as GET is still advancing, this is
* to avoid misdetecting a GPU lockup if the GPU happens to
......@@ -86,7 +86,7 @@ nv50_dma_push(struct nouveau_channel *chan, u64 offset, int length)
/* Flush writes. */
nouveau_bo_rd32(pb, 0);
nvif_wr32(&chan->user, 0x8c, chan->dma.ib_put);
nvif_wr32(chan->userd, 0x8c, chan->dma.ib_put);
if (user->func && user->func->doorbell)
user->func->doorbell(user, chan->token);
chan->dma.ib_free--;
......@@ -98,7 +98,7 @@ nv50_dma_push_wait(struct nouveau_channel *chan, int count)
uint32_t cnt = 0, prev_get = 0;
while (chan->dma.ib_free < count) {
uint32_t get = nvif_rd32(&chan->user, 0x88);
uint32_t get = nvif_rd32(chan->userd, 0x88);
if (get != prev_get) {
prev_get = get;
cnt = 0;
......
......@@ -29,8 +29,7 @@
#include "nouveau_encoder.h"
#include "nouveau_crtc.h"
#include <nvif/class.h>
#include <nvif/cl5070.h>
#include <nvif/if0011.h>
MODULE_PARM_DESC(mst, "Enable DisplayPort multi-stream (default: enabled)");
static int nouveau_mst = 1;
......@@ -140,12 +139,17 @@ nouveau_dp_detect(struct nouveau_connector *nv_connector,
* TODO: look into checking this before probing I2C to detect DVI/HDMI
*/
hpd = nvif_conn_hpd_status(&nv_connector->conn);
if (hpd == NVIF_CONN_HPD_STATUS_NOT_PRESENT)
if (hpd == NVIF_CONN_HPD_STATUS_NOT_PRESENT) {
nvif_outp_dp_aux_pwr(&nv_encoder->outp, false);
goto out;
}
nvif_outp_dp_aux_pwr(&nv_encoder->outp, true);
status = nouveau_dp_probe_dpcd(nv_connector, nv_encoder);
if (status == connector_status_disconnected)
if (status == connector_status_disconnected) {
nvif_outp_dp_aux_pwr(&nv_encoder->outp, false);
goto out;
}
/* If we're in MST mode, we're done here */
if (mstm && mstm->can_mst && mstm->is_mst) {
......@@ -193,6 +197,7 @@ nouveau_dp_detect(struct nouveau_connector *nv_connector,
ret = NOUVEAU_DP_MST;
goto out;
} else if (ret != 0) {
nvif_outp_dp_aux_pwr(&nv_encoder->outp, false);
goto out;
}
}
......@@ -206,14 +211,28 @@ nouveau_dp_detect(struct nouveau_connector *nv_connector,
return ret;
}
void nouveau_dp_irq(struct nouveau_drm *drm,
struct nouveau_connector *nv_connector)
bool
nouveau_dp_link_check(struct nouveau_connector *nv_connector)
{
struct nouveau_encoder *nv_encoder = find_encoder(&nv_connector->base, DCB_OUTPUT_DP);
if (!nv_encoder || nv_encoder->outp.or.id < 0)
return true;
return nvif_outp_dp_retrain(&nv_encoder->outp) == 0;
}
void
nouveau_dp_irq(struct work_struct *work)
{
struct nouveau_connector *nv_connector =
container_of(work, typeof(*nv_connector), irq_work);
struct drm_connector *connector = &nv_connector->base;
struct nouveau_encoder *outp = find_encoder(connector, DCB_OUTPUT_DP);
struct nouveau_drm *drm = nouveau_drm(outp->base.base.dev);
struct nv50_mstm *mstm;
u64 hpd = 0;
int ret;
bool send_hpd = false;
if (!outp)
return;
......@@ -225,14 +244,14 @@ void nouveau_dp_irq(struct nouveau_drm *drm,
if (mstm && mstm->is_mst) {
if (!nv50_mstm_service(drm, nv_connector, mstm))
send_hpd = true;
hpd |= NVIF_CONN_EVENT_V0_UNPLUG;
} else {
drm_dp_cec_irq(&nv_connector->aux);
if (nouveau_dp_has_sink_count(connector, outp)) {
ret = drm_dp_read_sink_count(&nv_connector->aux);
if (ret != outp->dp.sink_count)
send_hpd = true;
hpd |= NVIF_CONN_EVENT_V0_PLUG;
if (ret >= 0)
outp->dp.sink_count = ret;
}
......@@ -240,8 +259,7 @@ void nouveau_dp_irq(struct nouveau_drm *drm,
mutex_unlock(&outp->dp.hpd_irq_lock);
if (send_hpd)
nouveau_connector_hpd(connector);
nouveau_connector_hpd(nv_connector, NVIF_CONN_EVENT_V0_IRQ | hpd);
}
/* TODO:
......
......@@ -33,6 +33,7 @@
#include <drm/drm_aperture.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_drv.h>
#include <drm/drm_fb_helper.h>
#include <drm/drm_gem_ttm_helper.h>
#include <drm/drm_ioctl.h>
#include <drm/drm_vblank.h>
......@@ -49,7 +50,6 @@
#include <nvif/class.h>
#include <nvif/cl0002.h>
#include <nvif/cla06f.h>
#include "nouveau_drv.h"
#include "nouveau_dma.h"
......@@ -62,7 +62,6 @@
#include "nouveau_bios.h"
#include "nouveau_ioctl.h"
#include "nouveau_abi16.h"
#include "nouveau_fbcon.h"
#include "nouveau_fence.h"
#include "nouveau_debugfs.h"
#include "nouveau_usif.h"
......@@ -316,28 +315,19 @@ static void
nouveau_accel_ce_init(struct nouveau_drm *drm)
{
struct nvif_device *device = &drm->client.device;
u64 runm;
int ret = 0;
/* Allocate channel that has access to a (preferably async) copy
* engine, to use for TTM buffer moves.
*/
if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) {
ret = nouveau_channel_new(drm, device,
nvif_fifo_runlist_ce(device), 0,
true, &drm->cechan);
} else
if (device->info.chipset >= 0xa3 &&
device->info.chipset != 0xaa &&
device->info.chipset != 0xac) {
/* Prior to Kepler, there's only a single runlist, so all
* engines can be accessed from any channel.
*
* We still want to use a separate channel though.
*/
ret = nouveau_channel_new(drm, device, NvDmaFB, NvDmaTT, false,
&drm->cechan);
runm = nvif_fifo_runlist_ce(device);
if (!runm) {
NV_DEBUG(drm, "no ce runlist\n");
return;
}
ret = nouveau_channel_new(drm, device, false, runm, NvDmaFB, NvDmaTT, &drm->cechan);
if (ret)
NV_ERROR(drm, "failed to create ce channel, %d\n", ret);
}
......@@ -355,23 +345,17 @@ static void
nouveau_accel_gr_init(struct nouveau_drm *drm)
{
struct nvif_device *device = &drm->client.device;
u32 arg0, arg1;
u64 runm;
int ret;
if (device->info.family >= NV_DEVICE_INFO_V0_AMPERE)
return;
/* Allocate channel that has access to the graphics engine. */
if (device->info.family >= NV_DEVICE_INFO_V0_KEPLER) {
arg0 = nvif_fifo_runlist(device, NV_DEVICE_HOST_RUNLIST_ENGINES_GR);
arg1 = 1;
} else {
arg0 = NvDmaFB;
arg1 = NvDmaTT;
runm = nvif_fifo_runlist(device, NV_DEVICE_HOST_RUNLIST_ENGINES_GR);
if (!runm) {
NV_DEBUG(drm, "no gr runlist\n");
return;
}
ret = nouveau_channel_new(drm, device, arg0, arg1, false,
&drm->channel);
ret = nouveau_channel_new(drm, device, false, runm, NvDmaFB, NvDmaTT, &drm->channel);
if (ret) {
NV_ERROR(drm, "failed to create kernel channel, %d\n", ret);
nouveau_accel_gr_fini(drm);
......@@ -436,6 +420,7 @@ nouveau_accel_fini(struct nouveau_drm *drm)
nouveau_accel_gr_fini(drm);
if (drm->fence)
nouveau_fence(drm)->dtor(drm);
nouveau_channels_fini(drm);
}
static void
......@@ -485,6 +470,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
case PASCAL_CHANNEL_GPFIFO_A:
case VOLTA_CHANNEL_GPFIFO_A:
case TURING_CHANNEL_GPFIFO_A:
case AMPERE_CHANNEL_GPFIFO_A:
case AMPERE_CHANNEL_GPFIFO_B:
ret = nvc0_fence_create(drm);
break;
......@@ -611,7 +597,6 @@ nouveau_drm_device_init(struct drm_device *dev)
nouveau_hwmon_init(dev);
nouveau_svm_init(drm);
nouveau_dmem_init(drm);
nouveau_fbcon_init(dev);
nouveau_led_init(dev);
if (nouveau_pmops_runtime()) {
......@@ -655,7 +640,6 @@ nouveau_drm_device_fini(struct drm_device *dev)
}
nouveau_led_fini(dev);
nouveau_fbcon_fini(dev);
nouveau_dmem_fini(drm);
nouveau_svm_fini(drm);
nouveau_hwmon_fini(dev);
......@@ -809,6 +793,11 @@ static int nouveau_drm_probe(struct pci_dev *pdev,
if (ret)
goto fail_drm_dev_init;
if (nouveau_drm(drm_dev)->client.device.info.ram_size <= 32 * 1024 * 1024)
drm_fbdev_generic_setup(drm_dev, 8);
else
drm_fbdev_generic_setup(drm_dev, 32);
quirk_broken_nv_runpm(pdev);
return 0;
......@@ -865,8 +854,6 @@ nouveau_do_suspend(struct drm_device *dev, bool runtime)
nouveau_led_suspend(dev);
if (dev->mode_config.num_crtc) {
NV_DEBUG(drm, "suspending console...\n");
nouveau_fbcon_set_suspend(dev, 1);
NV_DEBUG(drm, "suspending display...\n");
ret = nouveau_display_suspend(dev, runtime);
if (ret)
......@@ -940,8 +927,6 @@ nouveau_do_resume(struct drm_device *dev, bool runtime)
if (dev->mode_config.num_crtc) {
NV_DEBUG(drm, "resuming display...\n");
nouveau_display_resume(dev, runtime);
NV_DEBUG(drm, "resuming console...\n");
nouveau_fbcon_set_suspend(dev, 0);
}
nouveau_led_resume(dev);
......@@ -1296,7 +1281,6 @@ static void nouveau_display_options(void)
DRM_DEBUG_DRIVER("... tv_disable : %d\n", nouveau_tv_disable);
DRM_DEBUG_DRIVER("... ignorelid : %d\n", nouveau_ignorelid);
DRM_DEBUG_DRIVER("... duallink : %d\n", nouveau_duallink);
DRM_DEBUG_DRIVER("... nofbaccel : %d\n", nouveau_nofbaccel);
DRM_DEBUG_DRIVER("... config : %s\n", nouveau_config);
DRM_DEBUG_DRIVER("... debug : %s\n", nouveau_debug);
DRM_DEBUG_DRIVER("... noaccel : %d\n", nouveau_noaccel);
......
......@@ -78,11 +78,6 @@ enum nouveau_drm_object_route {
NVDRM_OBJECT_ANY = NVIF_IOCTL_V0_OWNER_ANY,
};
enum nouveau_drm_notify_route {
NVDRM_NOTIFY_NVIF = 0,
NVDRM_NOTIFY_USIF
};
enum nouveau_drm_handle {
NVDRM_CHAN = 0xcccc0000, /* |= client chid */
NVDRM_NVSW = 0x55550000,
......@@ -179,16 +174,19 @@ struct nouveau_drm {
void *fence;
/* Global channel management. */
int chan_total; /* Number of channels across all runlists. */
int chan_nr; /* 0 if per-runlist CHIDs. */
int runl_nr;
struct {
int nr;
int chan_nr;
int chan_id_base;
u64 context_base;
} chan;
} *runl;
/* context for accelerated drm-internal operations */
struct nouveau_channel *cechan;
struct nouveau_channel *channel;
struct nvkm_gpuobj *notify;
struct nouveau_fbdev *fbcon;
struct nvif_object ntfy;
/* nv10-nv40 tiling regions */
......@@ -201,10 +199,8 @@ struct nouveau_drm {
struct nvbios vbios;
struct nouveau_display *display;
struct work_struct hpd_work;
struct mutex hpd_lock;
spinlock_t hpd_lock;
u32 hpd_pending;
struct work_struct fbcon_work;
int fbcon_new_state;
#ifdef CONFIG_ACPI
struct notifier_block acpi_nb;
#endif
......
......@@ -48,7 +48,6 @@ struct nouveau_encoder {
struct dcb_output *dcb;
struct nvif_outp outp;
int or;
int link;
struct i2c_adapter *i2c;
struct nvkm_i2c_aux *aux;
......@@ -142,8 +141,8 @@ enum nouveau_dp_status {
};
int nouveau_dp_detect(struct nouveau_connector *, struct nouveau_encoder *);
void nouveau_dp_irq(struct nouveau_drm *drm,
struct nouveau_connector *nv_connector);
bool nouveau_dp_link_check(struct nouveau_connector *);
void nouveau_dp_irq(struct work_struct *);
enum drm_mode_status nv50_dp_mode_valid(struct drm_connector *,
struct nouveau_encoder *,
const struct drm_display_mode *,
......
This diff is collapsed.
/*
* Copyright (C) 2008 Maarten Maathuis.
* 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 (including the
* next paragraph) shall be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS 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.
*
*/
#ifndef __NOUVEAU_FBCON_H__
#define __NOUVEAU_FBCON_H__
#include <drm/drm_fb_helper.h>
#include "nouveau_display.h"
struct nouveau_vma;
struct nouveau_fbdev {
struct drm_fb_helper helper; /* must be first */
unsigned int saved_flags;
struct nvif_object surf2d;
struct nvif_object clip;
struct nvif_object rop;
struct nvif_object patt;
struct nvif_object gdi;
struct nvif_object blit;
struct nvif_object twod;
struct nouveau_vma *vma;
struct mutex hotplug_lock;
bool hotplug_waiting;
};
void nouveau_fbcon_restore(void);
int nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region);
int nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
int nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image);
int nv04_fbcon_accel_init(struct fb_info *info);
int nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
int nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region);
int nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image);
int nv50_fbcon_accel_init(struct fb_info *info);
int nvc0_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
int nvc0_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region);
int nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image);
int nvc0_fbcon_accel_init(struct fb_info *info);
void nouveau_fbcon_gpu_lockup(struct fb_info *info);
int nouveau_fbcon_init(struct drm_device *dev);
void nouveau_fbcon_fini(struct drm_device *dev);
void nouveau_fbcon_set_suspend(struct drm_device *dev, int state);
void nouveau_fbcon_accel_save_disable(struct drm_device *dev);
void nouveau_fbcon_accel_restore(struct drm_device *dev);
void nouveau_fbcon_output_poll_changed(struct drm_device *dev);
void nouveau_fbcon_hotplug_resume(struct nouveau_fbdev *fbcon);
extern int nouveau_nofbaccel;
#endif /* __NV50_FBCON_H__ */
......@@ -29,9 +29,7 @@
#include <linux/sched/signal.h>
#include <trace/events/dma_fence.h>
#include <nvif/cl826e.h>
#include <nvif/notify.h>
#include <nvif/event.h>
#include <nvif/if0020.h>
#include "nouveau_drv.h"
#include "nouveau_dma.h"
......@@ -79,10 +77,6 @@ nouveau_local_fence(struct dma_fence *fence, struct nouveau_drm *drm)
fence->ops != &nouveau_fence_ops_uevent)
return NULL;
if (fence->context < drm->chan.context_base ||
fence->context >= drm->chan.context_base + drm->chan.nr)
return NULL;
return from_fence(fence);
}
......@@ -90,8 +84,9 @@ void
nouveau_fence_context_kill(struct nouveau_fence_chan *fctx, int error)
{
struct nouveau_fence *fence;
unsigned long flags;
spin_lock_irq(&fctx->lock);
spin_lock_irqsave(&fctx->lock, flags);
while (!list_empty(&fctx->pending)) {
fence = list_entry(fctx->pending.next, typeof(*fence), head);
......@@ -99,16 +94,16 @@ nouveau_fence_context_kill(struct nouveau_fence_chan *fctx, int error)
dma_fence_set_error(&fence->base, error);
if (nouveau_fence_signal(fence))
nvif_notify_put(&fctx->notify);
nvif_event_block(&fctx->event);
}
spin_unlock_irq(&fctx->lock);
spin_unlock_irqrestore(&fctx->lock, flags);
}
void
nouveau_fence_context_del(struct nouveau_fence_chan *fctx)
{
nouveau_fence_context_kill(fctx, 0);
nvif_notify_dtor(&fctx->notify);
nvif_event_dtor(&fctx->event);
fctx->dead = 1;
/*
......@@ -150,12 +145,11 @@ nouveau_fence_update(struct nouveau_channel *chan, struct nouveau_fence_chan *fc
}
static int
nouveau_fence_wait_uevent_handler(struct nvif_notify *notify)
nouveau_fence_wait_uevent_handler(struct nvif_event *event, void *repv, u32 repc)
{
struct nouveau_fence_chan *fctx =
container_of(notify, typeof(*fctx), notify);
struct nouveau_fence_chan *fctx = container_of(event, typeof(*fctx), event);
unsigned long flags;
int ret = NVIF_NOTIFY_KEEP;
int ret = NVIF_EVENT_KEEP;
spin_lock_irqsave(&fctx->lock, flags);
if (!list_empty(&fctx->pending)) {
......@@ -165,7 +159,7 @@ nouveau_fence_wait_uevent_handler(struct nvif_notify *notify)
fence = list_entry(fctx->pending.next, typeof(*fence), head);
chan = rcu_dereference_protected(fence->channel, lockdep_is_held(&fctx->lock));
if (nouveau_fence_update(chan, fctx))
ret = NVIF_NOTIFY_DROP;
ret = NVIF_EVENT_DROP;
}
spin_unlock_irqrestore(&fctx->lock, flags);
......@@ -177,12 +171,16 @@ nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_cha
{
struct nouveau_fence_priv *priv = (void*)chan->drm->fence;
struct nouveau_cli *cli = (void *)chan->user.client;
struct {
struct nvif_event_v0 base;
struct nvif_chan_event_v0 host;
} args;
int ret;
INIT_LIST_HEAD(&fctx->flip);
INIT_LIST_HEAD(&fctx->pending);
spin_lock_init(&fctx->lock);
fctx->context = chan->drm->chan.context_base + chan->chid;
fctx->context = chan->drm->runl[chan->runlist].context_base + chan->chid;
if (chan == chan->drm->cechan)
strcpy(fctx->name, "copy engine channel");
......@@ -195,13 +193,12 @@ nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_cha
if (!priv->uevent)
return;
ret = nvif_notify_ctor(&chan->user, "fenceNonStallIntr",
nouveau_fence_wait_uevent_handler,
false, NV826E_V0_NTFY_NON_STALL_INTERRUPT,
&(struct nvif_notify_uevent_req) { },
sizeof(struct nvif_notify_uevent_req),
sizeof(struct nvif_notify_uevent_rep),
&fctx->notify);
args.host.version = 0;
args.host.type = NVIF_CHAN_EVENT_V0_NON_STALL_INTR;
ret = nvif_event_ctor(&chan->user, "fenceNonStallIntr", (chan->runlist << 16) | chan->chid,
nouveau_fence_wait_uevent_handler, false,
&args.base, sizeof(args), &fctx->event);
WARN_ON(ret);
}
......@@ -230,7 +227,7 @@ nouveau_fence_emit(struct nouveau_fence *fence, struct nouveau_channel *chan)
spin_lock_irq(&fctx->lock);
if (nouveau_fence_update(chan, fctx))
nvif_notify_put(&fctx->notify);
nvif_event_block(&fctx->event);
list_add_tail(&fence->head, &fctx->pending);
spin_unlock_irq(&fctx->lock);
......@@ -254,7 +251,7 @@ nouveau_fence_done(struct nouveau_fence *fence)
spin_lock_irqsave(&fctx->lock, flags);
chan = rcu_dereference_protected(fence->channel, lockdep_is_held(&fctx->lock));
if (chan && nouveau_fence_update(chan, fctx))
nvif_notify_put(&fctx->notify);
nvif_event_block(&fctx->event);
spin_unlock_irqrestore(&fctx->lock, flags);
}
return dma_fence_is_signaled(&fence->base);
......@@ -505,13 +502,13 @@ static bool nouveau_fence_enable_signaling(struct dma_fence *f)
bool ret;
if (!fctx->notify_ref++)
nvif_notify_get(&fctx->notify);
nvif_event_allow(&fctx->event);
ret = nouveau_fence_no_signaling(f);
if (ret)
set_bit(DMA_FENCE_FLAG_USER_BITS, &fence->base.flags);
else if (!--fctx->notify_ref)
nvif_notify_put(&fctx->notify);
nvif_event_block(&fctx->event);
return ret;
}
......
......@@ -3,7 +3,7 @@
#define __NOUVEAU_FENCE_H__
#include <linux/dma-fence.h>
#include <nvif/notify.h>
#include <nvif/event.h>
struct nouveau_drm;
struct nouveau_bo;
......@@ -44,7 +44,7 @@ struct nouveau_fence_chan {
u32 context;
char name[32];
struct nvif_notify notify;
struct nvif_event event;
int notify_ref, dead;
};
......
......@@ -27,12 +27,10 @@
******************************************************************************/
#include <core/client.h>
#include <core/notify.h>
#include <core/ioctl.h>
#include <nvif/client.h>
#include <nvif/driver.h>
#include <nvif/notify.h>
#include <nvif/event.h>
#include <nvif/ioctl.h>
......@@ -71,11 +69,24 @@ nvkm_client_suspend(void *priv)
return nvkm_object_fini(&client->object, true);
}
static int
nvkm_client_event(u64 token, void *repv, u32 repc)
{
struct nvif_object *object = (void *)(unsigned long)token;
struct nvif_event *event = container_of(object, typeof(*event), object);
if (event->func(event, repv, repc) == NVIF_EVENT_KEEP)
return NVKM_EVENT_KEEP;
return NVKM_EVENT_DROP;
}
static int
nvkm_client_driver_init(const char *name, u64 device, const char *cfg,
const char *dbg, void **ppriv)
{
return nvkm_client_new(name, device, cfg, dbg, nvif_notify, (struct nvkm_client **)ppriv);
return nvkm_client_new(name, device, cfg, dbg, nvkm_client_event,
(struct nvkm_client **)ppriv);
}
const struct nvif_driver
......
......@@ -24,7 +24,7 @@
#include "nouveau_chan.h"
#include "nouveau_dmem.h"
#include <nvif/notify.h>
#include <nvif/event.h>
#include <nvif/object.h>
#include <nvif/vmm.h>
......@@ -51,7 +51,8 @@ struct nouveau_svm {
u32 putaddr;
u32 get;
u32 put;
struct nvif_notify notify;
struct nvif_event notify;
struct work_struct work;
struct nouveau_svm_fault {
u64 inst;
......@@ -711,13 +712,11 @@ static int nouveau_range_fault(struct nouveau_svmm *svmm,
return ret;
}
static int
nouveau_svm_fault(struct nvif_notify *notify)
static void
nouveau_svm_fault(struct work_struct *work)
{
struct nouveau_svm_fault_buffer *buffer =
container_of(notify, typeof(*buffer), notify);
struct nouveau_svm *svm =
container_of(buffer, typeof(*svm), buffer[buffer->id]);
struct nouveau_svm_fault_buffer *buffer = container_of(work, typeof(*buffer), work);
struct nouveau_svm *svm = container_of(buffer, typeof(*svm), buffer[buffer->id]);
struct nvif_object *device = &svm->drm->client.device.object;
struct nouveau_svmm *svmm;
struct {
......@@ -737,7 +736,7 @@ nouveau_svm_fault(struct nvif_notify *notify)
buffer->put = nvif_rd32(device, buffer->putaddr);
buffer->get = nvif_rd32(device, buffer->getaddr);
if (buffer->get == buffer->put)
return NVIF_NOTIFY_KEEP;
return;
}
buffer->fault_nr = 0;
......@@ -881,7 +880,15 @@ nouveau_svm_fault(struct nvif_notify *notify)
/* Issue fault replay to the GPU. */
if (replay)
nouveau_svm_fault_replay(svm);
return NVIF_NOTIFY_KEEP;
}
static int
nouveau_svm_event(struct nvif_event *event, void *argv, u32 argc)
{
struct nouveau_svm_fault_buffer *buffer = container_of(event, typeof(*buffer), notify);
schedule_work(&buffer->work);
return NVIF_EVENT_KEEP;
}
static struct nouveau_pfnmap_args *
......@@ -936,7 +943,9 @@ static void
nouveau_svm_fault_buffer_fini(struct nouveau_svm *svm, int id)
{
struct nouveau_svm_fault_buffer *buffer = &svm->buffer[id];
nvif_notify_put(&buffer->notify);
nvif_event_block(&buffer->notify);
flush_work(&buffer->work);
}
static int
......@@ -944,10 +953,12 @@ nouveau_svm_fault_buffer_init(struct nouveau_svm *svm, int id)
{
struct nouveau_svm_fault_buffer *buffer = &svm->buffer[id];
struct nvif_object *device = &svm->drm->client.device.object;
buffer->get = nvif_rd32(device, buffer->getaddr);
buffer->put = nvif_rd32(device, buffer->putaddr);
SVM_DBG(svm, "get %08x put %08x (init)", buffer->get, buffer->put);
return nvif_notify_get(&buffer->notify);
return nvif_event_allow(&buffer->notify);
}
static void
......@@ -956,15 +967,18 @@ nouveau_svm_fault_buffer_dtor(struct nouveau_svm *svm, int id)
struct nouveau_svm_fault_buffer *buffer = &svm->buffer[id];
int i;
if (!nvif_object_constructed(&buffer->object))
return;
nouveau_svm_fault_buffer_fini(svm, id);
if (buffer->fault) {
for (i = 0; buffer->fault[i] && i < buffer->entries; i++)
kfree(buffer->fault[i]);
kvfree(buffer->fault);
}
nouveau_svm_fault_buffer_fini(svm, id);
nvif_notify_dtor(&buffer->notify);
nvif_event_dtor(&buffer->notify);
nvif_object_dtor(&buffer->object);
}
......@@ -990,10 +1004,10 @@ nouveau_svm_fault_buffer_ctor(struct nouveau_svm *svm, s32 oclass, int id)
buffer->entries = args.entries;
buffer->getaddr = args.get;
buffer->putaddr = args.put;
INIT_WORK(&buffer->work, nouveau_svm_fault);
ret = nvif_notify_ctor(&buffer->object, "svmFault", nouveau_svm_fault,
true, NVB069_V0_NTFY_FAULT, NULL, 0, 0,
&buffer->notify);
ret = nvif_event_ctor(&buffer->object, "svmFault", id, nouveau_svm_event, true, NULL, 0,
&buffer->notify);
if (ret)
return ret;
......
......@@ -151,12 +151,6 @@ usif_ioctl(struct drm_file *filp, void __user *user, u32 argc)
case NVIF_IOCTL_V0_NEW:
ret = usif_object_new(filp, data, size, argv, argc, abi16);
break;
case NVIF_IOCTL_V0_NTFY_NEW:
case NVIF_IOCTL_V0_NTFY_DEL:
case NVIF_IOCTL_V0_NTFY_GET:
case NVIF_IOCTL_V0_NTFY_PUT:
ret = -ENOSYS;
break;
default:
ret = nvif_client_ioctl(client, argv, argc);
break;
......
......@@ -7,7 +7,6 @@
#include "nouveau_drv.h"
#include "nouveau_acpi.h"
#include "nouveau_fbcon.h"
#include "nouveau_vga.h"
static unsigned int
......
This diff is collapsed.
This diff is collapsed.
......@@ -76,12 +76,18 @@ nv84_fence_sync32(struct nouveau_channel *chan, u64 virtual, u32 sequence)
return ret;
}
static inline u32
nv84_fence_chid(struct nouveau_channel *chan)
{
return chan->drm->runl[chan->runlist].chan_id_base + chan->chid;
}
static int
nv84_fence_emit(struct nouveau_fence *fence)
{
struct nouveau_channel *chan = fence->channel;
struct nv84_fence_chan *fctx = chan->fence;
u64 addr = fctx->vma->addr + chan->chid * 16;
u64 addr = fctx->vma->addr + nv84_fence_chid(chan) * 16;
return fctx->base.emit32(chan, addr, fence->base.seqno);
}
......@@ -91,7 +97,7 @@ nv84_fence_sync(struct nouveau_fence *fence,
struct nouveau_channel *prev, struct nouveau_channel *chan)
{
struct nv84_fence_chan *fctx = chan->fence;
u64 addr = fctx->vma->addr + prev->chid * 16;
u64 addr = fctx->vma->addr + nv84_fence_chid(prev) * 16;
return fctx->base.sync32(chan, addr, fence->base.seqno);
}
......@@ -100,7 +106,7 @@ static u32
nv84_fence_read(struct nouveau_channel *chan)
{
struct nv84_fence_priv *priv = chan->drm->fence;
return nouveau_bo_rd32(priv->bo, chan->chid * 16/4);
return nouveau_bo_rd32(priv->bo, nv84_fence_chid(chan) * 16/4);
}
static void
......@@ -109,7 +115,7 @@ nv84_fence_context_del(struct nouveau_channel *chan)
struct nv84_fence_priv *priv = chan->drm->fence;
struct nv84_fence_chan *fctx = chan->fence;
nouveau_bo_wr32(priv->bo, chan->chid * 16 / 4, fctx->base.sequence);
nouveau_bo_wr32(priv->bo, nv84_fence_chid(chan) * 16 / 4, fctx->base.sequence);
mutex_lock(&priv->mutex);
nouveau_vma_del(&fctx->vma);
mutex_unlock(&priv->mutex);
......@@ -152,9 +158,9 @@ nv84_fence_suspend(struct nouveau_drm *drm)
struct nv84_fence_priv *priv = drm->fence;
int i;
priv->suspend = vmalloc(array_size(sizeof(u32), drm->chan.nr));
priv->suspend = vmalloc(array_size(sizeof(u32), drm->chan_total));
if (priv->suspend) {
for (i = 0; i < drm->chan.nr; i++)
for (i = 0; i < drm->chan_total; i++)
priv->suspend[i] = nouveau_bo_rd32(priv->bo, i*4);
}
......@@ -168,7 +174,7 @@ nv84_fence_resume(struct nouveau_drm *drm)
int i;
if (priv->suspend) {
for (i = 0; i < drm->chan.nr; i++)
for (i = 0; i < drm->chan_total; i++)
nouveau_bo_wr32(priv->bo, i*4, priv->suspend[i]);
vfree(priv->suspend);
priv->suspend = NULL;
......@@ -204,7 +210,7 @@ nv84_fence_create(struct nouveau_drm *drm)
priv->base.context_new = nv84_fence_context_new;
priv->base.context_del = nv84_fence_context_del;
priv->base.uevent = drm->client.device.info.family < NV_DEVICE_INFO_V0_AMPERE;
priv->base.uevent = true;
mutex_init(&priv->mutex);
......@@ -216,7 +222,7 @@ nv84_fence_create(struct nouveau_drm *drm)
* will lose CPU/GPU coherency!
*/
NOUVEAU_GEM_DOMAIN_GART | NOUVEAU_GEM_DOMAIN_COHERENT;
ret = nouveau_bo_new(&drm->client, 16 * drm->chan.nr, 0,
ret = nouveau_bo_new(&drm->client, 16 * drm->chan_total, 0,
domain, 0, 0, NULL, NULL, &priv->bo);
if (ret == 0) {
ret = nouveau_bo_pin(priv->bo, domain, false);
......
This diff is collapsed.
......@@ -5,10 +5,11 @@ nvif-y += nvif/conn.o
nvif-y += nvif/device.o
nvif-y += nvif/disp.o
nvif-y += nvif/driver.o
nvif-y += nvif/event.o
nvif-y += nvif/fifo.o
nvif-y += nvif/head.o
nvif-y += nvif/mem.o
nvif-y += nvif/mmu.o
nvif-y += nvif/notify.o
nvif-y += nvif/outp.o
nvif-y += nvif/timer.o
nvif-y += nvif/vmm.o
......
......@@ -26,6 +26,25 @@
#include <nvif/class.h>
#include <nvif/if0011.h>
int
nvif_conn_event_ctor(struct nvif_conn *conn, const char *name, nvif_event_func func, u8 types,
struct nvif_event *event)
{
struct {
struct nvif_event_v0 base;
struct nvif_conn_event_v0 conn;
} args;
int ret;
args.conn.version = 0;
args.conn.types = types;
ret = nvif_event_ctor_(&conn->object, name ?: "nvifConnHpd", nvif_conn_id(conn),
func, true, &args.base, sizeof(args), false, event);
NVIF_DEBUG(&conn->object, "[NEW EVENT:HPD types:%02x]", types);
return ret;
}
int
nvif_conn_hpd_status(struct nvif_conn *conn)
{
......
......@@ -72,9 +72,10 @@ nvif_disp_ctor(struct nvif_device *device, const char *name, s32 oclass, struct
if (ret)
return ret;
NVIF_DEBUG(&disp->object, "[NEW] conn_mask:%08x outp_mask:%08x",
args.conn_mask, args.outp_mask);
NVIF_DEBUG(&disp->object, "[NEW] conn_mask:%08x outp_mask:%08x head_mask:%08x",
args.conn_mask, args.outp_mask, args.head_mask);
disp->conn_mask = args.conn_mask;
disp->outp_mask = args.outp_mask;
disp->head_mask = args.head_mask;
return 0;
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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