Fixed MTP to work with TWRP

This commit is contained in:
awab228 2018-06-19 23:16:04 +02:00
commit f6dfaef42e
50820 changed files with 20846062 additions and 0 deletions

View file

@ -0,0 +1,101 @@
config EXYNOS_DECON_7870
bool "Samsung Exynos7870 Display system (DECON, MIPI)"
depends on FB
choice
prompt "Select Display Operation Mode"
depends on EXYNOS_DECON_7870
default EXYNOS7870_DISPLAY_VIDEO_MODE
help
Select the display operation mode (Command/Video).
config EXYNOS7870_DISPLAY_COMMAND_MODE
bool "Command Mode"
config EXYNOS7870_DISPLAY_VIDEO_MODE
bool "Video Mode"
endchoice
choice
prompt "Select TE IRQ Mode"
depends on EXYNOS_DECON_7870 && EXYNOS7870_DISPLAY_COMMAND_MODE
default EXYNOS7870_DISPLAY_TE_IRQ_GPIO
help
Select the TE IRQ mode.
config EXYNOS7870_DISPLAY_TE_IRQ_GPIO
bool "Dual GPIO"
config EXYNOS7870_DISPLAY_TE_IRQ_GIC
bool "GIC Interrupt"
endchoice
config USE_VSYNC_SKIP
bool "Vsync Skip Enable"
depends on EXYNOS_DECON_7870
default n
help
Say Y here if you want to enable vsync skip feature for DFS solution.
config EXYNOS_DECON_FB
bool "Samsung DECON Framebuffer driver"
depends on EXYNOS_DECON_7870
select MEDIA_EXYNOS
default y
help
Say Y here if you want support for the DECON in Samsung S5P SoCs.
This device produce image data to one of output interfaces.
config EXYNOS_MIPI_DSI
bool "Samsung Exynos MIPI-DSI driver"
depends on EXYNOS_DECON_7870
default y
help
Enable MIPI-DSI driver.
config DECON_MIPI_DSI_PKTGO
bool "Samsung Exynos MIPI-DSI Packet Go"
depends on EXYNOS_DECON_7870 && EXYNOS_MIPI_DSI
default n
help
Enable/disable MIPI-DSI Packet Go function
config DECON_LPD_DISPLAY
bool "Decon Low Power Display MODE"
depends on EXYNOS_DECON_7870
depends on EXYNOS7870_DISPLAY_COMMAND_MODE
default n
config DECON_LPD_DISPLAY_WITH_CAMERA
bool "Decon Low Power Display MODE with Camera"
depends on DECON_LPD_DISPLAY
depends on EXYNOS7870_DISPLAY_COMMAND_MODE
config DECON_DEVFREQ
bool "Decon devfreq implementation"
depends on EXYNOS_DECON_7870
config FB_WINDOW_UPDATE
bool "DECON window update mode"
depends on EXYNOS_DECON_7870
depends on EXYNOS7870_DISPLAY_COMMAND_MODE
default n
config DECON_BLOCKING_MODE
bool "DECON blocking mode"
depends on EXYNOS_DECON_7870
default n
config DECON_USE_BOOTLOADER_FB
bool "DECON Bootloader Framebuffer support"
depends on EXYNOS7870_DISPLAY_VIDEO_MODE
default n
config DECON_EVENT_LOG
bool "Display sub-system event logger (DECON/DSIM)"
depends on DEBUG_INFO && EXYNOS_DECON_7870
default y
source "drivers/video/fbdev/exynos/decon_7870/panels/Kconfig"

View file

@ -0,0 +1,12 @@
#
# Copyright (c) 2013 Samsung Electronics Co., Ltd.
# http://www.samsung.com
#
# Licensed under GPLv2
#
obj-$(CONFIG_EXYNOS_MIPI_DSI) += dsim.o
dsim-y += dsim_drv.o dsim_reg_7870.o
obj-$(CONFIG_EXYNOS_DECON_7870) += decon.o
decon-y += decon_core.o decon-int_drv.o decon_helper.o decon_reg_7870.o
obj-y += panels/

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,852 @@
/*
* Copyright (c) 2015 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Header file for Exynos DECON driver
*
* 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.
*/
#ifndef ___SAMSUNG_DECON_H__
#define ___SAMSUNG_DECON_H__
#include <linux/fb.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include <linux/wait.h>
#include <linux/kthread.h>
#include <linux/pm_qos.h>
#include <linux/delay.h>
#include <linux/seq_file.h>
#include <media/v4l2-device.h>
#include <media/videobuf2-core.h>
#include <media/exynos_mc.h>
#include <soc/samsung/bts.h>
#include "regs-decon.h"
#include "decon_common.h"
#include "./panels/decon_lcd.h"
extern struct ion_device *ion_exynos;
extern struct decon_device *decon_int_drvdata;
extern int decon_log_level;
#if defined(CONFIG_ARM_EXYNOS7870_BUS_DEVFREQ)
#define CONFIG_DECON_DEVFREQ
#endif
/*
* Lets Keep it same as 7420. This is the count for
* maximum number of layers supported by this driver.
* Real number of HW layers (or Active layers) will be
* provided by device tree.
*/
#define MAX_DECON_WIN (7)
#define DECON_INT (0)
#define DRIVER_NAME "decon"
#define MAX_NAME_SIZE 32
#define MAX_DECON_PADS 9
#define MAX_BUF_PLANE_CNT 3
#define DECON_ENTER_LPD_CNT 3
#define MIN_BLK_MODE_WIDTH 144
#define MIN_BLK_MODE_HEIGHT 10
#define DECON_ENABLE 1
#define DECON_DISABLE 0
#define DECON_BACKGROUND 0
#define VSYNC_TIMEOUT_MSEC 200
#define MAX_BW_PER_WINDOW (2560 * 1600 * 4 * 60)
#define LCD_DEFAULT_BPP 24
#define SHADOW_OFFSET (0x7000)
#define DRM_DEV_DECON 3
#define DECON_CFW_OFFSET 3
#define EVT_TYPE_INT BIT(31)
#define EVT_TYPE_IOCTL BIT(30)
#define EVT_TYPE_ASYNC_EVT BIT(29)
#define EVT_TYPE_PM BIT(28)
#define EVT_TYPE_WININFO BIT(27)
#define DECON_LOG_LEVEL_ERR 3
#define DECON_LOG_LEVEL_WARN 4
#define DECON_LOG_LEVEL_INFO 6
#define DECON_LOG_LEVEL_DBG 7
#define DECON_UNDERRUN_THRESHOLD 300
#ifdef CONFIG_FB_WINDOW_UPDATE
#define DECON_WIN_UPDATE_IDX (7)
#define decon_win_update_dbg(fmt, ...) \
do { \
if (decon_log_level >= DECON_LOG_LEVEL_DBG) \
pr_info(pr_fmt(fmt), ##__VA_ARGS__); \
} while (0)
#else
#define decon_win_update_dbg(fmt, ...) (while (0))
#endif
#define decon_err(fmt, ...) \
do { \
if (decon_log_level >= DECON_LOG_LEVEL_ERR) \
pr_err(pr_fmt(fmt), ##__VA_ARGS__); \
} while (0)
#define decon_warn(fmt, ...) \
do { \
if (decon_log_level >= DECON_LOG_LEVEL_WARN) \
pr_warn(pr_fmt(fmt), ##__VA_ARGS__); \
} while (0)
#define decon_info(fmt, ...) \
do { \
if (decon_log_level >= DECON_LOG_LEVEL_INFO) \
pr_info(pr_fmt(fmt), ##__VA_ARGS__); \
} while (0)
#define decon_dbg(fmt, ...) \
do { \
if (decon_log_level >= DECON_LOG_LEVEL_DBG) \
pr_info(pr_fmt(fmt), ##__VA_ARGS__); \
} while (0)
/*
* DECON_STATE_ON : disp power on, decon/dsim clock on & lcd on
* DECON_STATE_LPD_ENT_REQ : disp power on, decon/dsim clock on, lcd on & request for LPD
* DECON_STATE_LPD_EXIT_REQ : disp power off, decon/dsim clock off, lcd on & request for LPD exit.
* DECON_STATE_LPD : disp power off, decon/dsim clock off & lcd on
* DECON_STATE_OFF : disp power off, decon/dsim clock off & lcd off
*/
enum decon_state {
DECON_STATE_INIT = 0,
DECON_STATE_ON,
DECON_STATE_LPD_ENT_REQ,
DECON_STATE_LPD_EXIT_REQ,
DECON_STATE_LPD,
DECON_STATE_OFF
};
enum decon_ip_version {
IP_VER_DECON_7I = BIT(0),
};
struct exynos_decon_platdata {
enum decon_ip_version ip_ver;
enum decon_psr_mode psr_mode;
enum decon_trig_mode trig_mode;
enum decon_dsi_mode dsi_mode;
int max_win;
int default_win;
u32 disp_pll_clk;
u32 disp_eclk;
u32 disp_vclk;
u32 disp_dvfs;
};
struct decon_vsync {
wait_queue_head_t wait;
ktime_t timestamp;
bool active;
int irq_refcount;
struct mutex irq_lock;
struct task_struct *thread;
};
/*
* @width: The width of display in mm
* @height: The height of display in mm
*/
struct decon_fb_videomode {
struct fb_videomode videomode;
unsigned short width;
unsigned short height;
u8 cs_setup_time;
u8 wr_setup_time;
u8 wr_act_time;
u8 wr_hold_time;
u8 auto_cmd_rate;
u8 frame_skip:2;
u8 rs_pol:1;
};
struct decon_fb_pd_win {
struct decon_fb_videomode win_mode;
unsigned short default_bpp;
unsigned short max_bpp;
unsigned short virtual_x;
unsigned short virtual_y;
unsigned short width;
unsigned short height;
};
struct decon_dma_buf_data {
struct ion_handle *ion_handle;
struct dma_buf *dma_buf;
struct dma_buf_attachment *attachment;
struct sg_table *sg_table;
dma_addr_t dma_addr;
struct sync_fence *fence;
};
struct decon_win_rect {
int x;
int y;
u32 w;
u32 h;
};
struct decon_resources {
struct clk *dpll; /* Display PLL */
struct clk *core_clk; /* Core CLock, APB, BUS */
struct clk *eclk; /* ECLK from MIF */
struct clk *eclk_leaf; /* ECLK Local (DISP PLL or MIF) */
struct clk *vclk; /* VCLK from MIF */
struct clk *vclk_leaf; /* VCLK Local (DISP PLL or MIF) */
};
struct decon_rect {
int left;
int top;
int right;
int bottom;
};
struct decon_win {
struct decon_fb_pd_win windata;
struct decon_device *decon;
struct fb_info *fbinfo;
struct media_pad pad;
struct decon_fb_videomode win_mode;
struct decon_dma_buf_data dma_buf_data[MAX_BUF_PLANE_CNT];
struct fb_var_screeninfo prev_var;
struct fb_fix_screeninfo prev_fix;
int fps;
int index;
int use;
int local;
unsigned long state;
u32 pseudo_palette[16];
};
struct decon_user_window {
int x;
int y;
};
struct s3c_fb_user_plane_alpha {
int channel;
unsigned char red;
unsigned char green;
unsigned char blue;
};
struct s3c_fb_user_chroma {
int enabled;
unsigned char red;
unsigned char green;
unsigned char blue;
};
struct s3c_fb_user_ion_client {
int fd[MAX_BUF_PLANE_CNT];
int offset;
};
enum decon_pixel_format {
/* RGB 32bit */
DECON_PIXEL_FORMAT_ARGB_8888 = 0,
DECON_PIXEL_FORMAT_ABGR_8888,
DECON_PIXEL_FORMAT_RGBA_8888,
DECON_PIXEL_FORMAT_BGRA_8888,
DECON_PIXEL_FORMAT_XRGB_8888,
DECON_PIXEL_FORMAT_XBGR_8888,
DECON_PIXEL_FORMAT_RGBX_8888,
DECON_PIXEL_FORMAT_BGRX_8888,
/* RGB 16 bit */
DECON_PIXEL_FORMAT_RGBA_5551,
DECON_PIXEL_FORMAT_RGB_565,
/* YUV422 2P */
DECON_PIXEL_FORMAT_NV16,
DECON_PIXEL_FORMAT_NV61,
/* YUV422 3P */
DECON_PIXEL_FORMAT_YVU422_3P,
/* YUV420 2P */
DECON_PIXEL_FORMAT_NV12,
DECON_PIXEL_FORMAT_NV21,
DECON_PIXEL_FORMAT_NV12M,
DECON_PIXEL_FORMAT_NV21M,
/* YUV420 3P */
DECON_PIXEL_FORMAT_YUV420,
DECON_PIXEL_FORMAT_YVU420,
DECON_PIXEL_FORMAT_YUV420M,
DECON_PIXEL_FORMAT_YVU420M,
DECON_PIXEL_FORMAT_NV21M_FULL,
DECON_PIXEL_FORMAT_MAX,
};
enum decon_blending {
DECON_BLENDING_NONE = 0,
DECON_BLENDING_PREMULT = 1,
DECON_BLENDING_COVERAGE = 2,
DECON_BLENDING_MAX = 3,
};
struct exynos_hdmi_data {
enum {
EXYNOS_HDMI_STATE_PRESET = 0,
EXYNOS_HDMI_STATE_ENUM_PRESET,
EXYNOS_HDMI_STATE_CEC_ADDR,
EXYNOS_HDMI_STATE_HDCP,
EXYNOS_HDMI_STATE_AUDIO,
} state;
struct v4l2_dv_timings timings;
struct v4l2_enum_dv_timings etimings;
__u32 cec_addr;
__u32 audio_info;
int hdcp;
};
enum vpp_rotate {
VPP_ROT_NORMAL = 0x0,
VPP_ROT_XFLIP,
VPP_ROT_YFLIP,
VPP_ROT_180,
VPP_ROT_90,
VPP_ROT_90_XFLIP,
VPP_ROT_90_YFLIP,
VPP_ROT_270,
};
enum vpp_csc_eq {
BT_601_NARROW = 0x0,
BT_601_WIDE,
BT_709_NARROW,
BT_709_WIDE,
};
struct vpp_params {
dma_addr_t addr[MAX_BUF_PLANE_CNT];
enum vpp_rotate rot;
enum vpp_csc_eq eq_mode;
};
struct decon_phys_addr {
unsigned long phy_addr[MAX_BUF_PLANE_CNT];
unsigned int phy_addr_len[MAX_BUF_PLANE_CNT];
};
struct decon_phys_old_info {
int win_id;
int pixel_format;
int plane;
unsigned long int phys_addr[MAX_BUF_PLANE_CNT];
unsigned int phys_addr_len[MAX_BUF_PLANE_CNT];
};
struct decon_frame {
int x;
int y;
u32 w;
u32 h;
u32 f_w;
u32 f_h;
};
struct decon_win_config {
enum {
DECON_WIN_STATE_DISABLED = 0,
DECON_WIN_STATE_COLOR,
DECON_WIN_STATE_BUFFER,
DECON_WIN_STATE_UPDATE,
} state;
union {
__u32 color;
struct {
int fd_idma[3];
int fence_fd;
int plane_alpha;
enum decon_blending blending;
enum decon_idma_type idma_type;
enum decon_pixel_format format;
struct vpp_params vpp_parm;
/* no read area of IDMA */
struct decon_win_rect block_area;
struct decon_win_rect transparent_area;
struct decon_win_rect opaque_area;
/* source framebuffer coordinates */
struct decon_frame src;
};
};
/* destination OSD coordinates */
struct decon_frame dst;
bool protection;
};
struct decon_reg_data {
struct list_head list;
u32 shadowcon;
u32 wincon[MAX_DECON_WIN];
u32 win_rgborder[MAX_DECON_WIN];
u32 winmap[MAX_DECON_WIN];
u32 vidosd_a[MAX_DECON_WIN];
u32 vidosd_b[MAX_DECON_WIN];
u32 vidosd_c[MAX_DECON_WIN];
u32 vidosd_d[MAX_DECON_WIN];
u32 vidw_alpha0[MAX_DECON_WIN];
u32 vidw_alpha1[MAX_DECON_WIN];
u32 blendeq[MAX_DECON_WIN - 1];
u32 buf_start[MAX_DECON_WIN];
struct decon_dma_buf_data dma_buf_data[MAX_DECON_WIN][MAX_BUF_PLANE_CNT];
unsigned int num_of_window;
u32 win_overlap_cnt;
u32 offset_x[MAX_DECON_WIN];
u32 offset_y[MAX_DECON_WIN];
u32 whole_w[MAX_DECON_WIN];
u32 whole_h[MAX_DECON_WIN];
struct decon_win_config win_config[MAX_DECON_WIN];
struct decon_win_rect block_rect[MAX_DECON_WIN];
struct decon_phys_addr phys_addr[MAX_DECON_WIN + 1];
#ifdef CONFIG_FB_WINDOW_UPDATE
struct decon_win_rect update_win;
bool need_update;
#endif
u64 cur_bw;
u64 bandwidth;
bool protection[MAX_DECON_WIN];
};
struct decon_win_config_data {
int fence;
int fd_odma;
struct decon_win_config config[MAX_DECON_WIN + 1];
};
union decon_ioctl_data {
struct decon_user_window user_window;
struct s3c_fb_user_plane_alpha user_alpha;
struct s3c_fb_user_chroma user_chroma;
struct exynos_hdmi_data hdmi_data;
struct decon_win_config_data win_data;
u32 vsync;
};
struct decon_underrun_stat {
u64 prev_bw;
int chmap;
int fifo_level;
int underrun_cnt;
unsigned long aclk;
unsigned long lh_disp0;
unsigned long mif_pll;
unsigned long used_windows;
};
#ifdef CONFIG_DECON_EVENT_LOG
#define DEFAULT_BASE_IDX (-1)
/**
* Display Subsystem event management status.
*
* These status labels are used internally by the DECON to indicate the
* current status of a device with operations.
*/
typedef enum disp_ss_event_type {
/* Related with FB interface */
DISP_EVT_BLANK = EVT_TYPE_IOCTL,
DISP_EVT_UNBLANK,
DISP_EVT_ACT_VSYNC,
DISP_EVT_DEACT_VSYNC,
DISP_EVT_WIN_CONFIG,
DISP_EVT_ACT_PROT,
DISP_EVT_DEACT_PROT,
/* Related with interrupt */
DISP_EVT_TE_INTERRUPT = EVT_TYPE_INT,
DISP_EVT_UNDERRUN,
DISP_EVT_DECON_FRAMEDONE,
DISP_EVT_DSIM_FRAMEDONE,
DISP_EVT_UPDATE_TIMEOUT,
DISP_EVT_LINECNT_TIMEOUT,
/* Related with async event */
DISP_EVT_UPDATE_HANDLER = EVT_TYPE_ASYNC_EVT,
DISP_EVT_DSIM_COMMAND,
DISP_EVT_TRIG_MASK,
DISP_EVT_DECON_FRAMEDONE_WAIT,
DISP_EVT_LINECNT_ZERO,
DISP_EVT_SIZE_ERR,
DISP_EVT_DSIM_INTR_ENABLE,
DISP_EVT_DSIM_INTR_DISABLE,
DISP_EVT_DECON_SHUTDOWN,
DISP_EVT_DSIM_SHUTDOWN,
DISP_EVT_WIN_CONFIG_PARAM = EVT_TYPE_WININFO,
DISP_EVT_UPDATE_PARAMS,
/* Related with PM */
DISP_EVT_DECON_SUSPEND = EVT_TYPE_PM,
DISP_EVT_DECON_RESUME,
DISP_EVT_ENTER_LPD,
DISP_EVT_EXIT_LPD,
DISP_EVT_DSIM_SUSPEND,
DISP_EVT_DSIM_RESUME,
DISP_EVT_ENTER_ULPS,
DISP_EVT_EXIT_ULPS,
DISP_EVT_VSYNC_TIMEOUT,
DISP_EVT_VSTATUS_TIMEOUT,
DISP_EVT_MAX, /* End of EVENT */
} disp_ss_event_t;
/* Related with PM */
struct disp_log_pm {
u32 pm_status; /* ACTIVE(1) or SUSPENDED(0) */
ktime_t elapsed; /* End time - Start time */
};
/* Related with S3CFB_WIN_CONFIG */
struct decon_update_reg_data {
bool need_update;
u32 overlap_cnt;
u32 bandwidth;
u32 wincon[MAX_DECON_WIN];
u32 offset_x[MAX_DECON_WIN];
u32 offset_y[MAX_DECON_WIN];
u32 whole_w[MAX_DECON_WIN];
u32 whole_h[MAX_DECON_WIN];
u32 vidosd_a[MAX_DECON_WIN];
u32 vidosd_b[MAX_DECON_WIN];
struct decon_win_config win_config[MAX_DECON_WIN];
struct decon_win_rect win;
};
/* Related with MIPI COMMAND read/write */
struct dsim_log_cmd_buf {
u32 id;
u8 buf;
};
/* Related with size mismatch error */
struct disp_ss_size_info {
u32 w_in;
u32 h_in;
u32 w_out;
u32 h_out;
};
/**
* struct disp_ss_log - Display Subsystem Log
* This struct includes DECON/DSIM
*/
struct disp_ss_log {
ktime_t time;
disp_ss_event_t type;
union {
struct disp_log_pm pm;
struct decon_update_reg_data reg;
struct dsim_log_cmd_buf cmd_buf;
struct decon_win_config_data win_data;
struct disp_ss_size_info size_mismatch;
} data;
};
/* bootloader framebuffer information */
struct disp_bootloader_fb_info {
u32 phy_addr;
u32 size;
u32 l;
u32 t;
u32 r;
u32 b;
u32 format;
};
/* Definitions below are used in the DECON */
#define DISP_EVENT_LOG_MAX SZ_2K
#define DISP_EVENT_PRINT_MAX 256
/* APIs below are used in the DECON/DSIM driver */
#define DISP_SS_EVENT_START() ktime_t start = ktime_get()
void DISP_SS_EVENT_LOG(disp_ss_event_t type, struct v4l2_subdev *sd, ktime_t time);
void DISP_SS_EVENT_LOG_WINCON(struct v4l2_subdev *sd, struct decon_reg_data *regs);
void DISP_SS_EVENT_LOG_UPDATE_PARAMS(struct v4l2_subdev *sd, struct decon_reg_data *regs);
void DISP_SS_EVENT_LOG_CMD(struct v4l2_subdev *sd, u32 cmd_id, unsigned long data);
void DISP_SS_EVENT_SHOW(struct seq_file *s, struct decon_device *decon, int base_idx, bool sync);
void DISP_SS_EVENT_LOG_WIN_CONFIG(struct v4l2_subdev *sd, struct decon_win_config_data *win_data);
void DISP_SS_EVENT_SIZE_ERR_LOG(struct v4l2_subdev *sd, struct disp_ss_size_info *info);
#else /*!*/
#define DISP_SS_EVENT_START(...) do { } while(0)
#define DISP_SS_EVENT_LOG(...) do { } while(0)
#define DISP_SS_EVENT_LOG_WINCON(...) do { } while(0)
#define DISP_SS_EVENT_LOG_CMD(...) do { } while(0)
#define DISP_SS_EVENT_SHOW(...) do { } while(0)
#define DISP_SS_EVENT_LOG_UPDATE_PARAMS(...) do { } while(0)
#define DISP_SS_EVENT_LOG_WIN_CONFIG(...) do { } while(0)
#define DISP_SS_EVENT_SIZE_ERR_LOG(...) do { } while(0)
#endif
/**
* END of CONFIG_DECON_EVENT_LOG
*/
struct decon_device {
void __iomem *regs;
struct device *dev;
struct exynos_decon_platdata *pdata;
struct media_pad pads[MAX_DECON_PADS];
struct v4l2_subdev sd;
struct decon_win *windows[MAX_DECON_WIN];
struct decon_resources res;
struct v4l2_subdev *output_sd;
struct exynos_md *mdev;
struct mutex update_regs_list_lock;
struct list_head update_regs_list;
struct task_struct *update_regs_thread;
struct kthread_worker update_regs_worker;
struct kthread_work update_regs_work;
struct mutex lpd_lock;
struct work_struct lpd_work;
struct workqueue_struct *lpd_wq;
atomic_t lpd_trig_cnt;
atomic_t lpd_block_cnt;
struct ion_client *ion_client;
struct sw_sync_timeline *timeline;
int timeline_max;
struct mutex output_lock;
struct mutex mutex;
spinlock_t slock;
struct decon_vsync vsync_info;
enum decon_state state;
enum decon_output_type out_type;
int mic_enabled;
int n_sink_pad;
int n_src_pad;
union decon_ioctl_data ioctl_data;
struct decon_lcd *lcd_info;
#ifdef CONFIG_FB_WINDOW_UPDATE
struct decon_win_rect update_win;
bool need_update;
#endif
struct decon_underrun_stat underrun_stat;
void __iomem *cam_status[2];
u32 prev_protection_status;
u32 cur_protection_bitmask;
unsigned int irq;
int frame_idle;
bool eint_en_status;
struct dentry *debug_root;
int frame_done_cnt_cur;
int frame_done_cnt_target;
int frame_start_cnt_cur;
int frame_start_cnt_target;
wait_queue_head_t wait_frmdone;
wait_queue_head_t wait_vstatus;
ktime_t trig_mask_timestamp;
int idle_ip_index;
u64 max_win_bw;
u64 prev_bw;
#ifdef CONFIG_DECON_EVENT_LOG
wait_queue_head_t event_wait;
struct dentry *mask;
struct dentry *debug_event;
struct disp_ss_log disp_ss_log[DISP_EVENT_LOG_MAX];
atomic_t disp_ss_log_idx;
#endif
u32 disp_ss_log_unmask;
#ifdef CONFIG_DECON_USE_BOOTLOADER_FB
struct disp_bootloader_fb_info bl_fb_info;
#endif
struct pinctrl *pinctrl;
struct pinctrl_state *decon_te_on;
struct pinctrl_state *decon_te_off;
struct decon_phys_old_info old_info;
};
static inline struct decon_device *get_decon_drvdata(u32 id)
{
return decon_int_drvdata;
}
/* register access subroutines */
static inline u32 decon_read(u32 id, u32 reg_id)
{
struct decon_device *decon = get_decon_drvdata(id);
return readl(decon->regs + reg_id);
}
static inline u32 decon_read_mask(u32 id, u32 reg_id, u32 mask)
{
u32 val = decon_read(id, reg_id);
val &= (~mask);
return val;
}
static inline void decon_write(u32 id, u32 reg_id, u32 val)
{
struct decon_device *decon = get_decon_drvdata(id);
writel(val, decon->regs + reg_id);
}
static inline void decon_write_mask(u32 id, u32 reg_id, u32 val, u32 mask)
{
struct decon_device *decon = get_decon_drvdata(id);
u32 old = decon_read(id, reg_id);
val = (val & mask) | (old & ~mask);
writel(val, decon->regs + reg_id);
}
/* common function API */
bool decon_validate_x_alignment(struct decon_device *decon, int x, u32 w,
u32 bits_per_pixel);
int find_subdev_mipi(struct decon_device *decon);
int find_subdev_hdmi(struct decon_device *decon);
int create_link_mipi(struct decon_device *decon);
int create_link_hdmi(struct decon_device *decon);
int decon_int_register_irq(struct platform_device *pdev, struct decon_device *decon);
irqreturn_t decon_int_irq_handler(int irq, void *dev_data);
int decon_int_get_clocks(struct decon_device *decon);
void decon_int_set_clocks(struct decon_device *decon);
int decon_int_register_lpd_work(struct decon_device *decon);
int decon_exit_lpd(struct decon_device *decon);
int decon_lpd_block_exit(struct decon_device *decon);
int decon_lcd_off(struct decon_device *decon);
int decon_enable(struct decon_device *decon);
int decon_disable(struct decon_device *decon);
void decon_lpd_enable(void);
/* internal only function API */
int decon_fb_config_eint_for_te(struct platform_device *pdev, struct decon_device *decon);
int decon_int_create_vsync_thread(struct decon_device *decon);
int decon_int_create_psr_thread(struct decon_device *decon);
void decon_int_destroy_vsync_thread(struct decon_device *decon);
void decon_int_destroy_psr_thread(struct decon_device *decon);
int decon_int_set_lcd_config(struct decon_device *decon);
int decon_check_var(struct fb_var_screeninfo *var, struct fb_info *info);
int decon_pan_display(struct fb_var_screeninfo *var,
struct fb_info *info);
/* external only function API */
struct decon_lcd *find_porch(struct v4l2_mbus_framefmt mbus_fmt);
int decon_get_hdmi_config(struct decon_device *decon,
struct exynos_hdmi_data *hdmi_data);
int decon_set_hdmi_config(struct decon_device *decon,
struct exynos_hdmi_data *hdmi_data);
/* POWER and ClOCK API */
int init_display_decon_clocks(struct device *dev);
int disable_display_decon_clocks(struct device *dev);
void decon_clock_on(struct decon_device *decon);
void decon_clock_off(struct decon_device *decon);
u32 decon_reg_get_cam_status(void __iomem *);
void decon_reg_set_block_mode(u32 id, u32 win_idx, u32 x, u32 y, u32 h, u32 w, u32 enable);
void decon_reg_set_tui_va(u32 id, u32 va);
void decon_set_qos(struct decon_device *decon, struct decon_reg_data *regs,
bool is_after, bool is_default_qos);
/* LPD related */
static inline void decon_lpd_block(struct decon_device *decon)
{
atomic_inc(&decon->lpd_block_cnt);
}
static inline bool decon_is_lpd_blocked(struct decon_device *decon)
{
return (atomic_read(&decon->lpd_block_cnt) > 0);
}
static inline int decon_get_lpd_block_cnt(struct decon_device *decon)
{
return atomic_read(&decon->lpd_block_cnt);
}
static inline void decon_lpd_unblock(struct decon_device *decon)
{
if (decon_is_lpd_blocked(decon))
atomic_dec(&decon->lpd_block_cnt);
}
static inline void decon_lpd_block_reset(struct decon_device *decon)
{
atomic_set(&decon->lpd_block_cnt, 0);
}
static inline void decon_lpd_trig_reset(struct decon_device *decon)
{
atomic_set(&decon->lpd_trig_cnt, 0);
}
#ifdef CONFIG_DECON_LPD_DISPLAY_WITH_CAMERA
static inline bool is_cam_not_running(struct decon_device *decon)
{
return !(decon_reg_get_cam_status(decon->cam_status[0]) & 0xF);
}
#else
static inline bool is_cam_not_running(struct decon_device *decon)
{
return true;
}
#endif
static inline bool decon_lpd_enter_cond(struct decon_device *decon)
{
return ((atomic_inc_return(&decon->lpd_trig_cnt) > DECON_ENTER_LPD_CNT) &&
(atomic_read(&decon->lpd_block_cnt) <= 0) && is_cam_not_running(decon));
}
static inline bool is_any_pending_frames(struct decon_device *decon)
{
return ((decon->timeline_max - decon->timeline->value) > 1);
}
/* IOCTL commands */
#define S3CFB_WIN_POSITION _IOW('F', 203, \
struct decon_user_window)
#define S3CFB_WIN_SET_PLANE_ALPHA _IOW('F', 204, \
struct s3c_fb_user_plane_alpha)
#define S3CFB_WIN_SET_CHROMA _IOW('F', 205, \
struct s3c_fb_user_chroma)
#define S3CFB_SET_VSYNC_INT _IOW('F', 206, __u32)
#define S3CFB_GET_ION_USER_HANDLE _IOWR('F', 208, \
struct s3c_fb_user_ion_client)
#define S3CFB_WIN_CONFIG _IOW('F', 209, \
struct decon_win_config_data)
#define S3CFB_WIN_PSR_EXIT _IOW('F', 210, int)
#define EXYNOS_GET_HDMI_CONFIG _IOW('F', 220, \
struct exynos_hdmi_data)
#define EXYNOS_SET_HDMI_CONFIG _IOW('F', 221, \
struct exynos_hdmi_data)
#define DECON_IOC_LPD_EXIT_LOCK _IOW('L', 0, u32)
#define DECON_IOC_LPD_UNLOCK _IOW('L', 1, u32)
#endif /* ___SAMSUNG_DECON_H__ */

View file

