| .. | .. |
|---|
| 25 | 25 | * Authors: |
|---|
| 26 | 26 | * Eric Anholt <eric@anholt.net> |
|---|
| 27 | 27 | */ |
|---|
| 28 | | -#include <linux/module.h> |
|---|
| 29 | | -#include <linux/i2c.h> |
|---|
| 30 | | -#include <linux/slab.h> |
|---|
| 28 | + |
|---|
| 31 | 29 | #include <linux/delay.h> |
|---|
| 32 | | -#include <drm/drmP.h> |
|---|
| 30 | +#include <linux/i2c.h> |
|---|
| 31 | +#include <linux/kernel.h> |
|---|
| 32 | +#include <linux/module.h> |
|---|
| 33 | +#include <linux/slab.h> |
|---|
| 34 | + |
|---|
| 33 | 35 | #include <drm/drm_crtc.h> |
|---|
| 34 | 36 | #include <drm/drm_edid.h> |
|---|
| 35 | | -#include "psb_intel_drv.h" |
|---|
| 36 | | -#include <drm/gma_drm.h> |
|---|
| 37 | + |
|---|
| 37 | 38 | #include "psb_drv.h" |
|---|
| 38 | | -#include "psb_intel_sdvo_regs.h" |
|---|
| 39 | +#include "psb_intel_drv.h" |
|---|
| 39 | 40 | #include "psb_intel_reg.h" |
|---|
| 40 | | -#include <linux/kernel.h> |
|---|
| 41 | +#include "psb_intel_sdvo_regs.h" |
|---|
| 41 | 42 | |
|---|
| 42 | 43 | #define SDVO_TMDS_MASK (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1) |
|---|
| 43 | 44 | #define SDVO_RGB_MASK (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1) |
|---|
| .. | .. |
|---|
| 124 | 125 | bool is_lvds; |
|---|
| 125 | 126 | |
|---|
| 126 | 127 | /** |
|---|
| 127 | | - * This is sdvo fixed pannel mode pointer |
|---|
| 128 | + * This is sdvo fixed panel mode pointer |
|---|
| 128 | 129 | */ |
|---|
| 129 | 130 | struct drm_display_mode *sdvo_lvds_fixed_mode; |
|---|
| 130 | 131 | |
|---|
| 131 | 132 | /* DDC bus used by this SDVO encoder */ |
|---|
| 132 | 133 | uint8_t ddc_bus; |
|---|
| 134 | + |
|---|
| 135 | + u8 pixel_multiplier; |
|---|
| 133 | 136 | |
|---|
| 134 | 137 | /* Input timings for adjusted_mode */ |
|---|
| 135 | 138 | struct psb_intel_sdvo_dtd input_dtd; |
|---|
| .. | .. |
|---|
| 863 | 866 | DRM_INFO("HDMI is not supported yet"); |
|---|
| 864 | 867 | |
|---|
| 865 | 868 | return false; |
|---|
| 866 | | -#if 0 |
|---|
| 867 | | - struct dip_infoframe avi_if = { |
|---|
| 868 | | - .type = DIP_TYPE_AVI, |
|---|
| 869 | | - .ver = DIP_VERSION_AVI, |
|---|
| 870 | | - .len = DIP_LEN_AVI, |
|---|
| 871 | | - }; |
|---|
| 872 | | - uint8_t tx_rate = SDVO_HBUF_TX_VSYNC; |
|---|
| 873 | | - uint8_t set_buf_index[2] = { 1, 0 }; |
|---|
| 874 | | - uint64_t *data = (uint64_t *)&avi_if; |
|---|
| 875 | | - unsigned i; |
|---|
| 876 | | - |
|---|
| 877 | | - intel_dip_infoframe_csum(&avi_if); |
|---|
| 878 | | - |
|---|
| 879 | | - if (!psb_intel_sdvo_set_value(psb_intel_sdvo, |
|---|
| 880 | | - SDVO_CMD_SET_HBUF_INDEX, |
|---|
| 881 | | - set_buf_index, 2)) |
|---|
| 882 | | - return false; |
|---|
| 883 | | - |
|---|
| 884 | | - for (i = 0; i < sizeof(avi_if); i += 8) { |
|---|
| 885 | | - if (!psb_intel_sdvo_set_value(psb_intel_sdvo, |
|---|
| 886 | | - SDVO_CMD_SET_HBUF_DATA, |
|---|
| 887 | | - data, 8)) |
|---|
| 888 | | - return false; |
|---|
| 889 | | - data++; |
|---|
| 890 | | - } |
|---|
| 891 | | - |
|---|
| 892 | | - return psb_intel_sdvo_set_value(psb_intel_sdvo, |
|---|
| 893 | | - SDVO_CMD_SET_HBUF_TXRATE, |
|---|
| 894 | | - &tx_rate, 1); |
|---|
| 895 | | -#endif |
|---|
| 896 | 869 | } |
|---|
| 897 | 870 | |
|---|
| 898 | 871 | static bool psb_intel_sdvo_set_tv_format(struct psb_intel_sdvo *psb_intel_sdvo) |
|---|
| .. | .. |
|---|
| 957 | 930 | struct drm_display_mode *adjusted_mode) |
|---|
| 958 | 931 | { |
|---|
| 959 | 932 | struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(encoder); |
|---|
| 960 | | - int multiplier; |
|---|
| 961 | 933 | |
|---|
| 962 | 934 | /* We need to construct preferred input timings based on our |
|---|
| 963 | 935 | * output timings. To do that, we have to set the output |
|---|
| .. | .. |
|---|
| 984 | 956 | /* Make the CRTC code factor in the SDVO pixel multiplier. The |
|---|
| 985 | 957 | * SDVO device will factor out the multiplier during mode_set. |
|---|
| 986 | 958 | */ |
|---|
| 987 | | - multiplier = psb_intel_sdvo_get_pixel_multiplier(adjusted_mode); |
|---|
| 988 | | - psb_intel_mode_set_pixel_multiplier(adjusted_mode, multiplier); |
|---|
| 959 | + psb_intel_sdvo->pixel_multiplier = |
|---|
| 960 | + psb_intel_sdvo_get_pixel_multiplier(adjusted_mode); |
|---|
| 961 | + adjusted_mode->clock *= psb_intel_sdvo->pixel_multiplier; |
|---|
| 989 | 962 | |
|---|
| 990 | 963 | return true; |
|---|
| 991 | 964 | } |
|---|
| .. | .. |
|---|
| 1001 | 974 | u32 sdvox; |
|---|
| 1002 | 975 | struct psb_intel_sdvo_in_out_map in_out; |
|---|
| 1003 | 976 | struct psb_intel_sdvo_dtd input_dtd; |
|---|
| 1004 | | - int pixel_multiplier = psb_intel_mode_get_pixel_multiplier(adjusted_mode); |
|---|
| 1005 | 977 | int rate; |
|---|
| 1006 | 978 | int need_aux = IS_MRST(dev) ? 1 : 0; |
|---|
| 1007 | 979 | |
|---|
| .. | .. |
|---|
| 1059 | 1031 | |
|---|
| 1060 | 1032 | (void) psb_intel_sdvo_set_input_timing(psb_intel_sdvo, &input_dtd); |
|---|
| 1061 | 1033 | |
|---|
| 1062 | | - switch (pixel_multiplier) { |
|---|
| 1034 | + switch (psb_intel_sdvo->pixel_multiplier) { |
|---|
| 1063 | 1035 | default: |
|---|
| 1064 | 1036 | case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break; |
|---|
| 1065 | 1037 | case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break; |
|---|
| .. | .. |
|---|
| 1225 | 1197 | |
|---|
| 1226 | 1198 | return true; |
|---|
| 1227 | 1199 | } |
|---|
| 1228 | | - |
|---|
| 1229 | | -/* No use! */ |
|---|
| 1230 | | -#if 0 |
|---|
| 1231 | | -struct drm_connector* psb_intel_sdvo_find(struct drm_device *dev, int sdvoB) |
|---|
| 1232 | | -{ |
|---|
| 1233 | | - struct drm_connector *connector = NULL; |
|---|
| 1234 | | - struct psb_intel_sdvo *iout = NULL; |
|---|
| 1235 | | - struct psb_intel_sdvo *sdvo; |
|---|
| 1236 | | - |
|---|
| 1237 | | - /* find the sdvo connector */ |
|---|
| 1238 | | - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
|---|
| 1239 | | - iout = to_psb_intel_sdvo(connector); |
|---|
| 1240 | | - |
|---|
| 1241 | | - if (iout->type != INTEL_OUTPUT_SDVO) |
|---|
| 1242 | | - continue; |
|---|
| 1243 | | - |
|---|
| 1244 | | - sdvo = iout->dev_priv; |
|---|
| 1245 | | - |
|---|
| 1246 | | - if (sdvo->sdvo_reg == SDVOB && sdvoB) |
|---|
| 1247 | | - return connector; |
|---|
| 1248 | | - |
|---|
| 1249 | | - if (sdvo->sdvo_reg == SDVOC && !sdvoB) |
|---|
| 1250 | | - return connector; |
|---|
| 1251 | | - |
|---|
| 1252 | | - } |
|---|
| 1253 | | - |
|---|
| 1254 | | - return NULL; |
|---|
| 1255 | | -} |
|---|
| 1256 | | - |
|---|
| 1257 | | -int psb_intel_sdvo_supports_hotplug(struct drm_connector *connector) |
|---|
| 1258 | | -{ |
|---|
| 1259 | | - u8 response[2]; |
|---|
| 1260 | | - u8 status; |
|---|
| 1261 | | - struct psb_intel_sdvo *psb_intel_sdvo; |
|---|
| 1262 | | - DRM_DEBUG_KMS("\n"); |
|---|
| 1263 | | - |
|---|
| 1264 | | - if (!connector) |
|---|
| 1265 | | - return 0; |
|---|
| 1266 | | - |
|---|
| 1267 | | - psb_intel_sdvo = to_psb_intel_sdvo(connector); |
|---|
| 1268 | | - |
|---|
| 1269 | | - return psb_intel_sdvo_get_value(psb_intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, |
|---|
| 1270 | | - &response, 2) && response[0]; |
|---|
| 1271 | | -} |
|---|
| 1272 | | - |
|---|
| 1273 | | -void psb_intel_sdvo_set_hotplug(struct drm_connector *connector, int on) |
|---|
| 1274 | | -{ |
|---|
| 1275 | | - u8 response[2]; |
|---|
| 1276 | | - u8 status; |
|---|
| 1277 | | - struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(connector); |
|---|
| 1278 | | - |
|---|
| 1279 | | - psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); |
|---|
| 1280 | | - psb_intel_sdvo_read_response(psb_intel_sdvo, &response, 2); |
|---|
| 1281 | | - |
|---|
| 1282 | | - if (on) { |
|---|
| 1283 | | - psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); |
|---|
| 1284 | | - status = psb_intel_sdvo_read_response(psb_intel_sdvo, &response, 2); |
|---|
| 1285 | | - |
|---|
| 1286 | | - psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); |
|---|
| 1287 | | - } else { |
|---|
| 1288 | | - response[0] = 0; |
|---|
| 1289 | | - response[1] = 0; |
|---|
| 1290 | | - psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); |
|---|
| 1291 | | - } |
|---|
| 1292 | | - |
|---|
| 1293 | | - psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); |
|---|
| 1294 | | - psb_intel_sdvo_read_response(psb_intel_sdvo, &response, 2); |
|---|
| 1295 | | -} |
|---|
| 1296 | | -#endif |
|---|
| 1297 | 1200 | |
|---|
| 1298 | 1201 | static bool |
|---|
| 1299 | 1202 | psb_intel_sdvo_multifunc_encoder(struct psb_intel_sdvo *psb_intel_sdvo) |
|---|