Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/komeda: komeda_dev/pipeline/component definition and initialzation

1. Added a brief definition of komeda_dev/pipeline/component, this change
didn't add the detailed component features and capabilities, which will
be added in the following changes.
2. Corresponding resources discovery and initialzation functions.

Changes in v4:
- Deleted unnecessary headers

Changes in v3:
- Fixed style problem found by checkpatch.pl --strict.

Changes in v2:
- Unified abbreviation of "pipeline" to "pipe".

Signed-off-by: James Qian Wang (Arm Technology China) <james.qian.wang@arm.com>
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>

authored by

james qian wang (Arm Technology China) and committed by
Liviu Dudau
bd628c1b 37fc9bb0

+826
+2
drivers/gpu/drm/arm/Kconfig
··· 37 37 38 38 If compiled as a module it will be called mali-dp. 39 39 40 + source "drivers/gpu/drm/arm/display/Kconfig" 41 + 40 42 endmenu
+1
drivers/gpu/drm/arm/Makefile
··· 3 3 mali-dp-y := malidp_drv.o malidp_hw.o malidp_planes.o malidp_crtc.o 4 4 mali-dp-y += malidp_mw.o 5 5 obj-$(CONFIG_DRM_MALI_DISPLAY) += mali-dp.o 6 + obj-$(CONFIG_DRM_KOMEDA) += display/
+3
drivers/gpu/drm/arm/display/Kbuild
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + 3 + obj-$(CONFIG_DRM_KOMEDA) += komeda/
+14
drivers/gpu/drm/arm/display/Kconfig
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + config DRM_KOMEDA 3 + tristate "ARM Komeda display driver" 4 + depends on DRM && OF 5 + depends on COMMON_CLK 6 + select DRM_KMS_HELPER 7 + select DRM_KMS_CMA_HELPER 8 + select DRM_GEM_CMA_HELPER 9 + select VIDEOMODE_HELPERS 10 + help 11 + Choose this option if you want to compile the ARM Komeda display 12 + Processor driver. It supports the D71 variants of the hardware. 13 + 14 + If compiled as a module it will be called komeda.
+23
drivers/gpu/drm/arm/display/include/malidp_product.h
··· 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 _MALIDP_PRODUCT_H_ 8 + #define _MALIDP_PRODUCT_H_ 9 + 10 + /* Product identification */ 11 + #define MALIDP_CORE_ID(__product, __major, __minor, __status) \ 12 + ((((__product) & 0xFFFF) << 16) | (((__major) & 0xF) << 12) | \ 13 + (((__minor) & 0xF) << 8) | ((__status) & 0xFF)) 14 + 15 + #define MALIDP_CORE_ID_PRODUCT_ID(__core_id) ((__u32)(__core_id) >> 16) 16 + #define MALIDP_CORE_ID_MAJOR(__core_id) (((__u32)(__core_id) >> 12) & 0xF) 17 + #define MALIDP_CORE_ID_MINOR(__core_id) (((__u32)(__core_id) >> 8) & 0xF) 18 + #define MALIDP_CORE_ID_STATUS(__core_id) (((__u32)(__core_id)) & 0xFF) 19 + 20 + /* Mali-display product IDs */ 21 + #define MALIDP_D71_PRODUCT_ID 0x0071 22 + 23 + #endif /* _MALIDP_PRODUCT_H_ */
+16
drivers/gpu/drm/arm/display/include/malidp_utils.h
··· 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 _MALIDP_UTILS_ 8 + #define _MALIDP_UTILS_ 9 + 10 + #define has_bit(nr, mask) (BIT(nr) & (mask)) 11 + #define has_bits(bits, mask) (((bits) & (mask)) == (bits)) 12 + 13 + #define dp_for_each_set_bit(bit, mask) \ 14 + for_each_set_bit((bit), ((unsigned long *)&(mask)), sizeof(mask) * 8) 15 + 16 + #endif /* _MALIDP_UTILS_ */
+11
drivers/gpu/drm/arm/display/komeda/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0 2 + 3 + ccflags-y := \ 4 + -I$(src)/../include \ 5 + -I$(src) 6 + 7 + komeda-y := \ 8 + komeda_dev.o \ 9 + komeda_pipeline.o \ 10 + 11 + obj-$(CONFIG_DRM_KOMEDA) += komeda.o
+114
drivers/gpu/drm/arm/display/komeda/komeda_dev.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 + #include <linux/platform_device.h> 8 + #include <linux/of_device.h> 9 + #include <linux/of_graph.h> 10 + #include "komeda_dev.h" 11 + 12 + struct komeda_dev *komeda_dev_create(struct device *dev) 13 + { 14 + struct platform_device *pdev = to_platform_device(dev); 15 + const struct komeda_product_data *product; 16 + struct komeda_dev *mdev; 17 + struct resource *io_res; 18 + int err = 0; 19 + 20 + product = of_device_get_match_data(dev); 21 + if (!product) 22 + return ERR_PTR(-ENODEV); 23 + 24 + io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 25 + if (!io_res) { 26 + DRM_ERROR("No registers defined.\n"); 27 + return ERR_PTR(-ENODEV); 28 + } 29 + 30 + mdev = devm_kzalloc(dev, sizeof(*mdev), GFP_KERNEL); 31 + if (!mdev) 32 + return ERR_PTR(-ENOMEM); 33 + 34 + mdev->dev = dev; 35 + mdev->reg_base = devm_ioremap_resource(dev, io_res); 36 + if (IS_ERR(mdev->reg_base)) { 37 + DRM_ERROR("Map register space failed.\n"); 38 + err = PTR_ERR(mdev->reg_base); 39 + mdev->reg_base = NULL; 40 + goto err_cleanup; 41 + } 42 + 43 + mdev->pclk = devm_clk_get(dev, "pclk"); 44 + if (IS_ERR(mdev->pclk)) { 45 + DRM_ERROR("Get APB clk failed.\n"); 46 + err = PTR_ERR(mdev->pclk); 47 + mdev->pclk = NULL; 48 + goto err_cleanup; 49 + } 50 + 51 + /* Enable APB clock to access the registers */ 52 + clk_prepare_enable(mdev->pclk); 53 + 54 + mdev->funcs = product->identify(mdev->reg_base, &mdev->chip); 55 + if (!komeda_product_match(mdev, product->product_id)) { 56 + DRM_ERROR("DT configured %x mismatch with real HW %x.\n", 57 + product->product_id, 58 + MALIDP_CORE_ID_PRODUCT_ID(mdev->chip.core_id)); 59 + err = -ENODEV; 60 + goto err_cleanup; 61 + } 62 + 63 + DRM_INFO("Found ARM Mali-D%x version r%dp%d\n", 64 + MALIDP_CORE_ID_PRODUCT_ID(mdev->chip.core_id), 65 + MALIDP_CORE_ID_MAJOR(mdev->chip.core_id), 66 + MALIDP_CORE_ID_MINOR(mdev->chip.core_id)); 67 + 68 + err = mdev->funcs->enum_resources(mdev); 69 + if (err) { 70 + DRM_ERROR("enumerate display resource failed.\n"); 71 + goto err_cleanup; 72 + } 73 + 74 + return mdev; 75 + 76 + err_cleanup: 77 + komeda_dev_destroy(mdev); 78 + return ERR_PTR(err); 79 + } 80 + 81 + void komeda_dev_destroy(struct komeda_dev *mdev) 82 + { 83 + struct device *dev = mdev->dev; 84 + struct komeda_dev_funcs *funcs = mdev->funcs; 85 + int i; 86 + 87 + for (i = 0; i < mdev->n_pipelines; i++) { 88 + komeda_pipeline_destroy(mdev, mdev->pipelines[i]); 89 + mdev->pipelines[i] = NULL; 90 + } 91 + 92 + mdev->n_pipelines = 0; 93 + 94 + if (funcs && funcs->cleanup) 95 + funcs->cleanup(mdev); 96 + 97 + if (mdev->reg_base) { 98 + devm_iounmap(dev, mdev->reg_base); 99 + mdev->reg_base = NULL; 100 + } 101 + 102 + if (mdev->mclk) { 103 + devm_clk_put(dev, mdev->mclk); 104 + mdev->mclk = NULL; 105 + } 106 + 107 + if (mdev->pclk) { 108 + clk_disable_unprepare(mdev->pclk); 109 + devm_clk_put(dev, mdev->pclk); 110 + mdev->pclk = NULL; 111 + } 112 + 113 + devm_kfree(dev, mdev); 114 + }
+98
drivers/gpu/drm/arm/display/komeda/komeda_dev.h
··· 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_DEV_H_ 8 + #define _KOMEDA_DEV_H_ 9 + 10 + #include <linux/device.h> 11 + #include <linux/clk.h> 12 + #include "komeda_pipeline.h" 13 + #include "malidp_product.h" 14 + 15 + /* malidp device id */ 16 + enum { 17 + MALI_D71 = 0, 18 + }; 19 + 20 + /* pipeline DT ports */ 21 + enum { 22 + KOMEDA_OF_PORT_OUTPUT = 0, 23 + KOMEDA_OF_PORT_COPROC = 1, 24 + }; 25 + 26 + struct komeda_chip_info { 27 + u32 arch_id; 28 + u32 core_id; 29 + u32 core_info; 30 + u32 bus_width; 31 + }; 32 + 33 + struct komeda_product_data { 34 + u32 product_id; 35 + struct komeda_dev_funcs *(*identify)(u32 __iomem *reg, 36 + struct komeda_chip_info *info); 37 + }; 38 + 39 + struct komeda_dev; 40 + 41 + /** 42 + * struct komeda_dev_funcs 43 + * 44 + * Supplied by chip level and returned by the chip entry function xxx_identify, 45 + */ 46 + struct komeda_dev_funcs { 47 + /** 48 + * @enum_resources: 49 + * 50 + * for CHIP to report or add pipeline and component resources to CORE 51 + */ 52 + int (*enum_resources)(struct komeda_dev *mdev); 53 + /** @cleanup: call to chip to cleanup komeda_dev->chip data */ 54 + void (*cleanup)(struct komeda_dev *mdev); 55 + }; 56 + 57 + /** 58 + * struct komeda_dev 59 + * 60 + * Pipeline and component are used to describe how to handle the pixel data. 61 + * komeda_device is for describing the whole view of the device, and the 62 + * control-abilites of device. 63 + */ 64 + struct komeda_dev { 65 + struct device *dev; 66 + u32 __iomem *reg_base; 67 + 68 + struct komeda_chip_info chip; 69 + 70 + /** @pclk: APB clock for register access */ 71 + struct clk *pclk; 72 + /** @mck: HW main engine clk */ 73 + struct clk *mclk; 74 + 75 + int n_pipelines; 76 + struct komeda_pipeline *pipelines[KOMEDA_MAX_PIPELINES]; 77 + 78 + /** @funcs: chip funcs to access to HW */ 79 + struct komeda_dev_funcs *funcs; 80 + /** 81 + * @chip_data: 82 + * 83 + * chip data will be added by &komeda_dev_funcs.enum_resources() and 84 + * destroyed by &komeda_dev_funcs.cleanup() 85 + */ 86 + void *chip_data; 87 + }; 88 + 89 + static inline bool 90 + komeda_product_match(struct komeda_dev *mdev, u32 target) 91 + { 92 + return MALIDP_CORE_ID_PRODUCT_ID(mdev->chip.core_id) == target; 93 + } 94 + 95 + struct komeda_dev *komeda_dev_create(struct device *dev); 96 + void komeda_dev_destroy(struct komeda_dev *mdev); 97 + 98 + #endif /*_KOMEDA_DEV_H_*/
+196
drivers/gpu/drm/arm/display/komeda/komeda_pipeline.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 + #include "komeda_dev.h" 8 + #include "komeda_pipeline.h" 9 + 10 + /** komeda_pipeline_add - Add a pipeline to &komeda_dev */ 11 + struct komeda_pipeline * 12 + komeda_pipeline_add(struct komeda_dev *mdev, size_t size, 13 + struct komeda_pipeline_funcs *funcs) 14 + { 15 + struct komeda_pipeline *pipe; 16 + 17 + if (mdev->n_pipelines + 1 > KOMEDA_MAX_PIPELINES) { 18 + DRM_ERROR("Exceed max support %d pipelines.\n", 19 + KOMEDA_MAX_PIPELINES); 20 + return NULL; 21 + } 22 + 23 + if (size < sizeof(*pipe)) { 24 + DRM_ERROR("Request pipeline size too small.\n"); 25 + return NULL; 26 + } 27 + 28 + pipe = devm_kzalloc(mdev->dev, size, GFP_KERNEL); 29 + if (!pipe) 30 + return NULL; 31 + 32 + pipe->mdev = mdev; 33 + pipe->id = mdev->n_pipelines; 34 + pipe->funcs = funcs; 35 + 36 + mdev->pipelines[mdev->n_pipelines] = pipe; 37 + mdev->n_pipelines++; 38 + 39 + return pipe; 40 + } 41 + 42 + void komeda_pipeline_destroy(struct komeda_dev *mdev, 43 + struct komeda_pipeline *pipe) 44 + { 45 + struct komeda_component *c; 46 + int i; 47 + 48 + dp_for_each_set_bit(i, pipe->avail_comps) { 49 + c = komeda_pipeline_get_component(pipe, i); 50 + komeda_component_destroy(mdev, c); 51 + } 52 + 53 + clk_put(pipe->pxlclk); 54 + clk_put(pipe->aclk); 55 + 56 + devm_kfree(mdev->dev, pipe); 57 + } 58 + 59 + struct komeda_component ** 60 + komeda_pipeline_get_component_pos(struct komeda_pipeline *pipe, int id) 61 + { 62 + struct komeda_dev *mdev = pipe->mdev; 63 + struct komeda_pipeline *temp = NULL; 64 + struct komeda_component **pos = NULL; 65 + 66 + switch (id) { 67 + case KOMEDA_COMPONENT_LAYER0: 68 + case KOMEDA_COMPONENT_LAYER1: 69 + case KOMEDA_COMPONENT_LAYER2: 70 + case KOMEDA_COMPONENT_LAYER3: 71 + pos = to_cpos(pipe->layers[id - KOMEDA_COMPONENT_LAYER0]); 72 + break; 73 + case KOMEDA_COMPONENT_WB_LAYER: 74 + pos = to_cpos(pipe->wb_layer); 75 + break; 76 + case KOMEDA_COMPONENT_COMPIZ0: 77 + case KOMEDA_COMPONENT_COMPIZ1: 78 + temp = mdev->pipelines[id - KOMEDA_COMPONENT_COMPIZ0]; 79 + if (!temp) { 80 + DRM_ERROR("compiz-%d doesn't exist.\n", id); 81 + return NULL; 82 + } 83 + pos = to_cpos(temp->compiz); 84 + break; 85 + case KOMEDA_COMPONENT_SCALER0: 86 + case KOMEDA_COMPONENT_SCALER1: 87 + pos = to_cpos(pipe->scalers[id - KOMEDA_COMPONENT_SCALER0]); 88 + break; 89 + case KOMEDA_COMPONENT_IPS0: 90 + case KOMEDA_COMPONENT_IPS1: 91 + temp = mdev->pipelines[id - KOMEDA_COMPONENT_IPS0]; 92 + if (!temp) { 93 + DRM_ERROR("ips-%d doesn't exist.\n", id); 94 + return NULL; 95 + } 96 + pos = to_cpos(temp->improc); 97 + break; 98 + case KOMEDA_COMPONENT_TIMING_CTRLR: 99 + pos = to_cpos(pipe->ctrlr); 100 + break; 101 + default: 102 + pos = NULL; 103 + DRM_ERROR("Unknown pipeline resource ID: %d.\n", id); 104 + break; 105 + } 106 + 107 + return pos; 108 + } 109 + 110 + struct komeda_component * 111 + komeda_pipeline_get_component(struct komeda_pipeline *pipe, int id) 112 + { 113 + struct komeda_component **pos = NULL; 114 + struct komeda_component *c = NULL; 115 + 116 + pos = komeda_pipeline_get_component_pos(pipe, id); 117 + if (pos) 118 + c = *pos; 119 + 120 + return c; 121 + } 122 + 123 + /** komeda_component_add - Add a component to &komeda_pipeline */ 124 + struct komeda_component * 125 + komeda_component_add(struct komeda_pipeline *pipe, 126 + size_t comp_sz, u32 id, u32 hw_id, 127 + struct komeda_component_funcs *funcs, 128 + u8 max_active_inputs, u32 supported_inputs, 129 + u8 max_active_outputs, u32 __iomem *reg, 130 + const char *name_fmt, ...) 131 + { 132 + struct komeda_component **pos; 133 + struct komeda_component *c; 134 + int idx, *num = NULL; 135 + 136 + if (max_active_inputs > KOMEDA_COMPONENT_N_INPUTS) { 137 + WARN(1, "please large KOMEDA_COMPONENT_N_INPUTS to %d.\n", 138 + max_active_inputs); 139 + return NULL; 140 + } 141 + 142 + pos = komeda_pipeline_get_component_pos(pipe, id); 143 + if (!pos || (*pos)) 144 + return NULL; 145 + 146 + if (has_bit(id, KOMEDA_PIPELINE_LAYERS)) { 147 + idx = id - KOMEDA_COMPONENT_LAYER0; 148 + num = &pipe->n_layers; 149 + if (idx != pipe->n_layers) { 150 + DRM_ERROR("please add Layer by id sequence.\n"); 151 + return NULL; 152 + } 153 + } else if (has_bit(id, KOMEDA_PIPELINE_SCALERS)) { 154 + idx = id - KOMEDA_COMPONENT_SCALER0; 155 + num = &pipe->n_scalers; 156 + if (idx != pipe->n_scalers) { 157 + DRM_ERROR("please add Scaler by id sequence.\n"); 158 + return NULL; 159 + } 160 + } 161 + 162 + c = devm_kzalloc(pipe->mdev->dev, comp_sz, GFP_KERNEL); 163 + if (!c) 164 + return NULL; 165 + 166 + c->id = id; 167 + c->hw_id = hw_id; 168 + c->reg = reg; 169 + c->pipeline = pipe; 170 + c->max_active_inputs = max_active_inputs; 171 + c->max_active_outputs = max_active_outputs; 172 + c->supported_inputs = supported_inputs; 173 + c->funcs = funcs; 174 + 175 + if (name_fmt) { 176 + va_list args; 177 + 178 + va_start(args, name_fmt); 179 + vsnprintf(c->name, sizeof(c->name), name_fmt, args); 180 + va_end(args); 181 + } 182 + 183 + if (num) 184 + *num = *num + 1; 185 + 186 + pipe->avail_comps |= BIT(c->id); 187 + *pos = c; 188 + 189 + return c; 190 + } 191 + 192 + void komeda_component_destroy(struct komeda_dev *mdev, 193 + struct komeda_component *c) 194 + { 195 + devm_kfree(mdev->dev, c); 196 + }
+348
drivers/gpu/drm/arm/display/komeda/komeda_pipeline.h
··· 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 + 15 + #define KOMEDA_MAX_PIPELINES 2 16 + #define KOMEDA_PIPELINE_MAX_LAYERS 4 17 + #define KOMEDA_PIPELINE_MAX_SCALERS 2 18 + #define KOMEDA_COMPONENT_N_INPUTS 5 19 + 20 + /* pipeline component IDs */ 21 + enum { 22 + KOMEDA_COMPONENT_LAYER0 = 0, 23 + KOMEDA_COMPONENT_LAYER1 = 1, 24 + KOMEDA_COMPONENT_LAYER2 = 2, 25 + KOMEDA_COMPONENT_LAYER3 = 3, 26 + KOMEDA_COMPONENT_WB_LAYER = 7, /* write back layer */ 27 + KOMEDA_COMPONENT_SCALER0 = 8, 28 + KOMEDA_COMPONENT_SCALER1 = 9, 29 + KOMEDA_COMPONENT_SPLITTER = 12, 30 + KOMEDA_COMPONENT_MERGER = 14, 31 + KOMEDA_COMPONENT_COMPIZ0 = 16, /* compositor */ 32 + KOMEDA_COMPONENT_COMPIZ1 = 17, 33 + KOMEDA_COMPONENT_IPS0 = 20, /* post image processor */ 34 + KOMEDA_COMPONENT_IPS1 = 21, 35 + KOMEDA_COMPONENT_TIMING_CTRLR = 22, /* timing controller */ 36 + }; 37 + 38 + #define KOMEDA_PIPELINE_LAYERS (BIT(KOMEDA_COMPONENT_LAYER0) |\ 39 + BIT(KOMEDA_COMPONENT_LAYER1) |\ 40 + BIT(KOMEDA_COMPONENT_LAYER2) |\ 41 + BIT(KOMEDA_COMPONENT_LAYER3)) 42 + 43 + #define KOMEDA_PIPELINE_SCALERS (BIT(KOMEDA_COMPONENT_SCALER0) |\ 44 + BIT(KOMEDA_COMPONENT_SCALER1)) 45 + 46 + #define KOMEDA_PIPELINE_COMPIZS (BIT(KOMEDA_COMPONENT_COMPIZ0) |\ 47 + BIT(KOMEDA_COMPONENT_COMPIZ1)) 48 + 49 + #define KOMEDA_PIPELINE_IMPROCS (BIT(KOMEDA_COMPONENT_IPS0) |\ 50 + BIT(KOMEDA_COMPONENT_IPS1)) 51 + struct komeda_component; 52 + struct komeda_component_state; 53 + 54 + /** komeda_component_funcs - component control functions */ 55 + struct komeda_component_funcs { 56 + /** @validate: optional, 57 + * component may has special requirements or limitations, this function 58 + * supply HW the ability to do the further HW specific check. 59 + */ 60 + int (*validate)(struct komeda_component *c, 61 + struct komeda_component_state *state); 62 + /** @update: update is a active update */ 63 + void (*update)(struct komeda_component *c, 64 + struct komeda_component_state *state); 65 + /** @disable: disable component */ 66 + void (*disable)(struct komeda_component *c); 67 + /** @dump_register: Optional, dump registers to seq_file */ 68 + void (*dump_register)(struct komeda_component *c, struct seq_file *seq); 69 + }; 70 + 71 + /** 72 + * struct komeda_component 73 + * 74 + * struct komeda_component describe the data flow capabilities for how to link a 75 + * component into the display pipeline. 76 + * all specified components are subclass of this structure. 77 + */ 78 + struct komeda_component { 79 + /** @obj: treat component as private obj */ 80 + struct drm_private_obj obj; 81 + /** @pipeline: the komeda pipeline this component belongs to */ 82 + struct komeda_pipeline *pipeline; 83 + /** @name: component name */ 84 + char name[32]; 85 + /** 86 + * @reg: 87 + * component register base, 88 + * which is initialized by chip and used by chip only 89 + */ 90 + u32 __iomem *reg; 91 + /** @id: component id */ 92 + u32 id; 93 + /** @hw_ic: component hw id, 94 + * which is initialized by chip and used by chip only 95 + */ 96 + u32 hw_id; 97 + 98 + /** 99 + * @max_active_inputs: 100 + * @max_active_outpus: 101 + * 102 + * maximum number of inputs/outputs that can be active in the same time 103 + * Note: 104 + * the number isn't the bit number of @supported_inputs or 105 + * @supported_outputs, but may be less than it, since component may not 106 + * support enabling all @supported_inputs/outputs at the same time. 107 + */ 108 + u8 max_active_inputs; 109 + u8 max_active_outputs; 110 + /** 111 + * @supported_inputs: 112 + * @supported_outputs: 113 + * 114 + * bitmask of BIT(component->id) for the supported inputs/outputs 115 + * describes the possibilities of how a component is linked into a 116 + * pipeline. 117 + */ 118 + u32 supported_inputs; 119 + u32 supported_outputs; 120 + 121 + /** 122 + * @funcs: chip functions to access HW 123 + */ 124 + struct komeda_component_funcs *funcs; 125 + }; 126 + 127 + /** 128 + * struct komeda_component_output 129 + * 130 + * a component has multiple outputs, if want to know where the data 131 + * comes from, only know the component is not enough, we still need to know 132 + * its output port 133 + */ 134 + struct komeda_component_output { 135 + /** @component: indicate which component the data comes from */ 136 + struct komeda_component *component; 137 + /** @output_port: 138 + * the output port of the &komeda_component_output.component 139 + */ 140 + u8 output_port; 141 + }; 142 + 143 + /** 144 + * struct komeda_component_state 145 + * 146 + * component_state is the data flow configuration of the component, and it's 147 + * the superclass of all specific component_state like @komeda_layer_state, 148 + * @komeda_scaler_state 149 + */ 150 + struct komeda_component_state { 151 + /** @obj: tracking component_state by drm_atomic_state */ 152 + struct drm_private_state obj; 153 + struct komeda_component *component; 154 + /** 155 + * @binding_user: 156 + * currently bound user, the user can be crtc/plane/wb_conn, which is 157 + * valid decided by @component and @inputs 158 + * 159 + * - Layer: its user always is plane. 160 + * - compiz/improc/timing_ctrlr: the user is crtc. 161 + * - wb_layer: wb_conn; 162 + * - scaler: plane when input is layer, wb_conn if input is compiz. 163 + */ 164 + union { 165 + struct drm_crtc *crtc; 166 + struct drm_plane *plane; 167 + struct drm_connector *wb_conn; 168 + void *binding_user; 169 + }; 170 + /** 171 + * @active_inputs: 172 + * 173 + * active_inputs is bitmask of @inputs index 174 + * 175 + * - active_inputs = changed_active_inputs + unchanged_active_inputs 176 + * - affected_inputs = old->active_inputs + new->active_inputs; 177 + * - disabling_inputs = affected_inputs ^ active_inputs; 178 + * - changed_inputs = disabling_inputs + changed_active_inputs; 179 + * 180 + * NOTE: 181 + * changed_inputs doesn't include all active_input but only 182 + * @changed_active_inputs, and this bitmask can be used in chip 183 + * level for dirty update. 184 + */ 185 + u16 active_inputs; 186 + u16 changed_active_inputs; 187 + u16 affected_inputs; 188 + /** 189 + * @inputs: 190 + * 191 + * the specific inputs[i] only valid on BIT(i) has been set in 192 + * @active_inputs, if not the inputs[i] is undefined. 193 + */ 194 + struct komeda_component_output inputs[KOMEDA_COMPONENT_N_INPUTS]; 195 + }; 196 + 197 + static inline u16 component_disabling_inputs(struct komeda_component_state *st) 198 + { 199 + return st->affected_inputs ^ st->active_inputs; 200 + } 201 + 202 + static inline u16 component_changed_inputs(struct komeda_component_state *st) 203 + { 204 + return component_disabling_inputs(st) | st->changed_active_inputs; 205 + } 206 + 207 + #define to_comp(__c) (((__c) == NULL) ? NULL : &((__c)->base)) 208 + #define to_cpos(__c) ((struct komeda_component **)&(__c)) 209 + 210 + /* these structures are going to be filled in in uture patches */ 211 + struct komeda_layer { 212 + struct komeda_component base; 213 + /* layer specific features and caps */ 214 + }; 215 + 216 + struct komeda_layer_state { 217 + struct komeda_component_state base; 218 + /* layer specific configuration state */ 219 + }; 220 + 221 + struct komeda_compiz { 222 + struct komeda_component base; 223 + /* compiz specific features and caps */ 224 + }; 225 + 226 + struct komeda_compiz_state { 227 + struct komeda_component_state base; 228 + /* compiz specific configuration state */ 229 + }; 230 + 231 + struct komeda_scaler { 232 + struct komeda_component base; 233 + /* scaler features and caps */ 234 + }; 235 + 236 + struct komeda_scaler_state { 237 + struct komeda_component_state base; 238 + }; 239 + 240 + struct komeda_improc { 241 + struct komeda_component base; 242 + }; 243 + 244 + struct komeda_improc_state { 245 + struct komeda_component_state base; 246 + }; 247 + 248 + /* display timing controller */ 249 + struct komeda_timing_ctrlr { 250 + struct komeda_component base; 251 + }; 252 + 253 + struct komeda_timing_ctrlr_state { 254 + struct komeda_component_state base; 255 + }; 256 + 257 + /** struct komeda_pipeline_funcs */ 258 + struct komeda_pipeline_funcs { 259 + /* dump_register: Optional, dump registers to seq_file */ 260 + void (*dump_register)(struct komeda_pipeline *pipe, 261 + struct seq_file *sf); 262 + }; 263 + 264 + /** 265 + * struct komeda_pipeline 266 + * 267 + * Represent a complete display pipeline and hold all functional components. 268 + */ 269 + struct komeda_pipeline { 270 + /** @obj: link pipeline as private obj of drm_atomic_state */ 271 + struct drm_private_obj obj; 272 + /** @mdev: the parent komeda_dev */ 273 + struct komeda_dev *mdev; 274 + /** @pxlclk: pixel clock */ 275 + struct clk *pxlclk; 276 + /** @aclk: AXI clock */ 277 + struct clk *aclk; 278 + /** @id: pipeline id */ 279 + int id; 280 + /** @avail_comps: available components mask of pipeline */ 281 + u32 avail_comps; 282 + int n_layers; 283 + struct komeda_layer *layers[KOMEDA_PIPELINE_MAX_LAYERS]; 284 + int n_scalers; 285 + struct komeda_scaler *scalers[KOMEDA_PIPELINE_MAX_SCALERS]; 286 + struct komeda_compiz *compiz; 287 + struct komeda_layer *wb_layer; 288 + struct komeda_improc *improc; 289 + struct komeda_timing_ctrlr *ctrlr; 290 + struct komeda_pipeline_funcs *funcs; /* private pipeline functions */ 291 + }; 292 + 293 + /** 294 + * struct komeda_pipeline_state 295 + * 296 + * NOTE: 297 + * Unlike the pipeline, pipeline_state doesn’t gather any component_state 298 + * into it. It because all component will be managed by drm_atomic_state. 299 + */ 300 + struct komeda_pipeline_state { 301 + /** @obj: tracking pipeline_state by drm_atomic_state */ 302 + struct drm_private_state obj; 303 + struct komeda_pipeline *pipe; 304 + /** @crtc: currently bound crtc */ 305 + struct drm_crtc *crtc; 306 + /** 307 + * @active_comps: 308 + * 309 + * bitmask - BIT(component->id) of active components 310 + */ 311 + u32 active_comps; 312 + }; 313 + 314 + #define to_layer(c) container_of(c, struct komeda_layer, base) 315 + #define to_compiz(c) container_of(c, struct komeda_compiz, base) 316 + #define to_scaler(c) container_of(c, struct komeda_scaler, base) 317 + #define to_improc(c) container_of(c, struct komeda_improc, base) 318 + #define to_ctrlr(c) container_of(c, struct komeda_timing_ctrlr, base) 319 + 320 + #define to_layer_st(c) container_of(c, struct komeda_layer_state, base) 321 + #define to_compiz_st(c) container_of(c, struct komeda_compiz_state, base) 322 + #define to_scaler_st(c) container_of(c, struct komeda_scaler_state, base) 323 + #define to_improc_st(c) container_of(c, struct komeda_improc_state, base) 324 + #define to_ctrlr_st(c) container_of(c, struct komeda_timing_ctrlr_state, base) 325 + 326 + /* pipeline APIs */ 327 + struct komeda_pipeline * 328 + komeda_pipeline_add(struct komeda_dev *mdev, size_t size, 329 + struct komeda_pipeline_funcs *funcs); 330 + void komeda_pipeline_destroy(struct komeda_dev *mdev, 331 + struct komeda_pipeline *pipe); 332 + 333 + struct komeda_component * 334 + komeda_pipeline_get_component(struct komeda_pipeline *pipe, int id); 335 + 336 + /* component APIs */ 337 + struct komeda_component * 338 + komeda_component_add(struct komeda_pipeline *pipe, 339 + size_t comp_sz, u32 id, u32 hw_id, 340 + struct komeda_component_funcs *funcs, 341 + u8 max_active_inputs, u32 supported_inputs, 342 + u8 max_active_outputs, u32 __iomem *reg, 343 + const char *name_fmt, ...); 344 + 345 + void komeda_component_destroy(struct komeda_dev *mdev, 346 + struct komeda_component *c); 347 + 348 + #endif /* _KOMEDA_PIPELINE_H_*/