msm: ais: add AIS IFE Drivers

Add new AIS IFE driver as a lightweight variant for RDI only usecases
based on msm-4.14 cam_isp as of commit 698ee3d927
("msm: ais: isp: validate in_port before accessing").

The API definition is in ais_isp.h and ais_isp_hw.h.

Change-Id: I04927f0f184045985f52bb7cb6c8c42a47ec6476
Signed-off-by: Terence Ho <terenceh@codeaurora.org>
This commit is contained in:
Terence Ho
2020-05-26 13:03:10 -04:00
parent cdad21ac76
commit eee28504be
56 changed files with 13493 additions and 24 deletions

View File

@@ -0,0 +1,36 @@
* Qualcomm Technologies, Inc. MSM Camera ISP
The MSM AIS IFE driver provides the definitions for enabling
the Camera IFE hadware for Automotive usecase. It provides the
functions for the Client to control the IFE hardware.
=======================
Required Node Structure
=======================
The Camera AIS IFE device is described in one level of device node.
==================================
First Level Node - AIS IFE device
==================================
- compatible
Usage: required
Value type: <string>
Definition: Should be "qcom,ais-ife".
- arch-compat
Usage: required
Value type: <string>
Definition: Should be "ife".
- cell-index
Usage: required
Value type: <u32>
Definition: Should specify the hardware index id.
Example:
qcom,ais-ife0 {
compatible = "qcom,ais-ife";
cell-index = <0>;
status = "ok";
};

View File

@@ -17,6 +17,8 @@ First Level Node - CAM IFE CSID device
Value type: <string>
Definition: Should be "qcom,csid170", "qcom,csid175", "qcom,csid175_200", "qcom,csid-lite170"
or "qcom,csid-lite175".
For automotive, can specify "qcom,ais-csid170", "qcom,ais-csid175", "qcom,ais-csid175_200", "qcom,ais-csid-lite170"
or "qcom,ais-csid-lite175"
- cell-index
Usage: required

View File

@@ -18,6 +18,7 @@ Required properties:
Value type: <string>
Definition: Should specify the compatibility string for matching the
driver. e.g. "qcom,vfe175", "qcom,vfe170", "qcom,vfe175_130", "qcom,vfe-lite175", "qcom,vfe-lite175_130", "qcom,vfe-lite170".
For automotive, can specify "qcom,ais-vfe175", "qcom,ais-vfe170", "qcom,ais-vfe175_130", "qcom,ais-vfe-lite175", "qcom,ais-vfe-lite175_130", "qcom,ais-vfe-lite170".
- cell-index
Usage: required

View File

@@ -6,6 +6,7 @@ obj-$(CONFIG_MSM_AIS) += cam_sync/
obj-$(CONFIG_MSM_AIS) += cam_smmu/
obj-$(CONFIG_MSM_AIS) += cam_cpas/
obj-$(CONFIG_MSM_AIS) += cam_cdm/
obj-$(CONFIG_MSM_AIS) += ais_isp/
obj-$(CONFIG_MSM_AIS) += cam_isp/
obj-$(CONFIG_MSM_AIS) += cam_sensor_module/
obj-$(CONFIG_MSM_AIS) += cam_icp/

View File

@@ -0,0 +1,12 @@
ccflags-y += -Idrivers/media/platform/msm/ais/cam_core
ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp/include
ccflags-y += -Idrivers/media/platform/msm/ais/cam_req_mgr
ccflags-y += -Idrivers/media/platform/msm/ais/cam_smmu/
ccflags-y += -Idrivers/media/platform/msm/ais/cam_sync
ccflags-y += -Idrivers/media/platform/msm/ais/cam_utils
ccflags-y += -Idrivers/media/platform/msm/ais/cam_cdm/
obj-$(CONFIG_MSM_AIS) += csid_hw/
obj-$(CONFIG_MSM_AIS) += vfe_hw/
obj-$(CONFIG_MSM_AIS) += ais_ife_dev.o

View File

@@ -0,0 +1,703 @@
/* Copyright (c) 2017-2018, 2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/module.h>
#include <linux/ion.h>
#include <linux/iommu.h>
#include <linux/timer.h>
#include <linux/kernel.h>
#include <uapi/media/ais_isp.h>
#include <uapi/media/cam_req_mgr.h>
#include "ais_ife_dev.h"
#include "ais_vfe_hw_intf.h"
#include "ais_ife_csid_hw_intf.h"
#include "cam_node.h"
#include "cam_debug_util.h"
#include "cam_smmu_api.h"
#define AIS_IFE_SUBDEVICE_EVENT_MAX 30
static int ais_ife_driver_cmd(struct ais_ife_dev *p_ife_dev, void *arg);
static int ais_ife_init_subdev_params(struct ais_ife_dev *p_ife_dev);
static int ais_ife_subdev_subscribe_event(struct v4l2_subdev *sd,
struct v4l2_fh *fh,
struct v4l2_event_subscription *sub)
{
return v4l2_event_subscribe(fh, sub, AIS_IFE_SUBDEVICE_EVENT_MAX, NULL);
}
static int ais_ife_subdev_unsubscribe_event(struct v4l2_subdev *sd,
struct v4l2_fh *fh,
struct v4l2_event_subscription *sub)
{
return v4l2_event_unsubscribe(fh, sub);
}
static long ais_ife_subdev_ioctl(struct v4l2_subdev *sd,
unsigned int cmd, void *arg)
{
int rc = 0;
struct ais_ife_dev *p_ife_dev = v4l2_get_subdevdata(sd);
switch (cmd) {
case VIDIOC_CAM_CONTROL:
rc = ais_ife_driver_cmd(p_ife_dev, arg);
break;
default:
CAM_ERR(CAM_ISP, "Invalid ioctl cmd: %d", cmd);
rc = -EINVAL;
break;
}
return rc;
}
#ifdef CONFIG_COMPAT
static long ais_ife_subdev_ioctl_compat(struct v4l2_subdev *sd,
unsigned int cmd, unsigned long arg)
{
struct cam_control cmd_data;
int32_t rc = 0;
if (copy_from_user(&cmd_data, (void __user *)arg,
sizeof(cmd_data))) {
CAM_ERR(CAM_SENSOR, "Failed to copy from user_ptr=%pK size=%zu",
(void __user *)arg, sizeof(cmd_data));
return -EFAULT;
}
switch (cmd) {
case VIDIOC_CAM_CONTROL:
rc = ais_ife_subdev_ioctl(sd, cmd, &cmd_data);
if (rc < 0)
CAM_ERR(CAM_SENSOR, "cam_sensor_subdev_ioctl failed");
break;
default:
CAM_ERR(CAM_SENSOR, "Invalid compat ioctl cmd_type: %d", cmd);
rc = -EINVAL;
}
if (!rc) {
if (copy_to_user((void __user *)arg, &cmd_data,
sizeof(cmd_data))) {
CAM_ERR(CAM_SENSOR,
"Failed to copy to user_ptr=%pK size=%zu",
(void __user *)arg, sizeof(cmd_data));
rc = -EFAULT;
}
}
return rc;
}
#endif
static void ais_ife_dev_get_hw_caps(struct ais_ife_dev *p_ife_dev,
struct cam_isp_query_cap_cmd *query_isp)
{
int i;
query_isp->device_iommu.non_secure = p_ife_dev->iommu_hdl;
query_isp->device_iommu.secure = p_ife_dev->iommu_hdl_secure;
query_isp->reserved = p_ife_dev->hw_idx;
query_isp->num_dev = 1;
for (i = 0; i < query_isp->num_dev; i++) {
query_isp->dev_caps[i].hw_type = CAM_ISP_HW_IFE;
query_isp->dev_caps[i].hw_version.major = 1;
query_isp->dev_caps[i].hw_version.minor = 7;
query_isp->dev_caps[i].hw_version.incr = 0;
query_isp->dev_caps[i].hw_version.reserved = 0;
}
}
static int ais_ife_cmd_reserve(struct ais_ife_dev *p_ife_dev,
struct ais_ife_rdi_init_args *rdi_init,
uint32_t cmd_size)
{
int rc;
struct cam_hw_intf *csid_drv;
struct cam_hw_intf *vfe_drv;
struct ais_ife_rdi_deinit_args rdi_deinit;
csid_drv = p_ife_dev->p_csid_drv;
vfe_drv = p_ife_dev->p_vfe_drv;
rdi_deinit.path = rdi_init->path;
rc = csid_drv->hw_ops.init(
csid_drv->hw_priv, rdi_init, cmd_size);
if (!rc) {
rc = vfe_drv->hw_ops.init(
vfe_drv->hw_priv, rdi_init, cmd_size);
if (rc)
goto fail_vfe_init;
}
if (!rc) {
rc = csid_drv->hw_ops.reserve(
csid_drv->hw_priv, rdi_init, cmd_size);
if (rc)
goto fail_csid_reserve;
}
if (!rc) {
rc = vfe_drv->hw_ops.reserve(
vfe_drv->hw_priv, rdi_init, cmd_size);
if (rc)
goto fail_vfe_reserve;
}
return rc;
fail_vfe_reserve:
csid_drv->hw_ops.release(
csid_drv->hw_priv, &rdi_deinit, sizeof(rdi_deinit));
fail_csid_reserve:
vfe_drv->hw_ops.deinit(
vfe_drv->hw_priv, &rdi_deinit, sizeof(rdi_deinit));
fail_vfe_init:
csid_drv->hw_ops.deinit(
csid_drv->hw_priv, &rdi_deinit, sizeof(rdi_deinit));
return rc;
}
static int ais_ife_cmd_release(struct ais_ife_dev *p_ife_dev,
struct ais_ife_rdi_deinit_args *rdi_deinit,
uint32_t cmd_size)
{
int rc;
int tmp;
struct cam_hw_intf *csid_drv;
struct cam_hw_intf *vfe_drv;
csid_drv = p_ife_dev->p_csid_drv;
vfe_drv = p_ife_dev->p_vfe_drv;
rc = csid_drv->hw_ops.release(
csid_drv->hw_priv, rdi_deinit, cmd_size);
tmp = vfe_drv->hw_ops.release(
vfe_drv->hw_priv, rdi_deinit, cmd_size);
if (!rc)
rc = tmp;
tmp = csid_drv->hw_ops.deinit(
csid_drv->hw_priv, rdi_deinit, cmd_size);
if (!rc)
rc = tmp;
tmp = vfe_drv->hw_ops.deinit(
vfe_drv->hw_priv, rdi_deinit, cmd_size);
if (!rc)
rc = tmp;
return rc;
}
static int ais_ife_driver_cmd(struct ais_ife_dev *p_ife_dev, void *arg)
{
int rc = 0;
struct cam_control *cmd = (struct cam_control *)arg;
struct cam_hw_intf *csid_drv;
struct cam_hw_intf *vfe_drv;
if (!p_ife_dev || !arg) {
CAM_ERR(CAM_SENSOR, "s_ctrl is NULL");
rc = -EINVAL;
goto EXIT;
}
if (cmd->handle_type != AIS_ISP_CMD_TYPE) {
CAM_ERR(CAM_SENSOR, "Invalid handle type 0x%x",
cmd->handle_type);
rc = -EINVAL;
goto EXIT;
}
csid_drv = p_ife_dev->p_csid_drv;
vfe_drv = p_ife_dev->p_vfe_drv;
CAM_DBG(CAM_ISP, "CMD %d", cmd->op_code);
mutex_lock(&p_ife_dev->mutex);
switch (cmd->op_code) {
case AIS_IFE_QUERY_CAPS: {
struct cam_isp_query_cap_cmd query_isp;
if (cmd->size != sizeof(query_isp)) {
rc = -EINVAL;
} else if (copy_from_user(&query_isp,
u64_to_user_ptr(cmd->handle),
cmd->size)) {
rc = -EFAULT;
} else {
ais_ife_dev_get_hw_caps(p_ife_dev, &query_isp);
if (copy_to_user(u64_to_user_ptr(cmd->handle),
&query_isp,
cmd->size))
rc = -EFAULT;
}
}
break;
case AIS_IFE_POWER_UP: {
}
break;
case AIS_IFE_POWER_DOWN: {
}
break;
case AIS_IFE_RESET: {
int tmp;
rc = p_ife_dev->p_csid_drv->hw_ops.reset(
p_ife_dev->p_csid_drv->hw_priv, NULL, 0);
tmp = p_ife_dev->p_vfe_drv->hw_ops.reset(
p_ife_dev->p_vfe_drv->hw_priv, NULL, 0);
if (!rc)
rc = tmp;
}
break;
case AIS_IFE_RESERVE: {
struct ais_ife_rdi_init_args rdi_init;
if (cmd->size != sizeof(rdi_init)) {
CAM_ERR(CAM_ISP, "Invalid cmd size");
rc = -EINVAL;
} else if (copy_from_user(&rdi_init,
u64_to_user_ptr(cmd->handle),
cmd->size)) {
rc = -EFAULT;
} else {
rc = ais_ife_cmd_reserve(p_ife_dev,
&rdi_init, cmd->size);
}
}
break;
case AIS_IFE_RELEASE: {
struct ais_ife_rdi_deinit_args rdi_deinit;
if (cmd->size != sizeof(rdi_deinit)) {
CAM_ERR(CAM_ISP, "Invalid cmd size");
rc = -EINVAL;
} else if (copy_from_user(&rdi_deinit,
u64_to_user_ptr(cmd->handle),
cmd->size)) {
rc = -EFAULT;
} else {
rc = ais_ife_cmd_release(p_ife_dev,
&rdi_deinit, cmd->size);
}
}
break;
case AIS_IFE_START: {
struct ais_ife_rdi_start_args rdi_start;
if (cmd->size != sizeof(rdi_start)) {
CAM_ERR(CAM_ISP, "Invalid cmd size");
rc = -EINVAL;
} else if (copy_from_user(&rdi_start,
u64_to_user_ptr(cmd->handle),
cmd->size)) {
rc = -EFAULT;
} else {
rc = csid_drv->hw_ops.start(
csid_drv->hw_priv, &rdi_start, cmd->size);
if (!rc) {
struct ais_ife_rdi_stop_args rdi_stop;
rdi_stop.path = rdi_start.path;
rc = vfe_drv->hw_ops.start(vfe_drv->hw_priv,
&rdi_start, cmd->size);
if (rc)
csid_drv->hw_ops.stop(csid_drv->hw_priv,
&rdi_stop, sizeof(rdi_stop));
}
}
}
break;
case AIS_IFE_STOP: {
struct ais_ife_rdi_stop_args rdi_stop;
if (cmd->size != sizeof(rdi_stop)) {
CAM_ERR(CAM_ISP, "Invalid cmd size");
rc = -EINVAL;
} else if (copy_from_user(&rdi_stop,
u64_to_user_ptr(cmd->handle),
cmd->size)) {
rc = -EFAULT;
} else {
int tmp;
rc = vfe_drv->hw_ops.stop(
vfe_drv->hw_priv, &rdi_stop, cmd->size);
tmp = csid_drv->hw_ops.stop(
csid_drv->hw_priv, &rdi_stop, cmd->size);
if (!rc)
rc = tmp;
}
}
break;
case AIS_IFE_PAUSE: {
struct ais_ife_rdi_stop_args rdi_stop;
if (cmd->size != sizeof(rdi_stop)) {
CAM_ERR(CAM_ISP, "Invalid cmd size");
rc = -EINVAL;
} else if (copy_from_user(&rdi_stop,
u64_to_user_ptr(cmd->handle),
cmd->size)) {
rc = -EFAULT;
} else {
rc = vfe_drv->hw_ops.stop(
vfe_drv->hw_priv, &rdi_stop, cmd->size);
}
}
break;
case AIS_IFE_RESUME: {
struct ais_ife_rdi_start_args rdi_start;
if (cmd->size != sizeof(rdi_start)) {
CAM_ERR(CAM_ISP, "Invalid cmd size");
rc = -EINVAL;
} else if (copy_from_user(&rdi_start,
u64_to_user_ptr(cmd->handle),
cmd->size)) {
rc = -EFAULT;
} else {
rc = vfe_drv->hw_ops.start(
vfe_drv->hw_priv, &rdi_start, cmd->size);
}
}
break;
case AIS_IFE_BUFFER_ENQ: {
struct ais_ife_enqueue_buffer_args enq_buf;
if (cmd->size != sizeof(enq_buf)) {
CAM_ERR(CAM_ISP, "Invalid cmd size");
rc = -EINVAL;
} else if (copy_from_user(&enq_buf,
u64_to_user_ptr(cmd->handle),
cmd->size)) {
rc = -EFAULT;
} else {
rc = vfe_drv->hw_ops.process_cmd(vfe_drv->hw_priv,
AIS_VFE_CMD_ENQ_BUFFER, &enq_buf,
cmd->size);
}
}
break;
default:
rc = -EINVAL;
break;
}
mutex_unlock(&p_ife_dev->mutex);
EXIT:
return rc;
}
static int ais_ife_subdev_open(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
struct ais_ife_dev *p_ife_dev = v4l2_get_subdevdata(sd);
mutex_lock(&p_ife_dev->mutex);
p_ife_dev->open_cnt++;
mutex_unlock(&p_ife_dev->mutex);
return 0;
}
static int ais_ife_subdev_close(struct v4l2_subdev *sd,
struct v4l2_subdev_fh *fh)
{
int rc = 0;
struct ais_ife_dev *p_ife_dev = v4l2_get_subdevdata(sd);
CAM_INFO(CAM_ISP, "IFE%d close", p_ife_dev->hw_idx);
mutex_lock(&p_ife_dev->mutex);
if (p_ife_dev->open_cnt <= 0) {
CAM_ERR(CAM_ISP, "IFE device is already closed");
rc = -EINVAL;
goto end;
}
p_ife_dev->open_cnt--;
/*reset to shutdown vfe and csid*/
if (p_ife_dev->open_cnt == 0) {
CAM_DBG(CAM_ISP, "IFE%d shutdown", p_ife_dev->hw_idx);
p_ife_dev->p_csid_drv->hw_ops.reset(
p_ife_dev->p_csid_drv->hw_priv, NULL, 0);
p_ife_dev->p_vfe_drv->hw_ops.reset(
p_ife_dev->p_vfe_drv->hw_priv, NULL, 0);
CAM_INFO(CAM_ISP, "IFE%d shutdown complete", p_ife_dev->hw_idx);
}
end:
mutex_unlock(&p_ife_dev->mutex);
return rc;
}
static int ais_ife_dev_cb(void *priv, struct ais_ife_event_data *evt_data)
{
struct ais_ife_dev *p_ife_dev;
struct v4l2_event event = {};
p_ife_dev = (struct ais_ife_dev *)priv;
if (!evt_data) {
CAM_ERR(CAM_ISP, "IFE%d callback with NULL event",
p_ife_dev->hw_idx);
return -EINVAL;
}
CAM_DBG(CAM_ISP, "IFE%d CALLBACK %d",
p_ife_dev->hw_idx, evt_data->type);
if (sizeof(*evt_data) > sizeof(event.u.data)) {
CAM_ERR(CAM_ISP, "IFE Callback struct too large (%d)!",
sizeof(*evt_data));
return -EINVAL;
}
spin_lock_bh(&p_ife_dev->eventq_lock);
/* Queue the event */
memcpy(event.u.data, (void *)evt_data, sizeof(*evt_data));
event.id = V4L_EVENT_ID_AIS_IFE;
event.type = V4L_EVENT_TYPE_AIS_IFE;
v4l2_event_queue(p_ife_dev->cam_sd.sd.devnode, &event);
spin_unlock_bh(&p_ife_dev->eventq_lock);
return 0;
}
static void ais_ife_dev_iommu_fault_handler(
struct iommu_domain *domain, struct device *dev, unsigned long iova,
int flags, void *token, uint32_t buf_info)
{
struct ais_ife_dev *p_ife_dev = NULL;
if (!token) {
CAM_ERR(CAM_ISP, "invalid token in page handler cb");
return;
}
p_ife_dev = (struct ais_ife_dev *)token;
CAM_ERR(CAM_ISP, "IFE%d Pagefault at %lu", p_ife_dev->hw_idx, iova);
}
static int ais_ife_dev_remove(struct platform_device *pdev)
{
int rc = 0;
struct ais_ife_dev *p_ife_dev;
p_ife_dev = platform_get_drvdata(pdev);
if (!p_ife_dev) {
CAM_ERR(CAM_ISP, "IFE device is NULL");
return 0;
}
/* clean up resources */
cam_unregister_subdev(&(p_ife_dev->cam_sd));
platform_set_drvdata(pdev, NULL);
v4l2_set_subdevdata(&(p_ife_dev->cam_sd.sd), NULL);
devm_kfree(&pdev->dev, p_ife_dev);
return rc;
}
static int ais_ife_dev_probe(struct platform_device *pdev)
{
int rc = -1;
struct ais_ife_dev *p_ife_dev = NULL;
struct ais_isp_hw_init_args hw_init = {};
/* Create IFE control structure */
p_ife_dev = devm_kzalloc(&pdev->dev,
sizeof(struct ais_ife_dev), GFP_KERNEL);
if (!p_ife_dev)
return -ENOMEM;
rc = of_property_read_u32(pdev->dev.of_node,
"cell-index", &p_ife_dev->hw_idx);
if (rc) {
CAM_ERR(CAM_ISP, "IFE failed to read cell-index");
return rc;
}
/* Initialze the v4l2 subdevice and register with cam_node */
rc = ais_ife_init_subdev_params(p_ife_dev);
if (rc) {
CAM_ERR(CAM_ISP, "IFE%d init subdev failed!",
p_ife_dev->hw_idx);
goto err;
}
mutex_init(&p_ife_dev->mutex);
spin_lock_init(&p_ife_dev->eventq_lock);
/*
* for now, we only support one iommu handle. later
* we will need to setup more iommu handle for other
* use cases.
* Also, we have to release them once we have the
* deinit support
*/
cam_smmu_get_handle("ife", &p_ife_dev->iommu_hdl);
if (rc) {
CAM_ERR(CAM_ISP, "Can not get iommu handle");
rc = -EINVAL;
goto unregister;
}
rc = cam_smmu_ops(p_ife_dev->iommu_hdl, CAM_SMMU_ATTACH);
if (rc && rc != -EALREADY) {
CAM_ERR(CAM_ISP, "Attach iommu handle failed %d", rc);
goto attach_fail;
}
rc = cam_smmu_get_handle("cam-secure",
&p_ife_dev->iommu_hdl_secure);
if (rc) {
CAM_ERR(CAM_ISP, "Failed to get secure iommu handle %d", rc);
goto secure_fail;
}
CAM_DBG(CAM_ISP, "iommu_handles: non-secure[0x%x], secure[0x%x]",
p_ife_dev->iommu_hdl,
p_ife_dev->iommu_hdl_secure);
cam_smmu_set_client_page_fault_handler(p_ife_dev->iommu_hdl,
ais_ife_dev_iommu_fault_handler, p_ife_dev);
hw_init.hw_idx = p_ife_dev->hw_idx;
hw_init.iommu_hdl = p_ife_dev->iommu_hdl;
hw_init.iommu_hdl_secure = p_ife_dev->iommu_hdl_secure;
hw_init.event_cb = &ais_ife_dev_cb;
hw_init.event_cb_priv = p_ife_dev;
rc = ais_ife_csid_hw_init(&p_ife_dev->p_csid_drv, &hw_init);
if (rc) {
CAM_ERR(CAM_ISP, "IFE%d no CSID dev", p_ife_dev->hw_idx, rc);
goto secure_fail;
}
rc = ais_vfe_hw_init(&p_ife_dev->p_vfe_drv, &hw_init,
p_ife_dev->p_csid_drv);
if (rc) {
CAM_ERR(CAM_ISP, "IFE%d no VFE dev", p_ife_dev->hw_idx, rc);
goto secure_fail;
}
CAM_INFO(CAM_ISP, "IFE%d probe complete", p_ife_dev->hw_idx);
platform_set_drvdata(pdev, p_ife_dev);
return 0;
secure_fail:
cam_smmu_ops(p_ife_dev->iommu_hdl,
CAM_SMMU_DETACH);
attach_fail:
cam_smmu_destroy_handle(p_ife_dev->iommu_hdl);
p_ife_dev->iommu_hdl = -1;
unregister:
cam_unregister_subdev(&(p_ife_dev->cam_sd));
err:
return rc;
}
static struct v4l2_subdev_core_ops ais_ife_subdev_core_ops = {
.ioctl = ais_ife_subdev_ioctl,
#ifdef CONFIG_COMPAT
.compat_ioctl32 = ais_ife_subdev_ioctl_compat,
#endif
.subscribe_event = ais_ife_subdev_subscribe_event,
.unsubscribe_event = ais_ife_subdev_unsubscribe_event,
};
static struct v4l2_subdev_ops ais_ife_subdev_ops = {
.core = &ais_ife_subdev_core_ops,
};
static const struct v4l2_subdev_internal_ops ais_ife_internal_ops = {
.open = ais_ife_subdev_open,
.close = ais_ife_subdev_close,
};
static int ais_ife_init_subdev_params(struct ais_ife_dev *p_ife_dev)
{
int rc = 0;
p_ife_dev->cam_sd.internal_ops =
&ais_ife_internal_ops;
p_ife_dev->cam_sd.ops =
&ais_ife_subdev_ops;
strlcpy(p_ife_dev->device_name, AIS_IFE_DEV_NAME,
sizeof(p_ife_dev->device_name));
p_ife_dev->cam_sd.name =
p_ife_dev->device_name;
p_ife_dev->cam_sd.sd_flags =
(V4L2_SUBDEV_FL_HAS_DEVNODE | V4L2_SUBDEV_FL_HAS_EVENTS);
p_ife_dev->cam_sd.ent_function =
AIS_IFE_DEVICE_TYPE;
p_ife_dev->cam_sd.token = p_ife_dev;
rc = cam_register_subdev(&(p_ife_dev->cam_sd));
if (rc)
CAM_ERR(CAM_ISP, "Fail with cam_register_subdev rc: %d", rc);
return rc;
}
static const struct of_device_id ais_ife_dt_match[] = {
{
.compatible = "qcom,ais-ife"
},
{}
};
static struct platform_driver ife_driver = {
.probe = ais_ife_dev_probe,
.remove = ais_ife_dev_remove,
.driver = {
.name = "ais_ife",
.owner = THIS_MODULE,
.of_match_table = ais_ife_dt_match,
.suppress_bind_attrs = true,
},
};
static int __init ais_ife_dev_init_module(void)
{
return platform_driver_register(&ife_driver);
}
static void __exit ais_ife_dev_exit_module(void)
{
platform_driver_unregister(&ife_driver);
}
module_init(ais_ife_dev_init_module);
module_exit(ais_ife_dev_exit_module);
MODULE_DESCRIPTION("AIS IFE driver");
MODULE_LICENSE("GPL v2");

View File

@@ -0,0 +1,48 @@
/* Copyright (c) 2017-2018, 2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_IFE_DEV_H_
#define _AIS_IFE_DEV_H_
#include "cam_subdev.h"
#include "cam_hw_intf.h"
#define AIS_IFE_DEV_NAME_MAX_LENGTH 20
/**
* struct ais_ife_dev - Camera IFE V4l2 device node
*
* @sd: IFE subdevice node
* @ctx: IFE base context storage
* @ctx_isp: IFE private context storage
* @mutex: IFE dev mutex
* @open_cnt: Open device count
*/
struct ais_ife_dev {
/*subdev info*/
char device_name[AIS_IFE_DEV_NAME_MAX_LENGTH];
struct cam_subdev cam_sd;
uint32_t hw_idx;
struct cam_hw_intf *p_vfe_drv;
struct cam_hw_intf *p_csid_drv;
int iommu_hdl;
int iommu_hdl_secure;
spinlock_t eventq_lock;
struct mutex mutex;
int32_t open_cnt;
};
#endif /* _AIS_IFE_DEV_H_ */

View File

@@ -0,0 +1,9 @@
ccflags-y += -Idrivers/media/platform/msm/ais/cam_utils
ccflags-y += -Idrivers/media/platform/msm/ais/cam_core
ccflags-y += -Idrivers/media/platform/msm/ais/cam_cpas/include
ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp/include
ccflags-y += -Idrivers/media/platform/msm/ais/cam_smmu/
ccflags-y += -Idrivers/media/platform/msm/ais/cam_req_mgr/
obj-$(CONFIG_MSM_AIS) += ais_ife_csid_dev.o ais_ife_csid_soc.o ais_ife_csid_core.o
obj-$(CONFIG_MSM_AIS) += ais_ife_csid17x.o ais_ife_csid_lite17x.o

View File

