diff options
| author | Dave Airlie <airlied@redhat.com> | 2019-02-12 22:05:03 -0500 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2019-02-12 22:05:09 -0500 |
| commit | cd4c5a48741056266ff19b2516e5355b5a01abf3 (patch) | |
| tree | 214cdadfa4816b4f7fd39e05e7ce942ec09449c0 | |
| parent | d13937116f1e82bf508a6325111b322c30c85eb9 (diff) | |
| parent | eb0200a4357da100064971689d3a0e9e3cf57f33 (diff) | |
Merge tag 'imx-drm-fixes-2019-02-12' of git://git.pengutronix.de/pza/linux into drm-fixes
drm/imx: plane, ldb, and ipu-v3 fixes
- Fix CSI register offsets for i.MX51 and i.MX53.
- Fix delayed page flip completion events on i.MX6QP due to unexpected
behaviour of the PRE when issuing NOP buffer updates to the same
buffer address.
- Stop throwing errors for plane updates on disabled CRTCs when a
userspace process is killed while a plane update is pending.
- Add missing of_node_put cleanup in imx_ldb_bind.
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Philipp Zabel <p.zabel@pengutronix.de>
Link: https://patchwork.freedesktop.org/patch/msgid/1549990602.4800.11.camel@pengutronix.de
| -rw-r--r-- | drivers/gpu/drm/imx/imx-ldb.c | 25 | ||||
| -rw-r--r-- | drivers/gpu/drm/imx/ipuv3-plane.c | 4 | ||||
| -rw-r--r-- | drivers/gpu/ipu-v3/ipu-common.c | 8 | ||||
| -rw-r--r-- | drivers/gpu/ipu-v3/ipu-pre.c | 6 |
4 files changed, 29 insertions, 14 deletions
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index 2c5bbe317353..e31e263cf86b 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c | |||
| @@ -643,8 +643,10 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) | |||
| 643 | int bus_format; | 643 | int bus_format; |
| 644 | 644 | ||
| 645 | ret = of_property_read_u32(child, "reg", &i); | 645 | ret = of_property_read_u32(child, "reg", &i); |
| 646 | if (ret || i < 0 || i > 1) | 646 | if (ret || i < 0 || i > 1) { |
| 647 | return -EINVAL; | 647 | ret = -EINVAL; |
| 648 | goto free_child; | ||
| 649 | } | ||
| 648 | 650 | ||
| 649 | if (!of_device_is_available(child)) | 651 | if (!of_device_is_available(child)) |
| 650 | continue; | 652 | continue; |
| @@ -657,7 +659,6 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) | |||
| 657 | channel = &imx_ldb->channel[i]; | 659 | channel = &imx_ldb->channel[i]; |
| 658 | channel->ldb = imx_ldb; | 660 | channel->ldb = imx_ldb; |
| 659 | channel->chno = i; | 661 | channel->chno = i; |
| 660 | channel->child = child; | ||
| 661 | 662 | ||
| 662 | /* | 663 | /* |
| 663 | * The output port is port@4 with an external 4-port mux or | 664 | * The output port is port@4 with an external 4-port mux or |
| @@ -667,13 +668,13 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) | |||
| 667 | imx_ldb->lvds_mux ? 4 : 2, 0, | 668 | imx_ldb->lvds_mux ? 4 : 2, 0, |
| 668 | &channel->panel, &channel->bridge); | 669 | &channel->panel, &channel->bridge); |
| 669 | if (ret && ret != -ENODEV) | 670 | if (ret && ret != -ENODEV) |
| 670 | return ret; | 671 | goto free_child; |
| 671 | 672 | ||
| 672 | /* panel ddc only if there is no bridge */ | 673 | /* panel ddc only if there is no bridge */ |
| 673 | if (!channel->bridge) { | 674 | if (!channel->bridge) { |
| 674 | ret = imx_ldb_panel_ddc(dev, channel, child); | 675 | ret = imx_ldb_panel_ddc(dev, channel, child); |
| 675 | if (ret) | 676 | if (ret) |
| 676 | return ret; | 677 | goto free_child; |
| 677 | } | 678 | } |
| 678 | 679 | ||
| 679 | bus_format = of_get_bus_format(dev, child); | 680 | bus_format = of_get_bus_format(dev, child); |
| @@ -689,18 +690,26 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) | |||
| 689 | if (bus_format < 0) { | 690 | if (bus_format < 0) { |
| 690 | dev_err(dev, "could not determine data mapping: %d\n", | 691 | dev_err(dev, "could not determine data mapping: %d\n", |
| 691 | bus_format); | 692 | bus_format); |
| 692 | return bus_format; | 693 | ret = bus_format; |
| 694 | goto free_child; | ||
| 693 | } | 695 | } |
| 694 | channel->bus_format = bus_format; | 696 | channel->bus_format = bus_format; |
| 697 | channel->child = child; | ||
| 695 | 698 | ||
| 696 | ret = imx_ldb_register(drm, channel); | 699 | ret = imx_ldb_register(drm, channel); |
| 697 | if (ret) | 700 | if (ret) { |
| 698 | return ret; | 701 | channel->child = NULL; |
| 702 | goto free_child; | ||
| 703 | } | ||
| 699 | } | 704 | } |
| 700 | 705 | ||
| 701 | dev_set_drvdata(dev, imx_ldb); | 706 | dev_set_drvdata(dev, imx_ldb); |
| 702 | 707 | ||
| 703 | return 0; | 708 | return 0; |
| 709 | |||
| 710 | free_child: | ||
| 711 | of_node_put(child); | ||
| 712 | return ret; | ||
| 704 | } | 713 | } |
| 705 | 714 | ||
| 706 | static void imx_ldb_unbind(struct device *dev, struct device *master, | 715 | static void imx_ldb_unbind(struct device *dev, struct device *master, |
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c index c390924de93d..21e964f6ab5c 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.c +++ b/drivers/gpu/drm/imx/ipuv3-plane.c | |||
| @@ -370,9 +370,9 @@ static int ipu_plane_atomic_check(struct drm_plane *plane, | |||
| 370 | if (ret) | 370 | if (ret) |
| 371 | return ret; | 371 | return ret; |
| 372 | 372 | ||
| 373 | /* CRTC should be enabled */ | 373 | /* nothing to check when disabling or disabled */ |
| 374 | if (!crtc_state->enable) | 374 | if (!crtc_state->enable) |
| 375 | return -EINVAL; | 375 | return 0; |
| 376 | 376 | ||
| 377 | switch (plane->type) { | 377 | switch (plane->type) { |
| 378 | case DRM_PLANE_TYPE_PRIMARY: | 378 | case DRM_PLANE_TYPE_PRIMARY: |
diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index 474b00e19697..0a7d4395d427 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c | |||
| @@ -898,8 +898,8 @@ static struct ipu_devtype ipu_type_imx51 = { | |||
| 898 | .cpmem_ofs = 0x1f000000, | 898 | .cpmem_ofs = 0x1f000000, |
| 899 | .srm_ofs = 0x1f040000, | 899 | .srm_ofs = 0x1f040000, |
| 900 | .tpm_ofs = 0x1f060000, | 900 | .tpm_ofs = 0x1f060000, |
| 901 | .csi0_ofs = 0x1f030000, | 901 | .csi0_ofs = 0x1e030000, |
| 902 | .csi1_ofs = 0x1f038000, | 902 | .csi1_ofs = 0x1e038000, |
| 903 | .ic_ofs = 0x1e020000, | 903 | .ic_ofs = 0x1e020000, |
| 904 | .disp0_ofs = 0x1e040000, | 904 | .disp0_ofs = 0x1e040000, |
| 905 | .disp1_ofs = 0x1e048000, | 905 | .disp1_ofs = 0x1e048000, |
| @@ -914,8 +914,8 @@ static struct ipu_devtype ipu_type_imx53 = { | |||
| 914 | .cpmem_ofs = 0x07000000, | 914 | .cpmem_ofs = 0x07000000, |
| 915 | .srm_ofs = 0x07040000, | 915 | .srm_ofs = 0x07040000, |
| 916 | .tpm_ofs = 0x07060000, | 916 | .tpm_ofs = 0x07060000, |
| 917 | .csi0_ofs = 0x07030000, | 917 | .csi0_ofs = 0x06030000, |
| 918 | .csi1_ofs = 0x07038000, | 918 | .csi1_ofs = 0x06038000, |
| 919 | .ic_ofs = 0x06020000, | 919 | .ic_ofs = 0x06020000, |
| 920 | .disp0_ofs = 0x06040000, | 920 | .disp0_ofs = 0x06040000, |
| 921 | .disp1_ofs = 0x06048000, | 921 | .disp1_ofs = 0x06048000, |
diff --git a/drivers/gpu/ipu-v3/ipu-pre.c b/drivers/gpu/ipu-v3/ipu-pre.c index 2f8db9d62551..4a28f3fbb0a2 100644 --- a/drivers/gpu/ipu-v3/ipu-pre.c +++ b/drivers/gpu/ipu-v3/ipu-pre.c | |||
| @@ -106,6 +106,7 @@ struct ipu_pre { | |||
| 106 | void *buffer_virt; | 106 | void *buffer_virt; |
| 107 | bool in_use; | 107 | bool in_use; |
| 108 | unsigned int safe_window_end; | 108 | unsigned int safe_window_end; |
| 109 | unsigned int last_bufaddr; | ||
| 109 | }; | 110 | }; |
| 110 | 111 | ||
| 111 | static DEFINE_MUTEX(ipu_pre_list_mutex); | 112 | static DEFINE_MUTEX(ipu_pre_list_mutex); |
| @@ -185,6 +186,7 @@ void ipu_pre_configure(struct ipu_pre *pre, unsigned int width, | |||
| 185 | 186 | ||
| 186 | writel(bufaddr, pre->regs + IPU_PRE_CUR_BUF); | 187 | writel(bufaddr, pre->regs + IPU_PRE_CUR_BUF); |
| 187 | writel(bufaddr, pre->regs + IPU_PRE_NEXT_BUF); | 188 | writel(bufaddr, pre->regs + IPU_PRE_NEXT_BUF); |
| 189 | pre->last_bufaddr = bufaddr; | ||
| 188 | 190 | ||
| 189 | val = IPU_PRE_PREF_ENG_CTRL_INPUT_PIXEL_FORMAT(0) | | 191 | val = IPU_PRE_PREF_ENG_CTRL_INPUT_PIXEL_FORMAT(0) | |
| 190 | IPU_PRE_PREF_ENG_CTRL_INPUT_ACTIVE_BPP(active_bpp) | | 192 | IPU_PRE_PREF_ENG_CTRL_INPUT_ACTIVE_BPP(active_bpp) | |
| @@ -242,7 +244,11 @@ void ipu_pre_update(struct ipu_pre *pre, unsigned int bufaddr) | |||
| 242 | unsigned short current_yblock; | 244 | unsigned short current_yblock; |
| 243 | u32 val; | 245 | u32 val; |
| 244 | 246 | ||
| 247 | if (bufaddr == pre->last_bufaddr) | ||
| 248 | return; | ||
| 249 | |||
| 245 | writel(bufaddr, pre->regs + IPU_PRE_NEXT_BUF); | 250 | writel(bufaddr, pre->regs + IPU_PRE_NEXT_BUF); |
| 251 | pre->last_bufaddr = bufaddr; | ||
| 246 | 252 | ||
| 247 | do { | 253 | do { |
| 248 | if (time_after(jiffies, timeout)) { | 254 | if (time_after(jiffies, timeout)) { |
