提交 57b4f7e6 编写于 作者: D Dave Airlie

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

- gk20a instmem fixes / improvements
- more gm10x vs gm20x differences deal with
- better support for high-frequency hdmi modes
- pstate control interfaces moved to debugfs
- support for pcie link speed changes
- misc other fixes across the board

* 'linux-4.5' of git://github.com/skeggsb/linux: (50 commits)
  drm/nouveau/pmu: prevent falcon from acking interrupts routed to the host
  drm/nouveau/perf: change pcie speed on pstate change
  drm/nouveau/perf: add fields for pci speed and width and use it for the pstates
  drm/nouveau/bios/perf: parse the pci speed from the bios for tesla and newer cards
  drm/nouveau/pci: implement pcie speed change for kepler+
  drm/nouveau/pci: implement pcie speed change for Fermi
  drm/nouveau/pci: implement pcie speed change for tesla
  drm/nouveau/pci: implement generic code for pcie speed change
  drm/nouveau/pci: add gk104 variant
  drm/nouveau/pci: add gf106 variant
  drm/nouveau/kms: take mode_config mutex in connector hotplug path
  drm/nouveau/nouveau/perfmon: add interface files for current core voltage
  drm/nouveau/sysfs: remove pstate interface
  drm/nouveau/debugfs: add copy of sysfs pstate interface ported to debugfs
  drm/nouveau/debugfs: we need a ctrl object for debugfs
  drm/nouveau/debugfs: rename functions to indicate they are used inside drm
  drm/nouveau/debugfs: add infrastructure to add files with other fops than only read
  drm/nouveau/fifo/gf100: remove references to "daemon"
  drm/nouveau/fb/nv50: remove references to "daemon"
  drm/nouveau/clk: remove references to "daemon"
  ...
......@@ -24,7 +24,6 @@ nouveau-y += nouveau_hwmon.o
nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o
nouveau-y += nouveau_nvif.o
nouveau-$(CONFIG_NOUVEAU_PLATFORM_DRIVER) += nouveau_platform.o
nouveau-y += nouveau_sysfs.o
nouveau-y += nouveau_usif.o # userspace <-> nvif
nouveau-y += nouveau_vga.o
......
#ifndef __NVIF_CL0002_H__
#define __NVIF_CL0002_H__
struct nv_dma_v0 {
__u8 version;
#define NV_DMA_V0_TARGET_VM 0x00
#define NV_DMA_V0_TARGET_VRAM 0x01
#define NV_DMA_V0_TARGET_PCI 0x02
#define NV_DMA_V0_TARGET_PCI_US 0x03
#define NV_DMA_V0_TARGET_AGP 0x04
__u8 target;
#define NV_DMA_V0_ACCESS_VM 0x00
#define NV_DMA_V0_ACCESS_RD 0x01
#define NV_DMA_V0_ACCESS_WR 0x02
#define NV_DMA_V0_ACCESS_RDWR (NV_DMA_V0_ACCESS_RD | NV_DMA_V0_ACCESS_WR)
__u8 access;
__u8 pad03[5];
__u64 start;
__u64 limit;
/* ... chipset-specific class data */
};
struct nv50_dma_v0 {
__u8 version;
#define NV50_DMA_V0_PRIV_VM 0x00
#define NV50_DMA_V0_PRIV_US 0x01
#define NV50_DMA_V0_PRIV__S 0x02
__u8 priv;
#define NV50_DMA_V0_PART_VM 0x00
#define NV50_DMA_V0_PART_256 0x01
#define NV50_DMA_V0_PART_1KB 0x02
__u8 part;
#define NV50_DMA_V0_COMP_NONE 0x00
#define NV50_DMA_V0_COMP_1 0x01
#define NV50_DMA_V0_COMP_2 0x02
#define NV50_DMA_V0_COMP_VM 0x03
__u8 comp;
#define NV50_DMA_V0_KIND_PITCH 0x00
#define NV50_DMA_V0_KIND_VM 0x7f
__u8 kind;
__u8 pad05[3];
};
struct gf100_dma_v0 {
__u8 version;
#define GF100_DMA_V0_PRIV_VM 0x00
#define GF100_DMA_V0_PRIV_US 0x01
#define GF100_DMA_V0_PRIV__S 0x02
__u8 priv;
#define GF100_DMA_V0_KIND_PITCH 0x00
#define GF100_DMA_V0_KIND_VM 0xff
__u8 kind;
__u8 pad03[5];
};
struct gf119_dma_v0 {
__u8 version;
#define GF119_DMA_V0_PAGE_LP 0x00
#define GF119_DMA_V0_PAGE_SP 0x01
__u8 page;
#define GF119_DMA_V0_KIND_PITCH 0x00
#define GF119_DMA_V0_KIND_VM 0xff
__u8 kind;
__u8 pad03[5];
};
#endif
#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
#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
#ifndef __NVIF_CL0080_H__
#define __NVIF_CL0080_H__
struct nv_device_v0 {
__u8 version;
__u8 pad01[7];
__u64 device; /* device identifier, ~0 for client default */
};
#define NV_DEVICE_V0_INFO 0x00
#define NV_DEVICE_V0_TIME 0x01
struct nv_device_info_v0 {
__u8 version;
#define NV_DEVICE_INFO_V0_IGP 0x00
#define NV_DEVICE_INFO_V0_PCI 0x01
#define NV_DEVICE_INFO_V0_AGP 0x02
#define NV_DEVICE_INFO_V0_PCIE 0x03
#define NV_DEVICE_INFO_V0_SOC 0x04
__u8 platform;
__u16 chipset; /* from NV_PMC_BOOT_0 */
__u8 revision; /* from NV_PMC_BOOT_0 */
#define NV_DEVICE_INFO_V0_TNT 0x01
#define NV_DEVICE_INFO_V0_CELSIUS 0x02
#define NV_DEVICE_INFO_V0_KELVIN 0x03
#define NV_DEVICE_INFO_V0_RANKINE 0x04
#define NV_DEVICE_INFO_V0_CURIE 0x05
#define NV_DEVICE_INFO_V0_TESLA 0x06
#define NV_DEVICE_INFO_V0_FERMI 0x07
#define NV_DEVICE_INFO_V0_KEPLER 0x08
#define NV_DEVICE_INFO_V0_MAXWELL 0x09
__u8 family;
__u8 pad06[2];
__u64 ram_size;
__u64 ram_user;
char chip[16];
char name[64];
};
struct nv_device_time_v0 {
__u8 version;
__u8 pad01[7];
__u64 time;
};
#endif
#ifndef __NVIF_CL506E_H__
#define __NVIF_CL506E_H__
struct nv50_channel_dma_v0 {
__u8 version;
__u8 chid;
__u8 pad02[6];
__u64 vm;
__u64 pushbuf;
__u64 offset;
};
#endif
#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 vm;
};
#endif
#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_DAC_PWR 0x10
#define NV50_DISP_MTHD_V1_DAC_LOAD 0x11
#define NV50_DISP_MTHD_V1_SOR_PWR 0x20
#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_PWR 0x24
#define NV50_DISP_MTHD_V1_PIOR_PWR 0x30
__u8 method;
__u16 hasht;
__u16 hashm;
__u8 pad06[2];
};
struct nv50_disp_dac_pwr_v0 {
__u8 version;
__u8 state;
__u8 data;
__u8 vsync;
__u8 hsync;
__u8 pad05[3];
};
struct nv50_disp_dac_load_v0 {
__u8 version;
__u8 load;
__u8 pad02[2];
__u32 data;
};
struct nv50_disp_sor_pwr_v0 {
__u8 version;
__u8 state;
__u8 pad02[6];
};
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 pad04[4];
};
struct nv50_disp_sor_lvds_script_v0 {
__u8 version;
__u8 pad01[1];
__u16 script;
__u8 pad04[4];
};
struct nv50_disp_sor_dp_pwr_v0 {
__u8 version;
__u8 state;
__u8 pad02[6];
};
struct nv50_disp_pior_pwr_v0 {
__u8 version;
__u8 state;
__u8 type;
__u8 pad03[5];
};
#endif
#ifndef __NVIF_CL507A_H__
#define __NVIF_CL507A_H__
struct nv50_disp_cursor_v0 {
__u8 version;
__u8 head;
__u8 pad02[6];
};
#define NV50_DISP_CURSOR_V0_NTFY_UEVENT 0x00
#endif
#ifndef __NVIF_CL507B_H__
#define __NVIF_CL507B_H__
struct nv50_disp_overlay_v0 {
__u8 version;
__u8 head;
__u8 pad02[6];
};
#define NV50_DISP_OVERLAY_V0_NTFY_UEVENT 0x00
#endif
#ifndef __NVIF_CL507C_H__
#define __NVIF_CL507C_H__
struct nv50_disp_base_channel_dma_v0 {
__u8 version;
__u8 head;
__u8 pad02[6];
__u64 pushbuf;
};
#define NV50_DISP_BASE_CHANNEL_DMA_V0_NTFY_UEVENT 0x00
#endif
#ifndef __NVIF_CL507D_H__
#define __NVIF_CL507D_H__
struct nv50_disp_core_channel_dma_v0 {
__u8 version;
__u8 pad01[7];
__u64 pushbuf;
};
#define NV50_DISP_CORE_CHANNEL_DMA_V0_NTFY_UEVENT 0x00
#endif
#ifndef __NVIF_CL507E_H__
#define __NVIF_CL507E_H__
struct nv50_disp_overlay_channel_dma_v0 {
__u8 version;
__u8 head;
__u8 pad02[6];
__u64 pushbuf;
};
#define NV50_DISP_OVERLAY_CHANNEL_DMA_V0_NTFY_UEVENT 0x00
#endif
#ifndef __NVIF_CL826E_H__
#define __NVIF_CL826E_H__
struct g82_channel_dma_v0 {
__u8 version;
__u8 chid;
__u8 pad02[6];
__u64 vm;
__u64 pushbuf;
__u64 offset;
};
#define G82_CHANNEL_DMA_V0_NTFY_UEVENT 0x00
#endif
#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 vm;
};
#define G82_CHANNEL_GPFIFO_V0_NTFY_UEVENT 0x00
#endif
#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 vm;
};
#define FERMI_CHANNEL_GPFIFO_V0_NTFY_UEVENT 0x00
#endif
#ifndef __NVIF_CL9097_H__
#define __NVIF_CL9097_H__
#define FERMI_A_ZBC_COLOR 0x00
#define FERMI_A_ZBC_DEPTH 0x01
struct fermi_a_zbc_color_v0 {
__u8 version;
#define FERMI_A_ZBC_COLOR_V0_FMT_ZERO 0x01
#define FERMI_A_ZBC_COLOR_V0_FMT_UNORM_ONE 0x02
#define FERMI_A_ZBC_COLOR_V0_FMT_RF32_GF32_BF32_AF32 0x04
#define FERMI_A_ZBC_COLOR_V0_FMT_R16_G16_B16_A16 0x08
#define FERMI_A_ZBC_COLOR_V0_FMT_RN16_GN16_BN16_AN16 0x0c
#define FERMI_A_ZBC_COLOR_V0_FMT_RS16_GS16_BS16_AS16 0x10
#define FERMI_A_ZBC_COLOR_V0_FMT_RU16_GU16_BU16_AU16 0x14
#define FERMI_A_ZBC_COLOR_V0_FMT_RF16_GF16_BF16_AF16 0x16
#define FERMI_A_ZBC_COLOR_V0_FMT_A8R8G8B8 0x18
#define FERMI_A_ZBC_COLOR_V0_FMT_A8RL8GL8BL8 0x1c
#define FERMI_A_ZBC_COLOR_V0_FMT_A2B10G10R10 0x20
#define FERMI_A_ZBC_COLOR_V0_FMT_AU2BU10GU10RU10 0x24
#define FERMI_A_ZBC_COLOR_V0_FMT_A8B8G8R8 0x28
#define FERMI_A_ZBC_COLOR_V0_FMT_A8BL8GL8RL8 0x2c
#define FERMI_A_ZBC_COLOR_V0_FMT_AN8BN8GN8RN8 0x30
#define FERMI_A_ZBC_COLOR_V0_FMT_AS8BS8GS8RS8 0x34
#define FERMI_A_ZBC_COLOR_V0_FMT_AU8BU8GU8RU8 0x38
#define FERMI_A_ZBC_COLOR_V0_FMT_A2R10G10B10 0x3c
#define FERMI_A_ZBC_COLOR_V0_FMT_BF10GF11RF11 0x40
__u8 format;
__u8 index;
__u8 pad03[5];
__u32 ds[4];
__u32 l2[4];
};
struct fermi_a_zbc_depth_v0 {
__u8 version;
#define FERMI_A_ZBC_DEPTH_V0_FMT_FP32 0x01
__u8 format;
__u8 index;
__u8 pad03[5];
__u32 ds;
__u32 l2;
};
#endif
#ifndef __NVIF_CLA06F_H__
#define __NVIF_CLA06F_H__
struct kepler_channel_gpfifo_a_v0 {
__u8 version;
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_GR 0x01
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_MSPDEC 0x02
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_MSPPP 0x04
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_MSVLD 0x08
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_CE0 0x10
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_CE1 0x20
#define KEPLER_CHANNEL_GPFIFO_A_V0_ENGINE_ENC 0x40
__u8 engine;
__u16 chid;
__u32 ilength;
__u64 ioffset;
__u64 vm;
};
#define KEPLER_CHANNEL_GPFIFO_A_V0_NTFY_UEVENT 0x00
#endif
......@@ -2,7 +2,7 @@
#define __NVIF_DEVICE_H__
#include <nvif/object.h>
#include <nvif/class.h>
#include <nvif/cl0080.h>
struct nvif_device {
struct nvif_object object;
......@@ -63,6 +63,7 @@ u64 nvif_device_time(struct nvif_device *);
#define nvxx_clk(a) nvxx_device(a)->clk
#define nvxx_i2c(a) nvxx_device(a)->i2c
#define nvxx_therm(a) nvxx_device(a)->therm
#define nvxx_volt(a) nvxx_device(a)->volt
#include <core/device.h>
#include <engine/fifo.h>
......
#ifndef __NVIF_IF0000_H__
#define __NVIF_IF0000_H__
#define NV_CLIENT_DEVLIST 0x00
struct nv_client_devlist_v0 {
__u8 version;
__u8 count;
__u8 pad02[6];
__u64 device[];
};
#endif
#ifndef __NVIF_IF0001_H__
#define __NVIF_IF0001_H__
#define NVIF_CONTROL_PSTATE_INFO 0x00
#define NVIF_CONTROL_PSTATE_ATTR 0x01
#define NVIF_CONTROL_PSTATE_USER 0x02
struct nvif_control_pstate_info_v0 {
__u8 version;
__u8 count; /* out: number of power states */
#define NVIF_CONTROL_PSTATE_INFO_V0_USTATE_DISABLE (-1)
#define NVIF_CONTROL_PSTATE_INFO_V0_USTATE_PERFMON (-2)
__s8 ustate_ac; /* out: target pstate index */
__s8 ustate_dc; /* out: target pstate index */
__s8 pwrsrc; /* out: current power source */
#define NVIF_CONTROL_PSTATE_INFO_V0_PSTATE_UNKNOWN (-1)
#define NVIF_CONTROL_PSTATE_INFO_V0_PSTATE_PERFMON (-2)
__s8 pstate; /* out: current pstate index */
__u8 pad06[2];
};
struct nvif_control_pstate_attr_v0 {
__u8 version;
#define NVIF_CONTROL_PSTATE_ATTR_V0_STATE_CURRENT (-1)
__s8 state; /* in: index of pstate to query
* out: pstate identifier
*/
__u8 index; /* in: index of attribute to query
* out: index of next attribute, or 0 if no more
*/
__u8 pad03[5];
__u32 min;
__u32 max;
char name[32];
char unit[16];
};
struct nvif_control_pstate_user_v0 {
__u8 version;
#define NVIF_CONTROL_PSTATE_USER_V0_STATE_UNKNOWN (-1)
#define NVIF_CONTROL_PSTATE_USER_V0_STATE_PERFMON (-2)
__s8 ustate; /* in: pstate identifier */
__s8 pwrsrc; /* in: target power source */
__u8 pad03[5];
};
#endif
#ifndef __NVIF_IF0002_H__
#define __NVIF_IF0002_H__
#define NVIF_PERFMON_V0_QUERY_DOMAIN 0x00
#define NVIF_PERFMON_V0_QUERY_SIGNAL 0x01
#define NVIF_PERFMON_V0_QUERY_SOURCE 0x02
struct nvif_perfmon_query_domain_v0 {
__u8 version;
__u8 id;
__u8 counter_nr;
__u8 iter;
__u16 signal_nr;
__u8 pad05[2];
char name[64];
};
struct nvif_perfmon_query_signal_v0 {
__u8 version;
__u8 domain;
__u16 iter;
__u8 signal;
__u8 source_nr;
__u8 pad05[2];
char name[64];
};
struct nvif_perfmon_query_source_v0 {
__u8 version;
__u8 domain;
__u8 signal;
__u8 iter;
__u8 pad04[4];
__u32 source;
__u32 mask;
char name[64];
};
#endif
#ifndef __NVIF_IF0003_H__
#define __NVIF_IF0003_H__
struct nvif_perfdom_v0 {
__u8 version;
__u8 domain;
__u8 mode;
__u8 pad03[1];
struct {
__u8 signal[4];
__u64 source[4][8];
__u16 logic_op;
} ctr[4];
};
#define NVIF_PERFDOM_V0_INIT 0x00
#define NVIF_PERFDOM_V0_SAMPLE 0x01
#define NVIF_PERFDOM_V0_READ 0x02
struct nvif_perfdom_init {
};
struct nvif_perfdom_sample {
};
struct nvif_perfdom_read_v0 {
__u8 version;
__u8 pad01[7];
__u32 ctr[4];
__u32 clk;
__u8 pad04[4];
};
#endif
#ifndef __NVIF_IF0004_H__
#define __NVIF_IF0004_H__
#define NV04_NVSW_NTFY_UEVENT 0x00
#define NV04_NVSW_GET_REF 0x00
struct nv04_nvsw_get_ref_v0 {
__u8 version;
__u8 pad01[3];
__u32 ref;
};
#endif
#ifndef __NVIF_IF0005_H__
#define __NVIF_IF0005_H__
#define NV10_NVSW_NTFY_UEVENT 0x00
#endif
......@@ -55,14 +55,6 @@ struct nvif_ioctl_new_v0 {
__u64 token;
__u64 object;
__u32 handle;
/* these class numbers are made up by us, and not nvidia-assigned */
#define NVIF_IOCTL_NEW_V0_CONTROL -1
#define NVIF_IOCTL_NEW_V0_PERFMON -2
#define NVIF_IOCTL_NEW_V0_PERFDOM -3
#define NVIF_IOCTL_NEW_V0_SW_NV04 -4
#define NVIF_IOCTL_NEW_V0_SW_NV10 -5
#define NVIF_IOCTL_NEW_V0_SW_NV50 -6
#define NVIF_IOCTL_NEW_V0_SW_GF100 -7
__s32 oclass;
__u8 data[]; /* class data (class.h) */
};
......
#ifndef __NVIF_UNPACK_H__
#define __NVIF_UNPACK_H__
#define nvif_unvers(d) ({ \
ret = (size == sizeof(d)) ? 0 : -ENOSYS; \
(ret == 0); \
#define nvif_unvers(r,d,s,m) ({ \
void **_data = (d); __u32 *_size = (s); int _ret = (r); \
if (_ret == -ENOSYS && *_size == sizeof(m)) { \
*_data = NULL; \
*_size = _ret = 0; \
} \
_ret; \
})
#define nvif_unpack(d,vl,vh,m) ({ \
if ((vl) == 0 || ret == -ENOSYS) { \
int _size = sizeof(d); \
if (_size <= size && (d).version >= (vl) && \
(d).version <= (vh)) { \
data = (u8 *)data + _size; \
size = size - _size; \
ret = ((m) || !size) ? 0 : -E2BIG; \
} else { \
ret = -ENOSYS; \
#define nvif_unpack(r,d,s,m,vl,vh,x) ({ \
void **_data = (d); __u32 *_size = (s); \
int _ret = (r), _vl = (vl), _vh = (vh); \
if (_ret == -ENOSYS && *_size >= sizeof(m) && \
(m).version >= _vl && (m).version <= _vh) { \
*_data = (__u8 *)*_data + sizeof(m); \
*_size = *_size - sizeof(m); \
if (_ret = 0, !(x)) { \
_ret = *_size ? -E2BIG : 0; \
*_data = NULL; \
*_size = 0; \
} \
} \
(ret == 0); \
_ret; \
})
#endif
......@@ -13,6 +13,8 @@ struct nvbios_perfE {
u32 vdec;
u32 disp;
u32 script;
u8 pcie_speed;
u8 pcie_width;
};
u16 nvbios_perf_entry(struct nvkm_bios *, int idx,
......
......@@ -2,6 +2,7 @@
#define __NVKM_CLK_H__
#include <core/subdev.h>
#include <core/notify.h>
#include <subdev/pci.h>
struct nvbios_pll;
struct nvkm_pll_vals;
......@@ -38,7 +39,7 @@ enum nv_clk_src {
nv_clk_src_hubk06,
nv_clk_src_hubk07,
nv_clk_src_copy,
nv_clk_src_daemon,
nv_clk_src_pmu,
nv_clk_src_disp,
nv_clk_src_vdec,
......@@ -59,6 +60,8 @@ struct nvkm_pstate {
struct nvkm_cstate base;
u8 pstate;
u8 fanspeed;
enum nvkm_pcie_speed pcie_speed;
u8 pcie_width;
};
struct nvkm_domain {
......
......@@ -6,4 +6,5 @@ int gf100_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **);
int gf117_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **);
int gk104_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **);
int gk20a_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **);
int gm204_ibus_new(struct nvkm_device *, int, struct nvkm_subdev **);
#endif
......@@ -37,4 +37,5 @@ int gf100_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **);
int gk104_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **);
int gk20a_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **);
int gm107_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **);
int gm204_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **);
#endif
......@@ -2,6 +2,12 @@
#define __NVKM_PCI_H__
#include <core/subdev.h>
enum nvkm_pcie_speed {
NVKM_PCIE_SPEED_2_5,
NVKM_PCIE_SPEED_5_0,
NVKM_PCIE_SPEED_8_0,
};
struct nvkm_pci {
const struct nvkm_pci_func *func;
struct nvkm_subdev subdev;
......@@ -18,6 +24,11 @@ struct nvkm_pci {
bool acquired;
} agp;
struct {
enum nvkm_pcie_speed speed;
u8 width;
} pcie;
bool msi;
};
......@@ -34,4 +45,9 @@ int nv4c_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
int g84_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
int g94_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
int gf100_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
int gf106_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
int gk104_pci_new(struct nvkm_device *, int, struct nvkm_pci **);
/* pcie functions */
int nvkm_pcie_set_link(struct nvkm_pci *, enum nvkm_pcie_speed, u8 width);
#endif
......@@ -25,6 +25,8 @@
#include <nvif/driver.h>
#include <nvif/ioctl.h>
#include <nvif/class.h>
#include <nvif/cl0002.h>
#include <nvif/cla06f.h>
#include <nvif/unpack.h>
#include "nouveau_drm.h"
......@@ -87,18 +89,18 @@ nouveau_abi16_swclass(struct nouveau_drm *drm)
{
switch (drm->device.info.family) {
case NV_DEVICE_INFO_V0_TNT:
return NVIF_IOCTL_NEW_V0_SW_NV04;
return NVIF_CLASS_SW_NV04;
case NV_DEVICE_INFO_V0_CELSIUS:
case NV_DEVICE_INFO_V0_KELVIN:
case NV_DEVICE_INFO_V0_RANKINE:
case NV_DEVICE_INFO_V0_CURIE:
return NVIF_IOCTL_NEW_V0_SW_NV10;
return NVIF_CLASS_SW_NV10;
case NV_DEVICE_INFO_V0_TESLA:
return NVIF_IOCTL_NEW_V0_SW_NV50;
return NVIF_CLASS_SW_NV50;
case NV_DEVICE_INFO_V0_FERMI:
case NV_DEVICE_INFO_V0_KEPLER:
case NV_DEVICE_INFO_V0_MAXWELL:
return NVIF_IOCTL_NEW_V0_SW_GF100;
return NVIF_CLASS_SW_GF100;
}
return 0x0000;
......@@ -355,9 +357,9 @@ nouveau_abi16_usif(struct drm_file *file_priv, void *data, u32 size)
} *args = data;
struct nouveau_abi16_chan *chan;
struct nouveau_abi16 *abi16;
int ret;
int ret = -ENOSYS;
if (nvif_unpack(args->v0, 0, 0, true)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
switch (args->v0.type) {
case NVIF_IOCTL_V0_NEW:
case NVIF_IOCTL_V0_MTHD:
......@@ -433,10 +435,10 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS)
/* nvsw: compatibility with older 0x*6e class identifier */
for (i = 0; !oclass && i < ret; i++) {
switch (sclass[i].oclass) {
case NVIF_IOCTL_NEW_V0_SW_NV04:
case NVIF_IOCTL_NEW_V0_SW_NV10:
case NVIF_IOCTL_NEW_V0_SW_NV50:
case NVIF_IOCTL_NEW_V0_SW_GF100:
case NVIF_CLASS_SW_NV04:
case NVIF_CLASS_SW_NV10:
case NVIF_CLASS_SW_NV50:
case NVIF_CLASS_SW_GF100:
oclass = sclass[i].oclass;
break;
default:
......
......@@ -24,6 +24,11 @@
#include <nvif/os.h>
#include <nvif/class.h>
#include <nvif/cl0002.h>
#include <nvif/cl006b.h>
#include <nvif/cl506f.h>
#include <nvif/cl906f.h>
#include <nvif/cla06f.h>
#include <nvif/ioctl.h>
/*XXX*/
......@@ -378,7 +383,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
/* allocate software object class (used for fences on <= nv05) */
if (device->info.family < NV_DEVICE_INFO_V0_CELSIUS) {
ret = nvif_object_init(&chan->user, 0x006e,
NVIF_IOCTL_NEW_V0_SW_NV04,
NVIF_CLASS_SW_NV04,
NULL, 0, &chan->nvsw);
if (ret)
return ret;
......
......@@ -42,6 +42,8 @@
#include "nouveau_encoder.h"
#include "nouveau_crtc.h"
#include <nvif/class.h>
#include <nvif/cl0046.h>
#include <nvif/event.h>
MODULE_PARM_DESC(tv_disable, "Disable TV-out detection");
......@@ -56,6 +58,10 @@ MODULE_PARM_DESC(duallink, "Allow dual-link TMDS (default: enabled)");
int nouveau_duallink = 1;
module_param_named(duallink, nouveau_duallink, int, 0400);
MODULE_PARM_DESC(hdmimhz, "Force a maximum HDMI pixel clock (in MHz)");
int nouveau_hdmimhz = 0;
module_param_named(hdmimhz, nouveau_hdmimhz, int, 0400);
struct nouveau_encoder *
find_encoder(struct drm_connector *connector, int type)
{
......@@ -809,12 +815,23 @@ nouveau_connector_get_modes(struct drm_connector *connector)
}
static unsigned
get_tmds_link_bandwidth(struct drm_connector *connector)
get_tmds_link_bandwidth(struct drm_connector *connector, bool hdmi)
{
struct nouveau_connector *nv_connector = nouveau_connector(connector);
struct nouveau_drm *drm = nouveau_drm(connector->dev);
struct dcb_output *dcb = nv_connector->detected_encoder->dcb;
if (hdmi) {
if (nouveau_hdmimhz > 0)
return nouveau_hdmimhz * 1000;
/* Note: these limits are conservative, some Fermi's
* can do 297 MHz. Unclear how this can be determined.
*/
if (drm->device.info.family >= NV_DEVICE_INFO_V0_KEPLER)
return 297000;
if (drm->device.info.family >= NV_DEVICE_INFO_V0_FERMI)
return 225000;
}
if (dcb->location != DCB_LOC_ON_CHIP ||
drm->device.info.chipset >= 0x46)
return 165000;
......@@ -835,6 +852,7 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
struct drm_encoder *encoder = to_drm_encoder(nv_encoder);
unsigned min_clock = 25000, max_clock = min_clock;
unsigned clock = mode->clock;
bool hdmi;
switch (nv_encoder->dcb->type) {
case DCB_OUTPUT_LVDS:
......@@ -847,8 +865,10 @@ nouveau_connector_mode_valid(struct drm_connector *connector,
max_clock = 400000;
break;
case DCB_OUTPUT_TMDS:
max_clock = get_tmds_link_bandwidth(connector);
if (nouveau_duallink && nv_encoder->dcb->duallink_possible)
hdmi = drm_detect_hdmi_monitor(nv_connector->edid);
max_clock = get_tmds_link_bandwidth(connector, hdmi);
if (!hdmi && nouveau_duallink &&
nv_encoder->dcb->duallink_possible)
max_clock *= 2;
break;
case DCB_OUTPUT_ANALOG:
......@@ -963,10 +983,13 @@ nouveau_connector_hotplug(struct nvif_notify *notify)
NV_DEBUG(drm, "%splugged %s\n", plugged ? "" : "un", name);
mutex_lock(&drm->dev->mode_config.mutex);
if (plugged)
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
else
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
mutex_unlock(&drm->dev->mode_config.mutex);
drm_helper_hpd_irq_event(connector->dev);
}
......
......@@ -28,6 +28,9 @@
* Ben Skeggs <bskeggs@redhat.com>
*/
#include <linux/debugfs.h>
#include <nvif/class.h>
#include <nvif/if0001.h>
#include "nouveau_debugfs.h"
#include "nouveau_drm.h"
......@@ -43,22 +46,233 @@ nouveau_debugfs_vbios_image(struct seq_file *m, void *data)
return 0;
}
static int
nouveau_debugfs_pstate_get(struct seq_file *m, void *data)
{
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct nouveau_debugfs *debugfs = nouveau_debugfs(node->minor->dev);
struct nvif_object *ctrl = &debugfs->ctrl;
struct nvif_control_pstate_info_v0 info = {};
int ret, i;
if (!debugfs)
return -ENODEV;
ret = nvif_mthd(ctrl, NVIF_CONTROL_PSTATE_INFO, &info, sizeof(info));
if (ret)
return ret;
for (i = 0; i < info.count + 1; i++) {
const s32 state = i < info.count ? i :
NVIF_CONTROL_PSTATE_ATTR_V0_STATE_CURRENT;
struct nvif_control_pstate_attr_v0 attr = {
.state = state,
.index = 0,
};
ret = nvif_mthd(ctrl, NVIF_CONTROL_PSTATE_ATTR,
&attr, sizeof(attr));
if (ret)
return ret;
if (i < info.count)
seq_printf(m, "%02x:", attr.state);
else
seq_printf(m, "%s:", info.pwrsrc == 0 ? "DC" :
info.pwrsrc == 1 ? "AC" : "--");
attr.index = 0;
do {
attr.state = state;
ret = nvif_mthd(ctrl, NVIF_CONTROL_PSTATE_ATTR,
&attr, sizeof(attr));
if (ret)
return ret;
seq_printf(m, " %s %d", attr.name, attr.min);
if (attr.min != attr.max)
seq_printf(m, "-%d", attr.max);
seq_printf(m, " %s", attr.unit);
} while (attr.index);
if (state >= 0) {
if (info.ustate_ac == state)
seq_printf(m, " AC");
if (info.ustate_dc == state)
seq_printf(m, " DC");
if (info.pstate == state)
seq_printf(m, " *");
} else {
if (info.ustate_ac < -1)
seq_printf(m, " AC");
if (info.ustate_dc < -1)
seq_printf(m, " DC");
}
seq_printf(m, "\n");
}
return 0;
}
static ssize_t
nouveau_debugfs_pstate_set(struct file *file, const char __user *ubuf,
size_t len, loff_t *offp)
{
struct seq_file *m = file->private_data;
struct drm_info_node *node = (struct drm_info_node *) m->private;
struct nouveau_debugfs *debugfs = nouveau_debugfs(node->minor->dev);
struct nvif_object *ctrl = &debugfs->ctrl;
struct nvif_control_pstate_user_v0 args = { .pwrsrc = -EINVAL };
char buf[32] = {}, *tmp, *cur = buf;
long value, ret;
if (!debugfs)
return -ENODEV;
if (len >= sizeof(buf))
return -EINVAL;
if (copy_from_user(buf, ubuf, len))
return -EFAULT;
if ((tmp = strchr(buf, '\n')))
*tmp = '\0';
if (!strncasecmp(cur, "dc:", 3)) {
args.pwrsrc = 0;
cur += 3;
} else
if (!strncasecmp(cur, "ac:", 3)) {
args.pwrsrc = 1;
cur += 3;
}
if (!strcasecmp(cur, "none"))
args.ustate = NVIF_CONTROL_PSTATE_USER_V0_STATE_UNKNOWN;
else
if (!strcasecmp(cur, "auto"))
args.ustate = NVIF_CONTROL_PSTATE_USER_V0_STATE_PERFMON;
else {
ret = kstrtol(cur, 16, &value);
if (ret)
return ret;
args.ustate = value;
}
ret = nvif_mthd(ctrl, NVIF_CONTROL_PSTATE_USER, &args, sizeof(args));
if (ret < 0)
return ret;
return len;
}
static int
nouveau_debugfs_pstate_open(struct inode *inode, struct file *file)
{
return single_open(file, nouveau_debugfs_pstate_get, inode->i_private);
}
static const struct file_operations nouveau_pstate_fops = {
.owner = THIS_MODULE,
.open = nouveau_debugfs_pstate_open,
.read = seq_read,
.write = nouveau_debugfs_pstate_set,
};
static struct drm_info_list nouveau_debugfs_list[] = {
{ "vbios.rom", nouveau_debugfs_vbios_image, 0, NULL },
};
#define NOUVEAU_DEBUGFS_ENTRIES ARRAY_SIZE(nouveau_debugfs_list)
int
nouveau_debugfs_init(struct drm_minor *minor)
static const struct nouveau_debugfs_files {
const char *name;
const struct file_operations *fops;
} nouveau_debugfs_files[] = {
{"pstate", &nouveau_pstate_fops},
};
static int
nouveau_debugfs_create_file(struct drm_minor *minor,
const struct nouveau_debugfs_files *ndf)
{
drm_debugfs_create_files(nouveau_debugfs_list, NOUVEAU_DEBUGFS_ENTRIES,
minor->debugfs_root, minor);
struct drm_info_node *node;
node = kmalloc(sizeof(*node), GFP_KERNEL);
if (node == NULL)
return -ENOMEM;
node->minor = minor;
node->info_ent = (const void *)ndf->fops;
node->dent = debugfs_create_file(ndf->name, S_IRUGO | S_IWUSR,
minor->debugfs_root, node, ndf->fops);
if (!node->dent) {
kfree(node);
return -ENOMEM;
}
mutex_lock(&minor->debugfs_lock);
list_add(&node->list, &minor->debugfs_list);
mutex_unlock(&minor->debugfs_lock);
return 0;
}
int
nouveau_drm_debugfs_init(struct drm_minor *minor)
{
int i, ret;
for (i = 0; i < ARRAY_SIZE(nouveau_debugfs_files); i++) {
ret = nouveau_debugfs_create_file(minor,
&nouveau_debugfs_files[i]);
if (ret)
return ret;
}
return drm_debugfs_create_files(nouveau_debugfs_list,
NOUVEAU_DEBUGFS_ENTRIES,
minor->debugfs_root, minor);
}
void
nouveau_debugfs_takedown(struct drm_minor *minor)
nouveau_drm_debugfs_cleanup(struct drm_minor *minor)
{
int i;
drm_debugfs_remove_files(nouveau_debugfs_list, NOUVEAU_DEBUGFS_ENTRIES,
minor);
for (i = 0; i < ARRAY_SIZE(nouveau_debugfs_files); i++) {
drm_debugfs_remove_files((struct drm_info_list *)
nouveau_debugfs_files[i].fops,
1, minor);
}
}
int
nouveau_debugfs_init(struct nouveau_drm *drm)
{
int ret;
drm->debugfs = kzalloc(sizeof(*drm->debugfs), GFP_KERNEL);
if (!drm->debugfs)
return -ENOMEM;
ret = nvif_object_init(&drm->device.object, 0, NVIF_CLASS_CONTROL,
NULL, 0, &drm->debugfs->ctrl);
if (ret)
return ret;
return 0;
}
void
nouveau_debugfs_fini(struct nouveau_drm *drm)
{
if (drm->debugfs && drm->debugfs->ctrl.priv)
nvif_object_fini(&drm->debugfs->ctrl);
kfree(drm->debugfs);
drm->debugfs = NULL;
}
......@@ -4,16 +4,43 @@
#include <drm/drmP.h>
#if defined(CONFIG_DEBUG_FS)
extern int nouveau_debugfs_init(struct drm_minor *);
extern void nouveau_debugfs_takedown(struct drm_minor *);
#include "nouveau_drm.h"
struct nouveau_debugfs {
struct nvif_object ctrl;
};
static inline struct nouveau_debugfs *
nouveau_debugfs(struct drm_device *dev)
{
return nouveau_drm(dev)->debugfs;
}
extern int nouveau_drm_debugfs_init(struct drm_minor *);
extern void nouveau_drm_debugfs_cleanup(struct drm_minor *);
extern int nouveau_debugfs_init(struct nouveau_drm *);
extern void nouveau_debugfs_fini(struct nouveau_drm *);
#else
static inline int
nouveau_debugfs_init(struct drm_minor *minor)
nouveau_drm_debugfs_init(struct drm_minor *minor)
{
return 0;
}
static inline void nouveau_debugfs_takedown(struct drm_minor *minor)
static inline void
nouveau_drm_debugfs_cleanup(struct drm_minor *minor)
{
}
static inline int
nouveau_debugfs_init(struct nouveau_drm *)
{
return 0;
}
static inline void
nouveau_debugfs_fini(struct nouveau_drm *)
{
}
......
......@@ -39,6 +39,7 @@
#include "nouveau_fence.h"
#include <nvif/cl0046.h>
#include <nvif/event.h>
static int
......
......@@ -37,12 +37,16 @@
#include <core/pci.h>
#include <core/tegra.h>
#include <nvif/class.h>
#include <nvif/cl0002.h>
#include <nvif/cla06f.h>
#include <nvif/if0004.h>
#include "nouveau_drm.h"
#include "nouveau_dma.h"
#include "nouveau_ttm.h"
#include "nouveau_gem.h"
#include "nouveau_vga.h"
#include "nouveau_sysfs.h"
#include "nouveau_hwmon.h"
#include "nouveau_acpi.h"
#include "nouveau_bios.h"
......@@ -256,8 +260,8 @@ nouveau_accel_init(struct nouveau_drm *drm)
}
ret = nvif_notify_init(&drm->nvsw, nouveau_flip_complete,
false, NVSW_NTFY_UEVENT, NULL, 0, 0,
&drm->flip);
false, NV04_NVSW_NTFY_UEVENT,
NULL, 0, 0, &drm->flip);
if (ret == 0)
ret = nvif_notify_get(&drm->flip);
if (ret) {
......@@ -448,7 +452,7 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
goto fail_dispinit;
}
nouveau_sysfs_init(dev);
nouveau_debugfs_init(drm);
nouveau_hwmon_init(dev);
nouveau_accel_init(drm);
nouveau_fbcon_init(dev);
......@@ -486,7 +490,7 @@ nouveau_drm_unload(struct drm_device *dev)
nouveau_fbcon_fini(dev);
nouveau_accel_fini(drm);
nouveau_hwmon_fini(dev);
nouveau_sysfs_fini(dev);
nouveau_debugfs_fini(drm);
if (dev->mode_config.num_crtc)
nouveau_display_fini(dev);
......@@ -928,8 +932,8 @@ driver_stub = {
.lastclose = nouveau_vga_lastclose,
#if defined(CONFIG_DEBUG_FS)
.debugfs_init = nouveau_debugfs_init,
.debugfs_cleanup = nouveau_debugfs_takedown,
.debugfs_init = nouveau_drm_debugfs_init,
.debugfs_cleanup = nouveau_drm_debugfs_cleanup,
#endif
.get_vblank_counter = drm_vblank_no_hw_counter,
......@@ -1003,7 +1007,6 @@ static void nouveau_display_options(void)
DRM_DEBUG_DRIVER("... modeset : %d\n", nouveau_modeset);
DRM_DEBUG_DRIVER("... runpm : %d\n", nouveau_runtime_pm);
DRM_DEBUG_DRIVER("... vram_pushbuf : %d\n", nouveau_vram_pushbuf);
DRM_DEBUG_DRIVER("... pstate : %d\n", nouveau_pstate);
}
static const struct dev_pm_ops nouveau_pm_ops = {
......
......@@ -164,7 +164,7 @@ struct nouveau_drm {
/* power management */
struct nouveau_hwmon *hwmon;
struct nouveau_sysfs *sysfs;
struct nouveau_debugfs *debugfs;
/* display power reference */
bool have_disp_power_ref;
......
......@@ -30,6 +30,7 @@
#include <linux/hrtimer.h>
#include <trace/events/fence.h>
#include <nvif/cl826e.h>
#include <nvif/notify.h>
#include <nvif/event.h>
......
......@@ -34,6 +34,8 @@
#include "nouveau_drm.h"
#include "nouveau_hwmon.h"
#include <nvkm/subdev/volt.h>
#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
static ssize_t
nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char *buf)
......@@ -512,6 +514,35 @@ static SENSOR_DEVICE_ATTR(pwm1_max, S_IRUGO | S_IWUSR,
nouveau_hwmon_get_pwm1_max,
nouveau_hwmon_set_pwm1_max, 0);
static ssize_t
nouveau_hwmon_get_in0_input(struct device *d,
struct device_attribute *a, char *buf)
{
struct drm_device *dev = dev_get_drvdata(d);
struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_volt *volt = nvxx_volt(&drm->device);
int ret;
ret = nvkm_volt_get(volt);
if (ret < 0)
return ret;
return sprintf(buf, "%i\n", ret / 1000);
}
static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO,
nouveau_hwmon_get_in0_input, NULL, 0);
static ssize_t
nouveau_hwmon_get_in0_label(struct device *d,
struct device_attribute *a, char *buf)
{
return sprintf(buf, "GPU core\n");
}
static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO,
nouveau_hwmon_get_in0_label, NULL, 0);
static struct attribute *hwmon_default_attributes[] = {
&sensor_dev_attr_name.dev_attr.attr,
&sensor_dev_attr_update_rate.dev_attr.attr,
......@@ -542,6 +573,12 @@ static struct attribute *hwmon_pwm_fan_attributes[] = {
NULL
};
static struct attribute *hwmon_in0_attributes[] = {
&sensor_dev_attr_in0_input.dev_attr.attr,
&sensor_dev_attr_in0_label.dev_attr.attr,
NULL
};
static const struct attribute_group hwmon_default_attrgroup = {
.attrs = hwmon_default_attributes,
};
......@@ -554,6 +591,9 @@ static const struct attribute_group hwmon_fan_rpm_attrgroup = {
static const struct attribute_group hwmon_pwm_fan_attrgroup = {
.attrs = hwmon_pwm_fan_attributes,
};
static const struct attribute_group hwmon_in0_attrgroup = {
.attrs = hwmon_in0_attributes,
};
#endif
int
......@@ -562,6 +602,7 @@ nouveau_hwmon_init(struct drm_device *dev)
#if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE))
struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_therm *therm = nvxx_therm(&drm->device);
struct nvkm_volt *volt = nvxx_volt(&drm->device);
struct nouveau_hwmon *hwmon;
struct device *hwmon_dev;
int ret = 0;
......@@ -613,6 +654,14 @@ nouveau_hwmon_init(struct drm_device *dev)
goto error;
}
if (volt && nvkm_volt_get(volt) >= 0) {
ret = sysfs_create_group(&hwmon_dev->kobj,
&hwmon_in0_attrgroup);
if (ret)
goto error;
}
hwmon->hwmon = hwmon_dev;
return 0;
......@@ -638,6 +687,7 @@ nouveau_hwmon_fini(struct drm_device *dev)
sysfs_remove_group(&hwmon->hwmon->kobj, &hwmon_temp_attrgroup);
sysfs_remove_group(&hwmon->hwmon->kobj, &hwmon_pwm_fan_attrgroup);
sysfs_remove_group(&hwmon->hwmon->kobj, &hwmon_fan_rpm_attrgroup);
sysfs_remove_group(&hwmon->hwmon->kobj, &hwmon_in0_attrgroup);
hwmon_device_unregister(hwmon->hwmon);
}
......
......@@ -78,3 +78,14 @@ struct platform_driver nouveau_platform_driver = {
.probe = nouveau_platform_probe,
.remove = nouveau_platform_remove,
};
#if IS_ENABLED(CONFIG_ARCH_TEGRA_124_SOC) || IS_ENABLED(CONFIG_ARCH_TEGRA_132_SOC)
MODULE_FIRMWARE("nvidia/gk20a/fecs_data.bin");
MODULE_FIRMWARE("nvidia/gk20a/fecs_inst.bin");
MODULE_FIRMWARE("nvidia/gk20a/gpccs_data.bin");
MODULE_FIRMWARE("nvidia/gk20a/gpccs_inst.bin");
MODULE_FIRMWARE("nvidia/gk20a/sw_bundle_init.bin");
MODULE_FIRMWARE("nvidia/gk20a/sw_ctx.bin");
MODULE_FIRMWARE("nvidia/gk20a/sw_method_init.bin");
MODULE_FIRMWARE("nvidia/gk20a/sw_nonctx.bin");
#endif
/*
* Copyright 2013 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Ben Skeggs <bskeggs@redhat.com>
*/
#include <nvif/os.h>
#include <nvif/class.h>
#include <nvif/ioctl.h>
#include "nouveau_sysfs.h"
MODULE_PARM_DESC(pstate, "enable sysfs pstate file, which will be moved in the future");
int nouveau_pstate;
module_param_named(pstate, nouveau_pstate, int, 0400);
static inline struct drm_device *
drm_device(struct device *d)
{
return dev_get_drvdata(d);
}
#define snappendf(p,r,f,a...) do { \
snprintf(p, r, f, ##a); \
r -= strlen(p); \
p += strlen(p); \
} while(0)
static ssize_t
nouveau_sysfs_pstate_get(struct device *d, struct device_attribute *a, char *b)
{
struct nouveau_sysfs *sysfs = nouveau_sysfs(drm_device(d));
struct nvif_control_pstate_info_v0 info = {};
size_t cnt = PAGE_SIZE;
char *buf = b;
int ret, i;
ret = nvif_mthd(&sysfs->ctrl, NVIF_CONTROL_PSTATE_INFO,
&info, sizeof(info));
if (ret)
return ret;
for (i = 0; i < info.count + 1; i++) {
const s32 state = i < info.count ? i :
NVIF_CONTROL_PSTATE_ATTR_V0_STATE_CURRENT;
struct nvif_control_pstate_attr_v0 attr = {
.state = state,
.index = 0,
};
ret = nvif_mthd(&sysfs->ctrl, NVIF_CONTROL_PSTATE_ATTR,
&attr, sizeof(attr));
if (ret)
return ret;
if (i < info.count)
snappendf(buf, cnt, "%02x:", attr.state);
else
snappendf(buf, cnt, "%s:", info.pwrsrc == 0 ? "DC" :
info.pwrsrc == 1 ? "AC" :
"--");
attr.index = 0;
do {
attr.state = state;
ret = nvif_mthd(&sysfs->ctrl,
NVIF_CONTROL_PSTATE_ATTR,
&attr, sizeof(attr));
if (ret)
return ret;
snappendf(buf, cnt, " %s %d", attr.name, attr.min);
if (attr.min != attr.max)
snappendf(buf, cnt, "-%d", attr.max);
snappendf(buf, cnt, " %s", attr.unit);
} while (attr.index);
if (state >= 0) {
if (info.ustate_ac == state)
snappendf(buf, cnt, " AC");
if (info.ustate_dc == state)
snappendf(buf, cnt, " DC");
if (info.pstate == state)
snappendf(buf, cnt, " *");
} else {
if (info.ustate_ac < -1)
snappendf(buf, cnt, " AC");
if (info.ustate_dc < -1)
snappendf(buf, cnt, " DC");
}
snappendf(buf, cnt, "\n");
}
return strlen(b);
}
static ssize_t
nouveau_sysfs_pstate_set(struct device *d, struct device_attribute *a,
const char *buf, size_t count)
{
struct nouveau_sysfs *sysfs = nouveau_sysfs(drm_device(d));
struct nvif_control_pstate_user_v0 args = { .pwrsrc = -EINVAL };
long value, ret;
char *tmp;
if ((tmp = strchr(buf, '\n')))
*tmp = '\0';
if (!strncasecmp(buf, "dc:", 3)) {
args.pwrsrc = 0;
buf += 3;
} else
if (!strncasecmp(buf, "ac:", 3)) {
args.pwrsrc = 1;
buf += 3;
}
if (!strcasecmp(buf, "none"))
args.ustate = NVIF_CONTROL_PSTATE_USER_V0_STATE_UNKNOWN;
else
if (!strcasecmp(buf, "auto"))
args.ustate = NVIF_CONTROL_PSTATE_USER_V0_STATE_PERFMON;
else {
ret = kstrtol(buf, 16, &value);
if (ret)
return ret;
args.ustate = value;
}
ret = nvif_mthd(&sysfs->ctrl, NVIF_CONTROL_PSTATE_USER,
&args, sizeof(args));
if (ret < 0)
return ret;
return count;
}
static DEVICE_ATTR(pstate, S_IRUGO | S_IWUSR,
nouveau_sysfs_pstate_get, nouveau_sysfs_pstate_set);
void
nouveau_sysfs_fini(struct drm_device *dev)
{
struct nouveau_sysfs *sysfs = nouveau_sysfs(dev);
struct nouveau_drm *drm = nouveau_drm(dev);
struct nvif_device *device = &drm->device;
if (sysfs && sysfs->ctrl.priv) {
device_remove_file(nvxx_device(device)->dev, &dev_attr_pstate);
nvif_object_fini(&sysfs->ctrl);
}
drm->sysfs = NULL;
kfree(sysfs);
}
int
nouveau_sysfs_init(struct drm_device *dev)
{
struct nouveau_drm *drm = nouveau_drm(dev);
struct nvif_device *device = &drm->device;
struct nouveau_sysfs *sysfs;
int ret;
if (!nouveau_pstate)
return 0;
sysfs = drm->sysfs = kzalloc(sizeof(*sysfs), GFP_KERNEL);
if (!sysfs)
return -ENOMEM;
ret = nvif_object_init(&device->object, 0, NVIF_IOCTL_NEW_V0_CONTROL,
NULL, 0, &sysfs->ctrl);
if (ret == 0)
device_create_file(nvxx_device(device)->dev, &dev_attr_pstate);
return 0;
}
#ifndef __NOUVEAU_SYSFS_H__
#define __NOUVEAU_SYSFS_H__
#include "nouveau_drm.h"
struct nouveau_sysfs {
struct nvif_object ctrl;
};
static inline struct nouveau_sysfs *
nouveau_sysfs(struct drm_device *dev)
{
return nouveau_drm(dev)->sysfs;
}
int nouveau_sysfs_init(struct drm_device *);
void nouveau_sysfs_fini(struct drm_device *);
extern int nouveau_pstate;
#endif
......@@ -130,20 +130,21 @@ usif_notify_new(struct drm_file *f, void *data, u32 size, void *argv, u32 argc)
struct nvif_notify_req_v0 v0;
} *req;
struct usif_notify *ntfy;
int ret;
int ret = -ENOSYS;
if (nvif_unpack(args->v0, 0, 0, true)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
if (usif_notify_find(f, args->v0.index))
return -EEXIST;
} else
return ret;
req = data;
ret = -ENOSYS;
if (!(ntfy = kmalloc(sizeof(*ntfy), GFP_KERNEL)))
return -ENOMEM;
atomic_set(&ntfy->enabled, 0);
if (nvif_unpack(req->v0, 0, 0, true)) {
if (!(ret = nvif_unpack(ret, &data, &size, req->v0, 0, 0, true))) {
ntfy->reply = sizeof(struct nvif_notify_rep_v0) + req->v0.reply;
ntfy->route = req->v0.route;
ntfy->token = req->v0.token;
......@@ -171,9 +172,9 @@ usif_notify_del(struct drm_file *f, void *data, u32 size, void *argv, u32 argc)
struct nvif_ioctl_ntfy_del_v0 v0;
} *args = data;
struct usif_notify *ntfy;
int ret;
int ret = -ENOSYS;
if (nvif_unpack(args->v0, 0, 0, true)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
if (!(ntfy = usif_notify_find(f, args->v0.index)))
return -ENOENT;
} else
......@@ -194,9 +195,9 @@ usif_notify_get(struct drm_file *f, void *data, u32 size, void *argv, u32 argc)
struct nvif_ioctl_ntfy_del_v0 v0;
} *args = data;
struct usif_notify *ntfy;
int ret;
int ret = -ENOSYS;
if (nvif_unpack(args->v0, 0, 0, true)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
if (!(ntfy = usif_notify_find(f, args->v0.index)))
return -ENOENT;
} else
......@@ -233,9 +234,9 @@ usif_notify_put(struct drm_file *f, void *data, u32 size, void *argv, u32 argc)
struct nvif_ioctl_ntfy_put_v0 v0;
} *args = data;
struct usif_notify *ntfy;
int ret;
int ret = -ENOSYS;
if (nvif_unpack(args->v0, 0, 0, true)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
if (!(ntfy = usif_notify_find(f, args->v0.index)))
return -ENOENT;
} else
......@@ -270,13 +271,13 @@ usif_object_new(struct drm_file *f, void *data, u32 size, void *argv, u32 argc)
struct nvif_ioctl_new_v0 v0;
} *args = data;
struct usif_object *object;
int ret;
int ret = -ENOSYS;
if (!(object = kmalloc(sizeof(*object), GFP_KERNEL)))
return -ENOMEM;
list_add(&object->head, &cli->objects);
if (nvif_unpack(args->v0, 0, 0, true)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
object->route = args->v0.route;
object->token = args->v0.token;
args->v0.route = NVDRM_OBJECT_USIF;
......@@ -310,7 +311,7 @@ usif_ioctl(struct drm_file *filp, void __user *user, u32 argc)
if (ret = -EFAULT, copy_from_user(argv, user, size))
goto done;
if (nvif_unpack(argv->v0, 0, 0, true)) {
if (!(ret = nvif_unpack(-ENOSYS, &data, &size, argv->v0, 0, 0, true))) {
/* block access to objects not created via this interface */
owner = argv->v0.owner;
if (argv->v0.object == 0ULL)
......
......@@ -26,6 +26,8 @@
#include "nouveau_dma.h"
#include "nouveau_fence.h"
#include <nvif/if0004.h>
struct nv04_fence_chan {
struct nouveau_fence_chan base;
};
......
......@@ -24,6 +24,7 @@
#include <nvif/os.h>
#include <nvif/class.h>
#include <nvif/cl0002.h>
#include "nouveau_drm.h"
#include "nouveau_dma.h"
......
......@@ -31,6 +31,13 @@
#include <drm/drm_fb_helper.h>
#include <nvif/class.h>
#include <nvif/cl0002.h>
#include <nvif/cl5070.h>
#include <nvif/cl507a.h>
#include <nvif/cl507b.h>
#include <nvif/cl507c.h>
#include <nvif/cl507d.h>
#include <nvif/cl507e.h>
#include "nouveau_drm.h"
#include "nouveau_dma.h"
......@@ -774,7 +781,6 @@ nv50_crtc_set_scale(struct nouveau_crtc *nv_crtc, bool update)
*/
if (nv_connector && ( nv_connector->underscan == UNDERSCAN_ON ||
(nv_connector->underscan == UNDERSCAN_AUTO &&
nv_connector->edid &&
drm_detect_hdmi_monitor(nv_connector->edid)))) {
u32 bX = nv_connector->underscan_hborder;
u32 bY = nv_connector->underscan_vborder;
......@@ -1962,10 +1968,17 @@ nv50_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,
switch (nv_encoder->dcb->type) {
case DCB_OUTPUT_TMDS:
if (nv_encoder->dcb->sorconf.link & 1) {
if (mode->clock < 165000)
proto = 0x1;
else
proto = 0x5;
proto = 0x1;
/* Only enable dual-link if:
* - Need to (i.e. rate > 165MHz)
* - DCB says we can
* - Not an HDMI monitor, since there's no dual-link
* on HDMI.
*/
if (mode->clock >= 165000 &&
nv_encoder->dcb->duallink_possible &&
!drm_detect_hdmi_monitor(nv_connector->edid))
proto |= 0x4;
} else {
proto = 0x2;
}
......
......@@ -24,6 +24,7 @@
#include <nvif/os.h>
#include <nvif/class.h>
#include <nvif/cl0002.h>
#include "nouveau_drm.h"
#include "nouveau_dma.h"
......
......@@ -28,6 +28,7 @@
#include <nvif/class.h>
#include <nvif/event.h>
#include <nvif/if0000.h>
#include <nvif/unpack.h>
struct nvkm_client_notify {
......@@ -96,7 +97,7 @@ nvkm_client_notify_new(struct nvkm_object *object,
struct nvif_notify_req_v0 v0;
} *req = data;
u8 index, reply;
int ret;
int ret = -ENOSYS;
for (index = 0; index < ARRAY_SIZE(client->notify); index++) {
if (!client->notify[index])
......@@ -111,7 +112,7 @@ nvkm_client_notify_new(struct nvkm_object *object,
return -ENOMEM;
nvif_ioctl(object, "notify new size %d\n", size);
if (nvif_unpack(req->v0, 0, 0, true)) {
if (!(ret = nvif_unpack(ret, &data, &size, req->v0, 0, 0, true))) {
nvif_ioctl(object, "notify new vers %d reply %d route %02x "
"token %llx\n", req->v0.version,
req->v0.reply, req->v0.route, req->v0.token);
......@@ -143,10 +144,10 @@ nvkm_client_mthd_devlist(struct nvkm_object *object, void *data, u32 size)
union {
struct nv_client_devlist_v0 v0;
} *args = data;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "client devlist size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, true)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
nvif_ioctl(object, "client devlist vers %d count %d\n",
args->v0.version, args->v0.count);
if (size == sizeof(args->v0.device[0]) * args->v0.count) {
......
......@@ -34,10 +34,10 @@ nvkm_ioctl_nop(struct nvkm_object *object, void *data, u32 size)
union {
struct nvif_ioctl_nop_v0 v0;
} *args = data;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "nop size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "nop vers %lld\n", args->v0.version);
args->v0.version = NVIF_VERSION_LATEST;
}
......@@ -52,10 +52,10 @@ nvkm_ioctl_sclass(struct nvkm_object *object, void *data, u32 size)
struct nvif_ioctl_sclass_v0 v0;
} *args = data;
struct nvkm_oclass oclass;
int ret, i = 0;
int ret = -ENOSYS, i = 0;
nvif_ioctl(object, "sclass size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, true)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
nvif_ioctl(object, "sclass vers %d count %d\n",
args->v0.version, args->v0.count);
if (size != args->v0.count * sizeof(args->v0.oclass[0]))
......@@ -86,10 +86,10 @@ nvkm_ioctl_new(struct nvkm_object *parent, void *data, u32 size)
struct nvkm_client *client = parent->client;
struct nvkm_object *object = NULL;
struct nvkm_oclass oclass;
int ret, i = 0;
int ret = -ENOSYS, i = 0;
nvif_ioctl(parent, "new size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, true)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
nvif_ioctl(parent, "new vers %d handle %08x class %08x "
"route %02x token %llx object %016llx\n",
args->v0.version, args->v0.handle, args->v0.oclass,
......@@ -147,10 +147,10 @@ nvkm_ioctl_del(struct nvkm_object *object, void *data, u32 size)
union {
struct nvif_ioctl_del none;
} *args = data;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "delete size %d\n", size);
if (nvif_unvers(args->none)) {
if (!(ret = nvif_unvers(ret, &data, &size, args->none))) {
nvif_ioctl(object, "delete\n");
nvkm_object_fini(object, false);
nvkm_object_del(&object);
......@@ -165,10 +165,10 @@ nvkm_ioctl_mthd(struct nvkm_object *object, void *data, u32 size)
union {
struct nvif_ioctl_mthd_v0 v0;
} *args = data;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "mthd size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, true)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
nvif_ioctl(object, "mthd vers %d mthd %02x\n",
args->v0.version, args->v0.method);
ret = nvkm_object_mthd(object, args->v0.method, data, size);
......@@ -189,10 +189,10 @@ nvkm_ioctl_rd(struct nvkm_object *object, void *data, u32 size)
u16 b16;
u32 b32;
} v;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "rd size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "rd vers %d size %d addr %016llx\n",
args->v0.version, args->v0.size, args->v0.addr);
switch (args->v0.size) {
......@@ -223,10 +223,10 @@ nvkm_ioctl_wr(struct nvkm_object *object, void *data, u32 size)
union {
struct nvif_ioctl_wr_v0 v0;
} *args = data;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "wr size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object,
"wr vers %d size %d addr %016llx data %08x\n",
args->v0.version, args->v0.size, args->v0.addr,
......@@ -251,10 +251,10 @@ nvkm_ioctl_map(struct nvkm_object *object, void *data, u32 size)
union {
struct nvif_ioctl_map_v0 v0;
} *args = data;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "map size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "map vers %d\n", args->v0.version);
ret = nvkm_object_map(object, &args->v0.handle,
&args->v0.length);
......@@ -269,10 +269,10 @@ nvkm_ioctl_unmap(struct nvkm_object *object, void *data, u32 size)
union {
struct nvif_ioctl_unmap none;
} *args = data;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "unmap size %d\n", size);
if (nvif_unvers(args->none)) {
if (!(ret = nvif_unvers(ret, &data, &size, args->none))) {
nvif_ioctl(object, "unmap\n");
}
......@@ -286,10 +286,10 @@ nvkm_ioctl_ntfy_new(struct nvkm_object *object, void *data, u32 size)
struct nvif_ioctl_ntfy_new_v0 v0;
} *args = data;
struct nvkm_event *event;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "ntfy new size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, true)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
nvif_ioctl(object, "ntfy new vers %d event %02x\n",
args->v0.version, args->v0.event);
ret = nvkm_object_ntfy(object, args->v0.event, &event);
......@@ -312,10 +312,10 @@ nvkm_ioctl_ntfy_del(struct nvkm_object *object, void *data, u32 size)
union {
struct nvif_ioctl_ntfy_del_v0 v0;
} *args = data;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "ntfy del size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "ntfy del vers %d index %d\n",
args->v0.version, args->v0.index);
ret = nvkm_client_notify_del(client, args->v0.index);
......@@ -331,10 +331,10 @@ nvkm_ioctl_ntfy_get(struct nvkm_object *object, void *data, u32 size)
union {
struct nvif_ioctl_ntfy_get_v0 v0;
} *args = data;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "ntfy get size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "ntfy get vers %d index %d\n",
args->v0.version, args->v0.index);
ret = nvkm_client_notify_get(client, args->v0.index);
......@@ -350,10 +350,10 @@ nvkm_ioctl_ntfy_put(struct nvkm_object *object, void *data, u32 size)
union {
struct nvif_ioctl_ntfy_put_v0 v0;
} *args = data;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "ntfy put size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "ntfy put vers %d index %d\n",
args->v0.version, args->v0.index);
ret = nvkm_client_notify_put(client, args->v0.index);
......@@ -421,12 +421,12 @@ nvkm_ioctl(struct nvkm_client *client, bool supervisor,
union {
struct nvif_ioctl_v0 v0;
} *args = data;
int ret;
int ret = -ENOSYS;
client->super = supervisor;
nvif_ioctl(object, "size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, true)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
nvif_ioctl(object,
"vers %d type %02x object %016llx owner %02x\n",
args->v0.version, args->v0.type, args->v0.object,
......
......@@ -22,19 +22,65 @@
* Authors: Ben Skeggs
*/
#include "priv.h"
#include <core/enum.h>
#include <nvif/class.h>
static const struct nvkm_enum
gk104_ce_launcherr_report[] = {
{ 0x0, "NO_ERR" },
{ 0x1, "2D_LAYER_EXCEEDS_DEPTH" },
{ 0x2, "INVALID_ARGUMENT" },
{ 0x3, "MEM2MEM_RECT_OUT_OF_BOUNDS" },
{ 0x4, "SRC_LINE_EXCEEDS_PITCH" },
{ 0x5, "SRC_LINE_EXCEEDS_NEG_PITCH" },
{ 0x6, "DST_LINE_EXCEEDS_PITCH" },
{ 0x7, "DST_LINE_EXCEEDS_NEG_PITCH" },
{ 0x8, "BAD_SRC_PIXEL_COMP_REF" },
{ 0x9, "INVALID_VALUE" },
{ 0xa, "UNUSED_FIELD" },
{ 0xb, "INVALID_OPERATION" },
{}
};
static void
gk104_ce_intr_launcherr(struct nvkm_engine *ce, const u32 base)
{
struct nvkm_subdev *subdev = &ce->subdev;
struct nvkm_device *device = subdev->device;
u32 stat = nvkm_rd32(device, 0x104f14 + base);
const struct nvkm_enum *en =
nvkm_enum_find(gk104_ce_launcherr_report, stat & 0x0000000f);
nvkm_warn(subdev, "LAUNCHERR %08x [%s]\n", stat, en ? en->name : "");
nvkm_wr32(device, 0x104f14 + base, 0x00000000);
}
void
gk104_ce_intr(struct nvkm_engine *ce)
{
const u32 base = (ce->subdev.index - NVKM_ENGINE_CE0) * 0x1000;
struct nvkm_subdev *subdev = &ce->subdev;
struct nvkm_device *device = subdev->device;
u32 stat = nvkm_rd32(device, 0x104908 + base);
if (stat) {
nvkm_warn(subdev, "intr %08x\n", stat);
nvkm_wr32(device, 0x104908 + base, stat);
u32 mask = nvkm_rd32(device, 0x104904 + base);
u32 intr = nvkm_rd32(device, 0x104908 + base) & mask;
if (intr & 0x00000001) {
nvkm_warn(subdev, "BLOCKPIPE\n");
nvkm_wr32(device, 0x104908 + base, 0x00000001);
intr &= ~0x00000001;
}
if (intr & 0x00000002) {
nvkm_warn(subdev, "NONBLOCKPIPE\n");
nvkm_wr32(device, 0x104908 + base, 0x00000002);
intr &= ~0x00000002;
}
if (intr & 0x00000004) {
gk104_ce_intr_launcherr(ce, base);
nvkm_wr32(device, 0x104908 + base, 0x00000004);
intr &= ~0x00000004;
}
if (intr) {
nvkm_warn(subdev, "intr %08x\n", intr);
nvkm_wr32(device, 0x104908 + base, intr);
}
}
......
......@@ -1388,7 +1388,7 @@ nvc1_chipset = {
.mc = gf100_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pci = g94_pci_new,
.pci = gf106_pci_new,
.pmu = gf100_pmu_new,
.therm = gt215_therm_new,
.timer = nv41_timer_new,
......@@ -1423,7 +1423,7 @@ nvc3_chipset = {
.mc = gf100_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pci = g94_pci_new,
.pci = gf106_pci_new,
.pmu = gf100_pmu_new,
.therm = gt215_therm_new,
.timer = nv41_timer_new,
......@@ -1566,7 +1566,7 @@ nvcf_chipset = {
.mc = gf100_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pci = g94_pci_new,
.pci = gf106_pci_new,
.pmu = gf100_pmu_new,
.therm = gt215_therm_new,
.timer = nv41_timer_new,
......@@ -1601,7 +1601,7 @@ nvd7_chipset = {
.mc = gf100_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pci = g94_pci_new,
.pci = gf106_pci_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
.ce[0] = gf100_ce_new,
......@@ -1634,7 +1634,7 @@ nvd9_chipset = {
.mc = gf100_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pci = g94_pci_new,
.pci = gf106_pci_new,
.pmu = gf119_pmu_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
......@@ -1669,7 +1669,7 @@ nve4_chipset = {
.mc = gf100_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pci = g94_pci_new,
.pci = gk104_pci_new,
.pmu = gk104_pmu_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
......@@ -1706,7 +1706,7 @@ nve6_chipset = {
.mc = gf100_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pci = g94_pci_new,
.pci = gk104_pci_new,
.pmu = gk104_pmu_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
......@@ -1743,7 +1743,7 @@ nve7_chipset = {
.mc = gf100_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pci = g94_pci_new,
.pci = gk104_pci_new,
.pmu = gk104_pmu_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
......@@ -1804,7 +1804,7 @@ nvf0_chipset = {
.mc = gf100_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pci = g94_pci_new,
.pci = gk104_pci_new,
.pmu = gk110_pmu_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
......@@ -1840,7 +1840,7 @@ nvf1_chipset = {
.mc = gf100_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pci = g94_pci_new,
.pci = gk104_pci_new,
.pmu = gk110_pmu_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
......@@ -1876,7 +1876,7 @@ nv106_chipset = {
.mc = gk20a_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pci = g94_pci_new,
.pci = gk104_pci_new,
.pmu = gk208_pmu_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
......@@ -1912,7 +1912,7 @@ nv108_chipset = {
.mc = gk20a_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pci = g94_pci_new,
.pci = gk104_pci_new,
.pmu = gk208_pmu_new,
.therm = gf119_therm_new,
.timer = nv41_timer_new,
......@@ -1948,7 +1948,7 @@ nv117_chipset = {
.mc = gk20a_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pci = g94_pci_new,
.pci = gk104_pci_new,
.pmu = gm107_pmu_new,
.therm = gm107_therm_new,
.timer = gk20a_timer_new,
......@@ -1973,13 +1973,13 @@ nv124_chipset = {
.fuse = gm107_fuse_new,
.gpio = gk104_gpio_new,
.i2c = gm204_i2c_new,
.ibus = gk104_ibus_new,
.ibus = gm204_ibus_new,
.imem = nv50_instmem_new,
.ltc = gm107_ltc_new,
.ltc = gm204_ltc_new,
.mc = gk20a_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pci = g94_pci_new,
.pci = gk104_pci_new,
.pmu = gm107_pmu_new,
.timer = gk20a_timer_new,
.volt = gk104_volt_new,
......@@ -2004,13 +2004,13 @@ nv126_chipset = {
.fuse = gm107_fuse_new,
.gpio = gk104_gpio_new,
.i2c = gm204_i2c_new,
.ibus = gk104_ibus_new,
.ibus = gm204_ibus_new,
.imem = nv50_instmem_new,
.ltc = gm107_ltc_new,
.ltc = gm204_ltc_new,
.mc = gk20a_mc_new,
.mmu = gf100_mmu_new,
.mxm = nv50_mxm_new,
.pci = g94_pci_new,
.pci = gk104_pci_new,
.pmu = gm107_pmu_new,
.timer = gk20a_timer_new,
.volt = gk104_volt_new,
......@@ -2033,7 +2033,7 @@ nv12b_chipset = {
.fuse = gm107_fuse_new,
.ibus = gk20a_ibus_new,
.imem = gk20a_instmem_new,
.ltc = gm107_ltc_new,
.ltc = gm204_ltc_new,
.mc = gk20a_mc_new,
.mmu = gf100_mmu_new,
.timer = gk20a_timer_new,
......@@ -2494,7 +2494,8 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
device->pri = ioremap(mmio_base, mmio_size);
if (!device->pri) {
nvdev_error(device, "unable to map PRI\n");
return -ENOMEM;
ret = -ENOMEM;
goto done;
}
}
......
......@@ -27,6 +27,7 @@
#include <subdev/clk.h>
#include <nvif/class.h>
#include <nvif/if0001.h>
#include <nvif/ioctl.h>
#include <nvif/unpack.h>
......@@ -37,10 +38,10 @@ nvkm_control_mthd_pstate_info(struct nvkm_control *ctrl, void *data, u32 size)
struct nvif_control_pstate_info_v0 v0;
} *args = data;
struct nvkm_clk *clk = ctrl->device->clk;
int ret;
int ret = -ENOSYS;
nvif_ioctl(&ctrl->object, "control pstate info size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(&ctrl->object, "control pstate info vers %d\n",
args->v0.version);
} else
......@@ -75,10 +76,10 @@ nvkm_control_mthd_pstate_attr(struct nvkm_control *ctrl, void *data, u32 size)
struct nvkm_cstate *cstate;
int i = 0, j = -1;
u32 lo, hi;
int ret;
int ret = -ENOSYS;
nvif_ioctl(&ctrl->object, "control pstate attr size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(&ctrl->object,
"control pstate attr vers %d state %d index %d\n",
args->v0.version, args->v0.state, args->v0.index);
......@@ -143,10 +144,10 @@ nvkm_control_mthd_pstate_user(struct nvkm_control *ctrl, void *data, u32 size)
struct nvif_control_pstate_user_v0 v0;
} *args = data;
struct nvkm_clk *clk = ctrl->device->clk;
int ret;
int ret = -ENOSYS;
nvif_ioctl(&ctrl->object, "control pstate user size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(&ctrl->object,
"control pstate user vers %d ustate %d pwrsrc %d\n",
args->v0.version, args->v0.ustate, args->v0.pwrsrc);
......@@ -204,7 +205,7 @@ nvkm_control_new(struct nvkm_device *device, const struct nvkm_oclass *oclass,
const struct nvkm_device_oclass
nvkm_control_oclass = {
.base.oclass = NVIF_IOCTL_NEW_V0_CONTROL,
.base.oclass = NVIF_CLASS_CONTROL,
.base.minver = -1,
.base.maxver = -1,
.ctor = nvkm_control_new,
......
......@@ -31,6 +31,7 @@
#include <subdev/timer.h>
#include <nvif/class.h>
#include <nvif/cl0080.h>
#include <nvif/unpack.h>
struct nvkm_udevice {
......@@ -48,10 +49,10 @@ nvkm_udevice_info(struct nvkm_udevice *udev, void *data, u32 size)
union {
struct nv_device_info_v0 v0;
} *args = data;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "device info size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "device info vers %d\n", args->v0.version);
} else
return ret;
......@@ -123,13 +124,16 @@ nvkm_udevice_info(struct nvkm_udevice *udev, void *data, u32 size)
static int
nvkm_udevice_time(struct nvkm_udevice *udev, void *data, u32 size)
{
struct nvkm_object *object = &udev->object;
struct nvkm_device *device = udev->device;
union {
struct nv_device_time_v0 v0;
} *args = data;
int ret;
int ret = -ENOSYS;
if (nvif_unpack(args->v0, 0, 0, false)) {
nvif_ioctl(object, "device time size %d\n", size);
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "device time vers %d\n", args->v0.version);
args->v0.time = nvkm_timer_read(device->timer);
}
......@@ -140,6 +144,7 @@ static int
nvkm_udevice_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
{
struct nvkm_udevice *udev = nvkm_udevice(object);
nvif_ioctl(object, "device mthd %08x\n", mthd);
switch (mthd) {
case NV_DEVICE_V0_INFO:
return nvkm_udevice_info(udev, data, size);
......@@ -331,10 +336,10 @@ nvkm_udevice_new(const struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object *parent = &client->object;
const struct nvkm_object_func *func;
struct nvkm_udevice *udev;
int ret;
int ret = -ENOSYS;
nvif_ioctl(parent, "create device size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(parent, "create device v%d device %016llx\n",
args->v0.version, args->v0.device);
} else
......
......@@ -32,6 +32,7 @@
#include <subdev/bios/dcb.h>
#include <nvif/class.h>
#include <nvif/cl0046.h>
#include <nvif/event.h>
#include <nvif/unpack.h>
......@@ -58,9 +59,9 @@ nvkm_disp_vblank_ctor(struct nvkm_object *object, void *data, u32 size,
union {
struct nvif_notify_head_req_v0 v0;
} *req = data;
int ret;
int ret = -ENOSYS;
if (nvif_unpack(req->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, req->v0, 0, 0, false))) {
notify->size = sizeof(struct nvif_notify_head_rep_v0);
if (ret = -ENXIO, req->v0.head <= disp->vblank.index_nr) {
notify->types = 1;
......@@ -96,9 +97,9 @@ nvkm_disp_hpd_ctor(struct nvkm_object *object, void *data, u32 size,
struct nvif_notify_conn_req_v0 v0;
} *req = data;
struct nvkm_output *outp;
int ret;
int ret = -ENOSYS;
if (nvif_unpack(req->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, req->v0, 0, 0, false))) {
notify->size = sizeof(struct nvif_notify_conn_rep_v0);
list_for_each_entry(outp, &disp->outp, head) {
if (ret = -ENXIO, outp->conn->index == req->v0.conn) {
......
......@@ -27,6 +27,7 @@
#include <core/client.h>
#include <nvif/class.h>
#include <nvif/cl507c.h>
#include <nvif/unpack.h>
int
......@@ -41,11 +42,11 @@ nv50_disp_base_new(const struct nv50_disp_dmac_func *func,
} *args = data;
struct nvkm_object *parent = oclass->parent;
struct nv50_disp *disp = root->disp;
int head, ret;
int head, ret = -ENOSYS;
u64 push;
nvif_ioctl(parent, "create disp base channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(parent, "create disp base channel dma vers %d "
"pushbuf %016llx head %d\n",
args->v0.version, args->v0.pushbuf, args->v0.head);
......
......@@ -28,7 +28,7 @@
#include <core/ramht.h>
#include <engine/dma.h>
#include <nvif/class.h>
#include <nvif/cl507d.h>
#include <nvif/event.h>
#include <nvif/unpack.h>
......@@ -134,9 +134,9 @@ nv50_disp_chan_uevent_ctor(struct nvkm_object *object, void *data, u32 size,
union {
struct nvif_notify_uevent_req none;
} *args = data;
int ret;
int ret = -ENOSYS;
if (nvif_unvers(args->none)) {
if (!(ret = nvif_unvers(ret, &data, &size, args->none))) {
notify->size = sizeof(struct nvif_notify_uevent_rep);
notify->types = 1;
notify->index = chan->chid;
......
......@@ -28,6 +28,7 @@
#include <subdev/timer.h>
#include <nvif/class.h>
#include <nvif/cl507d.h>
#include <nvif/unpack.h>
int
......@@ -42,10 +43,10 @@ nv50_disp_core_new(const struct nv50_disp_dmac_func *func,
} *args = data;
struct nvkm_object *parent = oclass->parent;
u64 push;
int ret;
int ret = -ENOSYS;
nvif_ioctl(parent, "create disp core channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(parent, "create disp core channel dma vers %d "
"pushbuf %016llx\n",
args->v0.version, args->v0.pushbuf);
......
......@@ -27,6 +27,7 @@
#include <core/client.h>
#include <nvif/class.h>
#include <nvif/cl507a.h>
#include <nvif/unpack.h>
int
......@@ -41,10 +42,10 @@ nv50_disp_curs_new(const struct nv50_disp_chan_func *func,
} *args = data;
struct nvkm_object *parent = oclass->parent;
struct nv50_disp *disp = root->disp;
int head, ret;
int head, ret = -ENOSYS;
nvif_ioctl(parent, "create disp cursor size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(parent, "create disp cursor vers %d head %d\n",
args->v0.version, args->v0.head);
if (args->v0.head > disp->base.head.nr)
......
......@@ -27,7 +27,7 @@
#include <core/client.h>
#include <subdev/timer.h>
#include <nvif/class.h>
#include <nvif/cl5070.h>
#include <nvif/unpack.h>
int
......@@ -39,10 +39,10 @@ nv50_dac_power(NV50_DISP_MTHD_V1)
struct nv50_disp_dac_pwr_v0 v0;
} *args = data;
u32 stat;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "disp dac pwr size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "disp dac pwr vers %d state %d data %d "
"vsync %d hsync %d\n",
args->v0.version, args->v0.state, args->v0.data,
......@@ -76,10 +76,10 @@ nv50_dac_sense(NV50_DISP_MTHD_V1)
} *args = data;
const u32 doff = outp->or * 0x800;
u32 loadval;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "disp dac load size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "disp dac load vers %d data %08x\n",
args->v0.version, args->v0.data);
if (args->v0.data & 0xfff00000)
......
......@@ -158,7 +158,7 @@ exec_clkcmp(struct nv50_disp *disp, int head, int id, u32 pclk, u32 *conf)
switch (outp->info.type) {
case DCB_OUTPUT_TMDS:
*conf = (ctrl & 0x00000f00) >> 8;
if (pclk >= 165000)
if (*conf == 5)
*conf |= 0x0100;
break;
case DCB_OUTPUT_LVDS:
......
......@@ -29,7 +29,7 @@
#include <subdev/bios/dcb.h>
#include <subdev/timer.h>
#include <nvif/class.h>
#include <nvif/cl5070.h>
#include <nvif/unpack.h>
int
......@@ -41,10 +41,10 @@ gf119_hda_eld(NV50_DISP_MTHD_V1)
} *args = data;
const u32 soff = outp->or * 0x030;
const u32 hoff = head * 0x800;
int ret, i;
int ret = -ENOSYS, i;
nvif_ioctl(object, "disp sor hda eld size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, true)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
nvif_ioctl(object, "disp sor hda eld vers %d\n",
args->v0.version);
if (size > 0x60)
......
......@@ -27,7 +27,7 @@
#include <core/client.h>
#include <subdev/timer.h>
#include <nvif/class.h>
#include <nvif/cl5070.h>
#include <nvif/unpack.h>
int
......@@ -38,10 +38,10 @@ gt215_hda_eld(NV50_DISP_MTHD_V1)
struct nv50_disp_sor_hda_eld_v0 v0;
} *args = data;
const u32 soff = outp->or * 0x800;
int ret, i;
int ret = -ENOSYS, i;
nvif_ioctl(object, "disp sor hda eld size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, true)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
nvif_ioctl(object, "disp sor hda eld vers %d\n",
args->v0.version);
if (size > 0x60)
......
......@@ -25,7 +25,7 @@
#include <core/client.h>
#include <nvif/class.h>
#include <nvif/cl5070.h>
#include <nvif/unpack.h>
int
......@@ -37,10 +37,10 @@ g84_hdmi_ctrl(NV50_DISP_MTHD_V1)
struct nv50_disp_sor_hdmi_pwr_v0 v0;
} *args = data;
u32 ctrl;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "disp sor hdmi ctrl size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "disp sor hdmi ctrl vers %d state %d "
"max_ac_packet %d rekey %d\n",
args->v0.version, args->v0.state,
......
......@@ -25,7 +25,7 @@
#include <core/client.h>
#include <nvif/class.h>
#include <nvif/cl5070.h>
#include <nvif/unpack.h>
int
......@@ -37,10 +37,10 @@ gf119_hdmi_ctrl(NV50_DISP_MTHD_V1)
struct nv50_disp_sor_hdmi_pwr_v0 v0;
} *args = data;
u32 ctrl;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "disp sor hdmi ctrl size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "disp sor hdmi ctrl vers %d state %d "
"max_ac_packet %d rekey %d\n",
args->v0.version, args->v0.state,
......
......@@ -25,7 +25,7 @@
#include <core/client.h>
#include <nvif/class.h>
#include <nvif/cl5070.h>
#include <nvif/unpack.h>
int
......@@ -38,10 +38,10 @@ gk104_hdmi_ctrl(NV50_DISP_MTHD_V1)
struct nv50_disp_sor_hdmi_pwr_v0 v0;
} *args = data;
u32 ctrl;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "disp sor hdmi ctrl size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "disp sor hdmi ctrl vers %d state %d "
"max_ac_packet %d rekey %d\n",
args->v0.version, args->v0.state,
......
......@@ -26,7 +26,7 @@
#include <core/client.h>
#include <nvif/class.h>
#include <nvif/cl5070.h>
#include <nvif/unpack.h>
int
......@@ -38,10 +38,10 @@ gt215_hdmi_ctrl(NV50_DISP_MTHD_V1)
struct nv50_disp_sor_hdmi_pwr_v0 v0;
} *args = data;
u32 ctrl;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "disp sor hdmi ctrl size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "disp sor hdmi ctrl vers %d state %d "
"max_ac_packet %d rekey %d\n",
args->v0.version, args->v0.state,
......
......@@ -391,7 +391,7 @@ exec_clkcmp(struct nv50_disp *disp, int head, int id, u32 pclk, u32 *conf)
switch (outp->info.type) {
case DCB_OUTPUT_TMDS:
*conf = (ctrl & 0x00000f00) >> 8;
if (pclk >= 165000)
if (*conf == 5)
*conf |= 0x0100;
break;
case DCB_OUTPUT_LVDS:
......
......@@ -27,6 +27,7 @@
#include <core/client.h>
#include <nvif/class.h>
#include <nvif/cl507b.h>
#include <nvif/unpack.h>
int
......@@ -41,10 +42,10 @@ nv50_disp_oimm_new(const struct nv50_disp_chan_func *func,
} *args = data;
struct nvkm_object *parent = oclass->parent;
struct nv50_disp *disp = root->disp;
int head, ret;
int head, ret = -ENOSYS;
nvif_ioctl(parent, "create disp overlay size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(parent, "create disp overlay vers %d head %d\n",
args->v0.version, args->v0.head);
if (args->v0.head > disp->base.head.nr)
......
......@@ -27,6 +27,7 @@
#include <core/client.h>
#include <nvif/class.h>
#include <nvif/cl507e.h>
#include <nvif/unpack.h>
int
......@@ -41,11 +42,11 @@ nv50_disp_ovly_new(const struct nv50_disp_dmac_func *func,
} *args = data;
struct nvkm_object *parent = oclass->parent;
struct nv50_disp *disp = root->disp;
int head, ret;
int head, ret = -ENOSYS;
u64 push;
nvif_ioctl(parent, "create disp overlay channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(parent, "create disp overlay channel dma vers %d "
"pushbuf %016llx head %d\n",
args->v0.version, args->v0.pushbuf, args->v0.head);
......
......@@ -28,7 +28,7 @@
#include <subdev/i2c.h>
#include <subdev/timer.h>
#include <nvif/class.h>
#include <nvif/cl5070.h>
#include <nvif/unpack.h>
int
......@@ -40,10 +40,10 @@ nv50_pior_power(NV50_DISP_MTHD_V1)
struct nv50_disp_pior_pwr_v0 v0;
} *args = data;
u32 ctrl, type;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "disp pior pwr size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "disp pior pwr vers %d state %d type %x\n",
args->v0.version, args->v0.state, args->v0.type);
if (args->v0.type > 0x0f)
......
......@@ -29,6 +29,7 @@
#include <subdev/timer.h>
#include <nvif/class.h>
#include <nvif/cl5070.h>
#include <nvif/unpack.h>
int
......@@ -39,12 +40,12 @@ gf119_disp_root_scanoutpos(NV50_DISP_MTHD_V0)
const u32 blanke = nvkm_rd32(device, 0x64041c + (head * 0x300));
const u32 blanks = nvkm_rd32(device, 0x640420 + (head * 0x300));
union {
struct nv04_disp_scanoutpos_v0 v0;
struct nv50_disp_scanoutpos_v0 v0;
} *args = data;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "disp scanoutpos size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "disp scanoutpos vers %d\n",
args->v0.version);
args->v0.vblanke = (blanke & 0xffff0000) >> 16;
......
......@@ -27,6 +27,7 @@
#include <core/client.h>
#include <nvif/class.h>
#include <nvif/cl0046.h>
#include <nvif/unpack.h>
struct nv04_disp_root {
......@@ -45,10 +46,10 @@ nv04_disp_scanoutpos(struct nv04_disp_root *root,
struct nv04_disp_scanoutpos_v0 v0;
} *args = data;
u32 line;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "disp scanoutpos size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "disp scanoutpos vers %d\n",
args->v0.version);
args->v0.vblanks = nvkm_rd32(device, 0x680800 + hoff) & 0xffff;
......@@ -85,10 +86,10 @@ nv04_disp_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
union {
struct nv04_disp_mthd_v0 v0;
} *args = data;
int head, ret;
int head, ret = -ENOSYS;
nvif_ioctl(object, "disp mthd size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, true)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
nvif_ioctl(object, "disp mthd vers %d mthd %02x head %d\n",
args->v0.version, args->v0.method, args->v0.head);
mthd = args->v0.method;
......
......@@ -29,6 +29,7 @@
#include <subdev/timer.h>
#include <nvif/class.h>
#include <nvif/cl5070.h>
#include <nvif/unpack.h>
int
......@@ -39,12 +40,12 @@ nv50_disp_root_scanoutpos(NV50_DISP_MTHD_V0)
const u32 blanks = nvkm_rd32(device, 0x610af4 + (head * 0x540));
const u32 total = nvkm_rd32(device, 0x610afc + (head * 0x540));
union {
struct nv04_disp_scanoutpos_v0 v0;
struct nv50_disp_scanoutpos_v0 v0;
} *args = data;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "disp scanoutpos size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "disp scanoutpos vers %d\n",
args->v0.version);
args->v0.vblanke = (blanke & 0xffff0000) >> 16;
......@@ -78,19 +79,19 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
struct nvkm_output *outp = NULL;
struct nvkm_output *temp;
u16 type, mask = 0;
int head, ret;
int head, ret = -ENOSYS;
if (mthd != NV50_DISP_MTHD)
return -EINVAL;
nvif_ioctl(object, "disp mthd size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, true)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
nvif_ioctl(object, "disp mthd vers %d mthd %02x head %d\n",
args->v0.version, args->v0.method, args->v0.head);
mthd = args->v0.method;
head = args->v0.head;
} else
if (nvif_unpack(args->v1, 1, 1, true)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v1, 1, 1, true))) {
nvif_ioctl(object, "disp mthd vers %d mthd %02x "
"type %04x mask %04x\n",
args->v1.version, args->v1.method,
......@@ -143,8 +144,9 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
union {
struct nv50_disp_sor_lvds_script_v0 v0;
} *args = data;
int ret = -ENOSYS;
nvif_ioctl(object, "disp sor lvds script size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "disp sor lvds script "
"vers %d name %04x\n",
args->v0.version, args->v0.script);
......@@ -159,8 +161,9 @@ nv50_disp_root_mthd_(struct nvkm_object *object, u32 mthd, void *data, u32 size)
union {
struct nv50_disp_sor_dp_pwr_v0 v0;
} *args = data;
int ret = -ENOSYS;
nvif_ioctl(object, "disp sor dp pwr size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "disp sor dp pwr vers %d state %d\n",
args->v0.version, args->v0.state);
if (args->v0.state == 0) {
......
......@@ -27,7 +27,7 @@
#include <core/client.h>
#include <subdev/timer.h>
#include <nvif/class.h>
#include <nvif/cl5070.h>
#include <nvif/unpack.h>
int
......@@ -39,10 +39,10 @@ nv50_sor_power(NV50_DISP_MTHD_V1)
} *args = data;
const u32 soff = outp->or * 0x800;
u32 stat;
int ret;
int ret = -ENOSYS;
nvif_ioctl(object, "disp sor pwr size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(object, "disp sor pwr vers %d state %d\n",
args->v0.version, args->v0.state);
stat = !!args->v0.state;
......
......@@ -28,7 +28,7 @@
#include <subdev/fb.h>
#include <subdev/instmem.h>
#include <nvif/class.h>
#include <nvif/cl0002.h>
#include <nvif/unpack.h>
static int
......@@ -69,7 +69,7 @@ nvkm_dmaobj_ctor(const struct nvkm_dmaobj_func *func, struct nvkm_dma *dma,
struct nvkm_fb *fb = device->fb;
void *data = *pdata;
u32 size = *psize;
int ret;
int ret = -ENOSYS;
nvkm_object_ctor(&nvkm_dmaobj_func, oclass, &dmaobj->object);
dmaobj->func = func;
......@@ -77,7 +77,7 @@ nvkm_dmaobj_ctor(const struct nvkm_dmaobj_func *func, struct nvkm_dma *dma,
RB_CLEAR_NODE(&dmaobj->rb);
nvif_ioctl(parent, "create dma size %d\n", *psize);
if (nvif_unpack(args->v0, 0, 0, true)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
nvif_ioctl(parent, "create dma vers %d target %d access %d "
"start %016llx limit %016llx\n",
args->v0.version, args->v0.target, args->v0.access,
......
......@@ -28,7 +28,7 @@
#include <core/gpuobj.h>
#include <subdev/fb.h>
#include <nvif/class.h>
#include <nvif/cl0002.h>
#include <nvif/unpack.h>
struct gf100_dmaobj {
......@@ -87,10 +87,11 @@ gf100_dmaobj_new(struct nvkm_dma *dma, const struct nvkm_oclass *oclass,
if (ret)
return ret;
ret = -ENOSYS;
args = data;
nvif_ioctl(parent, "create gf100 dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(parent,
"create gf100 dma vers %d priv %d kind %02x\n",
args->v0.version, args->v0.priv, args->v0.kind);
......
......@@ -28,7 +28,7 @@
#include <core/gpuobj.h>
#include <subdev/fb.h>
#include <nvif/class.h>
#include <nvif/cl0002.h>
#include <nvif/unpack.h>
struct gf119_dmaobj {
......@@ -85,10 +85,11 @@ gf119_dmaobj_new(struct nvkm_dma *dma, const struct nvkm_oclass *oclass,
if (ret)
return ret;
ret = -ENOSYS;
args = data;
nvif_ioctl(parent, "create gf119 dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(parent,
"create gf100 dma vers %d page %d kind %02x\n",
args->v0.version, args->v0.page, args->v0.kind);
......
......@@ -28,7 +28,7 @@
#include <core/gpuobj.h>
#include <subdev/fb.h>
#include <nvif/class.h>
#include <nvif/cl0002.h>
#include <nvif/unpack.h>
struct nv50_dmaobj {
......@@ -87,10 +87,11 @@ nv50_dmaobj_new(struct nvkm_dma *dma, const struct nvkm_oclass *oclass,
if (ret)
return ret;
ret = -ENOSYS;
args = data;
nvif_ioctl(parent, "create nv50 dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(parent, "create nv50 dma vers %d priv %d part %d "
"comp %d kind %02x\n", args->v0.version,
args->v0.priv, args->v0.part, args->v0.comp,
......
......@@ -129,9 +129,9 @@ nvkm_fifo_uevent_ctor(struct nvkm_object *object, void *data, u32 size,
union {
struct nvif_notify_uevent_req none;
} *req = data;
int ret;
int ret = -ENOSYS;
if (nvif_unvers(req->none)) {
if (!(ret = nvif_unvers(ret, &data, &size, req->none))) {
notify->size = sizeof(struct nvif_notify_uevent_rep);
notify->types = 1;
notify->index = 0;
......
......@@ -28,7 +28,7 @@
#include <subdev/mmu.h>
#include <subdev/timer.h>
#include <nvif/class.h>
#include <nvif/cl826e.h>
int
g84_fifo_chan_ntfy(struct nvkm_fifo_chan *chan, u32 type,
......
......@@ -27,6 +27,7 @@
#include <core/ramht.h>
#include <nvif/class.h>
#include <nvif/cl826e.h>
#include <nvif/unpack.h>
static int
......@@ -35,14 +36,14 @@ g84_fifo_dma_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
{
struct nvkm_object *parent = oclass->parent;
union {
struct nv50_channel_dma_v0 v0;
struct g82_channel_dma_v0 v0;
} *args = data;
struct nv50_fifo *fifo = nv50_fifo(base);
struct nv50_fifo_chan *chan;
int ret;
int ret = -ENOSYS;
nvif_ioctl(parent, "create channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(parent, "create channel dma vers %d vm %llx "
"pushbuf %llx offset %016llx\n",
args->v0.version, args->v0.vm, args->v0.pushbuf,
......
......@@ -29,6 +29,7 @@
#include <subdev/instmem.h>
#include <nvif/class.h>
#include <nvif/cl006b.h>
#include <nvif/unpack.h>
void
......@@ -167,10 +168,10 @@ nv04_fifo_dma_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
struct nv04_fifo_chan *chan = NULL;
struct nvkm_device *device = fifo->base.engine.subdev.device;
struct nvkm_instmem *imem = device->imem;
int ret;
int ret = -ENOSYS;
nvif_ioctl(parent, "create channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(parent, "create channel dma vers %d pushbuf %llx "
"offset %08x\n", args->v0.version,
args->v0.pushbuf, args->v0.offset);
......
......@@ -29,6 +29,7 @@
#include <subdev/instmem.h>
#include <nvif/class.h>
#include <nvif/cl006b.h>
#include <nvif/unpack.h>
static int
......@@ -43,10 +44,10 @@ nv10_fifo_dma_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
struct nv04_fifo_chan *chan = NULL;
struct nvkm_device *device = fifo->base.engine.subdev.device;
struct nvkm_instmem *imem = device->imem;
int ret;
int ret = -ENOSYS;
nvif_ioctl(parent, "create channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(parent, "create channel dma vers %d pushbuf %llx "
"offset %08x\n", args->v0.version,
args->v0.pushbuf, args->v0.offset);
......
......@@ -29,6 +29,7 @@
#include <subdev/instmem.h>
#include <nvif/class.h>
#include <nvif/cl006b.h>
#include <nvif/unpack.h>
static int
......@@ -43,10 +44,10 @@ nv17_fifo_dma_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
struct nv04_fifo_chan *chan = NULL;
struct nvkm_device *device = fifo->base.engine.subdev.device;
struct nvkm_instmem *imem = device->imem;
int ret;
int ret = -ENOSYS;
nvif_ioctl(parent, "create channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(parent, "create channel dma vers %d pushbuf %llx "
"offset %08x\n", args->v0.version,
args->v0.pushbuf, args->v0.offset);
......
......@@ -29,6 +29,7 @@
#include <subdev/instmem.h>
#include <nvif/class.h>
#include <nvif/cl006b.h>
#include <nvif/unpack.h>
static bool
......@@ -188,10 +189,10 @@ nv40_fifo_dma_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
struct nv04_fifo_chan *chan = NULL;
struct nvkm_device *device = fifo->base.engine.subdev.device;
struct nvkm_instmem *imem = device->imem;
int ret;
int ret = -ENOSYS;
nvif_ioctl(parent, "create channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(parent, "create channel dma vers %d pushbuf %llx "
"offset %08x\n", args->v0.version,
args->v0.pushbuf, args->v0.offset);
......
......@@ -27,6 +27,7 @@
#include <core/ramht.h>
#include <nvif/class.h>
#include <nvif/cl506e.h>
#include <nvif/unpack.h>
static int
......@@ -39,10 +40,10 @@ nv50_fifo_dma_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
} *args = data;
struct nv50_fifo *fifo = nv50_fifo(base);
struct nv50_fifo_chan *chan;
int ret;
int ret = -ENOSYS;
nvif_ioctl(parent, "create channel dma size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(parent, "create channel dma vers %d vm %llx "
"pushbuf %llx offset %016llx\n",
args->v0.version, args->v0.vm, args->v0.pushbuf,
......
......@@ -47,7 +47,7 @@ gf100_fifo_uevent_fini(struct nvkm_fifo *fifo)
}
void
gf100_fifo_runlist_update(struct gf100_fifo *fifo)
gf100_fifo_runlist_commit(struct gf100_fifo *fifo)
{
struct gf100_fifo_chan *chan;
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
......@@ -77,6 +77,22 @@ gf100_fifo_runlist_update(struct gf100_fifo *fifo)
mutex_unlock(&subdev->mutex);
}
void
gf100_fifo_runlist_remove(struct gf100_fifo *fifo, struct gf100_fifo_chan *chan)
{
mutex_lock(&fifo->base.engine.subdev.mutex);
list_del_init(&chan->head);
mutex_unlock(&fifo->base.engine.subdev.mutex);
}
void
gf100_fifo_runlist_insert(struct gf100_fifo *fifo, struct gf100_fifo_chan *chan)
{
mutex_lock(&fifo->base.engine.subdev.mutex);
list_add_tail(&chan->head, &fifo->chan);
mutex_unlock(&fifo->base.engine.subdev.mutex);
}
static inline int
gf100_fifo_engidx(struct gf100_fifo *fifo, u32 engn)
{
......@@ -139,7 +155,7 @@ gf100_fifo_recover_work(struct work_struct *work)
}
}
gf100_fifo_runlist_update(fifo);
gf100_fifo_runlist_commit(fifo);
nvkm_wr32(device, 0x00262c, engm);
nvkm_mask(device, 0x002630, engm, 0x00000000);
}
......@@ -239,7 +255,7 @@ gf100_fifo_fault_engine[] = {
{ 0x14, "PMSPDEC", NULL, NVKM_ENGINE_MSPDEC },
{ 0x15, "PCE0", NULL, NVKM_ENGINE_CE0 },
{ 0x16, "PCE1", NULL, NVKM_ENGINE_CE1 },
{ 0x17, "PDAEMON" },
{ 0x17, "PMU" },
{}
};
......@@ -270,7 +286,7 @@ gf100_fifo_fault_hubclient[] = {
{ 0x0c, "PMSPPP" },
{ 0x0d, "PMSVLD" },
{ 0x11, "PCOUNTER" },
{ 0x12, "PDAEMON" },
{ 0x12, "PMU" },
{ 0x14, "CCACHE" },
{ 0x15, "CCACHE_POST" },
{}
......
......@@ -5,6 +5,7 @@
#include <subdev/mmu.h>
struct gf100_fifo_chan;
struct gf100_fifo {
struct nvkm_fifo base;
......@@ -27,5 +28,7 @@ struct gf100_fifo {
};
void gf100_fifo_intr_engine(struct gf100_fifo *);
void gf100_fifo_runlist_update(struct gf100_fifo *);
void gf100_fifo_runlist_insert(struct gf100_fifo *, struct gf100_fifo_chan *);
void gf100_fifo_runlist_remove(struct gf100_fifo *, struct gf100_fifo_chan *);
void gf100_fifo_runlist_commit(struct gf100_fifo *);
#endif
......@@ -47,7 +47,7 @@ gk104_fifo_uevent_init(struct nvkm_fifo *fifo)
}
void
gk104_fifo_runlist_update(struct gk104_fifo *fifo, u32 engine)
gk104_fifo_runlist_commit(struct gk104_fifo *fifo, u32 engine)
{
struct gk104_fifo_engn *engn = &fifo->engine[engine];
struct gk104_fifo_chan *chan;
......@@ -78,6 +78,22 @@ gk104_fifo_runlist_update(struct gk104_fifo *fifo, u32 engine)
mutex_unlock(&subdev->mutex);
}
void
gk104_fifo_runlist_remove(struct gk104_fifo *fifo, struct gk104_fifo_chan *chan)
{
mutex_lock(&fifo->base.engine.subdev.mutex);
list_del_init(&chan->head);
mutex_unlock(&fifo->base.engine.subdev.mutex);
}
void
gk104_fifo_runlist_insert(struct gk104_fifo *fifo, struct gk104_fifo_chan *chan)
{
mutex_lock(&fifo->base.engine.subdev.mutex);
list_add_tail(&chan->head, &fifo->engine[chan->engine].chan);
mutex_unlock(&fifo->base.engine.subdev.mutex);
}
static inline struct nvkm_engine *
gk104_fifo_engine(struct gk104_fifo *fifo, u32 engn)
{
......@@ -112,7 +128,7 @@ gk104_fifo_recover_work(struct work_struct *work)
nvkm_subdev_fini(&engine->subdev, false);
WARN_ON(nvkm_subdev_init(&engine->subdev));
}
gk104_fifo_runlist_update(fifo, gk104_fifo_subdev_engine(engn));
gk104_fifo_runlist_commit(fifo, gk104_fifo_subdev_engine(engn));
}
nvkm_wr32(device, 0x00262c, engm);
......@@ -180,7 +196,7 @@ gk104_fifo_intr_sched_ctxsw(struct gk104_fifo *fifo)
spin_lock_irqsave(&fifo->base.lock, flags);
for (engn = 0; engn < ARRAY_SIZE(fifo->engine); engn++) {
u32 stat = nvkm_rd32(device, 0x002640 + (engn * 0x04));
u32 stat = nvkm_rd32(device, 0x002640 + (engn * 0x08));
u32 busy = (stat & 0x80000000);
u32 next = (stat & 0x07ff0000) >> 16;
u32 chsw = (stat & 0x00008000);
......
......@@ -5,6 +5,7 @@
#include <subdev/mmu.h>
struct gk104_fifo_chan;
struct gk104_fifo_engn {
struct nvkm_memory *runlist[2];
int cur_runlist;
......@@ -35,7 +36,9 @@ void gk104_fifo_fini(struct nvkm_fifo *);
void gk104_fifo_intr(struct nvkm_fifo *);
void gk104_fifo_uevent_init(struct nvkm_fifo *);
void gk104_fifo_uevent_fini(struct nvkm_fifo *);
void gk104_fifo_runlist_update(struct gk104_fifo *, u32 engine);
void gk104_fifo_runlist_insert(struct gk104_fifo *, struct gk104_fifo_chan *);
void gk104_fifo_runlist_remove(struct gk104_fifo *, struct gk104_fifo_chan *);
void gk104_fifo_runlist_commit(struct gk104_fifo *, u32 engine);
static inline u64
gk104_fifo_engine_subdev(int engine)
......
......@@ -27,6 +27,7 @@
#include <core/ramht.h>
#include <nvif/class.h>
#include <nvif/cl826f.h>
#include <nvif/unpack.h>
static int
......@@ -35,15 +36,15 @@ g84_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
{
struct nvkm_object *parent = oclass->parent;
union {
struct nv50_channel_gpfifo_v0 v0;
struct g82_channel_gpfifo_v0 v0;
} *args = data;
struct nv50_fifo *fifo = nv50_fifo(base);
struct nv50_fifo_chan *chan;
u64 ioffset, ilength;
int ret;
int ret = -ENOSYS;
nvif_ioctl(parent, "create channel gpfifo size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(parent, "create channel gpfifo vers %d vm %llx "
"pushbuf %llx ioffset %016llx "
"ilength %08x\n",
......
......@@ -29,6 +29,7 @@
#include <subdev/timer.h>
#include <nvif/class.h>
#include <nvif/cl906f.h>
#include <nvif/unpack.h>
static u32
......@@ -138,9 +139,9 @@ gf100_fifo_gpfifo_fini(struct nvkm_fifo_chan *base)
u32 coff = chan->base.chid * 8;
if (!list_empty(&chan->head) && !chan->killed) {
list_del_init(&chan->head);
gf100_fifo_runlist_remove(fifo, chan);
nvkm_mask(device, 0x003004 + coff, 0x00000001, 0x00000000);
gf100_fifo_runlist_update(fifo);
gf100_fifo_runlist_commit(fifo);
}
gf100_fifo_intr_engine(fifo);
......@@ -160,9 +161,9 @@ gf100_fifo_gpfifo_init(struct nvkm_fifo_chan *base)
nvkm_wr32(device, 0x003000 + coff, 0xc0000000 | addr);
if (list_empty(&chan->head) && !chan->killed) {
list_add_tail(&chan->head, &fifo->chan);
gf100_fifo_runlist_insert(fifo, chan);
nvkm_wr32(device, 0x003004 + coff, 0x001f0001);
gf100_fifo_runlist_update(fifo);
gf100_fifo_runlist_commit(fifo);
}
}
......@@ -199,10 +200,10 @@ gf100_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
struct nvkm_object *parent = oclass->parent;
struct gf100_fifo_chan *chan;
u64 usermem, ioffset, ilength;
int ret, i;
int ret = -ENOSYS, i;
nvif_ioctl(parent, "create channel gpfifo size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(parent, "create channel gpfifo vers %d vm %llx "
"ioffset %016llx ilength %08x\n",
args->v0.version, args->v0.vm, args->v0.ioffset,
......
......@@ -30,6 +30,7 @@
#include <subdev/timer.h>
#include <nvif/class.h>
#include <nvif/cla06f.h>
#include <nvif/unpack.h>
static int
......@@ -151,9 +152,9 @@ gk104_fifo_gpfifo_fini(struct nvkm_fifo_chan *base)
u32 coff = chan->base.chid * 8;
if (!list_empty(&chan->head)) {
list_del_init(&chan->head);
gk104_fifo_runlist_remove(fifo, chan);
nvkm_mask(device, 0x800004 + coff, 0x00000800, 0x00000800);
gk104_fifo_runlist_update(fifo, chan->engine);
gk104_fifo_runlist_commit(fifo, chan->engine);
}
nvkm_wr32(device, 0x800000 + coff, 0x00000000);
......@@ -172,9 +173,9 @@ gk104_fifo_gpfifo_init(struct nvkm_fifo_chan *base)
nvkm_wr32(device, 0x800000 + coff, 0x80000000 | addr);
if (list_empty(&chan->head) && !chan->killed) {
list_add_tail(&chan->head, &fifo->engine[chan->engine].chan);
gk104_fifo_runlist_insert(fifo, chan);
nvkm_mask(device, 0x800004 + coff, 0x00000400, 0x00000400);
gk104_fifo_runlist_update(fifo, chan->engine);
gk104_fifo_runlist_commit(fifo, chan->engine);
nvkm_mask(device, 0x800004 + coff, 0x00000400, 0x00000400);
}
}
......@@ -213,10 +214,10 @@ gk104_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
struct gk104_fifo_chan *chan;
u64 usermem, ioffset, ilength;
u32 engines;
int ret, i;
int ret = -ENOSYS, i;
nvif_ioctl(parent, "create channel gpfifo size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(parent, "create channel gpfifo vers %d vm %llx "
"ioffset %016llx ilength %08x engine %08x\n",
args->v0.version, args->v0.vm, args->v0.ioffset,
......
......@@ -27,6 +27,7 @@
#include <core/ramht.h>
#include <nvif/class.h>
#include <nvif/cl506f.h>
#include <nvif/unpack.h>
static int
......@@ -40,10 +41,10 @@ nv50_fifo_gpfifo_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
struct nv50_fifo *fifo = nv50_fifo(base);
struct nv50_fifo_chan *chan;
u64 ioffset, ilength;
int ret;
int ret = -ENOSYS;
nvif_ioctl(parent, "create channel gpfifo size %d\n", size);
if (nvif_unpack(args->v0, 0, 0, false)) {
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(parent, "create channel gpfifo vers %d vm %llx "
"pushbuf %llx ioffset %016llx "
"ilength %08x\n",
......
......@@ -55,7 +55,7 @@ gk20a_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
gk104_grctx_generate_rop_active_fbps(gr);
nvkm_mask(device, 0x5044b0, 0x8000000, 0x8000000);
nvkm_mask(device, 0x5044b0, 0x08000000, 0x08000000);
gf100_gr_wait_idle(gr);
......
......@@ -247,10 +247,7 @@ init:
tpc_strand_info(-1);
ld b32 $r4 D[$r0 + #tpc_count]
mov $r5 NV_PGRAPH_GPC0_TPC0
ld b32 $r6 D[$r0 + #gpc_id]
shl b32 $r6 15
add b32 $r5 $r6
gpc_addr($r5, NV_PGRAPH_GPC0_TPC0)
tpc_strand_init_tpc_loop:
add b32 $r14 $r5 NV_TPC_STRAND_CNT
call(nv_rd32)
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册