@@ -0,0 +1,316 @@
/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_IFE_CSID_170_H_
#define _AIS_IFE_CSID_170_H_
#include "ais_ife_csid_core.h"
static struct ais_ife_csid_pxl_reg_offset ais_ife_csid_170_ipp_reg_offset = {
.csid_pxl_irq_status_addr = 0x30,
.csid_pxl_irq_mask_addr = 0x34,
.csid_pxl_irq_clear_addr = 0x38,
.csid_pxl_irq_set_addr = 0x3c,
.csid_pxl_cfg0_addr = 0x200,
.csid_pxl_cfg1_addr = 0x204,
.csid_pxl_ctrl_addr = 0x208,
.csid_pxl_frm_drop_pattern_addr = 0x20c,
.csid_pxl_frm_drop_period_addr = 0x210,
.csid_pxl_irq_subsample_pattern_addr = 0x214,
.csid_pxl_irq_subsample_period_addr = 0x218,
.csid_pxl_hcrop_addr = 0x21c,
.csid_pxl_vcrop_addr = 0x220,
.csid_pxl_pix_drop_pattern_addr = 0x224,
.csid_pxl_pix_drop_period_addr = 0x228,
.csid_pxl_line_drop_pattern_addr = 0x22c,
.csid_pxl_line_drop_period_addr = 0x230,
.csid_pxl_rst_strobes_addr = 0x240,
.csid_pxl_status_addr = 0x254,
.csid_pxl_misr_val_addr = 0x258,
.csid_pxl_format_measure_cfg0_addr = 0x270,
.csid_pxl_format_measure_cfg1_addr = 0x274,
.csid_pxl_format_measure0_addr = 0x278,
.csid_pxl_format_measure1_addr = 0x27c,
.csid_pxl_format_measure2_addr = 0x280,
.csid_pxl_timestamp_curr0_sof_addr = 0x290,
.csid_pxl_timestamp_curr1_sof_addr = 0x294,
.csid_pxl_timestamp_perv0_sof_addr = 0x298,
.csid_pxl_timestamp_perv1_sof_addr = 0x29c,
.csid_pxl_timestamp_curr0_eof_addr = 0x2a0,
.csid_pxl_timestamp_curr1_eof_addr = 0x2a4,
.csid_pxl_timestamp_perv0_eof_addr = 0x2a8,
.csid_pxl_timestamp_perv1_eof_addr = 0x2ac,
/* configurations */
.pix_store_en_shift_val = 7,
.early_eof_en_shift_val = 29,
};
static struct ais_ife_csid_rdi_reg_offset ais_ife_csid_170_rdi_0_reg_offset = {
.csid_rdi_irq_status_addr = 0x40,
.csid_rdi_irq_mask_addr = 0x44,
.csid_rdi_irq_clear_addr = 0x48,
.csid_rdi_irq_set_addr = 0x4c,
.csid_rdi_cfg0_addr = 0x300,
.csid_rdi_cfg1_addr = 0x304,
.csid_rdi_ctrl_addr = 0x308,
.csid_rdi_frm_drop_pattern_addr = 0x30c,
.csid_rdi_frm_drop_period_addr = 0x310,
.csid_rdi_irq_subsample_pattern_addr = 0x314,
.csid_rdi_irq_subsample_period_addr = 0x318,
.csid_rdi_rpp_hcrop_addr = 0x31c,
.csid_rdi_rpp_vcrop_addr = 0x320,
.csid_rdi_rpp_pix_drop_pattern_addr = 0x324,
.csid_rdi_rpp_pix_drop_period_addr = 0x328,
.csid_rdi_rpp_line_drop_pattern_addr = 0x32c,
.csid_rdi_rpp_line_drop_period_addr = 0x330,
.csid_rdi_rst_strobes_addr = 0x340,
.csid_rdi_status_addr = 0x350,
.csid_rdi_misr_val0_addr = 0x354,
.csid_rdi_misr_val1_addr = 0x358,
.csid_rdi_misr_val2_addr = 0x35c,
.csid_rdi_misr_val3_addr = 0x360,
.csid_rdi_format_measure_cfg0_addr = 0x370,
.csid_rdi_format_measure_cfg1_addr = 0x374,
.csid_rdi_format_measure0_addr = 0x378,
.csid_rdi_format_measure1_addr = 0x37c,
.csid_rdi_format_measure2_addr = 0x380,
.csid_rdi_timestamp_curr0_sof_addr = 0x390,
.csid_rdi_timestamp_curr1_sof_addr = 0x394,
.csid_rdi_timestamp_prev0_sof_addr = 0x398,
.csid_rdi_timestamp_prev1_sof_addr = 0x39c,
.csid_rdi_timestamp_curr0_eof_addr = 0x3a0,
.csid_rdi_timestamp_curr1_eof_addr = 0x3a4,
.csid_rdi_timestamp_prev0_eof_addr = 0x3a8,
.csid_rdi_timestamp_prev1_eof_addr = 0x3ac,
.csid_rdi_byte_cntr_ping_addr = 0x3e0,
.csid_rdi_byte_cntr_pong_addr = 0x3e4,
};
static struct ais_ife_csid_rdi_reg_offset ais_ife_csid_170_rdi_1_reg_offset = {
.csid_rdi_irq_status_addr = 0x50,
.csid_rdi_irq_mask_addr = 0x54,
.csid_rdi_irq_clear_addr = 0x58,
.csid_rdi_irq_set_addr = 0x5c,
.csid_rdi_cfg0_addr = 0x400,
.csid_rdi_cfg1_addr = 0x404,
.csid_rdi_ctrl_addr = 0x408,
.csid_rdi_frm_drop_pattern_addr = 0x40c,
.csid_rdi_frm_drop_period_addr = 0x410,
.csid_rdi_irq_subsample_pattern_addr = 0x414,
.csid_rdi_irq_subsample_period_addr = 0x418,
.csid_rdi_rpp_hcrop_addr = 0x41c,
.csid_rdi_rpp_vcrop_addr = 0x420,
.csid_rdi_rpp_pix_drop_pattern_addr = 0x424,
.csid_rdi_rpp_pix_drop_period_addr = 0x428,
.csid_rdi_rpp_line_drop_pattern_addr = 0x42c,
.csid_rdi_rpp_line_drop_period_addr = 0x430,
.csid_rdi_rst_strobes_addr = 0x440,
.csid_rdi_status_addr = 0x450,
.csid_rdi_misr_val0_addr = 0x454,
.csid_rdi_misr_val1_addr = 0x458,
.csid_rdi_misr_val2_addr = 0x45c,
.csid_rdi_misr_val3_addr = 0x460,
.csid_rdi_format_measure_cfg0_addr = 0x470,
.csid_rdi_format_measure_cfg1_addr = 0x474,
.csid_rdi_format_measure0_addr = 0x478,
.csid_rdi_format_measure1_addr = 0x47c,
.csid_rdi_format_measure2_addr = 0x480,
.csid_rdi_timestamp_curr0_sof_addr = 0x490,
.csid_rdi_timestamp_curr1_sof_addr = 0x494,
.csid_rdi_timestamp_prev0_sof_addr = 0x498,
.csid_rdi_timestamp_prev1_sof_addr = 0x49c,
.csid_rdi_timestamp_curr0_eof_addr = 0x4a0,
.csid_rdi_timestamp_curr1_eof_addr = 0x4a4,
.csid_rdi_timestamp_prev0_eof_addr = 0x4a8,
.csid_rdi_timestamp_prev1_eof_addr = 0x4ac,
.csid_rdi_byte_cntr_ping_addr = 0x4e0,
.csid_rdi_byte_cntr_pong_addr = 0x4e4,
};
static struct ais_ife_csid_rdi_reg_offset ais_ife_csid_170_rdi_2_reg_offset = {
.csid_rdi_irq_status_addr = 0x60,
.csid_rdi_irq_mask_addr = 0x64,
.csid_rdi_irq_clear_addr = 0x68,
.csid_rdi_irq_set_addr = 0x6c,
.csid_rdi_cfg0_addr = 0x500,
.csid_rdi_cfg1_addr = 0x504,
.csid_rdi_ctrl_addr = 0x508,
.csid_rdi_frm_drop_pattern_addr = 0x50c,
.csid_rdi_frm_drop_period_addr = 0x510,
.csid_rdi_irq_subsample_pattern_addr = 0x514,
.csid_rdi_irq_subsample_period_addr = 0x518,
.csid_rdi_rpp_hcrop_addr = 0x51c,
.csid_rdi_rpp_vcrop_addr = 0x520,
.csid_rdi_rpp_pix_drop_pattern_addr = 0x524,
.csid_rdi_rpp_pix_drop_period_addr = 0x528,
.csid_rdi_rpp_line_drop_pattern_addr = 0x52c,
.csid_rdi_rpp_line_drop_period_addr = 0x530,
.csid_rdi_yuv_chroma_conversion_addr = 0x534,
.csid_rdi_rst_strobes_addr = 0x540,
.csid_rdi_status_addr = 0x550,
.csid_rdi_misr_val0_addr = 0x554,
.csid_rdi_misr_val1_addr = 0x558,
.csid_rdi_misr_val2_addr = 0x55c,
.csid_rdi_misr_val3_addr = 0x560,
.csid_rdi_format_measure_cfg0_addr = 0x570,
.csid_rdi_format_measure_cfg1_addr = 0x574,
.csid_rdi_format_measure0_addr = 0x578,
.csid_rdi_format_measure1_addr = 0x57c,
.csid_rdi_format_measure2_addr = 0x580,
.csid_rdi_timestamp_curr0_sof_addr = 0x590,
.csid_rdi_timestamp_curr1_sof_addr = 0x594,
.csid_rdi_timestamp_prev0_sof_addr = 0x598,
.csid_rdi_timestamp_prev1_sof_addr = 0x59c,
.csid_rdi_timestamp_curr0_eof_addr = 0x5a0,
.csid_rdi_timestamp_curr1_eof_addr = 0x5a4,
.csid_rdi_timestamp_prev0_eof_addr = 0x5a8,
.csid_rdi_timestamp_prev1_eof_addr = 0x5ac,
.csid_rdi_byte_cntr_ping_addr = 0x5e0,
.csid_rdi_byte_cntr_pong_addr = 0x5e4,
};
static struct ais_ife_csid_csi2_rx_reg_offset
ais_ife_csid_170_csi2_reg_offset = {
.csid_csi2_rx_irq_status_addr = 0x20,
.csid_csi2_rx_irq_mask_addr = 0x24,
.csid_csi2_rx_irq_clear_addr = 0x28,
.csid_csi2_rx_irq_set_addr = 0x2c,
/*CSI2 rx control */
.csid_csi2_rx_cfg0_addr = 0x100,
.csid_csi2_rx_cfg1_addr = 0x104,
.csid_csi2_rx_capture_ctrl_addr = 0x108,
.csid_csi2_rx_rst_strobes_addr = 0x110,
.csid_csi2_rx_de_scramble_cfg0_addr = 0x114,
.csid_csi2_rx_de_scramble_cfg1_addr = 0x118,
.csid_csi2_rx_cap_unmap_long_pkt_hdr_0_addr = 0x120,
.csid_csi2_rx_cap_unmap_long_pkt_hdr_1_addr = 0x124,
.csid_csi2_rx_captured_short_pkt_0_addr = 0x128,
.csid_csi2_rx_captured_short_pkt_1_addr = 0x12c,
.csid_csi2_rx_captured_long_pkt_0_addr = 0x130,
.csid_csi2_rx_captured_long_pkt_1_addr = 0x134,
.csid_csi2_rx_captured_long_pkt_ftr_addr = 0x138,
.csid_csi2_rx_captured_cphy_pkt_hdr_addr = 0x13c,
.csid_csi2_rx_lane0_misr_addr = 0x150,
.csid_csi2_rx_lane1_misr_addr = 0x154,
.csid_csi2_rx_lane2_misr_addr = 0x158,
.csid_csi2_rx_lane3_misr_addr = 0x15c,
.csid_csi2_rx_total_pkts_rcvd_addr = 0x160,
.csid_csi2_rx_stats_ecc_addr = 0x164,
.csid_csi2_rx_total_crc_err_addr = 0x168,
.csi2_rst_srb_all = 0x3FFF,
.csi2_rst_done_shift_val = 27,
.csi2_irq_mask_all = 0xFFFFFFF,
.csi2_misr_enable_shift_val = 6,
.csi2_vc_mode_shift_val = 2,
.csi2_capture_long_pkt_en_shift = 0,
.csi2_capture_short_pkt_en_shift = 1,
.csi2_capture_cphy_pkt_en_shift = 2,
.csi2_capture_long_pkt_dt_shift = 4,
.csi2_capture_long_pkt_vc_shift = 10,
.csi2_capture_short_pkt_vc_shift = 15,
.csi2_capture_cphy_pkt_dt_shift = 20,
.csi2_capture_cphy_pkt_vc_shift = 26,
.csi2_rx_phy_num_mask = 0x3,
};
static struct ais_ife_csid_csi2_tpg_reg_offset
ais_ife_csid_170_tpg_reg_offset = {
/*CSID TPG control */
.csid_tpg_ctrl_addr = 0x600,
.csid_tpg_vc_cfg0_addr = 0x604,
.csid_tpg_vc_cfg1_addr = 0x608,
.csid_tpg_lfsr_seed_addr = 0x60c,
.csid_tpg_dt_n_cfg_0_addr = 0x610,
.csid_tpg_dt_n_cfg_1_addr = 0x614,
.csid_tpg_dt_n_cfg_2_addr = 0x618,
.csid_tpg_color_bars_cfg_addr = 0x640,
.csid_tpg_color_box_cfg_addr = 0x644,
.csid_tpg_common_gen_cfg_addr = 0x648,
.csid_tpg_cgen_n_cfg_addr = 0x650,
.csid_tpg_cgen_n_x0_addr = 0x654,
.csid_tpg_cgen_n_x1_addr = 0x658,
.csid_tpg_cgen_n_x2_addr = 0x65c,
.csid_tpg_cgen_n_xy_addr = 0x660,
.csid_tpg_cgen_n_y1_addr = 0x664,
.csid_tpg_cgen_n_y2_addr = 0x668,
/* configurations */
.tpg_dtn_cfg_offset = 0xc,
.tpg_cgen_cfg_offset = 0x20,
.tpg_cpas_ife_reg_offset = 0x28,
};
static struct ais_ife_csid_common_reg_offset
ais_ife_csid_170_cmn_reg_offset = {
.csid_hw_version_addr = 0x0,
.csid_cfg0_addr = 0x4,
.csid_ctrl_addr = 0x8,
.csid_reset_addr = 0xc,
.csid_rst_strobes_addr = 0x10,
.csid_test_bus_ctrl_addr = 0x14,
.csid_top_irq_status_addr = 0x70,
.csid_top_irq_mask_addr = 0x74,
.csid_top_irq_clear_addr = 0x78,
.csid_top_irq_set_addr = 0x7c,
.csid_irq_cmd_addr = 0x80,
/*configurations */
.major_version = 1,
.minor_version = 7,
.version_incr = 0,
.num_rdis = 3,
.num_pix = 1,
.num_ppp = 0,
.csid_reg_rst_stb = 1,
.csid_rst_stb = 0x1e,
.csid_rst_stb_sw_all = 0x1f,
.path_rst_stb_all = 0x7f,
.path_rst_done_shift_val = 1,
.path_en_shift_val = 31,
.dt_id_shift_val = 27,
.vc_shift_val = 22,
.dt_shift_val = 16,
.fmt_shift_val = 12,
.plain_fmt_shit_val = 10,
.crop_v_en_shift_val = 6,
.crop_h_en_shift_val = 5,
.crop_shift = 16,
.ipp_irq_mask_all = 0x7FFF,
.rdi_irq_mask_all = 0x7FFF,
.ppp_irq_mask_all = 0x0,
.measure_en_hbi_vbi_cnt_mask = 0xC,
.format_measure_en_val = 1,
.format_measure_height_mask_val = 0xFFFF,
.format_measure_height_shift_val = 0x10,
.format_measure_width_mask_val = 0xFFFF,
.format_measure_width_shift_val = 0x0,
};
static struct ais_ife_csid_reg_offset ais_ife_csid_170_reg_offset = {
.cmn_reg = &ais_ife_csid_170_cmn_reg_offset,
.csi2_reg = &ais_ife_csid_170_csi2_reg_offset,
.ipp_reg = &ais_ife_csid_170_ipp_reg_offset,
.ppp_reg = NULL,
.rdi_reg = {
&ais_ife_csid_170_rdi_0_reg_offset,
&ais_ife_csid_170_rdi_1_reg_offset,
&ais_ife_csid_170_rdi_2_reg_offset,
NULL,
},
.tpg_reg = &ais_ife_csid_170_tpg_reg_offset,
};
#endif /*_AIS_IFE_CSID_170_H_ */

View File

@@ -0,0 +1,357 @@
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_IFE_CSID_175_H_
#define _AIS_IFE_CSID_175_H_
#include "ais_ife_csid_core.h"
static struct ais_ife_csid_pxl_reg_offset ais_ife_csid_175_ipp_reg_offset = {
.csid_pxl_irq_status_addr = 0x30,
.csid_pxl_irq_mask_addr = 0x34,
.csid_pxl_irq_clear_addr = 0x38,
.csid_pxl_irq_set_addr = 0x3c,
.csid_pxl_cfg0_addr = 0x200,
.csid_pxl_cfg1_addr = 0x204,
.csid_pxl_ctrl_addr = 0x208,
.csid_pxl_frm_drop_pattern_addr = 0x20c,
.csid_pxl_frm_drop_period_addr = 0x210,
.csid_pxl_irq_subsample_pattern_addr = 0x214,
.csid_pxl_irq_subsample_period_addr = 0x218,
.csid_pxl_hcrop_addr = 0x21c,
.csid_pxl_vcrop_addr = 0x220,
.csid_pxl_pix_drop_pattern_addr = 0x224,
.csid_pxl_pix_drop_period_addr = 0x228,
.csid_pxl_line_drop_pattern_addr = 0x22c,
.csid_pxl_line_drop_period_addr = 0x230,
.csid_pxl_rst_strobes_addr = 0x240,
.csid_pxl_status_addr = 0x254,
.csid_pxl_misr_val_addr = 0x258,
.csid_pxl_format_measure_cfg0_addr = 0x270,
.csid_pxl_format_measure_cfg1_addr = 0x274,
.csid_pxl_format_measure0_addr = 0x278,
.csid_pxl_format_measure1_addr = 0x27c,
.csid_pxl_format_measure2_addr = 0x280,
.csid_pxl_timestamp_curr0_sof_addr = 0x290,
.csid_pxl_timestamp_curr1_sof_addr = 0x294,
.csid_pxl_timestamp_perv0_sof_addr = 0x298,
.csid_pxl_timestamp_perv1_sof_addr = 0x29c,
.csid_pxl_timestamp_curr0_eof_addr = 0x2a0,
.csid_pxl_timestamp_curr1_eof_addr = 0x2a4,
.csid_pxl_timestamp_perv0_eof_addr = 0x2a8,
.csid_pxl_timestamp_perv1_eof_addr = 0x2ac,
/* configurations */
.pix_store_en_shift_val = 7,
.early_eof_en_shift_val = 29,
};
static struct ais_ife_csid_pxl_reg_offset ais_ife_csid_175_ppp_reg_offset = {
.csid_pxl_irq_status_addr = 0xa0,
.csid_pxl_irq_mask_addr = 0xa4,
.csid_pxl_irq_clear_addr = 0xa8,
.csid_pxl_irq_set_addr = 0xac,
.csid_pxl_cfg0_addr = 0x700,
.csid_pxl_cfg1_addr = 0x704,
.csid_pxl_ctrl_addr = 0x708,
.csid_pxl_frm_drop_pattern_addr = 0x70c,
.csid_pxl_frm_drop_period_addr = 0x710,
.csid_pxl_irq_subsample_pattern_addr = 0x714,
.csid_pxl_irq_subsample_period_addr = 0x718,
.csid_pxl_hcrop_addr = 0x71c,
.csid_pxl_vcrop_addr = 0x720,
.csid_pxl_pix_drop_pattern_addr = 0x724,
.csid_pxl_pix_drop_period_addr = 0x728,
.csid_pxl_line_drop_pattern_addr = 0x72c,
.csid_pxl_line_drop_period_addr = 0x730,
.csid_pxl_rst_strobes_addr = 0x740,
.csid_pxl_status_addr = 0x754,
.csid_pxl_misr_val_addr = 0x758,
.csid_pxl_format_measure_cfg0_addr = 0x770,
.csid_pxl_format_measure_cfg1_addr = 0x774,
.csid_pxl_format_measure0_addr = 0x778,
.csid_pxl_format_measure1_addr = 0x77c,
.csid_pxl_format_measure2_addr = 0x780,
.csid_pxl_timestamp_curr0_sof_addr = 0x790,
.csid_pxl_timestamp_curr1_sof_addr = 0x794,
.csid_pxl_timestamp_perv0_sof_addr = 0x798,
.csid_pxl_timestamp_perv1_sof_addr = 0x79c,
.csid_pxl_timestamp_curr0_eof_addr = 0x7a0,
.csid_pxl_timestamp_curr1_eof_addr = 0x7a4,
.csid_pxl_timestamp_perv0_eof_addr = 0x7a8,
.csid_pxl_timestamp_perv1_eof_addr = 0x7ac,
/* configurations */
.pix_store_en_shift_val = 7,
.early_eof_en_shift_val = 29,
};
static struct ais_ife_csid_rdi_reg_offset ais_ife_csid_175_rdi_0_reg_offset = {
.csid_rdi_irq_status_addr = 0x40,
.csid_rdi_irq_mask_addr = 0x44,
.csid_rdi_irq_clear_addr = 0x48,
.csid_rdi_irq_set_addr = 0x4c,
.csid_rdi_cfg0_addr = 0x300,
.csid_rdi_cfg1_addr = 0x304,
.csid_rdi_ctrl_addr = 0x308,
.csid_rdi_frm_drop_pattern_addr = 0x30c,
.csid_rdi_frm_drop_period_addr = 0x310,
.csid_rdi_irq_subsample_pattern_addr = 0x314,
.csid_rdi_irq_subsample_period_addr = 0x318,
.csid_rdi_rpp_hcrop_addr = 0x31c,
.csid_rdi_rpp_vcrop_addr = 0x320,
.csid_rdi_rpp_pix_drop_pattern_addr = 0x324,
.csid_rdi_rpp_pix_drop_period_addr = 0x328,
.csid_rdi_rpp_line_drop_pattern_addr = 0x32c,
.csid_rdi_rpp_line_drop_period_addr = 0x330,
.csid_rdi_rst_strobes_addr = 0x340,
.csid_rdi_status_addr = 0x350,
.csid_rdi_misr_val0_addr = 0x354,
.csid_rdi_misr_val1_addr = 0x358,
.csid_rdi_misr_val2_addr = 0x35c,
.csid_rdi_misr_val3_addr = 0x360,
.csid_rdi_format_measure_cfg0_addr = 0x370,
.csid_rdi_format_measure_cfg1_addr = 0x374,
.csid_rdi_format_measure0_addr = 0x378,
.csid_rdi_format_measure1_addr = 0x37c,
.csid_rdi_format_measure2_addr = 0x380,
.csid_rdi_timestamp_curr0_sof_addr = 0x390,
.csid_rdi_timestamp_curr1_sof_addr = 0x394,
.csid_rdi_timestamp_prev0_sof_addr = 0x398,
.csid_rdi_timestamp_prev1_sof_addr = 0x39c,
.csid_rdi_timestamp_curr0_eof_addr = 0x3a0,
.csid_rdi_timestamp_curr1_eof_addr = 0x3a4,
.csid_rdi_timestamp_prev0_eof_addr = 0x3a8,
.csid_rdi_timestamp_prev1_eof_addr = 0x3ac,
.csid_rdi_byte_cntr_ping_addr = 0x3e0,
.csid_rdi_byte_cntr_pong_addr = 0x3e4,
};
static struct ais_ife_csid_rdi_reg_offset ais_ife_csid_175_rdi_1_reg_offset = {
.csid_rdi_irq_status_addr = 0x50,
.csid_rdi_irq_mask_addr = 0x54,
.csid_rdi_irq_clear_addr = 0x58,
.csid_rdi_irq_set_addr = 0x5c,
.csid_rdi_cfg0_addr = 0x400,
.csid_rdi_cfg1_addr = 0x404,
.csid_rdi_ctrl_addr = 0x408,
.csid_rdi_frm_drop_pattern_addr = 0x40c,
.csid_rdi_frm_drop_period_addr = 0x410,
.csid_rdi_irq_subsample_pattern_addr = 0x414,
.csid_rdi_irq_subsample_period_addr = 0x418,
.csid_rdi_rpp_hcrop_addr = 0x41c,
.csid_rdi_rpp_vcrop_addr = 0x420,
.csid_rdi_rpp_pix_drop_pattern_addr = 0x424,
.csid_rdi_rpp_pix_drop_period_addr = 0x428,
.csid_rdi_rpp_line_drop_pattern_addr = 0x42c,
.csid_rdi_rpp_line_drop_period_addr = 0x430,
.csid_rdi_rst_strobes_addr = 0x440,
.csid_rdi_status_addr = 0x450,
.csid_rdi_misr_val0_addr = 0x454,
.csid_rdi_misr_val1_addr = 0x458,
.csid_rdi_misr_val2_addr = 0x45c,
.csid_rdi_misr_val3_addr = 0x460,
.csid_rdi_format_measure_cfg0_addr = 0x470,
.csid_rdi_format_measure_cfg1_addr = 0x474,
.csid_rdi_format_measure0_addr = 0x478,
.csid_rdi_format_measure1_addr = 0x47c,
.csid_rdi_format_measure2_addr = 0x480,
.csid_rdi_timestamp_curr0_sof_addr = 0x490,
.csid_rdi_timestamp_curr1_sof_addr = 0x494,
.csid_rdi_timestamp_prev0_sof_addr = 0x498,
.csid_rdi_timestamp_prev1_sof_addr = 0x49c,
.csid_rdi_timestamp_curr0_eof_addr = 0x4a0,
.csid_rdi_timestamp_curr1_eof_addr = 0x4a4,
.csid_rdi_timestamp_prev0_eof_addr = 0x4a8,
.csid_rdi_timestamp_prev1_eof_addr = 0x4ac,
.csid_rdi_byte_cntr_ping_addr = 0x4e0,
.csid_rdi_byte_cntr_pong_addr = 0x4e4,
};
static struct ais_ife_csid_rdi_reg_offset ais_ife_csid_175_rdi_2_reg_offset = {
.csid_rdi_irq_status_addr = 0x60,
.csid_rdi_irq_mask_addr = 0x64,
.csid_rdi_irq_clear_addr = 0x68,
.csid_rdi_irq_set_addr = 0x6c,
.csid_rdi_cfg0_addr = 0x500,
.csid_rdi_cfg1_addr = 0x504,
.csid_rdi_ctrl_addr = 0x508,
.csid_rdi_frm_drop_pattern_addr = 0x50c,
.csid_rdi_frm_drop_period_addr = 0x510,
.csid_rdi_irq_subsample_pattern_addr = 0x514,
.csid_rdi_irq_subsample_period_addr = 0x518,
.csid_rdi_rpp_hcrop_addr = 0x51c,
.csid_rdi_rpp_vcrop_addr = 0x520,
.csid_rdi_rpp_pix_drop_pattern_addr = 0x524,
.csid_rdi_rpp_pix_drop_period_addr = 0x528,
.csid_rdi_rpp_line_drop_pattern_addr = 0x52c,
.csid_rdi_rpp_line_drop_period_addr = 0x530,
.csid_rdi_yuv_chroma_conversion_addr = 0x534,
.csid_rdi_rst_strobes_addr = 0x540,
.csid_rdi_status_addr = 0x550,
.csid_rdi_misr_val0_addr = 0x554,
.csid_rdi_misr_val1_addr = 0x558,
.csid_rdi_misr_val2_addr = 0x55c,
.csid_rdi_misr_val3_addr = 0x560,
.csid_rdi_format_measure_cfg0_addr = 0x570,
.csid_rdi_format_measure_cfg1_addr = 0x574,
.csid_rdi_format_measure0_addr = 0x578,
.csid_rdi_format_measure1_addr = 0x57c,
.csid_rdi_format_measure2_addr = 0x580,
.csid_rdi_timestamp_curr0_sof_addr = 0x590,
.csid_rdi_timestamp_curr1_sof_addr = 0x594,
.csid_rdi_timestamp_prev0_sof_addr = 0x598,
.csid_rdi_timestamp_prev1_sof_addr = 0x59c,
.csid_rdi_timestamp_curr0_eof_addr = 0x5a0,
.csid_rdi_timestamp_curr1_eof_addr = 0x5a4,
.csid_rdi_timestamp_prev0_eof_addr = 0x5a8,
.csid_rdi_timestamp_prev1_eof_addr = 0x5ac,
.csid_rdi_byte_cntr_ping_addr = 0x5e0,
.csid_rdi_byte_cntr_pong_addr = 0x5e4,
};
static struct ais_ife_csid_csi2_rx_reg_offset
ais_ife_csid_175_csi2_reg_offset = {
.csid_csi2_rx_irq_status_addr = 0x20,
.csid_csi2_rx_irq_mask_addr = 0x24,
.csid_csi2_rx_irq_clear_addr = 0x28,
.csid_csi2_rx_irq_set_addr = 0x2c,
/*CSI2 rx control */
.csid_csi2_rx_cfg0_addr = 0x100,
.csid_csi2_rx_cfg1_addr = 0x104,
.csid_csi2_rx_capture_ctrl_addr = 0x108,
.csid_csi2_rx_rst_strobes_addr = 0x110,
.csid_csi2_rx_de_scramble_cfg0_addr = 0x114,
.csid_csi2_rx_de_scramble_cfg1_addr = 0x118,
.csid_csi2_rx_cap_unmap_long_pkt_hdr_0_addr = 0x120,
.csid_csi2_rx_cap_unmap_long_pkt_hdr_1_addr = 0x124,
.csid_csi2_rx_captured_short_pkt_0_addr = 0x128,
.csid_csi2_rx_captured_short_pkt_1_addr = 0x12c,
.csid_csi2_rx_captured_long_pkt_0_addr = 0x130,
.csid_csi2_rx_captured_long_pkt_1_addr = 0x134,
.csid_csi2_rx_captured_long_pkt_ftr_addr = 0x138,
.csid_csi2_rx_captured_cphy_pkt_hdr_addr = 0x13c,
.csid_csi2_rx_lane0_misr_addr = 0x150,
.csid_csi2_rx_lane1_misr_addr = 0x154,
.csid_csi2_rx_lane2_misr_addr = 0x158,
.csid_csi2_rx_lane3_misr_addr = 0x15c,
.csid_csi2_rx_total_pkts_rcvd_addr = 0x160,
.csid_csi2_rx_stats_ecc_addr = 0x164,
.csid_csi2_rx_total_crc_err_addr = 0x168,
.csi2_rst_srb_all = 0x3FFF,
.csi2_rst_done_shift_val = 27,
.csi2_irq_mask_all = 0xFFFFFFF,
.csi2_misr_enable_shift_val = 6,
.csi2_vc_mode_shift_val = 2,
.csi2_capture_long_pkt_en_shift = 0,
.csi2_capture_short_pkt_en_shift = 1,
.csi2_capture_cphy_pkt_en_shift = 2,
.csi2_capture_long_pkt_dt_shift = 4,
.csi2_capture_long_pkt_vc_shift = 10,
.csi2_capture_short_pkt_vc_shift = 15,
.csi2_capture_cphy_pkt_dt_shift = 20,
.csi2_capture_cphy_pkt_vc_shift = 26,
.csi2_rx_phy_num_mask = 0x3,
};
static struct ais_ife_csid_csi2_tpg_reg_offset
ais_ife_csid_175_tpg_reg_offset = {
/*CSID TPG control */
.csid_tpg_ctrl_addr = 0x600,
.csid_tpg_vc_cfg0_addr = 0x604,
.csid_tpg_vc_cfg1_addr = 0x608,
.csid_tpg_lfsr_seed_addr = 0x60c,
.csid_tpg_dt_n_cfg_0_addr = 0x610,
.csid_tpg_dt_n_cfg_1_addr = 0x614,
.csid_tpg_dt_n_cfg_2_addr = 0x618,
.csid_tpg_color_bars_cfg_addr = 0x640,
.csid_tpg_color_box_cfg_addr = 0x644,
.csid_tpg_common_gen_cfg_addr = 0x648,
.csid_tpg_cgen_n_cfg_addr = 0x650,
.csid_tpg_cgen_n_x0_addr = 0x654,
.csid_tpg_cgen_n_x1_addr = 0x658,
.csid_tpg_cgen_n_x2_addr = 0x65c,
.csid_tpg_cgen_n_xy_addr = 0x660,
.csid_tpg_cgen_n_y1_addr = 0x664,
.csid_tpg_cgen_n_y2_addr = 0x668,
/* configurations */
.tpg_dtn_cfg_offset = 0xc,
.tpg_cgen_cfg_offset = 0x20,
.tpg_cpas_ife_reg_offset = 0x28,
};
static struct ais_ife_csid_common_reg_offset
ais_ife_csid_175_cmn_reg_offset = {
.csid_hw_version_addr = 0x0,
.csid_cfg0_addr = 0x4,
.csid_ctrl_addr = 0x8,
.csid_reset_addr = 0xc,
.csid_rst_strobes_addr = 0x10,
.csid_test_bus_ctrl_addr = 0x14,
.csid_top_irq_status_addr = 0x70,
.csid_top_irq_mask_addr = 0x74,
.csid_top_irq_clear_addr = 0x78,
.csid_top_irq_set_addr = 0x7c,
.csid_irq_cmd_addr = 0x80,
/*configurations */
.major_version = 1,
.minor_version = 7,
.version_incr = 0,
.num_rdis = 3,
.num_pix = 1,
.num_ppp = 1,
.csid_reg_rst_stb = 1,
.csid_rst_stb = 0x1e,
.csid_rst_stb_sw_all = 0x1f,
.path_rst_stb_all = 0x7f,
.path_rst_done_shift_val = 1,
.path_en_shift_val = 31,
.dt_id_shift_val = 27,
.vc_shift_val = 22,
.dt_shift_val = 16,
.fmt_shift_val = 12,
.plain_fmt_shit_val = 10,
.crop_v_en_shift_val = 6,
.crop_h_en_shift_val = 5,
.crop_shift = 16,
.ipp_irq_mask_all = 0x7FFF,
.rdi_irq_mask_all = 0x7FFF,
.ppp_irq_mask_all = 0xFFFF,
.measure_en_hbi_vbi_cnt_mask = 0xC,
.format_measure_en_val = 1,
.format_measure_height_mask_val = 0xFFFF,
.format_measure_height_shift_val = 0x10,
.format_measure_width_mask_val = 0xFFFF,
.format_measure_width_shift_val = 0x0,
};
static struct ais_ife_csid_reg_offset ais_ife_csid_175_reg_offset = {
.cmn_reg = &ais_ife_csid_175_cmn_reg_offset,
.csi2_reg = &ais_ife_csid_175_csi2_reg_offset,
.ipp_reg = &ais_ife_csid_175_ipp_reg_offset,
.ppp_reg = &ais_ife_csid_175_ppp_reg_offset,
.rdi_reg = {
&ais_ife_csid_175_rdi_0_reg_offset,
&ais_ife_csid_175_rdi_1_reg_offset,
&ais_ife_csid_175_rdi_2_reg_offset,
NULL,
},
.tpg_reg = &ais_ife_csid_175_tpg_reg_offset,
};
#endif /*_AIS_IFE_CSID_175_H_ */

