core:
 - fix drm_wait_vblank uapi copying bug
 
 ttm:
 - fix debugfs init when debugfs is off
 
 amdgpu:
 - vega10 SMU workload fix
 - DCN VM fix
 - DCN 3.01 watermark fix
 
 amdkfd:
 - SVM fix
 
 nouveau:
 - ampere display fixes
 - remove MM misfeature to fix a longstanding race condition
 
 i915:
 - tweaked display workaround for all PCHs
 - eDP MSO pipe sanity for ADL-P fix
 - remove unused symbol export
 
 mediatek:
 - AAL output size setting
 - Delete component in remove function
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEEKbZHaGwW9KfbeusDHTzWXnEhr4FAmEfPsgACgkQDHTzWXnE
 hr5BEg//QPG86+IybghlzsLRtzyC/YnE12gkkREmq67gNqY8rVUdC8jR7nq2OJWa
 S1M6WR0wLR9mfw+zLr6HXnaP5+KqGe0JqnJVIyMx50LSL8qJzttO5wHzp+G2tI7C
 +lPozccei+VirWj351Qall+TmV1s2I1h/QnW/CyGEa/uQ8iZXr7+1fad3st8194c
 Lzb+qFvwykEa4jeo8oD2OHiCHCGkTkI1cnSt9g7/BMCzRr5KuNaFAd5hvSUaQyfD
 5FX+0/sPiGRzIbLDHU/xTVvdvDcSW0w8+x93EcPkaGLfQd7FNzOCoEOwdYvBqcSL
 p49rIEwfAltyHKKvqajD05DUAe+XS+LGhN99ykW1zoO+s9qPchzNrAaGImrZlbw+
 JAruyxW2NhxBBXGlx0AgyCBdbWjydosfIToj/GXf7uXZRkxxtNQlFj56i+PT0hx3
 Xadc7BBNZvHYY5JCi9oEDttrsQUexRy9XWTfN9o1I7oN4Uuksn7CtRXSHG/UfYa2
 90z6rVTmAaS8h/3Ir5FMBY/O8aQbKHK27Rui9vgSmRNMwxKUun2+UjKJLC8DFZFu
 zx4mc5p+ByC3GmLb9G4FOj1DI5ZeNIHrX/JD6Lf78ooje+vW5mme1iMGQp+jlb6C
 FAtpNteDMeqY/b5piJDoJ0qWxqm0YqL2K5S1mDauPPthAu73uS8=
 =7B9v
 -----END PGP SIGNATURE-----

Merge tag 'drm-fixes-2021-08-20-3' of git://anongit.freedesktop.org/drm/drm

Pull drm fixes from Dave Airlie:
 "Regularly scheduled fixes. The ttm one solves a problem of GPU drivers
  failing to load if debugfs is off in Kconfig, otherwise the i915 and
  mediatek, and amdgpu fixes all fairly normal.

  Nouveau has a couple of display fixes, but it has a fix for a
  longstanding race condition in it's memory manager code, and the fix
  mostly removes some code that wasn't working properly and has no
  userspace users. This fix makes the diffstat kinda larger but in a
  good (negative line-count) way.

  core:
   - fix drm_wait_vblank uapi copying bug

  ttm:
   - fix debugfs init when debugfs is off

  amdgpu:
   - vega10 SMU workload fix
   - DCN VM fix
   - DCN 3.01 watermark fix

  amdkfd:
   - SVM fix

  nouveau:
   - ampere display fixes
   - remove MM misfeature to fix a longstanding race condition

  i915:
   - tweaked display workaround for all PCHs
   - eDP MSO pipe sanity for ADL-P fix
   - remove unused symbol export

  mediatek:
   - AAL output size setting
   - Delete component in remove function"

* tag 'drm-fixes-2021-08-20-3' of git://anongit.freedesktop.org/drm/drm:
  drm/amd/display: Use DCN30 watermark calc for DCN301
  drm/i915/dp: remove superfluous EXPORT_SYMBOL()
  drm/i915/edp: fix eDP MSO pipe sanity checks for ADL-P
  drm/i915: Tweaked Wa_14010685332 for all PCHs
  drm/nouveau: rip out nvkm_client.super
  drm/nouveau: block a bunch of classes from userspace
  drm/nouveau/fifo/nv50-: rip out dma channels
  drm/nouveau/kms/nv50: workaround EFI GOP window channel format differences
  drm/nouveau/disp: power down unused DP links during init
  drm/nouveau: recognise GA107
  drm: Copy drm_wait_vblank to user before returning
  drm/amd/display: Ensure DCN save after VM setup
  drm/amdkfd: fix random KFDSVMRangeTest.SetGetAttributesTest test failure
  drm/amd/pm: change the workload type for some cards
  Revert "drm/amd/pm: fix workload mismatch on vega10"
  drm: ttm: Don't bail from ttm_global_init if debugfs_create_dir fails
  drm/mediatek: Add component_del in OVL and COLOR remove function
  drm/mediatek: Add AAL output size configuration
This commit is contained in:
Linus Torvalds 2021-08-20 12:59:54 -07:00
Родитель 3db903a8ea daa7772d47
Коммит 8ba9fbe1e4
61 изменённых файлов: 224 добавлений и 477 удалений

Просмотреть файл

@ -3026,6 +3026,14 @@ svm_range_get_attr(struct kfd_process *p, uint64_t start, uint64_t size,
pr_debug("svms 0x%p [0x%llx 0x%llx] nattr 0x%x\n", &p->svms, start,
start + size - 1, nattr);
/* Flush pending deferred work to avoid racing with deferred actions from
* previous memory map changes (e.g. munmap). Concurrent memory map changes
* can still race with get_attr because we don't hold the mmap lock. But that
* would be a race condition in the application anyway, and undefined
* behaviour is acceptable in that case.
*/
flush_work(&p->svms.deferred_list_work);
mmap_read_lock(mm);
if (!svm_range_is_valid(mm, start, size)) {
pr_debug("invalid range\n");

Просмотреть файл

@ -1530,6 +1530,12 @@ void dc_z10_restore(struct dc *dc)
if (dc->hwss.z10_restore)
dc->hwss.z10_restore(dc);
}
void dc_z10_save_init(struct dc *dc)
{
if (dc->hwss.z10_save_init)
dc->hwss.z10_save_init(dc);
}
#endif
/*
* Applies given context to HW and copy it into current context.

Просмотреть файл

@ -47,6 +47,9 @@ int dc_setup_system_context(struct dc *dc, struct dc_phy_addr_space_config *pa_c
*/
memcpy(&dc->vm_pa_config, pa_config, sizeof(struct dc_phy_addr_space_config));
dc->vm_pa_config.valid = true;
#if defined(CONFIG_DRM_AMD_DC_DCN)
dc_z10_save_init(dc);
#endif
}
return num_vmids;

Просмотреть файл

@ -1338,6 +1338,7 @@ void dc_hardware_release(struct dc *dc);
bool dc_set_psr_allow_active(struct dc *dc, bool enable);
#if defined(CONFIG_DRM_AMD_DC_DCN)
void dc_z10_restore(struct dc *dc);
void dc_z10_save_init(struct dc *dc);
#endif
bool dc_enable_dmub_notifications(struct dc *dc);

Просмотреть файл

@ -1622,106 +1622,12 @@ static void dcn301_update_bw_bounding_box(struct dc *dc, struct clk_bw_params *b
dml_init_instance(&dc->dml, &dcn3_01_soc, &dcn3_01_ip, DML_PROJECT_DCN30);
}
static void calculate_wm_set_for_vlevel(
int vlevel,
struct wm_range_table_entry *table_entry,
struct dcn_watermarks *wm_set,
struct display_mode_lib *dml,
display_e2e_pipe_params_st *pipes,
int pipe_cnt)
{
double dram_clock_change_latency_cached = dml->soc.dram_clock_change_latency_us;
ASSERT(vlevel < dml->soc.num_states);
/* only pipe 0 is read for voltage and dcf/soc clocks */
pipes[0].clks_cfg.voltage = vlevel;
pipes[0].clks_cfg.dcfclk_mhz = dml->soc.clock_limits[vlevel].dcfclk_mhz;
pipes[0].clks_cfg.socclk_mhz = dml->soc.clock_limits[vlevel].socclk_mhz;
dml->soc.dram_clock_change_latency_us = table_entry->pstate_latency_us;
dml->soc.sr_exit_time_us = table_entry->sr_exit_time_us;
dml->soc.sr_enter_plus_exit_time_us = table_entry->sr_enter_plus_exit_time_us;
wm_set->urgent_ns = get_wm_urgent(dml, pipes, pipe_cnt) * 1000;
wm_set->cstate_pstate.cstate_enter_plus_exit_ns = get_wm_stutter_enter_exit(dml, pipes, pipe_cnt) * 1000;
wm_set->cstate_pstate.cstate_exit_ns = get_wm_stutter_exit(dml, pipes, pipe_cnt) * 1000;
wm_set->cstate_pstate.pstate_change_ns = get_wm_dram_clock_change(dml, pipes, pipe_cnt) * 1000;
wm_set->pte_meta_urgent_ns = get_wm_memory_trip(dml, pipes, pipe_cnt) * 1000;
wm_set->frac_urg_bw_nom = get_fraction_of_urgent_bandwidth(dml, pipes, pipe_cnt) * 1000;
wm_set->frac_urg_bw_flip = get_fraction_of_urgent_bandwidth_imm_flip(dml, pipes, pipe_cnt) * 1000;
wm_set->urgent_latency_ns = get_urgent_latency(dml, pipes, pipe_cnt) * 1000;
dml->soc.dram_clock_change_latency_us = dram_clock_change_latency_cached;
}
static void dcn301_calculate_wm_and_dlg(
struct dc *dc, struct dc_state *context,
display_e2e_pipe_params_st *pipes,
int pipe_cnt,
int vlevel_req)
{
int i, pipe_idx;
int vlevel, vlevel_max;
struct wm_range_table_entry *table_entry;
struct clk_bw_params *bw_params = dc->clk_mgr->bw_params;
ASSERT(bw_params);
vlevel_max = bw_params->clk_table.num_entries - 1;
/* WM Set D */
table_entry = &bw_params->wm_table.entries[WM_D];
if (table_entry->wm_type == WM_TYPE_RETRAINING)
vlevel = 0;
else
vlevel = vlevel_max;
calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.d,
&context->bw_ctx.dml, pipes, pipe_cnt);
/* WM Set C */
table_entry = &bw_params->wm_table.entries[WM_C];
vlevel = min(max(vlevel_req, 2), vlevel_max);
calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.c,
&context->bw_ctx.dml, pipes, pipe_cnt);
/* WM Set B */
table_entry = &bw_params->wm_table.entries[WM_B];
vlevel = min(max(vlevel_req, 1), vlevel_max);
calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.b,
&context->bw_ctx.dml, pipes, pipe_cnt);
/* WM Set A */
table_entry = &bw_params->wm_table.entries[WM_A];
vlevel = min(vlevel_req, vlevel_max);
calculate_wm_set_for_vlevel(vlevel, table_entry, &context->bw_ctx.bw.dcn.watermarks.a,
&context->bw_ctx.dml, pipes, pipe_cnt);
for (i = 0, pipe_idx = 0; i < dc->res_pool->pipe_count; i++) {
if (!context->res_ctx.pipe_ctx[i].stream)
continue;
pipes[pipe_idx].clks_cfg.dispclk_mhz = get_dispclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt);
pipes[pipe_idx].clks_cfg.dppclk_mhz = get_dppclk_calculated(&context->bw_ctx.dml, pipes, pipe_cnt, pipe_idx);
if (dc->config.forced_clocks) {
pipes[pipe_idx].clks_cfg.dispclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dispclk_mhz;
pipes[pipe_idx].clks_cfg.dppclk_mhz = context->bw_ctx.dml.soc.clock_limits[0].dppclk_mhz;
}
if (dc->debug.min_disp_clk_khz > pipes[pipe_idx].clks_cfg.dispclk_mhz * 1000)
pipes[pipe_idx].clks_cfg.dispclk_mhz = dc->debug.min_disp_clk_khz / 1000.0;
if (dc->debug.min_dpp_clk_khz > pipes[pipe_idx].clks_cfg.dppclk_mhz * 1000)
pipes[pipe_idx].clks_cfg.dppclk_mhz = dc->debug.min_dpp_clk_khz / 1000.0;
pipe_idx++;
}
dcn20_calculate_dlg_params(dc, context, pipes, pipe_cnt, vlevel);
}
static struct resource_funcs dcn301_res_pool_funcs = {
.destroy = dcn301_destroy_resource_pool,
.link_enc_create = dcn301_link_encoder_create,
.panel_cntl_create = dcn301_panel_cntl_create,
.validate_bandwidth = dcn30_validate_bandwidth,
.calculate_wm_and_dlg = dcn301_calculate_wm_and_dlg,
.calculate_wm_and_dlg = dcn30_calculate_wm_and_dlg,
.update_soc_for_wm_a = dcn30_update_soc_for_wm_a,
.populate_dml_pipes = dcn30_populate_dml_pipes_from_context,
.acquire_idle_pipe_for_layer = dcn20_acquire_idle_pipe_for_layer,

Просмотреть файл

@ -404,6 +404,18 @@ void dcn31_update_info_frame(struct pipe_ctx *pipe_ctx)
&pipe_ctx->stream_res.encoder_info_frame);
}
}
void dcn31_z10_save_init(struct dc *dc)
{
union dmub_rb_cmd cmd;
memset(&cmd, 0, sizeof(cmd));
cmd.dcn_restore.header.type = DMUB_CMD__IDLE_OPT;
cmd.dcn_restore.header.sub_type = DMUB_CMD__IDLE_OPT_DCN_SAVE_INIT;
dc_dmub_srv_cmd_queue(dc->ctx->dmub_srv, &cmd);
dc_dmub_srv_cmd_execute(dc->ctx->dmub_srv);
dc_dmub_srv_wait_idle(dc->ctx->dmub_srv);
}
void dcn31_z10_restore(struct dc *dc)
{

Просмотреть файл

@ -44,6 +44,7 @@ void dcn31_enable_power_gating_plane(
void dcn31_update_info_frame(struct pipe_ctx *pipe_ctx);
void dcn31_z10_restore(struct dc *dc);
void dcn31_z10_save_init(struct dc *dc);
void dcn31_hubp_pg_control(struct dce_hwseq *hws, unsigned int hubp_inst, bool power_on);
int dcn31_init_sys_ctx(struct dce_hwseq *hws, struct dc *dc, struct dc_phy_addr_space_config *pa_config);

Просмотреть файл

@ -97,6 +97,7 @@ static const struct hw_sequencer_funcs dcn31_funcs = {
.set_abm_immediate_disable = dcn21_set_abm_immediate_disable,
.set_pipe = dcn21_set_pipe,
.z10_restore = dcn31_z10_restore,
.z10_save_init = dcn31_z10_save_init,
.is_abm_supported = dcn31_is_abm_supported,
.set_disp_pattern_generator = dcn30_set_disp_pattern_generator,
.update_visual_confirm_color = dcn20_update_visual_confirm_color,

Просмотреть файл

@ -237,6 +237,7 @@ struct hw_sequencer_funcs {
int width, int height, int offset);
void (*z10_restore)(struct dc *dc);
void (*z10_save_init)(struct dc *dc);
void (*update_visual_confirm_color)(struct dc *dc,
struct pipe_ctx *pipe_ctx,

Просмотреть файл

@ -856,6 +856,11 @@ enum dmub_cmd_idle_opt_type {
* DCN hardware restore.
*/
DMUB_CMD__IDLE_OPT_DCN_RESTORE = 0,
/**
* DCN hardware save.
*/
DMUB_CMD__IDLE_OPT_DCN_SAVE_INIT = 1
};
/**

Просмотреть файл

@ -5127,6 +5127,13 @@ static int vega10_get_power_profile_mode(struct pp_hwmgr *hwmgr, char *buf)
return size;
}
static bool vega10_get_power_profile_mode_quirks(struct pp_hwmgr *hwmgr)
{
struct amdgpu_device *adev = hwmgr->adev;
return (adev->pdev->device == 0x6860);
}
static int vega10_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, uint32_t size)
{
struct vega10_hwmgr *data = hwmgr->backend;
@ -5163,9 +5170,15 @@ static int vega10_set_power_profile_mode(struct pp_hwmgr *hwmgr, long *input, ui
}
out:
smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetWorkloadMask,
if (vega10_get_power_profile_mode_quirks(hwmgr))
smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetWorkloadMask,
1 << power_profile_mode,
NULL);
else
smum_send_msg_to_smc_with_parameter(hwmgr, PPSMC_MSG_SetWorkloadMask,
(!power_profile_mode) ? 0 : 1 << (power_profile_mode - 1),
NULL);
hwmgr->power_profile_mode = power_profile_mode;
return 0;

Просмотреть файл

@ -855,8 +855,6 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd,
req.request.sequence = req32.request.sequence;
req.request.signal = req32.request.signal;
err = drm_ioctl_kernel(file, drm_wait_vblank_ioctl, &req, DRM_UNLOCKED);
if (err)
return err;
req32.reply.type = req.reply.type;
req32.reply.sequence = req.reply.sequence;
@ -865,7 +863,7 @@ static int compat_drm_wait_vblank(struct file *file, unsigned int cmd,
if (copy_to_user(argp, &req32, sizeof(req32)))
return -EFAULT;
return 0;
return err;
}
#if defined(CONFIG_X86)

Просмотреть файл

@ -2463,6 +2463,15 @@ static void intel_ddi_power_up_lanes(struct intel_encoder *encoder,
}
}
/* Splitter enable for eDP MSO is limited to certain pipes. */
static u8 intel_ddi_splitter_pipe_mask(struct drm_i915_private *i915)
{
if (IS_ALDERLAKE_P(i915))
return BIT(PIPE_A) | BIT(PIPE_B);
else
return BIT(PIPE_A);
}
static void intel_ddi_mso_get_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config)
{
@ -2480,8 +2489,7 @@ static void intel_ddi_mso_get_config(struct intel_encoder *encoder,
if (!pipe_config->splitter.enable)
return;
/* Splitter enable is supported for pipe A only. */
if (drm_WARN_ON(&i915->drm, pipe != PIPE_A)) {
if (drm_WARN_ON(&i915->drm, !(intel_ddi_splitter_pipe_mask(i915) & BIT(pipe)))) {
pipe_config->splitter.enable = false;
return;
}
@ -2513,10 +2521,6 @@ static void intel_ddi_mso_configure(const struct intel_crtc_state *crtc_state)
return;
if (crtc_state->splitter.enable) {
/* Splitter enable is supported for pipe A only. */
if (drm_WARN_ON(&i915->drm, pipe != PIPE_A))
return;
dss1 |= SPLITTER_ENABLE;
dss1 |= OVERLAP_PIXELS(crtc_state->splitter.pixel_overlap);
if (crtc_state->splitter.link_count == 2)
@ -4743,12 +4747,8 @@ void intel_ddi_init(struct drm_i915_private *dev_priv, enum port port)
dig_port->hpd_pulse = intel_dp_hpd_pulse;
/* Splitter enable for eDP MSO is limited to certain pipes. */
if (dig_port->dp.mso_link_count) {
encoder->pipe_mask = BIT(PIPE_A);
if (IS_ALDERLAKE_P(dev_priv))
encoder->pipe_mask |= BIT(PIPE_B);
}
if (dig_port->dp.mso_link_count)
encoder->pipe_mask = intel_ddi_splitter_pipe_mask(dev_priv);
}
/* In theory we don't need the encoder->type check, but leave it just in

Просмотреть файл

@ -6387,13 +6387,13 @@ void intel_display_power_suspend_late(struct drm_i915_private *i915)
if (DISPLAY_VER(i915) >= 11 || IS_GEMINILAKE(i915) ||
IS_BROXTON(i915)) {
bxt_enable_dc9(i915);
/* Tweaked Wa_14010685332:icp,jsp,mcc */
if (INTEL_PCH_TYPE(i915) >= PCH_ICP && INTEL_PCH_TYPE(i915) <= PCH_MCC)
intel_de_rmw(i915, SOUTH_CHICKEN1,
SBCLK_RUN_REFCLK_DIS, SBCLK_RUN_REFCLK_DIS);
} else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
hsw_enable_pc8(i915);
}
/* Tweaked Wa_14010685332:cnp,icp,jsp,mcc,tgp,adp */
if (INTEL_PCH_TYPE(i915) >= PCH_CNP && INTEL_PCH_TYPE(i915) < PCH_DG1)
intel_de_rmw(i915, SOUTH_CHICKEN1, SBCLK_RUN_REFCLK_DIS, SBCLK_RUN_REFCLK_DIS);
}
void intel_display_power_resume_early(struct drm_i915_private *i915)
@ -6402,13 +6402,13 @@ void intel_display_power_resume_early(struct drm_i915_private *i915)
IS_BROXTON(i915)) {
gen9_sanitize_dc_state(i915);
bxt_disable_dc9(i915);
/* Tweaked Wa_14010685332:icp,jsp,mcc */
if (INTEL_PCH_TYPE(i915) >= PCH_ICP && INTEL_PCH_TYPE(i915) <= PCH_MCC)
intel_de_rmw(i915, SOUTH_CHICKEN1, SBCLK_RUN_REFCLK_DIS, 0);
} else if (IS_HASWELL(i915) || IS_BROADWELL(i915)) {
hsw_disable_pc8(i915);
}
/* Tweaked Wa_14010685332:cnp,icp,jsp,mcc,tgp,adp */
if (INTEL_PCH_TYPE(i915) >= PCH_CNP && INTEL_PCH_TYPE(i915) < PCH_DG1)
intel_de_rmw(i915, SOUTH_CHICKEN1, SBCLK_RUN_REFCLK_DIS, 0);
}
void intel_display_power_suspend(struct drm_i915_private *i915)

Просмотреть файл

@ -206,7 +206,6 @@ int intel_dp_init_lttpr_and_dprx_caps(struct intel_dp *intel_dp)
return lttpr_count;
}
EXPORT_SYMBOL(intel_dp_init_lttpr_and_dprx_caps);
static u8 dp_voltage_max(u8 preemph)
{

Просмотреть файл

@ -3064,24 +3064,6 @@ static void valleyview_irq_reset(struct drm_i915_private *dev_priv)
spin_unlock_irq(&dev_priv->irq_lock);
}
static void cnp_display_clock_wa(struct drm_i915_private *dev_priv)
{
struct intel_uncore *uncore = &dev_priv->uncore;
/*
* Wa_14010685332:cnp/cmp,tgp,adp
* TODO: Clarify which platforms this applies to
* TODO: Figure out if this workaround can be applied in the s0ix suspend/resume handlers as
* on earlier platforms and whether the workaround is also needed for runtime suspend/resume
*/
if (INTEL_PCH_TYPE(dev_priv) == PCH_CNP ||
(INTEL_PCH_TYPE(dev_priv) >= PCH_TGP && INTEL_PCH_TYPE(dev_priv) < PCH_DG1)) {
intel_uncore_rmw(uncore, SOUTH_CHICKEN1, SBCLK_RUN_REFCLK_DIS,
SBCLK_RUN_REFCLK_DIS);
intel_uncore_rmw(uncore, SOUTH_CHICKEN1, SBCLK_RUN_REFCLK_DIS, 0);
}
}
static void gen8_display_irq_reset(struct drm_i915_private *dev_priv)
{
struct intel_uncore *uncore = &dev_priv->uncore;
@ -3115,7 +3097,6 @@ static void gen8_irq_reset(struct drm_i915_private *dev_priv)
if (HAS_PCH_SPLIT(dev_priv))
ibx_irq_reset(dev_priv);
cnp_display_clock_wa(dev_priv);
}
static void gen11_display_irq_reset(struct drm_i915_private *dev_priv)
@ -3159,8 +3140,6 @@ static void gen11_display_irq_reset(struct drm_i915_private *dev_priv)
if (INTEL_PCH_TYPE(dev_priv) >= PCH_ICP)
GEN3_IRQ_RESET(uncore, SDE);
cnp_display_clock_wa(dev_priv);
}
static void gen11_irq_reset(struct drm_i915_private *dev_priv)

