mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-14 06:35:12 +00:00
drm/kmb: Enable alpha blended second plane
Enable one additional plane that is alpha blended on top of the primary plane. This also fixes the below warnings when building with -Warray-bounds: drivers/gpu/drm/kmb/kmb_plane.c:135:20: warning: array subscript 3 is above array bounds of 'struct layer_status[1]' [-Warray-bounds] drivers/gpu/drm/kmb/kmb_plane.c:132:20: warning: array subscript 2 is above array bounds of 'struct layer_status[1]' [-Warray-bounds] drivers/gpu/drm/kmb/kmb_plane.c:129:20: warning: array subscript 1 is above array bounds of 'struct layer_status[1]' [-Warray-bounds] v2: corrected previous patch dependecies so it builds Signed-off-by: Edmund Dea <edmund.j.dea@intel.com> Signed-off-by: Anitha Chrisanthus <anitha.chrisanthus@intel.com> Acked-by: Sam Ravnborg <sam@ravnborg.org> Link: https://patchwork.kernel.org/project/dri-devel/patch/20210728003126.1425028-13-anitha.chrisanthus@intel.com/ Signed-off-by: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
This commit is contained in:
parent
9e1ff307c7
commit
c026565fe9
5 changed files with 87 additions and 15 deletions
|
@ -172,10 +172,10 @@ static int kmb_setup_mode_config(struct drm_device *drm)
|
||||||
ret = drmm_mode_config_init(drm);
|
ret = drmm_mode_config_init(drm);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
drm->mode_config.min_width = KMB_MIN_WIDTH;
|
drm->mode_config.min_width = KMB_FB_MIN_WIDTH;
|
||||||
drm->mode_config.min_height = KMB_MIN_HEIGHT;
|
drm->mode_config.min_height = KMB_FB_MIN_HEIGHT;
|
||||||
drm->mode_config.max_width = KMB_MAX_WIDTH;
|
drm->mode_config.max_width = KMB_FB_MAX_WIDTH;
|
||||||
drm->mode_config.max_height = KMB_MAX_HEIGHT;
|
drm->mode_config.max_height = KMB_FB_MAX_HEIGHT;
|
||||||
drm->mode_config.funcs = &kmb_mode_config_funcs;
|
drm->mode_config.funcs = &kmb_mode_config_funcs;
|
||||||
|
|
||||||
ret = kmb_setup_crtc(drm);
|
ret = kmb_setup_crtc(drm);
|
||||||
|
|
|
@ -20,6 +20,11 @@
|
||||||
#define DRIVER_MAJOR 1
|
#define DRIVER_MAJOR 1
|
||||||
#define DRIVER_MINOR 1
|
#define DRIVER_MINOR 1
|
||||||
|
|
||||||
|
#define KMB_FB_MAX_WIDTH 1920
|
||||||
|
#define KMB_FB_MAX_HEIGHT 1080
|
||||||
|
#define KMB_FB_MIN_WIDTH 1
|
||||||
|
#define KMB_FB_MIN_HEIGHT 1
|
||||||
|
|
||||||
#define KMB_LCD_DEFAULT_CLK 200000000
|
#define KMB_LCD_DEFAULT_CLK 200000000
|
||||||
#define KMB_SYS_CLK_MHZ 500
|
#define KMB_SYS_CLK_MHZ 500
|
||||||
|
|
||||||
|
|
|
@ -94,9 +94,10 @@ static int kmb_plane_atomic_check(struct drm_plane *plane,
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
if (new_plane_state->crtc_w > KMB_MAX_WIDTH || new_plane_state->crtc_h > KMB_MAX_HEIGHT)
|
if (new_plane_state->crtc_w > KMB_FB_MAX_WIDTH ||
|
||||||
return -EINVAL;
|
new_plane_state->crtc_h > KMB_FB_MAX_HEIGHT ||
|
||||||
if (new_plane_state->crtc_w < KMB_MIN_WIDTH || new_plane_state->crtc_h < KMB_MIN_HEIGHT)
|
new_plane_state->crtc_w < KMB_FB_MIN_WIDTH ||
|
||||||
|
new_plane_state->crtc_h < KMB_FB_MIN_HEIGHT)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY);
|
can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY);
|
||||||
crtc_state =
|
crtc_state =
|
||||||
|
@ -277,6 +278,44 @@ static void config_csc(struct kmb_drm_private *kmb, int plane_id)
|
||||||
kmb_write_lcd(kmb, LCD_LAYERn_CSC_OFF3(plane_id), csc_coef_lcd[11]);
|
kmb_write_lcd(kmb, LCD_LAYERn_CSC_OFF3(plane_id), csc_coef_lcd[11]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void kmb_plane_set_alpha(struct kmb_drm_private *kmb,
|
||||||
|
const struct drm_plane_state *state,
|
||||||
|
unsigned char plane_id,
|
||||||
|
unsigned int *val)
|
||||||
|
{
|
||||||
|
u16 plane_alpha = state->alpha;
|
||||||
|
u16 pixel_blend_mode = state->pixel_blend_mode;
|
||||||
|
int has_alpha = state->fb->format->has_alpha;
|
||||||
|
|
||||||
|
if (plane_alpha != DRM_BLEND_ALPHA_OPAQUE)
|
||||||
|
*val |= LCD_LAYER_ALPHA_STATIC;
|
||||||
|
|
||||||
|
if (has_alpha) {
|
||||||
|
switch (pixel_blend_mode) {
|
||||||
|
case DRM_MODE_BLEND_PIXEL_NONE:
|
||||||
|
break;
|
||||||
|
case DRM_MODE_BLEND_PREMULTI:
|
||||||
|
*val |= LCD_LAYER_ALPHA_EMBED | LCD_LAYER_ALPHA_PREMULT;
|
||||||
|
break;
|
||||||
|
case DRM_MODE_BLEND_COVERAGE:
|
||||||
|
*val |= LCD_LAYER_ALPHA_EMBED;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
DRM_DEBUG("Missing pixel blend mode case (%s == %ld)\n",
|
||||||
|
__stringify(pixel_blend_mode),
|
||||||
|
(long)pixel_blend_mode);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plane_alpha == DRM_BLEND_ALPHA_OPAQUE && !has_alpha) {
|
||||||
|
*val &= LCD_LAYER_ALPHA_DISABLED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
kmb_write_lcd(kmb, LCD_LAYERn_ALPHA(plane_id), plane_alpha);
|
||||||
|
}
|
||||||
|
|
||||||
static void kmb_plane_atomic_update(struct drm_plane *plane,
|
static void kmb_plane_atomic_update(struct drm_plane *plane,
|
||||||
struct drm_atomic_state *state)
|
struct drm_atomic_state *state)
|
||||||
{
|
{
|
||||||
|
@ -303,11 +342,12 @@ static void kmb_plane_atomic_update(struct drm_plane *plane,
|
||||||
fb = new_plane_state->fb;
|
fb = new_plane_state->fb;
|
||||||
if (!fb)
|
if (!fb)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
num_planes = fb->format->num_planes;
|
num_planes = fb->format->num_planes;
|
||||||
kmb_plane = to_kmb_plane(plane);
|
kmb_plane = to_kmb_plane(plane);
|
||||||
plane_id = kmb_plane->id;
|
|
||||||
|
|
||||||
kmb = to_kmb(plane->dev);
|
kmb = to_kmb(plane->dev);
|
||||||
|
plane_id = kmb_plane->id;
|
||||||
|
|
||||||
spin_lock_irq(&kmb->irq_lock);
|
spin_lock_irq(&kmb->irq_lock);
|
||||||
if (kmb->kmb_under_flow || kmb->kmb_flush_done) {
|
if (kmb->kmb_under_flow || kmb->kmb_flush_done) {
|
||||||
|
@ -400,20 +440,32 @@ static void kmb_plane_atomic_update(struct drm_plane *plane,
|
||||||
config_csc(kmb, plane_id);
|
config_csc(kmb, plane_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kmb_plane_set_alpha(kmb, plane->state, plane_id, &val);
|
||||||
|
|
||||||
kmb_write_lcd(kmb, LCD_LAYERn_CFG(plane_id), val);
|
kmb_write_lcd(kmb, LCD_LAYERn_CFG(plane_id), val);
|
||||||
|
|
||||||
|
/* Configure LCD_CONTROL */
|
||||||
|
ctrl = kmb_read_lcd(kmb, LCD_CONTROL);
|
||||||
|
|
||||||
|
/* Set layer blending config */
|
||||||
|
ctrl &= ~LCD_CTRL_ALPHA_ALL;
|
||||||
|
ctrl |= LCD_CTRL_ALPHA_BOTTOM_VL1 |
|
||||||
|
LCD_CTRL_ALPHA_BLEND_VL2;
|
||||||
|
|
||||||
|
ctrl &= ~LCD_CTRL_ALPHA_BLEND_BKGND_DISABLE;
|
||||||
|
|
||||||
switch (plane_id) {
|
switch (plane_id) {
|
||||||
case LAYER_0:
|
case LAYER_0:
|
||||||
ctrl = LCD_CTRL_VL1_ENABLE;
|
ctrl |= LCD_CTRL_VL1_ENABLE;
|
||||||
break;
|
break;
|
||||||
case LAYER_1:
|
case LAYER_1:
|
||||||
ctrl = LCD_CTRL_VL2_ENABLE;
|
ctrl |= LCD_CTRL_VL2_ENABLE;
|
||||||
break;
|
break;
|
||||||
case LAYER_2:
|
case LAYER_2:
|
||||||
ctrl = LCD_CTRL_GL1_ENABLE;
|
ctrl |= LCD_CTRL_GL1_ENABLE;
|
||||||
break;
|
break;
|
||||||
case LAYER_3:
|
case LAYER_3:
|
||||||
ctrl = LCD_CTRL_GL2_ENABLE;
|
ctrl |= LCD_CTRL_GL2_ENABLE;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -425,7 +477,7 @@ static void kmb_plane_atomic_update(struct drm_plane *plane,
|
||||||
*/
|
*/
|
||||||
ctrl |= LCD_CTRL_VHSYNC_IDLE_LVL;
|
ctrl |= LCD_CTRL_VHSYNC_IDLE_LVL;
|
||||||
|
|
||||||
kmb_set_bitmask_lcd(kmb, LCD_CONTROL, ctrl);
|
kmb_write_lcd(kmb, LCD_CONTROL, ctrl);
|
||||||
|
|
||||||
/* Enable pipeline AXI read transactions for the DMA
|
/* Enable pipeline AXI read transactions for the DMA
|
||||||
* after setting graphics layers. This must be done
|
* after setting graphics layers. This must be done
|
||||||
|
@ -490,6 +542,9 @@ struct kmb_plane *kmb_plane_init(struct drm_device *drm)
|
||||||
enum drm_plane_type plane_type;
|
enum drm_plane_type plane_type;
|
||||||
const u32 *plane_formats;
|
const u32 *plane_formats;
|
||||||
int num_plane_formats;
|
int num_plane_formats;
|
||||||
|
unsigned int blend_caps = BIT(DRM_MODE_BLEND_PIXEL_NONE) |
|
||||||
|
BIT(DRM_MODE_BLEND_PREMULTI) |
|
||||||
|
BIT(DRM_MODE_BLEND_COVERAGE);
|
||||||
|
|
||||||
for (i = 0; i < KMB_MAX_PLANES; i++) {
|
for (i = 0; i < KMB_MAX_PLANES; i++) {
|
||||||
plane = drmm_kzalloc(drm, sizeof(*plane), GFP_KERNEL);
|
plane = drmm_kzalloc(drm, sizeof(*plane), GFP_KERNEL);
|
||||||
|
@ -521,8 +576,16 @@ struct kmb_plane *kmb_plane_init(struct drm_device *drm)
|
||||||
drm_dbg(drm, "%s : %d i=%d type=%d",
|
drm_dbg(drm, "%s : %d i=%d type=%d",
|
||||||
__func__, __LINE__,
|
__func__, __LINE__,
|
||||||
i, plane_type);
|
i, plane_type);
|
||||||
|
drm_plane_create_alpha_property(&plane->base_plane);
|
||||||
|
|
||||||
|
drm_plane_create_blend_mode_property(&plane->base_plane,
|
||||||
|
blend_caps);
|
||||||
|
|
||||||
|
drm_plane_create_zpos_immutable_property(&plane->base_plane, i);
|
||||||
|
|
||||||
drm_plane_helper_add(&plane->base_plane,
|
drm_plane_helper_add(&plane->base_plane,
|
||||||
&kmb_plane_helper_funcs);
|
&kmb_plane_helper_funcs);
|
||||||
|
|
||||||
if (plane_type == DRM_PLANE_TYPE_PRIMARY) {
|
if (plane_type == DRM_PLANE_TYPE_PRIMARY) {
|
||||||
primary = plane;
|
primary = plane;
|
||||||
kmb->plane = plane;
|
kmb->plane = plane;
|
||||||
|
|
|
@ -35,6 +35,9 @@
|
||||||
#define POSSIBLE_CRTCS 1
|
#define POSSIBLE_CRTCS 1
|
||||||
#define to_kmb_plane(x) container_of(x, struct kmb_plane, base_plane)
|
#define to_kmb_plane(x) container_of(x, struct kmb_plane, base_plane)
|
||||||
|
|
||||||
|
#define POSSIBLE_CRTCS 1
|
||||||
|
#define KMB_MAX_PLANES 2
|
||||||
|
|
||||||
enum layer_id {
|
enum layer_id {
|
||||||
LAYER_0,
|
LAYER_0,
|
||||||
LAYER_1,
|
LAYER_1,
|
||||||
|
@ -43,8 +46,6 @@ enum layer_id {
|
||||||
/* KMB_MAX_PLANES */
|
/* KMB_MAX_PLANES */
|
||||||
};
|
};
|
||||||
|
|
||||||
#define KMB_MAX_PLANES 1
|
|
||||||
|
|
||||||
enum sub_plane_id {
|
enum sub_plane_id {
|
||||||
Y_PLANE,
|
Y_PLANE,
|
||||||
U_PLANE,
|
U_PLANE,
|
||||||
|
|
|
@ -43,8 +43,10 @@
|
||||||
#define LCD_CTRL_OUTPUT_ENABLED BIT(19)
|
#define LCD_CTRL_OUTPUT_ENABLED BIT(19)
|
||||||
#define LCD_CTRL_BPORCH_ENABLE BIT(21)
|
#define LCD_CTRL_BPORCH_ENABLE BIT(21)
|
||||||
#define LCD_CTRL_FPORCH_ENABLE BIT(22)
|
#define LCD_CTRL_FPORCH_ENABLE BIT(22)
|
||||||
|
#define LCD_CTRL_ALPHA_BLEND_BKGND_DISABLE BIT(23)
|
||||||
#define LCD_CTRL_PIPELINE_DMA BIT(28)
|
#define LCD_CTRL_PIPELINE_DMA BIT(28)
|
||||||
#define LCD_CTRL_VHSYNC_IDLE_LVL BIT(31)
|
#define LCD_CTRL_VHSYNC_IDLE_LVL BIT(31)
|
||||||
|
#define LCD_CTRL_ALPHA_ALL (0xff << 6)
|
||||||
|
|
||||||
/* interrupts */
|
/* interrupts */
|
||||||
#define LCD_INT_STATUS (0x4 * 0x001)
|
#define LCD_INT_STATUS (0x4 * 0x001)
|
||||||
|
@ -115,6 +117,7 @@
|
||||||
#define LCD_LAYER_ALPHA_EMBED BIT(5)
|
#define LCD_LAYER_ALPHA_EMBED BIT(5)
|
||||||
#define LCD_LAYER_ALPHA_COMBI (LCD_LAYER_ALPHA_STATIC | \
|
#define LCD_LAYER_ALPHA_COMBI (LCD_LAYER_ALPHA_STATIC | \
|
||||||
LCD_LAYER_ALPHA_EMBED)
|
LCD_LAYER_ALPHA_EMBED)
|
||||||
|
#define LCD_LAYER_ALPHA_DISABLED ~(LCD_LAYER_ALPHA_COMBI)
|
||||||
/* RGB multiplied with alpha */
|
/* RGB multiplied with alpha */
|
||||||
#define LCD_LAYER_ALPHA_PREMULT BIT(6)
|
#define LCD_LAYER_ALPHA_PREMULT BIT(6)
|
||||||
#define LCD_LAYER_INVERT_COL BIT(7)
|
#define LCD_LAYER_INVERT_COL BIT(7)
|
||||||
|
|
Loading…
Reference in a new issue