View File

@@ -0,0 +1,373 @@
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_IFE_CSID_175_200_H_
#define _AIS_IFE_CSID_175_200_H_
#include "ais_ife_csid_core.h"
static struct ais_ife_csid_pxl_reg_offset
ais_ife_csid_175_200_ipp_reg_offset = {
.csid_pxl_irq_status_addr = 0x30,
.csid_pxl_irq_mask_addr = 0x34,
.csid_pxl_irq_clear_addr = 0x38,
.csid_pxl_irq_set_addr = 0x3c,
.csid_pxl_cfg0_addr = 0x200,
.csid_pxl_cfg1_addr = 0x204,
.csid_pxl_ctrl_addr = 0x208,
.csid_pxl_frm_drop_pattern_addr = 0x20c,
.csid_pxl_frm_drop_period_addr = 0x210,
.csid_pxl_irq_subsample_pattern_addr = 0x214,
.csid_pxl_irq_subsample_period_addr = 0x218,
.csid_pxl_hcrop_addr = 0x21c,
.csid_pxl_vcrop_addr = 0x220,
.csid_pxl_pix_drop_pattern_addr = 0x224,
.csid_pxl_pix_drop_period_addr = 0x228,
.csid_pxl_line_drop_pattern_addr = 0x22c,
.csid_pxl_line_drop_period_addr = 0x230,
.csid_pxl_rst_strobes_addr = 0x240,
.csid_pxl_status_addr = 0x254,
.csid_pxl_misr_val_addr = 0x258,
.csid_pxl_format_measure_cfg0_addr = 0x270,
.csid_pxl_format_measure_cfg1_addr = 0x274,
.csid_pxl_format_measure0_addr = 0x278,
.csid_pxl_format_measure1_addr = 0x27c,
.csid_pxl_format_measure2_addr = 0x280,
.csid_pxl_timestamp_curr0_sof_addr = 0x290,
.csid_pxl_timestamp_curr1_sof_addr = 0x294,
.csid_pxl_timestamp_perv0_sof_addr = 0x298,
.csid_pxl_timestamp_perv1_sof_addr = 0x29c,
.csid_pxl_timestamp_curr0_eof_addr = 0x2a0,
.csid_pxl_timestamp_curr1_eof_addr = 0x2a4,
.csid_pxl_timestamp_perv0_eof_addr = 0x2a8,
.csid_pxl_timestamp_perv1_eof_addr = 0x2ac,
/* configurations */
.pix_store_en_shift_val = 7,
.early_eof_en_shift_val = 29,
.ccif_violation_en = 1,
};
static struct ais_ife_csid_pxl_reg_offset
ais_ife_csid_175_200_ppp_reg_offset = {
.csid_pxl_irq_status_addr = 0xa0,
.csid_pxl_irq_mask_addr = 0xa4,
.csid_pxl_irq_clear_addr = 0xa8,
.csid_pxl_irq_set_addr = 0xac,
.csid_pxl_cfg0_addr = 0x700,
.csid_pxl_cfg1_addr = 0x704,
.csid_pxl_ctrl_addr = 0x708,
.csid_pxl_frm_drop_pattern_addr = 0x70c,
.csid_pxl_frm_drop_period_addr = 0x710,
.csid_pxl_irq_subsample_pattern_addr = 0x714,
.csid_pxl_irq_subsample_period_addr = 0x718,
.csid_pxl_hcrop_addr = 0x71c,
.csid_pxl_vcrop_addr = 0x720,
.csid_pxl_pix_drop_pattern_addr = 0x724,
.csid_pxl_pix_drop_period_addr = 0x728,
.csid_pxl_line_drop_pattern_addr = 0x72c,
.csid_pxl_line_drop_period_addr = 0x730,
.csid_pxl_rst_strobes_addr = 0x740,
.csid_pxl_status_addr = 0x754,
.csid_pxl_misr_val_addr = 0x758,
.csid_pxl_format_measure_cfg0_addr = 0x770,
.csid_pxl_format_measure_cfg1_addr = 0x774,
.csid_pxl_format_measure0_addr = 0x778,
.csid_pxl_format_measure1_addr = 0x77c,
.csid_pxl_format_measure2_addr = 0x780,
.csid_pxl_timestamp_curr0_sof_addr = 0x790,
.csid_pxl_timestamp_curr1_sof_addr = 0x794,
.csid_pxl_timestamp_perv0_sof_addr = 0x798,
.csid_pxl_timestamp_perv1_sof_addr = 0x79c,
.csid_pxl_timestamp_curr0_eof_addr = 0x7a0,
.csid_pxl_timestamp_curr1_eof_addr = 0x7a4,
.csid_pxl_timestamp_perv0_eof_addr = 0x7a8,
.csid_pxl_timestamp_perv1_eof_addr = 0x7ac,
/* configurations */
.pix_store_en_shift_val = 7,
.early_eof_en_shift_val = 29,
.ccif_violation_en = 1,
};
static struct ais_ife_csid_rdi_reg_offset
ais_ife_csid_175_200_rdi_0_reg_offset = {
.csid_rdi_irq_status_addr = 0x40,
.csid_rdi_irq_mask_addr = 0x44,
.csid_rdi_irq_clear_addr = 0x48,
.csid_rdi_irq_set_addr = 0x4c,
.csid_rdi_cfg0_addr = 0x300,
.csid_rdi_cfg1_addr = 0x304,
.csid_rdi_ctrl_addr = 0x308,
.csid_rdi_frm_drop_pattern_addr = 0x30c,
.csid_rdi_frm_drop_period_addr = 0x310,
.csid_rdi_irq_subsample_pattern_addr = 0x314,
.csid_rdi_irq_subsample_period_addr = 0x318,
.csid_rdi_rpp_hcrop_addr = 0x31c,
.csid_rdi_rpp_vcrop_addr = 0x320,
.csid_rdi_rpp_pix_drop_pattern_addr = 0x324,
.csid_rdi_rpp_pix_drop_period_addr = 0x328,
.csid_rdi_rpp_line_drop_pattern_addr = 0x32c,
.csid_rdi_rpp_line_drop_period_addr = 0x330,
.csid_rdi_rst_strobes_addr = 0x340,
.csid_rdi_status_addr = 0x350,
.csid_rdi_misr_val0_addr = 0x354,
.csid_rdi_misr_val1_addr = 0x358,
.csid_rdi_misr_val2_addr = 0x35c,
.csid_rdi_misr_val3_addr = 0x360,
.csid_rdi_format_measure_cfg0_addr = 0x370,
.csid_rdi_format_measure_cfg1_addr = 0x374,
.csid_rdi_format_measure0_addr = 0x378,
.csid_rdi_format_measure1_addr = 0x37c,
.csid_rdi_format_measure2_addr = 0x380,
.csid_rdi_timestamp_curr0_sof_addr = 0x390,
.csid_rdi_timestamp_curr1_sof_addr = 0x394,
.csid_rdi_timestamp_prev0_sof_addr = 0x398,
.csid_rdi_timestamp_prev1_sof_addr = 0x39c,
.csid_rdi_timestamp_curr0_eof_addr = 0x3a0,
.csid_rdi_timestamp_curr1_eof_addr = 0x3a4,
.csid_rdi_timestamp_prev0_eof_addr = 0x3a8,
.csid_rdi_timestamp_prev1_eof_addr = 0x3ac,
.csid_rdi_byte_cntr_ping_addr = 0x3e0,
.csid_rdi_byte_cntr_pong_addr = 0x3e4,
.ccif_violation_en = 1,
};
static struct ais_ife_csid_rdi_reg_offset
ais_ife_csid_175_200_rdi_1_reg_offset = {
.csid_rdi_irq_status_addr = 0x50,
.csid_rdi_irq_mask_addr = 0x54,
.csid_rdi_irq_clear_addr = 0x58,
.csid_rdi_irq_set_addr = 0x5c,
.csid_rdi_cfg0_addr = 0x400,
.csid_rdi_cfg1_addr = 0x404,
.csid_rdi_ctrl_addr = 0x408,
.csid_rdi_frm_drop_pattern_addr = 0x40c,
.csid_rdi_frm_drop_period_addr = 0x410,
.csid_rdi_irq_subsample_pattern_addr = 0x414,
.csid_rdi_irq_subsample_period_addr = 0x418,
.csid_rdi_rpp_hcrop_addr = 0x41c,
.csid_rdi_rpp_vcrop_addr = 0x420,
.csid_rdi_rpp_pix_drop_pattern_addr = 0x424,
.csid_rdi_rpp_pix_drop_period_addr = 0x428,
.csid_rdi_rpp_line_drop_pattern_addr = 0x42c,
.csid_rdi_rpp_line_drop_period_addr = 0x430,
.csid_rdi_rst_strobes_addr = 0x440,
.csid_rdi_status_addr = 0x450,
.csid_rdi_misr_val0_addr = 0x454,
.csid_rdi_misr_val1_addr = 0x458,
.csid_rdi_misr_val2_addr = 0x45c,
.csid_rdi_misr_val3_addr = 0x460,
.csid_rdi_format_measure_cfg0_addr = 0x470,
.csid_rdi_format_measure_cfg1_addr = 0x474,
.csid_rdi_format_measure0_addr = 0x478,
.csid_rdi_format_measure1_addr = 0x47c,
.csid_rdi_format_measure2_addr = 0x480,
.csid_rdi_timestamp_curr0_sof_addr = 0x490,
.csid_rdi_timestamp_curr1_sof_addr = 0x494,
.csid_rdi_timestamp_prev0_sof_addr = 0x498,
.csid_rdi_timestamp_prev1_sof_addr = 0x49c,
.csid_rdi_timestamp_curr0_eof_addr = 0x4a0,
.csid_rdi_timestamp_curr1_eof_addr = 0x4a4,
.csid_rdi_timestamp_prev0_eof_addr = 0x4a8,
.csid_rdi_timestamp_prev1_eof_addr = 0x4ac,
.csid_rdi_byte_cntr_ping_addr = 0x4e0,
.csid_rdi_byte_cntr_pong_addr = 0x4e4,
.ccif_violation_en = 1,
};
static struct ais_ife_csid_rdi_reg_offset
ais_ife_csid_175_200_rdi_2_reg_offset = {
.csid_rdi_irq_status_addr = 0x60,
.csid_rdi_irq_mask_addr = 0x64,
.csid_rdi_irq_clear_addr = 0x68,
.csid_rdi_irq_set_addr = 0x6c,
.csid_rdi_cfg0_addr = 0x500,
.csid_rdi_cfg1_addr = 0x504,
.csid_rdi_ctrl_addr = 0x508,
.csid_rdi_frm_drop_pattern_addr = 0x50c,
.csid_rdi_frm_drop_period_addr = 0x510,
.csid_rdi_irq_subsample_pattern_addr = 0x514,
.csid_rdi_irq_subsample_period_addr = 0x518,
.csid_rdi_rpp_hcrop_addr = 0x51c,
.csid_rdi_rpp_vcrop_addr = 0x520,
.csid_rdi_rpp_pix_drop_pattern_addr = 0x524,
.csid_rdi_rpp_pix_drop_period_addr = 0x528,
.csid_rdi_rpp_line_drop_pattern_addr = 0x52c,
.csid_rdi_rpp_line_drop_period_addr = 0x530,
.csid_rdi_yuv_chroma_conversion_addr = 0x534,
.csid_rdi_rst_strobes_addr = 0x540,
.csid_rdi_status_addr = 0x550,
.csid_rdi_misr_val0_addr = 0x554,
.csid_rdi_misr_val1_addr = 0x558,
.csid_rdi_misr_val2_addr = 0x55c,
.csid_rdi_misr_val3_addr = 0x560,
.csid_rdi_format_measure_cfg0_addr = 0x570,
.csid_rdi_format_measure_cfg1_addr = 0x574,
.csid_rdi_format_measure0_addr = 0x578,
.csid_rdi_format_measure1_addr = 0x57c,
.csid_rdi_format_measure2_addr = 0x580,
.csid_rdi_timestamp_curr0_sof_addr = 0x590,
.csid_rdi_timestamp_curr1_sof_addr = 0x594,
.csid_rdi_timestamp_prev0_sof_addr = 0x598,
.csid_rdi_timestamp_prev1_sof_addr = 0x59c,
.csid_rdi_timestamp_curr0_eof_addr = 0x5a0,
.csid_rdi_timestamp_curr1_eof_addr = 0x5a4,
.csid_rdi_timestamp_prev0_eof_addr = 0x5a8,
.csid_rdi_timestamp_prev1_eof_addr = 0x5ac,
.csid_rdi_byte_cntr_ping_addr = 0x5e0,
.csid_rdi_byte_cntr_pong_addr = 0x5e4,
.ccif_violation_en = 1,
};
static struct ais_ife_csid_csi2_rx_reg_offset
ais_ife_csid_175_200_csi2_reg_offset = {
.csid_csi2_rx_irq_status_addr = 0x20,
.csid_csi2_rx_irq_mask_addr = 0x24,
.csid_csi2_rx_irq_clear_addr = 0x28,
.csid_csi2_rx_irq_set_addr = 0x2c,
/*CSI2 rx control */
.csid_csi2_rx_cfg0_addr = 0x100,
.csid_csi2_rx_cfg1_addr = 0x104,
.csid_csi2_rx_capture_ctrl_addr = 0x108,
.csid_csi2_rx_rst_strobes_addr = 0x110,
.csid_csi2_rx_cap_unmap_long_pkt_hdr_0_addr = 0x120,
.csid_csi2_rx_cap_unmap_long_pkt_hdr_1_addr = 0x124,
.csid_csi2_rx_captured_short_pkt_0_addr = 0x128,
.csid_csi2_rx_captured_short_pkt_1_addr = 0x12c,
.csid_csi2_rx_captured_long_pkt_0_addr = 0x130,
.csid_csi2_rx_captured_long_pkt_1_addr = 0x134,
.csid_csi2_rx_captured_long_pkt_ftr_addr = 0x138,
.csid_csi2_rx_captured_cphy_pkt_hdr_addr = 0x13c,
.csid_csi2_rx_lane0_misr_addr = 0x150,
.csid_csi2_rx_lane1_misr_addr = 0x154,
.csid_csi2_rx_lane2_misr_addr = 0x158,
.csid_csi2_rx_lane3_misr_addr = 0x15c,
.csid_csi2_rx_total_pkts_rcvd_addr = 0x160,
.csid_csi2_rx_stats_ecc_addr = 0x164,
.csid_csi2_rx_total_crc_err_addr = 0x168,
.csid_csi2_rx_de_scramble_type3_cfg0_addr = 0x170,
.csid_csi2_rx_de_scramble_type3_cfg1_addr = 0x174,
.csid_csi2_rx_de_scramble_type2_cfg0_addr = 0x178,
.csid_csi2_rx_de_scramble_type2_cfg1_addr = 0x17c,
.csid_csi2_rx_de_scramble_type1_cfg0_addr = 0x180,
.csid_csi2_rx_de_scramble_type1_cfg1_addr = 0x184,
.csid_csi2_rx_de_scramble_type0_cfg0_addr = 0x188,
.csid_csi2_rx_de_scramble_type0_cfg1_addr = 0x18c,
.csi2_rst_srb_all = 0x3FFF,
.csi2_rst_done_shift_val = 27,
.csi2_irq_mask_all = 0xFFFFFFF,
.csi2_misr_enable_shift_val = 6,
.csi2_vc_mode_shift_val = 2,
.csi2_capture_long_pkt_en_shift = 0,
.csi2_capture_short_pkt_en_shift = 1,
.csi2_capture_cphy_pkt_en_shift = 2,
.csi2_capture_long_pkt_dt_shift = 4,
.csi2_capture_long_pkt_vc_shift = 10,
.csi2_capture_short_pkt_vc_shift = 15,
.csi2_capture_cphy_pkt_dt_shift = 20,
.csi2_capture_cphy_pkt_vc_shift = 26,
.csi2_rx_phy_num_mask = 0x7,
};
static struct ais_ife_csid_csi2_tpg_reg_offset
ais_ife_csid_175_200_tpg_reg_offset = {
/*CSID TPG control */
.csid_tpg_ctrl_addr = 0x600,
.csid_tpg_vc_cfg0_addr = 0x604,
.csid_tpg_vc_cfg1_addr = 0x608,
.csid_tpg_lfsr_seed_addr = 0x60c,
.csid_tpg_dt_n_cfg_0_addr = 0x610,
.csid_tpg_dt_n_cfg_1_addr = 0x614,
.csid_tpg_dt_n_cfg_2_addr = 0x618,
.csid_tpg_color_bars_cfg_addr = 0x640,
.csid_tpg_color_box_cfg_addr = 0x644,
.csid_tpg_common_gen_cfg_addr = 0x648,
.csid_tpg_cgen_n_cfg_addr = 0x650,
.csid_tpg_cgen_n_x0_addr = 0x654,
.csid_tpg_cgen_n_x1_addr = 0x658,
.csid_tpg_cgen_n_x2_addr = 0x65c,
.csid_tpg_cgen_n_xy_addr = 0x660,
.csid_tpg_cgen_n_y1_addr = 0x664,
.csid_tpg_cgen_n_y2_addr = 0x668,
/* configurations */
.tpg_dtn_cfg_offset = 0xc,
.tpg_cgen_cfg_offset = 0x20,
.tpg_cpas_ife_reg_offset = 0x28,
};
static struct ais_ife_csid_common_reg_offset
ais_ife_csid_175_200_cmn_reg_offset = {
.csid_hw_version_addr = 0x0,
.csid_cfg0_addr = 0x4,
.csid_ctrl_addr = 0x8,
.csid_reset_addr = 0xc,
.csid_rst_strobes_addr = 0x10,
.csid_test_bus_ctrl_addr = 0x14,
.csid_top_irq_status_addr = 0x70,
.csid_top_irq_mask_addr = 0x74,
.csid_top_irq_clear_addr = 0x78,
.csid_top_irq_set_addr = 0x7c,
.csid_irq_cmd_addr = 0x80,
/*configurations */
.major_version = 1,
.minor_version = 7,
.version_incr = 5,
.num_rdis = 3,
.num_pix = 1,
.num_ppp = 1,
.csid_reg_rst_stb = 1,
.csid_rst_stb = 0x1e,
.csid_rst_stb_sw_all = 0x1f,
.path_rst_stb_all = 0x7f,
.path_rst_done_shift_val = 1,
.path_en_shift_val = 31,
.dt_id_shift_val = 27,
.vc_shift_val = 22,
.dt_shift_val = 16,
.fmt_shift_val = 12,
.plain_fmt_shit_val = 10,
.crop_v_en_shift_val = 6,
.crop_h_en_shift_val = 5,
.crop_shift = 16,
.ipp_irq_mask_all = 0xFFFF,
.rdi_irq_mask_all = 0xFFFF,
.ppp_irq_mask_all = 0xFFFF,
.measure_en_hbi_vbi_cnt_mask = 0xC,
.format_measure_en_val = 1,
.format_measure_height_mask_val = 0xFFFF,
.format_measure_height_shift_val = 0x10,
.format_measure_width_mask_val = 0xFFFF,
.format_measure_width_shift_val = 0x0,
};
static struct ais_ife_csid_reg_offset ais_ife_csid_175_200_reg_offset = {
.cmn_reg = &ais_ife_csid_175_200_cmn_reg_offset,
.csi2_reg = &ais_ife_csid_175_200_csi2_reg_offset,
.ipp_reg = &ais_ife_csid_175_200_ipp_reg_offset,
.ppp_reg = &ais_ife_csid_175_200_ppp_reg_offset,
.rdi_reg = {
&ais_ife_csid_175_200_rdi_0_reg_offset,
&ais_ife_csid_175_200_rdi_1_reg_offset,
&ais_ife_csid_175_200_rdi_2_reg_offset,
NULL,
},
.tpg_reg = &ais_ife_csid_175_200_tpg_reg_offset,
};
#endif /*_AIS_IFE_CSID_175_200_H_ */

View File

