summaryrefslogtreecommitdiff
path: root/drivers/media/platform/qcom/camss-8x16/camss.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/platform/qcom/camss-8x16/camss.c')
-rw-r--r--drivers/media/platform/qcom/camss-8x16/camss.c67
1 files changed, 57 insertions, 10 deletions
diff --git a/drivers/media/platform/qcom/camss-8x16/camss.c b/drivers/media/platform/qcom/camss-8x16/camss.c
index 2dee77a80327..a3760b5dd1d1 100644
--- a/drivers/media/platform/qcom/camss-8x16/camss.c
+++ b/drivers/media/platform/qcom/camss-8x16/camss.c
@@ -33,13 +33,19 @@
#include "camss.h"
+#define CAMSS_CLOCK_MARGIN_NUMERATOR 105
+#define CAMSS_CLOCK_MARGIN_DENOMINATOR 100
+
static const struct resources csiphy_res[] = {
/* CSIPHY0 */
{
.regulator = { NULL },
.clock = { "camss_top_ahb", "ispif_ahb",
"camss_ahb", "csiphy0_timer" },
- .clock_rate = { 0, 0, 0, 200000000 },
+ .clock_rate = { { 0 },
+ { 0 },
+ { 0 },
+ { 100000000, 200000000 } },
.reg = { "csiphy0", "csiphy0_clk_mux" },
.interrupt = { "csiphy0" }
},
@@ -49,7 +55,10 @@ static const struct resources csiphy_res[] = {
.regulator = { NULL },
.clock = { "camss_top_ahb", "ispif_ahb",
"camss_ahb", "csiphy1_timer" },
- .clock_rate = { 0, 0, 0, 200000000 },
+ .clock_rate = { { 0 },
+ { 0 },
+ { 0 },
+ { 100000000, 200000000 } },
.reg = { "csiphy1", "csiphy1_clk_mux" },
.interrupt = { "csiphy1" }
}
@@ -62,7 +71,14 @@ static const struct resources csid_res[] = {
.clock = { "camss_top_ahb", "ispif_ahb",
"csi0_ahb", "camss_ahb",
"csi0", "csi0_phy", "csi0_pix", "csi0_rdi" },
- .clock_rate = { 0, 0, 0, 0, 200000000, 0, 0, 0 },
+ .clock_rate = { { 0 },
+ { 0 },
+ { 0 },
+ { 0 },
+ { 100000000, 200000000 },
+ { 0 },
+ { 0 },
+ { 0 } },
.reg = { "csid0" },
.interrupt = { "csid0" }
},
@@ -73,7 +89,14 @@ static const struct resources csid_res[] = {
.clock = { "camss_top_ahb", "ispif_ahb",
"csi1_ahb", "camss_ahb",
"csi1", "csi1_phy", "csi1_pix", "csi1_rdi" },
- .clock_rate = { 0, 0, 0, 0, 200000000, 0, 0, 0 },
+ .clock_rate = { { 0 },
+ { 0 },
+ { 0 },
+ { 0 },
+ { 100000000, 200000000 },
+ { 0 },
+ { 0 },
+ { 0 } },
.reg = { "csid1" },
.interrupt = { "csid1" }
},
@@ -95,12 +118,35 @@ static const struct resources vfe_res = {
.regulator = { NULL },
.clock = { "camss_top_ahb", "camss_vfe_vfe", "camss_csi_vfe",
"iface", "bus", "camss_ahb" },
- .clock_rate = { 0, 320000000, 0, 0, 0, 0, 0, 0 },
+ .clock_rate = { { 0 },
+ { 50000000, 80000000, 100000000, 160000000,
+ 177780000, 200000000, 266670000, 320000000,
+ 400000000, 465000000 },
+ { 0 },
+ { 0 },
+ { 0 },
+ { 0 },
+ { 0 },
+ { 0 },
+ { 0 } },
.reg = { "vfe0" },
.interrupt = { "vfe0" }
};
/*
+ * camss_add_clock_margin - Add margin to clock frequency rate
+ * @rate: Clock frequency rate
+ *
+ * When making calculations with physical clock frequency values
+ * some safety margin must be added. Add it.
+ */
+inline void camss_add_clock_margin(u64 *rate)
+{
+ *rate *= CAMSS_CLOCK_MARGIN_NUMERATOR;
+ *rate = div_u64(*rate, CAMSS_CLOCK_MARGIN_DENOMINATOR);
+}
+
+/*
* camss_enable_clocks - Enable multiple clocks
* @nclocks: Number of clocks in clock array
* @clock: Clock array
@@ -108,13 +154,14 @@ static const struct resources vfe_res = {
*
* Return 0 on success or a negative error code otherwise
*/
-int camss_enable_clocks(int nclocks, struct clk **clock, struct device *dev)
+int camss_enable_clocks(int nclocks, struct camss_clock *clock,
+ struct device *dev)
{
int ret;
int i;
for (i = 0; i < nclocks; i++) {
- ret = clk_prepare_enable(clock[i]);
+ ret = clk_prepare_enable(clock[i].clk);
if (ret) {
dev_err(dev, "clock enable failed: %d\n", ret);
goto error;
@@ -125,7 +172,7 @@ int camss_enable_clocks(int nclocks, struct clk **clock, struct device *dev)
error:
for (i--; i >= 0; i--)
- clk_disable_unprepare(clock[i]);
+ clk_disable_unprepare(clock[i].clk);
return ret;
}
@@ -135,12 +182,12 @@ error:
* @nclocks: Number of clocks in clock array
* @clock: Clock array
*/
-void camss_disable_clocks(int nclocks, struct clk **clock)
+void camss_disable_clocks(int nclocks, struct camss_clock *clock)
{
int i;
for (i = nclocks - 1; i >= 0; i--)
- clk_disable_unprepare(clock[i]);
+ clk_disable_unprepare(clock[i].clk);
}
/*