@ -0,0 +1,149 @@
/*
* Copyright (c) 2015 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Header file for Exynos DECON driver
*
* 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.
*/
#ifndef ___SAMSUNG_DECON_COMMON_H__
#define ___SAMSUNG_DECON_COMMON_H__
#include "./panels/decon_lcd.h"
enum decon_dsi_mode {
DSI_MODE_SINGLE = 0,
};
enum decon_trig_mode {
DECON_HW_TRIG = 0,
DECON_SW_TRIG
};
enum decon_hold_scheme {
DECON_VCLK_HOLD = 0x00,
DECON_VCLK_RUNNING = 0x01,
DECON_VCLK_RUN_VDEN_DISABLE = 0x3,
};
enum decon_rgb_order {
DECON_RGB = 0x0,
DECON_GBR = 0x1,
DECON_BRG = 0x2,
DECON_BGR = 0x4,
DECON_RBG = 0x5,
DECON_GRB = 0x6,
};
enum decon_set_trig {
DECON_TRIG_DISABLE = 0,
DECON_TRIG_ENABLE
};
enum decon_set_eclk_idle_gate {
DECON_ECLK_IDLE_GATE_DISABLE = 0,
DECON_ECLK_IDLE_GATE_ENABLE
};
enum decon_idma_type {
IDMA_G0 = 0x0,
IDMA_G1,
IDMA_VG0,
IDMA_VG1,
IDMA_VGR0,
IDMA_VGR1,
IDMA_G2,
IDMA_G3,
IDMA_MAX
};
enum decon_output_type {
DECON_OUT_DSI = 0,
};
struct decon_psr_info {
enum decon_psr_mode psr_mode;
enum decon_trig_mode trig_mode;
enum decon_output_type out_type;
};
struct decon_init_param {
struct decon_psr_info psr;
struct decon_lcd *lcd_info;
u32 nr_windows;
};
struct decon_regs_data {
u32 wincon;
u32 winmap;
u32 vidosd_a;
u32 vidosd_b;
u32 vidosd_c;
u32 vidosd_d;
u32 vidosd_e;
u32 vidw_buf_start;
u32 vidw_whole_w;
u32 vidw_whole_h;
u32 vidw_offset_x;
u32 vidw_offset_y;
u32 blendeq;
u32 vidw_plane2_buf_start;
u32 vidw_plane3_buf_start;
enum decon_idma_type type;
};
/* CAL APIs list */
void decon_reg_init(u32 id, enum decon_dsi_mode dsi_mode, struct decon_init_param *p);
void decon_reg_init_probe(u32 id, enum decon_dsi_mode dsi_mode, struct decon_init_param *p);
void decon_reg_start(u32 id, enum decon_dsi_mode dsi_mode, struct decon_psr_info *psr);
int decon_reg_stop(u32 id, enum decon_dsi_mode dsi_mode, struct decon_psr_info *psr);
void decon_reg_set_regs_data(u32 id, int win_idx, struct decon_regs_data *regs);
void decon_reg_set_int(u32 id, struct decon_psr_info *psr, enum decon_dsi_mode dsi_mode, u32 en);
void decon_reg_set_trigger(u32 id, enum decon_dsi_mode dsi_mode,
enum decon_trig_mode trig, enum decon_set_trig en);
int decon_reg_wait_for_update_timeout(u32 id, unsigned long timeout);
void decon_reg_shadow_protect_win(u32 id, u32 win_idx, u32 protect);
void decon_reg_activate_window(u32 id, u32 index);
void decon_enable_eclk_idle_gate(u32 id, enum decon_set_eclk_idle_gate en);
/* CAL raw functions list */
int decon_reg_reset(u32 id);
void decon_reg_set_default_win_channel(u32 id);
void decon_reg_set_clkgate_mode(u32 id, u32 en);
void decon_reg_blend_alpha_bits(u32 id, u32 alpha_bits);
void decon_reg_set_vidout(u32 id, struct decon_psr_info *psr, enum decon_dsi_mode dsi_mode, u32 en);
void decon_reg_set_crc(u32 id, u32 en);
void decon_reg_set_fixvclk(u32 id, int dsi_idx, enum decon_hold_scheme mode);
void decon_reg_clear_win(u32 id, int win_idx);
void decon_reg_set_rgb_order(u32 id, int dsi_idx, enum decon_rgb_order order);
void decon_reg_set_porch(u32 id, int dsi_idx, struct decon_lcd *info);
void decon_reg_set_linecnt_op_threshold(u32 id, int dsi_idx, u32 th);
void decon_reg_set_clkval(u32 id, u32 clkdiv);
void decon_reg_direct_on_off(u32 id, u32 en);
void decon_reg_per_frame_off(u32 id);
void decon_reg_set_freerun_mode(u32 id, u32 en);
void decon_reg_update_standalone(u32 id);
void decon_reg_configure_lcd(u32 id, enum decon_dsi_mode dsi_mode, struct decon_lcd *lcd_info);
void decon_reg_configure_trigger(u32 id, enum decon_trig_mode mode);
void decon_reg_set_winmap(u32 id, u32 idx, u32 color, u32 en);
u32 decon_reg_get_linecnt(u32 id, int dsi_idx);
u32 decon_reg_get_vstatus(u32 id, int dsi_idx);
int decon_reg_wait_linecnt_is_zero_timeout(u32 id, int dsi_idx, unsigned long timeout);
u32 decon_reg_get_stop_status(u32 id);
int decon_reg_wait_stop_status_timeout(u32 id, unsigned long timeout);
int decon_reg_is_win_enabled(u32 id, int win_idx);
int decon_reg_is_shadow_updated(u32 id);
void decon_reg_config_mic(u32 id, int dsi_idx, struct decon_lcd *lcd_info);
void decon_reg_clear_int(u32 id);
void decon_reg_config_win_channel(u32 id, u32 win_idx, enum decon_idma_type type);
void decon_reg_set_mdnie_pclk(u32 id, u32 en);
void decon_reg_enable_mdnie(u32 id, u32 en);
void decon_reg_set_mdnie_blank(u32 id, u32 front, u32 sync, u32 back, u32 line);
u32 decon_reg_get_lineval(u32 id, int dsi_idx, struct decon_lcd *lcd_info);
u32 decon_reg_get_hozval(u32 id, int dsi_idx, struct decon_lcd *lcd_info);
#endif /* ___SAMSUNG_DECON_COMMON_H__ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,646 @@
/*
* Copyright (c) 2015 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Helper file for Samsung EXYNOS DECON driver
*
* 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.
*/
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/pm_runtime.h>
#include "decon.h"
#include "dsim.h"
#include "decon_helper.h"
#include "./panels/lcd_ctrl.h"
#include <video/mipi_display.h>
inline int decon_is_no_bootloader_fb(struct decon_device *decon)
{
#ifdef CONFIG_DECON_USE_BOOTLOADER_FB
return !decon->bl_fb_info.phy_addr;
#else
return 1;
#endif
}
inline int decon_clk_set_parent(struct device *dev, struct clk *p, struct clk *c)
{
clk_set_parent(c, p);
return 0;
}
int decon_clk_set_rate(struct device *dev, struct clk *clk,
const char *conid, unsigned long rate)
{
if (IS_ERR_OR_NULL(clk)) {
if (IS_ERR_OR_NULL(conid)) {
decon_err("%s: couldn't set clock(%ld)\n", __func__, rate);
return -ENODEV;
}
clk = clk_get(dev, conid);
clk_set_rate(clk, rate);
clk_put(clk);
} else {
clk_set_rate(clk, rate);
}
return 0;
}
void decon_to_psr_info(struct decon_device *decon, struct decon_psr_info *psr)
{
psr->psr_mode = decon->pdata->psr_mode;
psr->trig_mode = decon->pdata->trig_mode;
psr->out_type = decon->out_type;
}
void decon_to_init_param(struct decon_device *decon, struct decon_init_param *p)
{
struct decon_lcd *lcd_info = decon->lcd_info;
struct v4l2_mbus_framefmt mbus_fmt;
mbus_fmt.width = 0;
mbus_fmt.height = 0;
mbus_fmt.code = 0;
mbus_fmt.field = 0;
mbus_fmt.colorspace = 0;
p->lcd_info = lcd_info;
p->psr.psr_mode = decon->pdata->psr_mode;
p->psr.trig_mode = decon->pdata->trig_mode;
p->psr.out_type = decon->out_type;
p->nr_windows = decon->pdata->max_win;
}
/**
* ----- APIs for DISPLAY_SUBSYSTEM_EVENT_LOG -----
*/
/* ===== STATIC APIs ===== */
#ifdef CONFIG_DECON_EVENT_LOG
/* logging a event related with DECON */
void disp_log_win_config(char *ts, struct seq_file *s,
struct decon_win_config *config)
{
int win;
struct decon_win_config *cfg;
char *state[] = { "D", "C", "B", "U" };
char *blending[] = { "N", "P", "C" };
char *idma[] = { "G0", "G1", "V0", "V1", "VR0", "VR1", "G2" };
for (win = 0; win < MAX_DECON_WIN; win++) {
cfg = &config[win];
if (cfg->state == DECON_WIN_STATE_DISABLED)
continue;
if (cfg->state == DECON_WIN_STATE_COLOR) {
seq_printf(s, "%s\t[%d] %s, C(%d), D(%d,%d,%d,%d) "
"P(%d)\n",
ts, win, state[cfg->state], cfg->color,
cfg->dst.x, cfg->dst.y,
cfg->dst.x + cfg->dst.w,
cfg->dst.y + cfg->dst.h,
cfg->protection);
} else {
seq_printf(s, "%s\t[%d] %s,(%d,%d,%d), F(%d) P(%d)"
" A(%d), %s, %s, f(%d) (%d,%d,%d,%d,%d,%d) ->"
" (%d,%d,%d,%d,%d,%d)\n",
ts, win, state[cfg->state], cfg->fd_idma[0],
cfg->fd_idma[1], cfg->fd_idma[2],
cfg->fence_fd, cfg->protection,
cfg->plane_alpha, blending[cfg->blending],
idma[cfg->idma_type], cfg->format,
cfg->src.x, cfg->src.y,
cfg->src.x + cfg->src.w,
cfg->src.y + cfg->src.h,
cfg->src.f_w, cfg->src.f_h,
cfg->dst.x, cfg->dst.y,
cfg->dst.x + cfg->dst.w,
cfg->dst.y + cfg->dst.h,
cfg->dst.f_w, cfg->dst.f_h);
}
}
}
void disp_log_update_info(char *ts, struct seq_file *s,
struct decon_update_reg_data *reg)
{
int win;
for (win = 0; win < MAX_DECON_WIN; win++) {
if (!(reg->wincon[win] & WINCON_ENWIN))
continue;
seq_printf(s, "%s\t[%d] U(%d): (%d,%d,%d,%d) -> "
"(%d,%d,%d,%d)\n",
ts, win, reg->need_update,
reg->offset_x[win], reg->offset_y[win],
reg->whole_w[win], reg->whole_h[win],
(reg->vidosd_a[win] >> 13) & 0x1fff,
(reg->vidosd_a[win]) & 0x1fff,
(reg->vidosd_b[win] >> 13) & 0x1fff,
(reg->vidosd_b[win]) & 0x1fff);
}
}
void disp_ss_event_log_win_update(char *ts, struct seq_file *s,
struct decon_update_reg_data *reg)
{
disp_log_win_config(ts, s, reg->win_config);
disp_log_update_info(ts, s, reg);
}
void disp_ss_event_log_win_config(char *ts, struct seq_file *s,
struct decon_win_config_data *win_cfg)
{
disp_log_win_config(ts, s, win_cfg->config);
}
static inline void disp_ss_event_log_decon
(disp_ss_event_t type, struct v4l2_subdev *sd, ktime_t time)
{
struct decon_device *decon = container_of(sd, struct decon_device, sd);
int idx = atomic_inc_return(&decon->disp_ss_log_idx) % DISP_EVENT_LOG_MAX;
struct disp_ss_log *log = &decon->disp_ss_log[idx];
if (time.tv64)
log->time = time;
else
log->time = ktime_get();
log->type = type;
switch (type) {
case DISP_EVT_DECON_SUSPEND:
case DISP_EVT_DECON_RESUME:
case DISP_EVT_ENTER_LPD:
case DISP_EVT_EXIT_LPD:
log->data.pm.pm_status = pm_runtime_active(decon->dev);
log->data.pm.elapsed = ktime_sub(ktime_get(), log->time);
break;
case DISP_EVT_TE_INTERRUPT:
case DISP_EVT_UNDERRUN:
case DISP_EVT_LINECNT_ZERO:
break;
default:
/* Any remaining types will be log just time and type */
break;
}
}
/* logging a event related with DSIM */
static inline void disp_ss_event_log_dsim
(disp_ss_event_t type, struct v4l2_subdev *sd, ktime_t time)
{
struct dsim_device *dsim = container_of(sd, struct dsim_device, sd);
struct decon_device *decon = get_decon_drvdata(dsim->id);
int idx = atomic_inc_return(&decon->disp_ss_log_idx) % DISP_EVENT_LOG_MAX;
struct disp_ss_log *log = &decon->disp_ss_log[idx];
if (time.tv64)
log->time = time;
else
log->time = ktime_get();
log->type = type;
switch (type) {
case DISP_EVT_DSIM_SUSPEND:
case DISP_EVT_DSIM_RESUME:
case DISP_EVT_ENTER_ULPS:
case DISP_EVT_EXIT_ULPS:
log->data.pm.pm_status = pm_runtime_active(dsim->dev);
log->data.pm.elapsed = ktime_sub(ktime_get(), log->time);
break;
default:
/* Any remaining types will be log just time and type */
break;
}
}
/* If event are happend continuously, then ignore */
static bool disp_ss_event_ignore
(disp_ss_event_t type, struct decon_device *decon)
{
int latest = atomic_read(&decon->disp_ss_log_idx) % DISP_EVENT_LOG_MAX;
struct disp_ss_log *log;
int idx;
/* Seek a oldest from current index */
idx = (latest + DISP_EVENT_LOG_MAX - DECON_ENTER_LPD_CNT) % DISP_EVENT_LOG_MAX;
do {
if (++idx >= DISP_EVENT_LOG_MAX)
idx = 0;
log = &decon->disp_ss_log[idx];
if (log->type != type)
return false;
} while (latest != idx);
return true;
}
/* ===== EXTERN APIs ===== */
/* Common API to log a event related with DECON/DSIM */
void DISP_SS_EVENT_LOG(disp_ss_event_t type, struct v4l2_subdev *sd, ktime_t time)
{
struct decon_device *decon = get_decon_drvdata(0);
if (!decon || IS_ERR_OR_NULL(decon->debug_event))
return;
if (!(decon->disp_ss_log_unmask & type))
return;
/* log a eventy softly */
switch (type) {
case DISP_EVT_TE_INTERRUPT:
case DISP_EVT_UNDERRUN:
/* If occurs continuously, skipped. It is a burden */
if (disp_ss_event_ignore(type, decon))
break;
case DISP_EVT_BLANK:
case DISP_EVT_UNBLANK:
case DISP_EVT_ENTER_LPD:
case DISP_EVT_EXIT_LPD:
case DISP_EVT_DECON_SUSPEND:
case DISP_EVT_DECON_RESUME:
case DISP_EVT_LINECNT_ZERO:
case DISP_EVT_TRIG_MASK:
case DISP_EVT_DECON_FRAMEDONE:
case DISP_EVT_DECON_FRAMEDONE_WAIT:
case DISP_EVT_ACT_VSYNC:
case DISP_EVT_DEACT_VSYNC:
case DISP_EVT_WIN_CONFIG:
case DISP_EVT_ACT_PROT:
case DISP_EVT_DEACT_PROT:
case DISP_EVT_UPDATE_TIMEOUT:
case DISP_EVT_LINECNT_TIMEOUT:
case DISP_EVT_VSYNC_TIMEOUT:
case DISP_EVT_VSTATUS_TIMEOUT:
disp_ss_event_log_decon(type, sd, time);
break;
case DISP_EVT_ENTER_ULPS:
case DISP_EVT_EXIT_ULPS:
case DISP_EVT_DSIM_SUSPEND:
case DISP_EVT_DSIM_RESUME:
case DISP_EVT_DSIM_FRAMEDONE:
case DISP_EVT_DSIM_INTR_ENABLE:
case DISP_EVT_DSIM_INTR_DISABLE:
disp_ss_event_log_dsim(type, sd, time);
break;
default:
return;
}
wake_up_interruptible_all(&decon->event_wait);
}
void DISP_SS_EVENT_LOG_WINCON(struct v4l2_subdev *sd, struct decon_reg_data *regs)
{
struct decon_device *decon = container_of(sd, struct decon_device, sd);
int idx = atomic_inc_return(&decon->disp_ss_log_idx) % DISP_EVENT_LOG_MAX;
struct disp_ss_log *log = &decon->disp_ss_log[idx];
int win = 0;
bool window_updated = false;
log->time = ktime_get();
log->type = DISP_EVT_UPDATE_HANDLER;
for (win = 0; win < 3; win++) {
if (regs->wincon[win] & WINCON_ENWIN) {
log->data.reg.wincon[win] = regs->wincon[win];
log->data.reg.offset_x[win] = regs->offset_x[win];
log->data.reg.offset_y[win] = regs->offset_y[win];
log->data.reg.whole_w[win] = regs->whole_w[win];
log->data.reg.whole_h[win] = regs->whole_h[win];
log->data.reg.vidosd_a[win] = regs->vidosd_a[win];
log->data.reg.vidosd_b[win] = regs->vidosd_b[win];
memcpy(&log->data.reg.win_config[win], &regs->win_config[win],
sizeof(struct decon_win_config));
} else {
log->data.reg.win_config[win].state = DECON_WIN_STATE_DISABLED;
}
}
#ifdef CONFIG_FB_WINDOW_UPDATE
if ((regs->need_update) ||
(decon->need_update && regs->update_win.w)) {
window_updated = true;
memcpy(&log->data.reg.win, &regs->update_win,
sizeof(struct decon_rect));
}
#endif
if (!window_updated) {
log->data.reg.win.x = 0;
log->data.reg.win.y = 0;
log->data.reg.win.w = decon->lcd_info->xres;
log->data.reg.win.h = decon->lcd_info->yres;
}
}
void DISP_SS_EVENT_LOG_UPDATE_PARAMS(struct v4l2_subdev *sd,
struct decon_reg_data *regs)
{
struct decon_device *decon = container_of(sd, struct decon_device, sd);
int idx = atomic_inc_return(&decon->disp_ss_log_idx) % DISP_EVENT_LOG_MAX;
struct disp_ss_log *log = &decon->disp_ss_log[idx];
int win = 0;
if (!(decon->disp_ss_log_unmask & DISP_EVT_UPDATE_PARAMS))
return;
log->time = ktime_get();
log->type = DISP_EVT_UPDATE_PARAMS;
log->data.reg.overlap_cnt = regs->win_overlap_cnt;
log->data.reg.bandwidth = regs->cur_bw;
for (win = 0; win < MAX_DECON_WIN; win++) {
log->data.reg.wincon[win] = 0;
if (regs->wincon[win] & WINCON_ENWIN) {
log->data.reg.wincon[win] = regs->wincon[win];
log->data.reg.offset_x[win] = regs->offset_x[win];
log->data.reg.offset_y[win] = regs->offset_y[win];
log->data.reg.whole_w[win] = regs->whole_w[win];
log->data.reg.whole_h[win] = regs->whole_h[win];
log->data.reg.vidosd_a[win] = regs->vidosd_a[win];
log->data.reg.vidosd_b[win] = regs->vidosd_b[win];
memcpy(&log->data.reg.win_config[win], &regs->win_config[win],
sizeof(struct decon_win_config));
}
}
#ifdef CONFIG_FB_WINDOW_UPDATE
log->data.reg.need_update = regs->need_update;
if ((regs->need_update) ||
(decon->need_update && regs->update_win.w)) {
memcpy(&log->data.reg.win, &regs->update_win,
sizeof(struct decon_rect));
} else {
log->data.reg.win.x = 0;
log->data.reg.win.y = 0;
log->data.reg.win.w = decon->lcd_info->xres;
log->data.reg.win.h = decon->lcd_info->yres;
}
#else
memset(&log->data.reg.win, 0, sizeof(struct decon_rect));
#endif
wake_up_interruptible_all(&decon->event_wait);
}
void DISP_SS_EVENT_LOG_WIN_CONFIG(struct v4l2_subdev *sd, struct decon_win_config_data *win_data)
{
struct decon_device *decon = container_of(sd, struct decon_device, sd);
int idx = atomic_inc_return(&decon->disp_ss_log_idx) % DISP_EVENT_LOG_MAX;
struct disp_ss_log *log = &decon->disp_ss_log[idx];
if (!(decon->disp_ss_log_unmask & DISP_EVT_WIN_CONFIG_PARAM))
return;
log->time = ktime_get();
log->type = DISP_EVT_WIN_CONFIG_PARAM;
memcpy(&log->data.win_data, win_data, sizeof(struct decon_win_config_data));
wake_up_interruptible_all(&decon->event_wait);
}
/* Common API to log a event related with DSIM COMMAND */
void DISP_SS_EVENT_LOG_CMD(struct v4l2_subdev *sd, u32 cmd_id, unsigned long data)
{
struct dsim_device *dsim = container_of(sd, struct dsim_device, sd);
struct decon_device *decon = get_decon_drvdata(dsim->id);
int idx;
struct disp_ss_log *log;
if (!decon || IS_ERR_OR_NULL(decon->debug_event))
return;
if (!(decon->disp_ss_log_unmask & DISP_EVT_DSIM_COMMAND))
return;
idx = atomic_inc_return(&decon->disp_ss_log_idx) % DISP_EVENT_LOG_MAX;
log = &decon->disp_ss_log[idx];
log->time = ktime_get();
log->type = DISP_EVT_DSIM_COMMAND;
if (cmd_id == MIPI_DSI_DCS_LONG_WRITE)
log->data.cmd_buf.buf = *(u8 *)(data);
else
log->data.cmd_buf.buf = (u8)data;
wake_up_interruptible_all(&decon->event_wait);
}
void DISP_SS_EVENT_SIZE_ERR_LOG(struct v4l2_subdev *sd, struct disp_ss_size_info *info)
{
struct dsim_device *dsim = container_of(sd, struct dsim_device, sd);
struct decon_device *decon = get_decon_drvdata(dsim->id);
int idx;
struct disp_ss_log *log;
if (!decon || IS_ERR_OR_NULL(decon->debug_event))
return;
idx = atomic_inc_return(&decon->disp_ss_log_idx) % DISP_EVENT_LOG_MAX;
log = &decon->disp_ss_log[idx];
log->time = ktime_get();
log->type = DISP_EVT_SIZE_ERR;
memcpy(&log->data.size_mismatch, info, sizeof(struct disp_ss_size_info));
wake_up_interruptible_all(&decon->event_wait);
}
/* display logged events related with DECON */
void DISP_SS_EVENT_SHOW(struct seq_file *s, struct decon_device *decon,
int base_idx, bool sync)
{
int idx = atomic_read(&decon->disp_ss_log_idx) % DISP_EVENT_LOG_MAX;
struct disp_ss_log *log;
int latest = idx;
struct timeval tv;
char ts[20];
if (!sync) {
/* TITLE */
seq_printf(s, "-------------------DECON EVENT LOGGER ----------------------\n");
seq_printf(s, "-- STATUS: LPD(%s) ", IS_ENABLED(CONFIG_DECON_LPD_DISPLAY) ? "on" : "off");
seq_printf(s, "PKTGO(%s) ", IS_ENABLED(CONFIG_DECON_MIPI_DSI_PKTGO) ? "on" : "off");
seq_printf(s, "BlockMode(%s) ", IS_ENABLED(CONFIG_DECON_BLOCKING_MODE) ? "on" : "off");
seq_printf(s, "Window_Update(%s)\n", IS_ENABLED(CONFIG_FB_WINDOW_UPDATE) ? "on" : "off");
seq_printf(s, "-------------------------------------------------------------\n");
seq_printf(s, "%14s %20s %20s\n",
"Time", "Event ID", "Remarks");
seq_printf(s, "-------------------------------------------------------------\n");
if (idx < 0) {
seq_printf(s, "No Events available. Done.\n");
seq_printf(s, "-------------------------------------------------------------\n");
return;
}
}
if (sync) {
if (base_idx != DEFAULT_BASE_IDX)
idx = base_idx % DISP_EVENT_LOG_MAX;
} else {
/* Seek a oldest from current index */
idx = (idx + DISP_EVENT_LOG_MAX - DISP_EVENT_PRINT_MAX) % DISP_EVENT_LOG_MAX;
}
do {
if (++idx >= DISP_EVENT_LOG_MAX)
idx = 0;
/* Seek a index */
log = &decon->disp_ss_log[idx];
/* TIME */
tv = ktime_to_timeval(log->time);
sprintf(ts, "[%6ld.%06ld] ", tv.tv_sec, tv.tv_usec);
seq_printf(s, "%s", ts);
/* EVETN ID + Information */
switch (log->type) {
case DISP_EVT_BLANK:
seq_printf(s, "%20s %20s", "FB_BLANK", "-\n");
break;
case DISP_EVT_UNBLANK:
seq_printf(s, "%20s %20s", "FB_UNBLANK", "-\n");
break;
case DISP_EVT_ACT_VSYNC:
seq_printf(s, "%20s %20s", "ACT_VSYNC", "-\n");
break;
case DISP_EVT_DEACT_VSYNC:
seq_printf(s, "%20s %20s", "DEACT_VSYNC", "-\n");
break;
case DISP_EVT_WIN_CONFIG:
seq_printf(s, "%20s %20s", "WIN_CONFIG", "-\n");
break;
case DISP_EVT_WIN_CONFIG_PARAM:
seq_printf(s, "%20s %d %20s", "WIN_CONFIG_PARAM", log->data.win_data.fd_odma, "-\n");
disp_ss_event_log_win_config(ts, s, &log->data.win_data);
break;
case DISP_EVT_TE_INTERRUPT:
seq_printf(s, "%20s %20s", "TE_INTERRUPT", "-\n");
break;
case DISP_EVT_UNDERRUN:
seq_printf(s, "%20s %20s", "UNDER_RUN", "-\n");
break;
case DISP_EVT_DSIM_FRAMEDONE:
seq_printf(s, "%20s %20s", "DSIM_FRAME_DONE", "-\n");
break;
case DISP_EVT_DECON_FRAMEDONE:
seq_printf(s, "%20s %20s", "DECON_FRAME_DONE", "-\n");
break;
case DISP_EVT_TRIG_MASK:
seq_printf(s, "%20s %20s", "TRIG_MASK", "-\n");
break;
case DISP_EVT_DECON_FRAMEDONE_WAIT:
seq_printf(s, "%20s %20s", "FRAMEDONE_WAIT", "-\n");
break;
case DISP_EVT_ACT_PROT:
seq_printf(s, "%20s %20s", "PROTECTION_ENABLE", "-\n");
break;
case DISP_EVT_DEACT_PROT:
seq_printf(s, "%20s %20s", "PROTECTION_DISABLE", "-\n");
break;
case DISP_EVT_UPDATE_TIMEOUT:
seq_printf(s, "%20s %20s", "UPDATE_TIMEOUT", "-\n");
break;
case DISP_EVT_LINECNT_TIMEOUT:
seq_printf(s, "%20s %20s", "LINECNT_TIMEOUT", "-\n");
break;
case DISP_EVT_UPDATE_HANDLER:
seq_printf(s, "%20s ", "UPDATE_HANDLER");
seq_printf(s, "overlap=%d, bw=0x%x, (%d,%d,%d,%d) U=%d\n",
log->data.reg.overlap_cnt,
log->data.reg.bandwidth,
log->data.reg.win.x,
log->data.reg.win.y,
log->data.reg.win.x + log->data.reg.win.w,
log->data.reg.win.y + log->data.reg.win.h,
log->data.reg.need_update);
break;
case DISP_EVT_UPDATE_PARAMS:
seq_printf(s, "%20s ", "UPDATE_PARAMS");
seq_printf(s, "overlap=%d, bw=0x%x, (%d,%d,%d,%d) U=%d\n",
log->data.reg.overlap_cnt,
log->data.reg.bandwidth,
log->data.reg.win.x,
log->data.reg.win.y,
log->data.reg.win.w,
log->data.reg.win.h,
log->data.reg.need_update);
disp_ss_event_log_win_update(ts, s,
&log->data.reg);
break;
case DISP_EVT_DSIM_COMMAND:
seq_printf(s, "%20s ", "DSIM_COMMAND");
seq_printf(s, "id=0x%x, command=0x%x\n",
log->data.cmd_buf.id,
log->data.cmd_buf.buf);
break;
case DISP_EVT_DECON_SUSPEND:
seq_printf(s, "%20s %20s", "DECON_SUSPEND", "-\n");
break;
case DISP_EVT_DECON_RESUME:
seq_printf(s, "%20s %20s", "DECON_RESUME", "-\n");
break;
case DISP_EVT_ENTER_LPD:
seq_printf(s, "%20s ", "ENTER_LPD");
tv = ktime_to_timeval(log->data.pm.elapsed);
seq_printf(s, "pm=%s, elapsed=[%ld.%03lds]\n",
log->data.pm.pm_status ? "active ":"suspend",
tv.tv_sec, tv.tv_usec/1000);
break;
case DISP_EVT_EXIT_LPD:
seq_printf(s, "%20s ", "EXIT_LPD");
tv = ktime_to_timeval(log->data.pm.elapsed);
seq_printf(s, "pm=%s, elapsed=[%ld.%03lds]\n",
log->data.pm.pm_status ? "active ":"suspend",
tv.tv_sec, tv.tv_usec/1000);
break;
case DISP_EVT_DSIM_SUSPEND:
seq_printf(s, "%20s %20s", "DSIM_SUSPEND", "-\n");
break;
case DISP_EVT_DSIM_RESUME:
seq_printf(s, "%20s %20s", "DSIM_RESUME", "-\n");
break;
case DISP_EVT_ENTER_ULPS:
seq_printf(s, "%20s ", "ENTER_ULPS");
tv = ktime_to_timeval(log->data.pm.elapsed);
seq_printf(s, "pm=%s, elapsed=[%ld.%03lds]\n",
log->data.pm.pm_status ? "active ":"suspend",
tv.tv_sec, tv.tv_usec/1000);
break;
case DISP_EVT_EXIT_ULPS:
seq_printf(s, "%20s ", "EXIT_ULPS");
tv = ktime_to_timeval(log->data.pm.elapsed);
seq_printf(s, "pm=%s, elapsed=[%ld.%03lds]\n",
log->data.pm.pm_status ? "active ":"suspend",
tv.tv_sec, tv.tv_usec/1000);
break;
case DISP_EVT_DSIM_INTR_ENABLE:
seq_printf(s, "%20s %20s", "DSIM_INTR_ENABLE", "-\n");
break;
case DISP_EVT_DSIM_INTR_DISABLE:
seq_printf(s, "%20s %20s", "DSIM_INTR_DISABLE", "-\n");
break;
default:
break;
}
} while (latest != idx);
if (!sync)
seq_printf(s, "-------------------------------------------------------------\n");
return;
}
#endif

View file

@ -0,0 +1,27 @@
/*
* Copyright (c) 2015 Samsung Electronics Co., Ltd.
* http://www.samsung.com
*
* Header file for Exynos DECON driver
*
* 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.
*/
#ifndef __SAMSUNG_DECON_HELPER_H__
#define __SAMSUNG_DECON_HELPER_H__
#include <linux/device.h>
#include "decon.h"
int decon_clk_set_rate(struct device *dev, struct clk *clk,
const char *conid, unsigned long rate);
int decon_clk_set_parent(struct device *dev, struct clk *p, struct clk *c);
void decon_to_psr_info(struct decon_device *decon, struct decon_psr_info *psr);
void decon_to_init_param(struct decon_device *decon, struct decon_init_param *p);
int decon_get_psr_mode_from_config(void);
int decon_is_no_bootloader_fb(struct decon_device *decon);
#endif /* __SAMSUNG_DECON_HELPER_H__ */

View file

