566 lines · c
1/* SPDX-License-Identifier: GPL-2.0 */2/*3 * (C) COPYRIGHT 2018 ARM Limited. All rights reserved.4 * Author: James.Qian.Wang <james.qian.wang@arm.com>5 *6 */7#ifndef _KOMEDA_PIPELINE_H_8#define _KOMEDA_PIPELINE_H_9 10#include <linux/types.h>11#include <drm/drm_atomic.h>12#include <drm/drm_atomic_helper.h>13#include "malidp_utils.h"14#include "komeda_color_mgmt.h"15 16#define KOMEDA_MAX_PIPELINES 217#define KOMEDA_PIPELINE_MAX_LAYERS 418#define KOMEDA_PIPELINE_MAX_SCALERS 219#define KOMEDA_COMPONENT_N_INPUTS 520 21/* pipeline component IDs */22enum {23 KOMEDA_COMPONENT_LAYER0 = 0,24 KOMEDA_COMPONENT_LAYER1 = 1,25 KOMEDA_COMPONENT_LAYER2 = 2,26 KOMEDA_COMPONENT_LAYER3 = 3,27 KOMEDA_COMPONENT_WB_LAYER = 7, /* write back layer */28 KOMEDA_COMPONENT_SCALER0 = 8,29 KOMEDA_COMPONENT_SCALER1 = 9,30 KOMEDA_COMPONENT_SPLITTER = 12,31 KOMEDA_COMPONENT_MERGER = 14,32 KOMEDA_COMPONENT_COMPIZ0 = 16, /* compositor */33 KOMEDA_COMPONENT_COMPIZ1 = 17,34 KOMEDA_COMPONENT_IPS0 = 20, /* post image processor */35 KOMEDA_COMPONENT_IPS1 = 21,36 KOMEDA_COMPONENT_TIMING_CTRLR = 22, /* timing controller */37};38 39#define KOMEDA_PIPELINE_LAYERS (BIT(KOMEDA_COMPONENT_LAYER0) |\40 BIT(KOMEDA_COMPONENT_LAYER1) |\41 BIT(KOMEDA_COMPONENT_LAYER2) |\42 BIT(KOMEDA_COMPONENT_LAYER3))43 44#define KOMEDA_PIPELINE_SCALERS (BIT(KOMEDA_COMPONENT_SCALER0) |\45 BIT(KOMEDA_COMPONENT_SCALER1))46 47#define KOMEDA_PIPELINE_COMPIZS (BIT(KOMEDA_COMPONENT_COMPIZ0) |\48 BIT(KOMEDA_COMPONENT_COMPIZ1))49 50#define KOMEDA_PIPELINE_IMPROCS (BIT(KOMEDA_COMPONENT_IPS0) |\51 BIT(KOMEDA_COMPONENT_IPS1))52struct komeda_component;53struct komeda_component_state;54 55/** komeda_component_funcs - component control functions */56struct komeda_component_funcs {57 /** @validate: optional,58 * component may has special requirements or limitations, this function59 * supply HW the ability to do the further HW specific check.60 */61 int (*validate)(struct komeda_component *c,62 struct komeda_component_state *state);63 /** @update: update is a active update */64 void (*update)(struct komeda_component *c,65 struct komeda_component_state *state);66 /** @disable: disable component */67 void (*disable)(struct komeda_component *c);68 /** @dump_register: Optional, dump registers to seq_file */69 void (*dump_register)(struct komeda_component *c, struct seq_file *seq);70};71 72/**73 * struct komeda_component74 *75 * struct komeda_component describe the data flow capabilities for how to link a76 * component into the display pipeline.77 * all specified components are subclass of this structure.78 */79struct komeda_component {80 /** @obj: treat component as private obj */81 struct drm_private_obj obj;82 /** @pipeline: the komeda pipeline this component belongs to */83 struct komeda_pipeline *pipeline;84 /** @name: component name */85 char name[32];86 /**87 * @reg:88 * component register base,89 * which is initialized by chip and used by chip only90 */91 u32 __iomem *reg;92 /** @id: component id */93 u32 id;94 /**95 * @hw_id: component hw id,96 * which is initialized by chip and used by chip only97 */98 u32 hw_id;99 100 /**101 * @max_active_inputs:102 * @max_active_outputs:103 *104 * maximum number of inputs/outputs that can be active at the same time105 * Note:106 * the number isn't the bit number of @supported_inputs or107 * @supported_outputs, but may be less than it, since component may not108 * support enabling all @supported_inputs/outputs at the same time.109 */110 u8 max_active_inputs;111 /** @max_active_outputs: maximum number of outputs */112 u8 max_active_outputs;113 /**114 * @supported_inputs:115 * @supported_outputs:116 *117 * bitmask of BIT(component->id) for the supported inputs/outputs,118 * describes the possibilities of how a component is linked into a119 * pipeline.120 */121 u32 supported_inputs;122 /** @supported_outputs: bitmask of supported output componenet ids */123 u32 supported_outputs;124 125 /**126 * @funcs: chip functions to access HW127 */128 const struct komeda_component_funcs *funcs;129};130 131/**132 * struct komeda_component_output133 *134 * a component has multiple outputs, if want to know where the data135 * comes from, only know the component is not enough, we still need to know136 * its output port137 */138struct komeda_component_output {139 /** @component: indicate which component the data comes from */140 struct komeda_component *component;141 /**142 * @output_port:143 * the output port of the &komeda_component_output.component144 */145 u8 output_port;146};147 148/**149 * struct komeda_component_state150 *151 * component_state is the data flow configuration of the component, and it's152 * the superclass of all specific component_state like @komeda_layer_state,153 * @komeda_scaler_state154 */155struct komeda_component_state {156 /** @obj: tracking component_state by drm_atomic_state */157 struct drm_private_state obj;158 /** @component: backpointer to the component */159 struct komeda_component *component;160 /**161 * @binding_user:162 * currently bound user, the user can be @crtc, @plane or @wb_conn,163 * which is valid decided by @component and @inputs164 *165 * - Layer: its user always is plane.166 * - compiz/improc/timing_ctrlr: the user is crtc.167 * - wb_layer: wb_conn;168 * - scaler: plane when input is layer, wb_conn if input is compiz.169 */170 union {171 /** @crtc: backpointer for user crtc */172 struct drm_crtc *crtc;173 /** @plane: backpointer for user plane */174 struct drm_plane *plane;175 /** @wb_conn: backpointer for user wb_connector */176 struct drm_connector *wb_conn;177 void *binding_user;178 };179 180 /**181 * @active_inputs:182 *183 * active_inputs is bitmask of @inputs index184 *185 * - active_inputs = changed_active_inputs | unchanged_active_inputs186 * - affected_inputs = old->active_inputs | new->active_inputs;187 * - disabling_inputs = affected_inputs ^ active_inputs;188 * - changed_inputs = disabling_inputs | changed_active_inputs;189 *190 * NOTE:191 * changed_inputs doesn't include all active_input but only192 * @changed_active_inputs, and this bitmask can be used in chip193 * level for dirty update.194 */195 u16 active_inputs;196 /** @changed_active_inputs: bitmask of the changed @active_inputs */197 u16 changed_active_inputs;198 /** @affected_inputs: bitmask for affected @inputs */199 u16 affected_inputs;200 /**201 * @inputs:202 *203 * the specific inputs[i] only valid on BIT(i) has been set in204 * @active_inputs, if not the inputs[i] is undefined.205 */206 struct komeda_component_output inputs[KOMEDA_COMPONENT_N_INPUTS];207};208 209static inline u16 component_disabling_inputs(struct komeda_component_state *st)210{211 return st->affected_inputs ^ st->active_inputs;212}213 214static inline u16 component_changed_inputs(struct komeda_component_state *st)215{216 return component_disabling_inputs(st) | st->changed_active_inputs;217}218 219#define for_each_changed_input(st, i) \220 for ((i) = 0; (i) < (st)->component->max_active_inputs; (i)++) \221 if (has_bit((i), component_changed_inputs(st)))222 223#define to_comp(__c) (((__c) == NULL) ? NULL : &((__c)->base))224#define to_cpos(__c) ((struct komeda_component **)&(__c))225 226struct komeda_layer {227 struct komeda_component base;228 /* accepted h/v input range before rotation */229 struct malidp_range hsize_in, vsize_in;230 u32 layer_type; /* RICH, SIMPLE or WB */231 u32 line_sz;232 u32 yuv_line_sz; /* maximum line size for YUV422 and YUV420 */233 u32 supported_rots;234 /* komeda supports layer split which splits a whole image to two parts235 * left and right and handle them by two individual layer processors236 * Note: left/right are always according to the final display rect,237 * not the source buffer.238 */239 struct komeda_layer *right;240};241 242struct komeda_layer_state {243 struct komeda_component_state base;244 /* layer specific configuration state */245 u16 hsize, vsize;246 u32 rot;247 u16 afbc_crop_l;248 u16 afbc_crop_r;249 u16 afbc_crop_t;250 u16 afbc_crop_b;251 dma_addr_t addr[3];252};253 254struct komeda_scaler {255 struct komeda_component base;256 struct malidp_range hsize, vsize;257 u32 max_upscaling;258 u32 max_downscaling;259 u8 scaling_split_overlap; /* split overlap for scaling */260 u8 enh_split_overlap; /* split overlap for image enhancement */261};262 263struct komeda_scaler_state {264 struct komeda_component_state base;265 u16 hsize_in, vsize_in;266 u16 hsize_out, vsize_out;267 u16 total_hsize_in, total_vsize_in;268 u16 total_hsize_out; /* total_xxxx are size before split */269 u16 left_crop, right_crop;270 u8 en_scaling : 1,271 en_alpha : 1, /* enable alpha processing */272 en_img_enhancement : 1,273 en_split : 1,274 right_part : 1; /* right part of split image */275};276 277struct komeda_compiz {278 struct komeda_component base;279 struct malidp_range hsize, vsize;280};281 282struct komeda_compiz_input_cfg {283 u16 hsize, vsize;284 u16 hoffset, voffset;285 u8 pixel_blend_mode, layer_alpha;286};287 288struct komeda_compiz_state {289 struct komeda_component_state base;290 /* composition size */291 u16 hsize, vsize;292 struct komeda_compiz_input_cfg cins[KOMEDA_COMPONENT_N_INPUTS];293};294 295struct komeda_merger {296 struct komeda_component base;297 struct malidp_range hsize_merged;298 struct malidp_range vsize_merged;299};300 301struct komeda_merger_state {302 struct komeda_component_state base;303 u16 hsize_merged;304 u16 vsize_merged;305};306 307struct komeda_splitter {308 struct komeda_component base;309 struct malidp_range hsize, vsize;310};311 312struct komeda_splitter_state {313 struct komeda_component_state base;314 u16 hsize, vsize;315 u16 overlap;316};317 318struct komeda_improc {319 struct komeda_component base;320 u32 supported_color_formats; /* DRM_RGB/YUV444/YUV420*/321 u32 supported_color_depths; /* BIT(8) | BIT(10)*/322 u8 supports_degamma : 1;323 u8 supports_csc : 1;324 u8 supports_gamma : 1;325};326 327struct komeda_improc_state {328 struct komeda_component_state base;329 u8 color_format, color_depth;330 u16 hsize, vsize;331 u32 fgamma_coeffs[KOMEDA_N_GAMMA_COEFFS];332 u32 ctm_coeffs[KOMEDA_N_CTM_COEFFS];333};334 335/* display timing controller */336struct komeda_timing_ctrlr {337 struct komeda_component base;338 u8 supports_dual_link : 1;339};340 341struct komeda_timing_ctrlr_state {342 struct komeda_component_state base;343};344 345/* Why define A separated structure but not use plane_state directly ?346 * 1. Komeda supports layer_split which means a plane_state can be split and347 * handled by two layers, one layer only handle half of plane image.348 * 2. Fix up the user properties according to HW's capabilities, like user349 * set rotation to R180, but HW only supports REFLECT_X+Y. the rot here is350 * after drm_rotation_simplify()351 */352struct komeda_data_flow_cfg {353 struct komeda_component_output input;354 u16 in_x, in_y, in_w, in_h;355 u32 out_x, out_y, out_w, out_h;356 u16 total_in_h, total_in_w;357 u16 total_out_w;358 u16 left_crop, right_crop, overlap;359 u32 rot;360 int blending_zorder;361 u8 pixel_blend_mode, layer_alpha;362 u8 en_scaling : 1,363 en_img_enhancement : 1,364 en_split : 1,365 is_yuv : 1,366 right_part : 1; /* right part of display image if split enabled */367};368 369struct komeda_pipeline_funcs {370 /* check if the aclk (main engine clock) can satisfy the clock371 * requirements of the downscaling that specified by dflow372 */373 int (*downscaling_clk_check)(struct komeda_pipeline *pipe,374 struct drm_display_mode *mode,375 unsigned long aclk_rate,376 struct komeda_data_flow_cfg *dflow);377 /* dump_register: Optional, dump registers to seq_file */378 void (*dump_register)(struct komeda_pipeline *pipe,379 struct seq_file *sf);380};381 382/**383 * struct komeda_pipeline384 *385 * Represent a complete display pipeline and hold all functional components.386 */387struct komeda_pipeline {388 /** @obj: link pipeline as private obj of drm_atomic_state */389 struct drm_private_obj obj;390 /** @mdev: the parent komeda_dev */391 struct komeda_dev *mdev;392 /** @pxlclk: pixel clock */393 struct clk *pxlclk;394 /** @id: pipeline id */395 int id;396 /** @avail_comps: available components mask of pipeline */397 u32 avail_comps;398 /**399 * @standalone_disabled_comps:400 *401 * When disable the pipeline, some components can not be disabled402 * together with others, but need a sparated and standalone disable.403 * The standalone_disabled_comps are the components which need to be404 * disabled standalone, and this concept also introduce concept of405 * two phase.406 * phase 1: for disabling the common components.407 * phase 2: for disabling the standalong_disabled_comps.408 */409 u32 standalone_disabled_comps;410 /** @n_layers: the number of layer on @layers */411 int n_layers;412 /** @layers: the pipeline layers */413 struct komeda_layer *layers[KOMEDA_PIPELINE_MAX_LAYERS];414 /** @n_scalers: the number of scaler on @scalers */415 int n_scalers;416 /** @scalers: the pipeline scalers */417 struct komeda_scaler *scalers[KOMEDA_PIPELINE_MAX_SCALERS];418 /** @compiz: compositor */419 struct komeda_compiz *compiz;420 /** @splitter: for split the compiz output to two half data flows */421 struct komeda_splitter *splitter;422 /** @merger: merger */423 struct komeda_merger *merger;424 /** @wb_layer: writeback layer */425 struct komeda_layer *wb_layer;426 /** @improc: post image processor */427 struct komeda_improc *improc;428 /** @ctrlr: timing controller */429 struct komeda_timing_ctrlr *ctrlr;430 /** @funcs: chip private pipeline functions */431 const struct komeda_pipeline_funcs *funcs;432 433 /** @of_node: pipeline dt node */434 struct device_node *of_node;435 /** @of_output_port: pipeline output port */436 struct device_node *of_output_port;437 /** @of_output_links: output connector device nodes */438 struct device_node *of_output_links[2];439 /** @dual_link: true if of_output_links[0] and [1] are both valid */440 bool dual_link;441};442 443/**444 * struct komeda_pipeline_state445 *446 * NOTE:447 * Unlike the pipeline, pipeline_state doesn’t gather any component_state448 * into it. It because all component will be managed by drm_atomic_state.449 */450struct komeda_pipeline_state {451 /** @obj: tracking pipeline_state by drm_atomic_state */452 struct drm_private_state obj;453 /** @pipe: backpointer to the pipeline */454 struct komeda_pipeline *pipe;455 /** @crtc: currently bound crtc */456 struct drm_crtc *crtc;457 /**458 * @active_comps:459 *460 * bitmask - BIT(component->id) of active components461 */462 u32 active_comps;463};464 465#define to_layer(c) container_of(c, struct komeda_layer, base)466#define to_compiz(c) container_of(c, struct komeda_compiz, base)467#define to_scaler(c) container_of(c, struct komeda_scaler, base)468#define to_splitter(c) container_of(c, struct komeda_splitter, base)469#define to_merger(c) container_of(c, struct komeda_merger, base)470#define to_improc(c) container_of(c, struct komeda_improc, base)471#define to_ctrlr(c) container_of(c, struct komeda_timing_ctrlr, base)472 473#define to_layer_st(c) container_of(c, struct komeda_layer_state, base)474#define to_compiz_st(c) container_of(c, struct komeda_compiz_state, base)475#define to_scaler_st(c) container_of(c, struct komeda_scaler_state, base)476#define to_splitter_st(c) container_of(c, struct komeda_splitter_state, base)477#define to_merger_st(c) container_of(c, struct komeda_merger_state, base)478#define to_improc_st(c) container_of(c, struct komeda_improc_state, base)479#define to_ctrlr_st(c) container_of(c, struct komeda_timing_ctrlr_state, base)480 481#define priv_to_comp_st(o) container_of(o, struct komeda_component_state, obj)482#define priv_to_pipe_st(o) container_of(o, struct komeda_pipeline_state, obj)483 484/* pipeline APIs */485struct komeda_pipeline *486komeda_pipeline_add(struct komeda_dev *mdev, size_t size,487 const struct komeda_pipeline_funcs *funcs);488void komeda_pipeline_destroy(struct komeda_dev *mdev,489 struct komeda_pipeline *pipe);490struct komeda_pipeline *491komeda_pipeline_get_slave(struct komeda_pipeline *master);492int komeda_assemble_pipelines(struct komeda_dev *mdev);493struct komeda_component *494komeda_pipeline_get_component(struct komeda_pipeline *pipe, int id);495struct komeda_component *496komeda_pipeline_get_first_component(struct komeda_pipeline *pipe,497 u32 comp_mask);498 499void komeda_pipeline_dump_register(struct komeda_pipeline *pipe,500 struct seq_file *sf);501 502/* component APIs */503extern __printf(10, 11)504struct komeda_component *505komeda_component_add(struct komeda_pipeline *pipe,506 size_t comp_sz, u32 id, u32 hw_id,507 const struct komeda_component_funcs *funcs,508 u8 max_active_inputs, u32 supported_inputs,509 u8 max_active_outputs, u32 __iomem *reg,510 const char *name_fmt, ...);511 512void komeda_component_destroy(struct komeda_dev *mdev,513 struct komeda_component *c);514 515static inline struct komeda_component *516komeda_component_pickup_output(struct komeda_component *c, u32 avail_comps)517{518 u32 avail_inputs = c->supported_outputs & (avail_comps);519 520 return komeda_pipeline_get_first_component(c->pipeline, avail_inputs);521}522 523struct komeda_plane_state;524struct komeda_crtc_state;525struct komeda_crtc;526 527void pipeline_composition_size(struct komeda_crtc_state *kcrtc_st,528 u16 *hsize, u16 *vsize);529 530int komeda_build_layer_data_flow(struct komeda_layer *layer,531 struct komeda_plane_state *kplane_st,532 struct komeda_crtc_state *kcrtc_st,533 struct komeda_data_flow_cfg *dflow);534int komeda_build_wb_data_flow(struct komeda_layer *wb_layer,535 struct drm_connector_state *conn_st,536 struct komeda_crtc_state *kcrtc_st,537 struct komeda_data_flow_cfg *dflow);538int komeda_build_display_data_flow(struct komeda_crtc *kcrtc,539 struct komeda_crtc_state *kcrtc_st);540 541int komeda_build_layer_split_data_flow(struct komeda_layer *left,542 struct komeda_plane_state *kplane_st,543 struct komeda_crtc_state *kcrtc_st,544 struct komeda_data_flow_cfg *dflow);545int komeda_build_wb_split_data_flow(struct komeda_layer *wb_layer,546 struct drm_connector_state *conn_st,547 struct komeda_crtc_state *kcrtc_st,548 struct komeda_data_flow_cfg *dflow);549 550int komeda_release_unclaimed_resources(struct komeda_pipeline *pipe,551 struct komeda_crtc_state *kcrtc_st);552 553struct komeda_pipeline_state *554komeda_pipeline_get_old_state(struct komeda_pipeline *pipe,555 struct drm_atomic_state *state);556bool komeda_pipeline_disable(struct komeda_pipeline *pipe,557 struct drm_atomic_state *old_state);558void komeda_pipeline_update(struct komeda_pipeline *pipe,559 struct drm_atomic_state *old_state);560 561void komeda_complete_data_flow_cfg(struct komeda_layer *layer,562 struct komeda_data_flow_cfg *dflow,563 struct drm_framebuffer *fb);564 565#endif /* _KOMEDA_PIPELINE_H_*/566