1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include <drm/drm_atomic_helper.h>
20#include <drm/drm_crtc_helper.h>
21
22#include "hibmc_drm_drv.h"
23#include "hibmc_drm_regs.h"
24
25static int hibmc_connector_get_modes(struct drm_connector *connector)
26{
27 return drm_add_modes_noedid(connector, 800, 600);
28}
29
30static enum drm_mode_status hibmc_connector_mode_valid(struct drm_connector *connector,
31 struct drm_display_mode *mode)
32{
33 return MODE_OK;
34}
35
36static struct drm_encoder *
37hibmc_connector_best_encoder(struct drm_connector *connector)
38{
39 return drm_encoder_find(connector->dev, NULL, connector->encoder_ids[0]);
40}
41
42static const struct drm_connector_helper_funcs
43 hibmc_connector_helper_funcs = {
44 .get_modes = hibmc_connector_get_modes,
45 .mode_valid = hibmc_connector_mode_valid,
46 .best_encoder = hibmc_connector_best_encoder,
47};
48
49static const struct drm_connector_funcs hibmc_connector_funcs = {
50 .fill_modes = drm_helper_probe_single_connector_modes,
51 .destroy = drm_connector_cleanup,
52 .reset = drm_atomic_helper_connector_reset,
53 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
54 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
55};
56
57static struct drm_connector *
58hibmc_connector_init(struct hibmc_drm_private *priv)
59{
60 struct drm_device *dev = priv->dev;
61 struct drm_connector *connector;
62 int ret;
63
64 connector = devm_kzalloc(dev->dev, sizeof(*connector), GFP_KERNEL);
65 if (!connector) {
66 DRM_ERROR("failed to alloc memory when init connector\n");
67 return ERR_PTR(-ENOMEM);
68 }
69
70 ret = drm_connector_init(dev, connector,
71 &hibmc_connector_funcs,
72 DRM_MODE_CONNECTOR_VGA);
73 if (ret) {
74 DRM_ERROR("failed to init connector: %d\n", ret);
75 return ERR_PTR(ret);
76 }
77 drm_connector_helper_add(connector,
78 &hibmc_connector_helper_funcs);
79
80 return connector;
81}
82
83static void hibmc_encoder_mode_set(struct drm_encoder *encoder,
84 struct drm_display_mode *mode,
85 struct drm_display_mode *adj_mode)
86{
87 u32 reg;
88 struct drm_device *dev = encoder->dev;
89 struct hibmc_drm_private *priv = dev->dev_private;
90
91 reg = readl(priv->mmio + HIBMC_DISPLAY_CONTROL_HISILE);
92 reg |= HIBMC_DISPLAY_CONTROL_FPVDDEN(1);
93 reg |= HIBMC_DISPLAY_CONTROL_PANELDATE(1);
94 reg |= HIBMC_DISPLAY_CONTROL_FPEN(1);
95 reg |= HIBMC_DISPLAY_CONTROL_VBIASEN(1);
96 writel(reg, priv->mmio + HIBMC_DISPLAY_CONTROL_HISILE);
97}
98
99static const struct drm_encoder_helper_funcs hibmc_encoder_helper_funcs = {
100 .mode_set = hibmc_encoder_mode_set,
101};
102
103static const struct drm_encoder_funcs hibmc_encoder_funcs = {
104 .destroy = drm_encoder_cleanup,
105};
106
107int hibmc_vdac_init(struct hibmc_drm_private *priv)
108{
109 struct drm_device *dev = priv->dev;
110 struct drm_encoder *encoder;
111 struct drm_connector *connector;
112 int ret;
113
114 connector = hibmc_connector_init(priv);
115 if (IS_ERR(connector)) {
116 DRM_ERROR("failed to create connector: %ld\n",
117 PTR_ERR(connector));
118 return PTR_ERR(connector);
119 }
120
121 encoder = devm_kzalloc(dev->dev, sizeof(*encoder), GFP_KERNEL);
122 if (!encoder) {
123 DRM_ERROR("failed to alloc memory when init encoder\n");
124 return -ENOMEM;
125 }
126
127 encoder->possible_crtcs = 0x1;
128 ret = drm_encoder_init(dev, encoder, &hibmc_encoder_funcs,
129 DRM_MODE_ENCODER_DAC, NULL);
130 if (ret) {
131 DRM_ERROR("failed to init encoder: %d\n", ret);
132 return ret;
133 }
134
135 drm_encoder_helper_add(encoder, &hibmc_encoder_helper_funcs);
136 drm_connector_attach_encoder(connector, encoder);
137
138 return 0;
139}
140