Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 02f1c74b authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "Added early camera changes to AIS"

parents c0273c5d 6ce79e5b
Loading
Loading
Loading
Loading
+110 −0
Original line number Diff line number Diff line
* Qualcomm Technologies Inc MSM BA

[Root level node]
==================
Required properties:
- compatible: Must be "qcom,early-cam".

[Subnode]
==========
- qcom,early-cam-input-profile-#: Defines child nodes for the profiles supported
              by early camera driver. Each profile should have properties
              "mmagic-supply", "gdscr-supply", "vfe0-vdd-supply",
              "qcom,cam-vreg-name", "clocks", "clock-names",
              "qcom,clock-rates".
Required properties:
- mmagic-supply : should contain mmagic regulator used for mmagic clocks.
- gdscr-supply : should contain gdsr regulator used for cci clocks.
- vfe0-vdd-supply: phandle to vfe0 regulator.
- qcom,cam-vreg-name : name of the voltage regulators required for the device.
- clocks: List of clock handles. The parent clocks of the input clocks to the
	devices in this power domain are set to oscclk before power gating
	and restored back after powering on a domain. This is required for
	all domains which are powered on and off and not required for unused
	domains.
- clock-names: name of the clock used by the driver.
- qcom,clock-rates: clock rate in Hz.
Example:

    qcom,early-cam {
		cell-index = <0>;
		compatible = "qcom,early-cam";
		status = "ok";
		mmagic-supply = <&gdsc_mmagic_camss>;
		gdscr-supply = <&gdsc_camss_top>;
		vfe0-vdd-supply = <&gdsc_vfe0>;
		qcom,cam-vreg-name = "mmagic", "gdscr", "vfe0-vdd";
		clocks = <&clock_mmss clk_mmss_mmagic_ahb_clk>,
			<&clock_mmss clk_camss_top_ahb_clk>,
			<&clock_mmss clk_cci_clk_src>,
			<&clock_mmss clk_camss_cci_ahb_clk>,
			<&clock_mmss clk_camss_cci_clk>,
			<&clock_mmss clk_camss_ahb_clk>,
			<&clock_mmss clk_mmagic_camss_axi_clk>,
			<&clock_mmss clk_camss_vfe_ahb_clk>,
			<&clock_mmss clk_camss_vfe0_ahb_clk>,
			<&clock_mmss clk_camss_vfe_axi_clk>,
			<&clock_mmss clk_camss_vfe0_stream_clk>,
			<&clock_mmss clk_smmu_vfe_axi_clk>,
			<&clock_mmss clk_smmu_vfe_ahb_clk>,
			<&clock_mmss clk_camss_csi_vfe0_clk>,
			<&clock_mmss clk_vfe0_clk_src>,
			<&clock_mmss clk_camss_csi_vfe0_clk>,
			<&clock_mmss clk_camss_csi2_ahb_clk>,
			<&clock_mmss clk_camss_csi2_clk>,
			<&clock_mmss clk_camss_csi2phy_clk>,
			<&clock_mmss clk_csi2phytimer_clk_src>,
			<&clock_mmss clk_camss_csi2phytimer_clk>,
			<&clock_mmss clk_camss_csi2rdi_clk>,
			<&clock_mmss clk_camss_ispif_ahb_clk>,
			<&clock_mmss clk_camss_vfe0_clk>;
		clock-names =
			"mmss_mmagic_ahb_clk",
			"camss_top_ahb_clk",
			"cci_clk_src",
			"camss_cci_ahb_clk",
			"camss_cci_clk",
			"camss_ahb_clk",
			"mmagic_camss_axi_clk",
			"camss_vfe_ahb_clk",
			"camss_vfe0_ahb_clk",
			"camss_vfe_axi_clk",
			"camss_vfe0_stream_clk",
			"smmu_vfe_axi_clk",
			"smmu_vfe_ahb_clk",
			"camss_csi_vfe0_clk",
			"vfe0_clk_src",
			"camss_csi_vfe0_clk",
			"camss_csi2_ahb_clk",
			"camss_csi2_clk",
			"camss_csi2phy_clk",
			"csi2phytimer_clk_src",
			"camss_csi2phytimer_clk",
			"camss_csi2rdi_clk",
			"camss_ispif_ahb_clk",
			"clk_camss_vfe0_clk";

		qcom,clock-rates = <19200000
						19200000
						19200000
						19200000
						19200000
						19200000
						0
						0
						0
						320000000
						0
						0
						0
						0
						19200000
						0
						0
						200000000
						200000000
						200000000
						200000000
						200000000
						0
	};
