diff options
author | Rahul Sharma <rahul.sharma@samsung.com> | 2013-01-04 07:59:11 -0500 |
---|---|---|
committer | Inki Dae <inki.dae@samsung.com> | 2013-01-25 00:38:43 -0500 |
commit | 9c08e4ba81a73862e15b3eb4e6ae2e11aaf4151b (patch) | |
tree | d4c9ab1009a0843f856647e563aa17d8de299f60 /drivers/gpu | |
parent | 4af6924b8adce0c408ec3f366c42a61e0c304b28 (diff) |
drm/exynos: let drm handle edid allocations
There's no need to allocate edid twice and do a memcpy when drm helpers
exist to do just that. This patch cleans that interaction up, and
doesn't keep the edid hanging around in the connector.
v4:
- removed error check for drm_mode_connector_update_edid_property
which is expected to fail for Virtual Connectors like VIDI.
Thanks to Seung-Woo Kim.
v3:
- removed MAX_EDID as it is not used anymore.
v2:
- changed vidi_get_edid callback inside vidi driver.
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_connector.c | 33 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_drv.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_hdmi.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_hdmi.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_vidi.c | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_hdmi.c | 25 |
6 files changed, 46 insertions, 48 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_connector.c b/drivers/gpu/drm/exynos/exynos_drm_connector.c index ab37437bad8a..4c5b6859c9ea 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_connector.c +++ b/drivers/gpu/drm/exynos/exynos_drm_connector.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include "exynos_drm_drv.h" | 18 | #include "exynos_drm_drv.h" |
19 | #include "exynos_drm_encoder.h" | 19 | #include "exynos_drm_encoder.h" |
20 | 20 | ||
21 | #define MAX_EDID 256 | ||
22 | #define to_exynos_connector(x) container_of(x, struct exynos_drm_connector,\ | 21 | #define to_exynos_connector(x) container_of(x, struct exynos_drm_connector,\ |
23 | drm_connector) | 22 | drm_connector) |
24 | 23 | ||
@@ -96,7 +95,9 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector) | |||
96 | to_exynos_connector(connector); | 95 | to_exynos_connector(connector); |
97 | struct exynos_drm_manager *manager = exynos_connector->manager; | 96 | struct exynos_drm_manager *manager = exynos_connector->manager; |
98 | struct exynos_drm_display_ops *display_ops = manager->display_ops; | 97 | struct exynos_drm_display_ops *display_ops = manager->display_ops; |
99 | unsigned int count; | 98 | struct edid *edid = NULL; |
99 | unsigned int count = 0; | ||
100 | int ret; | ||
100 | 101 | ||
101 | DRM_DEBUG_KMS("%s\n", __FILE__); | 102 | DRM_DEBUG_KMS("%s\n", __FILE__); |
102 | 103 | ||
@@ -114,27 +115,21 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector) | |||
114 | * because lcd panel has only one mode. | 115 | * because lcd panel has only one mode. |
115 | */ | 116 | */ |
116 | if (display_ops->get_edid) { | 117 | if (display_ops->get_edid) { |
117 | int ret; | 118 | edid = display_ops->get_edid(manager->dev, connector); |
118 | void *edid; | 119 | if (IS_ERR_OR_NULL(edid)) { |
119 | 120 | ret = PTR_ERR(edid); | |
120 | edid = kzalloc(MAX_EDID, GFP_KERNEL); | 121 | edid = NULL; |
121 | if (!edid) { | 122 | DRM_ERROR("Panel operation get_edid failed %d\n", ret); |
122 | DRM_ERROR("failed to allocate edid\n"); | 123 | goto out; |
123 | return 0; | ||
124 | } | 124 | } |
125 | 125 | ||
126 | ret = display_ops->get_edid(manager->dev, connector, | 126 | count = drm_add_edid_modes(connector, edid); |
127 | edid, MAX_EDID); | 127 | if (count < 0) { |
128 | if (ret < 0) { | 128 | DRM_ERROR("Add edid modes failed %d\n", count); |
129 | DRM_ERROR("failed to get edid data.\n"); | 129 | goto out; |
130 | kfree(edid); | ||
131 | edid = NULL; | ||
132 | return 0; | ||
133 | } | 130 | } |
134 | 131 | ||
135 | drm_mode_connector_update_edid_property(connector, edid); | 132 | drm_mode_connector_update_edid_property(connector, edid); |
136 | count = drm_add_edid_modes(connector, edid); | ||
137 | kfree(edid); | ||
138 | } else { | 133 | } else { |
139 | struct exynos_drm_panel_info *panel; | 134 | struct exynos_drm_panel_info *panel; |
140 | struct drm_display_mode *mode = drm_mode_create(connector->dev); | 135 | struct drm_display_mode *mode = drm_mode_create(connector->dev); |
@@ -161,6 +156,8 @@ static int exynos_drm_connector_get_modes(struct drm_connector *connector) | |||
161 | count = 1; | 156 | count = 1; |
162 | } | 157 | } |
163 | 158 | ||
159 | out: | ||
160 | kfree(edid); | ||
164 | return count; | 161 | return count; |
165 | } | 162 | } |
166 | 163 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h index b9e51bc09e81..4606fac7241a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.h +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h | |||
@@ -148,8 +148,8 @@ struct exynos_drm_overlay { | |||
148 | struct exynos_drm_display_ops { | 148 | struct exynos_drm_display_ops { |
149 | enum exynos_drm_output_type type; | 149 | enum exynos_drm_output_type type; |
150 | bool (*is_connected)(struct device *dev); | 150 | bool (*is_connected)(struct device *dev); |
151 | int (*get_edid)(struct device *dev, struct drm_connector *connector, | 151 | struct edid *(*get_edid)(struct device *dev, |
152 | u8 *edid, int len); | 152 | struct drm_connector *connector); |
153 | void *(*get_panel)(struct device *dev); | 153 | void *(*get_panel)(struct device *dev); |
154 | int (*check_timing)(struct device *dev, void *timing); | 154 | int (*check_timing)(struct device *dev, void *timing); |
155 | int (*power_on)(struct device *dev, int mode); | 155 | int (*power_on)(struct device *dev, int mode); |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c index 850e9950b7da..427d2dea9f07 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.c | |||
@@ -108,18 +108,17 @@ static bool drm_hdmi_is_connected(struct device *dev) | |||
108 | return false; | 108 | return false; |
109 | } | 109 | } |
110 | 110 | ||
111 | static int drm_hdmi_get_edid(struct device *dev, | 111 | struct edid *drm_hdmi_get_edid(struct device *dev, |
112 | struct drm_connector *connector, u8 *edid, int len) | 112 | struct drm_connector *connector) |
113 | { | 113 | { |
114 | struct drm_hdmi_context *ctx = to_context(dev); | 114 | struct drm_hdmi_context *ctx = to_context(dev); |
115 | 115 | ||
116 | DRM_DEBUG_KMS("%s\n", __FILE__); | 116 | DRM_DEBUG_KMS("%s\n", __FILE__); |
117 | 117 | ||
118 | if (hdmi_ops && hdmi_ops->get_edid) | 118 | if (hdmi_ops && hdmi_ops->get_edid) |
119 | return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector, edid, | 119 | return hdmi_ops->get_edid(ctx->hdmi_ctx->ctx, connector); |
120 | len); | ||
121 | 120 | ||
122 | return 0; | 121 | return NULL; |
123 | } | 122 | } |
124 | 123 | ||
125 | static int drm_hdmi_check_timing(struct device *dev, void *timing) | 124 | static int drm_hdmi_check_timing(struct device *dev, void *timing) |
diff --git a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h index 784a7e9a766c..d80516fc9ed7 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_hdmi.h +++ b/drivers/gpu/drm/exynos/exynos_drm_hdmi.h | |||
@@ -30,8 +30,8 @@ struct exynos_drm_hdmi_context { | |||
30 | struct exynos_hdmi_ops { | 30 | struct exynos_hdmi_ops { |
31 | /* display */ | 31 | /* display */ |
32 | bool (*is_connected)(void *ctx); | 32 | bool (*is_connected)(void *ctx); |
33 | int (*get_edid)(void *ctx, struct drm_connector *connector, | 33 | struct edid *(*get_edid)(void *ctx, |
34 | u8 *edid, int len); | 34 | struct drm_connector *connector); |
35 | int (*check_timing)(void *ctx, void *timing); | 35 | int (*check_timing)(void *ctx, void *timing); |
36 | int (*power_on)(void *ctx, int mode); | 36 | int (*power_on)(void *ctx, int mode); |
37 | 37 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_vidi.c b/drivers/gpu/drm/exynos/exynos_drm_vidi.c index d0ca3c4e06c6..6d91000c56f9 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_vidi.c +++ b/drivers/gpu/drm/exynos/exynos_drm_vidi.c | |||
@@ -98,10 +98,12 @@ static bool vidi_display_is_connected(struct device *dev) | |||
98 | return ctx->connected ? true : false; | 98 | return ctx->connected ? true : false; |
99 | } | 99 | } |
100 | 100 | ||
101 | static int vidi_get_edid(struct device *dev, struct drm_connector *connector, | 101 | static struct edid *vidi_get_edid(struct device *dev, |
102 | u8 *edid, int len) | 102 | struct drm_connector *connector) |
103 | { | 103 | { |
104 | struct vidi_context *ctx = get_vidi_context(dev); | 104 | struct vidi_context *ctx = get_vidi_context(dev); |
105 | struct edid *edid; | ||
106 | int edid_len; | ||
105 | 107 | ||
106 | DRM_DEBUG_KMS("%s\n", __FILE__); | 108 | DRM_DEBUG_KMS("%s\n", __FILE__); |
107 | 109 | ||
@@ -111,13 +113,18 @@ static int vidi_get_edid(struct device *dev, struct drm_connector *connector, | |||
111 | */ | 113 | */ |
112 | if (!ctx->raw_edid) { | 114 | if (!ctx->raw_edid) { |
113 | DRM_DEBUG_KMS("raw_edid is null.\n"); | 115 | DRM_DEBUG_KMS("raw_edid is null.\n"); |
114 | return -EFAULT; | 116 | return ERR_PTR(-EFAULT); |
115 | } | 117 | } |
116 | 118 | ||
117 | memcpy(edid, ctx->raw_edid, min((1 + ctx->raw_edid->extensions) | 119 | edid_len = (1 + ctx->raw_edid->extensions) * EDID_LENGTH; |
118 | * EDID_LENGTH, len)); | 120 | edid = kzalloc(edid_len, GFP_KERNEL); |
121 | if (!edid) { | ||
122 | DRM_DEBUG_KMS("failed to allocate edid\n"); | ||
123 | return ERR_PTR(-ENOMEM); | ||
124 | } | ||
119 | 125 | ||
120 | return 0; | 126 | memcpy(edid, ctx->raw_edid, edid_len); |
127 | return edid; | ||
121 | } | 128 | } |
122 | 129 | ||
123 | static void *vidi_get_panel(struct device *dev) | 130 | static void *vidi_get_panel(struct device *dev) |
diff --git a/drivers/gpu/drm/exynos/exynos_hdmi.c b/drivers/gpu/drm/exynos/exynos_hdmi.c index 41ff79d8ac8e..24dbb7f7c290 100644 --- a/drivers/gpu/drm/exynos/exynos_hdmi.c +++ b/drivers/gpu/drm/exynos/exynos_hdmi.c | |||
@@ -1391,8 +1391,7 @@ static bool hdmi_is_connected(void *ctx) | |||
1391 | return hdata->hpd; | 1391 | return hdata->hpd; |
1392 | } | 1392 | } |
1393 | 1393 | ||
1394 | static int hdmi_get_edid(void *ctx, struct drm_connector *connector, | 1394 | static struct edid *hdmi_get_edid(void *ctx, struct drm_connector *connector) |
1395 | u8 *edid, int len) | ||
1396 | { | 1395 | { |
1397 | struct edid *raw_edid; | 1396 | struct edid *raw_edid; |
1398 | struct hdmi_context *hdata = ctx; | 1397 | struct hdmi_context *hdata = ctx; |
@@ -1400,22 +1399,18 @@ static int hdmi_get_edid(void *ctx, struct drm_connector *connector, | |||
1400 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); | 1399 | DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__); |
1401 | 1400 | ||
1402 | if (!hdata->ddc_port) | 1401 | if (!hdata->ddc_port) |
1403 | return -ENODEV; | 1402 | return ERR_PTR(-ENODEV); |
1404 | 1403 | ||
1405 | raw_edid = drm_get_edid(connector, hdata->ddc_port->adapter); | 1404 | raw_edid = drm_get_edid(connector, hdata->ddc_port->adapter); |
1406 | if (raw_edid) { | 1405 | if (!raw_edid) |
1407 | hdata->dvi_mode = !drm_detect_hdmi_monitor(raw_edid); | 1406 | return ERR_PTR(-ENODEV); |
1408 | memcpy(edid, raw_edid, min((1 + raw_edid->extensions) | ||
1409 | * EDID_LENGTH, len)); | ||
1410 | DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n", | ||
1411 | (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"), | ||
1412 | raw_edid->width_cm, raw_edid->height_cm); | ||
1413 | kfree(raw_edid); | ||
1414 | } else { | ||
1415 | return -ENODEV; | ||
1416 | } | ||
1417 | 1407 | ||
1418 | return 0; | 1408 | hdata->dvi_mode = !drm_detect_hdmi_monitor(raw_edid); |
1409 | DRM_DEBUG_KMS("%s : width[%d] x height[%d]\n", | ||
1410 | (hdata->dvi_mode ? "dvi monitor" : "hdmi monitor"), | ||
1411 | raw_edid->width_cm, raw_edid->height_cm); | ||
1412 | |||
1413 | return raw_edid; | ||
1419 | } | 1414 | } |
1420 | 1415 | ||
1421 | static int hdmi_v13_check_timing(struct fb_videomode *check_timing) | 1416 | static int hdmi_v13_check_timing(struct fb_videomode *check_timing) |