@ -0,0 +1,615 @@
/* drivers/video/fbdev/exynos/decon_7870/decon_reg_7870.c
*
* Copyright 2015 Samsung Electronics
*
* 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.
*/
/* use this definition when you test CAL on firmware */
/* #define FW_TEST */
#ifdef FW_TEST
#include "decon_fw.h"
#else
#include "decon.h"
#endif
/******************* CAL raw functions implementation *************************/
int decon_reg_reset(u32 id)
{
int tries;
decon_write(id, VIDCON0, VIDCON0_SWRESET);
for (tries = 2000; tries; --tries) {
if (~decon_read(id, VIDCON0) & VIDCON0_SWRESET)
break;
udelay(10);
}
if (!tries) {
decon_err("failed to reset Decon\n");
return -EBUSY;
}
return 0;
}
void decon_reg_set_default_win_channel(u32 id)
{
decon_write_mask(id, WINCHMAP0, WINCHMAP_DMA(0, 1), WINCHMAP_MASK(0));
decon_write_mask(id, WINCHMAP0, WINCHMAP_DMA(1, 1), WINCHMAP_MASK(1));
decon_write_mask(id, WINCHMAP0, WINCHMAP_DMA(2, 1), WINCHMAP_MASK(2));
}
void decon_reg_set_clkgate_mode(u32 id, u32 en)
{
}
void decon_reg_blend_alpha_bits(u32 id, u32 alpha_bits)
{
decon_write(id, BLENDCON, alpha_bits);
}
void decon_reg_set_vidout(u32 id, struct decon_psr_info *psr,
enum decon_dsi_mode dsi_mode, u32 en)
{
if (psr->psr_mode == DECON_MIPI_COMMAND_MODE)
decon_write_mask(id, VIDOUTCON0, VIDOUTCON0_I80IF_F,
VIDOUTCON0_IF_MASK);
else
decon_write_mask(id, VIDOUTCON0, VIDOUTCON0_RGBIF_F,
VIDOUTCON0_IF_MASK);
decon_write_mask(id, VIDOUTCON0, en ? ~0 : 0, VIDOUTCON0_LCD_ON_F);
}
void decon_reg_set_crc(u32 id, u32 en)
{
u32 val = en ? ~0 : 0;
decon_write_mask(id, CRCCTRL, val,
CRCCTRL_CRCCLKEN | CRCCTRL_CRCEN | CRCCTRL_CRCSTART_F);
}
void decon_reg_set_fixvclk(u32 id, int dsi_idx, enum decon_hold_scheme mode)
{
u32 val = VIDCON1_VCLK_HOLD;
switch (mode) {
case DECON_VCLK_HOLD:
val = VIDCON1_VCLK_HOLD;
break;
case DECON_VCLK_RUNNING:
val = VIDCON1_VCLK_RUN;
break;
case DECON_VCLK_RUN_VDEN_DISABLE:
val = VIDCON1_VCLK_RUN_VDEN_DISABLE;
break;
}
decon_write_mask(id, VIDCON1(dsi_idx), val, VIDCON1_VCLK_MASK);
}
void decon_reg_clear_win(u32 id, int win_idx)
{
decon_write(id, WINCON(win_idx), WINCON_RESET_VALUE);
decon_write(id, VIDOSD_A(win_idx), 0);
decon_write(id, VIDOSD_B(win_idx), 0);
decon_write(id, VIDOSD_C(win_idx), 0);
decon_write(id, VIDOSD_D(win_idx), 0);
}
void decon_reg_set_rgb_order(u32 id, int dsi_idx, enum decon_rgb_order order)
{
u32 val = VIDCON1_RGB_ORDER_O_RGB;
switch (order) {
case DECON_RGB:
val = VIDCON1_RGB_ORDER_O_RGB;
break;
case DECON_GBR:
val = VIDCON1_RGB_ORDER_O_GBR;
break;
case DECON_BRG:
val = VIDCON1_RGB_ORDER_O_BRG;
break;
case DECON_BGR:
val = VIDCON1_RGB_ORDER_O_BGR;
break;
case DECON_RBG:
val = VIDCON1_RGB_ORDER_O_RBG;
break;
case DECON_GRB:
val = VIDCON1_RGB_ORDER_O_GRB;
break;
}
decon_write_mask(id, VIDCON1(dsi_idx), val, VIDCON1_RGB_ORDER_O_MASK);
}
void decon_reg_set_porch(u32 id, int dsi_idx, struct decon_lcd *info)
{
u32 val = 0;
val = VIDTCON0_VBPD(info->vbp - 1) | VIDTCON0_VFPD(info->vfp - 1);
decon_write(id, VIDTCON0(dsi_idx), val);
val = VIDTCON1_VSPW(info->vsa - 1);
decon_write(id, VIDTCON1(dsi_idx), val);
val = VIDTCON2_HBPD(info->hbp - 1) | VIDTCON2_HFPD(info->hfp - 1);
decon_write(id, VIDTCON2(dsi_idx), val);
val = VIDTCON3_HSPW(info->hsa - 1);
decon_write(id, VIDTCON3(dsi_idx), val);
val = VIDTCON4_LINEVAL(info->yres - 1) |
VIDTCON4_HOZVAL(info->xres - 1);
decon_write(id, VIDTCON4(dsi_idx), val);
}
void decon_reg_set_linecnt_op_threshold(u32 id, int dsi_idx, u32 th)
{
decon_write(id, LINECNT_OP_THRESHOLD(dsi_idx), th);
}
void decon_reg_set_clkval(u32 id, u32 clkdiv)
{
decon_write_mask(id, VCLKCON0, ~0, VCLKCON0_CLKVALUP);
}
void decon_reg_direct_on_off(u32 id, u32 en)
{
u32 val = en ? ~0 : 0;
decon_write_mask(id, VIDCON0, val, VIDCON0_ENVID_F | VIDCON0_ENVID);
}
void decon_reg_per_frame_off(u32 id)
{
decon_write_mask(id, VIDCON0, 0, VIDCON0_ENVID_F);
}
void decon_reg_set_freerun_mode(u32 id, u32 en)
{
decon_write_mask(id, VCLKCON0, en ? ~0 : 0, VCLKCON0_VLCKFREE);
}
void decon_reg_update_standalone(u32 id)
{
decon_write_mask(id, DECON_UPDATE, ~0, DECON_UPDATE_STANDALONE_F);
}
void decon_reg_configure_lcd(u32 id, enum decon_dsi_mode dsi_mode,
struct decon_lcd *lcd_info)
{
decon_reg_set_rgb_order(id, 0, DECON_RGB);
decon_reg_set_porch(id, 0, lcd_info);
if (lcd_info->mic_enabled)
decon_reg_config_mic(id, 0, lcd_info);
if (lcd_info->mode == DECON_VIDEO_MODE)
decon_reg_set_linecnt_op_threshold(id, 0, lcd_info->yres - 1);
decon_reg_set_clkval(id, 0);
decon_reg_set_freerun_mode(id, 1);
decon_reg_direct_on_off(id, 0);
}
void decon_reg_configure_trigger(u32 id, enum decon_trig_mode mode)
{
u32 val, mask;
mask = TRIGCON_SWTRIGEN_I80_RGB | TRIGCON_HWTRIGEN_I80_RGB |
TRIGCON_TRIG_SAVE_DISABLE_SYNCMGR;
if (mode == DECON_SW_TRIG) {
val = TRIGCON_SWTRIGEN_I80_RGB;
} else {
val = TRIGCON_HWTRIGEN_I80_RGB | TRIGCON_HWTRIG_AUTO_MASK |
TRIGCON_TRIG_SAVE_DISABLE_SYNCMGR;
}
decon_write_mask(id, TRIGCON, val, mask);
}
void decon_reg_set_winmap(u32 id, u32 idx, u32 color, u32 en)
{
u32 val = en ? WIN_MAP_MAP : 0;
decon_reg_shadow_protect_win(id, idx, 1);
val |= WIN_MAP_MAP_COLOUR(color);
decon_write_mask(id, WIN_MAP(idx), val,
WIN_MAP_MAP | WIN_MAP_MAP_COLOUR_MASK);
decon_reg_shadow_protect_win(id, idx, 0);
}
u32 decon_reg_get_linecnt(u32 id, int dsi_idx)
{
return VIDCON1_LINECNT_GET(decon_read(id, VIDCON1(dsi_idx)));
}
u32 decon_reg_get_vstatus(u32 id, int dsi_idx)
{
return decon_read(id, VIDCON1(dsi_idx)) & VIDCON1_VSTATUS_MASK;
}
/* timeout : usec */
int decon_reg_wait_linecnt_is_zero_timeout(u32 id, int dsi_idx,
unsigned long timeout)
{
unsigned long delay_time = 10;
unsigned long cnt = timeout / delay_time;
u32 linecnt, vstatus;
do {
linecnt = decon_reg_get_linecnt(id, dsi_idx);
if (!linecnt) {
vstatus = decon_reg_get_vstatus(id, dsi_idx);
if (vstatus == VIDCON1_VSTATUS_IDLE)
break;
}
cnt--;
udelay(delay_time);
} while (cnt);
if (!cnt) {
decon_err("wait timeout linecount is zero(%u)\n", linecnt);
return -EBUSY;
}
return 0;
}
u32 decon_reg_get_stop_status(u32 id)
{
u32 val;
val = decon_read(id, VIDCON0);
if (val & VIDCON0_DECON_STOP_STATUS)
return 1;
return 0;
}
int decon_reg_wait_stop_status_timeout(u32 id, unsigned long timeout)
{
unsigned long delay_time = 10;
unsigned long cnt = timeout / delay_time;
u32 status;
do {
status = decon_reg_get_stop_status(id);
cnt--;
udelay(delay_time);
} while (status && cnt);
if (!cnt) {
decon_err("wait timeout decon stop status(%u)\n", status);
return -EBUSY;
}
return 0;
}
int decon_reg_is_win_enabled(u32 id, int win_idx)
{
if (decon_read(id, WINCON(win_idx)) & WINCON_ENWIN)
return 1;
return 0;
}
int decon_reg_is_shadow_updated(u32 id)
{
return 0;
}
void decon_reg_config_mic(u32 id, int dsi_idx, struct decon_lcd *lcd_info)
{
}
void decon_reg_clear_int(u32 id)
{
u32 mask;
mask = VIDINTCON1_INT_I80 | VIDINTCON1_INT_FRAME | VIDINTCON1_INT_FIFO;
decon_write_mask(id, VIDINTCON1, 0, mask);
}
void decon_reg_config_win_channel(u32 id, u32 win_idx,
enum decon_idma_type type)
{
switch (type) {
case IDMA_G0:
case IDMA_G1:
decon_write_mask(id, WINCHMAP0, WINCHMAP_DMA(type + 1, win_idx),
WINCHMAP_MASK(win_idx));
break;
case IDMA_VG0:
case IDMA_VG1:
case IDMA_VGR0:
case IDMA_VGR1:
case IDMA_G2:
case IDMA_G3:
decon_write_mask(id, WINCHMAP0, WINCHMAP_DMA(0, win_idx),
WINCHMAP_MASK(win_idx));
break;
default:
decon_err("channel(0x%x) is not valid\n", type);
return;
}
decon_dbg("decon-%s win[%d]-type[%d] WINCHMAP:%#x\n", "int",
win_idx, type, decon_read(id, WINCHMAP0));
}
/***************** CAL APIs implementation *******************/
void decon_reg_init(u32 id, enum decon_dsi_mode dsi_mode,
struct decon_init_param *p)
{
int win_idx;
struct decon_lcd *lcd_info = p->lcd_info;
struct decon_psr_info *psr = &p->psr;
decon_reg_reset(id);
decon_reg_set_clkgate_mode(id, 0);
decon_reg_blend_alpha_bits(id, BLENDCON_NEW_8BIT_ALPHA_VALUE);
decon_reg_set_vidout(id, psr, dsi_mode, 1);
decon_reg_set_crc(id, 0);
/* Does exynos7870 decon always use DECON_VCLK_HOLD ? No */
if (psr->psr_mode == DECON_MIPI_COMMAND_MODE)
decon_reg_set_fixvclk(id, 0, DECON_VCLK_RUN_VDEN_DISABLE);
else
decon_reg_set_fixvclk(id, 0, DECON_VCLK_HOLD);
for (win_idx = 0; win_idx < p->nr_windows; win_idx++)
decon_reg_clear_win(id, win_idx);
/* RGB order -> porch values -> LINECNT_OP_THRESHOLD -> clock divider
* -> freerun mode --> stop DECON */
decon_reg_configure_lcd(id, dsi_mode, lcd_info);
if (psr->psr_mode == DECON_MIPI_COMMAND_MODE)
decon_reg_configure_trigger(id, psr->trig_mode);
/* asserted interrupt should be cleared before initializing decon hw */
decon_reg_clear_int(id);
}
void decon_reg_init_probe(u32 id, enum decon_dsi_mode dsi_mode,
struct decon_init_param *p)
{
struct decon_lcd *lcd_info = p->lcd_info;
struct decon_psr_info *psr = &p->psr;
decon_reg_set_clkgate_mode(id, 0);
decon_reg_blend_alpha_bits(id, BLENDCON_NEW_8BIT_ALPHA_VALUE);
decon_reg_set_vidout(id, psr, dsi_mode, 1);
/* Does exynos7870 decon always use DECON_VCLK_HOLD ? */
if (psr->psr_mode == DECON_MIPI_COMMAND_MODE)
decon_reg_set_fixvclk(id, 0, DECON_VCLK_RUN_VDEN_DISABLE);
else
decon_reg_set_fixvclk(id, 0, DECON_VCLK_HOLD);
decon_reg_set_rgb_order(id, 0, DECON_RGB);
decon_reg_set_porch(id, 0, lcd_info);
if (lcd_info->mic_enabled)
decon_reg_config_mic(id, 0, lcd_info);
if (lcd_info->mode == DECON_VIDEO_MODE)
decon_reg_set_linecnt_op_threshold(id, 0, lcd_info->yres - 1);
decon_reg_set_clkval(id, 0);
decon_reg_set_freerun_mode(id, 1);
decon_reg_update_standalone(id);
if (psr->psr_mode == DECON_MIPI_COMMAND_MODE)
decon_reg_configure_trigger(id, psr->trig_mode);
}
void decon_reg_start(u32 id, enum decon_dsi_mode dsi_mode,
struct decon_psr_info *psr)
{
decon_reg_direct_on_off(id, 1);
decon_reg_update_standalone(id);
if ((psr->psr_mode == DECON_MIPI_COMMAND_MODE) &&
(psr->trig_mode == DECON_HW_TRIG))
decon_reg_set_trigger(id, dsi_mode, psr->trig_mode,
DECON_TRIG_ENABLE);
}
int decon_reg_stop(u32 id, enum decon_dsi_mode dsi_mode,
struct decon_psr_info *psr)
{
int ret = 0;
if ((psr->psr_mode == DECON_MIPI_COMMAND_MODE) &&
(psr->trig_mode == DECON_HW_TRIG)) {
decon_reg_set_trigger(id, dsi_mode, psr->trig_mode,
DECON_TRIG_DISABLE);
}
if (decon_reg_get_stop_status(id) == 1) {
/* timeout : 50ms */
/* TODO: dual DSI scenario */
ret = decon_reg_wait_linecnt_is_zero_timeout(id, 0, 50 * 1000);
if (ret)
goto err;
if (psr->psr_mode == DECON_MIPI_COMMAND_MODE)
decon_reg_direct_on_off(id, 0);
else
decon_reg_per_frame_off(id);
/* timeout : 20ms */
ret = decon_reg_wait_stop_status_timeout(id, 20 * 1000);
if (ret)
goto err;
}
err:
ret = decon_reg_reset(id);
return ret;
}
void decon_reg_set_regs_data(u32 id, int win_idx,
struct decon_regs_data *regs)
{
u32 val;
if (regs->wincon & WINCON_ENWIN)
decon_reg_config_win_channel(id, win_idx, regs->type);
val = regs->wincon & WINCON_OUTSTAND_MAX_MASK;
if (val < (WINCON_OUTSTAND_MAX_DEFAULT << WINCON_OUTSTAND_MAX_POS)) {
val = regs->wincon & (~WINCON_OUTSTAND_MAX_MASK);
regs->wincon = val | (WINCON_OUTSTAND_MAX_DEFAULT <<
WINCON_OUTSTAND_MAX_POS);
}
decon_write(id, WINCON(win_idx), regs->wincon);
decon_write(id, WIN_MAP(win_idx), regs->winmap);
if (regs->winmap & WIN_MAP_MAP) {
decon_write_mask(id, WINCHMAP0, WINCHMAP_DMA(0x7, win_idx),
WINCHMAP_MASK(win_idx));
}
decon_write(id, VIDOSD_A(win_idx), regs->vidosd_a);
decon_write(id, VIDOSD_B(win_idx), regs->vidosd_b);
decon_write(id, VIDOSD_C(win_idx), regs->vidosd_c);
decon_write(id, VIDOSD_D(win_idx), regs->vidosd_d);
decon_write(id, VIDW_ADD0(win_idx), regs->vidw_buf_start);
decon_write(id, VIDW_WHOLE_X(win_idx), regs->vidw_whole_w);
decon_write(id, VIDW_WHOLE_Y(win_idx), regs->vidw_whole_h);
decon_write(id, VIDW_OFFSET_X(win_idx), regs->vidw_offset_x);
decon_write(id, VIDW_OFFSET_Y(win_idx), regs->vidw_offset_y);
decon_write(id, VIDW_ADD2(win_idx), regs->vidw_plane2_buf_start);
decon_write(id, VIDW_ADD3(win_idx), regs->vidw_plane3_buf_start);
if (win_idx)
decon_write(id, BLENDE(win_idx - 1), regs->blendeq);
decon_dbg("%s: regs->type(%d)\n", __func__, regs->type);
}
void decon_reg_set_int(u32 id, struct decon_psr_info *psr,
enum decon_dsi_mode dsi_mode, u32 en)
{
u32 val;
if (en) {
val = VIDINTCON0_INT_ENABLE | VIDINTCON0_FIFOLEVEL_EMPTY;
if (psr->psr_mode == DECON_MIPI_COMMAND_MODE) {
decon_write_mask(id, VIDINTCON1, ~0,
VIDINTCON1_INT_I80);
val |= VIDINTCON0_INT_FIFO | VIDINTCON0_INT_I80_EN | VIDINTCON0_INT_FRAME
| VIDINTCON0_FRAMESEL0_VSYNC;
} else {
val |= VIDINTCON0_INT_FIFO | VIDINTCON0_INT_FRAME
| VIDINTCON0_FRAMESEL0_VSYNC;
}
decon_write_mask(id, VIDINTCON0, val, ~0);
} else {
decon_write_mask(id, VIDINTCON0, 0, VIDINTCON0_INT_ENABLE);
}
}
void decon_enable_eclk_idle_gate(u32 id, enum decon_set_eclk_idle_gate en)
{
u32 val = (en == DECON_ECLK_IDLE_GATE_ENABLE) ? ~0 : 0;
decon_write_mask(id, VCLKCON0, val, ECLK_IDLE_GATE_EN);
}
/* It is needed to unmask hw trigger and mask asynchronously for dual DSI */
/* enable(unmask) / disable(mask) hw trigger */
void decon_reg_set_trigger(u32 id, enum decon_dsi_mode dsi_mode,
enum decon_trig_mode trig, enum decon_set_trig en)
{
u32 val = (en == DECON_TRIG_ENABLE) ? ~0 : 0;
u32 mask;
if (trig == DECON_SW_TRIG)
mask = TRIGCON_SWTRIGCMD_I80_RGB;
else
mask = TRIGCON_HWTRIGMASK_DISPIF0;
decon_write_mask(id, TRIGCON, val, mask);
}
/* wait until shadow update is finished */
int decon_reg_wait_for_update_timeout(u32 id, unsigned long timeout)
{
unsigned long delay_time = 100;
unsigned long cnt = timeout / delay_time;
while ((decon_read(id, DECON_UPDATE) & DECON_UPDATE_STANDALONE_F) &&
--cnt)
udelay(delay_time);
if (!cnt) {
decon_err("timeout of updating decon registers\n");
return -EBUSY;
}
return 0;
}
/* prohibit shadow update during writing something to SFR */
void decon_reg_shadow_protect_win(u32 id, u32 win_idx, u32 protect)
{
u32 val = protect ? ~0 : 0;
decon_write_mask(id, SHADOWCON, val, SHADOWCON_WIN_PROTECT(win_idx));
}
/* enable each window */
void decon_reg_activate_window(u32 id, u32 index)
{
decon_write_mask(id, WINCON(index), ~0, WINCON_ENWIN);
decon_reg_update_standalone(id);
}
void decon_reg_set_block_mode(u32 id, u32 win_idx, u32 x, u32 y, u32 w,
u32 h, u32 en)
{
u32 val = en ? ~0 : 0;
u32 blk_offset = 0, blk_size = 0;
blk_offset = VIDW_BLKOFFSET_Y_F(y) | VIDW_BLKOFFSET_X_F(x);
blk_size = VIDW_BLKSIZE_W_F(w) | VIDW_BLKSIZE_H_F(h);
decon_write_mask(id, VIDW_BLKOFFSET(win_idx), blk_offset,
VIDW_BLKOFFSET_MASK);
decon_write_mask(id, VIDW_BLKSIZE(win_idx), blk_size,
VIDW_BLKSIZE_MASK);
decon_write_mask(id, WINCON(win_idx), val, WINCON_BLK_EN_F);
}
void decon_reg_set_tui_va(u32 id, u32 va)
{
decon_write(id, VIDW_ADD2(6), va);
}
u32 decon_reg_get_lineval(u32 id, int dsi_idx, struct decon_lcd *lcd_info)
{
u32 val;
val = decon_read(id, VIDTCON4(dsi_idx) + SHADOW_OFFSET);
return VIDTCONx_LINEVAL_GET(val) + 1;
}
u32 decon_reg_get_hozval(u32 id, int dsi_idx, struct decon_lcd *lcd_info)
{
u32 val;
val = decon_read(id, VIDTCON4(dsi_idx) + SHADOW_OFFSET);
return VIDTCONx_HOZVAL_GET(val) + 1;
}

View file

