summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLakshmi Narayana Kalavala <lkalaval@codeaurora.org>2016-02-18 16:50:33 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-25 16:02:54 -0700
commitb6e680b53b89430e9025828ccd49db78fb90664b (patch)
tree053ecd11831ea19da88fe9b1079faa0a1ac9ba69 /drivers
parent5a3ebc46d9ebe39de0fd9d39ed5267a5d37f4b3d (diff)
msm: cpp: Changes to adapt cpp driver to soc layer
Adapt CPP driver to SOC layer by replacing the msm specific routines with SOC API which eases the portability of cpp driver on to non-msm platforms. Change-Id: I8cd6bdcaa9d310b770f2dfe66047c64316a309de Signed-off-by: Lakshmi Narayana Kalavala <lkalaval@codeaurora.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/platform/msm/camera_v2/pproc/cpp/Makefile2
-rw-r--r--drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c675
-rw-r--r--drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h25
-rw-r--r--drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c249
4 files changed, 392 insertions, 559 deletions
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/Makefile b/drivers/media/platform/msm/camera_v2/pproc/cpp/Makefile
index 17fb6dfd8dcd..56880f4d5676 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/Makefile
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/Makefile
@@ -2,4 +2,4 @@ ccflags-y += -Idrivers/media/platform/msm/camera_v2
ccflags-y += -Idrivers/media/platform/msm/camera_v2/isp/
ccflags-y += -Idrivers/media/platform/msm/camera_v2/sensor/io
ccflags-y += -Idrivers/media/platform/msm/camera_v2/common
-obj-$(CONFIG_MSM_CPP) += msm_cpp.o
+obj-$(CONFIG_MSM_CPP) += msm_cpp_soc.o msm_cpp.o
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
index 0cca1260b308..abfe0529bdab 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
@@ -14,12 +14,10 @@
#include <linux/delay.h>
-#include <linux/clk.h>
#include <linux/firmware.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/module.h>
-#include <linux/regulator/consumer.h>
#include <linux/ion.h>
#include <linux/proc_fs.h>
#include <linux/msm_ion.h>
@@ -27,20 +25,17 @@
#include <linux/timer.h>
#include <linux/kernel.h>
#include <linux/workqueue.h>
-#include <linux/clk/msm-clk.h>
#include <media/msm_isp.h>
#include <media/v4l2-event.h>
#include <media/v4l2-ioctl.h>
#include <media/msmb_camera.h>
#include <media/msmb_generic_buf_mgr.h>
#include <media/msmb_pproc.h>
-#include <linux/clk/msm-clk-provider.h>
#include "msm_cpp.h"
#include "msm_isp_util.h"
#include "msm_camera_io_util.h"
#include <linux/debugfs.h>
#include "cam_smmu_api.h"
-#include "cam_hw_ops.h"
#define MSM_CPP_DRV_NAME "msm_cpp"
@@ -81,17 +76,6 @@
#define POP_BACK 0
#define BATCH_DUP_MASK 0x100
-#define CPP_DT_READ_U32_ERR(_dev, _key, _str, _ret, _out) { \
- _key = _str; \
- _ret = of_property_read_u32(_dev, _key, &_out); \
- if (_ret) \
- break; \
- }
-
-#define CPP_DT_READ_U32(_dev, _str, _out) { \
- of_property_read_u32(_dev, _str, &_out); \
- }
-
#define IS_BATCH_BUFFER_ON_PREVIEW(new_frame) \
(((new_frame->batch_info.batch_mode == BATCH_MODE_PREVIEW) && \
new_frame->duplicate_output) ? 1 : 0)
@@ -124,57 +108,6 @@ static int msm_cpp_update_gdscr_status(struct cpp_device *cpp_dev,
((to) ? "to" : "from"))
#define ERR_COPY_FROM_USER() ERR_USER_COPY(0)
-/* CPP bus bandwidth definitions */
-static struct msm_bus_vectors msm_cpp_init_vectors[] = {
- {
- .src = MSM_BUS_MASTER_CPP,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 0,
- .ib = 0,
- },
-};
-
-static struct msm_bus_vectors msm_cpp_ping_vectors[] = {
- {
- .src = MSM_BUS_MASTER_CPP,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 0,
- .ib = 0,
- },
-};
-
-static struct msm_bus_vectors msm_cpp_pong_vectors[] = {
- {
- .src = MSM_BUS_MASTER_CPP,
- .dst = MSM_BUS_SLAVE_EBI_CH0,
- .ab = 0,
- .ib = 0,
- },
-};
-
-
-
-static struct msm_bus_paths msm_cpp_bus_client_config[] = {
- {
- ARRAY_SIZE(msm_cpp_init_vectors),
- msm_cpp_init_vectors,
- },
- {
- ARRAY_SIZE(msm_cpp_ping_vectors),
- msm_cpp_ping_vectors,
- },
- {
- ARRAY_SIZE(msm_cpp_pong_vectors),
- msm_cpp_pong_vectors,
- },
-};
-
-static struct msm_bus_scale_pdata msm_cpp_bus_scale_data = {
- msm_cpp_bus_client_config,
- ARRAY_SIZE(msm_cpp_bus_client_config),
- .name = "msm_camera_cpp",
-};
-
#define msm_dequeue(queue, member, pop_dir) ({ \
unsigned long flags; \
struct msm_device_queue *__q = (queue); \
@@ -213,21 +146,18 @@ static int msm_cpp_init_bandwidth_mgr(struct cpp_device *cpp_dev)
{
int rc = 0;
- cpp_dev->bus_client =
- msm_bus_scale_register_client(&msm_cpp_bus_scale_data);
- if (!cpp_dev->bus_client) {
+ rc = msm_camera_register_bus_client(cpp_dev->pdev, CAM_BUS_CLIENT_CPP);
+ if (rc < 0) {
pr_err("Fail to register bus client\n");
return -ENOENT;
}
- rc = msm_bus_scale_client_update_request(cpp_dev->bus_client, 0);
+ rc = msm_camera_update_bus_bw(CAM_BUS_CLIENT_CPP, 0, 0);
if (rc < 0) {
- msm_bus_scale_unregister_client(cpp_dev->bus_client);
- cpp_dev->bus_client = 0;
+ msm_camera_unregister_bus_client(CAM_BUS_CLIENT_CPP);
pr_err("Fail bus scale update %d\n", rc);
return -EINVAL;
}
- cpp_dev->bus_idx = 1;
return 0;
}
@@ -237,16 +167,8 @@ static int msm_cpp_update_bandwidth(struct cpp_device *cpp_dev,
{
int rc;
- struct msm_bus_paths *path;
-
- cpp_dev->bus_idx = 3 - cpp_dev->bus_idx;
- path = &(msm_cpp_bus_scale_data.usecase[cpp_dev->bus_idx]);
- path->vectors[0].ab = ab;
- path->vectors[0].ib = ib;
-
- rc = msm_bus_scale_client_update_request(cpp_dev->bus_client,
- cpp_dev->bus_idx);
+ rc = msm_camera_update_bus_bw(CAM_BUS_CLIENT_CPP, ab, ib);
if (rc < 0) {
pr_err("Fail bus scale update %d\n", rc);
return -EINVAL;
@@ -257,9 +179,12 @@ static int msm_cpp_update_bandwidth(struct cpp_device *cpp_dev,
void msm_cpp_deinit_bandwidth_mgr(struct cpp_device *cpp_dev)
{
- if (cpp_dev->bus_client) {
- msm_bus_scale_unregister_client(cpp_dev->bus_client);
- cpp_dev->bus_client = 0;
+ int rc = 0;
+
+ rc = msm_camera_unregister_bus_client(CAM_BUS_CLIENT_CPP);
+ if (rc < 0) {
+ pr_err("Failed to unregister %d\n", rc);
+ return;
}
}
@@ -316,17 +241,6 @@ static void msm_enqueue(struct msm_device_queue *queue,
} \
}
-static struct msm_cam_clk_info cpp_clk_info[CPP_CLK_INFO_MAX];
-
-static int get_clock_index(const char *clk_name)
-{
- uint32_t i = 0;
- for (i = 0; i < ARRAY_SIZE(cpp_clk_info); i++) {
- if (!strcmp(clk_name, cpp_clk_info[i].clk_name))
- return i;
- }
- return -EINVAL;
-}
static int msm_cpp_notify_frame_done(struct cpp_device *cpp_dev,
@@ -848,111 +762,9 @@ void msm_cpp_do_tasklet(unsigned long data)
}
}
-static void cpp_get_clk_freq_tbl(struct clk *clk, struct cpp_hw_info *hw_info,
- uint32_t min_clk_rate)
-{
- uint32_t i;
- uint32_t idx = 0;
- signed long freq_tbl_entry = 0;
-
- if ((clk == NULL) || (hw_info == NULL) || (clk->ops == NULL) ||
- (clk->ops->list_rate == NULL)) {
- pr_err("Bad parameter\n");
- return;
- }
-
- for (i = 0; i < MAX_FREQ_TBL; i++) {
- freq_tbl_entry = clk->ops->list_rate(clk, i);
- pr_debug("entry=%ld\n", freq_tbl_entry);
- if (freq_tbl_entry >= 0) {
- if (freq_tbl_entry >= min_clk_rate) {
- hw_info->freq_tbl[idx++] = freq_tbl_entry;
- pr_debug("tbl[%d]=%ld\n", idx-1,
- freq_tbl_entry);
- }
- } else {
- pr_debug("freq table returned invalid entry/end %ld\n",
- freq_tbl_entry);
- break;
- }
- }
-
- pr_debug("%s: idx %d", __func__, idx);
- hw_info->freq_tbl_count = idx;
-}
-
-static int msm_cpp_read_payload_params_from_dt(struct cpp_device *cpp_dev)
-{
- struct platform_device *pdev = cpp_dev->pdev;
- struct device_node *fw_info_node = NULL, *dev_node = NULL;
- char *key = "qcom,cpp-fw-payload-info";
- struct msm_cpp_payload_params *payload_params;
- int ret = 0;
-
- if (!pdev || !pdev->dev.of_node) {
- pr_err("%s: Invalid platform device/node\n", __func__);
- ret = -ENODEV;
- goto no_cpp_node;
- }
-
- dev_node = pdev->dev.of_node;
- fw_info_node = of_find_node_by_name(dev_node, key);
- if (!fw_info_node) {
- ret = -ENODEV;
- goto no_binding;
- }
- payload_params = &cpp_dev->payload_params;
- memset(payload_params, 0x0, sizeof(struct msm_cpp_payload_params));
-
- do {
- CPP_DT_READ_U32_ERR(fw_info_node, key, "qcom,stripe-base", ret,
- payload_params->stripe_base);
- CPP_DT_READ_U32_ERR(fw_info_node, key, "qcom,plane-base", ret,
- payload_params->plane_base);
- CPP_DT_READ_U32_ERR(fw_info_node, key, "qcom,stripe-size", ret,
- payload_params->stripe_size);
- CPP_DT_READ_U32_ERR(fw_info_node, key, "qcom,plane-size", ret,
- payload_params->plane_size);
- CPP_DT_READ_U32_ERR(fw_info_node, key, "qcom,fe-ptr-off", ret,
- payload_params->rd_pntr_off);
- CPP_DT_READ_U32_ERR(fw_info_node, key, "qcom,we-ptr-off", ret,
- payload_params->wr_0_pntr_off);
-
- CPP_DT_READ_U32(fw_info_node, "qcom,ref-fe-ptr-off",
- payload_params->rd_ref_pntr_off);
- CPP_DT_READ_U32(fw_info_node, "qcom,ref-we-ptr-off",
- payload_params->wr_ref_pntr_off);
- CPP_DT_READ_U32(fw_info_node, "qcom,we-meta-ptr-off",
- payload_params->wr_0_meta_data_wr_pntr_off);
- CPP_DT_READ_U32(fw_info_node, "qcom,fe-mmu-pf-ptr-off",
- payload_params->fe_mmu_pf_ptr_off);
- CPP_DT_READ_U32(fw_info_node, "qcom,ref-fe-mmu-pf-ptr-off",
- payload_params->ref_fe_mmu_pf_ptr_off);
- CPP_DT_READ_U32(fw_info_node, "qcom,we-mmu-pf-ptr-off",
- payload_params->we_mmu_pf_ptr_off);
- CPP_DT_READ_U32(fw_info_node, "qcom,dup-we-mmu-pf-ptr-off",
- payload_params->dup_we_mmu_pf_ptr_off);
- CPP_DT_READ_U32(fw_info_node, "qcom,ref-we-mmu-pf-ptr-off",
- payload_params->ref_we_mmu_pf_ptr_off);
- CPP_DT_READ_U32(fw_info_node, "qcom,set-group-buffer-len",
- payload_params->set_group_buffer_len);
- CPP_DT_READ_U32(fw_info_node, "qcom,dup-frame-indicator-off",
- payload_params->dup_frame_indicator_off);
- } while (0);
-
-no_binding:
- if (ret)
- pr_err("%s: Error reading binding %s, ret %d\n",
- __func__, key, ret);
-no_cpp_node:
- return ret;
-}
-
static int cpp_init_hardware(struct cpp_device *cpp_dev)
{
int rc = 0;
- uint32_t msm_cpp_core_clk_idx;
- uint32_t msm_micro_iface_idx;
uint32_t vbif_version;
rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CPP,
@@ -962,169 +774,31 @@ static int cpp_init_hardware(struct cpp_device *cpp_dev)
goto ahb_vote_fail;
}
- if (cpp_dev->bus_master_flag)
- rc = msm_cpp_init_bandwidth_mgr(cpp_dev);
- else
- rc = msm_isp_init_bandwidth_mgr(ISP_CPP);
+ rc = msm_camera_regulator_enable(cpp_dev->cpp_vdd,
+ cpp_dev->num_reg, true);
if (rc < 0) {
- pr_err("%s: Bandwidth registration Failed!\n", __func__);
- goto bus_scale_register_failed;
- }
-
- if (of_get_property(cpp_dev->pdev->dev.of_node,
- "mmagic-vdd-supply", NULL) &&
- (cpp_dev->fs_mmagic_camss == NULL)) {
- cpp_dev->fs_mmagic_camss = regulator_get(&cpp_dev->pdev->dev,
- "mmagic-vdd");
- if (IS_ERR(cpp_dev->fs_mmagic_camss)) {
- pr_debug("%s: Regulator mmagic get failed %ld\n",
- __func__, PTR_ERR(cpp_dev->fs_mmagic_camss));
- cpp_dev->fs_mmagic_camss = NULL;
- rc = -ENODEV;
- goto fs_mmagic_failed;
- }
- rc = regulator_enable(cpp_dev->fs_mmagic_camss);
- if (rc) {
- pr_err("%s: Regulator enable mmagic camss failed\n",
- __func__);
- regulator_put(cpp_dev->fs_mmagic_camss);
- cpp_dev->fs_mmagic_camss = NULL;
- goto fs_mmagic_failed;
- }
- }
-
- if (of_get_property(cpp_dev->pdev->dev.of_node,
- "camss-vdd-supply", NULL) &&
- (cpp_dev->fs_camss == NULL)) {
- cpp_dev->fs_camss = regulator_get(&cpp_dev->pdev->dev,
- "camss-vdd");
- if (IS_ERR(cpp_dev->fs_camss)) {
- pr_err("%s: Regulator camss get failed %ld\n",
- __func__, PTR_ERR(cpp_dev->fs_camss));
- cpp_dev->fs_camss = NULL;
- rc = -ENODEV;
- goto fs_camss_failed;
- }
- rc = regulator_enable(cpp_dev->fs_camss);
- if (rc) {
- pr_err("%s: Regulator enable camss failed\n", __func__);
- regulator_put(cpp_dev->fs_camss);
- cpp_dev->fs_camss = NULL;
- goto fs_camss_failed;
- }
+ pr_err("%s: failed to enable regulators\n", __func__);
+ goto reg_enable_failed;
}
- if (cpp_dev->fs_cpp == NULL) {
- cpp_dev->fs_cpp =
- regulator_get(&cpp_dev->pdev->dev, "vdd");
- if (IS_ERR(cpp_dev->fs_cpp)) {
- pr_err("Regulator cpp vdd get failed %ld\n",
- PTR_ERR(cpp_dev->fs_cpp));
- rc = -ENODEV;
- cpp_dev->fs_cpp = NULL;
- goto fs_failed;
- }
-
- rc = regulator_enable(cpp_dev->fs_cpp);
- if (rc != 0) {
- pr_err("Regulator cpp vdd enable failed\n");
- regulator_put(cpp_dev->fs_cpp);
- cpp_dev->fs_cpp = NULL;
- goto fs_failed;
- }
- }
- msm_micro_iface_idx = get_clock_index("micro_iface_clk");
- if (msm_micro_iface_idx < 0) {
- pr_err("Fail to get clock index\n");
- rc = msm_micro_iface_idx;
+ rc = msm_cpp_set_micro_clk(cpp_dev);
+ if (rc < 0) {
+ pr_err("%s: set micro clk failed\n", __func__);
goto clk_failed;
}
- cpp_dev->cpp_clk[msm_micro_iface_idx] =
- clk_get(&cpp_dev->pdev->dev,
- cpp_clk_info[msm_micro_iface_idx].clk_name);
- if (IS_ERR(cpp_dev->cpp_clk[msm_micro_iface_idx])) {
- pr_err("%s get failed\n",
- cpp_clk_info[msm_micro_iface_idx].clk_name);
- rc = PTR_ERR(cpp_dev->cpp_clk[msm_micro_iface_idx]);
- goto remap_failed;
- }
-
- rc = clk_reset(cpp_dev->cpp_clk[msm_micro_iface_idx],
- CLK_RESET_ASSERT);
- if (rc) {
- pr_err("%s:micro_iface_clk assert failed\n",
- __func__);
- clk_put(cpp_dev->cpp_clk[msm_micro_iface_idx]);
- goto remap_failed;
- }
- /*Below usleep values are chosen based on experiments
- and this was the smallest number which works. This
- sleep is needed to leave enough time for Microcontroller
- to resets all its registers.*/
- usleep_range(1000, 1200);
-
- rc = clk_reset(cpp_dev->cpp_clk[msm_micro_iface_idx],
- CLK_RESET_DEASSERT);
- if (rc) {
- pr_err("%s:micro_iface_clk assert failed\n", __func__);
- clk_put(cpp_dev->cpp_clk[msm_micro_iface_idx]);
- goto remap_failed;
- }
- /*Below usleep values are chosen based on experiments and
- this was the smallest number which works. This sleep is
- needed to leave enough time for Microcontroller to
- resets all its registers.*/
- usleep_range(1000, 1200);
-
- clk_put(cpp_dev->cpp_clk[msm_micro_iface_idx]);
-
- rc = msm_cam_clk_enable(&cpp_dev->pdev->dev, cpp_clk_info,
- cpp_dev->cpp_clk, cpp_dev->num_clk, 1);
+ rc = msm_camera_clk_enable(&cpp_dev->pdev->dev, cpp_dev->clk_info,
+ cpp_dev->cpp_clk, cpp_dev->num_clks, true);
if (rc < 0) {
- pr_err("clk enable failed\n");
+ pr_err("%s: clk enable failed\n", __func__);
goto clk_failed;
}
- if (cpp_dev->camss_cpp != NULL) {
- cpp_dev->camss_cpp_base = ioremap(cpp_dev->camss_cpp->start,
- resource_size(cpp_dev->camss_cpp));
- if (!cpp_dev->camss_cpp_base) {
- rc = -ENOMEM;
- pr_err("ioremap failed\n");
- goto remap_failed;
- }
- }
-
- cpp_dev->base = ioremap(cpp_dev->mem->start,
- resource_size(cpp_dev->mem));
- if (!cpp_dev->base) {
- rc = -ENOMEM;
- pr_err("ioremap failed\n");
- goto remap_failed;
- }
-
- cpp_dev->vbif_base = ioremap(cpp_dev->vbif_mem->start,
- resource_size(cpp_dev->vbif_mem));
- if (!cpp_dev->vbif_base) {
- rc = -ENOMEM;
- pr_err("ioremap failed\n");
- goto vbif_remap_failed;
- }
-
- cpp_dev->cpp_hw_base = ioremap(cpp_dev->cpp_hw_mem->start,
- resource_size(cpp_dev->cpp_hw_mem));
- if (!cpp_dev->cpp_hw_base) {
- rc = -ENOMEM;
- pr_err("ioremap failed\n");
- goto cpp_hw_remap_failed;
- }
-
if (cpp_dev->state != CPP_STATE_BOOT) {
- rc = request_irq(cpp_dev->irq->start, msm_cpp_irq,
- IRQF_TRIGGER_RISING, "cpp", cpp_dev);
+ rc = msm_camera_register_irq(cpp_dev->pdev, cpp_dev->irq,
+ msm_cpp_irq, IRQF_TRIGGER_RISING, "cpp", cpp_dev);
if (rc < 0) {
- pr_err("irq request fail\n");
+ pr_err("%s: irq request fail\n", __func__);
goto req_irq_fail;
}
cpp_dev->buf_mgr_subdev = msm_buf_mngr_get_subdev();
@@ -1133,7 +807,8 @@ static int cpp_init_hardware(struct cpp_device *cpp_dev)
VIDIOC_MSM_BUF_MNGR_INIT, NULL);
if (rc < 0) {
pr_err("buf mngr init failed\n");
- free_irq(cpp_dev->irq->start, cpp_dev);
+ msm_camera_unregister_irq(cpp_dev->pdev,
+ cpp_dev->irq, cpp_dev);
goto req_irq_fail;
}
}
@@ -1148,14 +823,11 @@ static int cpp_init_hardware(struct cpp_device *cpp_dev)
pr_info("CPP HW Version: 0x%x\n", cpp_dev->hw_info.cpp_hw_version);
cpp_dev->hw_info.cpp_hw_caps =
msm_camera_io_r(cpp_dev->cpp_hw_base + 0x4);
- msm_cpp_core_clk_idx = get_clock_index("cpp_core_clk");
- if (msm_cpp_core_clk_idx < 0) {
- pr_err("cpp_core_clk: fail to get clock index\n");
- rc = msm_cpp_core_clk_idx;
+
+ rc = msm_update_freq_tbl(cpp_dev);
+ if (rc < 0)
goto pwr_collapse_reset;
- }
- cpp_get_clk_freq_tbl(cpp_dev->cpp_clk[msm_cpp_core_clk_idx],
- &cpp_dev->hw_info, cpp_dev->min_clk_rate);
+
pr_debug("CPP HW Caps: 0x%x\n", cpp_dev->hw_info.cpp_hw_caps);
msm_camera_io_w(0x1, cpp_dev->vbif_base + 0x4);
cpp_dev->taskletq_idx = 0;
@@ -1169,9 +841,9 @@ static int cpp_init_hardware(struct cpp_device *cpp_dev)
pr_err("stream_cnt:%d\n", cpp_dev->stream_cnt);
cpp_dev->stream_cnt = 0;
if (cpp_dev->fw_name_bin) {
- disable_irq(cpp_dev->irq->start);
+ msm_camera_enable_irq(cpp_dev->irq, false);
rc = cpp_load_fw(cpp_dev, cpp_dev->fw_name_bin);
- enable_irq(cpp_dev->irq->start);
+ msm_camera_enable_irq(cpp_dev->irq, true);
if (rc < 0) {
pr_err("%s: load firmware failure %d\n", __func__, rc);
goto pwr_collapse_reset;
@@ -1188,39 +860,12 @@ static int cpp_init_hardware(struct cpp_device *cpp_dev)
pwr_collapse_reset:
msm_cpp_update_gdscr_status(cpp_dev, false);
req_irq_fail:
- iounmap(cpp_dev->cpp_hw_base);
-cpp_hw_remap_failed:
- iounmap(cpp_dev->vbif_base);
-vbif_remap_failed:
- iounmap(cpp_dev->base);
-remap_failed:
- iounmap(cpp_dev->camss_cpp_base);
- msm_cam_clk_enable(&cpp_dev->pdev->dev, cpp_clk_info,
- cpp_dev->cpp_clk, cpp_dev->num_clk, 0);
+ msm_camera_clk_enable(&cpp_dev->pdev->dev, cpp_dev->clk_info,
+ cpp_dev->cpp_clk, cpp_dev->num_clks, false);
clk_failed:
- if (cpp_dev->fs_cpp) {
- regulator_disable(cpp_dev->fs_cpp);
- regulator_put(cpp_dev->fs_cpp);
- cpp_dev->fs_cpp = NULL;
- }
-fs_failed:
- if (cpp_dev->fs_camss) {
- regulator_disable(cpp_dev->fs_camss);
- regulator_put(cpp_dev->fs_camss);
- cpp_dev->fs_camss = NULL;
- }
-fs_camss_failed:
- if (cpp_dev->fs_mmagic_camss) {
- regulator_disable(cpp_dev->fs_mmagic_camss);
- regulator_put(cpp_dev->fs_mmagic_camss);
- cpp_dev->fs_mmagic_camss = NULL;
- }
-fs_mmagic_failed:
- if (cpp_dev->bus_master_flag)
- msm_cpp_deinit_bandwidth_mgr(cpp_dev);
- else
- msm_isp_deinit_bandwidth_mgr(ISP_CPP);
-bus_scale_register_failed:
+ msm_camera_regulator_enable(cpp_dev->cpp_vdd,
+ cpp_dev->num_reg, false);
+reg_enable_failed:
if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CPP,
CAM_AHB_SUSPEND_VOTE) < 0)
pr_err("%s: failed to remove vote for AHB\n", __func__);
@@ -1238,42 +883,20 @@ static void cpp_release_hardware(struct cpp_device *cpp_dev)
pr_err("error in buf mngr deinit\n");
rc = -EINVAL;
}
- free_irq(cpp_dev->irq->start, cpp_dev);
+ msm_camera_unregister_irq(cpp_dev->pdev, cpp_dev->irq, cpp_dev);
tasklet_kill(&cpp_dev->cpp_tasklet);
atomic_set(&cpp_dev->irq_cnt, 0);
}
msm_cpp_delete_buff_queue(cpp_dev);
msm_cpp_update_gdscr_status(cpp_dev, false);
- iounmap(cpp_dev->base);
- iounmap(cpp_dev->vbif_base);
- iounmap(cpp_dev->cpp_hw_base);
- iounmap(cpp_dev->camss_cpp_base);
- msm_cam_clk_enable(&cpp_dev->pdev->dev, cpp_clk_info,
- cpp_dev->cpp_clk, cpp_dev->num_clk, 0);
- if (cpp_dev->fs_cpp) {
- regulator_disable(cpp_dev->fs_cpp);
- regulator_put(cpp_dev->fs_cpp);
- cpp_dev->fs_cpp = NULL;
- }
- if (cpp_dev->fs_camss) {
- regulator_disable(cpp_dev->fs_camss);
- regulator_put(cpp_dev->fs_camss);
- cpp_dev->fs_camss = NULL;
- }
- if (cpp_dev->fs_mmagic_camss) {
- regulator_disable(cpp_dev->fs_mmagic_camss);
- regulator_put(cpp_dev->fs_mmagic_camss);
- cpp_dev->fs_mmagic_camss = NULL;
- }
+ msm_camera_clk_enable(&cpp_dev->pdev->dev, cpp_dev->clk_info,
+ cpp_dev->cpp_clk, cpp_dev->num_clks, false);
+ msm_camera_regulator_enable(cpp_dev->cpp_vdd, cpp_dev->num_reg, false);
if (cpp_dev->stream_cnt > 0) {
pr_warn("stream count active\n");
rc = msm_cpp_update_bandwidth_setting(cpp_dev, 0, 0);
}
cpp_dev->stream_cnt = 0;
- if (cpp_dev->bus_master_flag)
- msm_cpp_deinit_bandwidth_mgr(cpp_dev);
- else
- msm_isp_deinit_bandwidth_mgr(ISP_CPP);
if (cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CPP,
CAM_AHB_SUSPEND_VOTE) < 0)
@@ -1791,8 +1414,7 @@ static void msm_cpp_do_timeout_work(struct work_struct *work)
goto end;
}
-
- disable_irq(cpp_timer.data.cpp_dev->irq->start);
+ msm_camera_enable_irq(cpp_timer.data.cpp_dev->irq, false);
/* make sure all the pending queued entries are scheduled */
tasklet_kill(&cpp_dev->cpp_tasklet);
@@ -3042,7 +2664,7 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
mutex_unlock(&cpp_dev->mutex);
return -EINVAL;
}
- disable_irq(cpp_dev->irq->start);
+ msm_camera_enable_irq(cpp_dev->irq, false);
rc = cpp_load_fw(cpp_dev, cpp_dev->fw_name_bin);
if (rc < 0) {
pr_err("%s: load firmware failure %d\n",
@@ -3059,7 +2681,7 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
mutex_unlock(&cpp_dev->mutex);
return rc;
}
- enable_irq(cpp_dev->irq->start);
+ msm_camera_enable_irq(cpp_dev->irq, true);
cpp_dev->is_firmware_loaded = 1;
}
break;
@@ -3303,7 +2925,8 @@ STREAM_BUFF_END:
}
if (clock_settings.clock_rate > 0) {
- msm_cpp_core_clk_idx = get_clock_index("cpp_core_clk");
+ msm_cpp_core_clk_idx = msm_cpp_get_clock_index(cpp_dev,
+ "cpp_core_clk");
if (msm_cpp_core_clk_idx < 0) {
pr_err(" Fail to get clock index\n");
mutex_unlock(&cpp_dev->mutex);
@@ -3319,14 +2942,17 @@ STREAM_BUFF_END:
mutex_unlock(&cpp_dev->mutex);
return -EINVAL;
}
- clock_rate = clk_round_rate(
- cpp_dev->cpp_clk[msm_cpp_core_clk_idx],
- clock_settings.clock_rate);
+ clock_rate = msm_cpp_set_core_clk(cpp_dev,
+ clock_settings.clock_rate,
+ msm_cpp_core_clk_idx);
+ if (rc < 0) {
+ pr_err("Fail to set core clk\n");
+ mutex_unlock(&cpp_dev->mutex);
+ return -EINVAL;
+ }
if (clock_rate != clock_settings.clock_rate)
pr_err("clock rate differ from settings\n");
- clk_set_rate(cpp_dev->cpp_clk[msm_cpp_core_clk_idx],
- clock_rate);
- msm_isp_util_update_clk_rate(clock_rate);
+ msm_isp_util_update_clk_rate(clock_settings.clock_rate);
}
break;
}
@@ -4131,60 +3757,6 @@ static long msm_cpp_subdev_fops_compat_ioctl(struct file *file,
}
#endif
-static int msm_cpp_get_clk_info(struct cpp_device *cpp_dev,
- struct platform_device *pdev)
-{
- uint32_t count;
- int i, rc;
- uint32_t rates[CPP_CLK_INFO_MAX];
-
- struct device_node *of_node;
- of_node = pdev->dev.of_node;
-
- count = of_property_count_strings(of_node, "clock-names");
-
- CPP_DBG("count = %d\n", count);
- if (count == 0) {
- pr_err("no clocks found in device tree, count=%d", count);
- return 0;
- }
-
- if (count > CPP_CLK_INFO_MAX) {
- pr_err("invalid count=%d, max is %d\n", count,
- CPP_CLK_INFO_MAX);
- return -EINVAL;
- }
-
- for (i = 0; i < count; i++) {
- rc = of_property_read_string_index(of_node, "clock-names",
- i, &(cpp_clk_info[i].clk_name));
- CPP_DBG("clock-names[%d] = %s\n", i, cpp_clk_info[i].clk_name);
- if (rc < 0) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- return rc;
- }
- }
- rc = of_property_read_u32_array(of_node, "qcom,clock-rates",
- rates, count);
- if (rc < 0) {
- pr_err("%s failed %d\n", __func__, __LINE__);
- return rc;
- }
- for (i = 0; i < count; i++) {
- cpp_clk_info[i].clk_rate = (rates[i] == 0) ?
- (long)-1 : rates[i];
- CPP_DBG("clk_rate[%d] = %ld\n", i, cpp_clk_info[i].clk_rate);
- }
- cpp_dev->num_clk = count;
- rc = of_property_read_u32(of_node, "qcom,min-clock-rate",
- &cpp_dev->min_clk_rate);
- if (rc < 0) {
- CPP_DBG("min-clk-rate not defined, setting it to 0\n");
- cpp_dev->min_clk_rate = 0;
- }
- return 0;
-}
-
struct v4l2_file_operations msm_cpp_v4l2_subdev_fops = {
.unlocked_ioctl = msm_cpp_subdev_fops_ioctl,
#ifdef CONFIG_COMPAT
@@ -4268,14 +3840,6 @@ static int cpp_probe(struct platform_device *pdev)
return -ENOMEM;
}
- cpp_dev->cpp_clk = kzalloc(sizeof(struct clk *) *
- ARRAY_SIZE(cpp_clk_info), GFP_KERNEL);
- if (!cpp_dev->cpp_clk) {
- pr_err("no enough memory\n");
- rc = -ENOMEM;
- goto clk_err;
- }
-
v4l2_subdev_init(&cpp_dev->msm_sd.sd, &msm_cpp_subdev_ops);
cpp_dev->msm_sd.sd.internal_ops = &msm_cpp_internal_ops;
snprintf(cpp_dev->msm_sd.sd.name, ARRAY_SIZE(cpp_dev->msm_sd.sd.name),
@@ -4288,72 +3852,77 @@ static int cpp_probe(struct platform_device *pdev)
spin_lock_init(&cpp_dev->tasklet_lock);
spin_lock_init(&cpp_timer.data.processed_frame_lock);
- if (pdev->dev.of_node)
- of_property_read_u32((&pdev->dev)->of_node,
- "cell-index", &pdev->id);
-
cpp_dev->pdev = pdev;
- cpp_dev->camss_cpp = platform_get_resource_byname(pdev,
- IORESOURCE_MEM, "camss_cpp");
- if (!cpp_dev->camss_cpp)
- pr_debug("no mem resource?\n");
+ cpp_dev->camss_cpp_base =
+ msm_camera_get_reg_base(pdev, "camss_cpp", true);
+ if (!cpp_dev->camss_cpp_base) {
+ rc = -ENOMEM;
+ pr_err("failed to get camss_cpp_base\n");
+ goto camss_cpp_base_failed;
+ }
- cpp_dev->mem = platform_get_resource_byname(pdev,
- IORESOURCE_MEM, "cpp");
- if (!cpp_dev->mem) {
- pr_err("no mem resource?\n");
- rc = -ENODEV;
- goto mem_err;
+ cpp_dev->base =
+ msm_camera_get_reg_base(pdev, "cpp", true);
+ if (!cpp_dev->base) {
+ rc = -ENOMEM;
+ pr_err("failed to get cpp_base\n");
+ goto cpp_base_failed;
}
- cpp_dev->vbif_mem = platform_get_resource_byname(pdev,
- IORESOURCE_MEM, "cpp_vbif");
- if (!cpp_dev->vbif_mem) {
- pr_err("no mem resource?\n");
- rc = -ENODEV;
- goto mem_err;
+ cpp_dev->vbif_base =
+ msm_camera_get_reg_base(pdev, "cpp_vbif", false);
+ if (!cpp_dev->vbif_base) {
+ rc = -ENOMEM;
+ pr_err("failed to get vbif_base\n");
+ goto vbif_base_failed;
}
- cpp_dev->cpp_hw_mem = platform_get_resource_byname(pdev,
- IORESOURCE_MEM, "cpp_hw");
- if (!cpp_dev->cpp_hw_mem) {
- pr_err("no mem resource?\n");
- rc = -ENODEV;
- goto mem_err;
+ cpp_dev->cpp_hw_base =
+ msm_camera_get_reg_base(pdev, "cpp_hw", true);
+ if (!cpp_dev->cpp_hw_base) {
+ rc = -ENOMEM;
+ pr_err("failed to get cpp_hw_base\n");
+ goto cpp_hw_base_failed;
}
- cpp_dev->irq = platform_get_resource_byname(pdev,
- IORESOURCE_IRQ, "cpp");
+ cpp_dev->irq = msm_camera_get_irq(pdev, "cpp");
if (!cpp_dev->irq) {
pr_err("%s: no irq resource?\n", __func__);
rc = -ENODEV;
goto mem_err;
}
- cpp_dev->io = request_mem_region(cpp_dev->mem->start,
- resource_size(cpp_dev->mem), pdev->name);
- if (!cpp_dev->io) {
- pr_err("%s: no valid mem region\n", __func__);
- rc = -EBUSY;
+ rc = msm_camera_get_clk_info(pdev, &cpp_dev->clk_info,
+ &cpp_dev->cpp_clk, &cpp_dev->num_clks);
+ if (rc < 0) {
+ pr_err("%s: failed to get the clocks\n", __func__);
goto mem_err;
}
- if (msm_cpp_get_clk_info(cpp_dev, pdev) < 0) {
- pr_err("msm_cpp_get_clk_info() failed\n");
- goto region_err;
+ rc = msm_camera_get_regulator_info(pdev, &cpp_dev->cpp_vdd,
+ &cpp_dev->num_reg);
+ if (rc < 0) {
+ pr_err("%s: failed to get the regulators\n", __func__);
+ goto get_reg_err;
}
- if (pdev->dev.of_node)
- rc = of_property_read_u32(pdev->dev.of_node, "qcom,bus-master",
- &cpp_dev->bus_master_flag);
- if (rc)
- cpp_dev->bus_master_flag = 0;
+ msm_cpp_fetch_dt_params(cpp_dev);
rc = msm_cpp_read_payload_params_from_dt(cpp_dev);
if (rc)
goto cpp_probe_init_error;
+ if (cpp_dev->bus_master_flag)
+ rc = msm_cpp_init_bandwidth_mgr(cpp_dev);
+ else
+ rc = msm_isp_init_bandwidth_mgr(ISP_CPP);
+ if (rc < 0) {
+ pr_err("%s: Bandwidth registration Failed!\n", __func__);
+ goto cpp_probe_init_error;
+ }
+
+ cpp_dev->state = CPP_STATE_BOOT;
rc = cpp_init_hardware(cpp_dev);
if (rc < 0)
goto cpp_probe_init_error;
@@ -4373,7 +3942,6 @@ static int cpp_probe(struct platform_device *pdev)
cpp_dev->msm_sd.sd.devnode->fops = &msm_cpp_v4l2_subdev_fops;
cpp_dev->msm_sd.sd.entity.revision = cpp_dev->msm_sd.sd.devnode->num;
- cpp_dev->state = CPP_STATE_BOOT;
msm_camera_io_w(0x0, cpp_dev->base +
MSM_CPP_MICRO_IRQGEN_MASK);
@@ -4410,9 +3978,6 @@ static int cpp_probe(struct platform_device *pdev)
setup_timer(&cpp_timer.cpp_timer,
cpp_timer_callback, (unsigned long)&cpp_timer);
cpp_dev->fw_name_bin = NULL;
- cpp_dev->fs_cpp = NULL;
- cpp_dev->fs_camss = NULL;
- cpp_dev->fs_mmagic_camss = NULL;
cpp_dev->max_timeout_trial_cnt = MSM_CPP_MAX_TIMEOUT_TRIAL;
if (rc == 0)
CPP_DBG("SUCCESS.");
@@ -4422,11 +3987,19 @@ static int cpp_probe(struct platform_device *pdev)
cpp_probe_init_error:
media_entity_cleanup(&cpp_dev->msm_sd.sd.entity);
msm_sd_unregister(&cpp_dev->msm_sd);
-region_err:
- release_mem_region(cpp_dev->mem->start, resource_size(cpp_dev->mem));
+get_reg_err:
+ msm_camera_put_clk_info(pdev, &cpp_dev->clk_info, &cpp_dev->cpp_clk,
+ cpp_dev->num_clks);
mem_err:
- kfree(cpp_dev->cpp_clk);
-clk_err:
+ msm_camera_put_reg_base(pdev, cpp_dev->cpp_hw_base, "cpp_hw", true);
+cpp_hw_base_failed:
+ msm_camera_put_reg_base(pdev, cpp_dev->vbif_base, "cpp_vbif", false);
+vbif_base_failed:
+ msm_camera_put_reg_base(pdev, cpp_dev->base, "cpp", true);
+cpp_base_failed:
+ msm_camera_put_reg_base(pdev, cpp_dev->camss_cpp_base,
+ "camss_cpp", true);
+camss_cpp_base_failed:
kfree(cpp_dev);
return rc;
}
@@ -4454,15 +4027,21 @@ static int cpp_device_remove(struct platform_device *dev)
release_firmware(cpp_dev->fw);
cpp_dev->fw = NULL;
}
+ if (cpp_dev->bus_master_flag)
+ msm_cpp_deinit_bandwidth_mgr(cpp_dev);
+ else
+ msm_isp_deinit_bandwidth_mgr(ISP_CPP);
msm_sd_unregister(&cpp_dev->msm_sd);
- release_mem_region(cpp_dev->mem->start, resource_size(cpp_dev->mem));
- release_mem_region(cpp_dev->vbif_mem->start,
- resource_size(cpp_dev->vbif_mem));
- release_mem_region(cpp_dev->cpp_hw_mem->start,
- resource_size(cpp_dev->cpp_hw_mem));
- if (cpp_dev->camss_cpp)
- release_mem_region(cpp_dev->camss_cpp->start,
- resource_size(cpp_dev->camss_cpp));
+ msm_camera_put_reg_base(dev, cpp_dev->camss_cpp_base,
+ "camss_cpp", true);
+ msm_camera_put_reg_base(dev, cpp_dev->base, "cpp", true);
+ msm_camera_put_reg_base(dev, cpp_dev->vbif_base, "cpp_vbif", false);
+ msm_camera_put_reg_base(dev, cpp_dev->cpp_hw_base, "cpp_hw", true);
+ msm_camera_put_regulators(dev, &cpp_dev->cpp_vdd,
+ cpp_dev->num_reg);
+ msm_camera_put_clk_info(dev, &cpp_dev->clk_info,
+ &cpp_dev->cpp_clk, cpp_dev->num_clks);
+ msm_camera_unregister_bus_client(CAM_BUS_CLIENT_CPP);
mutex_destroy(&cpp_dev->mutex);
kfree(cpp_dev->work);
destroy_workqueue(cpp_dev->timer_wq);
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h
index 7a6a9efcaa26..203314b182a7 100644
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2013-2016, 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
@@ -20,6 +20,8 @@
#include <linux/interrupt.h>
#include <media/v4l2-subdev.h>
#include "msm_sd.h"
+#include "cam_soc_api.h"
+#include "cam_hw_ops.h"
/* hw version info:
31:28 Major version
@@ -200,21 +202,16 @@ struct cpp_device {
struct platform_device *pdev;
struct msm_sd_subdev msm_sd;
struct v4l2_subdev subdev;
- struct resource *mem;
struct resource *irq;
- struct resource *io;
- struct resource *vbif_mem;
- struct resource *vbif_io;
- struct resource *cpp_hw_mem;
- struct resource *camss_cpp;
void __iomem *vbif_base;
void __iomem *base;
void __iomem *cpp_hw_base;
void __iomem *camss_cpp_base;
struct clk **cpp_clk;
- struct regulator *fs_cpp;
- struct regulator *fs_camss;
- struct regulator *fs_mmagic_camss;
+ struct msm_cam_clk_info *clk_info;
+ size_t num_clks;
+ struct regulator **cpp_vdd;
+ int num_reg;
struct mutex mutex;
enum cpp_state state;
enum cpp_iommu_state iommu_state;
@@ -264,4 +261,12 @@ struct cpp_device {
uint32_t bus_master_flag;
struct msm_cpp_payload_params payload_params;
};
+
+int msm_cpp_set_micro_clk(struct cpp_device *cpp_dev);
+int msm_update_freq_tbl(struct cpp_device *cpp_dev);
+int msm_cpp_get_clock_index(struct cpp_device *cpp_dev, const char *clk_name);
+long msm_cpp_set_core_clk(struct cpp_device *cpp_dev, long rate, int idx);
+void msm_cpp_fetch_dt_params(struct cpp_device *cpp_dev);
+int msm_cpp_read_payload_params_from_dt(struct cpp_device *cpp_dev);
+
#endif /* __MSM_CPP_H__ */
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c
new file mode 100644
index 000000000000..ee52284e3ae3
--- /dev/null
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp_soc.c
@@ -0,0 +1,249 @@
+/* Copyright (c) 2016, 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.
+ */
+
+#define pr_fmt(fmt) "MSM-CPP-SOC %s:%d " fmt, __func__, __LINE__
+
+#include <linux/clk/msm-clk.h>
+#include <linux/clk/msm-clk-provider.h>
+#include <linux/delay.h>
+#include <media/msmb_pproc.h>
+#include "msm_cpp.h"
+
+
+#define CPP_DT_READ_U32_ERR(_dev, _key, _str, _ret, _out) { \
+ _key = _str; \
+ _ret = of_property_read_u32(_dev, _key, &_out); \
+ if (_ret) \
+ break; \
+ }
+
+#define CPP_DT_READ_U32(_dev, _str, _out) { \
+ of_property_read_u32(_dev, _str, &_out); \
+ }
+
+void msm_cpp_fetch_dt_params(struct cpp_device *cpp_dev)
+{
+ int rc = 0;
+ struct device_node *of_node = cpp_dev->pdev->dev.of_node;
+
+ if (!of_node) {
+ pr_err("%s: invalid params\n", __func__);
+ return;
+ }
+
+ of_property_read_u32(of_node, "cell-index", &cpp_dev->pdev->id);
+
+ rc = of_property_read_u32(of_node, "qcom,min-clock-rate",
+ &cpp_dev->min_clk_rate);
+ if (rc < 0) {
+ pr_debug("min-clk-rate not defined, setting it to 0\n");
+ cpp_dev->min_clk_rate = 0;
+ }
+
+ rc = of_property_read_u32(of_node, "qcom,bus-master",
+ &cpp_dev->bus_master_flag);
+ if (rc)
+ cpp_dev->bus_master_flag = 0;
+}
+
+int msm_cpp_get_clock_index(struct cpp_device *cpp_dev, const char *clk_name)
+{
+ uint32_t i = 0;
+
+ for (i = 0; i < cpp_dev->num_clks; i++) {
+ if (!strcmp(clk_name, cpp_dev->clk_info[i].clk_name))
+ return i;
+ }
+ return -EINVAL;
+}
+
+static int cpp_get_clk_freq_tbl(struct clk *clk, struct cpp_hw_info *hw_info,
+ uint32_t min_clk_rate)
+{
+ uint32_t i;
+ uint32_t idx = 0;
+ signed long freq_tbl_entry = 0;
+
+ if ((clk == NULL) || (hw_info == NULL) || (clk->ops == NULL) ||
+ (clk->ops->list_rate == NULL)) {
+ pr_err("Bad parameter\n");
+ return -EINVAL;
+ }
+
+ for (i = 0; i < MAX_FREQ_TBL; i++) {
+ freq_tbl_entry = clk->ops->list_rate(clk, i);
+ pr_debug("entry=%ld\n", freq_tbl_entry);
+ if (freq_tbl_entry >= 0) {
+ if (freq_tbl_entry >= min_clk_rate) {
+ hw_info->freq_tbl[idx++] = freq_tbl_entry;
+ pr_debug("tbl[%d]=%ld\n", idx-1,
+ freq_tbl_entry);
+ }
+ } else {
+ pr_debug("freq table returned invalid entry/end %ld\n",
+ freq_tbl_entry);
+ break;
+ }
+ }
+
+ pr_debug("%s: idx %d", __func__, idx);
+ hw_info->freq_tbl_count = idx;
+
+ return 0;
+}
+
+int msm_cpp_set_micro_clk(struct cpp_device *cpp_dev)
+{
+ uint32_t msm_micro_iface_idx;
+ int rc;
+
+ msm_micro_iface_idx = msm_cpp_get_clock_index(cpp_dev,
+ "micro_iface_clk");
+ if (msm_micro_iface_idx < 0) {
+ pr_err("Fail to get clock index\n");
+ return -EINVAL;
+ }
+
+ rc = clk_reset(cpp_dev->cpp_clk[msm_micro_iface_idx],
+ CLK_RESET_ASSERT);
+ if (rc) {
+ pr_err("%s:micro_iface_clk assert failed\n",
+ __func__);
+ return -EINVAL;
+ }
+
+ /*
+ * Below usleep values are chosen based on experiments
+ * and this was the smallest number which works. This
+ * sleep is needed to leave enough time for Microcontroller
+ * to resets all its registers.
+ */
+ usleep_range(1000, 1200);
+
+ rc = clk_reset(cpp_dev->cpp_clk[msm_micro_iface_idx],
+ CLK_RESET_DEASSERT);
+ if (rc) {
+ pr_err("%s:micro_iface_clk de-assert failed\n", __func__);
+ return -EINVAL;
+ }
+
+ /*
+ * Below usleep values are chosen based on experiments
+ * and this was the smallest number which works. This
+ * sleep is needed to leave enough time for Microcontroller
+ * to resets all its registers.
+ */
+ usleep_range(1000, 1200);
+ return 0;
+}
+
+int msm_update_freq_tbl(struct cpp_device *cpp_dev)
+{
+ uint32_t msm_cpp_core_clk_idx;
+ int rc = 0;
+
+ msm_cpp_core_clk_idx = msm_cpp_get_clock_index(cpp_dev, "cpp_core_clk");
+ if (msm_cpp_core_clk_idx < 0) {
+ pr_err("%s: fail to get clock index\n", __func__);
+ rc = msm_cpp_core_clk_idx;
+ return rc;
+ }
+ rc = cpp_get_clk_freq_tbl(cpp_dev->cpp_clk[msm_cpp_core_clk_idx],
+ &cpp_dev->hw_info, cpp_dev->min_clk_rate);
+ if (rc < 0) {
+ pr_err("%s: fail to get frequency table\n", __func__);
+ return rc;
+ }
+
+ return rc;
+}
+
+long msm_cpp_set_core_clk(struct cpp_device *cpp_dev, long rate, int idx)
+{
+ long rc = 0;
+
+ rc = msm_camera_clk_set_rate(&cpp_dev->pdev->dev,
+ cpp_dev->cpp_clk[idx], rate);
+ if (rc < 0) {
+ pr_err("%s: fail to get frequency table\n", __func__);
+ return rc;
+ }
+
+ return rc;
+}
+
+int msm_cpp_read_payload_params_from_dt(struct cpp_device *cpp_dev)
+{
+ struct platform_device *pdev = cpp_dev->pdev;
+ struct device_node *fw_info_node = NULL, *dev_node = NULL;
+ char *key = "qcom,cpp-fw-payload-info";
+ struct msm_cpp_payload_params *payload_params;
+ int ret = 0;
+
+ if (!pdev || !pdev->dev.of_node) {
+ pr_err("%s: Invalid platform device/node\n", __func__);
+ ret = -ENODEV;
+ goto no_cpp_node;
+ }
+
+ dev_node = pdev->dev.of_node;
+ fw_info_node = of_find_node_by_name(dev_node, key);
+ if (!fw_info_node) {
+ ret = -ENODEV;
+ goto no_binding;
+ }
+ payload_params = &cpp_dev->payload_params;
+ memset(payload_params, 0x0, sizeof(struct msm_cpp_payload_params));
+
+ do {
+ CPP_DT_READ_U32_ERR(fw_info_node, key, "qcom,stripe-base", ret,
+ payload_params->stripe_base);
+ CPP_DT_READ_U32_ERR(fw_info_node, key, "qcom,plane-base", ret,
+ payload_params->plane_base);
+ CPP_DT_READ_U32_ERR(fw_info_node, key, "qcom,stripe-size", ret,
+ payload_params->stripe_size);
+ CPP_DT_READ_U32_ERR(fw_info_node, key, "qcom,plane-size", ret,
+ payload_params->plane_size);
+ CPP_DT_READ_U32_ERR(fw_info_node, key, "qcom,fe-ptr-off", ret,
+ payload_params->rd_pntr_off);
+ CPP_DT_READ_U32_ERR(fw_info_node, key, "qcom,we-ptr-off", ret,
+ payload_params->wr_0_pntr_off);
+
+ CPP_DT_READ_U32(fw_info_node, "qcom,ref-fe-ptr-off",
+ payload_params->rd_ref_pntr_off);
+ CPP_DT_READ_U32(fw_info_node, "qcom,ref-we-ptr-off",
+ payload_params->wr_ref_pntr_off);
+ CPP_DT_READ_U32(fw_info_node, "qcom,we-meta-ptr-off",
+ payload_params->wr_0_meta_data_wr_pntr_off);
+ CPP_DT_READ_U32(fw_info_node, "qcom,fe-mmu-pf-ptr-off",
+ payload_params->fe_mmu_pf_ptr_off);
+ CPP_DT_READ_U32(fw_info_node, "qcom,ref-fe-mmu-pf-ptr-off",
+ payload_params->ref_fe_mmu_pf_ptr_off);
+ CPP_DT_READ_U32(fw_info_node, "qcom,we-mmu-pf-ptr-off",
+ payload_params->we_mmu_pf_ptr_off);
+ CPP_DT_READ_U32(fw_info_node, "qcom,dup-we-mmu-pf-ptr-off",
+ payload_params->dup_we_mmu_pf_ptr_off);
+ CPP_DT_READ_U32(fw_info_node, "qcom,ref-we-mmu-pf-ptr-off",
+ payload_params->ref_we_mmu_pf_ptr_off);
+ CPP_DT_READ_U32(fw_info_node, "qcom,set-group-buffer-len",
+ payload_params->set_group_buffer_len);
+ CPP_DT_READ_U32(fw_info_node, "qcom,dup-frame-indicator-off",
+ payload_params->dup_frame_indicator_off);
+ } while (0);
+
+no_binding:
+ if (ret)
+ pr_err("%s: Error reading binding %s, ret %d\n",
+ __func__, key, ret);
+no_cpp_node:
+ return ret;
+}