1 // SPDX-License-Identifier: GPL-2.0
3 * (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
4 * Author: James.Qian.Wang <james.qian.wang@arm.com>
7 #include "komeda_dev.h"
8 #include "komeda_kms.h"
11 komeda_wb_init_data_flow(struct komeda_layer
*wb_layer
,
12 struct drm_connector_state
*conn_st
,
13 struct komeda_crtc_state
*kcrtc_st
,
14 struct komeda_data_flow_cfg
*dflow
)
16 struct drm_framebuffer
*fb
= conn_st
->writeback_job
->fb
;
18 memset(dflow
, 0, sizeof(*dflow
));
20 dflow
->out_w
= fb
->width
;
21 dflow
->out_h
= fb
->height
;
23 /* the write back data comes from the compiz */
24 pipeline_composition_size(kcrtc_st
, &dflow
->in_w
, &dflow
->in_h
);
25 dflow
->input
.component
= &wb_layer
->base
.pipeline
->compiz
->base
;
26 /* compiz doesn't output alpha */
27 dflow
->pixel_blend_mode
= DRM_MODE_BLEND_PIXEL_NONE
;
28 dflow
->rot
= DRM_MODE_ROTATE_0
;
30 komeda_complete_data_flow_cfg(wb_layer
, dflow
, fb
);
36 komeda_wb_encoder_atomic_check(struct drm_encoder
*encoder
,
37 struct drm_crtc_state
*crtc_st
,
38 struct drm_connector_state
*conn_st
)
40 struct komeda_crtc_state
*kcrtc_st
= to_kcrtc_st(crtc_st
);
41 struct drm_writeback_job
*writeback_job
= conn_st
->writeback_job
;
42 struct komeda_layer
*wb_layer
;
43 struct komeda_data_flow_cfg dflow
;
49 if (!crtc_st
->active
) {
50 DRM_DEBUG_ATOMIC("Cannot write the composition result out on a inactive CRTC.\n");
54 wb_layer
= to_kconn(to_wb_conn(conn_st
->connector
))->wb_layer
;
57 * No need for a full modested when the only connector changed is the
58 * writeback connector.
60 if (crtc_st
->connectors_changed
&&
61 is_only_changed_connector(crtc_st
, conn_st
->connector
))
62 crtc_st
->connectors_changed
= false;
64 err
= komeda_wb_init_data_flow(wb_layer
, conn_st
, kcrtc_st
, &dflow
);
69 err
= komeda_build_wb_split_data_flow(wb_layer
,
70 conn_st
, kcrtc_st
, &dflow
);
72 err
= komeda_build_wb_data_flow(wb_layer
,
73 conn_st
, kcrtc_st
, &dflow
);
78 static const struct drm_encoder_helper_funcs komeda_wb_encoder_helper_funcs
= {
79 .atomic_check
= komeda_wb_encoder_atomic_check
,
83 komeda_wb_connector_get_modes(struct drm_connector
*connector
)
88 static enum drm_mode_status
89 komeda_wb_connector_mode_valid(struct drm_connector
*connector
,
90 struct drm_display_mode
*mode
)
92 struct drm_device
*dev
= connector
->dev
;
93 struct drm_mode_config
*mode_config
= &dev
->mode_config
;
94 int w
= mode
->hdisplay
, h
= mode
->vdisplay
;
96 if ((w
< mode_config
->min_width
) || (w
> mode_config
->max_width
))
97 return MODE_BAD_HVALUE
;
99 if ((h
< mode_config
->min_height
) || (h
> mode_config
->max_height
))
100 return MODE_BAD_VVALUE
;
105 static const struct drm_connector_helper_funcs komeda_wb_conn_helper_funcs
= {
106 .get_modes
= komeda_wb_connector_get_modes
,
107 .mode_valid
= komeda_wb_connector_mode_valid
,
110 static enum drm_connector_status
111 komeda_wb_connector_detect(struct drm_connector
*connector
, bool force
)
113 return connector_status_connected
;
117 komeda_wb_connector_fill_modes(struct drm_connector
*connector
,
118 uint32_t maxX
, uint32_t maxY
)
123 static void komeda_wb_connector_destroy(struct drm_connector
*connector
)
125 drm_connector_cleanup(connector
);
126 kfree(to_kconn(to_wb_conn(connector
)));
129 static const struct drm_connector_funcs komeda_wb_connector_funcs
= {
130 .reset
= drm_atomic_helper_connector_reset
,
131 .detect
= komeda_wb_connector_detect
,
132 .fill_modes
= komeda_wb_connector_fill_modes
,
133 .destroy
= komeda_wb_connector_destroy
,
134 .atomic_duplicate_state
= drm_atomic_helper_connector_duplicate_state
,
135 .atomic_destroy_state
= drm_atomic_helper_connector_destroy_state
,
138 static int komeda_wb_connector_add(struct komeda_kms_dev
*kms
,
139 struct komeda_crtc
*kcrtc
)
141 struct komeda_dev
*mdev
= kms
->base
.dev_private
;
142 struct komeda_wb_connector
*kwb_conn
;
143 struct drm_writeback_connector
*wb_conn
;
144 struct drm_display_info
*info
;
145 u32
*formats
, n_formats
= 0;
148 if (!kcrtc
->master
->wb_layer
)
151 kwb_conn
= kzalloc(sizeof(*kwb_conn
), GFP_KERNEL
);
155 kwb_conn
->wb_layer
= kcrtc
->master
->wb_layer
;
157 wb_conn
= &kwb_conn
->base
;
158 wb_conn
->encoder
.possible_crtcs
= BIT(drm_crtc_index(&kcrtc
->base
));
160 formats
= komeda_get_layer_fourcc_list(&mdev
->fmt_tbl
,
161 kwb_conn
->wb_layer
->layer_type
,
164 err
= drm_writeback_connector_init(&kms
->base
, wb_conn
,
165 &komeda_wb_connector_funcs
,
166 &komeda_wb_encoder_helper_funcs
,
168 komeda_put_fourcc_list(formats
);
174 drm_connector_helper_add(&wb_conn
->base
, &komeda_wb_conn_helper_funcs
);
176 info
= &kwb_conn
->base
.base
.display_info
;
177 info
->bpc
= __fls(kcrtc
->master
->improc
->supported_color_depths
);
178 info
->color_formats
= kcrtc
->master
->improc
->supported_color_formats
;
180 kcrtc
->wb_conn
= kwb_conn
;
185 int komeda_kms_add_wb_connectors(struct komeda_kms_dev
*kms
,
186 struct komeda_dev
*mdev
)
190 for (i
= 0; i
< kms
->n_crtcs
; i
++) {
191 err
= komeda_wb_connector_add(kms
, &kms
->crtcs
[i
]);