161f1c4a8Sjames qian wang (Arm Technology China) // SPDX-License-Identifier: GPL-2.0 261f1c4a8Sjames qian wang (Arm Technology China) /* 361f1c4a8Sjames qian wang (Arm Technology China) * (C) COPYRIGHT 2018 ARM Limited. All rights reserved. 461f1c4a8Sjames qian wang (Arm Technology China) * Author: James.Qian.Wang <james.qian.wang@arm.com> 561f1c4a8Sjames qian wang (Arm Technology China) * 661f1c4a8Sjames qian wang (Arm Technology China) */ 761f1c4a8Sjames qian wang (Arm Technology China) #include <drm/drm_atomic.h> 861f1c4a8Sjames qian wang (Arm Technology China) #include <drm/drm_atomic_helper.h> 961f1c4a8Sjames qian wang (Arm Technology China) #include <drm/drm_plane_helper.h> 109e560309Sjames qian wang (Arm Technology China) #include <drm/drm_print.h> 1161f1c4a8Sjames qian wang (Arm Technology China) #include "komeda_dev.h" 1261f1c4a8Sjames qian wang (Arm Technology China) #include "komeda_kms.h" 13429bfabeSLowry Li (Arm Technology China) #include "komeda_framebuffer.h" 1461f1c4a8Sjames qian wang (Arm Technology China) 159e560309Sjames qian wang (Arm Technology China) static int 169e560309Sjames qian wang (Arm Technology China) komeda_plane_init_data_flow(struct drm_plane_state *st, 173b9dfa4eSLowry Li (Arm Technology China) struct komeda_crtc_state *kcrtc_st, 189e560309Sjames qian wang (Arm Technology China) struct komeda_data_flow_cfg *dflow) 199e560309Sjames qian wang (Arm Technology China) { 203b9dfa4eSLowry Li (Arm Technology China) struct komeda_plane *kplane = to_kplane(st->plane); 2142b6f118Sjames qian wang (Arm Technology China) struct komeda_plane_state *kplane_st = to_kplane_st(st); 229e560309Sjames qian wang (Arm Technology China) struct drm_framebuffer *fb = st->fb; 23429bfabeSLowry Li (Arm Technology China) const struct komeda_format_caps *caps = to_kfb(fb)->format_caps; 243b9dfa4eSLowry Li (Arm Technology China) struct komeda_pipeline *pipe = kplane->layer->base.pipeline; 259e560309Sjames qian wang (Arm Technology China) 269e560309Sjames qian wang (Arm Technology China) memset(dflow, 0, sizeof(*dflow)); 279e560309Sjames qian wang (Arm Technology China) 28109bd7d5SLowry Li (Arm Technology China) dflow->blending_zorder = st->normalized_zpos; 293b9dfa4eSLowry Li (Arm Technology China) if (pipe == to_kcrtc(st->crtc)->master) 303b9dfa4eSLowry Li (Arm Technology China) dflow->blending_zorder -= kcrtc_st->max_slave_zorder; 313b9dfa4eSLowry Li (Arm Technology China) if (dflow->blending_zorder < 0) { 323b9dfa4eSLowry Li (Arm Technology China) DRM_DEBUG_ATOMIC("%s zorder:%d < max_slave_zorder: %d.\n", 333b9dfa4eSLowry Li (Arm Technology China) st->plane->name, st->normalized_zpos, 343b9dfa4eSLowry Li (Arm Technology China) kcrtc_st->max_slave_zorder); 353b9dfa4eSLowry Li (Arm Technology China) return -EINVAL; 363b9dfa4eSLowry Li (Arm Technology China) } 373b9dfa4eSLowry Li (Arm Technology China) 38b35d0927Sjames qian wang (Arm Technology China) dflow->pixel_blend_mode = st->pixel_blend_mode; 399e560309Sjames qian wang (Arm Technology China) dflow->layer_alpha = st->alpha >> 8; 409e560309Sjames qian wang (Arm Technology China) 419e560309Sjames qian wang (Arm Technology China) dflow->out_x = st->crtc_x; 429e560309Sjames qian wang (Arm Technology China) dflow->out_y = st->crtc_y; 439e560309Sjames qian wang (Arm Technology China) dflow->out_w = st->crtc_w; 449e560309Sjames qian wang (Arm Technology China) dflow->out_h = st->crtc_h; 459e560309Sjames qian wang (Arm Technology China) 469e560309Sjames qian wang (Arm Technology China) dflow->in_x = st->src_x >> 16; 479e560309Sjames qian wang (Arm Technology China) dflow->in_y = st->src_y >> 16; 489e560309Sjames qian wang (Arm Technology China) dflow->in_w = st->src_w >> 16; 499e560309Sjames qian wang (Arm Technology China) dflow->in_h = st->src_h >> 16; 509e560309Sjames qian wang (Arm Technology China) 51429bfabeSLowry Li (Arm Technology China) dflow->rot = drm_rotation_simplify(st->rotation, caps->supported_rots); 52429bfabeSLowry Li (Arm Technology China) if (!has_bits(dflow->rot, caps->supported_rots)) { 53429bfabeSLowry Li (Arm Technology China) DRM_DEBUG_ATOMIC("rotation(0x%x) isn't supported by %s.\n", 54429bfabeSLowry Li (Arm Technology China) dflow->rot, 55429bfabeSLowry Li (Arm Technology China) komeda_get_format_name(caps->fourcc, 56429bfabeSLowry Li (Arm Technology China) fb->modifier)); 57429bfabeSLowry Li (Arm Technology China) return -EINVAL; 58429bfabeSLowry Li (Arm Technology China) } 59429bfabeSLowry Li (Arm Technology China) 60a407a650Sjames qian wang (Arm Technology China) dflow->en_img_enhancement = !!kplane_st->img_enhancement; 61a407a650Sjames qian wang (Arm Technology China) dflow->en_split = !!kplane_st->layer_split; 62b35d0927Sjames qian wang (Arm Technology China) 63b35d0927Sjames qian wang (Arm Technology China) komeda_complete_data_flow_cfg(dflow, fb); 64502932a0Sjames qian wang (Arm Technology China) 659e560309Sjames qian wang (Arm Technology China) return 0; 669e560309Sjames qian wang (Arm Technology China) } 679e560309Sjames qian wang (Arm Technology China) 688c919745Sjames qian wang (Arm Technology China) /** 698c919745Sjames qian wang (Arm Technology China) * komeda_plane_atomic_check - build input data flow 708c919745Sjames qian wang (Arm Technology China) * @plane: DRM plane 718c919745Sjames qian wang (Arm Technology China) * @state: the plane state object 728c919745Sjames qian wang (Arm Technology China) * 738c919745Sjames qian wang (Arm Technology China) * RETURNS: 748c919745Sjames qian wang (Arm Technology China) * Zero for success or -errno 758c919745Sjames qian wang (Arm Technology China) */ 7615e9122dSjames qian wang (Arm Technology China) static int 7715e9122dSjames qian wang (Arm Technology China) komeda_plane_atomic_check(struct drm_plane *plane, 789e560309Sjames qian wang (Arm Technology China) struct drm_plane_state *state) 799e560309Sjames qian wang (Arm Technology China) { 809e560309Sjames qian wang (Arm Technology China) struct komeda_plane *kplane = to_kplane(plane); 819e560309Sjames qian wang (Arm Technology China) struct komeda_plane_state *kplane_st = to_kplane_st(state); 829e560309Sjames qian wang (Arm Technology China) struct komeda_layer *layer = kplane->layer; 839e560309Sjames qian wang (Arm Technology China) struct drm_crtc_state *crtc_st; 849e560309Sjames qian wang (Arm Technology China) struct komeda_crtc_state *kcrtc_st; 859e560309Sjames qian wang (Arm Technology China) struct komeda_data_flow_cfg dflow; 869e560309Sjames qian wang (Arm Technology China) int err; 879e560309Sjames qian wang (Arm Technology China) 889e560309Sjames qian wang (Arm Technology China) if (!state->crtc || !state->fb) 899e560309Sjames qian wang (Arm Technology China) return 0; 909e560309Sjames qian wang (Arm Technology China) 919e560309Sjames qian wang (Arm Technology China) crtc_st = drm_atomic_get_crtc_state(state->state, state->crtc); 926d10dc61SDan Carpenter if (IS_ERR(crtc_st) || !crtc_st->enable) { 939e560309Sjames qian wang (Arm Technology China) DRM_DEBUG_ATOMIC("Cannot update plane on a disabled CRTC.\n"); 949e560309Sjames qian wang (Arm Technology China) return -EINVAL; 959e560309Sjames qian wang (Arm Technology China) } 969e560309Sjames qian wang (Arm Technology China) 979e560309Sjames qian wang (Arm Technology China) /* crtc is inactive, skip the resource assignment */ 989e560309Sjames qian wang (Arm Technology China) if (!crtc_st->active) 999e560309Sjames qian wang (Arm Technology China) return 0; 1009e560309Sjames qian wang (Arm Technology China) 1019e560309Sjames qian wang (Arm Technology China) kcrtc_st = to_kcrtc_st(crtc_st); 1029e560309Sjames qian wang (Arm Technology China) 1033b9dfa4eSLowry Li (Arm Technology China) err = komeda_plane_init_data_flow(state, kcrtc_st, &dflow); 1049e560309Sjames qian wang (Arm Technology China) if (err) 1059e560309Sjames qian wang (Arm Technology China) return err; 1069e560309Sjames qian wang (Arm Technology China) 107a407a650Sjames qian wang (Arm Technology China) if (dflow.en_split) 108a407a650Sjames qian wang (Arm Technology China) err = komeda_build_layer_split_data_flow(layer, 109a407a650Sjames qian wang (Arm Technology China) kplane_st, kcrtc_st, &dflow); 110a407a650Sjames qian wang (Arm Technology China) else 111a407a650Sjames qian wang (Arm Technology China) err = komeda_build_layer_data_flow(layer, 112a407a650Sjames qian wang (Arm Technology China) kplane_st, kcrtc_st, &dflow); 1139e560309Sjames qian wang (Arm Technology China) 1149e560309Sjames qian wang (Arm Technology China) return err; 1159e560309Sjames qian wang (Arm Technology China) } 1169e560309Sjames qian wang (Arm Technology China) 1179e560309Sjames qian wang (Arm Technology China) /* plane doesn't represent a real HW, so there is no HW update for plane. 1189e560309Sjames qian wang (Arm Technology China) * komeda handles all the HW update in crtc->atomic_flush 1199e560309Sjames qian wang (Arm Technology China) */ 12015e9122dSjames qian wang (Arm Technology China) static void 12115e9122dSjames qian wang (Arm Technology China) komeda_plane_atomic_update(struct drm_plane *plane, 1229e560309Sjames qian wang (Arm Technology China) struct drm_plane_state *old_state) 1239e560309Sjames qian wang (Arm Technology China) { 1249e560309Sjames qian wang (Arm Technology China) } 1259e560309Sjames qian wang (Arm Technology China) 12661f1c4a8Sjames qian wang (Arm Technology China) static const struct drm_plane_helper_funcs komeda_plane_helper_funcs = { 1279e560309Sjames qian wang (Arm Technology China) .atomic_check = komeda_plane_atomic_check, 1289e560309Sjames qian wang (Arm Technology China) .atomic_update = komeda_plane_atomic_update, 12961f1c4a8Sjames qian wang (Arm Technology China) }; 13061f1c4a8Sjames qian wang (Arm Technology China) 13161f1c4a8Sjames qian wang (Arm Technology China) static void komeda_plane_destroy(struct drm_plane *plane) 13261f1c4a8Sjames qian wang (Arm Technology China) { 13361f1c4a8Sjames qian wang (Arm Technology China) drm_plane_cleanup(plane); 13461f1c4a8Sjames qian wang (Arm Technology China) 13561f1c4a8Sjames qian wang (Arm Technology China) kfree(to_kplane(plane)); 13661f1c4a8Sjames qian wang (Arm Technology China) } 13761f1c4a8Sjames qian wang (Arm Technology China) 1389e560309Sjames qian wang (Arm Technology China) static void komeda_plane_reset(struct drm_plane *plane) 1399e560309Sjames qian wang (Arm Technology China) { 1409e560309Sjames qian wang (Arm Technology China) struct komeda_plane_state *state; 1419e560309Sjames qian wang (Arm Technology China) struct komeda_plane *kplane = to_kplane(plane); 1429e560309Sjames qian wang (Arm Technology China) 1439e560309Sjames qian wang (Arm Technology China) if (plane->state) 1449e560309Sjames qian wang (Arm Technology China) __drm_atomic_helper_plane_destroy_state(plane->state); 1459e560309Sjames qian wang (Arm Technology China) 1469e560309Sjames qian wang (Arm Technology China) kfree(plane->state); 1479e560309Sjames qian wang (Arm Technology China) plane->state = NULL; 1489e560309Sjames qian wang (Arm Technology China) 1499e560309Sjames qian wang (Arm Technology China) state = kzalloc(sizeof(*state), GFP_KERNEL); 1509e560309Sjames qian wang (Arm Technology China) if (state) { 1519e560309Sjames qian wang (Arm Technology China) state->base.rotation = DRM_MODE_ROTATE_0; 1529e560309Sjames qian wang (Arm Technology China) state->base.pixel_blend_mode = DRM_MODE_BLEND_PREMULTI; 1539e560309Sjames qian wang (Arm Technology China) state->base.alpha = DRM_BLEND_ALPHA_OPAQUE; 1549e560309Sjames qian wang (Arm Technology China) state->base.zpos = kplane->layer->base.id; 1559682dee9SLowry Li (Arm Technology China) state->base.color_encoding = DRM_COLOR_YCBCR_BT601; 1569682dee9SLowry Li (Arm Technology China) state->base.color_range = DRM_COLOR_YCBCR_LIMITED_RANGE; 1579e560309Sjames qian wang (Arm Technology China) plane->state = &state->base; 1589e560309Sjames qian wang (Arm Technology China) plane->state->plane = plane; 1599e560309Sjames qian wang (Arm Technology China) } 1609e560309Sjames qian wang (Arm Technology China) } 1619e560309Sjames qian wang (Arm Technology China) 1629e560309Sjames qian wang (Arm Technology China) static struct drm_plane_state * 1639e560309Sjames qian wang (Arm Technology China) komeda_plane_atomic_duplicate_state(struct drm_plane *plane) 1649e560309Sjames qian wang (Arm Technology China) { 16542b6f118Sjames qian wang (Arm Technology China) struct komeda_plane_state *new, *old; 1669e560309Sjames qian wang (Arm Technology China) 1679e560309Sjames qian wang (Arm Technology China) if (WARN_ON(!plane->state)) 1689e560309Sjames qian wang (Arm Technology China) return NULL; 1699e560309Sjames qian wang (Arm Technology China) 1709e560309Sjames qian wang (Arm Technology China) new = kzalloc(sizeof(*new), GFP_KERNEL); 1719e560309Sjames qian wang (Arm Technology China) if (!new) 1729e560309Sjames qian wang (Arm Technology China) return NULL; 1739e560309Sjames qian wang (Arm Technology China) 1749e560309Sjames qian wang (Arm Technology China) __drm_atomic_helper_plane_duplicate_state(plane, &new->base); 1759e560309Sjames qian wang (Arm Technology China) 17642b6f118Sjames qian wang (Arm Technology China) old = to_kplane_st(plane->state); 17742b6f118Sjames qian wang (Arm Technology China) 17842b6f118Sjames qian wang (Arm Technology China) new->img_enhancement = old->img_enhancement; 17942b6f118Sjames qian wang (Arm Technology China) 1809e560309Sjames qian wang (Arm Technology China) return &new->base; 1819e560309Sjames qian wang (Arm Technology China) } 1829e560309Sjames qian wang (Arm Technology China) 1839e560309Sjames qian wang (Arm Technology China) static void 1849e560309Sjames qian wang (Arm Technology China) komeda_plane_atomic_destroy_state(struct drm_plane *plane, 1859e560309Sjames qian wang (Arm Technology China) struct drm_plane_state *state) 1869e560309Sjames qian wang (Arm Technology China) { 1879e560309Sjames qian wang (Arm Technology China) __drm_atomic_helper_plane_destroy_state(state); 1889e560309Sjames qian wang (Arm Technology China) kfree(to_kplane_st(state)); 1899e560309Sjames qian wang (Arm Technology China) } 1909e560309Sjames qian wang (Arm Technology China) 19142b6f118Sjames qian wang (Arm Technology China) static int 19242b6f118Sjames qian wang (Arm Technology China) komeda_plane_atomic_get_property(struct drm_plane *plane, 19342b6f118Sjames qian wang (Arm Technology China) const struct drm_plane_state *state, 19442b6f118Sjames qian wang (Arm Technology China) struct drm_property *property, 19542b6f118Sjames qian wang (Arm Technology China) uint64_t *val) 19642b6f118Sjames qian wang (Arm Technology China) { 19742b6f118Sjames qian wang (Arm Technology China) struct komeda_plane *kplane = to_kplane(plane); 19842b6f118Sjames qian wang (Arm Technology China) struct komeda_plane_state *st = to_kplane_st(state); 19942b6f118Sjames qian wang (Arm Technology China) 20042b6f118Sjames qian wang (Arm Technology China) if (property == kplane->prop_img_enhancement) 20142b6f118Sjames qian wang (Arm Technology China) *val = st->img_enhancement; 202a407a650Sjames qian wang (Arm Technology China) else if (property == kplane->prop_layer_split) 203a407a650Sjames qian wang (Arm Technology China) *val = st->layer_split; 20442b6f118Sjames qian wang (Arm Technology China) else 20542b6f118Sjames qian wang (Arm Technology China) return -EINVAL; 20642b6f118Sjames qian wang (Arm Technology China) 20742b6f118Sjames qian wang (Arm Technology China) return 0; 20842b6f118Sjames qian wang (Arm Technology China) } 20942b6f118Sjames qian wang (Arm Technology China) 21042b6f118Sjames qian wang (Arm Technology China) static int 21142b6f118Sjames qian wang (Arm Technology China) komeda_plane_atomic_set_property(struct drm_plane *plane, 21242b6f118Sjames qian wang (Arm Technology China) struct drm_plane_state *state, 21342b6f118Sjames qian wang (Arm Technology China) struct drm_property *property, 21442b6f118Sjames qian wang (Arm Technology China) uint64_t val) 21542b6f118Sjames qian wang (Arm Technology China) { 21642b6f118Sjames qian wang (Arm Technology China) struct komeda_plane *kplane = to_kplane(plane); 21742b6f118Sjames qian wang (Arm Technology China) struct komeda_plane_state *st = to_kplane_st(state); 21842b6f118Sjames qian wang (Arm Technology China) 21942b6f118Sjames qian wang (Arm Technology China) if (property == kplane->prop_img_enhancement) 22042b6f118Sjames qian wang (Arm Technology China) st->img_enhancement = !!val; 221a407a650Sjames qian wang (Arm Technology China) else if (property == kplane->prop_layer_split) 222a407a650Sjames qian wang (Arm Technology China) st->layer_split = !!val; 22342b6f118Sjames qian wang (Arm Technology China) else 22442b6f118Sjames qian wang (Arm Technology China) return -EINVAL; 22542b6f118Sjames qian wang (Arm Technology China) 22642b6f118Sjames qian wang (Arm Technology China) return 0; 22742b6f118Sjames qian wang (Arm Technology China) } 22842b6f118Sjames qian wang (Arm Technology China) 22965ad2392Sjames qian wang (Arm Technology China) static bool 23065ad2392Sjames qian wang (Arm Technology China) komeda_plane_format_mod_supported(struct drm_plane *plane, 23165ad2392Sjames qian wang (Arm Technology China) u32 format, u64 modifier) 23265ad2392Sjames qian wang (Arm Technology China) { 23365ad2392Sjames qian wang (Arm Technology China) struct komeda_dev *mdev = plane->dev->dev_private; 23465ad2392Sjames qian wang (Arm Technology China) struct komeda_plane *kplane = to_kplane(plane); 23565ad2392Sjames qian wang (Arm Technology China) u32 layer_type = kplane->layer->layer_type; 23665ad2392Sjames qian wang (Arm Technology China) 23765ad2392Sjames qian wang (Arm Technology China) return komeda_format_mod_supported(&mdev->fmt_tbl, layer_type, 23819358630SLowry Li (Arm Technology China) format, modifier, 0); 23965ad2392Sjames qian wang (Arm Technology China) } 24065ad2392Sjames qian wang (Arm Technology China) 24161f1c4a8Sjames qian wang (Arm Technology China) static const struct drm_plane_funcs komeda_plane_funcs = { 2429e560309Sjames qian wang (Arm Technology China) .update_plane = drm_atomic_helper_update_plane, 2439e560309Sjames qian wang (Arm Technology China) .disable_plane = drm_atomic_helper_disable_plane, 2449e560309Sjames qian wang (Arm Technology China) .destroy = komeda_plane_destroy, 2459e560309Sjames qian wang (Arm Technology China) .reset = komeda_plane_reset, 2469e560309Sjames qian wang (Arm Technology China) .atomic_duplicate_state = komeda_plane_atomic_duplicate_state, 2479e560309Sjames qian wang (Arm Technology China) .atomic_destroy_state = komeda_plane_atomic_destroy_state, 24842b6f118Sjames qian wang (Arm Technology China) .atomic_get_property = komeda_plane_atomic_get_property, 24942b6f118Sjames qian wang (Arm Technology China) .atomic_set_property = komeda_plane_atomic_set_property, 25065ad2392Sjames qian wang (Arm Technology China) .format_mod_supported = komeda_plane_format_mod_supported, 25161f1c4a8Sjames qian wang (Arm Technology China) }; 25261f1c4a8Sjames qian wang (Arm Technology China) 25342b6f118Sjames qian wang (Arm Technology China) static int 25442b6f118Sjames qian wang (Arm Technology China) komeda_plane_create_layer_properties(struct komeda_plane *kplane, 25542b6f118Sjames qian wang (Arm Technology China) struct komeda_layer *layer) 25642b6f118Sjames qian wang (Arm Technology China) { 25742b6f118Sjames qian wang (Arm Technology China) struct drm_device *drm = kplane->base.dev; 25842b6f118Sjames qian wang (Arm Technology China) struct drm_plane *plane = &kplane->base; 25942b6f118Sjames qian wang (Arm Technology China) struct drm_property *prop = NULL; 26042b6f118Sjames qian wang (Arm Technology China) 26142b6f118Sjames qian wang (Arm Technology China) /* property: layer image_enhancement */ 26242b6f118Sjames qian wang (Arm Technology China) if (layer->base.supported_outputs & KOMEDA_PIPELINE_SCALERS) { 26342b6f118Sjames qian wang (Arm Technology China) prop = drm_property_create_bool(drm, DRM_MODE_PROP_ATOMIC, 26442b6f118Sjames qian wang (Arm Technology China) "img_enhancement"); 26542b6f118Sjames qian wang (Arm Technology China) if (!prop) 26642b6f118Sjames qian wang (Arm Technology China) return -ENOMEM; 26742b6f118Sjames qian wang (Arm Technology China) 26842b6f118Sjames qian wang (Arm Technology China) drm_object_attach_property(&plane->base, prop, 0); 26942b6f118Sjames qian wang (Arm Technology China) kplane->prop_img_enhancement = prop; 27042b6f118Sjames qian wang (Arm Technology China) } 27142b6f118Sjames qian wang (Arm Technology China) 272a407a650Sjames qian wang (Arm Technology China) /* property: layer split */ 273a407a650Sjames qian wang (Arm Technology China) if (layer->right) { 274a407a650Sjames qian wang (Arm Technology China) prop = drm_property_create_bool(drm, DRM_MODE_PROP_ATOMIC, 275a407a650Sjames qian wang (Arm Technology China) "layer_split"); 276a407a650Sjames qian wang (Arm Technology China) if (!prop) 277a407a650Sjames qian wang (Arm Technology China) return -ENOMEM; 278a407a650Sjames qian wang (Arm Technology China) kplane->prop_layer_split = prop; 279a407a650Sjames qian wang (Arm Technology China) drm_object_attach_property(&plane->base, prop, 0); 280a407a650Sjames qian wang (Arm Technology China) } 281a407a650Sjames qian wang (Arm Technology China) 28242b6f118Sjames qian wang (Arm Technology China) return 0; 28342b6f118Sjames qian wang (Arm Technology China) } 28442b6f118Sjames qian wang (Arm Technology China) 28561f1c4a8Sjames qian wang (Arm Technology China) /* for komeda, which is pipeline can be share between crtcs */ 28661f1c4a8Sjames qian wang (Arm Technology China) static u32 get_possible_crtcs(struct komeda_kms_dev *kms, 28761f1c4a8Sjames qian wang (Arm Technology China) struct komeda_pipeline *pipe) 28861f1c4a8Sjames qian wang (Arm Technology China) { 28961f1c4a8Sjames qian wang (Arm Technology China) struct komeda_crtc *crtc; 29061f1c4a8Sjames qian wang (Arm Technology China) u32 possible_crtcs = 0; 29161f1c4a8Sjames qian wang (Arm Technology China) int i; 29261f1c4a8Sjames qian wang (Arm Technology China) 29361f1c4a8Sjames qian wang (Arm Technology China) for (i = 0; i < kms->n_crtcs; i++) { 29461f1c4a8Sjames qian wang (Arm Technology China) crtc = &kms->crtcs[i]; 29561f1c4a8Sjames qian wang (Arm Technology China) 29661f1c4a8Sjames qian wang (Arm Technology China) if ((pipe == crtc->master) || (pipe == crtc->slave)) 29761f1c4a8Sjames qian wang (Arm Technology China) possible_crtcs |= BIT(i); 29861f1c4a8Sjames qian wang (Arm Technology China) } 29961f1c4a8Sjames qian wang (Arm Technology China) 30061f1c4a8Sjames qian wang (Arm Technology China) return possible_crtcs; 30161f1c4a8Sjames qian wang (Arm Technology China) } 30261f1c4a8Sjames qian wang (Arm Technology China) 3033b9dfa4eSLowry Li (Arm Technology China) static void 3043b9dfa4eSLowry Li (Arm Technology China) komeda_set_crtc_plane_mask(struct komeda_kms_dev *kms, 3053b9dfa4eSLowry Li (Arm Technology China) struct komeda_pipeline *pipe, 3063b9dfa4eSLowry Li (Arm Technology China) struct drm_plane *plane) 3073b9dfa4eSLowry Li (Arm Technology China) { 3083b9dfa4eSLowry Li (Arm Technology China) struct komeda_crtc *kcrtc; 3093b9dfa4eSLowry Li (Arm Technology China) int i; 3103b9dfa4eSLowry Li (Arm Technology China) 3113b9dfa4eSLowry Li (Arm Technology China) for (i = 0; i < kms->n_crtcs; i++) { 3123b9dfa4eSLowry Li (Arm Technology China) kcrtc = &kms->crtcs[i]; 3133b9dfa4eSLowry Li (Arm Technology China) 3143b9dfa4eSLowry Li (Arm Technology China) if (pipe == kcrtc->slave) 3153b9dfa4eSLowry Li (Arm Technology China) kcrtc->slave_planes |= BIT(drm_plane_index(plane)); 3163b9dfa4eSLowry Li (Arm Technology China) } 3173b9dfa4eSLowry Li (Arm Technology China) } 3183b9dfa4eSLowry Li (Arm Technology China) 31961f1c4a8Sjames qian wang (Arm Technology China) /* use Layer0 as primary */ 32061f1c4a8Sjames qian wang (Arm Technology China) static u32 get_plane_type(struct komeda_kms_dev *kms, 32161f1c4a8Sjames qian wang (Arm Technology China) struct komeda_component *c) 32261f1c4a8Sjames qian wang (Arm Technology China) { 32361f1c4a8Sjames qian wang (Arm Technology China) bool is_primary = (c->id == KOMEDA_COMPONENT_LAYER0); 32461f1c4a8Sjames qian wang (Arm Technology China) 32561f1c4a8Sjames qian wang (Arm Technology China) return is_primary ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; 32661f1c4a8Sjames qian wang (Arm Technology China) } 32761f1c4a8Sjames qian wang (Arm Technology China) 32861f1c4a8Sjames qian wang (Arm Technology China) static int komeda_plane_add(struct komeda_kms_dev *kms, 32961f1c4a8Sjames qian wang (Arm Technology China) struct komeda_layer *layer) 33061f1c4a8Sjames qian wang (Arm Technology China) { 33161f1c4a8Sjames qian wang (Arm Technology China) struct komeda_dev *mdev = kms->base.dev_private; 33261f1c4a8Sjames qian wang (Arm Technology China) struct komeda_component *c = &layer->base; 33361f1c4a8Sjames qian wang (Arm Technology China) struct komeda_plane *kplane; 33461f1c4a8Sjames qian wang (Arm Technology China) struct drm_plane *plane; 33561f1c4a8Sjames qian wang (Arm Technology China) u32 *formats, n_formats = 0; 33661f1c4a8Sjames qian wang (Arm Technology China) int err; 33761f1c4a8Sjames qian wang (Arm Technology China) 33861f1c4a8Sjames qian wang (Arm Technology China) kplane = kzalloc(sizeof(*kplane), GFP_KERNEL); 33961f1c4a8Sjames qian wang (Arm Technology China) if (!kplane) 34061f1c4a8Sjames qian wang (Arm Technology China) return -ENOMEM; 34161f1c4a8Sjames qian wang (Arm Technology China) 34261f1c4a8Sjames qian wang (Arm Technology China) plane = &kplane->base; 34361f1c4a8Sjames qian wang (Arm Technology China) kplane->layer = layer; 34461f1c4a8Sjames qian wang (Arm Technology China) 34561f1c4a8Sjames qian wang (Arm Technology China) formats = komeda_get_layer_fourcc_list(&mdev->fmt_tbl, 34661f1c4a8Sjames qian wang (Arm Technology China) layer->layer_type, &n_formats); 34761f1c4a8Sjames qian wang (Arm Technology China) 34861f1c4a8Sjames qian wang (Arm Technology China) err = drm_universal_plane_init(&kms->base, plane, 34961f1c4a8Sjames qian wang (Arm Technology China) get_possible_crtcs(kms, c->pipeline), 35061f1c4a8Sjames qian wang (Arm Technology China) &komeda_plane_funcs, 35165ad2392Sjames qian wang (Arm Technology China) formats, n_formats, komeda_supported_modifiers, 35261f1c4a8Sjames qian wang (Arm Technology China) get_plane_type(kms, c), 35361f1c4a8Sjames qian wang (Arm Technology China) "%s", c->name); 35461f1c4a8Sjames qian wang (Arm Technology China) 35561f1c4a8Sjames qian wang (Arm Technology China) komeda_put_fourcc_list(formats); 35661f1c4a8Sjames qian wang (Arm Technology China) 35761f1c4a8Sjames qian wang (Arm Technology China) if (err) 35861f1c4a8Sjames qian wang (Arm Technology China) goto cleanup; 35961f1c4a8Sjames qian wang (Arm Technology China) 36061f1c4a8Sjames qian wang (Arm Technology China) drm_plane_helper_add(plane, &komeda_plane_helper_funcs); 36161f1c4a8Sjames qian wang (Arm Technology China) 362429bfabeSLowry Li (Arm Technology China) err = drm_plane_create_rotation_property(plane, DRM_MODE_ROTATE_0, 363429bfabeSLowry Li (Arm Technology China) layer->supported_rots); 364429bfabeSLowry Li (Arm Technology China) if (err) 365429bfabeSLowry Li (Arm Technology China) goto cleanup; 366429bfabeSLowry Li (Arm Technology China) 36762ffc393SLowry Li (Arm Technology China) err = drm_plane_create_alpha_property(plane); 36862ffc393SLowry Li (Arm Technology China) if (err) 36962ffc393SLowry Li (Arm Technology China) goto cleanup; 37062ffc393SLowry Li (Arm Technology China) 37162ffc393SLowry Li (Arm Technology China) err = drm_plane_create_blend_mode_property(plane, 37262ffc393SLowry Li (Arm Technology China) BIT(DRM_MODE_BLEND_PIXEL_NONE) | 37362ffc393SLowry Li (Arm Technology China) BIT(DRM_MODE_BLEND_PREMULTI) | 37462ffc393SLowry Li (Arm Technology China) BIT(DRM_MODE_BLEND_COVERAGE)); 37562ffc393SLowry Li (Arm Technology China) if (err) 37662ffc393SLowry Li (Arm Technology China) goto cleanup; 37762ffc393SLowry Li (Arm Technology China) 37842b6f118Sjames qian wang (Arm Technology China) err = komeda_plane_create_layer_properties(kplane, layer); 37942b6f118Sjames qian wang (Arm Technology China) if (err) 38042b6f118Sjames qian wang (Arm Technology China) goto cleanup; 38142b6f118Sjames qian wang (Arm Technology China) 3829682dee9SLowry Li (Arm Technology China) err = drm_plane_create_color_properties(plane, 3839682dee9SLowry Li (Arm Technology China) BIT(DRM_COLOR_YCBCR_BT601) | 3849682dee9SLowry Li (Arm Technology China) BIT(DRM_COLOR_YCBCR_BT709) | 3859682dee9SLowry Li (Arm Technology China) BIT(DRM_COLOR_YCBCR_BT2020), 3869682dee9SLowry Li (Arm Technology China) BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) | 3879682dee9SLowry Li (Arm Technology China) BIT(DRM_COLOR_YCBCR_FULL_RANGE), 3889682dee9SLowry Li (Arm Technology China) DRM_COLOR_YCBCR_BT601, 3899682dee9SLowry Li (Arm Technology China) DRM_COLOR_YCBCR_LIMITED_RANGE); 3909682dee9SLowry Li (Arm Technology China) if (err) 3919682dee9SLowry Li (Arm Technology China) goto cleanup; 3929682dee9SLowry Li (Arm Technology China) 393109bd7d5SLowry Li (Arm Technology China) err = drm_plane_create_zpos_property(plane, layer->base.id, 0, 8); 394109bd7d5SLowry Li (Arm Technology China) if (err) 395109bd7d5SLowry Li (Arm Technology China) goto cleanup; 396109bd7d5SLowry Li (Arm Technology China) 3973b9dfa4eSLowry Li (Arm Technology China) komeda_set_crtc_plane_mask(kms, c->pipeline, plane); 3983b9dfa4eSLowry Li (Arm Technology China) 39961f1c4a8Sjames qian wang (Arm Technology China) return 0; 40061f1c4a8Sjames qian wang (Arm Technology China) cleanup: 40161f1c4a8Sjames qian wang (Arm Technology China) komeda_plane_destroy(plane); 40261f1c4a8Sjames qian wang (Arm Technology China) return err; 40361f1c4a8Sjames qian wang (Arm Technology China) } 40461f1c4a8Sjames qian wang (Arm Technology China) 40561f1c4a8Sjames qian wang (Arm Technology China) int komeda_kms_add_planes(struct komeda_kms_dev *kms, struct komeda_dev *mdev) 40661f1c4a8Sjames qian wang (Arm Technology China) { 40761f1c4a8Sjames qian wang (Arm Technology China) struct komeda_pipeline *pipe; 40861f1c4a8Sjames qian wang (Arm Technology China) int i, j, err; 40961f1c4a8Sjames qian wang (Arm Technology China) 41061f1c4a8Sjames qian wang (Arm Technology China) for (i = 0; i < mdev->n_pipelines; i++) { 41161f1c4a8Sjames qian wang (Arm Technology China) pipe = mdev->pipelines[i]; 41261f1c4a8Sjames qian wang (Arm Technology China) 41361f1c4a8Sjames qian wang (Arm Technology China) for (j = 0; j < pipe->n_layers; j++) { 41461f1c4a8Sjames qian wang (Arm Technology China) err = komeda_plane_add(kms, pipe->layers[j]); 41561f1c4a8Sjames qian wang (Arm Technology China) if (err) 41661f1c4a8Sjames qian wang (Arm Technology China) return err; 41761f1c4a8Sjames qian wang (Arm Technology China) } 41861f1c4a8Sjames qian wang (Arm Technology China) } 41961f1c4a8Sjames qian wang (Arm Technology China) 42061f1c4a8Sjames qian wang (Arm Technology China) return 0; 42161f1c4a8Sjames qian wang (Arm Technology China) } 422