+103 −0
Original line number Diff line number Diff line
@@ -863,6 +863,90 @@
};

&soc {
	qcom,early-cam {
		cell-index = <0>;
		compatible = "qcom,early-cam";
		status = "ok";
		mmagic-supply = <&gdsc_mmagic_camss>;
		gdscr-supply = <&gdsc_camss_top>;
		vfe0-vdd-supply = <&gdsc_vfe0>;
		qcom,cam-vreg-name = "mmagic", "gdscr", "vfe0-vdd";
		clocks = <&clock_mmss clk_mmss_mmagic_ahb_clk>,
			<&clock_mmss clk_camss_top_ahb_clk>,
			<&clock_mmss clk_cci_clk_src>,
			<&clock_mmss clk_camss_cci_ahb_clk>,
			<&clock_mmss clk_camss_cci_clk>,
			<&clock_mmss clk_camss_ahb_clk>,
			<&clock_mmss clk_mmagic_camss_axi_clk>,
			<&clock_mmss clk_camss_vfe_ahb_clk>,
			<&clock_mmss clk_camss_vfe0_ahb_clk>,
			<&clock_mmss clk_camss_vfe_axi_clk>,
			<&clock_mmss clk_camss_vfe0_stream_clk>,
			<&clock_mmss clk_smmu_vfe_axi_clk>,
			<&clock_mmss clk_smmu_vfe_ahb_clk>,
			<&clock_mmss clk_camss_csi_vfe0_clk>,
			<&clock_mmss clk_vfe0_clk_src>,
			<&clock_mmss clk_camss_csi_vfe0_clk>,
			<&clock_mmss clk_camss_csi2_ahb_clk>,
			<&clock_mmss clk_camss_csi2_clk>,
			<&clock_mmss clk_camss_csi2phy_clk>,
			<&clock_mmss clk_csi2phytimer_clk_src>,
			<&clock_mmss clk_camss_csi2phytimer_clk>,
			<&clock_mmss clk_camss_csi2rdi_clk>,
			<&clock_mmss clk_camss_ispif_ahb_clk>,
			<&clock_mmss clk_camss_vfe0_clk>;
		clock-names =
			"mmss_mmagic_ahb_clk",
			"camss_top_ahb_clk",
			"cci_clk_src",
			"camss_cci_ahb_clk",
			"camss_cci_clk",
			"camss_ahb_clk",
			"mmagic_camss_axi_clk",
			"camss_vfe_ahb_clk",
			"camss_vfe0_ahb_clk",
			"camss_vfe_axi_clk",
			"camss_vfe0_stream_clk",
			"smmu_vfe_axi_clk",
			"smmu_vfe_ahb_clk",
			"camss_csi_vfe0_clk",
			"vfe0_clk_src",
			"camss_csi_vfe0_clk",
			"camss_csi2_ahb_clk",
			"camss_csi2_clk",
			"camss_csi2phy_clk",
			"csi2phytimer_clk_src",
			"camss_csi2phytimer_clk",
			"camss_csi2rdi_clk",
			"camss_ispif_ahb_clk",
			"clk_camss_vfe0_clk";

		qcom,clock-rates = <19200000
						19200000
						19200000
						19200000
						19200000
						19200000
						0
						0
						0
						320000000
						0
						0
						0
						0
						19200000
						0
						0
						200000000
						200000000
						200000000
						200000000
						200000000
						0
						100000000>;
	};

	qcom,ntn_avb {
		compatible = "qcom,ntn_avb";

@@ -1455,3 +1539,22 @@
		spi-cpha;
	};
};

&vfe_smmu {
	qcom,no-smr-check;
};

/ {
	reserved-memory {
		lk_mem: lk_pool@0x91600000 {
			no-map;
			reg = <0 0x91600000 0 0x00600000>;
			label = "lk_pool";
		};

		early_camera_mem: early_camera_mem@b3fff000 {
			reg = <0 0xb3fff000 0 0x800000>;
			label = "early_camera_mem";
		};
	};
};
+102 −0
Original line number Diff line number Diff line
@@ -645,6 +645,90 @@
};

