msm: camera: isp: Bring PPI driver in camera techpack
This change bring PPI driver from msm-4.14 to camera-kernel.lnx.4.0. msm: camera: isp: Added PPI driver functionality msm: camera: ppi: Change PPI reset sequence msm: camera: isp: Do not enable the ppi hw twice. CRs-Fixed: 2682747 Change-Id: I7cde3aeed1dbcef95f25441c2482f5bc8c1534de Signed-off-by: Trishansh Bhardwaj <tbhardwa@codeaurora.org>
This commit is contained in:
@@ -197,6 +197,9 @@ camera-$(CONFIG_SPECTRA_OPE) += \
|
|||||||
cam_ope/ope_hw_mgr/ope_hw/bus_wr/ope_bus_wr.o
|
cam_ope/ope_hw_mgr/ope_hw/bus_wr/ope_bus_wr.o
|
||||||
|
|
||||||
camera-$(CONFIG_SPECTRA_TFE) += \
|
camera-$(CONFIG_SPECTRA_TFE) += \
|
||||||
|
cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi_core.o \
|
||||||
|
cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi_dev.o \
|
||||||
|
cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi100.o \
|
||||||
cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_soc.o \
|
cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_soc.o \
|
||||||
cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_dev.o \
|
cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_dev.o \
|
||||||
cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.o \
|
cam_isp/isp_hw_mgr/isp_hw/tfe_hw/cam_tfe_core.o \
|
||||||
|
49
drivers/cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi100.c
Normal file
49
drivers/cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi100.c
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include "cam_csid_ppi_core.h"
|
||||||
|
#include "cam_csid_ppi100.h"
|
||||||
|
#include "cam_csid_ppi_dev.h"
|
||||||
|
|
||||||
|
#define CAM_PPI_DRV_NAME "ppi_100"
|
||||||
|
#define CAM_PPI_VERSION_V100 0x10000000
|
||||||
|
|
||||||
|
static struct cam_csid_ppi_hw_info cam_csid_ppi100_hw_info = {
|
||||||
|
.ppi_reg = &cam_csid_ppi_100_reg_offset,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct of_device_id cam_csid_ppi100_dt_match[] = {
|
||||||
|
{
|
||||||
|
.compatible = "qcom,ppi100",
|
||||||
|
.data = &cam_csid_ppi100_hw_info,
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
|
MODULE_DEVICE_TABLE(of, cam_csid_ppi100_dt_match);
|
||||||
|
|
||||||
|
static struct platform_driver cam_csid_ppi100_driver = {
|
||||||
|
.probe = cam_csid_ppi_probe,
|
||||||
|
.remove = cam_csid_ppi_remove,
|
||||||
|
.driver = {
|
||||||
|
.name = CAM_PPI_DRV_NAME,
|
||||||
|
.of_match_table = cam_csid_ppi100_dt_match,
|
||||||
|
.suppress_bind_attrs = true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
int cam_csid_ppi100_init_module(void)
|
||||||
|
{
|
||||||
|
return platform_driver_register(&cam_csid_ppi100_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cam_csid_ppi100_exit_module(void)
|
||||||
|
{
|
||||||
|
platform_driver_unregister(&cam_csid_ppi100_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
MODULE_DESCRIPTION("CAM CSID_PPI100 driver");
|
||||||
|
MODULE_LICENSE("GPL v2");
|
35
drivers/cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi100.h
Normal file
35
drivers/cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi100.h
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CAM_CSID_PPI_100_H_
|
||||||
|
#define _CAM_CSID_PPI_100_H_
|
||||||
|
|
||||||
|
#include "cam_csid_ppi_core.h"
|
||||||
|
|
||||||
|
static struct cam_csid_ppi_reg_offset cam_csid_ppi_100_reg_offset = {
|
||||||
|
.ppi_hw_version_addr = 0,
|
||||||
|
.ppi_module_cfg_addr = 0x60,
|
||||||
|
.ppi_irq_status_addr = 0x68,
|
||||||
|
.ppi_irq_mask_addr = 0x6c,
|
||||||
|
.ppi_irq_set_addr = 0x70,
|
||||||
|
.ppi_irq_clear_addr = 0x74,
|
||||||
|
.ppi_irq_cmd_addr = 0x78,
|
||||||
|
.ppi_rst_cmd_addr = 0x7c,
|
||||||
|
.ppi_test_bus_ctrl_addr = 0x1f4,
|
||||||
|
.ppi_debug_addr = 0x1f8,
|
||||||
|
.ppi_spare_addr = 0x1fc,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief : API to register PPI Dev to platform framework.
|
||||||
|
* @return struct platform_device pointer on on success, or ERR_PTR() on error.
|
||||||
|
*/
|
||||||
|
int cam_csid_ppi100_init_module(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief : API to remove PPI Dev from platform framework.
|
||||||
|
*/
|
||||||
|
void cam_csid_ppi100_exit_module(void);
|
||||||
|
#endif /*_CAM_CSID_PPI_100_H_ */
|
391
drivers/cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi_core.c
Normal file
391
drivers/cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi_core.c
Normal file
@@ -0,0 +1,391 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/iopoll.h>
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <media/cam_defs.h>
|
||||||
|
|
||||||
|
#include "cam_csid_ppi_core.h"
|
||||||
|
#include "cam_csid_ppi_dev.h"
|
||||||
|
#include "cam_soc_util.h"
|
||||||
|
#include "cam_debug_util.h"
|
||||||
|
#include "cam_io_util.h"
|
||||||
|
|
||||||
|
static int cam_csid_ppi_reset(struct cam_csid_ppi_hw *ppi_hw)
|
||||||
|
{
|
||||||
|
struct cam_hw_soc_info *soc_info;
|
||||||
|
const struct cam_csid_ppi_reg_offset *ppi_reg;
|
||||||
|
int rc = 0;
|
||||||
|
uint32_t status;
|
||||||
|
|
||||||
|
soc_info = &ppi_hw->hw_info->soc_info;
|
||||||
|
ppi_reg = ppi_hw->ppi_info->ppi_reg;
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ISP, "PPI:%d reset", ppi_hw->hw_intf->hw_idx);
|
||||||
|
|
||||||
|
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
|
||||||
|
ppi_reg->ppi_irq_mask_addr);
|
||||||
|
cam_io_w_mb(PPI_RST_CONTROL, soc_info->reg_map[0].mem_base +
|
||||||
|
ppi_reg->ppi_irq_set_addr);
|
||||||
|
cam_io_w_mb(PPI_RST_CONTROL, soc_info->reg_map[0].mem_base +
|
||||||
|
ppi_reg->ppi_rst_cmd_addr);
|
||||||
|
cam_io_w_mb(PPI_IRQ_CMD_SET, soc_info->reg_map[0].mem_base +
|
||||||
|
ppi_reg->ppi_irq_cmd_addr);
|
||||||
|
|
||||||
|
rc = readl_poll_timeout(soc_info->reg_map[0].mem_base +
|
||||||
|
ppi_reg->ppi_irq_status_addr, status,
|
||||||
|
(status & 0x1) == 0x1, 1000, 500000);
|
||||||
|
CAM_DBG(CAM_ISP, "PPI:%d reset status %d", ppi_hw->hw_intf->hw_idx,
|
||||||
|
status);
|
||||||
|
if (rc < 0) {
|
||||||
|
CAM_ERR(CAM_ISP, "PPI:%d ppi_reset fail rc = %d status = %d",
|
||||||
|
ppi_hw->hw_intf->hw_idx, rc, status);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
cam_io_w_mb(PPI_RST_CONTROL, soc_info->reg_map[0].mem_base +
|
||||||
|
ppi_reg->ppi_irq_clear_addr);
|
||||||
|
cam_io_w_mb(PPI_IRQ_CMD_CLEAR, soc_info->reg_map[0].mem_base +
|
||||||
|
ppi_reg->ppi_irq_cmd_addr);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cam_csid_ppi_enable_hw(struct cam_csid_ppi_hw *ppi_hw)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
int32_t i;
|
||||||
|
uint64_t val;
|
||||||
|
const struct cam_csid_ppi_reg_offset *ppi_reg;
|
||||||
|
struct cam_hw_soc_info *soc_info;
|
||||||
|
uint32_t err_irq_mask;
|
||||||
|
|
||||||
|
ppi_reg = ppi_hw->ppi_info->ppi_reg;
|
||||||
|
soc_info = &ppi_hw->hw_info->soc_info;
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ISP, "PPI:%d init PPI HW", ppi_hw->hw_intf->hw_idx);
|
||||||
|
|
||||||
|
ppi_hw->hw_info->open_count++;
|
||||||
|
if (ppi_hw->hw_info->open_count > 1) {
|
||||||
|
CAM_DBG(CAM_ISP, "PPI:%d dual vfe already enabled",
|
||||||
|
ppi_hw->hw_intf->hw_idx);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < soc_info->num_clk; i++) {
|
||||||
|
rc = cam_soc_util_clk_enable(soc_info->clk[i],
|
||||||
|
soc_info->clk_name[i], 0);
|
||||||
|
if (rc)
|
||||||
|
goto clk_disable;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = cam_csid_ppi_reset(ppi_hw);
|
||||||
|
if (rc)
|
||||||
|
goto clk_disable;
|
||||||
|
|
||||||
|
err_irq_mask = PPI_IRQ_FIFO0_OVERFLOW | PPI_IRQ_FIFO1_OVERFLOW |
|
||||||
|
PPI_IRQ_FIFO2_OVERFLOW;
|
||||||
|
cam_io_w_mb(err_irq_mask, soc_info->reg_map[0].mem_base +
|
||||||
|
ppi_reg->ppi_irq_mask_addr);
|
||||||
|
rc = cam_soc_util_irq_enable(soc_info);
|
||||||
|
if (rc)
|
||||||
|
goto clk_disable;
|
||||||
|
|
||||||
|
cam_io_w_mb(PPI_RST_CONTROL, soc_info->reg_map[0].mem_base +
|
||||||
|
ppi_reg->ppi_irq_clear_addr);
|
||||||
|
cam_io_w_mb(PPI_IRQ_CMD_CLEAR, soc_info->reg_map[0].mem_base +
|
||||||
|
ppi_reg->ppi_irq_cmd_addr);
|
||||||
|
val = cam_io_r_mb(soc_info->reg_map[0].mem_base +
|
||||||
|
ppi_reg->ppi_hw_version_addr);
|
||||||
|
CAM_DBG(CAM_ISP, "PPI:%d PPI HW version: 0x%x",
|
||||||
|
ppi_hw->hw_intf->hw_idx, val);
|
||||||
|
ppi_hw->device_enabled = 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
clk_disable:
|
||||||
|
for (--i; i >= 0; i--)
|
||||||
|
cam_soc_util_clk_disable(soc_info->clk[i],
|
||||||
|
soc_info->clk_name[i]);
|
||||||
|
ppi_hw->hw_info->open_count--;
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cam_csid_ppi_disable_hw(struct cam_csid_ppi_hw *ppi_hw)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
int i;
|
||||||
|
struct cam_hw_soc_info *soc_info;
|
||||||
|
const struct cam_csid_ppi_reg_offset *ppi_reg;
|
||||||
|
uint64_t ppi_cfg_val = 0;
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ISP, "PPI:%d De-init PPI HW",
|
||||||
|
ppi_hw->hw_intf->hw_idx);
|
||||||
|
|
||||||
|
if (!ppi_hw->hw_info->open_count) {
|
||||||
|
CAM_WARN(CAM_ISP, "ppi[%d] unbalanced disable hw",
|
||||||
|
ppi_hw->hw_intf->hw_idx);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
ppi_hw->hw_info->open_count--;
|
||||||
|
|
||||||
|
if (ppi_hw->hw_info->open_count)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
soc_info = &ppi_hw->hw_info->soc_info;
|
||||||
|
ppi_reg = ppi_hw->ppi_info->ppi_reg;
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ISP, "Calling PPI Reset");
|
||||||
|
cam_csid_ppi_reset(ppi_hw);
|
||||||
|
CAM_DBG(CAM_ISP, "PPI Reset Done");
|
||||||
|
|
||||||
|
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
|
||||||
|
ppi_reg->ppi_irq_mask_addr);
|
||||||
|
cam_soc_util_irq_disable(soc_info);
|
||||||
|
|
||||||
|
for (i = 0; i < CAM_CSID_PPI_LANES_MAX; i++)
|
||||||
|
ppi_cfg_val &= ~PPI_CFG_CPHY_DLX_EN(i);
|
||||||
|
|
||||||
|
cam_io_w_mb(ppi_cfg_val, soc_info->reg_map[0].mem_base +
|
||||||
|
ppi_reg->ppi_module_cfg_addr);
|
||||||
|
|
||||||
|
ppi_hw->device_enabled = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < soc_info->num_clk; i++)
|
||||||
|
cam_soc_util_clk_disable(soc_info->clk[i],
|
||||||
|
soc_info->clk_name[i]);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cam_csid_ppi_init_hw(void *hw_priv, void *init_args,
|
||||||
|
uint32_t arg_size)
|
||||||
|
{
|
||||||
|
int i, rc = 0;
|
||||||
|
uint32_t num_lanes;
|
||||||
|
uint32_t lanes[CAM_CSID_PPI_HW_MAX] = {0, 0, 0, 0};
|
||||||
|
uint32_t cphy;
|
||||||
|
bool dl0, dl1;
|
||||||
|
uint32_t ppi_cfg_val = 0;
|
||||||
|
struct cam_csid_ppi_hw *ppi_hw;
|
||||||
|
struct cam_hw_info *ppi_hw_info;
|
||||||
|
const struct cam_csid_ppi_reg_offset *ppi_reg;
|
||||||
|
struct cam_hw_soc_info *soc_info;
|
||||||
|
struct cam_csid_ppi_cfg ppi_cfg;
|
||||||
|
|
||||||
|
if (!hw_priv || !init_args ||
|
||||||
|
(arg_size != sizeof(struct cam_csid_ppi_cfg))) {
|
||||||
|
CAM_ERR(CAM_ISP, "PPI: Invalid args");
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
dl0 = dl1 = false;
|
||||||
|
ppi_hw_info = (struct cam_hw_info *)hw_priv;
|
||||||
|
ppi_hw = (struct cam_csid_ppi_hw *)ppi_hw_info->core_info;
|
||||||
|
ppi_reg = ppi_hw->ppi_info->ppi_reg;
|
||||||
|
ppi_cfg = *((struct cam_csid_ppi_cfg *)init_args);
|
||||||
|
|
||||||
|
rc = cam_csid_ppi_enable_hw(ppi_hw);
|
||||||
|
if (rc)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
num_lanes = ppi_cfg.lane_num;
|
||||||
|
cphy = ppi_cfg.lane_type;
|
||||||
|
CAM_DBG(CAM_ISP, "lane_cfg 0x%x | num_lanes 0x%x | lane_type 0x%x",
|
||||||
|
ppi_cfg.lane_cfg, num_lanes, cphy);
|
||||||
|
|
||||||
|
for (i = 0; i < num_lanes; i++) {
|
||||||
|
lanes[i] = ppi_cfg.lane_cfg & (0x3 << (4 * i));
|
||||||
|
(lanes[i] < 2) ? (dl0 = true) : (dl1 = true);
|
||||||
|
CAM_DBG(CAM_ISP, "lanes[%d] %d", i, lanes[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num_lanes) {
|
||||||
|
if (cphy) {
|
||||||
|
for (i = 0; i < num_lanes; i++) {
|
||||||
|
ppi_cfg_val |= PPI_CFG_CPHY_DLX_SEL(lanes[i]);
|
||||||
|
ppi_cfg_val |= PPI_CFG_CPHY_DLX_EN(lanes[i]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (dl0)
|
||||||
|
ppi_cfg_val |= PPI_CFG_CPHY_DLX_EN(0);
|
||||||
|
if (dl1)
|
||||||
|
ppi_cfg_val |= PPI_CFG_CPHY_DLX_EN(1);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
CAM_ERR(CAM_ISP,
|
||||||
|
"Number of lanes to enable is cannot be zero");
|
||||||
|
rc = -1;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ISP, "ppi_cfg_val 0x%x", ppi_cfg_val);
|
||||||
|
soc_info = &ppi_hw->hw_info->soc_info;
|
||||||
|
cam_io_w_mb(ppi_cfg_val, soc_info->reg_map[0].mem_base +
|
||||||
|
ppi_reg->ppi_module_cfg_addr);
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ISP, "ppi cfg 0x%x",
|
||||||
|
cam_io_r_mb(soc_info->reg_map[0].mem_base +
|
||||||
|
ppi_reg->ppi_module_cfg_addr));
|
||||||
|
end:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cam_csid_ppi_deinit_hw(void *hw_priv, void *deinit_args,
|
||||||
|
uint32_t arg_size)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
struct cam_csid_ppi_hw *ppi_hw;
|
||||||
|
struct cam_hw_info *ppi_hw_info;
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ISP, "Enter");
|
||||||
|
|
||||||
|
if (!hw_priv) {
|
||||||
|
CAM_ERR(CAM_ISP, "PPI:Invalid arguments");
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppi_hw_info = (struct cam_hw_info *)hw_priv;
|
||||||
|
ppi_hw = (struct cam_csid_ppi_hw *)ppi_hw_info->core_info;
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ISP, "Disabling PPI Hw");
|
||||||
|
rc = cam_csid_ppi_disable_hw(ppi_hw);
|
||||||
|
if (rc < 0)
|
||||||
|
CAM_DBG(CAM_ISP, "Exit with %d", rc);
|
||||||
|
end:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cam_csid_ppi_hw_probe_init(struct cam_hw_intf *ppi_hw_intf,
|
||||||
|
uint32_t ppi_idx)
|
||||||
|
{
|
||||||
|
int rc = -EINVAL;
|
||||||
|
struct cam_hw_info *ppi_hw_info;
|
||||||
|
struct cam_csid_ppi_hw *csid_ppi_hw = NULL;
|
||||||
|
|
||||||
|
if (ppi_idx >= CAM_CSID_PPI_HW_MAX) {
|
||||||
|
CAM_ERR(CAM_ISP, "Invalid ppi index:%d", ppi_idx);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppi_hw_info = (struct cam_hw_info *) ppi_hw_intf->hw_priv;
|
||||||
|
csid_ppi_hw = (struct cam_csid_ppi_hw *) ppi_hw_info->core_info;
|
||||||
|
|
||||||
|
csid_ppi_hw->hw_intf = ppi_hw_intf;
|
||||||
|
csid_ppi_hw->hw_info = ppi_hw_info;
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ISP, "type %d index %d",
|
||||||
|
csid_ppi_hw->hw_intf->hw_type, ppi_idx);
|
||||||
|
|
||||||
|
rc = cam_csid_ppi_init_soc_resources(&csid_ppi_hw->hw_info->soc_info,
|
||||||
|
cam_csid_ppi_irq, csid_ppi_hw);
|
||||||
|
if (rc < 0) {
|
||||||
|
CAM_ERR(CAM_ISP, "PPI:%d Failed to init_soc", ppi_idx);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
csid_ppi_hw->hw_intf->hw_ops.init = cam_csid_ppi_init_hw;
|
||||||
|
csid_ppi_hw->hw_intf->hw_ops.deinit = cam_csid_ppi_deinit_hw;
|
||||||
|
return 0;
|
||||||
|
err:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cam_csid_ppi_init_soc_resources(struct cam_hw_soc_info *soc_info,
|
||||||
|
irq_handler_t ppi_irq_handler, void *irq_data)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
rc = cam_soc_util_get_dt_properties(soc_info);
|
||||||
|
if (rc) {
|
||||||
|
CAM_ERR(CAM_ISP, "PPI: Failed to get dt properties");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = cam_soc_util_request_platform_resource(soc_info, ppi_irq_handler,
|
||||||
|
irq_data);
|
||||||
|
if (rc) {
|
||||||
|
CAM_ERR(CAM_ISP,
|
||||||
|
"PPI: Error Request platform resources failed rc=%d",
|
||||||
|
rc);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
end:
|
||||||
|
return rc;
|
||||||
|
err:
|
||||||
|
cam_soc_util_release_platform_resource(soc_info);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
irqreturn_t cam_csid_ppi_irq(int irq_num, void *data)
|
||||||
|
{
|
||||||
|
uint32_t irq_status = 0;
|
||||||
|
uint32_t i, ppi_cfg_val = 0;
|
||||||
|
bool fatal_err_detected = false;
|
||||||
|
|
||||||
|
struct cam_csid_ppi_hw *ppi_hw;
|
||||||
|
struct cam_hw_soc_info *soc_info;
|
||||||
|
const struct cam_csid_ppi_reg_offset *ppi_reg;
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
CAM_ERR(CAM_ISP, "PPI: Invalid arguments");
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppi_hw = (struct cam_csid_ppi_hw *)data;
|
||||||
|
ppi_reg = ppi_hw->ppi_info->ppi_reg;
|
||||||
|
soc_info = &ppi_hw->hw_info->soc_info;
|
||||||
|
|
||||||
|
if (ppi_hw->device_enabled != 1)
|
||||||
|
goto ret;
|
||||||
|
|
||||||
|
irq_status = cam_io_r_mb(soc_info->reg_map[0].mem_base +
|
||||||
|
ppi_reg->ppi_irq_status_addr);
|
||||||
|
|
||||||
|
cam_io_w_mb(irq_status, soc_info->reg_map[0].mem_base +
|
||||||
|
ppi_reg->ppi_irq_clear_addr);
|
||||||
|
|
||||||
|
cam_io_w_mb(PPI_IRQ_CMD_CLEAR, soc_info->reg_map[0].mem_base +
|
||||||
|
ppi_reg->ppi_irq_cmd_addr);
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ISP, "PPI %d irq status 0x%x", ppi_hw->hw_intf->hw_idx,
|
||||||
|
irq_status);
|
||||||
|
|
||||||
|
if (irq_status & PPI_IRQ_RST_DONE) {
|
||||||
|
CAM_DBG(CAM_ISP, "PPI Reset Done");
|
||||||
|
goto ret;
|
||||||
|
}
|
||||||
|
if ((irq_status & PPI_IRQ_FIFO0_OVERFLOW) ||
|
||||||
|
(irq_status & PPI_IRQ_FIFO1_OVERFLOW) ||
|
||||||
|
(irq_status & PPI_IRQ_FIFO2_OVERFLOW)) {
|
||||||
|
fatal_err_detected = true;
|
||||||
|
goto handle_fatal_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
handle_fatal_error:
|
||||||
|
if (fatal_err_detected) {
|
||||||
|
CAM_ERR(CAM_ISP, "PPI: %d irq_status:0x%x",
|
||||||
|
ppi_hw->hw_intf->hw_idx, irq_status);
|
||||||
|
for (i = 0; i < CAM_CSID_PPI_LANES_MAX; i++)
|
||||||
|
ppi_cfg_val &= ~PPI_CFG_CPHY_DLX_EN(i);
|
||||||
|
|
||||||
|
cam_io_w_mb(ppi_cfg_val, soc_info->reg_map[0].mem_base +
|
||||||
|
ppi_reg->ppi_module_cfg_addr);
|
||||||
|
}
|
||||||
|
ret:
|
||||||
|
CAM_DBG(CAM_ISP, "IRQ Handling exit");
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cam_csid_ppi_hw_deinit(struct cam_csid_ppi_hw *csid_ppi_hw)
|
||||||
|
{
|
||||||
|
if (!csid_ppi_hw) {
|
||||||
|
CAM_ERR(CAM_ISP, "Invalid param");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return cam_soc_util_release_platform_resource(
|
||||||
|
&csid_ppi_hw->hw_info->soc_info);
|
||||||
|
}
|
||||||
|
|
95
drivers/cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi_core.h
Normal file
95
drivers/cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi_core.h
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CAM_CSID_PPI_HW_H_
|
||||||
|
#define _CAM_CSID_PPI_HW_H_
|
||||||
|
|
||||||
|
#include "cam_hw.h"
|
||||||
|
#include "cam_hw_intf.h"
|
||||||
|
|
||||||
|
#define CAM_CSID_PPI_HW_MAX 6
|
||||||
|
#define CAM_CSID_PPI_LANES_MAX 3
|
||||||
|
|
||||||
|
#define PPI_IRQ_RST_DONE BIT(0)
|
||||||
|
#define PPI_IRQ_FIFO0_OVERFLOW BIT(1)
|
||||||
|
#define PPI_IRQ_FIFO1_OVERFLOW BIT(2)
|
||||||
|
#define PPI_IRQ_FIFO2_OVERFLOW BIT(3)
|
||||||
|
|
||||||
|
#define PPI_IRQ_CMD_SET BIT(1)
|
||||||
|
|
||||||
|
#define PPI_IRQ_CMD_CLEAR BIT(0)
|
||||||
|
|
||||||
|
#define PPI_RST_CONTROL BIT(0)
|
||||||
|
/*
|
||||||
|
* Select the PHY (CPHY set '1' or DPHY set '0')
|
||||||
|
*/
|
||||||
|
#define PPI_CFG_CPHY_DLX_SEL(X) ((X < 2) ? BIT(X) : 0)
|
||||||
|
|
||||||
|
#define PPI_CFG_CPHY_DLX_EN(X) BIT(4+X)
|
||||||
|
|
||||||
|
struct cam_csid_ppi_reg_offset {
|
||||||
|
uint32_t ppi_hw_version_addr;
|
||||||
|
uint32_t ppi_module_cfg_addr;
|
||||||
|
|
||||||
|
uint32_t ppi_irq_status_addr;
|
||||||
|
uint32_t ppi_irq_mask_addr;
|
||||||
|
uint32_t ppi_irq_set_addr;
|
||||||
|
uint32_t ppi_irq_clear_addr;
|
||||||
|
uint32_t ppi_irq_cmd_addr;
|
||||||
|
uint32_t ppi_rst_cmd_addr;
|
||||||
|
uint32_t ppi_test_bus_ctrl_addr;
|
||||||
|
uint32_t ppi_debug_addr;
|
||||||
|
uint32_t ppi_spare_addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct cam_csid_ppi_hw_info- ppi HW info
|
||||||
|
*
|
||||||
|
* @ppi_reg: ppi register offsets
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct cam_csid_ppi_hw_info {
|
||||||
|
const struct cam_csid_ppi_reg_offset *ppi_reg;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct cam_csid_ppi_hw- ppi hw device resources data
|
||||||
|
*
|
||||||
|
* @hw_intf: contain the ppi hw interface information
|
||||||
|
* @hw_info: ppi hw device information
|
||||||
|
* @ppi_info: ppi hw specific information
|
||||||
|
* @device_enabled Device enabled will set once ppi powered on and
|
||||||
|
* initial configuration are done.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct cam_csid_ppi_hw {
|
||||||
|
struct cam_hw_intf *hw_intf;
|
||||||
|
struct cam_hw_info *hw_info;
|
||||||
|
struct cam_csid_ppi_hw_info *ppi_info;
|
||||||
|
uint32_t device_enabled;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct cam_csid_ppi_cfg - ppi lane configuration data
|
||||||
|
* @lane_type: lane type: c-phy or d-phy
|
||||||
|
* @lane_num : active lane number
|
||||||
|
* @lane_cfg: lane configurations: 4 bits per lane
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct cam_csid_ppi_cfg {
|
||||||
|
uint32_t lane_type;
|
||||||
|
uint32_t lane_num;
|
||||||
|
uint32_t lane_cfg;
|
||||||
|
};
|
||||||
|
|
||||||
|
int cam_csid_ppi_hw_probe_init(struct cam_hw_intf *ppi_hw_intf,
|
||||||
|
uint32_t ppi_idx);
|
||||||
|
int cam_csid_ppi_hw_deinit(struct cam_csid_ppi_hw *csid_ppi_hw);
|
||||||
|
int cam_csid_ppi_init_soc_resources(struct cam_hw_soc_info *soc_info,
|
||||||
|
irq_handler_t ppi_irq_handler, void *irq_data);
|
||||||
|
int cam_csid_ppi_deinit_soc_resources(struct cam_hw_soc_info *soc_info);
|
||||||
|
int cam_csid_ppi_hw_init(struct cam_hw_intf **csid_ppi_hw,
|
||||||
|
uint32_t hw_idx);
|
||||||
|
#endif /* _CAM_CSID_PPI_HW_H_ */
|
164
drivers/cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi_dev.c
Normal file
164
drivers/cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi_dev.c
Normal file
@@ -0,0 +1,164 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/slab.h>
|
||||||
|
#include <linux/mod_devicetable.h>
|
||||||
|
#include <linux/of_device.h>
|
||||||
|
#include <linux/component.h>
|
||||||
|
|
||||||
|
#include "cam_isp_hw.h"
|
||||||
|
#include "cam_hw_intf.h"
|
||||||
|
#include "cam_csid_ppi_core.h"
|
||||||
|
#include "cam_csid_ppi_dev.h"
|
||||||
|
#include "cam_debug_util.h"
|
||||||
|
|
||||||
|
static struct cam_hw_intf *cam_csid_ppi_hw_list[CAM_CSID_PPI_HW_MAX] = {
|
||||||
|
NULL, NULL, NULL, NULL};
|
||||||
|
static char ppi_dev_name[8];
|
||||||
|
|
||||||
|
static int cam_ppi_component_bind(struct device *dev,
|
||||||
|
struct device *master_dev, void *data)
|
||||||
|
{
|
||||||
|
struct cam_hw_intf *ppi_hw_intf;
|
||||||
|
struct cam_hw_info *ppi_hw_info;
|
||||||
|
struct cam_csid_ppi_hw *ppi_dev = NULL;
|
||||||
|
const struct of_device_id *match_dev = NULL;
|
||||||
|
struct cam_csid_ppi_hw_info *ppi_hw_data = NULL;
|
||||||
|
uint32_t ppi_dev_idx;
|
||||||
|
int rc = 0;
|
||||||
|
struct platform_device *pdev = to_platform_device(dev);
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ISP, "PPI probe called");
|
||||||
|
|
||||||
|
ppi_hw_intf = kzalloc(sizeof(struct cam_hw_intf), GFP_KERNEL);
|
||||||
|
if (!ppi_hw_intf) {
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppi_hw_info = kzalloc(sizeof(struct cam_hw_info), GFP_KERNEL);
|
||||||
|
if (!ppi_hw_info) {
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto free_hw_intf;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppi_dev = kzalloc(sizeof(struct cam_csid_ppi_hw), GFP_KERNEL);
|
||||||
|
if (!ppi_dev) {
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto free_hw_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
of_property_read_u32(pdev->dev.of_node, "cell-index", &ppi_dev_idx);
|
||||||
|
|
||||||
|
match_dev = of_match_device(pdev->dev.driver->of_match_table,
|
||||||
|
&pdev->dev);
|
||||||
|
if (!match_dev) {
|
||||||
|
CAM_ERR(CAM_ISP, "No matching table for the CSID PPI HW!");
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto free_dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(ppi_dev_name, 0, sizeof(ppi_dev_name));
|
||||||
|
snprintf(ppi_dev_name, sizeof(ppi_dev_name), "ppi%1u", ppi_dev_idx);
|
||||||
|
|
||||||
|
ppi_hw_intf->hw_idx = ppi_dev_idx;
|
||||||
|
ppi_hw_intf->hw_priv = ppi_hw_info;
|
||||||
|
|
||||||
|
if (ppi_hw_intf->hw_idx < CAM_CSID_PPI_HW_MAX)
|
||||||
|
cam_csid_ppi_hw_list[ppi_hw_intf->hw_idx] = ppi_hw_intf;
|
||||||
|
else {
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto free_dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
ppi_hw_info->core_info = ppi_dev;
|
||||||
|
ppi_hw_info->soc_info.pdev = pdev;
|
||||||
|
ppi_hw_info->soc_info.dev = &pdev->dev;
|
||||||
|
ppi_hw_info->soc_info.dev_name = ppi_dev_name;
|
||||||
|
ppi_hw_info->soc_info.index = ppi_dev_idx;
|
||||||
|
|
||||||
|
ppi_hw_data = (struct cam_csid_ppi_hw_info *)match_dev->data;
|
||||||
|
ppi_dev->ppi_info = ppi_hw_data;
|
||||||
|
|
||||||
|
rc = cam_csid_ppi_hw_probe_init(ppi_hw_intf, ppi_dev_idx);
|
||||||
|
if (rc) {
|
||||||
|
CAM_ERR(CAM_ISP, "PPI: Probe init failed!");
|
||||||
|
goto free_dev;
|
||||||
|
}
|
||||||
|
|
||||||
|
platform_set_drvdata(pdev, ppi_dev);
|
||||||
|
CAM_DBG(CAM_ISP, "PPI:%d probe successful",
|
||||||
|
ppi_hw_intf->hw_idx);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
free_dev:
|
||||||
|
kfree(ppi_dev);
|
||||||
|
free_hw_info:
|
||||||
|
kfree(ppi_hw_info);
|
||||||
|
free_hw_intf:
|
||||||
|
kfree(ppi_hw_intf);
|
||||||
|
err:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cam_ppi_component_unbind(struct device *dev,
|
||||||
|
struct device *master_dev, void *data)
|
||||||
|
{
|
||||||
|
struct cam_csid_ppi_hw *ppi_dev = NULL;
|
||||||
|
struct cam_hw_intf *ppi_hw_intf;
|
||||||
|
struct cam_hw_info *ppi_hw_info;
|
||||||
|
struct platform_device *pdev = to_platform_device(dev);
|
||||||
|
|
||||||
|
ppi_dev = (struct cam_csid_ppi_hw *)platform_get_drvdata(pdev);
|
||||||
|
ppi_hw_intf = ppi_dev->hw_intf;
|
||||||
|
ppi_hw_info = ppi_dev->hw_info;
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ISP, "PPI:%d remove", ppi_dev->hw_intf->hw_idx);
|
||||||
|
|
||||||
|
cam_csid_ppi_hw_deinit(ppi_dev);
|
||||||
|
|
||||||
|
kfree(ppi_dev);
|
||||||
|
kfree(ppi_hw_info);
|
||||||
|
kfree(ppi_hw_intf);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cam_csid_ppi_hw_init(struct cam_hw_intf **csid_ppi_hw,
|
||||||
|
uint32_t hw_idx)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
if (cam_csid_ppi_hw_list[hw_idx]) {
|
||||||
|
*csid_ppi_hw = cam_csid_ppi_hw_list[hw_idx];
|
||||||
|
} else {
|
||||||
|
*csid_ppi_hw = NULL;
|
||||||
|
rc = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(cam_csid_ppi_hw_init);
|
||||||
|
|
||||||
|
const static struct component_ops cam_ppi_component_ops = {
|
||||||
|
.bind = cam_ppi_component_bind,
|
||||||
|
.unbind = cam_ppi_component_unbind,
|
||||||
|
};
|
||||||
|
|
||||||
|
int cam_csid_ppi_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ISP, "Adding PPI component");
|
||||||
|
rc = component_add(&pdev->dev, &cam_ppi_component_ops);
|
||||||
|
if (rc)
|
||||||
|
CAM_ERR(CAM_ISP, "failed to add component rc: %d", rc);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int cam_csid_ppi_remove(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
component_del(&pdev->dev, &cam_ppi_component_ops);
|
||||||
|
return 0;
|
||||||
|
}
|
15
drivers/cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi_dev.h
Normal file
15
drivers/cam_isp/isp_hw_mgr/isp_hw/ppi_hw/cam_csid_ppi_dev.h
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CAM_CSID_PPI_DEV_H_
|
||||||
|
#define _CAM_CSID_PPI_DEV_H_
|
||||||
|
|
||||||
|
#include "cam_isp_hw.h"
|
||||||
|
|
||||||
|
irqreturn_t cam_csid_ppi_irq(int irq_num, void *data);
|
||||||
|
int cam_csid_ppi_probe(struct platform_device *pdev);
|
||||||
|
int cam_csid_ppi_remove(struct platform_device *pdev);
|
||||||
|
|
||||||
|
#endif /*_CAM_CSID_PPI_DEV_H_ */
|
@@ -9,6 +9,7 @@
|
|||||||
#include <media/cam_defs.h>
|
#include <media/cam_defs.h>
|
||||||
|
|
||||||
#include "cam_tfe_csid_core.h"
|
#include "cam_tfe_csid_core.h"
|
||||||
|
#include "cam_csid_ppi_core.h"
|
||||||
#include "cam_isp_hw.h"
|
#include "cam_isp_hw.h"
|
||||||
#include "cam_soc_util.h"
|
#include "cam_soc_util.h"
|
||||||
#include "cam_io_util.h"
|
#include "cam_io_util.h"
|
||||||
@@ -733,7 +734,9 @@ static int cam_tfe_csid_enable_csi2(
|
|||||||
{
|
{
|
||||||
const struct cam_tfe_csid_reg_offset *csid_reg;
|
const struct cam_tfe_csid_reg_offset *csid_reg;
|
||||||
struct cam_hw_soc_info *soc_info;
|
struct cam_hw_soc_info *soc_info;
|
||||||
|
struct cam_csid_ppi_cfg ppi_lane_cfg;
|
||||||
uint32_t val = 0;
|
uint32_t val = 0;
|
||||||
|
uint32_t ppi_index = 0, rc;
|
||||||
|
|
||||||
csid_reg = csid_hw->csid_info->csid_reg;
|
csid_reg = csid_hw->csid_info->csid_reg;
|
||||||
soc_info = &csid_hw->hw_info->soc_info;
|
soc_info = &csid_hw->hw_info->soc_info;
|
||||||
@@ -797,6 +800,25 @@ static int cam_tfe_csid_enable_csi2(
|
|||||||
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
|
cam_io_w_mb(val, soc_info->reg_map[0].mem_base +
|
||||||
csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
|
csid_reg->csi2_reg->csid_csi2_rx_irq_mask_addr);
|
||||||
|
|
||||||
|
ppi_index = csid_hw->csi2_rx_cfg.phy_sel;
|
||||||
|
if (csid_hw->ppi_hw_intf[ppi_index] && csid_hw->ppi_enable) {
|
||||||
|
ppi_lane_cfg.lane_type = csid_hw->csi2_rx_cfg.lane_type;
|
||||||
|
ppi_lane_cfg.lane_num = csid_hw->csi2_rx_cfg.lane_num;
|
||||||
|
ppi_lane_cfg.lane_cfg = csid_hw->csi2_rx_cfg.lane_cfg;
|
||||||
|
|
||||||
|
CAM_DBG(CAM_ISP, "ppi_index to init %d", ppi_index);
|
||||||
|
rc = csid_hw->ppi_hw_intf[ppi_index]->hw_ops.init(
|
||||||
|
csid_hw->ppi_hw_intf[ppi_index]->hw_priv,
|
||||||
|
&ppi_lane_cfg,
|
||||||
|
sizeof(struct cam_csid_ppi_cfg));
|
||||||
|
if (rc < 0) {
|
||||||
|
CAM_ERR(CAM_ISP, "PPI:%d Init Failed",
|
||||||
|
ppi_index);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -805,6 +827,7 @@ static int cam_tfe_csid_disable_csi2(
|
|||||||
{
|
{
|
||||||
const struct cam_tfe_csid_reg_offset *csid_reg;
|
const struct cam_tfe_csid_reg_offset *csid_reg;
|
||||||
struct cam_hw_soc_info *soc_info;
|
struct cam_hw_soc_info *soc_info;
|
||||||
|
uint32_t ppi_index = 0, rc;
|
||||||
|
|
||||||
csid_reg = csid_hw->csid_info->csid_reg;
|
csid_reg = csid_hw->csid_info->csid_reg;
|
||||||
soc_info = &csid_hw->hw_info->soc_info;
|
soc_info = &csid_hw->hw_info->soc_info;
|
||||||
@@ -821,6 +844,19 @@ static int cam_tfe_csid_disable_csi2(
|
|||||||
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
|
cam_io_w_mb(0, soc_info->reg_map[0].mem_base +
|
||||||
csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
|
csid_reg->csi2_reg->csid_csi2_rx_cfg1_addr);
|
||||||
|
|
||||||
|
ppi_index = csid_hw->csi2_rx_cfg.phy_sel;
|
||||||
|
if (csid_hw->ppi_hw_intf[ppi_index] && csid_hw->ppi_enable) {
|
||||||
|
/* De-Initialize the PPI bridge */
|
||||||
|
CAM_DBG(CAM_ISP, "ppi_index to de-init %d\n", ppi_index);
|
||||||
|
rc = csid_hw->ppi_hw_intf[ppi_index]->hw_ops.deinit(
|
||||||
|
csid_hw->ppi_hw_intf[ppi_index]->hw_priv,
|
||||||
|
NULL, 0);
|
||||||
|
if (rc < 0) {
|
||||||
|
CAM_ERR(CAM_ISP, "PPI:%d De-Init Failed", ppi_index);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2456,13 +2492,14 @@ irqreturn_t cam_tfe_csid_irq(int irq_num, void *data)
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
uint32_t i, val;
|
uint32_t i, val;
|
||||||
|
|
||||||
csid_hw = (struct cam_tfe_csid_hw *)data;
|
|
||||||
|
|
||||||
if (!data) {
|
if (!data) {
|
||||||
CAM_ERR(CAM_ISP, "CSID: Invalid arguments");
|
CAM_ERR(CAM_ISP, "CSID: Invalid arguments");
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
csid_hw = (struct cam_tfe_csid_hw *)data;
|
||||||
|
CAM_DBG(CAM_ISP, "CSID %d IRQ Handling", csid_hw->hw_intf->hw_idx);
|
||||||
|
|
||||||
csid_reg = csid_hw->csid_info->csid_reg;
|
csid_reg = csid_hw->csid_info->csid_reg;
|
||||||
soc_info = &csid_hw->hw_info->soc_info;
|
soc_info = &csid_hw->hw_info->soc_info;
|
||||||
csi2_reg = csid_reg->csi2_reg;
|
csi2_reg = csid_reg->csi2_reg;
|
||||||
@@ -2961,6 +2998,23 @@ int cam_tfe_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check if ppi bridge is present or not? */
|
||||||
|
tfe_csid_hw->ppi_enable = of_property_read_bool(
|
||||||
|
csid_hw_info->soc_info.pdev->dev.of_node,
|
||||||
|
"ppi-enable");
|
||||||
|
|
||||||
|
if (!tfe_csid_hw->ppi_enable)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Initialize the PPI bridge */
|
||||||
|
for (i = 0; i < CAM_CSID_PPI_HW_MAX; i++) {
|
||||||
|
rc = cam_csid_ppi_hw_init(&tfe_csid_hw->ppi_hw_intf[i], i);
|
||||||
|
if (rc < 0) {
|
||||||
|
CAM_ERR(CAM_ISP, "PPI init failed for PPI %d", i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
err:
|
err:
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
#include "cam_hw.h"
|
#include "cam_hw.h"
|
||||||
#include "cam_tfe_csid_hw_intf.h"
|
#include "cam_tfe_csid_hw_intf.h"
|
||||||
#include "cam_tfe_csid_soc.h"
|
#include "cam_tfe_csid_soc.h"
|
||||||
|
#include "cam_csid_ppi_core.h"
|
||||||
|
|
||||||
#define CAM_TFE_CSID_CID_MAX 4
|
#define CAM_TFE_CSID_CID_MAX 4
|
||||||
|
|
||||||
@@ -383,6 +384,9 @@ struct cam_tfe_csid_path_cfg {
|
|||||||
* @lock_state csid spin lock
|
* @lock_state csid spin lock
|
||||||
* @event_cb: Callback function to hw mgr in case of hw events
|
* @event_cb: Callback function to hw mgr in case of hw events
|
||||||
* @event_cb_priv: Context data
|
* @event_cb_priv: Context data
|
||||||
|
* @ppi_hw_intf interface to ppi hardware
|
||||||
|
* @ppi_enabled flag to specify if the hardware has ppi bridge
|
||||||
|
* or not
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
struct cam_tfe_csid_hw {
|
struct cam_tfe_csid_hw {
|
||||||
@@ -409,6 +413,8 @@ struct cam_tfe_csid_hw {
|
|||||||
spinlock_t spin_lock;
|
spinlock_t spin_lock;
|
||||||
cam_hw_mgr_event_cb_func event_cb;
|
cam_hw_mgr_event_cb_func event_cb;
|
||||||
void *event_cb_priv;
|
void *event_cb_priv;
|
||||||
|
struct cam_hw_intf *ppi_hw_intf[CAM_CSID_PPI_HW_MAX];
|
||||||
|
bool ppi_enable;
|
||||||
};
|
};
|
||||||
|
|
||||||
int cam_tfe_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
|
int cam_tfe_csid_hw_probe_init(struct cam_hw_intf *csid_hw_intf,
|
||||||
|
@@ -54,6 +54,7 @@
|
|||||||
#include "cam_top_tpg.h"
|
#include "cam_top_tpg.h"
|
||||||
#include "cam_tfe_dev.h"
|
#include "cam_tfe_dev.h"
|
||||||
#include "cam_tfe_csid530.h"
|
#include "cam_tfe_csid530.h"
|
||||||
|
#include "cam_csid_ppi100.h"
|
||||||
#include "camera_main.h"
|
#include "camera_main.h"
|
||||||
|
|
||||||
struct camera_submodule_component {
|
struct camera_submodule_component {
|
||||||
@@ -76,6 +77,15 @@ static const struct camera_submodule_component camera_base[] = {
|
|||||||
{&cam_hw_cdm_init_module, &cam_hw_cdm_exit_module},
|
{&cam_hw_cdm_init_module, &cam_hw_cdm_exit_module},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct camera_submodule_component camera_tfe[] = {
|
||||||
|
#ifdef CONFIG_SPECTRA_TFE
|
||||||
|
{&cam_top_tpg_init_module, &cam_top_tpg_exit_module},
|
||||||
|
{&cam_csid_ppi100_init_module, &cam_csid_ppi100_exit_module},
|
||||||
|
{&cam_tfe_init_module, &cam_tfe_exit_module},
|
||||||
|
{&cam_tfe_csid530_init_module, &cam_tfe_csid530_exit_module},
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
static const struct camera_submodule_component camera_isp[] = {
|
static const struct camera_submodule_component camera_isp[] = {
|
||||||
#ifdef CONFIG_SPECTRA_ISP
|
#ifdef CONFIG_SPECTRA_ISP
|
||||||
{&cam_top_tpg_init_module, &cam_top_tpg_exit_module},
|
{&cam_top_tpg_init_module, &cam_top_tpg_exit_module},
|
||||||
@@ -86,14 +96,6 @@ static const struct camera_submodule_component camera_isp[] = {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct camera_submodule_component camera_tfe[] = {
|
|
||||||
#ifdef CONFIG_SPECTRA_TFE
|
|
||||||
{&cam_top_tpg_init_module, &cam_top_tpg_exit_module},
|
|
||||||
{&cam_tfe_init_module, &cam_tfe_exit_module},
|
|
||||||
{&cam_tfe_csid530_init_module, &cam_tfe_csid530_exit_module},
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct camera_submodule_component camera_sensor[] = {
|
static const struct camera_submodule_component camera_sensor[] = {
|
||||||
#ifdef CONFIG_SPECTRA_SENSOR
|
#ifdef CONFIG_SPECTRA_SENSOR
|
||||||
{&cam_res_mgr_init, &cam_res_mgr_exit},
|
{&cam_res_mgr_init, &cam_res_mgr_exit},
|
||||||
@@ -162,16 +164,16 @@ static const struct camera_submodule submodule_table[] = {
|
|||||||
.num_component = ARRAY_SIZE(camera_base),
|
.num_component = ARRAY_SIZE(camera_base),
|
||||||
.component = camera_base,
|
.component = camera_base,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
.name = "Camera ISP",
|
|
||||||
.num_component = ARRAY_SIZE(camera_isp),
|
|
||||||
.component = camera_isp,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
.name = "Camera TFE",
|
.name = "Camera TFE",
|
||||||
.num_component = ARRAY_SIZE(camera_tfe),
|
.num_component = ARRAY_SIZE(camera_tfe),
|
||||||
.component = camera_tfe,
|
.component = camera_tfe,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.name = "Camera ISP",
|
||||||
|
.num_component = ARRAY_SIZE(camera_isp),
|
||||||
|
.component = camera_isp,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.name = "Camera SENSOR",
|
.name = "Camera SENSOR",
|
||||||
.num_component = ARRAY_SIZE(camera_sensor),
|
.num_component = ARRAY_SIZE(camera_sensor),
|
||||||
|
Reference in New Issue
Block a user