Import F(x)tec Pro1-X BSP kernel changes as of 2022-06-01
This commit is contained in:
parent
c3bcbab00e
commit
f13e1f4e3e
128 changed files with 5284 additions and 757 deletions
|
@ -647,7 +647,6 @@ CONFIG_SQUASHFS_LZ4=y
|
|||
# CONFIG_NETWORK_FILESYSTEMS is not set
|
||||
CONFIG_NLS_CODEPAGE_437=y
|
||||
CONFIG_NLS_ISO8859_1=y
|
||||
CONFIG_SECURITY_PERF_EVENTS_RESTRICT=y
|
||||
CONFIG_SECURITY=y
|
||||
CONFIG_HARDENED_USERCOPY=y
|
||||
CONFIG_HARDENED_USERCOPY_PAGESPAN=y
|
||||
|
|
|
@ -1030,7 +1030,7 @@ static int geni_i2c_probe(struct platform_device *pdev)
|
|||
|
||||
if (of_property_read_u32(pdev->dev.of_node, "qcom,clk-freq-out",
|
||||
&gi2c->i2c_rsc.clk_freq_out)) {
|
||||
gi2c->i2c_rsc.clk_freq_out = KHz(400);
|
||||
gi2c->i2c_rsc.clk_freq_out = KHz(100);
|
||||
}
|
||||
dev_info(&pdev->dev, "Bus frequency is set to %dHz\n",
|
||||
gi2c->i2c_rsc.clk_freq_out);
|
||||
|
|
|
@ -22,16 +22,18 @@ static DECLARE_WAIT_QUEUE_HEAD(screenwaitq);
|
|||
static DECLARE_WAIT_QUEUE_HEAD(gWaitq);
|
||||
static DECLARE_WAIT_QUEUE_HEAD(U1_Waitq);
|
||||
static DECLARE_WAIT_QUEUE_HEAD(U2_Waitq);
|
||||
|
||||
#ifdef CONFIG_PM_WAKELOCKS
|
||||
struct wakeup_source *gIntWakeLock = NULL;
|
||||
struct wakeup_source *gProcessWakeLock = NULL;
|
||||
#else
|
||||
struct wake_lock gIntWakeLock;
|
||||
struct wake_lock gProcessWakeLock;
|
||||
#endif
|
||||
#endif //CONFIG_PM_WAKELOCKS
|
||||
|
||||
struct work_struct gWork;
|
||||
struct workqueue_struct *gWorkq;
|
||||
//
|
||||
|
||||
static LIST_HEAD(dev_list);
|
||||
static DEFINE_MUTEX(dev_lock);
|
||||
static DEFINE_MUTEX(drv_lock);
|
||||
|
@ -55,17 +57,17 @@ static void mas_work(struct work_struct *pws) {
|
|||
smas->f_irq = 1;
|
||||
wake_up(&gWaitq);
|
||||
#ifdef COMPATIBLE_VERSION3
|
||||
wake_up(&drv_waitq);
|
||||
wake_up(&drv_waitq);
|
||||
#endif
|
||||
}
|
||||
|
||||
static irqreturn_t mas_interrupt(int irq, void *dev_id) {
|
||||
#ifdef DOUBLE_EDGE_IRQ
|
||||
if(mas_get_interrupt_gpio(0)==1){
|
||||
//TODO IRQF_TRIGGER_RISING
|
||||
}else{
|
||||
//TODO IRQF_TRIGGER_FALLING
|
||||
}
|
||||
if(mas_get_interrupt_gpio(0)==1){
|
||||
//TODO IRQF_TRIGGER_RISING
|
||||
}else{
|
||||
//TODO IRQF_TRIGGER_FALLING
|
||||
}
|
||||
#else
|
||||
printk("mas_interrupt.\n");
|
||||
#ifdef CONFIG_PM_WAKELOCKS
|
||||
|
@ -126,27 +128,6 @@ struct spi_transfer t = {
|
|||
|
||||
|
||||
|
||||
/* 读数据
|
||||
* @return 成功:count, -1count太大,-2通讯失败, -3拷贝失败
|
||||
*/
|
||||
static ssize_t mas_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) {
|
||||
int val, ret = 0;
|
||||
// MALOGD("start");
|
||||
ret = mas_sync(stxb, srxb, count);
|
||||
if(ret) {
|
||||
MALOGW("mas_sync failed.");
|
||||
return -2;
|
||||
}
|
||||
ret = copy_to_user(buf, srxb, count);
|
||||
if(!ret) val = count;
|
||||
else {
|
||||
val = -3;
|
||||
MALOGW("copy_to_user failed.");
|
||||
}
|
||||
// MALOGD("end.");
|
||||
return val;
|
||||
}
|
||||
|
||||
|
||||
static void mas_set_input(void) {
|
||||
struct input_dev *input = NULL;
|
||||
|
@ -200,12 +181,14 @@ static long mas_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) {
|
|||
smas->f_irq = 1;
|
||||
wake_up(&gWaitq);
|
||||
break;
|
||||
#ifndef USE_PLATFORM_DRIVE
|
||||
case ENABLE_CLK:
|
||||
mas_enable_spi_clock(smas->spi); //if the spi clock is not opening always, do this methods
|
||||
break;
|
||||
case DISABLE_CLK:
|
||||
mas_disable_spi_clock(smas->spi); //disable the spi clock
|
||||
break;
|
||||
#endif
|
||||
case ENABLE_INTERRUPT:
|
||||
enable_irq(irq); //enable the irq,in fact, you can make irq enable always
|
||||
break;
|
||||
|
@ -362,10 +345,12 @@ int version3_ioctl(int cmd, int arg){
|
|||
break;
|
||||
case IOCTL_IRQ_ENABLE:
|
||||
break;
|
||||
#ifndef USE_PLATFORM_DRIVE
|
||||
case IOCTL_SPI_SPEED:
|
||||
smas->spi->max_speed_hz = (u32) arg;
|
||||
spi_setup(smas->spi);
|
||||
break;
|
||||
#endif //USE_PLATFORM_DRIVE
|
||||
case IOCTL_COVER_NUM:
|
||||
ret = COVER_NUM;
|
||||
break;
|
||||
|
@ -444,13 +429,14 @@ int version3_ioctl(int cmd, int arg){
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef USE_PLATFORM_DRIVE
|
||||
/* 写数据
|
||||
* @return 成功:count, -1count太大,-2拷贝失败
|
||||
*/
|
||||
static ssize_t mas_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) {
|
||||
int val = 0;
|
||||
// MALOGD("start");
|
||||
if(count==6) { //cmd ioctl, old version used the write interface to do ioctl, this is only for the old version
|
||||
// MALOGD("start");
|
||||
if(count==6) { //cmd ioctl, old version used the write interface to do ioctl, this is only for the old version
|
||||
int cmd, arg;
|
||||
u8 tmp[6];
|
||||
ret = copy_from_user(tmp, buf, count);
|
||||
|
@ -464,10 +450,10 @@ static ssize_t mas_write(struct file *filp, const char __user *buf, size_t count
|
|||
arg += tmp[4];
|
||||
arg <<= 8;
|
||||
arg += tmp[5];
|
||||
#ifdef COMPATIBLE_VERSION3
|
||||
#ifdef COMPATIBLE_VERSION3
|
||||
val = (int)version3_ioctl(NULL, (unsigned int)cmd, (unsigned long)arg);
|
||||
#endif
|
||||
} else {
|
||||
#endif
|
||||
} else {
|
||||
memset(stxb, 0, FBUF);
|
||||
ret = copy_from_user(stxb, buf, count);
|
||||
if(ret) {
|
||||
|
@ -477,9 +463,32 @@ static ssize_t mas_write(struct file *filp, const char __user *buf, size_t count
|
|||
val = count;
|
||||
}
|
||||
}
|
||||
// MALOGD("end");
|
||||
// MALOGD("end");
|
||||
return val;
|
||||
}
|
||||
|
||||
/* 读数据
|
||||
* @return 成功:count, -1count太大,-2通讯失败, -3拷贝失败
|
||||
*/
|
||||
static ssize_t mas_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos) {
|
||||
int val, ret = 0;
|
||||
// MALOGD("start");
|
||||
ret = mas_sync(stxb, srxb, count);
|
||||
if(ret) {
|
||||
MALOGW("mas_sync failed.");
|
||||
return -2;
|
||||
}
|
||||
ret = copy_to_user(buf, srxb, count);
|
||||
if(!ret) val = count;
|
||||
else {
|
||||
val = -3;
|
||||
MALOGW("copy_to_user failed.");
|
||||
}
|
||||
// MALOGD("end.");
|
||||
return val;
|
||||
}
|
||||
#endif
|
||||
|
||||
void * kernel_memaddr = NULL;
|
||||
unsigned long kernel_memesize = 0;
|
||||
|
||||
|
@ -526,8 +535,10 @@ static unsigned int mas_poll(struct file *filp, struct poll_table_struct *wait)
|
|||
/*---------------------------------- fops ------------------------------------*/
|
||||
static const struct file_operations sfops = {
|
||||
.owner = THIS_MODULE,
|
||||
#ifndef USE_PLATFORM_DRIVE
|
||||
.write = mas_write,
|
||||
.read = mas_read,
|
||||
#endif
|
||||
.unlocked_ioctl = mas_ioctl,
|
||||
.mmap = mas_mmap,
|
||||
//.ioctl = mas_ioctl,
|
||||
|
@ -543,56 +554,64 @@ static const struct file_operations sfops = {
|
|||
|
||||
static int init_file_node(void)
|
||||
{
|
||||
int ret;
|
||||
//MALOGF("start");
|
||||
ret = alloc_chrdev_region(&sdev->idd, 0, 1, MA_CHR_DEV_NAME);
|
||||
if(ret < 0)
|
||||
{
|
||||
MALOGW("alloc_chrdev_region error!");
|
||||
return -1;
|
||||
}
|
||||
sdev->chd = cdev_alloc();
|
||||
if (!sdev->chd)
|
||||
{
|
||||
MALOGW("cdev_alloc error!");
|
||||
return -1;
|
||||
}
|
||||
sdev->chd->owner = THIS_MODULE;
|
||||
sdev->chd->ops = &sfops;
|
||||
cdev_add(sdev->chd, sdev->idd, 1);
|
||||
sdev->cls = class_create(THIS_MODULE, MA_CHR_DEV_NAME);
|
||||
if (IS_ERR(sdev->cls)) {
|
||||
MALOGE("class_create");
|
||||
return -1;
|
||||
}
|
||||
sdev->dev = device_create(sdev->cls, NULL, sdev->idd, NULL, MA_CHR_FILE_NAME);
|
||||
ret = IS_ERR(sdev->dev) ? PTR_ERR(sdev->dev) : 0;
|
||||
if(ret){
|
||||
MALOGE("device_create");
|
||||
}
|
||||
//MALOGF("end");
|
||||
return 0;
|
||||
int ret;
|
||||
//MALOGF("start");
|
||||
ret = alloc_chrdev_region(&sdev->idd, 0, 1, MA_CHR_DEV_NAME);
|
||||
if(ret < 0)
|
||||
{
|
||||
MALOGW("alloc_chrdev_region error!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sdev->chd = cdev_alloc();
|
||||
if (!sdev->chd)
|
||||
{
|
||||
MALOGW("cdev_alloc error!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sdev->chd->owner = THIS_MODULE;
|
||||
sdev->chd->ops = &sfops;
|
||||
|
||||
cdev_add(sdev->chd, sdev->idd, 1);
|
||||
|
||||
sdev->cls = class_create(THIS_MODULE, MA_CHR_DEV_NAME);
|
||||
if (IS_ERR(sdev->cls)) {
|
||||
MALOGE("class_create");
|
||||
return -1;
|
||||
}
|
||||
|
||||
sdev->dev = device_create(sdev->cls, NULL, sdev->idd, NULL, MA_CHR_FILE_NAME);
|
||||
ret = IS_ERR(sdev->dev) ? PTR_ERR(sdev->dev) : 0;
|
||||
if(ret){
|
||||
MALOGE("device_create");
|
||||
}
|
||||
//MALOGF("end");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int deinit_file_node(void)
|
||||
{
|
||||
cdev_del(sdev->chd);
|
||||
sdev->chd = NULL;
|
||||
kfree(sdev->chd);
|
||||
device_destroy(sdev->cls, sdev->idd);
|
||||
unregister_chrdev_region(sdev->idd, 1);
|
||||
class_destroy(sdev->cls);
|
||||
cdev_del(sdev->chd);
|
||||
sdev->chd = NULL;
|
||||
kfree(sdev->chd);
|
||||
device_destroy(sdev->cls, sdev->idd);
|
||||
unregister_chrdev_region(sdev->idd, 1);
|
||||
class_destroy(sdev->cls);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init_interrupt(void)
|
||||
{
|
||||
const char*tname = MA_EINT_NAME;
|
||||
int ret = 0;
|
||||
|
||||
irq = mas_get_irq();
|
||||
if(irq<=0){
|
||||
ret = irq;
|
||||
MALOGE("mas_get_irq");
|
||||
}
|
||||
|
||||
#ifdef DOUBLE_EDGE_IRQ
|
||||
ret = request_irq(irq, mas_interrupt, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, tname, NULL);
|
||||
#else
|
||||
|
@ -601,23 +620,25 @@ static int init_interrupt(void)
|
|||
if(ret<0){
|
||||
MALOGE("request_irq");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
static int deinit_interrupt(void)
|
||||
{
|
||||
if(irq)
|
||||
if(irq)
|
||||
{disable_irq(irq);
|
||||
free_irq(irq, NULL);
|
||||
free_irq(irq, NULL);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int init_vars(void)
|
||||
{
|
||||
sdev = kmalloc(sizeof(struct fprint_dev), GFP_KERNEL);
|
||||
smas = kmalloc(sizeof(struct fprint_spi), GFP_KERNEL);
|
||||
stxb = kmalloc(FBUF, GFP_KERNEL);
|
||||
srxb = kmalloc(FBUF, GFP_KERNEL);
|
||||
if (sdev==NULL || smas==NULL ) {
|
||||
MALOGW("smas kmalloc failed.");
|
||||
if(sdev!=NULL) kfree(sdev);
|
||||
|
@ -625,10 +646,15 @@ static int init_vars(void)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
printk("[%s][%d]smas %p \r\n",__func__,__LINE__, smas);
|
||||
printk("[%s][%d]sdev %p \r\n",__func__,__LINE__, sdev);
|
||||
printk("[%s][%d]stxb %p \r\n",__func__,__LINE__, stxb);
|
||||
printk("[%s][%d]srxb %p \r\n",__func__,__LINE__, srxb);
|
||||
stxb = kmalloc(FBUF, GFP_KERNEL);
|
||||
srxb = kmalloc(FBUF, GFP_KERNEL);
|
||||
if (stxb==NULL || srxb==NULL ) {
|
||||
MALOGW("stxb srxb kmalloc failed.");
|
||||
if(stxb!=NULL) kfree(stxb);
|
||||
if(srxb!=NULL) kfree(srxb);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_PM_WAKELOCKS
|
||||
gIntWakeLock = wakeup_source_register(NULL, "microarray_int_wakelock");
|
||||
|
@ -655,13 +681,23 @@ static int deinit_vars(void)
|
|||
wake_lock_destroy(&gIntWakeLock);
|
||||
wake_lock_destroy(&gProcessWakeLock);
|
||||
#endif
|
||||
if(sdev!=NULL) kfree(sdev);
|
||||
if(smas!=NULL) kfree(smas);
|
||||
// if(stxb!=NULL) kfree(stxb);
|
||||
// if(srxb!=NULL) kfree(srxb);
|
||||
if(sdev!=NULL)
|
||||
kfree(sdev);
|
||||
|
||||
if(smas!=NULL)
|
||||
kfree(smas);
|
||||
|
||||
if(stxb!=NULL)
|
||||
kfree(stxb);
|
||||
|
||||
if(srxb!=NULL)
|
||||
kfree(srxb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifndef USE_PLATFORM_DRIVE
|
||||
static int init_spi(struct spi_device *spi){
|
||||
msleep(50);
|
||||
smas->spi = spi;
|
||||
|
@ -673,16 +709,21 @@ static int init_spi(struct spi_device *spi){
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int deinit_spi(struct spi_device *spi){
|
||||
smas->spi = NULL;
|
||||
mas_disable_spi_clock(spi);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* init_connect function to check whether the chip is microarray's
|
||||
* @return 0 not 1 yes
|
||||
* param void
|
||||
*/
|
||||
#ifdef REE
|
||||
int init_connect(void){
|
||||
int i;
|
||||
int res = 0;
|
||||
|
@ -721,6 +762,7 @@ int init_connect(void){
|
|||
int deinit_connect(void){
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int mas_fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data){
|
||||
struct fb_event *evdata = data;
|
||||
|
@ -748,72 +790,96 @@ static int init_notifier_call(void);
|
|||
static int deinit_notifier_call(void);
|
||||
|
||||
static int init_notifier_call(){
|
||||
notifier.notifier_call = mas_fb_notifier_callback;
|
||||
fb_register_client(¬ifier);
|
||||
is_screen_on = 1;
|
||||
return 0;
|
||||
notifier.notifier_call = mas_fb_notifier_callback;
|
||||
fb_register_client(¬ifier);
|
||||
is_screen_on = 1;
|
||||
return 0;
|
||||
}
|
||||
static int deinit_notifier_call(){
|
||||
fb_unregister_client(¬ifier);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef USE_PLATFORM_DRIVE
|
||||
int mas_probe(struct platform_device *spi){
|
||||
#else
|
||||
int mas_probe(struct spi_device *spi) {
|
||||
int ret;
|
||||
#endif
|
||||
int ret;
|
||||
pr_err("mas_probe,by eric.wang\n");
|
||||
|
||||
ret= mas_qcm_platform_init(spi);
|
||||
pr_err("mas_qcm_platform_init:ret=%d,by eric.wang\n",ret);
|
||||
if(ret)
|
||||
goto err0;
|
||||
goto err0;
|
||||
|
||||
ret = init_vars();
|
||||
pr_err("init_vars:ret=%d,by eric.wang\n",ret);
|
||||
if(ret){
|
||||
goto err1;
|
||||
}
|
||||
|
||||
ret = init_interrupt();
|
||||
pr_err("init_interrupt:ret=%d,by eric.wang\n",ret);
|
||||
if(ret){
|
||||
goto err2;
|
||||
}
|
||||
|
||||
ret = init_file_node();
|
||||
pr_err("init_file_node:ret=%d,by eric.wang\n",ret);
|
||||
if(ret){
|
||||
goto err3;
|
||||
}
|
||||
|
||||
#ifndef USE_PLATFORM_DRIVE
|
||||
ret = init_spi(spi);
|
||||
pr_err("init_spi:ret=%d,by eric.wang\n",ret);
|
||||
if(ret){
|
||||
goto err4;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef REE
|
||||
ret = init_connect();
|
||||
#elif defined TEE
|
||||
ret = 1;
|
||||
ret = 1;
|
||||
#endif
|
||||
if(ret == 0){//not chip
|
||||
compatible = 0;
|
||||
pr_info("%s:init_connect failed.\n", __func__);
|
||||
pr_info("%s:init_connect failed.\n", __func__);
|
||||
#ifdef USE_PLATFORM_DRIVE
|
||||
goto err3;
|
||||
#else
|
||||
goto err5;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
pr_info("%s:init_connect successfully.\n", __func__);
|
||||
pr_err("%s:init_connect successfully.\n", __func__);
|
||||
|
||||
mas_set_input();
|
||||
MALOGF("end");
|
||||
|
||||
ret = init_notifier_call();
|
||||
if(ret != 0){
|
||||
ret = -ENODEV;
|
||||
goto err6;
|
||||
}
|
||||
ret = -ENODEV;
|
||||
goto err6;
|
||||
}
|
||||
|
||||
mas_set_wakeup(spi);
|
||||
//Fingerprint_name="Microarray_A121N";
|
||||
pr_info("%s:completed.\n", __func__);
|
||||
pr_err("%s:completed.\n", __func__);
|
||||
return ret;
|
||||
|
||||
err6:
|
||||
deinit_notifier_call();
|
||||
#ifdef REE
|
||||
err5:
|
||||
deinit_connect();
|
||||
#endif
|
||||
#ifndef USE_PLATFORM_DRIVE
|
||||
err4:
|
||||
deinit_spi(spi);
|
||||
#endif
|
||||
err3:
|
||||
deinit_file_node();
|
||||
err2:
|
||||
|
@ -825,7 +891,11 @@ int mas_probe(struct spi_device *spi) {
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
#ifdef USE_PLATFORM_DRIVE
|
||||
int mas_remove(struct platform_device *spi) {
|
||||
#else
|
||||
int mas_remove(struct spi_device *spi) {
|
||||
#endif
|
||||
deinit_file_node();
|
||||
deinit_interrupt();
|
||||
deinit_vars();
|
||||
|
|
|
@ -13,13 +13,15 @@
|
|||
//settings macro
|
||||
#define QUALCOMM //[MTK|QUALCOMM|SPRD]
|
||||
|
||||
#define REE //[TEE|REE] //select platform
|
||||
#define TEE //[TEE|REE] //select platform
|
||||
|
||||
#define MALOGD_LEVEL KERN_EMERG //[KERN_DEBUG|KERN_EMERG] usually, the debug level is used for the release version
|
||||
|
||||
#define MA_CHR_FILE_NAME "madev0" //do not neeed modify usually
|
||||
#define MA_CHR_DEV_NAME "madev" //do not neeed modify usually
|
||||
|
||||
#define USE_PLATFORM_DRIVE
|
||||
|
||||
#define MA_EINT_NAME "afs121_irq"
|
||||
|
||||
|
||||
|
@ -158,20 +160,26 @@ struct fprint_dev {
|
|||
//function define
|
||||
|
||||
//extern the settings.h function
|
||||
#ifdef USE_PLATFORM_DRIVE
|
||||
extern int mas_qcm_platform_init(struct platform_device *spi);
|
||||
extern int mas_qcm_platform_uninit(struct platform_device *spi);
|
||||
extern void mas_set_wakeup(struct platform_device *spi);
|
||||
#else
|
||||
extern int mas_qcm_platform_init(struct spi_device *spi);
|
||||
extern int mas_qcm_platform_uninit(struct spi_device *spi);
|
||||
extern int mas_fingerprint_power(bool flags);
|
||||
|
||||
extern void mas_select_transfer(struct spi_device *spi, int len);
|
||||
extern int mas_finger_get_gpio_info(struct platform_device *pdev);
|
||||
extern int mas_finger_set_gpio_info(int cmd);
|
||||
extern void mas_enable_spi_clock(struct spi_device *spi);
|
||||
extern void mas_disable_spi_clock(struct spi_device *spi);
|
||||
extern unsigned int mas_get_irq(void);
|
||||
extern int mas_get_platform(void);
|
||||
extern int mas_remove_platform(void);
|
||||
extern void ma_spi_change(struct spi_device *spi, unsigned int speed, int flag);
|
||||
extern void mas_set_wakeup(struct spi_device *spi);
|
||||
#endif
|
||||
|
||||
extern int mas_fingerprint_power(bool flags);
|
||||
extern int mas_finger_get_gpio_info(struct platform_device *pdev);
|
||||
extern int mas_finger_set_gpio_info(int cmd);
|
||||
extern unsigned int mas_get_irq(void);
|
||||
extern int mas_get_platform(void);
|
||||
extern int mas_remove_platform(void);\
|
||||
extern int mas_get_interrupt_gpio(unsigned int index);
|
||||
//end
|
||||
|
||||
|
|
|
@ -22,13 +22,15 @@ struct mas_platform_data {
|
|||
//kingsun/zlc:
|
||||
int clk_enabled;
|
||||
struct clk *core_clk;
|
||||
struct clk *iface_clk;
|
||||
struct clk *iface_clk;
|
||||
unsigned int int_irq;
|
||||
//end
|
||||
};
|
||||
|
||||
struct mas_platform_data *mas_pdata;
|
||||
int first_int_after_suspend=0; //kingsun/zlc:
|
||||
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
/* -------------------------------------------------------------------- */
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
|
@ -36,10 +38,12 @@ int mas_suspend(struct spi_device *spi, pm_message_t mesg)
|
|||
{
|
||||
printk("%s start\n",__func__);
|
||||
if (device_may_wakeup(&spi->dev))
|
||||
enable_irq_wake(mas_pdata->int_irq);
|
||||
enable_irq_wake(mas_pdata->int_irq);
|
||||
|
||||
#ifndef USE_PLATFORM_DRIVE
|
||||
printk("mas_ioctl_clk_disable\n");
|
||||
mas_disable_spi_clock(spi);
|
||||
#endif //USE_PLATFORM_DRIVE
|
||||
first_int_after_suspend=1;
|
||||
printk("%s end\n",__func__);
|
||||
return 0;
|
||||
|
@ -49,18 +53,27 @@ int mas_suspend(struct spi_device *spi, pm_message_t mesg)
|
|||
/* -------------------------------------------------------------------- */
|
||||
int mas_resume(struct spi_device *spi)
|
||||
{
|
||||
printk("%s start\n",__func__);
|
||||
if (device_may_wakeup(&spi->dev))
|
||||
disable_irq_wake(mas_pdata->int_irq);
|
||||
printk("%s start\n",__func__);
|
||||
if (device_may_wakeup(&spi->dev))
|
||||
disable_irq_wake(mas_pdata->int_irq);
|
||||
|
||||
#ifndef USE_PLATFORM_DRIVE
|
||||
printk("mas_enable_spi_clock\n");
|
||||
mas_enable_spi_clock(spi);
|
||||
#endif //USE_PLATFORM_DRIVE
|
||||
printk("%s end\n",__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
|
||||
int mas_suspend(struct device *dev)
|
||||
{
|
||||
#ifdef USE_PLATFORM_DRIVE
|
||||
printk("%s start\n",__func__);
|
||||
#else
|
||||
struct spi_device *spi = NULL;
|
||||
printk("%s start\n",__func__);
|
||||
|
||||
|
@ -69,20 +82,28 @@ int mas_suspend(struct device *dev)
|
|||
printk("%s get spi device failed\n",__func__);
|
||||
return -1;
|
||||
}
|
||||
#endif //USE_PLATFORM_DRIVE
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
enable_irq_wake(mas_pdata->int_irq);
|
||||
enable_irq_wake(mas_pdata->int_irq);
|
||||
|
||||
#ifndef USE_PLATFORM_DRIVE
|
||||
printk("mas_ioctl_clk_disable\n");
|
||||
mas_disable_spi_clock(spi);
|
||||
#endif //USE_PLATFORM_DRIVE
|
||||
first_int_after_suspend=1;
|
||||
printk("%s end\n",__func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int mas_resume(struct device *dev)
|
||||
{
|
||||
#ifdef USE_PLATFORM_DRIVE
|
||||
printk("%s start\n",__func__);
|
||||
#else
|
||||
struct spi_device *spi = NULL;
|
||||
|
||||
printk("%s start\n",__func__);
|
||||
|
||||
spi = to_spi_device(dev);
|
||||
|
@ -90,61 +111,76 @@ int mas_resume(struct device *dev)
|
|||
printk("%s get spi device failed\n",__func__);
|
||||
return -1;
|
||||
}
|
||||
#endif //USE_PLATFORM_DRIVE
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
disable_irq_wake(mas_pdata->int_irq);
|
||||
if (device_may_wakeup(dev))
|
||||
disable_irq_wake(mas_pdata->int_irq);
|
||||
|
||||
#ifndef USE_PLATFORM_DRIVE
|
||||
printk("mas_enable_spi_clock\n");
|
||||
mas_enable_spi_clock(spi);
|
||||
#endif //USE_PLATFORM_DRIVE
|
||||
|
||||
printk("%s end\n",__func__);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif //CONFIG_HAS_EARLYSUSPEND
|
||||
|
||||
|
||||
static struct of_device_id mas_of_match[] = {
|
||||
{.compatible = "microarray,fingerprint",},
|
||||
{}
|
||||
{.compatible = "microarray,fingerprint",},
|
||||
{}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, mas_of_match);
|
||||
|
||||
#ifndef CONFIG_HAS_EARLYSUSPEND
|
||||
const struct dev_pm_ops mas_pm_ops = {
|
||||
.suspend = mas_suspend,
|
||||
.resume = mas_resume,
|
||||
.suspend = mas_suspend,
|
||||
.resume = mas_resume,
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
#endif //CONFIG_HAS_EARLYSUSPEND
|
||||
|
||||
#endif//CONFIG_OF
|
||||
|
||||
|
||||
#ifndef USE_PLATFORM_DRIVE
|
||||
struct spi_device_id sdev_id = {MA_DRV_NAME, 0};
|
||||
#endif //USE_PLATFORM_DRIVE
|
||||
|
||||
#ifdef USE_PLATFORM_DRIVE
|
||||
struct platform_driver sdrv = {
|
||||
#else
|
||||
struct spi_driver sdrv = {
|
||||
.driver = {
|
||||
.name = MA_DRV_NAME,
|
||||
//.bus = &spi_bus_type,
|
||||
.owner = THIS_MODULE,
|
||||
#endif //USE_PLATFORM_DRIVE
|
||||
.driver = {
|
||||
.name = MA_DRV_NAME,
|
||||
//.bus = &spi_bus_type,
|
||||
.owner = THIS_MODULE,
|
||||
#ifndef CONFIG_HAS_EARLYSUSPEND
|
||||
.pm = &mas_pm_ops,
|
||||
#endif
|
||||
.pm = &mas_pm_ops,
|
||||
#endif //CONFIG_HAS_EARLYSUSPEND
|
||||
#ifdef CONFIG_OF
|
||||
.of_match_table = mas_of_match,
|
||||
#endif
|
||||
},
|
||||
.id_table = &sdev_id,
|
||||
.probe = mas_probe,
|
||||
.remove = mas_remove,
|
||||
.of_match_table = mas_of_match,
|
||||
#endif //CONFIG_OF
|
||||
},
|
||||
#ifndef USE_PLATFORM_DRIVE
|
||||
.id_table = &sdev_id,
|
||||
#endif //USE_PLATFORM_DRIVE
|
||||
.probe = mas_probe,
|
||||
.remove = mas_remove,
|
||||
#ifdef CONFIG_HAS_EARLYSUSPEND
|
||||
.suspend = mas_suspend,
|
||||
.resume = mas_resume,
|
||||
#endif
|
||||
.suspend = mas_suspend,
|
||||
.resume = mas_resume,
|
||||
#endif //CONFIG_HAS_EARLYSUSPEND
|
||||
};
|
||||
//driver end
|
||||
|
||||
#ifndef USE_PLATFORM_DRIVE
|
||||
/**
|
||||
* the spi struct date start,for getting the spi_device to set the spi clock enable end
|
||||
*/
|
||||
|
||||
|
||||
void mas_select_transfer(struct spi_device *spi, int len) {
|
||||
return ;
|
||||
}
|
||||
|
@ -246,7 +282,8 @@ static int mas_ioctl_clk_init(struct spi_device *spi, struct mas_platform_data *
|
|||
}
|
||||
|
||||
static int mas_ioctl_clk_uninit(struct mas_platform_data *data)
|
||||
{ return 0; //kingsun/zlc: bypass the operation of spi clock
|
||||
{
|
||||
return 0; //kingsun/zlc: bypass the operation of spi clock
|
||||
pr_info("%s: enter\n", __func__);
|
||||
|
||||
if (!IS_ERR_OR_NULL(data->core_clk)) {
|
||||
|
@ -290,7 +327,8 @@ static int mas_ioctl_clk_enable(struct mas_platform_data *data)
|
|||
}
|
||||
|
||||
static int mas_ioctl_clk_disable(struct mas_platform_data *data)
|
||||
{ return 0; //kingsun/zlc: bypass the operation of spi clock
|
||||
{
|
||||
return 0; //kingsun/zlc: bypass the operation of spi clock
|
||||
if (!data->clk_enabled)
|
||||
return 0;
|
||||
|
||||
|
@ -300,11 +338,15 @@ static int mas_ioctl_clk_disable(struct mas_platform_data *data)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif //USE_PLATFORM_DRIVE
|
||||
|
||||
int mas_get_platform(void) {
|
||||
int ret;
|
||||
#ifdef USE_PLATFORM_DRIVE
|
||||
ret = platform_driver_register(&sdrv);
|
||||
#else
|
||||
ret = spi_register_driver(&sdrv);
|
||||
#endif
|
||||
pr_err("MAFP_ spi_register_driver ret = %d",ret);
|
||||
|
||||
if(ret) {
|
||||
|
@ -314,7 +356,11 @@ int mas_get_platform(void) {
|
|||
}
|
||||
|
||||
int mas_remove_platform(void){
|
||||
spi_unregister_driver(&sdrv);
|
||||
#ifdef USE_PLATFORM_DRIVE
|
||||
platform_driver_unregister(&sdrv);
|
||||
#else
|
||||
spi_unregister_driver(&sdrv);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -447,34 +493,44 @@ static int mas_gpio_configure(bool on)
|
|||
return rc;
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_PLATFORM_DRIVE
|
||||
int mas_qcm_platform_uninit(struct platform_device *spi)
|
||||
#else
|
||||
int mas_qcm_platform_uninit(struct spi_device *spi)
|
||||
{ int ret=0;
|
||||
#endif
|
||||
{
|
||||
int ret=0;
|
||||
#ifndef USE_PLATFORM_DRIVE
|
||||
mas_ioctl_clk_uninit(mas_pdata);
|
||||
#endif
|
||||
mas_fingerprint_power(false);
|
||||
|
||||
#if 0
|
||||
if(mas_pdata->vcc_io_l6)
|
||||
regulator_put(mas_pdata->vcc_io_l6);
|
||||
#endif
|
||||
mas_gpio_configure(false);
|
||||
mas_pdata->int_irq=0;
|
||||
kfree(mas_pdata);
|
||||
return ret;
|
||||
if(mas_pdata->vcc_io_l6)
|
||||
regulator_put(mas_pdata->vcc_io_l6);
|
||||
#endif
|
||||
mas_gpio_configure(false);
|
||||
mas_pdata->int_irq=0;
|
||||
kfree(mas_pdata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_PLATFORM_DRIVE
|
||||
int mas_qcm_platform_init(struct platform_device *spi)
|
||||
#else
|
||||
int mas_qcm_platform_init(struct spi_device *spi)
|
||||
#endif
|
||||
{
|
||||
int ret=0;
|
||||
mas_pdata = kmalloc(sizeof(struct mas_platform_data), GFP_KERNEL);
|
||||
if (mas_pdata == NULL) {
|
||||
pr_info("%s:Failed to allocate buffer\n", __func__);
|
||||
ret=-ENOMEM;
|
||||
goto err_devm_kzalloc;
|
||||
goto fingeriprnt_err_devm_kzalloc;
|
||||
}
|
||||
ret = mas_get_of_pdata(&spi->dev);
|
||||
if(ret<0)
|
||||
goto get_of_pdata_err;
|
||||
goto fingeriprnt_get_of_pdata_err;
|
||||
|
||||
ret = mas_gpio_configure(true);
|
||||
if(ret<0)
|
||||
|
@ -484,26 +540,32 @@ int mas_qcm_platform_init(struct spi_device *spi)
|
|||
if(ret<0)
|
||||
goto fingeriprnt_power_err;
|
||||
|
||||
#ifndef USE_PLATFORM_DRIVE
|
||||
if (mas_ioctl_clk_init(spi, mas_pdata))
|
||||
goto fingeriprnt_power_err;
|
||||
|
||||
if (mas_ioctl_clk_enable(mas_pdata))
|
||||
goto fingeriprnt_clk_enable_failed;
|
||||
spi_clock_set(mas_pdata, 9600000);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
|
||||
#ifndef USE_PLATFORM_DRIVE
|
||||
fingeriprnt_clk_enable_failed:
|
||||
mas_ioctl_clk_uninit(mas_pdata);
|
||||
#endif
|
||||
fingeriprnt_power_err:
|
||||
//if(mas_pdata->vcc_io_l6)
|
||||
//regulator_put(mas_pdata->vcc_io_l6);
|
||||
fingeriprnt_gpio_configure_err:
|
||||
get_of_pdata_err:
|
||||
fingeriprnt_get_of_pdata_err:
|
||||
kfree(mas_pdata);
|
||||
err_devm_kzalloc:
|
||||
fingeriprnt_err_devm_kzalloc:
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef USE_PLATFORM_DRIVE
|
||||
void mas_enable_spi_clock(struct spi_device *spi)
|
||||
{
|
||||
mas_ioctl_clk_enable(mas_pdata);
|
||||
|
@ -513,19 +575,22 @@ void mas_disable_spi_clock(struct spi_device *spi)
|
|||
{
|
||||
mas_ioctl_clk_disable(mas_pdata);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
unsigned int mas_get_irq(void){
|
||||
unsigned int irq=0;
|
||||
irq = gpio_to_irq(mas_pdata->irq_gpio);
|
||||
if(irq)
|
||||
printk("mas_get_irq: %d\n",irq);
|
||||
mas_pdata->int_irq=irq;
|
||||
return irq;
|
||||
unsigned int irq=0;
|
||||
irq = gpio_to_irq(mas_pdata->irq_gpio);
|
||||
if(irq)
|
||||
printk("mas_get_irq: %d\n",irq);
|
||||
mas_pdata->int_irq=irq;
|
||||
return irq;
|
||||
}
|
||||
|
||||
|
||||
#ifdef USE_PLATFORM_DRIVE
|
||||
void mas_set_wakeup(struct platform_device *spi)
|
||||
#else
|
||||
void mas_set_wakeup(struct spi_device *spi)
|
||||
#endif
|
||||
{
|
||||
device_init_wakeup(&spi->dev, 1);
|
||||
}
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#include <linux/of_gpio.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include "madev.h"
|
||||
|
||||
//macro settings
|
||||
#define MA_DRV_NAME "madev"
|
||||
|
@ -53,10 +54,18 @@
|
|||
#define MA_DTS_NAME "mediatek,hct_finger"
|
||||
|
||||
#define MA_EINT_DTS_NAME "mediatek,hct_finger"
|
||||
|
||||
|
||||
//macro settings end
|
||||
|
||||
#ifdef USE_PLATFORM_DRIVE
|
||||
extern int mas_probe(struct platform_device *spi);
|
||||
extern int mas_remove(struct platform_device *spi);
|
||||
#else
|
||||
extern int mas_probe(struct spi_device *spi);
|
||||
extern int mas_remove(struct spi_device *spi);
|
||||
#endif
|
||||
|
||||
|
||||
/* add for spi cls ctl start */
|
||||
struct mt_spi_t {
|
||||
|
|
|
@ -143,14 +143,14 @@ static struct input_dev *aw9523b_input_dev = NULL;
|
|||
static struct i2c_client *g_client = NULL;
|
||||
|
||||
static const unsigned short key_array[Y_NUM][X_NUM] = {
|
||||
{ 0xFFFF, KEY_H, KEY_B, KEY_7, KEY_UP, KEY_ENTER, KEY_Y, KEY_COMMA },
|
||||
{ KEY_3, KEY_S, KEY_Z, KEY_M, KEY_I, KEY_9, KEY_W, KEY_J },
|
||||
{ KEY_LEFT, KEY_G, KEY_V, KEY_6, KEY_RIGHT, KEY_DELETE, KEY_T, KEY_DOT },
|
||||
{ KEY_SYM, KEY_A, KEY_RIGHTBRACE, KEY_HOMEPAGE, KEY_P, KEY_MINUS, KEY_Q, KEY_L },
|
||||
{ KEY_BACKSPACE, KEY_D, KEY_X, KEY_K, KEY_SEMICOLON, KEY_EQUAL, KEY_E, KEY_APOSTROPHE },
|
||||
{ KEY_CAPSLOCK, KEY_BACKSLASH, KEY_LEFTBRACE, KEY_DOWN, KEY_O, KEY_0, KEY_GRAVE, KEY_K },
|
||||
{ KEY_SPACE, KEY_F, KEY_C, KEY_N, KEY_U, KEY_8, KEY_R, KEY_5 },
|
||||
{ KEY_ESC, KEY_1, 0xFFFF, 0xFFFF, KEY_2, KEY_4, KEY_TAB, 0xFFFF }
|
||||
{ 0xFFFF, KEY_J, KEY_N, KEY_7, KEY_UP, KEY_ENTER, KEY_U, KEY_DOT },
|
||||
{ KEY_3, KEY_D, KEY_X, KEY_COMMA, KEY_O, KEY_9, KEY_E, KEY_K },
|
||||
{ KEY_LEFT, KEY_H, KEY_B, KEY_6, KEY_RIGHT, KEY_DELETE, KEY_Y, KEY_SLASH },
|
||||
{ KEY_SYM, KEY_S, KEY_Z, KEY_HOMEPAGE, KEY_LEFTBRACE, KEY_MINUS, KEY_W, KEY_SEMICOLON },
|
||||
{ KEY_BACKSPACE, KEY_F, KEY_C, 0xFFFF, KEY_RIGHTBRACE,KEY_EQUAL, KEY_R, KEY_APOSTROPHE },
|
||||
{ KEY_CAPSLOCK, KEY_A, KEY_GRAVE, KEY_DOWN, KEY_P, KEY_0, KEY_Q, KEY_L },
|
||||
{ KEY_SPACE, KEY_G, KEY_V, KEY_M, KEY_I, KEY_8, KEY_T, KEY_5 },
|
||||
{ KEY_ESC, KEY_1, 0xFFFF, 0xFFFF, KEY_2, KEY_4, KEY_TAB, 0xFFFF }
|
||||
};
|
||||
|
||||
// This macro sets the interval between polls of the key matrix for ghosted keys (in milliseconds).
|
||||
|
@ -1034,12 +1034,9 @@ static int aw9523b_check_dt(struct device_node *np)
|
|||
{
|
||||
int i;
|
||||
int count;
|
||||
|
||||
|
||||
struct device_node *node;
|
||||
struct drm_panel *panel;
|
||||
|
||||
|
||||
//需要在屏dts初始化后才能找到panel的字段
|
||||
count = of_count_phandle_with_args(np, "panel", NULL);
|
||||
|
||||
|
|
|
@ -42,12 +42,12 @@
|
|||
|
||||
|
||||
|
||||
//IIC的写地址,={1011,0,AD1,AD0,0},AD0,AD1接低则为0xB0 ,接高则是0xB6
|
||||
//IIC的写地址,={1011,0,AD1,AD0,0},AD0,AD1接低则为0xB0 ,接高则是0xB6
|
||||
#define IIC_ADDRESS_WRITE (0xB0) //0x58
|
||||
#define IIC_ADDRESS_READ (0xB1)
|
||||
|
||||
#define X_NUM (8) //列
|
||||
#define Y_NUM (8) //行
|
||||
#define X_NUM (8) //列
|
||||
#define Y_NUM (8) //行
|
||||
|
||||
//i2c tranfer ,repeat try times
|
||||
#define AW9523_I2C_MAX_LOOP (50)
|
||||
|
|
|
@ -77,3 +77,4 @@ obj-$(CONFIG_QTI_MAXIM_FAN_CONTROLLER) += max31760.o
|
|||
obj-$(CONFIG_QTI_XR_SMRTVWR_MISC) += qxr-stdalonevwr.o
|
||||
obj-$(CONFIG_FPR_FPC) += fpr_FingerprintCard/
|
||||
obj-y += qrc/
|
||||
obj-$(CONFIG_AW862XX_HAPTIC) += aw862xx_haptic/
|
||||
|
|
|
@ -5366,8 +5366,8 @@ int qseecom_process_listener_from_smcinvoke(struct scm_desc *desc)
|
|||
pr_err("Failed on cmd %d for lsnr %d session %d, ret = %d\n",
|
||||
(int)desc->ret[0], (int)desc->ret[2],
|
||||
(int)desc->ret[1], ret);
|
||||
desc->ret[0] = resp.resp_type;
|
||||
desc->ret[1] = resp.result;
|
||||
desc->ret[0] = resp.result;
|
||||
desc->ret[1] = resp.resp_type;
|
||||
desc->ret[2] = resp.data;
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ static void scm_disable_sdi(void);
|
|||
* There is no API from TZ to re-enable the registers.
|
||||
* So the SDI cannot be re-enabled when it already by-passed.
|
||||
*/
|
||||
static int download_mode = 0;
|
||||
static int download_mode = 1;
|
||||
static struct kobject dload_kobj;
|
||||
|
||||
static int in_panic;
|
||||
|
|
|
@ -374,8 +374,7 @@ int qg_get_battery_temp(struct qpnp_qg *chip, int *temp)
|
|||
pr_err("Failed reading BAT_TEMP over ADC rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
//pr_err("batt_temp = %d,by eric.wang\n", *temp);//by eric.wang
|
||||
//*temp = 250;
|
||||
pr_debug("batt_temp = %d\n", *temp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -3699,12 +3699,6 @@ static int smblib_get_prop_ufp_mode(struct smb_charger *chg)
|
|||
}
|
||||
smblib_dbg(chg, PR_REGISTER, "TYPE_C_STATUS_1 = 0x%02x\n", stat);
|
||||
|
||||
/* config 0x154A to 0x17 */
|
||||
if (stat & (SNK_RP_STD_DAM_BIT | SNK_RP_1P5_DAM_BIT | SNK_RP_3P0_DAM_BIT)){
|
||||
smblib_masked_write(chg, TYPE_C_DEBUG_ACCESS_SINK_REG,
|
||||
TYPEC_DEBUG_ACCESS_SINK_MASK, 0x17);
|
||||
}
|
||||
|
||||
switch (stat & DETECTED_SRC_TYPE_MASK) {
|
||||
case SNK_RP_STD_BIT:
|
||||
case SNK_RP_STD_DAM_BIT:
|
||||
|
@ -5628,10 +5622,6 @@ void smblib_usb_plugin_locked(struct smb_charger *chg)
|
|||
smblib_err(chg, "Couldn't disable DPDM rc=%d\n", rc);
|
||||
|
||||
smblib_update_usb_type(chg);
|
||||
|
||||
if(chg->use_extcon)
|
||||
smblib_notify_device_mode(chg,false);
|
||||
vote(chg->usb_icl_votable, USB_PSY_VOTER,false, 0);//remove USB_PSY voting when plugin detach
|
||||
}
|
||||
|
||||
if (chg->connector_type == POWER_SUPPLY_CONNECTOR_MICRO_USB)
|
||||
|
@ -5779,7 +5769,6 @@ static void update_sw_icl_max(struct smb_charger *chg, int pst)
|
|||
|
||||
/* TypeC rp med or high, use rp value */
|
||||
typec_mode = smblib_get_prop_typec_mode(chg);
|
||||
|
||||
if (typec_rp_med_high(chg, typec_mode)) {
|
||||
rp_ua = get_rp_based_dcp_current(chg, typec_mode);
|
||||
vote(chg->usb_icl_votable, SW_ICL_MAX_VOTER, true, rp_ua);
|
||||
|
@ -5834,6 +5823,7 @@ static void smblib_handle_apsd_done(struct smb_charger *chg, bool rising)
|
|||
return;
|
||||
|
||||
apsd_result = smblib_update_usb_type(chg);
|
||||
|
||||
update_sw_icl_max(chg, apsd_result->pst);
|
||||
|
||||
switch (apsd_result->bit) {
|
||||
|
@ -6400,6 +6390,7 @@ static void smblib_handle_rp_change(struct smb_charger *chg, int typec_mode)
|
|||
== FORCE_FLOAT_SDP_CFG_BIT)
|
||||
return;
|
||||
}
|
||||
|
||||
update_sw_icl_max(chg, apsd->pst);
|
||||
|
||||
smblib_dbg(chg, PR_MISC, "CC change old_mode=%d new_mode=%d\n",
|
||||
|
|
|
@ -3589,6 +3589,13 @@ static int msm_geni_serial_probe(struct platform_device *pdev)
|
|||
if (!uart_console(uport))
|
||||
spin_lock_init(&dev_port->rx_lock);
|
||||
|
||||
/*
|
||||
* Earlyconsole to kernel console will switch happen after
|
||||
* uart_add_one_port. Hence marking is_earlycon to false here.
|
||||
*/
|
||||
if (is_console)
|
||||
is_earlycon = false;
|
||||
|
||||
IPC_LOG_MSG(dev_port->ipc_log_misc, "%s: port:%s irq:%d\n", __func__,
|
||||
uport->name, uport->irq);
|
||||
|
||||
|
|
|
@ -1958,8 +1958,11 @@ char *pointer(const char *fmt, char *buf, char *end, void *ptr,
|
|||
return buf;
|
||||
}
|
||||
case 'K':
|
||||
/*
|
||||
if (!kptr_restrict ||
|
||||
IS_ENABLED(CONFIG_DEBUG_CONSOLE_UNHASHED_POINTERS))
|
||||
*/
|
||||
if (!kptr_restrict)
|
||||
break;
|
||||
return restricted_pointer(buf, end, ptr, spec);
|
||||
case 'N':
|
||||
|
|
|
@ -13,6 +13,10 @@ ifeq ($(CONFIG_ARCH_BENGAL), y)
|
|||
include $(srctree)/techpack/camera/config/bengalcamera.conf
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_KHAJE), y)
|
||||
include $(srctree)/techpack/camera/config/khajecamera.conf
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_KONA), y)
|
||||
LINUXINCLUDE += \
|
||||
-include $(srctree)/techpack/camera/config/konacameraconf.h
|
||||
|
@ -28,6 +32,11 @@ LINUXINCLUDE += \
|
|||
-include $(srctree)/techpack/camera/config/bengalcameraconf.h
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_ARCH_KHAJE), y)
|
||||
LINUXINCLUDE += \
|
||||
-include $(srctree)/techpack/camera/config/khajecameraconf.h
|
||||
endif
|
||||
|
||||
ifdef CONFIG_SPECTRA_CAMERA
|
||||
# Use USERINCLUDE when you must reference the UAPI directories only.
|
||||
USERINCLUDE += \
|
||||
|
|
6
techpack/camera/config/khajecamera.conf
Normal file
6
techpack/camera/config/khajecamera.conf
Normal file
|
@ -0,0 +1,6 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
# Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
|
||||
export CONFIG_SPECTRA_CAMERA_OPE=y
|
||||
export CONFIG_SPECTRA_CAMERA_TFE=y
|
||||
export CONFIG_SPECTRA_CAMERA_SENSOR=y
|
8
techpack/camera/config/khajecameraconf.h
Normal file
8
techpack/camera/config/khajecameraconf.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#define CONFIG_SPECTRA_CAMERA 1
|
||||
#define CONFIG_SPECTRA_CAMERA_OPE 1
|
||||
#define CONFIG_SPECTRA_CAMERA_TFE 1
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_CDM_H_
|
||||
|
@ -83,6 +83,7 @@
|
|||
#define CAM_CDM_RESET_HW_STATUS 0x4
|
||||
#define CAM_CDM_ERROR_HW_STATUS 0x5
|
||||
#define CAM_CDM_FLUSH_HW_STATUS 0x6
|
||||
#define CAM_CDM_RESET_ERR_STATUS 0x7
|
||||
|
||||
/* Curent BL command masks and shifts */
|
||||
#define CAM_CDM_CURRENT_BL_LEN 0xFFFFF
|
||||
|
@ -276,6 +277,7 @@ struct cam_cdm_common_reg_data {
|
|||
* wait, etc.
|
||||
* @core_en: offset to pause/enable CDM
|
||||
* @fe_cfg: offset to configure CDM fetch engine
|
||||
* @irq_context_status offset to read back irq context status
|
||||
* @bl_fifo_rb: offset to set BL_FIFO read back
|
||||
* @bl_fifo_base_rb: offset to read back base address on offset set by
|
||||
* bl_fifo_rb
|
||||
|
@ -319,6 +321,7 @@ struct cam_cdm_common_regs {
|
|||
uint32_t core_cfg;
|
||||
uint32_t core_en;
|
||||
uint32_t fe_cfg;
|
||||
uint32_t irq_context_status;
|
||||
uint32_t bl_fifo_rb;
|
||||
uint32_t bl_fifo_base_rb;
|
||||
uint32_t bl_fifo_len_rb;
|
||||
|
@ -374,6 +377,7 @@ enum cam_cdm_hw_process_intf_cmd {
|
|||
CAM_CDM_HW_INTF_CMD_FLUSH_HW,
|
||||
CAM_CDM_HW_INTF_CMD_HANDLE_ERROR,
|
||||
CAM_CDM_HW_INTF_CMD_HANG_DETECT,
|
||||
CAM_CDM_HW_INTF_DUMP_DBG_REGS,
|
||||
CAM_CDM_HW_INTF_CMD_INVALID,
|
||||
};
|
||||
|
||||
|
@ -415,6 +419,7 @@ enum cam_cdm_hw_version {
|
|||
CAM_CDM_VERSION_1_1 = 0x10010000,
|
||||
CAM_CDM_VERSION_1_2 = 0x10020000,
|
||||
CAM_CDM_VERSION_2_0 = 0x20000000,
|
||||
CAM_CDM_VERSION_2_1 = 0x20010000,
|
||||
CAM_CDM_VERSION_MAX,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
@ -49,6 +49,7 @@ bool cam_cdm_set_cam_hw_version(
|
|||
case CAM_CDM110_VERSION:
|
||||
case CAM_CDM120_VERSION:
|
||||
case CAM_CDM200_VERSION:
|
||||
case CAM_CDM210_VERSION:
|
||||
cam_version->major = (ver & 0xF0000000);
|
||||
cam_version->minor = (ver & 0xFFF0000);
|
||||
cam_version->incr = (ver & 0xFFFF);
|
||||
|
@ -81,6 +82,7 @@ struct cam_cdm_utils_ops *cam_cdm_get_ops(
|
|||
case CAM_CDM110_VERSION:
|
||||
case CAM_CDM120_VERSION:
|
||||
case CAM_CDM200_VERSION:
|
||||
case CAM_CDM210_VERSION:
|
||||
return &CDM170_ops;
|
||||
default:
|
||||
CAM_ERR(CAM_CDM, "CDM Version=%x not supported in util",
|
||||
|
@ -178,10 +180,12 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
|
|||
(struct cam_cdm_bl_cb_request_entry *)data;
|
||||
|
||||
client_idx = CAM_CDM_GET_CLIENT_IDX(node->client_hdl);
|
||||
mutex_lock(&cdm_hw->hw_mutex);
|
||||
client = core->clients[client_idx];
|
||||
if ((!client) || (client->handle != node->client_hdl)) {
|
||||
CAM_ERR(CAM_CDM, "Invalid client %pK hdl=%x", client,
|
||||
node->client_hdl);
|
||||
mutex_unlock(&cdm_hw->hw_mutex);
|
||||
return;
|
||||
}
|
||||
cam_cdm_get_client_refcount(client);
|
||||
|
@ -200,6 +204,7 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
|
|||
}
|
||||
mutex_unlock(&client->lock);
|
||||
cam_cdm_put_client_refcount(client);
|
||||
mutex_unlock(&cdm_hw->hw_mutex);
|
||||
return;
|
||||
} else if (status == CAM_CDM_CB_STATUS_HW_RESET_DONE ||
|
||||
status == CAM_CDM_CB_STATUS_HW_FLUSH ||
|
||||
|
@ -215,7 +220,7 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
|
|||
if ((!client) || (client->handle != node->client_hdl)) {
|
||||
CAM_ERR(CAM_CDM, "Invalid client %pK hdl=%x", client,
|
||||
node->client_hdl);
|
||||
return;
|
||||
return;
|
||||
}
|
||||
cam_cdm_get_client_refcount(client);
|
||||
mutex_lock(&client->lock);
|
||||
|
@ -237,6 +242,7 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
|
|||
|
||||
for (i = 0; i < CAM_PER_CDM_MAX_REGISTERED_CLIENTS; i++) {
|
||||
if (core->clients[i] != NULL) {
|
||||
mutex_lock(&cdm_hw->hw_mutex);
|
||||
client = core->clients[i];
|
||||
cam_cdm_get_client_refcount(client);
|
||||
mutex_lock(&client->lock);
|
||||
|
@ -259,6 +265,7 @@ void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
|
|||
}
|
||||
mutex_unlock(&client->lock);
|
||||
cam_cdm_put_client_refcount(client);
|
||||
mutex_unlock(&cdm_hw->hw_mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -318,35 +325,34 @@ int cam_cdm_stream_ops_internal(void *hw_priv,
|
|||
return -EINVAL;
|
||||
|
||||
core = (struct cam_cdm *)cdm_hw->core_info;
|
||||
mutex_lock(&cdm_hw->hw_mutex);
|
||||
client_idx = CAM_CDM_GET_CLIENT_IDX(*handle);
|
||||
client = core->clients[client_idx];
|
||||
if (!client) {
|
||||
CAM_ERR(CAM_CDM, "Invalid client %pK hdl=%x", client, *handle);
|
||||
mutex_unlock(&cdm_hw->hw_mutex);
|
||||
return -EINVAL;
|
||||
}
|
||||
cam_cdm_get_client_refcount(client);
|
||||
if (*handle != client->handle) {
|
||||
CAM_ERR(CAM_CDM, "client id given handle=%x invalid", *handle);
|
||||
cam_cdm_put_client_refcount(client);
|
||||
return -EINVAL;
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
if (operation == true) {
|
||||
if (true == client->stream_on) {
|
||||
CAM_ERR(CAM_CDM,
|
||||
"Invalid CDM client is already streamed ON");
|
||||
cam_cdm_put_client_refcount(client);
|
||||
return rc;
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
if (client->stream_on == false) {
|
||||
CAM_ERR(CAM_CDM,
|
||||
"Invalid CDM client is already streamed Off");
|
||||
cam_cdm_put_client_refcount(client);
|
||||
return rc;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_lock(&cdm_hw->hw_mutex);
|
||||
if (operation == true) {
|
||||
if (!cdm_hw->open_count) {
|
||||
struct cam_ahb_vote ahb_vote;
|
||||
|
@ -817,6 +823,22 @@ int cam_cdm_process_cmd(void *hw_priv,
|
|||
rc = cam_hw_cdm_hang_detect(cdm_hw, *handle);
|
||||
break;
|
||||
}
|
||||
case CAM_CDM_HW_INTF_DUMP_DBG_REGS:
|
||||
{
|
||||
uint32_t *handle = cmd_args;
|
||||
|
||||
if (sizeof(uint32_t) != arg_size) {
|
||||
CAM_ERR(CAM_CDM,
|
||||
"Invalid CDM cmd %d size=%x for handle=0x%x",
|
||||
cmd, arg_size, *handle);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
mutex_lock(&cdm_hw->hw_mutex);
|
||||
cam_hw_cdm_dump_core_debug_registers(cdm_hw, true);
|
||||
mutex_unlock(&cdm_hw->hw_mutex);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
CAM_ERR(CAM_CDM, "CDM HW intf command not valid =%d", cmd);
|
||||
break;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_CDM_CORE_COMMON_H_
|
||||
|
@ -12,6 +12,7 @@
|
|||
#define CAM_CDM110_VERSION 0x10010000
|
||||
#define CAM_CDM120_VERSION 0x10020000
|
||||
#define CAM_CDM200_VERSION 0x20000000
|
||||
#define CAM_CDM210_VERSION 0x20010000
|
||||
|
||||
#define CAM_CDM_AHB_BURST_LEN_1 (BIT(1) - 1)
|
||||
#define CAM_CDM_AHB_BURST_LEN_4 (BIT(2) - 1)
|
||||
|
@ -55,5 +56,7 @@ struct cam_cdm_bl_cb_request_entry *cam_cdm_find_request_by_bl_tag(
|
|||
uint32_t tag, struct list_head *bl_list);
|
||||
void cam_cdm_notify_clients(struct cam_hw_info *cdm_hw,
|
||||
enum cam_cdm_cb_status status, void *data);
|
||||
void cam_hw_cdm_dump_core_debug_registers(
|
||||
struct cam_hw_info *cdm_hw, bool pause_core);
|
||||
|
||||
#endif /* _CAM_CDM_CORE_COMMON_H_ */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
@ -22,6 +22,7 @@
|
|||
#include "cam_cdm_hw_reg_1_1.h"
|
||||
#include "cam_cdm_hw_reg_1_2.h"
|
||||
#include "cam_cdm_hw_reg_2_0.h"
|
||||
#include "cam_cdm_hw_reg_2_1.h"
|
||||
#include "cam_trace.h"
|
||||
#include "cam_req_mgr_workq.h"
|
||||
|
||||
|
@ -60,6 +61,19 @@ static const struct of_device_id msm_cam_hw_cdm_dt_match[] = {
|
|||
.compatible = CAM_HW_CDM_OPE_NAME_2_0,
|
||||
.data = &cam_cdm_2_0_reg_offset,
|
||||
},
|
||||
{
|
||||
.compatible = CAM_HW_CDM_CPAS_NAME_2_1,
|
||||
.data = &cam_cdm_2_1_reg_offset,
|
||||
},
|
||||
{
|
||||
.compatible = CAM_HW_CDM_OPE_NAME_2_1,
|
||||
.data = &cam_cdm_2_1_reg_offset,
|
||||
},
|
||||
{
|
||||
.compatible = CAM_HW_CDM_IFE_NAME_2_1,
|
||||
.data = &cam_cdm_2_1_reg_offset,
|
||||
},
|
||||
{},
|
||||
};
|
||||
|
||||
static enum cam_cdm_id cam_hw_cdm_get_id_by_name(char *name)
|
||||
|
@ -85,6 +99,15 @@ static enum cam_cdm_id cam_hw_cdm_get_id_by_name(char *name)
|
|||
if (strnstr(name, CAM_HW_CDM_OPE_NAME_2_0,
|
||||
strlen(CAM_HW_CDM_CPAS_NAME_2_0)))
|
||||
return CAM_CDM_OPE;
|
||||
if (strnstr(name, CAM_HW_CDM_CPAS_NAME_2_1,
|
||||
strlen(CAM_HW_CDM_CPAS_NAME_2_1)))
|
||||
return CAM_CDM_CPAS;
|
||||
if (strnstr(name, CAM_HW_CDM_OPE_NAME_2_1,
|
||||
strlen(CAM_HW_CDM_OPE_NAME_2_1)))
|
||||
return CAM_CDM_OPE;
|
||||
if (strnstr(name, CAM_HW_CDM_IFE_NAME_2_1,
|
||||
strlen(CAM_HW_CDM_IFE_NAME_2_1)))
|
||||
return CAM_CDM_IFE;
|
||||
|
||||
return CAM_CDM_MAX;
|
||||
}
|
||||
|
@ -147,14 +170,14 @@ static int cam_hw_cdm_pause_core(struct cam_hw_info *cdm_hw, bool pause)
|
|||
return rc;
|
||||
}
|
||||
|
||||
int cam_hw_cdm_enable_core_dbg(struct cam_hw_info *cdm_hw)
|
||||
int cam_hw_cdm_enable_core_dbg(struct cam_hw_info *cdm_hw, uint32_t value)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_cdm *core = (struct cam_cdm *)cdm_hw->core_info;
|
||||
|
||||
if (cam_cdm_write_hw_reg(cdm_hw,
|
||||
core->offsets->cmn_reg->core_debug,
|
||||
0x10100)) {
|
||||
value)) {
|
||||
CAM_ERR(CAM_CDM, "Failed to Write CDM HW core debug");
|
||||
rc = -EIO;
|
||||
}
|
||||
|
@ -241,24 +264,7 @@ int cam_hw_cdm_bl_fifo_pending_bl_rb_in_fifo(
|
|||
return rc;
|
||||
}
|
||||
|
||||
int cam_hw_cdm_enable_core_dbg_per_fifo(
|
||||
struct cam_hw_info *cdm_hw,
|
||||
uint32_t fifo_idx)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_cdm *core = (struct cam_cdm *)cdm_hw->core_info;
|
||||
|
||||
if (cam_cdm_write_hw_reg(cdm_hw,
|
||||
core->offsets->cmn_reg->core_debug,
|
||||
(0x10100 | fifo_idx << 20))) {
|
||||
CAM_ERR(CAM_CDM, "Failed to Write CDM HW core debug");
|
||||
rc = -EIO;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void cam_hw_cdm_dump_bl_fifo_data(struct cam_hw_info *cdm_hw)
|
||||
static void cam_hw_cdm_dump_bl_fifo_data(struct cam_hw_info *cdm_hw)
|
||||
{
|
||||
struct cam_cdm *core = (struct cam_cdm *)cdm_hw->core_info;
|
||||
int i, j;
|
||||
|
@ -267,13 +273,7 @@ void cam_hw_cdm_dump_bl_fifo_data(struct cam_hw_info *cdm_hw)
|
|||
for (i = 0; i < core->offsets->reg_data->num_bl_fifo; i++) {
|
||||
cam_hw_cdm_bl_fifo_pending_bl_rb_in_fifo(cdm_hw,
|
||||
i, &num_pending_req);
|
||||
|
||||
if (cam_hw_cdm_enable_core_dbg_per_fifo(cdm_hw, i)) {
|
||||
CAM_ERR(CAM_CDM,
|
||||
"Problem in selecting the fifo for readback");
|
||||
continue;
|
||||
}
|
||||
for (j = 0 ; j < num_pending_req ; j++) {
|
||||
for (j = 0; j < num_pending_req ; j++) {
|
||||
cam_cdm_write_hw_reg(cdm_hw,
|
||||
core->offsets->cmn_reg->bl_fifo_rb, j);
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
|
@ -294,89 +294,152 @@ void cam_hw_cdm_dump_bl_fifo_data(struct cam_hw_info *cdm_hw)
|
|||
}
|
||||
}
|
||||
|
||||
void cam_hw_cdm_dump_core_debug_registers(
|
||||
struct cam_hw_info *cdm_hw)
|
||||
void cam_hw_cdm_dump_core_debug_registers(struct cam_hw_info *cdm_hw,
|
||||
bool pause_core)
|
||||
{
|
||||
uint32_t dump_reg, core_dbg;
|
||||
uint32_t dump_reg[4], core_dbg = 0x100;
|
||||
int i;
|
||||
bool is_core_paused_already;
|
||||
struct cam_cdm *core = (struct cam_cdm *)cdm_hw->core_info;
|
||||
const struct cam_cdm_icl_regs *inv_cmd_log =
|
||||
core->offsets->cmn_reg->icl_reg;
|
||||
|
||||
cam_cdm_read_hw_reg(cdm_hw, core->offsets->cmn_reg->core_en, &dump_reg);
|
||||
CAM_INFO(CAM_CDM, "CDM HW core status=%x", dump_reg);
|
||||
cam_cdm_read_hw_reg(cdm_hw, core->offsets->cmn_reg->core_en,
|
||||
&dump_reg[0]);
|
||||
|
||||
if (pause_core) {
|
||||
cam_hw_cdm_pause_core(cdm_hw, true);
|
||||
usleep_range(1000, 1010);
|
||||
}
|
||||
cam_hw_cdm_enable_core_dbg(cdm_hw, core_dbg);
|
||||
|
||||
cam_cdm_read_hw_reg(cdm_hw, core->offsets->cmn_reg->usr_data,
|
||||
&dump_reg);
|
||||
CAM_INFO(CAM_CDM, "CDM HW core userdata=0x%x", dump_reg);
|
||||
|
||||
usleep_range(1000, 1010);
|
||||
&dump_reg[1]);
|
||||
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
core->offsets->cmn_reg->debug_status,
|
||||
&dump_reg);
|
||||
CAM_INFO(CAM_CDM, "CDM HW Debug status reg=%x", dump_reg);
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
core->offsets->cmn_reg->core_debug,
|
||||
&core_dbg);
|
||||
&dump_reg[2]);
|
||||
|
||||
CAM_INFO(CAM_CDM, "Core stat 0x%x udata 0x%x dbg_stat 0x%x",
|
||||
dump_reg[0], dump_reg[1], dump_reg[2]);
|
||||
|
||||
if (core_dbg & 0x100) {
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
core->offsets->cmn_reg->last_ahb_addr,
|
||||
&dump_reg);
|
||||
CAM_INFO(CAM_CDM, "AHB dump reglastaddr=%x", dump_reg);
|
||||
&dump_reg[0]);
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
core->offsets->cmn_reg->last_ahb_data,
|
||||
&dump_reg);
|
||||
CAM_INFO(CAM_CDM, "AHB dump reglastdata=%x", dump_reg);
|
||||
&dump_reg[1]);
|
||||
CAM_INFO(CAM_CDM, "AHB dump lastaddr=0x%x lastdata=0x%x",
|
||||
dump_reg[0], dump_reg[1]);
|
||||
} else {
|
||||
CAM_INFO(CAM_CDM, "CDM HW AHB dump not enable");
|
||||
}
|
||||
|
||||
cam_hw_cdm_dump_bl_fifo_data(cdm_hw);
|
||||
if (inv_cmd_log) {
|
||||
if (inv_cmd_log->misc_regs) {
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
inv_cmd_log->misc_regs->icl_status,
|
||||
&dump_reg[0]);
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
inv_cmd_log->misc_regs->icl_inv_bl_addr,
|
||||
&dump_reg[1]);
|
||||
CAM_INFO(CAM_CDM,
|
||||
"Last Inv Cmd Log(ICL)Status: 0x%x bl_addr: 0x%x",
|
||||
dump_reg[0], dump_reg[1]);
|
||||
}
|
||||
if (inv_cmd_log->data_regs) {
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
inv_cmd_log->data_regs->icl_inv_data,
|
||||
&dump_reg[0]);
|
||||
CAM_INFO(CAM_CDM, "First word of Last Inv cmd: 0x%x",
|
||||
dump_reg[0]);
|
||||
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
inv_cmd_log->data_regs->icl_last_data_0,
|
||||
&dump_reg[0]);
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
inv_cmd_log->data_regs->icl_last_data_1,
|
||||
&dump_reg[1]);
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
inv_cmd_log->data_regs->icl_last_data_2,
|
||||
&dump_reg[2]);
|
||||
|
||||
|
||||
CAM_INFO(CAM_CDM, "Last good cmd word 0x%x 0x%x 0x%x",
|
||||
dump_reg[0], dump_reg[1], dump_reg[2]);
|
||||
}
|
||||
}
|
||||
|
||||
if (core_dbg & 0x10000) {
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
core->offsets->cmn_reg->core_en, &dump_reg[0]);
|
||||
is_core_paused_already = (bool)(dump_reg[0] & 0x20);
|
||||
if (!is_core_paused_already) {
|
||||
cam_hw_cdm_pause_core(cdm_hw, true);
|
||||
usleep_range(1000, 1010);
|
||||
}
|
||||
|
||||
cam_hw_cdm_dump_bl_fifo_data(cdm_hw);
|
||||
|
||||
if (!is_core_paused_already)
|
||||
cam_hw_cdm_pause_core(cdm_hw, false);
|
||||
}
|
||||
|
||||
CAM_INFO(CAM_CDM, "CDM HW default dump");
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
core->offsets->cmn_reg->core_cfg, &dump_reg);
|
||||
CAM_INFO(CAM_CDM, "CDM HW core cfg=%x", dump_reg);
|
||||
core->offsets->cmn_reg->core_cfg, &dump_reg[0]);
|
||||
CAM_INFO(CAM_CDM, "CDM HW core cfg=0x%x", dump_reg[0]);
|
||||
|
||||
for (i = 0; i <
|
||||
core->offsets->reg_data->num_bl_fifo_irq;
|
||||
i++) {
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
core->offsets->irq_reg[i]->irq_status, &dump_reg);
|
||||
CAM_INFO(CAM_CDM, "CDM HW irq status%d=%x", i, dump_reg);
|
||||
|
||||
core->offsets->irq_reg[i]->irq_status, &dump_reg[0]);
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
core->offsets->irq_reg[i]->irq_set, &dump_reg);
|
||||
CAM_INFO(CAM_CDM, "CDM HW irq set%d=%x", i, dump_reg);
|
||||
|
||||
core->offsets->irq_reg[i]->irq_set, &dump_reg[1]);
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
core->offsets->irq_reg[i]->irq_mask, &dump_reg);
|
||||
CAM_INFO(CAM_CDM, "CDM HW irq mask%d=%x", i, dump_reg);
|
||||
|
||||
core->offsets->irq_reg[i]->irq_mask, &dump_reg[2]);
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
core->offsets->irq_reg[i]->irq_clear, &dump_reg);
|
||||
CAM_INFO(CAM_CDM, "CDM HW irq clear%d=%x", i, dump_reg);
|
||||
core->offsets->irq_reg[i]->irq_clear, &dump_reg[3]);
|
||||
|
||||
CAM_INFO(CAM_CDM,
|
||||
"cnt %d irq status 0x%x set 0x%x mask 0x%x clear 0x%x",
|
||||
i, dump_reg[0], dump_reg[1], dump_reg[2], dump_reg[3]);
|
||||
}
|
||||
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
core->offsets->cmn_reg->current_bl_base, &dump_reg);
|
||||
CAM_INFO(CAM_CDM, "CDM HW current BL base=%x", dump_reg);
|
||||
core->offsets->cmn_reg->current_bl_base, &dump_reg[0]);
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
core->offsets->cmn_reg->current_used_ahb_base, &dump_reg[1]);
|
||||
CAM_INFO(CAM_CDM, "curr BL base 0x%x AHB base 0x%x",
|
||||
dump_reg[0], dump_reg[1]);
|
||||
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
core->offsets->cmn_reg->current_bl_len, &dump_reg);
|
||||
core->offsets->cmn_reg->wait_status, &dump_reg[0]);
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
core->offsets->cmn_reg->comp_wait[0]->comp_wait_status,
|
||||
&dump_reg[1]);
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
core->offsets->cmn_reg->comp_wait[1]->comp_wait_status,
|
||||
&dump_reg[2]);
|
||||
CAM_INFO(CAM_CDM, "wait status 0x%x comp wait status 0x%x: 0x%x",
|
||||
dump_reg[0], dump_reg[1], dump_reg[2]);
|
||||
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
core->offsets->cmn_reg->current_bl_len, &dump_reg[0]);
|
||||
CAM_INFO(CAM_CDM,
|
||||
"CDM HW current BL len=%d ARB %d FIFO %d tag=%d, ",
|
||||
(dump_reg & CAM_CDM_CURRENT_BL_LEN),
|
||||
(dump_reg & CAM_CDM_CURRENT_BL_ARB) >>
|
||||
(dump_reg[0] & CAM_CDM_CURRENT_BL_LEN),
|
||||
(dump_reg[0] & CAM_CDM_CURRENT_BL_ARB) >>
|
||||
CAM_CDM_CURRENT_BL_ARB_SHIFT,
|
||||
(dump_reg & CAM_CDM_CURRENT_BL_FIFO) >>
|
||||
(dump_reg[0] & CAM_CDM_CURRENT_BL_FIFO) >>
|
||||
CAM_CDM_CURRENT_BL_FIFO_SHIFT,
|
||||
(dump_reg & CAM_CDM_CURRENT_BL_TAG) >>
|
||||
(dump_reg[0] & CAM_CDM_CURRENT_BL_TAG) >>
|
||||
CAM_CDM_CURRENT_BL_TAG_SHIFT);
|
||||
|
||||
cam_cdm_read_hw_reg(cdm_hw,
|
||||
core->offsets->cmn_reg->current_used_ahb_base, &dump_reg);
|
||||
CAM_INFO(CAM_CDM, "CDM HW current AHB base=%x", dump_reg);
|
||||
|
||||
cam_hw_cdm_disable_core_dbg(cdm_hw);
|
||||
if (pause_core)
|
||||
cam_hw_cdm_pause_core(cdm_hw, false);
|
||||
}
|
||||
|
||||
enum cam_cdm_arbitration cam_cdm_get_arbitration_type(
|
||||
|
@ -1084,11 +1147,15 @@ static void cam_hw_cdm_reset_cleanup(
|
|||
int i;
|
||||
struct cam_cdm_bl_cb_request_entry *node, *tnode;
|
||||
bool flush_hw = false;
|
||||
bool reset_err = false;
|
||||
|
||||
if (test_bit(CAM_CDM_ERROR_HW_STATUS, &core->cdm_status) ||
|
||||
test_bit(CAM_CDM_FLUSH_HW_STATUS, &core->cdm_status))
|
||||
flush_hw = true;
|
||||
|
||||
if (test_bit(CAM_CDM_ERROR_HW_STATUS, &core->cdm_status))
|
||||
reset_err = true;
|
||||
|
||||
for (i = 0; i < core->offsets->reg_data->num_bl_fifo; i++) {
|
||||
list_for_each_entry_safe(node, tnode,
|
||||
&core->bl_fifo[i].bl_request_list, entry) {
|
||||
|
@ -1097,12 +1164,19 @@ static void cam_hw_cdm_reset_cleanup(
|
|||
CAM_DBG(CAM_CDM,
|
||||
"Notifying client %d for tag %d",
|
||||
node->client_hdl, node->bl_tag);
|
||||
if (flush_hw)
|
||||
if (flush_hw) {
|
||||
enum cam_cdm_cb_status status;
|
||||
|
||||
status = reset_err ?
|
||||
CAM_CDM_CB_STATUS_HW_ERROR :
|
||||
CAM_CDM_CB_STATUS_HW_RESUBMIT;
|
||||
|
||||
cam_cdm_notify_clients(cdm_hw,
|
||||
(node->client_hdl == handle) ?
|
||||
CAM_CDM_CB_STATUS_HW_FLUSH :
|
||||
CAM_CDM_CB_STATUS_HW_RESUBMIT,
|
||||
status,
|
||||
(void *)node);
|
||||
}
|
||||
else
|
||||
cam_cdm_notify_clients(cdm_hw,
|
||||
CAM_CDM_CB_STATUS_HW_RESET_DONE,
|
||||
|
@ -1245,7 +1319,7 @@ static void cam_hw_cdm_work(struct work_struct *work)
|
|||
* to dump debug info
|
||||
*/
|
||||
cam_hw_cdm_pause_core(cdm_hw, true);
|
||||
cam_hw_cdm_dump_core_debug_registers(cdm_hw);
|
||||
cam_hw_cdm_dump_core_debug_registers(cdm_hw, true);
|
||||
|
||||
if (payload->irq_status &
|
||||
CAM_CDM_IRQ_STATUS_ERROR_INV_CMD_MASK) {
|
||||
|
@ -1284,6 +1358,8 @@ static void cam_hw_cdm_work(struct work_struct *work)
|
|||
CAM_CDM_IRQ_STATUS_ERROR_INV_CMD_MASK))
|
||||
clear_bit(CAM_CDM_ERROR_HW_STATUS,
|
||||
&core->cdm_status);
|
||||
} else {
|
||||
CAM_ERR(CAM_CDM, "NULL payload");
|
||||
}
|
||||
kfree(payload);
|
||||
payload = NULL;
|
||||
|
@ -1306,16 +1382,8 @@ static void cam_hw_cdm_iommu_fault_handler(struct iommu_domain *domain,
|
|||
for (i = 0; i < core->offsets->reg_data->num_bl_fifo; i++)
|
||||
mutex_lock(&core->bl_fifo[i].fifo_lock);
|
||||
if (cdm_hw->hw_state == CAM_HW_STATE_POWER_UP) {
|
||||
/*
|
||||
* First pause CDM, If it fails still proceed
|
||||
* to dump debug info
|
||||
*/
|
||||
cam_hw_cdm_pause_core(cdm_hw, true);
|
||||
cam_hw_cdm_dump_core_debug_registers(cdm_hw);
|
||||
/* Resume CDM back */
|
||||
cam_hw_cdm_pause_core(cdm_hw, false);
|
||||
}
|
||||
else
|
||||
cam_hw_cdm_dump_core_debug_registers(cdm_hw, true);
|
||||
} else
|
||||
CAM_INFO(CAM_CDM, "CDM hw is power in off state");
|
||||
for (i = 0; i < core->offsets->reg_data->num_bl_fifo; i++)
|
||||
mutex_unlock(&core->bl_fifo[i].fifo_lock);
|
||||
|
@ -1338,17 +1406,28 @@ irqreturn_t cam_hw_cdm_irq(int irq_num, void *data)
|
|||
struct cam_cdm_work_payload *payload[CAM_CDM_BL_FIFO_MAX] = {0};
|
||||
uint32_t user_data = 0;
|
||||
uint32_t irq_status[CAM_CDM_BL_FIFO_MAX] = {0};
|
||||
uint32_t irq_context_summary = 0xF;
|
||||
bool work_status;
|
||||
int i;
|
||||
|
||||
CAM_DBG(CAM_CDM, "Got irq");
|
||||
CAM_DBG(CAM_CDM, "Got irq hw_version 0x%x", cdm_core->hw_version);
|
||||
spin_lock(&cdm_hw->hw_lock);
|
||||
if (cdm_hw->hw_state == CAM_HW_STATE_POWER_DOWN) {
|
||||
CAM_DBG(CAM_CDM, "CDM is in power down state");
|
||||
spin_unlock(&cdm_hw->hw_lock);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
if (cdm_core->hw_version >= CAM_CDM_VERSION_2_1) {
|
||||
if (cam_cdm_read_hw_reg(cdm_hw,
|
||||
cdm_core->offsets->cmn_reg->irq_context_status,
|
||||
&irq_context_summary)) {
|
||||
CAM_ERR(CAM_CDM, "Failed to read CDM HW IRQ status");
|
||||
}
|
||||
}
|
||||
for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo_irq; i++) {
|
||||
if (!(BIT(i) & irq_context_summary))
|
||||
continue;
|
||||
|
||||
if (cam_cdm_read_hw_reg(cdm_hw,
|
||||
cdm_core->offsets->irq_reg[i]->irq_status,
|
||||
&irq_status[i])) {
|
||||
|
@ -1613,7 +1692,7 @@ int cam_hw_cdm_handle_error_info(
|
|||
current_fifo, current_tag);
|
||||
|
||||
/* dump cdm registers for further debug */
|
||||
cam_hw_cdm_dump_core_debug_registers(cdm_hw);
|
||||
cam_hw_cdm_dump_core_debug_registers(cdm_hw, false);
|
||||
|
||||
for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo; i++) {
|
||||
reset_val = reset_val |
|
||||
|
@ -1639,7 +1718,7 @@ int cam_hw_cdm_handle_error_info(
|
|||
if (time_left <= 0) {
|
||||
rc = -ETIMEDOUT;
|
||||
CAM_ERR(CAM_CDM, "CDM HW reset Wait failed rc=%d", rc);
|
||||
goto end;
|
||||
set_bit(CAM_CDM_RESET_ERR_STATUS, &cdm_core->cdm_status);
|
||||
}
|
||||
|
||||
rc = cam_hw_cdm_set_cdm_core_cfg(cdm_hw);
|
||||
|
@ -1678,6 +1757,7 @@ int cam_hw_cdm_handle_error_info(
|
|||
end:
|
||||
clear_bit(CAM_CDM_FLUSH_HW_STATUS, &cdm_core->cdm_status);
|
||||
clear_bit(CAM_CDM_RESET_HW_STATUS, &cdm_core->cdm_status);
|
||||
clear_bit(CAM_CDM_RESET_ERR_STATUS, &cdm_core->cdm_status);
|
||||
for (i = 0; i < cdm_core->offsets->reg_data->num_bl_fifo; i++)
|
||||
mutex_unlock(&cdm_core->bl_fifo[i].fifo_lock);
|
||||
|
||||
|
|
253
techpack/camera/drivers/cam_cdm/cam_cdm_hw_reg_2_1.h
Normal file
253
techpack/camera/drivers/cam_cdm/cam_cdm_hw_reg_2_1.h
Normal file
|
@ -0,0 +1,253 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "cam_cdm.h"
|
||||
|
||||
struct cam_cdm_bl_pending_req_reg_params cdm_hw_2_1_bl_pending_req0 = {
|
||||
.rb_offset = 0x6c,
|
||||
.rb_mask = 0x1ff,
|
||||
.rb_num_fifo = 0x2,
|
||||
.rb_next_fifo_shift = 0x10,
|
||||
};
|
||||
|
||||
struct cam_cdm_bl_pending_req_reg_params cdm_hw_2_1_bl_pending_req1 = {
|
||||
.rb_offset = 0x70,
|
||||
.rb_mask = 0x1ff,
|
||||
.rb_num_fifo = 0x2,
|
||||
.rb_next_fifo_shift = 0x10,
|
||||
};
|
||||
|
||||
static struct cam_cdm_irq_regs cdm_hw_2_1_irq0 = {
|
||||
.irq_mask = 0x30,
|
||||
.irq_clear = 0x34,
|
||||
.irq_clear_cmd = 0x38,
|
||||
.irq_set = 0x3c,
|
||||
.irq_set_cmd = 0x40,
|
||||
.irq_status = 0x44,
|
||||
};
|
||||
|
||||
static struct cam_cdm_irq_regs cdm_hw_2_1_irq1 = {
|
||||
.irq_mask = 0x130,
|
||||
.irq_clear = 0x134,
|
||||
.irq_clear_cmd = 0x138,
|
||||
.irq_set = 0x13c,
|
||||
.irq_set_cmd = 0x140,
|
||||
.irq_status = 0x144,
|
||||
};
|
||||
|
||||
static struct cam_cdm_irq_regs cdm_hw_2_1_irq2 = {
|
||||
.irq_mask = 0x230,
|
||||
.irq_clear = 0x234,
|
||||
.irq_clear_cmd = 0x238,
|
||||
.irq_set = 0x23c,
|
||||
.irq_set_cmd = 0x240,
|
||||
.irq_status = 0x244,
|
||||
};
|
||||
|
||||
static struct cam_cdm_irq_regs cdm_hw_2_1_irq3 = {
|
||||
.irq_mask = 0x330,
|
||||
.irq_clear = 0x334,
|
||||
.irq_clear_cmd = 0x338,
|
||||
.irq_set = 0x33c,
|
||||
.irq_set_cmd = 0x340,
|
||||
.irq_status = 0x344,
|
||||
};
|
||||
|
||||
static struct cam_cdm_bl_fifo_regs cdm_hw_2_1_bl_fifo0 = {
|
||||
.bl_fifo_base = 0x50,
|
||||
.bl_fifo_len = 0x54,
|
||||
.bl_fifo_store = 0x58,
|
||||
.bl_fifo_cfg = 0x5c,
|
||||
};
|
||||
|
||||
static struct cam_cdm_bl_fifo_regs cdm_hw_2_1_bl_fifo1 = {
|
||||
.bl_fifo_base = 0x150,
|
||||
.bl_fifo_len = 0x154,
|
||||
.bl_fifo_store = 0x158,
|
||||
.bl_fifo_cfg = 0x15c,
|
||||
};
|
||||
|
||||
static struct cam_cdm_bl_fifo_regs cdm_hw_2_1_bl_fifo2 = {
|
||||
.bl_fifo_base = 0x250,
|
||||
.bl_fifo_len = 0x254,
|
||||
.bl_fifo_store = 0x258,
|
||||
.bl_fifo_cfg = 0x25c,
|
||||
};
|
||||
|
||||
static struct cam_cdm_bl_fifo_regs cdm_hw_2_1_bl_fifo3 = {
|
||||
.bl_fifo_base = 0x350,
|
||||
.bl_fifo_len = 0x354,
|
||||
.bl_fifo_store = 0x358,
|
||||
.bl_fifo_cfg = 0x35c,
|
||||
};
|
||||
|
||||
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg0 = {
|
||||
.scratch_reg = 0x90,
|
||||
};
|
||||
|
||||
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg1 = {
|
||||
.scratch_reg = 0x94,
|
||||
};
|
||||
|
||||
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg2 = {
|
||||
.scratch_reg = 0x98,
|
||||
};
|
||||
|
||||
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg3 = {
|
||||
.scratch_reg = 0x9c,
|
||||
};
|
||||
|
||||
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg4 = {
|
||||
.scratch_reg = 0xa0,
|
||||
};
|
||||
|
||||
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg5 = {
|
||||
.scratch_reg = 0xa4,
|
||||
};
|
||||
|
||||
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg6 = {
|
||||
.scratch_reg = 0xa8,
|
||||
};
|
||||
|
||||
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg7 = {
|
||||
.scratch_reg = 0xac,
|
||||
};
|
||||
|
||||
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg8 = {
|
||||
.scratch_reg = 0xb0,
|
||||
};
|
||||
|
||||
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg9 = {
|
||||
.scratch_reg = 0xb4,
|
||||
};
|
||||
|
||||
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg10 = {
|
||||
.scratch_reg = 0xb8,
|
||||
};
|
||||
|
||||
static struct cam_cdm_scratch_reg cdm_2_1_scratch_reg11 = {
|
||||
.scratch_reg = 0xbc,
|
||||
};
|
||||
|
||||
static struct cam_cdm_perf_mon_regs cdm_2_1_perf_mon0 = {
|
||||
.perf_mon_ctrl = 0x110,
|
||||
.perf_mon_0 = 0x114,
|
||||
.perf_mon_1 = 0x118,
|
||||
.perf_mon_2 = 0x11c,
|
||||
};
|
||||
|
||||
static struct cam_cdm_perf_mon_regs cdm_2_1_perf_mon1 = {
|
||||
.perf_mon_ctrl = 0x120,
|
||||
.perf_mon_0 = 0x124,
|
||||
.perf_mon_1 = 0x128,
|
||||
.perf_mon_2 = 0x12c,
|
||||
};
|
||||
|
||||
static struct cam_cdm_comp_wait_status cdm_2_1_comp_wait_status0 = {
|
||||
.comp_wait_status = 0x88,
|
||||
};
|
||||
|
||||
static struct cam_cdm_comp_wait_status cdm_2_1_comp_wait_status1 = {
|
||||
.comp_wait_status = 0x8c,
|
||||
};
|
||||
|
||||
static struct cam_cdm_icl_data_regs cdm_2_1_icl_data = {
|
||||
.icl_last_data_0 = 0x1c0,
|
||||
.icl_last_data_1 = 0x1c4,
|
||||
.icl_last_data_2 = 0x1c8,
|
||||
.icl_inv_data = 0x1cc,
|
||||
};
|
||||
|
||||
static struct cam_cdm_icl_misc_regs cdm_2_1_icl_misc = {
|
||||
.icl_inv_bl_addr = 0x1d0,
|
||||
.icl_status = 0x1d8,
|
||||
};
|
||||
|
||||
static struct cam_cdm_icl_regs cdm_2_1_icl = {
|
||||
.data_regs = &cdm_2_1_icl_data,
|
||||
.misc_regs = &cdm_2_1_icl_misc,
|
||||
};
|
||||
|
||||
static struct cam_cdm_common_regs cdm_hw_2_1_cmn_reg_offset = {
|
||||
.cdm_hw_version = 0x0,
|
||||
.cam_version = NULL,
|
||||
.rst_cmd = 0x10,
|
||||
.cgc_cfg = 0x14,
|
||||
.core_cfg = 0x18,
|
||||
.core_en = 0x1c,
|
||||
.fe_cfg = 0x20,
|
||||
.irq_context_status = 0x2c,
|
||||
.bl_fifo_rb = 0x60,
|
||||
.bl_fifo_base_rb = 0x64,
|
||||
.bl_fifo_len_rb = 0x68,
|
||||
.usr_data = 0x80,
|
||||
.wait_status = 0x84,
|
||||
.last_ahb_addr = 0xd0,
|
||||
.last_ahb_data = 0xd4,
|
||||
.core_debug = 0xd8,
|
||||
.last_ahb_err_addr = 0xe0,
|
||||
.last_ahb_err_data = 0xe4,
|
||||
.current_bl_base = 0xe8,
|
||||
.current_bl_len = 0xec,
|
||||
.current_used_ahb_base = 0xf0,
|
||||
.debug_status = 0xf4,
|
||||
.bus_misr_cfg0 = 0x100,
|
||||
.bus_misr_cfg1 = 0x104,
|
||||
.bus_misr_rd_val = 0x108,
|
||||
.pending_req = {
|
||||
&cdm_hw_2_1_bl_pending_req0,
|
||||
&cdm_hw_2_1_bl_pending_req1,
|
||||
},
|
||||
.comp_wait = {
|
||||
&cdm_2_1_comp_wait_status0,
|
||||
&cdm_2_1_comp_wait_status1,
|
||||
},
|
||||
.perf_mon = {
|
||||
&cdm_2_1_perf_mon0,
|
||||
&cdm_2_1_perf_mon1,
|
||||
},
|
||||
.scratch = {
|
||||
&cdm_2_1_scratch_reg0,
|
||||
&cdm_2_1_scratch_reg1,
|
||||
&cdm_2_1_scratch_reg2,
|
||||
&cdm_2_1_scratch_reg3,
|
||||
&cdm_2_1_scratch_reg4,
|
||||
&cdm_2_1_scratch_reg5,
|
||||
&cdm_2_1_scratch_reg6,
|
||||
&cdm_2_1_scratch_reg7,
|
||||
&cdm_2_1_scratch_reg8,
|
||||
&cdm_2_1_scratch_reg9,
|
||||
&cdm_2_1_scratch_reg10,
|
||||
&cdm_2_1_scratch_reg11,
|
||||
},
|
||||
.perf_reg = NULL,
|
||||
.icl_reg = &cdm_2_1_icl,
|
||||
.spare = 0x3fc,
|
||||
};
|
||||
|
||||
static struct cam_cdm_common_reg_data cdm_hw_2_1_cmn_reg_data = {
|
||||
.num_bl_fifo = 0x4,
|
||||
.num_bl_fifo_irq = 0x4,
|
||||
.num_bl_pending_req_reg = 0x2,
|
||||
.num_scratch_reg = 0xc,
|
||||
};
|
||||
|
||||
struct cam_cdm_hw_reg_offset cam_cdm_2_1_reg_offset = {
|
||||
.cmn_reg = &cdm_hw_2_1_cmn_reg_offset,
|
||||
.bl_fifo_reg = {
|
||||
&cdm_hw_2_1_bl_fifo0,
|
||||
&cdm_hw_2_1_bl_fifo1,
|
||||
&cdm_hw_2_1_bl_fifo2,
|
||||
&cdm_hw_2_1_bl_fifo3,
|
||||
},
|
||||
.irq_reg = {
|
||||
&cdm_hw_2_1_irq0,
|
||||
&cdm_hw_2_1_irq1,
|
||||
&cdm_hw_2_1_irq2,
|
||||
&cdm_hw_2_1_irq3,
|
||||
},
|
||||
.reg_data = &cdm_hw_2_1_cmn_reg_data,
|
||||
};
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
@ -506,6 +506,32 @@ int cam_cdm_detect_hang_error(uint32_t handle)
|
|||
}
|
||||
EXPORT_SYMBOL(cam_cdm_detect_hang_error);
|
||||
|
||||
int cam_cdm_dump_debug_registers(uint32_t handle)
|
||||
{
|
||||
uint32_t hw_index;
|
||||
int rc = -EINVAL;
|
||||
struct cam_hw_intf *hw;
|
||||
|
||||
if (get_cdm_mgr_refcount()) {
|
||||
CAM_ERR(CAM_CDM, "CDM intf mgr get refcount failed");
|
||||
rc = -EPERM;
|
||||
return rc;
|
||||
}
|
||||
|
||||
hw_index = CAM_CDM_GET_HW_IDX(handle);
|
||||
if (hw_index < CAM_CDM_INTF_MGR_MAX_SUPPORTED_CDM) {
|
||||
hw = cdm_mgr.nodes[hw_index].device;
|
||||
if (hw && hw->hw_ops.process_cmd)
|
||||
rc = hw->hw_ops.process_cmd(hw->hw_priv,
|
||||
CAM_CDM_HW_INTF_DUMP_DBG_REGS,
|
||||
&handle,
|
||||
sizeof(handle));
|
||||
}
|
||||
put_cdm_mgr_refcount();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_cdm_intf_register_hw_cdm(struct cam_hw_intf *hw,
|
||||
struct cam_cdm_private_dt_data *data, enum cam_cdm_type type,
|
||||
uint32_t *index)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_CDM_API_H_
|
||||
|
@ -296,4 +296,13 @@ struct cam_cdm_utils_ops *cam_cdm_publish_ops(void);
|
|||
* @return 0 on success
|
||||
*/
|
||||
int cam_cdm_detect_hang_error(uint32_t handle);
|
||||
|
||||
/**
|
||||
* @brief : API to dump the CDM Debug registers
|
||||
*
|
||||
* @handle : Input handle of the CDM to dump the registers
|
||||
*
|
||||
* @return 0 on success
|
||||
*/
|
||||
int cam_cdm_dump_debug_registers(uint32_t handle);
|
||||
#endif /* _CAM_CDM_API_H_ */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_CDM_SOC_H_
|
||||
|
@ -13,6 +13,9 @@
|
|||
#define CAM_HW_CDM_IFE_NAME_1_2 "qcom,cam-ife-cdm1_2"
|
||||
#define CAM_HW_CDM_CPAS_NAME_2_0 "qcom,cam-cpas-cdm2_0"
|
||||
#define CAM_HW_CDM_OPE_NAME_2_0 "qcom,cam-ope-cdm2_0"
|
||||
#define CAM_HW_CDM_CPAS_NAME_2_1 "qcom,cam-cpas-cdm2_1"
|
||||
#define CAM_HW_CDM_OPE_NAME_2_1 "qcom,cam-ope-cdm2_1"
|
||||
#define CAM_HW_CDM_IFE_NAME_2_1 "qcom,cam-ife-cdm2_1"
|
||||
|
||||
int cam_hw_cdm_soc_get_dt_properties(struct cam_hw_info *cdm_hw,
|
||||
const struct of_device_id *table);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
|
@ -529,6 +529,10 @@ int cam_cpas_get_custom_dt_info(struct cam_hw_info *cpas_hw,
|
|||
(u32 *)&soc_private->camnoc_axi_min_ib_bw);
|
||||
}
|
||||
|
||||
soc_private->custom_id = 0;
|
||||
rc = of_property_read_u32(of_node,
|
||||
"custom-id",
|
||||
&soc_private->custom_id);
|
||||
if (rc) {
|
||||
CAM_DBG(CAM_CPAS,
|
||||
"failed to read camnoc-axi-min-ib-bw rc:%d", rc);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021 The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_CPAS_SOC_H_
|
||||
|
@ -109,6 +109,8 @@ struct cam_cpas_feature_info {
|
|||
* @feature_info: fuse based feature info for hw supported features
|
||||
* @cx_ipeak_gpu_limit: Flag for Cx Ipeak GPU mitigation
|
||||
* @gpu_pwr_limit: Handle for Cx Ipeak GPU Mitigation
|
||||
* @custom_id: Custom id to differentiate between target if
|
||||
* cpas version is same
|
||||
*
|
||||
*/
|
||||
struct cam_cpas_private_soc {
|
||||
|
@ -129,6 +131,7 @@ struct cam_cpas_private_soc {
|
|||
struct cam_cpas_feature_info feature_info[CAM_CPAS_MAX_FUSE_FEATURE];
|
||||
uint32_t cx_ipeak_gpu_limit;
|
||||
struct kgsl_pwr_limit *gpu_pwr_limit;
|
||||
uint32_t custom_id;
|
||||
};
|
||||
|
||||
void cam_cpas_util_debug_parse_data(struct cam_cpas_private_soc *soc_private);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
@ -24,6 +24,7 @@
|
|||
#include "cpastop_v480_100.h"
|
||||
#include "cpastop_v540_100.h"
|
||||
#include "cpastop_v520_100.h"
|
||||
#include "cpastop_v545_110_518.h"
|
||||
#include "cam_req_mgr_workq.h"
|
||||
|
||||
struct cam_camnoc_info *camnoc_info;
|
||||
|
@ -133,6 +134,14 @@ static int cam_cpastop_get_hw_info(struct cam_hw_info *cpas_hw,
|
|||
(hw_caps->camera_version.minor == 2) &&
|
||||
(hw_caps->camera_version.incr == 0)) {
|
||||
soc_info->hw_version = CAM_CPAS_TITAN_520_V100;
|
||||
} else if ((hw_caps->camera_version.major == 5) &&
|
||||
(hw_caps->camera_version.minor == 4) &&
|
||||
(hw_caps->camera_version.incr == 5)) {
|
||||
if ((hw_caps->cpas_version.major == 1) &&
|
||||
(hw_caps->cpas_version.minor == 1) &&
|
||||
(hw_caps->cpas_version.incr == 0)) {
|
||||
soc_info->hw_version = CAM_CPAS_TITAN_545_V110;
|
||||
}
|
||||
}
|
||||
|
||||
CAM_DBG(CAM_CPAS, "CPAS HW VERSION %x", soc_info->hw_version);
|
||||
|
@ -605,6 +614,7 @@ static int cam_cpastop_init_hw_version(struct cam_hw_info *cpas_hw,
|
|||
{
|
||||
int rc = 0;
|
||||
struct cam_hw_soc_info *soc_info = &cpas_hw->soc_info;
|
||||
struct cam_cpas_private_soc *soc_private;
|
||||
|
||||
CAM_DBG(CAM_CPAS,
|
||||
"hw_version=0x%x Camera Version %d.%d.%d, cpas version %d.%d.%d",
|
||||
|
@ -647,6 +657,12 @@ static int cam_cpastop_init_hw_version(struct cam_hw_info *cpas_hw,
|
|||
case CAM_CPAS_TITAN_520_V100:
|
||||
camnoc_info = &cam520_cpas100_camnoc_info;
|
||||
break;
|
||||
case CAM_CPAS_TITAN_545_V110:
|
||||
soc_private = (struct cam_cpas_private_soc *)
|
||||
soc_info->soc_private;
|
||||
if (soc_private->custom_id == CAM_CPAS_TITAN_SOC_ID_518)
|
||||
camnoc_info = &cam545_cpas110_socid518_camnoc_info;
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_CPAS, "Camera Version not supported %d.%d.%d",
|
||||
hw_caps->camera_version.major,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_CPASTOP_HW_H_
|
||||
|
@ -107,6 +107,8 @@ enum cam_camnoc_hw_irq_type {
|
|||
* @CAM_CAMNOC_FD: Indicates FD HW connection to camnoc
|
||||
* @CAM_CAMNOC_ICP: Indicates ICP HW connection to camnoc
|
||||
* @CAM_CAMNOC_TFE: Indicates TFE HW connection to camnoc
|
||||
* @CAM_CAMNOC_TFE_1 : Indicates TFE1 HW connection to camnoc
|
||||
* @CAM_CAMNOC_TFE_2 : Indicates TFE2 HW connection to camnoc
|
||||
* @CAM_CAMNOC_OPE: Indicates OPE HW connection to camnoc
|
||||
*/
|
||||
enum cam_camnoc_port_type {
|
||||
|
@ -131,6 +133,8 @@ enum cam_camnoc_port_type {
|
|||
CAM_CAMNOC_FD,
|
||||
CAM_CAMNOC_ICP,
|
||||
CAM_CAMNOC_TFE,
|
||||
CAM_CAMNOC_TFE_1,
|
||||
CAM_CAMNOC_TFE_2,
|
||||
CAM_CAMNOC_OPE,
|
||||
};
|
||||
|
||||
|
|
320
techpack/camera/drivers/cam_cpas/cpas_top/cpastop_v545_110_518.h
Normal file
320
techpack/camera/drivers/cam_cpas/cpas_top/cpastop_v545_110_518.h
Normal file
|
@ -0,0 +1,320 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CPASTOP_V545_110_518_H_
|
||||
#define _CPASTOP_V545_110_518_H_
|
||||
|
||||
#define TEST_IRQ_ENABLE 0
|
||||
|
||||
static struct cam_camnoc_irq_sbm cam_cpas_v545_110_socid518_irq_sbm = {
|
||||
.sbm_enable = {
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.enable = true,
|
||||
.offset = 0xA40, /* SBM_FAULTINEN0_LOW */
|
||||
.value = 0x1 | /* SBM_FAULTINEN0_LOW_PORT0_MASK*/
|
||||
(TEST_IRQ_ENABLE ?
|
||||
0x2 : /* SBM_FAULTINEN0_LOW_PORT6_MASK */
|
||||
0x0) /* SBM_FAULTINEN0_LOW_PORT1_MASK */,
|
||||
},
|
||||
.sbm_status = {
|
||||
.access_type = CAM_REG_TYPE_READ,
|
||||
.enable = true,
|
||||
.offset = 0xA48, /* SBM_FAULTINSTATUS0_LOW */
|
||||
},
|
||||
.sbm_clear = {
|
||||
.access_type = CAM_REG_TYPE_WRITE,
|
||||
.enable = true,
|
||||
.offset = 0xA80, /* SBM_FLAGOUTCLR0_LOW */
|
||||
.value = TEST_IRQ_ENABLE ? 0x3 : 0x1,
|
||||
}
|
||||
};
|
||||
|
||||
static struct cam_camnoc_irq_err
|
||||
cam_cpas_v545_110_socid518_irq_err[] = {
|
||||
{
|
||||
.irq_type = CAM_CAMNOC_HW_IRQ_SLAVE_ERROR,
|
||||
.enable = true,
|
||||
.sbm_port = 0x1, /* SBM_FAULTINSTATUS0_LOW_PORT0_MASK */
|
||||
.err_enable = {
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.enable = true,
|
||||
.offset = 0xD08, /* ERRORLOGGER_MAINCTL_LOW */
|
||||
.value = 1,
|
||||
},
|
||||
.err_status = {
|
||||
.access_type = CAM_REG_TYPE_READ,
|
||||
.enable = true,
|
||||
.offset = 0xD10, /* ERRORLOGGER_ERRVLD_LOW */
|
||||
},
|
||||
.err_clear = {
|
||||
.access_type = CAM_REG_TYPE_WRITE,
|
||||
.enable = true,
|
||||
.offset = 0xD18, /* ERRORLOGGER_ERRCLR_LOW */
|
||||
.value = 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
.irq_type = CAM_CAMNOC_HW_IRQ_CAMNOC_TEST,
|
||||
.enable = TEST_IRQ_ENABLE ? true : false,
|
||||
.sbm_port = 0x2, /* SBM_FAULTINSTATUS0_LOW_PORT6_MASK */
|
||||
.err_enable = {
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.enable = true,
|
||||
.offset = 0xA88, /* SBM_FLAGOUTSET0_LOW */
|
||||
.value = 0x1,
|
||||
},
|
||||
.err_status = {
|
||||
.access_type = CAM_REG_TYPE_READ,
|
||||
.enable = true,
|
||||
.offset = 0xA90, /* SBM_FLAGOUTSTATUS0_LOW */
|
||||
},
|
||||
.err_clear = {
|
||||
.enable = false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
static struct cam_camnoc_specific
|
||||
cam_cpas_v545_110_socid518_camnoc_specific[] = {
|
||||
{
|
||||
.port_type = CAM_CAMNOC_CDM,
|
||||
.enable = true,
|
||||
.priority_lut_low = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0xE30, /* CDM_PRIORITYLUT_LOW */
|
||||
.value = 0x33333333,
|
||||
},
|
||||
.priority_lut_high = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0xE34, /* CDM_PRIORITYLUT_HIGH */
|
||||
.value = 0x33333333,
|
||||
},
|
||||
.urgency = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0xE38, /* CDM_URGENCY_LOW */
|
||||
.value = 0x00000003,
|
||||
},
|
||||
.danger_lut = {
|
||||
.enable = false,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0xE40, /* CDM_DANGERLUT_LOW */
|
||||
.value = 0x0,
|
||||
},
|
||||
.safe_lut = {
|
||||
.enable = false,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0xE48, /* CDM_SAFELUT_LOW */
|
||||
.value = 0x0,
|
||||
},
|
||||
.ubwc_ctl = {
|
||||
.enable = false,
|
||||
},
|
||||
},
|
||||
{
|
||||
.port_type = CAM_CAMNOC_TFE,
|
||||
.enable = true,
|
||||
.priority_lut_low = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
/* TFE_PRIORITYLUT_LOW */
|
||||
.offset = 0x30,
|
||||
.value = 0x44443333,
|
||||
},
|
||||
.priority_lut_high = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
/* TFE_PRIORITYLUT_HIGH */
|
||||
.offset = 0x34,
|
||||
.value = 0x66665555,
|
||||
},
|
||||
.urgency = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0x38, /* TFE_URGENCY_LOW */
|
||||
.value = 0x00001030,
|
||||
},
|
||||
.danger_lut = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.offset = 0x40, /* TFE_DANGERLUT_LOW */
|
||||
.value = 0xFFFF0000,
|
||||
},
|
||||
.safe_lut = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.offset = 0x48, /* TFE_SAFELUT_LOW */
|
||||
.value = 0x00000003,
|
||||
},
|
||||
.ubwc_ctl = {
|
||||
/*
|
||||
* Do not explicitly set ubwc config register.
|
||||
* Power on default values are taking care of required
|
||||
* register settings.
|
||||
*/
|
||||
.enable = false,
|
||||
},
|
||||
},
|
||||
{
|
||||
.port_type = CAM_CAMNOC_TFE_1,
|
||||
.enable = true,
|
||||
.priority_lut_low = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
/* TFE_PRIORITYLUT_LOW */
|
||||
.offset = 0x4030,
|
||||
.value = 0x44443333,
|
||||
},
|
||||
.priority_lut_high = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
/* TFE_PRIORITYLUT_HIGH */
|
||||
.offset = 0x4034,
|
||||
.value = 0x66665555,
|
||||
},
|
||||
.urgency = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0x4038, /* TFE_URGENCY_LOW */
|
||||
.value = 0x00001030,
|
||||
},
|
||||
.danger_lut = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.offset = 0x4040, /* TFE_DANGERLUT_LOW */
|
||||
.value = 0xFFFF0000,
|
||||
},
|
||||
.safe_lut = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.offset = 0x4048, /* TFE_SAFELUT_LOW */
|
||||
.value = 0x00000003,
|
||||
},
|
||||
},
|
||||
{
|
||||
.port_type = CAM_CAMNOC_TFE_2,
|
||||
.enable = true,
|
||||
.priority_lut_low = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
/* TFE_PRIORITYLUT_LOW */
|
||||
.offset = 0x5030,
|
||||
.value = 0x44443333,
|
||||
},
|
||||
.priority_lut_high = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
/* TFE_PRIORITYLUT_HIGH */
|
||||
.offset = 0x5034,
|
||||
.value = 0x66665555,
|
||||
},
|
||||
.urgency = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0x5038, /* TFE_URGENCY_LOW */
|
||||
.value = 0x00001030,
|
||||
},
|
||||
.danger_lut = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.offset = 0x5040, /* TFE_DANGERLUT_LOW */
|
||||
.value = 0xFFFF0000,
|
||||
},
|
||||
.safe_lut = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.offset = 0x5048, /* TFE_SAFELUT_LOW */
|
||||
.value = 0x00000003,
|
||||
},
|
||||
},
|
||||
{
|
||||
.port_type = CAM_CAMNOC_OPE,
|
||||
.enable = true,
|
||||
.priority_lut_low = {
|
||||
.enable = false,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0x430, /* OPE_PRIORITYLUT_LOW */
|
||||
.value = 0x33333333,
|
||||
},
|
||||
.priority_lut_high = {
|
||||
.enable = false,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.masked_value = 0,
|
||||
.offset = 0x434, /* OPE_PRIORITYLUT_HIGH */
|
||||
.value = 0x33333333,
|
||||
},
|
||||
.urgency = {
|
||||
.enable = true,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.offset = 0x438, /* OPE_URGENCY_LOW */
|
||||
.value = 0x00000033,
|
||||
},
|
||||
.danger_lut = {
|
||||
.enable = false,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.offset = 0x440, /* OPE_DANGERLUT_LOW */
|
||||
.value = 0xFFFFFF00,
|
||||
},
|
||||
.safe_lut = {
|
||||
.enable = false,
|
||||
.access_type = CAM_REG_TYPE_READ_WRITE,
|
||||
.offset = 0x448, /* OPE_SAFELUT_LOW */
|
||||
.value = 0xF,
|
||||
},
|
||||
.ubwc_ctl = {
|
||||
/*
|
||||
* Do not explicitly set ubwc config register.
|
||||
* Power on default values are taking care of required
|
||||
* register settings.
|
||||
*/
|
||||
.enable = false,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct cam_camnoc_err_logger_info
|
||||
cam545_cpas110_socid518_err_logger_offsets = {
|
||||
.mainctrl = 0xD08, /* ERRLOGGER_MAINCTL_LOW */
|
||||
.errvld = 0xD10, /* ERRLOGGER_ERRVLD_LOW */
|
||||
.errlog0_low = 0xD20, /* ERRLOGGER_ERRLOG0_LOW */
|
||||
.errlog0_high = 0xD24, /* ERRLOGGER_ERRLOG0_HIGH */
|
||||
.errlog1_low = 0xD28, /* ERRLOGGER_ERRLOG1_LOW */
|
||||
.errlog1_high = 0xD2C, /* ERRLOGGER_ERRLOG1_HIGH */
|
||||
.errlog2_low = 0xD30, /* ERRLOGGER_ERRLOG2_LOW */
|
||||
.errlog2_high = 0xD34, /* ERRLOGGER_ERRLOG2_HIGH */
|
||||
.errlog3_low = 0xD38, /* ERRLOGGER_ERRLOG3_LOW */
|
||||
.errlog3_high = 0xD3C, /* ERRLOGGER_ERRLOG3_HIGH */
|
||||
};
|
||||
|
||||
static struct cam_camnoc_info cam545_cpas110_socid518_camnoc_info = {
|
||||
.specific = &cam_cpas_v545_110_socid518_camnoc_specific[0],
|
||||
.specific_size =
|
||||
ARRAY_SIZE(cam_cpas_v545_110_socid518_camnoc_specific),
|
||||
.irq_sbm = &cam_cpas_v545_110_socid518_irq_sbm,
|
||||
.irq_err = &cam_cpas_v545_110_socid518_irq_err[0],
|
||||
.irq_err_size = ARRAY_SIZE(cam_cpas_v545_110_socid518_irq_err),
|
||||
.err_logger = &cam545_cpas110_socid518_err_logger_offsets,
|
||||
.errata_wa_list = NULL,
|
||||
};
|
||||
|
||||
#endif /* _CPASTOP_V545_110_518_H_ */
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_CPAS_API_H_
|
||||
|
@ -48,9 +48,19 @@ enum cam_cpas_hw_version {
|
|||
CAM_CPAS_TITAN_480_V100 = 0x480100,
|
||||
CAM_CPAS_TITAN_540_V100 = 0x540100,
|
||||
CAM_CPAS_TITAN_520_V100 = 0x520100,
|
||||
CAM_CPAS_TITAN_545_V110 = 0x545110,
|
||||
CAM_CPAS_TITAN_MAX
|
||||
};
|
||||
|
||||
/**
|
||||
* enum cam_cpas_hw_soc_id - Enum for Titan soc id
|
||||
*/
|
||||
enum cam_cpas_hw_soc_id {
|
||||
CAM_CPAS_TITAN_SOC_ID_507 = 507,
|
||||
CAM_CPAS_TITAN_SOC_ID_518 = 518,
|
||||
CAM_CPAS_TITAN_SOC_ID_MAX
|
||||
};
|
||||
|
||||
/**
|
||||
* enum cam_camnoc_irq_type - Enum for camnoc irq types
|
||||
*
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
|
@ -3066,6 +3066,7 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_applied(
|
|||
ctx_isp->frame_id,
|
||||
ctx->ctx_id);
|
||||
ctx->ctx_crm_intf->notify_err(¬ify);
|
||||
atomic_set(&ctx_isp->process_bubble, 1);
|
||||
} else {
|
||||
req_isp->bubble_report = 0;
|
||||
}
|
||||
|
@ -3123,6 +3124,44 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_state(
|
|||
ctx_isp->boot_timestamp = sof_event_data->boot_time;
|
||||
CAM_DBG(CAM_ISP, "frame id: %lld time stamp:0x%llx",
|
||||
ctx_isp->frame_id, ctx_isp->sof_timestamp_val);
|
||||
|
||||
|
||||
if (atomic_read(&ctx_isp->process_bubble)) {
|
||||
if (list_empty(&ctx->active_req_list)) {
|
||||
CAM_ERR(CAM_ISP, "No available active req in bubble");
|
||||
atomic_set(&ctx_isp->process_bubble, 0);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (ctx_isp->last_sof_timestamp ==
|
||||
ctx_isp->sof_timestamp_val) {
|
||||
CAM_DBG(CAM_ISP,
|
||||
"Tasklet delay detected! Bubble frame: %lld check skipped, sof_timestamp: %lld, ctx_id: %d",
|
||||
ctx_isp->frame_id,
|
||||
ctx_isp->sof_timestamp_val,
|
||||
ctx->ctx_id);
|
||||
goto end;
|
||||
}
|
||||
|
||||
req = list_first_entry(&ctx->active_req_list,
|
||||
struct cam_ctx_request, list);
|
||||
req_isp = (struct cam_isp_ctx_req *) req->req_priv;
|
||||
|
||||
if (req_isp->bubble_detected) {
|
||||
req_isp->num_acked = 0;
|
||||
req_isp->bubble_detected = false;
|
||||
list_del_init(&req->list);
|
||||
list_add(&req->list, &ctx->pending_req_list);
|
||||
atomic_set(&ctx_isp->process_bubble, 0);
|
||||
ctx_isp->active_req_cnt--;
|
||||
CAM_DBG(CAM_REQ,
|
||||
"Move active req: %lld to pending list(cnt = %d) [bubble re-apply],ctx %u",
|
||||
req->request_id,
|
||||
ctx_isp->active_req_cnt, ctx->ctx_id);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Signal all active requests with error and move the all the active
|
||||
* requests to free list
|
||||
|
@ -3144,6 +3183,7 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_state(
|
|||
ctx_isp->active_req_cnt--;
|
||||
}
|
||||
|
||||
end:
|
||||
/* notify reqmgr with sof signal */
|
||||
if (ctx->ctx_crm_intf && ctx->ctx_crm_intf->notify_trigger) {
|
||||
notify.link_hdl = ctx->link_hdl;
|
||||
|
@ -3174,6 +3214,7 @@ static int __cam_isp_ctx_rdi_only_sof_in_bubble_state(
|
|||
__cam_isp_ctx_substate_val_to_type(
|
||||
ctx_isp->substate_activated));
|
||||
|
||||
ctx_isp->last_sof_timestamp = ctx_isp->sof_timestamp_val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3426,6 +3467,7 @@ static int __cam_isp_ctx_release_hw_in_top_state(struct cam_context *ctx,
|
|||
ctx_isp->hw_acquired = false;
|
||||
ctx_isp->init_received = false;
|
||||
ctx_isp->req_info.last_bufdone_req_id = 0;
|
||||
ctx_isp->last_sof_timestamp = 0;
|
||||
|
||||
atomic64_set(&ctx_isp->state_monitor_head, -1);
|
||||
|
||||
|
@ -3490,6 +3532,7 @@ static int __cam_isp_ctx_release_dev_in_top_state(struct cam_context *ctx,
|
|||
ctx_isp->init_received = false;
|
||||
ctx_isp->rdi_only_context = false;
|
||||
ctx_isp->req_info.last_bufdone_req_id = 0;
|
||||
ctx_isp->last_sof_timestamp = 0;
|
||||
|
||||
atomic64_set(&ctx_isp->state_monitor_head, -1);
|
||||
for (i = 0; i < CAM_ISP_CTX_EVENT_MAX; i++)
|
||||
|
@ -3830,6 +3873,7 @@ static int __cam_isp_ctx_acquire_dev_in_available(struct cam_context *ctx,
|
|||
ctx_isp->hw_acquired = true;
|
||||
ctx_isp->split_acquire = false;
|
||||
ctx->ctxt_to_hw_map = param.ctxt_to_hw_map;
|
||||
ctx_isp->last_sof_timestamp = 0;
|
||||
|
||||
atomic64_set(&ctx_isp->state_monitor_head, -1);
|
||||
for (i = 0; i < CAM_ISP_CTX_EVENT_MAX; i++)
|
||||
|
@ -3987,6 +4031,7 @@ static int __cam_isp_ctx_acquire_hw_v1(struct cam_context *ctx,
|
|||
ctx_isp->hw_ctx = param.ctxt_to_hw_map;
|
||||
ctx_isp->hw_acquired = true;
|
||||
ctx->ctxt_to_hw_map = param.ctxt_to_hw_map;
|
||||
ctx_isp->last_sof_timestamp = 0;
|
||||
|
||||
atomic64_set(&ctx_isp->state_monitor_head, -1);
|
||||
|
||||
|
@ -4132,6 +4177,7 @@ static int __cam_isp_ctx_acquire_hw_v2(struct cam_context *ctx,
|
|||
ctx_isp->hw_ctx = param.ctxt_to_hw_map;
|
||||
ctx_isp->hw_acquired = true;
|
||||
ctx->ctxt_to_hw_map = param.ctxt_to_hw_map;
|
||||
ctx_isp->last_sof_timestamp = 0;
|
||||
|
||||
trace_cam_context_state("ISP", ctx);
|
||||
CAM_DBG(CAM_ISP,
|
||||
|
@ -4390,9 +4436,11 @@ static int __cam_isp_ctx_start_dev_in_ready(struct cam_context *ctx,
|
|||
/* HW failure. user need to clean up the resource */
|
||||
CAM_ERR(CAM_ISP, "Start HW failed");
|
||||
ctx->state = CAM_CTX_READY;
|
||||
trace_cam_context_state("ISP", ctx);
|
||||
if (rc == -ETIMEDOUT)
|
||||
if ((rc == -ETIMEDOUT) &&
|
||||
(isp_ctx_debug.enable_cdm_cmd_buff_dump))
|
||||
rc = cam_isp_ctx_dump_req(req_isp, 0, 0, NULL, false);
|
||||
|
||||
trace_cam_context_state("ISP", ctx);
|
||||
list_del_init(&req->list);
|
||||
list_add(&req->list, &ctx->pending_req_list);
|
||||
goto end;
|
||||
|
@ -4953,8 +5001,15 @@ static int cam_isp_context_debug_register(void)
|
|||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
if (!debugfs_create_u32("enable_cdm_cmd_buffer_dump",
|
||||
0644,
|
||||
isp_ctx_debug.dentry,
|
||||
&isp_ctx_debug.enable_cdm_cmd_buff_dump)) {
|
||||
CAM_ERR(CAM_ISP, "failed to create enable_cdm_cmd_buffer_dump");
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
debugfs_remove_recursive(isp_ctx_debug.dentry);
|
||||
return -ENOMEM;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_ISP_CONTEXT_H_
|
||||
|
@ -110,13 +110,15 @@ enum cam_isp_state_change_trigger {
|
|||
/**
|
||||
* struct cam_isp_ctx_debug - Contains debug parameters
|
||||
*
|
||||
* @dentry: Debugfs entry
|
||||
* @enable_state_monitor_dump: Enable isp state monitor dump
|
||||
* @dentry: Debugfs entry
|
||||
* @enable_state_monitor_dump: Enable isp state monitor dump
|
||||
* @enable_cdm_cmd_buff_dump: Enable CDM Command buffer dump
|
||||
*
|
||||
*/
|
||||
struct cam_isp_ctx_debug {
|
||||
struct dentry *dentry;
|
||||
uint32_t enable_state_monitor_dump;
|
||||
uint32_t enable_cdm_cmd_buff_dump;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -232,6 +234,7 @@ struct cam_isp_context_event_record {
|
|||
* @req_isp: ISP private request object storage
|
||||
* @hw_ctx: HW object returned by the acquire device command
|
||||
* @sof_timestamp_val: Captured time stamp value at sof hw event
|
||||
* @last_sof_timestamp: Time stamp value for last SOF event
|
||||
* @boot_timestamp: Boot time stamp for a given req_id
|
||||
* @active_req_cnt: Counter for the active request
|
||||
* @reported_req_id: Last reported request id
|
||||
|
@ -268,6 +271,7 @@ struct cam_isp_context {
|
|||
|
||||
void *hw_ctx;
|
||||
uint64_t sof_timestamp_val;
|
||||
uint64_t last_sof_timestamp;
|
||||
uint64_t boot_timestamp;
|
||||
int32_t active_req_cnt;
|
||||
int64_t reported_req_id;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
|
@ -2971,6 +2971,17 @@ static int cam_tfe_mgr_start_hw(void *hw_mgr_priv, void *start_hw_args)
|
|||
sizeof(g_tfe_hw_mgr.debug_cfg.csid_debug));
|
||||
}
|
||||
|
||||
/* set tpg debug information for top tpg */
|
||||
for (i = 0; i < CAM_TOP_TPG_HW_NUM_MAX; i++) {
|
||||
if (g_tfe_hw_mgr.tpg_devices[i]) {
|
||||
rc = g_tfe_hw_mgr.tpg_devices[i]->hw_ops.process_cmd(
|
||||
g_tfe_hw_mgr.tpg_devices[i]->hw_priv,
|
||||
CAM_ISP_HW_CMD_TPG_SET_PATTERN,
|
||||
&g_tfe_hw_mgr.debug_cfg.set_tpg_pattern,
|
||||
sizeof(g_tfe_hw_mgr.debug_cfg.set_tpg_pattern));
|
||||
}
|
||||
}
|
||||
|
||||
camif_debug = g_tfe_hw_mgr.debug_cfg.camif_debug;
|
||||
list_for_each_entry(hw_mgr_res, &ctx->res_list_tfe_in, list) {
|
||||
for (i = 0; i < CAM_ISP_HW_SPLIT_MAX; i++) {
|
||||
|
@ -5450,6 +5461,7 @@ DEFINE_DEBUGFS_ATTRIBUTE(cam_tfe_camif_debug,
|
|||
|
||||
static int cam_tfe_hw_mgr_debug_register(void)
|
||||
{
|
||||
g_tfe_hw_mgr.debug_cfg.set_tpg_pattern = CAM_TOP_TPG_DEFAULT_PATTERN;
|
||||
g_tfe_hw_mgr.debug_cfg.dentry = debugfs_create_dir("camera_tfe",
|
||||
NULL);
|
||||
|
||||
|
@ -5482,6 +5494,14 @@ static int cam_tfe_hw_mgr_debug_register(void)
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (!debugfs_create_u32("set_tpg_pattern",
|
||||
0644,
|
||||
g_tfe_hw_mgr.debug_cfg.dentry,
|
||||
&g_tfe_hw_mgr.debug_cfg.set_tpg_pattern)) {
|
||||
CAM_ERR(CAM_ISP, "failed to create set_tpg_pattern");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!debugfs_create_u32("enable_reg_dump",
|
||||
0644,
|
||||
g_tfe_hw_mgr.debug_cfg.dentry,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_TFE_HW_MGR_H_
|
||||
|
@ -30,6 +30,7 @@
|
|||
* @enable_recovery: enable recovery
|
||||
* @enable_csid_recovery: enable csid recovery
|
||||
* @camif_debug: enable sensor diagnosis status
|
||||
* @set_tpg_pattern: tpg pattern information
|
||||
* @enable_reg_dump: enable reg dump on error;
|
||||
* @per_req_reg_dump: Enable per request reg dump
|
||||
*
|
||||
|
@ -40,6 +41,7 @@ struct cam_tfe_hw_mgr_debug {
|
|||
uint32_t enable_recovery;
|
||||
uint32_t enable_csid_recovery;
|
||||
uint32_t camif_debug;
|
||||
uint32_t set_tpg_pattern;
|
||||
uint32_t enable_reg_dump;
|
||||
uint32_t per_req_reg_dump;
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <media/cam_defs.h>
|
||||
|
@ -140,6 +140,14 @@ static int cam_isp_update_dual_config(
|
|||
}
|
||||
|
||||
hw_mgr_res = &res_list_isp_out[i];
|
||||
if (!hw_mgr_res) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"Invalid isp out resource i %d num_out_res %d",
|
||||
i, dual_config->num_ports);
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
for (j = 0; j < CAM_ISP_HW_SPLIT_MAX; j++) {
|
||||
if (!hw_mgr_res->hw_res[j])
|
||||
continue;
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
obj-$(CONFIG_SPECTRA_CAMERA) += top_tpg/
|
||||
|
||||
ifdef CONFIG_SPECTRA_CAMERA_TFE
|
||||
obj-$(CONFIG_SPECTRA_CAMERA) += ppi_hw/
|
||||
obj-$(CONFIG_SPECTRA_CAMERA) += tfe_csid_hw/ tfe_hw/
|
||||
endif
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_ISP_HW_H_
|
||||
|
@ -114,6 +114,7 @@ enum cam_isp_hw_cmd_type {
|
|||
CAM_ISP_HW_CMD_TPG_PHY_CLOCK_UPDATE,
|
||||
CAM_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP,
|
||||
CAM_ISP_HW_CMD_DUMP_HW,
|
||||
CAM_ISP_HW_CMD_TPG_SET_PATTERN,
|
||||
CAM_ISP_HW_CMD_MAX,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_TOP_TPG_HW_INTF_H_
|
||||
|
@ -13,7 +13,8 @@
|
|||
#define CAM_TOP_TPG_HW_NUM_MAX 2
|
||||
/* Max supported number of DT for TPG */
|
||||
#define CAM_TOP_TPG_MAX_SUPPORTED_DT 4
|
||||
|
||||
/* TPG default pattern should be color bar */
|
||||
#define CAM_TOP_TPG_DEFAULT_PATTERN 0x8
|
||||
/**
|
||||
* enum cam_top_tpg_id - top tpg hw instance id
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_utils
|
||||
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_core
|
||||
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_cdm/
|
||||
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_cpas/include
|
||||
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_isp/isp_hw_mgr/include
|
||||
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_isp/isp_hw_mgr/hw_utils/include
|
||||
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_isp/isp_hw_mgr/hw_utils/irq_controller
|
||||
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/include
|
||||
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_smmu/
|
||||
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_req_mgr/
|
||||
|
||||
obj-$(CONFIG_SPECTRA_CAMERA) += cam_csid_ppi_dev.o cam_csid_ppi_core.o cam_csid_ppi100.o
|
|
@ -0,0 +1,50 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019, 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include "cam_csid_ppi_core.h"
|
||||
#include "cam_csid_ppi100.h"
|
||||
#include "cam_csid_ppi_dev.h"
|
||||
|
||||
#define CAM_PPI_DRV_NAME "ppi_100"
|
||||
#define CAM_PPI_VERSION_V100 0x10000000
|
||||
|
||||
static struct cam_csid_ppi_hw_info cam_csid_ppi100_hw_info = {
|
||||
.ppi_reg = &cam_csid_ppi_100_reg_offset,
|
||||
};
|
||||
|
||||
static const struct of_device_id cam_csid_ppi100_dt_match[] = {
|
||||
{
|
||||
.compatible = "qcom,ppi100",
|
||||
.data = &cam_csid_ppi100_hw_info,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, cam_csid_ppi100_dt_match);
|
||||
|
||||
static struct platform_driver cam_csid_ppi100_driver = {
|
||||
.probe = cam_csid_ppi_probe,
|
||||
.remove = cam_csid_ppi_remove,
|
||||
.driver = {
|
||||
.name = CAM_PPI_DRV_NAME,
|
||||
.of_match_table = cam_csid_ppi100_dt_match,
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init cam_csid_ppi100_init_module(void)
|
||||
{
|
||||
return platform_driver_register(&cam_csid_ppi100_driver);
|
||||
}
|
||||
|
||||
static void __exit cam_csid_ppi100_exit_module(void)
|
||||
{
|
||||
platform_driver_unregister(&cam_csid_ppi100_driver);
|
||||
}
|
||||
|
||||
module_init(cam_csid_ppi100_init_module);
|
||||
MODULE_DESCRIPTION("CAM CSID_PPI100 driver");
|
||||
MODULE_LICENSE("GPL v2");
|
|
@ -0,0 +1,25 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2019, 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_CSID_PPI_100_H_
|
||||
#define _CAM_CSID_PPI_100_H_
|
||||
|
||||
#include "cam_csid_ppi_core.h"
|
||||
|
||||
static struct cam_csid_ppi_reg_offset cam_csid_ppi_100_reg_offset = {
|
||||
.ppi_hw_version_addr = 0,
|
||||
.ppi_module_cfg_addr = 0x60,
|
||||
.ppi_irq_status_addr = 0x68,
|
||||
.ppi_irq_mask_addr = 0x6c,
|
||||
.ppi_irq_set_addr = 0x70,
|
||||
.ppi_irq_clear_addr = 0x74,
|
||||
.ppi_irq_cmd_addr = 0x78,
|
||||
.ppi_rst_cmd_addr = 0x7c,
|
||||
.ppi_test_bus_ctrl_addr = 0x1f4,
|
||||
.ppi_debug_addr = 0x1f8,
|
||||
.ppi_spare_addr = 0x1fc,
|
||||
};
|
||||
|
||||
#endif /*_CAM_CSID_PPI_100_H_ */
|
|
@ -0,0 +1,374 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019, 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/slab.h>
|
||||
#include <media/cam_defs.h>
|
||||
|
||||
#include "cam_csid_ppi_core.h"
|
||||
#include "cam_csid_ppi_dev.h"
|
||||
#include "cam_soc_util.h"
|
||||
#include "cam_debug_util.h"
|
||||
#include "cam_io_util.h"
|
||||
|
||||
static int cam_csid_ppi_reset(struct cam_csid_ppi_hw *ppi_hw)
|
||||
{
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
const struct cam_csid_ppi_reg_offset *ppi_reg;
|
||||
int rc = 0;
|
||||
uint32_t status;
|
||||
|
||||
soc_info = &ppi_hw->hw_info->soc_info;
|
||||
ppi_reg = ppi_hw->ppi_info->ppi_reg;
|
||||
|
||||
CAM_DBG(CAM_ISP, "PPI:%d reset", ppi_hw->hw_intf->hw_idx);
|
||||
|
||||
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
|
||||
ppi_reg->ppi_irq_mask_addr);
|
||||
cam_io_w_mb(PPI_RST_CONTROL, soc_info->reg_map[0].mem_base +
|
||||
ppi_reg->ppi_irq_set_addr);
|
||||
cam_io_w_mb(PPI_RST_CONTROL, soc_info->reg_map[0].mem_base +
|
||||
ppi_reg->ppi_rst_cmd_addr);
|
||||
cam_io_w_mb(PPI_IRQ_CMD_SET, soc_info->reg_map[0].mem_base +
|
||||
ppi_reg->ppi_irq_cmd_addr);
|
||||
|
||||
rc = readl_poll_timeout(soc_info->reg_map[0].mem_base +
|
||||
ppi_reg->ppi_irq_status_addr, status,
|
||||
(status & 0x1) == 0x1, 1000, 500000);
|
||||
CAM_DBG(CAM_ISP, "PPI:%d reset status %d", ppi_hw->hw_intf->hw_idx,
|
||||
status);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_ISP, "PPI:%d ppi_reset fail rc = %d status = %d",
|
||||
ppi_hw->hw_intf->hw_idx, rc, status);
|
||||
return rc;
|
||||
}
|
||||
cam_io_w_mb(PPI_RST_CONTROL, soc_info->reg_map[0].mem_base +
|
||||
ppi_reg->ppi_irq_clear_addr);
|
||||
cam_io_w_mb(PPI_IRQ_CMD_CLEAR, soc_info->reg_map[0].mem_base +
|
||||
ppi_reg->ppi_irq_cmd_addr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_csid_ppi_enable_hw(struct cam_csid_ppi_hw *ppi_hw)
|
||||
{
|
||||
int rc = 0;
|
||||
int32_t i;
|
||||
uint64_t val;
|
||||
const struct cam_csid_ppi_reg_offset *ppi_reg;
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
uint32_t err_irq_mask;
|
||||
|
||||
ppi_reg = ppi_hw->ppi_info->ppi_reg;
|
||||
soc_info = &ppi_hw->hw_info->soc_info;
|
||||
|
||||
CAM_DBG(CAM_ISP, "PPI:%d init PPI HW", ppi_hw->hw_intf->hw_idx);
|
||||
|
||||
ppi_hw->hw_info->open_count++;
|
||||
if (ppi_hw->hw_info->open_count > 1) {
|
||||
CAM_DBG(CAM_ISP, "PPI:%d dual vfe already enabled",
|
||||
ppi_hw->hw_intf->hw_idx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < soc_info->num_clk; i++) {
|
||||
rc = cam_soc_util_clk_enable(soc_info->clk[i],
|
||||
soc_info->clk_name[i], 0);
|
||||
if (rc)
|
||||
goto clk_disable;
|
||||
}
|
||||
|
||||
rc = cam_csid_ppi_reset(ppi_hw);
|
||||
if (rc)
|
||||
goto clk_disable;
|
||||
|
||||
err_irq_mask = PPI_IRQ_FIFO0_OVERFLOW | PPI_IRQ_FIFO1_OVERFLOW |
|
||||
PPI_IRQ_FIFO2_OVERFLOW;
|
||||
cam_io_w_mb(err_irq_mask, soc_info->reg_map[0].mem_base +
|
||||
ppi_reg->ppi_irq_mask_addr);
|
||||
rc = cam_soc_util_irq_enable(soc_info);
|
||||
if (rc)
|
||||
goto clk_disable;
|
||||
|
||||
cam_io_w_mb(PPI_RST_CONTROL, soc_info->reg_map[0].mem_base +
|
||||
ppi_reg->ppi_irq_clear_addr);
|
||||
cam_io_w_mb(PPI_IRQ_CMD_CLEAR, soc_info->reg_map[0].mem_base +
|
||||
ppi_reg->ppi_irq_cmd_addr);
|
||||
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
|
||||
ppi_reg->ppi_hw_version_addr);
|
||||
CAM_DBG(CAM_ISP, "PPI:%d PPI HW version: 0x%x",
|
||||
ppi_hw->hw_intf->hw_idx, val);
|
||||
ppi_hw->device_enabled = 1;
|
||||
|
||||
return 0;
|
||||
clk_disable:
|
||||
for (--i; i >= 0; i--)
|
||||
cam_soc_util_clk_disable(soc_info->clk[i],
|
||||
soc_info->clk_name[i]);
|
||||
ppi_hw->hw_info->open_count--;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_csid_ppi_disable_hw(struct cam_csid_ppi_hw *ppi_hw)
|
||||
{
|
||||
int rc = 0;
|
||||
int i;
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
const struct cam_csid_ppi_reg_offset *ppi_reg;
|
||||
uint64_t ppi_cfg_val = 0;
|
||||
|
||||
CAM_DBG(CAM_ISP, "PPI:%d De-init PPI HW",
|
||||
ppi_hw->hw_intf->hw_idx);
|
||||
|
||||
if (!ppi_hw->hw_info->open_count) {
|
||||
CAM_WARN(CAM_ISP, "ppi[%d] unbalanced disable hw",
|
||||
ppi_hw->hw_intf->hw_idx);
|
||||
return -EINVAL;
|
||||
}
|
||||
ppi_hw->hw_info->open_count--;
|
||||
|
||||
if (ppi_hw->hw_info->open_count)
|
||||
return rc;
|
||||
|
||||
soc_info = &ppi_hw->hw_info->soc_info;
|
||||
ppi_reg = ppi_hw->ppi_info->ppi_reg;
|
||||
|
||||
CAM_DBG(CAM_ISP, "Calling PPI Reset");
|
||||
cam_csid_ppi_reset(ppi_hw);
|
||||
CAM_DBG(CAM_ISP, "PPI Reset Done");
|
||||
|
||||
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
|
||||
ppi_reg->ppi_irq_mask_addr);
|
||||
cam_soc_util_irq_disable(soc_info);
|
||||
|
||||
for (i = 0; i < CAM_CSID_PPI_LANES_MAX; i++)
|
||||
ppi_cfg_val &= ~PPI_CFG_CPHY_DLX_EN(i);
|
||||
|
||||
cam_io_w_mb(ppi_cfg_val, soc_info->reg_map[0].mem_base +
|
||||
ppi_reg->ppi_module_cfg_addr);
|
||||
|
||||
ppi_hw->device_enabled = 0;
|
||||
|
||||
for (i = 0; i < soc_info->num_clk; i++)
|
||||
cam_soc_util_clk_disable(soc_info->clk[i],
|
||||
soc_info->clk_name[i]);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_csid_ppi_init_hw(void *hw_priv, void *init_args,
|
||||
uint32_t arg_size)
|
||||
{
|
||||
int i, rc = 0;
|
||||
uint32_t num_lanes;
|
||||
uint32_t cphy;
|
||||
uint32_t ppi_cfg_val = 0;
|
||||
struct cam_csid_ppi_hw *ppi_hw;
|
||||
struct cam_hw_info *ppi_hw_info;
|
||||
const struct cam_csid_ppi_reg_offset *ppi_reg;
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
struct cam_csid_ppi_cfg ppi_cfg;
|
||||
|
||||
if (!hw_priv || !init_args ||
|
||||
(arg_size != sizeof(struct cam_csid_ppi_cfg))) {
|
||||
CAM_ERR(CAM_ISP, "PPI: Invalid args");
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ppi_hw_info = (struct cam_hw_info *)hw_priv;
|
||||
ppi_hw = (struct cam_csid_ppi_hw *)ppi_hw_info->core_info;
|
||||
ppi_reg = ppi_hw->ppi_info->ppi_reg;
|
||||
ppi_cfg = *((struct cam_csid_ppi_cfg *)init_args);
|
||||
|
||||
rc = cam_csid_ppi_enable_hw(ppi_hw);
|
||||
if (rc)
|
||||
goto end;
|
||||
|
||||
num_lanes = ppi_cfg.lane_num;
|
||||
cphy = ppi_cfg.lane_type;
|
||||
CAM_DBG(CAM_ISP, "lane_cfg 0x%x | num_lanes 0x%x | lane_type 0x%x",
|
||||
ppi_cfg.lane_cfg, num_lanes, cphy);
|
||||
|
||||
if (cphy) {
|
||||
ppi_cfg_val |= PPI_CFG_CPHY_DLX_SEL(0);
|
||||
ppi_cfg_val |= PPI_CFG_CPHY_DLX_SEL(1);
|
||||
} else {
|
||||
ppi_cfg_val = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < CAM_CSID_PPI_LANES_MAX; i++)
|
||||
ppi_cfg_val |= PPI_CFG_CPHY_DLX_EN(i);
|
||||
|
||||
CAM_DBG(CAM_ISP, "ppi_cfg_val 0x%x", ppi_cfg_val);
|
||||
soc_info = &ppi_hw->hw_info->soc_info;
|
||||
cam_io_w_mb(ppi_cfg_val, soc_info->reg_map[0].mem_base +
|
||||
ppi_reg->ppi_module_cfg_addr);
|
||||
|
||||
CAM_DBG(CAM_ISP, "ppi cfg 0x%x",
|
||||
cam_io_r_mb(soc_info->reg_map[0].mem_base +
|
||||
ppi_reg->ppi_module_cfg_addr));
|
||||
end:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int cam_csid_ppi_deinit_hw(void *hw_priv, void *deinit_args,
|
||||
uint32_t arg_size)
|
||||
{
|
||||
int rc = 0;
|
||||
struct cam_csid_ppi_hw *ppi_hw;
|
||||
struct cam_hw_info *ppi_hw_info;
|
||||
|
||||
CAM_DBG(CAM_ISP, "Enter");
|
||||
|
||||
if (!hw_priv) {
|
||||
CAM_ERR(CAM_ISP, "PPI:Invalid arguments");
|
||||
rc = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
ppi_hw_info = (struct cam_hw_info *)hw_priv;
|
||||
ppi_hw = (struct cam_csid_ppi_hw *)ppi_hw_info->core_info;
|
||||
|
||||
CAM_DBG(CAM_ISP, "Disabling PPI Hw");
|
||||
rc = cam_csid_ppi_disable_hw(ppi_hw);
|
||||
if (rc < 0)
|
||||
CAM_DBG(CAM_ISP, "Exit with %d", rc);
|
||||
end:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_csid_ppi_hw_probe_init(struct cam_hw_intf *ppi_hw_intf,
|
||||
uint32_t ppi_idx)
|
||||
{
|
||||
int rc = -EINVAL;
|
||||
struct cam_hw_info *ppi_hw_info;
|
||||
struct cam_csid_ppi_hw *csid_ppi_hw = NULL;
|
||||
|
||||
if (ppi_idx >= CAM_CSID_PPI_HW_MAX) {
|
||||
CAM_ERR(CAM_ISP, "Invalid ppi index:%d", ppi_idx);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ppi_hw_info = (struct cam_hw_info *) ppi_hw_intf->hw_priv;
|
||||
csid_ppi_hw = (struct cam_csid_ppi_hw *) ppi_hw_info->core_info;
|
||||
|
||||
csid_ppi_hw->hw_intf = ppi_hw_intf;
|
||||
csid_ppi_hw->hw_info = ppi_hw_info;
|
||||
|
||||
CAM_DBG(CAM_ISP, "type %d index %d",
|
||||
csid_ppi_hw->hw_intf->hw_type, ppi_idx);
|
||||
|
||||
rc = cam_csid_ppi_init_soc_resources(&csid_ppi_hw->hw_info->soc_info,
|
||||
cam_csid_ppi_irq, csid_ppi_hw);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_ISP, "PPI:%d Failed to init_soc", ppi_idx);
|
||||
goto err;
|
||||
}
|
||||
|
||||
csid_ppi_hw->hw_intf->hw_ops.init = cam_csid_ppi_init_hw;
|
||||
csid_ppi_hw->hw_intf->hw_ops.deinit = cam_csid_ppi_deinit_hw;
|
||||
return 0;
|
||||
err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_csid_ppi_init_soc_resources(struct cam_hw_soc_info *soc_info,
|
||||
irq_handler_t ppi_irq_handler, void *irq_data)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
rc = cam_soc_util_get_dt_properties(soc_info);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "PPI: Failed to get dt properties");
|
||||
goto end;
|
||||
}
|
||||
|
||||
rc = cam_soc_util_request_platform_resource(soc_info, ppi_irq_handler,
|
||||
irq_data);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP,
|
||||
"PPI: Error Request platform resources failed rc=%d",
|
||||
rc);
|
||||
goto err;
|
||||
}
|
||||
end:
|
||||
return rc;
|
||||
err:
|
||||
cam_soc_util_release_platform_resource(soc_info);
|
||||
return rc;
|
||||
}
|
||||
|
||||
irqreturn_t cam_csid_ppi_irq(int irq_num, void *data)
|
||||
{
|
||||
uint32_t irq_status = 0;
|
||||
uint32_t i, ppi_cfg_val = 0;
|
||||
bool fatal_err_detected = false;
|
||||
|
||||
struct cam_csid_ppi_hw *ppi_hw;
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
const struct cam_csid_ppi_reg_offset *ppi_reg;
|
||||
|
||||
if (!data) {
|
||||
CAM_ERR(CAM_ISP, "PPI: Invalid arguments");
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
ppi_hw = (struct cam_csid_ppi_hw *)data;
|
||||
ppi_reg = ppi_hw->ppi_info->ppi_reg;
|
||||
soc_info = &ppi_hw->hw_info->soc_info;
|
||||
|
||||
if (ppi_hw->device_enabled != 1)
|
||||
goto ret;
|
||||
|
||||
irq_status = cam_io_r_mb(soc_info->reg_map[0].mem_base +
|
||||
ppi_reg->ppi_irq_status_addr);
|
||||
|
||||
cam_io_w_mb(irq_status, soc_info->reg_map[0].mem_base +
|
||||
ppi_reg->ppi_irq_clear_addr);
|
||||
|
||||
cam_io_w_mb(PPI_IRQ_CMD_CLEAR, soc_info->reg_map[0].mem_base +
|
||||
ppi_reg->ppi_irq_cmd_addr);
|
||||
|
||||
CAM_DBG(CAM_ISP, "PPI %d irq status 0x%x", ppi_hw->hw_intf->hw_idx,
|
||||
irq_status);
|
||||
|
||||
if (irq_status & PPI_IRQ_RST_DONE) {
|
||||
CAM_DBG(CAM_ISP, "PPI Reset Done");
|
||||
goto ret;
|
||||
}
|
||||
if ((irq_status & PPI_IRQ_FIFO0_OVERFLOW) ||
|
||||
(irq_status & PPI_IRQ_FIFO1_OVERFLOW) ||
|
||||
(irq_status & PPI_IRQ_FIFO2_OVERFLOW)) {
|
||||
fatal_err_detected = true;
|
||||
goto handle_fatal_error;
|
||||
}
|
||||
|
||||
handle_fatal_error:
|
||||
if (fatal_err_detected) {
|
||||
CAM_ERR(CAM_ISP, "PPI: %d irq_status:0x%x",
|
||||
ppi_hw->hw_intf->hw_idx, irq_status);
|
||||
for (i = 0; i < CAM_CSID_PPI_LANES_MAX; i++)
|
||||
ppi_cfg_val &= ~PPI_CFG_CPHY_DLX_EN(i);
|
||||
|
||||
cam_io_w_mb(ppi_cfg_val, soc_info->reg_map[0].mem_base +
|
||||
ppi_reg->ppi_module_cfg_addr);
|
||||
}
|
||||
ret:
|
||||
CAM_DBG(CAM_ISP, "IRQ Handling exit");
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
int cam_csid_ppi_hw_deinit(struct cam_csid_ppi_hw *csid_ppi_hw)
|
||||
{
|
||||
if (!csid_ppi_hw) {
|
||||
CAM_ERR(CAM_ISP, "Invalid param");
|
||||
return -EINVAL;
|
||||
}
|
||||
return cam_soc_util_release_platform_resource(
|
||||
&csid_ppi_hw->hw_info->soc_info);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2019, 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_CSID_PPI_HW_H_
|
||||
#define _CAM_CSID_PPI_HW_H_
|
||||
|
||||
#include "cam_hw.h"
|
||||
#include "cam_hw_intf.h"
|
||||
|
||||
#define CAM_CSID_PPI_HW_MAX 4
|
||||
#define CAM_CSID_PPI_LANES_MAX 3
|
||||
|
||||
#define PPI_IRQ_RST_DONE BIT(0)
|
||||
#define PPI_IRQ_FIFO0_OVERFLOW BIT(1)
|
||||
#define PPI_IRQ_FIFO1_OVERFLOW BIT(2)
|
||||
#define PPI_IRQ_FIFO2_OVERFLOW BIT(3)
|
||||
|
||||
#define PPI_IRQ_CMD_SET BIT(1)
|
||||
|
||||
#define PPI_IRQ_CMD_CLEAR BIT(0)
|
||||
|
||||
#define PPI_RST_CONTROL BIT(0)
|
||||
/*
|
||||
* Select the PHY (CPHY set '1' or DPHY set '0')
|
||||
*/
|
||||
#define PPI_CFG_CPHY_DLX_SEL(X) BIT(X)
|
||||
|
||||
#define PPI_CFG_CPHY_DLX_EN(X) BIT(4+X)
|
||||
|
||||
struct cam_csid_ppi_reg_offset {
|
||||
uint32_t ppi_hw_version_addr;
|
||||
uint32_t ppi_module_cfg_addr;
|
||||
|
||||
uint32_t ppi_irq_status_addr;
|
||||
uint32_t ppi_irq_mask_addr;
|
||||
uint32_t ppi_irq_set_addr;
|
||||
uint32_t ppi_irq_clear_addr;
|
||||
uint32_t ppi_irq_cmd_addr;
|
||||
uint32_t ppi_rst_cmd_addr;
|
||||
uint32_t ppi_test_bus_ctrl_addr;
|
||||
uint32_t ppi_debug_addr;
|
||||
uint32_t ppi_spare_addr;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cam_csid_ppi_hw_info- ppi HW info
|
||||
*
|
||||
* @ppi_reg: ppi register offsets
|
||||
*
|
||||
*/
|
||||
struct cam_csid_ppi_hw_info {
|
||||
const struct cam_csid_ppi_reg_offset *ppi_reg;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cam_csid_ppi_hw- ppi hw device resources data
|
||||
*
|
||||
* @hw_intf: contain the ppi hw interface information
|
||||
* @hw_info: ppi hw device information
|
||||
* @ppi_info: ppi hw specific information
|
||||
* @device_enabled Device enabled will set once ppi powered on and
|
||||
* initial configuration are done.
|
||||
*
|
||||
*/
|
||||
struct cam_csid_ppi_hw {
|
||||
struct cam_hw_intf *hw_intf;
|
||||
struct cam_hw_info *hw_info;
|
||||
struct cam_csid_ppi_hw_info *ppi_info;
|
||||
uint32_t device_enabled;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cam_csid_ppi_cfg - ppi lane configuration data
|
||||
* @lane_type: lane type: c-phy or d-phy
|
||||
* @lane_num : active lane number
|
||||
* @lane_cfg: lane configurations: 4 bits per lane
|
||||
*
|
||||
*/
|
||||
struct cam_csid_ppi_cfg {
|
||||
uint32_t lane_type;
|
||||
uint32_t lane_num;
|
||||
uint32_t lane_cfg;
|
||||
};
|
||||
|
||||
int cam_csid_ppi_hw_probe_init(struct cam_hw_intf *ppi_hw_intf,
|
||||
uint32_t ppi_idx);
|
||||
int cam_csid_ppi_hw_deinit(struct cam_csid_ppi_hw *csid_ppi_hw);
|
||||
int cam_csid_ppi_init_soc_resources(struct cam_hw_soc_info *soc_info,
|
||||
irq_handler_t ppi_irq_handler, void *irq_data);
|
||||
int cam_csid_ppi_deinit_soc_resources(struct cam_hw_soc_info *soc_info);
|
||||
int cam_csid_ppi_hw_init(struct cam_hw_intf **csid_ppi_hw,
|
||||
uint32_t hw_idx);
|
||||
#endif /* _CAM_CSID_PPI_HW_H_ */
|
|
@ -0,0 +1,139 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019, 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/slab.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/component.h>
|
||||
|
||||
#include "cam_isp_hw.h"
|
||||
#include "cam_hw_intf.h"
|
||||
#include "cam_csid_ppi_core.h"
|
||||
#include "cam_csid_ppi_dev.h"
|
||||
#include "cam_debug_util.h"
|
||||
|
||||
static struct cam_hw_intf *cam_csid_ppi_hw_list[CAM_CSID_PPI_HW_MAX] = {
|
||||
NULL, NULL, NULL, NULL};
|
||||
static char ppi_dev_name[8];
|
||||
|
||||
int cam_csid_ppi_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct cam_hw_intf *ppi_hw_intf;
|
||||
struct cam_hw_info *ppi_hw_info;
|
||||
struct cam_csid_ppi_hw *ppi_dev = NULL;
|
||||
const struct of_device_id *match_dev = NULL;
|
||||
struct cam_csid_ppi_hw_info *ppi_hw_data = NULL;
|
||||
uint32_t ppi_dev_idx;
|
||||
int rc = 0;
|
||||
|
||||
CAM_DBG(CAM_ISP, "PPI probe called");
|
||||
|
||||
ppi_hw_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
|
||||
if (!ppi_hw_intf) {
|
||||
rc = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
ppi_hw_info = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL);
|
||||
if (!ppi_hw_info) {
|
||||
rc = -ENOMEM;
|
||||
goto free_hw_intf;
|
||||
}
|
||||
|
||||
ppi_dev = kzalloc(sizeof(struct cam_csid_ppi_hw), GFP_KERNEL);
|
||||
if (!ppi_dev) {
|
||||
rc = -ENOMEM;
|
||||
goto free_hw_info;
|
||||
}
|
||||
|
||||
of_property_read_u32(pdev->dev.of_node, "cell-index", &ppi_dev_idx);
|
||||
|
||||
match_dev = of_match_device(pdev->dev.driver->of_match_table,
|
||||
&pdev->dev);
|
||||
if (!match_dev) {
|
||||
CAM_ERR(CAM_ISP, "No matching table for the CSID PPI HW!");
|
||||
rc = -EINVAL;
|
||||
goto free_dev;
|
||||
}
|
||||
|
||||
memset(ppi_dev_name, 0, sizeof(ppi_dev_name));
|
||||
snprintf(ppi_dev_name, sizeof(ppi_dev_name), "ppi%1u", ppi_dev_idx);
|
||||
|
||||
ppi_hw_intf->hw_idx = ppi_dev_idx;
|
||||
ppi_hw_intf->hw_priv = ppi_hw_info;
|
||||
|
||||
if (ppi_hw_intf->hw_idx < CAM_CSID_PPI_HW_MAX)
|
||||
cam_csid_ppi_hw_list[ppi_hw_intf->hw_idx] = ppi_hw_intf;
|
||||
else {
|
||||
rc = -EINVAL;
|
||||
goto free_dev;
|
||||
}
|
||||
|
||||
ppi_hw_info->core_info = ppi_dev;
|
||||
ppi_hw_info->soc_info.pdev = pdev;
|
||||
ppi_hw_info->soc_info.dev = &pdev->dev;
|
||||
ppi_hw_info->soc_info.dev_name = ppi_dev_name;
|
||||
ppi_hw_info->soc_info.index = ppi_dev_idx;
|
||||
|
||||
ppi_hw_data = (struct cam_csid_ppi_hw_info *)match_dev->data;
|
||||
ppi_dev->ppi_info = ppi_hw_data;
|
||||
|
||||
rc = cam_csid_ppi_hw_probe_init(ppi_hw_intf, ppi_dev_idx);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_ISP, "PPI: Probe init failed!");
|
||||
goto free_dev;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, ppi_dev);
|
||||
CAM_DBG(CAM_ISP, "PPI:%d probe successful",
|
||||
ppi_hw_intf->hw_idx);
|
||||
|
||||
return 0;
|
||||
free_dev:
|
||||
kfree(ppi_dev);
|
||||
free_hw_info:
|
||||
kfree(ppi_hw_info);
|
||||
free_hw_intf:
|
||||
kfree(ppi_hw_intf);
|
||||
err:
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cam_csid_ppi_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct cam_csid_ppi_hw *ppi_dev = NULL;
|
||||
struct cam_hw_intf *ppi_hw_intf;
|
||||
struct cam_hw_info *ppi_hw_info;
|
||||
|
||||
ppi_dev = (struct cam_csid_ppi_hw *)platform_get_drvdata(pdev);
|
||||
ppi_hw_intf = ppi_dev->hw_intf;
|
||||
ppi_hw_info = ppi_dev->hw_info;
|
||||
|
||||
CAM_DBG(CAM_ISP, "PPI:%d remove", ppi_dev->hw_intf->hw_idx);
|
||||
|
||||
cam_csid_ppi_hw_deinit(ppi_dev);
|
||||
|
||||
kfree(ppi_dev);
|
||||
kfree(ppi_hw_info);
|
||||
kfree(ppi_hw_intf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cam_csid_ppi_hw_init(struct cam_hw_intf **csid_ppi_hw,
|
||||
uint32_t hw_idx)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (cam_csid_ppi_hw_list[hw_idx]) {
|
||||
*csid_ppi_hw = cam_csid_ppi_hw_list[hw_idx];
|
||||
} else {
|
||||
*csid_ppi_hw = NULL;
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(cam_csid_ppi_hw_init);
|
|
@ -0,0 +1,15 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2019, 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_CSID_PPI_DEV_H_
|
||||
#define _CAM_CSID_PPI_DEV_H_
|
||||
|
||||
#include "cam_isp_hw.h"
|
||||
|
||||
irqreturn_t cam_csid_ppi_irq(int irq_num, void *data);
|
||||
int cam_csid_ppi_probe(struct platform_device *pdev);
|
||||
int cam_csid_ppi_remove(struct platform_device *pdev);
|
||||
|
||||
#endif /*_CAM_CSID_PPI_DEV_H_ */
|
|
@ -8,6 +8,7 @@ ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_isp/isp_hw_mgr/include
|
|||
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_isp/isp_hw_mgr/hw_utils/include
|
||||
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_isp/isp_hw_mgr/hw_utils/irq_controller
|
||||
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/include
|
||||
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_isp/isp_hw_mgr/isp_hw/ppi_hw
|
||||
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_smmu/
|
||||
ccflags-y += -I$(srctree)/techpack/camera/drivers/cam_req_mgr/
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_TFE_CSID_530_H_
|
||||
|
@ -134,6 +134,7 @@ static struct cam_tfe_csid_csi2_rx_reg_offset
|
|||
.csid_csi2_rx_irq_set_addr = 0x2c,
|
||||
|
||||
/*CSI2 rx control */
|
||||
.phy_sel_base = 1,
|
||||
.csid_csi2_rx_cfg0_addr = 0x100,
|
||||
.csid_csi2_rx_cfg1_addr = 0x104,
|
||||
.csid_csi2_rx_capture_ctrl_addr = 0x108,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/iopoll.h>
|
||||
|
@ -10,6 +10,7 @@
|
|||
#include <media/cam_req_mgr.h>
|
||||
|
||||
#include "cam_tfe_csid_core.h"
|
||||
#include "cam_csid_ppi_core.h"
|
||||
#include "cam_isp_hw.h"
|
||||
#include "cam_soc_util.h"
|
||||
#include "cam_io_util.h"
|
||||
|
@ -738,6 +739,8 @@ static int cam_tfe_csid_enable_csi2(
|
|||
{
|
||||
const struct cam_tfe_csid_reg_offset *csid_reg;
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
struct cam_csid_ppi_cfg ppi_lane_cfg;
|
||||
uint32_t ppi_index = 0, rc;
|
||||
uint32_t val = 0;
|
||||
|
||||
csid_reg = csid_hw->csid_info->csid_reg;
|
||||
|
@ -801,6 +804,30 @@ static int cam_tfe_csid_enable_csi2(
|
|||
|
||||
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
|
||||
csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
|
||||
/*
|
||||
* There is one to one mapping for ppi index with phy index
|
||||
* we do not always update phy sel equal to phy number,for some
|
||||
* targets "phy_sel = phy_num + 1", and for some targets it is
|
||||
* "phy_sel = phy_num", ppi_index should be updated accordingly
|
||||
*/
|
||||
ppi_index = csid_hw->csi2_rx_cfg.phy_sel -
|
||||
csid_reg->csi2_reg->phy_sel_base;
|
||||
|
||||
if (csid_hw->ppi_hw_intf[ppi_index] && csid_hw->ppi_enable) {
|
||||
ppi_lane_cfg.lane_type = csid_hw->csi2_rx_cfg.lane_type;
|
||||
ppi_lane_cfg.lane_num = csid_hw->csi2_rx_cfg.lane_num;
|
||||
ppi_lane_cfg.lane_cfg = csid_hw->csi2_rx_cfg.lane_cfg;
|
||||
|
||||
CAM_DBG(CAM_ISP, "ppi_index to init %d", ppi_index);
|
||||
rc = csid_hw->ppi_hw_intf[ppi_index]->hw_ops.init(
|
||||
csid_hw->ppi_hw_intf[ppi_index]->hw_priv,
|
||||
&ppi_lane_cfg,
|
||||
sizeof(struct cam_csid_ppi_cfg));
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_ISP, "PPI:%d Init Failed", ppi_index);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -810,6 +837,7 @@ static int cam_tfe_csid_disable_csi2(
|
|||
{
|
||||
const struct cam_tfe_csid_reg_offset *csid_reg;
|
||||
struct cam_hw_soc_info *soc_info;
|
||||
uint32_t ppi_index = 0, rc;
|
||||
|
||||
csid_reg = csid_hw->csid_info->csid_reg;
|
||||
soc_info = &csid_hw->hw_info->soc_info;
|
||||
|
@ -826,6 +854,20 @@ static int cam_tfe_csid_disable_csi2(
|
|||
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
|
||||
csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
|
||||
|
||||
ppi_index = csid_hw->csi2_rx_cfg.phy_sel -
|
||||
csid_reg->csi2_reg->phy_sel_base;
|
||||
if (csid_hw->ppi_hw_intf[ppi_index] && csid_hw->ppi_enable) {
|
||||
/* De-Initialize the PPI bridge */
|
||||
CAM_DBG(CAM_ISP, "ppi_index to de-init %d\n", ppi_index);
|
||||
rc = csid_hw->ppi_hw_intf[ppi_index]->hw_ops.deinit(
|
||||
csid_hw->ppi_hw_intf[ppi_index]->hw_priv,
|
||||
NULL, 0);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_ISP, "PPI:%d De-Init Failed", ppi_index);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -2700,13 +2742,15 @@ irqreturn_t cam_tfe_csid_irq(int irq_num, void *data)
|
|||
unsigned long flags;
|
||||
uint32_t i, val;
|
||||
|
||||
csid_hw = (struct cam_tfe_csid_hw *)data;
|
||||
|
||||
if (!data) {
|
||||
CAM_ERR(CAM_ISP, "CSID: Invalid arguments");
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
csid_hw = (struct cam_tfe_csid_hw *)data;
|
||||
CAM_DBG(CAM_ISP, "CSID %d IRQ Handling", csid_hw->hw_intf->hw_idx);
|
||||
|
||||
csid_reg = csid_hw->csid_info->csid_reg;
|
||||
soc_info = &csid_hw->hw_info->soc_info;
|
||||
csi2_reg = csid_reg->csi2_reg;
|
||||
|
@ -3207,6 +3251,24 @@ int cam_tfe_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
|
|||
tfe_csid_hw->error_irq_count = 0;
|
||||
tfe_csid_hw->prev_boot_timestamp = 0;
|
||||
|
||||
/* Check if ppi bridge is present or not? */
|
||||
tfe_csid_hw->ppi_enable = of_property_read_bool(
|
||||
csid_hw_info->soc_info.pdev->dev.of_node,
|
||||
"ppi-enable");
|
||||
|
||||
if (!tfe_csid_hw->ppi_enable)
|
||||
return 0;
|
||||
|
||||
/* Initialize the PPI bridge */
|
||||
for (i = 0; i < CAM_CSID_PPI_HW_MAX; i++) {
|
||||
rc = cam_csid_ppi_hw_init(&tfe_csid_hw->ppi_hw_intf[i], i);
|
||||
if (rc < 0) {
|
||||
CAM_INFO(CAM_ISP, "PPI init failed for PPI %d", i);
|
||||
rc = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
err:
|
||||
if (rc) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_TFE_CSID_HW_H_
|
||||
|
@ -9,6 +9,7 @@
|
|||
#include "cam_hw.h"
|
||||
#include "cam_tfe_csid_hw_intf.h"
|
||||
#include "cam_tfe_csid_soc.h"
|
||||
#include "cam_csid_ppi_core.h"
|
||||
|
||||
#define CAM_TFE_CSID_CID_MAX 4
|
||||
|
||||
|
@ -184,6 +185,7 @@ struct cam_tfe_csid_csi2_rx_reg_offset {
|
|||
uint32_t csid_csi2_rx_total_crc_err_addr;
|
||||
|
||||
/*configurations */
|
||||
uint32_t phy_sel_base;
|
||||
uint32_t csi2_rst_srb_all;
|
||||
uint32_t csi2_rst_done_shift_val;
|
||||
uint32_t csi2_irq_mask_all;
|
||||
|
@ -407,6 +409,9 @@ struct cam_csid_evt_payload {
|
|||
* @event_cb_priv: Context data
|
||||
* @prev_boot_timestamp previous frame bootime stamp
|
||||
* @prev_qtimer_ts previous frame qtimer csid timestamp
|
||||
* @ppi_hw_intf interface to ppi hardware
|
||||
* @ppi_enabled flag to specify if the hardware has ppi bridge
|
||||
* or not
|
||||
*
|
||||
*/
|
||||
struct cam_tfe_csid_hw {
|
||||
|
@ -439,6 +444,8 @@ struct cam_tfe_csid_hw {
|
|||
void *event_cb_priv;
|
||||
uint64_t prev_boot_timestamp;
|
||||
uint64_t prev_qtimer_ts;
|
||||
struct cam_hw_intf *ppi_hw_intf[CAM_CSID_PPI_HW_MAX];
|
||||
bool ppi_enable;
|
||||
};
|
||||
|
||||
int cam_tfe_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
@ -1902,6 +1902,7 @@ static int cam_tfe_camif_resource_start(
|
|||
uint32_t epoch0_irq_mask;
|
||||
uint32_t epoch1_irq_mask;
|
||||
uint32_t computed_epoch_line_cfg;
|
||||
uint32_t camera_hw_version = 0;
|
||||
|
||||
if (!camif_res || !core_info) {
|
||||
CAM_ERR(CAM_ISP, "Error Invalid input arguments");
|
||||
|
@ -1947,13 +1948,18 @@ static int cam_tfe_camif_resource_start(
|
|||
CAM_DBG(CAM_ISP, "TFE:%d core_cfg 0 val:0x%x", core_info->core_index,
|
||||
val);
|
||||
|
||||
val = cam_io_r(rsrc_data->mem_base +
|
||||
rsrc_data->common_reg->core_cfg_1);
|
||||
val &= ~BIT(0);
|
||||
cam_io_w_mb(val, rsrc_data->mem_base +
|
||||
rsrc_data->common_reg->core_cfg_1);
|
||||
CAM_DBG(CAM_ISP, "TFE:%d core_cfg 1 val:0x%x", core_info->core_index,
|
||||
val);
|
||||
if (cam_cpas_get_cpas_hw_version(&camera_hw_version))
|
||||
CAM_ERR(CAM_ISP, "Failed to get HW version");
|
||||
|
||||
if (camera_hw_version == CAM_CPAS_TITAN_540_V100) {
|
||||
val = cam_io_r(rsrc_data->mem_base +
|
||||
rsrc_data->common_reg->core_cfg_1);
|
||||
val &= ~BIT(0);
|
||||
cam_io_w_mb(val, rsrc_data->mem_base +
|
||||
rsrc_data->common_reg->core_cfg_1);
|
||||
CAM_DBG(CAM_ISP, "TFE:%d core_cfg 1 val:0x%x",
|
||||
core_info->core_index, val);
|
||||
}
|
||||
|
||||
/* Epoch config */
|
||||
epoch0_irq_mask = ((rsrc_data->last_line -
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/iopoll.h>
|
||||
|
@ -400,6 +400,7 @@ static int cam_top_tpg_start(void *hw_priv, void *start_args,
|
|||
const struct cam_top_tpg_reg_offset *tpg_reg;
|
||||
struct cam_top_tpg_cfg *tpg_data;
|
||||
uint32_t i, val;
|
||||
uint32_t in_format = 0;
|
||||
|
||||
if (!hw_priv || !start_args ||
|
||||
(arg_size != sizeof(struct cam_isp_resource_node))) {
|
||||
|
@ -456,6 +457,56 @@ static int cam_top_tpg_start(void *hw_priv, void *start_args,
|
|||
cam_io_w_mb(0x2581F4,
|
||||
soc_info->reg_map[0].mem_base + tpg_reg->tpg_vc_cfg1);
|
||||
|
||||
/* configure tpg pattern */
|
||||
in_format = tpg_data->dt_cfg[0].encode_format & 0xF;
|
||||
val = in_format << tpg_reg->tpg_dt_encode_format_shift;
|
||||
|
||||
switch (tpg_hw->tpg_pattern) {
|
||||
case 0x0:
|
||||
val = val | tpg_hw->tpg_pattern;
|
||||
break;
|
||||
case 0x1:
|
||||
val = val | tpg_hw->tpg_pattern;
|
||||
break;
|
||||
case 0x2:
|
||||
val = val | tpg_hw->tpg_pattern;
|
||||
break;
|
||||
case 0x3:
|
||||
val = val | tpg_hw->tpg_pattern;
|
||||
break;
|
||||
case 0x4:
|
||||
val = val | tpg_hw->tpg_pattern;
|
||||
break;
|
||||
case 0x5:
|
||||
val = val | tpg_hw->tpg_pattern;
|
||||
break;
|
||||
case 0x6:
|
||||
val = val | tpg_hw->tpg_pattern;
|
||||
break;
|
||||
case 0x7:
|
||||
val = val | tpg_hw->tpg_pattern;
|
||||
break;
|
||||
case 0x8:
|
||||
/* unicolor bar selection */
|
||||
val = 0x1 | (1 << tpg_reg->top_unicolor_bar_shift);
|
||||
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
|
||||
tpg_reg->tpg_color_bar_cfg);
|
||||
val = (in_format << tpg_reg->tpg_dt_encode_format_shift) |
|
||||
tpg_hw->tpg_pattern;
|
||||
break;
|
||||
default:
|
||||
/* frame with split color bar */
|
||||
val = 1 << tpg_reg->tpg_split_en_shift;
|
||||
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
|
||||
tpg_reg->tpg_color_bar_cfg);
|
||||
val = (in_format << tpg_reg->tpg_dt_encode_format_shift) |
|
||||
CAM_TOP_TPG_DEFAULT_PATTERN;
|
||||
break;
|
||||
}
|
||||
|
||||
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
|
||||
tpg_reg->tpg_dt_0_cfg_2);
|
||||
|
||||
val = (1 << tpg_reg->tpg_split_en_shift);
|
||||
cam_io_w_mb(tpg_data->pix_pattern, soc_info->reg_map[0].mem_base +
|
||||
tpg_reg->tpg_common_gen_cfg);
|
||||
|
@ -469,8 +520,14 @@ static int cam_top_tpg_start(void *hw_priv, void *start_args,
|
|||
soc_info->reg_map[0].mem_base + tpg_reg->tpg_vbi_cfg);
|
||||
|
||||
/* Set the TOP tpg mux sel*/
|
||||
cam_io_w_mb((1 << tpg_hw->hw_intf->hw_idx),
|
||||
val = cam_io_r_mb(soc_info->reg_map[1].mem_base +
|
||||
tpg_reg->top_mux_reg_offset);
|
||||
val |= (1 << tpg_hw->hw_intf->hw_idx);
|
||||
|
||||
cam_io_w_mb(val,
|
||||
soc_info->reg_map[1].mem_base + tpg_reg->top_mux_reg_offset);
|
||||
CAM_DBG(CAM_ISP, "TPG:%d Set top Mux: 0x%x",
|
||||
tpg_hw->hw_intf->hw_idx, val);
|
||||
|
||||
val = ((tpg_data->num_active_lanes - 1) <<
|
||||
tpg_reg->tpg_num_active_lines_shift) |
|
||||
|
@ -498,6 +555,7 @@ static int cam_top_tpg_stop(void *hw_priv,
|
|||
struct cam_isp_resource_node *tpg_res;
|
||||
const struct cam_top_tpg_reg_offset *tpg_reg;
|
||||
struct cam_top_tpg_cfg *tpg_data;
|
||||
uint32_t val;
|
||||
|
||||
if (!hw_priv || !stop_args ||
|
||||
(arg_size != sizeof(struct cam_isp_resource_node))) {
|
||||
|
@ -524,6 +582,16 @@ static int cam_top_tpg_stop(void *hw_priv,
|
|||
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
|
||||
tpg_reg->tpg_ctrl);
|
||||
|
||||
/* Reset the TOP tpg mux sel*/
|
||||
val = cam_io_r_mb(soc_info->reg_map[1].mem_base +
|
||||
tpg_reg->top_mux_reg_offset);
|
||||
val &= ~(1 << tpg_hw->hw_intf->hw_idx);
|
||||
|
||||
cam_io_w_mb(val,
|
||||
soc_info->reg_map[1].mem_base + tpg_reg->top_mux_reg_offset);
|
||||
CAM_DBG(CAM_ISP, "TPG:%d Reset Top Mux: 0x%x",
|
||||
tpg_hw->hw_intf->hw_idx, val);
|
||||
|
||||
tpg_res->res_state = CAM_ISP_RESOURCE_STATE_RESERVED;
|
||||
|
||||
CAM_DBG(CAM_ISP, "TPG:%d stopped", tpg_hw->hw_intf->hw_idx);
|
||||
|
@ -563,6 +631,19 @@ static int cam_top_tpg_set_phy_clock(
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int cam_top_tpg_set_top_tpg_pattern(struct cam_top_tpg_hw *tpg_hw,
|
||||
void *cmd_args)
|
||||
{
|
||||
uint32_t *top_tpg_pattern;
|
||||
|
||||
top_tpg_pattern = (uint32_t *) cmd_args;
|
||||
tpg_hw->tpg_pattern = *top_tpg_pattern;
|
||||
CAM_DBG(CAM_ISP, "TPG:%d set tpg debug value:%d",
|
||||
tpg_hw->hw_intf->hw_idx, tpg_hw->tpg_pattern);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cam_top_tpg_process_cmd(void *hw_priv,
|
||||
uint32_t cmd_type, void *cmd_args, uint32_t arg_size)
|
||||
{
|
||||
|
@ -582,6 +663,9 @@ static int cam_top_tpg_process_cmd(void *hw_priv,
|
|||
case CAM_ISP_HW_CMD_TPG_PHY_CLOCK_UPDATE:
|
||||
rc = cam_top_tpg_set_phy_clock(tpg_hw, cmd_args);
|
||||
break;
|
||||
case CAM_ISP_HW_CMD_TPG_SET_PATTERN:
|
||||
rc = cam_top_tpg_set_top_tpg_pattern(tpg_hw, cmd_args);
|
||||
break;
|
||||
default:
|
||||
CAM_ERR(CAM_ISP, "TPG:%d unsupported cmd:%d",
|
||||
tpg_hw->hw_intf->hw_idx, cmd_type);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_TOP_TPG_HW_H_
|
||||
|
@ -60,6 +60,7 @@ struct cam_top_tpg_reg_offset {
|
|||
uint32_t tpg_payload_mode_color;
|
||||
uint32_t tpg_split_en_shift;
|
||||
uint32_t top_mux_reg_offset;
|
||||
uint32_t top_unicolor_bar_shift;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -129,7 +130,7 @@ struct cam_top_tpg_cfg {
|
|||
* @hw_info: tpg hw device information
|
||||
* @tpg_info: tpg hw specific information
|
||||
* @tpg_res: tpg resource
|
||||
* @tpg_cfg: tpg configuration
|
||||
* @tpg_pattern: tpg pattern configuration
|
||||
* @clk_rate clock rate
|
||||
* @lock_state lock state
|
||||
* @tpg_complete tpg completion
|
||||
|
@ -140,6 +141,7 @@ struct cam_top_tpg_hw {
|
|||
struct cam_hw_info *hw_info;
|
||||
struct cam_top_tpg_hw_info *tpg_info;
|
||||
struct cam_isp_resource_node tpg_res;
|
||||
uint32_t tpg_pattern;
|
||||
uint64_t clk_rate;
|
||||
spinlock_t lock_state;
|
||||
struct completion tpg_complete;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_TOP_TPG_V1_H_
|
||||
|
@ -48,6 +48,7 @@ static struct cam_top_tpg_reg_offset cam_top_tpg_v1_reg_offset = {
|
|||
.tpg_payload_mode_color = 0x8,
|
||||
.tpg_split_en_shift = 5,
|
||||
.top_mux_reg_offset = 0x1C,
|
||||
.top_unicolor_bar_shift = 2,
|
||||
};
|
||||
|
||||
#endif /*_CAM_TOP_TPG_V1_H_ */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
|
@ -732,10 +732,12 @@ static int cam_jpeg_mgr_prepare_hw_update(void *hw_mgr_priv,
|
|||
}
|
||||
|
||||
if ((packet->num_cmd_buf > 5) || !packet->num_patches ||
|
||||
!packet->num_io_configs) {
|
||||
CAM_ERR(CAM_JPEG, "wrong number of cmd/patch info: %u %u",
|
||||
packet->num_cmd_buf,
|
||||
packet->num_patches);
|
||||
!packet->num_io_configs ||
|
||||
(packet->num_io_configs > CAM_JPEG_IMAGE_MAX)) {
|
||||
CAM_ERR(CAM_JPEG,
|
||||
"wrong number of cmd/patch/io_configs info: %u %u %u",
|
||||
packet->num_cmd_buf, packet->num_patches,
|
||||
packet->num_io_configs);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
|
@ -695,15 +695,14 @@ static int32_t cam_ope_process_request_timer(void *priv, void *data)
|
|||
}
|
||||
|
||||
CAM_ERR(CAM_OPE,
|
||||
"pending requests means, issue is with HW for ctx %d",
|
||||
ctx_data->ctx_id);
|
||||
CAM_ERR(CAM_OPE, "ctx: %d, lrt: %llu, lct: %llu",
|
||||
"pending req at HW, ctx %d lrt %llu lct %llu",
|
||||
ctx_data->ctx_id, ctx_data->last_req_time,
|
||||
ope_hw_mgr->last_callback_time);
|
||||
hw_mgr->ope_dev_intf[i]->hw_ops.process_cmd(
|
||||
hw_mgr->ope_dev_intf[i]->hw_priv,
|
||||
OPE_HW_DUMP_DEBUG,
|
||||
NULL, 0);
|
||||
|
||||
task = cam_req_mgr_workq_get_task(ope_hw_mgr->msg_work);
|
||||
if (!task) {
|
||||
CAM_ERR(CAM_OPE, "no empty task");
|
||||
|
@ -1601,6 +1600,7 @@ static void cam_ope_ctx_cdm_callback(uint32_t handle, void *userdata,
|
|||
struct timespec64 ts;
|
||||
bool flag = false;
|
||||
bool dump_flag = true;
|
||||
int i;
|
||||
|
||||
if (!userdata) {
|
||||
CAM_ERR(CAM_OPE, "Invalid ctx from CDM callback");
|
||||
|
@ -1660,9 +1660,17 @@ static void cam_ope_ctx_cdm_callback(uint32_t handle, void *userdata,
|
|||
ope_req->request_id, ctx->ctx_id);
|
||||
CAM_INFO(CAM_OPE, "Rst of CDM and OPE for error reqid = %lld",
|
||||
ope_req->request_id);
|
||||
|
||||
if (status != CAM_CDM_CB_STATUS_HW_FLUSH) {
|
||||
cam_ope_dump_req_data(ope_req);
|
||||
dump_flag = false;
|
||||
|
||||
CAM_INFO(CAM_OPE, "bach_size: %d",
|
||||
ctx->req_list[cookie]->num_batch);
|
||||
for (i = 0; i < ctx->req_list[cookie]->num_batch; i++)
|
||||
CAM_INFO(CAM_OPE, "i: %d num_stripes: %d",
|
||||
i,
|
||||
ctx->req_list[cookie]->num_stripes[i]);
|
||||
}
|
||||
rc = cam_ope_mgr_reset_hw();
|
||||
flag = true;
|
||||
|
@ -1753,7 +1761,7 @@ static int cam_ope_mgr_create_kmd_buf(struct cam_ope_hw_mgr *hw_mgr,
|
|||
|
||||
static int cam_ope_mgr_process_io_cfg(struct cam_ope_hw_mgr *hw_mgr,
|
||||
struct cam_packet *packet,
|
||||
struct cam_hw_prepare_update_args *prep_args,
|
||||
struct cam_hw_prepare_update_args *prep_arg,
|
||||
struct cam_ope_ctx *ctx_data, uint32_t req_idx)
|
||||
{
|
||||
|
||||
|
@ -1764,8 +1772,8 @@ static int cam_ope_mgr_process_io_cfg(struct cam_ope_hw_mgr *hw_mgr,
|
|||
struct cam_ope_request *ope_request;
|
||||
|
||||
ope_request = ctx_data->req_list[req_idx];
|
||||
prep_args->num_out_map_entries = 0;
|
||||
prep_args->num_in_map_entries = 0;
|
||||
prep_arg->num_out_map_entries = 0;
|
||||
prep_arg->num_in_map_entries = 0;
|
||||
|
||||
ope_request = ctx_data->req_list[req_idx];
|
||||
CAM_DBG(CAM_OPE, "E: req_idx = %u %x", req_idx, packet);
|
||||
|
@ -1775,8 +1783,16 @@ static int cam_ope_mgr_process_io_cfg(struct cam_ope_hw_mgr *hw_mgr,
|
|||
io_buf = ope_request->io_buf[i][l];
|
||||
if (io_buf->direction == CAM_BUF_INPUT) {
|
||||
if (io_buf->fence != -1) {
|
||||
sync_in_obj[j++] = io_buf->fence;
|
||||
prep_args->num_in_map_entries++;
|
||||
if (j < CAM_MAX_IN_RES) {
|
||||
sync_in_obj[j++] =
|
||||
io_buf->fence;
|
||||
prep_arg->num_in_map_entries++;
|
||||
} else {
|
||||
CAM_ERR(CAM_OPE,
|
||||
"reached max in_res %d %d",
|
||||
io_buf->resource_type,
|
||||
ope_request->request_id);
|
||||
}
|
||||
} else {
|
||||
CAM_ERR(CAM_OPE, "Invalid fence %d %d",
|
||||
io_buf->resource_type,
|
||||
|
@ -1784,10 +1800,10 @@ static int cam_ope_mgr_process_io_cfg(struct cam_ope_hw_mgr *hw_mgr,
|
|||
}
|
||||
} else {
|
||||
if (io_buf->fence != -1) {
|
||||
prep_args->out_map_entries[k].sync_id =
|
||||
prep_arg->out_map_entries[k].sync_id =
|
||||
io_buf->fence;
|
||||
k++;
|
||||
prep_args->num_out_map_entries++;
|
||||
prep_arg->num_out_map_entries++;
|
||||
} else {
|
||||
if (io_buf->resource_type
|
||||
!= OPE_OUT_RES_STATS_LTM) {
|
||||
|
@ -1808,38 +1824,38 @@ static int cam_ope_mgr_process_io_cfg(struct cam_ope_hw_mgr *hw_mgr,
|
|||
}
|
||||
}
|
||||
|
||||
if (prep_args->num_in_map_entries > 1 &&
|
||||
prep_args->num_in_map_entries <= CAM_MAX_IN_RES)
|
||||
prep_args->num_in_map_entries =
|
||||
if (prep_arg->num_in_map_entries > 1 &&
|
||||
prep_arg->num_in_map_entries <= CAM_MAX_IN_RES)
|
||||
prep_arg->num_in_map_entries =
|
||||
cam_common_util_remove_duplicate_arr(
|
||||
sync_in_obj, prep_args->num_in_map_entries);
|
||||
sync_in_obj, prep_arg->num_in_map_entries);
|
||||
|
||||
if (prep_args->num_in_map_entries > 1 &&
|
||||
prep_args->num_in_map_entries <= CAM_MAX_IN_RES) {
|
||||
if (prep_arg->num_in_map_entries > 1 &&
|
||||
prep_arg->num_in_map_entries <= CAM_MAX_IN_RES) {
|
||||
rc = cam_sync_merge(&sync_in_obj[0],
|
||||
prep_args->num_in_map_entries, &merged_sync_in_obj);
|
||||
prep_arg->num_in_map_entries, &merged_sync_in_obj);
|
||||
if (rc) {
|
||||
prep_args->num_out_map_entries = 0;
|
||||
prep_args->num_in_map_entries = 0;
|
||||
prep_arg->num_out_map_entries = 0;
|
||||
prep_arg->num_in_map_entries = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
ope_request->in_resource = merged_sync_in_obj;
|
||||
|
||||
prep_args->in_map_entries[0].sync_id = merged_sync_in_obj;
|
||||
prep_args->num_in_map_entries = 1;
|
||||
prep_arg->in_map_entries[0].sync_id = merged_sync_in_obj;
|
||||
prep_arg->num_in_map_entries = 1;
|
||||
CAM_DBG(CAM_REQ, "ctx_id: %u req_id: %llu Merged Sync obj: %d",
|
||||
ctx_data->ctx_id, packet->header.request_id,
|
||||
merged_sync_in_obj);
|
||||
} else if (prep_args->num_in_map_entries == 1) {
|
||||
prep_args->in_map_entries[0].sync_id = sync_in_obj[0];
|
||||
prep_args->num_in_map_entries = 1;
|
||||
} else if (prep_arg->num_in_map_entries == 1) {
|
||||
prep_arg->in_map_entries[0].sync_id = sync_in_obj[0];
|
||||
prep_arg->num_in_map_entries = 1;
|
||||
ope_request->in_resource = 0;
|
||||
CAM_DBG(CAM_OPE, "fence = %d", sync_in_obj[0]);
|
||||
} else {
|
||||
CAM_DBG(CAM_OPE, "Invalid count of input fences, count: %d",
|
||||
prep_args->num_in_map_entries);
|
||||
prep_args->num_in_map_entries = 0;
|
||||
prep_arg->num_in_map_entries);
|
||||
prep_arg->num_in_map_entries = 0;
|
||||
ope_request->in_resource = 0;
|
||||
rc = -EINVAL;
|
||||
}
|
||||
|
@ -2740,6 +2756,10 @@ static int cam_ope_mgr_acquire_hw(void *hw_priv, void *hw_acquire_args)
|
|||
ctx->ctxt_event_cb = args->event_cb;
|
||||
cam_ope_ctx_clk_info_init(ctx);
|
||||
ctx->ctx_state = OPE_CTX_STATE_ACQUIRED;
|
||||
kzfree(cdm_acquire);
|
||||
cdm_acquire = NULL;
|
||||
kzfree(bw_update);
|
||||
bw_update = NULL;
|
||||
|
||||
mutex_unlock(&ctx->ctx_mutex);
|
||||
mutex_unlock(&hw_mgr->hw_mgr_mutex);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
|
@ -787,6 +787,11 @@ static uint32_t *ope_create_stripe_cmd(struct cam_ope_hw_mgr *hw_mgr,
|
|||
uint32_t *print_ptr;
|
||||
int num_dmi = 0;
|
||||
struct cam_cdm_utils_ops *cdm_ops;
|
||||
uint32_t reg_val_pair[2];
|
||||
struct cam_hw_info *ope_dev;
|
||||
struct cam_ope_device_core_info *core_info;
|
||||
struct ope_hw *ope_hw;
|
||||
struct cam_ope_top_reg *top_reg;
|
||||
|
||||
if (s_idx >= OPE_MAX_CMD_BUFS ||
|
||||
batch_idx >= OPE_MAX_BATCH_SIZE) {
|
||||
|
@ -868,10 +873,21 @@ static uint32_t *ope_create_stripe_cmd(struct cam_ope_hw_mgr *hw_mgr,
|
|||
}
|
||||
CAM_DBG(CAM_OPE, "Stripe:%d Indirect:X", stripe_idx);
|
||||
}
|
||||
|
||||
if (hw_mgr->frame_dump_enable)
|
||||
dump_stripe_cmd(frm_proc, stripe_idx, i, k,
|
||||
iova_addr, kmd_buf, buf_len);
|
||||
}
|
||||
|
||||
ope_dev = hw_mgr->ope_dev_intf[0]->hw_priv;
|
||||
core_info = (struct cam_ope_device_core_info *)ope_dev->core_info;
|
||||
ope_hw = core_info->ope_hw_info->ope_hw;
|
||||
top_reg = ope_hw->top_reg;
|
||||
|
||||
reg_val_pair[0] = top_reg->offset + top_reg->scratch_reg;
|
||||
reg_val_pair[1] = stripe_idx;
|
||||
kmd_buf = cdm_ops->cdm_write_regrandom(kmd_buf, 1, reg_val_pair);
|
||||
|
||||
return kmd_buf;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
@ -66,6 +66,7 @@ static int cam_ope_init_hw_version(struct cam_hw_soc_info *soc_info,
|
|||
|
||||
switch (core_info->hw_version) {
|
||||
case OPE_HW_VER_1_0_0:
|
||||
case OPE_HW_VER_1_1_0:
|
||||
core_info->ope_hw_info->ope_hw = &ope_hw_100;
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef CAM_OPE_HW_H
|
||||
#define CAM_OPE_HW_H
|
||||
|
||||
#define OPE_HW_VER_1_0_0 0x10000000
|
||||
#define OPE_HW_VER_1_1_0 0x10010000
|
||||
|
||||
#define OPE_DEV_OPE 0
|
||||
#define OPE_DEV_MAX 1
|
||||
|
@ -72,6 +73,7 @@ struct cam_ope_top_reg {
|
|||
uint32_t violation_status;
|
||||
uint32_t throttle_cnt_cfg;
|
||||
uint32_t debug_cfg;
|
||||
uint32_t scratch_reg;
|
||||
uint32_t num_debug_registers;
|
||||
struct cam_ope_debug_register *debug_regs;
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef CAM_OPE_HW_100_H
|
||||
|
@ -70,6 +70,9 @@ static struct cam_ope_debug_register ope_debug_regs[OPE_MAX_DEBUG_REGISTER] = {
|
|||
{
|
||||
.offset = 0xD0,
|
||||
},
|
||||
{
|
||||
.offset = 0xD4,
|
||||
},
|
||||
};
|
||||
|
||||
static struct cam_ope_top_reg ope_top_reg = {
|
||||
|
@ -87,7 +90,8 @@ static struct cam_ope_top_reg ope_top_reg = {
|
|||
.violation_status = 0x28,
|
||||
.throttle_cnt_cfg = 0x2C,
|
||||
.debug_cfg = 0xDC,
|
||||
.num_debug_registers = 9,
|
||||
.scratch_reg = 0x1F0,
|
||||
.num_debug_registers = 10,
|
||||
.debug_regs = ope_debug_regs,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
|
@ -31,15 +31,27 @@ static struct ope_top ope_top_info;
|
|||
|
||||
static int cam_ope_top_dump_debug_reg(struct ope_hw *ope_hw_info)
|
||||
{
|
||||
uint32_t i, val;
|
||||
uint32_t i, val[3];
|
||||
struct cam_ope_top_reg *top_reg;
|
||||
|
||||
top_reg = ope_hw_info->top_reg;
|
||||
for (i = 0; i < top_reg->num_debug_registers; i++) {
|
||||
val = cam_io_r_mb(top_reg->base +
|
||||
for (i = 0; i < top_reg->num_debug_registers; i = i+3) {
|
||||
val[0] = cam_io_r_mb(top_reg->base +
|
||||
top_reg->debug_regs[i].offset);
|
||||
CAM_INFO(CAM_OPE, "Debug_status_%d val: 0x%x", i, val);
|
||||
val[1] = ((i+1) < top_reg->num_debug_registers) ?
|
||||
cam_io_r_mb(top_reg->base +
|
||||
top_reg->debug_regs[i+1].offset) : 0;
|
||||
val[2] = ((i+2) < top_reg->num_debug_registers) ?
|
||||
cam_io_r_mb(top_reg->base +
|
||||
top_reg->debug_regs[i+2].offset) : 0;
|
||||
|
||||
CAM_INFO(CAM_OPE, "status[%d-%d] : 0x%x 0x%x 0x%x",
|
||||
i, i+2, val[0], val[1], val[2]);
|
||||
}
|
||||
|
||||
CAM_INFO(CAM_OPE, "scrath reg: 0x%x, stripe_idx: %d",
|
||||
top_reg->offset + top_reg->scratch_reg,
|
||||
cam_io_r_mb(top_reg->base + top_reg->scratch_reg));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "CAM-REQ-MGR_UTIL %s:%d " fmt, __func__, __LINE__
|
||||
|
@ -114,7 +114,7 @@ static int32_t cam_get_free_handle_index(void)
|
|||
idx = find_first_zero_bit(hdl_tbl->bitmap, hdl_tbl->bits);
|
||||
|
||||
if (idx >= CAM_REQ_MGR_MAX_HANDLES_V2 || idx < 0) {
|
||||
CAM_DBG(CAM_CRM, "idx: %d", idx);
|
||||
CAM_ERR(CAM_CRM, "No free index found idx: %d", idx);
|
||||
return -ENOSR;
|
||||
}
|
||||
|
||||
|
@ -123,20 +123,6 @@ static int32_t cam_get_free_handle_index(void)
|
|||
return idx;
|
||||
}
|
||||
|
||||
void cam_dump_tbl_info(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < CAM_REQ_MGR_MAX_HANDLES_V2; i++)
|
||||
CAM_INFO(CAM_CRM,
|
||||
"i: %d session_hdl=0x%x hdl_value=0x%x type=%d state=%d dev_id=0x%llx",
|
||||
i, hdl_tbl->hdl[i].session_hdl,
|
||||
hdl_tbl->hdl[i].hdl_value,
|
||||
hdl_tbl->hdl[i].type,
|
||||
hdl_tbl->hdl[i].state,
|
||||
hdl_tbl->hdl[i].dev_id);
|
||||
}
|
||||
|
||||
int32_t cam_create_session_hdl(void *priv)
|
||||
{
|
||||
int idx;
|
||||
|
@ -153,7 +139,6 @@ int32_t cam_create_session_hdl(void *priv)
|
|||
idx = cam_get_free_handle_index();
|
||||
if (idx < 0) {
|
||||
CAM_ERR(CAM_CRM, "Unable to create session handle");
|
||||
cam_dump_tbl_info();
|
||||
spin_unlock_bh(&hdl_tbl_lock);
|
||||
return idx;
|
||||
}
|
||||
|
@ -189,7 +174,6 @@ int32_t cam_create_device_hdl(struct cam_create_dev_hdl *hdl_data)
|
|||
if (idx < 0) {
|
||||
CAM_ERR(CAM_CRM,
|
||||
"Unable to create device handle(idx= %d)", idx);
|
||||
cam_dump_tbl_info();
|
||||
spin_unlock_bh(&hdl_tbl_lock);
|
||||
return idx;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
/*
|
||||
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2018-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_CSIPHY_1_2_1_HWREG_H_
|
||||
|
@ -13,10 +13,10 @@ struct csiphy_reg_parms_t csiphy_v1_2_1 = {
|
|||
.mipi_csiphy_interrupt_clear0_addr = 0x858,
|
||||
.mipi_csiphy_glbl_irq_cmd_addr = 0x828,
|
||||
.csiphy_interrupt_status_size = 11,
|
||||
.csiphy_common_array_size = 6,
|
||||
.csiphy_common_array_size = 7,
|
||||
.csiphy_reset_array_size = 5,
|
||||
.csiphy_2ph_config_array_size = 20,
|
||||
.csiphy_3ph_config_array_size = 34,
|
||||
.csiphy_3ph_config_array_size = 33,
|
||||
.csiphy_2ph_clock_lane = 0x1,
|
||||
.csiphy_2ph_combo_ck_ln = 0x10,
|
||||
};
|
||||
|
@ -26,6 +26,7 @@ struct csiphy_reg_t csiphy_common_reg_1_2_1[] = {
|
|||
{0x0818, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x081C, 0x02, 0x00, CSIPHY_2PH_REGS},
|
||||
{0x081C, 0x52, 0x00, CSIPHY_3PH_REGS},
|
||||
{0x0800, 0x03, 0x01, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0800, 0x02, 0x00, CSIPHY_2PH_REGS},
|
||||
{0x0800, 0x0E, 0x00, CSIPHY_3PH_REGS},
|
||||
};
|
||||
|
@ -34,7 +35,7 @@ struct csiphy_reg_t csiphy_reset_reg_1_2_1[] = {
|
|||
{0x0814, 0x00, 0x05, CSIPHY_LANE_ENABLE},
|
||||
{0x0818, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x081C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0800, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0800, 0x01, 0x01, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
};
|
||||
|
||||
|
@ -59,7 +60,7 @@ csiphy_reg_t csiphy_2ph_v1_2_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
|
|||
{0x0900, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0908, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0904, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0904, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0904, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0004, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x002C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0034, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
|
@ -70,7 +71,7 @@ csiphy_reg_t csiphy_2ph_v1_2_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
|
|||
{0x0000, 0x8D, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x000c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
{0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0014, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0014, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0028, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
{0x0024, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
{0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
|
@ -81,7 +82,7 @@ csiphy_reg_t csiphy_2ph_v1_2_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
|
|||
{0x0C80, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0C88, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0C84, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0C84, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0C84, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0704, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x072C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0734, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
|
@ -92,7 +93,7 @@ csiphy_reg_t csiphy_2ph_v1_2_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
|
|||
{0x0700, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x070c, 0xA5, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0714, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0714, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0728, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0724, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
{0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
|
@ -103,7 +104,7 @@ csiphy_reg_t csiphy_2ph_v1_2_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
|
|||
{0x0A00, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0A08, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0A04, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0A04, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0A04, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0204, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x022C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0234, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
|
@ -114,7 +115,7 @@ csiphy_reg_t csiphy_2ph_v1_2_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
|
|||
{0x0200, 0x8D, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x020c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
{0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0214, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0214, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0228, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
{0x0224, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
{0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
|
@ -125,7 +126,7 @@ csiphy_reg_t csiphy_2ph_v1_2_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
|
|||
{0x0B00, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0B08, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0B04, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0B04, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0B04, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0404, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x042C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0434, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
|
@ -136,7 +137,7 @@ csiphy_reg_t csiphy_2ph_v1_2_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
|
|||
{0x0400, 0x8D, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x040c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
{0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0414, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0414, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0428, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
{0x0424, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
{0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
|
@ -147,7 +148,7 @@ csiphy_reg_t csiphy_2ph_v1_2_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
|
|||
{0x0C00, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0C08, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0C04, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0C04, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0C04, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0604, 0x0C, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x062C, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0634, 0x07, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
|
@ -158,7 +159,7 @@ csiphy_reg_t csiphy_2ph_v1_2_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
|
|||
{0x0600, 0x8D, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x060c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
{0x0638, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0614, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0614, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0628, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
{0x0624, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
{0x0800, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
|
@ -184,7 +185,7 @@ struct csiphy_reg_t
|
|||
{0x0000, 0x8D, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x000c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
{0x0038, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0014, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0014, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0028, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
{0x0024, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
{0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
|
@ -206,7 +207,7 @@ struct csiphy_reg_t
|
|||
{0x0700, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x070c, 0xA5, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0738, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0714, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0714, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0728, 0x04, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0724, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
{0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
|
@ -228,7 +229,7 @@ struct csiphy_reg_t
|
|||
{0x0200, 0x8D, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x020c, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
{0x0238, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0214, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0214, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0228, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
{0x0224, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
{0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
|
@ -250,7 +251,7 @@ struct csiphy_reg_t
|
|||
{0x0400, 0x8D, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x040C, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
{0x0438, 0xFE, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0414, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0414, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0428, 0x0A, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0424, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
{0x0800, 0x00, 0x00, CSIPHY_DNP_PARAMS},
|
||||
|
@ -272,9 +273,9 @@ struct csiphy_reg_t
|
|||
{0x0600, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x060C, 0xA5, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0638, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0614, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0614, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0628, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0624, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0624, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0800, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0884, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
},
|
||||
|
@ -289,10 +290,11 @@ csiphy_reg_t csiphy_3ph_v1_2_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
|
|||
{0x0990, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0994, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0998, 0x1A, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x098C, 0xAF, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0168, 0xAC, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x098C, 0xAF, 0x01, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x015C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0168, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0104, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x010C, 0x07, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
|
||||
{0x010C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
|
||||
{0x0108, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE},
|
||||
{0x0114, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0150, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
|
@ -307,28 +309,27 @@ csiphy_reg_t csiphy_3ph_v1_2_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
|
|||
{0x012C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0160, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x01CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0164, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x01DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x09C0, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x09C4, 0x7D, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x09C8, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0984, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0988, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0980, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x09AC, 0x35, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x09B0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0800, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0884, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
},
|
||||
{
|
||||
{0x0A90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0A94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0A98, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0A90, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0A94, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0A98, 0x1F, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0A8C, 0xBF, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0368, 0xAC, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0A94, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0A98, 0x1A, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0A8C, 0xAF, 0x01, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x035C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0368, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0304, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x030C, 0x07, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
|
||||
{0x030C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
|
||||
{0x0308, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE},
|
||||
{0x0314, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0350, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
|
@ -343,16 +344,14 @@ csiphy_reg_t csiphy_3ph_v1_2_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
|
|||
{0x032C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0360, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x03CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0364, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x03DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0AC0, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0AC4, 0x7D, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0AC8, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0A84, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0A88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0A80, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0AAC, 0x35, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0AB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0800, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0884, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
},
|
||||
{
|
||||
{0x0B90, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
|
@ -361,10 +360,11 @@ csiphy_reg_t csiphy_3ph_v1_2_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
|
|||
{0x0B90, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0B94, 0x08, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0B98, 0x1A, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0B8C, 0xAF, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0568, 0xAC, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0B8C, 0xAF, 0x01, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x055C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0568, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0504, 0x06, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x050C, 0x07, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
|
||||
{0x050C, 0x12, 0x00, CSIPHY_SETTLE_CNT_LOWER_BYTE},
|
||||
{0x0508, 0x00, 0x00, CSIPHY_SETTLE_CNT_HIGHER_BYTE},
|
||||
{0x0514, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0550, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
|
@ -379,16 +379,14 @@ csiphy_reg_t csiphy_3ph_v1_2_1_reg[MAX_LANES][MAX_SETTINGS_PER_LANE] = {
|
|||
{0x052C, 0x00, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0560, 0x02, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x05CC, 0x41, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0564, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x05DC, 0x50, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0BC0, 0x80, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0BC4, 0x7D, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0BC8, 0x7F, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0B84, 0x20, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0B88, 0x05, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0B80, 0x60, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0BAC, 0x35, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0BB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0800, 0x0E, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x0884, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -398,82 +396,55 @@ struct data_rate_settings_t data_rate_delta_table_1_2_1 = {
|
|||
{
|
||||
/* (2.5 * 10**3 * 2.28) rounded value*/
|
||||
.bandwidth = 5700000000,
|
||||
.data_rate_reg_array_size = 12,
|
||||
.data_rate_reg_array_size = 9,
|
||||
.csiphy_data_rate_regs = {
|
||||
{0x15C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x35C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x55C, 0x66, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x9B4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0xAB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0xBB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x144, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x344, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x544, 0x22, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x16C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x36C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x56C, 0xAD, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x164, 0x0B, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x364, 0x0B, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x564, 0x0B, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x144, 0x32, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x344, 0x32, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x544, 0x32, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x16C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x36C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x56C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
}
|
||||
},
|
||||
{
|
||||
/* (3.5 * 10**3 * 2.28) rounded value */
|
||||
.bandwidth = 7980000000,
|
||||
.data_rate_reg_array_size = 24,
|
||||
.data_rate_reg_array_size = 12,
|
||||
.csiphy_data_rate_regs = {
|
||||
{0x15C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x35C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x55C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x9B4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0xAB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0xBB4, 0x03, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x9B0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0xAB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0xBB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x144, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x344, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x544, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x13C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x33C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x53C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x140, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x340, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x540, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x168, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x368, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x568, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x16C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x36C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x56C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x9B4, 0x03, 0x01, CSIPHY_DEFAULT_PARAMS},
|
||||
{0xAB4, 0x03, 0x01, CSIPHY_DEFAULT_PARAMS},
|
||||
{0xBB4, 0x03, 0x01, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x144, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x344, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x544, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x164, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x364, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x564, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x16C, 0x1D, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x36C, 0x1D, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x56C, 0x1D, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
},
|
||||
},
|
||||
{
|
||||
/* (4.5 * 10**3 * 2.28) rounded value */
|
||||
.bandwidth = 10260000000,
|
||||
.data_rate_reg_array_size = 24,
|
||||
.data_rate_reg_array_size = 12,
|
||||
.csiphy_data_rate_regs = {
|
||||
{0x15C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x35C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x55C, 0x46, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x9B4, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0xAB4, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0xBB4, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x9B0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0xAB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0xBB0, 0x01, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x144, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x344, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x544, 0xA2, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x13C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x33C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x53C, 0x10, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x140, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x340, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x540, 0x81, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x168, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x368, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x568, 0xA0, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x16C, 0x1D, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x36C, 0x1D, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x56C, 0x1D, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x9B4, 0x02, 0x01, CSIPHY_DEFAULT_PARAMS},
|
||||
{0xAB4, 0x02, 0x01, CSIPHY_DEFAULT_PARAMS},
|
||||
{0xBB4, 0x02, 0x01, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x144, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x344, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x544, 0xB2, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x164, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x364, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x564, 0x33, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x16C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x36C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
{0x56C, 0x25, 0x00, CSIPHY_DEFAULT_PARAMS},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
@ -474,7 +474,6 @@ static int cam_flash_ops(struct cam_flash_ctrl *flash_ctrl,
|
|||
|
||||
CAM_DBG(CAM_FLASH, "Led_Torch[%d]: Current: %d",
|
||||
i, curr);
|
||||
|
||||
cam_res_mgr_led_trigger_event(
|
||||
flash_ctrl->torch_trigger[i], curr);
|
||||
}
|
||||
|
@ -509,6 +508,8 @@ static int cam_flash_ops(struct cam_flash_ctrl *flash_ctrl,
|
|||
|
||||
int cam_flash_off(struct cam_flash_ctrl *flash_ctrl)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
if (!flash_ctrl) {
|
||||
CAM_ERR(CAM_FLASH, "Flash control Null");
|
||||
return -EINVAL;
|
||||
|
@ -519,6 +520,18 @@ int cam_flash_off(struct cam_flash_ctrl *flash_ctrl)
|
|||
(enum led_brightness)LED_SWITCH_OFF);
|
||||
|
||||
flash_ctrl->flash_state = CAM_FLASH_STATE_START;
|
||||
|
||||
if ((flash_ctrl->i2c_data.streamoff_settings.is_settings_valid) &&
|
||||
(flash_ctrl->i2c_data.streamoff_settings.request_id == 0)) {
|
||||
flash_ctrl->apply_streamoff = true;
|
||||
rc = cam_flash_i2c_apply_setting(flash_ctrl, 0);
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_SENSOR,
|
||||
"cannot apply streamoff settings");
|
||||
}
|
||||
flash_ctrl->flash_state = CAM_FLASH_STATE_CONFIG;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -621,6 +634,21 @@ static int cam_flash_i2c_delete_req(struct cam_flash_ctrl *fctrl,
|
|||
|
||||
CAM_DBG(CAM_FLASH, "top: %llu, del_req_id:%llu",
|
||||
top, del_req_id);
|
||||
|
||||
for (i = 0; i < MAX_PER_FRAME_ARRAY; i++) {
|
||||
if ((del_req_id >
|
||||
fctrl->i2c_data.per_frame[i].request_id) && (
|
||||
fctrl->i2c_data.per_frame[i].is_settings_valid
|
||||
== 1)) {
|
||||
fctrl->i2c_data.per_frame[i].request_id = 0;
|
||||
rc = delete_request(
|
||||
&(fctrl->i2c_data.per_frame[i]));
|
||||
if (rc < 0)
|
||||
CAM_ERR(CAM_SENSOR,
|
||||
"Delete request Fail:%lld rc:%d",
|
||||
del_req_id, rc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cam_flash_i2c_flush_nrt(fctrl);
|
||||
|
@ -720,10 +748,27 @@ int cam_flash_i2c_apply_setting(struct cam_flash_ctrl *fctrl,
|
|||
struct i2c_settings_list *i2c_list;
|
||||
struct i2c_settings_array *i2c_set = NULL;
|
||||
int frame_offset = 0, rc = 0;
|
||||
|
||||
CAM_DBG(CAM_FLASH, "req_id=%llu", req_id);
|
||||
if (req_id == 0) {
|
||||
/* NonRealTime Init settings*/
|
||||
if (fctrl->i2c_data.init_settings.is_settings_valid == true) {
|
||||
if (fctrl->apply_streamoff == true) {
|
||||
fctrl->apply_streamoff = false;
|
||||
i2c_set = &fctrl->i2c_data.streamoff_settings;
|
||||
list_for_each_entry(i2c_list,
|
||||
&(i2c_set->list_head),
|
||||
list) {
|
||||
rc = cam_sensor_util_i2c_apply_setting
|
||||
(&(fctrl->io_master_info), i2c_list);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_FLASH,
|
||||
"Failed to apply stream on settings: %d",
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (fctrl->i2c_data.init_settings.is_settings_valid ==
|
||||
true) {
|
||||
list_for_each_entry(i2c_list,
|
||||
&(fctrl->i2c_data.init_settings.list_head),
|
||||
list) {
|
||||
|
@ -1202,7 +1247,8 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
|
|||
|
||||
rc = fctrl->func_tbl.apply_setting(fctrl, 0);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_FLASH, "cannot apply settings rc = %d", rc);
|
||||
CAM_ERR(CAM_FLASH,
|
||||
"cannot apply settings rc = %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -1218,6 +1264,7 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
|
|||
i2c_reg_settings =
|
||||
&fctrl->i2c_data.per_frame[frm_offset];
|
||||
if (i2c_reg_settings->is_settings_valid == true) {
|
||||
CAM_DBG(CAM_FLASH, "settings already valid");
|
||||
i2c_reg_settings->request_id = 0;
|
||||
i2c_reg_settings->is_settings_valid = false;
|
||||
goto update_req_mgr;
|
||||
|
@ -1234,6 +1281,18 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
|
|||
"Failed in parsing i2c packets");
|
||||
return rc;
|
||||
}
|
||||
if ((fctrl->flash_state == CAM_FLASH_STATE_ACQUIRE) ||
|
||||
(fctrl->flash_state == CAM_FLASH_STATE_CONFIG)) {
|
||||
fctrl->flash_state = CAM_FLASH_STATE_CONFIG;
|
||||
rc = fctrl->func_tbl.apply_setting(fctrl, 1);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_FLASH,
|
||||
"cannot apply fire settings rc = %d",
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CAM_FLASH_PACKET_OPCODE_NON_REALTIME_SET_OPS: {
|
||||
|
@ -1272,21 +1331,48 @@ int cam_flash_i2c_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg)
|
|||
return rc;
|
||||
}
|
||||
case CAM_PKT_NOP_OPCODE: {
|
||||
frm_offset = csl_packet->header.request_id %
|
||||
MAX_PER_FRAME_ARRAY;
|
||||
if ((fctrl->flash_state == CAM_FLASH_STATE_INIT) ||
|
||||
(fctrl->flash_state == CAM_FLASH_STATE_ACQUIRE)) {
|
||||
CAM_WARN(CAM_FLASH,
|
||||
"Rxed NOP packets without linking");
|
||||
frm_offset = csl_packet->header.request_id %
|
||||
MAX_PER_FRAME_ARRAY;
|
||||
fctrl->i2c_data.per_frame[frm_offset].is_settings_valid
|
||||
= false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
i2c_reg_settings =
|
||||
&fctrl->i2c_data.per_frame[frm_offset];
|
||||
i2c_reg_settings->is_settings_valid = true;
|
||||
i2c_reg_settings->request_id =
|
||||
csl_packet->header.request_id;
|
||||
CAM_DBG(CAM_FLASH, "NOP Packet is Received: req_id: %u",
|
||||
csl_packet->header.request_id);
|
||||
goto update_req_mgr;
|
||||
}
|
||||
case CAM_FLASH_PACKET_OPCODE_STREAM_OFF: {
|
||||
if (fctrl->streamoff_count > 0)
|
||||
return rc;
|
||||
|
||||
CAM_DBG(CAM_FLASH, "Received Stream off Settings");
|
||||
i2c_data = &(fctrl->i2c_data);
|
||||
fctrl->streamoff_count = fctrl->streamoff_count + 1;
|
||||
i2c_reg_settings = &i2c_data->streamoff_settings;
|
||||
i2c_reg_settings->request_id = 0;
|
||||
i2c_reg_settings->is_settings_valid = 1;
|
||||
offset = (uint32_t *)((uint8_t *)&csl_packet->payload +
|
||||
csl_packet->cmd_buf_offset);
|
||||
cmd_desc = (struct cam_cmd_buf_desc *)(offset);
|
||||
rc = cam_sensor_i2c_command_parser(&fctrl->io_master_info,
|
||||
i2c_reg_settings,
|
||||
cmd_desc, 1, NULL);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_FLASH,
|
||||
"Failed in parsing i2c Stream off packets");
|
||||
return rc;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
CAM_ERR(CAM_FLASH, "Wrong Opcode : %d",
|
||||
(csl_packet->header.op_code & 0xFFFFFF));
|
||||
|
@ -1827,6 +1913,16 @@ int cam_flash_release_dev(struct cam_flash_ctrl *fctrl)
|
|||
{
|
||||
int rc = 0;
|
||||
|
||||
if (fctrl->i2c_data.streamoff_settings.is_settings_valid == true) {
|
||||
fctrl->i2c_data.streamoff_settings.is_settings_valid = false;
|
||||
rc = delete_request(&fctrl->i2c_data.streamoff_settings);
|
||||
if (rc) {
|
||||
CAM_WARN(CAM_FLASH,
|
||||
"Failed to delete Stream off i2c_setting: %d",
|
||||
rc);
|
||||
}
|
||||
}
|
||||
|
||||
if (fctrl->bridge_intf.device_hdl != 1) {
|
||||
rc = cam_destroy_device_hdl(fctrl->bridge_intf.device_hdl);
|
||||
if (rc)
|
||||
|
@ -1837,6 +1933,7 @@ int cam_flash_release_dev(struct cam_flash_ctrl *fctrl)
|
|||
fctrl->bridge_intf.link_hdl = -1;
|
||||
fctrl->bridge_intf.session_hdl = -1;
|
||||
fctrl->last_flush_req = 0;
|
||||
fctrl->streamoff_count = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
@ -71,6 +71,7 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl,
|
|||
flash_acq_dev.device_handle;
|
||||
fctrl->bridge_intf.session_hdl =
|
||||
flash_acq_dev.session_handle;
|
||||
fctrl->apply_streamoff = false;
|
||||
|
||||
rc = copy_to_user(u64_to_user_ptr(cmd->handle),
|
||||
&flash_acq_dev,
|
||||
|
@ -123,6 +124,7 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl,
|
|||
if (fctrl->func_tbl.power_ops(fctrl, false))
|
||||
CAM_WARN(CAM_FLASH, "Power Down Failed");
|
||||
|
||||
fctrl->streamoff_count = 0;
|
||||
fctrl->flash_state = CAM_FLASH_STATE_INIT;
|
||||
break;
|
||||
}
|
||||
|
@ -130,7 +132,8 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl,
|
|||
struct cam_flash_query_cap_info flash_cap = {0};
|
||||
|
||||
CAM_DBG(CAM_FLASH, "CAM_QUERY_CAP");
|
||||
flash_cap.slot_info = fctrl->soc_info.index;
|
||||
flash_cap.slot_info = fctrl->soc_info.index;
|
||||
flash_cap.flash_type = soc_private->flash_type;
|
||||
for (i = 0; i < fctrl->flash_num_sources; i++) {
|
||||
flash_cap.max_current_flash[i] =
|
||||
soc_private->flash_max_current[i];
|
||||
|
@ -161,6 +164,7 @@ static int32_t cam_flash_driver_cmd(struct cam_flash_ctrl *fctrl,
|
|||
goto release_mutex;
|
||||
}
|
||||
|
||||
fctrl->apply_streamoff = false;
|
||||
fctrl->flash_state = CAM_FLASH_STATE_START;
|
||||
break;
|
||||
}
|
||||
|
@ -401,8 +405,9 @@ static int cam_flash_init_subdev(struct cam_flash_ctrl *fctrl)
|
|||
static int32_t cam_flash_platform_probe(struct platform_device *pdev)
|
||||
{
|
||||
int32_t rc = 0, i = 0;
|
||||
struct cam_flash_ctrl *fctrl = NULL;
|
||||
struct device_node *of_parent = NULL;
|
||||
struct cam_flash_ctrl *fctrl = NULL;
|
||||
struct device_node *of_parent = NULL;
|
||||
struct cam_hw_soc_info *soc_info = NULL;
|
||||
|
||||
CAM_DBG(CAM_FLASH, "Enter");
|
||||
if (!pdev->dev.of_node) {
|
||||
|
@ -418,6 +423,7 @@ static int32_t cam_flash_platform_probe(struct platform_device *pdev)
|
|||
fctrl->soc_info.pdev = pdev;
|
||||
fctrl->soc_info.dev = &pdev->dev;
|
||||
fctrl->soc_info.dev_name = pdev->name;
|
||||
fctrl->of_node = pdev->dev.of_node;
|
||||
|
||||
platform_set_drvdata(pdev, fctrl);
|
||||
|
||||
|
@ -458,6 +464,25 @@ static int32_t cam_flash_platform_probe(struct platform_device *pdev)
|
|||
fctrl->io_master_info.cci_client->cci_device = fctrl->cci_num;
|
||||
CAM_DBG(CAM_FLASH, "cci-index %d", fctrl->cci_num, rc);
|
||||
|
||||
soc_info = &fctrl->soc_info;
|
||||
if (!soc_info->gpio_data) {
|
||||
CAM_DBG(CAM_FLASH, "No GPIO found");
|
||||
} else {
|
||||
if (!soc_info->gpio_data->cam_gpio_common_tbl_size) {
|
||||
CAM_ERR(CAM_FLASH, "Invalid gpio table size");
|
||||
rc = -EINVAL;
|
||||
goto free_cci_resource;
|
||||
}
|
||||
|
||||
rc = cam_sensor_util_init_gpio_pin_tbl(soc_info,
|
||||
&fctrl->power_info.gpio_num_info);
|
||||
if ((rc < 0) || (!fctrl->power_info.gpio_num_info)) {
|
||||
CAM_ERR(CAM_FLASH, "No/Error Flash GPIOs");
|
||||
rc = -EINVAL;
|
||||
goto free_cci_resource;
|
||||
}
|
||||
}
|
||||
|
||||
fctrl->i2c_data.per_frame =
|
||||
kzalloc(sizeof(struct i2c_settings_array) *
|
||||
MAX_PER_FRAME_ARRAY, GFP_KERNEL);
|
||||
|
@ -469,6 +494,7 @@ static int32_t cam_flash_platform_probe(struct platform_device *pdev)
|
|||
|
||||
INIT_LIST_HEAD(&(fctrl->i2c_data.init_settings.list_head));
|
||||
INIT_LIST_HEAD(&(fctrl->i2c_data.config_settings.list_head));
|
||||
INIT_LIST_HEAD(&(fctrl->i2c_data.streamoff_settings.list_head));
|
||||
for (i = 0; i < MAX_PER_FRAME_ARRAY; i++)
|
||||
INIT_LIST_HEAD(
|
||||
&(fctrl->i2c_data.per_frame[i].list_head));
|
||||
|
@ -526,13 +552,17 @@ static int32_t cam_flash_i2c_driver_probe(struct i2c_client *client,
|
|||
{
|
||||
int32_t rc = 0, i = 0;
|
||||
struct cam_flash_ctrl *fctrl;
|
||||
struct cam_hw_soc_info *soc_info = NULL;
|
||||
|
||||
if (client == NULL || id == NULL) {
|
||||
CAM_ERR(CAM_FLASH, "Invalid Args client: %pK id: %pK",
|
||||
client, id);
|
||||
if (client == NULL) {
|
||||
CAM_ERR(CAM_FLASH, "Invalid Args client: %pK", client);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (id == NULL) {
|
||||
CAM_DBG(CAM_FLASH, "device id is Null");
|
||||
}
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
|
||||
CAM_ERR(CAM_FLASH, "%s :: i2c_check_functionality failed",
|
||||
client->name);
|
||||
|
@ -541,22 +571,51 @@ static int32_t cam_flash_i2c_driver_probe(struct i2c_client *client,
|
|||
|
||||
/* Create sensor control structure */
|
||||
fctrl = kzalloc(sizeof(*fctrl), GFP_KERNEL);
|
||||
if (!fctrl)
|
||||
if (!fctrl) {
|
||||
CAM_ERR(CAM_FLASH, "Failed to allocate memory for fctrl");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
i2c_set_clientdata(client, fctrl);
|
||||
|
||||
fctrl->io_master_info.client = client;
|
||||
fctrl->of_node = client->dev.of_node;
|
||||
fctrl->soc_info.dev = &client->dev;
|
||||
fctrl->soc_info.dev_name = client->name;
|
||||
fctrl->io_master_info.master_type = I2C_MASTER;
|
||||
|
||||
rc = cam_flash_init_default_params(fctrl);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_FLASH,
|
||||
"failed: cam_flash_init_default_params rc %d", rc);
|
||||
goto free_ctrl;
|
||||
}
|
||||
|
||||
rc = cam_flash_get_dt_data(fctrl, &fctrl->soc_info);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_FLASH, "failed: cam_sensor_parse_dt rc %d", rc);
|
||||
goto free_ctrl;
|
||||
}
|
||||
|
||||
soc_info = &fctrl->soc_info;
|
||||
if (!soc_info->gpio_data) {
|
||||
CAM_DBG(CAM_FLASH, "No GPIO found");
|
||||
} else {
|
||||
if (!soc_info->gpio_data->cam_gpio_common_tbl_size) {
|
||||
CAM_ERR(CAM_FLASH, "Invalid gpio table size");
|
||||
rc = -EINVAL;
|
||||
goto free_ctrl;
|
||||
}
|
||||
|
||||
rc = cam_sensor_util_init_gpio_pin_tbl(soc_info,
|
||||
&fctrl->power_info.gpio_num_info);
|
||||
if ((rc < 0) || (!fctrl->power_info.gpio_num_info)) {
|
||||
CAM_ERR(CAM_FLASH, "No/Error Flash GPIOs");
|
||||
rc = -EINVAL;
|
||||
goto free_ctrl;
|
||||
}
|
||||
}
|
||||
|
||||
rc = cam_flash_init_subdev(fctrl);
|
||||
if (rc)
|
||||
goto free_ctrl;
|
||||
|
@ -571,6 +630,7 @@ static int32_t cam_flash_i2c_driver_probe(struct i2c_client *client,
|
|||
|
||||
INIT_LIST_HEAD(&(fctrl->i2c_data.init_settings.list_head));
|
||||
INIT_LIST_HEAD(&(fctrl->i2c_data.config_settings.list_head));
|
||||
INIT_LIST_HEAD(&(fctrl->i2c_data.streamoff_settings.list_head));
|
||||
for (i = 0; i < MAX_PER_FRAME_ARRAY; i++)
|
||||
INIT_LIST_HEAD(&(fctrl->i2c_data.per_frame[i].list_head));
|
||||
|
||||
|
@ -624,6 +684,7 @@ static struct i2c_driver cam_flash_i2c_driver = {
|
|||
.remove = cam_flash_i2c_driver_remove,
|
||||
.driver = {
|
||||
.name = FLASH_DRIVER_I2C,
|
||||
.of_match_table = cam_flash_dt_match,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -632,14 +693,13 @@ static int32_t __init cam_flash_init_module(void)
|
|||
int32_t rc = 0;
|
||||
|
||||
rc = platform_driver_register(&cam_flash_platform_driver);
|
||||
if (rc == 0) {
|
||||
CAM_DBG(CAM_FLASH, "platform probe success");
|
||||
return 0;
|
||||
}
|
||||
if (rc < 0)
|
||||
CAM_ERR(CAM_FLASH, "platform probe failed rc: %d", rc);
|
||||
|
||||
rc = i2c_add_driver(&cam_flash_i2c_driver);
|
||||
if (rc)
|
||||
if (rc < 0)
|
||||
CAM_ERR(CAM_FLASH, "i2c_add_driver failed rc: %d", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2019, 2021 The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _CAM_FLASH_DEV_H_
|
||||
|
@ -24,6 +24,7 @@
|
|||
#include "cam_subdev.h"
|
||||
#include "cam_mem_mgr.h"
|
||||
#include "cam_sensor_cmn_header.h"
|
||||
#include "cam_sensor_util.h"
|
||||
#include "cam_soc_util.h"
|
||||
#include "cam_debug_util.h"
|
||||
#include "cam_sensor_io.h"
|
||||
|
@ -39,6 +40,7 @@
|
|||
#define CAM_FLASH_PACKET_OPCODE_INIT 0
|
||||
#define CAM_FLASH_PACKET_OPCODE_SET_OPS 1
|
||||
#define CAM_FLASH_PACKET_OPCODE_NON_REALTIME_SET_OPS 2
|
||||
#define CAM_FLASH_PACKET_OPCODE_STREAM_OFF 3
|
||||
|
||||
struct cam_flash_ctrl;
|
||||
|
||||
|
@ -130,6 +132,7 @@ struct cam_flash_frame_setting {
|
|||
* @torch_op_current : Torch operational current
|
||||
* @torch_max_current : Max supported current for LED in torch mode
|
||||
* @is_wled_flash : Detection between WLED/LED flash
|
||||
* @flash_type : Flash type
|
||||
*/
|
||||
|
||||
struct cam_flash_private_soc {
|
||||
|
@ -142,6 +145,7 @@ struct cam_flash_private_soc {
|
|||
uint32_t torch_op_current[CAM_FLASH_MAX_LED_TRIGGERS];
|
||||
uint32_t torch_max_current[CAM_FLASH_MAX_LED_TRIGGERS];
|
||||
bool is_wled_flash;
|
||||
uint32_t flash_type;
|
||||
};
|
||||
|
||||
struct cam_flash_func_tbl {
|
||||
|
@ -179,6 +183,8 @@ struct cam_flash_func_tbl {
|
|||
* @io_master_info : Information about the communication master
|
||||
* @i2c_data : I2C register settings
|
||||
* @last_flush_req : last request to flush
|
||||
* @streamoff_count : Count to hold the number of times stream off called
|
||||
* @apply_streamoff : variable to store when to apply stream off
|
||||
*/
|
||||
struct cam_flash_ctrl {
|
||||
char device_name[CAM_CTX_DEV_NAME_MAX_LENGTH];
|
||||
|
@ -207,6 +213,8 @@ struct cam_flash_ctrl {
|
|||
struct camera_io_master io_master_info;
|
||||
struct i2c_data_settings i2c_data;
|
||||
uint32_t last_flush_req;
|
||||
uint32_t streamoff_count;
|
||||
int32_t apply_streamoff;
|
||||
};
|
||||
|
||||
int cam_flash_pmic_pkt_parser(struct cam_flash_ctrl *fctrl, void *arg);
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2018, 2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2018, 2020, 2021 The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include "cam_flash_soc.h"
|
||||
#include "cam_res_mgr_api.h"
|
||||
#include <dt-bindings/msm/msm-camera.h>
|
||||
|
||||
static int32_t cam_get_source_node_info(
|
||||
struct device_node *of_node,
|
||||
|
@ -22,6 +23,13 @@ static int32_t cam_get_source_node_info(
|
|||
soc_private->is_wled_flash =
|
||||
of_property_read_bool(of_node, "wled-flash-support");
|
||||
|
||||
rc = of_property_read_u32(of_node,
|
||||
"flash-type", &soc_private->flash_type);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_FLASH, "flash-type read failed rc=%d", rc);
|
||||
soc_private->flash_type = CAM_FLASH_TYPE_PMIC;
|
||||
}
|
||||
|
||||
switch_src_node = of_parse_phandle(of_node, "switch-source", 0);
|
||||
if (!switch_src_node) {
|
||||
CAM_WARN(CAM_FLASH, "switch_src_node NULL");
|
||||
|
@ -232,7 +240,14 @@ int cam_flash_get_dt_data(struct cam_flash_ctrl *fctrl,
|
|||
rc = -ENOMEM;
|
||||
goto release_soc_res;
|
||||
}
|
||||
of_node = fctrl->pdev->dev.of_node;
|
||||
|
||||
if (fctrl->of_node == NULL) {
|
||||
CAM_ERR(CAM_FLASH, "device node is NULL");
|
||||
rc = -EINVAL;
|
||||
goto free_soc_private;
|
||||
}
|
||||
|
||||
of_node = fctrl->of_node;
|
||||
|
||||
rc = cam_soc_util_get_dt_properties(soc_info);
|
||||
if (rc) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
|
@ -9,6 +9,7 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include "cam_debug_util.h"
|
||||
#include "cam_res_mgr_api.h"
|
||||
#include "cam_res_mgr_private.h"
|
||||
|
@ -604,15 +605,13 @@ EXPORT_SYMBOL(cam_res_mgr_shared_clk_config);
|
|||
|
||||
static int cam_res_mgr_parse_dt(struct device *dev)
|
||||
{
|
||||
int rc = 0;
|
||||
int rc = 0, i = 0;
|
||||
struct device_node *of_node = NULL;
|
||||
struct cam_res_mgr_dt *dt = &cam_res->dt;
|
||||
|
||||
of_node = dev->of_node;
|
||||
|
||||
dt->num_shared_gpio = of_property_count_u32_elems(of_node,
|
||||
"shared-gpios");
|
||||
|
||||
dt->num_shared_gpio = of_gpio_count(of_node);
|
||||
if (dt->num_shared_gpio > MAX_SHARED_GPIO_SIZE ||
|
||||
dt->num_shared_gpio <= 0) {
|
||||
/*
|
||||
|
@ -624,11 +623,14 @@ static int cam_res_mgr_parse_dt(struct device *dev)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
rc = of_property_read_u32_array(of_node, "shared-gpios",
|
||||
dt->shared_gpio, dt->num_shared_gpio);
|
||||
if (rc) {
|
||||
CAM_ERR(CAM_RES, "Get shared gpio array failed.");
|
||||
return -EINVAL;
|
||||
for (i = 0; i < dt->num_shared_gpio; i++) {
|
||||
dt->shared_gpio[i] = of_get_gpio(of_node, i);
|
||||
if (dt->shared_gpio[i] < 0) {
|
||||
CAM_ERR(CAM_RES, "Get shared gpio array failed.");
|
||||
return -EINVAL;
|
||||
}
|
||||
CAM_DBG(CAM_UTIL, "shared_gpio[%d] = %d",
|
||||
i, dt->shared_gpio[i]);
|
||||
}
|
||||
|
||||
dt->pinctrl_info.pinctrl = devm_pinctrl_get(dev);
|
||||
|
|
|
@ -1134,6 +1134,7 @@ int cam_sensor_power_up(struct cam_sensor_ctrl_t *s_ctrl)
|
|||
//add by hzt 2021-9-4 for control external gpio
|
||||
power_info->imx582_avdd18_gpio=s_ctrl->imx582_avdd18_gpio;
|
||||
//add by hzt 2021-9-4 for control external gpio
|
||||
power_info->imx582_avdd28_gpio=s_ctrl->imx582_avdd28_gpio;
|
||||
|
||||
rc = cam_sensor_core_power_up(power_info, soc_info);
|
||||
if (rc < 0) {
|
||||
|
|
|
@ -114,6 +114,7 @@ struct cam_sensor_ctrl_t {
|
|||
//add by hzt 2021-9-4 for control external gpio
|
||||
int imx582_avdd18_gpio;
|
||||
//add by hzt 2021-9-4 for control external gpio
|
||||
int imx582_avdd28_gpio;
|
||||
};
|
||||
|
||||
#endif /* _CAM_SENSOR_DEV_H_ */
|
||||
|
|
|
@ -260,6 +260,7 @@ int32_t cam_sensor_parse_dt(struct cam_sensor_ctrl_t *s_ctrl)
|
|||
|
||||
//add by hzt 2021-9-4 for control external gpio
|
||||
|
||||
s_ctrl->imx582_avdd28_gpio = of_get_named_gpio(s_ctrl->of_node, "imx582_avdd28,pwr-gpio", 0);
|
||||
|
||||
|
||||
/* Initialize mutex */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include "cam_sensor_cmn_header.h"
|
||||
|
@ -32,9 +32,14 @@ static int32_t cam_qup_i2c_rxdata(
|
|||
},
|
||||
};
|
||||
rc = i2c_transfer(dev_client->adapter, msgs, 2);
|
||||
if (rc < 0)
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_SENSOR, "failed 0x%x", saddr);
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
/* Returns negative errno */
|
||||
/* else the number of messages executed. */
|
||||
/* So positive values are not errors. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -53,9 +58,14 @@ static int32_t cam_qup_i2c_txdata(
|
|||
},
|
||||
};
|
||||
rc = i2c_transfer(dev_client->client->adapter, msg, 1);
|
||||
if (rc < 0)
|
||||
if (rc < 0) {
|
||||
CAM_ERR(CAM_SENSOR, "failed 0x%x", saddr);
|
||||
return rc;
|
||||
return rc;
|
||||
}
|
||||
/* Returns negative errno, */
|
||||
/* else the number of messages executed. */
|
||||
/* So positive values are not errors. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t cam_qup_i2c_read(struct i2c_client *client,
|
||||
|
|
|
@ -319,6 +319,7 @@ struct cam_sensor_power_ctrl_t {
|
|||
//add by hzt 2021-9-4 for control external gpio
|
||||
int imx582_avdd18_gpio;
|
||||
//add by hzt 2021-9-4 for control external gpio
|
||||
int imx582_avdd28_gpio;
|
||||
};
|
||||
|
||||
struct cam_camera_slave_info {
|
||||
|
|
|
@ -1774,6 +1774,7 @@ int msm_cam_sensor_handle_reg_gpio(int seq_type,
|
|||
|
||||
//add by hzt 2021-9-4 for control external gpio
|
||||
//s_ctrl.imx582_avdd18_gpio = of_get_named_gpio(s_ctrl->of_node, "imx582_avdd18,pwr-gpio", 0);
|
||||
//s_ctrl.imx582_avdd28_gpio = of_get_named_gpio(s_ctrl->of_node, "imx582_avdd28,pwr-gpio", 0);
|
||||
//add by hzt 2021-9-4 control external gpio
|
||||
|
||||
|
||||
|
@ -2068,6 +2069,15 @@ int cam_sensor_core_power_up(struct cam_sensor_power_ctrl_t *ctrl,
|
|||
//gpio_set_value_cansleep(ctrl->imx582_avdd18_gpio, 1);
|
||||
gpio_direction_output(ctrl->imx582_avdd18_gpio,1);
|
||||
gpio_free(ctrl->imx582_avdd18_gpio);
|
||||
|
||||
CAM_DBG(CAM_SENSOR, "before to request imx582_avdd28_gpio:%d,,\n",ctrl->imx582_avdd28_gpio);
|
||||
ret = gpio_request(ctrl->imx582_avdd28_gpio, "imx582_avdd28_gpio");
|
||||
if (ret < 0) {
|
||||
CAM_DBG(CAM_SENSOR, "Failed to request imx582_avdd28_gpio:%d,,\n",ctrl->imx582_avdd28_gpio);
|
||||
}
|
||||
//gpio_set_value_cansleep(ctrl->imx582_avdd28_gpio, 1);
|
||||
gpio_direction_output(ctrl->imx582_avdd28_gpio,1);
|
||||
gpio_free(ctrl->imx582_avdd28_gpio);
|
||||
}
|
||||
//add by hzt 2021-9-4 control external gpio
|
||||
|
||||
|
@ -2357,7 +2367,6 @@ int cam_sensor_util_power_down(struct cam_sensor_power_ctrl_t *ctrl,
|
|||
//add by hzt 2021-9-4 for control external gpio
|
||||
if(pd->seq_val==SENSOR_VANA)
|
||||
{
|
||||
|
||||
CAM_DBG(CAM_SENSOR, "before to request imx582_avdd18_gpio:%d,,\n",ctrl->imx582_avdd18_gpio);
|
||||
ret = gpio_request(ctrl->imx582_avdd18_gpio, "imx582_avdd18_gpio");
|
||||
if (ret < 0) {
|
||||
|
@ -2366,6 +2375,15 @@ int cam_sensor_util_power_down(struct cam_sensor_power_ctrl_t *ctrl,
|
|||
//gpio_set_value_cansleep(ctrl->imx582_avdd18_gpio, 0);
|
||||
gpio_direction_output(ctrl->imx582_avdd18_gpio,0);
|
||||
gpio_free(ctrl->imx582_avdd18_gpio);
|
||||
|
||||
CAM_DBG(CAM_SENSOR, "before to request imx582_avdd28_gpio:%d,,\n",ctrl->imx582_avdd28_gpio);
|
||||
ret = gpio_request(ctrl->imx582_avdd28_gpio, "imx582_avdd28_gpio");
|
||||
if (ret < 0) {
|
||||
CAM_DBG(CAM_SENSOR, "Failed to request imx582_avdd28_gpio:%d,,\n",ctrl->imx582_avdd28_gpio);
|
||||
}
|
||||
//gpio_set_value_cansleep(ctrl->imx582_avdd28_gpio, 0);
|
||||
gpio_direction_output(ctrl->imx582_avdd28_gpio,0);
|
||||
gpio_free(ctrl->imx582_avdd28_gpio);
|
||||
}
|
||||
//add by hzt 2021-9-4 control external gpio
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
@ -203,6 +203,8 @@ struct cam_dma_buff_info {
|
|||
|
||||
struct cam_sec_buff_info {
|
||||
struct dma_buf *buf;
|
||||
struct dma_buf_attachment *attach;
|
||||
struct sg_table *table;
|
||||
enum dma_data_direction dir;
|
||||
int ref_count;
|
||||
dma_addr_t paddr;
|
||||
|
@ -2674,6 +2676,8 @@ static int cam_smmu_map_stage2_buffer_and_add_to_list(int idx, int ion_fd,
|
|||
mapping_info->dir = dma_dir;
|
||||
mapping_info->ref_count = 1;
|
||||
mapping_info->buf = dmabuf;
|
||||
mapping_info->attach = attach;
|
||||
mapping_info->table = table;
|
||||
|
||||
CAM_DBG(CAM_SMMU, "idx=%d, ion_fd=%d, dev=%pK, paddr=%pK, len=%u",
|
||||
idx, ion_fd,
|
||||
|
@ -2774,11 +2778,28 @@ static int cam_smmu_secure_unmap_buf_and_remove_from_list(
|
|||
struct cam_sec_buff_info *mapping_info,
|
||||
int idx)
|
||||
{
|
||||
if (!mapping_info) {
|
||||
CAM_ERR(CAM_SMMU, "Error: List doesn't exist");
|
||||
if ((!mapping_info->buf) || (!mapping_info->table) ||
|
||||
(!mapping_info->attach)) {
|
||||
CAM_ERR(CAM_SMMU,
|
||||
"Error: Invalid params dev = %pK, table = %pK",
|
||||
(void *)iommu_cb_set.cb_info[idx].dev,
|
||||
(void *)mapping_info->table);
|
||||
CAM_ERR(CAM_SMMU, "Error:dma_buf = %pK, attach = %pK\n",
|
||||
(void *)mapping_info->buf,
|
||||
(void *)mapping_info->attach);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* skip cache operations */
|
||||
mapping_info->attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC;
|
||||
|
||||
/* iommu buffer clean up */
|
||||
dma_buf_unmap_attachment(mapping_info->attach,
|
||||
mapping_info->table, mapping_info->dir);
|
||||
dma_buf_detach(mapping_info->buf, mapping_info->attach);
|
||||
dma_buf_put(mapping_info->buf);
|
||||
mapping_info->buf = NULL;
|
||||
|
||||
list_del_init(&mapping_info->list);
|
||||
|
||||
CAM_DBG(CAM_SMMU, "unmap fd: %d, idx : %d", mapping_info->ion_fd, idx);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
|
@ -471,6 +471,7 @@ static int cam_sync_handle_create(struct cam_private_ioctl_arg *k_ioctl)
|
|||
u64_to_user_ptr(k_ioctl->ioctl_ptr),
|
||||
k_ioctl->size))
|
||||
return -EFAULT;
|
||||
sync_create.name[SYNC_DEBUG_NAME_LEN] = '\0';
|
||||
|
||||
result = cam_sync_create(&sync_create.sync_obj,
|
||||
sync_create.name);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only WITH Linux-syscall-note */
|
||||
/*
|
||||
* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2019, 2021 The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef __UAPI_CAM_SENSOR_H__
|
||||
|
@ -474,6 +474,7 @@ struct cam_flash_query_curr {
|
|||
* @max_current_flash : max supported current for flash
|
||||
* @max_duration_flash : max flash turn on duration
|
||||
* @max_current_torch : max supported current for torch
|
||||
* @flash_type : Indicates about the flash type -I2C,GPIO,PMIC
|
||||
*
|
||||
*/
|
||||
struct cam_flash_query_cap_info {
|
||||
|
@ -481,6 +482,7 @@ struct cam_flash_query_cap_info {
|
|||
uint32_t max_current_flash[CAM_FLASH_MAX_LED_TRIGGERS];
|
||||
uint32_t max_duration_flash[CAM_FLASH_MAX_LED_TRIGGERS];
|
||||
uint32_t max_current_torch[CAM_FLASH_MAX_LED_TRIGGERS];
|
||||
uint32_t flash_type;
|
||||
} __attribute__ ((packed));
|
||||
|
||||
#endif
|
||||
|
|
|
@ -70,6 +70,7 @@ msm_drm-$(CONFIG_DRM_MSM_SDE) += sde/sde_crtc.o \
|
|||
sde/sde_hw_qdss.o \
|
||||
sde_dbg.o \
|
||||
sde_dbg_evtlog.o \
|
||||
sde/sde_hw_rc.o \
|
||||
|
||||
msm_drm-$(CONFIG_DRM_SDE_WB) += sde/sde_wb.o \
|
||||
sde/sde_encoder_phys_wb.o \
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
|
@ -2570,6 +2570,27 @@ static int dp_display_config_hdr(struct dp_display *dp_display, void *panel,
|
|||
core_clk_rate, flush_hdr);
|
||||
}
|
||||
|
||||
static int dp_display_get_display_type(struct dp_display *dp_display,
|
||||
const char **display_type)
|
||||
{
|
||||
struct dp_display_private *dp;
|
||||
|
||||
if (!dp_display || !display_type) {
|
||||
pr_err("invalid input\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dp = container_of(dp_display, struct dp_display_private, dp_display);
|
||||
|
||||
*display_type = dp->parser->display_type;
|
||||
|
||||
if (!strcmp(*display_type, "primary"))
|
||||
dp_display->is_primary = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int dp_display_setup_colospace(struct dp_display *dp_display,
|
||||
void *panel,
|
||||
u32 colorspace)
|
||||
|
@ -3100,6 +3121,7 @@ static int dp_display_probe(struct platform_device *pdev)
|
|||
g_dp_display->post_open = NULL;
|
||||
g_dp_display->post_init = dp_display_post_init;
|
||||
g_dp_display->config_hdr = dp_display_config_hdr;
|
||||
g_dp_display->get_display_type = dp_display_get_display_type;
|
||||
g_dp_display->mst_install = dp_display_mst_install;
|
||||
g_dp_display->mst_uninstall = dp_display_mst_uninstall;
|
||||
g_dp_display->mst_connector_install = dp_display_mst_connector_install;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DP_DISPLAY_H_
|
||||
|
@ -72,6 +72,7 @@ struct dp_display {
|
|||
u32 max_pclk_khz;
|
||||
u32 no_mst_encoder;
|
||||
void *dp_mst_prv_info;
|
||||
bool is_primary;
|
||||
|
||||
int (*enable)(struct dp_display *dp_display, void *panel);
|
||||
int (*post_enable)(struct dp_display *dp_display, void *panel);
|
||||
|
@ -126,6 +127,8 @@ struct dp_display {
|
|||
struct drm_connector *connector, char *pps_cmd);
|
||||
void (*wakeup_phy_layer)(struct dp_display *dp_display,
|
||||
bool wakeup);
|
||||
int (*get_display_type)(struct dp_display *dp_display,
|
||||
const char **display_type);
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DRM_MSM_DP
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2019, 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <drm/drm_atomic_helper.h>
|
||||
|
@ -580,6 +580,19 @@ int dp_connector_get_modes(struct drm_connector *connector,
|
|||
return rc;
|
||||
}
|
||||
|
||||
int dp_connnector_set_info_blob(struct drm_connector *connector,
|
||||
void *info, void *display, struct msm_mode_info *mode_info)
|
||||
{
|
||||
struct dp_display *dp_display = display;
|
||||
const char *display_type = NULL;
|
||||
|
||||
dp_display->get_display_type(dp_display, &display_type);
|
||||
sde_kms_info_add_keystr(info,
|
||||
"display type", display_type);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dp_drm_bridge_init(void *data, struct drm_encoder *encoder)
|
||||
{
|
||||
int rc = 0;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2017-2019, 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DP_DRM_H_
|
||||
|
@ -177,6 +177,18 @@ int dp_mst_init(struct dp_display *dp_display);
|
|||
* @display: Pointer to private display structure
|
||||
*/
|
||||
void dp_mst_deinit(struct dp_display *dp_display);
|
||||
|
||||
/**
|
||||
* dp_conn_set_info_blob - callback to perform info blob initialization
|
||||
* @connector: Pointer to drm connector structure
|
||||
* @info: Pointer to sde connector info structure
|
||||
* @display: Pointer to private display handle
|
||||
* @mode_info: Pointer to mode info structure
|
||||
* Returns: Zero on success
|
||||
*/
|
||||
int dp_connnector_set_info_blob(struct drm_connector *connector,
|
||||
void *info, void *display, struct msm_mode_info *mode_info);
|
||||
|
||||
#else
|
||||
static inline int dp_connector_config_hdr(struct drm_connector *connector,
|
||||
void *display, struct sde_connector_state *c_state)
|
||||
|
@ -278,6 +290,13 @@ static inline int dp_mst_deinit(struct dp_display *dp_display)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dp_connnector_set_info_blob(struct drm_connector *connector,
|
||||
void *info, void *display, struct msm_mode_info *mode_info)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* _DP_DRM_H_ */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/of_gpio.h>
|
||||
|
@ -166,6 +166,10 @@ static int dp_parser_misc(struct dp_parser *parser)
|
|||
if (rc)
|
||||
parser->max_lclk_khz = DP_MAX_LINK_CLK_KHZ;
|
||||
|
||||
parser->display_type = of_get_property(of_node, "label", NULL);
|
||||
if (!parser->display_type)
|
||||
parser->display_type = "unknown";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2012-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2012-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DP_PARSER_H_
|
||||
|
@ -198,6 +198,7 @@ static inline char *dp_phy_aux_config_type_to_string(u32 cfg_type)
|
|||
* @max_dp_dsc_input_width_pixs: Maximum input width for DSC block
|
||||
* @has_widebus: widebus (2PPC) feature eanble status
|
||||
*@mst_fixed_port: mst port_num reserved for fixed topology
|
||||
* @display_type: display type as defined in device tree.
|
||||
* @parse: function to be called by client to parse device tree.
|
||||
* @get_io: function to be called by client to get io data.
|
||||
* @get_io_buf: function to be called by client to get io buffers.
|
||||
|
@ -230,6 +231,8 @@ struct dp_parser {
|
|||
bool lphw_hpd;
|
||||
u32 mst_fixed_port[MAX_DP_MST_STREAMS];
|
||||
|
||||
const char *display_type;
|
||||
|
||||
int (*parse)(struct dp_parser *parser);
|
||||
struct dp_io_data *(*get_io)(struct dp_parser *parser, char *name);
|
||||
void (*get_io_buf)(struct dp_parser *parser, char *name);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
@ -466,7 +466,6 @@ void set_lcd_vcc_3v3_gpio(int enable){
|
|||
}
|
||||
EXPORT_SYMBOL(set_lcd_vcc_3v3_gpio);//by eric.wang
|
||||
|
||||
|
||||
static int dsi_panel_power_on(struct dsi_panel *panel)
|
||||
{
|
||||
int rc = 0;
|
||||
|
@ -662,12 +661,29 @@ static int dsi_panel_wled_register(struct dsi_panel *panel,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int dsi_panel_dcs_set_display_brightness_c2(struct mipi_dsi_device *dsi,
|
||||
u32 bl_lvl)
|
||||
{
|
||||
u16 brightness = (u16)bl_lvl;
|
||||
u8 first_byte = brightness & 0xff;
|
||||
u8 second_byte = brightness >> 8;
|
||||
u8 payload[8] = {second_byte, first_byte,
|
||||
second_byte, first_byte,
|
||||
second_byte, first_byte,
|
||||
second_byte, first_byte};
|
||||
|
||||
return mipi_dsi_dcs_write(dsi, 0xC2, payload, sizeof(payload));
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int dsi_panel_update_backlight(struct dsi_panel *panel,
|
||||
u32 bl_lvl)
|
||||
{
|
||||
int rc = 0;
|
||||
static int old_bkl = 0;
|
||||
struct mipi_dsi_device *dsi;
|
||||
struct dsi_backlight_config *bl;
|
||||
//DSI_ERR("----------update dcs backlight:%d,by eric.wang------\n", bl_lvl);
|
||||
if(bl_lvl==0&&old_bkl>0){
|
||||
set_lcd_vcc_3v3_gpio(0);
|
||||
|
@ -682,11 +698,16 @@ static int dsi_panel_update_backlight(struct dsi_panel *panel,
|
|||
}
|
||||
|
||||
dsi = &panel->mipi_device;
|
||||
bl = &panel->bl_config;
|
||||
|
||||
if (panel->bl_config.bl_inverted_dbv)
|
||||
bl_lvl = (((bl_lvl & 0xff) << 8) | (bl_lvl >> 8));
|
||||
|
||||
rc = mipi_dsi_dcs_set_display_brightness(dsi, bl_lvl);
|
||||
if (panel->bl_config.bl_dcs_subtype == 0xc2)
|
||||
rc = dsi_panel_dcs_set_display_brightness_c2(dsi, bl_lvl);
|
||||
else
|
||||
rc = mipi_dsi_dcs_set_display_brightness(dsi, bl_lvl);
|
||||
|
||||
if (rc < 0)
|
||||
DSI_ERR("failed to update dcs backlight:%d\n", bl_lvl);
|
||||
|
||||
|
@ -1907,7 +1928,7 @@ static int dsi_panel_create_cmd_packets(const char *data,
|
|||
cmd[i].msg.type = data[0];
|
||||
cmd[i].last_command = (data[1] == 1);
|
||||
cmd[i].msg.channel = data[2];
|
||||
cmd[i].msg.flags |= (data[3] == 1 ? MIPI_DSI_MSG_REQ_ACK : 0);
|
||||
cmd[i].msg.flags |= data[3];
|
||||
cmd[i].msg.ctrl = 0;
|
||||
cmd[i].post_wait_ms = cmd[i].msg.wait_ms = data[4];
|
||||
cmd[i].msg.tx_len = ((data[5] << 8) | (data[6]));
|
||||
|
@ -2417,6 +2438,16 @@ static int dsi_panel_parse_bl_config(struct dsi_panel *panel)
|
|||
panel->bl_config.brightness_max_level = val;
|
||||
}
|
||||
|
||||
rc = utils->read_u32(utils->data, "qcom,mdss-dsi-bl-ctrl-dcs-subtype",
|
||||
&val);
|
||||
if (rc) {
|
||||
DSI_DEBUG("[%s] bl-ctrl-dcs-subtype, defautling to zero\n",
|
||||
panel->name);
|
||||
panel->bl_config.bl_dcs_subtype = 0;
|
||||
} else {
|
||||
panel->bl_config.bl_dcs_subtype = val;
|
||||
}
|
||||
|
||||
panel->bl_config.bl_inverted_dbv = utils->read_bool(utils->data,
|
||||
"qcom,mdss-dsi-bl-inverted-dbv");
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DSI_PANEL_H_
|
||||
|
@ -122,6 +122,7 @@ struct dsi_backlight_config {
|
|||
u32 bl_scale;
|
||||
u32 bl_scale_sv;
|
||||
bool bl_inverted_dbv;
|
||||
u32 bl_dcs_subtype;
|
||||
|
||||
int en_gpio;
|
||||
/* PWM params */
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* Author: Rob Clark <robdclark@gmail.com>
|
||||
*
|
||||
|
@ -61,6 +61,8 @@
|
|||
#define MSM_VERSION_MINOR 3
|
||||
#define MSM_VERSION_PATCHLEVEL 0
|
||||
|
||||
static DEFINE_MUTEX(msm_release_lock);
|
||||
|
||||
static void msm_fb_output_poll_changed(struct drm_device *dev)
|
||||
{
|
||||
struct msm_drm_private *priv = NULL;
|
||||
|
@ -1460,14 +1462,27 @@ void msm_mode_object_event_notify(struct drm_mode_object *obj,
|
|||
|
||||
static int msm_release(struct inode *inode, struct file *filp)
|
||||
{
|
||||
struct drm_file *file_priv = filp->private_data;
|
||||
struct drm_minor *minor = file_priv->minor;
|
||||
struct drm_device *dev = minor->dev;
|
||||
struct msm_drm_private *priv = dev->dev_private;
|
||||
struct drm_file *file_priv;
|
||||
struct drm_minor *minor;
|
||||
struct drm_device *dev;
|
||||
struct msm_drm_private *priv;
|
||||
struct msm_drm_event *node, *temp, *tmp_node;
|
||||
u32 count;
|
||||
unsigned long flags;
|
||||
LIST_HEAD(tmp_head);
|
||||
int ret = 0;
|
||||
|
||||
mutex_lock(&msm_release_lock);
|
||||
|
||||
file_priv = filp->private_data;
|
||||
if (!file_priv) {
|
||||
ret = -EINVAL;
|
||||
goto end;
|
||||
}
|
||||
|
||||
minor = file_priv->minor;
|
||||
dev = minor->dev;
|
||||
priv = dev->dev_private;
|
||||
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
list_for_each_entry_safe(node, temp, &priv->client_event_list,
|
||||
|
@ -1504,7 +1519,11 @@ static int msm_release(struct inode *inode, struct file *filp)
|
|||
*/
|
||||
msm_preclose(dev, file_priv);
|
||||
|
||||
return drm_release(inode, filp);
|
||||
ret = drm_release(inode, filp);
|
||||
filp->private_data = NULL;
|
||||
end:
|
||||
mutex_unlock(&msm_release_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* Author: Rob Clark <robdclark@gmail.com>
|
||||
*
|
||||
|
@ -138,6 +138,7 @@ enum msm_mdp_crtc_property {
|
|||
CRTC_PROP_DEST_SCALER_LUT_ED,
|
||||
CRTC_PROP_DEST_SCALER_LUT_CIR,
|
||||
CRTC_PROP_DEST_SCALER_LUT_SEP,
|
||||
CRTC_PROP_DSPP_INFO,
|
||||
|
||||
/* # of blob properties */
|
||||
CRTC_PROP_BLOBCOUNT,
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "%s: " fmt, __func__
|
||||
|
||||
#include <linux/dma-buf.h>
|
||||
#include <linux/string.h>
|
||||
#include <drm/msm_drm_pp.h>
|
||||
#include "sde_color_processing.h"
|
||||
#include "sde_kms.h"
|
||||
|
@ -29,6 +30,7 @@ struct sde_cp_node {
|
|||
struct list_head active_list;
|
||||
struct list_head dirty_list;
|
||||
bool is_dspp_feature;
|
||||
bool lm_flush_override;
|
||||
u32 prop_blob_sz;
|
||||
struct sde_irq_callback *irq;
|
||||
};
|
||||
|
@ -55,6 +57,8 @@ static void dspp_ad_install_property(struct drm_crtc *crtc);
|
|||
|
||||
static void dspp_ltm_install_property(struct drm_crtc *crtc);
|
||||
|
||||
static void dspp_rc_install_property(struct drm_crtc *crtc);
|
||||
|
||||
static void dspp_vlut_install_property(struct drm_crtc *crtc);
|
||||
|
||||
static void dspp_gamut_install_property(struct drm_crtc *crtc);
|
||||
|
@ -111,6 +115,7 @@ do { \
|
|||
func[SDE_DSPP_IGC] = dspp_igc_install_property; \
|
||||
func[SDE_DSPP_HIST] = dspp_hist_install_property; \
|
||||
func[SDE_DSPP_DITHER] = dspp_dither_install_property; \
|
||||
func[SDE_DSPP_RC] = dspp_rc_install_property; \
|
||||
} while (0)
|
||||
|
||||
typedef void (*lm_prop_install_func_t)(struct drm_crtc *crtc);
|
||||
|
@ -122,7 +127,7 @@ static void lm_gc_install_property(struct drm_crtc *crtc);
|
|||
#define setup_lm_prop_install_funcs(func) \
|
||||
(func[SDE_MIXER_GC] = lm_gc_install_property)
|
||||
|
||||
enum {
|
||||
enum sde_cp_crtc_features {
|
||||
/* Append new DSPP features before SDE_CP_CRTC_DSPP_MAX */
|
||||
/* DSPP Features start */
|
||||
SDE_CP_CRTC_DSPP_IGC,
|
||||
|
@ -158,6 +163,7 @@ enum {
|
|||
SDE_CP_CRTC_DSPP_LTM_QUEUE_BUF2,
|
||||
SDE_CP_CRTC_DSPP_LTM_QUEUE_BUF3,
|
||||
SDE_CP_CRTC_DSPP_LTM_VLUT,
|
||||
SDE_CP_CRTC_DSPP_RC_MASK,
|
||||
SDE_CP_CRTC_DSPP_MAX,
|
||||
/* DSPP features end */
|
||||
|
||||
|
@ -169,12 +175,52 @@ enum {
|
|||
SDE_CP_CRTC_MAX_FEATURES,
|
||||
};
|
||||
|
||||
enum sde_cp_crtc_pu_features {
|
||||
SDE_CP_CRTC_DSPP_RC_PU,
|
||||
SDE_CP_CRTC_MAX_PU_FEATURES,
|
||||
};
|
||||
|
||||
typedef void (*dspp_cap_update_func_t)(struct sde_crtc *crtc,
|
||||
struct sde_kms_info *info);
|
||||
enum sde_dspp_caps_features {
|
||||
SDE_CP_RC_CAPS,
|
||||
SDE_CP_CAPS_MAX,
|
||||
};
|
||||
|
||||
static void rc_caps_update(struct sde_crtc *crtc, struct sde_kms_info *info);
|
||||
static dspp_cap_update_func_t dspp_cap_update_func[SDE_CP_CAPS_MAX];
|
||||
|
||||
#define setup_dspp_caps_funcs(func) \
|
||||
(func[SDE_CP_RC_CAPS] = rc_caps_update)
|
||||
|
||||
static void _sde_cp_crtc_enable_hist_irq(struct sde_crtc *sde_crtc);
|
||||
|
||||
typedef int (*set_feature_wrapper)(struct sde_hw_dspp *hw_dspp,
|
||||
typedef int (*feature_wrapper)(struct sde_hw_dspp *hw_dspp,
|
||||
struct sde_hw_cp_cfg *hw_cfg,
|
||||
struct sde_crtc *hw_crtc);
|
||||
|
||||
|
||||
static struct sde_kms *get_kms(struct drm_crtc *crtc)
|
||||
{
|
||||
struct msm_drm_private *priv = crtc->dev->dev_private;
|
||||
|
||||
return to_sde_kms(priv->kms);
|
||||
}
|
||||
|
||||
static void update_pu_feature_enable(struct sde_crtc *sde_crtc,
|
||||
u32 feature, bool enable)
|
||||
{
|
||||
if (!sde_crtc || feature > SDE_CP_CRTC_MAX_PU_FEATURES) {
|
||||
DRM_ERROR("invalid args feature %d\n", feature);
|
||||
return;
|
||||
}
|
||||
|
||||
if (enable)
|
||||
sde_crtc->cp_pu_feature_mask |= BIT(feature);
|
||||
else
|
||||
sde_crtc->cp_pu_feature_mask &= ~BIT(feature);
|
||||
}
|
||||
|
||||
static int set_dspp_vlut_feature(struct sde_hw_dspp *hw_dspp,
|
||||
struct sde_hw_cp_cfg *hw_cfg,
|
||||
struct sde_crtc *hw_crtc)
|
||||
|
@ -655,9 +701,127 @@ static int set_ltm_hist_crtl_feature(struct sde_hw_dspp *hw_dspp,
|
|||
return ret;
|
||||
}
|
||||
|
||||
set_feature_wrapper crtc_feature_wrappers[SDE_CP_CRTC_MAX_FEATURES];
|
||||
static int check_rc_mask_feature(struct sde_hw_dspp *hw_dspp,
|
||||
struct sde_hw_cp_cfg *hw_cfg,
|
||||
struct sde_crtc *sde_crtc)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
#define setup_crtc_feature_wrappers(wrappers) \
|
||||
if (!hw_dspp || !hw_cfg || !sde_crtc) {
|
||||
DRM_ERROR("invalid arguments");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!hw_dspp->ops.validate_rc_mask) {
|
||||
DRM_ERROR("invalid rc ops");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = hw_dspp->ops.validate_rc_mask(hw_dspp, hw_cfg);
|
||||
if (ret)
|
||||
DRM_ERROR("failed to validate rc mask %d", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_rc_mask_feature(struct sde_hw_dspp *hw_dspp,
|
||||
struct sde_hw_cp_cfg *hw_cfg,
|
||||
struct sde_crtc *sde_crtc)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!hw_dspp || !hw_cfg || !sde_crtc) {
|
||||
DRM_ERROR("invalid arguments\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!hw_dspp->ops.setup_rc_mask || !hw_dspp->ops.setup_rc_data) {
|
||||
DRM_ERROR("invalid rc ops\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DRM_DEBUG_DRIVER("dspp %d setup mask for rc instance %u\n",
|
||||
hw_dspp->idx, hw_dspp->cap->sblk->rc.idx);
|
||||
|
||||
ret = hw_dspp->ops.setup_rc_mask(hw_dspp, hw_cfg);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to setup rc mask, ret %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* rc data should be programmed once if dspp are in multi-pipe mode */
|
||||
if (hw_dspp->cap->sblk->rc.idx % hw_cfg->num_of_mixers == 0) {
|
||||
ret = hw_dspp->ops.setup_rc_data(hw_dspp, hw_cfg);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed to setup rc data, ret %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
update_pu_feature_enable(sde_crtc, SDE_CP_CRTC_DSPP_RC_PU,
|
||||
hw_cfg->payload != NULL);
|
||||
exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int set_rc_pu_feature(struct sde_hw_dspp *hw_dspp,
|
||||
struct sde_hw_cp_cfg *hw_cfg,
|
||||
struct sde_crtc *sde_crtc)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!hw_dspp || !hw_cfg || !sde_crtc) {
|
||||
DRM_ERROR("invalid arguments\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!hw_dspp->ops.setup_rc_pu_roi) {
|
||||
DRM_ERROR("invalid rc ops\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
DRM_DEBUG_DRIVER("dspp %d setup pu roi for rc instance %u\n",
|
||||
hw_dspp->idx, hw_dspp->cap->sblk->rc.idx);
|
||||
|
||||
ret = hw_dspp->ops.setup_rc_pu_roi(hw_dspp, hw_cfg);
|
||||
if (ret < 0)
|
||||
DRM_ERROR("failed to setup rc pu roi, ret %d\n", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int check_rc_pu_feature(struct sde_hw_dspp *hw_dspp,
|
||||
struct sde_hw_cp_cfg *hw_cfg,
|
||||
struct sde_crtc *sde_crtc)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!hw_dspp || !hw_cfg || !sde_crtc) {
|
||||
DRM_ERROR("invalid arguments\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!hw_dspp->ops.validate_rc_pu_roi) {
|
||||
SDE_ERROR("invalid rc ops");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = hw_dspp->ops.validate_rc_pu_roi(hw_dspp, hw_cfg);
|
||||
if (ret)
|
||||
SDE_ERROR("failed to validate rc pu roi, ret %d", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
feature_wrapper check_crtc_feature_wrappers[SDE_CP_CRTC_MAX_FEATURES];
|
||||
#define setup_check_crtc_feature_wrappers(wrappers) \
|
||||
do { \
|
||||
memset(wrappers, 0, sizeof(wrappers)); \
|
||||
wrappers[SDE_CP_CRTC_DSPP_RC_MASK] = check_rc_mask_feature; \
|
||||
} while (0)
|
||||
|
||||
feature_wrapper set_crtc_feature_wrappers[SDE_CP_CRTC_MAX_FEATURES];
|
||||
#define setup_set_crtc_feature_wrappers(wrappers) \
|
||||
do { \
|
||||
memset(wrappers, 0, sizeof(wrappers)); \
|
||||
wrappers[SDE_CP_CRTC_DSPP_VLUT] = set_dspp_vlut_feature; \
|
||||
|
@ -697,6 +861,21 @@ do { \
|
|||
wrappers[SDE_CP_CRTC_DSPP_LTM_QUEUE_BUF2] = set_ltm_queue_buf_feature; \
|
||||
wrappers[SDE_CP_CRTC_DSPP_LTM_QUEUE_BUF3] = set_ltm_queue_buf_feature; \
|
||||
wrappers[SDE_CP_CRTC_DSPP_LTM_HIST_CTL] = set_ltm_hist_crtl_feature; \
|
||||
wrappers[SDE_CP_CRTC_DSPP_RC_MASK] = set_rc_mask_feature; \
|
||||
} while (0)
|
||||
|
||||
feature_wrapper set_crtc_pu_feature_wrappers[SDE_CP_CRTC_MAX_PU_FEATURES];
|
||||
#define setup_set_crtc_pu_feature_wrappers(wrappers) \
|
||||
do { \
|
||||
memset(wrappers, 0, sizeof(wrappers)); \
|
||||
wrappers[SDE_CP_CRTC_DSPP_RC_PU] = set_rc_pu_feature; \
|
||||
} while (0)
|
||||
|
||||
feature_wrapper check_crtc_pu_feature_wrappers[SDE_CP_CRTC_MAX_PU_FEATURES];
|
||||
#define setup_check_crtc_pu_feature_wrappers(wrappers) \
|
||||
do { \
|
||||
memset(wrappers, 0, sizeof(wrappers)); \
|
||||
wrappers[SDE_CP_CRTC_DSPP_RC_PU] = check_rc_pu_feature; \
|
||||
} while (0)
|
||||
|
||||
#define INIT_PROP_ATTACH(p, crtc, prop, node, feature, val) \
|
||||
|
@ -886,12 +1065,6 @@ static int sde_cp_enable_crtc_property(struct drm_crtc *crtc,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static struct sde_kms *get_kms(struct drm_crtc *crtc)
|
||||
{
|
||||
struct msm_drm_private *priv = crtc->dev->dev_private;
|
||||
|
||||
return to_sde_kms(priv->kms);
|
||||
}
|
||||
|
||||
static void sde_cp_crtc_prop_attach(struct sde_cp_prop_attach *prop_attach)
|
||||
{
|
||||
|
@ -938,6 +1111,9 @@ void sde_cp_crtc_init(struct drm_crtc *crtc)
|
|||
if (IS_ERR(sde_crtc->hist_blob))
|
||||
sde_crtc->hist_blob = NULL;
|
||||
|
||||
msm_property_install_blob(&sde_crtc->property_info,
|
||||
"dspp_caps", DRM_MODE_PROP_IMMUTABLE, CRTC_PROP_DSPP_INFO);
|
||||
|
||||
mutex_init(&sde_crtc->crtc_cp_lock);
|
||||
INIT_LIST_HEAD(&sde_crtc->active_list);
|
||||
INIT_LIST_HEAD(&sde_crtc->dirty_list);
|
||||
|
@ -948,6 +1124,7 @@ void sde_cp_crtc_init(struct drm_crtc *crtc)
|
|||
spin_lock_init(&sde_crtc->ltm_lock);
|
||||
INIT_LIST_HEAD(&sde_crtc->ltm_buf_free);
|
||||
INIT_LIST_HEAD(&sde_crtc->ltm_buf_busy);
|
||||
sde_cp_crtc_disable(crtc);
|
||||
}
|
||||
|
||||
static void sde_cp_crtc_install_immutable_property(struct drm_crtc *crtc,
|
||||
|
@ -1182,6 +1359,70 @@ static void _sde_cp_crtc_enable_hist_irq(struct sde_crtc *sde_crtc)
|
|||
spin_unlock_irqrestore(&node->state_lock, flags);
|
||||
}
|
||||
|
||||
static int sde_cp_crtc_checkfeature(struct sde_cp_node *prop_node,
|
||||
struct sde_crtc *sde_crtc, struct sde_crtc_state *sde_crtc_state)
|
||||
{
|
||||
struct sde_hw_cp_cfg hw_cfg;
|
||||
struct sde_hw_mixer *hw_lm;
|
||||
struct sde_hw_dspp *hw_dspp;
|
||||
u32 num_mixers;
|
||||
int i = 0, ret = 0;
|
||||
bool feature_enabled = false;
|
||||
feature_wrapper check_feature = NULL;
|
||||
|
||||
if (!prop_node || !sde_crtc || !sde_crtc_state) {
|
||||
DRM_ERROR("invalid arguments");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
num_mixers = sde_crtc->num_mixers;
|
||||
|
||||
if (prop_node->feature >= SDE_CP_CRTC_MAX_FEATURES) {
|
||||
DRM_ERROR("invalid feature %d\n", prop_node->feature);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
check_feature = check_crtc_feature_wrappers[prop_node->feature];
|
||||
if (check_feature == NULL)
|
||||
return 0;
|
||||
|
||||
memset(&hw_cfg, 0, sizeof(hw_cfg));
|
||||
sde_cp_get_hw_payload(prop_node, &hw_cfg, &feature_enabled);
|
||||
hw_cfg.num_of_mixers = sde_crtc->num_mixers;
|
||||
hw_cfg.last_feature = 0;
|
||||
|
||||
for (i = 0; i < num_mixers; i++) {
|
||||
hw_dspp = sde_crtc->mixers[i].hw_dspp;
|
||||
if (!hw_dspp || i >= DSPP_MAX)
|
||||
continue;
|
||||
hw_cfg.dspp[i] = hw_dspp;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_mixers && !ret; i++) {
|
||||
hw_lm = sde_crtc->mixers[i].hw_lm;
|
||||
hw_dspp = sde_crtc->mixers[i].hw_dspp;
|
||||
if (!hw_lm) {
|
||||
ret = -EINVAL;
|
||||
continue;
|
||||
}
|
||||
hw_cfg.ctl = sde_crtc->mixers[i].hw_ctl;
|
||||
hw_cfg.mixer_info = hw_lm;
|
||||
|
||||
/* use incoming state information */
|
||||
hw_cfg.displayh = num_mixers *
|
||||
sde_crtc_state->lm_roi[i].w;
|
||||
hw_cfg.displayv = sde_crtc_state->lm_roi[i].h;
|
||||
|
||||
DRM_DEBUG_DRIVER("check cp feature %d on mixer %d\n",
|
||||
prop_node->feature, hw_lm->idx - LM_0);
|
||||
ret = check_feature(hw_dspp, &hw_cfg, sde_crtc);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node,
|
||||
struct sde_crtc *sde_crtc)
|
||||
{
|
||||
|
@ -1206,11 +1447,11 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node,
|
|||
}
|
||||
|
||||
if ((prop_node->feature >= SDE_CP_CRTC_MAX_FEATURES) ||
|
||||
crtc_feature_wrappers[prop_node->feature] == NULL) {
|
||||
set_crtc_feature_wrappers[prop_node->feature] == NULL) {
|
||||
ret = -EINVAL;
|
||||
} else {
|
||||
set_feature_wrapper set_feature =
|
||||
crtc_feature_wrappers[prop_node->feature];
|
||||
feature_wrapper set_feature =
|
||||
set_crtc_feature_wrappers[prop_node->feature];
|
||||
catalog = get_kms(&sde_crtc->base)->catalog;
|
||||
hw_cfg.broadcast_disabled = catalog->dma_cfg.broadcast_disabled;
|
||||
|
||||
|
@ -1252,6 +1493,257 @@ static void sde_cp_crtc_setfeature(struct sde_cp_node *prop_node,
|
|||
list_del_init(&prop_node->dirty_list);
|
||||
}
|
||||
|
||||
static int sde_cp_crtc_check_pu_features(struct drm_crtc *crtc)
|
||||
{
|
||||
int ret = 0, i = 0, j = 0;
|
||||
struct sde_crtc *sde_crtc;
|
||||
struct sde_crtc_state *sde_crtc_state;
|
||||
struct sde_hw_cp_cfg hw_cfg;
|
||||
struct sde_hw_dspp *hw_dspp;
|
||||
|
||||
if (!crtc) {
|
||||
DRM_ERROR("invalid crtc %pK\n", crtc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sde_crtc = to_sde_crtc(crtc);
|
||||
if (!sde_crtc) {
|
||||
DRM_ERROR("invalid sde_crtc %pK\n", sde_crtc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sde_crtc_state = to_sde_crtc_state(crtc->state);
|
||||
if (!sde_crtc_state) {
|
||||
DRM_ERROR("invalid sde_crtc_state %pK\n", sde_crtc_state);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < sde_crtc->num_mixers; i++) {
|
||||
if (!sde_crtc->mixers[i].hw_lm) {
|
||||
DRM_ERROR("invalid lm in mixer %d\n", i);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!sde_crtc->mixers[i].hw_ctl) {
|
||||
DRM_ERROR("invalid ctl in mixer %d\n", i);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* early return when not a partial update frame */
|
||||
if (sde_crtc_state->user_roi_list.num_rects == 0) {
|
||||
DRM_DEBUG_DRIVER("no partial update required\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&hw_cfg, 0, sizeof(hw_cfg));
|
||||
hw_cfg.num_of_mixers = sde_crtc->num_mixers;
|
||||
hw_cfg.payload = &sde_crtc_state->user_roi_list;
|
||||
hw_cfg.len = sizeof(sde_crtc_state->user_roi_list);
|
||||
for (i = 0; i < hw_cfg.num_of_mixers; i++)
|
||||
hw_cfg.dspp[i] = sde_crtc->mixers[i].hw_dspp;
|
||||
|
||||
for (i = 0; i < SDE_CP_CRTC_MAX_PU_FEATURES; i++) {
|
||||
feature_wrapper check_pu_feature =
|
||||
check_crtc_pu_feature_wrappers[i];
|
||||
|
||||
if (!check_pu_feature ||
|
||||
!(sde_crtc->cp_pu_feature_mask & BIT(i)))
|
||||
continue;
|
||||
|
||||
for (j = 0; j < hw_cfg.num_of_mixers; j++) {
|
||||
hw_dspp = sde_crtc->mixers[j].hw_dspp;
|
||||
|
||||
/* use incoming state information */
|
||||
hw_cfg.mixer_info = sde_crtc->mixers[j].hw_lm;
|
||||
hw_cfg.ctl = sde_crtc->mixers[j].hw_ctl;
|
||||
hw_cfg.displayh = hw_cfg.num_of_mixers *
|
||||
sde_crtc_state->lm_roi[j].w;
|
||||
hw_cfg.displayv = sde_crtc_state->lm_roi[j].h;
|
||||
|
||||
ret = check_pu_feature(hw_dspp, &hw_cfg, sde_crtc);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed pu feature %d in mixer %d\n",
|
||||
i, j);
|
||||
return -EAGAIN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sde_cp_crtc_check_properties(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *state)
|
||||
{
|
||||
struct sde_crtc *sde_crtc = NULL;
|
||||
struct sde_crtc_state *sde_crtc_state = NULL;
|
||||
struct sde_cp_node *prop_node = NULL, *n = NULL;
|
||||
int ret = 0;
|
||||
|
||||
if (!crtc || !crtc->dev || !state) {
|
||||
DRM_ERROR("invalid crtc %pK dev %pK state %pK\n", crtc,
|
||||
(crtc ? crtc->dev : NULL), state);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sde_crtc = to_sde_crtc(crtc);
|
||||
if (!sde_crtc) {
|
||||
DRM_ERROR("invalid sde_crtc %pK\n", sde_crtc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sde_crtc_state = to_sde_crtc_state(state);
|
||||
if (!sde_crtc_state) {
|
||||
DRM_ERROR("invalid sde_crtc_state %pK\n", sde_crtc_state);
|
||||
return -EINVAL;
|
||||
}
|
||||
mutex_lock(&sde_crtc->crtc_cp_lock);
|
||||
|
||||
ret = sde_cp_crtc_check_pu_features(crtc);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed check pu features, ret %d\n", ret);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (list_empty(&sde_crtc->dirty_list)) {
|
||||
DRM_DEBUG_DRIVER("Dirty list is empty\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(prop_node, n, &sde_crtc->dirty_list,
|
||||
dirty_list) {
|
||||
ret = sde_cp_crtc_checkfeature(prop_node, sde_crtc,
|
||||
sde_crtc_state);
|
||||
if (ret) {
|
||||
DRM_ERROR("failed check on prop_node %u\n",
|
||||
prop_node->property_id);
|
||||
/* remove invalid feature from dirty list */
|
||||
list_del_init(&prop_node->dirty_list);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
mutex_unlock(&sde_crtc->crtc_cp_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sde_cp_crtc_set_pu_features(struct drm_crtc *crtc, bool *need_flush)
|
||||
{
|
||||
int ret = 0, i = 0, j = 0;
|
||||
struct sde_crtc *sde_crtc;
|
||||
struct sde_crtc_state *sde_crtc_state;
|
||||
struct sde_hw_cp_cfg hw_cfg;
|
||||
struct sde_hw_dspp *hw_dspp;
|
||||
struct sde_hw_mixer *hw_lm;
|
||||
struct sde_mdss_cfg *catalog;
|
||||
struct sde_rect user_rect, cached_rect;
|
||||
|
||||
if (!need_flush) {
|
||||
DRM_ERROR("invalid need_flush %pK\n", need_flush);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!crtc) {
|
||||
DRM_ERROR("invalid crtc %pK\n", crtc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sde_crtc = to_sde_crtc(crtc);
|
||||
if (!sde_crtc) {
|
||||
DRM_ERROR("invalid sde_crtc %pK\n", sde_crtc);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
sde_crtc_state = to_sde_crtc_state(crtc->state);
|
||||
if (!sde_crtc_state) {
|
||||
DRM_ERROR("invalid sde_crtc_state %pK\n", sde_crtc_state);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (i = 0; i < sde_crtc->num_mixers; i++) {
|
||||
if (!sde_crtc->mixers[i].hw_lm) {
|
||||
DRM_ERROR("invalid lm in mixer %d\n", i);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!sde_crtc->mixers[i].hw_ctl) {
|
||||
DRM_ERROR("invalid ctl in mixer %d\n", i);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* early return if not a partial update frame or no change in rois */
|
||||
if ((sde_crtc_state->user_roi_list.num_rects == 0) &&
|
||||
(sde_crtc->cached_user_roi_list.num_rects == 0)) {
|
||||
DRM_DEBUG_DRIVER("no partial update required\n");
|
||||
return 0;
|
||||
} else if (sde_crtc_state->user_roi_list.num_rects == 0) {
|
||||
DRM_DEBUG_DRIVER("transition from PU to full update\n");
|
||||
memset(&sde_crtc->cached_user_roi_list, 0,
|
||||
sizeof(struct msm_roi_list));
|
||||
} else {
|
||||
sde_kms_rect_merge_rectangles(&sde_crtc_state->user_roi_list,
|
||||
&user_rect);
|
||||
sde_kms_rect_merge_rectangles(
|
||||
&sde_crtc->cached_user_roi_list,
|
||||
&cached_rect);
|
||||
if (sde_kms_rect_is_equal(&user_rect, &cached_rect)) {
|
||||
DRM_DEBUG_DRIVER("no change in list of ROIs\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
catalog = get_kms(&sde_crtc->base)->catalog;
|
||||
memset(&hw_cfg, 0, sizeof(hw_cfg));
|
||||
hw_cfg.num_of_mixers = sde_crtc->num_mixers;
|
||||
hw_cfg.broadcast_disabled = catalog->dma_cfg.broadcast_disabled;
|
||||
hw_cfg.payload = (sde_crtc_state->user_roi_list.num_rects) ?
|
||||
&sde_crtc_state->user_roi_list : NULL;
|
||||
hw_cfg.len = sizeof(sde_crtc_state->user_roi_list);
|
||||
for (i = 0; i < hw_cfg.num_of_mixers; i++)
|
||||
hw_cfg.dspp[i] = sde_crtc->mixers[i].hw_dspp;
|
||||
|
||||
for (i = 0; i < SDE_CP_CRTC_MAX_PU_FEATURES; i++) {
|
||||
feature_wrapper set_pu_feature =
|
||||
set_crtc_pu_feature_wrappers[i];
|
||||
|
||||
if (!set_pu_feature ||
|
||||
!(sde_crtc->cp_pu_feature_mask & BIT(i)))
|
||||
continue;
|
||||
|
||||
for (j = 0; j < hw_cfg.num_of_mixers; j++) {
|
||||
hw_lm = sde_crtc->mixers[j].hw_lm;
|
||||
hw_dspp = sde_crtc->mixers[j].hw_dspp;
|
||||
|
||||
hw_cfg.mixer_info = hw_lm;
|
||||
hw_cfg.ctl = sde_crtc->mixers[j].hw_ctl;
|
||||
hw_cfg.displayh = hw_cfg.num_of_mixers *
|
||||
hw_lm->cfg.out_width;
|
||||
hw_cfg.displayv = hw_lm->cfg.out_height;
|
||||
|
||||
ret = set_pu_feature(hw_dspp, &hw_cfg, sde_crtc);
|
||||
/* feature does not need flush when ret > 0 */
|
||||
if (ret < 0) {
|
||||
DRM_ERROR("failed pu feature %d in mixer %d\n",
|
||||
i, j);
|
||||
return ret;
|
||||
} else if (ret == 0) {
|
||||
*need_flush = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (sde_crtc_state->user_roi_list.num_rects != 0) {
|
||||
memcpy(&sde_crtc->cached_user_roi_list,
|
||||
&sde_crtc_state->user_roi_list,
|
||||
sizeof(struct msm_roi_list));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sde_cp_crtc_apply_properties(struct drm_crtc *crtc)
|
||||
{
|
||||
struct sde_crtc *sde_crtc = NULL;
|
||||
|
@ -1259,6 +1751,8 @@ void sde_cp_crtc_apply_properties(struct drm_crtc *crtc)
|
|||
struct sde_cp_node *prop_node = NULL, *n = NULL;
|
||||
struct sde_hw_ctl *ctl;
|
||||
u32 num_mixers = 0, i = 0;
|
||||
int rc = 0;
|
||||
bool need_flush = false;
|
||||
|
||||
if (!crtc || !crtc->dev) {
|
||||
DRM_ERROR("invalid crtc %pK dev %pK\n", crtc,
|
||||
|
@ -1274,42 +1768,49 @@ void sde_cp_crtc_apply_properties(struct drm_crtc *crtc)
|
|||
|
||||
num_mixers = sde_crtc->num_mixers;
|
||||
if (!num_mixers) {
|
||||
DRM_DEBUG_DRIVER("no mixers for this crtc\n");
|
||||
DRM_ERROR("no mixers for this crtc\n");
|
||||
return;
|
||||
}
|
||||
|
||||
mutex_lock(&sde_crtc->crtc_cp_lock);
|
||||
|
||||
/* Check if dirty lists are empty and ad features are disabled for
|
||||
* early return. If ad properties are active then we need to issue
|
||||
* dspp flush.
|
||||
**/
|
||||
if (list_empty(&sde_crtc->dirty_list) &&
|
||||
list_empty(&sde_crtc->ad_dirty)) {
|
||||
if (list_empty(&sde_crtc->ad_active)) {
|
||||
DRM_DEBUG_DRIVER("Dirty list is empty\n");
|
||||
goto exit;
|
||||
}
|
||||
set_dspp_flush = true;
|
||||
list_empty(&sde_crtc->ad_dirty) &&
|
||||
list_empty(&sde_crtc->ad_active) &&
|
||||
list_empty(&sde_crtc->active_list)) {
|
||||
DRM_DEBUG_DRIVER("all lists are empty\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (!list_empty(&sde_crtc->ad_active))
|
||||
sde_cp_ad_set_prop(sde_crtc, AD_IPC_RESET);
|
||||
rc = sde_cp_crtc_set_pu_features(crtc, &need_flush);
|
||||
if (rc) {
|
||||
DRM_ERROR("failed set pu features, skip cp updates\n");
|
||||
goto exit;
|
||||
} else if (need_flush) {
|
||||
set_dspp_flush = true;
|
||||
set_lm_flush = true;
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(prop_node, n, &sde_crtc->dirty_list,
|
||||
dirty_list) {
|
||||
dirty_list) {
|
||||
sde_cp_crtc_setfeature(prop_node, sde_crtc);
|
||||
/* Set the flush flag to true */
|
||||
if (prop_node->is_dspp_feature)
|
||||
if (prop_node->is_dspp_feature &&
|
||||
!prop_node->lm_flush_override)
|
||||
set_dspp_flush = true;
|
||||
else
|
||||
set_lm_flush = true;
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(prop_node, n, &sde_crtc->ad_dirty,
|
||||
dirty_list) {
|
||||
if (!list_empty(&sde_crtc->ad_active)) {
|
||||
sde_cp_ad_set_prop(sde_crtc, AD_IPC_RESET);
|
||||
set_dspp_flush = true;
|
||||
}
|
||||
|
||||
list_for_each_entry_safe(prop_node, n, &sde_crtc->ad_dirty,
|
||||
dirty_list) {
|
||||
sde_cp_crtc_setfeature(prop_node, sde_crtc);
|
||||
set_dspp_flush = true;
|
||||
}
|
||||
|
||||
for (i = 0; i < num_mixers; i++) {
|
||||
|
@ -1381,7 +1882,13 @@ void sde_cp_crtc_install_properties(struct drm_crtc *crtc)
|
|||
SDE_CP_CRTC_MAX_FEATURES), GFP_KERNEL);
|
||||
setup_dspp_prop_install_funcs(dspp_prop_install_func);
|
||||
setup_lm_prop_install_funcs(lm_prop_install_func);
|
||||
setup_crtc_feature_wrappers(crtc_feature_wrappers);
|
||||
setup_set_crtc_feature_wrappers(set_crtc_feature_wrappers);
|
||||
setup_check_crtc_feature_wrappers(check_crtc_feature_wrappers);
|
||||
setup_set_crtc_pu_feature_wrappers(
|
||||
set_crtc_pu_feature_wrappers);
|
||||
setup_check_crtc_pu_feature_wrappers(
|
||||
check_crtc_pu_feature_wrappers);
|
||||
setup_dspp_caps_funcs(dspp_cap_update_func);
|
||||
}
|
||||
if (!priv->cp_property)
|
||||
goto exit;
|
||||
|
@ -1659,6 +2166,7 @@ void sde_cp_crtc_clear(struct drm_crtc *crtc)
|
|||
list_del_init(&sde_crtc->dirty_list);
|
||||
list_del_init(&sde_crtc->ad_active);
|
||||
list_del_init(&sde_crtc->ad_dirty);
|
||||
sde_crtc->cp_pu_feature_mask = 0;
|
||||
mutex_unlock(&sde_crtc->crtc_cp_lock);
|
||||
|
||||
spin_lock_irqsave(&sde_crtc->spin_lock, flags);
|
||||
|
@ -1944,6 +2452,57 @@ static void dspp_ltm_install_property(struct drm_crtc *crtc)
|
|||
}
|
||||
}
|
||||
|
||||
static void dspp_rc_install_property(struct drm_crtc *crtc)
|
||||
{
|
||||
char feature_name[256];
|
||||
struct sde_kms *kms = NULL;
|
||||
struct sde_mdss_cfg *catalog = NULL;
|
||||
struct sde_cp_node *prop_node = NULL;
|
||||
struct sde_crtc *sde_crtc = NULL;
|
||||
u32 version;
|
||||
|
||||
if (!crtc) {
|
||||
DRM_ERROR("invalid arguments");
|
||||
return;
|
||||
}
|
||||
|
||||
sde_crtc = to_sde_crtc(crtc);
|
||||
if (!sde_crtc) {
|
||||
DRM_ERROR("invalid sde_crtc %pK\n", sde_crtc);
|
||||
return;
|
||||
}
|
||||
|
||||
kms = get_kms(crtc);
|
||||
catalog = kms->catalog;
|
||||
version = catalog->dspp[0].sblk->rc.version >> 16;
|
||||
switch (version) {
|
||||
case 1:
|
||||
snprintf(feature_name, ARRAY_SIZE(feature_name), "%s%d",
|
||||
"SDE_DSPP_RC_MASK_V", version);
|
||||
sde_cp_crtc_install_blob_property(crtc, feature_name,
|
||||
SDE_CP_CRTC_DSPP_RC_MASK,
|
||||
sizeof(struct drm_msm_rc_mask_cfg));
|
||||
|
||||
/* Override flush mechanism to use layer mixer flush bits */
|
||||
if (!catalog->rc_lm_flush_override)
|
||||
break;
|
||||
|
||||
DRM_DEBUG("rc using lm flush override\n");
|
||||
list_for_each_entry(prop_node, &sde_crtc->feature_list,
|
||||
feature_list) {
|
||||
if (prop_node->feature == SDE_CP_CRTC_DSPP_RC_MASK) {
|
||||
prop_node->lm_flush_override = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("version %d not supported\n", version);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void lm_gc_install_property(struct drm_crtc *crtc)
|
||||
{
|
||||
char feature_name[256];
|
||||
|
@ -3373,3 +3932,72 @@ void sde_cp_mode_switch_prop_dirty(struct drm_crtc *crtc_drm)
|
|||
}
|
||||
mutex_unlock(&crtc->crtc_cp_lock);
|
||||
}
|
||||
|
||||
static void rc_caps_update(struct sde_crtc *crtc, struct sde_kms_info *info)
|
||||
{
|
||||
struct sde_mdss_cfg *catalog = get_kms(&crtc->base)->catalog;
|
||||
u32 i, num_mixers = crtc->num_mixers;
|
||||
char blk_name[256];
|
||||
|
||||
if (!catalog->rc_count || num_mixers > catalog->rc_count)
|
||||
return;
|
||||
|
||||
for (i = 0; i < num_mixers; i++) {
|
||||
struct sde_hw_dspp *dspp = crtc->mixers[i].hw_dspp;
|
||||
|
||||
if (!dspp || (dspp->idx - DSPP_0) >= catalog->rc_count)
|
||||
continue;
|
||||
snprintf(blk_name, sizeof(blk_name), "rc%u",
|
||||
(dspp->idx - DSPP_0));
|
||||
sde_kms_info_add_keyint(info, blk_name, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void sde_cp_crtc_enable(struct drm_crtc *drm_crtc)
|
||||
{
|
||||
struct sde_crtc *crtc;
|
||||
struct sde_kms_info *info = NULL;
|
||||
u32 i, num_mixers;
|
||||
|
||||
if (!drm_crtc) {
|
||||
DRM_ERROR("invalid crtc handle");
|
||||
return;
|
||||
}
|
||||
crtc = to_sde_crtc(drm_crtc);
|
||||
num_mixers = crtc->num_mixers;
|
||||
if (!num_mixers)
|
||||
return;
|
||||
mutex_lock(&crtc->crtc_cp_lock);
|
||||
info = kzalloc(sizeof(struct sde_kms_info), GFP_KERNEL);
|
||||
if (info) {
|
||||
for (i = 0; i < ARRAY_SIZE(dspp_cap_update_func); i++)
|
||||
dspp_cap_update_func[i](crtc, info);
|
||||
msm_property_set_blob(&crtc->property_info,
|
||||
&crtc->dspp_blob_info,
|
||||
info->data, SDE_KMS_INFO_DATALEN(info),
|
||||
CRTC_PROP_DSPP_INFO);
|
||||
}
|
||||
kfree(info);
|
||||
mutex_unlock(&crtc->crtc_cp_lock);
|
||||
}
|
||||
|
||||
void sde_cp_crtc_disable(struct drm_crtc *drm_crtc)
|
||||
{
|
||||
struct sde_kms_info *info = NULL;
|
||||
struct sde_crtc *crtc;
|
||||
|
||||
if (!drm_crtc) {
|
||||
DRM_ERROR("invalid crtc handle");
|
||||
return;
|
||||
}
|
||||
crtc = to_sde_crtc(drm_crtc);
|
||||
mutex_lock(&crtc->crtc_cp_lock);
|
||||
info = kzalloc(sizeof(struct sde_kms_info), GFP_KERNEL);
|
||||
if (info)
|
||||
msm_property_set_blob(&crtc->property_info,
|
||||
&crtc->dspp_blob_info,
|
||||
info->data, SDE_KMS_INFO_DATALEN(info),
|
||||
CRTC_PROP_DSPP_INFO);
|
||||
mutex_unlock(&crtc->crtc_cp_lock);
|
||||
kfree(info);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2016-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2019, 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SDE_COLOR_PROCESSING_H
|
||||
|
@ -93,6 +93,15 @@ void sde_cp_crtc_destroy_properties(struct drm_crtc *crtc);
|
|||
*/
|
||||
int sde_cp_crtc_set_property(struct drm_crtc *crtc,
|
||||
struct drm_property *property, uint64_t val);
|
||||
/**
|
||||
* sde_cp_crtc_check_properties: Verify color processing properties for a crtc.
|
||||
* Should be called during atomic check call.
|
||||
* @crtc: Pointer to crtc.
|
||||
* @state: Pointer to crtc state.
|
||||
* @returns: 0 on success, non-zero otherwise
|
||||
*/
|
||||
int sde_cp_crtc_check_properties(struct drm_crtc *crtc,
|
||||
struct drm_crtc_state *state);
|
||||
|
||||
/**
|
||||
* sde_cp_crtc_apply_properties: Enable/disable properties
|
||||
|
@ -196,4 +205,18 @@ int sde_cp_ltm_off_event_handler(struct drm_crtc *crtc_drm, bool en,
|
|||
* @crtc_drm: Pointer to crtc.
|
||||
*/
|
||||
void sde_cp_mode_switch_prop_dirty(struct drm_crtc *crtc_drm);
|
||||
|
||||
/**
|
||||
* sde_cp_crtc_enable(): enable color processing info in the crtc.
|
||||
* Should be called during crtc enable.
|
||||
* @crtc: Pointer to drm_crtc.
|
||||
*/
|
||||
void sde_cp_crtc_enable(struct drm_crtc *crtc);
|
||||
|
||||
/**
|
||||
* sde_cp_crtc_disable(): disable color processing info in the crtc.
|
||||
* Should be called during crtc disable.
|
||||
* @crtc: Pointer to drm_crtc.
|
||||
*/
|
||||
void sde_cp_crtc_disable(struct drm_crtc *crtc);
|
||||
#endif /*_SDE_COLOR_PROCESSING_H */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2016-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
|
||||
|
@ -676,6 +676,10 @@ static void _sde_core_perf_crtc_update_bus(struct sde_kms *kms,
|
|||
bus_ab_quota = max(bw_sum_of_intfs, kms->perf.perf_tune.min_bus_vote);
|
||||
bus_ib_quota = perf.max_per_pipe_ib[bus_id];
|
||||
|
||||
if (!kms->perf.sde_rsc_available)
|
||||
bus_ib_quota = max(SDE_POWER_HANDLE_ENABLE_BUS_IB_QUOTA,
|
||||
bus_ib_quota);
|
||||
|
||||
if (kms->perf.perf_tune.mode == SDE_PERF_MODE_FIXED) {
|
||||
bus_ab_quota = max(kms->perf.fix_core_ab_vote,
|
||||
bus_ab_quota);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2014-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* Author: Rob Clark <robdclark@gmail.com>
|
||||
*
|
||||
|
@ -781,6 +781,9 @@ static int _sde_crtc_set_crtc_roi(struct drm_crtc *crtc,
|
|||
}
|
||||
|
||||
sde_kms_rect_merge_rectangles(&sde_conn_state->rois, &conn_roi);
|
||||
SDE_DEBUG("conn_roi x:%u, y:%u, w:%u, h:%u\n",
|
||||
conn_roi.x, conn_roi.y,
|
||||
conn_roi.w, conn_roi.h);
|
||||
SDE_EVT32_VERBOSE(DRMID(crtc), DRMID(conn),
|
||||
conn_roi.x, conn_roi.y,
|
||||
conn_roi.w, conn_roi.h);
|
||||
|
@ -4079,6 +4082,7 @@ static void sde_crtc_disable(struct drm_crtc *crtc)
|
|||
/* disable clk & bw control until clk & bw properties are set */
|
||||
cstate->bw_control = false;
|
||||
cstate->bw_split_vote = false;
|
||||
sde_cp_crtc_disable(crtc);
|
||||
|
||||
mutex_unlock(&sde_crtc->crtc_lock);
|
||||
}
|
||||
|
@ -4150,7 +4154,7 @@ static void sde_crtc_enable(struct drm_crtc *crtc,
|
|||
}
|
||||
|
||||
sde_crtc->enabled = true;
|
||||
|
||||
sde_cp_crtc_enable(crtc);
|
||||
/* update color processing on resume */
|
||||
event.type = DRM_EVENT_CRTC_POWER;
|
||||
event.length = sizeof(u32);
|
||||
|
@ -4903,6 +4907,12 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc,
|
|||
goto end;
|
||||
}
|
||||
|
||||
rc = sde_cp_crtc_check_properties(crtc, state);
|
||||
if (rc) {
|
||||
SDE_ERROR("crtc%d failed cp properties check %d\n",
|
||||
crtc->base.id, rc);
|
||||
goto end;
|
||||
}
|
||||
end:
|
||||
kfree(pstates);
|
||||
kfree(multirect_plane);
|
||||
|
@ -4989,6 +4999,26 @@ static void sde_kms_add_ubwc_info(struct sde_kms_info *info,
|
|||
sde_kms_info_add_keystr(info, "DDR version", "DDR5");
|
||||
}
|
||||
|
||||
/**
|
||||
* _sde_crtc_install_cp_properties - install color properties for crtc
|
||||
* @info: Pointer to kms info structure
|
||||
* @catalog: Pointer to catalog structure
|
||||
*/
|
||||
static void _sde_crtc_install_cp_properties(struct sde_kms_info *info,
|
||||
struct sde_mdss_cfg *catalog)
|
||||
{
|
||||
if (!info || !catalog) {
|
||||
SDE_ERROR("invalid info or catalog\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sde_kms_info_add_keyint(info, "has_hdr", catalog->has_hdr);
|
||||
sde_kms_info_add_keyint(info, "has_hdr_plus", catalog->has_hdr_plus);
|
||||
if (catalog->dspp_count && catalog->rc_count)
|
||||
sde_kms_info_add_keyint(info, "rc_mem_size",
|
||||
catalog->dspp[0].sblk->rc.mem_total_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* sde_crtc_install_properties - install all drm properties for crtc
|
||||
* @crtc: Pointer to drm crtc structure
|
||||
|
@ -5189,8 +5219,7 @@ static void sde_crtc_install_properties(struct drm_crtc *crtc,
|
|||
}
|
||||
|
||||
sde_kms_info_add_keyint(info, "has_src_split", catalog->has_src_split);
|
||||
sde_kms_info_add_keyint(info, "has_hdr", catalog->has_hdr);
|
||||
sde_kms_info_add_keyint(info, "has_hdr_plus", catalog->has_hdr_plus);
|
||||
_sde_crtc_install_cp_properties(info, catalog);
|
||||
if (catalog->perf.max_bw_low)
|
||||
sde_kms_info_add_keyint(info, "max_bandwidth_low",
|
||||
catalog->perf.max_bw_low * 1000LL);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2015-2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2021 The Linux Foundation. All rights reserved.
|
||||
* Copyright (C) 2013 Red Hat
|
||||
* Author: Rob Clark <robdclark@gmail.com>
|
||||
*
|
||||
|
@ -276,6 +276,8 @@ struct sde_crtc_misr_info {
|
|||
* @cur_perf : current performance committed to clock/bandwidth driver
|
||||
* @plane_mask_old: keeps track of the planes used in the previous commit
|
||||
* @frame_trigger_mode: frame trigger mode
|
||||
* @cp_pu_feature_mask: mask indicating cp feature enable for partial update
|
||||
* @cached_user_roi_list : Copy of user_roi_list from previous PU frame
|
||||
* @ltm_buffer_cnt : number of ltm buffers
|
||||
* @ltm_buffers : struct stores ltm buffer related data
|
||||
* @ltm_buf_free : list of LTM buffers that are available
|
||||
|
@ -285,6 +287,7 @@ struct sde_crtc_misr_info {
|
|||
* @ltm_lock : Spinlock to protect ltm buffer_cnt, hist_en and ltm lists
|
||||
* @needs_hw_reset : Initiate a hw ctl reset
|
||||
* @comp_ratio : Compression ratio
|
||||
* @dspp_blob_info : blob containing dspp hw capability information
|
||||
*/
|
||||
struct sde_crtc {
|
||||
struct drm_crtc base;
|
||||
|
@ -358,6 +361,9 @@ struct sde_crtc {
|
|||
struct drm_property_blob *hist_blob;
|
||||
enum frame_trigger_mode_type frame_trigger_mode;
|
||||
|
||||
u32 cp_pu_feature_mask;
|
||||
struct msm_roi_list cached_user_roi_list;
|
||||
|
||||
u32 ltm_buffer_cnt;
|
||||
struct sde_ltm_buffer *ltm_buffers[LTM_BUFFER_SIZE];
|
||||
struct list_head ltm_buf_free;
|
||||
|
@ -369,6 +375,8 @@ struct sde_crtc {
|
|||
bool needs_hw_reset;
|
||||
|
||||
int comp_ratio;
|
||||
|
||||
struct drm_property_blob *dspp_blob_info;
|
||||
};
|
||||
|
||||
#define to_sde_crtc(x) container_of(x, struct sde_crtc, base)
|
||||
|
@ -389,7 +397,7 @@ struct sde_crtc {
|
|||
* @lm_roi : Current LM ROI, possibly sub-rectangle of mode.
|
||||
* Origin top left of CRTC.
|
||||
* @user_roi_list : List of user's requested ROIs as from set property
|
||||
* @property_state: Local storage for msm_prop properties
|
||||
* @property_state: Local storage for msm_prop properties
|
||||
* @property_values: Current crtc property values
|
||||
* @input_fence_timeout_ns : Cached input fence timeout, in ns
|
||||
* @num_dim_layers: Number of dim layers
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
|
||||
|
@ -383,6 +383,14 @@ enum {
|
|||
LTM_PROP_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
RC_OFF,
|
||||
RC_LEN,
|
||||
RC_VERSION,
|
||||
RC_MEM_TOTAL_SIZE,
|
||||
RC_PROP_MAX,
|
||||
};
|
||||
|
||||
enum {
|
||||
MIXER_OFF,
|
||||
MIXER_LEN,
|
||||
|
@ -692,6 +700,13 @@ static struct sde_prop_type ltm_prop[] = {
|
|||
{LTM_VERSION, "qcom,sde-dspp-ltm-version", false, PROP_TYPE_U32},
|
||||
};
|
||||
|
||||
static struct sde_prop_type rc_prop[] = {
|
||||
{RC_OFF, "qcom,sde-dspp-rc-off", false, PROP_TYPE_U32_ARRAY},
|
||||
{RC_LEN, "qcom,sde-dspp-rc-size", false, PROP_TYPE_U32},
|
||||
{RC_VERSION, "qcom,sde-dspp-rc-version", false, PROP_TYPE_U32},
|
||||
{RC_MEM_TOTAL_SIZE, "qcom,sde-dspp-rc-mem-size", false, PROP_TYPE_U32},
|
||||
};
|
||||
|
||||
static struct sde_prop_type ds_top_prop[] = {
|
||||
{DS_TOP_OFF, "qcom,sde-dest-scaler-top-off", false, PROP_TYPE_U32},
|
||||
{DS_TOP_LEN, "qcom,sde-dest-scaler-top-size", false, PROP_TYPE_U32},
|
||||
|
@ -2357,14 +2372,15 @@ static int sde_dspp_parse_dt(struct device_node *np,
|
|||
{
|
||||
int rc, prop_count[DSPP_PROP_MAX], i;
|
||||
int ad_prop_count[AD_PROP_MAX];
|
||||
int ltm_prop_count[LTM_PROP_MAX];
|
||||
int ltm_prop_count[LTM_PROP_MAX], rc_prop_count[RC_PROP_MAX];
|
||||
bool prop_exists[DSPP_PROP_MAX], ad_prop_exists[AD_PROP_MAX];
|
||||
bool ltm_prop_exists[LTM_PROP_MAX];
|
||||
bool ltm_prop_exists[LTM_PROP_MAX], rc_prop_exists[RC_PROP_MAX];
|
||||
bool blocks_prop_exists[DSPP_BLOCKS_PROP_MAX];
|
||||
struct sde_prop_value *ad_prop_value = NULL, *ltm_prop_value = NULL;
|
||||
struct sde_prop_value *rc_prop_value = NULL;
|
||||
int blocks_prop_count[DSPP_BLOCKS_PROP_MAX];
|
||||
struct sde_prop_value *prop_value = NULL, *blocks_prop_value = NULL;
|
||||
u32 off_count, ad_off_count, ltm_off_count;
|
||||
u32 off_count, ad_off_count, ltm_off_count, rc_off_count;
|
||||
struct sde_dspp_cfg *dspp;
|
||||
struct sde_dspp_sub_blks *sblk;
|
||||
struct device_node *snp = NULL;
|
||||
|
@ -2426,6 +2442,22 @@ static int sde_dspp_parse_dt(struct device_node *np,
|
|||
if (rc)
|
||||
goto end;
|
||||
|
||||
/* Parse RC dtsi entries */
|
||||
rc_prop_value = kcalloc(RC_PROP_MAX,
|
||||
sizeof(struct sde_prop_value), GFP_KERNEL);
|
||||
if (!rc_prop_value) {
|
||||
rc = -ENOMEM;
|
||||
goto end;
|
||||
}
|
||||
rc = _validate_dt_entry(np, rc_prop, ARRAY_SIZE(rc_prop),
|
||||
rc_prop_count, &rc_off_count);
|
||||
if (rc)
|
||||
goto end;
|
||||
rc = _read_dt_entry(np, rc_prop, ARRAY_SIZE(rc_prop), rc_prop_count,
|
||||
rc_prop_exists, rc_prop_value);
|
||||
if (rc)
|
||||
goto end;
|
||||
|
||||
/* get DSPP feature dt properties if they exist */
|
||||
snp = of_get_child_by_name(np, dspp_prop[DSPP_BLOCKS].prop_name);
|
||||
if (snp) {
|
||||
|
@ -2489,6 +2521,22 @@ static int sde_dspp_parse_dt(struct device_node *np,
|
|||
set_bit(SDE_DSPP_LTM, &dspp->features);
|
||||
}
|
||||
|
||||
sblk->rc.id = SDE_DSPP_RC;
|
||||
sde_cfg->rc_count = rc_off_count;
|
||||
if (rc_prop_value && (i < rc_off_count) &&
|
||||
rc_prop_exists[RC_OFF]) {
|
||||
sblk->rc.base = PROP_VALUE_ACCESS(rc_prop_value,
|
||||
RC_OFF, i);
|
||||
sblk->rc.len = PROP_VALUE_ACCESS(rc_prop_value,
|
||||
RC_LEN, 0);
|
||||
sblk->rc.version = PROP_VALUE_ACCESS(rc_prop_value,
|
||||
RC_VERSION, 0);
|
||||
sblk->rc.mem_total_size = PROP_VALUE_ACCESS(
|
||||
rc_prop_value, RC_MEM_TOTAL_SIZE,
|
||||
0);
|
||||
sblk->rc.idx = i;
|
||||
set_bit(SDE_DSPP_RC, &dspp->features);
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
|
@ -2496,6 +2544,8 @@ static int sde_dspp_parse_dt(struct device_node *np,
|
|||
kfree(ad_prop_value);
|
||||
kfree(ltm_prop_value);
|
||||
kfree(blocks_prop_value);
|
||||
kfree(rc_prop_value);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -4383,6 +4433,23 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
|
|||
sde_cfg->allow_gdsc_toggle = true;
|
||||
clear_bit(MDSS_INTR_AD4_0_INTR, sde_cfg->mdss_irqs);
|
||||
clear_bit(MDSS_INTR_AD4_1_INTR, sde_cfg->mdss_irqs);
|
||||
} else if (IS_KHAJE_TARGET(hw_rev)) {
|
||||
sde_cfg->has_cwb_support = false;
|
||||
sde_cfg->has_qsync = true;
|
||||
sde_cfg->perf.min_prefill_lines = 24;
|
||||
sde_cfg->vbif_qos_nlvl = 8;
|
||||
sde_cfg->ts_prefill_rev = 2;
|
||||
sde_cfg->ctl_rev = SDE_CTL_CFG_VERSION_1_0_0;
|
||||
sde_cfg->delay_prg_fetch_start = true;
|
||||
sde_cfg->sui_ns_allowed = true;
|
||||
sde_cfg->sui_misr_supported = true;
|
||||
sde_cfg->sui_block_xin_mask = 0xC01;
|
||||
sde_cfg->has_hdr = false;
|
||||
sde_cfg->has_sui_blendstage = true;
|
||||
sde_cfg->allow_gdsc_toggle = true;
|
||||
clear_bit(MDSS_INTR_AD4_0_INTR, sde_cfg->mdss_irqs);
|
||||
clear_bit(MDSS_INTR_AD4_1_INTR, sde_cfg->mdss_irqs);
|
||||
sde_cfg->rc_lm_flush_override = true;
|
||||
} else {
|
||||
SDE_ERROR("unsupported chipset id:%X\n", hw_rev);
|
||||
sde_cfg->perf.min_prefill_lines = 0xffff;
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SDE_HW_CATALOG_H
|
||||
|
@ -56,6 +56,7 @@
|
|||
#define SDE_HW_VER_630 SDE_HW_VER(6, 3, 0) /* bengal */
|
||||
#define SDE_HW_VER_640 SDE_HW_VER(6, 4, 0) /* lagoon */
|
||||
#define SDE_HW_VER_650 SDE_HW_VER(6, 5, 0) /* scuba */
|
||||
#define SDE_HW_VER_6100 SDE_HW_VER(6, 10, 0) /* khaje */
|
||||
|
||||
#define IS_MSM8996_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_170)
|
||||
#define IS_MSM8998_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_300)
|
||||
|
@ -71,6 +72,7 @@
|
|||
#define IS_BENGAL_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_630)
|
||||
#define IS_LAGOON_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_640)
|
||||
#define IS_SCUBA_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_650)
|
||||
#define IS_KHAJE_TARGET(rev) IS_SDE_MAJOR_MINOR_SAME((rev), SDE_HW_VER_6100)
|
||||
|
||||
#define SDE_HW_BLK_NAME_LEN 16
|
||||
|
||||
|
@ -313,6 +315,7 @@ enum {
|
|||
* @SDE_DSPP_VLUT PA VLUT block
|
||||
* @SDE_DSPP_AD AD block
|
||||
* @SDE_DSPP_LTM LTM block
|
||||
* @SDE_DSPP_RC RC block
|
||||
* @SDE_DSPP_MAX maximum value
|
||||
*/
|
||||
enum {
|
||||
|
@ -328,6 +331,7 @@ enum {
|
|||
SDE_DSPP_VLUT,
|
||||
SDE_DSPP_AD,
|
||||
SDE_DSPP_LTM,
|
||||
SDE_DSPP_RC,
|
||||
SDE_DSPP_MAX
|
||||
};
|
||||
|
||||
|
@ -662,6 +666,20 @@ struct sde_lm_sub_blks {
|
|||
struct sde_pp_blk gc;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct sde_dspp_rc: Pixel processing rounded corner sub-blk information
|
||||
* @info: HW register and features supported by this sub-blk.
|
||||
* @version: HW Algorithm version.
|
||||
* @idx: HW block instance id.
|
||||
* @mem_total_size: data memory size.
|
||||
*/
|
||||
struct sde_dspp_rc {
|
||||
SDE_HW_SUBBLK_INFO;
|
||||
u32 version;
|
||||
u32 idx;
|
||||
u32 mem_total_size;
|
||||
};
|
||||
|
||||
struct sde_dspp_sub_blks {
|
||||
struct sde_pp_blk igc;
|
||||
struct sde_pp_blk pcc;
|
||||
|
@ -675,6 +693,7 @@ struct sde_dspp_sub_blks {
|
|||
struct sde_pp_blk ad;
|
||||
struct sde_pp_blk ltm;
|
||||
struct sde_pp_blk vlut;
|
||||
struct sde_dspp_rc rc;
|
||||
};
|
||||
|
||||
struct sde_pingpong_sub_blks {
|
||||
|
@ -1269,6 +1288,7 @@ struct sde_limit_cfg {
|
|||
* @has_base_layer Supports staging layer as base layer
|
||||
* @allow_gdsc_toggle Flag to check if gdsc toggle is needed after crtc is
|
||||
* disabled when external vote is present
|
||||
* @rc_lm_flush_override Support Rounded Corner using layer mixer flush
|
||||
* @sc_cfg: system cache configuration
|
||||
* @uidle_cfg Settings for uidle feature
|
||||
* @sui_misr_supported indicate if secure-ui-misr is supported
|
||||
|
@ -1285,6 +1305,7 @@ struct sde_limit_cfg {
|
|||
* @has_vig_p010 indicates if vig pipe supports p010 format
|
||||
* @inline_rot_formats formats supported by the inline rotator feature
|
||||
* @mdss_irqs bitmap with the irqs supported by the target
|
||||
* @rc_count number of rounded corner hardware instances
|
||||
*/
|
||||
struct sde_mdss_cfg {
|
||||
u32 hwversion;
|
||||
|
@ -1327,6 +1348,7 @@ struct sde_mdss_cfg {
|
|||
bool update_tcsr_disp_glitch;
|
||||
bool has_base_layer;
|
||||
bool allow_gdsc_toggle;
|
||||
bool rc_lm_flush_override;
|
||||
|
||||
struct sde_sc_cfg sc_cfg;
|
||||
|
||||
|
@ -1392,6 +1414,7 @@ struct sde_mdss_cfg {
|
|||
|
||||
u32 ad_count;
|
||||
u32 ltm_count;
|
||||
u32 rc_count;
|
||||
|
||||
u32 merge_3d_count;
|
||||
struct sde_merge_3d_cfg merge_3d[MAX_BLOCKS];
|
||||
|
@ -1439,6 +1462,7 @@ struct sde_mdss_hw_cfg_handler {
|
|||
#define BLK_WB(s) ((s)->wb)
|
||||
#define BLK_AD(s) ((s)->ad)
|
||||
#define BLK_LTM(s) ((s)->ltm)
|
||||
#define BLK_RC(s) ((s)->rc)
|
||||
|
||||
/**
|
||||
* sde_hw_set_preference: populate the individual hw lm preferences,
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2019, 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <drm/msm_drm_pp.h>
|
||||
#include "sde_hw_mdss.h"
|
||||
#include "sde_hwio.h"
|
||||
|
@ -10,6 +11,7 @@
|
|||
#include "sde_hw_color_processing.h"
|
||||
#include "sde_dbg.h"
|
||||
#include "sde_ad4.h"
|
||||
#include "sde_hw_rc.h"
|
||||
#include "sde_kms.h"
|
||||
|
||||
static struct sde_dspp_cfg *_dspp_offset(enum sde_dspp dspp,
|
||||
|
@ -229,6 +231,37 @@ static void dspp_ltm(struct sde_hw_dspp *c)
|
|||
}
|
||||
}
|
||||
|
||||
static void dspp_rc(struct sde_hw_dspp *c)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (!c) {
|
||||
SDE_ERROR("invalid arguments\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (c->cap->sblk->rc.version == SDE_COLOR_PROCESS_VER(0x1, 0x0)) {
|
||||
ret = sde_hw_rc_init(c);
|
||||
if (ret) {
|
||||
SDE_ERROR("rc init failed, ret %d\n", ret);
|
||||
return;
|
||||
}
|
||||
|
||||
ret = reg_dmav1_init_dspp_op_v4(SDE_DSPP_RC, c->idx);
|
||||
if (!ret)
|
||||
c->ops.setup_rc_data =
|
||||
sde_hw_rc_setup_data_dma;
|
||||
else
|
||||
c->ops.setup_rc_data =
|
||||
sde_hw_rc_setup_data_ahb;
|
||||
|
||||
c->ops.validate_rc_mask = sde_hw_rc_check_mask;
|
||||
c->ops.setup_rc_mask = sde_hw_rc_setup_mask;
|
||||
c->ops.validate_rc_pu_roi = sde_hw_rc_check_pu_roi;
|
||||
c->ops.setup_rc_pu_roi = sde_hw_rc_setup_pu_roi;
|
||||
}
|
||||
}
|
||||
|
||||
static void (*dspp_blocks[SDE_DSPP_MAX])(struct sde_hw_dspp *c);
|
||||
|
||||
static void _init_dspp_ops(void)
|
||||
|
@ -245,6 +278,7 @@ static void _init_dspp_ops(void)
|
|||
dspp_blocks[SDE_DSPP_VLUT] = dspp_vlut;
|
||||
dspp_blocks[SDE_DSPP_AD] = dspp_ad;
|
||||
dspp_blocks[SDE_DSPP_LTM] = dspp_ltm;
|
||||
dspp_blocks[SDE_DSPP_RC] = dspp_rc;
|
||||
}
|
||||
|
||||
static void _setup_dspp_ops(struct sde_hw_dspp *c, unsigned long features)
|
||||
|
@ -274,6 +308,7 @@ struct sde_hw_dspp *sde_hw_dspp_init(enum sde_dspp idx,
|
|||
struct sde_hw_dspp *c;
|
||||
struct sde_dspp_cfg *cfg;
|
||||
int rc;
|
||||
char buf[256];
|
||||
|
||||
if (!addr || !m)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
@ -317,6 +352,13 @@ struct sde_hw_dspp *sde_hw_dspp_init(enum sde_dspp idx,
|
|||
c->hw.xin_id);
|
||||
}
|
||||
|
||||
if ((cfg->sblk->rc.id == SDE_DSPP_RC) && cfg->sblk->rc.base) {
|
||||
snprintf(buf, ARRAY_SIZE(buf), "%s_%d", "rc", c->idx - DSPP_0);
|
||||
sde_dbg_reg_register_dump_range(SDE_DBG_NAME, buf,
|
||||
c->hw.blk_off + cfg->sblk->rc.base,
|
||||
c->hw.blk_off + cfg->sblk->rc.base +
|
||||
cfg->sblk->rc.len, c->hw.xin_id);
|
||||
}
|
||||
return c;
|
||||
|
||||
blk_init_error:
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2019, 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SDE_HW_DSPP_H
|
||||
|
@ -209,6 +209,46 @@ struct sde_hw_dspp_ops {
|
|||
* @status: Pointer to u32 where ltm status value is dumped.
|
||||
*/
|
||||
void (*ltm_read_intr_status)(struct sde_hw_dspp *ctx, u32 *status);
|
||||
|
||||
/**
|
||||
* validate_rc_mask - Validate RC mask configuration
|
||||
* @ctx: Pointer to dspp context.
|
||||
* @cfg: Pointer to configuration.
|
||||
* Return: 0 on success, non-zero otherwise.
|
||||
*/
|
||||
int (*validate_rc_mask)(struct sde_hw_dspp *ctx, void *cfg);
|
||||
|
||||
/**
|
||||
* setup_rc_mask - Setup RC mask configuration
|
||||
* @ctx: Pointer to dspp context.
|
||||
* @cfg: Pointer to configuration.
|
||||
* Return: 0 on success, non-zero otherwise.
|
||||
*/
|
||||
int (*setup_rc_mask)(struct sde_hw_dspp *ctx, void *cfg);
|
||||
|
||||
/**
|
||||
* validate_rc_pu_roi - Validate RC regions in during partial update.
|
||||
* @ctx: Pointer to dspp context.
|
||||
* @cfg: Pointer to configuration.
|
||||
* Return: 0 on success, non-zero otherwise.
|
||||
*/
|
||||
int (*validate_rc_pu_roi)(struct sde_hw_dspp *ctx, void *cfg);
|
||||
|
||||
/**
|
||||
* setup_rc_pu_roi - Setup RC regions in during partial update.
|
||||
* @ctx: Pointer to dspp context.
|
||||
* @cfg: Pointer to configuration.
|
||||
* Return: 0 on success, non-zero otherwise.
|
||||
*/
|
||||
int (*setup_rc_pu_roi)(struct sde_hw_dspp *ctx, void *cfg);
|
||||
|
||||
/**
|
||||
* setup_rc_data - Program RC mask data
|
||||
* @ctx: Pointer to dspp context.
|
||||
* @cfg: Pointer to configuration.
|
||||
* Return: 0 on success, non-zero otherwise.
|
||||
*/
|
||||
int (*setup_rc_data)(struct sde_hw_dspp *ctx, void *cfg);
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2015-2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2015-2019, 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _SDE_HW_MDSS_H
|
||||
|
@ -171,6 +171,7 @@ enum sde_stage {
|
|||
SDE_STAGE_10,
|
||||
SDE_STAGE_MAX
|
||||
};
|
||||
|
||||
enum sde_dspp {
|
||||
DSPP_0 = 1,
|
||||
DSPP_1,
|
||||
|
@ -185,6 +186,12 @@ enum sde_ltm {
|
|||
LTM_MAX
|
||||
};
|
||||
|
||||
enum sde_rc {
|
||||
RC_0 = DSPP_0,
|
||||
RC_1,
|
||||
RC_MAX
|
||||
};
|
||||
|
||||
enum sde_ds {
|
||||
DS_TOP,
|
||||
DS_0,
|
||||
|
|
1069
techpack/display/msm/sde/sde_hw_rc.c
Normal file
1069
techpack/display/msm/sde/sde_hw_rc.c
Normal file
File diff suppressed because it is too large
Load diff
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue