diff options
-rw-r--r-- | drivers/gpu/drm/imx/ipuv3-plane.c | 26 | ||||
-rw-r--r-- | drivers/gpu/ipu-v3/ipu-dmfc.c | 213 | ||||
-rw-r--r-- | include/video/imx-ipu-v3.h | 3 |
3 files changed, 7 insertions, 235 deletions
diff --git a/drivers/gpu/drm/imx/ipuv3-plane.c b/drivers/gpu/drm/imx/ipuv3-plane.c index cd7eb2658757..02701de370c7 100644 --- a/drivers/gpu/drm/imx/ipuv3-plane.c +++ b/drivers/gpu/drm/imx/ipuv3-plane.c @@ -53,24 +53,6 @@ int ipu_plane_irq(struct ipu_plane *ipu_plane) IPU_IRQ_EOF); } -static int calc_vref(struct drm_display_mode *mode) -{ - unsigned long htotal, vtotal; - - htotal = mode->htotal; - vtotal = mode->vtotal; - - if (!htotal || !vtotal) - return 60; - - return DIV_ROUND_UP(mode->clock * 1000, vtotal * htotal); -} - -static inline int calc_bandwidth(int width, int height, unsigned int vref) -{ - return width * height * vref; -} - int ipu_plane_set_base(struct ipu_plane *ipu_plane, struct drm_framebuffer *fb, int x, int y) { @@ -291,14 +273,6 @@ int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc, } } - ret = ipu_dmfc_alloc_bandwidth(ipu_plane->dmfc, - calc_bandwidth(crtc_w, crtc_h, - calc_vref(mode)), 64); - if (ret) { - dev_err(dev, "allocating dmfc bandwidth failed with %d\n", ret); - return ret; - } - ipu_dmfc_config_wait4eot(ipu_plane->dmfc, crtc_w); ipu_cpmem_zero(ipu_plane->ipu_ch); diff --git a/drivers/gpu/ipu-v3/ipu-dmfc.c b/drivers/gpu/ipu-v3/ipu-dmfc.c index 837b1ec22800..42705bb5aaa3 100644 --- a/drivers/gpu/ipu-v3/ipu-dmfc.c +++ b/drivers/gpu/ipu-v3/ipu-dmfc.c @@ -45,17 +45,6 @@ #define DMFC_DP_CHAN_6B_24 16 #define DMFC_DP_CHAN_6F_29 24 -#define DMFC_FIFO_SIZE_64 (3 << 3) -#define DMFC_FIFO_SIZE_128 (2 << 3) -#define DMFC_FIFO_SIZE_256 (1 << 3) -#define DMFC_FIFO_SIZE_512 (0 << 3) - -#define DMFC_SEGMENT(x) ((x & 0x7) << 0) -#define DMFC_BURSTSIZE_128 (0 << 6) -#define DMFC_BURSTSIZE_64 (1 << 6) -#define DMFC_BURSTSIZE_32 (2 << 6) -#define DMFC_BURSTSIZE_16 (3 << 6) - struct dmfc_channel_data { int ipu_channel; unsigned long channel_reg; @@ -104,9 +93,6 @@ struct ipu_dmfc_priv; struct dmfc_channel { unsigned slots; - unsigned slotmask; - unsigned segment; - int burstsize; struct ipu_soc *ipu; struct ipu_dmfc_priv *priv; const struct dmfc_channel_data *data; @@ -117,7 +103,6 @@ struct ipu_dmfc_priv { struct device *dev; struct dmfc_channel channels[DMFC_NUM_CHANNELS]; struct mutex mutex; - unsigned long bandwidth_per_slot; void __iomem *base; int use_count; }; @@ -172,184 +157,6 @@ void ipu_dmfc_disable_channel(struct dmfc_channel *dmfc) } EXPORT_SYMBOL_GPL(ipu_dmfc_disable_channel); -static int ipu_dmfc_setup_channel(struct dmfc_channel *dmfc, int slots, - int segment, int burstsize) -{ - struct ipu_dmfc_priv *priv = dmfc->priv; - u32 val, field; - - dev_dbg(priv->dev, - "dmfc: using %d slots starting from segment %d for IPU channel %d\n", - slots, segment, dmfc->data->ipu_channel); - - switch (slots) { - case 1: - field = DMFC_FIFO_SIZE_64; - break; - case 2: - field = DMFC_FIFO_SIZE_128; - break; - case 4: - field = DMFC_FIFO_SIZE_256; - break; - case 8: - field = DMFC_FIFO_SIZE_512; - break; - default: - return -EINVAL; - } - - switch (burstsize) { - case 16: - field |= DMFC_BURSTSIZE_16; - break; - case 32: - field |= DMFC_BURSTSIZE_32; - break; - case 64: - field |= DMFC_BURSTSIZE_64; - break; - case 128: - field |= DMFC_BURSTSIZE_128; - break; - } - - field |= DMFC_SEGMENT(segment); - - val = readl(priv->base + dmfc->data->channel_reg); - - val &= ~(0xff << dmfc->data->shift); - val |= field << dmfc->data->shift; - - writel(val, priv->base + dmfc->data->channel_reg); - - dmfc->slots = slots; - dmfc->segment = segment; - dmfc->burstsize = burstsize; - dmfc->slotmask = ((1 << slots) - 1) << segment; - - return 0; -} - -static int dmfc_bandwidth_to_slots(struct ipu_dmfc_priv *priv, - unsigned long bandwidth) -{ - int slots = 1; - - while (slots * priv->bandwidth_per_slot < bandwidth) - slots *= 2; - - return slots; -} - -static int dmfc_find_slots(struct ipu_dmfc_priv *priv, int slots) -{ - unsigned slotmask_need, slotmask_used = 0; - int i, segment = 0; - - slotmask_need = (1 << slots) - 1; - - for (i = 0; i < DMFC_NUM_CHANNELS; i++) - slotmask_used |= priv->channels[i].slotmask; - - while (slotmask_need <= 0xff) { - if (!(slotmask_used & slotmask_need)) - return segment; - - slotmask_need <<= 1; - segment++; - } - - return -EBUSY; -} - -void ipu_dmfc_free_bandwidth(struct dmfc_channel *dmfc) -{ - struct ipu_dmfc_priv *priv = dmfc->priv; - int i; - - dev_dbg(priv->dev, "dmfc: freeing %d slots starting from segment %d\n", - dmfc->slots, dmfc->segment); - - mutex_lock(&priv->mutex); - - if (!dmfc->slots) - goto out; - - dmfc->slotmask = 0; - dmfc->slots = 0; - dmfc->segment = 0; - - for (i = 0; i < DMFC_NUM_CHANNELS; i++) - priv->channels[i].slotmask = 0; - - for (i = 0; i < DMFC_NUM_CHANNELS; i++) { - if (priv->channels[i].slots > 0) { - priv->channels[i].segment = - dmfc_find_slots(priv, priv->channels[i].slots); - priv->channels[i].slotmask = - ((1 << priv->channels[i].slots) - 1) << - priv->channels[i].segment; - } - } - - for (i = 0; i < DMFC_NUM_CHANNELS; i++) { - if (priv->channels[i].slots > 0) - ipu_dmfc_setup_channel(&priv->channels[i], - priv->channels[i].slots, - priv->channels[i].segment, - priv->channels[i].burstsize); - } -out: - mutex_unlock(&priv->mutex); -} -EXPORT_SYMBOL_GPL(ipu_dmfc_free_bandwidth); - -int ipu_dmfc_alloc_bandwidth(struct dmfc_channel *dmfc, - unsigned long bandwidth_pixel_per_second, int burstsize) -{ - struct ipu_dmfc_priv *priv = dmfc->priv; - int slots = dmfc_bandwidth_to_slots(priv, bandwidth_pixel_per_second); - int segment = -1, ret = 0; - - dev_dbg(priv->dev, "dmfc: trying to allocate %ldMpixel/s for IPU channel %d\n", - bandwidth_pixel_per_second / 1000000, - dmfc->data->ipu_channel); - - ipu_dmfc_free_bandwidth(dmfc); - - mutex_lock(&priv->mutex); - - if (slots > 8) { - ret = -EBUSY; - goto out; - } - - /* For the MEM_BG channel, first try to allocate twice the slots */ - if (dmfc->data->ipu_channel == IPUV3_CHANNEL_MEM_BG_SYNC) - segment = dmfc_find_slots(priv, slots * 2); - else if (slots < 2) - /* Always allocate at least 128*4 bytes (2 slots) */ - slots = 2; - - if (segment >= 0) - slots *= 2; - else - segment = dmfc_find_slots(priv, slots); - if (segment < 0) { - ret = -EBUSY; - goto out; - } - - ipu_dmfc_setup_channel(dmfc, slots, segment, burstsize); - -out: - mutex_unlock(&priv->mutex); - - return ret; -} -EXPORT_SYMBOL_GPL(ipu_dmfc_alloc_bandwidth); - void ipu_dmfc_config_wait4eot(struct dmfc_channel *dmfc, int width) { struct ipu_dmfc_priv *priv = dmfc->priv; @@ -384,7 +191,6 @@ EXPORT_SYMBOL_GPL(ipu_dmfc_get); void ipu_dmfc_put(struct dmfc_channel *dmfc) { - ipu_dmfc_free_bandwidth(dmfc); } EXPORT_SYMBOL_GPL(ipu_dmfc_put); @@ -412,20 +218,15 @@ int ipu_dmfc_init(struct ipu_soc *ipu, struct device *dev, unsigned long base, priv->channels[i].priv = priv; priv->channels[i].ipu = ipu; priv->channels[i].data = &dmfcdata[i]; - } - - writel(0x0, priv->base + DMFC_WR_CHAN); - writel(0x0, priv->base + DMFC_DP_CHAN); - /* - * We have a total bandwidth of clkrate * 4pixel divided - * into 8 slots. - */ - priv->bandwidth_per_slot = clk_get_rate(ipu_clk) * 4 / 8; - - dev_dbg(dev, "dmfc: 8 slots with %ldMpixel/s bandwidth each\n", - priv->bandwidth_per_slot / 1000000); + if (dmfcdata[i].ipu_channel == IPUV3_CHANNEL_MEM_BG_SYNC || + dmfcdata[i].ipu_channel == IPUV3_CHANNEL_MEM_FG_SYNC || + dmfcdata[i].ipu_channel == IPUV3_CHANNEL_MEM_DC_SYNC) + priv->channels[i].slots = 2; + } + writel(0x00000050, priv->base + DMFC_WR_CHAN); + writel(0x00005654, priv->base + DMFC_DP_CHAN); writel(0x202020f6, priv->base + DMFC_WR_CHAN_DEF); writel(0x2020f6f6, priv->base + DMFC_DP_CHAN_DEF); writel(0x00000003, priv->base + DMFC_GENERAL1); diff --git a/include/video/imx-ipu-v3.h b/include/video/imx-ipu-v3.h index 3a2a79401789..7adeaae06961 100644 --- a/include/video/imx-ipu-v3.h +++ b/include/video/imx-ipu-v3.h @@ -235,9 +235,6 @@ int ipu_di_init_sync_panel(struct ipu_di *, struct ipu_di_signal_cfg *sig); struct dmfc_channel; int ipu_dmfc_enable_channel(struct dmfc_channel *dmfc); void ipu_dmfc_disable_channel(struct dmfc_channel *dmfc); -int ipu_dmfc_alloc_bandwidth(struct dmfc_channel *dmfc, - unsigned long bandwidth_mbs, int burstsize); -void ipu_dmfc_free_bandwidth(struct dmfc_channel *dmfc); void ipu_dmfc_config_wait4eot(struct dmfc_channel *dmfc, int width); struct dmfc_channel *ipu_dmfc_get(struct ipu_soc *ipu, int ipuv3_channel); void ipu_dmfc_put(struct dmfc_channel *dmfc); |