mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-30 12:49:36 +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);
|
||||
if (ret)
|
||||
return ret;
|
||||
drm->mode_config.min_width = KMB_MIN_WIDTH;
|
||||
drm->mode_config.min_height = KMB_MIN_HEIGHT;
|
||||
drm->mode_config.max_width = KMB_MAX_WIDTH;
|
||||
drm->mode_config.max_height = KMB_MAX_HEIGHT;
|
||||
drm->mode_config.min_width = KMB_FB_MIN_WIDTH;
|
||||
drm->mode_config.min_height = KMB_FB_MIN_HEIGHT;
|
||||
drm->mode_config.max_width = KMB_FB_MAX_WIDTH;
|
||||
drm->mode_config.max_height = KMB_FB_MAX_HEIGHT;
|
||||
drm->mode_config.funcs = &kmb_mode_config_funcs;
|
||||
|
||||
ret = kmb_setup_crtc(drm);
|
||||
|
|
|
@ -20,6 +20,11 @@
|
|||
#define DRIVER_MAJOR 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_SYS_CLK_MHZ 500
|
||||
|
||||
|
|
|
@ -94,9 +94,10 @@ static int kmb_plane_atomic_check(struct drm_plane *plane,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (new_plane_state->crtc_w > KMB_MAX_WIDTH || new_plane_state->crtc_h > KMB_MAX_HEIGHT)
|
||||
return -EINVAL;
|
||||
if (new_plane_state->crtc_w < KMB_MIN_WIDTH || new_plane_state->crtc_h < KMB_MIN_HEIGHT)
|
||||
if (new_plane_state->crtc_w > KMB_FB_MAX_WIDTH ||
|
||||
new_plane_state->crtc_h > KMB_FB_MAX_HEIGHT ||
|
||||
new_plane_state->crtc_w < KMB_FB_MIN_WIDTH ||
|
||||
new_plane_state->crtc_h < KMB_FB_MIN_HEIGHT)
|
||||
return -EINVAL;
|
||||
can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY);
|
||||
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]);
|
||||
}
|
||||
|
||||
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,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
|
@ -303,11 +342,12 @@ static void kmb_plane_atomic_update(struct drm_plane *plane,
|
|||
fb = new_plane_state->fb;
|
||||
if (!fb)
|
||||
return;
|
||||
|
||||
num_planes = fb->format->num_planes;
|
||||
kmb_plane = to_kmb_plane(plane);
|
||||
plane_id = kmb_plane->id;
|
||||
|
||||
kmb = to_kmb(plane->dev);
|
||||
plane_id = kmb_plane->id;
|
||||
|
||||
spin_lock_irq(&kmb->irq_lock);
|
||||
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);
|
||||
}
|
||||
|
||||
kmb_plane_set_alpha(kmb, plane->state, 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) {
|
||||
case LAYER_0:
|
||||
ctrl = LCD_CTRL_VL1_ENABLE;
|
||||
ctrl |= LCD_CTRL_VL1_ENABLE;
|
||||
break;
|
||||
case LAYER_1:
|
||||
ctrl = LCD_CTRL_VL2_ENABLE;
|
||||
ctrl |= LCD_CTRL_VL2_ENABLE;
|
||||
break;
|
||||
case LAYER_2:
|
||||
ctrl = LCD_CTRL_GL1_ENABLE;
|
||||
ctrl |= LCD_CTRL_GL1_ENABLE;
|
||||
break;
|
||||
case LAYER_3:
|
||||
ctrl = LCD_CTRL_GL2_ENABLE;
|
||||
ctrl |= LCD_CTRL_GL2_ENABLE;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -425,7 +477,7 @@ static void kmb_plane_atomic_update(struct drm_plane *plane,
|
|||
*/
|
||||
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
|
||||
* 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;
|
||||
const u32 *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++) {
|
||||
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",
|
||||
__func__, __LINE__,
|
||||
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,
|
||||
&kmb_plane_helper_funcs);
|
||||
|
||||
if (plane_type == DRM_PLANE_TYPE_PRIMARY) {
|
||||
primary = plane;
|
||||
kmb->plane = plane;
|
||||
|
|
|
@ -35,6 +35,9 @@
|
|||
#define POSSIBLE_CRTCS 1
|
||||
#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 {
|
||||
LAYER_0,
|
||||
LAYER_1,
|
||||
|
@ -43,8 +46,6 @@ enum layer_id {
|
|||
/* KMB_MAX_PLANES */
|
||||
};
|
||||
|
||||
#define KMB_MAX_PLANES 1
|
||||
|
||||
enum sub_plane_id {
|
||||
Y_PLANE,
|
||||
U_PLANE,
|
||||
|
|
|
@ -43,8 +43,10 @@
|
|||
#define LCD_CTRL_OUTPUT_ENABLED BIT(19)
|
||||
#define LCD_CTRL_BPORCH_ENABLE BIT(21)
|
||||
#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_VHSYNC_IDLE_LVL BIT(31)
|
||||
#define LCD_CTRL_ALPHA_ALL (0xff << 6)
|
||||
|
||||
/* interrupts */
|
||||
#define LCD_INT_STATUS (0x4 * 0x001)
|
||||
|
@ -115,6 +117,7 @@
|
|||
#define LCD_LAYER_ALPHA_EMBED BIT(5)
|
||||
#define LCD_LAYER_ALPHA_COMBI (LCD_LAYER_ALPHA_STATIC | \
|
||||
LCD_LAYER_ALPHA_EMBED)
|
||||
#define LCD_LAYER_ALPHA_DISABLED ~(LCD_LAYER_ALPHA_COMBI)
|
||||
/* RGB multiplied with alpha */
|
||||
#define LCD_LAYER_ALPHA_PREMULT BIT(6)
|
||||
#define LCD_LAYER_INVERT_COL BIT(7)
|
||||
|
|
Loading…
Reference in a new issue