@ -0,0 +1,230 @@
/* linux/drivers/video/fbdev/exynos/decon_7870/dsim.h
*
* Header file for Samsung MIPI-DSI common driver.
*
* Copyright (c) 2015 Samsung Electronics
* Haowei Li <haowei.li@samsung.com>
*
* 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.
*/
#ifndef __DSIM_H__
#define __DSIM_H__
#include <linux/device.h>
#include <linux/fb.h>
#include <linux/notifier.h>
#include <linux/kernel.h>
#include <linux/regulator/consumer.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <media/v4l2-subdev.h>
#include <media/media-entity.h>
#include "./panels/decon_lcd.h"
#include "regs-dsim.h"
#include "dsim_common.h"
#define DSIM_PAD_SINK 0
#define DSIM_PADS_NUM 1
#define DSIM_RX_FIFO_READ_DONE (0x30800002)
#define DSIM_MAX_RX_FIFO (64)
#define dsim_err(fmt, ...) \
do { \
pr_err(pr_fmt(fmt), ##__VA_ARGS__); \
} while (0)
#define dsim_info(fmt, ...) \
do { \
pr_info(pr_fmt(fmt), ##__VA_ARGS__); \
} while (0)
#define dsim_dbg(fmt, ...) \
do { \
pr_debug(pr_fmt(fmt), ##__VA_ARGS__); \
} while (0)
#define call_panel_ops(q, op, args...) \
(((q)->panel_ops->op) ? ((q)->panel_ops->op(args)) : 0)
extern struct dsim_device *dsim0_for_decon;
extern struct dsim_device *dsim1_for_decon;
extern struct mipi_dsim_lcd_driver s6e3ha0_mipi_lcd_driver;
extern struct mipi_dsim_lcd_driver s6e3ha2k_mipi_lcd_driver;
extern struct mipi_dsim_lcd_driver s6e3hf2_mipi_lcd_driver;
extern struct mipi_dsim_lcd_driver s6e3hf2_wqhd_mipi_lcd_driver;
extern struct mipi_dsim_lcd_driver s6e3fa0_mipi_lcd_driver;
extern struct mipi_dsim_lcd_driver ea8064g_mipi_lcd_driver;
enum mipi_dsim_pktgo_state {
DSIM_PKTGO_DISABLED,
DSIM_PKTGO_STANDBY,
DSIM_PKTGO_ENABLED
};
/* operation state of dsim driver */
enum dsim_state {
DSIM_STATE_HSCLKEN, /* HS clock was enabled. */
DSIM_STATE_ULPS, /* DSIM was entered ULPS state */
DSIM_STATE_SUSPEND /* DSIM is suspend state */
};
struct dsim_resources {
struct clk *pclk;
struct clk *dphy_esc;
struct clk *dphy_byte;
struct clk *rgb_vclk0;
struct clk *pclk_disp;
int lcd_power[2];
int lcd_reset;
};
struct panel_private {
struct backlight_device *bd;
unsigned int power;
unsigned int lcdConnected;
};
struct dsim_device {
struct device *dev;
void *decon;
struct dsim_resources res;
unsigned int irq;
void __iomem *reg_base;
enum dsim_state state;
unsigned int data_lane;
unsigned long hs_clk;
unsigned long byte_clk;
unsigned long escape_clk;
unsigned char freq_band;
struct notifier_block fb_notif;
struct lcd_device *lcd;
unsigned int enabled;
struct decon_lcd lcd_info;
struct dphy_timing_value timing;
int pktgo;
int id;
u32 data_lane_cnt;
struct mipi_dsim_lcd_driver *panel_ops;
spinlock_t slock;
struct mutex lock;
struct v4l2_subdev sd;
struct media_pad pad;
struct panel_private priv;
struct dsim_clks_param clks_param;
struct phy *phy;
};
/**
* driver structure for mipi-dsi based lcd panel.
*
* this structure should be registered by lcd panel driver.
* mipi-dsi driver seeks lcd panel registered through name field
* and calls these callback functions in appropriate time.
*/
struct mipi_dsim_lcd_driver {
int (*probe)(struct dsim_device *dsim);
int (*suspend)(struct dsim_device *dsim);
int (*displayon)(struct dsim_device *dsim);
int (*resume)(struct dsim_device *dsim);
int (*dump)(struct dsim_device *dsim);
};
int dsim_write_data(struct dsim_device *dsim, unsigned int data_id,
unsigned long data0, unsigned int data1);
int dsim_read_data(struct dsim_device *dsim, u32 data_id, u32 addr,
u32 count, u8 *buf);
#ifdef CONFIG_DECON_MIPI_DSI_PKTGO
void dsim_pkt_go_ready(struct dsim_device *dsim);
void dsim_pkt_go_enable(struct dsim_device *dsim, bool enable);
#endif
static inline struct dsim_device *get_dsim_drvdata(u32 id)
{
if (id)
return dsim1_for_decon;
else
return dsim0_for_decon;
}
static inline int dsim_rd_data(u32 id, u32 cmd_id,
u32 addr, u32 size, u8 *buf)
{
int ret;
struct dsim_device *dsim = get_dsim_drvdata(id);
ret = dsim_read_data(dsim, cmd_id, addr, size, buf);
if (ret)
return ret;
return 0;
}
static inline int dsim_wr_data(u32 id, u32 cmd_id, unsigned long d0, u32 d1)
{
int ret;
struct dsim_device *dsim = get_dsim_drvdata(id);
ret = dsim_write_data(dsim, cmd_id, d0, d1);
if (ret)
return ret;
return 0;
}
/* register access subroutines */
static inline u32 dsim_read(u32 id, u32 reg_id)
{
struct dsim_device *dsim = get_dsim_drvdata(id);
return readl(dsim->reg_base + reg_id);
}
static inline u32 dsim_read_mask(u32 id, u32 reg_id, u32 mask)
{
u32 val = dsim_read(id, reg_id);
val &= (mask);
return val;
}
static inline void dsim_write(u32 id, u32 reg_id, u32 val)
{
struct dsim_device *dsim = get_dsim_drvdata(id);
writel(val, dsim->reg_base + reg_id);
}
static inline void dsim_write_mask(u32 id, u32 reg_id, u32 val, u32 mask)
{
struct dsim_device *dsim = get_dsim_drvdata(id);
u32 old = dsim_read(id, reg_id);
val = (val & mask) | (old & ~mask);
writel(val, dsim->reg_base + reg_id);
}
u32 dsim_reg_get_yres(u32 id);
u32 dsim_reg_get_xres(u32 id);
#define DSIM_IOC_ENTER_ULPS _IOW('D', 0, u32)
#define DSIM_IOC_LCD_OFF _IOW('D', 1, u32)
#define DSIM_IOC_PKT_GO_ENABLE _IOW('D', 2, u32)
#define DSIM_IOC_PKT_GO_DISABLE _IOW('D', 3, u32)
#define DSIM_IOC_PKT_GO_READY _IOW('D', 4, u32)
#define DSIM_IOC_GET_LCD_INFO _IOW('D', 5, struct decon_lcd *)
#define DSIM_IOC_PARTIAL_CMD _IOW('D', 6, u32)
#define DSIM_IOC_SET_PORCH _IOW('D', 7, struct decon_lcd *)
#define DSIM_IOC_DUMP _IOW('D', 8, u32)
#define DSIM_IOC_VSYNC _IOW('D', 9, u32)
#endif /* __DSIM_H__ */

View file

@ -0,0 +1,169 @@
/* dsim_common.h
*
* Header file for Samsung MIPI-DSI lowlevel driver.
*
* Copyright (c) 2015 Samsung Electronics
* Jiun Yu <jiun.yu@samsung.com>
*
* 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.
*/
#ifndef _DSIM_COMMON_H_
#define _DSIM_COMMON_H_
#include "./panels/decon_lcd.h"
#define DSIM_PIXEL_FORMAT_RGB24 0x7
#define DSIM_PIXEL_FORMAT_RGB18 0x6
#define DSIM_PIXEL_FORMAT_RGB18_PACKED 0x5
/* define DSI lane types. */
enum {
DSIM_LANE_CLOCK = (1 << 0),
DSIM_LANE_DATA0 = (1 << 1),
DSIM_LANE_DATA1 = (1 << 2),
DSIM_LANE_DATA2 = (1 << 3),
DSIM_LANE_DATA3 = (1 << 4),
};
struct dsim_pll_param {
u32 p;
u32 m;
u32 s;
u32 pll_freq; /* in/out parameter: Mhz */
};
struct dsim_clks {
u32 hs_clk;
u32 esc_clk;
u32 byte_clk;
};
struct dphy_timing_value {
u32 bps;
u32 clk_prepare;
u32 clk_zero;
u32 clk_post;
u32 clk_trail;
u32 hs_prepare;
u32 hs_zero;
u32 hs_trail;
u32 lpx;
u32 hs_exit;
u32 b_dphyctl;
};
struct dsim_clks_param {
struct dsim_clks clks;
struct dsim_pll_param pll;
struct dphy_timing_value t;
u32 esc_div;
};
/* CAL APIs list */
int dsim_reg_init(u32 id, struct decon_lcd *lcd_info,
u32 data_lane_cnt, struct dsim_clks *clks);
void dsim_reg_init_probe(u32 id, struct decon_lcd *lcd_info,
u32 data_lane_cnt, struct dsim_clks *clks);
int dsim_reg_set_clocks(u32 id, struct dsim_clks *clks, struct stdphy_pms *dphy_pms, u32 en);
int dsim_reg_set_lanes(u32 id, u32 lanes, u32 en);
int dsim_reg_set_hs_clock(u32 id, u32 en);
void dsim_reg_set_int(u32 id, u32 en);
int dsim_reg_set_ulps(u32 id, u32 en, u32 lanes);
int dsim_reg_set_smddi_ulps(u32 id, u32 en, u32 lanes);
/* CAL raw functions list */
void dsim_reg_sw_reset(u32 id);
void dsim_reg_dphy_reset(u32 id);
void dsim_reg_funtion_reset(u32 id);
void dsim_reg_dp_dn_swap(u32 id, u32 en);
void dsim_reg_set_num_of_lane(u32 id, u32 lane);
void dsim_reg_enable_lane(u32 id, u32 lane, u32 en);
void dsim_reg_set_pll_freq(u32 id, u32 p, u32 m, u32 s);
void dsim_reg_pll_stable_time(u32 id);
void dsim_reg_set_dphy_timing_values(u32 id, struct dphy_timing_value *t);
void dsim_reg_clear_int(u32 id, u32 int_src);
void dsim_reg_clear_int_all(u32 id);
void dsim_reg_set_pll(u32 id, u32 en);
u32 dsim_reg_is_pll_stable(u32 id);
int dsim_reg_enable_pll(u32 id, u32 en);
void dsim_reg_set_byte_clock(u32 id, u32 en);
void dsim_reg_set_esc_clk_prescaler(u32 id, u32 en, u32 p);
void dsim_reg_set_esc_clk_on_lane(u32 id, u32 en, u32 lane);
u32 dsim_reg_wait_lane_stop_state(u32 id);
void dsim_reg_set_stop_state_cnt(u32 id);
void dsim_reg_set_bta_timeout(u32 id);
void dsim_reg_set_lpdr_timeout(u32 id);
void dsim_reg_set_porch(u32 id, struct decon_lcd *lcd);
void dsim_reg_set_pixel_format(u32 id, u32 pixformat);
void dsim_reg_set_config(u32 id, struct decon_lcd *lcd_info, u32 data_lane_cnt);
void dsim_reg_set_cmd_transfer_mode(u32 id, u32 lp);
void dsim_reg_set_multipix(u32 id, u32 multipix);
void dsim_reg_set_vc_id(u32 id, u32 vcid);
void dsim_reg_set_video_mode(u32 id, u32 mode);
void dsim_reg_enable_dsc(u32 id, u32 en);
void dsim_reg_disable_hsa(u32 id, u32 en);
void dsim_reg_disable_hbp(u32 id, u32 en);
void dsim_reg_disable_hfp(u32 id, u32 en);
void dsim_reg_disable_hse(u32 id, u32 en);
void dsim_reg_set_hsync_preserve(u32 id, u32 en);
void dsim_reg_set_burst_mode(u32 id, u32 burst);
void dsim_reg_set_sync_inform(u32 id, u32 inform);
void dsim_reg_set_cmdallow(u32 id, u32 cmdallow);
void dsim_reg_set_stable_vfp(u32 id, u32 stablevfp);
void dsim_reg_set_vbp(u32 id, u32 vbp);
void dsim_reg_set_hfp(u32 id, u32 hfp);
void dsim_reg_set_hbp(u32 id, u32 hbp);
void dsim_reg_set_vsa(u32 id, u32 vsa);
void dsim_reg_set_hsa(u32 id, u32 hsa);
void dsim_reg_set_vresol(u32 id, u32 vresol);
void dsim_reg_set_hresol(u32 id, u32 hresol, struct decon_lcd *lcd);
void dsim_reg_set_multi_packet_count(u32 id, u32 multipacketcnt);
void dsim_reg_set_command_control(u32 id, u32 cmdcontrol);
void dsim_reg_set_time_stable_vfp(u32 id, u32 stablevfp);
void dsim_reg_set_time_vsync_timeout(u32 id, u32 vsynctout);
void dsim_reg_set_time_te_protect_on(u32 id, u32 teprotecton);
void dsim_reg_set_time_te_timeout(u32 id, u32 tetout);
void dsim_reg_set_hsync_timeout(u32 id, u32 hsynctout);
void dsim_reg_enable_mflush(u32 id, u32 en);
void dsim_reg_enable_noncontinuous_clock(u32 id, u32 en);
void dsim_reg_enable_clocklane_stop_start(u32 id, u32 en);
void dsim_reg_enable_packetgo(u32 id, u32 en);
void dsim_reg_set_packetgo_ready(u32 id);
void dsim_reg_enable_multi_command_packet(u32 id, u32 en);
void dsim_reg_enable_shadow(u32 id, u32 en);
void dsim_reg_enable_hs_clock(u32 id, u32 en);
void dsim_reg_enable_byte_clock(u32 id, u32 en);
u32 dsim_reg_is_hs_clk_ready(u32 id);
void dsim_reg_enable_per_frame_read(u32 id, u32 en);
void dsim_reg_enable_qchannel(u32 id, u32 en);
int dsim_reg_wait_hs_clk_ready(u32 id);
void dsim_reg_set_fifo_ctrl(u32 id, u32 cfg);
void dsim_reg_force_dphy_stop_state(u32 id, u32 en);
void dsim_reg_wr_tx_header(u32 id, u32 data_id, unsigned long data0, u32 data1);
void dsim_reg_wr_tx_payload(u32 id, u32 payload);
void dsim_reg_enter_ulps(u32 id, u32 enter);
void dsim_reg_exit_ulps(u32 id, u32 exit);
int dsim_reg_set_ulps_by_ddi(u32 id, u32 ddi_type, u32 lanes, u32 en);
int dsim_reg_wait_enter_ulps_state(u32 id, u32 lanes);
int dsim_reg_wait_exit_ulps_state(u32 id);
void dsim_reg_set_standby(u32 id, u32 en);
void dsim_reg_set_bist(u32 id, u32 en, u32 vfp, u32 format, u32 type);
void dsim_reg_set_packet_ctrl(u32 id);
void dsim_reg_enable_loopback(u32 id, u32 en);
void dsim_reg_set_loopback_id(u32 id, u32 en);
void dsim_reg_set_pkt_go_enable(u32 id, bool en);
void dsim_reg_set_pkt_go_ready(u32 id);
void dsim_reg_set_pkt_go_cnt(u32 id, unsigned int count);
void dsim_reg_set_shadow(u32 id, u32 en);
void dsim_reg_shadow_update(u32 id);
int dsim_reg_exit_ulps_and_start(u32 id, u32 ddi_type, u32 lanes);
int dsim_reg_stop_and_enter_ulps(u32 id, u32 ddi_type, u32 lanes);
void dsim_reg_start(u32 id, struct dsim_clks *clks, u32 lanes);
void dsim_reg_stop(u32 id, u32 lanes);
void dsim_reg_set_partial_update(u32 id, struct decon_lcd *lcd_info);
#endif /* _DSIM_COMMON_H_ */

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,40 @@
config EXYNOS7870_DECON_DISP_LCD
depends on EXYNOS_DECON_7870 && EXYNOS_MIPI_DSI
bool "Select LCD panel driver"
config EXYNOS7870_DECON_DISP_LCD_NAME
string
default "s6d78a" if EXYNOS_DECON_LCD_S6D78A
default "s6e8aa0" if EXYNOS_DECON_LCD_S6E8AA0
default "s6e3fa0" if EXYNOS_DECON_LCD_S6E3FA0
help
This string is compared with lcd name fron Device Tree.
choice
prompt "Select Panel"
depends on EXYNOS7870_DECON_DISP_LCD
default EXYNOS_DECON_LCD_S6E3FA0
help
select the display panel.
config EXYNOS_DECON_LCD_S6D78A
depends on EXYNOS7870_DECON_DISP_LCD
depends on EXYNOS7870_DISPLAY_VIDEO_MODE
bool "S6D78A AMOLED qHD LCD driver(540 x 960)"
config EXYNOS_DECON_LCD_S6E8AA0
depends on EXYNOS7870_DECON_DISP_LCD
depends on EXYNOS7870_DISPLAY_VIDEO_MODE
bool "S6E8AA0 AMOLED HD LCD driver(800 x 1280)"
config EXYNOS_DECON_LCD_EA8064G
depends on EXYNOS7870_DECON_DISP_LCD
depends on EXYNOS7870_DISPLAY_COMMAND_MODE
bool "EA8064G COMMAND MODE AMOLED FHD LCD driver(1080 x 1920)"
config EXYNOS_DECON_LCD_S6E3FA0
depends on EXYNOS7870_DECON_DISP_LCD
depends on EXYNOS7870_DISPLAY_COMMAND_MODE || EXYNOS7870_DISPLAY_VIDEO_MODE
bool "S6E3FA0 COMMAND/VIDEO MODE AMOLED FHD LCD driver(1080 x 1920)"
endchoice

View file

@ -0,0 +1,4 @@
obj-$(CONFIG_EXYNOS_DECON_LCD_S6E8AA0) += s6e8aa0_mipi_lcd.o s6e8aa0_lcd_ctrl.o
obj-$(CONFIG_EXYNOS_DECON_LCD_S6D78A) += s6d78a_mipi_lcd.o s6d78a_lcd_ctrl.o
obj-$(CONFIG_EXYNOS_DECON_LCD_S6E3FA0) += s6e3fa0_mipi_lcd.o s6e3fa0_lcd_ctrl.o
obj-$(CONFIG_EXYNOS_DECON_LCD_EA8064G) += ea8064g_mipi_lcd.o ea8064g_lcd_ctrl.o

View file

@ -0,0 +1,72 @@
/* drivers/video/exynos_decon/lcd.h
*
* Copyright (c) 2011 Samsung Electronics
* 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.
*/
#ifndef __DECON_LCD__
#define __DECON_LCD__
enum decon_psr_mode {
DECON_VIDEO_MODE = 0,
DECON_DP_PSR_MODE = 1,
DECON_MIPI_COMMAND_MODE = 2,
};
/* Mic ratio: 0: 1/2 ratio, 1: 1/3 ratio */
enum decon_mic_comp_ratio {
MIC_COMP_RATIO_1_2 = 0,
MIC_COMP_RATIO_1_3 = 1,
MIC_COMP_BYPASS
};
enum mic_ver {
MIC_VER_1_1,
MIC_VER_1_2,
MIC_VER_2_0,
};
enum type_of_ddi {
TYPE_OF_SM_DDI = 0,
TYPE_OF_MAGNA_DDI,
TYPE_OF_NORMAL_DDI,
};
struct stdphy_pms {
unsigned int p;
unsigned int m;
unsigned int s;
};
struct decon_lcd {
enum decon_psr_mode mode;
unsigned int vfp;
unsigned int vbp;
unsigned int hfp;
unsigned int hbp;
unsigned int vsa;
unsigned int hsa;
unsigned int xres;
unsigned int yres;
unsigned int width;
unsigned int height;
unsigned int hs_clk;
struct stdphy_pms dphy_pms;
unsigned int esc_clk;
unsigned int fps;
unsigned int mic_enabled;
enum decon_mic_comp_ratio mic_ratio;
unsigned int dsc_enabled;
unsigned int dsc_slice;
enum mic_ver mic_ver;
enum type_of_ddi ddi_type;
};
#endif

View file

@ -0,0 +1,521 @@
/* linux/drivers/video/backlight/dynamic_aid.c
*
* Samsung Electronics Dynamic AID for AMOLED.
*
* Copyright (c) 2013 Samsung Electronics
*
* 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.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/mutex.h>
#include <linux/wait.h>
#include <linux/ctype.h>
#include "dynamic_aid.h"
#ifdef DYNAMIC_AID_DEBUG
#define aid_dbg(format, arg...) printk(format, ##arg)
#else
#define aid_dbg(format, arg...)
#endif
struct rgb64_t {
s64 rgb[3];
};
struct dynamic_aid_info {
struct dynamic_aid_param_t param;
int *iv_tbl;
int iv_max;
int iv_top;
int *ibr_tbl;
int ibr_max;
int ibr_top;
int *mtp;
int vreg;
struct rgb64_t *point_voltages;
struct rgb64_t *output_voltages;
int *l_value;
int *l_lookup_table;
int *m_gray;
struct rgb64_t *m_voltage;
};
#define MUL_100(x) (x*100)
#define MUL_1000(x) (x*1000)
#define MUL_10000(x) (x*10000)
#define DIV_10(x) ((x+5)/10)
#define DIV_100(x) ((x+50)/100)
static int calc_point_voltages(struct dynamic_aid_info d_aid)
{
int ret, iv, c;
struct rgb64_t *vt, *vp;
int *vd, *mtp;
int numerator, denominator;
s64 v0;
s64 t1, t2;
struct rgb64_t *point_voltages;
point_voltages = d_aid.point_voltages;
v0 = d_aid.vreg;
ret = 0;
/* iv == 0; */
{
vd = (int *)&d_aid.param.gamma_default[0];
mtp = &d_aid.mtp[0];
numerator = d_aid.param.formular[0].numerator;
denominator = d_aid.param.formular[0].denominator;
for (c = 0; c < CI_MAX; c++) {
t1 = v0;
t2 = v0*d_aid.param.vt_voltage_value[vd[c] +
mtp[c]];
point_voltages[0].rgb[c] = t1 -
div_s64(t2, denominator);
}
}
iv = d_aid.iv_max - 1;
/* iv == (IV_MAX-1) ~ 1; */
for (; iv > 0; iv--) {
vt = &point_voltages[0];
vp = &point_voltages[iv+1];
vd = (int *)&d_aid.param.gamma_default[iv*CI_MAX];
mtp = &d_aid.mtp[iv*CI_MAX];
numerator = d_aid.param.formular[iv].numerator;
denominator = d_aid.param.formular[iv].denominator;
for (c = 0; c < CI_MAX; c++) {
if (iv == 1) {
t1 = v0;
t2 = v0 - vp->rgb[c];
} else if (iv == d_aid.iv_max - 1) {
t1 = v0;
t2 = v0;
} else {
t1 = vt->rgb[c];
t2 = vt->rgb[c] - vp->rgb[c];
}
t2 *= vd[c] + mtp[c] + numerator;
point_voltages[iv].rgb[c] = (t1 -
div_s64(t2, denominator));
}
}
#ifdef DYNAMIC_AID_DEBUG
for (iv = 0; iv < d_aid.iv_max; iv++) {
aid_dbg("Point Voltage[%d] = ", iv);
for (c = 0; c < CI_MAX; c++)
aid_dbg("%lld ", point_voltages[iv].rgb[c]);
aid_dbg("\n");
}
#endif
return ret;
}
static int calc_output_voltages(struct dynamic_aid_info d_aid)
{
int iv, i, c;
int v_idx, v_cnt;
struct rgb_t v, v_diff;
struct rgb64_t *output_voltages;
struct rgb64_t *point_voltages;
output_voltages = d_aid.output_voltages;
point_voltages = d_aid.point_voltages;
iv = d_aid.iv_max - 1;
/* iv == (IV_MAX-1) ~ 0; */
for (; iv > 0; iv--) {
v_cnt = d_aid.iv_tbl[iv] - d_aid.iv_tbl[iv-1];
v_idx = d_aid.iv_tbl[iv];
for (c = 0; c < CI_MAX; c++) {
v.rgb[c] = point_voltages[iv].rgb[c];
v_diff.rgb[c] =
point_voltages[iv-1].rgb[c] -
point_voltages[iv].rgb[c];
}
if (iv == 1)
for (c = 0; c < CI_MAX; c++)
v_diff.rgb[c] = d_aid.vreg -
point_voltages[iv].rgb[c];
for (i = 0; i < v_cnt; i++, v_idx--) {
for (c = 0; c < CI_MAX; c++)
output_voltages[v_idx].rgb[c] = v.rgb[c]
+ v_diff.rgb[c]*i/v_cnt;
}
}
for (c = 0; c < CI_MAX; c++)
output_voltages[0].rgb[c] = d_aid.vreg;
#ifdef DYNAMIC_AID_DEBUG
for (iv = 0; iv <= d_aid.iv_top; iv++) {
aid_dbg("Output Voltage[%d] = ", iv);
for (c = 0; c < CI_MAX; c++)
aid_dbg("%lld ", output_voltages[iv].rgb[c]);
aid_dbg("\n");
}
#endif
return 0;
}
static int calc_voltage_table(struct dynamic_aid_info d_aid)
{
int ret;
ret = calc_point_voltages(d_aid);
if (ret)
return ret;
ret = calc_output_voltages(d_aid);
if (ret)
return ret;
return 0;
}
static int init_l_lookup_table(struct dynamic_aid_info d_aid)
{
int iv;
int *gamma_curve;
int *l_lookup_table;
gamma_curve = (int *)d_aid.param.gc_lut;
l_lookup_table = d_aid.l_lookup_table;
for (iv = 0; iv <= d_aid.iv_top; iv++)
l_lookup_table[iv] = DIV_100(d_aid.ibr_top*gamma_curve[iv]);
#ifdef DYNAMIC_AID_DEBUG
for (iv = 0; iv <= d_aid.iv_top; iv++)
aid_dbg("L lookup table[%d] = %d\n", iv, l_lookup_table[iv]);
#endif
return 0;
}
static int min_diff_gray(int in, int *table, int table_cnt)
{
int ret, i, min, temp;
ret = min = table[table_cnt] + 1;
for (i = 0; i <= table_cnt; i++) {
temp = table[i] - in;
if (temp < 0)
temp = -temp;
if (temp <= min) {
min = temp;
ret = i;
}
if ((in >= table[i-1]) && (in <= table[i]))
break;
}
return ret;
}
static int calc_l_values(struct dynamic_aid_info d_aid, int ibr)
{
int iv;
int *gamma_curve;
int *br_base;
int *l_value;
gamma_curve = (int *)d_aid.param.gc_tbls[ibr];
br_base = (int *)d_aid.param.br_base;
l_value = d_aid.l_value;
iv = d_aid.iv_max - 1;
/* iv == (IV_MAX - 1) ~ 0; */
for (; iv >= 0; iv--) {
if (iv == d_aid.iv_max - 1)
l_value[iv] = MUL_10000(br_base[ibr]);
else
l_value[iv] = DIV_100(br_base[ibr]*
gamma_curve[d_aid.iv_tbl[iv]]);
}
#ifdef DYNAMIC_AID_DEBUG
aid_dbg("L value (%d) = ", d_aid.ibr_tbl[ibr]);
for (iv = 0; iv < d_aid.iv_max; iv++)
aid_dbg("%d ", l_value[iv]);
aid_dbg("\n");
#endif
return 0;
}
static int calc_m_gray_values(struct dynamic_aid_info d_aid, int ibr)
{
int iv;
int (*offset_gra)[d_aid.iv_max];
int *l_lookup_table;
int *l_value;
int *m_gray;
offset_gra = (int(*)[])d_aid.param.offset_gra;
l_lookup_table = d_aid.l_lookup_table;
l_value = d_aid.l_value;
m_gray = d_aid.m_gray;
iv = d_aid.iv_max - 1;
/* iv == (IV_MAX - 1) ~ 0; */
for (; iv >= 0; iv--) {
m_gray[iv] = min_diff_gray(l_value[iv], l_lookup_table,
d_aid.iv_top);
if (offset_gra)
m_gray[iv] += offset_gra[ibr][iv];
}
#ifdef DYNAMIC_AID_DEBUG
aid_dbg("M-Gray value[%d] = ", d_aid.ibr_tbl[ibr]);
for (iv = 0; iv < d_aid.iv_max; iv++)
aid_dbg("%d ", d_aid.m_gray[iv]);
aid_dbg("\n");
#endif
return 0;
}
static int calc_m_rgb_voltages(struct dynamic_aid_info d_aid, int ibr)
{
int iv, c;
struct rgb64_t *output_voltages;
struct rgb64_t *point_voltages;
int *m_gray;
struct rgb64_t *m_voltage;
output_voltages = d_aid.output_voltages;
point_voltages = d_aid.point_voltages;
m_gray = d_aid.m_gray;
m_voltage = d_aid.m_voltage;
iv = d_aid.iv_max - 1;
/* iv == (IV_MAX - 1) ~ 1; */
for (; iv > 0; iv--) {
for (c = 0; c < CI_MAX; c++)
m_voltage[iv].rgb[c] =
output_voltages[m_gray[iv]].rgb[c];
}
/* iv == 0; */
for (c = 0; c < CI_MAX; c++)
m_voltage[iv].rgb[c] = point_voltages[0].rgb[c];
#ifdef DYNAMIC_AID_DEBUG
aid_dbg("M-RGB voltage (%d) =\n", d_aid.ibr_tbl[ibr]);
for (iv = 0; iv < d_aid.iv_max; iv++) {
aid_dbg("[%d] = ", iv);
for (c = 0; c < CI_MAX; c++)
aid_dbg("%lld ", d_aid.m_voltage[iv].rgb[c]);
aid_dbg("\n");
}
#endif
return 0;
}
static int calc_gamma(struct dynamic_aid_info d_aid, int ibr, int *result)
{
int ret, iv, c;
int numerator, denominator;
s64 t1, t2;
int *vd, *mtp, *res;
struct rgb_t (*offset_color)[d_aid.iv_max];
struct rgb64_t *m_voltage;
offset_color = (struct rgb_t(*)[])d_aid.param.offset_color;
m_voltage = d_aid.m_voltage;
iv = d_aid.iv_max - 1;
ret = 0;
/* iv == (IV_MAX - 1) ~ 1; */
for (; iv > 0; iv--) {
mtp = &d_aid.mtp[iv*CI_MAX];
res = &result[iv*CI_MAX];
numerator = d_aid.param.formular[iv].numerator;
denominator = d_aid.param.formular[iv].denominator;
for (c = 0; c < CI_MAX; c++) {
if (iv == 0) {
t1 = 0;
t2 = 1;
} else if (iv == 1) {
t1 = d_aid.vreg - m_voltage[iv].rgb[c];
t2 = d_aid.vreg - m_voltage[iv+1].rgb[c];
} else if (iv == d_aid.iv_max - 1) {
t1 = d_aid.vreg - m_voltage[iv].rgb[c];
t2 = d_aid.vreg;
} else {
t1 = m_voltage[0].rgb[c] -
m_voltage[iv].rgb[c];
t2 = m_voltage[0].rgb[c] -
m_voltage[iv+1].rgb[c];
}
res[c] = div64_s64((t1 + 1) * denominator,
t2) - numerator;
res[c] -= mtp[c];
if (offset_color)
res[c] += offset_color[ibr][iv].rgb[c];
if ((res[c] > 255) && (iv != d_aid.iv_max - 1))
res[c] = 255;
}
}
/* iv == 0; */
vd = (int *)&d_aid.param.gamma_default[0];
res = &result[0];
for (c = 0; c < CI_MAX; c++)
res[c] = vd[c];
#ifdef DYNAMIC_AID_DEBUG
aid_dbg("Gamma (%d) =\n", d_aid.ibr_tbl[ibr]);
for (iv = 0; iv < d_aid.iv_max; iv++) {
aid_dbg("[%d] = ", iv);
for (c = 0; c < CI_MAX; c++)
aid_dbg("%X ", result[iv*CI_MAX+c]);
aid_dbg("\n");
}
#endif
return ret;
}
static int calc_gamma_table(struct dynamic_aid_info d_aid, int **gamma)
{
int ibr;
#ifdef DYNAMIC_AID_DEBUG
int iv, c;
#endif
init_l_lookup_table(d_aid);
/* ibr == 0 ~ (IBRIGHTNESS_MAX - 1); */
for (ibr = 0; ibr < d_aid.ibr_max; ibr++) {
calc_l_values(d_aid, ibr);
calc_m_gray_values(d_aid, ibr);
calc_m_rgb_voltages(d_aid, ibr);
calc_gamma(d_aid, ibr, gamma[ibr]);
}
#ifdef DYNAMIC_AID_DEBUG
for (ibr = 0; ibr < d_aid.ibr_max; ibr++) {
aid_dbg("Gamma [%03d] = ", d_aid.ibr_tbl[ibr]);
for (iv = 1; iv < d_aid.iv_max; iv++) {
for (c = 0; c < CI_MAX; c++)
aid_dbg("%04d ",
gamma[ibr][iv*CI_MAX+c]);
}
for (c = 0; c < CI_MAX; c++)
aid_dbg("%d ", gamma[ibr][c]);
aid_dbg("\n");
}
#endif
return 0;
}
int dynamic_aid(struct dynamic_aid_param_t param, int **gamma)
{
struct dynamic_aid_info d_aid;
int ret;
d_aid.param = param;
d_aid.iv_tbl = (int *)param.iv_tbl;
d_aid.iv_max = param.iv_max;
/* number of top voltage index: 255 */
d_aid.iv_top = param.iv_tbl[param.iv_max-1];
d_aid.mtp = param.mtp;
d_aid.vreg = MUL_100(param.vreg);
d_aid.ibr_tbl = (int *)param.ibr_tbl;
d_aid.ibr_max = param.ibr_max;
/* number of top brightness : 300nt */
d_aid.ibr_top = param.ibr_tbl[param.ibr_max-1];
d_aid.point_voltages = kzalloc(sizeof(struct rgb64_t)*d_aid.iv_max,
GFP_KERNEL);
if (!d_aid.point_voltages) {
printk(KERN_ERR "failed to allocate point_voltages\n");
ret = -ENOMEM;
goto error1;
}
d_aid.output_voltages = kzalloc(sizeof(struct rgb64_t)*
(d_aid.iv_top+1), GFP_KERNEL);
if (!d_aid.output_voltages) {
printk(KERN_ERR "failed to allocate output_voltages\n");
ret = -ENOMEM;
goto error2;
}
d_aid.l_value = kzalloc(sizeof(int)*d_aid.iv_max, GFP_KERNEL);
if (!d_aid.l_value) {
printk(KERN_ERR "failed to allocate l_value\n");
ret = -ENOMEM;
goto error3;
}
d_aid.l_lookup_table = kzalloc(sizeof(int)*(d_aid.iv_top+1),
GFP_KERNEL);
if (!d_aid.l_lookup_table) {
printk(KERN_ERR "failed to allocate l_lookup_table\n");
ret = -ENOMEM;
goto error4;
}
d_aid.m_gray = kzalloc(sizeof(int)*d_aid.iv_max, GFP_KERNEL);
if (!d_aid.m_gray) {
printk(KERN_ERR "failed to allocate m_gray\n");
ret = -ENOMEM;
goto error5;
}
d_aid.m_voltage = kzalloc(sizeof(struct rgb64_t)*d_aid.iv_max,
GFP_KERNEL);
if (!d_aid.m_voltage) {
printk(KERN_ERR "failed to allocate m_voltage\n");
ret = -ENOMEM;
goto error6;
}
ret = calc_voltage_table(d_aid);
if (ret)
goto error7;
ret = calc_gamma_table(d_aid, gamma);
if (ret)
goto error7;
printk(KERN_INFO "Dynamic Aid Finished !\n");
error7:
kfree(d_aid.m_voltage);
error6:
kfree(d_aid.m_gray);
error5:
kfree(d_aid.l_lookup_table);
error4:
kfree(d_aid.l_value);
error3:
kfree(d_aid.output_voltages);
error2:
kfree(d_aid.point_voltages);
error1:
return ret;
}

View file

@ -0,0 +1,40 @@
#ifndef __DYNAMIC_AID_H
#define __DYNAMIC_AID_H __FILE__
enum {
CI_RED,
CI_GREEN,
CI_BLUE,
CI_MAX
};
struct rgb_t {
int rgb[CI_MAX];
};
struct formular_t {
int numerator;
int denominator;
};
struct dynamic_aid_param_t {
int vreg;
const int *iv_tbl;
int iv_max;
int *mtp;
const int *gamma_default;
const struct formular_t *formular;
const int *vt_voltage_value;
const int *ibr_tbl;
int ibr_max;
const int *br_base;
const int **gc_tbls; /* Gamma curve tables */
const int *gc_lut; /* Gamma curve for generating the Lookup Table */
const int (*offset_gra)[];
const struct rgb_t (*offset_color)[];
};
extern int dynamic_aid(struct dynamic_aid_param_t d_aid, int **gamma);
#endif /* __DYNAMIC_AID_H */

View file

@ -0,0 +1,739 @@
#ifndef __DYNAMIC_AID_GAMMA_CURVE_H
#define __DYNAMIC_AID_GAMMA_CURVE_H __FILE__
static const int gamma_curve_1p60_table[256] = {
0, 141, 428, 818, 1297, 1853, 2481, 3175,
3931, 4746, 5617, 6543, 7520, 8548, 9624, 10747,
11916, 13130, 14387, 15687, 17029, 18411, 19834, 21296,
22797, 24335, 25912, 27524, 29174, 30858, 32578, 34333,
36122, 37945, 39802, 41691, 43613, 45568, 47554, 49572,
51622, 53702, 55813, 57954, 60126, 62327, 64558, 66818,
69107, 71425, 73771, 76146, 78549, 80980, 83438, 85924,
88438, 90978, 93545, 96139, 98759, 101406, 104079, 106778,
109502, 112253, 115029, 117830, 120656, 123508, 126384, 129285,
132211, 135161, 138136, 141135, 144158, 147204, 150275, 153370,
156488, 159629, 162794, 165982, 169193, 172427, 175684, 178964,
182267, 185592, 188940, 192310, 195702, 199117, 202554, 206012,
209493, 212996, 216520, 220066, 223633, 227222, 230832, 234464,
238116, 241790, 245485, 249201, 252938, 256695, 260474, 264273,
268092, 271933, 275793, 279674, 283575, 287497, 291439, 295400,
299382, 303384, 307405, 311447, 315508, 319589, 323689, 327810,
331949, 336108, 340287, 344485, 348702, 352938, 357193, 361468,
365761, 370074, 374406, 378756, 383125, 387513, 391920, 396345,
400789, 405251, 409732, 414232, 418750, 423286, 427840, 432413,
437004, 441613, 446240, 450886, 455549, 460230, 464929, 469647,
474381, 479134, 483905, 488693, 493499, 498322, 503163, 508021,
512897, 517791, 522702, 527630, 532576, 537538, 542518, 547516,
552530, 557562, 562610, 567676, 572759, 577858, 582975, 588108,
593259, 598426, 603610, 608811, 614028, 619262, 624513, 629780,
635064, 640365, 645682, 651015, 656365, 661731, 667114, 672513,
677928, 683360, 688808, 694272, 699752, 705248, 710760, 716289,
721834, 727394, 732971, 738563, 744172, 749796, 755436, 761092,
766764, 772452, 778155, 783874, 789609, 795359, 801125, 806907,
812704, 818517, 824345, 830189, 836048, 841923, 847813, 853719,
859640, 865576, 871527, 877494, 883476, 889474, 895486, 901514,
907557, 913614, 919688, 925776, 931879, 937997, 944130, 950278,
956441, 962620, 968812, 975020, 981243, 987481, 993733, 1000000
};
static const int gamma_curve_1p65_table[256] = {
0, 107, 336, 655, 1053, 1522, 2057, 2652,
3306, 4015, 4778, 5591, 6454, 7366, 8324, 9327,
10375, 11467, 12601, 13777, 14994, 16251, 17547, 18883,
20256, 21668, 23116, 24601, 26123, 27680, 29272, 30900,
32562, 34258, 35987, 37750, 39546, 41375, 43237, 45130,
47055, 49012, 51000, 53019, 55069, 57149, 59260, 61400,
63571, 65771, 68000, 70259, 72546, 74862, 77207, 79581,
81982, 84412, 86869, 89354, 91867, 94407, 96974, 99568,
102189, 104837, 107512, 110213, 112940, 115694, 118473, 121279,
124110, 126967, 129850, 132758, 135691, 138650, 141633, 144642,
147675, 150733, 153816, 156923, 160055, 163211, 166392, 169596,
172824, 176077, 179353, 182653, 185977, 189324, 192695, 196089,
199506, 202947, 206410, 209897, 213407, 216940, 220495, 224073,
227674, 231298, 234943, 238612, 242303, 246015, 249751, 253508,
257287, 261089, 264912, 268757, 272624, 276513, 280423, 284355,
288309, 292284, 296280, 300298, 304337, 308397, 312478, 316581,
320705, 324849, 329015, 333201, 337408, 341636, 345885, 350154,
354444, 358755, 363086, 367437, 371809, 376201, 380614, 385046,
389499, 393972, 398466, 402979, 407512, 412065, 416638, 421231,
425844, 430477, 435129, 439801, 444492, 449203, 453934, 458684,
463454, 468243, 473052, 477879, 482726, 487593, 492478, 497383,
502307, 507250, 512212, 517193, 522193, 527211, 532249, 537306,
542381, 547475, 552588, 557720, 562870, 568039, 573227, 578433,
583658, 588901, 594162, 599442, 604741, 610057, 615392, 620746,
626117, 631507, 636915, 642341, 647785, 653248, 658728, 664227,
669743, 675277, 680830, 686400, 691988, 697594, 703217, 708859,
714518, 720195, 725890, 731602, 737332, 743079, 748844, 754627,
760427, 766244, 772079, 777932, 783802, 789689, 795593, 801515,
807454, 813411, 819384, 825375, 831383, 837408, 843451, 849510,
855586, 861680, 867790, 873918, 880062, 886224, 892402, 898598,
904810, 911039, 917285, 923547, 929826, 936123, 942435, 948765,
955111, 961474, 967854, 974250, 980663, 987092, 993538, 1000000
};
static const int gamma_curve_1p70_table[256] = {
0, 81, 263, 525, 856, 1251, 1705, 2216,
2781, 3397, 4063, 4778, 5540, 6347, 7199, 8095,
9034, 10015, 11037, 12099, 13202, 14343, 15524, 16742,
17999, 19292, 20622, 21989, 23391, 24829, 26302, 27810,
29352, 30928, 32538, 34182, 35859, 37569, 39311, 41086,
42893, 44732, 46602, 48504, 50437, 52401, 54396, 56422,
58478, 60564, 62680, 64826, 67002, 69207, 71442, 73705,
75998, 78319, 80669, 83048, 85455, 87891, 90354, 92845,
95365, 97912, 100486, 103088, 105717, 108374, 111058, 113768,
116506, 119270, 122061, 124878, 127722, 130592, 133488, 136410,
139359, 142333, 145333, 148359, 151411, 154488, 157590, 160718,
163871, 167049, 170253, 173481, 176734, 180013, 183315, 186643,
189995, 193372, 196773, 200199, 203649, 207123, 210621, 214144,
217690, 221260, 224855, 228473, 232114, 235780, 239469, 243182,
246918, 250677, 254460, 258266, 262096, 265949, 269824, 273723,
277645, 281590, 285557, 289548, 293561, 297597, 301656, 305737,
309841, 313967, 318116, 322287, 326481, 330696, 334934, 339195,
343477, 347782, 352108, 356457, 360827, 365220, 369634, 374070,
378528, 383008, 387509, 392032, 396576, 401142, 405730, 410339,
414969, 419621, 424294, 428988, 433704, 438441, 443199, 447978,
452778, 457600, 462442, 467305, 472189, 477094, 482020, 486967,
491935, 496923, 501932, 506962, 512012, 517083, 522174, 527286,
532419, 537572, 542745, 547939, 553153, 558387, 563642, 568917,
574212, 579527, 584862, 590218, 595594, 600989, 606405, 611841,
617296, 622772, 628268, 633783, 639318, 644873, 650448, 656042,
661657, 667291, 672944, 678617, 684310, 690023, 695754, 701506,
707277, 713067, 718877, 724706, 730555, 736422, 742310, 748216,
754142, 760087, 766051, 772034, 778037, 784059, 790099, 796159,
802238, 808336, 814453, 820589, 826744, 832918, 839110, 845322,
851552, 857801, 864069, 870356, 876662, 882986, 889329, 895691,
902071, 908470, 914888, 921324, 927779, 934252, 940744, 947254,
953783, 960330, 966896, 973480, 980082, 986703, 993342, 1000000
};
static const int gamma_curve_1p75_table[256] = {
0, 61, 207, 420, 695, 1027, 1414, 1851,
2339, 2874, 3456, 4083, 4755, 5470, 6227, 7026,
7866, 8747, 9667, 10626, 11624, 12660, 13734, 14845,
15993, 17177, 18397, 19654, 20945, 22272, 23633, 25029,
26459, 27922, 29420, 30951, 32515, 34112, 35742, 37404,
39098, 40825, 42583, 44374, 46195, 48048, 49932, 51847,
53793, 55770, 57777, 59814, 61881, 63979, 66106, 68264,
70450, 72667, 74912, 77187, 79491, 81824, 84186, 86577,
88996, 91444, 93920, 96424, 98957, 101517, 104106, 106723,
109367, 112039, 114739, 117466, 120220, 123002, 125811, 128648,
131511, 134401, 137318, 140262, 143233, 146230, 149254, 152305,
155382, 158485, 161614, 164770, 167951, 171159, 174393, 177652,
180938, 184249, 187586, 190949, 194337, 197750, 201189, 204654,
208144, 211659, 215199, 218764, 222355, 225970, 229611, 233276,
236966, 240681, 244421, 248185, 251974, 255788, 259626, 263489,
267376, 271287, 275223, 279183, 283167, 287175, 291208, 295264,
299345, 303450, 307578, 311731, 315907, 320107, 324331, 328578,
332849, 337144, 341463, 345804, 350170, 354559, 358971, 363407,
367865, 372348, 376853, 381382, 385934, 390509, 395107, 399728,
404372, 409039, 413729, 418442, 423178, 427936, 432718, 437522,
442349, 447198, 452070, 456965, 461882, 466822, 471785, 476770,
481777, 486807, 491859, 496933, 502030, 507149, 512290, 517453,
522639, 527847, 533077, 538329, 543603, 548899, 554217, 559557,
564919, 570302, 575708, 581136, 586585, 592056, 597549, 603064,
608600, 614158, 619737, 625339, 630961, 636606, 642272, 647959,
653668, 659398, 665150, 670923, 676718, 682533, 688371, 694229,
700109, 706010, 711932, 717875, 723840, 729825, 735832, 741860,
747909, 753979, 760070, 766182, 772315, 778469, 784644, 790839,
797056, 803293, 809551, 815830, 822130, 828451, 834792, 841154,
847537, 853940, 860364, 866809, 873274, 879760, 886267, 892793,
899341, 905909, 912497, 919106, 925735, 932385, 939055, 945746,
952456, 959188, 965939, 972711, 979503, 986315, 993147, 1000000
};
static const int gamma_curve_1p80_table[256] = {
0, 47, 162, 337, 565, 844, 1172, 1547,
1967, 2431, 2939, 3489, 4081, 4713, 5386, 6098,
6849, 7639, 8467, 9332, 10235, 11174, 12150, 13162,
14210, 15294, 16413, 17566, 18755, 19978, 21235, 22526,
23851, 25209, 26600, 28025, 29483, 30974, 32497, 34052,
35640, 37260, 38911, 40595, 42310, 44057, 45834, 47644,
49484, 51355, 53257, 55189, 57152, 59146, 61170, 63224,
65308, 67422, 69566, 71740, 73943, 76177, 78439, 80731,
83052, 85403, 87782, 90191, 92628, 95095, 97590, 100114,
102666, 105247, 107856, 110494, 113160, 115854, 118576, 121327,
124105, 126911, 129746, 132608, 135497, 138415, 141359, 144332,
147332, 150359, 153414, 156496, 159605, 162741, 165904, 169095,
172312, 175556, 178828, 182126, 185450, 188802, 192180, 195585,
199016, 202474, 205958, 209468, 213005, 216569, 220158, 223774,
227416, 231083, 234777, 238497, 242243, 246015, 249813, 253637,
257486, 261361, 265262, 269189, 273141, 277119, 281122, 285151,
289205, 293285, 297390, 301520, 305676, 309857, 314063, 318294,
322550, 326832, 331139, 335470, 339827, 344209, 348616, 353047,
357503, 361985, 366491, 371021, 375577, 380157, 384762, 389391,
394045, 398724, 403427, 408155, 412907, 417683, 422484, 427309,
432159, 437033, 441931, 446854, 451800, 456771, 461766, 466785,
471829, 476896, 481987, 487103, 492242, 497406, 502593, 507804,
513039, 518298, 523581, 528887, 534218, 539572, 544949, 550351,
555776, 561225, 566697, 572193, 577713, 583256, 588822, 594412,
600026, 605663, 611323, 617007, 622714, 628444, 634198, 639975,
645776, 651599, 657446, 663316, 669209, 675126, 681065, 687028,
693013, 699022, 705054, 711109, 717187, 723288, 729411, 735558,
741728, 747920, 754135, 760374, 766635, 772919, 779225, 785555,
791907, 798282, 804679, 811100, 817543, 824008, 830496, 837007,
843541, 850097, 856675, 863276, 869900, 876546, 883215, 889906,
896619, 903355, 910113, 916894, 923697, 930522, 937370, 944240,
951132, 958046, 964983, 971942, 978923, 985927, 992952, 1000000
};
static const int gamma_curve_1p85_table[256] = {
0, 35, 127, 270, 459, 693, 972, 1292,
1654, 2057, 2500, 2982, 3503, 4062, 4658, 5293,
5964, 6672, 7416, 8196, 9012, 9863, 10749, 11671,
12627, 13617, 14642, 15701, 16794, 17920, 19080, 20273,
21499, 22759, 24051, 25376, 26734, 28124, 29546, 31001,
32487, 34006, 35556, 37138, 38751, 40397, 42073, 43781,
45519, 47289, 49090, 50922, 52785, 54678, 56602, 58556,
60541, 62556, 64601, 66677, 68783, 70919, 73085, 75280,
77506, 79761, 82046, 84360, 86705, 89078, 91481, 93914,
96375, 98866, 101386, 103936, 106514, 109121, 111757, 114422,
117116, 119839, 122590, 125370, 128179, 131016, 133882, 136776,
139699, 142650, 145629, 148637, 151673, 154737, 157829, 160949,
164098, 167274, 170478, 173710, 176970, 180258, 183574, 186917,
190288, 193687, 197114, 200568, 204049, 207558, 211095, 214659,
218250, 221869, 225515, 229188, 232888, 236616, 240371, 244153,
247962, 251799, 255662, 259552, 263470, 267414, 271385, 275383,
279408, 283460, 287538, 291644, 295776, 299934, 304120, 308332,
312570, 316835, 321127, 325445, 329790, 334161, 338559, 342983,
347433, 351910, 356413, 360942, 365498, 370080, 374688, 379322,
383982, 388669, 393382, 398120, 402885, 407676, 412493, 417336,
422204, 427099, 432020, 436966, 441938, 446937, 451961, 457010,
462086, 467187, 472314, 477467, 482646, 487850, 493079, 498335,
503616, 508922, 514254, 519612, 524995, 530403, 535837, 541296,
546781, 552292, 557827, 563388, 568974, 574586, 580223, 585885,
591572, 597285, 603023, 608786, 614574, 620388, 626226, 632090,
637979, 643893, 649831, 655795, 661784, 667798, 673837, 679901,
685990, 692104, 698243, 704406, 710595, 716808, 723046, 729309,
735597, 741910, 748247, 754610, 760996, 767408, 773844, 780305,
786791, 793302, 799837, 806396, 812981, 819589, 826223, 832881,
839563, 846270, 853002, 859758, 866539, 873344, 880173, 887027,
893905, 900808, 907735, 914687, 921662, 928663, 935687, 942736,
949809, 956906, 964028, 971174, 978344, 985539, 992757, 1000000
};
static const int gamma_curve_1p90_table[256] = {
0, 27, 100, 216, 373, 570, 805, 1080,
1391, 1740, 2126, 2548, 3006, 3500, 4029, 4594,
5193, 5827, 6495, 7198, 7935, 8705, 9510, 10348,
11220, 12124, 13062, 14033, 15037, 16074, 17144, 18246,
19380, 20547, 21746, 22978, 24241, 25536, 26863, 28223,
29613, 31036, 32490, 33975, 35492, 37041, 38620, 40231,
41873, 43546, 45250, 46985, 48751, 50547, 52375, 54233,
56122, 58041, 59991, 61972, 63982, 66024, 68095, 70197,
72330, 74492, 76684, 78907, 81160, 83442, 85755, 88098,
90470, 92872, 95305, 97766, 100258, 102779, 105330, 107911,
110521, 113161, 115830, 118528, 121256, 124014, 126800, 129616,
132462, 135336, 138240, 141173, 144135, 147127, 150147, 153196,
156275, 159382, 162519, 165684, 168878, 172101, 175353, 178634,
181944, 185282, 188649, 192045, 195469, 198923, 202404, 205915,
209454, 213021, 216617, 220242, 223895, 227576, 231286, 235024,
238791, 242586, 246409, 250261, 254141, 258049, 261986, 265950,
269943, 273964, 278014, 282091, 286196, 290330, 294492, 298681,
302899, 307144, 311418, 315720, 320049, 324407, 328792, 333205,
337647, 342116, 346612, 351137, 355689, 360270, 364877, 369513,
374176, 378868, 383586, 388333, 393107, 397908, 402738, 407594,
412479, 417391, 422330, 427297, 432292, 437314, 442363, 447440,
452545, 457676, 462835, 468022, 473236, 478477, 483746, 489042,
494365, 499716, 505093, 510498, 515931, 521390, 526877, 532391,
537932, 543500, 549096, 554719, 560368, 566045, 571749, 577480,
583238, 589023, 594836, 600675, 606541, 612434, 618354, 624302,
630276, 636277, 642305, 648360, 654442, 660550, 666686, 672849,
679038, 685254, 691497, 697767, 704063, 710387, 716737, 723114,
729518, 735948, 742405, 748889, 755400, 761937, 768501, 775091,
781709, 788352, 795023, 801720, 808444, 815194, 821971, 828775,
835605, 842461, 849344, 856254, 863190, 870153, 877142, 884158,
891200, 898268, 905363, 912485, 919633, 926807, 934007, 941235,
948488, 955768, 963074, 970407, 977765, 985151, 992562, 1000000
};
static const int gamma_curve_1p95_table[256] = {
0, 20, 78, 173, 303, 468, 668, 902,
1170, 1472, 1808, 2178, 2580, 3016, 3485, 3987,
4521, 5089, 5689, 6321, 6986, 7684, 8413, 9175,
9969, 10795, 11653, 12543, 13465, 14419, 15404, 16421,
17470, 18550, 19662, 20806, 21980, 23187, 24424, 25693,
26994, 28325, 29688, 31082, 32507, 33963, 35451, 36969,
38518, 40099, 41710, 43352, 45025, 46729, 48463, 50229,
52025, 53852, 55710, 57598, 59517, 61467, 63447, 65458,
67499, 69571, 71673, 73806, 75969, 78163, 80387, 82642,
84927, 87242, 89588, 91964, 94370, 96806, 99273, 101770,
104297, 106854, 109442, 112060, 114707, 117385, 120093, 122831,
125599, 128398, 131226, 134084, 136972, 139891, 142839, 145817,
148825, 151863, 154931, 158028, 161156, 164314, 167501, 170718,
173965, 177242, 180548, 183884, 187250, 190646, 194072, 197527,
201012, 204527, 208071, 211645, 215248, 218882, 222544, 226237,
229959, 233710, 237492, 241302, 245143, 249013, 252912, 256841,
260799, 264787, 268804, 272851, 276927, 281033, 285168, 289333,
293527, 297750, 302003, 306285, 310596, 314937, 319307, 323707,
328136, 332594, 337081, 341598, 346144, 350719, 355324, 359958,
364621, 369313, 374035, 378786, 383566, 388375, 393213, 398081,
402977, 407903, 412858, 417842, 422856, 427898, 432970, 438070,
443200, 448359, 453547, 458764, 464010, 469285, 474589, 479922,
485284, 490676, 496096, 501545, 507023, 512531, 518067, 523632,
529226, 534849, 540501, 546182, 551892, 557631, 563399, 569196,
575021, 580876, 586759, 592672, 598613, 604583, 610582, 616609,
622666, 628751, 634866, 641009, 647181, 653381, 659611, 665869,
672156, 678472, 684817, 691190, 697592, 704023, 710483, 716971,
723488, 730034, 736609, 743212, 749844, 756505, 763194, 769912,
776659, 783434, 790238, 797071, 803933, 810823, 817741, 824689,
831665, 838669, 845702, 852764, 859855, 866974, 874121, 881298,
888502, 895736, 902998, 910288, 917607, 924955, 932331, 939736,
947169, 954631, 962121, 969640, 977187, 984763, 992367, 1000000
};
static const int gamma_curve_2p00_table[256] = {
0, 15, 62, 138, 246, 384, 554, 754,
984, 1246, 1538, 1861, 2215, 2599, 3014, 3460,
3937, 4444, 4983, 5552, 6151, 6782, 7443, 8135,
8858, 9612, 10396, 11211, 12057, 12933, 13841, 14779,
15748, 16747, 17778, 18839, 19931, 21053, 22207, 23391,
24606, 25852, 27128, 28435, 29773, 31142, 32541, 33972,
35433, 36924, 38447, 40000, 41584, 43199, 44844, 46521,
48228, 49965, 51734, 53533, 55363, 57224, 59116, 61038,
62991, 64975, 66990, 69035, 71111, 73218, 75356, 77524,
79723, 81953, 84214, 86505, 88827, 91180, 93564, 95978,
98424, 100900, 103406, 105944, 108512, 111111, 113741, 116401,
119093, 121815, 124567, 127351, 130165, 133010, 135886, 138793,
141730, 144698, 147697, 150727, 153787, 156878, 160000, 163153,
166336, 169550, 172795, 176071, 179377, 182714, 186082, 189481,
192910, 196371, 199862, 203383, 206936, 210519, 214133, 217778,
221453, 225160, 228897, 232664, 236463, 240292, 244152, 248043,
251965, 255917, 259900, 263914, 267958, 272034, 276140, 280277,
284444, 288643, 292872, 297132, 301423, 305744, 310096, 314479,
318893, 323337, 327812, 332318, 336855, 341423, 346021, 350650,
355309, 360000, 364721, 369473, 374256, 379070, 383914, 388789,
393695, 398631, 403599, 408597, 413626, 418685, 423775, 428897,
434048, 439231, 444444, 449689, 454963, 460269, 465606, 470973,
476371, 481799, 487259, 492749, 498270, 503822, 509404, 515017,
520661, 526336, 532042, 537778, 543545, 549343, 555171, 561030,
566920, 572841, 578793, 584775, 590788, 596832, 602907, 609012,
615148, 621315, 627512, 633741, 640000, 646290, 652611, 658962,
665344, 671757, 678201, 684675, 691180, 697716, 704283, 710880,
717509, 724168, 730857, 737578, 744329, 751111, 757924, 764767,
771642, 778547, 785483, 792449, 799446, 806474, 813533, 820623,
827743, 834894, 842076, 849289, 856532, 863806, 871111, 878447,
885813, 893210, 900638, 908097, 915586, 923106, 930657, 938239,
945852, 953495, 961169, 968874, 976609, 984375, 992172, 1000000
};
static const int gamma_curve_2p05_table[256] = {
0, 12, 48, 111, 200, 316, 459, 630,
828, 1054, 1308, 1590, 1901, 2240, 2607, 3003,
3428, 3882, 4364, 4876, 5416, 5986, 6585, 7213,
7871, 8558, 9274, 10020, 10796, 11601, 12436, 13301,
14195, 15120, 16074, 17058, 18072, 19116, 20191, 21295,
22429, 23594, 24789, 26014, 27269, 28555, 29871, 31217,
32594, 34001, 35439, 36907, 38406, 39935, 41495, 43086,
44707, 46359, 48042, 49755, 51499, 53274, 55080, 56917,
58784, 60683, 62612, 64572, 66563, 68586, 70639, 72723,
74838, 76985, 79162, 81371, 83610, 85881, 88183, 90517,
92881, 95277, 97704, 100162, 102651, 105172, 107724, 110308,
112923, 115569, 118247, 120956, 123697, 126469, 129272, 132107,
134974, 137872, 140801, 143762, 146755, 149779, 152835, 155923,
159042, 162192, 165375, 168589, 171835, 175112, 178422, 181763,
185135, 188540, 191976, 195444, 198944, 202476, 206040, 209635,
213262, 216922, 220613, 224336, 228090, 231877, 235696, 239547,
243429, 247344, 251291, 255269, 259280, 263323, 267398, 271504,
275643, 279814, 284017, 288252, 292520, 296819, 301151, 305514,
309910, 314338, 318798, 323291, 327815, 332372, 336961, 341582,
346236, 350922, 355640, 360390, 365172, 369987, 374835, 379714,
384626, 389570, 394547, 399556, 404597, 409671, 414777, 419915,
425086, 430289, 435525, 440793, 446094, 451427, 456792, 462190,
467621, 473084, 478579, 484107, 489667, 495261, 500886, 506544,
512235, 517958, 523714, 529502, 535323, 541177, 547063, 552982,
558934, 564918, 570934, 576984, 583066, 589181, 595328, 601508,
607721, 613966, 620245, 626555, 632899, 639275, 645685, 652126,
658601, 665109, 671649, 678222, 684827, 691466, 698137, 704842,
711579, 718348, 725151, 731986, 738855, 745756, 752690, 759657,
766657, 773690, 780755, 787854, 794985, 802150, 809347, 816577,
823840, 831136, 838465, 845827, 853222, 860650, 868111, 875605,
883132, 890692, 898285, 905911, 913570, 921262, 928987, 936745,
944536, 952360, 960218, 968108, 976031, 983988, 991977, 1000000
};
static const int gamma_curve_2p10_table[256] = {
0, 9, 38, 89, 162, 259, 381, 526,
696, 892, 1112, 1359, 1631, 1930, 2255, 2606,
2985, 3390, 3822, 4282, 4769, 5284, 5826, 6396,
6994, 7620, 8274, 8956, 9667, 10406, 11174, 11971,
12796, 13650, 14534, 15446, 16387, 17358, 18357, 19387,
20445, 21533, 22651, 23798, 24976, 26183, 27419, 28686,
29983, 31310, 32667, 34054, 35471, 36919, 38397, 39905,
41444, 43013, 44613, 46244, 47905, 49597, 51320, 53074,
54858, 56674, 58520, 60398, 62307, 64246, 66217, 68219,
70253, 72318, 74414, 76541, 78700, 80890, 83112, 85366,
87651, 89967, 92316, 94696, 97107, 99551, 102026, 104534,
107073, 109644, 112247, 114882, 117549, 120249, 122980, 125743,
128539, 131367, 134227, 137120, 140044, 143001, 145991, 149013,
152067, 155154, 158273, 161425, 164610, 167827, 171076, 174359,
177674, 181022, 184402, 187815, 191261, 194740, 198252, 201797,
205374, 208985, 212628, 216305, 220014, 223757, 227533, 231341,
235183, 239058, 242967, 246908, 250883, 254891, 258932, 263007,
267114, 271256, 275430, 279638, 283880, 288155, 292463, 296805,
301181, 305589, 310032, 314508, 319018, 323561, 328139, 332749,
337394, 342072, 346784, 351530, 356309, 361123, 365970, 370851,
375766, 380715, 385698, 390715, 395765, 400850, 405969, 411122,
416308, 421529, 426784, 432073, 437397, 442754, 448146, 453571,
459031, 464525, 470054, 475617, 481214, 486845, 492511, 498211,
503945, 509714, 515517, 521354, 527226, 533133, 539074, 545049,
551059, 557104, 563183, 569296, 575444, 581627, 587845, 594097,
600383, 606705, 613061, 619451, 625877, 632337, 638832, 645362,
651926, 658526, 665160, 671829, 678533, 685272, 692045, 698854,
705697, 712576, 719489, 726438, 733421, 740439, 747493, 754581,
761704, 768863, 776057, 783285, 790549, 797848, 805182, 812551,
819956, 827395, 834870, 842380, 849925, 857506, 865122, 872773,
880459, 888181, 895938, 903730, 911558, 919421, 927319, 935253,
943222, 951227, 959267, 967343, 975454, 983600, 991782, 1000000
};
static const int gamma_curve_2p12_table[256] = {
0, 8, 34, 81, 149, 240, 353, 489,
650, 834, 1043, 1276, 1535, 1818, 2128, 2463,
2824, 3211, 3625, 4065, 4532, 5026, 5547, 6095,
6671, 7274, 7905, 8563, 9249, 9964, 10706, 11477,
12276, 13103, 13960, 14844, 15758, 16700, 17672, 18672,
19702, 20760, 21849, 22966, 24113, 25290, 26496, 27732,
28998, 30294, 31619, 32975, 34361, 35777, 37223, 38699,
40206, 41744, 43311, 44910, 46539, 48199, 49889, 51610,
53363, 55146, 56960, 58805, 60681, 62589, 64527, 66497,
68498, 70531, 72595, 74690, 76817, 78976, 81166, 83388,
85642, 87927, 90244, 92593, 94974, 97387, 99832, 102309,
104819, 107360, 109933, 112539, 115177, 117847, 120550, 123285,
126052, 128852, 131684, 134549, 137447, 140377, 143340, 146336,
149364, 152425, 155519, 158646, 161805, 164998, 168224, 171482,
174774, 178099, 181457, 184848, 188272, 191729, 195220, 198744,
202301, 205892, 209516, 213174, 216865, 220589, 224347, 228139,
231964, 235822, 239715, 243641, 247601, 251594, 255621, 259682,
263777, 267906, 272069, 276265, 280496, 284760, 289059, 293391,
297758, 302159, 306593, 311062, 315566, 320103, 324675, 329280,
333921, 338595, 343304, 348047, 352825, 357637, 362483, 367364,
372280, 377230, 382214, 387233, 392287, 397375, 402498, 407656,
412848, 418075, 423337, 428634, 433965, 439332, 444733, 450169,
455640, 461146, 466686, 472262, 477873, 483519, 489200, 494916,
500667, 506453, 512274, 518130, 524022, 529949, 535911, 541908,
547941, 554008, 560111, 566250, 572424, 578633, 584878, 591158,
597473, 603824, 610211, 616633, 623090, 629583, 636112, 642676,
649276, 655911, 662582, 669289, 676031, 682810, 689623, 696473,
703359, 710280, 717237, 724230, 731258, 738323, 745424, 752560,
759732, 766941, 774185, 781465, 788781, 796134, 803522, 810947,
818407, 825904, 833436, 841005, 848610, 856251, 863929, 871642,
879392, 887178, 895001, 902859, 910754, 918686, 926653, 934657,
942698, 950774, 958887, 967037, 975223, 983446, 991705, 1000000
};
static const int gamma_curve_2p13_table[256] = {
0, 7, 33, 78, 143, 231, 340, 472,
628, 807, 1009, 1237, 1488, 1765, 2067, 2394,
2747, 3126, 3530, 3961, 4418, 4902, 5413, 5950,
6515, 7107, 7726, 8373, 9047, 9749, 10479, 11238,
12024, 12838, 13681, 14552, 15452, 16381, 17338, 18325,
19340, 20384, 21458, 22561, 23693, 24855, 26046, 27267,
28518, 29798, 31108, 32448, 33819, 35219, 36650, 38110,
39601, 41123, 42675, 44257, 45870, 47514, 49189, 50894,
52630, 54397, 56195, 58024, 59884, 61776, 63698, 65652,
67638, 69654, 71702, 73782, 75893, 78036, 80210, 82417,
84655, 86925, 89226, 91560, 93926, 96323, 98753, 101215,
103709, 106236, 108794, 111385, 114009, 116664, 119353, 122073,
124827, 127612, 130431, 133282, 136166, 139083, 142033, 145015,
148030, 151078, 154160, 157274, 160421, 163602, 166815, 170062,
173342, 176655, 180002, 183382, 186795, 190242, 193722, 197235,
200782, 204363, 207977, 211625, 215307, 219022, 222771, 226554,
230370, 234221, 238105, 242023, 245976, 249962, 253982, 258036,
262124, 266247, 270403, 274594, 278819, 283078, 287371, 291699,
296061, 300458, 304888, 309354, 313853, 318388, 322956, 327560,
332197, 336870, 341577, 346319, 351095, 355906, 360752, 365633,
370548, 375499, 380484, 385504, 390559, 395649, 400774, 405934,
411129, 416359, 421624, 426925, 432260, 437631, 443036, 448477,
453954, 459465, 465012, 470594, 476211, 481864, 487553, 493276,
499035, 504830, 510660, 516526, 522427, 528364, 534336, 540344,
546388, 552467, 558582, 564733, 570919, 577142, 583400, 589694,
596023, 602389, 608790, 615228, 621701, 628210, 634756, 641337,
647954, 654608, 661297, 668022, 674784, 681582, 688416, 695286,
702192, 709135, 716113, 723128, 730180, 737267, 744391, 751552,
758748, 765981, 773251, 780557, 787899, 795278, 802693, 810145,
817634, 825159, 832720, 840319, 847953, 855625, 863333, 871078,
878859, 886678, 894533, 902424, 910353, 918318, 926320, 934359,
942435, 950548, 958698, 966884, 975108, 983368, 991666, 1000000
};
static const int gamma_curve_2p15_table[256] = {
0, 7, 30, 71, 132, 213, 315, 439,
586, 754, 946, 1161, 1400, 1663, 1950, 2262,
2599, 2961, 3348, 3761, 4199, 4663, 5154, 5671,
6214, 6784, 7381, 8005, 8656, 9335, 10040, 10774,
11535, 12324, 13141, 13986, 14859, 15761, 16691, 17649,
18637, 19653, 20698, 21772, 22875, 24007, 25169, 26360,
27581, 28831, 30111, 31421, 32760, 34130, 35529, 36959,
38419, 39909, 41429, 42980, 44562, 46174, 47817, 49490,
51195, 52930, 54696, 56494, 58322, 60182, 62073, 63995,
65948, 67933, 69950, 71998, 74078, 76189, 78333, 80508,
82715, 84954, 87224, 89528, 91863, 94230, 96630, 99062,
101526, 104022, 106552, 109113, 111708, 114334, 116994, 119686,
122411, 125169, 127960, 130784, 133641, 136530, 139453, 142409,
145399, 148421, 151477, 154566, 157688, 160844, 164034, 167257,
170513, 173803, 177127, 180484, 183875, 187300, 190759, 194252,
197778, 201339, 204933, 208562, 212224, 215921, 219652, 223417,
227217, 231050, 234918, 238821, 242757, 246729, 250734, 254775,
258849, 262959, 267103, 271282, 275495, 279743, 284026, 288344,
292697, 297084, 301507, 305964, 310457, 314984, 319547, 324145,
328778, 333446, 338149, 342888, 347661, 352471, 357315, 362195,
367110, 372061, 377047, 382069, 387126, 392219, 397348, 402512,
407712, 412948, 418219, 423526, 428869, 434248, 439663, 445113,
450600, 456122, 461681, 467275, 472906, 478572, 484275, 490014,
495789, 501600, 507448, 513332, 519252, 525208, 531201, 537230,
543296, 549398, 555536, 561711, 567923, 574171, 580455, 586777,
593134, 599529, 605960, 612428, 618933, 625474, 632052, 638668,
645319, 652008, 658734, 665497, 672296, 679133, 686006, 692917,
699865, 706850, 713872, 720931, 728027, 735160, 742331, 749539,
756784, 764066, 771386, 778743, 786138, 793569, 801039, 808545,
816089, 823671, 831290, 838947, 846641, 854373, 862143, 869950,
877794, 885677, 893597, 901555, 909550, 917584, 925655, 933764,
941911, 950095, 958318, 966578, 974877, 983213, 991588, 1000000
};
static const int gamma_curve_2p18_table[256] = {
0, 6, 26, 62, 116, 189, 282, 395,
528, 682, 859, 1057, 1277, 1521, 1788, 2078,
2392, 2730, 3092, 3479, 3890, 4327, 4789, 5276,
5789, 6328, 6893, 7484, 8101, 8745, 9416, 10114,
10839, 11591, 12370, 13177, 14011, 14874, 15764, 16683,
17629, 18604, 19608, 20640, 21700, 22790, 23909, 25056,
26233, 27439, 28675, 29940, 31234, 32558, 33913, 35297,
36711, 38155, 39629, 41134, 42669, 44235, 45831, 47457,
49115, 50803, 52523, 54273, 56055, 57867, 59711, 61587,
63493, 65431, 67401, 69403, 71436, 73501, 75598, 77727,
79887, 82080, 84306, 86563, 88853, 91175, 93530, 95917,
98336, 100789, 103274, 105792, 108343, 110926, 113543, 116193,
118876, 121592, 124341, 127124, 129940, 132789, 135672, 138589,
141539, 144522, 147540, 150591, 153676, 156795, 159948, 163135,
166356, 169611, 172900, 176223, 179581, 182973, 186400, 189861,
193356, 196886, 200450, 204050, 207683, 211352, 215055, 218794,
222567, 226375, 230218, 234096, 238009, 241957, 245941, 249960,
254014, 258103, 262228, 266388, 270584, 274815, 279081, 283384,
287722, 292095, 296505, 300950, 305431, 309948, 314501, 319089,
323714, 328375, 333072, 337805, 342574, 347379, 352221, 357099,
362013, 366963, 371950, 376974, 382034, 387131, 392264, 397433,
402640, 407883, 413163, 418479, 423833, 429223, 434650, 440114,
445615, 451153, 456728, 462341, 467990, 473676, 479400, 485161,
490959, 496794, 502667, 508577, 514525, 520510, 526533, 532593,
538690, 544825, 550998, 557209, 563457, 569743, 576066, 582428,
588827, 595264, 601739, 608252, 614803, 621392, 628019, 634684,
641387, 648129, 654908, 661726, 668582, 675476, 682409, 689379,
696388, 703436, 710522, 717647, 724809, 732011, 739251, 746530,
753847, 761203, 768597, 776030, 783502, 791013, 798563, 806151,
813779, 821445, 829150, 836894, 844677, 852499, 860360, 868260,
876199, 884178, 892195, 900252, 908348, 916483, 924658, 932871,
941124, 949417, 957749, 966120, 974531, 982981, 991471, 1000000
};
static const int gamma_curve_2p20_table[256] = {
0, 5, 23, 57, 107, 175, 262, 367,
493, 638, 805, 992, 1202, 1433, 1687, 1963,
2263, 2586, 2932, 3303, 3697, 4116, 4560, 5028,
5522, 6041, 6585, 7155, 7751, 8373, 9021, 9696,
10398, 11126, 11881, 12664, 13473, 14311, 15175, 16068,
16988, 17936, 18913, 19918, 20951, 22013, 23104, 24223,
25371, 26549, 27755, 28991, 30257, 31551, 32876, 34230,
35614, 37029, 38473, 39947, 41452, 42987, 44553, 46149,
47776, 49433, 51122, 52842, 54592, 56374, 58187, 60032,
61907, 63815, 65754, 67725, 69727, 71761, 73828, 75926,
78057, 80219, 82414, 84642, 86901, 89194, 91518, 93876,
96266, 98689, 101145, 103634, 106156, 108711, 111299, 113921,
116576, 119264, 121986, 124741, 127530, 130352, 133209, 136099,
139022, 141980, 144972, 147998, 151058, 154152, 157281, 160444,
163641, 166872, 170138, 173439, 176774, 180144, 183549, 186989,
190463, 193972, 197516, 201096, 204710, 208360, 212044, 215764,
219520, 223310, 227137, 230998, 234895, 238828, 242796, 246800,
250840, 254916, 259027, 263175, 267358, 271577, 275833, 280124,
284452, 288816, 293216, 297653, 302125, 306635, 311180, 315763,
320382, 325037, 329729, 334458, 339223, 344026, 348865, 353741,
358654, 363604, 368591, 373615, 378676, 383775, 388910, 394083,
399293, 404541, 409826, 415148, 420508, 425905, 431340, 436813,
442323, 447871, 453456, 459080, 464741, 470440, 476177, 481952,
487765, 493616, 499505, 505432, 511398, 517401, 523443, 529523,
535642, 541798, 547994, 554227, 560499, 566810, 573159, 579547,
585973, 592438, 598942, 605484, 612066, 618686, 625345, 632043,
638779, 645555, 652370, 659224, 666117, 673049, 680020, 687031,
694081, 701170, 708298, 715465, 722672, 729919, 737205, 744530,
751895, 759300, 766744, 774227, 781751, 789314, 796917, 804559,
812241, 819964, 827726, 835528, 843370, 851252, 859174, 867136,
875138, 883180, 891262, 899385, 907547, 915750, 923993, 932277,
940601, 948965, 957370, 965815, 974300, 982826, 991393, 1000000
};
static const int gamma_curve_2p21_table[256] = {
0, 5, 22, 54, 103, 168, 252, 354,
476, 617, 779, 962, 1166, 1391, 1639, 1909,
2201, 2517, 2856, 3218, 3604, 4015, 4449, 4909,
5393, 5902, 6436, 6996, 7582, 8193, 8830, 9494,
10184, 10901, 11644, 12415, 13212, 14037, 14889, 15769,
16676, 17612, 18575, 19566, 20586, 21634, 22711, 23817,
24951, 26114, 27307, 28528, 29779, 31060, 32370, 33709,
35079, 36478, 37907, 39367, 40856, 42377, 43927, 45508,
47120, 48762, 50436, 52140, 53875, 55642, 57440, 59269,
61130, 63022, 64945, 66901, 68888, 70907, 72958, 75042,
77157, 79305, 81484, 83697, 85942, 88219, 90529, 92872,
95247, 97656, 100097, 102572, 105079, 107620, 110194, 112802,
115442, 118117, 120825, 123566, 126342, 129151, 131994, 134870,
137781, 140726, 143705, 146718, 149766, 152848, 155964, 159115,
162300, 165520, 168774, 172063, 175387, 178746, 182140, 185569,
189033, 192532, 196066, 199635, 203240, 206879, 210555, 214266,
218012, 221794, 225611, 229465, 233354, 237278, 241239, 245236,
249268, 253337, 257442, 261583, 265760, 269973, 274223, 278509,
282831, 287190, 291586, 296018, 300486, 304992, 309534, 314113,
318728, 323381, 328070, 332797, 337560, 342361, 347199, 352074,
356986, 361936, 366923, 371947, 377008, 382108, 387244, 392419,
397631, 402880, 408167, 413492, 418855, 424256, 429695, 435171,
440686, 446239, 451829, 457458, 463125, 468830, 474574, 480356,
486176, 492035, 497932, 503867, 509841, 515854, 521905, 527995,
534124, 540291, 546497, 552742, 559026, 565349, 571711, 578111,
584551, 591030, 597548, 604105, 610701, 617337, 624012, 630726,
637479, 644272, 651105, 657977, 664888, 671839, 678829, 685860,
692929, 700039, 707188, 714377, 721606, 728875, 736184, 743532,
750921, 758350, 765818, 773327, 780876, 788465, 796095, 803764,
811474, 819224, 827015, 834846, 842717, 850629, 858581, 866574,
874607, 882681, 890796, 898951, 907147, 915384, 923661, 931980,
940339, 948739, 957180, 965662, 974185, 982749, 991354, 1000000
};
static const int gamma_curve_2p22_table[256] = {
0, 5, 21, 52, 99, 162, 243, 342,
460, 597, 754, 932, 1130, 1350, 1592, 1855,
2141, 2449, 2781, 3136, 3514, 3916, 4342, 4792,
5267, 5766, 6291, 6841, 7416, 8017, 8644, 9296,
9975, 10680, 11412, 12171, 12956, 13769, 14608, 15475,
16370, 17293, 18243, 19221, 20228, 21262, 22326, 23417,
24538, 25687, 26865, 28073, 29309, 30575, 31871, 33196,
34551, 35935, 37350, 38795, 40270, 41775, 43310, 44876,
46473, 48100, 49759, 51448, 53168, 54919, 56702, 58516,
60361, 62238, 64147, 66087, 68059, 70063, 72099, 74167,
76268, 78400, 80565, 82763, 84993, 87255, 89550, 91878,
94239, 96633, 99060, 101520, 104014, 106540, 109100, 111693,
114320, 116981, 119675, 122403, 125164, 127960, 130790, 133653,
136551, 139483, 142449, 145450, 148485, 151554, 154658, 157797,
160970, 164178, 167421, 170699, 174011, 177359, 180742, 184160,
187613, 191102, 194625, 198185, 201779, 205410, 209076, 212777,
216514, 220288, 224096, 227941, 231822, 235739, 239692, 243681,
247706, 251768, 255866, 260000, 264171, 268378, 272622, 276902,
281220, 285573, 289964, 294392, 298856, 303357, 307896, 312471,
317083, 321733, 326420, 331144, 335906, 340705, 345541, 350415,
355326, 360275, 365262, 370286, 375348, 380448, 385586, 390761,
395975, 401226, 406516, 411843, 417209, 422613, 428056, 433536,
439055, 444612, 450208, 455842, 461515, 467226, 472976, 478765,
484592, 490458, 496363, 502307, 508290, 514311, 520372, 526472,
532610, 538788, 545005, 551261, 557557, 563892, 570266, 576680,
583133, 589625, 596157, 602729, 609340, 615991, 622682, 629412,
636182, 642992, 649842, 656732, 663661, 670631, 677641, 684690,
691780, 698910, 706080, 713291, 720542, 727833, 735164, 742536,
749948, 757401, 764894, 772428, 780003, 787618, 795274, 802970,
810707, 818485, 826304, 834164, 842065, 850006, 857989, 866012,
874077, 882183, 890330, 898518, 906747, 915018, 923330, 931683,
940077, 948513, 956990, 965509, 974070, 982671, 991315, 1000000
};
static const int gamma_curve_2p23_table[256] = {
0, 4, 20, 50, 95, 156, 234, 330,
444, 577, 730, 903, 1096, 1311, 1546, 1803,
2083, 2384, 2708, 3055, 3425, 3819, 4237, 4678,
5144, 5634, 6149, 6689, 7254, 7844, 8460, 9102,
9770, 10464, 11184, 11931, 12705, 13505, 14333, 15188,
16070, 16979, 17917, 18882, 19875, 20897, 21947, 23025,
24131, 25267, 26431, 27625, 28847, 30099, 31380, 32691,
34031, 35401, 36801, 38231, 39691, 41181, 42702, 44253,
45835, 47447, 49091, 50765, 52470, 54206, 55974, 57773,
59603, 61465, 63358, 65283, 67240, 69229, 71250, 73303,
75389, 77506, 79656, 81839, 84054, 86302, 88582, 90896,
93242, 95621, 98034, 100480, 102959, 105471, 108017, 110596,
113209, 115855, 118536, 121250, 123998, 126780, 129597, 132447,
135332, 138251, 141204, 144192, 147214, 150271, 153363, 156490,
159651, 162847, 166078, 169345, 172646, 175983, 179354, 182762,
186204, 189682, 193196, 196745, 200330, 203950, 207607, 211299,
215027, 218792, 222592, 226428, 230301, 234210, 238155, 242136,
246154, 250209, 254300, 258427, 262592, 266793, 271031, 275305,
279617, 283966, 288352, 292774, 297234, 301732, 306266, 310838,
315447, 320094, 324778, 329500, 334259, 339056, 343891, 348763,
353674, 358622, 363608, 368633, 373695, 378795, 383934, 389111,
394326, 399579, 404871, 410201, 415570, 420977, 426423, 431907,
437430, 442992, 448592, 454232, 459910, 465627, 471384, 477179,
483013, 488887, 494800, 500751, 506743, 512773, 518843, 524952,
531101, 537289, 543517, 549785, 556092, 562439, 568825, 575251,
581718, 588224, 594770, 601356, 607982, 614648, 621354, 628101,
634887, 641714, 648581, 655489, 662437, 669425, 676454, 683523,
690633, 697783, 704974, 712206, 719479, 726792, 734146, 741541,
748977, 756454, 763972, 771530, 779130, 786771, 794453, 802177,
809941, 817747, 825594, 833483, 841413, 849384, 857397, 865451,
873547, 881685, 889864, 898085, 906347, 914652, 922998, 931386,
939816, 948287, 956801, 965357, 973954, 982594, 991276, 1000000
};
static const int gamma_curve_2p24_table[256] = {
0, 4, 19, 48, 91, 150, 225, 318,
429, 558, 707, 875, 1063, 1272, 1502, 1753,
2026, 2320, 2637, 2977, 3339, 3725, 4134, 4567,
5024, 5505, 6010, 6540, 7096, 7676, 8281, 8913,
9569, 10252, 10961, 11697, 12459, 13247, 14063, 14905,
15775, 16672, 17597, 18549, 19529, 20537, 21574, 22639,
23732, 24854, 26004, 27184, 28392, 29630, 30897, 32193,
33519, 34875, 36260, 37675, 39121, 40597, 42102, 43639,
45206, 46803, 48432, 50091, 51781, 53502, 55255, 57039,
58854, 60701, 62579, 64489, 66431, 68405, 70411, 72449,
74520, 76623, 78758, 80925, 83126, 85359, 87625, 89923,
92255, 94620, 97018, 99450, 101914, 104412, 106944, 109509,
112108, 114741, 117408, 120108, 122843, 125612, 128415, 131252,
134123, 137029, 139970, 142945, 145955, 149000, 152079, 155193,
158343, 161527, 164747, 168001, 171292, 174617, 177978, 181374,
184806, 188274, 191777, 195316, 198891, 202502, 206148, 209831,
213550, 217306, 221097, 224925, 228789, 232690, 236627, 240601,
244612, 248659, 252743, 256864, 261022, 265217, 269449, 273718,
278024, 282367, 286748, 291166, 295622, 300115, 304645, 309213,
313819, 318463, 323144, 327863, 332621, 337416, 342249, 347120,
352029, 356977, 361963, 366987, 372049, 377150, 382289, 387467,
392684, 397939, 403233, 408565, 413936, 419347, 424796, 430284,
435811, 441377, 446983, 452627, 458311, 464034, 469797, 475598,
481440, 487320, 493241, 499201, 505200, 511240, 517319, 523437,
529596, 535795, 542033, 548312, 554630, 560989, 567388, 573827,
580306, 586826, 593386, 599986, 606627, 613308, 620030, 626792,
633595, 640439, 647323, 654248, 661214, 668221, 675269, 682358,
689488, 696658, 703870, 711123, 718417, 725753, 733129, 740547,
748007, 755508, 763050, 770634, 778259, 785926, 793634, 801384,
809176, 817010, 824885, 832802, 840762, 848763, 856806, 864891,
873018, 881187, 889399, 897652, 905948, 914286, 922666, 931089,
939554, 948062, 956612, 965204, 973839, 982517, 991237, 1000000
};
static const int gamma_curve_2p25_table[256] = {
0, 4, 18, 46, 87, 144, 217, 307,
414, 540, 684, 848, 1031, 1235, 1459, 1704,
1970, 2258, 2568, 2901, 3255, 3633, 4034, 4458,
4906, 5378, 5875, 6395, 6940, 7511, 8106, 8727,
9373, 10045, 10743, 11467, 12217, 12994, 13797, 14628,
15485, 16370, 17282, 18222, 19189, 20184, 21208, 22259,
23339, 24447, 25584, 26750, 27944, 29168, 30421, 31703,
33015, 34356, 35727, 37128, 38559, 40020, 41511, 43033,
44585, 46168, 47781, 49426, 51101, 52807, 54545, 56314,
58114, 59946, 61810, 63705, 65632, 67591, 69582, 71605,
73661, 75749, 77869, 80022, 82208, 84426, 86677, 88962,
91279, 93629, 96013, 98430, 100880, 103364, 105882, 108433,
111018, 113637, 116290, 118977, 121698, 124454, 127243, 130067,
132926, 135819, 138747, 141709, 144707, 147739, 150806, 153908,
157045, 160218, 163426, 166669, 169948, 173262, 176612, 179997,
183418, 186875, 190368, 193897, 197462, 201063, 204700, 208374,
212084, 215830, 219613, 223432, 227288, 231180, 235110, 239076,
243079, 247119, 251196, 255310, 259461, 263650, 267876, 272139,
276440, 280778, 285153, 289567, 294018, 298506, 303033, 307597,
312200, 316840, 321519, 326235, 330990, 335783, 340614, 345484,
350392, 355339, 360324, 365348, 370410, 375512, 380652, 385831,
391048, 396305, 401601, 406936, 412310, 417723, 423175, 428667,
434198, 439769, 445379, 451028, 456718, 462446, 468215, 474023,
479871, 485759, 491687, 497655, 503663, 509711, 515799, 521927,
528095, 534304, 540553, 546843, 553173, 559543, 565954, 572406,
578898, 585431, 592005, 598619, 605275, 611971, 618708, 625486,
632306, 639166, 646068, 653010, 659994, 667020, 674086, 681194,
688344, 695535, 702768, 710042, 717357, 724715, 732114, 739555,
747038, 754563, 762129, 769738, 777388, 785081, 792816, 800593,
808412, 816273, 824177, 832123, 840111, 848142, 856215, 864331,
872489, 880690, 888933, 897220, 905548, 913920, 922335, 930792,
939293, 947836, 956422, 965051, 973724, 982439, 991198, 1000000
};
#endif /* __DYNAMIC_AID_GAMMA_CURVE_H */

View file

@ -0,0 +1,188 @@
/*
* drivers/video/decon_7580/panels/ea8064g_lcd_ctrl.c
*
* Samsung SoC MIPI LCD CONTROL functions
*
* Copyright (c) 2015 Samsung Electronics
*
* 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.
*/
#include "ea8064g_param.h"
#include <video/mipi_display.h>
#include "../dsim.h"
static int dsim_write_hl_data(u32 id, const u8 *cmd, u32 cmdSize)
{
int ret;
int retry;
retry = 5;
try_write:
if (cmdSize == 1)
ret = dsim_wr_data(id, MIPI_DSI_DCS_SHORT_WRITE, cmd[0], 0);
else if (cmdSize == 2)
ret = dsim_wr_data(id, MIPI_DSI_DCS_SHORT_WRITE_PARAM, cmd[0], cmd[1]);
else
ret = dsim_wr_data(id, MIPI_DSI_DCS_LONG_WRITE, (unsigned long)cmd,
cmdSize);
if (ret != 0) {
if (--retry)
goto try_write;
else
dsim_err("dsim write failed, cmd : %x\n", cmd[0]);
}
return ret;
}
void lcd_enable(void)
{
int id = 0;
int ret = 0;
dsim_info("MDD : %s was called\n", __func__);
ret = dsim_write_hl_data(id, SEQ_DISPLAY_ON, ARRAY_SIZE(SEQ_DISPLAY_ON));
if (ret < 0)
dsim_err("%s : fail to write CMD : DISPLAY_ON\n", __func__);
}
void lcd_disable(struct dsim_device *dsim)
{
/* This function needs to implement */
}
void lcd_init(struct decon_lcd *lcd)
{
int id = 0;
int ret = 0;
dsim_info("MDD : %s was called\n", __func__);
/* set_brightness */
ret = dsim_write_hl_data(id, SEQ_TEST_KEY_ON_F0, ARRAY_SIZE(SEQ_TEST_KEY_ON_F0));
if (ret < 0) {
dsim_err("%s : fail to write CMD : SEQ_TEST_KEY_ON_F0\n", __func__);
goto init_exit;
}
ret = dsim_write_hl_data(id, SEQ_TEST_KEY_ON_F1, ARRAY_SIZE(SEQ_TEST_KEY_ON_F1));
if (ret < 0) {
dsim_err("%s : fail to write CMD : SEQ_TEST_KEY_ON_F1\n", __func__);
goto init_exit;
}
ret = dsim_write_hl_data(id, SEQ_TEST_KEY_ON_FC, ARRAY_SIZE(SEQ_TEST_KEY_ON_FC));
if (ret < 0) {
dsim_err("%s : fail to write CMD : SEQ_TEST_KEY_ON_FC\n", __func__);
goto init_exit;
}
ret = dsim_write_hl_data(id, SEQ_BRIGHTNESS_1, ARRAY_SIZE(SEQ_BRIGHTNESS_1));
if (ret < 0) {
dsim_err("%s : fail to write CMD : SEQ_BRIGHTNESS_1\n", __func__);
goto init_exit;
}
ret = dsim_write_hl_data(id, SEQ_BRIGHTNESS_2, ARRAY_SIZE(SEQ_BRIGHTNESS_2));
if (ret < 0) {
dsim_err("%s : fail to write CMD : SEQ_BRIGHTNESS_2\n", __func__);
goto init_exit;
}
ret = dsim_write_hl_data(id, SEQ_BRIGHTNESS_3, ARRAY_SIZE(SEQ_BRIGHTNESS_3));
if (ret < 0) {
dsim_err("%s : fail to write CMD : SEQ_BRIGHTNESS_3\n", __func__);
goto init_exit;
}
ret = dsim_write_hl_data(id, SEQ_GAMMA_UPDATE_EA8064G, ARRAY_SIZE(SEQ_GAMMA_UPDATE_EA8064G));
if (ret < 0) {
dsim_err(":%s fail to write CMD : SEQ_GAMMA_UPDATE_EA8064G\n", __func__);
goto init_exit;
}
ret = dsim_write_hl_data(id, SEQ_TEST_KEY_OFF_FC, ARRAY_SIZE(SEQ_TEST_KEY_OFF_FC));
if (ret < 0) {
dsim_err(":%s fail to write CMD : SEQ_TEST_KEY_OFF_FC\n", __func__);
goto init_exit;
}
ret = dsim_write_hl_data(id, SEQ_TEST_KEY_OFF_F1, ARRAY_SIZE(SEQ_TEST_KEY_OFF_F1));
if (ret < 0) {
dsim_err(":%s fail to write CMD : SEQ_TEST_KEY_OFF_F1\n", __func__);
goto init_exit;
}
ret = dsim_write_hl_data(id, SEQ_TEST_KEY_OFF_F0, ARRAY_SIZE(SEQ_TEST_KEY_OFF_F0));
if (ret < 0) {
dsim_err(":%s fail to write CMD : SEQ_TEST_KEY_OFF_F0\n", __func__);
goto init_exit;
}
/* panel init */
ret = dsim_write_hl_data(id, SEQ_TEST_KEY_ON_F0, ARRAY_SIZE(SEQ_TEST_KEY_ON_F0));
if (ret < 0) {
dsim_err("%s : fail to write CMD : SEQ_TEST_KEY_ON_F0\n", __func__);
goto init_exit;
}
ret = dsim_write_hl_data(id, SEQ_TEST_KEY_ON_FC, ARRAY_SIZE(SEQ_TEST_KEY_ON_FC));
if (ret < 0) {
dsim_err("%s : fail to write CMD : SEQ_TEST_KEY_ON_FC\n", __func__);
goto init_exit;
}
ret = dsim_write_hl_data(id, SEQ_SLEEP_OUT, ARRAY_SIZE(SEQ_SLEEP_OUT));
if (ret < 0) {
dsim_err("%s : fail to write CMD : SEQ_SLEEP_OUT\n", __func__);
goto init_exit;
}
msleep(25);
ret = dsim_write_hl_data(id, SEQ_DCDC1_GP, ARRAY_SIZE(SEQ_DCDC1_GP));
if (ret < 0) {
dsim_err(":%s fail to write CMD : SEQ_SOURCE_CONTROL\n", __func__);
goto init_exit;
}
ret = dsim_write_hl_data(id, SEQ_DCDC1_SET, ARRAY_SIZE(SEQ_DCDC1_SET));
if (ret < 0) {
dsim_err(":%s fail to write CMD : SEQ_SOURCE_CONTROL\n", __func__);
goto init_exit;
}
ret = dsim_write_hl_data(id, SEQ_SOURCE_CONTROL, ARRAY_SIZE(SEQ_SOURCE_CONTROL));
if (ret < 0) {
dsim_err(":%s fail to write CMD : SEQ_SOURCE_CONTROL\n", __func__);
goto init_exit;
}
ret = dsim_write_hl_data(id, SEQ_PCD_CONTROL, ARRAY_SIZE(SEQ_PCD_CONTROL));
if (ret < 0) {
dsim_err(":%s fail to write CMD : SEQ_PCD_CONTROL\n", __func__);
goto init_exit;
}
ret = dsim_write_hl_data(id, SEQ_TEST_KEY_OFF_FC, ARRAY_SIZE(SEQ_TEST_KEY_OFF_FC));
if (ret < 0) {
dsim_err(":%s fail to write CMD : SEQ_TEST_KEY_OFF_FC\n", __func__);
goto init_exit;
}
msleep(120);
ret = dsim_write_hl_data(id, SEQ_TE_OUT, ARRAY_SIZE(SEQ_TE_OUT));
if (ret < 0) {
dsim_err(":%s fail to write CMD : SEQ_TE_OUT\n", __func__);
goto init_exit;
}
ret = dsim_write_hl_data(id, SEQ_TEST_KEY_OFF_F0, ARRAY_SIZE(SEQ_TEST_KEY_OFF_F0));
if (ret < 0) {
dsim_err("%s : fail to write CMD : SEQ_TEST_KEY_OFF_F0\n", __func__);
goto init_exit;
}
init_exit:
return;
}

View file

@ -0,0 +1,77 @@
/* drivers/video/fbdev/exynos/decon_7870/panels/ea8064g_mipi_lcd.c
*
* Samsung SoC MIPI LCD driver.
*
* Copyright (c) 2015 Samsung Electronics
*
* 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.
*/
#include <linux/delay.h>
#include <linux/gpio.h>
#include <video/mipi_display.h>
#include <linux/platform_device.h>
#include "../dsim.h"
#include "lcd_ctrl.h"
#include "decon_lcd.h"
#define MAX_BRIGHTNESS 255
#define MIN_BRIGHTNESS 0
#define DEFAULT_BRIGHTNESS 0
static struct backlight_device *bd;
static int ea8064g_get_brightness(struct backlight_device *bd)
{
return bd->props.brightness;
}
static int ea8064g_set_brightness(struct backlight_device *bd)
{
return 1;
}
static const struct backlight_ops ea8064g_backlight_ops = {
.get_brightness = ea8064g_get_brightness,
.update_status = ea8064g_set_brightness,
};
static int ea8064g_probe(struct dsim_device *dsim)
{
bd = backlight_device_register("pwm-backlight.0", NULL,
NULL, &ea8064g_backlight_ops, NULL);
if (IS_ERR(bd))
pr_alert("failed to register backlight device!\n");
bd->props.max_brightness = MAX_BRIGHTNESS;
bd->props.brightness = DEFAULT_BRIGHTNESS;
return 1;
}
static int ea8064g_displayon(struct dsim_device *dsim)
{
lcd_init(&dsim->lcd_info);
lcd_enable();
return 1;
}
static int ea8064g_suspend(struct dsim_device *dsim)
{
return 1;
}
static int ea8064g_resume(struct dsim_device *dsim)
{
return 1;
}
struct mipi_dsim_lcd_driver ea8064g_mipi_lcd_driver = {
.probe = ea8064g_probe,
.displayon = ea8064g_displayon,
.suspend = ea8064g_suspend,
.resume = ea8064g_resume,
};

View file

@ -0,0 +1,239 @@
/* linux/drivers/video/fbdev/exynos/decon_7870/panels/ea8064g_param.h
*
* Copyright (c) 2015 Samsung Electronics Co., Ltd.
*
* 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.
*/
#ifndef __EA8064G_PARAM_H__
#define __EA8064G_PARAM_H__
#include <linux/types.h>
#include <linux/kernel.h>
static const unsigned char SEQ_TEST_KEY_ON_F0[] = {
0xF0,
0x5A, 0x5A
};
static const unsigned char SEQ_TEST_KEY_OFF_F0[] = {
0xF0,
0xA5, 0xA5
};
static const unsigned char SEQ_TEST_KEY_ON_F1[] = {
0xF1,
0x5A, 0x5A
};
static const unsigned char SEQ_TEST_KEY_OFF_F1[] = {
0xF1,
0xA5, 0xA5
};
static const unsigned char SEQ_TEST_KEY_ON_FC[] = {
0xFC,
0x5A, 0x5A,
};
static const unsigned char SEQ_TEST_KEY_OFF_FC[] = {
0xFC,
0xA5, 0xA5,
};
static const unsigned char SEQ_SLEEP_OUT[] = {
0x11
};
static const unsigned char SEQ_SOURCE_CONTROL[] = {
0xBA,
0x32, 0x30, 0x01
};
static const unsigned char SEQ_PCD_CONTROL[] = {
0xCC,
0x55,
};
static const unsigned char SEQ_GAMMA_CONDITION_SET[] = {
0xCA,
0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x00, 0x00, 0x00
};
static const unsigned char SEQ_AID_SET[] = {
0xB2,
0x00, 0x0E, 0x00, 0x0E,
};
static const unsigned char SEQ_AID_SET_RevF[] = {
0xB2,
0x00, 0x06, 0x00, 0x06,
};
static const unsigned char SEQ_ELVSS_SET[] = {
0xB6,
0x98, 0x0A,
};
static const unsigned char SEQ_CAPS_ELVSS_SET[] = {
0xB6,
0x98, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x55, 0x54,
0x20, 0x00, 0x08, 0x88, 0x8F, 0x0F, 0x02, 0x11, 0x11, 0x10
};
static const unsigned char SEQ_GAMMA_UPDATE[] = {
0xF7,
0x03
};
static const unsigned char SEQ_GAMMA_UPDATE_L[] = {
0xF7,
0x00
};
static const unsigned char SEQ_GAMMA_UPDATE_EA8064G[] = {
0xF7,
0x01
};
static const unsigned char SEQ_HBM_OFF[] = {
0x53,
0x00
};
static const unsigned char SEQ_HBM_ON[] = {
0x53,
0xD0
};
static const unsigned char SEQ_ACL_SET[] = {
0x55,
0x02
};
static const unsigned char SEQ_ACL_OFF[] = {
0x55,
0x00
};
static const unsigned char SEQ_ACL_15[] = {
0x55,
0x02,
};
static const unsigned char SEQ_ACL_OFF_OPR_AVR[] = {
0xB5,
0x21
};
static const unsigned char SEQ_ACL_ON_OPR_AVR[] = {
0xB5,
0x29
};
static const unsigned char SEQ_ACL_OFF_OPR_AVR_EA8064G[] = {
0xB5,
0x21
};
static const unsigned char SEQ_ACL_ON_OPR_AVR_EA8064G[] = {
0xB5,
0x29
};
static const unsigned char SEQ_TSET_GLOBAL[] = {
0xB0,
0x05
};
static const unsigned char SEQ_TSET[] = {
0xB8,
0x19
};
static const unsigned char SEQ_TE_OUT[] = {
0x35,
0x00
};
static const unsigned char SEQ_GPARAM_TE[] = {
0xB0,
0x02
};
static const unsigned char SEQ_TE_ON_SET1[] = {
0xFD,
0x0A
};
static const unsigned char SEQ_TE_ON_SET2[] = {
0xFE,
0x80
};
static const unsigned char SEQ_TE_ON_SET3[] = {
0xFE,
0x00
};
static const unsigned char SEQ_ERR_FG[] = {
0xED,
0x01, 0x00
};
static const unsigned char SEQ_DISPLAY_ON[] = {
0x29
};
static const unsigned char SEQ_DISPLAY_OFF[] = {
0x28,
0x00, 0x00
};
static const unsigned char SEQ_SLEEP_IN[] = {
0x10,
0x00, 0x00
};
static const unsigned char SEQ_TOUCH_HSYNC_ON_RevG[] = {
0xBD,
0x05, 0x02, 0x02
};
static const unsigned char SEQ_TOUCH_HSYNC_ON[] = {
0xBD,
0x05, 0x02, 0x0C
};
static const unsigned char SEQ_DCDC1_GP[] = {
0xB0,
0x01
};
static const unsigned char SEQ_DCDC1_SET[] = {
0xB8,
0x04,
};
static const unsigned char SEQ_BRIGHTNESS_1[] = {
0xca, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x0, 0x0, 0x0,
};
static const unsigned char SEQ_BRIGHTNESS_2[] = {
0xb2, 0x0, 0xe, 0x0, 0x10,
};
static const unsigned char SEQ_BRIGHTNESS_3[] = {
0xb6, 0x5c, 0x84, 0xb8, 0x13,
};
#endif /* __EA8064G_PARAM_H__ */

View file

@ -0,0 +1,23 @@
/* linux/drivers/video/decon_display/s6e3fa0_gamma.h
*
* Copyright (c) 2012 Samsung Electronics Co., Ltd.
*
* Haowe Li <haowei.li@samsung.com>
*
* 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.
*/
#ifndef __LCD_CTRL_H__
#define __LCD_CTRL_H__
#include "decon_lcd.h"
void lcd_init(struct decon_lcd *lcd);
void lcd_enable(void);
void lcd_disable(void);
int lcd_gamma_ctrl(unsigned int backlightlevel);
int lcd_gamma_update(void);
#endif /* __LCD_CTRL_H__ */

View file

@ -0,0 +1,164 @@
/* s6d78a_lcd_ctrl.c
*
* Samsung SoC MIPI LCD CONTROL functions
*
* Copyright (c) 2015 Samsung Electronics
*
* Manseok Kim, <Manseoks.kim@samsung.com>
*
* 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.
*/
#include "s6d78a_param.h"
#include "lcd_ctrl.h"
/* use FW_TEST definition when you test CAL on firmware */
/* #define FW_TEST */
#ifdef FW_TEST
#include "../dsim_fw.h"
#include "mipi_display.h"
#else
#include "../dsim.h"
#include <video/mipi_display.h>
#endif
#define VIDEO_MODE 1
#define ID 0
void lcd_init(struct decon_lcd * lcd)
{
/* Initializing Sequence(1-1) */
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) SEQ_INIT1_1,
ARRAY_SIZE(SEQ_INIT1_1)) == -1)
dsim_err("failed to send init_seq1_level_1_command.\n");
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) SEQ_INIT1_2,
ARRAY_SIZE(SEQ_INIT1_2)) == -1)
dsim_err("failed to send init_seq1_level_2_command.\n");
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) SEQ_INIT1_3,
ARRAY_SIZE(SEQ_INIT1_3)) == -1)
dsim_err("failed to send init_seq1_level_3_command.\n");
/* sleep out */
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) SEQ_SLEEP_OUT,
ARRAY_SIZE(SEQ_SLEEP_OUT)) == -1)
dsim_err("failed to send sleep_exit_command.\n");
/* 120ms delay */
msleep(120);
/* Initializing Sequence(3) */
#if 0
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) SEQ_INIT3_INT_CLK,
ARRAY_SIZE(SEQ_INIT3_INT_CLK)) == -1)
dsim_err("failed to send internal_clk_command.\n");
#endif
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) SEQ_INIT3_PAN_PROTECT,
ARRAY_SIZE(SEQ_INIT3_PAN_PROTECT)) == -1)
dsim_err("failed to send panel_protection_command.\n");
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) SEQ_INIT3_INT_POW,
ARRAY_SIZE(SEQ_INIT3_INT_POW)) == -1)
dsim_err("failed to send internal_power_seq_command.\n");
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) SEQ_INIT3_GOA,
ARRAY_SIZE(SEQ_INIT3_GOA)) == -1)
dsim_err("failed to send goa_timing_command.\n");
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) SEQ_INIT3_INT_PORCH,
ARRAY_SIZE(SEQ_INIT3_INT_PORCH)) == -1)
dsim_err("failed to send internal_porch_command.\n");
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) SEQ_INIT3_SRC_CONT,
ARRAY_SIZE(SEQ_INIT3_SRC_CONT)) == -1)
dsim_err("failed to send source_control_command.\n");
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) SEQ_INIT3_MIPI_ABNORMAL,
ARRAY_SIZE(SEQ_INIT3_MIPI_ABNORMAL)) == -1)
dsim_err("failed to send mipi_abnormal_detect_command.\n");
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) SEQ_INIT3_MIPI_AUTO_RECOVERY,
ARRAY_SIZE(SEQ_INIT3_MIPI_AUTO_RECOVERY)) == -1)
dsim_err("failed to send mipi_auto_recover_command.\n");
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) SEQ_INIT3_GOA_OUTPUT,
ARRAY_SIZE(SEQ_INIT3_GOA_OUTPUT)) == -1)
dsim_err("failed to send goa_output_command.\n");
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) SEQ_INIT3_MEM_ACC_CONT,
ARRAY_SIZE(SEQ_INIT3_MEM_ACC_CONT)) == -1)
dsim_err("failed to memory_data_access_command.\n");
/* Gamma Setting Sequence(4) */
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) SEQ_GAMMA_POSITIVE_CONT,
ARRAY_SIZE(SEQ_GAMMA_POSITIVE_CONT)) == -1)
dsim_err("failed to send positive_gama_control_command.\n");
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) SEQ_GAMMA_NEGATIVE_CONT,
ARRAY_SIZE(SEQ_GAMMA_NEGATIVE_CONT)) == -1)
dsim_err("failed to send negative_gama_control_command.\n");
/* display_on */
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) SEQ_DISPLAY_ON,
ARRAY_SIZE(SEQ_DISPLAY_ON)) == -1)
dsim_err("failed to display_on_command.\n");
/* 20ms delay */
msleep(20);
/* Initializing Sequence(2) */
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) SEQ_INIT2_1,
ARRAY_SIZE(SEQ_INIT2_1)) == -1)
dsim_err("failed to send init_seq2_level_1_command.\n");
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) SEQ_INIT2_2,
ARRAY_SIZE(SEQ_INIT2_2)) == -1)
dsim_err("failed to send init_seq2_level_2_command.\n");
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) SEQ_INIT2_3,
ARRAY_SIZE(SEQ_INIT2_3)) == -1)
dsim_err("failed to send init_seq2_level_3_command.\n");
}
void lcd_enable(void)
{
}
void lcd_disable(void)
{
}
int lcd_gamma_ctrl(u32 backlightlevel)
{
return 0;
}
int lcd_gamma_update(void)
{
return 0;
}

