2009-11-03 11:23:50 +02:00
/*
* Copyright ( C ) 2009 Nokia Corporation
* Author : Tomi Valkeinen < tomi . valkeinen @ nokia . com >
*
* Some code and ideas taken from drivers / video / omap / driver
* by Imre Deak .
*
* This program is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation .
*
* This program is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License for
* more details .
*
* You should have received a copy of the GNU General Public License along with
* this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# ifndef __OMAP2_DSS_H
# define __OMAP2_DSS_H
2012-10-10 15:55:19 +03:00
# include <linux/interrupt.h>
2016-02-19 16:54:36 +02:00
# include "omapdss.h"
2017-08-05 01:44:19 +03:00
# define MAX_DSS_LCD_MANAGERS 3
# define MAX_NUM_DSI 2
2012-09-24 17:12:58 +05:30
# ifdef pr_fmt
# undef pr_fmt
2009-11-03 11:23:50 +02:00
# endif
2012-09-24 17:12:58 +05:30
# ifdef DSS_SUBSYS_NAME
# define pr_fmt(fmt) DSS_SUBSYS_NAME ": " fmt
# else
# define pr_fmt(fmt) fmt
2009-11-03 11:23:50 +02:00
# endif
2012-09-24 17:12:58 +05:30
# define DSSDBG(format, ...) \
pr_debug ( format , # # __VA_ARGS__ )
2009-11-03 11:23:50 +02:00
# ifdef DSS_SUBSYS_NAME
# define DSSERR(format, ...) \
2017-02-28 04:55:54 -08:00
pr_err ( " omapdss " DSS_SUBSYS_NAME " error: " format , # # __VA_ARGS__ )
2009-11-03 11:23:50 +02:00
# else
# define DSSERR(format, ...) \
2017-02-28 04:55:54 -08:00
pr_err ( " omapdss error: " format , # # __VA_ARGS__ )
2009-11-03 11:23:50 +02:00
# endif
# ifdef DSS_SUBSYS_NAME
# define DSSINFO(format, ...) \
2017-02-28 04:55:54 -08:00
pr_info ( " omapdss " DSS_SUBSYS_NAME " : " format , # # __VA_ARGS__ )
2009-11-03 11:23:50 +02:00
# else
# define DSSINFO(format, ...) \
2017-02-28 04:55:54 -08:00
pr_info ( " omapdss: " format , # # __VA_ARGS__ )
2009-11-03 11:23:50 +02:00
# endif
# ifdef DSS_SUBSYS_NAME
# define DSSWARN(format, ...) \
2017-02-28 04:55:54 -08:00
pr_warn ( " omapdss " DSS_SUBSYS_NAME " : " format , # # __VA_ARGS__ )
2009-11-03 11:23:50 +02:00
# else
# define DSSWARN(format, ...) \
2017-02-28 04:55:54 -08:00
pr_warn ( " omapdss: " format , # # __VA_ARGS__ )
2009-11-03 11:23:50 +02:00
# endif
/* OMAP TRM gives bitfields as start:end, where start is the higher bit
number . For example 7 : 0 */
# define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end))
# define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))
# define FLD_GET(val, start, end) (((val) & FLD_MASK(start, end)) >> (end))
# define FLD_MOD(orig, val, start, end) \
( ( ( orig ) & ~ FLD_MASK ( start , end ) ) | FLD_VAL ( val , start , end ) )
2017-08-05 01:43:56 +03:00
enum dss_model {
DSS_MODEL_OMAP2 ,
DSS_MODEL_OMAP3 ,
DSS_MODEL_OMAP4 ,
DSS_MODEL_OMAP5 ,
DSS_MODEL_DRA7 ,
} ;
2011-08-22 17:41:57 +05:30
enum dss_io_pad_mode {
DSS_IO_PAD_MODE_RESET ,
DSS_IO_PAD_MODE_RFBI ,
DSS_IO_PAD_MODE_BYPASS ,
2009-11-03 11:23:50 +02:00
} ;
2011-03-09 16:31:38 +05:30
enum dss_hdmi_venc_clk_source_select {
DSS_VENC_TV_CLK = 0 ,
DSS_HDMI_M_PCLK = 1 ,
} ;
2011-08-25 18:35:58 +05:30
enum dss_dsi_content_type {
DSS_DSI_CONTENT_DCS ,
DSS_DSI_CONTENT_GENERIC ,
} ;
2012-09-22 12:38:19 +05:30
enum dss_writeback_channel {
DSS_WB_LCD1_MGR = 0 ,
DSS_WB_LCD2_MGR = 1 ,
DSS_WB_TV_MGR = 2 ,
DSS_WB_OVL0 = 3 ,
DSS_WB_OVL1 = 4 ,
DSS_WB_OVL2 = 5 ,
DSS_WB_OVL3 = 6 ,
DSS_WB_LCD3_MGR = 7 ,
} ;
2016-05-17 13:45:09 +03:00
enum dss_clk_source {
2016-05-17 14:01:10 +03:00
DSS_CLK_SRC_FCK = 0 ,
DSS_CLK_SRC_PLL1_1 ,
DSS_CLK_SRC_PLL1_2 ,
2016-05-17 14:12:35 +03:00
DSS_CLK_SRC_PLL1_3 ,
2016-05-17 14:01:10 +03:00
DSS_CLK_SRC_PLL2_1 ,
DSS_CLK_SRC_PLL2_2 ,
2016-05-17 14:12:35 +03:00
DSS_CLK_SRC_PLL2_3 ,
DSS_CLK_SRC_HDMI_PLL ,
2016-05-17 13:31:14 +03:00
} ;
2015-01-02 10:05:33 +02:00
enum dss_pll_id {
DSS_PLL_DSI1 ,
DSS_PLL_DSI2 ,
DSS_PLL_HDMI ,
2014-12-31 11:23:31 +02:00
DSS_PLL_VIDEO1 ,
DSS_PLL_VIDEO2 ,
2015-01-02 10:05:33 +02:00
} ;
2014-10-22 14:21:59 +03:00
struct dss_pll ;
# define DSS_PLL_MAX_HSDIVS 4
2016-05-18 10:48:44 +03:00
enum dss_pll_type {
DSS_PLL_TYPE_A ,
DSS_PLL_TYPE_B ,
} ;
2014-10-22 14:21:59 +03:00
/*
* Type - A PLLs : clkout [ ] / mX [ ] refer to hsdiv outputs m4 , m5 , m6 , m7 .
* Type - B PLLs : clkout [ 0 ] refers to m2 .
*/
struct dss_pll_clock_info {
/* rates that we get with dividers below */
unsigned long fint ;
unsigned long clkdco ;
unsigned long clkout [ DSS_PLL_MAX_HSDIVS ] ;
/* dividers */
u16 n ;
u16 m ;
u32 mf ;
u16 mX [ DSS_PLL_MAX_HSDIVS ] ;
u16 sd ;
} ;
struct dss_pll_ops {
int ( * enable ) ( struct dss_pll * pll ) ;
void ( * disable ) ( struct dss_pll * pll ) ;
int ( * set_config ) ( struct dss_pll * pll ,
const struct dss_pll_clock_info * cinfo ) ;
} ;
struct dss_pll_hw {
2016-05-18 10:48:44 +03:00
enum dss_pll_type type ;
2018-02-11 15:07:34 +02:00
unsigned int n_max ;
unsigned int m_min ;
unsigned int m_max ;
unsigned int mX_max ;
2014-10-22 14:21:59 +03:00
unsigned long fint_min , fint_max ;
unsigned long clkdco_min , clkdco_low , clkdco_max ;
u8 n_msb , n_lsb ;
u8 m_msb , m_lsb ;
u8 mX_msb [ DSS_PLL_MAX_HSDIVS ] , mX_lsb [ DSS_PLL_MAX_HSDIVS ] ;
bool has_stopmode ;
bool has_freqsel ;
bool has_selfreqdco ;
bool has_refsel ;
2017-06-13 12:02:10 +03:00
/* DRA7 errata i886: use high N & M to avoid jitter */
bool errata_i886 ;
2014-10-22 14:21:59 +03:00
} ;
struct dss_pll {
const char * name ;
2015-01-02 10:05:33 +02:00
enum dss_pll_id id ;
2018-02-13 14:00:21 +02:00
struct dss_device * dss ;
2014-10-22 14:21:59 +03:00
struct clk * clkin ;
struct regulator * regulator ;
void __iomem * base ;
const struct dss_pll_hw * hw ;
const struct dss_pll_ops * ops ;
struct dss_pll_clock_info cinfo ;
} ;
2017-08-05 01:44:07 +03:00
/* Defines a generic omap register field */
struct dss_reg_field {
u8 start , end ;
} ;
2009-11-03 11:23:50 +02:00
struct dispc_clock_info {
/* rates that we get with dividers below */
unsigned long lck ;
unsigned long pck ;
/* dividers */
u16 lck_div ;
u16 pck_div ;
} ;
2012-06-29 14:03:48 +05:30
struct dss_lcd_mgr_config {
enum dss_io_pad_mode io_pad_mode ;
bool stallmode ;
bool fifohandcheck ;
struct dispc_clock_info clock_info ;
int video_port_width ;
int lcden_sig_polarity ;
} ;
2009-11-03 11:23:50 +02:00
struct seq_file ;
struct platform_device ;
2018-02-13 14:00:20 +02:00
# define DSS_SZ_REGS SZ_512
struct dss_device {
struct platform_device * pdev ;
void __iomem * base ;
struct regmap * syscon_pll_ctrl ;
u32 syscon_pll_ctrl_offset ;
struct clk * parent_clk ;
struct clk * dss_clk ;
unsigned long dss_clk_rate ;
unsigned long cache_req_pck ;
unsigned long cache_prate ;
struct dispc_clock_info cache_dispc_cinfo ;
enum dss_clk_source dsi_clk_source [ MAX_NUM_DSI ] ;
enum dss_clk_source dispc_clk_source ;
enum dss_clk_source lcd_clk_source [ MAX_DSS_LCD_MANAGERS ] ;
bool ctx_valid ;
u32 ctx [ DSS_SZ_REGS / sizeof ( u32 ) ] ;
const struct dss_features * feat ;
struct dss_pll * video1_pll ;
struct dss_pll * video2_pll ;
} ;
2009-11-03 11:23:50 +02:00
/* core */
2017-08-05 01:43:54 +03:00
static inline int dss_set_min_bus_tput ( struct device * dev , unsigned long tput )
{
/* To be implemented when the OMAP platform will provide this feature */
return 0 ;
}
2012-06-29 14:37:03 +05:30
static inline bool dss_mgr_is_lcd ( enum omap_channel id )
{
if ( id = = OMAP_DSS_CHANNEL_LCD | | id = = OMAP_DSS_CHANNEL_LCD2 | |
id = = OMAP_DSS_CHANNEL_LCD3 )
return true ;
else
return false ;
}
2009-11-03 11:23:50 +02:00
/* DSS */
2017-08-05 01:44:01 +03:00
# if defined(CONFIG_OMAP2_DSS_DEBUGFS)
int dss_debugfs_create_file ( const char * name , void ( * write ) ( struct seq_file * ) ) ;
# else
static inline int dss_debugfs_create_file ( const char * name ,
void ( * write ) ( struct seq_file * ) )
{
return 0 ;
}
# endif /* CONFIG_OMAP2_DSS_DEBUGFS */
2018-02-13 14:00:21 +02:00
struct dss_device * dss_get_device ( struct device * dev ) ;
int dss_runtime_get ( struct dss_device * dss ) ;
void dss_runtime_put ( struct dss_device * dss ) ;
2014-07-04 13:38:27 +05:30
2012-12-12 10:37:03 +02:00
unsigned long dss_get_dispc_clk_rate ( void ) ;
2017-08-05 01:44:17 +03:00
unsigned long dss_get_max_fck_rate ( void ) ;
2017-08-05 01:44:18 +03:00
enum omap_dss_output_id dss_get_supported_outputs ( enum omap_channel channel ) ;
2014-04-23 18:00:18 +05:30
int dss_dpi_select_source ( int port , enum omap_channel channel ) ;
2011-03-09 16:31:38 +05:30
void dss_select_hdmi_venc_clk_source ( enum dss_hdmi_venc_clk_source_select ) ;
2016-05-17 13:50:55 +03:00
const char * dss_get_clk_source_name ( enum dss_clk_source clk_src ) ;
2009-11-03 11:23:50 +02:00
2014-07-04 13:38:27 +05:30
/* DSS VIDEO PLL */
2018-02-13 14:00:21 +02:00
struct dss_pll * dss_video_pll_init ( struct dss_device * dss ,
struct platform_device * pdev , int id ,
struct regulator * regulator ) ;
2014-07-04 13:38:27 +05:30
void dss_video_pll_uninit ( struct dss_pll * pll ) ;
2014-07-04 13:37:15 +05:30
void dss_ctrl_pll_enable ( enum dss_pll_id pll_id , bool enable ) ;
2012-07-20 17:18:49 +05:30
void dss_sdi_init ( int datapairs ) ;
2009-11-03 11:23:50 +02:00
int dss_sdi_enable ( void ) ;
void dss_sdi_disable ( void ) ;
2011-05-12 17:26:29 +05:30
void dss_select_dsi_clk_source ( int dsi_module ,
2016-05-17 13:45:09 +03:00
enum dss_clk_source clk_src ) ;
2011-03-08 05:50:35 -06:00
void dss_select_lcd_clk_source ( enum omap_channel channel ,
2016-05-17 13:45:09 +03:00
enum dss_clk_source clk_src ) ;
enum dss_clk_source dss_get_dispc_clk_source ( void ) ;
enum dss_clk_source dss_get_dsi_clk_source ( int dsi_module ) ;
enum dss_clk_source dss_get_lcd_clk_source ( enum omap_channel channel ) ;
2010-01-08 18:00:36 +02:00
2009-11-03 11:23:50 +02:00
void dss_set_venc_output ( enum omap_dss_venc_type type ) ;
void dss_set_dac_pwrdn_bgz ( bool enable ) ;
2013-10-31 14:44:23 +02:00
int dss_set_fck_rate ( unsigned long rate ) ;
2009-11-03 11:23:50 +02:00
2013-10-31 14:44:23 +02:00
typedef bool ( * dss_div_calc_func ) ( unsigned long fck , void * data ) ;
2013-10-31 16:41:57 +02:00
bool dss_div_calc ( unsigned long pck , unsigned long fck_min ,
dss_div_calc_func func , void * data ) ;
2013-03-05 16:34:05 +02:00
2009-11-03 11:23:50 +02:00
/* SDI */
2014-05-22 17:01:57 +05:30
# ifdef CONFIG_OMAP2_DSS_SDI
2015-06-04 14:12:16 +03:00
int sdi_init_port ( struct platform_device * pdev , struct device_node * port ) ;
void sdi_uninit_port ( struct device_node * port ) ;
2014-05-22 17:01:57 +05:30
# else
2015-06-04 14:12:16 +03:00
static inline int sdi_init_port ( struct platform_device * pdev ,
2014-05-22 17:01:57 +05:30
struct device_node * port )
{
return 0 ;
}
2015-06-04 14:12:16 +03:00
static inline void sdi_uninit_port ( struct device_node * port )
2014-05-22 17:01:57 +05:30
{
}
# endif
2013-12-16 15:13:24 +02:00
2009-11-03 11:23:50 +02:00
/* DSI */
2013-04-18 12:16:39 +03:00
2010-05-07 11:58:41 +02:00
# ifdef CONFIG_OMAP2_DSS_DSI
2011-05-12 17:26:29 +05:30
struct dentry ;
struct file_operations ;
2009-11-03 11:23:50 +02:00
void dsi_dump_clocks ( struct seq_file * s ) ;
void dsi_irq_handler ( void ) ;
2011-09-08 18:42:16 +05:30
2010-05-07 11:58:41 +02:00
# endif
2009-11-03 11:23:50 +02:00
/* DPI */
2014-05-22 17:01:57 +05:30
# ifdef CONFIG_OMAP2_DSS_DPI
2017-08-05 01:43:56 +03:00
int dpi_init_port ( struct platform_device * pdev , struct device_node * port ,
enum dss_model dss_model ) ;
2015-06-04 14:12:16 +03:00
void dpi_uninit_port ( struct device_node * port ) ;
2014-05-22 17:01:57 +05:30
# else
2015-06-04 14:12:16 +03:00
static inline int dpi_init_port ( struct platform_device * pdev ,
2017-08-05 01:43:56 +03:00
struct device_node * port , enum dss_model dss_model )
2014-05-22 17:01:57 +05:30
{
return 0 ;
}
2015-06-04 14:12:16 +03:00
static inline void dpi_uninit_port ( struct device_node * port )
2014-05-22 17:01:57 +05:30
{
}
# endif
2013-12-16 15:13:24 +02:00
2009-11-03 11:23:50 +02:00
/* DISPC */
void dispc_dump_clocks ( struct seq_file * s ) ;
2015-11-05 20:06:06 +02:00
int dispc_runtime_get ( void ) ;
void dispc_runtime_put ( void ) ;
2009-11-03 11:23:50 +02:00
void dispc_enable_sidle ( void ) ;
void dispc_disable_sidle ( void ) ;
void dispc_lcd_enable_signal ( bool enable ) ;
void dispc_pck_free_enable ( bool enable ) ;
2011-08-16 13:49:15 +03:00
void dispc_enable_fifomerge ( bool enable ) ;
2013-03-05 16:32:08 +02:00
typedef bool ( * dispc_div_calc_func ) ( int lckd , int pckd , unsigned long lck ,
unsigned long pck , void * data ) ;
bool dispc_div_calc ( unsigned long dispc ,
unsigned long pck_min , unsigned long pck_max ,
dispc_div_calc_func func , void * data ) ;
2016-09-22 14:07:04 +03:00
bool dispc_mgr_timings_ok ( enum omap_channel channel , const struct videomode * vm ) ;
2011-08-16 13:49:15 +03:00
int dispc_calc_clock_rates ( unsigned long dispc_fclk_rate ,
struct dispc_clock_info * cinfo ) ;
2017-03-24 16:47:52 +02:00
void dispc_ovl_set_fifo_threshold ( enum omap_plane_id plane , u32 low ,
u32 high ) ;
void dispc_ovl_compute_fifo_thresholds ( enum omap_plane_id plane ,
2012-05-15 15:31:01 +03:00
u32 * fifo_low , u32 * fifo_high , bool use_fifomerge ,
bool manual_update ) ;
2012-11-07 18:17:35 +02:00
2012-06-29 14:00:54 +05:30
void dispc_mgr_set_clock_div ( enum omap_channel channel ,
2012-10-03 09:09:11 +02:00
const struct dispc_clock_info * cinfo ) ;
2011-08-16 13:45:15 +03:00
int dispc_mgr_get_clock_div ( enum omap_channel channel ,
2010-12-02 11:27:11 +00:00
struct dispc_clock_info * cinfo ) ;
2013-05-16 10:44:13 +03:00
void dispc_set_tv_pclk ( unsigned long pclk ) ;
2009-11-03 11:23:50 +02:00
2012-09-22 12:39:33 +05:30
u32 dispc_wb_get_framedone_irq ( void ) ;
bool dispc_wb_go_busy ( void ) ;
void dispc_wb_go ( void ) ;
2012-09-22 12:38:19 +05:30
void dispc_wb_set_channel_in ( enum dss_writeback_channel channel ) ;
2012-08-31 12:32:52 +05:30
int dispc_wb_setup ( const struct omap_dss_writeback_info * wi ,
2016-09-22 14:07:04 +03:00
bool mem_to_mem , const struct videomode * vm ) ;
2012-09-22 12:38:19 +05:30
2009-12-17 14:35:21 +02:00
# ifdef CONFIG_OMAP2_DSS_COLLECT_IRQ_STATS
2018-02-11 15:07:34 +02:00
static inline void dss_collect_irq_stats ( u32 irqstatus , unsigned int * irq_arr )
2009-12-17 14:35:21 +02:00
{
int b ;
for ( b = 0 ; b < 32 ; + + b ) {
if ( irqstatus & ( 1 < < b ) )
irq_arr [ b ] + + ;
}
}
# endif
2014-10-22 14:21:59 +03:00
/* PLL */
typedef bool ( * dss_pll_calc_func ) ( int n , int m , unsigned long fint ,
unsigned long clkdco , void * data ) ;
typedef bool ( * dss_hsdiv_calc_func ) ( int m_dispc , unsigned long dispc ,
void * data ) ;
int dss_pll_register ( struct dss_pll * pll ) ;
void dss_pll_unregister ( struct dss_pll * pll ) ;
struct dss_pll * dss_pll_find ( const char * name ) ;
2016-05-18 12:42:09 +03:00
struct dss_pll * dss_pll_find_by_src ( enum dss_clk_source src ) ;
2018-02-11 15:07:34 +02:00
unsigned int dss_pll_get_clkout_idx_for_src ( enum dss_clk_source src ) ;
2014-10-22 14:21:59 +03:00
int dss_pll_enable ( struct dss_pll * pll ) ;
void dss_pll_disable ( struct dss_pll * pll ) ;
int dss_pll_set_config ( struct dss_pll * pll ,
const struct dss_pll_clock_info * cinfo ) ;
2016-05-17 21:23:37 +03:00
bool dss_pll_hsdiv_calc_a ( const struct dss_pll * pll , unsigned long clkdco ,
2014-10-22 14:21:59 +03:00
unsigned long out_min , unsigned long out_max ,
dss_hsdiv_calc_func func , void * data ) ;
2016-05-17 21:23:37 +03:00
bool dss_pll_calc_a ( const struct dss_pll * pll , unsigned long clkin ,
2014-10-22 14:21:59 +03:00
unsigned long pll_min , unsigned long pll_max ,
dss_pll_calc_func func , void * data ) ;
2016-05-18 10:45:20 +03:00
bool dss_pll_calc_b ( const struct dss_pll * pll , unsigned long clkin ,
2016-05-18 11:15:21 +03:00
unsigned long target_clkout , struct dss_pll_clock_info * cinfo ) ;
2016-05-18 10:45:20 +03:00
2014-10-22 14:21:59 +03:00
int dss_pll_write_config_type_a ( struct dss_pll * pll ,
const struct dss_pll_clock_info * cinfo ) ;
int dss_pll_write_config_type_b ( struct dss_pll * pll ,
const struct dss_pll_clock_info * cinfo ) ;
2014-12-31 14:22:42 +02:00
int dss_pll_wait_reset_done ( struct dss_pll * pll ) ;
2014-10-22 14:21:59 +03:00
2017-12-05 14:29:32 -06:00
extern struct platform_driver omap_dsshw_driver ;
extern struct platform_driver omap_dispchw_driver ;
# ifdef CONFIG_OMAP2_DSS_DSI
extern struct platform_driver omap_dsihw_driver ;
# endif
# ifdef CONFIG_OMAP2_DSS_VENC
extern struct platform_driver omap_venchw_driver ;
# endif
# ifdef CONFIG_OMAP4_DSS_HDMI
extern struct platform_driver omapdss_hdmi4hw_driver ;
# endif
# ifdef CONFIG_OMAP5_DSS_HDMI
extern struct platform_driver omapdss_hdmi5hw_driver ;
# endif
2009-11-03 11:23:50 +02:00
# endif