@@ -0,0 +1,82 @@
/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include "ais_ife_csid_core.h"
#include "ais_ife_csid170.h"
#include "ais_ife_csid175.h"
#include "ais_ife_csid175_200.h"
#include "ais_ife_csid_dev.h"
#define AIS_CSID_DRV_NAME "ais-csid_17x"
#define AIS_CSID_VERSION_V170 0x10070000
#define AIS_CSID_VERSION_V175 0x10070050
static struct ais_ife_csid_hw_info ais_ife_csid170_hw_info = {
.csid_reg = &ais_ife_csid_170_reg_offset,
.hw_dts_version = AIS_CSID_VERSION_V170,
};
static struct ais_ife_csid_hw_info ais_ife_csid175_hw_info = {
.csid_reg = &ais_ife_csid_175_reg_offset,
.hw_dts_version = AIS_CSID_VERSION_V175,
};
static struct ais_ife_csid_hw_info ais_ife_csid175_200_hw_info = {
.csid_reg = &ais_ife_csid_175_200_reg_offset,
.hw_dts_version = AIS_CSID_VERSION_V175,
};
static const struct of_device_id ais_ife_csid17x_dt_match[] = {
{
.compatible = "qcom,ais-csid170",
.data = &ais_ife_csid170_hw_info,
},
{
.compatible = "qcom,ais-csid175",
.data = &ais_ife_csid175_hw_info,
},
{
.compatible = "qcom,ais-csid175_200",
.data = &ais_ife_csid175_200_hw_info,
},
{}
};
MODULE_DEVICE_TABLE(of, ais_ife_csid17x_dt_match);
static struct platform_driver ais_ife_csid17x_driver = {
.probe = ais_ife_csid_probe,
.remove = ais_ife_csid_remove,
.driver = {
.name = AIS_CSID_DRV_NAME,
.owner = THIS_MODULE,
.of_match_table = ais_ife_csid17x_dt_match,
.suppress_bind_attrs = true,
},
};
static int __init ais_ife_csid17x_init_module(void)
{
return platform_driver_register(&ais_ife_csid17x_driver);
}
static void __exit ais_ife_csid17x_exit_module(void)
{
platform_driver_unregister(&ais_ife_csid17x_driver);
}
module_init(ais_ife_csid17x_init_module);
module_exit(ais_ife_csid17x_exit_module);
MODULE_DESCRIPTION("AIS IFE_CSID17X driver");
MODULE_LICENSE("GPL v2");

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,591 @@
/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_IFE_CSID_HW_H_
#define _AIS_IFE_CSID_HW_H_
#include "cam_hw.h"
#include "ais_ife_csid_hw_intf.h"
#include "ais_ife_csid_soc.h"
#define AIS_IFE_CSID_HW_RES_MAX 8
#define AIS_IFE_CSID_CID_RES_MAX 4
#define AIS_IFE_CSID_RDI_MAX 4
#define AIS_CSID_WORKQ_NUM_TASK 10
#define CSID_CSI2_RX_INFO_PHY_DL0_EOT_CAPTURED BIT(0)
#define CSID_CSI2_RX_INFO_PHY_DL1_EOT_CAPTURED BIT(1)
#define CSID_CSI2_RX_INFO_PHY_DL2_EOT_CAPTURED BIT(2)
#define CSID_CSI2_RX_INFO_PHY_DL3_EOT_CAPTURED BIT(3)
#define CSID_CSI2_RX_INFO_PHY_DL0_SOT_CAPTURED BIT(4)
#define CSID_CSI2_RX_INFO_PHY_DL1_SOT_CAPTURED BIT(5)
#define CSID_CSI2_RX_INFO_PHY_DL2_SOT_CAPTURED BIT(6)
#define CSID_CSI2_RX_INFO_PHY_DL3_SOT_CAPTURED BIT(7)
#define CSID_CSI2_RX_INFO_LONG_PKT_CAPTURED BIT(8)
#define CSID_CSI2_RX_INFO_SHORT_PKT_CAPTURED BIT(9)
#define CSID_CSI2_RX_INFO_CPHY_PKT_HDR_CAPTURED BIT(10)
#define CSID_CSI2_RX_ERROR_CPHY_EOT_RECEPTION BIT(11)
#define CSID_CSI2_RX_ERROR_CPHY_SOT_RECEPTION BIT(12)
#define CSID_CSI2_RX_ERROR_CPHY_PH_CRC BIT(13)
#define CSID_CSI2_RX_WARNING_ECC BIT(14)
#define CSID_CSI2_RX_ERROR_LANE0_FIFO_OVERFLOW BIT(15)
#define CSID_CSI2_RX_ERROR_LANE1_FIFO_OVERFLOW BIT(16)
#define CSID_CSI2_RX_ERROR_LANE2_FIFO_OVERFLOW BIT(17)
#define CSID_CSI2_RX_ERROR_LANE3_FIFO_OVERFLOW BIT(18)
#define CSID_CSI2_RX_ERROR_CRC BIT(19)
#define CSID_CSI2_RX_ERROR_ECC BIT(20)
#define CSID_CSI2_RX_ERROR_MMAPPED_VC_DT BIT(21)
#define CSID_CSI2_RX_ERROR_UNMAPPED_VC_DT BIT(22)
#define CSID_CSI2_RX_ERROR_STREAM_UNDERFLOW BIT(23)
#define CSID_CSI2_RX_ERROR_UNBOUNDED_FRAME BIT(24)
#define CSID_CSI2_RX_INFO_TG_DONE BIT(25)
#define CSID_CSI2_RX_ERROR_TG_FIFO_OVERFLOW BIT(26)
#define CSID_CSI2_RX_INFO_RST_DONE BIT(27)
#define CSID_PATH_INFO_RST_DONE BIT(1)
#define CSID_PATH_ERROR_FIFO_OVERFLOW BIT(2)
#define CSID_PATH_INFO_SUBSAMPLED_EOF BIT(3)
#define CSID_PATH_INFO_SUBSAMPLED_SOF BIT(4)
#define CSID_PATH_INFO_FRAME_DROP_EOF BIT(5)
#define CSID_PATH_INFO_FRAME_DROP_EOL BIT(6)
#define CSID_PATH_INFO_FRAME_DROP_SOL BIT(7)
#define CSID_PATH_INFO_FRAME_DROP_SOF BIT(8)
#define CSID_PATH_INFO_INPUT_EOF BIT(9)
#define CSID_PATH_INFO_INPUT_EOL BIT(10)
#define CSID_PATH_INFO_INPUT_SOL BIT(11)
#define CSID_PATH_INFO_INPUT_SOF BIT(12)
#define CSID_PATH_ERROR_PIX_COUNT BIT(13)
#define CSID_PATH_ERROR_LINE_COUNT BIT(14)
#define CSID_PATH_ERROR_CCIF_VIOLATION BIT(15)
/*
* Debug values enable the corresponding interrupts and debug logs provide
* necessary information
*/
#define CSID_DEBUG_ENABLE_SOF_IRQ BIT(0)
#define CSID_DEBUG_ENABLE_EOF_IRQ BIT(1)
#define CSID_DEBUG_ENABLE_SOT_IRQ BIT(2)
#define CSID_DEBUG_ENABLE_EOT_IRQ BIT(3)
#define CSID_DEBUG_ENABLE_SHORT_PKT_CAPTURE BIT(4)
#define CSID_DEBUG_ENABLE_LONG_PKT_CAPTURE BIT(5)
#define CSID_DEBUG_ENABLE_CPHY_PKT_CAPTURE BIT(6)
#define CSID_DEBUG_ENABLE_HBI_VBI_INFO BIT(7)
#define CSID_DEBUG_DISABLE_EARLY_EOF BIT(8)
/* enum ais_csid_path_halt_mode select the path halt mode control */
enum ais_csid_path_halt_mode {
CSID_HALT_MODE_INTERNAL,
CSID_HALT_MODE_GLOBAL,
CSID_HALT_MODE_MASTER,
CSID_HALT_MODE_SLAVE,
};
/**
*enum ais_csid_path_timestamp_stb_sel - select the sof/eof strobes used to
* capture the timestamp
*/
enum ais_csid_path_timestamp_stb_sel {
CSID_TIMESTAMP_STB_PRE_HALT,
CSID_TIMESTAMP_STB_POST_HALT,
CSID_TIMESTAMP_STB_POST_IRQ,
CSID_TIMESTAMP_STB_MAX,
};
/**
*enum ais_csid_irq_status - csid irq status to keep track
* various status registers
*/
enum ais_csid_irq_status {
CSID_IRQ_STATUS_TOP,
CSID_IRQ_STATUS_RX,
CSID_IRQ_STATUS_IPP,
CSID_IRQ_STATUS_PPP,
CSID_IRQ_STATUS_RDI0,
CSID_IRQ_STATUS_RDI1,
CSID_IRQ_STATUS_RDI2,
CSID_IRQ_STATUS_RDI3,
CSID_IRQ_STATUS_MAX,
};
struct ais_ife_csid_pxl_reg_offset {
/* Pxl path register offsets*/
uint32_t csid_pxl_irq_status_addr;
uint32_t csid_pxl_irq_mask_addr;
uint32_t csid_pxl_irq_clear_addr;
uint32_t csid_pxl_irq_set_addr;
uint32_t csid_pxl_cfg0_addr;
uint32_t csid_pxl_cfg1_addr;
uint32_t csid_pxl_ctrl_addr;
uint32_t csid_pxl_frm_drop_pattern_addr;
uint32_t csid_pxl_frm_drop_period_addr;
uint32_t csid_pxl_irq_subsample_pattern_addr;
uint32_t csid_pxl_irq_subsample_period_addr;
uint32_t csid_pxl_hcrop_addr;
uint32_t csid_pxl_vcrop_addr;
uint32_t csid_pxl_pix_drop_pattern_addr;
uint32_t csid_pxl_pix_drop_period_addr;
uint32_t csid_pxl_line_drop_pattern_addr;
uint32_t csid_pxl_line_drop_period_addr;
uint32_t csid_pxl_rst_strobes_addr;
uint32_t csid_pxl_status_addr;
uint32_t csid_pxl_misr_val_addr;
uint32_t csid_pxl_format_measure_cfg0_addr;
uint32_t csid_pxl_format_measure_cfg1_addr;
uint32_t csid_pxl_format_measure0_addr;
uint32_t csid_pxl_format_measure1_addr;
uint32_t csid_pxl_format_measure2_addr;
uint32_t csid_pxl_timestamp_curr0_sof_addr;
uint32_t csid_pxl_timestamp_curr1_sof_addr;
uint32_t csid_pxl_timestamp_perv0_sof_addr;
uint32_t csid_pxl_timestamp_perv1_sof_addr;
uint32_t csid_pxl_timestamp_curr0_eof_addr;
uint32_t csid_pxl_timestamp_curr1_eof_addr;
uint32_t csid_pxl_timestamp_perv0_eof_addr;
uint32_t csid_pxl_timestamp_perv1_eof_addr;
/* configuration */
uint32_t pix_store_en_shift_val;
uint32_t early_eof_en_shift_val;
uint32_t quad_cfa_bin_en_shift_val;
uint32_t ccif_violation_en;
};
struct ais_ife_csid_rdi_reg_offset {
uint32_t csid_rdi_irq_status_addr;
uint32_t csid_rdi_irq_mask_addr;
uint32_t csid_rdi_irq_clear_addr;
uint32_t csid_rdi_irq_set_addr;
/*RDI N register address */
uint32_t csid_rdi_cfg0_addr;
uint32_t csid_rdi_cfg1_addr;
uint32_t csid_rdi_ctrl_addr;
uint32_t csid_rdi_frm_drop_pattern_addr;
uint32_t csid_rdi_frm_drop_period_addr;
uint32_t csid_rdi_irq_subsample_pattern_addr;
uint32_t csid_rdi_irq_subsample_period_addr;
uint32_t csid_rdi_rpp_hcrop_addr;
uint32_t csid_rdi_rpp_vcrop_addr;
uint32_t csid_rdi_rpp_pix_drop_pattern_addr;
uint32_t csid_rdi_rpp_pix_drop_period_addr;
uint32_t csid_rdi_rpp_line_drop_pattern_addr;
uint32_t csid_rdi_rpp_line_drop_period_addr;
uint32_t csid_rdi_yuv_chroma_conversion_addr;
uint32_t csid_rdi_rst_strobes_addr;
uint32_t csid_rdi_status_addr;
uint32_t csid_rdi_misr_val0_addr;
uint32_t csid_rdi_misr_val1_addr;
uint32_t csid_rdi_misr_val2_addr;
uint32_t csid_rdi_misr_val3_addr;
uint32_t csid_rdi_format_measure_cfg0_addr;
uint32_t csid_rdi_format_measure_cfg1_addr;
uint32_t csid_rdi_format_measure0_addr;
uint32_t csid_rdi_format_measure1_addr;
uint32_t csid_rdi_format_measure2_addr;
uint32_t csid_rdi_timestamp_curr0_sof_addr;
uint32_t csid_rdi_timestamp_curr1_sof_addr;
uint32_t csid_rdi_timestamp_prev0_sof_addr;
uint32_t csid_rdi_timestamp_prev1_sof_addr;
uint32_t csid_rdi_timestamp_curr0_eof_addr;
uint32_t csid_rdi_timestamp_curr1_eof_addr;
uint32_t csid_rdi_timestamp_prev0_eof_addr;
uint32_t csid_rdi_timestamp_prev1_eof_addr;
uint32_t csid_rdi_byte_cntr_ping_addr;
uint32_t csid_rdi_byte_cntr_pong_addr;
/* configuration */
uint32_t packing_format;
uint32_t ccif_violation_en;
};
struct ais_ife_csid_csi2_rx_reg_offset {
uint32_t csid_csi2_rx_irq_status_addr;
uint32_t csid_csi2_rx_irq_mask_addr;
uint32_t csid_csi2_rx_irq_clear_addr;
uint32_t csid_csi2_rx_irq_set_addr;
uint32_t csid_csi2_rx_cfg0_addr;
uint32_t csid_csi2_rx_cfg1_addr;
uint32_t csid_csi2_rx_capture_ctrl_addr;
uint32_t csid_csi2_rx_rst_strobes_addr;
uint32_t csid_csi2_rx_de_scramble_cfg0_addr;
uint32_t csid_csi2_rx_de_scramble_cfg1_addr;
uint32_t csid_csi2_rx_cap_unmap_long_pkt_hdr_0_addr;
uint32_t csid_csi2_rx_cap_unmap_long_pkt_hdr_1_addr;
uint32_t csid_csi2_rx_captured_short_pkt_0_addr;
uint32_t csid_csi2_rx_captured_short_pkt_1_addr;
uint32_t csid_csi2_rx_captured_long_pkt_0_addr;
uint32_t csid_csi2_rx_captured_long_pkt_1_addr;
uint32_t csid_csi2_rx_captured_long_pkt_ftr_addr;
uint32_t csid_csi2_rx_captured_cphy_pkt_hdr_addr;
uint32_t csid_csi2_rx_lane0_misr_addr;
uint32_t csid_csi2_rx_lane1_misr_addr;
uint32_t csid_csi2_rx_lane2_misr_addr;
uint32_t csid_csi2_rx_lane3_misr_addr;
uint32_t csid_csi2_rx_total_pkts_rcvd_addr;
uint32_t csid_csi2_rx_stats_ecc_addr;
uint32_t csid_csi2_rx_total_crc_err_addr;
uint32_t csid_csi2_rx_de_scramble_type3_cfg0_addr;
uint32_t csid_csi2_rx_de_scramble_type3_cfg1_addr;
uint32_t csid_csi2_rx_de_scramble_type2_cfg0_addr;
uint32_t csid_csi2_rx_de_scramble_type2_cfg1_addr;
uint32_t csid_csi2_rx_de_scramble_type1_cfg0_addr;
uint32_t csid_csi2_rx_de_scramble_type1_cfg1_addr;
uint32_t csid_csi2_rx_de_scramble_type0_cfg0_addr;
uint32_t csid_csi2_rx_de_scramble_type0_cfg1_addr;
/*configurations */
uint32_t csi2_rst_srb_all;
uint32_t csi2_rst_done_shift_val;
uint32_t csi2_irq_mask_all;
uint32_t csi2_misr_enable_shift_val;
uint32_t csi2_vc_mode_shift_val;
uint32_t csi2_capture_long_pkt_en_shift;
uint32_t csi2_capture_short_pkt_en_shift;
uint32_t csi2_capture_cphy_pkt_en_shift;
uint32_t csi2_capture_long_pkt_dt_shift;
uint32_t csi2_capture_long_pkt_vc_shift;
uint32_t csi2_capture_short_pkt_vc_shift;
uint32_t csi2_capture_cphy_pkt_dt_shift;
uint32_t csi2_capture_cphy_pkt_vc_shift;
uint32_t csi2_rx_phy_num_mask;
};
struct ais_ife_csid_csi2_tpg_reg_offset {
uint32_t csid_tpg_ctrl_addr;
uint32_t csid_tpg_vc_cfg0_addr;
uint32_t csid_tpg_vc_cfg1_addr;
uint32_t csid_tpg_lfsr_seed_addr;
uint32_t csid_tpg_dt_n_cfg_0_addr;
uint32_t csid_tpg_dt_n_cfg_1_addr;
uint32_t csid_tpg_dt_n_cfg_2_addr;
uint32_t csid_tpg_color_bars_cfg_addr;
uint32_t csid_tpg_color_box_cfg_addr;
uint32_t csid_tpg_common_gen_cfg_addr;
uint32_t csid_tpg_cgen_n_cfg_addr;
uint32_t csid_tpg_cgen_n_x0_addr;
uint32_t csid_tpg_cgen_n_x1_addr;
uint32_t csid_tpg_cgen_n_x2_addr;
uint32_t csid_tpg_cgen_n_xy_addr;
uint32_t csid_tpg_cgen_n_y1_addr;
uint32_t csid_tpg_cgen_n_y2_addr;
/*configurations */
uint32_t tpg_dtn_cfg_offset;
uint32_t tpg_cgen_cfg_offset;
uint32_t tpg_cpas_ife_reg_offset;
};
struct ais_ife_csid_common_reg_offset {
/* MIPI CSID registers */
uint32_t csid_hw_version_addr;
uint32_t csid_cfg0_addr;
uint32_t csid_ctrl_addr;
uint32_t csid_reset_addr;
uint32_t csid_rst_strobes_addr;
uint32_t csid_test_bus_ctrl_addr;
uint32_t csid_top_irq_status_addr;
uint32_t csid_top_irq_mask_addr;
uint32_t csid_top_irq_clear_addr;
uint32_t csid_top_irq_set_addr;
uint32_t csid_irq_cmd_addr;
/*configurations */
uint32_t major_version;
uint32_t minor_version;
uint32_t version_incr;
uint32_t num_rdis;
uint32_t num_pix;
uint32_t num_ppp;
uint32_t csid_reg_rst_stb;
uint32_t csid_rst_stb;
uint32_t csid_rst_stb_sw_all;
uint32_t path_rst_stb_all;
uint32_t path_rst_done_shift_val;
uint32_t path_en_shift_val;
uint32_t dt_id_shift_val;
uint32_t vc_shift_val;
uint32_t dt_shift_val;
uint32_t fmt_shift_val;
uint32_t plain_fmt_shit_val;
uint32_t crop_v_en_shift_val;
uint32_t crop_h_en_shift_val;
uint32_t crop_shift;
uint32_t ipp_irq_mask_all;
uint32_t rdi_irq_mask_all;
uint32_t ppp_irq_mask_all;
uint32_t measure_en_hbi_vbi_cnt_mask;
uint32_t format_measure_en_val;
uint32_t format_measure_width_shift_val;
uint32_t format_measure_width_mask_val;
uint32_t format_measure_height_shift_val;
uint32_t format_measure_height_mask_val;
};
/**
* struct ais_ife_csid_reg_offset- CSID instance register info
*
* @cmn_reg: csid common registers info
* @ipp_reg: ipp register offset information
* @ppp_reg: ppp register offset information
* @rdi_reg: rdi register offser information
*
*/
struct ais_ife_csid_reg_offset {
const struct ais_ife_csid_common_reg_offset *cmn_reg;
const struct ais_ife_csid_csi2_rx_reg_offset *csi2_reg;
const struct ais_ife_csid_pxl_reg_offset *ipp_reg;
const struct ais_ife_csid_pxl_reg_offset *ppp_reg;
const struct ais_ife_csid_rdi_reg_offset *rdi_reg[AIS_IFE_CSID_RDI_MAX];
const struct ais_ife_csid_csi2_tpg_reg_offset *tpg_reg;
};
/**
* struct ais_ife_csid_hw_info- CSID HW info
*
* @csid_reg: csid register offsets
* @hw_dts_version: HW DTS version
* @csid_max_clk: maximim csid clock
*
*/
struct ais_ife_csid_hw_info {
const struct ais_ife_csid_reg_offset *csid_reg;
uint32_t hw_dts_version;
uint32_t csid_max_clk;
};
/**
* struct ais_ife_csid_csi2_rx_cfg- csid csi2 rx configuration data
* @phy_sel: input resource type for sensor only
* @lane_type: lane type: c-phy or d-phy
* @lane_num : active lane number
* @lane_cfg: lane configurations: 4 bits per lane
*
*/
struct ais_ife_csid_csi2_rx_cfg {
uint32_t phy_sel;
uint32_t lane_type;
uint32_t lane_num;
uint32_t lane_cfg;
};
/**
* struct ais_ife_csid_tpg_cfg- csid tpg configuration data
* @width: width
* @height: height
* @test_pattern : pattern
* @in_format: decode format
* @usage_type: whether dual isp is required
*
*/
struct ais_ife_csid_tpg_cfg {
uint32_t width;
uint32_t height;
uint32_t test_pattern;
uint32_t in_format;
uint32_t usage_type;
};
/**
* struct ais_ife_csid_cid_data- cid configuration private data
*
* @vc: Virtual channel
* @dt: Data type
* @cnt: Cid resource reference count.
* @tpg_set: Tpg used for this cid resource
*
*/
struct ais_ife_csid_cid_data {
uint32_t vc;
uint32_t dt;
uint32_t cnt;
uint32_t tpg_set;
};
/**
* struct ais_csid_hw_work_data- work data for csid
* Later other fields can be added to this data
* @evt_type : Event type from CSID
* @irq_status : IRQ Status register
*
*/
struct ais_csid_hw_work_data {
uint64_t timestamp;
uint32_t evt_type;
uint32_t irq_status[CSID_IRQ_STATUS_MAX];
};
/**
* struct ais_ife_csid_path_cfg- csid path configuration details. It is stored
* as private data for IPP/ RDI paths
* @vc : Virtual channel number
* @dt : Data type number
* @cid cid number, it is same as DT_ID number in HW
* @in_format: input decode format
* @out_format: output format
* @crop_enable: crop is enable or disabled, if enabled
* then remaining parameters are valid.
* @start_pixel: start pixel
* @end_pixel: end_pixel
* @width: width
* @start_line: start line
* @end_line: end_line
* @height: heigth
* @sync_mode: Applicable for IPP/RDI path reservation
* Reserving the path for master IPP or slave IPP
* master (set value 1), Slave ( set value 2)
* for RDI, set mode to none
* @master_idx: For Slave reservation, Give master IFE instance Index.
* Slave will synchronize with master Start and stop operations
* @clk_rate Clock rate
* @usage_type Usage type ie dual or single ife usecase
* @init_frame_drop init frame drop value. In dual ife case rdi need to drop one
* more frame than pix.
*
*/
struct ais_ife_csid_path_cfg {
enum ais_isp_resource_state state;
uint32_t vc;
uint32_t dt;
uint32_t cid;
uint32_t in_format;
uint32_t out_format;
bool pix_enable;
uint32_t decode_fmt;
uint32_t plain_fmt;
uint32_t in_bpp;
bool crop_enable;
uint32_t start_pixel;
uint32_t end_pixel;
uint32_t width;
uint32_t start_line;
uint32_t end_line;
uint32_t height;
struct cam_isp_sensor_dimension measure_cfg;
uint32_t master_idx;
uint64_t clk_rate;
uint32_t usage_type;
uint32_t init_frame_drop;
uint32_t sof_cnt;
uint32_t prev_sof_hw_ts;
uint32_t prev_sof_boot_ts;
};
/**
* struct ais_ife_csid_hw- csid hw device resources data
*
* @hw_intf: contain the csid hw interface information
* @hw_info: csid hw device information
* @csid_info: csid hw specific information
* @res_type: CSID in resource type
* @csi2_rx_cfg: Csi2 rx decoder configuration for csid
* @tpg_cfg: TPG configuration
* @csi2_rx_reserve_cnt: CSI2 reservations count value
* @csi2_cfg_cnt: csi2 configuration count
* @tpg_start_cnt: tpg start count
* @ipp_res: image pixel path resource
* @ppp_res: phase pxl path resource
* @rdi_res: raw dump image path resources
* @cid_res: cid resources state
* @csid_top_reset_complete: csid top reset completion
* @csid_csi2_reset_complete: csi2 reset completion
* @csid_ipp_reset_complete: ipp reset completion
* @csid_ppp_complete: ppp reset completion
* @csid_rdin_reset_complete: rdi n completion
* @csid_debug: csid debug information to enable the SOT, EOT,
* SOF, EOF, measure etc in the csid hw
* @clk_rate Clock rate
* @ipp_path ipp path configuration
* @ppp_path ppp path configuration
* @rdi_path RDI path configuration
* @hbi Horizontal blanking
* @vbi Vertical blanking
* @sof_irq_triggered: Flag is set on receiving event to enable sof irq
* incase of SOF freeze.
* @irq_debug_cnt: Counter to track sof irq's when above flag is set.
* @error_irq_count Error IRQ count, if continuous error irq comes
* need to stop the CSID and mask interrupts.
* @device_enabled Device enabled will set once CSID powered on and
* initial configuration are done.
* @lock_state csid spin lock
* @dual_usage usage type, dual ife or single ife
* @init_frame_drop Initial frame drop number
* @res_sof_cnt path resource sof count value. it used for initial
* frame drop
* @prev_boot_timestamp first bootime stamp at the start
* @prev_qtimer_ts stores csid timestamp
* @ppi_hw_intf interface to ppi hardware
* @ppi_enabled flag to specify if the hardware has ppi bridge
* or not
* @fatal_err_detected flag to indicate fatal errror is reported
* @ctx Hw manager context
* @work Work queue to handle CSID IRQ work
* @work_data Work data to be passed to work queue
* @event_cb Callback to hw manager if CSID event reported
*
*/
struct ais_ife_csid_hw {
struct cam_hw_intf *hw_intf;
struct cam_hw_info *hw_info;
struct ais_ife_csid_hw_info *csid_info;
enum ais_isp_resource_state state;
struct ais_ife_csid_path_cfg rdi_cfg[AIS_IFE_CSID_RDI_MAX];
bool ipp_fix_cfg;
uint32_t res_type;
struct ais_ife_csid_csi2_rx_cfg csi2_rx_cfg;
struct ais_ife_csid_tpg_cfg tpg_cfg;
uint32_t csi2_reserve_cnt;
uint32_t csi2_cfg_cnt;
uint32_t tpg_start_cnt;
struct completion csid_top_complete;
struct completion csid_csi2_complete;
struct completion csid_ipp_complete;
struct completion csid_ppp_complete;
struct completion csid_rdi_complete[AIS_IFE_CSID_RDI_MAX];
uint64_t csid_debug;
uint64_t clk_rate;
bool sof_irq_triggered;
uint32_t irq_debug_cnt;
uint32_t error_irq_count;
bool fatal_err_detected;
uint32_t device_enabled;
spinlock_t lock_state;
uint32_t dual_usage;
uint32_t init_frame_drop;
void *ctx;
struct cam_req_mgr_core_workq *work;
struct ais_csid_hw_work_data work_data[AIS_CSID_WORKQ_NUM_TASK];
ais_ife_event_cb_func event_cb;
void *event_cb_priv;
};
int ais_ife_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
uint32_t csid_idx);
int ais_ife_csid_hw_deinit(struct ais_ife_csid_hw *ife_csid_hw);
#endif /* _AIS_IFE_CSID_HW_H_ */

View File

@@ -0,0 +1,157 @@
/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/slab.h>
#include <linux/mod_devicetable.h>
#include <linux/of_device.h>
#include "ais_ife_csid_core.h"
#include "ais_ife_csid_dev.h"
#include "ais_ife_csid_hw_intf.h"
#include "cam_debug_util.h"
static struct cam_hw_intf *ais_ife_csid_hw_list[AIS_IFE_CSID_HW_RES_MAX] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
static char csid_dev_name[8];
int ais_ife_csid_probe(struct platform_device *pdev)
{
struct cam_hw_intf *csid_hw_intf;
struct cam_hw_info *csid_hw_info;
struct ais_ife_csid_hw *csid_dev = NULL;
const struct of_device_id *match_dev = NULL;
struct ais_ife_csid_hw_info *csid_hw_data = NULL;
uint32_t csid_dev_idx;
int rc = 0;
CAM_INFO(CAM_ISP, "probe called");
csid_hw_intf = kzalloc(sizeof(*csid_hw_intf), GFP_KERNEL);
if (!csid_hw_intf) {
rc = -ENOMEM;
goto err;
}
csid_hw_info = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL);
if (!csid_hw_info) {
rc = -ENOMEM;
goto free_hw_intf;
}
csid_dev = kzalloc(sizeof(struct ais_ife_csid_hw), GFP_KERNEL);
if (!csid_dev) {
rc = -ENOMEM;
goto free_hw_info;
}
/* get ife csid hw index */
of_property_read_u32(pdev->dev.of_node, "cell-index", &csid_dev_idx);
/* get ife csid hw information */
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 IFE CSID HW!");
rc = -EINVAL;
goto free_dev;
}
CAM_INFO(CAM_ISP, "CSID%d probe called", csid_dev_idx);
memset(csid_dev_name, 0, sizeof(csid_dev_name));
snprintf(csid_dev_name, sizeof(csid_dev_name),
"csid%1u", csid_dev_idx);
csid_hw_intf->hw_idx = csid_dev_idx;
csid_hw_intf->hw_type = AIS_ISP_HW_TYPE_IFE_CSID;
csid_hw_intf->hw_priv = csid_hw_info;
csid_hw_info->core_info = csid_dev;
csid_hw_info->soc_info.pdev = pdev;
csid_hw_info->soc_info.dev = &pdev->dev;
csid_hw_info->soc_info.dev_name = csid_dev_name;
csid_hw_info->soc_info.index = csid_dev_idx;
csid_hw_data = (struct ais_ife_csid_hw_info *)match_dev->data;
/* need to setup the pdev before call the ife hw probe init */
csid_dev->csid_info = csid_hw_data;
rc = ais_ife_csid_hw_probe_init(csid_hw_intf, csid_dev_idx);
if (rc)
goto free_dev;
platform_set_drvdata(pdev, csid_dev);
CAM_INFO(CAM_ISP, "CSID:%d probe successful",
csid_hw_intf->hw_idx);
if (csid_hw_intf->hw_idx < AIS_IFE_CSID_HW_RES_MAX)
ais_ife_csid_hw_list[csid_hw_intf->hw_idx] = csid_hw_intf;
else
goto free_dev;
return 0;
free_dev:
kfree(csid_dev);
free_hw_info:
kfree(csid_hw_info);
free_hw_intf:
kfree(csid_hw_intf);
err:
return rc;
}
int ais_ife_csid_remove(struct platform_device *pdev)
{
struct ais_ife_csid_hw *csid_dev = NULL;
struct cam_hw_intf *csid_hw_intf;
struct cam_hw_info *csid_hw_info;
csid_dev = (struct ais_ife_csid_hw *)platform_get_drvdata(pdev);
csid_hw_intf = csid_dev->hw_intf;
csid_hw_info = csid_dev->hw_info;
CAM_DBG(CAM_ISP, "CSID:%d remove",
csid_dev->hw_intf->hw_idx);
ais_ife_csid_hw_deinit(csid_dev);
/*release the csid device memory */
kfree(csid_dev);
kfree(csid_hw_info);
kfree(csid_hw_intf);
return 0;
}
int ais_ife_csid_hw_init(struct cam_hw_intf **ife_csid_hw,
struct ais_isp_hw_init_args *init)
{
int rc = 0;
if (ais_ife_csid_hw_list[init->hw_idx]) {
struct cam_hw_info *csid_hw_info = NULL;
struct ais_ife_csid_hw *core_info = NULL;
csid_hw_info = ais_ife_csid_hw_list[init->hw_idx]->hw_priv;
core_info = (struct ais_ife_csid_hw *)csid_hw_info->core_info;
core_info->event_cb = init->event_cb;
core_info->event_cb_priv = init->event_cb_priv;
*ife_csid_hw = ais_ife_csid_hw_list[init->hw_idx];
} else {
*ife_csid_hw = NULL;
rc = -1;
}
return rc;
}

View File

@@ -0,0 +1,23 @@
/* Copyright (c) 2017-2018, 2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_IFE_CSID_DEV_H_
#define _AIS_IFE_CSID_DEV_H_
#include "ais_isp_hw.h"
irqreturn_t ais_ife_csid_irq(int irq_num, void *data);
int ais_ife_csid_probe(struct platform_device *pdev);
int ais_ife_csid_remove(struct platform_device *pdev);
#endif /*_AIS_IFE_CSID_DEV_H_ */

View File