&soc {
	qcom,early-cam {
		cell-index = <0>;
		compatible = "qcom,early-cam";
		status = "ok";
		mmagic-supply = <&gdsc_mmagic_camss>;
		gdscr-supply = <&gdsc_camss_top>;
		vfe0-vdd-supply = <&gdsc_vfe0>;
		qcom,cam-vreg-name = "mmagic", "gdscr", "vfe0-vdd";
		clocks = <&clock_mmss clk_mmss_mmagic_ahb_clk>,
			<&clock_mmss clk_camss_top_ahb_clk>,
			<&clock_mmss clk_cci_clk_src>,
			<&clock_mmss clk_camss_cci_ahb_clk>,
			<&clock_mmss clk_camss_cci_clk>,
			<&clock_mmss clk_camss_ahb_clk>,
			<&clock_mmss clk_mmagic_camss_axi_clk>,
			<&clock_mmss clk_camss_vfe_ahb_clk>,
			<&clock_mmss clk_camss_vfe0_ahb_clk>,
			<&clock_mmss clk_camss_vfe_axi_clk>,
			<&clock_mmss clk_camss_vfe0_stream_clk>,
			<&clock_mmss clk_smmu_vfe_axi_clk>,
			<&clock_mmss clk_smmu_vfe_ahb_clk>,
			<&clock_mmss clk_camss_csi_vfe0_clk>,
			<&clock_mmss clk_vfe0_clk_src>,
			<&clock_mmss clk_camss_csi_vfe0_clk>,
			<&clock_mmss clk_camss_csi2_ahb_clk>,
			<&clock_mmss clk_camss_csi2_clk>,
			<&clock_mmss clk_camss_csi2phy_clk>,
			<&clock_mmss clk_csi2phytimer_clk_src>,
			<&clock_mmss clk_camss_csi2phytimer_clk>,
			<&clock_mmss clk_camss_csi2rdi_clk>,
			<&clock_mmss clk_camss_ispif_ahb_clk>,
			<&clock_mmss clk_camss_vfe0_clk>;
		clock-names =
			"mmss_mmagic_ahb_clk",
			"camss_top_ahb_clk",
			"cci_clk_src",
			"camss_cci_ahb_clk",
			"camss_cci_clk",
			"camss_ahb_clk",
			"mmagic_camss_axi_clk",
			"camss_vfe_ahb_clk",
			"camss_vfe0_ahb_clk",
			"camss_vfe_axi_clk",
			"camss_vfe0_stream_clk",
			"smmu_vfe_axi_clk",
			"smmu_vfe_ahb_clk",
			"camss_csi_vfe0_clk",
			"vfe0_clk_src",
			"camss_csi_vfe0_clk",
			"camss_csi2_ahb_clk",
			"camss_csi2_clk",
			"camss_csi2phy_clk",
			"csi2phytimer_clk_src",
			"camss_csi2phytimer_clk",
			"camss_csi2rdi_clk",
			"camss_ispif_ahb_clk",
			"clk_camss_vfe0_clk";

		qcom,clock-rates = <19200000
						19200000
						19200000
						19200000
						19200000
						19200000
						0
						0
						0
						320000000
						0
						0
						0
						0
						19200000
						0
						0
						200000000
						200000000
						200000000
						200000000
						200000000
						0
						100000000>;
	};

	ntn1: ntn_avb@1 { /* Neutrno device on RC1*/
		compatible = "qcom,ntn_avb";

@@ -1277,4 +1361,22 @@
	/delete-property/ qcom,spkr-sd-n-gpio;
};

&vfe_smmu {
	qcom,no-smr-check;
};

/ {
	reserved-memory {
		lk_mem: lk_pool@0x91600000 {
			no-map;
			reg = <0 0x91600000 0 0x00600000>;
			label = "lk_pool";
		};

		early_camera_mem: early_camera_mem@b3fff000 {
			reg = <0 0xb3fff000 0 0x800000>;
			label = "early_camera_mem";
		};
	};
};
+1 −0
Original line number Diff line number Diff line
@@ -2,3 +2,4 @@ ccflags-y += -Idrivers/media/platform/msm/ais
ccflags-y += -Idrivers/media/platform/msm/ais/common
ccflags-y += -Idrivers/media/platform/msm/ais/sensor/io
obj-$(CONFIG_MSM_AIS) += msm_cci.o
obj-$(CONFIG_MSM_AIS) += msm_early_cam.o
+277 −0
Original line number Diff line number Diff line
/* Copyright (c) 2012-2017, 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/clk.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/of_platform.h>
#include "msm_sd.h"
#include "msm_early_cam.h"
#include "msm_cam_cci_hwreg.h"
#include "msm_camera_io_util.h"
#include "msm_camera_dt_util.h"
#include "cam_hw_ops.h"

#undef CDBG
#define CDBG(fmt, args...) pr_debug(fmt, ##args)

#undef EARLY_CAM_DBG
#ifdef MSM_EARLY_CAM_DEBUG
#define EARLY_CAM_DBG(fmt, args...) pr_err(fmt, ##args)
#else
#define EARLY_CAM_DBG(fmt, args...) pr_debug(fmt, ##args)
#endif

#define MSM_EARLY_CAM_DRV_NAME "msm_early_cam"
static struct platform_driver msm_early_camera_driver;
static struct early_cam_device *new_early_cam_dev;

int msm_early_cam_disable_clocks(void)
{
	int rc = 0;

	CDBG("%s:\n", __func__);
	/* Vote OFF for clocks */
	if (new_early_cam_dev == NULL) {
		rc = -EINVAL;
		pr_err("%s: clock structure uninitialised %d\n", __func__,
			rc);
		return rc;
	}

	if ((new_early_cam_dev->pdev == NULL) ||
		(new_early_cam_dev->early_cam_clk_info == NULL) ||
		(new_early_cam_dev->early_cam_clk == NULL) ||
		(new_early_cam_dev->num_clk == 0)) {
		rc = -EINVAL;
		pr_err("%s: Clock details uninitialised %d\n", __func__,
			rc);
		return rc;
	}

	rc = msm_camera_clk_enable(&new_early_cam_dev->pdev->dev,
		new_early_cam_dev->early_cam_clk_info,
		new_early_cam_dev->early_cam_clk,
		new_early_cam_dev->num_clk, false);
	if (rc < 0) {
		pr_err("%s: clk disable failed %d\n", __func__, rc);
		return rc;
	}

	rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY,
		CAM_AHB_SUSPEND_VOTE);
	if (rc < 0) {
		pr_err("%s: failed to vote OFF AHB_CLIENT_CSIPHY %d\n",
			__func__, rc);
		return rc;
	}

	rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSID,
		CAM_AHB_SUSPEND_VOTE);
	if (rc < 0) {
		pr_err("%s: failed to vote OFF AHB_CLIENT_CSID %d\n",
			__func__, rc);
		return rc;
	}

	rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CCI,
		CAM_AHB_SUSPEND_VOTE);
	if (rc < 0) {
		pr_err("%s: failed to vote OFF AHB_CLIENT_CCI %d\n",
			__func__, rc);
		return rc;
	}

	rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_ISPIF,
		CAM_AHB_SUSPEND_VOTE);
	if (rc < 0) {
		pr_err("%s: failed to vote OFF AHB_CLIENT_ISPIF %d\n",
			__func__, rc);
		return rc;
	}

	rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_VFE0,
			CAM_AHB_SUSPEND_VOTE);
	if (rc < 0) {
		pr_err("%s: failed to vote OFF AHB_CLIENT_VFE0 %d\n",
			__func__, rc);
		return rc;
	}
	pr_debug("Turned OFF camera clocks\n");
	return 0;

}
static int msm_early_cam_probe(struct platform_device *pdev)
{
	int rc = 0;

	CDBG("%s: pdev %pK device id = %d\n", __func__, pdev, pdev->id);

	/* Vote for Early camera if enabled */
	rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSIPHY,
		CAM_AHB_SVS_VOTE);
	if (rc < 0) {
		pr_err("%s: failed to vote for AHB\n", __func__);
		return rc;
	}

	rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CSID,
		CAM_AHB_SVS_VOTE);
	if (rc < 0) {
		pr_err("%s: failed to vote for AHB\n", __func__);
		return rc;
	}

	rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_CCI,
		CAM_AHB_SVS_VOTE);
	if (rc < 0) {
		pr_err("%s: failed to vote for AHB\n", __func__);
		return rc;
	}

	rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_ISPIF,
		CAM_AHB_SVS_VOTE);
	if (rc < 0) {
		pr_err("%s: failed to vote for AHB\n", __func__);
		return rc;
	}

	rc = cam_config_ahb_clk(NULL, 0, CAM_AHB_CLIENT_VFE0,
			CAM_AHB_SVS_VOTE);
	if (rc < 0) {
		pr_err("%s: failed to vote for AHB\n", __func__);
		return rc;
	}

	new_early_cam_dev = kzalloc(sizeof(struct early_cam_device),
		GFP_KERNEL);

	if (pdev->dev.of_node)
		of_property_read_u32((&pdev->dev)->of_node,
			"cell-index", &pdev->id);

	rc = msm_camera_get_clk_info_and_rates(pdev,
		&new_early_cam_dev->early_cam_clk_info,
		&new_early_cam_dev->early_cam_clk,
		&new_early_cam_dev->early_cam_clk_rates,
		&new_early_cam_dev->num_clk_cases,
		&new_early_cam_dev->num_clk);
	if (rc < 0) {
		pr_err("%s: msm_early_cam_get_clk_info() failed", __func__);
		kfree(new_early_cam_dev);
		return -EFAULT;
	}

	new_early_cam_dev->ref_count = 0;
	new_early_cam_dev->pdev = pdev;

	rc = msm_camera_get_dt_vreg_data(
		new_early_cam_dev->pdev->dev.of_node,
		&(new_early_cam_dev->early_cam_vreg),
		&(new_early_cam_dev->regulator_count));
	if (rc < 0) {
		pr_err("%s: msm_camera_get_dt_vreg_data fail\n", __func__);
		rc = -EFAULT;
		goto early_cam_release_mem;
	}

	if ((new_early_cam_dev->regulator_count < 0) ||
		(new_early_cam_dev->regulator_count > MAX_REGULATOR)) {
		pr_err("%s: invalid reg count = %d, max is %d\n", __func__,
			new_early_cam_dev->regulator_count, MAX_REGULATOR);
		rc = -EFAULT;
		goto early_cam_invalid_vreg_data;
	}

	rc = msm_camera_config_vreg(&new_early_cam_dev->pdev->dev,
		new_early_cam_dev->early_cam_vreg,
		new_early_cam_dev->regulator_count,
		NULL,
		0,
		&new_early_cam_dev->early_cam_reg_ptr[0], 1);
	if (rc < 0)
		pr_err("%s:%d early_cam config_vreg failed\n", __func__,
			__LINE__);

	rc = msm_camera_enable_vreg(&new_early_cam_dev->pdev->dev,
		new_early_cam_dev->early_cam_vreg,
		new_early_cam_dev->regulator_count,
		NULL,
		0,
		&new_early_cam_dev->early_cam_reg_ptr[0], 1);
	if (rc < 0)
		pr_err("%s:%d early_cam enable_vreg failed\n", __func__,
		__LINE__);

	rc = msm_camera_clk_enable(&new_early_cam_dev->pdev->dev,
		new_early_cam_dev->early_cam_clk_info,
		new_early_cam_dev->early_cam_clk,
		new_early_cam_dev->num_clk, true);

	if (rc < 0) {
		pr_err("%s: clk enable failed %d\n", __func__, rc);
		rc = 0;
		goto early_cam_release_mem;
	}

	platform_set_drvdata(pdev, new_early_cam_dev);

	return 0;

