mirror of https://gitee.com/openkylin/linux.git
drm-fixes for 5.2-rc5:
- fix regression on amdgpu on SI - fix edid override regression - driver fixes: amdgpu, i915, mediatek, meson, panfrost - fix writecombine for vmap in gem-shmem helper (used by panfrost) - add more panel quirks -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEb4nG6jLu8Y5XI+PfTA9ye/CYqnEFAl0D4LAACgkQTA9ye/CY qnFePw/8DymJIm8hNIJ1hF65be0XVdQiKhggw76llBDAWv/Zc5LHZxK/4QJgwbrF ounfcJOnLWHyeMaoxO8AtLFZQc+4hlm6PMV3tkou8UwYPszcTK++wbvWiYmYn5/t q7MoLUf/kd1sngzFYJHEBDmNHFo34uPInc9YJX4Ufvz5fl6uIr+Yc2gLPOZsUhig PvcKSm7sJwNgUGJq7g0qPgLFaIwRL0FMVrPltTg533OkTBcQwAmC+cJVrx5AKxmo qJYyPy0iK3YNAz2KvMf4q+c8TGk4EpkExpqLD/6bHHiglD8PKMh9C5ER7iyhlzqo vgog+dD3cjFaTn+Fo1mX5UYo/rRl6DYantySKZcdfDVJ8VUo8HALeHs6vNE47WzD jDziMVRwgXs8uYFpQJM+E+V1XmuxmsJ+H21p+Lzv0BFxHDakTnPNY7Yibclgoz+v zMJP7uQbrMthGmM7VsVsHbiMARSak9UasbHoikUuMBhYG3pJ59jFpCwKlqTGfJ3+ hKWvL5jnXpOOpLP1beJg4bpFn2seBkN1uNDllCz0gv+WBw7B8vJMBOQR4c29Oy4v fDD/scs/eG29btdLUMeA4cJQNbUNY2MC2hfde3gWJHO3V1GCFdGMfAlQh09b+qhg Q9RqiRmw4oZqAZLCmx5oa+7vf19SWjUqh36zfXOu3aTy/9nDa0Q= =4gYP -----END PGP SIGNATURE----- Merge tag 'drm-fixes-2019-06-14' of git://anongit.freedesktop.org/drm/drm Pull drm fixes from Daniel Vetter: "Nothing unsettling here, also not aware of anything serious still pending. The edid override regression fix took a bit longer since this seems to be an area with an overabundance of bad options. But the fix we have now seems like a good path forward. Next week it should be back to Dave. Summary: - fix regression on amdgpu on SI - fix edid override regression - driver fixes: amdgpu, i915, mediatek, meson, panfrost - fix writecombine for vmap in gem-shmem helper (used by panfrost) - add more panel quirks" * tag 'drm-fixes-2019-06-14' of git://anongit.freedesktop.org/drm/drm: (25 commits) drm/amdgpu: return 0 by default in amdgpu_pm_load_smu_firmware drm/amdgpu: Fix bounds checking in amdgpu_ras_is_supported() drm: add fallback override/firmware EDID modes workaround drm/edid: abstract override/firmware EDID retrieval drm/i915/perf: fix whitelist on Gen10+ drm/i915/sdvo: Implement proper HDMI audio support for SDVO drm/i915: Fix per-pixel alpha with CCS drm/i915/dmc: protect against reading random memory drm/i915/dsi: Use a fuzzy check for burst mode clock check drm/amdgpu/{uvd,vcn}: fetch ring's read_ptr after alloc drm/panfrost: Require the simple_ondemand governor drm/panfrost: make devfreq optional again drm/gem_shmem: Use a writecombine mapping for ->vaddr drm: panel-orientation-quirks: Add quirk for GPD MicroPC drm: panel-orientation-quirks: Add quirk for GPD pocket2 drm/meson: fix G12A primary plane disabling drm/meson: fix primary plane disabling drm/meson: fix G12A HDMI PLL settings for 4K60 1000/1001 variations drm/mediatek: call mtk_dsi_stop() after mtk_drm_crtc_atomic_disable() drm/mediatek: clear num_pipes when unbind driver ...
This commit is contained in:
commit
6aa7a22b97
|
@ -2492,7 +2492,7 @@ void amdgpu_pm_print_power_states(struct amdgpu_device *adev)
|
|||
|
||||
int amdgpu_pm_load_smu_firmware(struct amdgpu_device *adev, uint32_t *smu_version)
|
||||
{
|
||||
int r = -EINVAL;
|
||||
int r;
|
||||
|
||||
if (adev->powerplay.pp_funcs && adev->powerplay.pp_funcs->load_firmware) {
|
||||
r = adev->powerplay.pp_funcs->load_firmware(adev->powerplay.pp_handle);
|
||||
|
@ -2502,7 +2502,7 @@ int amdgpu_pm_load_smu_firmware(struct amdgpu_device *adev, uint32_t *smu_versio
|
|||
}
|
||||
*smu_version = adev->pm.fw_version;
|
||||
}
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int amdgpu_pm_sysfs_init(struct amdgpu_device *adev)
|
||||
|
|
|
@ -172,6 +172,8 @@ static inline int amdgpu_ras_is_supported(struct amdgpu_device *adev,
|
|||
{
|
||||
struct amdgpu_ras *ras = amdgpu_ras_get_context(adev);
|
||||
|
||||
if (block >= AMDGPU_RAS_BLOCK_COUNT)
|
||||
return 0;
|
||||
return ras && (ras->supported & (1 << block));
|
||||
}
|
||||
|
||||
|
|
|
@ -594,7 +594,7 @@ int amdgpu_vcn_dec_ring_test_ib(struct amdgpu_ring *ring, long timeout)
|
|||
int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
uint32_t rptr = amdgpu_ring_get_rptr(ring);
|
||||
uint32_t rptr;
|
||||
unsigned i;
|
||||
int r;
|
||||
|
||||
|
@ -602,6 +602,8 @@ int amdgpu_vcn_enc_ring_test_ring(struct amdgpu_ring *ring)
|
|||
if (r)
|
||||
return r;
|
||||
|
||||
rptr = amdgpu_ring_get_rptr(ring);
|
||||
|
||||
amdgpu_ring_write(ring, VCN_ENC_CMD_END);
|
||||
amdgpu_ring_commit(ring);
|
||||
|
||||
|
|
|
@ -170,13 +170,16 @@ static void uvd_v6_0_enc_ring_set_wptr(struct amdgpu_ring *ring)
|
|||
static int uvd_v6_0_enc_ring_test_ring(struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
uint32_t rptr = amdgpu_ring_get_rptr(ring);
|
||||
uint32_t rptr;
|
||||
unsigned i;
|
||||
int r;
|
||||
|
||||
r = amdgpu_ring_alloc(ring, 16);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
rptr = amdgpu_ring_get_rptr(ring);
|
||||
|
||||
amdgpu_ring_write(ring, HEVC_ENC_CMD_END);
|
||||
amdgpu_ring_commit(ring);
|
||||
|
||||
|
|
|
@ -175,7 +175,7 @@ static void uvd_v7_0_enc_ring_set_wptr(struct amdgpu_ring *ring)
|
|||
static int uvd_v7_0_enc_ring_test_ring(struct amdgpu_ring *ring)
|
||||
{
|
||||
struct amdgpu_device *adev = ring->adev;
|
||||
uint32_t rptr = amdgpu_ring_get_rptr(ring);
|
||||
uint32_t rptr;
|
||||
unsigned i;
|
||||
int r;
|
||||
|
||||
|
@ -185,6 +185,9 @@ static int uvd_v7_0_enc_ring_test_ring(struct amdgpu_ring *ring)
|
|||
r = amdgpu_ring_alloc(ring, 16);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
rptr = amdgpu_ring_get_rptr(ring);
|
||||
|
||||
amdgpu_ring_write(ring, HEVC_ENC_CMD_END);
|
||||
amdgpu_ring_commit(ring);
|
||||
|
||||
|
|
|
@ -1570,6 +1570,50 @@ static void connector_bad_edid(struct drm_connector *connector,
|
|||
}
|
||||
}
|
||||
|
||||
/* Get override or firmware EDID */
|
||||
static struct edid *drm_get_override_edid(struct drm_connector *connector)
|
||||
{
|
||||
struct edid *override = NULL;
|
||||
|
||||
if (connector->override_edid)
|
||||
override = drm_edid_duplicate(connector->edid_blob_ptr->data);
|
||||
|
||||
if (!override)
|
||||
override = drm_load_edid_firmware(connector);
|
||||
|
||||
return IS_ERR(override) ? NULL : override;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_add_override_edid_modes - add modes from override/firmware EDID
|
||||
* @connector: connector we're probing
|
||||
*
|
||||
* Add modes from the override/firmware EDID, if available. Only to be used from
|
||||
* drm_helper_probe_single_connector_modes() as a fallback for when DDC probe
|
||||
* failed during drm_get_edid() and caused the override/firmware EDID to be
|
||||
* skipped.
|
||||
*
|
||||
* Return: The number of modes added or 0 if we couldn't find any.
|
||||
*/
|
||||
int drm_add_override_edid_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct edid *override;
|
||||
int num_modes = 0;
|
||||
|
||||
override = drm_get_override_edid(connector);
|
||||
if (override) {
|
||||
drm_connector_update_edid_property(connector, override);
|
||||
num_modes = drm_add_edid_modes(connector, override);
|
||||
kfree(override);
|
||||
|
||||
DRM_DEBUG_KMS("[CONNECTOR:%d:%s] adding %d modes via fallback override/firmware EDID\n",
|
||||
connector->base.id, connector->name, num_modes);
|
||||
}
|
||||
|
||||
return num_modes;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_add_override_edid_modes);
|
||||
|
||||
/**
|
||||
* drm_do_get_edid - get EDID data using a custom EDID block read function
|
||||
* @connector: connector we're probing
|
||||
|
@ -1597,15 +1641,10 @@ struct edid *drm_do_get_edid(struct drm_connector *connector,
|
|||
{
|
||||
int i, j = 0, valid_extensions = 0;
|
||||
u8 *edid, *new;
|
||||
struct edid *override = NULL;
|
||||
struct edid *override;
|
||||
|
||||
if (connector->override_edid)
|
||||
override = drm_edid_duplicate(connector->edid_blob_ptr->data);
|
||||
|
||||
if (!override)
|
||||
override = drm_load_edid_firmware(connector);
|
||||
|
||||
if (!IS_ERR_OR_NULL(override))
|
||||
override = drm_get_override_edid(connector);
|
||||
if (override)
|
||||
return override;
|
||||
|
||||
if ((edid = kmalloc(EDID_LENGTH, GFP_KERNEL)) == NULL)
|
||||
|
|
|
@ -255,7 +255,8 @@ static void *drm_gem_shmem_vmap_locked(struct drm_gem_shmem_object *shmem)
|
|||
if (obj->import_attach)
|
||||
shmem->vaddr = dma_buf_vmap(obj->import_attach->dmabuf);
|
||||
else
|
||||
shmem->vaddr = vmap(shmem->pages, obj->size >> PAGE_SHIFT, VM_MAP, PAGE_KERNEL);
|
||||
shmem->vaddr = vmap(shmem->pages, obj->size >> PAGE_SHIFT,
|
||||
VM_MAP, pgprot_writecombine(PAGE_KERNEL));
|
||||
|
||||
if (!shmem->vaddr) {
|
||||
DRM_DEBUG_KMS("Failed to vmap pages\n");
|
||||
|
|
|
@ -42,6 +42,14 @@ static const struct drm_dmi_panel_orientation_data asus_t100ha = {
|
|||
.orientation = DRM_MODE_PANEL_ORIENTATION_LEFT_UP,
|
||||
};
|
||||
|
||||
static const struct drm_dmi_panel_orientation_data gpd_micropc = {
|
||||
.width = 720,
|
||||
.height = 1280,
|
||||
.bios_dates = (const char * const []){ "04/26/2019",
|
||||
NULL },
|
||||
.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
|
||||
};
|
||||
|
||||
static const struct drm_dmi_panel_orientation_data gpd_pocket = {
|
||||
.width = 1200,
|
||||
.height = 1920,
|
||||
|
@ -50,6 +58,14 @@ static const struct drm_dmi_panel_orientation_data gpd_pocket = {
|
|||
.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
|
||||
};
|
||||
|
||||
static const struct drm_dmi_panel_orientation_data gpd_pocket2 = {
|
||||
.width = 1200,
|
||||
.height = 1920,
|
||||
.bios_dates = (const char * const []){ "06/28/2018", "08/28/2018",
|
||||
"12/07/2018", NULL },
|
||||
.orientation = DRM_MODE_PANEL_ORIENTATION_RIGHT_UP,
|
||||
};
|
||||
|
||||
static const struct drm_dmi_panel_orientation_data gpd_win = {
|
||||
.width = 720,
|
||||
.height = 1280,
|
||||
|
@ -99,6 +115,14 @@ static const struct dmi_system_id orientation_data[] = {
|
|||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "T100HAN"),
|
||||
},
|
||||
.driver_data = (void *)&asus_t100ha,
|
||||
}, { /* GPD MicroPC (generic strings, also match on bios date) */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Default string"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
|
||||
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Default string"),
|
||||
DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
|
||||
},
|
||||
.driver_data = (void *)&gpd_micropc,
|
||||
}, { /*
|
||||
* GPD Pocket, note that the the DMI data is less generic then
|
||||
* it seems, devices with a board-vendor of "AMI Corporation"
|
||||
|
@ -112,6 +136,14 @@ static const struct dmi_system_id orientation_data[] = {
|
|||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
|
||||
},
|
||||
.driver_data = (void *)&gpd_pocket,
|
||||
}, { /* GPD Pocket 2 (generic strings, also match on bios date) */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Default string"),
|
||||
DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"),
|
||||
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "Default string"),
|
||||
DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"),
|
||||
},
|
||||
.driver_data = (void *)&gpd_pocket2,
|
||||
}, { /* GPD Win (same note on DMI match as GPD Pocket) */
|
||||
.matches = {
|
||||
DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
|
||||
|
|
|
@ -479,6 +479,13 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
|
|||
|
||||
count = (*connector_funcs->get_modes)(connector);
|
||||
|
||||
/*
|
||||
* Fallback for when DDC probe failed in drm_get_edid() and thus skipped
|
||||
* override/firmware EDID.
|
||||
*/
|
||||
if (count == 0 && connector->status == connector_status_connected)
|
||||
count = drm_add_override_edid_modes(connector);
|
||||
|
||||
if (count == 0 && connector->status == connector_status_connected)
|
||||
count = drm_add_modes_noedid(connector, 1024, 768);
|
||||
count += drm_helper_probe_add_cmdline_mode(connector);
|
||||
|
|
|
@ -3005,6 +3005,7 @@ static bool gen8_is_valid_mux_addr(struct drm_i915_private *dev_priv, u32 addr)
|
|||
static bool gen10_is_valid_mux_addr(struct drm_i915_private *dev_priv, u32 addr)
|
||||
{
|
||||
return gen8_is_valid_mux_addr(dev_priv, addr) ||
|
||||
addr == i915_mmio_reg_offset(GEN10_NOA_WRITE_HIGH) ||
|
||||
(addr >= i915_mmio_reg_offset(OA_PERFCNT3_LO) &&
|
||||
addr <= i915_mmio_reg_offset(OA_PERFCNT4_HI));
|
||||
}
|
||||
|
|
|
@ -1062,6 +1062,7 @@ static inline bool i915_mmio_reg_valid(i915_reg_t reg)
|
|||
|
||||
#define NOA_DATA _MMIO(0x986C)
|
||||
#define NOA_WRITE _MMIO(0x9888)
|
||||
#define GEN10_NOA_WRITE_HIGH _MMIO(0x9884)
|
||||
|
||||
#define _GEN7_PIPEA_DE_LOAD_SL 0x70068
|
||||
#define _GEN7_PIPEB_DE_LOAD_SL 0x71068
|
||||
|
|
|
@ -303,10 +303,17 @@ static u32 *parse_csr_fw(struct drm_i915_private *dev_priv,
|
|||
u32 dmc_offset = CSR_DEFAULT_FW_OFFSET, readcount = 0, nbytes;
|
||||
u32 i;
|
||||
u32 *dmc_payload;
|
||||
size_t fsize;
|
||||
|
||||
if (!fw)
|
||||
return NULL;
|
||||
|
||||
fsize = sizeof(struct intel_css_header) +
|
||||
sizeof(struct intel_package_header) +
|
||||
sizeof(struct intel_dmc_header);
|
||||
if (fsize > fw->size)
|
||||
goto error_truncated;
|
||||
|
||||
/* Extract CSS Header information*/
|
||||
css_header = (struct intel_css_header *)fw->data;
|
||||
if (sizeof(struct intel_css_header) !=
|
||||
|
@ -366,6 +373,9 @@ static u32 *parse_csr_fw(struct drm_i915_private *dev_priv,
|
|||
/* Convert dmc_offset into number of bytes. By default it is in dwords*/
|
||||
dmc_offset *= 4;
|
||||
readcount += dmc_offset;
|
||||
fsize += dmc_offset;
|
||||
if (fsize > fw->size)
|
||||
goto error_truncated;
|
||||
|
||||
/* Extract dmc_header information. */
|
||||
dmc_header = (struct intel_dmc_header *)&fw->data[readcount];
|
||||
|
@ -397,6 +407,10 @@ static u32 *parse_csr_fw(struct drm_i915_private *dev_priv,
|
|||
|
||||
/* fw_size is in dwords, so multiplied by 4 to convert into bytes. */
|
||||
nbytes = dmc_header->fw_size * 4;
|
||||
fsize += nbytes;
|
||||
if (fsize > fw->size)
|
||||
goto error_truncated;
|
||||
|
||||
if (nbytes > csr->max_fw_size) {
|
||||
DRM_ERROR("DMC FW too big (%u bytes)\n", nbytes);
|
||||
return NULL;
|
||||
|
@ -410,6 +424,10 @@ static u32 *parse_csr_fw(struct drm_i915_private *dev_priv,
|
|||
}
|
||||
|
||||
return memcpy(dmc_payload, &fw->data[readcount], nbytes);
|
||||
|
||||
error_truncated:
|
||||
DRM_ERROR("Truncated DMC firmware, rejecting.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void intel_csr_runtime_pm_get(struct drm_i915_private *dev_priv)
|
||||
|
|
|
@ -2432,10 +2432,14 @@ static unsigned int intel_fb_modifier_to_tiling(u64 fb_modifier)
|
|||
* main surface.
|
||||
*/
|
||||
static const struct drm_format_info ccs_formats[] = {
|
||||
{ .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
|
||||
{ .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
|
||||
{ .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
|
||||
{ .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2, .cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
|
||||
{ .format = DRM_FORMAT_XRGB8888, .depth = 24, .num_planes = 2,
|
||||
.cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
|
||||
{ .format = DRM_FORMAT_XBGR8888, .depth = 24, .num_planes = 2,
|
||||
.cpp = { 4, 1, }, .hsub = 8, .vsub = 16, },
|
||||
{ .format = DRM_FORMAT_ARGB8888, .depth = 32, .num_planes = 2,
|
||||
.cpp = { 4, 1, }, .hsub = 8, .vsub = 16, .has_alpha = true, },
|
||||
{ .format = DRM_FORMAT_ABGR8888, .depth = 32, .num_planes = 2,
|
||||
.cpp = { 4, 1, }, .hsub = 8, .vsub = 16, .has_alpha = true, },
|
||||
};
|
||||
|
||||
static const struct drm_format_info *
|
||||
|
@ -11942,7 +11946,7 @@ intel_modeset_pipe_config(struct drm_crtc *crtc,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool intel_fuzzy_clock_check(int clock1, int clock2)
|
||||
bool intel_fuzzy_clock_check(int clock1, int clock2)
|
||||
{
|
||||
int diff;
|
||||
|
||||
|
|
|
@ -1742,6 +1742,7 @@ int vlv_force_pll_on(struct drm_i915_private *dev_priv, enum pipe pipe,
|
|||
const struct dpll *dpll);
|
||||
void vlv_force_pll_off(struct drm_i915_private *dev_priv, enum pipe pipe);
|
||||
int lpt_get_iclkip(struct drm_i915_private *dev_priv);
|
||||
bool intel_fuzzy_clock_check(int clock1, int clock2);
|
||||
|
||||
/* modesetting asserts */
|
||||
void assert_panel_unlocked(struct drm_i915_private *dev_priv,
|
||||
|
|
|
@ -853,6 +853,17 @@ bool intel_dsi_vbt_init(struct intel_dsi *intel_dsi, u16 panel_id)
|
|||
if (mipi_config->target_burst_mode_freq) {
|
||||
u32 bitrate = intel_dsi_bitrate(intel_dsi);
|
||||
|
||||
/*
|
||||
* Sometimes the VBT contains a slightly lower clock,
|
||||
* then the bitrate we have calculated, in this case
|
||||
* just replace it with the calculated bitrate.
|
||||
*/
|
||||
if (mipi_config->target_burst_mode_freq < bitrate &&
|
||||
intel_fuzzy_clock_check(
|
||||
mipi_config->target_burst_mode_freq,
|
||||
bitrate))
|
||||
mipi_config->target_burst_mode_freq = bitrate;
|
||||
|
||||
if (mipi_config->target_burst_mode_freq < bitrate) {
|
||||
DRM_ERROR("Burst mode freq is less than computed\n");
|
||||
return false;
|
||||
|
|
|
@ -916,6 +916,13 @@ static bool intel_sdvo_set_colorimetry(struct intel_sdvo *intel_sdvo,
|
|||
return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_COLORIMETRY, &mode, 1);
|
||||
}
|
||||
|
||||
static bool intel_sdvo_set_audio_state(struct intel_sdvo *intel_sdvo,
|
||||
u8 audio_state)
|
||||
{
|
||||
return intel_sdvo_set_value(intel_sdvo, SDVO_CMD_SET_AUDIO_STAT,
|
||||
&audio_state, 1);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void intel_sdvo_dump_hdmi_buf(struct intel_sdvo *intel_sdvo)
|
||||
{
|
||||
|
@ -1487,11 +1494,6 @@ static void intel_sdvo_pre_enable(struct intel_encoder *intel_encoder,
|
|||
else
|
||||
sdvox |= SDVO_PIPE_SEL(crtc->pipe);
|
||||
|
||||
if (crtc_state->has_audio) {
|
||||
WARN_ON_ONCE(INTEL_GEN(dev_priv) < 4);
|
||||
sdvox |= SDVO_AUDIO_ENABLE;
|
||||
}
|
||||
|
||||
if (INTEL_GEN(dev_priv) >= 4) {
|
||||
/* done in crtc_mode_set as the dpll_md reg must be written early */
|
||||
} else if (IS_I945G(dev_priv) || IS_I945GM(dev_priv) ||
|
||||
|
@ -1635,8 +1637,13 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
|
|||
if (sdvox & HDMI_COLOR_RANGE_16_235)
|
||||
pipe_config->limited_color_range = true;
|
||||
|
||||
if (sdvox & SDVO_AUDIO_ENABLE)
|
||||
pipe_config->has_audio = true;
|
||||
if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_AUDIO_STAT,
|
||||
&val, 1)) {
|
||||
u8 mask = SDVO_AUDIO_ELD_VALID | SDVO_AUDIO_PRESENCE_DETECT;
|
||||
|
||||
if ((val & mask) == mask)
|
||||
pipe_config->has_audio = true;
|
||||
}
|
||||
|
||||
if (intel_sdvo_get_value(intel_sdvo, SDVO_CMD_GET_ENCODE,
|
||||
&val, 1)) {
|
||||
|
@ -1647,6 +1654,32 @@ static void intel_sdvo_get_config(struct intel_encoder *encoder,
|
|||
intel_sdvo_get_avi_infoframe(intel_sdvo, pipe_config);
|
||||
}
|
||||
|
||||
static void intel_sdvo_disable_audio(struct intel_sdvo *intel_sdvo)
|
||||
{
|
||||
intel_sdvo_set_audio_state(intel_sdvo, 0);
|
||||
}
|
||||
|
||||
static void intel_sdvo_enable_audio(struct intel_sdvo *intel_sdvo,
|
||||
const struct intel_crtc_state *crtc_state,
|
||||
const struct drm_connector_state *conn_state)
|
||||
{
|
||||
const struct drm_display_mode *adjusted_mode =
|
||||
&crtc_state->base.adjusted_mode;
|
||||
struct drm_connector *connector = conn_state->connector;
|
||||
u8 *eld = connector->eld;
|
||||
|
||||
eld[6] = drm_av_sync_delay(connector, adjusted_mode) / 2;
|
||||
|
||||
intel_sdvo_set_audio_state(intel_sdvo, 0);
|
||||
|
||||
intel_sdvo_write_infoframe(intel_sdvo, SDVO_HBUF_INDEX_ELD,
|
||||
SDVO_HBUF_TX_DISABLED,
|
||||
eld, drm_eld_size(eld));
|
||||
|
||||
intel_sdvo_set_audio_state(intel_sdvo, SDVO_AUDIO_ELD_VALID |
|
||||
SDVO_AUDIO_PRESENCE_DETECT);
|
||||
}
|
||||
|
||||
static void intel_disable_sdvo(struct intel_encoder *encoder,
|
||||
const struct intel_crtc_state *old_crtc_state,
|
||||
const struct drm_connector_state *conn_state)
|
||||
|
@ -1656,6 +1689,9 @@ static void intel_disable_sdvo(struct intel_encoder *encoder,
|
|||
struct intel_crtc *crtc = to_intel_crtc(old_crtc_state->base.crtc);
|
||||
u32 temp;
|
||||
|
||||
if (old_crtc_state->has_audio)
|
||||
intel_sdvo_disable_audio(intel_sdvo);
|
||||
|
||||
intel_sdvo_set_active_outputs(intel_sdvo, 0);
|
||||
if (0)
|
||||
intel_sdvo_set_encoder_power_state(intel_sdvo,
|
||||
|
@ -1741,6 +1777,9 @@ static void intel_enable_sdvo(struct intel_encoder *encoder,
|
|||
intel_sdvo_set_encoder_power_state(intel_sdvo,
|
||||
DRM_MODE_DPMS_ON);
|
||||
intel_sdvo_set_active_outputs(intel_sdvo, intel_sdvo->attached_output);
|
||||
|
||||
if (pipe_config->has_audio)
|
||||
intel_sdvo_enable_audio(intel_sdvo, pipe_config, conn_state);
|
||||
}
|
||||
|
||||
static enum drm_mode_status
|
||||
|
@ -2603,7 +2642,6 @@ static bool
|
|||
intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
|
||||
{
|
||||
struct drm_encoder *encoder = &intel_sdvo->base.base;
|
||||
struct drm_i915_private *dev_priv = to_i915(encoder->dev);
|
||||
struct drm_connector *connector;
|
||||
struct intel_encoder *intel_encoder = to_intel_encoder(encoder);
|
||||
struct intel_connector *intel_connector;
|
||||
|
@ -2640,9 +2678,7 @@ intel_sdvo_dvi_init(struct intel_sdvo *intel_sdvo, int device)
|
|||
encoder->encoder_type = DRM_MODE_ENCODER_TMDS;
|
||||
connector->connector_type = DRM_MODE_CONNECTOR_DVID;
|
||||
|
||||
/* gen3 doesn't do the hdmi bits in the SDVO register */
|
||||
if (INTEL_GEN(dev_priv) >= 4 &&
|
||||
intel_sdvo_is_hdmi_connector(intel_sdvo, device)) {
|
||||
if (intel_sdvo_is_hdmi_connector(intel_sdvo, device)) {
|
||||
connector->connector_type = DRM_MODE_CONNECTOR_HDMIA;
|
||||
intel_sdvo_connector->is_hdmi = true;
|
||||
}
|
||||
|
|
|
@ -707,6 +707,9 @@ struct intel_sdvo_enhancements_arg {
|
|||
#define SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER 0x90
|
||||
#define SDVO_CMD_SET_AUDIO_STAT 0x91
|
||||
#define SDVO_CMD_GET_AUDIO_STAT 0x92
|
||||
#define SDVO_AUDIO_ELD_VALID (1 << 0)
|
||||
#define SDVO_AUDIO_PRESENCE_DETECT (1 << 1)
|
||||
#define SDVO_AUDIO_CP_READY (1 << 2)
|
||||
#define SDVO_CMD_SET_HBUF_INDEX 0x93
|
||||
#define SDVO_HBUF_INDEX_ELD 0
|
||||
#define SDVO_HBUF_INDEX_AVI_IF 1
|
||||
|
|
|
@ -90,10 +90,6 @@ static void mtk_drm_finish_page_flip(struct mtk_drm_crtc *mtk_crtc)
|
|||
static void mtk_drm_crtc_destroy(struct drm_crtc *crtc)
|
||||
{
|
||||
struct mtk_drm_crtc *mtk_crtc = to_mtk_crtc(crtc);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
|
||||
clk_unprepare(mtk_crtc->ddp_comp[i]->clk);
|
||||
|
||||
mtk_disp_mutex_put(mtk_crtc->mutex);
|
||||
|
||||
|
@ -186,7 +182,7 @@ static int mtk_crtc_ddp_clk_enable(struct mtk_drm_crtc *mtk_crtc)
|
|||
|
||||
DRM_DEBUG_DRIVER("%s\n", __func__);
|
||||
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++) {
|
||||
ret = clk_enable(mtk_crtc->ddp_comp[i]->clk);
|
||||
ret = clk_prepare_enable(mtk_crtc->ddp_comp[i]->clk);
|
||||
if (ret) {
|
||||
DRM_ERROR("Failed to enable clock %d: %d\n", i, ret);
|
||||
goto err;
|
||||
|
@ -196,7 +192,7 @@ static int mtk_crtc_ddp_clk_enable(struct mtk_drm_crtc *mtk_crtc)
|
|||
return 0;
|
||||
err:
|
||||
while (--i >= 0)
|
||||
clk_disable(mtk_crtc->ddp_comp[i]->clk);
|
||||
clk_disable_unprepare(mtk_crtc->ddp_comp[i]->clk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -206,7 +202,7 @@ static void mtk_crtc_ddp_clk_disable(struct mtk_drm_crtc *mtk_crtc)
|
|||
|
||||
DRM_DEBUG_DRIVER("%s\n", __func__);
|
||||
for (i = 0; i < mtk_crtc->ddp_comp_nr; i++)
|
||||
clk_disable(mtk_crtc->ddp_comp[i]->clk);
|
||||
clk_disable_unprepare(mtk_crtc->ddp_comp[i]->clk);
|
||||
}
|
||||
|
||||
static int mtk_crtc_ddp_hw_init(struct mtk_drm_crtc *mtk_crtc)
|
||||
|
@ -577,15 +573,7 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
|
|||
if (!comp) {
|
||||
dev_err(dev, "Component %pOF not initialized\n", node);
|
||||
ret = -ENODEV;
|
||||
goto unprepare;
|
||||
}
|
||||
|
||||
ret = clk_prepare(comp->clk);
|
||||
if (ret) {
|
||||
dev_err(dev,
|
||||
"Failed to prepare clock for component %pOF: %d\n",
|
||||
node, ret);
|
||||
goto unprepare;
|
||||
return ret;
|
||||
}
|
||||
|
||||
mtk_crtc->ddp_comp[i] = comp;
|
||||
|
@ -603,23 +591,17 @@ int mtk_drm_crtc_create(struct drm_device *drm_dev,
|
|||
ret = mtk_plane_init(drm_dev, &mtk_crtc->planes[zpos],
|
||||
BIT(pipe), type);
|
||||
if (ret)
|
||||
goto unprepare;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mtk_drm_crtc_init(drm_dev, mtk_crtc, &mtk_crtc->planes[0],
|
||||
mtk_crtc->layer_nr > 1 ? &mtk_crtc->planes[1] :
|
||||
NULL, pipe);
|
||||
if (ret < 0)
|
||||
goto unprepare;
|
||||
return ret;
|
||||
drm_mode_crtc_set_gamma_size(&mtk_crtc->base, MTK_LUT_SIZE);
|
||||
drm_crtc_enable_color_mgmt(&mtk_crtc->base, 0, false, MTK_LUT_SIZE);
|
||||
priv->num_pipes++;
|
||||
|
||||
return 0;
|
||||
|
||||
unprepare:
|
||||
while (--i >= 0)
|
||||
clk_unprepare(mtk_crtc->ddp_comp[i]->clk);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -303,6 +303,7 @@ static int mtk_drm_kms_init(struct drm_device *drm)
|
|||
static void mtk_drm_kms_deinit(struct drm_device *drm)
|
||||
{
|
||||
drm_kms_helper_poll_fini(drm);
|
||||
drm_atomic_helper_shutdown(drm);
|
||||
|
||||
component_unbind_all(drm->dev, drm);
|
||||
drm_mode_config_cleanup(drm);
|
||||
|
@ -389,7 +390,9 @@ static void mtk_drm_unbind(struct device *dev)
|
|||
struct mtk_drm_private *private = dev_get_drvdata(dev);
|
||||
|
||||
drm_dev_unregister(private->drm);
|
||||
mtk_drm_kms_deinit(private->drm);
|
||||
drm_dev_put(private->drm);
|
||||
private->num_pipes = 0;
|
||||
private->drm = NULL;
|
||||
}
|
||||
|
||||
|
@ -560,13 +563,8 @@ static int mtk_drm_probe(struct platform_device *pdev)
|
|||
static int mtk_drm_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct mtk_drm_private *private = platform_get_drvdata(pdev);
|
||||
struct drm_device *drm = private->drm;
|
||||
int i;
|
||||
|
||||
drm_dev_unregister(drm);
|
||||
mtk_drm_kms_deinit(drm);
|
||||
drm_dev_put(drm);
|
||||
|
||||
component_master_del(&pdev->dev, &mtk_drm_ops);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
of_node_put(private->mutex_node);
|
||||
|
|
|
@ -136,7 +136,6 @@ static int mtk_drm_gem_object_mmap(struct drm_gem_object *obj,
|
|||
* VM_PFNMAP flag that was set by drm_gem_mmap_obj()/drm_gem_mmap().
|
||||
*/
|
||||
vma->vm_flags &= ~VM_PFNMAP;
|
||||
vma->vm_pgoff = 0;
|
||||
|
||||
ret = dma_mmap_attrs(priv->dma_dev, vma, mtk_gem->cookie,
|
||||
mtk_gem->dma_addr, obj->size, mtk_gem->dma_attrs);
|
||||
|
@ -168,6 +167,12 @@ int mtk_drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
|
|||
|
||||
obj = vma->vm_private_data;
|
||||
|
||||
/*
|
||||
* Set vm_pgoff (used as a fake buffer offset by DRM) to 0 and map the
|
||||
* whole buffer from the start.
|
||||
*/
|
||||
vma->vm_pgoff = 0;
|
||||
|
||||
return mtk_drm_gem_object_mmap(obj, vma);
|
||||
}
|
||||
|
||||
|
|
|
@ -622,6 +622,15 @@ static void mtk_dsi_poweroff(struct mtk_dsi *dsi)
|
|||
if (--dsi->refcount != 0)
|
||||
return;
|
||||
|
||||
/*
|
||||
* mtk_dsi_stop() and mtk_dsi_start() is asymmetric, since
|
||||
* mtk_dsi_stop() should be called after mtk_drm_crtc_atomic_disable(),
|
||||
* which needs irq for vblank, and mtk_dsi_stop() will disable irq.
|
||||
* mtk_dsi_start() needs to be called in mtk_output_dsi_enable(),
|
||||
* after dsi is fully set.
|
||||
*/
|
||||
mtk_dsi_stop(dsi);
|
||||
|
||||
if (!mtk_dsi_switch_to_cmd_mode(dsi, VM_DONE_INT_FLAG, 500)) {
|
||||
if (dsi->panel) {
|
||||
if (drm_panel_unprepare(dsi->panel)) {
|
||||
|
@ -688,7 +697,6 @@ static void mtk_output_dsi_disable(struct mtk_dsi *dsi)
|
|||
}
|
||||
}
|
||||
|
||||
mtk_dsi_stop(dsi);
|
||||
mtk_dsi_poweroff(dsi);
|
||||
|
||||
dsi->enabled = false;
|
||||
|
@ -836,6 +844,8 @@ static void mtk_dsi_destroy_conn_enc(struct mtk_dsi *dsi)
|
|||
/* Skip connector cleanup if creation was delegated to the bridge */
|
||||
if (dsi->conn.dev)
|
||||
drm_connector_cleanup(&dsi->conn);
|
||||
if (dsi->panel)
|
||||
drm_panel_detach(dsi->panel);
|
||||
}
|
||||
|
||||
static void mtk_dsi_ddp_start(struct mtk_ddp_comp *comp)
|
||||
|
|
|
@ -107,8 +107,6 @@ static void meson_g12a_crtc_atomic_enable(struct drm_crtc *crtc,
|
|||
priv->io_base + _REG(VPP_OUT_H_V_SIZE));
|
||||
|
||||
drm_crtc_vblank_on(crtc);
|
||||
|
||||
priv->viu.osd1_enabled = true;
|
||||
}
|
||||
|
||||
static void meson_crtc_atomic_enable(struct drm_crtc *crtc,
|
||||
|
@ -137,8 +135,6 @@ static void meson_crtc_atomic_enable(struct drm_crtc *crtc,
|
|||
priv->io_base + _REG(VPP_MISC));
|
||||
|
||||
drm_crtc_vblank_on(crtc);
|
||||
|
||||
priv->viu.osd1_enabled = true;
|
||||
}
|
||||
|
||||
static void meson_g12a_crtc_atomic_disable(struct drm_crtc *crtc,
|
||||
|
@ -256,6 +252,8 @@ static void meson_g12a_crtc_enable_osd1(struct meson_drm *priv)
|
|||
writel_relaxed(priv->viu.osb_blend1_size,
|
||||
priv->io_base +
|
||||
_REG(VIU_OSD_BLEND_BLEND1_SIZE));
|
||||
writel_bits_relaxed(3 << 8, 3 << 8,
|
||||
priv->io_base + _REG(OSD1_BLEND_SRC_CTRL));
|
||||
}
|
||||
|
||||
static void meson_crtc_enable_vd1(struct meson_drm *priv)
|
||||
|
|
|
@ -305,6 +305,8 @@ static void meson_plane_atomic_update(struct drm_plane *plane,
|
|||
meson_plane->enabled = true;
|
||||
}
|
||||
|
||||
priv->viu.osd1_enabled = true;
|
||||
|
||||
spin_unlock_irqrestore(&priv->drm->event_lock, flags);
|
||||
}
|
||||
|
||||
|
@ -316,14 +318,14 @@ static void meson_plane_atomic_disable(struct drm_plane *plane,
|
|||
|
||||
/* Disable OSD1 */
|
||||
if (meson_vpu_is_compatible(priv, "amlogic,meson-g12a-vpu"))
|
||||
writel_bits_relaxed(BIT(0) | BIT(21), 0,
|
||||
priv->io_base + _REG(VIU_OSD1_CTRL_STAT));
|
||||
writel_bits_relaxed(3 << 8, 0,
|
||||
priv->io_base + _REG(OSD1_BLEND_SRC_CTRL));
|
||||
else
|
||||
writel_bits_relaxed(VPP_OSD1_POSTBLEND, 0,
|
||||
priv->io_base + _REG(VPP_MISC));
|
||||
|
||||
meson_plane->enabled = false;
|
||||
|
||||
priv->viu.osd1_enabled = false;
|
||||
}
|
||||
|
||||
static const struct drm_plane_helper_funcs meson_plane_helper_funcs = {
|
||||
|
|
|
@ -503,8 +503,17 @@ void meson_hdmi_pll_set_params(struct meson_drm *priv, unsigned int m,
|
|||
|
||||
/* G12A HDMI PLL Needs specific parameters for 5.4GHz */
|
||||
if (m >= 0xf7) {
|
||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4, 0xea68dc00);
|
||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5, 0x65771290);
|
||||
if (frac < 0x10000) {
|
||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4,
|
||||
0x6a685c00);
|
||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5,
|
||||
0x11551293);
|
||||
} else {
|
||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL4,
|
||||
0xea68dc00);
|
||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL5,
|
||||
0x65771290);
|
||||
}
|
||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL6, 0x39272000);
|
||||
regmap_write(priv->hhi, HHI_HDMI_PLL_CNTL7, 0x55540000);
|
||||
} else {
|
||||
|
|
|
@ -405,8 +405,7 @@ void meson_viu_init(struct meson_drm *priv)
|
|||
0 << 16 |
|
||||
1,
|
||||
priv->io_base + _REG(VIU_OSD_BLEND_CTRL));
|
||||
writel_relaxed(3 << 8 |
|
||||
1 << 20,
|
||||
writel_relaxed(1 << 20,
|
||||
priv->io_base + _REG(OSD1_BLEND_SRC_CTRL));
|
||||
writel_relaxed(1 << 20,
|
||||
priv->io_base + _REG(OSD2_BLEND_SRC_CTRL));
|
||||
|
|
|
@ -10,6 +10,7 @@ config DRM_PANFROST
|
|||
select IOMMU_IO_PGTABLE_LPAE
|
||||
select DRM_GEM_SHMEM_HELPER
|
||||
select PM_DEVFREQ
|
||||
select DEVFREQ_GOV_SIMPLE_ONDEMAND
|
||||
help
|
||||
DRM driver for ARM Mali Midgard (T6xx, T7xx, T8xx) and
|
||||
Bifrost (G3x, G5x, G7x) GPUs.
|
||||
|
|
|
@ -140,7 +140,9 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
|
|||
return 0;
|
||||
|
||||
ret = dev_pm_opp_of_add_table(&pfdev->pdev->dev);
|
||||
if (ret)
|
||||
if (ret == -ENODEV) /* Optional, continue without devfreq */
|
||||
return 0;
|
||||
else if (ret)
|
||||
return ret;
|
||||
|
||||
panfrost_devfreq_reset(pfdev);
|
||||
|
@ -170,6 +172,9 @@ void panfrost_devfreq_resume(struct panfrost_device *pfdev)
|
|||
{
|
||||
int i;
|
||||
|
||||
if (!pfdev->devfreq.devfreq)
|
||||
return;
|
||||
|
||||
panfrost_devfreq_reset(pfdev);
|
||||
for (i = 0; i < NUM_JOB_SLOTS; i++)
|
||||
pfdev->devfreq.slot[i].busy = false;
|
||||
|
@ -179,6 +184,9 @@ void panfrost_devfreq_resume(struct panfrost_device *pfdev)
|
|||
|
||||
void panfrost_devfreq_suspend(struct panfrost_device *pfdev)
|
||||
{
|
||||
if (!pfdev->devfreq.devfreq)
|
||||
return;
|
||||
|
||||
devfreq_suspend_device(pfdev->devfreq.devfreq);
|
||||
}
|
||||
|
||||
|
@ -188,6 +196,9 @@ static void panfrost_devfreq_update_utilization(struct panfrost_device *pfdev, i
|
|||
ktime_t now;
|
||||
ktime_t last;
|
||||
|
||||
if (!pfdev->devfreq.devfreq)
|
||||
return;
|
||||
|
||||
now = ktime_get();
|
||||
last = pfdev->devfreq.slot[slot].time_last_update;
|
||||
|
||||
|
|
|
@ -471,6 +471,7 @@ struct edid *drm_get_edid_switcheroo(struct drm_connector *connector,
|
|||
struct i2c_adapter *adapter);
|
||||
struct edid *drm_edid_duplicate(const struct edid *edid);
|
||||
int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid);
|
||||
int drm_add_override_edid_modes(struct drm_connector *connector);
|
||||
|
||||
u8 drm_match_cea_mode(const struct drm_display_mode *to_match);
|
||||
enum hdmi_picture_aspect drm_get_cea_aspect_ratio(const u8 video_code);
|
||||
|
|
Loading…
Reference in New Issue