forked from Minki/linux
drm etnaviv and exynos for rc1
-----BEGIN PGP SIGNATURE----- iQIcBAABAgAGBQJcJBeKAAoJEAx081l5xIa+6hYQAIpVqfcYBStXae/Ta4DhXTZ0 oAq685LhHOXrG2tsas50gw05w30g9GZUgcRcrbDiITdeiyoZfB0DNQY6bdc64+o8 X9EwGr4ZOK/Gm+Q6Z97FRTNARbKopm2RyNvZ4znn++Me7xrs32rx/SaL6ZAK9PpQ bqHeq1yMhJtOpj2eJZaUt2dcnY1fuQBx3saCR6B3sEDNEQpUwEISeThJvXsAhRB/ h9jO0yf9fb5wjO9alOIA3Nv7nB6h5XR+A6pyF396h8lUYZSTNBZL/Q6tPP1F6qSh l+SPLUI2U41ufkdGJfxmyWyt3b39TWslntCIUQF4FmZA3a7G+LsW8vihQqiZl8cv y6+Aoq5tA4uN9+mq0hRWS2bSXOLlxfRO8g58NRl+NhJG5T/i54vFAS/MfeR8zI+g dsjIYWRT4pu130qKP4Vj8iGpvSfvyqmZF5innlbJB3ruWOQf3pGFiuB6IghOindk trneV5homRCQgSwBHFx+YuOBNrYXeHUIyylyMB3IQXN02W7uLFmZUbwxBgiE1Aje cpy5OhOz39tDpDqSuJ0Lu7wjroqGEQ7DxIdCd2iq3ZpbStavqpiAtksaLa8dKVsl JrpJSZtF/0dYM7QZyGp3YHriL2FPR5TTiCzpdc+R8JDk3kraqV+pWAkpXxG6UK6a cjktD1xat7od4rGzQAcb =N74f -----END PGP SIGNATURE----- Merge tag 'drm-next-2018-12-27' of git://anongit.freedesktop.org/drm/drm Pull more drm updates from Dave Airlie: "Daniel collected a couple of pulls after I want on holidays, back for a couple of days, so may as well send them out. This has exynos and etnaviv work for 4.21. exynos: - plane alpha and blending configurability etnaviv: - mostly cleanups in prep for new features" * tag 'drm-next-2018-12-27' of git://anongit.freedesktop.org/drm/drm: drm/etnaviv: remove lastctx member from gpu struct drm/etnaviv: replace header include with forward declaration drm/etnaviv: remove unnecessary local irq disable drm/exynos: fimd: Make pixel blend mode configurable drm/exynos: fimd: Make plane alpha configurable drm/etnaviv: Replace drm_dev_unref with drm_dev_put drm/etnaviv: consolidate hardware fence handling in etnaviv_gpu drm/etnaviv: kill active fence tracking
This commit is contained in:
commit
7e59fad9c9
@ -439,6 +439,4 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
|
|||||||
|
|
||||||
if (drm_debug & DRM_UT_DRIVER)
|
if (drm_debug & DRM_UT_DRIVER)
|
||||||
etnaviv_buffer_dump(gpu, buffer, 0, 0x50);
|
etnaviv_buffer_dump(gpu, buffer, 0, 0x50);
|
||||||
|
|
||||||
gpu->lastctx = cmdbuf->ctx;
|
|
||||||
}
|
}
|
||||||
|
@ -72,14 +72,8 @@ static void etnaviv_postclose(struct drm_device *dev, struct drm_file *file)
|
|||||||
for (i = 0; i < ETNA_MAX_PIPES; i++) {
|
for (i = 0; i < ETNA_MAX_PIPES; i++) {
|
||||||
struct etnaviv_gpu *gpu = priv->gpu[i];
|
struct etnaviv_gpu *gpu = priv->gpu[i];
|
||||||
|
|
||||||
if (gpu) {
|
if (gpu)
|
||||||
mutex_lock(&gpu->lock);
|
|
||||||
if (gpu->lastctx == ctx)
|
|
||||||
gpu->lastctx = NULL;
|
|
||||||
mutex_unlock(&gpu->lock);
|
|
||||||
|
|
||||||
drm_sched_entity_destroy(&ctx->sched_entity[i]);
|
drm_sched_entity_destroy(&ctx->sched_entity[i]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
kfree(ctx);
|
kfree(ctx);
|
||||||
@ -523,7 +517,7 @@ static int etnaviv_bind(struct device *dev)
|
|||||||
if (!priv) {
|
if (!priv) {
|
||||||
dev_err(dev, "failed to allocate private data\n");
|
dev_err(dev, "failed to allocate private data\n");
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto out_unref;
|
goto out_put;
|
||||||
}
|
}
|
||||||
drm->dev_private = priv;
|
drm->dev_private = priv;
|
||||||
|
|
||||||
@ -549,7 +543,7 @@ out_register:
|
|||||||
component_unbind_all(dev, drm);
|
component_unbind_all(dev, drm);
|
||||||
out_bind:
|
out_bind:
|
||||||
kfree(priv);
|
kfree(priv);
|
||||||
out_unref:
|
out_put:
|
||||||
drm_dev_put(drm);
|
drm_dev_put(drm);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -107,17 +107,6 @@ static inline size_t size_vstruct(size_t nelem, size_t elem_size, size_t base)
|
|||||||
return base + nelem * elem_size;
|
return base + nelem * elem_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns true if fence a comes after fence b */
|
|
||||||
static inline bool fence_after(u32 a, u32 b)
|
|
||||||
{
|
|
||||||
return (s32)(a - b) > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool fence_after_eq(u32 a, u32 b)
|
|
||||||
{
|
|
||||||
return (s32)(a - b) >= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Etnaviv timeouts are specified wrt CLOCK_MONOTONIC, not jiffies.
|
* Etnaviv timeouts are specified wrt CLOCK_MONOTONIC, not jiffies.
|
||||||
* We need to calculate the timeout in terms of number of jiffies
|
* We need to calculate the timeout in terms of number of jiffies
|
||||||
|
@ -3,10 +3,12 @@
|
|||||||
* Copyright (C) 2015-2018 Etnaviv Project
|
* Copyright (C) 2015-2018 Etnaviv Project
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <linux/clk.h>
|
||||||
#include <linux/component.h>
|
#include <linux/component.h>
|
||||||
#include <linux/dma-fence.h>
|
#include <linux/dma-fence.h>
|
||||||
#include <linux/moduleparam.h>
|
#include <linux/moduleparam.h>
|
||||||
#include <linux/of_device.h>
|
#include <linux/of_device.h>
|
||||||
|
#include <linux/regulator/consumer.h>
|
||||||
#include <linux/thermal.h>
|
#include <linux/thermal.h>
|
||||||
|
|
||||||
#include "etnaviv_cmdbuf.h"
|
#include "etnaviv_cmdbuf.h"
|
||||||
@ -976,7 +978,6 @@ int etnaviv_gpu_debugfs(struct etnaviv_gpu *gpu, struct seq_file *m)
|
|||||||
|
|
||||||
void etnaviv_gpu_recover_hang(struct etnaviv_gpu *gpu)
|
void etnaviv_gpu_recover_hang(struct etnaviv_gpu *gpu)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
|
|
||||||
dev_err(gpu->dev, "recover hung GPU!\n");
|
dev_err(gpu->dev, "recover hung GPU!\n");
|
||||||
@ -989,15 +990,13 @@ void etnaviv_gpu_recover_hang(struct etnaviv_gpu *gpu)
|
|||||||
etnaviv_hw_reset(gpu);
|
etnaviv_hw_reset(gpu);
|
||||||
|
|
||||||
/* complete all events, the GPU won't do it after the reset */
|
/* complete all events, the GPU won't do it after the reset */
|
||||||
spin_lock_irqsave(&gpu->event_spinlock, flags);
|
spin_lock(&gpu->event_spinlock);
|
||||||
for_each_set_bit_from(i, gpu->event_bitmap, ETNA_NR_EVENTS)
|
for_each_set_bit_from(i, gpu->event_bitmap, ETNA_NR_EVENTS)
|
||||||
complete(&gpu->event_free);
|
complete(&gpu->event_free);
|
||||||
bitmap_zero(gpu->event_bitmap, ETNA_NR_EVENTS);
|
bitmap_zero(gpu->event_bitmap, ETNA_NR_EVENTS);
|
||||||
spin_unlock_irqrestore(&gpu->event_spinlock, flags);
|
spin_unlock(&gpu->event_spinlock);
|
||||||
gpu->completed_fence = gpu->active_fence;
|
|
||||||
|
|
||||||
etnaviv_gpu_hw_init(gpu);
|
etnaviv_gpu_hw_init(gpu);
|
||||||
gpu->lastctx = NULL;
|
|
||||||
gpu->exec_state = -1;
|
gpu->exec_state = -1;
|
||||||
|
|
||||||
mutex_unlock(&gpu->lock);
|
mutex_unlock(&gpu->lock);
|
||||||
@ -1032,7 +1031,7 @@ static bool etnaviv_fence_signaled(struct dma_fence *fence)
|
|||||||
{
|
{
|
||||||
struct etnaviv_fence *f = to_etnaviv_fence(fence);
|
struct etnaviv_fence *f = to_etnaviv_fence(fence);
|
||||||
|
|
||||||
return fence_completed(f->gpu, f->base.seqno);
|
return (s32)(f->gpu->completed_fence - f->base.seqno) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void etnaviv_fence_release(struct dma_fence *fence)
|
static void etnaviv_fence_release(struct dma_fence *fence)
|
||||||
@ -1071,6 +1070,12 @@ static struct dma_fence *etnaviv_gpu_fence_alloc(struct etnaviv_gpu *gpu)
|
|||||||
return &f->base;
|
return &f->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* returns true if fence a comes after fence b */
|
||||||
|
static inline bool fence_after(u32 a, u32 b)
|
||||||
|
{
|
||||||
|
return (s32)(a - b) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* event management:
|
* event management:
|
||||||
*/
|
*/
|
||||||
@ -1078,7 +1083,7 @@ static struct dma_fence *etnaviv_gpu_fence_alloc(struct etnaviv_gpu *gpu)
|
|||||||
static int event_alloc(struct etnaviv_gpu *gpu, unsigned nr_events,
|
static int event_alloc(struct etnaviv_gpu *gpu, unsigned nr_events,
|
||||||
unsigned int *events)
|
unsigned int *events)
|
||||||
{
|
{
|
||||||
unsigned long flags, timeout = msecs_to_jiffies(10 * 10000);
|
unsigned long timeout = msecs_to_jiffies(10 * 10000);
|
||||||
unsigned i, acquired = 0;
|
unsigned i, acquired = 0;
|
||||||
|
|
||||||
for (i = 0; i < nr_events; i++) {
|
for (i = 0; i < nr_events; i++) {
|
||||||
@ -1095,7 +1100,7 @@ static int event_alloc(struct etnaviv_gpu *gpu, unsigned nr_events,
|
|||||||
timeout = ret;
|
timeout = ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(&gpu->event_spinlock, flags);
|
spin_lock(&gpu->event_spinlock);
|
||||||
|
|
||||||
for (i = 0; i < nr_events; i++) {
|
for (i = 0; i < nr_events; i++) {
|
||||||
int event = find_first_zero_bit(gpu->event_bitmap, ETNA_NR_EVENTS);
|
int event = find_first_zero_bit(gpu->event_bitmap, ETNA_NR_EVENTS);
|
||||||
@ -1105,7 +1110,7 @@ static int event_alloc(struct etnaviv_gpu *gpu, unsigned nr_events,
|
|||||||
set_bit(event, gpu->event_bitmap);
|
set_bit(event, gpu->event_bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock_irqrestore(&gpu->event_spinlock, flags);
|
spin_unlock(&gpu->event_spinlock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -1118,18 +1123,11 @@ out:
|
|||||||
|
|
||||||
static void event_free(struct etnaviv_gpu *gpu, unsigned int event)
|
static void event_free(struct etnaviv_gpu *gpu, unsigned int event)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&gpu->event_spinlock, flags);
|
|
||||||
|
|
||||||
if (!test_bit(event, gpu->event_bitmap)) {
|
if (!test_bit(event, gpu->event_bitmap)) {
|
||||||
dev_warn(gpu->dev, "event %u is already marked as free",
|
dev_warn(gpu->dev, "event %u is already marked as free",
|
||||||
event);
|
event);
|
||||||
spin_unlock_irqrestore(&gpu->event_spinlock, flags);
|
|
||||||
} else {
|
} else {
|
||||||
clear_bit(event, gpu->event_bitmap);
|
clear_bit(event, gpu->event_bitmap);
|
||||||
spin_unlock_irqrestore(&gpu->event_spinlock, flags);
|
|
||||||
|
|
||||||
complete(&gpu->event_free);
|
complete(&gpu->event_free);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1306,8 +1304,6 @@ struct dma_fence *etnaviv_gpu_submit(struct etnaviv_gem_submit *submit)
|
|||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
gpu->active_fence = gpu_fence->seqno;
|
|
||||||
|
|
||||||
if (submit->nr_pmrs) {
|
if (submit->nr_pmrs) {
|
||||||
gpu->event[event[1]].sync_point = &sync_point_perfmon_sample_pre;
|
gpu->event[event[1]].sync_point = &sync_point_perfmon_sample_pre;
|
||||||
kref_get(&submit->refcount);
|
kref_get(&submit->refcount);
|
||||||
@ -1549,7 +1545,6 @@ static int etnaviv_gpu_hw_resume(struct etnaviv_gpu *gpu)
|
|||||||
etnaviv_gpu_update_clock(gpu);
|
etnaviv_gpu_update_clock(gpu);
|
||||||
etnaviv_gpu_hw_init(gpu);
|
etnaviv_gpu_hw_init(gpu);
|
||||||
|
|
||||||
gpu->lastctx = NULL;
|
|
||||||
gpu->exec_state = -1;
|
gpu->exec_state = -1;
|
||||||
|
|
||||||
mutex_unlock(&gpu->lock);
|
mutex_unlock(&gpu->lock);
|
||||||
@ -1806,8 +1801,8 @@ static int etnaviv_gpu_rpm_suspend(struct device *dev)
|
|||||||
struct etnaviv_gpu *gpu = dev_get_drvdata(dev);
|
struct etnaviv_gpu *gpu = dev_get_drvdata(dev);
|
||||||
u32 idle, mask;
|
u32 idle, mask;
|
||||||
|
|
||||||
/* If we have outstanding fences, we're not idle */
|
/* If there are any jobs in the HW queue, we're not idle */
|
||||||
if (gpu->completed_fence != gpu->active_fence)
|
if (atomic_read(&gpu->sched.hw_rq_count))
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
||||||
/* Check whether the hardware (except FE) is idle */
|
/* Check whether the hardware (except FE) is idle */
|
||||||
|
@ -6,9 +6,6 @@
|
|||||||
#ifndef __ETNAVIV_GPU_H__
|
#ifndef __ETNAVIV_GPU_H__
|
||||||
#define __ETNAVIV_GPU_H__
|
#define __ETNAVIV_GPU_H__
|
||||||
|
|
||||||
#include <linux/clk.h>
|
|
||||||
#include <linux/regulator/consumer.h>
|
|
||||||
|
|
||||||
#include "etnaviv_cmdbuf.h"
|
#include "etnaviv_cmdbuf.h"
|
||||||
#include "etnaviv_drv.h"
|
#include "etnaviv_drv.h"
|
||||||
|
|
||||||
@ -88,6 +85,8 @@ struct etnaviv_event {
|
|||||||
|
|
||||||
struct etnaviv_cmdbuf_suballoc;
|
struct etnaviv_cmdbuf_suballoc;
|
||||||
struct etnaviv_cmdbuf;
|
struct etnaviv_cmdbuf;
|
||||||
|
struct regulator;
|
||||||
|
struct clk;
|
||||||
|
|
||||||
#define ETNA_NR_EVENTS 30
|
#define ETNA_NR_EVENTS 30
|
||||||
|
|
||||||
@ -98,7 +97,6 @@ struct etnaviv_gpu {
|
|||||||
struct mutex lock;
|
struct mutex lock;
|
||||||
struct etnaviv_chip_identity identity;
|
struct etnaviv_chip_identity identity;
|
||||||
enum etnaviv_sec_mode sec_mode;
|
enum etnaviv_sec_mode sec_mode;
|
||||||
struct etnaviv_file_private *lastctx;
|
|
||||||
struct workqueue_struct *wq;
|
struct workqueue_struct *wq;
|
||||||
struct drm_gpu_scheduler sched;
|
struct drm_gpu_scheduler sched;
|
||||||
|
|
||||||
@ -121,7 +119,6 @@ struct etnaviv_gpu {
|
|||||||
struct mutex fence_lock;
|
struct mutex fence_lock;
|
||||||
struct idr fence_idr;
|
struct idr fence_idr;
|
||||||
u32 next_fence;
|
u32 next_fence;
|
||||||
u32 active_fence;
|
|
||||||
u32 completed_fence;
|
u32 completed_fence;
|
||||||
wait_queue_head_t fence_event;
|
wait_queue_head_t fence_event;
|
||||||
u64 fence_context;
|
u64 fence_context;
|
||||||
@ -161,11 +158,6 @@ static inline u32 gpu_read(struct etnaviv_gpu *gpu, u32 reg)
|
|||||||
return readl(gpu->mmio + reg);
|
return readl(gpu->mmio + reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool fence_completed(struct etnaviv_gpu *gpu, u32 fence)
|
|
||||||
{
|
|
||||||
return fence_after_eq(gpu->completed_fence, fence);
|
|
||||||
}
|
|
||||||
|
|
||||||
int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value);
|
int etnaviv_gpu_get_param(struct etnaviv_gpu *gpu, u32 param, u64 *value);
|
||||||
|
|
||||||
int etnaviv_gpu_init(struct etnaviv_gpu *gpu);
|
int etnaviv_gpu_init(struct etnaviv_gpu *gpu);
|
||||||
|
@ -228,6 +228,21 @@ static const uint32_t fimd_formats[] = {
|
|||||||
DRM_FORMAT_ARGB8888,
|
DRM_FORMAT_ARGB8888,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const unsigned int capabilities[WINDOWS_NR] = {
|
||||||
|
0,
|
||||||
|
EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
|
||||||
|
EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
|
||||||
|
EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
|
||||||
|
EXYNOS_DRM_PLANE_CAP_WIN_BLEND | EXYNOS_DRM_PLANE_CAP_PIX_BLEND,
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void fimd_set_bits(struct fimd_context *ctx, u32 reg, u32 mask,
|
||||||
|
u32 val)
|
||||||
|
{
|
||||||
|
val = (val & mask) | (readl(ctx->regs + reg) & ~mask);
|
||||||
|
writel(val, ctx->regs + reg);
|
||||||
|
}
|
||||||
|
|
||||||
static int fimd_enable_vblank(struct exynos_drm_crtc *crtc)
|
static int fimd_enable_vblank(struct exynos_drm_crtc *crtc)
|
||||||
{
|
{
|
||||||
struct fimd_context *ctx = crtc->ctx;
|
struct fimd_context *ctx = crtc->ctx;
|
||||||
@ -551,13 +566,88 @@ static void fimd_commit(struct exynos_drm_crtc *crtc)
|
|||||||
writel(val, ctx->regs + VIDCON0);
|
writel(val, ctx->regs + VIDCON0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fimd_win_set_bldeq(struct fimd_context *ctx, unsigned int win,
|
||||||
|
unsigned int alpha, unsigned int pixel_alpha)
|
||||||
|
{
|
||||||
|
u32 mask = BLENDEQ_A_FUNC_F(0xf) | BLENDEQ_B_FUNC_F(0xf);
|
||||||
|
u32 val = 0;
|
||||||
|
|
||||||
|
switch (pixel_alpha) {
|
||||||
|
case DRM_MODE_BLEND_PIXEL_NONE:
|
||||||
|
case DRM_MODE_BLEND_COVERAGE:
|
||||||
|
val |= BLENDEQ_A_FUNC_F(BLENDEQ_ALPHA_A);
|
||||||
|
val |= BLENDEQ_B_FUNC_F(BLENDEQ_ONE_MINUS_ALPHA_A);
|
||||||
|
break;
|
||||||
|
case DRM_MODE_BLEND_PREMULTI:
|
||||||
|
default:
|
||||||
|
if (alpha != DRM_BLEND_ALPHA_OPAQUE) {
|
||||||
|
val |= BLENDEQ_A_FUNC_F(BLENDEQ_ALPHA0);
|
||||||
|
val |= BLENDEQ_B_FUNC_F(BLENDEQ_ONE_MINUS_ALPHA_A);
|
||||||
|
} else {
|
||||||
|
val |= BLENDEQ_A_FUNC_F(BLENDEQ_ONE);
|
||||||
|
val |= BLENDEQ_B_FUNC_F(BLENDEQ_ONE_MINUS_ALPHA_A);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fimd_set_bits(ctx, BLENDEQx(win), mask, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fimd_win_set_bldmod(struct fimd_context *ctx, unsigned int win,
|
||||||
|
unsigned int alpha, unsigned int pixel_alpha)
|
||||||
|
{
|
||||||
|
u32 win_alpha_l = (alpha >> 8) & 0xf;
|
||||||
|
u32 win_alpha_h = alpha >> 12;
|
||||||
|
u32 val = 0;
|
||||||
|
|
||||||
|
switch (pixel_alpha) {
|
||||||
|
case DRM_MODE_BLEND_PIXEL_NONE:
|
||||||
|
break;
|
||||||
|
case DRM_MODE_BLEND_COVERAGE:
|
||||||
|
case DRM_MODE_BLEND_PREMULTI:
|
||||||
|
default:
|
||||||
|
val |= WINCON1_ALPHA_SEL;
|
||||||
|
val |= WINCON1_BLD_PIX;
|
||||||
|
val |= WINCON1_ALPHA_MUL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fimd_set_bits(ctx, WINCON(win), WINCONx_BLEND_MODE_MASK, val);
|
||||||
|
|
||||||
|
/* OSD alpha */
|
||||||
|
val = VIDISD14C_ALPHA0_R(win_alpha_h) |
|
||||||
|
VIDISD14C_ALPHA0_G(win_alpha_h) |
|
||||||
|
VIDISD14C_ALPHA0_B(win_alpha_h) |
|
||||||
|
VIDISD14C_ALPHA1_R(0x0) |
|
||||||
|
VIDISD14C_ALPHA1_G(0x0) |
|
||||||
|
VIDISD14C_ALPHA1_B(0x0);
|
||||||
|
writel(val, ctx->regs + VIDOSD_C(win));
|
||||||
|
|
||||||
|
val = VIDW_ALPHA_R(win_alpha_l) | VIDW_ALPHA_G(win_alpha_l) |
|
||||||
|
VIDW_ALPHA_B(win_alpha_l);
|
||||||
|
writel(val, ctx->regs + VIDWnALPHA0(win));
|
||||||
|
|
||||||
|
val = VIDW_ALPHA_R(0x0) | VIDW_ALPHA_G(0x0) |
|
||||||
|
VIDW_ALPHA_B(0x0);
|
||||||
|
writel(val, ctx->regs + VIDWnALPHA1(win));
|
||||||
|
|
||||||
|
fimd_set_bits(ctx, BLENDCON, BLENDCON_NEW_MASK,
|
||||||
|
BLENDCON_NEW_8BIT_ALPHA_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win,
|
static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win,
|
||||||
uint32_t pixel_format, int width)
|
struct drm_framebuffer *fb, int width)
|
||||||
{
|
{
|
||||||
unsigned long val;
|
struct exynos_drm_plane plane = ctx->planes[win];
|
||||||
|
struct exynos_drm_plane_state *state =
|
||||||
|
to_exynos_plane_state(plane.base.state);
|
||||||
|
uint32_t pixel_format = fb->format->format;
|
||||||
|
unsigned int alpha = state->base.alpha;
|
||||||
|
u32 val = WINCONx_ENWIN;
|
||||||
|
unsigned int pixel_alpha;
|
||||||
|
|
||||||
val = WINCONx_ENWIN;
|
if (fb->format->has_alpha)
|
||||||
|
pixel_alpha = state->base.pixel_blend_mode;
|
||||||
|
else
|
||||||
|
pixel_alpha = DRM_MODE_BLEND_PIXEL_NONE;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In case of s3c64xx, window 0 doesn't support alpha channel.
|
* In case of s3c64xx, window 0 doesn't support alpha channel.
|
||||||
@ -591,8 +681,7 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win,
|
|||||||
break;
|
break;
|
||||||
case DRM_FORMAT_ARGB8888:
|
case DRM_FORMAT_ARGB8888:
|
||||||
default:
|
default:
|
||||||
val |= WINCON1_BPPMODE_25BPP_A1888
|
val |= WINCON1_BPPMODE_25BPP_A1888;
|
||||||
| WINCON1_BLD_PIX | WINCON1_ALPHA_SEL;
|
|
||||||
val |= WINCONx_WSWP;
|
val |= WINCONx_WSWP;
|
||||||
val |= WINCONx_BURSTLEN_16WORD;
|
val |= WINCONx_BURSTLEN_16WORD;
|
||||||
break;
|
break;
|
||||||
@ -610,25 +699,12 @@ static void fimd_win_set_pixfmt(struct fimd_context *ctx, unsigned int win,
|
|||||||
val &= ~WINCONx_BURSTLEN_MASK;
|
val &= ~WINCONx_BURSTLEN_MASK;
|
||||||
val |= WINCONx_BURSTLEN_4WORD;
|
val |= WINCONx_BURSTLEN_4WORD;
|
||||||
}
|
}
|
||||||
|
fimd_set_bits(ctx, WINCON(win), ~WINCONx_BLEND_MODE_MASK, val);
|
||||||
writel(val, ctx->regs + WINCON(win));
|
|
||||||
|
|
||||||
/* hardware window 0 doesn't support alpha channel. */
|
/* hardware window 0 doesn't support alpha channel. */
|
||||||
if (win != 0) {
|
if (win != 0) {
|
||||||
/* OSD alpha */
|
fimd_win_set_bldmod(ctx, win, alpha, pixel_alpha);
|
||||||
val = VIDISD14C_ALPHA0_R(0xf) |
|
fimd_win_set_bldeq(ctx, win, alpha, pixel_alpha);
|
||||||
VIDISD14C_ALPHA0_G(0xf) |
|
|
||||||
VIDISD14C_ALPHA0_B(0xf) |
|
|
||||||
VIDISD14C_ALPHA1_R(0xf) |
|
|
||||||
VIDISD14C_ALPHA1_G(0xf) |
|
|
||||||
VIDISD14C_ALPHA1_B(0xf);
|
|
||||||
|
|
||||||
writel(val, ctx->regs + VIDOSD_C(win));
|
|
||||||
|
|
||||||
val = VIDW_ALPHA_R(0xf) | VIDW_ALPHA_G(0xf) |
|
|
||||||
VIDW_ALPHA_G(0xf);
|
|
||||||
writel(val, ctx->regs + VIDWnALPHA0(win));
|
|
||||||
writel(val, ctx->regs + VIDWnALPHA1(win));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -785,7 +861,7 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
|
|||||||
DRM_DEBUG_KMS("osd size = 0x%x\n", (unsigned int)val);
|
DRM_DEBUG_KMS("osd size = 0x%x\n", (unsigned int)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
fimd_win_set_pixfmt(ctx, win, fb->format->format, state->src.w);
|
fimd_win_set_pixfmt(ctx, win, fb, state->src.w);
|
||||||
|
|
||||||
/* hardware window 0 doesn't support color key. */
|
/* hardware window 0 doesn't support color key. */
|
||||||
if (win != 0)
|
if (win != 0)
|
||||||
@ -987,6 +1063,7 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
|
|||||||
ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_formats);
|
ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_formats);
|
||||||
ctx->configs[i].zpos = i;
|
ctx->configs[i].zpos = i;
|
||||||
ctx->configs[i].type = fimd_win_types[i];
|
ctx->configs[i].type = fimd_win_types[i];
|
||||||
|
ctx->configs[i].capabilities = capabilities[i];
|
||||||
ret = exynos_plane_init(drm_dev, &ctx->planes[i], i,
|
ret = exynos_plane_init(drm_dev, &ctx->planes[i], i,
|
||||||
&ctx->configs[i]);
|
&ctx->configs[i]);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -198,6 +198,7 @@
|
|||||||
#define WINCONx_BURSTLEN_8WORD (0x1 << 9)
|
#define WINCONx_BURSTLEN_8WORD (0x1 << 9)
|
||||||
#define WINCONx_BURSTLEN_4WORD (0x2 << 9)
|
#define WINCONx_BURSTLEN_4WORD (0x2 << 9)
|
||||||
#define WINCONx_ENWIN (1 << 0)
|
#define WINCONx_ENWIN (1 << 0)
|
||||||
|
#define WINCONx_BLEND_MODE_MASK (0xc2)
|
||||||
|
|
||||||
#define WINCON0_BPPMODE_MASK (0xf << 2)
|
#define WINCON0_BPPMODE_MASK (0xf << 2)
|
||||||
#define WINCON0_BPPMODE_SHIFT 2
|
#define WINCON0_BPPMODE_SHIFT 2
|
||||||
@ -211,6 +212,7 @@
|
|||||||
#define WINCON0_BPPMODE_24BPP_888 (0xb << 2)
|
#define WINCON0_BPPMODE_24BPP_888 (0xb << 2)
|
||||||
|
|
||||||
#define WINCON1_LOCALSEL_CAMIF (1 << 23)
|
#define WINCON1_LOCALSEL_CAMIF (1 << 23)
|
||||||
|
#define WINCON1_ALPHA_MUL (1 << 7)
|
||||||
#define WINCON1_BLD_PIX (1 << 6)
|
#define WINCON1_BLD_PIX (1 << 6)
|
||||||
#define WINCON1_BPPMODE_MASK (0xf << 2)
|
#define WINCON1_BPPMODE_MASK (0xf << 2)
|
||||||
#define WINCON1_BPPMODE_SHIFT 2
|
#define WINCON1_BPPMODE_SHIFT 2
|
||||||
@ -437,6 +439,14 @@
|
|||||||
#define WPALCON_W0PAL_16BPP_565 (0x6 << 0)
|
#define WPALCON_W0PAL_16BPP_565 (0x6 << 0)
|
||||||
|
|
||||||
/* Blending equation control */
|
/* Blending equation control */
|
||||||
|
#define BLENDEQx(_win) (0x244 + ((_win - 1) * 4))
|
||||||
|
#define BLENDEQ_ZERO 0x0
|
||||||
|
#define BLENDEQ_ONE 0x1
|
||||||
|
#define BLENDEQ_ALPHA_A 0x2
|
||||||
|
#define BLENDEQ_ONE_MINUS_ALPHA_A 0x3
|
||||||
|
#define BLENDEQ_ALPHA0 0x6
|
||||||
|
#define BLENDEQ_B_FUNC_F(_x) (_x << 6)
|
||||||
|
#define BLENDEQ_A_FUNC_F(_x) (_x << 0)
|
||||||
#define BLENDCON 0x260
|
#define BLENDCON 0x260
|
||||||
#define BLENDCON_NEW_MASK (1 << 0)
|
#define BLENDCON_NEW_MASK (1 << 0)
|
||||||
#define BLENDCON_NEW_8BIT_ALPHA_VALUE (1 << 0)
|
#define BLENDCON_NEW_8BIT_ALPHA_VALUE (1 << 0)
|
||||||
|
Loading…
Reference in New Issue
Block a user