drm: Stop including drm_bridge.h from drm_crtc.h
[linux-block.git] / drivers / gpu / drm / rcar-du / rcar_du_encoder.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * rcar_du_encoder.c  --  R-Car Display Unit Encoder
4  *
5  * Copyright (C) 2013-2014 Renesas Electronics Corporation
6  *
7  * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
8  */
9
10 #include <linux/export.h>
11
12 #include <drm/drm_bridge.h>
13 #include <drm/drm_crtc.h>
14 #include <drm/drm_modeset_helper_vtables.h>
15 #include <drm/drm_panel.h>
16
17 #include "rcar_du_drv.h"
18 #include "rcar_du_encoder.h"
19 #include "rcar_du_kms.h"
20 #include "rcar_lvds.h"
21
22 /* -----------------------------------------------------------------------------
23  * Encoder
24  */
25
26 static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
27 };
28
29 static const struct drm_encoder_funcs encoder_funcs = {
30         .destroy = drm_encoder_cleanup,
31 };
32
33 static unsigned int rcar_du_encoder_count_ports(struct device_node *node)
34 {
35         struct device_node *ports;
36         struct device_node *port;
37         unsigned int num_ports = 0;
38
39         ports = of_get_child_by_name(node, "ports");
40         if (!ports)
41                 ports = of_node_get(node);
42
43         for_each_child_of_node(ports, port) {
44                 if (of_node_name_eq(port, "port"))
45                         num_ports++;
46         }
47
48         of_node_put(ports);
49
50         return num_ports;
51 }
52
53 int rcar_du_encoder_init(struct rcar_du_device *rcdu,
54                          enum rcar_du_output output,
55                          struct device_node *enc_node)
56 {
57         struct rcar_du_encoder *renc;
58         struct drm_encoder *encoder;
59         struct drm_bridge *bridge;
60         int ret;
61
62         renc = devm_kzalloc(rcdu->dev, sizeof(*renc), GFP_KERNEL);
63         if (renc == NULL)
64                 return -ENOMEM;
65
66         rcdu->encoders[output] = renc;
67         renc->output = output;
68         encoder = rcar_encoder_to_drm_encoder(renc);
69
70         dev_dbg(rcdu->dev, "initializing encoder %pOF for output %u\n",
71                 enc_node, output);
72
73         /*
74          * Locate the DRM bridge from the DT node. For the DPAD outputs, if the
75          * DT node has a single port, assume that it describes a panel and
76          * create a panel bridge.
77          */
78         if ((output == RCAR_DU_OUTPUT_DPAD0 ||
79              output == RCAR_DU_OUTPUT_DPAD1) &&
80             rcar_du_encoder_count_ports(enc_node) == 1) {
81                 struct drm_panel *panel = of_drm_find_panel(enc_node);
82
83                 if (IS_ERR(panel)) {
84                         ret = PTR_ERR(panel);
85                         goto done;
86                 }
87
88                 bridge = devm_drm_panel_bridge_add(rcdu->dev, panel,
89                                                    DRM_MODE_CONNECTOR_DPI);
90                 if (IS_ERR(bridge)) {
91                         ret = PTR_ERR(bridge);
92                         goto done;
93                 }
94         } else {
95                 bridge = of_drm_find_bridge(enc_node);
96                 if (!bridge) {
97                         ret = -EPROBE_DEFER;
98                         goto done;
99                 }
100         }
101
102         /*
103          * On Gen3 skip the LVDS1 output if the LVDS1 encoder is used as a
104          * companion for LVDS0 in dual-link mode.
105          */
106         if (rcdu->info->gen >= 3 && output == RCAR_DU_OUTPUT_LVDS1) {
107                 if (rcar_lvds_dual_link(bridge)) {
108                         ret = -ENOLINK;
109                         goto done;
110                 }
111         }
112
113         ret = drm_encoder_init(rcdu->ddev, encoder, &encoder_funcs,
114                                DRM_MODE_ENCODER_NONE, NULL);
115         if (ret < 0)
116                 goto done;
117
118         drm_encoder_helper_add(encoder, &encoder_helper_funcs);
119
120         /*
121          * Attach the bridge to the encoder. The bridge will create the
122          * connector.
123          */
124         ret = drm_bridge_attach(encoder, bridge, NULL);
125         if (ret) {
126                 drm_encoder_cleanup(encoder);
127                 return ret;
128         }
129
130 done:
131         if (ret < 0) {
132                 if (encoder->name)
133                         encoder->funcs->destroy(encoder);
134                 devm_kfree(rcdu->dev, renc);
135         }
136
137         return ret;
138 }