|
23 | 23 | #include <video/of_videomode.h>
|
24 | 24 |
|
25 | 25 | #include <drm/drmP.h>
|
| 26 | +#include <drm/drm_crtc.h> |
| 27 | +#include <drm/drm_crtc_helper.h> |
26 | 28 |
|
27 | 29 | #include "exynos_drm_drv.h"
|
28 | 30 | #include "exynos_dp_core.h"
|
29 | 31 |
|
| 32 | +#define ctx_from_connector(c) container_of(c, struct exynos_dp_device, \ |
| 33 | + connector) |
| 34 | + |
30 | 35 | static int exynos_dp_init_dp(struct exynos_dp_device *dp)
|
31 | 36 | {
|
32 | 37 | exynos_dp_reset(dp);
|
@@ -897,21 +902,98 @@ static void exynos_dp_hotplug(struct work_struct *work)
|
897 | 902 | dev_err(dp->dev, "unable to config video\n");
|
898 | 903 | }
|
899 | 904 |
|
900 |
| -static bool exynos_dp_display_is_connected(struct exynos_drm_display *display) |
| 905 | +static enum drm_connector_status exynos_dp_detect( |
| 906 | + struct drm_connector *connector, bool force) |
901 | 907 | {
|
902 |
| - return true; |
| 908 | + return connector_status_connected; |
903 | 909 | }
|
904 | 910 |
|
905 |
| -static void *exynos_dp_get_panel(struct exynos_drm_display *display) |
| 911 | +static void exynos_dp_connector_destroy(struct drm_connector *connector) |
906 | 912 | {
|
907 |
| - struct exynos_dp_device *dp = display->ctx; |
| 913 | +} |
| 914 | + |
| 915 | +static struct drm_connector_funcs exynos_dp_connector_funcs = { |
| 916 | + .dpms = drm_helper_connector_dpms, |
| 917 | + .fill_modes = drm_helper_probe_single_connector_modes, |
| 918 | + .detect = exynos_dp_detect, |
| 919 | + .destroy = exynos_dp_connector_destroy, |
| 920 | +}; |
| 921 | + |
| 922 | +static int exynos_dp_get_modes(struct drm_connector *connector) |
| 923 | +{ |
| 924 | + struct exynos_dp_device *dp = ctx_from_connector(connector); |
| 925 | + struct drm_display_mode *mode; |
| 926 | + |
| 927 | + mode = drm_mode_create(connector->dev); |
| 928 | + if (!mode) { |
| 929 | + DRM_ERROR("failed to create a new display mode.\n"); |
| 930 | + return 0; |
| 931 | + } |
908 | 932 |
|
909 |
| - return &dp->panel; |
| 933 | + drm_display_mode_from_videomode(&dp->panel.vm, mode); |
| 934 | + mode->width_mm = dp->panel.width_mm; |
| 935 | + mode->height_mm = dp->panel.height_mm; |
| 936 | + connector->display_info.width_mm = mode->width_mm; |
| 937 | + connector->display_info.height_mm = mode->height_mm; |
| 938 | + |
| 939 | + mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED; |
| 940 | + drm_mode_set_name(mode); |
| 941 | + drm_mode_probed_add(connector, mode); |
| 942 | + |
| 943 | + return 1; |
910 | 944 | }
|
911 | 945 |
|
912 |
| -static int exynos_dp_check_mode(struct exynos_drm_display *display, |
| 946 | +static int exynos_dp_mode_valid(struct drm_connector *connector, |
913 | 947 | struct drm_display_mode *mode)
|
914 | 948 | {
|
| 949 | + return MODE_OK; |
| 950 | +} |
| 951 | + |
| 952 | +static struct drm_encoder *exynos_dp_best_encoder( |
| 953 | + struct drm_connector *connector) |
| 954 | +{ |
| 955 | + struct exynos_dp_device *dp = ctx_from_connector(connector); |
| 956 | + |
| 957 | + return dp->encoder; |
| 958 | +} |
| 959 | + |
| 960 | +static struct drm_connector_helper_funcs exynos_dp_connector_helper_funcs = { |
| 961 | + .get_modes = exynos_dp_get_modes, |
| 962 | + .mode_valid = exynos_dp_mode_valid, |
| 963 | + .best_encoder = exynos_dp_best_encoder, |
| 964 | +}; |
| 965 | + |
| 966 | +static int exynos_dp_initialize(struct exynos_drm_display *display, |
| 967 | + struct drm_device *drm_dev) |
| 968 | +{ |
| 969 | + struct exynos_dp_device *dp = display->ctx; |
| 970 | + |
| 971 | + dp->drm_dev = drm_dev; |
| 972 | + |
| 973 | + return 0; |
| 974 | +} |
| 975 | + |
| 976 | +static int exynos_dp_create_connector(struct exynos_drm_display *display, |
| 977 | + struct drm_encoder *encoder) |
| 978 | +{ |
| 979 | + struct exynos_dp_device *dp = display->ctx; |
| 980 | + struct drm_connector *connector = &dp->connector; |
| 981 | + int ret; |
| 982 | + |
| 983 | + dp->encoder = encoder; |
| 984 | + connector->polled = DRM_CONNECTOR_POLL_HPD; |
| 985 | + |
| 986 | + ret = drm_connector_init(dp->drm_dev, connector, |
| 987 | + &exynos_dp_connector_funcs, DRM_MODE_CONNECTOR_eDP); |
| 988 | + if (ret) { |
| 989 | + DRM_ERROR("Failed to initialize connector with drm\n"); |
| 990 | + return ret; |
| 991 | + } |
| 992 | + |
| 993 | + drm_connector_helper_add(connector, &exynos_dp_connector_helper_funcs); |
| 994 | + drm_sysfs_connector_add(connector); |
| 995 | + drm_mode_connector_attach_encoder(connector, encoder); |
| 996 | + |
915 | 997 | return 0;
|
916 | 998 | }
|
917 | 999 |
|
@@ -983,9 +1065,8 @@ static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
|
983 | 1065 | }
|
984 | 1066 |
|
985 | 1067 | static struct exynos_drm_display_ops exynos_dp_display_ops = {
|
986 |
| - .is_connected = exynos_dp_display_is_connected, |
987 |
| - .get_panel = exynos_dp_get_panel, |
988 |
| - .check_mode = exynos_dp_check_mode, |
| 1068 | + .initialize = exynos_dp_initialize, |
| 1069 | + .create_connector = exynos_dp_create_connector, |
989 | 1070 | .dpms = exynos_dp_dpms,
|
990 | 1071 | };
|
991 | 1072 |
|
|
0 commit comments