@@ -0,0 +1,61 @@
/* Copyright (c) 2017-2018, 2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include "ais_ife_csid_lite17x.h"
#include "ais_ife_csid_core.h"
#include "ais_ife_csid_dev.h"
#define CAM_CSID_LITE_DRV_NAME "ais-csid_lite"
static struct ais_ife_csid_hw_info ais_ife_csid_lite_hw_info = {
.csid_reg = &ais_ife_csid_lite_17x_reg_offset,
};
static const struct of_device_id ais_ife_csid_lite_dt_match[] = {
{
.compatible = "qcom,ais-csid-lite170",
.data = &ais_ife_csid_lite_hw_info,
},
{
.compatible = "qcom,ais-csid-lite175",
.data = &ais_ife_csid_lite_hw_info,
},
{}
};
MODULE_DEVICE_TABLE(of, ais_ife_csid_lite_dt_match);
static struct platform_driver ais_ife_csid_lite_driver = {
.probe = ais_ife_csid_probe,
.remove = ais_ife_csid_remove,
.driver = {
.name = CAM_CSID_LITE_DRV_NAME,
.owner = THIS_MODULE,
.of_match_table = ais_ife_csid_lite_dt_match,
.suppress_bind_attrs = true,
},
};
static int __init ais_ife_csid_lite_init_module(void)
{
return platform_driver_register(&ais_ife_csid_lite_driver);
}
static void __exit ais_ife_csid_lite_exit_module(void)
{
platform_driver_unregister(&ais_ife_csid_lite_driver);
}
module_init(ais_ife_csid_lite_init_module);
module_exit(ais_ife_csid_lite_exit_module);
MODULE_DESCRIPTION("CAM IFE_CSID_LITE driver");
MODULE_LICENSE("GPL v2");

View File

@@ -0,0 +1,322 @@
/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_IFE_CSID_LITE17X_H_
#define _AIS_IFE_CSID_LITE17X_H_
#include "ais_ife_csid_core.h"
static const struct ais_ife_csid_rdi_reg_offset
ais_ife_csid_lite_17x_rdi_0_reg_offset = {
.csid_rdi_irq_status_addr = 0x30,
.csid_rdi_irq_mask_addr = 0x34,
.csid_rdi_irq_clear_addr = 0x38,
.csid_rdi_irq_set_addr = 0x3c,
.csid_rdi_cfg0_addr = 0x200,
.csid_rdi_cfg1_addr = 0x204,
.csid_rdi_ctrl_addr = 0x208,
.csid_rdi_frm_drop_pattern_addr = 0x20c,
.csid_rdi_frm_drop_period_addr = 0x210,
.csid_rdi_irq_subsample_pattern_addr = 0x214,
.csid_rdi_irq_subsample_period_addr = 0x218,
.csid_rdi_rpp_hcrop_addr = 0x21c,
.csid_rdi_rpp_vcrop_addr = 0x220,
.csid_rdi_rpp_pix_drop_pattern_addr = 0x224,
.csid_rdi_rpp_pix_drop_period_addr = 0x228,
.csid_rdi_rpp_line_drop_pattern_addr = 0x22c,
.csid_rdi_rpp_line_drop_period_addr = 0x230,
.csid_rdi_rst_strobes_addr = 0x240,
.csid_rdi_status_addr = 0x250,
.csid_rdi_misr_val0_addr = 0x254,
.csid_rdi_misr_val1_addr = 0x258,
.csid_rdi_misr_val2_addr = 0x25c,
.csid_rdi_misr_val3_addr = 0x260,
.csid_rdi_format_measure_cfg0_addr = 0x270,
.csid_rdi_format_measure_cfg1_addr = 0x274,
.csid_rdi_format_measure0_addr = 0x278,
.csid_rdi_format_measure1_addr = 0x27c,
.csid_rdi_format_measure2_addr = 0x280,
.csid_rdi_timestamp_curr0_sof_addr = 0x290,
.csid_rdi_timestamp_curr1_sof_addr = 0x294,
.csid_rdi_timestamp_prev0_sof_addr = 0x298,
.csid_rdi_timestamp_prev1_sof_addr = 0x29c,
.csid_rdi_timestamp_curr0_eof_addr = 0x2a0,
.csid_rdi_timestamp_curr1_eof_addr = 0x2a4,
.csid_rdi_timestamp_prev0_eof_addr = 0x2a8,
.csid_rdi_timestamp_prev1_eof_addr = 0x2ac,
.csid_rdi_byte_cntr_ping_addr = 0x2e0,
.csid_rdi_byte_cntr_pong_addr = 0x2e4,
};
static const struct ais_ife_csid_rdi_reg_offset
ais_ife_csid_lite_17x_rdi_1_reg_offset = {
.csid_rdi_irq_status_addr = 0x40,
.csid_rdi_irq_mask_addr = 0x44,
.csid_rdi_irq_clear_addr = 0x48,
.csid_rdi_irq_set_addr = 0x4c,
.csid_rdi_cfg0_addr = 0x300,
.csid_rdi_cfg1_addr = 0x304,
.csid_rdi_ctrl_addr = 0x308,
.csid_rdi_frm_drop_pattern_addr = 0x30c,
.csid_rdi_frm_drop_period_addr = 0x310,
.csid_rdi_irq_subsample_pattern_addr = 0x314,
.csid_rdi_irq_subsample_period_addr = 0x318,
.csid_rdi_rpp_hcrop_addr = 0x31c,
.csid_rdi_rpp_vcrop_addr = 0x320,
.csid_rdi_rpp_pix_drop_pattern_addr = 0x324,
.csid_rdi_rpp_pix_drop_period_addr = 0x328,
.csid_rdi_rpp_line_drop_pattern_addr = 0x32c,
.csid_rdi_rpp_line_drop_period_addr = 0x330,
.csid_rdi_rst_strobes_addr = 0x340,
.csid_rdi_status_addr = 0x350,
.csid_rdi_misr_val0_addr = 0x354,
.csid_rdi_misr_val1_addr = 0x358,
.csid_rdi_misr_val2_addr = 0x35c,
.csid_rdi_misr_val3_addr = 0x360,
.csid_rdi_format_measure_cfg0_addr = 0x370,
.csid_rdi_format_measure_cfg1_addr = 0x374,
.csid_rdi_format_measure0_addr = 0x378,
.csid_rdi_format_measure1_addr = 0x37c,
.csid_rdi_format_measure2_addr = 0x380,
.csid_rdi_timestamp_curr0_sof_addr = 0x390,
.csid_rdi_timestamp_curr1_sof_addr = 0x394,
.csid_rdi_timestamp_prev0_sof_addr = 0x398,
.csid_rdi_timestamp_prev1_sof_addr = 0x39c,
.csid_rdi_timestamp_curr0_eof_addr = 0x3a0,
.csid_rdi_timestamp_curr1_eof_addr = 0x3a4,
.csid_rdi_timestamp_prev0_eof_addr = 0x3a8,
.csid_rdi_timestamp_prev1_eof_addr = 0x3ac,
.csid_rdi_byte_cntr_ping_addr = 0x3e0,
.csid_rdi_byte_cntr_pong_addr = 0x3e4,
};
static const struct ais_ife_csid_rdi_reg_offset
ais_ife_csid_lite_17x_rdi_2_reg_offset = {
.csid_rdi_irq_status_addr = 0x50,
.csid_rdi_irq_mask_addr = 0x54,
.csid_rdi_irq_clear_addr = 0x58,
.csid_rdi_irq_set_addr = 0x5c,
.csid_rdi_cfg0_addr = 0x400,
.csid_rdi_cfg1_addr = 0x404,
.csid_rdi_ctrl_addr = 0x408,
.csid_rdi_frm_drop_pattern_addr = 0x40c,
.csid_rdi_frm_drop_period_addr = 0x410,
.csid_rdi_irq_subsample_pattern_addr = 0x414,
.csid_rdi_irq_subsample_period_addr = 0x418,
.csid_rdi_rpp_hcrop_addr = 0x41c,
.csid_rdi_rpp_vcrop_addr = 0x420,
.csid_rdi_rpp_pix_drop_pattern_addr = 0x424,
.csid_rdi_rpp_pix_drop_period_addr = 0x428,
.csid_rdi_rpp_line_drop_pattern_addr = 0x42c,
.csid_rdi_rpp_line_drop_period_addr = 0x430,
.csid_rdi_yuv_chroma_conversion_addr = 0x434,
.csid_rdi_rst_strobes_addr = 0x440,
.csid_rdi_status_addr = 0x450,
.csid_rdi_misr_val0_addr = 0x454,
.csid_rdi_misr_val1_addr = 0x458,
.csid_rdi_misr_val2_addr = 0x45c,
.csid_rdi_misr_val3_addr = 0x460,
.csid_rdi_format_measure_cfg0_addr = 0x470,
.csid_rdi_format_measure_cfg1_addr = 0x474,
.csid_rdi_format_measure0_addr = 0x478,
.csid_rdi_format_measure1_addr = 0x47c,
.csid_rdi_format_measure2_addr = 0x480,
.csid_rdi_timestamp_curr0_sof_addr = 0x490,
.csid_rdi_timestamp_curr1_sof_addr = 0x494,
.csid_rdi_timestamp_prev0_sof_addr = 0x498,
.csid_rdi_timestamp_prev1_sof_addr = 0x49c,
.csid_rdi_timestamp_curr0_eof_addr = 0x4a0,
.csid_rdi_timestamp_curr1_eof_addr = 0x4a4,
.csid_rdi_timestamp_prev0_eof_addr = 0x4a8,
.csid_rdi_timestamp_prev1_eof_addr = 0x4ac,
.csid_rdi_byte_cntr_ping_addr = 0x4e0,
.csid_rdi_byte_cntr_pong_addr = 0x4e4,
};
static const struct ais_ife_csid_rdi_reg_offset
ais_ife_csid_lite_17x_rdi_3_reg_offset = {
.csid_rdi_irq_status_addr = 0x60,
.csid_rdi_irq_mask_addr = 0x64,
.csid_rdi_irq_clear_addr = 0x68,
.csid_rdi_irq_set_addr = 0x6c,
.csid_rdi_cfg0_addr = 0x500,
.csid_rdi_cfg1_addr = 0x504,
.csid_rdi_ctrl_addr = 0x508,
.csid_rdi_frm_drop_pattern_addr = 0x50c,
.csid_rdi_frm_drop_period_addr = 0x510,
.csid_rdi_irq_subsample_pattern_addr = 0x514,
.csid_rdi_irq_subsample_period_addr = 0x518,
.csid_rdi_rpp_hcrop_addr = 0x51c,
.csid_rdi_rpp_vcrop_addr = 0x520,
.csid_rdi_rpp_pix_drop_pattern_addr = 0x524,
.csid_rdi_rpp_pix_drop_period_addr = 0x528,
.csid_rdi_rpp_line_drop_pattern_addr = 0x52c,
.csid_rdi_rpp_line_drop_period_addr = 0x530,
.csid_rdi_yuv_chroma_conversion_addr = 0x534,
.csid_rdi_rst_strobes_addr = 0x540,
.csid_rdi_status_addr = 0x550,
.csid_rdi_misr_val0_addr = 0x554,
.csid_rdi_misr_val1_addr = 0x558,
.csid_rdi_misr_val2_addr = 0x55c,
.csid_rdi_misr_val3_addr = 0x560,
.csid_rdi_format_measure_cfg0_addr = 0x570,
.csid_rdi_format_measure_cfg1_addr = 0x574,
.csid_rdi_format_measure0_addr = 0x578,
.csid_rdi_format_measure1_addr = 0x57c,
.csid_rdi_format_measure2_addr = 0x580,
.csid_rdi_timestamp_curr0_sof_addr = 0x590,
.csid_rdi_timestamp_curr1_sof_addr = 0x594,
.csid_rdi_timestamp_prev0_sof_addr = 0x598,
.csid_rdi_timestamp_prev1_sof_addr = 0x59c,
.csid_rdi_timestamp_curr0_eof_addr = 0x5a0,
.csid_rdi_timestamp_curr1_eof_addr = 0x5a4,
.csid_rdi_timestamp_prev0_eof_addr = 0x5a8,
.csid_rdi_timestamp_prev1_eof_addr = 0x5ac,
.csid_rdi_byte_cntr_ping_addr = 0x5e0,
.csid_rdi_byte_cntr_pong_addr = 0x5e4,
};
static const struct ais_ife_csid_csi2_rx_reg_offset
ais_ife_csid_lite_17x_csi2_reg_offset = {
.csid_csi2_rx_irq_status_addr = 0x20,
.csid_csi2_rx_irq_mask_addr = 0x24,
.csid_csi2_rx_irq_clear_addr = 0x28,
.csid_csi2_rx_irq_set_addr = 0x2c,
/*CSI2 rx control */
.csid_csi2_rx_cfg0_addr = 0x100,
.csid_csi2_rx_cfg1_addr = 0x104,
.csid_csi2_rx_capture_ctrl_addr = 0x108,
.csid_csi2_rx_rst_strobes_addr = 0x110,
.csid_csi2_rx_de_scramble_cfg0_addr = 0x114,
.csid_csi2_rx_de_scramble_cfg1_addr = 0x118,
.csid_csi2_rx_cap_unmap_long_pkt_hdr_0_addr = 0x120,
.csid_csi2_rx_cap_unmap_long_pkt_hdr_1_addr = 0x124,
.csid_csi2_rx_captured_short_pkt_0_addr = 0x128,
.csid_csi2_rx_captured_short_pkt_1_addr = 0x12c,
.csid_csi2_rx_captured_long_pkt_0_addr = 0x130,
.csid_csi2_rx_captured_long_pkt_1_addr = 0x134,
.csid_csi2_rx_captured_long_pkt_ftr_addr = 0x138,
.csid_csi2_rx_captured_cphy_pkt_hdr_addr = 0x13c,
.csid_csi2_rx_lane0_misr_addr = 0x150,
.csid_csi2_rx_lane1_misr_addr = 0x154,
.csid_csi2_rx_lane2_misr_addr = 0x158,
.csid_csi2_rx_lane3_misr_addr = 0x15c,
.csid_csi2_rx_total_pkts_rcvd_addr = 0x160,
.csid_csi2_rx_stats_ecc_addr = 0x164,
.csid_csi2_rx_total_crc_err_addr = 0x168,
.csi2_rst_srb_all = 0x3FFF,
.csi2_rst_done_shift_val = 27,
.csi2_irq_mask_all = 0xFFFFFFF,
.csi2_misr_enable_shift_val = 6,
.csi2_vc_mode_shift_val = 2,
.csi2_capture_long_pkt_en_shift = 0,
.csi2_capture_short_pkt_en_shift = 1,
.csi2_capture_cphy_pkt_en_shift = 2,
.csi2_capture_long_pkt_dt_shift = 4,
.csi2_capture_long_pkt_vc_shift = 10,
.csi2_capture_short_pkt_vc_shift = 15,
.csi2_capture_cphy_pkt_dt_shift = 20,
.csi2_capture_cphy_pkt_vc_shift = 26,
.csi2_rx_phy_num_mask = 0x3,
};
static const struct ais_ife_csid_csi2_tpg_reg_offset
ais_ife_csid_lite_17x_tpg_reg_offset = {
/*CSID TPG control */
.csid_tpg_ctrl_addr = 0x600,
.csid_tpg_vc_cfg0_addr = 0x604,
.csid_tpg_vc_cfg1_addr = 0x608,
.csid_tpg_lfsr_seed_addr = 0x60c,
.csid_tpg_dt_n_cfg_0_addr = 0x610,
.csid_tpg_dt_n_cfg_1_addr = 0x614,
.csid_tpg_dt_n_cfg_2_addr = 0x618,
.csid_tpg_color_bars_cfg_addr = 0x640,
.csid_tpg_color_box_cfg_addr = 0x644,
.csid_tpg_common_gen_cfg_addr = 0x648,
.csid_tpg_cgen_n_cfg_addr = 0x650,
.csid_tpg_cgen_n_x0_addr = 0x654,
.csid_tpg_cgen_n_x1_addr = 0x658,
.csid_tpg_cgen_n_x2_addr = 0x65c,
.csid_tpg_cgen_n_xy_addr = 0x660,
.csid_tpg_cgen_n_y1_addr = 0x664,
.csid_tpg_cgen_n_y2_addr = 0x668,
/*configurations */
.tpg_dtn_cfg_offset = 0xc,
.tpg_cgen_cfg_offset = 0x20,
.tpg_cpas_ife_reg_offset = 0x28,
};
static const struct ais_ife_csid_common_reg_offset
cam_csid_lite_17x_cmn_reg_offset = {
.csid_hw_version_addr = 0x0,
.csid_cfg0_addr = 0x4,
.csid_ctrl_addr = 0x8,
.csid_reset_addr = 0xc,
.csid_rst_strobes_addr = 0x10,
.csid_test_bus_ctrl_addr = 0x14,
.csid_top_irq_status_addr = 0x70,
.csid_top_irq_mask_addr = 0x74,
.csid_top_irq_clear_addr = 0x78,
.csid_top_irq_set_addr = 0x7c,
.csid_irq_cmd_addr = 0x80,
/*configurations */
.major_version = 1,
.minor_version = 7,
.version_incr = 0,
.num_rdis = 4,
.num_pix = 0,
.csid_reg_rst_stb = 1,
.csid_rst_stb = 0x1e,
.csid_rst_stb_sw_all = 0x1f,
.path_rst_stb_all = 0x7f,
.path_rst_done_shift_val = 1,
.path_en_shift_val = 31,
.dt_id_shift_val = 27,
.vc_shift_val = 22,
.dt_shift_val = 16,
.fmt_shift_val = 12,
.plain_fmt_shit_val = 10,
.crop_v_en_shift_val = 6,
.crop_h_en_shift_val = 5,
.crop_shift = 16,
.ipp_irq_mask_all = 0x7FFF,
.rdi_irq_mask_all = 0x7FFF,
.ppp_irq_mask_all = 0xFFFF,
};
static const struct ais_ife_csid_reg_offset ais_ife_csid_lite_17x_reg_offset = {
.cmn_reg = &cam_csid_lite_17x_cmn_reg_offset,
.csi2_reg = &ais_ife_csid_lite_17x_csi2_reg_offset,
.ipp_reg = NULL,
.rdi_reg = {
&ais_ife_csid_lite_17x_rdi_0_reg_offset,
&ais_ife_csid_lite_17x_rdi_1_reg_offset,
&ais_ife_csid_lite_17x_rdi_2_reg_offset,
&ais_ife_csid_lite_17x_rdi_3_reg_offset,
},
.tpg_reg = &ais_ife_csid_lite_17x_tpg_reg_offset,
};
#endif /*_AIS_IFE_CSID_LITE17X_H_ */

View File

@@ -0,0 +1,238 @@
/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/slab.h>
#include "ais_ife_csid_soc.h"
#include "cam_cpas_api.h"
#include "cam_debug_util.h"
static int ais_ife_csid_get_dt_properties(struct cam_hw_soc_info *soc_info)
{
struct device_node *of_node = NULL;
struct csid_device_soc_info *csid_soc_info = NULL;
int rc = 0;
of_node = soc_info->pdev->dev.of_node;
csid_soc_info = (struct csid_device_soc_info *)soc_info->soc_private;
rc = cam_soc_util_get_dt_properties(soc_info);
if (rc)
return rc;
return rc;
}
static int ais_ife_csid_request_platform_resource(
struct cam_hw_soc_info *soc_info,
irq_handler_t csid_irq_handler,
void *irq_data)
{
int rc = 0;
rc = cam_soc_util_request_platform_resource(soc_info, csid_irq_handler,
irq_data);
if (rc)
return rc;
return rc;
}
int ais_ife_csid_init_soc_resources(struct cam_hw_soc_info *soc_info,
irq_handler_t csid_irq_handler, void *irq_data)
{
int rc = 0;
struct cam_cpas_register_params cpas_register_param;
struct ais_csid_soc_private *soc_private;
soc_private = kzalloc(sizeof(struct ais_csid_soc_private), GFP_KERNEL);
if (!soc_private)
return -ENOMEM;
soc_info->soc_private = soc_private;
rc = ais_ife_csid_get_dt_properties(soc_info);
if (rc < 0)
return rc;
/* Need to see if we want post process the clock list */
rc = ais_ife_csid_request_platform_resource(soc_info, csid_irq_handler,
irq_data);
if (rc < 0) {
CAM_ERR(CAM_ISP,
"Error Request platform resources failed rc=%d", rc);
goto free_soc_private;
}
memset(&cpas_register_param, 0, sizeof(cpas_register_param));
strlcpy(cpas_register_param.identifier, "csid",
CAM_HW_IDENTIFIER_LENGTH);
cpas_register_param.cell_index = soc_info->index;
cpas_register_param.dev = soc_info->dev;
rc = cam_cpas_register_client(&cpas_register_param);
if (rc) {
CAM_ERR(CAM_ISP, "CPAS registration failed rc=%d", rc);
goto release_soc;
} else {
soc_private->cpas_handle = cpas_register_param.client_handle;
}
return rc;
release_soc:
cam_soc_util_release_platform_resource(soc_info);
free_soc_private:
kfree(soc_private);
return rc;
}
int ais_ife_csid_deinit_soc_resources(
struct cam_hw_soc_info *soc_info)
{
int rc = 0;
struct ais_csid_soc_private *soc_private;
soc_private = soc_info->soc_private;
if (!soc_private) {
CAM_ERR(CAM_ISP, "Error soc_private NULL");
return -ENODEV;
}
rc = cam_cpas_unregister_client(soc_private->cpas_handle);
if (rc)
CAM_ERR(CAM_ISP, "CPAS unregistration failed rc=%d", rc);
rc = cam_soc_util_release_platform_resource(soc_info);
return rc;
}
int ais_ife_csid_enable_soc_resources(
struct cam_hw_soc_info *soc_info, enum cam_vote_level clk_level)
{
int rc = 0;
struct ais_csid_soc_private *soc_private;
struct cam_ahb_vote ahb_vote;
struct cam_axi_vote axi_vote;
soc_private = soc_info->soc_private;
ahb_vote.type = CAM_VOTE_ABSOLUTE;
ahb_vote.vote.level = CAM_SVS_VOTE;
axi_vote.compressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
axi_vote.compressed_bw_ab = CAM_CPAS_DEFAULT_AXI_BW;
axi_vote.uncompressed_bw = CAM_CPAS_DEFAULT_AXI_BW;
CAM_DBG(CAM_ISP, "csid vote compressed_bw:%lld uncompressed_bw:%lld",
axi_vote.compressed_bw, axi_vote.uncompressed_bw);
rc = cam_cpas_start(soc_private->cpas_handle, &ahb_vote, &axi_vote);
if (rc) {
CAM_ERR(CAM_ISP, "Error CPAS start failed");
rc = -EFAULT;
goto end;
}
rc = cam_soc_util_enable_platform_resource(soc_info, true,
clk_level, true);
if (rc) {
CAM_ERR(CAM_ISP, "enable platform failed");
goto stop_cpas;
}
return rc;
stop_cpas:
cam_cpas_stop(soc_private->cpas_handle);
end:
return rc;
}
int ais_ife_csid_disable_soc_resources(struct cam_hw_soc_info *soc_info)
{
int rc = 0;
struct ais_csid_soc_private *soc_private;
if (!soc_info) {
CAM_ERR(CAM_ISP, "Error Invalid params");
return -EINVAL;
}
soc_private = soc_info->soc_private;
rc = cam_soc_util_disable_platform_resource(soc_info, true, true);
if (rc)
CAM_ERR(CAM_ISP, "Disable platform failed");
rc = cam_cpas_stop(soc_private->cpas_handle);
if (rc) {
CAM_ERR(CAM_ISP, "Error CPAS stop failed rc=%d", rc);
return rc;
}
return rc;
}
int ais_ife_csid_enable_ife_force_clock_on(struct cam_hw_soc_info *soc_info,
uint32_t cpas_ife_base_offset)
{
int rc = 0;
struct ais_csid_soc_private *soc_private;
uint32_t cpass_ife_force_clk_offset;
if (!soc_info) {
CAM_ERR(CAM_ISP, "Error Invalid params");
return -EINVAL;
}
soc_private = soc_info->soc_private;
cpass_ife_force_clk_offset =
cpas_ife_base_offset + (0x4 * soc_info->index);
rc = cam_cpas_reg_write(soc_private->cpas_handle, CAM_CPAS_REG_CPASTOP,
cpass_ife_force_clk_offset, 1, 1);
if (rc)
CAM_ERR(CAM_ISP, "CPASS set IFE:%d Force clock On failed",
soc_info->index);
else
CAM_DBG(CAM_ISP, "CPASS set IFE:%d Force clock On",
soc_info->index);
return rc;
}
int ais_ife_csid_disable_ife_force_clock_on(struct cam_hw_soc_info *soc_info,
uint32_t cpas_ife_base_offset)
{
int rc = 0;
struct ais_csid_soc_private *soc_private;
uint32_t cpass_ife_force_clk_offset;
if (!soc_info) {
CAM_ERR(CAM_ISP, "Error Invalid params");
return -EINVAL;
}
soc_private = soc_info->soc_private;
cpass_ife_force_clk_offset =
cpas_ife_base_offset + (0x4 * soc_info->index);
rc = cam_cpas_reg_write(soc_private->cpas_handle, CAM_CPAS_REG_CPASTOP,
cpass_ife_force_clk_offset, 1, 0);
if (rc)
CAM_ERR(CAM_ISP, "CPASS set IFE:%d Force clock Off failed",
soc_info->index);
else
CAM_DBG(CAM_ISP, "CPASS set IFE:%d Force clock off",
soc_info->index);
return rc;
}

View File

@@ -0,0 +1,126 @@
/* Copyright (c) 2017-2018, 2020 The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_IFE_CSID_SOC_H_
#define _AIS_IFE_CSID_SOC_H_
#include "ais_isp_hw.h"
/*
* struct ais_csid_soc_private:
*
* @Brief: Private SOC data specific to CSID HW Driver
*
* @cpas_handle: Handle returned on registering with CPAS driver.
* This handle is used for all further interface
* with CPAS.
*/
struct ais_csid_soc_private {
uint32_t cpas_handle;
};
/**
* struct csid_device_soc_info - CSID SOC info object
*
* @csi_vdd_voltage: csi vdd voltage value
*
*/
struct csid_device_soc_info {
int csi_vdd_voltage;
};
/**
* ais_ife_csid_init_soc_resources()
*
* @brief: csid initialization function for the soc info
*
* @soc_info: soc info structure pointer
* @csid_irq_handler: irq handler function to be registered
* @irq_data: irq data for the callback function
*
*/
int ais_ife_csid_init_soc_resources(struct cam_hw_soc_info *soc_info,
irq_handler_t csid_irq_handler, void *irq_data);
/**
* ais_ife_csid_deinit_soc_resources()
*
* @brief: csid de initialization function for the soc info
*
* @soc_info: soc info structure pointer
*
*/
int ais_ife_csid_deinit_soc_resources(struct cam_hw_soc_info *soc_info);
/**
* ais_ife_csid_enable_soc_resources()
*
* @brief: csid soc resource enable function
*
* @soc_info: soc info structure pointer
* @clk_lvl: vote level to start with
*
*/
int ais_ife_csid_enable_soc_resources(struct cam_hw_soc_info *soc_info,
uint32_t clk_lvl);
/**
* ais_ife_csid_disable_soc_resources()
*
* @brief: csid soc resource disable function
*
* @soc_info: soc info structure pointer
*
*/
int ais_ife_csid_disable_soc_resources(struct cam_hw_soc_info *soc_info);
/**
* ais_ife_csid_enable_ife_force_clock()
*
* @brief: if csid testgen used for dual isp case, before
* starting csid test gen, enable ife force clock on
* through cpas
*
* @soc_info: soc info structure pointer
* @cpas_ife_base_offset: cpas ife force clock base reg offset value
*
*/
int ais_ife_csid_enable_ife_force_clock_on(struct cam_hw_soc_info *soc_info,
uint32_t cpas_ife_base_offset);
/**
* ais_ife_csid_disable_ife_force_clock_on()
*
* @brief: disable the IFE force clock on after dual ISP
* CSID test gen stop
*
* @soc_info: soc info structure pointer
* @cpas_ife_base_offset: cpas ife force clock base reg offset value
*
*/
int ais_ife_csid_disable_ife_force_clock_on(struct cam_hw_soc_info *soc_info,
uint32_t cpas_ife_base_offset);
/**
* ais_ife_csid_get_vote_level()
*
* @brief: get the vote level from clock rate
*
* @soc_info: soc info structure pointer
* @clock_rate clock rate
*
*/
uint32_t ais_ife_csid_get_vote_level(struct cam_hw_soc_info *soc_info,
uint64_t clock_rate);
#endif

View File

@@ -0,0 +1,115 @@
/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_CSID_HW_INTF_H_
#define _AIS_CSID_HW_INTF_H_
#include "ais_isp_hw.h"
#include "cam_hw_intf.h"
/* MAX IFE CSID instance */
#define AIS_IFE_CSID_HW_NUM_MAX 8
/**
* enum ais_ife_cid_res_id - Specify the csid cid
*/
enum ais_ife_cid_res_id {
AIS_IFE_CSID_CID_0,
AIS_IFE_CSID_CID_1,
AIS_IFE_CSID_CID_2,
AIS_IFE_CSID_CID_3,
AIS_IFE_CSID_CID_MAX,
};
/**
* struct ais_ife_csid_hw_caps- get the CSID hw capability
* @num_rdis: number of rdis supported by CSID HW device
* @num_pix: number of pxl paths supported by CSID HW device
* @num_ppp: number of ppp paths supported by CSID HW device
* @major_version : major version
* @minor_version: minor version
* @version_incr: version increment
*
*/
struct ais_ife_csid_hw_caps {
uint32_t num_rdis;
uint32_t num_pix;
uint32_t num_ppp;
uint32_t major_version;
uint32_t minor_version;
uint32_t version_incr;
};
/**
* enum ais_ife_csid_halt_cmd - Specify the halt command type
*/
enum ais_ife_csid_halt_cmd {
AIS_CSID_HALT_AT_FRAME_BOUNDARY,
AIS_CSID_RESUME_AT_FRAME_BOUNDARY,
AIS_CSID_HALT_IMMEDIATELY,
AIS_CSID_HALT_MAX,
};
/**
* enum ais_ife_csid_reset_type - Specify the reset type
*/
enum ais_ife_csid_reset_type {
AIS_IFE_CSID_RESET_GLOBAL,
AIS_IFE_CSID_RESET_PATH,
AIS_IFE_CSID_RESET_MAX,
};
/**
* struct ais_ife_csid_reset_cfg- csid reset configuration
* @ reset_type : Global reset or path reset
* @res_node : resource need to be reset
*
*/
struct ais_csid_reset_cfg_args {
enum ais_ife_csid_reset_type reset_type;
enum ais_ife_output_path_id path;
};
/**
* enum ais_ife_csid_cmd_type - Specify the csid command
*/
enum ais_ife_csid_cmd_type {
AIS_IFE_CSID_CMD_GET_TIME_STAMP,
AIS_IFE_CSID_SET_CSID_DEBUG,
AIS_IFE_CSID_SOF_IRQ_DEBUG,
AIS_IFE_CSID_SET_INIT_FRAME_DROP,
AIS_IFE_CSID_SET_SENSOR_DIMENSION_CFG,
AIS_IFE_CSID_CMD_MAX,
};
/**
* ais_ife_csid_hw_init()
*
* @brief: Initialize function for the CSID hardware
*
* @ife_csid_hw: CSID hardware instance returned
* @hw_idex: CSID hardware instance id
*/
int ais_ife_csid_hw_init(struct cam_hw_intf **ife_csid_hw,
struct ais_isp_hw_init_args *init);
/*
* struct ais_ife_csid_clock_update_args:
*
* @clk_rate: Clock rate requested
*/
struct ais_ife_csid_clock_update_args {
uint64_t clk_rate;
};
#endif /* _AIS_CSID_HW_INTF_H_ */

View File

