brintos

brintos / linux-shallow public Read only

0
0
Text · 5.1 KiB · ebccb74 Raw
199 lines · c
1// SPDX-License-Identifier: GPL-2.02/*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_framebuffer.h>8#include "komeda_dev.h"9#include "komeda_kms.h"10 11static int12komeda_wb_init_data_flow(struct komeda_layer *wb_layer,13			 struct drm_connector_state *conn_st,14			 struct komeda_crtc_state *kcrtc_st,15			 struct komeda_data_flow_cfg *dflow)16{17	struct drm_framebuffer *fb = conn_st->writeback_job->fb;18 19	memset(dflow, 0, sizeof(*dflow));20 21	dflow->out_w = fb->width;22	dflow->out_h = fb->height;23 24	/* the write back data comes from the compiz */25	pipeline_composition_size(kcrtc_st, &dflow->in_w, &dflow->in_h);26	dflow->input.component = &wb_layer->base.pipeline->compiz->base;27	/* compiz doesn't output alpha */28	dflow->pixel_blend_mode = DRM_MODE_BLEND_PIXEL_NONE;29	dflow->rot = DRM_MODE_ROTATE_0;30 31	komeda_complete_data_flow_cfg(wb_layer, dflow, fb);32 33	return 0;34}35 36static int37komeda_wb_encoder_atomic_check(struct drm_encoder *encoder,38			       struct drm_crtc_state *crtc_st,39			       struct drm_connector_state *conn_st)40{41	struct komeda_crtc_state *kcrtc_st = to_kcrtc_st(crtc_st);42	struct drm_writeback_job *writeback_job = conn_st->writeback_job;43	struct komeda_layer *wb_layer;44	struct komeda_data_flow_cfg dflow;45	int err;46 47	if (!writeback_job)48		return 0;49 50	if (!crtc_st->active) {51		DRM_DEBUG_ATOMIC("Cannot write the composition result out on a inactive CRTC.\n");52		return -EINVAL;53	}54 55	wb_layer = to_kconn(to_wb_conn(conn_st->connector))->wb_layer;56 57	/*58	 * No need for a full modested when the only connector changed is the59	 * writeback connector.60	 */61	if (crtc_st->connectors_changed &&62	    is_only_changed_connector(crtc_st, conn_st->connector))63		crtc_st->connectors_changed = false;64 65	err = komeda_wb_init_data_flow(wb_layer, conn_st, kcrtc_st, &dflow);66	if (err)67		return err;68 69	if (dflow.en_split)70		err = komeda_build_wb_split_data_flow(wb_layer,71				conn_st, kcrtc_st, &dflow);72	else73		err = komeda_build_wb_data_flow(wb_layer,74				conn_st, kcrtc_st, &dflow);75 76	return err;77}78 79static const struct drm_encoder_helper_funcs komeda_wb_encoder_helper_funcs = {80	.atomic_check = komeda_wb_encoder_atomic_check,81};82 83static int84komeda_wb_connector_get_modes(struct drm_connector *connector)85{86	return 0;87}88 89static enum drm_mode_status90komeda_wb_connector_mode_valid(struct drm_connector *connector,91			       struct drm_display_mode *mode)92{93	struct drm_device *dev = connector->dev;94	struct drm_mode_config *mode_config = &dev->mode_config;95	int w = mode->hdisplay, h = mode->vdisplay;96 97	if ((w < mode_config->min_width) || (w > mode_config->max_width))98		return MODE_BAD_HVALUE;99 100	if ((h < mode_config->min_height) || (h > mode_config->max_height))101		return MODE_BAD_VVALUE;102 103	return MODE_OK;104}105 106static const struct drm_connector_helper_funcs komeda_wb_conn_helper_funcs = {107	.get_modes	= komeda_wb_connector_get_modes,108	.mode_valid	= komeda_wb_connector_mode_valid,109};110 111static enum drm_connector_status112komeda_wb_connector_detect(struct drm_connector *connector, bool force)113{114	return connector_status_connected;115}116 117static int118komeda_wb_connector_fill_modes(struct drm_connector *connector,119			       uint32_t maxX, uint32_t maxY)120{121	return 0;122}123 124static void komeda_wb_connector_destroy(struct drm_connector *connector)125{126	drm_connector_cleanup(connector);127	kfree(to_kconn(to_wb_conn(connector)));128}129 130static const struct drm_connector_funcs komeda_wb_connector_funcs = {131	.reset			= drm_atomic_helper_connector_reset,132	.detect			= komeda_wb_connector_detect,133	.fill_modes		= komeda_wb_connector_fill_modes,134	.destroy		= komeda_wb_connector_destroy,135	.atomic_duplicate_state	= drm_atomic_helper_connector_duplicate_state,136	.atomic_destroy_state	= drm_atomic_helper_connector_destroy_state,137};138 139static int komeda_wb_connector_add(struct komeda_kms_dev *kms,140				   struct komeda_crtc *kcrtc)141{142	struct komeda_dev *mdev = kms->base.dev_private;143	struct komeda_wb_connector *kwb_conn;144	struct drm_writeback_connector *wb_conn;145	struct drm_display_info *info;146	u32 *formats, n_formats = 0;147	int err;148 149	if (!kcrtc->master->wb_layer)150		return 0;151 152	kwb_conn = kzalloc(sizeof(*kwb_conn), GFP_KERNEL);153	if (!kwb_conn)154		return -ENOMEM;155 156	kwb_conn->wb_layer = kcrtc->master->wb_layer;157 158	wb_conn = &kwb_conn->base;159 160	formats = komeda_get_layer_fourcc_list(&mdev->fmt_tbl,161					       kwb_conn->wb_layer->layer_type,162					       &n_formats);163 164	err = drm_writeback_connector_init(&kms->base, wb_conn,165					   &komeda_wb_connector_funcs,166					   &komeda_wb_encoder_helper_funcs,167					   formats, n_formats,168					   BIT(drm_crtc_index(&kcrtc->base)));169	komeda_put_fourcc_list(formats);170	if (err) {171		kfree(kwb_conn);172		return err;173	}174 175	drm_connector_helper_add(&wb_conn->base, &komeda_wb_conn_helper_funcs);176 177	info = &kwb_conn->base.base.display_info;178	info->bpc = __fls(kcrtc->master->improc->supported_color_depths);179	info->color_formats = kcrtc->master->improc->supported_color_formats;180 181	kcrtc->wb_conn = kwb_conn;182 183	return 0;184}185 186int komeda_kms_add_wb_connectors(struct komeda_kms_dev *kms,187				 struct komeda_dev *mdev)188{189	int i, err;190 191	for (i = 0; i < kms->n_crtcs; i++) {192		err = komeda_wb_connector_add(kms, &kms->crtcs[i]);193		if (err)194			return err;195	}196 197	return 0;198}199