drm fixes for 6.9 final

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
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCAAdFiEEEKbZHaGwW9KfbeusDHTzWXnEhr4FAmY+jmwACgkQDHTzWXnE
 hr7Pxg//dN+QwBuJZKU98BQAUqeHXX1JHwa28Lk9li9H09xmZhUPQ1LeAhDkq8DA
 VX/2Y6kqFNEh9y/RViV6CkVxwnhZGwJLQL+/mydyhvU5fc1kV9t+dxEweCGcfIqa
 lqg5wUniv0r5qeC74AQswuY8usIuRE0AWb/jTZ5G+62wr0bQXjSgjFXqOmv10Gah
 rLDFlx+3eKDxOIi8NF0sMJbgEEz6Vqr4cJGSW+lTYN18FGPEitO/EPk1qwwJqXNe
 9fK/vquh2i79bI4icphaVzcnrMJYGCyiIz+oOpPJ2P7qiJL5nmAv+nzmgRcFoGdw
 66psgqL2waiwGDOzgiRu/X2rtbYy/PNm704tpgP7g2Ny1iLxqoMJzWYnOnynmK1Q
 rLMxPDjOJgC9VciEorrn6G0m4Yh0EWkfrraFTbXrySOPzvCcE8MAv12NvyltAoA9
 KxyaOntrEYI3a1GDsF5brdSONq2DkOocT1HXya/dMeIX0e2pvaZ4/LNfW96cWkVr
 wl5MlmJXlcRDZIQZ4+NLTUvcS22QV/lFSVMsRbS0ocH+CqdduyyFv2VSctk8Rh3p
 Q9LRD3iyvi7YRBMtff5HBR9c+W5uRz9DpDK7vRdVGbwE3lBEq5eJIOfTIMTP6Wd+
 cWf2cqaMBkipZqQgR9eHHH4mTclTdZiJtgUEXxj11Qe3k81/axQ=
 =Y7zz
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Linus Torvalds 2024-05-10 14:37:05 -07:00
commit cf87f46fd3
20 changed files with 122 additions and 203 deletions

View File

@ -427,7 +427,7 @@ bool amdgpu_res_cpu_visible(struct amdgpu_device *adev,
amdgpu_res_first(res, 0, res->size, &cursor);
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;
amdgpu_res_next(&cursor, cursor.size);
}

View File

@ -1139,7 +1139,7 @@ static int kfd_ioctl_alloc_memory_of_gpu(struct file *filep,
goto err_unlock;
}
offset = dev->adev->rmmio_remap.bus_addr;
if (!offset) {
if (!offset || (PAGE_SIZE > 4096)) {
err = -ENOMEM;
goto err_unlock;
}
@ -2307,7 +2307,7 @@ static int criu_restore_memory_of_gpu(struct kfd_process_device *pdd,
return -EINVAL;
}
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");
return -ENOMEM;
}
@ -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)
return -EINVAL;
if (PAGE_SIZE > 4096)
return -EINVAL;
address = dev->adev->rmmio_remap.bus_addr;
vm_flags_set(vma, VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE |

View File

@ -1997,9 +1997,8 @@ int kfd_topology_add_device(struct kfd_node *gpu)
HSA_CAP_ASIC_REVISION_MASK);
dev->node_props.location_id = pci_dev_id(gpu->adev->pdev);
/* On multi-partition nodes, node id = location_id[31:28] */
if (gpu->kfd->num_nodes > 1)
dev->node_props.location_id |= (dev->gpu->node_id << 28);
if (KFD_GC_VERSION(dev->gpu->kfd) == IP_VERSION(9, 4, 3))
dev->node_props.location_id |= dev->gpu->node_id;
dev->node_props.domain = pci_domain_nr(gpu->adev->pdev->bus);
dev->node_props.max_engine_clk_fcompute =

View File