Просмотреть файл

@ -133,6 +133,8 @@ static int mtk_disp_color_probe(struct platform_device *pdev)
static int mtk_disp_color_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &mtk_disp_color_component_ops);
return 0;
}

Просмотреть файл

@ -423,6 +423,8 @@ static int mtk_disp_ovl_probe(struct platform_device *pdev)
static int mtk_disp_ovl_remove(struct platform_device *pdev)
{
component_del(&pdev->dev, &mtk_disp_ovl_component_ops);
return 0;
}

Просмотреть файл

@ -34,6 +34,7 @@
#define DISP_AAL_EN 0x0000
#define DISP_AAL_SIZE 0x0030
#define DISP_AAL_OUTPUT_SIZE 0x04d8
#define DISP_DITHER_EN 0x0000
#define DITHER_EN BIT(0)
@ -197,6 +198,7 @@ static void mtk_aal_config(struct device *dev, unsigned int w,
struct mtk_ddp_comp_dev *priv = dev_get_drvdata(dev);
mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_AAL_SIZE);
mtk_ddp_write(cmdq_pkt, w << 16 | h, &priv->cmdq_reg, priv->regs, DISP_AAL_OUTPUT_SIZE);
}
static void mtk_aal_gamma_set(struct device *dev, struct drm_crtc_state *state)

Просмотреть файл

@ -2237,6 +2237,33 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
interlock[NV50_DISP_INTERLOCK_CORE] = 0;
}
/* Finish updating head(s)...
*
* NVD is rather picky about both where window assignments can change,
* *and* about certain core and window channel states matching.
*
* The EFI GOP driver on newer GPUs configures window channels with a
* different output format to what we do, and the core channel update
* in the assign_windows case above would result in a state mismatch.
*
* Delay some of the head update until after that point to workaround
* the issue. This only affects the initial modeset.
*
* TODO: handle this better when adding flexible window mapping
*/
for_each_oldnew_crtc_in_state(state, crtc, old_crtc_state, new_crtc_state, i) {
struct nv50_head_atom *asyh = nv50_head_atom(new_crtc_state);
struct nv50_head *head = nv50_head(crtc);
NV_ATOMIC(drm, "%s: set %04x (clr %04x)\n", crtc->name,
asyh->set.mask, asyh->clr.mask);
if (asyh->set.mask) {
nv50_head_flush_set_wndw(head, asyh);
interlock[NV50_DISP_INTERLOCK_CORE] = 1;
}
}
/* Update plane(s). */
for_each_new_plane_in_state(state, plane, new_plane_state, i) {
struct nv50_wndw_atom *asyw = nv50_wndw_atom(new_plane_state);

Просмотреть файл

@ -50,11 +50,8 @@ nv50_head_flush_clr(struct nv50_head *head,
}
void
nv50_head_flush_set(struct nv50_head *head, struct nv50_head_atom *asyh)
nv50_head_flush_set_wndw(struct nv50_head *head, struct nv50_head_atom *asyh)
{
if (asyh->set.view ) head->func->view (head, asyh);
if (asyh->set.mode ) head->func->mode (head, asyh);
if (asyh->set.core ) head->func->core_set(head, asyh);
if (asyh->set.olut ) {
asyh->olut.offset = nv50_lut_load(&head->olut,
asyh->olut.buffer,
@ -62,6 +59,14 @@ nv50_head_flush_set(struct nv50_head *head, struct nv50_head_atom *asyh)
asyh->olut.load);
head->func->olut_set(head, asyh);
}
}
void
nv50_head_flush_set(struct nv50_head *head, struct nv50_head_atom *asyh)
{
if (asyh->set.view ) head->func->view (head, asyh);
if (asyh->set.mode ) head->func->mode (head, asyh);
if (asyh->set.core ) head->func->core_set(head, asyh);
if (asyh->set.curs ) head->func->curs_set(head, asyh);
if (asyh->set.base ) head->func->base (head, asyh);
if (asyh->set.ovly ) head->func->ovly (head, asyh);

Просмотреть файл

@ -21,6 +21,7 @@ struct nv50_head {
struct nv50_head *nv50_head_create(struct drm_device *, int index);
void nv50_head_flush_set(struct nv50_head *head, struct nv50_head_atom *asyh);
void nv50_head_flush_set_wndw(struct nv50_head *head, struct nv50_head_atom *asyh);
void nv50_head_flush_clr(struct nv50_head *head,
struct nv50_head_atom *asyh, bool flush);

Просмотреть файл

@ -4,7 +4,8 @@
struct nv_device_v0 {
__u8 version;
__u8 pad01[7];
__u8 priv;
__u8 pad02[6];
__u64 device; /* device identifier, ~0 for client default */
};

Просмотреть файл

@ -61,8 +61,6 @@
#define NV10_CHANNEL_DMA /* cl506b.h */ 0x0000006e
#define NV17_CHANNEL_DMA /* cl506b.h */ 0x0000176e
#define NV40_CHANNEL_DMA /* cl506b.h */ 0x0000406e
#define NV50_CHANNEL_DMA /* cl506e.h */ 0x0000506e
#define G82_CHANNEL_DMA /* cl826e.h */ 0x0000826e
#define NV50_CHANNEL_GPFIFO /* cl506f.h */ 0x0000506f
#define G82_CHANNEL_GPFIFO /* cl826f.h */ 0x0000826f

Просмотреть файл

@ -9,7 +9,6 @@ struct nvif_client {
const struct nvif_driver *driver;
u64 version;
u8 route;
bool super;
};
int nvif_client_ctor(struct nvif_client *parent, const char *name, u64 device,

Просмотреть файл

@ -11,7 +11,7 @@ struct nvif_driver {
void (*fini)(void *priv);
int (*suspend)(void *priv);
int (*resume)(void *priv);
int (*ioctl)(void *priv, bool super, void *data, u32 size, void **hack);
int (*ioctl)(void *priv, void *data, u32 size, void **hack);
void __iomem *(*map)(void *priv, u64 handle, u32 size);
void (*unmap)(void *priv, void __iomem *ptr, u32 size);
bool keep;

Просмотреть файл

@ -13,7 +13,6 @@ struct nvkm_client {
struct nvkm_client_notify *notify[32];
struct rb_root objroot;
bool super;
void *data;
int (*ntfy)(const void *, u32, const void *, u32);

Просмотреть файл

@ -4,5 +4,5 @@
#include <core/os.h>
struct nvkm_client;
int nvkm_ioctl(struct nvkm_client *, bool, void *, u32, void **);
int nvkm_ioctl(struct nvkm_client *, void *, u32, void **);
#endif

Просмотреть файл

@ -15,7 +15,6 @@ struct nvkm_vma {
u8 refd:3; /* Current page type (index, or NONE for unreferenced). */
bool used:1; /* Region allocated. */
bool part:1; /* Region was split from an allocated region by map(). */
bool user:1; /* Region user-allocated. */
bool busy:1; /* Region busy (for temporarily preventing user access). */
bool mapped:1; /* Region contains valid pages. */
struct nvkm_memory *memory; /* Memory currently mapped into VMA. */

Просмотреть файл

@ -570,11 +570,9 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS)
}
client->route = NVDRM_OBJECT_ABI16;
client->super = true;
ret = nvif_object_ctor(&chan->chan->user, "abi16Ntfy", info->handle,
NV_DMA_IN_MEMORY, &args, sizeof(args),
&ntfy->object);
client->super = false;
client->route = NVDRM_OBJECT_NVIF;
if (ret)
goto done;

Просмотреть файл

@ -86,12 +86,6 @@ nouveau_channel_del(struct nouveau_channel **pchan)
struct nouveau_channel *chan = *pchan;
if (chan) {
struct nouveau_cli *cli = (void *)chan->user.client;
bool super;
if (cli) {
super = cli->base.super;
cli->base.super = true;
}
if (chan->fence)
nouveau_fence(chan->drm)->context_del(chan);
@ -111,9 +105,6 @@ nouveau_channel_del(struct nouveau_channel **pchan)
nouveau_bo_unpin(chan->push.buffer);
nouveau_bo_ref(NULL, &chan->push.buffer);
kfree(chan);
if (cli)
cli->base.super = super;
}
*pchan = NULL;
}
@ -512,20 +503,16 @@ nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device,
struct nouveau_channel **pchan)
{
struct nouveau_cli *cli = (void *)device->object.client;
bool super;
int ret;
/* hack until fencenv50 is fixed, and agp access relaxed */
super = cli->base.super;
cli->base.super = true;
ret = nouveau_channel_ind(drm, device, arg0, priv, pchan);
if (ret) {
NV_PRINTK(dbg, cli, "ib channel create, %d\n", ret);
ret = nouveau_channel_dma(drm, device, pchan);
if (ret) {
NV_PRINTK(dbg, cli, "dma channel create, %d\n", ret);
goto done;
return ret;
}
}
@ -533,15 +520,13 @@ nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device,
if (ret) {
NV_PRINTK(err, cli, "channel failed to initialise, %d\n", ret);
nouveau_channel_del(pchan);
goto done;
return ret;
}
ret = nouveau_svmm_join((*pchan)->vmm->svmm, (*pchan)->inst);
if (ret)
nouveau_channel_del(pchan);
done:
cli->base.super = super;
return ret;
}

Просмотреть файл

@ -244,6 +244,7 @@ nouveau_cli_init(struct nouveau_drm *drm, const char *sname,
ret = nvif_device_ctor(&cli->base.object, "drmDevice", 0, NV_DEVICE,
&(struct nv_device_v0) {
.device = ~0,
.priv = true,
}, sizeof(struct nv_device_v0),
&cli->device);
if (ret) {
@ -1086,8 +1087,6 @@ nouveau_drm_open(struct drm_device *dev, struct drm_file *fpriv)
if (ret)
goto done;
cli->base.super = false;
fpriv->driver_priv = cli;
mutex_lock(&drm->client.mutex);

Просмотреть файл

@ -41,8 +41,6 @@ nouveau_mem_map(struct nouveau_mem *mem,
struct gf100_vmm_map_v0 gf100;
} args;
u32 argc = 0;
bool super;
int ret;
switch (vmm->object.oclass) {
case NVIF_CLASS_VMM_NV04:
@ -73,12 +71,7 @@ nouveau_mem_map(struct nouveau_mem *mem,
return -ENOSYS;
}
super = vmm->object.client->super;
vmm->object.client->super = true;
ret = nvif_vmm_map(vmm, vma->addr, mem->mem.size, &args, argc,
&mem->mem, 0);
vmm->object.client->super = super;
return ret;
return nvif_vmm_map(vmm, vma->addr, mem->mem.size, &args, argc, &mem->mem, 0);
}
void
@ -99,7 +92,6 @@ nouveau_mem_host(struct ttm_resource *reg, struct ttm_tt *tt)
struct nouveau_drm *drm = cli->drm;
struct nvif_mmu *mmu = &cli->mmu;
struct nvif_mem_ram_v0 args = {};
bool super = cli->base.super;
u8 type;
int ret;
@ -122,11 +114,9 @@ nouveau_mem_host(struct ttm_resource *reg, struct ttm_tt *tt)
args.dma = tt->dma_address;
mutex_lock(&drm->master.lock);
cli->base.super = true;
ret = nvif_mem_ctor_type(mmu, "ttmHostMem", cli->mem->oclass, type, PAGE_SHIFT,
reg->num_pages << PAGE_SHIFT,
&args, sizeof(args), &mem->mem);
cli->base.super = super;
mutex_unlock(&drm->master.lock);
return ret;
}
@ -138,12 +128,10 @@ nouveau_mem_vram(struct ttm_resource *reg, bool contig, u8 page)
struct nouveau_cli *cli = mem->cli;
struct nouveau_drm *drm = cli->drm;
struct nvif_mmu *mmu = &cli->mmu;
bool super = cli->base.super;
u64 size = ALIGN(reg->num_pages << PAGE_SHIFT, 1 << page);
int ret;
mutex_lock(&drm->master.lock);
cli->base.super = true;
switch (cli->mem->oclass) {
case NVIF_CLASS_MEM_GF100:
ret = nvif_mem_ctor_type(mmu, "ttmVram", cli->mem->oclass,
@ -167,7 +155,6 @@ nouveau_mem_vram(struct ttm_resource *reg, bool contig, u8 page)
WARN_ON(1);
break;
}
cli->base.super = super;
mutex_unlock(&drm->master.lock);
reg->start = mem->mem.addr >> PAGE_SHIFT;

Просмотреть файл

@ -52,9 +52,9 @@ nvkm_client_map(void *priv, u64 handle, u32 size)
}
static int
nvkm_client_ioctl(void *priv, bool super, void *data, u32 size, void **hack)
nvkm_client_ioctl(void *priv, void *data, u32 size, void **hack)
{
return nvkm_ioctl(priv, super, data, size, hack);
return nvkm_ioctl(priv, data, size, hack);
}
static int

Просмотреть файл

@ -237,14 +237,11 @@ void
nouveau_svmm_invalidate(struct nouveau_svmm *svmm, u64 start, u64 limit)
{
if (limit > start) {
bool super = svmm->vmm->vmm.object.client->super;
svmm->vmm->vmm.object.client->super = true;
nvif_object_mthd(&svmm->vmm->vmm.object, NVIF_VMM_V0_PFNCLR,
&(struct nvif_vmm_pfnclr_v0) {
.addr = start,
.size = limit - start,
}, sizeof(struct nvif_vmm_pfnclr_v0));
svmm->vmm->vmm.object.client->super = super;
}
}
@ -634,9 +631,7 @@ static int nouveau_atomic_range_fault(struct nouveau_svmm *svmm,
NVIF_VMM_PFNMAP_V0_A |
NVIF_VMM_PFNMAP_V0_HOST;
svmm->vmm->vmm.object.client->super = true;
ret = nvif_object_ioctl(&svmm->vmm->vmm.object, args, size, NULL);
svmm->vmm->vmm.object.client->super = false;
mutex_unlock(&svmm->mutex);
unlock_page(page);
@ -702,9 +697,7 @@ static int nouveau_range_fault(struct nouveau_svmm *svmm,
nouveau_hmm_convert_pfn(drm, &range, args);
svmm->vmm->vmm.object.client->super = true;
ret = nvif_object_ioctl(&svmm->vmm->vmm.object, args, size, NULL);
svmm->vmm->vmm.object.client->super = false;
mutex_unlock(&svmm->mutex);
out:
@ -928,10 +921,8 @@ nouveau_pfns_map(struct nouveau_svmm *svmm, struct mm_struct *mm,
mutex_lock(&svmm->mutex);
svmm->vmm->vmm.object.client->super = true;
ret = nvif_object_ioctl(&svmm->vmm->vmm.object, args, sizeof(*args) +
npages * sizeof(args->p.phys[0]), NULL);
svmm->vmm->vmm.object.client->super = false;
mutex_unlock(&svmm->mutex);
}

Просмотреть файл

@ -32,6 +32,9 @@
#include <nvif/event.h>
#include <nvif/ioctl.h>
#include <nvif/class.h>
#include <nvif/cl0080.h>
struct usif_notify_p {
struct drm_pending_event base;
struct {
@ -261,7 +264,7 @@ usif_object_dtor(struct usif_object *object)
}
static int
usif_object_new(struct drm_file *f, void *data, u32 size, void *argv, u32 argc)
usif_object_new(struct drm_file *f, void *data, u32 size, void *argv, u32 argc, bool parent_abi16)
{
struct nouveau_cli *cli = nouveau_cli(f);
struct nvif_client *client = &cli->base;
@ -271,23 +274,48 @@ usif_object_new(struct drm_file *f, void *data, u32 size, void *argv, u32 argc)
struct usif_object *object;
int ret = -ENOSYS;
if ((ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true)))
return ret;
switch (args->v0.oclass) {
case NV_DMA_FROM_MEMORY:
case NV_DMA_TO_MEMORY:
case NV_DMA_IN_MEMORY:
return -EINVAL;
case NV_DEVICE: {
union {
struct nv_device_v0 v0;
} *args = data;
if ((ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false)))
return ret;
args->v0.priv = false;
break;
}
default:
if (!parent_abi16)
return -EINVAL;
break;
}
if (!(object = kmalloc(sizeof(*object), GFP_KERNEL)))
return -ENOMEM;
list_add(&object->head, &cli->objects);
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;
args->v0.token = (unsigned long)(void *)object;
ret = nvif_client_ioctl(client, argv, argc);
args->v0.token = object->token;
args->v0.route = object->route;
object->route = args->v0.route;
object->token = args->v0.token;
args->v0.route = NVDRM_OBJECT_USIF;
args->v0.token = (unsigned long)(void *)object;
ret = nvif_client_ioctl(client, argv, argc);
if (ret) {
usif_object_dtor(object);
return ret;
}
if (ret)
usif_object_dtor(object);
return ret;
args->v0.token = object->token;
args->v0.route = object->route;
return 0;
}
int
@ -301,6 +329,7 @@ usif_ioctl(struct drm_file *filp, void __user *user, u32 argc)
struct nvif_ioctl_v0 v0;
} *argv = data;
struct usif_object *object;
bool abi16 = false;
u8 owner;
int ret;
@ -331,11 +360,13 @@ usif_ioctl(struct drm_file *filp, void __user *user, u32 argc)
mutex_unlock(&cli->mutex);
goto done;
}
abi16 = true;
}
switch (argv->v0.type) {
case NVIF_IOCTL_V0_NEW:
ret = usif_object_new(filp, data, size, argv, argc);
ret = usif_object_new(filp, data, size, argv, argc, abi16);
break;
case NVIF_IOCTL_V0_NTFY_NEW:
ret = usif_notify_new(filp, data, size, argv, argc);

Просмотреть файл

@ -32,7 +32,7 @@
int
nvif_client_ioctl(struct nvif_client *client, void *data, u32 size)
{
return client->driver->ioctl(client->object.priv, client->super, data, size, NULL);
return client->driver->ioctl(client->object.priv, data, size, NULL);
}
int
@ -80,7 +80,6 @@ nvif_client_ctor(struct nvif_client *parent, const char *name, u64 device,
client->object.client = client;
client->object.handle = ~0;
client->route = NVIF_IOCTL_V0_ROUTE_NVIF;
client->super = true;
client->driver = parent->driver;
if (ret == 0) {

Просмотреть файл

@ -44,8 +44,7 @@ nvif_object_ioctl(struct nvif_object *object, void *data, u32 size, void **hack)
} else
return -ENOSYS;
return client->driver->ioctl(client->object.priv, client->super,
data, size, hack);
return client->driver->ioctl(client->object.priv, data, size, hack);
}
void

Просмотреть файл

@ -426,8 +426,7 @@ nvkm_ioctl_path(struct nvkm_client *client, u64 handle, u32 type,
}
int
nvkm_ioctl(struct nvkm_client *client, bool supervisor,
void *data, u32 size, void **hack)
nvkm_ioctl(struct nvkm_client *client, void *data, u32 size, void **hack)
{
struct nvkm_object *object = &client->object;
union {
@ -435,7 +434,6 @@ nvkm_ioctl(struct nvkm_client *client, bool supervisor,
} *args = data;
int ret = -ENOSYS;
client->super = supervisor;
nvif_ioctl(object, "size %d\n", size);
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {

Просмотреть файл

@ -2624,6 +2624,26 @@ nv174_chipset = {
.dma = { 0x00000001, gv100_dma_new },
};
static const struct nvkm_device_chip
nv177_chipset = {
.name = "GA107",
.bar = { 0x00000001, tu102_bar_new },
.bios = { 0x00000001, nvkm_bios_new },
.devinit = { 0x00000001, ga100_devinit_new },
.fb = { 0x00000001, ga102_fb_new },
.gpio = { 0x00000001, ga102_gpio_new },
.i2c = { 0x00000001, gm200_i2c_new },
.imem = { 0x00000001, nv50_instmem_new },
.mc = { 0x00000001, ga100_mc_new },
.mmu = { 0x00000001, tu102_mmu_new },
.pci = { 0x00000001, gp100_pci_new },
.privring = { 0x00000001, gm200_privring_new },
.timer = { 0x00000001, gk20a_timer_new },
.top = { 0x00000001, ga100_top_new },
.disp = { 0x00000001, ga102_disp_new },
.dma = { 0x00000001, gv100_dma_new },
};
static int
nvkm_device_event_ctor(struct nvkm_object *object, void *data, u32 size,
struct nvkm_notify *notify)
@ -3049,6 +3069,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
case 0x168: device->chip = &nv168_chipset; break;
case 0x172: device->chip = &nv172_chipset; break;
case 0x174: device->chip = &nv174_chipset; break;
case 0x177: device->chip = &nv177_chipset; break;
default:
if (nvkm_boolopt(device->cfgopt, "NvEnableUnsupportedChipsets", false)) {
switch (device->chipset) {

Просмотреть файл

@ -397,7 +397,7 @@ nvkm_udevice_new(const struct nvkm_oclass *oclass, void *data, u32 size,
return ret;
/* give priviledged clients register access */
if (client->super)
if (args->v0.priv)
func = &nvkm_udevice_super;
else
func = &nvkm_udevice;

Просмотреть файл

@ -440,7 +440,7 @@ nvkm_dp_train(struct nvkm_dp *dp, u32 dataKBps)
return ret;
}
static void
void
nvkm_dp_disable(struct nvkm_outp *outp, struct nvkm_ior *ior)
{
struct nvkm_dp *dp = nvkm_dp(outp);

Просмотреть файл

@ -32,6 +32,7 @@ struct nvkm_dp {
int nvkm_dp_new(struct nvkm_disp *, int index, struct dcb_output *,
struct nvkm_outp **);
void nvkm_dp_disable(struct nvkm_outp *, struct nvkm_ior *);
/* DPCD Receiver Capabilities */
#define DPCD_RC00_DPCD_REV 0x00000

Просмотреть файл

@ -22,6 +22,7 @@
* Authors: Ben Skeggs
*/
#include "outp.h"
#include "dp.h"
#include "ior.h"
#include <subdev/bios.h>
@ -257,6 +258,14 @@ nvkm_outp_init_route(struct nvkm_outp *outp)
if (!ior->arm.head || ior->arm.proto != proto) {
OUTP_DBG(outp, "no heads (%x %d %d)", ior->arm.head,
ior->arm.proto, proto);
/* The EFI GOP driver on Ampere can leave unused DP links routed,
* which we don't expect. The DisableLT IED script *should* get
* us back to where we need to be.
*/
if (ior->func->route.get && !ior->arm.head && outp->info.type == DCB_OUTPUT_DP)
nvkm_dp_disable(outp, ior);
return;
}

Просмотреть файл

@ -26,7 +26,6 @@
#include <core/client.h>
#include <core/gpuobj.h>
#include <subdev/fb.h>
#include <subdev/instmem.h>
#include <nvif/cl0002.h>
#include <nvif/unpack.h>
@ -72,11 +71,7 @@ nvkm_dmaobj_ctor(const struct nvkm_dmaobj_func *func, struct nvkm_dma *dma,
union {
struct nv_dma_v0 v0;
} *args = *pdata;
struct nvkm_device *device = dma->engine.subdev.device;
struct nvkm_client *client = oclass->client;
struct nvkm_object *parent = oclass->parent;
struct nvkm_instmem *instmem = device->imem;
struct nvkm_fb *fb = device->fb;
void *data = *pdata;
u32 size = *psize;
int ret = -ENOSYS;
@ -109,23 +104,13 @@ nvkm_dmaobj_ctor(const struct nvkm_dmaobj_func *func, struct nvkm_dma *dma,
dmaobj->target = NV_MEM_TARGET_VM;
break;
case NV_DMA_V0_TARGET_VRAM:
if (!client->super) {
if (dmaobj->limit >= fb->ram->size - instmem->reserved)
return -EACCES;
if (device->card_type >= NV_50)
return -EACCES;
}
dmaobj->target = NV_MEM_TARGET_VRAM;
break;
case NV_DMA_V0_TARGET_PCI:
if (!client->super)
return -EACCES;
dmaobj->target = NV_MEM_TARGET_PCI;
break;
case NV_DMA_V0_TARGET_PCI_US:
case NV_DMA_V0_TARGET_AGP:
if (!client->super)
return -EACCES;
dmaobj->target = NV_MEM_TARGET_PCI_NOSNOOP;
break;
default:

Просмотреть файл

@ -27,8 +27,6 @@ nvkm-y += nvkm/engine/fifo/dmanv04.o
nvkm-y += nvkm/engine/fifo/dmanv10.o
nvkm-y += nvkm/engine/fifo/dmanv17.o
nvkm-y += nvkm/engine/fifo/dmanv40.o
nvkm-y += nvkm/engine/fifo/dmanv50.o
nvkm-y += nvkm/engine/fifo/dmag84.o
nvkm-y += nvkm/engine/fifo/gpfifonv50.o
nvkm-y += nvkm/engine/fifo/gpfifog84.o

Просмотреть файл

@ -48,8 +48,6 @@ void nv50_fifo_chan_object_dtor(struct nvkm_fifo_chan *, int);
int g84_fifo_chan_ctor(struct nv50_fifo *, u64 vmm, u64 push,
const struct nvkm_oclass *, struct nv50_fifo_chan *);
extern const struct nvkm_fifo_chan_oclass nv50_fifo_dma_oclass;
extern const struct nvkm_fifo_chan_oclass nv50_fifo_gpfifo_oclass;
extern const struct nvkm_fifo_chan_oclass g84_fifo_dma_oclass;
extern const struct nvkm_fifo_chan_oclass g84_fifo_gpfifo_oclass;
#endif

Просмотреть файл

@ -1,94 +0,0 @@
/*
* Copyright 2012 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
*/
#include "channv50.h"
#include <core/client.h>
#include <core/ramht.h>
#include <nvif/class.h>
#include <nvif/cl826e.h>
#include <nvif/unpack.h>
static int
g84_fifo_dma_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
void *data, u32 size, struct nvkm_object **pobject)
{
struct nvkm_object *parent = oclass->parent;
union {
struct g82_channel_dma_v0 v0;
} *args = data;
struct nv50_fifo *fifo = nv50_fifo(base);
struct nv50_fifo_chan *chan;
int ret = -ENOSYS;
nvif_ioctl(parent, "create channel dma size %d\n", size);
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(parent, "create channel dma vers %d vmm %llx "
"pushbuf %llx offset %016llx\n",
args->v0.version, args->v0.vmm, args->v0.pushbuf,
args->v0.offset);
if (!args->v0.pushbuf)
return -EINVAL;
} else
return ret;
if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL)))
return -ENOMEM;
*pobject = &chan->base.object;
ret = g84_fifo_chan_ctor(fifo, args->v0.vmm, args->v0.pushbuf,
oclass, chan);
if (ret)
return ret;
args->v0.chid = chan->base.chid;
nvkm_kmap(chan->ramfc);
nvkm_wo32(chan->ramfc, 0x08, lower_32_bits(args->v0.offset));
nvkm_wo32(chan->ramfc, 0x0c, upper_32_bits(args->v0.offset));
nvkm_wo32(chan->ramfc, 0x10, lower_32_bits(args->v0.offset));
nvkm_wo32(chan->ramfc, 0x14, upper_32_bits(args->v0.offset));
nvkm_wo32(chan->ramfc, 0x3c, 0x003f6078);
nvkm_wo32(chan->ramfc, 0x44, 0x01003fff);
nvkm_wo32(chan->ramfc, 0x48, chan->base.push->node->offset >> 4);
nvkm_wo32(chan->ramfc, 0x4c, 0xffffffff);
nvkm_wo32(chan->ramfc, 0x60, 0x7fffffff);
nvkm_wo32(chan->ramfc, 0x78, 0x00000000);
nvkm_wo32(chan->ramfc, 0x7c, 0x30000001);
nvkm_wo32(chan->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
(4 << 24) /* SEARCH_FULL */ |
(chan->ramht->gpuobj->node->offset >> 4));
nvkm_wo32(chan->ramfc, 0x88, chan->cache->addr >> 10);
nvkm_wo32(chan->ramfc, 0x98, chan->base.inst->addr >> 12);
nvkm_done(chan->ramfc);
return 0;
}
const struct nvkm_fifo_chan_oclass
g84_fifo_dma_oclass = {
.base.oclass = G82_CHANNEL_DMA,
.base.minver = 0,
.base.maxver = 0,
.ctor = g84_fifo_dma_new,
};

Просмотреть файл

@ -1,92 +0,0 @@
/*
* Copyright 2012 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
*/
#include "channv50.h"
#include <core/client.h>
#include <core/ramht.h>
#include <nvif/class.h>
#include <nvif/cl506e.h>
#include <nvif/unpack.h>
static int
nv50_fifo_dma_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass,
void *data, u32 size, struct nvkm_object **pobject)
{
struct nvkm_object *parent = oclass->parent;
union {
struct nv50_channel_dma_v0 v0;
} *args = data;
struct nv50_fifo *fifo = nv50_fifo(base);
struct nv50_fifo_chan *chan;
int ret = -ENOSYS;
nvif_ioctl(parent, "create channel dma size %d\n", size);
if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
nvif_ioctl(parent, "create channel dma vers %d vmm %llx "
"pushbuf %llx offset %016llx\n",
args->v0.version, args->v0.vmm, args->v0.pushbuf,
args->v0.offset);
if (!args->v0.pushbuf)
return -EINVAL;
} else
return ret;
if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL)))
return -ENOMEM;
*pobject = &chan->base.object;
ret = nv50_fifo_chan_ctor(fifo, args->v0.vmm, args->v0.pushbuf,
oclass, chan);
if (ret)
return ret;
args->v0.chid = chan->base.chid;
nvkm_kmap(chan->ramfc);
nvkm_wo32(chan->ramfc, 0x08, lower_32_bits(args->v0.offset));
nvkm_wo32(chan->ramfc, 0x0c, upper_32_bits(args->v0.offset));
nvkm_wo32(chan->ramfc, 0x10, lower_32_bits(args->v0.offset));
nvkm_wo32(chan->ramfc, 0x14, upper_32_bits(args->v0.offset));
nvkm_wo32(chan->ramfc, 0x3c, 0x003f6078);
nvkm_wo32(chan->ramfc, 0x44, 0x01003fff);
nvkm_wo32(chan->ramfc, 0x48, chan->base.push->node->offset >> 4);
nvkm_wo32(chan->ramfc, 0x4c, 0xffffffff);
nvkm_wo32(chan->ramfc, 0x60, 0x7fffffff);
nvkm_wo32(chan->ramfc, 0x78, 0x00000000);
nvkm_wo32(chan->ramfc, 0x7c, 0x30000001);
nvkm_wo32(chan->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
(4 << 24) /* SEARCH_FULL */ |
(chan->ramht->gpuobj->node->offset >> 4));
nvkm_done(chan->ramfc);
return 0;
}
const struct nvkm_fifo_chan_oclass
nv50_fifo_dma_oclass = {
.base.oclass = NV50_CHANNEL_DMA,
.base.minver = 0,
.base.maxver = 0,
.ctor = nv50_fifo_dma_new,
};

Просмотреть файл

@ -119,7 +119,6 @@ g84_fifo = {
.uevent_init = g84_fifo_uevent_init,
.uevent_fini = g84_fifo_uevent_fini,
.chan = {
&g84_fifo_dma_oclass,
&g84_fifo_gpfifo_oclass,
NULL
},

Просмотреть файл

@ -341,8 +341,6 @@ gk104_fifo_gpfifo_new(struct gk104_fifo *fifo, const struct nvkm_oclass *oclass,
"runlist %016llx priv %d\n",
args->v0.version, args->v0.vmm, args->v0.ioffset,
args->v0.ilength, args->v0.runlist, args->v0.priv);
if (args->v0.priv && !oclass->client->super)
return -EINVAL;
return gk104_fifo_gpfifo_new_(fifo,
&args->v0.runlist,
&args->v0.chid,

Просмотреть файл

@ -226,8 +226,6 @@ gv100_fifo_gpfifo_new(struct gk104_fifo *fifo, const struct nvkm_oclass *oclass,
"runlist %016llx priv %d\n",
args->v0.version, args->v0.vmm, args->v0.ioffset,
args->v0.ilength, args->v0.runlist, args->v0.priv);
if (args->v0.priv && !oclass->client->super)
return -EINVAL;
return gv100_fifo_gpfifo_new_(&gv100_fifo_gpfifo, fifo,
&args->v0.runlist,
&args->v0.chid,

Просмотреть файл

@ -65,8 +65,6 @@ tu102_fifo_gpfifo_new(struct gk104_fifo *fifo, const struct nvkm_oclass *oclass,
"runlist %016llx priv %d\n",
args->v0.version, args->v0.vmm, args->v0.ioffset,
args->v0.ilength, args->v0.runlist, args->v0.priv);
if (args->v0.priv && !oclass->client->super)
return -EINVAL;
return gv100_fifo_gpfifo_new_(&tu102_fifo_gpfifo, fifo,
&args->v0.runlist,
&args->v0.chid,

Просмотреть файл

@ -136,7 +136,6 @@ nv50_fifo = {
.pause = nv04_fifo_pause,
.start = nv04_fifo_start,
.chan = {
&nv50_fifo_dma_oclass,
&nv50_fifo_gpfifo_oclass,
NULL
},

Просмотреть файл

@ -41,7 +41,7 @@ nvkm_umem_search(struct nvkm_client *client, u64 handle)
object = nvkm_object_search(client, handle, &nvkm_umem);
if (IS_ERR(object)) {
if (client->super && client != master) {
if (client != master) {
spin_lock(&master->lock);
list_for_each_entry(umem, &master->umem, head) {
if (umem->object.object == handle) {
@ -53,8 +53,7 @@ nvkm_umem_search(struct nvkm_client *client, u64 handle)
}
} else {
umem = nvkm_umem(object);
if (!umem->priv || client->super)
memory = nvkm_memory_ref(umem->memory);
memory = nvkm_memory_ref(umem->memory);
}
return memory ? memory : ERR_PTR(-ENOENT);
@ -167,7 +166,6 @@ nvkm_umem_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
nvkm_object_ctor(&nvkm_umem, oclass, &umem->object);
umem->mmu = mmu;
umem->type = mmu->type[type].type;
umem->priv = oclass->client->super;
INIT_LIST_HEAD(&umem->head);
*pobject = &umem->object;

Просмотреть файл

@ -8,7 +8,6 @@ struct nvkm_umem {
struct nvkm_object object;
struct nvkm_mmu *mmu;
u8 type:8;
bool priv:1;
bool mappable:1;
bool io:1;

Просмотреть файл

@ -34,7 +34,7 @@ nvkm_ummu_sclass(struct nvkm_object *object, int index,
{
struct nvkm_mmu *mmu = nvkm_ummu(object)->mmu;
if (mmu->func->mem.user.oclass && oclass->client->super) {
if (mmu->func->mem.user.oclass) {
if (index-- == 0) {
oclass->base = mmu->func->mem.user;
oclass->ctor = nvkm_umem_new;

Просмотреть файл

@ -45,7 +45,6 @@ nvkm_uvmm_search(struct nvkm_client *client, u64 handle)
static int
nvkm_uvmm_mthd_pfnclr(struct nvkm_uvmm *uvmm, void *argv, u32 argc)
{
struct nvkm_client *client = uvmm->object.client;
union {
struct nvif_vmm_pfnclr_v0 v0;
} *args = argv;
@ -59,9 +58,6 @@ nvkm_uvmm_mthd_pfnclr(struct nvkm_uvmm *uvmm, void *argv, u32 argc)
} else
return ret;
if (!client->super)
return -ENOENT;
if (size) {
mutex_lock(&vmm->mutex);
ret = nvkm_vmm_pfn_unmap(vmm, addr, size);
@ -74,7 +70,6 @@ nvkm_uvmm_mthd_pfnclr(struct nvkm_uvmm *uvmm, void *argv, u32 argc)
static int
nvkm_uvmm_mthd_pfnmap(struct nvkm_uvmm *uvmm, void *argv, u32 argc)
{
struct nvkm_client *client = uvmm->object.client;
union {
struct nvif_vmm_pfnmap_v0 v0;
} *args = argv;
@ -93,9 +88,6 @@ nvkm_uvmm_mthd_pfnmap(struct nvkm_uvmm *uvmm, void *argv, u32 argc)
} else
return ret;
if (!client->super)
return -ENOENT;
if (size) {
mutex_lock(&vmm->mutex);
ret = nvkm_vmm_pfn_map(vmm, page, addr, size, phys);
@ -108,7 +100,6 @@ nvkm_uvmm_mthd_pfnmap(struct nvkm_uvmm *uvmm, void *argv, u32 argc)
static int
nvkm_uvmm_mthd_unmap(struct nvkm_uvmm *uvmm, void *argv, u32 argc)
{
struct nvkm_client *client = uvmm->object.client;
union {
struct nvif_vmm_unmap_v0 v0;
} *args = argv;
@ -130,9 +121,8 @@ nvkm_uvmm_mthd_unmap(struct nvkm_uvmm *uvmm, void *argv, u32 argc)
goto done;
}
if (ret = -ENOENT, (!vma->user && !client->super) || vma->busy) {
VMM_DEBUG(vmm, "denied %016llx: %d %d %d", addr,
vma->user, !client->super, vma->busy);
if (ret = -ENOENT, vma->busy) {
VMM_DEBUG(vmm, "denied %016llx: %d", addr, vma->busy);
goto done;
}
@ -181,9 +171,8 @@ nvkm_uvmm_mthd_map(struct nvkm_uvmm *uvmm, void *argv, u32 argc)
goto fail;
}
if (ret = -ENOENT, (!vma->user && !client->super) || vma->busy) {
VMM_DEBUG(vmm, "denied %016llx: %d %d %d", addr,
vma->user, !client->super, vma->busy);
if (ret = -ENOENT, vma->busy) {
VMM_DEBUG(vmm, "denied %016llx: %d", addr, vma->busy);
goto fail;
}
@ -230,7 +219,6 @@ fail:
static int
nvkm_uvmm_mthd_put(struct nvkm_uvmm *uvmm, void *argv, u32 argc)
{
struct nvkm_client *client = uvmm->object.client;
union {
struct nvif_vmm_put_v0 v0;
} *args = argv;
@ -252,9 +240,8 @@ nvkm_uvmm_mthd_put(struct nvkm_uvmm *uvmm, void *argv, u32 argc)
goto done;
}
if (ret = -ENOENT, (!vma->user && !client->super) || vma->busy) {
VMM_DEBUG(vmm, "denied %016llx: %d %d %d", addr,
vma->user, !client->super, vma->busy);
if (ret = -ENOENT, vma->busy) {
VMM_DEBUG(vmm, "denied %016llx: %d", addr, vma->busy);
goto done;
}
@ -268,7 +255,6 @@ done:
static int
nvkm_uvmm_mthd_get(struct nvkm_uvmm *uvmm, void *argv, u32 argc)
{
struct nvkm_client *client = uvmm->object.client;
union {
struct nvif_vmm_get_v0 v0;
} *args = argv;
@ -297,7 +283,6 @@ nvkm_uvmm_mthd_get(struct nvkm_uvmm *uvmm, void *argv, u32 argc)
return ret;
args->v0.addr = vma->addr;
vma->user = !client->super;
return ret;
}

Просмотреть файл

@ -774,7 +774,6 @@ nvkm_vma_tail(struct nvkm_vma *vma, u64 tail)
new->refd = vma->refd;
new->used = vma->used;
new->part = vma->part;
new->user = vma->user;
new->busy = vma->busy;
new->mapped = vma->mapped;
list_add(&new->head, &vma->head);
@ -951,7 +950,7 @@ nvkm_vmm_node_split(struct nvkm_vmm *vmm,
static void
nvkm_vma_dump(struct nvkm_vma *vma)
{
printk(KERN_ERR "%016llx %016llx %c%c%c%c%c%c%c%c%c %p\n",
printk(KERN_ERR "%016llx %016llx %c%c%c%c%c%c%c%c %p\n",
vma->addr, (u64)vma->size,
vma->used ? '-' : 'F',
vma->mapref ? 'R' : '-',
@ -959,7 +958,6 @@ nvkm_vma_dump(struct nvkm_vma *vma)
vma->page != NVKM_VMA_PAGE_NONE ? '0' + vma->page : '-',
vma->refd != NVKM_VMA_PAGE_NONE ? '0' + vma->refd : '-',
vma->part ? 'P' : '-',
vma->user ? 'U' : '-',
vma->busy ? 'B' : '-',
vma->mapped ? 'M' : '-',
vma->memory);
@ -1024,7 +1022,6 @@ nvkm_vmm_ctor_managed(struct nvkm_vmm *vmm, u64 addr, u64 size)
vma->mapref = true;
vma->sparse = false;
vma->used = true;
vma->user = true;
nvkm_vmm_node_insert(vmm, vma);
list_add_tail(&vma->head, &vmm->list);
return 0;
@ -1615,7 +1612,6 @@ nvkm_vmm_put_locked(struct nvkm_vmm *vmm, struct nvkm_vma *vma)
vma->page = NVKM_VMA_PAGE_NONE;
vma->refd = NVKM_VMA_PAGE_NONE;
vma->used = false;
vma->user = false;
nvkm_vmm_put_region(vmm, vma);
}

Просмотреть файл

@ -534,15 +534,13 @@ int
gp100_vmm_mthd(struct nvkm_vmm *vmm,
struct nvkm_client *client, u32 mthd, void *argv, u32 argc)
{
if (client->super) {
switch (mthd) {
case GP100_VMM_VN_FAULT_REPLAY:
return gp100_vmm_fault_replay(vmm, argv, argc);
case GP100_VMM_VN_FAULT_CANCEL:
return gp100_vmm_fault_cancel(vmm, argv, argc);
default:
break;
}
switch (mthd) {
case GP100_VMM_VN_FAULT_REPLAY:
return gp100_vmm_fault_replay(vmm, argv, argc);
case GP100_VMM_VN_FAULT_CANCEL:
return gp100_vmm_fault_cancel(vmm, argv, argc);
default:
break;
}
return -EINVAL;
}

Просмотреть файл

@ -78,9 +78,7 @@ static int ttm_global_init(void)
ttm_debugfs_root = debugfs_create_dir("ttm", NULL);
if (IS_ERR(ttm_debugfs_root)) {
ret = PTR_ERR(ttm_debugfs_root);
ttm_debugfs_root = NULL;
goto out;
}
/* Limit the number of pages in the pool to about 50% of the total