commit
64ec5359e1
@ -404,6 +404,7 @@ CONFIG_HAVE_MLOCKED_PAGE_BIT=y
|
||||
CONFIG_KSM=y
|
||||
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
|
||||
CONFIG_ALIGNMENT_TRAP=y
|
||||
CONFIG_ALLOW_CPU_ALIGNMENT=y
|
||||
# CONFIG_UACCESS_WITH_MEMCPY is not set
|
||||
|
||||
#
|
||||
@ -1407,8 +1408,6 @@ CONFIG_FB_CFB_IMAGEBLIT=y
|
||||
CONFIG_FB_MSM=y
|
||||
CONFIG_FB_MSM_LCDC=y
|
||||
# CONFIG_FB_MSM_TVOUT is not set
|
||||
# CONFIG_GPU_MSM_KGSL is not set
|
||||
# CONFIG_GPU_MSM_KGSL_MMU is not set
|
||||
# CONFIG_MSM_HDMI is not set
|
||||
CONFIG_FB_MSM_LOGO=y
|
||||
# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
|
||||
|
@ -382,11 +382,13 @@ ENDPROC(sys_clone_wrapper)
|
||||
|
||||
sys_sigreturn_wrapper:
|
||||
add r0, sp, #S_OFF
|
||||
mov why, #0 @ prevent syscall restart handling
|
||||
b sys_sigreturn
|
||||
ENDPROC(sys_sigreturn_wrapper)
|
||||
|
||||
sys_rt_sigreturn_wrapper:
|
||||
add r0, sp, #S_OFF
|
||||
mov why, #0 @ prevent syscall restart handling
|
||||
b sys_rt_sigreturn
|
||||
ENDPROC(sys_rt_sigreturn_wrapper)
|
||||
|
||||
|
@ -158,10 +158,10 @@ __secondary_data:
|
||||
* registers.
|
||||
*/
|
||||
__enable_mmu:
|
||||
#ifdef CONFIG_ALIGNMENT_TRAP
|
||||
orr r0, r0, #CR_A
|
||||
#else
|
||||
#ifdef CONFIG_ALLOW_CPU_ALIGNMENT
|
||||
bic r0, r0, #CR_A
|
||||
#else
|
||||
orr r0, r0, #CR_A
|
||||
#endif
|
||||
#ifdef CONFIG_CPU_DCACHE_DISABLE
|
||||
bic r0, r0, #CR_C
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
|
||||
#include <mach/board.h>
|
||||
#include <mach/msm_iomap.h>
|
||||
@ -62,6 +63,19 @@ struct clkctl_acpu_speed {
|
||||
unsigned axiclk_khz;
|
||||
};
|
||||
|
||||
static unsigned long max_axi_rate;
|
||||
|
||||
struct regulator {
|
||||
struct device *dev;
|
||||
struct list_head list;
|
||||
int uA_load;
|
||||
int min_uV;
|
||||
int max_uV;
|
||||
char *supply_name;
|
||||
struct device_attribute dev_attr;
|
||||
struct regulator_dev *rdev;
|
||||
};
|
||||
|
||||
/* clock sources */
|
||||
#define CLK_TCXO 0 /* 19.2 MHz */
|
||||
#define CLK_GLOBAL_PLL 1 /* 768 MHz */
|
||||
@ -76,135 +90,46 @@ struct clkctl_acpu_speed {
|
||||
#define SRC_PLL1 3 /* 768 MHz */
|
||||
|
||||
struct clkctl_acpu_speed acpu_freq_tbl[] = {
|
||||
#ifdef CONFIG_HTCLEO_UNDERVOLT_1000
|
||||
{ 19200, CCTL(CLK_TCXO, 1), SRC_RAW, 0, 0, 1000, 14000 },
|
||||
{ 19200, CCTL(CLK_TCXO, 1), SRC_RAW, 0, 0, 1000, 14000},
|
||||
{ 96000, CCTL(CLK_TCXO, 1), SRC_AXI, 0, 0, 1000, 14000 },
|
||||
{ 128000, CCTL(CLK_TCXO, 1), SRC_AXI, 0, 0, 1000, 14000 },
|
||||
{ 245000, CCTL(CLK_MODEM_PLL, 1), SRC_RAW, 0, 0, 1000, 29000 },
|
||||
//{ 256000, CCTL(CLK_GLOBAL_PLL, 3), SRC_RAW, 0, 0, 1000, 29000 },
|
||||
{ 384000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0A, 0, 1000, 58000 },
|
||||
{ 422400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0B, 0, 1000, 117000 },
|
||||
{ 460800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0C, 0, 1000, 117000 },
|
||||
{ 499200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0D, 0, 1025, 117000 },
|
||||
{ 537600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0E, 0, 1050, 117000 },
|
||||
{ 576000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0F, 0, 1050, 117000 },
|
||||
{ 614400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x10, 0, 1075, 117000 },
|
||||
{ 652800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x11, 0, 1100, 117000 },
|
||||
{ 691200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x12, 0, 1125, 117000 },
|
||||
{ 729600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x13, 0, 1150, 117000 },
|
||||
{ 768000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x14, 0, 1150, 128000 },
|
||||
{ 806400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x15, 0, 1175, 128000 },
|
||||
{ 844800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x16, 0, 1200, 128000 },
|
||||
{ 883200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x17, 0, 1200, 128000 },
|
||||
{ 921600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x18, 0, 1225, 128000 },
|
||||
{ 960000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x19, 0, 1225, 128000 },
|
||||
{ 998400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1A, 0, 1225, 128000 },
|
||||
#elif CONFIG_HTCLEO_UNDERVOLT_925
|
||||
// should work with most of HD2s
|
||||
{ 19200, CCTL(CLK_TCXO, 1), SRC_RAW, 0, 0, 925, 14000 },
|
||||
{ 128000, CCTL(CLK_TCXO, 1), SRC_AXI, 0, 0, 925, 14000 },
|
||||
{ 245000, CCTL(CLK_MODEM_PLL, 1), SRC_RAW, 0, 0, 925, 29000 },
|
||||
//{ 256000, CCTL(CLK_GLOBAL_PLL, 3), SRC_RAW, 0, 0, 925, 29000 },
|
||||
{ 384000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0A, 0, 950, 58000 },
|
||||
{ 422400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0B, 0, 975, 117000 },
|
||||
{ 460800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0C, 0, 1000, 117000 },
|
||||
{ 499200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0D, 0, 1025, 117000 },
|
||||
{ 537600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0E, 0, 1050, 117000 },
|
||||
{ 576000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0F, 0, 1050, 117000 },
|
||||
{ 614400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x10, 0, 1075, 117000 },
|
||||
{ 652800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x11, 0, 1100, 117000 },
|
||||
{ 691200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x12, 0, 1125, 117000 },
|
||||
{ 729600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x13, 0, 1150, 117000 },
|
||||
{ 768000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x14, 0, 1150, 128000 },
|
||||
{ 806400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x15, 0, 1175, 128000 },
|
||||
{ 844800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x16, 0, 1200, 128000 },
|
||||
{ 883200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x17, 0, 1200, 128000 },
|
||||
{ 921600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x18, 0, 1225, 128000 },
|
||||
{ 960000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x19, 0, 1225, 128000 },
|
||||
{ 998400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1A, 0, 1225, 128000 },
|
||||
#elif CONFIG_HTCLEO_UNDERVOLT_800
|
||||
// not working yet
|
||||
{ 19200, CCTL(CLK_TCXO, 1), SRC_RAW, 0, 0, 850, 14000 },
|
||||
{ 128000, CCTL(CLK_TCXO, 1), SRC_AXI, 0, 0, 850, 14000 },
|
||||
{ 245000, CCTL(CLK_MODEM_PLL, 1), SRC_RAW, 0, 0, 850, 29000 },
|
||||
//{ 256000, CCTL(CLK_GLOBAL_PLL, 3), SRC_RAW, 0, 0, 850, 29000 },
|
||||
{ 384000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0A, 0, 850, 58000 },
|
||||
{ 422400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0B, 0, 875, 117000 },
|
||||
{ 460800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0C, 0, 900, 117000 },
|
||||
{ 499200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0D, 0, 925, 117000 },
|
||||
{ 537600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0E, 0, 950, 117000 },
|
||||
{ 576000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0F, 0, 950, 117000 },
|
||||
{ 614400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x10, 0, 975, 117000 },
|
||||
{ 652800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x11, 0, 1000, 117000 },
|
||||
{ 691200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x12, 0, 1025, 117000 },
|
||||
{ 729600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x13, 0, 1050, 117000 },
|
||||
{ 768000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x14, 0, 1125, 128000 },
|
||||
{ 806400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x15, 0, 1125, 128000 },
|
||||
{ 844800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x16, 0, 1150, 128000 },
|
||||
{ 883200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x17, 0, 1150, 128000 },
|
||||
{ 921600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x18, 0, 1175, 128000 },
|
||||
{ 960000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x19, 0, 1175, 128000 },
|
||||
{ 998400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1A, 0, 1200, 128000 },
|
||||
#else
|
||||
{ 19200, CCTL(CLK_TCXO, 1), SRC_RAW, 0, 0, 1050, 14000},
|
||||
{ 128000, CCTL(CLK_TCXO, 1), SRC_AXI, 0, 0, 1050, 14000 },
|
||||
{ 245000, CCTL(CLK_MODEM_PLL, 1), SRC_RAW, 0, 0, 1050, 29000 },
|
||||
/* Work arround for acpu resume hung, GPLL is turn off by arm9 */
|
||||
/*{ 256000, CCTL(CLK_GLOBAL_PLL, 3), SRC_RAW, 0, 0, 1050, 29000 },*/
|
||||
{ 384000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0A, 0, 1050, 58000 },
|
||||
{ 422400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0B, 0, 1050, 117000 },
|
||||
{ 460800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0C, 0, 1050, 117000 },
|
||||
{ 499200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0D, 0, 1075, 117000 },
|
||||
{ 537600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0E, 0, 1100, 117000 },
|
||||
{ 576000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0F, 0, 1100, 117000 },
|
||||
{ 614400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x10, 0, 1125, 117000 },
|
||||
{ 652800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x11, 0, 1150, 117000 },
|
||||
{ 691200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x12, 0, 1175, 117000 },
|
||||
{ 729600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x13, 0, 1200, 117000 },
|
||||
{ 768000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x14, 0, 1200, 128000 },
|
||||
{ 806400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x15, 0, 1225, 128000 },
|
||||
{ 844800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x16, 0, 1250, 128000 },
|
||||
{ 883200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x17, 0, 1275, 128000 },
|
||||
{ 921600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x18, 0, 1300, 128000 },
|
||||
{ 960000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x19, 0, 1300, 128000 },
|
||||
{ 998400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1A, 0, 1300, 128000 },
|
||||
#endif
|
||||
#ifdef CONFIG_HTCLEO_OVERCLOCK
|
||||
#ifdef CONFIG_HTCLEO_UNDERVOLT_1000
|
||||
{ 1036800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1B, 0, 1225, 128000 },
|
||||
{ 1075200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1C, 0, 1250, 128000 },
|
||||
{ 1113600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1D, 0, 1275, 128000 },
|
||||
{ 1152000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1E, 0, 1300, 128000 },
|
||||
{ 1190400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1F, 0, 1325, 128000 },
|
||||
#elif CONFIG_HTCLEO_UNDERVOLT_925
|
||||
{ 1036800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1B, 0, 1225, 128000 },
|
||||
{ 1075200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1C, 0, 1250, 128000 },
|
||||
{ 1113600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1D, 0, 1275, 128000 },
|
||||
{ 1152000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1E, 0, 1300, 128000 },
|
||||
{ 1190400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1F, 0, 1325, 128000 },
|
||||
#elif CONFIG_HTCLEO_UNDERVOLT_800
|
||||
{ 1036800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1B, 0, 1225, 128000 },
|
||||
{ 1075200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1C, 0, 1250, 128000 },
|
||||
{ 1113600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1D, 0, 1275, 128000 },
|
||||
{ 1152000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1E, 0, 1300, 128000 },
|
||||
{ 1190400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1F, 0, 1325, 128000 },
|
||||
#else
|
||||
{ 1036800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1B, 0, 1300, 128000 },
|
||||
{ 1075200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1C, 0, 1300, 128000 },
|
||||
{ 1113600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1D, 0, 1300, 128000 },
|
||||
{ 1152000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1E, 0, 1325, 128000 },
|
||||
{ 1190400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1F, 0, 1325, 128000 },
|
||||
#endif
|
||||
/* Work arround for acpu resume hung, GPLL is turn off by arm9 */
|
||||
/*{ 256000, CCTL(CLK_GLOBAL_PLL, 3), SRC_RAW, 0, 0, 1050, 29000 },*/
|
||||
{ 384000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0A, 0, 1000, 58000 },
|
||||
{ 422400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0B, 0, 1000, 117000 },
|
||||
{ 460800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0C, 0, 1000, 117000 },
|
||||
{ 499200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0D, 0, 1050, 117000 },
|
||||
{ 537600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0E, 0, 1050, 117000 },
|
||||
{ 576000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x0F, 0, 1050, 117000 },
|
||||
{ 614400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x10, 0, 1075, 117000 },
|
||||
{ 652800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x11, 0, 1100, 117000 },
|
||||
{ 691200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x12, 0, 1125, 117000 },
|
||||
{ 729600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x13, 0, 1150, 117000 },
|
||||
{ 768000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x14, 0, 1150, 128000 },
|
||||
{ 806400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x15, 0, 1175, 128000 },
|
||||
{ 844800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x16, 0, 1225, 128000 },
|
||||
{ 883200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x17, 0, 1250, 128000 },
|
||||
{ 921600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x18, 0, 1300, 128000 },
|
||||
{ 960000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x19, 0, 1300, 128000 },
|
||||
{ 998400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1A, 0, 1300, 128000 },
|
||||
#ifdef CONFIG_HTCLEO_OVERCLOCK
|
||||
{ 1036800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1B, 0, 1300, 128000 },
|
||||
{ 1075200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1C, 0, 1300, 128000 },
|
||||
{ 1113600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1D, 0, 1300, 128000 },
|
||||
{ 1152000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1E, 0, 1300, 128000 },
|
||||
{ 1190400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x1F, 0, 1325, 128000 },
|
||||
#endif
|
||||
#ifdef CONFIG_HTCLEO_EXOVERCLOCK
|
||||
{ 1228800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x20, 0, 1325, 128000 },
|
||||
{ 1267200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x21, 0, 1350, 128000 },
|
||||
{ 1305600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x22, 0, 1350, 128000 },
|
||||
{ 1344000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x23, 0, 1350, 128000 },
|
||||
{ 1382400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x24, 0, 1350, 128000 },
|
||||
{ 1420800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x25, 0, 1350, 128000 },
|
||||
{ 1459200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x26, 0, 1350, 128000 },
|
||||
{ 1497600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x27, 0, 1350, 128000 },
|
||||
{ 1536000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x28, 0, 1350, 128000 },
|
||||
{ 1228800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x20, 0, 1325, 128000 },
|
||||
{ 1267200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x21, 0, 1350, 128000 },
|
||||
{ 1305600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x22, 0, 1350, 128000 },
|
||||
{ 1344000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x23, 0, 1350, 128000 },
|
||||
{ 1382400, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x24, 0, 1350, 128000 },
|
||||
{ 1420800, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x25, 0, 1350, 128000 },
|
||||
{ 1459200, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x26, 0, 1350, 128000 },
|
||||
{ 1497600, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x27, 0, 1350, 128000 },
|
||||
{ 1536000, CCTL(CLK_TCXO, 1), SRC_SCPLL, 0x28, 0, 1350, 128000 },
|
||||
#endif
|
||||
{ 0 },
|
||||
};
|
||||
@ -231,11 +156,10 @@ static void __init acpuclk_init_cpufreq_table(void)
|
||||
freq_table[i].index = i;
|
||||
freq_table[i].frequency = CPUFREQ_ENTRY_INVALID;
|
||||
|
||||
/* Skip speeds we don't want */
|
||||
if ( acpu_freq_tbl[i].acpu_khz == 19200 ||
|
||||
//acpu_freq_tbl[i].acpu_khz == 128000 ||
|
||||
acpu_freq_tbl[i].acpu_khz == 256000)
|
||||
continue;
|
||||
/* Skip speeds using the global pll */
|
||||
if (acpu_freq_tbl[i].acpu_khz == 256000 ||
|
||||
acpu_freq_tbl[i].acpu_khz == 19200)
|
||||
continue;
|
||||
|
||||
vdd = acpu_freq_tbl[i].vdd;
|
||||
/* Allow mpll and the first scpll speeds */
|
||||
@ -269,6 +193,7 @@ struct clock_state {
|
||||
unsigned long wait_for_irq_khz;
|
||||
struct clk* clk_ebi1;
|
||||
struct regulator *regulator;
|
||||
int (*acpu_set_vdd) (int mvolts);
|
||||
};
|
||||
|
||||
static struct clock_state drv_state = { 0 };
|
||||
@ -345,11 +270,10 @@ static void scpll_set_freq(uint32_t lval)
|
||||
dmb();
|
||||
|
||||
/* wait for frequency switch to finish */
|
||||
while (readl(SCPLL_STATUS_ADDR) & 0x1)
|
||||
;
|
||||
while (readl(SCPLL_STATUS_ADDR) & 0x1);
|
||||
|
||||
/* completion bit is not reliable for SHOT switch */
|
||||
udelay(25);
|
||||
udelay(15);
|
||||
}
|
||||
|
||||
/* write the new L val and switch mode */
|
||||
@ -363,8 +287,7 @@ static void scpll_set_freq(uint32_t lval)
|
||||
dmb();
|
||||
|
||||
/* wait for frequency switch to finish */
|
||||
while (readl(SCPLL_STATUS_ADDR) & 0x1)
|
||||
;
|
||||
while (readl(SCPLL_STATUS_ADDR) & 0x1);
|
||||
}
|
||||
|
||||
/* this is still a bit weird... */
|
||||
@ -625,13 +548,20 @@ static void __init acpuclk_init(void)
|
||||
}
|
||||
drv_state.current_speed = speed;
|
||||
|
||||
for (speed = acpu_freq_tbl; speed->acpu_khz; speed++)
|
||||
for (speed = acpu_freq_tbl; speed->acpu_khz; speed++) {
|
||||
speed->lpj = cpufreq_scale(loops_per_jiffy,
|
||||
init_khz, speed->acpu_khz);
|
||||
max_axi_rate = speed->axiclk_khz * 1000;
|
||||
}
|
||||
|
||||
loops_per_jiffy = drv_state.current_speed->lpj;
|
||||
}
|
||||
|
||||
unsigned long acpuclk_get_max_axi_rate(void)
|
||||
{
|
||||
return max_axi_rate;
|
||||
}
|
||||
|
||||
unsigned long acpuclk_get_rate(void)
|
||||
{
|
||||
return drv_state.current_speed->acpu_khz;
|
||||
@ -674,6 +604,7 @@ void __init msm_acpu_clock_init(struct msm_acpu_clock_platform_data *clkdata)
|
||||
drv_state.vdd_switch_time_us = clkdata->vdd_switch_time_us;
|
||||
drv_state.power_collapse_khz = clkdata->power_collapse_khz;
|
||||
drv_state.wait_for_irq_khz = clkdata->wait_for_irq_khz;
|
||||
drv_state.acpu_set_vdd = acpuclk_set_vdd_level;
|
||||
|
||||
if (clkdata->mpll_khz)
|
||||
acpu_mpll->acpu_khz = clkdata->mpll_khz;
|
||||
@ -708,7 +639,7 @@ ssize_t acpuclk_get_vdd_levels_str(char *buf)
|
||||
void acpuclk_set_vdd(unsigned acpu_khz, int vdd)
|
||||
{
|
||||
int i;
|
||||
vdd = vdd / 25 * 25; //! regulator only accepts multiples of 25 (mV)
|
||||
vdd = (vdd / HTCLEO_TPS65023_UV_STEP_MV) * HTCLEO_TPS65023_UV_STEP_MV;
|
||||
mutex_lock(&drv_state.lock);
|
||||
for (i = 0; acpu_freq_tbl[i].acpu_khz; i++)
|
||||
{
|
||||
@ -722,5 +653,16 @@ void acpuclk_set_vdd(unsigned acpu_khz, int vdd)
|
||||
}
|
||||
mutex_unlock(&drv_state.lock);
|
||||
}
|
||||
|
||||
unsigned int acpuclk_get_vdd_min(void)
|
||||
{
|
||||
return HTCLEO_TPS65023_MIN_UV_MV;
|
||||
}
|
||||
unsigned int acpuclk_get_vdd_max(void)
|
||||
{
|
||||
return HTCLEO_TPS65023_MAX_UV_MV;
|
||||
}
|
||||
unsigned int acpuclk_get_vdd_step(void)
|
||||
{
|
||||
return HTCLEO_TPS65023_UV_STEP_MV;
|
||||
}
|
||||
#endif
|
||||
|
@ -39,7 +39,6 @@
|
||||
|
||||
#define HTCLEO_DEFAULT_BACKLIGHT_BRIGHTNESS 255
|
||||
|
||||
|
||||
static struct led_trigger *htcleo_lcd_backlight;
|
||||
static int auto_bl_state=0;
|
||||
static DEFINE_MUTEX(htcleo_backlight_lock);
|
||||
|
@ -118,7 +118,7 @@ int lightsensor_read_value(uint32_t *val)
|
||||
}
|
||||
|
||||
*val = data[1] | (data[0] << 8);
|
||||
D("lsensor adc = %d\n", *val);
|
||||
D("lsensor adc = %u\n", *val); /* val is unsigned */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include <mach/vreg.h>
|
||||
#include <mach/gpio.h>
|
||||
#include <mach/board-htcleo-mmc.h>
|
||||
|
||||
#include "board-htcleo.h"
|
||||
#include "devices.h"
|
||||
@ -391,7 +392,7 @@ static int __init htcleommc_dbg_init(void)
|
||||
{
|
||||
struct dentry *dent;
|
||||
|
||||
if (!machine_is_htcleo() && !machine_is_htcleo())
|
||||
if (!machine_is_htcleo())
|
||||
return 0;
|
||||
|
||||
dent = debugfs_create_dir("htcleo_mmc_dbg", 0);
|
||||
|
@ -55,7 +55,9 @@
|
||||
#ifdef CONFIG_SERIAL_BCM_BT_LPM
|
||||
#include <mach/bcm_bt_lpm.h>
|
||||
#endif
|
||||
#ifdef CONFIG_PERFLOCK
|
||||
#include <mach/perflock.h>
|
||||
#endif
|
||||
#include <mach/htc_headset_mgr.h>
|
||||
#include <mach/htc_headset_gpio.h>
|
||||
|
||||
@ -395,10 +397,9 @@ static uint32_t flashlight_gpio_table[] =
|
||||
PCOM_GPIO_CFG(HTCLEO_GPIO_FLASHLIGHT_FLASH, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA),
|
||||
};
|
||||
|
||||
static int config_htcleo_flashlight_gpios(void)
|
||||
static void config_htcleo_flashlight_gpios(void)
|
||||
{
|
||||
config_gpio_table(flashlight_gpio_table, ARRAY_SIZE(flashlight_gpio_table));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct flashlight_platform_data htcleo_flashlight_data =
|
||||
@ -748,28 +749,6 @@ static struct platform_device qsd_device_spi = {
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// KGSL (HW3D support)#include <linux/android_pmem.h>
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
static struct resource msm_kgsl_resources[] =
|
||||
{
|
||||
{
|
||||
.name = "kgsl_reg_memory",
|
||||
.start = MSM_GPU_REG_PHYS,
|
||||
.end = MSM_GPU_REG_PHYS + MSM_GPU_REG_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.name = "kgsl_phys_memory",
|
||||
.start = MSM_GPU_PHYS_BASE,
|
||||
.end = MSM_GPU_PHYS_BASE + MSM_GPU_PHYS_SIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = INT_GRAPHICS,
|
||||
.end = INT_GRAPHICS,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
static int htcleo_kgsl_power_rail_mode(int follow_clk)
|
||||
{
|
||||
int mode = follow_clk ? 0 : 1;
|
||||
@ -786,16 +765,7 @@ static int htcleo_kgsl_power(bool on)
|
||||
return msm_proc_comm(cmd, &rail_id, 0);
|
||||
}
|
||||
|
||||
static struct platform_device msm_kgsl_device =
|
||||
{
|
||||
.name = "kgsl",
|
||||
.id = -1,
|
||||
.resource = msm_kgsl_resources,
|
||||
.num_resources = ARRAY_SIZE(msm_kgsl_resources),
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MSM_KGSL
|
||||
/* start kgsl */
|
||||
/* start kgsl-3d0 */
|
||||
static struct resource kgsl_3d0_resources[] = {
|
||||
{
|
||||
.name = KGSL_3D0_REG_MEMORY,
|
||||
@ -843,9 +813,7 @@ struct platform_device msm_kgsl_3d0 = {
|
||||
.platform_data = &kgsl_3d0_pdata,
|
||||
},
|
||||
};
|
||||
/* end kgsl */
|
||||
#endif
|
||||
|
||||
/* end kgsl-3d0 */
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Memory
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
@ -897,7 +865,7 @@ static struct platform_device android_pmem_mdp_device = {
|
||||
|
||||
static struct platform_device android_pmem_adsp_device = {
|
||||
.name = "android_pmem",
|
||||
.id = 4,
|
||||
.id = 1, /* 4 */
|
||||
.dev = {
|
||||
.platform_data = &android_pmem_adsp_pdata,
|
||||
},
|
||||
@ -905,7 +873,7 @@ static struct platform_device android_pmem_adsp_device = {
|
||||
|
||||
static struct platform_device android_pmem_venc_device = {
|
||||
.name = "android_pmem",
|
||||
.id = 5,
|
||||
.id = 3, /* 5 */
|
||||
.dev = {
|
||||
.platform_data = &android_pmem_venc_pdata,
|
||||
},
|
||||
@ -1083,6 +1051,7 @@ static struct msm_acpu_clock_platform_data htcleo_clock_data = {
|
||||
// .wait_for_irq_khz = 19200, // TCXO
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PERFLOCK
|
||||
static unsigned htcleo_perf_acpu_table[] = {
|
||||
245000000,
|
||||
576000000,
|
||||
@ -1093,6 +1062,8 @@ static struct perflock_platform_data htcleo_perflock_data = {
|
||||
.perf_acpu_table = htcleo_perf_acpu_table,
|
||||
.table_size = ARRAY_SIZE(htcleo_perf_acpu_table),
|
||||
};
|
||||
#endif
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
// Reset
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
@ -1139,7 +1110,9 @@ static void __init htcleo_init(void)
|
||||
|
||||
msm_acpu_clock_init(&htcleo_clock_data);
|
||||
|
||||
#ifdef CONFIG_PERFLOCK
|
||||
perflock_init(&htcleo_perflock_data);
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MSM_SERIAL_DEBUGGER)
|
||||
msm_serial_debug_init(MSM_UART1_PHYS, INT_UART1,
|
||||
|
@ -178,7 +178,8 @@
|
||||
|
||||
/* Voltage driver */
|
||||
#define HTCLEO_TPS65023_MIN_UV_MV (800)
|
||||
#define HTCLEO_TPS65023_MAX_UV_MV (1350)
|
||||
#define HTCLEO_TPS65023_MAX_UV_MV (1375)
|
||||
#define HTCLEO_TPS65023_UV_STEP_MV (25)
|
||||
|
||||
/* LEDS */
|
||||
#define LED_RGB (1 << 0)
|
||||
@ -196,11 +197,12 @@ struct microp_led_platform_data {
|
||||
int num_leds;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
int htcleo_pm_set_vreg(int enable, unsigned id);
|
||||
int __init htcleo_init_panel(void);
|
||||
int htcleo_is_nand_boot(void);
|
||||
unsigned htcleo_get_vbus_state(void);
|
||||
void config_camera_on_gpios(void);
|
||||
void config_camera_off_gpios(void);
|
||||
int is_valid_mac_address(char *mac);
|
||||
|
||||
#endif /* __ARCH_ARM_MACH_MSM_BOARD_HTCLEO_H */
|
||||
|
@ -34,6 +34,8 @@
|
||||
|
||||
//#define ENABLE_CLOCK_INFO 1
|
||||
|
||||
extern struct clk msm_clocks[];
|
||||
|
||||
static DEFINE_MUTEX(clocks_mutex);
|
||||
static DEFINE_SPINLOCK(clocks_lock);
|
||||
static LIST_HEAD(clocks);
|
||||
@ -233,8 +235,16 @@ struct mdns_clock_params msm_clock_freq_parameters[] = {
|
||||
MSM_CLOCK_REG(64000000,0x19, 0x60, 0x30, 0, 2, 4, 1, 245760000), /* BT, 4000000 (*16) */
|
||||
};
|
||||
|
||||
int status_set_grp_clk = 0;
|
||||
int i_set_grp_clk = 0;
|
||||
int control_set_grp_clk;
|
||||
|
||||
static void set_grp_clk( int on )
|
||||
{
|
||||
int i = 0;
|
||||
int status = 0;
|
||||
int control;
|
||||
|
||||
if ( on != 0 )
|
||||
{
|
||||
//axi_reset
|
||||
@ -274,8 +284,7 @@ static void set_grp_clk( int on )
|
||||
writel(readl(MSM_CLK_CTL_BASE) |0x8, MSM_CLK_CTL_BASE);
|
||||
//grp MD
|
||||
writel(readl(MSM_CLK_CTL_BASE+0x80) |0x1, MSM_CLK_CTL_BASE+0x80); //PRPH_WEB_NS_REG
|
||||
int i = 0;
|
||||
int status = 0;
|
||||
|
||||
while ( status == 0 && i < 100) {
|
||||
i++;
|
||||
status = readl(MSM_CLK_CTL_BASE+0x84) & 0x1;
|
||||
@ -297,7 +306,7 @@ static void set_grp_clk( int on )
|
||||
writel(readl(MSM_CLK_CTL_BASE+0x290) |0x4, MSM_CLK_CTL_BASE+0x290); //MSM_RAIL_CLAMP_IO
|
||||
writel( 0x11f, MSM_CLK_CTL_BASE+0x284); //VDD_GRP_GFS_CTL
|
||||
|
||||
int control = readl(MSM_CLK_CTL_BASE+0x288); //VDD_VDC_GFS_CTL
|
||||
control = readl(MSM_CLK_CTL_BASE+0x288); //VDD_VDC_GFS_CTL
|
||||
if ( control & 0x100 )
|
||||
writel(readl(MSM_CLK_CTL_BASE) &(~(0x8)), MSM_CLK_CTL_BASE);
|
||||
}
|
||||
@ -1291,5 +1300,18 @@ static int __init clock_late_init(void)
|
||||
//pr_info("reset imem_config\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
late_initcall(clock_late_init);
|
||||
|
||||
struct clk_ops clk_ops_pcom = {
|
||||
.enable = pc_clk_enable,
|
||||
.disable = pc_clk_disable,
|
||||
.auto_off = pc_clk_disable,
|
||||
// .reset = pc_clk_reset,
|
||||
.set_rate = pc_clk_set_rate,
|
||||
.set_min_rate = pc_clk_set_min_rate,
|
||||
.set_max_rate = pc_clk_set_max_rate,
|
||||
.set_flags = pc_clk_set_flags,
|
||||
.get_rate = pc_clk_get_rate,
|
||||
.is_enabled = pc_clk_is_enabled,
|
||||
// .round_rate = pc_clk_round_rate,
|
||||
};
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <linux/list.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/clk.h>
|
||||
#include <mach/clk.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/debugfs.h>
|
||||
|
@ -17,6 +17,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/cpumask.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/suspend.h>
|
||||
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/earlysuspend.h>
|
||||
#include <linux/init.h>
|
||||
|
@ -138,13 +138,14 @@ dmov_exec_cmdptr_complete_func(struct msm_dmov_cmd *_cmd,
|
||||
complete(&cmd->complete);
|
||||
}
|
||||
|
||||
int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr)
|
||||
int msm_dmov_exec_cmd(unsigned id, unsigned int crci_mask, unsigned int cmdptr)
|
||||
{
|
||||
struct msm_dmov_exec_cmdptr_cmd cmd;
|
||||
|
||||
PRINT_FLOW("dmov_exec_cmdptr(%d, %x)\n", id, cmdptr);
|
||||
|
||||
cmd.dmov_cmd.cmdptr = cmdptr;
|
||||
cmd.dmov_cmd.crci_mask = crci_mask;
|
||||
cmd.dmov_cmd.complete_func = dmov_exec_cmdptr_complete_func;
|
||||
cmd.dmov_cmd.execute_func = NULL;
|
||||
cmd.id = id;
|
||||
|
29
arch/arm/mach-msm/include/mach/board-htcleo-audio.h
Normal file
29
arch/arm/mach-msm/include/mach/board-htcleo-audio.h
Normal file
@ -0,0 +1,29 @@
|
||||
/* board-htcleo-mmc.h
|
||||
*
|
||||
* Copyright (C) 2011 marc1706
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HTCLEO_AUDIO_H
|
||||
#define HTCLEO_AUDIO_H
|
||||
|
||||
void htcleo_headset_enable(int en);
|
||||
void htcleo_speaker_enable(int en);
|
||||
void htcleo_receiver_enable(int en);
|
||||
void htcleo_bt_sco_enable(int en);
|
||||
void htcleo_mic_enable(int en);
|
||||
void htcleo_analog_init(void);
|
||||
int htcleo_get_rx_vol(uint8_t hw, int level);
|
||||
void __init htcleo_audio_init(void);
|
||||
|
||||
#endif // HTCLEO_AUDIO_H
|
||||
|
@ -136,4 +136,14 @@ struct microp_i2c_client_data {
|
||||
int microp_i2c_read(uint8_t addr, uint8_t *data, int length);
|
||||
int microp_i2c_write(uint8_t addr, uint8_t *data, int length);
|
||||
int capella_cm3602_power(int pwr_device, uint8_t enable);
|
||||
int microp_read_gpo_status(uint16_t *status);
|
||||
int microp_gpo_enable(uint16_t gpo_mask);
|
||||
int microp_gpo_disable(uint16_t gpo_mask);
|
||||
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
void microp_early_suspend(struct early_suspend *h);
|
||||
void microp_early_resume(struct early_suspend *h);
|
||||
#endif // CONFIG_HAS_EARLYSUSPEND
|
||||
|
||||
|
||||
#endif
|
||||
|
31
arch/arm/mach-msm/include/mach/board-htcleo-mmc.h
Normal file
31
arch/arm/mach-msm/include/mach/board-htcleo-mmc.h
Normal file
@ -0,0 +1,31 @@
|
||||
/* board-htcleo-mmc.h
|
||||
*
|
||||
* Copyright (C) 2011 marc1706
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef HTCLEO_MMC_H
|
||||
#define HTCLEO_MMC_H
|
||||
|
||||
static bool opt_disable_sdcard;
|
||||
static void (*wifi_status_cb)(int card_present, void *dev_id);
|
||||
static void *wifi_status_cb_devid;
|
||||
static int htcleo_wifi_power_state;
|
||||
static int htcleo_wifi_reset_state;
|
||||
|
||||
int htcleo_wifi_set_carddetect(int val);
|
||||
int htcleo_wifi_power(int on);
|
||||
int htcleo_wifi_reset(int on);
|
||||
int __init htcleo_init_mmc(unsigned debug_uart);
|
||||
|
||||
#endif // HTCLEO_MMC_H
|
||||
|
@ -178,6 +178,8 @@ enum {
|
||||
BOOTMODE_OFFMODE_CHARGING = 0x5,
|
||||
};
|
||||
|
||||
void msm_hsusb_set_vbus_state(int online);
|
||||
|
||||
#define MSM_MAX_DEC_CNT 14
|
||||
/* 7k target ADSP information */
|
||||
/* Bit 23:0, for codec identification like mp3, wav etc *
|
||||
|
@ -32,6 +32,7 @@
|
||||
#define NUM_AUTOFOCUS_MULTI_WINDOW_GRIDS 16
|
||||
#define NUM_STAT_OUTPUT_BUFFERS 3
|
||||
#define NUM_AF_STAT_OUTPUT_BUFFERS 3
|
||||
#define max_control_command_size 150
|
||||
|
||||
enum msm_queue {
|
||||
MSM_CAM_Q_CTRL, /* control command or control command status */
|
||||
|
@ -51,4 +51,7 @@ int clk_set_max_rate(struct clk *clk, unsigned long rate);
|
||||
int clk_reset(struct clk *clk, enum clk_reset_action action);
|
||||
|
||||
int clk_set_flags(struct clk *clk, unsigned long flags);
|
||||
|
||||
unsigned long acpuclk_get_max_axi_rate(void);
|
||||
|
||||
#endif
|
||||
|
47
arch/arm/mach-msm/include/mach/debug_mm.h
Normal file
47
arch/arm/mach-msm/include/mach/debug_mm.h
Normal file
@ -0,0 +1,47 @@
|
||||
/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met:
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials provided
|
||||
* with the distribution.
|
||||
* * Neither the name of Code Aurora Forum, Inc. nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
||||
* IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
#ifndef __ARCH_ARM_MACH_MSM_DEBUG_MM_H_
|
||||
#define __ARCH_ARM_MACH_MSM_DEBUG_MM_H_
|
||||
|
||||
/* The below macro removes the directory path name and retains only the
|
||||
* file name to avoid long path names in log messages that comes as
|
||||
* part of __FILE__ to compiler.
|
||||
*/
|
||||
#define __MM_FILE__ strrchr(__FILE__, '/') ? (strrchr(__FILE__, '/')+1) : \
|
||||
__FILE__
|
||||
|
||||
#define MM_DBG(fmt, args...) pr_debug("[%s] " fmt,\
|
||||
__func__, ##args)
|
||||
|
||||
#define MM_INFO(fmt, args...) pr_info("[%s:%s] " fmt,\
|
||||
__MM_FILE__, __func__, ##args)
|
||||
|
||||
#define MM_ERR(fmt, args...) pr_err("[%s:%s] " fmt,\
|
||||
__MM_FILE__, __func__, ##args)
|
||||
#endif /* __ARCH_ARM_MACH_MSM_DEBUG_MM_H_ */
|
@ -27,6 +27,7 @@ struct msm_dmov_errdata {
|
||||
struct msm_dmov_cmd {
|
||||
struct list_head list;
|
||||
unsigned int cmdptr;
|
||||
unsigned int crci_mask;
|
||||
void (*complete_func)(struct msm_dmov_cmd *cmd,
|
||||
unsigned int result,
|
||||
struct msm_dmov_errdata *err);
|
||||
@ -38,7 +39,7 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd);
|
||||
void msm_dmov_enqueue_cmd_ext(unsigned id, struct msm_dmov_cmd *cmd);
|
||||
void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful);
|
||||
void msm_dmov_flush(unsigned int id);
|
||||
int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr);
|
||||
int msm_dmov_exec_cmd(unsigned id, unsigned int crci_mask, unsigned int cmdptr);
|
||||
|
||||
|
||||
|
||||
|
@ -311,6 +311,7 @@
|
||||
#define INT_MDDI_CLIENT INT_MDC
|
||||
#define INT_NAND_WR_ER_DONE INT_EBI2_WR_ER_DONE
|
||||
#define INT_NAND_OP_DONE INT_EBI2_OP_DONE
|
||||
#define INT_GRAPHICS INT_GRP_3D
|
||||
|
||||
#define NR_SIRC_IRQS 0
|
||||
|
||||
|
@ -27,10 +27,12 @@ struct mddi_info;
|
||||
#define MSM_MDP_OUT_IF_FMT_RGB888 2
|
||||
|
||||
/* mdp override operations */
|
||||
#define MSM_MDP_PANEL_IGNORE_PIXEL_DATA (1 << 0)
|
||||
#define MSM_MDP_PANEL_IGNORE_PIXEL_DATA (1 << 0)
|
||||
#define MSM_MDP_PANEL_FLIP_UD (1 << 1)
|
||||
#define MSM_MDP_PANEL_FLIP_LR (1 << 2)
|
||||
#define MSM_MDP4_MDDI_DMA_SWITCH (1 << 3)
|
||||
#define MSM_MDP_DMA_PACK_ALIGN_LSB (1 << 4)
|
||||
#define MSM_MDP_RGB_PANEL_SELF_REFRESH (1 << 5)
|
||||
|
||||
/* mddi type */
|
||||
#define MSM_MDP_MDDI_TYPE_I 0
|
||||
@ -190,6 +192,7 @@ struct msm_lcdc_panel_ops {
|
||||
int (*uninit)(struct msm_lcdc_panel_ops *);
|
||||
int (*blank)(struct msm_lcdc_panel_ops *);
|
||||
int (*unblank)(struct msm_lcdc_panel_ops *);
|
||||
int (*shutdown)(struct msm_lcdc_panel_ops *);
|
||||
};
|
||||
|
||||
struct msm_lcdc_platform_data {
|
||||
@ -211,6 +214,8 @@ struct msm_tvenc_platform_data {
|
||||
|
||||
struct mdp_blit_req;
|
||||
struct fb_info;
|
||||
struct mdp_overlay;
|
||||
struct msmfb_overlay_data;
|
||||
struct mdp_device {
|
||||
struct device dev;
|
||||
void (*dma)(struct mdp_device *mdp, uint32_t addr,
|
||||
@ -227,14 +232,17 @@ struct mdp_device {
|
||||
int (*overlay_unset)(struct mdp_device *mdp, struct fb_info *fb,
|
||||
int ndx);
|
||||
int (*overlay_play)(struct mdp_device *mdp, struct fb_info *fb,
|
||||
struct msmfb_overlay_data *req, struct file *p_src_file);
|
||||
struct msmfb_overlay_data *req, struct file **p_src_file);
|
||||
#endif
|
||||
void (*set_grp_disp)(struct mdp_device *mdp, uint32_t disp_id);
|
||||
void (*configure_dma)(struct mdp_device *mdp);
|
||||
int (*check_output_format)(struct mdp_device *mdp, int bpp);
|
||||
int (*set_output_format)(struct mdp_device *mdp, int bpp);
|
||||
void (*set_panel_size)(struct mdp_device *mdp, int width, int height);
|
||||
unsigned color_format;
|
||||
unsigned overrides;
|
||||
uint32_t width; /*panel width*/
|
||||
uint32_t height; /*panel height*/
|
||||
};
|
||||
|
||||
struct class_interface;
|
||||
|
@ -132,6 +132,8 @@ uint32_t msm_rpc_get_vers(struct msm_rpc_endpoint *ept);
|
||||
/* check if server version can handle client requested version */
|
||||
int msm_rpc_is_compatible_version(uint32_t server_version,
|
||||
uint32_t client_version);
|
||||
struct msm_rpc_endpoint *msm_rpc_connect_compatible(uint32_t prog,
|
||||
uint32_t vers, unsigned flags);
|
||||
|
||||
int msm_rpc_close(struct msm_rpc_endpoint *ept);
|
||||
int msm_rpc_write(struct msm_rpc_endpoint *ept,
|
||||
@ -164,7 +166,7 @@ struct msm_rpc_xdr {
|
||||
void *in_buf;
|
||||
uint32_t in_size;
|
||||
uint32_t in_index;
|
||||
struct mutex in_lock;
|
||||
wait_queue_head_t in_buf_wait_q;
|
||||
|
||||
void *out_buf;
|
||||
uint32_t out_size;
|
||||
@ -174,6 +176,22 @@ struct msm_rpc_xdr {
|
||||
struct msm_rpc_endpoint *ept;
|
||||
};
|
||||
|
||||
int xdr_send_int8(struct msm_rpc_xdr *xdr, const int8_t *value);
|
||||
int xdr_send_uint8(struct msm_rpc_xdr *xdr, const uint8_t *value);
|
||||
int xdr_send_int16(struct msm_rpc_xdr *xdr, const int16_t *value);
|
||||
int xdr_send_uint16(struct msm_rpc_xdr *xdr, const uint16_t *value);
|
||||
int xdr_send_int32(struct msm_rpc_xdr *xdr, const int32_t *value);
|
||||
int xdr_send_uint32(struct msm_rpc_xdr *xdr, const uint32_t *value);
|
||||
int xdr_send_bytes(struct msm_rpc_xdr *xdr, const void **data, uint32_t *size);
|
||||
|
||||
int xdr_recv_int8(struct msm_rpc_xdr *xdr, int8_t *value);
|
||||
int xdr_recv_uint8(struct msm_rpc_xdr *xdr, uint8_t *value);
|
||||
int xdr_recv_int16(struct msm_rpc_xdr *xdr, int16_t *value);
|
||||
int xdr_recv_uint16(struct msm_rpc_xdr *xdr, uint16_t *value);
|
||||
int xdr_recv_int32(struct msm_rpc_xdr *xdr, int32_t *value);
|
||||
int xdr_recv_uint32(struct msm_rpc_xdr *xdr, uint32_t *value);
|
||||
int xdr_recv_bytes(struct msm_rpc_xdr *xdr, void **data, uint32_t *size);
|
||||
|
||||
struct msm_rpc_server
|
||||
{
|
||||
struct list_head list;
|
||||
|
@ -63,6 +63,8 @@ int smd_wait_until_writable(smd_channel_t *ch, int bytes);
|
||||
#endif
|
||||
int smd_wait_until_opened(smd_channel_t *ch, int timeout_us);
|
||||
|
||||
int smd_total_fifo_size(smd_channel_t *ch);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
SMD_PORT_DS = 0,
|
||||
|
@ -142,13 +142,15 @@ int msm_irq_idle_sleep_allowed(void);
|
||||
int msm_irq_pending(void);
|
||||
int clks_allow_tcxo_locked_debug(void);
|
||||
extern int board_mfg_mode(void);
|
||||
extern char * board_get_mfg_sleep_gpio_table(void);
|
||||
extern unsigned long * board_get_mfg_sleep_gpio_table(void);
|
||||
extern void gpio_set_diag_gpio_table(unsigned long * dwMFG_gpio_table);
|
||||
extern void wait_rmt_final_call_back(int timeout);
|
||||
|
||||
#ifdef CONFIG_AXI_SCREEN_POLICY
|
||||
static int axi_rate;
|
||||
static int sleep_axi_rate;
|
||||
static struct clk *axi_clk;
|
||||
#endif
|
||||
static uint32_t *msm_pm_reset_vector;
|
||||
|
||||
static uint32_t msm_pm_max_sleep_time;
|
||||
@ -654,8 +656,8 @@ static int msm_wakeup_after; /* default, no wakeup by alarm */
|
||||
static int msm_power_wakeup_after(const char *val, struct kernel_param *kp)
|
||||
{
|
||||
int ret;
|
||||
struct uart_port *port;
|
||||
struct msm_port *msm_port;
|
||||
//struct uart_port *port;
|
||||
//struct msm_port *msm_port;
|
||||
|
||||
ret = param_set_int(val, kp);
|
||||
printk(KERN_INFO "+msm_power_wakeup_after, ret=%d\r\n", ret);
|
||||
@ -681,7 +683,7 @@ static void msm_pm_power_off(void)
|
||||
|
||||
pmic_glb_power_down();
|
||||
|
||||
#if CONFIG_MSM_RMT_STORAGE_SERVER
|
||||
#ifdef CONFIG_MSM_RMT_STORAGE_SERVER
|
||||
printk(KERN_INFO "from %s\r\n", __func__);
|
||||
wait_rmt_final_call_back(10);
|
||||
printk(KERN_INFO "back %s\r\n", __func__);
|
||||
@ -715,7 +717,7 @@ void msm_pm_flush_console(void)
|
||||
}
|
||||
|
||||
#if defined(CONFIG_MACH_HTCLEO)
|
||||
static void htcleo_save_reset_reason()
|
||||
static void htcleo_save_reset_reason(void)
|
||||
{
|
||||
/* save restart_reason to be accesible in bootloader @ ramconsole - 0x1000*/
|
||||
uint32_t *bootloader_reset_reason = ioremap(0x2FFB0000, PAGE_SIZE);
|
||||
@ -728,7 +730,7 @@ static void htcleo_save_reset_reason()
|
||||
}
|
||||
#endif
|
||||
|
||||
static void msm_pm_restart(char str)
|
||||
static void msm_pm_restart(char str, const char *cmd)
|
||||
{
|
||||
msm_pm_flush_console();
|
||||
|
||||
@ -742,7 +744,7 @@ static void msm_pm_restart(char str)
|
||||
else
|
||||
msm_proc_comm(PCOM_RESET_CHIP, &restart_reason, 0);
|
||||
|
||||
#if CONFIG_MSM_RMT_STORAGE_SERVER
|
||||
#ifdef CONFIG_MSM_RMT_STORAGE_SERVER
|
||||
printk(KERN_INFO "from %s\r\n", __func__);
|
||||
wait_rmt_final_call_back(10);
|
||||
printk(KERN_INFO "back %s\r\n", __func__);
|
||||
@ -858,6 +860,7 @@ void msm_pm_set_max_sleep_time(int64_t max_sleep_time_ns)
|
||||
EXPORT_SYMBOL(msm_pm_set_max_sleep_time);
|
||||
|
||||
#ifdef CONFIG_EARLYSUSPEND
|
||||
#ifdef CONFIG_AXI_SCREEN_POLICY
|
||||
/* axi 128 screen on, 61mhz screen off */
|
||||
static void axi_early_suspend(struct early_suspend *handler)
|
||||
{
|
||||
@ -877,7 +880,9 @@ static struct early_suspend axi_screen_suspend = {
|
||||
.resume = axi_late_resume,
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_AXI_SCREEN_POLICY
|
||||
static void __init msm_pm_axi_init(void)
|
||||
{
|
||||
#ifdef CONFIG_EARLYSUSPEND
|
||||
@ -895,19 +900,18 @@ static void __init msm_pm_axi_init(void)
|
||||
axi_rate = 0;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static int __init msm_pm_init(void)
|
||||
{
|
||||
pm_power_off = msm_pm_power_off;
|
||||
arm_pm_restart = msm_pm_restart;
|
||||
msm_pm_max_sleep_time = 0;
|
||||
#if defined(CONFIG_ARCH_MSM_SCORPION)
|
||||
#ifdef CONFIG_AXI_SCREEN_POLICY
|
||||
msm_pm_axi_init();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
register_reboot_notifier(&msm_reboot_notifier);
|
||||
|
||||
msm_pm_reset_vector = ioremap(0x0, PAGE_SIZE);
|
||||
|
||||
#if defined(CONFIG_MACH_HTCLEO)
|
||||
|
@ -14,6 +14,7 @@
|
||||
*
|
||||
*/
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/module.h>
|
||||
#include "devices.h"
|
||||
#include "proc_comm.h"
|
||||
|
||||
|
@ -188,6 +188,12 @@ static void sirc_irq_handler(unsigned int irq, struct irq_desc *desc)
|
||||
(sirc_reg_table[reg].cascade_irq != irq))
|
||||
reg++;
|
||||
|
||||
if (reg == ARRAY_SIZE(sirc_reg_table)) {
|
||||
printk(KERN_ERR "%s: incorrect irq %d called\n",
|
||||
__func__, irq);
|
||||
return;
|
||||
}
|
||||
|
||||
status = readl(sirc_reg_table[reg].int_status);
|
||||
status &= SIRC_MASK;
|
||||
if (status == 0)
|
||||
|
@ -381,17 +381,18 @@ static void update_packet_state(struct smd_channel *ch)
|
||||
int r;
|
||||
|
||||
/* can't do anything if we're in the middle of a packet */
|
||||
if (ch->current_packet != 0)
|
||||
return;
|
||||
while (ch->current_packet == 0) {
|
||||
/* discard 0 length packets if any */
|
||||
|
||||
/* don't bother unless we can get the full header */
|
||||
if (smd_stream_read_avail(ch) < SMD_HEADER_SIZE)
|
||||
return;
|
||||
/* don't bother unless we can get the full header */
|
||||
if (smd_stream_read_avail(ch) < SMD_HEADER_SIZE)
|
||||
return;
|
||||
|
||||
r = ch_read(ch, hdr, SMD_HEADER_SIZE);
|
||||
BUG_ON(r != SMD_HEADER_SIZE);
|
||||
r = ch_read(ch, hdr, SMD_HEADER_SIZE);
|
||||
BUG_ON(r != SMD_HEADER_SIZE);
|
||||
|
||||
ch->current_packet = hdr[0];
|
||||
ch->current_packet = hdr[0];
|
||||
}
|
||||
}
|
||||
|
||||
/* provide a pointer and length to next free space in the fifo */
|
||||
@ -490,7 +491,7 @@ static void handle_smd_irq(struct list_head *list, void (*notify)(void))
|
||||
#ifdef CONFIG_BUILD_CIQ
|
||||
/* put here to make sure we got the disable/enable index */
|
||||
if (!msm_smd_ciq_info)
|
||||
msm_smd_ciq_info = (*(volatile uint32_t *)(MSM_SHARED_RAM_BASE + 0xFC11C));
|
||||
msm_smd_ciq_info = (*(volatile uint32_t *)(MSM_SHARED_RAM_BASE + SMD_CIQ_BASE));
|
||||
#endif
|
||||
spin_lock_irqsave(&smd_lock, flags);
|
||||
list_for_each_entry(ch, list, ch_list) {
|
||||
@ -641,6 +642,8 @@ static int smd_stream_write(smd_channel_t *ch, const void *_data, int len)
|
||||
|
||||
if (len < 0)
|
||||
return -EINVAL;
|
||||
else if (len == 0)
|
||||
return 0;
|
||||
|
||||
while ((xfer = ch_write_buffer(ch, &ptr)) != 0) {
|
||||
if (!ch_is_open(ch))
|
||||
@ -911,6 +914,7 @@ int smd_close(smd_channel_t *ch)
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(smd_close);
|
||||
|
||||
int smd_read(smd_channel_t *ch, void *data, int len)
|
||||
{
|
||||
@ -922,6 +926,7 @@ int smd_write(smd_channel_t *ch, const void *data, int len)
|
||||
{
|
||||
return ch->write(ch, data, len);
|
||||
}
|
||||
EXPORT_SYMBOL(smd_write);
|
||||
|
||||
int smd_write_atomic(smd_channel_t *ch, const void *data, int len)
|
||||
{
|
||||
@ -944,6 +949,7 @@ int smd_write_avail(smd_channel_t *ch)
|
||||
{
|
||||
return ch->write_avail(ch);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(smd_write_avail);
|
||||
|
||||
int smd_wait_until_readable(smd_channel_t *ch, int bytes)
|
||||
{
|
||||
@ -981,6 +987,11 @@ int smd_cur_packet_size(smd_channel_t *ch)
|
||||
}
|
||||
EXPORT_SYMBOL(smd_cur_packet_size);
|
||||
|
||||
/* Returns SMD buffer size */
|
||||
int smd_total_fifo_size(smd_channel_t *ch)
|
||||
{
|
||||
return ch->fifo_size;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
|
@ -89,6 +89,33 @@ struct smsm_interrupt_info {
|
||||
};
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_MSM_N_WAY_SMSM)
|
||||
enum {
|
||||
SMSM_APPS_STATE,
|
||||
SMSM_MODEM_STATE,
|
||||
SMSM_Q6_STATE,
|
||||
SMSM_APPS_DEM,
|
||||
SMSM_MODEM_DEM,
|
||||
SMSM_Q6_DEM,
|
||||
SMSM_POWER_MASTER_DEM,
|
||||
SMSM_TIME_MASTER_DEM,
|
||||
SMSM_NUM_ENTRIES,
|
||||
};
|
||||
#else
|
||||
enum {
|
||||
SMSM_APPS_STATE = 1,
|
||||
SMSM_MODEM_STATE = 3,
|
||||
SMSM_NUM_ENTRIES,
|
||||
};
|
||||
#endif
|
||||
|
||||
enum {
|
||||
SMSM_APPS,
|
||||
SMSM_MODEM,
|
||||
SMSM_Q6,
|
||||
SMSM_NUM_HOSTS,
|
||||
};
|
||||
|
||||
#define SZ_DIAG_ERR_MSG 0xC8
|
||||
#define ID_DIAG_ERR_MSG SMEM_DIAG_ERR_MESSAGE
|
||||
#define ID_SMD_CHANNELS SMEM_SMD_BASE_ID
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/cdev.h>
|
||||
@ -105,7 +106,7 @@ static struct wake_lock rpcrouter_wake_lock;
|
||||
static int rpcrouter_need_len;
|
||||
|
||||
static atomic_t next_xid = ATOMIC_INIT(1);
|
||||
static uint8_t next_pacmarkid;
|
||||
static atomic_t next_mid = ATOMIC_INIT(0);
|
||||
|
||||
static void do_read_data(struct work_struct *work);
|
||||
static void do_create_pdevs(struct work_struct *work);
|
||||
@ -114,12 +115,16 @@ static void do_create_rpcrouter_pdev(struct work_struct *work);
|
||||
static DECLARE_WORK(work_read_data, do_read_data);
|
||||
static DECLARE_WORK(work_create_pdevs, do_create_pdevs);
|
||||
static DECLARE_WORK(work_create_rpcrouter_pdev, do_create_rpcrouter_pdev);
|
||||
static atomic_t rpcrouter_pdev_created = ATOMIC_INIT(0);
|
||||
|
||||
#define RR_STATE_IDLE 0
|
||||
#define RR_STATE_HEADER 1
|
||||
#define RR_STATE_BODY 2
|
||||
#define RR_STATE_ERROR 3
|
||||
|
||||
#define RMT_STORAGE_APIPROG_BE32 0xa7000030
|
||||
#define RMT_STORAGE_SRV_APIPROG_BE32 0x9c000030
|
||||
|
||||
struct rr_context {
|
||||
struct rr_packet *pkt;
|
||||
uint8_t *ptr;
|
||||
@ -262,6 +267,7 @@ struct msm_rpc_endpoint *msm_rpcrouter_create_local_endpoint(dev_t dev)
|
||||
{
|
||||
struct msm_rpc_endpoint *ept;
|
||||
unsigned long flags;
|
||||
int i;
|
||||
|
||||
ept = kmalloc(sizeof(struct msm_rpc_endpoint), GFP_KERNEL);
|
||||
if (!ept)
|
||||
@ -269,7 +275,9 @@ struct msm_rpc_endpoint *msm_rpcrouter_create_local_endpoint(dev_t dev)
|
||||
memset(ept, 0, sizeof(struct msm_rpc_endpoint));
|
||||
|
||||
/* mark no reply outstanding */
|
||||
ept->reply_pid = 0xffffffff;
|
||||
ept->next_rroute = 0;
|
||||
for (i = 0; i < MAX_REPLY_ROUTE; i++)
|
||||
ept->rroute[i].pid = 0xffffffff;
|
||||
|
||||
ept->cid = (uint32_t) ept;
|
||||
ept->pid = RPCROUTER_PID_LOCAL;
|
||||
@ -530,7 +538,8 @@ static int process_control_msg(union rr_control_msg *msg, int len)
|
||||
|
||||
static void do_create_rpcrouter_pdev(struct work_struct *work)
|
||||
{
|
||||
platform_device_register(&rpcrouter_pdev);
|
||||
if (atomic_cmpxchg(&rpcrouter_pdev_created, 0, 1) == 0)
|
||||
platform_device_register(&rpcrouter_pdev);
|
||||
}
|
||||
|
||||
static void do_create_pdevs(struct work_struct *work)
|
||||
@ -652,11 +661,13 @@ static void do_read_data(struct work_struct *work)
|
||||
|
||||
hdr.size -= sizeof(pm);
|
||||
|
||||
frag = rr_malloc(hdr.size + sizeof(*frag));
|
||||
frag = rr_malloc(sizeof(*frag));
|
||||
frag->next = NULL;
|
||||
frag->length = hdr.size;
|
||||
if (rr_read(frag->data, hdr.size))
|
||||
if (rr_read(frag->data, hdr.size)) {
|
||||
kfree(frag);
|
||||
goto fail_io;
|
||||
}
|
||||
|
||||
ept = rpcrouter_lookup_local_endpoint(hdr.dst_cid);
|
||||
if (!ept) {
|
||||
@ -758,19 +769,77 @@ int msm_rpc_close(struct msm_rpc_endpoint *ept)
|
||||
}
|
||||
EXPORT_SYMBOL(msm_rpc_close);
|
||||
|
||||
static int msm_rpc_write_pkt(struct msm_rpc_endpoint *ept,
|
||||
struct rr_remote_endpoint *r_ept,
|
||||
struct rr_header *hdr,
|
||||
uint32_t pacmark,
|
||||
void *buffer, int count)
|
||||
{
|
||||
DEFINE_WAIT(__wait);
|
||||
unsigned long flags;
|
||||
int needed;
|
||||
|
||||
for (;;) {
|
||||
prepare_to_wait(&r_ept->quota_wait, &__wait,
|
||||
TASK_INTERRUPTIBLE);
|
||||
spin_lock_irqsave(&r_ept->quota_lock, flags);
|
||||
if (r_ept->tx_quota_cntr < RPCROUTER_DEFAULT_RX_QUOTA)
|
||||
break;
|
||||
if (signal_pending(current) &&
|
||||
(!(ept->flags & MSM_RPC_UNINTERRUPTIBLE)))
|
||||
break;
|
||||
spin_unlock_irqrestore(&r_ept->quota_lock, flags);
|
||||
schedule();
|
||||
}
|
||||
finish_wait(&r_ept->quota_wait, &__wait);
|
||||
|
||||
if (signal_pending(current) &&
|
||||
(!(ept->flags & MSM_RPC_UNINTERRUPTIBLE))) {
|
||||
spin_unlock_irqrestore(&r_ept->quota_lock, flags);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
r_ept->tx_quota_cntr++;
|
||||
if (r_ept->tx_quota_cntr == RPCROUTER_DEFAULT_RX_QUOTA)
|
||||
hdr->confirm_rx = 1;
|
||||
|
||||
spin_unlock_irqrestore(&r_ept->quota_lock, flags);
|
||||
|
||||
spin_lock_irqsave(&smd_lock, flags);
|
||||
|
||||
needed = sizeof(*hdr) + hdr->size;
|
||||
while (smd_write_avail(smd_channel) < needed) {
|
||||
spin_unlock_irqrestore(&smd_lock, flags);
|
||||
msleep(250);
|
||||
spin_lock_irqsave(&smd_lock, flags);
|
||||
}
|
||||
|
||||
/* TODO: deal with full fifo */
|
||||
smd_write(smd_channel, hdr, sizeof(*hdr));
|
||||
smd_write(smd_channel, &pacmark, sizeof(pacmark));
|
||||
smd_write(smd_channel, buffer, count);
|
||||
|
||||
spin_unlock_irqrestore(&smd_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int msm_rpc_write(struct msm_rpc_endpoint *ept, void *buffer, int count)
|
||||
{
|
||||
struct rr_header hdr;
|
||||
uint32_t pacmark;
|
||||
uint32_t mid;
|
||||
struct rpc_request_hdr *rq = buffer;
|
||||
struct rr_remote_endpoint *r_ept;
|
||||
unsigned long flags;
|
||||
int needed;
|
||||
DEFINE_WAIT(__wait);
|
||||
int ret;
|
||||
int total;
|
||||
|
||||
/* TODO: fragmentation for large outbound packets */
|
||||
if (count > (RPCROUTER_MSGSIZE_MAX - sizeof(uint32_t)) || !count)
|
||||
return -EINVAL;
|
||||
if (((rq->prog&0xFFFFFFF0) == RMT_STORAGE_APIPROG_BE32) ||
|
||||
((rq->prog&0xFFFFFFF0) == RMT_STORAGE_SRV_APIPROG_BE32)) {
|
||||
printk(KERN_DEBUG
|
||||
"rpc_write: prog = %x , procedure = %d, type = %d, xid = %d\n"
|
||||
, be32_to_cpu(rq->prog), be32_to_cpu(rq->procedure)
|
||||
, be32_to_cpu(rq->type), be32_to_cpu(rq->xid));
|
||||
}
|
||||
|
||||
/* snoop the RPC packet and enforce permissions */
|
||||
|
||||
@ -818,23 +887,21 @@ int msm_rpc_write(struct msm_rpc_endpoint *ept, void *buffer, int count)
|
||||
} else {
|
||||
/* RPC REPLY */
|
||||
/* TODO: locking */
|
||||
if (ept->reply_pid == 0xffffffff) {
|
||||
printk(KERN_ERR
|
||||
"rr_write: rejecting unexpected reply\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (ept->reply_xid != rq->xid) {
|
||||
printk(KERN_ERR
|
||||
"rr_write: rejecting packet w/ bad xid\n");
|
||||
return -EINVAL;
|
||||
for (ret = 0; ret < MAX_REPLY_ROUTE; ret++)
|
||||
if (ept->rroute[ret].xid == rq->xid) {
|
||||
if (ept->rroute[ret].pid == 0xffffffff)
|
||||
continue;
|
||||
hdr.dst_pid = ept->rroute[ret].pid;
|
||||
hdr.dst_cid = ept->rroute[ret].cid;
|
||||
/* consume this reply */
|
||||
ept->rroute[ret].pid = 0xffffffff;
|
||||
goto found_rroute;
|
||||
}
|
||||
|
||||
hdr.dst_pid = ept->reply_pid;
|
||||
hdr.dst_cid = ept->reply_cid;
|
||||
|
||||
/* consume this reply */
|
||||
ept->reply_pid = 0xffffffff;
|
||||
printk(KERN_ERR "rr_write: rejecting packet w/ bad xid\n");
|
||||
return -EINVAL;
|
||||
|
||||
found_rroute:
|
||||
IO("REPLY on ept %p to xid=%d @ %d:%08x (%d bytes)\n",
|
||||
ept,
|
||||
be32_to_cpu(rq->xid), hdr.dst_pid, hdr.dst_cid, count);
|
||||
@ -854,56 +921,36 @@ int msm_rpc_write(struct msm_rpc_endpoint *ept, void *buffer, int count)
|
||||
hdr.version = RPCROUTER_VERSION;
|
||||
hdr.src_pid = ept->pid;
|
||||
hdr.src_cid = ept->cid;
|
||||
hdr.confirm_rx = 0;
|
||||
hdr.size = count + sizeof(uint32_t);
|
||||
|
||||
for (;;) {
|
||||
prepare_to_wait(&r_ept->quota_wait, &__wait,
|
||||
TASK_INTERRUPTIBLE);
|
||||
spin_lock_irqsave(&r_ept->quota_lock, flags);
|
||||
if (r_ept->tx_quota_cntr < RPCROUTER_DEFAULT_RX_QUOTA)
|
||||
break;
|
||||
if (signal_pending(current) &&
|
||||
(!(ept->flags & MSM_RPC_UNINTERRUPTIBLE)))
|
||||
break;
|
||||
spin_unlock_irqrestore(&r_ept->quota_lock, flags);
|
||||
schedule();
|
||||
}
|
||||
finish_wait(&r_ept->quota_wait, &__wait);
|
||||
total = count;
|
||||
|
||||
if (signal_pending(current) &&
|
||||
(!(ept->flags & MSM_RPC_UNINTERRUPTIBLE))) {
|
||||
spin_unlock_irqrestore(&r_ept->quota_lock, flags);
|
||||
return -ERESTARTSYS;
|
||||
}
|
||||
r_ept->tx_quota_cntr++;
|
||||
if (r_ept->tx_quota_cntr == RPCROUTER_DEFAULT_RX_QUOTA)
|
||||
hdr.confirm_rx = 1;
|
||||
mid = atomic_add_return(1, &next_mid) & 0xFF;
|
||||
|
||||
/* bump pacmark while interrupts disabled to avoid race
|
||||
* probably should be atomic op instead
|
||||
*/
|
||||
pacmark = PACMARK(count, ++next_pacmarkid, 0, 1);
|
||||
while (count > 0) {
|
||||
unsigned xfer;
|
||||
|
||||
spin_unlock_irqrestore(&r_ept->quota_lock, flags);
|
||||
if (count > RPCROUTER_DATASIZE_MAX)
|
||||
xfer = RPCROUTER_DATASIZE_MAX;
|
||||
else
|
||||
xfer = count;
|
||||
|
||||
spin_lock_irqsave(&smd_lock, flags);
|
||||
hdr.confirm_rx = 0;
|
||||
hdr.size = xfer + sizeof(uint32_t);
|
||||
|
||||
needed = sizeof(hdr) + hdr.size;
|
||||
while (smd_write_avail(smd_channel) < needed) {
|
||||
spin_unlock_irqrestore(&smd_lock, flags);
|
||||
msleep(250);
|
||||
spin_lock_irqsave(&smd_lock, flags);
|
||||
/* total == count -> must be first packet
|
||||
* xfer == count -> must be last packet
|
||||
*/
|
||||
pacmark = PACMARK(xfer, mid, (total == count), (xfer == count));
|
||||
|
||||
ret = msm_rpc_write_pkt(ept, r_ept, &hdr, pacmark, buffer, xfer);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
buffer += xfer;
|
||||
count -= xfer;
|
||||
}
|
||||
|
||||
/* TODO: deal with full fifo */
|
||||
smd_write(smd_channel, &hdr, sizeof(hdr));
|
||||
smd_write(smd_channel, &pacmark, sizeof(pacmark));
|
||||
smd_write(smd_channel, buffer, count);
|
||||
|
||||
spin_unlock_irqrestore(&smd_lock, flags);
|
||||
|
||||
return count;
|
||||
return total;
|
||||
}
|
||||
EXPORT_SYMBOL(msm_rpc_write);
|
||||
|
||||
@ -1104,20 +1151,30 @@ int __msm_rpc_read(struct msm_rpc_endpoint *ept,
|
||||
|
||||
*frag_ret = pkt->first;
|
||||
rq = (void*) pkt->first->data;
|
||||
|
||||
if (((rq->prog&0xFFFFFFF0) == RMT_STORAGE_APIPROG_BE32) ||
|
||||
((rq->prog&0xFFFFFFF0) == RMT_STORAGE_SRV_APIPROG_BE32)) {
|
||||
printk(KERN_DEBUG
|
||||
"rpc_read: prog = %x , procedure = %d, type = %d, xid = %d\n"
|
||||
, be32_to_cpu(rq->prog), be32_to_cpu(rq->procedure)
|
||||
, be32_to_cpu(rq->type), be32_to_cpu(rq->xid));
|
||||
}
|
||||
|
||||
if ((rc >= (sizeof(uint32_t) * 3)) && (rq->type == 0)) {
|
||||
IO("READ on ept %p is a CALL on %08x:%08x proc %d xid %d\n",
|
||||
ept, be32_to_cpu(rq->prog), be32_to_cpu(rq->vers),
|
||||
be32_to_cpu(rq->procedure),
|
||||
be32_to_cpu(rq->xid));
|
||||
/* RPC CALL */
|
||||
if (ept->reply_pid != 0xffffffff) {
|
||||
if (ept->rroute[ept->next_rroute].pid != 0xffffffff) {
|
||||
printk(KERN_WARNING
|
||||
"rr_read: lost previous reply xid...\n");
|
||||
}
|
||||
/* TODO: locking? */
|
||||
ept->reply_pid = pkt->hdr.src_pid;
|
||||
ept->reply_cid = pkt->hdr.src_cid;
|
||||
ept->reply_xid = rq->xid;
|
||||
ept->rroute[ept->next_rroute].pid = pkt->hdr.src_pid;
|
||||
ept->rroute[ept->next_rroute].cid = pkt->hdr.src_cid;
|
||||
ept->rroute[ept->next_rroute].xid = rq->xid;
|
||||
ept->next_rroute = (ept->next_rroute + 1) & (MAX_REPLY_ROUTE - 1);
|
||||
}
|
||||
#if TRACE_RPC_MSG
|
||||
else if ((rc >= (sizeof(uint32_t) * 3)) && (rq->type == 1))
|
||||
|
@ -32,6 +32,7 @@
|
||||
#define RPCROUTER_VERSION 1
|
||||
#define RPCROUTER_PROCESSORS_MAX 4
|
||||
#define RPCROUTER_MSGSIZE_MAX 512
|
||||
#define RPCROUTER_DATASIZE_MAX 500
|
||||
#if defined(CONFIG_ARCH_MSM7X30)
|
||||
#define RPCROUTER_PEND_REPLIES_MAX 32
|
||||
#endif
|
||||
@ -50,6 +51,7 @@
|
||||
#define RPCROUTER_CTRL_CMD_REMOVE_CLIENT 6
|
||||
#define RPCROUTER_CTRL_CMD_RESUME_TX 7
|
||||
#define RPCROUTER_CTRL_CMD_EXIT 8
|
||||
#define RPCROUTER_CTRL_CMD_PING 9
|
||||
|
||||
#define RPCROUTER_DEFAULT_RX_QUOTA 5
|
||||
|
||||
@ -141,6 +143,15 @@ struct rr_remote_endpoint {
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct msm_reply_route {
|
||||
uint32_t xid;
|
||||
uint32_t pid;
|
||||
uint32_t cid;
|
||||
uint32_t unused;
|
||||
};
|
||||
|
||||
#define MAX_REPLY_ROUTE 4
|
||||
|
||||
#if defined(CONFIG_ARCH_MSM7X30)
|
||||
struct msm_rpc_reply {
|
||||
struct list_head list;
|
||||
@ -183,15 +194,12 @@ struct msm_rpc_endpoint {
|
||||
uint32_t dst_prog; /* be32 */
|
||||
uint32_t dst_vers; /* be32 */
|
||||
|
||||
/* reply remote address
|
||||
* if reply_pid == 0xffffffff, none available
|
||||
* RPC_REPLY writes may only go to the pid/cid/xid of the
|
||||
* last RPC_CALL we received.
|
||||
/* RPC_REPLY writes must be routed to the pid/cid of the
|
||||
* RPC_CALL they are in reply to. Keep a cache of valid
|
||||
* xid/pid/cid groups. pid 0xffffffff -> not valid.
|
||||
*/
|
||||
uint32_t reply_pid;
|
||||
uint32_t reply_cid;
|
||||
uint32_t reply_xid; /* be32 */
|
||||
uint32_t next_pm; /* Pacmark sequence */
|
||||
unsigned next_rroute;
|
||||
struct msm_reply_route rroute[MAX_REPLY_ROUTE];
|
||||
|
||||
#if defined(CONFIG_ARCH_MSM7X30)
|
||||
/* reply queue for inbound messages */
|
||||
@ -224,6 +232,7 @@ void msm_rpcrouter_exit_devices(void);
|
||||
#if defined(CONFIG_ARCH_MSM7X30)
|
||||
void get_requesting_client(struct msm_rpc_endpoint *ept, uint32_t xid,
|
||||
struct msm_rpc_client_info *clnt_info);
|
||||
int msm_rpc_clear_netreset(struct msm_rpc_endpoint *ept);
|
||||
#endif
|
||||
|
||||
extern dev_t msm_rpcrouter_devno;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <linux/fs.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/msm_rpcrouter.h>
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/cdev.h>
|
||||
|
@ -78,6 +78,8 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <mach/msm_rpcrouter.h>
|
||||
|
||||
@ -421,7 +423,7 @@ int xdr_send_msg(struct msm_rpc_xdr *xdr)
|
||||
void xdr_init(struct msm_rpc_xdr *xdr)
|
||||
{
|
||||
mutex_init(&xdr->out_lock);
|
||||
mutex_init(&xdr->in_lock);
|
||||
init_waitqueue_head(&xdr->in_buf_wait_q);
|
||||
|
||||
xdr->in_buf = NULL;
|
||||
xdr->in_size = 0;
|
||||
@ -434,7 +436,7 @@ void xdr_init(struct msm_rpc_xdr *xdr)
|
||||
|
||||
void xdr_init_input(struct msm_rpc_xdr *xdr, void *buf, uint32_t size)
|
||||
{
|
||||
mutex_lock(&xdr->in_lock);
|
||||
wait_event(xdr->in_buf_wait_q, !(xdr->in_buf));
|
||||
|
||||
xdr->in_buf = buf;
|
||||
xdr->in_size = size;
|
||||
@ -455,7 +457,7 @@ void xdr_clean_input(struct msm_rpc_xdr *xdr)
|
||||
xdr->in_size = 0;
|
||||
xdr->in_index = 0;
|
||||
|
||||
mutex_unlock(&xdr->in_lock);
|
||||
wake_up(&xdr->in_buf_wait_q);
|
||||
}
|
||||
|
||||
void xdr_clean_output(struct msm_rpc_xdr *xdr)
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "board-htcleo.h"
|
||||
|
||||
#define MAX_SMD_TTYS 32
|
||||
#define MAX_TTY_BUF_SIZE 2048
|
||||
|
||||
static DEFINE_MUTEX(smd_tty_lock);
|
||||
|
||||
@ -75,6 +76,9 @@ static void smd_tty_work_func(struct work_struct *work)
|
||||
tty->low_latency = 0;
|
||||
tty_flip_buffer_push(tty);
|
||||
break;
|
||||
if (avail > MAX_TTY_BUF_SIZE)
|
||||
avail = MAX_TTY_BUF_SIZE;
|
||||
|
||||
}
|
||||
|
||||
ptr = NULL;
|
||||
|
@ -169,18 +169,10 @@ static int msm_timer_set_next_event(unsigned long cycles,
|
||||
clock->last_set = now;
|
||||
clock->alarm_vtime = alarm + clock->offset;
|
||||
late = now - alarm;
|
||||
if (late >= (int)(-clock->write_delay << clock->shift) && late < DGT_HZ*5) {
|
||||
static int print_limit = 10;
|
||||
if (print_limit > 0) {
|
||||
print_limit--;
|
||||
printk(KERN_NOTICE "msm_timer_set_next_event(%lu) "
|
||||
"clock %s, alarm already expired, now %x, "
|
||||
"alarm %x, late %d%s\n",
|
||||
cycles, clock->clockevent.name, now, alarm, late,
|
||||
print_limit ? "" : " stop printing");
|
||||
}
|
||||
if (late >= (int)(-clock->write_delay << clock->shift) &&
|
||||
late < clock->freq*5)
|
||||
return -ETIME;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -582,9 +574,12 @@ static struct msm_clock msm_clocks[] = {
|
||||
#endif
|
||||
.freq = GPT_HZ,
|
||||
.flags =
|
||||
#ifdef CONFIG_ARCH_MSM_ARM11
|
||||
MSM_CLOCK_FLAGS_UNSTABLE_COUNT |
|
||||
MSM_CLOCK_FLAGS_ODD_MATCH_WRITE |
|
||||
MSM_CLOCK_FLAGS_DELAYED_WRITE_POST,
|
||||
MSM_CLOCK_FLAGS_DELAYED_WRITE_POST |
|
||||
#endif
|
||||
0,
|
||||
.write_delay = 9,
|
||||
},
|
||||
[MSM_CLOCK_DGT] = {
|
||||
|
2
drivers/misc/pmem.c
Normal file → Executable file
2
drivers/misc/pmem.c
Normal file → Executable file
@ -4386,4 +4386,4 @@ static void __exit pmem_exit(void)
|
||||
module_init(pmem_init);
|
||||
module_exit(pmem_exit);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
@ -33,12 +33,15 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/moduleparam.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/dma.h>
|
||||
#include <asm/mach/flash.h>
|
||||
|
||||
#include <mach/dma.h>
|
||||
|
||||
unsigned crci_mask;
|
||||
|
||||
#if defined(CONFIG_ARCH_MSM7X30)
|
||||
#define MSM_NAND_BASE 0xA0200000
|
||||
#else
|
||||
@ -178,6 +181,11 @@ static void *msm_nand_get_dma_buffer(struct msm_nand_chip *chip, size_t size)
|
||||
do {
|
||||
free_index = __ffs(free_bitmask);
|
||||
current_need_mask = need_mask << free_index;
|
||||
|
||||
if (size + free_index * MSM_NAND_DMA_BUFFER_SLOTS >=
|
||||
MSM_NAND_DMA_BUFFER_SIZE)
|
||||
return NULL;
|
||||
|
||||
if ((bitmask & current_need_mask) == 0) {
|
||||
old_bitmask =
|
||||
atomic_cmpxchg(&chip->dma_buffer_busy,
|
||||
@ -262,7 +270,7 @@ uint32_t flash_read_id(struct msm_nand_chip *chip)
|
||||
|
||||
dsb();
|
||||
msm_dmov_exec_cmd(
|
||||
chip->dma_channel, DMOV_CMD_PTR_LIST |
|
||||
chip->dma_channel, crci_mask, DMOV_CMD_PTR_LIST |
|
||||
DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
|
||||
dsb();
|
||||
|
||||
@ -306,7 +314,7 @@ int flash_read_config(struct msm_nand_chip *chip)
|
||||
|
||||
dsb();
|
||||
msm_dmov_exec_cmd(
|
||||
chip->dma_channel, DMOV_CMD_PTR_LIST |
|
||||
chip->dma_channel, crci_mask, DMOV_CMD_PTR_LIST |
|
||||
DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
|
||||
dsb();
|
||||
|
||||
@ -346,7 +354,7 @@ unsigned flash_rd_reg(struct msm_nand_chip *chip, unsigned addr)
|
||||
|
||||
dsb();
|
||||
msm_dmov_exec_cmd(
|
||||
chip->dma_channel, DMOV_CMD_PTR_LIST |
|
||||
chip->dma_channel, crci_mask, DMOV_CMD_PTR_LIST |
|
||||
DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
|
||||
dsb();
|
||||
rv = dma_buffer->data;
|
||||
@ -379,7 +387,7 @@ void flash_wr_reg(struct msm_nand_chip *chip, unsigned addr, unsigned val)
|
||||
|
||||
dsb();
|
||||
msm_dmov_exec_cmd(
|
||||
chip->dma_channel, DMOV_CMD_PTR_LIST |
|
||||
chip->dma_channel, crci_mask, DMOV_CMD_PTR_LIST |
|
||||
DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
|
||||
dsb();
|
||||
|
||||
@ -750,7 +758,7 @@ static int msm_nand_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_o
|
||||
|
||||
dsb();
|
||||
msm_dmov_exec_cmd(
|
||||
chip->dma_channel, DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(
|
||||
chip->dma_channel, crci_mask, DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(
|
||||
msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
|
||||
dsb();
|
||||
|
||||
@ -893,13 +901,13 @@ static int msm_nand_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_o
|
||||
dma_buffer->data.result[2].buffer_status,
|
||||
dma_buffer->data.result[3].flash_status,
|
||||
dma_buffer->data.result[3].buffer_status,
|
||||
dma_buffer->data.result[4].flash_status,
|
||||
dma_buffer->data.result[4].buffer_status,
|
||||
dma_buffer->data.result[4].buffer_status,
|
||||
dma_buffer->data.result[5].buffer_status,
|
||||
dma_buffer->data.result[5].flash_status,
|
||||
dma_buffer->data.result[5].buffer_status,
|
||||
dma_buffer->data.result[6].flash_status,
|
||||
dma_buffer->data.result[6].buffer_status,
|
||||
dma_buffer->data.result[6].buffer_status,
|
||||
dma_buffer->data.result[7].buffer_status,
|
||||
dma_buffer->data.result[7].flash_status,
|
||||
dma_buffer->data.result[7].buffer_status);
|
||||
}
|
||||
#endif
|
||||
@ -1364,7 +1372,7 @@ msm_nand_write_oob(struct mtd_info *mtd, loff_t to, struct mtd_oob_ops *ops)
|
||||
dma_buffer->cmdptr = (msm_virt_to_dma(chip, dma_buffer->cmd) >> 3) | CMD_PTR_LP;
|
||||
|
||||
dsb();
|
||||
msm_dmov_exec_cmd(chip->dma_channel, DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
|
||||
msm_dmov_exec_cmd(chip->dma_channel, crci_mask, DMOV_CMD_PTR_LIST | DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
|
||||
dsb();
|
||||
|
||||
/* if any of the writes failed (0x10), or there was a
|
||||
@ -1576,7 +1584,7 @@ msm_nand_erase(struct mtd_info *mtd, struct erase_info *instr)
|
||||
|
||||
dsb();
|
||||
msm_dmov_exec_cmd(
|
||||
chip->dma_channel, DMOV_CMD_PTR_LIST |
|
||||
chip->dma_channel, crci_mask, DMOV_CMD_PTR_LIST |
|
||||
DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
|
||||
dsb();
|
||||
|
||||
@ -1727,7 +1735,7 @@ msm_nand_block_isbad(struct mtd_info *mtd, loff_t ofs)
|
||||
dma_buffer->cmd) >> 3) | CMD_PTR_LP;
|
||||
|
||||
dsb();
|
||||
msm_dmov_exec_cmd(chip->dma_channel, DMOV_CMD_PTR_LIST |
|
||||
msm_dmov_exec_cmd(chip->dma_channel, crci_mask, DMOV_CMD_PTR_LIST |
|
||||
DMOV_CMD_ADDR(msm_virt_to_dma(chip, &dma_buffer->cmdptr)));
|
||||
dsb();
|
||||
|
||||
|
@ -697,9 +697,9 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
|
||||
struct inode *inode = file->f_path.dentry->d_inode;
|
||||
int fbidx = iminor(inode);
|
||||
struct fb_info *info = registered_fb[fbidx];
|
||||
u32 *buffer, *dst;
|
||||
u32 __iomem *src;
|
||||
int c, i, cnt = 0, err = 0;
|
||||
u8 *buffer, *dst;
|
||||
u8 __iomem *src;
|
||||
int c, cnt = 0, err = 0;
|
||||
unsigned long total_size;
|
||||
|
||||
if (!info || ! info->screen_base)
|
||||
@ -730,7 +730,7 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
|
||||
if (!buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
src = (u32 __iomem *) (info->screen_base + p);
|
||||
src = (u8 __iomem *) (info->screen_base + p);
|
||||
|
||||
if (info->fbops->fb_sync)
|
||||
info->fbops->fb_sync(info);
|
||||
@ -738,17 +738,9 @@ fb_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
|
||||
while (count) {
|
||||
c = (count > PAGE_SIZE) ? PAGE_SIZE : count;
|
||||
dst = buffer;
|
||||
for (i = c >> 2; i--; )
|
||||
*dst++ = fb_readl(src++);
|
||||
if (c & 3) {
|
||||
u8 *dst8 = (u8 *) dst;
|
||||
u8 __iomem *src8 = (u8 __iomem *) src;
|
||||
|
||||
for (i = c & 3; i--;)
|
||||
*dst8++ = fb_readb(src8++);
|
||||
|
||||
src = (u32 __iomem *) src8;
|
||||
}
|
||||
fb_memcpy_fromfb(dst, src, c);
|
||||
dst += c;
|
||||
src += c;
|
||||
|
||||
if (copy_to_user(buf, buffer, c)) {
|
||||
err = -EFAULT;
|
||||
@ -772,9 +764,9 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
|
||||
struct inode *inode = file->f_path.dentry->d_inode;
|
||||
int fbidx = iminor(inode);
|
||||
struct fb_info *info = registered_fb[fbidx];
|
||||
u32 *buffer, *src;
|
||||
u32 __iomem *dst;
|
||||
int c, i, cnt = 0, err = 0;
|
||||
u8 *buffer, *src;
|
||||
u8 __iomem *dst;
|
||||
int c, cnt = 0, err = 0;
|
||||
unsigned long total_size;
|
||||
|
||||
if (!info || !info->screen_base)
|
||||
@ -811,7 +803,7 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
|
||||
if (!buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
dst = (u32 __iomem *) (info->screen_base + p);
|
||||
dst = (u8 __iomem *) (info->screen_base + p);
|
||||
|
||||
if (info->fbops->fb_sync)
|
||||
info->fbops->fb_sync(info);
|
||||
@ -825,19 +817,9 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = c >> 2; i--; )
|
||||
fb_writel(*src++, dst++);
|
||||
|
||||
if (c & 3) {
|
||||
u8 *src8 = (u8 *) src;
|
||||
u8 __iomem *dst8 = (u8 __iomem *) dst;
|
||||
|
||||
for (i = c & 3; i--; )
|
||||
fb_writeb(*src8++, dst8++);
|
||||
|
||||
dst = (u32 __iomem *) dst8;
|
||||
}
|
||||
|
||||
fb_memcpy_tofb(dst, src, c);
|
||||
dst += c;
|
||||
src += c;
|
||||
*ppos += c;
|
||||
buf += c;
|
||||
cnt += c;
|
||||
@ -877,13 +859,13 @@ fb_pan_display(struct fb_info *info, struct fb_var_screeninfo *var)
|
||||
|
||||
if ((err = info->fbops->fb_pan_display(var, info)))
|
||||
return err;
|
||||
info->var.xoffset = var->xoffset;
|
||||
info->var.yoffset = var->yoffset;
|
||||
if (var->vmode & FB_VMODE_YWRAP)
|
||||
info->var.vmode |= FB_VMODE_YWRAP;
|
||||
else
|
||||
info->var.vmode &= ~FB_VMODE_YWRAP;
|
||||
return 0;
|
||||
info->var.xoffset = var->xoffset;
|
||||
info->var.yoffset = var->yoffset;
|
||||
if (var->vmode & FB_VMODE_YWRAP)
|
||||
info->var.vmode |= FB_VMODE_YWRAP;
|
||||
else
|
||||
info->var.vmode &= ~FB_VMODE_YWRAP;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fb_check_caps(struct fb_info *info, struct fb_var_screeninfo *var,
|
||||
@ -1438,6 +1420,7 @@ static const struct file_operations fb_fops = {
|
||||
#ifdef CONFIG_FB_DEFERRED_IO
|
||||
.fsync = fb_deferred_io_fsync,
|
||||
#endif
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
struct class *fb_class;
|
||||
@ -1468,16 +1451,70 @@ static int fb_check_foreignness(struct fb_info *fi)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static bool fb_do_apertures_overlap(struct fb_info *gen, struct fb_info *hw)
|
||||
static bool apertures_overlap(struct aperture *gen, struct aperture *hw)
|
||||
{
|
||||
/* is the generic aperture base the same as the HW one */
|
||||
if (gen->aperture_base == hw->aperture_base)
|
||||
if (gen->base == hw->base)
|
||||
return true;
|
||||
/* is the generic aperture base inside the hw base->hw base+size */
|
||||
if (gen->aperture_base > hw->aperture_base && gen->aperture_base <= hw->aperture_base + hw->aperture_size)
|
||||
if (gen->base > hw->base && gen->base < hw->base + hw->size)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool fb_do_apertures_overlap(struct apertures_struct *gena,
|
||||
struct apertures_struct *hwa)
|
||||
{
|
||||
int i, j;
|
||||
if (!hwa || !gena)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < hwa->count; ++i) {
|
||||
struct aperture *h = &hwa->ranges[i];
|
||||
for (j = 0; j < gena->count; ++j) {
|
||||
struct aperture *g = &gena->ranges[j];
|
||||
printk(KERN_DEBUG "checking generic (%llx %llx) vs hw (%llx %llx)\n",
|
||||
(unsigned long long)g->base,
|
||||
(unsigned long long)g->size,
|
||||
(unsigned long long)h->base,
|
||||
(unsigned long long)h->size);
|
||||
if (apertures_overlap(g, h))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#define VGA_FB_PHYS 0xA0000
|
||||
void remove_conflicting_framebuffers(struct apertures_struct *a,
|
||||
const char *name, bool primary)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* check all firmware fbs and kick off if the base addr overlaps */
|
||||
for (i = 0 ; i < FB_MAX; i++) {
|
||||
struct apertures_struct *gen_aper;
|
||||
if (!registered_fb[i])
|
||||
continue;
|
||||
|
||||
if (!(registered_fb[i]->flags & FBINFO_MISC_FIRMWARE))
|
||||
continue;
|
||||
|
||||
gen_aper = registered_fb[i]->apertures;
|
||||
if (fb_do_apertures_overlap(gen_aper, a) ||
|
||||
(primary && gen_aper && gen_aper->count &&
|
||||
gen_aper->ranges[0].base == VGA_FB_PHYS)) {
|
||||
|
||||
printk(KERN_ERR "fb: conflicting fb hw usage "
|
||||
"%s vs %s - removing generic driver\n",
|
||||
name, registered_fb[i]->fix.id);
|
||||
unregister_framebuffer(registered_fb[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(remove_conflicting_framebuffers);
|
||||
|
||||
/**
|
||||
* register_framebuffer - registers a frame buffer device
|
||||
* @fb_info: frame buffer info structure
|
||||
|
100
drivers/video/msm/Kconfig
Normal file → Executable file
100
drivers/video/msm/Kconfig
Normal file → Executable file
@ -1,3 +1,26 @@
|
||||
config FB_MSM
|
||||
tristate "MSM Framebuffer"
|
||||
depends on FB && ARCH_MSM
|
||||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
default y
|
||||
|
||||
config FB_MSM_MDP_PPP
|
||||
bool "MSM MDP PPP"
|
||||
depends on FB_MSM_LEGACY_MDP
|
||||
default y
|
||||
|
||||
config FB_MSM_LCDC
|
||||
bool "Support for integrated LCD controller in MDP3/4"
|
||||
depends on FB_MSM && (MSM_MDP31 || MSM_MDP302 || MSM_MDP40)
|
||||
default y
|
||||
|
||||
config FB_MSM_MDDI
|
||||
bool "Support for MSM MDDI controllers"
|
||||
depends on FB_MSM
|
||||
default y
|
||||
|
||||
config FB_MSM
|
||||
tristate
|
||||
depends on FB && ARCH_MSM
|
||||
@ -6,70 +29,35 @@ config FB_MSM
|
||||
select FB_CFB_IMAGEBLIT
|
||||
default y
|
||||
|
||||
config FB_MSM_LEGACY_MDP
|
||||
bool "MSM Legacy MDP (qsd8k)"
|
||||
depends on FB_MSM && (MSM_MDP30 || MSM_MDP31 || MSM_MDP302)
|
||||
default y
|
||||
|
||||
config FB_MSM_MDP_PPP
|
||||
bool "MSM MDP PPP"
|
||||
depends on FB_MSM_LEGACY_MDP
|
||||
default y
|
||||
|
||||
config FB_MSM_LCDC
|
||||
bool "Support for integrated LCD controller in qsd8x50 and MSM7x27"
|
||||
depends on FB_MSM && (MSM_MDP31 || MSM_MDP302)
|
||||
bool "Support for integrated LCD controller in qsd8x50 ,MSM7x27 and MSM7x30"
|
||||
depends on FB_MSM && (MSM_MDP31 || MSM_MDP302 || MSM_MDP40)
|
||||
default y
|
||||
|
||||
config FB_MSM_TVOUT
|
||||
bool "Support for TV-Out in qsd8x50"
|
||||
depends on FB_MSM && MSM_MDP31
|
||||
default n
|
||||
|
||||
config FB_MSM_OVERLAY
|
||||
bool "Support for overlay in MSM7X30"
|
||||
depends on FB_MSM && MSM_MDP40
|
||||
config FB_MSM_MDDI
|
||||
bool "Support for MSM MDDI controllers"
|
||||
depends on FB_MSM
|
||||
default y
|
||||
|
||||
config FB_MSM_DTV
|
||||
depends on FB_MSM_OVERLAY
|
||||
bool
|
||||
config FB_MSM_MDDI_EPSON
|
||||
bool "Support for Epson MDDI panels"
|
||||
depends on FB_MSM_MDDI
|
||||
default n
|
||||
|
||||
config GPU_MSM_KGSL
|
||||
tristate "MSM 3D Graphics driver for QSD8x50 and MSM7x27"
|
||||
config FB_MSM_MDDI_NOVTEC
|
||||
bool "Support for Novtec MDDI panels"
|
||||
depends on FB_MSM_MDDI
|
||||
default n
|
||||
depends on FB_MSM && (ARCH_QSD8X50 || ARCH_MSM7227 || ARCH_MSM7X30)
|
||||
select GENERIC_ALLOCATOR
|
||||
select CONFIG_FW_LOADER
|
||||
help
|
||||
3D graphics driver for QSD8x50 and MSM7x27. Required to
|
||||
use hardware accelerated OpenGL ES 2.0 and 1.1 on these
|
||||
chips.
|
||||
|
||||
config MSM_ROTATOR
|
||||
tristate "MSM Offline Image Rotator Driver"
|
||||
depends on ARCH_MSM7X30 && ANDROID_PMEM
|
||||
default y
|
||||
help
|
||||
This driver provides support for the image rotator HW block in the
|
||||
MSM 7x30 SoC.
|
||||
|
||||
config MSM_ROTATOR_USE_IMEM
|
||||
bool "Enable rotator driver to use iMem"
|
||||
depends on MSM_ROTATOR
|
||||
default y
|
||||
help
|
||||
This option enables the msm_rotator driver to use the move efficient
|
||||
iMem. Some MSM platforms may not have iMem available for the rotator
|
||||
block. Or some systems may want the iMem to be dedicated to a
|
||||
different function.
|
||||
|
||||
config GPU_MSM_KGSL_MMU
|
||||
bool "Turn on MMU for graphics driver "
|
||||
depends on GPU_MSM_KGSL && MMU
|
||||
default n
|
||||
help
|
||||
If enabled, the GPU driver will allocate memory from vmalloc
|
||||
and enable the use of GPU MMU, instead of using pmem.
|
||||
|
||||
config MSM_KGSL_PER_FD_PAGETABLE
|
||||
bool "Turn on per-fd pagetable for MMU of graphics driver "
|
||||
depends on MSM_KGSL_MMU && MMU
|
||||
default n
|
||||
help
|
||||
If enabled, the MMU unit of GPU driver will use seperate
|
||||
pagetables for each file descriptor
|
||||
|
||||
config MSM_HDMI
|
||||
bool "Support for HDMI in QCT platform"
|
||||
|
11
drivers/video/msm/Makefile
Normal file → Executable file
11
drivers/video/msm/Makefile
Normal file → Executable file
@ -1,7 +1,7 @@
|
||||
|
||||
# core framebuffer
|
||||
#
|
||||
obj-y := msm_fb.o logo.o
|
||||
obj-y := msm_fb.o
|
||||
ifeq ($(CONFIG_FB_MSM_LOGO),y)
|
||||
obj-y += logo.o
|
||||
endif
|
||||
@ -14,6 +14,8 @@ obj-$(CONFIG_FB_MSM_OVERLAY) += mdp4_overlay.o
|
||||
obj-$(CONFIG_FB_MSM_OVERLAY) += mdp4_overlay_mddi.o
|
||||
obj-$(CONFIG_MSM_MDP40) += msm_rotator.o
|
||||
|
||||
obj-$(CONFIG_FB_MSM_LEGACY_MDP) += mdp_hw_legacy.o
|
||||
|
||||
obj-$(CONFIG_MSM_MDP22) += mdp_ppp22.o
|
||||
obj-$(CONFIG_MSM_MDP30) += mdp_ppp22.o
|
||||
obj-$(CONFIG_MSM_MDP302)+= mdp_ppp22.o
|
||||
@ -25,13 +27,10 @@ obj-y += mddi.o
|
||||
|
||||
# MDDI client/panel drivers
|
||||
#
|
||||
obj-y += mddi_client_dummy.o
|
||||
obj-y += mddi_client_simple.o
|
||||
obj-y += mddi_client_toshiba.o
|
||||
obj-y += mddi_client_epson.o
|
||||
obj-y += mddi_client_novb9f6_5582.o
|
||||
|
||||
# MDP LCD controller driver
|
||||
obj-$(CONFIG_FB_MSM_LCDC) += mdp_lcdc.o
|
||||
obj-$(CONFIG_FB_MSM_TVOUT) += tvenc.o tvfb.o
|
||||
|
||||
# Yamato GL driver
|
||||
obj-$(CONFIG_GPU_MSM_KGSL) += gpu/kgsl/
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,12 +0,0 @@
|
||||
---- CONFIG_MSM_KGSL_MMU Matches (11 in 6 files) ----
|
||||
kgsl.c (\\jupiter\xinwang\hd2\kernel\msm8x50\20120427A\dorimanx-Dorimanx-HD2-2.6.32.X-69084da_hwa_mix\drivers\video\msm\gpu\kgsl):#ifdef CONFIG_MSM_KGSL_MMU
|
||||
kgsl.c (\\jupiter\xinwang\hd2\kernel\msm8x50\20120427A\dorimanx-Dorimanx-HD2-2.6.32.X-69084da_hwa_mix\drivers\video\msm\gpu\kgsl):#ifdef CONFIG_MSM_KGSL_MMU
|
||||
kgsl.c (\\jupiter\xinwang\hd2\kernel\msm8x50\20120427A\dorimanx-Dorimanx-HD2-2.6.32.X-69084da_hwa_mix\drivers\video\msm\gpu\kgsl):#ifdef CONFIG_MSM_KGSL_MMU
|
||||
kgsl_device.h (\\jupiter\xinwang\hd2\kernel\msm8x50\20120427A\dorimanx-Dorimanx-HD2-2.6.32.X-69084da_hwa_mix\drivers\video\msm\gpu\kgsl):#ifdef CONFIG_MSM_KGSL_MMU
|
||||
kgsl_log.c (\\jupiter\xinwang\hd2\kernel\msm8x50\20120427A\dorimanx-Dorimanx-HD2-2.6.32.X-69084da_hwa_mix\drivers\video\msm\gpu\kgsl):#ifdef CONFIG_MSM_KGSL_MMU
|
||||
kgsl_log.c (\\jupiter\xinwang\hd2\kernel\msm8x50\20120427A\dorimanx-Dorimanx-HD2-2.6.32.X-69084da_hwa_mix\drivers\video\msm\gpu\kgsl):#ifdef CONFIG_MSM_KGSL_MMU
|
||||
kgsl_mmu.c (\\jupiter\xinwang\hd2\kernel\msm8x50\20120427A\dorimanx-Dorimanx-HD2-2.6.32.X-69084da_hwa_mix\drivers\video\msm\gpu\kgsl):#ifndef CONFIG_MSM_KGSL_MMU
|
||||
kgsl_mmu.c (\\jupiter\xinwang\hd2\kernel\msm8x50\20120427A\dorimanx-Dorimanx-HD2-2.6.32.X-69084da_hwa_mix\drivers\video\msm\gpu\kgsl):#ifdef CONFIG_MSM_KGSL_MMU
|
||||
kgsl_mmu.h (\\jupiter\xinwang\hd2\kernel\msm8x50\20120427A\dorimanx-Dorimanx-HD2-2.6.32.X-69084da_hwa_mix\drivers\video\msm\gpu\kgsl):#ifdef CONFIG_MSM_KGSL_MMU
|
||||
kgsl_yamato.c (\\jupiter\xinwang\hd2\kernel\msm8x50\20120427A\dorimanx-Dorimanx-HD2-2.6.32.X-69084da_hwa_mix\drivers\video\msm\gpu\kgsl):#ifdef CONFIG_MSM_KGSL_MMU
|
||||
kgsl_yamato.c (\\jupiter\xinwang\hd2\kernel\msm8x50\20120427A\dorimanx-Dorimanx-HD2-2.6.32.X-69084da_hwa_mix\drivers\video\msm\gpu\kgsl):#ifdef CONFIG_MSM_KGSL_MMU
|
@ -1,11 +0,0 @@
|
||||
msm_kgsl-objs = \
|
||||
kgsl_drawctxt.o \
|
||||
kgsl_cmdstream.o \
|
||||
kgsl.o \
|
||||
kgsl_log.o \
|
||||
kgsl_mmu.o \
|
||||
kgsl_ringbuffer.o \
|
||||
kgsl_sharedmem.o \
|
||||
kgsl_yamato.o
|
||||
|
||||
obj-$(CONFIG_GPU_MSM_KGSL) += msm_kgsl.o
|
File diff suppressed because it is too large
Load Diff
@ -1,84 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2009 QUALCOMM USA, INC.
|
||||
*
|
||||
* All source code in this file is licensed under the following license
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can find it at http://www.fsf.org
|
||||
*/
|
||||
#ifndef _GSL_DRIVER_H
|
||||
#define _GSL_DRIVER_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/msm_kgsl.h>
|
||||
#include <linux/miscdevice.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/wakelock.h>
|
||||
|
||||
#include <asm/atomic.h>
|
||||
|
||||
#include "kgsl_device.h"
|
||||
#include "kgsl_sharedmem.h"
|
||||
|
||||
#define DRIVER_NAME "kgsl"
|
||||
|
||||
struct kgsl_driver {
|
||||
struct miscdevice misc;
|
||||
struct platform_device *pdev;
|
||||
atomic_t open_count;
|
||||
struct mutex mutex;
|
||||
|
||||
int interrupt_num;
|
||||
int have_irq;
|
||||
|
||||
struct clk *grp_clk;
|
||||
struct clk *grp_pclk;
|
||||
struct clk *imem_clk;
|
||||
struct clk *ebi1_clk;
|
||||
|
||||
struct kgsl_devconfig yamato_config;
|
||||
|
||||
uint32_t flags_debug;
|
||||
|
||||
struct kgsl_sharedmem shmem;
|
||||
struct kgsl_device yamato_device;
|
||||
|
||||
struct list_head client_list;
|
||||
|
||||
bool active;
|
||||
int active_cnt;
|
||||
struct timer_list standby_timer;
|
||||
|
||||
struct wake_lock wake_lock;
|
||||
};
|
||||
|
||||
extern struct kgsl_driver kgsl_driver;
|
||||
|
||||
struct kgsl_mem_entry {
|
||||
struct kgsl_memdesc memdesc;
|
||||
struct file *pmem_file;
|
||||
struct list_head list;
|
||||
struct list_head free_list;
|
||||
uint32_t free_timestamp;
|
||||
|
||||
/* back pointer to private structure under whose context this
|
||||
* allocation is made */
|
||||
struct kgsl_file_private *priv;
|
||||
};
|
||||
|
||||
void kgsl_remove_mem_entry(struct kgsl_mem_entry *entry);
|
||||
|
||||
#endif /* _GSL_DRIVER_H */
|
@ -1,105 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2008-2009 QUALCOMM USA, INC.
|
||||
*
|
||||
* All source code in this file is licensed under the following license
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can find it at http://www.fsf.org
|
||||
*/
|
||||
|
||||
#include "kgsl.h"
|
||||
#include "kgsl_device.h"
|
||||
#include "kgsl_cmdstream.h"
|
||||
#include "kgsl_sharedmem.h"
|
||||
|
||||
int kgsl_cmdstream_init(struct kgsl_device *device)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kgsl_cmdstream_close(struct kgsl_device *device)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
kgsl_cmdstream_readtimestamp(struct kgsl_device *device,
|
||||
enum kgsl_timestamp_type type)
|
||||
{
|
||||
uint32_t timestamp = 0;
|
||||
|
||||
KGSL_CMD_VDBG("enter (device_id=%d, type=%d)\n", device->id, type);
|
||||
|
||||
if (type == KGSL_TIMESTAMP_CONSUMED)
|
||||
KGSL_CMDSTREAM_GET_SOP_TIMESTAMP(device,
|
||||
(unsigned int *)×tamp);
|
||||
else if (type == KGSL_TIMESTAMP_RETIRED)
|
||||
KGSL_CMDSTREAM_GET_EOP_TIMESTAMP(device,
|
||||
(unsigned int *)×tamp);
|
||||
|
||||
rmb();
|
||||
|
||||
KGSL_CMD_VDBG("return %d\n", timestamp);
|
||||
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
int kgsl_cmdstream_check_timestamp(struct kgsl_device *device,
|
||||
unsigned int timestamp)
|
||||
{
|
||||
unsigned int ts_processed;
|
||||
|
||||
ts_processed = kgsl_cmdstream_readtimestamp(device,
|
||||
KGSL_TIMESTAMP_RETIRED);
|
||||
return timestamp_cmp(ts_processed, timestamp);
|
||||
}
|
||||
|
||||
void kgsl_cmdstream_memqueue_drain(struct kgsl_device *device)
|
||||
{
|
||||
struct kgsl_mem_entry *entry, *entry_tmp;
|
||||
uint32_t ts_processed;
|
||||
struct kgsl_ringbuffer *rb = &device->ringbuffer;
|
||||
|
||||
/* get current EOP timestamp */
|
||||
ts_processed =
|
||||
kgsl_cmdstream_readtimestamp(device, KGSL_TIMESTAMP_RETIRED);
|
||||
|
||||
list_for_each_entry_safe(entry, entry_tmp, &rb->memqueue, free_list) {
|
||||
/*NOTE: this assumes that the free list is sorted by
|
||||
* timestamp, but I'm not yet sure that it is a valid
|
||||
* assumption
|
||||
*/
|
||||
if (!timestamp_cmp(ts_processed, entry->free_timestamp))
|
||||
break;
|
||||
KGSL_MEM_DBG("ts_processed %d ts_free %d gpuaddr %x)\n",
|
||||
ts_processed, entry->free_timestamp,
|
||||
entry->memdesc.gpuaddr);
|
||||
kgsl_remove_mem_entry(entry);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
kgsl_cmdstream_freememontimestamp(struct kgsl_device *device,
|
||||
struct kgsl_mem_entry *entry,
|
||||
uint32_t timestamp,
|
||||
enum kgsl_timestamp_type type)
|
||||
{
|
||||
struct kgsl_ringbuffer *rb = &device->ringbuffer;
|
||||
KGSL_MEM_DBG("enter (dev %p gpuaddr %x ts %d)\n",
|
||||
device, entry->memdesc.gpuaddr, timestamp);
|
||||
(void)type; /* unref. For now just use EOP timestamp */
|
||||
|
||||
list_add_tail(&entry->free_list, &rb->memqueue);
|
||||
entry->free_timestamp = timestamp;
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
#ifndef __KGSL_CMDSTREAM_H
|
||||
#define __KGSL_CMDSTREAM_H
|
||||
|
||||
#include <linux/msm_kgsl.h>
|
||||
#include "kgsl_device.h"
|
||||
#include "kgsl_log.h"
|
||||
|
||||
#ifdef KGSL_DEVICE_SHADOW_MEMSTORE_TO_USER
|
||||
#define KGSL_CMDSTREAM_USE_MEM_TIMESTAMP
|
||||
#endif /* KGSL_DEVICE_SHADOW_MEMSTORE_TO_USER */
|
||||
|
||||
#ifdef KGSL_CMDSTREAM_USE_MEM_TIMESTAMP
|
||||
#define KGSL_CMDSTREAM_GET_SOP_TIMESTAMP(device, data) \
|
||||
kgsl_sharedmem_read(&device->memstore, (data), \
|
||||
KGSL_DEVICE_MEMSTORE_OFFSET(soptimestamp), 4)
|
||||
#else
|
||||
#define KGSL_CMDSTREAM_GET_SOP_TIMESTAMP(device, data) \
|
||||
kgsl_yamato_regread(device, REG_CP_TIMESTAMP, (data))
|
||||
#endif /* KGSL_CMDSTREAM_USE_MEM_TIMESTAMP */
|
||||
|
||||
#define KGSL_CMDSTREAM_GET_EOP_TIMESTAMP(device, data) \
|
||||
kgsl_sharedmem_read(&device->memstore, (data), \
|
||||
KGSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp), 4)
|
||||
|
||||
/* Flags to control command packet settings */
|
||||
#define KGSL_CMD_FLAGS_PMODE 0x00000001
|
||||
#define KGSL_CMD_FLAGS_NO_TS_CMP 0x00000002
|
||||
|
||||
int kgsl_cmdstream_init(struct kgsl_device *device);
|
||||
|
||||
int kgsl_cmdstream_close(struct kgsl_device *device);
|
||||
|
||||
void kgsl_cmdstream_memqueue_drain(struct kgsl_device *device);
|
||||
|
||||
uint32_t
|
||||
kgsl_cmdstream_readtimestamp(struct kgsl_device *device,
|
||||
enum kgsl_timestamp_type type);
|
||||
|
||||
int kgsl_cmdstream_check_timestamp(struct kgsl_device *device,
|
||||
unsigned int timestamp);
|
||||
|
||||
int
|
||||
kgsl_cmdstream_freememontimestamp(struct kgsl_device *device,
|
||||
struct kgsl_mem_entry *entry,
|
||||
uint32_t timestamp,
|
||||
enum kgsl_timestamp_type type);
|
||||
|
||||
static inline bool timestamp_cmp(unsigned int new, unsigned int old)
|
||||
{
|
||||
int ts_diff = new - old;
|
||||
return (ts_diff >= 0) || (ts_diff < -20000);
|
||||
}
|
||||
|
||||
#endif /* __KGSL_CMDSTREAM_H */
|
@ -1,141 +0,0 @@
|
||||
/*
|
||||
* (C) Copyright Advanced Micro Devices, Inc. 2002, 2007
|
||||
* Copyright (c) 2008-2009 QUALCOMM USA, INC.
|
||||
*
|
||||
* All source code in this file is licensed under the following license
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can find it at http://www.fsf.org
|
||||
*/
|
||||
#ifndef _KGSL_DEVICE_H
|
||||
#define _KGSL_DEVICE_H
|
||||
|
||||
#include <asm/atomic.h>
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/irqreturn.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/msm_kgsl.h>
|
||||
|
||||
#include "kgsl_drawctxt.h"
|
||||
#include "kgsl_mmu.h"
|
||||
#include "kgsl_ringbuffer.h"
|
||||
|
||||
#define KGSL_CONTEXT_MAX 8
|
||||
|
||||
#define KGSL_TIMEOUT_NONE 0
|
||||
#define KGSL_TIMEOUT_DEFAULT 0xFFFFFFFF
|
||||
|
||||
#define KGSL_DEV_FLAGS_INITIALIZED0 0x00000001
|
||||
#define KGSL_DEV_FLAGS_INITIALIZED 0x00000002
|
||||
#define KGSL_DEV_FLAGS_STARTED 0x00000004
|
||||
#define KGSL_DEV_FLAGS_ACTIVE 0x00000008
|
||||
|
||||
#define KGSL_CHIPID_YAMATODX_REV21 0x20100
|
||||
#define KGSL_CHIPID_YAMATODX_REV211 0x20101
|
||||
|
||||
/* Private memory flags for use with memdesc->priv feild */
|
||||
#define KGSL_MEMFLAGS_MEM_REQUIRES_FLUSH 0x00000001
|
||||
#define KGSL_MEMFLAGS_VMALLOC_MEM 0x00000002
|
||||
|
||||
#define KGSL_GRAPHICS_MEMORY_LOW_WATERMARK 0x1000000
|
||||
#define KGSL_IS_PAGE_ALIGNED(addr) (!((addr) & (~PAGE_MASK)))
|
||||
|
||||
struct kgsl_device;
|
||||
struct platform_device;
|
||||
|
||||
|
||||
struct kgsl_memregion {
|
||||
unsigned char *mmio_virt_base;
|
||||
unsigned int mmio_phys_base;
|
||||
uint32_t gpu_base;
|
||||
unsigned int sizebytes;
|
||||
};
|
||||
|
||||
struct kgsl_device {
|
||||
|
||||
unsigned int refcnt;
|
||||
uint32_t flags;
|
||||
enum kgsl_deviceid id;
|
||||
unsigned int chip_id;
|
||||
struct kgsl_memregion regspace;
|
||||
struct kgsl_memdesc memstore;
|
||||
|
||||
struct kgsl_mmu mmu;
|
||||
struct kgsl_memregion gmemspace;
|
||||
struct kgsl_ringbuffer ringbuffer;
|
||||
unsigned int drawctxt_count;
|
||||
struct kgsl_drawctxt *drawctxt_active;
|
||||
struct kgsl_drawctxt drawctxt[KGSL_CONTEXT_MAX];
|
||||
|
||||
wait_queue_head_t ib1_wq;
|
||||
};
|
||||
|
||||
struct kgsl_devconfig {
|
||||
struct kgsl_memregion regspace;
|
||||
|
||||
unsigned int mmu_config;
|
||||
uint32_t mpu_base;
|
||||
int mpu_range;
|
||||
uint32_t va_base;
|
||||
unsigned int va_range;
|
||||
|
||||
struct kgsl_memregion gmemspace;
|
||||
};
|
||||
|
||||
int kgsl_yamato_start(struct kgsl_device *device, uint32_t flags);
|
||||
|
||||
int kgsl_yamato_stop(struct kgsl_device *device);
|
||||
|
||||
bool kgsl_yamato_is_idle(struct kgsl_device *device);
|
||||
|
||||
int kgsl_yamato_idle(struct kgsl_device *device, unsigned int timeout);
|
||||
|
||||
int kgsl_yamato_getproperty(struct kgsl_device *device,
|
||||
enum kgsl_property_type type, void *value,
|
||||
unsigned int sizebytes);
|
||||
|
||||
int kgsl_yamato_regread(struct kgsl_device *device, unsigned int offsetwords,
|
||||
unsigned int *value);
|
||||
|
||||
int kgsl_yamato_regwrite(struct kgsl_device *device, unsigned int offsetwords,
|
||||
unsigned int value);
|
||||
|
||||
int kgsl_yamato_waittimestamp(struct kgsl_device *device,
|
||||
unsigned int timestamp, unsigned int timeout);
|
||||
|
||||
|
||||
int kgsl_yamato_init(struct kgsl_device *, struct kgsl_devconfig *);
|
||||
|
||||
int kgsl_yamato_close(struct kgsl_device *device);
|
||||
|
||||
int kgsl_yamato_runpending(struct kgsl_device *device);
|
||||
|
||||
int __init kgsl_yamato_config(struct kgsl_devconfig *,
|
||||
struct platform_device *pdev);
|
||||
|
||||
void kgsl_register_dump(struct kgsl_device *device);
|
||||
|
||||
int kgsl_yamato_setup_pt(struct kgsl_device *device,
|
||||
struct kgsl_pagetable *pagetable);
|
||||
int kgsl_yamato_cleanup_pt(struct kgsl_device *device,
|
||||
struct kgsl_pagetable *pagetable);
|
||||
#ifdef CONFIG_GPU_MSM_KGSL_MMU
|
||||
int kgsl_yamato_setstate(struct kgsl_device *device, uint32_t flags);
|
||||
#else
|
||||
static inline int kgsl_yamato_setstate(struct kgsl_device *device, uint32_t flags)
|
||||
{ return 0; }
|
||||
#endif
|
||||
|
||||
irqreturn_t kgsl_yamato_isr(int irq, void *data);
|
||||
|
||||
#endif /* _KGSL_DEVICE_H */
|
File diff suppressed because it is too large
Load Diff
@ -1,120 +0,0 @@
|
||||
/*
|
||||
* (C) Copyright Advanced Micro Devices, Inc. 2002, 2007
|
||||
* Copyright (c) 2008-2009 QUALCOMM USA, INC.
|
||||
*
|
||||
* All source code in this file is licensed under the following license
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can find it at http://www.fsf.org
|
||||
*/
|
||||
#ifndef __GSL_DRAWCTXT_H
|
||||
#define __GSL_DRAWCTXT_H
|
||||
|
||||
/* Flags */
|
||||
|
||||
#define CTXT_FLAGS_NOT_IN_USE 0x00000000
|
||||
#define CTXT_FLAGS_IN_USE 0x00000001
|
||||
|
||||
/* state shadow memory allocated */
|
||||
#define CTXT_FLAGS_STATE_SHADOW 0x00000010
|
||||
|
||||
/* gmem shadow memory allocated */
|
||||
#define CTXT_FLAGS_GMEM_SHADOW 0x00000100
|
||||
/* gmem must be copied to shadow */
|
||||
#define CTXT_FLAGS_GMEM_SAVE 0x00000200
|
||||
/* gmem can be restored from shadow */
|
||||
#define CTXT_FLAGS_GMEM_RESTORE 0x00000400
|
||||
/* shader must be copied to shadow */
|
||||
#define CTXT_FLAGS_SHADER_SAVE 0x00002000
|
||||
/* shader can be restored from shadow */
|
||||
#define CTXT_FLAGS_SHADER_RESTORE 0x00004000
|
||||
|
||||
#include "kgsl_sharedmem.h"
|
||||
#include "yamato_reg.h"
|
||||
|
||||
#define KGSL_MAX_GMEM_SHADOW_BUFFERS 2
|
||||
|
||||
struct kgsl_device;
|
||||
|
||||
/* types */
|
||||
|
||||
/* draw context */
|
||||
struct gmem_shadow_t {
|
||||
struct kgsl_memdesc gmemshadow; /* Shadow buffer address */
|
||||
|
||||
/* 256 KB GMEM surface = 4 bytes-per-pixel x 256 pixels/row x
|
||||
* 256 rows. */
|
||||
/* width & height must be a multiples of 32, in case tiled textures
|
||||
* are used. */
|
||||
enum COLORFORMATX format;
|
||||
unsigned int size; /* Size of surface used to store GMEM */
|
||||
unsigned int width; /* Width of surface used to store GMEM */
|
||||
unsigned int height; /* Height of surface used to store GMEM */
|
||||
unsigned int pitch; /* Pitch of surface used to store GMEM */
|
||||
int offset;
|
||||
unsigned int offset_x;
|
||||
unsigned int offset_y;
|
||||
unsigned int gmem_offset_x;
|
||||
unsigned int gmem_offset_y;
|
||||
unsigned int gmem_pitch; /* Pitch value used for GMEM */
|
||||
unsigned int *gmem_save_commands;
|
||||
unsigned int *gmem_restore_commands;
|
||||
unsigned int gmem_save[3];
|
||||
unsigned int gmem_restore[3];
|
||||
struct kgsl_memdesc quad_vertices;
|
||||
struct kgsl_memdesc quad_texcoords;
|
||||
};
|
||||
|
||||
struct kgsl_drawctxt {
|
||||
uint32_t flags;
|
||||
struct kgsl_pagetable *pagetable;
|
||||
struct kgsl_memdesc gpustate;
|
||||
unsigned int reg_save[3];
|
||||
unsigned int reg_restore[3];
|
||||
unsigned int shader_save[3];
|
||||
unsigned int shader_fixup[3];
|
||||
unsigned int shader_restore[3];
|
||||
unsigned int chicken_restore[3];
|
||||
unsigned int bin_base_offset;
|
||||
/* Information of the GMEM shadow that is created in context create */
|
||||
struct gmem_shadow_t context_gmem_shadow;
|
||||
/* User defined GMEM shadow buffers */
|
||||
struct gmem_shadow_t user_gmem_shadow[KGSL_MAX_GMEM_SHADOW_BUFFERS];
|
||||
};
|
||||
|
||||
|
||||
int kgsl_drawctxt_create(struct kgsl_device *, struct kgsl_pagetable *,
|
||||
unsigned int flags,
|
||||
unsigned int *drawctxt_id);
|
||||
|
||||
int kgsl_drawctxt_destroy(struct kgsl_device *device, unsigned int drawctxt_id);
|
||||
|
||||
int kgsl_drawctxt_init(struct kgsl_device *device);
|
||||
|
||||
int kgsl_drawctxt_close(struct kgsl_device *device);
|
||||
|
||||
void kgsl_drawctxt_switch(struct kgsl_device *device,
|
||||
struct kgsl_drawctxt *drawctxt,
|
||||
unsigned int flags);
|
||||
int kgsl_drawctxt_bind_gmem_shadow(struct kgsl_device *device,
|
||||
unsigned int drawctxt_id,
|
||||
const struct kgsl_gmem_desc *gmem_desc,
|
||||
unsigned int shadow_x,
|
||||
unsigned int shadow_y,
|
||||
const struct kgsl_buffer_desc
|
||||
*shadow_buffer, unsigned int buffer_id);
|
||||
|
||||
int kgsl_drawctxt_set_bin_base_offset(struct kgsl_device *device,
|
||||
unsigned int drawctxt_id,
|
||||
unsigned int offset);
|
||||
|
||||
#endif /* __GSL_DRAWCTXT_H */
|
@ -1,292 +0,0 @@
|
||||
/*
|
||||
* (C) Copyright Advanced Micro Devices, Inc. 2002, 2008
|
||||
* Copyright (c) 2008-2009 QUALCOMM USA, INC.
|
||||
*
|
||||
* All source code in this file is licensed under the following license
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can find it at http://www.fsf.org
|
||||
*/
|
||||
#include <linux/debugfs.h>
|
||||
#include "kgsl_log.h"
|
||||
#include "kgsl_ringbuffer.h"
|
||||
#include "kgsl_device.h"
|
||||
#include "kgsl.h"
|
||||
|
||||
/*default log levels is error for everything*/
|
||||
#define KGSL_LOG_LEVEL_DEFAULT 3
|
||||
#define KGSL_LOG_LEVEL_MAX 7
|
||||
unsigned int kgsl_drv_log = KGSL_LOG_LEVEL_DEFAULT;
|
||||
unsigned int kgsl_cmd_log = KGSL_LOG_LEVEL_DEFAULT;
|
||||
unsigned int kgsl_ctxt_log = KGSL_LOG_LEVEL_DEFAULT;
|
||||
unsigned int kgsl_mem_log = KGSL_LOG_LEVEL_DEFAULT;
|
||||
|
||||
unsigned int kgsl_cache_enable;
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
static int kgsl_log_set(unsigned int *log_val, void *data, u64 val)
|
||||
{
|
||||
*log_val = min((unsigned int)val, (unsigned int)KGSL_LOG_LEVEL_MAX);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kgsl_drv_log_set(void *data, u64 val)
|
||||
{
|
||||
return kgsl_log_set(&kgsl_drv_log, data, val);
|
||||
}
|
||||
|
||||
static int kgsl_drv_log_get(void *data, u64 *val)
|
||||
{
|
||||
*val = kgsl_drv_log;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_ATTRIBUTE(kgsl_drv_log_fops, kgsl_drv_log_get,
|
||||
kgsl_drv_log_set, "%llu\n");
|
||||
|
||||
static int kgsl_cmd_log_set(void *data, u64 val)
|
||||
{
|
||||
return kgsl_log_set(&kgsl_cmd_log, data, val);
|
||||
}
|
||||
|
||||
static int kgsl_cmd_log_get(void *data, u64 *val)
|
||||
{
|
||||
*val = kgsl_cmd_log;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_ATTRIBUTE(kgsl_cmd_log_fops, kgsl_cmd_log_get,
|
||||
kgsl_cmd_log_set, "%llu\n");
|
||||
|
||||
static int kgsl_ctxt_log_set(void *data, u64 val)
|
||||
{
|
||||
return kgsl_log_set(&kgsl_ctxt_log, data, val);
|
||||
}
|
||||
|
||||
static int kgsl_ctxt_log_get(void *data, u64 *val)
|
||||
{
|
||||
*val = kgsl_ctxt_log;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_ATTRIBUTE(kgsl_ctxt_log_fops, kgsl_ctxt_log_get,
|
||||
kgsl_ctxt_log_set, "%llu\n");
|
||||
|
||||
static int kgsl_mem_log_set(void *data, u64 val)
|
||||
{
|
||||
return kgsl_log_set(&kgsl_mem_log, data, val);
|
||||
}
|
||||
|
||||
static int kgsl_mem_log_get(void *data, u64 *val)
|
||||
{
|
||||
*val = kgsl_mem_log;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_ATTRIBUTE(kgsl_mem_log_fops, kgsl_mem_log_get,
|
||||
kgsl_mem_log_set, "%llu\n");
|
||||
|
||||
#ifdef DEBUG
|
||||
static ssize_t rb_regs_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
file->private_data = inode->i_private;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t rb_regs_read(struct file *file, char __user *buf, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
const int debug_bufmax = 4096;
|
||||
static char buffer[4096];
|
||||
int n = 0;
|
||||
struct kgsl_device *device = NULL;
|
||||
struct kgsl_ringbuffer *rb = NULL;
|
||||
struct kgsl_rb_debug rb_debug;
|
||||
|
||||
device = &kgsl_driver.yamato_device;
|
||||
|
||||
rb = &device->ringbuffer;
|
||||
|
||||
kgsl_ringbuffer_debug(rb, &rb_debug);
|
||||
|
||||
n += scnprintf(buffer + n, debug_bufmax - n,
|
||||
"rbbm_status %08x mem_rptr %08x mem_wptr_poll %08x\n",
|
||||
rb_debug.rbbm_status,
|
||||
rb_debug.mem_rptr,
|
||||
rb_debug.mem_wptr_poll);
|
||||
|
||||
n += scnprintf(buffer + n, debug_bufmax - n,
|
||||
"rb_base %08x rb_cntl %08x rb_rptr_addr %08x"
|
||||
" rb_rptr %08x rb_rptr_wr %08x\n",
|
||||
rb_debug.cp_rb_base,
|
||||
rb_debug.cp_rb_cntl,
|
||||
rb_debug.cp_rb_rptr_addr,
|
||||
rb_debug.cp_rb_rptr,
|
||||
rb_debug.cp_rb_rptr_wr);
|
||||
|
||||
n += scnprintf(buffer + n, debug_bufmax - n,
|
||||
"rb_wptr %08x rb_wptr_delay %08x rb_wptr_base %08x"
|
||||
" ib1_base %08x ib1_bufsz %08x\n",
|
||||
rb_debug.cp_rb_wptr,
|
||||
rb_debug.cp_rb_wptr_delay,
|
||||
rb_debug.cp_rb_wptr_base,
|
||||
rb_debug.cp_ib1_base,
|
||||
rb_debug.cp_ib1_bufsz);
|
||||
|
||||
n += scnprintf(buffer + n, debug_bufmax - n,
|
||||
"ib2_base %08x ib2_bufsz %08x st_base %08x"
|
||||
" st_bufsz %08x cp_me_cntl %08x cp_me_status %08x\n",
|
||||
rb_debug.cp_ib2_base,
|
||||
rb_debug.cp_ib2_bufsz,
|
||||
rb_debug.cp_st_base,
|
||||
rb_debug.cp_st_bufsz,
|
||||
rb_debug.cp_me_cntl,
|
||||
rb_debug.cp_me_status);
|
||||
|
||||
n += scnprintf(buffer + n, debug_bufmax - n,
|
||||
"csq_cp_rb %08x csq_cp_ib1 %08x csq_cp_ib2 %08x\n",
|
||||
rb_debug.cp_csq_rb_stat,
|
||||
rb_debug.cp_csq_ib1_stat,
|
||||
rb_debug.cp_csq_ib2_stat);
|
||||
|
||||
n += scnprintf(buffer + n, debug_bufmax - n,
|
||||
"cp_debug %08x cp_stat %08x cp_int_status %08x"
|
||||
" cp_int_cntl %08x\n",
|
||||
rb_debug.cp_debug,
|
||||
rb_debug.cp_stat,
|
||||
rb_debug.cp_int_status,
|
||||
rb_debug.cp_int_cntl);
|
||||
|
||||
n += scnprintf(buffer + n, debug_bufmax - n,
|
||||
"sop_timestamp: %0d eop_timestamp: %d\n",
|
||||
rb_debug.sop_timestamp,
|
||||
rb_debug.eop_timestamp);
|
||||
n++;
|
||||
buffer[n] = 0;
|
||||
return simple_read_from_buffer(buf, count, ppos, buffer, n);
|
||||
}
|
||||
|
||||
static struct file_operations kgsl_rb_regs_fops = {
|
||||
.read = rb_regs_read,
|
||||
.open = rb_regs_open,
|
||||
};
|
||||
#endif /*DEBUG*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static ssize_t mmu_regs_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
file->private_data = inode->i_private;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t mmu_regs_read(struct file *file, char __user *buf, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
const int debug_bufmax = 4096;
|
||||
static char buffer[4096];
|
||||
int n = 0;
|
||||
struct kgsl_device *device = NULL;
|
||||
struct kgsl_mmu *mmu = NULL;
|
||||
struct kgsl_mmu_debug mmu_debug;
|
||||
|
||||
device = &kgsl_driver.yamato_device;
|
||||
|
||||
mmu = &device->mmu;
|
||||
|
||||
kgsl_mmu_debug(mmu, &mmu_debug);
|
||||
|
||||
n += scnprintf(buffer + n, debug_bufmax - n,
|
||||
"config %08x mpu_base %08x mpu_end %08x\n",
|
||||
mmu_debug.config,
|
||||
mmu_debug.mpu_base,
|
||||
mmu_debug.mpu_end);
|
||||
|
||||
n += scnprintf(buffer + n, debug_bufmax - n,
|
||||
"va_range %08x pt_base %08x\n",
|
||||
mmu_debug.va_range,
|
||||
mmu_debug.pt_base);
|
||||
|
||||
n += scnprintf(buffer + n, debug_bufmax - n,
|
||||
"page_fault %08x trans_error %08x axi_error %08x\n",
|
||||
mmu_debug.page_fault,
|
||||
mmu_debug.trans_error,
|
||||
mmu_debug.axi_error);
|
||||
|
||||
n += scnprintf(buffer + n, debug_bufmax - n,
|
||||
"interrupt_mask %08x interrupt_status %08x\n",
|
||||
mmu_debug.interrupt_mask,
|
||||
mmu_debug.interrupt_status);
|
||||
|
||||
n++;
|
||||
buffer[n] = 0;
|
||||
return simple_read_from_buffer(buf, count, ppos, buffer, n);
|
||||
}
|
||||
|
||||
static struct file_operations kgsl_mmu_regs_fops = {
|
||||
.read = mmu_regs_read,
|
||||
.open = mmu_regs_open,
|
||||
};
|
||||
#endif /*DEBUG*/
|
||||
|
||||
#ifdef CONFIG_GPU_MSM_KGSL_MMU
|
||||
static int kgsl_cache_enable_set(void *data, u64 val)
|
||||
{
|
||||
kgsl_cache_enable = (val != 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int kgsl_cache_enable_get(void *data, u64 *val)
|
||||
{
|
||||
*val = kgsl_cache_enable;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_ATTRIBUTE(kgsl_cache_enable_fops, kgsl_cache_enable_get,
|
||||
kgsl_cache_enable_set, "%llu\n");
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
|
||||
int kgsl_debug_init(void)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
struct dentry *dent;
|
||||
dent = debugfs_create_dir("kgsl", 0);
|
||||
if (IS_ERR(dent))
|
||||
return 0;
|
||||
|
||||
debugfs_create_file("log_level_cmd", 0644, dent, 0,
|
||||
&kgsl_cmd_log_fops);
|
||||
debugfs_create_file("log_level_ctxt", 0644, dent, 0,
|
||||
&kgsl_ctxt_log_fops);
|
||||
debugfs_create_file("log_level_drv", 0644, dent, 0,
|
||||
&kgsl_drv_log_fops);
|
||||
debugfs_create_file("log_level_mem", 0644, dent, 0,
|
||||
&kgsl_mem_log_fops);
|
||||
#ifdef DEBUG
|
||||
debugfs_create_file("rb_regs", 0444, dent, 0,
|
||||
&kgsl_rb_regs_fops);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
debugfs_create_file("mmu_regs", 0444, dent, 0,
|
||||
&kgsl_mmu_regs_fops);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_GPU_MSM_KGSL_MMU
|
||||
debugfs_create_file("cache_enable", 0644, dent, 0,
|
||||
&kgsl_cache_enable_fops);
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
return 0;
|
||||
}
|
@ -1,105 +0,0 @@
|
||||
/*
|
||||
* (C) Copyright Advanced Micro Devices, Inc. 2002, 2008
|
||||
* Copyright (c) 2008-2009 QUALCOMM USA, INC.
|
||||
*
|
||||
* All source code in this file is licensed under the following license
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can find it at http://www.fsf.org
|
||||
*/
|
||||
#ifndef _GSL_LOG_H
|
||||
#define _GSL_LOG_H
|
||||
|
||||
#include <linux/bug.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/msm_kgsl.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
extern unsigned int kgsl_drv_log;
|
||||
extern unsigned int kgsl_cmd_log;
|
||||
extern unsigned int kgsl_ctxt_log;
|
||||
extern unsigned int kgsl_mem_log;
|
||||
|
||||
struct device *kgsl_driver_getdevnode(void);
|
||||
int kgsl_debug_init(void);
|
||||
|
||||
#define KGSL_LOG_VDBG(lvl, fmt, args...) \
|
||||
do { \
|
||||
if ((lvl) >= 7) \
|
||||
dev_vdbg(kgsl_driver_getdevnode(), "|%s| " fmt, \
|
||||
__func__, ##args);\
|
||||
} while (0)
|
||||
|
||||
#define KGSL_LOG_DBG(lvl, fmt, args...) \
|
||||
do { \
|
||||
if ((lvl) >= 7) \
|
||||
dev_dbg(kgsl_driver_getdevnode(), "|%s| " fmt, \
|
||||
__func__, ##args);\
|
||||
} while (0)
|
||||
|
||||
#define KGSL_LOG_INFO(lvl, fmt, args...) \
|
||||
do { \
|
||||
if ((lvl) >= 6) \
|
||||
dev_info(kgsl_driver_getdevnode(), "|%s| " fmt, \
|
||||
__func__, ##args);\
|
||||
} while (0)
|
||||
|
||||
#define KGSL_LOG_WARN(lvl, fmt, args...) \
|
||||
do { \
|
||||
if ((lvl) >= 4) \
|
||||
dev_warn(kgsl_driver_getdevnode(), "|%s| " fmt, \
|
||||
__func__, ##args);\
|
||||
} while (0)
|
||||
|
||||
#define KGSL_LOG_ERR(lvl, fmt, args...) \
|
||||
do { \
|
||||
if ((lvl) >= 3) \
|
||||
dev_err(kgsl_driver_getdevnode(), "|%s| " fmt, \
|
||||
__func__, ##args);\
|
||||
} while (0)
|
||||
|
||||
#define KGSL_LOG_FATAL(lvl, fmt, args...) \
|
||||
do { \
|
||||
if ((lvl) >= 2) \
|
||||
dev_crit(kgsl_driver_getdevnode(), "|%s| " fmt, \
|
||||
__func__, ##args);\
|
||||
} while (0)
|
||||
|
||||
#define KGSL_DRV_VDBG(fmt, args...) KGSL_LOG_VDBG(kgsl_drv_log, fmt, ##args)
|
||||
#define KGSL_DRV_DBG(fmt, args...) KGSL_LOG_DBG(kgsl_drv_log, fmt, ##args)
|
||||
#define KGSL_DRV_INFO(fmt, args...) KGSL_LOG_INFO(kgsl_drv_log, fmt, ##args)
|
||||
#define KGSL_DRV_WARN(fmt, args...) KGSL_LOG_WARN(kgsl_drv_log, fmt, ##args)
|
||||
#define KGSL_DRV_ERR(fmt, args...) KGSL_LOG_ERR(kgsl_drv_log, fmt, ##args)
|
||||
#define KGSL_DRV_FATAL(fmt, args...) KGSL_LOG_FATAL(kgsl_drv_log, fmt, ##args)
|
||||
|
||||
#define KGSL_CMD_VDBG(fmt, args...) KGSL_LOG_VDBG(kgsl_cmd_log, fmt, ##args)
|
||||
#define KGSL_CMD_DBG(fmt, args...) KGSL_LOG_DBG(kgsl_cmd_log, fmt, ##args)
|
||||
#define KGSL_CMD_INFO(fmt, args...) KGSL_LOG_INFO(kgsl_cmd_log, fmt, ##args)
|
||||
#define KGSL_CMD_WARN(fmt, args...) KGSL_LOG_WARN(kgsl_cmd_log, fmt, ##args)
|
||||
#define KGSL_CMD_ERR(fmt, args...) KGSL_LOG_ERR(kgsl_cmd_log, fmt, ##args)
|
||||
#define KGSL_CMD_FATAL(fmt, args...) KGSL_LOG_FATAL(kgsl_cmd_log, fmt, ##args)
|
||||
|
||||
#define KGSL_CTXT_VDBG(fmt, args...) KGSL_LOG_VDBG(kgsl_ctxt_log, fmt, ##args)
|
||||
#define KGSL_CTXT_DBG(fmt, args...) KGSL_LOG_DBG(kgsl_ctxt_log, fmt, ##args)
|
||||
#define KGSL_CTXT_INFO(fmt, args...) KGSL_LOG_INFO(kgsl_ctxt_log, fmt, ##args)
|
||||
#define KGSL_CTXT_WARN(fmt, args...) KGSL_LOG_WARN(kgsl_ctxt_log, fmt, ##args)
|
||||
#define KGSL_CTXT_ERR(fmt, args...) KGSL_LOG_ERR(kgsl_ctxt_log, fmt, ##args)
|
||||
#define KGSL_CTXT_FATAL(fmt, args...) KGSL_LOG_FATAL(kgsl_ctxt_log, fmt, ##args)
|
||||
|
||||
#define KGSL_MEM_VDBG(fmt, args...) KGSL_LOG_VDBG(kgsl_mem_log, fmt, ##args)
|
||||
#define KGSL_MEM_DBG(fmt, args...) KGSL_LOG_DBG(kgsl_mem_log, fmt, ##args)
|
||||
#define KGSL_MEM_INFO(fmt, args...) KGSL_LOG_INFO(kgsl_mem_log, fmt, ##args)
|
||||
#define KGSL_MEM_WARN(fmt, args...) KGSL_LOG_WARN(kgsl_mem_log, fmt, ##args)
|
||||
#define KGSL_MEM_ERR(fmt, args...) KGSL_LOG_ERR(kgsl_mem_log, fmt, ##args)
|
||||
#define KGSL_MEM_FATAL(fmt, args...) KGSL_LOG_FATAL(kgsl_mem_log, fmt, ##args)
|
||||
|
||||
#endif /* _GSL_LOG_H */
|
@ -1,672 +0,0 @@
|
||||
/*
|
||||
* (C) Copyright Advanced Micro Devices, Inc. 2002, 2007
|
||||
* Copyright (c) 2008-2009 QUALCOMM USA, INC.
|
||||
*
|
||||
* All source code in this file is licensed under the following license
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can find it at http://www.fsf.org
|
||||
*/
|
||||
#include <linux/types.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/genalloc.h>
|
||||
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/pgtable.h>
|
||||
|
||||
#include "kgsl_mmu.h"
|
||||
#include "kgsl.h"
|
||||
#include "kgsl_log.h"
|
||||
#include "yamato_reg.h"
|
||||
|
||||
struct kgsl_pte_debug {
|
||||
unsigned int read:1;
|
||||
unsigned int write:1;
|
||||
unsigned int dirty:1;
|
||||
unsigned int reserved:9;
|
||||
unsigned int phyaddr:20;
|
||||
};
|
||||
|
||||
#define GSL_PTE_SIZE 4
|
||||
#define GSL_PT_EXTRA_ENTRIES 16
|
||||
|
||||
|
||||
#define GSL_PT_PAGE_BITS_MASK 0x00000007
|
||||
#define GSL_PT_PAGE_ADDR_MASK (~(KGSL_PAGESIZE - 1))
|
||||
|
||||
#define GSL_MMU_INT_MASK \
|
||||
(MH_INTERRUPT_MASK__AXI_READ_ERROR | \
|
||||
MH_INTERRUPT_MASK__AXI_WRITE_ERROR)
|
||||
|
||||
uint32_t kgsl_pt_entry_get(struct kgsl_pagetable *pt, uint32_t va)
|
||||
{
|
||||
return (va - pt->va_base) >> KGSL_PAGESIZE_SHIFT;
|
||||
}
|
||||
|
||||
uint32_t kgsl_pt_map_get(struct kgsl_pagetable *pt, uint32_t pte)
|
||||
{
|
||||
uint32_t *baseptr = (uint32_t *)pt->base.hostptr;
|
||||
return baseptr[pte];
|
||||
}
|
||||
|
||||
void kgsl_pt_map_set(struct kgsl_pagetable *pt, uint32_t pte, uint32_t val)
|
||||
{
|
||||
uint32_t *baseptr = (uint32_t *)pt->base.hostptr;
|
||||
baseptr[pte] = val;
|
||||
}
|
||||
#define GSL_PT_MAP_DEBUG(pte) ((struct kgsl_pte_debug *) \
|
||||
&gsl_pt_map_get(pagetable, pte))
|
||||
|
||||
void kgsl_pt_map_setbits(struct kgsl_pagetable *pt, uint32_t pte, uint32_t bits)
|
||||
{
|
||||
uint32_t *baseptr = (uint32_t *)pt->base.hostptr;
|
||||
baseptr[pte] |= bits;
|
||||
}
|
||||
|
||||
void kgsl_pt_map_setaddr(struct kgsl_pagetable *pt, uint32_t pte,
|
||||
uint32_t pageaddr)
|
||||
{
|
||||
uint32_t *baseptr = (uint32_t *)pt->base.hostptr;
|
||||
uint32_t val = baseptr[pte];
|
||||
val &= ~GSL_PT_PAGE_ADDR_MASK;
|
||||
val |= (pageaddr & GSL_PT_PAGE_ADDR_MASK);
|
||||
baseptr[pte] = val;
|
||||
}
|
||||
|
||||
void kgsl_pt_map_resetall(struct kgsl_pagetable *pt, uint32_t pte)
|
||||
{
|
||||
uint32_t *baseptr = (uint32_t *)pt->base.hostptr;
|
||||
baseptr[pte] &= GSL_PT_PAGE_DIRTY;
|
||||
}
|
||||
|
||||
void kgsl_pt_map_resetbits(struct kgsl_pagetable *pt, uint32_t pte,
|
||||
uint32_t bits)
|
||||
{
|
||||
uint32_t *baseptr = (uint32_t *)pt->base.hostptr;
|
||||
baseptr[pte] &= ~(bits & GSL_PT_PAGE_BITS_MASK);
|
||||
}
|
||||
|
||||
int kgsl_pt_map_isdirty(struct kgsl_pagetable *pt, uint32_t pte)
|
||||
{
|
||||
uint32_t *baseptr = (uint32_t *)pt->base.hostptr;
|
||||
return baseptr[pte] & GSL_PT_PAGE_DIRTY;
|
||||
}
|
||||
|
||||
uint32_t kgsl_pt_map_getaddr(struct kgsl_pagetable *pt, uint32_t pte)
|
||||
{
|
||||
uint32_t *baseptr = (uint32_t *)pt->base.hostptr;
|
||||
return baseptr[pte] & GSL_PT_PAGE_ADDR_MASK;
|
||||
}
|
||||
|
||||
void kgsl_mh_intrcallback(struct kgsl_device *device)
|
||||
{
|
||||
unsigned int status = 0;
|
||||
unsigned int reg;
|
||||
unsigned int axi_error;
|
||||
struct kgsl_mmu_debug dbg;
|
||||
|
||||
KGSL_MEM_VDBG("enter (device=%p)\n", device);
|
||||
|
||||
kgsl_yamato_regread(device, REG_MH_INTERRUPT_STATUS, &status);
|
||||
|
||||
if (status & MH_INTERRUPT_MASK__AXI_READ_ERROR) {
|
||||
kgsl_yamato_regread(device, REG_MH_AXI_ERROR, &axi_error);
|
||||
KGSL_MEM_FATAL("axi read error interrupt (%08x)\n", axi_error);
|
||||
kgsl_mmu_debug(&device->mmu, &dbg);
|
||||
} else if (status & MH_INTERRUPT_MASK__AXI_WRITE_ERROR) {
|
||||
kgsl_yamato_regread(device, REG_MH_AXI_ERROR, &axi_error);
|
||||
KGSL_MEM_FATAL("axi write error interrupt (%08x)\n", axi_error);
|
||||
kgsl_mmu_debug(&device->mmu, &dbg);
|
||||
} else if (status & MH_INTERRUPT_MASK__MMU_PAGE_FAULT) {
|
||||
kgsl_yamato_regread(device, REG_MH_MMU_PAGE_FAULT, ®);
|
||||
KGSL_MEM_FATAL("mmu page fault interrupt: %08x\n", reg);
|
||||
kgsl_mmu_debug(&device->mmu, &dbg);
|
||||
} else {
|
||||
KGSL_MEM_DBG("bad bits in REG_MH_INTERRUPT_STATUS %08x\n",
|
||||
status);
|
||||
}
|
||||
|
||||
kgsl_yamato_regwrite(device, REG_MH_INTERRUPT_CLEAR, status);
|
||||
|
||||
/*TODO: figure out how to handle errror interupts.
|
||||
* specifically, page faults should probably nuke the client that
|
||||
* caused them, but we don't have enough info to figure that out yet.
|
||||
*/
|
||||
|
||||
KGSL_MEM_VDBG("return\n");
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void kgsl_mmu_debug(struct kgsl_mmu *mmu, struct kgsl_mmu_debug *regs)
|
||||
{
|
||||
memset(regs, 0, sizeof(struct kgsl_mmu_debug));
|
||||
|
||||
kgsl_yamato_regread(mmu->device, REG_MH_MMU_CONFIG,
|
||||
®s->config);
|
||||
kgsl_yamato_regread(mmu->device, REG_MH_MMU_MPU_BASE,
|
||||
®s->mpu_base);
|
||||
kgsl_yamato_regread(mmu->device, REG_MH_MMU_MPU_END,
|
||||
®s->mpu_end);
|
||||
kgsl_yamato_regread(mmu->device, REG_MH_MMU_VA_RANGE,
|
||||
®s->va_range);
|
||||
kgsl_yamato_regread(mmu->device, REG_MH_MMU_PT_BASE,
|
||||
®s->pt_base);
|
||||
kgsl_yamato_regread(mmu->device, REG_MH_MMU_PAGE_FAULT,
|
||||
®s->page_fault);
|
||||
kgsl_yamato_regread(mmu->device, REG_MH_MMU_TRAN_ERROR,
|
||||
®s->trans_error);
|
||||
kgsl_yamato_regread(mmu->device, REG_MH_AXI_ERROR,
|
||||
®s->axi_error);
|
||||
kgsl_yamato_regread(mmu->device, REG_MH_INTERRUPT_MASK,
|
||||
®s->interrupt_mask);
|
||||
kgsl_yamato_regread(mmu->device, REG_MH_INTERRUPT_STATUS,
|
||||
®s->interrupt_status);
|
||||
|
||||
KGSL_MEM_DBG("mmu config %08x mpu_base %08x mpu_end %08x\n",
|
||||
regs->config, regs->mpu_base, regs->mpu_end);
|
||||
KGSL_MEM_DBG("mmu va_range %08x pt_base %08x \n",
|
||||
regs->va_range, regs->pt_base);
|
||||
KGSL_MEM_DBG("mmu page_fault %08x tran_err %08x\n",
|
||||
regs->page_fault, regs->trans_error);
|
||||
KGSL_MEM_DBG("mmu int mask %08x int status %08x\n",
|
||||
regs->interrupt_mask, regs->interrupt_status);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct kgsl_pagetable *kgsl_mmu_createpagetableobject(struct kgsl_mmu *mmu)
|
||||
{
|
||||
int status = 0;
|
||||
struct kgsl_pagetable *pagetable = NULL;
|
||||
uint32_t flags;
|
||||
|
||||
KGSL_MEM_VDBG("enter (mmu=%p)\n", mmu);
|
||||
|
||||
pagetable = kzalloc(sizeof(struct kgsl_pagetable), GFP_KERNEL);
|
||||
if (pagetable == NULL) {
|
||||
KGSL_MEM_ERR("Unable to allocate pagetable object.\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pagetable->mmu = mmu;
|
||||
pagetable->va_base = mmu->va_base;
|
||||
pagetable->va_range = mmu->va_range;
|
||||
pagetable->last_superpte = 0;
|
||||
pagetable->max_entries = (mmu->va_range >> KGSL_PAGESIZE_SHIFT)
|
||||
+ GSL_PT_EXTRA_ENTRIES;
|
||||
|
||||
pagetable->pool = gen_pool_create(KGSL_PAGESIZE_SHIFT, -1);
|
||||
if (pagetable->pool == NULL) {
|
||||
KGSL_MEM_ERR("Unable to allocate virtualaddr pool.\n");
|
||||
goto err_gen_pool_create;
|
||||
}
|
||||
|
||||
if (gen_pool_add(pagetable->pool, pagetable->va_base,
|
||||
pagetable->va_range, -1)) {
|
||||
KGSL_MEM_ERR("gen_pool_create failed for pagetable %p\n",
|
||||
pagetable);
|
||||
goto err_gen_pool_add;
|
||||
}
|
||||
|
||||
/* allocate page table memory */
|
||||
flags = (KGSL_MEMFLAGS_ALIGN4K | KGSL_MEMFLAGS_CONPHYS
|
||||
| KGSL_MEMFLAGS_STRICTREQUEST);
|
||||
status = kgsl_sharedmem_alloc(flags,
|
||||
pagetable->max_entries * GSL_PTE_SIZE,
|
||||
&pagetable->base);
|
||||
|
||||
if (status) {
|
||||
KGSL_MEM_ERR("cannot alloc page tables\n");
|
||||
goto err_kgsl_sharedmem_alloc;
|
||||
}
|
||||
|
||||
/* reset page table entries
|
||||
* -- all pte's are marked as not dirty initially
|
||||
*/
|
||||
kgsl_sharedmem_set(&pagetable->base, 0, 0, pagetable->base.size);
|
||||
pagetable->base.gpuaddr = pagetable->base.physaddr;
|
||||
|
||||
KGSL_MEM_VDBG("return %p\n", pagetable);
|
||||
|
||||
return pagetable;
|
||||
|
||||
err_kgsl_sharedmem_alloc:
|
||||
err_gen_pool_add:
|
||||
gen_pool_destroy(pagetable->pool);
|
||||
err_gen_pool_create:
|
||||
kfree(pagetable);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int kgsl_mmu_destroypagetableobject(struct kgsl_pagetable *pagetable)
|
||||
{
|
||||
KGSL_MEM_VDBG("enter (pagetable=%p)\n", pagetable);
|
||||
|
||||
if (pagetable) {
|
||||
if (pagetable->base.gpuaddr)
|
||||
kgsl_sharedmem_free(&pagetable->base);
|
||||
|
||||
if (pagetable->pool) {
|
||||
gen_pool_destroy(pagetable->pool);
|
||||
pagetable->pool = NULL;
|
||||
}
|
||||
|
||||
kfree(pagetable);
|
||||
|
||||
}
|
||||
KGSL_MEM_VDBG("return 0x%08x\n", 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kgsl_mmu_setstate(struct kgsl_device *device,
|
||||
struct kgsl_pagetable *pagetable)
|
||||
{
|
||||
int status = 0;
|
||||
struct kgsl_mmu *mmu = &device->mmu;
|
||||
|
||||
KGSL_MEM_VDBG("enter (device=%p, pagetable=%p)\n", device, pagetable);
|
||||
|
||||
if (mmu->flags & KGSL_FLAGS_STARTED) {
|
||||
/* page table not current, then setup mmu to use new
|
||||
* specified page table
|
||||
*/
|
||||
KGSL_MEM_INFO("from %p to %p\n", mmu->hwpagetable, pagetable);
|
||||
if (mmu->hwpagetable != pagetable) {
|
||||
mmu->hwpagetable = pagetable;
|
||||
|
||||
/* call device specific set page table */
|
||||
status = kgsl_yamato_setstate(mmu->device,
|
||||
KGSL_MMUFLAGS_TLBFLUSH |
|
||||
KGSL_MMUFLAGS_PTUPDATE);
|
||||
}
|
||||
}
|
||||
|
||||
KGSL_MEM_VDBG("return %d\n", status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
int kgsl_mmu_init(struct kgsl_device *device)
|
||||
{
|
||||
/*
|
||||
* intialize device mmu
|
||||
*
|
||||
* call this with the global lock held
|
||||
*/
|
||||
int status;
|
||||
uint32_t flags;
|
||||
struct kgsl_mmu *mmu = &device->mmu;
|
||||
#ifdef _DEBUG
|
||||
struct kgsl_mmu_debug regs;
|
||||
#endif /* _DEBUG */
|
||||
|
||||
KGSL_MEM_VDBG("enter (device=%p)\n", device);
|
||||
|
||||
if (mmu->flags & KGSL_FLAGS_INITIALIZED0) {
|
||||
KGSL_MEM_INFO("MMU already initialized.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
mmu->device = device;
|
||||
|
||||
#ifndef CONFIG_GPU_MSM_KGSL_MMU
|
||||
mmu->config = 0x00000000;
|
||||
#endif
|
||||
|
||||
/* setup MMU and sub-client behavior */
|
||||
kgsl_yamato_regwrite(device, REG_MH_MMU_CONFIG, mmu->config);
|
||||
|
||||
/* enable axi interrupts */
|
||||
KGSL_MEM_DBG("enabling mmu interrupts mask=0x%08lx\n",
|
||||
GSL_MMU_INT_MASK);
|
||||
kgsl_yamato_regwrite(device, REG_MH_INTERRUPT_MASK, GSL_MMU_INT_MASK);
|
||||
|
||||
mmu->flags |= KGSL_FLAGS_INITIALIZED0;
|
||||
|
||||
/* MMU not enabled */
|
||||
if ((mmu->config & 0x1) == 0) {
|
||||
KGSL_MEM_VDBG("return %d\n", 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* idle device */
|
||||
kgsl_yamato_idle(device, KGSL_TIMEOUT_DEFAULT);
|
||||
|
||||
/* make sure aligned to pagesize */
|
||||
BUG_ON(mmu->mpu_base & (KGSL_PAGESIZE - 1));
|
||||
BUG_ON((mmu->mpu_base + mmu->mpu_range) & (KGSL_PAGESIZE - 1));
|
||||
|
||||
/* define physical memory range accessible by the core */
|
||||
kgsl_yamato_regwrite(device, REG_MH_MMU_MPU_BASE,
|
||||
mmu->mpu_base);
|
||||
kgsl_yamato_regwrite(device, REG_MH_MMU_MPU_END,
|
||||
mmu->mpu_base + mmu->mpu_range);
|
||||
|
||||
/* enable axi interrupts */
|
||||
KGSL_MEM_DBG("enabling mmu interrupts mask=0x%08lx\n",
|
||||
GSL_MMU_INT_MASK | MH_INTERRUPT_MASK__MMU_PAGE_FAULT);
|
||||
kgsl_yamato_regwrite(device, REG_MH_INTERRUPT_MASK,
|
||||
GSL_MMU_INT_MASK | MH_INTERRUPT_MASK__MMU_PAGE_FAULT);
|
||||
|
||||
mmu->flags |= KGSL_FLAGS_INITIALIZED;
|
||||
|
||||
/* sub-client MMU lookups require address translation */
|
||||
if ((mmu->config & ~0x1) > 0) {
|
||||
/*make sure virtual address range is a multiple of 64Kb */
|
||||
BUG_ON(mmu->va_range & ((1 << 16) - 1));
|
||||
|
||||
/* allocate memory used for completing r/w operations that
|
||||
* cannot be mapped by the MMU
|
||||
*/
|
||||
flags = (KGSL_MEMFLAGS_ALIGN4K | KGSL_MEMFLAGS_CONPHYS
|
||||
| KGSL_MEMFLAGS_STRICTREQUEST);
|
||||
status = kgsl_sharedmem_alloc(flags, 64, &mmu->dummyspace);
|
||||
if (status != 0) {
|
||||
KGSL_MEM_ERR
|
||||
("Unable to allocate dummy space memory.\n");
|
||||
kgsl_mmu_close(device);
|
||||
return status;
|
||||
}
|
||||
|
||||
kgsl_sharedmem_set(&mmu->dummyspace, 0, 0,
|
||||
mmu->dummyspace.size);
|
||||
/* TRAN_ERROR needs a 32 byte (32 byte aligned) chunk of memory
|
||||
* to complete transactions in case of an MMU fault. Note that
|
||||
* we'll leave the bottom 32 bytes of the dummyspace for other
|
||||
* purposes (e.g. use it when dummy read cycles are needed
|
||||
* for other blocks */
|
||||
kgsl_yamato_regwrite(device,
|
||||
REG_MH_MMU_TRAN_ERROR,
|
||||
mmu->dummyspace.physaddr + 32);
|
||||
|
||||
mmu->defaultpagetable = kgsl_mmu_createpagetableobject(mmu);
|
||||
if (!mmu->defaultpagetable) {
|
||||
KGSL_MEM_ERR("Failed to create global page table\n");
|
||||
kgsl_mmu_close(device);
|
||||
return -ENOMEM;
|
||||
}
|
||||
mmu->hwpagetable = mmu->defaultpagetable;
|
||||
mmu->tlbflushfilter.size = (mmu->va_range /
|
||||
(PAGE_SIZE * GSL_PT_SUPER_PTE * 8)) + 1;
|
||||
mmu->tlbflushfilter.base = (unsigned int *)
|
||||
kzalloc(mmu->tlbflushfilter.size, GFP_KERNEL);
|
||||
if (!mmu->tlbflushfilter.base) {
|
||||
KGSL_MEM_ERR("Failed to create tlbflushfilter\n");
|
||||
kgsl_mmu_close(device);
|
||||
return -ENOMEM;
|
||||
}
|
||||
GSL_TLBFLUSH_FILTER_RESET();
|
||||
kgsl_yamato_regwrite(device, REG_MH_MMU_PT_BASE,
|
||||
mmu->hwpagetable->base.gpuaddr);
|
||||
kgsl_yamato_regwrite(device, REG_MH_MMU_VA_RANGE,
|
||||
(mmu->hwpagetable->va_base |
|
||||
(mmu->hwpagetable->va_range >> 16)));
|
||||
status = kgsl_yamato_setstate(device, KGSL_MMUFLAGS_TLBFLUSH);
|
||||
if (status) {
|
||||
kgsl_mmu_close(device);
|
||||
return status;
|
||||
}
|
||||
|
||||
mmu->flags |= KGSL_FLAGS_STARTED;
|
||||
}
|
||||
|
||||
KGSL_MEM_VDBG("return %d\n", 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_GPU_MSM_KGSL_MMU
|
||||
pte_t *kgsl_get_pte_from_vaddr(unsigned int vaddr)
|
||||
{
|
||||
pgd_t *pgd_ptr = NULL;
|
||||
pmd_t *pmd_ptr = NULL;
|
||||
pte_t *pte_ptr = NULL;
|
||||
|
||||
pgd_ptr = pgd_offset(current->mm, vaddr);
|
||||
if (pgd_none(*pgd) || pgd_bad(*pgd)) {
|
||||
KGSL_MEM_ERR
|
||||
("Invalid pgd entry found while trying to convert virtual "
|
||||
"address to physical\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pmd_ptr = pmd_offset(pgd_ptr, vaddr);
|
||||
if (pmd_none(*pmd_ptr) || pmd_bad(*pmd_ptr)) {
|
||||
KGSL_MEM_ERR
|
||||
("Invalid pmd entry found while trying to convert virtual "
|
||||
"address to physical\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
pte_ptr = pte_offset_map(pmd_ptr, vaddr);
|
||||
if (!pte_ptr) {
|
||||
KGSL_MEM_ERR
|
||||
("Unable to map pte entry while trying to convert virtual "
|
||||
"address to physical\n");
|
||||
return 0;
|
||||
}
|
||||
return pte_ptr;
|
||||
}
|
||||
|
||||
int kgsl_mmu_map(struct kgsl_pagetable *pagetable,
|
||||
unsigned int address,
|
||||
int range,
|
||||
unsigned int protflags,
|
||||
unsigned int *gpuaddr,
|
||||
unsigned int flags)
|
||||
{
|
||||
int numpages;
|
||||
unsigned int pte, ptefirst, ptelast, physaddr;
|
||||
int flushtlb, alloc_size;
|
||||
struct kgsl_mmu *mmu = NULL;
|
||||
int phys_contiguous = flags & KGSL_MEMFLAGS_CONPHYS;
|
||||
unsigned int align = flags & KGSL_MEMFLAGS_ALIGN_MASK;
|
||||
|
||||
KGSL_MEM_VDBG("enter (pt=%p, physaddr=%08x, range=%08d, gpuaddr=%p)\n",
|
||||
pagetable, address, range, gpuaddr);
|
||||
|
||||
mmu = pagetable->mmu;
|
||||
|
||||
BUG_ON(mmu == NULL);
|
||||
BUG_ON(protflags & ~(GSL_PT_PAGE_RV | GSL_PT_PAGE_WV));
|
||||
BUG_ON(protflags == 0);
|
||||
BUG_ON(range <= 0);
|
||||
|
||||
/* Only support 4K and 8K alignment for now */
|
||||
if (align != KGSL_MEMFLAGS_ALIGN8K && align != KGSL_MEMFLAGS_ALIGN4K) {
|
||||
KGSL_MEM_ERR("Cannot map memory according to "
|
||||
"requested flags: %08x\n", flags);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Make sure address being mapped is at 4K boundary */
|
||||
if (!IS_ALIGNED(address, KGSL_PAGESIZE) || range & ~KGSL_PAGEMASK) {
|
||||
KGSL_MEM_ERR("Cannot map address not aligned "
|
||||
"at page boundary: address: %08x, range: %08x\n",
|
||||
address, range);
|
||||
return -EINVAL;
|
||||
}
|
||||
alloc_size = range;
|
||||
if (align == KGSL_MEMFLAGS_ALIGN8K)
|
||||
alloc_size += KGSL_PAGESIZE;
|
||||
|
||||
*gpuaddr = gen_pool_alloc(pagetable->pool, alloc_size);
|
||||
if (*gpuaddr == 0) {
|
||||
KGSL_MEM_ERR("gen_pool_alloc failed: %d\n", alloc_size);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (align == KGSL_MEMFLAGS_ALIGN8K) {
|
||||
if (*gpuaddr & ((1 << 13) - 1)) {
|
||||
/* Not 8k aligned, align it */
|
||||
gen_pool_free(pagetable->pool, *gpuaddr, KGSL_PAGESIZE);
|
||||
*gpuaddr = *gpuaddr + KGSL_PAGESIZE;
|
||||
} else
|
||||
gen_pool_free(pagetable->pool, *gpuaddr + range,
|
||||
KGSL_PAGESIZE);
|
||||
}
|
||||
|
||||
numpages = (range >> KGSL_PAGESIZE_SHIFT);
|
||||
|
||||
ptefirst = kgsl_pt_entry_get(pagetable, *gpuaddr);
|
||||
ptelast = ptefirst + numpages;
|
||||
|
||||
pte = ptefirst;
|
||||
flushtlb = 0;
|
||||
|
||||
/* tlb needs to be flushed when the first and last pte are not at
|
||||
* superpte boundaries */
|
||||
if ((ptefirst & (GSL_PT_SUPER_PTE - 1)) != 0 ||
|
||||
((ptelast + 1) & (GSL_PT_SUPER_PTE-1)) != 0)
|
||||
flushtlb = 1;
|
||||
|
||||
for (pte = ptefirst; pte < ptelast; pte++) {
|
||||
#ifdef VERBOSE_DEBUG
|
||||
/* check if PTE exists */
|
||||
uint32_t val = kgsl_pt_map_getaddr(pagetable, pte);
|
||||
BUG_ON(val != 0 && val != GSL_PT_PAGE_DIRTY);
|
||||
#endif
|
||||
if ((pte & (GSL_PT_SUPER_PTE-1)) == 0)
|
||||
if (GSL_TLBFLUSH_FILTER_ISDIRTY(pte / GSL_PT_SUPER_PTE))
|
||||
flushtlb = 1;
|
||||
|
||||
/* mark pte as in use */
|
||||
if (phys_contiguous)
|
||||
physaddr = address;
|
||||
else {
|
||||
physaddr = vmalloc_to_pfn((void *)address);
|
||||
physaddr <<= PAGE_SHIFT;
|
||||
}
|
||||
|
||||
if (physaddr)
|
||||
kgsl_pt_map_set(pagetable, pte, physaddr | protflags);
|
||||
else {
|
||||
KGSL_MEM_ERR
|
||||
("Unable to find physaddr for vmallloc address: %x\n",
|
||||
address);
|
||||
kgsl_mmu_unmap(pagetable, *gpuaddr, range);
|
||||
return -EFAULT;
|
||||
}
|
||||
address += KGSL_PAGESIZE;
|
||||
}
|
||||
|
||||
KGSL_MEM_INFO("pt %p p %08x g %08x pte f %d l %d n %d f %d\n",
|
||||
pagetable, address, *gpuaddr, ptefirst, ptelast,
|
||||
numpages, flushtlb);
|
||||
|
||||
dmb();
|
||||
|
||||
/* Invalidate tlb only if current page table used by GPU is the
|
||||
* pagetable that we used to allocate */
|
||||
if (flushtlb && (pagetable == mmu->hwpagetable)) {
|
||||
kgsl_yamato_setstate(mmu->device, KGSL_MMUFLAGS_TLBFLUSH);
|
||||
GSL_TLBFLUSH_FILTER_RESET();
|
||||
}
|
||||
|
||||
|
||||
KGSL_MEM_VDBG("return %d\n", 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
kgsl_mmu_unmap(struct kgsl_pagetable *pagetable, unsigned int gpuaddr,
|
||||
int range)
|
||||
{
|
||||
unsigned int numpages;
|
||||
unsigned int pte, ptefirst, ptelast, superpte;
|
||||
struct kgsl_mmu *mmu = NULL;
|
||||
|
||||
KGSL_MEM_VDBG("enter (pt=%p, gpuaddr=0x%08x, range=%d)\n",
|
||||
pagetable, gpuaddr, range);
|
||||
|
||||
BUG_ON(range <= 0);
|
||||
|
||||
numpages = (range >> KGSL_PAGESIZE_SHIFT);
|
||||
if (range & (KGSL_PAGESIZE - 1))
|
||||
numpages++;
|
||||
|
||||
ptefirst = kgsl_pt_entry_get(pagetable, gpuaddr);
|
||||
ptelast = ptefirst + numpages;
|
||||
|
||||
KGSL_MEM_INFO("pt %p gpu %08x pte first %d last %d numpages %d\n",
|
||||
pagetable, gpuaddr, ptefirst, ptelast, numpages);
|
||||
|
||||
mmu = pagetable->mmu;
|
||||
|
||||
superpte = ptefirst - (ptefirst & (GSL_PT_SUPER_PTE-1));
|
||||
GSL_TLBFLUSH_FILTER_SETDIRTY(superpte / GSL_PT_SUPER_PTE);
|
||||
for (pte = ptefirst; pte < ptelast; pte++) {
|
||||
#ifdef VERBOSE_DEBUG
|
||||
/* check if PTE exists */
|
||||
BUG_ON(!kgsl_pt_map_getaddr(pagetable, pte));
|
||||
#endif
|
||||
kgsl_pt_map_set(pagetable, pte, GSL_PT_PAGE_DIRTY);
|
||||
superpte = pte - (pte & (GSL_PT_SUPER_PTE - 1));
|
||||
if (pte == superpte)
|
||||
GSL_TLBFLUSH_FILTER_SETDIRTY(superpte /
|
||||
GSL_PT_SUPER_PTE);
|
||||
}
|
||||
|
||||
dmb();
|
||||
|
||||
gen_pool_free(pagetable->pool, gpuaddr, range);
|
||||
|
||||
KGSL_MEM_VDBG("return %d\n", 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int kgsl_mmu_close(struct kgsl_device *device)
|
||||
{
|
||||
/*
|
||||
* close device mmu
|
||||
*
|
||||
* call this with the global lock held
|
||||
*/
|
||||
struct kgsl_mmu *mmu = &device->mmu;
|
||||
#ifdef _DEBUG
|
||||
int i;
|
||||
#endif /* _DEBUG */
|
||||
|
||||
KGSL_MEM_VDBG("enter (device=%p)\n", device);
|
||||
|
||||
if (mmu->flags & KGSL_FLAGS_INITIALIZED0) {
|
||||
/* disable mh interrupts */
|
||||
KGSL_MEM_DBG("disabling mmu interrupts\n");
|
||||
kgsl_yamato_regwrite(device, REG_MH_INTERRUPT_MASK, 0);
|
||||
|
||||
/* disable MMU */
|
||||
kgsl_yamato_regwrite(device, REG_MH_MMU_CONFIG, 0x00000000);
|
||||
|
||||
if (mmu->dummyspace.gpuaddr)
|
||||
kgsl_sharedmem_free(&mmu->dummyspace);
|
||||
|
||||
if (mmu->tlbflushfilter.base) {
|
||||
mmu->tlbflushfilter.size = 0;
|
||||
kfree(mmu->tlbflushfilter.base);
|
||||
mmu->tlbflushfilter.base = NULL;
|
||||
}
|
||||
|
||||
mmu->flags &= ~KGSL_FLAGS_STARTED;
|
||||
mmu->flags &= ~KGSL_FLAGS_INITIALIZED;
|
||||
mmu->flags &= ~KGSL_FLAGS_INITIALIZED0;
|
||||
kgsl_mmu_destroypagetableobject(mmu->defaultpagetable);
|
||||
mmu->defaultpagetable = NULL;
|
||||
}
|
||||
|
||||
KGSL_MEM_VDBG("return %d\n", 0);
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,169 +0,0 @@
|
||||
/*
|
||||
* (C) Copyright Advanced Micro Devices, Inc. 2002, 2007
|
||||
* Copyright (c) 2008-2009 QUALCOMM USA, INC.
|
||||
*
|
||||
* All source code in this file is licensed under the following license
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can find it at http://www.fsf.org
|
||||
*/
|
||||
#ifndef __GSL_MMU_H
|
||||
#define __GSL_MMU_H
|
||||
#include <linux/types.h>
|
||||
#include <linux/msm_kgsl.h>
|
||||
#include "kgsl_log.h"
|
||||
#include "kgsl_sharedmem.h"
|
||||
|
||||
#define GSL_PT_SUPER_PTE 8
|
||||
#define GSL_PT_PAGE_WV 0x00000001
|
||||
#define GSL_PT_PAGE_RV 0x00000002
|
||||
#define GSL_PT_PAGE_DIRTY 0x00000004
|
||||
/* MMU Flags */
|
||||
#define KGSL_MMUFLAGS_TLBFLUSH 0x10000000
|
||||
#define KGSL_MMUFLAGS_PTUPDATE 0x20000000
|
||||
|
||||
/* Macros to manage TLB flushing */
|
||||
#define GSL_TLBFLUSH_FILTER_ENTRY_NUMBITS (sizeof(unsigned char) * 8)
|
||||
#define GSL_TLBFLUSH_FILTER_GET(superpte) \
|
||||
(*((unsigned char *) \
|
||||
(((unsigned int)mmu->tlbflushfilter.base) \
|
||||
+ (superpte / GSL_TLBFLUSH_FILTER_ENTRY_NUMBITS))))
|
||||
#define GSL_TLBFLUSH_FILTER_SETDIRTY(superpte) \
|
||||
(GSL_TLBFLUSH_FILTER_GET((superpte)) |= 1 << \
|
||||
(superpte % GSL_TLBFLUSH_FILTER_ENTRY_NUMBITS))
|
||||
#define GSL_TLBFLUSH_FILTER_ISDIRTY(superpte) \
|
||||
(GSL_TLBFLUSH_FILTER_GET((superpte)) & \
|
||||
(1 << (superpte % GSL_TLBFLUSH_FILTER_ENTRY_NUMBITS)))
|
||||
#define GSL_TLBFLUSH_FILTER_RESET() memset(mmu->tlbflushfilter.base,\
|
||||
0, mmu->tlbflushfilter.size)
|
||||
|
||||
extern unsigned int kgsl_cache_enable;
|
||||
|
||||
struct kgsl_device;
|
||||
|
||||
struct kgsl_mmu_debug {
|
||||
unsigned int config;
|
||||
unsigned int mpu_base;
|
||||
unsigned int mpu_end;
|
||||
unsigned int va_range;
|
||||
unsigned int pt_base;
|
||||
unsigned int page_fault;
|
||||
unsigned int trans_error;
|
||||
unsigned int axi_error;
|
||||
unsigned int interrupt_mask;
|
||||
unsigned int interrupt_status;
|
||||
};
|
||||
|
||||
struct kgsl_ptstats {
|
||||
int64_t maps;
|
||||
int64_t unmaps;
|
||||
int64_t superpteallocs;
|
||||
int64_t superptefrees;
|
||||
int64_t ptswitches;
|
||||
int64_t tlbflushes[KGSL_DEVICE_MAX];
|
||||
};
|
||||
|
||||
struct kgsl_pagetable {
|
||||
unsigned int refcnt;
|
||||
struct kgsl_mmu *mmu;
|
||||
struct kgsl_memdesc base;
|
||||
uint32_t va_base;
|
||||
unsigned int va_range;
|
||||
unsigned int last_superpte;
|
||||
unsigned int max_entries;
|
||||
struct gen_pool *pool;
|
||||
};
|
||||
|
||||
struct kgsl_tlbflushfilter {
|
||||
unsigned int *base;
|
||||
unsigned int size;
|
||||
};
|
||||
|
||||
struct kgsl_mmu {
|
||||
unsigned int refcnt;
|
||||
uint32_t flags;
|
||||
struct kgsl_device *device;
|
||||
unsigned int config;
|
||||
uint32_t mpu_base;
|
||||
int mpu_range;
|
||||
uint32_t va_base;
|
||||
unsigned int va_range;
|
||||
struct kgsl_memdesc dummyspace;
|
||||
/* current page table object being used by device mmu */
|
||||
struct kgsl_pagetable *defaultpagetable;
|
||||
struct kgsl_pagetable *hwpagetable;
|
||||
/* Maintain filter to manage tlb flushing */
|
||||
struct kgsl_tlbflushfilter tlbflushfilter;
|
||||
};
|
||||
|
||||
|
||||
static inline int
|
||||
kgsl_mmu_isenabled(struct kgsl_mmu *mmu)
|
||||
{
|
||||
return ((mmu)->flags & KGSL_FLAGS_STARTED) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
int kgsl_mmu_init(struct kgsl_device *device);
|
||||
|
||||
int kgsl_mmu_close(struct kgsl_device *device);
|
||||
|
||||
struct kgsl_pagetable *kgsl_mmu_createpagetableobject(struct kgsl_mmu *mmu);
|
||||
|
||||
int kgsl_mmu_destroypagetableobject(struct kgsl_pagetable *pagetable);
|
||||
|
||||
int kgsl_mmu_setstate(struct kgsl_device *device,
|
||||
struct kgsl_pagetable *pagetable);
|
||||
|
||||
#ifdef CONFIG_GPU_MSM_KGSL_MMU
|
||||
int kgsl_mmu_map(struct kgsl_pagetable *pagetable,
|
||||
unsigned int address,
|
||||
int range,
|
||||
unsigned int protflags,
|
||||
unsigned int *gpuaddr,
|
||||
unsigned int flags);
|
||||
|
||||
int kgsl_mmu_unmap(struct kgsl_pagetable *pagetable,
|
||||
unsigned int gpuaddr, int range);
|
||||
|
||||
pte_t *kgsl_get_pte_from_vaddr(unsigned int vaddr);
|
||||
#else
|
||||
static inline int kgsl_mmu_map(struct kgsl_pagetable *pagetable,
|
||||
unsigned int address,
|
||||
int range,
|
||||
unsigned int protflags,
|
||||
unsigned int *gpuaddr,
|
||||
unsigned int flags)
|
||||
{
|
||||
*gpuaddr = address;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int kgsl_mmu_unmap(struct kgsl_pagetable *pagetable,
|
||||
unsigned int gpuaddr, int range) { return 0; }
|
||||
|
||||
static inline pte_t *kgsl_get_pte_from_vaddr(unsigned int vaddr) {return NULL;}
|
||||
#endif
|
||||
|
||||
int kgsl_mmu_querystats(struct kgsl_pagetable *pagetable,
|
||||
struct kgsl_ptstats *stats);
|
||||
|
||||
void kgsl_mh_intrcallback(struct kgsl_device *device);
|
||||
|
||||
#ifdef DEBUG
|
||||
void kgsl_mmu_debug(struct kgsl_mmu *, struct kgsl_mmu_debug*);
|
||||
#else
|
||||
static inline void kgsl_mmu_debug(struct kgsl_mmu *mmu,
|
||||
struct kgsl_mmu_debug *mmu_debug) { }
|
||||
#endif /* DEBUG */
|
||||
|
||||
#endif /* __GSL_MMU_H */
|
@ -1,182 +0,0 @@
|
||||
/*
|
||||
* (C) Copyright Advanced Micro Devices, Inc. 2002, 2007
|
||||
* Copyright (c) 2008-2009 QUALCOMM USA, INC.
|
||||
*
|
||||
* All source code in this file is licensed under the following license
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can find it at http://www.fsf.org
|
||||
*/
|
||||
#ifndef __GSL_PM4TYPES_H
|
||||
#define __GSL_PM4TYPES_H
|
||||
|
||||
|
||||
#define PM4_PKT_MASK 0xc0000000
|
||||
|
||||
#define PM4_TYPE0_PKT ((unsigned int)0 << 30)
|
||||
#define PM4_TYPE1_PKT ((unsigned int)1 << 30)
|
||||
#define PM4_TYPE2_PKT ((unsigned int)2 << 30)
|
||||
#define PM4_TYPE3_PKT ((unsigned int)3 << 30)
|
||||
|
||||
|
||||
/* type3 packets */
|
||||
/* initialize CP's micro-engine */
|
||||
#define PM4_ME_INIT 0x48
|
||||
|
||||
/* skip N 32-bit words to get to the next packet */
|
||||
#define PM4_NOP 0x10
|
||||
|
||||
/* indirect buffer dispatch. prefetch parser uses this packet type to determine
|
||||
* whether to pre-fetch the IB
|
||||
*/
|
||||
#define PM4_INDIRECT_BUFFER 0x3f
|
||||
|
||||
/* indirect buffer dispatch. same as IB, but init is pipelined */
|
||||
#define PM4_INDIRECT_BUFFER_PFD 0x37
|
||||
|
||||
/* wait for the IDLE state of the engine */
|
||||
#define PM4_WAIT_FOR_IDLE 0x26
|
||||
|
||||
/* wait until a register or memory location is a specific value */
|
||||
#define PM4_WAIT_REG_MEM 0x3c
|
||||
|
||||
/* wait until a register location is equal to a specific value */
|
||||
#define PM4_WAIT_REG_EQ 0x52
|
||||
|
||||
/* wait until a register location is >= a specific value */
|
||||
#define PM4_WAT_REG_GTE 0x53
|
||||
|
||||
/* wait until a read completes */
|
||||
#define PM4_WAIT_UNTIL_READ 0x5c
|
||||
|
||||
/* wait until all base/size writes from an IB_PFD packet have completed */
|
||||
#define PM4_WAIT_IB_PFD_COMPLETE 0x5d
|
||||
|
||||
/* register read/modify/write */
|
||||
#define PM4_REG_RMW 0x21
|
||||
|
||||
/* reads register in chip and writes to memory */
|
||||
#define PM4_REG_TO_MEM 0x3e
|
||||
|
||||
/* write N 32-bit words to memory */
|
||||
#define PM4_MEM_WRITE 0x3d
|
||||
|
||||
/* write CP_PROG_COUNTER value to memory */
|
||||
#define PM4_MEM_WRITE_CNTR 0x4f
|
||||
|
||||
/* conditional execution of a sequence of packets */
|
||||
#define PM4_COND_EXEC 0x44
|
||||
|
||||
/* conditional write to memory or register */
|
||||
#define PM4_COND_WRITE 0x45
|
||||
|
||||
/* generate an event that creates a write to memory when completed */
|
||||
#define PM4_EVENT_WRITE 0x46
|
||||
|
||||
/* generate a VS|PS_done event */
|
||||
#define PM4_EVENT_WRITE_SHD 0x58
|
||||
|
||||
/* generate a cache flush done event */
|
||||
#define PM4_EVENT_WRITE_CFL 0x59
|
||||
|
||||
/* generate a z_pass done event */
|
||||
#define PM4_EVENT_WRITE_ZPD 0x5b
|
||||
|
||||
|
||||
/* initiate fetch of index buffer and draw */
|
||||
#define PM4_DRAW_INDX 0x22
|
||||
|
||||
/* draw using supplied indices in packet */
|
||||
#define PM4_DRAW_INDX_2 0x36
|
||||
|
||||
/* initiate fetch of index buffer and binIDs and draw */
|
||||
#define PM4_DRAW_INDX_BIN 0x34
|
||||
|
||||
/* initiate fetch of bin IDs and draw using supplied indices */
|
||||
#define PM4_DRAW_INDX_2_BIN 0x35
|
||||
|
||||
|
||||
/* begin/end initiator for viz query extent processing */
|
||||
#define PM4_VIZ_QUERY 0x23
|
||||
|
||||
/* fetch state sub-blocks and initiate shader code DMAs */
|
||||
#define PM4_SET_STATE 0x25
|
||||
|
||||
/* load constant into chip and to memory */
|
||||
#define PM4_SET_CONSTANT 0x2d
|
||||
|
||||
/* load sequencer instruction memory (pointer-based) */
|
||||
#define PM4_IM_LOAD 0x27
|
||||
|
||||
/* load sequencer instruction memory (code embedded in packet) */
|
||||
#define PM4_IM_LOAD_IMMEDIATE 0x2b
|
||||
|
||||
/* load constants from a location in memory */
|
||||
#define PM4_LOAD_CONSTANT_CONTEXT 0x2e
|
||||
|
||||
/* selective invalidation of state pointers */
|
||||
#define PM4_INVALIDATE_STATE 0x3b
|
||||
|
||||
|
||||
/* dynamically changes shader instruction memory partition */
|
||||
#define PM4_SET_SHADER_BASES 0x4A
|
||||
|
||||
/* sets the 64-bit BIN_MASK register in the PFP */
|
||||
#define PM4_SET_BIN_MASK 0x50
|
||||
|
||||
/* sets the 64-bit BIN_SELECT register in the PFP */
|
||||
#define PM4_SET_BIN_SELECT 0x51
|
||||
|
||||
|
||||
/* updates the current context, if needed */
|
||||
#define PM4_CONTEXT_UPDATE 0x5e
|
||||
|
||||
/* generate interrupt from the command stream */
|
||||
#define PM4_INTERRUPT 0x40
|
||||
|
||||
|
||||
/* copy sequencer instruction memory to system memory */
|
||||
#define PM4_IM_STORE 0x2c
|
||||
|
||||
/* program an offset that will added to the BIN_BASE value of
|
||||
* the 3D_DRAW_INDX_BIN packet */
|
||||
#define PM4_SET_BIN_BASE_OFFSET 0x4B
|
||||
|
||||
#define PM4_SET_PROTECTED_MODE 0x5f /* sets the register protection mode */
|
||||
|
||||
/* packet header building macros */
|
||||
#define pm4_type0_packet(regindx, cnt) \
|
||||
(PM4_TYPE0_PKT | (((cnt)-1) << 16) | ((regindx) & 0x7FFF))
|
||||
|
||||
#define pm4_type0_packet_for_sameregister(regindx, cnt) \
|
||||
((PM4_TYPE0_PKT | (((cnt)-1) << 16) | ((1 << 15) | \
|
||||
((regindx) & 0x7FFF)))
|
||||
|
||||
#define pm4_type1_packet(reg0, reg1) \
|
||||
(PM4_TYPE1_PKT | ((reg1) << 12) | (reg0))
|
||||
|
||||
#define pm4_type3_packet(opcode, cnt) \
|
||||
(PM4_TYPE3_PKT | (((cnt)-1) << 16) | (((opcode) & 0xFF) << 8))
|
||||
|
||||
#define pm4_predicated_type3_packet(opcode, cnt) \
|
||||
(PM4_TYPE3_PKT | (((cnt)-1) << 16) | (((opcode) & 0xFF) << 8) | 0x1)
|
||||
|
||||
#define pm4_nop_packet(cnt) \
|
||||
(PM4_TYPE3_PKT | (((cnt)-1) << 16) | (PM4_NOP << 8))
|
||||
|
||||
|
||||
/* packet headers */
|
||||
#define PM4_HDR_ME_INIT pm4_type3_packet(PM4_ME_INIT, 18)
|
||||
#define PM4_HDR_INDIRECT_BUFFER_PFD pm4_type3_packet(PM4_INDIRECT_BUFFER_PFD, 2)
|
||||
#define PM4_HDR_INDIRECT_BUFFER pm4_type3_packet(PM4_INDIRECT_BUFFER, 2)
|
||||
|
||||
#endif /* __GSL_PM4TYPES_H */
|
@ -1,837 +0,0 @@
|
||||
/*
|
||||
* (C) Copyright Advanced Micro Devices, Inc. 2002, 2007
|
||||
* Copyright (c) 2008-2009 QUALCOMM USA, INC.
|
||||
*
|
||||
* All source code in this file is licensed under the following license
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can find it at http://www.fsf.org
|
||||
*/
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/wait.h>
|
||||
|
||||
#include "kgsl.h"
|
||||
#include "kgsl_device.h"
|
||||
#include "kgsl_log.h"
|
||||
#include "kgsl_pm4types.h"
|
||||
#include "kgsl_ringbuffer.h"
|
||||
#include "kgsl_cmdstream.h"
|
||||
|
||||
#include "yamato_reg.h"
|
||||
|
||||
#define GSL_RB_NOP_SIZEDWORDS 2
|
||||
/* protected mode error checking below register address 0x800
|
||||
* note: if CP_INTERRUPT packet is used then checking needs
|
||||
* to change to below register address 0x7C8
|
||||
*/
|
||||
#define GSL_RB_PROTECTED_MODE_CONTROL 0x200001F2
|
||||
|
||||
#define GSL_CP_INT_MASK \
|
||||
(CP_INT_CNTL__SW_INT_MASK | \
|
||||
CP_INT_CNTL__T0_PACKET_IN_IB_MASK | \
|
||||
CP_INT_CNTL__OPCODE_ERROR_MASK | \
|
||||
CP_INT_CNTL__PROTECTED_MODE_ERROR_MASK | \
|
||||
CP_INT_CNTL__RESERVED_BIT_ERROR_MASK | \
|
||||
CP_INT_CNTL__IB_ERROR_MASK | \
|
||||
CP_INT_CNTL__IB2_INT_MASK | \
|
||||
CP_INT_CNTL__IB1_INT_MASK | \
|
||||
CP_INT_CNTL__RB_INT_MASK)
|
||||
|
||||
#define YAMATO_PFP_FW "yamato_pfp.fw"
|
||||
#define YAMATO_PM4_FW "yamato_pm4.fw"
|
||||
|
||||
/* ringbuffer size log2 quadwords equivalent */
|
||||
inline unsigned int kgsl_ringbuffer_sizelog2quadwords(unsigned int sizedwords)
|
||||
{
|
||||
unsigned int sizelog2quadwords = 0;
|
||||
int i = sizedwords >> 1;
|
||||
|
||||
while (i >>= 1)
|
||||
sizelog2quadwords++;
|
||||
|
||||
return sizelog2quadwords;
|
||||
}
|
||||
|
||||
|
||||
/* functions */
|
||||
void kgsl_cp_intrcallback(struct kgsl_device *device)
|
||||
{
|
||||
unsigned int status = 0;
|
||||
struct kgsl_ringbuffer *rb = &device->ringbuffer;
|
||||
|
||||
KGSL_CMD_VDBG("enter (device=%p)\n", device);
|
||||
|
||||
kgsl_yamato_regread(device, REG_CP_INT_STATUS, &status);
|
||||
|
||||
if (status & CP_INT_CNTL__RB_INT_MASK) {
|
||||
/* signal intr completion event */
|
||||
int init_reftimestamp = 0x7fffffff;
|
||||
int enableflag = 0;
|
||||
kgsl_sharedmem_write(&rb->device->memstore,
|
||||
KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable),
|
||||
&enableflag, 4);
|
||||
kgsl_sharedmem_write(&rb->device->memstore,
|
||||
KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts),
|
||||
&init_reftimestamp, 4);
|
||||
KGSL_CMD_WARN("ringbuffer rb interrupt\n");
|
||||
}
|
||||
|
||||
if (status & (CP_INT_CNTL__IB1_INT_MASK | CP_INT_CNTL__RB_INT_MASK)) {
|
||||
KGSL_CMD_WARN("ringbuffer ib1/rb interrupt\n");
|
||||
wake_up_interruptible_all(&device->ib1_wq);
|
||||
}
|
||||
if (status & CP_INT_CNTL__T0_PACKET_IN_IB_MASK) {
|
||||
KGSL_CMD_FATAL("ringbuffer TO packet in IB interrupt\n");
|
||||
kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, 0);
|
||||
kgsl_ringbuffer_dump(rb);
|
||||
}
|
||||
if (status & CP_INT_CNTL__OPCODE_ERROR_MASK) {
|
||||
KGSL_CMD_FATAL("ringbuffer opcode error interrupt\n");
|
||||
kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, 0);
|
||||
kgsl_ringbuffer_dump(rb);
|
||||
}
|
||||
if (status & CP_INT_CNTL__PROTECTED_MODE_ERROR_MASK) {
|
||||
KGSL_CMD_FATAL("ringbuffer protected mode error interrupt\n");
|
||||
kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, 0);
|
||||
kgsl_ringbuffer_dump(rb);
|
||||
}
|
||||
if (status & CP_INT_CNTL__RESERVED_BIT_ERROR_MASK) {
|
||||
KGSL_CMD_FATAL("ringbuffer reserved bit error interrupt\n");
|
||||
kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, 0);
|
||||
kgsl_ringbuffer_dump(rb);
|
||||
}
|
||||
if (status & CP_INT_CNTL__IB_ERROR_MASK) {
|
||||
KGSL_CMD_FATAL("ringbuffer IB error interrupt\n");
|
||||
kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, 0);
|
||||
kgsl_ringbuffer_dump(rb);
|
||||
}
|
||||
if (status & CP_INT_CNTL__SW_INT_MASK)
|
||||
KGSL_CMD_DBG("ringbuffer software interrupt\n");
|
||||
|
||||
if (status & CP_INT_CNTL__IB2_INT_MASK)
|
||||
KGSL_CMD_DBG("ringbuffer ib2 interrupt\n");
|
||||
|
||||
if (status & (~GSL_CP_INT_MASK))
|
||||
KGSL_CMD_DBG("bad bits in REG_CP_INT_STATUS %08x\n", status);
|
||||
|
||||
/* only ack bits we understand */
|
||||
status &= GSL_CP_INT_MASK;
|
||||
kgsl_yamato_regwrite(device, REG_CP_INT_ACK, status);
|
||||
|
||||
KGSL_CMD_VDBG("return\n");
|
||||
}
|
||||
|
||||
|
||||
void kgsl_ringbuffer_watchdog()
|
||||
{
|
||||
struct kgsl_device *device = NULL;
|
||||
struct kgsl_ringbuffer *rb = NULL;
|
||||
|
||||
device = &kgsl_driver.yamato_device;
|
||||
|
||||
BUG_ON(device == NULL);
|
||||
|
||||
rb = &device->ringbuffer;
|
||||
|
||||
KGSL_CMD_VDBG("enter\n");
|
||||
|
||||
if ((rb->flags & KGSL_FLAGS_STARTED) == 0) {
|
||||
KGSL_CMD_VDBG("not started\n");
|
||||
return;
|
||||
}
|
||||
|
||||
GSL_RB_GET_READPTR(rb, &rb->rptr);
|
||||
|
||||
if (rb->rptr == rb->wptr) {
|
||||
/* clear rptr sample for interval n */
|
||||
rb->watchdog.flags &= ~KGSL_FLAGS_ACTIVE;
|
||||
goto done;
|
||||
}
|
||||
/* ringbuffer is currently not empty */
|
||||
/* and a rptr sample was taken during interval n-1 */
|
||||
if (rb->watchdog.flags & KGSL_FLAGS_ACTIVE) {
|
||||
/* and the rptr did not advance between
|
||||
* interval n-1 and n */
|
||||
if (rb->rptr == rb->watchdog.rptr_sample) {
|
||||
/* then the core has hung */
|
||||
KGSL_CMD_FATAL("Watchdog detected core hung.\n");
|
||||
goto done;
|
||||
}
|
||||
/* save rptr sample for interval n */
|
||||
rb->watchdog.flags |= KGSL_FLAGS_ACTIVE;
|
||||
rb->watchdog.rptr_sample = rb->rptr;
|
||||
}
|
||||
done:
|
||||
KGSL_CMD_VDBG("return\n");
|
||||
}
|
||||
|
||||
static void kgsl_ringbuffer_submit(struct kgsl_ringbuffer *rb)
|
||||
{
|
||||
BUG_ON(rb->wptr == 0);
|
||||
|
||||
GSL_RB_UPDATE_WPTR_POLLING(rb);
|
||||
/* Drain write buffer and data memory barrier */
|
||||
dsb();
|
||||
dmb();
|
||||
|
||||
/* Memory fence to ensure all data has posted. On some systems,
|
||||
* like 7x27, the register block is not allocated as strongly ordered
|
||||
* memory. Adding a memory fence ensures ordering during ringbuffer
|
||||
* submits.*/
|
||||
mb();
|
||||
|
||||
kgsl_yamato_regwrite(rb->device, REG_CP_RB_WPTR, rb->wptr);
|
||||
|
||||
rb->flags |= KGSL_FLAGS_ACTIVE;
|
||||
}
|
||||
|
||||
static int
|
||||
kgsl_ringbuffer_waitspace(struct kgsl_ringbuffer *rb, unsigned int numcmds,
|
||||
int wptr_ahead)
|
||||
{
|
||||
int nopcount;
|
||||
unsigned int freecmds;
|
||||
unsigned int *cmds;
|
||||
|
||||
KGSL_CMD_VDBG("enter (rb=%p, numcmds=%d, wptr_ahead=%d)\n",
|
||||
rb, numcmds, wptr_ahead);
|
||||
|
||||
/* if wptr ahead, fill the remaining with NOPs */
|
||||
if (wptr_ahead) {
|
||||
/* -1 for header */
|
||||
nopcount = rb->sizedwords - rb->wptr - 1;
|
||||
|
||||
cmds = (unsigned int *)rb->buffer_desc.hostptr + rb->wptr;
|
||||
GSL_RB_WRITE(cmds, pm4_nop_packet(nopcount));
|
||||
rb->wptr++;
|
||||
|
||||
kgsl_ringbuffer_submit(rb);
|
||||
|
||||
rb->wptr = 0;
|
||||
}
|
||||
|
||||
/* wait for space in ringbuffer */
|
||||
do {
|
||||
GSL_RB_GET_READPTR(rb, &rb->rptr);
|
||||
|
||||
freecmds = rb->rptr - rb->wptr;
|
||||
|
||||
} while ((freecmds != 0) && (freecmds < numcmds));
|
||||
|
||||
KGSL_CMD_VDBG("return %d\n", 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int *kgsl_ringbuffer_allocspace(struct kgsl_ringbuffer *rb,
|
||||
unsigned int numcmds)
|
||||
{
|
||||
unsigned int *ptr = NULL;
|
||||
int status = 0;
|
||||
|
||||
BUG_ON(numcmds >= rb->sizedwords);
|
||||
|
||||
/* check for available space */
|
||||
if (rb->wptr >= rb->rptr) {
|
||||
/* wptr ahead or equal to rptr */
|
||||
/* reserve dwords for nop packet */
|
||||
if ((rb->wptr + numcmds) > (rb->sizedwords -
|
||||
GSL_RB_NOP_SIZEDWORDS))
|
||||
status = kgsl_ringbuffer_waitspace(rb, numcmds, 1);
|
||||
} else {
|
||||
/* wptr behind rptr */
|
||||
if ((rb->wptr + numcmds) >= rb->rptr)
|
||||
status = kgsl_ringbuffer_waitspace(rb, numcmds, 0);
|
||||
/* check for remaining space */
|
||||
/* reserve dwords for nop packet */
|
||||
if ((rb->wptr + numcmds) > (rb->sizedwords -
|
||||
GSL_RB_NOP_SIZEDWORDS))
|
||||
status = kgsl_ringbuffer_waitspace(rb, numcmds, 1);
|
||||
}
|
||||
|
||||
if (status == 0) {
|
||||
ptr = (unsigned int *)rb->buffer_desc.hostptr + rb->wptr;
|
||||
rb->wptr += numcmds;
|
||||
}
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
static int kgsl_ringbuffer_load_pm4_ucode(struct kgsl_device *device)
|
||||
{
|
||||
int status = 0;
|
||||
int i;
|
||||
const struct firmware *fw = NULL;
|
||||
unsigned int *fw_ptr = NULL;
|
||||
size_t fw_word_size = 0;
|
||||
|
||||
status = request_firmware(&fw, YAMATO_PM4_FW,
|
||||
kgsl_driver.misc.this_device);
|
||||
if (status != 0) {
|
||||
KGSL_DRV_ERR("request_firmware failed for %s with error %d\n",
|
||||
YAMATO_PM4_FW, status);
|
||||
goto done;
|
||||
}
|
||||
/*this firmware must come in 3 word chunks. plus 1 word of version*/
|
||||
if ((fw->size % (sizeof(uint32_t)*3)) != 4) {
|
||||
KGSL_DRV_ERR("bad firmware size %d.\n", fw->size);
|
||||
status = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
fw_ptr = (unsigned int *)fw->data;
|
||||
fw_word_size = fw->size/sizeof(uint32_t);
|
||||
KGSL_DRV_INFO("loading pm4 ucode version: %d\n", fw_ptr[0]);
|
||||
|
||||
kgsl_yamato_regwrite(device, REG_CP_DEBUG, 0x02000000);
|
||||
kgsl_yamato_regwrite(device, REG_CP_ME_RAM_WADDR, 0);
|
||||
for (i = 1; i < fw_word_size; i++)
|
||||
kgsl_yamato_regwrite(device, REG_CP_ME_RAM_DATA, fw_ptr[i]);
|
||||
|
||||
done:
|
||||
release_firmware(fw);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int kgsl_ringbuffer_load_pfp_ucode(struct kgsl_device *device)
|
||||
{
|
||||
int status = 0;
|
||||
int i;
|
||||
const struct firmware *fw = NULL;
|
||||
unsigned int *fw_ptr = NULL;
|
||||
size_t fw_word_size = 0;
|
||||
|
||||
status = request_firmware(&fw, YAMATO_PFP_FW,
|
||||
kgsl_driver.misc.this_device);
|
||||
if (status != 0) {
|
||||
KGSL_DRV_ERR("request_firmware for %s failed with error %d\n",
|
||||
YAMATO_PFP_FW, status);
|
||||
return status;
|
||||
}
|
||||
/*this firmware must come in 1 word chunks. */
|
||||
if ((fw->size % sizeof(uint32_t)) != 0) {
|
||||
KGSL_DRV_ERR("bad firmware size %d.\n", fw->size);
|
||||
release_firmware(fw);
|
||||
return -EINVAL;
|
||||
}
|
||||
fw_ptr = (unsigned int *)fw->data;
|
||||
fw_word_size = fw->size/sizeof(uint32_t);
|
||||
|
||||
KGSL_DRV_INFO("loading pfp ucode version: %d\n", fw_ptr[0]);
|
||||
|
||||
kgsl_yamato_regwrite(device, REG_CP_PFP_UCODE_ADDR, 0);
|
||||
for (i = 1; i < fw_word_size; i++)
|
||||
kgsl_yamato_regwrite(device, REG_CP_PFP_UCODE_DATA, fw_ptr[i]);
|
||||
|
||||
release_firmware(fw);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int kgsl_ringbuffer_start(struct kgsl_ringbuffer *rb)
|
||||
{
|
||||
int status;
|
||||
/*cp_rb_cntl_u cp_rb_cntl; */
|
||||
union reg_cp_rb_cntl cp_rb_cntl;
|
||||
unsigned int *cmds, rb_cntl;
|
||||
struct kgsl_device *device = rb->device;
|
||||
|
||||
KGSL_CMD_VDBG("enter (rb=%p)\n", rb);
|
||||
|
||||
if (rb->flags & KGSL_FLAGS_STARTED) {
|
||||
KGSL_CMD_VDBG("return %d\n", 0);
|
||||
return 0;
|
||||
}
|
||||
kgsl_sharedmem_set(&rb->memptrs_desc, 0, 0,
|
||||
sizeof(struct kgsl_rbmemptrs));
|
||||
|
||||
kgsl_sharedmem_set(&rb->buffer_desc, 0, 0xAA,
|
||||
(rb->sizedwords << 2));
|
||||
|
||||
kgsl_yamato_regwrite(device, REG_CP_RB_WPTR_BASE,
|
||||
(rb->memptrs_desc.gpuaddr
|
||||
+ GSL_RB_MEMPTRS_WPTRPOLL_OFFSET));
|
||||
|
||||
/* setup WPTR delay */
|
||||
kgsl_yamato_regwrite(device, REG_CP_RB_WPTR_DELAY, 0 /*0x70000010 */);
|
||||
|
||||
/*setup REG_CP_RB_CNTL */
|
||||
kgsl_yamato_regread(device, REG_CP_RB_CNTL, &rb_cntl);
|
||||
cp_rb_cntl.val = rb_cntl;
|
||||
/* size of ringbuffer */
|
||||
cp_rb_cntl.f.rb_bufsz =
|
||||
kgsl_ringbuffer_sizelog2quadwords(rb->sizedwords);
|
||||
/* quadwords to read before updating mem RPTR */
|
||||
cp_rb_cntl.f.rb_blksz = rb->blksizequadwords;
|
||||
cp_rb_cntl.f.rb_poll_en = GSL_RB_CNTL_POLL_EN; /* WPTR polling */
|
||||
/* mem RPTR writebacks */
|
||||
cp_rb_cntl.f.rb_no_update = GSL_RB_CNTL_NO_UPDATE;
|
||||
|
||||
kgsl_yamato_regwrite(device, REG_CP_RB_CNTL, cp_rb_cntl.val);
|
||||
|
||||
kgsl_yamato_regwrite(device, REG_CP_RB_BASE, rb->buffer_desc.gpuaddr);
|
||||
|
||||
kgsl_yamato_regwrite(device, REG_CP_RB_RPTR_ADDR,
|
||||
rb->memptrs_desc.gpuaddr +
|
||||
GSL_RB_MEMPTRS_RPTR_OFFSET);
|
||||
|
||||
/* explicitly clear all cp interrupts */
|
||||
kgsl_yamato_regwrite(device, REG_CP_INT_ACK, 0xFFFFFFFF);
|
||||
|
||||
/* setup scratch/timestamp */
|
||||
kgsl_yamato_regwrite(device, REG_SCRATCH_ADDR,
|
||||
device->memstore.gpuaddr +
|
||||
KGSL_DEVICE_MEMSTORE_OFFSET(soptimestamp));
|
||||
|
||||
kgsl_yamato_regwrite(device, REG_SCRATCH_UMSK,
|
||||
GSL_RB_MEMPTRS_SCRATCH_MASK);
|
||||
|
||||
/* load the CP ucode */
|
||||
|
||||
status = kgsl_ringbuffer_load_pm4_ucode(device);
|
||||
if (status != 0) {
|
||||
KGSL_DRV_ERR("kgsl_ringbuffer_load_pm4_ucode failed %d\n",
|
||||
status);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/* load the prefetch parser ucode */
|
||||
status = kgsl_ringbuffer_load_pfp_ucode(device);
|
||||
if (status != 0) {
|
||||
KGSL_DRV_ERR("kgsl_ringbuffer_load_pm4_ucode failed %d\n",
|
||||
status);
|
||||
return status;
|
||||
}
|
||||
|
||||
kgsl_yamato_regwrite(device, REG_CP_QUEUE_THRESHOLDS, 0x000C0804);
|
||||
|
||||
rb->rptr = 0;
|
||||
rb->wptr = 0;
|
||||
|
||||
rb->timestamp = 0;
|
||||
GSL_RB_INIT_TIMESTAMP(rb);
|
||||
|
||||
INIT_LIST_HEAD(&rb->memqueue);
|
||||
|
||||
/* clear ME_HALT to start micro engine */
|
||||
kgsl_yamato_regwrite(device, REG_CP_ME_CNTL, 0);
|
||||
|
||||
/* ME_INIT */
|
||||
cmds = kgsl_ringbuffer_allocspace(rb, 19);
|
||||
|
||||
GSL_RB_WRITE(cmds, PM4_HDR_ME_INIT);
|
||||
/* All fields present (bits 9:0) */
|
||||
GSL_RB_WRITE(cmds, 0x000003ff);
|
||||
/* Disable/Enable Real-Time Stream processing (present but ignored) */
|
||||
GSL_RB_WRITE(cmds, 0x00000000);
|
||||
/* Enable (2D <-> 3D) implicit synchronization (present but ignored) */
|
||||
GSL_RB_WRITE(cmds, 0x00000000);
|
||||
|
||||
GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(REG_RB_SURFACE_INFO));
|
||||
GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(REG_PA_SC_WINDOW_OFFSET));
|
||||
GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(REG_VGT_MAX_VTX_INDX));
|
||||
GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(REG_SQ_PROGRAM_CNTL));
|
||||
GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(REG_RB_DEPTHCONTROL));
|
||||
GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(REG_PA_SU_POINT_SIZE));
|
||||
GSL_RB_WRITE(cmds, GSL_HAL_SUBBLOCK_OFFSET(REG_PA_SC_LINE_CNTL));
|
||||
GSL_RB_WRITE(cmds,
|
||||
GSL_HAL_SUBBLOCK_OFFSET(REG_PA_SU_POLY_OFFSET_FRONT_SCALE));
|
||||
|
||||
/* Vertex and Pixel Shader Start Addresses in instructions
|
||||
* (3 DWORDS per instruction) */
|
||||
GSL_RB_WRITE(cmds, 0x80000180);
|
||||
/* Maximum Contexts */
|
||||
GSL_RB_WRITE(cmds, 0x00000001);
|
||||
/* Write Confirm Interval and The CP will wait the
|
||||
* wait_interval * 16 clocks between polling */
|
||||
GSL_RB_WRITE(cmds, 0x00000000);
|
||||
|
||||
/* NQ and External Memory Swap */
|
||||
GSL_RB_WRITE(cmds, 0x00000000);
|
||||
/* Protected mode error checking */
|
||||
GSL_RB_WRITE(cmds, GSL_RB_PROTECTED_MODE_CONTROL);
|
||||
/* Disable header dumping and Header dump address */
|
||||
GSL_RB_WRITE(cmds, 0x00000000);
|
||||
/* Header dump size */
|
||||
GSL_RB_WRITE(cmds, 0x00000000);
|
||||
|
||||
kgsl_ringbuffer_submit(rb);
|
||||
|
||||
/* idle device to validate ME INIT */
|
||||
status = kgsl_yamato_idle(device, KGSL_TIMEOUT_DEFAULT);
|
||||
|
||||
KGSL_CMD_DBG("enabling CP interrupts: mask %08lx\n", GSL_CP_INT_MASK);
|
||||
kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, GSL_CP_INT_MASK);
|
||||
if (status == 0)
|
||||
rb->flags |= KGSL_FLAGS_STARTED;
|
||||
|
||||
KGSL_CMD_VDBG("return %d\n", status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int kgsl_ringbuffer_stop(struct kgsl_ringbuffer *rb)
|
||||
{
|
||||
KGSL_CMD_VDBG("enter (rb=%p)\n", rb);
|
||||
|
||||
if (rb->flags & KGSL_FLAGS_STARTED) {
|
||||
KGSL_CMD_DBG("disabling CP interrupts: mask %08x\n", 0);
|
||||
kgsl_yamato_regwrite(rb->device, REG_CP_INT_CNTL, 0);
|
||||
|
||||
/* ME_HALT */
|
||||
kgsl_yamato_regwrite(rb->device, REG_CP_ME_CNTL, 0x10000000);
|
||||
|
||||
rb->flags &= ~KGSL_FLAGS_STARTED;
|
||||
kgsl_ringbuffer_dump(rb);
|
||||
}
|
||||
|
||||
KGSL_CMD_VDBG("return %d\n", 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kgsl_ringbuffer_init(struct kgsl_device *device)
|
||||
{
|
||||
int status;
|
||||
uint32_t flags;
|
||||
struct kgsl_ringbuffer *rb = &device->ringbuffer;
|
||||
|
||||
KGSL_CMD_VDBG("enter (device=%p)\n", device);
|
||||
|
||||
rb->device = device;
|
||||
rb->sizedwords = (2 << kgsl_cfg_rb_sizelog2quadwords);
|
||||
rb->blksizequadwords = kgsl_cfg_rb_blksizequadwords;
|
||||
|
||||
/* allocate memory for ringbuffer, needs to be double octword aligned
|
||||
* align on page from contiguous physical memory
|
||||
*/
|
||||
flags =
|
||||
(KGSL_MEMFLAGS_ALIGNPAGE | KGSL_MEMFLAGS_CONPHYS |
|
||||
KGSL_MEMFLAGS_STRICTREQUEST);
|
||||
|
||||
status = kgsl_sharedmem_alloc(flags, (rb->sizedwords << 2),
|
||||
&rb->buffer_desc);
|
||||
|
||||
if (status != 0) {
|
||||
kgsl_ringbuffer_close(rb);
|
||||
KGSL_CMD_VDBG("return %d\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* allocate memory for polling and timestamps */
|
||||
/* This really can be at 4 byte alignment boundry but for using MMU
|
||||
* we need to make it at page boundary */
|
||||
flags = (KGSL_MEMFLAGS_ALIGNPAGE | KGSL_MEMFLAGS_CONPHYS);
|
||||
|
||||
status = kgsl_sharedmem_alloc(flags, sizeof(struct kgsl_rbmemptrs),
|
||||
&rb->memptrs_desc);
|
||||
|
||||
if (status != 0) {
|
||||
kgsl_ringbuffer_close(rb);
|
||||
KGSL_CMD_VDBG("return %d\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* last allocation of init process is made here so map all
|
||||
* allocations to MMU */
|
||||
status = kgsl_yamato_setup_pt(device, device->mmu.defaultpagetable);
|
||||
if (status != 0) {
|
||||
kgsl_ringbuffer_close(rb);
|
||||
KGSL_CMD_VDBG("return %d\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* overlay structure on memptrs memory */
|
||||
rb->memptrs = (struct kgsl_rbmemptrs *) rb->memptrs_desc.hostptr;
|
||||
|
||||
rb->flags |= KGSL_FLAGS_INITIALIZED;
|
||||
|
||||
status = kgsl_ringbuffer_start(rb);
|
||||
if (status != 0) {
|
||||
kgsl_ringbuffer_close(rb);
|
||||
KGSL_CMD_VDBG("return %d\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
KGSL_CMD_VDBG("return %d\n", 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int kgsl_ringbuffer_close(struct kgsl_ringbuffer *rb)
|
||||
{
|
||||
KGSL_CMD_VDBG("enter (rb=%p)\n", rb);
|
||||
|
||||
kgsl_cmdstream_memqueue_drain(rb->device);
|
||||
|
||||
kgsl_ringbuffer_stop(rb);
|
||||
|
||||
/* this must happen before first sharedmem_free */
|
||||
kgsl_yamato_cleanup_pt(rb->device, rb->device->mmu.defaultpagetable);
|
||||
|
||||
if (rb->buffer_desc.hostptr)
|
||||
kgsl_sharedmem_free(&rb->buffer_desc);
|
||||
|
||||
if (rb->memptrs_desc.hostptr)
|
||||
kgsl_sharedmem_free(&rb->memptrs_desc);
|
||||
|
||||
rb->flags &= ~KGSL_FLAGS_INITIALIZED;
|
||||
|
||||
memset(rb, 0, sizeof(struct kgsl_ringbuffer));
|
||||
|
||||
KGSL_CMD_VDBG("return %d\n", 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
kgsl_ringbuffer_addcmds(struct kgsl_ringbuffer *rb,
|
||||
int flags, unsigned int *cmds,
|
||||
int sizedwords)
|
||||
{
|
||||
unsigned int *ringcmds;
|
||||
unsigned int timestamp;
|
||||
unsigned int total_sizedwords = sizedwords + 6;
|
||||
|
||||
/* reserve space to temporarily turn off protected mode
|
||||
* error checking if needed
|
||||
*/
|
||||
total_sizedwords += flags & KGSL_CMD_FLAGS_PMODE ? 4 : 0;
|
||||
total_sizedwords += !(flags & KGSL_CMD_FLAGS_NO_TS_CMP) ? 9 : 0;
|
||||
|
||||
ringcmds = kgsl_ringbuffer_allocspace(rb, total_sizedwords);
|
||||
|
||||
if (flags & KGSL_CMD_FLAGS_PMODE) {
|
||||
/* disable protected mode error checking */
|
||||
*ringcmds++ = pm4_type3_packet(PM4_SET_PROTECTED_MODE, 1);
|
||||
*ringcmds++ = 0;
|
||||
}
|
||||
|
||||
memcpy(ringcmds, cmds, (sizedwords << 2));
|
||||
|
||||
ringcmds += sizedwords;
|
||||
|
||||
if (flags & KGSL_CMD_FLAGS_PMODE) {
|
||||
/* re-enable protected mode error checking */
|
||||
*ringcmds++ = pm4_type3_packet(PM4_SET_PROTECTED_MODE, 1);
|
||||
*ringcmds++ = 1;
|
||||
}
|
||||
|
||||
rb->timestamp++;
|
||||
timestamp = rb->timestamp;
|
||||
|
||||
/* start-of-pipeline and end-of-pipeline timestamps */
|
||||
*ringcmds++ = pm4_type0_packet(REG_CP_TIMESTAMP, 1);
|
||||
*ringcmds++ = rb->timestamp;
|
||||
*ringcmds++ = pm4_type3_packet(PM4_EVENT_WRITE, 3);
|
||||
*ringcmds++ = CACHE_FLUSH_TS;
|
||||
*ringcmds++ =
|
||||
(rb->device->memstore.gpuaddr +
|
||||
KGSL_DEVICE_MEMSTORE_OFFSET(eoptimestamp));
|
||||
*ringcmds++ = rb->timestamp;
|
||||
|
||||
if (!(flags & KGSL_CMD_FLAGS_NO_TS_CMP)) {
|
||||
/* Add idle packet so avoid RBBM errors */
|
||||
*ringcmds++ = pm4_type3_packet(PM4_WAIT_FOR_IDLE, 1);
|
||||
*ringcmds++ = 0x00000000;
|
||||
/* Conditional execution based on memory values */
|
||||
*ringcmds++ = pm4_type3_packet(PM4_COND_EXEC, 4);
|
||||
*ringcmds++ = (rb->device->memstore.gpuaddr +
|
||||
KGSL_DEVICE_MEMSTORE_OFFSET(ts_cmp_enable)) >> 2;
|
||||
*ringcmds++ = (rb->device->memstore.gpuaddr +
|
||||
KGSL_DEVICE_MEMSTORE_OFFSET(ref_wait_ts)) >> 2;
|
||||
*ringcmds++ = rb->timestamp;
|
||||
/* # of conditional command DWORDs */
|
||||
*ringcmds++ = 2;
|
||||
*ringcmds++ = pm4_type3_packet(PM4_INTERRUPT, 1);
|
||||
*ringcmds++ = CP_INT_CNTL__RB_INT_MASK;
|
||||
}
|
||||
|
||||
kgsl_ringbuffer_submit(rb);
|
||||
|
||||
GSL_RB_STATS(rb->stats.words_total += sizedwords);
|
||||
GSL_RB_STATS(rb->stats.issues++);
|
||||
|
||||
KGSL_CMD_VDBG("return %d\n", timestamp);
|
||||
|
||||
/* return timestamp of issued coREG_ands */
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
kgsl_ringbuffer_issuecmds(struct kgsl_device *device,
|
||||
int flags,
|
||||
unsigned int *cmds,
|
||||
int sizedwords)
|
||||
{
|
||||
unsigned int timestamp;
|
||||
struct kgsl_ringbuffer *rb = &device->ringbuffer;
|
||||
|
||||
KGSL_CMD_VDBG("enter (device->id=%d, flags=%d, cmds=%p, "
|
||||
"sizedwords=%d)\n", device->id, flags, cmds, sizedwords);
|
||||
|
||||
timestamp = kgsl_ringbuffer_addcmds(rb, flags, cmds, sizedwords);
|
||||
|
||||
KGSL_CMD_VDBG("return %d\n)", timestamp);
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
int
|
||||
kgsl_ringbuffer_issueibcmds(struct kgsl_device *device,
|
||||
int drawctxt_index,
|
||||
uint32_t ibaddr,
|
||||
int sizedwords,
|
||||
uint32_t *timestamp,
|
||||
unsigned int flags)
|
||||
{
|
||||
unsigned int link[3];
|
||||
|
||||
KGSL_CMD_VDBG("enter (device_id=%d, drawctxt_index=%d, ibaddr=0x%08x,"
|
||||
" sizedwords=%d, timestamp=%p)\n",
|
||||
device->id, drawctxt_index, ibaddr,
|
||||
sizedwords, timestamp);
|
||||
|
||||
if (!(device->ringbuffer.flags & KGSL_FLAGS_STARTED)) {
|
||||
KGSL_CMD_VDBG("return %d\n", -EINVAL);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
BUG_ON(ibaddr == 0);
|
||||
BUG_ON(sizedwords == 0);
|
||||
|
||||
link[0] = PM4_HDR_INDIRECT_BUFFER_PFD;
|
||||
link[1] = ibaddr;
|
||||
link[2] = sizedwords;
|
||||
|
||||
kgsl_drawctxt_switch(device, &device->drawctxt[drawctxt_index], flags);
|
||||
|
||||
*timestamp = kgsl_ringbuffer_addcmds(&device->ringbuffer,
|
||||
0, &link[0], 3);
|
||||
|
||||
|
||||
KGSL_CMD_INFO("ctxt %d g %08x sd %d ts %d\n",
|
||||
drawctxt_index, ibaddr, sizedwords, *timestamp);
|
||||
|
||||
KGSL_CMD_VDBG("return %d\n", 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
void kgsl_ringbuffer_debug(struct kgsl_ringbuffer *rb,
|
||||
struct kgsl_rb_debug *rb_debug)
|
||||
{
|
||||
memset(rb_debug, 0, sizeof(struct kgsl_rb_debug));
|
||||
|
||||
rb_debug->mem_rptr = rb->memptrs->rptr;
|
||||
rb_debug->mem_wptr_poll = rb->memptrs->wptr_poll;
|
||||
kgsl_yamato_regread(rb->device, REG_CP_RB_BASE,
|
||||
(unsigned int *)&rb_debug->cp_rb_base);
|
||||
kgsl_yamato_regread(rb->device, REG_CP_RB_CNTL,
|
||||
(unsigned int *)&rb_debug->cp_rb_cntl);
|
||||
kgsl_yamato_regread(rb->device, REG_CP_RB_RPTR_ADDR,
|
||||
(unsigned int *)&rb_debug->cp_rb_rptr_addr);
|
||||
kgsl_yamato_regread(rb->device, REG_CP_RB_RPTR,
|
||||
(unsigned int *)&rb_debug->cp_rb_rptr);
|
||||
kgsl_yamato_regread(rb->device, REG_CP_RB_RPTR_WR,
|
||||
(unsigned int *)&rb_debug->cp_rb_rptr_wr);
|
||||
kgsl_yamato_regread(rb->device, REG_CP_RB_WPTR,
|
||||
(unsigned int *)&rb_debug->cp_rb_wptr);
|
||||
kgsl_yamato_regread(rb->device, REG_CP_RB_WPTR_DELAY,
|
||||
(unsigned int *)&rb_debug->cp_rb_wptr_delay);
|
||||
kgsl_yamato_regread(rb->device, REG_CP_RB_WPTR_BASE,
|
||||
(unsigned int *)&rb_debug->cp_rb_wptr_base);
|
||||
kgsl_yamato_regread(rb->device, REG_CP_IB1_BASE,
|
||||
(unsigned int *)&rb_debug->cp_ib1_base);
|
||||
kgsl_yamato_regread(rb->device, REG_CP_IB1_BUFSZ,
|
||||
(unsigned int *)&rb_debug->cp_ib1_bufsz);
|
||||
kgsl_yamato_regread(rb->device, REG_CP_IB2_BASE,
|
||||
(unsigned int *)&rb_debug->cp_ib2_base);
|
||||
kgsl_yamato_regread(rb->device, REG_CP_IB2_BUFSZ,
|
||||
(unsigned int *)&rb_debug->cp_ib2_bufsz);
|
||||
kgsl_yamato_regread(rb->device, REG_CP_ST_BASE,
|
||||
(unsigned int *)&rb_debug->cp_st_base);
|
||||
kgsl_yamato_regread(rb->device, REG_CP_ST_BUFSZ,
|
||||
(unsigned int *)&rb_debug->cp_st_bufsz);
|
||||
kgsl_yamato_regread(rb->device, REG_CP_CSQ_RB_STAT,
|
||||
(unsigned int *)&rb_debug->cp_csq_rb_stat);
|
||||
kgsl_yamato_regread(rb->device, REG_CP_CSQ_IB1_STAT,
|
||||
(unsigned int *)&rb_debug->cp_csq_ib1_stat);
|
||||
kgsl_yamato_regread(rb->device, REG_CP_CSQ_IB2_STAT,
|
||||
(unsigned int *)&rb_debug->cp_csq_ib2_stat);
|
||||
kgsl_yamato_regread(rb->device, REG_SCRATCH_UMSK,
|
||||
(unsigned int *)&rb_debug->scratch_umsk);
|
||||
kgsl_yamato_regread(rb->device, REG_SCRATCH_ADDR,
|
||||
(unsigned int *)&rb_debug->scratch_addr);
|
||||
kgsl_yamato_regread(rb->device, REG_CP_ME_CNTL,
|
||||
(unsigned int *)&rb_debug->cp_me_cntl);
|
||||
kgsl_yamato_regread(rb->device, REG_CP_ME_STATUS,
|
||||
(unsigned int *)&rb_debug->cp_me_status);
|
||||
kgsl_yamato_regread(rb->device, REG_CP_DEBUG,
|
||||
(unsigned int *)&rb_debug->cp_debug);
|
||||
kgsl_yamato_regread(rb->device, REG_CP_STAT,
|
||||
(unsigned int *)&rb_debug->cp_stat);
|
||||
kgsl_yamato_regread(rb->device, REG_CP_INT_STATUS,
|
||||
(unsigned int *)&rb_debug->cp_int_status);
|
||||
kgsl_yamato_regread(rb->device, REG_CP_INT_CNTL,
|
||||
(unsigned int *)&rb_debug->cp_int_cntl);
|
||||
kgsl_yamato_regread(rb->device, REG_RBBM_STATUS,
|
||||
(unsigned int *)&rb_debug->rbbm_status);
|
||||
kgsl_yamato_regread(rb->device, REG_RBBM_INT_STATUS,
|
||||
(unsigned int *)&rb_debug->rbbm_int_status);
|
||||
GSL_RB_GET_SOP_TIMESTAMP(rb, (unsigned int *)&rb_debug->sop_timestamp);
|
||||
GSL_RB_GET_EOP_TIMESTAMP(rb, (unsigned int *)&rb_debug->eop_timestamp);
|
||||
|
||||
}
|
||||
#endif /*DEBUG*/
|
||||
|
||||
#ifdef DEBUG
|
||||
void kgsl_ringbuffer_dump(struct kgsl_ringbuffer *rb)
|
||||
{
|
||||
struct kgsl_rb_debug rb_debug;
|
||||
kgsl_ringbuffer_debug(rb, &rb_debug);
|
||||
|
||||
KGSL_CMD_DBG("rbbm_status %08x rbbm_int_status %08x"
|
||||
" mem_rptr %08x mem_wptr_poll %08x\n",
|
||||
rb_debug.rbbm_status,
|
||||
rb_debug.rbbm_int_status,
|
||||
rb_debug.mem_rptr, rb_debug.mem_wptr_poll);
|
||||
|
||||
KGSL_CMD_DBG("rb_base %08x rb_cntl %08x rb_rptr_addr %08x rb_rptr %08x"
|
||||
" rb_rptr_wr %08x\n",
|
||||
rb_debug.cp_rb_base, rb_debug.cp_rb_cntl,
|
||||
rb_debug.cp_rb_rptr_addr, rb_debug.cp_rb_rptr,
|
||||
rb_debug.cp_rb_rptr_wr);
|
||||
|
||||
KGSL_CMD_DBG("rb_wptr %08x rb_wptr_delay %08x rb_wptr_base %08x"
|
||||
" ib1_base %08x ib1_bufsz %08x\n",
|
||||
rb_debug.cp_rb_wptr, rb_debug.cp_rb_wptr_delay,
|
||||
rb_debug.cp_rb_wptr_base, rb_debug.cp_ib1_base,
|
||||
rb_debug.cp_ib1_bufsz);
|
||||
|
||||
KGSL_CMD_DBG("ib2_base %08x ib2_bufsz %08x st_base %08x st_bufsz %08x"
|
||||
" cp_me_cntl %08x cp_me_status %08x\n",
|
||||
rb_debug.cp_ib2_base, rb_debug.cp_ib2_bufsz,
|
||||
rb_debug.cp_st_base, rb_debug.cp_st_bufsz,
|
||||
rb_debug.cp_me_cntl, rb_debug.cp_me_status);
|
||||
|
||||
KGSL_CMD_DBG("cp_debug %08x cp_stat %08x cp_int_status %08x"
|
||||
" cp_int_cntl %08x\n",
|
||||
rb_debug.cp_debug, rb_debug.cp_stat,
|
||||
rb_debug.cp_int_status, rb_debug.cp_int_cntl);
|
||||
|
||||
KGSL_CMD_DBG("sop_timestamp: %d eop_timestamp: %d\n",
|
||||
rb_debug.sop_timestamp, rb_debug.eop_timestamp);
|
||||
|
||||
}
|
||||
#endif /* DEBUG */
|
@ -1,254 +0,0 @@
|
||||
/*
|
||||
* (C) Copyright Advanced Micro Devices, Inc. 2002, 2007
|
||||
* Copyright (c) 2008-2009 QUALCOMM USA, INC.
|
||||
*
|
||||
* All source code in this file is licensed under the following license
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can find it at http://www.fsf.org
|
||||
*/
|
||||
#ifndef __GSL_RINGBUFFER_H
|
||||
#define __GSL_RINGBUFFER_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/msm_kgsl.h>
|
||||
#include <linux/mutex.h>
|
||||
#include "kgsl_log.h"
|
||||
#include "kgsl_sharedmem.h"
|
||||
#include "yamato_reg.h"
|
||||
|
||||
#define GSL_STATS_RINGBUFFER
|
||||
|
||||
#define GSL_RB_USE_MEM_RPTR
|
||||
#define GSL_RB_USE_MEM_TIMESTAMP
|
||||
#define GSL_DEVICE_SHADOW_MEMSTORE_TO_USER
|
||||
|
||||
/* ringbuffer sizes log2quadword */
|
||||
#define GSL_RB_SIZE_8 0
|
||||
#define GSL_RB_SIZE_16 1
|
||||
#define GSL_RB_SIZE_32 2
|
||||
#define GSL_RB_SIZE_64 3
|
||||
#define GSL_RB_SIZE_128 4
|
||||
#define GSL_RB_SIZE_256 5
|
||||
#define GSL_RB_SIZE_512 6
|
||||
#define GSL_RB_SIZE_1K 7
|
||||
#define GSL_RB_SIZE_2K 8
|
||||
#define GSL_RB_SIZE_4K 9
|
||||
#define GSL_RB_SIZE_8K 10
|
||||
#define GSL_RB_SIZE_16K 11
|
||||
#define GSL_RB_SIZE_32K 12
|
||||
#define GSL_RB_SIZE_64K 13
|
||||
#define GSL_RB_SIZE_128K 14
|
||||
#define GSL_RB_SIZE_256K 15
|
||||
#define GSL_RB_SIZE_512K 16
|
||||
#define GSL_RB_SIZE_1M 17
|
||||
#define GSL_RB_SIZE_2M 18
|
||||
#define GSL_RB_SIZE_4M 19
|
||||
|
||||
/* Yamato ringbuffer config*/
|
||||
static const unsigned int kgsl_cfg_rb_sizelog2quadwords = GSL_RB_SIZE_32K;
|
||||
static const unsigned int kgsl_cfg_rb_blksizequadwords = GSL_RB_SIZE_16;
|
||||
|
||||
/* CP timestamp register */
|
||||
#define REG_CP_TIMESTAMP REG_SCRATCH_REG0
|
||||
|
||||
|
||||
struct kgsl_device;
|
||||
struct kgsl_drawctxt;
|
||||
struct kgsl_ringbuffer;
|
||||
|
||||
struct kgsl_rb_debug {
|
||||
unsigned int pm4_ucode_rel;
|
||||
unsigned int pfp_ucode_rel;
|
||||
unsigned int mem_wptr_poll;
|
||||
unsigned int mem_rptr;
|
||||
unsigned int cp_rb_base;
|
||||
unsigned int cp_rb_cntl;
|
||||
unsigned int cp_rb_rptr_addr;
|
||||
unsigned int cp_rb_rptr;
|
||||
unsigned int cp_rb_rptr_wr;
|
||||
unsigned int cp_rb_wptr;
|
||||
unsigned int cp_rb_wptr_delay;
|
||||
unsigned int cp_rb_wptr_base;
|
||||
unsigned int cp_ib1_base;
|
||||
unsigned int cp_ib1_bufsz;
|
||||
unsigned int cp_ib2_base;
|
||||
unsigned int cp_ib2_bufsz;
|
||||
unsigned int cp_st_base;
|
||||
unsigned int cp_st_bufsz;
|
||||
unsigned int cp_csq_rb_stat;
|
||||
unsigned int cp_csq_ib1_stat;
|
||||
unsigned int cp_csq_ib2_stat;
|
||||
unsigned int scratch_umsk;
|
||||
unsigned int scratch_addr;
|
||||
unsigned int cp_me_cntl;
|
||||
unsigned int cp_me_status;
|
||||
unsigned int cp_debug;
|
||||
unsigned int cp_stat;
|
||||
unsigned int cp_int_status;
|
||||
unsigned int cp_int_cntl;
|
||||
unsigned int rbbm_status;
|
||||
unsigned int rbbm_int_status;
|
||||
unsigned int sop_timestamp;
|
||||
unsigned int eop_timestamp;
|
||||
};
|
||||
#ifdef DEBUG
|
||||
void kgsl_ringbuffer_debug(struct kgsl_ringbuffer *rb,
|
||||
struct kgsl_rb_debug *rb_debug);
|
||||
|
||||
void kgsl_ringbuffer_dump(struct kgsl_ringbuffer *rb);
|
||||
#else
|
||||
static inline void kgsl_ringbuffer_debug(struct kgsl_ringbuffer *rb,
|
||||
struct kgsl_rb_debug *rb_debug)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void kgsl_ringbuffer_dump(struct kgsl_ringbuffer *rb)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
struct kgsl_rbwatchdog {
|
||||
uint32_t flags;
|
||||
unsigned int rptr_sample;
|
||||
};
|
||||
|
||||
#define GSL_RB_MEMPTRS_SCRATCH_COUNT 8
|
||||
struct kgsl_rbmemptrs {
|
||||
volatile int rptr;
|
||||
volatile int wptr_poll;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#define GSL_RB_MEMPTRS_RPTR_OFFSET \
|
||||
(offsetof(struct kgsl_rbmemptrs, rptr))
|
||||
|
||||
#define GSL_RB_MEMPTRS_WPTRPOLL_OFFSET \
|
||||
(offsetof(struct kgsl_rbmemptrs, wptr_poll))
|
||||
|
||||
struct kgsl_rbstats {
|
||||
int64_t issues;
|
||||
int64_t words_total;
|
||||
};
|
||||
|
||||
|
||||
struct kgsl_ringbuffer {
|
||||
struct kgsl_device *device;
|
||||
uint32_t flags;
|
||||
|
||||
struct kgsl_memdesc buffer_desc;
|
||||
|
||||
struct kgsl_memdesc memptrs_desc;
|
||||
struct kgsl_rbmemptrs *memptrs;
|
||||
|
||||
/*ringbuffer size */
|
||||
unsigned int sizedwords;
|
||||
unsigned int blksizequadwords;
|
||||
|
||||
unsigned int wptr; /* write pointer offset in dwords from baseaddr */
|
||||
unsigned int rptr; /* read pointer offset in dwords from baseaddr */
|
||||
uint32_t timestamp;
|
||||
|
||||
/* queue of memfrees pending timestamp elapse */
|
||||
struct list_head memqueue;
|
||||
|
||||
struct kgsl_rbwatchdog watchdog;
|
||||
|
||||
#ifdef GSL_STATS_RINGBUFFER
|
||||
struct kgsl_rbstats stats;
|
||||
#endif /* GSL_STATS_RINGBUFFER */
|
||||
|
||||
};
|
||||
|
||||
/* dword base address of the GFX decode space */
|
||||
#define GSL_HAL_SUBBLOCK_OFFSET(reg) ((unsigned int)((reg) - (0x2000)))
|
||||
|
||||
#define GSL_RB_WRITE(ring, data) \
|
||||
do { \
|
||||
mb(); \
|
||||
writel(data, ring); \
|
||||
ring++; \
|
||||
} while (0)
|
||||
|
||||
/* timestamp */
|
||||
#ifdef GSL_DEVICE_SHADOW_MEMSTORE_TO_USER
|
||||
#define GSL_RB_USE_MEM_TIMESTAMP
|
||||
#endif /* GSL_DEVICE_SHADOW_MEMSTORE_TO_USER */
|
||||
|
||||
#ifdef GSL_RB_USE_MEM_TIMESTAMP
|
||||
/* enable timestamp (...scratch0) memory shadowing */
|
||||
#define GSL_RB_MEMPTRS_SCRATCH_MASK 0x1
|
||||
#define GSL_RB_INIT_TIMESTAMP(rb)
|
||||
|
||||
#else
|
||||
#define GSL_RB_MEMPTRS_SCRATCH_MASK 0x0
|
||||
#define GSL_RB_INIT_TIMESTAMP(rb) \
|
||||
kgsl_yamato_regwrite((rb)->device->id, REG_CP_TIMESTAMP, 0)
|
||||
|
||||
#endif /* GSL_RB_USE_MEMTIMESTAMP */
|
||||
|
||||
/* mem rptr */
|
||||
#ifdef GSL_RB_USE_MEM_RPTR
|
||||
#define GSL_RB_CNTL_NO_UPDATE 0x0 /* enable */
|
||||
#define GSL_RB_GET_READPTR(rb, data) \
|
||||
do { \
|
||||
*(data) = (rb)->memptrs->rptr; \
|
||||
} while (0)
|
||||
#else
|
||||
#define GSL_RB_CNTL_NO_UPDATE 0x1 /* disable */
|
||||
#define GSL_RB_GET_READPTR(rb, data) \
|
||||
do { \
|
||||
kgsl_yamato_regread((rb)->device->id, REG_CP_RB_RPTR, (data)); \
|
||||
} while (0)
|
||||
#endif /* GSL_RB_USE_MEMRPTR */
|
||||
|
||||
/* wptr polling */
|
||||
#ifdef GSL_RB_USE_WPTR_POLLING
|
||||
#define GSL_RB_CNTL_POLL_EN 0x1 /* enable */
|
||||
#define GSL_RB_UPDATE_WPTR_POLLING(rb) \
|
||||
do { (rb)->memptrs->wptr_poll = (rb)->wptr; } while (0)
|
||||
#else
|
||||
#define GSL_RB_CNTL_POLL_EN 0x0 /* disable */
|
||||
#define GSL_RB_UPDATE_WPTR_POLLING(rb)
|
||||
#endif /* GSL_RB_USE_WPTR_POLLING */
|
||||
|
||||
/* stats */
|
||||
#ifdef GSL_STATS_RINGBUFFER
|
||||
#define GSL_RB_STATS(x) x
|
||||
#else
|
||||
#define GSL_RB_STATS(x)
|
||||
#endif /* GSL_STATS_RINGBUFFER */
|
||||
|
||||
struct kgsl_pmem_entry;
|
||||
|
||||
int kgsl_ringbuffer_issueibcmds(struct kgsl_device *, int drawctxt_index,
|
||||
uint32_t ibaddr, int sizedwords,
|
||||
uint32_t *timestamp,
|
||||
unsigned int flags);
|
||||
|
||||
int kgsl_ringbuffer_init(struct kgsl_device *device);
|
||||
|
||||
int kgsl_ringbuffer_close(struct kgsl_ringbuffer *rb);
|
||||
|
||||
uint32_t kgsl_ringbuffer_issuecmds(struct kgsl_device *device,
|
||||
int pmodeoff,
|
||||
unsigned int *cmdaddr,
|
||||
int sizedwords);
|
||||
|
||||
int kgsl_ringbuffer_gettimestampshadow(struct kgsl_device *device,
|
||||
unsigned int *sopaddr,
|
||||
unsigned int *eopaddr);
|
||||
|
||||
void kgsl_ringbuffer_watchdog(void);
|
||||
|
||||
void kgsl_cp_intrcallback(struct kgsl_device *device);
|
||||
|
||||
#endif /* __GSL_RINGBUFFER_H */
|
@ -1,300 +0,0 @@
|
||||
/*
|
||||
* (C) Copyright Advanced Micro Devices, Inc. 2002, 2007
|
||||
* Copyright (c) 2008-2009 QUALCOMM USA, INC.
|
||||
*
|
||||
* All source code in this file is licensed under the following license
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can find it at http://www.fsf.org
|
||||
*/
|
||||
#include <linux/io.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/genalloc.h>
|
||||
|
||||
#include "kgsl_sharedmem.h"
|
||||
#include "kgsl_device.h"
|
||||
#include "kgsl.h"
|
||||
#include "kgsl_log.h"
|
||||
|
||||
/* block alignment shift count */
|
||||
static inline unsigned int
|
||||
kgsl_memarena_get_order(uint32_t flags)
|
||||
{
|
||||
unsigned int alignshift;
|
||||
alignshift = ((flags & KGSL_MEMFLAGS_ALIGN_MASK)
|
||||
>> KGSL_MEMFLAGS_ALIGN_SHIFT);
|
||||
return alignshift;
|
||||
}
|
||||
|
||||
/* block alignment shift count */
|
||||
static inline unsigned int
|
||||
kgsl_memarena_align(unsigned int address, unsigned int shift)
|
||||
{
|
||||
unsigned int alignedbaseaddr = ((address) >> shift) << shift;
|
||||
if (alignedbaseaddr < address)
|
||||
alignedbaseaddr += (1 << shift);
|
||||
|
||||
return alignedbaseaddr;
|
||||
}
|
||||
|
||||
int
|
||||
kgsl_sharedmem_init(struct kgsl_sharedmem *shmem)
|
||||
{
|
||||
int result = -EINVAL;
|
||||
|
||||
if (!request_mem_region(shmem->physbase, shmem->size, DRIVER_NAME)) {
|
||||
KGSL_MEM_ERR("request_mem_region failed\n");
|
||||
goto error;
|
||||
}
|
||||
|
||||
shmem->baseptr = ioremap(shmem->physbase, shmem->size);
|
||||
KGSL_MEM_INFO("ioremap(shm) = %p\n", shmem->baseptr);
|
||||
|
||||
if (shmem->baseptr == NULL) {
|
||||
KGSL_MEM_ERR("ioremap failed for address %08x size %d\n",
|
||||
shmem->physbase, shmem->size);
|
||||
result = -ENODEV;
|
||||
goto error_release_mem;
|
||||
}
|
||||
|
||||
shmem->pool = gen_pool_create(KGSL_PAGESIZE_SHIFT, -1);
|
||||
if (shmem->pool == NULL) {
|
||||
KGSL_MEM_ERR("gen_pool_create failed\n");
|
||||
result = -ENOMEM;
|
||||
goto error_iounmap;
|
||||
}
|
||||
|
||||
if (gen_pool_add(shmem->pool, shmem->physbase, shmem->size, -1)) {
|
||||
KGSL_MEM_ERR("gen_pool_create failed\n");
|
||||
result = -ENOMEM;
|
||||
goto error_pool_destroy;
|
||||
}
|
||||
result = 0;
|
||||
KGSL_MEM_INFO("physbase 0x%08x size 0x%08x baseptr 0x%p\n",
|
||||
shmem->physbase, shmem->size, shmem->baseptr);
|
||||
return 0;
|
||||
|
||||
error_pool_destroy:
|
||||
gen_pool_destroy(shmem->pool);
|
||||
error_iounmap:
|
||||
iounmap(shmem->baseptr);
|
||||
shmem->baseptr = NULL;
|
||||
error_release_mem:
|
||||
release_mem_region(shmem->physbase, shmem->size);
|
||||
error:
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
kgsl_sharedmem_close(struct kgsl_sharedmem *shmem)
|
||||
{
|
||||
if (shmem->pool) {
|
||||
gen_pool_destroy(shmem->pool);
|
||||
shmem->pool = NULL;
|
||||
}
|
||||
|
||||
if (shmem->baseptr != NULL) {
|
||||
KGSL_MEM_INFO("iounmap(shm) = %p\n", shmem->baseptr);
|
||||
iounmap(shmem->baseptr);
|
||||
shmem->baseptr = NULL;
|
||||
release_mem_region(shmem->physbase, shmem->size);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*
|
||||
* get the host mapped address for a hardware device address
|
||||
*/
|
||||
static void *kgsl_memarena_gethostptr(struct kgsl_sharedmem *shmem,
|
||||
uint32_t physaddr)
|
||||
{
|
||||
void *result;
|
||||
|
||||
KGSL_MEM_VDBG("enter (memarena=%p, physaddr=0x%08x)\n",
|
||||
shmem, physaddr);
|
||||
|
||||
BUG_ON(shmem == NULL);
|
||||
|
||||
/* check address range */
|
||||
if (physaddr < shmem->physbase)
|
||||
return NULL;
|
||||
|
||||
if (physaddr >= shmem->physbase + shmem->size)
|
||||
return NULL;
|
||||
|
||||
if (shmem->baseptr == NULL) {
|
||||
KGSL_MEM_VDBG("return: %p\n", NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = ((physaddr - shmem->physbase) + shmem->baseptr);
|
||||
|
||||
KGSL_MEM_VDBG("return: %p\n", result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
kgsl_sharedmem_alloc(uint32_t flags, int size,
|
||||
struct kgsl_memdesc *memdesc)
|
||||
{
|
||||
struct kgsl_sharedmem *shmem;
|
||||
int result = -ENOMEM;
|
||||
unsigned int blksize;
|
||||
unsigned int baseaddr;
|
||||
unsigned int alignshift;
|
||||
unsigned int alignedbaseaddr;
|
||||
|
||||
KGSL_MEM_VDBG("enter (flags=0x%08x, size=%d, memdesc=%p)\n",
|
||||
flags, size, memdesc);
|
||||
|
||||
shmem = &kgsl_driver.shmem;
|
||||
BUG_ON(memdesc == NULL);
|
||||
BUG_ON(size <= 0);
|
||||
|
||||
alignshift = kgsl_memarena_get_order(flags);
|
||||
|
||||
size = ALIGN(size, KGSL_PAGESIZE);
|
||||
blksize = size;
|
||||
if (alignshift > KGSL_PAGESIZE_SHIFT)
|
||||
blksize += (1 << alignshift) - KGSL_PAGESIZE;
|
||||
|
||||
baseaddr = gen_pool_alloc(shmem->pool, blksize);
|
||||
if (baseaddr == 0) {
|
||||
KGSL_MEM_ERR("gen_pool_alloc failed\n");
|
||||
result = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
result = 0;
|
||||
|
||||
if (alignshift > KGSL_PAGESIZE_SHIFT) {
|
||||
alignedbaseaddr = ALIGN(baseaddr, (1 << alignshift));
|
||||
|
||||
KGSL_MEM_VDBG("ba %x al %x as %d m->as %d bs %x s %x\n",
|
||||
baseaddr, alignedbaseaddr, alignshift,
|
||||
KGSL_PAGESIZE_SHIFT, blksize, size);
|
||||
if (alignedbaseaddr > baseaddr) {
|
||||
KGSL_MEM_VDBG("physaddr %x free before %x size %x\n",
|
||||
alignedbaseaddr,
|
||||
baseaddr, alignedbaseaddr - baseaddr);
|
||||
gen_pool_free(shmem->pool, baseaddr,
|
||||
alignedbaseaddr - baseaddr);
|
||||
blksize -= alignedbaseaddr - baseaddr;
|
||||
}
|
||||
if (blksize > size) {
|
||||
KGSL_MEM_VDBG("physaddr %x free after %x size %x\n",
|
||||
alignedbaseaddr,
|
||||
alignedbaseaddr + size,
|
||||
blksize - size);
|
||||
gen_pool_free(shmem->pool,
|
||||
alignedbaseaddr + size,
|
||||
blksize - size);
|
||||
}
|
||||
} else {
|
||||
alignedbaseaddr = baseaddr;
|
||||
}
|
||||
|
||||
memdesc->physaddr = alignedbaseaddr;
|
||||
memdesc->hostptr = kgsl_memarena_gethostptr(shmem, memdesc->physaddr);
|
||||
memdesc->size = size;
|
||||
|
||||
KGSL_MEM_VDBG("ashift %d m->ashift %d blksize %d base %x abase %x\n",
|
||||
alignshift, KGSL_PAGESIZE_SHIFT, blksize, baseaddr,
|
||||
alignedbaseaddr);
|
||||
|
||||
done:
|
||||
if (result)
|
||||
memset(memdesc, 0, sizeof(*memdesc));
|
||||
|
||||
|
||||
KGSL_MEM_VDBG("return: %d\n", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
kgsl_sharedmem_free(struct kgsl_memdesc *memdesc)
|
||||
{
|
||||
struct kgsl_sharedmem *shmem = &kgsl_driver.shmem;
|
||||
|
||||
KGSL_MEM_VDBG("enter (shmem=%p, memdesc=%p, physaddr=%08x, size=%d)\n",
|
||||
shmem, memdesc, memdesc->physaddr, memdesc->size);
|
||||
|
||||
BUG_ON(memdesc == NULL);
|
||||
BUG_ON(memdesc->size <= 0);
|
||||
BUG_ON(shmem->physbase > memdesc->physaddr);
|
||||
BUG_ON((shmem->physbase + shmem->size)
|
||||
< (memdesc->physaddr + memdesc->size));
|
||||
|
||||
gen_pool_free(shmem->pool, memdesc->physaddr, memdesc->size);
|
||||
|
||||
memset(memdesc, 0, sizeof(struct kgsl_memdesc));
|
||||
KGSL_MEM_VDBG("return\n");
|
||||
}
|
||||
|
||||
int
|
||||
kgsl_sharedmem_read(const struct kgsl_memdesc *memdesc, void *dst,
|
||||
unsigned int offsetbytes, unsigned int sizebytes)
|
||||
{
|
||||
if (memdesc == NULL || memdesc->hostptr == NULL || dst == NULL) {
|
||||
KGSL_MEM_ERR("bad ptr memdesc %p hostptr %p dst %p\n",
|
||||
memdesc,
|
||||
(memdesc ? memdesc->hostptr : NULL),
|
||||
dst);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (offsetbytes + sizebytes > memdesc->size) {
|
||||
KGSL_MEM_ERR("bad range: offset %d size %d memdesc %d\n",
|
||||
offsetbytes, sizebytes, memdesc->size);
|
||||
return -ERANGE;
|
||||
}
|
||||
memcpy(dst, memdesc->hostptr + offsetbytes, sizebytes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
kgsl_sharedmem_write(const struct kgsl_memdesc *memdesc,
|
||||
unsigned int offsetbytes,
|
||||
void *value, unsigned int sizebytes)
|
||||
{
|
||||
if (memdesc == NULL || memdesc->hostptr == NULL) {
|
||||
KGSL_MEM_ERR("bad ptr memdesc %p hostptr %p\n", memdesc,
|
||||
(memdesc ? memdesc->hostptr : NULL));
|
||||
return -EINVAL;
|
||||
}
|
||||
if (offsetbytes + sizebytes > memdesc->size) {
|
||||
KGSL_MEM_ERR("bad range: offset %d size %d memdesc %d\n",
|
||||
offsetbytes, sizebytes, memdesc->size);
|
||||
return -ERANGE;
|
||||
}
|
||||
memcpy(memdesc->hostptr + offsetbytes, value, sizebytes);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
kgsl_sharedmem_set(const struct kgsl_memdesc *memdesc, unsigned int offsetbytes,
|
||||
unsigned int value, unsigned int sizebytes)
|
||||
{
|
||||
if (memdesc == NULL || memdesc->hostptr == NULL) {
|
||||
KGSL_MEM_ERR("bad ptr memdesc %p hostptr %p\n", memdesc,
|
||||
(memdesc ? memdesc->hostptr : NULL));
|
||||
return -EINVAL;
|
||||
}
|
||||
if (offsetbytes + sizebytes > memdesc->size) {
|
||||
KGSL_MEM_ERR("bad range: offset %d size %d memdesc %d\n",
|
||||
offsetbytes, sizebytes, memdesc->size);
|
||||
return -ERANGE;
|
||||
}
|
||||
memset(memdesc->hostptr + offsetbytes, value, sizebytes);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,111 +0,0 @@
|
||||
/*
|
||||
* (C) Copyright Advanced Micro Devices, Inc. 2002, 2007
|
||||
* Copyright (c) 2008-2009 QUALCOMM USA, INC.
|
||||
*
|
||||
* All source code in this file is licensed under the following license
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can find it at http://www.fsf.org
|
||||
*/
|
||||
#ifndef __GSL_SHAREDMEM_H
|
||||
#define __GSL_SHAREDMEM_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/msm_kgsl.h>
|
||||
|
||||
#define KGSL_PAGESIZE 0x1000
|
||||
#define KGSL_PAGESIZE_SHIFT 12
|
||||
#define KGSL_PAGEMASK (~(KGSL_PAGESIZE - 1))
|
||||
|
||||
struct kgsl_pagetable;
|
||||
|
||||
struct platform_device;
|
||||
struct gen_pool;
|
||||
|
||||
/* memory allocation flags */
|
||||
#define KGSL_MEMFLAGS_ANY 0x00000000 /*dont care*/
|
||||
|
||||
#define KGSL_MEMFLAGS_APERTUREANY 0x00000000
|
||||
#define KGSL_MEMFLAGS_EMEM 0x00000000
|
||||
#define KGSL_MEMFLAGS_CONPHYS 0x00001000
|
||||
|
||||
#define KGSL_MEMFLAGS_ALIGNANY 0x00000000
|
||||
#define KGSL_MEMFLAGS_ALIGN32 0x00000000
|
||||
#define KGSL_MEMFLAGS_ALIGN64 0x00060000
|
||||
#define KGSL_MEMFLAGS_ALIGN128 0x00070000
|
||||
#define KGSL_MEMFLAGS_ALIGN256 0x00080000
|
||||
#define KGSL_MEMFLAGS_ALIGN512 0x00090000
|
||||
#define KGSL_MEMFLAGS_ALIGN1K 0x000A0000
|
||||
#define KGSL_MEMFLAGS_ALIGN2K 0x000B0000
|
||||
#define KGSL_MEMFLAGS_ALIGN4K 0x000C0000
|
||||
#define KGSL_MEMFLAGS_ALIGN8K 0x000D0000
|
||||
#define KGSL_MEMFLAGS_ALIGN16K 0x000E0000
|
||||
#define KGSL_MEMFLAGS_ALIGN32K 0x000F0000
|
||||
#define KGSL_MEMFLAGS_ALIGN64K 0x00100000
|
||||
#define KGSL_MEMFLAGS_ALIGNPAGE KGSL_MEMFLAGS_ALIGN4K
|
||||
|
||||
/* fail the alloc if the flags cannot be honored */
|
||||
#define KGSL_MEMFLAGS_STRICTREQUEST 0x80000000
|
||||
|
||||
#define KGSL_MEMFLAGS_APERTURE_MASK 0x0000F000
|
||||
#define KGSL_MEMFLAGS_ALIGN_MASK 0x00FF0000
|
||||
|
||||
#define KGSL_MEMFLAGS_APERTURE_SHIFT 12
|
||||
#define KGSL_MEMFLAGS_ALIGN_SHIFT 16
|
||||
|
||||
|
||||
/* shared memory allocation */
|
||||
struct kgsl_memdesc {
|
||||
struct kgsl_pagetable *pagetable;
|
||||
void *hostptr;
|
||||
unsigned int gpuaddr;
|
||||
unsigned int physaddr;
|
||||
unsigned int size;
|
||||
unsigned int priv;
|
||||
};
|
||||
|
||||
struct kgsl_sharedmem {
|
||||
void *baseptr;
|
||||
unsigned int physbase;
|
||||
unsigned int size;
|
||||
struct gen_pool *pool;
|
||||
};
|
||||
|
||||
int kgsl_sharedmem_alloc(uint32_t flags, int size,
|
||||
struct kgsl_memdesc *memdesc);
|
||||
|
||||
/*TODO: add protection flags */
|
||||
int kgsl_sharedmem_import(struct kgsl_pagetable *,
|
||||
uint32_t phys_addr,
|
||||
uint32_t size,
|
||||
struct kgsl_memdesc *memdesc);
|
||||
|
||||
|
||||
void kgsl_sharedmem_free(struct kgsl_memdesc *memdesc);
|
||||
|
||||
|
||||
int kgsl_sharedmem_read(const struct kgsl_memdesc *memdesc, void *dst,
|
||||
unsigned int offsetbytes, unsigned int sizebytes);
|
||||
|
||||
int kgsl_sharedmem_write(const struct kgsl_memdesc *memdesc,
|
||||
unsigned int offsetbytes, void *value,
|
||||
unsigned int sizebytes);
|
||||
|
||||
int kgsl_sharedmem_set(const struct kgsl_memdesc *memdesc,
|
||||
unsigned int offsetbytes, unsigned int value,
|
||||
unsigned int sizebytes);
|
||||
|
||||
int kgsl_sharedmem_init(struct kgsl_sharedmem *shmem);
|
||||
|
||||
int kgsl_sharedmem_close(struct kgsl_sharedmem *shmem);
|
||||
|
||||
#endif /* __GSL_SHAREDMEM_H */
|
File diff suppressed because it is too large
Load Diff
@ -1,400 +0,0 @@
|
||||
/*
|
||||
* (C) Copyright Advanced Micro Devices, Inc. 2002, 2007
|
||||
* Copyright (c) 2008-2009 QUALCOMM USA, INC.
|
||||
*
|
||||
* All source code in this file is licensed under the following license
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can find it at http://www.fsf.org
|
||||
*/
|
||||
#ifndef _YAMATO_REG_H
|
||||
#define _YAMATO_REG_H
|
||||
|
||||
enum VGT_EVENT_TYPE {
|
||||
VS_DEALLOC = 0,
|
||||
PS_DEALLOC = 1,
|
||||
VS_DONE_TS = 2,
|
||||
PS_DONE_TS = 3,
|
||||
CACHE_FLUSH_TS = 4,
|
||||
CONTEXT_DONE = 5,
|
||||
CACHE_FLUSH = 6,
|
||||
VIZQUERY_START = 7,
|
||||
VIZQUERY_END = 8,
|
||||
SC_WAIT_WC = 9,
|
||||
RST_PIX_CNT = 13,
|
||||
RST_VTX_CNT = 14,
|
||||
TILE_FLUSH = 15,
|
||||
CACHE_FLUSH_AND_INV_TS_EVENT = 20,
|
||||
ZPASS_DONE = 21,
|
||||
CACHE_FLUSH_AND_INV_EVENT = 22,
|
||||
PERFCOUNTER_START = 23,
|
||||
PERFCOUNTER_STOP = 24,
|
||||
VS_FETCH_DONE = 27,
|
||||
FACENESS_FLUSH = 28,
|
||||
};
|
||||
|
||||
enum COLORFORMATX {
|
||||
COLORX_4_4_4_4 = 0,
|
||||
COLORX_1_5_5_5 = 1,
|
||||
COLORX_5_6_5 = 2,
|
||||
COLORX_8 = 3,
|
||||
COLORX_8_8 = 4,
|
||||
COLORX_8_8_8_8 = 5,
|
||||
COLORX_S8_8_8_8 = 6,
|
||||
COLORX_16_FLOAT = 7,
|
||||
COLORX_16_16_FLOAT = 8,
|
||||
COLORX_16_16_16_16_FLOAT = 9,
|
||||
COLORX_32_FLOAT = 10,
|
||||
COLORX_32_32_FLOAT = 11,
|
||||
COLORX_32_32_32_32_FLOAT = 12,
|
||||
COLORX_2_3_3 = 13,
|
||||
COLORX_8_8_8 = 14,
|
||||
};
|
||||
|
||||
enum SURFACEFORMAT {
|
||||
FMT_1_REVERSE = 0,
|
||||
FMT_1 = 1,
|
||||
FMT_8 = 2,
|
||||
FMT_1_5_5_5 = 3,
|
||||
FMT_5_6_5 = 4,
|
||||
FMT_6_5_5 = 5,
|
||||
FMT_8_8_8_8 = 6,
|
||||
FMT_2_10_10_10 = 7,
|
||||
FMT_8_A = 8,
|
||||
FMT_8_B = 9,
|
||||
FMT_8_8 = 10,
|
||||
FMT_Cr_Y1_Cb_Y0 = 11,
|
||||
FMT_Y1_Cr_Y0_Cb = 12,
|
||||
FMT_5_5_5_1 = 13,
|
||||
FMT_8_8_8_8_A = 14,
|
||||
FMT_4_4_4_4 = 15,
|
||||
FMT_10_11_11 = 16,
|
||||
FMT_11_11_10 = 17,
|
||||
FMT_DXT1 = 18,
|
||||
FMT_DXT2_3 = 19,
|
||||
FMT_DXT4_5 = 20,
|
||||
FMT_24_8 = 22,
|
||||
FMT_24_8_FLOAT = 23,
|
||||
FMT_16 = 24,
|
||||
FMT_16_16 = 25,
|
||||
FMT_16_16_16_16 = 26,
|
||||
FMT_16_EXPAND = 27,
|
||||
FMT_16_16_EXPAND = 28,
|
||||
FMT_16_16_16_16_EXPAND = 29,
|
||||
FMT_16_FLOAT = 30,
|
||||
FMT_16_16_FLOAT = 31,
|
||||
FMT_16_16_16_16_FLOAT = 32,
|
||||
FMT_32 = 33,
|
||||
FMT_32_32 = 34,
|
||||
FMT_32_32_32_32 = 35,
|
||||
FMT_32_FLOAT = 36,
|
||||
FMT_32_32_FLOAT = 37,
|
||||
FMT_32_32_32_32_FLOAT = 38,
|
||||
FMT_32_AS_8 = 39,
|
||||
FMT_32_AS_8_8 = 40,
|
||||
FMT_16_MPEG = 41,
|
||||
FMT_16_16_MPEG = 42,
|
||||
FMT_8_INTERLACED = 43,
|
||||
FMT_32_AS_8_INTERLACED = 44,
|
||||
FMT_32_AS_8_8_INTERLACED = 45,
|
||||
FMT_16_INTERLACED = 46,
|
||||
FMT_16_MPEG_INTERLACED = 47,
|
||||
FMT_16_16_MPEG_INTERLACED = 48,
|
||||
FMT_DXN = 49,
|
||||
FMT_8_8_8_8_AS_16_16_16_16 = 50,
|
||||
FMT_DXT1_AS_16_16_16_16 = 51,
|
||||
FMT_DXT2_3_AS_16_16_16_16 = 52,
|
||||
FMT_DXT4_5_AS_16_16_16_16 = 53,
|
||||
FMT_2_10_10_10_AS_16_16_16_16 = 54,
|
||||
FMT_10_11_11_AS_16_16_16_16 = 55,
|
||||
FMT_11_11_10_AS_16_16_16_16 = 56,
|
||||
FMT_32_32_32_FLOAT = 57,
|
||||
FMT_DXT3A = 58,
|
||||
FMT_DXT5A = 59,
|
||||
FMT_CTX1 = 60,
|
||||
FMT_DXT3A_AS_1_1_1_1 = 61
|
||||
};
|
||||
|
||||
#define RB_EDRAM_INFO_EDRAM_SIZE_SIZE 4
|
||||
#define RB_EDRAM_INFO_EDRAM_MAPPING_MODE_SIZE 2
|
||||
#define RB_EDRAM_INFO_UNUSED0_SIZE 8
|
||||
#define RB_EDRAM_INFO_EDRAM_RANGE_SIZE 18
|
||||
|
||||
struct rb_edram_info_t {
|
||||
unsigned int edram_size:RB_EDRAM_INFO_EDRAM_SIZE_SIZE;
|
||||
unsigned int edram_mapping_mode:RB_EDRAM_INFO_EDRAM_MAPPING_MODE_SIZE;
|
||||
unsigned int unused0:RB_EDRAM_INFO_UNUSED0_SIZE;
|
||||
unsigned int edram_range:RB_EDRAM_INFO_EDRAM_RANGE_SIZE;
|
||||
};
|
||||
|
||||
union reg_rb_edram_info {
|
||||
unsigned int val:32;
|
||||
struct rb_edram_info_t f;
|
||||
};
|
||||
|
||||
#define CP_RB_CNTL_RB_BUFSZ_SIZE 6
|
||||
#define CP_RB_CNTL_UNUSED0_SIZE 2
|
||||
#define CP_RB_CNTL_RB_BLKSZ_SIZE 6
|
||||
#define CP_RB_CNTL_UNUSED1_SIZE 2
|
||||
#define CP_RB_CNTL_BUF_SWAP_SIZE 2
|
||||
#define CP_RB_CNTL_UNUSED2_SIZE 2
|
||||
#define CP_RB_CNTL_RB_POLL_EN_SIZE 1
|
||||
#define CP_RB_CNTL_UNUSED3_SIZE 6
|
||||
#define CP_RB_CNTL_RB_NO_UPDATE_SIZE 1
|
||||
#define CP_RB_CNTL_UNUSED4_SIZE 3
|
||||
#define CP_RB_CNTL_RB_RPTR_WR_ENA_SIZE 1
|
||||
|
||||
struct cp_rb_cntl_t {
|
||||
unsigned int rb_bufsz:CP_RB_CNTL_RB_BUFSZ_SIZE;
|
||||
unsigned int unused0:CP_RB_CNTL_UNUSED0_SIZE;
|
||||
unsigned int rb_blksz:CP_RB_CNTL_RB_BLKSZ_SIZE;
|
||||
unsigned int unused1:CP_RB_CNTL_UNUSED1_SIZE;
|
||||
unsigned int buf_swap:CP_RB_CNTL_BUF_SWAP_SIZE;
|
||||
unsigned int unused2:CP_RB_CNTL_UNUSED2_SIZE;
|
||||
unsigned int rb_poll_en:CP_RB_CNTL_RB_POLL_EN_SIZE;
|
||||
unsigned int unused3:CP_RB_CNTL_UNUSED3_SIZE;
|
||||
unsigned int rb_no_update:CP_RB_CNTL_RB_NO_UPDATE_SIZE;
|
||||
unsigned int unused4:CP_RB_CNTL_UNUSED4_SIZE;
|
||||
unsigned int rb_rptr_wr_ena:CP_RB_CNTL_RB_RPTR_WR_ENA_SIZE;
|
||||
};
|
||||
|
||||
union reg_cp_rb_cntl {
|
||||
unsigned int val:32;
|
||||
struct cp_rb_cntl_t f;
|
||||
};
|
||||
|
||||
#define RB_COLOR_INFO__COLOR_FORMAT_MASK 0x0000000fL
|
||||
#define RB_COPY_DEST_INFO__COPY_DEST_FORMAT__SHIFT 0x00000004
|
||||
|
||||
|
||||
#define SQ_INT_CNTL__PS_WATCHDOG_MASK 0x00000001L
|
||||
#define SQ_INT_CNTL__VS_WATCHDOG_MASK 0x00000002L
|
||||
|
||||
#define MH_INTERRUPT_MASK__AXI_READ_ERROR 0x00000001L
|
||||
#define MH_INTERRUPT_MASK__AXI_WRITE_ERROR 0x00000002L
|
||||
#define MH_INTERRUPT_MASK__MMU_PAGE_FAULT 0x00000004L
|
||||
|
||||
#define RBBM_INT_CNTL__RDERR_INT_MASK 0x00000001L
|
||||
#define RBBM_INT_CNTL__DISPLAY_UPDATE_INT_MASK 0x00000002L
|
||||
#define RBBM_INT_CNTL__GUI_IDLE_INT_MASK 0x00080000L
|
||||
|
||||
#define RBBM_STATUS__CMDFIFO_AVAIL_MASK 0x0000001fL
|
||||
#define RBBM_STATUS__TC_BUSY_MASK 0x00000020L
|
||||
#define RBBM_STATUS__HIRQ_PENDING_MASK 0x00000100L
|
||||
#define RBBM_STATUS__CPRQ_PENDING_MASK 0x00000200L
|
||||
#define RBBM_STATUS__CFRQ_PENDING_MASK 0x00000400L
|
||||
#define RBBM_STATUS__PFRQ_PENDING_MASK 0x00000800L
|
||||
#define RBBM_STATUS__VGT_BUSY_NO_DMA_MASK 0x00001000L
|
||||
#define RBBM_STATUS__RBBM_WU_BUSY_MASK 0x00004000L
|
||||
#define RBBM_STATUS__CP_NRT_BUSY_MASK 0x00010000L
|
||||
#define RBBM_STATUS__MH_BUSY_MASK 0x00040000L
|
||||
#define RBBM_STATUS__MH_COHERENCY_BUSY_MASK 0x00080000L
|
||||
#define RBBM_STATUS__SX_BUSY_MASK 0x00200000L
|
||||
#define RBBM_STATUS__TPC_BUSY_MASK 0x00400000L
|
||||
#define RBBM_STATUS__SC_CNTX_BUSY_MASK 0x01000000L
|
||||
#define RBBM_STATUS__PA_BUSY_MASK 0x02000000L
|
||||
#define RBBM_STATUS__VGT_BUSY_MASK 0x04000000L
|
||||
#define RBBM_STATUS__SQ_CNTX17_BUSY_MASK 0x08000000L
|
||||
#define RBBM_STATUS__SQ_CNTX0_BUSY_MASK 0x10000000L
|
||||
#define RBBM_STATUS__RB_CNTX_BUSY_MASK 0x40000000L
|
||||
#define RBBM_STATUS__GUI_ACTIVE_MASK 0x80000000L
|
||||
|
||||
#define CP_INT_CNTL__SW_INT_MASK 0x00080000L
|
||||
#define CP_INT_CNTL__T0_PACKET_IN_IB_MASK 0x00800000L
|
||||
#define CP_INT_CNTL__OPCODE_ERROR_MASK 0x01000000L
|
||||
#define CP_INT_CNTL__PROTECTED_MODE_ERROR_MASK 0x02000000L
|
||||
#define CP_INT_CNTL__RESERVED_BIT_ERROR_MASK 0x04000000L
|
||||
#define CP_INT_CNTL__IB_ERROR_MASK 0x08000000L
|
||||
#define CP_INT_CNTL__IB2_INT_MASK 0x20000000L
|
||||
#define CP_INT_CNTL__IB1_INT_MASK 0x40000000L
|
||||
#define CP_INT_CNTL__RB_INT_MASK 0x80000000L
|
||||
|
||||
#define MASTER_INT_SIGNAL__MH_INT_STAT 0x00000020L
|
||||
#define MASTER_INT_SIGNAL__SQ_INT_STAT 0x04000000L
|
||||
#define MASTER_INT_SIGNAL__CP_INT_STAT 0x40000000L
|
||||
#define MASTER_INT_SIGNAL__RBBM_INT_STAT 0x80000000L
|
||||
|
||||
#define RB_EDRAM_INFO__EDRAM_SIZE_MASK 0x0000000fL
|
||||
#define RB_EDRAM_INFO__EDRAM_RANGE_MASK 0xffffc000L
|
||||
|
||||
#define MH_ARBITER_CONFIG__SAME_PAGE_GRANULARITY__SHIFT 0x00000006
|
||||
#define MH_ARBITER_CONFIG__L1_ARB_ENABLE__SHIFT 0x00000007
|
||||
#define MH_ARBITER_CONFIG__L1_ARB_HOLD_ENABLE__SHIFT 0x00000008
|
||||
#define MH_ARBITER_CONFIG__L2_ARB_CONTROL__SHIFT 0x00000009
|
||||
#define MH_ARBITER_CONFIG__PAGE_SIZE__SHIFT 0x0000000a
|
||||
#define MH_ARBITER_CONFIG__TC_REORDER_ENABLE__SHIFT 0x0000000d
|
||||
#define MH_ARBITER_CONFIG__TC_ARB_HOLD_ENABLE__SHIFT 0x0000000e
|
||||
#define MH_ARBITER_CONFIG__IN_FLIGHT_LIMIT_ENABLE__SHIFT 0x0000000f
|
||||
#define MH_ARBITER_CONFIG__IN_FLIGHT_LIMIT__SHIFT 0x00000010
|
||||
#define MH_ARBITER_CONFIG__CP_CLNT_ENABLE__SHIFT 0x00000016
|
||||
#define MH_ARBITER_CONFIG__VGT_CLNT_ENABLE__SHIFT 0x00000017
|
||||
#define MH_ARBITER_CONFIG__TC_CLNT_ENABLE__SHIFT 0x00000018
|
||||
#define MH_ARBITER_CONFIG__RB_CLNT_ENABLE__SHIFT 0x00000019
|
||||
#define MH_ARBITER_CONFIG__PA_CLNT_ENABLE__SHIFT 0x0000001a
|
||||
|
||||
#define MH_MMU_CONFIG__RB_W_CLNT_BEHAVIOR__SHIFT 0x00000004
|
||||
#define MH_MMU_CONFIG__CP_W_CLNT_BEHAVIOR__SHIFT 0x00000006
|
||||
#define MH_MMU_CONFIG__CP_R0_CLNT_BEHAVIOR__SHIFT 0x00000008
|
||||
#define MH_MMU_CONFIG__CP_R1_CLNT_BEHAVIOR__SHIFT 0x0000000a
|
||||
#define MH_MMU_CONFIG__CP_R2_CLNT_BEHAVIOR__SHIFT 0x0000000c
|
||||
#define MH_MMU_CONFIG__CP_R3_CLNT_BEHAVIOR__SHIFT 0x0000000e
|
||||
#define MH_MMU_CONFIG__CP_R4_CLNT_BEHAVIOR__SHIFT 0x00000010
|
||||
#define MH_MMU_CONFIG__VGT_R0_CLNT_BEHAVIOR__SHIFT 0x00000012
|
||||
#define MH_MMU_CONFIG__VGT_R1_CLNT_BEHAVIOR__SHIFT 0x00000014
|
||||
#define MH_MMU_CONFIG__TC_R_CLNT_BEHAVIOR__SHIFT 0x00000016
|
||||
#define MH_MMU_CONFIG__PA_W_CLNT_BEHAVIOR__SHIFT 0x00000018
|
||||
|
||||
#define CP_RB_CNTL__RB_BUFSZ__SHIFT 0x00000000
|
||||
#define CP_RB_CNTL__RB_BLKSZ__SHIFT 0x00000008
|
||||
#define CP_RB_CNTL__RB_POLL_EN__SHIFT 0x00000014
|
||||
#define CP_RB_CNTL__RB_NO_UPDATE__SHIFT 0x0000001b
|
||||
|
||||
#define RB_COLOR_INFO__COLOR_FORMAT__SHIFT 0x00000000
|
||||
#define RB_EDRAM_INFO__EDRAM_MAPPING_MODE__SHIFT 0x00000004
|
||||
#define RB_EDRAM_INFO__EDRAM_RANGE__SHIFT 0x0000000e
|
||||
|
||||
#define REG_CP_CSQ_IB1_STAT 0x01FE
|
||||
#define REG_CP_CSQ_IB2_STAT 0x01FF
|
||||
#define REG_CP_CSQ_RB_STAT 0x01FD
|
||||
#define REG_CP_DEBUG 0x01FC
|
||||
#define REG_CP_IB1_BASE 0x0458
|
||||
#define REG_CP_IB1_BUFSZ 0x0459
|
||||
#define REG_CP_IB2_BASE 0x045A
|
||||
#define REG_CP_IB2_BUFSZ 0x045B
|
||||
#define REG_CP_INT_ACK 0x01F4
|
||||
#define REG_CP_INT_CNTL 0x01F2
|
||||
#define REG_CP_INT_STATUS 0x01F3
|
||||
#define REG_CP_ME_CNTL 0x01F6
|
||||
#define REG_CP_ME_RAM_DATA 0x01FA
|
||||
#define REG_CP_ME_RAM_WADDR 0x01F8
|
||||
#define REG_CP_ME_STATUS 0x01F7
|
||||
#define REG_CP_PFP_UCODE_ADDR 0x00C0
|
||||
#define REG_CP_PFP_UCODE_DATA 0x00C1
|
||||
#define REG_CP_QUEUE_THRESHOLDS 0x01D5
|
||||
#define REG_CP_RB_BASE 0x01C0
|
||||
#define REG_CP_RB_CNTL 0x01C1
|
||||
#define REG_CP_RB_RPTR 0x01C4
|
||||
#define REG_CP_RB_RPTR_ADDR 0x01C3
|
||||
#define REG_CP_RB_RPTR_WR 0x01C7
|
||||
#define REG_CP_RB_WPTR 0x01C5
|
||||
#define REG_CP_RB_WPTR_BASE 0x01C8
|
||||
#define REG_CP_RB_WPTR_DELAY 0x01C6
|
||||
#define REG_CP_STAT 0x047F
|
||||
#define REG_CP_STATE_DEBUG_DATA 0x01ED
|
||||
#define REG_CP_STATE_DEBUG_INDEX 0x01EC
|
||||
#define REG_CP_ST_BASE 0x044D
|
||||
#define REG_CP_ST_BUFSZ 0x044E
|
||||
|
||||
#define REG_MASTER_INT_SIGNAL 0x03B7
|
||||
|
||||
#define REG_MH_ARBITER_CONFIG 0x0A40
|
||||
#define REG_MH_INTERRUPT_CLEAR 0x0A44
|
||||
#define REG_MH_INTERRUPT_MASK 0x0A42
|
||||
#define REG_MH_INTERRUPT_STATUS 0x0A43
|
||||
#define REG_MH_MMU_CONFIG 0x0040
|
||||
#define REG_MH_MMU_INVALIDATE 0x0045
|
||||
#define REG_MH_MMU_MPU_BASE 0x0046
|
||||
#define REG_MH_MMU_MPU_END 0x0047
|
||||
#define REG_MH_MMU_PAGE_FAULT 0x0043
|
||||
#define REG_MH_MMU_PT_BASE 0x0042
|
||||
#define REG_MH_MMU_TRAN_ERROR 0x0044
|
||||
#define REG_MH_MMU_VA_RANGE 0x0041
|
||||
|
||||
#define REG_PA_CL_VPORT_XSCALE 0x210F
|
||||
#define REG_PA_CL_VPORT_ZOFFSET 0x2114
|
||||
#define REG_PA_CL_VPORT_ZSCALE 0x2113
|
||||
#define REG_PA_CL_VTE_CNTL 0x2206
|
||||
#define REG_PA_SC_AA_MASK 0x2312
|
||||
#define REG_PA_SC_LINE_CNTL 0x2300
|
||||
#define REG_PA_SC_SCREEN_SCISSOR_BR 0x200F
|
||||
#define REG_PA_SC_SCREEN_SCISSOR_TL 0x200E
|
||||
#define REG_PA_SC_VIZ_QUERY 0x2293
|
||||
#define REG_PA_SC_VIZ_QUERY_STATUS 0x0C44
|
||||
#define REG_PA_SC_WINDOW_OFFSET 0x2080
|
||||
#define REG_PA_SC_WINDOW_SCISSOR_BR 0x2082
|
||||
#define REG_PA_SC_WINDOW_SCISSOR_TL 0x2081
|
||||
#define REG_PA_SU_FACE_DATA 0x0C86
|
||||
#define REG_PA_SU_POINT_SIZE 0x2280
|
||||
#define REG_PA_SU_POLY_OFFSET_BACK_OFFSET 0x2383
|
||||
#define REG_PA_SU_POLY_OFFSET_FRONT_SCALE 0x2380
|
||||
#define REG_PA_SU_SC_MODE_CNTL 0x2205
|
||||
|
||||
#define REG_RBBM_CNTL 0x003B
|
||||
#define REG_RBBM_INT_ACK 0x03B6
|
||||
#define REG_RBBM_INT_CNTL 0x03B4
|
||||
#define REG_RBBM_INT_STATUS 0x03B5
|
||||
#define REG_RBBM_PATCH_RELEASE 0x0001
|
||||
#define REG_RBBM_PERIPHID1 0x03F9
|
||||
#define REG_RBBM_PERIPHID2 0x03FA
|
||||
#define REG_RBBM_DEBUG 0x039B
|
||||
#define REG_RBBM_PM_OVERRIDE1 0x039C
|
||||
#define REG_RBBM_PM_OVERRIDE2 0x039D
|
||||
#define REG_RBBM_READ_ERROR 0x03B3
|
||||
#define REG_RBBM_SOFT_RESET 0x003C
|
||||
#define REG_RBBM_STATUS 0x05D0
|
||||
|
||||
#define REG_RB_COLORCONTROL 0x2202
|
||||
#define REG_RB_COLOR_DEST_MASK 0x2326
|
||||
#define REG_RB_COLOR_MASK 0x2104
|
||||
#define REG_RB_COPY_CONTROL 0x2318
|
||||
#define REG_RB_DEPTHCONTROL 0x2200
|
||||
#define REG_RB_EDRAM_INFO 0x0F02
|
||||
#define REG_RB_MODECONTROL 0x2208
|
||||
#define REG_RB_SURFACE_INFO 0x2000
|
||||
|
||||
#define REG_SCRATCH_ADDR 0x01DD
|
||||
#define REG_SCRATCH_REG0 0x0578
|
||||
#define REG_SCRATCH_REG2 0x057A
|
||||
#define REG_SCRATCH_UMSK 0x01DC
|
||||
|
||||
#define REG_SQ_CF_BOOLEANS 0x4900
|
||||
#define REG_SQ_CF_LOOP 0x4908
|
||||
#define REG_SQ_GPR_MANAGEMENT 0x0D00
|
||||
#define REG_SQ_INST_STORE_MANAGMENT 0x0D02
|
||||
#define REG_SQ_INT_ACK 0x0D36
|
||||
#define REG_SQ_INT_CNTL 0x0D34
|
||||
#define REG_SQ_INT_STATUS 0x0D35
|
||||
#define REG_SQ_PROGRAM_CNTL 0x2180
|
||||
#define REG_SQ_PS_PROGRAM 0x21F6
|
||||
#define REG_SQ_VS_PROGRAM 0x21F7
|
||||
#define REG_SQ_WRAPPING_0 0x2183
|
||||
#define REG_SQ_WRAPPING_1 0x2184
|
||||
|
||||
#define REG_VGT_ENHANCE 0x2294
|
||||
#define REG_VGT_INDX_OFFSET 0x2102
|
||||
#define REG_VGT_MAX_VTX_INDX 0x2100
|
||||
#define REG_VGT_MIN_VTX_INDX 0x2101
|
||||
|
||||
#define REG_TP0_CHICKEN 0x0E1E
|
||||
#define REG_TC_CNTL_STATUS 0x0E00
|
||||
#define REG_PA_SC_AA_CONFIG 0x2301
|
||||
#define REG_VGT_VERTEX_REUSE_BLOCK_CNTL 0x2316
|
||||
#define REG_SQ_INTERPOLATOR_CNTL 0x2182
|
||||
#define REG_RB_DEPTH_INFO 0x2002
|
||||
#define REG_COHER_DEST_BASE_0 0x2006
|
||||
#define REG_PA_SC_SCREEN_SCISSOR_BR 0x200F
|
||||
#define REG_RB_FOG_COLOR 0x2109
|
||||
#define REG_RB_STENCILREFMASK_BF 0x210C
|
||||
#define REG_PA_SC_LINE_STIPPLE 0x2283
|
||||
#define REG_SQ_PS_CONST 0x2308
|
||||
#define REG_VGT_VERTEX_REUSE_BLOCK_CNTL 0x2316
|
||||
#define REG_RB_DEPTH_CLEAR 0x231D
|
||||
#define REG_RB_SAMPLE_COUNT_CTL 0x2324
|
||||
#define REG_SQ_CONSTANT_0 0x4000
|
||||
#define REG_SQ_FETCH_0 0x4800
|
||||
|
||||
#define REG_MH_AXI_ERROR 0xA45
|
||||
#define REG_COHER_BASE_PM4 0xA2A
|
||||
#define REG_COHER_STATUS_PM4 0xA2B
|
||||
#define REG_COHER_SIZE_PM4 0xA29
|
||||
|
||||
#endif /* _YAMATO_REG_H */
|
28
drivers/video/msm/logo.c
Normal file → Executable file
28
drivers/video/msm/logo.c
Normal file → Executable file
@ -28,12 +28,31 @@
|
||||
#define fb_height(fb) ((fb)->var.yres)
|
||||
#define fb_size(fb) ((fb)->var.xres * (fb)->var.yres * 2)
|
||||
|
||||
/* 2012.5.2 SecureCRT
|
||||
Since the RLE is 565 but the framebuffer need 888 format
|
||||
so need to convert the format.
|
||||
*/
|
||||
static unsigned int rgb565to888(unsigned short rgb565_val)
|
||||
{
|
||||
unsigned int rgb888_val=0;
|
||||
unsigned int r = (rgb565_val>>11) & 0x1f;
|
||||
unsigned int g = (rgb565_val>> 5) & 0x3f;
|
||||
unsigned int b = (rgb565_val ) & 0x1f;
|
||||
|
||||
rgb888_val = (r<<3) | (r>>2);
|
||||
rgb888_val |=((g<<2) | (g>>4))<<8;
|
||||
rgb888_val |=((b<<3) | (b>>2))<<16;
|
||||
|
||||
return rgb888_val;
|
||||
}
|
||||
|
||||
static void memset16(void *_ptr, unsigned short val, unsigned count)
|
||||
{
|
||||
unsigned short *ptr = _ptr;
|
||||
unsigned int *ptr = _ptr;
|
||||
unsigned int rgb888_val = rgb565to888(val);
|
||||
count >>= 1;
|
||||
while (count--)
|
||||
*ptr++ = val;
|
||||
*ptr++ = rgb888_val;
|
||||
}
|
||||
|
||||
/* 565RLE image format: [count(2 bytes), rle(2 bytes)] */
|
||||
@ -42,7 +61,8 @@ int load_565rle_image(char *filename)
|
||||
struct fb_info *info;
|
||||
int fd, err = 0;
|
||||
unsigned count, max;
|
||||
unsigned short *data, *bits, *ptr;
|
||||
unsigned short *data, *ptr;
|
||||
unsigned int *bits;
|
||||
|
||||
info = registered_fb[0];
|
||||
if (!info) {
|
||||
@ -77,7 +97,7 @@ int load_565rle_image(char *filename)
|
||||
|
||||
max = fb_width(info) * fb_height(info);
|
||||
ptr = data;
|
||||
bits = (unsigned short *)(info->screen_base);
|
||||
bits = (unsigned int *)(info->screen_base);
|
||||
while (count > 3) {
|
||||
unsigned n = ptr[0];
|
||||
if (n > max)
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/earlysuspend.h>
|
||||
#include <linux/wakelock.h>
|
||||
|
||||
#include <asm/uaccess.h>
|
||||
#include <mach/msm_fb.h>
|
||||
#include "mddi_hw.h"
|
||||
|
||||
@ -106,7 +106,9 @@ struct mddi_info {
|
||||
};
|
||||
|
||||
static void mddi_init_rev_encap(struct mddi_info *mddi);
|
||||
/* FIXME: Workaround for Novatek
|
||||
static void mddi_skew_calibration(struct mddi_info *mddi);
|
||||
*/
|
||||
|
||||
#define mddi_readl(r) readl(mddi->base + (MDDI_##r))
|
||||
#define mddi_writel(v, r) writel((v), mddi->base + (MDDI_##r))
|
||||
@ -204,10 +206,8 @@ static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask);
|
||||
|
||||
static void mddi_handle_rev_data_avail(struct mddi_info *mddi)
|
||||
{
|
||||
union mddi_rev *rev = mddi->rev_data;
|
||||
uint32_t rev_data_count;
|
||||
uint32_t rev_crc_err_count;
|
||||
int i;
|
||||
struct reg_read_info *ri;
|
||||
size_t prev_offset;
|
||||
uint16_t length;
|
||||
@ -242,6 +242,8 @@ static void mddi_handle_rev_data_avail(struct mddi_info *mddi)
|
||||
return;
|
||||
|
||||
if (mddi_debug_flags & 1) {
|
||||
int i;
|
||||
union mddi_rev *rev = mddi->rev_data;
|
||||
printk(KERN_INFO "INT %x, STAT %x, CURR_REV_PTR %x\n",
|
||||
mddi_readl(INT), mddi_readl(STAT),
|
||||
mddi_readl(CURR_REV_PTR));
|
||||
@ -355,7 +357,7 @@ static irqreturn_t mddi_isr(int irq, void *data)
|
||||
static long mddi_wait_interrupt_timeout(struct mddi_info *mddi,
|
||||
uint32_t intmask, int timeout)
|
||||
{
|
||||
unsigned long irq_flags;
|
||||
unsigned long irq_flags=0;
|
||||
|
||||
spin_lock_irqsave(&mddi->int_lock, irq_flags);
|
||||
mddi->got_int &= ~intmask;
|
||||
@ -369,7 +371,7 @@ static long mddi_wait_interrupt_timeout(struct mddi_info *mddi,
|
||||
static void mddi_wait_interrupt(struct mddi_info *mddi, uint32_t intmask)
|
||||
{
|
||||
if (mddi_wait_interrupt_timeout(mddi, intmask, HZ/10) == 0)
|
||||
printk(KERN_INFO KERN_ERR "mddi_wait_interrupt %d, timeout "
|
||||
printk(KERN_INFO "mddi_wait_interrupt %d, timeout "
|
||||
"waiting for %x, INT = %x, STAT = %x gotint = %x\n",
|
||||
current->pid, intmask, mddi_readl(INT), mddi_readl(STAT),
|
||||
mddi->got_int);
|
||||
@ -399,7 +401,10 @@ static uint16_t mddi_init_registers(struct mddi_info *mddi)
|
||||
mddi_writel(0x0001, VERSION);
|
||||
mddi_writel(MDDI_HOST_BYTES_PER_SUBFRAME, BPS);
|
||||
mddi_writel(0x0003, SPM); /* subframes per media */
|
||||
mddi_writel(0x0005, TA1_LEN);
|
||||
if (mddi->type == MSM_MDP_MDDI_TYPE_II)
|
||||
mddi_writel(0x00C8, TA1_LEN);
|
||||
else
|
||||
mddi_writel(0x0005, TA1_LEN);
|
||||
mddi_writel(MDDI_HOST_TA2_LEN, TA2_LEN);
|
||||
mddi_writel(0x003C, DISP_WAKE); /* wakeup counter */
|
||||
mddi_writel(MDDI_HOST_REV_RATE_DIV, REV_RATE_DIV);
|
||||
@ -431,7 +436,7 @@ static uint16_t mddi_init_registers(struct mddi_info *mddi)
|
||||
mddi_writel(0x0050, DRIVE_LO);
|
||||
mddi_writel(0x00320000, PAD_IO_CTL);
|
||||
if (mddi->type == MSM_MDP_MDDI_TYPE_II)
|
||||
mddi_writel(0x40884020, PAD_CAL);
|
||||
mddi_writel(0x40880020, PAD_CAL);
|
||||
else
|
||||
mddi_writel(0x00220020, PAD_CAL);
|
||||
#else
|
||||
@ -469,7 +474,7 @@ static void mddi_suspend(struct msm_mddi_client_data *cdata)
|
||||
mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
|
||||
/* turn off the clock */
|
||||
clk_disable(mddi->clk);
|
||||
#if CONFIG_MSM_MDP40
|
||||
#ifdef CONFIG_MSM_MDP40
|
||||
clk_disable(mdp_clk);
|
||||
#endif
|
||||
wake_unlock(&mddi->idle_lock);
|
||||
@ -484,7 +489,7 @@ static void mddi_resume(struct msm_mddi_client_data *cdata)
|
||||
/* turn on the client */
|
||||
if (mddi->power_client)
|
||||
mddi->power_client(&mddi->client_data, 1);
|
||||
#if CONFIG_MSM_MDP40
|
||||
#ifdef CONFIG_MSM_MDP40
|
||||
clk_enable(mdp_clk);
|
||||
#endif
|
||||
/* turn on the clock */
|
||||
@ -498,7 +503,8 @@ static void mddi_resume(struct msm_mddi_client_data *cdata)
|
||||
*/
|
||||
mddi_writel(mddi->int_enable, INTEN);
|
||||
mddi_writel(MDDI_CMD_LINK_ACTIVE, CMD);
|
||||
mddi_writel(MDDI_CMD_SEND_RTD, CMD);
|
||||
if (mddi->type == MSM_MDP_MDDI_TYPE_I)
|
||||
mddi_writel(MDDI_CMD_SEND_RTD, CMD);
|
||||
mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
|
||||
mddi_set_auto_hibernate(&mddi->client_data, 1);
|
||||
wake_unlock(&mddi->idle_lock);
|
||||
@ -689,7 +695,7 @@ uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg)
|
||||
struct reg_read_info ri;
|
||||
unsigned s;
|
||||
int retry_count = 2;
|
||||
unsigned long irq_flags;
|
||||
unsigned long irq_flags=0;
|
||||
|
||||
mutex_lock(&mddi->reg_read_lock);
|
||||
|
||||
@ -720,6 +726,9 @@ uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg)
|
||||
|
||||
do {
|
||||
init_completion(&ri.done);
|
||||
if (mddi->type == MSM_MDP_MDDI_TYPE_II)
|
||||
mddi_set_auto_hibernate(&mddi->client_data, 0);
|
||||
mddi_writel(MDDI_CMD_SEND_RTD, CMD);
|
||||
mddi->reg_read = &ri;
|
||||
mddi_writel(mddi->reg_read_addr, PRI_PTR);
|
||||
|
||||
@ -732,10 +741,14 @@ uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg)
|
||||
/* while((s & MDDI_STAT_PRI_LINK_LIST_DONE) == 0){ */
|
||||
/* s = mddi_readl(STAT); */
|
||||
/* } */
|
||||
|
||||
/* Enable Periodic Reverse Encapsulation. */
|
||||
mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 1, CMD);
|
||||
mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
|
||||
if (mddi->type == MSM_MDP_MDDI_TYPE_II) {
|
||||
mddi_writel(MDDI_CMD_SEND_REV_ENCAP, CMD);
|
||||
mddi_wait_interrupt(mddi, MDDI_INT_REV_DATA_AVAIL);
|
||||
} else {
|
||||
/* Enable Periodic Reverse Encapsulation. */
|
||||
mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 1, CMD);
|
||||
mddi_wait_interrupt(mddi, MDDI_INT_NO_CMD_PKTS_PEND);
|
||||
}
|
||||
if (wait_for_completion_timeout(&ri.done, HZ/10) == 0 &&
|
||||
!ri.done.done) {
|
||||
printk(KERN_INFO "mddi_remote_read(%x) timeout "
|
||||
@ -763,6 +776,8 @@ uint32_t mddi_remote_read(struct msm_mddi_client_data *cdata, uint32_t reg)
|
||||
"MDDI_CMD_SEND_RTD: int %x, stat %x, rtd val %x "
|
||||
"curr_rev_ptr %x\n", mddi_readl(INT), mddi_readl(STAT),
|
||||
mddi_readl(RTD_VAL), mddi_readl(CURR_REV_PTR));
|
||||
if (mddi->type == MSM_MDP_MDDI_TYPE_II)
|
||||
mddi_set_auto_hibernate(&mddi->client_data, 1);
|
||||
} while (retry_count-- > 0);
|
||||
/* Disable Periodic Reverse Encapsulation. */
|
||||
mddi_writel(MDDI_CMD_PERIODIC_REV_ENCAP | 0, CMD);
|
||||
@ -830,7 +845,7 @@ static int __init mddi_rev_data_setup(struct mddi_info *mddi)
|
||||
sizeof(*mddi->reg_write_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* FIXME: Workaround for Novatek
|
||||
static void mddi_skew_calibration(struct mddi_info *mddi)
|
||||
{
|
||||
struct msm_mddi_platform_data *pdata = mddi->client_pdev.dev.platform_data;
|
||||
@ -842,6 +857,7 @@ static void mddi_skew_calibration(struct mddi_info *mddi)
|
||||
clk_set_rate( mddi->clk, pdata->clk_rate);
|
||||
mdelay(1);
|
||||
}
|
||||
*/
|
||||
|
||||
static int __init mddi_probe(struct platform_device *pdev)
|
||||
{
|
||||
@ -871,7 +887,7 @@ static int __init mddi_probe(struct platform_device *pdev)
|
||||
printk(KERN_INFO "mddi: init() base=0x%p irq=%d\n", mddi->base,
|
||||
mddi->irq);
|
||||
mddi->power_client = pdata->power_client;
|
||||
if (pdata->type != NULL)
|
||||
if ((pdata->type != NULL) && (pdata->type != MSM_MDP_MDDI_TYPE_I))
|
||||
mddi->type = pdata->type;
|
||||
|
||||
mutex_init(&mddi->reg_write_lock);
|
||||
|
@ -1,97 +0,0 @@
|
||||
/* drivers/video/msm_fb/mddi_client_dummy.c
|
||||
*
|
||||
* Support for "dummy" mddi client devices which require no
|
||||
* special initialization code.
|
||||
*
|
||||
* Copyright (C) 2007 Google Incorporated
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <mach/msm_fb.h>
|
||||
|
||||
struct panel_info {
|
||||
struct platform_device pdev;
|
||||
struct msm_panel_data panel_data;
|
||||
};
|
||||
|
||||
static int mddi_dummy_suspend(struct msm_panel_data *panel_data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mddi_dummy_resume(struct msm_panel_data *panel_data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mddi_dummy_blank(struct msm_panel_data *panel_data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mddi_dummy_unblank(struct msm_panel_data *panel_data)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mddi_dummy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct msm_mddi_client_data *client_data = pdev->dev.platform_data;
|
||||
struct panel_info *panel =
|
||||
kzalloc(sizeof(struct panel_info), GFP_KERNEL);
|
||||
int ret;
|
||||
if (!panel)
|
||||
return -ENOMEM;
|
||||
platform_set_drvdata(pdev, panel);
|
||||
panel->panel_data.suspend = mddi_dummy_suspend;
|
||||
panel->panel_data.resume = mddi_dummy_resume;
|
||||
panel->panel_data.blank = mddi_dummy_blank;
|
||||
panel->panel_data.unblank = mddi_dummy_unblank;
|
||||
panel->panel_data.caps = MSMFB_CAP_PARTIAL_UPDATES;
|
||||
panel->pdev.name = "msm_panel";
|
||||
panel->pdev.id = pdev->id;
|
||||
platform_device_add_resources(&panel->pdev,
|
||||
client_data->fb_resource, 1);
|
||||
panel->panel_data.fb_data = client_data->private_client_data;
|
||||
panel->pdev.dev.platform_data = &panel->panel_data;
|
||||
ret = platform_device_register(&panel->pdev);
|
||||
if (ret) {
|
||||
kfree(panel);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mddi_dummy_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct panel_info *panel = platform_get_drvdata(pdev);
|
||||
kfree(panel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver mddi_client_dummy = {
|
||||
.probe = mddi_dummy_probe,
|
||||
.remove = mddi_dummy_remove,
|
||||
.driver = { .name = "mddi_c_dummy" },
|
||||
};
|
||||
|
||||
static int __init mddi_client_dummy_init(void)
|
||||
{
|
||||
platform_driver_register(&mddi_client_dummy);
|
||||
return 0;
|
||||
}
|
||||
|
||||
module_init(mddi_client_dummy_init);
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/wakelock.h>
|
||||
#include <mach/msm_fb.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
static DECLARE_WAIT_QUEUE_HEAD(epson_vsync_wait);
|
||||
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/wakelock.h>
|
||||
#include <mach/msm_fb.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/sched.h>
|
||||
|
||||
static DECLARE_WAIT_QUEUE_HEAD(novtec_vsync_wait);
|
||||
|
||||
@ -145,7 +147,6 @@ static irqreturn_t novtec_vsync_interrupt(int irq, void *data)
|
||||
|
||||
panel->novtec_got_int = 1;
|
||||
if (panel->novtec_callback) {
|
||||
mdelay(3);
|
||||
panel->novtec_callback->func(panel->novtec_callback);
|
||||
panel->novtec_callback = 0;
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/slab.h>
|
||||
#include <mach/msm_fb.h>
|
||||
|
||||
static DECLARE_WAIT_QUEUE_HEAD(nt35399_vsync_wait);
|
||||
|
236
drivers/video/msm/mddi_client_simple.c
Normal file
236
drivers/video/msm/mddi_client_simple.c
Normal file
@ -0,0 +1,236 @@
|
||||
/* drivers/video/msm_fb/mddi_client_simple.c
|
||||
*
|
||||
* Support for simple mddi client devices which require no special
|
||||
* initialization code except for what may be provided in the board file.
|
||||
* If the clients do not provide board specific code, this driver's
|
||||
* panel operations are no-ops.
|
||||
*
|
||||
* Copyright (C) 2007-2010, Google Incorporated
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/wait.h>
|
||||
|
||||
#include <mach/msm_fb.h>
|
||||
|
||||
struct panel_info {
|
||||
struct platform_device pdev;
|
||||
struct msm_mddi_client_data *client_data;
|
||||
struct msm_panel_data panel_data;
|
||||
struct msmfb_callback *fb_callback;
|
||||
wait_queue_head_t vsync_wait;
|
||||
int got_vsync;
|
||||
int irq;
|
||||
};
|
||||
|
||||
#define to_panel_info(pd) container_of((pd), struct panel_info, panel_data)
|
||||
|
||||
static void mddi_simple_request_vsync(struct msm_panel_data *panel_data,
|
||||
struct msmfb_callback *callback)
|
||||
{
|
||||
struct panel_info *panel = to_panel_info(panel_data);
|
||||
struct msm_mddi_client_data *client_data = panel->client_data;
|
||||
|
||||
panel->fb_callback = callback;
|
||||
if (panel->got_vsync) {
|
||||
panel->got_vsync = 0;
|
||||
client_data->activate_link(client_data); /* clears interrupt */
|
||||
}
|
||||
}
|
||||
|
||||
static void mddi_simple_wait_vsync(struct msm_panel_data *panel_data)
|
||||
{
|
||||
struct panel_info *panel = to_panel_info(panel_data);
|
||||
struct msm_mddi_client_data *client_data = panel->client_data;
|
||||
int ret;
|
||||
|
||||
if (panel->got_vsync) {
|
||||
panel->got_vsync = 0;
|
||||
client_data->activate_link(client_data); /* clears interrupt */
|
||||
}
|
||||
|
||||
ret = wait_event_timeout(panel->vsync_wait, panel->got_vsync, HZ/2);
|
||||
if (!ret && !panel->got_vsync)
|
||||
pr_err("mddi_client_simple: timeout waiting for vsync\n");
|
||||
|
||||
panel->got_vsync = 0;
|
||||
/* interrupt clears when screen dma starts */
|
||||
}
|
||||
|
||||
|
||||
static int mddi_simple_suspend(struct msm_panel_data *panel_data)
|
||||
{
|
||||
struct panel_info *panel = to_panel_info(panel_data);
|
||||
struct msm_mddi_client_data *client_data = panel->client_data;
|
||||
struct msm_mddi_bridge_platform_data *bridge_data =
|
||||
client_data->private_client_data;
|
||||
int ret;
|
||||
|
||||
if (!bridge_data->uninit)
|
||||
return 0;
|
||||
|
||||
ret = bridge_data->uninit(bridge_data, client_data);
|
||||
if (ret) {
|
||||
pr_info("%s: non zero return from uninit\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
client_data->suspend(client_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mddi_simple_resume(struct msm_panel_data *panel_data)
|
||||
{
|
||||
struct panel_info *panel = to_panel_info(panel_data);
|
||||
struct msm_mddi_client_data *client_data = panel->client_data;
|
||||
struct msm_mddi_bridge_platform_data *bridge_data =
|
||||
client_data->private_client_data;
|
||||
|
||||
if (!bridge_data->init)
|
||||
return 0;
|
||||
|
||||
client_data->resume(client_data);
|
||||
return bridge_data->init(bridge_data, client_data);
|
||||
}
|
||||
|
||||
static int mddi_simple_blank(struct msm_panel_data *panel_data)
|
||||
{
|
||||
struct panel_info *panel = to_panel_info(panel_data);
|
||||
struct msm_mddi_client_data *client_data = panel->client_data;
|
||||
struct msm_mddi_bridge_platform_data *bridge_data =
|
||||
client_data->private_client_data;
|
||||
|
||||
if (!bridge_data->blank)
|
||||
return 0;
|
||||
return bridge_data->blank(bridge_data, client_data);
|
||||
}
|
||||
|
||||
static int mddi_simple_unblank(struct msm_panel_data *panel_data)
|
||||
{
|
||||
struct panel_info *panel = to_panel_info(panel_data);
|
||||
struct msm_mddi_client_data *client_data = panel->client_data;
|
||||
struct msm_mddi_bridge_platform_data *bridge_data =
|
||||
client_data->private_client_data;
|
||||
|
||||
if (!bridge_data->unblank)
|
||||
return 0;
|
||||
return bridge_data->unblank(bridge_data, client_data);
|
||||
}
|
||||
|
||||
static irqreturn_t handle_vsync_irq(int irq, void *data)
|
||||
{
|
||||
struct panel_info *panel = data;
|
||||
|
||||
panel->got_vsync = 1;
|
||||
if (panel->fb_callback) {
|
||||
panel->fb_callback->func(panel->fb_callback);
|
||||
panel->fb_callback = NULL;
|
||||
}
|
||||
|
||||
wake_up(&panel->vsync_wait);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int mddi_simple_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct msm_mddi_client_data *client_data = pdev->dev.platform_data;
|
||||
struct msm_mddi_bridge_platform_data *bridge_data =
|
||||
client_data->private_client_data;
|
||||
struct panel_info *panel;
|
||||
int ret;
|
||||
|
||||
pr_debug("%s()\n", __func__);
|
||||
|
||||
panel = kzalloc(sizeof(struct panel_info), GFP_KERNEL);
|
||||
if (!panel)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(pdev, panel);
|
||||
|
||||
init_waitqueue_head(&panel->vsync_wait);
|
||||
|
||||
panel->irq = platform_get_irq_byname(pdev, "vsync");
|
||||
if (panel->irq >= 0) {
|
||||
ret = request_irq(panel->irq, handle_vsync_irq,
|
||||
IRQF_TRIGGER_RISING, "mddi_c_simple_vsync",
|
||||
panel);
|
||||
if (ret) {
|
||||
pr_err("%s: request vsync irq %d failed (%d)\n",
|
||||
__func__, panel->irq, ret);
|
||||
goto err_req_irq;
|
||||
}
|
||||
|
||||
panel->panel_data.wait_vsync = mddi_simple_wait_vsync;
|
||||
panel->panel_data.request_vsync = mddi_simple_request_vsync;
|
||||
}
|
||||
|
||||
panel->client_data = client_data;
|
||||
panel->panel_data.suspend = mddi_simple_suspend;
|
||||
panel->panel_data.resume = mddi_simple_resume;
|
||||
panel->panel_data.blank = mddi_simple_blank;
|
||||
panel->panel_data.unblank = mddi_simple_unblank;
|
||||
panel->panel_data.caps = bridge_data->caps;
|
||||
panel->panel_data.fb_data = &bridge_data->fb_data;
|
||||
|
||||
panel->pdev.name = "msm_panel";
|
||||
panel->pdev.id = pdev->id;
|
||||
platform_device_add_resources(&panel->pdev,
|
||||
client_data->fb_resource, 1);
|
||||
panel->pdev.dev.platform_data = &panel->panel_data;
|
||||
|
||||
if (bridge_data->init)
|
||||
bridge_data->init(bridge_data, client_data);
|
||||
|
||||
ret = platform_device_register(&panel->pdev);
|
||||
if (ret) {
|
||||
pr_err("%s: Can't register platform device\n", __func__);
|
||||
goto err_plat_dev_reg;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_plat_dev_reg:
|
||||
if (panel->irq >= 0)
|
||||
free_irq(panel->irq, panel);
|
||||
err_req_irq:
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
kfree(panel);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mddi_simple_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct panel_info *panel = platform_get_drvdata(pdev);
|
||||
kfree(panel);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver mddi_client_simple = {
|
||||
.probe = mddi_simple_probe,
|
||||
.remove = mddi_simple_remove,
|
||||
.driver = {
|
||||
.owner = THIS_MODULE,
|
||||
.name = "mddi_c_simple"
|
||||
},
|
||||
};
|
||||
|
||||
static int __init mddi_client_simple_init(void)
|
||||
{
|
||||
platform_driver_register(&mddi_client_simple);
|
||||
return 0;
|
||||
}
|
||||
|
||||
module_init(mddi_client_simple_init);
|
@ -21,6 +21,7 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/slab.h>
|
||||
#include <mach/msm_fb.h>
|
||||
|
||||
|
||||
|
@ -53,8 +53,9 @@
|
||||
#define MDDI_MF_CNT 0x0084
|
||||
#define MDDI_CURR_REV_PTR 0x0088
|
||||
#define MDDI_CORE_VER 0x008c
|
||||
#define MDDI_PAD_IO_CTL 0x00a0
|
||||
#define MDDI_PAD_CAL 0x00a4
|
||||
#define MDDI_SF_LEN_CTL_REG 0x0094
|
||||
#define MDDI_PAD_IO_CTL 0x00a0
|
||||
#define MDDI_PAD_CAL 0x00a4
|
||||
|
||||
#define MDDI_INT_PRI_PTR_READ 0x0001
|
||||
#define MDDI_INT_SEC_PTR_READ 0x0002
|
||||
@ -131,8 +132,10 @@
|
||||
#define MDDI_HOST_TA2_LEN 0x000c
|
||||
#endif
|
||||
|
||||
#if defined (CONFIG_ARCH_QSD8X50) || defined (CONFIG_ARCH_MSM7X30)
|
||||
#if defined (CONFIG_ARCH_QSD8X50)
|
||||
#define MDDI_HOST_REV_RATE_DIV 0x0004
|
||||
#elif defined (CONFIG_ARCH_MSM7X30)
|
||||
#define MDDI_HOST_REV_RATE_DIV 0x0010
|
||||
#else
|
||||
#define MDDI_HOST_REV_RATE_DIV 0x0002
|
||||
#endif
|
||||
|
@ -21,10 +21,10 @@
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/timer.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/android_pmem.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/msm_hw3d.h>
|
||||
|
||||
#include <mach/msm_iomap.h>
|
||||
#include <mach/msm_fb.h>
|
||||
@ -36,10 +36,16 @@
|
||||
|
||||
struct class *mdp_class;
|
||||
|
||||
#ifdef CONFIG_MSM_HDMI
|
||||
/* Used to report LCDC underflows */
|
||||
void reportUnderflow(void);
|
||||
#endif
|
||||
|
||||
#define MDP_CMD_DEBUG_ACCESS_BASE (0x10000)
|
||||
|
||||
static DECLARE_WAIT_QUEUE_HEAD(mdp_ppp_waitqueue);
|
||||
static unsigned int mdp_irq_mask;
|
||||
static unsigned int mdp_dma_timer_enable = 0;
|
||||
struct clk *mdp_clk_to_disable_later = 0;
|
||||
static struct mdp_blit_req *timeout_req;
|
||||
#ifdef CONFIG_FB_MSM_OVERLAY
|
||||
@ -53,7 +59,19 @@ extern void mdp4_mddi_overlay(void *priv, uint32_t addr, uint32_t stride,
|
||||
uint32_t y);
|
||||
#include "mdp4.h"
|
||||
#endif
|
||||
DEFINE_MUTEX(mdp_mutex);
|
||||
|
||||
|
||||
static void mdp_do_standby_timer(unsigned long data)
|
||||
{
|
||||
struct mdp_info *mdp = (struct mdp_info *) data;
|
||||
if (!mdp_irq_mask) {
|
||||
clk_set_rate(mdp->ebi1_clk, 0);
|
||||
mdp->state |= MDP_STATE_STANDBY;
|
||||
} else {
|
||||
mod_timer(&mdp->standby_timer,
|
||||
jiffies + msecs_to_jiffies(200));
|
||||
}
|
||||
}
|
||||
|
||||
static int locked_enable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
|
||||
{
|
||||
@ -69,7 +87,17 @@ static int locked_enable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
|
||||
if (!mdp_irq_mask) {
|
||||
clk_enable(mdp->clk);
|
||||
enable_irq(mdp->irq);
|
||||
clk_set_rate(mdp->ebi1_clk, 128000000);
|
||||
if (mdp->state & MDP_STATE_STANDBY) {
|
||||
#ifdef CONFIG_MSM_MDP40
|
||||
clk_set_rate(mdp->ebi1_clk, 153000000);
|
||||
#else
|
||||
clk_set_rate(mdp->ebi1_clk, 128000000);
|
||||
#endif
|
||||
mdp->state &= ~MDP_STATE_STANDBY;
|
||||
} else {
|
||||
del_timer_sync(&mdp->standby_timer);
|
||||
barrier();
|
||||
}
|
||||
}
|
||||
|
||||
/* clear out any previous irqs for the requested mask*/
|
||||
@ -84,7 +112,7 @@ static int locked_enable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
|
||||
|
||||
static int enable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long flags=0;
|
||||
int ret;
|
||||
|
||||
spin_lock_irqsave(&mdp->lock, flags);
|
||||
@ -111,14 +139,16 @@ static int locked_disable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
|
||||
disable_irq_nosync(mdp->irq);
|
||||
if (mdp->clk)
|
||||
clk_disable(mdp->clk);
|
||||
clk_set_rate(mdp->ebi1_clk, 0);
|
||||
if (!(mdp->state & MDP_STATE_STANDBY))
|
||||
mod_timer(&mdp->standby_timer,
|
||||
jiffies + msecs_to_jiffies(200));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int disable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
|
||||
{
|
||||
unsigned long irq_flags;
|
||||
unsigned long irq_flags=0;
|
||||
int ret;
|
||||
|
||||
spin_lock_irqsave(&mdp->lock, irq_flags);
|
||||
@ -130,7 +160,7 @@ int disable_mdp_irq(struct mdp_info *mdp, uint32_t mask)
|
||||
static irqreturn_t mdp_isr(int irq, void *data)
|
||||
{
|
||||
uint32_t status;
|
||||
unsigned long irq_flags;
|
||||
unsigned long irq_flags=0;
|
||||
struct mdp_info *mdp = data;
|
||||
int i;
|
||||
|
||||
@ -139,13 +169,22 @@ static irqreturn_t mdp_isr(int irq, void *data)
|
||||
status = mdp_readl(mdp, MDP_INTR_STATUS);
|
||||
mdp_writel(mdp, status, MDP_INTR_CLEAR);
|
||||
|
||||
|
||||
#if defined(CONFIG_MACH_HTCLEO)
|
||||
status &= ~0x10000; // Cotulla
|
||||
#endif
|
||||
|
||||
// pr_info("%s: status=%08x (irq_mask=%08x)\n", __func__, status,
|
||||
// mdp_irq_mask);
|
||||
|
||||
if (mdp_dma_timer_enable) {
|
||||
del_timer_sync(&mdp->dma_timer);
|
||||
mdp_dma_timer_enable = 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MSM_HDMI
|
||||
if (status & MDP_LCDC_UNDERFLOW)
|
||||
{
|
||||
pr_err("%s: LCDC Underflow\n", __func__);
|
||||
reportUnderflow();
|
||||
}
|
||||
#endif
|
||||
status &= ~0x10000; // Cotulla
|
||||
status &= mdp_irq_mask;
|
||||
#ifdef CONFIG_MSM_MDP40
|
||||
if (mdp->mdp_dev.overrides & MSM_MDP4_MDDI_DMA_SWITCH) {
|
||||
@ -168,9 +207,9 @@ static irqreturn_t mdp_isr(int irq, void *data)
|
||||
}
|
||||
}
|
||||
|
||||
if (status & DL0_ROI_DONE)
|
||||
wake_up(&mdp_ppp_waitqueue);
|
||||
|
||||
#ifndef CONFIG_MSM_MDP40
|
||||
mdp_ppp_handle_isr(mdp, status);
|
||||
#endif
|
||||
if (status)
|
||||
locked_disable_mdp_irq(mdp, status);
|
||||
|
||||
@ -178,10 +217,43 @@ static irqreturn_t mdp_isr(int irq, void *data)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static void mdp_do_dma_timer(unsigned long data)
|
||||
{
|
||||
uint32_t status;
|
||||
struct mdp_info *mdp = (struct mdp_info *) data;
|
||||
unsigned long irq_flags=0;
|
||||
int i;
|
||||
|
||||
spin_lock_irqsave(&mdp->lock, irq_flags);
|
||||
|
||||
status = mdp_readl(mdp, MDP_INTR_STATUS);
|
||||
mdp_writel(mdp, mdp_irq_mask, MDP_INTR_CLEAR);
|
||||
|
||||
for (i = 0; i < MSM_MDP_NUM_INTERFACES; ++i) {
|
||||
struct mdp_out_interface *out_if = &mdp->out_if[i];
|
||||
if (mdp_irq_mask & out_if->dma_mask) {
|
||||
if (out_if->dma_cb) {
|
||||
out_if->dma_cb->func(out_if->dma_cb);
|
||||
out_if->dma_cb = NULL;
|
||||
}
|
||||
wake_up(&out_if->dma_waitqueue);
|
||||
}
|
||||
if (mdp_irq_mask & out_if->irq_mask) {
|
||||
out_if->irq_cb->func(out_if->irq_cb);
|
||||
out_if->irq_cb = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
locked_disable_mdp_irq(mdp, mdp_irq_mask);
|
||||
|
||||
spin_unlock_irqrestore(&mdp->lock, irq_flags);
|
||||
|
||||
}
|
||||
|
||||
static uint32_t mdp_check_mask(struct mdp_info *mdp, uint32_t mask)
|
||||
{
|
||||
uint32_t ret;
|
||||
unsigned long irq_flags;
|
||||
unsigned long irq_flags=0;
|
||||
|
||||
spin_lock_irqsave(&mdp->lock, irq_flags);
|
||||
ret = mdp_irq_mask & mask;
|
||||
@ -189,10 +261,29 @@ static uint32_t mdp_check_mask(struct mdp_info *mdp, uint32_t mask)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int mdp_wait(struct mdp_info *mdp, uint32_t mask, wait_queue_head_t *wq)
|
||||
void mdp_dump_blit(struct mdp_blit_req *req)
|
||||
{
|
||||
pr_info("%s: src: w=%d h=%d f=0x%x offs=0x%x mem_id=%d\n", __func__,
|
||||
req->src.width, req->src.height, req->src.format,
|
||||
req->src.offset, req->src.memory_id);
|
||||
pr_info("%s: dst: w=%d h=%d f=0x%x offs=0x%x mem_id=%d\n", __func__,
|
||||
req->dst.width, req->dst.height, req->dst.format,
|
||||
req->dst.offset, req->dst.memory_id);
|
||||
pr_info("%s: src_rect: x=%d y=%d w=%d h=%d\n", __func__,
|
||||
req->src_rect.x, req->src_rect.y, req->src_rect.w,
|
||||
req->src_rect.h);
|
||||
pr_info("%s: dst_rect: x=%d y=%d w=%d h=%d\n", __func__,
|
||||
req->dst_rect.x, req->dst_rect.y, req->dst_rect.w,
|
||||
req->dst_rect.h);
|
||||
pr_info("%s: alpha=0x%08x\n", __func__, req->alpha);
|
||||
pr_info("%s: transp_max=0x%08x\n", __func__, req->transp_mask);
|
||||
pr_info("%s: flags=%08x\n", __func__, req->flags);
|
||||
}
|
||||
|
||||
int mdp_wait(struct mdp_info *mdp, uint32_t mask, wait_queue_head_t *wq)
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned long irq_flags;
|
||||
unsigned long irq_flags=0;
|
||||
|
||||
// pr_info("%s: WAITING for 0x%x\n", __func__, mask);
|
||||
wait_event_timeout(*wq, !mdp_check_mask(mdp, mask), HZ);
|
||||
@ -214,7 +305,7 @@ static int mdp_wait(struct mdp_info *mdp, uint32_t mask, wait_queue_head_t *wq)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void mdp_dma_wait(struct mdp_device *mdp_dev, int interface)
|
||||
static void mdp_dma_wait(struct mdp_device *mdp_dev, int interface)
|
||||
{
|
||||
#define MDP_MAX_TIMEOUTS 20
|
||||
static int timeout_count;
|
||||
@ -247,54 +338,42 @@ void mdp_dma_wait(struct mdp_device *mdp_dev, int interface)
|
||||
BUG();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
static int mdp_ppp_wait(struct mdp_info *mdp)
|
||||
{
|
||||
return mdp_wait(mdp, DL0_ROI_DONE, &mdp_ppp_waitqueue);
|
||||
}
|
||||
|
||||
*/
|
||||
#ifndef CONFIG_MSM_MDP40
|
||||
static void mdp_dmas_to_mddi(void *priv, uint32_t addr, uint32_t stride,
|
||||
uint32_t width, uint32_t height, uint32_t x, uint32_t y)
|
||||
{
|
||||
struct mdp_info *mdp = priv;
|
||||
uint32_t dma2_cfg;
|
||||
uint32_t video_packet_parameter;
|
||||
uint32_t video_packet_parameter = 0;
|
||||
uint16_t ld_param = 1;
|
||||
|
||||
dma2_cfg = DMA_PACK_TIGHT |
|
||||
DMA_PACK_ALIGN_LSB |
|
||||
DMA_OUT_SEL_AHB |
|
||||
DMA_IBUF_NONCONTIGUOUS;
|
||||
|
||||
if(machine_is_htcleo()) {
|
||||
dma2_cfg = DMA_PACK_ALIGN_MSB |
|
||||
DMA_PACK_PATTERN_RGB;
|
||||
dma2_cfg |= mdp->dma_format;
|
||||
|
||||
dma2_cfg |= mdp->format;
|
||||
#if defined CONFIG_MSM_MDP22 || defined CONFIG_MSM_MDP30
|
||||
if (mdp->dma_format == DMA_IBUF_FORMAT_RGB888_OR_ARGB8888)
|
||||
#else
|
||||
if (mdp->dma_format == DMA_IBUF_FORMAT_XRGB8888)
|
||||
#endif
|
||||
dma2_cfg |= DMA_PACK_PATTERN_BGR;
|
||||
else
|
||||
dma2_cfg |= DMA_PACK_PATTERN_RGB;
|
||||
|
||||
dma2_cfg |= DMA_OUT_SEL_LCDC;
|
||||
dma2_cfg |= DMA_OUT_SEL_MDDI;
|
||||
|
||||
dma2_cfg |= DMA_IBUF_FORMAT_RGB565;
|
||||
|
||||
} else {
|
||||
dma2_cfg = DMA_PACK_TIGHT |
|
||||
DMA_PACK_ALIGN_LSB |
|
||||
DMA_OUT_SEL_AHB |
|
||||
DMA_IBUF_NONCONTIGUOUS;
|
||||
dma2_cfg |= DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY;
|
||||
|
||||
dma2_cfg |= mdp->format;
|
||||
|
||||
#if defined CONFIG_MSM_MDP22 || defined CONFIG_MSM_MDP30
|
||||
if (mdp->format == DMA_IBUF_FORMAT_RGB888_OR_ARGB8888)
|
||||
#else
|
||||
if (mdp->format == DMA_IBUF_FORMAT_XRGB8888)
|
||||
#endif
|
||||
dma2_cfg |= DMA_PACK_PATTERN_BGR;
|
||||
else
|
||||
dma2_cfg |= DMA_PACK_PATTERN_RGB;
|
||||
|
||||
dma2_cfg |= DMA_OUT_SEL_MDDI;
|
||||
|
||||
dma2_cfg |= DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY;
|
||||
|
||||
dma2_cfg |= DMA_DITHER_EN;
|
||||
}
|
||||
dma2_cfg |= DMA_DITHER_EN;
|
||||
|
||||
if (mdp->mdp_dev.color_format == MSM_MDP_OUT_IF_FMT_RGB565) {
|
||||
dma2_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
|
||||
@ -341,12 +420,12 @@ static void mdp_dma_to_mddi(void *priv, uint32_t addr, uint32_t stride,
|
||||
DMA_IBUF_NONCONTIGUOUS;
|
||||
|
||||
#endif
|
||||
dma2_cfg |= mdp->format;
|
||||
dma2_cfg |= mdp->dma_format;
|
||||
|
||||
#if defined CONFIG_MSM_MDP22 || defined CONFIG_MSM_MDP30
|
||||
if (mdp->format == DMA_IBUF_FORMAT_RGB888_OR_ARGB8888)
|
||||
if (mdp->dma_format == DMA_IBUF_FORMAT_RGB888_OR_ARGB8888)
|
||||
#else
|
||||
if (mdp->format == DMA_IBUF_FORMAT_XRGB8888)
|
||||
if (mdp->dma_format == DMA_IBUF_FORMAT_XRGB8888)
|
||||
#endif
|
||||
dma2_cfg |= DMA_PACK_PATTERN_BGR;
|
||||
else
|
||||
@ -417,6 +496,7 @@ static void mdp_dma_to_mddi(void *priv, uint32_t addr, uint32_t stride,
|
||||
mdp_writel(mdp, 0, MDP_DMA_P_START);
|
||||
#endif
|
||||
}
|
||||
#endif /* ifndef CONFIG_MSM_MDP40 */
|
||||
|
||||
void mdp_dma(struct mdp_device *mdp_dev, uint32_t addr, uint32_t stride,
|
||||
uint32_t width, uint32_t height, uint32_t x, uint32_t y,
|
||||
@ -435,54 +515,21 @@ void mdp_dma(struct mdp_device *mdp_dev, uint32_t addr, uint32_t stride,
|
||||
|
||||
spin_lock_irqsave(&mdp->lock, flags);
|
||||
if (locked_enable_mdp_irq(mdp, out_if->dma_mask)) {
|
||||
/* something wrong in dma, workaround it */
|
||||
mdp_dma_timer_enable = 1;
|
||||
pr_err("%s: busy\n", __func__);
|
||||
goto done;
|
||||
}
|
||||
|
||||
out_if->dma_cb = callback;
|
||||
out_if->dma_start(out_if->priv, addr, stride, width, height, x, y);
|
||||
done:
|
||||
|
||||
if (mdp_dma_timer_enable)
|
||||
mod_timer(&mdp->dma_timer,
|
||||
jiffies + msecs_to_jiffies(17));
|
||||
|
||||
spin_unlock_irqrestore(&mdp->lock, flags);
|
||||
}
|
||||
|
||||
static int get_img(struct mdp_img *img, struct fb_info *info,
|
||||
unsigned long *start, unsigned long *len,
|
||||
struct file** filep)
|
||||
{
|
||||
int put_needed, ret = 0;
|
||||
struct file *file;
|
||||
unsigned long vstart;
|
||||
|
||||
if (!get_pmem_file(img->memory_id, start, &vstart, len, filep))
|
||||
return 0;
|
||||
else if (!get_msm_hw3d_file(img->memory_id, &img->offset, start, len,
|
||||
filep))
|
||||
return 0;
|
||||
|
||||
file = fget_light(img->memory_id, &put_needed);
|
||||
if (file == NULL)
|
||||
return -1;
|
||||
|
||||
if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
|
||||
*start = info->fix.smem_start;
|
||||
*len = info->fix.smem_len;
|
||||
ret = 0;
|
||||
} else
|
||||
ret = -1;
|
||||
fput_light(file, put_needed);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void put_img(struct file *file)
|
||||
{
|
||||
if (file) {
|
||||
if (is_pmem_file(file))
|
||||
put_pmem_file(file);
|
||||
else if (is_msm_hw3d_file(file))
|
||||
put_msm_hw3d_file(file);
|
||||
}
|
||||
}
|
||||
|
||||
void mdp_configure_dma(struct mdp_device *mdp_dev)
|
||||
{
|
||||
@ -494,7 +541,7 @@ void mdp_configure_dma(struct mdp_device *mdp_dev)
|
||||
dma_cfg = mdp_readl(mdp, MDP_DMA_P_CONFIG);
|
||||
dma_cfg &= ~DMA_IBUF_FORMAT_MASK;
|
||||
dma_cfg &= ~DMA_PACK_PATTERN_MASK;
|
||||
dma_cfg |= (mdp->format | mdp->pack_pattern);
|
||||
dma_cfg |= (mdp->dma_format | mdp->dma_pack_pattern);
|
||||
mdp_writel(mdp, dma_cfg, MDP_DMA_P_CONFIG);
|
||||
mdp->dma_config_dirty = false;
|
||||
|
||||
@ -514,6 +561,13 @@ int mdp_check_output_format(struct mdp_device *mdp_dev, int bpp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mdp_set_panel_size(struct mdp_device *mdp_dev, int width, int height)
|
||||
{
|
||||
struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
|
||||
mdp->mdp_dev.width = width;
|
||||
mdp->mdp_dev.height = height;
|
||||
}
|
||||
|
||||
int mdp_set_output_format(struct mdp_device *mdp_dev, int bpp)
|
||||
{
|
||||
struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
|
||||
@ -542,214 +596,24 @@ int mdp_set_output_format(struct mdp_device *mdp_dev, int bpp)
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
if (format != mdp->format || pack_pattern != mdp->pack_pattern) {
|
||||
mdp->format = format;
|
||||
mdp->pack_pattern = pack_pattern;
|
||||
if (format != mdp->dma_format || pack_pattern != mdp->dma_pack_pattern) {
|
||||
mdp->dma_format = format;
|
||||
mdp->dma_pack_pattern = pack_pattern;
|
||||
mdp->dma_config_dirty = true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dump_req(struct mdp_blit_req *req,
|
||||
unsigned long src_start, unsigned long src_len,
|
||||
unsigned long dst_start, unsigned long dst_len)
|
||||
{
|
||||
pr_err("flags: 0x%x\n", req->flags);
|
||||
pr_err("src_start: 0x%08lx\n", src_start);
|
||||
pr_err("src_len: 0x%08lx\n", src_len);
|
||||
pr_err("src.offset: 0x%x\n", req->src.offset);
|
||||
pr_err("src.format: 0x%x\n", req->src.format);
|
||||
pr_err("src.width: %d\n", req->src.width);
|
||||
pr_err("src.height: %d\n", req->src.height);
|
||||
pr_err("src_rect.x: %d\n", req->src_rect.x);
|
||||
pr_err("src_rect.y: %d\n", req->src_rect.y);
|
||||
pr_err("src_rect.w: %d\n", req->src_rect.w);
|
||||
pr_err("src_rect.h: %d\n", req->src_rect.h);
|
||||
|
||||
pr_err("dst_start: 0x%08lx\n", dst_start);
|
||||
pr_err("dst_len: 0x%08lx\n", dst_len);
|
||||
pr_err("dst.offset: 0x%x\n", req->dst.offset);
|
||||
pr_err("dst.format: 0x%x\n", req->dst.format);
|
||||
pr_err("dst.width: %d\n", req->dst.width);
|
||||
pr_err("dst.height: %d\n", req->dst.height);
|
||||
pr_err("dst_rect.x: %d\n", req->dst_rect.x);
|
||||
pr_err("dst_rect.y: %d\n", req->dst_rect.y);
|
||||
pr_err("dst_rect.w: %d\n", req->dst_rect.w);
|
||||
pr_err("dst_rect.h: %d\n", req->dst_rect.h);
|
||||
}
|
||||
|
||||
int mdp_blit_and_wait(struct mdp_info *mdp, struct mdp_blit_req *req,
|
||||
struct file *src_file, unsigned long src_start, unsigned long src_len,
|
||||
struct file *dst_file, unsigned long dst_start, unsigned long dst_len)
|
||||
{
|
||||
int ret;
|
||||
enable_mdp_irq(mdp, DL0_ROI_DONE);
|
||||
ret = mdp_ppp_blit(mdp, req,
|
||||
src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
if (unlikely(ret)) {
|
||||
disable_mdp_irq(mdp, DL0_ROI_DONE);
|
||||
return ret;
|
||||
}
|
||||
ret = mdp_ppp_wait(mdp);
|
||||
if (unlikely(ret)) {
|
||||
printk(KERN_ERR "%s: failed!\n", __func__);
|
||||
pr_err("original request:\n");
|
||||
dump_req(mdp->req, src_start, src_len, dst_start, dst_len);
|
||||
pr_err("dead request:\n");
|
||||
dump_req(req, src_start, src_len, dst_start, dst_len);
|
||||
BUG();
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mdp_blit(struct mdp_device *mdp_dev, struct fb_info *fb,
|
||||
struct mdp_blit_req *req)
|
||||
{
|
||||
int ret;
|
||||
unsigned long src_start = 0, src_len = 0, dst_start = 0, dst_len = 0;
|
||||
struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
|
||||
struct file *src_file = 0, *dst_file = 0;
|
||||
|
||||
#if defined(CONFIG_MSM_MDP31) || defined(CONFIG_MSM_MDP302)
|
||||
if (req->flags & MDP_ROT_90) {
|
||||
if (unlikely(((req->dst_rect.h == 1) &&
|
||||
((req->src_rect.w != 1) ||
|
||||
(req->dst_rect.w != req->src_rect.h))) ||
|
||||
((req->dst_rect.w == 1) && ((req->src_rect.h != 1) ||
|
||||
(req->dst_rect.h != req->src_rect.w))))) {
|
||||
pr_err("mpd_ppp: error scaling when size is 1!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
if (unlikely(((req->dst_rect.w == 1) &&
|
||||
((req->src_rect.w != 1) ||
|
||||
(req->dst_rect.h != req->src_rect.h))) ||
|
||||
((req->dst_rect.h == 1) && ((req->src_rect.h != 1) ||
|
||||
(req->dst_rect.h != req->src_rect.h))))) {
|
||||
pr_err("mpd_ppp: error scaling when size is 1!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* WORKAROUND FOR HARDWARE BUG IN BG TILE FETCH */
|
||||
if (unlikely(req->src_rect.h == 0 ||
|
||||
req->src_rect.w == 0)) {
|
||||
printk(KERN_ERR "mdp_ppp: src img of zero size!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (unlikely(req->dst_rect.h == 0 ||
|
||||
req->dst_rect.w == 0))
|
||||
return -EINVAL;
|
||||
|
||||
/* do this first so that if this fails, the caller can always
|
||||
* safely call put_img */
|
||||
if (unlikely(get_img(&req->src, fb, &src_start, &src_len, &src_file))) {
|
||||
printk(KERN_ERR "mdp_ppp: could not retrieve src image from "
|
||||
"memory\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (unlikely(get_img(&req->dst, fb, &dst_start, &dst_len, &dst_file))) {
|
||||
printk(KERN_ERR "mdp_ppp: could not retrieve dst image from "
|
||||
"memory\n");
|
||||
put_img(src_file);
|
||||
return -EINVAL;
|
||||
}
|
||||
mutex_lock(&mdp_mutex);
|
||||
|
||||
timeout_req = req;
|
||||
/* transp_masking unimplemented */
|
||||
req->transp_mask = MDP_TRANSP_NOP;
|
||||
mdp->req = req;
|
||||
#if !defined(CONFIG_MSM_MDP31) && !defined(CONFIG_MSM_MDP302)
|
||||
if (unlikely((req->transp_mask != MDP_TRANSP_NOP ||
|
||||
req->alpha != MDP_ALPHA_NOP ||
|
||||
HAS_ALPHA(req->src.format)) &&
|
||||
(req->flags & MDP_ROT_90 &&
|
||||
req->dst_rect.w <= 16 && req->dst_rect.h >= 16))) {
|
||||
int i;
|
||||
unsigned int tiles = req->dst_rect.h / 16;
|
||||
unsigned int remainder = req->dst_rect.h % 16;
|
||||
req->src_rect.w = 16*req->src_rect.w / req->dst_rect.h;
|
||||
req->dst_rect.h = 16;
|
||||
for (i = 0; i < tiles; i++) {
|
||||
ret = mdp_blit_and_wait(mdp, req,
|
||||
src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
if (ret)
|
||||
goto end;
|
||||
req->dst_rect.y += 16;
|
||||
req->src_rect.x += req->src_rect.w;
|
||||
}
|
||||
if (!remainder)
|
||||
goto end;
|
||||
req->src_rect.w = remainder*req->src_rect.w / req->dst_rect.h;
|
||||
req->dst_rect.h = remainder;
|
||||
}
|
||||
#else
|
||||
/* Workarounds for MDP 3.1 hardware bugs */
|
||||
if (unlikely((mdp_get_bytes_per_pixel(req->dst.format) == 4) &&
|
||||
(req->dst_rect.w != 1) &&
|
||||
(((req->dst_rect.w % 8) == 6) ||
|
||||
((req->dst_rect.w % 32) == 3) ||
|
||||
((req->dst_rect.w % 32) == 1)))) {
|
||||
ret = mdp_ppp_blit_split_width(mdp, req,
|
||||
src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
goto end;
|
||||
} else if (unlikely((req->dst_rect.w != 1) && (req->dst_rect.h != 1) &&
|
||||
((req->dst_rect.h % 32) == 3 ||
|
||||
(req->dst_rect.h % 32) == 1))) {
|
||||
ret = mdp_ppp_blit_split_height(mdp, req,
|
||||
src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
goto end;
|
||||
}
|
||||
#endif
|
||||
ret = mdp_blit_and_wait(mdp, req,
|
||||
src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
end:
|
||||
put_img(src_file);
|
||||
put_img(dst_file);
|
||||
mutex_unlock(&mdp_mutex);
|
||||
return ret;
|
||||
return mdp_ppp_blit(mdp, fb, req);
|
||||
}
|
||||
|
||||
int mdp_fb_mirror(struct mdp_device *mdp_dev,
|
||||
struct fb_info *src_fb, struct fb_info *dst_fb,
|
||||
struct mdp_blit_req *req)
|
||||
{
|
||||
int ret;
|
||||
struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
|
||||
|
||||
if (!src_fb || !dst_fb)
|
||||
return -EINVAL;
|
||||
|
||||
enable_mdp_irq(mdp, DL0_ROI_DONE);
|
||||
ret = mdp_ppp_blit(mdp, req,
|
||||
-1, src_fb->fix.smem_start, src_fb->fix.smem_len,
|
||||
-1, dst_fb->fix.smem_start, dst_fb->fix.smem_len);
|
||||
if (ret)
|
||||
goto err_bad_blit;
|
||||
|
||||
ret = mdp_ppp_wait(mdp);
|
||||
if (ret) {
|
||||
pr_err("mdp_ppp_wait error\n");
|
||||
goto err_wait_failed;
|
||||
}
|
||||
return 0;
|
||||
|
||||
err_bad_blit:
|
||||
disable_mdp_irq(mdp, DL0_ROI_DONE);
|
||||
|
||||
err_wait_failed:
|
||||
return ret;
|
||||
}
|
||||
|
||||
void mdp_set_grp_disp(struct mdp_device *mdp_dev, unsigned disp_id)
|
||||
{
|
||||
@ -765,7 +629,7 @@ int mdp_out_if_register(struct mdp_device *mdp_dev, int interface,
|
||||
mdp_dma_start_func_t dma_start)
|
||||
{
|
||||
struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
|
||||
unsigned long flags;
|
||||
unsigned long flags=0;
|
||||
int ret = 0;
|
||||
|
||||
if (interface < 0 || interface >= MSM_MDP_NUM_INTERFACES) {
|
||||
@ -798,7 +662,7 @@ int mdp_out_if_req_irq(struct mdp_device *mdp_dev, int interface,
|
||||
uint32_t mask, struct msmfb_callback *cb)
|
||||
{
|
||||
struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
|
||||
unsigned long flags;
|
||||
unsigned long flags=0;
|
||||
int ret = 0;
|
||||
|
||||
if (interface < 0 || interface >= MSM_MDP_NUM_INTERFACES) {
|
||||
@ -841,94 +705,6 @@ int register_mdp_client(struct class_interface *cint)
|
||||
return class_interface_register(cint);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MSM_MDP40
|
||||
void mdp_hw_init(struct mdp_info *mdp)
|
||||
{
|
||||
mdp_irq_mask = 0;
|
||||
mdp_writel(mdp, 0, MDP_INTR_ENABLE);
|
||||
}
|
||||
#else
|
||||
#include "mdp_csc_table.h"
|
||||
|
||||
void mdp_check_tearing(struct mdp_info *mdp, struct msm_mdp_platform_data *pdata)
|
||||
{
|
||||
mdp_writel(mdp, pdata->sync_config, MDP_SYNC_CONFIG_0);
|
||||
mdp_writel(mdp, 1, MDP_TEAR_CHECK_EN);
|
||||
mdp_writel(mdp, pdata->sync_thresh, MDP_SYNC_THRESH_0);
|
||||
mdp_writel(mdp, pdata->sync_start_pos, MDP_PRIM_START_POS);
|
||||
}
|
||||
void mdp_hw_init(struct mdp_info *mdp)
|
||||
{
|
||||
int n;
|
||||
int lcdc_enabled;
|
||||
|
||||
mdp_irq_mask = 0;
|
||||
|
||||
mdp_writel(mdp, 0, MDP_INTR_ENABLE);
|
||||
|
||||
/* debug interface write access */
|
||||
mdp_writel(mdp, 1, 0x60);
|
||||
mdp_writel(mdp, 1, MDP_EBI2_PORTMAP_MODE);
|
||||
|
||||
#ifndef CONFIG_MSM_MDP22
|
||||
lcdc_enabled = mdp_readl(mdp, MDP_LCDC_EN);
|
||||
/* disable lcdc */
|
||||
mdp_writel(mdp, 0, MDP_LCDC_EN);
|
||||
/* enable auto clock gating for all blocks by default */
|
||||
mdp_writel(mdp, 0xffffffff, MDP_CGC_EN);
|
||||
/* reset color/gamma correct parms */
|
||||
mdp_writel(mdp, 0, MDP_DMA_P_COLOR_CORRECT_CONFIG);
|
||||
#endif
|
||||
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01f8);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01fc);
|
||||
mdp_writel(mdp, 1, 0x60);
|
||||
|
||||
for (n = 0; n < ARRAY_SIZE(csc_color_lut); n++)
|
||||
mdp_writel(mdp, csc_color_lut[n].val, csc_color_lut[n].reg);
|
||||
|
||||
/* clear up unused fg/main registers */
|
||||
/* comp.plane 2&3 ystride */
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0120);
|
||||
|
||||
/* unpacked pattern */
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x012c);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0130);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0134);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0158);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x015c);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0160);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0170);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0174);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x017c);
|
||||
|
||||
/* comp.plane 2 & 3 */
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0114);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0118);
|
||||
|
||||
/* clear unused bg registers */
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01c8);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01d0);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01dc);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e0);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e4);
|
||||
|
||||
for (n = 0; n < ARRAY_SIZE(csc_matrix_config_table); n++)
|
||||
mdp_writel(mdp, csc_matrix_config_table[n].val,
|
||||
csc_matrix_config_table[n].reg);
|
||||
|
||||
mdp_ppp_init_scale(mdp);
|
||||
|
||||
#ifndef CONFIG_MSM_MDP31
|
||||
mdp_writel(mdp, 0x04000400, MDP_COMMAND_CONFIG);
|
||||
#endif
|
||||
#ifndef CONFIG_MSM_MDP22
|
||||
if(lcdc_enabled)
|
||||
mdp_writel(mdp, 1, MDP_LCDC_EN);
|
||||
#endif
|
||||
}
|
||||
#endif //CONFIG_MSM_MDP40
|
||||
|
||||
int mdp_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *resource;
|
||||
@ -974,9 +750,13 @@ int mdp_probe(struct platform_device *pdev)
|
||||
#endif
|
||||
mdp->mdp_dev.set_grp_disp = mdp_set_grp_disp;
|
||||
mdp->mdp_dev.set_output_format = mdp_set_output_format;
|
||||
mdp->mdp_dev.set_panel_size = mdp_set_panel_size;
|
||||
mdp->mdp_dev.check_output_format = mdp_check_output_format;
|
||||
mdp->mdp_dev.configure_dma = mdp_configure_dma;
|
||||
|
||||
mdp->enable_irq = enable_mdp_irq;
|
||||
mdp->disable_irq = disable_mdp_irq;
|
||||
|
||||
if (pdata == NULL || pdata->overrides == 0)
|
||||
mdp->mdp_dev.overrides = 0;
|
||||
else if(pdata->overrides)
|
||||
@ -987,27 +767,27 @@ int mdp_probe(struct platform_device *pdev)
|
||||
else if(pdata->color_format)
|
||||
mdp->mdp_dev.color_format = pdata->color_format;
|
||||
|
||||
if (pdata == NULL || pdata->dma_channel == MDP_DMA_P) {
|
||||
#ifdef CONFIG_MSM_MDP40
|
||||
if (mdp->mdp_dev.overrides & MSM_MDP4_MDDI_DMA_SWITCH) {
|
||||
ret = mdp_out_if_register(&mdp->mdp_dev,
|
||||
MSM_MDDI_PMDH_INTERFACE, mdp, INTR_OVERLAY0_DONE
|
||||
| MDP_DMA_S_DONE, mdp4_mddi_overlay);
|
||||
} else {
|
||||
ret = mdp_out_if_register(&mdp->mdp_dev,
|
||||
MSM_MDDI_PMDH_INTERFACE, mdp, INTR_OVERLAY0_DONE,
|
||||
mdp4_mddi_overlay);
|
||||
}
|
||||
if (mdp->mdp_dev.overrides & MSM_MDP4_MDDI_DMA_SWITCH) {
|
||||
ret = mdp_out_if_register(&mdp->mdp_dev,
|
||||
MSM_MDDI_PMDH_INTERFACE, mdp, INTR_OVERLAY0_DONE
|
||||
| MDP_DMA_S_DONE, mdp4_mddi_overlay);
|
||||
} else {
|
||||
ret = mdp_out_if_register(&mdp->mdp_dev,
|
||||
MSM_MDDI_PMDH_INTERFACE, mdp, INTR_OVERLAY0_DONE,
|
||||
mdp4_mddi_overlay);
|
||||
}
|
||||
#else
|
||||
if (pdata == NULL || pdata->dma_channel == MDP_DMA_P) {
|
||||
ret = mdp_out_if_register(&mdp->mdp_dev,
|
||||
MSM_MDDI_PMDH_INTERFACE, mdp, MDP_DMA_P_DONE,
|
||||
mdp_dma_to_mddi);
|
||||
#endif
|
||||
} else if (pdata->dma_channel == MDP_DMA_S) {
|
||||
ret = mdp_out_if_register(&mdp->mdp_dev,
|
||||
MSM_MDDI_PMDH_INTERFACE, mdp, MDP_DMA_S_DONE,
|
||||
mdp_dmas_to_mddi);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ret)
|
||||
goto error_mddi_pmdh_register;
|
||||
@ -1019,13 +799,12 @@ int mdp_probe(struct platform_device *pdev)
|
||||
goto error_get_mdp_clk;
|
||||
}
|
||||
|
||||
mdp->ebi1_clk = clk_get(NULL, "ebi1_clk");
|
||||
if (IS_ERR(mdp->ebi1_clk)) {
|
||||
pr_err("mdp: failed to get ebi1 clk\n");
|
||||
ret = PTR_ERR(mdp->ebi1_clk);
|
||||
goto error_get_ebi1_clk;
|
||||
}
|
||||
|
||||
mdp->ebi1_clk = clk_get(NULL, "ebi1_clk");
|
||||
if (IS_ERR(mdp->ebi1_clk)) {
|
||||
pr_err("mdp: failed to get ebi1 clk\n");
|
||||
ret = PTR_ERR(mdp->ebi1_clk);
|
||||
goto error_get_ebi1_clk;
|
||||
}
|
||||
|
||||
ret = request_irq(mdp->irq, mdp_isr, IRQF_DISABLED, "msm_mdp", mdp);
|
||||
if (ret)
|
||||
@ -1034,6 +813,7 @@ int mdp_probe(struct platform_device *pdev)
|
||||
|
||||
clk_enable(mdp->clk);
|
||||
mdp_clk_to_disable_later = mdp->clk;
|
||||
|
||||
#ifdef CONFIG_MSM_MDP40
|
||||
//MDP_DISP_INTF_SEL
|
||||
if (mdp_readl(mdp, 0xc0000))
|
||||
@ -1045,7 +825,6 @@ int mdp_probe(struct platform_device *pdev)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MSM_MDP40
|
||||
extern void mdp4_hw_init(struct mdp_info *mdp);
|
||||
mdp4_hw_init(mdp);
|
||||
#else
|
||||
mdp_hw_init(mdp);
|
||||
@ -1069,6 +848,10 @@ extern void mdp4_hw_init(struct mdp_info *mdp);
|
||||
if (ret)
|
||||
goto error_device_register;
|
||||
|
||||
setup_timer(&mdp->standby_timer, mdp_do_standby_timer, (unsigned long )mdp);
|
||||
setup_timer(&mdp->dma_timer, mdp_do_dma_timer, (unsigned long )mdp);
|
||||
|
||||
|
||||
pr_info("%s: initialized\n", __func__);
|
||||
|
||||
return 0;
|
||||
|
@ -47,12 +47,61 @@ struct mdp_info {
|
||||
char * __iomem base;
|
||||
int irq;
|
||||
struct clk *clk;
|
||||
struct clk *pclk;
|
||||
struct clk *ebi1_clk;
|
||||
struct mdp_out_interface out_if[MSM_MDP_NUM_INTERFACES];
|
||||
int format;
|
||||
int pack_pattern;
|
||||
int dma_format;
|
||||
int dma_pack_pattern;
|
||||
bool dma_config_dirty;
|
||||
struct mdp_blit_req *req;
|
||||
uint32_t state;
|
||||
struct timer_list standby_timer;
|
||||
struct timer_list dma_timer;
|
||||
|
||||
int (*enable_irq)(struct mdp_info *mdp, uint32_t mask);
|
||||
int (*disable_irq)(struct mdp_info *mdp, uint32_t mask);
|
||||
};
|
||||
|
||||
struct mdp_lcdc_info {
|
||||
struct mdp_info *mdp;
|
||||
struct clk *mdp_clk;
|
||||
struct clk *mdp_pclk;
|
||||
struct clk *pclk;
|
||||
struct clk *pad_pclk;
|
||||
struct msm_panel_data fb_panel_data;
|
||||
struct platform_device fb_pdev;
|
||||
struct msm_lcdc_platform_data *pdata;
|
||||
uint32_t fb_start;
|
||||
|
||||
struct msmfb_callback frame_start_cb;
|
||||
wait_queue_head_t vsync_waitq;
|
||||
int got_vsync;
|
||||
unsigned color_format;
|
||||
struct {
|
||||
uint32_t clk_rate;
|
||||
uint32_t hsync_ctl;
|
||||
uint32_t vsync_period;
|
||||
uint32_t vsync_pulse_width;
|
||||
uint32_t display_hctl;
|
||||
uint32_t display_vstart;
|
||||
uint32_t display_vend;
|
||||
uint32_t hsync_skew;
|
||||
uint32_t polarity;
|
||||
} parms;
|
||||
atomic_t blank_count;
|
||||
struct mutex blank_lock;
|
||||
};
|
||||
|
||||
struct panel_icm_info {
|
||||
bool icm_mode;
|
||||
bool icm_doable;
|
||||
bool clock_enabled;
|
||||
int panel_update;
|
||||
bool icm_suspend;
|
||||
struct mutex icm_lock;
|
||||
struct mdp_lcdc_info *lcdc;
|
||||
spinlock_t lock;
|
||||
void (*force_leave)(void);
|
||||
};
|
||||
|
||||
extern int mdp_out_if_register(struct mdp_device *mdp_dev, int interface,
|
||||
@ -64,15 +113,21 @@ extern int mdp_out_if_req_irq(struct mdp_device *mdp_dev, int interface,
|
||||
|
||||
struct mdp_blit_req;
|
||||
struct mdp_device;
|
||||
int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req,
|
||||
struct file *src_file, unsigned long src_start,
|
||||
unsigned long src_len, struct file *dst_file,
|
||||
unsigned long dst_start, unsigned long dst_len);
|
||||
|
||||
void mdp_ppp_dump_debug(const struct mdp_info *mdp);
|
||||
int mdp_hw_init(struct mdp_info *mdp);
|
||||
void mdp_check_tearing(struct mdp_info *mdp, struct msm_mdp_platform_data *pdata);
|
||||
void mdp_dump_blit(struct mdp_blit_req *req);
|
||||
int mdp_wait(struct mdp_info *mdp, uint32_t mask, wait_queue_head_t *wq);
|
||||
|
||||
#define mdp_writel(mdp, value, offset) writel(value, mdp->base + offset)
|
||||
#define mdp_readl(mdp, offset) readl(mdp->base + offset)
|
||||
#define panel_to_lcdc(p) container_of((p), struct mdp_lcdc_info, fb_panel_data)
|
||||
#define panel_to_dtv(p) container_of((p), struct mdp_dtv_info, fb_panel_data)
|
||||
|
||||
/* define mdp state for multi purpose */
|
||||
#define MDP_STATE_STANDBY (1 << 0)
|
||||
|
||||
|
||||
#ifdef CONFIG_MSM_MDP302
|
||||
#define MDP_SYNC_CONFIG_0 ( 0x00300)
|
||||
@ -142,6 +197,7 @@ void mdp_ppp_dump_debug(const struct mdp_info *mdp);
|
||||
#define MDP_VSYNC_CTRL (0x0008c)
|
||||
#define MDP_MDDI_PARAM_WR_SEL (0x00090)
|
||||
#define MDP_MDDI_PARAM (0x00094)
|
||||
#define MDP_MDDI_DATA_XFR (0x00098)
|
||||
#define MDP_CGC_EN (0x00100)
|
||||
#define MDP_CMD_STATUS (0x10008)
|
||||
#define MDP_PROFILE_EN (0x10010)
|
||||
@ -292,6 +348,21 @@ void mdp_ppp_dump_debug(const struct mdp_info *mdp);
|
||||
#define MDP_LCDC_HSYNC_SKEW (0xc0030)
|
||||
#define MDP_LCDC_TEST_CTL (0xc0034)
|
||||
#define MDP_LCDC_CTL_POLARITY (0xc0038)
|
||||
|
||||
#define MDP_DTV_EN (0xd0000)
|
||||
#define MDP_DTV_HSYNC_CTL (0xd0004)
|
||||
#define MDP_DTV_VSYNC_PERIOD (0xd0008)
|
||||
#define MDP_DTV_VSYNC_PULSE_WIDTH (0xd000c)
|
||||
#define MDP_DTV_DISPLAY_HCTL (0xd0018)
|
||||
#define MDP_DTV_DISPLAY_V_START (0xd001c)
|
||||
#define MDP_DTV_DISPLAY_V_END (0xd0020)
|
||||
#define MDP_DTV_ACTIVE_HCTL (0xd002c)
|
||||
#define MDP_DTV_ACTIVE_V_START (0xd0030)
|
||||
#define MDP_DTV_ACTIVE_V_END (0xd0038)
|
||||
#define MDP_DTV_BORDER_CLR (0xd0040)
|
||||
#define MDP_DTV_UNDERFLOW_CTL (0xd0044)
|
||||
#define MDP_DTV_HSYNC_SKEW (0xd0048)
|
||||
#define MDP_DTV_CTL_POLARITY (0xd0050)
|
||||
#else
|
||||
#define MDP_LCDC_EN (0xe0000)
|
||||
#define MDP_LCDC_HSYNC_CTL (0xe0004)
|
||||
@ -321,6 +392,7 @@ void mdp_ppp_dump_debug(const struct mdp_info *mdp);
|
||||
#define TV_OUT_DMA3_DONE (1<<6)
|
||||
#define TV_ENC_UNDERRUN (1<<7)
|
||||
#define TV_OUT_FRAME_START (1<<13)
|
||||
#define MDP_HIST_DONE (1<<20)
|
||||
|
||||
#ifdef CONFIG_MSM_MDP22
|
||||
#define MDP_DMA_P_DONE (1 << 2)
|
||||
@ -800,6 +872,7 @@ void mdp_ppp_dump_debug(const struct mdp_info *mdp);
|
||||
#define DMA_PACK_LOOSE 0
|
||||
#define DMA_PACK_ALIGN_LSB 0
|
||||
#define DMA_PACK_ALIGN_MSB (1<<7)
|
||||
#define DMA_PACK_ALIGN_MASK (1<<7)
|
||||
#define DMA_PACK_PATTERN_MASK (0x3f<<8)
|
||||
#define DMA_PACK_PATTERN_RGB \
|
||||
(MDP_GET_PACK_PATTERN(0, CLR_R, CLR_G, CLR_B, 2)<<8)
|
||||
@ -823,31 +896,14 @@ void mdp_ppp_dump_debug(const struct mdp_info *mdp);
|
||||
#define DMA_IBUF_FORMAT_MASK (1 << 20)
|
||||
#define DMA_IBUF_NONCONTIGUOUS (1<<21)
|
||||
|
||||
#elif defined(CONFIG_MSM_MDP30)
|
||||
|
||||
#define DMA_OUT_SEL_AHB 0
|
||||
#define DMA_OUT_SEL_MDDI (1<<19)
|
||||
#define DMA_AHBM_LCD_SEL_PRIMARY 0
|
||||
#define DMA_AHBM_LCD_SEL_SECONDARY (0)
|
||||
#define DMA_IBUF_C3ALPHA_EN (0)
|
||||
#define DMA_DITHER_EN (1<<24)
|
||||
|
||||
#define DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY 0
|
||||
#define DMA_MDDI_DMAOUT_LCD_SEL_SECONDARY (0)
|
||||
#define DMA_MDDI_DMAOUT_LCD_SEL_EXTERNAL (0)
|
||||
|
||||
#define DMA_IBUF_FORMAT_MASK (1 << 20)
|
||||
#define DMA_IBUF_FORMAT_RGB565 (1<<25)
|
||||
#define DMA_IBUF_FORMAT_RGB888_OR_ARGB8888 (1<<26)
|
||||
#define DMA_IBUF_NONCONTIGUOUS (0)
|
||||
|
||||
#else /* CONFIG_MSM_MDP31 | CONFIG_MSM_MDP302 */
|
||||
#else /* CONFIG_MSM_MDP31 || CONFIG_MSM_MDP40 */
|
||||
|
||||
#define DMA_OUT_SEL_AHB (0 << 19)
|
||||
#define DMA_OUT_SEL_MDDI (1 << 19)
|
||||
#define DMA_OUT_SEL_LCDC (2 << 19)
|
||||
#define DMA_OUT_SEL_LCDC_MDDI (3 << 19)
|
||||
#define DMA_DITHER_EN (1 << 24)
|
||||
#define DMA_DEFLKR_EN (1 << 24) /* dma_e */
|
||||
#define DMA_IBUF_FORMAT_RGB888 (0 << 25)
|
||||
#define DMA_IBUF_FORMAT_RGB565 (1 << 25)
|
||||
#define DMA_IBUF_FORMAT_XRGB8888 (2 << 25)
|
||||
@ -862,6 +918,7 @@ void mdp_ppp_dump_debug(const struct mdp_info *mdp);
|
||||
/* MDDI REGISTER ? */
|
||||
#define MDDI_VDO_PACKET_DESC_RGB565 0x5565
|
||||
#define MDDI_VDO_PACKET_DESC_RGB666 0x5666
|
||||
#define MDDI_VDO_PACKET_DESC_RGB888 0x5888
|
||||
#define MDDI_VDO_PACKET_PRIM 0xC3
|
||||
#define MDDI_VDO_PACKET_SECD 0xC0
|
||||
|
||||
|
242
drivers/video/msm/mdp_hw_legacy.c
Normal file
242
drivers/video/msm/mdp_hw_legacy.c
Normal file
@ -0,0 +1,242 @@
|
||||
/*
|
||||
* Copyright (C) 2010 Google, Inc.
|
||||
* Author: Dima Zavin <dima@android.com>
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/io.h>
|
||||
|
||||
#include "mdp_hw.h"
|
||||
#include "mdp_ppp.h"
|
||||
#include "mdp_csc_table.h"
|
||||
|
||||
#define MDP_CMD_DEBUG_ACCESS_BASE (0x10000)
|
||||
static unsigned int mdp_irq_mask;
|
||||
#if 0
|
||||
static void mdp_dma_to_mddi(void *priv, uint32_t addr, uint32_t stride,
|
||||
uint32_t width, uint32_t height, uint32_t x,
|
||||
uint32_t y)
|
||||
{
|
||||
struct mdp_info *mdp = priv;
|
||||
uint32_t dma2_cfg;
|
||||
uint16_t ld_param = 0; /* 0=PRIM, 1=SECD, 2=EXT */
|
||||
|
||||
dma2_cfg = DMA_PACK_TIGHT |
|
||||
DMA_PACK_ALIGN_LSB |
|
||||
DMA_OUT_SEL_AHB |
|
||||
DMA_IBUF_NONCONTIGUOUS;
|
||||
|
||||
dma2_cfg |= mdp->dma_format;
|
||||
dma2_cfg |= mdp->dma_pack_pattern;
|
||||
|
||||
dma2_cfg |= DMA_OUT_SEL_MDDI;
|
||||
|
||||
dma2_cfg |= DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY;
|
||||
|
||||
dma2_cfg |= DMA_DITHER_EN;
|
||||
|
||||
/* 666 18BPP */
|
||||
dma2_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
|
||||
|
||||
#ifdef CONFIG_MSM_MDP22
|
||||
/* setup size, address, and stride */
|
||||
mdp_writel(mdp, (height << 16) | (width),
|
||||
MDP_CMD_DEBUG_ACCESS_BASE + 0x0184);
|
||||
mdp_writel(mdp, addr, MDP_CMD_DEBUG_ACCESS_BASE + 0x0188);
|
||||
mdp_writel(mdp, stride, MDP_CMD_DEBUG_ACCESS_BASE + 0x018C);
|
||||
|
||||
/* set y & x offset and MDDI transaction parameters */
|
||||
mdp_writel(mdp, (y << 16) | (x), MDP_CMD_DEBUG_ACCESS_BASE + 0x0194);
|
||||
mdp_writel(mdp, ld_param, MDP_CMD_DEBUG_ACCESS_BASE + 0x01a0);
|
||||
if (mdp->mdp_dev.color_format == MSM_MDP_OUT_IF_FMT_RGB565)
|
||||
mdp_writel(mdp, (MDDI_VDO_PACKET_DESC_RGB565 << 16) | MDDI_VDO_PACKET_PRIM,
|
||||
MDP_CMD_DEBUG_ACCESS_BASE + 0x01a4);
|
||||
else
|
||||
mdp_writel(mdp, (MDDI_VDO_PACKET_DESC_RGB666 << 16) | MDDI_VDO_PACKET_PRIM,
|
||||
MDP_CMD_DEBUG_ACCESS_BASE + 0x01a4);
|
||||
mdp_writel(mdp, dma2_cfg, MDP_CMD_DEBUG_ACCESS_BASE + 0x0180);
|
||||
|
||||
/* start DMA2 */
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0044);
|
||||
#else
|
||||
/* setup size, address, and stride */
|
||||
mdp_writel(mdp, (height << 16) | (width), MDP_DMA_P_SIZE);
|
||||
mdp_writel(mdp, addr, MDP_DMA_P_IBUF_ADDR);
|
||||
mdp_writel(mdp, stride, MDP_DMA_P_IBUF_Y_STRIDE);
|
||||
|
||||
/* set y & x offset and MDDI transaction parameters */
|
||||
mdp_writel(mdp, (y << 16) | (x), MDP_DMA_P_OUT_XY);
|
||||
mdp_writel(mdp, ld_param, MDP_MDDI_PARAM_WR_SEL);
|
||||
if (mdp->mdp_dev.color_format == MSM_MDP_OUT_IF_FMT_RGB565)
|
||||
mdp_writel(mdp, (MDDI_VDO_PACKET_DESC_RGB565 << 16) | MDDI_VDO_PACKET_PRIM,
|
||||
MDP_MDDI_PARAM);
|
||||
else
|
||||
mdp_writel(mdp, (MDDI_VDO_PACKET_DESC_RGB666 << 16) | MDDI_VDO_PACKET_PRIM,
|
||||
MDP_MDDI_PARAM);
|
||||
|
||||
mdp_writel(mdp, 0x1, MDP_MDDI_DATA_XFR);
|
||||
mdp_writel(mdp, dma2_cfg, MDP_DMA_P_CONFIG);
|
||||
mdp_writel(mdp, 0, MDP_DMA_P_START);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#if defined CONFIG_MSM_MDP302
|
||||
void mdp_check_tearing(struct mdp_info *mdp, struct msm_mdp_platform_data *pdata)
|
||||
{ mdp_writel(mdp, pdata->sync_config, MDP_SYNC_CONFIG_0);
|
||||
mdp_writel(mdp, 1, MDP_TEAR_CHECK_EN);
|
||||
mdp_writel(mdp, pdata->sync_thresh, MDP_SYNC_THRESH_0);
|
||||
mdp_writel(mdp, pdata->sync_start_pos, MDP_PRIM_START_POS);
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
int mdp_hw_init(struct mdp_info *mdp)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = mdp_out_if_register(&mdp->mdp_dev, MSM_MDDI_PMDH_INTERFACE, mdp,
|
||||
MDP_DMA_P_DONE, mdp_dma_to_mddi);
|
||||
if (n)
|
||||
return n;
|
||||
|
||||
mdp_writel(mdp, 0, MDP_INTR_ENABLE);
|
||||
|
||||
/* debug interface write access */
|
||||
mdp_writel(mdp, 1, 0x60);
|
||||
mdp_writel(mdp, 1, MDP_EBI2_PORTMAP_MODE);
|
||||
|
||||
#ifndef CONFIG_MSM_MDP22
|
||||
/* disable lcdc */
|
||||
mdp_writel(mdp, 0, MDP_LCDC_EN);
|
||||
/* enable auto clock gating for all blocks by default */
|
||||
mdp_writel(mdp, 0xffffffff, MDP_CGC_EN);
|
||||
/* reset color/gamma correct parms */
|
||||
mdp_writel(mdp, 0, MDP_DMA_P_COLOR_CORRECT_CONFIG);
|
||||
#endif
|
||||
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01f8);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01fc);
|
||||
mdp_writel(mdp, 1, 0x60);
|
||||
|
||||
for (n = 0; n < ARRAY_SIZE(csc_color_lut); n++)
|
||||
mdp_writel(mdp, csc_color_lut[n].val, csc_color_lut[n].reg);
|
||||
|
||||
/* clear up unused fg/main registers */
|
||||
/* comp.plane 2&3 ystride */
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0120);
|
||||
|
||||
/* unpacked pattern */
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x012c);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0130);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0134);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0158);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x015c);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0160);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0170);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0174);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x017c);
|
||||
|
||||
/* comp.plane 2 & 3 */
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0114);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0118);
|
||||
|
||||
/* clear unused bg registers */
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01c8);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01d0);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01dc);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e0);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e4);
|
||||
|
||||
for (n = 0; n < ARRAY_SIZE(csc_matrix_config_table); n++)
|
||||
mdp_writel(mdp, csc_matrix_config_table[n].val,
|
||||
csc_matrix_config_table[n].reg);
|
||||
|
||||
mdp_ppp_init_scale(mdp);
|
||||
|
||||
#ifndef CONFIG_MSM_MDP31
|
||||
mdp_writel(mdp, 0x04000400, MDP_COMMAND_CONFIG);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int mdp_hw_init(struct mdp_info *mdp)
|
||||
{
|
||||
int n;
|
||||
int lcdc_enabled;
|
||||
|
||||
mdp_irq_mask = 0;
|
||||
|
||||
mdp_writel(mdp, 0, MDP_INTR_ENABLE);
|
||||
|
||||
/* debug interface write access */
|
||||
mdp_writel(mdp, 1, 0x60);
|
||||
mdp_writel(mdp, 1, MDP_EBI2_PORTMAP_MODE);
|
||||
|
||||
#ifndef CONFIG_MSM_MDP22
|
||||
lcdc_enabled = mdp_readl(mdp, MDP_LCDC_EN);
|
||||
/* disable lcdc */
|
||||
mdp_writel(mdp, 0, MDP_LCDC_EN);
|
||||
/* enable auto clock gating for all blocks by default */
|
||||
mdp_writel(mdp, 0xffffffff, MDP_CGC_EN);
|
||||
/* reset color/gamma correct parms */
|
||||
mdp_writel(mdp, 0, MDP_DMA_P_COLOR_CORRECT_CONFIG);
|
||||
#endif
|
||||
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01f8);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01fc);
|
||||
mdp_writel(mdp, 1, 0x60);
|
||||
|
||||
for (n = 0; n < ARRAY_SIZE(csc_color_lut); n++)
|
||||
mdp_writel(mdp, csc_color_lut[n].val, csc_color_lut[n].reg);
|
||||
|
||||
/* clear up unused fg/main registers */
|
||||
/* comp.plane 2&3 ystride */
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0120);
|
||||
|
||||
/* unpacked pattern */
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x012c);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0130);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0134);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0158);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x015c);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0160);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0170);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0174);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x017c);
|
||||
|
||||
/* comp.plane 2 & 3 */
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0114);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0118);
|
||||
|
||||
/* clear unused bg registers */
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01c8);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01d0);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01dc);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e0);
|
||||
mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e4);
|
||||
|
||||
for (n = 0; n < ARRAY_SIZE(csc_matrix_config_table); n++)
|
||||
mdp_writel(mdp, csc_matrix_config_table[n].val,
|
||||
csc_matrix_config_table[n].reg);
|
||||
|
||||
mdp_ppp_init_scale(mdp);
|
||||
|
||||
#ifndef CONFIG_MSM_MDP31
|
||||
mdp_writel(mdp, 0x04000400, MDP_COMMAND_CONFIG);
|
||||
#endif
|
||||
#ifndef CONFIG_MSM_MDP22
|
||||
if (lcdc_enabled)
|
||||
mdp_writel(mdp, 1, MDP_LCDC_EN);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
@ -23,6 +23,7 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <asm/mach-types.h>
|
||||
@ -33,6 +34,9 @@
|
||||
#ifdef CONFIG_MSM_MDP40
|
||||
#include "mdp4.h"
|
||||
#endif
|
||||
#ifdef CONFIG_PANEL_SELF_REFRESH
|
||||
#include <linux/kthread.h>
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#define D(fmt, args...) printk(KERN_INFO "Dispaly: " fmt, ##args)
|
||||
@ -43,32 +47,6 @@
|
||||
#if defined(CONFIG_ARCH_MSM7227)
|
||||
#define LCDC_MUX_CTL (MSM_TGPIO1_BASE + 0x278)
|
||||
#endif
|
||||
struct mdp_lcdc_info {
|
||||
struct mdp_info *mdp;
|
||||
struct clk *mdp_clk;
|
||||
struct clk *pclk;
|
||||
struct clk *pad_pclk;
|
||||
struct msm_panel_data fb_panel_data;
|
||||
struct platform_device fb_pdev;
|
||||
struct msm_lcdc_platform_data *pdata;
|
||||
uint32_t fb_start;
|
||||
|
||||
struct msmfb_callback frame_start_cb;
|
||||
wait_queue_head_t vsync_waitq;
|
||||
int got_vsync;
|
||||
unsigned color_format;
|
||||
struct {
|
||||
uint32_t clk_rate;
|
||||
uint32_t hsync_ctl;
|
||||
uint32_t vsync_period;
|
||||
uint32_t vsync_pulse_width;
|
||||
uint32_t display_hctl;
|
||||
uint32_t display_vstart;
|
||||
uint32_t display_vend;
|
||||
uint32_t hsync_skew;
|
||||
uint32_t polarity;
|
||||
} parms;
|
||||
};
|
||||
|
||||
static struct mdp_device *mdp_dev;
|
||||
|
||||
@ -76,7 +54,142 @@ static struct mdp_device *mdp_dev;
|
||||
static struct mdp4_overlay_pipe *lcdc_pipe;
|
||||
#endif
|
||||
|
||||
#define panel_to_lcdc(p) container_of((p), struct mdp_lcdc_info, fb_panel_data)
|
||||
#ifdef CONFIG_PANEL_SELF_REFRESH
|
||||
#if 0
|
||||
#define ICM_DBG(s...) printk("[icm]" s)
|
||||
#else
|
||||
#define ICM_DBG(s...) do {} while (0)
|
||||
#endif
|
||||
|
||||
/* set the timeout to 200 milliseconds */
|
||||
#define PANEL_ENTER_IDLE_TIMEOUT HZ/5
|
||||
/* Afetr setting ICM=1, we need to keep sending the RGB signal more than 2-frame */
|
||||
#define PANEL_IDLE_STABLE_TIMEOUT 48
|
||||
|
||||
static struct task_struct *th_display;
|
||||
struct panel_icm_info *panel_icm;
|
||||
DECLARE_WAIT_QUEUE_HEAD(panel_update_wait_queue);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PANEL_SELF_REFRESH
|
||||
static int icm_check_panel_update(void)
|
||||
{
|
||||
int ret;
|
||||
unsigned long irq_flags = 0;
|
||||
|
||||
spin_lock_irqsave(&panel_icm->lock, irq_flags);
|
||||
ret = panel_icm->panel_update;
|
||||
spin_unlock_irqrestore(&panel_icm->lock, irq_flags);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int icm_thread(void *data)
|
||||
{
|
||||
struct mdp_lcdc_info *lcdc;
|
||||
struct msm_lcdc_panel_ops *panel_ops;
|
||||
int rc;
|
||||
unsigned long irq_flags = 0;
|
||||
|
||||
lcdc = data;
|
||||
panel_ops = lcdc->pdata->panel_ops;
|
||||
while (1) {
|
||||
rc = wait_event_timeout(panel_update_wait_queue, icm_check_panel_update() == 1, PANEL_ENTER_IDLE_TIMEOUT);
|
||||
ICM_DBG("ICM Thread:wake up rc=%d \n", rc);
|
||||
mutex_lock(&panel_icm->icm_lock);
|
||||
if (rc == 0 && icm_check_panel_update() != 1) {/* wait_timeout */
|
||||
ICM_DBG("EnterICM: icm_mode=%d icm_doable=%d \n", panel_icm->icm_mode, panel_icm->icm_doable);
|
||||
if (panel_icm->icm_mode == false && panel_icm->icm_doable == true) {
|
||||
|
||||
if (panel_ops->refresh_enable)
|
||||
panel_ops->refresh_enable(panel_ops);
|
||||
|
||||
panel_icm->icm_mode = true;
|
||||
msleep(PANEL_IDLE_STABLE_TIMEOUT);
|
||||
|
||||
mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN);
|
||||
clk_disable(lcdc->pad_pclk);
|
||||
clk_disable(lcdc->pclk);
|
||||
clk_disable(lcdc->mdp_clk);
|
||||
panel_icm->clock_enabled = false;
|
||||
pr_info("EnterICM: enter ICM MODE done!!!\n");
|
||||
}
|
||||
} else {/* get update event, no timeout */
|
||||
ICM_DBG("Leave ICM: icm_mode=%d icm_doable=%d \n", panel_icm->icm_mode, panel_icm->icm_doable);
|
||||
if (panel_icm->icm_mode == true && panel_icm->icm_doable == true) {
|
||||
clk_enable(lcdc->mdp_clk);
|
||||
clk_enable(lcdc->pclk);
|
||||
clk_enable(lcdc->pad_pclk);
|
||||
mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN);
|
||||
panel_icm->clock_enabled = true;
|
||||
|
||||
if (panel_ops->refresh_disable)
|
||||
panel_ops->refresh_disable(panel_ops);
|
||||
|
||||
panel_icm->icm_mode = false;
|
||||
pr_info("LeaveICM: leave ICM MODE done !!!\n");
|
||||
}
|
||||
spin_lock_irqsave(&panel_icm->lock, irq_flags);
|
||||
panel_icm->panel_update = 0;
|
||||
spin_unlock_irqrestore(&panel_icm->lock, irq_flags);
|
||||
}
|
||||
mutex_unlock(&panel_icm->icm_lock);
|
||||
} /* end while */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void icm_force_leave(void)
|
||||
{
|
||||
struct msm_lcdc_panel_ops *panel_ops;
|
||||
unsigned long irq_flags = 0;
|
||||
|
||||
panel_ops = panel_icm->lcdc->pdata->panel_ops;
|
||||
|
||||
mutex_lock(&panel_icm->icm_lock);
|
||||
ICM_DBG("Force Leave ICM: icm_mode=%d icm_doable=%d \n", panel_icm->icm_mode, panel_icm->icm_doable);
|
||||
if (panel_icm->icm_mode == true) {
|
||||
clk_enable(panel_icm->lcdc->mdp_clk);
|
||||
clk_enable(panel_icm->lcdc->pclk);
|
||||
clk_enable(panel_icm->lcdc->pad_pclk);
|
||||
mdp_writel(panel_icm->lcdc->mdp, 1, MDP_LCDC_EN);
|
||||
panel_icm->clock_enabled = true;
|
||||
if (panel_ops->refresh_disable)
|
||||
panel_ops->refresh_disable(panel_ops);
|
||||
panel_icm->icm_mode = false;
|
||||
panel_icm->icm_doable = true;
|
||||
pr_info("ForceLeaveICM: leave ICM MODE done !!!\n");
|
||||
}
|
||||
spin_lock_irqsave(&panel_icm->lock, irq_flags);
|
||||
panel_icm->panel_update = 0;
|
||||
spin_unlock_irqrestore(&panel_icm->lock, irq_flags);
|
||||
mutex_unlock(&panel_icm->icm_lock);
|
||||
}
|
||||
|
||||
static int icm_init(struct mdp_lcdc_info *lcdc)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
/* init panel_icm_info */
|
||||
panel_icm = kzalloc(sizeof(struct panel_icm_info), GFP_KERNEL);
|
||||
if (!panel_icm)
|
||||
return -ENOMEM;
|
||||
panel_icm->icm_doable = 1;
|
||||
panel_icm->clock_enabled = true;
|
||||
panel_icm->lcdc = lcdc;
|
||||
panel_icm->force_leave = icm_force_leave;
|
||||
panel_icm->icm_suspend = false;
|
||||
mutex_init(&panel_icm->icm_lock);
|
||||
th_display = kthread_run(icm_thread, lcdc, "panel-enterIdle");
|
||||
if (IS_ERR(th_display)) {
|
||||
ret = PTR_ERR(th_display);
|
||||
pr_err("%s: panel_icm_thread create fail:%d!!!\n", __func__, ret);
|
||||
goto error_create_thread;
|
||||
}
|
||||
return ret;
|
||||
error_create_thread:
|
||||
kfree(panel_icm);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int lcdc_unblank(struct msm_panel_data *fb_panel)
|
||||
{
|
||||
@ -85,7 +198,8 @@ static int lcdc_unblank(struct msm_panel_data *fb_panel)
|
||||
|
||||
pr_info("%s: ()\n", __func__);
|
||||
|
||||
panel_ops->unblank(panel_ops);
|
||||
if (panel_ops->unblank)
|
||||
panel_ops->unblank(panel_ops);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -96,14 +210,28 @@ static int lcdc_blank(struct msm_panel_data *fb_panel)
|
||||
struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops;
|
||||
|
||||
pr_info("%s: ()\n", __func__);
|
||||
panel_ops->blank(panel_ops);
|
||||
|
||||
if (panel_ops->blank)
|
||||
panel_ops->blank(panel_ops);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lcdc_shutdown(struct msm_panel_data *fb_panel)
|
||||
{
|
||||
struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
|
||||
struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops;
|
||||
|
||||
pr_info("%s: ()\n", __func__);
|
||||
|
||||
if (panel_ops->shutdown)
|
||||
panel_ops->shutdown(panel_ops);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lcdc_suspend(struct msm_panel_data *fb_panel)
|
||||
{
|
||||
int status;
|
||||
struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
|
||||
struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops;
|
||||
|
||||
@ -111,13 +239,39 @@ static int lcdc_suspend(struct msm_panel_data *fb_panel)
|
||||
|
||||
#if defined(CONFIG_ARCH_MSM7227)
|
||||
writel(0x0, LCDC_MUX_CTL);
|
||||
status = readl(LCDC_MUX_CTL);
|
||||
D("suspend_lcdc_mux_ctl = %x\n", status);
|
||||
D("suspend_lcdc_mux_ctl = %x\n", readl(LCDC_MUX_CTL));
|
||||
#endif
|
||||
#ifdef CONFIG_PANEL_SELF_REFRESH
|
||||
if (lcdc->mdp->mdp_dev.overrides & MSM_MDP_RGB_PANEL_SELE_REFRESH) {
|
||||
mutex_lock(&panel_icm->icm_lock);
|
||||
panel_icm->icm_doable = false;
|
||||
pr_info("[ICM %s]: icm mode=%d, clock_enabled=%d\n", __func__, panel_icm->icm_mode, panel_icm->clock_enabled);
|
||||
if (panel_icm->icm_mode == true && panel_icm->clock_enabled == false) {
|
||||
if (panel_ops->refresh_disable)
|
||||
panel_ops->refresh_disable(panel_ops);
|
||||
panel_icm->icm_mode = false;
|
||||
} else {
|
||||
mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN);
|
||||
clk_disable(lcdc->pad_pclk);
|
||||
clk_disable(lcdc->pclk);
|
||||
clk_disable(lcdc->mdp_clk);
|
||||
}
|
||||
panel_icm->clock_enabled = false;
|
||||
mutex_unlock(&panel_icm->icm_lock);
|
||||
} else {
|
||||
mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN);
|
||||
clk_disable(lcdc->pad_pclk);
|
||||
clk_disable(lcdc->pclk);
|
||||
clk_disable(lcdc->mdp_clk);
|
||||
}
|
||||
#else
|
||||
mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN);
|
||||
clk_disable(lcdc->pad_pclk);
|
||||
clk_disable(lcdc->pclk);
|
||||
if (lcdc->mdp_pclk)
|
||||
clk_disable(lcdc->mdp_pclk);
|
||||
clk_disable(lcdc->mdp_clk);
|
||||
#endif
|
||||
if (panel_ops->uninit)
|
||||
panel_ops->uninit(panel_ops);
|
||||
|
||||
@ -126,7 +280,6 @@ static int lcdc_suspend(struct msm_panel_data *fb_panel)
|
||||
|
||||
static int lcdc_resume(struct msm_panel_data *fb_panel)
|
||||
{
|
||||
unsigned int status;
|
||||
struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
|
||||
struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops;
|
||||
|
||||
@ -136,17 +289,26 @@ static int lcdc_resume(struct msm_panel_data *fb_panel)
|
||||
if (panel_ops->init(panel_ops) < 0)
|
||||
printk(KERN_ERR "LCD init fail!\n");
|
||||
}
|
||||
|
||||
clk_enable(lcdc->mdp_clk);
|
||||
if (lcdc->mdp_pclk)
|
||||
clk_enable(lcdc->mdp_pclk);
|
||||
clk_enable(lcdc->pclk);
|
||||
clk_enable(lcdc->pad_pclk);
|
||||
#if defined(CONFIG_ARCH_MSM7227)
|
||||
writel(0x1, LCDC_MUX_CTL);
|
||||
status = readl(LCDC_MUX_CTL);
|
||||
D("resume_lcdc_mux_ctl = %x\n",status);
|
||||
D("resume_lcdc_mux_ctl = %x\n", readl(LCDC_MUX_CTL));
|
||||
#endif
|
||||
|
||||
mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN);
|
||||
#ifdef CONFIG_PANEL_SELF_REFRESH
|
||||
if (lcdc->mdp->mdp_dev.overrides & MSM_MDP_RGB_PANEL_SELE_REFRESH) {
|
||||
mutex_lock(&panel_icm->icm_lock);
|
||||
panel_icm->icm_doable = true;
|
||||
panel_icm->clock_enabled = true;
|
||||
panel_icm->icm_suspend = false;
|
||||
mutex_unlock(&panel_icm->icm_lock);
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -157,12 +319,13 @@ static int lcdc_hw_init(struct mdp_lcdc_info *lcdc)
|
||||
uint32_t dma_cfg;
|
||||
|
||||
clk_enable(lcdc->mdp_clk);
|
||||
if (lcdc->mdp_pclk)
|
||||
clk_enable(lcdc->mdp_pclk);
|
||||
clk_enable(lcdc->pclk);
|
||||
clk_enable(lcdc->pad_pclk);
|
||||
|
||||
clk_set_rate(lcdc->pclk, lcdc->parms.clk_rate);
|
||||
clk_set_rate(lcdc->pad_pclk, lcdc->parms.clk_rate);
|
||||
|
||||
/* write the lcdc params */
|
||||
mdp_writel(lcdc->mdp, lcdc->parms.hsync_ctl, MDP_LCDC_HSYNC_CTL);
|
||||
mdp_writel(lcdc->mdp, lcdc->parms.vsync_period, MDP_LCDC_VSYNC_PERIOD);
|
||||
@ -175,46 +338,45 @@ static int lcdc_hw_init(struct mdp_lcdc_info *lcdc)
|
||||
mdp_writel(lcdc->mdp, lcdc->parms.hsync_skew, MDP_LCDC_HSYNC_SKEW);
|
||||
|
||||
mdp_writel(lcdc->mdp, 0, MDP_LCDC_BORDER_CLR);
|
||||
mdp_writel(lcdc->mdp, 0xff, MDP_LCDC_UNDERFLOW_CTL);
|
||||
mdp_writel(lcdc->mdp, 0x80000000 | 0xff, MDP_LCDC_UNDERFLOW_CTL);
|
||||
mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_HCTL);
|
||||
mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_V_START);
|
||||
mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_V_END);
|
||||
mdp_writel(lcdc->mdp, lcdc->parms.polarity, MDP_LCDC_CTL_POLARITY);
|
||||
|
||||
/* config the dma_p block that drives the lcdc data */
|
||||
mdp_writel(lcdc->mdp, lcdc->fb_start, MDP_DMA_P_IBUF_ADDR);
|
||||
mdp_writel(lcdc->mdp, (((fb_panel->fb_data->yres & 0x7ff) << 16) |
|
||||
(fb_panel->fb_data->xres & 0x7ff)),
|
||||
MDP_DMA_P_SIZE);
|
||||
|
||||
mdp_writel(lcdc->mdp, 0, MDP_DMA_P_OUT_XY);
|
||||
|
||||
dma_cfg = mdp_readl(lcdc->mdp, MDP_DMA_P_CONFIG);
|
||||
#if defined(CONFIG_MACH_HTCLEO)
|
||||
dma_cfg &= ~(DMA_PACK_PATTERN_MASK | DMA_PACK_ALIGN_MASK);
|
||||
dma_cfg |= (DMA_PACK_ALIGN_MSB |
|
||||
DMA_PACK_PATTERN_RGB |
|
||||
DMA_DITHER_EN);
|
||||
DMA_PACK_PATTERN_RGB |
|
||||
DMA_DITHER_EN);
|
||||
dma_cfg |= DMA_OUT_SEL_LCDC;
|
||||
dma_cfg |= DMA_IBUF_FORMAT_RGB565;
|
||||
//dma_cfg &= ~DMA_DITHER_EN; // solve color banding issue - marc1706
|
||||
//zeusk: dma_cfg |= DMA_IBUF_FORMAT_RGB565;
|
||||
dma_cfg &= ~DMA_DST_BITS_MASK;
|
||||
#else
|
||||
dma_cfg |= (DMA_PACK_ALIGN_LSB |
|
||||
DMA_PACK_PATTERN_RGB |
|
||||
DMA_DITHER_EN);
|
||||
dma_cfg |= DMA_OUT_SEL_LCDC;
|
||||
dma_cfg &= ~DMA_DST_BITS_MASK;
|
||||
#endif
|
||||
|
||||
if(lcdc->color_format == MSM_MDP_OUT_IF_FMT_RGB565)
|
||||
dma_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;
|
||||
else if (lcdc->color_format == MSM_MDP_OUT_IF_FMT_RGB666)
|
||||
dma_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
|
||||
if (fb_panel->fb_data->output_format == MSM_MDP_OUT_IF_FMT_RGB666)
|
||||
dma_cfg |= DMA_DSTC0G_6BITS |
|
||||
DMA_DSTC1B_6BITS |
|
||||
DMA_DSTC2R_6BITS;
|
||||
else if (fb_panel->fb_data->output_format == MSM_MDP_OUT_IF_FMT_RGB888)
|
||||
dma_cfg |= DMA_DSTC0G_8BITS |
|
||||
DMA_DSTC1B_8BITS |
|
||||
DMA_DSTC2R_8BITS;
|
||||
else
|
||||
dma_cfg |= DMA_DSTC0G_6BITS |
|
||||
DMA_DSTC1B_5BITS |
|
||||
DMA_DSTC2R_5BITS;
|
||||
|
||||
mdp_writel(lcdc->mdp, dma_cfg, MDP_DMA_P_CONFIG);
|
||||
|
||||
/* enable the lcdc timing generation */
|
||||
mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -301,35 +463,6 @@ static void lcdc_dma_start(void *priv, uint32_t addr, uint32_t stride,
|
||||
mdp_writel(lcdc->mdp, addr, MDP_DMA_P_IBUF_ADDR);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MSM_MDP40
|
||||
static void lcdc_overlay_start(void *priv, uint32_t addr, uint32_t stride,
|
||||
uint32_t width, uint32_t height, uint32_t x,
|
||||
uint32_t y)
|
||||
{
|
||||
struct mdp_lcdc_info *lcdc = priv;
|
||||
struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
|
||||
|
||||
struct mdp4_overlay_pipe *pipe;
|
||||
pipe = lcdc_pipe;
|
||||
pipe->srcp0_addr = addr;
|
||||
|
||||
if (mdp->dma_config_dirty)
|
||||
{
|
||||
if(mdp->format == DMA_IBUF_FORMAT_RGB565) {
|
||||
pipe->src_format = MDP_RGB_565;
|
||||
pipe->srcp0_ystride = pipe->src_width * 2;
|
||||
} else if(mdp->format == DMA_IBUF_FORMAT_XRGB8888) {
|
||||
pipe->src_format = MDP_RGBA_8888;
|
||||
pipe->srcp0_ystride = pipe->src_width * 4;
|
||||
}
|
||||
mdp4_overlay_format2pipe(pipe);
|
||||
mdp->dma_config_dirty = false;
|
||||
}
|
||||
mdp4_overlay_rgb_setup(pipe);
|
||||
mdp4_overlay_reg_flush(pipe, 1); /* rgb1 and mixer0 */
|
||||
|
||||
}
|
||||
#endif
|
||||
static void precompute_timing_parms(struct mdp_lcdc_info *lcdc)
|
||||
{
|
||||
struct msm_lcdc_timing *timing = lcdc->pdata->timing;
|
||||
@ -404,6 +537,10 @@ static int mdp_lcdc_probe(struct platform_device *pdev)
|
||||
goto err_get_mdp_clk;
|
||||
}
|
||||
|
||||
lcdc->mdp_pclk = clk_get(mdp_dev->dev.parent, "mdp_pclk");
|
||||
if (IS_ERR(lcdc->mdp_pclk))
|
||||
lcdc->mdp_pclk = NULL;
|
||||
|
||||
lcdc->pclk = clk_get(mdp_dev->dev.parent, "lcdc_pclk_clk");
|
||||
if (IS_ERR(lcdc->pclk)) {
|
||||
pr_err("%s: failed to get lcdc_pclk\n", __func__);
|
||||
@ -443,7 +580,10 @@ static int mdp_lcdc_probe(struct platform_device *pdev)
|
||||
if (lcdc_pipe == NULL) {
|
||||
ptype = mdp4_overlay_format2type(MDP_RGB_565);
|
||||
pipe = mdp4_overlay_pipe_alloc(ptype);
|
||||
if (!pipe)
|
||||
goto err_mdp4_overlay_pipe_alloc;
|
||||
pipe->mixer_stage = MDP4_MIXER_STAGE_BASE;
|
||||
pipe->pipe_used = 1;
|
||||
pipe->mixer_num = MDP4_MIXER0;
|
||||
pipe->src_format = MDP_RGB_565;
|
||||
mdp4_overlay_format2pipe(pipe);
|
||||
@ -463,15 +603,8 @@ static int mdp_lcdc_probe(struct platform_device *pdev)
|
||||
pipe->srcp0_addr = (uint32_t) lcdc->fb_start;
|
||||
pipe->srcp0_ystride = pdata->fb_data->xres * 2;
|
||||
|
||||
mdp4_overlay_dmap_xy(pipe);
|
||||
mdp4_overlay_dmap_cfg(pipe, 1);
|
||||
|
||||
mdp4_overlay_rgb_setup(pipe);
|
||||
|
||||
mdp4_mixer_stage_up(pipe);
|
||||
|
||||
mdp4_overlayproc_cfg(pipe);
|
||||
mdp4_overlay_reg_flush(pipe, 1);
|
||||
#endif
|
||||
|
||||
lcdc->fb_panel_data.suspend = lcdc_suspend;
|
||||
@ -483,13 +616,12 @@ static int mdp_lcdc_probe(struct platform_device *pdev)
|
||||
lcdc->fb_panel_data.unblank = lcdc_unblank;
|
||||
lcdc->fb_panel_data.fb_data = pdata->fb_data;
|
||||
lcdc->fb_panel_data.interface_type = MSM_LCDC_INTERFACE;
|
||||
|
||||
lcdc->fb_panel_data.shutdown = lcdc_shutdown;
|
||||
ret = lcdc_hw_init(lcdc);
|
||||
if (ret) {
|
||||
pr_err("%s: Cannot initialize the mdp_lcdc\n", __func__);
|
||||
goto err_hw_init;
|
||||
}
|
||||
|
||||
lcdc->fb_pdev.name = "msm_panel";
|
||||
lcdc->fb_pdev.id = pdata->fb_id;
|
||||
lcdc->fb_pdev.resource = pdata->fb_resource;
|
||||
@ -504,16 +636,30 @@ static int mdp_lcdc_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
pr_info("%s: initialized\n", __func__);
|
||||
#ifdef CONFIG_PANEL_SELF_REFRESH
|
||||
if (lcdc->mdp->mdp_dev.overrides & MSM_MDP_RGB_PANEL_SELE_REFRESH) {
|
||||
ret = icm_init(lcdc);
|
||||
if (ret) {
|
||||
pr_err("%s: Cannot init dispaly selfrefresh \n", __func__);
|
||||
goto err_plat_dev_reg;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
err_plat_dev_reg:
|
||||
err_hw_init:
|
||||
#ifdef CONFIG_MSM_MDP40
|
||||
err_mdp4_overlay_pipe_alloc:
|
||||
#endif
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
clk_put(lcdc->pad_pclk);
|
||||
err_get_pad_pclk:
|
||||
clk_put(lcdc->pclk);
|
||||
err_get_pclk:
|
||||
if (lcdc->mdp_pclk)
|
||||
clk_put(lcdc->mdp_pclk);
|
||||
clk_put(lcdc->mdp_clk);
|
||||
err_get_mdp_clk:
|
||||
kfree(lcdc);
|
||||
|
@ -15,8 +15,12 @@
|
||||
#include <linux/fb.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/major.h>
|
||||
#include <linux/msm_hw3d.h>
|
||||
#include <linux/msm_mdp.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/android_pmem.h>
|
||||
#include <linux/wait.h>
|
||||
#include <mach/msm_fb.h>
|
||||
|
||||
#include "mdp_hw.h"
|
||||
@ -52,19 +56,19 @@ static uint32_t dst_img_cfg[] = {
|
||||
PPP_ARRAY1(CFG, DST)
|
||||
};
|
||||
|
||||
static uint32_t bytes_per_pixel[] = {
|
||||
static const uint32_t bytes_per_pixel[] = {
|
||||
[MDP_RGB_565] = 2,
|
||||
[MDP_RGB_888] = 3,
|
||||
[MDP_XRGB_8888] = 4,
|
||||
[MDP_Y_CBCR_H2V2] = 1,
|
||||
[MDP_ARGB_8888] = 4,
|
||||
[MDP_RGB_888] = 3,
|
||||
[MDP_Y_CRCB_H2V2] = 1,
|
||||
[MDP_YCRYCB_H2V1] = 2,
|
||||
[MDP_Y_CRCB_H2V1] = 1,
|
||||
[MDP_Y_CBCR_H2V1] = 1,
|
||||
[MDP_RGBA_8888] = 4,
|
||||
[MDP_BGRA_8888] = 4,
|
||||
[MDP_RGBX_8888] = 4,
|
||||
[MDP_Y_CBCR_H2V1] = 1,
|
||||
[MDP_Y_CBCR_H2V2] = 1,
|
||||
[MDP_Y_CRCB_H2V1] = 1,
|
||||
[MDP_Y_CRCB_H2V2] = 1,
|
||||
[MDP_YCRYCB_H2V1] = 2
|
||||
};
|
||||
|
||||
static uint32_t dst_op_chroma[] = {
|
||||
@ -79,6 +83,9 @@ static uint32_t bg_op_chroma[] = {
|
||||
PPP_ARRAY1(CHROMA_SAMP, BG)
|
||||
};
|
||||
|
||||
static DECLARE_WAIT_QUEUE_HEAD(mdp_ppp_waitqueue);
|
||||
DEFINE_MUTEX(mdp_mutex);
|
||||
|
||||
static uint32_t get_luma_offset(struct mdp_img *img,
|
||||
struct mdp_rect *rect, uint32_t bpp)
|
||||
{
|
||||
@ -268,7 +275,6 @@ static void blit_blend(struct mdp_blit_req *req, struct ppp_regs *regs)
|
||||
req->alpha &= 0xff;
|
||||
/* ALPHA BLEND */
|
||||
if (HAS_ALPHA(req->src.format)) {
|
||||
#if !defined(CONFIG_MACH_HTCLEO)
|
||||
regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON;
|
||||
if (req->flags & MDP_BLEND_FG_PREMULT) {
|
||||
#ifdef CONFIG_MSM_MDP31
|
||||
@ -285,10 +291,6 @@ static void blit_blend(struct mdp_blit_req *req, struct ppp_regs *regs)
|
||||
} else {
|
||||
regs->op |= PPP_OP_BLEND_SRCPIXEL_ALPHA;
|
||||
}
|
||||
#else
|
||||
regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON;
|
||||
regs->op |= PPP_OP_BLEND_SRCPIXEL_ALPHA;
|
||||
#endif
|
||||
} else if (req->alpha < MDP_ALPHA_NOP) {
|
||||
/* just blend by alpha */
|
||||
regs->op |= PPP_OP_ROT_ON | PPP_OP_BLEND_ON |
|
||||
@ -309,7 +311,7 @@ static void blit_blend(struct mdp_blit_req *req, struct ppp_regs *regs)
|
||||
set_blend_region(&req->dst, &req->dst_rect, regs);
|
||||
}
|
||||
|
||||
static int blit_scale(const struct mdp_info *mdp, struct mdp_blit_req *req,
|
||||
static int blit_scale(struct mdp_info *mdp, struct mdp_blit_req *req,
|
||||
struct ppp_regs *regs)
|
||||
{
|
||||
struct mdp_rect dst_rect;
|
||||
@ -330,7 +332,7 @@ static int blit_scale(const struct mdp_info *mdp, struct mdp_blit_req *req,
|
||||
}
|
||||
|
||||
if (mdp_ppp_cfg_scale(mdp, regs, &req->src_rect, &dst_rect,
|
||||
req->src.format, req->dst.format)) {
|
||||
req->src.format, req->dst.format)) {
|
||||
DLOG("crap, bad scale\n");
|
||||
return -1;
|
||||
}
|
||||
@ -339,7 +341,7 @@ static int blit_scale(const struct mdp_info *mdp, struct mdp_blit_req *req,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void blit_blur(const struct mdp_info *mdp, struct mdp_blit_req *req,
|
||||
static void blit_blur(struct mdp_info *mdp, struct mdp_blit_req *req,
|
||||
struct ppp_regs *regs)
|
||||
{
|
||||
int ret;
|
||||
@ -411,21 +413,23 @@ static void flush_imgs(struct mdp_blit_req *req, struct ppp_regs *regs,
|
||||
#ifdef CONFIG_ANDROID_PMEM
|
||||
uint32_t src0_len, src1_len, dst0_len, dst1_len;
|
||||
|
||||
/* flush src images to memory before dma to mdp */
|
||||
get_len(&req->src, &req->src_rect, regs->src_bpp, &src0_len,
|
||||
&src1_len);
|
||||
flush_pmem_file(src_file, req->src.offset, src0_len);
|
||||
if (IS_PSEUDOPLNR(req->src.format))
|
||||
flush_pmem_file(src_file, req->src.offset + src0_len,
|
||||
src1_len);
|
||||
if (!(req->flags & MDP_BLIT_NON_CACHED)) {
|
||||
/* flush src images to memory before dma to mdp */
|
||||
get_len(&req->src, &req->src_rect, regs->src_bpp, &src0_len,
|
||||
&src1_len);
|
||||
flush_pmem_file(src_file, req->src.offset, src0_len);
|
||||
if (IS_PSEUDOPLNR(req->src.format))
|
||||
flush_pmem_file(src_file, req->src.offset + src0_len,
|
||||
src1_len);
|
||||
|
||||
/* flush dst images */
|
||||
get_len(&req->dst, &req->dst_rect, regs->dst_bpp, &dst0_len,
|
||||
&dst1_len);
|
||||
flush_pmem_file(dst_file, req->dst.offset, dst0_len);
|
||||
if (IS_PSEUDOPLNR(req->dst.format))
|
||||
flush_pmem_file(dst_file, req->dst.offset + dst0_len,
|
||||
dst1_len);
|
||||
/* flush dst images */
|
||||
get_len(&req->dst, &req->dst_rect, regs->dst_bpp, &dst0_len,
|
||||
&dst1_len);
|
||||
flush_pmem_file(dst_file, req->dst.offset, dst0_len);
|
||||
if (IS_PSEUDOPLNR(req->dst.format))
|
||||
flush_pmem_file(dst_file, req->dst.offset + dst0_len,
|
||||
dst1_len);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -439,6 +443,13 @@ static uint32_t get_chroma_base(struct mdp_img *img, uint32_t base,
|
||||
return addr;
|
||||
}
|
||||
|
||||
int mdp_get_bytes_per_pixel(int format)
|
||||
{
|
||||
if (format < 0 || format >= MDP_IMGTYPE_LIMIT)
|
||||
return -1;
|
||||
return bytes_per_pixel[format];
|
||||
}
|
||||
|
||||
#if PPP_DUMP_BLITS
|
||||
#define mdp_writel_dbg(mdp, val, reg) do { \
|
||||
pr_info("%s: writing 0x%08x=0x%08x\n", __func__, (reg), (val));\
|
||||
@ -501,19 +512,17 @@ static int send_blit(const struct mdp_info *mdp, struct mdp_blit_req *req,
|
||||
mdp_writel_dbg(mdp, regs->bg_img_sz, MDP_PPP_BG_IMAGE_SIZE);
|
||||
mdp_writel_dbg(mdp, regs->bg_alpha_sel,
|
||||
MDP_PPP_BLEND_BG_ALPHA_SEL);
|
||||
|
||||
#if defined(CONFIG_MACH_HTCLEO)
|
||||
#if 0 /* zeusk: defined(CONFIG_MACH_HTCLEO) */
|
||||
mdp_writel_dbg(mdp, 0, MDP_TFETCH_TEST_MODE);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
if( src_file != -1 && dst_file != -1 )
|
||||
flush_imgs(req, regs, src_file, dst_file);
|
||||
flush_imgs(req, regs, src_file, dst_file);
|
||||
mdp_writel_dbg(mdp, 0x1000, MDP_DISPLAY0_START);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mdp_dump_blit(struct mdp_blit_req *req)
|
||||
/*
|
||||
static void mdp_dump_blit(struct mdp_blit_req *req)
|
||||
{
|
||||
pr_info("%s: src: w=%d h=%d f=0x%x offs=0x%x mem_id=%d\n", __func__,
|
||||
req->src.width, req->src.height, req->src.format,
|
||||
@ -531,8 +540,8 @@ void mdp_dump_blit(struct mdp_blit_req *req)
|
||||
pr_info("%s: transp_max=0x%08x\n", __func__, req->transp_mask);
|
||||
pr_info("%s: flags=%08x\n", __func__, req->flags);
|
||||
}
|
||||
|
||||
int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req,
|
||||
*/
|
||||
static int process_blit(struct mdp_info *mdp, struct mdp_blit_req *req,
|
||||
struct file *src_file, unsigned long src_start, unsigned long src_len,
|
||||
struct file *dst_file, unsigned long dst_start, unsigned long dst_len)
|
||||
{
|
||||
@ -644,13 +653,6 @@ int mdp_ppp_blit(const struct mdp_info *mdp, struct mdp_blit_req *req,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mdp_get_bytes_per_pixel(int format)
|
||||
{
|
||||
if (format < 0 || format >= MDP_IMGTYPE_LIMIT)
|
||||
return -1;
|
||||
return bytes_per_pixel[format];
|
||||
}
|
||||
|
||||
#define mdp_dump_register(mdp, reg) \
|
||||
printk(# reg ": %08x\n", mdp_readl((mdp), (reg)))
|
||||
|
||||
@ -668,234 +670,164 @@ void mdp_ppp_dump_debug(const struct mdp_info *mdp)
|
||||
mdp_dump_register(mdp, MDP_INTR_ENABLE);
|
||||
}
|
||||
|
||||
|
||||
/* Splits a blit into two horizontal stripes. Used to work around MDP bugs */
|
||||
int mdp_ppp_blit_split_height(struct mdp_info *mdp, const struct mdp_blit_req *req,
|
||||
struct file *src_file, unsigned long src_start, unsigned long src_len,
|
||||
struct file *dst_file, unsigned long dst_start, unsigned long dst_len)
|
||||
static int mdp_ppp_wait(struct mdp_info *mdp)
|
||||
{
|
||||
int ret;
|
||||
struct mdp_blit_req splitreq;
|
||||
int s_x_0, s_x_1, s_w_0, s_w_1, s_y_0, s_y_1, s_h_0, s_h_1;
|
||||
int d_x_0, d_x_1, d_w_0, d_w_1, d_y_0, d_y_1, d_h_0, d_h_1;
|
||||
|
||||
splitreq = *req;
|
||||
/* break dest roi at height*/
|
||||
d_x_0 = d_x_1 = req->dst_rect.x;
|
||||
d_w_0 = d_w_1 = req->dst_rect.w;
|
||||
d_y_0 = req->dst_rect.y;
|
||||
if (req->dst_rect.h % 32 == 3)
|
||||
d_h_1 = (req->dst_rect.h - 3) / 2 - 1;
|
||||
else
|
||||
d_h_1 = (req->dst_rect.h - 1) / 2 - 1;
|
||||
d_h_0 = req->dst_rect.h - d_h_1;
|
||||
d_y_1 = d_y_0 + d_h_0;
|
||||
if (req->dst_rect.h == 3) {
|
||||
d_h_1 = 2;
|
||||
d_h_0 = 2;
|
||||
d_y_1 = d_y_0 + 1;
|
||||
}
|
||||
/* break source roi */
|
||||
if (splitreq.flags & MDP_ROT_90) {
|
||||
s_y_0 = s_y_1 = req->src_rect.y;
|
||||
s_h_0 = s_h_1 = req->src_rect.h;
|
||||
s_x_0 = req->src_rect.x;
|
||||
s_w_1 = (req->src_rect.w * d_h_1) / req->dst_rect.h;
|
||||
s_w_0 = req->src_rect.w - s_w_1;
|
||||
s_x_1 = s_x_0 + s_w_0;
|
||||
if (d_h_1 >= 8 * s_w_1) {
|
||||
s_w_1++;
|
||||
s_x_1--;
|
||||
}
|
||||
} else {
|
||||
s_x_0 = s_x_1 = req->src_rect.x;
|
||||
s_w_0 = s_w_1 = req->src_rect.w;
|
||||
s_y_0 = req->src_rect.y;
|
||||
s_h_1 = (req->src_rect.h * d_h_1) / req->dst_rect.h;
|
||||
s_h_0 = req->src_rect.h - s_h_1;
|
||||
s_y_1 = s_y_0 + s_h_0;
|
||||
if (d_h_1 >= 8 * s_h_1) {
|
||||
s_h_1++;
|
||||
s_y_1--;
|
||||
}
|
||||
}
|
||||
|
||||
/* blit first region */
|
||||
if (((splitreq.flags & MDP_ROT_MASK) == MDP_ROT_90) ||
|
||||
((splitreq.flags & MDP_ROT_MASK) == 0x0)) {
|
||||
splitreq.src_rect.h = s_h_0;
|
||||
splitreq.src_rect.y = s_y_0;
|
||||
splitreq.dst_rect.h = d_h_0;
|
||||
splitreq.dst_rect.y = d_y_0;
|
||||
splitreq.src_rect.x = s_x_0;
|
||||
splitreq.src_rect.w = s_w_0;
|
||||
splitreq.dst_rect.x = d_x_0;
|
||||
splitreq.dst_rect.w = d_w_0;
|
||||
} else {
|
||||
splitreq.src_rect.h = s_h_0;
|
||||
splitreq.src_rect.y = s_y_0;
|
||||
splitreq.dst_rect.h = d_h_1;
|
||||
splitreq.dst_rect.y = d_y_1;
|
||||
splitreq.src_rect.x = s_x_0;
|
||||
splitreq.src_rect.w = s_w_0;
|
||||
splitreq.dst_rect.x = d_x_1;
|
||||
splitreq.dst_rect.w = d_w_1;
|
||||
}
|
||||
ret = mdp_blit_and_wait(mdp, &splitreq,
|
||||
src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
ret = mdp_wait(mdp, DL0_ROI_DONE, &mdp_ppp_waitqueue);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* blit second region */
|
||||
if (((splitreq.flags & MDP_ROT_MASK) == MDP_ROT_90) ||
|
||||
((splitreq.flags & MDP_ROT_MASK) == 0x0)) {
|
||||
splitreq.src_rect.h = s_h_1;
|
||||
splitreq.src_rect.y = s_y_1;
|
||||
splitreq.dst_rect.h = d_h_1;
|
||||
splitreq.dst_rect.y = d_y_1;
|
||||
splitreq.src_rect.x = s_x_1;
|
||||
splitreq.src_rect.w = s_w_1;
|
||||
splitreq.dst_rect.x = d_x_1;
|
||||
splitreq.dst_rect.w = d_w_1;
|
||||
} else {
|
||||
splitreq.src_rect.h = s_h_1;
|
||||
splitreq.src_rect.y = s_y_1;
|
||||
splitreq.dst_rect.h = d_h_0;
|
||||
splitreq.dst_rect.y = d_y_0;
|
||||
splitreq.src_rect.x = s_x_1;
|
||||
splitreq.src_rect.w = s_w_1;
|
||||
splitreq.dst_rect.x = d_x_0;
|
||||
splitreq.dst_rect.w = d_w_0;
|
||||
}
|
||||
ret = mdp_blit_and_wait(mdp, &splitreq,
|
||||
src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
mdp_ppp_dump_debug(mdp);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Splits a blit into two vertical stripes. Used to work around MDP bugs */
|
||||
int mdp_ppp_blit_split_width(struct mdp_info *mdp, const struct mdp_blit_req *req,
|
||||
struct file *src_file, unsigned long src_start, unsigned long src_len,
|
||||
struct file *dst_file, unsigned long dst_start, unsigned long dst_len)
|
||||
static int get_img(struct mdp_img *img, struct fb_info *info,
|
||||
unsigned long *start, unsigned long *len,
|
||||
struct file** filep)
|
||||
{
|
||||
int put_needed, ret = 0;
|
||||
struct file *file;
|
||||
unsigned long vstart;
|
||||
|
||||
if (img->memory_id & 0x40000000)
|
||||
{
|
||||
struct fb_info *fb = registered_fb[img->memory_id & 0x0000FFFF];
|
||||
if (fb)
|
||||
{
|
||||
*start = fb->fix.smem_start;
|
||||
*len = fb->fix.smem_len;
|
||||
}
|
||||
*filep = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!get_pmem_file(img->memory_id, start, &vstart, len, filep))
|
||||
return 0;
|
||||
else if (!get_msm_hw3d_file(img->memory_id, &img->offset, start, len,
|
||||
filep))
|
||||
return 0;
|
||||
|
||||
file = fget_light(img->memory_id, &put_needed);
|
||||
if (file == NULL)
|
||||
return -1;
|
||||
|
||||
if (MAJOR(file->f_dentry->d_inode->i_rdev) == FB_MAJOR) {
|
||||
*start = info->fix.smem_start;
|
||||
*len = info->fix.smem_len;
|
||||
ret = 0;
|
||||
} else
|
||||
ret = -1;
|
||||
fput_light(file, put_needed);
|
||||
|
||||
return ret;
|
||||
}
|
||||
void put_img(struct file *p_src_file)
|
||||
{
|
||||
#ifdef CONFIG_ANDROID_PMEM
|
||||
if (p_src_file)
|
||||
put_pmem_file(p_src_file);
|
||||
#else
|
||||
if (is_msm_hw3d_file(p_src_file))
|
||||
put_msm_hw3d_file(p_src_file);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void dump_req(struct mdp_blit_req *req,
|
||||
unsigned long src_start, unsigned long src_len,
|
||||
unsigned long dst_start, unsigned long dst_len)
|
||||
{
|
||||
pr_err("flags: 0x%x\n", req->flags);
|
||||
pr_err("src_start: 0x%08lx\n", src_start);
|
||||
pr_err("src_len: 0x%08lx\n", src_len);
|
||||
pr_err("src.offset: 0x%x\n", req->src.offset);
|
||||
pr_err("src.format: 0x%x\n", req->src.format);
|
||||
pr_err("src.width: %d\n", req->src.width);
|
||||
pr_err("src.height: %d\n", req->src.height);
|
||||
pr_err("src_rect.x: %d\n", req->src_rect.x);
|
||||
pr_err("src_rect.y: %d\n", req->src_rect.y);
|
||||
pr_err("src_rect.w: %d\n", req->src_rect.w);
|
||||
pr_err("src_rect.h: %d\n", req->src_rect.h);
|
||||
|
||||
pr_err("dst_start: 0x%08lx\n", dst_start);
|
||||
pr_err("dst_len: 0x%08lx\n", dst_len);
|
||||
pr_err("dst.offset: 0x%x\n", req->dst.offset);
|
||||
pr_err("dst.format: 0x%x\n", req->dst.format);
|
||||
pr_err("dst.width: %d\n", req->dst.width);
|
||||
pr_err("dst.height: %d\n", req->dst.height);
|
||||
pr_err("dst_rect.x: %d\n", req->dst_rect.x);
|
||||
pr_err("dst_rect.y: %d\n", req->dst_rect.y);
|
||||
pr_err("dst_rect.w: %d\n", req->dst_rect.w);
|
||||
pr_err("dst_rect.h: %d\n", req->dst_rect.h);
|
||||
}
|
||||
|
||||
int mdp_ppp_blit_and_wait(struct mdp_info *mdp, struct mdp_blit_req *req,
|
||||
struct file *src_file, unsigned long src_start, unsigned long src_len,
|
||||
struct file *dst_file, unsigned long dst_start, unsigned long dst_len)
|
||||
{
|
||||
int ret;
|
||||
struct mdp_blit_req splitreq;
|
||||
int s_x_0, s_x_1, s_w_0, s_w_1, s_y_0, s_y_1, s_h_0, s_h_1;
|
||||
int d_x_0, d_x_1, d_w_0, d_w_1, d_y_0, d_y_1, d_h_0, d_h_1;
|
||||
splitreq = *req;
|
||||
|
||||
/* break dest roi at width*/
|
||||
d_y_0 = d_y_1 = req->dst_rect.y;
|
||||
d_h_0 = d_h_1 = req->dst_rect.h;
|
||||
d_x_0 = req->dst_rect.x;
|
||||
if (req->dst_rect.w % 32 == 6)
|
||||
d_w_1 = req->dst_rect.w / 2 - 1;
|
||||
else if (req->dst_rect.w % 2 == 0)
|
||||
d_w_1 = req->dst_rect.w / 2;
|
||||
else if (req->dst_rect.w % 32 == 3)
|
||||
d_w_1 = (req->dst_rect.w - 3) / 2 - 1;
|
||||
else
|
||||
d_w_1 = (req->dst_rect.w - 1) / 2 - 1;
|
||||
d_w_0 = req->dst_rect.w - d_w_1;
|
||||
d_x_1 = d_x_0 + d_w_0;
|
||||
if (req->dst_rect.w == 3) {
|
||||
d_w_1 = 2;
|
||||
d_w_0 = 2;
|
||||
d_x_1 = d_x_0 + 1;
|
||||
mdp->enable_irq(mdp, DL0_ROI_DONE);
|
||||
ret = process_blit(mdp, req, src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
if (unlikely(ret)) {
|
||||
mdp->disable_irq(mdp, DL0_ROI_DONE);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* break src roi at height or width*/
|
||||
if (splitreq.flags & MDP_ROT_90) {
|
||||
s_x_0 = s_x_1 = req->src_rect.x;
|
||||
s_w_0 = s_w_1 = req->src_rect.w;
|
||||
s_y_0 = req->src_rect.y;
|
||||
s_h_1 = (req->src_rect.h * d_w_1) / req->dst_rect.w;
|
||||
s_h_0 = req->src_rect.h - s_h_1;
|
||||
s_y_1 = s_y_0 + s_h_0;
|
||||
if (d_w_1 >= 8 * s_h_1) {
|
||||
s_h_1++;
|
||||
s_y_1--;
|
||||
}
|
||||
} else {
|
||||
s_y_0 = s_y_1 = req->src_rect.y;
|
||||
s_h_0 = s_h_1 = req->src_rect.h;
|
||||
s_x_0 = req->src_rect.x;
|
||||
s_w_1 = (req->src_rect.w * d_w_1) / req->dst_rect.w;
|
||||
s_w_0 = req->src_rect.w - s_w_1;
|
||||
s_x_1 = s_x_0 + s_w_0;
|
||||
if (d_w_1 >= 8 * s_w_1) {
|
||||
s_w_1++;
|
||||
s_x_1--;
|
||||
}
|
||||
ret = mdp_ppp_wait(mdp);
|
||||
if (unlikely(ret)) {
|
||||
printk(KERN_ERR "%s: failed!\n", __func__);
|
||||
pr_err("original request:\n");
|
||||
dump_req(mdp->req, src_start, src_len, dst_start, dst_len);
|
||||
pr_err("dead request:\n");
|
||||
dump_req(req, src_start, src_len, dst_start, dst_len);
|
||||
BUG();
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* blit first region */
|
||||
if (((splitreq.flags & MDP_ROT_MASK) == MDP_ROT_270) ||
|
||||
((splitreq.flags & MDP_ROT_MASK) == 0x0)) {
|
||||
splitreq.src_rect.h = s_h_0;
|
||||
splitreq.src_rect.y = s_y_0;
|
||||
splitreq.dst_rect.h = d_h_0;
|
||||
splitreq.dst_rect.y = d_y_0;
|
||||
splitreq.src_rect.x = s_x_0;
|
||||
splitreq.src_rect.w = s_w_0;
|
||||
splitreq.dst_rect.x = d_x_0;
|
||||
splitreq.dst_rect.w = d_w_0;
|
||||
} else {
|
||||
splitreq.src_rect.h = s_h_0;
|
||||
splitreq.src_rect.y = s_y_0;
|
||||
splitreq.dst_rect.h = d_h_1;
|
||||
splitreq.dst_rect.y = d_y_1;
|
||||
splitreq.src_rect.x = s_x_0;
|
||||
splitreq.src_rect.w = s_w_0;
|
||||
splitreq.dst_rect.x = d_x_1;
|
||||
splitreq.dst_rect.w = d_w_1;
|
||||
}
|
||||
int mdp_ppp_blit(struct mdp_info *mdp, struct fb_info *fb,
|
||||
struct mdp_blit_req *req)
|
||||
{
|
||||
int ret;
|
||||
unsigned long src_start = 0, src_len = 0, dst_start = 0, dst_len = 0;
|
||||
struct file *src_file = 0, *dst_file = 0;
|
||||
|
||||
if (unlikely((splitreq.dst_rect.h != 1) &&
|
||||
((splitreq.dst_rect.h % 32 == 3) ||
|
||||
(splitreq.dst_rect.h % 32) == 1)))
|
||||
ret = mdp_ppp_blit_split_height(mdp, &splitreq,
|
||||
src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
else
|
||||
ret = mdp_blit_and_wait(mdp, &splitreq,
|
||||
src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
ret = mdp_ppp_validate_blit(mdp, req);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* blit second region */
|
||||
if (((splitreq.flags & MDP_ROT_MASK) == MDP_ROT_270) ||
|
||||
((splitreq.flags & MDP_ROT_MASK) == 0x0)) {
|
||||
splitreq.src_rect.h = s_h_1;
|
||||
splitreq.src_rect.y = s_y_1;
|
||||
splitreq.dst_rect.h = d_h_1;
|
||||
splitreq.dst_rect.y = d_y_1;
|
||||
splitreq.src_rect.x = s_x_1;
|
||||
splitreq.src_rect.w = s_w_1;
|
||||
splitreq.dst_rect.x = d_x_1;
|
||||
splitreq.dst_rect.w = d_w_1;
|
||||
} else {
|
||||
splitreq.src_rect.h = s_h_1;
|
||||
splitreq.src_rect.y = s_y_1;
|
||||
splitreq.dst_rect.h = d_h_0;
|
||||
splitreq.dst_rect.y = d_y_0;
|
||||
splitreq.src_rect.x = s_x_1;
|
||||
splitreq.src_rect.w = s_w_1;
|
||||
splitreq.dst_rect.x = d_x_0;
|
||||
splitreq.dst_rect.w = d_w_0;
|
||||
/* do this first so that if this fails, the caller can always
|
||||
* safely call put_img */
|
||||
if (unlikely(get_img(&req->src, fb, &src_start, &src_len, &src_file))) {
|
||||
printk(KERN_ERR "mdp_ppp: could not retrieve src image from "
|
||||
"memory\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (unlikely((splitreq.dst_rect.h != 1) &&
|
||||
((splitreq.dst_rect.h % 32 == 3) ||
|
||||
(splitreq.dst_rect.h % 32) == 1)))
|
||||
ret = mdp_ppp_blit_split_height(mdp, &splitreq,
|
||||
src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
else
|
||||
ret = mdp_blit_and_wait(mdp, &splitreq,
|
||||
src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
if (unlikely(get_img(&req->dst, fb, &dst_start, &dst_len, &dst_file))) {
|
||||
printk(KERN_ERR "mdp_ppp: could not retrieve dst image from "
|
||||
"memory\n");
|
||||
put_img(src_file);
|
||||
return -EINVAL;
|
||||
}
|
||||
mutex_lock(&mdp_mutex);
|
||||
|
||||
/* transp_masking unimplemented */
|
||||
req->transp_mask = MDP_TRANSP_NOP;
|
||||
mdp->req = req;
|
||||
|
||||
ret = mdp_ppp_do_blit(mdp, req, src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
|
||||
put_img(src_file);
|
||||
put_img(dst_file);
|
||||
mutex_unlock(&mdp_mutex);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
void mdp_ppp_handle_isr(struct mdp_info *mdp, uint32_t mask)
|
||||
{
|
||||
if (mask & DL0_ROI_DONE)
|
||||
wake_up(&mdp_ppp_waitqueue);
|
||||
}
|
||||
|
||||
|
||||
|
@ -16,7 +16,6 @@
|
||||
#define _VIDEO_MSM_MDP_PPP_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#define PPP_DUMP_BLITS 0
|
||||
|
||||
struct ppp_regs {
|
||||
uint32_t src0;
|
||||
@ -63,40 +62,57 @@ struct ppp_regs {
|
||||
struct mdp_info;
|
||||
struct mdp_rect;
|
||||
struct mdp_blit_req;
|
||||
struct fb_info;
|
||||
|
||||
void mdp_ppp_init_scale(const struct mdp_info *mdp);
|
||||
int mdp_ppp_cfg_scale(const struct mdp_info *mdp, struct ppp_regs *regs,
|
||||
struct mdp_rect *src_rect, struct mdp_rect *dst_rect,
|
||||
uint32_t src_format, uint32_t dst_format);
|
||||
int mdp_ppp_load_blur(const struct mdp_info *mdp);
|
||||
void mdp_dump_blit(struct mdp_blit_req *req);
|
||||
|
||||
|
||||
#if defined(CONFIG_MSM_MDP31) || defined(CONFIG_MSM_MDP302)
|
||||
int mdp_ppp_blit_split_width(struct mdp_info *mdp, const struct mdp_blit_req *req,
|
||||
struct file *src_file, unsigned long src_start, unsigned long src_len,
|
||||
struct file *dst_file, unsigned long dst_start, unsigned long dst_len);
|
||||
int mdp_ppp_blit_split_height(struct mdp_info *mdp, const struct mdp_blit_req *req,
|
||||
struct file *src_file, unsigned long src_start, unsigned long src_len,
|
||||
struct file *dst_file, unsigned long dst_start, unsigned long dst_len);
|
||||
|
||||
#if defined(CONFIG_MSM_MDP302)
|
||||
int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req, struct ppp_regs *regs);
|
||||
#else
|
||||
static inline int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req,
|
||||
struct ppp_regs *regs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req, struct ppp_regs *regs);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_FB_MSM_MDP_PPP
|
||||
int mdp_get_bytes_per_pixel(int format);
|
||||
int mdp_blit_and_wait(struct mdp_info *mdp, struct mdp_blit_req *req,
|
||||
struct file *src_file, unsigned long src_start, unsigned long src_len,
|
||||
struct file *dst_file, unsigned long dst_start, unsigned long dst_len);
|
||||
int mdp_ppp_blit(struct mdp_info *mdp, struct fb_info *fb,
|
||||
struct mdp_blit_req *req);
|
||||
void mdp_ppp_handle_isr(struct mdp_info *mdp, uint32_t mask);
|
||||
int mdp_ppp_blit_and_wait(struct mdp_info *mdp, struct mdp_blit_req *req,
|
||||
struct file *src_file, unsigned long src_start,
|
||||
unsigned long src_len, struct file *dst_file,
|
||||
unsigned long dst_start, unsigned long dst_len);
|
||||
|
||||
/* these must be provided by h/w specific ppp files */
|
||||
void mdp_ppp_init_scale(struct mdp_info *mdp);
|
||||
int mdp_ppp_cfg_scale(struct mdp_info *mdp, struct ppp_regs *regs,
|
||||
struct mdp_rect *src_rect, struct mdp_rect *dst_rect,
|
||||
uint32_t src_format, uint32_t dst_format);
|
||||
int mdp_ppp_load_blur(struct mdp_info *mdp);
|
||||
int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req, struct ppp_regs *regs);
|
||||
int mdp_ppp_validate_blit(struct mdp_info *mdp, struct mdp_blit_req *req);
|
||||
int mdp_ppp_do_blit(struct mdp_info *mdp, struct mdp_blit_req *req,
|
||||
struct file *src_file, unsigned long src_start,
|
||||
unsigned long src_len, struct file *dst_file,
|
||||
unsigned long dst_start, unsigned long dst_len);
|
||||
|
||||
#else
|
||||
|
||||
static inline int mdp_get_bytes_per_pixel(int format) { return -1; }
|
||||
static inline int mdp_ppp_blit(struct mdp_info *mdp, struct fb_info *fb,
|
||||
struct mdp_blit_req *req) { return -EINVAL; }
|
||||
static inline void mdp_ppp_handle_isr(struct mdp_info *mdp, uint32_t mask) {}
|
||||
static inline int mdp_ppp_blit_and_wait(struct mdp_info *mdp,
|
||||
struct mdp_blit_req *req, struct file *src_file,
|
||||
unsigned long src_start, unsigned long src_len,
|
||||
struct file *dst_file, unsigned long dst_start,
|
||||
unsigned long dst_len) { return 0; }
|
||||
|
||||
static inline void mdp_ppp_init_scale(struct mdp_info *mdp) {}
|
||||
static inline int mdp_ppp_cfg_scale(struct mdp_info *mdp, struct ppp_regs *regs,
|
||||
struct mdp_rect *src_rect, struct mdp_rect *dst_rect,
|
||||
uint32_t src_format, uint32_t dst_format) { return 0; }
|
||||
static inline int mdp_ppp_load_blur(struct mdp_info *mdp) { return 0; }
|
||||
static inline int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req, struct ppp_regs *regs) { return 0; }
|
||||
static inline int mdp_ppp_validate_blit(struct mdp_info *mdp, struct mdp_blit_req *req) { return -EINVAL; }
|
||||
static inline int mdp_ppp_do_blit(struct mdp_info *mdp,
|
||||
struct mdp_blit_req *req,
|
||||
struct file *src_file, unsigned long src_start,
|
||||
unsigned long src_len, struct file *dst_file,
|
||||
unsigned long dst_start, unsigned long dst_len) { return 0; }
|
||||
|
||||
|
||||
#endif /* CONFIG_FB_MSM_MDP_PPP */
|
||||
|
||||
#endif /* _VIDEO_MSM_MDP_PPP_H_ */
|
||||
|
@ -1016,7 +1016,7 @@ static int scale_params(uint32_t dim_in, uint32_t dim_out, uint32_t origin,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mdp_ppp_cfg_scale(const struct mdp_info *mdp, struct ppp_regs *regs,
|
||||
int mdp_ppp_cfg_scale(struct mdp_info *mdp, struct ppp_regs *regs,
|
||||
struct mdp_rect *src_rect, struct mdp_rect *dst_rect,
|
||||
uint32_t src_format, uint32_t dst_format)
|
||||
{
|
||||
@ -1070,7 +1070,7 @@ int mdp_ppp_cfg_scale(const struct mdp_info *mdp, struct ppp_regs *regs,
|
||||
}
|
||||
|
||||
|
||||
int mdp_ppp_load_blur(const struct mdp_info *mdp)
|
||||
int mdp_ppp_load_blur(struct mdp_info *mdp)
|
||||
{
|
||||
if (!(downscale_x_table == MDP_DOWNSCALE_BLUR &&
|
||||
downscale_y_table == MDP_DOWNSCALE_BLUR)) {
|
||||
@ -1082,10 +1082,64 @@ int mdp_ppp_load_blur(const struct mdp_info *mdp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mdp_ppp_init_scale(const struct mdp_info *mdp)
|
||||
void mdp_ppp_init_scale(struct mdp_info *mdp)
|
||||
{
|
||||
downscale_x_table = MDP_DOWNSCALE_MAX;
|
||||
downscale_y_table = MDP_DOWNSCALE_MAX;
|
||||
|
||||
load_table(mdp, mdp_upscale_table, ARRAY_SIZE(mdp_upscale_table));
|
||||
}
|
||||
|
||||
int mdp_ppp_validate_blit(struct mdp_info *mdp, struct mdp_blit_req *req)
|
||||
{
|
||||
/* WORKAROUND FOR HARDWARE BUG IN BG TILE FETCH */
|
||||
if (unlikely(req->src_rect.h == 0 ||
|
||||
req->src_rect.w == 0)) {
|
||||
pr_info("mdp_ppp: src img of zero size!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (unlikely(req->dst_rect.h == 0 ||
|
||||
req->dst_rect.w == 0))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mdp_ppp_do_blit(struct mdp_info *mdp, struct mdp_blit_req *req,
|
||||
struct file *src_file, unsigned long src_start,
|
||||
unsigned long src_len, struct file *dst_file,
|
||||
unsigned long dst_start, unsigned long dst_len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (unlikely((req->transp_mask != MDP_TRANSP_NOP ||
|
||||
req->alpha != MDP_ALPHA_NOP ||
|
||||
HAS_ALPHA(req->src.format)) &&
|
||||
(req->flags & MDP_ROT_90 &&
|
||||
req->dst_rect.w <= 16 && req->dst_rect.h >= 16))) {
|
||||
int i;
|
||||
unsigned int tiles = req->dst_rect.h / 16;
|
||||
unsigned int remainder = req->dst_rect.h % 16;
|
||||
req->src_rect.w = 16*req->src_rect.w / req->dst_rect.h;
|
||||
req->dst_rect.h = 16;
|
||||
for (i = 0; i < tiles; i++) {
|
||||
ret = mdp_ppp_blit_and_wait(mdp, req,
|
||||
src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
if (ret)
|
||||
goto end;
|
||||
req->dst_rect.y += 16;
|
||||
req->src_rect.x += req->src_rect.w;
|
||||
}
|
||||
if (!remainder)
|
||||
goto end;
|
||||
req->src_rect.w = remainder*req->src_rect.w / req->dst_rect.h;
|
||||
req->dst_rect.h = remainder;
|
||||
}
|
||||
|
||||
ret = mdp_ppp_blit_and_wait(mdp, req,
|
||||
src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
@ -276,7 +276,7 @@ static int scale_idx(int factor)
|
||||
return idx;
|
||||
}
|
||||
|
||||
int mdp_ppp_cfg_scale(const struct mdp_info *mdp, struct ppp_regs *regs,
|
||||
int mdp_ppp_cfg_scale(struct mdp_info *mdp, struct ppp_regs *regs,
|
||||
struct mdp_rect *src_rect, struct mdp_rect *dst_rect,
|
||||
uint32_t src_format, uint32_t dst_format)
|
||||
{
|
||||
@ -319,16 +319,319 @@ int mdp_ppp_cfg_scale(const struct mdp_info *mdp, struct ppp_regs *regs,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mdp_ppp_load_blur(const struct mdp_info *mdp)
|
||||
int mdp_ppp_load_blur(struct mdp_info *mdp)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
void mdp_ppp_init_scale(const struct mdp_info *mdp)
|
||||
int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req, struct ppp_regs *regs)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void mdp_ppp_init_scale(struct mdp_info *mdp)
|
||||
{
|
||||
int scale;
|
||||
for (scale = 0; scale < MDP_SCALE_MAX; ++scale)
|
||||
load_table(mdp, scale, 0);
|
||||
}
|
||||
|
||||
/* Splits a blit into two horizontal stripes. Used to work around MDP bugs */
|
||||
static int blit_split_height(struct mdp_info *mdp, const struct mdp_blit_req *req,
|
||||
struct file *src_file, unsigned long src_start, unsigned long src_len,
|
||||
struct file *dst_file, unsigned long dst_start, unsigned long dst_len)
|
||||
{
|
||||
int ret;
|
||||
struct mdp_blit_req splitreq;
|
||||
int s_x_0, s_x_1, s_w_0, s_w_1, s_y_0, s_y_1, s_h_0, s_h_1;
|
||||
int d_x_0, d_x_1, d_w_0, d_w_1, d_y_0, d_y_1, d_h_0, d_h_1;
|
||||
|
||||
splitreq = *req;
|
||||
/* break dest roi at height*/
|
||||
d_x_0 = d_x_1 = req->dst_rect.x;
|
||||
d_w_0 = d_w_1 = req->dst_rect.w;
|
||||
d_y_0 = req->dst_rect.y;
|
||||
if (req->dst_rect.h % 32 == 3)
|
||||
d_h_1 = (req->dst_rect.h - 3) / 2 - 1;
|
||||
else
|
||||
d_h_1 = (req->dst_rect.h - 1) / 2 - 1;
|
||||
d_h_0 = req->dst_rect.h - d_h_1;
|
||||
d_y_1 = d_y_0 + d_h_0;
|
||||
if (req->dst_rect.h == 3) {
|
||||
d_h_1 = 2;
|
||||
d_h_0 = 2;
|
||||
d_y_1 = d_y_0 + 1;
|
||||
}
|
||||
/* break source roi */
|
||||
if (splitreq.flags & MDP_ROT_90) {
|
||||
s_y_0 = s_y_1 = req->src_rect.y;
|
||||
s_h_0 = s_h_1 = req->src_rect.h;
|
||||
s_x_0 = req->src_rect.x;
|
||||
s_w_1 = (req->src_rect.w * d_h_1) / req->dst_rect.h;
|
||||
s_w_0 = req->src_rect.w - s_w_1;
|
||||
s_x_1 = s_x_0 + s_w_0;
|
||||
if (d_h_1 >= 8 * s_w_1) {
|
||||
s_w_1++;
|
||||
s_x_1--;
|
||||
}
|
||||
} else {
|
||||
s_x_0 = s_x_1 = req->src_rect.x;
|
||||
s_w_0 = s_w_1 = req->src_rect.w;
|
||||
s_y_0 = req->src_rect.y;
|
||||
s_h_1 = (req->src_rect.h * d_h_1) / req->dst_rect.h;
|
||||
s_h_0 = req->src_rect.h - s_h_1;
|
||||
s_y_1 = s_y_0 + s_h_0;
|
||||
if (d_h_1 >= 8 * s_h_1) {
|
||||
s_h_1++;
|
||||
s_y_1--;
|
||||
}
|
||||
}
|
||||
|
||||
/* blit first region */
|
||||
if (((splitreq.flags & 0x07) == MDP_ROT_90) ||
|
||||
((splitreq.flags & 0x07) == 0x0)) {
|
||||
splitreq.src_rect.h = s_h_0;
|
||||
splitreq.src_rect.y = s_y_0;
|
||||
splitreq.dst_rect.h = d_h_0;
|
||||
splitreq.dst_rect.y = d_y_0;
|
||||
splitreq.src_rect.x = s_x_0;
|
||||
splitreq.src_rect.w = s_w_0;
|
||||
splitreq.dst_rect.x = d_x_0;
|
||||
splitreq.dst_rect.w = d_w_0;
|
||||
} else {
|
||||
splitreq.src_rect.h = s_h_0;
|
||||
splitreq.src_rect.y = s_y_0;
|
||||
splitreq.dst_rect.h = d_h_1;
|
||||
splitreq.dst_rect.y = d_y_1;
|
||||
splitreq.src_rect.x = s_x_0;
|
||||
splitreq.src_rect.w = s_w_0;
|
||||
splitreq.dst_rect.x = d_x_1;
|
||||
splitreq.dst_rect.w = d_w_1;
|
||||
}
|
||||
ret = mdp_ppp_blit_and_wait(mdp, &splitreq,
|
||||
src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* blit second region */
|
||||
if (((splitreq.flags & 0x07) == MDP_ROT_90) ||
|
||||
((splitreq.flags & 0x07) == 0x0)) {
|
||||
splitreq.src_rect.h = s_h_1;
|
||||
splitreq.src_rect.y = s_y_1;
|
||||
splitreq.dst_rect.h = d_h_1;
|
||||
splitreq.dst_rect.y = d_y_1;
|
||||
splitreq.src_rect.x = s_x_1;
|
||||
splitreq.src_rect.w = s_w_1;
|
||||
splitreq.dst_rect.x = d_x_1;
|
||||
splitreq.dst_rect.w = d_w_1;
|
||||
} else {
|
||||
splitreq.src_rect.h = s_h_1;
|
||||
splitreq.src_rect.y = s_y_1;
|
||||
splitreq.dst_rect.h = d_h_0;
|
||||
splitreq.dst_rect.y = d_y_0;
|
||||
splitreq.src_rect.x = s_x_1;
|
||||
splitreq.src_rect.w = s_w_1;
|
||||
splitreq.dst_rect.x = d_x_0;
|
||||
splitreq.dst_rect.w = d_w_0;
|
||||
}
|
||||
ret = mdp_ppp_blit_and_wait(mdp, &splitreq,
|
||||
src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Splits a blit into two vertical stripes. Used to work around MDP bugs */
|
||||
static int blit_split_width(struct mdp_info *mdp, const struct mdp_blit_req *req,
|
||||
struct file *src_file, unsigned long src_start, unsigned long src_len,
|
||||
struct file *dst_file, unsigned long dst_start, unsigned long dst_len)
|
||||
{
|
||||
int ret;
|
||||
struct mdp_blit_req splitreq;
|
||||
int s_x_0, s_x_1, s_w_0, s_w_1, s_y_0, s_y_1, s_h_0, s_h_1;
|
||||
int d_x_0, d_x_1, d_w_0, d_w_1, d_y_0, d_y_1, d_h_0, d_h_1;
|
||||
splitreq = *req;
|
||||
|
||||
/* break dest roi at width*/
|
||||
d_y_0 = d_y_1 = req->dst_rect.y;
|
||||
d_h_0 = d_h_1 = req->dst_rect.h;
|
||||
d_x_0 = req->dst_rect.x;
|
||||
if (req->dst_rect.w % 32 == 6)
|
||||
d_w_1 = req->dst_rect.w / 2 - 1;
|
||||
else if (req->dst_rect.w % 2 == 0)
|
||||
d_w_1 = req->dst_rect.w / 2;
|
||||
else if (req->dst_rect.w % 32 == 3)
|
||||
d_w_1 = (req->dst_rect.w - 3) / 2 - 1;
|
||||
else
|
||||
d_w_1 = (req->dst_rect.w - 1) / 2 - 1;
|
||||
d_w_0 = req->dst_rect.w - d_w_1;
|
||||
d_x_1 = d_x_0 + d_w_0;
|
||||
if (req->dst_rect.w == 3) {
|
||||
d_w_1 = 2;
|
||||
d_w_0 = 2;
|
||||
d_x_1 = d_x_0 + 1;
|
||||
}
|
||||
|
||||
/* break src roi at height or width*/
|
||||
if (splitreq.flags & MDP_ROT_90) {
|
||||
s_x_0 = s_x_1 = req->src_rect.x;
|
||||
s_w_0 = s_w_1 = req->src_rect.w;
|
||||
s_y_0 = req->src_rect.y;
|
||||
s_h_1 = (req->src_rect.h * d_w_1) / req->dst_rect.w;
|
||||
s_h_0 = req->src_rect.h - s_h_1;
|
||||
s_y_1 = s_y_0 + s_h_0;
|
||||
if (d_w_1 >= 8 * s_h_1) {
|
||||
s_h_1++;
|
||||
s_y_1--;
|
||||
}
|
||||
} else {
|
||||
s_y_0 = s_y_1 = req->src_rect.y;
|
||||
s_h_0 = s_h_1 = req->src_rect.h;
|
||||
s_x_0 = req->src_rect.x;
|
||||
s_w_1 = (req->src_rect.w * d_w_1) / req->dst_rect.w;
|
||||
s_w_0 = req->src_rect.w - s_w_1;
|
||||
s_x_1 = s_x_0 + s_w_0;
|
||||
if (d_w_1 >= 8 * s_w_1) {
|
||||
s_w_1++;
|
||||
s_x_1--;
|
||||
}
|
||||
}
|
||||
|
||||
/* blit first region */
|
||||
if (((splitreq.flags & 0x07) == MDP_ROT_270) ||
|
||||
((splitreq.flags & 0x07) == 0x0)) {
|
||||
splitreq.src_rect.h = s_h_0;
|
||||
splitreq.src_rect.y = s_y_0;
|
||||
splitreq.dst_rect.h = d_h_0;
|
||||
splitreq.dst_rect.y = d_y_0;
|
||||
splitreq.src_rect.x = s_x_0;
|
||||
splitreq.src_rect.w = s_w_0;
|
||||
splitreq.dst_rect.x = d_x_0;
|
||||
splitreq.dst_rect.w = d_w_0;
|
||||
} else {
|
||||
splitreq.src_rect.h = s_h_0;
|
||||
splitreq.src_rect.y = s_y_0;
|
||||
splitreq.dst_rect.h = d_h_1;
|
||||
splitreq.dst_rect.y = d_y_1;
|
||||
splitreq.src_rect.x = s_x_0;
|
||||
splitreq.src_rect.w = s_w_0;
|
||||
splitreq.dst_rect.x = d_x_1;
|
||||
splitreq.dst_rect.w = d_w_1;
|
||||
}
|
||||
|
||||
if (unlikely((splitreq.dst_rect.h != 1) &&
|
||||
((splitreq.dst_rect.h % 32 == 3) ||
|
||||
(splitreq.dst_rect.h % 32) == 1)))
|
||||
ret = blit_split_height(mdp, &splitreq,
|
||||
src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
else
|
||||
ret = mdp_ppp_blit_and_wait(mdp, &splitreq,
|
||||
src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* blit second region */
|
||||
if (((splitreq.flags & 0x07) == MDP_ROT_270) ||
|
||||
((splitreq.flags & 0x07) == 0x0)) {
|
||||
splitreq.src_rect.h = s_h_1;
|
||||
splitreq.src_rect.y = s_y_1;
|
||||
splitreq.dst_rect.h = d_h_1;
|
||||
splitreq.dst_rect.y = d_y_1;
|
||||
splitreq.src_rect.x = s_x_1;
|
||||
splitreq.src_rect.w = s_w_1;
|
||||
splitreq.dst_rect.x = d_x_1;
|
||||
splitreq.dst_rect.w = d_w_1;
|
||||
} else {
|
||||
splitreq.src_rect.h = s_h_1;
|
||||
splitreq.src_rect.y = s_y_1;
|
||||
splitreq.dst_rect.h = d_h_0;
|
||||
splitreq.dst_rect.y = d_y_0;
|
||||
splitreq.src_rect.x = s_x_1;
|
||||
splitreq.src_rect.w = s_w_1;
|
||||
splitreq.dst_rect.x = d_x_0;
|
||||
splitreq.dst_rect.w = d_w_0;
|
||||
}
|
||||
|
||||
if (unlikely((splitreq.dst_rect.h != 1) &&
|
||||
((splitreq.dst_rect.h % 32 == 3) ||
|
||||
(splitreq.dst_rect.h % 32) == 1)))
|
||||
ret = blit_split_height(mdp, &splitreq,
|
||||
src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
else
|
||||
ret = mdp_ppp_blit_and_wait(mdp, &splitreq,
|
||||
src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int mdp_ppp_validate_blit(struct mdp_info *mdp, struct mdp_blit_req *req)
|
||||
{
|
||||
if (req->flags & MDP_ROT_90) {
|
||||
if (unlikely(((req->dst_rect.h == 1) &&
|
||||
((req->src_rect.w != 1) ||
|
||||
(req->dst_rect.w != req->src_rect.h))) ||
|
||||
((req->dst_rect.w == 1) && ((req->src_rect.h != 1) ||
|
||||
(req->dst_rect.h != req->src_rect.w))))) {
|
||||
pr_err("mpd_ppp: error scaling when size is 1!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
if (unlikely(((req->dst_rect.w == 1) &&
|
||||
((req->src_rect.w != 1) ||
|
||||
(req->dst_rect.h != req->src_rect.h))) ||
|
||||
((req->dst_rect.h == 1) && ((req->src_rect.h != 1) ||
|
||||
(req->dst_rect.h != req->src_rect.h))))) {
|
||||
pr_err("mpd_ppp: error scaling when size is 1!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* WORKAROUND FOR HARDWARE BUG IN BG TILE FETCH */
|
||||
if (unlikely(req->src_rect.h == 0 ||
|
||||
req->src_rect.w == 0)) {
|
||||
pr_info("mdp_ppp: src img of zero size!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if (unlikely(req->dst_rect.h == 0 ||
|
||||
req->dst_rect.w == 0))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mdp_ppp_do_blit(struct mdp_info *mdp, struct mdp_blit_req *req,
|
||||
struct file *src_file, unsigned long src_start,
|
||||
unsigned long src_len, struct file *dst_file,
|
||||
unsigned long dst_start, unsigned long dst_len)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Workarounds for MDP 3.1 hardware bugs */
|
||||
if (unlikely((mdp_get_bytes_per_pixel(req->dst.format) == 4) &&
|
||||
(req->dst_rect.w != 1) &&
|
||||
(((req->dst_rect.w % 8) == 6) ||
|
||||
((req->dst_rect.w % 32) == 3) ||
|
||||
((req->dst_rect.w % 32) == 1)))) {
|
||||
ret = blit_split_width(mdp, req,
|
||||
src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
goto end;
|
||||
} else if (unlikely((req->dst_rect.w != 1) && (req->dst_rect.h != 1) &&
|
||||
((req->dst_rect.h % 32) == 3 ||
|
||||
(req->dst_rect.h % 32) == 1))) {
|
||||
ret = blit_split_height(mdp, req,
|
||||
src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
goto end;
|
||||
}
|
||||
|
||||
ret = mdp_ppp_blit_and_wait(mdp, req,
|
||||
src_file, src_start, src_len,
|
||||
dst_file, dst_start, dst_len);
|
||||
end:
|
||||
return ret;
|
||||
}
|
||||
|
@ -33,11 +33,17 @@
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/android_pmem.h>
|
||||
#include "mdp_hw.h"
|
||||
|
||||
extern void start_drawing_late_resume(struct early_suspend *h);
|
||||
static void msmfb_resume_handler(struct early_suspend *h);
|
||||
static void msmfb_resume(struct work_struct *work);
|
||||
|
||||
#ifdef CONFIG_MSM_HDMI
|
||||
void hdmi_DoBlit(int offset);
|
||||
int hdmi_usePanelSync(void);
|
||||
#endif
|
||||
|
||||
#define MSMFB_DEBUG 1
|
||||
#ifdef CONFIG_FB_MSM_LOGO
|
||||
#define INIT_IMAGE_FILE "/logo.rle"
|
||||
@ -59,6 +65,11 @@ extern int load_565rle_image(char *filename);
|
||||
#define BLIT_TIME 0x4
|
||||
#define SHOW_UPDATES 0x8
|
||||
|
||||
#ifdef CONFIG_PANEL_SELF_REFRESH
|
||||
extern struct panel_icm_info *panel_icm;
|
||||
extern wait_queue_head_t panel_update_wait_queue;
|
||||
#endif
|
||||
|
||||
#define DLOG(mask, fmt, args...) \
|
||||
do { \
|
||||
if ((msmfb_debug_mask | SUSPEND_RESUME) & mask) \
|
||||
@ -72,6 +83,7 @@ module_param_named(msmfb_debug_mask, msmfb_debug_mask, int,
|
||||
S_IRUGO | S_IWUSR | S_IWGRP);
|
||||
|
||||
struct mdp_device *mdp;
|
||||
static atomic_t mdpclk_on = ATOMIC_INIT(1);
|
||||
|
||||
struct msmfb_info {
|
||||
struct fb_info *fb;
|
||||
@ -91,9 +103,13 @@ struct msmfb_info {
|
||||
int ebottom; /* exclusive */
|
||||
} update_info;
|
||||
char *black;
|
||||
|
||||
#ifdef CONFIG_HTC_ONMODE_CHARGING
|
||||
struct early_suspend onchg_earlier_suspend;
|
||||
struct early_suspend onchg_suspend;
|
||||
#endif
|
||||
struct early_suspend earlier_suspend;
|
||||
struct early_suspend early_suspend;
|
||||
|
||||
struct wake_lock idle_lock;
|
||||
spinlock_t update_lock;
|
||||
struct mutex panel_init_lock;
|
||||
@ -166,7 +182,7 @@ static int msmfb_release(struct fb_info *info, int user)
|
||||
/* Called from dma interrupt handler, must not sleep */
|
||||
static void msmfb_handle_dma_interrupt(struct msmfb_callback *callback)
|
||||
{
|
||||
unsigned long irq_flags;
|
||||
unsigned long irq_flags=0;
|
||||
struct msmfb_info *msmfb = container_of(callback, struct msmfb_info,
|
||||
dma_callback);
|
||||
#if PRINT_FPS
|
||||
@ -178,6 +194,7 @@ static void msmfb_handle_dma_interrupt(struct msmfb_callback *callback)
|
||||
|
||||
spin_lock_irqsave(&msmfb->update_lock, irq_flags);
|
||||
msmfb->frame_done = msmfb->frame_requested;
|
||||
|
||||
if (msmfb->sleeping == UPDATING &&
|
||||
msmfb->frame_done == msmfb->update_frame) {
|
||||
DLOG(SUSPEND_RESUME, "full update completed\n");
|
||||
@ -203,7 +220,7 @@ static int msmfb_start_dma(struct msmfb_info *msmfb)
|
||||
{
|
||||
uint32_t x, y, w, h;
|
||||
unsigned addr;
|
||||
unsigned long irq_flags;
|
||||
unsigned long irq_flags=0;
|
||||
uint32_t yoffset;
|
||||
s64 time_since_request;
|
||||
struct msm_panel_data *panel = msmfb->panel;
|
||||
@ -230,11 +247,13 @@ static int msmfb_start_dma(struct msmfb_info *msmfb)
|
||||
y = msmfb->update_info.top;
|
||||
w = msmfb->update_info.eright - x;
|
||||
h = msmfb->update_info.ebottom - y;
|
||||
|
||||
#if 0 /* zeusk: */
|
||||
;;;;;;ASD
|
||||
#if defined(CONFIG_FRAMEBUFFER_CONSOLE)
|
||||
x = 0; y = 0; w = msmfb->xres; h = msmfb->yres;
|
||||
#endif
|
||||
|
||||
ASD;;;;;;
|
||||
#endif
|
||||
yoffset = msmfb->yoffset;
|
||||
msmfb->update_info.left = msmfb->xres + 1;
|
||||
msmfb->update_info.top = msmfb->yres + 1;
|
||||
@ -287,7 +306,10 @@ static void msmfb_pan_update(struct fb_info *info, uint32_t left, uint32_t top,
|
||||
{
|
||||
struct msmfb_info *msmfb = info->par;
|
||||
struct msm_panel_data *panel = msmfb->panel;
|
||||
unsigned long irq_flags;
|
||||
#ifdef CONFIG_PANEL_SELF_REFRESH
|
||||
struct mdp_lcdc_info *lcdc = panel_to_lcdc(panel);
|
||||
#endif
|
||||
unsigned long irq_flags=0;
|
||||
int sleeping;
|
||||
int retry = 1;
|
||||
#if PRINT_FPS
|
||||
@ -300,16 +322,21 @@ static void msmfb_pan_update(struct fb_info *info, uint32_t left, uint32_t top,
|
||||
DLOG(SHOW_UPDATES, "update %d %d %d %d %d %d\n",
|
||||
left, top, eright, ebottom, yoffset, pan_display);
|
||||
|
||||
#if !defined(CONFIG_MACH_HTCLEO)
|
||||
// For some reason we need to remove it here, state is 1, we have to look later to this problem
|
||||
if (msmfb->sleeping != AWAKE)
|
||||
DLOG(SUSPEND_RESUME, "pan_update in state(%d)\n", msmfb->sleeping);
|
||||
#ifdef CONFIG_PANEL_SELF_REFRESH
|
||||
if (lcdc->mdp->mdp_dev.overrides & MSM_MDP_RGB_PANEL_SELE_REFRESH) {
|
||||
spin_lock_irqsave(&panel_icm->lock, irq_flags);
|
||||
panel_icm->panel_update = 1;
|
||||
spin_unlock_irqrestore(&panel_icm->lock, irq_flags);
|
||||
wake_up(&panel_update_wait_queue);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if (defined(CONFIG_USB_FUNCTION_PROJECTOR) || defined(CONFIG_USB_ANDROID_PROJECTOR))
|
||||
/* Jay, 8/1/09' */
|
||||
msmfb_set_var(msmfb->fb->screen_base, yoffset);
|
||||
#endif
|
||||
if (msmfb->sleeping != AWAKE)
|
||||
DLOG(SUSPEND_RESUME, "pan_update in state(%d)\n", msmfb->sleeping);
|
||||
|
||||
restart:
|
||||
spin_lock_irqsave(&msmfb->update_lock, irq_flags);
|
||||
@ -401,19 +428,35 @@ restart:
|
||||
msmfb->yoffset);
|
||||
spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
|
||||
|
||||
/* if the panel is all the way on wait for vsync, otherwise sleep
|
||||
* for 16 ms (long enough for the dma to panel) and then begin dma */
|
||||
msmfb->vsync_request_time = ktime_get();
|
||||
if (panel->request_vsync && (sleeping == AWAKE)) {
|
||||
wake_lock_timeout(&msmfb->idle_lock, HZ/4);
|
||||
panel->request_vsync(panel, &msmfb->vsync_callback);
|
||||
} else {
|
||||
if (!hrtimer_active(&msmfb->fake_vsync)) {
|
||||
hrtimer_start(&msmfb->fake_vsync,
|
||||
ktime_set(0, NSEC_PER_SEC/60),
|
||||
HRTIMER_MODE_REL);
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_MSM_HDMI
|
||||
if (!hdmi_usePanelSync())
|
||||
{
|
||||
msmfb->vsync_request_time = ktime_get();
|
||||
msmfb_start_dma(msmfb);
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
/* if the panel is all the way on wait for vsync, otherwise sleep
|
||||
* for 16 ms (long enough for the dma to panel) and then begin dma */
|
||||
msmfb->vsync_request_time = ktime_get();
|
||||
if (panel->request_vsync && (sleeping == AWAKE)) {
|
||||
wake_lock_timeout(&msmfb->idle_lock, HZ/4);
|
||||
panel->request_vsync(panel, &msmfb->vsync_callback);
|
||||
} else {
|
||||
if (!hrtimer_active(&msmfb->fake_vsync)) {
|
||||
hrtimer_start(&msmfb->fake_vsync,
|
||||
ktime_set(0, NSEC_PER_SEC/60),
|
||||
HRTIMER_MODE_REL);
|
||||
}
|
||||
}
|
||||
#ifdef CONFIG_MSM_HDMI
|
||||
}
|
||||
|
||||
/* We did the DMA, now blit the data to the other display */
|
||||
hdmi_DoBlit(msmfb->xres * msmfb->yoffset * BYTES_PER_PIXEL(msmfb));
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
static void msmfb_update(struct fb_info *info, uint32_t left, uint32_t top,
|
||||
@ -427,7 +470,7 @@ static void power_on_panel(struct work_struct *work)
|
||||
struct msmfb_info *msmfb =
|
||||
container_of(work, struct msmfb_info, resume_work);
|
||||
struct msm_panel_data *panel = msmfb->panel;
|
||||
unsigned long irq_flags;
|
||||
unsigned long irq_flags=0;
|
||||
mutex_lock(&msmfb->panel_init_lock);
|
||||
DLOG(SUSPEND_RESUME, "turning on panel\n");
|
||||
if (msmfb->sleeping == UPDATING) {
|
||||
@ -447,34 +490,33 @@ error:
|
||||
mutex_unlock(&msmfb->panel_init_lock);
|
||||
}
|
||||
|
||||
static BLOCKING_NOTIFIER_HEAD(display_chain_head);
|
||||
int register_display_notifier(struct notifier_block *nb)
|
||||
{
|
||||
return blocking_notifier_chain_register(&display_chain_head, nb);
|
||||
}
|
||||
static int display_notifier_callback(struct notifier_block *nfb,
|
||||
unsigned long action,
|
||||
void *ignored)
|
||||
{
|
||||
struct msmfb_info *msm_fb = (struct msmfb_info *)ignored;
|
||||
|
||||
static BLOCKING_NOTIFIER_HEAD(display_chain_head);
|
||||
int register_display_notifier(struct notifier_block *nb)
|
||||
{
|
||||
return blocking_notifier_chain_register(&display_chain_head, nb);
|
||||
}
|
||||
static int display_notifier_callback(struct notifier_block *nfb,
|
||||
unsigned long action,
|
||||
void *ignored)
|
||||
{
|
||||
//struct msmfb_info *msm_fb = (struct msmfb_info *)ignored;
|
||||
|
||||
switch (action) {
|
||||
case NOTIFY_MSM_FB:
|
||||
printk(KERN_DEBUG "NOTIFY_MSM_FB\n");
|
||||
msmfb_resume(&msm_fb->early_suspend);
|
||||
break;
|
||||
printk(KERN_DEBUG "NOTIFY_MSM_FB\n");
|
||||
//msmfb_resume(&msm_fb->early_suspend);
|
||||
break;
|
||||
case NOTIFY_POWER:
|
||||
/* nothing to do */
|
||||
break;
|
||||
/* nothing to do */
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "%s: unknown action in 0x%lx\n",
|
||||
__func__, action);
|
||||
return NOTIFY_BAD;
|
||||
printk(KERN_ERR "%s: unknown action in 0x%lx\n",
|
||||
__func__, action);
|
||||
return NOTIFY_BAD;
|
||||
}
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------------- */
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
/* turn off the panel */
|
||||
static void msmfb_earlier_suspend(struct early_suspend *h)
|
||||
@ -482,7 +524,7 @@ static void msmfb_earlier_suspend(struct early_suspend *h)
|
||||
struct msmfb_info *msmfb = container_of(h, struct msmfb_info,
|
||||
earlier_suspend);
|
||||
struct msm_panel_data *panel = msmfb->panel;
|
||||
unsigned long irq_flags;
|
||||
unsigned long irq_flags=0;
|
||||
|
||||
mutex_lock(&msmfb->panel_init_lock);
|
||||
msmfb->sleeping = SLEEPING;
|
||||
@ -513,6 +555,8 @@ static void msmfb_suspend(struct early_suspend *h)
|
||||
overlay_event.event_wait,
|
||||
(overlay_event.waked_up == ~USE_OVERLAY),
|
||||
10*HZ);
|
||||
/*wait until USE_OVERLAY flag is off and set mdpclk_on as off*/
|
||||
atomic_set(&mdpclk_on, 0);
|
||||
pr_info("wait event : %X\n", overlay_event.waked_up);
|
||||
#endif
|
||||
panel->suspend(panel);
|
||||
@ -523,17 +567,81 @@ static void msmfb_suspend(struct early_suspend *h)
|
||||
static void msmfb_resume_handler(struct early_suspend *h)
|
||||
{
|
||||
struct msmfb_info *msmfb = container_of(h, struct msmfb_info,
|
||||
early_suspend);
|
||||
early_suspend);
|
||||
#ifdef CONFIG_HTC_ONMODE_CHARGING
|
||||
if (msmfb->fb_resumed == 1) {
|
||||
DLOG(SUSPEND_RESUME, "fb is resumed by onchg. skip resume\n");
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
queue_work(msmfb->resume_workqueue, &msmfb->msmfb_resume_work);
|
||||
wait_event_interruptible_timeout(msmfb->frame_wq, msmfb->fb_resumed==1,HZ/2);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_HTC_ONMODE_CHARGING
|
||||
static void msmfb_onchg_earlier_suspend(struct early_suspend *h)
|
||||
{
|
||||
struct msmfb_info *msmfb = container_of(h, struct msmfb_info,
|
||||
onchg_earlier_suspend);
|
||||
|
||||
struct msm_panel_data *panel = msmfb->panel;
|
||||
unsigned long irq_flags=0;
|
||||
|
||||
mutex_lock(&msmfb->panel_init_lock);
|
||||
msmfb->sleeping = SLEEPING;
|
||||
wake_up(&msmfb->frame_wq);
|
||||
spin_lock_irqsave(&msmfb->update_lock, irq_flags);
|
||||
spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
|
||||
|
||||
#ifndef CONFIG_MSM_MDP40
|
||||
mdp->dma(mdp, virt_to_phys(msmfb->black), 0,
|
||||
msmfb->fb->var.xres, msmfb->fb->var.yres, 0, 0,
|
||||
NULL, panel->interface_type);
|
||||
mdp->dma_wait(mdp, panel->interface_type);
|
||||
#endif
|
||||
wait_event_timeout(msmfb->frame_wq,
|
||||
msmfb->frame_requested == msmfb->frame_done, HZ/10);
|
||||
|
||||
/* turn off the panel */
|
||||
panel->blank(panel);
|
||||
}
|
||||
|
||||
static void msmfb_onchg_suspend(struct early_suspend *h)
|
||||
{
|
||||
struct msmfb_info *msmfb = container_of(h, struct msmfb_info,
|
||||
onchg_suspend);
|
||||
struct msm_panel_data *panel = msmfb->panel;
|
||||
/* suspend the panel */
|
||||
#ifdef CONFIG_FB_MSM_OVERLAY
|
||||
/*check whether overlay done*/
|
||||
wait_event_interruptible_timeout(
|
||||
overlay_event.event_wait,
|
||||
(overlay_event.waked_up == ~USE_OVERLAY),
|
||||
10*HZ);
|
||||
/*wait until USE_OVERLAY flag is off and set mdpclk_on as off*/
|
||||
atomic_set(&mdpclk_on, 0);
|
||||
pr_info("wait event : %X\n", overlay_event.waked_up);
|
||||
#endif
|
||||
panel->suspend(panel);
|
||||
msmfb->fb_resumed = 0;
|
||||
mutex_unlock(&msmfb->panel_init_lock);
|
||||
}
|
||||
|
||||
static void msmfb_onchg_resume_handler(struct early_suspend *h)
|
||||
{
|
||||
struct msmfb_info *msmfb = container_of(h, struct msmfb_info,
|
||||
onchg_suspend);
|
||||
queue_work(msmfb->resume_workqueue, &msmfb->msmfb_resume_work);
|
||||
wait_event_interruptible_timeout(msmfb->frame_wq, msmfb->fb_resumed == 1, HZ/2);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void msmfb_resume(struct work_struct *work)
|
||||
{
|
||||
struct msmfb_info *msmfb =
|
||||
container_of(work, struct msmfb_info, msmfb_resume_work);
|
||||
struct msm_panel_data *panel = msmfb->panel;
|
||||
unsigned long irq_flags;
|
||||
unsigned long irq_flags=0;
|
||||
|
||||
if (panel->resume(panel)) {
|
||||
printk(KERN_INFO "msmfb: panel resume failed, not resuming "
|
||||
@ -545,15 +653,16 @@ static void msmfb_resume(struct work_struct *work)
|
||||
msmfb->sleeping = WAKING;
|
||||
DLOG(SUSPEND_RESUME, "ready, waiting for full update\n");
|
||||
spin_unlock_irqrestore(&msmfb->update_lock, irq_flags);
|
||||
start_drawing_late_resume(NULL);
|
||||
msmfb->fb_resumed = 1;
|
||||
wake_up(&msmfb->frame_wq);
|
||||
|
||||
atomic_set(&mdpclk_on, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int msmfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
|
||||
{
|
||||
u32 size;
|
||||
uint32_t size;
|
||||
|
||||
if ((var->xres != info->var.xres) ||
|
||||
(var->yres != info->var.yres) ||
|
||||
@ -625,28 +734,22 @@ int msmfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
|
||||
static void msmfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
|
||||
{
|
||||
cfb_fillrect(p, rect);
|
||||
#if !defined(CONFIG_FRAMEBUFFER_CONSOLE)
|
||||
msmfb_update(p, rect->dx, rect->dy, rect->dx + rect->width,
|
||||
rect->dy + rect->height);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void msmfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
|
||||
{
|
||||
cfb_copyarea(p, area);
|
||||
#if !defined(CONFIG_FRAMEBUFFER_CONSOLE)
|
||||
msmfb_update(p, area->dx, area->dy, area->dx + area->width,
|
||||
area->dy + area->height);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void msmfb_imageblit(struct fb_info *p, const struct fb_image *image)
|
||||
{
|
||||
cfb_imageblit(p, image);
|
||||
#if !defined(CONFIG_FRAMEBUFFER_CONSOLE)
|
||||
msmfb_update(p, image->dx, image->dy, image->dx + image->width,
|
||||
image->dy + image->height);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -705,6 +808,7 @@ static int msmfb_overlay_set(struct fb_info *info, void __user *p)
|
||||
if (copy_from_user(&req, p, sizeof(req)))
|
||||
return -EFAULT;
|
||||
|
||||
printk(KERN_INFO "%s(%d) dst rect info w=%d h=%d x=%d y=%d rotator=%d\n", __func__, __LINE__, req.dst_rect.w, req.dst_rect.h, req.dst_rect.x, req.dst_rect.y, req.user_data[0]);
|
||||
ret = mdp->overlay_set(mdp, info, &req);
|
||||
if (ret) {
|
||||
printk(KERN_ERR "%s:ioctl failed \n",
|
||||
@ -764,7 +868,7 @@ DEFINE_MUTEX(mdp_ppp_lock);
|
||||
static int msmfb_ioctl(struct fb_info *p, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
void __user *argp = (void __user *)arg;
|
||||
int ret;
|
||||
int ret = 0;
|
||||
#if PRINT_BLIT_TIME
|
||||
ktime_t t1, t2;
|
||||
#endif
|
||||
@ -788,41 +892,41 @@ static int msmfb_ioctl(struct fb_info *p, unsigned int cmd, unsigned long arg)
|
||||
break;
|
||||
#ifdef CONFIG_FB_MSM_OVERLAY
|
||||
case MSMFB_OVERLAY_GET:
|
||||
printk("CONFIG_FB_MSM_OVERLAY\n");
|
||||
//down(&mdp_ppp_lock);
|
||||
ret = msmfb_overlay_get(p, argp);
|
||||
//up(&mdp_ppp_lock);
|
||||
break;
|
||||
case MSMFB_OVERLAY_SET:
|
||||
printk("MSMFB_OVERLAY_SET\n");
|
||||
//down(&mdp_ppp_lock);
|
||||
ret = msmfb_overlay_set(p, argp);
|
||||
mutex_lock(&overlay_event_lock);
|
||||
overlay_event.waked_up = USE_OVERLAY;
|
||||
mutex_unlock(&overlay_event_lock);
|
||||
//up(&mdp_ppp_lock);
|
||||
if(!atomic_read(&mdpclk_on)) {
|
||||
printk(KERN_ERR "MSMFB_OVERLAY_SET during suspend\n");
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
mutex_lock(&overlay_event_lock);
|
||||
overlay_event.waked_up = USE_OVERLAY;
|
||||
mutex_unlock(&overlay_event_lock);
|
||||
ret = msmfb_overlay_set(p, argp);
|
||||
}
|
||||
printk(KERN_INFO "MSMFB_OVERLAY_SET ret=%d\n", ret);
|
||||
break;
|
||||
case MSMFB_OVERLAY_UNSET:
|
||||
printk("MSMFB_OVERLAY_UNSET\n");
|
||||
//down(&mdp_ppp_lock);
|
||||
ret = msmfb_overlay_unset(p, argp);
|
||||
mutex_lock(&overlay_event_lock);
|
||||
overlay_event.waked_up = ~USE_OVERLAY;
|
||||
wake_up(&overlay_event.event_wait);
|
||||
mutex_unlock(&overlay_event_lock);
|
||||
//up(&mdp_ppp_lock);
|
||||
printk(KERN_INFO "MSMFB_OVERLAY_UNSET ret=%d\n", ret);
|
||||
break;
|
||||
case MSMFB_OVERLAY_PLAY:
|
||||
//down(&mdp_ppp_lock);
|
||||
ret = msmfb_overlay_play(p, argp);
|
||||
//up(&mdp_ppp_lock);
|
||||
if(!atomic_read(&mdpclk_on)) {
|
||||
printk(KERN_ERR "MSMFB_OVERLAY_PLAY during suspend\n");
|
||||
ret = -EINVAL;
|
||||
} else
|
||||
ret = msmfb_overlay_play(p, argp);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printk(KERN_INFO "msmfb unknown ioctl: %d\n", cmd);
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct fb_ops msmfb_ops = {
|
||||
@ -856,7 +960,7 @@ static ssize_t debug_read(struct file *file, char __user *buf, size_t count,
|
||||
static char buffer[4096];
|
||||
int n = 0;
|
||||
struct msmfb_info *msmfb = (struct msmfb_info *)file->private_data;
|
||||
unsigned long irq_flags;
|
||||
unsigned long irq_flags=0;
|
||||
|
||||
spin_lock_irqsave(&msmfb->update_lock, irq_flags);
|
||||
n = scnprintf(buffer, debug_bufmax, "yoffset %d\n", msmfb->yoffset);
|
||||
@ -880,7 +984,7 @@ static struct file_operations debug_fops = {
|
||||
};
|
||||
#endif
|
||||
|
||||
#define BITS_PER_PIXEL 16
|
||||
#define BITS_PER_PIXEL_DEF 32
|
||||
|
||||
static void setup_fb_info(struct msmfb_info *msmfb)
|
||||
{
|
||||
@ -904,8 +1008,9 @@ static void setup_fb_info(struct msmfb_info *msmfb)
|
||||
fb_info->var.height = msmfb->panel->fb_data->height;
|
||||
fb_info->var.xres_virtual = msmfb->xres;
|
||||
fb_info->var.yres_virtual = msmfb->yres * 2;
|
||||
fb_info->var.bits_per_pixel = BITS_PER_PIXEL;
|
||||
fb_info->var.bits_per_pixel = BITS_PER_PIXEL_DEF;
|
||||
fb_info->var.accel_flags = 0;
|
||||
fb_info->var.reserved[4] = 60;
|
||||
|
||||
fb_info->var.yoffset = 0;
|
||||
|
||||
@ -938,6 +1043,7 @@ static void setup_fb_info(struct msmfb_info *msmfb)
|
||||
fb_info->var.blue.msb_right = 0;
|
||||
|
||||
mdp->set_output_format(mdp, fb_info->var.bits_per_pixel);
|
||||
mdp->set_panel_size(mdp, msmfb->xres, msmfb->yres);
|
||||
|
||||
r = fb_alloc_cmap(&fb_info->cmap, 16, 0);
|
||||
fb_info->pseudo_palette = PP;
|
||||
@ -1027,7 +1133,7 @@ static int msmfb_probe(struct platform_device *pdev)
|
||||
spin_lock_init(&msmfb->update_lock);
|
||||
mutex_init(&msmfb->panel_init_lock);
|
||||
init_waitqueue_head(&msmfb->frame_wq);
|
||||
msmfb->resume_workqueue = create_rt_workqueue("panel_on");
|
||||
msmfb->resume_workqueue = create_workqueue("panel_on");
|
||||
if (msmfb->resume_workqueue == NULL) {
|
||||
printk(KERN_ERR "failed to create panel_on workqueue\n");
|
||||
ret = -ENOMEM;
|
||||
@ -1049,6 +1155,16 @@ static int msmfb_probe(struct platform_device *pdev)
|
||||
msmfb->earlier_suspend.suspend = msmfb_earlier_suspend;
|
||||
msmfb->earlier_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
|
||||
register_early_suspend(&msmfb->earlier_suspend);
|
||||
#ifdef CONFIG_HTC_ONMODE_CHARGING
|
||||
msmfb->onchg_suspend.suspend = msmfb_onchg_suspend;
|
||||
msmfb->onchg_suspend.resume = msmfb_onchg_resume_handler;
|
||||
msmfb->onchg_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
|
||||
register_onchg_suspend(&msmfb->onchg_suspend);
|
||||
|
||||
msmfb->onchg_earlier_suspend.suspend = msmfb_onchg_earlier_suspend;
|
||||
msmfb->onchg_earlier_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN;
|
||||
register_onchg_suspend(&msmfb->onchg_earlier_suspend);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if MSMFB_DEBUG
|
||||
@ -1082,10 +1198,10 @@ static int msmfb_probe(struct platform_device *pdev)
|
||||
#ifdef CONFIG_FB_MSM_LOGO
|
||||
if (!load_565rle_image(INIT_IMAGE_FILE)) {
|
||||
/* Flip buffer */
|
||||
msmfb->update_info.left = 0;
|
||||
msmfb->update_info.left = 0;
|
||||
msmfb->update_info.top = 0;
|
||||
msmfb->update_info.eright = msmfb->xres;
|
||||
msmfb->update_info.ebottom = msmfb->yres;
|
||||
msmfb->update_info.ebottom = msmfb->yres;
|
||||
msmfb_pan_update(msmfb->fb, 0, 0, msmfb->xres,
|
||||
msmfb->yres, 0, 1);
|
||||
}
|
||||
|
@ -3,13 +3,31 @@
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/i2c.h>
|
||||
|
||||
struct dentry;
|
||||
|
||||
/* Definitions of frame buffers */
|
||||
|
||||
#define FB_MAX 32 /* sufficient for now */
|
||||
|
||||
struct fbcon_decor_iowrapper
|
||||
{
|
||||
unsigned short vc; /* Virtual console */
|
||||
unsigned char origin; /* Point of origin of the request */
|
||||
void *data;
|
||||
};
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#ifdef CONFIG_COMPAT
|
||||
#include <linux/compat.h>
|
||||
struct fbcon_decor_iowrapper32
|
||||
{
|
||||
unsigned short vc; /* Virtual console */
|
||||
unsigned char origin; /* Point of origin of the request */
|
||||
compat_uptr_t data;
|
||||
};
|
||||
#endif /* CONFIG_COMPAT */
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
/* ioctls
|
||||
0x46 is 'F' */
|
||||
#define FBIOGET_VSCREENINFO 0x4600
|
||||
@ -37,7 +55,24 @@ struct dentry;
|
||||
#define FBIOGET_HWCINFO 0x4616
|
||||
#define FBIOPUT_MODEINFO 0x4617
|
||||
#define FBIOGET_DISPINFO 0x4618
|
||||
#define FBIOCONDECOR_SETCFG _IOWR('F', 0x19, struct fbcon_decor_iowrapper)
|
||||
#define FBIOCONDECOR_GETCFG _IOR('F', 0x1A, struct fbcon_decor_iowrapper)
|
||||
#define FBIOCONDECOR_SETSTATE _IOWR('F', 0x1B, struct fbcon_decor_iowrapper)
|
||||
#define FBIOCONDECOR_GETSTATE _IOR('F', 0x1C, struct fbcon_decor_iowrapper)
|
||||
#define FBIOCONDECOR_SETPIC _IOWR('F', 0x1D, struct fbcon_decor_iowrapper)
|
||||
#ifdef __KERNEL__
|
||||
#ifdef CONFIG_COMPAT
|
||||
#define FBIOCONDECOR_SETCFG32 _IOWR('F', 0x19, struct fbcon_decor_iowrapper32)
|
||||
#define FBIOCONDECOR_GETCFG32 _IOR('F', 0x1A, struct fbcon_decor_iowrapper32)
|
||||
#define FBIOCONDECOR_SETSTATE32 _IOWR('F', 0x1B, struct fbcon_decor_iowrapper32)
|
||||
#define FBIOCONDECOR_GETSTATE32 _IOR('F', 0x1C, struct fbcon_decor_iowrapper32)
|
||||
#define FBIOCONDECOR_SETPIC32 _IOWR('F', 0x1D, struct fbcon_decor_iowrapper32)
|
||||
#endif /* CONFIG_COMPAT */
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#define FBCON_DECOR_THEME_LEN 128 /* Maximum lenght of a theme name */
|
||||
#define FBCON_DECOR_IO_ORIG_KERNEL 0 /* Kernel ioctl origin */
|
||||
#define FBCON_DECOR_IO_ORIG_USER 1 /* User ioctl origin */
|
||||
|
||||
#define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */
|
||||
#define FB_TYPE_PLANES 1 /* Non interleaved planes */
|
||||
@ -282,6 +317,28 @@ struct fb_cmap {
|
||||
__u16 *transp; /* transparency, can be NULL */
|
||||
};
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#ifdef CONFIG_COMPAT
|
||||
struct fb_cmap32 {
|
||||
__u32 start;
|
||||
__u32 len; /* Number of entries */
|
||||
compat_uptr_t red; /* Red values */
|
||||
compat_uptr_t green;
|
||||
compat_uptr_t blue;
|
||||
compat_uptr_t transp; /* transparency, can be NULL */
|
||||
};
|
||||
|
||||
#define fb_cmap_from_compat(to, from) \
|
||||
(to).start = (from).start; \
|
||||
(to).len = (from).len; \
|
||||
(to).red = compat_ptr((from).red); \
|
||||
(to).green = compat_ptr((from).green); \
|
||||
(to).blue = compat_ptr((from).blue); \
|
||||
(to).transp = compat_ptr((from).transp)
|
||||
|
||||
#endif /* CONFIG_COMPAT */
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
struct fb_con2fbmap {
|
||||
__u32 console;
|
||||
__u32 framebuffer;
|
||||
@ -363,6 +420,34 @@ struct fb_image {
|
||||
struct fb_cmap cmap; /* color map info */
|
||||
};
|
||||
|
||||
#ifdef __KERNEL__
|
||||
#ifdef CONFIG_COMPAT
|
||||
struct fb_image32 {
|
||||
__u32 dx; /* Where to place image */
|
||||
__u32 dy;
|
||||
__u32 width; /* Size of image */
|
||||
__u32 height;
|
||||
__u32 fg_color; /* Only used when a mono bitmap */
|
||||
__u32 bg_color;
|
||||
__u8 depth; /* Depth of the image */
|
||||
const compat_uptr_t data; /* Pointer to image data */
|
||||
struct fb_cmap32 cmap; /* color map info */
|
||||
};
|
||||
|
||||
#define fb_image_from_compat(to, from) \
|
||||
(to).dx = (from).dx; \
|
||||
(to).dy = (from).dy; \
|
||||
(to).width = (from).width; \
|
||||
(to).height = (from).height; \
|
||||
(to).fg_color = (from).fg_color; \
|
||||
(to).bg_color = (from).bg_color; \
|
||||
(to).depth = (from).depth; \
|
||||
(to).data = compat_ptr((from).data); \
|
||||
fb_cmap_from_compat((to).cmap, (from).cmap)
|
||||
|
||||
#endif /* CONFIG_COMPAT */
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
/*
|
||||
* hardware cursor control
|
||||
*/
|
||||
@ -403,6 +488,7 @@ struct fb_cursor {
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/backlight.h>
|
||||
#include <linux/slab.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
struct vm_area_struct;
|
||||
@ -543,6 +629,8 @@ struct fb_cursor_user {
|
||||
#define FB_EVENT_GET_REQ 0x0D
|
||||
/* Unbind from the console if possible */
|
||||
#define FB_EVENT_FB_UNBIND 0x0E
|
||||
/* CONSOLE-SPECIFIC: remap all consoles to new fb - for vga switcheroo */
|
||||
#define FB_EVENT_REMAP_ALL_CONSOLE 0x0F
|
||||
|
||||
struct fb_event {
|
||||
struct fb_info *info;
|
||||
@ -606,6 +694,12 @@ struct fb_deferred_io {
|
||||
* LOCKING NOTE: those functions must _ALL_ be called with the console
|
||||
* semaphore held, this is the only suitable locking mechanism we have
|
||||
* in 2.6. Some may be called at interrupt time at this point though.
|
||||
*
|
||||
* The exception to this is the debug related hooks. Putting the fb
|
||||
* into a debug state (e.g. flipping to the kernel console) and restoring
|
||||
* it must be done in a lock-free manner, so low level drivers should
|
||||
* keep track of the initial console (if applicable) and may need to
|
||||
* perform direct, unlocked hardware writes in these hooks.
|
||||
*/
|
||||
|
||||
struct fb_ops {
|
||||
@ -675,6 +769,10 @@ struct fb_ops {
|
||||
|
||||
/* teardown any resources to do with this framebuffer */
|
||||
void (*fb_destroy)(struct fb_info *info);
|
||||
|
||||
/* called at KDB enter and leave time to prepare the console */
|
||||
int (*fb_debug_enter)(struct fb_info *info);
|
||||
int (*fb_debug_leave)(struct fb_info *info);
|
||||
};
|
||||
|
||||
#ifdef CONFIG_FB_TILEBLITTING
|
||||
@ -763,6 +861,7 @@ struct fb_tile_ops {
|
||||
* takes over; acceleration engine should be in a quiescent state */
|
||||
|
||||
/* hints */
|
||||
#define FBINFO_VIRTFB 0x0004 /* FB is System RAM, not device. */
|
||||
#define FBINFO_PARTIAL_PAN_OK 0x0040 /* otw use pan only for double-buffering */
|
||||
#define FBINFO_READS_FAST 0x0080 /* soft-copy faster than rendering */
|
||||
|
||||
@ -784,8 +883,6 @@ struct fb_tile_ops {
|
||||
#define FBINFO_MISC_USEREVENT 0x10000 /* event request
|
||||
from userspace */
|
||||
#define FBINFO_MISC_TILEBLITTING 0x20000 /* use tile blitting */
|
||||
#define FBINFO_MISC_FIRMWARE 0x40000 /* a replaceable firmware
|
||||
inited framebuffer */
|
||||
|
||||
/* A driver may set this flag to indicate that it does want a set_par to be
|
||||
* called every time when fbcon_switch is executed. The advantage is that with
|
||||
@ -799,6 +896,8 @@ struct fb_tile_ops {
|
||||
*/
|
||||
#define FBINFO_MISC_ALWAYS_SETPAR 0x40000
|
||||
|
||||
/* where the fb is a firmware driver, and can be replaced with a proper one */
|
||||
#define FBINFO_MISC_FIRMWARE 0x80000
|
||||
/*
|
||||
* Host and GPU endianness differ.
|
||||
*/
|
||||
@ -810,6 +909,10 @@ struct fb_tile_ops {
|
||||
*/
|
||||
#define FBINFO_BE_MATH 0x100000
|
||||
|
||||
/* report to the VT layer that this fb driver can accept forced console
|
||||
output like oopses */
|
||||
#define FBINFO_CAN_FORCE_OUTPUT 0x200000
|
||||
|
||||
struct fb_info {
|
||||
int node;
|
||||
int flags;
|
||||
@ -854,15 +957,32 @@ struct fb_info {
|
||||
#define FBINFO_STATE_SUSPENDED 1
|
||||
u32 state; /* Hardware state i.e suspend */
|
||||
void *fbcon_par; /* fbcon use-only private area */
|
||||
|
||||
struct fb_image bgdecor;
|
||||
|
||||
/* From here on everything is device dependent */
|
||||
void *par;
|
||||
/* we need the PCI or similiar aperture base/size not
|
||||
smem_start/size as smem_start may just be an object
|
||||
allocated inside the aperture so may not actually overlap */
|
||||
resource_size_t aperture_base;
|
||||
resource_size_t aperture_size;
|
||||
struct apertures_struct {
|
||||
unsigned int count;
|
||||
struct aperture {
|
||||
resource_size_t base;
|
||||
resource_size_t size;
|
||||
} ranges[0];
|
||||
} *apertures;
|
||||
};
|
||||
|
||||
static inline struct apertures_struct *alloc_apertures(unsigned int max_num) {
|
||||
struct apertures_struct *a = kzalloc(sizeof(struct apertures_struct)
|
||||
+ max_num * sizeof(struct aperture), GFP_KERNEL);
|
||||
if (!a)
|
||||
return NULL;
|
||||
a->count = max_num;
|
||||
return a;
|
||||
}
|
||||
|
||||
#ifdef MODULE
|
||||
#define FBINFO_DEFAULT FBINFO_MODULE
|
||||
#else
|
||||
@ -898,6 +1018,8 @@ struct fb_info {
|
||||
#define fb_writel sbus_writel
|
||||
#define fb_writeq sbus_writeq
|
||||
#define fb_memset sbus_memset_io
|
||||
#define fb_memcpy_fromfb sbus_memcpy_fromio
|
||||
#define fb_memcpy_tofb sbus_memcpy_toio
|
||||
|
||||
#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || defined(__sh__) || defined(__powerpc__) || defined(__avr32__) || defined(__bfin__)
|
||||
|
||||
@ -910,6 +1032,8 @@ struct fb_info {
|
||||
#define fb_writel __raw_writel
|
||||
#define fb_writeq __raw_writeq
|
||||
#define fb_memset memset_io
|
||||
#define fb_memcpy_fromfb memcpy_fromio
|
||||
#define fb_memcpy_tofb memcpy_toio
|
||||
|
||||
#else
|
||||
|
||||
@ -922,6 +1046,8 @@ struct fb_info {
|
||||
#define fb_writel(b,addr) (*(volatile u32 *) (addr) = (b))
|
||||
#define fb_writeq(b,addr) (*(volatile u64 *) (addr) = (b))
|
||||
#define fb_memset memset
|
||||
#define fb_memcpy_fromfb memcpy
|
||||
#define fb_memcpy_tofb memcpy
|
||||
|
||||
#endif
|
||||
|
||||
@ -955,6 +1081,8 @@ extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
|
||||
/* drivers/video/fbmem.c */
|
||||
extern int register_framebuffer(struct fb_info *fb_info);
|
||||
extern int unregister_framebuffer(struct fb_info *fb_info);
|
||||
extern void remove_conflicting_framebuffers(struct apertures_struct *a,
|
||||
const char *name, bool primary);
|
||||
extern int fb_prepare_logo(struct fb_info *fb_info, int rotate);
|
||||
extern int fb_show_logo(struct fb_info *fb_info, int rotate);
|
||||
extern char* fb_get_buffer_offset(struct fb_info *info, struct fb_pixmap *buf, u32 size);
|
||||
@ -1052,6 +1180,8 @@ extern int fb_parse_edid(unsigned char *edid, struct fb_var_screeninfo *var);
|
||||
extern const unsigned char *fb_firmware_edid(struct device *device);
|
||||
extern void fb_edid_to_monspecs(unsigned char *edid,
|
||||
struct fb_monspecs *specs);
|
||||
extern void fb_edid_add_monspecs(unsigned char *edid,
|
||||
struct fb_monspecs *specs);
|
||||
extern void fb_destroy_modedb(struct fb_videomode *modedb);
|
||||
extern int fb_find_mode_cvt(struct fb_videomode *mode, int margins, int rb);
|
||||
extern unsigned char *fb_ddc_read(struct i2c_adapter *adapter);
|
||||
@ -1082,6 +1212,7 @@ extern const struct fb_videomode *fb_find_best_display(const struct fb_monspecs
|
||||
|
||||
/* drivers/video/fbcmap.c */
|
||||
extern int fb_alloc_cmap(struct fb_cmap *cmap, int len, int transp);
|
||||
extern int fb_alloc_cmap_gfp(struct fb_cmap *cmap, int len, int transp, gfp_t flags);
|
||||
extern void fb_dealloc_cmap(struct fb_cmap *cmap);
|
||||
extern int fb_copy_cmap(const struct fb_cmap *from, struct fb_cmap *to);
|
||||
extern int fb_cmap_to_user(const struct fb_cmap *from, struct fb_cmap_user *to);
|
||||
|
209
include/linux/msm_audio_1550.h
Normal file
209
include/linux/msm_audio_1550.h
Normal file
@ -0,0 +1,209 @@
|
||||
/* include/linux/msm_audio.h
|
||||
*
|
||||
* Copyright (C) 2008 Google, Inc.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_MSM_AUDIO_H
|
||||
#define __LINUX_MSM_AUDIO_H
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <linux/ioctl.h>
|
||||
#include <asm/sizes.h>
|
||||
|
||||
/* PCM Audio */
|
||||
|
||||
#define AUDIO_IOCTL_MAGIC 'a'
|
||||
|
||||
#define AUDIO_ENABLE_AUDPRE _IOW(AUDIO_IOCTL_MAGIC, 11, unsigned)
|
||||
#define AUDIO_SET_AGC _IOW(AUDIO_IOCTL_MAGIC, 12, unsigned)
|
||||
#define AUDIO_SET_NS _IOW(AUDIO_IOCTL_MAGIC, 13, unsigned)
|
||||
#define AUDIO_SET_TX_IIR _IOW(AUDIO_IOCTL_MAGIC, 14, unsigned)
|
||||
#define AUDIO_PLAY_DTMF _IOW(AUDIO_IOCTL_MAGIC, 19, unsigned)
|
||||
|
||||
#define AUDIO_START _IOW(AUDIO_IOCTL_MAGIC, 0, unsigned)
|
||||
#define AUDIO_STOP _IOW(AUDIO_IOCTL_MAGIC, 1, unsigned)
|
||||
#define AUDIO_FLUSH _IOW(AUDIO_IOCTL_MAGIC, 2, unsigned)
|
||||
#define AUDIO_GET_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 3, unsigned)
|
||||
#define AUDIO_SET_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 4, unsigned)
|
||||
#define AUDIO_GET_STATS _IOR(AUDIO_IOCTL_MAGIC, 5, unsigned)
|
||||
#define AUDIO_ENABLE_AUDPP _IOW(AUDIO_IOCTL_MAGIC, 6, unsigned)
|
||||
#define AUDIO_SET_ADRC _IOW(AUDIO_IOCTL_MAGIC, 7, unsigned)
|
||||
#define AUDIO_SET_EQ _IOW(AUDIO_IOCTL_MAGIC, 8, unsigned)
|
||||
#define AUDIO_SET_RX_IIR _IOW(AUDIO_IOCTL_MAGIC, 9, unsigned)
|
||||
#define AUDIO_SET_VOLUME _IOW(AUDIO_IOCTL_MAGIC, 10, unsigned)
|
||||
#define AUDIO_PAUSE _IOW(AUDIO_IOCTL_MAGIC, 11, unsigned)
|
||||
#define AUDIO_GET_EVENT _IOR(AUDIO_IOCTL_MAGIC, 13, unsigned)
|
||||
#define AUDIO_ABORT_GET_EVENT _IOW(AUDIO_IOCTL_MAGIC, 14, unsigned)
|
||||
#define AUDIO_REGISTER_PMEM _IOW(AUDIO_IOCTL_MAGIC, 15, unsigned)
|
||||
#define AUDIO_DEREGISTER_PMEM _IOW(AUDIO_IOCTL_MAGIC, 16, unsigned)
|
||||
#define AUDIO_WAIT_ADSP_DONE _IOR(AUDIO_IOCTL_MAGIC, 16, unsigned)
|
||||
#define AUDIO_ADSP_PAUSE _IOR(AUDIO_IOCTL_MAGIC, 17, unsigned)
|
||||
#define AUDIO_ASYNC_WRITE _IOW(AUDIO_IOCTL_MAGIC, 17, unsigned)
|
||||
#define AUDIO_ADSP_RESUME _IOR(AUDIO_IOCTL_MAGIC, 18, unsigned)
|
||||
#define AUDIO_ASYNC_READ _IOW(AUDIO_IOCTL_MAGIC, 18, unsigned)
|
||||
#define AUDIO_SET_INCALL _IOW(AUDIO_IOCTL_MAGIC, 19, \
|
||||
struct msm_voicerec_mode)
|
||||
#define AUDIO_GET_NUM_SND_DEVICE _IOR(AUDIO_IOCTL_MAGIC, 20, unsigned)
|
||||
#define AUDIO_GET_AMRNB_ENC_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 21, unsigned)
|
||||
#define AUDIO_GET_SND_DEVICES _IOWR(AUDIO_IOCTL_MAGIC, 21, \
|
||||
struct msm_snd_device_list)
|
||||
#define AUDIO_SET_AMRNB_ENC_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 22, unsigned)
|
||||
#define AUDIO_ENABLE_SND_DEVICE _IOW(AUDIO_IOCTL_MAGIC, 22, unsigned)
|
||||
#define AUDIO_DISABLE_SND_DEVICE _IOW(AUDIO_IOCTL_MAGIC, 23, unsigned)
|
||||
#define AUDIO_ROUTE_STREAM _IOW(AUDIO_IOCTL_MAGIC, 24, \
|
||||
struct msm_audio_route_config)
|
||||
#define AUDIO_GET_PCM_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 30, unsigned)
|
||||
#define AUDIO_SET_PCM_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 31, unsigned)
|
||||
#define AUDIO_SWITCH_DEVICE _IOW(AUDIO_IOCTL_MAGIC, 32, unsigned)
|
||||
#define AUDIO_SET_MUTE _IOW(AUDIO_IOCTL_MAGIC, 33, unsigned)
|
||||
#define AUDIO_UPDATE_ACDB _IOW(AUDIO_IOCTL_MAGIC, 34, unsigned)
|
||||
#define AUDIO_START_VOICE _IOW(AUDIO_IOCTL_MAGIC, 35, unsigned)
|
||||
#define AUDIO_STOP_VOICE _IOW(AUDIO_IOCTL_MAGIC, 36, unsigned)
|
||||
#define AUDIO_START_FM _IOW(AUDIO_IOCTL_MAGIC, 37, unsigned)
|
||||
#define AUDIO_STOP_FM _IOW(AUDIO_IOCTL_MAGIC, 38, unsigned)
|
||||
#define AUDIO_REINIT_ACDB _IOW(AUDIO_IOCTL_MAGIC, 39, unsigned)
|
||||
#define AUDIO_ENABLE_AUXPGA_LOOPBACK _IOW(AUDIO_IOCTL_MAGIC, 40, unsigned)
|
||||
#define AUDIO_OUTPORT_FLUSH _IOW(AUDIO_IOCTL_MAGIC, 40, \
|
||||
unsigned short)
|
||||
#define AUDIO_SET_AUXPGA_GAIN _IOW(AUDIO_IOCTL_MAGIC, 41, unsigned)
|
||||
#define AUDIO_SET_ERR_THRESHOLD_VALUE _IOW(AUDIO_IOCTL_MAGIC, 41, \
|
||||
unsigned short)
|
||||
#define AUDIO_SET_RX_MUTE _IOW(AUDIO_IOCTL_MAGIC, 42, unsigned)
|
||||
#define AUDIO_GET_BITSTREAM_ERROR_INFO _IOR(AUDIO_IOCTL_MAGIC, 42, \
|
||||
struct msm_audio_bitstream_error_info)
|
||||
|
||||
/* Qualcomm extensions */
|
||||
#define AUDIO_SET_STREAM_CONFIG _IOW(AUDIO_IOCTL_MAGIC, 80, \
|
||||
struct msm_audio_stream_config)
|
||||
#define AUDIO_GET_STREAM_CONFIG _IOR(AUDIO_IOCTL_MAGIC, 81, \
|
||||
struct msm_audio_stream_config)
|
||||
#define AUDIO_GET_SESSION_ID _IOR(AUDIO_IOCTL_MAGIC, 82, \
|
||||
unsigned short)
|
||||
#define AUDIO_GET_STREAM_INFO _IOR(AUDIO_IOCTL_MAGIC, 83, \
|
||||
struct msm_audio_bitstream_info)
|
||||
#define AUDIO_SET_PAN _IOW(AUDIO_IOCTL_MAGIC, 84, unsigned)
|
||||
#define AUDIO_SET_QCONCERT_PLUS _IOW(AUDIO_IOCTL_MAGIC, 85, unsigned)
|
||||
#define AUDIO_SET_MBADRC _IOW(AUDIO_IOCTL_MAGIC, 86, unsigned)
|
||||
#define AUDIO_SET_VOLUME_PATH _IOW(AUDIO_IOCTL_MAGIC, 87, \
|
||||
struct msm_vol_info)
|
||||
#define AUDIO_SET_MAX_VOL_ALL _IOW(AUDIO_IOCTL_MAGIC, 88, unsigned)
|
||||
#define AUDIO_GET_BUF_CFG _IOW(AUDIO_IOCTL_MAGIC, 93, \
|
||||
struct msm_audio_buf_cfg)
|
||||
#define AUDIO_SET_BUF_CFG _IOW(AUDIO_IOCTL_MAGIC, 94, \
|
||||
struct msm_audio_buf_cfg)
|
||||
#define AUDIO_SET_ACDB_BLK _IOW(AUDIO_IOCTL_MAGIC, 95, \
|
||||
struct msm_acdb_cmd_device)
|
||||
#define AUDIO_GET_ACDB_BLK _IOW(AUDIO_IOCTL_MAGIC, 96, \
|
||||
struct msm_acdb_cmd_device)
|
||||
|
||||
#define AUDIO_MAX_COMMON_IOCTL_NUM 100
|
||||
|
||||
struct msm_audio_config {
|
||||
uint32_t buffer_size;
|
||||
uint32_t buffer_count;
|
||||
uint32_t channel_count;
|
||||
uint32_t sample_rate;
|
||||
uint32_t type;
|
||||
uint32_t unused[3];
|
||||
};
|
||||
|
||||
struct msm_audio_stats {
|
||||
uint32_t byte_count;
|
||||
uint32_t sample_count;
|
||||
uint32_t unused[2];
|
||||
};
|
||||
|
||||
struct msm_mute_info {
|
||||
uint32_t mute;
|
||||
uint32_t path;
|
||||
};
|
||||
|
||||
#define AAC_OBJECT_ER_LC 17
|
||||
#define AAC_OBJECT_ER_LTP 19
|
||||
#define AAC_OBJECT_ER_SCALABLE 20
|
||||
#define AAC_OBJECT_BSAC 22
|
||||
#define AAC_OBJECT_ER_LD 23
|
||||
|
||||
struct aac_format {
|
||||
uint16_t sample_rate;
|
||||
uint16_t channel_config;
|
||||
uint16_t block_formats;
|
||||
uint16_t audio_object_type;
|
||||
uint16_t ep_config;
|
||||
uint16_t aac_section_data_resilience_flag;
|
||||
uint16_t aac_scalefactor_data_resilience_flag;
|
||||
uint16_t aac_spectral_data_resilience_flag;
|
||||
uint16_t sbr_on_flag;
|
||||
uint16_t sbr_ps_on_flag;
|
||||
uint32_t bit_rate;
|
||||
};
|
||||
|
||||
struct msm_audio_stream_config {
|
||||
uint32_t buffer_size;
|
||||
uint32_t buffer_count;
|
||||
};
|
||||
|
||||
/* Audio routing */
|
||||
|
||||
#define SND_IOCTL_MAGIC 's'
|
||||
|
||||
#define SND_MUTE_UNMUTED 0
|
||||
#define SND_MUTE_MUTED 1
|
||||
|
||||
struct msm_voicerec_mode {
|
||||
uint32_t rec_mode;
|
||||
};
|
||||
|
||||
struct msm_snd_device_config {
|
||||
uint32_t device;
|
||||
uint32_t ear_mute;
|
||||
uint32_t mic_mute;
|
||||
};
|
||||
|
||||
#define SND_SET_DEVICE _IOW(SND_IOCTL_MAGIC, 2, struct msm_device_config *)
|
||||
|
||||
#define SND_METHOD_VOICE 0
|
||||
|
||||
struct msm_snd_volume_config {
|
||||
uint32_t device;
|
||||
uint32_t method;
|
||||
uint32_t volume;
|
||||
};
|
||||
|
||||
#define SND_SET_VOLUME _IOW(SND_IOCTL_MAGIC, 3, struct msm_snd_volume_config *)
|
||||
|
||||
/* Returns the number of SND endpoints supported. */
|
||||
|
||||
#define SND_GET_NUM_ENDPOINTS _IOR(SND_IOCTL_MAGIC, 4, unsigned *)
|
||||
|
||||
struct msm_snd_endpoint {
|
||||
int id; /* input and output */
|
||||
char name[64]; /* output only */
|
||||
};
|
||||
|
||||
/* Takes an index between 0 and one less than the number returned by
|
||||
* SND_GET_NUM_ENDPOINTS, and returns the SND index and name of a
|
||||
* SND endpoint. On input, the .id field contains the number of the
|
||||
* endpoint, and on exit it contains the SND index, while .name contains
|
||||
* the description of the endpoint.
|
||||
*/
|
||||
|
||||
#define SND_GET_ENDPOINT _IOWR(SND_IOCTL_MAGIC, 5, struct msm_snd_endpoint *)
|
||||
|
||||
struct msm_audio_pcm_config {
|
||||
uint32_t pcm_feedback; /* 0 - disable > 0 - enable */
|
||||
uint32_t buffer_count; /* Number of buffers to allocate */
|
||||
uint32_t buffer_size; /* Size of buffer for capturing of
|
||||
PCM samples */
|
||||
};
|
||||
#endif
|
91
include/linux/msm_audio_aac.h
Normal file
91
include/linux/msm_audio_aac.h
Normal file
@ -0,0 +1,91 @@
|
||||
/* arch/arm/mach-msm/include/mach/msm_audio_aac.h
|
||||
*
|
||||
* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* See the GNU General Public License for more details.
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you can find it at http://www.fsf.org.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MSM_AUDIO_AAC_H
|
||||
#define __MSM_AUDIO_AAC_H
|
||||
|
||||
#include <linux/msm_audio_1550.h>
|
||||
|
||||
#define AUDIO_SET_AAC_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \
|
||||
(AUDIO_MAX_COMMON_IOCTL_NUM+0), unsigned)
|
||||
#define AUDIO_GET_AAC_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \
|
||||
(AUDIO_MAX_COMMON_IOCTL_NUM+1), unsigned)
|
||||
|
||||
#define AUDIO_SET_AAC_ENC_CONFIG _IOW(AUDIO_IOCTL_MAGIC, \
|
||||
(AUDIO_MAX_COMMON_IOCTL_NUM+3), struct msm_audio_aac_enc_config)
|
||||
|
||||
#define AUDIO_GET_AAC_ENC_CONFIG _IOR(AUDIO_IOCTL_MAGIC, \
|
||||
(AUDIO_MAX_COMMON_IOCTL_NUM+4), struct msm_audio_aac_enc_config)
|
||||
|
||||
#define AUDIO_AAC_FORMAT_ADTS -1
|
||||
#define AUDIO_AAC_FORMAT_RAW 0x0000
|
||||
#define AUDIO_AAC_FORMAT_PSUEDO_RAW 0x0001
|
||||
#define AUDIO_AAC_FORMAT_LOAS 0x0002
|
||||
#define AUDIO_AAC_FORMAT_ADIF 0x0003
|
||||
|
||||
|
||||
#define AUDIO_AAC_OBJECT_LC 0x0002
|
||||
#define AUDIO_AAC_OBJECT_LTP 0x0004
|
||||
#define AUDIO_AAC_OBJECT_ERLC 0x0011
|
||||
#define AUDIO_AAC_OBJECT_BSAC 0x0016
|
||||
|
||||
#define AUDIO_AAC_SEC_DATA_RES_ON 0x0001
|
||||
#define AUDIO_AAC_SEC_DATA_RES_OFF 0x0000
|
||||
|
||||
#define AUDIO_AAC_SCA_DATA_RES_ON 0x0001
|
||||
#define AUDIO_AAC_SCA_DATA_RES_OFF 0x0000
|
||||
|
||||
#define AUDIO_AAC_SPEC_DATA_RES_ON 0x0001
|
||||
#define AUDIO_AAC_SPEC_DATA_RES_OFF 0x0000
|
||||
|
||||
#define AUDIO_AAC_SBR_ON_FLAG_ON 0x0001
|
||||
#define AUDIO_AAC_SBR_ON_FLAG_OFF 0x0000
|
||||
|
||||
#define AUDIO_AAC_SBR_PS_ON_FLAG_ON 0x0001
|
||||
#define AUDIO_AAC_SBR_PS_ON_FLAG_OFF 0x0000
|
||||
|
||||
/* Primary channel on both left and right channels */
|
||||
#define AUDIO_AAC_DUAL_MONO_PL_PR 0
|
||||
/* Secondary channel on both left and right channels */
|
||||
#define AUDIO_AAC_DUAL_MONO_SL_SR 1
|
||||
/* Primary channel on right channel and 2nd on left channel */
|
||||
#define AUDIO_AAC_DUAL_MONO_SL_PR 2
|
||||
/* 2nd channel on right channel and primary on left channel */
|
||||
#define AUDIO_AAC_DUAL_MONO_PL_SR 3
|
||||
|
||||
struct msm_audio_aac_config {
|
||||
signed short format;
|
||||
unsigned short audio_object;
|
||||
unsigned short ep_config; /* 0 ~ 3 useful only obj = ERLC */
|
||||
unsigned short aac_section_data_resilience_flag;
|
||||
unsigned short aac_scalefactor_data_resilience_flag;
|
||||
unsigned short aac_spectral_data_resilience_flag;
|
||||
unsigned short sbr_on_flag;
|
||||
unsigned short sbr_ps_on_flag;
|
||||
unsigned short dual_mono_mode;
|
||||
unsigned short channel_configuration;
|
||||
};
|
||||
|
||||
struct msm_audio_aac_enc_config {
|
||||
uint32_t channels;
|
||||
uint32_t sample_rate;
|
||||
uint32_t bit_rate;
|
||||
uint32_t stream_format;
|
||||
};
|
||||
|
||||
#endif /* __MSM_AUDIO_AAC_H */
|
@ -19,36 +19,21 @@
|
||||
#define MSMFB_IOCTL_MAGIC 'm'
|
||||
#define MSMFB_GRP_DISP _IOW(MSMFB_IOCTL_MAGIC, 1, unsigned int)
|
||||
#define MSMFB_BLIT _IOW(MSMFB_IOCTL_MAGIC, 2, unsigned int)
|
||||
#ifdef CONFIG_MSM_MDP40
|
||||
#define MSMFB_OVERLAY_SET _IOWR(MSMFB_IOCTL_MAGIC, 135, \
|
||||
struct mdp_overlay)
|
||||
#define MSMFB_OVERLAY_UNSET _IOW(MSMFB_IOCTL_MAGIC, 136, unsigned int)
|
||||
#define MSMFB_OVERLAY_PLAY _IOW(MSMFB_IOCTL_MAGIC, 137, \
|
||||
struct msmfb_overlay_data)
|
||||
#define MSMFB_OVERLAY_GET _IOR(MSMFB_IOCTL_MAGIC, 140, \
|
||||
struct mdp_overlay)
|
||||
#endif
|
||||
|
||||
enum {
|
||||
MDP_RGB_565, // RGB 565 planer
|
||||
MDP_XRGB_8888, // RGB 888 padded
|
||||
MDP_Y_CBCR_H2V2, // Y and CbCr, pseudo planer w/ Cb is in MSB
|
||||
MDP_ARGB_8888, // ARGB 888
|
||||
MDP_RGB_888, // RGB 888 planer
|
||||
MDP_Y_CRCB_H2V2, // Y and CrCb, pseudo planer w/ Cr is in MSB
|
||||
MDP_YCRYCB_H2V1, // YCrYCb interleave
|
||||
MDP_Y_CRCB_H2V1, // Y and CrCb, pseduo planer w/ Cr is in MSB
|
||||
MDP_Y_CBCR_H2V1, // Y and CrCb, pseduo planer w/ Cr is in MSB
|
||||
MDP_RGBA_8888, // ARGB 888
|
||||
MDP_BGRA_8888, // ARGB 888
|
||||
MDP_RGBX_8888, // RGBX 888
|
||||
MDP_Y_CRCB_H2V2_TILE, /* Y and CrCb, pseudo planer tile */
|
||||
MDP_Y_CBCR_H2V2_TILE, /* Y and CbCr, pseudo planer tile */
|
||||
MDP_IMGTYPE_LIMIT, // Non valid image type after this enum
|
||||
MDP_IMGTYPE2_START = 0x10000,
|
||||
MDP_BGR_565 = MDP_IMGTYPE2_START, /* BGR 565 planer */
|
||||
MDP_FB_FORMAT, /* framebuffer format */
|
||||
MDP_IMGTYPE_LIMIT2 /* Non valid image type after this enum */
|
||||
MDP_RGB_565, /* RGB 565 planar */
|
||||
MDP_XRGB_8888, /* RGB 888 padded */
|
||||
MDP_Y_CBCR_H2V2, /* Y and CbCr, pseudo planar w/ Cb is in MSB */
|
||||
MDP_ARGB_8888, /* ARGB 888 */
|
||||
MDP_RGB_888, /* RGB 888 planar */
|
||||
MDP_Y_CRCB_H2V2, /* Y and CrCb, pseudo planar w/ Cr is in MSB */
|
||||
MDP_YCRYCB_H2V1, /* YCrYCb interleave */
|
||||
MDP_Y_CRCB_H2V1, /* Y and CrCb, pseduo planar w/ Cr is in MSB */
|
||||
MDP_Y_CBCR_H2V1, /* Y and CrCb, pseduo planar w/ Cr is in MSB */
|
||||
MDP_RGBA_8888, /* ARGB 888 */
|
||||
MDP_BGRA_8888, /* ABGR 888 */
|
||||
MDP_RGBX_8888, /* RGBX 888 */
|
||||
MDP_IMGTYPE_LIMIT /* Non valid image type after this enum */
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -57,20 +42,23 @@ enum {
|
||||
};
|
||||
|
||||
/* flag values */
|
||||
#define MDP_ROT_NOP 0
|
||||
#define MDP_FLIP_LR 0x1
|
||||
#define MDP_FLIP_UD 0x2
|
||||
#define MDP_ROT_90 0x4
|
||||
#define MDP_ROT_180 (MDP_FLIP_UD|MDP_FLIP_LR)
|
||||
#define MDP_ROT_270 (MDP_ROT_90|MDP_FLIP_UD|MDP_FLIP_LR)
|
||||
#define MDP_ROT_MASK 0x7
|
||||
#define MDP_DITHER 0x8
|
||||
#define MDP_BLUR 0x10
|
||||
#define MDP_ROT_NOP 0
|
||||
#define MDP_FLIP_LR 0x1
|
||||
#define MDP_FLIP_UD 0x2
|
||||
#define MDP_ROT_90 0x4
|
||||
#define MDP_ROT_180 (MDP_FLIP_UD|MDP_FLIP_LR)
|
||||
#define MDP_ROT_270 (MDP_ROT_90|MDP_FLIP_UD|MDP_FLIP_LR)
|
||||
#define MDP_ROT_MASK 0x7
|
||||
#define MDP_DITHER 0x8
|
||||
#define MDP_BLUR 0x10
|
||||
#define MDP_BLEND_FG_PREMULT 0x20000
|
||||
#define MDP_DEINTERLACE 0x80000000
|
||||
#define MDP_SHARPENING 0x40000000
|
||||
#define MDP_TRANSP_NOP 0xffffffff
|
||||
#define MDP_ALPHA_NOP 0xff
|
||||
|
||||
#define MDP_TRANSP_NOP 0xffffffff
|
||||
#define MDP_ALPHA_NOP 0xff
|
||||
|
||||
/* drewis: added for android 4.0 */
|
||||
#define MDP_BLIT_NON_CACHED 0x01000000
|
||||
/* drewis: end */
|
||||
|
||||
struct mdp_rect {
|
||||
uint32_t x;
|
||||
@ -95,7 +83,6 @@ struct mdp_blit_req {
|
||||
uint32_t alpha;
|
||||
uint32_t transp_mask;
|
||||
uint32_t flags;
|
||||
int sharpening_strength; /* -127 <--> 127, default 64 */
|
||||
};
|
||||
|
||||
struct mdp_blit_req_list {
|
||||
@ -103,37 +90,4 @@ struct mdp_blit_req_list {
|
||||
struct mdp_blit_req req[];
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MSM_MDP40
|
||||
struct msmfb_data {
|
||||
uint32_t offset;
|
||||
int memory_id;
|
||||
int id;
|
||||
};
|
||||
|
||||
#define MSMFB_NEW_REQUEST -1
|
||||
|
||||
struct msmfb_overlay_data {
|
||||
uint32_t id;
|
||||
struct msmfb_data data;
|
||||
};
|
||||
|
||||
struct msmfb_img {
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t format;
|
||||
};
|
||||
|
||||
struct mdp_overlay {
|
||||
struct msmfb_img src;
|
||||
struct mdp_rect src_rect;
|
||||
struct mdp_rect dst_rect;
|
||||
uint32_t z_order; /* stage number */
|
||||
uint32_t is_fg; /* control alpha & transp */
|
||||
uint32_t alpha;
|
||||
uint32_t transp_mask;
|
||||
uint32_t flags;
|
||||
uint32_t id;
|
||||
uint32_t user_data[8];
|
||||
};
|
||||
#endif
|
||||
#endif //_MSM_MDP_H_
|
||||
#endif /* _MSM_MDP_H_ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user