View file

@ -0,0 +1,211 @@
/* s6d78a_mipi_lcd.c
*
* Samsung SoC MIPI LCD driver.
*
* Copyright (c) 2015 Samsung Electronics
*
* Haowei Li, <haowei.li@samsung.com>
*
* 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.
*/
#include <linux/delay.h>
#include <linux/gpio.h>
#include <video/mipi_display.h>
#include <linux/platform_device.h>
#include "../dsim.h"
#include "lcd_ctrl.h"
#include "decon_lcd.h"
#include "s6d78a_param.h"
#define GAMMA_PARAM_SIZE 26
#define MAX_BRIGHTNESS 255
#define MIN_BRIGHTNESS 0
#define DEFAULT_BRIGHTNESS 0
static struct dsim_device *dsim_base;
struct backlight_device *bd;
#ifdef CONFIG_HAS_EARLYSUSPEND
static struct early_suspend s6d78a_early_suspend;
#endif
static int s6d78a_get_brightness(struct backlight_device *bd)
{
return bd->props.brightness;
}
static int get_backlight_level(int brightness)
{
int backlightlevel;
switch (brightness) {
case 0:
backlightlevel = 0;
break;
case 1 ... 29:
backlightlevel = 0;
break;
case 30 ... 34:
backlightlevel = 1;
break;
case 35 ... 39:
backlightlevel = 2;
break;
case 40 ... 44:
backlightlevel = 3;
break;
case 45 ... 49:
backlightlevel = 4;
break;
case 50 ... 54:
backlightlevel = 5;
break;
case 55 ... 64:
backlightlevel = 6;
break;
case 65 ... 74:
backlightlevel = 7;
break;
case 75 ... 83:
backlightlevel = 8;
break;
case 84 ... 93:
backlightlevel = 9;
break;
case 94 ... 103:
backlightlevel = 10;
break;
case 104 ... 113:
backlightlevel = 11;
break;
case 114 ... 122:
backlightlevel = 12;
break;
case 123 ... 132:
backlightlevel = 13;
break;
case 133 ... 142:
backlightlevel = 14;
break;
case 143 ... 152:
backlightlevel = 15;
break;
case 153 ... 162:
backlightlevel = 16;
break;
case 163 ... 171:
backlightlevel = 17;
break;
case 172 ... 181:
backlightlevel = 18;
break;
case 182 ... 191:
backlightlevel = 19;
break;
case 192 ... 201:
backlightlevel = 20;
break;
case 202 ... 210:
backlightlevel = 21;
break;
case 211 ... 220:
backlightlevel = 22;
break;
case 221 ... 230:
backlightlevel = 23;
break;
case 231 ... 240:
backlightlevel = 24;
break;
case 241 ... 250:
backlightlevel = 25;
break;
case 251 ... 255:
backlightlevel = 26;
break;
default:
backlightlevel = 12;
break;
}
return backlightlevel;
}
static int update_brightness(int brightness)
{
int backlightlevel;
backlightlevel = get_backlight_level(brightness);
/* Need to implement
if (s5p_mipi_dsi_wr_data(dsim_base, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int)gamma22_table[backlightlevel],
GAMMA_PARAM_SIZE) == -1)
printk(KERN_INFO "fail to write gamma value.\n");
if (s5p_mipi_dsi_wr_data(dsim_base, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int)gamma_update,
ARRAY_SIZE(gamma_update)) == -1)
printk(KERN_INFO "fail to update gamma value.\n");
*/
return 1;
}
static int s6d78a_set_brightness(struct backlight_device *bd)
{
int brightness = bd->props.brightness;
if (brightness < MIN_BRIGHTNESS || brightness > MAX_BRIGHTNESS) {
printk(KERN_ALERT "Brightness should be in the range of 0 ~ 255\n");
return -EINVAL;
}
update_brightness(brightness);
return 1;
}
static const struct backlight_ops s6d78a_backlight_ops = {
.get_brightness = s6d78a_get_brightness,
.update_status = s6d78a_set_brightness,
};
static int s6d78a_probe(struct dsim_device *dsim)
{
dsim_base = dsim;
bd = backlight_device_register("pwm-backlight.0", NULL,
NULL, &s6d78a_backlight_ops, NULL);
if (IS_ERR(bd))
printk(KERN_ALERT "failed to register backlight device!\n");
bd->props.max_brightness = MAX_BRIGHTNESS;
bd->props.brightness = DEFAULT_BRIGHTNESS;
return 1;
}
static int s6d78a_displayon(struct dsim_device *dsim)
{
lcd_init(&dsim->lcd_info);
return 1;
}
static int s6d78a_suspend(struct dsim_device *dsim)
{
return 1;
}
static int s6d78a_resume(struct dsim_device *dsim)
{
return 1;
}
struct mipi_dsim_lcd_driver s6d78a_mipi_lcd_driver = {
.probe = s6d78a_probe,
.displayon = s6d78a_displayon,
.suspend = s6d78a_suspend,
.resume = s6d78a_resume,
};

View file

@ -0,0 +1,185 @@
/* s6d78a_param.h
*
* Copyright (c) 2015 Samsung Electronics Co., Ltd.
*
* Manseok Kim, <Manseoks.kim@samsung.com>
*
* 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.
*/
#ifndef __S6D78A_PARAM_H__
#define __S6D78A_PARAM_H__
/* Initializing Sequence(1) - password */
static const unsigned char SEQ_INIT1_1[3] = {
/* command */
0xF0,
/* parameter */
0x5A, 0x5A
};
static const unsigned char SEQ_INIT1_2[3] = {
/* command */
0xF1,
/* parameter */
0x5A, 0x5A
};
static const unsigned char SEQ_INIT1_3[3] = {
/* command */
0xFC,
/* parameter */
0xA5, 0xA5
};
/* Initializing Sequence(2) - password */
static const unsigned char SEQ_INIT2_1[3] = {
/* command */
0xF0,
/* parameter */
0xA5, 0xA5
};
static const unsigned char SEQ_INIT2_2[3] = {
/* command */
0xF1,
/* parameter */
0xA5, 0xA5
};
static const unsigned char SEQ_INIT2_3[3] = {
/* command */
0xFC,
/* parameter */
0x5A, 0x5A
};
/* Initializing Sequence(3) */
static const unsigned char SEQ_INIT3_INT_CLK[3] = {
/* command */
0xB1,
/* parameter */
0x93, 0x00
};
static const unsigned char SEQ_INIT3_PAN_PROTECT[3] = {
/* command */
0xB5,
/* parameter */
0x10, 0x00
};
static const unsigned char SEQ_INIT3_INT_POW[18] = {
/* command */
0xF4,
/* parameter */
0x01, 0x10, 0x32, 0x00, 0x24,
0x26, 0x28, 0x27, 0x27, 0x27,
0xB7, 0x2B, 0x2C, 0x65, 0x6A,
0x34, 0x20
};
static const unsigned char SEQ_INIT3_GOA[21] = {
/* command */
0xEF,
/* parameter */
0x01, 0x01, 0x81, 0x22, 0x83,
0x04, 0x00, 0x00, 0x00, 0x00,
0x28, 0x81, 0x00, 0x21, 0x21,
0x03, 0x03, 0x40, 0x00, 0x10,
};
static const unsigned char SEQ_INIT3_INT_PORCH[9] = {
/* command */
0xF2,
/* parameter */
0x19, 0x04, 0x08, 0x08, 0x08,
0x14, 0x14, 0x00
};
static const unsigned char SEQ_INIT3_SRC_CONT[7] = {
/* command */
0xF6,
/* parameter */
0x93, 0x23, 0x15, 0x07, 0x07,
0x0C
};
static const unsigned char SEQ_INIT3_MIPI_ABNORMAL[7] = {
/* command */
0xE1,
/* parameter */
0x01, 0xFF, 0x01, 0x1B, 0x20,
0x17
};
static const unsigned char SEQ_INIT3_MIPI_AUTO_RECOVERY[4] = {
/* command */
0xE2,
/* parameter */
0xED, 0xC7, 0x23
};
static const unsigned char SEQ_INIT3_GOA_OUTPUT[39] = {
/* command */
0xF7,
/* parameter */
0x01, 0x01, 0x0A, 0x0B, 0x05,
0x1B, 0x1A, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x08, 0x09, 0x04, 0x1B,
0x1A, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x01
};
static const unsigned char SEQ_INIT3_MEM_ACC_CONT[3] = {
/* command */
0x36,
/* parameter */
0x10, 0x00
};
/* Gamma Setting Sequence(4) */
static const unsigned char SEQ_GAMMA_POSITIVE_CONT[40] = {
/* command */
0xFA,
/* parameter */
0x00, 0x19, 0x21, 0x1E, 0x14,
0x0B, 0x10, 0x0E, 0x09, 0x0B,
0x00, 0x00, 0x0A,
0x00, 0x1D, 0x21, 0x1E, 0x14,
0x0B, 0x10, 0x0E, 0x09, 0x0B,
0x00, 0x00, 0x0A,
0x00, 0x1C, 0x21, 0x1E, 0x14,
0x0B, 0x10, 0x0E, 0x09, 0x0B,
0x00, 0x00, 0x0A,
};
static const unsigned char SEQ_GAMMA_NEGATIVE_CONT[40] = {
/* command */
0xFB,
/* parameter */
0x07, 0x2D, 0x22, 0x24, 0x18,
0x0E, 0x11, 0x0C, 0x05, 0x05,
0x00, 0x00, 0x0A,
0x00, 0x29, 0x22, 0x24, 0x18,
0x0E, 0x11, 0x0C, 0x05, 0x05,
0x00, 0x00, 0x0A,
0x07, 0x2A, 0x22, 0x24, 0x18,
0x0E, 0x11, 0x0C, 0x05, 0x05,
0x00, 0x00, 0x0A,
};
static const unsigned char SEQ_SLEEP_OUT[3] = {
0x11, 0x00, 0x00
};
static const unsigned char SEQ_DISPLAY_ON[3] = {
0x29, 0x00, 0x00
};
#endif /* __S6D78A_PARAM_H__ */

View file

@ -0,0 +1,270 @@
/* linux/drivers/video/decon_display/s6e3fa0_gamma.h
*
* Copyright (c) 2012 Samsung Electronics Co., Ltd.
*
* Haowe Li <haowei.li@samsung.com>
*
* 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.
*/
#ifndef __S6E3FA0_GAMMA_H__
#define __S6E3FA0_GAMMA_H__
static const unsigned char gamma22_30[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xDF, 0x86, 0xF5,
0xD5, 0xC7, 0xCF, 0xDF, 0xE0, 0xE0,
0xC9, 0xC9, 0xCC, 0xD7, 0xD6, 0xD5,
0x00, 0x68, 0x00, 0x68, 0x00, 0x75,
};
static const unsigned char gamma22_40[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xE5, 0xAA, 0xF2,
0xD6, 0xCC, 0xCF, 0xE0, 0xE2, 0xE2,
0xC8, 0xC9, 0xCA, 0xD2, 0xD2, 0xCF,
0x00, 0x71, 0x00, 0x70, 0x00, 0x80,
};
static const unsigned char gamma22_50[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xE7, 0xBB, 0xEE,
0xD6, 0xCE, 0xD0, 0xE0, 0xE3, 0xE4,
0xC5, 0xC4, 0xC5, 0xD2, 0xD2, 0xCF,
0x00, 0x78, 0x00, 0x78, 0x00, 0x88,
};
static const unsigned char gamma22_60[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xE9, 0xC4, 0xEB,
0xD6, 0xD0, 0xD1, 0xE0, 0xE3, 0xE4,
0xC3, 0xC2, 0xC2, 0xD2, 0xD1, 0xCF,
0x00, 0x7E, 0x00, 0x7E, 0x00, 0x8F,
};
static const unsigned char gamma22_70[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xEA, 0xC9, 0xEA,
0xD6, 0xD2, 0xD2, 0xDF, 0xE1, 0xE3,
0xC2, 0xC1, 0xC0, 0xD1, 0xD0, 0xCE,
0x00, 0x84, 0x00, 0x84, 0x00, 0x96,
};
static const unsigned char gamma22_80[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xEB, 0xCC, 0xE9,
0xD5, 0xD4, 0xD3, 0xDE, 0xE1, 0xE2,
0xC2, 0xBF, 0xBF, 0xCF, 0xCF, 0xCC,
0x00, 0x89, 0x00, 0x89, 0x00, 0x9C,
};
static const unsigned char gamma22_90[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xEB, 0xD0, 0xE9,
0xD4, 0xD5, 0xD4, 0xDF, 0xE0, 0xE1,
0xC1, 0xBE, 0xBD, 0xCD, 0xCD, 0xCA,
0x00, 0x8E, 0x00, 0x8F, 0x00, 0xA2,
};
static const unsigned char gamma22_100[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xEA, 0xD2, 0xE7,
0xD7, 0xD6, 0xD6, 0xDF, 0xDF, 0xE2,
0xBF, 0xBD, 0xBC, 0xCD, 0xCD, 0xC9,
0x00, 0x92, 0x00, 0x93, 0x00, 0xA7,
};
static const unsigned char gamma22_110[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xEB, 0xD4, 0xE5,
0xD6, 0xD6, 0xD7, 0xDE, 0xDF, 0xE0,
0xBE, 0xBC, 0xBB, 0xCE, 0xCC, 0xC9,
0x00, 0x96, 0x00, 0x97, 0x00, 0xAC,
};
static const unsigned char gamma22_120[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xED, 0xD6, 0xE6,
0xD6, 0xD7, 0xD8, 0xDE, 0xDE, 0xE0,
0xBC, 0xBC, 0xB9, 0xCD, 0xCA, 0xC8,
0x00, 0x9A, 0x00, 0x9C, 0x00, 0xB1,
};
static const unsigned char gamma22_130[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xEC, 0xD7, 0xE6,
0xD3, 0xD8, 0xD7, 0xDE, 0xDD, 0xDF,
0xBD, 0xBB, 0xB8, 0xCA, 0xC9, 0xC6,
0x00, 0x9F, 0x00, 0xA0, 0x00, 0xB7,
};
static const unsigned char gamma22_140[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xEC, 0xD9, 0xE5,
0xD4, 0xD8, 0xD9, 0xDE, 0xDD, 0xDF,
0xBB, 0xB9, 0xB7, 0xCA, 0xC9, 0xC5,
0x00, 0xA3, 0x00, 0xA4, 0x00, 0xBB,
};
static const unsigned char gamma22_150[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xEC, 0xDA, 0xE5,
0xD4, 0xD8, 0xD9, 0xDD, 0xDD, 0xDD,
0xBB, 0xB9, 0xB6, 0xC9, 0xC7, 0xC5,
0x00, 0xA6, 0x00, 0xA8, 0x00, 0xBF,
};
static const unsigned char gamma22_160[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xED, 0xDB, 0xE6,
0xD4, 0xD7, 0xD9, 0xDC, 0xDD, 0xDD,
0xB9, 0xB8, 0xB4, 0xC9, 0xC6, 0xC4,
0x00, 0xAA, 0x00, 0xAC, 0x00, 0xC4,
};
static const unsigned char gamma22_170[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xEC, 0xDC, 0xE5,
0xD5, 0xD8, 0xD9, 0xDD, 0xDC, 0xDD,
0xBA, 0xB7, 0xB5, 0xC7, 0xC6, 0xC3,
0x00, 0xAD, 0x00, 0xAF, 0x00, 0xC7,
};
static const unsigned char gamma22_180[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xEE, 0xDD, 0xE6,
0xD4, 0xD7, 0xD9, 0xDB, 0xDC, 0xDB,
0xB9, 0xB7, 0xB4, 0xC6, 0xC4, 0xC2,
0x00, 0xB1, 0x00, 0xB3, 0x00, 0xCC,
};
static const unsigned char gamma22_190[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xED, 0xDE, 0xE6,
0xD3, 0xD8, 0xD8, 0xDD, 0xDB, 0xDC,
0xB9, 0xB6, 0xB4, 0xC5, 0xC4, 0xC0,
0x00, 0xB4, 0x00, 0xB6, 0x00, 0xD0,
};
static const unsigned char gamma22_200[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xED, 0xDF, 0xE6,
0xD3, 0xD7, 0xD8, 0xDB, 0xDB, 0xDA,
0xB8, 0xB6, 0xB3, 0xC4, 0xC3, 0xC0,
0x00, 0xB8, 0x00, 0xB9, 0x00, 0xD4,
};
static const unsigned char gamma22_210[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xEC, 0xE0, 0xE5,
0xD5, 0xD7, 0xD9, 0xDB, 0xDA, 0xDA,
0xB7, 0xB5, 0xB1, 0xC4, 0xC2, 0xC0,
0x00, 0xBA, 0x00, 0xBD, 0x00, 0xD7,
};
static const unsigned char gamma22_220[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xED, 0xE0, 0xE6,
0xD4, 0xD7, 0xD9, 0xDA, 0xDA, 0xD9,
0xB7, 0xB4, 0xB1, 0xC2, 0xC2, 0xBE,
0x00, 0xBE, 0x00, 0xC0, 0x00, 0xDC,
};
static const unsigned char gamma22_230[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xEC, 0xE2, 0xE6,
0xD3, 0xD6, 0xD8, 0xDC, 0xD9, 0xD9,
0xB6, 0xB4, 0xB1, 0xC1, 0xC1, 0xBD,
0x00, 0xC1, 0x00, 0xC3, 0x00, 0xDF,
};
static const unsigned char gamma22_240[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xED, 0xE2, 0xE6,
0xD4, 0xD6, 0xD8, 0xDA, 0xDA, 0xDA,
0xB6, 0xB3, 0xB0, 0xC1, 0xBF, 0xBC,
0x00, 0xC4, 0x00, 0xC7, 0x00, 0xE3,
};
static const unsigned char gamma22_250[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xED, 0xE3, 0xE7,
0xD4, 0xD6, 0xD8, 0xDB, 0xD9, 0xD9,
0xB3, 0xB2, 0xAE, 0xC1, 0xC0, 0xBC,
0x00, 0xC7, 0x00, 0xC9, 0x00, 0xE7,
};
static const unsigned char gamma22_260[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xED, 0xE4, 0xE7,
0xD4, 0xD5, 0xD7, 0xDA, 0xD9, 0xD9,
0xB3, 0xB2, 0xAD, 0xC1, 0xBE, 0xBC,
0x00, 0xC9, 0x00, 0xCD, 0x00, 0xEA,
};
static const unsigned char gamma22_270[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xED, 0xE5, 0xE8,
0xD3, 0xD5, 0xD5, 0xDB, 0xD9, 0xD9,
0xB3, 0xB1, 0xAE, 0xBF, 0xBE, 0xBA,
0x00, 0xCC, 0x00, 0xD0, 0x00, 0xEE,
};
static const unsigned char gamma22_280[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xEC, 0xE5, 0xE6,
0xD2, 0xD4, 0xD6, 0xDA, 0xD9, 0xD8,
0xB3, 0xB1, 0xAD, 0xBF, 0xBD, 0xBA,
0x00, 0xCF, 0x00, 0xD3, 0x00, 0xF1,
};
static const unsigned char gamma22_290[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xEC, 0xE6, 0xE7,
0xD2, 0xD4, 0xD5, 0xDB, 0xD8, 0xD8,
0xB1, 0xB0, 0xAC, 0xBE, 0xBD, 0xB9,
0x00, 0xD3, 0x00, 0xD6, 0x00, 0xF5,
};
static const unsigned char gamma22_300[] = {
0xFA, 0x01,
0x1F, 0x1F, 0x1F, 0xED, 0xE6, 0xE7,
0xD1, 0xD3, 0xD4, 0xDA, 0xD8, 0xD7,
0xB1, 0xAF, 0xAB, 0xBD, 0xBB, 0xB8,
0x00, 0xD6, 0x00, 0xDA, 0x00, 0xFA,
};
static const unsigned char *gamma22_table[] = {
gamma22_30,
gamma22_40,
gamma22_50,
gamma22_60,
gamma22_70,
gamma22_80,
gamma22_90,
gamma22_100,
gamma22_110,
gamma22_120,
gamma22_130,
gamma22_140,
gamma22_150,
gamma22_160,
gamma22_170,
gamma22_180,
gamma22_190,
gamma22_200,
gamma22_210,
gamma22_220,
gamma22_230,
gamma22_240,
gamma22_250,
gamma22_260,
gamma22_270,
gamma22_280,
gamma22_290,
};
#endif /* __S6E3FA0_GAMMA_H__ */

View file

@ -0,0 +1,237 @@
/* drivers/video/exynos/panels/s6e3fa0_lcd_ctrl.c
*
* Samsung SoC MIPI LCD CONTROL functions
*
* Copyright (c) 2014 Samsung Electronics
*
* Jiun Yu, <jiun.yu@samsung.com>
*
* 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.
*/
#include "s6e3fa0_gamma.h"
#include "s6e3fa0_param.h"
#include "lcd_ctrl.h"
/* use FW_TEST definition when you test CAL on firmware */
/* #define FW_TEST */
#ifdef FW_TEST
#include "../dsim_fw.h"
#include "mipi_display.h"
#else
#include "../dsim.h"
#include <video/mipi_display.h>
#endif
#define GAMMA_PARAM_SIZE 26
/* Porch values. It depends on command or video mode */
#define S6E3FA0_CMD_VBP 10
#define S6E3FA0_CMD_VFP 1
#define S6E3FA0_CMD_VSA 1
#define S6E3FA0_CMD_HBP 1
#define S6E3FA0_CMD_HFP 1
#define S6E3FA0_CMD_HSA 1
#define S6E3FA0_VIDEO_VBP 2
#define S6E3FA0_VIDEO_VFP 20
#define S6E3FA0_VIDEO_VSA 2
#define S6E3FA0_VIDEO_HBP 20
#define S6E3FA0_VIDEO_HFP 20
#define S6E3FA0_VIDEO_HSA 20
#define S6E3FA0_HORIZONTAL 1080
#define S6E3FA0_VERTICAL 1920
#ifdef FW_TEST /* This information is moved to DT */
#define CONFIG_FB_I80_COMMAND_MODE
struct decon_lcd s6e3fa0_lcd_info = {
#ifdef CONFIG_FB_I80_COMMAND_MODE
.mode = DECON_MIPI_COMMAND_MODE,
.vfp = S6E3FA0_CMD_VFP,
.vbp = S6E3FA0_CMD_VBP,
.hfp = S6E3FA0_CMD_HFP,
.hbp = S6E3FA0_CMD_HBP,
.vsa = S6E3FA0_CMD_VSA,
.hsa = S6E3FA0_CMD_HSA,
#else
.mode = DECON_VIDEO_MODE,
.vfp = S6E3FA0_VIDEO_VFP,
.vbp = S6E3FA0_VIDEO_VBP,
.hfp = S6E3FA0_VIDEO_HFP,
.hbp = S6E3FA0_VIDEO_HBP,
.vsa = S6E3FA0_VIDEO_VSA,
.hsa = S6E3FA0_VIDEO_HSA,
#endif
.xres = S6E3FA0_HORIZONTAL,
.yres = S6E3FA0_VERTICAL,
/* Maybe, width and height will be removed */
.width = 70,
.height = 121,
/* Mhz */
.hs_clk = 1100,
.esc_clk = 20,
.fps = 60,
.mic_enabled = 0,
.mic_ver = MIC_VER_1_2,
};
#endif
/*
* 3FAH0 lcd init sequence
*
* Parameters
* - mic : if mic is enabled, MIC_ENABLE command must be sent
* - mode : LCD init sequence depends on command or video mode
*/
void lcd_init(struct decon_lcd *lcd)
{
int id = 0;
if (dsim_wr_data(id, MIPI_DSI_DCS_LONG_WRITE,
(unsigned long)SEQ_TEST_KEY_ON_F0,
ARRAY_SIZE(SEQ_TEST_KEY_ON_F0)) < 0)
dsim_err("fail to send SEQ_TEST_KEY_ON_F0 command.\n");
msleep(12);
if (dsim_wr_data(id, MIPI_DSI_DCS_LONG_WRITE,
(unsigned long)SEQ_TEST_KEY_ON_F1,
ARRAY_SIZE(SEQ_TEST_KEY_ON_F1)) < 0)
dsim_err("fail to send SEQ_TEST_KEY_ON_F1 command.\n");
msleep(12);
if (dsim_wr_data(id, MIPI_DSI_DCS_LONG_WRITE,
(unsigned long)SEQ_TEST_KEY_ON_FC,
ARRAY_SIZE(SEQ_TEST_KEY_ON_FC)) < 0)
dsim_err("fail to send SEQ_TEST_KEY_ON_FC command.\n");
msleep(12);
if (dsim_wr_data(id, MIPI_DSI_DCS_LONG_WRITE,
(unsigned long)SEQ_TEST_KEY_ON_ED,
ARRAY_SIZE(SEQ_TEST_KEY_ON_ED)) < 0)
dsim_err("fail to send SEQ_TEST_KEY_ON_ED command.\n");
msleep(12);
if (lcd->mode == DECON_MIPI_COMMAND_MODE) {
if (dsim_wr_data(id, MIPI_DSI_DCS_LONG_WRITE,
(unsigned long)SEQ_TEST_KEY_ON_FD,
ARRAY_SIZE(SEQ_TEST_KEY_ON_FD)) < 0)
dsim_err(
"fail to send SEQ_TEST_KEY_ON_FD command.\n");
msleep(12);
if (dsim_wr_data(id, MIPI_DSI_DCS_SHORT_WRITE_PARAM,
SEQ_TEST_KEY_ON_F6[0],
SEQ_TEST_KEY_ON_F6[1]) < 0)
dsim_err(
"fail to send SEQ_TEST_KEY_ON_F6 command.\n");
mdelay(12);
} else {
if (dsim_wr_data(id, MIPI_DSI_DCS_LONG_WRITE,
(unsigned long)SEQ_TEST_KEY_ON_E7,
ARRAY_SIZE(SEQ_TEST_KEY_ON_E7)) < 0)
dsim_err(
"fail to send SEQ_TEST_KEY_ON_E7 command.\n");
msleep(120);
}
if (lcd->mic_enabled)
dsim_wr_data(id, MIPI_DSI_DCS_SHORT_WRITE_PARAM,
SEQ_MIC_ENABLE[0],
SEQ_MIC_ENABLE[1]);
if (dsim_wr_data(id, MIPI_DSI_DCS_SHORT_WRITE,
SEQ_SLEEP_OUT[0], 0) < 0)
dsim_err("fail to send SEQ_SLEEP_OUT command.\n");
mdelay(20);
if (lcd->mode == DECON_VIDEO_MODE) {
if (dsim_wr_data(id, MIPI_DSI_DCS_SHORT_WRITE,
SEQ_DISPLAY_ON[0], 0) < 0)
dsim_err("fail to send SEQ_DISPLAY_ON command.\n");
mdelay(120);
if (dsim_wr_data(id, MIPI_DSI_DCS_SHORT_WRITE_PARAM,
SEQ_TEST_KEY_ON_F2[0],
SEQ_TEST_KEY_ON_F2[1]) < 0)
dsim_err(
"fail to send SEQ_TEST_KEY_ON_F2 command.\n");
mdelay(12);
}
if (dsim_wr_data(id, MIPI_DSI_DCS_LONG_WRITE,
(unsigned long)SEQ_TEST_KEY_ON_EB,
ARRAY_SIZE(SEQ_TEST_KEY_ON_EB)) < 0)
dsim_err("fail to send SEQ_TEST_KEY_ON_EB command.\n");
mdelay(12);
if (dsim_wr_data(id, MIPI_DSI_DCS_LONG_WRITE,
(unsigned long)SEQ_TEST_KEY_ON_C0,
ARRAY_SIZE(SEQ_TEST_KEY_ON_C0)) < 0)
dsim_err("fail to send SEQ_TEST_KEY_ON_C0 command.\n");
mdelay(12);
if (lcd->mode == DECON_MIPI_COMMAND_MODE) {
if (dsim_wr_data(id, MIPI_DSI_DCS_SHORT_WRITE,
SEQ_TE_ON[0], 0) < 0)
dsim_err("fail to send SEQ_TE_ON command.\n");
mdelay(12);
}
}
void lcd_enable()
{
int id = 0;
if (dsim_wr_data(id, MIPI_DSI_DCS_SHORT_WRITE,
SEQ_DISPLAY_ON[0], 0) < 0)
dsim_err("fail to send SEQ_DISPLAY_ON command.\n");
}
void lcd_disable()
{
/* This function needs to implement */
}
/*
* Set gamma values
*
* Parameter
* - backlightlevel : It is from 0 to 26.
*/
int lcd_gamma_ctrl(u32 backlightlevel)
{
int id = 0;
int ret;
ret = dsim_wr_data(id, MIPI_DSI_DCS_LONG_WRITE,
(unsigned long)gamma22_table[backlightlevel],
GAMMA_PARAM_SIZE);
if (ret) {
dsim_err("fail to write gamma value.\n");
return ret;
}
return 0;
}
int lcd_gamma_update()
{
int id = 0;
int ret;
ret = dsim_wr_data(id, MIPI_DSI_DCS_LONG_WRITE,
(unsigned long)SEQ_GAMMA_UPDATE,
ARRAY_SIZE(SEQ_GAMMA_UPDATE));
if (ret) {
dsim_err("fail to update gamma value.\n");
return ret;
}
return 0;
}

View file

@ -0,0 +1,212 @@
/* drivers/video/exynos/panels/s6e3fa0_mipi_lcd.c
*
* Samsung SoC MIPI LCD driver.
*
* Copyright (c) 2014 Samsung Electronics
*
* Haowei Li, <haowei.li@samsung.com>
*
* 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.
*/
#include <linux/delay.h>
#include <linux/gpio.h>
#include <video/mipi_display.h>
#include <linux/platform_device.h>
#include "s6e3fa0_param.h"
#include "lcd_ctrl.h"
#include "decon_lcd.h"
#include "../dsim.h"
#define MAX_BRIGHTNESS 255
#define MIN_BRIGHTNESS 0
#define DEFAULT_BRIGHTNESS 0
static struct dsim_device *dsim_base;
static struct backlight_device *bd;
static int s6e3fa0_get_brightness(struct backlight_device *bd)
{
return bd->props.brightness;
}
static int get_backlight_level(int brightness)
{
int backlightlevel;
switch (brightness) {
case 0:
backlightlevel = 0;
break;
case 1 ... 29:
backlightlevel = 0;
break;
case 30 ... 34:
backlightlevel = 1;
break;
case 35 ... 39:
backlightlevel = 2;
break;
case 40 ... 44:
backlightlevel = 3;
break;
case 45 ... 49:
backlightlevel = 4;
break;
case 50 ... 54:
backlightlevel = 5;
break;
case 55 ... 64:
backlightlevel = 6;
break;
case 65 ... 74:
backlightlevel = 7;
break;
case 75 ... 83:
backlightlevel = 8;
break;
case 84 ... 93:
backlightlevel = 9;
break;
case 94 ... 103:
backlightlevel = 10;
break;
case 104 ... 113:
backlightlevel = 11;
break;
case 114 ... 122:
backlightlevel = 12;
break;
case 123 ... 132:
backlightlevel = 13;
break;
case 133 ... 142:
backlightlevel = 14;
break;
case 143 ... 152:
backlightlevel = 15;
break;
case 153 ... 162:
backlightlevel = 16;
break;
case 163 ... 171:
backlightlevel = 17;
break;
case 172 ... 181:
backlightlevel = 18;
break;
case 182 ... 191:
backlightlevel = 19;
break;
case 192 ... 201:
backlightlevel = 20;
break;
case 202 ... 210:
backlightlevel = 21;
break;
case 211 ... 220:
backlightlevel = 22;
break;
case 221 ... 230:
backlightlevel = 23;
break;
case 231 ... 240:
backlightlevel = 24;
break;
case 241 ... 250:
backlightlevel = 25;
break;
case 251 ... 255:
backlightlevel = 26;
break;
default:
backlightlevel = 12;
break;
}
return backlightlevel;
}
static int update_brightness(int brightness)
{
int backlightlevel;
backlightlevel = get_backlight_level(brightness);
/* Need to implemnt
while (s5p_mipi_dsi_wr_data(dsim_base, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int)gamma22_table[backlightlevel],
GAMMA_PARAM_SIZE) == -1)
printk(KERN_ERR "fail to write gamma value.\n");
while (s5p_mipi_dsi_wr_data(dsim_base, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int)SEQ_GAMMA_UPDATE,
ARRAY_SIZE(SEQ_GAMMA_UPDATE)) == -1)
printk(KERN_ERR "fail to update gamma value.\n");
*/
return 0;
}
static int s6e3fa0_set_brightness(struct backlight_device *bd)
{
int brightness = bd->props.brightness;
if (brightness < MIN_BRIGHTNESS || brightness > MAX_BRIGHTNESS) {
printk(
KERN_ALERT "Brightness should be in the range of 0 ~ 255\n"
);
return -EINVAL;
}
update_brightness(brightness);
return 1;
}
static const struct backlight_ops s6e3fa0_backlight_ops = {
.get_brightness = s6e3fa0_get_brightness,
.update_status = s6e3fa0_set_brightness,
};
static int s6e3fa0_probe(struct dsim_device *dsim)
{
char bl_name[SZ_64];
dsim_base = dsim;
snprintf(bl_name, SZ_64, "pwm-backlight.%d", dsim->id);
bd = backlight_device_register(bl_name, NULL,
NULL, &s6e3fa0_backlight_ops, NULL);
if (IS_ERR(bd))
printk(KERN_ALERT "failed to register backlight device!\n");
bd->props.max_brightness = MAX_BRIGHTNESS;
bd->props.brightness = DEFAULT_BRIGHTNESS;
return 1;
}
static int s6e3fa0_displayon(struct dsim_device *dsim)
{
lcd_init(&dsim->lcd_info);
lcd_enable();
return 1;
}
static int s6e3fa0_suspend(struct dsim_device *dsim)
{
return 1;
}
static int s6e3fa0_resume(struct dsim_device *dsim)
{
return 1;
}
struct mipi_dsim_lcd_driver s6e3fa0_mipi_lcd_driver = {
.probe = s6e3fa0_probe,
.displayon = s6e3fa0_displayon,
.suspend = s6e3fa0_suspend,
.resume = s6e3fa0_resume,
};

View file

@ -0,0 +1,188 @@
/* linux/drivers/video/decon_display/s6e3fa0_param.h
*
* Copyright (c) 2014 Samsung Electronics Co., Ltd.
*
* Jiun Yu <jiun.yu@samsung.com>
*
* 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.
*/
#ifndef __S6E3FA0_PARAM_H__
#define __S6E3FA0_PARAM_H__
/* MIPI commands list */
static const unsigned char SEQ_TEST_KEY_ON_C0[] = {
0xc0,
0x63, 0x02, 0x03, 0x32, 0xFF, 0x44, 0x44, 0xC0, 0x00, 0x40
};
static const unsigned char SEQ_TEST_KEY_ON_EB[] = {
0xeb,
0x01, 0x00
};
static const unsigned char SEQ_TEST_KEY_ON_F2[] = {
0xf2,
0x02,
};
static const unsigned char SEQ_MIC_ENABLE[] = {
0xf9,
0x2b
};
static const unsigned char SEQ_TEST_KEY_ON_E7[] = {
0xE7,
0xED, 0xC7, 0x23, 0x57, 0xA5
};
static const unsigned char SEQ_TEST_KEY_ON_F6[] = {
0xf6,
0x08
};
static const unsigned char SEQ_TEST_KEY_ON_FD[] = {
0xfd,
0x16, 0x80
};
static const unsigned char SEQ_TEST_KEY_ON_ED[] = {
0xed,
0x01, 0x00
};
static const unsigned char SEQ_READ_ID[] = {
0x04,
0x5A, 0x5A,
};
static const unsigned char SEQ_TEST_KEY_ON_F0[] = {
0xF0,
0x5A, 0x5A,
};
static const unsigned char SEQ_TEST_KEY_ON_F1[] = {
0xF1,
0x5A, 0x5A,
};
static const unsigned char SEQ_TEST_KEY_ON_FC[] = {
0xFC,
0x5A, 0x5A,
};
static const unsigned char SEQ_TEST_KEY_OFF_FC[] = {
0xFC,
0xA5, 0xA5,
};
static const unsigned char SEQ_GAMMA_CONTROL_SET_300CD[] = {
0xCA,
0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x00, 0x00, 0x00,
};
static const unsigned char SEQ_AOR_CONTROL[] = {
0xB2,
0x00, 0x06, 0x00, 0x06, 0x06, 0x06, 0x48, 0x18, 0x3F, 0xFF,
0xFF,
};
static const unsigned char SEQ_ELVSS_CONDITION_SET[] = {
0xB6,
0x88, 0x0A,
};
static const unsigned char SEQ_GAMMA_UPDATE[] = {
0xF7,
0x03, 0x00
};
static const unsigned char SEQ_SLEEP_OUT[] = {
0x11,
};
static const unsigned char SEQ_ACL_CONTROL[] = {
0xB5,
0x03, 0x98, 0x26, 0x36, 0x45,
};
static const unsigned char SEQ_ETC_PENTILE_SETTING[] = {
0xC0,
0x00, 0x02, 0x03, 0x32, 0xD8, 0x44, 0x44, 0xC0, 0x00, 0x48,
0x20, 0xD8,
};
static const unsigned char SEQ_GLOBAL_PARAM_SOURCE_AMP[] = {
0xB0,
0x24,
};
static const unsigned char SEQ_ETC_SOURCE_AMP[] = {
0xD7,
0xA5,
};
static const unsigned char SEQ_GLOBAL_PARAM_BIAS_CURRENT[] = {
0xB0,
0x1F,
};
static const unsigned char SEQ_ETC_BIAS_CURRENT[] = {
0xD7,
0x0A,
};
static const unsigned char SEQ_TE_ON[] = {
0x35,
};
static const unsigned char SEQ_DISPLAY_ON[] = {
0x29,
};
static const unsigned char SEQ_DISPLAY_OFF[] = {
0x28,
0x00, 0x00
};
static const unsigned char SEQ_SLEEP_IN[] = {
0x10,
0x00, 0x00
};
static const unsigned char SEQ_TOUCHKEY_OFF[] = {
0xFF,
0x00,
};
static const unsigned char SEQ_TOUCHKEY_ON[] = {
0xFF,
0x01,
};
static const unsigned char SEQ_ACL_OFF[] = {
0x55, 0x00,
0x00
};
static const unsigned char SEQ_ACL_40[] = {
0x55, 0x02,
0x00
};
static const unsigned char SEQ_ACL_40_RE_LOW[] = {
0x55, 0x02,
0x00
};
static const unsigned char SEQ_DISPCTL[] = {
0xF2,
0x02, 0x03, 0xC, 0xA0, 0x01, 0x48
};
#endif /* __S6E3FA0_PARAM_H__ */

View file

@ -0,0 +1,176 @@
/* s6e3ha2k_lcd_ctrl.c
*
* Samsung SoC MIPI LCD CONTROL functions
*
* Copyright (c) 2015 Samsung Electronics
*
* Manseok Kim, <Manseoks.kim@samsung.com>
*
* 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.
*/
#include "s6e8aa0_param.h"
#include "lcd_ctrl.h"
/* use FW_TEST definition when you test CAL on firmware */
/* #define FW_TEST */
#ifdef FW_TEST
#include "../dsim_fw.h"
#include "mipi_display.h"
#else
#include "../dsim.h"
#include <video/mipi_display.h>
#endif
#define VIDEO_MODE 1
#define COMMAND_MODE 0
#define ID 0
struct decon_lcd s6e8aa0_lcd_info = {
/* Only availaable VIDEO MODE */
.mode = VIDEO_MODE,
.vfp = 0x1,
.vbp = 0xD,
.hfp = 0x18,
.hbp = 0x18,
.vsa = 0x02,
.hsa = 0x02,
.xres = 800,
.yres = 1280,
.width = 71,
.height = 114,
/* Mhz */
.hs_clk = 480,
.esc_clk = 20,
.fps = 60,
};
struct decon_lcd *decon_get_lcd_info(void)
{
return &s6e8aa0_lcd_info;
}
void lcd_init(struct decon_lcd * lcd)
{
/*level1_command (to be added)*/
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) apply_level_1_key,
ARRAY_SIZE(apply_level_1_key)) == -1)
dsim_err("failed to send apply_level_1_key_command.\n");
/*level2_command*/
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) apply_level_2_key,
ARRAY_SIZE(apply_level_2_key)) == -1)
dsim_err("failed to send apply_level_2_key_command.\n");
/*sleep out */
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) sleep_out,
ARRAY_SIZE(sleep_out)) == -1)
dsim_err("failed to send sleep_out_command.\n");
/*5ms delay */
msleep(5);
/*panel_condition_set */
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) panel_condition_set,
ARRAY_SIZE(panel_condition_set)) == -1)
dsim_err("failed to send panel_condition_set_command.\n");
/*panel_condition_update */
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) panel_condition_update,
ARRAY_SIZE(panel_condition_update)) == -1)
dsim_err("failed to send panel_condition_update_command.\n");
/*gamma_condition_set */
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) gamma_condition_set,
ARRAY_SIZE(gamma_condition_set)) == -1)
dsim_err("failed to send gamma_condition_set_command.\n");
/*gamma_condition_update */
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) gamma_update,
ARRAY_SIZE(gamma_update)) == -1)
dsim_err("failed to send gamma_update_command.\n");
/*source control */
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) etc_set_source_ctrl,
ARRAY_SIZE(etc_set_source_ctrl)) == -1)
dsim_err("failed to etc_set_source_ctrl_command.\n");
/*pentile control */
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) etc_set_pentile_ctrl,
ARRAY_SIZE(etc_set_pentile_ctrl)) == -1)
dsim_err("failed to send etc_set_pentile_ctrl_command.\n");
/*nvm setting */
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) elvss_NVM_set,
ARRAY_SIZE(elvss_NVM_set)) == -1)
dsim_err("failed to send elvss_NVM_set_command.\n");
/*power control */
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) etc_set_power_ctrl,
ARRAY_SIZE(etc_set_power_ctrl)) == -1)
dsim_err("failed to send etc_set_power_ctrl_command.\n");
/*dynamic elvss control */
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) elvss_ctrl_set,
ARRAY_SIZE(elvss_ctrl_set)) == -1)
dsim_err("failed to send dyanmic_elvss_ctrl_set_command.\n");
/*acl control1 */
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) acl_ctrl1,
ARRAY_SIZE(acl_ctrl1)) == -1)
dsim_err("failed to send acl_ctrl1_command.\n");
/*acl control2 */
while(dsim_wr_data(ID, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int) acl_ctrl2,
ARRAY_SIZE(acl_ctrl2)) == -1)
dsim_err("failed to send acl_ctrl2_command.\n");
/* 120ms delay */
msleep(120);
/* display on */
dsim_wr_data(ID, MIPI_DSI_DCS_SHORT_WRITE,
0x29, 0);
}
void lcd_enable(void)
{
}
void lcd_disable(void)
{
}
int lcd_gamma_ctrl(u32 backlightlevel)
{
return 0;
}
int lcd_gamma_update(void)
{
return 0;
}

View file

@ -0,0 +1,211 @@
/* s6e8aa0_mipi_lcd.c
*
* Samsung SoC MIPI LCD driver.
*
* Copyright (c) 2015 Samsung Electronics
*
* Haowei Li, <haowei.li@samsung.com>
*
* 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.
*/
#include <linux/delay.h>
#include <linux/gpio.h>
#include <video/mipi_display.h>
#include <linux/platform_device.h>
#include "../dsim.h"
#include "lcd_ctrl.h"
#include "decon_lcd.h"
#include "s6e8aa0_param.h"
#define GAMMA_PARAM_SIZE 26
#define MAX_BRIGHTNESS 255
#define MIN_BRIGHTNESS 0
#define DEFAULT_BRIGHTNESS 0
static struct dsim_device *dsim_base;
struct backlight_device *bd;
#ifdef CONFIG_HAS_EARLYSUSPEND
static struct early_suspend s6e8aa0_early_suspend;
#endif
static int s6e8aa0_get_brightness(struct backlight_device *bd)
{
return bd->props.brightness;
}
static int get_backlight_level(int brightness)
{
int backlightlevel;
switch (brightness) {
case 0:
backlightlevel = 0;
break;
case 1 ... 29:
backlightlevel = 0;
break;
case 30 ... 34:
backlightlevel = 1;
break;
case 35 ... 39:
backlightlevel = 2;
break;
case 40 ... 44:
backlightlevel = 3;
break;
case 45 ... 49:
backlightlevel = 4;
break;
case 50 ... 54:
backlightlevel = 5;
break;
case 55 ... 64:
backlightlevel = 6;
break;
case 65 ... 74:
backlightlevel = 7;
break;
case 75 ... 83:
backlightlevel = 8;
break;
case 84 ... 93:
backlightlevel = 9;
break;
case 94 ... 103:
backlightlevel = 10;
break;
case 104 ... 113:
backlightlevel = 11;
break;
case 114 ... 122:
backlightlevel = 12;
break;
case 123 ... 132:
backlightlevel = 13;
break;
case 133 ... 142:
backlightlevel = 14;
break;
case 143 ... 152:
backlightlevel = 15;
break;
case 153 ... 162:
backlightlevel = 16;
break;
case 163 ... 171:
backlightlevel = 17;
break;
case 172 ... 181:
backlightlevel = 18;
break;
case 182 ... 191:
backlightlevel = 19;
break;
case 192 ... 201:
backlightlevel = 20;
break;
case 202 ... 210:
backlightlevel = 21;
break;
case 211 ... 220:
backlightlevel = 22;
break;
case 221 ... 230:
backlightlevel = 23;
break;
case 231 ... 240:
backlightlevel = 24;
break;
case 241 ... 250:
backlightlevel = 25;
break;
case 251 ... 255:
backlightlevel = 26;
break;
default:
backlightlevel = 12;
break;
}
return backlightlevel;
}
static int update_brightness(int brightness)
{
int backlightlevel;
backlightlevel = get_backlight_level(brightness);
/* Need to implement
if (s5p_mipi_dsi_wr_data(dsim_base, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int)gamma22_table[backlightlevel],
GAMMA_PARAM_SIZE) == -1)
printk(KERN_INFO "fail to write gamma value.\n");
if (s5p_mipi_dsi_wr_data(dsim_base, MIPI_DSI_DCS_LONG_WRITE,
(unsigned int)gamma_update,
ARRAY_SIZE(gamma_update)) == -1)
printk(KERN_INFO "fail to update gamma value.\n");
*/
return 1;
}
static int s6e8aa0_set_brightness(struct backlight_device *bd)
{
int brightness = bd->props.brightness;
if (brightness < MIN_BRIGHTNESS || brightness > MAX_BRIGHTNESS) {
printk(KERN_ALERT "Brightness should be in the range of 0 ~ 255\n");
return -EINVAL;
}
update_brightness(brightness);
return 1;
}
static const struct backlight_ops s6e8aa0_backlight_ops = {
.get_brightness = s6e8aa0_get_brightness,
.update_status = s6e8aa0_set_brightness,
};
static int s6e8aa0_probe(struct dsim_device *dsim)
{
dsim_base = dsim;
bd = backlight_device_register("pwm-backlight.0", NULL,
NULL, &s6e8aa0_backlight_ops, NULL);
if (IS_ERR(bd))
printk(KERN_ALERT "failed to register backlight device!\n");
bd->props.max_brightness = MAX_BRIGHTNESS;
bd->props.brightness = DEFAULT_BRIGHTNESS;
return 1;
}
static int s6e8aa0_displayon(struct dsim_device *dsim)
{
lcd_init(&dsim->lcd_info);
return 1;
}
static int s6e8aa0_suspend(struct dsim_device *dsim)
{
return 1;
}
static int s6e8aa0_resume(struct dsim_device *dsim)
{
return 1;
}
struct mipi_dsim_lcd_driver s6e8aa0_mipi_lcd_driver = {
.probe = s6e8aa0_probe,
.displayon = s6e8aa0_displayon,
.suspend = s6e8aa0_suspend,
.resume = s6e8aa0_resume,
};

View file

@ -0,0 +1,93 @@
/* s6e8aa0_param.h
*
* Copyright (c) 2015 Samsung Electronics Co., Ltd.
*
* Manseok Kim, <Manseoks.kim@samsung.com>
*
* 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.
*/
#ifndef __S6E8AA0_PARAM_H__
#define __S6E8AA0_PARAM_H__
static const unsigned char apply_level_1_key[3] = {
/* command */
0xF0,
/* parameter */
0x5A, 0x5A
};
static const unsigned char apply_level_2_key[3] = {
/* command */
0xf1,
/* parameter */
0x5a, 0x5a
};
static const unsigned char sleep_out[1] = {
0x11,
};
static const unsigned char panel_condition_set[39] = {
0xF8,
0x3D, 0x35, 0x00, 0x00, 0x00, 0x93, 0x00, 0x3C, 0x7D, 0x08,
0x27, 0x7D, 0x3F, 0x00, 0x00, 0x00, 0x20, 0x04, 0x08, 0x6E,
0x00, 0x00, 0x00, 0x02, 0x08, 0x08, 0x23, 0x23, 0xC0, 0xC8,
0x08, 0x48, 0xC1, 0x00, 0xC1, 0xFF, 0xFF, 0xC8
};
static const unsigned char panel_condition_update[4] = {
0xF2, 0x80, 0x03, 0x0D
};
static const unsigned char gamma_condition_set[26] = {
0xFA,
0x01, 0x46, 0x46, 0x46, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00,
0xBE, 0x00, 0xBE, 0x00, 0xBE
};
static const unsigned char gamma_update[2] = {
0xF7,0x03
};
static const unsigned char etc_set_source_ctrl[3] = {
0xF6,0x00, 0x02
};
static const unsigned char etc_set_pentile_ctrl[10] = {
0xB6,
0x0C, 0x02, 0x03, 0x32, 0xFF, 0x44, 0x44, 0xC0, 0x00
};
static const unsigned char elvss_NVM_set[15] = {
0xD9,
0x14, 0x40, 0x0C, 0xCB, 0xCE, 0x6E, 0xC4, 0x07, 0x40, 0x41,
0xCB, 0x00, 0x60, 0x19
};
static const unsigned char etc_set_power_ctrl[8] = {
0xF4,
0xCF, 0x0A, 0x12, 0x10, 0x1E, 0x33, 0x02
};
static const unsigned char elvss_ctrl_set[3] = {
0xB1, 0x04, 0x95
};
static const unsigned char acl_ctrl1[2] = {
0xC0, 0x01
};
static const unsigned char acl_ctrl2[28] = {
0x47, 0x53, 0x13, 0x53, 0x00,
0x00, 0x02, 0xCF, 0x00, 0x00,
0x04, 0xFF, 0x00, 0x00, 0x00,
0x00, 0x00, 0x01, 0x09, 0x10,
0x18, 0x1F, 0x27, 0x2E, 0x36,
0x3D, 0x45, 0x4C
};
#endif /* __S6E8AA0_PARAM_H__ */

