1 /* 2 * Copyright (C) 2010 Francisco Jerez. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining 6 * a copy of this software and associated documentation files (the 7 * "Software"), to deal in the Software without restriction, including 8 * without limitation the rights to use, copy, modify, merge, publish, 9 * distribute, sublicense, and/or sell copies of the Software, and to 10 * permit persons to whom the Software is furnished to do so, subject to 11 * the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the 14 * next paragraph) shall be included in all copies or substantial 15 * portions of the Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 20 * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 21 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 22 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 */ 26 27 #include <linux/module.h> 28 29 #include <drm/drm_drv.h> 30 #include <drm/drm_print.h> 31 #include <drm/drm_probe_helper.h> 32 33 #include <dispnv04/i2c/encoder_i2c.h> 34 #include <dispnv04/i2c/sil164.h> 35 36 struct sil164_priv { 37 struct sil164_encoder_params config; 38 struct i2c_client *duallink_slave; 39 40 uint8_t saved_state[0x10]; 41 uint8_t saved_slave_state[0x10]; 42 }; 43 44 #define to_sil164_priv(x) \ 45 ((struct sil164_priv *)to_encoder_i2c(x)->encoder_i2c_priv) 46 47 #define sil164_dbg(client, format, ...) do { \ 48 if (drm_debug_enabled(DRM_UT_KMS)) \ 49 dev_printk(KERN_DEBUG, &client->dev, \ 50 "%s: " format, __func__, ## __VA_ARGS__); \ 51 } while (0) 52 #define sil164_info(client, format, ...) \ 53 dev_info(&client->dev, format, __VA_ARGS__) 54 #define sil164_err(client, format, ...) \ 55 dev_err(&client->dev, format, __VA_ARGS__) 56 57 #define SIL164_I2C_ADDR_MASTER 0x38 58 #define SIL164_I2C_ADDR_SLAVE 0x39 59 60 /* HW register definitions */ 61 62 #define SIL164_VENDOR_LO 0x0 63 #define SIL164_VENDOR_HI 0x1 64 #define SIL164_DEVICE_LO 0x2 65 #define SIL164_DEVICE_HI 0x3 66 #define SIL164_REVISION 0x4 67 #define SIL164_FREQ_MIN 0x6 68 #define SIL164_FREQ_MAX 0x7 69 #define SIL164_CONTROL0 0x8 70 # define SIL164_CONTROL0_POWER_ON 0x01 71 # define SIL164_CONTROL0_EDGE_RISING 0x02 72 # define SIL164_CONTROL0_INPUT_24BIT 0x04 73 # define SIL164_CONTROL0_DUAL_EDGE 0x08 74 # define SIL164_CONTROL0_HSYNC_ON 0x10 75 # define SIL164_CONTROL0_VSYNC_ON 0x20 76 #define SIL164_DETECT 0x9 77 # define SIL164_DETECT_INTR_STAT 0x01 78 # define SIL164_DETECT_HOTPLUG_STAT 0x02 79 # define SIL164_DETECT_RECEIVER_STAT 0x04 80 # define SIL164_DETECT_INTR_MODE_RECEIVER 0x00 81 # define SIL164_DETECT_INTR_MODE_HOTPLUG 0x08 82 # define SIL164_DETECT_OUT_MODE_HIGH 0x00 83 # define SIL164_DETECT_OUT_MODE_INTR 0x10 84 # define SIL164_DETECT_OUT_MODE_RECEIVER 0x20 85 # define SIL164_DETECT_OUT_MODE_HOTPLUG 0x30 86 # define SIL164_DETECT_VSWING_STAT 0x80 87 #define SIL164_CONTROL1 0xa 88 # define SIL164_CONTROL1_DESKEW_ENABLE 0x10 89 # define SIL164_CONTROL1_DESKEW_INCR_SHIFT 5 90 #define SIL164_GPIO 0xb 91 #define SIL164_CONTROL2 0xc 92 # define SIL164_CONTROL2_FILTER_ENABLE 0x01 93 # define SIL164_CONTROL2_FILTER_SETTING_SHIFT 1 94 # define SIL164_CONTROL2_DUALLINK_MASTER 0x40 95 # define SIL164_CONTROL2_SYNC_CONT 0x80 96 #define SIL164_DUALLINK 0xd 97 # define SIL164_DUALLINK_ENABLE 0x10 98 # define SIL164_DUALLINK_SKEW_SHIFT 5 99 #define SIL164_PLLZONE 0xe 100 # define SIL164_PLLZONE_STAT 0x08 101 # define SIL164_PLLZONE_FORCE_ON 0x10 102 # define SIL164_PLLZONE_FORCE_HIGH 0x20 103 104 /* HW access functions */ 105 106 static void 107 sil164_write(struct i2c_client *client, uint8_t addr, uint8_t val) 108 { 109 uint8_t buf[] = {addr, val}; 110 int ret; 111 112 ret = i2c_master_send(client, buf, ARRAY_SIZE(buf)); 113 if (ret < 0) 114 sil164_err(client, "Error %d writing to subaddress 0x%x\n", 115 ret, addr); 116 } 117 118 static uint8_t 119 sil164_read(struct i2c_client *client, uint8_t addr) 120 { 121 uint8_t val; 122 int ret; 123 124 ret = i2c_master_send(client, &addr, sizeof(addr)); 125 if (ret < 0) 126 goto fail; 127 128 ret = i2c_master_recv(client, &val, sizeof(val)); 129 if (ret < 0) 130 goto fail; 131 132 return val; 133 134 fail: 135 sil164_err(client, "Error %d reading from subaddress 0x%x\n", 136 ret, addr); 137 return 0; 138 } 139 140 static void 141 sil164_save_state(struct i2c_client *client, uint8_t *state) 142 { 143 int i; 144 145 for (i = 0x8; i <= 0xe; i++) 146 state[i] = sil164_read(client, i); 147 } 148 149 static void 150 sil164_restore_state(struct i2c_client *client, uint8_t *state) 151 { 152 int i; 153 154 for (i = 0x8; i <= 0xe; i++) 155 sil164_write(client, i, state[i]); 156 } 157 158 static void 159 sil164_set_power_state(struct i2c_client *client, bool on) 160 { 161 uint8_t control0 = sil164_read(client, SIL164_CONTROL0); 162 163 if (on) 164 control0 |= SIL164_CONTROL0_POWER_ON; 165 else 166 control0 &= ~SIL164_CONTROL0_POWER_ON; 167 168 sil164_write(client, SIL164_CONTROL0, control0); 169 } 170 171 static void 172 sil164_init_state(struct i2c_client *client, 173 struct sil164_encoder_params *config, 174 bool duallink) 175 { 176 sil164_write(client, SIL164_CONTROL0, 177 SIL164_CONTROL0_HSYNC_ON | 178 SIL164_CONTROL0_VSYNC_ON | 179 (config->input_edge ? SIL164_CONTROL0_EDGE_RISING : 0) | 180 (config->input_width ? SIL164_CONTROL0_INPUT_24BIT : 0) | 181 (config->input_dual ? SIL164_CONTROL0_DUAL_EDGE : 0)); 182 183 sil164_write(client, SIL164_DETECT, 184 SIL164_DETECT_INTR_STAT | 185 SIL164_DETECT_OUT_MODE_RECEIVER); 186 187 sil164_write(client, SIL164_CONTROL1, 188 (config->input_skew ? SIL164_CONTROL1_DESKEW_ENABLE : 0) | 189 (((config->input_skew + 4) & 0x7) 190 << SIL164_CONTROL1_DESKEW_INCR_SHIFT)); 191 192 sil164_write(client, SIL164_CONTROL2, 193 SIL164_CONTROL2_SYNC_CONT | 194 (config->pll_filter ? 0 : SIL164_CONTROL2_FILTER_ENABLE) | 195 (4 << SIL164_CONTROL2_FILTER_SETTING_SHIFT)); 196 197 sil164_write(client, SIL164_PLLZONE, 0); 198 199 if (duallink) 200 sil164_write(client, SIL164_DUALLINK, 201 SIL164_DUALLINK_ENABLE | 202 (((config->duallink_skew + 4) & 0x7) 203 << SIL164_DUALLINK_SKEW_SHIFT)); 204 else 205 sil164_write(client, SIL164_DUALLINK, 0); 206 } 207 208 /* DRM encoder functions */ 209 210 static void 211 sil164_encoder_set_config(struct drm_encoder *encoder, void *params) 212 { 213 struct sil164_priv *priv = to_sil164_priv(encoder); 214 215 priv->config = *(struct sil164_encoder_params *)params; 216 } 217 218 static void 219 sil164_encoder_dpms(struct drm_encoder *encoder, int mode) 220 { 221 struct sil164_priv *priv = to_sil164_priv(encoder); 222 bool on = (mode == DRM_MODE_DPMS_ON); 223 bool duallink = (on && encoder->crtc->mode.clock > 165000); 224 225 sil164_set_power_state(nouveau_i2c_encoder_get_client(encoder), on); 226 227 if (priv->duallink_slave) 228 sil164_set_power_state(priv->duallink_slave, duallink); 229 } 230 231 static void 232 sil164_encoder_save(struct drm_encoder *encoder) 233 { 234 struct sil164_priv *priv = to_sil164_priv(encoder); 235 236 sil164_save_state(nouveau_i2c_encoder_get_client(encoder), 237 priv->saved_state); 238 239 if (priv->duallink_slave) 240 sil164_save_state(priv->duallink_slave, 241 priv->saved_slave_state); 242 } 243 244 static void 245 sil164_encoder_restore(struct drm_encoder *encoder) 246 { 247 struct sil164_priv *priv = to_sil164_priv(encoder); 248 249 sil164_restore_state(nouveau_i2c_encoder_get_client(encoder), 250 priv->saved_state); 251 252 if (priv->duallink_slave) 253 sil164_restore_state(priv->duallink_slave, 254 priv->saved_slave_state); 255 } 256 257 static int 258 sil164_encoder_mode_valid(struct drm_encoder *encoder, 259 const struct drm_display_mode *mode) 260 { 261 struct sil164_priv *priv = to_sil164_priv(encoder); 262 263 if (mode->clock < 32000) 264 return MODE_CLOCK_LOW; 265 266 if (mode->clock > 330000 || 267 (mode->clock > 165000 && !priv->duallink_slave)) 268 return MODE_CLOCK_HIGH; 269 270 return MODE_OK; 271 } 272 273 static void 274 sil164_encoder_mode_set(struct drm_encoder *encoder, 275 struct drm_display_mode *mode, 276 struct drm_display_mode *adjusted_mode) 277 { 278 struct sil164_priv *priv = to_sil164_priv(encoder); 279 bool duallink = adjusted_mode->clock > 165000; 280 281 sil164_init_state(nouveau_i2c_encoder_get_client(encoder), 282 &priv->config, duallink); 283 284 if (priv->duallink_slave) 285 sil164_init_state(priv->duallink_slave, 286 &priv->config, duallink); 287 288 sil164_encoder_dpms(encoder, DRM_MODE_DPMS_ON); 289 } 290 291 static enum drm_connector_status 292 sil164_encoder_detect(struct drm_encoder *encoder, 293 struct drm_connector *connector) 294 { 295 struct i2c_client *client = nouveau_i2c_encoder_get_client(encoder); 296 297 if (sil164_read(client, SIL164_DETECT) & SIL164_DETECT_HOTPLUG_STAT) 298 return connector_status_connected; 299 else 300 return connector_status_disconnected; 301 } 302 303 static int 304 sil164_encoder_get_modes(struct drm_encoder *encoder, 305 struct drm_connector *connector) 306 { 307 return 0; 308 } 309 310 static int 311 sil164_encoder_create_resources(struct drm_encoder *encoder, 312 struct drm_connector *connector) 313 { 314 return 0; 315 } 316 317 static int 318 sil164_encoder_set_property(struct drm_encoder *encoder, 319 struct drm_connector *connector, 320 struct drm_property *property, 321 uint64_t val) 322 { 323 return 0; 324 } 325 326 static void 327 sil164_encoder_destroy(struct drm_encoder *encoder) 328 { 329 struct sil164_priv *priv = to_sil164_priv(encoder); 330 331 i2c_unregister_device(priv->duallink_slave); 332 333 kfree(priv); 334 nouveau_i2c_encoder_destroy(encoder); 335 } 336 337 static const struct nouveau_i2c_encoder_funcs sil164_encoder_funcs = { 338 .set_config = sil164_encoder_set_config, 339 .destroy = sil164_encoder_destroy, 340 .dpms = sil164_encoder_dpms, 341 .save = sil164_encoder_save, 342 .restore = sil164_encoder_restore, 343 .mode_valid = sil164_encoder_mode_valid, 344 .mode_set = sil164_encoder_mode_set, 345 .detect = sil164_encoder_detect, 346 .get_modes = sil164_encoder_get_modes, 347 .create_resources = sil164_encoder_create_resources, 348 .set_property = sil164_encoder_set_property, 349 }; 350 351 /* I2C driver functions */ 352 353 static int 354 sil164_probe(struct i2c_client *client) 355 { 356 int vendor = sil164_read(client, SIL164_VENDOR_HI) << 8 | 357 sil164_read(client, SIL164_VENDOR_LO); 358 int device = sil164_read(client, SIL164_DEVICE_HI) << 8 | 359 sil164_read(client, SIL164_DEVICE_LO); 360 int rev = sil164_read(client, SIL164_REVISION); 361 362 if (vendor != 0x1 || device != 0x6) { 363 sil164_dbg(client, "Unknown device %x:%x.%x\n", 364 vendor, device, rev); 365 return -ENODEV; 366 } 367 368 sil164_info(client, "Detected device %x:%x.%x\n", 369 vendor, device, rev); 370 371 return 0; 372 } 373 374 static struct i2c_client * 375 sil164_detect_slave(struct i2c_client *client) 376 { 377 struct i2c_adapter *adap = client->adapter; 378 struct i2c_msg msg = { 379 .addr = SIL164_I2C_ADDR_SLAVE, 380 .len = 0, 381 }; 382 const struct i2c_board_info info = { 383 I2C_BOARD_INFO("sil164", SIL164_I2C_ADDR_SLAVE) 384 }; 385 386 if (i2c_transfer(adap, &msg, 1) != 1) { 387 sil164_dbg(adap, "No dual-link slave found."); 388 return NULL; 389 } 390 391 return i2c_new_client_device(adap, &info); 392 } 393 394 static int 395 sil164_encoder_init(struct i2c_client *client, 396 struct drm_device *dev, 397 struct nouveau_i2c_encoder *encoder) 398 { 399 struct sil164_priv *priv; 400 struct i2c_client *slave_client; 401 402 priv = kzalloc(sizeof(*priv), GFP_KERNEL); 403 if (!priv) 404 return -ENOMEM; 405 406 encoder->encoder_i2c_priv = priv; 407 encoder->encoder_i2c_funcs = &sil164_encoder_funcs; 408 409 slave_client = sil164_detect_slave(client); 410 if (!IS_ERR(slave_client)) 411 priv->duallink_slave = slave_client; 412 413 return 0; 414 } 415 416 static const struct i2c_device_id sil164_ids[] = { 417 { "sil164" }, 418 { } 419 }; 420 MODULE_DEVICE_TABLE(i2c, sil164_ids); 421 422 static struct nouveau_i2c_encoder_driver sil164_driver = { 423 .i2c_driver = { 424 .probe = sil164_probe, 425 .driver = { 426 .name = "sil164", 427 }, 428 .id_table = sil164_ids, 429 }, 430 .encoder_init = sil164_encoder_init, 431 }; 432 433 /* Module initialization */ 434 435 static int __init 436 sil164_init(void) 437 { 438 return i2c_add_driver(&sil164_driver.i2c_driver); 439 } 440 441 static void __exit 442 sil164_exit(void) 443 { 444 i2c_del_driver(&sil164_driver.i2c_driver); 445 } 446 447 MODULE_AUTHOR("Francisco Jerez <currojerez@riseup.net>"); 448 MODULE_DESCRIPTION("Silicon Image sil164 TMDS transmitter driver"); 449 MODULE_LICENSE("GPL and additional rights"); 450 451 module_init(sil164_init); 452 module_exit(sil164_exit); 453