@@ -0,0 +1,526 @@
/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_ISP_HW_H_
#define _AIS_ISP_HW_H_
#include <linux/completion.h>
#include <uapi/media/cam_isp.h>
#include "cam_hw.h"
#include "cam_hw_intf.h"
#include "cam_soc_util.h"
/* cam_control handle_type for IFE device */
#define AIS_ISP_CMD_TYPE 0xA151FE00
/* Maximum length of tag while dumping */
#define AIS_ISP_HW_DUMP_TAG_MAX_LEN 32
/*
* struct ais_irq_register_set:
* @Brief: Structure containing offsets of IRQ related
* registers belonging to a Set
*
* @mask_reg_offset: Offset of IRQ MASK register
* @clear_reg_offset: Offset of IRQ CLEAR register
* @status_reg_offset: Offset of IRQ STATUS register
*/
struct ais_irq_register_set {
uint32_t mask_reg_offset;
uint32_t clear_reg_offset;
uint32_t status_reg_offset;
};
/*
* struct ais_irq_controller_reg_info:
* @Brief: Structure describing the IRQ registers
*
* @num_registers: Number of sets(mask/clear/status) of IRQ registers
* @irq_reg_set: Array of Register Set Offsets.
* Length of array = num_registers
* @global_clear_offset: Offset of Global IRQ Clear register. This register
* contains the BIT that needs to be set for the CLEAR
* to take effect
* @global_clear_bitmask: Bitmask needed to be used in Global Clear register
* for Clear IRQ cmd to take effect
*/
struct ais_irq_controller_reg_info {
uint32_t num_registers;
struct ais_irq_register_set *irq_reg_set;
uint32_t global_clear_offset;
uint32_t global_clear_bitmask;
};
/*
* struct ais_isp_timestamp:
*
* @mono_time: Monotonic boot time
* @vt_time: AV Timer time
* @ticks: Qtimer ticks
* @time_usecs: time in micro seconds
*/
struct ais_isp_timestamp {
struct timeval mono_time;
struct timeval vt_time;
uint64_t ticks;
uint64_t time_usecs;
};
/*
* ais_isp_hw_get_timestamp()
*
* @Brief: Get timestamp values
*
* @time_stamp: Structure that holds different time values
*
* @Return: Void
*/
void ais_isp_hw_get_timestamp(struct ais_isp_timestamp *time_stamp);
enum ais_isp_hw_type {
AIS_ISP_HW_TYPE_CSID = 0,
AIS_ISP_HW_TYPE_ISPIF = 1,
AIS_ISP_HW_TYPE_VFE = 2,
AIS_ISP_HW_TYPE_IFE_CSID = 3,
AIS_ISP_HW_TYPE_MAX = 4,
};
enum ais_isp_resource_state {
AIS_ISP_RESOURCE_STATE_UNAVAILABLE = 0,
AIS_ISP_RESOURCE_STATE_AVAILABLE = 1,
AIS_ISP_RESOURCE_STATE_RESERVED = 2,
AIS_ISP_RESOURCE_STATE_INIT_HW = 3,
AIS_ISP_RESOURCE_STATE_STREAMING = 4,
AIS_ISP_RESOURCE_STATE_ERROR = 5
};
enum ais_isp_hw_cmd_type {
AIS_ISP_HW_CMD_GET_CHANGE_BASE,
AIS_ISP_HW_CMD_GET_BUF_UPDATE,
AIS_ISP_HW_CMD_GET_BUF_UPDATE_RM,
AIS_ISP_HW_CMD_GET_REG_UPDATE,
AIS_ISP_HW_CMD_GET_HFR_UPDATE,
AIS_ISP_HW_CMD_GET_HFR_UPDATE_RM,
AIS_ISP_HW_CMD_GET_SECURE_MODE,
AIS_ISP_HW_CMD_STRIPE_UPDATE,
AIS_ISP_HW_CMD_CLOCK_UPDATE,
AIS_ISP_HW_CMD_BW_UPDATE,
AIS_ISP_HW_CMD_BW_CONTROL,
AIS_ISP_HW_CMD_STOP_BUS_ERR_IRQ,
AIS_ISP_HW_CMD_GET_REG_DUMP,
AIS_ISP_HW_CMD_UBWC_UPDATE,
AIS_ISP_HW_CMD_SOF_IRQ_DEBUG,
AIS_ISP_HW_CMD_SET_CAMIF_DEBUG,
AIS_ISP_HW_CMD_CSID_CLOCK_UPDATE,
AIS_ISP_HW_CMD_FE_UPDATE_IN_RD,
AIS_ISP_HW_CMD_FE_UPDATE_BUS_RD,
AIS_ISP_HW_CMD_GET_IRQ_REGISTER_DUMP,
AIS_ISP_HW_CMD_FPS_CONFIG,
AIS_ISP_HW_CMD_DUMP_HW,
AIS_ISP_HW_CMD_SET_STATS_DMI_DUMP,
AIS_ISP_HW_CMD_GET_RDI_IRQ_MASK,
AIS_ISP_HW_CMD_MAX,
};
/*
* struct ais_isp_hw_cmd_buf_update:
*
* @Brief: Contain the new created command buffer information
*
* @cmd_buf_addr: Command buffer to store the change base command
* @size: Size of the buffer in bytes
* @used_bytes: Consumed bytes in the command buffer
*
*/
struct ais_isp_hw_cmd_buf_update {
uint32_t *cmd_buf_addr;
uint32_t size;
uint32_t used_bytes;
};
/*
* struct ais_isp_hw_get_wm_update:
*
* @Brief: Get cmd buffer for WM updates.
*
* @ image_buf: image buffer address array
* @ num_buf: Number of buffers in the image_buf array
* @ io_cfg: IO buffer config information sent from UMD
*
*/
struct ais_isp_hw_get_wm_update {
uint64_t *image_buf;
uint32_t num_buf;
struct cam_buf_io_cfg *io_cfg;
};
/*
* struct ais_isp_hw_rup_data:
*
* @Brief: RUP for required resources.
*
* @is_fe_enable if fetch engine enabled
* @res_bitmap resource bitmap for set resources
*
*/
struct ais_isp_hw_rup_data {
bool is_fe_enable;
unsigned long res_bitmap;
};
/*
* struct ais_isp_hw_get_cmd_update:
*
* @Brief: Get cmd buffer update for different CMD types
*
* @res: Resource node
* @cmd_type: Command type for which to get update
* @cmd: Command buffer information
*
*/
struct ais_isp_hw_get_cmd_update {
enum ais_isp_hw_cmd_type cmd_type;
union {
void *data;
};
};
/*
* struct ais_isp_hw_dump_args:
*
* @Brief: isp hw dump args
*
* @ req_id: request id
* @ cpu_addr: cpu address
* @ buf_len: buf len
* @ offset: offset of buffer
* @ ctxt_to_hw_map: ctx to hw map
*/
struct ais_isp_hw_dump_args {
uint64_t req_id;
uintptr_t cpu_addr;
size_t buf_len;
uint32_t offset;
void *ctxt_to_hw_map;
};
/**
* struct ais_isp_hw_dump_header - ISP context dump header
*
* @Brief: isp hw dump header
*
* @tag: Tag name for the header
* @word_size: Size of word
* @size: Size of data
*
*/
struct ais_isp_hw_dump_header {
char tag[AIS_ISP_HW_DUMP_TAG_MAX_LEN];
uint64_t size;
uint32_t word_size;
};
/**
* enum ais_ife_output_path_id
*
* @brief output path IDs
*/
enum ais_ife_output_path_id {
AIS_IFE_PATH_RDI_0,
AIS_IFE_PATH_RDI_1,
AIS_IFE_PATH_RDI_2,
AIS_IFE_PATH_RDI_3,
AIS_IFE_PATH_MAX,
};
/**
* struct ais_ife_rdi_in_cfg
*
* @brief Input Configuration
*
* @format : format
* @width : width
* @height : height
* @crop_enable : is crop enabled
* @crop_top : crop top line
* @crop_bottom : crop bottom line
* @crop_left : crop left pixel
* @crop_right : crop right pixel
* @reserved
*/
struct ais_ife_rdi_in_cfg {
uint32_t format;
uint32_t decode_format;
uint32_t pack_type;
uint32_t width;
uint32_t height;
uint32_t crop_enable;
uint32_t crop_top;
uint32_t crop_bottom;
uint32_t crop_left;
uint32_t crop_right;
uint32_t reserved;
};
/**
* struct ais_ife_rdi_out_cfg
*
* @brief Output Configuration
*
* @format : format
* @secure_mode : Data Type
* @mode : line based or frame based
* @width : width
* @height : height
* @stride : stride
* @frame_increment : frame increment
* @frame_drop_pattern : framedrop pattern
* @frame_drop_period : framedrop period
* @reserved
*/
struct ais_ife_rdi_out_cfg {
uint32_t format;
uint32_t secure_mode;
uint32_t mode;
uint32_t width;
uint32_t height;
uint32_t stride;
uint32_t frame_increment;
uint32_t frame_drop_pattern;
uint32_t frame_drop_period;
uint32_t reserved;
};
/**
* struct ais_ife_csid_csi_info
*
* @brief CSI Configuration
*
* @csiphy_id : CSIPHY id
* @vc : Virtual Channel
* @dt : Data Type
* @num_lanes : Number of lanes
* @lane_assign : Lane mapping
* @is_3Phase : DPHY or CPHY
*/
struct ais_ife_csid_csi_info {
uint32_t csiphy_id;
uint32_t vc;
uint32_t dt;
uint32_t num_lanes;
uint32_t lane_assign;
uint32_t is_3Phase;
};
/**
* struct ais_ife_rdi_init_args
*
* @brief Iniit RDI path
*
* @path : output path
* @csi_cfg : CSI configuration
* @in_cfg : Input configuration
* @out_cfg : Output configuration
*/
struct ais_ife_rdi_init_args {
enum ais_ife_output_path_id path;
struct ais_ife_csid_csi_info csi_cfg;
struct ais_ife_rdi_in_cfg in_cfg;
struct ais_ife_rdi_out_cfg out_cfg;
};
/**
* struct ais_ife_rdi_deinit_args
*
* @brief Deinit RDI path
*
* @path : output path
*/
struct ais_ife_rdi_deinit_args {
enum ais_ife_output_path_id path;
};
/**
* struct ais_ife_rdi_stop_args
*
* @brief Start RDI path
*
* @path : output path
*/
struct ais_ife_rdi_start_args {
enum ais_ife_output_path_id path;
};
/**
* struct ais_ife_rdi_stop_args
*
* @brief Stop RDI path
*
* @path : output path
*/
struct ais_ife_rdi_stop_args {
enum ais_ife_output_path_id path;
};
/**
* struct ais_ife_enqueue_buffer_args
*
* @brief buffer definition for enqueue
*
* @mem_handle : allocated mem_handle
* @idx : buffer index used as identifier
* @offset : offset into buffer for hw to write to
*/
struct ais_ife_buffer_enqueue {
int32_t mem_handle;
uint32_t idx;
uint32_t offset;
};
/**
* struct ais_ife_enqueue_buffer_args
*
* @brief Enqueue buffer command argument
*
* @path : output path to enqueue to
* @buffer : image buffer
* @buffer_header : frame header buffer
*/
struct ais_ife_enqueue_buffer_args {
enum ais_ife_output_path_id path;
struct ais_ife_buffer_enqueue buffer;
struct ais_ife_buffer_enqueue buffer_header;
};
/**
* struct ais_ife_rdi_timestamps
*
* @brief : timestamps for RDI path
*
* @cur_sof_ts : current SOF time stamp
* @prev_sof_ts : previous SOF time stamp
*/
struct ais_ife_rdi_timestamps {
uint64_t cur_sof_ts;
uint64_t prev_sof_ts;
};
/**
* struct ais_ife_rdi_get_timestamp_args
*
* @brief : time stamp capture arguments
*
* @path : output path to get the time stamp
* @ts : timestamps
*/
struct ais_ife_rdi_get_timestamp_args {
enum ais_ife_output_path_id path;
struct ais_ife_rdi_timestamps *ts;
};
/**
* struct ais_ife_sof_msg
*
* @brief SOF event message
*
* @hw_ts : HW timestamp
* @frame_id : frame count
*/
struct ais_ife_sof_msg {
uint64_t hw_ts;
uint32_t frame_id;
};
/**
* struct ais_ife_error_msg
*
* @brief Error event message
*
* @reserved : payload information
*/
struct ais_ife_error_msg {
uint32_t reserved;
};
/**
* struct ais_ife_frame_msg
*
* @brief Frame done event message
*
* @hw_ts : SOF HW timestamp
* @ts : SOF timestamp
* @frame_id : frame count
* @buf_idx : buffer index
*/
struct ais_ife_frame_msg {
uint64_t hw_ts;
uint64_t ts;
uint32_t frame_id;
uint32_t buf_idx;
};
/**
* enum ais_ife_msg_type
*
* @brief event message type
*/
enum ais_ife_msg_type {
AIS_IFE_MSG_SOF,
AIS_IFE_MSG_FRAME_DONE,
AIS_IFE_MSG_OUTPUT_ERROR,
AIS_IFE_MSG_CSID_WARNING,
AIS_IFE_MSG_CSID_ERROR
};
/**
* struct ais_ife_frame_msg
*
* @brief Frame done event message
*
* @type : message type
* @idx : IFE idx
* @path : input/output path
* @reserved: reserved for alignment
* @reserved1: reserved for alignment
* @boot_ts : event timestamp
* @u : event message
*/
struct ais_ife_event_data {
uint8_t type;
uint8_t idx;
uint8_t path;
uint8_t reserved;
uint32_t reserved1;
uint64_t boot_ts;
union {
struct ais_ife_sof_msg sof_msg;
struct ais_ife_error_msg err_msg;
struct ais_ife_frame_msg frame_msg;
} u;
};
/* hardware event callback function type */
typedef int (*ais_ife_event_cb_func)(void *priv,
struct ais_ife_event_data *evt_data);
struct ais_isp_hw_init_args {
uint32_t hw_idx;
int iommu_hdl;
int iommu_hdl_secure;
ais_ife_event_cb_func event_cb;
void *event_cb_priv;
};
#endif /* _AIS_ISP_HW_H_ */

View File

@@ -0,0 +1,106 @@
/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_VFE_HW_INTF_H_
#define _AIS_VFE_HW_INTF_H_
#include "ais_isp_hw.h"
#define AIS_VFE_HW_NUM_MAX 8
#define VFE_CORE_BASE_IDX 0
/*
* VBIF and BUS do not exist on same HW.
* Hence both can be 1 below.
*/
#define VFE_VBIF_BASE_IDX 1
#define VFE_BUS_BASE_IDX 1
enum ais_vfe_hw_cmd_type {
AIS_VFE_CMD_ENQ_BUFFER = 0
};
enum ais_vfe_hw_irq_status {
AIS_VFE_IRQ_STATUS_ERR_COMP = -3,
AIS_VFE_IRQ_STATUS_COMP_OWRT = -2,
AIS_VFE_IRQ_STATUS_ERR = -1,
AIS_VFE_IRQ_STATUS_SUCCESS = 0,
AIS_VFE_IRQ_STATUS_OVERFLOW = 1,
AIS_VFE_IRQ_STATUS_P2I_ERROR = 2,
AIS_VFE_IRQ_STATUS_VIOLATION = 3,
AIS_VFE_IRQ_STATUS_MAX,
};
enum ais_vfe_hw_irq_regs {
CAM_IFE_IRQ_CAMIF_REG_STATUS0 = 0,
CAM_IFE_IRQ_CAMIF_REG_STATUS1 = 1,
CAM_IFE_IRQ_VIOLATION_STATUS = 2,
CAM_IFE_IRQ_REGISTERS_MAX,
};
enum ais_vfe_bus_irq_regs {
CAM_IFE_IRQ_BUS_REG_STATUS0 = 0,
CAM_IFE_IRQ_BUS_REG_STATUS1 = 1,
CAM_IFE_IRQ_BUS_REG_STATUS2 = 2,
CAM_IFE_IRQ_BUS_REG_COMP_ERR = 3,
CAM_IFE_IRQ_BUS_REG_COMP_OWRT = 4,
CAM_IFE_IRQ_BUS_DUAL_COMP_ERR = 5,
CAM_IFE_IRQ_BUS_DUAL_COMP_OWRT = 6,
CAM_IFE_BUS_IRQ_REGISTERS_MAX,
};
enum ais_vfe_reset_type {
AIS_VFE_HW_RESET_HW_AND_REG,
AIS_VFE_HW_RESET_HW,
AIS_VFE_HW_RESET_MAX,
};
/**
* struct ais_vfe_hw_evt_payload- handle vfe error
* @hw_idx : Hw index of vfe
* @evt_type : Event type from VFE
*/
struct ais_vfe_hw_evt_payload {
uint32_t hw_idx;
uint32_t evt_type;
};
/*
* struct ais_vfe_hw_get_hw_cap:
*
* @max_width: Max width supported by HW
* @max_height: Max height supported by HW
* @max_pixel_num: Max Pixel channels available
* @max_rdi_num: Max Raw channels available
*/
struct ais_vfe_hw_get_hw_cap {
uint32_t max_width;
uint32_t max_height;
uint32_t max_pixel_num;
uint32_t max_rdi_num;
};
/*
* ais_vfe_hw_init()
*
* @Brief: Initialize VFE HW device
*
* @vfe_hw: vfe_hw interface to fill in and return on
* successful initialization
* @hw_idx: Index of VFE HW
*/
int ais_vfe_hw_init(struct cam_hw_intf **vfe_hw,
struct ais_isp_hw_init_args *init,
struct cam_hw_intf *csid_hw);
#endif /* _AIS_VFE_HW_INTF_H_ */

View File

@@ -0,0 +1,15 @@
ccflags-y += -Idrivers/media/platform/msm/ais/cam_utils
ccflags-y += -Idrivers/media/platform/msm/ais/cam_core
ccflags-y += -Idrivers/media/platform/msm/ais/cam_cpas/include
ccflags-y += -Idrivers/media/platform/msm/ais/cam_smmu/
ccflags-y += -Idrivers/media/platform/msm/ais/cam_req_mgr/
ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp
ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp/include
ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp/vfe_hw/include
ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp/vfe_hw/vfe_bus/include
ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp/vfe_hw/vfe_bus
ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp/vfe_hw/vfe_top/include
ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp/vfe_hw/vfe_top
obj-$(CONFIG_MSM_AIS) += ais_vfe_soc.o ais_vfe_dev.o ais_vfe_core.o
obj-$(CONFIG_MSM_AIS) += vfe17x/

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,165 @@
/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_VFE_CORE_H_
#define _AIS_VFE_CORE_H_
#include <linux/spinlock.h>
#include "cam_hw_intf.h"
#include "ais_vfe_hw_intf.h"
#include "ais_ife_csid_hw_intf.h"
#include "ais_vfe_bus_ver2.h"
#include "ais_vfe_top_ver2.h"
#define AIS_VFE_WORKQ_NUM_TASK 16
#define AIS_VFE_MAX_BUF 12
enum ais_vfe_hw_irq_event {
AIS_VFE_HW_IRQ_EVENT_SOF,
AIS_VFE_HW_IRQ_EVENT_BUS_WR,
AIS_VFE_HW_IRQ_EVENT_ERROR,
};
/**
* struct ais_csid_hw_work_data- work data for csid
* Later other fields can be added to this data
* @evt_type : Event type from CSID
* @irq_status : IRQ Status register
*
*/
struct ais_vfe_hw_work_data {
enum ais_vfe_hw_irq_event evt_type;
uint32_t path;
uint64_t ts;
struct ais_ife_rdi_timestamps ts_hw[AIS_IFE_PATH_MAX];
};
struct ais_vfe_hw_info {
struct ais_irq_controller_reg_info *irq_reg_info;
uint32_t bus_version;
struct ais_vfe_bus_ver2_hw_info *bus_hw_info;
uint32_t bus_rd_version;
void *bus_rd_hw_info;
uint32_t top_version;
struct ais_vfe_top_ver2_hw_info *top_hw_info;
uint32_t camif_version;
void *camif_reg;
uint32_t camif_lite_version;
void *camif_lite_reg;
uint32_t testgen_version;
void *testgen_reg;
uint32_t num_qos_settings;
struct cam_isp_reg_val_pair *qos_settings;
uint32_t num_ds_settings;
struct cam_isp_reg_val_pair *ds_settings;
uint32_t num_vbif_settings;
struct cam_isp_reg_val_pair *vbif_settings;
};
struct ais_vfe_buffer_t {
struct list_head list;
int32_t mem_handle;
uint64_t iova_addr;
uint32_t bufIdx;
};
struct ais_vfe_rdi_output {
enum ais_isp_resource_state state;
uint32_t en_cfg;
spinlock_t buffer_lock;
struct ais_vfe_buffer_t buffers[AIS_VFE_MAX_BUF];
struct list_head buffer_q;
uint8_t num_buffer_hw_q;
struct list_head buffer_hw_q;
struct list_head free_buffer_list;
uint32_t last_addr;
uint64_t frame_cnt;
uint64_t sof_ts;
uint64_t sof_hw_ts;
};
struct ais_vfe_hw_core_info {
struct ais_vfe_hw_info *vfe_hw_info;
uint32_t vfe_idx;
void __iomem *mem_base;
int iommu_hdl;
int iommu_hdl_secure;
uint32_t max_rdis;
struct ais_vfe_rdi_output rdi_out[AIS_IFE_PATH_MAX];
uint32_t cpas_handle;
int irq_handle;
int irq_err_handle;
uint32_t irq_mask0;
uint32_t irq_mask1;
uint32_t bus_wr_mask1;
spinlock_t spin_lock;
struct cam_req_mgr_core_workq *workq;
struct ais_vfe_hw_work_data work_data[AIS_VFE_WORKQ_NUM_TASK];
struct cam_hw_intf *csid_hw;
struct ais_ife_event_data event;
void *event_cb_priv;
ais_ife_event_cb_func event_cb;
};
int ais_vfe_get_hw_caps(void *device_priv,
void *get_hw_cap_args, uint32_t arg_size);
int ais_vfe_init_hw(void *device_priv,
void *init_hw_args, uint32_t arg_size);
int ais_vfe_deinit_hw(void *hw_priv,
void *deinit_hw_args, uint32_t arg_size);
int ais_vfe_force_reset(void *device_priv,
void *reset_core_args, uint32_t arg_size);
int ais_vfe_reserve(void *device_priv,
void *reserve_args, uint32_t arg_size);
int ais_vfe_release(void *device_priv,
void *reserve_args, uint32_t arg_size);
int ais_vfe_start(void *device_priv,
void *start_args, uint32_t arg_size);
int ais_vfe_stop(void *device_priv,
void *stop_args, uint32_t arg_size);
int ais_vfe_read(void *device_priv,
void *read_args, uint32_t arg_size);
int ais_vfe_write(void *device_priv,
void *write_args, uint32_t arg_size);
int ais_vfe_process_cmd(void *device_priv, uint32_t cmd_type,
void *cmd_args, uint32_t arg_size);
irqreturn_t ais_vfe_irq(int irq_num, void *data);
int ais_vfe_core_init(struct ais_vfe_hw_core_info *core_info,
struct cam_hw_soc_info *soc_info,
struct cam_hw_intf *hw_intf,
struct ais_vfe_hw_info *vfe_hw_info);
int ais_vfe_core_deinit(struct ais_vfe_hw_core_info *core_info,
struct ais_vfe_hw_info *vfe_hw_info);
#endif /* _AIS_VFE_CORE_H_ */

View File

@@ -0,0 +1,223 @@
/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/slab.h>
#include <linux/mod_devicetable.h>
#include <linux/of_device.h>
#include "ais_vfe_dev.h"
#include "ais_vfe_core.h"
#include "ais_vfe_soc.h"
#include "cam_debug_util.h"
static struct cam_hw_intf *ais_vfe_hw_list[AIS_VFE_HW_NUM_MAX] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
static char vfe_dev_name[8];
int ais_vfe_probe(struct platform_device *pdev)
{
struct cam_hw_info *vfe_hw = NULL;
struct cam_hw_intf *vfe_hw_intf = NULL;
const struct of_device_id *match_dev = NULL;
struct ais_vfe_hw_core_info *core_info = NULL;
struct ais_vfe_hw_info *hw_info = NULL;
int rc = 0;
CAM_INFO(CAM_ISP, "Probe called");
vfe_hw_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
if (!vfe_hw_intf) {
rc = -ENOMEM;
goto end;
}
of_property_read_u32(pdev->dev.of_node,
"cell-index", &vfe_hw_intf->hw_idx);
vfe_hw = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL);
if (!vfe_hw) {
rc = -ENOMEM;
goto free_vfe_hw_intf;
}
memset(vfe_dev_name, 0, sizeof(vfe_dev_name));
snprintf(vfe_dev_name, sizeof(vfe_dev_name),
"vfe%1u", vfe_hw_intf->hw_idx);
vfe_hw->soc_info.pdev = pdev;
vfe_hw->soc_info.dev = &pdev->dev;
vfe_hw->soc_info.dev_name = vfe_dev_name;
vfe_hw_intf->hw_priv = vfe_hw;
vfe_hw_intf->hw_ops.get_hw_caps = ais_vfe_get_hw_caps;
vfe_hw_intf->hw_ops.init = ais_vfe_init_hw;
vfe_hw_intf->hw_ops.deinit = ais_vfe_deinit_hw;
vfe_hw_intf->hw_ops.reset = ais_vfe_force_reset;
vfe_hw_intf->hw_ops.reserve = ais_vfe_reserve;
vfe_hw_intf->hw_ops.release = ais_vfe_release;
vfe_hw_intf->hw_ops.start = ais_vfe_start;
vfe_hw_intf->hw_ops.stop = ais_vfe_stop;
vfe_hw_intf->hw_ops.read = ais_vfe_read;
vfe_hw_intf->hw_ops.write = ais_vfe_write;
vfe_hw_intf->hw_ops.process_cmd = ais_vfe_process_cmd;
vfe_hw_intf->hw_type = AIS_ISP_HW_TYPE_VFE;
CAM_INFO(CAM_ISP, "Probe called for VFE%d", vfe_hw_intf->hw_idx);
platform_set_drvdata(pdev, vfe_hw_intf);
vfe_hw->core_info = kzalloc(sizeof(struct ais_vfe_hw_core_info),
GFP_KERNEL);
if (!vfe_hw->core_info) {
CAM_DBG(CAM_ISP, "Failed to alloc for core");
rc = -ENOMEM;
goto free_vfe_hw;
}
core_info = (struct ais_vfe_hw_core_info *)vfe_hw->core_info;
match_dev = of_match_device(pdev->dev.driver->of_match_table,
&pdev->dev);
if (!match_dev) {
CAM_ERR(CAM_ISP, "Of_match Failed");
rc = -EINVAL;
goto free_core_info;
}
hw_info = (struct ais_vfe_hw_info *)match_dev->data;
core_info->vfe_hw_info = hw_info;
rc = ais_vfe_init_soc_resources(&vfe_hw->soc_info, ais_vfe_irq,
vfe_hw);
if (rc < 0) {
CAM_ERR(CAM_ISP, "Failed to init soc rc=%d", rc);
goto free_core_info;
}
rc = ais_vfe_core_init(core_info, &vfe_hw->soc_info,
vfe_hw_intf, hw_info);
if (rc < 0) {
CAM_ERR(CAM_ISP, "Failed to init core rc=%d", rc);
goto deinit_soc;
}
vfe_hw->hw_state = CAM_HW_STATE_POWER_DOWN;
mutex_init(&vfe_hw->hw_mutex);
spin_lock_init(&vfe_hw->hw_lock);
init_completion(&vfe_hw->hw_complete);
if (vfe_hw_intf->hw_idx < AIS_VFE_HW_NUM_MAX)
ais_vfe_hw_list[vfe_hw_intf->hw_idx] = vfe_hw_intf;
/*@TODO: why do we need this if not checking for errors*/
ais_vfe_init_hw(vfe_hw, NULL, 0);
ais_vfe_deinit_hw(vfe_hw, NULL, 0);
CAM_DBG(CAM_ISP, "VFE%d probe successful", vfe_hw_intf->hw_idx);
return rc;
deinit_soc:
if (ais_vfe_deinit_soc_resources(&vfe_hw->soc_info))
CAM_ERR(CAM_ISP, "Failed to deinit soc");
free_core_info:
kfree(vfe_hw->core_info);
free_vfe_hw:
kfree(vfe_hw);
free_vfe_hw_intf:
kfree(vfe_hw_intf);
end:
return rc;
}
int ais_vfe_remove(struct platform_device *pdev)
{
struct cam_hw_info *vfe_hw = NULL;
struct cam_hw_intf *vfe_hw_intf = NULL;
struct ais_vfe_hw_core_info *core_info = NULL;
int rc = 0;
vfe_hw_intf = platform_get_drvdata(pdev);
if (!vfe_hw_intf) {
CAM_ERR(CAM_ISP, "Error! No data in pdev");
return -EINVAL;
}
CAM_DBG(CAM_ISP, "type %d index %d",
vfe_hw_intf->hw_type, vfe_hw_intf->hw_idx);
if (vfe_hw_intf->hw_idx < AIS_VFE_HW_NUM_MAX)
ais_vfe_hw_list[vfe_hw_intf->hw_idx] = NULL;
vfe_hw = vfe_hw_intf->hw_priv;
if (!vfe_hw) {
CAM_ERR(CAM_ISP, "Error! HW data is NULL");
rc = -ENODEV;
goto free_vfe_hw_intf;
}
core_info = (struct ais_vfe_hw_core_info *)vfe_hw->core_info;
if (!core_info) {
CAM_ERR(CAM_ISP, "Error! core data NULL");
rc = -EINVAL;
goto deinit_soc;
}
rc = ais_vfe_core_deinit(core_info, core_info->vfe_hw_info);
if (rc < 0)
CAM_ERR(CAM_ISP, "Failed to deinit core rc=%d", rc);
kfree(vfe_hw->core_info);
deinit_soc:
rc = ais_vfe_deinit_soc_resources(&vfe_hw->soc_info);
if (rc < 0)
CAM_ERR(CAM_ISP, "Failed to deinit soc rc=%d", rc);
mutex_destroy(&vfe_hw->hw_mutex);
kfree(vfe_hw);
CAM_DBG(CAM_ISP, "VFE%d remove successful", vfe_hw_intf->hw_idx);
free_vfe_hw_intf:
kfree(vfe_hw_intf);
return rc;
}
int ais_vfe_hw_init(struct cam_hw_intf **vfe_hw,
struct ais_isp_hw_init_args *init,
struct cam_hw_intf *csid_hw)
{
int rc = 0;
if (ais_vfe_hw_list[init->hw_idx]) {
struct cam_hw_info *vfe_hw_info = NULL;
struct ais_vfe_hw_core_info *core_info = NULL;
vfe_hw_info = ais_vfe_hw_list[init->hw_idx]->hw_priv;
core_info =
(struct ais_vfe_hw_core_info *)vfe_hw_info->core_info;
core_info->csid_hw = csid_hw;
core_info->event_cb = init->event_cb;
core_info->event_cb_priv = init->event_cb_priv;
core_info->iommu_hdl = init->iommu_hdl;
core_info->iommu_hdl_secure = init->iommu_hdl_secure;
*vfe_hw = ais_vfe_hw_list[init->hw_idx];
rc = 0;
} else {
*vfe_hw = NULL;
rc = -ENODEV;
}
return rc;
}

View File

@@ -0,0 +1,42 @@
/* Copyright (c) 2017-2018, 2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_VFE_DEV_H_
#define _AIS_VFE_DEV_H_
#include <linux/platform_device.h>
/*
* ais_vfe_probe()
*
* @brief: Driver probe function called on Boot
*
* @pdev: Platform Device pointer
*
* @Return: 0: Success
* Non-zero: Failure
*/
int ais_vfe_probe(struct platform_device *pdev);
/*
* ais_vfe_remove()
*
* @brief: Driver remove function
*
* @pdev: Platform Device pointer
*
* @Return: 0: Success
* Non-zero: Failure
*/
int ais_vfe_remove(struct platform_device *pdev);
#endif /* _AIS_VFE_DEV_H_ */

View File

