2 * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 and
6 * only version 2 as published by the Free Software Foundation.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
14 #include "drm/drm_edid.h"
18 struct edp_connector
{
19 struct drm_connector base
;
22 #define to_edp_connector(x) container_of(x, struct edp_connector, base)
24 static enum drm_connector_status
edp_connector_detect(
25 struct drm_connector
*connector
, bool force
)
27 struct edp_connector
*edp_connector
= to_edp_connector(connector
);
28 struct msm_edp
*edp
= edp_connector
->edp
;
31 return msm_edp_ctrl_panel_connected(edp
->ctrl
) ?
32 connector_status_connected
: connector_status_disconnected
;
35 static void edp_connector_destroy(struct drm_connector
*connector
)
37 struct edp_connector
*edp_connector
= to_edp_connector(connector
);
40 drm_connector_unregister(connector
);
41 drm_connector_cleanup(connector
);
46 static int edp_connector_get_modes(struct drm_connector
*connector
)
48 struct edp_connector
*edp_connector
= to_edp_connector(connector
);
49 struct msm_edp
*edp
= edp_connector
->edp
;
51 struct edid
*drm_edid
= NULL
;
55 ret
= msm_edp_ctrl_get_panel_info(edp
->ctrl
, connector
, &drm_edid
);
59 drm_mode_connector_update_edid_property(connector
, drm_edid
);
61 ret
= drm_add_edid_modes(connector
, drm_edid
);
66 static int edp_connector_mode_valid(struct drm_connector
*connector
,
67 struct drm_display_mode
*mode
)
69 struct edp_connector
*edp_connector
= to_edp_connector(connector
);
70 struct msm_edp
*edp
= edp_connector
->edp
;
71 struct msm_drm_private
*priv
= connector
->dev
->dev_private
;
72 struct msm_kms
*kms
= priv
->kms
;
73 long actual
, requested
;
75 requested
= 1000 * mode
->clock
;
76 actual
= kms
->funcs
->round_pixclk(kms
,
77 requested
, edp_connector
->edp
->encoder
);
79 DBG("requested=%ld, actual=%ld", requested
, actual
);
80 if (actual
!= requested
)
81 return MODE_CLOCK_RANGE
;
83 if (!msm_edp_ctrl_pixel_clock_valid(
84 edp
->ctrl
, mode
->clock
, NULL
, NULL
))
85 return MODE_CLOCK_RANGE
;
87 /* Invalidate all modes if color format is not supported */
88 if (connector
->display_info
.bpc
> 8)
94 static struct drm_encoder
*
95 edp_connector_best_encoder(struct drm_connector
*connector
)
97 struct edp_connector
*edp_connector
= to_edp_connector(connector
);
100 return edp_connector
->edp
->encoder
;
103 static const struct drm_connector_funcs edp_connector_funcs
= {
104 .dpms
= drm_atomic_helper_connector_dpms
,
105 .detect
= edp_connector_detect
,
106 .fill_modes
= drm_helper_probe_single_connector_modes
,
107 .destroy
= edp_connector_destroy
,
108 .reset
= drm_atomic_helper_connector_reset
,
109 .atomic_duplicate_state
= drm_atomic_helper_connector_duplicate_state
,
110 .atomic_destroy_state
= drm_atomic_helper_connector_destroy_state
,
113 static const struct drm_connector_helper_funcs edp_connector_helper_funcs
= {
114 .get_modes
= edp_connector_get_modes
,
115 .mode_valid
= edp_connector_mode_valid
,
116 .best_encoder
= edp_connector_best_encoder
,
119 /* initialize connector */
120 struct drm_connector
*msm_edp_connector_init(struct msm_edp
*edp
)
122 struct drm_connector
*connector
= NULL
;
123 struct edp_connector
*edp_connector
;
126 edp_connector
= kzalloc(sizeof(*edp_connector
), GFP_KERNEL
);
127 if (!edp_connector
) {
132 edp_connector
->edp
= edp
;
134 connector
= &edp_connector
->base
;
136 ret
= drm_connector_init(edp
->dev
, connector
, &edp_connector_funcs
,
137 DRM_MODE_CONNECTOR_eDP
);
141 drm_connector_helper_add(connector
, &edp_connector_helper_funcs
);
143 /* We don't support HPD, so only poll status until connected. */
144 connector
->polled
= DRM_CONNECTOR_POLL_CONNECT
;
146 /* Display driver doesn't support interlace now. */
147 connector
->interlace_allowed
= false;
148 connector
->doublescan_allowed
= false;
150 ret
= drm_connector_register(connector
);
154 drm_mode_connector_attach_encoder(connector
, edp
->encoder
);
160 edp_connector_destroy(connector
);