early_cam_invalid_vreg_data:
	kfree(new_early_cam_dev->early_cam_vreg);
early_cam_release_mem:
	kfree(new_early_cam_dev);
	new_early_cam_dev = NULL;
	return rc;
}

static int msm_early_cam_exit(struct platform_device *pdev)
{
	return 0;
}

static int __init msm_early_cam_init_module(void)
{
	return platform_driver_register(&msm_early_camera_driver);
}

static void __exit msm_early_cam_exit_module(void)
{
	kfree(new_early_cam_dev);
	platform_driver_unregister(&msm_early_camera_driver);
}

static const struct of_device_id msm_early_camera_match_table[] = {
	{ .compatible = "qcom,early-cam" },
	{},
};

static struct platform_driver msm_early_camera_driver = {
	.probe = msm_early_cam_probe,
	.remove = msm_early_cam_exit,
	.driver = {
		.name = MSM_EARLY_CAM_DRV_NAME,
		.owner = THIS_MODULE,
		.of_match_table = msm_early_camera_match_table,
	},
};

MODULE_DEVICE_TABLE(of, msm_early_camera_match_table);

module_init(msm_early_cam_init_module);
module_exit(msm_early_cam_exit_module);
MODULE_DESCRIPTION("MSM early camera driver");
MODULE_LICENSE("GPL v2");
Loading