Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add linux patches for V4L2 M2M driver
- Loading branch information
1 parent
f7311d1
commit b3b60c3
Showing
20 changed files
with
8,662 additions
and
115 deletions.
There are no files selected for viewing
136 changes: 136 additions & 0 deletions
136
...el/linux/linux-yocto-meson64-4.16/0001-clock-meson8b-add-clocks-necessary-for-VDEC1.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
From f7c84635cccaeeefae003012611f26d6a85f342e Mon Sep 17 00:00:00 2001 | ||
From: Maxime Jourdan <raptorteak@gmail.com> | ||
Date: Thu, 15 Mar 2018 13:32:33 +0100 | ||
Subject: [PATCH] clock: meson8b: add clocks necessary for VDEC1 | ||
|
||
--- | ||
drivers/clk/meson/meson8b.c | 55 ++++++++++++++++++++++++++++++++ | ||
drivers/clk/meson/meson8b.h | 6 +++- | ||
include/dt-bindings/clock/meson8b-clkc.h | 3 ++ | ||
3 files changed, 63 insertions(+), 1 deletion(-) | ||
|
||
diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c | ||
index 3ffea80..d323749 100644 | ||
--- a/drivers/clk/meson/meson8b.c | ||
+++ b/drivers/clk/meson/meson8b.c | ||
@@ -418,6 +418,55 @@ struct clk_gate meson8b_clk81 = { | ||
}, | ||
}; | ||
|
||
+/* VDEC clocks */ | ||
+ | ||
+static u32 mux_table_vdec[] = {0, 1, 2, 3}; | ||
+static const char * const meson8b_vdec_parent_names[] = { | ||
+ "fclk_div4", "fclk_div3", "fclk_div5", "fclk_div7" | ||
+}; | ||
+ | ||
+static struct clk_mux meson8b_vdec_1_sel = { | ||
+ .reg = (void *)HHI_VDEC_CLK_CNTL, | ||
+ .mask = 0x3, | ||
+ .shift = 9, | ||
+ .lock = &meson_clk_lock, | ||
+ .table = mux_table_vdec, | ||
+ .hw.init = &(struct clk_init_data){ | ||
+ .name = "vdec_1_sel", | ||
+ .ops = &clk_mux_ops, | ||
+ .parent_names = meson8b_vdec_parent_names, | ||
+ .num_parents = ARRAY_SIZE(meson8b_vdec_parent_names), | ||
+ .flags = CLK_SET_RATE_NO_REPARENT, | ||
+ }, | ||
+}; | ||
+ | ||
+static struct clk_divider meson8b_vdec_1_div = { | ||
+ .reg = (void *)HHI_VDEC_CLK_CNTL, | ||
+ .shift = 0, | ||
+ .width = 7, | ||
+ .lock = &meson_clk_lock, | ||
+ .hw.init = &(struct clk_init_data){ | ||
+ .name = "vdec_1_div", | ||
+ .ops = &clk_divider_ops, | ||
+ .parent_names = (const char *[]){ "vdec_1_sel" }, | ||
+ .num_parents = 1, | ||
+ .flags = CLK_SET_RATE_PARENT, | ||
+ }, | ||
+}; | ||
+ | ||
+static struct clk_gate meson8b_vdec_1 = { | ||
+ .reg = (void *)HHI_VDEC_CLK_CNTL, | ||
+ .bit_idx = 8, | ||
+ .lock = &meson_clk_lock, | ||
+ .hw.init = &(struct clk_init_data) { | ||
+ .name = "vdec_1", | ||
+ .ops = &clk_gate_ops, | ||
+ .parent_names = (const char *[]){ "vdec_1_div" }, | ||
+ .num_parents = 1, | ||
+ .flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED, | ||
+ }, | ||
+}; | ||
+ | ||
/* Everything Else (EE) domain gates */ | ||
|
||
static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0); | ||
@@ -599,6 +648,9 @@ static struct clk_hw_onecell_data meson8b_hw_onecell_data = { | ||
[CLKID_MPLL0] = &meson8b_mpll0.hw, | ||
[CLKID_MPLL1] = &meson8b_mpll1.hw, | ||
[CLKID_MPLL2] = &meson8b_mpll2.hw, | ||
+ [CLKID_VDEC_1_SEL] = &meson8b_vdec_1_sel.hw, | ||
+ [CLKID_VDEC_1_DIV] = &meson8b_vdec_1_div.hw, | ||
+ [CLKID_VDEC_1] = &meson8b_vdec_1.hw, | ||
[CLK_NR_CLKS] = NULL, | ||
}, | ||
.num = CLK_NR_CLKS, | ||
@@ -695,14 +747,17 @@ static struct clk_gate *const meson8b_clk_gates[] = { | ||
&meson8b_ao_ahb_sram, | ||
&meson8b_ao_ahb_bus, | ||
&meson8b_ao_iface, | ||
+ &meson8b_vdec_1, | ||
}; | ||
|
||
static struct clk_mux *const meson8b_clk_muxes[] = { | ||
&meson8b_mpeg_clk_sel, | ||
+ &meson8b_vdec_1_sel, | ||
}; | ||
|
||
static struct clk_divider *const meson8b_clk_dividers[] = { | ||
&meson8b_mpeg_clk_div, | ||
+ &meson8b_vdec_1_div, | ||
}; | ||
|
||
static const struct meson8b_clk_reset_line { | ||
diff --git a/drivers/clk/meson/meson8b.h b/drivers/clk/meson/meson8b.h | ||
index 2eaf8a5..aa5f97f 100644 | ||
--- a/drivers/clk/meson/meson8b.h | ||
+++ b/drivers/clk/meson/meson8b.h | ||
@@ -40,6 +40,10 @@ | ||
#define HHI_VID_CLK_CNTL 0x17c /* 0x5f offset in data sheet */ | ||
#define HHI_VID_DIVIDER_CNTL 0x198 /* 0x66 offset in data sheet */ | ||
#define HHI_SYS_CPU_CLK_CNTL0 0x19c /* 0x67 offset in data sheet */ | ||
+#define HHI_VDEC_CLK_CNTL 0x1e0 | ||
+#define HHI_VDEC2_CLK_CNTL 0x1e4 | ||
+#define HHI_VDEC3_CLK_CNTL 0x1e8 | ||
+#define HHI_VDEC4_CLK_CNTL 0x1ec | ||
#define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */ | ||
#define HHI_SYS_PLL_CNTL 0x300 /* 0xc0 offset in data sheet */ | ||
#define HHI_VID_PLL_CNTL 0x320 /* 0xc8 offset in data sheet */ | ||
@@ -69,7 +73,7 @@ | ||
* will remain defined here. | ||
*/ | ||
|
||
-#define CLK_NR_CLKS 96 | ||
+#define CLK_NR_CLKS 99 | ||
|
||
/* | ||
* include the CLKID and RESETID that have | ||
diff --git a/include/dt-bindings/clock/meson8b-clkc.h b/include/dt-bindings/clock/meson8b-clkc.h | ||
index dea9d46..49bcf5f 100644 | ||
--- a/include/dt-bindings/clock/meson8b-clkc.h | ||
+++ b/include/dt-bindings/clock/meson8b-clkc.h | ||
@@ -102,5 +102,8 @@ | ||
#define CLKID_MPLL0 93 | ||
#define CLKID_MPLL1 94 | ||
#define CLKID_MPLL2 95 | ||
+#define CLKID_VDEC_1_SEL 96 | ||
+#define CLKID_VDEC_1_DIV 97 | ||
+#define CLKID_VDEC_1 98 | ||
|
||
#endif /* __MESON8B_CLKC_H */ |
170 changes: 170 additions & 0 deletions
170
...-kernel/linux/linux-yocto-meson64-4.16/0002-soc-meson-add-power-controller-for-vdec.patch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
From f013a1deeac856e9b46f27b66463d6f978039789 Mon Sep 17 00:00:00 2001 | ||
From: Maxime Jourdan <raptorteak@gmail.com> | ||
Date: Thu, 15 Mar 2018 13:39:41 +0100 | ||
Subject: [PATCH] soc: meson: add power controller for vdec | ||
|
||
--- | ||
drivers/soc/amlogic/Makefile | 1 + | ||
drivers/soc/amlogic/meson-pwrc-vdec.c | 144 ++++++++++++++++++++++++++++++++++ | ||
2 files changed, 145 insertions(+) | ||
create mode 100644 drivers/soc/amlogic/meson-pwrc-vdec.c | ||
|
||
diff --git a/drivers/soc/amlogic/Makefile b/drivers/soc/amlogic/Makefile | ||
index 8fa3218..ffb388d 100644 | ||
--- a/drivers/soc/amlogic/Makefile | ||
+++ b/drivers/soc/amlogic/Makefile | ||
@@ -1,3 +1,4 @@ | ||
obj-$(CONFIG_MESON_GX_SOCINFO) += meson-gx-socinfo.o | ||
obj-$(CONFIG_MESON_GX_PM_DOMAINS) += meson-gx-pwrc-vpu.o | ||
+obj-$(CONFIG_MESON_GX_PM_DOMAINS) += meson-pwrc-vdec.o | ||
obj-$(CONFIG_MESON_MX_SOCINFO) += meson-mx-socinfo.o | ||
diff --git a/drivers/soc/amlogic/meson-pwrc-vdec.c b/drivers/soc/amlogic/meson-pwrc-vdec.c | ||
new file mode 100644 | ||
index 0000000..fac704c | ||
--- /dev/null | ||
+++ b/drivers/soc/amlogic/meson-pwrc-vdec.c | ||
@@ -0,0 +1,144 @@ | ||
+/* | ||
+ * Author: Maxime Jourdan <maxi.jourdan@wanadoo.fr> | ||
+ * | ||
+ * SPDX-License-Identifier: GPL-2.0+ | ||
+ */ | ||
+ | ||
+#include <linux/of_address.h> | ||
+#include <linux/platform_device.h> | ||
+#include <linux/pm_domain.h> | ||
+#include <linux/bitfield.h> | ||
+#include <linux/regmap.h> | ||
+#include <linux/mfd/syscon.h> | ||
+#include <linux/reset.h> | ||
+#include <linux/clk.h> | ||
+#include <linux/clk-provider.h> | ||
+ | ||
+/* AO Offsets */ | ||
+#define AO_RTI_GEN_PWR_SLEEP0 (0x3a << 2) | ||
+ | ||
+#define GEN_PWR_VDEC_1 (BIT(3) | BIT(2)) | ||
+ | ||
+struct meson_pwrc_vdec { | ||
+ struct generic_pm_domain genpd; | ||
+ struct regmap *regmap_ao; | ||
+ struct clk *dos_parser_clk; | ||
+ struct clk *vpu_intr_clk; | ||
+ struct clk *vdec_1_clk; | ||
+}; | ||
+ | ||
+static inline | ||
+struct meson_pwrc_vdec *genpd_to_pd(struct generic_pm_domain *d) | ||
+{ | ||
+ return container_of(d, struct meson_pwrc_vdec, genpd); | ||
+} | ||
+ | ||
+static int meson_pwrc_vdec_power_off(struct generic_pm_domain *genpd) | ||
+{ | ||
+ struct meson_pwrc_vdec *pd = genpd_to_pd(genpd); | ||
+ | ||
+ regmap_update_bits(pd->regmap_ao, AO_RTI_GEN_PWR_SLEEP0, | ||
+ GEN_PWR_VDEC_1, GEN_PWR_VDEC_1); | ||
+ udelay(20); | ||
+ | ||
+ clk_disable_unprepare(pd->vpu_intr_clk); | ||
+ clk_disable_unprepare(pd->dos_parser_clk); | ||
+ clk_disable_unprepare(pd->vdec_1_clk); | ||
+ | ||
+ return 0; | ||
+} | ||
+ | ||
+static int meson_pwrc_vdec_setup_clk(struct meson_pwrc_vdec *pd) { | ||
+ clk_prepare_enable(pd->dos_parser_clk); | ||
+ clk_prepare_enable(pd->vpu_intr_clk); | ||
+ clk_prepare_enable(pd->vdec_1_clk); | ||
+ | ||
+ return 0; | ||
+} | ||
+ | ||
+static int meson_pwrc_vdec_power_on(struct generic_pm_domain *genpd) | ||
+{ | ||
+ struct meson_pwrc_vdec *pd = genpd_to_pd(genpd); | ||
+ | ||
+ meson_pwrc_vdec_setup_clk(pd); | ||
+ regmap_update_bits(pd->regmap_ao, AO_RTI_GEN_PWR_SLEEP0, GEN_PWR_VDEC_1, 0); | ||
+ udelay(10); | ||
+ | ||
+ return 0; | ||
+} | ||
+ | ||
+static bool meson_pwrc_vdec_get_power(struct meson_pwrc_vdec *pd) | ||
+{ | ||
+ u32 reg; | ||
+ | ||
+ regmap_read(pd->regmap_ao, AO_RTI_GEN_PWR_SLEEP0, ®); | ||
+ | ||
+ return ((reg & GEN_PWR_VDEC_1) == GEN_PWR_VDEC_1); | ||
+} | ||
+ | ||
+static struct meson_pwrc_vdec vdec_pd = { | ||
+ .genpd = { | ||
+ .name = "vdec", | ||
+ .power_off = meson_pwrc_vdec_power_off, | ||
+ .power_on = meson_pwrc_vdec_power_on, | ||
+ }, | ||
+}; | ||
+ | ||
+static int meson_pwrc_vdec_probe(struct platform_device *pdev) | ||
+{ | ||
+ struct regmap *regmap_ao; | ||
+ bool powered_off; | ||
+ int ret; | ||
+ | ||
+ regmap_ao = syscon_node_to_regmap(of_get_parent(pdev->dev.of_node)); | ||
+ if (IS_ERR(regmap_ao)) { | ||
+ dev_err(&pdev->dev, "failed to get AO regmap\n"); | ||
+ return PTR_ERR(regmap_ao); | ||
+ } | ||
+ | ||
+ vdec_pd.vpu_intr_clk = devm_clk_get(&pdev->dev, "vpu_intr"); | ||
+ vdec_pd.dos_parser_clk = devm_clk_get(&pdev->dev, "dos_parser"); | ||
+ vdec_pd.vdec_1_clk = devm_clk_get(&pdev->dev, "vdec_1"); | ||
+ vdec_pd.regmap_ao = regmap_ao; | ||
+ | ||
+ powered_off = meson_pwrc_vdec_get_power(&vdec_pd); | ||
+ | ||
+ pm_genpd_init(&vdec_pd.genpd, &pm_domain_always_on_gov, | ||
+ powered_off); | ||
+ | ||
+ /* If already powered, sync the clock states */ | ||
+ if (!powered_off) { | ||
+ ret = meson_pwrc_vdec_setup_clk(&vdec_pd); | ||
+ if (ret) | ||
+ return ret; | ||
+ } else { | ||
+ meson_pwrc_vdec_power_on(&vdec_pd.genpd); | ||
+ } | ||
+ | ||
+ return of_genpd_add_provider_simple(pdev->dev.of_node, | ||
+ &vdec_pd.genpd); | ||
+} | ||
+ | ||
+static void meson_pwrc_vdec_shutdown(struct platform_device *pdev) | ||
+{ | ||
+ bool powered_off; | ||
+ | ||
+ powered_off = meson_pwrc_vdec_get_power(&vdec_pd); | ||
+ if (!powered_off) | ||
+ meson_pwrc_vdec_power_off(&vdec_pd.genpd); | ||
+} | ||
+ | ||
+static const struct of_device_id meson_pwrc_vdec_match_table[] = { | ||
+ { .compatible = "amlogic,meson-pwrc-vdec" }, | ||
+ { /* sentinel */ } | ||
+}; | ||
+ | ||
+static struct platform_driver meson_pwrc_vdec_driver = { | ||
+ .probe = meson_pwrc_vdec_probe, | ||
+ .shutdown = meson_pwrc_vdec_shutdown, | ||
+ .driver = { | ||
+ .name = "meson_pwrc_vdec", | ||
+ .of_match_table = meson_pwrc_vdec_match_table, | ||
+ }, | ||
+}; | ||
+builtin_platform_driver(meson_pwrc_vdec_driver); |
Oops, something went wrong.