@@ -0,0 +1,356 @@
/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/slab.h>
#include "cam_cpas_api.h"
#include "ais_vfe_soc.h"
#include "cam_debug_util.h"
static bool ais_vfe_cpas_cb(uint32_t client_handle, void *userdata,
struct cam_cpas_irq_data *irq_data)
{
bool error_handled = false;
if (!irq_data)
return error_handled;
switch (irq_data->irq_type) {
case CAM_CAMNOC_IRQ_IFE02_UBWC_ENCODE_ERROR:
case CAM_CAMNOC_IRQ_IFE13_UBWC_ENCODE_ERROR:
case CAM_CAMNOC_IRQ_IFE0_UBWC_ENCODE_ERROR:
case CAM_CAMNOC_IRQ_IFE1_WRITE_UBWC_ENCODE_ERROR:
CAM_ERR_RATE_LIMIT(CAM_ISP,
"IFE UBWC Encode error type=%d status=%x",
irq_data->irq_type,
irq_data->u.enc_err.encerr_status.value);
error_handled = true;
break;
default:
break;
}
return error_handled;
}
static int ais_vfe_get_dt_properties(struct cam_hw_soc_info *soc_info)
{
int rc = 0;
rc = cam_soc_util_get_dt_properties(soc_info);
if (rc) {
CAM_ERR(CAM_ISP, "Error! get DT properties failed rc=%d", rc);
return rc;
}
return rc;
}
static int ais_vfe_request_platform_resource(
struct cam_hw_soc_info *soc_info,
irq_handler_t vfe_irq_handler, void *irq_data)
{
int rc = 0;
rc = cam_soc_util_request_platform_resource(soc_info, vfe_irq_handler,
irq_data);
if (rc)
CAM_ERR(CAM_ISP,
"Error! Request platform resource failed rc=%d", rc);
return rc;
}
static int ais_vfe_release_platform_resource(struct cam_hw_soc_info *soc_info)
{
int rc = 0;
rc = cam_soc_util_release_platform_resource(soc_info);
if (rc)
CAM_ERR(CAM_ISP,
"Error! Release platform resource failed rc=%d", rc);
return rc;
}
int ais_vfe_init_soc_resources(struct cam_hw_soc_info *soc_info,
irq_handler_t vfe_irq_handler, void *irq_data)
{
int rc = 0;
struct ais_vfe_soc_private *soc_private;
struct cam_cpas_register_params cpas_register_param;
soc_private = kzalloc(sizeof(struct ais_vfe_soc_private),
GFP_KERNEL);
if (!soc_private) {
CAM_DBG(CAM_ISP, "Error! soc_private Alloc Failed");
return -ENOMEM;
}
soc_info->soc_private = soc_private;
rc = ais_vfe_get_dt_properties(soc_info);
if (rc < 0) {
CAM_ERR(CAM_ISP, "Error! Get DT properties failed rc=%d", rc);
goto free_soc_private;
}
rc = cam_soc_util_get_option_clk_by_name(soc_info,
AIS_VFE_DSP_CLK_NAME, &soc_private->dsp_clk,
&soc_private->dsp_clk_index, &soc_private->dsp_clk_rate);
if (rc)
/* failure expected as dsp clk is not used for now */
CAM_INFO(CAM_ISP, "Option clk get failed with rc %d", rc);
rc = ais_vfe_request_platform_resource(soc_info, vfe_irq_handler,
irq_data);
if (rc < 0) {
CAM_ERR(CAM_ISP,
"Error! Request platform resources failed rc=%d", rc);
goto free_soc_private;
}
memset(&cpas_register_param, 0, sizeof(cpas_register_param));
cpas_register_param.cell_index = soc_info->index;
cpas_register_param.dev = soc_info->dev;
cpas_register_param.cam_cpas_client_cb = ais_vfe_cpas_cb;
cpas_register_param.userdata = soc_info;
rc = cam_cpas_get_cpas_hw_version(&soc_private->cpas_version);
if (rc) {
CAM_ERR(CAM_ISP, "Error! Invalid cpas version rc=%d", rc);
goto free_soc_private;
}
switch (soc_private->cpas_version) {
case CAM_CPAS_TITAN_175_V120:
strlcpy(cpas_register_param.identifier, "iferdi",
CAM_HW_IDENTIFIER_LENGTH);
rc = cam_cpas_register_client(&cpas_register_param);
if (rc) {
CAM_ERR(CAM_ISP, "rdi CPAS registration failed rc=%d",
rc);
goto release_soc;
} else {
soc_private->cpas_handle[0] =
cpas_register_param.client_handle;
}
strlcpy(cpas_register_param.identifier, "ifenrdi",
CAM_HW_IDENTIFIER_LENGTH);
rc = cam_cpas_register_client(&cpas_register_param);
if (rc) {
CAM_ERR(CAM_ISP, "nrdi CPAS registration failed rc=%d",
rc);
goto release_soc;
} else {
soc_private->cpas_handle[1] =
cpas_register_param.client_handle;
}
break;
default:
strlcpy(cpas_register_param.identifier, "ife",
CAM_HW_IDENTIFIER_LENGTH);
rc = cam_cpas_register_client(&cpas_register_param);
if (rc) {
CAM_ERR(CAM_ISP, "CPAS registration failed rc=%d", rc);
goto release_soc;
} else {
soc_private->cpas_handle[0] =
cpas_register_param.client_handle;
}
}
return rc;
release_soc:
cam_soc_util_release_platform_resource(soc_info);
free_soc_private:
kfree(soc_private);
return rc;
}
int ais_vfe_deinit_soc_resources(struct cam_hw_soc_info *soc_info)
{
int rc = 0;
struct ais_vfe_soc_private *soc_private;
if (!soc_info) {
CAM_ERR(CAM_ISP, "Error! soc_info NULL");
return -ENODEV;
}
soc_private = soc_info->soc_private;
if (!soc_private) {
CAM_ERR(CAM_ISP, "Error! soc_private NULL");
return -ENODEV;
}
rc = cam_cpas_unregister_client(soc_private->cpas_handle[0]);
if (rc)
CAM_ERR(CAM_ISP, "CPAS0 unregistration failed rc=%d", rc);
if (!rc && soc_private->cpas_version == CAM_CPAS_TITAN_175_V120)
rc = cam_cpas_unregister_client(soc_private->cpas_handle[1]);
if (rc)
CAM_ERR(CAM_ISP, "CPAS1 unregistration failed rc=%d",
rc);
rc = ais_vfe_release_platform_resource(soc_info);
if (rc < 0)
CAM_ERR(CAM_ISP,
"Error! Release platform resources failed rc=%d", rc);
rc = cam_soc_util_clk_put(&soc_private->dsp_clk);
if (rc < 0)
CAM_ERR(CAM_ISP,
"Error Put dsp clk failed rc=%d", rc);
kfree(soc_private);
return rc;
}
int ais_vfe_enable_soc_resources(struct cam_hw_soc_info *soc_info)
{
int rc = 0;
struct ais_vfe_soc_private *soc_private;
struct cam_ahb_vote ahb_vote;
struct cam_axi_vote axi_vote;
if (!soc_info) {
CAM_ERR(CAM_ISP, "Error! Invalid params");
rc = -EINVAL;
goto end;
}
soc_private = soc_info->soc_private;
ahb_vote.type = CAM_VOTE_ABSOLUTE;
ahb_vote.vote.level = CAM_SVS_VOTE;
axi_vote.compressed_bw = 10640000000L;
axi_vote.compressed_bw_ab = 10640000000L;
axi_vote.uncompressed_bw = 10640000000L;
rc = cam_cpas_start(soc_private->cpas_handle[0], &ahb_vote, &axi_vote);
if (rc) {
CAM_ERR(CAM_ISP, "Error! CPAS0 start failed rc=%d", rc);
rc = -EFAULT;
goto end;
}
if (!rc && soc_private->cpas_version == CAM_CPAS_TITAN_175_V120)
rc = cam_cpas_start(soc_private->cpas_handle[1], &ahb_vote,
&axi_vote);
if (rc) {
CAM_ERR(CAM_ISP, "Error! CPAS1 start failed rc=%d", rc);
rc = -EFAULT;
goto end;
}
rc = cam_soc_util_enable_platform_resource(soc_info, true,
CAM_TURBO_VOTE, true);
if (rc) {
CAM_ERR(CAM_ISP, "Error! enable platform failed rc=%d", rc);
goto stop_cpas;
}
return rc;
stop_cpas:
cam_cpas_stop(soc_private->cpas_handle[0]);
if (soc_private->cpas_version == CAM_CPAS_TITAN_175_V120)
cam_cpas_stop(soc_private->cpas_handle[1]);
end:
return rc;
}
int ais_vfe_soc_enable_clk(struct cam_hw_soc_info *soc_info,
const char *clk_name)
{
int rc = 0;
struct ais_vfe_soc_private *soc_private;
if (!soc_info) {
CAM_ERR(CAM_ISP, "Error Invalid params");
rc = -EINVAL;
return rc;
}
soc_private = soc_info->soc_private;
if (strcmp(clk_name, AIS_VFE_DSP_CLK_NAME) == 0) {
rc = cam_soc_util_clk_enable(soc_private->dsp_clk,
AIS_VFE_DSP_CLK_NAME, soc_private->dsp_clk_rate);
if (rc)
CAM_ERR(CAM_ISP,
"Error enable dsp clk failed rc=%d", rc);
}
return rc;
}
int ais_vfe_soc_disable_clk(struct cam_hw_soc_info *soc_info,
const char *clk_name)
{
int rc = 0;
struct ais_vfe_soc_private *soc_private;
if (!soc_info) {
CAM_ERR(CAM_ISP, "Error Invalid params");
rc = -EINVAL;
return rc;
}
soc_private = soc_info->soc_private;
if (strcmp(clk_name, AIS_VFE_DSP_CLK_NAME) == 0) {
rc = cam_soc_util_clk_disable(soc_private->dsp_clk,
AIS_VFE_DSP_CLK_NAME);
if (rc)
CAM_ERR(CAM_ISP,
"Error enable dsp clk failed rc=%d", rc);
}
return rc;
}
int ais_vfe_disable_soc_resources(struct cam_hw_soc_info *soc_info)
{
int rc = 0;
struct ais_vfe_soc_private *soc_private;
if (!soc_info) {
CAM_ERR(CAM_ISP, "Error! Invalid params");
rc = -EINVAL;
return rc;
}
soc_private = soc_info->soc_private;
rc = cam_soc_util_disable_platform_resource(soc_info, true, true);
if (rc) {
CAM_ERR(CAM_ISP, "Disable platform failed rc=%d", rc);
return rc;
}
rc = cam_cpas_stop(soc_private->cpas_handle[0]);
if (rc) {
CAM_ERR(CAM_ISP, "Error! CPAS stop failed rc=%d", rc);
return rc;
}
if (!rc && soc_private->cpas_version == CAM_CPAS_TITAN_175_V120)
rc = cam_cpas_stop(soc_private->cpas_handle[1]);
if (rc) {
CAM_ERR(CAM_ISP, "Error! CPAS stop failed rc=%d", rc);
return rc;
}
return rc;
}

View File

@@ -0,0 +1,124 @@
/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_VFE_SOC_H_
#define _AIS_VFE_SOC_H_
#include "cam_soc_util.h"
#include "ais_isp_hw.h"
#define AIS_VFE_DSP_CLK_NAME "ife_dsp_clk"
enum cam_cpas_handle_id {
CAM_CPAS_HANDLE_CAMIF,
CAM_CPAS_HANDLE_RAW,
CAM_CPAS_HANDLE_MAX,
};
/*
* struct ais_vfe_soc_private:
*
* @Brief: Private SOC data specific to VFE HW Driver
*
* @cpas_handle: Handle returned on registering with CPAS driver.
* This handle is used for all further interface
* with CPAS.
* @cpas_version: Has cpas version read from Hardware
*/
struct ais_vfe_soc_private {
uint32_t cpas_handle[CAM_CPAS_HANDLE_MAX];
uint32_t cpas_version;
struct clk *dsp_clk;
int32_t dsp_clk_index;
int32_t dsp_clk_rate;
};
/*
* ais_vfe_init_soc_resources()
*
* @Brief: Initialize SOC resources including private data
*
* @soc_info: Device soc information
* @handler: Irq handler function pointer
* @irq_data: Irq handler function Callback data
*
* @Return: 0: Success
* Non-zero: Failure
*/
int ais_vfe_init_soc_resources(struct cam_hw_soc_info *soc_info,
irq_handler_t vfe_irq_handler, void *irq_data);
/*
* ais_vfe_deinit_soc_resources()
*
* @Brief: Deinitialize SOC resources including private data
*
* @soc_info: Device soc information
*
* @Return: 0: Success
* Non-zero: Failure
*/
int ais_vfe_deinit_soc_resources(struct cam_hw_soc_info *soc_info);
/*
* ais_vfe_enable_soc_resources()
*
* @brief: Enable regulator, irq resources, start CPAS
*
* @soc_info: Device soc information
*
* @Return: 0: Success
* Non-zero: Failure
*/
int ais_vfe_enable_soc_resources(struct cam_hw_soc_info *soc_info);
/*
* ais_vfe_disable_soc_resources()
*
* @brief: Disable regulator, irq resources, stop CPAS
*
* @soc_info: Device soc information
*
* @Return: 0: Success
* Non-zero: Failure
*/
int ais_vfe_disable_soc_resources(struct cam_hw_soc_info *soc_info);
/*
* ais_vfe_soc_enable_clk()
*
* @brief: Enable clock with given name
*
* @soc_info: Device soc information
* @clk_name: Name of clock to enable
*
* @Return: 0: Success
* Non-zero: Failure
*/
int ais_vfe_soc_enable_clk(struct cam_hw_soc_info *soc_info,
const char *clk_name);
/*
* ais_vfe_soc_disable_dsp_clk()
*
* @brief: Disable clock with given name
*
* @soc_info: Device soc information
* @clk_name: Name of clock to enable
*
* @Return: 0: Success
* Non-zero: Failure
*/
int ais_vfe_soc_disable_clk(struct cam_hw_soc_info *soc_info,
const char *clk_name);
#endif /* _AIS_VFE_SOC_H_ */

View File

@@ -0,0 +1,14 @@
ccflags-y += -Idrivers/media/platform/msm/ais/cam_utils
ccflags-y += -Idrivers/media/platform/msm/ais/cam_core
ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp/include
ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp/include
ccflags-y += -Idrivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/hw_utils/include
ccflags-y += -Idrivers/media/platform/msm/ais/cam_isp/isp_hw_mgr/hw_utils/irq_controller
ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp/vfe_hw/include
ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp/vfe_hw/vfe_bus/include
ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp/vfe_hw/vfe_top/include
ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp/vfe_hw/vfe_top
ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp/vfe_hw/vfe_bus
ccflags-y += -Idrivers/media/platform/msm/ais/ais_isp/vfe_hw
obj-$(CONFIG_MSM_AIS) += ais_vfe17x.o

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,71 @@
/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include <linux/module.h>
#include "ais_vfe170.h"
#include "ais_vfe175.h"
#include "ais_vfe175_130.h"
#include "ais_vfe_lite17x.h"
#include "ais_vfe_hw_intf.h"
#include "ais_vfe_core.h"
#include "ais_vfe_dev.h"
static const struct of_device_id ais_vfe_dt_match[] = {
{
.compatible = "qcom,ais-vfe170",
.data = &ais_vfe170_hw_info,
},
{
.compatible = "qcom,ais-vfe175",
.data = &ais_vfe175_hw_info,
},
{
.compatible = "qcom,ais-vfe175_130",
.data = &ais_vfe175_130_hw_info,
},
{
.compatible = "qcom,ais-vfe-lite170",
.data = &ais_vfe_lite17x_hw_info,
},
{
.compatible = "qcom,ais-vfe-lite175",
.data = &ais_vfe_lite17x_hw_info,
},
{}
};
MODULE_DEVICE_TABLE(of, ais_vfe_dt_match);
static struct platform_driver ais_vfe_driver = {
.probe = ais_vfe_probe,
.remove = ais_vfe_remove,
.driver = {
.name = "ais_vfe17x",
.owner = THIS_MODULE,
.of_match_table = ais_vfe_dt_match,
.suppress_bind_attrs = true,
},
};
static int __init ais_vfe_init_module(void)
{
return platform_driver_register(&ais_vfe_driver);
}
static void __exit ais_vfe_exit_module(void)
{
platform_driver_unregister(&ais_vfe_driver);
}
module_init(ais_vfe_init_module);
module_exit(ais_vfe_exit_module);
MODULE_DESCRIPTION("AIS VFE17X driver");
MODULE_LICENSE("GPL v2");

View File

@@ -0,0 +1,334 @@
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_VFE_LITE17X_H_
#define _AIS_VFE_LITE17X_H_
#include "ais_vfe_core.h"
static struct ais_irq_register_set vfe17x_top_irq_reg_set[2] = {
{
.mask_reg_offset = 0x0000005C,
.clear_reg_offset = 0x00000064,
.status_reg_offset = 0x0000006C,
},
{
.mask_reg_offset = 0x00000060,
.clear_reg_offset = 0x00000068,
.status_reg_offset = 0x00000070,
},
};
static struct ais_irq_controller_reg_info vfe17x_top_irq_reg_info = {
.num_registers = 2,
.irq_reg_set = vfe17x_top_irq_reg_set,
.global_clear_offset = 0x00000058,
.global_clear_bitmask = 0x00000001,
};
static struct ais_vfe_top_ver2_reg_offset_common vfe17x_top_common_reg = {
.hw_version = 0x00000000,
.hw_capability = 0x00000004,
.lens_feature = 0x00000008,
.stats_feature = 0x0000000C,
.color_feature = 0x00000010,
.zoom_feature = 0x00000014,
.global_reset_cmd = 0x00000018,
.module_ctrl = {
NULL,
NULL,
NULL,
NULL,
},
.bus_cgc_ovd = 0x0000003C,
.core_cfg = 0x00000000,
.three_D_cfg = 0x00000000,
.violation_status = 0x0000007C,
.reg_update_cmd = 0x000004AC,
};
static struct ais_vfe_rdi_ver2_reg vfe17x_rdi_reg = {
.reg_update_cmd = 0x000004AC,
};
static struct ais_vfe_rdi_reg_data vfe17x_rdi_0_data = {
.reg_update_cmd_data = 0x2,
.sof_irq_mask = 0x8000000,
.reg_update_irq_mask = 0x20,
};
static struct ais_vfe_rdi_reg_data vfe17x_rdi_1_data = {
.reg_update_cmd_data = 0x4,
.sof_irq_mask = 0x10000000,
.reg_update_irq_mask = 0x40,
};
static struct ais_vfe_rdi_reg_data vfe17x_rdi_2_data = {
.reg_update_cmd_data = 0x8,
.sof_irq_mask = 0x20000000,
.reg_update_irq_mask = 0x80,
};
static struct ais_vfe_rdi_reg_data vfe17x_rdi_3_data = {
.reg_update_cmd_data = 0x10,
.sof_irq_mask = 0x40000000,
.reg_update_irq_mask = 0x100,
};
static struct ais_vfe_top_ver2_hw_info vfe17x_top_hw_info = {
.common_reg = &vfe17x_top_common_reg,
.camif_hw_info = {
.common_reg = NULL,
.camif_reg = NULL,
.reg_data = NULL,
},
.rdi_hw_info = {
.common_reg = &vfe17x_top_common_reg,
.rdi_reg = &vfe17x_rdi_reg,
.reg_data = {
&vfe17x_rdi_0_data,
&vfe17x_rdi_1_data,
&vfe17x_rdi_2_data,
&vfe17x_rdi_3_data,
},
},
.mux_type = {
AIS_VFE_RDI_VER_1_0,
AIS_VFE_RDI_VER_1_0,
AIS_VFE_RDI_VER_1_0,
AIS_VFE_RDI_VER_1_0,
},
};
static struct ais_irq_register_set vfe17x_bus_irq_reg[3] = {
{
.mask_reg_offset = 0x00002044,
.clear_reg_offset = 0x00002050,
.status_reg_offset = 0x0000205C,
},
{
.mask_reg_offset = 0x00002048,
.clear_reg_offset = 0x00002054,
.status_reg_offset = 0x00002060,
},
{
.mask_reg_offset = 0x0000204C,
.clear_reg_offset = 0x00002058,
.status_reg_offset = 0x00002064,
},
};
static struct ais_vfe_bus_ver2_hw_info vfe17x_bus_hw_info = {
.common_reg = {
.hw_version = 0x00002000,
.hw_capability = 0x00002004,
.sw_reset = 0x00002008,
.cgc_ovd = 0x0000200C,
.pwr_iso_cfg = 0x000020CC,
.dual_master_comp_cfg = 0x00002028,
.irq_reg_info = {
.num_registers = 3,
.irq_reg_set = vfe17x_bus_irq_reg,
.global_clear_offset = 0x00002068,
.global_clear_bitmask = 0x00000001,
},
.comp_error_status = 0x0000206C,
.comp_ovrwr_status = 0x00002070,
.dual_comp_error_status = 0x00002074,
.dual_comp_ovrwr_status = 0x00002078,
.addr_sync_cfg = 0x0000207C,
.addr_sync_frame_hdr = 0x00002080,
.addr_sync_no_sync = 0x00002084,
},
.num_client = 4,
.is_lite = 1,
.bus_client_reg = {
/* BUS Client 0 */
{
.status0 = 0x00002200,
.status1 = 0x00002204,
.cfg = 0x00002208,
.header_addr = 0x0000220C,
.header_cfg = 0x00002210,
.image_addr = 0x00002214,
.image_addr_offset = 0x00002218,
.buffer_width_cfg = 0x0000221C,
.buffer_height_cfg = 0x00002220,
.packer_cfg = 0x00002224,
.stride = 0x00002228,
.irq_subsample_period = 0x00002248,
.irq_subsample_pattern = 0x0000224C,
.framedrop_period = 0x00002250,
.framedrop_pattern = 0x00002254,
.frame_inc = 0x00002258,
.burst_limit = 0x0000225C,
.ubwc_regs = NULL,
},
/* BUS Client 1 */
{
.status0 = 0x00002300,
.status1 = 0x00002304,
.cfg = 0x00002308,
.header_addr = 0x0000230C,
.header_cfg = 0x00002310,
.image_addr = 0x00002314,
.image_addr_offset = 0x00002318,
.buffer_width_cfg = 0x0000231C,
.buffer_height_cfg = 0x00002320,
.packer_cfg = 0x00002324,
.stride = 0x00002328,
.irq_subsample_period = 0x00002348,
.irq_subsample_pattern = 0x0000234C,
.framedrop_period = 0x00002350,
.framedrop_pattern = 0x00002354,
.frame_inc = 0x00002358,
.burst_limit = 0x0000235C,
.ubwc_regs = NULL,
},
/* BUS Client 2 */
{
.status0 = 0x00002400,
.status1 = 0x00002404,
.cfg = 0x00002408,
.header_addr = 0x0000240C,
.header_cfg = 0x00002410,
.image_addr = 0x00002414,
.image_addr_offset = 0x00002418,
.buffer_width_cfg = 0x0000241C,
.buffer_height_cfg = 0x00002420,
.packer_cfg = 0x00002424,
.stride = 0x00002428,
.irq_subsample_period = 0x00002448,
.irq_subsample_pattern = 0x0000244C,
.framedrop_period = 0x00002450,
.framedrop_pattern = 0x00002454,
.frame_inc = 0x00002458,
.burst_limit = 0x0000245C,
.ubwc_regs = NULL,
},
/* BUS Client 3 */
{
.status0 = 0x00002500,
.status1 = 0x00002504,
.cfg = 0x00002508,
.header_addr = 0x0000250C,
.header_cfg = 0x00002510,
.image_addr = 0x00002514,
.image_addr_offset = 0x00002518,
.buffer_width_cfg = 0x0000251C,
.buffer_height_cfg = 0x00002520,
.packer_cfg = 0x00002524,
.stride = 0x00002528,
.irq_subsample_period = 0x00002548,
.irq_subsample_pattern = 0x0000254C,
.framedrop_period = 0x00002550,
.framedrop_pattern = 0x00002554,
.frame_inc = 0x00002558,
.burst_limit = 0x0000255C,
.ubwc_regs = NULL,
},
},
.comp_grp_reg = {
/* AIS_VFE_BUS_VER2_COMP_GRP_0 */
{
.comp_mask = 0x00002010,
},
/* AIS_VFE_BUS_VER2_COMP_GRP_1 */
{
.comp_mask = 0x00002014,
},
/* AIS_VFE_BUS_VER2_COMP_GRP_2 */
{
.comp_mask = 0x00002018,
},
/* AIS_VFE_BUS_VER2_COMP_GRP_3 */
{
.comp_mask = 0x0000201C,
},
/* AIS_VFE_BUS_VER2_COMP_GRP_4 */
{
.comp_mask = 0x00002020,
},
/* AIS_VFE_BUS_VER2_COMP_GRP_5 */
{
.comp_mask = 0x00002024,
},
/* AIS_VFE_BUS_VER2_COMP_GRP_DUAL_0 */
{
.comp_mask = 0x0000202C,
.addr_sync_mask = 0x00002088,
},
/* AIS_VFE_BUS_VER2_COMP_GRP_DUAL_1 */
{
.comp_mask = 0x00002030,
.addr_sync_mask = 0x0000208C,
},
/* AIS_VFE_BUS_VER2_COMP_GRP_DUAL_2 */
{
.comp_mask = 0x00002034,
.addr_sync_mask = 0x00002090,
},
/* AIS_VFE_BUS_VER2_COMP_GRP_DUAL_3 */
{
.comp_mask = 0x00002038,
.addr_sync_mask = 0x00002094,
},
/* AIS_VFE_BUS_VER2_COMP_GRP_DUAL_4 */
{
.comp_mask = 0x0000203C,
.addr_sync_mask = 0x00002098,
},
/* AIS_VFE_BUS_VER2_COMP_GRP_DUAL_5 */
{
.comp_mask = 0x00002040,
.addr_sync_mask = 0x0000209C,
},
},
.num_out = 4,
.vfe_out_hw_info = {
{
.vfe_out_type = AIS_VFE_BUS_VER2_VFE_OUT_RDI0,
.max_width = -1,
.max_height = -1,
},
{
.vfe_out_type = AIS_VFE_BUS_VER2_VFE_OUT_RDI1,
.max_width = -1,
.max_height = -1,
},
{
.vfe_out_type = AIS_VFE_BUS_VER2_VFE_OUT_RDI2,
.max_width = -1,
.max_height = -1,
},
{
.vfe_out_type = AIS_VFE_BUS_VER2_VFE_OUT_RDI3,
.max_width = -1,
.max_height = -1,
},
},
};
static struct ais_vfe_hw_info ais_vfe_lite17x_hw_info = {
.irq_reg_info = &vfe17x_top_irq_reg_info,
.bus_version = AIS_VFE_BUS_VER_2_0,
.bus_hw_info = &vfe17x_bus_hw_info,
.top_version = AIS_VFE_TOP_VER_2_0,
.top_hw_info = &vfe17x_top_hw_info,
};
#endif /* _AIS_VFE_LITE17X_H_ */

View File

@@ -0,0 +1,107 @@
/* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_VFE_BUS_R_VER1_H_
#define _AIS_VFE_BUS_R_VER1_H_
#include "ais_vfe_bus.h"
#define AIS_VFE_BUS_RD_VER1_MAX_CLIENTS 1
enum ais_vfe_bus_rd_ver1_vfe_core_id {
AIS_VFE_BUS_RD_VER1_VFE_CORE_0,
AIS_VFE_BUS_RD_VER1_VFE_CORE_1,
AIS_VFE_BUS_RD_VER1_VFE_CORE_MAX,
};
enum ais_vfe_bus_rd_ver1_comp_grp_type {
AIS_VFE_BUS_RD_VER1_COMP_GRP_0,
AIS_VFE_BUS_RD_VER1_COMP_GRP_MAX,
};
enum ais_vfe_bus_rd_ver1_vfe_bus_rd_type {
AIS_VFE_BUS_RD_VER1_VFE_BUSRD_RDI0,
AIS_VFE_BUS_RD_VER1_VFE_BUSRD_MAX,
};
/*
* struct ais_vfe_bus_rd_ver1_reg_offset_common:
*
* @Brief: Common registers across all BUS Clients
*/
struct ais_vfe_bus_rd_ver1_reg_offset_common {
uint32_t hw_version;
uint32_t hw_capability;
uint32_t sw_reset;
uint32_t cgc_ovd;
uint32_t pwr_iso_cfg;
uint32_t input_if_cmd;
uint32_t test_bus_ctrl;
struct ais_irq_controller_reg_info irq_reg_info;
};
/*
* struct ais_vfe_bus_rd_ver1_reg_offset_bus_client:
*
* @Brief: Register offsets for BUS Clients
*/
struct ais_vfe_bus_rd_ver1_reg_offset_bus_client {
uint32_t status0;
uint32_t status1;
uint32_t cfg;
uint32_t header_addr;
uint32_t header_cfg;
uint32_t image_addr;
uint32_t image_addr_offset;
uint32_t buffer_width_cfg;
uint32_t buffer_height_cfg;
uint32_t unpacker_cfg;
uint32_t stride;
void *ubwc_regs;
uint32_t burst_limit;
uint32_t latency_buf_allocation;
uint32_t buf_size;
};
/*
* struct ais_vfe_bus_rd_ver1_vfe_bus_hw_info:
*
* @Brief: HW capability of VFE Bus Client
*/
struct ais_vfe_bus_rd_ver1_vfe_bus_hw_info {
enum ais_vfe_bus_rd_ver1_vfe_bus_rd_type vfe_bus_rd_type;
uint32_t max_width;
uint32_t max_height;
};
/*
* struct ais_vfe_bus_rd_ver1_hw_info:
*
* @Brief: HW register info for entire Bus
*
* @common_reg: Common register details
* @bus_client_reg: Bus client register info
* @comp_reg_grp: Composite group register info
* @vfe_out_hw_info: VFE output capability
*/
struct ais_vfe_bus_rd_ver1_hw_info {
struct ais_vfe_bus_rd_ver1_reg_offset_common common_reg;
uint32_t num_client;
struct ais_vfe_bus_rd_ver1_reg_offset_bus_client
bus_client_reg[AIS_VFE_BUS_RD_VER1_MAX_CLIENTS];
uint32_t num_bus_rd_resc;
struct ais_vfe_bus_rd_ver1_vfe_bus_hw_info
vfe_bus_rd_hw_info[AIS_VFE_BUS_RD_VER1_VFE_BUSRD_MAX];
};
#endif /* _AIS_VFE_BUS_R_VER1_H_ */

View File

@@ -0,0 +1,100 @@
/* Copyright (c) 2017-2018, 2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_VFE_BUS_VER1_H_
#define _AIS_VFE_BUS_VER1_H_
enum ais_vfe_bus_ver1_pingpong_id {
AIS_VFE_BUS_VER1_PING,
AIS_VFE_BUS_VER1_PONG,
AIS_VFE_BUS_VER1_PINGPONG_MAX,
};
enum ais_vfe_bus_ver1_wm_type {
AIS_VFE_BUS_WM_TYPE_IMAGE,
AIS_VFE_BUS_WM_TYPE_STATS,
AIS_VFE_BUS_WM_TYPE_MAX,
};
enum ais_vfe_bus_ver1_comp_grp_type {
AIS_VFE_BUS_VER1_COMP_GRP_IMG0,
AIS_VFE_BUS_VER1_COMP_GRP_IMG1,
AIS_VFE_BUS_VER1_COMP_GRP_IMG2,
AIS_VFE_BUS_VER1_COMP_GRP_IMG3,
AIS_VFE_BUS_VER1_COMP_GRP_STATS0,
AIS_VFE_BUS_VER1_COMP_GRP_STATS1,
AIS_VFE_BUS_VER1_COMP_GRP_MAX,
};
struct ais_vfe_bus_ver1_common_reg {
uint32_t cmd_offset;
uint32_t cfg_offset;
uint32_t io_fmt_offset;
uint32_t argb_cfg_offset;
uint32_t xbar_cfg0_offset;
uint32_t xbar_cfg1_offset;
uint32_t xbar_cfg2_offset;
uint32_t xbar_cfg3_offset;
uint32_t ping_pong_status_reg;
};
struct ais_vfe_bus_ver1_wm_reg {
uint32_t wm_cfg_offset;
uint32_t ping_addr_offset;
uint32_t ping_max_addr_offset;
uint32_t pong_addr_offset;
uint32_t pong_max_addr_offset;
uint32_t addr_cfg_offset;
uint32_t ub_cfg_offset;
uint32_t image_size_offset;
uint32_t buffer_cfg_offset;
uint32_t framedrop_pattern_offset;
uint32_t irq_subsample_pattern_offset;
uint32_t ping_pong_status_bit; /* 0 - 31 */
uint32_t composite_bit; /* 0 -31 */
};
struct ais_vfe_bus_ver1_wm_resource_data {
uint32_t index;
uint32_t wm_type;
uint32_t res_type;
uint32_t offset;
uint32_t width;
uint32_t height;
uint32_t stride;
uint32_t scanline;
uint32_t burst_len;
uint32_t framedrop_period;
uint32_t framedrop_pattern;
uint32_t buf_valid[AIS_VFE_BUS_VER1_PINGPONG_MAX];
uint32_t ub_size;
uint32_t ub_offset;
struct ais_vfe_bus_ver1_wm_reg hw_regs;
};
struct ais_vfe_bus_ver1_comp_grp_reg {
enum ais_vfe_bus_ver1_comp_grp_type comp_grp_type;
uint32_t comp_grp_offset;
};
struct ais_vfe_bus_ver1_comp_grp {
struct ais_vfe_bus_ver1_comp_grp_reg reg_info;
struct list_head wm_list;
uint32_t cur_bit_mask;
};
#endif /* _AIS_VFE_BUS_VER1_H_ */

