diff options
Diffstat (limited to 'drivers/media/platform/qcom/camss-8x16/camss.c')
-rw-r--r-- | drivers/media/platform/qcom/camss-8x16/camss.c | 67 |
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); } /* |