mirror of https://gitee.com/openkylin/linux.git
core, i915, amdgpu, imx, sun4i, ast, tegra, vmwgfx fixes.
-----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJatEGeAAoJEAx081l5xIa+I48P/1hikZ9+JzL3paYkknLVsBCg TkVxOLFDk+1vd4MtmEhiDgwR1VxETgQJv/Y6wRqBALGu/kYcyRq5S1j6B65ZLFMx sKVSmp2quGE2myJeFVQj3mi2N2duVbaNk1hbZDXDh/tvvlAfnpX2XkjR2gtKGjOM LfY4AFYggoBeMEFWBk287b/O/qk1BvVNZxyxnvpsm6HboCwOB6QFt5Du8MFafxbp lqqfXEHFVUQ8ukqphoYcrRzr3d6AGtR6HBHDC8ooVIe2QAyZftsWaxHgbyZnBExG obH/e9ssrIQBQsOky2VVxS1QesWarUwV+m3j/u4N2OvNZ7uSTKt4meHHdpihujLf H8xErUbkMMGYCgatqHCSCAFz8TNRDWutecMxSoAmpsF+6rKr4T+oKvbHiubN6rPa s4m1BA2SjSmeowNcUNeTfcKeyRFKYrCepRtlTCibLB+1Nco5oArVEXEMqti3VMvk cJW1qLpdQVyQHk7EA5lZHB5iFtPsxhOpyzjIWScdyFjTx0JcmnVxraUbnqFU8J5X aNhBz6tbfxTn1r2bTZgkW+zKpVJd6LCWleUNsKHTNcyHffz2ny4kiK8TdcUJBTkC sK26IPIY8X5lM1p3/Lytrki7+Ul+ChfyDaUcXC3VEqseznaRxzzlDhKpLohOmuAt z5VQUFYxZR6EYQ6oOo1W =4caQ -----END PGP SIGNATURE----- Merge tag 'drm-fixes-for-v4.16-rc7' of git://people.freedesktop.org/~airlied/linux Pull drm fixes from Dave Airlie: "A bunch of fixes all over the place (core, i915, amdgpu, imx, sun4i, ast, tegra, vmwgfx), nothing too serious or worrying at this stage. - one uapi fix to stop multi-planar images with getfb - Sun4i error path and clock fixes - udl driver mmap offset fix - i915 DP MST and GPU reset fixes - vmwgfx mutex and black screen fixes - imx array underflow fix and vblank fix - amdgpu: display fixes - exynos devicetree fix - ast mode fix" * tag 'drm-fixes-for-v4.16-rc7' of git://people.freedesktop.org/~airlied/linux: (29 commits) drm/ast: Fixed 1280x800 Display Issue drm: udl: Properly check framebuffer mmap offsets drm/i915: Specify which engines to reset following semaphore/event lockups drm/vmwgfx: Fix a destoy-while-held mutex problem. drm/vmwgfx: Fix black screen and device errors when running without fbdev drm: Reject getfb for multi-plane framebuffers drm/amd/display: Add one to EDID's audio channel count when passing to DC drm/amd/display: We shouldn't set format_default on plane as atomic driver drm/amd/display: Fix FMT truncation programming drm/amd/display: Allow truncation to 10 bits drm/sun4i: hdmi: Fix another error handling path in 'sun4i_hdmi_bind()' drm/sun4i: hdmi: Fix an error handling path in 'sun4i_hdmi_bind()' drm/i915/dp: Write to SET_POWER dpcd to enable MST hub. drm/amd/display: fix dereferencing possible ERR_PTR() drm/amd/display: Refine disable VGA drm/tegra: Shutdown on driver unbind drm/tegra: dsi: Don't disable regulator on ->exit() drm/tegra: dc: Detach IOMMU group from domain only once dt-bindings: exynos: Document #sound-dai-cells property of the HDMI node drm/imx: move arming of the vblank event to atomic_flush ...
This commit is contained in:
commit
9ec7ccc8f4
|
@ -16,6 +16,7 @@ Required properties:
|
|||
- ddc: phandle to the hdmi ddc node
|
||||
- phy: phandle to the hdmi phy node
|
||||
- samsung,syscon-phandle: phandle for system controller node for PMU.
|
||||
- #sound-dai-cells: should be 0.
|
||||
|
||||
Required properties for Exynos 4210, 4212, 5420 and 5433:
|
||||
- clocks: list of clock IDs from SoC clock driver.
|
||||
|
|
|
@ -2063,9 +2063,12 @@ void amdgpu_device_fini(struct amdgpu_device *adev)
|
|||
|
||||
DRM_INFO("amdgpu: finishing device.\n");
|
||||
adev->shutdown = true;
|
||||
if (adev->mode_info.mode_config_initialized)
|
||||
drm_crtc_force_disable_all(adev->ddev);
|
||||
|
||||
if (adev->mode_info.mode_config_initialized){
|
||||
if (!amdgpu_device_has_dc_support(adev))
|
||||
drm_crtc_force_disable_all(adev->ddev);
|
||||
else
|
||||
drm_atomic_helper_shutdown(adev->ddev);
|
||||
}
|
||||
amdgpu_ib_pool_fini(adev);
|
||||
amdgpu_fence_driver_fini(adev);
|
||||
amdgpu_fbdev_fini(adev);
|
||||
|
|
|
@ -3134,8 +3134,6 @@ static int amdgpu_dm_plane_init(struct amdgpu_display_manager *dm,
|
|||
|
||||
switch (aplane->base.type) {
|
||||
case DRM_PLANE_TYPE_PRIMARY:
|
||||
aplane->base.format_default = true;
|
||||
|
||||
res = drm_universal_plane_init(
|
||||
dm->adev->ddev,
|
||||
&aplane->base,
|
||||
|
@ -4794,6 +4792,9 @@ static int dm_atomic_check_plane_state_fb(struct drm_atomic_state *state,
|
|||
return -EDEADLK;
|
||||
|
||||
crtc_state = drm_atomic_get_crtc_state(plane_state->state, crtc);
|
||||
if (IS_ERR(crtc_state))
|
||||
return PTR_ERR(crtc_state);
|
||||
|
||||
if (crtc->primary == plane && crtc_state->active) {
|
||||
if (!plane_state->fb)
|
||||
return -EINVAL;
|
||||
|
|
|
@ -109,7 +109,7 @@ enum dc_edid_status dm_helpers_parse_edid_caps(
|
|||
struct cea_sad *sad = &sads[i];
|
||||
|
||||
edid_caps->audio_modes[i].format_code = sad->format;
|
||||
edid_caps->audio_modes[i].channel_count = sad->channels;
|
||||
edid_caps->audio_modes[i].channel_count = sad->channels + 1;
|
||||
edid_caps->audio_modes[i].sample_rate = sad->freq;
|
||||
edid_caps->audio_modes[i].sample_size = sad->byte2;
|
||||
}
|
||||
|
|
|
@ -496,6 +496,9 @@ struct dce_hwseq_registers {
|
|||
HWS_SF(, DOMAIN7_PG_STATUS, DOMAIN7_PGFSM_PWR_STATUS, mask_sh), \
|
||||
HWS_SF(, DC_IP_REQUEST_CNTL, IP_REQUEST_EN, mask_sh), \
|
||||
HWS_SF(, D1VGA_CONTROL, D1VGA_MODE_ENABLE, mask_sh),\
|
||||
HWS_SF(, D2VGA_CONTROL, D2VGA_MODE_ENABLE, mask_sh),\
|
||||
HWS_SF(, D3VGA_CONTROL, D3VGA_MODE_ENABLE, mask_sh),\
|
||||
HWS_SF(, D4VGA_CONTROL, D4VGA_MODE_ENABLE, mask_sh),\
|
||||
HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_ENABLE, mask_sh),\
|
||||
HWS_SF(, VGA_TEST_CONTROL, VGA_TEST_RENDER_START, mask_sh),\
|
||||
HWS_SF(, LVTMA_PWRSEQ_CNTL, LVTMA_BLON, mask_sh), \
|
||||
|
@ -591,7 +594,10 @@ struct dce_hwseq_registers {
|
|||
type DENTIST_DISPCLK_WDIVIDER; \
|
||||
type VGA_TEST_ENABLE; \
|
||||
type VGA_TEST_RENDER_START; \
|
||||
type D1VGA_MODE_ENABLE;
|
||||
type D1VGA_MODE_ENABLE; \
|
||||
type D2VGA_MODE_ENABLE; \
|
||||
type D3VGA_MODE_ENABLE; \
|
||||
type D4VGA_MODE_ENABLE;
|
||||
|
||||
struct dce_hwseq_shift {
|
||||
HWSEQ_REG_FIELD_LIST(uint8_t)
|
||||
|
|
|
@ -128,23 +128,22 @@ static void set_truncation(
|
|||
return;
|
||||
}
|
||||
/* on other format-to do */
|
||||
if (params->flags.TRUNCATE_ENABLED == 0 ||
|
||||
params->flags.TRUNCATE_DEPTH == 2)
|
||||
if (params->flags.TRUNCATE_ENABLED == 0)
|
||||
return;
|
||||
/*Set truncation depth and Enable truncation*/
|
||||
REG_UPDATE_3(FMT_BIT_DEPTH_CONTROL,
|
||||
FMT_TRUNCATE_EN, 1,
|
||||
FMT_TRUNCATE_DEPTH,
|
||||
params->flags.TRUNCATE_MODE,
|
||||
params->flags.TRUNCATE_DEPTH,
|
||||
FMT_TRUNCATE_MODE,
|
||||
params->flags.TRUNCATE_DEPTH);
|
||||
params->flags.TRUNCATE_MODE);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* set_spatial_dither
|
||||
* 1) set spatial dithering mode: pattern of seed
|
||||
* 2) set spatical dithering depth: 0 for 18bpp or 1 for 24bpp
|
||||
* 2) set spatial dithering depth: 0 for 18bpp or 1 for 24bpp
|
||||
* 3) set random seed
|
||||
* 4) set random mode
|
||||
* lfsr is reset every frame or not reset
|
||||
|
|
|
@ -238,14 +238,24 @@ static void enable_power_gating_plane(
|
|||
static void disable_vga(
|
||||
struct dce_hwseq *hws)
|
||||
{
|
||||
unsigned int in_vga_mode = 0;
|
||||
unsigned int in_vga1_mode = 0;
|
||||
unsigned int in_vga2_mode = 0;
|
||||
unsigned int in_vga3_mode = 0;
|
||||
unsigned int in_vga4_mode = 0;
|
||||
|
||||
REG_GET(D1VGA_CONTROL, D1VGA_MODE_ENABLE, &in_vga_mode);
|
||||
REG_GET(D1VGA_CONTROL, D1VGA_MODE_ENABLE, &in_vga1_mode);
|
||||
REG_GET(D2VGA_CONTROL, D2VGA_MODE_ENABLE, &in_vga2_mode);
|
||||
REG_GET(D3VGA_CONTROL, D3VGA_MODE_ENABLE, &in_vga3_mode);
|
||||
REG_GET(D4VGA_CONTROL, D4VGA_MODE_ENABLE, &in_vga4_mode);
|
||||
|
||||
if (in_vga_mode == 0)
|
||||
if (in_vga1_mode == 0 && in_vga2_mode == 0 &&
|
||||
in_vga3_mode == 0 && in_vga4_mode == 0)
|
||||
return;
|
||||
|
||||
REG_WRITE(D1VGA_CONTROL, 0);
|
||||
REG_WRITE(D2VGA_CONTROL, 0);
|
||||
REG_WRITE(D3VGA_CONTROL, 0);
|
||||
REG_WRITE(D4VGA_CONTROL, 0);
|
||||
|
||||
/* HW Engineer's Notes:
|
||||
* During switch from vga->extended, if we set the VGA_TEST_ENABLE and
|
||||
|
|
|
@ -97,7 +97,7 @@ static const struct ast_vbios_dclk_info dclk_table[] = {
|
|||
{0x67, 0x22, 0x00}, /* 0E: VCLK157_5 */
|
||||
{0x6A, 0x22, 0x00}, /* 0F: VCLK162 */
|
||||
{0x4d, 0x4c, 0x80}, /* 10: VCLK154 */
|
||||
{0xa7, 0x78, 0x80}, /* 11: VCLK83.5 */
|
||||
{0x68, 0x6f, 0x80}, /* 11: VCLK83.5 */
|
||||
{0x28, 0x49, 0x80}, /* 12: VCLK106.5 */
|
||||
{0x37, 0x49, 0x80}, /* 13: VCLK146.25 */
|
||||
{0x1f, 0x45, 0x80}, /* 14: VCLK148.5 */
|
||||
|
@ -127,7 +127,7 @@ static const struct ast_vbios_dclk_info dclk_table_ast2500[] = {
|
|||
{0x67, 0x22, 0x00}, /* 0E: VCLK157_5 */
|
||||
{0x6A, 0x22, 0x00}, /* 0F: VCLK162 */
|
||||
{0x4d, 0x4c, 0x80}, /* 10: VCLK154 */
|
||||
{0xa7, 0x78, 0x80}, /* 11: VCLK83.5 */
|
||||
{0x68, 0x6f, 0x80}, /* 11: VCLK83.5 */
|
||||
{0x28, 0x49, 0x80}, /* 12: VCLK106.5 */
|
||||
{0x37, 0x49, 0x80}, /* 13: VCLK146.25 */
|
||||
{0x1f, 0x45, 0x80}, /* 14: VCLK148.5 */
|
||||
|
|
|
@ -461,6 +461,12 @@ int drm_mode_getfb(struct drm_device *dev,
|
|||
if (!fb)
|
||||
return -ENOENT;
|
||||
|
||||
/* Multi-planar framebuffers need getfb2. */
|
||||
if (fb->format->num_planes > 1) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
r->height = fb->height;
|
||||
r->width = fb->width;
|
||||
r->depth = fb->format->depth;
|
||||
|
@ -484,6 +490,7 @@ int drm_mode_getfb(struct drm_device *dev,
|
|||
ret = -ENODEV;
|
||||
}
|
||||
|
||||
out:
|
||||
drm_framebuffer_put(fb);
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -2175,8 +2175,7 @@ static void intel_ddi_pre_enable_dp(struct intel_encoder *encoder,
|
|||
intel_prepare_dp_ddi_buffers(encoder, crtc_state);
|
||||
|
||||
intel_ddi_init_dp_buf_reg(encoder);
|
||||
if (!is_mst)
|
||||
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
|
||||
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON);
|
||||
intel_dp_start_link_train(intel_dp);
|
||||
if (port != PORT_A || INTEL_GEN(dev_priv) >= 9)
|
||||
intel_dp_stop_link_train(intel_dp);
|
||||
|
@ -2274,14 +2273,12 @@ static void intel_ddi_post_disable_dp(struct intel_encoder *encoder,
|
|||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||
struct intel_digital_port *dig_port = enc_to_dig_port(&encoder->base);
|
||||
struct intel_dp *intel_dp = &dig_port->dp;
|
||||
bool is_mst = intel_crtc_has_type(old_crtc_state, INTEL_OUTPUT_DP_MST);
|
||||
|
||||
/*
|
||||
* Power down sink before disabling the port, otherwise we end
|
||||
* up getting interrupts from the sink on detecting link loss.
|
||||
*/
|
||||
if (!is_mst)
|
||||
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
|
||||
intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
|
||||
|
||||
intel_disable_ddi_buf(encoder);
|
||||
|
||||
|
|
|
@ -246,7 +246,7 @@ engine_stuck(struct intel_engine_cs *engine, u64 acthd)
|
|||
*/
|
||||
tmp = I915_READ_CTL(engine);
|
||||
if (tmp & RING_WAIT) {
|
||||
i915_handle_error(dev_priv, 0,
|
||||
i915_handle_error(dev_priv, BIT(engine->id),
|
||||
"Kicking stuck wait on %s",
|
||||
engine->name);
|
||||
I915_WRITE_CTL(engine, tmp);
|
||||
|
@ -258,7 +258,7 @@ engine_stuck(struct intel_engine_cs *engine, u64 acthd)
|
|||
default:
|
||||
return ENGINE_DEAD;
|
||||
case 1:
|
||||
i915_handle_error(dev_priv, 0,
|
||||
i915_handle_error(dev_priv, ALL_ENGINES,
|
||||
"Kicking stuck semaphore on %s",
|
||||
engine->name);
|
||||
I915_WRITE_CTL(engine, tmp);
|
||||
|
|
|
@ -225,7 +225,11 @@ static void ipu_crtc_atomic_begin(struct drm_crtc *crtc,
|
|||
struct drm_crtc_state *old_crtc_state)
|
||||
{
|
||||
drm_crtc_vblank_on(crtc);
|
||||
}
|
||||
|
||||
static void ipu_crtc_atomic_flush(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *old_crtc_state)
|
||||
{
|
||||
spin_lock_irq(&crtc->dev->event_lock);
|
||||
if (crtc->state->event) {
|
||||
WARN_ON(drm_crtc_vblank_get(crtc));
|
||||
|
@ -293,6 +297,7 @@ static const struct drm_crtc_helper_funcs ipu_helper_funcs = {
|
|||
.mode_set_nofb = ipu_crtc_mode_set_nofb,
|
||||
.atomic_check = ipu_crtc_atomic_check,
|
||||
.atomic_begin = ipu_crtc_atomic_begin,
|
||||
.atomic_flush = ipu_crtc_atomic_flush,
|
||||
.atomic_disable = ipu_crtc_atomic_disable,
|
||||
.atomic_enable = ipu_crtc_atomic_enable,
|
||||
};
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <drm/drm_plane_helper.h>
|
||||
|
||||
#include "video/imx-ipu-v3.h"
|
||||
#include "imx-drm.h"
|
||||
#include "ipuv3-plane.h"
|
||||
|
||||
struct ipu_plane_state {
|
||||
|
@ -272,7 +273,7 @@ static void ipu_plane_destroy(struct drm_plane *plane)
|
|||
kfree(ipu_plane);
|
||||
}
|
||||
|
||||
void ipu_plane_state_reset(struct drm_plane *plane)
|
||||
static void ipu_plane_state_reset(struct drm_plane *plane)
|
||||
{
|
||||
struct ipu_plane_state *ipu_state;
|
||||
|
||||
|
@ -292,7 +293,8 @@ void ipu_plane_state_reset(struct drm_plane *plane)
|
|||
plane->state = &ipu_state->base;
|
||||
}
|
||||
|
||||
struct drm_plane_state *ipu_plane_duplicate_state(struct drm_plane *plane)
|
||||
static struct drm_plane_state *
|
||||
ipu_plane_duplicate_state(struct drm_plane *plane)
|
||||
{
|
||||
struct ipu_plane_state *state;
|
||||
|
||||
|
@ -306,8 +308,8 @@ struct drm_plane_state *ipu_plane_duplicate_state(struct drm_plane *plane)
|
|||
return &state->base;
|
||||
}
|
||||
|
||||
void ipu_plane_destroy_state(struct drm_plane *plane,
|
||||
struct drm_plane_state *state)
|
||||
static void ipu_plane_destroy_state(struct drm_plane *plane,
|
||||
struct drm_plane_state *state)
|
||||
{
|
||||
struct ipu_plane_state *ipu_state = to_ipu_plane_state(state);
|
||||
|
||||
|
|
|
@ -90,25 +90,18 @@ void radeon_connector_hotplug(struct drm_connector *connector)
|
|||
/* don't do anything if sink is not display port, i.e.,
|
||||
* passive dp->(dvi|hdmi) adaptor
|
||||
*/
|
||||
if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
|
||||
int saved_dpms = connector->dpms;
|
||||
/* Only turn off the display if it's physically disconnected */
|
||||
if (!radeon_hpd_sense(rdev, radeon_connector->hpd.hpd)) {
|
||||
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
|
||||
} else if (radeon_dp_needs_link_train(radeon_connector)) {
|
||||
/* Don't try to start link training before we
|
||||
* have the dpcd */
|
||||
if (!radeon_dp_getdpcd(radeon_connector))
|
||||
return;
|
||||
if (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_DISPLAYPORT &&
|
||||
radeon_hpd_sense(rdev, radeon_connector->hpd.hpd) &&
|
||||
radeon_dp_needs_link_train(radeon_connector)) {
|
||||
/* Don't start link training before we have the DPCD */
|
||||
if (!radeon_dp_getdpcd(radeon_connector))
|
||||
return;
|
||||
|
||||
/* set it to OFF so that drm_helper_connector_dpms()
|
||||
* won't return immediately since the current state
|
||||
* is ON at this point.
|
||||
*/
|
||||
connector->dpms = DRM_MODE_DPMS_OFF;
|
||||
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
|
||||
}
|
||||
connector->dpms = saved_dpms;
|
||||
/* Turn the connector off and back on immediately, which
|
||||
* will trigger link training
|
||||
*/
|
||||
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_OFF);
|
||||
drm_helper_connector_dpms(connector, DRM_MODE_DPMS_ON);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ static int sun4i_drv_bind(struct device *dev)
|
|||
/* drm_vblank_init calls kcalloc, which can fail */
|
||||
ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
|
||||
if (ret)
|
||||
goto free_mem_region;
|
||||
goto cleanup_mode_config;
|
||||
|
||||
drm->irq_enabled = true;
|
||||
|
||||
|
@ -139,7 +139,6 @@ static int sun4i_drv_bind(struct device *dev)
|
|||
sun4i_framebuffer_free(drm);
|
||||
cleanup_mode_config:
|
||||
drm_mode_config_cleanup(drm);
|
||||
free_mem_region:
|
||||
of_reserved_mem_device_release(dev);
|
||||
free_drm:
|
||||
drm_dev_unref(drm);
|
||||
|
|
|
@ -538,7 +538,8 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
|
|||
&sun4i_hdmi_regmap_config);
|
||||
if (IS_ERR(hdmi->regmap)) {
|
||||
dev_err(dev, "Couldn't create HDMI encoder regmap\n");
|
||||
return PTR_ERR(hdmi->regmap);
|
||||
ret = PTR_ERR(hdmi->regmap);
|
||||
goto err_disable_mod_clk;
|
||||
}
|
||||
|
||||
ret = sun4i_tmds_create(hdmi);
|
||||
|
@ -551,7 +552,8 @@ static int sun4i_hdmi_bind(struct device *dev, struct device *master,
|
|||
hdmi->ddc_parent_clk = devm_clk_get(dev, "ddc");
|
||||
if (IS_ERR(hdmi->ddc_parent_clk)) {
|
||||
dev_err(dev, "Couldn't get the HDMI DDC clock\n");
|
||||
return PTR_ERR(hdmi->ddc_parent_clk);
|
||||
ret = PTR_ERR(hdmi->ddc_parent_clk);
|
||||
goto err_disable_mod_clk;
|
||||
}
|
||||
} else {
|
||||
hdmi->ddc_parent_clk = hdmi->tmds_clk;
|
||||
|
|
|
@ -103,6 +103,7 @@ static void sun4i_tcon_channel_set_status(struct sun4i_tcon *tcon, int channel,
|
|||
|
||||
if (enabled) {
|
||||
clk_prepare_enable(clk);
|
||||
clk_rate_exclusive_get(clk);
|
||||
} else {
|
||||
clk_rate_exclusive_put(clk);
|
||||
clk_disable_unprepare(clk);
|
||||
|
@ -262,7 +263,7 @@ static void sun4i_tcon0_mode_set_common(struct sun4i_tcon *tcon,
|
|||
const struct drm_display_mode *mode)
|
||||
{
|
||||
/* Configure the dot clock */
|
||||
clk_set_rate_exclusive(tcon->dclk, mode->crtc_clock * 1000);
|
||||
clk_set_rate(tcon->dclk, mode->crtc_clock * 1000);
|
||||
|
||||
/* Set the resolution */
|
||||
regmap_write(tcon->regs, SUN4I_TCON0_BASIC0_REG,
|
||||
|
@ -423,7 +424,7 @@ static void sun4i_tcon1_mode_set(struct sun4i_tcon *tcon,
|
|||
WARN_ON(!tcon->quirks->has_channel_1);
|
||||
|
||||
/* Configure the dot clock */
|
||||
clk_set_rate_exclusive(tcon->sclk1, mode->crtc_clock * 1000);
|
||||
clk_set_rate(tcon->sclk1, mode->crtc_clock * 1000);
|
||||
|
||||
/* Adjust clock delay */
|
||||
clk_delay = sun4i_tcon_get_clk_delay(mode, 1);
|
||||
|
|
|
@ -1903,8 +1903,12 @@ static int tegra_dc_init(struct host1x_client *client)
|
|||
if (!IS_ERR(primary))
|
||||
drm_plane_cleanup(primary);
|
||||
|
||||
if (group && tegra->domain) {
|
||||
iommu_detach_group(tegra->domain, group);
|
||||
if (group && dc->domain) {
|
||||
if (group == tegra->group) {
|
||||
iommu_detach_group(dc->domain, group);
|
||||
tegra->group = NULL;
|
||||
}
|
||||
|
||||
dc->domain = NULL;
|
||||
}
|
||||
|
||||
|
@ -1913,8 +1917,10 @@ static int tegra_dc_init(struct host1x_client *client)
|
|||
|
||||
static int tegra_dc_exit(struct host1x_client *client)
|
||||
{
|
||||
struct drm_device *drm = dev_get_drvdata(client->parent);
|
||||
struct iommu_group *group = iommu_group_get(client->dev);
|
||||
struct tegra_dc *dc = host1x_client_to_dc(client);
|
||||
struct tegra_drm *tegra = drm->dev_private;
|
||||
int err;
|
||||
|
||||
devm_free_irq(dc->dev, dc->irq, dc);
|
||||
|
@ -1926,7 +1932,11 @@ static int tegra_dc_exit(struct host1x_client *client)
|
|||
}
|
||||
|
||||
if (group && dc->domain) {
|
||||
iommu_detach_group(dc->domain, group);
|
||||
if (group == tegra->group) {
|
||||
iommu_detach_group(dc->domain, group);
|
||||
tegra->group = NULL;
|
||||
}
|
||||
|
||||
dc->domain = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -250,6 +250,7 @@ static void tegra_drm_unload(struct drm_device *drm)
|
|||
|
||||
drm_kms_helper_poll_fini(drm);
|
||||
tegra_drm_fb_exit(drm);
|
||||
drm_atomic_helper_shutdown(drm);
|
||||
drm_mode_config_cleanup(drm);
|
||||
|
||||
err = host1x_device_exit(device);
|
||||
|
|
|
@ -1072,7 +1072,6 @@ static int tegra_dsi_exit(struct host1x_client *client)
|
|||
struct tegra_dsi *dsi = host1x_client_to_dsi(client);
|
||||
|
||||
tegra_output_exit(&dsi->output);
|
||||
regulator_disable(dsi->vdd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -297,6 +297,10 @@ int tegra_plane_format_get_alpha(unsigned int opaque, unsigned int *alpha)
|
|||
case WIN_COLOR_DEPTH_B8G8R8X8:
|
||||
*alpha = WIN_COLOR_DEPTH_B8G8R8A8;
|
||||
return 0;
|
||||
|
||||
case WIN_COLOR_DEPTH_B5G6R5:
|
||||
*alpha = opaque;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
|
@ -330,9 +334,6 @@ void tegra_plane_check_dependent(struct tegra_plane *tegra,
|
|||
unsigned int zpos[2];
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
state->dependent[i] = false;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
zpos[i] = 0;
|
||||
|
||||
|
@ -346,6 +347,8 @@ void tegra_plane_check_dependent(struct tegra_plane *tegra,
|
|||
|
||||
index = tegra_plane_get_overlap_index(tegra, p);
|
||||
|
||||
state->dependent[index] = false;
|
||||
|
||||
/*
|
||||
* If any of the other planes is on top of this plane and uses
|
||||
* a format with an alpha component, mark this plane as being
|
||||
|
|
|
@ -159,10 +159,15 @@ static int udl_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
|
|||
{
|
||||
unsigned long start = vma->vm_start;
|
||||
unsigned long size = vma->vm_end - vma->vm_start;
|
||||
unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
|
||||
unsigned long offset;
|
||||
unsigned long page, pos;
|
||||
|
||||
if (offset + size > info->fix.smem_len)
|
||||
if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
|
||||
return -EINVAL;
|
||||
|
||||
offset = vma->vm_pgoff << PAGE_SHIFT;
|
||||
|
||||
if (offset > info->fix.smem_len || size > info->fix.smem_len - offset)
|
||||
return -EINVAL;
|
||||
|
||||
pos = (unsigned long)info->fix.smem_start + offset;
|
||||
|
|
|
@ -1337,6 +1337,19 @@ static void __vmw_svga_disable(struct vmw_private *dev_priv)
|
|||
*/
|
||||
void vmw_svga_disable(struct vmw_private *dev_priv)
|
||||
{
|
||||
/*
|
||||
* Disabling SVGA will turn off device modesetting capabilities, so
|
||||
* notify KMS about that so that it doesn't cache atomic state that
|
||||
* isn't valid anymore, for example crtcs turned on.
|
||||
* Strictly we'd want to do this under the SVGA lock (or an SVGA mutex),
|
||||
* but vmw_kms_lost_device() takes the reservation sem and thus we'll
|
||||
* end up with lock order reversal. Thus, a master may actually perform
|
||||
* a new modeset just after we call vmw_kms_lost_device() and race with
|
||||
* vmw_svga_disable(), but that should at worst cause atomic KMS state
|
||||
* to be inconsistent with the device, causing modesetting problems.
|
||||
*
|
||||
*/
|
||||
vmw_kms_lost_device(dev_priv->dev);
|
||||
ttm_write_lock(&dev_priv->reservation_sem, false);
|
||||
spin_lock(&dev_priv->svga_lock);
|
||||
if (dev_priv->bdev.man[TTM_PL_VRAM].use_type) {
|
||||
|
|
|
@ -938,6 +938,7 @@ int vmw_kms_present(struct vmw_private *dev_priv,
|
|||
int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file_priv);
|
||||
void vmw_kms_legacy_hotspot_clear(struct vmw_private *dev_priv);
|
||||
void vmw_kms_lost_device(struct drm_device *dev);
|
||||
|
||||
int vmw_dumb_create(struct drm_file *file_priv,
|
||||
struct drm_device *dev,
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include <drm/drm_atomic_helper.h>
|
||||
#include <drm/drm_rect.h>
|
||||
|
||||
|
||||
/* Might need a hrtimer here? */
|
||||
#define VMWGFX_PRESENT_RATE ((HZ / 60 > 0) ? HZ / 60 : 1)
|
||||
|
||||
|
@ -2517,9 +2516,12 @@ void vmw_kms_helper_buffer_finish(struct vmw_private *dev_priv,
|
|||
* Helper to be used if an error forces the caller to undo the actions of
|
||||
* vmw_kms_helper_resource_prepare.
|
||||
*/
|
||||
void vmw_kms_helper_resource_revert(struct vmw_resource *res)
|
||||
void vmw_kms_helper_resource_revert(struct vmw_validation_ctx *ctx)
|
||||
{
|
||||
vmw_kms_helper_buffer_revert(res->backup);
|
||||
struct vmw_resource *res = ctx->res;
|
||||
|
||||
vmw_kms_helper_buffer_revert(ctx->buf);
|
||||
vmw_dmabuf_unreference(&ctx->buf);
|
||||
vmw_resource_unreserve(res, false, NULL, 0);
|
||||
mutex_unlock(&res->dev_priv->cmdbuf_mutex);
|
||||
}
|
||||
|
@ -2536,10 +2538,14 @@ void vmw_kms_helper_resource_revert(struct vmw_resource *res)
|
|||
* interrupted by a signal.
|
||||
*/
|
||||
int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
|
||||
bool interruptible)
|
||||
bool interruptible,
|
||||
struct vmw_validation_ctx *ctx)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
ctx->buf = NULL;
|
||||
ctx->res = res;
|
||||
|
||||
if (interruptible)
|
||||
ret = mutex_lock_interruptible(&res->dev_priv->cmdbuf_mutex);
|
||||
else
|
||||
|
@ -2558,6 +2564,8 @@ int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
|
|||
res->dev_priv->has_mob);
|
||||
if (ret)
|
||||
goto out_unreserve;
|
||||
|
||||
ctx->buf = vmw_dmabuf_reference(res->backup);
|
||||
}
|
||||
ret = vmw_resource_validate(res);
|
||||
if (ret)
|
||||
|
@ -2565,7 +2573,7 @@ int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
|
|||
return 0;
|
||||
|
||||
out_revert:
|
||||
vmw_kms_helper_buffer_revert(res->backup);
|
||||
vmw_kms_helper_buffer_revert(ctx->buf);
|
||||
out_unreserve:
|
||||
vmw_resource_unreserve(res, false, NULL, 0);
|
||||
out_unlock:
|
||||
|
@ -2581,11 +2589,13 @@ int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
|
|||
* @out_fence: Optional pointer to a fence pointer. If non-NULL, a
|
||||
* ref-counted fence pointer is returned here.
|
||||
*/
|
||||
void vmw_kms_helper_resource_finish(struct vmw_resource *res,
|
||||
struct vmw_fence_obj **out_fence)
|
||||
void vmw_kms_helper_resource_finish(struct vmw_validation_ctx *ctx,
|
||||
struct vmw_fence_obj **out_fence)
|
||||
{
|
||||
if (res->backup || out_fence)
|
||||
vmw_kms_helper_buffer_finish(res->dev_priv, NULL, res->backup,
|
||||
struct vmw_resource *res = ctx->res;
|
||||
|
||||
if (ctx->buf || out_fence)
|
||||
vmw_kms_helper_buffer_finish(res->dev_priv, NULL, ctx->buf,
|
||||
out_fence, NULL);
|
||||
|
||||
vmw_resource_unreserve(res, false, NULL, 0);
|
||||
|
@ -2851,3 +2861,14 @@ int vmw_kms_set_config(struct drm_mode_set *set,
|
|||
|
||||
return drm_atomic_helper_set_config(set, ctx);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* vmw_kms_lost_device - Notify kms that modesetting capabilities will be lost
|
||||
*
|
||||
* @dev: Pointer to the drm device
|
||||
*/
|
||||
void vmw_kms_lost_device(struct drm_device *dev)
|
||||
{
|
||||
drm_atomic_helper_shutdown(dev);
|
||||
}
|
||||
|
|
|
@ -240,6 +240,11 @@ struct vmw_display_unit {
|
|||
int set_gui_y;
|
||||
};
|
||||
|
||||
struct vmw_validation_ctx {
|
||||
struct vmw_resource *res;
|
||||
struct vmw_dma_buffer *buf;
|
||||
};
|
||||
|
||||
#define vmw_crtc_to_du(x) \
|
||||
container_of(x, struct vmw_display_unit, crtc)
|
||||
#define vmw_connector_to_du(x) \
|
||||
|
@ -296,9 +301,10 @@ void vmw_kms_helper_buffer_finish(struct vmw_private *dev_priv,
|
|||
struct drm_vmw_fence_rep __user *
|
||||
user_fence_rep);
|
||||
int vmw_kms_helper_resource_prepare(struct vmw_resource *res,
|
||||
bool interruptible);
|
||||
void vmw_kms_helper_resource_revert(struct vmw_resource *res);
|
||||
void vmw_kms_helper_resource_finish(struct vmw_resource *res,
|
||||
bool interruptible,
|
||||
struct vmw_validation_ctx *ctx);
|
||||
void vmw_kms_helper_resource_revert(struct vmw_validation_ctx *ctx);
|
||||
void vmw_kms_helper_resource_finish(struct vmw_validation_ctx *ctx,
|
||||
struct vmw_fence_obj **out_fence);
|
||||
int vmw_kms_readback(struct vmw_private *dev_priv,
|
||||
struct drm_file *file_priv,
|
||||
|
@ -439,5 +445,4 @@ int vmw_kms_stdu_dma(struct vmw_private *dev_priv,
|
|||
|
||||
int vmw_kms_set_config(struct drm_mode_set *set,
|
||||
struct drm_modeset_acquire_ctx *ctx);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -909,12 +909,13 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
|
|||
struct vmw_framebuffer_surface *vfbs =
|
||||
container_of(framebuffer, typeof(*vfbs), base);
|
||||
struct vmw_kms_sou_surface_dirty sdirty;
|
||||
struct vmw_validation_ctx ctx;
|
||||
int ret;
|
||||
|
||||
if (!srf)
|
||||
srf = &vfbs->surface->res;
|
||||
|
||||
ret = vmw_kms_helper_resource_prepare(srf, true);
|
||||
ret = vmw_kms_helper_resource_prepare(srf, true, &ctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -933,7 +934,7 @@ int vmw_kms_sou_do_surface_dirty(struct vmw_private *dev_priv,
|
|||
ret = vmw_kms_helper_dirty(dev_priv, framebuffer, clips, vclips,
|
||||
dest_x, dest_y, num_clips, inc,
|
||||
&sdirty.base);
|
||||
vmw_kms_helper_resource_finish(srf, out_fence);
|
||||
vmw_kms_helper_resource_finish(&ctx, out_fence);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -980,12 +980,13 @@ int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv,
|
|||
struct vmw_framebuffer_surface *vfbs =
|
||||
container_of(framebuffer, typeof(*vfbs), base);
|
||||
struct vmw_stdu_dirty sdirty;
|
||||
struct vmw_validation_ctx ctx;
|
||||
int ret;
|
||||
|
||||
if (!srf)
|
||||
srf = &vfbs->surface->res;
|
||||
|
||||
ret = vmw_kms_helper_resource_prepare(srf, true);
|
||||
ret = vmw_kms_helper_resource_prepare(srf, true, &ctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -1008,7 +1009,7 @@ int vmw_kms_stdu_surface_dirty(struct vmw_private *dev_priv,
|
|||
dest_x, dest_y, num_clips, inc,
|
||||
&sdirty.base);
|
||||
out_finish:
|
||||
vmw_kms_helper_resource_finish(srf, out_fence);
|
||||
vmw_kms_helper_resource_finish(&ctx, out_fence);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -250,10 +250,14 @@ void ipu_prg_channel_disable(struct ipuv3_channel *ipu_chan)
|
|||
{
|
||||
int prg_chan = ipu_prg_ipu_to_prg_chan(ipu_chan->num);
|
||||
struct ipu_prg *prg = ipu_chan->ipu->prg_priv;
|
||||
struct ipu_prg_channel *chan = &prg->chan[prg_chan];
|
||||
struct ipu_prg_channel *chan;
|
||||
u32 val;
|
||||
|
||||
if (!chan->enabled || prg_chan < 0)
|
||||
if (prg_chan < 0)
|
||||
return;
|
||||
|
||||
chan = &prg->chan[prg_chan];
|
||||
if (!chan->enabled)
|
||||
return;
|
||||
|
||||
pm_runtime_get_sync(prg->dev);
|
||||
|
@ -280,13 +284,15 @@ int ipu_prg_channel_configure(struct ipuv3_channel *ipu_chan,
|
|||
{
|
||||
int prg_chan = ipu_prg_ipu_to_prg_chan(ipu_chan->num);
|
||||
struct ipu_prg *prg = ipu_chan->ipu->prg_priv;
|
||||
struct ipu_prg_channel *chan = &prg->chan[prg_chan];
|
||||
struct ipu_prg_channel *chan;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
if (prg_chan < 0)
|
||||
return prg_chan;
|
||||
|
||||
chan = &prg->chan[prg_chan];
|
||||
|
||||
if (chan->enabled) {
|
||||
ipu_pre_update(prg->pres[chan->used_pre], *eba);
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue