diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-02 04:44:08 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-08-02 04:44:08 +0300 |
commit | 731c7d3a205ba89b475b2aa71b5f13dd6ae3de56 (patch) | |
tree | d2b9c3e0a98b94dfc3e4e60e35622c0143ef4ed4 /drivers/gpu/ipu-v3/ipu-dmfc.c | |
parent | 77a87824ed676ca8ff8482e4157d3adb284fd381 (diff) | |
parent | 753e7c8cbd8c503b962294303c7b5e9ea8513443 (diff) | |
download | linux-731c7d3a205ba89b475b2aa71b5f13dd6ae3de56.tar.xz |
Merge tag 'drm-for-v4.8' of git://people.freedesktop.org/~airlied/linux
Merge drm updates from Dave Airlie:
"This is the main drm pull request for 4.8.
I'm down with a cold at the moment so hopefully this isn't in too bad
a state, I finished pulling stuff last week mostly (nouveau fixes just
went in today), so only this message should be influenced by illness.
Apologies to anyone who's major feature I missed :-)
Core:
Lockless GEM BO freeing
Non-blocking atomic work
Documentation changes (rst/sphinx)
Prep for new fencing changes
Simple display helpers
Master/auth changes
Register/unregister rework
Loads of trivial patches/fixes.
New stuff:
ARM Mali display driver (not the 3D chip)
sii902x RGB->HDMI bridge
Panel:
Support for new panels
Improved backlight support
Bridge:
Convert ADV7511 to bridge driver
ADV7533 support
TC358767 (DSI/DPI to eDP) encoder chip support
i915:
BXT support enabled by default
GVT-g infrastructure
GuC command submission and fixes
BXT workarounds
SKL/BKL workarounds
Demidlayering device registration
Thundering herd fixes
Missing pci ids
Atomic updates
amdgpu/radeon:
ATPX improvements for better dGPU power control on PX systems
New power features for CZ/BR/ST
Pipelined BO moves and evictions in TTM
GPU scheduler improvements
GPU reset improvements
Overclocking on dGPUs with amdgpu
Polaris powermanagement enabled
nouveau:
GK20A/GM20B volt and clock improvements.
Initial support for GP100/GP104 GPUs, GP104 will not yet support
acceleration due to NVIDIA having not released firmware for them as of yet.
exynos:
Exynos5433 SoC with IOMMU support.
vc4:
Shader validation for branching
imx-drm:
Atomic mode setting conversion
Reworked DMFC FIFO allocation
External bridge support
analogix-dp:
RK3399 eDP support
Lots of fixes.
rockchip:
Lots of small fixes.
msm:
DT bindings cleanups
Shrinker and madvise support
ASoC HDMI codec support
tegra:
Host1x driver cleanups
SOR reworking for DP support
Runtime PM support
omapdrm:
PLL enhancements
Header refactoring
Gamma table support
arcgpu:
Simulator support
virtio-gpu:
Atomic modesetting fixes.
rcar-du:
Misc fixes.
mediatek:
MT8173 HDMI support
sti:
ASOC HDMI codec support
Minor fixes
fsl-dcu:
Suspend/resume support
Bridge support
amdkfd:
Minor fixes.
etnaviv:
Enable GPU clock gating
hisilicon:
Vblank and other fixes"
* tag 'drm-for-v4.8' of git://people.freedesktop.org/~airlied/linux: (1575 commits)
drm/nouveau/gr/nv3x: fix instobj write offsets in gr setup
drm/nouveau/acpi: fix lockup with PCIe runtime PM
drm/nouveau/acpi: check for function 0x1B before using it
drm/nouveau/acpi: return supported DSM functions
drm/nouveau/acpi: ensure matching ACPI handle and supported functions
drm/nouveau/fbcon: fix font width not divisible by 8
drm/amd/powerplay: remove enable_clock_power_gatings_tasks from initialize and resume events
drm/amd/powerplay: move clockgating to after ungating power in pp for uvd/vce
drm/amdgpu: add query device id and revision id into system info entry at CGS
drm/amdgpu: add new definition in bif header
drm/amd/powerplay: rename smum header guards
drm/amdgpu: enable UVD context buffer for older HW
drm/amdgpu: fix default UVD context size
drm/amdgpu: fix incorrect type of info_id
drm/amdgpu: make amdgpu_cgs_call_acpi_method as static
drm/amdgpu: comment out unused defaults_staturn_pro static const structure to fix the build
drm/amdgpu: enable UVD VM only on polaris
drm/amdgpu: increase timeout of IB test
drm/amdgpu: add destroy session when generate VCE destroy msg.
drm/amd: fix deadlock of job_list_lock V2
...
Diffstat (limited to 'drivers/gpu/ipu-v3/ipu-dmfc.c')
-rw-r--r-- | drivers/gpu/ipu-v3/ipu-dmfc.c | 213 |
1 files changed, 7 insertions, 206 deletions
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); |