View File

@@ -0,0 +1,250 @@
/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_VFE_BUS_VER2_H_
#define _AIS_VFE_BUS_VER2_H_
#include "ais_vfe_bus.h"
#define AIS_VFE_BUS_VER2_MAX_CLIENTS 24
#define AIS_VFE_BUS_ENABLE_DMI_DUMP BIT(0)
#define AIS_VFE_BUS_ENABLE_STATS_REG_DUMP BIT(1)
enum ais_vfe_bus_ver2_vfe_core_id {
AIS_VFE_BUS_VER2_VFE_CORE_0,
AIS_VFE_BUS_VER2_VFE_CORE_1,
AIS_VFE_BUS_VER2_VFE_CORE_MAX,
};
enum ais_vfe_bus_ver2_comp_grp_type {
AIS_VFE_BUS_VER2_COMP_GRP_0,
AIS_VFE_BUS_VER2_COMP_GRP_1,
AIS_VFE_BUS_VER2_COMP_GRP_2,
AIS_VFE_BUS_VER2_COMP_GRP_3,
AIS_VFE_BUS_VER2_COMP_GRP_4,
AIS_VFE_BUS_VER2_COMP_GRP_5,
AIS_VFE_BUS_VER2_COMP_GRP_DUAL_0,
AIS_VFE_BUS_VER2_COMP_GRP_DUAL_1,
AIS_VFE_BUS_VER2_COMP_GRP_DUAL_2,
AIS_VFE_BUS_VER2_COMP_GRP_DUAL_3,
AIS_VFE_BUS_VER2_COMP_GRP_DUAL_4,
AIS_VFE_BUS_VER2_COMP_GRP_DUAL_5,
AIS_VFE_BUS_VER2_COMP_GRP_MAX,
};
enum ais_vfe_bus_ver2_vfe_out_type {
AIS_VFE_BUS_VER2_VFE_OUT_RDI0,
AIS_VFE_BUS_VER2_VFE_OUT_RDI1,
AIS_VFE_BUS_VER2_VFE_OUT_RDI2,
AIS_VFE_BUS_VER2_VFE_OUT_RDI3,
AIS_VFE_BUS_VER2_VFE_OUT_FULL,
AIS_VFE_BUS_VER2_VFE_OUT_DS4,
AIS_VFE_BUS_VER2_VFE_OUT_DS16,
AIS_VFE_BUS_VER2_VFE_OUT_RAW_DUMP,
AIS_VFE_BUS_VER2_VFE_OUT_FD,
AIS_VFE_BUS_VER2_VFE_OUT_PDAF,
AIS_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BE,
AIS_VFE_BUS_VER2_VFE_OUT_STATS_HDR_BHIST,
AIS_VFE_BUS_VER2_VFE_OUT_STATS_TL_BG,
AIS_VFE_BUS_VER2_VFE_OUT_STATS_BF,
AIS_VFE_BUS_VER2_VFE_OUT_STATS_AWB_BG,
AIS_VFE_BUS_VER2_VFE_OUT_STATS_BHIST,
AIS_VFE_BUS_VER2_VFE_OUT_STATS_RS,
AIS_VFE_BUS_VER2_VFE_OUT_STATS_CS,
AIS_VFE_BUS_VER2_VFE_OUT_STATS_IHIST,
AIS_VFE_BUS_VER2_VFE_OUT_FULL_DISP,
AIS_VFE_BUS_VER2_VFE_OUT_DS4_DISP,
AIS_VFE_BUS_VER2_VFE_OUT_DS16_DISP,
AIS_VFE_BUS_VER2_VFE_OUT_2PD,
AIS_VFE_BUS_VER2_VFE_OUT_MAX,
};
struct ais_vfe_bus_ver2_dmi_lut_bank_info {
uint32_t size;
uint32_t bank_0;
uint32_t bank_1;
};
struct ais_vfe_bus_ver2_stats_cfg_offset {
uint32_t res_index;
uint32_t cfg_offset;
uint32_t num_cfg;
uint32_t cfg_size;
uint32_t is_lut;
struct ais_vfe_bus_ver2_dmi_lut_bank_info lut;
};
struct ais_vfe_bus_ver2_dmi_offset_common {
uint32_t auto_increment;
uint32_t cfg_offset;
uint32_t addr_offset;
uint32_t data_hi_offset;
uint32_t data_lo_offset;
};
struct ais_vfe_bus_ver2_stats_cfg_info {
struct ais_vfe_bus_ver2_dmi_offset_common
dmi_offset_info;
struct ais_vfe_bus_ver2_stats_cfg_offset
stats_cfg_offset[AIS_VFE_BUS_VER2_VFE_OUT_MAX];
};
/*
* struct ais_vfe_bus_ver2_reg_offset_common:
*
* @Brief: Common registers across all BUS Clients
*/
struct ais_vfe_bus_ver2_reg_offset_common {
uint32_t hw_version;
uint32_t hw_capability;
uint32_t sw_reset;
uint32_t cgc_ovd;
uint32_t pwr_iso_cfg;
uint32_t dual_master_comp_cfg;
struct ais_irq_controller_reg_info irq_reg_info;
uint32_t comp_error_status;
uint32_t comp_ovrwr_status;
uint32_t dual_comp_error_status;
uint32_t dual_comp_ovrwr_status;
uint32_t addr_sync_cfg;
uint32_t addr_sync_frame_hdr;
uint32_t addr_sync_no_sync;
uint32_t debug_status_cfg;
uint32_t debug_status_0;
};
/*
* struct ais_vfe_bus_ver2_reg_offset_ubwc_client:
*
* @Brief: UBWC register offsets for BUS Clients
*/
struct ais_vfe_bus_ver2_reg_offset_ubwc_client {
uint32_t tile_cfg;
uint32_t h_init;
uint32_t v_init;
uint32_t meta_addr;
uint32_t meta_offset;
uint32_t meta_stride;
uint32_t mode_cfg_0;
uint32_t bw_limit;
};
/*
* struct ais_vfe_bus_ver2_reg_offset_ubwc_client:
*
* @Brief: UBWC register offsets for BUS Clients
*/
struct ais_vfe_bus_ver2_reg_offset_ubwc_3_client {
uint32_t tile_cfg;
uint32_t h_init;
uint32_t v_init;
uint32_t meta_addr;
uint32_t meta_offset;
uint32_t meta_stride;
uint32_t mode_cfg_0;
uint32_t mode_cfg_1;
uint32_t bw_limit;
uint32_t threshlod_lossy_0;
uint32_t threshlod_lossy_1;
};
/*
* struct ais_vfe_bus_ver2_reg_offset_bus_client:
*
* @Brief: Register offsets for BUS Clients
*/
struct ais_vfe_bus_ver2_reg_offset_bus_client {
uint32_t status0;
uint32_t status1;
uint32_t cfg;
uint32_t header_addr;
uint32_t header_cfg;
uint32_t image_addr;
uint32_t image_addr_offset;
uint32_t buffer_width_cfg;
uint32_t buffer_height_cfg;
uint32_t packer_cfg;
uint32_t stride;
uint32_t irq_subsample_period;
uint32_t irq_subsample_pattern;
uint32_t framedrop_period;
uint32_t framedrop_pattern;
uint32_t frame_inc;
uint32_t burst_limit;
void *ubwc_regs;
};
/*
* struct ais_vfe_bus_ver2_reg_offset_comp_grp:
*
* @Brief: Register offsets for Composite Group registers
* comp_mask: Comp group register address
* addr_sync_mask:Address sync group register address
*/
struct ais_vfe_bus_ver2_reg_offset_comp_grp {
uint32_t comp_mask;
uint32_t addr_sync_mask;
};
/*
* struct ais_vfe_bus_ver2_vfe_out_hw_info:
*
* @Brief: HW capability of VFE Bus Client
*/
struct ais_vfe_bus_ver2_vfe_out_hw_info {
enum ais_vfe_bus_ver2_vfe_out_type vfe_out_type;
uint32_t max_width;
uint32_t max_height;
};
/*
* struct ais_vfe_bus_ver2_reg_data:
*
* @Brief: Holds the bus register data
*/
struct ais_vfe_bus_ver2_reg_data {
uint32_t ubwc_10bit_threshold_lossy_0;
uint32_t ubwc_10bit_threshold_lossy_1;
uint32_t ubwc_8bit_threshold_lossy_0;
uint32_t ubwc_8bit_threshold_lossy_1;
};
/*
* struct ais_vfe_bus_ver2_hw_info:
*
* @Brief: HW register info for entire Bus
*
* @common_reg: Common register details
* @bus_client_reg: Bus client register info
* @comp_reg_grp: Composite group register info
* @vfe_out_hw_info: VFE output capability
* @reg_data: bus register data;
*/
struct ais_vfe_bus_ver2_hw_info {
struct ais_vfe_bus_ver2_reg_offset_common common_reg;
uint32_t num_client;
uint32_t is_lite;
struct ais_vfe_bus_ver2_reg_offset_bus_client
bus_client_reg[AIS_VFE_BUS_VER2_MAX_CLIENTS];
struct ais_vfe_bus_ver2_reg_offset_comp_grp
comp_grp_reg[AIS_VFE_BUS_VER2_COMP_GRP_MAX];
uint32_t num_out;
struct ais_vfe_bus_ver2_vfe_out_hw_info
vfe_out_hw_info[AIS_VFE_BUS_VER2_VFE_OUT_MAX];
struct ais_vfe_bus_ver2_reg_data reg_data;
struct ais_vfe_bus_ver2_stats_cfg_info *stats_data;
};
#endif /* _AIS_VFE_BUS_VER2_H_ */

View File

@@ -0,0 +1,25 @@
/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_VFE_BUS_H_
#define _AIS_VFE_BUS_H_
#include <uapi/media/ais_isp.h>
#include <uapi/media/cam_isp.h>
#include "cam_hw_intf.h"
#include "ais_isp_hw.h"
#define AIS_VFE_BUS_VER_1_0 0x1000
#define AIS_VFE_BUS_VER_2_0 0x2000
#define AIS_VFE_BUS_RD_VER_4_0 0x4000
#endif /* _AIS_VFE_BUS_ */

View File

@@ -0,0 +1,46 @@
/* Copyright (c) 2018, 2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_VFE_CAMIF_LITE_VER2_H_
#define _AIS_VFE_CAMIF_LITE_VER2_H_
#include "ais_vfe_top.h"
struct ais_vfe_camif_lite_ver2_reg {
uint32_t camif_lite_cmd;
uint32_t camif_lite_config;
uint32_t lite_skip_period;
uint32_t lite_irq_subsample_pattern;
uint32_t lite_epoch_irq;
uint32_t reg_update_cmd;
};
struct ais_vfe_camif_lite_ver2_reg_data {
uint32_t dual_pd_reg_update_cmd_data;
uint32_t lite_epoch_line_cfg;
uint32_t lite_sof_irq_mask;
uint32_t lite_epoch0_irq_mask;
uint32_t dual_pd_reg_upd_irq_mask;
uint32_t lite_eof_irq_mask;
uint32_t lite_error_irq_mask0;
uint32_t lite_error_irq_mask1;
uint32_t extern_reg_update_shift;
uint32_t dual_pd_path_sel_shift;
};
struct ais_vfe_camif_lite_ver2_hw_info {
struct ais_vfe_top_ver2_reg_offset_common *common_reg;
struct ais_vfe_camif_lite_ver2_reg *camif_lite_reg;
struct ais_vfe_camif_lite_ver2_reg_data *reg_data;
};
#endif /* _AIS_VFE_CAMIF_LITE_VER2_H_ */

View File

@@ -0,0 +1,82 @@
/* Copyright (c) 2017-2018, 2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_VFE_CAMIF_VER2_H_
#define _AIS_VFE_CAMIF_VER2_H_
#include "ais_vfe_top.h"
/*
* Debug values for camif module
*/
#define CAMIF_DEBUG_ENABLE_SENSOR_DIAG_STATUS BIT(0)
struct ais_vfe_camif_ver2_reg {
uint32_t camif_cmd;
uint32_t camif_config;
uint32_t line_skip_pattern;
uint32_t pixel_skip_pattern;
uint32_t skip_period;
uint32_t irq_subsample_pattern;
uint32_t epoch_irq;
uint32_t raw_crop_width_cfg;
uint32_t raw_crop_height_cfg;
uint32_t reg_update_cmd;
uint32_t vfe_diag_config;
uint32_t vfe_diag_sensor_status;
};
struct ais_vfe_camif_reg_data {
uint32_t raw_crop_first_pixel_shift;
uint32_t raw_crop_first_pixel_mask;
uint32_t raw_crop_last_pixel_shift;
uint32_t raw_crop_last_pixel_mask;
uint32_t raw_crop_first_line_shift;
uint32_t raw_crop_first_line_mask;
uint32_t raw_crop_last_line_shift;
uint32_t raw_crop_last_line_mask;
uint32_t input_mux_sel_shift;
uint32_t input_mux_sel_mask;
uint32_t extern_reg_update_shift;
uint32_t extern_reg_update_mask;
uint32_t pixel_pattern_shift;
uint32_t pixel_pattern_mask;
uint32_t dsp_mode_shift;
uint32_t dsp_mode_mask;
uint32_t dsp_en_shift;
uint32_t dsp_en_mask;
uint32_t reg_update_cmd_data;
uint32_t epoch_line_cfg;
uint32_t sof_irq_mask;
uint32_t epoch0_irq_mask;
uint32_t reg_update_irq_mask;
uint32_t eof_irq_mask;
uint32_t error_irq_mask0;
uint32_t error_irq_mask1;
uint32_t enable_diagnostic_hw;
};
struct ais_vfe_camif_ver2_hw_info {
struct ais_vfe_top_ver2_reg_offset_common *common_reg;
struct ais_vfe_camif_ver2_reg *camif_reg;
struct ais_vfe_camif_reg_data *reg_data;
};
#endif /* _AIS_VFE_CAMIF_VER2_H_ */

View File

@@ -0,0 +1,80 @@
/* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_VFE_FE_VER1_H_
#define _AIS_VFE_FE_VER1_H_
#include "ais_vfe_top.h"
struct ais_vfe_fe_ver1_reg {
uint32_t camif_cmd;
uint32_t camif_config;
uint32_t line_skip_pattern;
uint32_t pixel_skip_pattern;
uint32_t skip_period;
uint32_t irq_subsample_pattern;
uint32_t epoch_irq;
uint32_t raw_crop_width_cfg;
uint32_t raw_crop_height_cfg;
uint32_t reg_update_cmd;
uint32_t vfe_diag_config;
uint32_t vfe_diag_sensor_status;
uint32_t fe_cfg;
};
struct ais_vfe_fe_reg_data {
uint32_t raw_crop_first_pixel_shift;
uint32_t raw_crop_first_pixel_mask;
uint32_t raw_crop_last_pixel_shift;
uint32_t raw_crop_last_pixel_mask;
uint32_t raw_crop_first_line_shift;
uint32_t raw_crop_first_line_mask;
uint32_t raw_crop_last_line_shift;
uint32_t raw_crop_last_line_mask;
uint32_t input_mux_sel_shift;
uint32_t input_mux_sel_mask;
uint32_t extern_reg_update_shift;
uint32_t extern_reg_update_mask;
uint32_t pixel_pattern_shift;
uint32_t pixel_pattern_mask;
uint32_t dsp_mode_shift;
uint32_t dsp_mode_mask;
uint32_t dsp_en_shift;
uint32_t dsp_en_mask;
uint32_t reg_update_cmd_data;
uint32_t epoch_line_cfg;
uint32_t sof_irq_mask;
uint32_t epoch0_irq_mask;
uint32_t reg_update_irq_mask;
uint32_t eof_irq_mask;
uint32_t error_irq_mask0;
uint32_t error_irq_mask1;
uint32_t enable_diagnostic_hw;
uint32_t fe_mux_data;
uint32_t hbi_cnt_shift;
};
struct ais_vfe_fe_ver1_hw_info {
struct ais_vfe_top_ver2_reg_offset_common *common_reg;
struct ais_vfe_fe_ver1_reg *fe_reg;
struct ais_vfe_fe_reg_data *reg_data;
};
#endif /* _AIS_VFE_FE_VER1_H_ */

View File

@@ -0,0 +1,36 @@
/* Copyright (c) 2017-2018, 2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_VFE_RDI_H_
#define _AIS_VFE_RDI_H_
#include "ais_vfe_top.h"
#define AIS_VFE_RDI_VER2_MAX 4
struct ais_vfe_rdi_ver2_reg {
uint32_t reg_update_cmd;
};
struct ais_vfe_rdi_reg_data {
uint32_t reg_update_cmd_data;
uint32_t sof_irq_mask;
uint32_t reg_update_irq_mask;
};
struct ais_vfe_rdi_ver2_hw_info {
struct ais_vfe_top_ver2_reg_offset_common *common_reg;
struct ais_vfe_rdi_ver2_reg *rdi_reg;
struct ais_vfe_rdi_reg_data *reg_data[AIS_VFE_RDI_VER2_MAX];
};
#endif /* _AIS_VFE_RDI_H_ */

View File

@@ -0,0 +1,99 @@
/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_VFE_TOP_VER2_H_
#define _AIS_VFE_TOP_VER2_H_
#include "ais_vfe_camif_ver2.h"
#include "ais_vfe_camif_lite_ver2.h"
#include "ais_vfe_rdi.h"
#include "ais_vfe_fe_ver1.h"
#define AIS_VFE_TOP_VER2_MUX_MAX 6
#define AIS_VFE_MAX_REG_DUMP_ENTRIES 5
#define AIS_VFE_MAX_LUT_DUMP_ENTRIES 6
enum ais_vfe_top_ver2_module_type {
AIS_VFE_TOP_VER2_MODULE_LENS,
AIS_VFE_TOP_VER2_MODULE_STATS,
AIS_VFE_TOP_VER2_MODULE_COLOR,
AIS_VFE_TOP_VER2_MODULE_ZOOM,
AIS_VFE_TOP_VER2_MODULE_MAX,
};
struct ais_vfe_top_ver2_reg_offset_module_ctrl {
uint32_t reset;
uint32_t cgc_ovd;
uint32_t enable;
};
struct ais_vfe_top_reg_dump_entry {
uint32_t reg_dump_start;
uint32_t reg_dump_end;
};
struct ais_vfe_top_lut_dump_entry {
uint32_t lut_word_size;
uint32_t lut_bank_sel;
uint32_t lut_addr_size;
};
struct ais_vfe_top_dump_data {
uint32_t num_reg_dump_entries;
uint32_t num_lut_dump_entries;
uint32_t dmi_cfg;
uint32_t dmi_addr;
uint32_t dmi_data_path_hi;
uint32_t dmi_data_path_lo;
struct ais_vfe_top_reg_dump_entry
reg_entry[AIS_VFE_MAX_REG_DUMP_ENTRIES];
struct ais_vfe_top_lut_dump_entry
lut_entry[AIS_VFE_MAX_LUT_DUMP_ENTRIES];
};
struct ais_vfe_top_ver2_reg_offset_common {
uint32_t hw_version;
uint32_t hw_capability;
uint32_t lens_feature;
uint32_t stats_feature;
uint32_t color_feature;
uint32_t zoom_feature;
uint32_t global_reset_cmd;
struct ais_vfe_top_ver2_reg_offset_module_ctrl
*module_ctrl[AIS_VFE_TOP_VER2_MODULE_MAX];
uint32_t bus_cgc_ovd;
uint32_t core_cfg;
uint32_t three_D_cfg;
uint32_t violation_status;
uint32_t reg_update_cmd;
};
struct ais_vfe_top_ver2_hw_info {
struct ais_vfe_top_ver2_reg_offset_common *common_reg;
struct ais_vfe_camif_ver2_hw_info camif_hw_info;
struct ais_vfe_camif_lite_ver2_hw_info camif_lite_hw_info;
struct ais_vfe_rdi_ver2_hw_info rdi_hw_info;
struct ais_vfe_fe_ver1_hw_info fe_hw_info;
struct ais_vfe_top_dump_data dump_data;
uint32_t mux_type[AIS_VFE_TOP_VER2_MUX_MAX];
};
int ais_vfe_top_ver2_init(struct cam_hw_soc_info *soc_info,
struct cam_hw_intf *hw_intf,
void *top_hw_info,
struct ais_vfe_top **vfe_top);
int ais_vfe_top_ver2_deinit(struct ais_vfe_top **vfe_top);
#endif /* _AIS_VFE_TOP_VER2_H_ */

View File

@@ -0,0 +1,44 @@
/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _AIS_VFE_TOP_H_
#define _AIS_VFE_TOP_H_
#include "cam_hw_intf.h"
#include "ais_isp_hw.h"
#define AIS_VFE_TOP_VER_1_0 0x100000
#define AIS_VFE_TOP_VER_2_0 0x200000
#define AIS_VFE_CAMIF_VER_1_0 0x10
#define AIS_VFE_CAMIF_VER_2_0 0x20
#define AIS_VFE_CAMIF_LITE_VER_2_0 0x02
#define AIS_VFE_RDI_VER_1_0 0x1000
#define AIS_VFE_IN_RD_VER_1_0 0x2000
struct ais_vfe_top {
void *top_priv;
struct cam_hw_ops hw_ops;
};
int ais_vfe_top_init(uint32_t top_version,
struct cam_hw_soc_info *soc_info,
struct cam_hw_intf *hw_intf,
void *top_hw_info,
struct ais_vfe_top **vfe_top);
int ais_vfe_top_deinit(uint32_t top_version,
struct ais_vfe_top **vfe_top);
#endif /* _AIS_VFE_TOP_H_*/

View File

@@ -69,7 +69,7 @@ int cam_vfe_probe(struct platform_device *pdev)
vfe_hw_intf->hw_ops.process_cmd = cam_vfe_process_cmd;
vfe_hw_intf->hw_type = CAM_ISP_HW_TYPE_VFE;
CAM_DBG(CAM_ISP, "type %d index %d",
CAM_INFO(CAM_ISP, "type %d index %d",
vfe_hw_intf->hw_type, vfe_hw_intf->hw_idx);
platform_set_drvdata(pdev, vfe_hw_intf);

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -84,25 +84,25 @@ static struct cam_vfe_camif_reg_data vfe_170_camif_reg_data = {
.enable_diagnostic_hw = 0x1,
};
struct cam_vfe_top_ver2_reg_offset_module_ctrl lens_170_reg = {
static struct cam_vfe_top_ver2_reg_offset_module_ctrl lens_170_reg = {
.reset = 0x0000001C,
.cgc_ovd = 0x0000002C,
.enable = 0x00000040,
};
struct cam_vfe_top_ver2_reg_offset_module_ctrl stats_170_reg = {
static struct cam_vfe_top_ver2_reg_offset_module_ctrl stats_170_reg = {
.reset = 0x00000020,
.cgc_ovd = 0x00000030,
.enable = 0x00000044,
};
struct cam_vfe_top_ver2_reg_offset_module_ctrl color_170_reg = {
static struct cam_vfe_top_ver2_reg_offset_module_ctrl color_170_reg = {
.reset = 0x00000024,
.cgc_ovd = 0x00000034,
.enable = 0x00000048,
};
struct cam_vfe_top_ver2_reg_offset_module_ctrl zoom_170_reg = {
static struct cam_vfe_top_ver2_reg_offset_module_ctrl zoom_170_reg = {
.reset = 0x00000028,
.cgc_ovd = 0x00000038,
.enable = 0x0000004C,
@@ -1039,7 +1039,7 @@ struct cam_vfe_hw_info cam_vfe170_hw_info = {
.camif_reg = &vfe170_camif_reg,
.camif_lite_version = 0,
.camif_reg = NULL,
.camif_lite_reg = NULL,
};

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -107,25 +107,25 @@ static struct cam_vfe_camif_lite_ver2_reg_data vfe175_camif_lite_reg_data = {
.dual_pd_path_sel_shift = 24,
};
struct cam_vfe_top_ver2_reg_offset_module_ctrl lens_175_reg = {
static struct cam_vfe_top_ver2_reg_offset_module_ctrl lens_175_reg = {
.reset = 0x0000001C,
.cgc_ovd = 0x0000002C,
.enable = 0x00000040,
};
struct cam_vfe_top_ver2_reg_offset_module_ctrl stats_175_reg = {
static struct cam_vfe_top_ver2_reg_offset_module_ctrl stats_175_reg = {
.reset = 0x00000020,
.cgc_ovd = 0x00000030,
.enable = 0x00000044,
};
struct cam_vfe_top_ver2_reg_offset_module_ctrl color_175_reg = {
static struct cam_vfe_top_ver2_reg_offset_module_ctrl color_175_reg = {
.reset = 0x00000024,
.cgc_ovd = 0x00000034,
.enable = 0x00000048,
};
struct cam_vfe_top_ver2_reg_offset_module_ctrl zoom_175_reg = {
static struct cam_vfe_top_ver2_reg_offset_module_ctrl zoom_175_reg = {
.reset = 0x00000028,
.cgc_ovd = 0x00000038,
.enable = 0x0000004C,

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2018-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -157,25 +157,25 @@ static struct cam_vfe_camif_lite_ver2_reg_data
.dual_pd_path_sel_shift = 24,
};
struct cam_vfe_top_ver2_reg_offset_module_ctrl lens_175_130_reg = {
static struct cam_vfe_top_ver2_reg_offset_module_ctrl lens_175_130_reg = {
.reset = 0x0000001C,
.cgc_ovd = 0x0000002C,
.enable = 0x00000040,
};
struct cam_vfe_top_ver2_reg_offset_module_ctrl stats_175_130_reg = {
static struct cam_vfe_top_ver2_reg_offset_module_ctrl stats_175_130_reg = {
.reset = 0x00000020,
.cgc_ovd = 0x00000030,
.enable = 0x00000044,
};
struct cam_vfe_top_ver2_reg_offset_module_ctrl color_175_130_reg = {
static struct cam_vfe_top_ver2_reg_offset_module_ctrl color_175_130_reg = {
.reset = 0x00000024,
.cgc_ovd = 0x00000034,
.enable = 0x00000048,
};
struct cam_vfe_top_ver2_reg_offset_module_ctrl zoom_175_130_reg = {
static struct cam_vfe_top_ver2_reg_offset_module_ctrl zoom_175_130_reg = {
.reset = 0x00000028,
.cgc_ovd = 0x00000038,
.enable = 0x0000004C,

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -430,7 +430,7 @@ static int cam_cci_platform_probe(struct platform_device *pdev)
g_cci_subdev[soc_info->index] = &new_cci_dev->v4l2_dev_str.sd;
mutex_init(&(new_cci_dev->init_mutex));
CAM_INFO(CAM_CCI, "Device Type :%d", soc_info->index);
CAM_INFO(CAM_CCI, "Probe CCI %d", soc_info->index);
cam_register_subdev_fops(&cci_v4l2_subdev_fops);
cci_v4l2_subdev_fops.unlocked_ioctl = cam_cci_subdev_fops_ioctl;

View File

@@ -1,4 +1,4 @@
/* Copyright (c) 2014-2019, The Linux Foundation. All rights reserved.
/* Copyright (c) 2014-2020, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -453,7 +453,7 @@ void cam_smmu_set_client_page_fault_handler(int handle,
if (handler_cb) {
if (iommu_cb_set.cb_info[idx].cb_count == CAM_SMMU_CB_MAX) {
CAM_ERR(CAM_SMMU,
"%s Should not regiester more handlers",
"%s Should not register more handlers",
iommu_cb_set.cb_info[idx].name);
mutex_unlock(&iommu_cb_set.cb_info[idx].lock);
return;
@@ -718,11 +718,12 @@ static int cam_smmu_create_add_handle_in_table(char *name,
return 0;
}
CAM_ERR(CAM_SMMU,
"Error: %s already got handle 0x%x",
CAM_DBG(CAM_SMMU,
"%s already got handle 0x%x",
name, iommu_cb_set.cb_info[i].handle);
return -EINVAL;
*hdl = iommu_cb_set.cb_info[i].handle;
return 0;
}
/* make sure handle is unique */

View File

@@ -631,6 +631,7 @@ gen_headers_out_arm = [
"linux/xilinx-v4l2-controls.h",
"linux/zorro.h",
"linux/zorro_ids.h",
"media/ais_isp.h",
"media/ais_sensor.h",
"media/cam_cpas.h",
"media/cam_defs.h",

View File

@@ -626,6 +626,7 @@ gen_headers_out_arm64 = [
"linux/xilinx-v4l2-controls.h",
"linux/zorro.h",
"linux/zorro_ids.h",
"media/ais_isp.h",
"media/ais_sensor.h",
"media/cam_cpas.h",
"media/cam_defs.h",

View File

@@ -9,6 +9,7 @@ header-y += cam_jpeg.h
header-y += cam_req_mgr.h
header-y += cam_sensor.h
header-y += cam_sync.h
header-y += ais_isp.h
header-y += ais_sensor.h
header-y += msm_media_info.h
header-y += msm_vidc.h

View File

@@ -0,0 +1,32 @@
#ifndef __UAPI_AIS_ISP_H__
#define __UAPI_AIS_ISP_H__
#include "cam_defs.h"
#include "cam_isp_vfe.h"
#include "cam_isp_ife.h"
#include "cam_cpas.h"
/* ISP driver name */
#define AIS_IFE_DEV_NAME "ais-ife"
#define AIS_IFE_DEVICE_TYPE (CAM_DEVICE_TYPE_BASE + 20)
#define AIS_IFE_OPCODE_START (CAM_COMMON_OPCODE_MAX)
#define AIS_IFE_QUERY_CAPS (AIS_IFE_OPCODE_START + 1)
#define AIS_IFE_POWER_UP (AIS_IFE_OPCODE_START + 2)
#define AIS_IFE_POWER_DOWN (AIS_IFE_OPCODE_START + 3)
#define AIS_IFE_RESET (AIS_IFE_OPCODE_START + 4)
#define AIS_IFE_RESERVE (AIS_IFE_OPCODE_START + 5)
#define AIS_IFE_RELEASE (AIS_IFE_OPCODE_START + 6)
#define AIS_IFE_START (AIS_IFE_OPCODE_START + 7)
#define AIS_IFE_STOP (AIS_IFE_OPCODE_START + 8)
#define AIS_IFE_PAUSE (AIS_IFE_OPCODE_START + 9)
#define AIS_IFE_RESUME (AIS_IFE_OPCODE_START + 10)
#define AIS_IFE_BUFFER_ENQ (AIS_IFE_OPCODE_START + 11)
/* Specific event ids to get notified in user space */
#define V4L_EVENT_TYPE_AIS_IFE (V4L2_EVENT_PRIVATE_START)
#define V4L_EVENT_ID_AIS_IFE 0
#endif /* __UAPI_AIS_ISP_H__ */