45
45
#include <linux/gpio.h>
46
46
#include <media/s5p_hdmi.h>
47
47
48
- #define MAX_WIDTH 1920
49
- #define MAX_HEIGHT 1080
50
48
#define get_hdmi_display (dev ) platform_get_drvdata(to_platform_device(dev))
49
+ #define ctx_from_connector (c ) container_of(c, struct hdmi_context, connector)
51
50
52
51
/* AVI header and aspect ratio */
53
52
#define HDMI_AVI_VERSION 0x02
@@ -172,6 +171,8 @@ struct hdmi_conf_regs {
172
171
struct hdmi_context {
173
172
struct device * dev ;
174
173
struct drm_device * drm_dev ;
174
+ struct drm_connector connector ;
175
+ struct drm_encoder * encoder ;
175
176
bool hpd ;
176
177
bool powered ;
177
178
bool dvi_mode ;
@@ -790,42 +791,46 @@ static void hdmi_reg_infoframe(struct hdmi_context *hdata,
790
791
}
791
792
}
792
793
793
- static int hdmi_initialize (struct exynos_drm_display * display ,
794
- struct drm_device * drm_dev )
794
+ static enum drm_connector_status hdmi_detect (struct drm_connector * connector ,
795
+ bool force )
795
796
{
796
- struct hdmi_context * hdata = display -> ctx ;
797
+ struct hdmi_context * hdata = ctx_from_connector ( connector ) ;
797
798
798
- hdata -> drm_dev = drm_dev ;
799
-
800
- return 0 ;
799
+ return hdata -> hpd ? connector_status_connected :
800
+ connector_status_disconnected ;
801
801
}
802
802
803
- static bool hdmi_is_connected (struct exynos_drm_display * display )
803
+ static void hdmi_connector_destroy (struct drm_connector * connector )
804
804
{
805
- struct hdmi_context * hdata = display -> ctx ;
806
-
807
- return hdata -> hpd ;
808
805
}
809
806
810
- static struct edid * hdmi_get_edid (struct exynos_drm_display * display ,
811
- struct drm_connector * connector )
807
+ static struct drm_connector_funcs hdmi_connector_funcs = {
808
+ .dpms = drm_helper_connector_dpms ,
809
+ .fill_modes = drm_helper_probe_single_connector_modes ,
810
+ .detect = hdmi_detect ,
811
+ .destroy = hdmi_connector_destroy ,
812
+ };
813
+
814
+ static int hdmi_get_modes (struct drm_connector * connector )
812
815
{
813
- struct edid * raw_edid ;
814
- struct hdmi_context * hdata = display -> ctx ;
816
+ struct hdmi_context * hdata = ctx_from_connector ( connector ) ;
817
+ struct edid * edid ;
815
818
816
819
if (!hdata -> ddc_port )
817
- return ERR_PTR ( - ENODEV ) ;
820
+ return - ENODEV ;
818
821
819
- raw_edid = drm_get_edid (connector , hdata -> ddc_port -> adapter );
820
- if (!raw_edid )
821
- return ERR_PTR ( - ENODEV ) ;
822
+ edid = drm_get_edid (connector , hdata -> ddc_port -> adapter );
823
+ if (!edid )
824
+ return - ENODEV ;
822
825
823
- hdata -> dvi_mode = !drm_detect_hdmi_monitor (raw_edid );
826
+ hdata -> dvi_mode = !drm_detect_hdmi_monitor (edid );
824
827
DRM_DEBUG_KMS ("%s : width[%d] x height[%d]\n" ,
825
828
(hdata -> dvi_mode ? "dvi monitor" : "hdmi monitor" ),
826
- raw_edid -> width_cm , raw_edid -> height_cm );
829
+ edid -> width_cm , edid -> height_cm );
830
+
831
+ drm_mode_connector_update_edid_property (connector , edid );
827
832
828
- return raw_edid ;
833
+ return drm_add_edid_modes ( connector , edid ) ;
829
834
}
830
835
831
836
static int hdmi_find_phy_conf (struct hdmi_context * hdata , u32 pixel_clock )
@@ -850,10 +855,10 @@ static int hdmi_find_phy_conf(struct hdmi_context *hdata, u32 pixel_clock)
850
855
return - EINVAL ;
851
856
}
852
857
853
- static int hdmi_check_mode (struct exynos_drm_display * display ,
858
+ static int hdmi_mode_valid (struct drm_connector * connector ,
854
859
struct drm_display_mode * mode )
855
860
{
856
- struct hdmi_context * hdata = display -> ctx ;
861
+ struct hdmi_context * hdata = ctx_from_connector ( connector ) ;
857
862
int ret ;
858
863
859
864
DRM_DEBUG_KMS ("xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n" ,
@@ -863,11 +868,60 @@ static int hdmi_check_mode(struct exynos_drm_display *display,
863
868
864
869
ret = mixer_check_mode (mode );
865
870
if (ret )
866
- return ret ;
871
+ return MODE_BAD ;
867
872
868
873
ret = hdmi_find_phy_conf (hdata , mode -> clock * 1000 );
869
874
if (ret < 0 )
875
+ return MODE_BAD ;
876
+
877
+ return MODE_OK ;
878
+ }
879
+
880
+ static struct drm_encoder * hdmi_best_encoder (struct drm_connector * connector )
881
+ {
882
+ struct hdmi_context * hdata = ctx_from_connector (connector );
883
+
884
+ return hdata -> encoder ;
885
+ }
886
+
887
+ static struct drm_connector_helper_funcs hdmi_connector_helper_funcs = {
888
+ .get_modes = hdmi_get_modes ,
889
+ .mode_valid = hdmi_mode_valid ,
890
+ .best_encoder = hdmi_best_encoder ,
891
+ };
892
+
893
+ static int hdmi_create_connector (struct exynos_drm_display * display ,
894
+ struct drm_encoder * encoder )
895
+ {
896
+ struct hdmi_context * hdata = display -> ctx ;
897
+ struct drm_connector * connector = & hdata -> connector ;
898
+ int ret ;
899
+
900
+ hdata -> encoder = encoder ;
901
+ connector -> interlace_allowed = true;
902
+ connector -> polled = DRM_CONNECTOR_POLL_HPD ;
903
+
904
+ ret = drm_connector_init (hdata -> drm_dev , connector ,
905
+ & hdmi_connector_funcs , DRM_MODE_CONNECTOR_HDMIA );
906
+ if (ret ) {
907
+ DRM_ERROR ("Failed to initialize connector with drm\n" );
870
908
return ret ;
909
+ }
910
+
911
+ drm_connector_helper_add (connector , & hdmi_connector_helper_funcs );
912
+ drm_sysfs_connector_add (connector );
913
+ drm_mode_connector_attach_encoder (connector , encoder );
914
+
915
+ return 0 ;
916
+ }
917
+
918
+ static int hdmi_initialize (struct exynos_drm_display * display ,
919
+ struct drm_device * drm_dev )
920
+ {
921
+ struct hdmi_context * hdata = display -> ctx ;
922
+
923
+ hdata -> drm_dev = drm_dev ;
924
+
871
925
return 0 ;
872
926
}
873
927
@@ -883,20 +937,20 @@ static void hdmi_mode_fixup(struct exynos_drm_display *display,
883
937
884
938
drm_mode_set_crtcinfo (adjusted_mode , 0 );
885
939
886
- mode_ok = hdmi_check_mode ( display , adjusted_mode );
940
+ mode_ok = hdmi_mode_valid ( connector , adjusted_mode );
887
941
888
942
/* just return if user desired mode exists. */
889
- if (mode_ok == 0 )
943
+ if (mode_ok == MODE_OK )
890
944
return ;
891
945
892
946
/*
893
947
* otherwise, find the most suitable mode among modes and change it
894
948
* to adjusted_mode.
895
949
*/
896
950
list_for_each_entry (m , & connector -> modes , head ) {
897
- mode_ok = hdmi_check_mode ( display , m );
951
+ mode_ok = hdmi_mode_valid ( connector , m );
898
952
899
- if (mode_ok == 0 ) {
953
+ if (mode_ok == MODE_OK ) {
900
954
DRM_INFO ("desired mode doesn't exist so\n" );
901
955
DRM_INFO ("use the most suitable mode among modes.\n" );
902
956
@@ -1753,13 +1807,6 @@ static void hdmi_mode_set(struct exynos_drm_display *display,
1753
1807
hdmi_v14_mode_set (hdata , mode );
1754
1808
}
1755
1809
1756
- static void hdmi_get_max_resol (struct exynos_drm_display * display ,
1757
- unsigned int * width , unsigned int * height )
1758
- {
1759
- * width = MAX_WIDTH ;
1760
- * height = MAX_HEIGHT ;
1761
- }
1762
-
1763
1810
static void hdmi_commit (struct exynos_drm_display * display )
1764
1811
{
1765
1812
struct hdmi_context * hdata = display -> ctx ;
@@ -1854,10 +1901,7 @@ static void hdmi_dpms(struct exynos_drm_display *display, int mode)
1854
1901
1855
1902
static struct exynos_drm_display_ops hdmi_display_ops = {
1856
1903
.initialize = hdmi_initialize ,
1857
- .is_connected = hdmi_is_connected ,
1858
- .get_max_resol = hdmi_get_max_resol ,
1859
- .get_edid = hdmi_get_edid ,
1860
- .check_mode = hdmi_check_mode ,
1904
+ .create_connector = hdmi_create_connector ,
1861
1905
.mode_fixup = hdmi_mode_fixup ,
1862
1906
.mode_set = hdmi_mode_set ,
1863
1907
.dpms = hdmi_dpms ,
0 commit comments