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

Merge tag 'drm/panel/for-3.19-rc1' of git://people.freedesktop.org/~tagr/linux into drm-next

drm/panel: Changes for v3.19-rc1

This contains support for a couple of new panels, updates for some GPIO
API changes and a bunch of updates to the MIPI DSI support that should
make it easier to write panel drivers in the future.

* tag 'drm/panel/for-3.19-rc1' of git://people.freedesktop.org/~tagr/linux: (31 commits)
drm/panel: Add Sharp LQ101R1SX01 support
drm/dsi: Do not require .owner field to be set
drm/dsi: Resolve MIPI DSI device from phandle
drm/dsi: Implement DCS set_{column,page}_address commands
drm/dsi: Implement DCS {get,set}_pixel_format commands
drm/dsi: Implement DCS get_power_mode command
drm/dsi: Implement DCS soft_reset command
drm/dsi: Implement DCS nop command
drm/dsi: Add to DocBook documentation
drm/dsi: Implement some standard DCS commands
drm/dsi: Implement generic read and write commands
drm/panel: s6e8aa0: Use standard MIPI DSI function
drm/dsi: Add mipi_dsi_set_maximum_return_packet_size() helper
drm/dsi: Constify mipi_dsi_msg
drm/dsi: Make mipi_dsi_dcs_{read,write}() symmetrical
drm/dsi: Add DSI transfer helper
drm/dsi: Add message to packet translator
drm/dsi: Introduce packet format helpers
drm/panel: s6e8aa0: Fix build warnings on 64-bit
drm/panel: ld9040: Fix build warnings on 64-bit
...

