2012-11-16 01:28:22 +04:00
/*
* Copyright ( C ) 2012 Avionic Design GmbH
2013-03-22 18:34:09 +04:00
* Copyright ( C ) 2012 - 2013 NVIDIA CORPORATION . All rights reserved .
2012-11-16 01:28:22 +04: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 18:34:05 +04:00
# ifndef HOST1X_DRM_H
# define HOST1X_DRM_H 1
2012-11-16 01:28:22 +04:00
2013-09-24 15:59:01 +04:00
# include <uapi/drm/tegra_drm.h>
# include <linux/host1x.h>
2012-11-16 01:28:22 +04: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-03-22 18:34:08 +04:00
struct tegra_fb {
struct drm_framebuffer base ;
struct tegra_bo * * planes ;
unsigned int num_planes ;
} ;
struct tegra_fbdev {
struct drm_fb_helper base ;
struct tegra_fb * fb ;
} ;
2013-09-24 15:22:17 +04:00
struct tegra_drm {
2012-11-16 01:28:22 +04:00
struct drm_device * drm ;
struct mutex clients_lock ;
struct list_head clients ;
2013-03-22 18:34:08 +04:00
struct tegra_fbdev * fbdev ;
2012-11-16 01:28:22 +04:00
} ;
2013-09-24 17:35:40 +04:00
struct tegra_drm_client ;
2012-11-16 01:28:22 +04:00
2013-09-26 18:08:22 +04:00
struct tegra_drm_context {
2013-09-24 17:35:40 +04:00
struct tegra_drm_client * client ;
2013-03-22 18:34:09 +04:00
struct host1x_channel * channel ;
struct list_head list ;
} ;
2013-09-24 17:35:40 +04:00
struct tegra_drm_client_ops {
int ( * open_channel ) ( struct tegra_drm_client * client ,
2013-09-26 18:08:22 +04:00
struct tegra_drm_context * context ) ;
void ( * close_channel ) ( struct tegra_drm_context * context ) ;
2013-10-10 13:00:33 +04:00
int ( * is_addr_reg ) ( struct device * dev , u32 class , u32 offset ) ;
2013-09-26 18:08:22 +04:00
int ( * submit ) ( struct tegra_drm_context * context ,
2013-03-22 18:34:09 +04:00
struct drm_tegra_submit * args , struct drm_device * drm ,
struct drm_file * file ) ;
} ;
2013-10-10 13:00:33 +04: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 17:35:40 +04:00
struct tegra_drm_client {
struct host1x_client base ;
2013-10-14 16:43:22 +04:00
struct list_head list ;
2013-03-22 18:34:09 +04:00
2013-09-24 17:35:40 +04:00
const struct tegra_drm_client_ops * ops ;
2012-11-16 01:28:22 +04:00
} ;
2013-09-24 17:35:40 +04:00
static inline struct tegra_drm_client *
2013-10-14 16:43:22 +04:00
host1x_to_drm_client ( struct host1x_client * client )
2013-09-24 17:35:40 +04:00
{
return container_of ( client , struct tegra_drm_client , base ) ;
}
2013-10-14 16:43:22 +04:00
extern int tegra_drm_register_client ( struct tegra_drm * tegra ,
struct tegra_drm_client * client ) ;
extern int tegra_drm_unregister_client ( struct tegra_drm * tegra ,
struct tegra_drm_client * client ) ;
2013-09-24 15:22:17 +04:00
extern int tegra_drm_init ( struct tegra_drm * tegra , struct drm_device * drm ) ;
extern int tegra_drm_exit ( struct tegra_drm * tegra ) ;
2012-11-16 01:28:22 +04:00
struct tegra_output ;
struct tegra_dc {
2013-10-14 16:43:22 +04:00
struct host1x_client client ;
2012-11-16 01:28:22 +04:00
struct device * dev ;
2013-09-26 18:09:19 +04:00
spinlock_t lock ;
2012-11-16 01:28:22 +04:00
struct drm_crtc base ;
int pipe ;
struct clk * clk ;
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 15:00:18 +04:00
/* page-flip handling */
struct drm_pending_vblank_event * event ;
2012-11-16 01:28:22 +04:00
} ;
2013-09-24 17:35:40 +04:00
static inline struct tegra_dc *
2013-10-14 16:43:22 +04:00
host1x_client_to_dc ( struct host1x_client * client )
2012-11-16 01:28:22 +04:00
{
return container_of ( client , struct tegra_dc , client ) ;
}
static inline struct tegra_dc * to_tegra_dc ( struct drm_crtc * crtc )
{
return container_of ( crtc , struct tegra_dc , base ) ;
}
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-05 00:47:13 +04: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 ;
unsigned int stride [ 2 ] ;
unsigned long base [ 3 ] ;
} ;
/* from dc.c */
extern unsigned int tegra_dc_format ( uint32_t format ) ;
extern int tegra_dc_setup_window ( struct tegra_dc * dc , unsigned int index ,
const struct tegra_dc_window * window ) ;
2012-11-28 14:45:47 +04:00
extern void tegra_dc_enable_vblank ( struct tegra_dc * dc ) ;
extern void tegra_dc_disable_vblank ( struct tegra_dc * dc ) ;
2012-11-28 15:00:18 +04:00
extern void tegra_dc_cancel_page_flip ( struct drm_crtc * crtc ,
struct drm_file * file ) ;
2012-11-05 00:47:13 +04:00
2012-11-16 01:28:22 +04: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 ) ;
} ;
enum tegra_output_type {
TEGRA_OUTPUT_RGB ,
2012-11-16 01:28:23 +04:00
TEGRA_OUTPUT_HDMI ,
2012-11-16 01:28:22 +04:00
} ;
struct tegra_output {
struct device_node * of_node ;
struct device * dev ;
const struct tegra_output_ops * ops ;
enum tegra_output_type type ;
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 16:43:22 +04: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-16 01:28:22 +04:00
/* from rgb.c */
extern int tegra_dc_rgb_probe ( struct tegra_dc * dc ) ;
2013-10-14 16:26:42 +04:00
extern int tegra_dc_rgb_remove ( struct tegra_dc * dc ) ;
2012-11-16 01:28:22 +04:00
extern int tegra_dc_rgb_init ( struct drm_device * drm , struct tegra_dc * dc ) ;
extern int tegra_dc_rgb_exit ( struct tegra_dc * dc ) ;
/* from output.c */
2013-10-14 16:26:42 +04:00
extern int tegra_output_probe ( struct tegra_output * output ) ;
extern int tegra_output_remove ( struct tegra_output * output ) ;
2012-11-16 01:28:22 +04:00
extern int tegra_output_init ( struct drm_device * drm , struct tegra_output * output ) ;
extern int tegra_output_exit ( struct tegra_output * output ) ;
/* from fb.c */
2013-03-22 18:34:08 +04:00
struct tegra_bo * tegra_fb_get_plane ( struct drm_framebuffer * framebuffer ,
unsigned int index ) ;
2012-11-16 01:28:22 +04:00
extern int tegra_drm_fb_init ( struct drm_device * drm ) ;
extern void tegra_drm_fb_exit ( struct drm_device * drm ) ;
2013-03-22 18:34:08 +04:00
extern void tegra_fbdev_restore_mode ( struct tegra_fbdev * fbdev ) ;
2012-11-16 01:28:22 +04:00
2013-10-14 16:43:22 +04:00
extern struct platform_driver tegra_dc_driver ;
extern struct platform_driver tegra_hdmi_driver ;
extern struct platform_driver tegra_gr2d_driver ;
2012-11-16 01:28:22 +04:00
2013-03-22 18:34:05 +04:00
# endif /* HOST1X_DRM_H */