Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

gma500: Replace SDVO code with slightly modified version from i915

Our current SDVO implementation is not working properly, so replace it with
a modified version of the i915. Further testing and debugging is needed to make
sure we can handle the different SDVO setups and wiring.

Signed-off-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Signed-off-by: Alan Cox <alan@linux.intel.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>

authored by

Patrik Jakobsson and committed by
Dave Airlie
5736995b 5c0c1d50

+2777 -1008
+19
drivers/gpu/drm/gma500/psb_drv.h
··· 260 260 int enabled; 261 261 }; 262 262 263 + struct sdvo_device_mapping { 264 + u8 initialized; 265 + u8 dvo_port; 266 + u8 slave_addr; 267 + u8 dvo_wiring; 268 + u8 i2c_pin; 269 + u8 i2c_speed; 270 + u8 ddc_pin; 271 + }; 272 + 263 273 struct intel_gmbus { 264 274 struct i2c_adapter adapter; 265 275 struct i2c_adapter *force_bit; ··· 354 344 355 345 /* gmbus */ 356 346 struct intel_gmbus *gmbus; 347 + 348 + /* Used by SDVO */ 349 + int crt_ddc_pin; 350 + /* FIXME: The mappings should be parsed from bios but for now we can 351 + pretend there are no mappings available */ 352 + struct sdvo_device_mapping sdvo_mappings[2]; 353 + u32 hotplug_supported_mask; 354 + struct drm_property *broadcast_rgb_property; 355 + struct drm_property *force_audio_property; 357 356 358 357 /* 359 358 * LVDS info
+8
drivers/gpu/drm/gma500/psb_intel_display.c
··· 552 552 encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); 553 553 } 554 554 555 + void psb_intel_encoder_destroy(struct drm_encoder *encoder) 556 + { 557 + struct psb_intel_encoder *intel_encoder = to_psb_intel_encoder(encoder); 558 + 559 + drm_encoder_cleanup(encoder); 560 + kfree(intel_encoder); 561 + } 562 + 555 563 static bool psb_intel_crtc_mode_fixup(struct drm_crtc *crtc, 556 564 struct drm_display_mode *mode, 557 565 struct drm_display_mode *adjusted_mode)
+40 -1
drivers/gpu/drm/gma500/psb_intel_drv.h
··· 39 39 #define INTEL_I2C_BUS_DVO 1 40 40 #define INTEL_I2C_BUS_SDVO 2 41 41 42 + /* Intel Pipe Clone Bit */ 43 + #define INTEL_HDMIB_CLONE_BIT 1 44 + #define INTEL_HDMIC_CLONE_BIT 2 45 + #define INTEL_HDMID_CLONE_BIT 3 46 + #define INTEL_HDMIE_CLONE_BIT 4 47 + #define INTEL_HDMIF_CLONE_BIT 5 48 + #define INTEL_SDVO_NON_TV_CLONE_BIT 6 49 + #define INTEL_SDVO_TV_CLONE_BIT 7 50 + #define INTEL_SDVO_LVDS_CLONE_BIT 8 51 + #define INTEL_ANALOG_CLONE_BIT 9 52 + #define INTEL_TV_CLONE_BIT 10 53 + #define INTEL_DP_B_CLONE_BIT 11 54 + #define INTEL_DP_C_CLONE_BIT 12 55 + #define INTEL_DP_D_CLONE_BIT 13 56 + #define INTEL_LVDS_CLONE_BIT 14 57 + #define INTEL_DVO_TMDS_CLONE_BIT 15 58 + #define INTEL_DVO_LVDS_CLONE_BIT 16 59 + #define INTEL_EDP_CLONE_BIT 17 60 + 42 61 /* these are outputs from the chip - integrated only 43 62 * external chips are via DVO or SDVO output */ 44 63 #define INTEL_OUTPUT_UNUSED 0 ··· 74 55 #define INTEL_DVO_CHIP_LVDS 1 75 56 #define INTEL_DVO_CHIP_TMDS 2 76 57 #define INTEL_DVO_CHIP_TVOUT 4 58 + 59 + #define INTEL_MODE_PIXEL_MULTIPLIER_SHIFT (0x0) 60 + #define INTEL_MODE_PIXEL_MULTIPLIER_MASK (0xf << INTEL_MODE_PIXEL_MULTIPLIER_SHIFT) 61 + 62 + static inline void 63 + psb_intel_mode_set_pixel_multiplier(struct drm_display_mode *mode, 64 + int multiplier) 65 + { 66 + mode->clock *= multiplier; 67 + mode->private_flags |= multiplier; 68 + } 69 + 70 + static inline int 71 + psb_intel_mode_get_pixel_multiplier(const struct drm_display_mode *mode) 72 + { 73 + return (mode->private_flags & INTEL_MODE_PIXEL_MULTIPLIER_MASK) 74 + >> INTEL_MODE_PIXEL_MULTIPLIER_SHIFT; 75 + } 76 + 77 77 78 78 /* 79 79 * Hold information useally put on the device driver privates here, ··· 211 173 extern void psb_intel_crtc_init(struct drm_device *dev, int pipe, 212 174 struct psb_intel_mode_device *mode_dev); 213 175 extern void psb_intel_crt_init(struct drm_device *dev); 214 - extern void psb_intel_sdvo_init(struct drm_device *dev, int output_device); 176 + extern bool psb_intel_sdvo_init(struct drm_device *dev, int output_device); 215 177 extern void psb_intel_dvo_init(struct drm_device *dev); 216 178 extern void psb_intel_tv_init(struct drm_device *dev); 217 179 extern void psb_intel_lvds_init(struct drm_device *dev, ··· 228 190 extern void psb_intel_crtc_load_lut(struct drm_crtc *crtc); 229 191 extern void psb_intel_encoder_prepare(struct drm_encoder *encoder); 230 192 extern void psb_intel_encoder_commit(struct drm_encoder *encoder); 193 + extern void psb_intel_encoder_destroy(struct drm_encoder *encoder); 231 194 232 195 static inline struct psb_intel_encoder *psb_intel_attached_encoder( 233 196 struct drm_connector *connector)
+2
drivers/gpu/drm/gma500/psb_intel_reg.h
··· 376 376 #define SDVO_PIPE_B_SELECT (1 << 30) 377 377 #define SDVO_STALL_SELECT (1 << 29) 378 378 #define SDVO_INTERRUPT_ENABLE (1 << 26) 379 + #define SDVO_COLOR_RANGE_16_235 (1 << 8) 380 + #define SDVO_AUDIO_ENABLE (1 << 6) 379 381 380 382 /** 381 383 * 915G/GM SDVO pixel multiplier.
+2224 -908
drivers/gpu/drm/gma500/psb_intel_sdvo.c
··· 1 1 /* 2 - * Copyright (c) 2006-2007 Intel Corporation 2 + * Copyright 2006 Dave Airlie <airlied@linux.ie> 3 + * Copyright © 2006-2007 Intel Corporation 4 + * Jesse Barnes <jesse.barnes@intel.com> 3 5 * 4 - * This program is free software; you can redistribute it and/or modify it 5 - * under the terms and conditions of the GNU General Public License, 6 - * version 2, as published by the Free Software Foundation. 6 + * Permission is hereby granted, free of charge, to any person obtaining a 7 + * copy of this software and associated documentation files (the "Software"), 8 + * to deal in the Software without restriction, including without limitation 9 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 + * and/or sell copies of the Software, and to permit persons to whom the 11 + * Software is furnished to do so, subject to the following conditions: 7 12 * 8 - * This program is distributed in the hope it will be useful, but WITHOUT 9 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11 - * more details. 13 + * The above copyright notice and this permission notice (including the next 14 + * paragraph) shall be included in all copies or substantial portions of the 15 + * Software. 12 16 * 13 - * You should have received a copy of the GNU General Public License along with 14 - * this program; if not, write to the Free Software Foundation, Inc., 15 - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 17 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 + * DEALINGS IN THE SOFTWARE. 16 24 * 17 25 * Authors: 18 26 * Eric Anholt <eric@anholt.net> 19 27 */ 20 - 28 + #include <linux/module.h> 21 29 #include <linux/i2c.h> 30 + #include <linux/slab.h> 22 31 #include <linux/delay.h> 23 - /* #include <drm/drm_crtc.h> */ 24 - #include <drm/drmP.h> 25 - #include "psb_drv.h" 32 + #include "drmP.h" 33 + #include "drm.h" 34 + #include "drm_crtc.h" 35 + #include "drm_edid.h" 26 36 #include "psb_intel_drv.h" 27 - #include "psb_intel_reg.h" 37 + #include "gma_drm.h" 38 + #include "psb_drv.h" 28 39 #include "psb_intel_sdvo_regs.h" 40 + #include "psb_intel_reg.h" 29 41 30 - struct psb_intel_sdvo_priv { 31 - struct psb_intel_i2c_chan *i2c_bus; 32 - int slaveaddr; 33 - int output_device; 42 + #define SDVO_TMDS_MASK (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1) 43 + #define SDVO_RGB_MASK (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1) 44 + #define SDVO_LVDS_MASK (SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1) 45 + #define SDVO_TV_MASK (SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_SVID0) 34 46 35 - u16 active_outputs; 47 + #define SDVO_OUTPUT_MASK (SDVO_TMDS_MASK | SDVO_RGB_MASK | SDVO_LVDS_MASK |\ 48 + SDVO_TV_MASK) 36 49 50 + #define IS_TV(c) (c->output_flag & SDVO_TV_MASK) 51 + #define IS_TMDS(c) (c->output_flag & SDVO_TMDS_MASK) 52 + #define IS_LVDS(c) (c->output_flag & SDVO_LVDS_MASK) 53 + #define IS_TV_OR_LVDS(c) (c->output_flag & (SDVO_TV_MASK | SDVO_LVDS_MASK)) 54 + 55 + 56 + static const char *tv_format_names[] = { 57 + "NTSC_M" , "NTSC_J" , "NTSC_443", 58 + "PAL_B" , "PAL_D" , "PAL_G" , 59 + "PAL_H" , "PAL_I" , "PAL_M" , 60 + "PAL_N" , "PAL_NC" , "PAL_60" , 61 + "SECAM_B" , "SECAM_D" , "SECAM_G" , 62 + "SECAM_K" , "SECAM_K1", "SECAM_L" , 63 + "SECAM_60" 64 + }; 65 + 66 + #define TV_FORMAT_NUM (sizeof(tv_format_names) / sizeof(*tv_format_names)) 67 + 68 + struct psb_intel_sdvo { 69 + struct psb_intel_encoder base; 70 + 71 + struct i2c_adapter *i2c; 72 + u8 slave_addr; 73 + 74 + struct i2c_adapter ddc; 75 + 76 + /* Register for the SDVO device: SDVOB or SDVOC */ 77 + int sdvo_reg; 78 + 79 + /* Active outputs controlled by this SDVO output */ 80 + uint16_t controlled_output; 81 + 82 + /* 83 + * Capabilities of the SDVO device returned by 84 + * i830_sdvo_get_capabilities() 85 + */ 37 86 struct psb_intel_sdvo_caps caps; 87 + 88 + /* Pixel clock limitations reported by the SDVO device, in kHz */ 38 89 int pixel_clock_min, pixel_clock_max; 39 90 40 - int save_sdvo_mult; 41 - u16 save_active_outputs; 42 - struct psb_intel_sdvo_dtd save_input_dtd_1, save_input_dtd_2; 43 - struct psb_intel_sdvo_dtd save_output_dtd[16]; 44 - u32 save_SDVOX; 45 - u8 in_out_map[4]; 91 + /* 92 + * For multiple function SDVO device, 93 + * this is for current attached outputs. 94 + */ 95 + uint16_t attached_output; 46 96 47 - u8 by_input_wiring; 48 - u32 active_device; 97 + /** 98 + * This is used to select the color range of RBG outputs in HDMI mode. 99 + * It is only valid when using TMDS encoding and 8 bit per color mode. 100 + */ 101 + uint32_t color_range; 102 + 103 + /** 104 + * This is set if we're going to treat the device as TV-out. 105 + * 106 + * While we have these nice friendly flags for output types that ought 107 + * to decide this for us, the S-Video output on our HDMI+S-Video card 108 + * shows up as RGB1 (VGA). 109 + */ 110 + bool is_tv; 111 + 112 + /* This is for current tv format name */ 113 + int tv_format_index; 114 + 115 + /** 116 + * This is set if we treat the device as HDMI, instead of DVI. 117 + */ 118 + bool is_hdmi; 119 + bool has_hdmi_monitor; 120 + bool has_hdmi_audio; 121 + 122 + /** 123 + * This is set if we detect output of sdvo device as LVDS and 124 + * have a valid fixed mode to use with the panel. 125 + */ 126 + bool is_lvds; 127 + 128 + /** 129 + * This is sdvo fixed pannel mode pointer 130 + */ 131 + struct drm_display_mode *sdvo_lvds_fixed_mode; 132 + 133 + /* DDC bus used by this SDVO encoder */ 134 + uint8_t ddc_bus; 135 + 136 + /* Input timings for adjusted_mode */ 137 + struct psb_intel_sdvo_dtd input_dtd; 49 138 }; 139 + 140 + struct psb_intel_sdvo_connector { 141 + struct psb_intel_connector base; 142 + 143 + /* Mark the type of connector */ 144 + uint16_t output_flag; 145 + 146 + int force_audio; 147 + 148 + /* This contains all current supported TV format */ 149 + u8 tv_format_supported[TV_FORMAT_NUM]; 150 + int format_supported_num; 151 + struct drm_property *tv_format; 152 + 153 + /* add the property for the SDVO-TV */ 154 + struct drm_property *left; 155 + struct drm_property *right; 156 + struct drm_property *top; 157 + struct drm_property *bottom; 158 + struct drm_property *hpos; 159 + struct drm_property *vpos; 160 + struct drm_property *contrast; 161 + struct drm_property *saturation; 162 + struct drm_property *hue; 163 + struct drm_property *sharpness; 164 + struct drm_property *flicker_filter; 165 + struct drm_property *flicker_filter_adaptive; 166 + struct drm_property *flicker_filter_2d; 167 + struct drm_property *tv_chroma_filter; 168 + struct drm_property *tv_luma_filter; 169 + struct drm_property *dot_crawl; 170 + 171 + /* add the property for the SDVO-TV/LVDS */ 172 + struct drm_property *brightness; 173 + 174 + /* Add variable to record current setting for the above property */ 175 + u32 left_margin, right_margin, top_margin, bottom_margin; 176 + 177 + /* this is to get the range of margin.*/ 178 + u32 max_hscan, max_vscan; 179 + u32 max_hpos, cur_hpos; 180 + u32 max_vpos, cur_vpos; 181 + u32 cur_brightness, max_brightness; 182 + u32 cur_contrast, max_contrast; 183 + u32 cur_saturation, max_saturation; 184 + u32 cur_hue, max_hue; 185 + u32 cur_sharpness, max_sharpness; 186 + u32 cur_flicker_filter, max_flicker_filter; 187 + u32 cur_flicker_filter_adaptive, max_flicker_filter_adaptive; 188 + u32 cur_flicker_filter_2d, max_flicker_filter_2d; 189 + u32 cur_tv_chroma_filter, max_tv_chroma_filter; 190 + u32 cur_tv_luma_filter, max_tv_luma_filter; 191 + u32 cur_dot_crawl, max_dot_crawl; 192 + }; 193 + 194 + static struct psb_intel_sdvo *to_psb_intel_sdvo(struct drm_encoder *encoder) 195 + { 196 + return container_of(encoder, struct psb_intel_sdvo, base.base); 197 + } 198 + 199 + static struct psb_intel_sdvo *intel_attached_sdvo(struct drm_connector *connector) 200 + { 201 + return container_of(psb_intel_attached_encoder(connector), 202 + struct psb_intel_sdvo, base); 203 + } 204 + 205 + static struct psb_intel_sdvo_connector *to_psb_intel_sdvo_connector(struct drm_connector *connector) 206 + { 207 + return container_of(to_psb_intel_connector(connector), struct psb_intel_sdvo_connector, base); 208 + } 209 + 210 + static bool 211 + psb_intel_sdvo_output_setup(struct psb_intel_sdvo *psb_intel_sdvo, uint16_t flags); 212 + static bool 213 + psb_intel_sdvo_tv_create_property(struct psb_intel_sdvo *psb_intel_sdvo, 214 + struct psb_intel_sdvo_connector *psb_intel_sdvo_connector, 215 + int type); 216 + static bool 217 + psb_intel_sdvo_create_enhance_property(struct psb_intel_sdvo *psb_intel_sdvo, 218 + struct psb_intel_sdvo_connector *psb_intel_sdvo_connector); 50 219 51 220 /** 52 221 * Writes the SDVOB or SDVOC with the given value, but always writes both 53 222 * SDVOB and SDVOC to work around apparent hardware issues (according to 54 223 * comments in the BIOS). 55 224 */ 56 - void psb_intel_sdvo_write_sdvox(struct psb_intel_output *psb_intel_output, 57 - u32 val) 225 + static void psb_intel_sdvo_write_sdvox(struct psb_intel_sdvo *psb_intel_sdvo, u32 val) 58 226 { 59 - struct drm_device *dev = psb_intel_output->base.dev; 60 - struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; 227 + struct drm_device *dev = psb_intel_sdvo->base.base.dev; 61 228 u32 bval = val, cval = val; 62 229 int i; 63 230 64 - if (sdvo_priv->output_device == SDVOB) 231 + if (psb_intel_sdvo->sdvo_reg == SDVOB) { 65 232 cval = REG_READ(SDVOC); 66 - else 233 + } else { 67 234 bval = REG_READ(SDVOB); 235 + } 68 236 /* 69 237 * Write the registers twice for luck. Sometimes, 70 238 * writing them only once doesn't appear to 'stick'. 71 239 * The BIOS does this too. Yay, magic 72 240 */ 73 - for (i = 0; i < 2; i++) { 241 + for (i = 0; i < 2; i++) 242 + { 74 243 REG_WRITE(SDVOB, bval); 75 244 REG_READ(SDVOB); 76 245 REG_WRITE(SDVOC, cval); ··· 247 78 } 248 79 } 249 80 250 - static bool psb_intel_sdvo_read_byte( 251 - struct psb_intel_output *psb_intel_output, 252 - u8 addr, u8 *ch) 81 + static bool psb_intel_sdvo_read_byte(struct psb_intel_sdvo *psb_intel_sdvo, u8 addr, u8 *ch) 253 82 { 254 - struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; 255 - u8 out_buf[2]; 256 - u8 buf[2]; 83 + struct i2c_msg msgs[] = { 84 + { 85 + .addr = psb_intel_sdvo->slave_addr, 86 + .flags = 0, 87 + .len = 1, 88 + .buf = &addr, 89 + }, 90 + { 91 + .addr = psb_intel_sdvo->slave_addr, 92 + .flags = I2C_M_RD, 93 + .len = 1, 94 + .buf = ch, 95 + } 96 + }; 257 97 int ret; 258 98 259 - struct i2c_msg msgs[] = { 260 - { 261 - .addr = sdvo_priv->i2c_bus->slave_addr, 262 - .flags = 0, 263 - .len = 1, 264 - .buf = out_buf, 265 - }, 266 - { 267 - .addr = sdvo_priv->i2c_bus->slave_addr, 268 - .flags = I2C_M_RD, 269 - .len = 1, 270 - .buf = buf, 271 - } 272 - }; 273 - 274 - out_buf[0] = addr; 275 - out_buf[1] = 0; 276 - 277 - ret = i2c_transfer(&sdvo_priv->i2c_bus->adapter, msgs, 2); 278 - if (ret == 2) { 279 - *ch = buf[0]; 99 + if ((ret = i2c_transfer(psb_intel_sdvo->i2c, msgs, 2)) == 2) 280 100 return true; 281 - } 282 101 283 - return false; 284 - } 285 - 286 - static bool psb_intel_sdvo_write_byte( 287 - struct psb_intel_output *psb_intel_output, 288 - int addr, u8 ch) 289 - { 290 - u8 out_buf[2]; 291 - struct i2c_msg msgs[] = { 292 - { 293 - .addr = psb_intel_output->i2c_bus->slave_addr, 294 - .flags = 0, 295 - .len = 2, 296 - .buf = out_buf, 297 - } 298 - }; 299 - 300 - out_buf[0] = addr; 301 - out_buf[1] = ch; 302 - 303 - if (i2c_transfer(&psb_intel_output->i2c_bus->adapter, msgs, 1) == 1) 304 - return true; 102 + DRM_DEBUG_KMS("i2c transfer returned %d\n", ret); 305 103 return false; 306 104 } 307 105 ··· 276 140 /** Mapping of command numbers to names, for debug output */ 277 141 static const struct _sdvo_cmd_name { 278 142 u8 cmd; 279 - char *name; 143 + const char *name; 280 144 } sdvo_cmd_names[] = { 281 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET), 282 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS), 283 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FIRMWARE_REV), 284 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TRAINED_INPUTS), 285 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_OUTPUTS), 286 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_OUTPUTS), 287 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_IN_OUT_MAP), 288 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_IN_OUT_MAP), 289 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ATTACHED_DISPLAYS), 290 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HOT_PLUG_SUPPORT), 291 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_HOT_PLUG), 292 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_HOT_PLUG), 293 - SDVO_CMD_NAME_ENTRY 294 - (SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE), 295 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_INPUT), 296 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_OUTPUT), 297 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART1), 298 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART2), 299 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1), 300 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART2), 301 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1), 302 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART1), 303 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART2), 304 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART1), 305 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART2), 306 - SDVO_CMD_NAME_ENTRY 307 - (SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING), 308 - SDVO_CMD_NAME_ENTRY 309 - (SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1), 310 - SDVO_CMD_NAME_ENTRY 311 - (SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2), 312 - SDVO_CMD_NAME_ENTRY 313 - (SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE), 314 - SDVO_CMD_NAME_ENTRY 315 - (SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE), 316 - SDVO_CMD_NAME_ENTRY 317 - (SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS), 318 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CLOCK_RATE_MULT), 319 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CLOCK_RATE_MULT), 320 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS), 321 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT), 322 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT), 323 - SDVO_CMD_NAME_ENTRY 324 - (SDVO_CMD_SET_TV_RESOLUTION_SUPPORT), 325 - SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH),}; 145 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_RESET), 146 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DEVICE_CAPS), 147 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FIRMWARE_REV), 148 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TRAINED_INPUTS), 149 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_OUTPUTS), 150 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_OUTPUTS), 151 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_IN_OUT_MAP), 152 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_IN_OUT_MAP), 153 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ATTACHED_DISPLAYS), 154 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HOT_PLUG_SUPPORT), 155 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ACTIVE_HOT_PLUG), 156 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ACTIVE_HOT_PLUG), 157 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE), 158 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_INPUT), 159 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TARGET_OUTPUT), 160 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART1), 161 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_TIMINGS_PART2), 162 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1), 163 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART2), 164 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_INPUT_TIMINGS_PART1), 165 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART1), 166 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OUTPUT_TIMINGS_PART2), 167 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART1), 168 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_TIMINGS_PART2), 169 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING), 170 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1), 171 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2), 172 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE), 173 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE), 174 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_CLOCK_RATE_MULTS), 175 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CLOCK_RATE_MULT), 176 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CLOCK_RATE_MULT), 177 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_TV_FORMATS), 178 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_FORMAT), 179 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_FORMAT), 180 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_POWER_STATES), 181 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_POWER_STATE), 182 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODER_POWER_STATE), 183 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_DISPLAY_POWER_STATE), 184 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTROL_BUS_SWITCH), 185 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT), 186 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT), 187 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS), 326 188 327 - #define SDVO_NAME(dev_priv) \ 328 - ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC") 329 - #define SDVO_PRIV(output) ((struct psb_intel_sdvo_priv *) (output)->dev_priv) 189 + /* Add the op code for SDVO enhancements */ 190 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_HPOS), 191 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HPOS), 192 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HPOS), 193 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_VPOS), 194 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_VPOS), 195 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_VPOS), 196 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SATURATION), 197 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SATURATION), 198 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SATURATION), 199 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_HUE), 200 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HUE), 201 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HUE), 202 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_CONTRAST), 203 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_CONTRAST), 204 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_CONTRAST), 205 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_BRIGHTNESS), 206 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_BRIGHTNESS), 207 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_BRIGHTNESS), 208 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_H), 209 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_H), 210 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_H), 211 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_OVERSCAN_V), 212 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_OVERSCAN_V), 213 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_OVERSCAN_V), 214 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER), 215 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER), 216 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER), 217 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_ADAPTIVE), 218 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_ADAPTIVE), 219 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER_ADAPTIVE), 220 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_FLICKER_FILTER_2D), 221 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_FLICKER_FILTER_2D), 222 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_FLICKER_FILTER_2D), 223 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_SHARPNESS), 224 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SHARPNESS), 225 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_SHARPNESS), 226 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_DOT_CRAWL), 227 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_DOT_CRAWL), 228 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_TV_CHROMA_FILTER), 229 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_CHROMA_FILTER), 230 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_CHROMA_FILTER), 231 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_MAX_TV_LUMA_FILTER), 232 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_TV_LUMA_FILTER), 233 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_TV_LUMA_FILTER), 330 234 331 - static void psb_intel_sdvo_write_cmd(struct psb_intel_output *psb_intel_output, 332 - u8 cmd, 333 - void *args, 334 - int args_len) 235 + /* HDMI op code */ 236 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_SUPP_ENCODE), 237 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_ENCODE), 238 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_ENCODE), 239 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_PIXEL_REPLI), 240 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_PIXEL_REPLI), 241 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY_CAP), 242 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_COLORIMETRY), 243 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_COLORIMETRY), 244 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER), 245 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_AUDIO_STAT), 246 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_AUDIO_STAT), 247 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INDEX), 248 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_INDEX), 249 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_INFO), 250 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_AV_SPLIT), 251 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_AV_SPLIT), 252 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_TXRATE), 253 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_TXRATE), 254 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_SET_HBUF_DATA), 255 + SDVO_CMD_NAME_ENTRY(SDVO_CMD_GET_HBUF_DATA), 256 + }; 257 + 258 + #define IS_SDVOB(reg) (reg == SDVOB) 259 + #define SDVO_NAME(svdo) (IS_SDVOB((svdo)->sdvo_reg) ? "SDVOB" : "SDVOC") 260 + 261 + static void psb_intel_sdvo_debug_write(struct psb_intel_sdvo *psb_intel_sdvo, u8 cmd, 262 + const void *args, int args_len) 335 263 { 336 - struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; 337 264 int i; 338 265 339 - if (0) { 340 - printk(KERN_DEBUG "%s: W: %02X ", SDVO_NAME(sdvo_priv), cmd); 341 - for (i = 0; i < args_len; i++) 342 - printk(KERN_CONT "%02X ", ((u8 *) args)[i]); 343 - for (; i < 8; i++) 344 - printk(KERN_CONT " "); 345 - for (i = 0; 346 - i < 347 - sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0]); 348 - i++) { 349 - if (cmd == sdvo_cmd_names[i].cmd) { 350 - printk(KERN_CONT 351 - "(%s)", sdvo_cmd_names[i].name); 352 - break; 353 - } 266 + DRM_DEBUG_KMS("%s: W: %02X ", 267 + SDVO_NAME(psb_intel_sdvo), cmd); 268 + for (i = 0; i < args_len; i++) 269 + DRM_LOG_KMS("%02X ", ((u8 *)args)[i]); 270 + for (; i < 8; i++) 271 + DRM_LOG_KMS(" "); 272 + for (i = 0; i < ARRAY_SIZE(sdvo_cmd_names); i++) { 273 + if (cmd == sdvo_cmd_names[i].cmd) { 274 + DRM_LOG_KMS("(%s)", sdvo_cmd_names[i].name); 275 + break; 354 276 } 355 - if (i == 356 - sizeof(sdvo_cmd_names) / sizeof(sdvo_cmd_names[0])) 357 - printk(KERN_CONT "(%02X)", cmd); 358 - printk(KERN_CONT "\n"); 359 277 } 360 - 361 - for (i = 0; i < args_len; i++) { 362 - psb_intel_sdvo_write_byte(psb_intel_output, 363 - SDVO_I2C_ARG_0 - i, 364 - ((u8 *) args)[i]); 365 - } 366 - 367 - psb_intel_sdvo_write_byte(psb_intel_output, SDVO_I2C_OPCODE, cmd); 278 + if (i == ARRAY_SIZE(sdvo_cmd_names)) 279 + DRM_LOG_KMS("(%02X)", cmd); 280 + DRM_LOG_KMS("\n"); 368 281 } 369 282 370 - static const char *const cmd_status_names[] = { 283 + static const char *cmd_status_names[] = { 371 284 "Power on", 372 285 "Success", 373 286 "Not supported", ··· 426 241 "Scaling not supported" 427 242 }; 428 243 429 - static u8 psb_intel_sdvo_read_response( 430 - struct psb_intel_output *psb_intel_output, 431 - void *response, int response_len) 244 + static bool psb_intel_sdvo_write_cmd(struct psb_intel_sdvo *psb_intel_sdvo, u8 cmd, 245 + const void *args, int args_len) 432 246 { 433 - struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; 434 - int i; 435 - u8 status; 436 - u8 retry = 50; 247 + u8 buf[args_len*2 + 2], status; 248 + struct i2c_msg msgs[args_len + 3]; 249 + int i, ret; 437 250 438 - while (retry--) { 439 - /* Read the command response */ 440 - for (i = 0; i < response_len; i++) { 441 - psb_intel_sdvo_read_byte(psb_intel_output, 442 - SDVO_I2C_RETURN_0 + i, 443 - &((u8 *) response)[i]); 444 - } 251 + psb_intel_sdvo_debug_write(psb_intel_sdvo, cmd, args, args_len); 445 252 446 - /* read the return status */ 447 - psb_intel_sdvo_read_byte(psb_intel_output, 448 - SDVO_I2C_CMD_STATUS, 449 - &status); 253 + for (i = 0; i < args_len; i++) { 254 + msgs[i].addr = psb_intel_sdvo->slave_addr; 255 + msgs[i].flags = 0; 256 + msgs[i].len = 2; 257 + msgs[i].buf = buf + 2 *i; 258 + buf[2*i + 0] = SDVO_I2C_ARG_0 - i; 259 + buf[2*i + 1] = ((u8*)args)[i]; 260 + } 261 + msgs[i].addr = psb_intel_sdvo->slave_addr; 262 + msgs[i].flags = 0; 263 + msgs[i].len = 2; 264 + msgs[i].buf = buf + 2*i; 265 + buf[2*i + 0] = SDVO_I2C_OPCODE; 266 + buf[2*i + 1] = cmd; 450 267 451 - if (0) { 452 - pr_debug("%s: R: ", SDVO_NAME(sdvo_priv)); 453 - for (i = 0; i < response_len; i++) 454 - printk(KERN_CONT "%02X ", ((u8 *) response)[i]); 455 - for (; i < 8; i++) 456 - printk(" "); 457 - if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP) 458 - printk(KERN_CONT "(%s)", 459 - cmd_status_names[status]); 460 - else 461 - printk(KERN_CONT "(??? %d)", status); 462 - printk(KERN_CONT "\n"); 463 - } 268 + /* the following two are to read the response */ 269 + status = SDVO_I2C_CMD_STATUS; 270 + msgs[i+1].addr = psb_intel_sdvo->slave_addr; 271 + msgs[i+1].flags = 0; 272 + msgs[i+1].len = 1; 273 + msgs[i+1].buf = &status; 464 274 465 - if (status != SDVO_CMD_STATUS_PENDING) 466 - return status; 275 + msgs[i+2].addr = psb_intel_sdvo->slave_addr; 276 + msgs[i+2].flags = I2C_M_RD; 277 + msgs[i+2].len = 1; 278 + msgs[i+2].buf = &status; 467 279 468 - mdelay(50); 280 + ret = i2c_transfer(psb_intel_sdvo->i2c, msgs, i+3); 281 + if (ret < 0) { 282 + DRM_DEBUG_KMS("I2c transfer returned %d\n", ret); 283 + return false; 284 + } 285 + if (ret != i+3) { 286 + /* failure in I2C transfer */ 287 + DRM_DEBUG_KMS("I2c transfer returned %d/%d\n", ret, i+3); 288 + return false; 469 289 } 470 290 471 - return status; 291 + return true; 472 292 } 473 293 474 - int psb_intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) 294 + static bool psb_intel_sdvo_read_response(struct psb_intel_sdvo *psb_intel_sdvo, 295 + void *response, int response_len) 296 + { 297 + u8 retry = 5; 298 + u8 status; 299 + int i; 300 + 301 + DRM_DEBUG_KMS("%s: R: ", SDVO_NAME(psb_intel_sdvo)); 302 + 303 + /* 304 + * The documentation states that all commands will be 305 + * processed within 15µs, and that we need only poll 306 + * the status byte a maximum of 3 times in order for the 307 + * command to be complete. 308 + * 309 + * Check 5 times in case the hardware failed to read the docs. 310 + */ 311 + if (!psb_intel_sdvo_read_byte(psb_intel_sdvo, 312 + SDVO_I2C_CMD_STATUS, 313 + &status)) 314 + goto log_fail; 315 + 316 + while (status == SDVO_CMD_STATUS_PENDING && retry--) { 317 + udelay(15); 318 + if (!psb_intel_sdvo_read_byte(psb_intel_sdvo, 319 + SDVO_I2C_CMD_STATUS, 320 + &status)) 321 + goto log_fail; 322 + } 323 + 324 + if (status <= SDVO_CMD_STATUS_SCALING_NOT_SUPP) 325 + DRM_LOG_KMS("(%s)", cmd_status_names[status]); 326 + else 327 + DRM_LOG_KMS("(??? %d)", status); 328 + 329 + if (status != SDVO_CMD_STATUS_SUCCESS) 330 + goto log_fail; 331 + 332 + /* Read the command response */ 333 + for (i = 0; i < response_len; i++) { 334 + if (!psb_intel_sdvo_read_byte(psb_intel_sdvo, 335 + SDVO_I2C_RETURN_0 + i, 336 + &((u8 *)response)[i])) 337 + goto log_fail; 338 + DRM_LOG_KMS(" %02X", ((u8 *)response)[i]); 339 + } 340 + DRM_LOG_KMS("\n"); 341 + return true; 342 + 343 + log_fail: 344 + DRM_LOG_KMS("... failed\n"); 345 + return false; 346 + } 347 + 348 + static int psb_intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode) 475 349 { 476 350 if (mode->clock >= 100000) 477 351 return 1; ··· 540 296 return 4; 541 297 } 542 298 543 - /** 544 - * Don't check status code from this as it switches the bus back to the 545 - * SDVO chips which defeats the purpose of doing a bus switch in the first 546 - * place. 547 - */ 548 - void psb_intel_sdvo_set_control_bus_switch( 549 - struct psb_intel_output *psb_intel_output, 550 - u8 target) 299 + static bool psb_intel_sdvo_set_control_bus_switch(struct psb_intel_sdvo *psb_intel_sdvo, 300 + u8 ddc_bus) 551 301 { 552 - psb_intel_sdvo_write_cmd(psb_intel_output, 553 - SDVO_CMD_SET_CONTROL_BUS_SWITCH, 554 - &target, 555 - 1); 302 + /* This must be the immediately preceding write before the i2c xfer */ 303 + return psb_intel_sdvo_write_cmd(psb_intel_sdvo, 304 + SDVO_CMD_SET_CONTROL_BUS_SWITCH, 305 + &ddc_bus, 1); 556 306 } 557 307 558 - static bool psb_intel_sdvo_set_target_input( 559 - struct psb_intel_output *psb_intel_output, 560 - bool target_0, bool target_1) 308 + static bool psb_intel_sdvo_set_value(struct psb_intel_sdvo *psb_intel_sdvo, u8 cmd, const void *data, int len) 561 309 { 562 - struct psb_intel_sdvo_set_target_input_args targets = { 0 }; 563 - u8 status; 310 + if (!psb_intel_sdvo_write_cmd(psb_intel_sdvo, cmd, data, len)) 311 + return false; 564 312 565 - if (target_0 && target_1) 566 - return SDVO_CMD_STATUS_NOTSUPP; 313 + return psb_intel_sdvo_read_response(psb_intel_sdvo, NULL, 0); 314 + } 567 315 568 - if (target_1) 569 - targets.target_1 = 1; 316 + static bool 317 + psb_intel_sdvo_get_value(struct psb_intel_sdvo *psb_intel_sdvo, u8 cmd, void *value, int len) 318 + { 319 + if (!psb_intel_sdvo_write_cmd(psb_intel_sdvo, cmd, NULL, 0)) 320 + return false; 570 321 571 - psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_TARGET_INPUT, 572 - &targets, sizeof(targets)); 322 + return psb_intel_sdvo_read_response(psb_intel_sdvo, value, len); 323 + } 573 324 574 - status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); 575 - 576 - return status == SDVO_CMD_STATUS_SUCCESS; 325 + static bool psb_intel_sdvo_set_target_input(struct psb_intel_sdvo *psb_intel_sdvo) 326 + { 327 + struct psb_intel_sdvo_set_target_input_args targets = {0}; 328 + return psb_intel_sdvo_set_value(psb_intel_sdvo, 329 + SDVO_CMD_SET_TARGET_INPUT, 330 + &targets, sizeof(targets)); 577 331 } 578 332 579 333 /** ··· 580 338 * This function is making an assumption about the layout of the response, 581 339 * which should be checked against the docs. 582 340 */ 583 - static bool psb_intel_sdvo_get_trained_inputs(struct psb_intel_output 584 - *psb_intel_output, bool *input_1, 585 - bool *input_2) 341 + static bool psb_intel_sdvo_get_trained_inputs(struct psb_intel_sdvo *psb_intel_sdvo, bool *input_1, bool *input_2) 586 342 { 587 343 struct psb_intel_sdvo_get_trained_inputs_response response; 588 - u8 status; 589 344 590 - psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_GET_TRAINED_INPUTS, 591 - NULL, 0); 592 - status = 593 - psb_intel_sdvo_read_response(psb_intel_output, &response, 594 - sizeof(response)); 595 - if (status != SDVO_CMD_STATUS_SUCCESS) 345 + BUILD_BUG_ON(sizeof(response) != 1); 346 + if (!psb_intel_sdvo_get_value(psb_intel_sdvo, SDVO_CMD_GET_TRAINED_INPUTS, 347 + &response, sizeof(response))) 596 348 return false; 597 349 598 350 *input_1 = response.input0_trained; ··· 594 358 return true; 595 359 } 596 360 597 - static bool psb_intel_sdvo_get_active_outputs(struct psb_intel_output 598 - *psb_intel_output, u16 *outputs) 361 + static bool psb_intel_sdvo_set_active_outputs(struct psb_intel_sdvo *psb_intel_sdvo, 362 + u16 outputs) 599 363 { 600 - u8 status; 601 - 602 - psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_GET_ACTIVE_OUTPUTS, 603 - NULL, 0); 604 - status = 605 - psb_intel_sdvo_read_response(psb_intel_output, outputs, 606 - sizeof(*outputs)); 607 - 608 - return status == SDVO_CMD_STATUS_SUCCESS; 364 + return psb_intel_sdvo_set_value(psb_intel_sdvo, 365 + SDVO_CMD_SET_ACTIVE_OUTPUTS, 366 + &outputs, sizeof(outputs)); 609 367 } 610 368 611 - static bool psb_intel_sdvo_set_active_outputs(struct psb_intel_output 612 - *psb_intel_output, u16 outputs) 369 + static bool psb_intel_sdvo_set_encoder_power_state(struct psb_intel_sdvo *psb_intel_sdvo, 370 + int mode) 613 371 { 614 - u8 status; 615 - 616 - psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_ACTIVE_OUTPUTS, 617 - &outputs, sizeof(outputs)); 618 - status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); 619 - return status == SDVO_CMD_STATUS_SUCCESS; 620 - } 621 - 622 - static bool psb_intel_sdvo_set_encoder_power_state(struct psb_intel_output 623 - *psb_intel_output, int mode) 624 - { 625 - u8 status, state = SDVO_ENCODER_STATE_ON; 372 + u8 state = SDVO_ENCODER_STATE_ON; 626 373 627 374 switch (mode) { 628 375 case DRM_MODE_DPMS_ON: ··· 622 403 break; 623 404 } 624 405 625 - psb_intel_sdvo_write_cmd(psb_intel_output, 626 - SDVO_CMD_SET_ENCODER_POWER_STATE, &state, 627 - sizeof(state)); 628 - status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); 629 - 630 - return status == SDVO_CMD_STATUS_SUCCESS; 406 + return psb_intel_sdvo_set_value(psb_intel_sdvo, 407 + SDVO_CMD_SET_ENCODER_POWER_STATE, &state, sizeof(state)); 631 408 } 632 409 633 - static bool psb_intel_sdvo_get_input_pixel_clock_range(struct psb_intel_output 634 - *psb_intel_output, 410 + static bool psb_intel_sdvo_get_input_pixel_clock_range(struct psb_intel_sdvo *psb_intel_sdvo, 635 411 int *clock_min, 636 412 int *clock_max) 637 413 { 638 414 struct psb_intel_sdvo_pixel_clock_range clocks; 639 - u8 status; 640 415 641 - psb_intel_sdvo_write_cmd(psb_intel_output, 642 - SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, NULL, 643 - 0); 644 - 645 - status = 646 - psb_intel_sdvo_read_response(psb_intel_output, &clocks, 647 - sizeof(clocks)); 648 - 649 - if (status != SDVO_CMD_STATUS_SUCCESS) 416 + BUILD_BUG_ON(sizeof(clocks) != 4); 417 + if (!psb_intel_sdvo_get_value(psb_intel_sdvo, 418 + SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE, 419 + &clocks, sizeof(clocks))) 650 420 return false; 651 421 652 422 /* Convert the values from units of 10 kHz to kHz. */ 653 423 *clock_min = clocks.min * 10; 654 424 *clock_max = clocks.max * 10; 655 - 656 425 return true; 657 426 } 658 427 659 - static bool psb_intel_sdvo_set_target_output( 660 - struct psb_intel_output *psb_intel_output, 661 - u16 outputs) 428 + static bool psb_intel_sdvo_set_target_output(struct psb_intel_sdvo *psb_intel_sdvo, 429 + u16 outputs) 662 430 { 663 - u8 status; 664 - 665 - psb_intel_sdvo_write_cmd(psb_intel_output, SDVO_CMD_SET_TARGET_OUTPUT, 666 - &outputs, sizeof(outputs)); 667 - 668 - status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); 669 - return status == SDVO_CMD_STATUS_SUCCESS; 431 + return psb_intel_sdvo_set_value(psb_intel_sdvo, 432 + SDVO_CMD_SET_TARGET_OUTPUT, 433 + &outputs, sizeof(outputs)); 670 434 } 671 435 672 - static bool psb_intel_sdvo_get_timing(struct psb_intel_output *psb_intel_output, 673 - u8 cmd, struct psb_intel_sdvo_dtd *dtd) 436 + static bool psb_intel_sdvo_set_timing(struct psb_intel_sdvo *psb_intel_sdvo, u8 cmd, 437 + struct psb_intel_sdvo_dtd *dtd) 674 438 { 675 - u8 status; 676 - 677 - psb_intel_sdvo_write_cmd(psb_intel_output, cmd, NULL, 0); 678 - status = psb_intel_sdvo_read_response(psb_intel_output, &dtd->part1, 679 - sizeof(dtd->part1)); 680 - if (status != SDVO_CMD_STATUS_SUCCESS) 681 - return false; 682 - 683 - psb_intel_sdvo_write_cmd(psb_intel_output, cmd + 1, NULL, 0); 684 - status = psb_intel_sdvo_read_response(psb_intel_output, &dtd->part2, 685 - sizeof(dtd->part2)); 686 - if (status != SDVO_CMD_STATUS_SUCCESS) 687 - return false; 688 - 689 - return true; 439 + return psb_intel_sdvo_set_value(psb_intel_sdvo, cmd, &dtd->part1, sizeof(dtd->part1)) && 440 + psb_intel_sdvo_set_value(psb_intel_sdvo, cmd + 1, &dtd->part2, sizeof(dtd->part2)); 690 441 } 691 442 692 - static bool psb_intel_sdvo_get_input_timing( 693 - struct psb_intel_output *psb_intel_output, 694 - struct psb_intel_sdvo_dtd *dtd) 443 + static bool psb_intel_sdvo_set_input_timing(struct psb_intel_sdvo *psb_intel_sdvo, 444 + struct psb_intel_sdvo_dtd *dtd) 695 445 { 696 - return psb_intel_sdvo_get_timing(psb_intel_output, 697 - SDVO_CMD_GET_INPUT_TIMINGS_PART1, 698 - dtd); 446 + return psb_intel_sdvo_set_timing(psb_intel_sdvo, 447 + SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd); 699 448 } 700 449 701 - static bool psb_intel_sdvo_set_timing( 702 - struct psb_intel_output *psb_intel_output, 703 - u8 cmd, 704 - struct psb_intel_sdvo_dtd *dtd) 450 + static bool psb_intel_sdvo_set_output_timing(struct psb_intel_sdvo *psb_intel_sdvo, 451 + struct psb_intel_sdvo_dtd *dtd) 705 452 { 706 - u8 status; 707 - 708 - psb_intel_sdvo_write_cmd(psb_intel_output, cmd, &dtd->part1, 709 - sizeof(dtd->part1)); 710 - status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); 711 - if (status != SDVO_CMD_STATUS_SUCCESS) 712 - return false; 713 - 714 - psb_intel_sdvo_write_cmd(psb_intel_output, cmd + 1, &dtd->part2, 715 - sizeof(dtd->part2)); 716 - status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); 717 - if (status != SDVO_CMD_STATUS_SUCCESS) 718 - return false; 719 - 720 - return true; 453 + return psb_intel_sdvo_set_timing(psb_intel_sdvo, 454 + SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd); 721 455 } 722 456 723 - static bool psb_intel_sdvo_set_input_timing( 724 - struct psb_intel_output *psb_intel_output, 725 - struct psb_intel_sdvo_dtd *dtd) 457 + static bool 458 + psb_intel_sdvo_create_preferred_input_timing(struct psb_intel_sdvo *psb_intel_sdvo, 459 + uint16_t clock, 460 + uint16_t width, 461 + uint16_t height) 726 462 { 727 - return psb_intel_sdvo_set_timing(psb_intel_output, 728 - SDVO_CMD_SET_INPUT_TIMINGS_PART1, 729 - dtd); 463 + struct psb_intel_sdvo_preferred_input_timing_args args; 464 + 465 + memset(&args, 0, sizeof(args)); 466 + args.clock = clock; 467 + args.width = width; 468 + args.height = height; 469 + args.interlace = 0; 470 + 471 + if (psb_intel_sdvo->is_lvds && 472 + (psb_intel_sdvo->sdvo_lvds_fixed_mode->hdisplay != width || 473 + psb_intel_sdvo->sdvo_lvds_fixed_mode->vdisplay != height)) 474 + args.scaled = 1; 475 + 476 + return psb_intel_sdvo_set_value(psb_intel_sdvo, 477 + SDVO_CMD_CREATE_PREFERRED_INPUT_TIMING, 478 + &args, sizeof(args)); 730 479 } 731 480 732 - static bool psb_intel_sdvo_set_output_timing( 733 - struct psb_intel_output *psb_intel_output, 734 - struct psb_intel_sdvo_dtd *dtd) 481 + static bool psb_intel_sdvo_get_preferred_input_timing(struct psb_intel_sdvo *psb_intel_sdvo, 482 + struct psb_intel_sdvo_dtd *dtd) 735 483 { 736 - return psb_intel_sdvo_set_timing(psb_intel_output, 737 - SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, 738 - dtd); 484 + BUILD_BUG_ON(sizeof(dtd->part1) != 8); 485 + BUILD_BUG_ON(sizeof(dtd->part2) != 8); 486 + return psb_intel_sdvo_get_value(psb_intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1, 487 + &dtd->part1, sizeof(dtd->part1)) && 488 + psb_intel_sdvo_get_value(psb_intel_sdvo, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2, 489 + &dtd->part2, sizeof(dtd->part2)); 739 490 } 740 491 741 - static int psb_intel_sdvo_get_clock_rate_mult(struct psb_intel_output 742 - *psb_intel_output) 492 + static bool psb_intel_sdvo_set_clock_rate_mult(struct psb_intel_sdvo *psb_intel_sdvo, u8 val) 743 493 { 744 - u8 response, status; 745 - 746 - psb_intel_sdvo_write_cmd(psb_intel_output, 747 - SDVO_CMD_GET_CLOCK_RATE_MULT, 748 - NULL, 749 - 0); 750 - 751 - status = psb_intel_sdvo_read_response(psb_intel_output, &response, 1); 752 - 753 - if (status != SDVO_CMD_STATUS_SUCCESS) { 754 - DRM_DEBUG("Couldn't get SDVO clock rate multiplier\n"); 755 - return SDVO_CLOCK_RATE_MULT_1X; 756 - } else { 757 - DRM_DEBUG("Current clock rate multiplier: %d\n", response); 758 - } 759 - 760 - return response; 494 + return psb_intel_sdvo_set_value(psb_intel_sdvo, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1); 761 495 } 762 496 763 - static bool psb_intel_sdvo_set_clock_rate_mult(struct psb_intel_output 764 - *psb_intel_output, u8 val) 497 + static void psb_intel_sdvo_get_dtd_from_mode(struct psb_intel_sdvo_dtd *dtd, 498 + const struct drm_display_mode *mode) 765 499 { 766 - u8 status; 767 - 768 - psb_intel_sdvo_write_cmd(psb_intel_output, 769 - SDVO_CMD_SET_CLOCK_RATE_MULT, 770 - &val, 771 - 1); 772 - 773 - status = psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); 774 - if (status != SDVO_CMD_STATUS_SUCCESS) 775 - return false; 776 - 777 - return true; 778 - } 779 - 780 - static bool psb_sdvo_set_current_inoutmap(struct psb_intel_output *output, 781 - u32 in0outputmask, 782 - u32 in1outputmask) 783 - { 784 - u8 byArgs[4]; 785 - u8 status; 786 - int i; 787 - struct psb_intel_sdvo_priv *sdvo_priv = output->dev_priv; 788 - 789 - /* Make all fields of the args/ret to zero */ 790 - memset(byArgs, 0, sizeof(byArgs)); 791 - 792 - /* Fill up the argument values; */ 793 - byArgs[0] = (u8) (in0outputmask & 0xFF); 794 - byArgs[1] = (u8) ((in0outputmask >> 8) & 0xFF); 795 - byArgs[2] = (u8) (in1outputmask & 0xFF); 796 - byArgs[3] = (u8) ((in1outputmask >> 8) & 0xFF); 797 - 798 - 799 - /*save inoutmap arg here*/ 800 - for (i = 0; i < 4; i++) 801 - sdvo_priv->in_out_map[i] = byArgs[0]; 802 - 803 - psb_intel_sdvo_write_cmd(output, SDVO_CMD_SET_IN_OUT_MAP, byArgs, 4); 804 - status = psb_intel_sdvo_read_response(output, NULL, 0); 805 - 806 - if (status != SDVO_CMD_STATUS_SUCCESS) 807 - return false; 808 - return true; 809 - } 810 - 811 - 812 - static void psb_intel_sdvo_set_iomap(struct psb_intel_output *output) 813 - { 814 - u32 dwCurrentSDVOIn0 = 0; 815 - u32 dwCurrentSDVOIn1 = 0; 816 - u32 dwDevMask = 0; 817 - 818 - 819 - struct psb_intel_sdvo_priv *sdvo_priv = output->dev_priv; 820 - 821 - /* Please DO NOT change the following code. */ 822 - /* SDVOB_IN0 or SDVOB_IN1 ==> sdvo_in0 */ 823 - /* SDVOC_IN0 or SDVOC_IN1 ==> sdvo_in1 */ 824 - if (sdvo_priv->by_input_wiring & (SDVOB_IN0 | SDVOC_IN0)) { 825 - switch (sdvo_priv->active_device) { 826 - case SDVO_DEVICE_LVDS: 827 - dwDevMask = SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1; 828 - break; 829 - case SDVO_DEVICE_TMDS: 830 - dwDevMask = SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1; 831 - break; 832 - case SDVO_DEVICE_TV: 833 - dwDevMask = 834 - SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_SVID0 | 835 - SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_YPRPB1 | 836 - SDVO_OUTPUT_SVID1 | SDVO_OUTPUT_CVBS1 | 837 - SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1; 838 - break; 839 - case SDVO_DEVICE_CRT: 840 - dwDevMask = SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1; 841 - break; 842 - } 843 - dwCurrentSDVOIn0 = (sdvo_priv->active_outputs & dwDevMask); 844 - } else if (sdvo_priv->by_input_wiring & (SDVOB_IN1 | SDVOC_IN1)) { 845 - switch (sdvo_priv->active_device) { 846 - case SDVO_DEVICE_LVDS: 847 - dwDevMask = SDVO_OUTPUT_LVDS0 | SDVO_OUTPUT_LVDS1; 848 - break; 849 - case SDVO_DEVICE_TMDS: 850 - dwDevMask = SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1; 851 - break; 852 - case SDVO_DEVICE_TV: 853 - dwDevMask = 854 - SDVO_OUTPUT_YPRPB0 | SDVO_OUTPUT_SVID0 | 855 - SDVO_OUTPUT_CVBS0 | SDVO_OUTPUT_YPRPB1 | 856 - SDVO_OUTPUT_SVID1 | SDVO_OUTPUT_CVBS1 | 857 - SDVO_OUTPUT_SCART0 | SDVO_OUTPUT_SCART1; 858 - break; 859 - case SDVO_DEVICE_CRT: 860 - dwDevMask = SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1; 861 - break; 862 - } 863 - dwCurrentSDVOIn1 = (sdvo_priv->active_outputs & dwDevMask); 864 - } 865 - 866 - psb_sdvo_set_current_inoutmap(output, dwCurrentSDVOIn0, 867 - dwCurrentSDVOIn1); 868 - } 869 - 870 - 871 - static bool psb_intel_sdvo_mode_fixup(struct drm_encoder *encoder, 872 - struct drm_display_mode *mode, 873 - struct drm_display_mode *adjusted_mode) 874 - { 875 - /* Make the CRTC code factor in the SDVO pixel multiplier. The SDVO 876 - * device will be told of the multiplier during mode_set. 877 - */ 878 - adjusted_mode->clock *= psb_intel_sdvo_get_pixel_multiplier(mode); 879 - return true; 880 - } 881 - 882 - static void psb_intel_sdvo_mode_set(struct drm_encoder *encoder, 883 - struct drm_display_mode *mode, 884 - struct drm_display_mode *adjusted_mode) 885 - { 886 - struct drm_device *dev = encoder->dev; 887 - struct drm_crtc *crtc = encoder->crtc; 888 - struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); 889 - struct psb_intel_output *psb_intel_output = 890 - enc_to_psb_intel_output(encoder); 891 - struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; 892 - u16 width, height; 893 - u16 h_blank_len, h_sync_len, v_blank_len, v_sync_len; 894 - u16 h_sync_offset, v_sync_offset; 895 - u32 sdvox; 896 - struct psb_intel_sdvo_dtd output_dtd; 897 - int sdvo_pixel_multiply; 898 - 899 - if (!mode) 900 - return; 901 - 902 - psb_intel_sdvo_set_target_output(psb_intel_output, 0); 500 + uint16_t width, height; 501 + uint16_t h_blank_len, h_sync_len, v_blank_len, v_sync_len; 502 + uint16_t h_sync_offset, v_sync_offset; 903 503 904 504 width = mode->crtc_hdisplay; 905 505 height = mode->crtc_vdisplay; ··· 733 695 h_sync_offset = mode->crtc_hsync_start - mode->crtc_hblank_start; 734 696 v_sync_offset = mode->crtc_vsync_start - mode->crtc_vblank_start; 735 697 736 - output_dtd.part1.clock = mode->clock / 10; 737 - output_dtd.part1.h_active = width & 0xff; 738 - output_dtd.part1.h_blank = h_blank_len & 0xff; 739 - output_dtd.part1.h_high = (((width >> 8) & 0xf) << 4) | 740 - ((h_blank_len >> 8) & 0xf); 741 - output_dtd.part1.v_active = height & 0xff; 742 - output_dtd.part1.v_blank = v_blank_len & 0xff; 743 - output_dtd.part1.v_high = (((height >> 8) & 0xf) << 4) | 744 - ((v_blank_len >> 8) & 0xf); 698 + dtd->part1.clock = mode->clock / 10; 699 + dtd->part1.h_active = width & 0xff; 700 + dtd->part1.h_blank = h_blank_len & 0xff; 701 + dtd->part1.h_high = (((width >> 8) & 0xf) << 4) | 702 + ((h_blank_len >> 8) & 0xf); 703 + dtd->part1.v_active = height & 0xff; 704 + dtd->part1.v_blank = v_blank_len & 0xff; 705 + dtd->part1.v_high = (((height >> 8) & 0xf) << 4) | 706 + ((v_blank_len >> 8) & 0xf); 745 707 746 - output_dtd.part2.h_sync_off = h_sync_offset; 747 - output_dtd.part2.h_sync_width = h_sync_len & 0xff; 748 - output_dtd.part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 | 749 - (v_sync_len & 0xf); 750 - output_dtd.part2.sync_off_width_high = 751 - ((h_sync_offset & 0x300) >> 2) | ((h_sync_len & 0x300) >> 4) | 752 - ((v_sync_offset & 0x30) >> 2) | ((v_sync_len & 0x30) >> 4); 708 + dtd->part2.h_sync_off = h_sync_offset & 0xff; 709 + dtd->part2.h_sync_width = h_sync_len & 0xff; 710 + dtd->part2.v_sync_off_width = (v_sync_offset & 0xf) << 4 | 711 + (v_sync_len & 0xf); 712 + dtd->part2.sync_off_width_high = ((h_sync_offset & 0x300) >> 2) | 713 + ((h_sync_len & 0x300) >> 4) | ((v_sync_offset & 0x30) >> 2) | 714 + ((v_sync_len & 0x30) >> 4); 753 715 754 - output_dtd.part2.dtd_flags = 0x18; 716 + dtd->part2.dtd_flags = 0x18; 755 717 if (mode->flags & DRM_MODE_FLAG_PHSYNC) 756 - output_dtd.part2.dtd_flags |= 0x2; 718 + dtd->part2.dtd_flags |= 0x2; 757 719 if (mode->flags & DRM_MODE_FLAG_PVSYNC) 758 - output_dtd.part2.dtd_flags |= 0x4; 720 + dtd->part2.dtd_flags |= 0x4; 759 721 760 - output_dtd.part2.sdvo_flags = 0; 761 - output_dtd.part2.v_sync_off_high = v_sync_offset & 0xc0; 762 - output_dtd.part2.reserved = 0; 722 + dtd->part2.sdvo_flags = 0; 723 + dtd->part2.v_sync_off_high = v_sync_offset & 0xc0; 724 + dtd->part2.reserved = 0; 725 + } 763 726 764 - /* Set the output timing to the screen */ 765 - psb_intel_sdvo_set_target_output(psb_intel_output, 766 - sdvo_priv->active_outputs); 727 + static void psb_intel_sdvo_get_mode_from_dtd(struct drm_display_mode * mode, 728 + const struct psb_intel_sdvo_dtd *dtd) 729 + { 730 + mode->hdisplay = dtd->part1.h_active; 731 + mode->hdisplay += ((dtd->part1.h_high >> 4) & 0x0f) << 8; 732 + mode->hsync_start = mode->hdisplay + dtd->part2.h_sync_off; 733 + mode->hsync_start += (dtd->part2.sync_off_width_high & 0xc0) << 2; 734 + mode->hsync_end = mode->hsync_start + dtd->part2.h_sync_width; 735 + mode->hsync_end += (dtd->part2.sync_off_width_high & 0x30) << 4; 736 + mode->htotal = mode->hdisplay + dtd->part1.h_blank; 737 + mode->htotal += (dtd->part1.h_high & 0xf) << 8; 767 738 768 - /* Set the input timing to the screen. Assume always input 0. */ 769 - psb_intel_sdvo_set_target_input(psb_intel_output, true, false); 739 + mode->vdisplay = dtd->part1.v_active; 740 + mode->vdisplay += ((dtd->part1.v_high >> 4) & 0x0f) << 8; 741 + mode->vsync_start = mode->vdisplay; 742 + mode->vsync_start += (dtd->part2.v_sync_off_width >> 4) & 0xf; 743 + mode->vsync_start += (dtd->part2.sync_off_width_high & 0x0c) << 2; 744 + mode->vsync_start += dtd->part2.v_sync_off_high & 0xc0; 745 + mode->vsync_end = mode->vsync_start + 746 + (dtd->part2.v_sync_off_width & 0xf); 747 + mode->vsync_end += (dtd->part2.sync_off_width_high & 0x3) << 4; 748 + mode->vtotal = mode->vdisplay + dtd->part1.v_blank; 749 + mode->vtotal += (dtd->part1.v_high & 0xf) << 8; 770 750 771 - psb_intel_sdvo_set_output_timing(psb_intel_output, &output_dtd); 751 + mode->clock = dtd->part1.clock * 10; 772 752 773 - /* We would like to use i830_sdvo_create_preferred_input_timing() to 774 - * provide the device with a timing it can support, if it supports that 775 - * feature. However, presumably we would need to adjust the CRTC to 776 - * output the preferred timing, and we don't support that currently. 777 - */ 778 - psb_intel_sdvo_set_input_timing(psb_intel_output, &output_dtd); 753 + mode->flags &= ~(DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC); 754 + if (dtd->part2.dtd_flags & 0x2) 755 + mode->flags |= DRM_MODE_FLAG_PHSYNC; 756 + if (dtd->part2.dtd_flags & 0x4) 757 + mode->flags |= DRM_MODE_FLAG_PVSYNC; 758 + } 779 759 780 - switch (psb_intel_sdvo_get_pixel_multiplier(mode)) { 781 - case 1: 782 - psb_intel_sdvo_set_clock_rate_mult(psb_intel_output, 783 - SDVO_CLOCK_RATE_MULT_1X); 784 - break; 785 - case 2: 786 - psb_intel_sdvo_set_clock_rate_mult(psb_intel_output, 787 - SDVO_CLOCK_RATE_MULT_2X); 788 - break; 789 - case 4: 790 - psb_intel_sdvo_set_clock_rate_mult(psb_intel_output, 791 - SDVO_CLOCK_RATE_MULT_4X); 792 - break; 760 + static bool psb_intel_sdvo_check_supp_encode(struct psb_intel_sdvo *psb_intel_sdvo) 761 + { 762 + struct psb_intel_sdvo_encode encode; 763 + 764 + BUILD_BUG_ON(sizeof(encode) != 2); 765 + return psb_intel_sdvo_get_value(psb_intel_sdvo, 766 + SDVO_CMD_GET_SUPP_ENCODE, 767 + &encode, sizeof(encode)); 768 + } 769 + 770 + static bool psb_intel_sdvo_set_encode(struct psb_intel_sdvo *psb_intel_sdvo, 771 + uint8_t mode) 772 + { 773 + return psb_intel_sdvo_set_value(psb_intel_sdvo, SDVO_CMD_SET_ENCODE, &mode, 1); 774 + } 775 + 776 + static bool psb_intel_sdvo_set_colorimetry(struct psb_intel_sdvo *psb_intel_sdvo, 777 + uint8_t mode) 778 + { 779 + return psb_intel_sdvo_set_value(psb_intel_sdvo, SDVO_CMD_SET_COLORIMETRY, &mode, 1); 780 + } 781 + 782 + #if 0 783 + static void psb_intel_sdvo_dump_hdmi_buf(struct psb_intel_sdvo *psb_intel_sdvo) 784 + { 785 + int i, j; 786 + uint8_t set_buf_index[2]; 787 + uint8_t av_split; 788 + uint8_t buf_size; 789 + uint8_t buf[48]; 790 + uint8_t *pos; 791 + 792 + psb_intel_sdvo_get_value(encoder, SDVO_CMD_GET_HBUF_AV_SPLIT, &av_split, 1); 793 + 794 + for (i = 0; i <= av_split; i++) { 795 + set_buf_index[0] = i; set_buf_index[1] = 0; 796 + psb_intel_sdvo_write_cmd(encoder, SDVO_CMD_SET_HBUF_INDEX, 797 + set_buf_index, 2); 798 + psb_intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_INFO, NULL, 0); 799 + psb_intel_sdvo_read_response(encoder, &buf_size, 1); 800 + 801 + pos = buf; 802 + for (j = 0; j <= buf_size; j += 8) { 803 + psb_intel_sdvo_write_cmd(encoder, SDVO_CMD_GET_HBUF_DATA, 804 + NULL, 0); 805 + psb_intel_sdvo_read_response(encoder, pos, 8); 806 + pos += 8; 807 + } 808 + } 809 + } 810 + #endif 811 + 812 + static bool psb_intel_sdvo_set_avi_infoframe(struct psb_intel_sdvo *psb_intel_sdvo) 813 + { 814 + DRM_INFO("HDMI is not supported yet"); 815 + 816 + return false; 817 + #if 0 818 + struct dip_infoframe avi_if = { 819 + .type = DIP_TYPE_AVI, 820 + .ver = DIP_VERSION_AVI, 821 + .len = DIP_LEN_AVI, 822 + }; 823 + uint8_t tx_rate = SDVO_HBUF_TX_VSYNC; 824 + uint8_t set_buf_index[2] = { 1, 0 }; 825 + uint64_t *data = (uint64_t *)&avi_if; 826 + unsigned i; 827 + 828 + intel_dip_infoframe_csum(&avi_if); 829 + 830 + if (!psb_intel_sdvo_set_value(psb_intel_sdvo, 831 + SDVO_CMD_SET_HBUF_INDEX, 832 + set_buf_index, 2)) 833 + return false; 834 + 835 + for (i = 0; i < sizeof(avi_if); i += 8) { 836 + if (!psb_intel_sdvo_set_value(psb_intel_sdvo, 837 + SDVO_CMD_SET_HBUF_DATA, 838 + data, 8)) 839 + return false; 840 + data++; 793 841 } 794 842 843 + return psb_intel_sdvo_set_value(psb_intel_sdvo, 844 + SDVO_CMD_SET_HBUF_TXRATE, 845 + &tx_rate, 1); 846 + #endif 847 + } 848 + 849 + static bool psb_intel_sdvo_set_tv_format(struct psb_intel_sdvo *psb_intel_sdvo) 850 + { 851 + struct psb_intel_sdvo_tv_format format; 852 + uint32_t format_map; 853 + 854 + format_map = 1 << psb_intel_sdvo->tv_format_index; 855 + memset(&format, 0, sizeof(format)); 856 + memcpy(&format, &format_map, min(sizeof(format), sizeof(format_map))); 857 + 858 + BUILD_BUG_ON(sizeof(format) != 6); 859 + return psb_intel_sdvo_set_value(psb_intel_sdvo, 860 + SDVO_CMD_SET_TV_FORMAT, 861 + &format, sizeof(format)); 862 + } 863 + 864 + static bool 865 + psb_intel_sdvo_set_output_timings_from_mode(struct psb_intel_sdvo *psb_intel_sdvo, 866 + struct drm_display_mode *mode) 867 + { 868 + struct psb_intel_sdvo_dtd output_dtd; 869 + 870 + if (!psb_intel_sdvo_set_target_output(psb_intel_sdvo, 871 + psb_intel_sdvo->attached_output)) 872 + return false; 873 + 874 + psb_intel_sdvo_get_dtd_from_mode(&output_dtd, mode); 875 + if (!psb_intel_sdvo_set_output_timing(psb_intel_sdvo, &output_dtd)) 876 + return false; 877 + 878 + return true; 879 + } 880 + 881 + static bool 882 + psb_intel_sdvo_set_input_timings_for_mode(struct psb_intel_sdvo *psb_intel_sdvo, 883 + struct drm_display_mode *mode, 884 + struct drm_display_mode *adjusted_mode) 885 + { 886 + /* Reset the input timing to the screen. Assume always input 0. */ 887 + if (!psb_intel_sdvo_set_target_input(psb_intel_sdvo)) 888 + return false; 889 + 890 + if (!psb_intel_sdvo_create_preferred_input_timing(psb_intel_sdvo, 891 + mode->clock / 10, 892 + mode->hdisplay, 893 + mode->vdisplay)) 894 + return false; 895 + 896 + if (!psb_intel_sdvo_get_preferred_input_timing(psb_intel_sdvo, 897 + &psb_intel_sdvo->input_dtd)) 898 + return false; 899 + 900 + psb_intel_sdvo_get_mode_from_dtd(adjusted_mode, &psb_intel_sdvo->input_dtd); 901 + 902 + drm_mode_set_crtcinfo(adjusted_mode, 0); 903 + return true; 904 + } 905 + 906 + static bool psb_intel_sdvo_mode_fixup(struct drm_encoder *encoder, 907 + struct drm_display_mode *mode, 908 + struct drm_display_mode *adjusted_mode) 909 + { 910 + struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(encoder); 911 + int multiplier; 912 + 913 + /* We need to construct preferred input timings based on our 914 + * output timings. To do that, we have to set the output 915 + * timings, even though this isn't really the right place in 916 + * the sequence to do it. Oh well. 917 + */ 918 + if (psb_intel_sdvo->is_tv) { 919 + if (!psb_intel_sdvo_set_output_timings_from_mode(psb_intel_sdvo, mode)) 920 + return false; 921 + 922 + (void) psb_intel_sdvo_set_input_timings_for_mode(psb_intel_sdvo, 923 + mode, 924 + adjusted_mode); 925 + } else if (psb_intel_sdvo->is_lvds) { 926 + if (!psb_intel_sdvo_set_output_timings_from_mode(psb_intel_sdvo, 927 + psb_intel_sdvo->sdvo_lvds_fixed_mode)) 928 + return false; 929 + 930 + (void) psb_intel_sdvo_set_input_timings_for_mode(psb_intel_sdvo, 931 + mode, 932 + adjusted_mode); 933 + } 934 + 935 + /* Make the CRTC code factor in the SDVO pixel multiplier. The 936 + * SDVO device will factor out the multiplier during mode_set. 937 + */ 938 + multiplier = psb_intel_sdvo_get_pixel_multiplier(adjusted_mode); 939 + psb_intel_mode_set_pixel_multiplier(adjusted_mode, multiplier); 940 + 941 + return true; 942 + } 943 + 944 + static void psb_intel_sdvo_mode_set(struct drm_encoder *encoder, 945 + struct drm_display_mode *mode, 946 + struct drm_display_mode *adjusted_mode) 947 + { 948 + struct drm_device *dev = encoder->dev; 949 + struct drm_crtc *crtc = encoder->crtc; 950 + struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc); 951 + struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(encoder); 952 + u32 sdvox; 953 + struct psb_intel_sdvo_in_out_map in_out; 954 + struct psb_intel_sdvo_dtd input_dtd; 955 + int pixel_multiplier = psb_intel_mode_get_pixel_multiplier(adjusted_mode); 956 + int rate; 957 + 958 + if (!mode) 959 + return; 960 + 961 + /* First, set the input mapping for the first input to our controlled 962 + * output. This is only correct if we're a single-input device, in 963 + * which case the first input is the output from the appropriate SDVO 964 + * channel on the motherboard. In a two-input device, the first input 965 + * will be SDVOB and the second SDVOC. 966 + */ 967 + in_out.in0 = psb_intel_sdvo->attached_output; 968 + in_out.in1 = 0; 969 + 970 + psb_intel_sdvo_set_value(psb_intel_sdvo, 971 + SDVO_CMD_SET_IN_OUT_MAP, 972 + &in_out, sizeof(in_out)); 973 + 974 + /* Set the output timings to the screen */ 975 + if (!psb_intel_sdvo_set_target_output(psb_intel_sdvo, 976 + psb_intel_sdvo->attached_output)) 977 + return; 978 + 979 + /* We have tried to get input timing in mode_fixup, and filled into 980 + * adjusted_mode. 981 + */ 982 + if (psb_intel_sdvo->is_tv || psb_intel_sdvo->is_lvds) { 983 + input_dtd = psb_intel_sdvo->input_dtd; 984 + } else { 985 + /* Set the output timing to the screen */ 986 + if (!psb_intel_sdvo_set_target_output(psb_intel_sdvo, 987 + psb_intel_sdvo->attached_output)) 988 + return; 989 + 990 + psb_intel_sdvo_get_dtd_from_mode(&input_dtd, adjusted_mode); 991 + (void) psb_intel_sdvo_set_output_timing(psb_intel_sdvo, &input_dtd); 992 + } 993 + 994 + /* Set the input timing to the screen. Assume always input 0. */ 995 + if (!psb_intel_sdvo_set_target_input(psb_intel_sdvo)) 996 + return; 997 + 998 + if (psb_intel_sdvo->has_hdmi_monitor) { 999 + psb_intel_sdvo_set_encode(psb_intel_sdvo, SDVO_ENCODE_HDMI); 1000 + psb_intel_sdvo_set_colorimetry(psb_intel_sdvo, 1001 + SDVO_COLORIMETRY_RGB256); 1002 + psb_intel_sdvo_set_avi_infoframe(psb_intel_sdvo); 1003 + } else 1004 + psb_intel_sdvo_set_encode(psb_intel_sdvo, SDVO_ENCODE_DVI); 1005 + 1006 + if (psb_intel_sdvo->is_tv && 1007 + !psb_intel_sdvo_set_tv_format(psb_intel_sdvo)) 1008 + return; 1009 + 1010 + (void) psb_intel_sdvo_set_input_timing(psb_intel_sdvo, &input_dtd); 1011 + 1012 + switch (pixel_multiplier) { 1013 + default: 1014 + case 1: rate = SDVO_CLOCK_RATE_MULT_1X; break; 1015 + case 2: rate = SDVO_CLOCK_RATE_MULT_2X; break; 1016 + case 4: rate = SDVO_CLOCK_RATE_MULT_4X; break; 1017 + } 1018 + if (!psb_intel_sdvo_set_clock_rate_mult(psb_intel_sdvo, rate)) 1019 + return; 1020 + 795 1021 /* Set the SDVO control regs. */ 796 - sdvox = REG_READ(sdvo_priv->output_device); 797 - switch (sdvo_priv->output_device) { 1022 + sdvox = REG_READ(psb_intel_sdvo->sdvo_reg); 1023 + switch (psb_intel_sdvo->sdvo_reg) { 798 1024 case SDVOB: 799 1025 sdvox &= SDVOB_PRESERVE_MASK; 800 1026 break; ··· 1067 765 break; 1068 766 } 1069 767 sdvox |= (9 << 19) | SDVO_BORDER_ENABLE; 768 + 1070 769 if (psb_intel_crtc->pipe == 1) 1071 770 sdvox |= SDVO_PIPE_B_SELECT; 771 + if (psb_intel_sdvo->has_hdmi_audio) 772 + sdvox |= SDVO_AUDIO_ENABLE; 1072 773 1073 - sdvo_pixel_multiply = psb_intel_sdvo_get_pixel_multiplier(mode); 774 + /* FIXME: Check if this is needed for PSB 775 + sdvox |= (pixel_multiplier - 1) << SDVO_PORT_MULTIPLY_SHIFT; 776 + */ 1074 777 1075 - psb_intel_sdvo_write_sdvox(psb_intel_output, sdvox); 1076 - 1077 - psb_intel_sdvo_set_iomap(psb_intel_output); 778 + if (input_dtd.part2.sdvo_flags & SDVO_NEED_TO_STALL) 779 + sdvox |= SDVO_STALL_SELECT; 780 + psb_intel_sdvo_write_sdvox(psb_intel_sdvo, sdvox); 1078 781 } 1079 782 1080 783 static void psb_intel_sdvo_dpms(struct drm_encoder *encoder, int mode) 1081 784 { 1082 785 struct drm_device *dev = encoder->dev; 1083 - struct psb_intel_output *psb_intel_output = 1084 - enc_to_psb_intel_output(encoder); 1085 - struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; 786 + struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(encoder); 1086 787 u32 temp; 1087 788 789 + switch (mode) { 790 + case DRM_MODE_DPMS_ON: 791 + DRM_DEBUG("DPMS_ON"); 792 + break; 793 + case DRM_MODE_DPMS_OFF: 794 + DRM_DEBUG("DPMS_OFF"); 795 + break; 796 + default: 797 + DRM_DEBUG("DPMS: %d", mode); 798 + } 799 + 1088 800 if (mode != DRM_MODE_DPMS_ON) { 1089 - psb_intel_sdvo_set_active_outputs(psb_intel_output, 0); 801 + psb_intel_sdvo_set_active_outputs(psb_intel_sdvo, 0); 1090 802 if (0) 1091 - psb_intel_sdvo_set_encoder_power_state( 1092 - psb_intel_output, 1093 - mode); 803 + psb_intel_sdvo_set_encoder_power_state(psb_intel_sdvo, mode); 1094 804 1095 805 if (mode == DRM_MODE_DPMS_OFF) { 1096 - temp = REG_READ(sdvo_priv->output_device); 806 + temp = REG_READ(psb_intel_sdvo->sdvo_reg); 1097 807 if ((temp & SDVO_ENABLE) != 0) { 1098 - psb_intel_sdvo_write_sdvox(psb_intel_output, 1099 - temp & 1100 - ~SDVO_ENABLE); 808 + psb_intel_sdvo_write_sdvox(psb_intel_sdvo, temp & ~SDVO_ENABLE); 1101 809 } 1102 810 } 1103 811 } else { ··· 1115 803 int i; 1116 804 u8 status; 1117 805 1118 - temp = REG_READ(sdvo_priv->output_device); 806 + temp = REG_READ(psb_intel_sdvo->sdvo_reg); 1119 807 if ((temp & SDVO_ENABLE) == 0) 1120 - psb_intel_sdvo_write_sdvox(psb_intel_output, 1121 - temp | SDVO_ENABLE); 808 + psb_intel_sdvo_write_sdvox(psb_intel_sdvo, temp | SDVO_ENABLE); 1122 809 for (i = 0; i < 2; i++) 1123 810 psb_intel_wait_for_vblank(dev); 1124 811 1125 - status = 1126 - psb_intel_sdvo_get_trained_inputs(psb_intel_output, 1127 - &input1, 1128 - &input2); 1129 - 1130 - 812 + status = psb_intel_sdvo_get_trained_inputs(psb_intel_sdvo, &input1, &input2); 1131 813 /* Warn if the device reported failure to sync. 1132 814 * A lot of SDVO devices fail to notify of sync, but it's 1133 815 * a given it the status is a success, we succeeded. 1134 816 */ 1135 817 if (status == SDVO_CMD_STATUS_SUCCESS && !input1) { 1136 - DRM_DEBUG 1137 - ("First %s output reported failure to sync\n", 1138 - SDVO_NAME(sdvo_priv)); 818 + DRM_DEBUG_KMS("First %s output reported failure to " 819 + "sync\n", SDVO_NAME(psb_intel_sdvo)); 1139 820 } 1140 821 1141 822 if (0) 1142 - psb_intel_sdvo_set_encoder_power_state( 1143 - psb_intel_output, 1144 - mode); 1145 - psb_intel_sdvo_set_active_outputs(psb_intel_output, 1146 - sdvo_priv->active_outputs); 823 + psb_intel_sdvo_set_encoder_power_state(psb_intel_sdvo, mode); 824 + psb_intel_sdvo_set_active_outputs(psb_intel_sdvo, psb_intel_sdvo->attached_output); 1147 825 } 1148 826 return; 1149 - } 1150 - 1151 - static void psb_intel_sdvo_save(struct drm_connector *connector) 1152 - { 1153 - struct drm_device *dev = connector->dev; 1154 - struct psb_intel_output *psb_intel_output = 1155 - to_psb_intel_output(connector); 1156 - struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; 1157 - /*int o;*/ 1158 - 1159 - sdvo_priv->save_sdvo_mult = 1160 - psb_intel_sdvo_get_clock_rate_mult(psb_intel_output); 1161 - psb_intel_sdvo_get_active_outputs(psb_intel_output, 1162 - &sdvo_priv->save_active_outputs); 1163 - 1164 - if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { 1165 - psb_intel_sdvo_set_target_input(psb_intel_output, 1166 - true, 1167 - false); 1168 - psb_intel_sdvo_get_input_timing(psb_intel_output, 1169 - &sdvo_priv->save_input_dtd_1); 1170 - } 1171 - 1172 - if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { 1173 - psb_intel_sdvo_set_target_input(psb_intel_output, 1174 - false, 1175 - true); 1176 - psb_intel_sdvo_get_input_timing(psb_intel_output, 1177 - &sdvo_priv->save_input_dtd_2); 1178 - } 1179 - sdvo_priv->save_SDVOX = REG_READ(sdvo_priv->output_device); 1180 - 1181 - /*TODO: save the in_out_map state*/ 1182 - } 1183 - 1184 - static void psb_intel_sdvo_restore(struct drm_connector *connector) 1185 - { 1186 - struct drm_device *dev = connector->dev; 1187 - struct psb_intel_output *psb_intel_output = 1188 - to_psb_intel_output(connector); 1189 - struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; 1190 - /*int o;*/ 1191 - int i; 1192 - bool input1, input2; 1193 - u8 status; 1194 - 1195 - psb_intel_sdvo_set_active_outputs(psb_intel_output, 0); 1196 - 1197 - if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) { 1198 - psb_intel_sdvo_set_target_input(psb_intel_output, true, false); 1199 - psb_intel_sdvo_set_input_timing(psb_intel_output, 1200 - &sdvo_priv->save_input_dtd_1); 1201 - } 1202 - 1203 - if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) { 1204 - psb_intel_sdvo_set_target_input(psb_intel_output, false, true); 1205 - psb_intel_sdvo_set_input_timing(psb_intel_output, 1206 - &sdvo_priv->save_input_dtd_2); 1207 - } 1208 - 1209 - psb_intel_sdvo_set_clock_rate_mult(psb_intel_output, 1210 - sdvo_priv->save_sdvo_mult); 1211 - 1212 - REG_WRITE(sdvo_priv->output_device, sdvo_priv->save_SDVOX); 1213 - 1214 - if (sdvo_priv->save_SDVOX & SDVO_ENABLE) { 1215 - for (i = 0; i < 2; i++) 1216 - psb_intel_wait_for_vblank(dev); 1217 - status = 1218 - psb_intel_sdvo_get_trained_inputs(psb_intel_output, 1219 - &input1, 1220 - &input2); 1221 - if (status == SDVO_CMD_STATUS_SUCCESS && !input1) 1222 - DRM_DEBUG 1223 - ("First %s output reported failure to sync\n", 1224 - SDVO_NAME(sdvo_priv)); 1225 - } 1226 - 1227 - psb_intel_sdvo_set_active_outputs(psb_intel_output, 1228 - sdvo_priv->save_active_outputs); 1229 - 1230 - /*TODO: restore in_out_map*/ 1231 - psb_intel_sdvo_write_cmd(psb_intel_output, 1232 - SDVO_CMD_SET_IN_OUT_MAP, 1233 - sdvo_priv->in_out_map, 1234 - 4); 1235 - 1236 - psb_intel_sdvo_read_response(psb_intel_output, NULL, 0); 1237 827 } 1238 828 1239 829 static int psb_intel_sdvo_mode_valid(struct drm_connector *connector, 1240 830 struct drm_display_mode *mode) 1241 831 { 1242 - struct psb_intel_output *psb_intel_output = 1243 - to_psb_intel_output(connector); 1244 - struct psb_intel_sdvo_priv *sdvo_priv = psb_intel_output->dev_priv; 832 + struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector); 1245 833 1246 834 if (mode->flags & DRM_MODE_FLAG_DBLSCAN) 1247 835 return MODE_NO_DBLESCAN; 1248 836 1249 - if (sdvo_priv->pixel_clock_min > mode->clock) 837 + if (psb_intel_sdvo->pixel_clock_min > mode->clock) 1250 838 return MODE_CLOCK_LOW; 1251 839 1252 - if (sdvo_priv->pixel_clock_max < mode->clock) 840 + if (psb_intel_sdvo->pixel_clock_max < mode->clock) 1253 841 return MODE_CLOCK_HIGH; 842 + 843 + if (psb_intel_sdvo->is_lvds) { 844 + if (mode->hdisplay > psb_intel_sdvo->sdvo_lvds_fixed_mode->hdisplay) 845 + return MODE_PANEL; 846 + 847 + if (mode->vdisplay > psb_intel_sdvo->sdvo_lvds_fixed_mode->vdisplay) 848 + return MODE_PANEL; 849 + } 1254 850 1255 851 return MODE_OK; 1256 852 } 1257 853 1258 - static bool psb_intel_sdvo_get_capabilities( 1259 - struct psb_intel_output *psb_intel_output, 1260 - struct psb_intel_sdvo_caps *caps) 854 + static bool psb_intel_sdvo_get_capabilities(struct psb_intel_sdvo *psb_intel_sdvo, struct psb_intel_sdvo_caps *caps) 1261 855 { 1262 - u8 status; 1263 - 1264 - psb_intel_sdvo_write_cmd(psb_intel_output, 1265 - SDVO_CMD_GET_DEVICE_CAPS, 1266 - NULL, 1267 - 0); 1268 - status = psb_intel_sdvo_read_response(psb_intel_output, 1269 - caps, 1270 - sizeof(*caps)); 1271 - if (status != SDVO_CMD_STATUS_SUCCESS) 856 + BUILD_BUG_ON(sizeof(*caps) != 8); 857 + if (!psb_intel_sdvo_get_value(psb_intel_sdvo, 858 + SDVO_CMD_GET_DEVICE_CAPS, 859 + caps, sizeof(*caps))) 1272 860 return false; 861 + 862 + DRM_DEBUG_KMS("SDVO capabilities:\n" 863 + " vendor_id: %d\n" 864 + " device_id: %d\n" 865 + " device_rev_id: %d\n" 866 + " sdvo_version_major: %d\n" 867 + " sdvo_version_minor: %d\n" 868 + " sdvo_inputs_mask: %d\n" 869 + " smooth_scaling: %d\n" 870 + " sharp_scaling: %d\n" 871 + " up_scaling: %d\n" 872 + " down_scaling: %d\n" 873 + " stall_support: %d\n" 874 + " output_flags: %d\n", 875 + caps->vendor_id, 876 + caps->device_id, 877 + caps->device_rev_id, 878 + caps->sdvo_version_major, 879 + caps->sdvo_version_minor, 880 + caps->sdvo_inputs_mask, 881 + caps->smooth_scaling, 882 + caps->sharp_scaling, 883 + caps->up_scaling, 884 + caps->down_scaling, 885 + caps->stall_support, 886 + caps->output_flags); 1273 887 1274 888 return true; 1275 889 } 1276 890 1277 - struct drm_connector *psb_intel_sdvo_find(struct drm_device *dev, int sdvoB) 891 + /* No use! */ 892 + #if 0 893 + struct drm_connector* psb_intel_sdvo_find(struct drm_device *dev, int sdvoB) 1278 894 { 1279 895 struct drm_connector *connector = NULL; 1280 - struct psb_intel_output *iout = NULL; 1281 - struct psb_intel_sdvo_priv *sdvo; 896 + struct psb_intel_sdvo *iout = NULL; 897 + struct psb_intel_sdvo *sdvo; 1282 898 1283 899 /* find the sdvo connector */ 1284 - list_for_each_entry(connector, &dev->mode_config.connector_list, 1285 - head) { 1286 - iout = to_psb_intel_output(connector); 900 + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { 901 + iout = to_psb_intel_sdvo(connector); 1287 902 1288 903 if (iout->type != INTEL_OUTPUT_SDVO) 1289 904 continue; 1290 905 1291 906 sdvo = iout->dev_priv; 1292 907 1293 - if (sdvo->output_device == SDVOB && sdvoB) 908 + if (sdvo->sdvo_reg == SDVOB && sdvoB) 1294 909 return connector; 1295 910 1296 - if (sdvo->output_device == SDVOC && !sdvoB) 911 + if (sdvo->sdvo_reg == SDVOC && !sdvoB) 1297 912 return connector; 1298 913 1299 914 } ··· 1232 993 { 1233 994 u8 response[2]; 1234 995 u8 status; 1235 - struct psb_intel_output *psb_intel_output; 996 + struct psb_intel_sdvo *psb_intel_sdvo; 997 + DRM_DEBUG_KMS("\n"); 1236 998 1237 999 if (!connector) 1238 1000 return 0; 1239 1001 1240 - psb_intel_output = to_psb_intel_output(connector); 1002 + psb_intel_sdvo = to_psb_intel_sdvo(connector); 1241 1003 1242 - psb_intel_sdvo_write_cmd(psb_intel_output, 1243 - SDVO_CMD_GET_HOT_PLUG_SUPPORT, 1244 - NULL, 1245 - 0); 1246 - status = psb_intel_sdvo_read_response(psb_intel_output, 1247 - &response, 1248 - 2); 1249 - 1250 - if (response[0] != 0) 1251 - return 1; 1252 - 1253 - return 0; 1004 + return psb_intel_sdvo_get_value(psb_intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, 1005 + &response, 2) && response[0]; 1254 1006 } 1255 1007 1256 1008 void psb_intel_sdvo_set_hotplug(struct drm_connector *connector, int on) 1257 1009 { 1258 1010 u8 response[2]; 1259 1011 u8 status; 1260 - struct psb_intel_output *psb_intel_output = 1261 - to_psb_intel_output(connector); 1012 + struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(connector); 1262 1013 1263 - psb_intel_sdvo_write_cmd(psb_intel_output, 1264 - SDVO_CMD_GET_ACTIVE_HOT_PLUG, 1265 - NULL, 1266 - 0); 1267 - psb_intel_sdvo_read_response(psb_intel_output, &response, 2); 1014 + psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); 1015 + psb_intel_sdvo_read_response(psb_intel_sdvo, &response, 2); 1268 1016 1269 1017 if (on) { 1270 - psb_intel_sdvo_write_cmd(psb_intel_output, 1271 - SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 1272 - 0); 1273 - status = psb_intel_sdvo_read_response(psb_intel_output, 1274 - &response, 1275 - 2); 1018 + psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0); 1019 + status = psb_intel_sdvo_read_response(psb_intel_sdvo, &response, 2); 1276 1020 1277 - psb_intel_sdvo_write_cmd(psb_intel_output, 1278 - SDVO_CMD_SET_ACTIVE_HOT_PLUG, 1279 - &response, 2); 1021 + psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); 1280 1022 } else { 1281 1023 response[0] = 0; 1282 1024 response[1] = 0; 1283 - psb_intel_sdvo_write_cmd(psb_intel_output, 1284 - SDVO_CMD_SET_ACTIVE_HOT_PLUG, 1285 - &response, 2); 1025 + psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2); 1286 1026 } 1287 1027 1288 - psb_intel_sdvo_write_cmd(psb_intel_output, 1289 - SDVO_CMD_GET_ACTIVE_HOT_PLUG, 1290 - NULL, 1291 - 0); 1292 - psb_intel_sdvo_read_response(psb_intel_output, &response, 2); 1028 + psb_intel_sdvo_write_cmd(psb_intel_sdvo, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0); 1029 + psb_intel_sdvo_read_response(psb_intel_sdvo, &response, 2); 1030 + } 1031 + #endif 1032 + 1033 + static bool 1034 + psb_intel_sdvo_multifunc_encoder(struct psb_intel_sdvo *psb_intel_sdvo) 1035 + { 1036 + /* Is there more than one type of output? */ 1037 + int caps = psb_intel_sdvo->caps.output_flags & 0xf; 1038 + return caps & -caps; 1293 1039 } 1294 1040 1295 - static enum drm_connector_status psb_intel_sdvo_detect(struct drm_connector 1296 - *connector, bool force) 1041 + static struct edid * 1042 + psb_intel_sdvo_get_edid(struct drm_connector *connector) 1297 1043 { 1298 - u8 response[2]; 1299 - u8 status; 1300 - struct psb_intel_output *psb_intel_output = 1301 - to_psb_intel_output(connector); 1044 + struct psb_intel_sdvo *sdvo = intel_attached_sdvo(connector); 1045 + return drm_get_edid(connector, &sdvo->ddc); 1046 + } 1302 1047 1303 - psb_intel_sdvo_write_cmd(psb_intel_output, 1304 - SDVO_CMD_GET_ATTACHED_DISPLAYS, 1305 - NULL, 1306 - 0); 1307 - status = psb_intel_sdvo_read_response(psb_intel_output, &response, 2); 1048 + /* Mac mini hack -- use the same DDC as the analog connector */ 1049 + static struct edid * 1050 + psb_intel_sdvo_get_analog_edid(struct drm_connector *connector) 1051 + { 1052 + struct drm_psb_private *dev_priv = connector->dev->dev_private; 1308 1053 1309 - DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]); 1310 - if ((response[0] != 0) || (response[1] != 0)) 1311 - return connector_status_connected; 1312 - else 1054 + return drm_get_edid(connector, 1055 + &dev_priv->gmbus[dev_priv->crt_ddc_pin].adapter); 1056 + return NULL; 1057 + } 1058 + 1059 + enum drm_connector_status 1060 + psb_intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) 1061 + { 1062 + struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector); 1063 + enum drm_connector_status status; 1064 + struct edid *edid; 1065 + 1066 + edid = psb_intel_sdvo_get_edid(connector); 1067 + 1068 + if (edid == NULL && psb_intel_sdvo_multifunc_encoder(psb_intel_sdvo)) { 1069 + u8 ddc, saved_ddc = psb_intel_sdvo->ddc_bus; 1070 + 1071 + /* 1072 + * Don't use the 1 as the argument of DDC bus switch to get 1073 + * the EDID. It is used for SDVO SPD ROM. 1074 + */ 1075 + for (ddc = psb_intel_sdvo->ddc_bus >> 1; ddc > 1; ddc >>= 1) { 1076 + psb_intel_sdvo->ddc_bus = ddc; 1077 + edid = psb_intel_sdvo_get_edid(connector); 1078 + if (edid) 1079 + break; 1080 + } 1081 + /* 1082 + * If we found the EDID on the other bus, 1083 + * assume that is the correct DDC bus. 1084 + */ 1085 + if (edid == NULL) 1086 + psb_intel_sdvo->ddc_bus = saved_ddc; 1087 + } 1088 + 1089 + /* 1090 + * When there is no edid and no monitor is connected with VGA 1091 + * port, try to use the CRT ddc to read the EDID for DVI-connector. 1092 + */ 1093 + if (edid == NULL) 1094 + edid = psb_intel_sdvo_get_analog_edid(connector); 1095 + 1096 + status = connector_status_unknown; 1097 + if (edid != NULL) { 1098 + /* DDC bus is shared, match EDID to connector type */ 1099 + if (edid->input & DRM_EDID_INPUT_DIGITAL) { 1100 + status = connector_status_connected; 1101 + if (psb_intel_sdvo->is_hdmi) { 1102 + psb_intel_sdvo->has_hdmi_monitor = drm_detect_hdmi_monitor(edid); 1103 + psb_intel_sdvo->has_hdmi_audio = drm_detect_monitor_audio(edid); 1104 + } 1105 + } else 1106 + status = connector_status_disconnected; 1107 + connector->display_info.raw_edid = NULL; 1108 + kfree(edid); 1109 + } 1110 + 1111 + if (status == connector_status_connected) { 1112 + struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector); 1113 + if (psb_intel_sdvo_connector->force_audio) 1114 + psb_intel_sdvo->has_hdmi_audio = psb_intel_sdvo_connector->force_audio > 0; 1115 + } 1116 + 1117 + return status; 1118 + } 1119 + 1120 + static enum drm_connector_status 1121 + psb_intel_sdvo_detect(struct drm_connector *connector, bool force) 1122 + { 1123 + uint16_t response; 1124 + struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector); 1125 + struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector); 1126 + enum drm_connector_status ret; 1127 + 1128 + if (!psb_intel_sdvo_write_cmd(psb_intel_sdvo, 1129 + SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0)) 1130 + return connector_status_unknown; 1131 + 1132 + /* add 30ms delay when the output type might be TV */ 1133 + if (psb_intel_sdvo->caps.output_flags & 1134 + (SDVO_OUTPUT_SVID0 | SDVO_OUTPUT_CVBS0)) 1135 + mdelay(30); 1136 + 1137 + if (!psb_intel_sdvo_read_response(psb_intel_sdvo, &response, 2)) 1138 + return connector_status_unknown; 1139 + 1140 + DRM_DEBUG_KMS("SDVO response %d %d [%x]\n", 1141 + response & 0xff, response >> 8, 1142 + psb_intel_sdvo_connector->output_flag); 1143 + 1144 + if (response == 0) 1313 1145 return connector_status_disconnected; 1146 + 1147 + psb_intel_sdvo->attached_output = response; 1148 + 1149 + psb_intel_sdvo->has_hdmi_monitor = false; 1150 + psb_intel_sdvo->has_hdmi_audio = false; 1151 + 1152 + if ((psb_intel_sdvo_connector->output_flag & response) == 0) 1153 + ret = connector_status_disconnected; 1154 + else if (IS_TMDS(psb_intel_sdvo_connector)) 1155 + ret = psb_intel_sdvo_hdmi_sink_detect(connector); 1156 + else { 1157 + struct edid *edid; 1158 + 1159 + /* if we have an edid check it matches the connection */ 1160 + edid = psb_intel_sdvo_get_edid(connector); 1161 + if (edid == NULL) 1162 + edid = psb_intel_sdvo_get_analog_edid(connector); 1163 + if (edid != NULL) { 1164 + if (edid->input & DRM_EDID_INPUT_DIGITAL) 1165 + ret = connector_status_disconnected; 1166 + else 1167 + ret = connector_status_connected; 1168 + connector->display_info.raw_edid = NULL; 1169 + kfree(edid); 1170 + } else 1171 + ret = connector_status_connected; 1172 + } 1173 + 1174 + /* May update encoder flag for like clock for SDVO TV, etc.*/ 1175 + if (ret == connector_status_connected) { 1176 + psb_intel_sdvo->is_tv = false; 1177 + psb_intel_sdvo->is_lvds = false; 1178 + psb_intel_sdvo->base.needs_tv_clock = false; 1179 + 1180 + if (response & SDVO_TV_MASK) { 1181 + psb_intel_sdvo->is_tv = true; 1182 + psb_intel_sdvo->base.needs_tv_clock = true; 1183 + } 1184 + if (response & SDVO_LVDS_MASK) 1185 + psb_intel_sdvo->is_lvds = psb_intel_sdvo->sdvo_lvds_fixed_mode != NULL; 1186 + } 1187 + 1188 + return ret; 1189 + } 1190 + 1191 + static void psb_intel_sdvo_get_ddc_modes(struct drm_connector *connector) 1192 + { 1193 + struct edid *edid; 1194 + 1195 + /* set the bus switch and get the modes */ 1196 + edid = psb_intel_sdvo_get_edid(connector); 1197 + 1198 + /* 1199 + * Mac mini hack. On this device, the DVI-I connector shares one DDC 1200 + * link between analog and digital outputs. So, if the regular SDVO 1201 + * DDC fails, check to see if the analog output is disconnected, in 1202 + * which case we'll look there for the digital DDC data. 1203 + */ 1204 + if (edid == NULL) 1205 + edid = psb_intel_sdvo_get_analog_edid(connector); 1206 + 1207 + if (edid != NULL) { 1208 + struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector); 1209 + bool monitor_is_digital = !!(edid->input & DRM_EDID_INPUT_DIGITAL); 1210 + bool connector_is_digital = !!IS_TMDS(psb_intel_sdvo_connector); 1211 + 1212 + if (connector_is_digital == monitor_is_digital) { 1213 + drm_mode_connector_update_edid_property(connector, edid); 1214 + drm_add_edid_modes(connector, edid); 1215 + } 1216 + 1217 + connector->display_info.raw_edid = NULL; 1218 + kfree(edid); 1219 + } 1220 + } 1221 + 1222 + /* 1223 + * Set of SDVO TV modes. 1224 + * Note! This is in reply order (see loop in get_tv_modes). 1225 + * XXX: all 60Hz refresh? 1226 + */ 1227 + static const struct drm_display_mode sdvo_tv_modes[] = { 1228 + { DRM_MODE("320x200", DRM_MODE_TYPE_DRIVER, 5815, 320, 321, 384, 1229 + 416, 0, 200, 201, 232, 233, 0, 1230 + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1231 + { DRM_MODE("320x240", DRM_MODE_TYPE_DRIVER, 6814, 320, 321, 384, 1232 + 416, 0, 240, 241, 272, 273, 0, 1233 + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1234 + { DRM_MODE("400x300", DRM_MODE_TYPE_DRIVER, 9910, 400, 401, 464, 1235 + 496, 0, 300, 301, 332, 333, 0, 1236 + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1237 + { DRM_MODE("640x350", DRM_MODE_TYPE_DRIVER, 16913, 640, 641, 704, 1238 + 736, 0, 350, 351, 382, 383, 0, 1239 + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1240 + { DRM_MODE("640x400", DRM_MODE_TYPE_DRIVER, 19121, 640, 641, 704, 1241 + 736, 0, 400, 401, 432, 433, 0, 1242 + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1243 + { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 22654, 640, 641, 704, 1244 + 736, 0, 480, 481, 512, 513, 0, 1245 + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1246 + { DRM_MODE("704x480", DRM_MODE_TYPE_DRIVER, 24624, 704, 705, 768, 1247 + 800, 0, 480, 481, 512, 513, 0, 1248 + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1249 + { DRM_MODE("704x576", DRM_MODE_TYPE_DRIVER, 29232, 704, 705, 768, 1250 + 800, 0, 576, 577, 608, 609, 0, 1251 + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1252 + { DRM_MODE("720x350", DRM_MODE_TYPE_DRIVER, 18751, 720, 721, 784, 1253 + 816, 0, 350, 351, 382, 383, 0, 1254 + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1255 + { DRM_MODE("720x400", DRM_MODE_TYPE_DRIVER, 21199, 720, 721, 784, 1256 + 816, 0, 400, 401, 432, 433, 0, 1257 + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1258 + { DRM_MODE("720x480", DRM_MODE_TYPE_DRIVER, 25116, 720, 721, 784, 1259 + 816, 0, 480, 481, 512, 513, 0, 1260 + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1261 + { DRM_MODE("720x540", DRM_MODE_TYPE_DRIVER, 28054, 720, 721, 784, 1262 + 816, 0, 540, 541, 572, 573, 0, 1263 + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1264 + { DRM_MODE("720x576", DRM_MODE_TYPE_DRIVER, 29816, 720, 721, 784, 1265 + 816, 0, 576, 577, 608, 609, 0, 1266 + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1267 + { DRM_MODE("768x576", DRM_MODE_TYPE_DRIVER, 31570, 768, 769, 832, 1268 + 864, 0, 576, 577, 608, 609, 0, 1269 + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1270 + { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 34030, 800, 801, 864, 1271 + 896, 0, 600, 601, 632, 633, 0, 1272 + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1273 + { DRM_MODE("832x624", DRM_MODE_TYPE_DRIVER, 36581, 832, 833, 896, 1274 + 928, 0, 624, 625, 656, 657, 0, 1275 + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1276 + { DRM_MODE("920x766", DRM_MODE_TYPE_DRIVER, 48707, 920, 921, 984, 1277 + 1016, 0, 766, 767, 798, 799, 0, 1278 + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1279 + { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 53827, 1024, 1025, 1088, 1280 + 1120, 0, 768, 769, 800, 801, 0, 1281 + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1282 + { DRM_MODE("1280x1024", DRM_MODE_TYPE_DRIVER, 87265, 1280, 1281, 1344, 1283 + 1376, 0, 1024, 1025, 1056, 1057, 0, 1284 + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, 1285 + }; 1286 + 1287 + static void psb_intel_sdvo_get_tv_modes(struct drm_connector *connector) 1288 + { 1289 + struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector); 1290 + struct psb_intel_sdvo_sdtv_resolution_request tv_res; 1291 + uint32_t reply = 0, format_map = 0; 1292 + int i; 1293 + 1294 + /* Read the list of supported input resolutions for the selected TV 1295 + * format. 1296 + */ 1297 + format_map = 1 << psb_intel_sdvo->tv_format_index; 1298 + memcpy(&tv_res, &format_map, 1299 + min(sizeof(format_map), sizeof(struct psb_intel_sdvo_sdtv_resolution_request))); 1300 + 1301 + if (!psb_intel_sdvo_set_target_output(psb_intel_sdvo, psb_intel_sdvo->attached_output)) 1302 + return; 1303 + 1304 + BUILD_BUG_ON(sizeof(tv_res) != 3); 1305 + if (!psb_intel_sdvo_write_cmd(psb_intel_sdvo, 1306 + SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT, 1307 + &tv_res, sizeof(tv_res))) 1308 + return; 1309 + if (!psb_intel_sdvo_read_response(psb_intel_sdvo, &reply, 3)) 1310 + return; 1311 + 1312 + for (i = 0; i < ARRAY_SIZE(sdvo_tv_modes); i++) 1313 + if (reply & (1 << i)) { 1314 + struct drm_display_mode *nmode; 1315 + nmode = drm_mode_duplicate(connector->dev, 1316 + &sdvo_tv_modes[i]); 1317 + if (nmode) 1318 + drm_mode_probed_add(connector, nmode); 1319 + } 1320 + } 1321 + 1322 + static void psb_intel_sdvo_get_lvds_modes(struct drm_connector *connector) 1323 + { 1324 + struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector); 1325 + struct drm_psb_private *dev_priv = connector->dev->dev_private; 1326 + struct drm_display_mode *newmode; 1327 + 1328 + /* 1329 + * Attempt to get the mode list from DDC. 1330 + * Assume that the preferred modes are 1331 + * arranged in priority order. 1332 + */ 1333 + psb_intel_ddc_get_modes(connector, psb_intel_sdvo->i2c); 1334 + if (list_empty(&connector->probed_modes) == false) 1335 + goto end; 1336 + 1337 + /* Fetch modes from VBT */ 1338 + if (dev_priv->sdvo_lvds_vbt_mode != NULL) { 1339 + newmode = drm_mode_duplicate(connector->dev, 1340 + dev_priv->sdvo_lvds_vbt_mode); 1341 + if (newmode != NULL) { 1342 + /* Guarantee the mode is preferred */ 1343 + newmode->type = (DRM_MODE_TYPE_PREFERRED | 1344 + DRM_MODE_TYPE_DRIVER); 1345 + drm_mode_probed_add(connector, newmode); 1346 + } 1347 + } 1348 + 1349 + end: 1350 + list_for_each_entry(newmode, &connector->probed_modes, head) { 1351 + if (newmode->type & DRM_MODE_TYPE_PREFERRED) { 1352 + psb_intel_sdvo->sdvo_lvds_fixed_mode = 1353 + drm_mode_duplicate(connector->dev, newmode); 1354 + 1355 + drm_mode_set_crtcinfo(psb_intel_sdvo->sdvo_lvds_fixed_mode, 1356 + 0); 1357 + 1358 + psb_intel_sdvo->is_lvds = true; 1359 + break; 1360 + } 1361 + } 1362 + 1314 1363 } 1315 1364 1316 1365 static int psb_intel_sdvo_get_modes(struct drm_connector *connector) 1317 1366 { 1318 - struct psb_intel_output *psb_intel_output = 1319 - to_psb_intel_output(connector); 1367 + struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector); 1320 1368 1321 - /* set the bus switch and get the modes */ 1322 - psb_intel_sdvo_set_control_bus_switch(psb_intel_output, 1323 - SDVO_CONTROL_BUS_DDC2); 1324 - psb_intel_ddc_get_modes(psb_intel_output); 1369 + if (IS_TV(psb_intel_sdvo_connector)) 1370 + psb_intel_sdvo_get_tv_modes(connector); 1371 + else if (IS_LVDS(psb_intel_sdvo_connector)) 1372 + psb_intel_sdvo_get_lvds_modes(connector); 1373 + else 1374 + psb_intel_sdvo_get_ddc_modes(connector); 1325 1375 1326 - if (list_empty(&connector->probed_modes)) 1327 - return 0; 1328 - return 1; 1376 + return !list_empty(&connector->probed_modes); 1377 + } 1378 + 1379 + static void 1380 + psb_intel_sdvo_destroy_enhance_property(struct drm_connector *connector) 1381 + { 1382 + struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector); 1383 + struct drm_device *dev = connector->dev; 1384 + 1385 + if (psb_intel_sdvo_connector->left) 1386 + drm_property_destroy(dev, psb_intel_sdvo_connector->left); 1387 + if (psb_intel_sdvo_connector->right) 1388 + drm_property_destroy(dev, psb_intel_sdvo_connector->right); 1389 + if (psb_intel_sdvo_connector->top) 1390 + drm_property_destroy(dev, psb_intel_sdvo_connector->top); 1391 + if (psb_intel_sdvo_connector->bottom) 1392 + drm_property_destroy(dev, psb_intel_sdvo_connector->bottom); 1393 + if (psb_intel_sdvo_connector->hpos) 1394 + drm_property_destroy(dev, psb_intel_sdvo_connector->hpos); 1395 + if (psb_intel_sdvo_connector->vpos) 1396 + drm_property_destroy(dev, psb_intel_sdvo_connector->vpos); 1397 + if (psb_intel_sdvo_connector->saturation) 1398 + drm_property_destroy(dev, psb_intel_sdvo_connector->saturation); 1399 + if (psb_intel_sdvo_connector->contrast) 1400 + drm_property_destroy(dev, psb_intel_sdvo_connector->contrast); 1401 + if (psb_intel_sdvo_connector->hue) 1402 + drm_property_destroy(dev, psb_intel_sdvo_connector->hue); 1403 + if (psb_intel_sdvo_connector->sharpness) 1404 + drm_property_destroy(dev, psb_intel_sdvo_connector->sharpness); 1405 + if (psb_intel_sdvo_connector->flicker_filter) 1406 + drm_property_destroy(dev, psb_intel_sdvo_connector->flicker_filter); 1407 + if (psb_intel_sdvo_connector->flicker_filter_2d) 1408 + drm_property_destroy(dev, psb_intel_sdvo_connector->flicker_filter_2d); 1409 + if (psb_intel_sdvo_connector->flicker_filter_adaptive) 1410 + drm_property_destroy(dev, psb_intel_sdvo_connector->flicker_filter_adaptive); 1411 + if (psb_intel_sdvo_connector->tv_luma_filter) 1412 + drm_property_destroy(dev, psb_intel_sdvo_connector->tv_luma_filter); 1413 + if (psb_intel_sdvo_connector->tv_chroma_filter) 1414 + drm_property_destroy(dev, psb_intel_sdvo_connector->tv_chroma_filter); 1415 + if (psb_intel_sdvo_connector->dot_crawl) 1416 + drm_property_destroy(dev, psb_intel_sdvo_connector->dot_crawl); 1417 + if (psb_intel_sdvo_connector->brightness) 1418 + drm_property_destroy(dev, psb_intel_sdvo_connector->brightness); 1329 1419 } 1330 1420 1331 1421 static void psb_intel_sdvo_destroy(struct drm_connector *connector) 1332 1422 { 1333 - struct psb_intel_output *psb_intel_output = 1334 - to_psb_intel_output(connector); 1423 + struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector); 1335 1424 1336 - if (psb_intel_output->i2c_bus) 1337 - psb_intel_i2c_destroy(psb_intel_output->i2c_bus); 1425 + if (psb_intel_sdvo_connector->tv_format) 1426 + drm_property_destroy(connector->dev, 1427 + psb_intel_sdvo_connector->tv_format); 1428 + 1429 + psb_intel_sdvo_destroy_enhance_property(connector); 1338 1430 drm_sysfs_connector_remove(connector); 1339 1431 drm_connector_cleanup(connector); 1340 - kfree(psb_intel_output); 1432 + kfree(connector); 1433 + } 1434 + 1435 + static bool psb_intel_sdvo_detect_hdmi_audio(struct drm_connector *connector) 1436 + { 1437 + struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector); 1438 + struct edid *edid; 1439 + bool has_audio = false; 1440 + 1441 + if (!psb_intel_sdvo->is_hdmi) 1442 + return false; 1443 + 1444 + edid = psb_intel_sdvo_get_edid(connector); 1445 + if (edid != NULL && edid->input & DRM_EDID_INPUT_DIGITAL) 1446 + has_audio = drm_detect_monitor_audio(edid); 1447 + 1448 + return has_audio; 1449 + } 1450 + 1451 + static int 1452 + psb_intel_sdvo_set_property(struct drm_connector *connector, 1453 + struct drm_property *property, 1454 + uint64_t val) 1455 + { 1456 + struct psb_intel_sdvo *psb_intel_sdvo = intel_attached_sdvo(connector); 1457 + struct psb_intel_sdvo_connector *psb_intel_sdvo_connector = to_psb_intel_sdvo_connector(connector); 1458 + struct drm_psb_private *dev_priv = connector->dev->dev_private; 1459 + uint16_t temp_value; 1460 + uint8_t cmd; 1461 + int ret; 1462 + 1463 + ret = drm_connector_property_set_value(connector, property, val); 1464 + if (ret) 1465 + return ret; 1466 + 1467 + if (property == dev_priv->force_audio_property) { 1468 + int i = val; 1469 + bool has_audio; 1470 + 1471 + if (i == psb_intel_sdvo_connector->force_audio) 1472 + return 0; 1473 + 1474 + psb_intel_sdvo_connector->force_audio = i; 1475 + 1476 + if (i == 0) 1477 + has_audio = psb_intel_sdvo_detect_hdmi_audio(connector); 1478 + else 1479 + has_audio = i > 0; 1480 + 1481 + if (has_audio == psb_intel_sdvo->has_hdmi_audio) 1482 + return 0; 1483 + 1484 + psb_intel_sdvo->has_hdmi_audio = has_audio; 1485 + goto done; 1486 + } 1487 + 1488 + if (property == dev_priv->broadcast_rgb_property) { 1489 + if (val == !!psb_intel_sdvo->color_range) 1490 + return 0; 1491 + 1492 + psb_intel_sdvo->color_range = val ? SDVO_COLOR_RANGE_16_235 : 0; 1493 + goto done; 1494 + } 1495 + 1496 + #define CHECK_PROPERTY(name, NAME) \ 1497 + if (psb_intel_sdvo_connector->name == property) { \ 1498 + if (psb_intel_sdvo_connector->cur_##name == temp_value) return 0; \ 1499 + if (psb_intel_sdvo_connector->max_##name < temp_value) return -EINVAL; \ 1500 + cmd = SDVO_CMD_SET_##NAME; \ 1501 + psb_intel_sdvo_connector->cur_##name = temp_value; \ 1502 + goto set_value; \ 1503 + } 1504 + 1505 + if (property == psb_intel_sdvo_connector->tv_format) { 1506 + if (val >= TV_FORMAT_NUM) 1507 + return -EINVAL; 1508 + 1509 + if (psb_intel_sdvo->tv_format_index == 1510 + psb_intel_sdvo_connector->tv_format_supported[val]) 1511 + return 0; 1512 + 1513 + psb_intel_sdvo->tv_format_index = psb_intel_sdvo_connector->tv_format_supported[val]; 1514 + goto done; 1515 + } else if (IS_TV_OR_LVDS(psb_intel_sdvo_connector)) { 1516 + temp_value = val; 1517 + if (psb_intel_sdvo_connector->left == property) { 1518 + drm_connector_property_set_value(connector, 1519 + psb_intel_sdvo_connector->right, val); 1520 + if (psb_intel_sdvo_connector->left_margin == temp_value) 1521 + return 0; 1522 + 1523 + psb_intel_sdvo_connector->left_margin = temp_value; 1524 + psb_intel_sdvo_connector->right_margin = temp_value; 1525 + temp_value = psb_intel_sdvo_connector->max_hscan - 1526 + psb_intel_sdvo_connector->left_margin; 1527 + cmd = SDVO_CMD_SET_OVERSCAN_H; 1528 + goto set_value; 1529 + } else if (psb_intel_sdvo_connector->right == property) { 1530 + drm_connector_property_set_value(connector, 1531 + psb_intel_sdvo_connector->left, val); 1532 + if (psb_intel_sdvo_connector->right_margin == temp_value) 1533 + return 0; 1534 + 1535 + psb_intel_sdvo_connector->left_margin = temp_value; 1536 + psb_intel_sdvo_connector->right_margin = temp_value; 1537 + temp_value = psb_intel_sdvo_connector->max_hscan - 1538 + psb_intel_sdvo_connector->left_margin; 1539 + cmd = SDVO_CMD_SET_OVERSCAN_H; 1540 + goto set_value; 1541 + } else if (psb_intel_sdvo_connector->top == property) { 1542 + drm_connector_property_set_value(connector, 1543 + psb_intel_sdvo_connector->bottom, val); 1544 + if (psb_intel_sdvo_connector->top_margin == temp_value) 1545 + return 0; 1546 + 1547 + psb_intel_sdvo_connector->top_margin = temp_value; 1548 + psb_intel_sdvo_connector->bottom_margin = temp_value; 1549 + temp_value = psb_intel_sdvo_connector->max_vscan - 1550 + psb_intel_sdvo_connector->top_margin; 1551 + cmd = SDVO_CMD_SET_OVERSCAN_V; 1552 + goto set_value; 1553 + } else if (psb_intel_sdvo_connector->bottom == property) { 1554 + drm_connector_property_set_value(connector, 1555 + psb_intel_sdvo_connector->top, val); 1556 + if (psb_intel_sdvo_connector->bottom_margin == temp_value) 1557 + return 0; 1558 + 1559 + psb_intel_sdvo_connector->top_margin = temp_value; 1560 + psb_intel_sdvo_connector->bottom_margin = temp_value; 1561 + temp_value = psb_intel_sdvo_connector->max_vscan - 1562 + psb_intel_sdvo_connector->top_margin; 1563 + cmd = SDVO_CMD_SET_OVERSCAN_V; 1564 + goto set_value; 1565 + } 1566 + CHECK_PROPERTY(hpos, HPOS) 1567 + CHECK_PROPERTY(vpos, VPOS) 1568 + CHECK_PROPERTY(saturation, SATURATION) 1569 + CHECK_PROPERTY(contrast, CONTRAST) 1570 + CHECK_PROPERTY(hue, HUE) 1571 + CHECK_PROPERTY(brightness, BRIGHTNESS) 1572 + CHECK_PROPERTY(sharpness, SHARPNESS) 1573 + CHECK_PROPERTY(flicker_filter, FLICKER_FILTER) 1574 + CHECK_PROPERTY(flicker_filter_2d, FLICKER_FILTER_2D) 1575 + CHECK_PROPERTY(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE) 1576 + CHECK_PROPERTY(tv_chroma_filter, TV_CHROMA_FILTER) 1577 + CHECK_PROPERTY(tv_luma_filter, TV_LUMA_FILTER) 1578 + CHECK_PROPERTY(dot_crawl, DOT_CRAWL) 1579 + } 1580 + 1581 + return -EINVAL; /* unknown property */ 1582 + 1583 + set_value: 1584 + if (!psb_intel_sdvo_set_value(psb_intel_sdvo, cmd, &temp_value, 2)) 1585 + return -EIO; 1586 + 1587 + 1588 + done: 1589 + if (psb_intel_sdvo->base.base.crtc) { 1590 + struct drm_crtc *crtc = psb_intel_sdvo->base.base.crtc; 1591 + drm_crtc_helper_set_mode(crtc, &crtc->mode, crtc->x, 1592 + crtc->y, crtc->fb); 1593 + } 1594 + 1595 + return 0; 1596 + #undef CHECK_PROPERTY 1341 1597 } 1342 1598 1343 1599 static const struct drm_encoder_helper_funcs psb_intel_sdvo_helper_funcs = { ··· 1845 1111 1846 1112 static const struct drm_connector_funcs psb_intel_sdvo_connector_funcs = { 1847 1113 .dpms = drm_helper_connector_dpms, 1848 - .save = psb_intel_sdvo_save, 1849 - .restore = psb_intel_sdvo_restore, 1850 1114 .detect = psb_intel_sdvo_detect, 1851 1115 .fill_modes = drm_helper_probe_single_connector_modes, 1116 + .set_property = psb_intel_sdvo_set_property, 1852 1117 .destroy = psb_intel_sdvo_destroy, 1853 1118 }; 1854 1119 1855 - static const struct drm_connector_helper_funcs 1856 - psb_intel_sdvo_connector_helper_funcs = { 1120 + static const struct drm_connector_helper_funcs psb_intel_sdvo_connector_helper_funcs = { 1857 1121 .get_modes = psb_intel_sdvo_get_modes, 1858 1122 .mode_valid = psb_intel_sdvo_mode_valid, 1859 1123 .best_encoder = psb_intel_best_encoder, 1860 1124 }; 1861 1125 1862 - void psb_intel_sdvo_enc_destroy(struct drm_encoder *encoder) 1126 + static void psb_intel_sdvo_enc_destroy(struct drm_encoder *encoder) 1863 1127 { 1864 - drm_encoder_cleanup(encoder); 1128 + struct psb_intel_sdvo *psb_intel_sdvo = to_psb_intel_sdvo(encoder); 1129 + 1130 + if (psb_intel_sdvo->sdvo_lvds_fixed_mode != NULL) 1131 + drm_mode_destroy(encoder->dev, 1132 + psb_intel_sdvo->sdvo_lvds_fixed_mode); 1133 + 1134 + i2c_del_adapter(&psb_intel_sdvo->ddc); 1135 + psb_intel_encoder_destroy(encoder); 1865 1136 } 1866 1137 1867 1138 static const struct drm_encoder_funcs psb_intel_sdvo_enc_funcs = { 1868 1139 .destroy = psb_intel_sdvo_enc_destroy, 1869 1140 }; 1870 1141 1871 - 1872 - void psb_intel_sdvo_init(struct drm_device *dev, int output_device) 1142 + static void 1143 + psb_intel_sdvo_guess_ddc_bus(struct psb_intel_sdvo *sdvo) 1873 1144 { 1874 - struct drm_connector *connector; 1875 - struct psb_intel_output *psb_intel_output; 1876 - struct psb_intel_sdvo_priv *sdvo_priv; 1877 - struct psb_intel_i2c_chan *i2cbus = NULL; 1878 - int connector_type; 1879 - u8 ch[0x40]; 1880 - int i; 1881 - int encoder_type, output_id; 1145 + uint16_t mask = 0; 1146 + unsigned int num_bits; 1882 1147 1883 - psb_intel_output = 1884 - kcalloc(sizeof(struct psb_intel_output) + 1885 - sizeof(struct psb_intel_sdvo_priv), 1, GFP_KERNEL); 1886 - if (!psb_intel_output) 1887 - return; 1888 - 1889 - connector = &psb_intel_output->base; 1890 - 1891 - drm_connector_init(dev, connector, &psb_intel_sdvo_connector_funcs, 1892 - DRM_MODE_CONNECTOR_Unknown); 1893 - drm_connector_helper_add(connector, 1894 - &psb_intel_sdvo_connector_helper_funcs); 1895 - sdvo_priv = (struct psb_intel_sdvo_priv *) (psb_intel_output + 1); 1896 - psb_intel_output->type = INTEL_OUTPUT_SDVO; 1897 - 1898 - connector->interlace_allowed = 0; 1899 - connector->doublescan_allowed = 0; 1900 - 1901 - /* setup the DDC bus. */ 1902 - if (output_device == SDVOB) 1903 - i2cbus = 1904 - psb_intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); 1905 - else 1906 - i2cbus = 1907 - psb_intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); 1908 - 1909 - if (!i2cbus) 1910 - goto err_connector; 1911 - 1912 - sdvo_priv->i2c_bus = i2cbus; 1913 - 1914 - if (output_device == SDVOB) { 1915 - output_id = 1; 1916 - sdvo_priv->by_input_wiring = SDVOB_IN0; 1917 - sdvo_priv->i2c_bus->slave_addr = 0x38; 1918 - } else { 1919 - output_id = 2; 1920 - sdvo_priv->i2c_bus->slave_addr = 0x39; 1148 + /* Make a mask of outputs less than or equal to our own priority in the 1149 + * list. 1150 + */ 1151 + switch (sdvo->controlled_output) { 1152 + case SDVO_OUTPUT_LVDS1: 1153 + mask |= SDVO_OUTPUT_LVDS1; 1154 + case SDVO_OUTPUT_LVDS0: 1155 + mask |= SDVO_OUTPUT_LVDS0; 1156 + case SDVO_OUTPUT_TMDS1: 1157 + mask |= SDVO_OUTPUT_TMDS1; 1158 + case SDVO_OUTPUT_TMDS0: 1159 + mask |= SDVO_OUTPUT_TMDS0; 1160 + case SDVO_OUTPUT_RGB1: 1161 + mask |= SDVO_OUTPUT_RGB1; 1162 + case SDVO_OUTPUT_RGB0: 1163 + mask |= SDVO_OUTPUT_RGB0; 1164 + break; 1921 1165 } 1922 1166 1923 - sdvo_priv->output_device = output_device; 1924 - psb_intel_output->i2c_bus = i2cbus; 1925 - psb_intel_output->dev_priv = sdvo_priv; 1167 + /* Count bits to find what number we are in the priority list. */ 1168 + mask &= sdvo->caps.output_flags; 1169 + num_bits = hweight16(mask); 1170 + /* If more than 3 outputs, default to DDC bus 3 for now. */ 1171 + if (num_bits > 3) 1172 + num_bits = 3; 1926 1173 1174 + /* Corresponds to SDVO_CONTROL_BUS_DDCx */ 1175 + sdvo->ddc_bus = 1 << num_bits; 1176 + } 1177 + 1178 + /** 1179 + * Choose the appropriate DDC bus for control bus switch command for this 1180 + * SDVO output based on the controlled output. 1181 + * 1182 + * DDC bus number assignment is in a priority order of RGB outputs, then TMDS 1183 + * outputs, then LVDS outputs. 1184 + */ 1185 + static void 1186 + psb_intel_sdvo_select_ddc_bus(struct drm_psb_private *dev_priv, 1187 + struct psb_intel_sdvo *sdvo, u32 reg) 1188 + { 1189 + struct sdvo_device_mapping *mapping; 1190 + 1191 + if (IS_SDVOB(reg)) 1192 + mapping = &(dev_priv->sdvo_mappings[0]); 1193 + else 1194 + mapping = &(dev_priv->sdvo_mappings[1]); 1195 + 1196 + if (mapping->initialized) 1197 + sdvo->ddc_bus = 1 << ((mapping->ddc_pin & 0xf0) >> 4); 1198 + else 1199 + psb_intel_sdvo_guess_ddc_bus(sdvo); 1200 + } 1201 + 1202 + static void 1203 + psb_intel_sdvo_select_i2c_bus(struct drm_psb_private *dev_priv, 1204 + struct psb_intel_sdvo *sdvo, u32 reg) 1205 + { 1206 + struct sdvo_device_mapping *mapping; 1207 + u8 pin, speed; 1208 + 1209 + if (IS_SDVOB(reg)) 1210 + mapping = &dev_priv->sdvo_mappings[0]; 1211 + else 1212 + mapping = &dev_priv->sdvo_mappings[1]; 1213 + 1214 + pin = GMBUS_PORT_DPB; 1215 + speed = GMBUS_RATE_1MHZ >> 8; 1216 + if (mapping->initialized) { 1217 + pin = mapping->i2c_pin; 1218 + speed = mapping->i2c_speed; 1219 + } 1220 + 1221 + if (pin < GMBUS_NUM_PORTS) { 1222 + sdvo->i2c = &dev_priv->gmbus[pin].adapter; 1223 + gma_intel_gmbus_set_speed(sdvo->i2c, speed); 1224 + gma_intel_gmbus_force_bit(sdvo->i2c, true); 1225 + } else 1226 + sdvo->i2c = &dev_priv->gmbus[GMBUS_PORT_DPB].adapter; 1227 + } 1228 + 1229 + static bool 1230 + psb_intel_sdvo_is_hdmi_connector(struct psb_intel_sdvo *psb_intel_sdvo, int device) 1231 + { 1232 + return psb_intel_sdvo_check_supp_encode(psb_intel_sdvo); 1233 + } 1234 + 1235 + static u8 1236 + psb_intel_sdvo_get_slave_addr(struct drm_device *dev, int sdvo_reg) 1237 + { 1238 + struct drm_psb_private *dev_priv = dev->dev_private; 1239 + struct sdvo_device_mapping *my_mapping, *other_mapping; 1240 + 1241 + if (IS_SDVOB(sdvo_reg)) { 1242 + my_mapping = &dev_priv->sdvo_mappings[0]; 1243 + other_mapping = &dev_priv->sdvo_mappings[1]; 1244 + } else { 1245 + my_mapping = &dev_priv->sdvo_mappings[1]; 1246 + other_mapping = &dev_priv->sdvo_mappings[0]; 1247 + } 1248 + 1249 + /* If the BIOS described our SDVO device, take advantage of it. */ 1250 + if (my_mapping->slave_addr) 1251 + return my_mapping->slave_addr; 1252 + 1253 + /* If the BIOS only described a different SDVO device, use the 1254 + * address that it isn't using. 1255 + */ 1256 + if (other_mapping->slave_addr) { 1257 + if (other_mapping->slave_addr == 0x70) 1258 + return 0x72; 1259 + else 1260 + return 0x70; 1261 + } 1262 + 1263 + /* No SDVO device info is found for another DVO port, 1264 + * so use mapping assumption we had before BIOS parsing. 1265 + */ 1266 + if (IS_SDVOB(sdvo_reg)) 1267 + return 0x70; 1268 + else 1269 + return 0x72; 1270 + } 1271 + 1272 + static void 1273 + psb_intel_sdvo_connector_init(struct psb_intel_sdvo_connector *connector, 1274 + struct psb_intel_sdvo *encoder) 1275 + { 1276 + drm_connector_init(encoder->base.base.dev, 1277 + &connector->base.base, 1278 + &psb_intel_sdvo_connector_funcs, 1279 + connector->base.base.connector_type); 1280 + 1281 + drm_connector_helper_add(&connector->base.base, 1282 + &psb_intel_sdvo_connector_helper_funcs); 1283 + 1284 + connector->base.base.interlace_allowed = 0; 1285 + connector->base.base.doublescan_allowed = 0; 1286 + connector->base.base.display_info.subpixel_order = SubPixelHorizontalRGB; 1287 + 1288 + psb_intel_connector_attach_encoder(&connector->base, &encoder->base); 1289 + drm_sysfs_connector_add(&connector->base.base); 1290 + } 1291 + 1292 + static void 1293 + psb_intel_sdvo_add_hdmi_properties(struct psb_intel_sdvo_connector *connector) 1294 + { 1295 + /* FIXME: We don't support HDMI at the moment 1296 + struct drm_device *dev = connector->base.base.dev; 1297 + 1298 + intel_attach_force_audio_property(&connector->base.base); 1299 + if (INTEL_INFO(dev)->gen >= 4 && IS_MOBILE(dev)) 1300 + intel_attach_broadcast_rgb_property(&connector->base.base); 1301 + */ 1302 + } 1303 + 1304 + static bool 1305 + psb_intel_sdvo_dvi_init(struct psb_intel_sdvo *psb_intel_sdvo, int device) 1306 + { 1307 + struct drm_encoder *encoder = &psb_intel_sdvo->base.base; 1308 + struct drm_connector *connector; 1309 + struct psb_intel_connector *intel_connector; 1310 + struct psb_intel_sdvo_connector *psb_intel_sdvo_connector; 1311 + 1312 + psb_intel_sdvo_connector = kzalloc(sizeof(struct psb_intel_sdvo_connector), GFP_KERNEL); 1313 + if (!psb_intel_sdvo_connector) 1314 + return false; 1315 + 1316 + if (device == 0) { 1317 + psb_intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS0; 1318 + psb_intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS0; 1319 + } else if (device == 1) { 1320 + psb_intel_sdvo->controlled_output |= SDVO_OUTPUT_TMDS1; 1321 + psb_intel_sdvo_connector->output_flag = SDVO_OUTPUT_TMDS1; 1322 + } 1323 + 1324 + intel_connector = &psb_intel_sdvo_connector->base; 1325 + connector = &intel_connector->base; 1326 + // connector->polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT; 1327 + encoder->encoder_type = DRM_MODE_ENCODER_TMDS; 1328 + connector->connector_type = DRM_MODE_CONNECTOR_DVID; 1329 + 1330 + if (psb_intel_sdvo_is_hdmi_connector(psb_intel_sdvo, device)) { 1331 + connector->connector_type = DRM_MODE_CONNECTOR_HDMIA; 1332 + psb_intel_sdvo->is_hdmi = true; 1333 + } 1334 + psb_intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | 1335 + (1 << INTEL_ANALOG_CLONE_BIT)); 1336 + 1337 + psb_intel_sdvo_connector_init(psb_intel_sdvo_connector, psb_intel_sdvo); 1338 + if (psb_intel_sdvo->is_hdmi) 1339 + psb_intel_sdvo_add_hdmi_properties(psb_intel_sdvo_connector); 1340 + 1341 + return true; 1342 + } 1343 + 1344 + static bool 1345 + psb_intel_sdvo_tv_init(struct psb_intel_sdvo *psb_intel_sdvo, int type) 1346 + { 1347 + struct drm_encoder *encoder = &psb_intel_sdvo->base.base; 1348 + struct drm_connector *connector; 1349 + struct psb_intel_connector *intel_connector; 1350 + struct psb_intel_sdvo_connector *psb_intel_sdvo_connector; 1351 + 1352 + psb_intel_sdvo_connector = kzalloc(sizeof(struct psb_intel_sdvo_connector), GFP_KERNEL); 1353 + if (!psb_intel_sdvo_connector) 1354 + return false; 1355 + 1356 + intel_connector = &psb_intel_sdvo_connector->base; 1357 + connector = &intel_connector->base; 1358 + encoder->encoder_type = DRM_MODE_ENCODER_TVDAC; 1359 + connector->connector_type = DRM_MODE_CONNECTOR_SVIDEO; 1360 + 1361 + psb_intel_sdvo->controlled_output |= type; 1362 + psb_intel_sdvo_connector->output_flag = type; 1363 + 1364 + psb_intel_sdvo->is_tv = true; 1365 + psb_intel_sdvo->base.needs_tv_clock = true; 1366 + psb_intel_sdvo->base.clone_mask = 1 << INTEL_SDVO_TV_CLONE_BIT; 1367 + 1368 + psb_intel_sdvo_connector_init(psb_intel_sdvo_connector, psb_intel_sdvo); 1369 + 1370 + if (!psb_intel_sdvo_tv_create_property(psb_intel_sdvo, psb_intel_sdvo_connector, type)) 1371 + goto err; 1372 + 1373 + if (!psb_intel_sdvo_create_enhance_property(psb_intel_sdvo, psb_intel_sdvo_connector)) 1374 + goto err; 1375 + 1376 + return true; 1377 + 1378 + err: 1379 + psb_intel_sdvo_destroy(connector); 1380 + return false; 1381 + } 1382 + 1383 + static bool 1384 + psb_intel_sdvo_analog_init(struct psb_intel_sdvo *psb_intel_sdvo, int device) 1385 + { 1386 + struct drm_encoder *encoder = &psb_intel_sdvo->base.base; 1387 + struct drm_connector *connector; 1388 + struct psb_intel_connector *intel_connector; 1389 + struct psb_intel_sdvo_connector *psb_intel_sdvo_connector; 1390 + 1391 + psb_intel_sdvo_connector = kzalloc(sizeof(struct psb_intel_sdvo_connector), GFP_KERNEL); 1392 + if (!psb_intel_sdvo_connector) 1393 + return false; 1394 + 1395 + intel_connector = &psb_intel_sdvo_connector->base; 1396 + connector = &intel_connector->base; 1397 + connector->polled = DRM_CONNECTOR_POLL_CONNECT; 1398 + encoder->encoder_type = DRM_MODE_ENCODER_DAC; 1399 + connector->connector_type = DRM_MODE_CONNECTOR_VGA; 1400 + 1401 + if (device == 0) { 1402 + psb_intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB0; 1403 + psb_intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB0; 1404 + } else if (device == 1) { 1405 + psb_intel_sdvo->controlled_output |= SDVO_OUTPUT_RGB1; 1406 + psb_intel_sdvo_connector->output_flag = SDVO_OUTPUT_RGB1; 1407 + } 1408 + 1409 + psb_intel_sdvo->base.clone_mask = ((1 << INTEL_SDVO_NON_TV_CLONE_BIT) | 1410 + (1 << INTEL_ANALOG_CLONE_BIT)); 1411 + 1412 + psb_intel_sdvo_connector_init(psb_intel_sdvo_connector, 1413 + psb_intel_sdvo); 1414 + return true; 1415 + } 1416 + 1417 + static bool 1418 + psb_intel_sdvo_lvds_init(struct psb_intel_sdvo *psb_intel_sdvo, int device) 1419 + { 1420 + struct drm_encoder *encoder = &psb_intel_sdvo->base.base; 1421 + struct drm_connector *connector; 1422 + struct psb_intel_connector *intel_connector; 1423 + struct psb_intel_sdvo_connector *psb_intel_sdvo_connector; 1424 + 1425 + psb_intel_sdvo_connector = kzalloc(sizeof(struct psb_intel_sdvo_connector), GFP_KERNEL); 1426 + if (!psb_intel_sdvo_connector) 1427 + return false; 1428 + 1429 + intel_connector = &psb_intel_sdvo_connector->base; 1430 + connector = &intel_connector->base; 1431 + encoder->encoder_type = DRM_MODE_ENCODER_LVDS; 1432 + connector->connector_type = DRM_MODE_CONNECTOR_LVDS; 1433 + 1434 + if (device == 0) { 1435 + psb_intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS0; 1436 + psb_intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS0; 1437 + } else if (device == 1) { 1438 + psb_intel_sdvo->controlled_output |= SDVO_OUTPUT_LVDS1; 1439 + psb_intel_sdvo_connector->output_flag = SDVO_OUTPUT_LVDS1; 1440 + } 1441 + 1442 + psb_intel_sdvo->base.clone_mask = ((1 << INTEL_ANALOG_CLONE_BIT) | 1443 + (1 << INTEL_SDVO_LVDS_CLONE_BIT)); 1444 + 1445 + psb_intel_sdvo_connector_init(psb_intel_sdvo_connector, psb_intel_sdvo); 1446 + if (!psb_intel_sdvo_create_enhance_property(psb_intel_sdvo, psb_intel_sdvo_connector)) 1447 + goto err; 1448 + 1449 + return true; 1450 + 1451 + err: 1452 + psb_intel_sdvo_destroy(connector); 1453 + return false; 1454 + } 1455 + 1456 + static bool 1457 + psb_intel_sdvo_output_setup(struct psb_intel_sdvo *psb_intel_sdvo, uint16_t flags) 1458 + { 1459 + psb_intel_sdvo->is_tv = false; 1460 + psb_intel_sdvo->base.needs_tv_clock = false; 1461 + psb_intel_sdvo->is_lvds = false; 1462 + 1463 + /* SDVO requires XXX1 function may not exist unless it has XXX0 function.*/ 1464 + 1465 + if (flags & SDVO_OUTPUT_TMDS0) 1466 + if (!psb_intel_sdvo_dvi_init(psb_intel_sdvo, 0)) 1467 + return false; 1468 + 1469 + if ((flags & SDVO_TMDS_MASK) == SDVO_TMDS_MASK) 1470 + if (!psb_intel_sdvo_dvi_init(psb_intel_sdvo, 1)) 1471 + return false; 1472 + 1473 + /* TV has no XXX1 function block */ 1474 + if (flags & SDVO_OUTPUT_SVID0) 1475 + if (!psb_intel_sdvo_tv_init(psb_intel_sdvo, SDVO_OUTPUT_SVID0)) 1476 + return false; 1477 + 1478 + if (flags & SDVO_OUTPUT_CVBS0) 1479 + if (!psb_intel_sdvo_tv_init(psb_intel_sdvo, SDVO_OUTPUT_CVBS0)) 1480 + return false; 1481 + 1482 + if (flags & SDVO_OUTPUT_RGB0) 1483 + if (!psb_intel_sdvo_analog_init(psb_intel_sdvo, 0)) 1484 + return false; 1485 + 1486 + if ((flags & SDVO_RGB_MASK) == SDVO_RGB_MASK) 1487 + if (!psb_intel_sdvo_analog_init(psb_intel_sdvo, 1)) 1488 + return false; 1489 + 1490 + if (flags & SDVO_OUTPUT_LVDS0) 1491 + if (!psb_intel_sdvo_lvds_init(psb_intel_sdvo, 0)) 1492 + return false; 1493 + 1494 + if ((flags & SDVO_LVDS_MASK) == SDVO_LVDS_MASK) 1495 + if (!psb_intel_sdvo_lvds_init(psb_intel_sdvo, 1)) 1496 + return false; 1497 + 1498 + if ((flags & SDVO_OUTPUT_MASK) == 0) { 1499 + unsigned char bytes[2]; 1500 + 1501 + psb_intel_sdvo->controlled_output = 0; 1502 + memcpy(bytes, &psb_intel_sdvo->caps.output_flags, 2); 1503 + DRM_DEBUG_KMS("%s: Unknown SDVO output type (0x%02x%02x)\n", 1504 + SDVO_NAME(psb_intel_sdvo), 1505 + bytes[0], bytes[1]); 1506 + return false; 1507 + } 1508 + psb_intel_sdvo->base.crtc_mask = (1 << 0) | (1 << 1); 1509 + 1510 + return true; 1511 + } 1512 + 1513 + static bool psb_intel_sdvo_tv_create_property(struct psb_intel_sdvo *psb_intel_sdvo, 1514 + struct psb_intel_sdvo_connector *psb_intel_sdvo_connector, 1515 + int type) 1516 + { 1517 + struct drm_device *dev = psb_intel_sdvo->base.base.dev; 1518 + struct psb_intel_sdvo_tv_format format; 1519 + uint32_t format_map, i; 1520 + 1521 + if (!psb_intel_sdvo_set_target_output(psb_intel_sdvo, type)) 1522 + return false; 1523 + 1524 + BUILD_BUG_ON(sizeof(format) != 6); 1525 + if (!psb_intel_sdvo_get_value(psb_intel_sdvo, 1526 + SDVO_CMD_GET_SUPPORTED_TV_FORMATS, 1527 + &format, sizeof(format))) 1528 + return false; 1529 + 1530 + memcpy(&format_map, &format, min(sizeof(format_map), sizeof(format))); 1531 + 1532 + if (format_map == 0) 1533 + return false; 1534 + 1535 + psb_intel_sdvo_connector->format_supported_num = 0; 1536 + for (i = 0 ; i < TV_FORMAT_NUM; i++) 1537 + if (format_map & (1 << i)) 1538 + psb_intel_sdvo_connector->tv_format_supported[psb_intel_sdvo_connector->format_supported_num++] = i; 1539 + 1540 + 1541 + psb_intel_sdvo_connector->tv_format = 1542 + drm_property_create(dev, DRM_MODE_PROP_ENUM, 1543 + "mode", psb_intel_sdvo_connector->format_supported_num); 1544 + if (!psb_intel_sdvo_connector->tv_format) 1545 + return false; 1546 + 1547 + for (i = 0; i < psb_intel_sdvo_connector->format_supported_num; i++) 1548 + drm_property_add_enum( 1549 + psb_intel_sdvo_connector->tv_format, i, 1550 + i, tv_format_names[psb_intel_sdvo_connector->tv_format_supported[i]]); 1551 + 1552 + psb_intel_sdvo->tv_format_index = psb_intel_sdvo_connector->tv_format_supported[0]; 1553 + drm_connector_attach_property(&psb_intel_sdvo_connector->base.base, 1554 + psb_intel_sdvo_connector->tv_format, 0); 1555 + return true; 1556 + 1557 + } 1558 + 1559 + #define ENHANCEMENT(name, NAME) do { \ 1560 + if (enhancements.name) { \ 1561 + if (!psb_intel_sdvo_get_value(psb_intel_sdvo, SDVO_CMD_GET_MAX_##NAME, &data_value, 4) || \ 1562 + !psb_intel_sdvo_get_value(psb_intel_sdvo, SDVO_CMD_GET_##NAME, &response, 2)) \ 1563 + return false; \ 1564 + psb_intel_sdvo_connector->max_##name = data_value[0]; \ 1565 + psb_intel_sdvo_connector->cur_##name = response; \ 1566 + psb_intel_sdvo_connector->name = \ 1567 + drm_property_create(dev, DRM_MODE_PROP_RANGE, #name, 2); \ 1568 + if (!psb_intel_sdvo_connector->name) return false; \ 1569 + psb_intel_sdvo_connector->name->values[0] = 0; \ 1570 + psb_intel_sdvo_connector->name->values[1] = data_value[0]; \ 1571 + drm_connector_attach_property(connector, \ 1572 + psb_intel_sdvo_connector->name, \ 1573 + psb_intel_sdvo_connector->cur_##name); \ 1574 + DRM_DEBUG_KMS(#name ": max %d, default %d, current %d\n", \ 1575 + data_value[0], data_value[1], response); \ 1576 + } \ 1577 + } while(0) 1578 + 1579 + static bool 1580 + psb_intel_sdvo_create_enhance_property_tv(struct psb_intel_sdvo *psb_intel_sdvo, 1581 + struct psb_intel_sdvo_connector *psb_intel_sdvo_connector, 1582 + struct psb_intel_sdvo_enhancements_reply enhancements) 1583 + { 1584 + struct drm_device *dev = psb_intel_sdvo->base.base.dev; 1585 + struct drm_connector *connector = &psb_intel_sdvo_connector->base.base; 1586 + uint16_t response, data_value[2]; 1587 + 1588 + /* when horizontal overscan is supported, Add the left/right property */ 1589 + if (enhancements.overscan_h) { 1590 + if (!psb_intel_sdvo_get_value(psb_intel_sdvo, 1591 + SDVO_CMD_GET_MAX_OVERSCAN_H, 1592 + &data_value, 4)) 1593 + return false; 1594 + 1595 + if (!psb_intel_sdvo_get_value(psb_intel_sdvo, 1596 + SDVO_CMD_GET_OVERSCAN_H, 1597 + &response, 2)) 1598 + return false; 1599 + 1600 + psb_intel_sdvo_connector->max_hscan = data_value[0]; 1601 + psb_intel_sdvo_connector->left_margin = data_value[0] - response; 1602 + psb_intel_sdvo_connector->right_margin = psb_intel_sdvo_connector->left_margin; 1603 + psb_intel_sdvo_connector->left = 1604 + drm_property_create(dev, DRM_MODE_PROP_RANGE, 1605 + "left_margin", 2); 1606 + if (!psb_intel_sdvo_connector->left) 1607 + return false; 1608 + 1609 + psb_intel_sdvo_connector->left->values[0] = 0; 1610 + psb_intel_sdvo_connector->left->values[1] = data_value[0]; 1611 + drm_connector_attach_property(connector, 1612 + psb_intel_sdvo_connector->left, 1613 + psb_intel_sdvo_connector->left_margin); 1614 + 1615 + psb_intel_sdvo_connector->right = 1616 + drm_property_create(dev, DRM_MODE_PROP_RANGE, 1617 + "right_margin", 2); 1618 + if (!psb_intel_sdvo_connector->right) 1619 + return false; 1620 + 1621 + psb_intel_sdvo_connector->right->values[0] = 0; 1622 + psb_intel_sdvo_connector->right->values[1] = data_value[0]; 1623 + drm_connector_attach_property(connector, 1624 + psb_intel_sdvo_connector->right, 1625 + psb_intel_sdvo_connector->right_margin); 1626 + DRM_DEBUG_KMS("h_overscan: max %d, " 1627 + "default %d, current %d\n", 1628 + data_value[0], data_value[1], response); 1629 + } 1630 + 1631 + if (enhancements.overscan_v) { 1632 + if (!psb_intel_sdvo_get_value(psb_intel_sdvo, 1633 + SDVO_CMD_GET_MAX_OVERSCAN_V, 1634 + &data_value, 4)) 1635 + return false; 1636 + 1637 + if (!psb_intel_sdvo_get_value(psb_intel_sdvo, 1638 + SDVO_CMD_GET_OVERSCAN_V, 1639 + &response, 2)) 1640 + return false; 1641 + 1642 + psb_intel_sdvo_connector->max_vscan = data_value[0]; 1643 + psb_intel_sdvo_connector->top_margin = data_value[0] - response; 1644 + psb_intel_sdvo_connector->bottom_margin = psb_intel_sdvo_connector->top_margin; 1645 + psb_intel_sdvo_connector->top = 1646 + drm_property_create(dev, DRM_MODE_PROP_RANGE, 1647 + "top_margin", 2); 1648 + if (!psb_intel_sdvo_connector->top) 1649 + return false; 1650 + 1651 + psb_intel_sdvo_connector->top->values[0] = 0; 1652 + psb_intel_sdvo_connector->top->values[1] = data_value[0]; 1653 + drm_connector_attach_property(connector, 1654 + psb_intel_sdvo_connector->top, 1655 + psb_intel_sdvo_connector->top_margin); 1656 + 1657 + psb_intel_sdvo_connector->bottom = 1658 + drm_property_create(dev, DRM_MODE_PROP_RANGE, 1659 + "bottom_margin", 2); 1660 + if (!psb_intel_sdvo_connector->bottom) 1661 + return false; 1662 + 1663 + psb_intel_sdvo_connector->bottom->values[0] = 0; 1664 + psb_intel_sdvo_connector->bottom->values[1] = data_value[0]; 1665 + drm_connector_attach_property(connector, 1666 + psb_intel_sdvo_connector->bottom, 1667 + psb_intel_sdvo_connector->bottom_margin); 1668 + DRM_DEBUG_KMS("v_overscan: max %d, " 1669 + "default %d, current %d\n", 1670 + data_value[0], data_value[1], response); 1671 + } 1672 + 1673 + ENHANCEMENT(hpos, HPOS); 1674 + ENHANCEMENT(vpos, VPOS); 1675 + ENHANCEMENT(saturation, SATURATION); 1676 + ENHANCEMENT(contrast, CONTRAST); 1677 + ENHANCEMENT(hue, HUE); 1678 + ENHANCEMENT(sharpness, SHARPNESS); 1679 + ENHANCEMENT(brightness, BRIGHTNESS); 1680 + ENHANCEMENT(flicker_filter, FLICKER_FILTER); 1681 + ENHANCEMENT(flicker_filter_adaptive, FLICKER_FILTER_ADAPTIVE); 1682 + ENHANCEMENT(flicker_filter_2d, FLICKER_FILTER_2D); 1683 + ENHANCEMENT(tv_chroma_filter, TV_CHROMA_FILTER); 1684 + ENHANCEMENT(tv_luma_filter, TV_LUMA_FILTER); 1685 + 1686 + if (enhancements.dot_crawl) { 1687 + if (!psb_intel_sdvo_get_value(psb_intel_sdvo, SDVO_CMD_GET_DOT_CRAWL, &response, 2)) 1688 + return false; 1689 + 1690 + psb_intel_sdvo_connector->max_dot_crawl = 1; 1691 + psb_intel_sdvo_connector->cur_dot_crawl = response & 0x1; 1692 + psb_intel_sdvo_connector->dot_crawl = 1693 + drm_property_create(dev, DRM_MODE_PROP_RANGE, "dot_crawl", 2); 1694 + if (!psb_intel_sdvo_connector->dot_crawl) 1695 + return false; 1696 + 1697 + psb_intel_sdvo_connector->dot_crawl->values[0] = 0; 1698 + psb_intel_sdvo_connector->dot_crawl->values[1] = 1; 1699 + drm_connector_attach_property(connector, 1700 + psb_intel_sdvo_connector->dot_crawl, 1701 + psb_intel_sdvo_connector->cur_dot_crawl); 1702 + DRM_DEBUG_KMS("dot crawl: current %d\n", response); 1703 + } 1704 + 1705 + return true; 1706 + } 1707 + 1708 + static bool 1709 + psb_intel_sdvo_create_enhance_property_lvds(struct psb_intel_sdvo *psb_intel_sdvo, 1710 + struct psb_intel_sdvo_connector *psb_intel_sdvo_connector, 1711 + struct psb_intel_sdvo_enhancements_reply enhancements) 1712 + { 1713 + struct drm_device *dev = psb_intel_sdvo->base.base.dev; 1714 + struct drm_connector *connector = &psb_intel_sdvo_connector->base.base; 1715 + uint16_t response, data_value[2]; 1716 + 1717 + ENHANCEMENT(brightness, BRIGHTNESS); 1718 + 1719 + return true; 1720 + } 1721 + #undef ENHANCEMENT 1722 + 1723 + static bool psb_intel_sdvo_create_enhance_property(struct psb_intel_sdvo *psb_intel_sdvo, 1724 + struct psb_intel_sdvo_connector *psb_intel_sdvo_connector) 1725 + { 1726 + union { 1727 + struct psb_intel_sdvo_enhancements_reply reply; 1728 + uint16_t response; 1729 + } enhancements; 1730 + 1731 + BUILD_BUG_ON(sizeof(enhancements) != 2); 1732 + 1733 + enhancements.response = 0; 1734 + psb_intel_sdvo_get_value(psb_intel_sdvo, 1735 + SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS, 1736 + &enhancements, sizeof(enhancements)); 1737 + if (enhancements.response == 0) { 1738 + DRM_DEBUG_KMS("No enhancement is supported\n"); 1739 + return true; 1740 + } 1741 + 1742 + if (IS_TV(psb_intel_sdvo_connector)) 1743 + return psb_intel_sdvo_create_enhance_property_tv(psb_intel_sdvo, psb_intel_sdvo_connector, enhancements.reply); 1744 + else if(IS_LVDS(psb_intel_sdvo_connector)) 1745 + return psb_intel_sdvo_create_enhance_property_lvds(psb_intel_sdvo, psb_intel_sdvo_connector, enhancements.reply); 1746 + else 1747 + return true; 1748 + } 1749 + 1750 + static int psb_intel_sdvo_ddc_proxy_xfer(struct i2c_adapter *adapter, 1751 + struct i2c_msg *msgs, 1752 + int num) 1753 + { 1754 + struct psb_intel_sdvo *sdvo = adapter->algo_data; 1755 + 1756 + if (!psb_intel_sdvo_set_control_bus_switch(sdvo, sdvo->ddc_bus)) 1757 + return -EIO; 1758 + 1759 + return sdvo->i2c->algo->master_xfer(sdvo->i2c, msgs, num); 1760 + } 1761 + 1762 + static u32 psb_intel_sdvo_ddc_proxy_func(struct i2c_adapter *adapter) 1763 + { 1764 + struct psb_intel_sdvo *sdvo = adapter->algo_data; 1765 + return sdvo->i2c->algo->functionality(sdvo->i2c); 1766 + } 1767 + 1768 + static const struct i2c_algorithm psb_intel_sdvo_ddc_proxy = { 1769 + .master_xfer = psb_intel_sdvo_ddc_proxy_xfer, 1770 + .functionality = psb_intel_sdvo_ddc_proxy_func 1771 + }; 1772 + 1773 + static bool 1774 + psb_intel_sdvo_init_ddc_proxy(struct psb_intel_sdvo *sdvo, 1775 + struct drm_device *dev) 1776 + { 1777 + sdvo->ddc.owner = THIS_MODULE; 1778 + sdvo->ddc.class = I2C_CLASS_DDC; 1779 + snprintf(sdvo->ddc.name, I2C_NAME_SIZE, "SDVO DDC proxy"); 1780 + sdvo->ddc.dev.parent = &dev->pdev->dev; 1781 + sdvo->ddc.algo_data = sdvo; 1782 + sdvo->ddc.algo = &psb_intel_sdvo_ddc_proxy; 1783 + 1784 + return i2c_add_adapter(&sdvo->ddc) == 0; 1785 + } 1786 + 1787 + bool psb_intel_sdvo_init(struct drm_device *dev, int sdvo_reg) 1788 + { 1789 + struct drm_psb_private *dev_priv = dev->dev_private; 1790 + struct psb_intel_encoder *psb_intel_encoder; 1791 + struct psb_intel_sdvo *psb_intel_sdvo; 1792 + int i; 1793 + 1794 + psb_intel_sdvo = kzalloc(sizeof(struct psb_intel_sdvo), GFP_KERNEL); 1795 + if (!psb_intel_sdvo) 1796 + return false; 1797 + 1798 + psb_intel_sdvo->sdvo_reg = sdvo_reg; 1799 + psb_intel_sdvo->slave_addr = psb_intel_sdvo_get_slave_addr(dev, sdvo_reg) >> 1; 1800 + psb_intel_sdvo_select_i2c_bus(dev_priv, psb_intel_sdvo, sdvo_reg); 1801 + if (!psb_intel_sdvo_init_ddc_proxy(psb_intel_sdvo, dev)) { 1802 + kfree(psb_intel_sdvo); 1803 + return false; 1804 + } 1805 + 1806 + /* encoder type will be decided later */ 1807 + psb_intel_encoder = &psb_intel_sdvo->base; 1808 + psb_intel_encoder->type = INTEL_OUTPUT_SDVO; 1809 + drm_encoder_init(dev, &psb_intel_encoder->base, &psb_intel_sdvo_enc_funcs, 0); 1927 1810 1928 1811 /* Read the regs to test if we can talk to the device */ 1929 1812 for (i = 0; i < 0x40; i++) { 1930 - if (!psb_intel_sdvo_read_byte(psb_intel_output, i, &ch[i])) { 1931 - dev_dbg(dev->dev, "No SDVO device found on SDVO%c\n", 1932 - output_device == SDVOB ? 'B' : 'C'); 1933 - goto err_i2c; 1813 + u8 byte; 1814 + 1815 + if (!psb_intel_sdvo_read_byte(psb_intel_sdvo, i, &byte)) { 1816 + DRM_DEBUG_KMS("No SDVO device found on SDVO%c\n", 1817 + IS_SDVOB(sdvo_reg) ? 'B' : 'C'); 1818 + goto err; 1934 1819 } 1935 1820 } 1936 1821 1937 - psb_intel_sdvo_get_capabilities(psb_intel_output, &sdvo_priv->caps); 1822 + if (IS_SDVOB(sdvo_reg)) 1823 + dev_priv->hotplug_supported_mask |= SDVOB_HOTPLUG_INT_STATUS; 1824 + else 1825 + dev_priv->hotplug_supported_mask |= SDVOC_HOTPLUG_INT_STATUS; 1938 1826 1939 - memset(&sdvo_priv->active_outputs, 0, 1940 - sizeof(sdvo_priv->active_outputs)); 1827 + drm_encoder_helper_add(&psb_intel_encoder->base, &psb_intel_sdvo_helper_funcs); 1941 1828 1942 - /* TODO, CVBS, SVID, YPRPB & SCART outputs. */ 1943 - if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0) { 1944 - sdvo_priv->active_outputs = SDVO_OUTPUT_RGB0; 1945 - sdvo_priv->active_device = SDVO_DEVICE_CRT; 1946 - connector->display_info.subpixel_order = 1947 - SubPixelHorizontalRGB; 1948 - encoder_type = DRM_MODE_ENCODER_DAC; 1949 - connector_type = DRM_MODE_CONNECTOR_VGA; 1950 - } else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1) { 1951 - sdvo_priv->active_outputs = SDVO_OUTPUT_RGB1; 1952 - sdvo_priv->active_outputs = SDVO_DEVICE_CRT; 1953 - connector->display_info.subpixel_order = 1954 - SubPixelHorizontalRGB; 1955 - encoder_type = DRM_MODE_ENCODER_DAC; 1956 - connector_type = DRM_MODE_CONNECTOR_VGA; 1957 - } else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0) { 1958 - sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS0; 1959 - sdvo_priv->active_device = SDVO_DEVICE_TMDS; 1960 - connector->display_info.subpixel_order = 1961 - SubPixelHorizontalRGB; 1962 - encoder_type = DRM_MODE_ENCODER_TMDS; 1963 - connector_type = DRM_MODE_CONNECTOR_DVID; 1964 - } else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS1) { 1965 - sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS1; 1966 - sdvo_priv->active_device = SDVO_DEVICE_TMDS; 1967 - connector->display_info.subpixel_order = 1968 - SubPixelHorizontalRGB; 1969 - encoder_type = DRM_MODE_ENCODER_TMDS; 1970 - connector_type = DRM_MODE_CONNECTOR_DVID; 1971 - } else { 1972 - unsigned char bytes[2]; 1829 + /* In default case sdvo lvds is false */ 1830 + if (!psb_intel_sdvo_get_capabilities(psb_intel_sdvo, &psb_intel_sdvo->caps)) 1831 + goto err; 1973 1832 1974 - memcpy(bytes, &sdvo_priv->caps.output_flags, 2); 1975 - dev_dbg(dev->dev, "%s: No active RGB or TMDS outputs (0x%02x%02x)\n", 1976 - SDVO_NAME(sdvo_priv), bytes[0], bytes[1]); 1977 - goto err_i2c; 1833 + if (psb_intel_sdvo_output_setup(psb_intel_sdvo, 1834 + psb_intel_sdvo->caps.output_flags) != true) { 1835 + DRM_DEBUG_KMS("SDVO output failed to setup on SDVO%c\n", 1836 + IS_SDVOB(sdvo_reg) ? 'B' : 'C'); 1837 + goto err; 1978 1838 } 1979 1839 1980 - drm_encoder_init(dev, &psb_intel_output->enc, &psb_intel_sdvo_enc_funcs, 1981 - encoder_type); 1982 - drm_encoder_helper_add(&psb_intel_output->enc, 1983 - &psb_intel_sdvo_helper_funcs); 1984 - connector->connector_type = connector_type; 1985 - 1986 - drm_mode_connector_attach_encoder(&psb_intel_output->base, 1987 - &psb_intel_output->enc); 1988 - drm_sysfs_connector_add(connector); 1840 + psb_intel_sdvo_select_ddc_bus(dev_priv, psb_intel_sdvo, sdvo_reg); 1989 1841 1990 1842 /* Set the input timing to the screen. Assume always input 0. */ 1991 - psb_intel_sdvo_set_target_input(psb_intel_output, true, false); 1843 + if (!psb_intel_sdvo_set_target_input(psb_intel_sdvo)) 1844 + goto err; 1992 1845 1993 - psb_intel_sdvo_get_input_pixel_clock_range(psb_intel_output, 1994 - &sdvo_priv->pixel_clock_min, 1995 - &sdvo_priv-> 1996 - pixel_clock_max); 1846 + if (!psb_intel_sdvo_get_input_pixel_clock_range(psb_intel_sdvo, 1847 + &psb_intel_sdvo->pixel_clock_min, 1848 + &psb_intel_sdvo->pixel_clock_max)) 1849 + goto err; 1997 1850 1851 + DRM_DEBUG_KMS("%s device VID/DID: %02X:%02X.%02X, " 1852 + "clock range %dMHz - %dMHz, " 1853 + "input 1: %c, input 2: %c, " 1854 + "output 1: %c, output 2: %c\n", 1855 + SDVO_NAME(psb_intel_sdvo), 1856 + psb_intel_sdvo->caps.vendor_id, psb_intel_sdvo->caps.device_id, 1857 + psb_intel_sdvo->caps.device_rev_id, 1858 + psb_intel_sdvo->pixel_clock_min / 1000, 1859 + psb_intel_sdvo->pixel_clock_max / 1000, 1860 + (psb_intel_sdvo->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N', 1861 + (psb_intel_sdvo->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N', 1862 + /* check currently supported outputs */ 1863 + psb_intel_sdvo->caps.output_flags & 1864 + (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N', 1865 + psb_intel_sdvo->caps.output_flags & 1866 + (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); 1867 + return true; 1998 1868 1999 - dev_dbg(dev->dev, "%s device VID/DID: %02X:%02X.%02X, " 2000 - "clock range %dMHz - %dMHz, " 2001 - "input 1: %c, input 2: %c, " 2002 - "output 1: %c, output 2: %c\n", 2003 - SDVO_NAME(sdvo_priv), 2004 - sdvo_priv->caps.vendor_id, sdvo_priv->caps.device_id, 2005 - sdvo_priv->caps.device_rev_id, 2006 - sdvo_priv->pixel_clock_min / 1000, 2007 - sdvo_priv->pixel_clock_max / 1000, 2008 - (sdvo_priv->caps.sdvo_inputs_mask & 0x1) ? 'Y' : 'N', 2009 - (sdvo_priv->caps.sdvo_inputs_mask & 0x2) ? 'Y' : 'N', 2010 - /* check currently supported outputs */ 2011 - sdvo_priv->caps.output_flags & 2012 - (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_RGB0) ? 'Y' : 'N', 2013 - sdvo_priv->caps.output_flags & 2014 - (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); 1869 + err: 1870 + drm_encoder_cleanup(&psb_intel_encoder->base); 1871 + i2c_del_adapter(&psb_intel_sdvo->ddc); 1872 + kfree(psb_intel_sdvo); 2015 1873 2016 - psb_intel_output->ddc_bus = i2cbus; 2017 - 2018 - return; 2019 - 2020 - err_i2c: 2021 - psb_intel_i2c_destroy(psb_intel_output->i2c_bus); 2022 - err_connector: 2023 - drm_connector_cleanup(connector); 2024 - kfree(psb_intel_output); 2025 - 2026 - return; 1874 + return false; 2027 1875 }
+484 -99
drivers/gpu/drm/gma500/psb_intel_sdvo_regs.h
··· 1 1 /* 2 - * SDVO command definitions and structures. 2 + * Copyright ? 2006-2007 Intel Corporation 3 3 * 4 - * Copyright (c) 2008, Intel Corporation 4 + * Permission is hereby granted, free of charge, to any person obtaining a 5 + * copy of this software and associated documentation files (the "Software"), 6 + * to deal in the Software without restriction, including without limitation 7 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 + * and/or sell copies of the Software, and to permit persons to whom the 9 + * Software is furnished to do so, subject to the following conditions: 5 10 * 6 - * This program is free software; you can redistribute it and/or modify it 7 - * under the terms and conditions of the GNU General Public License, 8 - * version 2, as published by the Free Software Foundation. 11 + * The above copyright notice and this permission notice (including the next 12 + * paragraph) shall be included in all copies or substantial portions of the 13 + * Software. 9 14 * 10 - * This program is distributed in the hope it will be useful, but WITHOUT 11 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 13 - * more details. 14 - * 15 - * You should have received a copy of the GNU General Public License along with 16 - * this program; if not, write to the Free Software Foundation, Inc., 17 - * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. 15 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 + * DEALINGS IN THE SOFTWARE. 18 22 * 19 23 * Authors: 20 24 * Eric Anholt <eric@anholt.net> 25 + */ 26 + 27 + /** 28 + * @file SDVO command definitions and structures. 21 29 */ 22 30 23 31 #define SDVO_OUTPUT_FIRST (0) ··· 46 38 #define SDVO_OUTPUT_LAST (14) 47 39 48 40 struct psb_intel_sdvo_caps { 49 - u8 vendor_id; 50 - u8 device_id; 51 - u8 device_rev_id; 52 - u8 sdvo_version_major; 53 - u8 sdvo_version_minor; 54 - unsigned int sdvo_inputs_mask:2; 55 - unsigned int smooth_scaling:1; 56 - unsigned int sharp_scaling:1; 57 - unsigned int up_scaling:1; 58 - unsigned int down_scaling:1; 59 - unsigned int stall_support:1; 60 - unsigned int pad:1; 61 - u16 output_flags; 62 - } __packed; 41 + u8 vendor_id; 42 + u8 device_id; 43 + u8 device_rev_id; 44 + u8 sdvo_version_major; 45 + u8 sdvo_version_minor; 46 + unsigned int sdvo_inputs_mask:2; 47 + unsigned int smooth_scaling:1; 48 + unsigned int sharp_scaling:1; 49 + unsigned int up_scaling:1; 50 + unsigned int down_scaling:1; 51 + unsigned int stall_support:1; 52 + unsigned int pad:1; 53 + u16 output_flags; 54 + } __attribute__((packed)); 63 55 64 56 /** This matches the EDID DTD structure, more or less */ 65 57 struct psb_intel_sdvo_dtd { 66 - struct { 67 - u16 clock; /**< pixel clock, in 10kHz units */ 68 - u8 h_active; /**< lower 8 bits (pixels) */ 69 - u8 h_blank; /**< lower 8 bits (pixels) */ 70 - u8 h_high; /**< upper 4 bits each h_active, h_blank */ 71 - u8 v_active; /**< lower 8 bits (lines) */ 72 - u8 v_blank; /**< lower 8 bits (lines) */ 73 - u8 v_high; /**< upper 4 bits each v_active, v_blank */ 74 - } part1; 58 + struct { 59 + u16 clock; /**< pixel clock, in 10kHz units */ 60 + u8 h_active; /**< lower 8 bits (pixels) */ 61 + u8 h_blank; /**< lower 8 bits (pixels) */ 62 + u8 h_high; /**< upper 4 bits each h_active, h_blank */ 63 + u8 v_active; /**< lower 8 bits (lines) */ 64 + u8 v_blank; /**< lower 8 bits (lines) */ 65 + u8 v_high; /**< upper 4 bits each v_active, v_blank */ 66 + } part1; 75 67 76 - struct { 77 - u8 h_sync_off; 78 - /**< lower 8 bits, from hblank start */ 79 - u8 h_sync_width;/**< lower 8 bits (pixels) */ 68 + struct { 69 + u8 h_sync_off; /**< lower 8 bits, from hblank start */ 70 + u8 h_sync_width; /**< lower 8 bits (pixels) */ 80 71 /** lower 4 bits each vsync offset, vsync width */ 81 - u8 v_sync_off_width; 72 + u8 v_sync_off_width; 82 73 /** 83 74 * 2 high bits of hsync offset, 2 high bits of hsync width, 84 75 * bits 4-5 of vsync offset, and 2 high bits of vsync width. 85 76 */ 86 - u8 sync_off_width_high; 87 - u8 dtd_flags; 88 - u8 sdvo_flags; 77 + u8 sync_off_width_high; 78 + u8 dtd_flags; 79 + u8 sdvo_flags; 89 80 /** bits 6-7 of vsync offset at bits 6-7 */ 90 - u8 v_sync_off_high; 91 - u8 reserved; 92 - } part2; 93 - } __packed; 81 + u8 v_sync_off_high; 82 + u8 reserved; 83 + } part2; 84 + } __attribute__((packed)); 94 85 95 86 struct psb_intel_sdvo_pixel_clock_range { 96 - u16 min; /**< pixel clock, in 10kHz units */ 97 - u16 max; /**< pixel clock, in 10kHz units */ 98 - } __packed; 87 + u16 min; /**< pixel clock, in 10kHz units */ 88 + u16 max; /**< pixel clock, in 10kHz units */ 89 + } __attribute__((packed)); 99 90 100 91 struct psb_intel_sdvo_preferred_input_timing_args { 101 - u16 clock; 102 - u16 width; 103 - u16 height; 104 - } __packed; 92 + u16 clock; 93 + u16 width; 94 + u16 height; 95 + u8 interlace:1; 96 + u8 scaled:1; 97 + u8 pad:6; 98 + } __attribute__((packed)); 105 99 106 100 /* I2C registers for SDVO */ 107 101 #define SDVO_I2C_ARG_0 0x07 ··· 139 129 140 130 #define SDVO_CMD_RESET 0x01 141 131 142 - /** Returns a struct psb_intel_sdvo_caps */ 132 + /** Returns a struct intel_sdvo_caps */ 143 133 #define SDVO_CMD_GET_DEVICE_CAPS 0x02 144 134 145 135 #define SDVO_CMD_GET_FIRMWARE_REV 0x86 ··· 154 144 */ 155 145 #define SDVO_CMD_GET_TRAINED_INPUTS 0x03 156 146 struct psb_intel_sdvo_get_trained_inputs_response { 157 - unsigned int input0_trained:1; 158 - unsigned int input1_trained:1; 159 - unsigned int pad:6; 160 - } __packed; 147 + unsigned int input0_trained:1; 148 + unsigned int input1_trained:1; 149 + unsigned int pad:6; 150 + } __attribute__((packed)); 161 151 162 - /** Returns a struct psb_intel_sdvo_output_flags of active outputs. */ 152 + /** Returns a struct intel_sdvo_output_flags of active outputs. */ 163 153 #define SDVO_CMD_GET_ACTIVE_OUTPUTS 0x04 164 154 165 155 /** 166 156 * Sets the current set of active outputs. 167 157 * 168 - * Takes a struct psb_intel_sdvo_output_flags. 169 - * Must be preceded by a SET_IN_OUT_MAP 158 + * Takes a struct intel_sdvo_output_flags. Must be preceded by a SET_IN_OUT_MAP 170 159 * on multi-output devices. 171 160 */ 172 161 #define SDVO_CMD_SET_ACTIVE_OUTPUTS 0x05 ··· 173 164 /** 174 165 * Returns the current mapping of SDVO inputs to outputs on the device. 175 166 * 176 - * Returns two struct psb_intel_sdvo_output_flags structures. 167 + * Returns two struct intel_sdvo_output_flags structures. 177 168 */ 178 169 #define SDVO_CMD_GET_IN_OUT_MAP 0x06 170 + struct psb_intel_sdvo_in_out_map { 171 + u16 in0, in1; 172 + }; 179 173 180 174 /** 181 175 * Sets the current mapping of SDVO inputs to outputs on the device. ··· 188 176 #define SDVO_CMD_SET_IN_OUT_MAP 0x07 189 177 190 178 /** 191 - * Returns a struct psb_intel_sdvo_output_flags of attached displays. 179 + * Returns a struct intel_sdvo_output_flags of attached displays. 192 180 */ 193 181 #define SDVO_CMD_GET_ATTACHED_DISPLAYS 0x0b 194 182 195 183 /** 196 - * Returns a struct psb_intel_sdvo_ouptut_flags of displays supporting hot plugging. 184 + * Returns a struct intel_sdvo_ouptut_flags of displays supporting hot plugging. 197 185 */ 198 186 #define SDVO_CMD_GET_HOT_PLUG_SUPPORT 0x0c 199 187 200 188 /** 201 - * Takes a struct psb_intel_sdvo_output_flags. 189 + * Takes a struct intel_sdvo_output_flags. 202 190 */ 203 191 #define SDVO_CMD_SET_ACTIVE_HOT_PLUG 0x0d 204 192 205 193 /** 206 - * Returns a struct psb_intel_sdvo_output_flags of displays with hot plug 194 + * Returns a struct intel_sdvo_output_flags of displays with hot plug 207 195 * interrupts enabled. 208 196 */ 209 197 #define SDVO_CMD_GET_ACTIVE_HOT_PLUG 0x0e 210 198 211 199 #define SDVO_CMD_GET_INTERRUPT_EVENT_SOURCE 0x0f 212 - struct psb_intel_sdvo_get_interrupt_event_source_response { 213 - u16 interrupt_status; 214 - unsigned int ambient_light_interrupt:1; 215 - unsigned int pad:7; 216 - } __packed; 200 + struct intel_sdvo_get_interrupt_event_source_response { 201 + u16 interrupt_status; 202 + unsigned int ambient_light_interrupt:1; 203 + unsigned int hdmi_audio_encrypt_change:1; 204 + unsigned int pad:6; 205 + } __attribute__((packed)); 217 206 218 207 /** 219 208 * Selects which input is affected by future input commands. ··· 225 212 */ 226 213 #define SDVO_CMD_SET_TARGET_INPUT 0x10 227 214 struct psb_intel_sdvo_set_target_input_args { 228 - unsigned int target_1:1; 229 - unsigned int pad:7; 230 - } __packed; 215 + unsigned int target_1:1; 216 + unsigned int pad:7; 217 + } __attribute__((packed)); 231 218 232 219 /** 233 - * Takes a struct psb_intel_sdvo_output_flags of which outputs are targeted by 220 + * Takes a struct intel_sdvo_output_flags of which outputs are targeted by 234 221 * future output commands. 235 222 * 236 223 * Affected commands inclue SET_OUTPUT_TIMINGS_PART[12], ··· 295 282 #define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1 0x1b 296 283 #define SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2 0x1c 297 284 298 - /** Returns a struct psb_intel_sdvo_pixel_clock_range */ 285 + /** Returns a struct intel_sdvo_pixel_clock_range */ 299 286 #define SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE 0x1d 300 - /** Returns a struct psb_intel_sdvo_pixel_clock_range */ 287 + /** Returns a struct intel_sdvo_pixel_clock_range */ 301 288 #define SDVO_CMD_GET_OUTPUT_PIXEL_CLOCK_RANGE 0x1e 302 289 303 290 /** Returns a byte bitfield containing SDVO_CLOCK_RATE_MULT_* flags */ ··· 312 299 # define SDVO_CLOCK_RATE_MULT_4X (1 << 3) 313 300 314 301 #define SDVO_CMD_GET_SUPPORTED_TV_FORMATS 0x27 302 + /** 6 bytes of bit flags for TV formats shared by all TV format functions */ 303 + struct psb_intel_sdvo_tv_format { 304 + unsigned int ntsc_m:1; 305 + unsigned int ntsc_j:1; 306 + unsigned int ntsc_443:1; 307 + unsigned int pal_b:1; 308 + unsigned int pal_d:1; 309 + unsigned int pal_g:1; 310 + unsigned int pal_h:1; 311 + unsigned int pal_i:1; 312 + 313 + unsigned int pal_m:1; 314 + unsigned int pal_n:1; 315 + unsigned int pal_nc:1; 316 + unsigned int pal_60:1; 317 + unsigned int secam_b:1; 318 + unsigned int secam_d:1; 319 + unsigned int secam_g:1; 320 + unsigned int secam_k:1; 321 + 322 + unsigned int secam_k1:1; 323 + unsigned int secam_l:1; 324 + unsigned int secam_60:1; 325 + unsigned int hdtv_std_smpte_240m_1080i_59:1; 326 + unsigned int hdtv_std_smpte_240m_1080i_60:1; 327 + unsigned int hdtv_std_smpte_260m_1080i_59:1; 328 + unsigned int hdtv_std_smpte_260m_1080i_60:1; 329 + unsigned int hdtv_std_smpte_274m_1080i_50:1; 330 + 331 + unsigned int hdtv_std_smpte_274m_1080i_59:1; 332 + unsigned int hdtv_std_smpte_274m_1080i_60:1; 333 + unsigned int hdtv_std_smpte_274m_1080p_23:1; 334 + unsigned int hdtv_std_smpte_274m_1080p_24:1; 335 + unsigned int hdtv_std_smpte_274m_1080p_25:1; 336 + unsigned int hdtv_std_smpte_274m_1080p_29:1; 337 + unsigned int hdtv_std_smpte_274m_1080p_30:1; 338 + unsigned int hdtv_std_smpte_274m_1080p_50:1; 339 + 340 + unsigned int hdtv_std_smpte_274m_1080p_59:1; 341 + unsigned int hdtv_std_smpte_274m_1080p_60:1; 342 + unsigned int hdtv_std_smpte_295m_1080i_50:1; 343 + unsigned int hdtv_std_smpte_295m_1080p_50:1; 344 + unsigned int hdtv_std_smpte_296m_720p_59:1; 345 + unsigned int hdtv_std_smpte_296m_720p_60:1; 346 + unsigned int hdtv_std_smpte_296m_720p_50:1; 347 + unsigned int hdtv_std_smpte_293m_480p_59:1; 348 + 349 + unsigned int hdtv_std_smpte_170m_480i_59:1; 350 + unsigned int hdtv_std_iturbt601_576i_50:1; 351 + unsigned int hdtv_std_iturbt601_576p_50:1; 352 + unsigned int hdtv_std_eia_7702a_480i_60:1; 353 + unsigned int hdtv_std_eia_7702a_480p_60:1; 354 + unsigned int pad:3; 355 + } __attribute__((packed)); 315 356 316 357 #define SDVO_CMD_GET_TV_FORMAT 0x28 317 358 318 359 #define SDVO_CMD_SET_TV_FORMAT 0x29 319 360 361 + /** Returns the resolutiosn that can be used with the given TV format */ 362 + #define SDVO_CMD_GET_SDTV_RESOLUTION_SUPPORT 0x83 363 + struct psb_intel_sdvo_sdtv_resolution_request { 364 + unsigned int ntsc_m:1; 365 + unsigned int ntsc_j:1; 366 + unsigned int ntsc_443:1; 367 + unsigned int pal_b:1; 368 + unsigned int pal_d:1; 369 + unsigned int pal_g:1; 370 + unsigned int pal_h:1; 371 + unsigned int pal_i:1; 372 + 373 + unsigned int pal_m:1; 374 + unsigned int pal_n:1; 375 + unsigned int pal_nc:1; 376 + unsigned int pal_60:1; 377 + unsigned int secam_b:1; 378 + unsigned int secam_d:1; 379 + unsigned int secam_g:1; 380 + unsigned int secam_k:1; 381 + 382 + unsigned int secam_k1:1; 383 + unsigned int secam_l:1; 384 + unsigned int secam_60:1; 385 + unsigned int pad:5; 386 + } __attribute__((packed)); 387 + 388 + struct psb_intel_sdvo_sdtv_resolution_reply { 389 + unsigned int res_320x200:1; 390 + unsigned int res_320x240:1; 391 + unsigned int res_400x300:1; 392 + unsigned int res_640x350:1; 393 + unsigned int res_640x400:1; 394 + unsigned int res_640x480:1; 395 + unsigned int res_704x480:1; 396 + unsigned int res_704x576:1; 397 + 398 + unsigned int res_720x350:1; 399 + unsigned int res_720x400:1; 400 + unsigned int res_720x480:1; 401 + unsigned int res_720x540:1; 402 + unsigned int res_720x576:1; 403 + unsigned int res_768x576:1; 404 + unsigned int res_800x600:1; 405 + unsigned int res_832x624:1; 406 + 407 + unsigned int res_920x766:1; 408 + unsigned int res_1024x768:1; 409 + unsigned int res_1280x1024:1; 410 + unsigned int pad:5; 411 + } __attribute__((packed)); 412 + 413 + /* Get supported resolution with squire pixel aspect ratio that can be 414 + scaled for the requested HDTV format */ 415 + #define SDVO_CMD_GET_SCALED_HDTV_RESOLUTION_SUPPORT 0x85 416 + 417 + struct psb_intel_sdvo_hdtv_resolution_request { 418 + unsigned int hdtv_std_smpte_240m_1080i_59:1; 419 + unsigned int hdtv_std_smpte_240m_1080i_60:1; 420 + unsigned int hdtv_std_smpte_260m_1080i_59:1; 421 + unsigned int hdtv_std_smpte_260m_1080i_60:1; 422 + unsigned int hdtv_std_smpte_274m_1080i_50:1; 423 + unsigned int hdtv_std_smpte_274m_1080i_59:1; 424 + unsigned int hdtv_std_smpte_274m_1080i_60:1; 425 + unsigned int hdtv_std_smpte_274m_1080p_23:1; 426 + 427 + unsigned int hdtv_std_smpte_274m_1080p_24:1; 428 + unsigned int hdtv_std_smpte_274m_1080p_25:1; 429 + unsigned int hdtv_std_smpte_274m_1080p_29:1; 430 + unsigned int hdtv_std_smpte_274m_1080p_30:1; 431 + unsigned int hdtv_std_smpte_274m_1080p_50:1; 432 + unsigned int hdtv_std_smpte_274m_1080p_59:1; 433 + unsigned int hdtv_std_smpte_274m_1080p_60:1; 434 + unsigned int hdtv_std_smpte_295m_1080i_50:1; 435 + 436 + unsigned int hdtv_std_smpte_295m_1080p_50:1; 437 + unsigned int hdtv_std_smpte_296m_720p_59:1; 438 + unsigned int hdtv_std_smpte_296m_720p_60:1; 439 + unsigned int hdtv_std_smpte_296m_720p_50:1; 440 + unsigned int hdtv_std_smpte_293m_480p_59:1; 441 + unsigned int hdtv_std_smpte_170m_480i_59:1; 442 + unsigned int hdtv_std_iturbt601_576i_50:1; 443 + unsigned int hdtv_std_iturbt601_576p_50:1; 444 + 445 + unsigned int hdtv_std_eia_7702a_480i_60:1; 446 + unsigned int hdtv_std_eia_7702a_480p_60:1; 447 + unsigned int pad:6; 448 + } __attribute__((packed)); 449 + 450 + struct psb_intel_sdvo_hdtv_resolution_reply { 451 + unsigned int res_640x480:1; 452 + unsigned int res_800x600:1; 453 + unsigned int res_1024x768:1; 454 + unsigned int res_1280x960:1; 455 + unsigned int res_1400x1050:1; 456 + unsigned int res_1600x1200:1; 457 + unsigned int res_1920x1440:1; 458 + unsigned int res_2048x1536:1; 459 + 460 + unsigned int res_2560x1920:1; 461 + unsigned int res_3200x2400:1; 462 + unsigned int res_3840x2880:1; 463 + unsigned int pad1:5; 464 + 465 + unsigned int res_848x480:1; 466 + unsigned int res_1064x600:1; 467 + unsigned int res_1280x720:1; 468 + unsigned int res_1360x768:1; 469 + unsigned int res_1704x960:1; 470 + unsigned int res_1864x1050:1; 471 + unsigned int res_1920x1080:1; 472 + unsigned int res_2128x1200:1; 473 + 474 + unsigned int res_2560x1400:1; 475 + unsigned int res_2728x1536:1; 476 + unsigned int res_3408x1920:1; 477 + unsigned int res_4264x2400:1; 478 + unsigned int res_5120x2880:1; 479 + unsigned int pad2:3; 480 + 481 + unsigned int res_768x480:1; 482 + unsigned int res_960x600:1; 483 + unsigned int res_1152x720:1; 484 + unsigned int res_1124x768:1; 485 + unsigned int res_1536x960:1; 486 + unsigned int res_1680x1050:1; 487 + unsigned int res_1728x1080:1; 488 + unsigned int res_1920x1200:1; 489 + 490 + unsigned int res_2304x1440:1; 491 + unsigned int res_2456x1536:1; 492 + unsigned int res_3072x1920:1; 493 + unsigned int res_3840x2400:1; 494 + unsigned int res_4608x2880:1; 495 + unsigned int pad3:3; 496 + 497 + unsigned int res_1280x1024:1; 498 + unsigned int pad4:7; 499 + 500 + unsigned int res_1280x768:1; 501 + unsigned int pad5:7; 502 + } __attribute__((packed)); 503 + 504 + /* Get supported power state returns info for encoder and monitor, rely on 505 + last SetTargetInput and SetTargetOutput calls */ 320 506 #define SDVO_CMD_GET_SUPPORTED_POWER_STATES 0x2a 507 + /* Get power state returns info for encoder and monitor, rely on last 508 + SetTargetInput and SetTargetOutput calls */ 509 + #define SDVO_CMD_GET_POWER_STATE 0x2b 321 510 #define SDVO_CMD_GET_ENCODER_POWER_STATE 0x2b 322 511 #define SDVO_CMD_SET_ENCODER_POWER_STATE 0x2c 323 512 # define SDVO_ENCODER_STATE_ON (1 << 0) 324 513 # define SDVO_ENCODER_STATE_STANDBY (1 << 1) 325 514 # define SDVO_ENCODER_STATE_SUSPEND (1 << 2) 326 515 # define SDVO_ENCODER_STATE_OFF (1 << 3) 516 + # define SDVO_MONITOR_STATE_ON (1 << 4) 517 + # define SDVO_MONITOR_STATE_STANDBY (1 << 5) 518 + # define SDVO_MONITOR_STATE_SUSPEND (1 << 6) 519 + # define SDVO_MONITOR_STATE_OFF (1 << 7) 327 520 328 - #define SDVO_CMD_SET_TV_RESOLUTION_SUPPORT 0x93 521 + #define SDVO_CMD_GET_MAX_PANEL_POWER_SEQUENCING 0x2d 522 + #define SDVO_CMD_GET_PANEL_POWER_SEQUENCING 0x2e 523 + #define SDVO_CMD_SET_PANEL_POWER_SEQUENCING 0x2f 524 + /** 525 + * The panel power sequencing parameters are in units of milliseconds. 526 + * The high fields are bits 8:9 of the 10-bit values. 527 + */ 528 + struct psb_sdvo_panel_power_sequencing { 529 + u8 t0; 530 + u8 t1; 531 + u8 t2; 532 + u8 t3; 533 + u8 t4; 534 + 535 + unsigned int t0_high:2; 536 + unsigned int t1_high:2; 537 + unsigned int t2_high:2; 538 + unsigned int t3_high:2; 539 + 540 + unsigned int t4_high:2; 541 + unsigned int pad:6; 542 + } __attribute__((packed)); 543 + 544 + #define SDVO_CMD_GET_MAX_BACKLIGHT_LEVEL 0x30 545 + struct sdvo_max_backlight_reply { 546 + u8 max_value; 547 + u8 default_value; 548 + } __attribute__((packed)); 549 + 550 + #define SDVO_CMD_GET_BACKLIGHT_LEVEL 0x31 551 + #define SDVO_CMD_SET_BACKLIGHT_LEVEL 0x32 552 + 553 + #define SDVO_CMD_GET_AMBIENT_LIGHT 0x33 554 + struct sdvo_get_ambient_light_reply { 555 + u16 trip_low; 556 + u16 trip_high; 557 + u16 value; 558 + } __attribute__((packed)); 559 + #define SDVO_CMD_SET_AMBIENT_LIGHT 0x34 560 + struct sdvo_set_ambient_light_reply { 561 + u16 trip_low; 562 + u16 trip_high; 563 + unsigned int enable:1; 564 + unsigned int pad:7; 565 + } __attribute__((packed)); 566 + 567 + /* Set display power state */ 568 + #define SDVO_CMD_SET_DISPLAY_POWER_STATE 0x7d 569 + # define SDVO_DISPLAY_STATE_ON (1 << 0) 570 + # define SDVO_DISPLAY_STATE_STANDBY (1 << 1) 571 + # define SDVO_DISPLAY_STATE_SUSPEND (1 << 2) 572 + # define SDVO_DISPLAY_STATE_OFF (1 << 3) 573 + 574 + #define SDVO_CMD_GET_SUPPORTED_ENHANCEMENTS 0x84 575 + struct psb_intel_sdvo_enhancements_reply { 576 + unsigned int flicker_filter:1; 577 + unsigned int flicker_filter_adaptive:1; 578 + unsigned int flicker_filter_2d:1; 579 + unsigned int saturation:1; 580 + unsigned int hue:1; 581 + unsigned int brightness:1; 582 + unsigned int contrast:1; 583 + unsigned int overscan_h:1; 584 + 585 + unsigned int overscan_v:1; 586 + unsigned int hpos:1; 587 + unsigned int vpos:1; 588 + unsigned int sharpness:1; 589 + unsigned int dot_crawl:1; 590 + unsigned int dither:1; 591 + unsigned int tv_chroma_filter:1; 592 + unsigned int tv_luma_filter:1; 593 + } __attribute__((packed)); 594 + 595 + /* Picture enhancement limits below are dependent on the current TV format, 596 + * and thus need to be queried and set after it. 597 + */ 598 + #define SDVO_CMD_GET_MAX_FLICKER_FILTER 0x4d 599 + #define SDVO_CMD_GET_MAX_FLICKER_FILTER_ADAPTIVE 0x7b 600 + #define SDVO_CMD_GET_MAX_FLICKER_FILTER_2D 0x52 601 + #define SDVO_CMD_GET_MAX_SATURATION 0x55 602 + #define SDVO_CMD_GET_MAX_HUE 0x58 603 + #define SDVO_CMD_GET_MAX_BRIGHTNESS 0x5b 604 + #define SDVO_CMD_GET_MAX_CONTRAST 0x5e 605 + #define SDVO_CMD_GET_MAX_OVERSCAN_H 0x61 606 + #define SDVO_CMD_GET_MAX_OVERSCAN_V 0x64 607 + #define SDVO_CMD_GET_MAX_HPOS 0x67 608 + #define SDVO_CMD_GET_MAX_VPOS 0x6a 609 + #define SDVO_CMD_GET_MAX_SHARPNESS 0x6d 610 + #define SDVO_CMD_GET_MAX_TV_CHROMA_FILTER 0x74 611 + #define SDVO_CMD_GET_MAX_TV_LUMA_FILTER 0x77 612 + struct psb_intel_sdvo_enhancement_limits_reply { 613 + u16 max_value; 614 + u16 default_value; 615 + } __attribute__((packed)); 616 + 617 + #define SDVO_CMD_GET_LVDS_PANEL_INFORMATION 0x7f 618 + #define SDVO_CMD_SET_LVDS_PANEL_INFORMATION 0x80 619 + # define SDVO_LVDS_COLOR_DEPTH_18 (0 << 0) 620 + # define SDVO_LVDS_COLOR_DEPTH_24 (1 << 0) 621 + # define SDVO_LVDS_CONNECTOR_SPWG (0 << 2) 622 + # define SDVO_LVDS_CONNECTOR_OPENLDI (1 << 2) 623 + # define SDVO_LVDS_SINGLE_CHANNEL (0 << 4) 624 + # define SDVO_LVDS_DUAL_CHANNEL (1 << 4) 625 + 626 + #define SDVO_CMD_GET_FLICKER_FILTER 0x4e 627 + #define SDVO_CMD_SET_FLICKER_FILTER 0x4f 628 + #define SDVO_CMD_GET_FLICKER_FILTER_ADAPTIVE 0x50 629 + #define SDVO_CMD_SET_FLICKER_FILTER_ADAPTIVE 0x51 630 + #define SDVO_CMD_GET_FLICKER_FILTER_2D 0x53 631 + #define SDVO_CMD_SET_FLICKER_FILTER_2D 0x54 632 + #define SDVO_CMD_GET_SATURATION 0x56 633 + #define SDVO_CMD_SET_SATURATION 0x57 634 + #define SDVO_CMD_GET_HUE 0x59 635 + #define SDVO_CMD_SET_HUE 0x5a 636 + #define SDVO_CMD_GET_BRIGHTNESS 0x5c 637 + #define SDVO_CMD_SET_BRIGHTNESS 0x5d 638 + #define SDVO_CMD_GET_CONTRAST 0x5f 639 + #define SDVO_CMD_SET_CONTRAST 0x60 640 + #define SDVO_CMD_GET_OVERSCAN_H 0x62 641 + #define SDVO_CMD_SET_OVERSCAN_H 0x63 642 + #define SDVO_CMD_GET_OVERSCAN_V 0x65 643 + #define SDVO_CMD_SET_OVERSCAN_V 0x66 644 + #define SDVO_CMD_GET_HPOS 0x68 645 + #define SDVO_CMD_SET_HPOS 0x69 646 + #define SDVO_CMD_GET_VPOS 0x6b 647 + #define SDVO_CMD_SET_VPOS 0x6c 648 + #define SDVO_CMD_GET_SHARPNESS 0x6e 649 + #define SDVO_CMD_SET_SHARPNESS 0x6f 650 + #define SDVO_CMD_GET_TV_CHROMA_FILTER 0x75 651 + #define SDVO_CMD_SET_TV_CHROMA_FILTER 0x76 652 + #define SDVO_CMD_GET_TV_LUMA_FILTER 0x78 653 + #define SDVO_CMD_SET_TV_LUMA_FILTER 0x79 654 + struct psb_intel_sdvo_enhancements_arg { 655 + u16 value; 656 + }__attribute__((packed)); 657 + 658 + #define SDVO_CMD_GET_DOT_CRAWL 0x70 659 + #define SDVO_CMD_SET_DOT_CRAWL 0x71 660 + # define SDVO_DOT_CRAWL_ON (1 << 0) 661 + # define SDVO_DOT_CRAWL_DEFAULT_ON (1 << 1) 662 + 663 + #define SDVO_CMD_GET_DITHER 0x72 664 + #define SDVO_CMD_SET_DITHER 0x73 665 + # define SDVO_DITHER_ON (1 << 0) 666 + # define SDVO_DITHER_DEFAULT_ON (1 << 1) 329 667 330 668 #define SDVO_CMD_SET_CONTROL_BUS_SWITCH 0x7a 331 - # define SDVO_CONTROL_BUS_PROM 0x0 332 - # define SDVO_CONTROL_BUS_DDC1 0x1 333 - # define SDVO_CONTROL_BUS_DDC2 0x2 334 - # define SDVO_CONTROL_BUS_DDC3 0x3 669 + # define SDVO_CONTROL_BUS_PROM (1 << 0) 670 + # define SDVO_CONTROL_BUS_DDC1 (1 << 1) 671 + # define SDVO_CONTROL_BUS_DDC2 (1 << 2) 672 + # define SDVO_CONTROL_BUS_DDC3 (1 << 3) 335 673 336 - /* SDVO Bus & SDVO Inputs wiring details*/ 337 - /* Bit 0: Is SDVOB connected to In0 (1 = yes, 0 = no*/ 338 - /* Bit 1: Is SDVOB connected to In1 (1 = yes, 0 = no*/ 339 - /* Bit 2: Is SDVOC connected to In0 (1 = yes, 0 = no*/ 340 - /* Bit 3: Is SDVOC connected to In1 (1 = yes, 0 = no*/ 341 - #define SDVOB_IN0 0x01 342 - #define SDVOB_IN1 0x02 343 - #define SDVOC_IN0 0x04 344 - #define SDVOC_IN1 0x08 674 + /* HDMI op codes */ 675 + #define SDVO_CMD_GET_SUPP_ENCODE 0x9d 676 + #define SDVO_CMD_GET_ENCODE 0x9e 677 + #define SDVO_CMD_SET_ENCODE 0x9f 678 + #define SDVO_ENCODE_DVI 0x0 679 + #define SDVO_ENCODE_HDMI 0x1 680 + #define SDVO_CMD_SET_PIXEL_REPLI 0x8b 681 + #define SDVO_CMD_GET_PIXEL_REPLI 0x8c 682 + #define SDVO_CMD_GET_COLORIMETRY_CAP 0x8d 683 + #define SDVO_CMD_SET_COLORIMETRY 0x8e 684 + #define SDVO_COLORIMETRY_RGB256 0x0 685 + #define SDVO_COLORIMETRY_RGB220 0x1 686 + #define SDVO_COLORIMETRY_YCrCb422 0x3 687 + #define SDVO_COLORIMETRY_YCrCb444 0x4 688 + #define SDVO_CMD_GET_COLORIMETRY 0x8f 689 + #define SDVO_CMD_GET_AUDIO_ENCRYPT_PREFER 0x90 690 + #define SDVO_CMD_SET_AUDIO_STAT 0x91 691 + #define SDVO_CMD_GET_AUDIO_STAT 0x92 692 + #define SDVO_CMD_SET_HBUF_INDEX 0x93 693 + #define SDVO_CMD_GET_HBUF_INDEX 0x94 694 + #define SDVO_CMD_GET_HBUF_INFO 0x95 695 + #define SDVO_CMD_SET_HBUF_AV_SPLIT 0x96 696 + #define SDVO_CMD_GET_HBUF_AV_SPLIT 0x97 697 + #define SDVO_CMD_SET_HBUF_DATA 0x98 698 + #define SDVO_CMD_GET_HBUF_DATA 0x99 699 + #define SDVO_CMD_SET_HBUF_TXRATE 0x9a 700 + #define SDVO_CMD_GET_HBUF_TXRATE 0x9b 701 + #define SDVO_HBUF_TX_DISABLED (0 << 6) 702 + #define SDVO_HBUF_TX_ONCE (2 << 6) 703 + #define SDVO_HBUF_TX_VSYNC (3 << 6) 704 + #define SDVO_CMD_GET_AUDIO_TX_INFO 0x9c 705 + #define SDVO_NEED_TO_STALL (1 << 7) 345 706 346 - #define SDVO_DEVICE_NONE 0x00 347 - #define SDVO_DEVICE_CRT 0x01 348 - #define SDVO_DEVICE_TV 0x02 349 - #define SDVO_DEVICE_LVDS 0x04 350 - #define SDVO_DEVICE_TMDS 0x08 351 - 707 + struct psb_intel_sdvo_encode { 708 + u8 dvi_rev; 709 + u8 hdmi_rev; 710 + } __attribute__ ((packed));