+1411 -88
+6
Documentation/DocBook/drm.tmpl
··· 2368 2368 !Edrivers/gpu/drm/drm_dp_mst_topology.c 2369 2369 </sect2> 2370 2370 <sect2> 2371 + <title>MIPI DSI Helper Functions Reference</title> 2372 + !Pdrivers/gpu/drm/drm_mipi_dsi.c dsi helpers 2373 + !Iinclude/drm/drm_mipi_dsi.h 2374 + !Edrivers/gpu/drm/drm_mipi_dsi.c 2375 + </sect2> 2376 + <sect2> 2371 2377 <title>EDID Helper Functions Reference</title> 2372 2378 !Edrivers/gpu/drm/drm_edid.c 2373 2379 </sect2>
+7
Documentation/devicetree/bindings/panel/auo,b116xw03.txt
··· 1 + AU Optronics Corporation 11.6" HD (1366x768) color TFT-LCD panel 2 + 3 + Required properties: 4 + - compatible: should be "auo,b116xw03" 5 + 6 + This binding is compatible with the simple-panel binding, which is specified 7 + in simple-panel.txt in this directory.
+7
Documentation/devicetree/bindings/panel/hannstar,hsd070pww1.txt
··· 1 + HannStar Display Corp. HSD070PWW1 7.0" WXGA TFT LCD panel 2 + 3 + Required properties: 4 + - compatible: should be "hannstar,hsd070pww1" 5 + 6 + This binding is compatible with the simple-panel binding, which is specified 7 + in simple-panel.txt in this directory.
+7
Documentation/devicetree/bindings/panel/hit,tx23d38vm0caa.txt
··· 1 + Hitachi Ltd. Corporation 9" WVGA (800x480) TFT LCD panel 2 + 3 + Required properties: 4 + - compatible: should be "hit,tx23d38vm0caa" 5 + 6 + This binding is compatible with the simple-panel binding, which is specified 7 + in simple-panel.txt in this directory.
+7
Documentation/devicetree/bindings/panel/innolux,g121i1-l01.txt
··· 1 + Innolux Corporation 12.1" WXGA (1280x800) TFT LCD panel 2 + 3 + Required properties: 4 + - compatible: should be "innolux,g121i1-l01" 5 + 6 + This binding is compatible with the simple-panel binding, which is specified 7 + in simple-panel.txt in this directory.
+49
Documentation/devicetree/bindings/panel/sharp,lq101r1sx01.txt
··· 1 + Sharp Microelectronics 10.1" WQXGA TFT LCD panel 2 + 3 + This panel requires a dual-channel DSI host to operate. It supports two modes: 4 + - left-right: each channel drives the left or right half of the screen 5 + - even-odd: each channel drives the even or odd lines of the screen 6 + 7 + Each of the DSI channels controls a separate DSI peripheral. The peripheral 8 + driven by the first link (DSI-LINK1), left or even, is considered the primary 9 + peripheral and controls the device. The 'link2' property contains a phandle 10 + to the peripheral driven by the second link (DSI-LINK2, right or odd). 11 + 12 + Note that in video mode the DSI-LINK1 interface always provides the left/even 13 + pixels and DSI-LINK2 always provides the right/odd pixels. In command mode it 14 + is possible to program either link to drive the left/even or right/odd pixels 15 + but for the sake of consistency this binding assumes that the same assignment 16 + is chosen as for video mode. 17 + 18 + Required properties: 19 + - compatible: should be "sharp,lq101r1sx01" 20 + - reg: DSI virtual channel of the peripheral 21 + 22 + Required properties (for DSI-LINK1 only): 23 + - link2: phandle to the DSI peripheral on the secondary link. Note that the 24 + presence of this property marks the containing node as DSI-LINK1. 25 + - power-supply: phandle of the regulator that provides the supply voltage 26 + 27 + Optional properties (for DSI-LINK1 only): 28 + - backlight: phandle of the backlight device attached to the panel 29 + 30 + Example: 31 + 32 + dsi@54300000 { 33 + panel: panel@0 { 34 + compatible = "sharp,lq101r1sx01"; 35 + reg = <0>; 36 + 37 + link2 = <&secondary>; 38 + 39 + power-supply = <...>; 40 + backlight = <...>; 41 + }; 42 + }; 43 + 44 + dsi@54400000 { 45 + secondary: panel@0 { 46 + compatible = "sharp,lq101r1sx01"; 47 + reg = <0>; 48 + }; 49 + };
+2
Documentation/devicetree/bindings/vendor-prefixes.txt
··· 64 64 google Google, Inc. 65 65 gumstix Gumstix, Inc. 66 66 gw Gateworks Corporation 67 + hannstar HannStar Display Corporation 67 68 haoyu Haoyu Microelectronic Co. Ltd. 68 69 hisilicon Hisilicon Limited. 70 + hit Hitachi Ltd. 69 71 honeywell Honeywell 70 72 hp Hewlett Packard 71 73 i2se I2SE GmbH
+632 -32
drivers/gpu/drm/drm_mipi_dsi.c
··· 35 35 36 36 #include <video/mipi_display.h> 37 37 38 + /** 39 + * DOC: dsi helpers 40 + * 41 + * These functions contain some common logic and helpers to deal with MIPI DSI 42 + * peripherals. 43 + * 44 + * Helpers are provided for a number of standard MIPI DSI command as well as a 45 + * subset of the MIPI DCS command set. 46 + */ 47 + 38 48 static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv) 39 49 { 40 50 return of_driver_match_device(dev, drv); ··· 66 56 .match = mipi_dsi_device_match, 67 57 .pm = &mipi_dsi_device_pm_ops, 68 58 }; 59 + 60 + static int of_device_match(struct device *dev, void *data) 61 + { 62 + return dev->of_node == data; 63 + } 64 + 65 + /** 66 + * of_find_mipi_dsi_device_by_node() - find the MIPI DSI device matching a 67 + * device tree node 68 + * @np: device tree node 69 + * 70 + * Return: A pointer to the MIPI DSI device corresponding to @np or NULL if no 71 + * such device exists (or has not been registered yet). 72 + */ 73 + struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np) 74 + { 75 + struct device *dev; 76 + 77 + dev = bus_find_device(&mipi_dsi_bus_type, NULL, np, of_device_match); 78 + 79 + return dev ? to_mipi_dsi_device(dev) : NULL; 80 + } 81 + EXPORT_SYMBOL(of_find_mipi_dsi_device_by_node); 69 82 70 83 static void mipi_dsi_dev_release(struct device *dev) 71 84 { ··· 231 198 } 232 199 EXPORT_SYMBOL(mipi_dsi_detach); 233 200 234 - /** 235 - * mipi_dsi_dcs_write - send DCS write command 236 - * @dsi: DSI device 237 - * @data: pointer to the command followed by parameters 238 - * @len: length of @data 239 - */ 240 - ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, const void *data, 241 - size_t len) 201 + static ssize_t mipi_dsi_device_transfer(struct mipi_dsi_device *dsi, 202 + struct mipi_dsi_msg *msg) 242 203 { 243 204 const struct mipi_dsi_host_ops *ops = dsi->host->ops; 205 + 206 + if (!ops || !ops->transfer) 207 + return -ENOSYS; 208 + 209 + if (dsi->mode_flags & MIPI_DSI_MODE_LPM) 210 + msg->flags |= MIPI_DSI_MSG_USE_LPM; 211 + 212 + return ops->transfer(dsi->host, msg); 213 + } 214 + 215 + /** 216 + * mipi_dsi_packet_format_is_short - check if a packet is of the short format 217 + * @type: MIPI DSI data type of the packet 218 + * 219 + * Return: true if the packet for the given data type is a short packet, false 220 + * otherwise. 221 + */ 222 + bool mipi_dsi_packet_format_is_short(u8 type) 223 + { 224 + switch (type) { 225 + case MIPI_DSI_V_SYNC_START: 226 + case MIPI_DSI_V_SYNC_END: 227 + case MIPI_DSI_H_SYNC_START: 228 + case MIPI_DSI_H_SYNC_END: 229 + case MIPI_DSI_END_OF_TRANSMISSION: 230 + case MIPI_DSI_COLOR_MODE_OFF: 231 + case MIPI_DSI_COLOR_MODE_ON: 232 + case MIPI_DSI_SHUTDOWN_PERIPHERAL: 233 + case MIPI_DSI_TURN_ON_PERIPHERAL: 234 + case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM: 235 + case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM: 236 + case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM: 237 + case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM: 238 + case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM: 239 + case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM: 240 + case MIPI_DSI_DCS_SHORT_WRITE: 241 + case MIPI_DSI_DCS_SHORT_WRITE_PARAM: 242 + case MIPI_DSI_DCS_READ: 243 + case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE: 244 + return true; 245 + } 246 + 247 + return false; 248 + } 249 + EXPORT_SYMBOL(mipi_dsi_packet_format_is_short); 250 + 251 + /** 252 + * mipi_dsi_packet_format_is_long - check if a packet is of the long format 253 + * @type: MIPI DSI data type of the packet 254 + * 255 + * Return: true if the packet for the given data type is a long packet, false 256 + * otherwise. 257 + */ 258 + bool mipi_dsi_packet_format_is_long(u8 type) 259 + { 260 + switch (type) { 261 + case MIPI_DSI_NULL_PACKET: 262 + case MIPI_DSI_BLANKING_PACKET: 263 + case MIPI_DSI_GENERIC_LONG_WRITE: 264 + case MIPI_DSI_DCS_LONG_WRITE: 265 + case MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20: 266 + case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24: 267 + case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16: 268 + case MIPI_DSI_PACKED_PIXEL_STREAM_30: 269 + case MIPI_DSI_PACKED_PIXEL_STREAM_36: 270 + case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12: 271 + case MIPI_DSI_PACKED_PIXEL_STREAM_16: 272 + case MIPI_DSI_PACKED_PIXEL_STREAM_18: 273 + case MIPI_DSI_PIXEL_STREAM_3BYTE_18: 274 + case MIPI_DSI_PACKED_PIXEL_STREAM_24: 275 + return true; 276 + } 277 + 278 + return false; 279 + } 280 + EXPORT_SYMBOL(mipi_dsi_packet_format_is_long); 281 + 282 + /** 283 + * mipi_dsi_create_packet - create a packet from a message according to the 284 + * DSI protocol 285 + * @packet: pointer to a DSI packet structure 286 + * @msg: message to translate into a packet 287 + * 288 + * Return: 0 on success or a negative error code on failure. 289 + */ 290 + int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, 291 + const struct mipi_dsi_msg *msg) 292 + { 293 + const u8 *tx = msg->tx_buf; 294 + 295 + if (!packet || !msg) 296 + return -EINVAL; 297 + 298 + /* do some minimum sanity checking */ 299 + if (!mipi_dsi_packet_format_is_short(msg->type) && 300 + !mipi_dsi_packet_format_is_long(msg->type)) 301 + return -EINVAL; 302 + 303 + if (msg->channel > 3) 304 + return -EINVAL; 305 + 306 + memset(packet, 0, sizeof(*packet)); 307 + packet->header[0] = ((msg->channel & 0x3) << 6) | (msg->type & 0x3f); 308 + 309 + /* TODO: compute ECC if hardware support is not available */ 310 + 311 + /* 312 + * Long write packets contain the word count in header bytes 1 and 2. 313 + * The payload follows the header and is word count bytes long. 314 + * 315 + * Short write packets encode up to two parameters in header bytes 1 316 + * and 2. 317 + */ 318 + if (mipi_dsi_packet_format_is_long(msg->type)) { 319 + packet->header[1] = (msg->tx_len >> 0) & 0xff; 320 + packet->header[2] = (msg->tx_len >> 8) & 0xff; 321 + 322 + packet->payload_length = msg->tx_len; 323 + packet->payload = tx; 324 + } else { 325 + packet->header[1] = (msg->tx_len > 0) ? tx[0] : 0; 326 + packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0; 327 + } 328 + 329 + packet->size = sizeof(packet->header) + packet->payload_length; 330 + 331 + return 0; 332 + } 333 + EXPORT_SYMBOL(mipi_dsi_create_packet); 334 + 335 + /* 336 + * mipi_dsi_set_maximum_return_packet_size() - specify the maximum size of the 337 + * the payload in a long packet transmitted from the peripheral back to the 338 + * host processor 339 + * @dsi: DSI peripheral device 340 + * @value: the maximum size of the payload 341 + * 342 + * Return: 0 on success or a negative error code on failure. 343 + */ 344 + int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi, 345 + u16 value) 346 + { 347 + u8 tx[2] = { value & 0xff, value >> 8 }; 348 + struct mipi_dsi_msg msg = { 349 + .channel = dsi->channel, 350 + .type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, 351 + .tx_len = sizeof(tx), 352 + .tx_buf = tx, 353 + }; 354 + 355 + return mipi_dsi_device_transfer(dsi, &msg); 356 + } 357 + EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size); 358 + 359 + /** 360 + * mipi_dsi_generic_write() - transmit data using a generic write packet 361 + * @dsi: DSI peripheral device 362 + * @payload: buffer containing the payload 363 + * @size: size of payload buffer 364 + * 365 + * This function will automatically choose the right data type depending on 366 + * the payload length. 367 + * 368 + * Return: The number of bytes transmitted on success or a negative error code 369 + * on failure. 370 + */ 371 + ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload, 372 + size_t size) 373 + { 374 + struct mipi_dsi_msg msg = { 375 + .channel = dsi->channel, 376 + .tx_buf = payload, 377 + .tx_len = size 378 + }; 379 + 380 + switch (size) { 381 + case 0: 382 + msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM; 383 + break; 384 + 385 + case 1: 386 + msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM; 387 + break; 388 + 389 + case 2: 390 + msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM; 391 + break; 392 + 393 + default: 394 + msg.type = MIPI_DSI_GENERIC_LONG_WRITE; 395 + break; 396 + } 397 + 398 + return mipi_dsi_device_transfer(dsi, &msg); 399 + } 400 + EXPORT_SYMBOL(mipi_dsi_generic_write); 401 + 402 + /** 403 + * mipi_dsi_generic_read() - receive data using a generic read packet 404 + * @dsi: DSI peripheral device 405 + * @params: buffer containing the request parameters 406 + * @num_params: number of request parameters 407 + * @data: buffer in which to return the received data 408 + * @size: size of receive buffer 409 + * 410 + * This function will automatically choose the right data type depending on 411 + * the number of parameters passed in. 412 + * 413 + * Return: The number of bytes successfully read or a negative error code on 414 + * failure. 415 + */ 416 + ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, 417 + size_t num_params, void *data, size_t size) 418 + { 419 + struct mipi_dsi_msg msg = { 420 + .channel = dsi->channel, 421 + .tx_len = num_params, 422 + .tx_buf = params, 423 + .rx_len = size, 424 + .rx_buf = data 425 + }; 426 + 427 + switch (num_params) { 428 + case 0: 429 + msg.type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM; 430 + break; 431 + 432 + case 1: 433 + msg.type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM; 434 + break; 435 + 436 + case 2: 437 + msg.type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM; 438 + break; 439 + 440 + default: 441 + return -EINVAL; 442 + } 443 + 444 + return mipi_dsi_device_transfer(dsi, &msg); 445 + } 446 + EXPORT_SYMBOL(mipi_dsi_generic_read); 447 + 448 + /** 449 + * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload 450 + * @dsi: DSI peripheral device 451 + * @data: buffer containing data to be transmitted 452 + * @len: size of transmission buffer 453 + * 454 + * This function will automatically choose the right data type depending on 455 + * the command payload length. 456 + * 457 + * Return: The number of bytes successfully transmitted or a negative error 458 + * code on failure. 459 + */ 460 + ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, 461 + const void *data, size_t len) 462 + { 244 463 struct mipi_dsi_msg msg = { 245 464 .channel = dsi->channel, 246 465 .tx_buf = data, 247 466 .tx_len = len 248 467 }; 249 468 250 - if (!ops || !ops->transfer) 251 - return -ENOSYS; 252 - 253 469 switch (len) { 254 470 case 0: 255 471 return -EINVAL; 472 + 256 473 case 1: 257 474 msg.type = MIPI_DSI_DCS_SHORT_WRITE; 258 475 break; 476 + 259 477 case 2: 260 478 msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM; 261 479 break; 480 + 262 481 default: 263 482 msg.type = MIPI_DSI_DCS_LONG_WRITE; 264 483 break; 265 484 } 266 485 267 - if (dsi->mode_flags & MIPI_DSI_MODE_LPM) 268 - msg.flags = MIPI_DSI_MSG_USE_LPM; 486 + return mipi_dsi_device_transfer(dsi, &msg); 487 + } 488 + EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer); 269 489 270 - return ops->transfer(dsi->host, &msg); 490 + /** 491 + * mipi_dsi_dcs_write() - send DCS write command 492 + * @dsi: DSI peripheral device 493 + * @cmd: DCS command 494 + * @data: buffer containing the command payload 495 + * @len: command payload length 496 + * 497 + * This function will automatically choose the right data type depending on 498 + * the command payload length. 499 + * 500 + * Return: The number of bytes successfully transmitted or a negative error 501 + * code on failure. 502 + */ 503 + ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, 504 + const void *data, size_t len) 505 + { 506 + ssize_t err; 507 + size_t size; 508 + u8 *tx; 509 + 510 + if (len > 0) { 511 + size = 1 + len; 512 + 513 + tx = kmalloc(size, GFP_KERNEL); 514 + if (!tx) 515 + return -ENOMEM; 516 + 517 + /* concatenate the DCS command byte and the payload */ 518 + tx[0] = cmd; 519 + memcpy(&tx[1], data, len); 520 + } else { 521 + tx = &cmd; 522 + size = 1; 523 + } 524 + 525 + err = mipi_dsi_dcs_write_buffer(dsi, tx, size); 526 + 527 + if (len > 0) 528 + kfree(tx); 529 + 530 + return err; 271 531 } 272 532 EXPORT_SYMBOL(mipi_dsi_dcs_write); 273 533 274 534 /** 275 - * mipi_dsi_dcs_read - send DCS read request command 276 - * @dsi: DSI device 277 - * @cmd: DCS read command 278 - * @data: pointer to read buffer 279 - * @len: length of @data 535 + * mipi_dsi_dcs_read() - send DCS read request command 536 + * @dsi: DSI peripheral device 537 + * @cmd: DCS command 538 + * @data: buffer in which to receive data 539 + * @len: size of receive buffer 280 540 * 281 - * Function returns number of read bytes or error code. 541 + * Return: The number of bytes read or a negative error code on failure. 282 542 */ 283 543 ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, 284 544 size_t len) 285 545 { 286 - const struct mipi_dsi_host_ops *ops = dsi->host->ops; 287 546 struct mipi_dsi_msg msg = { 288 547 .channel = dsi->channel, 289 548 .type = MIPI_DSI_DCS_READ, ··· 585 260 .rx_len = len 586 261 }; 587 262 588 - if (!ops || !ops->transfer) 589 - return -ENOSYS; 590 - 591 - if (dsi->mode_flags & MIPI_DSI_MODE_LPM) 592 - msg.flags = MIPI_DSI_MSG_USE_LPM; 593 - 594 - return ops->transfer(dsi->host, &msg); 263 + return mipi_dsi_device_transfer(dsi, &msg); 595 264 } 596 265 EXPORT_SYMBOL(mipi_dsi_dcs_read); 266 + 267 + /** 268 + * mipi_dsi_dcs_nop() - send DCS nop packet 269 + * @dsi: DSI peripheral device 270 + * 271 + * Return: 0 on success or a negative error code on failure. 272 + */ 273 + int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi) 274 + { 275 + ssize_t err; 276 + 277 + err = mipi_dsi_dcs_write(dsi, MIPI_DCS_NOP, NULL, 0); 278 + if (err < 0) 279 + return err; 280 + 281 + return 0; 282 + } 283 + EXPORT_SYMBOL(mipi_dsi_dcs_nop); 284 + 285 + /** 286 + * mipi_dsi_dcs_soft_reset() - perform a software reset of the display module 287 + * @dsi: DSI peripheral device 288 + * 289 + * Return: 0 on success or a negative error code on failure. 290 + */ 291 + int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi) 292 + { 293 + ssize_t err; 294 + 295 + err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SOFT_RESET, NULL, 0); 296 + if (err < 0) 297 + return err; 298 + 299 + return 0; 300 + } 301 + EXPORT_SYMBOL(mipi_dsi_dcs_soft_reset); 302 + 303 + /** 304 + * mipi_dsi_dcs_get_power_mode() - query the display module's current power 305 + * mode 306 + * @dsi: DSI peripheral device 307 + * @mode: return location for the current power mode 308 + * 309 + * Return: 0 on success or a negative error code on failure. 310 + */ 311 + int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode) 312 + { 313 + ssize_t err; 314 + 315 + err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_POWER_MODE, mode, 316 + sizeof(*mode)); 317 + if (err <= 0) { 318 + if (err == 0) 319 + err = -ENODATA; 320 + 321 + return err; 322 + } 323 + 324 + return 0; 325 + } 326 + EXPORT_SYMBOL(mipi_dsi_dcs_get_power_mode); 327 + 328 + /** 329 + * mipi_dsi_dcs_get_pixel_format() - gets the pixel format for the RGB image 330 + * data used by the interface 331 + * @dsi: DSI peripheral device 332 + * @format: return location for the pixel format 333 + * 334 + * Return: 0 on success or a negative error code on failure. 335 + */ 336 + int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format) 337 + { 338 + ssize_t err; 339 + 340 + err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_PIXEL_FORMAT, format, 341 + sizeof(*format)); 342 + if (err <= 0) { 343 + if (err == 0) 344 + err = -ENODATA; 345 + 346 + return err; 347 + } 348 + 349 + return 0; 350 + } 351 + EXPORT_SYMBOL(mipi_dsi_dcs_get_pixel_format); 352 + 353 + /** 354 + * mipi_dsi_dcs_enter_sleep_mode() - disable all unnecessary blocks inside the 355 + * display module except interface communication 356 + * @dsi: DSI peripheral device 357 + * 358 + * Return: 0 on success or a negative error code on failure. 359 + */ 360 + int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi) 361 + { 362 + ssize_t err; 363 + 364 + err = mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0); 365 + if (err < 0) 366 + return err; 367 + 368 + return 0; 369 + } 370 + EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode); 371 + 372 + /** 373 + * mipi_dsi_dcs_exit_sleep_mode() - enable all blocks inside the display 374 + * module 375 + * @dsi: DSI peripheral device 376 + * 377 + * Return: 0 on success or a negative error code on failure. 378 + */ 379 + int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi) 380 + { 381 + ssize_t err; 382 + 383 + err = mipi_dsi_dcs_write(dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0); 384 + if (err < 0) 385 + return err; 386 + 387 + return 0; 388 + } 389 + EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode); 390 + 391 + /** 392 + * mipi_dsi_dcs_set_display_off() - stop displaying the image data on the 393 + * display device 394 + * @dsi: DSI peripheral device 395 + * 396 + * Return: 0 on success or a negative error code on failure. 397 + */ 398 + int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi) 399 + { 400 + ssize_t err; 401 + 402 + err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0); 403 + if (err < 0) 404 + return err; 405 + 406 + return 0; 407 + } 408 + EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off); 409 + 410 + /** 411 + * mipi_dsi_dcs_set_display_on() - start displaying the image data on the 412 + * display device 413 + * @dsi: DSI peripheral device 414 + * 415 + * Return: 0 on success or a negative error code on failure 416 + */ 417 + int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi) 418 + { 419 + ssize_t err; 420 + 421 + err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0); 422 + if (err < 0) 423 + return err; 424 + 425 + return 0; 426 + } 427 + EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on); 428 + 429 + /** 430 + * mipi_dsi_dcs_set_column_address() - define the column extent of the frame 431 + * memory accessed by the host processor 432 + * @dsi: DSI peripheral device 433 + * @start: first column of frame memory 434 + * @end: last column of frame memory 435 + * 436 + * Return: 0 on success or a negative error code on failure. 437 + */ 438 + int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start, 439 + u16 end) 440 + { 441 + u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff }; 442 + ssize_t err; 443 + 444 + err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_COLUMN_ADDRESS, payload, 445 + sizeof(payload)); 446 + if (err < 0) 447 + return err; 448 + 449 + return 0; 450 + } 451 + EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address); 452 + 453 + /** 454 + * mipi_dsi_dcs_set_page_address() - define the page extent of the frame 455 + * memory accessed by the host processor 456 + * @dsi: DSI peripheral device 457 + * @start: first page of frame memory 458 + * @end: last page of frame memory 459 + * 460 + * Return: 0 on success or a negative error code on failure. 461 + */ 462 + int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start, 463 + u16 end) 464 + { 465 + u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff }; 466 + ssize_t err; 467 + 468 + err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PAGE_ADDRESS, payload, 469 + sizeof(payload)); 470 + if (err < 0) 471 + return err; 472 + 473 + return 0; 474 + } 475 + EXPORT_SYMBOL(mipi_dsi_dcs_set_page_address); 476 + 477 + /** 478 + * mipi_dsi_dcs_set_tear_off() - turn off the display module's Tearing Effect 479 + * output signal on the TE signal line 480 + * @dsi: DSI peripheral device 481 + * 482 + * Return: 0 on success or a negative error code on failure 483 + */ 484 + int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi) 485 + { 486 + ssize_t err; 487 + 488 + err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_OFF, NULL, 0); 489 + if (err < 0) 490 + return err; 491 + 492 + return 0; 493 + } 494 + EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_off); 495 + 496 + /** 497 + * mipi_dsi_dcs_set_tear_on() - turn on the display module's Tearing Effect 498 + * output signal on the TE signal line. 499 + * @dsi: DSI peripheral device 500 + * @mode: the Tearing Effect Output Line mode 501 + * 502 + * Return: 0 on success or a negative error code on failure 503 + */ 504 + int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi, 505 + enum mipi_dsi_dcs_tear_mode mode) 506 + { 507 + u8 value = mode; 508 + ssize_t err; 509 + 510 + err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_ON, &value, 511 + sizeof(value)); 512 + if (err < 0) 513 + return err; 514 + 515 + return 0; 516 + } 517 + EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on); 518 + 519 + /** 520 + * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image 521 + * data used by the interface 522 + * @dsi: DSI peripheral device 523 + * @format: pixel format 524 + * 525 + * Return: 0 on success or a negative error code on failure. 526 + */ 527 + int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format) 528 + { 529 + ssize_t err; 530 + 531 + err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PIXEL_FORMAT, &format, 532 + sizeof(format)); 533 + if (err < 0) 534 + return err; 535 + 536 + return 0; 537 + } 538 + EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format); 597 539 598 540 static int mipi_dsi_drv_probe(struct device *dev) 599 541 { ··· 887 295 } 888 296 889 297 /** 890 - * mipi_dsi_driver_register - register a driver for DSI devices 298 + * mipi_dsi_driver_register_full() - register a driver for DSI devices 891 299 * @drv: DSI driver structure 300 + * @owner: owner module 301 + * 302 + * Return: 0 on success or a negative error code on failure. 892 303 */ 893 - int mipi_dsi_driver_register(struct mipi_dsi_driver *drv) 304 + int mipi_dsi_driver_register_full(struct mipi_dsi_driver *drv, 305 + struct module *owner) 894 306 { 895 307 drv->driver.bus = &mipi_dsi_bus_type; 308 + drv->driver.owner = owner; 309 + 896 310 if (drv->probe) 897 311 drv->driver.probe = mipi_dsi_drv_probe; 898 312 if (drv->remove) ··· 908 310 909 311 return driver_register(&drv->driver); 910 312 } 911 - EXPORT_SYMBOL(mipi_dsi_driver_register); 313 + EXPORT_SYMBOL(mipi_dsi_driver_register_full); 912 314 913 315 /** 914 - * mipi_dsi_driver_unregister - unregister a driver for DSI devices 316 + * mipi_dsi_driver_unregister() - unregister a driver for DSI devices 915 317 * @drv: DSI driver structure 318 + * 319 + * Return: 0 on success or a negative error code on failure. 916 320 */ 917 321 void mipi_dsi_driver_unregister(struct mipi_dsi_driver *drv) 918 322 {
+1 -1
drivers/gpu/drm/exynos/exynos_drm_dsi.c
··· 1236 1236 } 1237 1237 1238 1238 static ssize_t exynos_dsi_host_transfer(struct mipi_dsi_host *host, 1239 - struct mipi_dsi_msg *msg) 1239 + const struct mipi_dsi_msg *msg) 1240 1240 { 1241 1241 struct exynos_dsi *dsi = host_to_dsi(host); 1242 1242 struct exynos_dsi_transfer xfer;
+13
drivers/gpu/drm/panel/Kconfig
··· 27 27 select DRM_MIPI_DSI 28 28 select VIDEOMODE_HELPERS 29 29 30 + config DRM_PANEL_SHARP_LQ101R1SX01 31 + tristate "Sharp LQ101R1SX01 panel" 32 + depends on OF 33 + depends on DRM_MIPI_DSI 34 + help 35 + Say Y here if you want to enable support for Sharp LQ101R1SX01 36 + TFT-LCD modules. The panel has a 2560x1600 resolution and uses 37 + 24 bit RGB per pixel. It provides a dual MIPI DSI interface to 38 + the host and has a built-in LED backlight. 39 + 40 + To compile this driver as a module, choose M here: the module 41 + will be called panel-sharp-lq101r1sx01. 42 + 30 43 endmenu
+1
drivers/gpu/drm/panel/Makefile
··· 1 1 obj-$(CONFIG_DRM_PANEL_SIMPLE) += panel-simple.o 2 2 obj-$(CONFIG_DRM_PANEL_LD9040) += panel-ld9040.o 3 3 obj-$(CONFIG_DRM_PANEL_S6E8AA0) += panel-s6e8aa0.o 4 + obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o
+4 -9
drivers/gpu/drm/panel/panel-ld9040.c
··· 145 145 if (ctx->error < 0 || len == 0) 146 146 return; 147 147 148 - dev_dbg(ctx->dev, "writing dcs seq: %*ph\n", len, data); 148 + dev_dbg(ctx->dev, "writing dcs seq: %*ph\n", (int)len, data); 149 149 ret = ld9040_spi_write_word(ctx, *data); 150 150 151 151 while (!ret && --len) { ··· 154 154 } 155 155 156 156 if (ret) { 157 - dev_err(ctx->dev, "error %d writing dcs seq: %*ph\n", ret, len, 158 - data); 157 + dev_err(ctx->dev, "error %d writing dcs seq: %*ph\n", ret, 158 + (int)len, data); 159 159 ctx->error = ret; 160 160 } 161 161 ··· 336 336 if (ret < 0) 337 337 return ret; 338 338 339 - ctx->reset_gpio = devm_gpiod_get(dev, "reset"); 339 + ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); 340 340 if (IS_ERR(ctx->reset_gpio)) { 341 341 dev_err(dev, "cannot get reset-gpios %ld\n", 342 342 PTR_ERR(ctx->reset_gpio)); 343 343 return PTR_ERR(ctx->reset_gpio); 344 - } 345 - ret = gpiod_direction_output(ctx->reset_gpio, 1); 346 - if (ret < 0) { 347 - dev_err(dev, "cannot configure reset-gpios %d\n", ret); 348 - return ret; 349 344 } 350 345 351 346 spi->bits_per_word = 9;
+6 -24
drivers/gpu/drm/panel/panel-s6e8aa0.c
··· 141 141 if (ctx->error < 0) 142 142 return; 143 143 144 - ret = mipi_dsi_dcs_write(dsi, data, len); 144 + ret = mipi_dsi_dcs_write_buffer(dsi, data, len); 145 145 if (ret < 0) { 146 - dev_err(ctx->dev, "error %zd writing dcs seq: %*ph\n", ret, len, 147 - data); 146 + dev_err(ctx->dev, "error %zd writing dcs seq: %*ph\n", ret, 147 + (int)len, data); 148 148 ctx->error = ret; 149 149 } 150 150 } ··· 800 800 } 801 801 802 802 static void s6e8aa0_set_maximum_return_packet_size(struct s6e8aa0 *ctx, 803 - int size) 803 + u16 size) 804 804 { 805 805 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 806 - const struct mipi_dsi_host_ops *ops = dsi->host->ops; 807 - u8 buf[] = {size, 0}; 808 - struct mipi_dsi_msg msg = { 809 - .channel = dsi->channel, 810 - .type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE, 811 - .tx_len = sizeof(buf), 812 - .tx_buf = buf 813 - }; 814 806 int ret; 815 807 816 808 if (ctx->error < 0) 817 809 return; 818 810 819 - if (!ops || !ops->transfer) 820 - ret = -EIO; 821 - else 822 - ret = ops->transfer(dsi->host, &msg); 823 - 811 + ret = mipi_dsi_set_maximum_return_packet_size(dsi, size); 824 812 if (ret < 0) { 825 813 dev_err(ctx->dev, 826 814 "error %d setting maximum return packet size to %d\n", ··· 1007 1019 return ret; 1008 1020 } 1009 1021 1010 - ctx->reset_gpio = devm_gpiod_get(dev, "reset"); 1022 + ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH); 1011 1023 if (IS_ERR(ctx->reset_gpio)) { 1012 1024 dev_err(dev, "cannot get reset-gpios %ld\n", 1013 1025 PTR_ERR(ctx->reset_gpio)); 1014 1026 return PTR_ERR(ctx->reset_gpio); 1015 - } 1016 - ret = gpiod_direction_output(ctx->reset_gpio, 1); 1017 - if (ret < 0) { 1018 - dev_err(dev, "cannot configure reset-gpios %d\n", ret); 1019 - return ret; 1020 1027 } 1021 1028 1022 1029 ctx->brightness = GAMMA_LEVEL_NUM - 1; ··· 1052 1069 .remove = s6e8aa0_remove, 1053 1070 .driver = { 1054 1071 .name = "panel_s6e8aa0", 1055 - .owner = THIS_MODULE, 1056 1072 .of_match_table = s6e8aa0_of_match, 1057 1073 }, 1058 1074 };
+464
drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c
··· 1 + /* 2 + * Copyright (C) 2014 NVIDIA Corporation 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 7 + */ 8 + 9 + #include <linux/backlight.h> 10 + #include <linux/gpio/consumer.h> 11 + #include <linux/module.h> 12 + #include <linux/of.h> 13 + #include <linux/regulator/consumer.h> 14 + 15 + #include <drm/drmP.h> 16 + #include <drm/drm_crtc.h> 17 + #include <drm/drm_mipi_dsi.h> 18 + #include <drm/drm_panel.h> 19 + 20 + #include <video/mipi_display.h> 21 + 22 + #include <linux/host1x.h> 23 + 24 + struct sharp_panel { 25 + struct drm_panel base; 26 + /* the datasheet refers to them as DSI-LINK1 and DSI-LINK2 */ 27 + struct mipi_dsi_device *link1; 28 + struct mipi_dsi_device *link2; 29 + 30 + struct backlight_device *backlight; 31 + struct regulator *supply; 32 + 33 + bool prepared; 34 + bool enabled; 35 + 36 + const struct drm_display_mode *mode; 37 + }; 38 + 39 + static inline struct sharp_panel *to_sharp_panel(struct drm_panel *panel) 40 + { 41 + return container_of(panel, struct sharp_panel, base); 42 + } 43 + 44 + static int sharp_panel_write(struct sharp_panel *sharp, u16 offset, u8 value) 45 + { 46 + u8 payload[3] = { offset >> 8, offset & 0xff, value }; 47 + struct mipi_dsi_device *dsi = sharp->link1; 48 + ssize_t err; 49 + 50 + err = mipi_dsi_generic_write(dsi, payload, sizeof(payload)); 51 + if (err < 0) { 52 + dev_err(&dsi->dev, "failed to write %02x to %04x: %zd\n", 53 + value, offset, err); 54 + return err; 55 + } 56 + 57 + err = mipi_dsi_dcs_nop(dsi); 58 + if (err < 0) { 59 + dev_err(&dsi->dev, "failed to send DCS nop: %zd\n", err); 60 + return err; 61 + } 62 + 63 + usleep_range(10, 20); 64 + 65 + return 0; 66 + } 67 + 68 + static __maybe_unused int sharp_panel_read(struct sharp_panel *sharp, 69 + u16 offset, u8 *value) 70 + { 71 + ssize_t err; 72 + 73 + cpu_to_be16s(&offset); 74 + 75 + err = mipi_dsi_generic_read(sharp->link1, &offset, sizeof(offset), 76 + value, sizeof(*value)); 77 + if (err < 0) 78 + dev_err(&sharp->link1->dev, "failed to read from %04x: %zd\n", 79 + offset, err); 80 + 81 + return err; 82 + } 83 + 84 + static int sharp_panel_disable(struct drm_panel *panel) 85 + { 86 + struct sharp_panel *sharp = to_sharp_panel(panel); 87 + 88 + if (!sharp->enabled) 89 + return 0; 90 + 91 + if (sharp->backlight) { 92 + sharp->backlight->props.power = FB_BLANK_POWERDOWN; 93 + backlight_update_status(sharp->backlight); 94 + } 95 + 96 + sharp->enabled = false; 97 + 98 + return 0; 99 + } 100 + 101 + static int sharp_panel_unprepare(struct drm_panel *panel) 102 + { 103 + struct sharp_panel *sharp = to_sharp_panel(panel); 104 + int err; 105 + 106 + if (!sharp->prepared) 107 + return 0; 108 + 109 + err = mipi_dsi_dcs_set_display_off(sharp->link1); 110 + if (err < 0) 111 + dev_err(panel->dev, "failed to set display off: %d\n", err); 112 + 113 + err = mipi_dsi_dcs_enter_sleep_mode(sharp->link1); 114 + if (err < 0) 115 + dev_err(panel->dev, "failed to enter sleep mode: %d\n", err); 116 + 117 + msleep(120); 118 + 119 + regulator_disable(sharp->supply); 120 + 121 + sharp->prepared = false; 122 + 123 + return 0; 124 + } 125 + 126 + static int sharp_setup_symmetrical_split(struct mipi_dsi_device *left, 127 + struct mipi_dsi_device *right, 128 + const struct drm_display_mode *mode) 129 + { 130 + int err; 131 + 132 + err = mipi_dsi_dcs_set_column_address(left, 0, mode->hdisplay / 2 - 1); 133 + if (err < 0) { 134 + dev_err(&left->dev, "failed to set column address: %d\n", err); 135 + return err; 136 + } 137 + 138 + err = mipi_dsi_dcs_set_page_address(left, 0, mode->vdisplay - 1); 139 + if (err < 0) { 140 + dev_err(&left->dev, "failed to set page address: %d\n", err); 141 + return err; 142 + } 143 + 144 + err = mipi_dsi_dcs_set_column_address(right, mode->hdisplay / 2, 145 + mode->hdisplay - 1); 146 + if (err < 0) { 147 + dev_err(&right->dev, "failed to set column address: %d\n", err); 148 + return err; 149 + } 150 + 151 + err = mipi_dsi_dcs_set_page_address(right, 0, mode->vdisplay - 1); 152 + if (err < 0) { 153 + dev_err(&right->dev, "failed to set page address: %d\n", err); 154 + return err; 155 + } 156 + 157 + return 0; 158 + } 159 + 160 + static int sharp_panel_prepare(struct drm_panel *panel) 161 + { 162 + struct sharp_panel *sharp = to_sharp_panel(panel); 163 + u8 format = MIPI_DCS_PIXEL_FMT_24BIT; 164 + int err; 165 + 166 + if (sharp->prepared) 167 + return 0; 168 + 169 + err = regulator_enable(sharp->supply); 170 + if (err < 0) 171 + return err; 172 + 173 + usleep_range(10000, 20000); 174 + 175 + err = mipi_dsi_dcs_soft_reset(sharp->link1); 176 + if (err < 0) { 177 + dev_err(panel->dev, "soft reset failed: %d\n", err); 178 + goto poweroff; 179 + } 180 + 181 + msleep(120); 182 + 183 + err = mipi_dsi_dcs_exit_sleep_mode(sharp->link1); 184 + if (err < 0) { 185 + dev_err(panel->dev, "failed to exit sleep mode: %d\n", err); 186 + goto poweroff; 187 + } 188 + 189 + /* 190 + * The MIPI DCS specification mandates this delay only between the 191 + * exit_sleep_mode and enter_sleep_mode commands, so it isn't strictly 192 + * necessary here. 193 + */ 194 + /* 195 + msleep(120); 196 + */ 197 + 198 + /* set left-right mode */ 199 + err = sharp_panel_write(sharp, 0x1000, 0x2a); 200 + if (err < 0) { 201 + dev_err(panel->dev, "failed to set left-right mode: %d\n", err); 202 + goto poweroff; 203 + } 204 + 205 + /* enable command mode */ 206 + err = sharp_panel_write(sharp, 0x1001, 0x01); 207 + if (err < 0) { 208 + dev_err(panel->dev, "failed to enable command mode: %d\n", err); 209 + goto poweroff; 210 + } 211 + 212 + err = mipi_dsi_dcs_set_pixel_format(sharp->link1, format); 213 + if (err < 0) { 214 + dev_err(panel->dev, "failed to set pixel format: %d\n", err); 215 + goto poweroff; 216 + } 217 + 218 + /* 219 + * TODO: The device supports both left-right and even-odd split 220 + * configurations, but this driver currently supports only the left- 221 + * right split. To support a different mode a mechanism needs to be 222 + * put in place to communicate the configuration back to the DSI host 223 + * controller. 224 + */ 225 + err = sharp_setup_symmetrical_split(sharp->link1, sharp->link2, 226 + sharp->mode); 227 + if (err < 0) { 228 + dev_err(panel->dev, "failed to set up symmetrical split: %d\n", 229 + err); 230 + goto poweroff; 231 + } 232 + 233 + err = mipi_dsi_dcs_set_display_on(sharp->link1); 234 + if (err < 0) { 235 + dev_err(panel->dev, "failed to set display on: %d\n", err); 236 + goto poweroff; 237 + } 238 + 239 + sharp->prepared = true; 240 + 241 + return 0; 242 + 243 + poweroff: 244 + regulator_disable(sharp->supply); 245 + return err; 246 + } 247 + 248 + static int sharp_panel_enable(struct drm_panel *panel) 249 + { 250 + struct sharp_panel *sharp = to_sharp_panel(panel); 251 + 252 + if (sharp->enabled) 253 + return 0; 254 + 255 + if (sharp->backlight) { 256 + sharp->backlight->props.power = FB_BLANK_UNBLANK; 257 + backlight_update_status(sharp->backlight); 258 + } 259 + 260 + sharp->enabled = true; 261 + 262 + return 0; 263 + } 264 + 265 + static const struct drm_display_mode default_mode = { 266 + .clock = 278000, 267 + .hdisplay = 2560, 268 + .hsync_start = 2560 + 128, 269 + .hsync_end = 2560 + 128 + 64, 270 + .htotal = 2560 + 128 + 64 + 64, 271 + .vdisplay = 1600, 272 + .vsync_start = 1600 + 4, 273 + .vsync_end = 1600 + 4 + 8, 274 + .vtotal = 1600 + 4 + 8 + 32, 275 + .vrefresh = 60, 276 + }; 277 + 278 + static int sharp_panel_get_modes(struct drm_panel *panel) 279 + { 280 + struct drm_display_mode *mode; 281 + 282 + mode = drm_mode_duplicate(panel->drm, &default_mode); 283 + if (!mode) { 284 + dev_err(panel->drm->dev, "failed to add mode %ux%ux@%u\n", 285 + default_mode.hdisplay, default_mode.vdisplay, 286 + default_mode.vrefresh); 287 + return -ENOMEM; 288 + } 289 + 290 + drm_mode_set_name(mode); 291 + 292 + drm_mode_probed_add(panel->connector, mode); 293 + 294 + panel->connector->display_info.width_mm = 217; 295 + panel->connector->display_info.height_mm = 136; 296 + 297 + return 1; 298 + } 299 + 300 + static const struct drm_panel_funcs sharp_panel_funcs = { 301 + .disable = sharp_panel_disable, 302 + .unprepare = sharp_panel_unprepare, 303 + .prepare = sharp_panel_prepare, 304 + .enable = sharp_panel_enable, 305 + .get_modes = sharp_panel_get_modes, 306 + }; 307 + 308 + static const struct of_device_id sharp_of_match[] = { 309 + { .compatible = "sharp,lq101r1sx01", }, 310 + { } 311 + }; 312 + MODULE_DEVICE_TABLE(of, sharp_of_match); 313 + 314 + static int sharp_panel_add(struct sharp_panel *sharp) 315 + { 316 + struct device_node *np; 317 + int err; 318 + 319 + sharp->mode = &default_mode; 320 + 321 + sharp->supply = devm_regulator_get(&sharp->link1->dev, "power"); 322 + if (IS_ERR(sharp->supply)) 323 + return PTR_ERR(sharp->supply); 324 + 325 + np = of_parse_phandle(sharp->link1->dev.of_node, "backlight", 0); 326 + if (np) { 327 + sharp->backlight = of_find_backlight_by_node(np); 328 + of_node_put(np); 329 + 330 + if (!sharp->backlight) 331 + return -EPROBE_DEFER; 332 + } 333 + 334 + drm_panel_init(&sharp->base); 335 + sharp->base.funcs = &sharp_panel_funcs; 336 + sharp->base.dev = &sharp->link1->dev; 337 + 338 + err = drm_panel_add(&sharp->base); 339 + if (err < 0) 340 + goto put_backlight; 341 + 342 + return 0; 343 + 344 + put_backlight: 345 + if (sharp->backlight) 346 + put_device(&sharp->backlight->dev); 347 + 348 + return err; 349 + } 350 + 351 + static void sharp_panel_del(struct sharp_panel *sharp) 352 + { 353 + if (sharp->base.dev) 354 + drm_panel_remove(&sharp->base); 355 + 356 + if (sharp->backlight) 357 + put_device(&sharp->backlight->dev); 358 + 359 + if (sharp->link2) 360 + put_device(&sharp->link2->dev); 361 + } 362 + 363 + static int sharp_panel_probe(struct mipi_dsi_device *dsi) 364 + { 365 + struct mipi_dsi_device *secondary = NULL; 366 + struct sharp_panel *sharp; 367 + struct device_node *np; 368 + int err; 369 + 370 + dsi->lanes = 4; 371 + dsi->format = MIPI_DSI_FMT_RGB888; 372 + dsi->mode_flags = MIPI_DSI_MODE_LPM; 373 + 374 + /* Find DSI-LINK1 */ 375 + np = of_parse_phandle(dsi->dev.of_node, "link2", 0); 376 + if (np) { 377 + secondary = of_find_mipi_dsi_device_by_node(np); 378 + of_node_put(np); 379 + 380 + if (!secondary) 381 + return -EPROBE_DEFER; 382 + } 383 + 384 + /* register a panel for only the DSI-LINK1 interface */ 385 + if (secondary) { 386 + sharp = devm_kzalloc(&dsi->dev, sizeof(*sharp), GFP_KERNEL); 387 + if (!sharp) { 388 + put_device(&secondary->dev); 389 + return -ENOMEM; 390 + } 391 + 392 + mipi_dsi_set_drvdata(dsi, sharp); 393 + 394 + sharp->link2 = secondary; 395 + sharp->link1 = dsi; 396 + 397 + err = sharp_panel_add(sharp); 398 + if (err < 0) { 399 + put_device(&secondary->dev); 400 + return err; 401 + } 402 + } 403 + 404 + err = mipi_dsi_attach(dsi); 405 + if (err < 0) { 406 + if (secondary) 407 + sharp_panel_del(sharp); 408 + 409 + return err; 410 + } 411 + 412 + return 0; 413 + } 414 + 415 + static int sharp_panel_remove(struct mipi_dsi_device *dsi) 416 + { 417 + struct sharp_panel *sharp = mipi_dsi_get_drvdata(dsi); 418 + int err; 419 + 420 + /* only detach from host for the DSI-LINK2 interface */ 421 + if (!sharp) { 422 + mipi_dsi_detach(dsi); 423 + return 0; 424 + } 425 + 426 + err = sharp_panel_disable(&sharp->base); 427 + if (err < 0) 428 + dev_err(&dsi->dev, "failed to disable panel: %d\n", err); 429 + 430 + err = mipi_dsi_detach(dsi); 431 + if (err < 0) 432 + dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", err); 433 + 434 + drm_panel_detach(&sharp->base); 435 + sharp_panel_del(sharp); 436 + 437 + return 0; 438 + } 439 + 440 + static void sharp_panel_shutdown(struct mipi_dsi_device *dsi) 441 + { 442 + struct sharp_panel *sharp = mipi_dsi_get_drvdata(dsi); 443 + 444 + /* nothing to do for DSI-LINK2 */ 445 + if (!sharp) 446 + return; 447 + 448 + sharp_panel_disable(&sharp->base); 449 + } 450 + 451 + static struct mipi_dsi_driver sharp_panel_driver = { 452 + .driver = { 453 + .name = "panel-sharp-lq101r1sx01", 454 + .of_match_table = sharp_of_match, 455 + }, 456 + .probe = sharp_panel_probe, 457 + .remove = sharp_panel_remove, 458 + .shutdown = sharp_panel_shutdown, 459 + }; 460 + module_mipi_dsi_driver(sharp_panel_driver); 461 + 462 + MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>"); 463 + MODULE_DESCRIPTION("Sharp LQ101R1SX01 panel driver"); 464 + MODULE_LICENSE("GPL v2");
+117 -16
drivers/gpu/drm/panel/panel-simple.c
··· 247 247 if (IS_ERR(panel->supply)) 248 248 return PTR_ERR(panel->supply); 249 249 250 - panel->enable_gpio = devm_gpiod_get_optional(dev, "enable"); 250 + panel->enable_gpio = devm_gpiod_get_optional(dev, "enable", 251 + GPIOD_OUT_LOW); 251 252 if (IS_ERR(panel->enable_gpio)) { 252 253 err = PTR_ERR(panel->enable_gpio); 253 254 dev_err(dev, "failed to request GPIO: %d\n", err); 254 255 return err; 255 - } 256 - 257 - if (panel->enable_gpio) { 258 - err = gpiod_direction_output(panel->enable_gpio, 0); 259 - if (err < 0) { 260 - dev_err(dev, "failed to setup GPIO: %d\n", err); 261 - return err; 262 - } 263 256 } 264 257 265 258 backlight = of_parse_phandle(dev->of_node, "backlight", 0); ··· 369 376 }, 370 377 }; 371 378 379 + static const struct drm_display_mode auo_b116xw03_mode = { 380 + .clock = 70589, 381 + .hdisplay = 1366, 382 + .hsync_start = 1366 + 40, 383 + .hsync_end = 1366 + 40 + 40, 384 + .htotal = 1366 + 40 + 40 + 32, 385 + .vdisplay = 768, 386 + .vsync_start = 768 + 10, 387 + .vsync_end = 768 + 10 + 12, 388 + .vtotal = 768 + 10 + 12 + 6, 389 + .vrefresh = 60, 390 + }; 391 + 392 + static const struct panel_desc auo_b116xw03 = { 393 + .modes = &auo_b116xw03_mode, 394 + .num_modes = 1, 395 + .bpc = 6, 396 + .size = { 397 + .width = 256, 398 + .height = 144, 399 + }, 400 + }; 401 + 372 402 static const struct drm_display_mode auo_b133xtn01_mode = { 373 403 .clock = 69500, 374 404 .hdisplay = 1366, ··· 431 415 static const struct panel_desc auo_b133htn01 = { 432 416 .modes = &auo_b133htn01_mode, 433 417 .num_modes = 1, 418 + .bpc = 6, 434 419 .size = { 435 420 .width = 293, 436 421 .height = 165, ··· 553 536 static const struct panel_desc foxlink_fl500wvr00_a0t = { 554 537 .modes = &foxlink_fl500wvr00_a0t_mode, 555 538 .num_modes = 1, 539 + .bpc = 8, 556 540 .size = { 557 541 .width = 108, 558 542 .height = 65, 559 543 }, 560 544 }; 561 545 562 - static const struct drm_display_mode innolux_n116bge_mode = { 546 + static const struct drm_display_mode hannstar_hsd070pww1_mode = { 547 + .clock = 71100, 548 + .hdisplay = 1280, 549 + .hsync_start = 1280 + 1, 550 + .hsync_end = 1280 + 1 + 158, 551 + .htotal = 1280 + 1 + 158 + 1, 552 + .vdisplay = 800, 553 + .vsync_start = 800 + 1, 554 + .vsync_end = 800 + 1 + 21, 555 + .vtotal = 800 + 1 + 21 + 1, 556 + .vrefresh = 60, 557 + }; 558 + 559 + static const struct panel_desc hannstar_hsd070pww1 = { 560 + .modes = &hannstar_hsd070pww1_mode, 561 + .num_modes = 1, 562 + .bpc = 6, 563 + .size = { 564 + .width = 151, 565 + .height = 94, 566 + }, 567 + }; 568 + 569 + static const struct drm_display_mode hitachi_tx23d38vm0caa_mode = { 570 + .clock = 33333, 571 + .hdisplay = 800, 572 + .hsync_start = 800 + 85, 573 + .hsync_end = 800 + 85 + 86, 574 + .htotal = 800 + 85 + 86 + 85, 575 + .vdisplay = 480, 576 + .vsync_start = 480 + 16, 577 + .vsync_end = 480 + 16 + 13, 578 + .vtotal = 480 + 16 + 13 + 16, 579 + .vrefresh = 60, 580 + }; 581 + 582 + static const struct panel_desc hitachi_tx23d38vm0caa = { 583 + .modes = &hitachi_tx23d38vm0caa_mode, 584 + .num_modes = 1, 585 + .bpc = 6, 586 + .size = { 587 + .width = 195, 588 + .height = 117, 589 + }, 590 + }; 591 + 592 + static const struct drm_display_mode innolux_g121i1_l01_mode = { 563 593 .clock = 71000, 594 + .hdisplay = 1280, 595 + .hsync_start = 1280 + 64, 596 + .hsync_end = 1280 + 64 + 32, 597 + .htotal = 1280 + 64 + 32 + 64, 598 + .vdisplay = 800, 599 + .vsync_start = 800 + 9, 600 + .vsync_end = 800 + 9 + 6, 601 + .vtotal = 800 + 9 + 6 + 9, 602 + .vrefresh = 60, 603 + }; 604 + 605 + static const struct panel_desc innolux_g121i1_l01 = { 606 + .modes = &innolux_g121i1_l01_mode, 607 + .num_modes = 1, 608 + .bpc = 6, 609 + .size = { 610 + .width = 261, 611 + .height = 163, 612 + }, 613 + }; 614 + 615 + static const struct drm_display_mode innolux_n116bge_mode = { 616 + .clock = 76420, 564 617 .hdisplay = 1366, 565 - .hsync_start = 1366 + 64, 566 - .hsync_end = 1366 + 64 + 6, 567 - .htotal = 1366 + 64 + 6 + 64, 618 + .hsync_start = 1366 + 136, 619 + .hsync_end = 1366 + 136 + 30, 620 + .htotal = 1366 + 136 + 30 + 60, 568 621 .vdisplay = 768, 569 622 .vsync_start = 768 + 8, 570 - .vsync_end = 768 + 8 + 4, 571 - .vtotal = 768 + 8 + 4 + 8, 623 + .vsync_end = 768 + 8 + 12, 624 + .vtotal = 768 + 8 + 12 + 12, 572 625 .vrefresh = 60, 573 626 .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC, 574 627 }; ··· 730 643 .compatible = "auo,b101xtn01", 731 644 .data = &auo_b101xtn01, 732 645 }, { 646 + .compatible = "auo,b116xw03", 647 + .data = &auo_b116xw03, 648 + }, { 733 649 .compatible = "auo,b133htn01", 734 650 .data = &auo_b133htn01, 735 651 }, { ··· 756 666 }, { 757 667 .compatible = "foxlink,fl500wvr00-a0t", 758 668 .data = &foxlink_fl500wvr00_a0t, 669 + }, { 670 + .compatible = "hannstar,hsd070pww1", 671 + .data = &hannstar_hsd070pww1, 672 + }, { 673 + .compatible = "hit,tx23d38vm0caa", 674 + .data = &hitachi_tx23d38vm0caa 675 + }, { 676 + .compatible ="innolux,g121i1-l01", 677 + .data = &innolux_g121i1_l01 759 678 }, { 760 679 .compatible = "innolux,n116bge", 761 680 .data = &innolux_n116bge, ··· 840 741 .desc = { 841 742 .modes = &lg_ld070wx3_sl01_mode, 842 743 .num_modes = 1, 744 + .bpc = 8, 843 745 .size = { 844 746 .width = 94, 845 747 .height = 151, ··· 868 768 .desc = { 869 769 .modes = &lg_lh500wx1_sd03_mode, 870 770 .num_modes = 1, 771 + .bpc = 8, 871 772 .size = { 872 773 .width = 62, 873 774 .height = 110, ··· 896 795 .desc = { 897 796 .modes = &panasonic_vvx10f004b00_mode, 898 797 .num_modes = 1, 798 + .bpc = 8, 899 799 .size = { 900 800 .width = 217, 901 801 .height = 136, ··· 966 864 static struct mipi_dsi_driver panel_simple_dsi_driver = { 967 865 .driver = { 968 866 .name = "panel-simple-dsi", 969 - .owner = THIS_MODULE, 970 867 .of_match_table = dsi_of_match, 971 868 }, 972 869 .probe = panel_simple_dsi_probe,
+88 -6
include/drm/drm_mipi_dsi.h
··· 26 26 * struct mipi_dsi_msg - read/write DSI buffer 27 27 * @channel: virtual channel id 28 28 * @type: payload data type 29 + * @flags: flags controlling this message transmission 29 30 * @tx_len: length of @tx_buf 30 31 * @tx_buf: data to be written 31 32 * @rx_len: length of @rx_buf ··· 44 43 void *rx_buf; 45 44 }; 46 45 46 + bool mipi_dsi_packet_format_is_short(u8 type); 47 + bool mipi_dsi_packet_format_is_long(u8 type); 48 + 49 + /** 50 + * struct mipi_dsi_packet - represents a MIPI DSI packet in protocol format 51 + * @size: size (in bytes) of the packet 52 + * @header: the four bytes that make up the header (Data ID, Word Count or 53 + * Packet Data, and ECC) 54 + * @payload_length: number of bytes in the payload 55 + * @payload: a pointer to a buffer containing the payload, if any 56 + */ 57 + struct mipi_dsi_packet { 58 + size_t size; 59 + u8 header[4]; 60 + size_t payload_length; 61 + const u8 *payload; 62 + }; 63 + 64 + int mipi_dsi_create_packet(struct mipi_dsi_packet *packet, 65 + const struct mipi_dsi_msg *msg); 66 + 47 67 /** 48 68 * struct mipi_dsi_host_ops - DSI bus operations 49 69 * @attach: attach DSI device to DSI host 50 70 * @detach: detach DSI device from DSI host 51 - * @transfer: send and/or receive DSI packet, return number of received bytes, 52 - * or error 71 + * @transfer: transmit a DSI packet 72 + * 73 + * DSI packets transmitted by .transfer() are passed in as mipi_dsi_msg 74 + * structures. This structure contains information about the type of packet 75 + * being transmitted as well as the transmit and receive buffers. When an 76 + * error is encountered during transmission, this function will return a 77 + * negative error code. On success it shall return the number of bytes 78 + * transmitted for write packets or the number of bytes received for read 79 + * packets. 80 + * 81 + * Note that typically DSI packet transmission is atomic, so the .transfer() 82 + * function will seldomly return anything other than the number of bytes 83 + * contained in the transmit buffer on success. 53 84 */ 54 85 struct mipi_dsi_host_ops { 55 86 int (*attach)(struct mipi_dsi_host *host, ··· 89 56 int (*detach)(struct mipi_dsi_host *host, 90 57 struct mipi_dsi_device *dsi); 91 58 ssize_t (*transfer)(struct mipi_dsi_host *host, 92 - struct mipi_dsi_msg *msg); 59 + const struct mipi_dsi_msg *msg); 93 60 }; 94 61 95 62 /** ··· 163 130 return container_of(dev, struct mipi_dsi_device, dev); 164 131 } 165 132 133 + struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np); 166 134 int mipi_dsi_attach(struct mipi_dsi_device *dsi); 167 135 int mipi_dsi_detach(struct mipi_dsi_device *dsi); 168 - ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, const void *data, 169 - size_t len); 136 + int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi, 137 + u16 value); 138 + 139 + ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload, 140 + size_t size); 141 + ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params, 142 + size_t num_params, void *data, size_t size); 143 + 144 + /** 145 + * enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode 146 + * @MIPI_DSI_DCS_TEAR_MODE_VBLANK: the TE output line consists of V-Blanking 147 + * information only 148 + * @MIPI_DSI_DCS_TEAR_MODE_VHBLANK : the TE output line consists of both 149 + * V-Blanking and H-Blanking information 150 + */ 151 + enum mipi_dsi_dcs_tear_mode { 152 + MIPI_DSI_DCS_TEAR_MODE_VBLANK, 153 + MIPI_DSI_DCS_TEAR_MODE_VHBLANK, 154 + }; 155 + 156 + #define MIPI_DSI_DCS_POWER_MODE_DISPLAY (1 << 2) 157 + #define MIPI_DSI_DCS_POWER_MODE_NORMAL (1 << 3) 158 + #define MIPI_DSI_DCS_POWER_MODE_SLEEP (1 << 4) 159 + #define MIPI_DSI_DCS_POWER_MODE_PARTIAL (1 << 5) 160 + #define MIPI_DSI_DCS_POWER_MODE_IDLE (1 << 6) 161 + 162 + ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi, 163 + const void *data, size_t len); 164 + ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd, 165 + const void *data, size_t len); 170 166 ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, 171 167 size_t len); 168 + int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi); 169 + int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi); 170 + int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode); 171 + int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format); 172 + int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi); 173 + int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi); 174 + int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi); 175 + int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi); 176 + int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start, 177 + u16 end); 178 + int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start, 179 + u16 end); 180 + int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi); 181 + int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi, 182 + enum mipi_dsi_dcs_tear_mode mode); 183 + int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format); 172 184 173 185 /** 174 186 * struct mipi_dsi_driver - DSI driver ··· 245 167 dev_set_drvdata(&dsi->dev, data); 246 168 } 247 169 248 - int mipi_dsi_driver_register(struct mipi_dsi_driver *driver); 170 + int mipi_dsi_driver_register_full(struct mipi_dsi_driver *driver, 171 + struct module *owner); 249 172 void mipi_dsi_driver_unregister(struct mipi_dsi_driver *driver); 173 + 174 + #define mipi_dsi_driver_register(driver) \ 175 + mipi_dsi_driver_register_full(driver, THIS_MODULE) 250 176 251 177 #define module_mipi_dsi_driver(__mipi_dsi_driver) \ 252 178 module_driver(__mipi_dsi_driver, mipi_dsi_driver_register, \