1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (C) 2018 Texas Instruments Incorporated - https://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 drm_for_each_bridge_in_chain(encoder
, bridge
) {
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 void tidss_encoder_destroy(struct drm_encoder
*encoder
)
60 drm_encoder_cleanup(encoder
);
64 static const struct drm_encoder_helper_funcs encoder_helper_funcs
= {
65 .atomic_check
= tidss_encoder_atomic_check
,
68 static const struct drm_encoder_funcs encoder_funcs
= {
69 .destroy
= tidss_encoder_destroy
,
72 struct drm_encoder
*tidss_encoder_create(struct tidss_device
*tidss
,
73 u32 encoder_type
, u32 possible_crtcs
)
75 struct drm_encoder
*enc
;
78 enc
= kzalloc(sizeof(*enc
), GFP_KERNEL
);
80 return ERR_PTR(-ENOMEM
);
82 enc
->possible_crtcs
= possible_crtcs
;
84 ret
= drm_encoder_init(&tidss
->ddev
, enc
, &encoder_funcs
,
91 drm_encoder_helper_add(enc
, &encoder_helper_funcs
);
93 dev_dbg(tidss
->dev
, "Encoder create done\n");