2012-11-15 21:28:22 +00:00
/*
* Copyright ( C ) 2012 Avionic Design GmbH
2013-03-22 16:34:09 +02:00
* Copyright ( C ) 2012 - 2013 NVIDIA CORPORATION . All rights reserved .
2012-11-15 21:28:22 +00:00
*
* 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 .
*/
2013-03-22 16:34:05 +02:00
# ifndef HOST1X_DRM_H
# define HOST1X_DRM_H 1
2012-11-15 21:28:22 +00:00
2013-09-24 13:59:01 +02:00
# include <uapi/drm/tegra_drm.h>
# include <linux/host1x.h>
2012-11-15 21:28:22 +00:00
# include <drm/drmP.h>
# include <drm/drm_crtc_helper.h>
# include <drm/drm_edid.h>
# include <drm/drm_fb_helper.h>
# include <drm/drm_fixed.h>
2013-11-06 16:20:54 -07:00
struct reset_control ;
2013-03-22 16:34:08 +02:00
struct tegra_fb {
struct drm_framebuffer base ;
struct tegra_bo * * planes ;
unsigned int num_planes ;
} ;
2013-10-31 13:28:50 +01:00
# ifdef CONFIG_DRM_TEGRA_FBDEV
2013-03-22 16:34:08 +02:00
struct tegra_fbdev {
struct drm_fb_helper base ;
struct tegra_fb * fb ;
} ;
2013-10-31 13:28:50 +01:00
# endif
2013-03-22 16:34:08 +02:00
2013-09-24 13:22:17 +02:00
struct tegra_drm {
2012-11-15 21:28:22 +00:00
struct drm_device * drm ;
struct mutex clients_lock ;
struct list_head clients ;
2013-10-31 13:28:50 +01:00
# ifdef CONFIG_DRM_TEGRA_FBDEV
2013-03-22 16:34:08 +02:00
struct tegra_fbdev * fbdev ;
2013-10-31 13:28:50 +01:00
# endif
2012-11-15 21:28:22 +00:00
} ;
2013-09-24 15:35:40 +02:00
struct tegra_drm_client ;
2012-11-15 21:28:22 +00:00
2013-09-26 16:08:22 +02:00
struct tegra_drm_context {
2013-09-24 15:35:40 +02:00
struct tegra_drm_client * client ;
2013-03-22 16:34:09 +02:00
struct host1x_channel * channel ;
struct list_head list ;
} ;
2013-09-24 15:35:40 +02:00
struct tegra_drm_client_ops {
int ( * open_channel ) ( struct tegra_drm_client * client ,
2013-09-26 16:08:22 +02:00
struct tegra_drm_context * context ) ;
void ( * close_channel ) ( struct tegra_drm_context * context ) ;
2013-10-10 11:00:33 +02:00
int ( * is_addr_reg ) ( struct device * dev , u32 class , u32 offset ) ;
2013-09-26 16:08:22 +02:00
int ( * submit ) ( struct tegra_drm_context * context ,
2013-03-22 16:34:09 +02:00
struct drm_tegra_submit * args , struct drm_device * drm ,
struct drm_file * file ) ;
} ;
2013-10-10 11:00:33 +02:00
int tegra_drm_submit ( struct tegra_drm_context * context ,
struct drm_tegra_submit * args , struct drm_device * drm ,
struct drm_file * file ) ;
2013-09-24 15:35:40 +02:00
struct tegra_drm_client {
struct host1x_client base ;
2013-10-14 14:43:22 +02:00
struct list_head list ;
2013-03-22 16:34:09 +02:00
2013-09-24 15:35:40 +02:00
const struct tegra_drm_client_ops * ops ;
2012-11-15 21:28:22 +00:00
} ;
2013-09-24 15:35:40 +02:00
static inline struct tegra_drm_client *
2013-10-14 14:43:22 +02:00
host1x_to_drm_client ( struct host1x_client * client )
2013-09-24 15:35:40 +02:00
{
return container_of ( client , struct tegra_drm_client , base ) ;
}
2014-04-16 09:54:21 +02:00
int tegra_drm_register_client ( struct tegra_drm * tegra ,
struct tegra_drm_client * client ) ;
int tegra_drm_unregister_client ( struct tegra_drm * tegra ,
struct tegra_drm_client * client ) ;
2013-10-14 14:43:22 +02:00
2014-04-16 09:54:21 +02:00
int tegra_drm_init ( struct tegra_drm * tegra , struct drm_device * drm ) ;
int tegra_drm_exit ( struct tegra_drm * tegra ) ;
2012-11-15 21:28:22 +00:00
2013-12-12 11:03:59 +01:00
struct tegra_dc_soc_info ;
2012-11-15 21:28:22 +00:00
struct tegra_output ;
struct tegra_dc {
2013-10-14 14:43:22 +02:00
struct host1x_client client ;
2012-11-15 21:28:22 +00:00
struct device * dev ;
2013-09-26 16:09:19 +02:00
spinlock_t lock ;
2012-11-15 21:28:22 +00:00
struct drm_crtc base ;
int pipe ;
struct clk * clk ;
2013-11-06 16:20:54 -07:00
struct reset_control * rst ;
2012-11-15 21:28:22 +00:00
void __iomem * regs ;
int irq ;
struct tegra_output * rgb ;
struct list_head list ;
struct drm_info_list * debugfs_files ;
struct drm_minor * minor ;
struct dentry * debugfs ;
2012-11-28 12:00:18 +01:00
/* page-flip handling */
struct drm_pending_vblank_event * event ;
2013-12-12 11:03:59 +01:00
const struct tegra_dc_soc_info * soc ;
2012-11-15 21:28:22 +00:00
} ;
2013-09-24 15:35:40 +02:00
static inline struct tegra_dc *
2013-10-14 14:43:22 +02:00
host1x_client_to_dc ( struct host1x_client * client )
2012-11-15 21:28:22 +00:00
{
return container_of ( client , struct tegra_dc , client ) ;
}
static inline struct tegra_dc * to_tegra_dc ( struct drm_crtc * crtc )
{
2013-11-08 12:30:37 +01:00
return crtc ? container_of ( crtc , struct tegra_dc , base ) : NULL ;
2012-11-15 21:28:22 +00:00
}
static inline void tegra_dc_writel ( struct tegra_dc * dc , unsigned long value ,
unsigned long reg )
{
writel ( value , dc - > regs + ( reg < < 2 ) ) ;
}
static inline unsigned long tegra_dc_readl ( struct tegra_dc * dc ,
unsigned long reg )
{
return readl ( dc - > regs + ( reg < < 2 ) ) ;
}
2012-11-04 21:47:13 +01:00
struct tegra_dc_window {
struct {
unsigned int x ;
unsigned int y ;
unsigned int w ;
unsigned int h ;
} src ;
struct {
unsigned int x ;
unsigned int y ;
unsigned int w ;
unsigned int h ;
} dst ;
unsigned int bits_per_pixel ;
unsigned int format ;
2014-01-29 20:31:17 +01:00
unsigned int swap ;
2012-11-04 21:47:13 +01:00
unsigned int stride [ 2 ] ;
unsigned long base [ 3 ] ;
2013-10-07 09:47:58 +02:00
bool bottom_up ;
2013-10-04 22:34:01 +02:00
bool tiled ;
2012-11-04 21:47:13 +01:00
} ;
/* from dc.c */
2014-01-29 20:31:17 +01:00
unsigned int tegra_dc_format ( uint32_t format , unsigned int * swap ) ;
2014-04-16 09:54:21 +02:00
int tegra_dc_setup_window ( struct tegra_dc * dc , unsigned int index ,
const struct tegra_dc_window * window ) ;
void tegra_dc_enable_vblank ( struct tegra_dc * dc ) ;
void tegra_dc_disable_vblank ( struct tegra_dc * dc ) ;
void tegra_dc_cancel_page_flip ( struct drm_crtc * crtc , struct drm_file * file ) ;
2012-11-04 21:47:13 +01:00
2012-11-15 21:28:22 +00:00
struct tegra_output_ops {
int ( * enable ) ( struct tegra_output * output ) ;
int ( * disable ) ( struct tegra_output * output ) ;
int ( * setup_clock ) ( struct tegra_output * output , struct clk * clk ,
unsigned long pclk ) ;
int ( * check_mode ) ( struct tegra_output * output ,
struct drm_display_mode * mode ,
enum drm_mode_status * status ) ;
2013-11-15 16:06:05 +01:00
enum drm_connector_status ( * detect ) ( struct tegra_output * output ) ;
2012-11-15 21:28:22 +00:00
} ;
enum tegra_output_type {
TEGRA_OUTPUT_RGB ,
2012-11-15 21:28:23 +00:00
TEGRA_OUTPUT_HDMI ,
2013-09-03 08:45:46 +02:00
TEGRA_OUTPUT_DSI ,
2013-11-15 16:06:05 +01:00
TEGRA_OUTPUT_EDP ,
2012-11-15 21:28:22 +00:00
} ;
struct tegra_output {
struct device_node * of_node ;
struct device * dev ;
const struct tegra_output_ops * ops ;
enum tegra_output_type type ;
2013-08-30 15:22:36 +02:00
struct drm_panel * panel ;
2012-11-15 21:28:22 +00:00
struct i2c_adapter * ddc ;
const struct edid * edid ;
unsigned int hpd_irq ;
int hpd_gpio ;
struct drm_encoder encoder ;
struct drm_connector connector ;
} ;
static inline struct tegra_output * encoder_to_output ( struct drm_encoder * e )
{
return container_of ( e , struct tegra_output , encoder ) ;
}
static inline struct tegra_output * connector_to_output ( struct drm_connector * c )
{
return container_of ( c , struct tegra_output , connector ) ;
}
static inline int tegra_output_enable ( struct tegra_output * output )
{
if ( output & & output - > ops & & output - > ops - > enable )
return output - > ops - > enable ( output ) ;
return output ? - ENOSYS : - EINVAL ;
}
static inline int tegra_output_disable ( struct tegra_output * output )
{
if ( output & & output - > ops & & output - > ops - > disable )
return output - > ops - > disable ( output ) ;
return output ? - ENOSYS : - EINVAL ;
}
static inline int tegra_output_setup_clock ( struct tegra_output * output ,
struct clk * clk , unsigned long pclk )
{
if ( output & & output - > ops & & output - > ops - > setup_clock )
return output - > ops - > setup_clock ( output , clk , pclk ) ;
return output ? - ENOSYS : - EINVAL ;
}
static inline int tegra_output_check_mode ( struct tegra_output * output ,
struct drm_display_mode * mode ,
enum drm_mode_status * status )
{
if ( output & & output - > ops & & output - > ops - > check_mode )
return output - > ops - > check_mode ( output , mode , status ) ;
return output ? - ENOSYS : - EINVAL ;
}
2013-10-14 14:43:22 +02:00
/* from bus.c */
int drm_host1x_init ( struct drm_driver * driver , struct host1x_device * device ) ;
void drm_host1x_exit ( struct drm_driver * driver , struct host1x_device * device ) ;
2012-11-15 21:28:22 +00:00
/* from rgb.c */
2014-04-16 09:54:21 +02:00
int tegra_dc_rgb_probe ( struct tegra_dc * dc ) ;
int tegra_dc_rgb_remove ( struct tegra_dc * dc ) ;
int tegra_dc_rgb_init ( struct drm_device * drm , struct tegra_dc * dc ) ;
int tegra_dc_rgb_exit ( struct tegra_dc * dc ) ;
2012-11-15 21:28:22 +00:00
/* from output.c */
2014-04-16 09:54:21 +02:00
int tegra_output_probe ( struct tegra_output * output ) ;
int tegra_output_remove ( struct tegra_output * output ) ;
int tegra_output_init ( struct drm_device * drm , struct tegra_output * output ) ;
int tegra_output_exit ( struct tegra_output * output ) ;
2012-11-15 21:28:22 +00:00
2013-11-15 16:06:05 +01:00
/* from dpaux.c */
struct tegra_dpaux ;
struct drm_dp_link ;
struct tegra_dpaux * tegra_dpaux_find_by_of_node ( struct device_node * np ) ;
enum drm_connector_status tegra_dpaux_detect ( struct tegra_dpaux * dpaux ) ;
int tegra_dpaux_attach ( struct tegra_dpaux * dpaux , struct tegra_output * output ) ;
int tegra_dpaux_detach ( struct tegra_dpaux * dpaux ) ;
int tegra_dpaux_enable ( struct tegra_dpaux * dpaux ) ;
int tegra_dpaux_disable ( struct tegra_dpaux * dpaux ) ;
int tegra_dpaux_prepare ( struct tegra_dpaux * dpaux , u8 encoding ) ;
int tegra_dpaux_train ( struct tegra_dpaux * dpaux , struct drm_dp_link * link ,
u8 pattern ) ;
2012-11-15 21:28:22 +00:00
/* from fb.c */
2013-03-22 16:34:08 +02:00
struct tegra_bo * tegra_fb_get_plane ( struct drm_framebuffer * framebuffer ,
unsigned int index ) ;
2013-10-07 09:47:58 +02:00
bool tegra_fb_is_bottom_up ( struct drm_framebuffer * framebuffer ) ;
2013-10-04 22:34:01 +02:00
bool tegra_fb_is_tiled ( struct drm_framebuffer * framebuffer ) ;
2014-04-16 09:54:21 +02:00
int tegra_drm_fb_init ( struct drm_device * drm ) ;
void tegra_drm_fb_exit ( struct drm_device * drm ) ;
2013-10-31 13:28:50 +01:00
# ifdef CONFIG_DRM_TEGRA_FBDEV
2014-04-16 09:54:21 +02:00
void tegra_fbdev_restore_mode ( struct tegra_fbdev * fbdev ) ;
2013-10-31 13:28:50 +01:00
# endif
2012-11-15 21:28:22 +00:00
2013-10-14 14:43:22 +02:00
extern struct platform_driver tegra_dc_driver ;
2013-09-03 08:45:46 +02:00
extern struct platform_driver tegra_dsi_driver ;
2013-11-15 16:06:05 +01:00
extern struct platform_driver tegra_sor_driver ;
2013-10-14 14:43:22 +02:00
extern struct platform_driver tegra_hdmi_driver ;
2013-11-15 16:06:05 +01:00
extern struct platform_driver tegra_dpaux_driver ;
2013-10-14 14:43:22 +02:00
extern struct platform_driver tegra_gr2d_driver ;
2013-02-28 08:08:01 +01:00
extern struct platform_driver tegra_gr3d_driver ;
2012-11-15 21:28:22 +00:00
2013-03-22 16:34:05 +02:00
# endif /* HOST1X_DRM_H */