0001
0002
0003
0004
0005
0006
0007 #include <linux/list.h>
0008
0009 #include <drm/drm_bridge.h>
0010 #include <drm/drm_crtc.h>
0011 #include <drm/drm_modeset_helper_vtables.h>
0012 #include <drm/drm_edid.h>
0013
0014 #include "omap_drv.h"
0015
0016
0017
0018
0019
0020 #define to_omap_encoder(x) container_of(x, struct omap_encoder, base)
0021
0022
0023
0024
0025
0026
0027 struct omap_encoder {
0028 struct drm_encoder base;
0029 struct omap_dss_device *output;
0030 };
0031
0032 static void omap_encoder_destroy(struct drm_encoder *encoder)
0033 {
0034 struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
0035
0036 drm_encoder_cleanup(encoder);
0037 kfree(omap_encoder);
0038 }
0039
0040 static const struct drm_encoder_funcs omap_encoder_funcs = {
0041 .destroy = omap_encoder_destroy,
0042 };
0043
0044 static void omap_encoder_update_videomode_flags(struct videomode *vm,
0045 u32 bus_flags)
0046 {
0047 if (!(vm->flags & (DISPLAY_FLAGS_DE_LOW |
0048 DISPLAY_FLAGS_DE_HIGH))) {
0049 if (bus_flags & DRM_BUS_FLAG_DE_LOW)
0050 vm->flags |= DISPLAY_FLAGS_DE_LOW;
0051 else if (bus_flags & DRM_BUS_FLAG_DE_HIGH)
0052 vm->flags |= DISPLAY_FLAGS_DE_HIGH;
0053 }
0054
0055 if (!(vm->flags & (DISPLAY_FLAGS_PIXDATA_POSEDGE |
0056 DISPLAY_FLAGS_PIXDATA_NEGEDGE))) {
0057 if (bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE)
0058 vm->flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE;
0059 else if (bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
0060 vm->flags |= DISPLAY_FLAGS_PIXDATA_NEGEDGE;
0061 }
0062
0063 if (!(vm->flags & (DISPLAY_FLAGS_SYNC_POSEDGE |
0064 DISPLAY_FLAGS_SYNC_NEGEDGE))) {
0065 if (bus_flags & DRM_BUS_FLAG_SYNC_DRIVE_POSEDGE)
0066 vm->flags |= DISPLAY_FLAGS_SYNC_POSEDGE;
0067 else if (bus_flags & DRM_BUS_FLAG_SYNC_DRIVE_NEGEDGE)
0068 vm->flags |= DISPLAY_FLAGS_SYNC_NEGEDGE;
0069 }
0070 }
0071
0072 static void omap_encoder_mode_set(struct drm_encoder *encoder,
0073 struct drm_display_mode *mode,
0074 struct drm_display_mode *adjusted_mode)
0075 {
0076 struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
0077 struct omap_dss_device *output = omap_encoder->output;
0078 struct drm_device *dev = encoder->dev;
0079 struct drm_connector *connector;
0080 struct drm_bridge *bridge;
0081 struct videomode vm = { 0 };
0082 u32 bus_flags;
0083
0084 list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
0085 if (connector->encoder == encoder)
0086 break;
0087 }
0088
0089 drm_display_mode_to_videomode(adjusted_mode, &vm);
0090
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100 for (bridge = output->bridge; bridge;
0101 bridge = drm_bridge_get_next_bridge(bridge)) {
0102 if (!bridge->timings)
0103 continue;
0104
0105 bus_flags = bridge->timings->input_bus_flags;
0106 omap_encoder_update_videomode_flags(&vm, bus_flags);
0107 }
0108
0109 bus_flags = connector->display_info.bus_flags;
0110 omap_encoder_update_videomode_flags(&vm, bus_flags);
0111
0112
0113 dss_mgr_set_timings(output, &vm);
0114 }
0115
0116 static const struct drm_encoder_helper_funcs omap_encoder_helper_funcs = {
0117 .mode_set = omap_encoder_mode_set,
0118 };
0119
0120
0121 struct drm_encoder *omap_encoder_init(struct drm_device *dev,
0122 struct omap_dss_device *output)
0123 {
0124 struct drm_encoder *encoder = NULL;
0125 struct omap_encoder *omap_encoder;
0126
0127 omap_encoder = kzalloc(sizeof(*omap_encoder), GFP_KERNEL);
0128 if (!omap_encoder)
0129 goto fail;
0130
0131 omap_encoder->output = output;
0132
0133 encoder = &omap_encoder->base;
0134
0135 drm_encoder_init(dev, encoder, &omap_encoder_funcs,
0136 DRM_MODE_ENCODER_TMDS, NULL);
0137 drm_encoder_helper_add(encoder, &omap_encoder_helper_funcs);
0138
0139 return encoder;
0140
0141 fail:
0142 if (encoder)
0143 omap_encoder_destroy(encoder);
0144
0145 return NULL;
0146 }