@ -1219,8 +1219,10 @@ static bool is_dsc_need_re_compute(
if (dc_link->type != dc_connection_mst_branch)
return false;
if (!(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))
/* add a check for older MST DSC with no virtual DPCDs */
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;
for (i = 0; i < MAX_PIPES; i++)
@ -1240,7 +1242,15 @@ static bool is_dsc_need_re_compute(
continue;
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;
stream_on_link[new_stream_on_link_num] = aconnector;

View File

@ -195,9 +195,9 @@ struct _vcs_dpi_soc_bounding_box_st dcn3_5_soc = {
.dcn_downspread_percent = 0.5,
.gpuvm_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_reference_mhz = 0,
.urgent_latency_adjustment_fabric_clock_reference_mhz = 3000,
};
void dcn35_build_wm_range_table_fpu(struct clk_mgr *clk_mgr)

View File

@ -638,22 +638,43 @@ void dcn35_power_down_on_boot(struct dc *dc)
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)
return true;
if (enable) {
dc_get_edp_links(dc, edp_links, &edp_num);
if (edp_num == 0 || edp_num > 1)
return false;
uint32_t num_active_edp = 0;
int i;
for (i = 0; i < dc->current_state->stream_count; ++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;
if (!stream->dpms_off && !dc_is_embedded_signal(stream->signal))
/* 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;
/* Check for panel power features required for idle optimizations. */
if (!is_psr && !is_replay)
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

View File

@ -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;
int ret = 0;
if (!en && !adev->in_s0ix) {
if (!en && adev->in_s4) {
/* Adds a GFX reset as workaround just before sending the
* MP1_UNLOAD message to prevent GC/RLC/PMFW from entering
* an invalid state.

View File

@ -2940,7 +2940,7 @@ int drm_mode_getconnector(struct drm_device *dev, void *data,
dev->mode_config.max_width,
dev->mode_config.max_height);
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);
}

View File

@ -76,19 +76,6 @@ struct intel_audio_funcs {
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 {
int sample_rate;
int clock;
@ -96,60 +83,6 @@ struct hdmi_aud_ncts {
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 {
int clock;
u32 config;
@ -387,47 +320,17 @@ hsw_dp_audio_config_update(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state)
{
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 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");
/* Enable time stamps. Let HW calculate Maud/Naud values */
intel_de_rmw(i915, HSW_AUD_CFG(cpu_transcoder),
AUD_CONFIG_N_VALUE_INDEX |
AUD_CONFIG_PIXEL_CLOCK_HDMI_MASK |
AUD_CONFIG_UPPER_N_MASK |
AUD_CONFIG_LOWER_N_MASK |
AUD_CONFIG_N_PROG_ENABLE,
AUD_CONFIG_N_VALUE_INDEX);
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) {
tmp &= ~AUD_CONFIG_N_MASK;
tmp |= AUD_CONFIG_N(nm->n);
tmp |= AUD_CONFIG_N_PROG_ENABLE;
}
intel_de_write(i915, HSW_AUD_CFG(cpu_transcoder), tmp);
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

View File

@ -1042,22 +1042,11 @@ parse_lfp_backlight(struct drm_i915_private *i915,
panel->vbt.backlight.type = INTEL_BACKLIGHT_DISPLAY_DDI;
panel->vbt.backlight.controller = 0;
if (i915->display.vbt.version >= 191) {
size_t exp_size;
const struct lfp_backlight_control_method *method;
if (i915->display.vbt.version >= 236)
exp_size = sizeof(struct bdb_lfp_backlight_data);
else if (i915->display.vbt.version >= 234)
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;
}
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;

View File

@ -897,11 +897,6 @@ struct lfp_brightness_level {
u16 reserved;
} __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 {
u8 entry_size;
struct lfp_backlight_data_entry data[16];

View File

@ -8,14 +8,14 @@
#include "intel_gt_ccs_mode.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;
u32 mode = 0;
int first_ccs = __ffs(CCS_MASK(gt));
if (!IS_DG2(gt->i915))
return;
return 0;
/* Build the value for the fixed CCS load balancing */
for (cslice = 0; cslice < I915_MAX_CCS; cslice++) {
@ -35,5 +35,5 @@ void intel_gt_apply_ccs_mode(struct intel_gt *gt)
XEHP_CCS_MODE_CSLICE_MASK);
}
intel_uncore_write(gt->uncore, XEHP_CCS_MODE, mode);
return mode;
}

View File

@ -8,6 +8,6 @@
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__ */

View File

@ -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)
{
struct intel_gt *gt = engine->gt;
u32 mode;
if (!IS_DG2(gt->i915))
return;
@ -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
* 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);
}
/*

View File

@ -106,6 +106,8 @@
#define HHI_HDMI_CLK_CNTL 0x1cc /* 0x73 */
#define HHI_HDMI_PHY_CNTL0 0x3a0 /* 0xe8 */
#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_CNTL3 0x3ac /* 0xeb */
#define HHI_HDMI_PHY_CNTL4 0x3b0 /* 0xec */
@ -130,6 +132,8 @@ struct meson_dw_hdmi_data {
unsigned int addr);
void (*dwc_write)(struct meson_dw_hdmi *dw_hdmi,
unsigned int addr, unsigned int data);
u32 cntl0_init;
u32 cntl1_init;
};
struct meson_dw_hdmi {
@ -384,26 +388,6 @@ static int dw_hdmi_phy_init(struct dw_hdmi *hdmi, void *data,
dw_hdmi_bus_fmt_is_420(hdmi))
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 */
if (mode->clock > 340000 && !mode_is_420) {
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,
/* Setup PHY parameters */
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 */
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,
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,
@ -610,11 +582,22 @@ static const struct regmap_config meson_dw_hdmi_regmap_config = {
.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_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 | 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 = {
@ -622,6 +605,8 @@ static const struct meson_dw_hdmi_data meson_dw_hdmi_g12a_data = {
.top_write = dw_hdmi_g12a_top_write,
.dwc_read = dw_hdmi_g12a_dwc_read,
.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)
@ -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,
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 */
meson_dw_hdmi->data->top_write(meson_dw_hdmi, HDMITX_TOP_INTR_STAT_CLR,
HDMITX_TOP_INTR_CORE);
@ -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[] = {
{ .compatible = "amlogic,meson-gxbb-dw-hdmi",
.data = &meson_dw_hdmi_gx_data },
.data = &meson_dw_hdmi_gxbb_data },
{ .compatible = "amlogic,meson-gxl-dw-hdmi",
.data = &meson_dw_hdmi_gx_data },
.data = &meson_dw_hdmi_gxl_data },
{ .compatible = "amlogic,meson-gxm-dw-hdmi",
.data = &meson_dw_hdmi_gx_data },
.data = &meson_dw_hdmi_gxl_data },
{ .compatible = "amlogic,meson-g12a-dw-hdmi",
.data = &meson_dw_hdmi_g12a_data },
{ }

View File

@ -205,9 +205,7 @@ nvkm_firmware_dtor(struct nvkm_firmware *fw)
break;
case NVKM_FIRMWARE_IMG_DMA:
nvkm_memory_unref(&memory);
dma_unmap_single(fw->device->dev, fw->phys, sg_dma_len(&fw->mem.sgl),
DMA_TO_DEVICE);
kfree(fw->img);
dma_free_coherent(fw->device->dev, sg_dma_len(&fw->mem.sgl), fw->img, fw->phys);
break;
case NVKM_FIRMWARE_IMG_SGT:
nvkm_memory_unref(&memory);
@ -237,17 +235,14 @@ nvkm_firmware_ctor(const struct nvkm_firmware_func *func, const char *name,
fw->img = kmemdup(src, fw->len, GFP_KERNEL);
break;
case NVKM_FIRMWARE_IMG_DMA: {
dma_addr_t addr;
len = ALIGN(fw->len, PAGE_SIZE);
fw->img = kmalloc(len, GFP_KERNEL);
if (!fw->img)
return -ENOMEM;
memcpy(fw->img, src, fw->len);
fw->phys = dma_map_single(fw->device->dev, fw->img, len, DMA_TO_DEVICE);
if (dma_mapping_error(fw->device->dev, fw->phys)) {
kfree(fw->img);
return -EFAULT;
fw->img = dma_alloc_coherent(fw->device->dev, len, &addr, GFP_KERNEL);
if (fw->img) {
memcpy(fw->img, src, fw->len);
fw->phys = addr;
}
sg_init_one(&fw->mem.sgl, fw->img, len);

View File

@ -100,7 +100,7 @@ struct __guc_ads_blob {
struct guc_engine_usage engine_usage;
struct guc_um_init_params um_init_params;
/* From here on, location is dynamic! Refer to above diagram. */
struct guc_mmio_reg regset[0];
struct guc_mmio_reg regset[];
} __packed;
#define ads_blob_read(ads_, field_) \

View File

@ -120,6 +120,7 @@ static void guc_ct_fini(struct drm_device *drm, void *arg)
{
struct xe_guc_ct *ct = arg;
destroy_workqueue(ct->g2h_wq);
xa_destroy(&ct->fence_lookup);
}
@ -145,13 +146,20 @@ int xe_guc_ct_init(struct xe_guc_ct *ct)
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);
xa_init(&ct->fence_lookup);
INIT_WORK(&ct->g2h_worker, g2h_worker_func);
init_waitqueue_head(&ct->wq);
init_waitqueue_head(&ct->g2h_fence_wq);
err = drmm_mutex_init(&xe->drm, &ct->lock);
if (err)
return err;
primelockdep(ct);
bo = xe_managed_bo_create_pin_map(xe, tile, guc_ct_size(),

View File

@ -34,7 +34,7 @@ static inline void xe_guc_ct_irq_handler(struct xe_guc_ct *ct)
return;
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);
}

View File

@ -120,6 +120,8 @@ struct xe_guc_ct {
wait_queue_head_t wq;
/** @g2h_fence_wq: wait queue used for G2H fencing */
wait_queue_head_t g2h_fence_wq;
/** @g2h_wq: used to process G2H */
struct workqueue_struct *g2h_wq;
/** @msg: Message buffer */
u32 msg[GUC_CTB_MSG_MAX_LEN];
/** @fast_msg: Message buffer */