2012-03-08 16:02:20 +00:00
/*
* Copyright © 2010 Intel Corporation
*
* Permission is hereby granted , free of charge , to any person obtaining a
* copy of this software and associated documentation files ( the " Software " ) ,
* to deal in the Software without restriction , including without limitation
* the rights to use , copy , modify , merge , publish , distribute , sublicense ,
* and / or sell copies of the Software , and to permit persons to whom the
* Software is furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice ( including the next
* paragraph ) shall be included in all copies or substantial portions of the
* Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING
* FROM , OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE .
*
* Authors :
* Jackie Li < yaodong . li @ intel . com >
*/
# include <linux/freezer.h>
# include "mdfld_dsi_output.h"
# include "mdfld_dsi_pkg_sender.h"
# include "mdfld_dsi_dpi.h"
# define MDFLD_DSI_READ_MAX_COUNT 5000
enum data_type {
DSI_DT_GENERIC_SHORT_WRITE_0 = 0x03 ,
DSI_DT_GENERIC_SHORT_WRITE_1 = 0x13 ,
DSI_DT_GENERIC_SHORT_WRITE_2 = 0x23 ,
DSI_DT_GENERIC_READ_0 = 0x04 ,
DSI_DT_GENERIC_READ_1 = 0x14 ,
DSI_DT_GENERIC_READ_2 = 0x24 ,
DSI_DT_GENERIC_LONG_WRITE = 0x29 ,
DSI_DT_DCS_SHORT_WRITE_0 = 0x05 ,
DSI_DT_DCS_SHORT_WRITE_1 = 0x15 ,
DSI_DT_DCS_READ = 0x06 ,
DSI_DT_DCS_LONG_WRITE = 0x39 ,
} ;
enum {
MDFLD_DSI_PANEL_MODE_SLEEP = 0x1 ,
} ;
enum {
MDFLD_DSI_PKG_SENDER_FREE = 0x0 ,
MDFLD_DSI_PKG_SENDER_BUSY = 0x1 ,
} ;
static const char * const dsi_errors [ ] = {
" RX SOT Error " ,
" RX SOT Sync Error " ,
" RX EOT Sync Error " ,
" RX Escape Mode Entry Error " ,
" RX LP TX Sync Error " ,
" RX HS Receive Timeout Error " ,
" RX False Control Error " ,
" RX ECC Single Bit Error " ,
" RX ECC Multibit Error " ,
" RX Checksum Error " ,
" RX DSI Data Type Not Recognised " ,
" RX DSI VC ID Invalid " ,
" TX False Control Error " ,
" TX ECC Single Bit Error " ,
" TX ECC Multibit Error " ,
" TX Checksum Error " ,
" TX DSI Data Type Not Recognised " ,
" TX DSI VC ID invalid " ,
" High Contention " ,
" Low contention " ,
" DPI FIFO Under run " ,
" HS TX Timeout " ,
" LP RX Timeout " ,
" Turn Around ACK Timeout " ,
" ACK With No Error " ,
" RX Invalid TX Length " ,
" RX Prot Violation " ,
" HS Generic Write FIFO Full " ,
" LP Generic Write FIFO Full " ,
" Generic Read Data Avail "
" Special Packet Sent " ,
" Tearing Effect " ,
} ;
static inline int wait_for_gen_fifo_empty ( struct mdfld_dsi_pkg_sender * sender ,
u32 mask )
{
struct drm_device * dev = sender - > dev ;
u32 gen_fifo_stat_reg = sender - > mipi_gen_fifo_stat_reg ;
int retry = 0xffff ;
while ( retry - - ) {
if ( ( mask & REG_READ ( gen_fifo_stat_reg ) ) = = mask )
return 0 ;
udelay ( 100 ) ;
}
DRM_ERROR ( " fifo is NOT empty 0x%08x \n " , REG_READ ( gen_fifo_stat_reg ) ) ;
return - EIO ;
}
static int wait_for_all_fifos_empty ( struct mdfld_dsi_pkg_sender * sender )
{
return wait_for_gen_fifo_empty ( sender , ( BIT ( 2 ) | BIT ( 10 ) | BIT ( 18 ) |
BIT ( 26 ) | BIT ( 27 ) | BIT ( 28 ) ) ) ;
}
static int wait_for_lp_fifos_empty ( struct mdfld_dsi_pkg_sender * sender )
{
return wait_for_gen_fifo_empty ( sender , ( BIT ( 10 ) | BIT ( 26 ) ) ) ;
}
static int wait_for_hs_fifos_empty ( struct mdfld_dsi_pkg_sender * sender )
{
return wait_for_gen_fifo_empty ( sender , ( BIT ( 2 ) | BIT ( 18 ) ) ) ;
}
static int handle_dsi_error ( struct mdfld_dsi_pkg_sender * sender , u32 mask )
{
u32 intr_stat_reg = sender - > mipi_intr_stat_reg ;
struct drm_device * dev = sender - > dev ;
dev_dbg ( sender - > dev - > dev , " Handling error 0x%08x \n " , mask ) ;
switch ( mask ) {
case BIT ( 0 ) :
case BIT ( 1 ) :
case BIT ( 2 ) :
case BIT ( 3 ) :
case BIT ( 4 ) :
case BIT ( 5 ) :
case BIT ( 6 ) :
case BIT ( 7 ) :
case BIT ( 8 ) :
case BIT ( 9 ) :
case BIT ( 10 ) :
case BIT ( 11 ) :
case BIT ( 12 ) :
case BIT ( 13 ) :
dev_dbg ( sender - > dev - > dev , " No Action required \n " ) ;
break ;
case BIT ( 14 ) :
/*wait for all fifo empty*/
/*wait_for_all_fifos_empty(sender)*/ ;
break ;
case BIT ( 15 ) :
dev_dbg ( sender - > dev - > dev , " No Action required \n " ) ;
break ;
case BIT ( 16 ) :
break ;
case BIT ( 17 ) :
break ;
case BIT ( 18 ) :
case BIT ( 19 ) :
dev_dbg ( sender - > dev - > dev , " High/Low contention detected \n " ) ;
/*wait for contention recovery time*/
/*mdelay(10);*/
/*wait for all fifo empty*/
if ( 0 )
wait_for_all_fifos_empty ( sender ) ;
break ;
case BIT ( 20 ) :
dev_dbg ( sender - > dev - > dev , " No Action required \n " ) ;
break ;
case BIT ( 21 ) :
/*wait for all fifo empty*/
/*wait_for_all_fifos_empty(sender);*/
break ;
case BIT ( 22 ) :
break ;
case BIT ( 23 ) :
case BIT ( 24 ) :
case BIT ( 25 ) :
case BIT ( 26 ) :
case BIT ( 27 ) :
dev_dbg ( sender - > dev - > dev , " HS Gen fifo full \n " ) ;
REG_WRITE ( intr_stat_reg , mask ) ;
wait_for_hs_fifos_empty ( sender ) ;
break ;
case BIT ( 28 ) :
dev_dbg ( sender - > dev - > dev , " LP Gen fifo full \n " ) ;
REG_WRITE ( intr_stat_reg , mask ) ;
wait_for_lp_fifos_empty ( sender ) ;
break ;
case BIT ( 29 ) :
case BIT ( 30 ) :
case BIT ( 31 ) :
dev_dbg ( sender - > dev - > dev , " No Action required \n " ) ;
break ;
}
if ( mask & REG_READ ( intr_stat_reg ) )
dev_dbg ( sender - > dev - > dev ,
" Cannot clean interrupt 0x%08x \n " , mask ) ;
return 0 ;
}
static int dsi_error_handler ( struct mdfld_dsi_pkg_sender * sender )
{
struct drm_device * dev = sender - > dev ;
u32 intr_stat_reg = sender - > mipi_intr_stat_reg ;
u32 mask ;
u32 intr_stat ;
int i ;
int err = 0 ;
intr_stat = REG_READ ( intr_stat_reg ) ;
for ( i = 0 ; i < 32 ; i + + ) {
mask = ( 0x00000001UL ) < < i ;
if ( intr_stat & mask ) {
dev_dbg ( sender - > dev - > dev , " [DSI]: %s \n " , dsi_errors [ i ] ) ;
err = handle_dsi_error ( sender , mask ) ;
if ( err )
DRM_ERROR ( " Cannot handle error \n " ) ;
}
}
return err ;
}
static int send_short_pkg ( struct mdfld_dsi_pkg_sender * sender , u8 data_type ,
u8 cmd , u8 param , bool hs )
{
struct drm_device * dev = sender - > dev ;
u32 ctrl_reg ;
u32 val ;
u8 virtual_channel = 0 ;
if ( hs ) {
ctrl_reg = sender - > mipi_hs_gen_ctrl_reg ;
/* FIXME: wait_for_hs_fifos_empty(sender); */
} else {
ctrl_reg = sender - > mipi_lp_gen_ctrl_reg ;
/* FIXME: wait_for_lp_fifos_empty(sender); */
}
val = FLD_VAL ( param , 23 , 16 ) | FLD_VAL ( cmd , 15 , 8 ) |
FLD_VAL ( virtual_channel , 7 , 6 ) | FLD_VAL ( data_type , 5 , 0 ) ;
REG_WRITE ( ctrl_reg , val ) ;
return 0 ;
}
static int send_long_pkg ( struct mdfld_dsi_pkg_sender * sender , u8 data_type ,
u8 * data , int len , bool hs )
{
struct drm_device * dev = sender - > dev ;
u32 ctrl_reg ;
u32 data_reg ;
u32 val ;
u8 * p ;
u8 b1 , b2 , b3 , b4 ;
u8 virtual_channel = 0 ;
int i ;
if ( hs ) {
ctrl_reg = sender - > mipi_hs_gen_ctrl_reg ;
data_reg = sender - > mipi_hs_gen_data_reg ;
/* FIXME: wait_for_hs_fifos_empty(sender); */
} else {
ctrl_reg = sender - > mipi_lp_gen_ctrl_reg ;
data_reg = sender - > mipi_lp_gen_data_reg ;
/* FIXME: wait_for_lp_fifos_empty(sender); */
}
p = data ;
for ( i = 0 ; i < len / 4 ; i + + ) {
b1 = * p + + ;
b2 = * p + + ;
b3 = * p + + ;
b4 = * p + + ;
REG_WRITE ( data_reg , b4 < < 24 | b3 < < 16 | b2 < < 8 | b1 ) ;
}
i = len % 4 ;
if ( i ) {
b1 = 0 ; b2 = 0 ; b3 = 0 ;
switch ( i ) {
case 3 :
b1 = * p + + ;
b2 = * p + + ;
b3 = * p + + ;
break ;
case 2 :
b1 = * p + + ;
b2 = * p + + ;
break ;
case 1 :
b1 = * p + + ;
break ;
}
REG_WRITE ( data_reg , b3 < < 16 | b2 < < 8 | b1 ) ;
}
val = FLD_VAL ( len , 23 , 8 ) | FLD_VAL ( virtual_channel , 7 , 6 ) |
FLD_VAL ( data_type , 5 , 0 ) ;
REG_WRITE ( ctrl_reg , val ) ;
return 0 ;
}
static int send_pkg_prepare ( struct mdfld_dsi_pkg_sender * sender , u8 data_type ,
u8 * data , u16 len )
{
u8 cmd ;
switch ( data_type ) {
case DSI_DT_DCS_SHORT_WRITE_0 :
case DSI_DT_DCS_SHORT_WRITE_1 :
case DSI_DT_DCS_LONG_WRITE :
cmd = * data ;
break ;
default :
return 0 ;
}
/*this prevents other package sending while doing msleep*/
sender - > status = MDFLD_DSI_PKG_SENDER_BUSY ;
/*wait for 120 milliseconds in case exit_sleep_mode just be sent*/
if ( unlikely ( cmd = = DCS_ENTER_SLEEP_MODE ) ) {
/*TODO: replace it with msleep later*/
mdelay ( 120 ) ;
}
if ( unlikely ( cmd = = DCS_EXIT_SLEEP_MODE ) ) {
/*TODO: replace it with msleep later*/
mdelay ( 120 ) ;
}
return 0 ;
}
static int send_pkg_done ( struct mdfld_dsi_pkg_sender * sender , u8 data_type ,
u8 * data , u16 len )
{
u8 cmd ;
switch ( data_type ) {
case DSI_DT_DCS_SHORT_WRITE_0 :
case DSI_DT_DCS_SHORT_WRITE_1 :
case DSI_DT_DCS_LONG_WRITE :
cmd = * data ;
break ;
default :
return 0 ;
}
/*update panel status*/
if ( unlikely ( cmd = = DCS_ENTER_SLEEP_MODE ) ) {
sender - > panel_mode | = MDFLD_DSI_PANEL_MODE_SLEEP ;
/*TODO: replace it with msleep later*/
mdelay ( 120 ) ;
} else if ( unlikely ( cmd = = DCS_EXIT_SLEEP_MODE ) ) {
sender - > panel_mode & = ~ MDFLD_DSI_PANEL_MODE_SLEEP ;
/*TODO: replace it with msleep later*/
mdelay ( 120 ) ;
} else if ( unlikely ( cmd = = DCS_SOFT_RESET ) ) {
/*TODO: replace it with msleep later*/
mdelay ( 5 ) ;
}
sender - > status = MDFLD_DSI_PKG_SENDER_FREE ;
return 0 ;
}
static int send_pkg ( struct mdfld_dsi_pkg_sender * sender , u8 data_type ,
u8 * data , u16 len , bool hs )
{
int ret ;
/*handle DSI error*/
ret = dsi_error_handler ( sender ) ;
if ( ret ) {
DRM_ERROR ( " Error handling failed \n " ) ;
return - EAGAIN ;
}
/* send pkg */
if ( sender - > status = = MDFLD_DSI_PKG_SENDER_BUSY ) {
DRM_ERROR ( " sender is busy \n " ) ;
return - EAGAIN ;
}
ret = send_pkg_prepare ( sender , data_type , data , len ) ;
if ( ret ) {
DRM_ERROR ( " send_pkg_prepare error \n " ) ;
return ret ;
}
switch ( data_type ) {
case DSI_DT_GENERIC_SHORT_WRITE_0 :
case DSI_DT_GENERIC_SHORT_WRITE_1 :
case DSI_DT_GENERIC_SHORT_WRITE_2 :
case DSI_DT_GENERIC_READ_0 :
case DSI_DT_GENERIC_READ_1 :
case DSI_DT_GENERIC_READ_2 :
case DSI_DT_DCS_SHORT_WRITE_0 :
case DSI_DT_DCS_SHORT_WRITE_1 :
case DSI_DT_DCS_READ :
ret = send_short_pkg ( sender , data_type , data [ 0 ] , data [ 1 ] , hs ) ;
break ;
case DSI_DT_GENERIC_LONG_WRITE :
case DSI_DT_DCS_LONG_WRITE :
ret = send_long_pkg ( sender , data_type , data , len , hs ) ;
break ;
}
send_pkg_done ( sender , data_type , data , len ) ;
/*FIXME: should I query complete and fifo empty here?*/
return ret ;
}
int mdfld_dsi_send_mcs_long ( struct mdfld_dsi_pkg_sender * sender , u8 * data ,
u32 len , bool hs )
{
unsigned long flags ;
if ( ! sender | | ! data | | ! len ) {
DRM_ERROR ( " Invalid parameters \n " ) ;
return - EINVAL ;
}
spin_lock_irqsave ( & sender - > lock , flags ) ;
send_pkg ( sender , DSI_DT_DCS_LONG_WRITE , data , len , hs ) ;
spin_unlock_irqrestore ( & sender - > lock , flags ) ;
return 0 ;
}
int mdfld_dsi_send_mcs_short ( struct mdfld_dsi_pkg_sender * sender , u8 cmd ,
u8 param , u8 param_num , bool hs )
{
u8 data [ 2 ] ;
unsigned long flags ;
u8 data_type ;
if ( ! sender ) {
DRM_ERROR ( " Invalid parameter \n " ) ;
return - EINVAL ;
}
data [ 0 ] = cmd ;
if ( param_num ) {
data_type = DSI_DT_DCS_SHORT_WRITE_1 ;
data [ 1 ] = param ;
} else {
data_type = DSI_DT_DCS_SHORT_WRITE_0 ;
data [ 1 ] = 0 ;
}
spin_lock_irqsave ( & sender - > lock , flags ) ;
send_pkg ( sender , data_type , data , sizeof ( data ) , hs ) ;
spin_unlock_irqrestore ( & sender - > lock , flags ) ;
return 0 ;
}
int mdfld_dsi_send_gen_short ( struct mdfld_dsi_pkg_sender * sender , u8 param0 ,
u8 param1 , u8 param_num , bool hs )
{
u8 data [ 2 ] ;
unsigned long flags ;
u8 data_type ;
2012-03-08 16:11:38 +00:00
if ( ! sender | | param_num > 2 ) {
2012-03-08 16:02:20 +00:00
DRM_ERROR ( " Invalid parameter \n " ) ;
return - EINVAL ;
}
switch ( param_num ) {
case 0 :
data_type = DSI_DT_GENERIC_SHORT_WRITE_0 ;
data [ 0 ] = 0 ;
data [ 1 ] = 0 ;
break ;
case 1 :
data_type = DSI_DT_GENERIC_SHORT_WRITE_1 ;
data [ 0 ] = param0 ;
data [ 1 ] = 0 ;
break ;
case 2 :
data_type = DSI_DT_GENERIC_SHORT_WRITE_2 ;
data [ 0 ] = param0 ;
data [ 1 ] = param1 ;
break ;
}
spin_lock_irqsave ( & sender - > lock , flags ) ;
send_pkg ( sender , data_type , data , sizeof ( data ) , hs ) ;
spin_unlock_irqrestore ( & sender - > lock , flags ) ;
return 0 ;
}
int mdfld_dsi_send_gen_long ( struct mdfld_dsi_pkg_sender * sender , u8 * data ,
u32 len , bool hs )
{
unsigned long flags ;
if ( ! sender | | ! data | | ! len ) {
DRM_ERROR ( " Invalid parameters \n " ) ;
return - EINVAL ;
}
spin_lock_irqsave ( & sender - > lock , flags ) ;
send_pkg ( sender , DSI_DT_GENERIC_LONG_WRITE , data , len , hs ) ;
spin_unlock_irqrestore ( & sender - > lock , flags ) ;
return 0 ;
}
static int __read_panel_data ( struct mdfld_dsi_pkg_sender * sender , u8 data_type ,
u8 * data , u16 len , u32 * data_out , u16 len_out , bool hs )
{
unsigned long flags ;
struct drm_device * dev = sender - > dev ;
int i ;
u32 gen_data_reg ;
int retry = MDFLD_DSI_READ_MAX_COUNT ;
if ( ! sender | | ! data_out | | ! len_out ) {
DRM_ERROR ( " Invalid parameters \n " ) ;
return - EINVAL ;
}
/**
* do reading .
* 0 ) send out generic read request
* 1 ) polling read data avail interrupt
* 2 ) read data
*/
spin_lock_irqsave ( & sender - > lock , flags ) ;
REG_WRITE ( sender - > mipi_intr_stat_reg , BIT ( 29 ) ) ;
if ( ( REG_READ ( sender - > mipi_intr_stat_reg ) & BIT ( 29 ) ) )
DRM_ERROR ( " Can NOT clean read data valid interrupt \n " ) ;
/*send out read request*/
send_pkg ( sender , data_type , data , len , hs ) ;
/*polling read data avail interrupt*/
while ( retry & & ! ( REG_READ ( sender - > mipi_intr_stat_reg ) & BIT ( 29 ) ) ) {
udelay ( 100 ) ;
retry - - ;
}
if ( ! retry ) {
spin_unlock_irqrestore ( & sender - > lock , flags ) ;
return - ETIMEDOUT ;
}
REG_WRITE ( sender - > mipi_intr_stat_reg , BIT ( 29 ) ) ;
/*read data*/
if ( hs )
gen_data_reg = sender - > mipi_hs_gen_data_reg ;
else
gen_data_reg = sender - > mipi_lp_gen_data_reg ;
for ( i = 0 ; i < len_out ; i + + )
* ( data_out + i ) = REG_READ ( gen_data_reg ) ;
spin_unlock_irqrestore ( & sender - > lock , flags ) ;
return 0 ;
}
int mdfld_dsi_read_mcs ( struct mdfld_dsi_pkg_sender * sender , u8 cmd ,
u32 * data , u16 len , bool hs )
{
if ( ! sender | | ! data | | ! len ) {
DRM_ERROR ( " Invalid parameters \n " ) ;
return - EINVAL ;
}
return __read_panel_data ( sender , DSI_DT_DCS_READ , & cmd , 1 ,
data , len , hs ) ;
}
int mdfld_dsi_pkg_sender_init ( struct mdfld_dsi_connector * dsi_connector ,
int pipe )
{
struct mdfld_dsi_pkg_sender * pkg_sender ;
struct mdfld_dsi_config * dsi_config =
mdfld_dsi_get_config ( dsi_connector ) ;
struct drm_device * dev = dsi_config - > dev ;
2012-05-11 11:31:22 +01:00
struct drm_psb_private * dev_priv = dev - > dev_private ;
const struct psb_offset * map = & dev_priv - > regmap [ pipe ] ;
2012-03-08 16:02:20 +00:00
u32 mipi_val = 0 ;
if ( ! dsi_connector ) {
DRM_ERROR ( " Invalid parameter \n " ) ;
return - EINVAL ;
}
pkg_sender = dsi_connector - > pkg_sender ;
if ( ! pkg_sender | | IS_ERR ( pkg_sender ) ) {
pkg_sender = kzalloc ( sizeof ( struct mdfld_dsi_pkg_sender ) ,
GFP_KERNEL ) ;
if ( ! pkg_sender ) {
DRM_ERROR ( " Create DSI pkg sender failed \n " ) ;
return - ENOMEM ;
}
dsi_connector - > pkg_sender = ( void * ) pkg_sender ;
}
pkg_sender - > dev = dev ;
pkg_sender - > dsi_connector = dsi_connector ;
pkg_sender - > pipe = pipe ;
pkg_sender - > pkg_num = 0 ;
pkg_sender - > panel_mode = 0 ;
pkg_sender - > status = MDFLD_DSI_PKG_SENDER_FREE ;
/*init regs*/
2012-05-11 11:31:22 +01:00
/* FIXME: should just copy the regmap ptr ? */
pkg_sender - > dpll_reg = map - > dpll ;
pkg_sender - > dspcntr_reg = map - > cntr ;
pkg_sender - > pipeconf_reg = map - > conf ;
pkg_sender - > dsplinoff_reg = map - > linoff ;
pkg_sender - > dspsurf_reg = map - > surf ;
pkg_sender - > pipestat_reg = map - > status ;
2012-03-08 16:02:20 +00:00
pkg_sender - > mipi_intr_stat_reg = MIPI_INTR_STAT_REG ( pipe ) ;
pkg_sender - > mipi_lp_gen_data_reg = MIPI_LP_GEN_DATA_REG ( pipe ) ;
pkg_sender - > mipi_hs_gen_data_reg = MIPI_HS_GEN_DATA_REG ( pipe ) ;
pkg_sender - > mipi_lp_gen_ctrl_reg = MIPI_LP_GEN_CTRL_REG ( pipe ) ;
pkg_sender - > mipi_hs_gen_ctrl_reg = MIPI_HS_GEN_CTRL_REG ( pipe ) ;
pkg_sender - > mipi_gen_fifo_stat_reg = MIPI_GEN_FIFO_STAT_REG ( pipe ) ;
pkg_sender - > mipi_data_addr_reg = MIPI_DATA_ADD_REG ( pipe ) ;
pkg_sender - > mipi_data_len_reg = MIPI_DATA_LEN_REG ( pipe ) ;
pkg_sender - > mipi_cmd_addr_reg = MIPI_CMD_ADD_REG ( pipe ) ;
pkg_sender - > mipi_cmd_len_reg = MIPI_CMD_LEN_REG ( pipe ) ;
/*init lock*/
spin_lock_init ( & pkg_sender - > lock ) ;
if ( mdfld_get_panel_type ( dev , pipe ) ! = TC35876X ) {
/**
* For video mode , don ' t enable DPI timing output here ,
* will init the DPI timing output during mode setting .
*/
mipi_val = PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX ;
if ( pipe = = 0 )
mipi_val | = 0x2 ;
REG_WRITE ( MIPI_PORT_CONTROL ( pipe ) , mipi_val ) ;
REG_READ ( MIPI_PORT_CONTROL ( pipe ) ) ;
/* do dsi controller init */
mdfld_dsi_controller_init ( dsi_config , pipe ) ;
}
return 0 ;
}
void mdfld_dsi_pkg_sender_destroy ( struct mdfld_dsi_pkg_sender * sender )
{
if ( ! sender | | IS_ERR ( sender ) )
return ;
/*free*/
kfree ( sender ) ;
}