1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
4 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
7 #include <linux/export.h>
9 #include <drm/drm_crtc.h>
10 #include <drm/drm_crtc_helper.h>
11 #include <drm/drm_panel.h>
12 #include <drm/drm_of.h>
14 #include "tidss_crtc.h"
15 #include "tidss_drv.h"
16 #include "tidss_encoder.h"
18 static int tidss_encoder_atomic_check(struct drm_encoder
*encoder
,
19 struct drm_crtc_state
*crtc_state
,
20 struct drm_connector_state
*conn_state
)
22 struct drm_device
*ddev
= encoder
->dev
;
23 struct tidss_crtc_state
*tcrtc_state
= to_tidss_crtc_state(crtc_state
);
24 struct drm_display_info
*di
= &conn_state
->connector
->display_info
;
25 struct drm_bridge
*bridge
;
26 bool bus_flags_set
= false;
28 dev_dbg(ddev
->dev
, "%s\n", __func__
);
31 * Take the bus_flags from the first bridge that defines
32 * bridge timings, or from the connector's display_info if no
33 * bridge defines the timings.
35 list_for_each_entry(bridge
, &encoder
->bridge_chain
, chain_node
) {
39 tcrtc_state
->bus_flags
= bridge
->timings
->input_bus_flags
;
44 if (!di
->bus_formats
|| di
->num_bus_formats
== 0) {
45 dev_err(ddev
->dev
, "%s: No bus_formats in connected display\n",
50 // XXX any cleaner way to set bus format and flags?
51 tcrtc_state
->bus_format
= di
->bus_formats
[0];
53 tcrtc_state
->bus_flags
= di
->bus_flags
;
58 static const struct drm_encoder_helper_funcs encoder_helper_funcs
= {
59 .atomic_check
= tidss_encoder_atomic_check
,
62 static const struct drm_encoder_funcs encoder_funcs
= {
63 .destroy
= drm_encoder_cleanup
,
66 struct drm_encoder
*tidss_encoder_create(struct tidss_device
*tidss
,
67 u32 encoder_type
, u32 possible_crtcs
)
69 struct drm_encoder
*enc
;
72 enc
= devm_kzalloc(tidss
->dev
, sizeof(*enc
), GFP_KERNEL
);
74 return ERR_PTR(-ENOMEM
);
76 enc
->possible_crtcs
= possible_crtcs
;
78 ret
= drm_encoder_init(&tidss
->ddev
, enc
, &encoder_funcs
,
83 drm_encoder_helper_add(enc
, &encoder_helper_funcs
);
85 dev_dbg(tidss
->dev
, "Encoder create done\n");