Commit cf87f46f authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'drm-fixes-2024-05-11' of https://gitlab.freedesktop.org/drm/kernel

Pull drm fixes from Dave Airlie:
 "This should be the last set of fixes for 6.9, i915, xe and amdgpu are
  the bulk here, one of the previous nouveau fixes turned up an issue,
  so reverting it, otherwise one core and a couple of meson fixes.

  core:
   - fix connector debugging output

  i915:
   - Automate CCS Mode setting during engine resets
   - Fix audio time stamp programming for DP
   - Fix parsing backlight BDB data

  xe:
   - Fix use zero-length element array
   - Move more from system wq to ordered private wq
   - Do not ignore return for drmm_mutex_init

  amdgpu:
   - DCN 3.5 fix
   - MST DSC fixes
   - S0i3 fix
   - S4 fix
   - HDP MMIO mapping fix
   - Fix a regression in visible vram handling

  amdkfd:
   - Spatial partition fix

  meson:
   - dw-hdmi: power-up fixes
   - dw-hdmi: add badngap setting for g12

  nouveau:
   - revert SG_DEBUG fix that has a side effect"

* tag 'drm-fixes-2024-05-11' of https://gitlab.freedesktop.org/drm/kernel:
  Revert "drm/nouveau/firmware: Fix SG_DEBUG error with nvkm_firmware_ctor()"
  drm/amdgpu: Fix comparison in amdgpu_res_cpu_visible
  drm/amdkfd: don't allow mapping the MMIO HDP page with large pages
  drm/xe: Use ordered WQ for G2H handler
  drm/xe/guc: Check error code when initializing the CT mutex
  drm/xe/ads: Use flexible-array
  Revert "drm/amdkfd: Add partition id field to location_id"
  dm/amd/pm: Fix problems with reboot/shutdown for some SMU 13.0.4/13.0.11 users
  drm/amd/display: MST DSC check for older devices
  drm/amd/display: Fix idle optimization checks for multi-display and dual eDP
  drm/amd/display: Fix DSC-re-computing
  drm/amd/display: Enable urgent latency adjustments for DCN35
  drm/connector: Add \n to message about demoting connector force-probes
  drm/i915/bios: Fix parsing backlight BDB data
  drm/i915/audio: Fix audio time stamp programming for DP
  drm/i915/gt: Automate CCS Mode setting during engine resets
  drm/meson: dw-hdmi: add bandgap setting for g12
  drm/meson: dw-hdmi: power up phy on device init