View file

@ -0,0 +1,252 @@
/*
* drivers/video/fbdev/exynos/decon_7870/regs-decon.h
*
* Register definition file for Samsung DECON driver
*
* Copyright (c) 2015 Samsung Electronics
* Jiun Yu <jiun.yu@samsung.com>
* Shaik Ameer Basha <shaik.ameer@samsung.com>
*
* 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.
*/
#ifndef _REGS_DECON_H
#define _REGS_DECON_H
#define VIDCON0 0x0000
#define VIDCON0_SWRESET (1 << 28)
#define VIDCON0_DECON_STOP_STATUS (1 << 2)
#define VIDCON0_ENVID (1 << 1)
#define VIDCON0_ENVID_F (1 << 0)
#define VIDOUTCON0 0x0004
#define VIDOUTCON0_LCD_ON_F (0x1 << 24)
#define VIDOUTCON0_IF_MASK (0x1 << 23)
#define VIDOUTCON0_RGBIF_F (0x0 << 23)
#define VIDOUTCON0_I80IF_F (0x1 << 23)
#define VCLKCON0 0x0010
#define ECLK_IDLE_GATE_EN (1 << 12)
#define VCLKCON0_CLKVALUP (1 << 8)
#define VCLKCON0_VLCKFREE (1 << 0)
#define VCLKCON1 (0x0014)
#define VCLKCON2 (0x0018)
#define VCLKCON_CLKVAL_F(_v) ((_v) << 16)
#define VCLKCON_CLKVAL_F_MASK (0xff << 16)
#define SHADOWCON 0x0030
#define SHADOWCON_WIN_PROTECT(_win) (1 << (8 + (_win)))
#define SHADOWCON_AUTO_PROTECT (1 << 0)
#define WINCHMAP0 0x0040
#define WINCHMAP_MASK(_win) (0x7 << ((_win) * 4))
#define WINCHMAP_DMA(_v, _win) ((_v) << ((_win) * 4))
#define WINCHMAP0_W5CHMAP_F(_v) ((_v) << 20)
#define WINCHMAP0_W5CHMAP_F_MASK (0x7 << 20)
#define WINCHMAP0_W4CHMAP_F(_v) ((_v) << 16)
#define WINCHMAP0_W4CHMAP_F_MASK (0x7 << 16)
#define WINCHMAP0_W3CHMAP_F(_v) ((_v) << 12)
#define WINCHMAP0_W3CHMAP_F_MASK (0x7 << 12)
#define WINCHMAP0_W2CHMAP_F(_v) ((_v) << 8)
#define WINCHMAP0_W2CHMAP_F_MASK (0x7 << 8)
#define WINCHMAP0_W1CHMAP_F(_v) ((_v) << 4)
#define WINCHMAP0_W1CHMAP_F_MASK (0x7 << 4)
#define WINCHMAP0_W0CHMAP_F(_v) ((_v) << 0)
#define WINCHMAP0_W0CHMAP_F_MASK (0x7 << 0)
#define WINCON(_win) (0x0050 + ((_win) * 4))
#define WINCON_RESET_VALUE (0x0001E000)
#define WINCON_RGB_TYPE_BT601W (0 << 26)
#define WINCON_RGB_TYPE_BT601N (1 << 26)
#define WINCON_RGB_TYPE_BT709W (2 << 26)
#define WINCON_RGB_TYPE_BT709N (3 << 26)
#define WINCON_BLK_EN_F (1 << 23)
#define WINCON_OUTSTAND_MAX_DEFAULT (0xF)
#define WINCON_OUTSTAND_MAX_POS (13)
#define WINCON_OUTSTAND_MAX_MASK (0x1F << 13)
#define WINCON_BURSTLEN_16WORD (0x0 << 10)
#define WINCON_BURSTLEN_8WORD (0x1 << 10)
#define WINCON_BURSTLEN_4WORD (0x2 << 10)
#define WINCON_INTERPOLATION_EN (1 << 9)
#define WINCON_BLD_PLANE (0 << 8)
#define WINCON_BLD_PIX (1 << 8)
#define WINCON_ALPHA_MUL (1 << 7)
#define WINCON_BPPMODE_ARGB8888 (0x0 << 2)
#define WINCON_BPPMODE_ABGR8888 (0x1 << 2)
#define WINCON_BPPMODE_RGBA8888 (0x2 << 2)
#define WINCON_BPPMODE_BGRA8888 (0x3 << 2)
#define WINCON_BPPMODE_XRGB8888 (0x4 << 2)
#define WINCON_BPPMODE_XBGR8888 (0x5 << 2)
#define WINCON_BPPMODE_RGBX8888 (0x6 << 2)
#define WINCON_BPPMODE_BGRX8888 (0x7 << 2)
#define WINCON_BPPMODE_RGB565 (0x8 << 2)
/*
* Todo: both formats are working but if 0x18 is passed for NV21
* and 0x19 is passed as NV12. This information is reversed in
* user manual. Need to check with Hardware team.
*/
#define WINCON_BPPMODE_NV21 (0x18 << 2)
#define WINCON_BPPMODE_NV12 (0x19 << 2)
#define WINCON_ALPHA_SEL (1 << 1)
#define WINCON_ENWIN (1 << 0)
#define VIDW_ADD0(_win) (0x0880 + ((_win) * 0x10))
#define VIDW_ADD2(_win) (0x1020 + ((_win) * 0x20))
#define VIDW_ADD3(_win) (0x1030 + ((_win) * 0x20))
#define VIDW_WHOLE_X(_win) (0x0130 + ((_win) * 8))
#define VIDW_WHOLE_Y(_win) (0x0134 + ((_win) * 8))
#define VIDW_OFFSET_X(_win) (0x0170 + ((_win) * 8))
#define VIDW_OFFSET_Y(_win) (0x0174 + ((_win) * 8))
#define VIDW_BLKOFFSET(_win) (0x01B0 + ((_win) * 4))
#define VIDW_BLKSIZE(_win) (0x0200 + ((_win) * 4))
#define VIDW_BLKOFFSET_Y_F(_v) (((_v) & 0x1fff) << 13)
#define VIDW_BLKOFFSET_X_F(_v) ((_v) & 0x1fff)
#define VIDW_BLKOFFSET_MASK (0x3ffffff)
#define VIDW_BLKSIZE_MASK (0x3ffffff)
#define VIDW_BLKSIZE_H_F(_v) (((_v) & 0x1fff) << 13)
#define VIDW_BLKSIZE_W_F(_v) ((_v) & 0x1fff)
#define VIDOSD_A(_win) (0x0230 + ((_win) * 0x20))
#define VIDOSD_A_TOPLEFT_X(_v) (((_v) & 0x1fff) << 13)
#define VIDOSD_A_TOPLEFT_Y(_v) (((_v) & 0x1fff) << 0)
#define VIDOSD_B(_win) (0x0234 + ((_win) * 0x20))
#define VIDOSD_B_BOTRIGHT_X(_v) (((_v) & 0x1fff) << 13)
#define VIDOSD_B_BOTRIGHT_Y(_v) (((_v) & 0x1fff) << 0)
#define VIDOSD_C(_win) (0x0238 + ((_win) * 0x20))
#define VIDOSD_C_ALPHA0_R_F(_v) (((_v) & 0xFF) << 16)
#define VIDOSD_C_ALPHA0_G_F(_v) (((_v) & 0xFF) << 8)
#define VIDOSD_C_ALPHA0_B_F(_v) (((_v) & 0xFF) << 0)
#define VIDOSD_D(_win) (0x023C + ((_win) * 0x20))
#define VIDOSD_D_ALPHA1_R_F(_v) (((_v) & 0xFF) << 16)
#define VIDOSD_D_ALPHA1_G_F(_v) (((_v) & 0xFF) << 8)
#define VIDOSD_D_ALPHA1_B_F(_v) (((_v) & 0xFF) >> 0)
#define WIN_MAP(_win) (0x0340 + ((_win) * 4))
#define WIN_MAP_MAP (1 << 24)
#define WIN_MAP_MAP_COLOUR(_v) ((_v) << 0)
#define WIN_MAP_MAP_COLOUR_MASK (0xffffff << 0)
#define W_KEYCON0(_win) (0x0370 + ((_win) * 8))
#define W_KEYCON1(_win) (0x0374 + ((_win) * 8))
#define W_KEYALPHA(_win) (0x03A0 + ((_win) * 4))
#define BLENDE(_win) (0x03C0 + ((_win) * 4))
#define BLENDE_COEF_ZERO 0x0
#define BLENDE_COEF_ONE 0x1
#define BLENDE_COEF_ALPHA_A 0x2
#define BLENDE_COEF_ONE_MINUS_ALPHA_A 0x3
#define BLENDE_COEF_ALPHA_B 0x4
#define BLENDE_COEF_ONE_MINUS_ALPHA_B 0x5
#define BLENDE_COEF_ALPHA0 0x6
#define BLENDE_COEF_A 0xA
#define BLENDE_COEF_ONE_MINUS_A 0xB
#define BLENDE_COEF_B 0xC
#define BLENDE_COEF_ONE_MINUS_B 0xD
#define BLENDE_Q_FUNC(_v) ((_v) << 18)
#define BLENDE_P_FUNC(_v) ((_v) << 12)
#define BLENDE_B_FUNC(_v) ((_v) << 6)
#define BLENDE_A_FUNC(_v) ((_v) << 0)
#define BLENDCON 0x03D8
#define BLENDCON_NEW_8BIT_ALPHA_VALUE (1 << 0)
#define BLENDCON_NEW_4BIT_ALPHA_VALUE (0 << 0)
#define VIDINTCON0 0x0500
#define VIDINTCON0_INT_EXTRA_EN (1 << 21)
#define VIDINTCON0_INT_I80_EN (1 << 17)
#define VIDINTCON0_FRAMESEL0_BACKPORCH (0x0 << 15)
#define VIDINTCON0_FRAMESEL0_VSYNC (0x1 << 15)
#define VIDINTCON0_FRAMESEL0_ACTIVE (0x2 << 15)
#define VIDINTCON0_FRAMESEL0_FRONTPORCH (0x3 << 15)
#define VIDINTCON0_INT_FRAME (1 << 11)
#define VIDINTCON0_FIFOLEVEL_EMPTY (0x0 << 3)
#define VIDINTCON0_FIFOLEVEL_TO25PC (0x1 << 3)
#define VIDINTCON0_FIFOLEVEL_TO50PC (0x2 << 3)
#define VIDINTCON0_FIFOLEVEL_FULL (0x4 << 3)
#define VIDINTCON0_INT_FIFO (1 << 1)
#define VIDINTCON0_INT_ENABLE (1 << 0)
#define VIDINTCON1 0x0504
#define VIDINTCON1_FIFOEP_TH_SHIFT 10
#define VIDINTCON1_INT_DPU1 (1 << 5)
#define VIDINTCON1_INT_DPU0 (1 << 4)
#define VIDINTCON1_INT_EXTRA (1 << 3)
#define VIDINTCON1_INT_I80 (1 << 2)
#define VIDINTCON1_INT_FRAME (1 << 1)
#define VIDINTCON1_INT_FIFO (1 << 0)
#define FRAMEFIFO_REG7 0x052C
#define FRAMEFIFO_FIFO0_VALID_SIZE_GET(_v) (((_v) >> 13) & 0x1fff)
#define VIDCON1(_x) (0x0600 + ((_x) * 0x50))
#define VIDCON1_LINECNT_GET(_v) (((_v) >> 17) & 0x1fff)
#define VIDCON1_VSTATUS_MASK (0x7 << 13)
#define VIDCON1_VSTATUS_IDLE (0x0 << 13)
#define VIDCON1_VSTATUS_VSYNC (0x1 << 13)
#define VIDCON1_VSTATUS_BACKPORCH (0x2 << 13)
#define VIDCON1_VSTATUS_ACTIVE (0x3 << 13)
#define VIDCON1_VSTATUS_FRONTPORCH (0x4 << 13)
#define VIDCON1_VCLK_MASK (0x3 << 9)
#define VIDCON1_VCLK_HOLD (0x0 << 9)
#define VIDCON1_VCLK_RUN (0x1 << 9)
#define VIDCON1_VCLK_RUN_VDEN_DISABLE (0x3 << 9)
#define VIDCON1_RGB_ORDER_O_MASK (0x7 << 4)
#define VIDCON1_RGB_ORDER_O_RGB (0x0 << 4)
#define VIDCON1_RGB_ORDER_O_GBR (0x1 << 4)
#define VIDCON1_RGB_ORDER_O_BRG (0x2 << 4)
#define VIDCON1_RGB_ORDER_O_BGR (0x4 << 4)
#define VIDCON1_RGB_ORDER_O_RBG (0x5 << 4)
#define VIDCON1_RGB_ORDER_O_GRB (0x6 << 4)
#define VIDTCON0(_x) (0x0610 + ((_x) * 0x50))
#define VIDTCON0_VBPD(_v) ((_v) << 16)
#define VIDTCON0_VFPD(_v) ((_v) << 0)
#define VIDTCON1(_x) (0x0614 + ((_x) * 0x50))
#define VIDTCON1_VSPW(_v) ((_v) << 16)
#define VIDTCON2(_x) (0x0618 + ((_x) * 0x50))
#define VIDTCON2_HBPD(_v) ((_v) << 16)
#define VIDTCON2_HFPD(_v) ((_v) << 0)
#define VIDTCON3(_x) (0x061C + ((_x) * 0x50))
#define VIDTCON3_HSPW(_v) ((_v) << 16)
#define VIDTCON4(_x) (0x0620 + ((_x) * 0x50))
#define VIDTCON4_LINEVAL(_v) (((_v) & 0x1fff) << 16)
#define VIDTCON4_HOZVAL(_v) (((_v) & 0x1fff) << 0)
#define VIDTCONx_LINEVAL_GET(_v) (((_v) >> 16) & 0x1fff)
#define VIDTCONx_HOZVAL_GET(_v) (((_v) >> 0) & 0x1fff)
#define LINECNT_OP_THRESHOLD(_x) (0x0630 + ((_x) * 0x50))
#define TRIGCON 0x06B0
#define TRIGCON_TRIG_SAVE_DISABLE_SYNCMGR (1 << 13)
#define TRIGCON_HWTRIG_AUTO_MASK (1 << 6)
#define TRIGCON_HWTRIGMASK_DISPIF0 (1 << 4)
#define TRIGCON_HWTRIGEN_I80_RGB (1 << 3)
#define TRIGCON_HWTRIG_INV_I80_RGB (1 << 2)
#define TRIGCON_SWTRIGCMD_I80_RGB (1 << 1)
#define TRIGCON_SWTRIGEN_I80_RGB (1 << 0)
#define CRCRDATA_E 0x06C0
#define CRCRDATA_V 0x06C4
#define CRCCTRL 0x06C8
#define CRCCTRL_CRCCLKEN (0x1 << 2)
#define CRCCTRL_CRCSTART_F (0x1 << 1)
#define CRCCTRL_CRCEN (0x1 << 0)
#define DECON_UPDATE 0x0710
#define DECON_UPDATE_STANDALONE_F (1 << 0)
/* TBD: Registers for Debugging features to be added */
#endif /* _REGS_DECON_H */

View file

@ -0,0 +1,304 @@
/* regs-dsim.h
*
* Register definition file for Samsung MIPI-DSIM driver
*
* Copyright (c) 2015 Samsung Electronics
* Jiun Yu <jiun.yu@samsung.com>
* Seuni Park <seuni.park@samsung.com>
* Shaik Ameer Basha <shaik.ameer@samsung.com>
*
* 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.
*/
#ifndef _REGS_DSIM_H
#define _REGS_DSIM_H
#define DSIM_LINK_STATUS (0x4)
#define DSIM_STATUS_PLL_STABLE (1 << 24)
#define DSIM_DPHY_STATUS (0x8)
#define DSIM_STATUS_STOP_STATE_DAT(_x) (((_x) & 0xf) << 0)
#define DSIM_STATUS_ULPS_DAT(_x) (((_x) & 0xf) << 4)
#define DSIM_STATUS_STOP_STATE_CLK (1 << 8)
#define DSIM_STATUS_ULPS_CLK (1 << 9)
#define DSIM_STATUS_TX_READY_HS_CLK (1 << 10)
#define DSIM_STATUS_ULPS_DATA_LANE_GET(x) (((x) >> 4) & 0xf)
#define DSIM_SWRST (0xc)
#define DSIM_SWRST_FUNCRST (1 << 16)
#define DSIM_DPHY_RST (1 << 8)
#define DSIM_SWRST_RESET (1 << 0)
#define DSIM_CLKCTRL (0x10)
#define DSIM_CLKCTRL_TX_REQUEST_HSCLK (1 << 20)
#define DSIM_CLKCTRL_BYTECLK_EN (1 << 17)
#define DSIM_CLKCTRL_ESCCLK_EN (1 << 16)
#define DSIM_CLKCTRL_LANE_ESCCLK_EN_MASK (0x1f << 8)
#define DSIM_CLKCTRL_LANE_ESCCLK_EN(_x) ((_x) << 8)
#define DSIM_CLKCTRL_ESC_PRESCALER(_x) ((_x) << 0)
#define DSIM_CLKCTRL_ESC_PRESCALER_MASK (0xffff << 0)
/* Time out register */
#define DSIM_TIMEOUT0 (0x14)
#define DSIM_TIMEOUT_BTA_TOUT(_x) ((_x) << 16)
#define DSIM_TIMEOUT_BTA_TOUT_MASK (0xff << 16)
#define DSIM_TIMEOUT_LPDR_TOUT(_x) ((_x) << 0)
#define DSIM_TIMEOUT_LPDR_TOUT_MASK (0xffff << 0)
/* Time out register */
#define DSIM_TIMEOUT1 (0x18)
#define DSIM_TIMEOUT_HSYNC_TOUT(_x) ((_x) << 0)
#define DSIM_TIMEOUT_HSYNC_TOUT_MASK (0xff << 0)
/* Escape mode register */
#define DSIM_ESCMODE (0x1c)
#define DSIM_ESCMODE_STOP_STATE_CNT(_x) ((_x) << 21)
#define DSIM_ESCMODE_STOP_STATE_CNT_MASK (0x7ff << 21)
#define DSIM_ESCMODE_FORCE_STOP_STATE (1 << 20)
#define DSIM_ESCMODE_FORCE_BTA (1 << 16)
#define DSIM_ESCMODE_CMD_LPDT (1 << 7)
#define DSIM_ESCMODE_TRIGGER_RST (1 << 4)
#define DSIM_ESCMODE_TX_ULPS_DATA (1 << 3)
#define DSIM_ESCMODE_TX_ULPS_DATA_EXIT (1 << 2)
#define DSIM_ESCMODE_TX_ULPS_CLK (1 << 1)
#define DSIM_ESCMODE_TX_ULPS_CLK_EXIT (1 << 0)
/* Display image resolution register */
#define DSIM_RESOL (0x20)
#define DSIM_RESOL_VRESOL(x) (((x) & 0xfff) << 16)
#define DSIM_RESOL_VRESOL_MASK (0xfff << 16)
#define DSIM_RESOL_HRESOL(x) (((x) & 0Xfff) << 0)
#define DSIM_RESOL_HRESOL_MASK (0xfff << 0)
#define DSIM_RESOL_LINEVAL_GET(_v) (((_v) >> 16) & 0xfff)
#define DSIM_RESOL_HOZVAL_GET(_v) (((_v) >> 0) & 0xfff)
/* Main display Vporch register */
#define DSIM_VPORCH (0x24)
#define DSIM_VPORCH_CMD_ALLOW(_x) ((_x) << 28)
#define DSIM_VPORCH_CMD_ALLOW_MASK (0xf << 28)
#define DSIM_VPORCH_STABLE_VFP(_x) ((_x) << 16)
#define DSIM_VPORCH_STABLE_VFP_MASK (0x7ff << 16)
#define DSIM_VPORCH_VBP(_x) ((_x) << 0)
#define DSIM_VPORCH_VBP_MASK (0x7ff << 0)
/* Main display Hporch register */
#define DSIM_HPORCH (0x28)
#define DSIM_HPORCH_HFP(_x) ((_x) << 16)
#define DSIM_HPORCH_HFP_MASK (0xffff << 16)
#define DSIM_HPORCH_HBP(_x) ((_x) << 0)
#define DSIM_HPORCH_HBP_MASK (0xffff << 0)
/* Main display sync area register */
#define DSIM_SYNC (0x2C)
#define DSIM_SYNC_VSA(_x) ((_x) << 16)
#define DSIM_SYNC_VSA_MASK (0x7ff << 16)
#define DSIM_SYNC_HSA(_x) ((_x) << 0)
#define DSIM_SYNC_HSA_MASK (0xffff << 0)
/* Configuration register */
#define DSIM_CONFIG (0x30)
#define DSIM_CONFIG_NONCONTINUOUS_CLOCK_LANE (1 << 31)
#define DSIM_CONFIG_CLKLANE_STOP_START (1 << 30)
#define DSIM_CONFIG_FLUSH_VS (1 << 29)
#define DSIM_CONFIG_SYNC_INFORM (1 << 27)
#define DSIM_CONFIG_BURST_MODE (1 << 26)
#define DSIM_CONFIG_HSYNC_PRESERVE (1 << 25)
#define DSIM_CONFIG_HSE_DISABLE (1 << 23)
#define DSIM_CONFIG_HFP_DISABLE (1 << 22)
#define DSIM_CONFIG_HBP_DISABLE (1 << 21)
#define DSIM_CONFIG_HSA_DISABLE (1 << 20)
#define DSIM_CONFIG_CPRS_EN (1 << 19)
#define DSIM_CONFIG_VIDEO_MODE (1 << 18)
#define DSIM_CONFIG_VC_CONTROL (1 << 17)
#define DSIM_CONFIG_VC_ID(_x) ((_x) << 16)
#define DSIM_CONFIG_VC_ID_MASK (0x3 << 16)
#define DSIM_CONFIG_PIXEL_FORMAT(_x) ((_x) << 12)
#define DSIM_CONFIG_PIXEL_FORMAT_MASK (0x7 << 12)
#define DSIM_CONFIG_MULTI_PIX (1 << 11)
#define DSIM_CONFIG_Q_CHANNEL_EN (1 << 10)
#define DSIM_CONFIG_PER_FRAME_READ_EN (1 << 9)
#define DSIM_CONFIG_NUM_OF_DATA_LANE(_x) ((_x) << 5)
#define DSIM_CONFIG_NUM_OF_DATA_LANE_MASK (0x3 << 5)
#define DSIM_CONFIG_LANES_EN(_x) (((_x) & 0x1f) << 0)
/* Interrupt source register */
#define DSIM_INTSRC (0x34)
#define DSIM_INTSRC_PLL_STABLE (1 << 31)
#define DSIM_INTSRC_SW_RST_RELEASE (1 << 30)
#define DSIM_INTSRC_SFR_PL_FIFO_EMPTY (1 << 29)
#define DSIM_INTSRC_SFR_PH_FIFO_EMPTY (1 << 28)
#define DSIM_INTSRC_SFR_PH_FIFO_OVERFLOW (1 << 26)
#define DSIM_INTSRC_BUS_TURN_OVER (1 << 25)
#define DSIM_INTSRC_FRAME_DONE (1 << 24)
#define DSIM_INTSRC_ABNRMAL_CMD_ST (1 << 22)
#define DSIM_INTSRC_LPDR_TOUT (1 << 21)
#define DSIM_INTSRC_BTA_TOUT (1 << 20)
#define DSIM_INTSRC_HSYNC_TOUT (1 << 19)
#define DSIM_INTSRC_RX_DATA_DONE (1 << 18)
#define DSIM_INTSRC_ERR_RX_ECC (1 << 15)
/* Interrupt mask register */
#define DSIM_INTMSK (0x38)
#define DSIM_INTMSK_PLL_STABLE (1 << 31)
#define DSIM_INTSRC_SW_RST_RELEASE (1 << 30)
#define DSIM_INTMSK_SFR_PL_FIFO_EMPTY (1 << 29)
#define DSIM_INTMSK_SFR_PH_FIFO_EMPTY (1 << 28)
#define DSIM_INTMSK_SFR_PH_FIFO_OVERFLOW (1 << 26)
#define DSIM_INTMSK_BUS_TURN_OVER (1 << 25)
#define DSIM_INTMSK_FRAME_DONE (1 << 24)
#define DSIM_INTMSK_ABNORMAL_CMD_ST (1 << 22)
#define DSIM_INTMSK_LPDR_TOUT (1 << 21)
#define DSIM_INTMSK_BTA_TOUT (1 << 20)
#define DSIM_INTMSK_HSYNC_TOUT (1 << 19)
#define DSIM_INTMSK_RX_DATA_DONE (1 << 18)
#define DSIM_INTMSK_ERR_RX_ECC (1 << 15)
/* Packet Header FIFO register */
#define DSIM_PKTHDR (0x3c)
#define DSIM_PKTHDR_ID(_x) ((_x) << 0)
#define DSIM_PKTHDR_DATA0(_x) ((_x) << 8)
#define DSIM_PKTHDR_DATA1(_x) ((_x) << 16)
/* Payload FIFO register */
#define DSIM_PAYLOAD (0x40)
/* Read FIFO register */
#define DSIM_RXFIFO (0x44)
/* SFR control Register for Stanby & Shadow*/
#define DSIM_SFR_CTRL (0x48)
#define DSIM_SFR_CTRL_STANDBY (1 << 4)
#define DSIM_SFR_CTRL_SHADOW_UPDATE (1 << 1)
#define DSIM_SFR_CTRL_SHADOW_EN (1 << 0)
/* FIFO status and control register */
#define DSIM_FIFOCTRL (0x4C)
#define DSIM_FIFOCTRL_NUMBER_OF_PH_SFR(_x) (((_x) & 0x3f) << 16)
#define DSIM_FIFOCTRL_EMPTY_RX (1 << 12)
#define DSIM_FIFOCTRL_FULL_PH_SFR (1 << 11)
#define DSIM_FIFOCTRL_FULL_PL_SFR (1 << 9)
#define DSIM_FIFOCTRL_INIT_RX (1 << 2)
#define DSIM_FIFOCTRL_INIT_SFR (1 << 1)
/* Muli slice setting register*/
#define DSIM_CPRS_CTRL (0x58)
#define DSIM_CPRS_CTRL_MULI_SLICE_PACKET (1 << 3)
#define DSIM_CPRS_CTRL_NUM_OF_SLICE(_x) ((_x) << 0)
#define DSIM_CPRS_CTRL_NUM_OF_SLICE_MASK (0x7 << 0)
/*Slice01 size register*/
#define DSIM_SLICE01 (0x5C)
#define DSIM_SLICE01_SIZE_OF_SLICE1(_x) ((_x) << 16)
#define DSIM_SLICE01_SIZE_OF_SLICE1_MASK (0x1fff << 16)
#define DSIM_SLICE01_SIZE_OF_SLICE0(_x) ((_x) << 0)
#define DSIM_SLICE01_SIZE_OF_SLICE0_MASK (0x1fff << 0)
/*Slice23 size register*/
#define DSIM_SLICE23 (0x60)
#define DSIM_SLICE23_SIZE_OF_SLICE3(_x) ((_x) << 16)
#define DSIM_SLICE23_SIZE_OF_SLICE3_MASK (0x1fff << 16)
#define DSIM_SLICE23_SIZE_OF_SLICE2(_x) ((_x) << 0)
#define DSIM_SLICE23_SIZE_OF_SLICE2_MASK (0x1fff << 0)
/* Command configuration register */
#define DSIM_CMD_CONFIG (0x78)
#define DSIM_CMD_CONFIG_TE_DETECT_POLARITY (1 << 25)
#define DSIM_CMD_CONFIG_VSYNC_DETECT_POLARITY (1 << 24)
#define DSIM_CMD_CONFIG_PKT_GO_RDY (1 << 22)
#define DSIM_CMD_CONFIG_PKT_GO_EN (1 << 21)
#define DSIM_CMD_CONFIG_CMD_CTRL_SEL (1 << 20)
#define DSIM_CMD_CONFIG_PKT_SEND_CNT(_x) ((_x) << 8)
#define DSIM_CMD_CONFIG_PKT_SEND_CNT_MASK (0xfff << 8)
#define DSIM_CMD_CONFIG_MULTI_CMD_PKT_EN (1 << 7)
#define DSIM_CMD_CONFIG_MULTI_PKT_CNT(_x) ((_x) << 0)
#define DSIM_CMD_CONFIG_MULTI_PKT_CNT_MASK (0xffff << 0)
/* TE based command register*/
#define DSIM_CMD_TE_CTRL0 (0x7C)
#define DSIM_CMD_TE_CTRL0_TIME_STABLE_VFP(_x) ((_x) << 16)
#define DSIM_CMD_TE_CTRL0_TIME_STABLE_VFP_MASK (0xffff << 16)
#define DSIM_CMD_TE_CTRL0_TIME_VSYNC_TOUT(_x) ((_x) << 0)
#define DSIM_CMD_TE_CTRL0_TIME_VSYNC_TOUT_MASK (0xffff << 0)
/* TE based command register*/
#define DSIM_CMD_TE_CTRL1 (0x80)
#define DSIM_CMD_TE_CTRL1_TIME_TE_PROTECT_ON(_x) ((_x) << 16)
#define DSIM_CMD_TE_CTRL1_TIME_TE_PROTECT_ON_MASK (0xffff << 16)
#define DSIM_CMD_TE_CTRL1_TIME_TE_TOUT(_x) ((_x) << 0)
#define DSIM_CMD_TE_CTRL1_TIME_TE_TOUT_MASK (0xffff << 0)
/*Command Mode Status register*/
#define DSIM_CMD_STATUS (0x87)
#define DSIM_CMD_STATUS_ABNORMAL_CAUSE_ST(_x) (((_x) & 0x3ff) << 0)
/*BIST generation register*/
#define DSIM_BIST_GEN (0x88)
#define DSIM_BIST_GEN_BIST_VFP(_x) ((_x) << 20)
#define DSIM_BIST_GEN_BIST_VFP_MASK (0x7ff << 20)
#define DSIM_BIST_GEN_BIST_START (1 << 16)
#define DSIM_BIST_GEN_COLORIMETRIC_FORMAT (1 << 6)
#define DSIM_BIST_GEN_HSYNC_POLARITY (1 << 5)
#define DSIM_BIST_GEN_VSYNC_POLARITY (1 << 4)
#define DSIM_BIST_GEN_BIST_BAR_WIDTH (1 << 3)
#define DSIM_BIST_GEN_BIST_TYPE(_x) ((_x) << 1)
#define DSIM_BIST_GEN_BIST_TYPE_MASK (0x3 << 1)
#define DSIM_BIST_GEN_BIST_EN (1 << 0)
/*DSIM to CSI loopback register*/
#define DSIM_CSIS_LB (0x8C)
#define DSIM_CSIS_LB_CSIS_LB_EN (1 << 8)
#define DSIM_CSIS_LB_CSIS_PH(_x) ((_x) << 0)
#define DSIM_CSIS_LB_CSIS_PH_MASK (0xff << 0)
/* PLL control register */
#define DSIM_PLLCTRL (0x94)
#define DSIM_PLLCTRL_DPDN_SWAP_CLK (1 << 25)
#define DSIM_PLLCTRL_DPDN_SWAP_DATA (1 << 24)
#define DSIM_PLLCTRL_PLL_EN (1 << 23)
#define DSIM_PLLCTRL_PMS_MASK (0x7ffff << 0)
/* M_PLL CTR1 register*/
#define DSIM_PLL_CTRL1 (0x98)
#define DSIM_PLL_CTRL1_M_PLL_CTRL1 (0xffffffff << 0)
/* M_PLL CTR1 register*/
#define DSIM_PLL_CTRL2 (0x9C)
#define DSIM_PLL_CTRL2_M_PLL_CTRL2 (0xffffffff << 0)
/* PLL timer register */
#define DSIM_PLLTMR (0xa0)
/* D-PHY Master & Slave Analog block characteristics control register */
#define DSIM_PHYCTRL (0xa4)
#define DSIM_PHYCTRL_VREG (1 << 26)
#define DSIM_PHYCTRL_B_DPHYCTL0(_x) ((_x) << 0)
#define DSIM_PHYCTRL_B_DPHYCTL0_MASK (0x3ff << 0)
/* D-PHY Master global operating timing register */
#define DSIM_PHYTIMING (0xb4)
#define DSIM_PHYTIMING_M_TLPXCTL(_x) ((_x) << 8)
#define DSIM_PHYTIMING_M_TLPXCTL_MASK (0xff << 8)
#define DSIM_PHYTIMING_M_THSEXITCTL(_x) ((_x) << 0)
#define DSIM_PHYTIMING_M_THSEXITCTL_MASK (0xff << 0)
#define DSIM_PHYTIMING1 (0xb8)
#define DSIM_PHYTIMING1_M_TCLKPRPRCTL(_x) ((_x) << 24)
#define DSIM_PHYTIMING1_M_TCLKPRPRCTL_MASK (0xff << 24)
#define DSIM_PHYTIMING1_M_TCLKZEROCTL(_x) ((_x) << 16)
#define DSIM_PHYTIMING1_M_TCLKZEROCTL_MASK (0xff << 16)
#define DSIM_PHYTIMING1_M_TCLKPOSTCTL(_x) ((_x) << 8)
#define DSIM_PHYTIMING1_M_TCLKPOSTCTL_MASK (0xff << 8)
#define DSIM_PHYTIMING1_M_TCLKTRAILCTL(_x) ((_x) << 0)
#define DSIM_PHYTIMING1_M_TCLKTRAILCTL_MASK (0xff << 0)
#define DSIM_PHYTIMING2 (0xbc)
#define DSIM_PHYTIMING2_M_THSPRPRCTL(_x) ((_x) << 16)
#define DSIM_PHYTIMING2_M_THSPRPRCTL_MASK (0xff << 16)
#define DSIM_PHYTIMING2_M_THSZEROCTL(_x) ((_x) << 8)
#define DSIM_PHYTIMING2_M_THSZEROCTL_MASK (0xff << 8)
#define DSIM_PHYTIMING2_M_THSTRAILCTL(_x) ((_x) << 0)
#define DSIM_PHYTIMING2_M_THSTRAILCTL_MASK (0xff << 0)
#endif /* _REGS_DSIM_H */