2019-06-04 11:11:33 +03:00
/* SPDX-License-Identifier: GPL-2.0-only */
2013-12-04 19:35:12 +04:00
/*
* MIPI DSI Bus
*
* Copyright ( C ) 2012 - 2013 , Samsung Electronics , Co . , Ltd .
* Andrzej Hajda < a . hajda @ samsung . com >
*/
# ifndef __DRM_MIPI_DSI_H__
# define __DRM_MIPI_DSI_H__
# include <linux/device.h>
struct mipi_dsi_host ;
struct mipi_dsi_device ;
2019-10-28 18:00:47 +03:00
struct drm_dsc_picture_parameter_set ;
2013-12-04 19:35:12 +04:00
2014-03-28 15:52:36 +04:00
/* request ACK from peripheral */
# define MIPI_DSI_MSG_REQ_ACK BIT(0)
/* use Low Power Mode to transmit message */
# define MIPI_DSI_MSG_USE_LPM BIT(1)
2013-12-04 19:35:12 +04:00
/**
* struct mipi_dsi_msg - read / write DSI buffer
* @ channel : virtual channel id
* @ type : payload data type
2014-08-05 12:41:13 +04:00
* @ flags : flags controlling this message transmission
2013-12-04 19:35:12 +04:00
* @ tx_len : length of @ tx_buf
* @ tx_buf : data to be written
* @ rx_len : length of @ rx_buf
* @ rx_buf : data to be read , or NULL
*/
struct mipi_dsi_msg {
u8 channel ;
u8 type ;
2014-03-28 15:52:36 +04:00
u16 flags ;
2013-12-04 19:35:12 +04:00
size_t tx_len ;
const void * tx_buf ;
size_t rx_len ;
void * rx_buf ;
} ;
2014-11-04 16:59:14 +03:00
bool mipi_dsi_packet_format_is_short ( u8 type ) ;
bool mipi_dsi_packet_format_is_long ( u8 type ) ;
2014-10-16 15:44:02 +04:00
/**
* struct mipi_dsi_packet - represents a MIPI DSI packet in protocol format
* @ size : size ( in bytes ) of the packet
* @ header : the four bytes that make up the header ( Data ID , Word Count or
* Packet Data , and ECC )
* @ payload_length : number of bytes in the payload
* @ payload : a pointer to a buffer containing the payload , if any
*/
struct mipi_dsi_packet {
size_t size ;
u8 header [ 4 ] ;
size_t payload_length ;
const u8 * payload ;
} ;
int mipi_dsi_create_packet ( struct mipi_dsi_packet * packet ,
const struct mipi_dsi_msg * msg ) ;
2013-12-04 19:35:12 +04:00
/**
* struct mipi_dsi_host_ops - DSI bus operations
* @ attach : attach DSI device to DSI host
* @ detach : detach DSI device from DSI host
2014-08-05 12:41:13 +04:00
* @ transfer : transmit a DSI packet
*
* DSI packets transmitted by . transfer ( ) are passed in as mipi_dsi_msg
* structures . This structure contains information about the type of packet
* being transmitted as well as the transmit and receive buffers . When an
* error is encountered during transmission , this function will return a
* negative error code . On success it shall return the number of bytes
* transmitted for write packets or the number of bytes received for read
* packets .
*
* Note that typically DSI packet transmission is atomic , so the . transfer ( )
* function will seldomly return anything other than the number of bytes
* contained in the transmit buffer on success .
2021-06-16 17:15:29 +03:00
*
* Also note that those callbacks can be called no matter the state the
* host is in . Drivers that need the underlying device to be powered to
* perform these operations will first need to make sure it ' s been
* properly enabled .
2013-12-04 19:35:12 +04:00
*/
struct mipi_dsi_host_ops {
int ( * attach ) ( struct mipi_dsi_host * host ,
struct mipi_dsi_device * dsi ) ;
int ( * detach ) ( struct mipi_dsi_host * host ,
struct mipi_dsi_device * dsi ) ;
ssize_t ( * transfer ) ( struct mipi_dsi_host * host ,
2014-08-05 13:27:56 +04:00
const struct mipi_dsi_msg * msg ) ;
2013-12-04 19:35:12 +04:00
} ;
/**
* struct mipi_dsi_host - DSI host device
* @ dev : driver model device node for this DSI host
* @ ops : DSI host operations
2016-02-12 12:18:34 +03:00
* @ list : list management
2013-12-04 19:35:12 +04:00
*/
struct mipi_dsi_host {
struct device * dev ;
const struct mipi_dsi_host_ops * ops ;
2016-02-12 12:18:34 +03:00
struct list_head list ;
2013-12-04 19:35:12 +04:00
} ;
int mipi_dsi_host_register ( struct mipi_dsi_host * host ) ;
void mipi_dsi_host_unregister ( struct mipi_dsi_host * host ) ;
2016-02-12 12:18:34 +03:00
struct mipi_dsi_host * of_find_mipi_dsi_host_by_node ( struct device_node * node ) ;
2013-12-04 19:35:12 +04:00
/* DSI mode flags */
/* video mode */
# define MIPI_DSI_MODE_VIDEO BIT(0)
/* video burst mode */
# define MIPI_DSI_MODE_VIDEO_BURST BIT(1)
/* video pulse mode */
# define MIPI_DSI_MODE_VIDEO_SYNC_PULSE BIT(2)
/* enable auto vertical count mode */
# define MIPI_DSI_MODE_VIDEO_AUTO_VERT BIT(3)
/* enable hsync-end packets in vsync-pulse and v-porch area */
# define MIPI_DSI_MODE_VIDEO_HSE BIT(4)
/* disable hfront-porch area */
2021-07-27 04:45:21 +03:00
# define MIPI_DSI_MODE_VIDEO_NO_HFP BIT(5)
2013-12-04 19:35:12 +04:00
/* disable hback-porch area */
2021-07-27 04:45:21 +03:00
# define MIPI_DSI_MODE_VIDEO_NO_HBP BIT(6)
2013-12-04 19:35:12 +04:00
/* disable hsync-active area */
2021-07-27 04:45:21 +03:00
# define MIPI_DSI_MODE_VIDEO_NO_HSA BIT(7)
2013-12-04 19:35:12 +04:00
/* flush display FIFO on vsync pulse */
# define MIPI_DSI_MODE_VSYNC_FLUSH BIT(8)
/* disable EoT packets in HS mode */
2021-07-27 04:45:21 +03:00
# define MIPI_DSI_MODE_NO_EOT_PACKET BIT(9)
2014-07-08 16:32:11 +04:00
/* device supports non-continuous clock behavior (DSI spec 5.6.1) */
# define MIPI_DSI_CLOCK_NON_CONTINUOUS BIT(10)
2014-08-13 11:38:23 +04:00
/* transmit data in low power */
# define MIPI_DSI_MODE_LPM BIT(11)
2022-03-09 10:36:35 +03:00
/* transmit data ending at the same time for all lanes within one hsync */
# define MIPI_DSI_HS_PKT_END_ALIGNED BIT(12)
2013-12-04 19:35:12 +04:00
enum mipi_dsi_pixel_format {
MIPI_DSI_FMT_RGB888 ,
MIPI_DSI_FMT_RGB666 ,
MIPI_DSI_FMT_RGB666_PACKED ,
MIPI_DSI_FMT_RGB565 ,
} ;
2016-02-12 12:18:32 +03:00
# define DSI_DEV_NAME_SIZE 20
/**
2016-02-12 12:18:31 +03:00
* struct mipi_dsi_device_info - template for creating a mipi_dsi_device
2016-02-12 12:18:32 +03:00
* @ type : DSI peripheral chip type
2016-02-12 12:18:31 +03:00
* @ channel : DSI virtual channel assigned to peripheral
2016-02-12 12:18:32 +03:00
* @ node : pointer to OF device node or NULL
2016-02-12 12:18:31 +03:00
*
* This is populated and passed to mipi_dsi_device_new to create a new
* DSI device
*/
struct mipi_dsi_device_info {
2016-02-12 12:18:32 +03:00
char type [ DSI_DEV_NAME_SIZE ] ;
2016-02-12 12:18:31 +03:00
u32 channel ;
struct device_node * node ;
} ;
2013-12-04 19:35:12 +04:00
/**
* struct mipi_dsi_device - DSI peripheral device
* @ host : DSI host for this peripheral
* @ dev : driver model device node for this peripheral
2016-02-12 12:18:32 +03:00
* @ name : DSI peripheral chip type
2013-12-04 19:35:12 +04:00
* @ channel : virtual channel assigned to the peripheral
* @ format : pixel format for video mode
* @ lanes : number of active data lanes
* @ mode_flags : DSI operation mode related flags
2018-10-23 10:24:22 +03:00
* @ hs_rate : maximum lane frequency for high speed mode in hertz , this should
* be set to the real limits of the hardware , zero is only accepted for
* legacy drivers
* @ lp_rate : maximum lane frequency for low power mode in hertz , this should
* be set to the real limits of the hardware , zero is only accepted for
* legacy drivers
2022-07-11 12:43:17 +03:00
* @ dsc : panel / bridge DSC pps payload to be sent
2013-12-04 19:35:12 +04:00
*/
struct mipi_dsi_device {
struct mipi_dsi_host * host ;
struct device dev ;
2016-02-12 12:18:32 +03:00
char name [ DSI_DEV_NAME_SIZE ] ;
2013-12-04 19:35:12 +04:00
unsigned int channel ;
unsigned int lanes ;
enum mipi_dsi_pixel_format format ;
unsigned long mode_flags ;
2018-10-23 10:24:22 +03:00
unsigned long hs_rate ;
unsigned long lp_rate ;
2022-07-11 12:43:17 +03:00
struct drm_dsc_config * dsc ;
2013-12-04 19:35:12 +04:00
} ;
2016-06-03 15:23:00 +03:00
# define MIPI_DSI_MODULE_PREFIX "mipi-dsi:"
2023-01-11 14:30:14 +03:00
# define to_mipi_dsi_device(__dev) container_of_const(__dev, struct mipi_dsi_device, dev)
2013-12-04 19:35:12 +04:00
2015-11-20 11:15:30 +03:00
/**
* mipi_dsi_pixel_format_to_bpp - obtain the number of bits per pixel for any
* given pixel format defined by the MIPI DSI
* specification
* @ fmt : MIPI DSI pixel format
*
* Returns : The number of bits per pixel of the given pixel format .
*/
static inline int mipi_dsi_pixel_format_to_bpp ( enum mipi_dsi_pixel_format fmt )
{
switch ( fmt ) {
case MIPI_DSI_FMT_RGB888 :
case MIPI_DSI_FMT_RGB666 :
return 24 ;
case MIPI_DSI_FMT_RGB666_PACKED :
return 18 ;
case MIPI_DSI_FMT_RGB565 :
return 16 ;
}
return - EINVAL ;
}
2016-02-12 12:18:31 +03:00
struct mipi_dsi_device *
mipi_dsi_device_register_full ( struct mipi_dsi_host * host ,
const struct mipi_dsi_device_info * info ) ;
2016-02-12 12:18:33 +03:00
void mipi_dsi_device_unregister ( struct mipi_dsi_device * dsi ) ;
2021-09-10 13:11:57 +03:00
struct mipi_dsi_device *
devm_mipi_dsi_device_register_full ( struct device * dev , struct mipi_dsi_host * host ,
const struct mipi_dsi_device_info * info ) ;
2014-08-06 10:53:39 +04:00
struct mipi_dsi_device * of_find_mipi_dsi_device_by_node ( struct device_node * np ) ;
2013-12-04 19:35:12 +04:00
int mipi_dsi_attach ( struct mipi_dsi_device * dsi ) ;
int mipi_dsi_detach ( struct mipi_dsi_device * dsi ) ;
2021-09-10 13:11:58 +03:00
int devm_mipi_dsi_attach ( struct device * dev , struct mipi_dsi_device * dsi ) ;
2015-10-31 03:38:26 +03:00
int mipi_dsi_shutdown_peripheral ( struct mipi_dsi_device * dsi ) ;
int mipi_dsi_turn_on_peripheral ( struct mipi_dsi_device * dsi ) ;
2014-08-05 11:27:15 +04:00
int mipi_dsi_set_maximum_return_packet_size ( struct mipi_dsi_device * dsi ,
u16 value ) ;
2019-10-28 18:00:47 +03:00
ssize_t mipi_dsi_compression_mode ( struct mipi_dsi_device * dsi , bool enable ) ;
ssize_t mipi_dsi_picture_parameter_set ( struct mipi_dsi_device * dsi ,
const struct drm_dsc_picture_parameter_set * pps ) ;
2014-08-05 12:36:21 +04:00
ssize_t mipi_dsi_generic_write ( struct mipi_dsi_device * dsi , const void * payload ,
size_t size ) ;
ssize_t mipi_dsi_generic_read ( struct mipi_dsi_device * dsi , const void * params ,
size_t num_params , void * data , size_t size ) ;
2014-08-05 12:38:31 +04:00
/**
* enum mipi_dsi_dcs_tear_mode - Tearing Effect Output Line mode
* @ MIPI_DSI_DCS_TEAR_MODE_VBLANK : the TE output line consists of V - Blanking
* information only
* @ MIPI_DSI_DCS_TEAR_MODE_VHBLANK : the TE output line consists of both
* V - Blanking and H - Blanking information
*/
enum mipi_dsi_dcs_tear_mode {
MIPI_DSI_DCS_TEAR_MODE_VBLANK ,
MIPI_DSI_DCS_TEAR_MODE_VHBLANK ,
} ;
2014-08-05 13:17:06 +04:00
# define MIPI_DSI_DCS_POWER_MODE_DISPLAY (1 << 2)
# define MIPI_DSI_DCS_POWER_MODE_NORMAL (1 << 3)
# define MIPI_DSI_DCS_POWER_MODE_SLEEP (1 << 4)
# define MIPI_DSI_DCS_POWER_MODE_PARTIAL (1 << 5)
# define MIPI_DSI_DCS_POWER_MODE_IDLE (1 << 6)
2014-07-21 17:47:10 +04:00
ssize_t mipi_dsi_dcs_write_buffer ( struct mipi_dsi_device * dsi ,
const void * data , size_t len ) ;
ssize_t mipi_dsi_dcs_write ( struct mipi_dsi_device * dsi , u8 cmd ,
const void * data , size_t len ) ;
2014-07-21 14:28:25 +04:00
ssize_t mipi_dsi_dcs_read ( struct mipi_dsi_device * dsi , u8 cmd , void * data ,
size_t len ) ;
2014-08-05 13:14:02 +04:00
int mipi_dsi_dcs_nop ( struct mipi_dsi_device * dsi ) ;
2014-08-05 13:15:15 +04:00
int mipi_dsi_dcs_soft_reset ( struct mipi_dsi_device * dsi ) ;
2014-08-05 13:17:06 +04:00
int mipi_dsi_dcs_get_power_mode ( struct mipi_dsi_device * dsi , u8 * mode ) ;
2014-08-05 13:18:46 +04:00
int mipi_dsi_dcs_get_pixel_format ( struct mipi_dsi_device * dsi , u8 * format ) ;
2014-08-05 12:38:31 +04:00
int mipi_dsi_dcs_enter_sleep_mode ( struct mipi_dsi_device * dsi ) ;
int mipi_dsi_dcs_exit_sleep_mode ( struct mipi_dsi_device * dsi ) ;
int mipi_dsi_dcs_set_display_off ( struct mipi_dsi_device * dsi ) ;
int mipi_dsi_dcs_set_display_on ( struct mipi_dsi_device * dsi ) ;
2014-08-05 13:20:25 +04:00
int mipi_dsi_dcs_set_column_address ( struct mipi_dsi_device * dsi , u16 start ,
u16 end ) ;
int mipi_dsi_dcs_set_page_address ( struct mipi_dsi_device * dsi , u16 start ,
u16 end ) ;
2014-08-05 12:38:31 +04:00
int mipi_dsi_dcs_set_tear_off ( struct mipi_dsi_device * dsi ) ;
int mipi_dsi_dcs_set_tear_on ( struct mipi_dsi_device * dsi ,
enum mipi_dsi_dcs_tear_mode mode ) ;
2014-08-05 13:18:46 +04:00
int mipi_dsi_dcs_set_pixel_format ( struct mipi_dsi_device * dsi , u8 format ) ;
2016-08-24 14:28:39 +03:00
int mipi_dsi_dcs_set_tear_scanline ( struct mipi_dsi_device * dsi , u16 scanline ) ;
2016-07-31 18:15:22 +03:00
int mipi_dsi_dcs_set_display_brightness ( struct mipi_dsi_device * dsi ,
u16 brightness ) ;
int mipi_dsi_dcs_get_display_brightness ( struct mipi_dsi_device * dsi ,
u16 * brightness ) ;
2023-01-17 01:49:07 +03:00
int mipi_dsi_dcs_set_display_brightness_large ( struct mipi_dsi_device * dsi ,
u16 brightness ) ;
int mipi_dsi_dcs_get_display_brightness_large ( struct mipi_dsi_device * dsi ,
u16 * brightness ) ;
2013-12-04 19:35:12 +04:00
2023-01-02 23:25:42 +03:00
/**
* mipi_dsi_generic_write_seq - transmit data using a generic write packet
* @ dsi : DSI peripheral device
* @ seq : buffer containing the payload
*/
# define mipi_dsi_generic_write_seq(dsi, seq...) \
do { \
static const u8 d [ ] = { seq } ; \
struct device * dev = & dsi - > dev ; \
int ret ; \
ret = mipi_dsi_generic_write ( dsi , d , ARRAY_SIZE ( d ) ) ; \
if ( ret < 0 ) { \
dev_err_ratelimited ( dev , " transmit data failed: %d \n " , \
ret ) ; \
return ret ; \
} \
} while ( 0 )
2022-06-01 11:24:09 +03:00
/**
* mipi_dsi_dcs_write_seq - transmit a DCS command with payload
* @ dsi : DSI peripheral device
* @ cmd : Command
* @ seq : buffer containing data to be transmitted
*/
2023-01-02 23:25:41 +03:00
# define mipi_dsi_dcs_write_seq(dsi, cmd, seq...) \
do { \
static const u8 d [ ] = { cmd , seq } ; \
struct device * dev = & dsi - > dev ; \
int ret ; \
ret = mipi_dsi_dcs_write_buffer ( dsi , d , ARRAY_SIZE ( d ) ) ; \
if ( ret < 0 ) { \
dev_err_ratelimited ( \
dev , " sending command %#02x failed: %d \n " , \
cmd , ret ) ; \
return ret ; \
} \
2022-06-01 11:24:09 +03:00
} while ( 0 )
2013-12-04 19:35:12 +04:00
/**
* struct mipi_dsi_driver - DSI driver
* @ driver : device driver model driver
* @ probe : callback for device binding
* @ remove : callback for device unbinding
2014-04-29 19:19:57 +04:00
* @ shutdown : called at shutdown time to quiesce the device
2013-12-04 19:35:12 +04:00
*/
struct mipi_dsi_driver {
struct device_driver driver ;
int ( * probe ) ( struct mipi_dsi_device * dsi ) ;
2022-07-08 12:49:22 +03:00
void ( * remove ) ( struct mipi_dsi_device * dsi ) ;
2014-04-29 19:19:57 +04:00
void ( * shutdown ) ( struct mipi_dsi_device * dsi ) ;
2013-12-04 19:35:12 +04:00
} ;
2014-08-05 11:01:32 +04:00
static inline struct mipi_dsi_driver *
to_mipi_dsi_driver ( struct device_driver * driver )
{
return container_of ( driver , struct mipi_dsi_driver , driver ) ;
}
2013-12-04 19:35:12 +04:00
static inline void * mipi_dsi_get_drvdata ( const struct mipi_dsi_device * dsi )
{
return dev_get_drvdata ( & dsi - > dev ) ;
}
static inline void mipi_dsi_set_drvdata ( struct mipi_dsi_device * dsi , void * data )
{
dev_set_drvdata ( & dsi - > dev , data ) ;
}
2014-11-04 18:09:56 +03:00
int mipi_dsi_driver_register_full ( struct mipi_dsi_driver * driver ,
struct module * owner ) ;
2013-12-04 19:35:12 +04:00
void mipi_dsi_driver_unregister ( struct mipi_dsi_driver * driver ) ;
2014-11-04 18:09:56 +03:00
# define mipi_dsi_driver_register(driver) \
mipi_dsi_driver_register_full ( driver , THIS_MODULE )
2013-12-04 19:35:12 +04:00
# define module_mipi_dsi_driver(__mipi_dsi_driver) \
module_driver ( __mipi_dsi_driver , mipi_dsi_driver_register , \
mipi_dsi_driver_unregister )
# endif /* __DRM_MIPI_DSI__ */