No such luck. The patch I used (against 4.11-rc4) is attached. The error was: SHIPPED arch/arm/boot/compressed/bswapsdi2.S AS arch/arm/boot/compressed/bswapsdi2.o LD arch/arm/boot/compressed/vmlinux OBJCOPY arch/arm/boot/zImage Kernel: arch/arm/boot/zImage is ready Building modules, stage 2. MODPOST 3341 modules ERROR: "ipu_plane_disable_deferred" [drivers/gpu/drm/imx/imxdrm.ko] undefined! make[1]: *** [scripts/Makefile.modpost:91: __modpost] Error 1 make: *** [Makefile:1200: modules] Error 2 ==> ERROR: A failure occurred in build(). Aborting... On Sat, Apr 1, 2017 at 1:26 AM, Dan MacDonald <allcoms@xxxxxxxxx> wrote: > Thanks Russell! > > I think the patch has applied OK - I've just started the build so it > could be a while yet. 12 hours maybe? Its building support for every > arm7 thing under the sun because I'm too lazy (sensible?) to try > hacking it down to size. > > Adding the patch to the Arch rc kernel PKGBUILD was as simple as > adding the name of the patch to the source() section, adding a > corresponding 'SKIP' to the end of the md5sums() section and then > adding: > > git apply ../sabre-lite.patch > > to the prepare() section of the PKGBUILD. I copied the patch into the > same dir as the PKGBUILD and then ran: > > $ makepkg > > In the same dir as the kernel PKGBUILD and patches. > > Results at last! :D > > On Fri, Mar 31, 2017 at 3:15 PM, Russell King - ARM Linux > <linux@xxxxxxxxxxxxxxx> wrote: >> On Fri, Mar 31, 2017 at 02:36:31PM +0100, Dan MacDonald wrote: >>> Hi all >>> >>> Up until now I've only ever used the most basic features of git, so >>> I've had to do some research into how to best/cleanly extract >>> Phillipps patches so that I can include his changes into an Arch >>> kernel PKGBUILD. >>> >>> I think the following should work: >>> >>> git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git >>> cd linux >>> git fetch https://git.pengutronix.de/git/pza/linux.git >>> tags/v4.10-ipu-dp-plane-fix >>> git checkout FETCH_HEAD >>> git whatchanged -p origin/master..FETCH_HEAD > sabre-lite.patch >> >> I don't think that will work, because it'll output the changes as >> individual patches in reverse order (newest first) which will be >> no good when trying to feed it into patch or git apply. >> >> I think what you instead want is: >> >> git diff origin/master...FETCH_HEAD > sabre-lite.patch >> >> which will be the changes that are in FETCH_HEAD that aren't in >> origin/master as a single patch. >> >>> I should then be able to include that patch in a 4.11-rc4 PKGBUILD - >>> I'll give it a go this weekend and see if it applies and builds OK but >>> please let me know if anyone sees any flaws in this procedure. >> >> Thanks - one of the issues is that not everyone knows the details of >> distribution package build systems (each distro seems to have their >> own unique way of building and packaging stuff.) >> >> -- >> RMK's Patch system: http://www.armlinux.org.uk/developer/patches/ >> FTTC broadband for 0.8mile line: currently at 9.6Mbps down 400kbps up >> according to speedtest.net.
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c index 33404295b447..b07499214c72 100644 --- a/drivers/gpu/drm/imx/imx-drm-core.c +++ b/drivers/gpu/drm/imx/imx-drm-core.c @@ -30,6 +30,7 @@ #include <video/imx-ipu-v3.h> #include "imx-drm.h" +#include "ipuv3-plane.h" #define MAX_CRTC 4 @@ -160,6 +161,9 @@ static const struct drm_mode_config_funcs imx_drm_mode_config_funcs = { static void imx_drm_atomic_commit_tail(struct drm_atomic_state *state) { struct drm_device *dev = state->dev; + struct drm_plane *plane; + struct drm_plane_state *plane_state; + int i; drm_atomic_helper_commit_modeset_disables(dev, state); @@ -169,10 +173,13 @@ static void imx_drm_atomic_commit_tail(struct drm_atomic_state *state) drm_atomic_helper_commit_modeset_enables(dev, state); - drm_atomic_helper_commit_hw_done(state); - drm_atomic_helper_wait_for_vblanks(dev, state); + for_each_plane_in_state(state, plane, plane_state, i) + ipu_plane_disable_deferred(plane); + + drm_atomic_helper_commit_hw_done(state); + drm_atomic_helper_cleanup_planes(dev, state); } diff --git a/drivers/gpu/drm/imx/ipuv3-crtc.c b/drivers/gpu/drm/imx/ipuv3-crtc.c index 6be515a9fb69..0f15f11f26e0 100644 --- a/drivers/gpu/drm/imx/ipuv3-crtc.c +++ b/drivers/gpu/drm/imx/ipuv3-crtc.c @@ -60,6 +60,26 @@ static void ipu_crtc_enable(struct drm_crtc *crtc) ipu_di_enable(ipu_crtc->di); } +static void ipu_crtc_disable_planes(struct ipu_crtc *ipu_crtc, + struct drm_crtc_state *old_crtc_state) +{ + bool disable_partial = false; + bool disable_full = false; + struct drm_plane *plane; + + drm_atomic_crtc_state_for_each_plane(plane, old_crtc_state) { + if (plane == &ipu_crtc->plane[0]->base) + disable_full = true; + if (&ipu_crtc->plane[1] && plane == &ipu_crtc->plane[1]->base) + disable_partial = true; + } + + if (disable_partial) + ipu_plane_disable(ipu_crtc->plane[1], true); + if (disable_full) + ipu_plane_disable(ipu_crtc->plane[0], false); +} + static void ipu_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) { @@ -73,7 +93,7 @@ static void ipu_crtc_atomic_disable(struct drm_crtc *crtc, * attached IDMACs will be left in undefined state, possibly hanging * the IPU or even system. */ - drm_atomic_helper_disable_planes_on_crtc(old_crtc_state, false); + ipu_crtc_disable_planes(ipu_crtc, old_crtc_state); ipu_dc_disable(ipu); spin_lock_irq(&crtc->dev->event_lock); diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c index e74a0ad52950..ec4f86295184 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.c +++ b/drivers/gpu/drm/imx/ipuv3-plane.c @@ -172,22 +172,28 @@ static void ipu_plane_enable(struct ipu_plane *ipu_plane) ipu_dp_enable_channel(ipu_plane->dp); } -static int ipu_disable_plane(struct drm_plane *plane) +void ipu_plane_disable(struct ipu_plane *ipu_plane, bool disable_dp_channel) { - struct ipu_plane *ipu_plane = to_ipu_plane(plane); - DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); ipu_idmac_wait_busy(ipu_plane->ipu_ch, 50); - if (ipu_plane->dp) - ipu_dp_disable_channel(ipu_plane->dp); + if (ipu_plane->dp && disable_dp_channel) + ipu_dp_disable_channel(ipu_plane->dp, false); ipu_idmac_disable_channel(ipu_plane->ipu_ch); ipu_dmfc_disable_channel(ipu_plane->dmfc); if (ipu_plane->dp) ipu_dp_disable(ipu_plane->ipu); +} - return 0; +void ipu_plane_disable_deferred(struct drm_plane *plane) +{ + struct ipu_plane *ipu_plane = to_ipu_plane(plane); + + if (ipu_plane->disabling) { + ipu_plane->disabling = false; + ipu_plane_disable(ipu_plane, false); + } } static void ipu_plane_destroy(struct drm_plane *plane) @@ -361,7 +367,11 @@ static int ipu_plane_atomic_check(struct drm_plane *plane, static void ipu_plane_atomic_disable(struct drm_plane *plane, struct drm_plane_state *old_state) { - ipu_disable_plane(plane); + struct ipu_plane *ipu_plane = to_ipu_plane(plane); + + if (ipu_plane->dp) + ipu_dp_disable_channel(ipu_plane->dp, true); + ipu_plane->disabling = true; } static void ipu_plane_atomic_update(struct drm_plane *plane, diff --git a/drivers/gpu/drm/imx/ipuv3-plane.h b/drivers/gpu/drm/imx/ipuv3-plane.h index 338b88a74eb6..0e2a723ff981 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.h +++ b/drivers/gpu/drm/imx/ipuv3-plane.h @@ -23,6 +23,8 @@ struct ipu_plane { int dma; int dp_flow; + + bool disabling; }; struct ipu_plane *ipu_plane_init(struct drm_device *dev, struct ipu_soc *ipu, @@ -42,4 +44,7 @@ void ipu_plane_put_resources(struct ipu_plane *plane); int ipu_plane_irq(struct ipu_plane *plane); +void ipu_plane_disable(struct ipu_plane *ipu_plane, bool disable_dp_channel); +void ipu_plane_disable_deferred(struct drm_plane *plane); + #endif diff --git a/drivers/gpu/ipu-v3/ipu-common.c b/drivers/gpu/ipu-v3/ipu-common.c index 97218af4fe75..b020d97e7699 100644 --- a/drivers/gpu/ipu-v3/ipu-common.c +++ b/drivers/gpu/ipu-v3/ipu-common.c @@ -51,15 +51,17 @@ int ipu_get_num(struct ipu_soc *ipu) } EXPORT_SYMBOL_GPL(ipu_get_num); -void ipu_srm_dp_sync_update(struct ipu_soc *ipu) +void ipu_srm_dp_update(struct ipu_soc *ipu, bool sync) { u32 val; val = ipu_cm_read(ipu, IPU_SRM_PRI2); - val |= 0x8; + val &= ~DP_S_SRM_MODE_MASK; + val |= sync ? DP_S_SRM_MODE_NEXT_FRAME : + DP_S_SRM_MODE_NOW; ipu_cm_write(ipu, val, IPU_SRM_PRI2); } -EXPORT_SYMBOL_GPL(ipu_srm_dp_sync_update); +EXPORT_SYMBOL_GPL(ipu_srm_dp_update); enum ipu_color_space ipu_drm_fourcc_to_colorspace(u32 drm_fourcc) { diff --git a/drivers/gpu/ipu-v3/ipu-dc.c b/drivers/gpu/ipu-v3/ipu-dc.c index 659475c1e44a..7a4b8362dda8 100644 --- a/drivers/gpu/ipu-v3/ipu-dc.c +++ b/drivers/gpu/ipu-v3/ipu-dc.c @@ -112,8 +112,6 @@ struct ipu_dc_priv { struct ipu_dc channels[IPU_DC_NUM_CHANNELS]; struct mutex mutex; struct completion comp; - int dc_irq; - int dp_irq; int use_count; }; @@ -262,47 +260,13 @@ void ipu_dc_enable_channel(struct ipu_dc *dc) } EXPORT_SYMBOL_GPL(ipu_dc_enable_channel); -static irqreturn_t dc_irq_handler(int irq, void *dev_id) -{ - struct ipu_dc *dc = dev_id; - u32 reg; - - reg = readl(dc->base + DC_WR_CH_CONF); - reg &= ~DC_WR_CH_CONF_PROG_TYPE_MASK; - writel(reg, dc->base + DC_WR_CH_CONF); - - /* The Freescale BSP kernel clears DIx_COUNTER_RELEASE here */ - - complete(&dc->priv->comp); - return IRQ_HANDLED; -} - void ipu_dc_disable_channel(struct ipu_dc *dc) { - struct ipu_dc_priv *priv = dc->priv; - int irq; - unsigned long ret; u32 val; - /* TODO: Handle MEM_FG_SYNC differently from MEM_BG_SYNC */ - if (dc->chno == 1) - irq = priv->dc_irq; - else if (dc->chno == 5) - irq = priv->dp_irq; - else - return; - - init_completion(&priv->comp); - enable_irq(irq); - ret = wait_for_completion_timeout(&priv->comp, msecs_to_jiffies(50)); - disable_irq(irq); - if (ret == 0) { - dev_warn(priv->dev, "DC stop timeout after 50 ms\n"); - - val = readl(dc->base + DC_WR_CH_CONF); - val &= ~DC_WR_CH_CONF_PROG_TYPE_MASK; - writel(val, dc->base + DC_WR_CH_CONF); - } + val = readl(dc->base + DC_WR_CH_CONF); + val &= ~DC_WR_CH_CONF_PROG_TYPE_MASK; + writel(val, dc->base + DC_WR_CH_CONF); } EXPORT_SYMBOL_GPL(ipu_dc_disable_channel); @@ -389,7 +353,7 @@ int ipu_dc_init(struct ipu_soc *ipu, struct device *dev, struct ipu_dc_priv *priv; static int channel_offsets[] = { 0, 0x1c, 0x38, 0x54, 0x58, 0x5c, 0x78, 0, 0x94, 0xb4}; - int i, ret; + int i; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) @@ -410,23 +374,6 @@ int ipu_dc_init(struct ipu_soc *ipu, struct device *dev, priv->channels[i].base = priv->dc_reg + channel_offsets[i]; } - priv->dc_irq = ipu_map_irq(ipu, IPU_IRQ_DC_FC_1); - if (!priv->dc_irq) - return -EINVAL; - ret = devm_request_irq(dev, priv->dc_irq, dc_irq_handler, 0, NULL, - &priv->channels[1]); - if (ret < 0) - return ret; - disable_irq(priv->dc_irq); - priv->dp_irq = ipu_map_irq(ipu, IPU_IRQ_DP_SF_END); - if (!priv->dp_irq) - return -EINVAL; - ret = devm_request_irq(dev, priv->dp_irq, dc_irq_handler, 0, NULL, - &priv->channels[5]); - if (ret < 0) - return ret; - disable_irq(priv->dp_irq); - writel(DC_WR_CH_CONF_WORD_SIZE_24 | DC_WR_CH_CONF_DISP_ID_PARALLEL(1) | DC_WR_CH_CONF_PROG_DI_ID, priv->channels[1].base + DC_WR_CH_CONF); diff --git a/drivers/gpu/ipu-v3/ipu-dp.c b/drivers/gpu/ipu-v3/ipu-dp.c index 98686edbcdbb..9b2b3fa479c4 100644 --- a/drivers/gpu/ipu-v3/ipu-dp.c +++ b/drivers/gpu/ipu-v3/ipu-dp.c @@ -112,7 +112,7 @@ int ipu_dp_set_global_alpha(struct ipu_dp *dp, bool enable, writel(reg & ~DP_COM_CONF_GWAM, flow->base + DP_COM_CONF); } - ipu_srm_dp_sync_update(priv->ipu); + ipu_srm_dp_update(priv->ipu, true); mutex_unlock(&priv->mutex); @@ -127,7 +127,7 @@ int ipu_dp_set_window_pos(struct ipu_dp *dp, u16 x_pos, u16 y_pos) writel((x_pos << 16) | y_pos, flow->base + DP_FG_POS); - ipu_srm_dp_sync_update(priv->ipu); + ipu_srm_dp_update(priv->ipu, true); return 0; } @@ -207,7 +207,7 @@ int ipu_dp_setup_channel(struct ipu_dp *dp, flow->out_cs, DP_COM_CONF_CSC_DEF_FG); } - ipu_srm_dp_sync_update(priv->ipu); + ipu_srm_dp_update(priv->ipu, true); mutex_unlock(&priv->mutex); @@ -247,7 +247,7 @@ int ipu_dp_enable_channel(struct ipu_dp *dp) reg |= DP_COM_CONF_FG_EN; writel(reg, flow->base + DP_COM_CONF); - ipu_srm_dp_sync_update(priv->ipu); + ipu_srm_dp_update(priv->ipu, true); mutex_unlock(&priv->mutex); @@ -255,7 +255,7 @@ int ipu_dp_enable_channel(struct ipu_dp *dp) } EXPORT_SYMBOL_GPL(ipu_dp_enable_channel); -void ipu_dp_disable_channel(struct ipu_dp *dp) +void ipu_dp_disable_channel(struct ipu_dp *dp, bool sync) { struct ipu_flow *flow = to_flow(dp); struct ipu_dp_priv *priv = flow->priv; @@ -275,10 +275,7 @@ void ipu_dp_disable_channel(struct ipu_dp *dp) writel(reg, flow->base + DP_COM_CONF); writel(0, flow->base + DP_FG_POS); - ipu_srm_dp_sync_update(priv->ipu); - - if (ipu_idmac_channel_busy(priv->ipu, IPUV3_CHANNEL_MEM_BG_SYNC)) - ipu_wait_interrupt(priv->ipu, IPU_IRQ_DP_SF_END, 50); + ipu_srm_dp_update(priv->ipu, sync); mutex_unlock(&priv->mutex); } diff --git a/drivers/gpu/ipu-v3/ipu-prv.h b/drivers/gpu/ipu-v3/ipu-prv.h index 22e47b68b14a..285595702ee0 100644 --- a/drivers/gpu/ipu-v3/ipu-prv.h +++ b/drivers/gpu/ipu-v3/ipu-prv.h @@ -75,6 +75,11 @@ struct ipu_soc; #define IPU_INT_CTRL(n) IPU_CM_REG(0x003C + 4 * (n)) #define IPU_INT_STAT(n) IPU_CM_REG(0x0200 + 4 * (n)) +/* SRM_PRI2 */ +#define DP_S_SRM_MODE_MASK (0x3 << 3) +#define DP_S_SRM_MODE_NOW (0x3 << 3) +#define DP_S_SRM_MODE_NEXT_FRAME (0x1 << 3) + /* FS_PROC_FLOW1 */ #define FS_PRPENC_ROT_SRC_SEL_MASK (0xf << 0) #define FS_PRPENC_ROT_SRC_SEL_ENC (0x7 << 0) @@ -215,7 +220,7 @@ static inline void ipu_idmac_write(struct ipu_soc *ipu, u32 value, writel(value, ipu->idmac_reg + offset); } -void ipu_srm_dp_sync_update(struct ipu_soc *ipu); +void ipu_srm_dp_update(struct ipu_soc *ipu, bool sync); int ipu_module_enable(struct ipu_soc *ipu, u32 mask); int ipu_module_disable(struct ipu_soc *ipu, u32 mask); diff --git a/include/video/imx-ipu-v3.h b/include/video/imx-ipu-v3.h index 53cd07ccaa4c..899d2b00ad6d 100644 --- a/include/video/imx-ipu-v3.h +++ b/include/video/imx-ipu-v3.h @@ -300,7 +300,7 @@ struct ipu_dp *ipu_dp_get(struct ipu_soc *ipu, unsigned int flow); void ipu_dp_put(struct ipu_dp *); int ipu_dp_enable(struct ipu_soc *ipu); int ipu_dp_enable_channel(struct ipu_dp *dp); -void ipu_dp_disable_channel(struct ipu_dp *dp); +void ipu_dp_disable_channel(struct ipu_dp *dp, bool sync); void ipu_dp_disable(struct ipu_soc *ipu); int ipu_dp_setup_channel(struct ipu_dp *dp, enum ipu_color_space in, enum ipu_color_space out);
_______________________________________________ dri-devel mailing list dri-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/dri-devel