parents c22c3e07 a222a647
...@@ -427,7 +427,7 @@ bool amdgpu_res_cpu_visible(struct amdgpu_device *adev, ...@@ -427,7 +427,7 @@ bool amdgpu_res_cpu_visible(struct amdgpu_device *adev,
amdgpu_res_first(res, 0, res->size, &cursor); amdgpu_res_first(res, 0, res->size, &cursor);
while (cursor.remaining) { while (cursor.remaining) {
if ((cursor.start + cursor.size) >= adev->gmc.visible_vram_size) if ((cursor.start + cursor.size) > adev->gmc.visible_vram_size)
return false; return false;
amdgpu_res_next(&cursor, cursor.size); amdgpu_res_next(&cursor, cursor.size);
} }
......
...@@ -1139,7 +1139,7 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep, ...@@ -1139,7 +1139,7 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep,
goto err_unlock; goto err_unlock;
} }
offset = dev->adev->rmmio_remap.bus_addr; offset = dev->adev->rmmio_remap.bus_addr;
if (!offset) { if (!offset || (PAGE_SIZE > 4096)) {
err = -ENOMEM; err = -ENOMEM;
goto err_unlock; goto err_unlock;
} }
...@@ -2307,7 +2307,7 @@ static int criu_restore_memory_of_gpu(struct kfd_process_device *pdd, ...@@ -2307,7 +2307,7 @@ static int criu_restore_memory_of_gpu(struct kfd_process_device *pdd,
return -EINVAL; return -EINVAL;
} }
offset = pdd->dev->adev->rmmio_remap.bus_addr; offset = pdd->dev->adev->rmmio_remap.bus_addr;
if (!offset) { if (!offset || (PAGE_SIZE > 4096)) {
pr_err("amdgpu_amdkfd_get_mmio_remap_phys_addr failed\n"); pr_err("amdgpu_amdkfd_get_mmio_remap_phys_addr failed\n");
return -ENOMEM; return -ENOMEM;
} }
...@@ -3349,6 +3349,9 @@ static int kfd_mmio_mmap(struct kfd_node *dev, struct kfd_process *process, ...@@ -3349,6 +3349,9 @@ static int kfd_mmio_mmap(struct kfd_node *dev, struct kfd_process *process,
if (vma->vm_end - vma->vm_start != PAGE_SIZE) if (vma->vm_end - vma->vm_start != PAGE_SIZE)
return -EINVAL; return -EINVAL;
if (PAGE_SIZE > 4096)
return -EINVAL;
address = dev->adev->rmmio_remap.bus_addr; address = dev->adev->rmmio_remap.bus_addr;
vm_flags_set(vma, VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE | vm_flags_set(vma, VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE |
......
...@@ -1997,9 +1997,8 @@ int kfd_topology_add_device(struct kfd_node *gpu) ...@@ -1997,9 +1997,8 @@ int kfd_topology_add_device(struct kfd_node *gpu)
HSA_CAP_ASIC_REVISION_MASK); HSA_CAP_ASIC_REVISION_MASK);
dev->node_props.location_id = pci_dev_id(gpu->adev->pdev); dev->node_props.location_id = pci_dev_id(gpu->adev->pdev);
/* On multi-partition nodes, node id = location_id[31:28] */ if (KFD_GC_VERSION(dev->gpu->kfd) == IP_VERSION(9, 4, 3))
if (gpu->kfd->num_nodes > 1) dev->node_props.location_id |= dev->gpu->node_id;
dev->node_props.location_id |= (dev->gpu->node_id << 28);
dev->node_props.domain = pci_domain_nr(gpu->adev->pdev->bus); dev->node_props.domain = pci_domain_nr(gpu->adev->pdev->bus);
dev->node_props.max_engine_clk_fcompute = dev->node_props.max_engine_clk_fcompute =
......
...@@ -1219,8 +1219,10 @@ static bool is_dsc_need_re_compute( ...@@ -1219,8 +1219,10 @@ static bool is_dsc_need_re_compute(
if (dc_link->type != dc_connection_mst_branch) if (dc_link->type != dc_connection_mst_branch)
return false; return false;
if (!(dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT || /* add a check for older MST DSC with no virtual DPCDs */
dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT)) if (needs_dsc_aux_workaround(dc_link) &&
(!(dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_SUPPORT ||
dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT)))
return false; return false;
for (i = 0; i < MAX_PIPES; i++) for (i = 0; i < MAX_PIPES; i++)
...@@ -1240,7 +1242,15 @@ static bool is_dsc_need_re_compute( ...@@ -1240,7 +1242,15 @@ static bool is_dsc_need_re_compute(
continue; continue;
aconnector = (struct amdgpu_dm_connector *) stream->dm_stream_context; aconnector = (struct amdgpu_dm_connector *) stream->dm_stream_context;
if (!aconnector) if (!aconnector || !aconnector->dsc_aux)
continue;
/*
* check if cached virtual MST DSC caps are available and DSC is supported
* as per specifications in their Virtual DPCD registers.
*/
if (!(aconnector->dc_sink->dsc_caps.dsc_dec_caps.is_dsc_supported ||
aconnector->dc_link->dpcd_caps.dsc_caps.dsc_basic_caps.fields.dsc_support.DSC_PASSTHROUGH_SUPPORT))
continue; continue;
stream_on_link[new_stream_on_link_num] = aconnector; stream_on_link[new_stream_on_link_num] = aconnector;
......
...@@ -195,9 +195,9 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_5_soc = { ...@@ -195,9 +195,9 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_5_soc = {
.dcn_downspread_percent = 0.5, .dcn_downspread_percent = 0.5,
.gpuvm_min_page_size_bytes = 4096, .gpuvm_min_page_size_bytes = 4096,
.hostvm_min_page_size_bytes = 4096, .hostvm_min_page_size_bytes = 4096,
.do_urgent_latency_adjustment = 0, .do_urgent_latency_adjustment = 1,
.urgent_latency_adjustment_fabric_clock_component_us = 0, .urgent_latency_adjustment_fabric_clock_component_us = 0,
.urgent_latency_adjustment_fabric_clock_reference_mhz = 0, .urgent_latency_adjustment_fabric_clock_reference_mhz = 3000,
}; };
void dcn35_build_wm_range_table_fpu(struct clk_mgr *clk_mgr) void dcn35_build_wm_range_table_fpu(struct clk_mgr *clk_mgr)
......
...@@ -638,22 +638,43 @@ void dcn35_power_down_on_boot(struct dc *dc) ...@@ -638,22 +638,43 @@ void dcn35_power_down_on_boot(struct dc *dc)
bool dcn35_apply_idle_power_optimizations(struct dc *dc, bool enable) bool dcn35_apply_idle_power_optimizations(struct dc *dc, bool enable)
{ {
struct dc_link *edp_links[MAX_NUM_EDP];
int i, edp_num;
if (dc->debug.dmcub_emulation) if (dc->debug.dmcub_emulation)
return true; return true;
if (enable) { if (enable) {
dc_get_edp_links(dc, edp_links, &edp_num); uint32_t num_active_edp = 0;
if (edp_num == 0 || edp_num > 1) int i;
return false;
for (i = 0; i < dc->current_state->stream_count; ++i) { for (i = 0; i < dc->current_state->stream_count; ++i) {
struct dc_stream_state *stream = dc->current_state->streams[i]; struct dc_stream_state *stream = dc->current_state->streams[i];
struct dc_link *link = stream->link;
bool is_psr = link && !link->panel_config.psr.disable_psr &&
(link->psr_settings.psr_version == DC_PSR_VERSION_1 ||
link->psr_settings.psr_version == DC_PSR_VERSION_SU_1);
bool is_replay = link && link->replay_settings.replay_feature_enabled;
/* Ignore streams that disabled. */
if (stream->dpms_off)
continue;
/* Active external displays block idle optimizations. */
if (!dc_is_embedded_signal(stream->signal))
return false;
/* If not PWRSEQ0 can't enter idle optimizations */
if (link && link->link_index != 0)
return false;
if (!stream->dpms_off && !dc_is_embedded_signal(stream->signal)) /* Check for panel power features required for idle optimizations. */
if (!is_psr && !is_replay)
return false; return false;
num_active_edp += 1;
} }
/* If more than one active eDP then disallow. */
if (num_active_edp > 1)
return false;
} }
// TODO: review other cases when idle optimization is allowed // TODO: review other cases when idle optimization is allowed
......
...@@ -226,7 +226,7 @@ static int smu_v13_0_4_system_features_control(struct smu_context *smu, bool en) ...@@ -226,7 +226,7 @@ static int smu_v13_0_4_system_features_control(struct smu_context *smu, bool en)
struct amdgpu_device *adev = smu->adev; struct amdgpu_device *adev = smu->adev;
int ret = 0; int ret = 0;
if (!en && !adev->in_s0ix) { if (!en && adev->in_s4) {
/* Adds a GFX reset as workaround just before sending the /* Adds a GFX reset as workaround just before sending the
* MP1_UNLOAD message to prevent GC/RLC/PMFW from entering * MP1_UNLOAD message to prevent GC/RLC/PMFW from entering
* an invalid state. * an invalid state.
......
...@@ -2940,7 +2940,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data, ...@@ -2940,7 +2940,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
dev->mode_config.max_width, dev->mode_config.max_width,
dev->mode_config.max_height); dev->mode_config.max_height);
else else
drm_dbg_kms(dev, "User-space requested a forced probe on [CONNECTOR:%d:%s] but is not the DRM master, demoting to read-only probe", drm_dbg_kms(dev, "User-space requested a forced probe on [CONNECTOR:%d:%s] but is not the DRM master, demoting to read-only probe\n",
connector->base.id, connector->name); connector->base.id, connector->name);
} }
......
...@@ -76,19 +76,6 @@ struct intel_audio_funcs { ...@@ -76,19 +76,6 @@ struct intel_audio_funcs {
struct intel_crtc_state *crtc_state); struct intel_crtc_state *crtc_state);
}; };
/* DP N/M table */
#define LC_810M 810000
#define LC_540M 540000
#define LC_270M 270000
#define LC_162M 162000
struct dp_aud_n_m {
int sample_rate;
int clock;
u16 m;
u16 n;
};
struct hdmi_aud_ncts { struct hdmi_aud_ncts {
int sample_rate; int sample_rate;
int clock; int clock;
...@@ -96,60 +83,6 @@ struct hdmi_aud_ncts { ...@@ -96,60 +83,6 @@ struct hdmi_aud_ncts {
int cts; int cts;
}; };
/* Values according to DP 1.4 Table 2-104 */
static const struct dp_aud_n_m dp_aud_n_m[] = {
{ 32000, LC_162M, 1024, 10125 },
{ 44100, LC_162M, 784, 5625 },
{ 48000, LC_162M, 512, 3375 },
{ 64000, LC_162M, 2048, 10125 },
{ 88200, LC_162M, 1568, 5625 },
{ 96000, LC_162M, 1024, 3375 },
{ 128000, LC_162M, 4096, 10125 },
{ 176400, LC_162M, 3136, 5625 },
{ 192000, LC_162M, 2048, 3375 },
{ 32000, LC_270M, 1024, 16875 },
{ 44100, LC_270M, 784, 9375 },
{ 48000, LC_270M, 512, 5625 },
{ 64000, LC_270M, 2048, 16875 },
{ 88200, LC_270M, 1568, 9375 },
{ 96000, LC_270M, 1024, 5625 },
{ 128000, LC_270M, 4096, 16875 },
{ 176400, LC_270M, 3136, 9375 },
{ 192000, LC_270M, 2048, 5625 },
{ 32000, LC_540M, 1024, 33750 },
{ 44100, LC_540M, 784, 18750 },
{ 48000, LC_540M, 512, 11250 },
{ 64000, LC_540M, 2048, 33750 },
{ 88200, LC_540M, 1568, 18750 },
{ 96000, LC_540M, 1024, 11250 },
{ 128000, LC_540M, 4096, 33750 },
{ 176400, LC_540M, 3136, 18750 },
{ 192000, LC_540M, 2048, 11250 },
{ 32000, LC_810M, 1024, 50625 },
{ 44100, LC_810M, 784, 28125 },
{ 48000, LC_810M, 512, 16875 },
{ 64000, LC_810M, 2048, 50625 },
{ 88200, LC_810M, 1568, 28125 },
{ 96000, LC_810M, 1024, 16875 },
{ 128000, LC_810M, 4096, 50625 },
{ 176400, LC_810M, 3136, 28125 },
{ 192000, LC_810M, 2048, 16875 },
};
static const struct dp_aud_n_m *
audio_config_dp_get_n_m(const struct intel_crtc_state *crtc_state, int rate)
{
int i;
for (i = 0; i < ARRAY_SIZE(dp_aud_n_m); i++) {
if (rate == dp_aud_n_m[i].sample_rate &&
crtc_state->port_clock == dp_aud_n_m[i].clock)
return &dp_aud_n_m[i];
}
return NULL;
}
static const struct { static const struct {
int clock; int clock;
u32 config; u32 config;
...@@ -387,47 +320,17 @@ hsw_dp_audio_config_update(struct intel_encoder *encoder, ...@@ -387,47 +320,17 @@ hsw_dp_audio_config_update(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state) const struct intel_crtc_state *crtc_state)
{ {
struct drm_i915_private *i915 = to_i915(encoder->base.dev); struct drm_i915_private *i915 = to_i915(encoder->base.dev);
struct i915_audio_component *acomp = i915->display.audio.component;
enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
enum port port = encoder->port;
const struct dp_aud_n_m *nm;
int rate;
u32 tmp;
rate = acomp ? acomp->aud_sample_rate[port] : 0;
nm = audio_config_dp_get_n_m(crtc_state, rate);
if (nm)
drm_dbg_kms(&i915->drm, "using Maud %u, Naud %u\n", nm->m,
nm->n);
else
drm_dbg_kms(&i915->drm, "using automatic Maud, Naud\n");
tmp = intel_de_read(i915, HSW_AUD_CFG(cpu_transcoder));
tmp &= ~AUD_CONFIG_N_VALUE_INDEX;
tmp &= ~AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK;
tmp &= ~AUD_CONFIG_N_PROG_ENABLE;
tmp |= AUD_CONFIG_N_VALUE_INDEX;
if (nm) { /* Enable time stamps. Let HW calculate Maud/Naud values */
tmp &= ~AUD_CONFIG_N_MASK; intel_de_rmw(i915, HSW_AUD_CFG(cpu_transcoder),
tmp |= AUD_CONFIG_N(nm->n); AUD_CONFIG_N_VALUE_INDEX |
tmp |= AUD_CONFIG_N_PROG_ENABLE; AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK |
} AUD_CONFIG_UPPER_N_MASK |
AUD_CONFIG_LOWER_N_MASK |
intel_de_write(i915, HSW_AUD_CFG(cpu_transcoder), tmp); AUD_CONFIG_N_PROG_ENABLE,
AUD_CONFIG_N_VALUE_INDEX);
tmp = intel_de_read(i915, HSW_AUD_M_CTS_ENABLE(cpu_transcoder));
tmp &= ~AUD_CONFIG_M_MASK;
tmp &= ~AUD_M_CTS_M_VALUE_INDEX;
tmp &= ~AUD_M_CTS_M_PROG_ENABLE;
if (nm) {
tmp |= nm->m;
tmp |= AUD_M_CTS_M_VALUE_INDEX;
tmp |= AUD_M_CTS_M_PROG_ENABLE;
}
intel_de_write(i915, HSW_AUD_M_CTS_ENABLE(cpu_transcoder), tmp);
} }
static void static void
......
...@@ -1042,22 +1042,11 @@ parse_lfp_backlight(struct drm_i915_private *i915, ...@@ -1042,22 +1042,11 @@ parse_lfp_backlight(struct drm_i915_private *i915,
panel->vbt.backlight.type = INTEL_BACKLIGHT_DISPLAY_DDI; panel->vbt.backlight.type = INTEL_BACKLIGHT_DISPLAY_DDI;
panel->vbt.backlight.controller = 0; panel->vbt.backlight.controller = 0;
if (i915->display.vbt.version >= 191) { if (i915->display.vbt.version >= 191) {
size_t exp_size; const struct lfp_backlight_control_method *method;
if (i915->display.vbt.version >= 236) method = &backlight_data->backlight_control[panel_type];
exp_size = sizeof(struct bdb_lfp_backlight_data); panel->vbt.backlight.type = method->type;
else if (i915->display.vbt.version >= 234) panel->vbt.backlight.controller = method->controller;
exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_234;
else
exp_size = EXP_BDB_LFP_BL_DATA_SIZE_REV_191;
if (get_blocksize(backlight_data) >= exp_size) {
const struct lfp_backlight_control_method *method;
method = &backlight_data->backlight_control[panel_type];
panel->vbt.backlight.type = method->type;
panel->vbt.backlight.controller = method->controller;
}
} }
panel->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz; panel->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz;
......
...@@ -897,11 +897,6 @@ struct lfp_brightness_level { ...@@ -897,11 +897,6 @@ struct lfp_brightness_level {
u16 reserved; u16 reserved;
} __packed; } __packed;
#define EXP_BDB_LFP_BL_DATA_SIZE_REV_191 \
offsetof(struct bdb_lfp_backlight_data, brightness_level)
#define EXP_BDB_LFP_BL_DATA_SIZE_REV_234 \
offsetof(struct bdb_lfp_backlight_data, brightness_precision_bits)
struct bdb_lfp_backlight_data { struct bdb_lfp_backlight_data {
u8 entry_size; u8 entry_size;
struct lfp_backlight_data_entry data[16]; struct lfp_backlight_data_entry data[16];
......
...@@ -8,14 +8,14 @@ ...@@ -8,14 +8,14 @@
#include "intel_gt_ccs_mode.h" #include "intel_gt_ccs_mode.h"
#include "intel_gt_regs.h" #include "intel_gt_regs.h"
void intel_gt_apply_ccs_mode(struct intel_gt *gt) unsigned int intel_gt_apply_ccs_mode(struct intel_gt *gt)
{ {
int cslice; int cslice;
u32 mode = 0; u32 mode = 0;
int first_ccs = __ffs(CCS_MASK(gt)); int first_ccs = __ffs(CCS_MASK(gt));
if (!IS_DG2(gt->i915)) if (!IS_DG2(gt->i915))
return; return 0;
/* Build the value for the fixed CCS load balancing */ /* Build the value for the fixed CCS load balancing */
for (cslice = 0; cslice < I915_MAX_CCS; cslice++) { for (cslice = 0; cslice < I915_MAX_CCS; cslice++) {
...@@ -35,5 +35,5 @@ void intel_gt_apply_ccs_mode(struct intel_gt *gt) ...@@ -35,5 +35,5 @@ void intel_gt_apply_ccs_mode(struct intel_gt *gt)
XEHP_CCS_MODE_CSLICE_MASK); XEHP_CCS_MODE_CSLICE_MASK);
} }
intel_uncore_write(gt->uncore, XEHP_CCS_MODE, mode); return mode;
} }
...@@ -8,6 +8,6 @@ ...@@ -8,6 +8,6 @@
struct intel_gt; struct intel_gt;
void intel_gt_apply_ccs_mode(struct intel_gt *gt); unsigned int intel_gt_apply_ccs_mode(struct intel_gt *gt);
#endif /* __INTEL_GT_CCS_MODE_H__ */ #endif /* __INTEL_GT_CCS_MODE_H__ */
...@@ -2859,6 +2859,7 @@ add_render_compute_tuning_settings(struct intel_gt *gt, ...@@ -2859,6 +2859,7 @@ add_render_compute_tuning_settings(struct intel_gt *gt,
static void ccs_engine_wa_mode(struct intel_engine_cs *engine, struct i915_wa_list *wal) static void ccs_engine_wa_mode(struct intel_engine_cs *engine, struct i915_wa_list *wal)
{ {
struct intel_gt *gt = engine->gt; struct intel_gt *gt = engine->gt;
u32 mode;
if (!IS_DG2(gt->i915)) if (!IS_DG2(gt->i915))
return; return;
...@@ -2875,7 +2876,8 @@ static void ccs_engine_wa_mode(struct intel_engine_cs *engine, struct i915_wa_li ...@@ -2875,7 +2876,8 @@ static void ccs_engine_wa_mode(struct intel_engine_cs *engine, struct i915_wa_li
* After having disabled automatic load balancing we need to * After having disabled automatic load balancing we need to
* assign all slices to a single CCS. We will call it CCS mode 1 * assign all slices to a single CCS. We will call it CCS mode 1
*/ */
intel_gt_apply_ccs_mode(gt); mode = intel_gt_apply_ccs_mode(gt);
wa_masked_en(wal, XEHP_CCS_MODE, mode);
} }
/* /*
......
...@@ -106,6 +106,8 @@ ...@@ -106,6 +106,8 @@
#define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 */ #define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 */
#define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 */ #define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 */
#define HHI_HDMI_PHY_CNTL1 0x3a4 /* 0xe9 */ #define HHI_HDMI_PHY_CNTL1 0x3a4 /* 0xe9 */
#define PHY_CNTL1_INIT 0x03900000
#define PHY_INVERT BIT(17)
#define HHI_HDMI_PHY_CNTL2 0x3a8 /* 0xea */ #define HHI_HDMI_PHY_CNTL2 0x3a8 /* 0xea */
#define HHI_HDMI_PHY_CNTL3 0x3ac /* 0xeb */ #define HHI_HDMI_PHY_CNTL3 0x3ac /* 0xeb */
#define HHI_HDMI_PHY_CNTL4 0x3b0 /* 0xec */ #define HHI_HDMI_PHY_CNTL4 0x3b0 /* 0xec */
...@@ -130,6 +132,8 @@ struct meson_dw_hdmi_data { ...@@ -130,6 +132,8 @@ struct meson_dw_hdmi_data {
unsigned int addr); unsigned int addr);
void (*dwc_write)(struct meson_dw_hdmi *dw_hdmi, void (*dwc_write)(struct meson_dw_hdmi *dw_hdmi,
unsigned int addr, unsigned int data); unsigned int addr, unsigned int data);
u32 cntl0_init;
u32 cntl1_init;
}; };
struct meson_dw_hdmi { struct meson_dw_hdmi {
...@@ -384,26 +388,6 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, ...@@ -384,26 +388,6 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
dw_hdmi_bus_fmt_is_420(hdmi)) dw_hdmi_bus_fmt_is_420(hdmi))
mode_is_420 = true; mode_is_420 = true;
/* Enable clocks */
regmap_update_bits(priv->hhi, HHI_HDMI_CLK_CNTL, 0xffff, 0x100);
/* Bring HDMITX MEM output of power down */
regmap_update_bits(priv->hhi, HHI_MEM_PD_REG0, 0xff << 8, 0);
/* Bring out of reset */
dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_SW_RESET, 0);
/* Enable internal pixclk, tmds_clk, spdif_clk, i2s_clk, cecclk */
dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL,
0x3, 0x3);
/* Enable cec_clk and hdcp22_tmdsclk_en */
dw_hdmi_top_write_bits(dw_hdmi, HDMITX_TOP_CLK_CNTL,
0x3 << 4, 0x3 << 4);
/* Enable normal output to PHY */
dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12));
/* TMDS pattern setup */ /* TMDS pattern setup */
if (mode->clock > 340000 && !mode_is_420) { if (mode->clock > 340000 && !mode_is_420) {
dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01, dw_hdmi->data->top_write(dw_hdmi, HDMITX_TOP_TMDS_CLK_PTTN_01,
...@@ -425,20 +409,6 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data, ...@@ -425,20 +409,6 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
/* Setup PHY parameters */ /* Setup PHY parameters */
meson_hdmi_phy_setup_mode(dw_hdmi, mode, mode_is_420); meson_hdmi_phy_setup_mode(dw_hdmi, mode, mode_is_420);
/* Setup PHY */
regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1,
0xffff << 16, 0x0390 << 16);
/* BIT_INVERT */
if (dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxl-dw-hdmi") ||
dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-gxm-dw-hdmi") ||
dw_hdmi_is_compatible(dw_hdmi, "amlogic,meson-g12a-dw-hdmi"))
regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1,
BIT(17), 0);
else
regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1,
BIT(17), BIT(17));
/* Disable clock, fifo, fifo_wr */ /* Disable clock, fifo, fifo_wr */
regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0); regmap_update_bits(priv->hhi, HHI_HDMI_PHY_CNTL1, 0xf, 0);
...@@ -492,7 +462,9 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi, ...@@ -492,7 +462,9 @@ static void dw_hdmi_phy_disable(struct dw_hdmi *hdmi,
DRM_DEBUG_DRIVER("\n"); DRM_DEBUG_DRIVER("\n");
regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, 0); /* Fallback to init mode */
regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL1, dw_hdmi->data->cntl1_init);
regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, dw_hdmi->data->cntl0_init);
} }
static enum drm_connector_status dw_hdmi_read_hpd(struct dw_hdmi *hdmi, static enum drm_connector_status dw_hdmi_read_hpd(struct dw_hdmi *hdmi,
...@@ -610,11 +582,22 @@ static const struct regmap_config meson_dw_hdmi_regmap_config = { ...@@ -610,11 +582,22 @@ static const struct regmap_config meson_dw_hdmi_regmap_config = {
.fast_io = true, .fast_io = true,
}; };
static const struct meson_dw_hdmi_data meson_dw_hdmi_gx_data = { static const struct meson_dw_hdmi_data meson_dw_hdmi_gxbb_data = {
.top_read = dw_hdmi_top_read, .top_read = dw_hdmi_top_read,
.top_write = dw_hdmi_top_write, .top_write = dw_hdmi_top_write,
.dwc_read = dw_hdmi_dwc_read, .dwc_read = dw_hdmi_dwc_read,
.dwc_write = dw_hdmi_dwc_write, .dwc_write = dw_hdmi_dwc_write,
.cntl0_init = 0x0,
.cntl1_init = PHY_CNTL1_INIT | PHY_INVERT,
};
static const struct meson_dw_hdmi_data meson_dw_hdmi_gxl_data = {
.top_read = dw_hdmi_top_read,
.top_write = dw_hdmi_top_write,
.dwc_read = dw_hdmi_dwc_read,
.dwc_write = dw_hdmi_dwc_write,
.cntl0_init = 0x0,
.cntl1_init = PHY_CNTL1_INIT,
}; };
static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = { static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = {
...@@ -622,6 +605,8 @@ static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = { ...@@ -622,6 +605,8 @@ static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = {
.top_write = dw_hdmi_g12a_top_write, .top_write = dw_hdmi_g12a_top_write,
.dwc_read = dw_hdmi_g12a_dwc_read, .dwc_read = dw_hdmi_g12a_dwc_read,
.dwc_write = dw_hdmi_g12a_dwc_write, .dwc_write = dw_hdmi_g12a_dwc_write,
.cntl0_init = 0x000b4242, /* Bandgap */
.cntl1_init = PHY_CNTL1_INIT,
}; };
static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi) static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi)
...@@ -656,6 +641,13 @@ static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi) ...@@ -656,6 +641,13 @@ static void meson_dw_hdmi_init(struct meson_dw_hdmi *meson_dw_hdmi)
meson_dw_hdmi->data->top_write(meson_dw_hdmi, meson_dw_hdmi->data->top_write(meson_dw_hdmi,
HDMITX_TOP_CLK_CNTL, 0xff); HDMITX_TOP_CLK_CNTL, 0xff);
/* Enable normal output to PHY */
meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_BIST_CNTL, BIT(12));
/* Setup PHY */
regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL1, meson_dw_hdmi->data->cntl1_init);
regmap_write(priv->hhi, HHI_HDMI_PHY_CNTL0, meson_dw_hdmi->data->cntl0_init);
/* Enable HDMI-TX Interrupt */ /* Enable HDMI-TX Interrupt */
meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_STAT_CLR, meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_STAT_CLR,
HDMITX_TOP_INTR_CORE); HDMITX_TOP_INTR_CORE);
...@@ -865,11 +857,11 @@ static const struct dev_pm_ops meson_dw_hdmi_pm_ops = { ...@@ -865,11 +857,11 @@ static const struct dev_pm_ops meson_dw_hdmi_pm_ops = {
static const struct of_device_id meson_dw_hdmi_of_table[] = { static const struct of_device_id meson_dw_hdmi_of_table[] = {
{ .compatible = "amlogic,meson-gxbb-dw-hdmi", { .compatible = "amlogic,meson-gxbb-dw-hdmi",
.data = &meson_dw_hdmi_gx_data }, .data = &meson_dw_hdmi_gxbb_data },
{ .compatible = "amlogic,meson-gxl-dw-hdmi", { .compatible = "amlogic,meson-gxl-dw-hdmi",
.data = &meson_dw_hdmi_gx_data }, .data = &meson_dw_hdmi_gxl_data },
{ .compatible = "amlogic,meson-gxm-dw-hdmi", { .compatible = "amlogic,meson-gxm-dw-hdmi",
.data = &meson_dw_hdmi_gx_data }, .data = &meson_dw_hdmi_gxl_data },
{ .compatible = "amlogic,meson-g12a-dw-hdmi", { .compatible = "amlogic,meson-g12a-dw-hdmi",
.data = &meson_dw_hdmi_g12a_data }, .data = &meson_dw_hdmi_g12a_data },
{ } { }
......
...@@ -205,9 +205,7 @@ nvkm_firmware_dtor(struct nvkm_firmware *fw) ...@@ -205,9 +205,7 @@ nvkm_firmware_dtor(struct nvkm_firmware *fw)
break; break;
case NVKM_FIRMWARE_IMG_DMA: case NVKM_FIRMWARE_IMG_DMA:
nvkm_memory_unref(&memory); nvkm_memory_unref(&memory);
dma_unmap_single(fw->device->dev, fw->phys, sg_dma_len(&fw->mem.sgl), dma_free_coherent(fw->device->dev, sg_dma_len(&fw->mem.sgl), fw->img, fw->phys);
DMA_TO_DEVICE);
kfree(fw->img);
break; break;
case NVKM_FIRMWARE_IMG_SGT: case NVKM_FIRMWARE_IMG_SGT:
nvkm_memory_unref(&memory); nvkm_memory_unref(&memory);
...@@ -237,17 +235,14 @@ nvkm_firmware_ctor(const struct nvkm_firmware_func *func, const char *name, ...@@ -237,17 +235,14 @@ nvkm_firmware_ctor(const struct nvkm_firmware_func *func, const char *name,
fw->img = kmemdup(src, fw->len, GFP_KERNEL); fw->img = kmemdup(src, fw->len, GFP_KERNEL);
break; break;
case NVKM_FIRMWARE_IMG_DMA: { case NVKM_FIRMWARE_IMG_DMA: {
len = ALIGN(fw->len, PAGE_SIZE); dma_addr_t addr;
fw->img = kmalloc(len, GFP_KERNEL); len = ALIGN(fw->len, PAGE_SIZE);
if (!fw->img)
return -ENOMEM;
memcpy(fw->img, src, fw->len); fw->img = dma_alloc_coherent(fw->device->dev, len, &addr, GFP_KERNEL);
fw->phys = dma_map_single(fw->device->dev, fw->img, len, DMA_TO_DEVICE); if (fw->img) {
if (dma_mapping_error(fw->device->dev, fw->phys)) { memcpy(fw->img, src, fw->len);
kfree(fw->img); fw->phys = addr;
return -EFAULT;
} }
sg_init_one(&fw->mem.sgl, fw->img, len); sg_init_one(&fw->mem.sgl, fw->img, len);
......
...@@ -100,7 +100,7 @@ struct __guc_ads_blob { ...@@ -100,7 +100,7 @@ struct __guc_ads_blob {
struct guc_engine_usage engine_usage; struct guc_engine_usage engine_usage;
struct guc_um_init_params um_init_params; struct guc_um_init_params um_init_params;
/* From here on, location is dynamic! Refer to above diagram. */ /* From here on, location is dynamic! Refer to above diagram. */
struct guc_mmio_reg regset[0]; struct guc_mmio_reg regset[];
} __packed; } __packed;
#define ads_blob_read(ads_, field_) \ #define ads_blob_read(ads_, field_) \
......
...@@ -120,6 +120,7 @@ static void guc_ct_fini(struct drm_device *drm, void *arg) ...@@ -120,6 +120,7 @@ static void guc_ct_fini(struct drm_device *drm, void *arg)
{ {
struct xe_guc_ct *ct = arg; struct xe_guc_ct *ct = arg;
destroy_workqueue(ct->g2h_wq);
xa_destroy(&ct->fence_lookup); xa_destroy(&ct->fence_lookup);
} }
...@@ -145,13 +146,20 @@ int xe_guc_ct_init(struct xe_guc_ct *ct) ...@@ -145,13 +146,20 @@ int xe_guc_ct_init(struct xe_guc_ct *ct)
xe_assert(xe, !(guc_ct_size() % PAGE_SIZE)); xe_assert(xe, !(guc_ct_size() % PAGE_SIZE));
drmm_mutex_init(&xe->drm, &ct->lock); ct->g2h_wq = alloc_ordered_workqueue("xe-g2h-wq", 0);
if (!ct->g2h_wq)
return -ENOMEM;
spin_lock_init(&ct->fast_lock); spin_lock_init(&ct->fast_lock);
xa_init(&ct->fence_lookup); xa_init(&ct->fence_lookup);
INIT_WORK(&ct->g2h_worker, g2h_worker_func); INIT_WORK(&ct->g2h_worker, g2h_worker_func);
init_waitqueue_head(&ct->wq); init_waitqueue_head(&ct->wq);
init_waitqueue_head(&ct->g2h_fence_wq); init_waitqueue_head(&ct->g2h_fence_wq);
err = drmm_mutex_init(&xe->drm, &ct->lock);
if (err)
return err;
primelockdep(ct); primelockdep(ct);
bo = xe_managed_bo_create_pin_map(xe, tile, guc_ct_size(), bo = xe_managed_bo_create_pin_map(xe, tile, guc_ct_size(),
......
...@@ -34,7 +34,7 @@ static inline void xe_guc_ct_irq_handler(struct xe_guc_ct *ct) ...@@ -34,7 +34,7 @@ static inline void xe_guc_ct_irq_handler(struct xe_guc_ct *ct)
return; return;
wake_up_all(&ct->wq); wake_up_all(&ct->wq);
queue_work(system_unbound_wq, &ct->g2h_worker); queue_work(ct->g2h_wq, &ct->g2h_worker);
xe_guc_ct_fast_path(ct); xe_guc_ct_fast_path(ct);
} }
......
...@@ -120,6 +120,8 @@ struct xe_guc_ct { ...@@ -120,6 +120,8 @@ struct xe_guc_ct {
wait_queue_head_t wq; wait_queue_head_t wq;
/** @g2h_fence_wq: wait queue used for G2H fencing */ /** @g2h_fence_wq: wait queue used for G2H fencing */
wait_queue_head_t g2h_fence_wq; wait_queue_head_t g2h_fence_wq;
/** @g2h_wq: used to process G2H */
struct workqueue_struct *g2h_wq;
/** @msg: Message buffer */ /** @msg: Message buffer */
u32 msg[GUC_CTB_MSG_MAX_LEN]; u32 msg[GUC_CTB_MSG_MAX_LEN];
/** @fast_msg: Message buffer */ /** @fast_msg: Message buffer */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment