cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

komeda_pipeline.c (9452B)


      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 <drm/drm_print.h>
      8
      9#include "komeda_dev.h"
     10#include "komeda_pipeline.h"
     11
     12/** komeda_pipeline_add - Add a pipeline to &komeda_dev */
     13struct komeda_pipeline *
     14komeda_pipeline_add(struct komeda_dev *mdev, size_t size,
     15		    const struct komeda_pipeline_funcs *funcs)
     16{
     17	struct komeda_pipeline *pipe;
     18
     19	if (mdev->n_pipelines + 1 > KOMEDA_MAX_PIPELINES) {
     20		DRM_ERROR("Exceed max support %d pipelines.\n",
     21			  KOMEDA_MAX_PIPELINES);
     22		return ERR_PTR(-ENOSPC);
     23	}
     24
     25	if (size < sizeof(*pipe)) {
     26		DRM_ERROR("Request pipeline size too small.\n");
     27		return ERR_PTR(-EINVAL);
     28	}
     29
     30	pipe = devm_kzalloc(mdev->dev, size, GFP_KERNEL);
     31	if (!pipe)
     32		return ERR_PTR(-ENOMEM);
     33
     34	pipe->mdev = mdev;
     35	pipe->id   = mdev->n_pipelines;
     36	pipe->funcs = funcs;
     37
     38	mdev->pipelines[mdev->n_pipelines] = pipe;
     39	mdev->n_pipelines++;
     40
     41	return pipe;
     42}
     43
     44void komeda_pipeline_destroy(struct komeda_dev *mdev,
     45			     struct komeda_pipeline *pipe)
     46{
     47	struct komeda_component *c;
     48	int i;
     49	unsigned long avail_comps = pipe->avail_comps;
     50
     51	for_each_set_bit(i, &avail_comps, 32) {
     52		c = komeda_pipeline_get_component(pipe, i);
     53		komeda_component_destroy(mdev, c);
     54	}
     55
     56	clk_put(pipe->pxlclk);
     57
     58	of_node_put(pipe->of_output_links[0]);
     59	of_node_put(pipe->of_output_links[1]);
     60	of_node_put(pipe->of_output_port);
     61	of_node_put(pipe->of_node);
     62
     63	devm_kfree(mdev->dev, pipe);
     64}
     65
     66static struct komeda_component **
     67komeda_pipeline_get_component_pos(struct komeda_pipeline *pipe, int id)
     68{
     69	struct komeda_dev *mdev = pipe->mdev;
     70	struct komeda_pipeline *temp = NULL;
     71	struct komeda_component **pos = NULL;
     72
     73	switch (id) {
     74	case KOMEDA_COMPONENT_LAYER0:
     75	case KOMEDA_COMPONENT_LAYER1:
     76	case KOMEDA_COMPONENT_LAYER2:
     77	case KOMEDA_COMPONENT_LAYER3:
     78		pos = to_cpos(pipe->layers[id - KOMEDA_COMPONENT_LAYER0]);
     79		break;
     80	case KOMEDA_COMPONENT_WB_LAYER:
     81		pos = to_cpos(pipe->wb_layer);
     82		break;
     83	case KOMEDA_COMPONENT_COMPIZ0:
     84	case KOMEDA_COMPONENT_COMPIZ1:
     85		temp = mdev->pipelines[id - KOMEDA_COMPONENT_COMPIZ0];
     86		if (!temp) {
     87			DRM_ERROR("compiz-%d doesn't exist.\n", id);
     88			return NULL;
     89		}
     90		pos = to_cpos(temp->compiz);
     91		break;
     92	case KOMEDA_COMPONENT_SCALER0:
     93	case KOMEDA_COMPONENT_SCALER1:
     94		pos = to_cpos(pipe->scalers[id - KOMEDA_COMPONENT_SCALER0]);
     95		break;
     96	case KOMEDA_COMPONENT_SPLITTER:
     97		pos = to_cpos(pipe->splitter);
     98		break;
     99	case KOMEDA_COMPONENT_MERGER:
    100		pos = to_cpos(pipe->merger);
    101		break;
    102	case KOMEDA_COMPONENT_IPS0:
    103	case KOMEDA_COMPONENT_IPS1:
    104		temp = mdev->pipelines[id - KOMEDA_COMPONENT_IPS0];
    105		if (!temp) {
    106			DRM_ERROR("ips-%d doesn't exist.\n", id);
    107			return NULL;
    108		}
    109		pos = to_cpos(temp->improc);
    110		break;
    111	case KOMEDA_COMPONENT_TIMING_CTRLR:
    112		pos = to_cpos(pipe->ctrlr);
    113		break;
    114	default:
    115		pos = NULL;
    116		DRM_ERROR("Unknown pipeline resource ID: %d.\n", id);
    117		break;
    118	}
    119
    120	return pos;
    121}
    122
    123struct komeda_component *
    124komeda_pipeline_get_component(struct komeda_pipeline *pipe, int id)
    125{
    126	struct komeda_component **pos = NULL;
    127	struct komeda_component *c = NULL;
    128
    129	pos = komeda_pipeline_get_component_pos(pipe, id);
    130	if (pos)
    131		c = *pos;
    132
    133	return c;
    134}
    135
    136struct komeda_component *
    137komeda_pipeline_get_first_component(struct komeda_pipeline *pipe,
    138				    u32 comp_mask)
    139{
    140	struct komeda_component *c = NULL;
    141	unsigned long comp_mask_local = (unsigned long)comp_mask;
    142	int id;
    143
    144	id = find_first_bit(&comp_mask_local, 32);
    145	if (id < 32)
    146		c = komeda_pipeline_get_component(pipe, id);
    147
    148	return c;
    149}
    150
    151static struct komeda_component *
    152komeda_component_pickup_input(struct komeda_component *c, u32 avail_comps)
    153{
    154	u32 avail_inputs = c->supported_inputs & (avail_comps);
    155
    156	return komeda_pipeline_get_first_component(c->pipeline, avail_inputs);
    157}
    158
    159/** komeda_component_add - Add a component to &komeda_pipeline */
    160struct komeda_component *
    161komeda_component_add(struct komeda_pipeline *pipe,
    162		     size_t comp_sz, u32 id, u32 hw_id,
    163		     const struct komeda_component_funcs *funcs,
    164		     u8 max_active_inputs, u32 supported_inputs,
    165		     u8 max_active_outputs, u32 __iomem *reg,
    166		     const char *name_fmt, ...)
    167{
    168	struct komeda_component **pos;
    169	struct komeda_component *c;
    170	int idx, *num = NULL;
    171
    172	if (max_active_inputs > KOMEDA_COMPONENT_N_INPUTS) {
    173		WARN(1, "please large KOMEDA_COMPONENT_N_INPUTS to %d.\n",
    174		     max_active_inputs);
    175		return ERR_PTR(-ENOSPC);
    176	}
    177
    178	pos = komeda_pipeline_get_component_pos(pipe, id);
    179	if (!pos || (*pos))
    180		return ERR_PTR(-EINVAL);
    181
    182	if (has_bit(id, KOMEDA_PIPELINE_LAYERS)) {
    183		idx = id - KOMEDA_COMPONENT_LAYER0;
    184		num = &pipe->n_layers;
    185		if (idx != pipe->n_layers) {
    186			DRM_ERROR("please add Layer by id sequence.\n");
    187			return ERR_PTR(-EINVAL);
    188		}
    189	} else if (has_bit(id,  KOMEDA_PIPELINE_SCALERS)) {
    190		idx = id - KOMEDA_COMPONENT_SCALER0;
    191		num = &pipe->n_scalers;
    192		if (idx != pipe->n_scalers) {
    193			DRM_ERROR("please add Scaler by id sequence.\n");
    194			return ERR_PTR(-EINVAL);
    195		}
    196	}
    197
    198	c = devm_kzalloc(pipe->mdev->dev, comp_sz, GFP_KERNEL);
    199	if (!c)
    200		return ERR_PTR(-ENOMEM);
    201
    202	c->id = id;
    203	c->hw_id = hw_id;
    204	c->reg = reg;
    205	c->pipeline = pipe;
    206	c->max_active_inputs = max_active_inputs;
    207	c->max_active_outputs = max_active_outputs;
    208	c->supported_inputs = supported_inputs;
    209	c->funcs = funcs;
    210
    211	if (name_fmt) {
    212		va_list args;
    213
    214		va_start(args, name_fmt);
    215		vsnprintf(c->name, sizeof(c->name), name_fmt, args);
    216		va_end(args);
    217	}
    218
    219	if (num)
    220		*num = *num + 1;
    221
    222	pipe->avail_comps |= BIT(c->id);
    223	*pos = c;
    224
    225	return c;
    226}
    227
    228void komeda_component_destroy(struct komeda_dev *mdev,
    229			      struct komeda_component *c)
    230{
    231	devm_kfree(mdev->dev, c);
    232}
    233
    234static void komeda_component_dump(struct komeda_component *c)
    235{
    236	if (!c)
    237		return;
    238
    239	DRM_DEBUG("	%s: ID %d-0x%08lx.\n",
    240		  c->name, c->id, BIT(c->id));
    241	DRM_DEBUG("		max_active_inputs:%d, supported_inputs: 0x%08x.\n",
    242		  c->max_active_inputs, c->supported_inputs);
    243	DRM_DEBUG("		max_active_outputs:%d, supported_outputs: 0x%08x.\n",
    244		  c->max_active_outputs, c->supported_outputs);
    245}
    246
    247static void komeda_pipeline_dump(struct komeda_pipeline *pipe)
    248{
    249	struct komeda_component *c;
    250	int id;
    251	unsigned long avail_comps = pipe->avail_comps;
    252
    253	DRM_INFO("Pipeline-%d: n_layers: %d, n_scalers: %d, output: %s.\n",
    254		 pipe->id, pipe->n_layers, pipe->n_scalers,
    255		 pipe->dual_link ? "dual-link" : "single-link");
    256	DRM_INFO("	output_link[0]: %s.\n",
    257		 pipe->of_output_links[0] ?
    258		 pipe->of_output_links[0]->full_name : "none");
    259	DRM_INFO("	output_link[1]: %s.\n",
    260		 pipe->of_output_links[1] ?
    261		 pipe->of_output_links[1]->full_name : "none");
    262
    263	for_each_set_bit(id, &avail_comps, 32) {
    264		c = komeda_pipeline_get_component(pipe, id);
    265
    266		komeda_component_dump(c);
    267	}
    268}
    269
    270static void komeda_component_verify_inputs(struct komeda_component *c)
    271{
    272	struct komeda_pipeline *pipe = c->pipeline;
    273	struct komeda_component *input;
    274	int id;
    275	unsigned long supported_inputs = c->supported_inputs;
    276
    277	for_each_set_bit(id, &supported_inputs, 32) {
    278		input = komeda_pipeline_get_component(pipe, id);
    279		if (!input) {
    280			c->supported_inputs &= ~(BIT(id));
    281			DRM_WARN("Can not find input(ID-%d) for component: %s.\n",
    282				 id, c->name);
    283			continue;
    284		}
    285
    286		input->supported_outputs |= BIT(c->id);
    287	}
    288}
    289
    290static struct komeda_layer *
    291komeda_get_layer_split_right_layer(struct komeda_pipeline *pipe,
    292				   struct komeda_layer *left)
    293{
    294	int index = left->base.id - KOMEDA_COMPONENT_LAYER0;
    295	int i;
    296
    297	for (i = index + 1; i < pipe->n_layers; i++)
    298		if (left->layer_type == pipe->layers[i]->layer_type)
    299			return pipe->layers[i];
    300	return NULL;
    301}
    302
    303static void komeda_pipeline_assemble(struct komeda_pipeline *pipe)
    304{
    305	struct komeda_component *c;
    306	struct komeda_layer *layer;
    307	int i, id;
    308	unsigned long avail_comps = pipe->avail_comps;
    309
    310	for_each_set_bit(id, &avail_comps, 32) {
    311		c = komeda_pipeline_get_component(pipe, id);
    312		komeda_component_verify_inputs(c);
    313	}
    314	/* calculate right layer for the layer split */
    315	for (i = 0; i < pipe->n_layers; i++) {
    316		layer = pipe->layers[i];
    317
    318		layer->right = komeda_get_layer_split_right_layer(pipe, layer);
    319	}
    320
    321	if (pipe->dual_link && !pipe->ctrlr->supports_dual_link) {
    322		pipe->dual_link = false;
    323		DRM_WARN("PIPE-%d doesn't support dual-link, ignore DT dual-link configuration.\n",
    324			 pipe->id);
    325	}
    326}
    327
    328/* if pipeline_A accept another pipeline_B's component as input, treat
    329 * pipeline_B as slave of pipeline_A.
    330 */
    331struct komeda_pipeline *
    332komeda_pipeline_get_slave(struct komeda_pipeline *master)
    333{
    334	struct komeda_component *slave;
    335
    336	slave = komeda_component_pickup_input(&master->compiz->base,
    337					      KOMEDA_PIPELINE_COMPIZS);
    338
    339	return slave ? slave->pipeline : NULL;
    340}
    341
    342int komeda_assemble_pipelines(struct komeda_dev *mdev)
    343{
    344	struct komeda_pipeline *pipe;
    345	int i;
    346
    347	for (i = 0; i < mdev->n_pipelines; i++) {
    348		pipe = mdev->pipelines[i];
    349
    350		komeda_pipeline_assemble(pipe);
    351		komeda_pipeline_dump(pipe);
    352	}
    353
    354	return 0;
    355}
    356
    357void komeda_pipeline_dump_register(struct komeda_pipeline *pipe,
    358				   struct seq_file *sf)
    359{
    360	struct komeda_component *c;
    361	u32 id;
    362	unsigned long avail_comps;
    363
    364	seq_printf(sf, "\n======== Pipeline-%d ==========\n", pipe->id);
    365
    366	if (pipe->funcs && pipe->funcs->dump_register)
    367		pipe->funcs->dump_register(pipe, sf);
    368
    369	avail_comps = pipe->avail_comps;
    370	for_each_set_bit(id, &avail_comps, 32) {
    371		c = komeda_pipeline_get_component(pipe, id);
    372
    373		seq_printf(sf, "\n------%s------\n", c->name);
    374		if (c->funcs->dump_register)
    375			c->funcs->dump_register(c, sf);
    376	}
    377}