drm-misc-fixes for v5.9-rc5:
- Fix double free in virtio. - Add missing put_device in sun4i, and other fixes. - Small ingenic fixes. - Handle sun4i alpha on lowest plane correctly. - Remove output->enabled from virtio, as it should use crtc_state. - Fix tve200 enable/disable. - Documentation fix. - Fix virtio unblank. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEuXvWqAysSYEJGuVH/lWMcqZwE8MFAl9Y6koACgkQ/lWMcqZw E8P5CxAAvH5B60s23LQdi7JWgWY4r560jneCtBtnesOKMan3ckVHZSX1XEsvvodQ Ihvm8EriajcYDTOSCgXg5CitPpFDD3WaxUPWZ5VNiLnQInncbP0+Scz147/bVyHo 1XoPyLqqjCrUcHEQSxYGZfFtJPEpm4CoRgqHDQk0QAdYtopgLf1ff6Z2gYGUC7kD 8nIOVakRdDlRlhQYIy9AzznUTPJvN4vm0cLmJS4xDlVpVJcLI7X9qiMEF1OsZvhw x6sH+3uttbQRzMJqARyANbMc0VD3osqwzTnHHehu6xGI03MLZW2NC6+LpQEe2zK1 AST/H8si7OpemXCyztevkqeDXj6jOBNgnIlr5gv2rUSK5Iva7ZKj4P/2xxr6qm4E 7Ip1Qa1WXMMJJiFGddcYZ2fjEpWUPGAmigtZtwVebugmqSgWigphengqhDZb3gMM IsVABfbAM0DZcV8iVeHYDq5OJmdOD+/qzAKOayaj4Sgq5G7LokkkIuYhtU7i28rQ Bl8vCR0VprxdyfKweS98PLBpbgo4oSh20zRTqvLtiNbVWZoVhTdladd9hlL2IChg cx5bOf7fkboX1hTy7vdU16BIuGzEFc38XgexXDYJuvvy/T+GvYDUtw4HL1vJwT79 /Ef6psjt6EqVE4JfTYvwv54Hbz4PrvLRUngZK/vzkzefDygw9Sc= =pqMB -----END PGP SIGNATURE----- Merge tag 'drm-misc-fixes-2020-09-09' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes drm-misc-fixes for v5.9-rc5: - Fix double free in virtio. - Add missing put_device in sun4i, and other fixes. - Small ingenic fixes. - Handle sun4i alpha on lowest plane correctly. - Remove output->enabled from virtio, as it should use crtc_state. - Fix tve200 enable/disable. - Documentation fix. - Fix virtio unblank. Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maarten Lankhorst <maarten.lankhorst@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/478b49d1-b1b3-c983-7056-8a89249be435@mblankhorst.nl
This commit is contained in:
commit
7f7a47952c
@ -179,7 +179,7 @@ DMA Fence uABI/Sync File
|
||||
:internal:
|
||||
|
||||
Indefinite DMA Fences
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
At various times &dma_fence with an indefinite time until dma_fence_wait()
|
||||
finishes have been proposed. Examples include:
|
||||
|
@ -316,9 +316,9 @@ out:
|
||||
* name of the dma-buf if the same piece of memory is used for multiple
|
||||
* purpose between different devices.
|
||||
*
|
||||
* @dmabuf [in] dmabuf buffer that will be renamed.
|
||||
* @buf: [in] A piece of userspace memory that contains the name of
|
||||
* the dma-buf.
|
||||
* @dmabuf: [in] dmabuf buffer that will be renamed.
|
||||
* @buf: [in] A piece of userspace memory that contains the name of
|
||||
* the dma-buf.
|
||||
*
|
||||
* Returns 0 on success. If the dma-buf buffer is already attached to
|
||||
* devices, return -EBUSY.
|
||||
|
@ -222,6 +222,7 @@ EXPORT_SYMBOL(dma_fence_chain_ops);
|
||||
* @chain: the chain node to initialize
|
||||
* @prev: the previous fence
|
||||
* @fence: the current fence
|
||||
* @seqno: the sequence number to use for the fence chain
|
||||
*
|
||||
* Initialize a new chain node and either start a new chain or add the node to
|
||||
* the existing chain of the previous fence.
|
||||
|
@ -673,7 +673,7 @@ static void ingenic_drm_unbind_all(void *d)
|
||||
component_unbind_all(priv->dev, &priv->drm);
|
||||
}
|
||||
|
||||
static int ingenic_drm_bind(struct device *dev)
|
||||
static int ingenic_drm_bind(struct device *dev, bool has_components)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
const struct jz_soc_info *soc_info;
|
||||
@ -808,7 +808,7 @@ static int ingenic_drm_bind(struct device *dev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_DRM_INGENIC_IPU)) {
|
||||
if (IS_ENABLED(CONFIG_DRM_INGENIC_IPU) && has_components) {
|
||||
ret = component_bind_all(dev, drm);
|
||||
if (ret) {
|
||||
if (ret != -EPROBE_DEFER)
|
||||
@ -939,6 +939,11 @@ err_pixclk_disable:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ingenic_drm_bind_with_components(struct device *dev)
|
||||
{
|
||||
return ingenic_drm_bind(dev, true);
|
||||
}
|
||||
|
||||
static int compare_of(struct device *dev, void *data)
|
||||
{
|
||||
return dev->of_node == data;
|
||||
@ -957,7 +962,7 @@ static void ingenic_drm_unbind(struct device *dev)
|
||||
}
|
||||
|
||||
static const struct component_master_ops ingenic_master_ops = {
|
||||
.bind = ingenic_drm_bind,
|
||||
.bind = ingenic_drm_bind_with_components,
|
||||
.unbind = ingenic_drm_unbind,
|
||||
};
|
||||
|
||||
@ -968,16 +973,15 @@ static int ingenic_drm_probe(struct platform_device *pdev)
|
||||
struct device_node *np;
|
||||
|
||||
if (!IS_ENABLED(CONFIG_DRM_INGENIC_IPU))
|
||||
return ingenic_drm_bind(dev);
|
||||
return ingenic_drm_bind(dev, false);
|
||||
|
||||
/* IPU is at port address 8 */
|
||||
np = of_graph_get_remote_node(dev->of_node, 8, 0);
|
||||
if (!np) {
|
||||
dev_err(dev, "Unable to get IPU node\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!np)
|
||||
return ingenic_drm_bind(dev, false);
|
||||
|
||||
drm_of_component_match_add(dev, &match, compare_of, np);
|
||||
of_node_put(np);
|
||||
|
||||
return component_master_add_with_match(dev, &ingenic_master_ops, match);
|
||||
}
|
||||
|
@ -589,8 +589,7 @@ static int sun4i_backend_atomic_check(struct sunxi_engine *engine,
|
||||
|
||||
/* We can't have an alpha plane at the lowest position */
|
||||
if (!backend->quirks->supports_lowest_plane_alpha &&
|
||||
(plane_states[0]->fb->format->has_alpha ||
|
||||
(plane_states[0]->alpha != DRM_BLEND_ALPHA_OPAQUE)))
|
||||
(plane_states[0]->alpha != DRM_BLEND_ALPHA_OPAQUE))
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 1; i < num_planes; i++) {
|
||||
@ -995,7 +994,6 @@ static const struct sun4i_backend_quirks sun6i_backend_quirks = {
|
||||
|
||||
static const struct sun4i_backend_quirks sun7i_backend_quirks = {
|
||||
.needs_output_muxing = true,
|
||||
.supports_lowest_plane_alpha = true,
|
||||
};
|
||||
|
||||
static const struct sun4i_backend_quirks sun8i_a33_backend_quirks = {
|
||||
|
@ -1433,14 +1433,18 @@ static int sun8i_r40_tcon_tv_set_mux(struct sun4i_tcon *tcon,
|
||||
if (IS_ENABLED(CONFIG_DRM_SUN8I_TCON_TOP) &&
|
||||
encoder->encoder_type == DRM_MODE_ENCODER_TMDS) {
|
||||
ret = sun8i_tcon_top_set_hdmi_src(&pdev->dev, id);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
put_device(&pdev->dev);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_DRM_SUN8I_TCON_TOP)) {
|
||||
ret = sun8i_tcon_top_de_config(&pdev->dev, tcon->id, id);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
put_device(&pdev->dev);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -889,7 +889,7 @@ static int sun6i_dsi_dcs_write_long(struct sun6i_dsi *dsi,
|
||||
regmap_write(dsi->regs, SUN6I_DSI_CMD_TX_REG(0),
|
||||
sun6i_dsi_dcs_build_pkt_hdr(dsi, msg));
|
||||
|
||||
bounce = kzalloc(msg->tx_len + sizeof(crc), GFP_KERNEL);
|
||||
bounce = kzalloc(ALIGN(msg->tx_len + sizeof(crc), 4), GFP_KERNEL);
|
||||
if (!bounce)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -900,7 +900,7 @@ static int sun6i_dsi_dcs_write_long(struct sun6i_dsi *dsi,
|
||||
memcpy((u8 *)bounce + msg->tx_len, &crc, sizeof(crc));
|
||||
len += sizeof(crc);
|
||||
|
||||
regmap_bulk_write(dsi->regs, SUN6I_DSI_CMD_TX_REG(1), bounce, len);
|
||||
regmap_bulk_write(dsi->regs, SUN6I_DSI_CMD_TX_REG(1), bounce, DIV_ROUND_UP(len, 4));
|
||||
regmap_write(dsi->regs, SUN6I_DSI_CMD_CTL_REG, len + 4 - 1);
|
||||
kfree(bounce);
|
||||
|
||||
|
@ -211,7 +211,7 @@ static int sun8i_vi_layer_update_coord(struct sun8i_mixer *mixer, int channel,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool sun8i_vi_layer_get_csc_mode(const struct drm_format_info *format)
|
||||
static u32 sun8i_vi_layer_get_csc_mode(const struct drm_format_info *format)
|
||||
{
|
||||
if (!format->is_yuv)
|
||||
return SUN8I_CSC_MODE_OFF;
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <linux/version.h>
|
||||
#include <linux/dma-buf.h>
|
||||
#include <linux/of_graph.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <drm/drm_fb_cma_helper.h>
|
||||
#include <drm/drm_fourcc.h>
|
||||
@ -130,9 +131,25 @@ static void tve200_display_enable(struct drm_simple_display_pipe *pipe,
|
||||
struct drm_connector *connector = priv->connector;
|
||||
u32 format = fb->format->format;
|
||||
u32 ctrl1 = 0;
|
||||
int retries;
|
||||
|
||||
clk_prepare_enable(priv->clk);
|
||||
|
||||
/* Reset the TVE200 and wait for it to come back online */
|
||||
writel(TVE200_CTRL_4_RESET, priv->regs + TVE200_CTRL_4);
|
||||
for (retries = 0; retries < 5; retries++) {
|
||||
usleep_range(30000, 50000);
|
||||
if (readl(priv->regs + TVE200_CTRL_4) & TVE200_CTRL_4_RESET)
|
||||
continue;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (retries == 5 &&
|
||||
readl(priv->regs + TVE200_CTRL_4) & TVE200_CTRL_4_RESET) {
|
||||
dev_err(drm->dev, "can't get hardware out of reset\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Function 1 */
|
||||
ctrl1 |= TVE200_CTRL_CSMODE;
|
||||
/* Interlace mode for CCIR656: parameterize? */
|
||||
@ -230,8 +247,9 @@ static void tve200_display_disable(struct drm_simple_display_pipe *pipe)
|
||||
|
||||
drm_crtc_vblank_off(crtc);
|
||||
|
||||
/* Disable and Power Down */
|
||||
/* Disable put into reset and Power Down */
|
||||
writel(0, priv->regs + TVE200_CTRL);
|
||||
writel(TVE200_CTRL_4_RESET, priv->regs + TVE200_CTRL_4);
|
||||
|
||||
clk_disable_unprepare(priv->clk);
|
||||
}
|
||||
@ -279,6 +297,8 @@ static int tve200_display_enable_vblank(struct drm_simple_display_pipe *pipe)
|
||||
struct drm_device *drm = crtc->dev;
|
||||
struct tve200_drm_dev_private *priv = drm->dev_private;
|
||||
|
||||
/* Clear any IRQs and enable */
|
||||
writel(0xFF, priv->regs + TVE200_INT_CLR);
|
||||
writel(TVE200_INT_V_STATUS, priv->regs + TVE200_INT_EN);
|
||||
return 0;
|
||||
}
|
||||
|
@ -97,9 +97,6 @@ static void virtio_gpu_crtc_mode_set_nofb(struct drm_crtc *crtc)
|
||||
static void virtio_gpu_crtc_atomic_enable(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *old_state)
|
||||
{
|
||||
struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc);
|
||||
|
||||
output->enabled = true;
|
||||
}
|
||||
|
||||
static void virtio_gpu_crtc_atomic_disable(struct drm_crtc *crtc,
|
||||
@ -111,7 +108,6 @@ static void virtio_gpu_crtc_atomic_disable(struct drm_crtc *crtc,
|
||||
|
||||
virtio_gpu_cmd_set_scanout(vgdev, output->index, 0, 0, 0, 0, 0);
|
||||
virtio_gpu_notify(vgdev);
|
||||
output->enabled = false;
|
||||
}
|
||||
|
||||
static int virtio_gpu_crtc_atomic_check(struct drm_crtc *crtc,
|
||||
@ -123,6 +119,17 @@ static int virtio_gpu_crtc_atomic_check(struct drm_crtc *crtc,
|
||||
static void virtio_gpu_crtc_atomic_flush(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *old_state)
|
||||
{
|
||||
struct virtio_gpu_output *output = drm_crtc_to_virtio_gpu_output(crtc);
|
||||
|
||||
/*
|
||||
* virtio-gpu can't do modeset and plane update operations
|
||||
* independent from each other. So the actual modeset happens
|
||||
* in the plane update callback, and here we just check
|
||||
* whenever we must force the modeset.
|
||||
*/
|
||||
if (drm_atomic_crtc_needs_modeset(crtc->state)) {
|
||||
output->needs_modeset = true;
|
||||
}
|
||||
}
|
||||
|
||||
static const struct drm_crtc_helper_funcs virtio_gpu_crtc_helper_funcs = {
|
||||
|
@ -137,7 +137,7 @@ struct virtio_gpu_output {
|
||||
struct edid *edid;
|
||||
int cur_x;
|
||||
int cur_y;
|
||||
bool enabled;
|
||||
bool needs_modeset;
|
||||
};
|
||||
#define drm_crtc_to_virtio_gpu_output(x) \
|
||||
container_of(x, struct virtio_gpu_output, crtc)
|
||||
|
@ -151,7 +151,13 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev,
|
||||
if (ret < 0)
|
||||
return -EINVAL;
|
||||
|
||||
shmem->pages = drm_gem_shmem_get_pages_sgt(&bo->base.base);
|
||||
/*
|
||||
* virtio_gpu uses drm_gem_shmem_get_sg_table instead of
|
||||
* drm_gem_shmem_get_pages_sgt because virtio has it's own set of
|
||||
* dma-ops. This is discouraged for other drivers, but should be fine
|
||||
* since virtio_gpu doesn't support dma-buf import from other devices.
|
||||
*/
|
||||
shmem->pages = drm_gem_shmem_get_sg_table(&bo->base.base);
|
||||
if (!shmem->pages) {
|
||||
drm_gem_shmem_unpin(&bo->base.base);
|
||||
return -EINVAL;
|
||||
|
@ -142,7 +142,7 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane,
|
||||
if (WARN_ON(!output))
|
||||
return;
|
||||
|
||||
if (!plane->state->fb || !output->enabled) {
|
||||
if (!plane->state->fb || !output->crtc.state->active) {
|
||||
DRM_DEBUG("nofb\n");
|
||||
virtio_gpu_cmd_set_scanout(vgdev, output->index, 0,
|
||||
plane->state->src_w >> 16,
|
||||
@ -163,7 +163,9 @@ static void virtio_gpu_primary_plane_update(struct drm_plane *plane,
|
||||
plane->state->src_w != old_state->src_w ||
|
||||
plane->state->src_h != old_state->src_h ||
|
||||
plane->state->src_x != old_state->src_x ||
|
||||
plane->state->src_y != old_state->src_y) {
|
||||
plane->state->src_y != old_state->src_y ||
|
||||
output->needs_modeset) {
|
||||
output->needs_modeset = false;
|
||||
DRM_DEBUG("handle 0x%x, crtc %dx%d+%d+%d, src %dx%d+%d+%d\n",
|
||||
bo->hw_res_handle,
|
||||
plane->state->crtc_w, plane->state->crtc_h,
|
||||
|
Loading…
Reference in New Issue
Block a user