diff options
author | Claudiu Beznea <claudiu.beznea@microchip.com> | 2022-02-04 15:57:50 +0200 |
---|---|---|
committer | Petr Štetiar <ynezz@true.cz> | 2022-02-24 19:05:28 +0100 |
commit | e58cd453d58b20c6a6f34d3591640aa19aa14d25 (patch) | |
tree | a4fef5f5d79575a7a60b516482ee114c1dbc932e /target | |
parent | 3ed992a99630457f660761ce199e3d2a00f06168 (diff) | |
download | upstream-e58cd453d58b20c6a6f34d3591640aa19aa14d25.tar.gz upstream-e58cd453d58b20c6a6f34d3591640aa19aa14d25.tar.bz2 upstream-e58cd453d58b20c6a6f34d3591640aa19aa14d25.zip |
at91: add kernel support for sama7g5 soc
Add kernel support for SAMA7G5 by back-porting mainline kernel patches.
Among SAMA7G5 features could be remembered:
- ARM Cortex-A7
- double data rate multi-port dynamic RAM controller supporting DDR2,
DDR3, DDR3L, LPDDR2, LPDDR3 up to 533MHz
- peripherals for audio, video processing
- 1 gigabit + 1 megabit Ethernet controllers
- 6 CAN controllers
- trust zone support
- DVFS for CPU
- criptography IPs
Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com>
Diffstat (limited to 'target')
152 files changed, 20714 insertions, 7 deletions
diff --git a/target/linux/at91/Makefile b/target/linux/at91/Makefile index e4da7fb7e7..36804a1eeb 100644 --- a/target/linux/at91/Makefile +++ b/target/linux/at91/Makefile @@ -8,7 +8,7 @@ ARCH:=arm BOARD:=at91 BOARDNAME:=Microchip (Atmel AT91) FEATURES:=ext4 squashfs targz usb usbgadget ubifs -SUBTARGETS:=sama5 sam9x +SUBTARGETS:=sama7 sama5 sam9x KERNEL_PATCHVER:=5.10 diff --git a/target/linux/at91/patches-5.10/102-dt-bindings-clock-at91-add-sama7g5-pll-defines.patch b/target/linux/at91/patches-5.10/102-dt-bindings-clock-at91-add-sama7g5-pll-defines.patch new file mode 100644 index 0000000000..2f2e6641a4 --- /dev/null +++ b/target/linux/at91/patches-5.10/102-dt-bindings-clock-at91-add-sama7g5-pll-defines.patch @@ -0,0 +1,72 @@ +From 44bb7c72cdd830f54fe18e730205f892d9cbfe39 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Thu, 19 Nov 2020 17:43:08 +0200 +Subject: [PATCH 102/247] dt-bindings: clock: at91: add sama7g5 pll defines + +Add SAMA7G5 specific PLL defines to be referenced in a phandle as a +PMC_TYPE_CORE clock. + +Suggested-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +[claudiu.beznea@microchip.com: adapt comit message, adapt sama7g5.c] +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/1605800597-16720-3-git-send-email-claudiu.beznea@microchip.com +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/sama7g5.c | 6 +++--- + include/dt-bindings/clock/at91.h | 10 ++++++++++ + 2 files changed, 13 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c +index a092a940baa4..7ef7963126b6 100644 +--- a/drivers/clk/at91/sama7g5.c ++++ b/drivers/clk/at91/sama7g5.c +@@ -182,13 +182,13 @@ static const struct { + .p = "audiopll_fracck", + .l = &pll_layout_divpmc, + .t = PLL_TYPE_DIV, +- .eid = PMC_I2S0_MUX, }, ++ .eid = PMC_AUDIOPMCPLL, }, + + { .n = "audiopll_diviock", + .p = "audiopll_fracck", + .l = &pll_layout_divio, + .t = PLL_TYPE_DIV, +- .eid = PMC_I2S1_MUX, }, ++ .eid = PMC_AUDIOIOPLL, }, + }, + + [PLL_ID_ETH] = { +@@ -835,7 +835,7 @@ static void __init sama7g5_pmc_setup(struct device_node *np) + if (IS_ERR(regmap)) + return; + +- sama7g5_pmc = pmc_data_allocate(PMC_I2S1_MUX + 1, ++ sama7g5_pmc = pmc_data_allocate(PMC_ETHPLL + 1, + nck(sama7g5_systemck), + nck(sama7g5_periphck), + nck(sama7g5_gck), 8); +diff --git a/include/dt-bindings/clock/at91.h b/include/dt-bindings/clock/at91.h +index eba17106608b..fab313f62e8f 100644 +--- a/include/dt-bindings/clock/at91.h ++++ b/include/dt-bindings/clock/at91.h +@@ -25,6 +25,16 @@ + #define PMC_PLLBCK 8 + #define PMC_AUDIOPLLCK 9 + ++/* SAMA7G5 */ ++#define PMC_CPUPLL (PMC_MAIN + 1) ++#define PMC_SYSPLL (PMC_MAIN + 2) ++#define PMC_DDRPLL (PMC_MAIN + 3) ++#define PMC_IMGPLL (PMC_MAIN + 4) ++#define PMC_BAUDPLL (PMC_MAIN + 5) ++#define PMC_AUDIOPMCPLL (PMC_MAIN + 6) ++#define PMC_AUDIOIOPLL (PMC_MAIN + 7) ++#define PMC_ETHPLL (PMC_MAIN + 8) ++ + #ifndef AT91_PMC_MOSCS + #define AT91_PMC_MOSCS 0 /* MOSCS Flag */ + #define AT91_PMC_LOCKA 1 /* PLLA Lock */ +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/103-clk-at91-sama7g5-allow-SYS-and-CPU-PLLs-to-be-export.patch b/target/linux/at91/patches-5.10/103-clk-at91-sama7g5-allow-SYS-and-CPU-PLLs-to-be-export.patch new file mode 100644 index 0000000000..312e6466cc --- /dev/null +++ b/target/linux/at91/patches-5.10/103-clk-at91-sama7g5-allow-SYS-and-CPU-PLLs-to-be-export.patch @@ -0,0 +1,46 @@ +From 55c14526f970805a6bf2ed4b820f062334375abe Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Thu, 19 Nov 2020 17:43:09 +0200 +Subject: [PATCH 103/247] clk: at91: sama7g5: allow SYS and CPU PLLs to be + exported and referenced in DT + +Allow SYSPLL and CPUPLL to be referenced as a PMC_TYPE_CORE clock +from phandle in DT. + +Suggested-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +[claudiu.beznea@microchip.com: adapt commit message, add CPU PLL] +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/1605800597-16720-4-git-send-email-claudiu.beznea@microchip.com +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/sama7g5.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c +index 7ef7963126b6..d3c3469d47d9 100644 +--- a/drivers/clk/at91/sama7g5.c ++++ b/drivers/clk/at91/sama7g5.c +@@ -117,7 +117,8 @@ static const struct { + .p = "cpupll_fracck", + .l = &pll_layout_divpmc, + .t = PLL_TYPE_DIV, +- .c = 1, }, ++ .c = 1, ++ .eid = PMC_CPUPLL, }, + }, + + [PLL_ID_SYS] = { +@@ -131,7 +132,8 @@ static const struct { + .p = "syspll_fracck", + .l = &pll_layout_divpmc, + .t = PLL_TYPE_DIV, +- .c = 1, }, ++ .c = 1, ++ .eid = PMC_SYSPLL, }, + }, + + [PLL_ID_DDR] = { +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/104-clk-at91-clk-master-add-5th-divisor-for-mck-master.patch b/target/linux/at91/patches-5.10/104-clk-at91-clk-master-add-5th-divisor-for-mck-master.patch new file mode 100644 index 0000000000..f01d6f4b3a --- /dev/null +++ b/target/linux/at91/patches-5.10/104-clk-at91-clk-master-add-5th-divisor-for-mck-master.patch @@ -0,0 +1,49 @@ +From b2349278894bb381fa26a8717d3093d53f08fd36 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Thu, 19 Nov 2020 17:43:10 +0200 +Subject: [PATCH 104/247] clk: at91: clk-master: add 5th divisor for mck master + +clk-master can have 5 divisors with a field width of 3 bits +on some products. + +Change the mask and number of divisors accordingly. + +Reported-by: Mihai Sain <mihai.sain@microchip.com> +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/1605800597-16720-5-git-send-email-claudiu.beznea@microchip.com +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/clk-master.c | 2 +- + drivers/clk/at91/pmc.h | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c +index bd0d8a69a2cf..aafd003b30cf 100644 +--- a/drivers/clk/at91/clk-master.c ++++ b/drivers/clk/at91/clk-master.c +@@ -15,7 +15,7 @@ + #define MASTER_PRES_MASK 0x7 + #define MASTER_PRES_MAX MASTER_PRES_MASK + #define MASTER_DIV_SHIFT 8 +-#define MASTER_DIV_MASK 0x3 ++#define MASTER_DIV_MASK 0x7 + + #define PMC_MCR 0x30 + #define PMC_MCR_ID_MSK GENMASK(3, 0) +diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h +index 7b86affc6d7c..0a9364bde339 100644 +--- a/drivers/clk/at91/pmc.h ++++ b/drivers/clk/at91/pmc.h +@@ -48,7 +48,7 @@ extern const struct clk_master_layout at91sam9x5_master_layout; + + struct clk_master_characteristics { + struct clk_range output; +- u32 divisors[4]; ++ u32 divisors[5]; + u8 have_div3_pres; + }; + +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/105-clk-at91-sama7g5-add-5th-divisor-for-mck0-layout-and.patch b/target/linux/at91/patches-5.10/105-clk-at91-sama7g5-add-5th-divisor-for-mck0-layout-and.patch new file mode 100644 index 0000000000..713bc737a1 --- /dev/null +++ b/target/linux/at91/patches-5.10/105-clk-at91-sama7g5-add-5th-divisor-for-mck0-layout-and.patch @@ -0,0 +1,41 @@ +From c41f013e13962dcc78239d5e4834214d44556cfb Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Thu, 19 Nov 2020 17:43:11 +0200 +Subject: [PATCH 105/247] clk: at91: sama7g5: add 5th divisor for mck0 layout + and characteristics + +This SoC has the 5th divisor for the mck0 master clock. +Adapt the characteristics accordingly. + +Reported-by: Mihai Sain <mihai.sain@microchip.com> +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/1605800597-16720-6-git-send-email-claudiu.beznea@microchip.com +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/sama7g5.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c +index d3c3469d47d9..d685e22b2014 100644 +--- a/drivers/clk/at91/sama7g5.c ++++ b/drivers/clk/at91/sama7g5.c +@@ -775,13 +775,13 @@ static const struct clk_pll_characteristics pll_characteristics = { + /* MCK0 characteristics. */ + static const struct clk_master_characteristics mck0_characteristics = { + .output = { .min = 140000000, .max = 200000000 }, +- .divisors = { 1, 2, 4, 3 }, ++ .divisors = { 1, 2, 4, 3, 5 }, + .have_div3_pres = 1, + }; + + /* MCK0 layout. */ + static const struct clk_master_layout mck0_layout = { +- .mask = 0x373, ++ .mask = 0x773, + .pres_shift = 4, + .offset = 0x28, + }; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/106-clk-at91-clk-sam9x60-pll-allow-runtime-changes-for-p.patch b/target/linux/at91/patches-5.10/106-clk-at91-clk-sam9x60-pll-allow-runtime-changes-for-p.patch new file mode 100644 index 0000000000..f27634ae8b --- /dev/null +++ b/target/linux/at91/patches-5.10/106-clk-at91-clk-sam9x60-pll-allow-runtime-changes-for-p.patch @@ -0,0 +1,521 @@ +From 6fe2927863de96edf35d8357712dbf83a489f556 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 19 Nov 2020 17:43:12 +0200 +Subject: [PATCH 106/247] clk: at91: clk-sam9x60-pll: allow runtime changes for + pll + +Allow runtime frequency changes for PLLs registered with proper flags. +This is necessary for CPU PLL on SAMA7G5 which is used by DVFS. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/1605800597-16720-7-git-send-email-claudiu.beznea@microchip.com +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/clk-sam9x60-pll.c | 145 +++++++++++++++++++++++++---- + drivers/clk/at91/pmc.h | 4 +- + drivers/clk/at91/sam9x60.c | 22 ++++- + drivers/clk/at91/sama7g5.c | 67 +++++++++---- + 4 files changed, 197 insertions(+), 41 deletions(-) + +diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c +index 5a9daa3643a7..1f52409475e9 100644 +--- a/drivers/clk/at91/clk-sam9x60-pll.c ++++ b/drivers/clk/at91/clk-sam9x60-pll.c +@@ -229,6 +229,57 @@ static int sam9x60_frac_pll_set_rate(struct clk_hw *hw, unsigned long rate, + return sam9x60_frac_pll_compute_mul_frac(core, rate, parent_rate, true); + } + ++static int sam9x60_frac_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate, ++ unsigned long parent_rate) ++{ ++ struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); ++ struct sam9x60_frac *frac = to_sam9x60_frac(core); ++ struct regmap *regmap = core->regmap; ++ unsigned long irqflags; ++ unsigned int val, cfrac, cmul; ++ long ret; ++ ++ ret = sam9x60_frac_pll_compute_mul_frac(core, rate, parent_rate, true); ++ if (ret <= 0) ++ return ret; ++ ++ spin_lock_irqsave(core->lock, irqflags); ++ ++ regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK, ++ core->id); ++ regmap_read(regmap, AT91_PMC_PLL_CTRL1, &val); ++ cmul = (val & core->layout->mul_mask) >> core->layout->mul_shift; ++ cfrac = (val & core->layout->frac_mask) >> core->layout->frac_shift; ++ ++ if (cmul == frac->mul && cfrac == frac->frac) ++ goto unlock; ++ ++ regmap_write(regmap, AT91_PMC_PLL_CTRL1, ++ (frac->mul << core->layout->mul_shift) | ++ (frac->frac << core->layout->frac_shift)); ++ ++ regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, ++ AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, ++ AT91_PMC_PLL_UPDT_UPDATE | core->id); ++ ++ regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, ++ AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL, ++ AT91_PMC_PLL_CTRL0_ENLOCK | ++ AT91_PMC_PLL_CTRL0_ENPLL); ++ ++ regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, ++ AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, ++ AT91_PMC_PLL_UPDT_UPDATE | core->id); ++ ++ while (!sam9x60_pll_ready(regmap, core->id)) ++ cpu_relax(); ++ ++unlock: ++ spin_unlock_irqrestore(core->lock, irqflags); ++ ++ return ret; ++} ++ + static const struct clk_ops sam9x60_frac_pll_ops = { + .prepare = sam9x60_frac_pll_prepare, + .unprepare = sam9x60_frac_pll_unprepare, +@@ -238,6 +289,15 @@ static const struct clk_ops sam9x60_frac_pll_ops = { + .set_rate = sam9x60_frac_pll_set_rate, + }; + ++static const struct clk_ops sam9x60_frac_pll_ops_chg = { ++ .prepare = sam9x60_frac_pll_prepare, ++ .unprepare = sam9x60_frac_pll_unprepare, ++ .is_prepared = sam9x60_frac_pll_is_prepared, ++ .recalc_rate = sam9x60_frac_pll_recalc_rate, ++ .round_rate = sam9x60_frac_pll_round_rate, ++ .set_rate = sam9x60_frac_pll_set_rate_chg, ++}; ++ + static int sam9x60_div_pll_prepare(struct clk_hw *hw) + { + struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); +@@ -384,6 +444,44 @@ static int sam9x60_div_pll_set_rate(struct clk_hw *hw, unsigned long rate, + return 0; + } + ++static int sam9x60_div_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate, ++ unsigned long parent_rate) ++{ ++ struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); ++ struct sam9x60_div *div = to_sam9x60_div(core); ++ struct regmap *regmap = core->regmap; ++ unsigned long irqflags; ++ unsigned int val, cdiv; ++ ++ div->div = DIV_ROUND_CLOSEST(parent_rate, rate) - 1; ++ ++ spin_lock_irqsave(core->lock, irqflags); ++ regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK, ++ core->id); ++ regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val); ++ cdiv = (val & core->layout->div_mask) >> core->layout->div_shift; ++ ++ /* Stop if nothing changed. */ ++ if (cdiv == div->div) ++ goto unlock; ++ ++ regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, ++ core->layout->div_mask, ++ (div->div << core->layout->div_shift)); ++ ++ regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, ++ AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, ++ AT91_PMC_PLL_UPDT_UPDATE | core->id); ++ ++ while (!sam9x60_pll_ready(regmap, core->id)) ++ cpu_relax(); ++ ++unlock: ++ spin_unlock_irqrestore(core->lock, irqflags); ++ ++ return 0; ++} ++ + static const struct clk_ops sam9x60_div_pll_ops = { + .prepare = sam9x60_div_pll_prepare, + .unprepare = sam9x60_div_pll_unprepare, +@@ -393,17 +491,26 @@ static const struct clk_ops sam9x60_div_pll_ops = { + .set_rate = sam9x60_div_pll_set_rate, + }; + ++static const struct clk_ops sam9x60_div_pll_ops_chg = { ++ .prepare = sam9x60_div_pll_prepare, ++ .unprepare = sam9x60_div_pll_unprepare, ++ .is_prepared = sam9x60_div_pll_is_prepared, ++ .recalc_rate = sam9x60_div_pll_recalc_rate, ++ .round_rate = sam9x60_div_pll_round_rate, ++ .set_rate = sam9x60_div_pll_set_rate_chg, ++}; ++ + struct clk_hw * __init + sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock, + const char *name, const char *parent_name, + struct clk_hw *parent_hw, u8 id, + const struct clk_pll_characteristics *characteristics, +- const struct clk_pll_layout *layout, bool critical) ++ const struct clk_pll_layout *layout, u32 flags) + { + struct sam9x60_frac *frac; + struct clk_hw *hw; + struct clk_init_data init; +- unsigned long parent_rate, flags; ++ unsigned long parent_rate, irqflags; + unsigned int val; + int ret; + +@@ -417,10 +524,12 @@ sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock, + init.name = name; + init.parent_names = &parent_name; + init.num_parents = 1; +- init.ops = &sam9x60_frac_pll_ops; +- init.flags = CLK_SET_RATE_GATE; +- if (critical) +- init.flags |= CLK_IS_CRITICAL; ++ if (flags & CLK_SET_RATE_GATE) ++ init.ops = &sam9x60_frac_pll_ops; ++ else ++ init.ops = &sam9x60_frac_pll_ops_chg; ++ ++ init.flags = flags; + + frac->core.id = id; + frac->core.hw.init = &init; +@@ -429,7 +538,7 @@ sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock, + frac->core.regmap = regmap; + frac->core.lock = lock; + +- spin_lock_irqsave(frac->core.lock, flags); ++ spin_lock_irqsave(frac->core.lock, irqflags); + if (sam9x60_pll_ready(regmap, id)) { + regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, + AT91_PMC_PLL_UPDT_ID_MSK, id); +@@ -457,7 +566,7 @@ sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock, + goto free; + } + } +- spin_unlock_irqrestore(frac->core.lock, flags); ++ spin_unlock_irqrestore(frac->core.lock, irqflags); + + hw = &frac->core.hw; + ret = clk_hw_register(NULL, hw); +@@ -469,7 +578,7 @@ sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock, + return hw; + + free: +- spin_unlock_irqrestore(frac->core.lock, flags); ++ spin_unlock_irqrestore(frac->core.lock, irqflags); + kfree(frac); + return hw; + } +@@ -478,12 +587,12 @@ struct clk_hw * __init + sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock, + const char *name, const char *parent_name, u8 id, + const struct clk_pll_characteristics *characteristics, +- const struct clk_pll_layout *layout, bool critical) ++ const struct clk_pll_layout *layout, u32 flags) + { + struct sam9x60_div *div; + struct clk_hw *hw; + struct clk_init_data init; +- unsigned long flags; ++ unsigned long irqflags; + unsigned int val; + int ret; + +@@ -497,11 +606,11 @@ sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock, + init.name = name; + init.parent_names = &parent_name; + init.num_parents = 1; +- init.ops = &sam9x60_div_pll_ops; +- init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | +- CLK_SET_RATE_PARENT; +- if (critical) +- init.flags |= CLK_IS_CRITICAL; ++ if (flags & CLK_SET_RATE_GATE) ++ init.ops = &sam9x60_div_pll_ops; ++ else ++ init.ops = &sam9x60_div_pll_ops_chg; ++ init.flags = flags; + + div->core.id = id; + div->core.hw.init = &init; +@@ -510,14 +619,14 @@ sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock, + div->core.regmap = regmap; + div->core.lock = lock; + +- spin_lock_irqsave(div->core.lock, flags); ++ spin_lock_irqsave(div->core.lock, irqflags); + + regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, + AT91_PMC_PLL_UPDT_ID_MSK, id); + regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val); + div->div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, val); + +- spin_unlock_irqrestore(div->core.lock, flags); ++ spin_unlock_irqrestore(div->core.lock, irqflags); + + hw = &div->core.hw; + ret = clk_hw_register(NULL, hw); +diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h +index 0a9364bde339..bedcd85ad750 100644 +--- a/drivers/clk/at91/pmc.h ++++ b/drivers/clk/at91/pmc.h +@@ -190,14 +190,14 @@ struct clk_hw * __init + sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock, + const char *name, const char *parent_name, u8 id, + const struct clk_pll_characteristics *characteristics, +- const struct clk_pll_layout *layout, bool critical); ++ const struct clk_pll_layout *layout, u32 flags); + + struct clk_hw * __init + sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock, + const char *name, const char *parent_name, + struct clk_hw *parent_hw, u8 id, + const struct clk_pll_characteristics *characteristics, +- const struct clk_pll_layout *layout, bool critical); ++ const struct clk_pll_layout *layout, u32 flags); + + struct clk_hw * __init + at91_clk_register_programmable(struct regmap *regmap, const char *name, +diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c +index c8cbec5308f0..4cb0d31babf7 100644 +--- a/drivers/clk/at91/sam9x60.c ++++ b/drivers/clk/at91/sam9x60.c +@@ -224,13 +224,24 @@ static void __init sam9x60_pmc_setup(struct device_node *np) + hw = sam9x60_clk_register_frac_pll(regmap, &pmc_pll_lock, "pllack_fracck", + "mainck", sam9x60_pmc->chws[PMC_MAIN], + 0, &plla_characteristics, +- &pll_frac_layout, true); ++ &pll_frac_layout, ++ /* ++ * This feeds pllack_divck which ++ * feeds CPU. It should not be ++ * disabled. ++ */ ++ CLK_IS_CRITICAL | CLK_SET_RATE_GATE); + if (IS_ERR(hw)) + goto err_free; + + hw = sam9x60_clk_register_div_pll(regmap, &pmc_pll_lock, "pllack_divck", + "pllack_fracck", 0, &plla_characteristics, +- &pll_div_layout, true); ++ &pll_div_layout, ++ /* ++ * This feeds CPU. It should not ++ * be disabled. ++ */ ++ CLK_IS_CRITICAL | CLK_SET_RATE_GATE); + if (IS_ERR(hw)) + goto err_free; + +@@ -239,13 +250,16 @@ static void __init sam9x60_pmc_setup(struct device_node *np) + hw = sam9x60_clk_register_frac_pll(regmap, &pmc_pll_lock, "upllck_fracck", + "main_osc", main_osc_hw, 1, + &upll_characteristics, +- &pll_frac_layout, false); ++ &pll_frac_layout, CLK_SET_RATE_GATE); + if (IS_ERR(hw)) + goto err_free; + + hw = sam9x60_clk_register_div_pll(regmap, &pmc_pll_lock, "upllck_divck", + "upllck_fracck", 1, &upll_characteristics, +- &pll_div_layout, false); ++ &pll_div_layout, ++ CLK_SET_RATE_GATE | ++ CLK_SET_PARENT_GATE | ++ CLK_SET_RATE_PARENT); + if (IS_ERR(hw)) + goto err_free; + +diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c +index d685e22b2014..d7c2b731ad20 100644 +--- a/drivers/clk/at91/sama7g5.c ++++ b/drivers/clk/at91/sama7g5.c +@@ -95,15 +95,15 @@ static const struct clk_pll_layout pll_layout_divio = { + * @p: clock parent + * @l: clock layout + * @t: clock type +- * @f: true if clock is critical and cannot be disabled ++ * @f: clock flags + * @eid: export index in sama7g5->chws[] array + */ + static const struct { + const char *n; + const char *p; + const struct clk_pll_layout *l; ++ unsigned long f; + u8 t; +- u8 c; + u8 eid; + } sama7g5_plls[][PLL_ID_MAX] = { + [PLL_ID_CPU] = { +@@ -111,13 +111,18 @@ static const struct { + .p = "mainck", + .l = &pll_layout_frac, + .t = PLL_TYPE_FRAC, +- .c = 1, }, ++ /* ++ * This feeds cpupll_divpmcck which feeds CPU. It should ++ * not be disabled. ++ */ ++ .f = CLK_IS_CRITICAL, }, + + { .n = "cpupll_divpmcck", + .p = "cpupll_fracck", + .l = &pll_layout_divpmc, + .t = PLL_TYPE_DIV, +- .c = 1, ++ /* This feeds CPU. It should not be disabled. */ ++ .f = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, + .eid = PMC_CPUPLL, }, + }, + +@@ -126,13 +131,22 @@ static const struct { + .p = "mainck", + .l = &pll_layout_frac, + .t = PLL_TYPE_FRAC, +- .c = 1, }, ++ /* ++ * This feeds syspll_divpmcck which may feed critial parts ++ * of the systems like timers. Therefore it should not be ++ * disabled. ++ */ ++ .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, }, + + { .n = "syspll_divpmcck", + .p = "syspll_fracck", + .l = &pll_layout_divpmc, + .t = PLL_TYPE_DIV, +- .c = 1, ++ /* ++ * This may feed critial parts of the systems like timers. ++ * Therefore it should not be disabled. ++ */ ++ .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, + .eid = PMC_SYSPLL, }, + }, + +@@ -141,55 +155,71 @@ static const struct { + .p = "mainck", + .l = &pll_layout_frac, + .t = PLL_TYPE_FRAC, +- .c = 1, }, ++ /* ++ * This feeds ddrpll_divpmcck which feeds DDR. It should not ++ * be disabled. ++ */ ++ .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, }, + + { .n = "ddrpll_divpmcck", + .p = "ddrpll_fracck", + .l = &pll_layout_divpmc, + .t = PLL_TYPE_DIV, +- .c = 1, }, ++ /* This feeds DDR. It should not be disabled. */ ++ .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, }, + }, + + [PLL_ID_IMG] = { + { .n = "imgpll_fracck", + .p = "mainck", + .l = &pll_layout_frac, +- .t = PLL_TYPE_FRAC, }, ++ .t = PLL_TYPE_FRAC, ++ .f = CLK_SET_RATE_GATE, }, + + { .n = "imgpll_divpmcck", + .p = "imgpll_fracck", + .l = &pll_layout_divpmc, +- .t = PLL_TYPE_DIV, }, ++ .t = PLL_TYPE_DIV, ++ .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | ++ CLK_SET_RATE_PARENT, }, + }, + + [PLL_ID_BAUD] = { + { .n = "baudpll_fracck", + .p = "mainck", + .l = &pll_layout_frac, +- .t = PLL_TYPE_FRAC, }, ++ .t = PLL_TYPE_FRAC, ++ .f = CLK_SET_RATE_GATE, }, + + { .n = "baudpll_divpmcck", + .p = "baudpll_fracck", + .l = &pll_layout_divpmc, +- .t = PLL_TYPE_DIV, }, ++ .t = PLL_TYPE_DIV, ++ .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | ++ CLK_SET_RATE_PARENT, }, + }, + + [PLL_ID_AUDIO] = { + { .n = "audiopll_fracck", + .p = "main_xtal", + .l = &pll_layout_frac, +- .t = PLL_TYPE_FRAC, }, ++ .t = PLL_TYPE_FRAC, ++ .f = CLK_SET_RATE_GATE, }, + + { .n = "audiopll_divpmcck", + .p = "audiopll_fracck", + .l = &pll_layout_divpmc, + .t = PLL_TYPE_DIV, ++ .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | ++ CLK_SET_RATE_PARENT, + .eid = PMC_AUDIOPMCPLL, }, + + { .n = "audiopll_diviock", + .p = "audiopll_fracck", + .l = &pll_layout_divio, + .t = PLL_TYPE_DIV, ++ .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | ++ CLK_SET_RATE_PARENT, + .eid = PMC_AUDIOIOPLL, }, + }, + +@@ -197,12 +227,15 @@ static const struct { + { .n = "ethpll_fracck", + .p = "main_xtal", + .l = &pll_layout_frac, +- .t = PLL_TYPE_FRAC, }, ++ .t = PLL_TYPE_FRAC, ++ .f = CLK_SET_RATE_GATE, }, + + { .n = "ethpll_divpmcck", + .p = "ethpll_fracck", + .l = &pll_layout_divpmc, +- .t = PLL_TYPE_DIV, }, ++ .t = PLL_TYPE_DIV, ++ .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | ++ CLK_SET_RATE_PARENT, }, + }, + }; + +@@ -890,7 +923,7 @@ static void __init sama7g5_pmc_setup(struct device_node *np) + sama7g5_plls[i][j].p, parent_hw, i, + &pll_characteristics, + sama7g5_plls[i][j].l, +- sama7g5_plls[i][j].c); ++ sama7g5_plls[i][j].f); + break; + + case PLL_TYPE_DIV: +@@ -899,7 +932,7 @@ static void __init sama7g5_pmc_setup(struct device_node *np) + sama7g5_plls[i][j].p, i, + &pll_characteristics, + sama7g5_plls[i][j].l, +- sama7g5_plls[i][j].c); ++ sama7g5_plls[i][j].f); + break; + + default: +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/107-clk-at91-sama7g5-remove-mck0-from-parent-list-of-oth.patch b/target/linux/at91/patches-5.10/107-clk-at91-sama7g5-remove-mck0-from-parent-list-of-oth.patch new file mode 100644 index 0000000000..20d6776a92 --- /dev/null +++ b/target/linux/at91/patches-5.10/107-clk-at91-sama7g5-remove-mck0-from-parent-list-of-oth.patch @@ -0,0 +1,201 @@ +From 7cfe2dfe5ac7c72b904e4b59b240caa42721ee07 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 19 Nov 2020 17:43:13 +0200 +Subject: [PATCH 107/247] clk: at91: sama7g5: remove mck0 from parent list of + other clocks + +MCK0 is changed at runtime by DVFS. Due to this, since not all IPs +are glitch free aware at MCK0 changes, remove MCK0 from parent list +of other clocks (e.g. generic clock, programmable/system clock, MCKX). + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/1605800597-16720-8-git-send-email-claudiu.beznea@microchip.com +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/sama7g5.c | 55 ++++++++++++++++++-------------------- + 1 file changed, 26 insertions(+), 29 deletions(-) + +diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c +index d7c2b731ad20..335e9c943c65 100644 +--- a/drivers/clk/at91/sama7g5.c ++++ b/drivers/clk/at91/sama7g5.c +@@ -280,7 +280,7 @@ static const struct { + .ep = { "syspll_divpmcck", "ddrpll_divpmcck", "imgpll_divpmcck", }, + .ep_mux_table = { 5, 6, 7, }, + .ep_count = 3, +- .ep_chg_id = 6, }, ++ .ep_chg_id = 5, }, + + { .n = "mck4", + .id = 4, +@@ -313,7 +313,7 @@ static const struct { + }; + + /* Mux table for programmable clocks. */ +-static u32 sama7g5_prog_mux_table[] = { 0, 1, 2, 3, 5, 6, 7, 8, 9, 10, }; ++static u32 sama7g5_prog_mux_table[] = { 0, 1, 2, 5, 6, 7, 8, 9, 10, }; + + /** + * Peripheral clock description +@@ -436,7 +436,7 @@ static const struct { + .pp = { "audiopll_divpmcck", }, + .pp_mux_table = { 9, }, + .pp_count = 1, +- .pp_chg_id = 4, }, ++ .pp_chg_id = 3, }, + + { .n = "csi_gclk", + .id = 33, +@@ -548,7 +548,7 @@ static const struct { + .pp = { "ethpll_divpmcck", }, + .pp_mux_table = { 10, }, + .pp_count = 1, +- .pp_chg_id = 4, }, ++ .pp_chg_id = 3, }, + + { .n = "gmac1_gclk", + .id = 52, +@@ -580,7 +580,7 @@ static const struct { + .pp = { "syspll_divpmcck", "audiopll_divpmcck", }, + .pp_mux_table = { 5, 9, }, + .pp_count = 2, +- .pp_chg_id = 5, }, ++ .pp_chg_id = 4, }, + + { .n = "i2smcc1_gclk", + .id = 58, +@@ -588,7 +588,7 @@ static const struct { + .pp = { "syspll_divpmcck", "audiopll_divpmcck", }, + .pp_mux_table = { 5, 9, }, + .pp_count = 2, +- .pp_chg_id = 5, }, ++ .pp_chg_id = 4, }, + + { .n = "mcan0_gclk", + .id = 61, +@@ -730,7 +730,7 @@ static const struct { + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, + .pp_mux_table = { 5, 8, }, + .pp_count = 2, +- .pp_chg_id = 5, }, ++ .pp_chg_id = 4, }, + + { .n = "sdmmc1_gclk", + .id = 81, +@@ -738,7 +738,7 @@ static const struct { + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, + .pp_mux_table = { 5, 8, }, + .pp_count = 2, +- .pp_chg_id = 5, }, ++ .pp_chg_id = 4, }, + + { .n = "sdmmc2_gclk", + .id = 82, +@@ -746,7 +746,7 @@ static const struct { + .pp = { "syspll_divpmcck", "baudpll_divpmcck", }, + .pp_mux_table = { 5, 8, }, + .pp_count = 2, +- .pp_chg_id = 5, }, ++ .pp_chg_id = 4, }, + + { .n = "spdifrx_gclk", + .id = 84, +@@ -754,7 +754,7 @@ static const struct { + .pp = { "syspll_divpmcck", "audiopll_divpmcck", }, + .pp_mux_table = { 5, 9, }, + .pp_count = 2, +- .pp_chg_id = 5, }, ++ .pp_chg_id = 4, }, + + { .n = "spdiftx_gclk", + .id = 85, +@@ -762,7 +762,7 @@ static const struct { + .pp = { "syspll_divpmcck", "audiopll_divpmcck", }, + .pp_mux_table = { 5, 9, }, + .pp_count = 2, +- .pp_chg_id = 5, }, ++ .pp_chg_id = 4, }, + + { .n = "tcb0_ch0_gclk", + .id = 88, +@@ -961,9 +961,8 @@ static void __init sama7g5_pmc_setup(struct device_node *np) + parent_names[0] = md_slck_name; + parent_names[1] = td_slck_name; + parent_names[2] = "mainck"; +- parent_names[3] = "mck0"; + for (i = 0; i < ARRAY_SIZE(sama7g5_mckx); i++) { +- u8 num_parents = 4 + sama7g5_mckx[i].ep_count; ++ u8 num_parents = 3 + sama7g5_mckx[i].ep_count; + u32 *mux_table; + + mux_table = kmalloc_array(num_parents, sizeof(*mux_table), +@@ -971,10 +970,10 @@ static void __init sama7g5_pmc_setup(struct device_node *np) + if (!mux_table) + goto err_free; + +- SAMA7G5_INIT_TABLE(mux_table, 4); +- SAMA7G5_FILL_TABLE(&mux_table[4], sama7g5_mckx[i].ep_mux_table, ++ SAMA7G5_INIT_TABLE(mux_table, 3); ++ SAMA7G5_FILL_TABLE(&mux_table[3], sama7g5_mckx[i].ep_mux_table, + sama7g5_mckx[i].ep_count); +- SAMA7G5_FILL_TABLE(&parent_names[4], sama7g5_mckx[i].ep, ++ SAMA7G5_FILL_TABLE(&parent_names[3], sama7g5_mckx[i].ep, + sama7g5_mckx[i].ep_count); + + hw = at91_clk_sama7g5_register_master(regmap, sama7g5_mckx[i].n, +@@ -997,20 +996,19 @@ static void __init sama7g5_pmc_setup(struct device_node *np) + parent_names[0] = md_slck_name; + parent_names[1] = td_slck_name; + parent_names[2] = "mainck"; +- parent_names[3] = "mck0"; +- parent_names[4] = "syspll_divpmcck"; +- parent_names[5] = "ddrpll_divpmcck"; +- parent_names[6] = "imgpll_divpmcck"; +- parent_names[7] = "baudpll_divpmcck"; +- parent_names[8] = "audiopll_divpmcck"; +- parent_names[9] = "ethpll_divpmcck"; ++ parent_names[3] = "syspll_divpmcck"; ++ parent_names[4] = "ddrpll_divpmcck"; ++ parent_names[5] = "imgpll_divpmcck"; ++ parent_names[6] = "baudpll_divpmcck"; ++ parent_names[7] = "audiopll_divpmcck"; ++ parent_names[8] = "ethpll_divpmcck"; + for (i = 0; i < 8; i++) { + char name[6]; + + snprintf(name, sizeof(name), "prog%d", i); + + hw = at91_clk_register_programmable(regmap, name, parent_names, +- 10, i, ++ 9, i, + &programmable_layout, + sama7g5_prog_mux_table); + if (IS_ERR(hw)) +@@ -1047,9 +1045,8 @@ static void __init sama7g5_pmc_setup(struct device_node *np) + parent_names[0] = md_slck_name; + parent_names[1] = td_slck_name; + parent_names[2] = "mainck"; +- parent_names[3] = "mck0"; + for (i = 0; i < ARRAY_SIZE(sama7g5_gck); i++) { +- u8 num_parents = 4 + sama7g5_gck[i].pp_count; ++ u8 num_parents = 3 + sama7g5_gck[i].pp_count; + u32 *mux_table; + + mux_table = kmalloc_array(num_parents, sizeof(*mux_table), +@@ -1057,10 +1054,10 @@ static void __init sama7g5_pmc_setup(struct device_node *np) + if (!mux_table) + goto err_free; + +- SAMA7G5_INIT_TABLE(mux_table, 4); +- SAMA7G5_FILL_TABLE(&mux_table[4], sama7g5_gck[i].pp_mux_table, ++ SAMA7G5_INIT_TABLE(mux_table, 3); ++ SAMA7G5_FILL_TABLE(&mux_table[3], sama7g5_gck[i].pp_mux_table, + sama7g5_gck[i].pp_count); +- SAMA7G5_FILL_TABLE(&parent_names[4], sama7g5_gck[i].pp, ++ SAMA7G5_FILL_TABLE(&parent_names[3], sama7g5_gck[i].pp, + sama7g5_gck[i].pp_count); + + hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/108-clk-at91-sama7g5-decrease-lower-limit-for-MCK0-rate.patch b/target/linux/at91/patches-5.10/108-clk-at91-sama7g5-decrease-lower-limit-for-MCK0-rate.patch new file mode 100644 index 0000000000..d812538c3e --- /dev/null +++ b/target/linux/at91/patches-5.10/108-clk-at91-sama7g5-decrease-lower-limit-for-MCK0-rate.patch @@ -0,0 +1,35 @@ +From 8b88f1e9918c173b24b43015cdb713cdde9e4d17 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 19 Nov 2020 17:43:14 +0200 +Subject: [PATCH 108/247] clk: at91: sama7g5: decrease lower limit for MCK0 + rate + +On SAMA7G5 CPU clock is changed at run-time by DVFS. Since MCK0 and +CPU clock shares the same parent clock (CPUPLL clock) the MCK0 is +also changed by DVFS to avoid over/under clocking of MCK0 consumers. +The lower limit is changed to be able to set MCK0 accordingly by +DVFS. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/1605800597-16720-9-git-send-email-claudiu.beznea@microchip.com +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/sama7g5.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c +index 335e9c943c65..29d9781e6712 100644 +--- a/drivers/clk/at91/sama7g5.c ++++ b/drivers/clk/at91/sama7g5.c +@@ -807,7 +807,7 @@ static const struct clk_pll_characteristics pll_characteristics = { + + /* MCK0 characteristics. */ + static const struct clk_master_characteristics mck0_characteristics = { +- .output = { .min = 140000000, .max = 200000000 }, ++ .output = { .min = 50000000, .max = 200000000 }, + .divisors = { 1, 2, 4, 3, 5 }, + .have_div3_pres = 1, + }; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/109-clk-at91-sama7g5-do-not-allow-cpu-pll-to-go-higher-t.patch b/target/linux/at91/patches-5.10/109-clk-at91-sama7g5-do-not-allow-cpu-pll-to-go-higher-t.patch new file mode 100644 index 0000000000..a30a489a8a --- /dev/null +++ b/target/linux/at91/patches-5.10/109-clk-at91-sama7g5-do-not-allow-cpu-pll-to-go-higher-t.patch @@ -0,0 +1,226 @@ +From 943ed75a2a5ab08582d3bc8025e8111903698763 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 19 Nov 2020 17:43:15 +0200 +Subject: [PATCH 109/247] clk: at91: sama7g5: do not allow cpu pll to go higher + than 1GHz + +Since CPU PLL feeds both CPU clock and MCK0, MCK0 cannot go higher +than 200MHz and MCK0 maximum prescaller is 5 limit the CPU PLL at +1GHz to avoid MCK0 overclocking while CPU PLL is changed by DVFS. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/1605800597-16720-10-git-send-email-claudiu.beznea@microchip.com +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/sama7g5.c | 61 +++++++++++++++++++++++++++++--------- + 1 file changed, 47 insertions(+), 14 deletions(-) + +diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c +index 29d9781e6712..e0c4d2eb9f59 100644 +--- a/drivers/clk/at91/sama7g5.c ++++ b/drivers/clk/at91/sama7g5.c +@@ -89,11 +89,40 @@ static const struct clk_pll_layout pll_layout_divio = { + .endiv_shift = 30, + }; + ++/* ++ * CPU PLL output range. ++ * Notice: The upper limit has been setup to 1000000002 due to hardware ++ * block which cannot output exactly 1GHz. ++ */ ++static const struct clk_range cpu_pll_outputs[] = { ++ { .min = 2343750, .max = 1000000002 }, ++}; ++ ++/* PLL output range. */ ++static const struct clk_range pll_outputs[] = { ++ { .min = 2343750, .max = 1200000000 }, ++}; ++ ++/* CPU PLL characteristics. */ ++static const struct clk_pll_characteristics cpu_pll_characteristics = { ++ .input = { .min = 12000000, .max = 50000000 }, ++ .num_output = ARRAY_SIZE(cpu_pll_outputs), ++ .output = cpu_pll_outputs, ++}; ++ ++/* PLL characteristics. */ ++static const struct clk_pll_characteristics pll_characteristics = { ++ .input = { .min = 12000000, .max = 50000000 }, ++ .num_output = ARRAY_SIZE(pll_outputs), ++ .output = pll_outputs, ++}; ++ + /** + * PLL clocks description + * @n: clock name + * @p: clock parent + * @l: clock layout ++ * @c: clock characteristics + * @t: clock type + * @f: clock flags + * @eid: export index in sama7g5->chws[] array +@@ -102,6 +131,7 @@ static const struct { + const char *n; + const char *p; + const struct clk_pll_layout *l; ++ const struct clk_pll_characteristics *c; + unsigned long f; + u8 t; + u8 eid; +@@ -110,6 +140,7 @@ static const struct { + { .n = "cpupll_fracck", + .p = "mainck", + .l = &pll_layout_frac, ++ .c = &cpu_pll_characteristics, + .t = PLL_TYPE_FRAC, + /* + * This feeds cpupll_divpmcck which feeds CPU. It should +@@ -120,6 +151,7 @@ static const struct { + { .n = "cpupll_divpmcck", + .p = "cpupll_fracck", + .l = &pll_layout_divpmc, ++ .c = &cpu_pll_characteristics, + .t = PLL_TYPE_DIV, + /* This feeds CPU. It should not be disabled. */ + .f = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, +@@ -130,6 +162,7 @@ static const struct { + { .n = "syspll_fracck", + .p = "mainck", + .l = &pll_layout_frac, ++ .c = &pll_characteristics, + .t = PLL_TYPE_FRAC, + /* + * This feeds syspll_divpmcck which may feed critial parts +@@ -141,6 +174,7 @@ static const struct { + { .n = "syspll_divpmcck", + .p = "syspll_fracck", + .l = &pll_layout_divpmc, ++ .c = &pll_characteristics, + .t = PLL_TYPE_DIV, + /* + * This may feed critial parts of the systems like timers. +@@ -154,6 +188,7 @@ static const struct { + { .n = "ddrpll_fracck", + .p = "mainck", + .l = &pll_layout_frac, ++ .c = &pll_characteristics, + .t = PLL_TYPE_FRAC, + /* + * This feeds ddrpll_divpmcck which feeds DDR. It should not +@@ -164,6 +199,7 @@ static const struct { + { .n = "ddrpll_divpmcck", + .p = "ddrpll_fracck", + .l = &pll_layout_divpmc, ++ .c = &pll_characteristics, + .t = PLL_TYPE_DIV, + /* This feeds DDR. It should not be disabled. */ + .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, }, +@@ -173,12 +209,14 @@ static const struct { + { .n = "imgpll_fracck", + .p = "mainck", + .l = &pll_layout_frac, ++ .c = &pll_characteristics, + .t = PLL_TYPE_FRAC, + .f = CLK_SET_RATE_GATE, }, + + { .n = "imgpll_divpmcck", + .p = "imgpll_fracck", + .l = &pll_layout_divpmc, ++ .c = &pll_characteristics, + .t = PLL_TYPE_DIV, + .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | + CLK_SET_RATE_PARENT, }, +@@ -188,12 +226,14 @@ static const struct { + { .n = "baudpll_fracck", + .p = "mainck", + .l = &pll_layout_frac, ++ .c = &pll_characteristics, + .t = PLL_TYPE_FRAC, + .f = CLK_SET_RATE_GATE, }, + + { .n = "baudpll_divpmcck", + .p = "baudpll_fracck", + .l = &pll_layout_divpmc, ++ .c = &pll_characteristics, + .t = PLL_TYPE_DIV, + .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | + CLK_SET_RATE_PARENT, }, +@@ -203,12 +243,14 @@ static const struct { + { .n = "audiopll_fracck", + .p = "main_xtal", + .l = &pll_layout_frac, ++ .c = &pll_characteristics, + .t = PLL_TYPE_FRAC, + .f = CLK_SET_RATE_GATE, }, + + { .n = "audiopll_divpmcck", + .p = "audiopll_fracck", + .l = &pll_layout_divpmc, ++ .c = &pll_characteristics, + .t = PLL_TYPE_DIV, + .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | + CLK_SET_RATE_PARENT, +@@ -217,6 +259,7 @@ static const struct { + { .n = "audiopll_diviock", + .p = "audiopll_fracck", + .l = &pll_layout_divio, ++ .c = &pll_characteristics, + .t = PLL_TYPE_DIV, + .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | + CLK_SET_RATE_PARENT, +@@ -227,12 +270,14 @@ static const struct { + { .n = "ethpll_fracck", + .p = "main_xtal", + .l = &pll_layout_frac, ++ .c = &pll_characteristics, + .t = PLL_TYPE_FRAC, + .f = CLK_SET_RATE_GATE, }, + + { .n = "ethpll_divpmcck", + .p = "ethpll_fracck", + .l = &pll_layout_divpmc, ++ .c = &pll_characteristics, + .t = PLL_TYPE_DIV, + .f = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE | + CLK_SET_RATE_PARENT, }, +@@ -793,18 +838,6 @@ static const struct { + .pp_chg_id = INT_MIN, }, + }; + +-/* PLL output range. */ +-static const struct clk_range pll_outputs[] = { +- { .min = 2343750, .max = 1200000000 }, +-}; +- +-/* PLL characteristics. */ +-static const struct clk_pll_characteristics pll_characteristics = { +- .input = { .min = 12000000, .max = 50000000 }, +- .num_output = ARRAY_SIZE(pll_outputs), +- .output = pll_outputs, +-}; +- + /* MCK0 characteristics. */ + static const struct clk_master_characteristics mck0_characteristics = { + .output = { .min = 50000000, .max = 200000000 }, +@@ -921,7 +954,7 @@ static void __init sama7g5_pmc_setup(struct device_node *np) + hw = sam9x60_clk_register_frac_pll(regmap, + &pmc_pll_lock, sama7g5_plls[i][j].n, + sama7g5_plls[i][j].p, parent_hw, i, +- &pll_characteristics, ++ sama7g5_plls[i][j].c, + sama7g5_plls[i][j].l, + sama7g5_plls[i][j].f); + break; +@@ -930,7 +963,7 @@ static void __init sama7g5_pmc_setup(struct device_node *np) + hw = sam9x60_clk_register_div_pll(regmap, + &pmc_pll_lock, sama7g5_plls[i][j].n, + sama7g5_plls[i][j].p, i, +- &pll_characteristics, ++ sama7g5_plls[i][j].c, + sama7g5_plls[i][j].l, + sama7g5_plls[i][j].f); + break; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/110-clk-at91-clk-master-re-factor-master-clock.patch b/target/linux/at91/patches-5.10/110-clk-at91-clk-master-re-factor-master-clock.patch new file mode 100644 index 0000000000..dc247654d2 --- /dev/null +++ b/target/linux/at91/patches-5.10/110-clk-at91-clk-master-re-factor-master-clock.patch @@ -0,0 +1,1261 @@ +From 9109b768fe65994547ef464b13e508b22de3e89b Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 19 Nov 2020 17:43:16 +0200 +Subject: [PATCH 110/247] clk: at91: clk-master: re-factor master clock + +Re-factor master clock driver by splitting it into 2 clocks: prescaller +and divider clocks. Based on registered clock flags the prescaler's rate +could be changed at runtime. This is necessary for platforms supporting +DVFS (e.g. SAMA7G5) where master clock could be changed at run-time. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/1605800597-16720-11-git-send-email-claudiu.beznea@microchip.com +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/at91rm9200.c | 21 ++- + drivers/clk/at91/at91sam9260.c | 26 ++- + drivers/clk/at91/at91sam9g45.c | 32 +++- + drivers/clk/at91/at91sam9n12.c | 36 ++-- + drivers/clk/at91/at91sam9rl.c | 23 ++- + drivers/clk/at91/at91sam9x5.c | 28 ++- + drivers/clk/at91/clk-master.c | 335 ++++++++++++++++++++++++++++----- + drivers/clk/at91/dt-compat.c | 15 +- + drivers/clk/at91/pmc.h | 16 +- + drivers/clk/at91/sam9x60.c | 23 ++- + drivers/clk/at91/sama5d2.c | 42 +++-- + drivers/clk/at91/sama5d3.c | 38 ++-- + drivers/clk/at91/sama5d4.c | 40 ++-- + drivers/clk/at91/sama7g5.c | 13 +- + 14 files changed, 542 insertions(+), 146 deletions(-) + +diff --git a/drivers/clk/at91/at91rm9200.c b/drivers/clk/at91/at91rm9200.c +index 2c3d8e6ca63c..0fad1009f315 100644 +--- a/drivers/clk/at91/at91rm9200.c ++++ b/drivers/clk/at91/at91rm9200.c +@@ -7,6 +7,8 @@ + + #include "pmc.h" + ++static DEFINE_SPINLOCK(rm9200_mck_lock); ++ + struct sck { + char *n; + char *p; +@@ -137,9 +139,20 @@ static void __init at91rm9200_pmc_setup(struct device_node *np) + parent_names[1] = "mainck"; + parent_names[2] = "pllack"; + parent_names[3] = "pllbck"; +- hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, +- &at91rm9200_master_layout, +- &rm9200_mck_characteristics); ++ hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4, ++ parent_names, ++ &at91rm9200_master_layout, ++ &rm9200_mck_characteristics, ++ &rm9200_mck_lock, CLK_SET_RATE_GATE, ++ INT_MIN); ++ if (IS_ERR(hw)) ++ goto err_free; ++ ++ hw = at91_clk_register_master_div(regmap, "masterck_div", ++ "masterck_pres", ++ &at91rm9200_master_layout, ++ &rm9200_mck_characteristics, ++ &rm9200_mck_lock, CLK_SET_RATE_GATE); + if (IS_ERR(hw)) + goto err_free; + +@@ -181,7 +194,7 @@ static void __init at91rm9200_pmc_setup(struct device_node *np) + for (i = 0; i < ARRAY_SIZE(at91rm9200_periphck); i++) { + hw = at91_clk_register_peripheral(regmap, + at91rm9200_periphck[i].n, +- "masterck", ++ "masterck_div", + at91rm9200_periphck[i].id); + if (IS_ERR(hw)) + goto err_free; +diff --git a/drivers/clk/at91/at91sam9260.c b/drivers/clk/at91/at91sam9260.c +index bb81ff731ad8..ceb5495f723a 100644 +--- a/drivers/clk/at91/at91sam9260.c ++++ b/drivers/clk/at91/at91sam9260.c +@@ -32,6 +32,8 @@ struct at91sam926x_data { + bool has_slck; + }; + ++static DEFINE_SPINLOCK(at91sam9260_mck_lock); ++ + static const struct clk_master_characteristics sam9260_mck_characteristics = { + .output = { .min = 0, .max = 105000000 }, + .divisors = { 1, 2, 4, 0 }, +@@ -218,8 +220,8 @@ static const struct sck at91sam9261_systemck[] = { + { .n = "pck1", .p = "prog1", .id = 9 }, + { .n = "pck2", .p = "prog2", .id = 10 }, + { .n = "pck3", .p = "prog3", .id = 11 }, +- { .n = "hclk0", .p = "masterck", .id = 16 }, +- { .n = "hclk1", .p = "masterck", .id = 17 }, ++ { .n = "hclk0", .p = "masterck_div", .id = 16 }, ++ { .n = "hclk1", .p = "masterck_div", .id = 17 }, + }; + + static const struct pck at91sam9261_periphck[] = { +@@ -413,9 +415,21 @@ static void __init at91sam926x_pmc_setup(struct device_node *np, + parent_names[1] = "mainck"; + parent_names[2] = "pllack"; + parent_names[3] = "pllbck"; +- hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, +- &at91rm9200_master_layout, +- data->mck_characteristics); ++ hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4, ++ parent_names, ++ &at91rm9200_master_layout, ++ data->mck_characteristics, ++ &at91sam9260_mck_lock, ++ CLK_SET_RATE_GATE, INT_MIN); ++ if (IS_ERR(hw)) ++ goto err_free; ++ ++ hw = at91_clk_register_master_div(regmap, "masterck_div", ++ "masterck_pres", ++ &at91rm9200_master_layout, ++ data->mck_characteristics, ++ &at91sam9260_mck_lock, ++ CLK_SET_RATE_GATE); + if (IS_ERR(hw)) + goto err_free; + +@@ -457,7 +471,7 @@ static void __init at91sam926x_pmc_setup(struct device_node *np, + for (i = 0; i < data->num_pck; i++) { + hw = at91_clk_register_peripheral(regmap, + data->pck[i].n, +- "masterck", ++ "masterck_div", + data->pck[i].id); + if (IS_ERR(hw)) + goto err_free; +diff --git a/drivers/clk/at91/at91sam9g45.c b/drivers/clk/at91/at91sam9g45.c +index cb4a406ed15d..0214333dedd3 100644 +--- a/drivers/clk/at91/at91sam9g45.c ++++ b/drivers/clk/at91/at91sam9g45.c +@@ -7,6 +7,8 @@ + + #include "pmc.h" + ++static DEFINE_SPINLOCK(at91sam9g45_mck_lock); ++ + static const struct clk_master_characteristics mck_characteristics = { + .output = { .min = 0, .max = 133333333 }, + .divisors = { 1, 2, 4, 3 }, +@@ -40,10 +42,10 @@ static const struct { + char *p; + u8 id; + } at91sam9g45_systemck[] = { +- { .n = "ddrck", .p = "masterck", .id = 2 }, +- { .n = "uhpck", .p = "usbck", .id = 6 }, +- { .n = "pck0", .p = "prog0", .id = 8 }, +- { .n = "pck1", .p = "prog1", .id = 9 }, ++ { .n = "ddrck", .p = "masterck_div", .id = 2 }, ++ { .n = "uhpck", .p = "usbck", .id = 6 }, ++ { .n = "pck0", .p = "prog0", .id = 8 }, ++ { .n = "pck1", .p = "prog1", .id = 9 }, + }; + + struct pck { +@@ -148,9 +150,21 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np) + parent_names[1] = "mainck"; + parent_names[2] = "plladivck"; + parent_names[3] = "utmick"; +- hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, +- &at91rm9200_master_layout, +- &mck_characteristics); ++ hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4, ++ parent_names, ++ &at91rm9200_master_layout, ++ &mck_characteristics, ++ &at91sam9g45_mck_lock, ++ CLK_SET_RATE_GATE, INT_MIN); ++ if (IS_ERR(hw)) ++ goto err_free; ++ ++ hw = at91_clk_register_master_div(regmap, "masterck_div", ++ "masterck_pres", ++ &at91rm9200_master_layout, ++ &mck_characteristics, ++ &at91sam9g45_mck_lock, ++ CLK_SET_RATE_GATE); + if (IS_ERR(hw)) + goto err_free; + +@@ -166,7 +180,7 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np) + parent_names[1] = "mainck"; + parent_names[2] = "plladivck"; + parent_names[3] = "utmick"; +- parent_names[4] = "masterck"; ++ parent_names[4] = "masterck_div"; + for (i = 0; i < 2; i++) { + char name[6]; + +@@ -195,7 +209,7 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np) + for (i = 0; i < ARRAY_SIZE(at91sam9g45_periphck); i++) { + hw = at91_clk_register_peripheral(regmap, + at91sam9g45_periphck[i].n, +- "masterck", ++ "masterck_div", + at91sam9g45_periphck[i].id); + if (IS_ERR(hw)) + goto err_free; +diff --git a/drivers/clk/at91/at91sam9n12.c b/drivers/clk/at91/at91sam9n12.c +index 93f7eb216122..f9db5316a7f1 100644 +--- a/drivers/clk/at91/at91sam9n12.c ++++ b/drivers/clk/at91/at91sam9n12.c +@@ -7,6 +7,8 @@ + + #include "pmc.h" + ++static DEFINE_SPINLOCK(at91sam9n12_mck_lock); ++ + static const struct clk_master_characteristics mck_characteristics = { + .output = { .min = 0, .max = 133333333 }, + .divisors = { 1, 2, 4, 3 }, +@@ -54,12 +56,12 @@ static const struct { + char *p; + u8 id; + } at91sam9n12_systemck[] = { +- { .n = "ddrck", .p = "masterck", .id = 2 }, +- { .n = "lcdck", .p = "masterck", .id = 3 }, +- { .n = "uhpck", .p = "usbck", .id = 6 }, +- { .n = "udpck", .p = "usbck", .id = 7 }, +- { .n = "pck0", .p = "prog0", .id = 8 }, +- { .n = "pck1", .p = "prog1", .id = 9 }, ++ { .n = "ddrck", .p = "masterck_div", .id = 2 }, ++ { .n = "lcdck", .p = "masterck_div", .id = 3 }, ++ { .n = "uhpck", .p = "usbck", .id = 6 }, ++ { .n = "udpck", .p = "usbck", .id = 7 }, ++ { .n = "pck0", .p = "prog0", .id = 8 }, ++ { .n = "pck1", .p = "prog1", .id = 9 }, + }; + + static const struct clk_pcr_layout at91sam9n12_pcr_layout = { +@@ -175,9 +177,21 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np) + parent_names[1] = "mainck"; + parent_names[2] = "plladivck"; + parent_names[3] = "pllbck"; +- hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, +- &at91sam9x5_master_layout, +- &mck_characteristics); ++ hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4, ++ parent_names, ++ &at91sam9x5_master_layout, ++ &mck_characteristics, ++ &at91sam9n12_mck_lock, ++ CLK_SET_RATE_GATE, INT_MIN); ++ if (IS_ERR(hw)) ++ goto err_free; ++ ++ hw = at91_clk_register_master_div(regmap, "masterck_div", ++ "masterck_pres", ++ &at91sam9x5_master_layout, ++ &mck_characteristics, ++ &at91sam9n12_mck_lock, ++ CLK_SET_RATE_GATE); + if (IS_ERR(hw)) + goto err_free; + +@@ -191,7 +205,7 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np) + parent_names[1] = "mainck"; + parent_names[2] = "plladivck"; + parent_names[3] = "pllbck"; +- parent_names[4] = "masterck"; ++ parent_names[4] = "masterck_div"; + for (i = 0; i < 2; i++) { + char name[6]; + +@@ -221,7 +235,7 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np) + hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, + &at91sam9n12_pcr_layout, + at91sam9n12_periphck[i].n, +- "masterck", ++ "masterck_div", + at91sam9n12_periphck[i].id, + &range, INT_MIN); + if (IS_ERR(hw)) +diff --git a/drivers/clk/at91/at91sam9rl.c b/drivers/clk/at91/at91sam9rl.c +index a343eb69bb35..66736e03cfef 100644 +--- a/drivers/clk/at91/at91sam9rl.c ++++ b/drivers/clk/at91/at91sam9rl.c +@@ -7,6 +7,8 @@ + + #include "pmc.h" + ++static DEFINE_SPINLOCK(sam9rl_mck_lock); ++ + static const struct clk_master_characteristics sam9rl_mck_characteristics = { + .output = { .min = 0, .max = 94000000 }, + .divisors = { 1, 2, 4, 0 }, +@@ -117,9 +119,20 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np) + parent_names[1] = "mainck"; + parent_names[2] = "pllack"; + parent_names[3] = "utmick"; +- hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, +- &at91rm9200_master_layout, +- &sam9rl_mck_characteristics); ++ hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4, ++ parent_names, ++ &at91rm9200_master_layout, ++ &sam9rl_mck_characteristics, ++ &sam9rl_mck_lock, CLK_SET_RATE_GATE, ++ INT_MIN); ++ if (IS_ERR(hw)) ++ goto err_free; ++ ++ hw = at91_clk_register_master_div(regmap, "masterck_div", ++ "masterck_pres", ++ &at91rm9200_master_layout, ++ &sam9rl_mck_characteristics, ++ &sam9rl_mck_lock, CLK_SET_RATE_GATE); + if (IS_ERR(hw)) + goto err_free; + +@@ -129,7 +142,7 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np) + parent_names[1] = "mainck"; + parent_names[2] = "pllack"; + parent_names[3] = "utmick"; +- parent_names[4] = "masterck"; ++ parent_names[4] = "masterck_div"; + for (i = 0; i < 2; i++) { + char name[6]; + +@@ -158,7 +171,7 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np) + for (i = 0; i < ARRAY_SIZE(at91sam9rl_periphck); i++) { + hw = at91_clk_register_peripheral(regmap, + at91sam9rl_periphck[i].n, +- "masterck", ++ "masterck_div", + at91sam9rl_periphck[i].id); + if (IS_ERR(hw)) + goto err_free; +diff --git a/drivers/clk/at91/at91sam9x5.c b/drivers/clk/at91/at91sam9x5.c +index 22b9aad9efb8..79b9d3667228 100644 +--- a/drivers/clk/at91/at91sam9x5.c ++++ b/drivers/clk/at91/at91sam9x5.c +@@ -7,6 +7,8 @@ + + #include "pmc.h" + ++static DEFINE_SPINLOCK(mck_lock); ++ + static const struct clk_master_characteristics mck_characteristics = { + .output = { .min = 0, .max = 133333333 }, + .divisors = { 1, 2, 4, 3 }, +@@ -41,7 +43,7 @@ static const struct { + char *p; + u8 id; + } at91sam9x5_systemck[] = { +- { .n = "ddrck", .p = "masterck", .id = 2 }, ++ { .n = "ddrck", .p = "masterck_div", .id = 2 }, + { .n = "smdck", .p = "smdclk", .id = 4 }, + { .n = "uhpck", .p = "usbck", .id = 6 }, + { .n = "udpck", .p = "usbck", .id = 7 }, +@@ -196,9 +198,19 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np, + parent_names[1] = "mainck"; + parent_names[2] = "plladivck"; + parent_names[3] = "utmick"; +- hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, +- &at91sam9x5_master_layout, +- &mck_characteristics); ++ hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4, ++ parent_names, ++ &at91sam9x5_master_layout, ++ &mck_characteristics, &mck_lock, ++ CLK_SET_RATE_GATE, INT_MIN); ++ if (IS_ERR(hw)) ++ goto err_free; ++ ++ hw = at91_clk_register_master_div(regmap, "masterck_div", ++ "masterck_pres", ++ &at91sam9x5_master_layout, ++ &mck_characteristics, &mck_lock, ++ CLK_SET_RATE_GATE); + if (IS_ERR(hw)) + goto err_free; + +@@ -218,7 +230,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np, + parent_names[1] = "mainck"; + parent_names[2] = "plladivck"; + parent_names[3] = "utmick"; +- parent_names[4] = "masterck"; ++ parent_names[4] = "masterck_div"; + for (i = 0; i < 2; i++) { + char name[6]; + +@@ -245,7 +257,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np, + } + + if (has_lcdck) { +- hw = at91_clk_register_system(regmap, "lcdck", "masterck", 3); ++ hw = at91_clk_register_system(regmap, "lcdck", "masterck_div", 3); + if (IS_ERR(hw)) + goto err_free; + +@@ -256,7 +268,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np, + hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, + &at91sam9x5_pcr_layout, + at91sam9x5_periphck[i].n, +- "masterck", ++ "masterck_div", + at91sam9x5_periphck[i].id, + &range, INT_MIN); + if (IS_ERR(hw)) +@@ -269,7 +281,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np, + hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, + &at91sam9x5_pcr_layout, + extra_pcks[i].n, +- "masterck", ++ "masterck_div", + extra_pcks[i].id, + &range, INT_MIN); + if (IS_ERR(hw)) +diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c +index aafd003b30cf..a80427980bf7 100644 +--- a/drivers/clk/at91/clk-master.c ++++ b/drivers/clk/at91/clk-master.c +@@ -58,83 +58,309 @@ static inline bool clk_master_ready(struct clk_master *master) + static int clk_master_prepare(struct clk_hw *hw) + { + struct clk_master *master = to_clk_master(hw); ++ unsigned long flags; ++ ++ spin_lock_irqsave(master->lock, flags); + + while (!clk_master_ready(master)) + cpu_relax(); + ++ spin_unlock_irqrestore(master->lock, flags); ++ + return 0; + } + + static int clk_master_is_prepared(struct clk_hw *hw) + { + struct clk_master *master = to_clk_master(hw); ++ unsigned long flags; ++ bool status; + +- return clk_master_ready(master); ++ spin_lock_irqsave(master->lock, flags); ++ status = clk_master_ready(master); ++ spin_unlock_irqrestore(master->lock, flags); ++ ++ return status; + } + +-static unsigned long clk_master_recalc_rate(struct clk_hw *hw, +- unsigned long parent_rate) ++static unsigned long clk_master_div_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) + { +- u8 pres; + u8 div; +- unsigned long rate = parent_rate; ++ unsigned long flags, rate = parent_rate; + struct clk_master *master = to_clk_master(hw); + const struct clk_master_layout *layout = master->layout; + const struct clk_master_characteristics *characteristics = + master->characteristics; + unsigned int mckr; + ++ spin_lock_irqsave(master->lock, flags); + regmap_read(master->regmap, master->layout->offset, &mckr); ++ spin_unlock_irqrestore(master->lock, flags); ++ + mckr &= layout->mask; + +- pres = (mckr >> layout->pres_shift) & MASTER_PRES_MASK; + div = (mckr >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; + +- if (characteristics->have_div3_pres && pres == MASTER_PRES_MAX) +- rate /= 3; +- else +- rate >>= pres; +- + rate /= characteristics->divisors[div]; + + if (rate < characteristics->output.min) +- pr_warn("master clk is underclocked"); ++ pr_warn("master clk div is underclocked"); + else if (rate > characteristics->output.max) +- pr_warn("master clk is overclocked"); ++ pr_warn("master clk div is overclocked"); + + return rate; + } + +-static u8 clk_master_get_parent(struct clk_hw *hw) ++static const struct clk_ops master_div_ops = { ++ .prepare = clk_master_prepare, ++ .is_prepared = clk_master_is_prepared, ++ .recalc_rate = clk_master_div_recalc_rate, ++}; ++ ++static int clk_master_div_set_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long parent_rate) ++{ ++ struct clk_master *master = to_clk_master(hw); ++ const struct clk_master_characteristics *characteristics = ++ master->characteristics; ++ unsigned long flags; ++ int div, i; ++ ++ div = DIV_ROUND_CLOSEST(parent_rate, rate); ++ if (div > ARRAY_SIZE(characteristics->divisors)) ++ return -EINVAL; ++ ++ for (i = 0; i < ARRAY_SIZE(characteristics->divisors); i++) { ++ if (!characteristics->divisors[i]) ++ break; ++ ++ if (div == characteristics->divisors[i]) { ++ div = i; ++ break; ++ } ++ } ++ ++ if (i == ARRAY_SIZE(characteristics->divisors)) ++ return -EINVAL; ++ ++ spin_lock_irqsave(master->lock, flags); ++ regmap_update_bits(master->regmap, master->layout->offset, ++ (MASTER_DIV_MASK << MASTER_DIV_SHIFT), ++ (div << MASTER_DIV_SHIFT)); ++ while (!clk_master_ready(master)) ++ cpu_relax(); ++ spin_unlock_irqrestore(master->lock, flags); ++ ++ return 0; ++} ++ ++static int clk_master_div_determine_rate(struct clk_hw *hw, ++ struct clk_rate_request *req) ++{ ++ struct clk_master *master = to_clk_master(hw); ++ const struct clk_master_characteristics *characteristics = ++ master->characteristics; ++ struct clk_hw *parent; ++ unsigned long parent_rate, tmp_rate, best_rate = 0; ++ int i, best_diff = INT_MIN, tmp_diff; ++ ++ parent = clk_hw_get_parent(hw); ++ if (!parent) ++ return -EINVAL; ++ ++ parent_rate = clk_hw_get_rate(parent); ++ if (!parent_rate) ++ return -EINVAL; ++ ++ for (i = 0; i < ARRAY_SIZE(characteristics->divisors); i++) { ++ if (!characteristics->divisors[i]) ++ break; ++ ++ tmp_rate = DIV_ROUND_CLOSEST_ULL(parent_rate, ++ characteristics->divisors[i]); ++ tmp_diff = abs(tmp_rate - req->rate); ++ ++ if (!best_rate || best_diff > tmp_diff) { ++ best_diff = tmp_diff; ++ best_rate = tmp_rate; ++ } ++ ++ if (!best_diff) ++ break; ++ } ++ ++ req->best_parent_rate = best_rate; ++ req->best_parent_hw = parent; ++ req->rate = best_rate; ++ ++ return 0; ++} ++ ++static const struct clk_ops master_div_ops_chg = { ++ .prepare = clk_master_prepare, ++ .is_prepared = clk_master_is_prepared, ++ .recalc_rate = clk_master_div_recalc_rate, ++ .determine_rate = clk_master_div_determine_rate, ++ .set_rate = clk_master_div_set_rate, ++}; ++ ++static void clk_sama7g5_master_best_diff(struct clk_rate_request *req, ++ struct clk_hw *parent, ++ unsigned long parent_rate, ++ long *best_rate, ++ long *best_diff, ++ u32 div) ++{ ++ unsigned long tmp_rate, tmp_diff; ++ ++ if (div == MASTER_PRES_MAX) ++ tmp_rate = parent_rate / 3; ++ else ++ tmp_rate = parent_rate >> div; ++ ++ tmp_diff = abs(req->rate - tmp_rate); ++ ++ if (*best_diff < 0 || *best_diff >= tmp_diff) { ++ *best_rate = tmp_rate; ++ *best_diff = tmp_diff; ++ req->best_parent_rate = parent_rate; ++ req->best_parent_hw = parent; ++ } ++} ++ ++static int clk_master_pres_determine_rate(struct clk_hw *hw, ++ struct clk_rate_request *req) + { + struct clk_master *master = to_clk_master(hw); ++ struct clk_rate_request req_parent = *req; ++ const struct clk_master_characteristics *characteristics = ++ master->characteristics; ++ struct clk_hw *parent; ++ long best_rate = LONG_MIN, best_diff = LONG_MIN; ++ u32 pres; ++ int i; ++ ++ if (master->chg_pid < 0) ++ return -EOPNOTSUPP; ++ ++ parent = clk_hw_get_parent_by_index(hw, master->chg_pid); ++ if (!parent) ++ return -EOPNOTSUPP; ++ ++ for (i = 0; i <= MASTER_PRES_MAX; i++) { ++ if (characteristics->have_div3_pres && i == MASTER_PRES_MAX) ++ pres = 3; ++ else ++ pres = 1 << i; ++ ++ req_parent.rate = req->rate * pres; ++ if (__clk_determine_rate(parent, &req_parent)) ++ continue; ++ ++ clk_sama7g5_master_best_diff(req, parent, req_parent.rate, ++ &best_diff, &best_rate, pres); ++ if (!best_diff) ++ break; ++ } ++ ++ return 0; ++} ++ ++static int clk_master_pres_set_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long parent_rate) ++{ ++ struct clk_master *master = to_clk_master(hw); ++ unsigned long flags; ++ unsigned int pres; ++ ++ pres = DIV_ROUND_CLOSEST(parent_rate, rate); ++ if (pres > MASTER_PRES_MAX) ++ return -EINVAL; ++ ++ else if (pres == 3) ++ pres = MASTER_PRES_MAX; ++ else ++ pres = ffs(pres) - 1; ++ ++ spin_lock_irqsave(master->lock, flags); ++ regmap_update_bits(master->regmap, master->layout->offset, ++ (MASTER_PRES_MASK << master->layout->pres_shift), ++ (pres << master->layout->pres_shift)); ++ ++ while (!clk_master_ready(master)) ++ cpu_relax(); ++ spin_unlock_irqrestore(master->lock, flags); ++ ++ return 0; ++} ++ ++static unsigned long clk_master_pres_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ struct clk_master *master = to_clk_master(hw); ++ const struct clk_master_characteristics *characteristics = ++ master->characteristics; ++ unsigned long flags; ++ unsigned int val, pres; ++ ++ spin_lock_irqsave(master->lock, flags); ++ regmap_read(master->regmap, master->layout->offset, &val); ++ spin_unlock_irqrestore(master->lock, flags); ++ ++ pres = (val >> master->layout->pres_shift) & MASTER_PRES_MASK; ++ if (pres == 3 && characteristics->have_div3_pres) ++ pres = 3; ++ else ++ pres = (1 << pres); ++ ++ return DIV_ROUND_CLOSEST_ULL(parent_rate, pres); ++} ++ ++static u8 clk_master_pres_get_parent(struct clk_hw *hw) ++{ ++ struct clk_master *master = to_clk_master(hw); ++ unsigned long flags; + unsigned int mckr; + ++ spin_lock_irqsave(master->lock, flags); + regmap_read(master->regmap, master->layout->offset, &mckr); ++ spin_unlock_irqrestore(master->lock, flags); + + return mckr & AT91_PMC_CSS; + } + +-static const struct clk_ops master_ops = { ++static const struct clk_ops master_pres_ops = { + .prepare = clk_master_prepare, + .is_prepared = clk_master_is_prepared, +- .recalc_rate = clk_master_recalc_rate, +- .get_parent = clk_master_get_parent, ++ .recalc_rate = clk_master_pres_recalc_rate, ++ .get_parent = clk_master_pres_get_parent, + }; + +-struct clk_hw * __init +-at91_clk_register_master(struct regmap *regmap, ++static const struct clk_ops master_pres_ops_chg = { ++ .prepare = clk_master_prepare, ++ .is_prepared = clk_master_is_prepared, ++ .determine_rate = clk_master_pres_determine_rate, ++ .recalc_rate = clk_master_pres_recalc_rate, ++ .get_parent = clk_master_pres_get_parent, ++ .set_rate = clk_master_pres_set_rate, ++}; ++ ++static struct clk_hw * __init ++at91_clk_register_master_internal(struct regmap *regmap, + const char *name, int num_parents, + const char **parent_names, + const struct clk_master_layout *layout, +- const struct clk_master_characteristics *characteristics) ++ const struct clk_master_characteristics *characteristics, ++ const struct clk_ops *ops, spinlock_t *lock, u32 flags, ++ int chg_pid) + { + struct clk_master *master; + struct clk_init_data init; + struct clk_hw *hw; + int ret; + +- if (!name || !num_parents || !parent_names) ++ if (!name || !num_parents || !parent_names || !lock) + return ERR_PTR(-EINVAL); + + master = kzalloc(sizeof(*master), GFP_KERNEL); +@@ -142,15 +368,17 @@ at91_clk_register_master(struct regmap *regmap, + return ERR_PTR(-ENOMEM); + + init.name = name; +- init.ops = &master_ops; ++ init.ops = ops; + init.parent_names = parent_names; + init.num_parents = num_parents; +- init.flags = 0; ++ init.flags = flags; + + master->hw.init = &init; + master->layout = layout; + master->characteristics = characteristics; + master->regmap = regmap; ++ master->chg_pid = chg_pid; ++ master->lock = lock; + + hw = &master->hw; + ret = clk_hw_register(NULL, &master->hw); +@@ -162,37 +390,54 @@ at91_clk_register_master(struct regmap *regmap, + return hw; + } + +-static unsigned long +-clk_sama7g5_master_recalc_rate(struct clk_hw *hw, +- unsigned long parent_rate) ++struct clk_hw * __init ++at91_clk_register_master_pres(struct regmap *regmap, ++ const char *name, int num_parents, ++ const char **parent_names, ++ const struct clk_master_layout *layout, ++ const struct clk_master_characteristics *characteristics, ++ spinlock_t *lock, u32 flags, int chg_pid) + { +- struct clk_master *master = to_clk_master(hw); ++ const struct clk_ops *ops; + +- return DIV_ROUND_CLOSEST_ULL(parent_rate, (1 << master->div)); ++ if (flags & CLK_SET_RATE_GATE) ++ ops = &master_pres_ops; ++ else ++ ops = &master_pres_ops_chg; ++ ++ return at91_clk_register_master_internal(regmap, name, num_parents, ++ parent_names, layout, ++ characteristics, ops, ++ lock, flags, chg_pid); + } + +-static void clk_sama7g5_master_best_diff(struct clk_rate_request *req, +- struct clk_hw *parent, +- unsigned long parent_rate, +- long *best_rate, +- long *best_diff, +- u32 div) ++struct clk_hw * __init ++at91_clk_register_master_div(struct regmap *regmap, ++ const char *name, const char *parent_name, ++ const struct clk_master_layout *layout, ++ const struct clk_master_characteristics *characteristics, ++ spinlock_t *lock, u32 flags) + { +- unsigned long tmp_rate, tmp_diff; ++ const struct clk_ops *ops; + +- if (div == MASTER_PRES_MAX) +- tmp_rate = parent_rate / 3; ++ if (flags & CLK_SET_RATE_GATE) ++ ops = &master_div_ops; + else +- tmp_rate = parent_rate >> div; ++ ops = &master_div_ops_chg; + +- tmp_diff = abs(req->rate - tmp_rate); ++ return at91_clk_register_master_internal(regmap, name, 1, ++ &parent_name, layout, ++ characteristics, ops, ++ lock, flags, -EINVAL); ++} + +- if (*best_diff < 0 || *best_diff >= tmp_diff) { +- *best_rate = tmp_rate; +- *best_diff = tmp_diff; +- req->best_parent_rate = parent_rate; +- req->best_parent_hw = parent; +- } ++static unsigned long ++clk_sama7g5_master_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ struct clk_master *master = to_clk_master(hw); ++ ++ return DIV_ROUND_CLOSEST_ULL(parent_rate, (1 << master->div)); + } + + static int clk_sama7g5_master_determine_rate(struct clk_hw *hw, +diff --git a/drivers/clk/at91/dt-compat.c b/drivers/clk/at91/dt-compat.c +index a50084de97d4..a97b99c2dc12 100644 +--- a/drivers/clk/at91/dt-compat.c ++++ b/drivers/clk/at91/dt-compat.c +@@ -24,6 +24,8 @@ + + #define GCK_INDEX_DT_AUDIO_PLL 5 + ++static DEFINE_SPINLOCK(mck_lock); ++ + #ifdef CONFIG_HAVE_AT91_AUDIO_PLL + static void __init of_sama5d2_clk_audio_pll_frac_setup(struct device_node *np) + { +@@ -388,9 +390,16 @@ of_at91_clk_master_setup(struct device_node *np, + if (IS_ERR(regmap)) + return; + +- hw = at91_clk_register_master(regmap, name, num_parents, +- parent_names, layout, +- characteristics); ++ hw = at91_clk_register_master_pres(regmap, "masterck_pres", num_parents, ++ parent_names, layout, ++ characteristics, &mck_lock, ++ CLK_SET_RATE_GATE, INT_MIN); ++ if (IS_ERR(hw)) ++ goto out_free_characteristics; ++ ++ hw = at91_clk_register_master_div(regmap, name, "masterck_pres", ++ layout, characteristics, ++ &mck_lock, CLK_SET_RATE_GATE); + if (IS_ERR(hw)) + goto out_free_characteristics; + +diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h +index bedcd85ad750..a49076c804a9 100644 +--- a/drivers/clk/at91/pmc.h ++++ b/drivers/clk/at91/pmc.h +@@ -155,10 +155,18 @@ at91_clk_register_sam9x5_main(struct regmap *regmap, const char *name, + const char **parent_names, int num_parents); + + struct clk_hw * __init +-at91_clk_register_master(struct regmap *regmap, const char *name, +- int num_parents, const char **parent_names, +- const struct clk_master_layout *layout, +- const struct clk_master_characteristics *characteristics); ++at91_clk_register_master_pres(struct regmap *regmap, const char *name, ++ int num_parents, const char **parent_names, ++ const struct clk_master_layout *layout, ++ const struct clk_master_characteristics *characteristics, ++ spinlock_t *lock, u32 flags, int chg_pid); ++ ++struct clk_hw * __init ++at91_clk_register_master_div(struct regmap *regmap, const char *name, ++ const char *parent_names, ++ const struct clk_master_layout *layout, ++ const struct clk_master_characteristics *characteristics, ++ spinlock_t *lock, u32 flags); + + struct clk_hw * __init + at91_clk_sama7g5_register_master(struct regmap *regmap, +diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c +index 4cb0d31babf7..5f6fa89571b7 100644 +--- a/drivers/clk/at91/sam9x60.c ++++ b/drivers/clk/at91/sam9x60.c +@@ -8,6 +8,7 @@ + #include "pmc.h" + + static DEFINE_SPINLOCK(pmc_pll_lock); ++static DEFINE_SPINLOCK(mck_lock); + + static const struct clk_master_characteristics mck_characteristics = { + .output = { .min = 140000000, .max = 200000000 }, +@@ -76,11 +77,11 @@ static const struct { + char *p; + u8 id; + } sam9x60_systemck[] = { +- { .n = "ddrck", .p = "masterck", .id = 2 }, ++ { .n = "ddrck", .p = "masterck_div", .id = 2 }, + { .n = "uhpck", .p = "usbck", .id = 6 }, + { .n = "pck0", .p = "prog0", .id = 8 }, + { .n = "pck1", .p = "prog1", .id = 9 }, +- { .n = "qspick", .p = "masterck", .id = 19 }, ++ { .n = "qspick", .p = "masterck_div", .id = 19 }, + }; + + static const struct { +@@ -268,9 +269,17 @@ static void __init sam9x60_pmc_setup(struct device_node *np) + parent_names[0] = md_slck_name; + parent_names[1] = "mainck"; + parent_names[2] = "pllack_divck"; +- hw = at91_clk_register_master(regmap, "masterck", 3, parent_names, +- &sam9x60_master_layout, +- &mck_characteristics); ++ hw = at91_clk_register_master_pres(regmap, "masterck_pres", 3, ++ parent_names, &sam9x60_master_layout, ++ &mck_characteristics, &mck_lock, ++ CLK_SET_RATE_GATE, INT_MIN); ++ if (IS_ERR(hw)) ++ goto err_free; ++ ++ hw = at91_clk_register_master_div(regmap, "masterck_div", ++ "masterck_pres", &sam9x60_master_layout, ++ &mck_characteristics, &mck_lock, ++ CLK_SET_RATE_GATE); + if (IS_ERR(hw)) + goto err_free; + +@@ -286,7 +295,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np) + parent_names[0] = md_slck_name; + parent_names[1] = td_slck_name; + parent_names[2] = "mainck"; +- parent_names[3] = "masterck"; ++ parent_names[3] = "masterck_div"; + parent_names[4] = "pllack_divck"; + parent_names[5] = "upllck_divck"; + for (i = 0; i < 2; i++) { +@@ -318,7 +327,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np) + hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, + &sam9x60_pcr_layout, + sam9x60_periphck[i].n, +- "masterck", ++ "masterck_div", + sam9x60_periphck[i].id, + &range, INT_MIN); + if (IS_ERR(hw)) +diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c +index 8b220762941a..9a5cbc7cd55a 100644 +--- a/drivers/clk/at91/sama5d2.c ++++ b/drivers/clk/at91/sama5d2.c +@@ -7,6 +7,8 @@ + + #include "pmc.h" + ++static DEFINE_SPINLOCK(mck_lock); ++ + static const struct clk_master_characteristics mck_characteristics = { + .output = { .min = 124000000, .max = 166000000 }, + .divisors = { 1, 2, 4, 3 }, +@@ -40,14 +42,14 @@ static const struct { + char *p; + u8 id; + } sama5d2_systemck[] = { +- { .n = "ddrck", .p = "masterck", .id = 2 }, +- { .n = "lcdck", .p = "masterck", .id = 3 }, +- { .n = "uhpck", .p = "usbck", .id = 6 }, +- { .n = "udpck", .p = "usbck", .id = 7 }, +- { .n = "pck0", .p = "prog0", .id = 8 }, +- { .n = "pck1", .p = "prog1", .id = 9 }, +- { .n = "pck2", .p = "prog2", .id = 10 }, +- { .n = "iscck", .p = "masterck", .id = 18 }, ++ { .n = "ddrck", .p = "masterck_div", .id = 2 }, ++ { .n = "lcdck", .p = "masterck_div", .id = 3 }, ++ { .n = "uhpck", .p = "usbck", .id = 6 }, ++ { .n = "udpck", .p = "usbck", .id = 7 }, ++ { .n = "pck0", .p = "prog0", .id = 8 }, ++ { .n = "pck1", .p = "prog1", .id = 9 }, ++ { .n = "pck2", .p = "prog2", .id = 10 }, ++ { .n = "iscck", .p = "masterck_div", .id = 18 }, + }; + + static const struct { +@@ -235,15 +237,25 @@ static void __init sama5d2_pmc_setup(struct device_node *np) + parent_names[1] = "mainck"; + parent_names[2] = "plladivck"; + parent_names[3] = "utmick"; +- hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, +- &at91sam9x5_master_layout, +- &mck_characteristics); ++ hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4, ++ parent_names, ++ &at91sam9x5_master_layout, ++ &mck_characteristics, &mck_lock, ++ CLK_SET_RATE_GATE, INT_MIN); ++ if (IS_ERR(hw)) ++ goto err_free; ++ ++ hw = at91_clk_register_master_div(regmap, "masterck_div", ++ "masterck_pres", ++ &at91sam9x5_master_layout, ++ &mck_characteristics, &mck_lock, ++ CLK_SET_RATE_GATE); + if (IS_ERR(hw)) + goto err_free; + + sama5d2_pmc->chws[PMC_MCK] = hw; + +- hw = at91_clk_register_h32mx(regmap, "h32mxck", "masterck"); ++ hw = at91_clk_register_h32mx(regmap, "h32mxck", "masterck_div"); + if (IS_ERR(hw)) + goto err_free; + +@@ -259,7 +271,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np) + parent_names[1] = "mainck"; + parent_names[2] = "plladivck"; + parent_names[3] = "utmick"; +- parent_names[4] = "masterck"; ++ parent_names[4] = "masterck_div"; + parent_names[5] = "audiopll_pmcck"; + for (i = 0; i < 3; i++) { + char name[6]; +@@ -290,7 +302,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np) + hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, + &sama5d2_pcr_layout, + sama5d2_periphck[i].n, +- "masterck", ++ "masterck_div", + sama5d2_periphck[i].id, + &range, INT_MIN); + if (IS_ERR(hw)) +@@ -317,7 +329,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np) + parent_names[1] = "mainck"; + parent_names[2] = "plladivck"; + parent_names[3] = "utmick"; +- parent_names[4] = "masterck"; ++ parent_names[4] = "masterck_div"; + parent_names[5] = "audiopll_pmcck"; + for (i = 0; i < ARRAY_SIZE(sama5d2_gck); i++) { + hw = at91_clk_register_generated(regmap, &pmc_pcr_lock, +diff --git a/drivers/clk/at91/sama5d3.c b/drivers/clk/at91/sama5d3.c +index 7c6e0a5b9dc8..87009ee8effc 100644 +--- a/drivers/clk/at91/sama5d3.c ++++ b/drivers/clk/at91/sama5d3.c +@@ -7,6 +7,8 @@ + + #include "pmc.h" + ++static DEFINE_SPINLOCK(mck_lock); ++ + static const struct clk_master_characteristics mck_characteristics = { + .output = { .min = 0, .max = 166000000 }, + .divisors = { 1, 2, 4, 3 }, +@@ -40,14 +42,14 @@ static const struct { + char *p; + u8 id; + } sama5d3_systemck[] = { +- { .n = "ddrck", .p = "masterck", .id = 2 }, +- { .n = "lcdck", .p = "masterck", .id = 3 }, +- { .n = "smdck", .p = "smdclk", .id = 4 }, +- { .n = "uhpck", .p = "usbck", .id = 6 }, +- { .n = "udpck", .p = "usbck", .id = 7 }, +- { .n = "pck0", .p = "prog0", .id = 8 }, +- { .n = "pck1", .p = "prog1", .id = 9 }, +- { .n = "pck2", .p = "prog2", .id = 10 }, ++ { .n = "ddrck", .p = "masterck_div", .id = 2 }, ++ { .n = "lcdck", .p = "masterck_div", .id = 3 }, ++ { .n = "smdck", .p = "smdclk", .id = 4 }, ++ { .n = "uhpck", .p = "usbck", .id = 6 }, ++ { .n = "udpck", .p = "usbck", .id = 7 }, ++ { .n = "pck0", .p = "prog0", .id = 8 }, ++ { .n = "pck1", .p = "prog1", .id = 9 }, ++ { .n = "pck2", .p = "prog2", .id = 10 }, + }; + + static const struct { +@@ -170,9 +172,19 @@ static void __init sama5d3_pmc_setup(struct device_node *np) + parent_names[1] = "mainck"; + parent_names[2] = "plladivck"; + parent_names[3] = "utmick"; +- hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, +- &at91sam9x5_master_layout, +- &mck_characteristics); ++ hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4, ++ parent_names, ++ &at91sam9x5_master_layout, ++ &mck_characteristics, &mck_lock, ++ CLK_SET_RATE_GATE, INT_MIN); ++ if (IS_ERR(hw)) ++ goto err_free; ++ ++ hw = at91_clk_register_master_div(regmap, "masterck_div", ++ "masterck_pres", ++ &at91sam9x5_master_layout, ++ &mck_characteristics, &mck_lock, ++ CLK_SET_RATE_GATE); + if (IS_ERR(hw)) + goto err_free; + +@@ -192,7 +204,7 @@ static void __init sama5d3_pmc_setup(struct device_node *np) + parent_names[1] = "mainck"; + parent_names[2] = "plladivck"; + parent_names[3] = "utmick"; +- parent_names[4] = "masterck"; ++ parent_names[4] = "masterck_div"; + for (i = 0; i < 3; i++) { + char name[6]; + +@@ -222,7 +234,7 @@ static void __init sama5d3_pmc_setup(struct device_node *np) + hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, + &sama5d3_pcr_layout, + sama5d3_periphck[i].n, +- "masterck", ++ "masterck_div", + sama5d3_periphck[i].id, + &sama5d3_periphck[i].r, + INT_MIN); +diff --git a/drivers/clk/at91/sama5d4.c b/drivers/clk/at91/sama5d4.c +index 92d8d4141b43..57fff790188b 100644 +--- a/drivers/clk/at91/sama5d4.c ++++ b/drivers/clk/at91/sama5d4.c +@@ -7,6 +7,8 @@ + + #include "pmc.h" + ++static DEFINE_SPINLOCK(mck_lock); ++ + static const struct clk_master_characteristics mck_characteristics = { + .output = { .min = 125000000, .max = 200000000 }, + .divisors = { 1, 2, 4, 3 }, +@@ -39,14 +41,14 @@ static const struct { + char *p; + u8 id; + } sama5d4_systemck[] = { +- { .n = "ddrck", .p = "masterck", .id = 2 }, +- { .n = "lcdck", .p = "masterck", .id = 3 }, +- { .n = "smdck", .p = "smdclk", .id = 4 }, +- { .n = "uhpck", .p = "usbck", .id = 6 }, +- { .n = "udpck", .p = "usbck", .id = 7 }, +- { .n = "pck0", .p = "prog0", .id = 8 }, +- { .n = "pck1", .p = "prog1", .id = 9 }, +- { .n = "pck2", .p = "prog2", .id = 10 }, ++ { .n = "ddrck", .p = "masterck_div", .id = 2 }, ++ { .n = "lcdck", .p = "masterck_div", .id = 3 }, ++ { .n = "smdck", .p = "smdclk", .id = 4 }, ++ { .n = "uhpck", .p = "usbck", .id = 6 }, ++ { .n = "udpck", .p = "usbck", .id = 7 }, ++ { .n = "pck0", .p = "prog0", .id = 8 }, ++ { .n = "pck1", .p = "prog1", .id = 9 }, ++ { .n = "pck2", .p = "prog2", .id = 10 }, + }; + + static const struct { +@@ -185,15 +187,25 @@ static void __init sama5d4_pmc_setup(struct device_node *np) + parent_names[1] = "mainck"; + parent_names[2] = "plladivck"; + parent_names[3] = "utmick"; +- hw = at91_clk_register_master(regmap, "masterck", 4, parent_names, +- &at91sam9x5_master_layout, +- &mck_characteristics); ++ hw = at91_clk_register_master_pres(regmap, "masterck_pres", 4, ++ parent_names, ++ &at91sam9x5_master_layout, ++ &mck_characteristics, &mck_lock, ++ CLK_SET_RATE_GATE, INT_MIN); ++ if (IS_ERR(hw)) ++ goto err_free; ++ ++ hw = at91_clk_register_master_div(regmap, "masterck_div", ++ "masterck_pres", ++ &at91sam9x5_master_layout, ++ &mck_characteristics, &mck_lock, ++ CLK_SET_RATE_GATE); + if (IS_ERR(hw)) + goto err_free; + + sama5d4_pmc->chws[PMC_MCK] = hw; + +- hw = at91_clk_register_h32mx(regmap, "h32mxck", "masterck"); ++ hw = at91_clk_register_h32mx(regmap, "h32mxck", "masterck_div"); + if (IS_ERR(hw)) + goto err_free; + +@@ -215,7 +227,7 @@ static void __init sama5d4_pmc_setup(struct device_node *np) + parent_names[1] = "mainck"; + parent_names[2] = "plladivck"; + parent_names[3] = "utmick"; +- parent_names[4] = "masterck"; ++ parent_names[4] = "masterck_div"; + for (i = 0; i < 3; i++) { + char name[6]; + +@@ -245,7 +257,7 @@ static void __init sama5d4_pmc_setup(struct device_node *np) + hw = at91_clk_register_sam9x5_peripheral(regmap, &pmc_pcr_lock, + &sama5d4_pcr_layout, + sama5d4_periphck[i].n, +- "masterck", ++ "masterck_div", + sama5d4_periphck[i].id, + &range, INT_MIN); + if (IS_ERR(hw)) +diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c +index e0c4d2eb9f59..927eb3b2b126 100644 +--- a/drivers/clk/at91/sama7g5.c ++++ b/drivers/clk/at91/sama7g5.c +@@ -32,6 +32,7 @@ + } while (0) + + static DEFINE_SPINLOCK(pmc_pll_lock); ++static DEFINE_SPINLOCK(pmc_mck0_lock); + static DEFINE_SPINLOCK(pmc_mckX_lock); + + /** +@@ -984,8 +985,16 @@ static void __init sama7g5_pmc_setup(struct device_node *np) + parent_names[1] = "mainck"; + parent_names[2] = "cpupll_divpmcck"; + parent_names[3] = "syspll_divpmcck"; +- hw = at91_clk_register_master(regmap, "mck0", 4, parent_names, +- &mck0_layout, &mck0_characteristics); ++ hw = at91_clk_register_master_pres(regmap, "mck0_pres", 4, parent_names, ++ &mck0_layout, &mck0_characteristics, ++ &pmc_mck0_lock, ++ CLK_SET_RATE_PARENT, 0); ++ if (IS_ERR(hw)) ++ goto err_free; ++ ++ hw = at91_clk_register_master_div(regmap, "mck0_div", "mck0_pres", ++ &mck0_layout, &mck0_characteristics, ++ &pmc_mck0_lock, 0); + if (IS_ERR(hw)) + goto err_free; + +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/111-clk-at91-sama7g5-register-cpu-clock.patch b/target/linux/at91/patches-5.10/111-clk-at91-sama7g5-register-cpu-clock.patch new file mode 100644 index 0000000000..9fb36e005f --- /dev/null +++ b/target/linux/at91/patches-5.10/111-clk-at91-sama7g5-register-cpu-clock.patch @@ -0,0 +1,72 @@ +From 36e97c421dd9f866e31fe14bcb7af01334791890 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 19 Nov 2020 17:43:17 +0200 +Subject: [PATCH 111/247] clk: at91: sama7g5: register cpu clock + +Register CPU clock as being the master clock prescaler. This would +be used by DVFS. The block schema of SAMA7G5's PMC contains also a divider +between master clock prescaler and CPU (PMC_CPU_RATIO.RATIO) but the +frequencies supported by SAMA7G5 could be directly received from +CPUPLL + master clock prescaler and the extra divider would do no work in +case it would be enabled. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/1605800597-16720-12-git-send-email-claudiu.beznea@microchip.com +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/sama7g5.c | 13 ++++++------- + include/dt-bindings/clock/at91.h | 1 + + 2 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c +index 927eb3b2b126..a6e20b35960e 100644 +--- a/drivers/clk/at91/sama7g5.c ++++ b/drivers/clk/at91/sama7g5.c +@@ -904,7 +904,7 @@ static void __init sama7g5_pmc_setup(struct device_node *np) + if (IS_ERR(regmap)) + return; + +- sama7g5_pmc = pmc_data_allocate(PMC_ETHPLL + 1, ++ sama7g5_pmc = pmc_data_allocate(PMC_CPU + 1, + nck(sama7g5_systemck), + nck(sama7g5_periphck), + nck(sama7g5_gck), 8); +@@ -981,18 +981,17 @@ static void __init sama7g5_pmc_setup(struct device_node *np) + } + } + +- parent_names[0] = md_slck_name; +- parent_names[1] = "mainck"; +- parent_names[2] = "cpupll_divpmcck"; +- parent_names[3] = "syspll_divpmcck"; +- hw = at91_clk_register_master_pres(regmap, "mck0_pres", 4, parent_names, ++ parent_names[0] = "cpupll_divpmcck"; ++ hw = at91_clk_register_master_pres(regmap, "cpuck", 1, parent_names, + &mck0_layout, &mck0_characteristics, + &pmc_mck0_lock, + CLK_SET_RATE_PARENT, 0); + if (IS_ERR(hw)) + goto err_free; + +- hw = at91_clk_register_master_div(regmap, "mck0_div", "mck0_pres", ++ sama7g5_pmc->chws[PMC_CPU] = hw; ++ ++ hw = at91_clk_register_master_div(regmap, "mck0", "cpuck", + &mck0_layout, &mck0_characteristics, + &pmc_mck0_lock, 0); + if (IS_ERR(hw)) +diff --git a/include/dt-bindings/clock/at91.h b/include/dt-bindings/clock/at91.h +index fab313f62e8f..98e1b2ab6403 100644 +--- a/include/dt-bindings/clock/at91.h ++++ b/include/dt-bindings/clock/at91.h +@@ -34,6 +34,7 @@ + #define PMC_AUDIOPMCPLL (PMC_MAIN + 6) + #define PMC_AUDIOIOPLL (PMC_MAIN + 7) + #define PMC_ETHPLL (PMC_MAIN + 8) ++#define PMC_CPU (PMC_MAIN + 9) + + #ifndef AT91_PMC_MOSCS + #define AT91_PMC_MOSCS 0 /* MOSCS Flag */ +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/112-clk-at91-Fix-the-declaration-of-the-clocks.patch b/target/linux/at91/patches-5.10/112-clk-at91-Fix-the-declaration-of-the-clocks.patch new file mode 100644 index 0000000000..42d4769354 --- /dev/null +++ b/target/linux/at91/patches-5.10/112-clk-at91-Fix-the-declaration-of-the-clocks.patch @@ -0,0 +1,202 @@ +From 5a25e2437af0db535b17da352fb16680a8dfdeda Mon Sep 17 00:00:00 2001 +From: Tudor Ambarus <tudor.ambarus@microchip.com> +Date: Wed, 3 Feb 2021 17:43:32 +0200 +Subject: [PATCH 112/247] clk: at91: Fix the declaration of the clocks + +These are all "early clocks" that require initialization just at +of_clk_init() time. Use CLK_OF_DECLARE() to declare them. + +This also fixes a problem that was spotted when fw_devlink was +set to 'on' by default: the boards failed to boot. The reason is +that CLK_OF_DECLARE_DRIVER() clears the OF_POPULATED and causes +the consumers of the clock to be postponed by fw_devlink until +the second initialization routine of the clock has been completed. +One of the consumers of the clock is the timer, which is used as a +clocksource, and needs the clock initialized early. Postponing the +timers caused the fail at boot. + +Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com> +Link: https://lore.kernel.org/r/20210203154332.470587-1-tudor.ambarus@microchip.com +Acked-by: Saravana Kannan <saravanak@google.com> +Tested-by: Eugen Hristev <eugen.hristev@microchip.com> +Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/at91rm9200.c | 3 +-- + drivers/clk/at91/at91sam9260.c | 16 ++++++++-------- + drivers/clk/at91/at91sam9g45.c | 3 +-- + drivers/clk/at91/at91sam9n12.c | 3 +-- + drivers/clk/at91/at91sam9rl.c | 3 ++- + drivers/clk/at91/at91sam9x5.c | 20 ++++++++++---------- + drivers/clk/at91/sama5d2.c | 3 ++- + drivers/clk/at91/sama5d3.c | 2 +- + drivers/clk/at91/sama5d4.c | 3 ++- + 9 files changed, 28 insertions(+), 28 deletions(-) + +diff --git a/drivers/clk/at91/at91rm9200.c b/drivers/clk/at91/at91rm9200.c +index 0fad1009f315..428a6f4b9ebc 100644 +--- a/drivers/clk/at91/at91rm9200.c ++++ b/drivers/clk/at91/at91rm9200.c +@@ -215,5 +215,4 @@ static void __init at91rm9200_pmc_setup(struct device_node *np) + * deferring properly. Once this is fixed, this can be switched to a platform + * driver. + */ +-CLK_OF_DECLARE_DRIVER(at91rm9200_pmc, "atmel,at91rm9200-pmc", +- at91rm9200_pmc_setup); ++CLK_OF_DECLARE(at91rm9200_pmc, "atmel,at91rm9200-pmc", at91rm9200_pmc_setup); +diff --git a/drivers/clk/at91/at91sam9260.c b/drivers/clk/at91/at91sam9260.c +index ceb5495f723a..b29843bea278 100644 +--- a/drivers/clk/at91/at91sam9260.c ++++ b/drivers/clk/at91/at91sam9260.c +@@ -491,26 +491,26 @@ static void __init at91sam9260_pmc_setup(struct device_node *np) + { + at91sam926x_pmc_setup(np, &at91sam9260_data); + } +-CLK_OF_DECLARE_DRIVER(at91sam9260_pmc, "atmel,at91sam9260-pmc", +- at91sam9260_pmc_setup); ++ ++CLK_OF_DECLARE(at91sam9260_pmc, "atmel,at91sam9260-pmc", at91sam9260_pmc_setup); + + static void __init at91sam9261_pmc_setup(struct device_node *np) + { + at91sam926x_pmc_setup(np, &at91sam9261_data); + } +-CLK_OF_DECLARE_DRIVER(at91sam9261_pmc, "atmel,at91sam9261-pmc", +- at91sam9261_pmc_setup); ++ ++CLK_OF_DECLARE(at91sam9261_pmc, "atmel,at91sam9261-pmc", at91sam9261_pmc_setup); + + static void __init at91sam9263_pmc_setup(struct device_node *np) + { + at91sam926x_pmc_setup(np, &at91sam9263_data); + } +-CLK_OF_DECLARE_DRIVER(at91sam9263_pmc, "atmel,at91sam9263-pmc", +- at91sam9263_pmc_setup); ++ ++CLK_OF_DECLARE(at91sam9263_pmc, "atmel,at91sam9263-pmc", at91sam9263_pmc_setup); + + static void __init at91sam9g20_pmc_setup(struct device_node *np) + { + at91sam926x_pmc_setup(np, &at91sam9g20_data); + } +-CLK_OF_DECLARE_DRIVER(at91sam9g20_pmc, "atmel,at91sam9g20-pmc", +- at91sam9g20_pmc_setup); ++ ++CLK_OF_DECLARE(at91sam9g20_pmc, "atmel,at91sam9g20-pmc", at91sam9g20_pmc_setup); +diff --git a/drivers/clk/at91/at91sam9g45.c b/drivers/clk/at91/at91sam9g45.c +index 0214333dedd3..15da0dfe3ef2 100644 +--- a/drivers/clk/at91/at91sam9g45.c ++++ b/drivers/clk/at91/at91sam9g45.c +@@ -228,5 +228,4 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np) + * The TCB is used as the clocksource so its clock is needed early. This means + * this can't be a platform driver. + */ +-CLK_OF_DECLARE_DRIVER(at91sam9g45_pmc, "atmel,at91sam9g45-pmc", +- at91sam9g45_pmc_setup); ++CLK_OF_DECLARE(at91sam9g45_pmc, "atmel,at91sam9g45-pmc", at91sam9g45_pmc_setup); +diff --git a/drivers/clk/at91/at91sam9n12.c b/drivers/clk/at91/at91sam9n12.c +index f9db5316a7f1..7fe435f4b46b 100644 +--- a/drivers/clk/at91/at91sam9n12.c ++++ b/drivers/clk/at91/at91sam9n12.c +@@ -255,5 +255,4 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np) + * The TCB is used as the clocksource so its clock is needed early. This means + * this can't be a platform driver. + */ +-CLK_OF_DECLARE_DRIVER(at91sam9n12_pmc, "atmel,at91sam9n12-pmc", +- at91sam9n12_pmc_setup); ++CLK_OF_DECLARE(at91sam9n12_pmc, "atmel,at91sam9n12-pmc", at91sam9n12_pmc_setup); +diff --git a/drivers/clk/at91/at91sam9rl.c b/drivers/clk/at91/at91sam9rl.c +index 66736e03cfef..ecbabf5162bd 100644 +--- a/drivers/clk/at91/at91sam9rl.c ++++ b/drivers/clk/at91/at91sam9rl.c +@@ -186,4 +186,5 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np) + err_free: + kfree(at91sam9rl_pmc); + } +-CLK_OF_DECLARE_DRIVER(at91sam9rl_pmc, "atmel,at91sam9rl-pmc", at91sam9rl_pmc_setup); ++ ++CLK_OF_DECLARE(at91sam9rl_pmc, "atmel,at91sam9rl-pmc", at91sam9rl_pmc_setup); +diff --git a/drivers/clk/at91/at91sam9x5.c b/drivers/clk/at91/at91sam9x5.c +index 79b9d3667228..5cce48c64ea2 100644 +--- a/drivers/clk/at91/at91sam9x5.c ++++ b/drivers/clk/at91/at91sam9x5.c +@@ -302,33 +302,33 @@ static void __init at91sam9g15_pmc_setup(struct device_node *np) + { + at91sam9x5_pmc_setup(np, at91sam9g15_periphck, true); + } +-CLK_OF_DECLARE_DRIVER(at91sam9g15_pmc, "atmel,at91sam9g15-pmc", +- at91sam9g15_pmc_setup); ++ ++CLK_OF_DECLARE(at91sam9g15_pmc, "atmel,at91sam9g15-pmc", at91sam9g15_pmc_setup); + + static void __init at91sam9g25_pmc_setup(struct device_node *np) + { + at91sam9x5_pmc_setup(np, at91sam9g25_periphck, false); + } +-CLK_OF_DECLARE_DRIVER(at91sam9g25_pmc, "atmel,at91sam9g25-pmc", +- at91sam9g25_pmc_setup); ++ ++CLK_OF_DECLARE(at91sam9g25_pmc, "atmel,at91sam9g25-pmc", at91sam9g25_pmc_setup); + + static void __init at91sam9g35_pmc_setup(struct device_node *np) + { + at91sam9x5_pmc_setup(np, at91sam9g35_periphck, true); + } +-CLK_OF_DECLARE_DRIVER(at91sam9g35_pmc, "atmel,at91sam9g35-pmc", +- at91sam9g35_pmc_setup); ++ ++CLK_OF_DECLARE(at91sam9g35_pmc, "atmel,at91sam9g35-pmc", at91sam9g35_pmc_setup); + + static void __init at91sam9x25_pmc_setup(struct device_node *np) + { + at91sam9x5_pmc_setup(np, at91sam9x25_periphck, false); + } +-CLK_OF_DECLARE_DRIVER(at91sam9x25_pmc, "atmel,at91sam9x25-pmc", +- at91sam9x25_pmc_setup); ++ ++CLK_OF_DECLARE(at91sam9x25_pmc, "atmel,at91sam9x25-pmc", at91sam9x25_pmc_setup); + + static void __init at91sam9x35_pmc_setup(struct device_node *np) + { + at91sam9x5_pmc_setup(np, at91sam9x35_periphck, true); + } +-CLK_OF_DECLARE_DRIVER(at91sam9x35_pmc, "atmel,at91sam9x35-pmc", +- at91sam9x35_pmc_setup); ++ ++CLK_OF_DECLARE(at91sam9x35_pmc, "atmel,at91sam9x35-pmc", at91sam9x35_pmc_setup); +diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c +index 9a5cbc7cd55a..3d1f78176c3e 100644 +--- a/drivers/clk/at91/sama5d2.c ++++ b/drivers/clk/at91/sama5d2.c +@@ -372,4 +372,5 @@ static void __init sama5d2_pmc_setup(struct device_node *np) + err_free: + kfree(sama5d2_pmc); + } +-CLK_OF_DECLARE_DRIVER(sama5d2_pmc, "atmel,sama5d2-pmc", sama5d2_pmc_setup); ++ ++CLK_OF_DECLARE(sama5d2_pmc, "atmel,sama5d2-pmc", sama5d2_pmc_setup); +diff --git a/drivers/clk/at91/sama5d3.c b/drivers/clk/at91/sama5d3.c +index 87009ee8effc..d376257807d2 100644 +--- a/drivers/clk/at91/sama5d3.c ++++ b/drivers/clk/at91/sama5d3.c +@@ -255,4 +255,4 @@ static void __init sama5d3_pmc_setup(struct device_node *np) + * The TCB is used as the clocksource so its clock is needed early. This means + * this can't be a platform driver. + */ +-CLK_OF_DECLARE_DRIVER(sama5d3_pmc, "atmel,sama5d3-pmc", sama5d3_pmc_setup); ++CLK_OF_DECLARE(sama5d3_pmc, "atmel,sama5d3-pmc", sama5d3_pmc_setup); +diff --git a/drivers/clk/at91/sama5d4.c b/drivers/clk/at91/sama5d4.c +index 57fff790188b..5cbaac68da44 100644 +--- a/drivers/clk/at91/sama5d4.c ++++ b/drivers/clk/at91/sama5d4.c +@@ -286,4 +286,5 @@ static void __init sama5d4_pmc_setup(struct device_node *np) + err_free: + kfree(sama5d4_pmc); + } +-CLK_OF_DECLARE_DRIVER(sama5d4_pmc, "atmel,sama5d4-pmc", sama5d4_pmc_setup); ++ ++CLK_OF_DECLARE(sama5d4_pmc, "atmel,sama5d4-pmc", sama5d4_pmc_setup); +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/113-clk-at91-Trivial-typo-fixes-in-the-file-sama7g5.c.patch b/target/linux/at91/patches-5.10/113-clk-at91-Trivial-typo-fixes-in-the-file-sama7g5.c.patch new file mode 100644 index 0000000000..9f8c67942e --- /dev/null +++ b/target/linux/at91/patches-5.10/113-clk-at91-Trivial-typo-fixes-in-the-file-sama7g5.c.patch @@ -0,0 +1,50 @@ +From 268b36c42b7d1e480dd56ecfec626a46f4b5975e Mon Sep 17 00:00:00 2001 +From: Bhaskar Chowdhury <unixbhaskar@gmail.com> +Date: Sat, 13 Mar 2021 11:02:22 +0530 +Subject: [PATCH 113/247] clk: at91: Trivial typo fixes in the file sama7g5.c + +s/critial/critical/ ......two different places +s/parrent/parent/ + +Signed-off-by: Bhaskar Chowdhury <unixbhaskar@gmail.com> +Link: https://lore.kernel.org/r/20210313053222.14706-1-unixbhaskar@gmail.com +Acked-by: Randy Dunlap <rdunlap@infradead.org> +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/sama7g5.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c +index a6e20b35960e..9e1ec48c4474 100644 +--- a/drivers/clk/at91/sama7g5.c ++++ b/drivers/clk/at91/sama7g5.c +@@ -166,7 +166,7 @@ static const struct { + .c = &pll_characteristics, + .t = PLL_TYPE_FRAC, + /* +- * This feeds syspll_divpmcck which may feed critial parts ++ * This feeds syspll_divpmcck which may feed critical parts + * of the systems like timers. Therefore it should not be + * disabled. + */ +@@ -178,7 +178,7 @@ static const struct { + .c = &pll_characteristics, + .t = PLL_TYPE_DIV, + /* +- * This may feed critial parts of the systems like timers. ++ * This may feed critical parts of the systems like timers. + * Therefore it should not be disabled. + */ + .f = CLK_IS_CRITICAL | CLK_SET_RATE_GATE, +@@ -455,7 +455,7 @@ static const struct { + * @pp: PLL parents + * @pp_mux_table: PLL parents mux table + * @r: clock output range +- * @pp_chg_id: id in parrent array of changeable PLL parent ++ * @pp_chg_id: id in parent array of changeable PLL parent + * @pp_count: PLL parents count + * @id: clock id + */ +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/114-clk-at91-sama7g5-remove-all-kernel-doc-kernel-doc-wa.patch b/target/linux/at91/patches-5.10/114-clk-at91-sama7g5-remove-all-kernel-doc-kernel-doc-wa.patch new file mode 100644 index 0000000000..f13be0bfd7 --- /dev/null +++ b/target/linux/at91/patches-5.10/114-clk-at91-sama7g5-remove-all-kernel-doc-kernel-doc-wa.patch @@ -0,0 +1,95 @@ +From 9997227090cf529675aeb775585ec9f6c2f0f131 Mon Sep 17 00:00:00 2001 +From: Randy Dunlap <rdunlap@infradead.org> +Date: Thu, 19 Aug 2021 15:32:37 -0700 +Subject: [PATCH 114/247] clk: at91: sama7g5: remove all kernel-doc & + kernel-doc warnings + +Remove all "/**" kernel-doc markers from sama7g5.c since they are +all internal to this driver source file only. +This eliminates 14 warnings that were reported by the kernel test robot. + +Signed-off-by: Randy Dunlap <rdunlap@infradead.org> +Reported-by: kernel test robot <lkp@intel.com> +Cc: Claudiu Beznea <claudiu.beznea@microchip.com> +Cc: Michael Turquette <mturquette@baylibre.com> +Cc: Stephen Boyd <sboyd@kernel.org> +Cc: Eugen Hristev <eugen.hristev@microchip.com> +Cc: linux-clk@vger.kernel.org +Cc: linux-arm-kernel@lists.infradead.org +Link: https://lore.kernel.org/r/20210819223237.20115-1-rdunlap@infradead.org +Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/sama7g5.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c +index 9e1ec48c4474..cf8c079aa086 100644 +--- a/drivers/clk/at91/sama7g5.c ++++ b/drivers/clk/at91/sama7g5.c +@@ -35,7 +35,7 @@ static DEFINE_SPINLOCK(pmc_pll_lock); + static DEFINE_SPINLOCK(pmc_mck0_lock); + static DEFINE_SPINLOCK(pmc_mckX_lock); + +-/** ++/* + * PLL clocks identifiers + * @PLL_ID_CPU: CPU PLL identifier + * @PLL_ID_SYS: System PLL identifier +@@ -56,7 +56,7 @@ enum pll_ids { + PLL_ID_MAX, + }; + +-/** ++/* + * PLL type identifiers + * @PLL_TYPE_FRAC: fractional PLL identifier + * @PLL_TYPE_DIV: divider PLL identifier +@@ -118,7 +118,7 @@ static const struct clk_pll_characteristics pll_characteristics = { + .output = pll_outputs, + }; + +-/** ++/* + * PLL clocks description + * @n: clock name + * @p: clock parent +@@ -285,7 +285,7 @@ static const struct { + }, + }; + +-/** ++/* + * Master clock (MCK[1..4]) description + * @n: clock name + * @ep: extra parents names array +@@ -337,7 +337,7 @@ static const struct { + .c = 1, }, + }; + +-/** ++/* + * System clock description + * @n: clock name + * @p: clock parent name +@@ -361,7 +361,7 @@ static const struct { + /* Mux table for programmable clocks. */ + static u32 sama7g5_prog_mux_table[] = { 0, 1, 2, 5, 6, 7, 8, 9, 10, }; + +-/** ++/* + * Peripheral clock description + * @n: clock name + * @p: clock parent name +@@ -449,7 +449,7 @@ static const struct { + { .n = "uhphs_clk", .p = "mck1", .id = 106, }, + }; + +-/** ++/* + * Generic clock description + * @n: clock name + * @pp: PLL parents +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/115-net-macb-add-userio-bits-as-platform-configuration.patch b/target/linux/at91/patches-5.10/115-net-macb-add-userio-bits-as-platform-configuration.patch new file mode 100644 index 0000000000..ce5a2ebc40 --- /dev/null +++ b/target/linux/at91/patches-5.10/115-net-macb-add-userio-bits-as-platform-configuration.patch @@ -0,0 +1,186 @@ +From 89f37ac2780d113d3c17d329726c0e92a1400744 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Wed, 9 Dec 2020 15:03:32 +0200 +Subject: [PATCH 115/247] net: macb: add userio bits as platform configuration + +This is necessary for SAMA7G5 as it uses different values for +PHY interface and also introduces hdfctlen bit. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Reviewed-by: Andrew Lunn <andrew@lunn.ch> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/cadence/macb.h | 10 +++++++++ + drivers/net/ethernet/cadence/macb_main.c | 28 ++++++++++++++++++++---- + 2 files changed, 34 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h +index 5de47f6fde5a..e9385a1390a9 100644 +--- a/drivers/net/ethernet/cadence/macb.h ++++ b/drivers/net/ethernet/cadence/macb.h +@@ -1104,6 +1104,14 @@ struct macb_pm_data { + u32 usrio; + }; + ++struct macb_usrio_config { ++ u32 mii; ++ u32 rmii; ++ u32 rgmii; ++ u32 refclk; ++ u32 hdfctlen; ++}; ++ + struct macb_config { + u32 caps; + unsigned int dma_burst_length; +@@ -1112,6 +1120,7 @@ struct macb_config { + struct clk **rx_clk, struct clk **tsu_clk); + int (*init)(struct platform_device *pdev); + int jumbo_max_len; ++ const struct macb_usrio_config *usrio; + }; + + struct tsu_incr { +@@ -1244,6 +1253,7 @@ struct macb { + u32 rx_intr_mask; + + struct macb_pm_data pm_data; ++ const struct macb_usrio_config *usrio; + }; + + #ifdef CONFIG_MACB_USE_HWSTAMP +diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c +index 1e8bf6b9834b..a8326b75eca8 100644 +--- a/drivers/net/ethernet/cadence/macb_main.c ++++ b/drivers/net/ethernet/cadence/macb_main.c +@@ -3800,15 +3800,15 @@ static int macb_init(struct platform_device *pdev) + if (!(bp->caps & MACB_CAPS_USRIO_DISABLED)) { + val = 0; + if (phy_interface_mode_is_rgmii(bp->phy_interface)) +- val = GEM_BIT(RGMII); ++ val = bp->usrio->rgmii; + else if (bp->phy_interface == PHY_INTERFACE_MODE_RMII && + (bp->caps & MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII)) +- val = MACB_BIT(RMII); ++ val = bp->usrio->rmii; + else if (!(bp->caps & MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII)) +- val = MACB_BIT(MII); ++ val = bp->usrio->mii; + + if (bp->caps & MACB_CAPS_USRIO_HAS_CLKEN) +- val |= MACB_BIT(CLKEN); ++ val |= bp->usrio->refclk; + + macb_or_gem_writel(bp, USRIO, val); + } +@@ -4326,6 +4326,13 @@ static int fu540_c000_init(struct platform_device *pdev) + return macb_init(pdev); + } + ++static const struct macb_usrio_config macb_default_usrio = { ++ .mii = MACB_BIT(MII), ++ .rmii = MACB_BIT(RMII), ++ .rgmii = GEM_BIT(RGMII), ++ .refclk = MACB_BIT(CLKEN), ++}; ++ + static const struct macb_config fu540_c000_config = { + .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_JUMBO | + MACB_CAPS_GEM_HAS_PTP, +@@ -4333,12 +4340,14 @@ static const struct macb_config fu540_c000_config = { + .clk_init = fu540_c000_clk_init, + .init = fu540_c000_init, + .jumbo_max_len = 10240, ++ .usrio = &macb_default_usrio, + }; + + static const struct macb_config at91sam9260_config = { + .caps = MACB_CAPS_USRIO_HAS_CLKEN | MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII, + .clk_init = macb_clk_init, + .init = macb_init, ++ .usrio = &macb_default_usrio, + }; + + static const struct macb_config sama5d3macb_config = { +@@ -4346,6 +4355,7 @@ static const struct macb_config sama5d3macb_config = { + | MACB_CAPS_USRIO_HAS_CLKEN | MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII, + .clk_init = macb_clk_init, + .init = macb_init, ++ .usrio = &macb_default_usrio, + }; + + static const struct macb_config pc302gem_config = { +@@ -4353,6 +4363,7 @@ static const struct macb_config pc302gem_config = { + .dma_burst_length = 16, + .clk_init = macb_clk_init, + .init = macb_init, ++ .usrio = &macb_default_usrio, + }; + + static const struct macb_config sama5d2_config = { +@@ -4360,6 +4371,7 @@ static const struct macb_config sama5d2_config = { + .dma_burst_length = 16, + .clk_init = macb_clk_init, + .init = macb_init, ++ .usrio = &macb_default_usrio, + }; + + static const struct macb_config sama5d3_config = { +@@ -4369,6 +4381,7 @@ static const struct macb_config sama5d3_config = { + .clk_init = macb_clk_init, + .init = macb_init, + .jumbo_max_len = 10240, ++ .usrio = &macb_default_usrio, + }; + + static const struct macb_config sama5d4_config = { +@@ -4376,18 +4389,21 @@ static const struct macb_config sama5d4_config = { + .dma_burst_length = 4, + .clk_init = macb_clk_init, + .init = macb_init, ++ .usrio = &macb_default_usrio, + }; + + static const struct macb_config emac_config = { + .caps = MACB_CAPS_NEEDS_RSTONUBR | MACB_CAPS_MACB_IS_EMAC, + .clk_init = at91ether_clk_init, + .init = at91ether_init, ++ .usrio = &macb_default_usrio, + }; + + static const struct macb_config np4_config = { + .caps = MACB_CAPS_USRIO_DISABLED, + .clk_init = macb_clk_init, + .init = macb_init, ++ .usrio = &macb_default_usrio, + }; + + static const struct macb_config zynqmp_config = { +@@ -4398,6 +4414,7 @@ static const struct macb_config zynqmp_config = { + .clk_init = macb_clk_init, + .init = macb_init, + .jumbo_max_len = 10240, ++ .usrio = &macb_default_usrio, + }; + + static const struct macb_config zynq_config = { +@@ -4406,6 +4423,7 @@ static const struct macb_config zynq_config = { + .dma_burst_length = 16, + .clk_init = macb_clk_init, + .init = macb_init, ++ .usrio = &macb_default_usrio, + }; + + static const struct of_device_id macb_dt_ids[] = { +@@ -4527,6 +4545,8 @@ static int macb_probe(struct platform_device *pdev) + bp->wol |= MACB_WOL_HAS_MAGIC_PACKET; + device_set_wakeup_capable(&pdev->dev, bp->wol & MACB_WOL_HAS_MAGIC_PACKET); + ++ bp->usrio = macb_config->usrio; ++ + spin_lock_init(&bp->lock); + + /* setup capabilities */ +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/116-net-macb-add-capability-to-not-set-the-clock-rate.patch b/target/linux/at91/patches-5.10/116-net-macb-add-capability-to-not-set-the-clock-rate.patch new file mode 100644 index 0000000000..9b904785fc --- /dev/null +++ b/target/linux/at91/patches-5.10/116-net-macb-add-capability-to-not-set-the-clock-rate.patch @@ -0,0 +1,92 @@ +From 1b15259551b701f416aa024050a2e619860bd0d8 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Wed, 9 Dec 2020 15:03:33 +0200 +Subject: [PATCH 116/247] net: macb: add capability to not set the clock rate + +SAMA7G5's ethernet IPs TX clock could be provided by its generic clock or +by the external clock provided by the PHY. The internal IP logic divides +properly this clock depending on the link speed. The patch adds a new +capability so that macb_set_tx_clock() to not be called for IPs having +this capability (the clock rate, in case of generic clock, is set at the +boot time via device tree and the driver only enables it). + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Reviewed-by: Andrew Lunn <andrew@lunn.ch> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/cadence/macb.h | 1 + + drivers/net/ethernet/cadence/macb_main.c | 18 +++++++++--------- + 2 files changed, 10 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h +index e9385a1390a9..23d294748779 100644 +--- a/drivers/net/ethernet/cadence/macb.h ++++ b/drivers/net/ethernet/cadence/macb.h +@@ -658,6 +658,7 @@ + #define MACB_CAPS_GEM_HAS_PTP 0x00000040 + #define MACB_CAPS_BD_RD_PREFETCH 0x00000080 + #define MACB_CAPS_NEEDS_RSTONUBR 0x00000100 ++#define MACB_CAPS_CLK_HW_CHG 0x04000000 + #define MACB_CAPS_MACB_IS_EMAC 0x08000000 + #define MACB_CAPS_FIFO_MODE 0x10000000 + #define MACB_CAPS_GIGABIT_MODE_AVAILABLE 0x20000000 +diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c +index a8326b75eca8..5d0d11eb6711 100644 +--- a/drivers/net/ethernet/cadence/macb_main.c ++++ b/drivers/net/ethernet/cadence/macb_main.c +@@ -457,15 +457,14 @@ static void macb_init_buffers(struct macb *bp) + + /** + * macb_set_tx_clk() - Set a clock to a new frequency +- * @clk: Pointer to the clock to change ++ * @bp: pointer to struct macb + * @speed: New frequency in Hz +- * @dev: Pointer to the struct net_device + */ +-static void macb_set_tx_clk(struct clk *clk, int speed, struct net_device *dev) ++static void macb_set_tx_clk(struct macb *bp, int speed) + { + long ferr, rate, rate_rounded; + +- if (!clk) ++ if (!bp->tx_clk || !(bp->caps & MACB_CAPS_CLK_HW_CHG)) + return; + + switch (speed) { +@@ -482,7 +481,7 @@ static void macb_set_tx_clk(struct clk *clk, int speed, struct net_device *dev) + return; + } + +- rate_rounded = clk_round_rate(clk, rate); ++ rate_rounded = clk_round_rate(bp->tx_clk, rate); + if (rate_rounded < 0) + return; + +@@ -492,11 +491,12 @@ static void macb_set_tx_clk(struct clk *clk, int speed, struct net_device *dev) + ferr = abs(rate_rounded - rate); + ferr = DIV_ROUND_UP(ferr, rate / 100000); + if (ferr > 5) +- netdev_warn(dev, "unable to generate target frequency: %ld Hz\n", ++ netdev_warn(bp->dev, ++ "unable to generate target frequency: %ld Hz\n", + rate); + +- if (clk_set_rate(clk, rate_rounded)) +- netdev_err(dev, "adjusting tx_clk failed.\n"); ++ if (clk_set_rate(bp->tx_clk, rate_rounded)) ++ netdev_err(bp->dev, "adjusting tx_clk failed.\n"); + } + + static void macb_validate(struct phylink_config *config, +@@ -649,7 +649,7 @@ static void macb_mac_link_up(struct phylink_config *config, + if (rx_pause) + ctrl |= MACB_BIT(PAE); + +- macb_set_tx_clk(bp->tx_clk, speed, ndev); ++ macb_set_tx_clk(bp, speed); + + /* Initialize rings & buffers as clearing MACB_BIT(TE) in link down + * cleared the pipeline and control registers. +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/117-net-macb-add-function-to-disable-all-macb-clocks.patch b/target/linux/at91/patches-5.10/117-net-macb-add-function-to-disable-all-macb-clocks.patch new file mode 100644 index 0000000000..9340c864b9 --- /dev/null +++ b/target/linux/at91/patches-5.10/117-net-macb-add-function-to-disable-all-macb-clocks.patch @@ -0,0 +1,87 @@ +From 935d9aae15ee245a1bc6e322cbef02566a8996cc Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Wed, 9 Dec 2020 15:03:34 +0200 +Subject: [PATCH 117/247] net: macb: add function to disable all macb clocks + +Add function to disable all macb clocks. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Suggested-by: Andrew Lunn <andrew@lunn.ch> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/cadence/macb_main.c | 38 +++++++++++++----------- + 1 file changed, 21 insertions(+), 17 deletions(-) + +diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c +index 5d0d11eb6711..eacf907a365d 100644 +--- a/drivers/net/ethernet/cadence/macb_main.c ++++ b/drivers/net/ethernet/cadence/macb_main.c +@@ -3575,6 +3575,20 @@ static void macb_probe_queues(void __iomem *mem, + *num_queues = hweight32(*queue_mask); + } + ++static void macb_clks_disable(struct clk *pclk, struct clk *hclk, struct clk *tx_clk, ++ struct clk *rx_clk, struct clk *tsu_clk) ++{ ++ struct clk_bulk_data clks[] = { ++ { .clk = tsu_clk, }, ++ { .clk = rx_clk, }, ++ { .clk = pclk, }, ++ { .clk = hclk, }, ++ { .clk = tx_clk }, ++ }; ++ ++ clk_bulk_disable_unprepare(ARRAY_SIZE(clks), clks); ++} ++ + static int macb_clk_init(struct platform_device *pdev, struct clk **pclk, + struct clk **hclk, struct clk **tx_clk, + struct clk **rx_clk, struct clk **tsu_clk) +@@ -4642,11 +4656,7 @@ static int macb_probe(struct platform_device *pdev) + free_netdev(dev); + + err_disable_clocks: +- clk_disable_unprepare(tx_clk); +- clk_disable_unprepare(hclk); +- clk_disable_unprepare(pclk); +- clk_disable_unprepare(rx_clk); +- clk_disable_unprepare(tsu_clk); ++ macb_clks_disable(pclk, hclk, tx_clk, rx_clk, tsu_clk); + pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_dont_use_autosuspend(&pdev->dev); +@@ -4671,11 +4681,8 @@ static int macb_remove(struct platform_device *pdev) + pm_runtime_disable(&pdev->dev); + pm_runtime_dont_use_autosuspend(&pdev->dev); + if (!pm_runtime_suspended(&pdev->dev)) { +- clk_disable_unprepare(bp->tx_clk); +- clk_disable_unprepare(bp->hclk); +- clk_disable_unprepare(bp->pclk); +- clk_disable_unprepare(bp->rx_clk); +- clk_disable_unprepare(bp->tsu_clk); ++ macb_clks_disable(bp->pclk, bp->hclk, bp->tx_clk, ++ bp->rx_clk, bp->tsu_clk); + pm_runtime_set_suspended(&pdev->dev); + } + phylink_destroy(bp->phylink); +@@ -4854,13 +4861,10 @@ static int __maybe_unused macb_runtime_suspend(struct device *dev) + struct net_device *netdev = dev_get_drvdata(dev); + struct macb *bp = netdev_priv(netdev); + +- if (!(device_may_wakeup(dev))) { +- clk_disable_unprepare(bp->tx_clk); +- clk_disable_unprepare(bp->hclk); +- clk_disable_unprepare(bp->pclk); +- clk_disable_unprepare(bp->rx_clk); +- } +- clk_disable_unprepare(bp->tsu_clk); ++ if (!(device_may_wakeup(dev))) ++ macb_clks_disable(bp->pclk, bp->hclk, bp->tx_clk, bp->rx_clk, bp->tsu_clk); ++ else ++ macb_clks_disable(NULL, NULL, NULL, NULL, bp->tsu_clk); + + return 0; + } +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/118-net-macb-unprepare-clocks-in-case-of-failure.patch b/target/linux/at91/patches-5.10/118-net-macb-unprepare-clocks-in-case-of-failure.patch new file mode 100644 index 0000000000..a1581086bc --- /dev/null +++ b/target/linux/at91/patches-5.10/118-net-macb-unprepare-clocks-in-case-of-failure.patch @@ -0,0 +1,65 @@ +From 9692c07ee8bf8f68b74d553d861d092e33264781 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Wed, 9 Dec 2020 15:03:35 +0200 +Subject: [PATCH 118/247] net: macb: unprepare clocks in case of failure + +Unprepare clocks in case of any failure in fu540_c000_clk_init(). + +Fixes: c218ad559020 ("macb: Add support for SiFive FU540-C000") +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/cadence/macb_main.c | 24 ++++++++++++++++++------ + 1 file changed, 18 insertions(+), 6 deletions(-) + +diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c +index eacf907a365d..c8d66f966a8b 100644 +--- a/drivers/net/ethernet/cadence/macb_main.c ++++ b/drivers/net/ethernet/cadence/macb_main.c +@@ -4307,8 +4307,10 @@ static int fu540_c000_clk_init(struct platform_device *pdev, struct clk **pclk, + return err; + + mgmt = devm_kzalloc(&pdev->dev, sizeof(*mgmt), GFP_KERNEL); +- if (!mgmt) +- return -ENOMEM; ++ if (!mgmt) { ++ err = -ENOMEM; ++ goto err_disable_clks; ++ } + + init.name = "sifive-gemgxl-mgmt"; + init.ops = &fu540_c000_ops; +@@ -4319,16 +4321,26 @@ static int fu540_c000_clk_init(struct platform_device *pdev, struct clk **pclk, + mgmt->hw.init = &init; + + *tx_clk = devm_clk_register(&pdev->dev, &mgmt->hw); +- if (IS_ERR(*tx_clk)) +- return PTR_ERR(*tx_clk); ++ if (IS_ERR(*tx_clk)) { ++ err = PTR_ERR(*tx_clk); ++ goto err_disable_clks; ++ } + + err = clk_prepare_enable(*tx_clk); +- if (err) ++ if (err) { + dev_err(&pdev->dev, "failed to enable tx_clk (%u)\n", err); +- else ++ *tx_clk = NULL; ++ goto err_disable_clks; ++ } else { + dev_info(&pdev->dev, "Registered clk switch '%s'\n", init.name); ++ } + + return 0; ++ ++err_disable_clks: ++ macb_clks_disable(*pclk, *hclk, *tx_clk, *rx_clk, *tsu_clk); ++ ++ return err; + } + + static int fu540_c000_init(struct platform_device *pdev) +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/119-net-macb-add-support-for-sama7g5-gem-interface.patch b/target/linux/at91/patches-5.10/119-net-macb-add-support-for-sama7g5-gem-interface.patch new file mode 100644 index 0000000000..773bbbba31 --- /dev/null +++ b/target/linux/at91/patches-5.10/119-net-macb-add-support-for-sama7g5-gem-interface.patch @@ -0,0 +1,59 @@ +From 0085cd8576ceeaddeedf973b939b41ba96e3f77c Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Wed, 9 Dec 2020 15:03:38 +0200 +Subject: [PATCH 119/247] net: macb: add support for sama7g5 gem interface + +Add support for SAMA7G5 gigabit ethernet interface. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Reviewed-by: Andrew Lunn <andrew@lunn.ch> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/cadence/macb_main.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c +index c8d66f966a8b..ebcc46d8aa9d 100644 +--- a/drivers/net/ethernet/cadence/macb_main.c ++++ b/drivers/net/ethernet/cadence/macb_main.c +@@ -4359,6 +4359,14 @@ static const struct macb_usrio_config macb_default_usrio = { + .refclk = MACB_BIT(CLKEN), + }; + ++static const struct macb_usrio_config sama7g5_usrio = { ++ .mii = 0, ++ .rmii = 1, ++ .rgmii = 2, ++ .refclk = BIT(2), ++ .hdfctlen = BIT(6), ++}; ++ + static const struct macb_config fu540_c000_config = { + .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_JUMBO | + MACB_CAPS_GEM_HAS_PTP, +@@ -4452,6 +4460,14 @@ static const struct macb_config zynq_config = { + .usrio = &macb_default_usrio, + }; + ++static const struct macb_config sama7g5_gem_config = { ++ .caps = MACB_CAPS_GIGABIT_MODE_AVAILABLE | MACB_CAPS_CLK_HW_CHG, ++ .dma_burst_length = 16, ++ .clk_init = macb_clk_init, ++ .init = macb_init, ++ .usrio = &sama7g5_usrio, ++}; ++ + static const struct of_device_id macb_dt_ids[] = { + { .compatible = "cdns,at32ap7000-macb" }, + { .compatible = "cdns,at91sam9260-macb", .data = &at91sam9260_config }, +@@ -4469,6 +4485,7 @@ static const struct of_device_id macb_dt_ids[] = { + { .compatible = "cdns,zynqmp-gem", .data = &zynqmp_config}, + { .compatible = "cdns,zynq-gem", .data = &zynq_config }, + { .compatible = "sifive,fu540-c000-gem", .data = &fu540_c000_config }, ++ { .compatible = "microchip,sama7g5-gem", .data = &sama7g5_gem_config }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, macb_dt_ids); +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/120-net-macb-add-support-for-sama7g5-emac-interface.patch b/target/linux/at91/patches-5.10/120-net-macb-add-support-for-sama7g5-emac-interface.patch new file mode 100644 index 0000000000..ea29cb0af0 --- /dev/null +++ b/target/linux/at91/patches-5.10/120-net-macb-add-support-for-sama7g5-emac-interface.patch @@ -0,0 +1,44 @@ +From a42f90357cfcfcf5cdade4594ad79a1eae633a9f Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Wed, 9 Dec 2020 15:03:39 +0200 +Subject: [PATCH 120/247] net: macb: add support for sama7g5 emac interface + +Add support for SAMA7G5 10/100Mbps interface. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Reviewed-by: Andrew Lunn <andrew@lunn.ch> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/cadence/macb_main.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c +index ebcc46d8aa9d..4ce302e03735 100644 +--- a/drivers/net/ethernet/cadence/macb_main.c ++++ b/drivers/net/ethernet/cadence/macb_main.c +@@ -4468,6 +4468,14 @@ static const struct macb_config sama7g5_gem_config = { + .usrio = &sama7g5_usrio, + }; + ++static const struct macb_config sama7g5_emac_config = { ++ .caps = MACB_CAPS_USRIO_DEFAULT_IS_MII_GMII | MACB_CAPS_USRIO_HAS_CLKEN, ++ .dma_burst_length = 16, ++ .clk_init = macb_clk_init, ++ .init = macb_init, ++ .usrio = &sama7g5_usrio, ++}; ++ + static const struct of_device_id macb_dt_ids[] = { + { .compatible = "cdns,at32ap7000-macb" }, + { .compatible = "cdns,at91sam9260-macb", .data = &at91sam9260_config }, +@@ -4486,6 +4494,7 @@ static const struct of_device_id macb_dt_ids[] = { + { .compatible = "cdns,zynq-gem", .data = &zynq_config }, + { .compatible = "sifive,fu540-c000-gem", .data = &fu540_c000_config }, + { .compatible = "microchip,sama7g5-gem", .data = &sama7g5_gem_config }, ++ { .compatible = "microchip,sama7g5-emac", .data = &sama7g5_emac_config }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, macb_dt_ids); +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/121-ASoC-pcm5102a-Make-codec-selectable.patch b/target/linux/at91/patches-5.10/121-ASoC-pcm5102a-Make-codec-selectable.patch new file mode 100644 index 0000000000..cf0db825ac --- /dev/null +++ b/target/linux/at91/patches-5.10/121-ASoC-pcm5102a-Make-codec-selectable.patch @@ -0,0 +1,33 @@ +From 5ac0e1f5577b266543756521b1a749003b0f3686 Mon Sep 17 00:00:00 2001 +From: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Date: Mon, 12 Oct 2020 17:19:11 +0300 +Subject: [PATCH 121/247] ASoC: pcm5102a: Make codec selectable + +The TI PCM5102A codec driver can be used with the generic sound card +drivers, so it should be selectable. For example, with the addition +of #sound-dai-cells = <0> property in DT, it can be used with simple/graph +card drivers. + +Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Link: https://lore.kernel.org/r/20201012141911.3150996-1-codrin.ciubotariu@microchip.com +Signed-off-by: Mark Brown <broonie@kernel.org> +--- + sound/soc/codecs/Kconfig | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig +index 34c6dd04b85a..5791b7056af6 100644 +--- a/sound/soc/codecs/Kconfig ++++ b/sound/soc/codecs/Kconfig +@@ -1003,7 +1003,7 @@ config SND_SOC_PCM3168A_SPI + select REGMAP_SPI + + config SND_SOC_PCM5102A +- tristate ++ tristate "Texas Instruments PCM5102A CODEC" + + config SND_SOC_PCM512x + tristate +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/122-ASoC-atmel-i2s-do-not-warn-if-muxclk-is-missing.patch b/target/linux/at91/patches-5.10/122-ASoC-atmel-i2s-do-not-warn-if-muxclk-is-missing.patch new file mode 100644 index 0000000000..5c168fbc0a --- /dev/null +++ b/target/linux/at91/patches-5.10/122-ASoC-atmel-i2s-do-not-warn-if-muxclk-is-missing.patch @@ -0,0 +1,35 @@ +From f4389949bf422fe04775c17b833100fa0e95ea68 Mon Sep 17 00:00:00 2001 +From: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Date: Tue, 3 Nov 2020 12:05:54 +0200 +Subject: [PATCH 122/247] ASoC: atmel-i2s: do not warn if muxclk is missing + +Besides the fact that muxclk is optional, muxclk can be set using +assigned-clocks, removing the need to set it in driver. The warning is +thus unneeded, so we can transform it in a debug print, eventually to just +reflect that muxclk was not set by the driver. + +Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Link: https://lore.kernel.org/r/20201103100554.1307190-1-codrin.ciubotariu@microchip.com +Signed-off-by: Mark Brown <broonie@kernel.org> +--- + sound/soc/atmel/atmel-i2s.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/atmel/atmel-i2s.c b/sound/soc/atmel/atmel-i2s.c +index d870f56c44cf..7483c474ccd7 100644 +--- a/sound/soc/atmel/atmel-i2s.c ++++ b/sound/soc/atmel/atmel-i2s.c +@@ -581,8 +581,8 @@ static int atmel_i2s_sama5d2_mck_init(struct atmel_i2s_dev *dev, + err = PTR_ERR(muxclk); + if (err == -EPROBE_DEFER) + return -EPROBE_DEFER; +- dev_warn(dev->dev, +- "failed to get the I2S clock control: %d\n", err); ++ dev_dbg(dev->dev, ++ "failed to get the I2S clock control: %d\n", err); + return 0; + } + +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/123-regulator-mcp16502-add-linear_min_sel.patch b/target/linux/at91/patches-5.10/123-regulator-mcp16502-add-linear_min_sel.patch new file mode 100644 index 0000000000..4e26bde627 --- /dev/null +++ b/target/linux/at91/patches-5.10/123-regulator-mcp16502-add-linear_min_sel.patch @@ -0,0 +1,30 @@ +From f5a73f3bb600b96b6149f2115360e1d0d51fbac4 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Fri, 13 Nov 2020 17:21:07 +0200 +Subject: [PATCH 123/247] regulator: mcp16502: add linear_min_sel + +Selectors b/w zero and VDD_LOW_SEL are not valid. Use linear_min_sel. + +Fixes: 919261c03e7ca ("regulator: mcp16502: add regulator driver for MCP16502") +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/1605280870-32432-4-git-send-email-claudiu.beznea@microchip.com +Signed-off-by: Mark Brown <broonie@kernel.org> +--- + drivers/regulator/mcp16502.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c +index 6d0ad74935b3..ab78f831f5bf 100644 +--- a/drivers/regulator/mcp16502.c ++++ b/drivers/regulator/mcp16502.c +@@ -93,6 +93,7 @@ static unsigned int mcp16502_of_map_mode(unsigned int mode) + .owner = THIS_MODULE, \ + .n_voltages = MCP16502_VSEL + 1, \ + .linear_ranges = _ranges, \ ++ .linear_min_sel = VDD_LOW_SEL, \ + .n_linear_ranges = ARRAY_SIZE(_ranges), \ + .of_match = of_match_ptr(_name), \ + .of_map_mode = mcp16502_of_map_mode, \ +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/124-regulator-mcp16502-adapt-for-get-set-on-other-regist.patch b/target/linux/at91/patches-5.10/124-regulator-mcp16502-adapt-for-get-set-on-other-regist.patch new file mode 100644 index 0000000000..5cd433f31a --- /dev/null +++ b/target/linux/at91/patches-5.10/124-regulator-mcp16502-adapt-for-get-set-on-other-regist.patch @@ -0,0 +1,122 @@ +From 5295f4c122258a11fb6012b7e043248e681db5a2 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Fri, 13 Nov 2020 17:21:08 +0200 +Subject: [PATCH 124/247] regulator: mcp16502: adapt for get/set on other + registers + +MCP16502 have multiple registers for each regulator (as described +in enum mcp16502_reg). Adapt the code to be able to get/set all these +registers. This is necessary for the following commits. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/1605280870-32432-5-git-send-email-claudiu.beznea@microchip.com +Signed-off-by: Mark Brown <broonie@kernel.org> +--- + drivers/regulator/mcp16502.c | 43 ++++++++++++++++++++++-------------- + 1 file changed, 27 insertions(+), 16 deletions(-) + +diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c +index ab78f831f5bf..48eb64bc4018 100644 +--- a/drivers/regulator/mcp16502.c ++++ b/drivers/regulator/mcp16502.c +@@ -54,13 +54,9 @@ + * This function is useful for iterating over all regulators and accessing their + * registers in a generic way or accessing a regulator device by its id. + */ +-#define MCP16502_BASE(i) (((i) + 1) << 4) ++#define MCP16502_REG_BASE(i, r) ((((i) + 1) << 4) + MCP16502_REG_##r) + #define MCP16502_STAT_BASE(i) ((i) + 5) + +-#define MCP16502_OFFSET_MODE_A 0 +-#define MCP16502_OFFSET_MODE_LPM 1 +-#define MCP16502_OFFSET_MODE_HIB 2 +- + #define MCP16502_OPMODE_ACTIVE REGULATOR_MODE_NORMAL + #define MCP16502_OPMODE_LPM REGULATOR_MODE_IDLE + #define MCP16502_OPMODE_HIB REGULATOR_MODE_STANDBY +@@ -75,6 +71,23 @@ + #define MCP16502_MIN_REG 0x0 + #define MCP16502_MAX_REG 0x65 + ++/** ++ * enum mcp16502_reg - MCP16502 regulators's registers ++ * @MCP16502_REG_A: active state register ++ * @MCP16502_REG_LPM: low power mode state register ++ * @MCP16502_REG_HIB: hibernate state register ++ * @MCP16502_REG_SEQ: startup sequence register ++ * @MCP16502_REG_CFG: configuration register ++ */ ++enum mcp16502_reg { ++ MCP16502_REG_A, ++ MCP16502_REG_LPM, ++ MCP16502_REG_HIB, ++ MCP16502_REG_HPM, ++ MCP16502_REG_SEQ, ++ MCP16502_REG_CFG, ++}; ++ + static unsigned int mcp16502_of_map_mode(unsigned int mode) + { + if (mode == REGULATOR_MODE_NORMAL || mode == REGULATOR_MODE_IDLE) +@@ -144,22 +157,20 @@ static void mcp16502_gpio_set_mode(struct mcp16502 *mcp, int mode) + } + + /* +- * mcp16502_get_reg() - get the PMIC's configuration register for opmode ++ * mcp16502_get_reg() - get the PMIC's state configuration register for opmode + * + * @rdev: the regulator whose register we are searching + * @opmode: the PMIC's operating mode ACTIVE, Low-power, Hibernate + */ +-static int mcp16502_get_reg(struct regulator_dev *rdev, int opmode) ++static int mcp16502_get_state_reg(struct regulator_dev *rdev, int opmode) + { +- int reg = MCP16502_BASE(rdev_get_id(rdev)); +- + switch (opmode) { + case MCP16502_OPMODE_ACTIVE: +- return reg + MCP16502_OFFSET_MODE_A; ++ return MCP16502_REG_BASE(rdev_get_id(rdev), A); + case MCP16502_OPMODE_LPM: +- return reg + MCP16502_OFFSET_MODE_LPM; ++ return MCP16502_REG_BASE(rdev_get_id(rdev), LPM); + case MCP16502_OPMODE_HIB: +- return reg + MCP16502_OFFSET_MODE_HIB; ++ return MCP16502_REG_BASE(rdev_get_id(rdev), HIB); + default: + return -EINVAL; + } +@@ -179,7 +190,7 @@ static unsigned int mcp16502_get_mode(struct regulator_dev *rdev) + unsigned int val; + int ret, reg; + +- reg = mcp16502_get_reg(rdev, MCP16502_OPMODE_ACTIVE); ++ reg = mcp16502_get_state_reg(rdev, MCP16502_OPMODE_ACTIVE); + if (reg < 0) + return reg; + +@@ -210,7 +221,7 @@ static int _mcp16502_set_mode(struct regulator_dev *rdev, unsigned int mode, + int val; + int reg; + +- reg = mcp16502_get_reg(rdev, op_mode); ++ reg = mcp16502_get_state_reg(rdev, op_mode); + if (reg < 0) + return reg; + +@@ -269,10 +280,10 @@ static int mcp16502_suspend_get_target_reg(struct regulator_dev *rdev) + { + switch (pm_suspend_target_state) { + case PM_SUSPEND_STANDBY: +- return mcp16502_get_reg(rdev, MCP16502_OPMODE_LPM); ++ return mcp16502_get_state_reg(rdev, MCP16502_OPMODE_LPM); + case PM_SUSPEND_ON: + case PM_SUSPEND_MEM: +- return mcp16502_get_reg(rdev, MCP16502_OPMODE_HIB); ++ return mcp16502_get_state_reg(rdev, MCP16502_OPMODE_HIB); + default: + dev_err(&rdev->dev, "invalid suspend target: %d\n", + pm_suspend_target_state); +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/125-regulator-mcp16502-add-support-for-ramp-delay.patch b/target/linux/at91/patches-5.10/125-regulator-mcp16502-add-support-for-ramp-delay.patch new file mode 100644 index 0000000000..ef06660803 --- /dev/null +++ b/target/linux/at91/patches-5.10/125-regulator-mcp16502-add-support-for-ramp-delay.patch @@ -0,0 +1,146 @@ +From 7f13433e11a3c88f1fd6417c4c5e5a6c98370b9a Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Fri, 13 Nov 2020 17:21:09 +0200 +Subject: [PATCH 125/247] regulator: mcp16502: add support for ramp delay + +MCP16502 have configurable ramp delay support (via DVSR bits in +regulators' CFG register). + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/1605280870-32432-6-git-send-email-claudiu.beznea@microchip.com +Signed-off-by: Mark Brown <broonie@kernel.org> +--- + drivers/regulator/mcp16502.c | 89 +++++++++++++++++++++++++++++++++++- + 1 file changed, 87 insertions(+), 2 deletions(-) + +diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c +index 48eb64bc4018..f81afeeddb19 100644 +--- a/drivers/regulator/mcp16502.c ++++ b/drivers/regulator/mcp16502.c +@@ -22,8 +22,9 @@ + #define VDD_LOW_SEL 0x0D + #define VDD_HIGH_SEL 0x3F + +-#define MCP16502_FLT BIT(7) +-#define MCP16502_ENS BIT(0) ++#define MCP16502_FLT BIT(7) ++#define MCP16502_DVSR GENMASK(3, 2) ++#define MCP16502_ENS BIT(0) + + /* + * The PMIC has four sets of registers corresponding to four power modes: +@@ -88,6 +89,12 @@ enum mcp16502_reg { + MCP16502_REG_CFG, + }; + ++/* Ramp delay (uV/us) for buck1, ldo1, ldo2. */ ++static const int mcp16502_ramp_b1l12[] = { 6250, 3125, 2083, 1563 }; ++ ++/* Ramp delay (uV/us) for buck2, buck3, buck4. */ ++static const int mcp16502_ramp_b234[] = { 3125, 1563, 1042, 781 }; ++ + static unsigned int mcp16502_of_map_mode(unsigned int mode) + { + if (mode == REGULATOR_MODE_NORMAL || mode == REGULATOR_MODE_IDLE) +@@ -271,6 +278,80 @@ static int mcp16502_get_status(struct regulator_dev *rdev) + return REGULATOR_STATUS_UNDEFINED; + } + ++static int mcp16502_set_voltage_time_sel(struct regulator_dev *rdev, ++ unsigned int old_sel, ++ unsigned int new_sel) ++{ ++ static const u8 us_ramp[] = { 8, 16, 24, 32 }; ++ int id = rdev_get_id(rdev); ++ unsigned int uV_delta, val; ++ int ret; ++ ++ ret = regmap_read(rdev->regmap, MCP16502_REG_BASE(id, CFG), &val); ++ if (ret) ++ return ret; ++ ++ val = (val & MCP16502_DVSR) >> 2; ++ uV_delta = abs(new_sel * rdev->desc->linear_ranges->step - ++ old_sel * rdev->desc->linear_ranges->step); ++ switch (id) { ++ case BUCK1: ++ case LDO1: ++ case LDO2: ++ ret = DIV_ROUND_CLOSEST(uV_delta * us_ramp[val], ++ mcp16502_ramp_b1l12[val]); ++ break; ++ ++ case BUCK2: ++ case BUCK3: ++ case BUCK4: ++ ret = DIV_ROUND_CLOSEST(uV_delta * us_ramp[val], ++ mcp16502_ramp_b234[val]); ++ break; ++ ++ default: ++ return -EINVAL; ++ } ++ ++ return ret; ++} ++ ++static int mcp16502_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) ++{ ++ const int *ramp; ++ int id = rdev_get_id(rdev); ++ unsigned int i, size; ++ ++ switch (id) { ++ case BUCK1: ++ case LDO1: ++ case LDO2: ++ ramp = mcp16502_ramp_b1l12; ++ size = ARRAY_SIZE(mcp16502_ramp_b1l12); ++ break; ++ ++ case BUCK2: ++ case BUCK3: ++ case BUCK4: ++ ramp = mcp16502_ramp_b234; ++ size = ARRAY_SIZE(mcp16502_ramp_b234); ++ break; ++ ++ default: ++ return -EINVAL; ++ } ++ ++ for (i = 0; i < size; i++) { ++ if (ramp[i] == ramp_delay) ++ break; ++ } ++ if (i == size) ++ return -EINVAL; ++ ++ return regmap_update_bits(rdev->regmap, MCP16502_REG_BASE(id, CFG), ++ MCP16502_DVSR, (i << 2)); ++} ++ + #ifdef CONFIG_SUSPEND + /* + * mcp16502_suspend_get_target_reg() - get the reg of the target suspend PMIC +@@ -365,6 +446,8 @@ static const struct regulator_ops mcp16502_buck_ops = { + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .get_status = mcp16502_get_status, ++ .set_voltage_time_sel = mcp16502_set_voltage_time_sel, ++ .set_ramp_delay = mcp16502_set_ramp_delay, + + .set_mode = mcp16502_set_mode, + .get_mode = mcp16502_get_mode, +@@ -389,6 +472,8 @@ static const struct regulator_ops mcp16502_ldo_ops = { + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .get_status = mcp16502_get_status, ++ .set_voltage_time_sel = mcp16502_set_voltage_time_sel, ++ .set_ramp_delay = mcp16502_set_ramp_delay, + + #ifdef CONFIG_SUSPEND + .set_suspend_voltage = mcp16502_set_suspend_voltage, +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/126-regulator-mcp16502-remove-void-documentation-of-stru.patch b/target/linux/at91/patches-5.10/126-regulator-mcp16502-remove-void-documentation-of-stru.patch new file mode 100644 index 0000000000..2c1f5d9806 --- /dev/null +++ b/target/linux/at91/patches-5.10/126-regulator-mcp16502-remove-void-documentation-of-stru.patch @@ -0,0 +1,32 @@ +From 8dcbcb052f682478dcbfa7fc9abdd909e1deab87 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Fri, 13 Nov 2020 17:21:10 +0200 +Subject: [PATCH 126/247] regulator: mcp16502: remove void documentation of + struct mcp16502 + +struct mcp16502 has no members called rdev or rmap. Remove the +documentation. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/1605280870-32432-7-git-send-email-claudiu.beznea@microchip.com +Signed-off-by: Mark Brown <broonie@kernel.org> +--- + drivers/regulator/mcp16502.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c +index f81afeeddb19..74ad92dc664a 100644 +--- a/drivers/regulator/mcp16502.c ++++ b/drivers/regulator/mcp16502.c +@@ -135,8 +135,6 @@ enum { + + /* + * struct mcp16502 - PMIC representation +- * @rdev: the regulators belonging to this chip +- * @rmap: regmap to be used for I2C communication + * @lpm: LPM GPIO descriptor + */ + struct mcp16502 { +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/127-regulator-core-validate-selector-against-linear_min_.patch b/target/linux/at91/patches-5.10/127-regulator-core-validate-selector-against-linear_min_.patch new file mode 100644 index 0000000000..88302fda04 --- /dev/null +++ b/target/linux/at91/patches-5.10/127-regulator-core-validate-selector-against-linear_min_.patch @@ -0,0 +1,71 @@ +From 3aee4f22ed0a22d3d6d22fc49812c03d876c7637 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Fri, 13 Nov 2020 17:21:05 +0200 +Subject: [PATCH 127/247] regulator: core: validate selector against + linear_min_sel + +There are regulators who's min selector is not zero. Selectors loops +(looping b/w zero and regulator::desc::n_voltages) might throw errors +because invalid selectors are used (lower than +regulator::desc::linear_min_sel). For this situations validate selectors +against regulator::desc::linear_min_sel. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/1605280870-32432-2-git-send-email-claudiu.beznea@microchip.com +Signed-off-by: Mark Brown <broonie@kernel.org> +--- + drivers/regulator/core.c | 9 +++++++-- + drivers/regulator/helpers.c | 3 ++- + 2 files changed, 9 insertions(+), 3 deletions(-) + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index 043b5f63b94a..dfdd42b9d773 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -2984,7 +2984,8 @@ static int _regulator_list_voltage(struct regulator_dev *rdev, + return rdev->desc->fixed_uV; + + if (ops->list_voltage) { +- if (selector >= rdev->desc->n_voltages) ++ if (selector >= rdev->desc->n_voltages || ++ selector < rdev->desc->linear_min_sel) + return -EINVAL; + if (lock) + regulator_lock(rdev); +@@ -3135,7 +3136,8 @@ int regulator_list_hardware_vsel(struct regulator *regulator, + struct regulator_dev *rdev = regulator->rdev; + const struct regulator_ops *ops = rdev->desc->ops; + +- if (selector >= rdev->desc->n_voltages) ++ if (selector >= rdev->desc->n_voltages || ++ selector < rdev->desc->linear_min_sel) + return -EINVAL; + if (ops->set_voltage_sel != regulator_set_voltage_sel_regmap) + return -EOPNOTSUPP; +@@ -4058,6 +4060,9 @@ int regulator_set_voltage_time(struct regulator *regulator, + + for (i = 0; i < rdev->desc->n_voltages; i++) { + /* We only look for exact voltage matches here */ ++ if (i < rdev->desc->linear_min_sel) ++ continue; ++ + voltage = regulator_list_voltage(regulator, i); + if (voltage < 0) + return -EINVAL; +diff --git a/drivers/regulator/helpers.c b/drivers/regulator/helpers.c +index e4bb09bbd3fa..974f1a63993d 100644 +--- a/drivers/regulator/helpers.c ++++ b/drivers/regulator/helpers.c +@@ -647,7 +647,8 @@ int regulator_list_voltage_table(struct regulator_dev *rdev, + return -EINVAL; + } + +- if (selector >= rdev->desc->n_voltages) ++ if (selector >= rdev->desc->n_voltages || ++ selector < rdev->desc->linear_min_sel) + return -EINVAL; + + return rdev->desc->volt_table[selector]; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/128-regulator-core-do-not-continue-if-selector-match.patch b/target/linux/at91/patches-5.10/128-regulator-core-do-not-continue-if-selector-match.patch new file mode 100644 index 0000000000..f3d53bc135 --- /dev/null +++ b/target/linux/at91/patches-5.10/128-regulator-core-do-not-continue-if-selector-match.patch @@ -0,0 +1,31 @@ +From 42b56e8bd343f34d5f2a601d8a8a05d8c861c08c Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Fri, 13 Nov 2020 19:56:04 +0200 +Subject: [PATCH 128/247] regulator: core: do not continue if selector match + +Do not continue if selector has already been located. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/1605290164-11556-1-git-send-email-claudiu.beznea@microchip.com +Signed-off-by: Mark Brown <broonie@kernel.org> +--- + drivers/regulator/core.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index dfdd42b9d773..0b7a23cdbcac 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -4063,6 +4063,9 @@ int regulator_set_voltage_time(struct regulator *regulator, + if (i < rdev->desc->linear_min_sel) + continue; + ++ if (old_sel >= 0 && new_sel >= 0) ++ break; ++ + voltage = regulator_list_voltage(regulator, i); + if (voltage < 0) + return -EINVAL; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/129-regulator-core-return-zero-for-selectors-lower-than-.patch b/target/linux/at91/patches-5.10/129-regulator-core-return-zero-for-selectors-lower-than-.patch new file mode 100644 index 0000000000..b44fa547e1 --- /dev/null +++ b/target/linux/at91/patches-5.10/129-regulator-core-return-zero-for-selectors-lower-than-.patch @@ -0,0 +1,71 @@ +From 0e933ffc049a0e181b5a6c3af1933976d6959ba9 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Wed, 25 Nov 2020 19:25:47 +0200 +Subject: [PATCH 129/247] regulator: core: return zero for selectors lower than + linear_min_sel + +Selectors lower than linear_min_sel should not be considered invalid. +Thus return zero in case _regulator_list_voltage(), +regulator_list_hardware_vsel() or regulator_list_voltage_table() +receives such selectors as argument. + +Fixes: bdcd1177578c ("regulator: core: validate selector against linear_min_sel") +Reported-by: Jon Hunter <jonathanh@nvidia.com> +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/1606325147-606-1-git-send-email-claudiu.beznea@microchip.com +Signed-off-by: Mark Brown <broonie@kernel.org> +--- + drivers/regulator/core.c | 10 ++++++---- + drivers/regulator/helpers.c | 5 +++-- + 2 files changed, 9 insertions(+), 6 deletions(-) + +diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c +index 0b7a23cdbcac..65ecf872b4e0 100644 +--- a/drivers/regulator/core.c ++++ b/drivers/regulator/core.c +@@ -2984,9 +2984,10 @@ static int _regulator_list_voltage(struct regulator_dev *rdev, + return rdev->desc->fixed_uV; + + if (ops->list_voltage) { +- if (selector >= rdev->desc->n_voltages || +- selector < rdev->desc->linear_min_sel) ++ if (selector >= rdev->desc->n_voltages) + return -EINVAL; ++ if (selector < rdev->desc->linear_min_sel) ++ return 0; + if (lock) + regulator_lock(rdev); + ret = ops->list_voltage(rdev, selector); +@@ -3136,9 +3137,10 @@ int regulator_list_hardware_vsel(struct regulator *regulator, + struct regulator_dev *rdev = regulator->rdev; + const struct regulator_ops *ops = rdev->desc->ops; + +- if (selector >= rdev->desc->n_voltages || +- selector < rdev->desc->linear_min_sel) ++ if (selector >= rdev->desc->n_voltages) + return -EINVAL; ++ if (selector < rdev->desc->linear_min_sel) ++ return 0; + if (ops->set_voltage_sel != regulator_set_voltage_sel_regmap) + return -EOPNOTSUPP; + +diff --git a/drivers/regulator/helpers.c b/drivers/regulator/helpers.c +index 974f1a63993d..f42b394a0c46 100644 +--- a/drivers/regulator/helpers.c ++++ b/drivers/regulator/helpers.c +@@ -647,9 +647,10 @@ int regulator_list_voltage_table(struct regulator_dev *rdev, + return -EINVAL; + } + +- if (selector >= rdev->desc->n_voltages || +- selector < rdev->desc->linear_min_sel) ++ if (selector >= rdev->desc->n_voltages) + return -EINVAL; ++ if (selector < rdev->desc->linear_min_sel) ++ return 0; + + return rdev->desc->volt_table[selector]; + } +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/130-regulator-mcp16502-lpm-pin-can-be-optional-on-some-p.patch b/target/linux/at91/patches-5.10/130-regulator-mcp16502-lpm-pin-can-be-optional-on-some-p.patch new file mode 100644 index 0000000000..9323fedaf7 --- /dev/null +++ b/target/linux/at91/patches-5.10/130-regulator-mcp16502-lpm-pin-can-be-optional-on-some-p.patch @@ -0,0 +1,35 @@ +From 763fe72f607d4e929d2c710c88e5c6978dd6ad97 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 7 Jan 2021 16:15:26 +0200 +Subject: [PATCH 130/247] regulator: mcp16502: lpm pin can be optional on some + platforms + +On some platform (e.g. SAMA7G5) LPM pin should be optional as it can +be controlled explicitly (via shutdown controller registers) in the +platform specific power saving code to decrease the power consumption +while suspended as this SoC pin may be connected to other devices that +could take power saving actions based on its value. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/1610028927-9842-3-git-send-email-claudiu.beznea@microchip.com +Signed-off-by: Mark Brown <broonie@kernel.org> +--- + drivers/regulator/mcp16502.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/regulator/mcp16502.c b/drivers/regulator/mcp16502.c +index 74ad92dc664a..88c6bd5b6c78 100644 +--- a/drivers/regulator/mcp16502.c ++++ b/drivers/regulator/mcp16502.c +@@ -550,7 +550,7 @@ static int mcp16502_probe(struct i2c_client *client, + config.regmap = rmap; + config.driver_data = mcp; + +- mcp->lpm = devm_gpiod_get(dev, "lpm", GPIOD_OUT_LOW); ++ mcp->lpm = devm_gpiod_get_optional(dev, "lpm", GPIOD_OUT_LOW); + if (IS_ERR(mcp->lpm)) { + dev_err(dev, "failed to get lpm pin: %ld\n", PTR_ERR(mcp->lpm)); + return PTR_ERR(mcp->lpm); +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/131-pinctrl-at91-pio4-add-support-for-fewer-lines-on-las.patch b/target/linux/at91/patches-5.10/131-pinctrl-at91-pio4-add-support-for-fewer-lines-on-las.patch new file mode 100644 index 0000000000..0ca118a24d --- /dev/null +++ b/target/linux/at91/patches-5.10/131-pinctrl-at91-pio4-add-support-for-fewer-lines-on-las.patch @@ -0,0 +1,75 @@ +From 7cb1dad7a7dfe4cfe55ebe86930dd6aef0de66b4 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Fri, 13 Nov 2020 15:24:29 +0200 +Subject: [PATCH 131/247] pinctrl: at91-pio4: add support for fewer lines on + last PIO bank + +Some products, like sama7g5, do not have a full last bank of PIO lines. +In this case for example, sama7g5 only has 8 lines for the PE bank. +PA0-31, PB0-31, PC0-31, PD0-31, PE0-7, in total 136 lines. +To cope with this situation, added a data attribute that is product dependent, +to specify the number of lines of the last bank. +In case this number is different from the macro ATMEL_PIO_NPINS_PER_BANK, +adjust the total number of lines accordingly. +This will avoid advertising 160 lines instead of the actual 136, as this +product supports, and to avoid reading/writing to invalid register addresses. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Acked-by: Ludovic Desroches <ludovic.desroches@microchip.com> +Link: https://lore.kernel.org/r/20201113132429.420940-1-eugen.hristev@microchip.com +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +--- + drivers/pinctrl/pinctrl-at91-pio4.c | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c +index 578b387100d9..d267367d94b9 100644 +--- a/drivers/pinctrl/pinctrl-at91-pio4.c ++++ b/drivers/pinctrl/pinctrl-at91-pio4.c +@@ -71,8 +71,15 @@ + /* Custom pinconf parameters */ + #define ATMEL_PIN_CONFIG_DRIVE_STRENGTH (PIN_CONFIG_END + 1) + ++/** ++ * struct atmel_pioctrl_data - Atmel PIO controller (pinmux + gpio) data struct ++ * @nbanks: number of PIO banks ++ * @last_bank_count: number of lines in the last bank (can be less than ++ * the rest of the banks). ++ */ + struct atmel_pioctrl_data { + unsigned nbanks; ++ unsigned last_bank_count; + }; + + struct atmel_group { +@@ -980,11 +987,13 @@ static const struct dev_pm_ops atmel_pctrl_pm_ops = { + * We can have up to 16 banks. + */ + static const struct atmel_pioctrl_data atmel_sama5d2_pioctrl_data = { +- .nbanks = 4, ++ .nbanks = 4, ++ .last_bank_count = ATMEL_PIO_NPINS_PER_BANK, + }; + + static const struct atmel_pioctrl_data microchip_sama7g5_pioctrl_data = { +- .nbanks = 5, ++ .nbanks = 5, ++ .last_bank_count = 8, /* sama7g5 has only PE0 to PE7 */ + }; + + static const struct of_device_id atmel_pctrl_of_match[] = { +@@ -1025,6 +1034,11 @@ static int atmel_pinctrl_probe(struct platform_device *pdev) + atmel_pioctrl_data = match->data; + atmel_pioctrl->nbanks = atmel_pioctrl_data->nbanks; + atmel_pioctrl->npins = atmel_pioctrl->nbanks * ATMEL_PIO_NPINS_PER_BANK; ++ /* if last bank has limited number of pins, adjust accordingly */ ++ if (atmel_pioctrl_data->last_bank_count != ATMEL_PIO_NPINS_PER_BANK) { ++ atmel_pioctrl->npins -= ATMEL_PIO_NPINS_PER_BANK; ++ atmel_pioctrl->npins += atmel_pioctrl_data->last_bank_count; ++ } + + atmel_pioctrl->reg_base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(atmel_pioctrl->reg_base)) +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/132-dmaengine-at_xdmac-adapt-perid-for-mem2mem-operation.patch b/target/linux/at91/patches-5.10/132-dmaengine-at_xdmac-adapt-perid-for-mem2mem-operation.patch new file mode 100644 index 0000000000..27c95082e3 --- /dev/null +++ b/target/linux/at91/patches-5.10/132-dmaengine-at_xdmac-adapt-perid-for-mem2mem-operation.patch @@ -0,0 +1,55 @@ +From 1dccaa4c1e99cd8bd27684a2c87ec806d426c088 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Fri, 16 Oct 2020 12:37:25 +0300 +Subject: [PATCH 132/247] dmaengine: at_xdmac: adapt perid for mem2mem + operations + +The PERID in the CC register for mem2mem operations must match an unused +PERID. +The PERID field is 7 bits, but the selected value is 0x3f. +On later products we can have more reserved PERIDs for actual peripherals, +thus this needs to be increased to maximum size. +Changing the value to 0x7f, which is the maximum for 7 bits field. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Reviewed-by: Tudor Ambarus <tudor.ambarus@microchip.com> +Link: https://lore.kernel.org/r/20201016093725.289880-1-eugen.hristev@microchip.com +Signed-off-by: Vinod Koul <vkoul@kernel.org> +--- + drivers/dma/at_xdmac.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c +index 90afba0b36fe..85fe260ccd07 100644 +--- a/drivers/dma/at_xdmac.c ++++ b/drivers/dma/at_xdmac.c +@@ -865,7 +865,7 @@ at_xdmac_interleaved_queue_desc(struct dma_chan *chan, + * match the one of another channel. If not, it could lead to spurious + * flag status. + */ +- u32 chan_cc = AT_XDMAC_CC_PERID(0x3f) ++ u32 chan_cc = AT_XDMAC_CC_PERID(0x7f) + | AT_XDMAC_CC_DIF(0) + | AT_XDMAC_CC_SIF(0) + | AT_XDMAC_CC_MBSIZE_SIXTEEN +@@ -1047,7 +1047,7 @@ at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, + * match the one of another channel. If not, it could lead to spurious + * flag status. + */ +- u32 chan_cc = AT_XDMAC_CC_PERID(0x3f) ++ u32 chan_cc = AT_XDMAC_CC_PERID(0x7f) + | AT_XDMAC_CC_DAM_INCREMENTED_AM + | AT_XDMAC_CC_SAM_INCREMENTED_AM + | AT_XDMAC_CC_DIF(0) +@@ -1153,7 +1153,7 @@ static struct at_xdmac_desc *at_xdmac_memset_create_desc(struct dma_chan *chan, + * match the one of another channel. If not, it could lead to spurious + * flag status. + */ +- u32 chan_cc = AT_XDMAC_CC_PERID(0x3f) ++ u32 chan_cc = AT_XDMAC_CC_PERID(0x7f) + | AT_XDMAC_CC_DAM_UBS_AM + | AT_XDMAC_CC_SAM_INCREMENTED_AM + | AT_XDMAC_CC_DIF(0) +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/133-dmaengine-at_xdmac-add-support-for-sama7g5-based-at_.patch b/target/linux/at91/patches-5.10/133-dmaengine-at_xdmac-add-support-for-sama7g5-based-at_.patch new file mode 100644 index 0000000000..5ddc90c044 --- /dev/null +++ b/target/linux/at91/patches-5.10/133-dmaengine-at_xdmac-add-support-for-sama7g5-based-at_.patch @@ -0,0 +1,285 @@ +From 613af756b93fe005d9db11ea26fd0318f239d5a2 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Fri, 16 Oct 2020 12:38:50 +0300 +Subject: [PATCH 133/247] dmaengine: at_xdmac: add support for sama7g5 based + at_xdmac + +SAMA7G5 SoC uses a slightly different variant of the AT_XDMAC. +Added support by a new compatible and a layout struct that copes +to the specific version considering the compatible string. +Only the differences in register map are present in the layout struct. +I reworked the register access for this part that has the differences. +Also the Source/Destination Interface bits are no longer valid for this +variant of the XDMAC. Thus, the layout also has a bool for specifying +whether these bits are required or not. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Link: https://lore.kernel.org/r/20201016093850.290053-1-eugen.hristev@microchip.com +Signed-off-by: Vinod Koul <vkoul@kernel.org> +--- + drivers/dma/at_xdmac.c | 110 +++++++++++++++++++++++++++++++---------- + 1 file changed, 84 insertions(+), 26 deletions(-) + +diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c +index 85fe260ccd07..2b096ea04018 100644 +--- a/drivers/dma/at_xdmac.c ++++ b/drivers/dma/at_xdmac.c +@@ -38,13 +38,6 @@ + #define AT_XDMAC_GE 0x1C /* Global Channel Enable Register */ + #define AT_XDMAC_GD 0x20 /* Global Channel Disable Register */ + #define AT_XDMAC_GS 0x24 /* Global Channel Status Register */ +-#define AT_XDMAC_GRS 0x28 /* Global Channel Read Suspend Register */ +-#define AT_XDMAC_GWS 0x2C /* Global Write Suspend Register */ +-#define AT_XDMAC_GRWS 0x30 /* Global Channel Read Write Suspend Register */ +-#define AT_XDMAC_GRWR 0x34 /* Global Channel Read Write Resume Register */ +-#define AT_XDMAC_GSWR 0x38 /* Global Channel Software Request Register */ +-#define AT_XDMAC_GSWS 0x3C /* Global channel Software Request Status Register */ +-#define AT_XDMAC_GSWF 0x40 /* Global Channel Software Flush Request Register */ + #define AT_XDMAC_VERSION 0xFFC /* XDMAC Version Register */ + + /* Channel relative registers offsets */ +@@ -151,8 +144,6 @@ + #define AT_XDMAC_CSUS 0x30 /* Channel Source Microblock Stride */ + #define AT_XDMAC_CDUS 0x34 /* Channel Destination Microblock Stride */ + +-#define AT_XDMAC_CHAN_REG_BASE 0x50 /* Channel registers base address */ +- + /* Microblock control members */ + #define AT_XDMAC_MBR_UBC_UBLEN_MAX 0xFFFFFFUL /* Maximum Microblock Length */ + #define AT_XDMAC_MBR_UBC_NDE (0x1 << 24) /* Next Descriptor Enable */ +@@ -180,6 +171,27 @@ enum atc_status { + AT_XDMAC_CHAN_IS_PAUSED, + }; + ++struct at_xdmac_layout { ++ /* Global Channel Read Suspend Register */ ++ u8 grs; ++ /* Global Write Suspend Register */ ++ u8 gws; ++ /* Global Channel Read Write Suspend Register */ ++ u8 grws; ++ /* Global Channel Read Write Resume Register */ ++ u8 grwr; ++ /* Global Channel Software Request Register */ ++ u8 gswr; ++ /* Global channel Software Request Status Register */ ++ u8 gsws; ++ /* Global Channel Software Flush Request Register */ ++ u8 gswf; ++ /* Channel reg base */ ++ u8 chan_cc_reg_base; ++ /* Source/Destination Interface must be specified or not */ ++ bool sdif; ++}; ++ + /* ----- Channels ----- */ + struct at_xdmac_chan { + struct dma_chan chan; +@@ -213,6 +225,7 @@ struct at_xdmac { + struct clk *clk; + u32 save_gim; + struct dma_pool *at_xdmac_desc_pool; ++ const struct at_xdmac_layout *layout; + struct at_xdmac_chan chan[]; + }; + +@@ -245,9 +258,33 @@ struct at_xdmac_desc { + struct list_head xfer_node; + } __aligned(sizeof(u64)); + ++static const struct at_xdmac_layout at_xdmac_sama5d4_layout = { ++ .grs = 0x28, ++ .gws = 0x2C, ++ .grws = 0x30, ++ .grwr = 0x34, ++ .gswr = 0x38, ++ .gsws = 0x3C, ++ .gswf = 0x40, ++ .chan_cc_reg_base = 0x50, ++ .sdif = true, ++}; ++ ++static const struct at_xdmac_layout at_xdmac_sama7g5_layout = { ++ .grs = 0x30, ++ .gws = 0x38, ++ .grws = 0x40, ++ .grwr = 0x44, ++ .gswr = 0x48, ++ .gsws = 0x4C, ++ .gswf = 0x50, ++ .chan_cc_reg_base = 0x60, ++ .sdif = false, ++}; ++ + static inline void __iomem *at_xdmac_chan_reg_base(struct at_xdmac *atxdmac, unsigned int chan_nb) + { +- return atxdmac->regs + (AT_XDMAC_CHAN_REG_BASE + chan_nb * 0x40); ++ return atxdmac->regs + (atxdmac->layout->chan_cc_reg_base + chan_nb * 0x40); + } + + #define at_xdmac_read(atxdmac, reg) readl_relaxed((atxdmac)->regs + (reg)) +@@ -343,8 +380,10 @@ static void at_xdmac_start_xfer(struct at_xdmac_chan *atchan, + first->active_xfer = true; + + /* Tell xdmac where to get the first descriptor. */ +- reg = AT_XDMAC_CNDA_NDA(first->tx_dma_desc.phys) +- | AT_XDMAC_CNDA_NDAIF(atchan->memif); ++ reg = AT_XDMAC_CNDA_NDA(first->tx_dma_desc.phys); ++ if (atxdmac->layout->sdif) ++ reg |= AT_XDMAC_CNDA_NDAIF(atchan->memif); ++ + at_xdmac_chan_write(atchan, AT_XDMAC_CNDA, reg); + + /* +@@ -539,6 +578,7 @@ static int at_xdmac_compute_chan_conf(struct dma_chan *chan, + enum dma_transfer_direction direction) + { + struct at_xdmac_chan *atchan = to_at_xdmac_chan(chan); ++ struct at_xdmac *atxdmac = to_at_xdmac(atchan->chan.device); + int csize, dwidth; + + if (direction == DMA_DEV_TO_MEM) { +@@ -546,12 +586,14 @@ static int at_xdmac_compute_chan_conf(struct dma_chan *chan, + AT91_XDMAC_DT_PERID(atchan->perid) + | AT_XDMAC_CC_DAM_INCREMENTED_AM + | AT_XDMAC_CC_SAM_FIXED_AM +- | AT_XDMAC_CC_DIF(atchan->memif) +- | AT_XDMAC_CC_SIF(atchan->perif) + | AT_XDMAC_CC_SWREQ_HWR_CONNECTED + | AT_XDMAC_CC_DSYNC_PER2MEM + | AT_XDMAC_CC_MBSIZE_SIXTEEN + | AT_XDMAC_CC_TYPE_PER_TRAN; ++ if (atxdmac->layout->sdif) ++ atchan->cfg |= AT_XDMAC_CC_DIF(atchan->memif) | ++ AT_XDMAC_CC_SIF(atchan->perif); ++ + csize = ffs(atchan->sconfig.src_maxburst) - 1; + if (csize < 0) { + dev_err(chan2dev(chan), "invalid src maxburst value\n"); +@@ -569,12 +611,14 @@ static int at_xdmac_compute_chan_conf(struct dma_chan *chan, + AT91_XDMAC_DT_PERID(atchan->perid) + | AT_XDMAC_CC_DAM_FIXED_AM + | AT_XDMAC_CC_SAM_INCREMENTED_AM +- | AT_XDMAC_CC_DIF(atchan->perif) +- | AT_XDMAC_CC_SIF(atchan->memif) + | AT_XDMAC_CC_SWREQ_HWR_CONNECTED + | AT_XDMAC_CC_DSYNC_MEM2PER + | AT_XDMAC_CC_MBSIZE_SIXTEEN + | AT_XDMAC_CC_TYPE_PER_TRAN; ++ if (atxdmac->layout->sdif) ++ atchan->cfg |= AT_XDMAC_CC_DIF(atchan->perif) | ++ AT_XDMAC_CC_SIF(atchan->memif); ++ + csize = ffs(atchan->sconfig.dst_maxburst) - 1; + if (csize < 0) { + dev_err(chan2dev(chan), "invalid src maxburst value\n"); +@@ -864,10 +908,12 @@ at_xdmac_interleaved_queue_desc(struct dma_chan *chan, + * ERRATA: Even if useless for memory transfers, the PERID has to not + * match the one of another channel. If not, it could lead to spurious + * flag status. ++ * For SAMA7G5x case, the SIF and DIF fields are no longer used. ++ * Thus, no need to have the SIF/DIF interfaces here. ++ * For SAMA5D4x and SAMA5D2x the SIF and DIF are already configured as ++ * zero. + */ + u32 chan_cc = AT_XDMAC_CC_PERID(0x7f) +- | AT_XDMAC_CC_DIF(0) +- | AT_XDMAC_CC_SIF(0) + | AT_XDMAC_CC_MBSIZE_SIXTEEN + | AT_XDMAC_CC_TYPE_MEM_TRAN; + +@@ -1046,12 +1092,14 @@ at_xdmac_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, + * ERRATA: Even if useless for memory transfers, the PERID has to not + * match the one of another channel. If not, it could lead to spurious + * flag status. ++ * For SAMA7G5x case, the SIF and DIF fields are no longer used. ++ * Thus, no need to have the SIF/DIF interfaces here. ++ * For SAMA5D4x and SAMA5D2x the SIF and DIF are already configured as ++ * zero. + */ + u32 chan_cc = AT_XDMAC_CC_PERID(0x7f) + | AT_XDMAC_CC_DAM_INCREMENTED_AM + | AT_XDMAC_CC_SAM_INCREMENTED_AM +- | AT_XDMAC_CC_DIF(0) +- | AT_XDMAC_CC_SIF(0) + | AT_XDMAC_CC_MBSIZE_SIXTEEN + | AT_XDMAC_CC_TYPE_MEM_TRAN; + unsigned long irqflags; +@@ -1152,12 +1200,14 @@ static struct at_xdmac_desc *at_xdmac_memset_create_desc(struct dma_chan *chan, + * ERRATA: Even if useless for memory transfers, the PERID has to not + * match the one of another channel. If not, it could lead to spurious + * flag status. ++ * For SAMA7G5x case, the SIF and DIF fields are no longer used. ++ * Thus, no need to have the SIF/DIF interfaces here. ++ * For SAMA5D4x and SAMA5D2x the SIF and DIF are already configured as ++ * zero. + */ + u32 chan_cc = AT_XDMAC_CC_PERID(0x7f) + | AT_XDMAC_CC_DAM_UBS_AM + | AT_XDMAC_CC_SAM_INCREMENTED_AM +- | AT_XDMAC_CC_DIF(0) +- | AT_XDMAC_CC_SIF(0) + | AT_XDMAC_CC_MBSIZE_SIXTEEN + | AT_XDMAC_CC_MEMSET_HW_MODE + | AT_XDMAC_CC_TYPE_MEM_TRAN; +@@ -1436,7 +1486,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + mask = AT_XDMAC_CC_TYPE | AT_XDMAC_CC_DSYNC; + value = AT_XDMAC_CC_TYPE_PER_TRAN | AT_XDMAC_CC_DSYNC_PER2MEM; + if ((desc->lld.mbr_cfg & mask) == value) { +- at_xdmac_write(atxdmac, AT_XDMAC_GSWF, atchan->mask); ++ at_xdmac_write(atxdmac, atxdmac->layout->gswf, atchan->mask); + while (!(at_xdmac_chan_read(atchan, AT_XDMAC_CIS) & AT_XDMAC_CIS_FIS)) + cpu_relax(); + } +@@ -1494,7 +1544,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie, + * FIFO flush ensures that data are really written. + */ + if ((desc->lld.mbr_cfg & mask) == value) { +- at_xdmac_write(atxdmac, AT_XDMAC_GSWF, atchan->mask); ++ at_xdmac_write(atxdmac, atxdmac->layout->gswf, atchan->mask); + while (!(at_xdmac_chan_read(atchan, AT_XDMAC_CIS) & AT_XDMAC_CIS_FIS)) + cpu_relax(); + } +@@ -1760,7 +1810,7 @@ static int at_xdmac_device_pause(struct dma_chan *chan) + return 0; + + spin_lock_irqsave(&atchan->lock, flags); +- at_xdmac_write(atxdmac, AT_XDMAC_GRWS, atchan->mask); ++ at_xdmac_write(atxdmac, atxdmac->layout->grws, atchan->mask); + while (at_xdmac_chan_read(atchan, AT_XDMAC_CC) + & (AT_XDMAC_CC_WRIP | AT_XDMAC_CC_RDIP)) + cpu_relax(); +@@ -1783,7 +1833,7 @@ static int at_xdmac_device_resume(struct dma_chan *chan) + return 0; + } + +- at_xdmac_write(atxdmac, AT_XDMAC_GRWR, atchan->mask); ++ at_xdmac_write(atxdmac, atxdmac->layout->grwr, atchan->mask); + clear_bit(AT_XDMAC_CHAN_IS_PAUSED, &atchan->status); + spin_unlock_irqrestore(&atchan->lock, flags); + +@@ -1985,6 +2035,10 @@ static int at_xdmac_probe(struct platform_device *pdev) + atxdmac->regs = base; + atxdmac->irq = irq; + ++ atxdmac->layout = of_device_get_match_data(&pdev->dev); ++ if (!atxdmac->layout) ++ return -ENODEV; ++ + atxdmac->clk = devm_clk_get(&pdev->dev, "dma_clk"); + if (IS_ERR(atxdmac->clk)) { + dev_err(&pdev->dev, "can't get dma_clk\n"); +@@ -2127,6 +2181,10 @@ static const struct dev_pm_ops atmel_xdmac_dev_pm_ops = { + static const struct of_device_id atmel_xdmac_dt_ids[] = { + { + .compatible = "atmel,sama5d4-dma", ++ .data = &at_xdmac_sama5d4_layout, ++ }, { ++ .compatible = "microchip,sama7g5-dma", ++ .data = &at_xdmac_sama7g5_layout, + }, { + /* sentinel */ + } +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/134-dmaengine-at_xdmac-add-AXI-priority-support-and-reco.patch b/target/linux/at91/patches-5.10/134-dmaengine-at_xdmac-add-AXI-priority-support-and-reco.patch new file mode 100644 index 0000000000..d519853363 --- /dev/null +++ b/target/linux/at91/patches-5.10/134-dmaengine-at_xdmac-add-AXI-priority-support-and-reco.patch @@ -0,0 +1,118 @@ +From 4833d6ea13a6d2c44a91247991a82c3eb6c1613e Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Fri, 16 Oct 2020 12:39:18 +0300 +Subject: [PATCH 134/247] dmaengine: at_xdmac: add AXI priority support and + recommended settings + +The sama7g5 version of the XDMAC supports priority configuration and +outstanding capabilities. +Add defines for the specific registers for this configuration, together +with recommended settings. +However the settings are very different if the XDMAC is a mem2mem or a +per2mem controller. +Thus, we need to differentiate according to device tree property. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Link: https://lore.kernel.org/r/20201016093918.290137-1-eugen.hristev@microchip.com +Signed-off-by: Vinod Koul <vkoul@kernel.org> +--- + drivers/dma/at_xdmac.c | 47 ++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 47 insertions(+) + +diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c +index 2b096ea04018..8ca86d09b255 100644 +--- a/drivers/dma/at_xdmac.c ++++ b/drivers/dma/at_xdmac.c +@@ -30,7 +30,24 @@ + #define AT_XDMAC_FIFO_SZ(i) (((i) >> 5) & 0x7FF) /* Number of Bytes */ + #define AT_XDMAC_NB_REQ(i) ((((i) >> 16) & 0x3F) + 1) /* Number of Peripheral Requests Minus One */ + #define AT_XDMAC_GCFG 0x04 /* Global Configuration Register */ ++#define AT_XDMAC_WRHP(i) (((i) & 0xF) << 4) ++#define AT_XDMAC_WRMP(i) (((i) & 0xF) << 8) ++#define AT_XDMAC_WRLP(i) (((i) & 0xF) << 12) ++#define AT_XDMAC_RDHP(i) (((i) & 0xF) << 16) ++#define AT_XDMAC_RDMP(i) (((i) & 0xF) << 20) ++#define AT_XDMAC_RDLP(i) (((i) & 0xF) << 24) ++#define AT_XDMAC_RDSG(i) (((i) & 0xF) << 28) ++#define AT_XDMAC_GCFG_M2M (AT_XDMAC_RDLP(0xF) | AT_XDMAC_WRLP(0xF)) ++#define AT_XDMAC_GCFG_P2M (AT_XDMAC_RDSG(0x1) | AT_XDMAC_RDHP(0x3) | \ ++ AT_XDMAC_WRHP(0x5)) + #define AT_XDMAC_GWAC 0x08 /* Global Weighted Arbiter Configuration Register */ ++#define AT_XDMAC_PW0(i) (((i) & 0xF) << 0) ++#define AT_XDMAC_PW1(i) (((i) & 0xF) << 4) ++#define AT_XDMAC_PW2(i) (((i) & 0xF) << 8) ++#define AT_XDMAC_PW3(i) (((i) & 0xF) << 12) ++#define AT_XDMAC_GWAC_M2M 0 ++#define AT_XDMAC_GWAC_P2M (AT_XDMAC_PW0(0xF) | AT_XDMAC_PW2(0xF)) ++ + #define AT_XDMAC_GIE 0x0C /* Global Interrupt Enable Register */ + #define AT_XDMAC_GID 0x10 /* Global Interrupt Disable Register */ + #define AT_XDMAC_GIM 0x14 /* Global Interrupt Mask Register */ +@@ -190,6 +207,8 @@ struct at_xdmac_layout { + u8 chan_cc_reg_base; + /* Source/Destination Interface must be specified or not */ + bool sdif; ++ /* AXI queue priority configuration supported */ ++ bool axi_config; + }; + + /* ----- Channels ----- */ +@@ -268,6 +287,7 @@ static const struct at_xdmac_layout at_xdmac_sama5d4_layout = { + .gswf = 0x40, + .chan_cc_reg_base = 0x50, + .sdif = true, ++ .axi_config = false, + }; + + static const struct at_xdmac_layout at_xdmac_sama7g5_layout = { +@@ -280,6 +300,7 @@ static const struct at_xdmac_layout at_xdmac_sama7g5_layout = { + .gswf = 0x50, + .chan_cc_reg_base = 0x60, + .sdif = false, ++ .axi_config = true, + }; + + static inline void __iomem *at_xdmac_chan_reg_base(struct at_xdmac *atxdmac, unsigned int chan_nb) +@@ -1996,6 +2017,30 @@ static int atmel_xdmac_resume(struct device *dev) + } + #endif /* CONFIG_PM_SLEEP */ + ++static void at_xdmac_axi_config(struct platform_device *pdev) ++{ ++ struct at_xdmac *atxdmac = (struct at_xdmac *)platform_get_drvdata(pdev); ++ bool dev_m2m = false; ++ u32 dma_requests; ++ ++ if (!atxdmac->layout->axi_config) ++ return; /* Not supported */ ++ ++ if (!of_property_read_u32(pdev->dev.of_node, "dma-requests", ++ &dma_requests)) { ++ dev_info(&pdev->dev, "controller in mem2mem mode.\n"); ++ dev_m2m = true; ++ } ++ ++ if (dev_m2m) { ++ at_xdmac_write(atxdmac, AT_XDMAC_GCFG, AT_XDMAC_GCFG_M2M); ++ at_xdmac_write(atxdmac, AT_XDMAC_GWAC, AT_XDMAC_GWAC_M2M); ++ } else { ++ at_xdmac_write(atxdmac, AT_XDMAC_GCFG, AT_XDMAC_GCFG_P2M); ++ at_xdmac_write(atxdmac, AT_XDMAC_GWAC, AT_XDMAC_GWAC_P2M); ++ } ++} ++ + static int at_xdmac_probe(struct platform_device *pdev) + { + struct at_xdmac *atxdmac; +@@ -2140,6 +2185,8 @@ static int at_xdmac_probe(struct platform_device *pdev) + dev_info(&pdev->dev, "%d channels, mapped at 0x%p\n", + nr_channels, atxdmac->regs); + ++ at_xdmac_axi_config(pdev); ++ + return 0; + + err_dma_unregister: +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/135-net-macb-Correct-usage-of-MACB_CAPS_CLK_HW_CHG-flag.patch b/target/linux/at91/patches-5.10/135-net-macb-Correct-usage-of-MACB_CAPS_CLK_HW_CHG-flag.patch new file mode 100644 index 0000000000..2ed825de61 --- /dev/null +++ b/target/linux/at91/patches-5.10/135-net-macb-Correct-usage-of-MACB_CAPS_CLK_HW_CHG-flag.patch @@ -0,0 +1,50 @@ +From 982347f757b85ef526afaf243867ddd515475e1b Mon Sep 17 00:00:00 2001 +From: Charles Keepax <ckeepax@opensource.cirrus.com> +Date: Mon, 4 Jan 2021 10:38:02 +0000 +Subject: [PATCH 135/247] net: macb: Correct usage of MACB_CAPS_CLK_HW_CHG flag + +A new flag MACB_CAPS_CLK_HW_CHG was added and all callers of +macb_set_tx_clk were gated on the presence of this flag. + +- if (!clk) ++ if (!bp->tx_clk || !(bp->caps & MACB_CAPS_CLK_HW_CHG)) + +However the flag was not added to anything other than the new +sama7g5_gem, turning that function call into a no op for all other +systems. This breaks the networking on Zynq. + +The commit message adding this states: a new capability so that +macb_set_tx_clock() to not be called for IPs having this +capability + +This strongly implies that present of the flag was intended to skip +the function not absence of the flag. Update the if statement to +this effect, which repairs the existing users. + +Fixes: daafa1d33cc9 ("net: macb: add capability to not set the clock rate") +Suggested-by: Andrew Lunn <andrew@lunn.ch> +Signed-off-by: Charles Keepax <ckeepax@opensource.cirrus.com> +Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Reviewed-by: Andrew Lunn <andrew@lunn.ch> +Link: https://lore.kernel.org/r/20210104103802.13091-1-ckeepax@opensource.cirrus.com +Signed-off-by: Jakub Kicinski <kuba@kernel.org> +--- + drivers/net/ethernet/cadence/macb_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c +index 4ce302e03735..d5bd640d3fa4 100644 +--- a/drivers/net/ethernet/cadence/macb_main.c ++++ b/drivers/net/ethernet/cadence/macb_main.c +@@ -464,7 +464,7 @@ static void macb_set_tx_clk(struct macb *bp, int speed) + { + long ferr, rate, rate_rounded; + +- if (!bp->tx_clk || !(bp->caps & MACB_CAPS_CLK_HW_CHG)) ++ if (!bp->tx_clk || (bp->caps & MACB_CAPS_CLK_HW_CHG)) + return; + + switch (speed) { +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/136-ARM-at91-sam9x60-SiP-types-added-to-soc-description.patch b/target/linux/at91/patches-5.10/136-ARM-at91-sam9x60-SiP-types-added-to-soc-description.patch new file mode 100644 index 0000000000..692a1d487b --- /dev/null +++ b/target/linux/at91/patches-5.10/136-ARM-at91-sam9x60-SiP-types-added-to-soc-description.patch @@ -0,0 +1,50 @@ +From a2eda4ef1e3d617cdd669e256e45e969fab62398 Mon Sep 17 00:00:00 2001 +From: Kai Stuhlemmer <kai.stuhlemmer@ebee.de> +Date: Thu, 8 Oct 2020 14:50:28 +0200 +Subject: [PATCH 136/247] ARM: at91: sam9x60 SiP types added to soc description + +Adding SAM9X60 SIP variants to the soc description list. + +Signed-off-by: Kai Stuhlemmer <kai.stuhlemmer@ebee.de> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> +Link: https://lore.kernel.org/r/20201008125028.21071-1-nicolas.ferre@microchip.com +--- + drivers/soc/atmel/soc.c | 6 ++++++ + drivers/soc/atmel/soc.h | 3 +++ + 2 files changed, 9 insertions(+) + +diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c +index 5d06ee70a36b..698d21f50516 100644 +--- a/drivers/soc/atmel/soc.c ++++ b/drivers/soc/atmel/soc.c +@@ -69,6 +69,12 @@ static const struct at91_soc __initconst socs[] = { + #endif + #ifdef CONFIG_SOC_SAM9X60 + AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_EXID_MATCH, "sam9x60", "sam9x60"), ++ AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_D5M_EXID_MATCH, ++ "sam9x60 64MiB DDR2 SiP", "sam9x60"), ++ AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_D1G_EXID_MATCH, ++ "sam9x60 128MiB DDR2 SiP", "sam9x60"), ++ AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_D6K_EXID_MATCH, ++ "sam9x60 8MiB SDRAM SiP", "sam9x60"), + #endif + #ifdef CONFIG_SOC_SAMA5 + AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D21CU_EXID_MATCH, +diff --git a/drivers/soc/atmel/soc.h b/drivers/soc/atmel/soc.h +index ee652e4841a5..5849846a69d6 100644 +--- a/drivers/soc/atmel/soc.h ++++ b/drivers/soc/atmel/soc.h +@@ -60,6 +60,9 @@ at91_soc_init(const struct at91_soc *socs); + #define AT91SAM9CN11_EXID_MATCH 0x00000009 + + #define SAM9X60_EXID_MATCH 0x00000000 ++#define SAM9X60_D5M_EXID_MATCH 0x00000001 ++#define SAM9X60_D1G_EXID_MATCH 0x00000010 ++#define SAM9X60_D6K_EXID_MATCH 0x00000011 + + #define AT91SAM9XE128_CIDR_MATCH 0x329973a0 + #define AT91SAM9XE256_CIDR_MATCH 0x329a93a0 +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/137-drivers-soc-atmel-use-GENMASK.patch b/target/linux/at91/patches-5.10/137-drivers-soc-atmel-use-GENMASK.patch new file mode 100644 index 0000000000..d78a7b95be --- /dev/null +++ b/target/linux/at91/patches-5.10/137-drivers-soc-atmel-use-GENMASK.patch @@ -0,0 +1,30 @@ +From 8d858d9c57a0210ca1ce9e5ba76fab8bdb4d7b39 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Fri, 22 Jan 2021 14:21:32 +0200 +Subject: [PATCH 137/247] drivers: soc: atmel: use GENMASK + +Use GENMASK() to define CIDR match mask. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/1611318097-8970-3-git-send-email-claudiu.beznea@microchip.com +--- + drivers/soc/atmel/soc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c +index 698d21f50516..c3f920ee5c6f 100644 +--- a/drivers/soc/atmel/soc.c ++++ b/drivers/soc/atmel/soc.c +@@ -27,7 +27,7 @@ + #define AT91_CHIPID_EXID 0x04 + #define AT91_CIDR_VERSION(x) ((x) & 0x1f) + #define AT91_CIDR_EXT BIT(31) +-#define AT91_CIDR_MATCH_MASK 0x7fffffe0 ++#define AT91_CIDR_MATCH_MASK GENMASK(30, 5) + + static const struct at91_soc __initconst socs[] = { + #ifdef CONFIG_SOC_AT91RM9200 +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/138-drivers-soc-atmel-fix-__initconst-should-be-placed-a.patch b/target/linux/at91/patches-5.10/138-drivers-soc-atmel-fix-__initconst-should-be-placed-a.patch new file mode 100644 index 0000000000..c3bf9e7866 --- /dev/null +++ b/target/linux/at91/patches-5.10/138-drivers-soc-atmel-fix-__initconst-should-be-placed-a.patch @@ -0,0 +1,31 @@ +From ed871f95827e9b6d4ee9f9eafec4e18b87fb1a56 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Fri, 22 Jan 2021 14:21:33 +0200 +Subject: [PATCH 138/247] drivers: soc: atmel: fix "__initconst should be + placed after socs[]" warning + +Fix checkpatch.pl warning: "__initconst should be placed after socs[]". + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/1611318097-8970-4-git-send-email-claudiu.beznea@microchip.com +--- + drivers/soc/atmel/soc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c +index c3f920ee5c6f..03f3c742716c 100644 +--- a/drivers/soc/atmel/soc.c ++++ b/drivers/soc/atmel/soc.c +@@ -29,7 +29,7 @@ + #define AT91_CIDR_EXT BIT(31) + #define AT91_CIDR_MATCH_MASK GENMASK(30, 5) + +-static const struct at91_soc __initconst socs[] = { ++static const struct at91_soc socs[] __initconst = { + #ifdef CONFIG_SOC_AT91RM9200 + AT91_SOC(AT91RM9200_CIDR_MATCH, 0, "at91rm9200 BGA", "at91rm9200"), + #endif +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/139-drivers-soc-atmel-add-per-soc-id-and-version-match-m.patch b/target/linux/at91/patches-5.10/139-drivers-soc-atmel-add-per-soc-id-and-version-match-m.patch new file mode 100644 index 0000000000..8bd02f89ad --- /dev/null +++ b/target/linux/at91/patches-5.10/139-drivers-soc-atmel-add-per-soc-id-and-version-match-m.patch @@ -0,0 +1,355 @@ +From 8f6f7ef363268f417f1729bb0b234326dd1e8e2a Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Fri, 22 Jan 2021 14:21:35 +0200 +Subject: [PATCH 139/247] drivers: soc: atmel: add per soc id and version match + masks + +SAMA7G5 has different masks for chip ID and chip version on CIDR +register compared to previous AT91 SoCs. For this the commit adapts +the code for SAMA7G5 addition by introducing 2 new members in +struct at91_soc and fill them properly and also preparing the +parsing of proper DT binding. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/1611318097-8970-6-git-send-email-claudiu.beznea@microchip.com +--- + drivers/soc/atmel/soc.c | 199 +++++++++++++++++++++++++++------------- + drivers/soc/atmel/soc.h | 7 +- + 2 files changed, 140 insertions(+), 66 deletions(-) + +diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c +index 03f3c742716c..f9052f45cb3e 100644 +--- a/drivers/soc/atmel/soc.c ++++ b/drivers/soc/atmel/soc.c +@@ -25,135 +25,200 @@ + #define AT91_DBGU_EXID 0x44 + #define AT91_CHIPID_CIDR 0x00 + #define AT91_CHIPID_EXID 0x04 +-#define AT91_CIDR_VERSION(x) ((x) & 0x1f) ++#define AT91_CIDR_VERSION(x, m) ((x) & (m)) ++#define AT91_CIDR_VERSION_MASK GENMASK(4, 0) + #define AT91_CIDR_EXT BIT(31) + #define AT91_CIDR_MATCH_MASK GENMASK(30, 5) + + static const struct at91_soc socs[] __initconst = { + #ifdef CONFIG_SOC_AT91RM9200 +- AT91_SOC(AT91RM9200_CIDR_MATCH, 0, "at91rm9200 BGA", "at91rm9200"), ++ AT91_SOC(AT91RM9200_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, 0, "at91rm9200 BGA", "at91rm9200"), + #endif + #ifdef CONFIG_SOC_AT91SAM9 +- AT91_SOC(AT91SAM9260_CIDR_MATCH, 0, "at91sam9260", NULL), +- AT91_SOC(AT91SAM9261_CIDR_MATCH, 0, "at91sam9261", NULL), +- AT91_SOC(AT91SAM9263_CIDR_MATCH, 0, "at91sam9263", NULL), +- AT91_SOC(AT91SAM9G20_CIDR_MATCH, 0, "at91sam9g20", NULL), +- AT91_SOC(AT91SAM9RL64_CIDR_MATCH, 0, "at91sam9rl64", NULL), +- AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9M11_EXID_MATCH, ++ AT91_SOC(AT91SAM9260_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, 0, "at91sam9260", NULL), ++ AT91_SOC(AT91SAM9261_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, 0, "at91sam9261", NULL), ++ AT91_SOC(AT91SAM9263_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, 0, "at91sam9263", NULL), ++ AT91_SOC(AT91SAM9G20_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, 0, "at91sam9g20", NULL), ++ AT91_SOC(AT91SAM9RL64_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, 0, "at91sam9rl64", NULL), ++ AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, AT91SAM9M11_EXID_MATCH, + "at91sam9m11", "at91sam9g45"), +- AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9M10_EXID_MATCH, ++ AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, AT91SAM9M10_EXID_MATCH, + "at91sam9m10", "at91sam9g45"), +- AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9G46_EXID_MATCH, ++ AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, AT91SAM9G46_EXID_MATCH, + "at91sam9g46", "at91sam9g45"), +- AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91SAM9G45_EXID_MATCH, ++ AT91_SOC(AT91SAM9G45_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, AT91SAM9G45_EXID_MATCH, + "at91sam9g45", "at91sam9g45"), +- AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9G15_EXID_MATCH, ++ AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, AT91SAM9G15_EXID_MATCH, + "at91sam9g15", "at91sam9x5"), +- AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9G35_EXID_MATCH, ++ AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, AT91SAM9G35_EXID_MATCH, + "at91sam9g35", "at91sam9x5"), +- AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9X35_EXID_MATCH, ++ AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, AT91SAM9X35_EXID_MATCH, + "at91sam9x35", "at91sam9x5"), +- AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9G25_EXID_MATCH, ++ AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, AT91SAM9G25_EXID_MATCH, + "at91sam9g25", "at91sam9x5"), +- AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91SAM9X25_EXID_MATCH, ++ AT91_SOC(AT91SAM9X5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, AT91SAM9X25_EXID_MATCH, + "at91sam9x25", "at91sam9x5"), +- AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91SAM9CN12_EXID_MATCH, ++ AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, AT91SAM9CN12_EXID_MATCH, + "at91sam9cn12", "at91sam9n12"), +- AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91SAM9N12_EXID_MATCH, ++ AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, AT91SAM9N12_EXID_MATCH, + "at91sam9n12", "at91sam9n12"), +- AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91SAM9CN11_EXID_MATCH, ++ AT91_SOC(AT91SAM9N12_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, AT91SAM9CN11_EXID_MATCH, + "at91sam9cn11", "at91sam9n12"), +- AT91_SOC(AT91SAM9XE128_CIDR_MATCH, 0, "at91sam9xe128", "at91sam9xe128"), +- AT91_SOC(AT91SAM9XE256_CIDR_MATCH, 0, "at91sam9xe256", "at91sam9xe256"), +- AT91_SOC(AT91SAM9XE512_CIDR_MATCH, 0, "at91sam9xe512", "at91sam9xe512"), ++ AT91_SOC(AT91SAM9XE128_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, 0, "at91sam9xe128", "at91sam9xe128"), ++ AT91_SOC(AT91SAM9XE256_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, 0, "at91sam9xe256", "at91sam9xe256"), ++ AT91_SOC(AT91SAM9XE512_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, 0, "at91sam9xe512", "at91sam9xe512"), + #endif + #ifdef CONFIG_SOC_SAM9X60 +- AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_EXID_MATCH, "sam9x60", "sam9x60"), ++ AT91_SOC(SAM9X60_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH, ++ "sam9x60", "sam9x60"), + AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_D5M_EXID_MATCH, ++ AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH, + "sam9x60 64MiB DDR2 SiP", "sam9x60"), + AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_D1G_EXID_MATCH, ++ AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH, + "sam9x60 128MiB DDR2 SiP", "sam9x60"), + AT91_SOC(SAM9X60_CIDR_MATCH, SAM9X60_D6K_EXID_MATCH, ++ AT91_CIDR_VERSION_MASK, SAM9X60_EXID_MATCH, + "sam9x60 8MiB SDRAM SiP", "sam9x60"), + #endif + #ifdef CONFIG_SOC_SAMA5 +- AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D21CU_EXID_MATCH, ++ AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D21CU_EXID_MATCH, + "sama5d21", "sama5d2"), +- AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D22CU_EXID_MATCH, ++ AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D22CU_EXID_MATCH, + "sama5d22", "sama5d2"), +- AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D225C_D1M_EXID_MATCH, ++ AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D225C_D1M_EXID_MATCH, + "sama5d225c 16MiB SiP", "sama5d2"), +- AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D23CU_EXID_MATCH, ++ AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D23CU_EXID_MATCH, + "sama5d23", "sama5d2"), +- AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D24CX_EXID_MATCH, ++ AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D24CX_EXID_MATCH, + "sama5d24", "sama5d2"), +- AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D24CU_EXID_MATCH, ++ AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D24CU_EXID_MATCH, + "sama5d24", "sama5d2"), +- AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D26CU_EXID_MATCH, ++ AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D26CU_EXID_MATCH, + "sama5d26", "sama5d2"), +- AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27CU_EXID_MATCH, ++ AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D27CU_EXID_MATCH, + "sama5d27", "sama5d2"), +- AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27CN_EXID_MATCH, ++ AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D27CN_EXID_MATCH, + "sama5d27", "sama5d2"), +- AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27C_D1G_EXID_MATCH, ++ AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D27C_D1G_EXID_MATCH, + "sama5d27c 128MiB SiP", "sama5d2"), +- AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27C_D5M_EXID_MATCH, ++ AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D27C_D5M_EXID_MATCH, + "sama5d27c 64MiB SiP", "sama5d2"), +- AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27C_LD1G_EXID_MATCH, ++ AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D27C_LD1G_EXID_MATCH, + "sama5d27c 128MiB LPDDR2 SiP", "sama5d2"), +- AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D27C_LD2G_EXID_MATCH, ++ AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D27C_LD2G_EXID_MATCH, + "sama5d27c 256MiB LPDDR2 SiP", "sama5d2"), +- AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28CU_EXID_MATCH, ++ AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D28CU_EXID_MATCH, + "sama5d28", "sama5d2"), +- AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28CN_EXID_MATCH, ++ AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D28CN_EXID_MATCH, + "sama5d28", "sama5d2"), +- AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28C_D1G_EXID_MATCH, ++ AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D28C_D1G_EXID_MATCH, + "sama5d28c 128MiB SiP", "sama5d2"), +- AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28C_LD1G_EXID_MATCH, ++ AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D28C_LD1G_EXID_MATCH, + "sama5d28c 128MiB LPDDR2 SiP", "sama5d2"), +- AT91_SOC(SAMA5D2_CIDR_MATCH, SAMA5D28C_LD2G_EXID_MATCH, ++ AT91_SOC(SAMA5D2_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D28C_LD2G_EXID_MATCH, + "sama5d28c 256MiB LPDDR2 SiP", "sama5d2"), +- AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D31_EXID_MATCH, ++ AT91_SOC(SAMA5D3_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D31_EXID_MATCH, + "sama5d31", "sama5d3"), +- AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D33_EXID_MATCH, ++ AT91_SOC(SAMA5D3_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D33_EXID_MATCH, + "sama5d33", "sama5d3"), +- AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D34_EXID_MATCH, ++ AT91_SOC(SAMA5D3_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D34_EXID_MATCH, + "sama5d34", "sama5d3"), +- AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D35_EXID_MATCH, ++ AT91_SOC(SAMA5D3_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D35_EXID_MATCH, + "sama5d35", "sama5d3"), +- AT91_SOC(SAMA5D3_CIDR_MATCH, SAMA5D36_EXID_MATCH, ++ AT91_SOC(SAMA5D3_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D36_EXID_MATCH, + "sama5d36", "sama5d3"), +- AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D41_EXID_MATCH, ++ AT91_SOC(SAMA5D4_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D41_EXID_MATCH, + "sama5d41", "sama5d4"), +- AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D42_EXID_MATCH, ++ AT91_SOC(SAMA5D4_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D42_EXID_MATCH, + "sama5d42", "sama5d4"), +- AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D43_EXID_MATCH, ++ AT91_SOC(SAMA5D4_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D43_EXID_MATCH, + "sama5d43", "sama5d4"), +- AT91_SOC(SAMA5D4_CIDR_MATCH, SAMA5D44_EXID_MATCH, ++ AT91_SOC(SAMA5D4_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMA5D44_EXID_MATCH, + "sama5d44", "sama5d4"), + #endif + #ifdef CONFIG_SOC_SAMV7 +- AT91_SOC(SAME70Q21_CIDR_MATCH, SAME70Q21_EXID_MATCH, ++ AT91_SOC(SAME70Q21_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAME70Q21_EXID_MATCH, + "same70q21", "same7"), +- AT91_SOC(SAME70Q20_CIDR_MATCH, SAME70Q20_EXID_MATCH, ++ AT91_SOC(SAME70Q20_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAME70Q20_EXID_MATCH, + "same70q20", "same7"), +- AT91_SOC(SAME70Q19_CIDR_MATCH, SAME70Q19_EXID_MATCH, ++ AT91_SOC(SAME70Q19_CIDR_MATCH, AT91_CIDR_MATCH_MASK ++ AT91_CIDR_VERSION_MASK, SAME70Q19_EXID_MATCH, + "same70q19", "same7"), +- AT91_SOC(SAMS70Q21_CIDR_MATCH, SAMS70Q21_EXID_MATCH, ++ AT91_SOC(SAMS70Q21_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMS70Q21_EXID_MATCH, + "sams70q21", "sams7"), +- AT91_SOC(SAMS70Q20_CIDR_MATCH, SAMS70Q20_EXID_MATCH, ++ AT91_SOC(SAMS70Q20_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMS70Q20_EXID_MATCH, + "sams70q20", "sams7"), +- AT91_SOC(SAMS70Q19_CIDR_MATCH, SAMS70Q19_EXID_MATCH, ++ AT91_SOC(SAMS70Q19_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMS70Q19_EXID_MATCH, + "sams70q19", "sams7"), +- AT91_SOC(SAMV71Q21_CIDR_MATCH, SAMV71Q21_EXID_MATCH, ++ AT91_SOC(SAMV71Q21_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMV71Q21_EXID_MATCH, + "samv71q21", "samv7"), +- AT91_SOC(SAMV71Q20_CIDR_MATCH, SAMV71Q20_EXID_MATCH, ++ AT91_SOC(SAMV71Q20_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMV71Q20_EXID_MATCH, + "samv71q20", "samv7"), +- AT91_SOC(SAMV71Q19_CIDR_MATCH, SAMV71Q19_EXID_MATCH, ++ AT91_SOC(SAMV71Q19_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMV71Q19_EXID_MATCH, + "samv71q19", "samv7"), +- AT91_SOC(SAMV70Q20_CIDR_MATCH, SAMV70Q20_EXID_MATCH, ++ AT91_SOC(SAMV70Q20_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMV70Q20_EXID_MATCH, + "samv70q20", "samv7"), +- AT91_SOC(SAMV70Q19_CIDR_MATCH, SAMV70Q19_EXID_MATCH, ++ AT91_SOC(SAMV70Q19_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK, SAMV70Q19_EXID_MATCH, + "samv70q19", "samv7"), + #endif + { /* sentinel */ }, +@@ -191,8 +256,12 @@ static int __init at91_get_cidr_exid_from_chipid(u32 *cidr, u32 *exid) + { + struct device_node *np; + void __iomem *regs; ++ static const struct of_device_id chipids[] = { ++ { .compatible = "atmel,sama5d2-chipid" }, ++ { }, ++ }; + +- np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-chipid"); ++ np = of_find_matching_node(NULL, chipids); + if (!np) + return -ENODEV; + +@@ -235,7 +304,7 @@ struct soc_device * __init at91_soc_init(const struct at91_soc *socs) + } + + for (soc = socs; soc->name; soc++) { +- if (soc->cidr_match != (cidr & AT91_CIDR_MATCH_MASK)) ++ if (soc->cidr_match != (cidr & soc->cidr_mask)) + continue; + + if (!(cidr & AT91_CIDR_EXT) || soc->exid_match == exid) +@@ -254,7 +323,7 @@ struct soc_device * __init at91_soc_init(const struct at91_soc *socs) + soc_dev_attr->family = soc->family; + soc_dev_attr->soc_id = soc->name; + soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%X", +- AT91_CIDR_VERSION(cidr)); ++ AT91_CIDR_VERSION(cidr, soc->version_mask)); + soc_dev = soc_device_register(soc_dev_attr); + if (IS_ERR(soc_dev)) { + kfree(soc_dev_attr->revision); +@@ -266,7 +335,7 @@ struct soc_device * __init at91_soc_init(const struct at91_soc *socs) + if (soc->family) + pr_info("Detected SoC family: %s\n", soc->family); + pr_info("Detected SoC: %s, revision %X\n", soc->name, +- AT91_CIDR_VERSION(cidr)); ++ AT91_CIDR_VERSION(cidr, soc->version_mask)); + + return soc_dev; + } +diff --git a/drivers/soc/atmel/soc.h b/drivers/soc/atmel/soc.h +index 5849846a69d6..02198a4de22b 100644 +--- a/drivers/soc/atmel/soc.h ++++ b/drivers/soc/atmel/soc.h +@@ -16,14 +16,19 @@ + + struct at91_soc { + u32 cidr_match; ++ u32 cidr_mask; ++ u32 version_mask; + u32 exid_match; + const char *name; + const char *family; + }; + +-#define AT91_SOC(__cidr, __exid, __name, __family) \ ++#define AT91_SOC(__cidr, __cidr_mask, __version_mask, __exid, \ ++ __name, __family) \ + { \ + .cidr_match = (__cidr), \ ++ .cidr_mask = (__cidr_mask), \ ++ .version_mask = (__version_mask), \ + .exid_match = (__exid), \ + .name = (__name), \ + .family = (__family), \ +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/140-drivers-soc-atmel-add-support-for-sama7g5.patch b/target/linux/at91/patches-5.10/140-drivers-soc-atmel-add-support-for-sama7g5.patch new file mode 100644 index 0000000000..82d12b9ffb --- /dev/null +++ b/target/linux/at91/patches-5.10/140-drivers-soc-atmel-add-support-for-sama7g5.patch @@ -0,0 +1,94 @@ +From e20bb57fc51741677a6fcae04e564797fd18921b Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Fri, 22 Jan 2021 14:21:37 +0200 +Subject: [PATCH 140/247] drivers: soc: atmel: add support for sama7g5 + +Add support for SAMA7G5 SoCs. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/1611318097-8970-8-git-send-email-claudiu.beznea@microchip.com +--- + drivers/soc/atmel/soc.c | 18 ++++++++++++++++++ + drivers/soc/atmel/soc.h | 6 ++++++ + 2 files changed, 24 insertions(+) + +diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c +index f9052f45cb3e..bc8e72fd431a 100644 +--- a/drivers/soc/atmel/soc.c ++++ b/drivers/soc/atmel/soc.c +@@ -27,8 +27,10 @@ + #define AT91_CHIPID_EXID 0x04 + #define AT91_CIDR_VERSION(x, m) ((x) & (m)) + #define AT91_CIDR_VERSION_MASK GENMASK(4, 0) ++#define AT91_CIDR_VERSION_MASK_SAMA7G5 GENMASK(3, 0) + #define AT91_CIDR_EXT BIT(31) + #define AT91_CIDR_MATCH_MASK GENMASK(30, 5) ++#define AT91_CIDR_MASK_SAMA7G5 GENMASK(27, 5) + + static const struct at91_soc socs[] __initconst = { + #ifdef CONFIG_SOC_AT91RM9200 +@@ -220,6 +222,20 @@ static const struct at91_soc socs[] __initconst = { + AT91_SOC(SAMV70Q19_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAMV70Q19_EXID_MATCH, + "samv70q19", "samv7"), ++#endif ++#ifdef CONFIG_SOC_SAMA7 ++ AT91_SOC(SAMA7G5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK_SAMA7G5, SAMA7G51_EXID_MATCH, ++ "sama7g51", "sama7g5"), ++ AT91_SOC(SAMA7G5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK_SAMA7G5, SAMA7G52_EXID_MATCH, ++ "sama7g52", "sama7g5"), ++ AT91_SOC(SAMA7G5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK_SAMA7G5, SAMA7G53_EXID_MATCH, ++ "sama7g53", "sama7g5"), ++ AT91_SOC(SAMA7G5_CIDR_MATCH, AT91_CIDR_MATCH_MASK, ++ AT91_CIDR_VERSION_MASK_SAMA7G5, SAMA7G54_EXID_MATCH, ++ "sama7g54", "sama7g5"), + #endif + { /* sentinel */ }, + }; +@@ -258,6 +274,7 @@ static int __init at91_get_cidr_exid_from_chipid(u32 *cidr, u32 *exid) + void __iomem *regs; + static const struct of_device_id chipids[] = { + { .compatible = "atmel,sama5d2-chipid" }, ++ { .compatible = "microchip,sama7g5-chipid" }, + { }, + }; + +@@ -345,6 +362,7 @@ static const struct of_device_id at91_soc_allowed_list[] __initconst = { + { .compatible = "atmel,at91sam9", }, + { .compatible = "atmel,sama5", }, + { .compatible = "atmel,samv7", }, ++ { .compatible = "microchip,sama7g5", }, + { } + }; + +diff --git a/drivers/soc/atmel/soc.h b/drivers/soc/atmel/soc.h +index 02198a4de22b..93c212533ff0 100644 +--- a/drivers/soc/atmel/soc.h ++++ b/drivers/soc/atmel/soc.h +@@ -48,6 +48,7 @@ at91_soc_init(const struct at91_soc *socs); + #define AT91SAM9X5_CIDR_MATCH 0x019a05a0 + #define AT91SAM9N12_CIDR_MATCH 0x019a07a0 + #define SAM9X60_CIDR_MATCH 0x019b35a0 ++#define SAMA7G5_CIDR_MATCH 0x00162100 + + #define AT91SAM9M11_EXID_MATCH 0x00000001 + #define AT91SAM9M10_EXID_MATCH 0x00000002 +@@ -69,6 +70,11 @@ at91_soc_init(const struct at91_soc *socs); + #define SAM9X60_D1G_EXID_MATCH 0x00000010 + #define SAM9X60_D6K_EXID_MATCH 0x00000011 + ++#define SAMA7G51_EXID_MATCH 0x3 ++#define SAMA7G52_EXID_MATCH 0x2 ++#define SAMA7G53_EXID_MATCH 0x1 ++#define SAMA7G54_EXID_MATCH 0x0 ++ + #define AT91SAM9XE128_CIDR_MATCH 0x329973a0 + #define AT91SAM9XE256_CIDR_MATCH 0x329a93a0 + #define AT91SAM9XE512_CIDR_MATCH 0x329aa3a0 +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/141-drivers-soc-atmel-add-spdx-license-identifier.patch b/target/linux/at91/patches-5.10/141-drivers-soc-atmel-add-spdx-license-identifier.patch new file mode 100644 index 0000000000..6d55372504 --- /dev/null +++ b/target/linux/at91/patches-5.10/141-drivers-soc-atmel-add-spdx-license-identifier.patch @@ -0,0 +1,56 @@ +From acd4816cfa7811b13ca2864645f2de41031ccf4d Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Tue, 26 Jan 2021 11:29:30 +0200 +Subject: [PATCH 141/247] drivers: soc: atmel: add spdx license identifier + +Add SPDX-License-Identifier. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +[nicolas.ferre@microhcip.com: remove license boilerplate now it's useless] +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/1611653376-24168-2-git-send-email-claudiu.beznea@microchip.com +--- + drivers/soc/atmel/soc.c | 6 +----- + drivers/soc/atmel/soc.h | 6 +----- + 2 files changed, 2 insertions(+), 10 deletions(-) + +diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c +index bc8e72fd431a..a2967846809f 100644 +--- a/drivers/soc/atmel/soc.c ++++ b/drivers/soc/atmel/soc.c +@@ -1,13 +1,9 @@ ++// SPDX-License-Identifier: GPL-2.0-only + /* + * Copyright (C) 2015 Atmel + * + * Alexandre Belloni <alexandre.belloni@free-electrons.com + * Boris Brezillon <boris.brezillon@free-electrons.com +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- * + */ + + #define pr_fmt(fmt) "AT91: " fmt +diff --git a/drivers/soc/atmel/soc.h b/drivers/soc/atmel/soc.h +index 93c212533ff0..c3eb3c8f0834 100644 +--- a/drivers/soc/atmel/soc.h ++++ b/drivers/soc/atmel/soc.h +@@ -1,12 +1,8 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ + /* + * Copyright (C) 2015 Atmel + * + * Boris Brezillon <boris.brezillon@free-electrons.com +- * +- * This file is licensed under the terms of the GNU General Public +- * License version 2. This program is licensed "as is" without any +- * warranty of any kind, whether express or implied. +- * + */ + + #ifndef __AT91_SOC_H +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/142-drivers-soc-atmel-fix-type-for-same7.patch b/target/linux/at91/patches-5.10/142-drivers-soc-atmel-fix-type-for-same7.patch new file mode 100644 index 0000000000..f25b25cc7f --- /dev/null +++ b/target/linux/at91/patches-5.10/142-drivers-soc-atmel-fix-type-for-same7.patch @@ -0,0 +1,33 @@ +From b105d1dfab46c13070b8bdea1ab28d223a9c1bee Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann <arnd@arndb.de> +Date: Thu, 4 Feb 2021 16:49:25 +0100 +Subject: [PATCH 142/247] drivers: soc: atmel: fix type for same7 + +A missing comma caused a build failure: + +drivers/soc/atmel/soc.c:196:24: error: too few arguments provided to function-like macro invocation + +Fixes: af3a10513cd6 ("drivers: soc: atmel: add per soc id and version match masks") +Signed-off-by: Arnd Bergmann <arnd@arndb.de> +Acked-by: Alexandre Belloni <alexandre.belloni@bootlin.com> +Signed-off-by: Arnd Bergmann <arnd@arndb.de> +--- + drivers/soc/atmel/soc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c +index a2967846809f..a490ad7e090f 100644 +--- a/drivers/soc/atmel/soc.c ++++ b/drivers/soc/atmel/soc.c +@@ -191,7 +191,7 @@ static const struct at91_soc socs[] __initconst = { + AT91_SOC(SAME70Q20_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAME70Q20_EXID_MATCH, + "same70q20", "same7"), +- AT91_SOC(SAME70Q19_CIDR_MATCH, AT91_CIDR_MATCH_MASK ++ AT91_SOC(SAME70Q19_CIDR_MATCH, AT91_CIDR_MATCH_MASK, + AT91_CIDR_VERSION_MASK, SAME70Q19_EXID_MATCH, + "same70q19", "same7"), + AT91_SOC(SAMS70Q21_CIDR_MATCH, AT91_CIDR_MATCH_MASK, +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/143-clocksource-drivers-timer-microchip-pit64b-Add-clock.patch b/target/linux/at91/patches-5.10/143-clocksource-drivers-timer-microchip-pit64b-Add-clock.patch new file mode 100644 index 0000000000..045e920526 --- /dev/null +++ b/target/linux/at91/patches-5.10/143-clocksource-drivers-timer-microchip-pit64b-Add-clock.patch @@ -0,0 +1,178 @@ +From 5f090a664d62ceeaf9a0f482426e35cab18d65a9 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Tue, 19 Jan 2021 14:59:25 +0200 +Subject: [PATCH 143/247] clocksource/drivers/timer-microchip-pit64b: Add + clocksource suspend/resume + +Add suspend/resume support for clocksource timer. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> +Link: https://lore.kernel.org/r/1611061165-30180-1-git-send-email-claudiu.beznea@microchip.com +--- + drivers/clocksource/timer-microchip-pit64b.c | 86 ++++++++++++++++---- + 1 file changed, 71 insertions(+), 15 deletions(-) + +diff --git a/drivers/clocksource/timer-microchip-pit64b.c b/drivers/clocksource/timer-microchip-pit64b.c +index 59e11ca8ee73..ab623b25a47b 100644 +--- a/drivers/clocksource/timer-microchip-pit64b.c ++++ b/drivers/clocksource/timer-microchip-pit64b.c +@@ -71,10 +71,24 @@ struct mchp_pit64b_clkevt { + struct clock_event_device clkevt; + }; + +-#define to_mchp_pit64b_timer(x) \ ++#define clkevt_to_mchp_pit64b_timer(x) \ + ((struct mchp_pit64b_timer *)container_of(x,\ + struct mchp_pit64b_clkevt, clkevt)) + ++/** ++ * mchp_pit64b_clksrc - PIT64B clocksource data structure ++ * @timer: PIT64B timer ++ * @clksrc: clocksource ++ */ ++struct mchp_pit64b_clksrc { ++ struct mchp_pit64b_timer timer; ++ struct clocksource clksrc; ++}; ++ ++#define clksrc_to_mchp_pit64b_timer(x) \ ++ ((struct mchp_pit64b_timer *)container_of(x,\ ++ struct mchp_pit64b_clksrc, clksrc)) ++ + /* Base address for clocksource timer. */ + static void __iomem *mchp_pit64b_cs_base; + /* Default cycles for clockevent timer. */ +@@ -116,6 +130,36 @@ static inline void mchp_pit64b_reset(struct mchp_pit64b_timer *timer, + writel_relaxed(MCHP_PIT64B_CR_START, timer->base + MCHP_PIT64B_CR); + } + ++static void mchp_pit64b_suspend(struct mchp_pit64b_timer *timer) ++{ ++ writel_relaxed(MCHP_PIT64B_CR_SWRST, timer->base + MCHP_PIT64B_CR); ++ if (timer->mode & MCHP_PIT64B_MR_SGCLK) ++ clk_disable_unprepare(timer->gclk); ++ clk_disable_unprepare(timer->pclk); ++} ++ ++static void mchp_pit64b_resume(struct mchp_pit64b_timer *timer) ++{ ++ clk_prepare_enable(timer->pclk); ++ if (timer->mode & MCHP_PIT64B_MR_SGCLK) ++ clk_prepare_enable(timer->gclk); ++} ++ ++static void mchp_pit64b_clksrc_suspend(struct clocksource *cs) ++{ ++ struct mchp_pit64b_timer *timer = clksrc_to_mchp_pit64b_timer(cs); ++ ++ mchp_pit64b_suspend(timer); ++} ++ ++static void mchp_pit64b_clksrc_resume(struct clocksource *cs) ++{ ++ struct mchp_pit64b_timer *timer = clksrc_to_mchp_pit64b_timer(cs); ++ ++ mchp_pit64b_resume(timer); ++ mchp_pit64b_reset(timer, ULLONG_MAX, MCHP_PIT64B_MR_CONT, 0); ++} ++ + static u64 mchp_pit64b_clksrc_read(struct clocksource *cs) + { + return mchp_pit64b_cnt_read(mchp_pit64b_cs_base); +@@ -128,7 +172,7 @@ static u64 mchp_pit64b_sched_read_clk(void) + + static int mchp_pit64b_clkevt_shutdown(struct clock_event_device *cedev) + { +- struct mchp_pit64b_timer *timer = to_mchp_pit64b_timer(cedev); ++ struct mchp_pit64b_timer *timer = clkevt_to_mchp_pit64b_timer(cedev); + + writel_relaxed(MCHP_PIT64B_CR_SWRST, timer->base + MCHP_PIT64B_CR); + +@@ -137,7 +181,7 @@ static int mchp_pit64b_clkevt_shutdown(struct clock_event_device *cedev) + + static int mchp_pit64b_clkevt_set_periodic(struct clock_event_device *cedev) + { +- struct mchp_pit64b_timer *timer = to_mchp_pit64b_timer(cedev); ++ struct mchp_pit64b_timer *timer = clkevt_to_mchp_pit64b_timer(cedev); + + mchp_pit64b_reset(timer, mchp_pit64b_ce_cycles, MCHP_PIT64B_MR_CONT, + MCHP_PIT64B_IER_PERIOD); +@@ -148,7 +192,7 @@ static int mchp_pit64b_clkevt_set_periodic(struct clock_event_device *cedev) + static int mchp_pit64b_clkevt_set_next_event(unsigned long evt, + struct clock_event_device *cedev) + { +- struct mchp_pit64b_timer *timer = to_mchp_pit64b_timer(cedev); ++ struct mchp_pit64b_timer *timer = clkevt_to_mchp_pit64b_timer(cedev); + + mchp_pit64b_reset(timer, evt, MCHP_PIT64B_MR_ONE_SHOT, + MCHP_PIT64B_IER_PERIOD); +@@ -158,21 +202,16 @@ static int mchp_pit64b_clkevt_set_next_event(unsigned long evt, + + static void mchp_pit64b_clkevt_suspend(struct clock_event_device *cedev) + { +- struct mchp_pit64b_timer *timer = to_mchp_pit64b_timer(cedev); ++ struct mchp_pit64b_timer *timer = clkevt_to_mchp_pit64b_timer(cedev); + +- writel_relaxed(MCHP_PIT64B_CR_SWRST, timer->base + MCHP_PIT64B_CR); +- if (timer->mode & MCHP_PIT64B_MR_SGCLK) +- clk_disable_unprepare(timer->gclk); +- clk_disable_unprepare(timer->pclk); ++ mchp_pit64b_suspend(timer); + } + + static void mchp_pit64b_clkevt_resume(struct clock_event_device *cedev) + { +- struct mchp_pit64b_timer *timer = to_mchp_pit64b_timer(cedev); ++ struct mchp_pit64b_timer *timer = clkevt_to_mchp_pit64b_timer(cedev); + +- clk_prepare_enable(timer->pclk); +- if (timer->mode & MCHP_PIT64B_MR_SGCLK) +- clk_prepare_enable(timer->gclk); ++ mchp_pit64b_resume(timer); + } + + static irqreturn_t mchp_pit64b_interrupt(int irq, void *dev_id) +@@ -296,20 +335,37 @@ static int __init mchp_pit64b_init_mode(struct mchp_pit64b_timer *timer, + static int __init mchp_pit64b_init_clksrc(struct mchp_pit64b_timer *timer, + u32 clk_rate) + { ++ struct mchp_pit64b_clksrc *cs; + int ret; + ++ cs = kzalloc(sizeof(*cs), GFP_KERNEL); ++ if (!cs) ++ return -ENOMEM; ++ + mchp_pit64b_reset(timer, ULLONG_MAX, MCHP_PIT64B_MR_CONT, 0); + + mchp_pit64b_cs_base = timer->base; + +- ret = clocksource_mmio_init(timer->base, MCHP_PIT64B_NAME, clk_rate, +- 210, 64, mchp_pit64b_clksrc_read); ++ cs->timer.base = timer->base; ++ cs->timer.pclk = timer->pclk; ++ cs->timer.gclk = timer->gclk; ++ cs->timer.mode = timer->mode; ++ cs->clksrc.name = MCHP_PIT64B_NAME; ++ cs->clksrc.mask = CLOCKSOURCE_MASK(64); ++ cs->clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS; ++ cs->clksrc.rating = 210; ++ cs->clksrc.read = mchp_pit64b_clksrc_read; ++ cs->clksrc.suspend = mchp_pit64b_clksrc_suspend; ++ cs->clksrc.resume = mchp_pit64b_clksrc_resume; ++ ++ ret = clocksource_register_hz(&cs->clksrc, clk_rate); + if (ret) { + pr_debug("clksrc: Failed to register PIT64B clocksource!\n"); + + /* Stop timer. */ + writel_relaxed(MCHP_PIT64B_CR_SWRST, + timer->base + MCHP_PIT64B_CR); ++ kfree(cs); + + return ret; + } +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/144-ASoC-atmel-pdc-Use-managed-DMA-buffer-allocation.patch b/target/linux/at91/patches-5.10/144-ASoC-atmel-pdc-Use-managed-DMA-buffer-allocation.patch new file mode 100644 index 0000000000..1cb43ca20c --- /dev/null +++ b/target/linux/at91/patches-5.10/144-ASoC-atmel-pdc-Use-managed-DMA-buffer-allocation.patch @@ -0,0 +1,140 @@ +From 0b20c174a17dcfa805ddac1301a5af7298877ec3 Mon Sep 17 00:00:00 2001 +From: Lars-Peter Clausen <lars@metafoo.de> +Date: Wed, 6 Jan 2021 14:36:48 +0100 +Subject: [PATCH 144/247] ASoC: atmel-pdc: Use managed DMA buffer allocation + +Instead of manually managing its DMA buffers using +dma_{alloc,free}_coherent() lets the sound core take care of this using +managed buffers. + +On one hand this reduces the amount of boiler plate code, but the main +motivation for the change is to use the shared code where possible. This +makes it easier to argue about correctness and that the code does not +contain subtle bugs like data leakage or similar. + +Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> +Reviewed-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Link: https://lore.kernel.org/r/20210106133650.13509-1-lars@metafoo.de +Signed-off-by: Mark Brown <broonie@kernel.org> +--- + sound/soc/atmel/atmel-pcm-pdc.c | 78 ++------------------------------- + 1 file changed, 4 insertions(+), 74 deletions(-) + +diff --git a/sound/soc/atmel/atmel-pcm-pdc.c b/sound/soc/atmel/atmel-pcm-pdc.c +index 704f700013d3..3e7ea2021b46 100644 +--- a/sound/soc/atmel/atmel-pcm-pdc.c ++++ b/sound/soc/atmel/atmel-pcm-pdc.c +@@ -34,86 +34,21 @@ + #include "atmel-pcm.h" + + +-static int atmel_pcm_preallocate_dma_buffer(struct snd_pcm *pcm, +- int stream) +-{ +- struct snd_pcm_substream *substream = pcm->streams[stream].substream; +- struct snd_dma_buffer *buf = &substream->dma_buffer; +- size_t size = ATMEL_SSC_DMABUF_SIZE; +- +- buf->dev.type = SNDRV_DMA_TYPE_DEV; +- buf->dev.dev = pcm->card->dev; +- buf->private_data = NULL; +- buf->area = dma_alloc_coherent(pcm->card->dev, size, +- &buf->addr, GFP_KERNEL); +- pr_debug("atmel-pcm: alloc dma buffer: area=%p, addr=%p, size=%zu\n", +- (void *)buf->area, (void *)(long)buf->addr, size); +- +- if (!buf->area) +- return -ENOMEM; +- +- buf->bytes = size; +- return 0; +-} +- +-static int atmel_pcm_mmap(struct snd_soc_component *component, +- struct snd_pcm_substream *substream, +- struct vm_area_struct *vma) +-{ +- return remap_pfn_range(vma, vma->vm_start, +- substream->dma_buffer.addr >> PAGE_SHIFT, +- vma->vm_end - vma->vm_start, vma->vm_page_prot); +-} +- + static int atmel_pcm_new(struct snd_soc_component *component, + struct snd_soc_pcm_runtime *rtd) + { + struct snd_card *card = rtd->card->snd_card; +- struct snd_pcm *pcm = rtd->pcm; + int ret; + + ret = dma_coerce_mask_and_coherent(card->dev, DMA_BIT_MASK(32)); + if (ret) + return ret; + +- if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) { +- pr_debug("atmel-pcm: allocating PCM playback DMA buffer\n"); +- ret = atmel_pcm_preallocate_dma_buffer(pcm, +- SNDRV_PCM_STREAM_PLAYBACK); +- if (ret) +- goto out; +- } ++ snd_pcm_set_managed_buffer_all(rtd->pcm, SNDRV_DMA_TYPE_DEV, ++ card->dev, ATMEL_SSC_DMABUF_SIZE, ++ ATMEL_SSC_DMABUF_SIZE); + +- if (pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream) { +- pr_debug("atmel-pcm: allocating PCM capture DMA buffer\n"); +- ret = atmel_pcm_preallocate_dma_buffer(pcm, +- SNDRV_PCM_STREAM_CAPTURE); +- if (ret) +- goto out; +- } +- out: +- return ret; +-} +- +-static void atmel_pcm_free(struct snd_soc_component *component, +- struct snd_pcm *pcm) +-{ +- struct snd_pcm_substream *substream; +- struct snd_dma_buffer *buf; +- int stream; +- +- for (stream = 0; stream < 2; stream++) { +- substream = pcm->streams[stream].substream; +- if (!substream) +- continue; +- +- buf = &substream->dma_buffer; +- if (!buf->area) +- continue; +- dma_free_coherent(pcm->card->dev, buf->bytes, +- buf->area, buf->addr); +- buf->area = NULL; +- } ++ return 0; + } + + /*--------------------------------------------------------------------------*\ +@@ -210,9 +145,6 @@ static int atmel_pcm_hw_params(struct snd_soc_component *component, + /* this may get called several times by oss emulation + * with different params */ + +- snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); +- runtime->dma_bytes = params_buffer_bytes(params); +- + prtd->params = snd_soc_dai_get_dma_data(asoc_rtd_to_cpu(rtd, 0), substream); + prtd->params->dma_intr_handler = atmel_pcm_dma_irq; + +@@ -384,9 +316,7 @@ static const struct snd_soc_component_driver atmel_soc_platform = { + .prepare = atmel_pcm_prepare, + .trigger = atmel_pcm_trigger, + .pointer = atmel_pcm_pointer, +- .mmap = atmel_pcm_mmap, + .pcm_construct = atmel_pcm_new, +- .pcm_destruct = atmel_pcm_free, + }; + + int atmel_pcm_pdc_platform_register(struct device *dev) +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/145-power-reset-at91-sama5d2_shdwc-add-support-for-sama7.patch b/target/linux/at91/patches-5.10/145-power-reset-at91-sama5d2_shdwc-add-support-for-sama7.patch new file mode 100644 index 0000000000..ed8ffac935 --- /dev/null +++ b/target/linux/at91/patches-5.10/145-power-reset-at91-sama5d2_shdwc-add-support-for-sama7.patch @@ -0,0 +1,146 @@ +From f39f2312a68ec0843adba08f9c9182ffa5624190 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Wed, 16 Dec 2020 14:57:33 +0200 +Subject: [PATCH 145/247] power: reset: at91-sama5d2_shdwc: add support for + sama7g5 + +Add support for SAMA7G5 by adding proper struct reg_config structure +and since SAMA7G5 is not currently on LPDDR setups the commit also +avoid the mapping of DDR controller. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> +--- + drivers/power/reset/at91-sama5d2_shdwc.c | 72 ++++++++++++++++++------ + 1 file changed, 54 insertions(+), 18 deletions(-) + +diff --git a/drivers/power/reset/at91-sama5d2_shdwc.c b/drivers/power/reset/at91-sama5d2_shdwc.c +index d9cf91e5b06d..125e592af445 100644 +--- a/drivers/power/reset/at91-sama5d2_shdwc.c ++++ b/drivers/power/reset/at91-sama5d2_shdwc.c +@@ -78,9 +78,15 @@ struct pmc_reg_config { + u8 mckr; + }; + ++struct ddrc_reg_config { ++ u32 type_offset; ++ u32 type_mask; ++}; ++ + struct reg_config { + struct shdwc_reg_config shdwc; + struct pmc_reg_config pmc; ++ struct ddrc_reg_config ddrc; + }; + + struct shdwc { +@@ -262,6 +268,10 @@ static const struct reg_config sama5d2_reg_config = { + .pmc = { + .mckr = 0x30, + }, ++ .ddrc = { ++ .type_offset = AT91_DDRSDRC_MDR, ++ .type_mask = AT91_DDRSDRC_MD ++ }, + }; + + static const struct reg_config sam9x60_reg_config = { +@@ -275,6 +285,23 @@ static const struct reg_config sam9x60_reg_config = { + .pmc = { + .mckr = 0x28, + }, ++ .ddrc = { ++ .type_offset = AT91_DDRSDRC_MDR, ++ .type_mask = AT91_DDRSDRC_MD ++ }, ++}; ++ ++static const struct reg_config sama7g5_reg_config = { ++ .shdwc = { ++ .wkup_pin_input = 0, ++ .mr_rtcwk_shift = 17, ++ .mr_rttwk_shift = 16, ++ .sr_rtcwk_shift = 5, ++ .sr_rttwk_shift = 4, ++ }, ++ .pmc = { ++ .mckr = 0x28, ++ }, + }; + + static const struct of_device_id at91_shdwc_of_match[] = { +@@ -285,6 +312,10 @@ static const struct of_device_id at91_shdwc_of_match[] = { + { + .compatible = "microchip,sam9x60-shdwc", + .data = &sam9x60_reg_config, ++ }, ++ { ++ .compatible = "microchip,sama7g5-shdwc", ++ .data = &sama7g5_reg_config, + }, { + /*sentinel*/ + } +@@ -294,6 +325,7 @@ MODULE_DEVICE_TABLE(of, at91_shdwc_of_match); + static const struct of_device_id at91_pmc_ids[] = { + { .compatible = "atmel,sama5d2-pmc" }, + { .compatible = "microchip,sam9x60-pmc" }, ++ { .compatible = "microchip,sama7g5-pmc" }, + { /* Sentinel. */ } + }; + +@@ -355,30 +387,34 @@ static int __init at91_shdwc_probe(struct platform_device *pdev) + goto clk_disable; + } + +- np = of_find_compatible_node(NULL, NULL, "atmel,sama5d3-ddramc"); +- if (!np) { +- ret = -ENODEV; +- goto unmap; +- } ++ if (at91_shdwc->rcfg->ddrc.type_mask) { ++ np = of_find_compatible_node(NULL, NULL, ++ "atmel,sama5d3-ddramc"); ++ if (!np) { ++ ret = -ENODEV; ++ goto unmap; ++ } + +- at91_shdwc->mpddrc_base = of_iomap(np, 0); +- of_node_put(np); ++ at91_shdwc->mpddrc_base = of_iomap(np, 0); ++ of_node_put(np); + +- if (!at91_shdwc->mpddrc_base) { +- ret = -ENOMEM; +- goto unmap; ++ if (!at91_shdwc->mpddrc_base) { ++ ret = -ENOMEM; ++ goto unmap; ++ } ++ ++ ddr_type = readl(at91_shdwc->mpddrc_base + ++ at91_shdwc->rcfg->ddrc.type_offset) & ++ at91_shdwc->rcfg->ddrc.type_mask; ++ if (ddr_type != AT91_DDRSDRC_MD_LPDDR2 && ++ ddr_type != AT91_DDRSDRC_MD_LPDDR3) { ++ iounmap(at91_shdwc->mpddrc_base); ++ at91_shdwc->mpddrc_base = NULL; ++ } + } + + pm_power_off = at91_poweroff; + +- ddr_type = readl(at91_shdwc->mpddrc_base + AT91_DDRSDRC_MDR) & +- AT91_DDRSDRC_MD; +- if (ddr_type != AT91_DDRSDRC_MD_LPDDR2 && +- ddr_type != AT91_DDRSDRC_MD_LPDDR3) { +- iounmap(at91_shdwc->mpddrc_base); +- at91_shdwc->mpddrc_base = NULL; +- } +- + return 0; + + unmap: +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/146-pinctrl-at91-pio4-add-support-for-slew-rate.patch b/target/linux/at91/patches-5.10/146-pinctrl-at91-pio4-add-support-for-slew-rate.patch new file mode 100644 index 0000000000..3568760d3c --- /dev/null +++ b/target/linux/at91/patches-5.10/146-pinctrl-at91-pio4-add-support-for-slew-rate.patch @@ -0,0 +1,126 @@ +From bd819c78346012ae0627b1cd4f6ceb1b51162c71 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Wed, 27 Jan 2021 13:45:44 +0200 +Subject: [PATCH 146/247] pinctrl: at91-pio4: add support for slew-rate + +SAMA7G5 supports slew rate configuration. Adapt the driver for this. +For output switching frequencies lower than 50MHz the slew rate needs to +be enabled. Since most of the pins on SAMA7G5 fall into this category +enabled the slew rate by default. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Acked-by: Ludovic Desroches <ludovic.desroches@microchip.com> +Link: https://lore.kernel.org/r/1611747945-29960-3-git-send-email-claudiu.beznea@microchip.com +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +--- + drivers/pinctrl/pinctrl-at91-pio4.c | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c +index d267367d94b9..f202cdb6dc3c 100644 +--- a/drivers/pinctrl/pinctrl-at91-pio4.c ++++ b/drivers/pinctrl/pinctrl-at91-pio4.c +@@ -36,6 +36,7 @@ + #define ATMEL_PIO_DIR_MASK BIT(8) + #define ATMEL_PIO_PUEN_MASK BIT(9) + #define ATMEL_PIO_PDEN_MASK BIT(10) ++#define ATMEL_PIO_SR_MASK BIT(11) + #define ATMEL_PIO_IFEN_MASK BIT(12) + #define ATMEL_PIO_IFSCEN_MASK BIT(13) + #define ATMEL_PIO_OPD_MASK BIT(14) +@@ -76,10 +77,12 @@ + * @nbanks: number of PIO banks + * @last_bank_count: number of lines in the last bank (can be less than + * the rest of the banks). ++ * @slew_rate_support: slew rate support + */ + struct atmel_pioctrl_data { + unsigned nbanks; + unsigned last_bank_count; ++ unsigned int slew_rate_support; + }; + + struct atmel_group { +@@ -117,6 +120,7 @@ struct atmel_pin { + * @pm_suspend_backup: backup/restore register values on suspend/resume + * @dev: device entry for the Atmel PIO controller. + * @node: node of the Atmel PIO controller. ++ * @slew_rate_support: slew rate support + */ + struct atmel_pioctrl { + void __iomem *reg_base; +@@ -138,6 +142,7 @@ struct atmel_pioctrl { + } *pm_suspend_backup; + struct device *dev; + struct device_node *node; ++ unsigned int slew_rate_support; + }; + + static const char * const atmel_functions[] = { +@@ -760,6 +765,13 @@ static int atmel_conf_pin_config_group_get(struct pinctrl_dev *pctldev, + return -EINVAL; + arg = 1; + break; ++ case PIN_CONFIG_SLEW_RATE: ++ if (!atmel_pioctrl->slew_rate_support) ++ return -EOPNOTSUPP; ++ if (!(res & ATMEL_PIO_SR_MASK)) ++ return -EINVAL; ++ arg = 1; ++ break; + case ATMEL_PIN_CONFIG_DRIVE_STRENGTH: + if (!(res & ATMEL_PIO_DRVSTR_MASK)) + return -EINVAL; +@@ -793,6 +805,10 @@ static int atmel_conf_pin_config_group_set(struct pinctrl_dev *pctldev, + dev_dbg(pctldev->dev, "%s: pin=%u, config=0x%lx\n", + __func__, pin_id, configs[i]); + ++ /* Keep slew rate enabled by default. */ ++ if (atmel_pioctrl->slew_rate_support) ++ conf |= ATMEL_PIO_SR_MASK; ++ + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + conf &= (~ATMEL_PIO_PUEN_MASK); +@@ -850,6 +866,13 @@ static int atmel_conf_pin_config_group_set(struct pinctrl_dev *pctldev, + ATMEL_PIO_SODR); + } + break; ++ case PIN_CONFIG_SLEW_RATE: ++ if (!atmel_pioctrl->slew_rate_support) ++ break; ++ /* And remove it if explicitly requested. */ ++ if (arg == 0) ++ conf &= ~ATMEL_PIO_SR_MASK; ++ break; + case ATMEL_PIN_CONFIG_DRIVE_STRENGTH: + switch (arg) { + case ATMEL_PIO_DRVSTR_LO: +@@ -901,6 +924,8 @@ static void atmel_conf_pin_config_dbg_show(struct pinctrl_dev *pctldev, + seq_printf(s, "%s ", "open-drain"); + if (conf & ATMEL_PIO_SCHMITT_MASK) + seq_printf(s, "%s ", "schmitt"); ++ if (atmel_pioctrl->slew_rate_support && (conf & ATMEL_PIO_SR_MASK)) ++ seq_printf(s, "%s ", "slew-rate"); + if (conf & ATMEL_PIO_DRVSTR_MASK) { + switch ((conf & ATMEL_PIO_DRVSTR_MASK) >> ATMEL_PIO_DRVSTR_OFFSET) { + case ATMEL_PIO_DRVSTR_ME: +@@ -994,6 +1019,7 @@ static const struct atmel_pioctrl_data atmel_sama5d2_pioctrl_data = { + static const struct atmel_pioctrl_data microchip_sama7g5_pioctrl_data = { + .nbanks = 5, + .last_bank_count = 8, /* sama7g5 has only PE0 to PE7 */ ++ .slew_rate_support = 1, + }; + + static const struct of_device_id atmel_pctrl_of_match[] = { +@@ -1039,6 +1065,7 @@ static int atmel_pinctrl_probe(struct platform_device *pdev) + atmel_pioctrl->npins -= ATMEL_PIO_NPINS_PER_BANK; + atmel_pioctrl->npins += atmel_pioctrl_data->last_bank_count; + } ++ atmel_pioctrl->slew_rate_support = atmel_pioctrl_data->slew_rate_support; + + atmel_pioctrl->reg_base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(atmel_pioctrl->reg_base)) +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/147-pinctrl-at91-pio4-fix-Prefer-unsigned-int-to-bare-us.patch b/target/linux/at91/patches-5.10/147-pinctrl-at91-pio4-fix-Prefer-unsigned-int-to-bare-us.patch new file mode 100644 index 0000000000..e3931bce64 --- /dev/null +++ b/target/linux/at91/patches-5.10/147-pinctrl-at91-pio4-fix-Prefer-unsigned-int-to-bare-us.patch @@ -0,0 +1,345 @@ +From 99629d1ad7e4e03ac3324d36b703220555b65566 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Wed, 27 Jan 2021 13:45:45 +0200 +Subject: [PATCH 147/247] pinctrl: at91-pio4: fix "Prefer 'unsigned int' to + bare use of 'unsigned'" + +Fix "Prefer 'unsigned int' to bare use of 'unsigned'" checkpatch.pl +warning. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Acked-by: Ludovic Desroches <ludovic.desroches@microchip.com> +Link: https://lore.kernel.org/r/1611747945-29960-4-git-send-email-claudiu.beznea@microchip.com +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +--- + drivers/pinctrl/pinctrl-at91-pio4.c | 110 ++++++++++++++-------------- + 1 file changed, 57 insertions(+), 53 deletions(-) + +diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c +index f202cdb6dc3c..a5d328808e4c 100644 +--- a/drivers/pinctrl/pinctrl-at91-pio4.c ++++ b/drivers/pinctrl/pinctrl-at91-pio4.c +@@ -80,8 +80,8 @@ + * @slew_rate_support: slew rate support + */ + struct atmel_pioctrl_data { +- unsigned nbanks; +- unsigned last_bank_count; ++ unsigned int nbanks; ++ unsigned int last_bank_count; + unsigned int slew_rate_support; + }; + +@@ -91,11 +91,11 @@ struct atmel_group { + }; + + struct atmel_pin { +- unsigned pin_id; +- unsigned mux; +- unsigned ioset; +- unsigned bank; +- unsigned line; ++ unsigned int pin_id; ++ unsigned int mux; ++ unsigned int ioset; ++ unsigned int bank; ++ unsigned int line; + const char *device; + }; + +@@ -125,16 +125,16 @@ struct atmel_pin { + struct atmel_pioctrl { + void __iomem *reg_base; + struct clk *clk; +- unsigned nbanks; ++ unsigned int nbanks; + struct pinctrl_dev *pinctrl_dev; + struct atmel_group *groups; + const char * const *group_names; + struct atmel_pin **pins; +- unsigned npins; ++ unsigned int npins; + struct gpio_chip *gpio_chip; + struct irq_domain *irq_domain; + int *irqs; +- unsigned *pm_wakeup_sources; ++ unsigned int *pm_wakeup_sources; + struct { + u32 imr; + u32 odsr; +@@ -177,11 +177,11 @@ static void atmel_gpio_irq_ack(struct irq_data *d) + */ + } + +-static int atmel_gpio_irq_set_type(struct irq_data *d, unsigned type) ++static int atmel_gpio_irq_set_type(struct irq_data *d, unsigned int type) + { + struct atmel_pioctrl *atmel_pioctrl = irq_data_get_irq_chip_data(d); + struct atmel_pin *pin = atmel_pioctrl->pins[d->hwirq]; +- unsigned reg; ++ unsigned int reg; + + atmel_gpio_write(atmel_pioctrl, pin->bank, ATMEL_PIO_MSKR, + BIT(pin->line)); +@@ -268,7 +268,7 @@ static struct irq_chip atmel_gpio_irq_chip = { + .irq_set_wake = atmel_gpio_irq_set_wake, + }; + +-static int atmel_gpio_to_irq(struct gpio_chip *chip, unsigned offset) ++static int atmel_gpio_to_irq(struct gpio_chip *chip, unsigned int offset) + { + struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(chip); + +@@ -316,11 +316,12 @@ static void atmel_gpio_irq_handler(struct irq_desc *desc) + chained_irq_exit(chip, desc); + } + +-static int atmel_gpio_direction_input(struct gpio_chip *chip, unsigned offset) ++static int atmel_gpio_direction_input(struct gpio_chip *chip, ++ unsigned int offset) + { + struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(chip); + struct atmel_pin *pin = atmel_pioctrl->pins[offset]; +- unsigned reg; ++ unsigned int reg; + + atmel_gpio_write(atmel_pioctrl, pin->bank, ATMEL_PIO_MSKR, + BIT(pin->line)); +@@ -331,11 +332,11 @@ static int atmel_gpio_direction_input(struct gpio_chip *chip, unsigned offset) + return 0; + } + +-static int atmel_gpio_get(struct gpio_chip *chip, unsigned offset) ++static int atmel_gpio_get(struct gpio_chip *chip, unsigned int offset) + { + struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(chip); + struct atmel_pin *pin = atmel_pioctrl->pins[offset]; +- unsigned reg; ++ unsigned int reg; + + reg = atmel_gpio_read(atmel_pioctrl, pin->bank, ATMEL_PIO_PDSR); + +@@ -369,12 +370,13 @@ static int atmel_gpio_get_multiple(struct gpio_chip *chip, unsigned long *mask, + return 0; + } + +-static int atmel_gpio_direction_output(struct gpio_chip *chip, unsigned offset, ++static int atmel_gpio_direction_output(struct gpio_chip *chip, ++ unsigned int offset, + int value) + { + struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(chip); + struct atmel_pin *pin = atmel_pioctrl->pins[offset]; +- unsigned reg; ++ unsigned int reg; + + atmel_gpio_write(atmel_pioctrl, pin->bank, + value ? ATMEL_PIO_SODR : ATMEL_PIO_CODR, +@@ -389,7 +391,7 @@ static int atmel_gpio_direction_output(struct gpio_chip *chip, unsigned offset, + return 0; + } + +-static void atmel_gpio_set(struct gpio_chip *chip, unsigned offset, int val) ++static void atmel_gpio_set(struct gpio_chip *chip, unsigned int offset, int val) + { + struct atmel_pioctrl *atmel_pioctrl = gpiochip_get_data(chip); + struct atmel_pin *pin = atmel_pioctrl->pins[offset]; +@@ -445,11 +447,11 @@ static struct gpio_chip atmel_gpio_chip = { + + /* --- PINCTRL --- */ + static unsigned int atmel_pin_config_read(struct pinctrl_dev *pctldev, +- unsigned pin_id) ++ unsigned int pin_id) + { + struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); +- unsigned bank = atmel_pioctrl->pins[pin_id]->bank; +- unsigned line = atmel_pioctrl->pins[pin_id]->line; ++ unsigned int bank = atmel_pioctrl->pins[pin_id]->bank; ++ unsigned int line = atmel_pioctrl->pins[pin_id]->line; + void __iomem *addr = atmel_pioctrl->reg_base + + bank * ATMEL_PIO_BANK_OFFSET; + +@@ -461,11 +463,11 @@ static unsigned int atmel_pin_config_read(struct pinctrl_dev *pctldev, + } + + static void atmel_pin_config_write(struct pinctrl_dev *pctldev, +- unsigned pin_id, u32 conf) ++ unsigned int pin_id, u32 conf) + { + struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); +- unsigned bank = atmel_pioctrl->pins[pin_id]->bank; +- unsigned line = atmel_pioctrl->pins[pin_id]->line; ++ unsigned int bank = atmel_pioctrl->pins[pin_id]->bank; ++ unsigned int line = atmel_pioctrl->pins[pin_id]->line; + void __iomem *addr = atmel_pioctrl->reg_base + + bank * ATMEL_PIO_BANK_OFFSET; + +@@ -483,7 +485,7 @@ static int atmel_pctl_get_groups_count(struct pinctrl_dev *pctldev) + } + + static const char *atmel_pctl_get_group_name(struct pinctrl_dev *pctldev, +- unsigned selector) ++ unsigned int selector) + { + struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); + +@@ -491,19 +493,20 @@ static const char *atmel_pctl_get_group_name(struct pinctrl_dev *pctldev, + } + + static int atmel_pctl_get_group_pins(struct pinctrl_dev *pctldev, +- unsigned selector, const unsigned **pins, +- unsigned *num_pins) ++ unsigned int selector, ++ const unsigned int **pins, ++ unsigned int *num_pins) + { + struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); + +- *pins = (unsigned *)&atmel_pioctrl->groups[selector].pin; ++ *pins = (unsigned int *)&atmel_pioctrl->groups[selector].pin; + *num_pins = 1; + + return 0; + } + + static struct atmel_group * +-atmel_pctl_find_group_by_pin(struct pinctrl_dev *pctldev, unsigned pin) ++atmel_pctl_find_group_by_pin(struct pinctrl_dev *pctldev, unsigned int pin) + { + struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); + int i; +@@ -524,7 +527,7 @@ static int atmel_pctl_xlate_pinfunc(struct pinctrl_dev *pctldev, + const char **func_name) + { + struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); +- unsigned pin_id, func_id; ++ unsigned int pin_id, func_id; + struct atmel_group *grp; + + pin_id = ATMEL_GET_PIN_NO(pinfunc); +@@ -554,10 +557,10 @@ static int atmel_pctl_xlate_pinfunc(struct pinctrl_dev *pctldev, + static int atmel_pctl_dt_subnode_to_map(struct pinctrl_dev *pctldev, + struct device_node *np, + struct pinctrl_map **map, +- unsigned *reserved_maps, +- unsigned *num_maps) ++ unsigned int *reserved_maps, ++ unsigned int *num_maps) + { +- unsigned num_pins, num_configs, reserve; ++ unsigned int num_pins, num_configs, reserve; + unsigned long *configs; + struct property *pins; + u32 pinfunc; +@@ -628,10 +631,10 @@ static int atmel_pctl_dt_subnode_to_map(struct pinctrl_dev *pctldev, + static int atmel_pctl_dt_node_to_map(struct pinctrl_dev *pctldev, + struct device_node *np_config, + struct pinctrl_map **map, +- unsigned *num_maps) ++ unsigned int *num_maps) + { + struct device_node *np; +- unsigned reserved_maps; ++ unsigned int reserved_maps; + int ret; + + *map = NULL; +@@ -679,13 +682,13 @@ static int atmel_pmx_get_functions_count(struct pinctrl_dev *pctldev) + } + + static const char *atmel_pmx_get_function_name(struct pinctrl_dev *pctldev, +- unsigned selector) ++ unsigned int selector) + { + return atmel_functions[selector]; + } + + static int atmel_pmx_get_function_groups(struct pinctrl_dev *pctldev, +- unsigned selector, ++ unsigned int selector, + const char * const **groups, + unsigned * const num_groups) + { +@@ -698,11 +701,11 @@ static int atmel_pmx_get_function_groups(struct pinctrl_dev *pctldev, + } + + static int atmel_pmx_set_mux(struct pinctrl_dev *pctldev, +- unsigned function, +- unsigned group) ++ unsigned int function, ++ unsigned int group) + { + struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); +- unsigned pin; ++ unsigned int pin; + u32 conf; + + dev_dbg(pctldev->dev, "enable function %s group %s\n", +@@ -726,13 +729,13 @@ static const struct pinmux_ops atmel_pmxops = { + }; + + static int atmel_conf_pin_config_group_get(struct pinctrl_dev *pctldev, +- unsigned group, ++ unsigned int group, + unsigned long *config) + { + struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); +- unsigned param = pinconf_to_config_param(*config), arg = 0; ++ unsigned int param = pinconf_to_config_param(*config), arg = 0; + struct atmel_group *grp = atmel_pioctrl->groups + group; +- unsigned pin_id = grp->pin; ++ unsigned int pin_id = grp->pin; + u32 res; + + res = atmel_pin_config_read(pctldev, pin_id); +@@ -786,21 +789,21 @@ static int atmel_conf_pin_config_group_get(struct pinctrl_dev *pctldev, + } + + static int atmel_conf_pin_config_group_set(struct pinctrl_dev *pctldev, +- unsigned group, ++ unsigned int group, + unsigned long *configs, +- unsigned num_configs) ++ unsigned int num_configs) + { + struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); + struct atmel_group *grp = atmel_pioctrl->groups + group; +- unsigned bank, pin, pin_id = grp->pin; ++ unsigned int bank, pin, pin_id = grp->pin; + u32 mask, conf = 0; + int i; + + conf = atmel_pin_config_read(pctldev, pin_id); + + for (i = 0; i < num_configs; i++) { +- unsigned param = pinconf_to_config_param(configs[i]); +- unsigned arg = pinconf_to_config_argument(configs[i]); ++ unsigned int param = pinconf_to_config_param(configs[i]); ++ unsigned int arg = pinconf_to_config_argument(configs[i]); + + dev_dbg(pctldev->dev, "%s: pin=%u, config=0x%lx\n", + __func__, pin_id, configs[i]); +@@ -900,7 +903,8 @@ static int atmel_conf_pin_config_group_set(struct pinctrl_dev *pctldev, + } + + static void atmel_conf_pin_config_dbg_show(struct pinctrl_dev *pctldev, +- struct seq_file *s, unsigned pin_id) ++ struct seq_file *s, ++ unsigned int pin_id) + { + struct atmel_pioctrl *atmel_pioctrl = pinctrl_dev_get_drvdata(pctldev); + u32 conf; +@@ -1108,8 +1112,8 @@ static int atmel_pinctrl_probe(struct platform_device *pdev) + return -ENOMEM; + for (i = 0 ; i < atmel_pioctrl->npins; i++) { + struct atmel_group *group = atmel_pioctrl->groups + i; +- unsigned bank = ATMEL_PIO_BANK(i); +- unsigned line = ATMEL_PIO_LINE(i); ++ unsigned int bank = ATMEL_PIO_BANK(i); ++ unsigned int line = ATMEL_PIO_LINE(i); + + atmel_pioctrl->pins[i] = devm_kzalloc(dev, + sizeof(**atmel_pioctrl->pins), GFP_KERNEL); +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/148-net-macb-Add-default-usrio-config-to-default-gem-con.patch b/target/linux/at91/patches-5.10/148-net-macb-Add-default-usrio-config-to-default-gem-con.patch new file mode 100644 index 0000000000..2e149cefc5 --- /dev/null +++ b/target/linux/at91/patches-5.10/148-net-macb-Add-default-usrio-config-to-default-gem-con.patch @@ -0,0 +1,63 @@ +From 096f58e564aed56936ef6de42a44c3101e9b8ed1 Mon Sep 17 00:00:00 2001 +From: Atish Patra <atish.patra@wdc.com> +Date: Wed, 3 Mar 2021 11:55:49 -0800 +Subject: [PATCH 148/247] net: macb: Add default usrio config to default gem + config + +There is no usrio config defined for default gem config leading to +a kernel panic devices that don't define a data. This issue can be +reprdouced with microchip polar fire soc where compatible string +is defined as "cdns,macb". + +Fixes: edac63861db7 ("add userio bits as platform configuration") + +Signed-off-by: Atish Patra <atish.patra@wdc.com> +Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/cadence/macb_main.c | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c +index d5bd640d3fa4..a8d266d72779 100644 +--- a/drivers/net/ethernet/cadence/macb_main.c ++++ b/drivers/net/ethernet/cadence/macb_main.c +@@ -3837,6 +3837,13 @@ static int macb_init(struct platform_device *pdev) + return 0; + } + ++static const struct macb_usrio_config macb_default_usrio = { ++ .mii = MACB_BIT(MII), ++ .rmii = MACB_BIT(RMII), ++ .rgmii = GEM_BIT(RGMII), ++ .refclk = MACB_BIT(CLKEN), ++}; ++ + #if defined(CONFIG_OF) + /* 1518 rounded up */ + #define AT91ETHER_MAX_RBUFF_SZ 0x600 +@@ -4352,13 +4359,6 @@ static int fu540_c000_init(struct platform_device *pdev) + return macb_init(pdev); + } + +-static const struct macb_usrio_config macb_default_usrio = { +- .mii = MACB_BIT(MII), +- .rmii = MACB_BIT(RMII), +- .rgmii = GEM_BIT(RGMII), +- .refclk = MACB_BIT(CLKEN), +-}; +- + static const struct macb_usrio_config sama7g5_usrio = { + .mii = 0, + .rmii = 1, +@@ -4507,6 +4507,7 @@ static const struct macb_config default_gem_config = { + .dma_burst_length = 16, + .clk_init = macb_clk_init, + .init = macb_init, ++ .usrio = &macb_default_usrio, + .jumbo_max_len = 10240, + }; + +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/149-ARM-at91-pm-Move-prototypes-to-mutually-included-hea.patch b/target/linux/at91/patches-5.10/149-ARM-at91-pm-Move-prototypes-to-mutually-included-hea.patch new file mode 100644 index 0000000000..892e8be295 --- /dev/null +++ b/target/linux/at91/patches-5.10/149-ARM-at91-pm-Move-prototypes-to-mutually-included-hea.patch @@ -0,0 +1,118 @@ +From 746aba88c64e409cbc3757a5f81fad5b5c74bbcc Mon Sep 17 00:00:00 2001 +From: Lee Jones <lee.jones@linaro.org> +Date: Wed, 3 Mar 2021 12:41:49 +0000 +Subject: [PATCH 149/247] ARM: at91: pm: Move prototypes to mutually included + header +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Both the caller and the supplier's source file should have access to +the include file containing the prototypes. + +Fixes the following W=1 kernel build warning(s): + + drivers/pinctrl/pinctrl-at91.c:1637:6: warning: no previous prototype for ‘at91_pinctrl_gpio_suspend’ [-Wmissing-prototypes] + 1637 | void at91_pinctrl_gpio_suspend(void) + | ^~~~~~~~~~~~~~~~~~~~~~~~~ + drivers/pinctrl/pinctrl-at91.c:1661:6: warning: no previous prototype for ‘at91_pinctrl_gpio_resume’ [-Wmissing-prototypes] + 1661 | void at91_pinctrl_gpio_resume(void) + | ^~~~~~~~~~~~~~~~~~~~~~~~ + +Cc: Russell King <linux@armlinux.org.uk> +Cc: Nicolas Ferre <nicolas.ferre@microchip.com> +Cc: Alexandre Belloni <alexandre.belloni@bootlin.com> +Cc: Ludovic Desroches <ludovic.desroches@microchip.com> +Signed-off-by: Lee Jones <lee.jones@linaro.org> +Acked-by: Linus Walleij <linus.walleij@linaro.org> +Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> +Link: https://lore.kernel.org/r/20210303124149.3149511-1-lee.jones@linaro.org +--- + arch/arm/mach-at91/pm.c | 19 ++++++++----------- + drivers/pinctrl/pinctrl-at91.c | 2 ++ + include/soc/at91/pm.h | 16 ++++++++++++++++ + 3 files changed, 26 insertions(+), 11 deletions(-) + create mode 100644 include/soc/at91/pm.h + +diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c +index 3f015cb6ec2b..2dee383f9050 100644 +--- a/arch/arm/mach-at91/pm.c ++++ b/arch/arm/mach-at91/pm.c +@@ -17,6 +17,8 @@ + #include <linux/clk/at91_pmc.h> + #include <linux/platform_data/atmel.h> + ++#include <soc/at91/pm.h> ++ + #include <asm/cacheflush.h> + #include <asm/fncpy.h> + #include <asm/system_misc.h> +@@ -25,17 +27,6 @@ + #include "generic.h" + #include "pm.h" + +-/* +- * FIXME: this is needed to communicate between the pinctrl driver and +- * the PM implementation in the machine. Possibly part of the PM +- * implementation should be moved down into the pinctrl driver and get +- * called as part of the generic suspend/resume path. +- */ +-#ifdef CONFIG_PINCTRL_AT91 +-extern void at91_pinctrl_gpio_suspend(void); +-extern void at91_pinctrl_gpio_resume(void); +-#endif +- + struct at91_soc_pm { + int (*config_shdwc_ws)(void __iomem *shdwc, u32 *mode, u32 *polarity); + int (*config_pmc_ws)(void __iomem *pmc, u32 mode, u32 polarity); +@@ -326,6 +317,12 @@ static void at91_pm_suspend(suspend_state_t state) + static int at91_pm_enter(suspend_state_t state) + { + #ifdef CONFIG_PINCTRL_AT91 ++ /* ++ * FIXME: this is needed to communicate between the pinctrl driver and ++ * the PM implementation in the machine. Possibly part of the PM ++ * implementation should be moved down into the pinctrl driver and get ++ * called as part of the generic suspend/resume path. ++ */ + at91_pinctrl_gpio_suspend(); + #endif + +diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c +index 9015486e38c1..dcbb71fa1b2b 100644 +--- a/drivers/pinctrl/pinctrl-at91.c ++++ b/drivers/pinctrl/pinctrl-at91.c +@@ -23,6 +23,8 @@ + /* Since we request GPIOs from ourself */ + #include <linux/pinctrl/consumer.h> + ++#include <soc/at91/pm.h> ++ + #include "pinctrl-at91.h" + #include "core.h" + +diff --git a/include/soc/at91/pm.h b/include/soc/at91/pm.h +new file mode 100644 +index 000000000000..7a41e53a3ffa +--- /dev/null ++++ b/include/soc/at91/pm.h +@@ -0,0 +1,16 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Atmel Power Management ++ * ++ * Copyright (C) 2020 Atmel ++ * ++ * Author: Lee Jones <lee.jones@linaro.org> ++ */ ++ ++#ifndef __SOC_ATMEL_PM_H ++#define __SOC_ATMEL_PM_H ++ ++void at91_pinctrl_gpio_suspend(void); ++void at91_pinctrl_gpio_resume(void); ++ ++#endif /* __SOC_ATMEL_PM_H */ +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/150-ASoC-mchp-i2s-mcc-Add-compatible-for-SAMA7G5.patch b/target/linux/at91/patches-5.10/150-ASoC-mchp-i2s-mcc-Add-compatible-for-SAMA7G5.patch new file mode 100644 index 0000000000..6749c3748b --- /dev/null +++ b/target/linux/at91/patches-5.10/150-ASoC-mchp-i2s-mcc-Add-compatible-for-SAMA7G5.patch @@ -0,0 +1,53 @@ +From d6493e6f1c42f7ad350ea25e11f0e71fc32e6116 Mon Sep 17 00:00:00 2001 +From: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Date: Mon, 1 Mar 2021 19:09:00 +0200 +Subject: [PATCH 150/247] ASoC: mchp-i2s-mcc: Add compatible for SAMA7G5 + +Microchip's new SAMA7G5 includes an updated I2S-MCC compatible with the +previous version found on SAM9X60. The new controller includes 8 (4 * 2) +input and output data pins for up to 8 channels for I2S and Left-Justified +formats. + +Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Link: https://lore.kernel.org/r/20210301170905.835091-3-codrin.ciubotariu@microchip.com +Signed-off-by: Mark Brown <broonie@kernel.org> +--- + sound/soc/atmel/Kconfig | 3 +++ + sound/soc/atmel/mchp-i2s-mcc.c | 3 +++ + 2 files changed, 6 insertions(+) + +diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig +index 89210048e6c2..802962935df0 100644 +--- a/sound/soc/atmel/Kconfig ++++ b/sound/soc/atmel/Kconfig +@@ -126,10 +126,13 @@ config SND_MCHP_SOC_I2S_MCC + Say Y or M if you want to add support for I2S Multi-Channel ASoC + driver on the following Microchip platforms: + - sam9x60 ++ - sama7g5 + + The I2SMCC complies with the Inter-IC Sound (I2S) bus specification + and supports a Time Division Multiplexed (TDM) interface with + external multi-channel audio codecs. ++ Starting with sama7g5, I2S and Left-Justified multi-channel is ++ supported by using multiple data pins, output and input, without TDM. + + config SND_MCHP_SOC_SPDIFTX + tristate "Microchip ASoC driver for boards using S/PDIF TX" +diff --git a/sound/soc/atmel/mchp-i2s-mcc.c b/sound/soc/atmel/mchp-i2s-mcc.c +index 04acc18f2d72..6a754cef9607 100644 +--- a/sound/soc/atmel/mchp-i2s-mcc.c ++++ b/sound/soc/atmel/mchp-i2s-mcc.c +@@ -873,6 +873,9 @@ static const struct of_device_id mchp_i2s_mcc_dt_ids[] = { + { + .compatible = "microchip,sam9x60-i2smcc", + }, ++ { ++ .compatible = "microchip,sama7g5-i2smcc", ++ }, + { /* sentinel */ } + }; + MODULE_DEVICE_TABLE(of, mchp_i2s_mcc_dt_ids); +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/151-ASoC-mchp-i2s-mcc-Add-multi-channel-support-for-I2S-.patch b/target/linux/at91/patches-5.10/151-ASoC-mchp-i2s-mcc-Add-multi-channel-support-for-I2S-.patch new file mode 100644 index 0000000000..a1260511f4 --- /dev/null +++ b/target/linux/at91/patches-5.10/151-ASoC-mchp-i2s-mcc-Add-multi-channel-support-for-I2S-.patch @@ -0,0 +1,118 @@ +From 5bef4e8125d09443b5486971d5550ed285cde4b1 Mon Sep 17 00:00:00 2001 +From: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Date: Mon, 1 Mar 2021 19:09:01 +0200 +Subject: [PATCH 151/247] ASoC: mchp-i2s-mcc: Add multi-channel support for I2S + and LEFT_J formats + +The latest I2S-MCC available in SAMA7G5 supports multi-channel for I2S and +Left-Justified formats. For this, the new version uses 8 (4 * 2) input and +output pins, with each pin being responsible for 2 channels. This sums up +to a total of 8 channels for synchronous capture and playback. + +Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Link: https://lore.kernel.org/r/20210301170905.835091-4-codrin.ciubotariu@microchip.com +Signed-off-by: Mark Brown <broonie@kernel.org> +--- + sound/soc/atmel/mchp-i2s-mcc.c | 38 ++++++++++++++++++++++++++++++++++ + 1 file changed, 38 insertions(+) + +diff --git a/sound/soc/atmel/mchp-i2s-mcc.c b/sound/soc/atmel/mchp-i2s-mcc.c +index 6a754cef9607..dca4fd1e2dfd 100644 +--- a/sound/soc/atmel/mchp-i2s-mcc.c ++++ b/sound/soc/atmel/mchp-i2s-mcc.c +@@ -16,6 +16,7 @@ + #include <linux/clk.h> + #include <linux/mfd/syscon.h> + #include <linux/lcm.h> ++#include <linux/of_device.h> + + #include <sound/core.h> + #include <sound/pcm.h> +@@ -225,6 +226,10 @@ static const struct regmap_config mchp_i2s_mcc_regmap_config = { + .max_register = MCHP_I2SMCC_VERSION, + }; + ++struct mchp_i2s_mcc_soc_data { ++ unsigned int data_pin_pair_num; ++}; ++ + struct mchp_i2s_mcc_dev { + struct wait_queue_head wq_txrdy; + struct wait_queue_head wq_rxrdy; +@@ -232,6 +237,7 @@ struct mchp_i2s_mcc_dev { + struct regmap *regmap; + struct clk *pclk; + struct clk *gclk; ++ const struct mchp_i2s_mcc_soc_data *soc; + struct snd_dmaengine_dai_dma_data playback; + struct snd_dmaengine_dai_dma_data capture; + unsigned int fmt; +@@ -549,6 +555,17 @@ static int mchp_i2s_mcc_hw_params(struct snd_pcm_substream *substream, + } + + if (dev->fmt & (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J)) { ++ /* for I2S and LEFT_J one pin is needed for every 2 channels */ ++ if (channels > dev->soc->data_pin_pair_num * 2) { ++ dev_err(dev->dev, ++ "unsupported number of audio channels: %d\n", ++ channels); ++ return -EINVAL; ++ } ++ ++ /* enable for interleaved format */ ++ mrb |= MCHP_I2SMCC_MRB_CRAMODE_REGULAR; ++ + switch (channels) { + case 1: + if (is_playback) +@@ -558,6 +575,12 @@ static int mchp_i2s_mcc_hw_params(struct snd_pcm_substream *substream, + break; + case 2: + break; ++ case 4: ++ mra |= MCHP_I2SMCC_MRA_WIRECFG_I2S_2_TDM_1; ++ break; ++ case 8: ++ mra |= MCHP_I2SMCC_MRA_WIRECFG_I2S_4_TDM_2; ++ break; + default: + dev_err(dev->dev, "unsupported number of audio channels\n"); + return -EINVAL; +@@ -869,12 +892,22 @@ static const struct snd_soc_component_driver mchp_i2s_mcc_component = { + }; + + #ifdef CONFIG_OF ++static struct mchp_i2s_mcc_soc_data mchp_i2s_mcc_sam9x60 = { ++ .data_pin_pair_num = 1, ++}; ++ ++static struct mchp_i2s_mcc_soc_data mchp_i2s_mcc_sama7g5 = { ++ .data_pin_pair_num = 4, ++}; ++ + static const struct of_device_id mchp_i2s_mcc_dt_ids[] = { + { + .compatible = "microchip,sam9x60-i2smcc", ++ .data = &mchp_i2s_mcc_sam9x60, + }, + { + .compatible = "microchip,sama7g5-i2smcc", ++ .data = &mchp_i2s_mcc_sama7g5, + }, + { /* sentinel */ } + }; +@@ -932,6 +965,11 @@ static int mchp_i2s_mcc_probe(struct platform_device *pdev) + dev->gclk = NULL; + } + ++ dev->soc = of_device_get_match_data(&pdev->dev); ++ if (!dev->soc) { ++ dev_err(&pdev->dev, "failed to get soc data\n"); ++ return -ENODEV; ++ } + dev->dev = &pdev->dev; + dev->regmap = regmap; + platform_set_drvdata(pdev, dev); +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/152-ASoC-mchp-i2s-mcc-Add-support-to-select-TDM-pins.patch b/target/linux/at91/patches-5.10/152-ASoC-mchp-i2s-mcc-Add-support-to-select-TDM-pins.patch new file mode 100644 index 0000000000..b4f1635e68 --- /dev/null +++ b/target/linux/at91/patches-5.10/152-ASoC-mchp-i2s-mcc-Add-support-to-select-TDM-pins.patch @@ -0,0 +1,113 @@ +From 2bbdc5b38603384996271a8817b0578a2360af2f Mon Sep 17 00:00:00 2001 +From: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Date: Mon, 1 Mar 2021 19:09:03 +0200 +Subject: [PATCH 152/247] ASoC: mchp-i2s-mcc: Add support to select TDM pins + +SAMA7G5's I2S-MCC has 4 pairs of DIN/DOUT pins. Since TDM only uses a +single pair of pins for synchronous capture and playback, the controller +needs to be told which of the pair is connected. This can be mentioned +using the "microchip,tdm-data-pair" property from DT. The property is +optional, useful only if TDM is used. If it's missing, DIN/DOUT 0 pins +will be used by default. + +Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Link: https://lore.kernel.org/r/20210301170905.835091-6-codrin.ciubotariu@microchip.com +Signed-off-by: Mark Brown <broonie@kernel.org> +--- + sound/soc/atmel/mchp-i2s-mcc.c | 52 +++++++++++++++++++++++++++++++--- + 1 file changed, 48 insertions(+), 4 deletions(-) + +diff --git a/sound/soc/atmel/mchp-i2s-mcc.c b/sound/soc/atmel/mchp-i2s-mcc.c +index dca4fd1e2dfd..0818fa864f0e 100644 +--- a/sound/soc/atmel/mchp-i2s-mcc.c ++++ b/sound/soc/atmel/mchp-i2s-mcc.c +@@ -100,6 +100,8 @@ + #define MCHP_I2SMCC_MRA_DATALENGTH_8_BITS_COMPACT (7 << 1) + + #define MCHP_I2SMCC_MRA_WIRECFG_MASK GENMASK(5, 4) ++#define MCHP_I2SMCC_MRA_WIRECFG_TDM(pin) (((pin) << 4) & \ ++ MCHP_I2SMCC_MRA_WIRECFG_MASK) + #define MCHP_I2SMCC_MRA_WIRECFG_I2S_1_TDM_0 (0 << 4) + #define MCHP_I2SMCC_MRA_WIRECFG_I2S_2_TDM_1 (1 << 4) + #define MCHP_I2SMCC_MRA_WIRECFG_I2S_4_TDM_2 (2 << 4) +@@ -245,6 +247,7 @@ struct mchp_i2s_mcc_dev { + unsigned int frame_length; + int tdm_slots; + int channels; ++ u8 tdm_data_pair; + unsigned int gclk_use:1; + unsigned int gclk_running:1; + unsigned int tx_rdy:1; +@@ -589,6 +592,8 @@ static int mchp_i2s_mcc_hw_params(struct snd_pcm_substream *substream, + if (!frame_length) + frame_length = 2 * params_physical_width(params); + } else if (dev->fmt & SND_SOC_DAIFMT_DSP_A) { ++ mra |= MCHP_I2SMCC_MRA_WIRECFG_TDM(dev->tdm_data_pair); ++ + if (dev->tdm_slots) { + if (channels % 2 && channels * 2 <= dev->tdm_slots) { + /* +@@ -914,6 +919,45 @@ static const struct of_device_id mchp_i2s_mcc_dt_ids[] = { + MODULE_DEVICE_TABLE(of, mchp_i2s_mcc_dt_ids); + #endif + ++static int mchp_i2s_mcc_soc_data_parse(struct platform_device *pdev, ++ struct mchp_i2s_mcc_dev *dev) ++{ ++ int err; ++ ++ if (!dev->soc) { ++ dev_err(&pdev->dev, "failed to get soc data\n"); ++ return -ENODEV; ++ } ++ ++ if (dev->soc->data_pin_pair_num == 1) ++ return 0; ++ ++ err = of_property_read_u8(pdev->dev.of_node, "microchip,tdm-data-pair", ++ &dev->tdm_data_pair); ++ if (err < 0 && err != -EINVAL) { ++ dev_err(&pdev->dev, ++ "bad property data for 'microchip,tdm-data-pair': %d", ++ err); ++ return err; ++ } ++ if (err == -EINVAL) { ++ dev_info(&pdev->dev, ++ "'microchip,tdm-data-pair' not found; assuming DIN/DOUT 0 for TDM\n"); ++ dev->tdm_data_pair = 0; ++ } else { ++ if (dev->tdm_data_pair > dev->soc->data_pin_pair_num - 1) { ++ dev_err(&pdev->dev, ++ "invalid value for 'microchip,tdm-data-pair': %d\n", ++ dev->tdm_data_pair); ++ return -EINVAL; ++ } ++ dev_dbg(&pdev->dev, "TMD format on DIN/DOUT %d pins\n", ++ dev->tdm_data_pair); ++ } ++ ++ return 0; ++} ++ + static int mchp_i2s_mcc_probe(struct platform_device *pdev) + { + struct mchp_i2s_mcc_dev *dev; +@@ -966,10 +1010,10 @@ static int mchp_i2s_mcc_probe(struct platform_device *pdev) + } + + dev->soc = of_device_get_match_data(&pdev->dev); +- if (!dev->soc) { +- dev_err(&pdev->dev, "failed to get soc data\n"); +- return -ENODEV; +- } ++ err = mchp_i2s_mcc_soc_data_parse(pdev, dev); ++ if (err < 0) ++ return err; ++ + dev->dev = &pdev->dev; + dev->regmap = regmap; + platform_set_drvdata(pdev, dev); +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/153-ASoC-mchp-i2s-mcc-Add-FIFOs-support.patch b/target/linux/at91/patches-5.10/153-ASoC-mchp-i2s-mcc-Add-FIFOs-support.patch new file mode 100644 index 0000000000..cf2063b884 --- /dev/null +++ b/target/linux/at91/patches-5.10/153-ASoC-mchp-i2s-mcc-Add-FIFOs-support.patch @@ -0,0 +1,192 @@ +From 36bb4f0ab8e7ef69cc11d4d888aa898223b0e901 Mon Sep 17 00:00:00 2001 +From: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Date: Mon, 1 Mar 2021 19:09:04 +0200 +Subject: [PATCH 153/247] ASoC: mchp-i2s-mcc: Add FIFOs support + +I2S-MCC found on SAMA7G5 includes 2 FIFOs (capture and playback). When +FIFOs are enabled, bits I2SMCC_ISRA.TXLRDYx and I2SMCC_ISRA.TXRRDYx must +not be used. Bits I2SMCC_ISRB.TXFFRDY and I2SMCC_ISRB.RXFFRDY must be used +instead. + +Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Link: https://lore.kernel.org/r/20210301170905.835091-7-codrin.ciubotariu@microchip.com +Signed-off-by: Mark Brown <broonie@kernel.org> +--- + sound/soc/atmel/mchp-i2s-mcc.c | 76 +++++++++++++++++++++++++--------- + 1 file changed, 56 insertions(+), 20 deletions(-) + +diff --git a/sound/soc/atmel/mchp-i2s-mcc.c b/sound/soc/atmel/mchp-i2s-mcc.c +index 0818fa864f0e..188484e84f94 100644 +--- a/sound/soc/atmel/mchp-i2s-mcc.c ++++ b/sound/soc/atmel/mchp-i2s-mcc.c +@@ -176,7 +176,7 @@ + */ + #define MCHP_I2SMCC_MRB_CRAMODE_REGULAR (1 << 0) + +-#define MCHP_I2SMCC_MRB_FIFOEN BIT(1) ++#define MCHP_I2SMCC_MRB_FIFOEN BIT(4) + + #define MCHP_I2SMCC_MRB_DMACHUNK_MASK GENMASK(9, 8) + #define MCHP_I2SMCC_MRB_DMACHUNK(no_words) \ +@@ -230,6 +230,7 @@ static const struct regmap_config mchp_i2s_mcc_regmap_config = { + + struct mchp_i2s_mcc_soc_data { + unsigned int data_pin_pair_num; ++ bool has_fifo; + }; + + struct mchp_i2s_mcc_dev { +@@ -257,7 +258,7 @@ struct mchp_i2s_mcc_dev { + static irqreturn_t mchp_i2s_mcc_interrupt(int irq, void *dev_id) + { + struct mchp_i2s_mcc_dev *dev = dev_id; +- u32 sra, imra, srb, imrb, pendinga, pendingb, idra = 0; ++ u32 sra, imra, srb, imrb, pendinga, pendingb, idra = 0, idrb = 0; + irqreturn_t ret = IRQ_NONE; + + regmap_read(dev->regmap, MCHP_I2SMCC_IMRA, &imra); +@@ -275,24 +276,36 @@ static irqreturn_t mchp_i2s_mcc_interrupt(int irq, void *dev_id) + * Tx/Rx ready interrupts are enabled when stopping only, to assure + * availability and to disable clocks if necessary + */ +- idra |= pendinga & (MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels) | +- MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)); +- if (idra) ++ if (dev->soc->has_fifo) { ++ idrb |= pendingb & (MCHP_I2SMCC_INT_TXFFRDY | ++ MCHP_I2SMCC_INT_RXFFRDY); ++ } else { ++ idra |= pendinga & (MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels) | ++ MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)); ++ } ++ if (idra || idrb) + ret = IRQ_HANDLED; + +- if ((imra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)) && +- (imra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)) == +- (idra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels))) { ++ if ((!dev->soc->has_fifo && ++ (imra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)) && ++ (imra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)) == ++ (idra & MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels))) || ++ (dev->soc->has_fifo && imrb & MCHP_I2SMCC_INT_TXFFRDY)) { + dev->tx_rdy = 1; + wake_up_interruptible(&dev->wq_txrdy); + } +- if ((imra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)) && +- (imra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)) == +- (idra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels))) { ++ if ((!dev->soc->has_fifo && ++ (imra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)) && ++ (imra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)) == ++ (idra & MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels))) || ++ (dev->soc->has_fifo && imrb & MCHP_I2SMCC_INT_RXFFRDY)) { + dev->rx_rdy = 1; + wake_up_interruptible(&dev->wq_rxrdy); + } +- regmap_write(dev->regmap, MCHP_I2SMCC_IDRA, idra); ++ if (dev->soc->has_fifo) ++ regmap_write(dev->regmap, MCHP_I2SMCC_IDRB, idrb); ++ else ++ regmap_write(dev->regmap, MCHP_I2SMCC_IDRA, idra); + + return ret; + } +@@ -664,6 +677,10 @@ static int mchp_i2s_mcc_hw_params(struct snd_pcm_substream *substream, + } + } + ++ /* enable FIFO if available */ ++ if (dev->soc->has_fifo) ++ mrb |= MCHP_I2SMCC_MRB_FIFOEN; ++ + /* + * If we are already running, the wanted setup must be + * the same with the one that's currently ongoing +@@ -726,8 +743,13 @@ static int mchp_i2s_mcc_hw_free(struct snd_pcm_substream *substream, + if (err == 0) { + dev_warn_once(dev->dev, + "Timeout waiting for Tx ready\n"); +- regmap_write(dev->regmap, MCHP_I2SMCC_IDRA, +- MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)); ++ if (dev->soc->has_fifo) ++ regmap_write(dev->regmap, MCHP_I2SMCC_IDRB, ++ MCHP_I2SMCC_INT_TXFFRDY); ++ else ++ regmap_write(dev->regmap, MCHP_I2SMCC_IDRA, ++ MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels)); ++ + dev->tx_rdy = 1; + } + } else { +@@ -737,8 +759,12 @@ static int mchp_i2s_mcc_hw_free(struct snd_pcm_substream *substream, + if (err == 0) { + dev_warn_once(dev->dev, + "Timeout waiting for Rx ready\n"); +- regmap_write(dev->regmap, MCHP_I2SMCC_IDRA, +- MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)); ++ if (dev->soc->has_fifo) ++ regmap_write(dev->regmap, MCHP_I2SMCC_IDRB, ++ MCHP_I2SMCC_INT_RXFFRDY); ++ else ++ regmap_write(dev->regmap, MCHP_I2SMCC_IDRA, ++ MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels)); + dev->rx_rdy = 1; + } + } +@@ -765,7 +791,7 @@ static int mchp_i2s_mcc_trigger(struct snd_pcm_substream *substream, int cmd, + struct mchp_i2s_mcc_dev *dev = snd_soc_dai_get_drvdata(dai); + bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK); + u32 cr = 0; +- u32 iera = 0; ++ u32 iera = 0, ierb = 0; + u32 sr; + int err; + +@@ -789,7 +815,10 @@ static int mchp_i2s_mcc_trigger(struct snd_pcm_substream *substream, int cmd, + * Enable Tx Ready interrupts on all channels + * to assure all data is sent + */ +- iera = MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels); ++ if (dev->soc->has_fifo) ++ ierb = MCHP_I2SMCC_INT_TXFFRDY; ++ else ++ iera = MCHP_I2SMCC_INT_TXRDY_MASK(dev->channels); + } else if (!is_playback && (sr & MCHP_I2SMCC_SR_RXEN)) { + cr = MCHP_I2SMCC_CR_RXDIS; + dev->rx_rdy = 0; +@@ -797,7 +826,10 @@ static int mchp_i2s_mcc_trigger(struct snd_pcm_substream *substream, int cmd, + * Enable Rx Ready interrupts on all channels + * to assure all data is received + */ +- iera = MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels); ++ if (dev->soc->has_fifo) ++ ierb = MCHP_I2SMCC_INT_RXFFRDY; ++ else ++ iera = MCHP_I2SMCC_INT_RXRDY_MASK(dev->channels); + } + break; + default: +@@ -815,7 +847,10 @@ static int mchp_i2s_mcc_trigger(struct snd_pcm_substream *substream, int cmd, + } + } + +- regmap_write(dev->regmap, MCHP_I2SMCC_IERA, iera); ++ if (dev->soc->has_fifo) ++ regmap_write(dev->regmap, MCHP_I2SMCC_IERB, ierb); ++ else ++ regmap_write(dev->regmap, MCHP_I2SMCC_IERA, iera); + regmap_write(dev->regmap, MCHP_I2SMCC_CR, cr); + + return 0; +@@ -903,6 +938,7 @@ static struct mchp_i2s_mcc_soc_data mchp_i2s_mcc_sam9x60 = { + + static struct mchp_i2s_mcc_soc_data mchp_i2s_mcc_sama7g5 = { + .data_pin_pair_num = 4, ++ .has_fifo = true, + }; + + static const struct of_device_id mchp_i2s_mcc_dt_ids[] = { +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/154-pinctrl-at91-pio4-Fix-slew-rate-disablement.patch b/target/linux/at91/patches-5.10/154-pinctrl-at91-pio4-Fix-slew-rate-disablement.patch new file mode 100644 index 0000000000..6235f91b9c --- /dev/null +++ b/target/linux/at91/patches-5.10/154-pinctrl-at91-pio4-Fix-slew-rate-disablement.patch @@ -0,0 +1,54 @@ +From dc07cbae6e96843d26e8f10b16e901620bd16462 Mon Sep 17 00:00:00 2001 +From: Tudor Ambarus <tudor.ambarus@microchip.com> +Date: Fri, 9 Apr 2021 11:25:22 +0300 +Subject: [PATCH 154/247] pinctrl: at91-pio4: Fix slew rate disablement + +The slew rate was enabled by default for each configuration of the +pin. In case the pin had more than one configuration, even if +we set the slew rate as disabled in the device tree, the next pin +configuration would set again the slew rate enabled by default, +overwriting the slew rate disablement. +Instead of enabling the slew rate by default for each pin configuration, +enable the slew rate by default just once per pin, regardless of the +number of configurations. This way the slew rate disablement will also +work for cases where pins have multiple configurations. + +Fixes: c709135e576b ("pinctrl: at91-pio4: add support for slew-rate") +Signed-off-by: Tudor Ambarus <tudor.ambarus@microchip.com> +Reviewed-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Acked-by: Ludovic Desroches <ludovic.desroches@microchip.com> +Link: https://lore.kernel.org/r/20210409082522.625168-1-tudor.ambarus@microchip.com +Signed-off-by: Linus Walleij <linus.walleij@linaro.org> +--- + drivers/pinctrl/pinctrl-at91-pio4.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c +index a5d328808e4c..4c01d8471ffa 100644 +--- a/drivers/pinctrl/pinctrl-at91-pio4.c ++++ b/drivers/pinctrl/pinctrl-at91-pio4.c +@@ -801,6 +801,10 @@ static int atmel_conf_pin_config_group_set(struct pinctrl_dev *pctldev, + + conf = atmel_pin_config_read(pctldev, pin_id); + ++ /* Keep slew rate enabled by default. */ ++ if (atmel_pioctrl->slew_rate_support) ++ conf |= ATMEL_PIO_SR_MASK; ++ + for (i = 0; i < num_configs; i++) { + unsigned int param = pinconf_to_config_param(configs[i]); + unsigned int arg = pinconf_to_config_argument(configs[i]); +@@ -808,10 +812,6 @@ static int atmel_conf_pin_config_group_set(struct pinctrl_dev *pctldev, + dev_dbg(pctldev->dev, "%s: pin=%u, config=0x%lx\n", + __func__, pin_id, configs[i]); + +- /* Keep slew rate enabled by default. */ +- if (atmel_pioctrl->slew_rate_support) +- conf |= ATMEL_PIO_SR_MASK; +- + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: + conf &= (~ATMEL_PIO_PUEN_MASK); +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/155-media-atmel-properly-get-pm_runtime.patch b/target/linux/at91/patches-5.10/155-media-atmel-properly-get-pm_runtime.patch new file mode 100644 index 0000000000..f8e7a24ce6 --- /dev/null +++ b/target/linux/at91/patches-5.10/155-media-atmel-properly-get-pm_runtime.patch @@ -0,0 +1,166 @@ +From c7660cc977621c4a14d870d523918df067f0db39 Mon Sep 17 00:00:00 2001 +From: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +Date: Fri, 23 Apr 2021 16:47:42 +0200 +Subject: [PATCH 155/247] media: atmel: properly get pm_runtime + +There are several issues in the way the atmel driver handles +pm_runtime_get_sync(): + +- it doesn't check return codes; +- it doesn't properly decrement the usage_count on all places; +- it starts streaming even if pm_runtime_get_sync() fails. +- while it tries to get pm_runtime at the clock enable logic, + it doesn't check if the operation was suceeded. + +Replace all occurrences of it to use the new kAPI: +pm_runtime_resume_and_get(), which ensures that, if the +return code is not negative, the usage_count was incremented. + +With that, add additional checks when this is called, in order +to ensure that errors will be properly addressed. + +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 30 ++++++++++++++----- + drivers/media/platform/atmel/atmel-isi.c | 19 +++++++++--- + 2 files changed, 38 insertions(+), 11 deletions(-) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index fe3ec8d0eaee..ce8e1351fa53 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -294,9 +294,13 @@ static int isc_wait_clk_stable(struct clk_hw *hw) + static int isc_clk_prepare(struct clk_hw *hw) + { + struct isc_clk *isc_clk = to_isc_clk(hw); ++ int ret; + +- if (isc_clk->id == ISC_ISPCK) +- pm_runtime_get_sync(isc_clk->dev); ++ if (isc_clk->id == ISC_ISPCK) { ++ ret = pm_runtime_resume_and_get(isc_clk->dev); ++ if (ret < 0) ++ return ret; ++ } + + return isc_wait_clk_stable(hw); + } +@@ -353,9 +357,13 @@ static int isc_clk_is_enabled(struct clk_hw *hw) + { + struct isc_clk *isc_clk = to_isc_clk(hw); + u32 status; ++ int ret; + +- if (isc_clk->id == ISC_ISPCK) +- pm_runtime_get_sync(isc_clk->dev); ++ if (isc_clk->id == ISC_ISPCK) { ++ ret = pm_runtime_resume_and_get(isc_clk->dev); ++ if (ret < 0) ++ return 0; ++ } + + regmap_read(isc_clk->regmap, ISC_CLKSR, &status); + +@@ -807,7 +815,12 @@ static int isc_start_streaming(struct vb2_queue *vq, unsigned int count) + goto err_start_stream; + } + +- pm_runtime_get_sync(isc->dev); ++ ret = pm_runtime_resume_and_get(isc->dev); ++ if (ret < 0) { ++ v4l2_err(&isc->v4l2_dev, "RPM resume failed in subdev %d\n", ++ ret); ++ goto err_pm_get; ++ } + + ret = isc_configure(isc); + if (unlikely(ret)) +@@ -838,7 +851,7 @@ static int isc_start_streaming(struct vb2_queue *vq, unsigned int count) + + err_configure: + pm_runtime_put_sync(isc->dev); +- ++err_pm_get: + v4l2_subdev_call(isc->current_subdev->sd, video, s_stream, 0); + + err_start_stream: +@@ -1809,6 +1822,7 @@ static void isc_awb_work(struct work_struct *w) + u32 baysel; + unsigned long flags; + u32 min, max; ++ int ret; + + /* streaming is not active anymore */ + if (isc->stop) +@@ -1831,7 +1845,9 @@ static void isc_awb_work(struct work_struct *w) + ctrls->hist_id = hist_id; + baysel = isc->config.sd_format->cfa_baycfg << ISC_HIS_CFG_BAYSEL_SHIFT; + +- pm_runtime_get_sync(isc->dev); ++ ret = pm_runtime_resume_and_get(isc->dev); ++ if (ret < 0) ++ return; + + /* + * only update if we have all the required histograms and controls +diff --git a/drivers/media/platform/atmel/atmel-isi.c b/drivers/media/platform/atmel/atmel-isi.c +index d74aa73f26be..4ac5b7c19d0c 100644 +--- a/drivers/media/platform/atmel/atmel-isi.c ++++ b/drivers/media/platform/atmel/atmel-isi.c +@@ -423,7 +423,9 @@ static int start_streaming(struct vb2_queue *vq, unsigned int count) + struct frame_buffer *buf, *node; + int ret; + +- pm_runtime_get_sync(isi->dev); ++ ret = pm_runtime_resume_and_get(isi->dev); ++ if (ret < 0) ++ return ret; + + /* Enable stream on the sub device */ + ret = v4l2_subdev_call(isi->entity.subdev, video, s_stream, 1); +@@ -783,9 +785,10 @@ static int isi_enum_frameintervals(struct file *file, void *fh, + return 0; + } + +-static void isi_camera_set_bus_param(struct atmel_isi *isi) ++static int isi_camera_set_bus_param(struct atmel_isi *isi) + { + u32 cfg1 = 0; ++ int ret; + + /* set bus param for ISI */ + if (isi->pdata.hsync_act_low) +@@ -802,12 +805,16 @@ static void isi_camera_set_bus_param(struct atmel_isi *isi) + cfg1 |= ISI_CFG1_THMASK_BEATS_16; + + /* Enable PM and peripheral clock before operate isi registers */ +- pm_runtime_get_sync(isi->dev); ++ ret = pm_runtime_resume_and_get(isi->dev); ++ if (ret < 0) ++ return ret; + + isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS); + isi_writel(isi, ISI_CFG1, cfg1); + + pm_runtime_put(isi->dev); ++ ++ return 0; + } + + /* -----------------------------------------------------------------------*/ +@@ -1086,7 +1093,11 @@ static int isi_graph_notify_complete(struct v4l2_async_notifier *notifier) + dev_err(isi->dev, "No supported mediabus format found\n"); + return ret; + } +- isi_camera_set_bus_param(isi); ++ ret = isi_camera_set_bus_param(isi); ++ if (ret) { ++ dev_err(isi->dev, "Can't wake up device\n"); ++ return ret; ++ } + + ret = isi_set_default_fmt(isi); + if (ret) { +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/156-media-atmel-atmel-isc-Remove-redundant-assignment-to.patch b/target/linux/at91/patches-5.10/156-media-atmel-atmel-isc-Remove-redundant-assignment-to.patch new file mode 100644 index 0000000000..4efc841078 --- /dev/null +++ b/target/linux/at91/patches-5.10/156-media-atmel-atmel-isc-Remove-redundant-assignment-to.patch @@ -0,0 +1,37 @@ +From b074b4695004b793a9199716295cb76da6c41686 Mon Sep 17 00:00:00 2001 +From: Jiapeng Chong <jiapeng.chong@linux.alibaba.com> +Date: Mon, 17 May 2021 12:07:48 +0200 +Subject: [PATCH 156/247] media: atmel: atmel-isc: Remove redundant assignment + to i + +Variable i is being assigned a value however the assignment is +never read, so this redundant assignment can be removed. + +Clean up the following clang-analyzer warning: + +drivers/media/platform/atmel/atmel-isc-base.c:975:2: warning: Value +stored to 'i' is never read [clang-analyzer-deadcode.DeadStores]. + +Reported-by: Abaci Robot <abaci@linux.alibaba.com> +Signed-off-by: Jiapeng Chong <jiapeng.chong@linux.alibaba.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index ce8e1351fa53..a017572c870c 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -972,7 +972,6 @@ static int isc_enum_fmt_vid_cap(struct file *file, void *priv, + + index -= ARRAY_SIZE(controller_formats); + +- i = 0; + supported_index = 0; + + for (i = 0; i < ARRAY_SIZE(formats_list); i++) { +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/157-media-atmel-atmel-isc-specialize-gamma-table-into-pr.patch b/target/linux/at91/patches-5.10/157-media-atmel-atmel-isc-specialize-gamma-table-into-pr.patch new file mode 100644 index 0000000000..838d6b2cf8 --- /dev/null +++ b/target/linux/at91/patches-5.10/157-media-atmel-atmel-isc-specialize-gamma-table-into-pr.patch @@ -0,0 +1,196 @@ +From c3f54d192dc7344c5216a3628b67c4bbccbf8c3c Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:56:59 +0200 +Subject: [PATCH 157/247] media: atmel: atmel-isc: specialize gamma table into + product specific + +Separate the gamma table from the isc base file into the specific sama5d2 +product file. +Add a pointer to the gamma table and entries count inside the platform +driver specific struct. + +[hverkuil: made isc_sama5d2_gamma_table static] + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 47 ++----------------- + drivers/media/platform/atmel/atmel-isc.h | 11 +++-- + .../media/platform/atmel/atmel-sama5d2-isc.c | 45 ++++++++++++++++++ + 3 files changed, 56 insertions(+), 47 deletions(-) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index a017572c870c..46d384332a58 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -176,48 +176,6 @@ struct isc_format formats_list[] = { + + }; + +-/* Gamma table with gamma 1/2.2 */ +-const u32 isc_gamma_table[GAMMA_MAX + 1][GAMMA_ENTRIES] = { +- /* 0 --> gamma 1/1.8 */ +- { 0x65, 0x66002F, 0x950025, 0xBB0020, 0xDB001D, 0xF8001A, +- 0x1130018, 0x12B0017, 0x1420016, 0x1580014, 0x16D0013, 0x1810012, +- 0x1940012, 0x1A60012, 0x1B80011, 0x1C90010, 0x1DA0010, 0x1EA000F, +- 0x1FA000F, 0x209000F, 0x218000F, 0x227000E, 0x235000E, 0x243000E, +- 0x251000E, 0x25F000D, 0x26C000D, 0x279000D, 0x286000D, 0x293000C, +- 0x2A0000C, 0x2AC000C, 0x2B8000C, 0x2C4000C, 0x2D0000B, 0x2DC000B, +- 0x2E7000B, 0x2F3000B, 0x2FE000B, 0x309000B, 0x314000B, 0x31F000A, +- 0x32A000A, 0x334000B, 0x33F000A, 0x349000A, 0x354000A, 0x35E000A, +- 0x368000A, 0x372000A, 0x37C000A, 0x386000A, 0x3900009, 0x399000A, +- 0x3A30009, 0x3AD0009, 0x3B60009, 0x3BF000A, 0x3C90009, 0x3D20009, +- 0x3DB0009, 0x3E40009, 0x3ED0009, 0x3F60009 }, +- +- /* 1 --> gamma 1/2 */ +- { 0x7F, 0x800034, 0xB50028, 0xDE0021, 0x100001E, 0x11E001B, +- 0x1390019, 0x1520017, 0x16A0015, 0x1800014, 0x1940014, 0x1A80013, +- 0x1BB0012, 0x1CD0011, 0x1DF0010, 0x1EF0010, 0x200000F, 0x20F000F, +- 0x21F000E, 0x22D000F, 0x23C000E, 0x24A000E, 0x258000D, 0x265000D, +- 0x273000C, 0x27F000D, 0x28C000C, 0x299000C, 0x2A5000C, 0x2B1000B, +- 0x2BC000C, 0x2C8000B, 0x2D3000C, 0x2DF000B, 0x2EA000A, 0x2F5000A, +- 0x2FF000B, 0x30A000A, 0x314000B, 0x31F000A, 0x329000A, 0x333000A, +- 0x33D0009, 0x3470009, 0x350000A, 0x35A0009, 0x363000A, 0x36D0009, +- 0x3760009, 0x37F0009, 0x3880009, 0x3910009, 0x39A0009, 0x3A30009, +- 0x3AC0008, 0x3B40009, 0x3BD0008, 0x3C60008, 0x3CE0008, 0x3D60009, +- 0x3DF0008, 0x3E70008, 0x3EF0008, 0x3F70008 }, +- +- /* 2 --> gamma 1/2.2 */ +- { 0x99, 0x9B0038, 0xD4002A, 0xFF0023, 0x122001F, 0x141001B, +- 0x15D0019, 0x1760017, 0x18E0015, 0x1A30015, 0x1B80013, 0x1CC0012, +- 0x1DE0011, 0x1F00010, 0x2010010, 0x2110010, 0x221000F, 0x230000F, +- 0x23F000E, 0x24D000E, 0x25B000D, 0x269000C, 0x276000C, 0x283000C, +- 0x28F000C, 0x29B000C, 0x2A7000C, 0x2B3000B, 0x2BF000B, 0x2CA000B, +- 0x2D5000B, 0x2E0000A, 0x2EB000A, 0x2F5000A, 0x2FF000A, 0x30A000A, +- 0x3140009, 0x31E0009, 0x327000A, 0x3310009, 0x33A0009, 0x3440009, +- 0x34D0009, 0x3560009, 0x35F0009, 0x3680008, 0x3710008, 0x3790009, +- 0x3820008, 0x38A0008, 0x3930008, 0x39B0008, 0x3A30008, 0x3AB0008, +- 0x3B30008, 0x3BB0008, 0x3C30008, 0x3CB0007, 0x3D20008, 0x3DA0007, +- 0x3E20007, 0x3E90007, 0x3F00008, 0x3F80007 }, +-}; +- + #define ISC_IS_FORMAT_RAW(mbus_code) \ + (((mbus_code) & 0xf000) == 0x3000) + +@@ -691,7 +649,7 @@ static void isc_set_pipeline(struct isc_device *isc, u32 pipeline) + + regmap_write(regmap, ISC_CFA_CFG, bay_cfg | ISC_CFA_CFG_EITPOL); + +- gamma = &isc_gamma_table[ctrls->gamma_index][0]; ++ gamma = &isc->gamma_table[ctrls->gamma_index][0]; + regmap_bulk_write(regmap, ISC_GAM_BENTRY, gamma, GAMMA_ENTRIES); + regmap_bulk_write(regmap, ISC_GAM_GENTRY, gamma, GAMMA_ENTRIES); + regmap_bulk_write(regmap, ISC_GAM_RENTRY, gamma, GAMMA_ENTRIES); +@@ -2085,7 +2043,8 @@ static int isc_ctrl_init(struct isc_device *isc) + + v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -1024, 1023, 1, 0); + v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -2048, 2047, 1, 256); +- v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAMMA, 0, GAMMA_MAX, 1, 2); ++ v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAMMA, 0, isc->gamma_max, 1, ++ isc->gamma_max); + isc->awb_ctrl = v4l2_ctrl_new_std(hdl, &isc_awb_ops, + V4L2_CID_AUTO_WHITE_BALANCE, + 0, 1, 1, 1); +diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h +index 24b784b893d6..a85b99274e34 100644 +--- a/drivers/media/platform/atmel/atmel-isc.h ++++ b/drivers/media/platform/atmel/atmel-isc.h +@@ -186,6 +186,10 @@ struct isc_ctrls { + * + * @current_subdev: current subdevice: the sensor + * @subdev_entities: list of subdevice entitites ++ * ++ * @gamma_table: pointer to the table with gamma values, has ++ * gamma_max sets of GAMMA_ENTRIES entries each ++ * @gamma_max: maximum number of sets of inside the gamma_table + */ + struct isc_device { + struct regmap *regmap; +@@ -244,16 +248,17 @@ struct isc_device { + struct v4l2_ctrl *gr_off_ctrl; + struct v4l2_ctrl *gb_off_ctrl; + }; +-}; + +-#define GAMMA_MAX 2 + #define GAMMA_ENTRIES 64 ++ /* pointer to the defined gamma table */ ++ const u32 (*gamma_table)[GAMMA_ENTRIES]; ++ u32 gamma_max; ++}; + + #define ATMEL_ISC_NAME "atmel-isc" + + extern struct isc_format formats_list[]; + extern const struct isc_format controller_formats[]; +-extern const u32 isc_gamma_table[GAMMA_MAX + 1][GAMMA_ENTRIES]; + extern const struct regmap_config isc_regmap_config; + extern const struct v4l2_async_notifier_operations isc_async_ops; + +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index a3304f49e499..1b537cd1e09e 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -54,6 +54,48 @@ + + #define ISC_CLK_MAX_DIV 255 + ++/* Gamma table with gamma 1/2.2 */ ++static const u32 isc_sama5d2_gamma_table[][GAMMA_ENTRIES] = { ++ /* 0 --> gamma 1/1.8 */ ++ { 0x65, 0x66002F, 0x950025, 0xBB0020, 0xDB001D, 0xF8001A, ++ 0x1130018, 0x12B0017, 0x1420016, 0x1580014, 0x16D0013, 0x1810012, ++ 0x1940012, 0x1A60012, 0x1B80011, 0x1C90010, 0x1DA0010, 0x1EA000F, ++ 0x1FA000F, 0x209000F, 0x218000F, 0x227000E, 0x235000E, 0x243000E, ++ 0x251000E, 0x25F000D, 0x26C000D, 0x279000D, 0x286000D, 0x293000C, ++ 0x2A0000C, 0x2AC000C, 0x2B8000C, 0x2C4000C, 0x2D0000B, 0x2DC000B, ++ 0x2E7000B, 0x2F3000B, 0x2FE000B, 0x309000B, 0x314000B, 0x31F000A, ++ 0x32A000A, 0x334000B, 0x33F000A, 0x349000A, 0x354000A, 0x35E000A, ++ 0x368000A, 0x372000A, 0x37C000A, 0x386000A, 0x3900009, 0x399000A, ++ 0x3A30009, 0x3AD0009, 0x3B60009, 0x3BF000A, 0x3C90009, 0x3D20009, ++ 0x3DB0009, 0x3E40009, 0x3ED0009, 0x3F60009 }, ++ ++ /* 1 --> gamma 1/2 */ ++ { 0x7F, 0x800034, 0xB50028, 0xDE0021, 0x100001E, 0x11E001B, ++ 0x1390019, 0x1520017, 0x16A0015, 0x1800014, 0x1940014, 0x1A80013, ++ 0x1BB0012, 0x1CD0011, 0x1DF0010, 0x1EF0010, 0x200000F, 0x20F000F, ++ 0x21F000E, 0x22D000F, 0x23C000E, 0x24A000E, 0x258000D, 0x265000D, ++ 0x273000C, 0x27F000D, 0x28C000C, 0x299000C, 0x2A5000C, 0x2B1000B, ++ 0x2BC000C, 0x2C8000B, 0x2D3000C, 0x2DF000B, 0x2EA000A, 0x2F5000A, ++ 0x2FF000B, 0x30A000A, 0x314000B, 0x31F000A, 0x329000A, 0x333000A, ++ 0x33D0009, 0x3470009, 0x350000A, 0x35A0009, 0x363000A, 0x36D0009, ++ 0x3760009, 0x37F0009, 0x3880009, 0x3910009, 0x39A0009, 0x3A30009, ++ 0x3AC0008, 0x3B40009, 0x3BD0008, 0x3C60008, 0x3CE0008, 0x3D60009, ++ 0x3DF0008, 0x3E70008, 0x3EF0008, 0x3F70008 }, ++ ++ /* 2 --> gamma 1/2.2 */ ++ { 0x99, 0x9B0038, 0xD4002A, 0xFF0023, 0x122001F, 0x141001B, ++ 0x15D0019, 0x1760017, 0x18E0015, 0x1A30015, 0x1B80013, 0x1CC0012, ++ 0x1DE0011, 0x1F00010, 0x2010010, 0x2110010, 0x221000F, 0x230000F, ++ 0x23F000E, 0x24D000E, 0x25B000D, 0x269000C, 0x276000C, 0x283000C, ++ 0x28F000C, 0x29B000C, 0x2A7000C, 0x2B3000B, 0x2BF000B, 0x2CA000B, ++ 0x2D5000B, 0x2E0000A, 0x2EB000A, 0x2F5000A, 0x2FF000A, 0x30A000A, ++ 0x3140009, 0x31E0009, 0x327000A, 0x3310009, 0x33A0009, 0x3440009, ++ 0x34D0009, 0x3560009, 0x35F0009, 0x3680008, 0x3710008, 0x3790009, ++ 0x3820008, 0x38A0008, 0x3930008, 0x39B0008, 0x3A30008, 0x3AB0008, ++ 0x3B30008, 0x3BB0008, 0x3C30008, 0x3CB0007, 0x3D20008, 0x3DA0007, ++ 0x3E20007, 0x3E90007, 0x3F00008, 0x3F80007 }, ++}; ++ + static int isc_parse_dt(struct device *dev, struct isc_device *isc) + { + struct device_node *np = dev->of_node; +@@ -171,6 +213,9 @@ static int atmel_isc_probe(struct platform_device *pdev) + return ret; + } + ++ isc->gamma_table = isc_sama5d2_gamma_table; ++ isc->gamma_max = 2; ++ + ret = isc_pipeline_init(isc); + if (ret) + return ret; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/158-media-atmel-atmel-isc-specialize-driver-name-constan.patch b/target/linux/at91/patches-5.10/158-media-atmel-atmel-isc-specialize-driver-name-constan.patch new file mode 100644 index 0000000000..b27552caa5 --- /dev/null +++ b/target/linux/at91/patches-5.10/158-media-atmel-atmel-isc-specialize-driver-name-constan.patch @@ -0,0 +1,79 @@ +From 0576e163d93d08a1ed112bd23f40478ef3fd323d Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:00 +0200 +Subject: [PATCH 158/247] media: atmel: atmel-isc: specialize driver name + constant + +The driver name constant must defined based on product driver, thus moving +the constant directly where it's required. This will allow each ISC based +product to define it's own name. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 4 ++-- + drivers/media/platform/atmel/atmel-isc.h | 2 -- + drivers/media/platform/atmel/atmel-sama5d2-isc.c | 4 ++-- + 3 files changed, 4 insertions(+), 6 deletions(-) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index 46d384332a58..d987a8891bd9 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -909,7 +909,7 @@ static int isc_querycap(struct file *file, void *priv, + { + struct isc_device *isc = video_drvdata(file); + +- strscpy(cap->driver, ATMEL_ISC_NAME, sizeof(cap->driver)); ++ strscpy(cap->driver, "microchip-isc", sizeof(cap->driver)); + strscpy(cap->card, "Atmel Image Sensor Controller", sizeof(cap->card)); + snprintf(cap->bus_info, sizeof(cap->bus_info), + "platform:%s", isc->v4l2_dev.name); +@@ -2261,7 +2261,7 @@ static int isc_async_complete(struct v4l2_async_notifier *notifier) + } + + /* Register video device */ +- strscpy(vdev->name, ATMEL_ISC_NAME, sizeof(vdev->name)); ++ strscpy(vdev->name, "microchip-isc", sizeof(vdev->name)); + vdev->release = video_device_release_empty; + vdev->fops = &isc_fops; + vdev->ioctl_ops = &isc_ioctl_ops; +diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h +index a85b99274e34..bb43d3a93052 100644 +--- a/drivers/media/platform/atmel/atmel-isc.h ++++ b/drivers/media/platform/atmel/atmel-isc.h +@@ -255,8 +255,6 @@ struct isc_device { + u32 gamma_max; + }; + +-#define ATMEL_ISC_NAME "atmel-isc" +- + extern struct isc_format formats_list[]; + extern const struct isc_format controller_formats[]; + extern const struct regmap_config isc_regmap_config; +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index 1b537cd1e09e..cba6e6c8810b 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -206,7 +206,7 @@ static int atmel_isc_probe(struct platform_device *pdev) + return irq; + + ret = devm_request_irq(dev, irq, isc_interrupt, 0, +- ATMEL_ISC_NAME, isc); ++ "atmel-sama5d2-isc", isc); + if (ret < 0) { + dev_err(dev, "can't register ISR for IRQ %u (ret=%i)\n", + irq, ret); +@@ -378,7 +378,7 @@ static struct platform_driver atmel_isc_driver = { + .probe = atmel_isc_probe, + .remove = atmel_isc_remove, + .driver = { +- .name = ATMEL_ISC_NAME, ++ .name = "atmel-sama5d2-isc", + .pm = &atmel_isc_dev_pm_ops, + .of_match_table = of_match_ptr(atmel_isc_of_match), + }, +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/159-media-atmel-atmel-isc-add-checks-for-limiting-frame-.patch b/target/linux/at91/patches-5.10/159-media-atmel-atmel-isc-add-checks-for-limiting-frame-.patch new file mode 100644 index 0000000000..24b6598d3c --- /dev/null +++ b/target/linux/at91/patches-5.10/159-media-atmel-atmel-isc-add-checks-for-limiting-frame-.patch @@ -0,0 +1,50 @@ +From de8fa25cdf3726c83ac0d7b3b1e28bcb6334aadd Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:01 +0200 +Subject: [PATCH 159/247] media: atmel: atmel-isc: add checks for limiting + frame sizes + +When calling the subdev, certain subdev drivers will overwrite the +frame size and adding sizes which are beyond the ISC's capabilities. +Thus we need to ensure the frame size is cropped to the maximum caps. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index d987a8891bd9..02f1d1c6b06e 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -1338,6 +1338,12 @@ static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f, + + v4l2_fill_pix_format(pixfmt, &format.format); + ++ /* Limit to Atmel ISC hardware capabilities */ ++ if (pixfmt->width > ISC_MAX_SUPPORT_WIDTH) ++ pixfmt->width = ISC_MAX_SUPPORT_WIDTH; ++ if (pixfmt->height > ISC_MAX_SUPPORT_HEIGHT) ++ pixfmt->height = ISC_MAX_SUPPORT_HEIGHT; ++ + pixfmt->field = V4L2_FIELD_NONE; + pixfmt->bytesperline = (pixfmt->width * isc->try_config.bpp) >> 3; + pixfmt->sizeimage = pixfmt->bytesperline * pixfmt->height; +@@ -1373,6 +1379,12 @@ static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f) + if (ret < 0) + return ret; + ++ /* Limit to Atmel ISC hardware capabilities */ ++ if (pixfmt->width > ISC_MAX_SUPPORT_WIDTH) ++ pixfmt->width = ISC_MAX_SUPPORT_WIDTH; ++ if (pixfmt->height > ISC_MAX_SUPPORT_HEIGHT) ++ pixfmt->height = ISC_MAX_SUPPORT_HEIGHT; ++ + isc->fmt = *f; + + if (isc->try_config.sd_format && isc->config.sd_format && +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/160-media-atmel-atmel-isc-specialize-max-width-and-max-h.patch b/target/linux/at91/patches-5.10/160-media-atmel-atmel-isc-specialize-max-width-and-max-h.patch new file mode 100644 index 0000000000..1508f8485f --- /dev/null +++ b/target/linux/at91/patches-5.10/160-media-atmel-atmel-isc-specialize-max-width-and-max-h.patch @@ -0,0 +1,140 @@ +From b51819e17260af2ecc152b7dcd61e63bcaa35edf Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:02 +0200 +Subject: [PATCH 160/247] media: atmel: atmel-isc: specialize max width and max + height + +Move the max width and max height constants to the product specific driver +and have them in the device struct. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 28 +++++++++---------- + drivers/media/platform/atmel/atmel-isc.h | 9 ++++-- + .../media/platform/atmel/atmel-sama5d2-isc.c | 7 +++-- + 3 files changed, 25 insertions(+), 19 deletions(-) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index 02f1d1c6b06e..ed0048e79f3b 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -1216,8 +1216,8 @@ static void isc_try_fse(struct isc_device *isc, + * just use the maximum ISC can receive. + */ + if (ret) { +- pad_cfg->try_crop.width = ISC_MAX_SUPPORT_WIDTH; +- pad_cfg->try_crop.height = ISC_MAX_SUPPORT_HEIGHT; ++ pad_cfg->try_crop.width = isc->max_width; ++ pad_cfg->try_crop.height = isc->max_height; + } else { + pad_cfg->try_crop.width = fse.max_width; + pad_cfg->try_crop.height = fse.max_height; +@@ -1294,10 +1294,10 @@ static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f, + isc->try_config.sd_format = sd_fmt; + + /* Limit to Atmel ISC hardware capabilities */ +- if (pixfmt->width > ISC_MAX_SUPPORT_WIDTH) +- pixfmt->width = ISC_MAX_SUPPORT_WIDTH; +- if (pixfmt->height > ISC_MAX_SUPPORT_HEIGHT) +- pixfmt->height = ISC_MAX_SUPPORT_HEIGHT; ++ if (pixfmt->width > isc->max_width) ++ pixfmt->width = isc->max_width; ++ if (pixfmt->height > isc->max_height) ++ pixfmt->height = isc->max_height; + + /* + * The mbus format is the one the subdev outputs. +@@ -1339,10 +1339,10 @@ static int isc_try_fmt(struct isc_device *isc, struct v4l2_format *f, + v4l2_fill_pix_format(pixfmt, &format.format); + + /* Limit to Atmel ISC hardware capabilities */ +- if (pixfmt->width > ISC_MAX_SUPPORT_WIDTH) +- pixfmt->width = ISC_MAX_SUPPORT_WIDTH; +- if (pixfmt->height > ISC_MAX_SUPPORT_HEIGHT) +- pixfmt->height = ISC_MAX_SUPPORT_HEIGHT; ++ if (pixfmt->width > isc->max_width) ++ pixfmt->width = isc->max_width; ++ if (pixfmt->height > isc->max_height) ++ pixfmt->height = isc->max_height; + + pixfmt->field = V4L2_FIELD_NONE; + pixfmt->bytesperline = (pixfmt->width * isc->try_config.bpp) >> 3; +@@ -1380,10 +1380,10 @@ static int isc_set_fmt(struct isc_device *isc, struct v4l2_format *f) + return ret; + + /* Limit to Atmel ISC hardware capabilities */ +- if (pixfmt->width > ISC_MAX_SUPPORT_WIDTH) +- pixfmt->width = ISC_MAX_SUPPORT_WIDTH; +- if (pixfmt->height > ISC_MAX_SUPPORT_HEIGHT) +- pixfmt->height = ISC_MAX_SUPPORT_HEIGHT; ++ if (f->fmt.pix.width > isc->max_width) ++ f->fmt.pix.width = isc->max_width; ++ if (f->fmt.pix.height > isc->max_height) ++ f->fmt.pix.height = isc->max_height; + + isc->fmt = *f; + +diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h +index bb43d3a93052..f208fb691ac9 100644 +--- a/drivers/media/platform/atmel/atmel-isc.h ++++ b/drivers/media/platform/atmel/atmel-isc.h +@@ -10,9 +10,6 @@ + */ + #ifndef _ATMEL_ISC_H_ + +-#define ISC_MAX_SUPPORT_WIDTH 2592 +-#define ISC_MAX_SUPPORT_HEIGHT 1944 +- + #define ISC_CLK_MAX_DIV 255 + + enum isc_clk_id { +@@ -190,6 +187,9 @@ struct isc_ctrls { + * @gamma_table: pointer to the table with gamma values, has + * gamma_max sets of GAMMA_ENTRIES entries each + * @gamma_max: maximum number of sets of inside the gamma_table ++ * ++ * @max_width: maximum frame width, dependent on the internal RAM ++ * @max_height: maximum frame height, dependent on the internal RAM + */ + struct isc_device { + struct regmap *regmap; +@@ -253,6 +253,9 @@ struct isc_device { + /* pointer to the defined gamma table */ + const u32 (*gamma_table)[GAMMA_ENTRIES]; + u32 gamma_max; ++ ++ u32 max_width; ++ u32 max_height; + }; + + extern struct isc_format formats_list[]; +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index cba6e6c8810b..39fc8d4f9bdc 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -49,8 +49,8 @@ + #include "atmel-isc-regs.h" + #include "atmel-isc.h" + +-#define ISC_MAX_SUPPORT_WIDTH 2592 +-#define ISC_MAX_SUPPORT_HEIGHT 1944 ++#define ISC_SAMA5D2_MAX_SUPPORT_WIDTH 2592 ++#define ISC_SAMA5D2_MAX_SUPPORT_HEIGHT 1944 + + #define ISC_CLK_MAX_DIV 255 + +@@ -216,6 +216,9 @@ static int atmel_isc_probe(struct platform_device *pdev) + isc->gamma_table = isc_sama5d2_gamma_table; + isc->gamma_max = 2; + ++ isc->max_width = ISC_SAMA5D2_MAX_SUPPORT_WIDTH; ++ isc->max_height = ISC_SAMA5D2_MAX_SUPPORT_HEIGHT; ++ + ret = isc_pipeline_init(isc); + if (ret) + return ret; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/161-media-atmel-atmel-isc-specialize-dma-cfg.patch b/target/linux/at91/patches-5.10/161-media-atmel-atmel-isc-specialize-dma-cfg.patch new file mode 100644 index 0000000000..4b7a974e4f --- /dev/null +++ b/target/linux/at91/patches-5.10/161-media-atmel-atmel-isc-specialize-dma-cfg.patch @@ -0,0 +1,69 @@ +From c42305f52560a1be6fc25a2f23579c7b323de654 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:03 +0200 +Subject: [PATCH 161/247] media: atmel: atmel-isc: specialize dma cfg + +The dma configuration (DCFG) is specific to the product. +Move this configuration in the product specific driver, and add the +field inside the driver struct. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 3 +-- + drivers/media/platform/atmel/atmel-isc.h | 2 ++ + drivers/media/platform/atmel/atmel-sama5d2-isc.c | 3 +++ + 3 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index ed0048e79f3b..07ba439eb7e9 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -724,8 +724,7 @@ static int isc_configure(struct isc_device *isc) + rlp_mode = isc->config.rlp_cfg_mode; + pipeline = isc->config.bits_pipeline; + +- dcfg = isc->config.dcfg_imode | +- ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; ++ dcfg = isc->config.dcfg_imode | isc->dcfg; + + pfe_cfg0 |= subdev->pfe_cfg0 | ISC_PFE_CFG0_MODE_PROGRESSIVE; + mask = ISC_PFE_CFG0_BPS_MASK | ISC_PFE_CFG0_HPOL_LOW | +diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h +index f208fb691ac9..88ec4268de11 100644 +--- a/drivers/media/platform/atmel/atmel-isc.h ++++ b/drivers/media/platform/atmel/atmel-isc.h +@@ -149,6 +149,7 @@ struct isc_ctrls { + * @hclock: Hclock clock input (refer datasheet) + * @ispck: iscpck clock (refer datasheet) + * @isc_clks: ISC clocks ++ * @dcfg: DMA master configuration, architecture dependent + * + * @dev: Registered device driver + * @v4l2_dev: v4l2 registered device +@@ -196,6 +197,7 @@ struct isc_device { + struct clk *hclock; + struct clk *ispck; + struct isc_clk isc_clks[2]; ++ u32 dcfg; + + struct device *dev; + struct v4l2_device v4l2_dev; +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index 39fc8d4f9bdc..12edeb07b618 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -219,6 +219,9 @@ static int atmel_isc_probe(struct platform_device *pdev) + isc->max_width = ISC_SAMA5D2_MAX_SUPPORT_WIDTH; + isc->max_height = ISC_SAMA5D2_MAX_SUPPORT_HEIGHT; + ++ /* sama5d2-isc - 8 bits per beat */ ++ isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; ++ + ret = isc_pipeline_init(isc); + if (ret) + return ret; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/162-media-atmel-atmel-isc-extract-CSC-submodule-config-i.patch b/target/linux/at91/patches-5.10/162-media-atmel-atmel-isc-extract-CSC-submodule-config-i.patch new file mode 100644 index 0000000000..da382d3587 --- /dev/null +++ b/target/linux/at91/patches-5.10/162-media-atmel-atmel-isc-extract-CSC-submodule-config-i.patch @@ -0,0 +1,103 @@ +From 6ccda3cf6a102ac4f6e21386d0dd0fedfb066525 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:04 +0200 +Subject: [PATCH 162/247] media: atmel: atmel-isc: extract CSC submodule config + into separate function + +The CSC submodule is a part of the atmel-isc pipeline, and stands for +Color Space Conversion. It is used to apply a matrix transformation to +RGB pixels to convert them to the YUV components. +The CSC submodule should be initialized in the product specific driver +as it's product specific. Other products can implement it differently. + +[hverkuil: made isc_sama5d2_config_csc static] + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 8 +------- + drivers/media/platform/atmel/atmel-isc.h | 7 +++++++ + drivers/media/platform/atmel/atmel-sama5d2-isc.c | 15 +++++++++++++++ + 3 files changed, 23 insertions(+), 7 deletions(-) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index 07ba439eb7e9..6c709f6a408c 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -654,13 +654,7 @@ static void isc_set_pipeline(struct isc_device *isc, u32 pipeline) + regmap_bulk_write(regmap, ISC_GAM_GENTRY, gamma, GAMMA_ENTRIES); + regmap_bulk_write(regmap, ISC_GAM_RENTRY, gamma, GAMMA_ENTRIES); + +- /* Convert RGB to YUV */ +- regmap_write(regmap, ISC_CSC_YR_YG, 0x42 | (0x81 << 16)); +- regmap_write(regmap, ISC_CSC_YB_OY, 0x19 | (0x10 << 16)); +- regmap_write(regmap, ISC_CSC_CBR_CBG, 0xFDA | (0xFB6 << 16)); +- regmap_write(regmap, ISC_CSC_CBB_OCB, 0x70 | (0x80 << 16)); +- regmap_write(regmap, ISC_CSC_CRR_CRG, 0x70 | (0xFA2 << 16)); +- regmap_write(regmap, ISC_CSC_CRB_OCR, 0xFEE | (0x80 << 16)); ++ isc->config_csc(isc); + + regmap_write(regmap, ISC_CBC_BRIGHT, ctrls->brightness); + regmap_write(regmap, ISC_CBC_CONTRAST, ctrls->contrast); +diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h +index 88ec4268de11..ebdb9ed791a7 100644 +--- a/drivers/media/platform/atmel/atmel-isc.h ++++ b/drivers/media/platform/atmel/atmel-isc.h +@@ -191,6 +191,9 @@ struct isc_ctrls { + * + * @max_width: maximum frame width, dependent on the internal RAM + * @max_height: maximum frame height, dependent on the internal RAM ++ * ++ * @config_csc: pointer to a function that initializes product ++ * specific CSC module + */ + struct isc_device { + struct regmap *regmap; +@@ -258,6 +261,10 @@ struct isc_device { + + u32 max_width; + u32 max_height; ++ ++ struct { ++ void (*config_csc)(struct isc_device *isc); ++ }; + }; + + extern struct isc_format formats_list[]; +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index 12edeb07b618..19d0f750636c 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -54,6 +54,19 @@ + + #define ISC_CLK_MAX_DIV 255 + ++static void isc_sama5d2_config_csc(struct isc_device *isc) ++{ ++ struct regmap *regmap = isc->regmap; ++ ++ /* Convert RGB to YUV */ ++ regmap_write(regmap, ISC_CSC_YR_YG, 0x42 | (0x81 << 16)); ++ regmap_write(regmap, ISC_CSC_YB_OY, 0x19 | (0x10 << 16)); ++ regmap_write(regmap, ISC_CSC_CBR_CBG, 0xFDA | (0xFB6 << 16)); ++ regmap_write(regmap, ISC_CSC_CBB_OCB, 0x70 | (0x80 << 16)); ++ regmap_write(regmap, ISC_CSC_CRR_CRG, 0x70 | (0xFA2 << 16)); ++ regmap_write(regmap, ISC_CSC_CRB_OCR, 0xFEE | (0x80 << 16)); ++} ++ + /* Gamma table with gamma 1/2.2 */ + static const u32 isc_sama5d2_gamma_table[][GAMMA_ENTRIES] = { + /* 0 --> gamma 1/1.8 */ +@@ -219,6 +232,8 @@ static int atmel_isc_probe(struct platform_device *pdev) + isc->max_width = ISC_SAMA5D2_MAX_SUPPORT_WIDTH; + isc->max_height = ISC_SAMA5D2_MAX_SUPPORT_HEIGHT; + ++ isc->config_csc = isc_sama5d2_config_csc; ++ + /* sama5d2-isc - 8 bits per beat */ + isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; + +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/163-media-atmel-atmel-isc-base-add-id-to-clock-debug-mes.patch b/target/linux/at91/patches-5.10/163-media-atmel-atmel-isc-base-add-id-to-clock-debug-mes.patch new file mode 100644 index 0000000000..f4139debc1 --- /dev/null +++ b/target/linux/at91/patches-5.10/163-media-atmel-atmel-isc-base-add-id-to-clock-debug-mes.patch @@ -0,0 +1,33 @@ +From 19dd7c72c6c457c147133a7dad8ab28d35538f99 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:05 +0200 +Subject: [PATCH 163/247] media: atmel: atmel-isc-base: add id to clock debug + message + +Add the clock id to the debug message regarding clock setup + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index 6c709f6a408c..f9190fccb482 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -281,8 +281,8 @@ static int isc_clk_enable(struct clk_hw *hw) + unsigned long flags; + unsigned int status; + +- dev_dbg(isc_clk->dev, "ISC CLK: %s, div = %d, parent id = %d\n", +- __func__, isc_clk->div, isc_clk->parent_id); ++ dev_dbg(isc_clk->dev, "ISC CLK: %s, id = %d, div = %d, parent id = %d\n", ++ __func__, id, isc_clk->div, isc_clk->parent_id); + + spin_lock_irqsave(&isc_clk->lock, flags); + regmap_update_bits(regmap, ISC_CLKCFG, +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/164-media-atmel-atmel-isc-create-register-offsets-struct.patch b/target/linux/at91/patches-5.10/164-media-atmel-atmel-isc-create-register-offsets-struct.patch new file mode 100644 index 0000000000..7834983d14 --- /dev/null +++ b/target/linux/at91/patches-5.10/164-media-atmel-atmel-isc-create-register-offsets-struct.patch @@ -0,0 +1,126 @@ +From 7a1b082cd81a2496e2687cee7ea1ef04a3020f48 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:06 +0200 +Subject: [PATCH 164/247] media: atmel: atmel-isc: create register offsets + struct + +Create a struct that holds register offsets that are product specific. +Add initially the CSC register. +This allows each product that contains a variant of the ISC to add their +own register offset. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 2 +- + drivers/media/platform/atmel/atmel-isc-regs.h | 3 +++ + drivers/media/platform/atmel/atmel-isc.h | 12 +++++++++++ + .../media/platform/atmel/atmel-sama5d2-isc.c | 20 +++++++++++++------ + 4 files changed, 30 insertions(+), 7 deletions(-) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index f9190fccb482..18136e58a754 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -2326,7 +2326,7 @@ int isc_pipeline_init(struct isc_device *isc) + REG_FIELD(ISC_GAM_CTRL, 1, 1), + REG_FIELD(ISC_GAM_CTRL, 2, 2), + REG_FIELD(ISC_GAM_CTRL, 3, 3), +- REG_FIELD(ISC_CSC_CTRL, 0, 0), ++ REG_FIELD(ISC_CSC_CTRL + isc->offsets.csc, 0, 0), + REG_FIELD(ISC_CBC_CTRL, 0, 0), + REG_FIELD(ISC_SUB422_CTRL, 0, 0), + REG_FIELD(ISC_SUB420_CTRL, 0, 0), +diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h +index f1e160ed4351..5a65600c5f88 100644 +--- a/drivers/media/platform/atmel/atmel-isc-regs.h ++++ b/drivers/media/platform/atmel/atmel-isc-regs.h +@@ -153,6 +153,9 @@ + /* ISC_Gamma Correction Green Entry Register */ + #define ISC_GAM_RENTRY 0x00000298 + ++/* Offset for CSC register specific to sama5d2 product */ ++#define ISC_SAMA5D2_CSC_OFFSET 0 ++ + /* Color Space Conversion Control Register */ + #define ISC_CSC_CTRL 0x00000398 + +diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h +index ebdb9ed791a7..db6b4d469dff 100644 +--- a/drivers/media/platform/atmel/atmel-isc.h ++++ b/drivers/media/platform/atmel/atmel-isc.h +@@ -143,6 +143,14 @@ struct isc_ctrls { + + #define ISC_PIPE_LINE_NODE_NUM 11 + ++/* ++ * struct isc_reg_offsets - ISC device register offsets ++ * @csc: Offset for the CSC register ++ */ ++struct isc_reg_offsets { ++ u32 csc; ++}; ++ + /* + * struct isc_device - ISC device driver data/config struct + * @regmap: Register map +@@ -194,6 +202,8 @@ struct isc_ctrls { + * + * @config_csc: pointer to a function that initializes product + * specific CSC module ++ * ++ * @offsets: struct holding the product specific register offsets + */ + struct isc_device { + struct regmap *regmap; +@@ -265,6 +275,8 @@ struct isc_device { + struct { + void (*config_csc)(struct isc_device *isc); + }; ++ ++ struct isc_reg_offsets offsets; + }; + + extern struct isc_format formats_list[]; +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index 19d0f750636c..2ad6227aa2f5 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -59,12 +59,18 @@ static void isc_sama5d2_config_csc(struct isc_device *isc) + struct regmap *regmap = isc->regmap; + + /* Convert RGB to YUV */ +- regmap_write(regmap, ISC_CSC_YR_YG, 0x42 | (0x81 << 16)); +- regmap_write(regmap, ISC_CSC_YB_OY, 0x19 | (0x10 << 16)); +- regmap_write(regmap, ISC_CSC_CBR_CBG, 0xFDA | (0xFB6 << 16)); +- regmap_write(regmap, ISC_CSC_CBB_OCB, 0x70 | (0x80 << 16)); +- regmap_write(regmap, ISC_CSC_CRR_CRG, 0x70 | (0xFA2 << 16)); +- regmap_write(regmap, ISC_CSC_CRB_OCR, 0xFEE | (0x80 << 16)); ++ regmap_write(regmap, ISC_CSC_YR_YG + isc->offsets.csc, ++ 0x42 | (0x81 << 16)); ++ regmap_write(regmap, ISC_CSC_YB_OY + isc->offsets.csc, ++ 0x19 | (0x10 << 16)); ++ regmap_write(regmap, ISC_CSC_CBR_CBG + isc->offsets.csc, ++ 0xFDA | (0xFB6 << 16)); ++ regmap_write(regmap, ISC_CSC_CBB_OCB + isc->offsets.csc, ++ 0x70 | (0x80 << 16)); ++ regmap_write(regmap, ISC_CSC_CRR_CRG + isc->offsets.csc, ++ 0x70 | (0xFA2 << 16)); ++ regmap_write(regmap, ISC_CSC_CRB_OCR + isc->offsets.csc, ++ 0xFEE | (0x80 << 16)); + } + + /* Gamma table with gamma 1/2.2 */ +@@ -234,6 +240,8 @@ static int atmel_isc_probe(struct platform_device *pdev) + + isc->config_csc = isc_sama5d2_config_csc; + ++ isc->offsets.csc = ISC_SAMA5D2_CSC_OFFSET; ++ + /* sama5d2-isc - 8 bits per beat */ + isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; + +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/165-media-atmel-atmel-isc-extract-CBC-submodule-config-i.patch b/target/linux/at91/patches-5.10/165-media-atmel-atmel-isc-extract-CBC-submodule-config-i.patch new file mode 100644 index 0000000000..f9d026394e --- /dev/null +++ b/target/linux/at91/patches-5.10/165-media-atmel-atmel-isc-extract-CBC-submodule-config-i.patch @@ -0,0 +1,89 @@ +From aa31e58d80d233385fa3b972e6b85f293e2a9093 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:07 +0200 +Subject: [PATCH 165/247] media: atmel: atmel-isc: extract CBC submodule config + into separate function + +The CBC submodule is a part of the atmel-isc pipeline, and stands for +Contrast Brightness Control. It is used to apply gains and offsets to the +luma (Y) and chroma (U, V) components of the YUV elements. +The CBC submodule should be initialized in the product specific driver +as it's product specific. Other products can implement it differently + +[hverkuil: made isc_sama5d2_config_cbc static] + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 4 +--- + drivers/media/platform/atmel/atmel-isc.h | 3 +++ + drivers/media/platform/atmel/atmel-sama5d2-isc.c | 9 +++++++++ + 3 files changed, 13 insertions(+), 3 deletions(-) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index 18136e58a754..865410e10e70 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -655,9 +655,7 @@ static void isc_set_pipeline(struct isc_device *isc, u32 pipeline) + regmap_bulk_write(regmap, ISC_GAM_RENTRY, gamma, GAMMA_ENTRIES); + + isc->config_csc(isc); +- +- regmap_write(regmap, ISC_CBC_BRIGHT, ctrls->brightness); +- regmap_write(regmap, ISC_CBC_CONTRAST, ctrls->contrast); ++ isc->config_cbc(isc); + } + + static int isc_update_profile(struct isc_device *isc) +diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h +index db6b4d469dff..65c3059afb8e 100644 +--- a/drivers/media/platform/atmel/atmel-isc.h ++++ b/drivers/media/platform/atmel/atmel-isc.h +@@ -202,6 +202,8 @@ struct isc_reg_offsets { + * + * @config_csc: pointer to a function that initializes product + * specific CSC module ++ * @config_cbc: pointer to a function that initializes product ++ * specific CBC module + * + * @offsets: struct holding the product specific register offsets + */ +@@ -274,6 +276,7 @@ struct isc_device { + + struct { + void (*config_csc)(struct isc_device *isc); ++ void (*config_cbc)(struct isc_device *isc); + }; + + struct isc_reg_offsets offsets; +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index 2ad6227aa2f5..770d62b483d0 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -73,6 +73,14 @@ static void isc_sama5d2_config_csc(struct isc_device *isc) + 0xFEE | (0x80 << 16)); + } + ++static void isc_sama5d2_config_cbc(struct isc_device *isc) ++{ ++ struct regmap *regmap = isc->regmap; ++ ++ regmap_write(regmap, ISC_CBC_BRIGHT, isc->ctrls.brightness); ++ regmap_write(regmap, ISC_CBC_CONTRAST, isc->ctrls.contrast); ++} ++ + /* Gamma table with gamma 1/2.2 */ + static const u32 isc_sama5d2_gamma_table[][GAMMA_ENTRIES] = { + /* 0 --> gamma 1/1.8 */ +@@ -239,6 +247,7 @@ static int atmel_isc_probe(struct platform_device *pdev) + isc->max_height = ISC_SAMA5D2_MAX_SUPPORT_HEIGHT; + + isc->config_csc = isc_sama5d2_config_csc; ++ isc->config_cbc = isc_sama5d2_config_cbc; + + isc->offsets.csc = ISC_SAMA5D2_CSC_OFFSET; + +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/166-media-atmel-atmel-isc-add-CBC-to-the-reg-offsets-str.patch b/target/linux/at91/patches-5.10/166-media-atmel-atmel-isc-add-CBC-to-the-reg-offsets-str.patch new file mode 100644 index 0000000000..46482f0397 --- /dev/null +++ b/target/linux/at91/patches-5.10/166-media-atmel-atmel-isc-add-CBC-to-the-reg-offsets-str.patch @@ -0,0 +1,93 @@ +From 52e4b779ae1af3e322d0c673375dcd51315739d4 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:08 +0200 +Subject: [PATCH 166/247] media: atmel: atmel-isc: add CBC to the reg offsets + struct + +The CBC submodule is a part of the atmel-isc pipeline, and stands for +Contrast Brightness Control. It is used to apply gains and offsets to the +luma (Y) and chroma (U, V) components of the YUV elements. +Add cbc to the reg offsets struct. This will allow different products +to have a different reg offset for this particular module. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 2 +- + drivers/media/platform/atmel/atmel-isc-regs.h | 3 +++ + drivers/media/platform/atmel/atmel-isc.h | 2 ++ + drivers/media/platform/atmel/atmel-sama5d2-isc.c | 7 +++++-- + 4 files changed, 11 insertions(+), 3 deletions(-) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index 865410e10e70..b7728914fda8 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -2325,7 +2325,7 @@ int isc_pipeline_init(struct isc_device *isc) + REG_FIELD(ISC_GAM_CTRL, 2, 2), + REG_FIELD(ISC_GAM_CTRL, 3, 3), + REG_FIELD(ISC_CSC_CTRL + isc->offsets.csc, 0, 0), +- REG_FIELD(ISC_CBC_CTRL, 0, 0), ++ REG_FIELD(ISC_CBC_CTRL + isc->offsets.cbc, 0, 0), + REG_FIELD(ISC_SUB422_CTRL, 0, 0), + REG_FIELD(ISC_SUB420_CTRL, 0, 0), + }; +diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h +index 5a65600c5f88..a5e2fe01ba9f 100644 +--- a/drivers/media/platform/atmel/atmel-isc-regs.h ++++ b/drivers/media/platform/atmel/atmel-isc-regs.h +@@ -177,6 +177,9 @@ + /* Color Space Conversion CRB OCR Register */ + #define ISC_CSC_CRB_OCR 0x000003b0 + ++/* Offset for CBC register specific to sama5d2 product */ ++#define ISC_SAMA5D2_CBC_OFFSET 0 ++ + /* Contrast And Brightness Control Register */ + #define ISC_CBC_CTRL 0x000003b4 + +diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h +index 65c3059afb8e..d8b4b1959b94 100644 +--- a/drivers/media/platform/atmel/atmel-isc.h ++++ b/drivers/media/platform/atmel/atmel-isc.h +@@ -146,9 +146,11 @@ struct isc_ctrls { + /* + * struct isc_reg_offsets - ISC device register offsets + * @csc: Offset for the CSC register ++ * @cbc: Offset for the CBC register + */ + struct isc_reg_offsets { + u32 csc; ++ u32 cbc; + }; + + /* +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index 770d62b483d0..bb9362093efe 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -77,8 +77,10 @@ static void isc_sama5d2_config_cbc(struct isc_device *isc) + { + struct regmap *regmap = isc->regmap; + +- regmap_write(regmap, ISC_CBC_BRIGHT, isc->ctrls.brightness); +- regmap_write(regmap, ISC_CBC_CONTRAST, isc->ctrls.contrast); ++ regmap_write(regmap, ISC_CBC_BRIGHT + isc->offsets.cbc, ++ isc->ctrls.brightness); ++ regmap_write(regmap, ISC_CBC_CONTRAST + isc->offsets.cbc, ++ isc->ctrls.contrast); + } + + /* Gamma table with gamma 1/2.2 */ +@@ -250,6 +252,7 @@ static int atmel_isc_probe(struct platform_device *pdev) + isc->config_cbc = isc_sama5d2_config_cbc; + + isc->offsets.csc = ISC_SAMA5D2_CSC_OFFSET; ++ isc->offsets.cbc = ISC_SAMA5D2_CBC_OFFSET; + + /* sama5d2-isc - 8 bits per beat */ + isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/167-media-atmel-atmel-isc-add-SUB422-and-SUB420-to-regis.patch b/target/linux/at91/patches-5.10/167-media-atmel-atmel-isc-add-SUB422-and-SUB420-to-regis.patch new file mode 100644 index 0000000000..d4d6f2ea45 --- /dev/null +++ b/target/linux/at91/patches-5.10/167-media-atmel-atmel-isc-add-SUB422-and-SUB420-to-regis.patch @@ -0,0 +1,91 @@ +From aebb741058a63c3493f4139d11d6f290d5691e9b Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:09 +0200 +Subject: [PATCH 167/247] media: atmel: atmel-isc: add SUB422 and SUB420 to + register offsets + +The SUB submodules are a part of the atmel-isc pipeline, and stand for +Subsampling. They are used to subsample the original YUV 4:4:4 pixel ratio +aspect to either 4:2:2 or 4:2:0. +Add sub420 and sub422 to the reg offsets struct. +This will allow different products to have a different reg offset for these +particular modules. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 4 ++-- + drivers/media/platform/atmel/atmel-isc-regs.h | 4 ++++ + drivers/media/platform/atmel/atmel-isc.h | 4 ++++ + drivers/media/platform/atmel/atmel-sama5d2-isc.c | 2 ++ + 4 files changed, 12 insertions(+), 2 deletions(-) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index b7728914fda8..b398cdfdc2c9 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -2326,8 +2326,8 @@ int isc_pipeline_init(struct isc_device *isc) + REG_FIELD(ISC_GAM_CTRL, 3, 3), + REG_FIELD(ISC_CSC_CTRL + isc->offsets.csc, 0, 0), + REG_FIELD(ISC_CBC_CTRL + isc->offsets.cbc, 0, 0), +- REG_FIELD(ISC_SUB422_CTRL, 0, 0), +- REG_FIELD(ISC_SUB420_CTRL, 0, 0), ++ REG_FIELD(ISC_SUB422_CTRL + isc->offsets.sub422, 0, 0), ++ REG_FIELD(ISC_SUB420_CTRL + isc->offsets.sub420, 0, 0), + }; + + for (i = 0; i < ISC_PIPE_LINE_NODE_NUM; i++) { +diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h +index a5e2fe01ba9f..04839def6ef6 100644 +--- a/drivers/media/platform/atmel/atmel-isc-regs.h ++++ b/drivers/media/platform/atmel/atmel-isc-regs.h +@@ -194,9 +194,13 @@ + #define ISC_CBC_CONTRAST 0x000003c0 + #define ISC_CBC_CONTRAST_MASK GENMASK(11, 0) + ++/* Offset for SUB422 register specific to sama5d2 product */ ++#define ISC_SAMA5D2_SUB422_OFFSET 0 + /* Subsampling 4:4:4 to 4:2:2 Control Register */ + #define ISC_SUB422_CTRL 0x000003c4 + ++/* Offset for SUB420 register specific to sama5d2 product */ ++#define ISC_SAMA5D2_SUB420_OFFSET 0 + /* Subsampling 4:2:2 to 4:2:0 Control Register */ + #define ISC_SUB420_CTRL 0x000003cc + +diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h +index d8b4b1959b94..9eb85540d89d 100644 +--- a/drivers/media/platform/atmel/atmel-isc.h ++++ b/drivers/media/platform/atmel/atmel-isc.h +@@ -147,10 +147,14 @@ struct isc_ctrls { + * struct isc_reg_offsets - ISC device register offsets + * @csc: Offset for the CSC register + * @cbc: Offset for the CBC register ++ * @sub422: Offset for the SUB422 register ++ * @sub420: Offset for the SUB420 register + */ + struct isc_reg_offsets { + u32 csc; + u32 cbc; ++ u32 sub422; ++ u32 sub420; + }; + + /* +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index bb9362093efe..57ea1ae50c44 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -253,6 +253,8 @@ static int atmel_isc_probe(struct platform_device *pdev) + + isc->offsets.csc = ISC_SAMA5D2_CSC_OFFSET; + isc->offsets.cbc = ISC_SAMA5D2_CBC_OFFSET; ++ isc->offsets.sub422 = ISC_SAMA5D2_SUB422_OFFSET; ++ isc->offsets.sub420 = ISC_SAMA5D2_SUB420_OFFSET; + + /* sama5d2-isc - 8 bits per beat */ + isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/168-media-atmel-atmel-isc-add-RLP-to-register-offsets.patch b/target/linux/at91/patches-5.10/168-media-atmel-atmel-isc-add-RLP-to-register-offsets.patch new file mode 100644 index 0000000000..a27ef80567 --- /dev/null +++ b/target/linux/at91/patches-5.10/168-media-atmel-atmel-isc-add-RLP-to-register-offsets.patch @@ -0,0 +1,85 @@ +From b432a8b0fc88de5b49236482053d8d372c68ee55 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:10 +0200 +Subject: [PATCH 168/247] media: atmel: atmel-isc: add RLP to register offsets + +The RLP submodule is a part of the atmel-isc pipeline, and stands for +Rounding,Limiting and Packaging. It used to extract specific data from the +ISC pipeline. For example if we want to output greyscale 8 bit, we would +use limiting to 8 bits, and packaging to Luma component only. +Add rlp to the reg offsets struct. +This will allow different products to have a different reg offset for this +particular module. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 4 ++-- + drivers/media/platform/atmel/atmel-isc-regs.h | 2 ++ + drivers/media/platform/atmel/atmel-isc.h | 2 ++ + drivers/media/platform/atmel/atmel-sama5d2-isc.c | 1 + + 4 files changed, 7 insertions(+), 2 deletions(-) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index b398cdfdc2c9..25c90b821067 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -726,8 +726,8 @@ static int isc_configure(struct isc_device *isc) + + regmap_update_bits(regmap, ISC_PFE_CFG0, mask, pfe_cfg0); + +- regmap_update_bits(regmap, ISC_RLP_CFG, ISC_RLP_CFG_MODE_MASK, +- rlp_mode); ++ regmap_update_bits(regmap, ISC_RLP_CFG + isc->offsets.rlp, ++ ISC_RLP_CFG_MODE_MASK, rlp_mode); + + regmap_write(regmap, ISC_DCFG, dcfg); + +diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h +index 04839def6ef6..2205484e04fc 100644 +--- a/drivers/media/platform/atmel/atmel-isc-regs.h ++++ b/drivers/media/platform/atmel/atmel-isc-regs.h +@@ -204,6 +204,8 @@ + /* Subsampling 4:2:2 to 4:2:0 Control Register */ + #define ISC_SUB420_CTRL 0x000003cc + ++/* Offset for RLP register specific to sama5d2 product */ ++#define ISC_SAMA5D2_RLP_OFFSET 0 + /* Rounding, Limiting and Packing Configuration Register */ + #define ISC_RLP_CFG 0x000003d0 + +diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h +index 9eb85540d89d..4a5293c66f49 100644 +--- a/drivers/media/platform/atmel/atmel-isc.h ++++ b/drivers/media/platform/atmel/atmel-isc.h +@@ -149,12 +149,14 @@ struct isc_ctrls { + * @cbc: Offset for the CBC register + * @sub422: Offset for the SUB422 register + * @sub420: Offset for the SUB420 register ++ * @rlp: Offset for the RLP register + */ + struct isc_reg_offsets { + u32 csc; + u32 cbc; + u32 sub422; + u32 sub420; ++ u32 rlp; + }; + + /* +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index 57ea1ae50c44..b01b5b9f229b 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -255,6 +255,7 @@ static int atmel_isc_probe(struct platform_device *pdev) + isc->offsets.cbc = ISC_SAMA5D2_CBC_OFFSET; + isc->offsets.sub422 = ISC_SAMA5D2_SUB422_OFFSET; + isc->offsets.sub420 = ISC_SAMA5D2_SUB420_OFFSET; ++ isc->offsets.rlp = ISC_SAMA5D2_RLP_OFFSET; + + /* sama5d2-isc - 8 bits per beat */ + isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/169-media-atmel-atmel-isc-add-HIS-to-register-offsets.patch b/target/linux/at91/patches-5.10/169-media-atmel-atmel-isc-add-HIS-to-register-offsets.patch new file mode 100644 index 0000000000..d818ccdaa6 --- /dev/null +++ b/target/linux/at91/patches-5.10/169-media-atmel-atmel-isc-add-HIS-to-register-offsets.patch @@ -0,0 +1,110 @@ +From 8c19aa14b8303a0e7c4bae42f3f00f9a2a65b0db Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:11 +0200 +Subject: [PATCH 169/247] media: atmel: atmel-isc: add HIS to register offsets + +The HIS submodule is a part of the atmel-isc pipeline, and stands for +Histogram. This module performs a color histogram that can be read and used +by the main processor. +Add his to the reg offsets struct. +This will allow different products to have a different reg offset for this +particular module. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 11 +++++++---- + drivers/media/platform/atmel/atmel-isc-regs.h | 2 ++ + drivers/media/platform/atmel/atmel-isc.h | 2 ++ + drivers/media/platform/atmel/atmel-sama5d2-isc.c | 1 + + 4 files changed, 12 insertions(+), 4 deletions(-) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index 25c90b821067..5c95aa45cf6c 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -686,12 +686,13 @@ static void isc_set_histogram(struct isc_device *isc, bool enable) + struct isc_ctrls *ctrls = &isc->ctrls; + + if (enable) { +- regmap_write(regmap, ISC_HIS_CFG, ++ regmap_write(regmap, ISC_HIS_CFG + isc->offsets.his, + ISC_HIS_CFG_MODE_GR | + (isc->config.sd_format->cfa_baycfg + << ISC_HIS_CFG_BAYSEL_SHIFT) | + ISC_HIS_CFG_RAR); +- regmap_write(regmap, ISC_HIS_CTRL, ISC_HIS_CTRL_EN); ++ regmap_write(regmap, ISC_HIS_CTRL + isc->offsets.his, ++ ISC_HIS_CTRL_EN); + regmap_write(regmap, ISC_INTEN, ISC_INT_HISDONE); + ctrls->hist_id = ISC_HIS_CFG_MODE_GR; + isc_update_profile(isc); +@@ -700,7 +701,8 @@ static void isc_set_histogram(struct isc_device *isc, bool enable) + ctrls->hist_stat = HIST_ENABLED; + } else { + regmap_write(regmap, ISC_INTDIS, ISC_INT_HISDONE); +- regmap_write(regmap, ISC_HIS_CTRL, ISC_HIS_CTRL_DIS); ++ regmap_write(regmap, ISC_HIS_CTRL + isc->offsets.his, ++ ISC_HIS_CTRL_DIS); + + ctrls->hist_stat = HIST_DISABLED; + } +@@ -1836,7 +1838,8 @@ static void isc_awb_work(struct work_struct *w) + ctrls->awb = ISC_WB_NONE; + } + } +- regmap_write(regmap, ISC_HIS_CFG, hist_id | baysel | ISC_HIS_CFG_RAR); ++ regmap_write(regmap, ISC_HIS_CFG + isc->offsets.his, ++ hist_id | baysel | ISC_HIS_CFG_RAR); + isc_update_profile(isc); + /* if awb has been disabled, we don't need to start another histogram */ + if (ctrls->awb) +diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h +index 2205484e04fc..0ab280ab59ec 100644 +--- a/drivers/media/platform/atmel/atmel-isc-regs.h ++++ b/drivers/media/platform/atmel/atmel-isc-regs.h +@@ -224,6 +224,8 @@ + #define ISC_RLP_CFG_MODE_YYCC_LIMITED 0xc + #define ISC_RLP_CFG_MODE_MASK GENMASK(3, 0) + ++/* Offset for HIS register specific to sama5d2 product */ ++#define ISC_SAMA5D2_HIS_OFFSET 0 + /* Histogram Control Register */ + #define ISC_HIS_CTRL 0x000003d4 + +diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h +index 4a5293c66f49..97ec4c58297e 100644 +--- a/drivers/media/platform/atmel/atmel-isc.h ++++ b/drivers/media/platform/atmel/atmel-isc.h +@@ -150,6 +150,7 @@ struct isc_ctrls { + * @sub422: Offset for the SUB422 register + * @sub420: Offset for the SUB420 register + * @rlp: Offset for the RLP register ++ * @his: Offset for the HIS related registers + */ + struct isc_reg_offsets { + u32 csc; +@@ -157,6 +158,7 @@ struct isc_reg_offsets { + u32 sub422; + u32 sub420; + u32 rlp; ++ u32 his; + }; + + /* +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index b01b5b9f229b..db93cb76c08b 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -256,6 +256,7 @@ static int atmel_isc_probe(struct platform_device *pdev) + isc->offsets.sub422 = ISC_SAMA5D2_SUB422_OFFSET; + isc->offsets.sub420 = ISC_SAMA5D2_SUB420_OFFSET; + isc->offsets.rlp = ISC_SAMA5D2_RLP_OFFSET; ++ isc->offsets.his = ISC_SAMA5D2_HIS_OFFSET; + + /* sama5d2-isc - 8 bits per beat */ + isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/170-media-atmel-atmel-isc-add-DMA-to-register-offsets.patch b/target/linux/at91/patches-5.10/170-media-atmel-atmel-isc-add-DMA-to-register-offsets.patch new file mode 100644 index 0000000000..92f6f3ead6 --- /dev/null +++ b/target/linux/at91/patches-5.10/170-media-atmel-atmel-isc-add-DMA-to-register-offsets.patch @@ -0,0 +1,121 @@ +From 7173e54070a9b530c8c16e0a507be71385133abd Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:12 +0200 +Subject: [PATCH 170/247] media: atmel: atmel-isc: add DMA to register offsets + +The DMA submodule is a part of the atmel-isc pipeline, and stands for +Direct Memory Access. It acts like a master on the AXI bus of the SoC, and +can directly write the RAM area with the pixel data from the ISC internal +sram. +Add dma to the reg offsets struct. +This will allow different products to have a different reg offset for this +particular module. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 19 ++++++++++++------- + drivers/media/platform/atmel/atmel-isc-regs.h | 3 +++ + drivers/media/platform/atmel/atmel-isc.h | 2 ++ + .../media/platform/atmel/atmel-sama5d2-isc.c | 1 + + 4 files changed, 18 insertions(+), 7 deletions(-) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index 5c95aa45cf6c..e010429fc44d 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -601,16 +601,20 @@ static void isc_start_dma(struct isc_device *isc) + ISC_PFE_CFG0_COLEN | ISC_PFE_CFG0_ROWEN); + + addr0 = vb2_dma_contig_plane_dma_addr(&isc->cur_frm->vb.vb2_buf, 0); +- regmap_write(regmap, ISC_DAD0, addr0); ++ regmap_write(regmap, ISC_DAD0 + isc->offsets.dma, addr0); + + switch (isc->config.fourcc) { + case V4L2_PIX_FMT_YUV420: +- regmap_write(regmap, ISC_DAD1, addr0 + (sizeimage * 2) / 3); +- regmap_write(regmap, ISC_DAD2, addr0 + (sizeimage * 5) / 6); ++ regmap_write(regmap, ISC_DAD1 + isc->offsets.dma, ++ addr0 + (sizeimage * 2) / 3); ++ regmap_write(regmap, ISC_DAD2 + isc->offsets.dma, ++ addr0 + (sizeimage * 5) / 6); + break; + case V4L2_PIX_FMT_YUV422P: +- regmap_write(regmap, ISC_DAD1, addr0 + sizeimage / 2); +- regmap_write(regmap, ISC_DAD2, addr0 + (sizeimage * 3) / 4); ++ regmap_write(regmap, ISC_DAD1 + isc->offsets.dma, ++ addr0 + sizeimage / 2); ++ regmap_write(regmap, ISC_DAD2 + isc->offsets.dma, ++ addr0 + (sizeimage * 3) / 4); + break; + default: + break; +@@ -618,7 +622,8 @@ static void isc_start_dma(struct isc_device *isc) + + dctrl_dview = isc->config.dctrl_dview; + +- regmap_write(regmap, ISC_DCTRL, dctrl_dview | ISC_DCTRL_IE_IS); ++ regmap_write(regmap, ISC_DCTRL + isc->offsets.dma, ++ dctrl_dview | ISC_DCTRL_IE_IS); + spin_lock(&isc->awb_lock); + regmap_write(regmap, ISC_CTRLEN, ISC_CTRL_CAPTURE); + spin_unlock(&isc->awb_lock); +@@ -731,7 +736,7 @@ static int isc_configure(struct isc_device *isc) + regmap_update_bits(regmap, ISC_RLP_CFG + isc->offsets.rlp, + ISC_RLP_CFG_MODE_MASK, rlp_mode); + +- regmap_write(regmap, ISC_DCFG, dcfg); ++ regmap_write(regmap, ISC_DCFG + isc->offsets.dma, dcfg); + + /* Set the pipeline */ + isc_set_pipeline(isc, pipeline); +diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h +index 0ab280ab59ec..4940998c82a2 100644 +--- a/drivers/media/platform/atmel/atmel-isc-regs.h ++++ b/drivers/media/platform/atmel/atmel-isc-regs.h +@@ -247,6 +247,9 @@ + + #define ISC_HIS_CFG_RAR BIT(8) + ++/* Offset for DMA register specific to sama5d2 product */ ++#define ISC_SAMA5D2_DMA_OFFSET 0 ++ + /* DMA Configuration Register */ + #define ISC_DCFG 0x000003e0 + #define ISC_DCFG_IMODE_PACKED8 0x0 +diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h +index 97ec4c58297e..bea545327d3d 100644 +--- a/drivers/media/platform/atmel/atmel-isc.h ++++ b/drivers/media/platform/atmel/atmel-isc.h +@@ -151,6 +151,7 @@ struct isc_ctrls { + * @sub420: Offset for the SUB420 register + * @rlp: Offset for the RLP register + * @his: Offset for the HIS related registers ++ * @dma: Offset for the DMA related registers + */ + struct isc_reg_offsets { + u32 csc; +@@ -159,6 +160,7 @@ struct isc_reg_offsets { + u32 sub420; + u32 rlp; + u32 his; ++ u32 dma; + }; + + /* +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index db93cb76c08b..bfd56ac5c921 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -257,6 +257,7 @@ static int atmel_isc_probe(struct platform_device *pdev) + isc->offsets.sub420 = ISC_SAMA5D2_SUB420_OFFSET; + isc->offsets.rlp = ISC_SAMA5D2_RLP_OFFSET; + isc->offsets.his = ISC_SAMA5D2_HIS_OFFSET; ++ isc->offsets.dma = ISC_SAMA5D2_DMA_OFFSET; + + /* sama5d2-isc - 8 bits per beat */ + isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/171-media-atmel-atmel-isc-add-support-for-version-regist.patch b/target/linux/at91/patches-5.10/171-media-atmel-atmel-isc-add-support-for-version-regist.patch new file mode 100644 index 0000000000..6eca9dbf91 --- /dev/null +++ b/target/linux/at91/patches-5.10/171-media-atmel-atmel-isc-add-support-for-version-regist.patch @@ -0,0 +1,86 @@ +From 0939b0a92acca11a5a3b0de5dd70434e17e40ed3 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:13 +0200 +Subject: [PATCH 171/247] media: atmel: atmel-isc: add support for version + register + +Add support for version register and print it at probe time. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-regs.h | 5 +++++ + drivers/media/platform/atmel/atmel-isc.h | 2 ++ + drivers/media/platform/atmel/atmel-sama5d2-isc.c | 5 +++++ + 3 files changed, 12 insertions(+) + +diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h +index 4940998c82a2..344668dcfcf4 100644 +--- a/drivers/media/platform/atmel/atmel-isc-regs.h ++++ b/drivers/media/platform/atmel/atmel-isc-regs.h +@@ -295,6 +295,11 @@ + /* DMA Address 2 Register */ + #define ISC_DAD2 0x000003fc + ++/* Offset for version register specific to sama5d2 product */ ++#define ISC_SAMA5D2_VERSION_OFFSET 0 ++/* Version Register */ ++#define ISC_VERSION 0x0000040c ++ + /* Histogram Entry */ + #define ISC_HIS_ENTRY 0x00000410 + +diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h +index bea545327d3d..13ee19d99c2e 100644 +--- a/drivers/media/platform/atmel/atmel-isc.h ++++ b/drivers/media/platform/atmel/atmel-isc.h +@@ -152,6 +152,7 @@ struct isc_ctrls { + * @rlp: Offset for the RLP register + * @his: Offset for the HIS related registers + * @dma: Offset for the DMA related registers ++ * @version: Offset for the version register + */ + struct isc_reg_offsets { + u32 csc; +@@ -161,6 +162,7 @@ struct isc_reg_offsets { + u32 rlp; + u32 his; + u32 dma; ++ u32 version; + }; + + /* +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index bfd56ac5c921..aebf38dde2d2 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -210,6 +210,7 @@ static int atmel_isc_probe(struct platform_device *pdev) + struct isc_subdev_entity *subdev_entity; + int irq; + int ret; ++ u32 ver; + + isc = devm_kzalloc(dev, sizeof(*isc), GFP_KERNEL); + if (!isc) +@@ -258,6 +259,7 @@ static int atmel_isc_probe(struct platform_device *pdev) + isc->offsets.rlp = ISC_SAMA5D2_RLP_OFFSET; + isc->offsets.his = ISC_SAMA5D2_HIS_OFFSET; + isc->offsets.dma = ISC_SAMA5D2_DMA_OFFSET; ++ isc->offsets.version = ISC_SAMA5D2_VERSION_OFFSET; + + /* sama5d2-isc - 8 bits per beat */ + isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; +@@ -346,6 +348,9 @@ static int atmel_isc_probe(struct platform_device *pdev) + pm_runtime_enable(dev); + pm_request_idle(dev); + ++ regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver); ++ dev_info(dev, "Microchip ISC version %x\n", ver); ++ + return 0; + + cleanup_subdev: +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/172-media-atmel-atmel-isc-add-his_entry-to-register-offs.patch b/target/linux/at91/patches-5.10/172-media-atmel-atmel-isc-add-his_entry-to-register-offs.patch new file mode 100644 index 0000000000..dd5118ed2a --- /dev/null +++ b/target/linux/at91/patches-5.10/172-media-atmel-atmel-isc-add-his_entry-to-register-offs.patch @@ -0,0 +1,82 @@ +From bce46a8a620a796ca3cfe5bff61baf6744074986 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:14 +0200 +Subject: [PATCH 172/247] media: atmel: atmel-isc: add his_entry to register + offsets + +Add his_entry to the reg offsets struct. +This will allow different products to have a different reg offset for this +particular module. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 3 ++- + drivers/media/platform/atmel/atmel-isc-regs.h | 2 ++ + drivers/media/platform/atmel/atmel-isc.h | 2 ++ + drivers/media/platform/atmel/atmel-sama5d2-isc.c | 1 + + 4 files changed, 7 insertions(+), 1 deletion(-) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index e010429fc44d..cfe60b2882ac 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -1684,7 +1684,8 @@ static void isc_hist_count(struct isc_device *isc, u32 *min, u32 *max) + *min = 0; + *max = HIST_ENTRIES; + +- regmap_bulk_read(regmap, ISC_HIS_ENTRY, hist_entry, HIST_ENTRIES); ++ regmap_bulk_read(regmap, ISC_HIS_ENTRY + isc->offsets.his_entry, ++ hist_entry, HIST_ENTRIES); + + *hist_count = 0; + /* +diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h +index 344668dcfcf4..a15c13e1a833 100644 +--- a/drivers/media/platform/atmel/atmel-isc-regs.h ++++ b/drivers/media/platform/atmel/atmel-isc-regs.h +@@ -300,6 +300,8 @@ + /* Version Register */ + #define ISC_VERSION 0x0000040c + ++/* Offset for version register specific to sama5d2 product */ ++#define ISC_SAMA5D2_HIS_ENTRY_OFFSET 0 + /* Histogram Entry */ + #define ISC_HIS_ENTRY 0x00000410 + +diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h +index 13ee19d99c2e..513b2b920b1f 100644 +--- a/drivers/media/platform/atmel/atmel-isc.h ++++ b/drivers/media/platform/atmel/atmel-isc.h +@@ -153,6 +153,7 @@ struct isc_ctrls { + * @his: Offset for the HIS related registers + * @dma: Offset for the DMA related registers + * @version: Offset for the version register ++ * @his_entry: Offset for the HIS entries registers + */ + struct isc_reg_offsets { + u32 csc; +@@ -163,6 +164,7 @@ struct isc_reg_offsets { + u32 his; + u32 dma; + u32 version; ++ u32 his_entry; + }; + + /* +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index aebf38dde2d2..ed575eb3726d 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -260,6 +260,7 @@ static int atmel_isc_probe(struct platform_device *pdev) + isc->offsets.his = ISC_SAMA5D2_HIS_OFFSET; + isc->offsets.dma = ISC_SAMA5D2_DMA_OFFSET; + isc->offsets.version = ISC_SAMA5D2_VERSION_OFFSET; ++ isc->offsets.his_entry = ISC_SAMA5D2_HIS_ENTRY_OFFSET; + + /* sama5d2-isc - 8 bits per beat */ + isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/173-media-atmel-atmel-isc-add-register-description-for-a.patch b/target/linux/at91/patches-5.10/173-media-atmel-atmel-isc-add-register-description-for-a.patch new file mode 100644 index 0000000000..3828835196 --- /dev/null +++ b/target/linux/at91/patches-5.10/173-media-atmel-atmel-isc-add-register-description-for-a.patch @@ -0,0 +1,104 @@ +From 87b581b1197df5f77bd65819d0428f2404c6b764 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:15 +0200 +Subject: [PATCH 173/247] media: atmel: atmel-isc: add register description for + additional modules + +Add register description for additional pipeline modules: the +Defective Pixel Correction (DPC) and the Vertical and Horizontal Scaler(VHXS) + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-regs.h | 67 +++++++++++++++++++ + 1 file changed, 67 insertions(+) + +diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h +index a15c13e1a833..457eed74cda9 100644 +--- a/drivers/media/platform/atmel/atmel-isc-regs.h ++++ b/drivers/media/platform/atmel/atmel-isc-regs.h +@@ -90,6 +90,46 @@ + #define ISC_INT_DDONE BIT(8) + #define ISC_INT_HISDONE BIT(12) + ++/* ISC DPC Control Register */ ++#define ISC_DPC_CTRL 0x40 ++ ++#define ISC_DPC_CTRL_DPCEN BIT(0) ++#define ISC_DPC_CTRL_GDCEN BIT(1) ++#define ISC_DPC_CTRL_BLCEN BIT(2) ++ ++/* ISC DPC Config Register */ ++#define ISC_DPC_CFG 0x44 ++ ++#define ISC_DPC_CFG_BAYSEL_SHIFT 0 ++ ++#define ISC_DPC_CFG_EITPOL BIT(4) ++ ++#define ISC_DPC_CFG_TA_ENABLE BIT(14) ++#define ISC_DPC_CFG_TC_ENABLE BIT(13) ++#define ISC_DPC_CFG_TM_ENABLE BIT(12) ++ ++#define ISC_DPC_CFG_RE_MODE BIT(17) ++ ++#define ISC_DPC_CFG_GDCCLP_SHIFT 20 ++#define ISC_DPC_CFG_GDCCLP_MASK GENMASK(22, 20) ++ ++#define ISC_DPC_CFG_BLOFF_SHIFT 24 ++#define ISC_DPC_CFG_BLOFF_MASK GENMASK(31, 24) ++ ++#define ISC_DPC_CFG_BAYCFG_SHIFT 0 ++#define ISC_DPC_CFG_BAYCFG_MASK GENMASK(1, 0) ++/* ISC DPC Threshold Median Register */ ++#define ISC_DPC_THRESHM 0x48 ++ ++/* ISC DPC Threshold Closest Register */ ++#define ISC_DPC_THRESHC 0x4C ++ ++/* ISC DPC Threshold Average Register */ ++#define ISC_DPC_THRESHA 0x50 ++ ++/* ISC DPC STatus Register */ ++#define ISC_DPC_SR 0x54 ++ + /* ISC White Balance Control Register */ + #define ISC_WB_CTRL 0x00000058 + +@@ -153,6 +193,33 @@ + /* ISC_Gamma Correction Green Entry Register */ + #define ISC_GAM_RENTRY 0x00000298 + ++/* ISC VHXS Control Register */ ++#define ISC_VHXS_CTRL 0x398 ++ ++/* ISC VHXS Source Size Register */ ++#define ISC_VHXS_SS 0x39C ++ ++/* ISC VHXS Destination Size Register */ ++#define ISC_VHXS_DS 0x3A0 ++ ++/* ISC Vertical Factor Register */ ++#define ISC_VXS_FACT 0x3a4 ++ ++/* ISC Horizontal Factor Register */ ++#define ISC_HXS_FACT 0x3a8 ++ ++/* ISC Vertical Config Register */ ++#define ISC_VXS_CFG 0x3ac ++ ++/* ISC Horizontal Config Register */ ++#define ISC_HXS_CFG 0x3b0 ++ ++/* ISC Vertical Tap Register */ ++#define ISC_VXS_TAP 0x3b4 ++ ++/* ISC Horizontal Tap Register */ ++#define ISC_HXS_TAP 0x434 ++ + /* Offset for CSC register specific to sama5d2 product */ + #define ISC_SAMA5D2_CSC_OFFSET 0 + +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/174-media-atmel-atmel-isc-extend-pipeline-with-extra-mod.patch b/target/linux/at91/patches-5.10/174-media-atmel-atmel-isc-extend-pipeline-with-extra-mod.patch new file mode 100644 index 0000000000..ee93b34a77 --- /dev/null +++ b/target/linux/at91/patches-5.10/174-media-atmel-atmel-isc-extend-pipeline-with-extra-mod.patch @@ -0,0 +1,111 @@ +From 58a6cc3c7eecd16208cd16b92b4eaf8385e69696 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:16 +0200 +Subject: [PATCH 174/247] media: atmel: atmel-isc: extend pipeline with extra + modules + +Newer ISC pipelines have the additional modules of +Defective Pixel Correction -> DPC itself, +Defective Pixel Correction -> Green Disparity Correction (DPC_GDC) +Defective Pixel Correction -> Black Level Correction (DPC_BLC) +Vertical and Horizontal Scaler -> VHXS + +Some products have this full pipeline (sama7g5), other products do not (sama5d2) + +Add the modules to the isc base, and also extend the register range to include +the modules. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 11 ++++++-- + drivers/media/platform/atmel/atmel-isc.h | 28 +++++++++++-------- + 2 files changed, 25 insertions(+), 14 deletions(-) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index cfe60b2882ac..a6b62e009c38 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -2324,8 +2324,14 @@ int isc_pipeline_init(struct isc_device *isc) + struct regmap_field *regs; + unsigned int i; + +- /* WB-->CFA-->CC-->GAM-->CSC-->CBC-->SUB422-->SUB420 */ ++ /* ++ * DPCEN-->GDCEN-->BLCEN-->WB-->CFA-->CC--> ++ * GAM-->VHXS-->CSC-->CBC-->SUB422-->SUB420 ++ */ + const struct reg_field regfields[ISC_PIPE_LINE_NODE_NUM] = { ++ REG_FIELD(ISC_DPC_CTRL, 0, 0), ++ REG_FIELD(ISC_DPC_CTRL, 1, 1), ++ REG_FIELD(ISC_DPC_CTRL, 2, 2), + REG_FIELD(ISC_WB_CTRL, 0, 0), + REG_FIELD(ISC_CFA_CTRL, 0, 0), + REG_FIELD(ISC_CC_CTRL, 0, 0), +@@ -2333,6 +2339,7 @@ int isc_pipeline_init(struct isc_device *isc) + REG_FIELD(ISC_GAM_CTRL, 1, 1), + REG_FIELD(ISC_GAM_CTRL, 2, 2), + REG_FIELD(ISC_GAM_CTRL, 3, 3), ++ REG_FIELD(ISC_VHXS_CTRL, 0, 0), + REG_FIELD(ISC_CSC_CTRL + isc->offsets.csc, 0, 0), + REG_FIELD(ISC_CBC_CTRL + isc->offsets.cbc, 0, 0), + REG_FIELD(ISC_SUB422_CTRL + isc->offsets.sub422, 0, 0), +@@ -2351,7 +2358,7 @@ int isc_pipeline_init(struct isc_device *isc) + } + + /* regmap configuration */ +-#define ATMEL_ISC_REG_MAX 0xbfc ++#define ATMEL_ISC_REG_MAX 0xd5c + const struct regmap_config isc_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, +diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h +index 513b2b920b1f..86edeea2d5cd 100644 +--- a/drivers/media/platform/atmel/atmel-isc.h ++++ b/drivers/media/platform/atmel/atmel-isc.h +@@ -67,17 +67,21 @@ struct isc_format { + }; + + /* Pipeline bitmap */ +-#define WB_ENABLE BIT(0) +-#define CFA_ENABLE BIT(1) +-#define CC_ENABLE BIT(2) +-#define GAM_ENABLE BIT(3) +-#define GAM_BENABLE BIT(4) +-#define GAM_GENABLE BIT(5) +-#define GAM_RENABLE BIT(6) +-#define CSC_ENABLE BIT(7) +-#define CBC_ENABLE BIT(8) +-#define SUB422_ENABLE BIT(9) +-#define SUB420_ENABLE BIT(10) ++#define DPC_DPCENABLE BIT(0) ++#define DPC_GDCENABLE BIT(1) ++#define DPC_BLCENABLE BIT(2) ++#define WB_ENABLE BIT(3) ++#define CFA_ENABLE BIT(4) ++#define CC_ENABLE BIT(5) ++#define GAM_ENABLE BIT(6) ++#define GAM_BENABLE BIT(7) ++#define GAM_GENABLE BIT(8) ++#define GAM_RENABLE BIT(9) ++#define VHXS_ENABLE BIT(10) ++#define CSC_ENABLE BIT(11) ++#define CBC_ENABLE BIT(12) ++#define SUB422_ENABLE BIT(13) ++#define SUB420_ENABLE BIT(14) + + #define GAM_ENABLES (GAM_RENABLE | GAM_GENABLE | GAM_BENABLE | GAM_ENABLE) + +@@ -141,7 +145,7 @@ struct isc_ctrls { + u32 hist_minmax[HIST_BAYER][2]; + }; + +-#define ISC_PIPE_LINE_NODE_NUM 11 ++#define ISC_PIPE_LINE_NODE_NUM 15 + + /* + * struct isc_reg_offsets - ISC device register offsets +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/175-media-atmel-atmel-isc-add-CC-initialization-function.patch b/target/linux/at91/patches-5.10/175-media-atmel-atmel-isc-add-CC-initialization-function.patch new file mode 100644 index 0000000000..91c68c82ff --- /dev/null +++ b/target/linux/at91/patches-5.10/175-media-atmel-atmel-isc-add-CC-initialization-function.patch @@ -0,0 +1,92 @@ +From 0db91d2a803221c313c9f2cd1d71050d7c5a7b5b Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:17 +0200 +Subject: [PATCH 175/247] media: atmel: atmel-isc: add CC initialization + function + +The CC submodule is a part of the atmel-isc pipeline, and stands for +Color Correction. It is used to apply gains and offsets to the +chroma (U, V) components of the YUV elements. +Implement the CC submodule initialization, as a product +specific function, which currently configures the neutral point in color +correction. + +[hverkuil: made isc_sama5d2_config_cc static] + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 1 + + drivers/media/platform/atmel/atmel-isc.h | 3 +++ + drivers/media/platform/atmel/atmel-sama5d2-isc.c | 14 ++++++++++++++ + 3 files changed, 18 insertions(+) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index a6b62e009c38..ffce8de2cf4d 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -661,6 +661,7 @@ static void isc_set_pipeline(struct isc_device *isc, u32 pipeline) + + isc->config_csc(isc); + isc->config_cbc(isc); ++ isc->config_cc(isc); + } + + static int isc_update_profile(struct isc_device *isc) +diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h +index 86edeea2d5cd..293746664cef 100644 +--- a/drivers/media/platform/atmel/atmel-isc.h ++++ b/drivers/media/platform/atmel/atmel-isc.h +@@ -224,6 +224,8 @@ struct isc_reg_offsets { + * specific CSC module + * @config_cbc: pointer to a function that initializes product + * specific CBC module ++ * @config_cc: pointer to a function that initializes product ++ * specific CC module + * + * @offsets: struct holding the product specific register offsets + */ +@@ -297,6 +299,7 @@ struct isc_device { + struct { + void (*config_csc)(struct isc_device *isc); + void (*config_cbc)(struct isc_device *isc); ++ void (*config_cc)(struct isc_device *isc); + }; + + struct isc_reg_offsets offsets; +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index ed575eb3726d..903920b74965 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -83,6 +83,19 @@ static void isc_sama5d2_config_cbc(struct isc_device *isc) + isc->ctrls.contrast); + } + ++static void isc_sama5d2_config_cc(struct isc_device *isc) ++{ ++ struct regmap *regmap = isc->regmap; ++ ++ /* Configure each register at the neutral fixed point 1.0 or 0.0 */ ++ regmap_write(regmap, ISC_CC_RR_RG, (1 << 8)); ++ regmap_write(regmap, ISC_CC_RB_OR, 0); ++ regmap_write(regmap, ISC_CC_GR_GG, (1 << 8) << 16); ++ regmap_write(regmap, ISC_CC_GB_OG, 0); ++ regmap_write(regmap, ISC_CC_BR_BG, 0); ++ regmap_write(regmap, ISC_CC_BB_OB, (1 << 8)); ++} ++ + /* Gamma table with gamma 1/2.2 */ + static const u32 isc_sama5d2_gamma_table[][GAMMA_ENTRIES] = { + /* 0 --> gamma 1/1.8 */ +@@ -251,6 +264,7 @@ static int atmel_isc_probe(struct platform_device *pdev) + + isc->config_csc = isc_sama5d2_config_csc; + isc->config_cbc = isc_sama5d2_config_cbc; ++ isc->config_cc = isc_sama5d2_config_cc; + + isc->offsets.csc = ISC_SAMA5D2_CSC_OFFSET; + isc->offsets.cbc = ISC_SAMA5D2_CBC_OFFSET; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/176-media-atmel-atmel-isc-create-product-specific-v4l2-c.patch b/target/linux/at91/patches-5.10/176-media-atmel-atmel-isc-create-product-specific-v4l2-c.patch new file mode 100644 index 0000000000..4ba3e3cace --- /dev/null +++ b/target/linux/at91/patches-5.10/176-media-atmel-atmel-isc-create-product-specific-v4l2-c.patch @@ -0,0 +1,95 @@ +From 0a75c502eac4f2ef71b6c3e0b3a01db1b3c37ba9 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:18 +0200 +Subject: [PATCH 176/247] media: atmel: atmel-isc: create product specific v4l2 + controls config + +Create product specific callback for initializing v4l2 controls. +Call this from v4l2 controls init function. + +[hverkuil: made isc_sama5d2_config_ctrls static] + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 5 +++-- + drivers/media/platform/atmel/atmel-isc.h | 5 +++++ + drivers/media/platform/atmel/atmel-sama5d2-isc.c | 12 ++++++++++++ + 3 files changed, 20 insertions(+), 2 deletions(-) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index ffce8de2cf4d..8ed8b8a4840c 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -2051,11 +2051,12 @@ static int isc_ctrl_init(struct isc_device *isc) + if (ret < 0) + return ret; + ++ /* Initialize product specific controls. For example, contrast */ ++ isc->config_ctrls(isc, ops); ++ + ctrls->brightness = 0; +- ctrls->contrast = 256; + + v4l2_ctrl_new_std(hdl, ops, V4L2_CID_BRIGHTNESS, -1024, 1023, 1, 0); +- v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -2048, 2047, 1, 256); + v4l2_ctrl_new_std(hdl, ops, V4L2_CID_GAMMA, 0, isc->gamma_max, 1, + isc->gamma_max); + isc->awb_ctrl = v4l2_ctrl_new_std(hdl, &isc_awb_ops, +diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h +index 293746664cef..428419d5a07d 100644 +--- a/drivers/media/platform/atmel/atmel-isc.h ++++ b/drivers/media/platform/atmel/atmel-isc.h +@@ -226,6 +226,8 @@ struct isc_reg_offsets { + * specific CBC module + * @config_cc: pointer to a function that initializes product + * specific CC module ++ * @config_ctrls: pointer to a functoin that initializes product ++ * specific v4l2 controls. + * + * @offsets: struct holding the product specific register offsets + */ +@@ -300,6 +302,9 @@ struct isc_device { + void (*config_csc)(struct isc_device *isc); + void (*config_cbc)(struct isc_device *isc); + void (*config_cc)(struct isc_device *isc); ++ ++ void (*config_ctrls)(struct isc_device *isc, ++ const struct v4l2_ctrl_ops *ops); + }; + + struct isc_reg_offsets offsets; +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index 903920b74965..7512012cd9f3 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -96,6 +96,17 @@ static void isc_sama5d2_config_cc(struct isc_device *isc) + regmap_write(regmap, ISC_CC_BB_OB, (1 << 8)); + } + ++static void isc_sama5d2_config_ctrls(struct isc_device *isc, ++ const struct v4l2_ctrl_ops *ops) ++{ ++ struct isc_ctrls *ctrls = &isc->ctrls; ++ struct v4l2_ctrl_handler *hdl = &ctrls->handler; ++ ++ ctrls->contrast = 256; ++ ++ v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -2048, 2047, 1, 256); ++} ++ + /* Gamma table with gamma 1/2.2 */ + static const u32 isc_sama5d2_gamma_table[][GAMMA_ENTRIES] = { + /* 0 --> gamma 1/1.8 */ +@@ -265,6 +276,7 @@ static int atmel_isc_probe(struct platform_device *pdev) + isc->config_csc = isc_sama5d2_config_csc; + isc->config_cbc = isc_sama5d2_config_cbc; + isc->config_cc = isc_sama5d2_config_cc; ++ isc->config_ctrls = isc_sama5d2_config_ctrls; + + isc->offsets.csc = ISC_SAMA5D2_CSC_OFFSET; + isc->offsets.cbc = ISC_SAMA5D2_CBC_OFFSET; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/177-media-atmel-atmel-isc-create-callback-for-DPC-submod.patch b/target/linux/at91/patches-5.10/177-media-atmel-atmel-isc-create-callback-for-DPC-submod.patch new file mode 100644 index 0000000000..466ddb97b9 --- /dev/null +++ b/target/linux/at91/patches-5.10/177-media-atmel-atmel-isc-create-callback-for-DPC-submod.patch @@ -0,0 +1,84 @@ +From d53eb90044c19ba22b51978fcb007d9b5200b83a Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:19 +0200 +Subject: [PATCH 177/247] media: atmel: atmel-isc: create callback for DPC + submodule product specific + +The DPC submodule is a part of the atmel-isc pipeline, and stands for +Defective Pixel Correction. Its purpose is to detect defective pixels and +correct them if possible with the help of adjacent pixels. +Create a product specific callback for initializing the DPC submodule +of the pipeline. +For sama5d2 product, this module does not exist, thus this function is a noop. + +[hverkuil: made isc_sama5d2_config_dpc static] + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 1 + + drivers/media/platform/atmel/atmel-isc.h | 3 +++ + drivers/media/platform/atmel/atmel-sama5d2-isc.c | 6 ++++++ + 3 files changed, 10 insertions(+) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index 8ed8b8a4840c..777a5dc19d6e 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -659,6 +659,7 @@ static void isc_set_pipeline(struct isc_device *isc, u32 pipeline) + regmap_bulk_write(regmap, ISC_GAM_GENTRY, gamma, GAMMA_ENTRIES); + regmap_bulk_write(regmap, ISC_GAM_RENTRY, gamma, GAMMA_ENTRIES); + ++ isc->config_dpc(isc); + isc->config_csc(isc); + isc->config_cbc(isc); + isc->config_cc(isc); +diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h +index 428419d5a07d..2f093dc968cd 100644 +--- a/drivers/media/platform/atmel/atmel-isc.h ++++ b/drivers/media/platform/atmel/atmel-isc.h +@@ -220,6 +220,8 @@ struct isc_reg_offsets { + * @max_width: maximum frame width, dependent on the internal RAM + * @max_height: maximum frame height, dependent on the internal RAM + * ++ * @config_dpc: pointer to a function that initializes product ++ * specific DPC module + * @config_csc: pointer to a function that initializes product + * specific CSC module + * @config_cbc: pointer to a function that initializes product +@@ -299,6 +301,7 @@ struct isc_device { + u32 max_height; + + struct { ++ void (*config_dpc)(struct isc_device *isc); + void (*config_csc)(struct isc_device *isc); + void (*config_cbc)(struct isc_device *isc); + void (*config_cc)(struct isc_device *isc); +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index 7512012cd9f3..84d1bf3305f2 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -107,6 +107,11 @@ static void isc_sama5d2_config_ctrls(struct isc_device *isc, + v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -2048, 2047, 1, 256); + } + ++static void isc_sama5d2_config_dpc(struct isc_device *isc) ++{ ++ /* This module is not present on sama5d2 pipeline */ ++} ++ + /* Gamma table with gamma 1/2.2 */ + static const u32 isc_sama5d2_gamma_table[][GAMMA_ENTRIES] = { + /* 0 --> gamma 1/1.8 */ +@@ -273,6 +278,7 @@ static int atmel_isc_probe(struct platform_device *pdev) + isc->max_width = ISC_SAMA5D2_MAX_SUPPORT_WIDTH; + isc->max_height = ISC_SAMA5D2_MAX_SUPPORT_HEIGHT; + ++ isc->config_dpc = isc_sama5d2_config_dpc; + isc->config_csc = isc_sama5d2_config_csc; + isc->config_cbc = isc_sama5d2_config_cbc; + isc->config_cc = isc_sama5d2_config_cc; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/178-media-atmel-atmel-isc-create-callback-for-GAM-submod.patch b/target/linux/at91/patches-5.10/178-media-atmel-atmel-isc-create-callback-for-GAM-submod.patch new file mode 100644 index 0000000000..6d53179f4a --- /dev/null +++ b/target/linux/at91/patches-5.10/178-media-atmel-atmel-isc-create-callback-for-GAM-submod.patch @@ -0,0 +1,84 @@ +From 96936a6753a13dea5a8f66de949e6594dd82ce22 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:20 +0200 +Subject: [PATCH 178/247] media: atmel: atmel-isc: create callback for GAM + submodule product specific + +The GAM submodule is a part of the atmel-isc pipeline, and stands for +Gamma Correction. It is used to apply the gamma curve to the incoming pixels. +Create a product specific callback for initializing the GAM submodule +of the pipeline. +For sama5d2 product, there is no special configuration at this moment, +thus this function is a noop. + +[hverkuil: made isc_sama5d2_config_gam static] + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 1 + + drivers/media/platform/atmel/atmel-isc.h | 3 +++ + drivers/media/platform/atmel/atmel-sama5d2-isc.c | 6 ++++++ + 3 files changed, 10 insertions(+) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index 777a5dc19d6e..aef0d6570d39 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -663,6 +663,7 @@ static void isc_set_pipeline(struct isc_device *isc, u32 pipeline) + isc->config_csc(isc); + isc->config_cbc(isc); + isc->config_cc(isc); ++ isc->config_gam(isc); + } + + static int isc_update_profile(struct isc_device *isc) +diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h +index 2f093dc968cd..151997c11f56 100644 +--- a/drivers/media/platform/atmel/atmel-isc.h ++++ b/drivers/media/platform/atmel/atmel-isc.h +@@ -228,6 +228,8 @@ struct isc_reg_offsets { + * specific CBC module + * @config_cc: pointer to a function that initializes product + * specific CC module ++ * @config_gam: pointer to a function that initializes product ++ * specific GAMMA module + * @config_ctrls: pointer to a functoin that initializes product + * specific v4l2 controls. + * +@@ -305,6 +307,7 @@ struct isc_device { + void (*config_csc)(struct isc_device *isc); + void (*config_cbc)(struct isc_device *isc); + void (*config_cc)(struct isc_device *isc); ++ void (*config_gam)(struct isc_device *isc); + + void (*config_ctrls)(struct isc_device *isc, + const struct v4l2_ctrl_ops *ops); +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index 84d1bf3305f2..b99849ecb8a1 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -112,6 +112,11 @@ static void isc_sama5d2_config_dpc(struct isc_device *isc) + /* This module is not present on sama5d2 pipeline */ + } + ++static void isc_sama5d2_config_gam(struct isc_device *isc) ++{ ++ /* No specific gamma configuration */ ++} ++ + /* Gamma table with gamma 1/2.2 */ + static const u32 isc_sama5d2_gamma_table[][GAMMA_ENTRIES] = { + /* 0 --> gamma 1/1.8 */ +@@ -282,6 +287,7 @@ static int atmel_isc_probe(struct platform_device *pdev) + isc->config_csc = isc_sama5d2_config_csc; + isc->config_cbc = isc_sama5d2_config_cbc; + isc->config_cc = isc_sama5d2_config_cc; ++ isc->config_gam = isc_sama5d2_config_gam; + isc->config_ctrls = isc_sama5d2_config_ctrls; + + isc->offsets.csc = ISC_SAMA5D2_CSC_OFFSET; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/179-media-atmel-atmel-isc-create-callback-for-RLP-submod.patch b/target/linux/at91/patches-5.10/179-media-atmel-atmel-isc-create-callback-for-RLP-submod.patch new file mode 100644 index 0000000000..74a08b2209 --- /dev/null +++ b/target/linux/at91/patches-5.10/179-media-atmel-atmel-isc-create-callback-for-RLP-submod.patch @@ -0,0 +1,104 @@ +From ece1d7059731e31875e6eb464da4fb4a16465305 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:21 +0200 +Subject: [PATCH 179/247] media: atmel: atmel-isc: create callback for RLP + submodule product specific + +The RLP submodule is a part of the atmel-isc pipeline, and stands for +Rounding,Limiting and Packaging. It used to extract specific data from the +ISC pipeline. For example if we want to output greyscale 8 bit, we would +use limiting to 8 bits, and packaging to Luma component only. + +Create a product specific callback for initializing the RLP submodule +of the pipeline + +[hverkuil: made isc_sama5d2_config_rlp static] + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 6 ++---- + drivers/media/platform/atmel/atmel-isc.h | 3 +++ + drivers/media/platform/atmel/atmel-sama5d2-isc.c | 10 ++++++++++ + 3 files changed, 15 insertions(+), 4 deletions(-) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index aef0d6570d39..67c16ca17672 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -719,11 +719,10 @@ static void isc_set_histogram(struct isc_device *isc, bool enable) + static int isc_configure(struct isc_device *isc) + { + struct regmap *regmap = isc->regmap; +- u32 pfe_cfg0, rlp_mode, dcfg, mask, pipeline; ++ u32 pfe_cfg0, dcfg, mask, pipeline; + struct isc_subdev_entity *subdev = isc->current_subdev; + + pfe_cfg0 = isc->config.sd_format->pfe_cfg0_bps; +- rlp_mode = isc->config.rlp_cfg_mode; + pipeline = isc->config.bits_pipeline; + + dcfg = isc->config.dcfg_imode | isc->dcfg; +@@ -736,8 +735,7 @@ static int isc_configure(struct isc_device *isc) + + regmap_update_bits(regmap, ISC_PFE_CFG0, mask, pfe_cfg0); + +- regmap_update_bits(regmap, ISC_RLP_CFG + isc->offsets.rlp, +- ISC_RLP_CFG_MODE_MASK, rlp_mode); ++ isc->config_rlp(isc); + + regmap_write(regmap, ISC_DCFG + isc->offsets.dma, dcfg); + +diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h +index 151997c11f56..24006327c5e4 100644 +--- a/drivers/media/platform/atmel/atmel-isc.h ++++ b/drivers/media/platform/atmel/atmel-isc.h +@@ -230,6 +230,8 @@ struct isc_reg_offsets { + * specific CC module + * @config_gam: pointer to a function that initializes product + * specific GAMMA module ++ * @config_rlp: pointer to a function that initializes product ++ * specific RLP module + * @config_ctrls: pointer to a functoin that initializes product + * specific v4l2 controls. + * +@@ -308,6 +310,7 @@ struct isc_device { + void (*config_cbc)(struct isc_device *isc); + void (*config_cc)(struct isc_device *isc); + void (*config_gam)(struct isc_device *isc); ++ void (*config_rlp)(struct isc_device *isc); + + void (*config_ctrls)(struct isc_device *isc, + const struct v4l2_ctrl_ops *ops); +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index b99849ecb8a1..86704a1a24b9 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -117,6 +117,15 @@ static void isc_sama5d2_config_gam(struct isc_device *isc) + /* No specific gamma configuration */ + } + ++static void isc_sama5d2_config_rlp(struct isc_device *isc) ++{ ++ struct regmap *regmap = isc->regmap; ++ u32 rlp_mode = isc->config.rlp_cfg_mode; ++ ++ regmap_update_bits(regmap, ISC_RLP_CFG + isc->offsets.rlp, ++ ISC_RLP_CFG_MODE_MASK, rlp_mode); ++} ++ + /* Gamma table with gamma 1/2.2 */ + static const u32 isc_sama5d2_gamma_table[][GAMMA_ENTRIES] = { + /* 0 --> gamma 1/1.8 */ +@@ -288,6 +297,7 @@ static int atmel_isc_probe(struct platform_device *pdev) + isc->config_cbc = isc_sama5d2_config_cbc; + isc->config_cc = isc_sama5d2_config_cc; + isc->config_gam = isc_sama5d2_config_gam; ++ isc->config_rlp = isc_sama5d2_config_rlp; + isc->config_ctrls = isc_sama5d2_config_ctrls; + + isc->offsets.csc = ISC_SAMA5D2_CSC_OFFSET; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/180-media-atmel-atmel-isc-move-the-formats-list-into-pro.patch b/target/linux/at91/patches-5.10/180-media-atmel-atmel-isc-move-the-formats-list-into-pro.patch new file mode 100644 index 0000000000..cce3fabc4c --- /dev/null +++ b/target/linux/at91/patches-5.10/180-media-atmel-atmel-isc-move-the-formats-list-into-pro.patch @@ -0,0 +1,449 @@ +From dda51aa2e4524914d25022864466fa9d8713a5e9 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:22 +0200 +Subject: [PATCH 180/247] media: atmel: atmel-isc: move the formats list into + product specific code + +The list of input and output formats has to be product specific. +Move this list into the product specific code. +Have pointers to these arrays inside the device struct. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 167 ++---------------- + drivers/media/platform/atmel/atmel-isc.h | 12 +- + .../media/platform/atmel/atmel-sama5d2-isc.c | 136 ++++++++++++++ + 3 files changed, 165 insertions(+), 150 deletions(-) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index 67c16ca17672..90a62d43fdb1 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -45,137 +45,6 @@ module_param(sensor_preferred, uint, 0644); + MODULE_PARM_DESC(sensor_preferred, + "Sensor is preferred to output the specified format (1-on 0-off), default 1"); + +-/* This is a list of the formats that the ISC can *output* */ +-const struct isc_format controller_formats[] = { +- { +- .fourcc = V4L2_PIX_FMT_ARGB444, +- }, +- { +- .fourcc = V4L2_PIX_FMT_ARGB555, +- }, +- { +- .fourcc = V4L2_PIX_FMT_RGB565, +- }, +- { +- .fourcc = V4L2_PIX_FMT_ABGR32, +- }, +- { +- .fourcc = V4L2_PIX_FMT_XBGR32, +- }, +- { +- .fourcc = V4L2_PIX_FMT_YUV420, +- }, +- { +- .fourcc = V4L2_PIX_FMT_YUYV, +- }, +- { +- .fourcc = V4L2_PIX_FMT_YUV422P, +- }, +- { +- .fourcc = V4L2_PIX_FMT_GREY, +- }, +- { +- .fourcc = V4L2_PIX_FMT_Y10, +- }, +-}; +- +-/* This is a list of formats that the ISC can receive as *input* */ +-struct isc_format formats_list[] = { +- { +- .fourcc = V4L2_PIX_FMT_SBGGR8, +- .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, +- .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, +- .cfa_baycfg = ISC_BAY_CFG_BGBG, +- }, +- { +- .fourcc = V4L2_PIX_FMT_SGBRG8, +- .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8, +- .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, +- .cfa_baycfg = ISC_BAY_CFG_GBGB, +- }, +- { +- .fourcc = V4L2_PIX_FMT_SGRBG8, +- .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8, +- .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, +- .cfa_baycfg = ISC_BAY_CFG_GRGR, +- }, +- { +- .fourcc = V4L2_PIX_FMT_SRGGB8, +- .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8, +- .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, +- .cfa_baycfg = ISC_BAY_CFG_RGRG, +- }, +- { +- .fourcc = V4L2_PIX_FMT_SBGGR10, +- .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, +- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, +- .cfa_baycfg = ISC_BAY_CFG_RGRG, +- }, +- { +- .fourcc = V4L2_PIX_FMT_SGBRG10, +- .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10, +- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, +- .cfa_baycfg = ISC_BAY_CFG_GBGB, +- }, +- { +- .fourcc = V4L2_PIX_FMT_SGRBG10, +- .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, +- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, +- .cfa_baycfg = ISC_BAY_CFG_GRGR, +- }, +- { +- .fourcc = V4L2_PIX_FMT_SRGGB10, +- .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10, +- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, +- .cfa_baycfg = ISC_BAY_CFG_RGRG, +- }, +- { +- .fourcc = V4L2_PIX_FMT_SBGGR12, +- .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12, +- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, +- .cfa_baycfg = ISC_BAY_CFG_BGBG, +- }, +- { +- .fourcc = V4L2_PIX_FMT_SGBRG12, +- .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12, +- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, +- .cfa_baycfg = ISC_BAY_CFG_GBGB, +- }, +- { +- .fourcc = V4L2_PIX_FMT_SGRBG12, +- .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12, +- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, +- .cfa_baycfg = ISC_BAY_CFG_GRGR, +- }, +- { +- .fourcc = V4L2_PIX_FMT_SRGGB12, +- .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12, +- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, +- .cfa_baycfg = ISC_BAY_CFG_RGRG, +- }, +- { +- .fourcc = V4L2_PIX_FMT_GREY, +- .mbus_code = MEDIA_BUS_FMT_Y8_1X8, +- .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, +- }, +- { +- .fourcc = V4L2_PIX_FMT_YUYV, +- .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, +- .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, +- }, +- { +- .fourcc = V4L2_PIX_FMT_RGB565, +- .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE, +- .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, +- }, +- { +- .fourcc = V4L2_PIX_FMT_Y10, +- .mbus_code = MEDIA_BUS_FMT_Y10_1X10, +- .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, +- }, +- +-}; +- + #define ISC_IS_FORMAT_RAW(mbus_code) \ + (((mbus_code) & 0xf000) == 0x3000) + +@@ -919,24 +788,25 @@ static int isc_querycap(struct file *file, void *priv, + static int isc_enum_fmt_vid_cap(struct file *file, void *priv, + struct v4l2_fmtdesc *f) + { ++ struct isc_device *isc = video_drvdata(file); + u32 index = f->index; + u32 i, supported_index; + +- if (index < ARRAY_SIZE(controller_formats)) { +- f->pixelformat = controller_formats[index].fourcc; ++ if (index < isc->controller_formats_size) { ++ f->pixelformat = isc->controller_formats[index].fourcc; + return 0; + } + +- index -= ARRAY_SIZE(controller_formats); ++ index -= isc->controller_formats_size; + + supported_index = 0; + +- for (i = 0; i < ARRAY_SIZE(formats_list); i++) { +- if (!ISC_IS_FORMAT_RAW(formats_list[i].mbus_code) || +- !formats_list[i].sd_support) ++ for (i = 0; i < isc->formats_list_size; i++) { ++ if (!ISC_IS_FORMAT_RAW(isc->formats_list[i].mbus_code) || ++ !isc->formats_list[i].sd_support) + continue; + if (supported_index == index) { +- f->pixelformat = formats_list[i].fourcc; ++ f->pixelformat = isc->formats_list[i].fourcc; + return 0; + } + supported_index++; +@@ -1477,8 +1347,8 @@ static int isc_enum_framesizes(struct file *file, void *fh, + if (isc->user_formats[i]->fourcc == fsize->pixel_format) + ret = 0; + +- for (i = 0; i < ARRAY_SIZE(controller_formats); i++) +- if (controller_formats[i].fourcc == fsize->pixel_format) ++ for (i = 0; i < isc->controller_formats_size; i++) ++ if (isc->controller_formats[i].fourcc == fsize->pixel_format) + ret = 0; + + if (ret) +@@ -1514,8 +1384,8 @@ static int isc_enum_frameintervals(struct file *file, void *fh, + if (isc->user_formats[i]->fourcc == fival->pixel_format) + ret = 0; + +- for (i = 0; i < ARRAY_SIZE(controller_formats); i++) +- if (controller_formats[i].fourcc == fival->pixel_format) ++ for (i = 0; i < isc->controller_formats_size; i++) ++ if (isc->controller_formats[i].fourcc == fival->pixel_format) + ret = 0; + + if (ret) +@@ -2126,12 +1996,13 @@ static void isc_async_unbind(struct v4l2_async_notifier *notifier, + v4l2_ctrl_handler_free(&isc->ctrls.handler); + } + +-static struct isc_format *find_format_by_code(unsigned int code, int *index) ++static struct isc_format *find_format_by_code(struct isc_device *isc, ++ unsigned int code, int *index) + { +- struct isc_format *fmt = &formats_list[0]; ++ struct isc_format *fmt = &isc->formats_list[0]; + unsigned int i; + +- for (i = 0; i < ARRAY_SIZE(formats_list); i++) { ++ for (i = 0; i < isc->formats_list_size; i++) { + if (fmt->mbus_code == code) { + *index = i; + return fmt; +@@ -2148,7 +2019,7 @@ static int isc_formats_init(struct isc_device *isc) + struct isc_format *fmt; + struct v4l2_subdev *subdev = isc->current_subdev->sd; + unsigned int num_fmts, i, j; +- u32 list_size = ARRAY_SIZE(formats_list); ++ u32 list_size = isc->formats_list_size; + struct v4l2_subdev_mbus_code_enum mbus_code = { + .which = V4L2_SUBDEV_FORMAT_ACTIVE, + }; +@@ -2158,7 +2029,7 @@ static int isc_formats_init(struct isc_device *isc) + NULL, &mbus_code)) { + mbus_code.index++; + +- fmt = find_format_by_code(mbus_code.code, &i); ++ fmt = find_format_by_code(isc, mbus_code.code, &i); + if (!fmt) { + v4l2_warn(&isc->v4l2_dev, "Mbus code %x not supported\n", + mbus_code.code); +@@ -2179,7 +2050,7 @@ static int isc_formats_init(struct isc_device *isc) + if (!isc->user_formats) + return -ENOMEM; + +- fmt = &formats_list[0]; ++ fmt = &isc->formats_list[0]; + for (i = 0, j = 0; i < list_size; i++) { + if (fmt->sd_support) + isc->user_formats[j++] = fmt; +diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h +index 24006327c5e4..b34737c09a5b 100644 +--- a/drivers/media/platform/atmel/atmel-isc.h ++++ b/drivers/media/platform/atmel/atmel-isc.h +@@ -236,6 +236,12 @@ struct isc_reg_offsets { + * specific v4l2 controls. + * + * @offsets: struct holding the product specific register offsets ++ * @controller_formats: pointer to the array of possible formats that the ++ * controller can output ++ * @formats_list: pointer to the array of possible formats that can ++ * be used as an input to the controller ++ * @controller_formats_size: size of controller_formats array ++ * @formats_list_size: size of formats_list array + */ + struct isc_device { + struct regmap *regmap; +@@ -317,10 +323,12 @@ struct isc_device { + }; + + struct isc_reg_offsets offsets; ++ const struct isc_format *controller_formats; ++ struct isc_format *formats_list; ++ u32 controller_formats_size; ++ u32 formats_list_size; + }; + +-extern struct isc_format formats_list[]; +-extern const struct isc_format controller_formats[]; + extern const struct regmap_config isc_regmap_config; + extern const struct v4l2_async_notifier_operations isc_async_ops; + +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index 86704a1a24b9..b8c1b57ed820 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -54,6 +54,137 @@ + + #define ISC_CLK_MAX_DIV 255 + ++/* This is a list of the formats that the ISC can *output* */ ++static const struct isc_format sama5d2_controller_formats[] = { ++ { ++ .fourcc = V4L2_PIX_FMT_ARGB444, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_ARGB555, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_RGB565, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_ABGR32, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_XBGR32, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_YUV420, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_YUYV, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_YUV422P, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_GREY, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_Y10, ++ }, ++}; ++ ++/* This is a list of formats that the ISC can receive as *input* */ ++static struct isc_format sama5d2_formats_list[] = { ++ { ++ .fourcc = V4L2_PIX_FMT_SBGGR8, ++ .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, ++ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, ++ .cfa_baycfg = ISC_BAY_CFG_BGBG, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_SGBRG8, ++ .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8, ++ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, ++ .cfa_baycfg = ISC_BAY_CFG_GBGB, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_SGRBG8, ++ .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8, ++ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, ++ .cfa_baycfg = ISC_BAY_CFG_GRGR, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_SRGGB8, ++ .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8, ++ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, ++ .cfa_baycfg = ISC_BAY_CFG_RGRG, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_SBGGR10, ++ .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, ++ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, ++ .cfa_baycfg = ISC_BAY_CFG_RGRG, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_SGBRG10, ++ .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10, ++ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, ++ .cfa_baycfg = ISC_BAY_CFG_GBGB, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_SGRBG10, ++ .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, ++ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, ++ .cfa_baycfg = ISC_BAY_CFG_GRGR, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_SRGGB10, ++ .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10, ++ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, ++ .cfa_baycfg = ISC_BAY_CFG_RGRG, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_SBGGR12, ++ .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12, ++ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, ++ .cfa_baycfg = ISC_BAY_CFG_BGBG, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_SGBRG12, ++ .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12, ++ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, ++ .cfa_baycfg = ISC_BAY_CFG_GBGB, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_SGRBG12, ++ .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12, ++ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, ++ .cfa_baycfg = ISC_BAY_CFG_GRGR, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_SRGGB12, ++ .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12, ++ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, ++ .cfa_baycfg = ISC_BAY_CFG_RGRG, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_GREY, ++ .mbus_code = MEDIA_BUS_FMT_Y8_1X8, ++ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_YUYV, ++ .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, ++ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_RGB565, ++ .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE, ++ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_Y10, ++ .mbus_code = MEDIA_BUS_FMT_Y10_1X10, ++ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, ++ }, ++ ++}; ++ + static void isc_sama5d2_config_csc(struct isc_device *isc) + { + struct regmap *regmap = isc->regmap; +@@ -310,6 +441,11 @@ static int atmel_isc_probe(struct platform_device *pdev) + isc->offsets.version = ISC_SAMA5D2_VERSION_OFFSET; + isc->offsets.his_entry = ISC_SAMA5D2_HIS_ENTRY_OFFSET; + ++ isc->controller_formats = sama5d2_controller_formats; ++ isc->controller_formats_size = ARRAY_SIZE(sama5d2_controller_formats); ++ isc->formats_list = sama5d2_formats_list; ++ isc->formats_list_size = ARRAY_SIZE(sama5d2_formats_list); ++ + /* sama5d2-isc - 8 bits per beat */ + isc->dcfg = ISC_DCFG_YMBSIZE_BEATS8 | ISC_DCFG_CMBSIZE_BEATS8; + +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/181-media-atmel-atmel-isc-create-an-adapt-pipeline-callb.patch b/target/linux/at91/patches-5.10/181-media-atmel-atmel-isc-create-an-adapt-pipeline-callb.patch new file mode 100644 index 0000000000..66c70e4ca3 --- /dev/null +++ b/target/linux/at91/patches-5.10/181-media-atmel-atmel-isc-create-an-adapt-pipeline-callb.patch @@ -0,0 +1,98 @@ +From 8601f1fc0a9a22788bfa6369fbbf83b3828a5b42 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:23 +0200 +Subject: [PATCH 181/247] media: atmel: atmel-isc: create an adapt pipeline + callback for product specific + +Once the pipeline is set in the base code, create a callback that will adapt +the ISC pipeline to each product. +Create the adapt_pipeline callback that will be used in this fashion. + +[hverkuil: made isc_sama5d2_adapt_pipeline static] + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 4 ++++ + drivers/media/platform/atmel/atmel-isc.h | 5 +++++ + drivers/media/platform/atmel/atmel-sama5d2-isc.c | 11 +++++++++++ + 3 files changed, 20 insertions(+) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index 90a62d43fdb1..7862d6bf850d 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -1059,6 +1059,10 @@ static int isc_try_configure_pipeline(struct isc_device *isc) + default: + isc->try_config.bits_pipeline = 0x0; + } ++ ++ /* Tune the pipeline to product specific */ ++ isc->adapt_pipeline(isc); ++ + return 0; + } + +diff --git a/drivers/media/platform/atmel/atmel-isc.h b/drivers/media/platform/atmel/atmel-isc.h +index b34737c09a5b..f59b2426ae74 100644 +--- a/drivers/media/platform/atmel/atmel-isc.h ++++ b/drivers/media/platform/atmel/atmel-isc.h +@@ -235,6 +235,9 @@ struct isc_reg_offsets { + * @config_ctrls: pointer to a functoin that initializes product + * specific v4l2 controls. + * ++ * @adapt_pipeline: pointer to a function that adapts the pipeline bits ++ * to the product specific pipeline ++ * + * @offsets: struct holding the product specific register offsets + * @controller_formats: pointer to the array of possible formats that the + * controller can output +@@ -320,6 +323,8 @@ struct isc_device { + + void (*config_ctrls)(struct isc_device *isc, + const struct v4l2_ctrl_ops *ops); ++ ++ void (*adapt_pipeline)(struct isc_device *isc); + }; + + struct isc_reg_offsets offsets; +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index b8c1b57ed820..26c971a380ca 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -54,6 +54,10 @@ + + #define ISC_CLK_MAX_DIV 255 + ++#define ISC_SAMA5D2_PIPELINE \ ++ (WB_ENABLE | CFA_ENABLE | CC_ENABLE | GAM_ENABLES | CSC_ENABLE | \ ++ CBC_ENABLE | SUB422_ENABLE | SUB420_ENABLE) ++ + /* This is a list of the formats that the ISC can *output* */ + static const struct isc_format sama5d2_controller_formats[] = { + { +@@ -257,6 +261,11 @@ static void isc_sama5d2_config_rlp(struct isc_device *isc) + ISC_RLP_CFG_MODE_MASK, rlp_mode); + } + ++static void isc_sama5d2_adapt_pipeline(struct isc_device *isc) ++{ ++ isc->try_config.bits_pipeline &= ISC_SAMA5D2_PIPELINE; ++} ++ + /* Gamma table with gamma 1/2.2 */ + static const u32 isc_sama5d2_gamma_table[][GAMMA_ENTRIES] = { + /* 0 --> gamma 1/1.8 */ +@@ -431,6 +440,8 @@ static int atmel_isc_probe(struct platform_device *pdev) + isc->config_rlp = isc_sama5d2_config_rlp; + isc->config_ctrls = isc_sama5d2_config_ctrls; + ++ isc->adapt_pipeline = isc_sama5d2_adapt_pipeline; ++ + isc->offsets.csc = ISC_SAMA5D2_CSC_OFFSET; + isc->offsets.cbc = ISC_SAMA5D2_CBC_OFFSET; + isc->offsets.sub422 = ISC_SAMA5D2_SUB422_OFFSET; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/182-media-atmel-atmel-isc-regs-add-additional-fields-for.patch b/target/linux/at91/patches-5.10/182-media-atmel-atmel-isc-regs-add-additional-fields-for.patch new file mode 100644 index 0000000000..e2a79bb7e3 --- /dev/null +++ b/target/linux/at91/patches-5.10/182-media-atmel-atmel-isc-regs-add-additional-fields-for.patch @@ -0,0 +1,60 @@ +From bf032d1a0105939b90072914d88181fbe6187f43 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:24 +0200 +Subject: [PATCH 182/247] media: atmel: atmel-isc-regs: add additional fields + for sama7g5 type pipeline + +Add additional fields for registers present in sama7g5 type pipeline. +Extend register masks for additional bits in sama7g5 type pipeline registers. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-regs.h | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h +index 457eed74cda9..5f99bf7717c1 100644 +--- a/drivers/media/platform/atmel/atmel-isc-regs.h ++++ b/drivers/media/platform/atmel/atmel-isc-regs.h +@@ -289,8 +289,18 @@ + #define ISC_RLP_CFG_MODE_ARGB32 0xa + #define ISC_RLP_CFG_MODE_YYCC 0xb + #define ISC_RLP_CFG_MODE_YYCC_LIMITED 0xc ++#define ISC_RLP_CFG_MODE_YCYC 0xd + #define ISC_RLP_CFG_MODE_MASK GENMASK(3, 0) + ++#define ISC_RLP_CFG_LSH BIT(5) ++ ++#define ISC_RLP_CFG_YMODE_YUYV (3 << 6) ++#define ISC_RLP_CFG_YMODE_YVYU (2 << 6) ++#define ISC_RLP_CFG_YMODE_VYUY (0 << 6) ++#define ISC_RLP_CFG_YMODE_UYVY (1 << 6) ++ ++#define ISC_RLP_CFG_YMODE_MASK GENMASK(7, 6) ++ + /* Offset for HIS register specific to sama5d2 product */ + #define ISC_SAMA5D2_HIS_OFFSET 0 + /* Histogram Control Register */ +@@ -332,13 +342,15 @@ + #define ISC_DCFG_YMBSIZE_BEATS4 (0x1 << 4) + #define ISC_DCFG_YMBSIZE_BEATS8 (0x2 << 4) + #define ISC_DCFG_YMBSIZE_BEATS16 (0x3 << 4) +-#define ISC_DCFG_YMBSIZE_MASK GENMASK(5, 4) ++#define ISC_DCFG_YMBSIZE_BEATS32 (0x4 << 4) ++#define ISC_DCFG_YMBSIZE_MASK GENMASK(6, 4) + + #define ISC_DCFG_CMBSIZE_SINGLE (0x0 << 8) + #define ISC_DCFG_CMBSIZE_BEATS4 (0x1 << 8) + #define ISC_DCFG_CMBSIZE_BEATS8 (0x2 << 8) + #define ISC_DCFG_CMBSIZE_BEATS16 (0x3 << 8) +-#define ISC_DCFG_CMBSIZE_MASK GENMASK(9, 8) ++#define ISC_DCFG_CMBSIZE_BEATS32 (0x4 << 8) ++#define ISC_DCFG_CMBSIZE_MASK GENMASK(10, 8) + + /* DMA Control Register */ + #define ISC_DCTRL 0x000003e4 +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/183-media-atmel-atmel-isc-base-add-support-for-more-form.patch b/target/linux/at91/patches-5.10/183-media-atmel-atmel-isc-base-add-support-for-more-form.patch new file mode 100644 index 0000000000..4b530134a1 --- /dev/null +++ b/target/linux/at91/patches-5.10/183-media-atmel-atmel-isc-base-add-support-for-more-form.patch @@ -0,0 +1,150 @@ +From fa9e6cd8f3ba4a277c06e4c1fb01cd69b3a57234 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:25 +0200 +Subject: [PATCH 183/247] media: atmel: atmel-isc-base: add support for more + formats and additional pipeline modules + +Add support for additional formats supported by newer pipelines, and for +additional pipeline modules. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-isc-base.c | 48 +++++++++++++++---- + 1 file changed, 38 insertions(+), 10 deletions(-) + +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index 7862d6bf850d..dcb321ad10b8 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -855,6 +855,8 @@ static int isc_try_validate_formats(struct isc_device *isc) + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YUV422P: + case V4L2_PIX_FMT_YUYV: ++ case V4L2_PIX_FMT_UYVY: ++ case V4L2_PIX_FMT_VYUY: + ret = 0; + yuv = true; + break; +@@ -869,6 +871,7 @@ static int isc_try_validate_formats(struct isc_device *isc) + break; + case V4L2_PIX_FMT_GREY: + case V4L2_PIX_FMT_Y10: ++ case V4L2_PIX_FMT_Y16: + ret = 0; + grey = true; + break; +@@ -899,6 +902,8 @@ static int isc_try_validate_formats(struct isc_device *isc) + */ + static int isc_try_configure_rlp_dma(struct isc_device *isc, bool direct_dump) + { ++ isc->try_config.rlp_cfg_mode = 0; ++ + switch (isc->try_config.fourcc) { + case V4L2_PIX_FMT_SBGGR8: + case V4L2_PIX_FMT_SGBRG8: +@@ -965,7 +970,19 @@ static int isc_try_configure_rlp_dma(struct isc_device *isc, bool direct_dump) + isc->try_config.bpp = 16; + break; + case V4L2_PIX_FMT_YUYV: +- isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YYCC; ++ isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YCYC | ISC_RLP_CFG_YMODE_YUYV; ++ isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32; ++ isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; ++ isc->try_config.bpp = 16; ++ break; ++ case V4L2_PIX_FMT_UYVY: ++ isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YCYC | ISC_RLP_CFG_YMODE_UYVY; ++ isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32; ++ isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; ++ isc->try_config.bpp = 16; ++ break; ++ case V4L2_PIX_FMT_VYUY: ++ isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_YCYC | ISC_RLP_CFG_YMODE_VYUY; + isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED32; + isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; + isc->try_config.bpp = 16; +@@ -976,8 +993,11 @@ static int isc_try_configure_rlp_dma(struct isc_device *isc, bool direct_dump) + isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; + isc->try_config.bpp = 8; + break; ++ case V4L2_PIX_FMT_Y16: ++ isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DATY10 | ISC_RLP_CFG_LSH; ++ fallthrough; + case V4L2_PIX_FMT_Y10: +- isc->try_config.rlp_cfg_mode = ISC_RLP_CFG_MODE_DATY10; ++ isc->try_config.rlp_cfg_mode |= ISC_RLP_CFG_MODE_DATY10; + isc->try_config.dcfg_imode = ISC_DCFG_IMODE_PACKED16; + isc->try_config.dctrl_dview = ISC_DCTRL_DVIEW_PACKED; + isc->try_config.bpp = 16; +@@ -1011,7 +1031,8 @@ static int isc_try_configure_pipeline(struct isc_device *isc) + /* if sensor format is RAW, we convert inside ISC */ + if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { + isc->try_config.bits_pipeline = CFA_ENABLE | +- WB_ENABLE | GAM_ENABLES; ++ WB_ENABLE | GAM_ENABLES | DPC_BLCENABLE | ++ CC_ENABLE; + } else { + isc->try_config.bits_pipeline = 0x0; + } +@@ -1020,8 +1041,9 @@ static int isc_try_configure_pipeline(struct isc_device *isc) + /* if sensor format is RAW, we convert inside ISC */ + if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { + isc->try_config.bits_pipeline = CFA_ENABLE | +- CSC_ENABLE | WB_ENABLE | GAM_ENABLES | +- SUB420_ENABLE | SUB422_ENABLE | CBC_ENABLE; ++ CSC_ENABLE | GAM_ENABLES | WB_ENABLE | ++ SUB420_ENABLE | SUB422_ENABLE | CBC_ENABLE | ++ DPC_BLCENABLE; + } else { + isc->try_config.bits_pipeline = 0x0; + } +@@ -1031,33 +1053,39 @@ static int isc_try_configure_pipeline(struct isc_device *isc) + if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { + isc->try_config.bits_pipeline = CFA_ENABLE | + CSC_ENABLE | WB_ENABLE | GAM_ENABLES | +- SUB422_ENABLE | CBC_ENABLE; ++ SUB422_ENABLE | CBC_ENABLE | DPC_BLCENABLE; + } else { + isc->try_config.bits_pipeline = 0x0; + } + break; + case V4L2_PIX_FMT_YUYV: ++ case V4L2_PIX_FMT_UYVY: ++ case V4L2_PIX_FMT_VYUY: + /* if sensor format is RAW, we convert inside ISC */ + if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { + isc->try_config.bits_pipeline = CFA_ENABLE | + CSC_ENABLE | WB_ENABLE | GAM_ENABLES | +- SUB422_ENABLE | CBC_ENABLE; ++ SUB422_ENABLE | CBC_ENABLE | DPC_BLCENABLE; + } else { + isc->try_config.bits_pipeline = 0x0; + } + break; + case V4L2_PIX_FMT_GREY: +- if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { ++ case V4L2_PIX_FMT_Y16: + /* if sensor format is RAW, we convert inside ISC */ ++ if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) { + isc->try_config.bits_pipeline = CFA_ENABLE | + CSC_ENABLE | WB_ENABLE | GAM_ENABLES | +- CBC_ENABLE; ++ CBC_ENABLE | DPC_BLCENABLE; + } else { + isc->try_config.bits_pipeline = 0x0; + } + break; + default: +- isc->try_config.bits_pipeline = 0x0; ++ if (ISC_IS_FORMAT_RAW(isc->try_config.sd_format->mbus_code)) ++ isc->try_config.bits_pipeline = WB_ENABLE | DPC_BLCENABLE; ++ else ++ isc->try_config.bits_pipeline = 0x0; + } + + /* Tune the pipeline to product specific */ +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/184-media-atmel-atmel-isc-sama5d2-remove-duplicate-defin.patch b/target/linux/at91/patches-5.10/184-media-atmel-atmel-isc-sama5d2-remove-duplicate-defin.patch new file mode 100644 index 0000000000..ea11e15654 --- /dev/null +++ b/target/linux/at91/patches-5.10/184-media-atmel-atmel-isc-sama5d2-remove-duplicate-defin.patch @@ -0,0 +1,31 @@ +From b36d11efc134f9f1e2804270d08b9dbefdee4a0d Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:26 +0200 +Subject: [PATCH 184/247] media: atmel: atmel-isc-sama5d2: remove duplicate + define + +Remove a duplicate definition of clock max divider + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/atmel-sama5d2-isc.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index 26c971a380ca..d6fd22b127fd 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -52,8 +52,6 @@ + #define ISC_SAMA5D2_MAX_SUPPORT_WIDTH 2592 + #define ISC_SAMA5D2_MAX_SUPPORT_HEIGHT 1944 + +-#define ISC_CLK_MAX_DIV 255 +- + #define ISC_SAMA5D2_PIPELINE \ + (WB_ENABLE | CFA_ENABLE | CC_ENABLE | GAM_ENABLES | CSC_ENABLE | \ + CBC_ENABLE | SUB422_ENABLE | SUB420_ENABLE) +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/185-media-atmel-atmel-isc-add-microchip-xisc-driver.patch b/target/linux/at91/patches-5.10/185-media-atmel-atmel-isc-add-microchip-xisc-driver.patch new file mode 100644 index 0000000000..f09443237c --- /dev/null +++ b/target/linux/at91/patches-5.10/185-media-atmel-atmel-isc-add-microchip-xisc-driver.patch @@ -0,0 +1,826 @@ +From 74fd7ea680cb1a3a43b51a7279aea45efdf9ec42 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Tue, 13 Apr 2021 12:57:29 +0200 +Subject: [PATCH 185/247] media: atmel: atmel-isc: add microchip-xisc driver + +Add driver for the extended variant of the isc, the microchip XISC +present on sama7g5 product. + +[hverkuil: drop MODULE_SUPPORTED_DEVICE, no longer exists] +[hverkuil: made isc_sama7g5_config_csc et al static] +[hverkuil: made sama7g5_controller_formats et al static] + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/Makefile | 1 + + drivers/media/platform/atmel/Kconfig | 11 + + drivers/media/platform/atmel/Makefile | 2 + + drivers/media/platform/atmel/atmel-isc-base.c | 2 +- + drivers/media/platform/atmel/atmel-isc-regs.h | 26 + + .../media/platform/atmel/atmel-sama7g5-isc.c | 630 ++++++++++++++++++ + 6 files changed, 671 insertions(+), 1 deletion(-) + create mode 100644 drivers/media/platform/atmel/atmel-sama7g5-isc.c + +diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile +index 62b6cdc8c730..fd15c76402c9 100644 +--- a/drivers/media/platform/Makefile ++++ b/drivers/media/platform/Makefile +@@ -64,6 +64,7 @@ obj-$(CONFIG_VIDEO_RCAR_VIN) += rcar-vin/ + + obj-$(CONFIG_VIDEO_ATMEL_ISC) += atmel/ + obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel/ ++obj-$(CONFIG_VIDEO_ATMEL_XISC) += atmel/ + + obj-$(CONFIG_VIDEO_STM32_DCMI) += stm32/ + +diff --git a/drivers/media/platform/atmel/Kconfig b/drivers/media/platform/atmel/Kconfig +index 1850fe7f9360..99b51213f871 100644 +--- a/drivers/media/platform/atmel/Kconfig ++++ b/drivers/media/platform/atmel/Kconfig +@@ -12,6 +12,17 @@ config VIDEO_ATMEL_ISC + This module makes the ATMEL Image Sensor Controller available + as a v4l2 device. + ++config VIDEO_ATMEL_XISC ++ tristate "ATMEL eXtended Image Sensor Controller (XISC) support" ++ depends on VIDEO_V4L2 && COMMON_CLK && VIDEO_V4L2_SUBDEV_API ++ depends on ARCH_AT91 || COMPILE_TEST ++ select VIDEOBUF2_DMA_CONTIG ++ select REGMAP_MMIO ++ select V4L2_FWNODE ++ help ++ This module makes the ATMEL eXtended Image Sensor Controller ++ available as a v4l2 device. ++ + config VIDEO_ATMEL_ISI + tristate "ATMEL Image Sensor Interface (ISI) support" + depends on VIDEO_V4L2 && OF +diff --git a/drivers/media/platform/atmel/Makefile b/drivers/media/platform/atmel/Makefile +index 2dba38994a70..c5c01556c653 100644 +--- a/drivers/media/platform/atmel/Makefile ++++ b/drivers/media/platform/atmel/Makefile +@@ -1,5 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0-only + atmel-isc-objs = atmel-sama5d2-isc.o atmel-isc-base.o ++atmel-xisc-objs = atmel-sama7g5-isc.o atmel-isc-base.o + + obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o + obj-$(CONFIG_VIDEO_ATMEL_ISC) += atmel-isc.o ++obj-$(CONFIG_VIDEO_ATMEL_XISC) += atmel-xisc.o +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index dcb321ad10b8..46c6e3e20f33 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -600,7 +600,7 @@ static int isc_configure(struct isc_device *isc) + mask = ISC_PFE_CFG0_BPS_MASK | ISC_PFE_CFG0_HPOL_LOW | + ISC_PFE_CFG0_VPOL_LOW | ISC_PFE_CFG0_PPOL_LOW | + ISC_PFE_CFG0_MODE_MASK | ISC_PFE_CFG0_CCIR_CRC | +- ISC_PFE_CFG0_CCIR656; ++ ISC_PFE_CFG0_CCIR656 | ISC_PFE_CFG0_MIPI; + + regmap_update_bits(regmap, ISC_PFE_CFG0, mask, pfe_cfg0); + +diff --git a/drivers/media/platform/atmel/atmel-isc-regs.h b/drivers/media/platform/atmel/atmel-isc-regs.h +index 5f99bf7717c1..d06b72228d4f 100644 +--- a/drivers/media/platform/atmel/atmel-isc-regs.h ++++ b/drivers/media/platform/atmel/atmel-isc-regs.h +@@ -26,6 +26,7 @@ + #define ISC_PFE_CFG0_PPOL_LOW BIT(2) + #define ISC_PFE_CFG0_CCIR656 BIT(9) + #define ISC_PFE_CFG0_CCIR_CRC BIT(10) ++#define ISC_PFE_CFG0_MIPI BIT(14) + + #define ISC_PFE_CFG0_MODE_PROGRESSIVE (0x0 << 4) + #define ISC_PFE_CFG0_MODE_MASK GENMASK(6, 4) +@@ -184,6 +185,8 @@ + /* ISC Gamma Correction Control Register */ + #define ISC_GAM_CTRL 0x00000094 + ++#define ISC_GAM_CTRL_BIPART BIT(4) ++ + /* ISC_Gamma Correction Blue Entry Register */ + #define ISC_GAM_BENTRY 0x00000098 + +@@ -222,6 +225,8 @@ + + /* Offset for CSC register specific to sama5d2 product */ + #define ISC_SAMA5D2_CSC_OFFSET 0 ++/* Offset for CSC register specific to sama7g5 product */ ++#define ISC_SAMA7G5_CSC_OFFSET 0x11c + + /* Color Space Conversion Control Register */ + #define ISC_CSC_CTRL 0x00000398 +@@ -246,6 +251,8 @@ + + /* Offset for CBC register specific to sama5d2 product */ + #define ISC_SAMA5D2_CBC_OFFSET 0 ++/* Offset for CBC register specific to sama7g5 product */ ++#define ISC_SAMA7G5_CBC_OFFSET 0x11c + + /* Contrast And Brightness Control Register */ + #define ISC_CBC_CTRL 0x000003b4 +@@ -261,18 +268,30 @@ + #define ISC_CBC_CONTRAST 0x000003c0 + #define ISC_CBC_CONTRAST_MASK GENMASK(11, 0) + ++/* Hue Register */ ++#define ISC_CBCHS_HUE 0x4e0 ++/* Saturation Register */ ++#define ISC_CBCHS_SAT 0x4e4 ++ + /* Offset for SUB422 register specific to sama5d2 product */ + #define ISC_SAMA5D2_SUB422_OFFSET 0 ++/* Offset for SUB422 register specific to sama7g5 product */ ++#define ISC_SAMA7G5_SUB422_OFFSET 0x124 ++ + /* Subsampling 4:4:4 to 4:2:2 Control Register */ + #define ISC_SUB422_CTRL 0x000003c4 + + /* Offset for SUB420 register specific to sama5d2 product */ + #define ISC_SAMA5D2_SUB420_OFFSET 0 ++/* Offset for SUB420 register specific to sama7g5 product */ ++#define ISC_SAMA7G5_SUB420_OFFSET 0x124 + /* Subsampling 4:2:2 to 4:2:0 Control Register */ + #define ISC_SUB420_CTRL 0x000003cc + + /* Offset for RLP register specific to sama5d2 product */ + #define ISC_SAMA5D2_RLP_OFFSET 0 ++/* Offset for RLP register specific to sama7g5 product */ ++#define ISC_SAMA7G5_RLP_OFFSET 0x124 + /* Rounding, Limiting and Packing Configuration Register */ + #define ISC_RLP_CFG 0x000003d0 + +@@ -303,6 +322,8 @@ + + /* Offset for HIS register specific to sama5d2 product */ + #define ISC_SAMA5D2_HIS_OFFSET 0 ++/* Offset for HIS register specific to sama7g5 product */ ++#define ISC_SAMA7G5_HIS_OFFSET 0x124 + /* Histogram Control Register */ + #define ISC_HIS_CTRL 0x000003d4 + +@@ -326,6 +347,8 @@ + + /* Offset for DMA register specific to sama5d2 product */ + #define ISC_SAMA5D2_DMA_OFFSET 0 ++/* Offset for DMA register specific to sama7g5 product */ ++#define ISC_SAMA7G5_DMA_OFFSET 0x13c + + /* DMA Configuration Register */ + #define ISC_DCFG 0x000003e0 +@@ -376,11 +399,14 @@ + + /* Offset for version register specific to sama5d2 product */ + #define ISC_SAMA5D2_VERSION_OFFSET 0 ++#define ISC_SAMA7G5_VERSION_OFFSET 0x13c + /* Version Register */ + #define ISC_VERSION 0x0000040c + + /* Offset for version register specific to sama5d2 product */ + #define ISC_SAMA5D2_HIS_ENTRY_OFFSET 0 ++/* Offset for version register specific to sama7g5 product */ ++#define ISC_SAMA7G5_HIS_ENTRY_OFFSET 0x14c + /* Histogram Entry */ + #define ISC_HIS_ENTRY 0x00000410 + +diff --git a/drivers/media/platform/atmel/atmel-sama7g5-isc.c b/drivers/media/platform/atmel/atmel-sama7g5-isc.c +new file mode 100644 +index 000000000000..f2785131ff56 +--- /dev/null ++++ b/drivers/media/platform/atmel/atmel-sama7g5-isc.c +@@ -0,0 +1,630 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Microchip eXtended Image Sensor Controller (XISC) driver ++ * ++ * Copyright (C) 2019-2021 Microchip Technology, Inc. and its subsidiaries ++ * ++ * Author: Eugen Hristev <eugen.hristev@microchip.com> ++ * ++ * Sensor-->PFE-->DPC-->WB-->CFA-->CC-->GAM-->VHXS-->CSC-->CBHS-->SUB-->RLP-->DMA-->HIS ++ * ++ * ISC video pipeline integrates the following submodules: ++ * PFE: Parallel Front End to sample the camera sensor input stream ++ * DPC: Defective Pixel Correction with black offset correction, green disparity ++ * correction and defective pixel correction (3 modules total) ++ * WB: Programmable white balance in the Bayer domain ++ * CFA: Color filter array interpolation module ++ * CC: Programmable color correction ++ * GAM: Gamma correction ++ *VHXS: Vertical and Horizontal Scaler ++ * CSC: Programmable color space conversion ++ *CBHS: Contrast Brightness Hue and Saturation control ++ * SUB: This module performs YCbCr444 to YCbCr420 chrominance subsampling ++ * RLP: This module performs rounding, range limiting ++ * and packing of the incoming data ++ * DMA: This module performs DMA master accesses to write frames to external RAM ++ * HIS: Histogram module performs statistic counters on the frames ++ */ ++ ++#include <linux/clk.h> ++#include <linux/clkdev.h> ++#include <linux/clk-provider.h> ++#include <linux/delay.h> ++#include <linux/interrupt.h> ++#include <linux/math64.h> ++#include <linux/module.h> ++#include <linux/of.h> ++#include <linux/of_graph.h> ++#include <linux/platform_device.h> ++#include <linux/pm_runtime.h> ++#include <linux/regmap.h> ++#include <linux/videodev2.h> ++ ++#include <media/v4l2-ctrls.h> ++#include <media/v4l2-device.h> ++#include <media/v4l2-event.h> ++#include <media/v4l2-image-sizes.h> ++#include <media/v4l2-ioctl.h> ++#include <media/v4l2-fwnode.h> ++#include <media/v4l2-subdev.h> ++#include <media/videobuf2-dma-contig.h> ++ ++#include "atmel-isc-regs.h" ++#include "atmel-isc.h" ++ ++#define ISC_SAMA7G5_MAX_SUPPORT_WIDTH 3264 ++#define ISC_SAMA7G5_MAX_SUPPORT_HEIGHT 2464 ++ ++#define ISC_SAMA7G5_PIPELINE \ ++ (WB_ENABLE | CFA_ENABLE | CC_ENABLE | GAM_ENABLES | CSC_ENABLE | \ ++ CBC_ENABLE | SUB422_ENABLE | SUB420_ENABLE) ++ ++/* This is a list of the formats that the ISC can *output* */ ++static const struct isc_format sama7g5_controller_formats[] = { ++ { ++ .fourcc = V4L2_PIX_FMT_ARGB444, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_ARGB555, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_RGB565, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_ABGR32, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_XBGR32, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_YUV420, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_UYVY, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_VYUY, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_YUYV, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_YUV422P, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_GREY, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_Y10, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_Y16, ++ }, ++}; ++ ++/* This is a list of formats that the ISC can receive as *input* */ ++static struct isc_format sama7g5_formats_list[] = { ++ { ++ .fourcc = V4L2_PIX_FMT_SBGGR8, ++ .mbus_code = MEDIA_BUS_FMT_SBGGR8_1X8, ++ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, ++ .cfa_baycfg = ISC_BAY_CFG_BGBG, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_SGBRG8, ++ .mbus_code = MEDIA_BUS_FMT_SGBRG8_1X8, ++ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, ++ .cfa_baycfg = ISC_BAY_CFG_GBGB, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_SGRBG8, ++ .mbus_code = MEDIA_BUS_FMT_SGRBG8_1X8, ++ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, ++ .cfa_baycfg = ISC_BAY_CFG_GRGR, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_SRGGB8, ++ .mbus_code = MEDIA_BUS_FMT_SRGGB8_1X8, ++ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, ++ .cfa_baycfg = ISC_BAY_CFG_RGRG, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_SBGGR10, ++ .mbus_code = MEDIA_BUS_FMT_SBGGR10_1X10, ++ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, ++ .cfa_baycfg = ISC_BAY_CFG_RGRG, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_SGBRG10, ++ .mbus_code = MEDIA_BUS_FMT_SGBRG10_1X10, ++ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, ++ .cfa_baycfg = ISC_BAY_CFG_GBGB, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_SGRBG10, ++ .mbus_code = MEDIA_BUS_FMT_SGRBG10_1X10, ++ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, ++ .cfa_baycfg = ISC_BAY_CFG_GRGR, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_SRGGB10, ++ .mbus_code = MEDIA_BUS_FMT_SRGGB10_1X10, ++ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, ++ .cfa_baycfg = ISC_BAY_CFG_RGRG, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_SBGGR12, ++ .mbus_code = MEDIA_BUS_FMT_SBGGR12_1X12, ++ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, ++ .cfa_baycfg = ISC_BAY_CFG_BGBG, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_SGBRG12, ++ .mbus_code = MEDIA_BUS_FMT_SGBRG12_1X12, ++ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, ++ .cfa_baycfg = ISC_BAY_CFG_GBGB, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_SGRBG12, ++ .mbus_code = MEDIA_BUS_FMT_SGRBG12_1X12, ++ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, ++ .cfa_baycfg = ISC_BAY_CFG_GRGR, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_SRGGB12, ++ .mbus_code = MEDIA_BUS_FMT_SRGGB12_1X12, ++ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TWELVE, ++ .cfa_baycfg = ISC_BAY_CFG_RGRG, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_GREY, ++ .mbus_code = MEDIA_BUS_FMT_Y8_1X8, ++ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_YUYV, ++ .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, ++ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_UYVY, ++ .mbus_code = MEDIA_BUS_FMT_YUYV8_2X8, ++ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_RGB565, ++ .mbus_code = MEDIA_BUS_FMT_RGB565_2X8_LE, ++ .pfe_cfg0_bps = ISC_PFE_CFG0_BPS_EIGHT, ++ }, ++ { ++ .fourcc = V4L2_PIX_FMT_Y10, ++ .mbus_code = MEDIA_BUS_FMT_Y10_1X10, ++ .pfe_cfg0_bps = ISC_PFG_CFG0_BPS_TEN, ++ }, ++ ++}; ++ ++static void isc_sama7g5_config_csc(struct isc_device *isc) ++{ ++ struct regmap *regmap = isc->regmap; ++ ++ /* Convert RGB to YUV */ ++ regmap_write(regmap, ISC_CSC_YR_YG + isc->offsets.csc, ++ 0x42 | (0x81 << 16)); ++ regmap_write(regmap, ISC_CSC_YB_OY + isc->offsets.csc, ++ 0x19 | (0x10 << 16)); ++ regmap_write(regmap, ISC_CSC_CBR_CBG + isc->offsets.csc, ++ 0xFDA | (0xFB6 << 16)); ++ regmap_write(regmap, ISC_CSC_CBB_OCB + isc->offsets.csc, ++ 0x70 | (0x80 << 16)); ++ regmap_write(regmap, ISC_CSC_CRR_CRG + isc->offsets.csc, ++ 0x70 | (0xFA2 << 16)); ++ regmap_write(regmap, ISC_CSC_CRB_OCR + isc->offsets.csc, ++ 0xFEE | (0x80 << 16)); ++} ++ ++static void isc_sama7g5_config_cbc(struct isc_device *isc) ++{ ++ struct regmap *regmap = isc->regmap; ++ ++ /* Configure what is set via v4l2 ctrls */ ++ regmap_write(regmap, ISC_CBC_BRIGHT + isc->offsets.cbc, isc->ctrls.brightness); ++ regmap_write(regmap, ISC_CBC_CONTRAST + isc->offsets.cbc, isc->ctrls.contrast); ++ /* Configure Hue and Saturation as neutral midpoint */ ++ regmap_write(regmap, ISC_CBCHS_HUE, 0); ++ regmap_write(regmap, ISC_CBCHS_SAT, (1 << 4)); ++} ++ ++static void isc_sama7g5_config_cc(struct isc_device *isc) ++{ ++ struct regmap *regmap = isc->regmap; ++ ++ /* Configure each register at the neutral fixed point 1.0 or 0.0 */ ++ regmap_write(regmap, ISC_CC_RR_RG, (1 << 8)); ++ regmap_write(regmap, ISC_CC_RB_OR, 0); ++ regmap_write(regmap, ISC_CC_GR_GG, (1 << 8) << 16); ++ regmap_write(regmap, ISC_CC_GB_OG, 0); ++ regmap_write(regmap, ISC_CC_BR_BG, 0); ++ regmap_write(regmap, ISC_CC_BB_OB, (1 << 8)); ++} ++ ++static void isc_sama7g5_config_ctrls(struct isc_device *isc, ++ const struct v4l2_ctrl_ops *ops) ++{ ++ struct isc_ctrls *ctrls = &isc->ctrls; ++ struct v4l2_ctrl_handler *hdl = &ctrls->handler; ++ ++ ctrls->contrast = 16; ++ ++ v4l2_ctrl_new_std(hdl, ops, V4L2_CID_CONTRAST, -2048, 2047, 1, 16); ++} ++ ++static void isc_sama7g5_config_dpc(struct isc_device *isc) ++{ ++ u32 bay_cfg = isc->config.sd_format->cfa_baycfg; ++ struct regmap *regmap = isc->regmap; ++ ++ regmap_update_bits(regmap, ISC_DPC_CFG, ISC_DPC_CFG_BLOFF_MASK, ++ (64 << ISC_DPC_CFG_BLOFF_SHIFT)); ++ regmap_update_bits(regmap, ISC_DPC_CFG, ISC_DPC_CFG_BAYCFG_MASK, ++ (bay_cfg << ISC_DPC_CFG_BAYCFG_SHIFT)); ++} ++ ++static void isc_sama7g5_config_gam(struct isc_device *isc) ++{ ++ struct regmap *regmap = isc->regmap; ++ ++ regmap_update_bits(regmap, ISC_GAM_CTRL, ISC_GAM_CTRL_BIPART, ++ ISC_GAM_CTRL_BIPART); ++} ++ ++static void isc_sama7g5_config_rlp(struct isc_device *isc) ++{ ++ struct regmap *regmap = isc->regmap; ++ u32 rlp_mode = isc->config.rlp_cfg_mode; ++ ++ regmap_update_bits(regmap, ISC_RLP_CFG + isc->offsets.rlp, ++ ISC_RLP_CFG_MODE_MASK | ISC_RLP_CFG_LSH | ++ ISC_RLP_CFG_YMODE_MASK, rlp_mode); ++} ++ ++static void isc_sama7g5_adapt_pipeline(struct isc_device *isc) ++{ ++ isc->try_config.bits_pipeline &= ISC_SAMA7G5_PIPELINE; ++} ++ ++/* Gamma table with gamma 1/2.2 */ ++static const u32 isc_sama7g5_gamma_table[][GAMMA_ENTRIES] = { ++ /* index 0 --> gamma bipartite */ ++ { ++ 0x980, 0x4c0320, 0x650260, 0x7801e0, 0x8701a0, 0x940180, ++ 0xa00160, 0xab0120, 0xb40120, 0xbd0120, 0xc60100, 0xce0100, ++ 0xd600e0, 0xdd00e0, 0xe400e0, 0xeb00c0, 0xf100c0, 0xf700c0, ++ 0xfd00c0, 0x10300a0, 0x10800c0, 0x10e00a0, 0x11300a0, 0x11800a0, ++ 0x11d00a0, 0x12200a0, 0x12700a0, 0x12c0080, 0x13000a0, 0x1350080, ++ 0x13900a0, 0x13e0080, 0x1420076, 0x17d0062, 0x1ae0054, 0x1d8004a, ++ 0x1fd0044, 0x21f003e, 0x23e003a, 0x25b0036, 0x2760032, 0x28f0030, ++ 0x2a7002e, 0x2be002c, 0x2d4002c, 0x2ea0028, 0x2fe0028, 0x3120026, ++ 0x3250024, 0x3370024, 0x3490022, 0x35a0022, 0x36b0020, 0x37b0020, ++ 0x38b0020, 0x39b001e, 0x3aa001e, 0x3b9001c, 0x3c7001c, 0x3d5001c, ++ 0x3e3001c, 0x3f1001c, 0x3ff001a, 0x40c001a }, ++}; ++ ++static int xisc_parse_dt(struct device *dev, struct isc_device *isc) ++{ ++ struct device_node *np = dev->of_node; ++ struct device_node *epn = NULL; ++ struct isc_subdev_entity *subdev_entity; ++ unsigned int flags; ++ int ret; ++ bool mipi_mode; ++ ++ INIT_LIST_HEAD(&isc->subdev_entities); ++ ++ mipi_mode = of_property_read_bool(np, "microchip,mipi-mode"); ++ ++ while (1) { ++ struct v4l2_fwnode_endpoint v4l2_epn = { .bus_type = 0 }; ++ ++ epn = of_graph_get_next_endpoint(np, epn); ++ if (!epn) ++ return 0; ++ ++ ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(epn), ++ &v4l2_epn); ++ if (ret) { ++ ret = -EINVAL; ++ dev_err(dev, "Could not parse the endpoint\n"); ++ break; ++ } ++ ++ subdev_entity = devm_kzalloc(dev, sizeof(*subdev_entity), ++ GFP_KERNEL); ++ if (!subdev_entity) { ++ ret = -ENOMEM; ++ break; ++ } ++ subdev_entity->epn = epn; ++ ++ flags = v4l2_epn.bus.parallel.flags; ++ ++ if (flags & V4L2_MBUS_HSYNC_ACTIVE_LOW) ++ subdev_entity->pfe_cfg0 = ISC_PFE_CFG0_HPOL_LOW; ++ ++ if (flags & V4L2_MBUS_VSYNC_ACTIVE_LOW) ++ subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_VPOL_LOW; ++ ++ if (flags & V4L2_MBUS_PCLK_SAMPLE_FALLING) ++ subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_PPOL_LOW; ++ ++ if (v4l2_epn.bus_type == V4L2_MBUS_BT656) ++ subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_CCIR_CRC | ++ ISC_PFE_CFG0_CCIR656; ++ ++ if (mipi_mode) ++ subdev_entity->pfe_cfg0 |= ISC_PFE_CFG0_MIPI; ++ ++ list_add_tail(&subdev_entity->list, &isc->subdev_entities); ++ } ++ of_node_put(epn); ++ ++ return ret; ++} ++ ++static int microchip_xisc_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct isc_device *isc; ++ struct resource *res; ++ void __iomem *io_base; ++ struct isc_subdev_entity *subdev_entity; ++ int irq; ++ int ret; ++ u32 ver; ++ ++ isc = devm_kzalloc(dev, sizeof(*isc), GFP_KERNEL); ++ if (!isc) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, isc); ++ isc->dev = dev; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ io_base = devm_ioremap_resource(dev, res); ++ if (IS_ERR(io_base)) ++ return PTR_ERR(io_base); ++ ++ isc->regmap = devm_regmap_init_mmio(dev, io_base, &isc_regmap_config); ++ if (IS_ERR(isc->regmap)) { ++ ret = PTR_ERR(isc->regmap); ++ dev_err(dev, "failed to init register map: %d\n", ret); ++ return ret; ++ } ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) ++ return irq; ++ ++ ret = devm_request_irq(dev, irq, isc_interrupt, 0, ++ "microchip-sama7g5-xisc", isc); ++ if (ret < 0) { ++ dev_err(dev, "can't register ISR for IRQ %u (ret=%i)\n", ++ irq, ret); ++ return ret; ++ } ++ ++ isc->gamma_table = isc_sama7g5_gamma_table; ++ isc->gamma_max = 0; ++ ++ isc->max_width = ISC_SAMA7G5_MAX_SUPPORT_WIDTH; ++ isc->max_height = ISC_SAMA7G5_MAX_SUPPORT_HEIGHT; ++ ++ isc->config_dpc = isc_sama7g5_config_dpc; ++ isc->config_csc = isc_sama7g5_config_csc; ++ isc->config_cbc = isc_sama7g5_config_cbc; ++ isc->config_cc = isc_sama7g5_config_cc; ++ isc->config_gam = isc_sama7g5_config_gam; ++ isc->config_rlp = isc_sama7g5_config_rlp; ++ isc->config_ctrls = isc_sama7g5_config_ctrls; ++ ++ isc->adapt_pipeline = isc_sama7g5_adapt_pipeline; ++ ++ isc->offsets.csc = ISC_SAMA7G5_CSC_OFFSET; ++ isc->offsets.cbc = ISC_SAMA7G5_CBC_OFFSET; ++ isc->offsets.sub422 = ISC_SAMA7G5_SUB422_OFFSET; ++ isc->offsets.sub420 = ISC_SAMA7G5_SUB420_OFFSET; ++ isc->offsets.rlp = ISC_SAMA7G5_RLP_OFFSET; ++ isc->offsets.his = ISC_SAMA7G5_HIS_OFFSET; ++ isc->offsets.dma = ISC_SAMA7G5_DMA_OFFSET; ++ isc->offsets.version = ISC_SAMA7G5_VERSION_OFFSET; ++ isc->offsets.his_entry = ISC_SAMA7G5_HIS_ENTRY_OFFSET; ++ ++ isc->controller_formats = sama7g5_controller_formats; ++ isc->controller_formats_size = ARRAY_SIZE(sama7g5_controller_formats); ++ isc->formats_list = sama7g5_formats_list; ++ isc->formats_list_size = ARRAY_SIZE(sama7g5_formats_list); ++ ++ /* sama7g5-isc RAM access port is full AXI4 - 32 bits per beat */ ++ isc->dcfg = ISC_DCFG_YMBSIZE_BEATS32 | ISC_DCFG_CMBSIZE_BEATS32; ++ ++ ret = isc_pipeline_init(isc); ++ if (ret) ++ return ret; ++ ++ isc->hclock = devm_clk_get(dev, "hclock"); ++ if (IS_ERR(isc->hclock)) { ++ ret = PTR_ERR(isc->hclock); ++ dev_err(dev, "failed to get hclock: %d\n", ret); ++ return ret; ++ } ++ ++ ret = clk_prepare_enable(isc->hclock); ++ if (ret) { ++ dev_err(dev, "failed to enable hclock: %d\n", ret); ++ return ret; ++ } ++ ++ ret = isc_clk_init(isc); ++ if (ret) { ++ dev_err(dev, "failed to init isc clock: %d\n", ret); ++ goto unprepare_hclk; ++ } ++ ++ isc->ispck = isc->isc_clks[ISC_ISPCK].clk; ++ ++ ret = clk_prepare_enable(isc->ispck); ++ if (ret) { ++ dev_err(dev, "failed to enable ispck: %d\n", ret); ++ goto unprepare_hclk; ++ } ++ ++ /* ispck should be greater or equal to hclock */ ++ ret = clk_set_rate(isc->ispck, clk_get_rate(isc->hclock)); ++ if (ret) { ++ dev_err(dev, "failed to set ispck rate: %d\n", ret); ++ goto unprepare_clk; ++ } ++ ++ ret = v4l2_device_register(dev, &isc->v4l2_dev); ++ if (ret) { ++ dev_err(dev, "unable to register v4l2 device.\n"); ++ goto unprepare_clk; ++ } ++ ++ ret = xisc_parse_dt(dev, isc); ++ if (ret) { ++ dev_err(dev, "fail to parse device tree\n"); ++ goto unregister_v4l2_device; ++ } ++ ++ if (list_empty(&isc->subdev_entities)) { ++ dev_err(dev, "no subdev found\n"); ++ ret = -ENODEV; ++ goto unregister_v4l2_device; ++ } ++ ++ list_for_each_entry(subdev_entity, &isc->subdev_entities, list) { ++ struct v4l2_async_subdev *asd; ++ ++ v4l2_async_notifier_init(&subdev_entity->notifier); ++ ++ asd = v4l2_async_notifier_add_fwnode_remote_subdev( ++ &subdev_entity->notifier, ++ of_fwnode_handle(subdev_entity->epn), ++ struct v4l2_async_subdev); ++ ++ of_node_put(subdev_entity->epn); ++ subdev_entity->epn = NULL; ++ ++ if (IS_ERR(asd)) { ++ ret = PTR_ERR(asd); ++ goto cleanup_subdev; ++ } ++ ++ subdev_entity->notifier.ops = &isc_async_ops; ++ ++ ret = v4l2_async_notifier_register(&isc->v4l2_dev, ++ &subdev_entity->notifier); ++ if (ret) { ++ dev_err(dev, "fail to register async notifier\n"); ++ goto cleanup_subdev; ++ } ++ ++ if (video_is_registered(&isc->video_dev)) ++ break; ++ } ++ ++ pm_runtime_set_active(dev); ++ pm_runtime_enable(dev); ++ pm_request_idle(dev); ++ ++ regmap_read(isc->regmap, ISC_VERSION + isc->offsets.version, &ver); ++ dev_info(dev, "Microchip XISC version %x\n", ver); ++ ++ return 0; ++ ++cleanup_subdev: ++ isc_subdev_cleanup(isc); ++ ++unregister_v4l2_device: ++ v4l2_device_unregister(&isc->v4l2_dev); ++ ++unprepare_clk: ++ clk_disable_unprepare(isc->ispck); ++unprepare_hclk: ++ clk_disable_unprepare(isc->hclock); ++ ++ isc_clk_cleanup(isc); ++ ++ return ret; ++} ++ ++static int microchip_xisc_remove(struct platform_device *pdev) ++{ ++ struct isc_device *isc = platform_get_drvdata(pdev); ++ ++ pm_runtime_disable(&pdev->dev); ++ ++ isc_subdev_cleanup(isc); ++ ++ v4l2_device_unregister(&isc->v4l2_dev); ++ ++ clk_disable_unprepare(isc->ispck); ++ clk_disable_unprepare(isc->hclock); ++ ++ isc_clk_cleanup(isc); ++ ++ return 0; ++} ++ ++static int __maybe_unused xisc_runtime_suspend(struct device *dev) ++{ ++ struct isc_device *isc = dev_get_drvdata(dev); ++ ++ clk_disable_unprepare(isc->ispck); ++ clk_disable_unprepare(isc->hclock); ++ ++ return 0; ++} ++ ++static int __maybe_unused xisc_runtime_resume(struct device *dev) ++{ ++ struct isc_device *isc = dev_get_drvdata(dev); ++ int ret; ++ ++ ret = clk_prepare_enable(isc->hclock); ++ if (ret) ++ return ret; ++ ++ ret = clk_prepare_enable(isc->ispck); ++ if (ret) ++ clk_disable_unprepare(isc->hclock); ++ ++ return ret; ++} ++ ++static const struct dev_pm_ops microchip_xisc_dev_pm_ops = { ++ SET_RUNTIME_PM_OPS(xisc_runtime_suspend, xisc_runtime_resume, NULL) ++}; ++ ++static const struct of_device_id microchip_xisc_of_match[] = { ++ { .compatible = "microchip,sama7g5-isc" }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, microchip_xisc_of_match); ++ ++static struct platform_driver microchip_xisc_driver = { ++ .probe = microchip_xisc_probe, ++ .remove = microchip_xisc_remove, ++ .driver = { ++ .name = "microchip-sama7g5-xisc", ++ .pm = µchip_xisc_dev_pm_ops, ++ .of_match_table = of_match_ptr(microchip_xisc_of_match), ++ }, ++}; ++ ++module_platform_driver(microchip_xisc_driver); ++ ++MODULE_AUTHOR("Eugen Hristev <eugen.hristev@microchip.com>"); ++MODULE_DESCRIPTION("The V4L2 driver for Microchip-XISC"); ++MODULE_LICENSE("GPL v2"); +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/186-ASoC-atmel-fix-shadowed-variable.patch b/target/linux/at91/patches-5.10/186-ASoC-atmel-fix-shadowed-variable.patch new file mode 100644 index 0000000000..17e208b4a0 --- /dev/null +++ b/target/linux/at91/patches-5.10/186-ASoC-atmel-fix-shadowed-variable.patch @@ -0,0 +1,53 @@ +From 1b41c69264d7233a3e9a0aa36333ee22a5a049e9 Mon Sep 17 00:00:00 2001 +From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> +Date: Fri, 26 Mar 2021 16:59:12 -0500 +Subject: [PATCH 186/247] ASoC: atmel: fix shadowed variable + +Fix cppcheck warning: + +sound/soc/atmel/atmel-classd.c:51:14: style: Local variable 'pwm_type' +shadows outer variable [shadowVariable] + const char *pwm_type; + ^ +sound/soc/atmel/atmel-classd.c:226:27: note: Shadowed declaration +static const char * const pwm_type[] = { + ^ +sound/soc/atmel/atmel-classd.c:51:14: note: Shadow variable + const char *pwm_type; + ^ + +Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> +Reviewed-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Link: https://lore.kernel.org/r/20210326215927.936377-3-pierre-louis.bossart@linux.intel.com +Signed-off-by: Mark Brown <broonie@kernel.org> +--- + sound/soc/atmel/atmel-classd.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/sound/soc/atmel/atmel-classd.c b/sound/soc/atmel/atmel-classd.c +index b1a28a9382fb..6023369e0f1a 100644 +--- a/sound/soc/atmel/atmel-classd.c ++++ b/sound/soc/atmel/atmel-classd.c +@@ -48,7 +48,7 @@ static struct atmel_classd_pdata *atmel_classd_dt_init(struct device *dev) + { + struct device_node *np = dev->of_node; + struct atmel_classd_pdata *pdata; +- const char *pwm_type; ++ const char *pwm_type_s; + int ret; + + if (!np) { +@@ -60,8 +60,8 @@ static struct atmel_classd_pdata *atmel_classd_dt_init(struct device *dev) + if (!pdata) + return ERR_PTR(-ENOMEM); + +- ret = of_property_read_string(np, "atmel,pwm-type", &pwm_type); +- if ((ret == 0) && (strcmp(pwm_type, "diff") == 0)) ++ ret = of_property_read_string(np, "atmel,pwm-type", &pwm_type_s); ++ if ((ret == 0) && (strcmp(pwm_type_s, "diff") == 0)) + pdata->pwm_type = CLASSD_MR_PWMTYP_DIFF; + else + pdata->pwm_type = CLASSD_MR_PWMTYP_SINGLE; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/187-ASoC-atmel-atmel-i2s-remove-useless-initialization.patch b/target/linux/at91/patches-5.10/187-ASoC-atmel-atmel-i2s-remove-useless-initialization.patch new file mode 100644 index 0000000000..60f825c521 --- /dev/null +++ b/target/linux/at91/patches-5.10/187-ASoC-atmel-atmel-i2s-remove-useless-initialization.patch @@ -0,0 +1,41 @@ +From e53725fe0c7e6b52927280272f49fe5f4b4ef317 Mon Sep 17 00:00:00 2001 +From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> +Date: Fri, 26 Mar 2021 16:59:13 -0500 +Subject: [PATCH 187/247] ASoC: atmel: atmel-i2s: remove useless initialization + +Cppcheck complains: + +sound/soc/atmel/atmel-i2s.c:628:6: style: Redundant initialization for 'err'. The initialized value is overwritten before it is read. [redundantInitialization] + err = devm_request_irq(&pdev->dev, irq, atmel_i2s_interrupt, 0, + ^ +sound/soc/atmel/atmel-i2s.c:598:10: note: err is initialized + int err = -ENXIO; + ^ +sound/soc/atmel/atmel-i2s.c:628:6: note: err is overwritten + err = devm_request_irq(&pdev->dev, irq, atmel_i2s_interrupt, 0, + ^ + +Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> +Reviewed-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Link: https://lore.kernel.org/r/20210326215927.936377-4-pierre-louis.bossart@linux.intel.com +Signed-off-by: Mark Brown <broonie@kernel.org> +--- + sound/soc/atmel/atmel-i2s.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/sound/soc/atmel/atmel-i2s.c b/sound/soc/atmel/atmel-i2s.c +index 7483c474ccd7..e7169c63becd 100644 +--- a/sound/soc/atmel/atmel-i2s.c ++++ b/sound/soc/atmel/atmel-i2s.c +@@ -613,7 +613,7 @@ static int atmel_i2s_probe(struct platform_device *pdev) + struct regmap *regmap; + void __iomem *base; + int irq; +- int err = -ENXIO; ++ int err; + unsigned int pcm_flags = 0; + unsigned int version; + +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/188-ASoC-atmel-i2s-Set-symmetric-sample-bits.patch b/target/linux/at91/patches-5.10/188-ASoC-atmel-i2s-Set-symmetric-sample-bits.patch new file mode 100644 index 0000000000..6a3bcc5060 --- /dev/null +++ b/target/linux/at91/patches-5.10/188-ASoC-atmel-i2s-Set-symmetric-sample-bits.patch @@ -0,0 +1,31 @@ +From a6f337fdf68294cfae233724567cbeea0ae5148f Mon Sep 17 00:00:00 2001 +From: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Date: Fri, 18 Jun 2021 18:07:40 +0300 +Subject: [PATCH 188/247] ASoC: atmel-i2s: Set symmetric sample bits + +The I2S needs to have the same sample bits for both capture and playback +streams. + +Fixes: b543e467d1a9 ("ASoC: atmel-i2s: add driver for the new Atmel I2S controller") +Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Link: https://lore.kernel.org/r/20210618150741.401739-1-codrin.ciubotariu@microchip.com +Signed-off-by: Mark Brown <broonie@kernel.org> +--- + sound/soc/atmel/atmel-i2s.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/soc/atmel/atmel-i2s.c b/sound/soc/atmel/atmel-i2s.c +index e7169c63becd..2a5bc7a54e6c 100644 +--- a/sound/soc/atmel/atmel-i2s.c ++++ b/sound/soc/atmel/atmel-i2s.c +@@ -560,6 +560,7 @@ static struct snd_soc_dai_driver atmel_i2s_dai = { + }, + .ops = &atmel_i2s_dai_ops, + .symmetric_rates = 1, ++ .symmetric_samplebits = 1, + }; + + static const struct snd_soc_component_driver atmel_i2s_component = { +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/189-watchdog-sama5d4_wdt-add-support-for-sama7g5-wdt.patch b/target/linux/at91/patches-5.10/189-watchdog-sama5d4_wdt-add-support-for-sama7g5-wdt.patch new file mode 100644 index 0000000000..55ce7c525b --- /dev/null +++ b/target/linux/at91/patches-5.10/189-watchdog-sama5d4_wdt-add-support-for-sama7g5-wdt.patch @@ -0,0 +1,51 @@ +From ff83cc9f95aaba75991210312061b7fe52aaa400 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Thu, 27 May 2021 13:01:19 +0300 +Subject: [PATCH 189/247] watchdog: sama5d4_wdt: add support for sama7g5-wdt + +Add support for compatible sama7g5-wdt. +The sama7g5 wdt is the same hardware block as on sam9x60. +Adapt the driver to use the sam9x60/sama7g5 variant if either +of the two compatibles are selected (sam9x60-wdt/sama7g5-wdt). + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Reviewed-by: Guenter Roeck <linux@roeck-us.net> +Link: https://lore.kernel.org/r/20210527100120.266796-2-eugen.hristev@microchip.com +Signed-off-by: Guenter Roeck <linux@roeck-us.net> +Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org> +--- + drivers/watchdog/sama5d4_wdt.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/drivers/watchdog/sama5d4_wdt.c b/drivers/watchdog/sama5d4_wdt.c +index e5d11d6a2600..ec20ad4e534f 100644 +--- a/drivers/watchdog/sama5d4_wdt.c ++++ b/drivers/watchdog/sama5d4_wdt.c +@@ -268,8 +268,10 @@ static int sama5d4_wdt_probe(struct platform_device *pdev) + wdd->min_timeout = MIN_WDT_TIMEOUT; + wdd->max_timeout = MAX_WDT_TIMEOUT; + wdt->last_ping = jiffies; +- wdt->sam9x60_support = of_device_is_compatible(dev->of_node, +- "microchip,sam9x60-wdt"); ++ ++ if (of_device_is_compatible(dev->of_node, "microchip,sam9x60-wdt") || ++ of_device_is_compatible(dev->of_node, "microchip,sama7g5-wdt")) ++ wdt->sam9x60_support = true; + + watchdog_set_drvdata(wdd, wdt); + +@@ -329,6 +331,10 @@ static const struct of_device_id sama5d4_wdt_of_match[] = { + { + .compatible = "microchip,sam9x60-wdt", + }, ++ { ++ .compatible = "microchip,sama7g5-wdt", ++ }, ++ + { } + }; + MODULE_DEVICE_TABLE(of, sama5d4_wdt_of_match); +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/190-media-atmel-fix-build-when-ISC-m-and-XISC-y.patch b/target/linux/at91/patches-5.10/190-media-atmel-fix-build-when-ISC-m-and-XISC-y.patch new file mode 100644 index 0000000000..f4d7bacdb4 --- /dev/null +++ b/target/linux/at91/patches-5.10/190-media-atmel-fix-build-when-ISC-m-and-XISC-y.patch @@ -0,0 +1,144 @@ +From dfcc0395f5e838c0b5c3fb93c9335b6a8892178a Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Mon, 5 Jul 2021 14:57:08 +0200 +Subject: [PATCH 190/247] media: atmel: fix build when ISC=m and XISC=y + +Building VIDEO_ATMEL_ISC as module and VIDEO_ATMEL_XISC as built-in +(or viceversa) causes build errors: + + or1k-linux-ld: drivers/media/platform/atmel/atmel-isc-base.o: in function `isc_async_complete': + atmel-isc-base.c:(.text+0x40d0): undefined reference to `__this_module' + or1k-linux-ld: atmel-isc-base.c:(.text+0x40f0): undefined reference to `__this_module' + or1k-linux-ld: drivers/media/platform/atmel/atmel-isc-base.o:(.rodata+0x390): undefined reference to `__this_module' + or1k-linux-ld: drivers/media/platform/atmel/atmel-isc-base.o:(__param+0x4): undefined reference to `__this_module' + or1k-linux-ld: drivers/media/platform/atmel/atmel-isc-base.o:(__param+0x18): undefined reference to `__this_module' + +This is caused by the file atmel-isc-base.c which is common code between +the two drivers. + +The solution is to create another Kconfig symbol that is automatically +selected and generates the module atmel-isc-base.ko. This module can be +loaded when both drivers are modules, or built-in when at least one of them +is built-in. + +Reported-by: kernel test robot <lkp@intel.com> +Fixes: c9aa973884a1 ("media: atmel: atmel-isc: add microchip-xisc driver") +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + drivers/media/platform/atmel/Kconfig | 8 ++++++++ + drivers/media/platform/atmel/Makefile | 5 +++-- + drivers/media/platform/atmel/atmel-isc-base.c | 11 +++++++++++ + 3 files changed, 22 insertions(+), 2 deletions(-) + +diff --git a/drivers/media/platform/atmel/Kconfig b/drivers/media/platform/atmel/Kconfig +index 99b51213f871..dda2f27da317 100644 +--- a/drivers/media/platform/atmel/Kconfig ++++ b/drivers/media/platform/atmel/Kconfig +@@ -8,6 +8,7 @@ config VIDEO_ATMEL_ISC + select VIDEOBUF2_DMA_CONTIG + select REGMAP_MMIO + select V4L2_FWNODE ++ select VIDEO_ATMEL_ISC_BASE + help + This module makes the ATMEL Image Sensor Controller available + as a v4l2 device. +@@ -19,10 +20,17 @@ config VIDEO_ATMEL_XISC + select VIDEOBUF2_DMA_CONTIG + select REGMAP_MMIO + select V4L2_FWNODE ++ select VIDEO_ATMEL_ISC_BASE + help + This module makes the ATMEL eXtended Image Sensor Controller + available as a v4l2 device. + ++config VIDEO_ATMEL_ISC_BASE ++ tristate ++ default n ++ help ++ ATMEL ISC and XISC common code base. ++ + config VIDEO_ATMEL_ISI + tristate "ATMEL Image Sensor Interface (ISI) support" + depends on VIDEO_V4L2 && OF +diff --git a/drivers/media/platform/atmel/Makefile b/drivers/media/platform/atmel/Makefile +index c5c01556c653..46d264ab7948 100644 +--- a/drivers/media/platform/atmel/Makefile ++++ b/drivers/media/platform/atmel/Makefile +@@ -1,7 +1,8 @@ + # SPDX-License-Identifier: GPL-2.0-only +-atmel-isc-objs = atmel-sama5d2-isc.o atmel-isc-base.o +-atmel-xisc-objs = atmel-sama7g5-isc.o atmel-isc-base.o ++atmel-isc-objs = atmel-sama5d2-isc.o ++atmel-xisc-objs = atmel-sama7g5-isc.o + + obj-$(CONFIG_VIDEO_ATMEL_ISI) += atmel-isi.o ++obj-$(CONFIG_VIDEO_ATMEL_ISC_BASE) += atmel-isc-base.o + obj-$(CONFIG_VIDEO_ATMEL_ISC) += atmel-isc.o + obj-$(CONFIG_VIDEO_ATMEL_XISC) += atmel-xisc.o +diff --git a/drivers/media/platform/atmel/atmel-isc-base.c b/drivers/media/platform/atmel/atmel-isc-base.c +index 46c6e3e20f33..54168b72fd2f 100644 +--- a/drivers/media/platform/atmel/atmel-isc-base.c ++++ b/drivers/media/platform/atmel/atmel-isc-base.c +@@ -378,6 +378,7 @@ int isc_clk_init(struct isc_device *isc) + + return 0; + } ++EXPORT_SYMBOL_GPL(isc_clk_init); + + void isc_clk_cleanup(struct isc_device *isc) + { +@@ -392,6 +393,7 @@ void isc_clk_cleanup(struct isc_device *isc) + clk_unregister(isc_clk->clk); + } + } ++EXPORT_SYMBOL_GPL(isc_clk_cleanup); + + static int isc_queue_setup(struct vb2_queue *vq, + unsigned int *nbuffers, unsigned int *nplanes, +@@ -1575,6 +1577,7 @@ irqreturn_t isc_interrupt(int irq, void *dev_id) + + return ret; + } ++EXPORT_SYMBOL_GPL(isc_interrupt); + + static void isc_hist_count(struct isc_device *isc, u32 *min, u32 *max) + { +@@ -2209,6 +2212,7 @@ const struct v4l2_async_notifier_operations isc_async_ops = { + .unbind = isc_async_unbind, + .complete = isc_async_complete, + }; ++EXPORT_SYMBOL_GPL(isc_async_ops); + + void isc_subdev_cleanup(struct isc_device *isc) + { +@@ -2221,6 +2225,7 @@ void isc_subdev_cleanup(struct isc_device *isc) + + INIT_LIST_HEAD(&isc->subdev_entities); + } ++EXPORT_SYMBOL_GPL(isc_subdev_cleanup); + + int isc_pipeline_init(struct isc_device *isc) + { +@@ -2261,6 +2266,7 @@ int isc_pipeline_init(struct isc_device *isc) + + return 0; + } ++EXPORT_SYMBOL_GPL(isc_pipeline_init); + + /* regmap configuration */ + #define ATMEL_ISC_REG_MAX 0xd5c +@@ -2270,4 +2276,9 @@ const struct regmap_config isc_regmap_config = { + .val_bits = 32, + .max_register = ATMEL_ISC_REG_MAX, + }; ++EXPORT_SYMBOL_GPL(isc_regmap_config); + ++MODULE_AUTHOR("Songjun Wu"); ++MODULE_AUTHOR("Eugen Hristev"); ++MODULE_DESCRIPTION("Atmel ISC common code base"); ++MODULE_LICENSE("GPL v2"); +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/191-i2c-at91-remove-define-CONFIG_PM.patch b/target/linux/at91/patches-5.10/191-i2c-at91-remove-define-CONFIG_PM.patch new file mode 100644 index 0000000000..bbdf5bcbac --- /dev/null +++ b/target/linux/at91/patches-5.10/191-i2c-at91-remove-define-CONFIG_PM.patch @@ -0,0 +1,81 @@ +From 023a6b46536dce41f2c5a7425826fc4da4509b8f Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Mon, 5 Jul 2021 15:15:16 +0300 +Subject: [PATCH 191/247] i2c: at91: remove #define CONFIG_PM + +Remove #define CONFIG_PM and use __maybe_unused for PM functions and +pm_ptr() for PM ops. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Reviewed-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Signed-off-by: Wolfram Sang <wsa@kernel.org> +--- + drivers/i2c/busses/i2c-at91-core.c | 17 +++++------------ + 1 file changed, 5 insertions(+), 12 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-at91-core.c b/drivers/i2c/busses/i2c-at91-core.c +index e14edd236108..9f3c3e8e8011 100644 +--- a/drivers/i2c/busses/i2c-at91-core.c ++++ b/drivers/i2c/busses/i2c-at91-core.c +@@ -286,9 +286,7 @@ static int at91_twi_remove(struct platform_device *pdev) + return 0; + } + +-#ifdef CONFIG_PM +- +-static int at91_twi_runtime_suspend(struct device *dev) ++static int __maybe_unused at91_twi_runtime_suspend(struct device *dev) + { + struct at91_twi_dev *twi_dev = dev_get_drvdata(dev); + +@@ -299,7 +297,7 @@ static int at91_twi_runtime_suspend(struct device *dev) + return 0; + } + +-static int at91_twi_runtime_resume(struct device *dev) ++static int __maybe_unused at91_twi_runtime_resume(struct device *dev) + { + struct at91_twi_dev *twi_dev = dev_get_drvdata(dev); + +@@ -308,7 +306,7 @@ static int at91_twi_runtime_resume(struct device *dev) + return clk_prepare_enable(twi_dev->clk); + } + +-static int at91_twi_suspend_noirq(struct device *dev) ++static int __maybe_unused at91_twi_suspend_noirq(struct device *dev) + { + if (!pm_runtime_status_suspended(dev)) + at91_twi_runtime_suspend(dev); +@@ -316,7 +314,7 @@ static int at91_twi_suspend_noirq(struct device *dev) + return 0; + } + +-static int at91_twi_resume_noirq(struct device *dev) ++static int __maybe_unused at91_twi_resume_noirq(struct device *dev) + { + struct at91_twi_dev *twi_dev = dev_get_drvdata(dev); + int ret; +@@ -342,11 +340,6 @@ static const struct dev_pm_ops at91_twi_pm = { + .runtime_resume = at91_twi_runtime_resume, + }; + +-#define at91_twi_pm_ops (&at91_twi_pm) +-#else +-#define at91_twi_pm_ops NULL +-#endif +- + static struct platform_driver at91_twi_driver = { + .probe = at91_twi_probe, + .remove = at91_twi_remove, +@@ -354,7 +347,7 @@ static struct platform_driver at91_twi_driver = { + .driver = { + .name = "at91_i2c", + .of_match_table = of_match_ptr(atmel_twi_dt_ids), +- .pm = at91_twi_pm_ops, ++ .pm = pm_ptr(&at91_twi_pm), + }, + }; + +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/192-ASoC-codecs-ad193x-add-support-for-96kHz-and-192kHz-.patch b/target/linux/at91/patches-5.10/192-ASoC-codecs-ad193x-add-support-for-96kHz-and-192kHz-.patch new file mode 100644 index 0000000000..54fe85861f --- /dev/null +++ b/target/linux/at91/patches-5.10/192-ASoC-codecs-ad193x-add-support-for-96kHz-and-192kHz-.patch @@ -0,0 +1,98 @@ +From 1c906a59a60887e1b997ebab63f19f33a1c69a3e Mon Sep 17 00:00:00 2001 +From: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Date: Tue, 3 Aug 2021 13:48:25 +0300 +Subject: [PATCH 192/247] ASoC: codecs: ad193x: add support for 96kHz and + 192kHz playback rates + +ad193x devices support 96KHz and 192KHz sampling rates, when PLL/MCLK is +referenced to 48kHz. +Tested on ad1934. + +Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +Link: https://lore.kernel.org/r/20210803104825.2198335-1-codrin.ciubotariu@microchip.com +Signed-off-by: Mark Brown <broonie@kernel.org> +--- + sound/soc/codecs/ad193x.c | 30 ++++++++++++++++++++++++++++-- + sound/soc/codecs/ad193x.h | 4 ++++ + 2 files changed, 32 insertions(+), 2 deletions(-) + +diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c +index f37ab7eda615..278a55af158b 100644 +--- a/sound/soc/codecs/ad193x.c ++++ b/sound/soc/codecs/ad193x.c +@@ -316,6 +316,13 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream, + int word_len = 0, master_rate = 0; + struct snd_soc_component *component = dai->component; + struct ad193x_priv *ad193x = snd_soc_component_get_drvdata(component); ++ bool is_playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK; ++ u8 dacc0; ++ ++ dev_dbg(dai->dev, "%s() rate=%u format=%#x width=%u channels=%u\n", ++ __func__, params_rate(params), params_format(params), ++ params_width(params), params_channels(params)); ++ + + /* bit size */ + switch (params_width(params)) { +@@ -346,6 +353,25 @@ static int ad193x_hw_params(struct snd_pcm_substream *substream, + break; + } + ++ if (is_playback) { ++ switch (params_rate(params)) { ++ case 48000: ++ dacc0 = AD193X_DAC_SR_48; ++ break; ++ case 96000: ++ dacc0 = AD193X_DAC_SR_96; ++ break; ++ case 192000: ++ dacc0 = AD193X_DAC_SR_192; ++ break; ++ default: ++ dev_err(dai->dev, "invalid sampling rate: %d\n", params_rate(params)); ++ return -EINVAL; ++ } ++ ++ regmap_update_bits(ad193x->regmap, AD193X_DAC_CTRL0, AD193X_DAC_SR_MASK, dacc0); ++ } ++ + regmap_update_bits(ad193x->regmap, AD193X_PLL_CLK_CTRL0, + AD193X_PLL_INPUT_MASK, master_rate); + +@@ -385,7 +411,7 @@ static struct snd_soc_dai_driver ad193x_dai = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 8, +- .rates = SNDRV_PCM_RATE_48000, ++ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE, + }, +@@ -407,7 +433,7 @@ static struct snd_soc_dai_driver ad193x_no_adc_dai = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 8, +- .rates = SNDRV_PCM_RATE_48000, ++ .rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_192000, + .formats = SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S24_LE, + }, +diff --git a/sound/soc/codecs/ad193x.h b/sound/soc/codecs/ad193x.h +index 377854712c20..61f4648861d5 100644 +--- a/sound/soc/codecs/ad193x.h ++++ b/sound/soc/codecs/ad193x.h +@@ -37,6 +37,10 @@ int ad193x_probe(struct device *dev, struct regmap *regmap, + #define AD193X_PLL_CLK_SRC_MCLK (1 << 1) + #define AD193X_DAC_CTRL0 0x02 + #define AD193X_DAC_POWERDOWN 0x01 ++#define AD193X_DAC_SR_MASK 0x06 ++#define AD193X_DAC_SR_48 (0 << 1) ++#define AD193X_DAC_SR_96 (1 << 1) ++#define AD193X_DAC_SR_192 (2 << 1) + #define AD193X_DAC_SERFMT_MASK 0xC0 + #define AD193X_DAC_SERFMT_STEREO (0 << 6) + #define AD193X_DAC_SERFMT_TDM (1 << 6) +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/193-media-atmel-atmel-sama5d2-isc-fix-YUYV-format.patch b/target/linux/at91/patches-5.10/193-media-atmel-atmel-sama5d2-isc-fix-YUYV-format.patch new file mode 100644 index 0000000000..c8cf87021f --- /dev/null +++ b/target/linux/at91/patches-5.10/193-media-atmel-atmel-sama5d2-isc-fix-YUYV-format.patch @@ -0,0 +1,53 @@ +From 21261e30679118b96ed537d1cdf9e12682fc1b29 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Wed, 9 Jun 2021 15:00:28 +0200 +Subject: [PATCH 193/247] media: atmel: atmel-sama5d2-isc: fix YUYV format + +SAMA5D2 does not have the YCYC field for the RLP (rounding, limiting, +packaging) module. +The YCYC field is supposed to work with interleaved YUV formats like YUYV. +In SAMA5D2, we have to use YYCC field, which is used for both planar +formats like YUV420 and interleaved formats like YUYV. +Fix the according rlp callback to replace the generic YCYC field (which +makes more sense from a logical point of view) with the required YYCC +field. + +Fixes: debfa496871c ("media: atmel: atmel-isc-base: add support for more formats and additional pipeline modules") +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Hans Verkuil <hverkuil-cisco@xs4all.nl> +Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org> +--- + .../media/platform/atmel/atmel-sama5d2-isc.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/drivers/media/platform/atmel/atmel-sama5d2-isc.c b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +index d6fd22b127fd..4f09db71d152 100644 +--- a/drivers/media/platform/atmel/atmel-sama5d2-isc.c ++++ b/drivers/media/platform/atmel/atmel-sama5d2-isc.c +@@ -255,6 +255,23 @@ static void isc_sama5d2_config_rlp(struct isc_device *isc) + struct regmap *regmap = isc->regmap; + u32 rlp_mode = isc->config.rlp_cfg_mode; + ++ /* ++ * In sama5d2, the YUV planar modes and the YUYV modes are treated ++ * in the same way in RLP register. ++ * Normally, YYCC mode should be Luma(n) - Color B(n) - Color R (n) ++ * and YCYC should be Luma(n + 1) - Color B (n) - Luma (n) - Color R (n) ++ * but in sama5d2, the YCYC mode does not exist, and YYCC must be ++ * selected for both planar and interleaved modes, as in fact ++ * both modes are supported. ++ * ++ * Thus, if the YCYC mode is selected, replace it with the ++ * sama5d2-compliant mode which is YYCC . ++ */ ++ if ((rlp_mode & ISC_RLP_CFG_MODE_YCYC) == ISC_RLP_CFG_MODE_YCYC) { ++ rlp_mode &= ~ISC_RLP_CFG_MODE_MASK; ++ rlp_mode |= ISC_RLP_CFG_MODE_YYCC; ++ } ++ + regmap_update_bits(regmap, ISC_RLP_CFG + isc->offsets.rlp, + ISC_RLP_CFG_MODE_MASK, rlp_mode); + } +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/194-clk-at91-add-register-definition-for-sama7g5-s-maste.patch b/target/linux/at91/patches-5.10/194-clk-at91-add-register-definition-for-sama7g5-s-maste.patch new file mode 100644 index 0000000000..deda80985d --- /dev/null +++ b/target/linux/at91/patches-5.10/194-clk-at91-add-register-definition-for-sama7g5-s-maste.patch @@ -0,0 +1,56 @@ +From 602f85ff15d45bd313f8f6600d72202a50fd83a9 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Mon, 19 Jul 2021 11:03:17 +0300 +Subject: [PATCH 194/247] clk: at91: add register definition for sama7g5's + master clock + +Add register definitions for SAMA7G5's master clock. These would be +also used by architecture specific power saving code. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210719080317.1045832-3-claudiu.beznea@microchip.com +--- + include/linux/clk/at91_pmc.h | 26 ++++++++++++++++++++++++++ + 1 file changed, 26 insertions(+) + +diff --git a/include/linux/clk/at91_pmc.h b/include/linux/clk/at91_pmc.h +index a4f82e836a7c..ccb3f034bfa9 100644 +--- a/include/linux/clk/at91_pmc.h ++++ b/include/linux/clk/at91_pmc.h +@@ -137,6 +137,32 @@ + #define AT91_PMC_PLLADIV2_ON (1 << 12) + #define AT91_PMC_H32MXDIV BIT(24) + ++#define AT91_PMC_MCR_V2 0x30 /* Master Clock Register [SAMA7G5 only] */ ++#define AT91_PMC_MCR_V2_ID_MSK (0xF) ++#define AT91_PMC_MCR_V2_ID(_id) ((_id) & AT91_PMC_MCR_V2_ID_MSK) ++#define AT91_PMC_MCR_V2_CMD (1 << 7) ++#define AT91_PMC_MCR_V2_DIV (7 << 8) ++#define AT91_PMC_MCR_V2_DIV1 (0 << 8) ++#define AT91_PMC_MCR_V2_DIV2 (1 << 8) ++#define AT91_PMC_MCR_V2_DIV4 (2 << 8) ++#define AT91_PMC_MCR_V2_DIV8 (3 << 8) ++#define AT91_PMC_MCR_V2_DIV16 (4 << 8) ++#define AT91_PMC_MCR_V2_DIV32 (5 << 8) ++#define AT91_PMC_MCR_V2_DIV64 (6 << 8) ++#define AT91_PMC_MCR_V2_DIV3 (7 << 8) ++#define AT91_PMC_MCR_V2_CSS (0x1F << 16) ++#define AT91_PMC_MCR_V2_CSS_MD_SLCK (0 << 16) ++#define AT91_PMC_MCR_V2_CSS_TD_SLCK (1 << 16) ++#define AT91_PMC_MCR_V2_CSS_MAINCK (2 << 16) ++#define AT91_PMC_MCR_V2_CSS_MCK0 (3 << 16) ++#define AT91_PMC_MCR_V2_CSS_SYSPLL (5 << 16) ++#define AT91_PMC_MCR_V2_CSS_DDRPLL (6 << 16) ++#define AT91_PMC_MCR_V2_CSS_IMGPLL (7 << 16) ++#define AT91_PMC_MCR_V2_CSS_BAUDPLL (8 << 16) ++#define AT91_PMC_MCR_V2_CSS_AUDIOPLL (9 << 16) ++#define AT91_PMC_MCR_V2_CSS_ETHPLL (10 << 16) ++#define AT91_PMC_MCR_V2_EN (1 << 28) ++ + #define AT91_PMC_XTALF 0x34 /* Main XTAL Frequency Register [SAMA7G5 only] */ + + #define AT91_PMC_USB 0x38 /* USB Clock Register [some SAM9 only] */ +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/195-ARM-at91-add-new-SoC-sama7g5.patch b/target/linux/at91/patches-5.10/195-ARM-at91-add-new-SoC-sama7g5.patch new file mode 100644 index 0000000000..d333f0d957 --- /dev/null +++ b/target/linux/at91/patches-5.10/195-ARM-at91-add-new-SoC-sama7g5.patch @@ -0,0 +1,54 @@ +From 32bac6971d0572f67758f9a8c8af7bf4592f1675 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Fri, 9 Apr 2021 14:31:15 +0300 +Subject: [PATCH 195/247] ARM: at91: add new SoC sama7g5 + +Add new SoC from at91 family : sama7g5 + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +[claudiu.beznea@microchip.com: Select PLL, generic clock and UTMI support, add PM configs] +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210409113116.482199-1-eugen.hristev@microchip.com +Link: https://lore.kernel.org/r/20210719080317.1045832-2-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/Kconfig | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig +index ccd7e80ce943..b09bb2279f7f 100644 +--- a/arch/arm/mach-at91/Kconfig ++++ b/arch/arm/mach-at91/Kconfig +@@ -57,6 +57,16 @@ config SOC_SAMA5D4 + help + Select this if you are using one of Microchip's SAMA5D4 family SoC. + ++config SOC_SAMA7G5 ++ bool "SAMA7G5 family" ++ depends on ARCH_MULTI_V7 ++ select HAVE_AT91_GENERATED_CLK ++ select HAVE_AT91_SAM9X60_PLL ++ select HAVE_AT91_UTMI ++ select SOC_SAMA7 ++ help ++ Select this if you are using one of Microchip's SAMA7G5 family SoC. ++ + config SOC_AT91RM9200 + bool "AT91RM9200" + depends on ARCH_MULTI_V4T +@@ -191,4 +201,12 @@ config SOC_SAMA5 + config ATMEL_PM + bool + ++config SOC_SAMA7 ++ bool ++ select ARM_GIC ++ select ATMEL_PM if PM ++ select ATMEL_SDRAMC ++ select MEMORY ++ select SOC_SAM_V7 ++ select SRAM if PM + endif +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/196-ARM-at91-debug-add-sama7g5-low-level-debug-uart.patch b/target/linux/at91/patches-5.10/196-ARM-at91-debug-add-sama7g5-low-level-debug-uart.patch new file mode 100644 index 0000000000..40b05a43e8 --- /dev/null +++ b/target/linux/at91/patches-5.10/196-ARM-at91-debug-add-sama7g5-low-level-debug-uart.patch @@ -0,0 +1,55 @@ +From 3de4879bf59b46a966ea226a67df70b88f43a23e Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Fri, 9 Apr 2021 14:31:16 +0300 +Subject: [PATCH 196/247] ARM: at91: debug: add sama7g5 low level debug uart + +Add sama7g5 SoC debug uart on Flexcom3. This is the UART that the +ROM bootloader uses. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210409113116.482199-2-eugen.hristev@microchip.com +[claudiu.beznea: adapt to v5.10.27] +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +--- + arch/arm/Kconfig.debug | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug +index dd1cf7035398..09901118e3fb 100644 +--- a/arch/arm/Kconfig.debug ++++ b/arch/arm/Kconfig.debug +@@ -191,6 +191,14 @@ choice + their output to the USART1 port on SAMV7 based + machines. + ++ config DEBUG_AT91_SAMA7G5_FLEXCOM3 ++ bool "Kernel low-level debugging on SAMA7G5 FLEXCOM3" ++ select DEBUG_AT91_UART ++ depends on SOC_SAMA7G5 ++ help ++ Say Y here if you want kernel low-level debugging support ++ on the FLEXCOM3 port of SAMA7G5. ++ + config DEBUG_BCM2835 + bool "Kernel low-level debugging on BCM2835 PL011 UART" + depends on ARCH_BCM2835 && ARCH_MULTI_V6 +@@ -1731,6 +1739,7 @@ config DEBUG_UART_PHYS + default 0xd4017000 if DEBUG_MMP_UART2 + default 0xd4018000 if DEBUG_MMP_UART3 + default 0xe0000000 if DEBUG_SPEAR13XX ++ default 0xe1824200 if DEBUG_AT91_SAMA7G5_FLEXCOM3 + default 0xe4007000 if DEBUG_HIP04_UART + default 0xe6c40000 if DEBUG_RMOBILE_SCIFA0 + default 0xe6c50000 if DEBUG_RMOBILE_SCIFA1 +@@ -1791,6 +1800,7 @@ config DEBUG_UART_VIRT + default 0xc8912000 if DEBUG_RV1108_UART0 + default 0xe0010fe0 if ARCH_RPC + default 0xf0000be0 if ARCH_EBSA110 ++ default 0xe0824200 if DEBUG_AT91_SAMA7G5_FLEXCOM3 + default 0xf0010000 if DEBUG_ASM9260_UART + default 0xf0100000 if DEBUG_DIGICOLOR_UA0 + default 0xf01fb000 if DEBUG_NOMADIK_UART +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/197-ARM-at91-pm-move-pm_bu-to-soc_pm-data-structure.patch b/target/linux/at91/patches-5.10/197-ARM-at91-pm-move-pm_bu-to-soc_pm-data-structure.patch new file mode 100644 index 0000000000..fd5a8cd93e --- /dev/null +++ b/target/linux/at91/patches-5.10/197-ARM-at91-pm-move-pm_bu-to-soc_pm-data-structure.patch @@ -0,0 +1,92 @@ +From e41d00bdaa31b36fd314e927104082615aa4643a Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 15 Apr 2021 13:49:47 +0300 +Subject: [PATCH 197/247] ARM: at91: pm: move pm_bu to soc_pm data structure + +Move pm_bu to soc_pm data structure. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210415105010.569620-2-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm.c | 34 +++++++++++++++++++++------------- + 1 file changed, 21 insertions(+), 13 deletions(-) + +diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c +index 2dee383f9050..3fa223c21618 100644 +--- a/arch/arm/mach-at91/pm.c ++++ b/arch/arm/mach-at91/pm.c +@@ -27,10 +27,25 @@ + #include "generic.h" + #include "pm.h" + ++/** ++ * struct at91_pm_bu - AT91 power management backup unit data structure ++ * @suspended: true if suspended to backup mode ++ * @reserved: reserved ++ * @canary: canary data for memory checking after exit from backup mode ++ * @resume: resume API ++ */ ++struct at91_pm_bu { ++ int suspended; ++ unsigned long reserved; ++ phys_addr_t canary; ++ phys_addr_t resume; ++}; ++ + struct at91_soc_pm { + int (*config_shdwc_ws)(void __iomem *shdwc, u32 *mode, u32 *polarity); + int (*config_pmc_ws)(void __iomem *pmc, u32 mode, u32 polarity); + const struct of_device_id *ws_ids; ++ struct at91_pm_bu *bu; + struct at91_pm_data data; + }; + +@@ -71,13 +86,6 @@ static int at91_pm_valid_state(suspend_state_t state) + + static int canary = 0xA5A5A5A5; + +-static struct at91_pm_bu { +- int suspended; +- unsigned long reserved; +- phys_addr_t canary; +- phys_addr_t resume; +-} *pm_bu; +- + struct wakeup_source_info { + unsigned int pmc_fsmr_bit; + unsigned int shdwc_mr_bit; +@@ -288,7 +296,7 @@ static int at91_suspend_finish(unsigned long val) + static void at91_pm_suspend(suspend_state_t state) + { + if (soc_pm.data.mode == AT91_PM_BACKUP) { +- pm_bu->suspended = 1; ++ soc_pm.bu->suspended = 1; + + cpu_suspend(0, at91_suspend_finish); + +@@ -672,16 +680,16 @@ static int __init at91_pm_backup_init(void) + goto securam_fail; + } + +- pm_bu = (void *)gen_pool_alloc(sram_pool, sizeof(struct at91_pm_bu)); +- if (!pm_bu) { ++ soc_pm.bu = (void *)gen_pool_alloc(sram_pool, sizeof(struct at91_pm_bu)); ++ if (!soc_pm.bu) { + pr_warn("%s: unable to alloc securam!\n", __func__); + ret = -ENOMEM; + goto securam_fail; + } + +- pm_bu->suspended = 0; +- pm_bu->canary = __pa_symbol(&canary); +- pm_bu->resume = __pa_symbol(cpu_resume); ++ soc_pm.bu->suspended = 0; ++ soc_pm.bu->canary = __pa_symbol(&canary); ++ soc_pm.bu->resume = __pa_symbol(cpu_resume); + + return 0; + +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/198-ARM-at91-pm-move-the-setup-of-soc_pm.bu-suspended.patch b/target/linux/at91/patches-5.10/198-ARM-at91-pm-move-the-setup-of-soc_pm.bu-suspended.patch new file mode 100644 index 0000000000..bbc0d00eed --- /dev/null +++ b/target/linux/at91/patches-5.10/198-ARM-at91-pm-move-the-setup-of-soc_pm.bu-suspended.patch @@ -0,0 +1,60 @@ +From c8f2a8aaae41fa0a40ad88855ae82696098230d7 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 15 Apr 2021 13:49:48 +0300 +Subject: [PATCH 198/247] ARM: at91: pm: move the setup of soc_pm.bu->suspended + +Move the setup of soc_pm.bu->suspended in platform_suspend::begin +function so that the PMC code in charge with clocks suspend/resume +to differentiate b/w standard PM mode and backup mode. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Reviewed-by: Alexandre Belloni <alexandre.belloni@bootlin.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210415105010.569620-3-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm.c | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c +index 3fa223c21618..f182d8bf6f82 100644 +--- a/arch/arm/mach-at91/pm.c ++++ b/arch/arm/mach-at91/pm.c +@@ -214,6 +214,8 @@ static int at91_sam9x60_config_pmc_ws(void __iomem *pmc, u32 mode, u32 polarity) + */ + static int at91_pm_begin(suspend_state_t state) + { ++ int ret; ++ + switch (state) { + case PM_SUSPEND_MEM: + soc_pm.data.mode = soc_pm.data.suspend_mode; +@@ -227,7 +229,16 @@ static int at91_pm_begin(suspend_state_t state) + soc_pm.data.mode = -1; + } + +- return at91_pm_config_ws(soc_pm.data.mode, true); ++ ret = at91_pm_config_ws(soc_pm.data.mode, true); ++ if (ret) ++ return ret; ++ ++ if (soc_pm.data.mode == AT91_PM_BACKUP) ++ soc_pm.bu->suspended = 1; ++ else if (soc_pm.bu) ++ soc_pm.bu->suspended = 0; ++ ++ return 0; + } + + /* +@@ -296,8 +307,6 @@ static int at91_suspend_finish(unsigned long val) + static void at91_pm_suspend(suspend_state_t state) + { + if (soc_pm.data.mode == AT91_PM_BACKUP) { +- soc_pm.bu->suspended = 1; +- + cpu_suspend(0, at91_suspend_finish); + + /* The SRAM is lost between suspend cycles */ +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/199-ARM-at91-pm-document-at91_soc_pm-structure.patch b/target/linux/at91/patches-5.10/199-ARM-at91-pm-document-at91_soc_pm-structure.patch new file mode 100644 index 0000000000..b0b94e472a --- /dev/null +++ b/target/linux/at91/patches-5.10/199-ARM-at91-pm-document-at91_soc_pm-structure.patch @@ -0,0 +1,36 @@ +From 59a4b3b9381b727f416d9cc52e60d0bc7d93ecae Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 15 Apr 2021 13:49:49 +0300 +Subject: [PATCH 199/247] ARM: at91: pm: document at91_soc_pm structure + +Document at91_soc_pm structure. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210415105010.569620-4-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c +index f182d8bf6f82..a060bec77f20 100644 +--- a/arch/arm/mach-at91/pm.c ++++ b/arch/arm/mach-at91/pm.c +@@ -41,6 +41,14 @@ struct at91_pm_bu { + phys_addr_t resume; + }; + ++/** ++ * struct at91_soc_pm - AT91 SoC power management data structure ++ * @config_shdwc_ws: wakeup sources configuration function for SHDWC ++ * @config_pmc_ws: wakeup srouces configuration function for PMC ++ * @ws_ids: wakup sources of_device_id array ++ * @data: PM data to be used on last phase of suspend ++ * @bu: backup unit mapped data (for backup mode) ++ */ + struct at91_soc_pm { + int (*config_shdwc_ws)(void __iomem *shdwc, u32 *mode, u32 *polarity); + int (*config_pmc_ws)(void __iomem *pmc, u32 mode, u32 polarity); +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/200-ARM-at91-pm-check-for-different-controllers-in-at91_.patch b/target/linux/at91/patches-5.10/200-ARM-at91-pm-check-for-different-controllers-in-at91_.patch new file mode 100644 index 0000000000..b3ccdbf6d0 --- /dev/null +++ b/target/linux/at91/patches-5.10/200-ARM-at91-pm-check-for-different-controllers-in-at91_.patch @@ -0,0 +1,243 @@ +From 0c4cbd38a705bdeab11de4c84ad0ce8c3de8a81d Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 15 Apr 2021 13:49:50 +0300 +Subject: [PATCH 200/247] ARM: at91: pm: check for different controllers in + at91_pm_modes_init() + +at91_pm_modes_init() checks for proper nodes in device tree and maps +them accordingly. Up to SAMA7G5 all AT91 SoCs had the same mapping +b/w power saving modes and different controllers needed in the +final/first steps of suspend/resume. SAMA7G5 is not aligned with the +old SoCs thus the code is adapted for this. This patch prepares +the field for next commits. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210415105010.569620-5-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm.c | 143 +++++++++++++++++++++++++--------------- + 1 file changed, 91 insertions(+), 52 deletions(-) + +diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c +index a060bec77f20..e9f9fb410761 100644 +--- a/arch/arm/mach-at91/pm.c ++++ b/arch/arm/mach-at91/pm.c +@@ -57,6 +57,18 @@ struct at91_soc_pm { + struct at91_pm_data data; + }; + ++/** ++ * enum at91_pm_iomaps: IOs that needs to be mapped for different PM modes ++ * @AT91_PM_IOMAP_SHDWC: SHDWC controller ++ * @AT91_PM_IOMAP_SFRBU: SFRBU controller ++ */ ++enum at91_pm_iomaps { ++ AT91_PM_IOMAP_SHDWC, ++ AT91_PM_IOMAP_SFRBU, ++}; ++ ++#define AT91_PM_IOMAP(name) BIT(AT91_PM_IOMAP_##name) ++ + static struct at91_soc_pm soc_pm = { + .data = { + .standby_mode = AT91_PM_STANDBY, +@@ -671,24 +683,15 @@ static int __init at91_pm_backup_init(void) + if (!at91_is_pm_mode_active(AT91_PM_BACKUP)) + return 0; + +- np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-sfrbu"); +- if (!np) { +- pr_warn("%s: failed to find sfrbu!\n", __func__); +- return ret; +- } +- +- soc_pm.data.sfrbu = of_iomap(np, 0); +- of_node_put(np); +- + np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-securam"); + if (!np) +- goto securam_fail_no_ref_dev; ++ return ret; + + pdev = of_find_device_by_node(np); + of_node_put(np); + if (!pdev) { + pr_warn("%s: failed to find securam device!\n", __func__); +- goto securam_fail_no_ref_dev; ++ return ret; + } + + sram_pool = gen_pool_get(&pdev->dev, NULL); +@@ -712,64 +715,92 @@ static int __init at91_pm_backup_init(void) + + securam_fail: + put_device(&pdev->dev); +-securam_fail_no_ref_dev: +- iounmap(soc_pm.data.sfrbu); +- soc_pm.data.sfrbu = NULL; + return ret; + } + +-static void __init at91_pm_use_default_mode(int pm_mode) +-{ +- if (pm_mode != AT91_PM_ULP1 && pm_mode != AT91_PM_BACKUP) +- return; +- +- if (soc_pm.data.standby_mode == pm_mode) +- soc_pm.data.standby_mode = AT91_PM_ULP0; +- if (soc_pm.data.suspend_mode == pm_mode) +- soc_pm.data.suspend_mode = AT91_PM_ULP0; +-} +- + static const struct of_device_id atmel_shdwc_ids[] = { + { .compatible = "atmel,sama5d2-shdwc" }, + { .compatible = "microchip,sam9x60-shdwc" }, + { /* sentinel. */ } + }; + +-static void __init at91_pm_modes_init(void) ++static void __init at91_pm_modes_init(const u32 *maps, int len) + { + struct device_node *np; +- int ret; ++ int ret, mode; + +- if (!at91_is_pm_mode_active(AT91_PM_BACKUP) && +- !at91_is_pm_mode_active(AT91_PM_ULP1)) +- return; ++ ret = at91_pm_backup_init(); ++ if (ret) { ++ if (soc_pm.data.standby_mode == AT91_PM_BACKUP) ++ soc_pm.data.standby_mode = AT91_PM_ULP0; ++ if (soc_pm.data.suspend_mode == AT91_PM_BACKUP) ++ soc_pm.data.suspend_mode = AT91_PM_ULP0; ++ } + +- np = of_find_matching_node(NULL, atmel_shdwc_ids); +- if (!np) { +- pr_warn("%s: failed to find shdwc!\n", __func__); +- goto ulp1_default; ++ if (maps[soc_pm.data.standby_mode] & AT91_PM_IOMAP(SHDWC) || ++ maps[soc_pm.data.suspend_mode] & AT91_PM_IOMAP(SHDWC)) { ++ np = of_find_matching_node(NULL, atmel_shdwc_ids); ++ if (!np) { ++ pr_warn("%s: failed to find shdwc!\n", __func__); ++ ++ /* Use ULP0 if it doesn't needs SHDWC.*/ ++ if (!(maps[AT91_PM_ULP0] & AT91_PM_IOMAP(SHDWC))) ++ mode = AT91_PM_ULP0; ++ else ++ mode = AT91_PM_STANDBY; ++ ++ if (maps[soc_pm.data.standby_mode] & AT91_PM_IOMAP(SHDWC)) ++ soc_pm.data.standby_mode = mode; ++ if (maps[soc_pm.data.suspend_mode] & AT91_PM_IOMAP(SHDWC)) ++ soc_pm.data.suspend_mode = mode; ++ } else { ++ soc_pm.data.shdwc = of_iomap(np, 0); ++ of_node_put(np); ++ } + } + +- soc_pm.data.shdwc = of_iomap(np, 0); +- of_node_put(np); ++ if (maps[soc_pm.data.standby_mode] & AT91_PM_IOMAP(SFRBU) || ++ maps[soc_pm.data.suspend_mode] & AT91_PM_IOMAP(SFRBU)) { ++ np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-sfrbu"); ++ if (!np) { ++ pr_warn("%s: failed to find sfrbu!\n", __func__); ++ ++ /* ++ * Use ULP0 if it doesn't need SHDWC or if SHDWC ++ * was already located. ++ */ ++ if (!(maps[AT91_PM_ULP0] & AT91_PM_IOMAP(SHDWC)) || ++ soc_pm.data.shdwc) ++ mode = AT91_PM_ULP0; ++ else ++ mode = AT91_PM_STANDBY; ++ ++ if (maps[soc_pm.data.standby_mode] & AT91_PM_IOMAP(SFRBU)) ++ soc_pm.data.standby_mode = mode; ++ if (maps[soc_pm.data.suspend_mode] & AT91_PM_IOMAP(SFRBU)) ++ soc_pm.data.suspend_mode = mode; ++ } else { ++ soc_pm.data.sfrbu = of_iomap(np, 0); ++ of_node_put(np); ++ } ++ } + +- ret = at91_pm_backup_init(); +- if (ret) { +- if (!at91_is_pm_mode_active(AT91_PM_ULP1)) +- goto unmap; +- else +- goto backup_default; ++ /* Unmap all unnecessary. */ ++ if (soc_pm.data.shdwc && ++ !(maps[soc_pm.data.standby_mode] & AT91_PM_IOMAP(SHDWC) || ++ maps[soc_pm.data.suspend_mode] & AT91_PM_IOMAP(SHDWC))) { ++ iounmap(soc_pm.data.shdwc); ++ soc_pm.data.shdwc = NULL; + } + +- return; ++ if (soc_pm.data.sfrbu && ++ !(maps[soc_pm.data.standby_mode] & AT91_PM_IOMAP(SFRBU) || ++ maps[soc_pm.data.suspend_mode] & AT91_PM_IOMAP(SFRBU))) { ++ iounmap(soc_pm.data.sfrbu); ++ soc_pm.data.sfrbu = NULL; ++ } + +-unmap: +- iounmap(soc_pm.data.shdwc); +- soc_pm.data.shdwc = NULL; +-ulp1_default: +- at91_pm_use_default_mode(AT91_PM_ULP1); +-backup_default: +- at91_pm_use_default_mode(AT91_PM_BACKUP); ++ return; + } + + struct pmc_info { +@@ -936,13 +967,16 @@ void __init sam9x60_pm_init(void) + static const int modes[] __initconst = { + AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST, AT91_PM_ULP1, + }; ++ static const int iomaps[] __initconst = { ++ [AT91_PM_ULP1] = AT91_PM_IOMAP(SHDWC), ++ }; + int ret; + + if (!IS_ENABLED(CONFIG_SOC_SAM9X60)) + return; + + at91_pm_modes_validate(modes, ARRAY_SIZE(modes)); +- at91_pm_modes_init(); ++ at91_pm_modes_init(iomaps, ARRAY_SIZE(iomaps)); + ret = at91_dt_ramc(); + if (ret) + return; +@@ -999,13 +1033,18 @@ void __init sama5d2_pm_init(void) + AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP0_FAST, AT91_PM_ULP1, + AT91_PM_BACKUP, + }; ++ static const u32 iomaps[] __initconst = { ++ [AT91_PM_ULP1] = AT91_PM_IOMAP(SHDWC), ++ [AT91_PM_BACKUP] = AT91_PM_IOMAP(SHDWC) | ++ AT91_PM_IOMAP(SFRBU), ++ }; + int ret; + + if (!IS_ENABLED(CONFIG_SOC_SAMA5D2)) + return; + + at91_pm_modes_validate(modes, ARRAY_SIZE(modes)); +- at91_pm_modes_init(); ++ at91_pm_modes_init(iomaps, ARRAY_SIZE(iomaps)); + ret = at91_dt_ramc(); + if (ret) + return; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/201-ARM-at91-pm-do-not-initialize-pdev.patch b/target/linux/at91/patches-5.10/201-ARM-at91-pm-do-not-initialize-pdev.patch new file mode 100644 index 0000000000..805cda8a5b --- /dev/null +++ b/target/linux/at91/patches-5.10/201-ARM-at91-pm-do-not-initialize-pdev.patch @@ -0,0 +1,30 @@ +From 31e25503bbad1fffd29fd074a46bd4858b65304f Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 15 Apr 2021 13:49:51 +0300 +Subject: [PATCH 201/247] ARM: at91: pm: do not initialize pdev + +There is no need to initialize pdev. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210415105010.569620-6-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c +index e9f9fb410761..96f2be0a53cb 100644 +--- a/arch/arm/mach-at91/pm.c ++++ b/arch/arm/mach-at91/pm.c +@@ -674,7 +674,7 @@ static int __init at91_pm_backup_init(void) + { + struct gen_pool *sram_pool; + struct device_node *np; +- struct platform_device *pdev = NULL; ++ struct platform_device *pdev; + int ret = -ENODEV; + + if (!IS_ENABLED(CONFIG_SOC_SAMA5D2)) +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/202-ARM-at91-pm-use-r7-instead-of-tmp1.patch b/target/linux/at91/patches-5.10/202-ARM-at91-pm-use-r7-instead-of-tmp1.patch new file mode 100644 index 0000000000..f53d38556f --- /dev/null +++ b/target/linux/at91/patches-5.10/202-ARM-at91-pm-use-r7-instead-of-tmp1.patch @@ -0,0 +1,65 @@ +From 8a7a4cf3860910e460e2c3ca467b1dabf7ce9827 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 15 Apr 2021 13:49:52 +0300 +Subject: [PATCH 202/247] ARM: at91: pm: use r7 instead of tmp1 + +Use r7 instead of tmp1 in macros. This prepares the filed for +next commits. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210415105010.569620-7-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm_suspend.S | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S +index b683c2caa40b..3d20c9880fee 100644 +--- a/arch/arm/mach-at91/pm_suspend.S ++++ b/arch/arm/mach-at91/pm_suspend.S +@@ -31,30 +31,36 @@ tmp3 .req r6 + + /* + * Wait until master oscillator has stabilized. ++ * ++ * Side effects: overwrites r7 + */ + .macro wait_moscrdy +-1: ldr tmp1, [pmc, #AT91_PMC_SR] +- tst tmp1, #AT91_PMC_MOSCS ++1: ldr r7, [pmc, #AT91_PMC_SR] ++ tst r7, #AT91_PMC_MOSCS + beq 1b + .endm + + /* + * Wait for main oscillator selection is done ++ * ++ * Side effects: overwrites r7 + */ + .macro wait_moscsels +-1: ldr tmp1, [pmc, #AT91_PMC_SR] +- tst tmp1, #AT91_PMC_MOSCSELS ++1: ldr r7, [pmc, #AT91_PMC_SR] ++ tst r7, #AT91_PMC_MOSCSELS + beq 1b + .endm + + /* + * Put the processor to enter the idle state ++ * ++ * Side effects: overwrites r7 + */ + .macro at91_cpu_idle + + #if defined(CONFIG_CPU_V7) +- mov tmp1, #AT91_PMC_PCK +- str tmp1, [pmc, #AT91_PMC_SCDR] ++ mov r7, #AT91_PMC_PCK ++ str r7, [pmc, #AT91_PMC_SCDR] + + dsb + +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/203-ARM-at91-pm-avoid-push-and-pop-on-stack-while-memory.patch b/target/linux/at91/patches-5.10/203-ARM-at91-pm-avoid-push-and-pop-on-stack-while-memory.patch new file mode 100644 index 0000000000..3b59430c9e --- /dev/null +++ b/target/linux/at91/patches-5.10/203-ARM-at91-pm-avoid-push-and-pop-on-stack-while-memory.patch @@ -0,0 +1,472 @@ +From 892f6d2fb9c42d4ac451236639599f533c37b507 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 15 Apr 2021 13:49:53 +0300 +Subject: [PATCH 203/247] ARM: at91: pm: avoid push and pop on stack while + memory is in self-refersh + +For the previous AT91 RAM controller and self-refresh procedure this +had no side effects. However, for SAMA7G5 the self-refresh procedure +doesn't allow this anymore as the RAM controller ports are closed +before switching it to self-refresh. This commits prepares the code +for the following ones adding self-refresh and PM support for SAMA7G5. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210415105010.569620-8-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm_suspend.S | 397 +++++++++++++++++--------------- + 1 file changed, 205 insertions(+), 192 deletions(-) + +diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S +index 3d20c9880fee..960ad29cce51 100644 +--- a/arch/arm/mach-at91/pm_suspend.S ++++ b/arch/arm/mach-at91/pm_suspend.S +@@ -75,98 +75,147 @@ tmp3 .req r6 + + .arm + +-/* +- * void at91_suspend_sram_fn(struct at91_pm_data*) +- * @input param: +- * @r0: base address of struct at91_pm_data ++/** ++ * Enable self-refresh ++ * ++ * register usage: ++ * @r1: memory type ++ * @r2: base address of the sram controller ++ * @r3: temporary + */ +-/* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */ +- .align 3 +-ENTRY(at91_pm_suspend_in_sram) +- /* Save registers on stack */ +- stmfd sp!, {r4 - r12, lr} ++.macro at91_sramc_self_refresh_ena ++ ldr r1, .memtype ++ ldr r2, .sramc_base + +- /* Drain write buffer */ +- mov tmp1, #0 +- mcr p15, 0, tmp1, c7, c10, 4 ++ cmp r1, #AT91_MEMCTRL_MC ++ bne sr_ena_ddrc_sf + +- ldr tmp1, [r0, #PM_DATA_PMC] +- str tmp1, .pmc_base +- ldr tmp1, [r0, #PM_DATA_RAMC0] +- str tmp1, .sramc_base +- ldr tmp1, [r0, #PM_DATA_RAMC1] +- str tmp1, .sramc1_base +- ldr tmp1, [r0, #PM_DATA_MEMCTRL] +- str tmp1, .memtype +- ldr tmp1, [r0, #PM_DATA_MODE] +- str tmp1, .pm_mode +- ldr tmp1, [r0, #PM_DATA_PMC_MCKR_OFFSET] +- str tmp1, .mckr_offset +- ldr tmp1, [r0, #PM_DATA_PMC_VERSION] +- str tmp1, .pmc_version +- /* Both ldrne below are here to preload their address in the TLB */ +- ldr tmp1, [r0, #PM_DATA_SHDWC] +- str tmp1, .shdwc +- cmp tmp1, #0 +- ldrne tmp2, [tmp1, #0] +- ldr tmp1, [r0, #PM_DATA_SFRBU] +- str tmp1, .sfrbu +- cmp tmp1, #0 +- ldrne tmp2, [tmp1, #0x10] ++ /* Active SDRAM self-refresh mode */ ++ mov r3, #1 ++ str r3, [r2, #AT91_MC_SDRAMC_SRR] ++ b sr_ena_exit + +- /* Active the self-refresh mode */ +- mov r0, #SRAMC_SELF_FRESH_ACTIVE +- bl at91_sramc_self_refresh ++sr_ena_ddrc_sf: ++ cmp r1, #AT91_MEMCTRL_DDRSDR ++ bne sr_ena_sdramc_sf + +- ldr r0, .pm_mode +- cmp r0, #AT91_PM_STANDBY +- beq standby +- cmp r0, #AT91_PM_BACKUP +- beq backup_mode ++ /* ++ * DDR Memory controller ++ */ + +- bl at91_ulp_mode +- b exit_suspend ++ /* LPDDR1 --> force DDR2 mode during self-refresh */ ++ ldr r3, [r2, #AT91_DDRSDRC_MDR] ++ str r3, .saved_sam9_mdr ++ bic r3, r3, #~AT91_DDRSDRC_MD ++ cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR ++ ldreq r3, [r2, #AT91_DDRSDRC_MDR] ++ biceq r3, r3, #AT91_DDRSDRC_MD ++ orreq r3, r3, #AT91_DDRSDRC_MD_DDR2 ++ streq r3, [r2, #AT91_DDRSDRC_MDR] + +-standby: +- /* Wait for interrupt */ +- ldr pmc, .pmc_base +- at91_cpu_idle +- b exit_suspend ++ /* Active DDRC self-refresh mode */ ++ ldr r3, [r2, #AT91_DDRSDRC_LPR] ++ str r3, .saved_sam9_lpr ++ bic r3, r3, #AT91_DDRSDRC_LPCB ++ orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH ++ str r3, [r2, #AT91_DDRSDRC_LPR] + +-backup_mode: +- bl at91_backup_mode +- b exit_suspend ++ /* If using the 2nd ddr controller */ ++ ldr r2, .sramc1_base ++ cmp r2, #0 ++ beq sr_ena_no_2nd_ddrc + +-exit_suspend: +- /* Exit the self-refresh mode */ +- mov r0, #SRAMC_SELF_FRESH_EXIT +- bl at91_sramc_self_refresh ++ ldr r3, [r2, #AT91_DDRSDRC_MDR] ++ str r3, .saved_sam9_mdr1 ++ bic r3, r3, #~AT91_DDRSDRC_MD ++ cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR ++ ldreq r3, [r2, #AT91_DDRSDRC_MDR] ++ biceq r3, r3, #AT91_DDRSDRC_MD ++ orreq r3, r3, #AT91_DDRSDRC_MD_DDR2 ++ streq r3, [r2, #AT91_DDRSDRC_MDR] + +- /* Restore registers, and return */ +- ldmfd sp!, {r4 - r12, pc} +-ENDPROC(at91_pm_suspend_in_sram) ++ /* Active DDRC self-refresh mode */ ++ ldr r3, [r2, #AT91_DDRSDRC_LPR] ++ str r3, .saved_sam9_lpr1 ++ bic r3, r3, #AT91_DDRSDRC_LPCB ++ orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH ++ str r3, [r2, #AT91_DDRSDRC_LPR] + +-ENTRY(at91_backup_mode) +- /* Switch the master clock source to slow clock. */ +- ldr pmc, .pmc_base +- ldr tmp2, .mckr_offset +- ldr tmp1, [pmc, tmp2] +- bic tmp1, tmp1, #AT91_PMC_CSS +- str tmp1, [pmc, tmp2] ++sr_ena_no_2nd_ddrc: ++ b sr_ena_exit + +- wait_mckrdy ++ /* ++ * SDRAMC Memory controller ++ */ ++sr_ena_sdramc_sf: ++ /* Active SDRAMC self-refresh mode */ ++ ldr r3, [r2, #AT91_SDRAMC_LPR] ++ str r3, .saved_sam9_lpr ++ bic r3, r3, #AT91_SDRAMC_LPCB ++ orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH ++ str r3, [r2, #AT91_SDRAMC_LPR] + +- /*BUMEN*/ +- ldr r0, .sfrbu +- mov tmp1, #0x1 +- str tmp1, [r0, #0x10] ++ ldr r3, .saved_sam9_lpr ++ str r3, [r2, #AT91_SDRAMC_LPR] + +- /* Shutdown */ +- ldr r0, .shdwc +- mov tmp1, #0xA5000000 +- add tmp1, tmp1, #0x1 +- str tmp1, [r0, #0] +-ENDPROC(at91_backup_mode) ++sr_ena_exit: ++.endm ++ ++/** ++ * Disable self-refresh ++ * ++ * register usage: ++ * @r1: memory type ++ * @r2: base address of the sram controller ++ * @r3: temporary ++ */ ++.macro at91_sramc_self_refresh_dis ++ ldr r1, .memtype ++ ldr r2, .sramc_base ++ ++ cmp r1, #AT91_MEMCTRL_MC ++ bne sr_dis_ddrc_exit_sf ++ ++ /* ++ * at91rm9200 Memory controller ++ */ ++ ++ /* ++ * For exiting the self-refresh mode, do nothing, ++ * automatically exit the self-refresh mode. ++ */ ++ b sr_dis_exit ++ ++sr_dis_ddrc_exit_sf: ++ cmp r1, #AT91_MEMCTRL_DDRSDR ++ bne sdramc_exit_sf ++ ++ /* DDR Memory controller */ ++ ++ /* Restore MDR in case of LPDDR1 */ ++ ldr r3, .saved_sam9_mdr ++ str r3, [r2, #AT91_DDRSDRC_MDR] ++ /* Restore LPR on AT91 with DDRAM */ ++ ldr r3, .saved_sam9_lpr ++ str r3, [r2, #AT91_DDRSDRC_LPR] ++ ++ /* If using the 2nd ddr controller */ ++ ldr r2, .sramc1_base ++ cmp r2, #0 ++ ldrne r3, .saved_sam9_mdr1 ++ strne r3, [r2, #AT91_DDRSDRC_MDR] ++ ldrne r3, .saved_sam9_lpr1 ++ strne r3, [r2, #AT91_DDRSDRC_LPR] ++ ++ b sr_dis_exit ++ ++sdramc_exit_sf: ++ /* SDRAMC Memory controller */ ++ ldr r3, .saved_sam9_lpr ++ str r3, [r2, #AT91_SDRAMC_LPR] ++ ++sr_dis_exit: ++.endm + + .macro at91_pm_ulp0_mode + ldr pmc, .pmc_base +@@ -503,7 +552,7 @@ ENDPROC(at91_backup_mode) + 2: + .endm + +-ENTRY(at91_ulp_mode) ++.macro at91_ulp_mode + ldr pmc, .pmc_base + ldr tmp2, .mckr_offset + ldr tmp3, .pm_mode +@@ -552,133 +601,97 @@ ulp_exit: + + wait_mckrdy + +- mov pc, lr +-ENDPROC(at91_ulp_mode) +- +-/* +- * void at91_sramc_self_refresh(unsigned int is_active) +- * +- * @input param: +- * @r0: 1 - active self-refresh mode +- * 0 - exit self-refresh mode +- * register usage: +- * @r1: memory type +- * @r2: base address of the sram controller +- */ +- +-ENTRY(at91_sramc_self_refresh) +- ldr r1, .memtype +- ldr r2, .sramc_base +- +- cmp r1, #AT91_MEMCTRL_MC +- bne ddrc_sf +- +- /* +- * at91rm9200 Memory controller +- */ +- +- /* +- * For exiting the self-refresh mode, do nothing, +- * automatically exit the self-refresh mode. +- */ +- tst r0, #SRAMC_SELF_FRESH_ACTIVE +- beq exit_sramc_sf +- +- /* Active SDRAM self-refresh mode */ +- mov r3, #1 +- str r3, [r2, #AT91_MC_SDRAMC_SRR] +- b exit_sramc_sf +- +-ddrc_sf: +- cmp r1, #AT91_MEMCTRL_DDRSDR +- bne sdramc_sf ++.endm + +- /* +- * DDR Memory controller +- */ +- tst r0, #SRAMC_SELF_FRESH_ACTIVE +- beq ddrc_exit_sf ++.macro at91_backup_mode ++ /* Switch the master clock source to slow clock. */ ++ ldr pmc, .pmc_base ++ ldr tmp2, .mckr_offset ++ ldr tmp1, [pmc, tmp2] ++ bic tmp1, tmp1, #AT91_PMC_CSS ++ str tmp1, [pmc, tmp2] + +- /* LPDDR1 --> force DDR2 mode during self-refresh */ +- ldr r3, [r2, #AT91_DDRSDRC_MDR] +- str r3, .saved_sam9_mdr +- bic r3, r3, #~AT91_DDRSDRC_MD +- cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR +- ldreq r3, [r2, #AT91_DDRSDRC_MDR] +- biceq r3, r3, #AT91_DDRSDRC_MD +- orreq r3, r3, #AT91_DDRSDRC_MD_DDR2 +- streq r3, [r2, #AT91_DDRSDRC_MDR] ++ wait_mckrdy + +- /* Active DDRC self-refresh mode */ +- ldr r3, [r2, #AT91_DDRSDRC_LPR] +- str r3, .saved_sam9_lpr +- bic r3, r3, #AT91_DDRSDRC_LPCB +- orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH +- str r3, [r2, #AT91_DDRSDRC_LPR] ++ /*BUMEN*/ ++ ldr r0, .sfrbu ++ mov tmp1, #0x1 ++ str tmp1, [r0, #0x10] + +- /* If using the 2nd ddr controller */ +- ldr r2, .sramc1_base +- cmp r2, #0 +- beq no_2nd_ddrc ++ /* Shutdown */ ++ ldr r0, .shdwc ++ mov tmp1, #0xA5000000 ++ add tmp1, tmp1, #0x1 ++ str tmp1, [r0, #0] ++.endm + +- ldr r3, [r2, #AT91_DDRSDRC_MDR] +- str r3, .saved_sam9_mdr1 +- bic r3, r3, #~AT91_DDRSDRC_MD +- cmp r3, #AT91_DDRSDRC_MD_LOW_POWER_DDR +- ldreq r3, [r2, #AT91_DDRSDRC_MDR] +- biceq r3, r3, #AT91_DDRSDRC_MD +- orreq r3, r3, #AT91_DDRSDRC_MD_DDR2 +- streq r3, [r2, #AT91_DDRSDRC_MDR] ++/* ++ * void at91_suspend_sram_fn(struct at91_pm_data*) ++ * @input param: ++ * @r0: base address of struct at91_pm_data ++ */ ++/* at91_pm_suspend_in_sram must be 8-byte aligned per the requirements of fncpy() */ ++ .align 3 ++ENTRY(at91_pm_suspend_in_sram) ++ /* Save registers on stack */ ++ stmfd sp!, {r4 - r12, lr} + +- /* Active DDRC self-refresh mode */ +- ldr r3, [r2, #AT91_DDRSDRC_LPR] +- str r3, .saved_sam9_lpr1 +- bic r3, r3, #AT91_DDRSDRC_LPCB +- orr r3, r3, #AT91_DDRSDRC_LPCB_SELF_REFRESH +- str r3, [r2, #AT91_DDRSDRC_LPR] ++ /* Drain write buffer */ ++ mov tmp1, #0 ++ mcr p15, 0, tmp1, c7, c10, 4 + +-no_2nd_ddrc: +- b exit_sramc_sf ++ ldr tmp1, [r0, #PM_DATA_PMC] ++ str tmp1, .pmc_base ++ ldr tmp1, [r0, #PM_DATA_RAMC0] ++ str tmp1, .sramc_base ++ ldr tmp1, [r0, #PM_DATA_RAMC1] ++ str tmp1, .sramc1_base ++ ldr tmp1, [r0, #PM_DATA_MEMCTRL] ++ str tmp1, .memtype ++ ldr tmp1, [r0, #PM_DATA_MODE] ++ str tmp1, .pm_mode ++ ldr tmp1, [r0, #PM_DATA_PMC_MCKR_OFFSET] ++ str tmp1, .mckr_offset ++ ldr tmp1, [r0, #PM_DATA_PMC_VERSION] ++ str tmp1, .pmc_version ++ /* Both ldrne below are here to preload their address in the TLB */ ++ ldr tmp1, [r0, #PM_DATA_SHDWC] ++ str tmp1, .shdwc ++ cmp tmp1, #0 ++ ldrne tmp2, [tmp1, #0] ++ ldr tmp1, [r0, #PM_DATA_SFRBU] ++ str tmp1, .sfrbu ++ cmp tmp1, #0 ++ ldrne tmp2, [tmp1, #0x10] + +-ddrc_exit_sf: +- /* Restore MDR in case of LPDDR1 */ +- ldr r3, .saved_sam9_mdr +- str r3, [r2, #AT91_DDRSDRC_MDR] +- /* Restore LPR on AT91 with DDRAM */ +- ldr r3, .saved_sam9_lpr +- str r3, [r2, #AT91_DDRSDRC_LPR] ++ /* Active the self-refresh mode */ ++ at91_sramc_self_refresh_ena + +- /* If using the 2nd ddr controller */ +- ldr r2, .sramc1_base +- cmp r2, #0 +- ldrne r3, .saved_sam9_mdr1 +- strne r3, [r2, #AT91_DDRSDRC_MDR] +- ldrne r3, .saved_sam9_lpr1 +- strne r3, [r2, #AT91_DDRSDRC_LPR] ++ ldr r0, .pm_mode ++ cmp r0, #AT91_PM_STANDBY ++ beq standby ++ cmp r0, #AT91_PM_BACKUP ++ beq backup_mode + +- b exit_sramc_sf ++ at91_ulp_mode ++ b exit_suspend + +- /* +- * SDRAMC Memory controller +- */ +-sdramc_sf: +- tst r0, #SRAMC_SELF_FRESH_ACTIVE +- beq sdramc_exit_sf ++standby: ++ /* Wait for interrupt */ ++ ldr pmc, .pmc_base ++ at91_cpu_idle ++ b exit_suspend + +- /* Active SDRAMC self-refresh mode */ +- ldr r3, [r2, #AT91_SDRAMC_LPR] +- str r3, .saved_sam9_lpr +- bic r3, r3, #AT91_SDRAMC_LPCB +- orr r3, r3, #AT91_SDRAMC_LPCB_SELF_REFRESH +- str r3, [r2, #AT91_SDRAMC_LPR] ++backup_mode: ++ at91_backup_mode + +-sdramc_exit_sf: +- ldr r3, .saved_sam9_lpr +- str r3, [r2, #AT91_SDRAMC_LPR] ++exit_suspend: ++ /* Exit the self-refresh mode */ ++ at91_sramc_self_refresh_dis + +-exit_sramc_sf: +- mov pc, lr +-ENDPROC(at91_sramc_self_refresh) ++ /* Restore registers, and return */ ++ ldmfd sp!, {r4 - r12, pc} ++ENDPROC(at91_pm_suspend_in_sram) + + .pmc_base: + .word 0 +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/204-ARM-at91-pm-s-CONFIG_SOC_SAM9X60-CONFIG_HAVE_AT91_SA.patch b/target/linux/at91/patches-5.10/204-ARM-at91-pm-s-CONFIG_SOC_SAM9X60-CONFIG_HAVE_AT91_SA.patch new file mode 100644 index 0000000000..b9db3622e8 --- /dev/null +++ b/target/linux/at91/patches-5.10/204-ARM-at91-pm-s-CONFIG_SOC_SAM9X60-CONFIG_HAVE_AT91_SA.patch @@ -0,0 +1,41 @@ +From 673d2519e9028dafb678fac29a990740958bed3c Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 15 Apr 2021 13:49:54 +0300 +Subject: [PATCH 204/247] ARM: at91: pm: + s/CONFIG_SOC_SAM9X60/CONFIG_HAVE_AT91_SAM9X60_PLL/g + +Replace CONFIG_SOC_SAM9X60 with CONFIG_HAVE_AT91_SAM9X60_PLL as the +SAM9X60's PLL is also present on SAMA7G5. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210415105010.569620-9-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm_suspend.S | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S +index 960ad29cce51..1f63bbfad728 100644 +--- a/arch/arm/mach-at91/pm_suspend.S ++++ b/arch/arm/mach-at91/pm_suspend.S +@@ -422,7 +422,7 @@ sr_dis_exit: + cmp tmp1, #AT91_PMC_V1 + beq 1f + +-#ifdef CONFIG_SOC_SAM9X60 ++#ifdef CONFIG_HAVE_AT91_SAM9X60_PLL + /* Save PLLA settings. */ + ldr tmp2, [pmc, #AT91_PMC_PLL_UPDT] + bic tmp2, tmp2, #AT91_PMC_PLL_UPDT_ID +@@ -489,7 +489,7 @@ sr_dis_exit: + cmp tmp3, #AT91_PMC_V1 + beq 4f + +-#ifdef CONFIG_SOC_SAM9X60 ++#ifdef CONFIG_HAVE_AT91_SAM9X60_PLL + /* step 1. */ + ldr tmp1, [pmc, #AT91_PMC_PLL_UPDT] + bic tmp1, tmp1, #AT91_PMC_PLL_UPDT_ID +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/205-ARM-at91-pm-add-support-for-waiting-MCK1.4.patch b/target/linux/at91/patches-5.10/205-ARM-at91-pm-add-support-for-waiting-MCK1.4.patch new file mode 100644 index 0000000000..64c92ac05a --- /dev/null +++ b/target/linux/at91/patches-5.10/205-ARM-at91-pm-add-support-for-waiting-MCK1.4.patch @@ -0,0 +1,155 @@ +From 67face049c62cb37cf93da26b7fea037228d1d3d Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 15 Apr 2021 13:49:55 +0300 +Subject: [PATCH 205/247] ARM: at91: pm: add support for waiting MCK1..4 + +SAMA7G5 has 5 master clocks 0..4. MCK0 is controlled differently than +MCK 1..4. MCK 1..4 should also be saved/restored in the last phase of +suspend/resume. Thus, adapt wait_mckrdy to support also MCK1..4. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210415105010.569620-10-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm_suspend.S | 48 ++++++++++++++++++++++++--------- + 1 file changed, 35 insertions(+), 13 deletions(-) + +diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S +index 1f63bbfad728..7669b32d5257 100644 +--- a/arch/arm/mach-at91/pm_suspend.S ++++ b/arch/arm/mach-at91/pm_suspend.S +@@ -22,11 +22,23 @@ tmp3 .req r6 + + /* + * Wait until master clock is ready (after switching master clock source) ++ * ++ * @r_mckid: register holding master clock identifier ++ * ++ * Side effects: overwrites r7, r8 + */ +- .macro wait_mckrdy +-1: ldr tmp1, [pmc, #AT91_PMC_SR] +- tst tmp1, #AT91_PMC_MCKRDY +- beq 1b ++ .macro wait_mckrdy r_mckid ++#ifdef CONFIG_SOC_SAMA7 ++ cmp \r_mckid, #0 ++ beq 1f ++ mov r7, #AT91_PMC_MCKXRDY ++ b 2f ++#endif ++1: mov r7, #AT91_PMC_MCKRDY ++2: ldr r8, [pmc, #AT91_PMC_SR] ++ and r8, r7 ++ cmp r8, r7 ++ bne 2b + .endm + + /* +@@ -231,7 +243,9 @@ sr_dis_exit: + bic tmp1, tmp1, #AT91_PMC_PRES + orr tmp1, tmp1, #AT91_PMC_PRES_64 + str tmp1, [pmc, tmp3] +- wait_mckrdy ++ ++ mov tmp3, #0 ++ wait_mckrdy tmp3 + b 1f + + 0: +@@ -267,10 +281,13 @@ sr_dis_exit: + bne 5f + + /* Set lowest prescaler for fast resume. */ ++ ldr tmp3, .mckr_offset + ldr tmp1, [pmc, tmp3] + bic tmp1, tmp1, #AT91_PMC_PRES + str tmp1, [pmc, tmp3] +- wait_mckrdy ++ ++ mov tmp3, #0 ++ wait_mckrdy tmp3 + b 6f + + 5: /* Restore RC oscillator state */ +@@ -307,6 +324,7 @@ sr_dis_exit: + .macro at91_pm_ulp1_mode + ldr pmc, .pmc_base + ldr tmp2, .mckr_offset ++ mov tmp3, #0 + + /* Save RC oscillator state and check if it is enabled. */ + ldr tmp1, [pmc, #AT91_PMC_SR] +@@ -348,7 +366,7 @@ sr_dis_exit: + orr tmp1, tmp1, #AT91_PMC_CSS_MAIN + str tmp1, [pmc, tmp2] + +- wait_mckrdy ++ wait_mckrdy tmp3 + + /* Enter the ULP1 mode by set WAITMODE bit in CKGR_MOR */ + ldr tmp1, [pmc, #AT91_CKGR_MOR] +@@ -361,7 +379,7 @@ sr_dis_exit: + nop + nop + +- wait_mckrdy ++ wait_mckrdy tmp3 + + /* Enable the crystal oscillator */ + ldr tmp1, [pmc, #AT91_CKGR_MOR] +@@ -377,7 +395,7 @@ sr_dis_exit: + bic tmp1, tmp1, #AT91_PMC_CSS + str tmp1, [pmc, tmp2] + +- wait_mckrdy ++ wait_mckrdy tmp3 + + /* Switch main clock source to crystal oscillator */ + ldr tmp1, [pmc, #AT91_CKGR_MOR] +@@ -394,7 +412,7 @@ sr_dis_exit: + orr tmp1, tmp1, #AT91_PMC_CSS_MAIN + str tmp1, [pmc, tmp2] + +- wait_mckrdy ++ wait_mckrdy tmp3 + + /* Restore RC oscillator state */ + ldr tmp1, .saved_osc_status +@@ -573,10 +591,12 @@ sr_dis_exit: + save_mck: + str tmp1, [pmc, tmp2] + +- wait_mckrdy ++ mov tmp3, #0 ++ wait_mckrdy tmp3 + + at91_plla_disable + ++ ldr tmp3, .pm_mode + cmp tmp3, #AT91_PM_ULP1 + beq ulp1_mode + +@@ -599,7 +619,8 @@ ulp_exit: + ldr tmp2, .saved_mckr + str tmp2, [pmc, tmp1] + +- wait_mckrdy ++ mov tmp3, #0 ++ wait_mckrdy tmp3 + + .endm + +@@ -611,7 +632,8 @@ ulp_exit: + bic tmp1, tmp1, #AT91_PMC_CSS + str tmp1, [pmc, tmp2] + +- wait_mckrdy ++ mov tmp3, #0 ++ wait_mckrdy tmp3 + + /*BUMEN*/ + ldr r0, .sfrbu +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/206-ARM-at91-sfrbu-add-sfrbu-registers-definitions-for-s.patch b/target/linux/at91/patches-5.10/206-ARM-at91-sfrbu-add-sfrbu-registers-definitions-for-s.patch new file mode 100644 index 0000000000..cf7619d45e --- /dev/null +++ b/target/linux/at91/patches-5.10/206-ARM-at91-sfrbu-add-sfrbu-registers-definitions-for-s.patch @@ -0,0 +1,59 @@ +From c6b435625975d9a6daeffd81509a9877ddfb93b5 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 15 Apr 2021 13:49:56 +0300 +Subject: [PATCH 206/247] ARM: at91: sfrbu: add sfrbu registers definitions for + sama7g5 + +Add SFRBU registers definitions for SAMA7G5. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210415105010.569620-11-claudiu.beznea@microchip.com +--- + include/soc/at91/sama7-sfrbu.h | 34 ++++++++++++++++++++++++++++++++++ + 1 file changed, 34 insertions(+) + create mode 100644 include/soc/at91/sama7-sfrbu.h + +diff --git a/include/soc/at91/sama7-sfrbu.h b/include/soc/at91/sama7-sfrbu.h +new file mode 100644 +index 000000000000..76b740810d34 +--- /dev/null ++++ b/include/soc/at91/sama7-sfrbu.h +@@ -0,0 +1,34 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Microchip SAMA7 SFRBU registers offsets and bit definitions. ++ * ++ * Copyright (C) [2020] Microchip Technology Inc. and its subsidiaries ++ * ++ * Author: Claudu Beznea <claudiu.beznea@microchip.com> ++ */ ++ ++#ifndef __SAMA7_SFRBU_H__ ++#define __SAMA7_SFRBU_H__ ++ ++#ifdef CONFIG_SOC_SAMA7 ++ ++#define AT91_SFRBU_PSWBU (0x00) /* SFRBU Power Switch BU Control Register */ ++#define AT91_SFRBU_PSWBU_PSWKEY (0x4BD20C << 8) /* Specific value mandatory to allow writing of other register bits */ ++#define AT91_SFRBU_PSWBU_STATE (1 << 2) /* Power switch BU state */ ++#define AT91_SFRBU_PSWBU_SOFTSWITCH (1 << 1) /* Power switch BU source selection */ ++#define AT91_SFRBU_PSWBU_CTRL (1 << 0) /* Power switch BU control */ ++ ++#define AT91_SFRBU_25LDOCR (0x0C) /* SFRBU 2.5V LDO Control Register */ ++#define AT91_SFRBU_25LDOCR_LDOANAKEY (0x3B6E18 << 8) /* Specific value mandatory to allow writing of other register bits. */ ++#define AT91_SFRBU_25LDOCR_STATE (1 << 3) /* LDOANA Switch On/Off Control */ ++#define AT91_SFRBU_25LDOCR_LP (1 << 2) /* LDOANA Low-Power Mode Control */ ++#define AT91_SFRBU_PD_VALUE_MSK (0x3) ++#define AT91_SFRBU_25LDOCR_PD_VALUE(v) ((v) & AT91_SFRBU_PD_VALUE_MSK) /* LDOANA Pull-down value */ ++ ++#define AT91_FRBU_DDRPWR (0x10) /* SFRBU DDR Power Control Register */ ++#define AT91_FRBU_DDRPWR_STATE (1 << 0) /* DDR Power Mode State */ ++ ++#endif /* CONFIG_SOC_SAMA7 */ ++ ++#endif /* __SAMA7_SFRBU_H__ */ ++ +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/207-ARM-at91-ddr-add-registers-definitions-for-sama7g5-s.patch b/target/linux/at91/patches-5.10/207-ARM-at91-ddr-add-registers-definitions-for-sama7g5-s.patch new file mode 100644 index 0000000000..0414a28856 --- /dev/null +++ b/target/linux/at91/patches-5.10/207-ARM-at91-ddr-add-registers-definitions-for-sama7g5-s.patch @@ -0,0 +1,105 @@ +From 0005be9abfcddf9a29c6d07afe06caa41560d424 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 15 Apr 2021 13:49:57 +0300 +Subject: [PATCH 207/247] ARM: at91: ddr: add registers definitions for + sama7g5's ddr + +Add registers and bits definitions for SAMA7G5's UDDRC and DDR3PHY. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210415105010.569620-12-claudiu.beznea@microchip.com +--- + include/soc/at91/sama7-ddr.h | 80 ++++++++++++++++++++++++++++++++++++ + 1 file changed, 80 insertions(+) + create mode 100644 include/soc/at91/sama7-ddr.h + +diff --git a/include/soc/at91/sama7-ddr.h b/include/soc/at91/sama7-ddr.h +new file mode 100644 +index 000000000000..f6542584ca13 +--- /dev/null ++++ b/include/soc/at91/sama7-ddr.h +@@ -0,0 +1,80 @@ ++/* SPDX-License-Identifier: GPL-2.0-only */ ++/* ++ * Microchip SAMA7 UDDR Controller and DDR3 PHY Controller registers offsets ++ * and bit definitions. ++ * ++ * Copyright (C) [2020] Microchip Technology Inc. and its subsidiaries ++ * ++ * Author: Claudu Beznea <claudiu.beznea@microchip.com> ++ */ ++ ++#ifndef __SAMA7_DDR_H__ ++#define __SAMA7_DDR_H__ ++ ++#ifdef CONFIG_SOC_SAMA7 ++ ++/* DDR3PHY */ ++#define DDR3PHY_PIR (0x04) /* DDR3PHY PHY Initialization Register */ ++#define DDR3PHY_PIR_DLLBYP (1 << 17) /* DLL Bypass */ ++#define DDR3PHY_PIR_ITMSRST (1 << 4) /* Interface Timing Module Soft Reset */ ++#define DDR3PHY_PIR_DLLLOCK (1 << 2) /* DLL Lock */ ++#define DDR3PHY_PIR_DLLSRST (1 << 1) /* DLL Soft Rest */ ++#define DDR3PHY_PIR_INIT (1 << 0) /* Initialization Trigger */ ++ ++#define DDR3PHY_PGCR (0x08) /* DDR3PHY PHY General Configuration Register */ ++#define DDR3PHY_PGCR_CKDV1 (1 << 13) /* CK# Disable Value */ ++#define DDR3PHY_PGCR_CKDV0 (1 << 12) /* CK Disable Value */ ++ ++#define DDR3PHY_PGSR (0x0C) /* DDR3PHY PHY General Status Register */ ++#define DDR3PHY_PGSR_IDONE (1 << 0) /* Initialization Done */ ++ ++#define DDR3PHY_ACIOCR (0x24) /* DDR3PHY AC I/O Configuration Register */ ++#define DDR3PHY_ACIOCR_CSPDD_CS0 (1 << 18) /* CS#[0] Power Down Driver */ ++#define DDR3PHY_ACIOCR_CKPDD_CK0 (1 << 8) /* CK[0] Power Down Driver */ ++#define DDR3PHY_ACIORC_ACPDD (1 << 3) /* AC Power Down Driver */ ++ ++#define DDR3PHY_DXCCR (0x28) /* DDR3PHY DATX8 Common Configuration Register */ ++#define DDR3PHY_DXCCR_DXPDR (1 << 3) /* Data Power Down Receiver */ ++ ++#define DDR3PHY_DSGCR (0x2C) /* DDR3PHY DDR System General Configuration Register */ ++#define DDR3PHY_DSGCR_ODTPDD_ODT0 (1 << 20) /* ODT[0] Power Down Driver */ ++ ++#define DDR3PHY_ZQ0SR0 (0x188) /* ZQ status register 0 */ ++ ++/* UDDRC */ ++#define UDDRC_STAT (0x04) /* UDDRC Operating Mode Status Register */ ++#define UDDRC_STAT_SELFREF_TYPE_DIS (0x0 << 4) /* SDRAM is not in Self-refresh */ ++#define UDDRC_STAT_SELFREF_TYPE_PHY (0x1 << 4) /* SDRAM is in Self-refresh, which was caused by PHY Master Request */ ++#define UDDRC_STAT_SELFREF_TYPE_SW (0x2 << 4) /* SDRAM is in Self-refresh, which was not caused solely under Automatic Self-refresh control */ ++#define UDDRC_STAT_SELFREF_TYPE_AUTO (0x3 << 4) /* SDRAM is in Self-refresh, which was caused by Automatic Self-refresh only */ ++#define UDDRC_STAT_SELFREF_TYPE_MSK (0x3 << 4) /* Self-refresh type mask */ ++#define UDDRC_STAT_OPMODE_INIT (0x0 << 0) /* Init */ ++#define UDDRC_STAT_OPMODE_NORMAL (0x1 << 0) /* Normal */ ++#define UDDRC_STAT_OPMODE_PWRDOWN (0x2 << 0) /* Power-down */ ++#define UDDRC_STAT_OPMODE_SELF_REFRESH (0x3 << 0) /* Self-refresh */ ++#define UDDRC_STAT_OPMODE_MSK (0x7 << 0) /* Operating mode mask */ ++ ++#define UDDRC_PWRCTL (0x30) /* UDDRC Low Power Control Register */ ++#define UDDRC_PWRCTRL_SELFREF_SW (1 << 5) /* Software self-refresh */ ++ ++#define UDDRC_DFIMISC (0x1B0) /* UDDRC DFI Miscellaneous Control Register */ ++#define UDDRC_DFIMISC_DFI_INIT_COMPLETE_EN (1 << 0) /* PHY initialization complete enable signal */ ++ ++#define UDDRC_SWCTRL (0x320) /* UDDRC Software Register Programming Control Enable */ ++#define UDDRC_SWCTRL_SW_DONE (1 << 0) /* Enable quasi-dynamic register programming outside reset */ ++ ++#define UDDRC_SWSTAT (0x324) /* UDDRC Software Register Programming Control Status */ ++#define UDDRC_SWSTAT_SW_DONE_ACK (1 << 0) /* Register programming done */ ++ ++#define UDDRC_PSTAT (0x3FC) /* UDDRC Port Status Register */ ++#define UDDRC_PSTAT_ALL_PORTS (0x1F001F) /* Read + writes outstanding transactions on all ports */ ++ ++#define UDDRC_PCTRL_0 (0x490) /* UDDRC Port 0 Control Register */ ++#define UDDRC_PCTRL_1 (0x540) /* UDDRC Port 1 Control Register */ ++#define UDDRC_PCTRL_2 (0x5F0) /* UDDRC Port 2 Control Register */ ++#define UDDRC_PCTRL_3 (0x6A0) /* UDDRC Port 3 Control Register */ ++#define UDDRC_PCTRL_4 (0x750) /* UDDRC Port 4 Control Register */ ++ ++#endif /* CONFIG_SOC_SAMA7 */ ++ ++#endif /* __SAMA7_DDR_H__ */ +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/208-ARM-at91-pm-add-self-refresh-support-for-sama7g5.patch b/target/linux/at91/patches-5.10/208-ARM-at91-pm-add-self-refresh-support-for-sama7g5.patch new file mode 100644 index 0000000000..344b14c4d9 --- /dev/null +++ b/target/linux/at91/patches-5.10/208-ARM-at91-pm-add-self-refresh-support-for-sama7g5.patch @@ -0,0 +1,283 @@ +From 1bfd85d71703f80392a71043caf74f159bec97b8 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 15 Apr 2021 13:49:58 +0300 +Subject: [PATCH 208/247] ARM: at91: pm: add self-refresh support for sama7g5 + +Add self-refresh support for SAMA7G5. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210415105010.569620-13-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm.h | 2 + + arch/arm/mach-at91/pm_data-offsets.c | 2 + + arch/arm/mach-at91/pm_suspend.S | 199 +++++++++++++++++++++++++++ + 3 files changed, 203 insertions(+) + +diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h +index bfb260be371e..666474088d55 100644 +--- a/arch/arm/mach-at91/pm.h ++++ b/arch/arm/mach-at91/pm.h +@@ -12,6 +12,7 @@ + #include <linux/mfd/syscon/atmel-mc.h> + #include <soc/at91/at91sam9_ddrsdr.h> + #include <soc/at91/at91sam9_sdramc.h> ++#include <soc/at91/sama7-ddr.h> + + #define AT91_MEMCTRL_MC 0 + #define AT91_MEMCTRL_SDRAMC 1 +@@ -27,6 +28,7 @@ + struct at91_pm_data { + void __iomem *pmc; + void __iomem *ramc[2]; ++ void __iomem *ramc_phy; + unsigned long uhp_udp_mask; + unsigned int memctrl; + unsigned int mode; +diff --git a/arch/arm/mach-at91/pm_data-offsets.c b/arch/arm/mach-at91/pm_data-offsets.c +index 82089ff258c0..40bd4e8fe40a 100644 +--- a/arch/arm/mach-at91/pm_data-offsets.c ++++ b/arch/arm/mach-at91/pm_data-offsets.c +@@ -8,6 +8,8 @@ int main(void) + DEFINE(PM_DATA_PMC, offsetof(struct at91_pm_data, pmc)); + DEFINE(PM_DATA_RAMC0, offsetof(struct at91_pm_data, ramc[0])); + DEFINE(PM_DATA_RAMC1, offsetof(struct at91_pm_data, ramc[1])); ++ DEFINE(PM_DATA_RAMC_PHY, offsetof(struct at91_pm_data, ++ ramc_phy)); + DEFINE(PM_DATA_MEMCTRL, offsetof(struct at91_pm_data, memctrl)); + DEFINE(PM_DATA_MODE, offsetof(struct at91_pm_data, mode)); + DEFINE(PM_DATA_SHDWC, offsetof(struct at91_pm_data, shdwc)); +diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S +index 7669b32d5257..84418120ba67 100644 +--- a/arch/arm/mach-at91/pm_suspend.S ++++ b/arch/arm/mach-at91/pm_suspend.S +@@ -87,6 +87,200 @@ tmp3 .req r6 + + .arm + ++#ifdef CONFIG_SOC_SAMA7 ++/** ++ * Enable self-refresh ++ * ++ * Side effects: overwrites r2, r3, tmp1, tmp2, tmp3, r7 ++ */ ++.macro at91_sramc_self_refresh_ena ++ ldr r2, .sramc_base ++ ldr r3, .sramc_phy_base ++ ldr r7, .pm_mode ++ ++ dsb ++ ++ /* Disable all AXI ports. */ ++ ldr tmp1, [r2, #UDDRC_PCTRL_0] ++ bic tmp1, tmp1, #0x1 ++ str tmp1, [r2, #UDDRC_PCTRL_0] ++ ++ ldr tmp1, [r2, #UDDRC_PCTRL_1] ++ bic tmp1, tmp1, #0x1 ++ str tmp1, [r2, #UDDRC_PCTRL_1] ++ ++ ldr tmp1, [r2, #UDDRC_PCTRL_2] ++ bic tmp1, tmp1, #0x1 ++ str tmp1, [r2, #UDDRC_PCTRL_2] ++ ++ ldr tmp1, [r2, #UDDRC_PCTRL_3] ++ bic tmp1, tmp1, #0x1 ++ str tmp1, [r2, #UDDRC_PCTRL_3] ++ ++ ldr tmp1, [r2, #UDDRC_PCTRL_4] ++ bic tmp1, tmp1, #0x1 ++ str tmp1, [r2, #UDDRC_PCTRL_4] ++ ++sr_ena_1: ++ /* Wait for all ports to disable. */ ++ ldr tmp1, [r2, #UDDRC_PSTAT] ++ ldr tmp2, =UDDRC_PSTAT_ALL_PORTS ++ tst tmp1, tmp2 ++ bne sr_ena_1 ++ ++ /* Switch to self-refresh. */ ++ ldr tmp1, [r2, #UDDRC_PWRCTL] ++ orr tmp1, tmp1, #UDDRC_PWRCTRL_SELFREF_SW ++ str tmp1, [r2, #UDDRC_PWRCTL] ++ ++sr_ena_2: ++ /* Wait for self-refresh enter. */ ++ ldr tmp1, [r2, #UDDRC_STAT] ++ bic tmp1, tmp1, #~UDDRC_STAT_SELFREF_TYPE_MSK ++ cmp tmp1, #UDDRC_STAT_SELFREF_TYPE_SW ++ bne sr_ena_2 ++ ++ /* Put DDR PHY's DLL in bypass mode for non-backup modes. */ ++ cmp r7, #AT91_PM_BACKUP ++ beq sr_ena_3 ++ ldr tmp1, [r3, #DDR3PHY_PIR] ++ orr tmp1, tmp1, #DDR3PHY_PIR_DLLBYP ++ str tmp1, [r3, #DDR3PHY_PIR] ++ ++sr_ena_3: ++ /* Power down DDR PHY data receivers. */ ++ ldr tmp1, [r3, #DDR3PHY_DXCCR] ++ orr tmp1, tmp1, #DDR3PHY_DXCCR_DXPDR ++ str tmp1, [r3, #DDR3PHY_DXCCR] ++ ++ /* Power down ADDR/CMD IO. */ ++ ldr tmp1, [r3, #DDR3PHY_ACIOCR] ++ orr tmp1, tmp1, #DDR3PHY_ACIORC_ACPDD ++ orr tmp1, tmp1, #DDR3PHY_ACIOCR_CKPDD_CK0 ++ orr tmp1, tmp1, #DDR3PHY_ACIOCR_CSPDD_CS0 ++ str tmp1, [r3, #DDR3PHY_ACIOCR] ++ ++ /* Power down ODT. */ ++ ldr tmp1, [r3, #DDR3PHY_DSGCR] ++ orr tmp1, tmp1, #DDR3PHY_DSGCR_ODTPDD_ODT0 ++ str tmp1, [r3, #DDR3PHY_DSGCR] ++.endm ++ ++/** ++ * Disable self-refresh ++ * ++ * Side effects: overwrites r2, r3, tmp1, tmp2, tmp3 ++ */ ++.macro at91_sramc_self_refresh_dis ++ ldr r2, .sramc_base ++ ldr r3, .sramc_phy_base ++ ++ /* Power up DDR PHY data receivers. */ ++ ldr tmp1, [r3, #DDR3PHY_DXCCR] ++ bic tmp1, tmp1, #DDR3PHY_DXCCR_DXPDR ++ str tmp1, [r3, #DDR3PHY_DXCCR] ++ ++ /* Power up the output of CK and CS pins. */ ++ ldr tmp1, [r3, #DDR3PHY_ACIOCR] ++ bic tmp1, tmp1, #DDR3PHY_ACIORC_ACPDD ++ bic tmp1, tmp1, #DDR3PHY_ACIOCR_CKPDD_CK0 ++ bic tmp1, tmp1, #DDR3PHY_ACIOCR_CSPDD_CS0 ++ str tmp1, [r3, #DDR3PHY_ACIOCR] ++ ++ /* Power up ODT. */ ++ ldr tmp1, [r3, #DDR3PHY_DSGCR] ++ bic tmp1, tmp1, #DDR3PHY_DSGCR_ODTPDD_ODT0 ++ str tmp1, [r3, #DDR3PHY_DSGCR] ++ ++ /* Take DDR PHY's DLL out of bypass mode. */ ++ ldr tmp1, [r3, #DDR3PHY_PIR] ++ bic tmp1, tmp1, #DDR3PHY_PIR_DLLBYP ++ str tmp1, [r3, #DDR3PHY_PIR] ++ ++ /* Enable quasi-dynamic programming. */ ++ mov tmp1, #0 ++ str tmp1, [r2, #UDDRC_SWCTRL] ++ ++ /* De-assert SDRAM initialization. */ ++ ldr tmp1, [r2, #UDDRC_DFIMISC] ++ bic tmp1, tmp1, #UDDRC_DFIMISC_DFI_INIT_COMPLETE_EN ++ str tmp1, [r2, #UDDRC_DFIMISC] ++ ++ /* Quasi-dynamic programming done. */ ++ mov tmp1, #UDDRC_SWCTRL_SW_DONE ++ str tmp1, [r2, #UDDRC_SWCTRL] ++ ++sr_dis_1: ++ ldr tmp1, [r2, #UDDRC_SWSTAT] ++ tst tmp1, #UDDRC_SWSTAT_SW_DONE_ACK ++ beq sr_dis_1 ++ ++ /* DLL soft-reset + DLL lock wait + ITM reset */ ++ mov tmp1, #(DDR3PHY_PIR_INIT | DDR3PHY_PIR_DLLSRST | \ ++ DDR3PHY_PIR_DLLLOCK | DDR3PHY_PIR_ITMSRST) ++ str tmp1, [r3, #DDR3PHY_PIR] ++ ++sr_dis_4: ++ /* Wait for it. */ ++ ldr tmp1, [r3, #DDR3PHY_PGSR] ++ tst tmp1, #DDR3PHY_PGSR_IDONE ++ beq sr_dis_4 ++ ++ /* Enable quasi-dynamic programming. */ ++ mov tmp1, #0 ++ str tmp1, [r2, #UDDRC_SWCTRL] ++ ++ /* Assert PHY init complete enable signal. */ ++ ldr tmp1, [r2, #UDDRC_DFIMISC] ++ orr tmp1, tmp1, #UDDRC_DFIMISC_DFI_INIT_COMPLETE_EN ++ str tmp1, [r2, #UDDRC_DFIMISC] ++ ++ /* Programming is done. Set sw_done. */ ++ mov tmp1, #UDDRC_SWCTRL_SW_DONE ++ str tmp1, [r2, #UDDRC_SWCTRL] ++ ++sr_dis_5: ++ /* Wait for it. */ ++ ldr tmp1, [r2, #UDDRC_SWSTAT] ++ tst tmp1, #UDDRC_SWSTAT_SW_DONE_ACK ++ beq sr_dis_5 ++ ++ /* Trigger self-refresh exit. */ ++ ldr tmp1, [r2, #UDDRC_PWRCTL] ++ bic tmp1, tmp1, #UDDRC_PWRCTRL_SELFREF_SW ++ str tmp1, [r2, #UDDRC_PWRCTL] ++ ++sr_dis_6: ++ /* Wait for self-refresh exit done. */ ++ ldr tmp1, [r2, #UDDRC_STAT] ++ bic tmp1, tmp1, #~UDDRC_STAT_OPMODE_MSK ++ cmp tmp1, #UDDRC_STAT_OPMODE_NORMAL ++ bne sr_dis_6 ++ ++ /* Enable all AXI ports. */ ++ ldr tmp1, [r2, #UDDRC_PCTRL_0] ++ orr tmp1, tmp1, #0x1 ++ str tmp1, [r2, #UDDRC_PCTRL_0] ++ ++ ldr tmp1, [r2, #UDDRC_PCTRL_1] ++ orr tmp1, tmp1, #0x1 ++ str tmp1, [r2, #UDDRC_PCTRL_1] ++ ++ ldr tmp1, [r2, #UDDRC_PCTRL_2] ++ orr tmp1, tmp1, #0x1 ++ str tmp1, [r2, #UDDRC_PCTRL_2] ++ ++ ldr tmp1, [r2, #UDDRC_PCTRL_3] ++ orr tmp1, tmp1, #0x1 ++ str tmp1, [r2, #UDDRC_PCTRL_3] ++ ++ ldr tmp1, [r2, #UDDRC_PCTRL_4] ++ orr tmp1, tmp1, #0x1 ++ str tmp1, [r2, #UDDRC_PCTRL_4] ++ ++ dsb ++.endm ++#else + /** + * Enable self-refresh + * +@@ -228,6 +422,7 @@ sdramc_exit_sf: + + sr_dis_exit: + .endm ++#endif + + .macro at91_pm_ulp0_mode + ldr pmc, .pmc_base +@@ -668,6 +863,8 @@ ENTRY(at91_pm_suspend_in_sram) + str tmp1, .sramc_base + ldr tmp1, [r0, #PM_DATA_RAMC1] + str tmp1, .sramc1_base ++ ldr tmp1, [r0, #PM_DATA_RAMC_PHY] ++ str tmp1, .sramc_phy_base + ldr tmp1, [r0, #PM_DATA_MEMCTRL] + str tmp1, .memtype + ldr tmp1, [r0, #PM_DATA_MODE] +@@ -721,6 +918,8 @@ ENDPROC(at91_pm_suspend_in_sram) + .word 0 + .sramc1_base: + .word 0 ++.sramc_phy_base: ++ .word 0 + .shdwc: + .word 0 + .sfrbu: +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/209-ARM-at91-pm-add-support-for-MCK1.4-save-restore-for-.patch b/target/linux/at91/patches-5.10/209-ARM-at91-pm-add-support-for-MCK1.4-save-restore-for-.patch new file mode 100644 index 0000000000..96f7811603 --- /dev/null +++ b/target/linux/at91/patches-5.10/209-ARM-at91-pm-add-support-for-MCK1.4-save-restore-for-.patch @@ -0,0 +1,170 @@ +From 9ee7fd7aa956671727752dac6bd131cf511c1137 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 15 Apr 2021 13:49:59 +0300 +Subject: [PATCH 209/247] ARM: at91: pm: add support for MCK1..4 save/restore + for ulp modes + +Add support for MCK1..4 save restore for ULP modes. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210415105010.569620-14-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm_suspend.S | 126 ++++++++++++++++++++++++++++++++ + 1 file changed, 126 insertions(+) + +diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S +index 84418120ba67..8b0b8619ee8a 100644 +--- a/arch/arm/mach-at91/pm_suspend.S ++++ b/arch/arm/mach-at91/pm_suspend.S +@@ -765,7 +765,122 @@ sr_dis_exit: + 2: + .endm + ++/** ++ * at91_mckx_ps_enable: save MCK1..4 settings and switch it to main clock ++ * ++ * Side effects: overwrites tmp1, tmp2 ++ */ ++.macro at91_mckx_ps_enable ++#ifdef CONFIG_SOC_SAMA7 ++ ldr pmc, .pmc_base ++ ++ /* There are 4 MCKs we need to handle: MCK1..4 */ ++ mov tmp1, #1 ++e_loop: cmp tmp1, #5 ++ beq e_done ++ ++ /* Write MCK ID to retrieve the settings. */ ++ str tmp1, [pmc, #AT91_PMC_MCR_V2] ++ ldr tmp2, [pmc, #AT91_PMC_MCR_V2] ++ ++e_save_mck1: ++ cmp tmp1, #1 ++ bne e_save_mck2 ++ str tmp2, .saved_mck1 ++ b e_ps ++ ++e_save_mck2: ++ cmp tmp1, #2 ++ bne e_save_mck3 ++ str tmp2, .saved_mck2 ++ b e_ps ++ ++e_save_mck3: ++ cmp tmp1, #3 ++ bne e_save_mck4 ++ str tmp2, .saved_mck3 ++ b e_ps ++ ++e_save_mck4: ++ str tmp2, .saved_mck4 ++ ++e_ps: ++ /* Use CSS=MAINCK and DIV=1. */ ++ bic tmp2, tmp2, #AT91_PMC_MCR_V2_CSS ++ bic tmp2, tmp2, #AT91_PMC_MCR_V2_DIV ++ orr tmp2, tmp2, #AT91_PMC_MCR_V2_CSS_MAINCK ++ orr tmp2, tmp2, #AT91_PMC_MCR_V2_DIV1 ++ str tmp2, [pmc, #AT91_PMC_MCR_V2] ++ ++ wait_mckrdy tmp1 ++ ++ add tmp1, tmp1, #1 ++ b e_loop ++ ++e_done: ++#endif ++.endm ++ ++/** ++ * at91_mckx_ps_restore: restore MCK1..4 settings ++ * ++ * Side effects: overwrites tmp1, tmp2 ++ */ ++.macro at91_mckx_ps_restore ++#ifdef CONFIG_SOC_SAMA7 ++ ldr pmc, .pmc_base ++ ++ /* There are 4 MCKs we need to handle: MCK1..4 */ ++ mov tmp1, #1 ++r_loop: cmp tmp1, #5 ++ beq r_done ++ ++r_save_mck1: ++ cmp tmp1, #1 ++ bne r_save_mck2 ++ ldr tmp2, .saved_mck1 ++ b r_ps ++ ++r_save_mck2: ++ cmp tmp1, #2 ++ bne r_save_mck3 ++ ldr tmp2, .saved_mck2 ++ b r_ps ++ ++r_save_mck3: ++ cmp tmp1, #3 ++ bne r_save_mck4 ++ ldr tmp2, .saved_mck3 ++ b r_ps ++ ++r_save_mck4: ++ ldr tmp2, .saved_mck4 ++ ++r_ps: ++ /* Write MCK ID to retrieve the settings. */ ++ str tmp1, [pmc, #AT91_PMC_MCR_V2] ++ ldr tmp3, [pmc, #AT91_PMC_MCR_V2] ++ ++ /* We need to restore CSS and DIV. */ ++ bic tmp3, tmp3, #AT91_PMC_MCR_V2_CSS ++ bic tmp3, tmp3, #AT91_PMC_MCR_V2_DIV ++ orr tmp3, tmp3, tmp2 ++ bic tmp3, tmp3, #AT91_PMC_MCR_V2_ID_MSK ++ orr tmp3, tmp3, tmp1 ++ orr tmp3, tmp3, #AT91_PMC_MCR_V2_CMD ++ str tmp2, [pmc, #AT91_PMC_MCR_V2] ++ ++ wait_mckrdy tmp1 ++ ++ add tmp1, tmp1, #1 ++ b r_loop ++r_done: ++#endif ++.endm ++ + .macro at91_ulp_mode ++ at91_mckx_ps_enable ++ + ldr pmc, .pmc_base + ldr tmp2, .mckr_offset + ldr tmp3, .pm_mode +@@ -817,6 +932,7 @@ ulp_exit: + mov tmp3, #0 + wait_mckrdy tmp3 + ++ at91_mckx_ps_restore + .endm + + .macro at91_backup_mode +@@ -946,6 +1062,16 @@ ENDPROC(at91_pm_suspend_in_sram) + .word 0 + .saved_osc_status: + .word 0 ++#ifdef CONFIG_SOC_SAMA7 ++.saved_mck1: ++ .word 0 ++.saved_mck2: ++ .word 0 ++.saved_mck3: ++ .word 0 ++.saved_mck4: ++ .word 0 ++#endif + + ENTRY(at91_pm_suspend_in_sram_sz) + .word .-at91_pm_suspend_in_sram +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/210-ARM-at91-pm-add-support-for-2.5V-LDO-regulator-contr.patch b/target/linux/at91/patches-5.10/210-ARM-at91-pm-add-support-for-2.5V-LDO-regulator-contr.patch new file mode 100644 index 0000000000..48638fa75e --- /dev/null +++ b/target/linux/at91/patches-5.10/210-ARM-at91-pm-add-support-for-2.5V-LDO-regulator-contr.patch @@ -0,0 +1,86 @@ +From b2073cc043612bf95b115bd94103cfb2936f05bf Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 15 Apr 2021 13:50:00 +0300 +Subject: [PATCH 210/247] ARM: at91: pm: add support for 2.5V LDO regulator + control + +Add support to disable/enable 2.5V LDO regulator when entering/exiting +any ULP mode. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210415105010.569620-15-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm.h | 1 + + arch/arm/mach-at91/pm_suspend.S | 29 +++++++++++++++++++++++++++++ + 2 files changed, 30 insertions(+) + +diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h +index 666474088d55..53bdc9000e44 100644 +--- a/arch/arm/mach-at91/pm.h ++++ b/arch/arm/mach-at91/pm.h +@@ -13,6 +13,7 @@ + #include <soc/at91/at91sam9_ddrsdr.h> + #include <soc/at91/at91sam9_sdramc.h> + #include <soc/at91/sama7-ddr.h> ++#include <soc/at91/sama7-sfrbu.h> + + #define AT91_MEMCTRL_MC 0 + #define AT91_MEMCTRL_SDRAMC 1 +diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S +index 8b0b8619ee8a..9c9e08fd8300 100644 +--- a/arch/arm/mach-at91/pm_suspend.S ++++ b/arch/arm/mach-at91/pm_suspend.S +@@ -83,6 +83,29 @@ tmp3 .req r6 + + .endm + ++/** ++ * Set state for 2.5V low power regulator ++ * @ena: 0 - disable regulator ++ * 1 - enable regulator ++ * ++ * Side effects: overwrites r7, r8, r9, r10 ++ */ ++ .macro at91_2_5V_reg_set_low_power ena ++#ifdef CONFIG_SOC_SAMA7 ++ ldr r7, .sfrbu ++ mov r8, #\ena ++ ldr r9, [r7, #AT91_SFRBU_25LDOCR] ++ orr r9, r9, #AT91_SFRBU_25LDOCR_LP ++ cmp r8, #1 ++ beq lp_done_\ena ++ bic r9, r9, #AT91_SFRBU_25LDOCR_LP ++lp_done_\ena: ++ ldr r10, =AT91_SFRBU_25LDOCR_LDOANAKEY ++ orr r9, r9, r10 ++ str r9, [r7, #AT91_SFRBU_25LDOCR] ++#endif ++ .endm ++ + .text + + .arm +@@ -906,6 +929,9 @@ save_mck: + + at91_plla_disable + ++ /* Enable low power mode for 2.5V regulator. */ ++ at91_2_5V_reg_set_low_power 1 ++ + ldr tmp3, .pm_mode + cmp tmp3, #AT91_PM_ULP1 + beq ulp1_mode +@@ -918,6 +944,9 @@ ulp1_mode: + b ulp_exit + + ulp_exit: ++ /* Disable low power mode for 2.5V regulator. */ ++ at91_2_5V_reg_set_low_power 0 ++ + ldr pmc, .pmc_base + + at91_plla_enable +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/211-ARM-at91-pm-wait-for-ddr-power-mode-off.patch b/target/linux/at91/patches-5.10/211-ARM-at91-pm-wait-for-ddr-power-mode-off.patch new file mode 100644 index 0000000000..f94b479240 --- /dev/null +++ b/target/linux/at91/patches-5.10/211-ARM-at91-pm-wait-for-ddr-power-mode-off.patch @@ -0,0 +1,33 @@ +From 2b522a22243938dd7613e09c954172b1fa6217f5 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 15 Apr 2021 13:50:01 +0300 +Subject: [PATCH 211/247] ARM: at91: pm: wait for ddr power mode off + +Wait for DDR power mode off before shutting down the core. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210415105010.569620-16-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm_suspend.S | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S +index 9c9e08fd8300..7396e18dd7e5 100644 +--- a/arch/arm/mach-at91/pm_suspend.S ++++ b/arch/arm/mach-at91/pm_suspend.S +@@ -980,6 +980,11 @@ ulp_exit: + mov tmp1, #0x1 + str tmp1, [r0, #0x10] + ++ /* Wait for it. */ ++1: ldr tmp1, [r0, #0x10] ++ tst tmp1, #0x1 ++ beq 1b ++ + /* Shutdown */ + ldr r0, .shdwc + mov tmp1, #0xA5000000 +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/212-ARM-at91-pm-add-sama7g5-ddr-controller.patch b/target/linux/at91/patches-5.10/212-ARM-at91-pm-add-sama7g5-ddr-controller.patch new file mode 100644 index 0000000000..e85e55ccc6 --- /dev/null +++ b/target/linux/at91/patches-5.10/212-ARM-at91-pm-add-sama7g5-ddr-controller.patch @@ -0,0 +1,45 @@ +From 3f55310c00b8c478da1458704027036c1a414973 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 15 Apr 2021 13:50:03 +0300 +Subject: [PATCH 212/247] ARM: at91: pm: add sama7g5 ddr controller + +Add SAMA7G5 DDR controller to the list of DDR controller compatibles. +At the moment there is no standby support. Adapt the code for this. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210415105010.569620-18-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c +index 96f2be0a53cb..622d68724c3f 100644 +--- a/arch/arm/mach-at91/pm.c ++++ b/arch/arm/mach-at91/pm.c +@@ -548,6 +548,7 @@ static const struct of_device_id ramc_ids[] __initconst = { + { .compatible = "atmel,at91sam9260-sdramc", .data = &ramc_infos[1] }, + { .compatible = "atmel,at91sam9g45-ddramc", .data = &ramc_infos[2] }, + { .compatible = "atmel,sama5d3-ddramc", .data = &ramc_infos[3] }, ++ { .compatible = "microchip,sama7g5-uddrc", }, + { /*sentinel*/ } + }; + +@@ -569,9 +570,11 @@ static __init int at91_dt_ramc(void) + } + + ramc = of_id->data; +- if (!standby) +- standby = ramc->idle; +- soc_pm.data.memctrl = ramc->memctrl; ++ if (ramc) { ++ if (!standby) ++ standby = ramc->idle; ++ soc_pm.data.memctrl = ramc->memctrl; ++ } + + idx++; + } +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/213-ARM-at91-pm-add-sama7g5-ddr-phy-controller.patch b/target/linux/at91/patches-5.10/213-ARM-at91-pm-add-sama7g5-ddr-phy-controller.patch new file mode 100644 index 0000000000..c01c952620 --- /dev/null +++ b/target/linux/at91/patches-5.10/213-ARM-at91-pm-add-sama7g5-ddr-phy-controller.patch @@ -0,0 +1,99 @@ +From bbbbf16c44f34a2d563fa7d71de64ffe3b4b82dc Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 15 Apr 2021 13:50:04 +0300 +Subject: [PATCH 213/247] ARM: at91: pm: add sama7g5 ddr phy controller + +SAMA7G5 self-refresh procedure accesses also the DDR PHY registers. +Adapt the code so that the at91_dt_ramc() to look also for DDR PHYs, +in case it is mandatory. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210415105010.569620-19-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm.c | 27 +++++++++++++++++++++------ + 1 file changed, 21 insertions(+), 6 deletions(-) + +diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c +index 622d68724c3f..b047a1f2ddfb 100644 +--- a/arch/arm/mach-at91/pm.c ++++ b/arch/arm/mach-at91/pm.c +@@ -552,7 +552,12 @@ static const struct of_device_id ramc_ids[] __initconst = { + { /*sentinel*/ } + }; + +-static __init int at91_dt_ramc(void) ++static const struct of_device_id ramc_phy_ids[] __initconst = { ++ { .compatible = "microchip,sama7g5-ddr3phy", }, ++ { /* Sentinel. */ }, ++}; ++ ++static __init void at91_dt_ramc(bool phy_mandatory) + { + struct device_node *np; + const struct of_device_id *of_id; +@@ -585,6 +590,16 @@ static __init int at91_dt_ramc(void) + goto unmap_ramc; + } + ++ /* Lookup for DDR PHY node, if any. */ ++ for_each_matching_node_and_match(np, ramc_phy_ids, &of_id) { ++ soc_pm.data.ramc_phy = of_iomap(np, 0); ++ if (!soc_pm.data.ramc_phy) ++ panic(pr_fmt("unable to map ramc phy cpu registers\n")); ++ } ++ ++ if (phy_mandatory && !soc_pm.data.ramc_phy) ++ panic(pr_fmt("DDR PHY is mandatory!\n")); ++ + if (!standby) { + pr_warn("ramc no standby function available\n"); + return 0; +@@ -953,7 +968,7 @@ void __init at91rm9200_pm_init(void) + soc_pm.data.standby_mode = AT91_PM_STANDBY; + soc_pm.data.suspend_mode = AT91_PM_ULP0; + +- ret = at91_dt_ramc(); ++ ret = at91_dt_ramc(false); + if (ret) + return; + +@@ -980,7 +995,7 @@ void __init sam9x60_pm_init(void) + + at91_pm_modes_validate(modes, ARRAY_SIZE(modes)); + at91_pm_modes_init(iomaps, ARRAY_SIZE(iomaps)); +- ret = at91_dt_ramc(); ++ ret = at91_dt_ramc(false); + if (ret) + return; + +@@ -1005,7 +1020,7 @@ void __init at91sam9_pm_init(void) + soc_pm.data.standby_mode = AT91_PM_STANDBY; + soc_pm.data.suspend_mode = AT91_PM_ULP0; + +- ret = at91_dt_ramc(); ++ ret = at91_dt_ramc(false); + if (ret) + return; + +@@ -1023,7 +1038,7 @@ void __init sama5_pm_init(void) + return; + + at91_pm_modes_validate(modes, ARRAY_SIZE(modes)); +- ret = at91_dt_ramc(); ++ ret = at91_dt_ramc(false); + if (ret) + return; + +@@ -1048,7 +1063,7 @@ void __init sama5d2_pm_init(void) + + at91_pm_modes_validate(modes, ARRAY_SIZE(modes)); + at91_pm_modes_init(iomaps, ARRAY_SIZE(iomaps)); +- ret = at91_dt_ramc(); ++ ret = at91_dt_ramc(false); + if (ret) + return; + +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/214-ARM-at91-pm-save-ddr-phy-calibration-data-to-securam.patch b/target/linux/at91/patches-5.10/214-ARM-at91-pm-save-ddr-phy-calibration-data-to-securam.patch new file mode 100644 index 0000000000..f6306c8276 --- /dev/null +++ b/target/linux/at91/patches-5.10/214-ARM-at91-pm-save-ddr-phy-calibration-data-to-securam.patch @@ -0,0 +1,156 @@ +From b355bb98eae3e343969fc5a0203e0dab472a6acd Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 15 Apr 2021 13:50:05 +0300 +Subject: [PATCH 214/247] ARM: at91: pm: save ddr phy calibration data to + securam + +The resuming from backup mode is done with the help of bootloader. +The bootloader reconfigure the DDR controller and DDR PHY controller. +To speed-up the resuming process save the PHY calibration data into +SECURAM before suspending (securam is powered on backup mode). +This data will be later used by bootloader in DDR PHY reconfiguration +process. Also, in the process or recalibration the first 8 words of +the memory may get corrupted. To solve this, these 8 words are saved +in the securam and restored by bootloader in the process of PHY +configuration. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210415105010.569620-20-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm.c | 60 ++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 59 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c +index b047a1f2ddfb..fd3beaeec17d 100644 +--- a/arch/arm/mach-at91/pm.c ++++ b/arch/arm/mach-at91/pm.c +@@ -10,6 +10,7 @@ + #include <linux/io.h> + #include <linux/of_address.h> + #include <linux/of.h> ++#include <linux/of_fdt.h> + #include <linux/of_platform.h> + #include <linux/parser.h> + #include <linux/suspend.h> +@@ -27,18 +28,23 @@ + #include "generic.h" + #include "pm.h" + ++#define BACKUP_DDR_PHY_CALIBRATION (9) ++ + /** + * struct at91_pm_bu - AT91 power management backup unit data structure + * @suspended: true if suspended to backup mode + * @reserved: reserved + * @canary: canary data for memory checking after exit from backup mode + * @resume: resume API ++ * @ddr_phy_calibration: DDR PHY calibration data: ZQ0CR0, first 8 words ++ * of the memory + */ + struct at91_pm_bu { + int suspended; + unsigned long reserved; + phys_addr_t canary; + phys_addr_t resume; ++ unsigned long ddr_phy_calibration[BACKUP_DDR_PHY_CALIBRATION]; + }; + + /** +@@ -48,6 +54,7 @@ struct at91_pm_bu { + * @ws_ids: wakup sources of_device_id array + * @data: PM data to be used on last phase of suspend + * @bu: backup unit mapped data (for backup mode) ++ * @memcs: memory chip select + */ + struct at91_soc_pm { + int (*config_shdwc_ws)(void __iomem *shdwc, u32 *mode, u32 *polarity); +@@ -55,6 +62,7 @@ struct at91_soc_pm { + const struct of_device_id *ws_ids; + struct at91_pm_bu *bu; + struct at91_pm_data data; ++ void *memcs; + }; + + /** +@@ -316,6 +324,19 @@ extern u32 at91_pm_suspend_in_sram_sz; + + static int at91_suspend_finish(unsigned long val) + { ++ int i; ++ ++ if (soc_pm.data.mode == AT91_PM_BACKUP && soc_pm.data.ramc_phy) { ++ /* ++ * The 1st 8 words of memory might get corrupted in the process ++ * of DDR PHY recalibration; it is saved here in securam and it ++ * will be restored later, after recalibration, by bootloader ++ */ ++ for (i = 1; i < BACKUP_DDR_PHY_CALIBRATION; i++) ++ soc_pm.bu->ddr_phy_calibration[i] = ++ *((unsigned int *)soc_pm.memcs + (i - 1)); ++ } ++ + flush_cache_all(); + outer_disable(); + +@@ -688,12 +709,40 @@ static bool __init at91_is_pm_mode_active(int pm_mode) + soc_pm.data.suspend_mode == pm_mode); + } + ++static int __init at91_pm_backup_scan_memcs(unsigned long node, ++ const char *uname, int depth, ++ void *data) ++{ ++ const char *type; ++ const __be32 *reg; ++ int *located = data; ++ int size; ++ ++ /* Memory node already located. */ ++ if (*located) ++ return 0; ++ ++ type = of_get_flat_dt_prop(node, "device_type", NULL); ++ ++ /* We are scanning "memory" nodes only. */ ++ if (!type || strcmp(type, "memory")) ++ return 0; ++ ++ reg = of_get_flat_dt_prop(node, "reg", &size); ++ if (reg) { ++ soc_pm.memcs = __va((phys_addr_t)be32_to_cpu(*reg)); ++ *located = 1; ++ } ++ ++ return 0; ++} ++ + static int __init at91_pm_backup_init(void) + { + struct gen_pool *sram_pool; + struct device_node *np; + struct platform_device *pdev; +- int ret = -ENODEV; ++ int ret = -ENODEV, located = 0; + + if (!IS_ENABLED(CONFIG_SOC_SAMA5D2)) + return -EPERM; +@@ -728,6 +777,15 @@ static int __init at91_pm_backup_init(void) + soc_pm.bu->suspended = 0; + soc_pm.bu->canary = __pa_symbol(&canary); + soc_pm.bu->resume = __pa_symbol(cpu_resume); ++ if (soc_pm.data.ramc_phy) { ++ of_scan_flat_dt(at91_pm_backup_scan_memcs, &located); ++ if (!located) ++ goto securam_fail; ++ ++ /* DDR3PHY_ZQ0SR0 */ ++ soc_pm.bu->ddr_phy_calibration[0] = readl(soc_pm.data.ramc_phy + ++ 0x188); ++ } + + return 0; + +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/215-ARM-at91-pm-add-backup-mode-support-for-SAMA7G5.patch b/target/linux/at91/patches-5.10/215-ARM-at91-pm-add-backup-mode-support-for-SAMA7G5.patch new file mode 100644 index 0000000000..41c796b693 --- /dev/null +++ b/target/linux/at91/patches-5.10/215-ARM-at91-pm-add-backup-mode-support-for-SAMA7G5.patch @@ -0,0 +1,59 @@ +From 62be32b56ff31b2cd048a53fac40a165c5bc66cd Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 15 Apr 2021 13:50:06 +0300 +Subject: [PATCH 215/247] ARM: at91: pm: add backup mode support for SAMA7G5 + +Adapt at91_pm_backup_init() to work for SAMA7G5. Also, set the LPM pin +to shutdown controller. This will signal to PMIC that it needs to switch +to the state corresponding to backup mode. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210415105010.569620-21-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm.c | 3 ++- + arch/arm/mach-at91/pm_suspend.S | 7 +++++++ + 2 files changed, 9 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c +index fd3beaeec17d..653350eec9b6 100644 +--- a/arch/arm/mach-at91/pm.c ++++ b/arch/arm/mach-at91/pm.c +@@ -744,7 +744,8 @@ static int __init at91_pm_backup_init(void) + struct platform_device *pdev; + int ret = -ENODEV, located = 0; + +- if (!IS_ENABLED(CONFIG_SOC_SAMA5D2)) ++ if (!IS_ENABLED(CONFIG_SOC_SAMA5D2) && ++ !IS_ENABLED(CONFIG_SOC_SAMA7G5)) + return -EPERM; + + if (!at91_is_pm_mode_active(AT91_PM_BACKUP)) +diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S +index 7396e18dd7e5..cbd61a3bcab1 100644 +--- a/arch/arm/mach-at91/pm_suspend.S ++++ b/arch/arm/mach-at91/pm_suspend.S +@@ -106,6 +106,12 @@ lp_done_\ena: + #endif + .endm + ++ .macro at91_backup_set_lpm reg ++#ifdef CONFIG_SOC_SAMA7 ++ orr \reg, \reg, #0x200000 ++#endif ++ .endm ++ + .text + + .arm +@@ -989,6 +995,7 @@ ulp_exit: + ldr r0, .shdwc + mov tmp1, #0xA5000000 + add tmp1, tmp1, #0x1 ++ at91_backup_set_lpm tmp1 + str tmp1, [r0, #0] + .endm + +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/216-ARM-at91-pm-add-sama7g5-s-pmc.patch b/target/linux/at91/patches-5.10/216-ARM-at91-pm-add-sama7g5-s-pmc.patch new file mode 100644 index 0000000000..f52478aaf7 --- /dev/null +++ b/target/linux/at91/patches-5.10/216-ARM-at91-pm-add-sama7g5-s-pmc.patch @@ -0,0 +1,41 @@ +From e9855ac00e8d9a2c41cea42b4f38a2b0b010bef3 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 15 Apr 2021 13:50:07 +0300 +Subject: [PATCH 216/247] ARM: at91: pm: add sama7g5's pmc + +Add SAMA7G5's PMC to compatible list. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210415105010.569620-22-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c +index 653350eec9b6..687ce8582b4f 100644 +--- a/arch/arm/mach-at91/pm.c ++++ b/arch/arm/mach-at91/pm.c +@@ -912,6 +912,11 @@ static const struct pmc_info pmc_infos[] __initconst = { + .mckr = 0x28, + .version = AT91_PMC_V2, + }, ++ { ++ .mckr = 0x28, ++ .version = AT91_PMC_V2, ++ }, ++ + }; + + static const struct of_device_id atmel_pmc_ids[] __initconst = { +@@ -927,6 +932,7 @@ static const struct of_device_id atmel_pmc_ids[] __initconst = { + { .compatible = "atmel,sama5d4-pmc", .data = &pmc_infos[1] }, + { .compatible = "atmel,sama5d2-pmc", .data = &pmc_infos[1] }, + { .compatible = "microchip,sam9x60-pmc", .data = &pmc_infos[4] }, ++ { .compatible = "microchip,sama7g5-pmc", .data = &pmc_infos[5] }, + { /* sentinel */ }, + }; + +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/217-ARM-at91-sama7-introduce-sama7-SoC-family.patch b/target/linux/at91/patches-5.10/217-ARM-at91-sama7-introduce-sama7-SoC-family.patch new file mode 100644 index 0000000000..de38988237 --- /dev/null +++ b/target/linux/at91/patches-5.10/217-ARM-at91-sama7-introduce-sama7-SoC-family.patch @@ -0,0 +1,71 @@ +From dea645bce478cc72a2bf2413ec873927d1471442 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Thu, 15 Apr 2021 13:50:08 +0300 +Subject: [PATCH 217/247] ARM: at91: sama7: introduce sama7 SoC family + +Introduce new family of SoCs, sama7, and first SoC, sama7g5. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +[claudiu.beznea@microchip.com: keep only the sama7_dt] +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210415105010.569620-23-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/Makefile | 1 + + arch/arm/mach-at91/sama7.c | 32 ++++++++++++++++++++++++++++++++ + 2 files changed, 33 insertions(+) + create mode 100644 arch/arm/mach-at91/sama7.c + +diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile +index f565490f1b70..522b680b6446 100644 +--- a/arch/arm/mach-at91/Makefile ++++ b/arch/arm/mach-at91/Makefile +@@ -8,6 +8,7 @@ obj-$(CONFIG_SOC_AT91RM9200) += at91rm9200.o + obj-$(CONFIG_SOC_AT91SAM9) += at91sam9.o + obj-$(CONFIG_SOC_SAM9X60) += sam9x60.o + obj-$(CONFIG_SOC_SAMA5) += sama5.o ++obj-$(CONFIG_SOC_SAMA7) += sama7.o + obj-$(CONFIG_SOC_SAMV7) += samv7.o + + # Power Management +diff --git a/arch/arm/mach-at91/sama7.c b/arch/arm/mach-at91/sama7.c +new file mode 100644 +index 000000000000..19d7bcbc97f1 +--- /dev/null ++++ b/arch/arm/mach-at91/sama7.c +@@ -0,0 +1,32 @@ ++// SPDX-License-Identifier: GPL-2.0-or-later ++/* ++ * Setup code for SAMA7 ++ * ++ * Copyright (C) 2021 Microchip Technology, Inc. and its subsidiaries ++ * ++ */ ++ ++#include <linux/of.h> ++#include <linux/of_platform.h> ++ ++#include <asm/mach/arch.h> ++#include <asm/system_misc.h> ++ ++#include "generic.h" ++ ++static void __init sama7_dt_device_init(void) ++{ ++ of_platform_default_populate(NULL, NULL, NULL); ++} ++ ++static const char *const sama7_dt_board_compat[] __initconst = { ++ "microchip,sama7", ++ NULL ++}; ++ ++DT_MACHINE_START(sama7_dt, "Microchip SAMA7") ++ /* Maintainer: Microchip */ ++ .init_machine = sama7_dt_device_init, ++ .dt_compat = sama7_dt_board_compat, ++MACHINE_END ++ +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/218-ARM-at91-pm-add-pm-support-for-SAMA7G5.patch b/target/linux/at91/patches-5.10/218-ARM-at91-pm-add-pm-support-for-SAMA7G5.patch new file mode 100644 index 0000000000..c6dc471346 --- /dev/null +++ b/target/linux/at91/patches-5.10/218-ARM-at91-pm-add-pm-support-for-SAMA7G5.patch @@ -0,0 +1,105 @@ +From aba3984dc7a405d20b83bff603d23719d0e26bc7 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 15 Apr 2021 13:50:09 +0300 +Subject: [PATCH 218/247] ARM: at91: pm: add pm support for SAMA7G5 + +Add support for SAMA7G5 power management modes: standby, ulp0, ulp1, backup. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210415105010.569620-24-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/generic.h | 2 ++ + arch/arm/mach-at91/pm.c | 37 ++++++++++++++++++++++++++++++++++++ + arch/arm/mach-at91/sama7.c | 1 + + 3 files changed, 40 insertions(+) + +diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h +index 0a4cdcb4985b..0c3960a8b3eb 100644 +--- a/arch/arm/mach-at91/generic.h ++++ b/arch/arm/mach-at91/generic.h +@@ -14,12 +14,14 @@ extern void __init at91sam9_pm_init(void); + extern void __init sam9x60_pm_init(void); + extern void __init sama5_pm_init(void); + extern void __init sama5d2_pm_init(void); ++extern void __init sama7_pm_init(void); + #else + static inline void __init at91rm9200_pm_init(void) { } + static inline void __init at91sam9_pm_init(void) { } + static inline void __init sam9x60_pm_init(void) { } + static inline void __init sama5_pm_init(void) { } + static inline void __init sama5d2_pm_init(void) { } ++static inline void __init sama7_pm_init(void) { } + #endif + + #endif /* _AT91_GENERIC_H */ +diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c +index 687ce8582b4f..9c8c998cf9f4 100644 +--- a/arch/arm/mach-at91/pm.c ++++ b/arch/arm/mach-at91/pm.c +@@ -152,6 +152,17 @@ static const struct of_device_id sam9x60_ws_ids[] = { + { /* sentinel */ } + }; + ++static const struct of_device_id sama7g5_ws_ids[] = { ++ { .compatible = "atmel,at91sam9x5-rtc", .data = &ws_info[1] }, ++ { .compatible = "microchip,sama7g5-ohci", .data = &ws_info[2] }, ++ { .compatible = "usb-ohci", .data = &ws_info[2] }, ++ { .compatible = "atmel,at91sam9g45-ehci", .data = &ws_info[2] }, ++ { .compatible = "usb-ehci", .data = &ws_info[2] }, ++ { .compatible = "microchip,sama7g5-sdhci", .data = &ws_info[3] }, ++ { .compatible = "atmel,at91sam9260-rtt", .data = &ws_info[4] }, ++ { /* sentinel */ } ++}; ++ + static int at91_pm_config_ws(unsigned int pm_mode, bool set) + { + const struct wakeup_source_info *wsi; +@@ -1139,6 +1150,32 @@ void __init sama5d2_pm_init(void) + soc_pm.config_pmc_ws = at91_sama5d2_config_pmc_ws; + } + ++void __init sama7_pm_init(void) ++{ ++ static const int modes[] __initconst = { ++ AT91_PM_STANDBY, AT91_PM_ULP0, AT91_PM_ULP1, AT91_PM_BACKUP, ++ }; ++ static const u32 iomaps[] __initconst = { ++ [AT91_PM_ULP0] = AT91_PM_IOMAP(SFRBU), ++ [AT91_PM_ULP1] = AT91_PM_IOMAP(SFRBU) | ++ AT91_PM_IOMAP(SHDWC), ++ [AT91_PM_BACKUP] = AT91_PM_IOMAP(SFRBU) | ++ AT91_PM_IOMAP(SHDWC), ++ }; ++ ++ if (!IS_ENABLED(CONFIG_SOC_SAMA7)) ++ return; ++ ++ at91_pm_modes_validate(modes, ARRAY_SIZE(modes)); ++ ++ at91_dt_ramc(true); ++ at91_pm_modes_init(iomaps, ARRAY_SIZE(iomaps)); ++ at91_pm_init(NULL); ++ ++ soc_pm.ws_ids = sama7g5_ws_ids; ++ soc_pm.config_pmc_ws = at91_sam9x60_config_pmc_ws; ++} ++ + static int __init at91_pm_modes_select(char *str) + { + char *s; +diff --git a/arch/arm/mach-at91/sama7.c b/arch/arm/mach-at91/sama7.c +index 19d7bcbc97f1..bd43733ede18 100644 +--- a/arch/arm/mach-at91/sama7.c ++++ b/arch/arm/mach-at91/sama7.c +@@ -17,6 +17,7 @@ + static void __init sama7_dt_device_init(void) + { + of_platform_default_populate(NULL, NULL, NULL); ++ sama7_pm_init(); + } + + static const char *const sama7_dt_board_compat[] __initconst = { +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/219-ARM-at91-pm-add-sama7g5-shdwc.patch b/target/linux/at91/patches-5.10/219-ARM-at91-pm-add-sama7g5-shdwc.patch new file mode 100644 index 0000000000..ac62f053e6 --- /dev/null +++ b/target/linux/at91/patches-5.10/219-ARM-at91-pm-add-sama7g5-shdwc.patch @@ -0,0 +1,29 @@ +From 84ff37cc98e6aaefe27d6edd5e3ced2be99d9833 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 15 Apr 2021 13:50:10 +0300 +Subject: [PATCH 219/247] ARM: at91: pm: add sama7g5 shdwc + +Add SAMA7G5 SHDWC. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210415105010.569620-25-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c +index 9c8c998cf9f4..a07e14d89ba4 100644 +--- a/arch/arm/mach-at91/pm.c ++++ b/arch/arm/mach-at91/pm.c +@@ -809,6 +809,7 @@ static int __init at91_pm_backup_init(void) + static const struct of_device_id atmel_shdwc_ids[] = { + { .compatible = "atmel,sama5d2-shdwc" }, + { .compatible = "microchip,sam9x60-shdwc" }, ++ { .compatible = "microchip,sama7g5-shdwc" }, + { /* sentinel. */ } + }; + +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/220-ARM-configs-at91-add-defconfig-for-sama7-family-of-S.patch b/target/linux/at91/patches-5.10/220-ARM-configs-at91-add-defconfig-for-sama7-family-of-S.patch new file mode 100644 index 0000000000..80a8d08d01 --- /dev/null +++ b/target/linux/at91/patches-5.10/220-ARM-configs-at91-add-defconfig-for-sama7-family-of-S.patch @@ -0,0 +1,239 @@ +From 2223a85aed2d892bd7c13053f27e777c743e5332 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Mon, 28 Jun 2021 15:04:51 +0300 +Subject: [PATCH 220/247] ARM: configs: at91: add defconfig for sama7 family of + SoCs + +Add defconfig for sama7 SoC family. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +[claudiu.beznea@microchip.com: add clocks, ethernet, timers, power] +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +[codrin.ciubotariu@microchip.com: add audio] +Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +[nicolas.ferre@microchip.com: atags not set, mtd tests, spi gpio] +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210628120452.74408-3-eugen.hristev@microchip.com +--- + arch/arm/configs/sama7_defconfig | 209 +++++++++++++++++++++++++++++++ + 1 file changed, 209 insertions(+) + create mode 100644 arch/arm/configs/sama7_defconfig + +diff --git a/arch/arm/configs/sama7_defconfig b/arch/arm/configs/sama7_defconfig +new file mode 100644 +index 000000000000..938aae4bd80b +--- /dev/null ++++ b/arch/arm/configs/sama7_defconfig +@@ -0,0 +1,209 @@ ++# CONFIG_LOCALVERSION_AUTO is not set ++# CONFIG_SWAP is not set ++CONFIG_SYSVIPC=y ++CONFIG_NO_HZ_IDLE=y ++CONFIG_HIGH_RES_TIMERS=y ++CONFIG_LOG_BUF_SHIFT=16 ++CONFIG_CGROUPS=y ++CONFIG_CGROUP_DEBUG=y ++CONFIG_NAMESPACES=y ++CONFIG_SYSFS_DEPRECATED=y ++CONFIG_SYSFS_DEPRECATED_V2=y ++CONFIG_BLK_DEV_INITRD=y ++# CONFIG_FHANDLE is not set ++# CONFIG_IO_URING is not set ++CONFIG_KALLSYMS_ALL=y ++CONFIG_EMBEDDED=y ++# CONFIG_VM_EVENT_COUNTERS is not set ++CONFIG_SLAB=y ++CONFIG_ARCH_AT91=y ++CONFIG_SOC_SAMA7G5=y ++CONFIG_ATMEL_CLOCKSOURCE_TCB=y ++# CONFIG_CACHE_L2X0 is not set ++# CONFIG_ARM_PATCH_IDIV is not set ++# CONFIG_CPU_SW_DOMAIN_PAN is not set ++CONFIG_FORCE_MAX_ZONEORDER=15 ++CONFIG_UACCESS_WITH_MEMCPY=y ++# CONFIG_ATAGS is not set ++CONFIG_CMDLINE="console=ttyS0,115200 earlyprintk ignore_loglevel" ++CONFIG_VFP=y ++CONFIG_NEON=y ++CONFIG_KERNEL_MODE_NEON=y ++CONFIG_MODULES=y ++CONFIG_MODULE_FORCE_LOAD=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_MODULE_FORCE_UNLOAD=y ++# CONFIG_BLK_DEV_BSG is not set ++CONFIG_PARTITION_ADVANCED=y ++# CONFIG_EFI_PARTITION is not set ++# CONFIG_COREDUMP is not set ++# CONFIG_COMPACTION is not set ++CONFIG_CMA=y ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++# CONFIG_INET_DIAG is not set ++CONFIG_IPV6_SIT_6RD=y ++CONFIG_BRIDGE=m ++CONFIG_BRIDGE_VLAN_FILTERING=y ++CONFIG_NET_DSA=m ++CONFIG_VLAN_8021Q=m ++CONFIG_CAN=y ++CONFIG_CAN_M_CAN=y ++CONFIG_CAN_M_CAN_PLATFORM=y ++CONFIG_BT=y ++CONFIG_BT_RFCOMM=y ++CONFIG_BT_RFCOMM_TTY=y ++CONFIG_BT_BNEP=y ++CONFIG_BT_BNEP_MC_FILTER=y ++CONFIG_BT_BNEP_PROTO_FILTER=y ++CONFIG_BT_HIDP=y ++CONFIG_BT_HCIBTUSB=y ++CONFIG_BT_HCIUART=y ++CONFIG_BT_HCIUART_H4=y ++CONFIG_BT_HCIVHCI=y ++CONFIG_CFG80211=m ++# CONFIG_CFG80211_DEFAULT_PS is not set ++CONFIG_CFG80211_DEBUGFS=y ++CONFIG_CFG80211_WEXT=y ++CONFIG_MAC80211=m ++CONFIG_MAC80211_LEDS=y ++CONFIG_RFKILL=y ++CONFIG_RFKILL_INPUT=y ++CONFIG_PCCARD=y ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++# CONFIG_STANDALONE is not set ++# CONFIG_PREVENT_FIRMWARE_BUILD is not set ++# CONFIG_ALLOW_DEV_COREDUMP is not set ++CONFIG_MTD=y ++CONFIG_MTD_TESTS=m ++CONFIG_MTD_CMDLINE_PARTS=y ++CONFIG_BLK_DEV_LOOP=y ++CONFIG_BLK_DEV_RAM=y ++CONFIG_BLK_DEV_RAM_COUNT=1 ++CONFIG_BLK_DEV_RAM_SIZE=8192 ++CONFIG_EEPROM_AT24=y ++CONFIG_SCSI=y ++CONFIG_BLK_DEV_SD=y ++CONFIG_NETDEVICES=y ++CONFIG_MACB=y ++CONFIG_MICREL_PHY=y ++CONFIG_INPUT_EVDEV=y ++CONFIG_KEYBOARD_GPIO=y ++# CONFIG_INPUT_MOUSE is not set ++CONFIG_LEGACY_PTY_COUNT=4 ++CONFIG_SERIAL_ATMEL=y ++CONFIG_SERIAL_ATMEL_CONSOLE=y ++CONFIG_HW_RANDOM=y ++CONFIG_I2C=y ++CONFIG_I2C_CHARDEV=y ++CONFIG_I2C_AT91=y ++CONFIG_SPI=y ++CONFIG_SPI_MEM=y ++CONFIG_SPI_ATMEL=y ++CONFIG_SPI_GPIO=y ++CONFIG_PINCTRL_AT91=y ++CONFIG_PINCTRL_AT91PIO4=y ++CONFIG_GPIO_SYSFS=y ++CONFIG_POWER_RESET=y ++CONFIG_POWER_RESET_AT91_RESET=y ++CONFIG_POWER_RESET_AT91_SAMA5D2_SHDWC=y ++# CONFIG_HWMON is not set ++CONFIG_WATCHDOG=y ++CONFIG_SAMA5D4_WATCHDOG=y ++CONFIG_MFD_ATMEL_FLEXCOM=y ++CONFIG_REGULATOR=y ++CONFIG_REGULATOR_FIXED_VOLTAGE=y ++CONFIG_REGULATOR_MCP16502=y ++CONFIG_MEDIA_SUPPORT=y ++CONFIG_MEDIA_SUPPORT_FILTER=y ++# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set ++CONFIG_MEDIA_CAMERA_SUPPORT=y ++CONFIG_MEDIA_PLATFORM_SUPPORT=y ++CONFIG_V4L_PLATFORM_DRIVERS=y ++CONFIG_VIDEO_IMX219=m ++CONFIG_VIDEO_IMX274=m ++CONFIG_VIDEO_OV5647=m ++CONFIG_SOUND=y ++CONFIG_SND=y ++CONFIG_SND_SOC=y ++CONFIG_SND_ATMEL_SOC=y ++CONFIG_SND_SOC_MIKROE_PROTO=m ++CONFIG_SND_MCHP_SOC_I2S_MCC=y ++CONFIG_SND_MCHP_SOC_SPDIFTX=y ++CONFIG_SND_MCHP_SOC_SPDIFRX=y ++CONFIG_SND_SOC_PCM5102A=y ++CONFIG_SND_SOC_SPDIF=y ++CONFIG_SND_SIMPLE_CARD=y ++CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_DYNAMIC_MINORS=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_OHCI_HCD=y ++CONFIG_USB_STORAGE=y ++CONFIG_USB_UAS=y ++CONFIG_USB_GADGET=y ++CONFIG_U_SERIAL_CONSOLE=y ++CONFIG_USB_ATMEL_USBA=m ++CONFIG_USB_CONFIGFS=y ++CONFIG_USB_CONFIGFS_ACM=y ++CONFIG_USB_CONFIGFS_MASS_STORAGE=y ++CONFIG_USB_CONFIGFS_F_UVC=y ++CONFIG_USB_G_SERIAL=m ++CONFIG_MMC=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++CONFIG_MMC_SDHCI_OF_AT91=y ++CONFIG_NEW_LEDS=y ++CONFIG_LEDS_CLASS=y ++CONFIG_LEDS_GPIO=y ++CONFIG_LEDS_TRIGGER_HEARTBEAT=y ++CONFIG_RTC_CLASS=y ++# CONFIG_RTC_NVMEM is not set ++CONFIG_RTC_DRV_AT91RM9200=y ++CONFIG_RTC_DRV_AT91SAM9=y ++CONFIG_DMADEVICES=y ++CONFIG_AT_XDMAC=y ++CONFIG_DMATEST=y ++CONFIG_STAGING=y ++CONFIG_MICROCHIP_PIT64B=y ++# CONFIG_IOMMU_SUPPORT is not set ++# CONFIG_ATMEL_EBI is not set ++CONFIG_IIO=y ++CONFIG_IIO_SW_TRIGGER=y ++CONFIG_AT91_SAMA5D2_ADC=y ++CONFIG_PWM=y ++CONFIG_PWM_ATMEL=y ++CONFIG_EXT2_FS=y ++CONFIG_EXT3_FS=y ++CONFIG_FANOTIFY=y ++CONFIG_VFAT_FS=y ++CONFIG_TMPFS=y ++CONFIG_NFS_FS=y ++CONFIG_ROOT_NFS=y ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_CODEPAGE_850=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_NLS_UTF8=y ++CONFIG_LSM="N" ++CONFIG_CRYPTO_DEFLATE=y ++CONFIG_CRYPTO_LZO=y ++# CONFIG_CRYPTO_HW is not set ++CONFIG_CRC_CCITT=y ++CONFIG_CRC_ITU_T=y ++CONFIG_DMA_CMA=y ++CONFIG_CMA_SIZE_MBYTES=32 ++CONFIG_CMA_ALIGNMENT=9 ++# CONFIG_SECTION_MISMATCH_WARN_ONLY is not set ++CONFIG_DEBUG_FS=y ++# CONFIG_DEBUG_MISC is not set ++# CONFIG_SCHED_DEBUG is not set ++CONFIG_STACKTRACE=y ++# CONFIG_FTRACE is not set ++CONFIG_DEBUG_USER=y ++# CONFIG_RUNTIME_TESTING_MENU is not set +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/221-ARM-multi_v7_defconfig-add-sama7g5-SoC.patch b/target/linux/at91/patches-5.10/221-ARM-multi_v7_defconfig-add-sama7g5-SoC.patch new file mode 100644 index 0000000000..5d8ab047fd --- /dev/null +++ b/target/linux/at91/patches-5.10/221-ARM-multi_v7_defconfig-add-sama7g5-SoC.patch @@ -0,0 +1,38 @@ +From a62536054548e85da84ed835dc87baa8e5e99b41 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Mon, 28 Jun 2021 15:04:52 +0300 +Subject: [PATCH 221/247] ARM: multi_v7_defconfig: add sama7g5 SoC + +Add the Microchip SAMA7G5 ARM v7 Cortex-A7 based SoC to multi_v7_defconfig. +Also add it's clock timer, the PIT64B. + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210628120452.74408-4-eugen.hristev@microchip.com +--- + arch/arm/configs/multi_v7_defconfig | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig +index a611b0c1e540..4974f9bf163f 100644 +--- a/arch/arm/configs/multi_v7_defconfig ++++ b/arch/arm/configs/multi_v7_defconfig +@@ -15,6 +15,7 @@ CONFIG_ARCH_AT91=y + CONFIG_SOC_SAMA5D2=y + CONFIG_SOC_SAMA5D3=y + CONFIG_SOC_SAMA5D4=y ++CONFIG_SOC_SAMA7G5=y + CONFIG_ARCH_BCM=y + CONFIG_ARCH_BCM_CYGNUS=y + CONFIG_ARCH_BCM_HR2=y +@@ -967,6 +968,7 @@ CONFIG_APQ_MMCC_8084=y + CONFIG_MSM_GCC_8660=y + CONFIG_MSM_MMCC_8960=y + CONFIG_MSM_MMCC_8974=y ++CONFIG_MICROCHIP_PIT64B=y + CONFIG_BCM2835_MBOX=y + CONFIG_ROCKCHIP_IOMMU=y + CONFIG_TEGRA_IOMMU_GART=y +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/222-ARM-dts-at91-add-sama7g5-SoC-DT-and-sama7g5-ek.patch b/target/linux/at91/patches-5.10/222-ARM-dts-at91-add-sama7g5-SoC-DT-and-sama7g5-ek.patch new file mode 100644 index 0000000000..ec2b25897f --- /dev/null +++ b/target/linux/at91/patches-5.10/222-ARM-dts-at91-add-sama7g5-SoC-DT-and-sama7g5-ek.patch @@ -0,0 +1,2168 @@ +From 969b39d51b7df0869cca9983b06cefb59dae72b0 Mon Sep 17 00:00:00 2001 +From: Eugen Hristev <eugen.hristev@microchip.com> +Date: Mon, 28 Jun 2021 15:04:50 +0300 +Subject: [PATCH 222/247] ARM: dts: at91: add sama7g5 SoC DT and sama7g5-ek + +Add Device Tree for sama7g5 SoC and associated board sama7g5-ek + +Signed-off-by: Eugen Hristev <eugen.hristev@microchip.com> +[claudiu.beznea@microchip.com: add clocks, ethernet, timers, power] +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +[codrin.ciubotariu@microchip.com: add audio] +Signed-off-by: Codrin Ciubotariu <codrin.ciubotariu@microchip.com> +[nicolas.ferre@microchip.com: removed eeproms, reorder i2s dma chans] +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210628120452.74408-2-eugen.hristev@microchip.com +[claudiu.beznea: adapt to kernel v5.10] +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +--- + arch/arm/boot/dts/Makefile | 2 + + arch/arm/boot/dts/at91-sama7g5ek.dts | 656 +++++++++++++++++++ + arch/arm/boot/dts/sama7g5-pinfunc.h | 923 +++++++++++++++++++++++++++ + arch/arm/boot/dts/sama7g5.dtsi | 528 +++++++++++++++ + 4 files changed, 2109 insertions(+) + create mode 100644 arch/arm/boot/dts/at91-sama7g5ek.dts + create mode 100644 arch/arm/boot/dts/sama7g5-pinfunc.h + create mode 100644 arch/arm/boot/dts/sama7g5.dtsi + +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index ce66ffd5a1bb..2345a2304bd0 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -78,6 +78,8 @@ dtb-$(CONFIG_ARCH_ATLAS6) += \ + atlas6-evb.dtb + dtb-$(CONFIG_ARCH_ATLAS7) += \ + atlas7-evb.dtb ++dtb-$(CONFIG_SOC_SAMA7G5) += \ ++ at91-sama7g5ek.dtb + dtb-$(CONFIG_ARCH_AXXIA) += \ + axm5516-amarillo.dtb + dtb-$(CONFIG_ARCH_BCM2835) += \ +diff --git a/arch/arm/boot/dts/at91-sama7g5ek.dts b/arch/arm/boot/dts/at91-sama7g5ek.dts +new file mode 100644 +index 000000000000..4cbed98cc2f4 +--- /dev/null ++++ b/arch/arm/boot/dts/at91-sama7g5ek.dts +@@ -0,0 +1,656 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * at91-sama7g5ek.dts - Device Tree file for SAMA7G5-EK board ++ * ++ * Copyright (c) 2020 Microchip Technology Inc. and its subsidiaries ++ * ++ * Author: Eugen Hristev <eugen.hristev@microchip.com> ++ * Author: Claudiu Beznea <claudiu.beznea@microchip.com> ++ * ++ */ ++/dts-v1/; ++#include "sama7g5-pinfunc.h" ++#include "sama7g5.dtsi" ++#include <dt-bindings/mfd/atmel-flexcom.h> ++#include <dt-bindings/input/input.h> ++ ++/ { ++ model = "Microchip SAMA7G5-EK"; ++ compatible = "microchip,sama7g5ek", "microchip,sama7g5", "microchip,sama7"; ++ ++ chosen { ++ bootargs = "rw root=/dev/mmcblk1p2 rootfstype=ext4 rootwait"; ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ serial0 = &uart3; ++ serial1 = &uart4; ++ serial2 = &uart7; ++ serial3 = &uart0; ++ i2c0 = &i2c1; ++ i2c1 = &i2c8; ++ i2c2 = &i2c9; ++ }; ++ ++ clocks { ++ slow_xtal { ++ clock-frequency = <32768>; ++ }; ++ ++ main_xtal { ++ clock-frequency = <24000000>; ++ }; ++ }; ++ ++ gpio_keys { ++ compatible = "gpio-keys"; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_key_gpio_default>; ++ ++ bp1 { ++ label = "PB_USER"; ++ gpios = <&pioA PIN_PA12 GPIO_ACTIVE_LOW>; ++ linux,code = <KEY_PROG1>; ++ wakeup-source; ++ }; ++ }; ++ ++ leds { ++ compatible = "gpio-leds"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_led_gpio_default>; ++ status = "okay"; /* Conflict with pwm. */ ++ ++ red_led { ++ label = "red"; ++ gpios = <&pioA PIN_PB8 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ green_led { ++ label = "green"; ++ gpios = <&pioA PIN_PA13 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ blue_led { ++ label = "blue"; ++ gpios = <&pioA PIN_PD20 GPIO_ACTIVE_HIGH>; ++ linux,default-trigger = "heartbeat"; ++ }; ++ }; ++ ++ /* 512 M */ ++ memory@60000000 { ++ device_type = "memory"; ++ reg = <0x60000000 0x20000000>; ++ }; ++ ++ sound: sound { ++ compatible = "simple-audio-card"; ++ simple-audio-card,name = "sama7g5ek audio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ simple-audio-card,dai-link@0 { ++ reg = <0>; ++ cpu { ++ sound-dai = <&spdiftx>; ++ }; ++ codec { ++ sound-dai = <&spdif_out>; ++ }; ++ }; ++ simple-audio-card,dai-link@1 { ++ reg = <1>; ++ cpu { ++ sound-dai = <&spdifrx>; ++ }; ++ codec { ++ sound-dai = <&spdif_in>; ++ }; ++ }; ++ }; ++ ++ spdif_in: spdif-in { ++ #sound-dai-cells = <0>; ++ compatible = "linux,spdif-dir"; ++ }; ++ ++ spdif_out: spdif-out { ++ #sound-dai-cells = <0>; ++ compatible = "linux,spdif-dit"; ++ }; ++}; ++ ++&cpu0 { ++ cpu-supply = <&vddcpu>; ++}; ++ ++&dma0 { ++ status = "okay"; ++}; ++ ++&dma1 { ++ status = "okay"; ++}; ++ ++&dma2 { ++ status = "okay"; ++}; ++ ++&flx0 { ++ atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>; ++ status = "disabled"; ++ ++ uart0: serial@200 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_flx0_default>; ++ status = "disabled"; ++ }; ++}; ++ ++&flx1 { ++ atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_TWI>; ++ status = "okay"; ++ ++ i2c1: i2c@600 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i2c1_default>; ++ i2c-analog-filter; ++ i2c-digital-filter; ++ i2c-digital-filter-width-ns = <35>; ++ status = "okay"; ++ ++ mcp16502@5b { ++ compatible = "microchip,mcp16502"; ++ reg = <0x5b>; ++ status = "okay"; ++ ++ regulators { ++ vdd_3v3: VDD_IO { ++ regulator-name = "VDD_IO"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <3700000>; ++ regulator-initial-mode = <2>; ++ regulator-allowed-modes = <2>, <4>; ++ regulator-always-on; ++ ++ regulator-state-standby { ++ regulator-on-in-suspend; ++ regulator-mode = <4>; ++ }; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ regulator-mode = <4>; ++ }; ++ }; ++ ++ vddioddr: VDD_DDR { ++ regulator-name = "VDD_DDR"; ++ regulator-min-microvolt = <1300000>; ++ regulator-max-microvolt = <1450000>; ++ regulator-initial-mode = <2>; ++ regulator-allowed-modes = <2>, <4>; ++ regulator-always-on; ++ ++ regulator-state-standby { ++ regulator-on-in-suspend; ++ regulator-mode = <4>; ++ }; ++ ++ regulator-state-mem { ++ regulator-on-in-suspend; ++ regulator-mode = <4>; ++ }; ++ }; ++ ++ vddcore: VDD_CORE { ++ regulator-name = "VDD_CORE"; ++ regulator-min-microvolt = <1100000>; ++ regulator-max-microvolt = <1850000>; ++ regulator-initial-mode = <2>; ++ regulator-allowed-modes = <2>, <4>; ++ regulator-always-on; ++ ++ regulator-state-standby { ++ regulator-on-in-suspend; ++ regulator-mode = <4>; ++ }; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ regulator-mode = <4>; ++ }; ++ }; ++ ++ vddcpu: VDD_OTHER { ++ regulator-name = "VDD_OTHER"; ++ regulator-min-microvolt = <1125000>; ++ regulator-max-microvolt = <1850000>; ++ regulator-initial-mode = <2>; ++ regulator-allowed-modes = <2>, <4>; ++ regulator-ramp-delay = <3125>; ++ regulator-always-on; ++ ++ regulator-state-standby { ++ regulator-on-in-suspend; ++ regulator-mode = <4>; ++ }; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ regulator-mode = <4>; ++ }; ++ }; ++ ++ vldo1: LDO1 { ++ regulator-name = "LDO1"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <3700000>; ++ regulator-always-on; ++ ++ regulator-state-standby { ++ regulator-on-in-suspend; ++ }; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ ++ vldo2: LDO2 { ++ regulator-name = "LDO2"; ++ regulator-min-microvolt = <1200000>; ++ regulator-max-microvolt = <3700000>; ++ ++ regulator-state-standby { ++ regulator-on-in-suspend; ++ }; ++ ++ regulator-state-mem { ++ regulator-off-in-suspend; ++ }; ++ }; ++ }; ++ }; ++ }; ++}; ++ ++&flx3 { ++ atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>; ++ status = "okay"; ++ ++ uart3: serial@200 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_flx3_default>; ++ status = "okay"; ++ }; ++}; ++ ++&flx4 { ++ atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>; ++ status = "okay"; ++ ++ uart4: serial@200 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_flx4_default>; ++ status = "okay"; ++ }; ++}; ++ ++&flx7 { ++ atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_USART>; ++ status = "okay"; ++ ++ uart7: serial@200 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_flx7_default>; ++ status = "okay"; ++ }; ++}; ++ ++&flx8 { ++ atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_TWI>; ++ status = "okay"; ++ ++ i2c8: i2c@600 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i2c8_default>; ++ i2c-analog-filter; ++ i2c-digital-filter; ++ i2c-digital-filter-width-ns = <35>; ++ status = "okay"; ++ }; ++}; ++ ++&flx9 { ++ atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_TWI>; ++ status = "okay"; ++ ++ i2c9: i2c@600 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i2c9_default>; ++ i2c-analog-filter; ++ i2c-digital-filter; ++ i2c-digital-filter-width-ns = <35>; ++ status = "okay"; ++ }; ++}; ++ ++&flx11 { ++ atmel,flexcom-mode = <ATMEL_FLEXCOM_MODE_SPI>; ++ status = "okay"; ++ ++ spi11: spi@400 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_mikrobus1_spi &pinctrl_mikrobus1_spi_cs>; ++ status = "okay"; ++ }; ++}; ++ ++&gmac0 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_gmac0_default &pinctrl_gmac0_txck_default &pinctrl_gmac0_phy_irq>; ++ phy-mode = "rgmii-id"; ++ status = "okay"; ++ ++ ethernet-phy@7 { ++ reg = <0x7>; ++ interrupt-parent = <&pioA>; ++ interrupts = <PIN_PA31 IRQ_TYPE_LEVEL_LOW>; ++ }; ++}; ++ ++&gmac1 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_gmac1_default &pinctrl_gmac1_phy_irq>; ++ phy-mode = "rmii"; ++ status = "okay"; ++ ++ ethernet-phy@0 { ++ reg = <0x0>; ++ interrupt-parent = <&pioA>; ++ interrupts = <PIN_PA21 IRQ_TYPE_LEVEL_LOW>; ++ }; ++}; ++ ++&i2s0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i2s0_default>; ++}; ++ ++&pioA { ++ pinctrl_flx0_default: flx0_default { ++ pinmux = <PIN_PE3__FLEXCOM0_IO0>, ++ <PIN_PE4__FLEXCOM0_IO1>, ++ <PIN_PE6__FLEXCOM0_IO3>, ++ <PIN_PE7__FLEXCOM0_IO4>; ++ bias-disable; ++ }; ++ ++ pinctrl_flx3_default: flx3_default { ++ pinmux = <PIN_PD16__FLEXCOM3_IO0>, ++ <PIN_PD17__FLEXCOM3_IO1>; ++ bias-disable; ++ }; ++ ++ pinctrl_flx4_default: flx4_default { ++ pinmux = <PIN_PD18__FLEXCOM4_IO0>, ++ <PIN_PD19__FLEXCOM4_IO1>; ++ bias-disable; ++ }; ++ ++ pinctrl_flx7_default: flx7_default { ++ pinmux = <PIN_PC23__FLEXCOM7_IO0>, ++ <PIN_PC24__FLEXCOM7_IO1>; ++ bias-disable; ++ }; ++ ++ pinctrl_gmac0_default: gmac0_default { ++ pinmux = <PIN_PA16__G0_TX0>, ++ <PIN_PA17__G0_TX1>, ++ <PIN_PA26__G0_TX2>, ++ <PIN_PA27__G0_TX3>, ++ <PIN_PA19__G0_RX0>, ++ <PIN_PA20__G0_RX1>, ++ <PIN_PA28__G0_RX2>, ++ <PIN_PA29__G0_RX3>, ++ <PIN_PA15__G0_TXEN>, ++ <PIN_PA30__G0_RXCK>, ++ <PIN_PA18__G0_RXDV>, ++ <PIN_PA22__G0_MDC>, ++ <PIN_PA23__G0_MDIO>, ++ <PIN_PA25__G0_125CK>; ++ bias-disable; ++ }; ++ ++ pinctrl_gmac0_txck_default: gmac0_txck_default { ++ pinmux = <PIN_PA24__G0_TXCK>; ++ bias-pull-up; ++ }; ++ ++ pinctrl_gmac0_phy_irq: gmac0_phy_irq { ++ pinmux = <PIN_PA31__GPIO>; ++ bias-disable; ++ }; ++ ++ pinctrl_gmac1_default: gmac1_default { ++ pinmux = <PIN_PD30__G1_TXCK>, ++ <PIN_PD22__G1_TX0>, ++ <PIN_PD23__G1_TX1>, ++ <PIN_PD21__G1_TXEN>, ++ <PIN_PD25__G1_RX0>, ++ <PIN_PD26__G1_RX1>, ++ <PIN_PD27__G1_RXER>, ++ <PIN_PD24__G1_RXDV>, ++ <PIN_PD28__G1_MDC>, ++ <PIN_PD29__G1_MDIO>; ++ bias-disable; ++ }; ++ ++ pinctrl_gmac1_phy_irq: gmac1_phy_irq { ++ pinmux = <PIN_PA21__GPIO>; ++ bias-disable; ++ }; ++ ++ pinctrl_i2c1_default: i2c1_default { ++ pinmux = <PIN_PC9__FLEXCOM1_IO0>, ++ <PIN_PC10__FLEXCOM1_IO1>; ++ bias-disable; ++ }; ++ ++ pinctrl_i2c8_default: i2c8_default { ++ pinmux = <PIN_PC14__FLEXCOM8_IO0>, ++ <PIN_PC13__FLEXCOM8_IO1>; ++ bias-disable; ++ }; ++ ++ pinctrl_i2c9_default: i2c9_default { ++ pinmux = <PIN_PC18__FLEXCOM9_IO0>, ++ <PIN_PC19__FLEXCOM9_IO1>; ++ bias-disable; ++ }; ++ ++ pinctrl_i2s0_default: i2s0_default { ++ pinmux = <PIN_PB23__I2SMCC0_CK>, ++ <PIN_PB24__I2SMCC0_WS>, ++ <PIN_PB25__I2SMCC0_DOUT1>, ++ <PIN_PB26__I2SMCC0_DOUT0>, ++ <PIN_PB27__I2SMCC0_MCK>; ++ bias-disable; ++ }; ++ ++ pinctrl_key_gpio_default: key_gpio_default { ++ pinmux = <PIN_PA12__GPIO>; ++ bias-pull-up; ++ }; ++ ++ pinctrl_led_gpio_default: led_gpio_default { ++ pinmux = <PIN_PA13__GPIO>, ++ <PIN_PB8__GPIO>, ++ <PIN_PD20__GPIO>; ++ bias-pull-up; ++ }; ++ ++ pinctrl_mikrobus1_an_default: mikrobus1_an_default { ++ pinmux = <PIN_PD0__GPIO>; ++ bias-disable; ++ }; ++ ++ pinctrl_mikrobus2_an_default: mikrobus2_an_default { ++ pinmux = <PIN_PD1__GPIO>; ++ bias-disable; ++ }; ++ ++ pinctrl_mikrobus1_pwm2_default: mikrobus1_pwm2_default { ++ pinmux = <PIN_PA13__PWMH2>; ++ bias-disable; ++ }; ++ ++ pinctrl_mikrobus2_pwm3_default: mikrobus2_pwm3_default { ++ pinmux = <PIN_PD20__PWMH3>; ++ bias-disable; ++ }; ++ ++ pinctrl_mikrobus1_spi_cs: mikrobus1_spi_cs { ++ pinmux = <PIN_PB6__FLEXCOM11_IO3>; ++ bias-disable; ++ }; ++ ++ pinctrl_mikrobus1_spi: mikrobus1_spi { ++ pinmux = <PIN_PB3__FLEXCOM11_IO0>, ++ <PIN_PB4__FLEXCOM11_IO1>, ++ <PIN_PB5__FLEXCOM11_IO2>; ++ bias-disable; ++ }; ++ ++ pinctrl_sdmmc0_default: sdmmc0_default { ++ cmd_data { ++ pinmux = <PIN_PA1__SDMMC0_CMD>, ++ <PIN_PA3__SDMMC0_DAT0>, ++ <PIN_PA4__SDMMC0_DAT1>, ++ <PIN_PA5__SDMMC0_DAT2>, ++ <PIN_PA6__SDMMC0_DAT3>, ++ <PIN_PA7__SDMMC0_DAT4>, ++ <PIN_PA8__SDMMC0_DAT5>, ++ <PIN_PA9__SDMMC0_DAT6>, ++ <PIN_PA10__SDMMC0_DAT7>; ++ bias-pull-up; ++ }; ++ ++ ck_cd_rstn_vddsel { ++ pinmux = <PIN_PA0__SDMMC0_CK>, ++ <PIN_PA2__SDMMC0_RSTN>, ++ <PIN_PA11__SDMMC0_DS>; ++ bias-pull-up; ++ }; ++ }; ++ ++ pinctrl_sdmmc1_default: sdmmc1_default { ++ cmd_data { ++ pinmux = <PIN_PB29__SDMMC1_CMD>, ++ <PIN_PB31__SDMMC1_DAT0>, ++ <PIN_PC0__SDMMC1_DAT1>, ++ <PIN_PC1__SDMMC1_DAT2>, ++ <PIN_PC2__SDMMC1_DAT3>; ++ bias-pull-up; ++ }; ++ ++ ck_cd_rstn_vddsel { ++ pinmux = <PIN_PB30__SDMMC1_CK>, ++ <PIN_PB28__SDMMC1_RSTN>, ++ <PIN_PC5__SDMMC1_1V8SEL>, ++ <PIN_PC4__SDMMC1_CD>; ++ bias-pull-up; ++ }; ++ }; ++ ++ pinctrl_sdmmc2_default: sdmmc2_default { ++ cmd_data { ++ pinmux = <PIN_PD3__SDMMC2_CMD>, ++ <PIN_PD5__SDMMC2_DAT0>, ++ <PIN_PD6__SDMMC2_DAT1>, ++ <PIN_PD7__SDMMC2_DAT2>, ++ <PIN_PD8__SDMMC2_DAT3>; ++ bias-pull-up; ++ }; ++ ++ ck { ++ pinmux = <PIN_PD4__SDMMC2_CK>; ++ bias-pull-up; ++ }; ++ }; ++ ++ pinctrl_spdifrx_default: spdifrx_default { ++ pinmux = <PIN_PB0__SPDIF_RX>; ++ bias-disable; ++ }; ++ ++ pinctrl_spdiftx_default: spdiftx_default { ++ pinmux = <PIN_PB1__SPDIF_TX>; ++ bias-disable; ++ }; ++}; ++ ++&pwm { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_mikrobus1_pwm2_default &pinctrl_mikrobus2_pwm3_default>; ++ status = "disabled"; /* Conflict with leds. */ ++}; ++ ++&rtt { ++ atmel,rtt-rtc-time-reg = <&gpbr 0x0>; ++}; ++ ++&sdmmc0 { ++ bus-width = <8>; ++ non-removable; ++ no-1-8-v; ++ sdhci-caps-mask = <0x0 0x00200000>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_sdmmc0_default>; ++ status = "okay"; ++}; ++ ++&sdmmc1 { ++ bus-width = <4>; ++ no-1-8-v; ++ sdhci-caps-mask = <0x0 0x00200000>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_sdmmc1_default>; ++ status = "okay"; ++}; ++ ++&sdmmc2 { ++ bus-width = <4>; ++ no-1-8-v; ++ sdhci-caps-mask = <0x0 0x00200000>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_sdmmc2_default>; ++}; ++ ++&spdifrx { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_spdifrx_default>; ++ status = "okay"; ++}; ++ ++&spdiftx { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_spdiftx_default>; ++ status = "okay"; ++}; ++ ++&trng { ++ status = "okay"; ++}; ++ ++&vddout25 { ++ vin-supply = <&vdd_3v3>; ++ status = "okay"; ++}; +diff --git a/arch/arm/boot/dts/sama7g5-pinfunc.h b/arch/arm/boot/dts/sama7g5-pinfunc.h +new file mode 100644 +index 000000000000..22fe9e522a97 +--- /dev/null ++++ b/arch/arm/boot/dts/sama7g5-pinfunc.h +@@ -0,0 +1,923 @@ ++/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */ ++#define PINMUX_PIN(no, func, ioset) \ ++(((no) & 0xffff) | (((func) & 0xf) << 16) | (((ioset) & 0xff) << 20)) ++ ++#define PIN_PA0 0 ++#define PIN_PA0__GPIO PINMUX_PIN(PIN_PA0, 0, 0) ++#define PIN_PA0__SDMMC0_CK PINMUX_PIN(PIN_PA0, 1, 1) ++#define PIN_PA0__FLEXCOM0_IO0 PINMUX_PIN(PIN_PA0, 2, 1) ++#define PIN_PA0__CANTX3 PINMUX_PIN(PIN_PA0, 3, 1) ++#define PIN_PA0__PWML0 PINMUX_PIN(PIN_PA0, 5, 2) ++#define PIN_PA1 1 ++#define PIN_PA1__GPIO PINMUX_PIN(PIN_PA1, 0, 0) ++#define PIN_PA1__SDMMC0_CMD PINMUX_PIN(PIN_PA1, 1, 1) ++#define PIN_PA1__FLEXCOM0_IO1 PINMUX_PIN(PIN_PA1, 2, 1) ++#define PIN_PA1__CANRX3 PINMUX_PIN(PIN_PA1, 3, 1) ++#define PIN_PA1__D14 PINMUX_PIN(PIN_PA1, 4, 1) ++#define PIN_PA1__PWMH0 PINMUX_PIN(PIN_PA1, 5, 3) ++#define PIN_PA2 2 ++#define PIN_PA2__GPIO PINMUX_PIN(PIN_PA2, 0, 0) ++#define PIN_PA2__SDMMC0_RSTN PINMUX_PIN(PIN_PA2, 1, 1) ++#define PIN_PA2__FLEXCOM0_IO2 PINMUX_PIN(PIN_PA2, 2, 1) ++#define PIN_PA2__PDMC1_CLK PINMUX_PIN(PIN_PA2, 3, 1) ++#define PIN_PA2__D15 PINMUX_PIN(PIN_PA2, 4, 1) ++#define PIN_PA2__PWMH1 PINMUX_PIN(PIN_PA2, 5, 3) ++#define PIN_PA2__FLEXCOM1_IO0 PINMUX_PIN(PIN_PA2, 6, 3) ++#define PIN_PA3 3 ++#define PIN_PA3__GPIO PINMUX_PIN(PIN_PA3, 0, 0) ++#define PIN_PA3__SDMMC0_DAT0 PINMUX_PIN(PIN_PA3, 1, 1) ++#define PIN_PA3__FLEXCOM0_IO3 PINMUX_PIN(PIN_PA3, 2, 1) ++#define PIN_PA3__PDMC1_DS0 PINMUX_PIN(PIN_PA3, 3, 1) ++#define PIN_PA3__NWR1_NBS1 PINMUX_PIN(PIN_PA3, 4, 1) ++#define PIN_PA3__PWML3 PINMUX_PIN(PIN_PA3, 5, 3) ++#define PIN_PA3__FLEXCOM1_IO1 PINMUX_PIN(PIN_PA3, 6, 3) ++#define PIN_PA4 4 ++#define PIN_PA4__GPIO PINMUX_PIN(PIN_PA4, 0, 0) ++#define PIN_PA4__SDMMC0_DAT1 PINMUX_PIN(PIN_PA4, 1, 1) ++#define PIN_PA4__FLEXCOM0_IO4 PINMUX_PIN(PIN_PA4, 2, 1) ++#define PIN_PA4__PDMC1_DS1 PINMUX_PIN(PIN_PA4, 3, 1) ++#define PIN_PA4__NCS2 PINMUX_PIN(PIN_PA4, 4, 1) ++#define PIN_PA4__PWMH3 PINMUX_PIN(PIN_PA4, 5, 3) ++#define PIN_PA4__FLEXCOM2_IO0 PINMUX_PIN(PIN_PA4, 6, 3) ++#define PIN_PA5 5 ++#define PIN_PA5__GPIO PINMUX_PIN(PIN_PA5, 0, 0) ++#define PIN_PA5__SDMMC0_DAT2 PINMUX_PIN(PIN_PA5, 1, 1) ++#define PIN_PA5__FLEXCOM1_IO0 PINMUX_PIN(PIN_PA5, 2, 1) ++#define PIN_PA5__CANTX2 PINMUX_PIN(PIN_PA5, 3, 1) ++#define PIN_PA5__A23 PINMUX_PIN(PIN_PA5, 4, 1) ++#define PIN_PA5__PWMEXTRG0 PINMUX_PIN(PIN_PA5, 5, 3) ++#define PIN_PA5__FLEXCOM2_IO1 PINMUX_PIN(PIN_PA5, 6, 3) ++#define PIN_PA6 6 ++#define PIN_PA6__GPIO PINMUX_PIN(PIN_PA6, 0, 0) ++#define PIN_PA6__SDMMC0_DAT3 PINMUX_PIN(PIN_PA6, 1, 1) ++#define PIN_PA6__FLEXCOM1_IO1 PINMUX_PIN(PIN_PA6, 2, 1) ++#define PIN_PA6__CANRX2 PINMUX_PIN(PIN_PA6, 3, 1) ++#define PIN_PA6__A24 PINMUX_PIN(PIN_PA6, 4, 1) ++#define PIN_PA6__PWMEXTRG1 PINMUX_PIN(PIN_PA6, 5, 3) ++#define PIN_PA6__FLEXCOM3_IO0 PINMUX_PIN(PIN_PA6, 6, 3) ++#define PIN_PA7 7 ++#define PIN_PA7__GPIO PINMUX_PIN(PIN_PA7, 0, 0) ++#define PIN_PA7__SDMMC0_DAT4 PINMUX_PIN(PIN_PA7, 1, 1) ++#define PIN_PA7__FLEXCOM2_IO0 PINMUX_PIN(PIN_PA7, 2, 1) ++#define PIN_PA7__CANTX1 PINMUX_PIN(PIN_PA7, 3, 1) ++#define PIN_PA7__NWAIT PINMUX_PIN(PIN_PA7, 4, 1) ++#define PIN_PA7__PWMFI0 PINMUX_PIN(PIN_PA7, 5, 3) ++#define PIN_PA7__FLEXCOM3_IO1 PINMUX_PIN(PIN_PA7, 6, 3) ++#define PIN_PA8 8 ++#define PIN_PA8__GPIO PINMUX_PIN(PIN_PA8, 0, 0) ++#define PIN_PA8__SDMMC0_DAT5 PINMUX_PIN(PIN_PA8, 1, 1) ++#define PIN_PA8__FLEXCOM2_IO1 PINMUX_PIN(PIN_PA8, 2, 1) ++#define PIN_PA8__CANRX1 PINMUX_PIN(PIN_PA8, 3, 1) ++#define PIN_PA8__NCS0 PINMUX_PIN(PIN_PA8, 4, 1) ++#define PIN_PA8__PWMIF1 PINMUX_PIN(PIN_PA8, 5, 3) ++#define PIN_PA8__FLEXCOM4_IO0 PINMUX_PIN(PIN_PA8, 6, 3) ++#define PIN_PA9 9 ++#define PIN_PA9__GPIO PINMUX_PIN(PIN_PA9, 0, 0) ++#define PIN_PA9__SDMMC0_DAT6 PINMUX_PIN(PIN_PA9, 1, 1) ++#define PIN_PA9__FLEXCOM2_IO2 PINMUX_PIN(PIN_PA9, 2, 1) ++#define PIN_PA9__CANTX0 PINMUX_PIN(PIN_PA9, 3, 1) ++#define PIN_PA9__SMCK PINMUX_PIN(PIN_PA9, 4, 1) ++#define PIN_PA9__SPDIF_RX PINMUX_PIN(PIN_PA9, 5, 1) ++#define PIN_PA9__FLEXCOM4_IO1 PINMUX_PIN(PIN_PA9, 6, 3) ++#define PIN_PA10 10 ++#define PIN_PA10__GPIO PINMUX_PIN(PIN_PA10, 0, 0) ++#define PIN_PA10__SDMMC0_DAT7 PINMUX_PIN(PIN_PA10, 1, 1) ++#define PIN_PA10__FLEXCOM2_IO3 PINMUX_PIN(PIN_PA10, 2, 1) ++#define PIN_PA10__CANRX0 PINMUX_PIN(PIN_PA10, 3, 1) ++#define PIN_PA10__NCS1 PINMUX_PIN(PIN_PA10, 4, 1) ++#define PIN_PA10__SPDIF_TX PINMUX_PIN(PIN_PA10, 5, 1) ++#define PIN_PA10__FLEXCOM5_IO0 PINMUX_PIN(PIN_PA10, 6, 3) ++#define PIN_PA11 11 ++#define PIN_PA11__GPIO PINMUX_PIN(PIN_PA11, 0, 0) ++#define PIN_PA11__SDMMC0_DS PINMUX_PIN(PIN_PA11, 1, 1) ++#define PIN_PA11__FLEXCOM2_IO4 PINMUX_PIN(PIN_PA11, 2, 1) ++#define PIN_PA11__A0_NBS0 PINMUX_PIN(PIN_PA11, 4, 1) ++#define PIN_PA11__TIOA0 PINMUX_PIN(PIN_PA11, 5, 1) ++#define PIN_PA11__FLEXCOM5_IO1 PINMUX_PIN(PIN_PA11, 6, 3) ++#define PIN_PA12 12 ++#define PIN_PA12__GPIO PINMUX_PIN(PIN_PA12, 0, 0) ++#define PIN_PA12__SDMMC0_WP PINMUX_PIN(PIN_PA12, 1, 1) ++#define PIN_PA12__FLEXCOM1_IO3 PINMUX_PIN(PIN_PA12, 2, 1) ++#define PIN_PA12__FLEXCOM3_IO5 PINMUX_PIN(PIN_PA12, 4, 1) ++#define PIN_PA12__PWML2 PINMUX_PIN(PIN_PA12, 5, 3) ++#define PIN_PA12__FLEXCOM6_IO0 PINMUX_PIN(PIN_PA12, 6, 3) ++#define PIN_PA13 13 ++#define PIN_PA13__GPIO PINMUX_PIN(PIN_PA13, 0, 0) ++#define PIN_PA13__SDMMC0_1V8SEL PINMUX_PIN(PIN_PA13, 1, 1) ++#define PIN_PA13__FLEXCOM1_IO2 PINMUX_PIN(PIN_PA13, 2, 1) ++#define PIN_PA13__FLEXCOM3_IO6 PINMUX_PIN(PIN_PA13, 4, 1) ++#define PIN_PA13__PWMH2 PINMUX_PIN(PIN_PA13, 5, 3) ++#define PIN_PA13__FLEXCOM6_IO1 PINMUX_PIN(PIN_PA13, 6, 3) ++#define PIN_PA14 14 ++#define PIN_PA14__GPIO PINMUX_PIN(PIN_PA14, 0, 0) ++#define PIN_PA14__SDMMC0_CD PINMUX_PIN(PIN_PA14, 1, 1) ++#define PIN_PA14__FLEXCOM1_IO4 PINMUX_PIN(PIN_PA14, 2, 1) ++#define PIN_PA14__A25 PINMUX_PIN(PIN_PA14, 4, 1) ++#define PIN_PA14__PWML1 PINMUX_PIN(PIN_PA14, 5, 3) ++#define PIN_PA15 15 ++#define PIN_PA15__GPIO PINMUX_PIN(PIN_PA15, 0, 0) ++#define PIN_PA15__G0_TXEN PINMUX_PIN(PIN_PA15, 1, 1) ++#define PIN_PA15__FLEXCOM3_IO0 PINMUX_PIN(PIN_PA15, 2, 1) ++#define PIN_PA15__ISC_MCK PINMUX_PIN(PIN_PA15, 3, 1) ++#define PIN_PA15__A1 PINMUX_PIN(PIN_PA15, 4, 1) ++#define PIN_PA15__TIOB0 PINMUX_PIN(PIN_PA15, 5, 1) ++#define PIN_PA16 16 ++#define PIN_PA16__GPIO PINMUX_PIN(PIN_PA16, 0, 0) ++#define PIN_PA16__G0_TX0 PINMUX_PIN(PIN_PA16, 1, 1) ++#define PIN_PA16__FLEXCOM3_IO1 PINMUX_PIN(PIN_PA16, 2, 1) ++#define PIN_PA16__ISC_D0 PINMUX_PIN(PIN_PA16, 3, 1) ++#define PIN_PA16__A2 PINMUX_PIN(PIN_PA16, 4, 1) ++#define PIN_PA16__TCLK0 PINMUX_PIN(PIN_PA16, 5, 1) ++#define PIN_PA17 17 ++#define PIN_PA17__GPIO PINMUX_PIN(PIN_PA17, 0, 0) ++#define PIN_PA17__G0_TX1 PINMUX_PIN(PIN_PA17, 1, 1) ++#define PIN_PA17__FLEXCOM3_IO2 PINMUX_PIN(PIN_PA17, 2, 1) ++#define PIN_PA17__ISC_D1 PINMUX_PIN(PIN_PA17, 3, 1) ++#define PIN_PA17__A3 PINMUX_PIN(PIN_PA17, 4, 1) ++#define PIN_PA17__TIOA1 PINMUX_PIN(PIN_PA17, 5, 1) ++#define PIN_PA18 18 ++#define PIN_PA18__GPIO PINMUX_PIN(PIN_PA18, 0, 0) ++#define PIN_PA18__G0_RXDV PINMUX_PIN(PIN_PA18, 1, 1) ++#define PIN_PA18__FLEXCOM3_IO3 PINMUX_PIN(PIN_PA18, 2, 1) ++#define PIN_PA18__ISC_D2 PINMUX_PIN(PIN_PA18, 3, 1) ++#define PIN_PA18__A4 PINMUX_PIN(PIN_PA18, 4, 1) ++#define PIN_PA18__TIOB1 PINMUX_PIN(PIN_PA18, 5, 1) ++#define PIN_PA19 19 ++#define PIN_PA19__GPIO PINMUX_PIN(PIN_PA19, 0, 0) ++#define PIN_PA19__G0_RX0 PINMUX_PIN(PIN_PA19, 1, 1) ++#define PIN_PA19__FLEXCOM3_IO4 PINMUX_PIN(PIN_PA19, 2, 1) ++#define PIN_PA19__ISC_D3 PINMUX_PIN(PIN_PA19, 3, 1) ++#define PIN_PA19__A5 PINMUX_PIN(PIN_PA19, 4, 1) ++#define PIN_PA19__TCLK1 PINMUX_PIN(PIN_PA19, 5, 1) ++#define PIN_PA20 20 ++#define PIN_PA20__GPIO PINMUX_PIN(PIN_PA20, 0, 0) ++#define PIN_PA20__G0_RX1 PINMUX_PIN(PIN_PA20, 1, 1) ++#define PIN_PA20__FLEXCOM4_IO0 PINMUX_PIN(PIN_PA20, 2, 1) ++#define PIN_PA20__ISC_D4 PINMUX_PIN(PIN_PA20, 3, 1) ++#define PIN_PA20__A6 PINMUX_PIN(PIN_PA20, 4, 1) ++#define PIN_PA20__TIOA2 PINMUX_PIN(PIN_PA20, 5, 1) ++#define PIN_PA21 21 ++#define PIN_PA21__GPIO PINMUX_PIN(PIN_PA21, 0, 0) ++#define PIN_PA21__G0_RXER PINMUX_PIN(PIN_PA21, 1, 1) ++#define PIN_PA21__FLEXCOM4_IO1 PINMUX_PIN(PIN_PA21, 2, 1) ++#define PIN_PA21__ISC_D5 PINMUX_PIN(PIN_PA21, 3, 1) ++#define PIN_PA21__A7 PINMUX_PIN(PIN_PA21, 4, 1) ++#define PIN_PA21__TIOB2 PINMUX_PIN(PIN_PA21, 5, 1) ++#define PIN_PA22 22 ++#define PIN_PA22__GPIO PINMUX_PIN(PIN_PA22, 0, 0) ++#define PIN_PA22__G0_MDC PINMUX_PIN(PIN_PA22, 1, 1) ++#define PIN_PA22__FLEXCOM4_IO2 PINMUX_PIN(PIN_PA22, 2, 1) ++#define PIN_PA22__ISC_D6 PINMUX_PIN(PIN_PA22, 3, 1) ++#define PIN_PA22__A8 PINMUX_PIN(PIN_PA22, 4, 1) ++#define PIN_PA22__TCLK2 PINMUX_PIN(PIN_PA22, 5, 1) ++#define PIN_PA23 23 ++#define PIN_PA23__GPIO PINMUX_PIN(PIN_PA23, 0, 0) ++#define PIN_PA23__G0_MDIO PINMUX_PIN(PIN_PA23, 1, 1) ++#define PIN_PA23__FLEXCOM4_IO3 PINMUX_PIN(PIN_PA23, 2, 1) ++#define PIN_PA23__ISC_D7 PINMUX_PIN(PIN_PA23, 3, 1) ++#define PIN_PA23__A9 PINMUX_PIN(PIN_PA23, 4, 1) ++#define PIN_PA24 24 ++#define PIN_PA24__GPIO PINMUX_PIN(PIN_PA24, 0, 0) ++#define PIN_PA24__G0_TXCK PINMUX_PIN(PIN_PA24, 1, 1) ++#define PIN_PA24__FLEXCOM4_IO4 PINMUX_PIN(PIN_PA24, 2, 1) ++#define PIN_PA24__ISC_HSYNC PINMUX_PIN(PIN_PA24, 3, 1) ++#define PIN_PA24__A10 PINMUX_PIN(PIN_PA24, 4, 1) ++#define PIN_PA24__FLEXCOM0_IO5 PINMUX_PIN(PIN_PA24, 5, 1) ++#define PIN_PA25 25 ++#define PIN_PA25__GPIO PINMUX_PIN(PIN_PA25, 0, 0) ++#define PIN_PA25__G0_125CK PINMUX_PIN(PIN_PA25, 1, 1) ++#define PIN_PA25__FLEXCOM5_IO4 PINMUX_PIN(PIN_PA25, 2, 1) ++#define PIN_PA25__ISC_VSYNC PINMUX_PIN(PIN_PA25, 3, 1) ++#define PIN_PA25__A11 PINMUX_PIN(PIN_PA25, 4, 1) ++#define PIN_PA25__FLEXCOM0_IO6 PINMUX_PIN(PIN_PA25, 5, 1) ++#define PIN_PA25__FLEXCOM7_IO0 PINMUX_PIN(PIN_PA25, 6, 3) ++#define PIN_PA26 26 ++#define PIN_PA26__GPIO PINMUX_PIN(PIN_PA26, 0, 0) ++#define PIN_PA26__G0_TX2 PINMUX_PIN(PIN_PA26, 1, 1) ++#define PIN_PA26__FLEXCOM5_IO2 PINMUX_PIN(PIN_PA26, 2, 1) ++#define PIN_PA26__ISC_FIELD PINMUX_PIN(PIN_PA26, 3, 1) ++#define PIN_PA26__A12 PINMUX_PIN(PIN_PA26, 4, 1) ++#define PIN_PA26__TF0 PINMUX_PIN(PIN_PA26, 5, 1) ++#define PIN_PA26__FLEXCOM7_IO1 PINMUX_PIN(PIN_PA26, 6, 3) ++#define PIN_PA27 27 ++#define PIN_PA27__GPIO PINMUX_PIN(PIN_PA27, 0, 0) ++#define PIN_PA27__G0_TX3 PINMUX_PIN(PIN_PA27, 1, 1) ++#define PIN_PA27__FLEXCOM5_IO3 PINMUX_PIN(PIN_PA27, 2, 1) ++#define PIN_PA27__ISC_PCK PINMUX_PIN(PIN_PA27, 3, 1) ++#define PIN_PA27__A13 PINMUX_PIN(PIN_PA27, 4, 1) ++#define PIN_PA27__TK0 PINMUX_PIN(PIN_PA27, 5, 1) ++#define PIN_PA27__FLEXCOM8_IO0 PINMUX_PIN(PIN_PA27, 6, 3) ++#define PIN_PA28 28 ++#define PIN_PA28__GPIO PINMUX_PIN(PIN_PA28, 0, 0) ++#define PIN_PA28__G0_RX2 PINMUX_PIN(PIN_PA28, 1, 1) ++#define PIN_PA28__FLEXCOM5_IO0 PINMUX_PIN(PIN_PA28, 2, 1) ++#define PIN_PA28__ISC_D8 PINMUX_PIN(PIN_PA28, 3, 1) ++#define PIN_PA28__A14 PINMUX_PIN(PIN_PA28, 4, 1) ++#define PIN_PA28__RD0 PINMUX_PIN(PIN_PA28, 5, 1) ++#define PIN_PA28__FLEXCOM8_IO1 PINMUX_PIN(PIN_PA28, 6, 3) ++#define PIN_PA29 29 ++#define PIN_PA29__GPIO PINMUX_PIN(PIN_PA29, 0, 0) ++#define PIN_PA29__G0_RX3 PINMUX_PIN(PIN_PA29, 1, 1) ++#define PIN_PA29__FLEXCOM5_IO1 PINMUX_PIN(PIN_PA29, 2, 1) ++#define PIN_PA29__ISC_D9 PINMUX_PIN(PIN_PA29, 3, 1) ++#define PIN_PA29__A15 PINMUX_PIN(PIN_PA29, 4, 1) ++#define PIN_PA29__RF0 PINMUX_PIN(PIN_PA29, 5, 1) ++#define PIN_PA29__FLEXCOM9_IO0 PINMUX_PIN(PIN_PA29, 6, 3) ++#define PIN_PA30 30 ++#define PIN_PA30__GPIO PINMUX_PIN(PIN_PA30, 0, 0) ++#define PIN_PA30__G0_RXCK PINMUX_PIN(PIN_PA30, 1, 1) ++#define PIN_PA30__FLEXCOM6_IO4 PINMUX_PIN(PIN_PA30, 2, 1) ++#define PIN_PA30__ISC_D10 PINMUX_PIN(PIN_PA30, 3, 1) ++#define PIN_PA30__A16 PINMUX_PIN(PIN_PA30, 4, 1) ++#define PIN_PA30__RK0 PINMUX_PIN(PIN_PA30, 5, 1) ++#define PIN_PA30__FLEXCOM9_IO1 PINMUX_PIN(PIN_PA30, 6, 3) ++#define PIN_PA31 31 ++#define PIN_PA31__GPIO PINMUX_PIN(PIN_PA31, 0, 0) ++#define PIN_PA31__G0_TXER PINMUX_PIN(PIN_PA31, 1, 1) ++#define PIN_PA31__FLEXCOM6_IO2 PINMUX_PIN(PIN_PA31, 2, 1) ++#define PIN_PA31__ISC_D11 PINMUX_PIN(PIN_PA31, 3, 1) ++#define PIN_PA31__A17 PINMUX_PIN(PIN_PA31, 4, 1) ++#define PIN_PA31__TD0 PINMUX_PIN(PIN_PA31, 5, 1) ++#define PIN_PA31__FLEXCOM10_IO0 PINMUX_PIN(PIN_PA31, 6, 3) ++#define PIN_PB0 32 ++#define PIN_PB0__GPIO PINMUX_PIN(PIN_PB0, 0, 0) ++#define PIN_PB0__G0_COL PINMUX_PIN(PIN_PB0, 1, 1) ++#define PIN_PB0__FLEXCOM6_IO3 PINMUX_PIN(PIN_PB0, 2, 2) ++#define PIN_PB0__EXT_IRQ0 PINMUX_PIN(PIN_PB0, 3, 1) ++#define PIN_PB0__A18 PINMUX_PIN(PIN_PB0, 4, 1) ++#define PIN_PB0__SPDIF_RX PINMUX_PIN(PIN_PB0, 5, 2) ++#define PIN_PB0__FLEXCOM10_IO1 PINMUX_PIN(PIN_PB0, 6, 3) ++#define PIN_PB1 33 ++#define PIN_PB1__GPIO PINMUX_PIN(PIN_PB1, 0, 0) ++#define PIN_PB1__G0_CRS PINMUX_PIN(PIN_PB1, 1, 1) ++#define PIN_PB1__FLEXCOM6_IO1 PINMUX_PIN(PIN_PB1, 2, 2) ++#define PIN_PB1__EXT_IRQ1 PINMUX_PIN(PIN_PB1, 3, 1) ++#define PIN_PB1__A19 PINMUX_PIN(PIN_PB1, 4, 1) ++#define PIN_PB1__SPDIF_TX PINMUX_PIN(PIN_PB1, 5, 2) ++#define PIN_PB1__FLEXCOM11_IO0 PINMUX_PIN(PIN_PB1, 6, 3) ++#define PIN_PB2 34 ++#define PIN_PB2__GPIO PINMUX_PIN(PIN_PB2, 0, 0) ++#define PIN_PB2__G0_TSUCOMP PINMUX_PIN(PIN_PB2, 1, 1) ++#define PIN_PB2__FLEXCOM6_IO0 PINMUX_PIN(PIN_PB2, 2, 1) ++#define PIN_PB2__ADTRG PINMUX_PIN(PIN_PB2, 3, 1) ++#define PIN_PB2__A20 PINMUX_PIN(PIN_PB2, 4, 1) ++#define PIN_PB2__FLEXCOM11_IO0 PINMUX_PIN(PIN_PB2, 6, 3) ++#define PIN_PB3 35 ++#define PIN_PB3__GPIO PINMUX_PIN(PIN_PB3, 0, 0) ++#define PIN_PB3__RF1 PINMUX_PIN(PIN_PB3, 1, 1) ++#define PIN_PB3__FLEXCOM11_IO0 PINMUX_PIN(PIN_PB3, 2, 1) ++#define PIN_PB3__PCK2 PINMUX_PIN(PIN_PB3, 3, 2) ++#define PIN_PB3__D8 PINMUX_PIN(PIN_PB3, 4, 1) ++#define PIN_PB4 36 ++#define PIN_PB4__GPIO PINMUX_PIN(PIN_PB4, 0, 0) ++#define PIN_PB4__TF1 PINMUX_PIN(PIN_PB4, 1, 1) ++#define PIN_PB4__FLEXCOM11_IO1 PINMUX_PIN(PIN_PB4, 2, 1) ++#define PIN_PB4__PCK3 PINMUX_PIN(PIN_PB4, 3, 2) ++#define PIN_PB4__D9 PINMUX_PIN(PIN_PB4, 4, 1) ++#define PIN_PB5 37 ++#define PIN_PB5__GPIO PINMUX_PIN(PIN_PB5, 0, 0) ++#define PIN_PB5__TK1 PINMUX_PIN(PIN_PB5, 1, 1) ++#define PIN_PB5__FLEXCOM11_IO2 PINMUX_PIN(PIN_PB5, 2, 1) ++#define PIN_PB5__PCK4 PINMUX_PIN(PIN_PB5, 3, 2) ++#define PIN_PB5__D10 PINMUX_PIN(PIN_PB5, 4, 1) ++#define PIN_PB6 38 ++#define PIN_PB6__GPIO PINMUX_PIN(PIN_PB6, 0, 0) ++#define PIN_PB6__RK1 PINMUX_PIN(PIN_PB6, 1, 1) ++#define PIN_PB6__FLEXCOM11_IO3 PINMUX_PIN(PIN_PB6, 2, 1) ++#define PIN_PB6__PCK5 PINMUX_PIN(PIN_PB6, 3, 2) ++#define PIN_PB6__D11 PINMUX_PIN(PIN_PB6, 4, 1) ++#define PIN_PB7 39 ++#define PIN_PB7__GPIO PINMUX_PIN(PIN_PB7, 0, 0) ++#define PIN_PB7__TD1 PINMUX_PIN(PIN_PB7, 1, 1) ++#define PIN_PB7__FLEXCOM11_IO4 PINMUX_PIN(PIN_PB7, 2, 1) ++#define PIN_PB7__FLEXCOM3_IO5 PINMUX_PIN(PIN_PB7, 3, 2) ++#define PIN_PB7__D12 PINMUX_PIN(PIN_PB7, 4, 1) ++#define PIN_PB8 40 ++#define PIN_PB8__GPIO PINMUX_PIN(PIN_PB8, 0, 0) ++#define PIN_PB8__RD1 PINMUX_PIN(PIN_PB8, 1, 1) ++#define PIN_PB8__FLEXCOM8_IO0 PINMUX_PIN(PIN_PB8, 2, 1) ++#define PIN_PB8__FLEXCOM3_IO6 PINMUX_PIN(PIN_PB8, 3, 2) ++#define PIN_PB8__D13 PINMUX_PIN(PIN_PB8, 4, 1) ++#define PIN_PB9 41 ++#define PIN_PB9__GPIO PINMUX_PIN(PIN_PB9, 0, 0) ++#define PIN_PB9__QSPI0_IO3 PINMUX_PIN(PIN_PB9, 1, 1) ++#define PIN_PB9__FLEXCOM8_IO1 PINMUX_PIN(PIN_PB9, 2, 1) ++#define PIN_PB9__PDMC0_CLK PINMUX_PIN(PIN_PB9, 3, 1) ++#define PIN_PB9__NCS3_NANDCS PINMUX_PIN(PIN_PB9, 4, 1) ++#define PIN_PB9__PWML0 PINMUX_PIN(PIN_PB9, 5, 2) ++#define PIN_PB10 42 ++#define PIN_PB10__GPIO PINMUX_PIN(PIN_PB10, 0, 0) ++#define PIN_PB10__QSPI0_IO2 PINMUX_PIN(PIN_PB10, 1, 1) ++#define PIN_PB10__FLEXCOM8_IO2 PINMUX_PIN(PIN_PB10, 2, 1) ++#define PIN_PB10__PDMC0_DS0 PINMUX_PIN(PIN_PB10, 3, 1) ++#define PIN_PB10__NWE_NWR0_NANDWE PINMUX_PIN(PIN_PB10, 4, 1) ++#define PIN_PB10__PWMH0 PINMUX_PIN(PIN_PB10, 5, 2) ++#define PIN_PB11 43 ++#define PIN_PB11__GPIO PINMUX_PIN(PIN_PB11, 0, 0) ++#define PIN_PB11__QSPI0_IO1 PINMUX_PIN(PIN_PB11, 1, 1) ++#define PIN_PB11__FLEXCOM8_IO3 PINMUX_PIN(PIN_PB11, 2, 1) ++#define PIN_PB11__PDMC0_DS1 PINMUX_PIN(PIN_PB11, 3, 1) ++#define PIN_PB11__NRD_NANDOE PINMUX_PIN(PIN_PB11, 4, 1) ++#define PIN_PB11__PWML1 PINMUX_PIN(PIN_PB11, 5, 2) ++#define PIN_PB12 44 ++#define PIN_PB12__GPIO PINMUX_PIN(PIN_PB12, 0, 0) ++#define PIN_PB12__QSPI0_IO0 PINMUX_PIN(PIN_PB12, 1, 1) ++#define PIN_PB12__FLEXCOM8_IO4 PINMUX_PIN(PIN_PB12, 2, 1) ++#define PIN_PB12__FLEXCOM6_IO5 PINMUX_PIN(PIN_PB12, 3, 1) ++#define PIN_PB12__A21_NANDALE PINMUX_PIN(PIN_PB12, 4, 1) ++#define PIN_PB12__PWMH1 PINMUX_PIN(PIN_PB12, 5, 2) ++#define PIN_PB13 45 ++#define PIN_PB13__GPIO PINMUX_PIN(PIN_PB13, 0, 0) ++#define PIN_PB13__QSPI0_CS PINMUX_PIN(PIN_PB13, 1, 1) ++#define PIN_PB13__FLEXCOM9_IO0 PINMUX_PIN(PIN_PB13, 2, 1) ++#define PIN_PB13__FLEXCOM6_IO6 PINMUX_PIN(PIN_PB13, 3, 1) ++#define PIN_PB13__A22_NANDCLE PINMUX_PIN(PIN_PB13, 4, 1) ++#define PIN_PB13__PWML2 PINMUX_PIN(PIN_PB13, 5, 2) ++#define PIN_PB14 46 ++#define PIN_PB14__GPIO PINMUX_PIN(PIN_PB14, 0, 0) ++#define PIN_PB14__QSPI0_SCK PINMUX_PIN(PIN_PB14, 1, 1) ++#define PIN_PB14__FLEXCOM9_IO1 PINMUX_PIN(PIN_PB14, 2, 1) ++#define PIN_PB14__D0 PINMUX_PIN(PIN_PB14, 4, 1) ++#define PIN_PB14__PWMH2 PINMUX_PIN(PIN_PB14, 5, 2) ++#define PIN_PB15 47 ++#define PIN_PB15__GPIO PINMUX_PIN(PIN_PB15, 0, 0) ++#define PIN_PB15__QSPI0_SCKN PINMUX_PIN(PIN_PB15, 1, 1) ++#define PIN_PB15__FLEXCOM9_IO2 PINMUX_PIN(PIN_PB15, 2, 1) ++#define PIN_PB15__D1 PINMUX_PIN(PIN_PB15, 4, 1) ++#define PIN_PB15__PWML3 PINMUX_PIN(PIN_PB15, 5, 2) ++#define PIN_PB16 48 ++#define PIN_PB16__GPIO PINMUX_PIN(PIN_PB16, 0, 0) ++#define PIN_PB16__QSPI0_IO4 PINMUX_PIN(PIN_PB16, 1, 1) ++#define PIN_PB16__FLEXCOM9_IO3 PINMUX_PIN(PIN_PB16, 2, 1) ++#define PIN_PB16__PCK0 PINMUX_PIN(PIN_PB16, 3, 1) ++#define PIN_PB16__D2 PINMUX_PIN(PIN_PB16, 4, 1) ++#define PIN_PB16__PWMH3 PINMUX_PIN(PIN_PB16, 5, 2) ++#define PIN_PB16__EXT_IRQ0 PINMUX_PIN(PIN_PB16, 6, 2) ++#define PIN_PB17 49 ++#define PIN_PB17__GPIO PINMUX_PIN(PIN_PB17, 0, 0) ++#define PIN_PB17__QSPI0_IO5 PINMUX_PIN(PIN_PB17, 1, 1) ++#define PIN_PB17__FLEXCOM9_IO4 PINMUX_PIN(PIN_PB17, 2, 1) ++#define PIN_PB17__PCK1 PINMUX_PIN(PIN_PB17, 3, 1) ++#define PIN_PB17__D3 PINMUX_PIN(PIN_PB17, 4, 1) ++#define PIN_PB17__PWMEXTRG0 PINMUX_PIN(PIN_PB17, 5, 2) ++#define PIN_PB17__EXT_IRQ1 PINMUX_PIN(PIN_PB17, 6, 2) ++#define PIN_PB18 50 ++#define PIN_PB18__GPIO PINMUX_PIN(PIN_PB18, 0, 0) ++#define PIN_PB18__QSPI0_IO6 PINMUX_PIN(PIN_PB18, 1, 1) ++#define PIN_PB18__FLEXCOM10_IO0 PINMUX_PIN(PIN_PB18, 2, 1) ++#define PIN_PB18__PCK2 PINMUX_PIN(PIN_PB18, 3, 1) ++#define PIN_PB18__D4 PINMUX_PIN(PIN_PB18, 4, 1) ++#define PIN_PB18__PWMEXTRG1 PINMUX_PIN(PIN_PB18, 5, 2) ++#define PIN_PB19 51 ++#define PIN_PB19__GPIO PINMUX_PIN(PIN_PB19, 0, 0) ++#define PIN_PB19__QSPI0_IO7 PINMUX_PIN(PIN_PB19, 1, 1) ++#define PIN_PB19__FLEXCOM10_IO1 PINMUX_PIN(PIN_PB19, 2, 1) ++#define PIN_PB19__PCK3 PINMUX_PIN(PIN_PB19, 3, 1) ++#define PIN_PB19__D5 PINMUX_PIN(PIN_PB19, 4, 1) ++#define PIN_PB19__PWMFI0 PINMUX_PIN(PIN_PB19, 5, 2) ++#define PIN_PB20 52 ++#define PIN_PB20__GPIO PINMUX_PIN(PIN_PB20, 0, 0) ++#define PIN_PB20__QSPI0_DQS PINMUX_PIN(PIN_PB20, 1, 1) ++#define PIN_PB20__FLEXCOM10_IO2 PINMUX_PIN(PIN_PB20, 2, 1) ++#define PIN_PB20__D6 PINMUX_PIN(PIN_PB20, 4, 1) ++#define PIN_PB20__PWMFI1 PINMUX_PIN(PIN_PB20, 5, 2) ++#define PIN_PB21 53 ++#define PIN_PB21__GPIO PINMUX_PIN(PIN_PB21, 0, 0) ++#define PIN_PB21__QSPI0_INT PINMUX_PIN(PIN_PB21, 1, 1) ++#define PIN_PB21__FLEXCOM10_IO3 PINMUX_PIN(PIN_PB21, 2, 1) ++#define PIN_PB21__FLEXCOM9_IO5 PINMUX_PIN(PIN_PB21, 3, 1) ++#define PIN_PB21__D7 PINMUX_PIN(PIN_PB21, 4, 1) ++#define PIN_PB22 54 ++#define PIN_PB22__GPIO PINMUX_PIN(PIN_PB22, 0, 0) ++#define PIN_PB22__QSPI1_IO3 PINMUX_PIN(PIN_PB22, 1, 1) ++#define PIN_PB22__FLEXCOM10_IO4 PINMUX_PIN(PIN_PB22, 2, 1) ++#define PIN_PB22__FLEXCOM9_IO6 PINMUX_PIN(PIN_PB22, 3, 1) ++#define PIN_PB22__NANDRDY PINMUX_PIN(PIN_PB22, 4, 1) ++#define PIN_PB23 55 ++#define PIN_PB23__GPIO PINMUX_PIN(PIN_PB23, 0, 0) ++#define PIN_PB23__QSPI1_IO2 PINMUX_PIN(PIN_PB23, 1, 1) ++#define PIN_PB23__FLEXCOM7_IO0 PINMUX_PIN(PIN_PB23, 2, 1) ++#define PIN_PB23__I2SMCC0_CK PINMUX_PIN(PIN_PB23, 3, 1) ++#define PIN_PB23__PCK4 PINMUX_PIN(PIN_PB23, 6, 1) ++#define PIN_PB24 56 ++#define PIN_PB24__GPIO PINMUX_PIN(PIN_PB24, 0, 0) ++#define PIN_PB24__QSPI1_IO1 PINMUX_PIN(PIN_PB24, 1, 1) ++#define PIN_PB24__FLEXCOM7_IO1 PINMUX_PIN(PIN_PB24, 2, 1) ++#define PIN_PB24__I2SMCC0_WS PINMUX_PIN(PIN_PB24, 3, 1) ++#define PIN_PB24__PCK5 PINMUX_PIN(PIN_PB24, 6, 1) ++#define PIN_PB25 57 ++#define PIN_PB25__GPIO PINMUX_PIN(PIN_PB25, 0, 0) ++#define PIN_PB25__QSPI1_IO0 PINMUX_PIN(PIN_PB25, 1, 1) ++#define PIN_PB25__FLEXCOM7_IO2 PINMUX_PIN(PIN_PB25, 2, 1) ++#define PIN_PB25__I2SMCC0_DOUT1 PINMUX_PIN(PIN_PB25, 3, 1) ++#define PIN_PB25__PCK6 PINMUX_PIN(PIN_PB25, 6, 1) ++#define PIN_PB26 58 ++#define PIN_PB26__GPIO PINMUX_PIN(PIN_PB26, 0, 0) ++#define PIN_PB26__QSPI1_CS PINMUX_PIN(PIN_PB26, 1, 1) ++#define PIN_PB26__FLEXCOM7_IO3 PINMUX_PIN(PIN_PB26, 2, 1) ++#define PIN_PB26__I2SMCC0_DOUT0 PINMUX_PIN(PIN_PB26, 3, 1) ++#define PIN_PB26__PWMEXTRG0 PINMUX_PIN(PIN_PB26, 5, 1) ++#define PIN_PB26__PCK7 PINMUX_PIN(PIN_PB26, 6, 1) ++#define PIN_PB27 59 ++#define PIN_PB27__GPIO PINMUX_PIN(PIN_PB27, 0, 0) ++#define PIN_PB27__QSPI1_SCK PINMUX_PIN(PIN_PB27, 1, 1) ++#define PIN_PB27__FLEXCOM7_IO4 PINMUX_PIN(PIN_PB27, 2, 1) ++#define PIN_PB27__I2SMCC0_MCK PINMUX_PIN(PIN_PB27, 3, 1) ++#define PIN_PB27__PWMEXTRG1 PINMUX_PIN(PIN_PB27, 5, 1) ++#define PIN_PB28 60 ++#define PIN_PB28__GPIO PINMUX_PIN(PIN_PB28, 0, 0) ++#define PIN_PB28__SDMMC1_RSTN PINMUX_PIN(PIN_PB28, 1, 1) ++#define PIN_PB28__ADTRG PINMUX_PIN(PIN_PB28, 2, 2) ++#define PIN_PB28__PWMFI0 PINMUX_PIN(PIN_PB28, 5, 1) ++#define PIN_PB28__FLEXCOM7_IO0 PINMUX_PIN(PIN_PB28, 6, 4) ++#define PIN_PB29 61 ++#define PIN_PB29__GPIO PINMUX_PIN(PIN_PB29, 0, 0) ++#define PIN_PB29__SDMMC1_CMD PINMUX_PIN(PIN_PB29, 1, 1) ++#define PIN_PB29__FLEXCOM3_IO2 PINMUX_PIN(PIN_PB29, 2, 2) ++#define PIN_PB29__FLEXCOM0_IO5 PINMUX_PIN(PIN_PB29, 3, 2) ++#define PIN_PB29__TIOA3 PINMUX_PIN(PIN_PB29, 4, 2) ++#define PIN_PB29__PWMFI1 PINMUX_PIN(PIN_PB29, 5, 1) ++#define PIN_PB29__FLEXCOM7_IO1 PINMUX_PIN(PIN_PB29, 6, 4) ++#define PIN_PB30 62 ++#define PIN_PB30__GPIO PINMUX_PIN(PIN_PB30, 0, 0) ++#define PIN_PB30__SDMMC1_CK PINMUX_PIN(PIN_PB30, 1, 1) ++#define PIN_PB30__FLEXCOM3_IO3 PINMUX_PIN(PIN_PB30, 2, 2) ++#define PIN_PB30__FLEXCOM0_IO6 PINMUX_PIN(PIN_PB30, 3, 2) ++#define PIN_PB30__TIOB3 PINMUX_PIN(PIN_PB30, 4, 1) ++#define PIN_PB30__PWMH0 PINMUX_PIN(PIN_PB30, 5, 1) ++#define PIN_PB30__FLEXCOM8_IO0 PINMUX_PIN(PIN_PB30, 6, 4) ++#define PIN_PB31 63 ++#define PIN_PB31__GPIO PINMUX_PIN(PIN_PB31, 0, 0) ++#define PIN_PB31__SDMMC1_DAT0 PINMUX_PIN(PIN_PB31, 1, 1) ++#define PIN_PB31__FLEXCOM3_IO4 PINMUX_PIN(PIN_PB31, 2, 2) ++#define PIN_PB31__FLEXCOM9_IO5 PINMUX_PIN(PIN_PB31, 3, 2) ++#define PIN_PB31__TCLK3 PINMUX_PIN(PIN_PB31, 4, 1) ++#define PIN_PB31__PWML0 PINMUX_PIN(PIN_PB31, 5, 1) ++#define PIN_PB31__FLEXCOM8_IO1 PINMUX_PIN(PIN_PB31, 6, 4) ++#define PIN_PC0 64 ++#define PIN_PC0__GPIO PINMUX_PIN(PIN_PC0, 0, 0) ++#define PIN_PC0__SDMMC1_DAT1 PINMUX_PIN(PIN_PC0, 1, 1) ++#define PIN_PC0__FLEXCOM3_IO0 PINMUX_PIN(PIN_PC0, 2, 2) ++#define PIN_PC0__TIOA4 PINMUX_PIN(PIN_PC0, 4, 1) ++#define PIN_PC0__PWML1 PINMUX_PIN(PIN_PC0, 5, 1) ++#define PIN_PC0__FLEXCOM9_IO0 PINMUX_PIN(PIN_PC0, 6, 4) ++#define PIN_PC1 65 ++#define PIN_PC1__GPIO PINMUX_PIN(PIN_PC1, 0, 0) ++#define PIN_PC1__SDMMC1_DAT2 PINMUX_PIN(PIN_PC1, 1, 1) ++#define PIN_PC1__FLEXCOM3_IO1 PINMUX_PIN(PIN_PC1, 2, 2) ++#define PIN_PC1__TIOB4 PINMUX_PIN(PIN_PC1, 4, 1) ++#define PIN_PC1__PWMH1 PINMUX_PIN(PIN_PC1, 5, 1) ++#define PIN_PC1__FLEXCOM9_IO1 PINMUX_PIN(PIN_PC1, 6, 4) ++#define PIN_PC2 66 ++#define PIN_PC2__GPIO PINMUX_PIN(PIN_PC2, 0, 0) ++#define PIN_PC2__SDMMC1_DAT3 PINMUX_PIN(PIN_PC2, 1, 1) ++#define PIN_PC2__FLEXCOM4_IO0 PINMUX_PIN(PIN_PC2, 2, 2) ++#define PIN_PC2__TCLK4 PINMUX_PIN(PIN_PC2, 4, 1) ++#define PIN_PC2__PWML2 PINMUX_PIN(PIN_PC2, 5, 1) ++#define PIN_PC2__FLEXCOM10_IO0 PINMUX_PIN(PIN_PC2, 6, 4) ++#define PIN_PC3 67 ++#define PIN_PC3__GPIO PINMUX_PIN(PIN_PC3, 0, 0) ++#define PIN_PC3__SDMMC1_WP PINMUX_PIN(PIN_PC3, 1, 1) ++#define PIN_PC3__FLEXCOM4_IO1 PINMUX_PIN(PIN_PC3, 2, 2) ++#define PIN_PC3__TIOA5 PINMUX_PIN(PIN_PC3, 4, 1) ++#define PIN_PC3__PWMH2 PINMUX_PIN(PIN_PC3, 5, 1) ++#define PIN_PC3__FLEXCOM10_IO1 PINMUX_PIN(PIN_PC3, 6, 4) ++#define PIN_PC4 68 ++#define PIN_PC4__GPIO PINMUX_PIN(PIN_PC4, 0, 0) ++#define PIN_PC4__SDMMC1_CD PINMUX_PIN(PIN_PC4, 1, 1) ++#define PIN_PC4__FLEXCOM4_IO2 PINMUX_PIN(PIN_PC4, 2, 2) ++#define PIN_PC4__FLEXCOM9_IO6 PINMUX_PIN(PIN_PC4, 3, 2) ++#define PIN_PC4__TIOB5 PINMUX_PIN(PIN_PC4, 4, 1) ++#define PIN_PC4__PWML3 PINMUX_PIN(PIN_PC4, 5, 1) ++#define PIN_PC4__FLEXCOM11_IO0 PINMUX_PIN(PIN_PC4, 6, 4) ++#define PIN_PC5 69 ++#define PIN_PC5__GPIO PINMUX_PIN(PIN_PC5, 0, 0) ++#define PIN_PC5__SDMMC1_1V8SEL PINMUX_PIN(PIN_PC5, 1, 1) ++#define PIN_PC5__FLEXCOM4_IO3 PINMUX_PIN(PIN_PC5, 2, 2) ++#define PIN_PC5__FLEXCOM6_IO5 PINMUX_PIN(PIN_PC5, 3, 2) ++#define PIN_PC5__TCLK5 PINMUX_PIN(PIN_PC5, 4, 1) ++#define PIN_PC5__PWMH3 PINMUX_PIN(PIN_PC5, 5, 1) ++#define PIN_PC5__FLEXCOM11_IO1 PINMUX_PIN(PIN_PC5, 6, 4) ++#define PIN_PC6 70 ++#define PIN_PC6__GPIO PINMUX_PIN(PIN_PC6, 0, 0) ++#define PIN_PC6__FLEXCOM4_IO4 PINMUX_PIN(PIN_PC6, 2, 2) ++#define PIN_PC6__FLEXCOM6_IO6 PINMUX_PIN(PIN_PC6, 3, 2) ++#define PIN_PC7 71 ++#define PIN_PC7__GPIO PINMUX_PIN(PIN_PC7, 0, 0) ++#define PIN_PC7__I2SMCC0_DIN0 PINMUX_PIN(PIN_PC7, 1, 1) ++#define PIN_PC7__FLEXCOM7_IO0 PINMUX_PIN(PIN_PC7, 2, 2) ++#define PIN_PC8 72 ++#define PIN_PC8__GPIO PINMUX_PIN(PIN_PC8, 0, 0) ++#define PIN_PC8__I2SMCC0_DIN1 PINMUX_PIN(PIN_PC8, 1, 1) ++#define PIN_PC8__FLEXCOM7_IO1 PINMUX_PIN(PIN_PC8, 2, 2) ++#define PIN_PC9 73 ++#define PIN_PC9__GPIO PINMUX_PIN(PIN_PC9, 0, 0) ++#define PIN_PC9__I2SMCC0_DOUT3 PINMUX_PIN(PIN_PC9, 1, 1) ++#define PIN_PC9__FLEXCOM7_IO2 PINMUX_PIN(PIN_PC9, 2, 2) ++#define PIN_PC9__FLEXCOM1_IO0 PINMUX_PIN(PIN_PC9, 6, 4) ++#define PIN_PC10 74 ++#define PIN_PC10__GPIO PINMUX_PIN(PIN_PC10, 0, 0) ++#define PIN_PC10__I2SMCC0_DOUT2 PINMUX_PIN(PIN_PC10, 1, 1) ++#define PIN_PC10__FLEXCOM7_IO3 PINMUX_PIN(PIN_PC10, 2, 2) ++#define PIN_PC10__FLEXCOM1_IO1 PINMUX_PIN(PIN_PC10, 6, 4) ++#define PIN_PC11 75 ++#define PIN_PC11__GPIO PINMUX_PIN(PIN_PC11, 0, 0) ++#define PIN_PC11__I2SMCC1_CK PINMUX_PIN(PIN_PC11, 1, 1) ++#define PIN_PC11__FLEXCOM7_IO4 PINMUX_PIN(PIN_PC11, 2, 2) ++#define PIN_PC11__FLEXCOM2_IO0 PINMUX_PIN(PIN_PC11, 6, 4) ++#define PIN_PC12 76 ++#define PIN_PC12__GPIO PINMUX_PIN(PIN_PC12, 0, 0) ++#define PIN_PC12__I2SMCC1_WS PINMUX_PIN(PIN_PC12, 1, 1) ++#define PIN_PC12__FLEXCOM8_IO2 PINMUX_PIN(PIN_PC12, 2, 2) ++#define PIN_PC12__FLEXCOM2_IO1 PINMUX_PIN(PIN_PC12, 6, 4) ++#define PIN_PC13 77 ++#define PIN_PC13__GPIO PINMUX_PIN(PIN_PC13, 0, 0) ++#define PIN_PC13__I2SMCC1_MCK PINMUX_PIN(PIN_PC13, 1, 1) ++#define PIN_PC13__FLEXCOM8_IO1 PINMUX_PIN(PIN_PC13, 2, 2) ++#define PIN_PC13__FLEXCOM3_IO0 PINMUX_PIN(PIN_PC13, 6, 4) ++#define PIN_PC14 78 ++#define PIN_PC14__GPIO PINMUX_PIN(PIN_PC14, 0, 0) ++#define PIN_PC14__I2SMCC1_DOUT0 PINMUX_PIN(PIN_PC14, 1, 1) ++#define PIN_PC14__FLEXCOM8_IO0 PINMUX_PIN(PIN_PC14, 2, 2) ++#define PIN_PC14__FLEXCOM3_IO1 PINMUX_PIN(PIN_PC14, 6, 4) ++#define PIN_PC15 79 ++#define PIN_PC15__GPIO PINMUX_PIN(PIN_PC15, 0, 0) ++#define PIN_PC15__I2SMCC1_DOUT1 PINMUX_PIN(PIN_PC15, 1, 1) ++#define PIN_PC15__FLEXCOM8_IO3 PINMUX_PIN(PIN_PC15, 2, 2) ++#define PIN_PC15__FLEXCOM4_IO0 PINMUX_PIN(PIN_PC15, 6, 4) ++#define PIN_PC16 80 ++#define PIN_PC16__GPIO PINMUX_PIN(PIN_PC16, 0, 0) ++#define PIN_PC16__I2SMCC1_DOUT2 PINMUX_PIN(PIN_PC16, 1, 1) ++#define PIN_PC16__FLEXCOM8_IO4 PINMUX_PIN(PIN_PC16, 2, 2) ++#define PIN_PC16__FLEXCOM3_IO1 PINMUX_PIN(PIN_PC16, 6, 4) ++#define PIN_PC17 81 ++#define PIN_PC17__GPIO PINMUX_PIN(PIN_PC17, 0, 0) ++#define PIN_PC17__I2SMCC1_DOUT3 PINMUX_PIN(PIN_PC17, 1, 1) ++#define PIN_PC17__EXT_IRQ0 PINMUX_PIN(PIN_PC17, 2, 3) ++#define PIN_PC17__FLEXCOM5_IO0 PINMUX_PIN(PIN_PC17, 6, 4) ++#define PIN_PC18 82 ++#define PIN_PC18__GPIO PINMUX_PIN(PIN_PC18, 0, 0) ++#define PIN_PC18__I2SMCC1_DIN0 PINMUX_PIN(PIN_PC18, 1, 1) ++#define PIN_PC18__FLEXCOM9_IO0 PINMUX_PIN(PIN_PC18, 2, 2) ++#define PIN_PC18__FLEXCOM5_IO1 PINMUX_PIN(PIN_PC18, 6, 4) ++#define PIN_PC19 83 ++#define PIN_PC19__GPIO PINMUX_PIN(PIN_PC19, 0, 0) ++#define PIN_PC19__I2SMCC1_DIN1 PINMUX_PIN(PIN_PC19, 1, 1) ++#define PIN_PC19__FLEXCOM9_IO1 PINMUX_PIN(PIN_PC19, 2, 2) ++#define PIN_PC19__FLEXCOM6_IO0 PINMUX_PIN(PIN_PC19, 6, 4) ++#define PIN_PC20 84 ++#define PIN_PC20__GPIO PINMUX_PIN(PIN_PC20, 0, 0) ++#define PIN_PC20__I2SMCC1_DIN2 PINMUX_PIN(PIN_PC20, 1, 1) ++#define PIN_PC20__FLEXCOM9_IO4 PINMUX_PIN(PIN_PC20, 2, 2) ++#define PIN_PC20__FLEXCOM6_IO1 PINMUX_PIN(PIN_PC20, 6, 4) ++#define PIN_PC21 85 ++#define PIN_PC21__GPIO PINMUX_PIN(PIN_PC21, 0, 0) ++#define PIN_PC21__I2SMCC1_DIN3 PINMUX_PIN(PIN_PC21, 1, 1) ++#define PIN_PC21__FLEXCOM9_IO2 PINMUX_PIN(PIN_PC21, 2, 2) ++#define PIN_PC21__D3 PINMUX_PIN(PIN_PC21, 4, 2) ++#define PIN_PC21__FLEXCOM6_IO0 PINMUX_PIN(PIN_PC21, 6, 5) ++#define PIN_PC22 86 ++#define PIN_PC22__GPIO PINMUX_PIN(PIN_PC22, 0, 0) ++#define PIN_PC22__I2SMCC0_DIN2 PINMUX_PIN(PIN_PC22, 1, 1) ++#define PIN_PC22__FLEXCOM9_IO3 PINMUX_PIN(PIN_PC22, 2, 2) ++#define PIN_PC22__D4 PINMUX_PIN(PIN_PC22, 4, 2) ++#define PIN_PC22__FLEXCOM6_IO1 PINMUX_PIN(PIN_PC22, 6, 5) ++#define PIN_PC23 87 ++#define PIN_PC23__GPIO PINMUX_PIN(PIN_PC23, 0, 0) ++#define PIN_PC23__I2SMCC0_DIN3 PINMUX_PIN(PIN_PC23, 1, 1) ++#define PIN_PC23__FLEXCOM0_IO5 PINMUX_PIN(PIN_PC23, 2, 3) ++#define PIN_PC23__D5 PINMUX_PIN(PIN_PC23, 4, 2) ++#define PIN_PC23__FLEXCOM7_IO0 PINMUX_PIN(PIN_PC23, 6, 5) ++#define PIN_PC24 88 ++#define PIN_PC24__GPIO PINMUX_PIN(PIN_PC24, 0, 0) ++#define PIN_PC24__FLEXCOM0_IO6 PINMUX_PIN(PIN_PC24, 2, 3) ++#define PIN_PC24__EXT_IRQ1 PINMUX_PIN(PIN_PC24, 3, 3) ++#define PIN_PC24__D6 PINMUX_PIN(PIN_PC24, 4, 2) ++#define PIN_PC24__FLEXCOM7_IO1 PINMUX_PIN(PIN_PC24, 6, 5) ++#define PIN_PC25 89 ++#define PIN_PC25__GPIO PINMUX_PIN(PIN_PC25, 0, 0) ++#define PIN_PC25__NTRST PINMUX_PIN(PIN_PC25, 1, 1) ++#define PIN_PC26 90 ++#define PIN_PC26__GPIO PINMUX_PIN(PIN_PC26, 0, 0) ++#define PIN_PC26__TCK_SWCLK PINMUX_PIN(PIN_PC26, 1, 1) ++#define PIN_PC27 91 ++#define PIN_PC27__GPIO PINMUX_PIN(PIN_PC27, 0, 0) ++#define PIN_PC27__TMS_SWDIO PINMUX_PIN(PIN_PC27, 1, 1) ++#define PIN_PC28 92 ++#define PIN_PC28__GPIO PINMUX_PIN(PIN_PC28, 0, 0) ++#define PIN_PC28__TDI PINMUX_PIN(PIN_PC28, 1, 1) ++#define PIN_PC29 93 ++#define PIN_PC29__GPIO PINMUX_PIN(PIN_PC29, 0, 0) ++#define PIN_PC29__TDO PINMUX_PIN(PIN_PC29, 1, 1) ++#define PIN_PC30 94 ++#define PIN_PC30__GPIO PINMUX_PIN(PIN_PC30, 0, 0) ++#define PIN_PC30__FLEXCOM10_IO0 PINMUX_PIN(PIN_PC30, 2, 2) ++#define PIN_PC31 95 ++#define PIN_PC31__GPIO PINMUX_PIN(PIN_PC31, 0, 0) ++#define PIN_PC31__FLEXCOM10_IO1 PINMUX_PIN(PIN_PC31, 2, 2) ++#define PIN_PD0 96 ++#define PIN_PD0__GPIO PINMUX_PIN(PIN_PD0, 0, 0) ++#define PIN_PD0__FLEXCOM11_IO0 PINMUX_PIN(PIN_PD0, 2, 2) ++#define PIN_PD1 97 ++#define PIN_PD1__GPIO PINMUX_PIN(PIN_PD1, 0, 0) ++#define PIN_PD1__FLEXCOM11_IO1 PINMUX_PIN(PIN_PD1, 2, 2) ++#define PIN_PD2 98 ++#define PIN_PD2__GPIO PINMUX_PIN(PIN_PD2, 0, 0) ++#define PIN_PD2__SDMMC2_RSTN PINMUX_PIN(PIN_PD2, 1, 1) ++#define PIN_PD2__PCK0 PINMUX_PIN(PIN_PD2, 2, 2) ++#define PIN_PD2__CANTX4 PINMUX_PIN(PIN_PD2, 3, 1) ++#define PIN_PD2__D7 PINMUX_PIN(PIN_PD2, 4, 2) ++#define PIN_PD2__TIOA0 PINMUX_PIN(PIN_PD2, 5, 2) ++#define PIN_PD2__FLEXCOM8_IO0 PINMUX_PIN(PIN_PD2, 6, 5) ++#define PIN_PD3 99 ++#define PIN_PD3__GPIO PINMUX_PIN(PIN_PD3, 0, 0) ++#define PIN_PD3__SDMMC2_CMD PINMUX_PIN(PIN_PD3, 1, 1) ++#define PIN_PD3__FLEXCOM0_IO0 PINMUX_PIN(PIN_PD3, 2, 2) ++#define PIN_PD3__CANRX4 PINMUX_PIN(PIN_PD3, 3, 1) ++#define PIN_PD3__NANDRDY PINMUX_PIN(PIN_PD3, 4, 2) ++#define PIN_PD3__TIOB0 PINMUX_PIN(PIN_PD3, 5, 2) ++#define PIN_PD3__FLEXCOM8_IO1 PINMUX_PIN(PIN_PD3, 6, 5) ++#define PIN_PD4 100 ++#define PIN_PD4__GPIO PINMUX_PIN(PIN_PD4, 0, 0) ++#define PIN_PD4__SDMMC2_CK PINMUX_PIN(PIN_PD4, 1, 1) ++#define PIN_PD4__FLEXCOM0_IO1 PINMUX_PIN(PIN_PD4, 2, 2) ++#define PIN_PD4__CANTX5 PINMUX_PIN(PIN_PD4, 3, 1) ++#define PIN_PD4__NCS3_NANDCS PINMUX_PIN(PIN_PD4, 4, 2) ++#define PIN_PD4__TCLK0 PINMUX_PIN(PIN_PD4, 5, 2) ++#define PIN_PD4__FLEXCOM9_IO0 PINMUX_PIN(PIN_PD4, 6, 5) ++#define PIN_PD5 101 ++#define PIN_PD5__GPIO PINMUX_PIN(PIN_PD5, 0, 0) ++#define PIN_PD5__SDMMC2_DAT0 PINMUX_PIN(PIN_PD5, 1, 1) ++#define PIN_PD5__FLEXCOM0_IO2 PINMUX_PIN(PIN_PD5, 2, 2) ++#define PIN_PD5__CANRX5 PINMUX_PIN(PIN_PD5, 3, 1) ++#define PIN_PD5__NWE_NWR0_NANDWE PINMUX_PIN(PIN_PD5, 4, 2) ++#define PIN_PD5__TIOA1 PINMUX_PIN(PIN_PD5, 5, 2) ++#define PIN_PD5__FLEXCOM9_IO1 PINMUX_PIN(PIN_PD5, 6, 5) ++#define PIN_PD6 102 ++#define PIN_PD6__GPIO PINMUX_PIN(PIN_PD6, 0, 0) ++#define PIN_PD6__SDMMC2_DAT1 PINMUX_PIN(PIN_PD6, 1, 1) ++#define PIN_PD6__FLEXCOM0_IO3 PINMUX_PIN(PIN_PD6, 2, 2) ++#define PIN_PD6__SPDIF_RX PINMUX_PIN(PIN_PD6, 3, 3) ++#define PIN_PD6__NRD_NANDOE PINMUX_PIN(PIN_PD6, 4, 2) ++#define PIN_PD6__TIOB1 PINMUX_PIN(PIN_PD6, 5, 2) ++#define PIN_PD6__FLEXCOM10_IO0 PINMUX_PIN(PIN_PD6, 6, 5) ++#define PIN_PD7 103 ++#define PIN_PD7__GPIO PINMUX_PIN(PIN_PD7, 0, 0) ++#define PIN_PD7__SDMMC2_DAT2 PINMUX_PIN(PIN_PD7, 1, 1) ++#define PIN_PD7__FLEXCOM0_IO4 PINMUX_PIN(PIN_PD7, 2, 2) ++#define PIN_PD7__SPDIF_TX PINMUX_PIN(PIN_PD7, 2, 2) ++#define PIN_PD7__A21_NANDALE PINMUX_PIN(PIN_PD7, 4, 2) ++#define PIN_PD7__TCLK1 PINMUX_PIN(PIN_PD7, 5, 2) ++#define PIN_PD7__FLEXCOM10_IO1 PINMUX_PIN(PIN_PD7, 6, 5) ++#define PIN_PD8 104 ++#define PIN_PD8__GPIO PINMUX_PIN(PIN_PD8, 0, 0) ++#define PIN_PD8__SDMMC2_DAT3 PINMUX_PIN(PIN_PD8, 1, 1) ++#define PIN_PD8__I2SMCC0_DIN0 PINMUX_PIN(PIN_PD8, 3, 1) ++#define PIN_PD8__A11_NANDCLE PINMUX_PIN(PIN_PD8, 4, 2) ++#define PIN_PD8__TIOA2 PINMUX_PIN(PIN_PD8, 5, 2) ++#define PIN_PD8__FLEXCOM11_IO0 PINMUX_PIN(PIN_PD8, 6, 5) ++#define PIN_PD9 105 ++#define PIN_PD9__GPIO PINMUX_PIN(PIN_PD9, 0, 0) ++#define PIN_PD9__SDMMC2_WP PINMUX_PIN(PIN_PD9, 1, 1) ++#define PIN_PD9__I2SMCC0_DIN1 PINMUX_PIN(PIN_PD9, 3, 2) ++#define PIN_PD9__D0 PINMUX_PIN(PIN_PD9, 4, 2) ++#define PIN_PD9__TIOB2 PINMUX_PIN(PIN_PD9, 5, 2) ++#define PIN_PD9__FLEXCOM11_IO1 PINMUX_PIN(PIN_PD9, 6, 5) ++#define PIN_PD10 106 ++#define PIN_PD10__GPIO PINMUX_PIN(PIN_PD10, 0, 0) ++#define PIN_PD10__SDMMC2_CD PINMUX_PIN(PIN_PD10, 1, 1) ++#define PIN_PD10__PCK6 PINMUX_PIN(PIN_PD10, 2, 2) ++#define PIN_PD10__I2SMCC0_DIN2 PINMUX_PIN(PIN_PD10, 3, 2) ++#define PIN_PD10__D1 PINMUX_PIN(PIN_PD10, 4, 2) ++#define PIN_PD10__TCLK2 PINMUX_PIN(PIN_PD10, 5, 2) ++#define PIN_PD10__FLEXCOM0_IO0 PINMUX_PIN(PIN_PD10, 6, 3) ++#define PIN_PD11 107 ++#define PIN_PD11__GPIO PINMUX_PIN(PIN_PD11, 0, 0) ++#define PIN_PD11__SDMMC2_1V8SEL PINMUX_PIN(PIN_PD11, 1, 1) ++#define PIN_PD11__PCK7 PINMUX_PIN(PIN_PD11, 2, 2) ++#define PIN_PD11__I2SMCC0_DIN3 PINMUX_PIN(PIN_PD11, 3, 2) ++#define PIN_PD11__D2 PINMUX_PIN(PIN_PD11, 4, 2) ++#define PIN_PD11__TIOA3 PINMUX_PIN(PIN_PD11, 5, 2) ++#define PIN_PD11__FLEXCOM0_IO1 PINMUX_PIN(PIN_PD11, 6, 3) ++#define PIN_PD12 108 ++#define PIN_PD12__GPIO PINMUX_PIN(PIN_PD12, 0, 0) ++#define PIN_PD12__PCK1 PINMUX_PIN(PIN_PD12, 1, 2) ++#define PIN_PD12__FLEXCOM1_IO0 PINMUX_PIN(PIN_PD12, 2, 2) ++#define PIN_PD12__CANTX0 PINMUX_PIN(PIN_PD12, 4, 2) ++#define PIN_PD12__TIOB3 PINMUX_PIN(PIN_PD12, 5, 2) ++#define PIN_PD13 109 ++#define PIN_PD13__GPIO PINMUX_PIN(PIN_PD13, 0, 0) ++#define PIN_PD13__I2SMCC0_CK PINMUX_PIN(PIN_PD13, 1, 2) ++#define PIN_PD13__FLEXCOM1_IO1 PINMUX_PIN(PIN_PD13, 2, 2) ++#define PIN_PD13__PWML0 PINMUX_PIN(PIN_PD13, 3, 4) ++#define PIN_PD13__CANRX0 PINMUX_PIN(PIN_PD13, 4, 2) ++#define PIN_PD13__TCLK3 PINMUX_PIN(PIN_PD13, 5, 2) ++#define PIN_PD14 110 ++#define PIN_PD14__GPIO PINMUX_PIN(PIN_PD14, 0, 0) ++#define PIN_PD14__I2SMCC0_MCK PINMUX_PIN(PIN_PD14, 1, 2) ++#define PIN_PD14__FLEXCOM1_IO2 PINMUX_PIN(PIN_PD14, 2, 2) ++#define PIN_PD14__PWMH0 PINMUX_PIN(PIN_PD14, 3, 4) ++#define PIN_PD14__CANTX1 PINMUX_PIN(PIN_PD14, 4, 2) ++#define PIN_PD14__TIOA4 PINMUX_PIN(PIN_PD14, 5, 2) ++#define PIN_PD14__FLEXCOM2_IO0 PINMUX_PIN(PIN_PD14, 6, 5) ++#define PIN_PD15 111 ++#define PIN_PD15__GPIO PINMUX_PIN(PIN_PD15, 0, 0) ++#define PIN_PD15__I2SMCC0_WS PINMUX_PIN(PIN_PD15, 1, 2) ++#define PIN_PD15__FLEXCOM1_IO3 PINMUX_PIN(PIN_PD15, 2, 2) ++#define PIN_PD15__PWML1 PINMUX_PIN(PIN_PD15, 3, 4) ++#define PIN_PD15__CANRX1 PINMUX_PIN(PIN_PD15, 4, 2) ++#define PIN_PD15__TIOB4 PINMUX_PIN(PIN_PD15, 5, 2) ++#define PIN_PD15__FLEXCOM2_IO1 PINMUX_PIN(PIN_PD15, 6, 5) ++#define PIN_PD16 112 ++#define PIN_PD16__GPIO PINMUX_PIN(PIN_PD16, 0, 0) ++#define PIN_PD16__I2SMCC0_DOUT0 PINMUX_PIN(PIN_PD16, 1, 2) ++#define PIN_PD16__FLEXCOM1_IO4 PINMUX_PIN(PIN_PD16, 2, 2) ++#define PIN_PD16__PWMH1 PINMUX_PIN(PIN_PD16, 3, 4) ++#define PIN_PD16__CANTX2 PINMUX_PIN(PIN_PD16, 4, 2) ++#define PIN_PD16__TCLK4 PINMUX_PIN(PIN_PD16, 5, 2) ++#define PIN_PD16__FLEXCOM3_IO0 PINMUX_PIN(PIN_PD16, 6, 5) ++#define PIN_PD17 113 ++#define PIN_PD17__GPIO PINMUX_PIN(PIN_PD17, 0, 0) ++#define PIN_PD17__I2SMCC0_DOUT1 PINMUX_PIN(PIN_PD17, 1, 2) ++#define PIN_PD17__FLEXCOM2_IO0 PINMUX_PIN(PIN_PD17, 2, 2) ++#define PIN_PD17__PWML2 PINMUX_PIN(PIN_PD17, 3, 4) ++#define PIN_PD17__CANRX2 PINMUX_PIN(PIN_PD17, 4, 2) ++#define PIN_PD17__TIOA5 PINMUX_PIN(PIN_PD17, 5, 2) ++#define PIN_PD17__FLEXCOM3_IO1 PINMUX_PIN(PIN_PD17, 6, 5) ++#define PIN_PD18 114 ++#define PIN_PD18__GPIO PINMUX_PIN(PIN_PD18, 0, 0) ++#define PIN_PD18__I2SMCC0_DOUT2 PINMUX_PIN(PIN_PD18, 1, 2) ++#define PIN_PD18__FLEXCOM2_IO1 PINMUX_PIN(PIN_PD18, 2, 2) ++#define PIN_PD18__PWMH2 PINMUX_PIN(PIN_PD18, 3, 4) ++#define PIN_PD18__CANTX3 PINMUX_PIN(PIN_PD18, 4, 2) ++#define PIN_PD18__TIOB5 PINMUX_PIN(PIN_PD18, 5, 2) ++#define PIN_PD18__FLEXCOM4_IO0 PINMUX_PIN(PIN_PD18, 6, 5) ++#define PIN_PD19 115 ++#define PIN_PD19__GPIO PINMUX_PIN(PIN_PD19, 0, 0) ++#define PIN_PD19__I2SMCC0_DOUT3 PINMUX_PIN(PIN_PD19, 1, 2) ++#define PIN_PD19__FLEXCOM2_IO2 PINMUX_PIN(PIN_PD19, 2, 2) ++#define PIN_PD19__PWML3 PINMUX_PIN(PIN_PD19, 3, 4) ++#define PIN_PD19__CANRX3 PINMUX_PIN(PIN_PD19, 4, 2) ++#define PIN_PD19__TCLK5 PINMUX_PIN(PIN_PD19, 5, 2) ++#define PIN_PD19__FLEXCOM4_IO1 PINMUX_PIN(PIN_PD19, 6, 5) ++#define PIN_PD20 116 ++#define PIN_PD20__GPIO PINMUX_PIN(PIN_PD20, 0, 0) ++#define PIN_PD20__PCK0 PINMUX_PIN(PIN_PD20, 1, 3) ++#define PIN_PD20__FLEXCOM2_IO3 PINMUX_PIN(PIN_PD20, 2, 2) ++#define PIN_PD20__PWMH3 PINMUX_PIN(PIN_PD20, 3, 4) ++#define PIN_PD20__CANTX4 PINMUX_PIN(PIN_PD20, 5, 2) ++#define PIN_PD20__FLEXCOM5_IO0 PINMUX_PIN(PIN_PD20, 6, 5) ++#define PIN_PD21 117 ++#define PIN_PD21__GPIO PINMUX_PIN(PIN_PD21, 0, 0) ++#define PIN_PD21__PCK1 PINMUX_PIN(PIN_PD21, 1, 3) ++#define PIN_PD21__FLEXCOM2_IO4 PINMUX_PIN(PIN_PD21, 2, 2) ++#define PIN_PD21__CANRX4 PINMUX_PIN(PIN_PD21, 4, 2) ++#define PIN_PD21__FLEXCOM5_IO1 PINMUX_PIN(PIN_PD21, 6, 5) ++#define PIN_PD21__G1_TXEN PINMUX_PIN(PIN_PD21, 7, 1) ++#define PIN_PD22 118 ++#define PIN_PD22__GPIO PINMUX_PIN(PIN_PD22, 0, 0) ++#define PIN_PD22__PDMC0_CLK PINMUX_PIN(PIN_PD22, 1, 2) ++#define PIN_PD22__PWMEXTRG0 PINMUX_PIN(PIN_PD22, 3, 4) ++#define PIN_PD22__RD1 PINMUX_PIN(PIN_PD22, 4, 2) ++#define PIN_PD22__CANTX5 PINMUX_PIN(PIN_PD22, 6, 2) ++#define PIN_PD22__G1_TX0 PINMUX_PIN(PIN_PD22, 7, 1) ++#define PIN_PD23 119 ++#define PIN_PD23__GPIO PINMUX_PIN(PIN_PD23, 0, 0) ++#define PIN_PD23__PDMC0_DS0 PINMUX_PIN(PIN_PD23, 1, 2) ++#define PIN_PD23__PWMEXTRG1 PINMUX_PIN(PIN_PD23, 3, 4) ++#define PIN_PD23__RF1 PINMUX_PIN(PIN_PD23, 4, 2) ++#define PIN_PD23__ISC_MCK PINMUX_PIN(PIN_PD23, 5, 2) ++#define PIN_PD23__CANRX5 PINMUX_PIN(PIN_PD23, 6, 2) ++#define PIN_PD23__G1_TX1 PINMUX_PIN(PIN_PD23, 7, 1) ++#define PIN_PD24 120 ++#define PIN_PD24__GPIO PINMUX_PIN(PIN_PD24, 0, 0) ++#define PIN_PD24__PDMC0_DS1 PINMUX_PIN(PIN_PD24, 1, 2) ++#define PIN_PD24__PWMFI0 PINMUX_PIN(PIN_PD24, 3, 4) ++#define PIN_PD24__RK1 PINMUX_PIN(PIN_PD24, 4, 2) ++#define PIN_PD24__ISC_D0 PINMUX_PIN(PIN_PD24, 5, 2) ++#define PIN_PD24__G1_RXDV PINMUX_PIN(PIN_PD24, 7, 1) ++#define PIN_PD25 121 ++#define PIN_PD25__GPIO PINMUX_PIN(PIN_PD25, 0, 0) ++#define PIN_PD25__PDMC1_CLK PINMUX_PIN(PIN_PD25, 1, 2) ++#define PIN_PD25__FLEXCOM5_IO0 PINMUX_PIN(PIN_PD25, 2, 2) ++#define PIN_PD25__PWMFI1 PINMUX_PIN(PIN_PD25, 3, 4) ++#define PIN_PD25__TD1 PINMUX_PIN(PIN_PD25, 4, 2) ++#define PIN_PD25__ISC_D1 PINMUX_PIN(PIN_PD25, 5, 2) ++#define PIN_PD25__G1_RX0 PINMUX_PIN(PIN_PD25, 7, 1) ++#define PIN_PD26 122 ++#define PIN_PD26__GPIO PINMUX_PIN(PIN_PD26, 0, 0) ++#define PIN_PD26__PDMC1_DS0 PINMUX_PIN(PIN_PD26, 1, 2) ++#define PIN_PD26__FLEXCOM5_IO1 PINMUX_PIN(PIN_PD26, 2, 2) ++#define PIN_PD26__ADTRG PINMUX_PIN(PIN_PD26, 3, 3) ++#define PIN_PD26__TF1 PINMUX_PIN(PIN_PD26, 4, 2) ++#define PIN_PD26__ISC_D2 PINMUX_PIN(PIN_PD26, 5, 2) ++#define PIN_PD26__G1_RX1 PINMUX_PIN(PIN_PD26, 7, 1) ++#define PIN_PD27 123 ++#define PIN_PD27__GPIO PINMUX_PIN(PIN_PD27, 0, 0) ++#define PIN_PD27__PDMC1_DS1 PINMUX_PIN(PIN_PD27, 1, 2) ++#define PIN_PD27__FLEXCOM5_IO2 PINMUX_PIN(PIN_PD27, 2, 2) ++#define PIN_PD27__TIOA0 PINMUX_PIN(PIN_PD27, 3, 3) ++#define PIN_PD27__TK1 PINMUX_PIN(PIN_PD27, 4, 2) ++#define PIN_PD27__ISC_D3 PINMUX_PIN(PIN_PD27, 5, 2) ++#define PIN_PD27__G1_RXER PINMUX_PIN(PIN_PD27, 7, 1) ++#define PIN_PD28 124 ++#define PIN_PD28__GPIO PINMUX_PIN(PIN_PD28, 0, 0) ++#define PIN_PD28__RD0 PINMUX_PIN(PIN_PD28, 1, 2) ++#define PIN_PD28__FLEXCOM5_IO3 PINMUX_PIN(PIN_PD28, 2, 2) ++#define PIN_PD28__TIOB0 PINMUX_PIN(PIN_PD28, 3, 3) ++#define PIN_PD28__I2SMCC1_CK PINMUX_PIN(PIN_PD28, 4, 2) ++#define PIN_PD28__ISC_D4 PINMUX_PIN(PIN_PD28, 5, 2) ++#define PIN_PD28__PWML3 PINMUX_PIN(PIN_PD28, 6, 5) ++#define PIN_PD28__G1_MDC PINMUX_PIN(PIN_PD28, 7, 1) ++#define PIN_PD29 125 ++#define PIN_PD29__GPIO PINMUX_PIN(PIN_PD29, 0, 0) ++#define PIN_PD29__RF0 PINMUX_PIN(PIN_PD29, 1, 2) ++#define PIN_PD29__FLEXCOM5_IO4 PINMUX_PIN(PIN_PD29, 2, 2) ++#define PIN_PD29__TCLK0 PINMUX_PIN(PIN_PD29, 3, 3) ++#define PIN_PD29__I2SMCC1_WS PINMUX_PIN(PIN_PD29, 4, 2) ++#define PIN_PD29__ISC_D5 PINMUX_PIN(PIN_PD29, 5, 2) ++#define PIN_PD29__PWMH3 PINMUX_PIN(PIN_PD29, 6, 5) ++#define PIN_PD29__G1_MDIO PINMUX_PIN(PIN_PD29, 7, 1) ++#define PIN_PD30 126 ++#define PIN_PD30__GPIO PINMUX_PIN(PIN_PD30, 0, 0) ++#define PIN_PD30__RK0 PINMUX_PIN(PIN_PD30, 1, 2) ++#define PIN_PD30__FLEXCOM6_IO0 PINMUX_PIN(PIN_PD30, 2, 2) ++#define PIN_PD30__TIOA1 PINMUX_PIN(PIN_PD30, 3, 3) ++#define PIN_PD30__I2SMCC1_MCK PINMUX_PIN(PIN_PD30, 4, 2) ++#define PIN_PD30__ISC_D6 PINMUX_PIN(PIN_PD30, 5, 2) ++#define PIN_PD30__PWMEXTRG0 PINMUX_PIN(PIN_PD30, 6, 5) ++#define PIN_PD30__G1_TXCK PINMUX_PIN(PIN_PD30, 7, 1) ++#define PIN_PD31 127 ++#define PIN_PD31__GPIO PINMUX_PIN(PIN_PD31, 0, 0) ++#define PIN_PD31__TD0 PINMUX_PIN(PIN_PD31, 1, 2) ++#define PIN_PD31__FLEXCOM6_IO1 PINMUX_PIN(PIN_PD31, 2, 2) ++#define PIN_PD31__TIOB1 PINMUX_PIN(PIN_PD31, 3, 3) ++#define PIN_PD31__I2SMCC1_DOUT0 PINMUX_PIN(PIN_PD31, 4, 2) ++#define PIN_PD31__ISC_D7 PINMUX_PIN(PIN_PD31, 5, 2) ++#define PIN_PD31__PWM_EXTRG1 PINMUX_PIN(PIN_PD31, 6, 5) ++#define PIN_PD31__G1_TX2 PINMUX_PIN(PIN_PD31, 7, 1) ++#define PIN_PE0 128 ++#define PIN_PE0__GPIO PINMUX_PIN(PIN_PE0, 0, 0) ++#define PIN_PE0__TF0 PINMUX_PIN(PIN_PE0, 1, 2) ++#define PIN_PE0__FLEXCOM6_IO2 PINMUX_PIN(PIN_PE0, 2, 2) ++#define PIN_PE0__TCLK1 PINMUX_PIN(PIN_PE0, 3, 3) ++#define PIN_PE0__I2SMCC1_DOUT1 PINMUX_PIN(PIN_PE0, 4, 2) ++#define PIN_PE0__ISC_HSYNC PINMUX_PIN(PIN_PE0, 5, 2) ++#define PIN_PE0__PWMFI0 PINMUX_PIN(PIN_PE0, 6, 5) ++#define PIN_PE0__G1_TX3 PINMUX_PIN(PIN_PE0, 7, 1) ++#define PIN_PE1 129 ++#define PIN_PE1__GPIO PINMUX_PIN(PIN_PE1, 0, 0) ++#define PIN_PE1__TK0 PINMUX_PIN(PIN_PE1, 1, 2) ++#define PIN_PE1__FLEXCOM6_IO3 PINMUX_PIN(PIN_PE1, 2, 2) ++#define PIN_PE1__TIOA2 PINMUX_PIN(PIN_PE1, 3, 3) ++#define PIN_PE1__I2SMCC1_DOUT2 PINMUX_PIN(PIN_PE1, 4, 2) ++#define PIN_PE1__ISC_VSYNC PINMUX_PIN(PIN_PE1, 5, 2) ++#define PIN_PE1__PWMFI1 PINMUX_PIN(PIN_PE1, 6, 5) ++#define PIN_PE1__G1_RX2 PINMUX_PIN(PIN_PE1, 7, 1) ++#define PIN_PE2 130 ++#define PIN_PE2__GPIO PINMUX_PIN(PIN_PE2, 0, 0) ++#define PIN_PE2__PWML0 PINMUX_PIN(PIN_PE2, 1, 5) ++#define PIN_PE2__FLEXCOM6_IO4 PINMUX_PIN(PIN_PE2, 2, 2) ++#define PIN_PE2__TIOB2 PINMUX_PIN(PIN_PE2, 3, 3) ++#define PIN_PE2__I2SMCC1_DOUT3 PINMUX_PIN(PIN_PE2, 4, 2) ++#define PIN_PE2__ISC_FIELD PINMUX_PIN(PIN_PE2, 5, 2) ++#define PIN_PE2__G1_RX3 PINMUX_PIN(PIN_PE2, 7, 1) ++#define PIN_PE3 131 ++#define PIN_PE3__GPIO PINMUX_PIN(PIN_PE3, 0, 0) ++#define PIN_PE3__PWMH0 PINMUX_PIN(PIN_PE3, 1, 5) ++#define PIN_PE3__FLEXCOM0_IO0 PINMUX_PIN(PIN_PE3, 2, 4) ++#define PIN_PE3__TCLK2 PINMUX_PIN(PIN_PE3, 3, 3) ++#define PIN_PE3__I2SMCC1_DIN0 PINMUX_PIN(PIN_PE3, 4, 2) ++#define PIN_PE3__ISC_PCK PINMUX_PIN(PIN_PE3, 5, 2) ++#define PIN_PE3__G1_RXCK PINMUX_PIN(PIN_PE3, 7, 1) ++#define PIN_PE4 132 ++#define PIN_PE4__GPIO PINMUX_PIN(PIN_PE4, 0, 0) ++#define PIN_PE4__PWML1 PINMUX_PIN(PIN_PE4, 1, 5) ++#define PIN_PE4__FLEXCOM0_IO1 PINMUX_PIN(PIN_PE4, 2, 4) ++#define PIN_PE4__TIOA3 PINMUX_PIN(PIN_PE4, 3, 3) ++#define PIN_PE4__I2SMCC1_DIN1 PINMUX_PIN(PIN_PE4, 4, 2) ++#define PIN_PE4__ISC_D8 PINMUX_PIN(PIN_PE4, 5, 2) ++#define PIN_PE4__G1_TXER PINMUX_PIN(PIN_PE4, 7, 1) ++#define PIN_PE5 133 ++#define PIN_PE5__GPIO PINMUX_PIN(PIN_PE5, 0, 0) ++#define PIN_PE5__PWMH1 PINMUX_PIN(PIN_PE5, 1, 5) ++#define PIN_PE5__FLEXCOM0_IO2 PINMUX_PIN(PIN_PE5, 2, 4) ++#define PIN_PE5__TIOB3 PINMUX_PIN(PIN_PE5, 3, 3) ++#define PIN_PE5__I2SMCC1_DIN2 PINMUX_PIN(PIN_PE5, 4, 2) ++#define PIN_PE5__ISC_D9 PINMUX_PIN(PIN_PE5, 5, 2) ++#define PIN_PE5__G1_COL PINMUX_PIN(PIN_PE5, 7, 1) ++#define PIN_PE6 134 ++#define PIN_PE6__GPIO PINMUX_PIN(PIN_PE6, 0, 0) ++#define PIN_PE6__PWML2 PINMUX_PIN(PIN_PE6, 1, 5) ++#define PIN_PE6__FLEXCOM0_IO3 PINMUX_PIN(PIN_PE6, 2, 4) ++#define PIN_PE6__TCLK3 PINMUX_PIN(PIN_PE6, 3, 3) ++#define PIN_PE6__I2SMCC1_DIN3 PINMUX_PIN(PIN_PE6, 4, 2) ++#define PIN_PE6__ISC_D10 PINMUX_PIN(PIN_PE6, 5, 2) ++#define PIN_PE6__G1_CRS PINMUX_PIN(PIN_PE6, 7, 1) ++#define PIN_PE7 135 ++#define PIN_PE7__GPIO PINMUX_PIN(PIN_PE7, 0, 0) ++#define PIN_PE7__PWMH2 PINMUX_PIN(PIN_PE7, 1, 5) ++#define PIN_PE7__FLEXCOM0_IO4 PINMUX_PIN(PIN_PE7, 2, 4) ++#define PIN_PE7__TIOA4 PINMUX_PIN(PIN_PE7, 3, 3) ++#define PIN_PE7__ISC_D11 PINMUX_PIN(PIN_PE7, 5, 2) ++#define PIN_PE7__G1_TSUCOMP PINMUX_PIN(PIN_PE7, 7, 1) +diff --git a/arch/arm/boot/dts/sama7g5.dtsi b/arch/arm/boot/dts/sama7g5.dtsi +new file mode 100644 +index 000000000000..cc6be6db7b80 +--- /dev/null ++++ b/arch/arm/boot/dts/sama7g5.dtsi +@@ -0,0 +1,528 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * sama7g5.dtsi - Device Tree Include file for SAMA7G5 family SoC ++ * ++ * Copyright (C) 2020 Microchip Technology, Inc. and its subsidiaries ++ * ++ * Author: Eugen Hristev <eugen.hristev@microchip.com> ++ * Author: Claudiu Beznea <claudiu.beznea@microchip.com> ++ * ++ */ ++ ++#include <dt-bindings/interrupt-controller/irq.h> ++#include <dt-bindings/interrupt-controller/arm-gic.h> ++#include <dt-bindings/clock/at91.h> ++#include <dt-bindings/dma/at91.h> ++#include <dt-bindings/gpio/gpio.h> ++ ++/ { ++ model = "Microchip SAMA7G5 family SoC"; ++ compatible = "microchip,sama7g5"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu0: cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0x0>; ++ }; ++ }; ++ ++ clocks { ++ slow_xtal: slow_xtal { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ }; ++ ++ main_xtal: main_xtal { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ }; ++ ++ usb_clk: usb_clk { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <48000000>; ++ }; ++ }; ++ ++ vddout25: fixed-regulator-vddout25 { ++ compatible = "regulator-fixed"; ++ ++ regulator-name = "VDDOUT25"; ++ regulator-min-microvolt = <2500000>; ++ regulator-max-microvolt = <2500000>; ++ regulator-boot-on; ++ status = "disabled"; ++ }; ++ ++ ns_sram: sram@100000 { ++ compatible = "mmio-sram"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x100000 0x20000>; ++ ranges; ++ }; ++ ++ soc { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ secumod: secumod@e0004000 { ++ compatible = "microchip,sama7g5-secumod", "atmel,sama5d2-secumod", "syscon"; ++ reg = <0xe0004000 0x4000>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ }; ++ ++ sfrbu: sfr@e0008000 { ++ compatible = "microchip,sama7g5-sfrbu", "atmel,sama5d2-sfrbu", "syscon"; ++ reg = <0xe0008000 0x20>; ++ }; ++ ++ pioA: pinctrl@e0014000 { ++ compatible = "microchip,sama7g5-pinctrl"; ++ reg = <0xe0014000 0x800>; ++ interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>, ++ <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 11>; ++ }; ++ ++ pmc: pmc@e0018000 { ++ compatible = "microchip,sama7g5-pmc", "syscon"; ++ reg = <0xe0018000 0x200>; ++ interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; ++ #clock-cells = <2>; ++ clocks = <&clk32k 1>, <&clk32k 0>, <&main_xtal>; ++ clock-names = "td_slck", "md_slck", "main_xtal"; ++ }; ++ ++ rtt: rtt@e001d020 { ++ compatible = "microchip,sama7g5-rtt", "microchip,sam9x60-rtt", "atmel,at91sam9260-rtt"; ++ reg = <0xe001d020 0x30>; ++ interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&clk32k 0>; ++ }; ++ ++ clk32k: clock-controller@e001d050 { ++ compatible = "microchip,sama7g5-sckc", "microchip,sam9x60-sckc"; ++ reg = <0xe001d050 0x4>; ++ clocks = <&slow_xtal>; ++ #clock-cells = <1>; ++ }; ++ ++ gpbr: gpbr@e001d060 { ++ compatible = "microchip,sama7g5-gpbr", "syscon"; ++ reg = <0xe001d060 0x48>; ++ }; ++ ++ ps_wdt: watchdog@e001d180 { ++ compatible = "microchip,sama7g5-wdt"; ++ reg = <0xe001d180 0x24>; ++ interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&clk32k 0>; ++ }; ++ ++ sdmmc0: mmc@e1204000 { ++ compatible = "microchip,sama7g5-sdhci", "microchip,sam9x60-sdhci"; ++ reg = <0xe1204000 0x4000>; ++ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 80>, <&pmc PMC_TYPE_GCK 80>; ++ clock-names = "hclock", "multclk"; ++ assigned-clock-parents = <&pmc PMC_TYPE_CORE PMC_SYSPLL>; ++ assigned-clocks = <&pmc PMC_TYPE_GCK 80>; ++ assigned-clock-rates = <200000000>; ++ microchip,sdcal-inverted; ++ status = "disabled"; ++ }; ++ ++ sdmmc1: mmc@e1208000 { ++ compatible = "microchip,sama7g5-sdhci", "microchip,sam9x60-sdhci"; ++ reg = <0xe1208000 0x4000>; ++ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 81>, <&pmc PMC_TYPE_GCK 81>; ++ clock-names = "hclock", "multclk"; ++ assigned-clock-parents = <&pmc PMC_TYPE_CORE PMC_SYSPLL>; ++ assigned-clocks = <&pmc PMC_TYPE_GCK 81>; ++ assigned-clock-rates = <200000000>; ++ microchip,sdcal-inverted; ++ status = "disabled"; ++ }; ++ ++ sdmmc2: mmc@e120c000 { ++ compatible = "microchip,sama7g5-sdhci", "microchip,sam9x60-sdhci"; ++ reg = <0xe120c000 0x4000>; ++ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 82>, <&pmc PMC_TYPE_GCK 82>; ++ clock-names = "hclock", "multclk"; ++ assigned-clock-parents = <&pmc PMC_TYPE_CORE PMC_SYSPLL>; ++ assigned-clocks = <&pmc PMC_TYPE_GCK 82>; ++ assigned-clock-rates = <200000000>; ++ microchip,sdcal-inverted; ++ status = "disabled"; ++ }; ++ ++ pwm: pwm@e1604000 { ++ compatible = "microchip,sama7g5-pwm", "atmel,sama5d2-pwm"; ++ reg = <0xe1604000 0x4000>; ++ interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; ++ #pwm-cells = <3>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 77>; ++ status = "disabled"; ++ }; ++ ++ spdifrx: spdifrx@e1614000 { ++ #sound-dai-cells = <0>; ++ compatible = "microchip,sama7g5-spdifrx"; ++ reg = <0xe1614000 0x4000>; ++ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>; ++ dmas = <&dma0 AT91_XDMAC_DT_PERID(49)>; ++ dma-names = "rx"; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 84>, <&pmc PMC_TYPE_GCK 84>; ++ clock-names = "pclk", "gclk"; ++ status = "disabled"; ++ }; ++ ++ spdiftx: spdiftx@e1618000 { ++ #sound-dai-cells = <0>; ++ compatible = "microchip,sama7g5-spdiftx"; ++ reg = <0xe1618000 0x4000>; ++ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; ++ dmas = <&dma0 AT91_XDMAC_DT_PERID(50)>; ++ dma-names = "tx"; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 85>, <&pmc PMC_TYPE_GCK 85>; ++ clock-names = "pclk", "gclk"; ++ }; ++ ++ i2s0: i2s@e161c000 { ++ compatible = "microchip,sama7g5-i2smcc"; ++ #sound-dai-cells = <0>; ++ reg = <0xe161c000 0x4000>; ++ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>; ++ dmas = <&dma0 AT91_XDMAC_DT_PERID(34)>, <&dma0 AT91_XDMAC_DT_PERID(33)>; ++ dma-names = "tx", "rx"; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 57>, <&pmc PMC_TYPE_GCK 57>; ++ clock-names = "pclk", "gclk"; ++ status = "disabled"; ++ }; ++ ++ i2s1: i2s@e1620000 { ++ compatible = "microchip,sama7g5-i2smcc"; ++ #sound-dai-cells = <0>; ++ reg = <0xe1620000 0x4000>; ++ interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>; ++ dmas = <&dma0 AT91_XDMAC_DT_PERID(36)>, <&dma0 AT91_XDMAC_DT_PERID(35)>; ++ dma-names = "tx", "rx"; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 58>, <&pmc PMC_TYPE_GCK 58>; ++ clock-names = "pclk", "gclk"; ++ status = "disabled"; ++ }; ++ ++ pit64b0: timer@e1800000 { ++ compatible = "microchip,sama7g5-pit64b", "microchip,sam9x60-pit64b"; ++ reg = <0xe1800000 0x4000>; ++ interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 70>, <&pmc PMC_TYPE_GCK 70>; ++ clock-names = "pclk", "gclk"; ++ }; ++ ++ pit64b1: timer@e1804000 { ++ compatible = "microchip,sama7g5-pit64b", "microchip,sam9x60-pit64b"; ++ reg = <0xe1804000 0x4000>; ++ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 71>, <&pmc PMC_TYPE_GCK 71>; ++ clock-names = "pclk", "gclk"; ++ }; ++ ++ flx0: flexcom@e1818000 { ++ compatible = "atmel,sama5d2-flexcom"; ++ reg = <0xe1818000 0x200>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 38>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0x0 0xe1818000 0x800>; ++ status = "disabled"; ++ ++ uart0: serial@200 { ++ compatible = "atmel,at91sam9260-usart"; ++ reg = <0x200 0x200>; ++ interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 38>; ++ clock-names = "usart"; ++ dmas = <&dma1 AT91_XDMAC_DT_PERID(6)>, ++ <&dma1 AT91_XDMAC_DT_PERID(5)>; ++ dma-names = "tx", "rx"; ++ atmel,use-dma-rx; ++ atmel,use-dma-tx; ++ status = "disabled"; ++ }; ++ }; ++ ++ flx1: flexcom@e181c000 { ++ compatible = "atmel,sama5d2-flexcom"; ++ reg = <0xe181c000 0x200>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 39>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0x0 0xe181c000 0x800>; ++ status = "disabled"; ++ ++ i2c1: i2c@600 { ++ compatible = "microchip,sama7g5-i2c", "microchip,sam9x60-i2c"; ++ reg = <0x600 0x200>; ++ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 39>; ++ atmel,fifo-size = <32>; ++ dmas = <&dma0 AT91_XDMAC_DT_PERID(7)>, ++ <&dma0 AT91_XDMAC_DT_PERID(8)>; ++ dma-names = "rx", "tx"; ++ atmel,use-dma-rx; ++ atmel,use-dma-tx; ++ status = "disabled"; ++ }; ++ }; ++ ++ flx3: flexcom@e1824000 { ++ compatible = "atmel,sama5d2-flexcom"; ++ reg = <0xe1824000 0x200>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 41>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0x0 0xe1824000 0x800>; ++ status = "disabled"; ++ ++ uart3: serial@200 { ++ compatible = "atmel,at91sam9260-usart"; ++ reg = <0x200 0x200>; ++ interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 41>; ++ clock-names = "usart"; ++ dmas = <&dma1 AT91_XDMAC_DT_PERID(12)>, ++ <&dma1 AT91_XDMAC_DT_PERID(11)>; ++ dma-names = "tx", "rx"; ++ atmel,use-dma-rx; ++ atmel,use-dma-tx; ++ status = "disabled"; ++ }; ++ }; ++ ++ trng: rng@e2010000 { ++ compatible = "microchip,sama7g5-trng", "atmel,at91sam9g45-trng"; ++ reg = <0xe2010000 0x100>; ++ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 97>; ++ status = "disabled"; ++ }; ++ ++ flx4: flexcom@e2018000 { ++ compatible = "atmel,sama5d2-flexcom"; ++ reg = <0xe2018000 0x200>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 42>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0x0 0xe2018000 0x800>; ++ status = "disabled"; ++ ++ uart4: serial@200 { ++ compatible = "atmel,at91sam9260-usart"; ++ reg = <0x200 0x200>; ++ interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 42>; ++ clock-names = "usart"; ++ dmas = <&dma1 AT91_XDMAC_DT_PERID(14)>, ++ <&dma1 AT91_XDMAC_DT_PERID(13)>; ++ dma-names = "tx", "rx"; ++ atmel,use-dma-rx; ++ atmel,use-dma-tx; ++ atmel,fifo-size = <16>; ++ status = "disabled"; ++ }; ++ }; ++ ++ flx7: flexcom@e2024000 { ++ compatible = "atmel,sama5d2-flexcom"; ++ reg = <0xe2024000 0x200>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 45>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0x0 0xe2024000 0x800>; ++ status = "disabled"; ++ ++ uart7: serial@200 { ++ compatible = "atmel,at91sam9260-usart"; ++ reg = <0x200 0x200>; ++ interrupts = <GIC_SPI 45 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 45>; ++ clock-names = "usart"; ++ dmas = <&dma1 AT91_XDMAC_DT_PERID(20)>, ++ <&dma1 AT91_XDMAC_DT_PERID(19)>; ++ dma-names = "tx", "rx"; ++ atmel,use-dma-rx; ++ atmel,use-dma-tx; ++ atmel,fifo-size = <16>; ++ status = "disabled"; ++ }; ++ }; ++ ++ gmac0: ethernet@e2800000 { ++ compatible = "microchip,sama7g5-gem"; ++ reg = <0xe2800000 0x1000>; ++ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 51>, <&pmc PMC_TYPE_PERIPHERAL 51>, <&pmc PMC_TYPE_GCK 51>, <&pmc PMC_TYPE_GCK 53>; ++ clock-names = "pclk", "hclk", "tx_clk", "tsu_clk"; ++ assigned-clocks = <&pmc PMC_TYPE_GCK 51>; ++ assigned-clock-rates = <125000000>; ++ status = "disabled"; ++ }; ++ ++ gmac1: ethernet@e2804000 { ++ compatible = "microchip,sama7g5-emac"; ++ reg = <0xe2804000 0x1000>; ++ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH ++ GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 52>, <&pmc PMC_TYPE_PERIPHERAL 52>; ++ clock-names = "pclk", "hclk"; ++ status = "disabled"; ++ }; ++ ++ dma0: dma-controller@e2808000 { ++ compatible = "microchip,sama7g5-dma"; ++ reg = <0xe2808000 0x1000>; ++ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_HIGH>; ++ #dma-cells = <1>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 22>; ++ clock-names = "dma_clk"; ++ status = "disabled"; ++ }; ++ ++ dma1: dma-controller@e280c000 { ++ compatible = "microchip,sama7g5-dma"; ++ reg = <0xe280c000 0x1000>; ++ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; ++ #dma-cells = <1>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 23>; ++ clock-names = "dma_clk"; ++ status = "disabled"; ++ }; ++ ++ /* Place dma2 here despite it's address */ ++ dma2: dma-controller@e1200000 { ++ compatible = "microchip,sama7g5-dma"; ++ reg = <0xe1200000 0x1000>; ++ interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; ++ #dma-cells = <1>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 24>; ++ clock-names = "dma_clk"; ++ dma-requests = <0>; ++ status = "disabled"; ++ }; ++ ++ flx8: flexcom@e2818000 { ++ compatible = "atmel,sama5d2-flexcom"; ++ reg = <0xe2818000 0x200>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 46>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0x0 0xe2818000 0x800>; ++ status = "disabled"; ++ ++ i2c8: i2c@600 { ++ compatible = "microchip,sama7g5-i2c", "microchip,sam9x60-i2c"; ++ reg = <0x600 0x200>; ++ interrupts = <GIC_SPI 46 IRQ_TYPE_LEVEL_HIGH>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 46>; ++ atmel,fifo-size = <32>; ++ dmas = <&dma0 AT91_XDMAC_DT_PERID(21)>, ++ <&dma0 AT91_XDMAC_DT_PERID(22)>; ++ dma-names = "rx", "tx"; ++ atmel,use-dma-rx; ++ atmel,use-dma-tx; ++ status = "disabled"; ++ }; ++ }; ++ ++ flx9: flexcom@e281c000 { ++ compatible = "atmel,sama5d2-flexcom"; ++ reg = <0xe281c000 0x200>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 47>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0x0 0xe281c000 0x800>; ++ status = "disabled"; ++ ++ i2c9: i2c@600 { ++ compatible = "microchip,sama7g5-i2c", "microchip,sam9x60-i2c"; ++ reg = <0x600 0x200>; ++ interrupts = <GIC_SPI 47 IRQ_TYPE_LEVEL_HIGH>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 47>; ++ atmel,fifo-size = <32>; ++ dmas = <&dma0 AT91_XDMAC_DT_PERID(23)>, ++ <&dma0 AT91_XDMAC_DT_PERID(24)>; ++ dma-names = "rx", "tx"; ++ atmel,use-dma-rx; ++ atmel,use-dma-tx; ++ status = "disabled"; ++ }; ++ }; ++ ++ flx11: flexcom@e2824000 { ++ compatible = "atmel,sama5d2-flexcom"; ++ reg = <0xe2824000 0x200>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 49>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0x0 0xe2824000 0x800>; ++ status = "disabled"; ++ ++ spi11: spi@400 { ++ compatible = "atmel,at91rm9200-spi"; ++ reg = <0x400 0x200>; ++ interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 49>; ++ clock-names = "spi_clk"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ atmel,fifo-size = <32>; ++ dmas = <&dma0 AT91_XDMAC_DT_PERID(27)>, ++ <&dma0 AT91_XDMAC_DT_PERID(28)>; ++ dma-names = "rx", "tx"; ++ status = "disabled"; ++ }; ++ }; ++ ++ gic: interrupt-controller@e8c11000 { ++ compatible = "arm,cortex-a7-gic"; ++ #interrupt-cells = <3>; ++ #address-cells = <0>; ++ interrupt-controller; ++ interrupt-parent; ++ reg = <0xe8c11000 0x1000>, ++ <0xe8c12000 0x2000>; ++ }; ++ }; ++}; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/223-ARM-at91-pm-do-not-panic-if-ram-controllers-are-not-.patch b/target/linux/at91/patches-5.10/223-ARM-at91-pm-do-not-panic-if-ram-controllers-are-not-.patch new file mode 100644 index 0000000000..302d0e3752 --- /dev/null +++ b/target/linux/at91/patches-5.10/223-ARM-at91-pm-do-not-panic-if-ram-controllers-are-not-.patch @@ -0,0 +1,79 @@ +From 76dbc56ad65350d78d12bd9b36b00c36fb27addf Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Mon, 23 Aug 2021 16:19:12 +0300 +Subject: [PATCH 223/247] ARM: at91: pm: do not panic if ram controllers are + not enabled + +In case PM is enabled but there is no RAM controller information +in DT the code will panic. Avoid such scenarios by not initializing +platform specific PM code in case RAM controller is not provided +via DT. + +Reported-by: Eugen Hristev <eugen.hristev@microchip.com> +Fixes: 827de1f123ba0 ("ARM: at91: remove at91_dt_initialize and machine init_early()") +Fixes: 892e1f4a3ae58 ("ARM: at91: pm: add sama7g5 ddr phy controller") +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210823131915.23857-2-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm.c | 22 ++++++++++++++++------ + 1 file changed, 16 insertions(+), 6 deletions(-) + +diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c +index a07e14d89ba4..d92afca64b49 100644 +--- a/arch/arm/mach-at91/pm.c ++++ b/arch/arm/mach-at91/pm.c +@@ -589,7 +589,7 @@ static const struct of_device_id ramc_phy_ids[] __initconst = { + { /* Sentinel. */ }, + }; + +-static __init void at91_dt_ramc(bool phy_mandatory) ++static __init int at91_dt_ramc(bool phy_mandatory) + { + struct device_node *np; + const struct of_device_id *of_id; +@@ -625,12 +625,18 @@ static __init void at91_dt_ramc(bool phy_mandatory) + /* Lookup for DDR PHY node, if any. */ + for_each_matching_node_and_match(np, ramc_phy_ids, &of_id) { + soc_pm.data.ramc_phy = of_iomap(np, 0); +- if (!soc_pm.data.ramc_phy) +- panic(pr_fmt("unable to map ramc phy cpu registers\n")); ++ if (!soc_pm.data.ramc_phy) { ++ pr_err("unable to map ramc phy cpu registers\n"); ++ ret = -ENOMEM; ++ goto unmap_ramc; ++ } + } + +- if (phy_mandatory && !soc_pm.data.ramc_phy) +- panic(pr_fmt("DDR PHY is mandatory!\n")); ++ if (phy_mandatory && !soc_pm.data.ramc_phy) { ++ pr_err("DDR PHY is mandatory!\n"); ++ ret = -ENODEV; ++ goto unmap_ramc; ++ } + + if (!standby) { + pr_warn("ramc no standby function available\n"); +@@ -1163,13 +1169,17 @@ void __init sama7_pm_init(void) + [AT91_PM_BACKUP] = AT91_PM_IOMAP(SFRBU) | + AT91_PM_IOMAP(SHDWC), + }; ++ int ret; + + if (!IS_ENABLED(CONFIG_SOC_SAMA7)) + return; + + at91_pm_modes_validate(modes, ARRAY_SIZE(modes)); + +- at91_dt_ramc(true); ++ ret = at91_dt_ramc(true); ++ if (ret) ++ return; ++ + at91_pm_modes_init(iomaps, ARRAY_SIZE(iomaps)); + at91_pm_init(NULL); + +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/224-ARM-dts-at91-sama7g5-add-ram-controllers.patch b/target/linux/at91/patches-5.10/224-ARM-dts-at91-sama7g5-add-ram-controllers.patch new file mode 100644 index 0000000000..3c36a41fbd --- /dev/null +++ b/target/linux/at91/patches-5.10/224-ARM-dts-at91-sama7g5-add-ram-controllers.patch @@ -0,0 +1,41 @@ +From cf96a88e44f1fde9f1a30ab335329ff9e895e6f8 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Mon, 23 Aug 2021 16:19:13 +0300 +Subject: [PATCH 224/247] ARM: dts: at91: sama7g5: add ram controllers + +Add RAM and RAMC PHY controllers. These are necessary for platform +specific power management code. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210823131915.23857-3-claudiu.beznea@microchip.com +--- + arch/arm/boot/dts/sama7g5.dtsi | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/arch/arm/boot/dts/sama7g5.dtsi b/arch/arm/boot/dts/sama7g5.dtsi +index cc6be6db7b80..ecabab4343b6 100644 +--- a/arch/arm/boot/dts/sama7g5.dtsi ++++ b/arch/arm/boot/dts/sama7g5.dtsi +@@ -515,6 +515,18 @@ spi11: spi@400 { + }; + }; + ++ uddrc: uddrc@e3800000 { ++ compatible = "microchip,sama7g5-uddrc"; ++ reg = <0xe3800000 0x4000>; ++ status = "okay"; ++ }; ++ ++ ddr3phy: ddr3phy@e3804000 { ++ compatible = "microchip,sama7g5-ddr3phy"; ++ reg = <0xe3804000 0x1000>; ++ status = "okay"; ++ }; ++ + gic: interrupt-controller@e8c11000 { + compatible = "arm,cortex-a7-gic"; + #interrupt-cells = <3>; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/225-ARM-dts-at91-sama7g5-add-securam-node.patch b/target/linux/at91/patches-5.10/225-ARM-dts-at91-sama7g5-add-securam-node.patch new file mode 100644 index 0000000000..ec1c2abbab --- /dev/null +++ b/target/linux/at91/patches-5.10/225-ARM-dts-at91-sama7g5-add-securam-node.patch @@ -0,0 +1,39 @@ +From 1da1aae0b207d6a5ac7c3070b8d7c6ef61a32d71 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Mon, 23 Aug 2021 16:19:14 +0300 +Subject: [PATCH 225/247] ARM: dts: at91: sama7g5: add securam node + +Add securam node. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210823131915.23857-4-claudiu.beznea@microchip.com +--- + arch/arm/boot/dts/sama7g5.dtsi | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/arch/arm/boot/dts/sama7g5.dtsi b/arch/arm/boot/dts/sama7g5.dtsi +index ecabab4343b6..3a4315ac0eb0 100644 +--- a/arch/arm/boot/dts/sama7g5.dtsi ++++ b/arch/arm/boot/dts/sama7g5.dtsi +@@ -75,6 +75,17 @@ soc { + #size-cells = <1>; + ranges; + ++ securam: securam@e0000000 { ++ compatible = "microchip,sama7g5-securam", "atmel,sama5d2-securam", "mmio-sram"; ++ reg = <0xe0000000 0x4000>; ++ clocks = <&pmc PMC_TYPE_PERIPHERAL 18>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges = <0 0xe0000000 0x4000>; ++ no-memory-wc; ++ status = "okay"; ++ }; ++ + secumod: secumod@e0004000 { + compatible = "microchip,sama7g5-secumod", "atmel,sama5d2-secumod", "syscon"; + reg = <0xe0004000 0x4000>; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/226-ARM-dts-at91-sama7g5-add-shdwc-node.patch b/target/linux/at91/patches-5.10/226-ARM-dts-at91-sama7g5-add-shdwc-node.patch new file mode 100644 index 0000000000..a149680ad5 --- /dev/null +++ b/target/linux/at91/patches-5.10/226-ARM-dts-at91-sama7g5-add-shdwc-node.patch @@ -0,0 +1,60 @@ +From 372fa27d07f66f97a4bf45621c1b840ce8417a85 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Mon, 23 Aug 2021 16:19:15 +0300 +Subject: [PATCH 226/247] ARM: dts: at91: sama7g5: add shdwc node + +Add shutdown controller node and enable it. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210823131915.23857-5-claudiu.beznea@microchip.com +--- + arch/arm/boot/dts/at91-sama7g5ek.dts | 9 +++++++++ + arch/arm/boot/dts/sama7g5.dtsi | 11 +++++++++++ + 2 files changed, 20 insertions(+) + +diff --git a/arch/arm/boot/dts/at91-sama7g5ek.dts b/arch/arm/boot/dts/at91-sama7g5ek.dts +index 4cbed98cc2f4..8b13b031a167 100644 +--- a/arch/arm/boot/dts/at91-sama7g5ek.dts ++++ b/arch/arm/boot/dts/at91-sama7g5ek.dts +@@ -634,6 +634,15 @@ &sdmmc2 { + pinctrl-0 = <&pinctrl_sdmmc2_default>; + }; + ++&shdwc { ++ atmel,shdwc-debouncer = <976>; ++ status = "okay"; ++ ++ input@0 { ++ reg = <0>; ++ }; ++}; ++ + &spdifrx { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spdifrx_default>; +diff --git a/arch/arm/boot/dts/sama7g5.dtsi b/arch/arm/boot/dts/sama7g5.dtsi +index 3a4315ac0eb0..e50806cf7660 100644 +--- a/arch/arm/boot/dts/sama7g5.dtsi ++++ b/arch/arm/boot/dts/sama7g5.dtsi +@@ -122,6 +122,17 @@ pmc: pmc@e0018000 { + clock-names = "td_slck", "md_slck", "main_xtal"; + }; + ++ shdwc: shdwc@e001d010 { ++ compatible = "microchip,sama7g5-shdwc", "syscon"; ++ reg = <0xe001d010 0x10>; ++ clocks = <&clk32k 0>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ atmel,wakeup-rtc-timer; ++ atmel,wakeup-rtt-timer; ++ status = "disabled"; ++ }; ++ + rtt: rtt@e001d020 { + compatible = "microchip,sama7g5-rtt", "microchip,sam9x60-rtt", "atmel,at91sam9260-rtt"; + reg = <0xe001d020 0x30>; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/227-ARM-dts-at91-sama7g5-add-chipid.patch b/target/linux/at91/patches-5.10/227-ARM-dts-at91-sama7g5-add-chipid.patch new file mode 100644 index 0000000000..53530a537b --- /dev/null +++ b/target/linux/at91/patches-5.10/227-ARM-dts-at91-sama7g5-add-chipid.patch @@ -0,0 +1,33 @@ +From d216c1ecf978574216ece8140146c8dc0ea400e3 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Wed, 8 Sep 2021 12:43:29 +0300 +Subject: [PATCH 227/247] ARM: dts: at91: sama7g5: add chipid + +Add chipid node for sama7g5. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210908094329.182477-1-claudiu.beznea@microchip.com +--- + arch/arm/boot/dts/sama7g5.dtsi | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/arch/arm/boot/dts/sama7g5.dtsi b/arch/arm/boot/dts/sama7g5.dtsi +index e50806cf7660..6c58c151c6d9 100644 +--- a/arch/arm/boot/dts/sama7g5.dtsi ++++ b/arch/arm/boot/dts/sama7g5.dtsi +@@ -159,6 +159,11 @@ ps_wdt: watchdog@e001d180 { + clocks = <&clk32k 0>; + }; + ++ chipid@e0020000 { ++ compatible = "microchip,sama7g5-chipid"; ++ reg = <0xe0020000 0x8>; ++ }; ++ + sdmmc0: mmc@e1204000 { + compatible = "microchip,sama7g5-sdhci", "microchip,sam9x60-sdhci"; + reg = <0xe1204000 0x4000>; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/228-ARM-at91-pm-switch-backup-area-to-vbat-in-backup-mod.patch b/target/linux/at91/patches-5.10/228-ARM-at91-pm-switch-backup-area-to-vbat-in-backup-mod.patch new file mode 100644 index 0000000000..7a8a47fd5d --- /dev/null +++ b/target/linux/at91/patches-5.10/228-ARM-at91-pm-switch-backup-area-to-vbat-in-backup-mod.patch @@ -0,0 +1,122 @@ +From 2cd84ddf0e9623c6bc723b1df368cd8b16a3a8e2 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Mon, 30 Aug 2021 13:09:27 +0300 +Subject: [PATCH 228/247] ARM: at91: pm: switch backup area to vbat in backup + mode + +Backup area is now switched to VDDIN33 at boot (with the help of +bootloader). When switching to backup mode we need to switch backup area +to VBAT as all the other power sources are cut off. The resuming from +backup mode is done with the help of bootloader, so there is no need to +do something particular in Linux to restore backup area power source. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210830100927.22711-1-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm.c | 52 +++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 52 insertions(+) + +diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c +index d92afca64b49..8711d6824c1f 100644 +--- a/arch/arm/mach-at91/pm.c ++++ b/arch/arm/mach-at91/pm.c +@@ -47,12 +47,26 @@ struct at91_pm_bu { + unsigned long ddr_phy_calibration[BACKUP_DDR_PHY_CALIBRATION]; + }; + ++/* ++ * struct at91_pm_sfrbu_offsets: registers mapping for SFRBU ++ * @pswbu: power switch BU control registers ++ */ ++struct at91_pm_sfrbu_regs { ++ struct { ++ u32 key; ++ u32 ctrl; ++ u32 state; ++ u32 softsw; ++ } pswbu; ++}; ++ + /** + * struct at91_soc_pm - AT91 SoC power management data structure + * @config_shdwc_ws: wakeup sources configuration function for SHDWC + * @config_pmc_ws: wakeup srouces configuration function for PMC + * @ws_ids: wakup sources of_device_id array + * @data: PM data to be used on last phase of suspend ++ * @sfrbu_regs: SFRBU registers mapping + * @bu: backup unit mapped data (for backup mode) + * @memcs: memory chip select + */ +@@ -62,6 +76,7 @@ struct at91_soc_pm { + const struct of_device_id *ws_ids; + struct at91_pm_bu *bu; + struct at91_pm_data data; ++ struct at91_pm_sfrbu_regs sfrbu_regs; + void *memcs; + }; + +@@ -356,9 +371,36 @@ static int at91_suspend_finish(unsigned long val) + return 0; + } + ++static void at91_pm_switch_ba_to_vbat(void) ++{ ++ unsigned int offset = offsetof(struct at91_pm_sfrbu_regs, pswbu); ++ unsigned int val; ++ ++ /* Just for safety. */ ++ if (!soc_pm.data.sfrbu) ++ return; ++ ++ val = readl(soc_pm.data.sfrbu + offset); ++ ++ /* Already on VBAT. */ ++ if (!(val & soc_pm.sfrbu_regs.pswbu.state)) ++ return; ++ ++ val &= ~soc_pm.sfrbu_regs.pswbu.softsw; ++ val |= soc_pm.sfrbu_regs.pswbu.key | soc_pm.sfrbu_regs.pswbu.ctrl; ++ writel(val, soc_pm.data.sfrbu + offset); ++ ++ /* Wait for update. */ ++ val = readl(soc_pm.data.sfrbu + offset); ++ while (val & soc_pm.sfrbu_regs.pswbu.state) ++ val = readl(soc_pm.data.sfrbu + offset); ++} ++ + static void at91_pm_suspend(suspend_state_t state) + { + if (soc_pm.data.mode == AT91_PM_BACKUP) { ++ at91_pm_switch_ba_to_vbat(); ++ + cpu_suspend(0, at91_suspend_finish); + + /* The SRAM is lost between suspend cycles */ +@@ -1155,6 +1197,11 @@ void __init sama5d2_pm_init(void) + soc_pm.ws_ids = sama5d2_ws_ids; + soc_pm.config_shdwc_ws = at91_sama5d2_config_shdwc_ws; + soc_pm.config_pmc_ws = at91_sama5d2_config_pmc_ws; ++ ++ soc_pm.sfrbu_regs.pswbu.key = (0x4BD20C << 8); ++ soc_pm.sfrbu_regs.pswbu.ctrl = BIT(0); ++ soc_pm.sfrbu_regs.pswbu.softsw = BIT(1); ++ soc_pm.sfrbu_regs.pswbu.state = BIT(3); + } + + void __init sama7_pm_init(void) +@@ -1185,6 +1232,11 @@ void __init sama7_pm_init(void) + + soc_pm.ws_ids = sama7g5_ws_ids; + soc_pm.config_pmc_ws = at91_sam9x60_config_pmc_ws; ++ ++ soc_pm.sfrbu_regs.pswbu.key = (0x4BD20C << 8); ++ soc_pm.sfrbu_regs.pswbu.ctrl = BIT(0); ++ soc_pm.sfrbu_regs.pswbu.softsw = BIT(1); ++ soc_pm.sfrbu_regs.pswbu.state = BIT(2); + } + + static int __init at91_pm_modes_select(char *str) +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/229-ARM-dts-at91-sama7g5ek-add-suspend-voltage-for-ddr3l.patch b/target/linux/at91/patches-5.10/229-ARM-dts-at91-sama7g5ek-add-suspend-voltage-for-ddr3l.patch new file mode 100644 index 0000000000..ce412dde1c --- /dev/null +++ b/target/linux/at91/patches-5.10/229-ARM-dts-at91-sama7g5ek-add-suspend-voltage-for-ddr3l.patch @@ -0,0 +1,47 @@ +From e5f87471392b344b1261d1eaf93fd44710587ea9 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 30 Sep 2021 18:42:17 +0300 +Subject: [PATCH 229/247] ARM: dts: at91: sama7g5ek: add suspend voltage for + ddr3l rail + +SAMA7G5-EK board has DDR3L type of memory soldered. This needs 1.35V. The +1.35V for DDR3L rail at run-time is selected by the proper configuration +on SELV2 pin (for 1.35V it needs to be in high-z state). When suspended +the MCP16502 PMIC soldered on SAMA7G5-EK will use different sets of +configuration registers to provide proper voltages on its rail. Run-time +configuration registers could be configured differently than suspend +configuration register for MCP16502 (VSEL2 affects only run-time +configuration). In suspend states the DDR3L memory soldered on SAMA7G5-EK +switches to self-refresh. Even on self-refresh it needs to be powered by +a 1.35V rail. Thus, make sure the PMIC is configured properly when system +is suspended. + +Fixes: 7540629e2fc7 (ARM: dts: at91: add sama7g5 SoC DT and sama7g5-ek") +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210930154219.2214051-2-claudiu.beznea@microchip.com +--- + arch/arm/boot/dts/at91-sama7g5ek.dts | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/arch/arm/boot/dts/at91-sama7g5ek.dts b/arch/arm/boot/dts/at91-sama7g5ek.dts +index 8b13b031a167..f0772fa01751 100644 +--- a/arch/arm/boot/dts/at91-sama7g5ek.dts ++++ b/arch/arm/boot/dts/at91-sama7g5ek.dts +@@ -196,11 +196,13 @@ vddioddr: VDD_DDR { + + regulator-state-standby { + regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1350000>; + regulator-mode = <4>; + }; + + regulator-state-mem { + regulator-on-in-suspend; ++ regulator-suspend-microvolt = <1350000>; + regulator-mode = <4>; + }; + }; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/230-ARM-at91-pm-group-constants-and-addresses-loading.patch b/target/linux/at91/patches-5.10/230-ARM-at91-pm-group-constants-and-addresses-loading.patch new file mode 100644 index 0000000000..af6698bfeb --- /dev/null +++ b/target/linux/at91/patches-5.10/230-ARM-at91-pm-group-constants-and-addresses-loading.patch @@ -0,0 +1,53 @@ +From 12330a9f6b99622e3c21ddcc720b02431b8a6e2d Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 30 Sep 2021 18:42:18 +0300 +Subject: [PATCH 230/247] ARM: at91: pm: group constants and addresses loading + +Group constants and addresses loading. This commit prepares the field for +the next one. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210930154219.2214051-3-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm_suspend.S | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S +index cbd61a3bcab1..34f251fdb743 100644 +--- a/arch/arm/mach-at91/pm_suspend.S ++++ b/arch/arm/mach-at91/pm_suspend.S +@@ -1014,6 +1014,15 @@ ENTRY(at91_pm_suspend_in_sram) + mov tmp1, #0 + mcr p15, 0, tmp1, c7, c10, 4 + ++ ldr tmp1, [r0, #PM_DATA_PMC_MCKR_OFFSET] ++ str tmp1, .mckr_offset ++ ldr tmp1, [r0, #PM_DATA_PMC_VERSION] ++ str tmp1, .pmc_version ++ ldr tmp1, [r0, #PM_DATA_MEMCTRL] ++ str tmp1, .memtype ++ ldr tmp1, [r0, #PM_DATA_MODE] ++ str tmp1, .pm_mode ++ + ldr tmp1, [r0, #PM_DATA_PMC] + str tmp1, .pmc_base + ldr tmp1, [r0, #PM_DATA_RAMC0] +@@ -1022,14 +1031,6 @@ ENTRY(at91_pm_suspend_in_sram) + str tmp1, .sramc1_base + ldr tmp1, [r0, #PM_DATA_RAMC_PHY] + str tmp1, .sramc_phy_base +- ldr tmp1, [r0, #PM_DATA_MEMCTRL] +- str tmp1, .memtype +- ldr tmp1, [r0, #PM_DATA_MODE] +- str tmp1, .pm_mode +- ldr tmp1, [r0, #PM_DATA_PMC_MCKR_OFFSET] +- str tmp1, .mckr_offset +- ldr tmp1, [r0, #PM_DATA_PMC_VERSION] +- str tmp1, .pmc_version + /* Both ldrne below are here to preload their address in the TLB */ + ldr tmp1, [r0, #PM_DATA_SHDWC] + str tmp1, .shdwc +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/231-ARM-at91-pm-preload-base-address-of-controllers-in-t.patch b/target/linux/at91/patches-5.10/231-ARM-at91-pm-preload-base-address-of-controllers-in-t.patch new file mode 100644 index 0000000000..86b07071a4 --- /dev/null +++ b/target/linux/at91/patches-5.10/231-ARM-at91-pm-preload-base-address-of-controllers-in-t.patch @@ -0,0 +1,98 @@ +From 6075bbc75e55258a762d618cd459dbe0dd38aff9 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Thu, 30 Sep 2021 18:42:19 +0300 +Subject: [PATCH 231/247] ARM: at91: pm: preload base address of controllers in + tlb + +In suspend/resume procedure for AT91 architecture different controllers +(PMC, SHDWC, RAM, RAM PHY, SFRBU) are accessed to do the proper settings +for power saving. Commit f0bbf17958e8 ("ARM: at91: pm: add self-refresh +support for sama7g5") introduced the access to RAMC PHY controller for +SAMA7G5. The access to this controller is done after RAMC ports are +closed, thus any TLB walk necessary for RAMC PHY virtual address will +fail. In the development branch this was not encountered. However, on +current kernel the issue is reproducible. + +To solve the issue the previous mechanism of pre-loading the TLB with +the RAMC PHY virtual address has been used. However, only the addition +of this new pre-load breaks the functionality for ARMv5 based +devices (SAM9X60). This behavior has been encountered previously +while debugging this code and using the same mechanism for pre-loading +address for different controllers (e.g. pin controller, the assumption +being that other requested translations are replaced from TLB). + +To solve this new issue the TLB flush + the extension of pre-loading +the rest of controllers to TLB (e.g. PMC, RAMC) has been added. The +rest of the controllers should have been pre-loaded previously, anyway. + +Fixes: f0bbf17958e8 ("ARM: at91: pm: add self-refresh support for sama7g5") +Depends-on: e42cbbe5c9a2 ("ARM: at91: pm: group constants and addresses loading") +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210930154219.2214051-4-claudiu.beznea@microchip.com +--- + arch/arm/mach-at91/pm_suspend.S | 25 ++++++++++++++++++++++++- + 1 file changed, 24 insertions(+), 1 deletion(-) + +diff --git a/arch/arm/mach-at91/pm_suspend.S b/arch/arm/mach-at91/pm_suspend.S +index 34f251fdb743..fdb4f63ecde4 100644 +--- a/arch/arm/mach-at91/pm_suspend.S ++++ b/arch/arm/mach-at91/pm_suspend.S +@@ -1014,6 +1014,10 @@ ENTRY(at91_pm_suspend_in_sram) + mov tmp1, #0 + mcr p15, 0, tmp1, c7, c10, 4 + ++ /* Flush tlb. */ ++ mov r4, #0 ++ mcr p15, 0, r4, c8, c7, 0 ++ + ldr tmp1, [r0, #PM_DATA_PMC_MCKR_OFFSET] + str tmp1, .mckr_offset + ldr tmp1, [r0, #PM_DATA_PMC_VERSION] +@@ -1023,23 +1027,42 @@ ENTRY(at91_pm_suspend_in_sram) + ldr tmp1, [r0, #PM_DATA_MODE] + str tmp1, .pm_mode + ++ /* ++ * ldrne below are here to preload their address in the TLB as access ++ * to RAM may be limited while in self-refresh. ++ */ + ldr tmp1, [r0, #PM_DATA_PMC] + str tmp1, .pmc_base ++ cmp tmp1, #0 ++ ldrne tmp2, [tmp1, #0] ++ + ldr tmp1, [r0, #PM_DATA_RAMC0] + str tmp1, .sramc_base ++ cmp tmp1, #0 ++ ldrne tmp2, [tmp1, #0] ++ + ldr tmp1, [r0, #PM_DATA_RAMC1] + str tmp1, .sramc1_base ++ cmp tmp1, #0 ++ ldrne tmp2, [tmp1, #0] ++ ++#ifndef CONFIG_SOC_SAM_V4_V5 ++ /* ldrne below are here to preload their address in the TLB */ + ldr tmp1, [r0, #PM_DATA_RAMC_PHY] + str tmp1, .sramc_phy_base +- /* Both ldrne below are here to preload their address in the TLB */ ++ cmp tmp1, #0 ++ ldrne tmp2, [tmp1, #0] ++ + ldr tmp1, [r0, #PM_DATA_SHDWC] + str tmp1, .shdwc + cmp tmp1, #0 + ldrne tmp2, [tmp1, #0] ++ + ldr tmp1, [r0, #PM_DATA_SFRBU] + str tmp1, .sfrbu + cmp tmp1, #0 + ldrne tmp2, [tmp1, #0x10] ++#endif + + /* Active the self-refresh mode */ + at91_sramc_self_refresh_ena +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/232-ARM-dts-at91-sama7g5ek-use-proper-slew-rate-settings.patch b/target/linux/at91/patches-5.10/232-ARM-dts-at91-sama7g5ek-use-proper-slew-rate-settings.patch new file mode 100644 index 0000000000..014ab46006 --- /dev/null +++ b/target/linux/at91/patches-5.10/232-ARM-dts-at91-sama7g5ek-use-proper-slew-rate-settings.patch @@ -0,0 +1,90 @@ +From 98d2c4ca97dde30616fa78ad5677825b1966cec6 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Wed, 15 Sep 2021 10:48:35 +0300 +Subject: [PATCH 232/247] ARM: dts: at91: sama7g5ek: use proper slew-rate + settings for GMACs + +Datasheet chapter "EMAC Timings" specifies that while in 3.3V domain +GMAC's MDIO pins should be configured with slew-rate enabled, while the +data + signaling pins should be configured with slew-rate disabled when +GMAC works in RGMII or RMII modes. The pin controller for SAMA7G5 sets +the slew-rate as enabled for all pins. Adapt the device tree to comply +with these. + +Fixes: 7540629e2fc7 ("ARM: dts: at91: add sama7g5 SoC DT and sama7g5-ek") +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210915074836.6574-2-claudiu.beznea@microchip.com +--- + arch/arm/boot/dts/at91-sama7g5ek.dts | 28 ++++++++++++++++++++++------ + 1 file changed, 22 insertions(+), 6 deletions(-) + +diff --git a/arch/arm/boot/dts/at91-sama7g5ek.dts b/arch/arm/boot/dts/at91-sama7g5ek.dts +index f0772fa01751..30b67cad5f14 100644 +--- a/arch/arm/boot/dts/at91-sama7g5ek.dts ++++ b/arch/arm/boot/dts/at91-sama7g5ek.dts +@@ -355,7 +355,10 @@ &gmac0 { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; +- pinctrl-0 = <&pinctrl_gmac0_default &pinctrl_gmac0_txck_default &pinctrl_gmac0_phy_irq>; ++ pinctrl-0 = <&pinctrl_gmac0_default ++ &pinctrl_gmac0_mdio_default ++ &pinctrl_gmac0_txck_default ++ &pinctrl_gmac0_phy_irq>; + phy-mode = "rgmii-id"; + status = "okay"; + +@@ -370,7 +373,9 @@ &gmac1 { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default"; +- pinctrl-0 = <&pinctrl_gmac1_default &pinctrl_gmac1_phy_irq>; ++ pinctrl-0 = <&pinctrl_gmac1_default ++ &pinctrl_gmac1_mdio_default ++ &pinctrl_gmac1_phy_irq>; + phy-mode = "rmii"; + status = "okay"; + +@@ -425,14 +430,20 @@ pinctrl_gmac0_default: gmac0_default { + <PIN_PA15__G0_TXEN>, + <PIN_PA30__G0_RXCK>, + <PIN_PA18__G0_RXDV>, +- <PIN_PA22__G0_MDC>, +- <PIN_PA23__G0_MDIO>, + <PIN_PA25__G0_125CK>; ++ slew-rate = <0>; ++ bias-disable; ++ }; ++ ++ pinctrl_gmac0_mdio_default: gmac0_mdio_default { ++ pinmux = <PIN_PA22__G0_MDC>, ++ <PIN_PA23__G0_MDIO>; + bias-disable; + }; + + pinctrl_gmac0_txck_default: gmac0_txck_default { + pinmux = <PIN_PA24__G0_TXCK>; ++ slew-rate = <0>; + bias-pull-up; + }; + +@@ -449,8 +460,13 @@ pinctrl_gmac1_default: gmac1_default { + <PIN_PD25__G1_RX0>, + <PIN_PD26__G1_RX1>, + <PIN_PD27__G1_RXER>, +- <PIN_PD24__G1_RXDV>, +- <PIN_PD28__G1_MDC>, ++ <PIN_PD24__G1_RXDV>; ++ slew-rate = <0>; ++ bias-disable; ++ }; ++ ++ pinctrl_gmac1_mdio_default: gmac1_mdio_default { ++ pinmux = <PIN_PD28__G1_MDC>, + <PIN_PD29__G1_MDIO>; + bias-disable; + }; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/233-ARM-dts-at91-sama7g5ek-to-not-touch-slew-rate-for-SD.patch b/target/linux/at91/patches-5.10/233-ARM-dts-at91-sama7g5ek-to-not-touch-slew-rate-for-SD.patch new file mode 100644 index 0000000000..75b64b7b54 --- /dev/null +++ b/target/linux/at91/patches-5.10/233-ARM-dts-at91-sama7g5ek-to-not-touch-slew-rate-for-SD.patch @@ -0,0 +1,78 @@ +From 4c0b77276307d2cba8ae2595cbae4cc916c84c36 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Wed, 15 Sep 2021 10:48:36 +0300 +Subject: [PATCH 233/247] ARM: dts: at91: sama7g5ek: to not touch slew-rate for + SDMMC pins + +With commit c709135e576b ("pinctrl: at91-pio4: add support for slew-rate") +and commit cbde6c823bfa ("pinctrl: at91-pio4: Fix slew rate disablement") +the slew-rate is enabled by default for each configured pin. The datasheet +specifies at chapter "Output Driver AC Characteristics" that HSIO +drivers (use in SDMMCx and QSPI0 peripherals), don't have a slewrate +setting but are rather calibrated against an external 1% resistor mounted +on the SDMMCx_CAL or QSPI0_CAL pins. Depending on the target signal +frequency and the external load, it is possible to adjust their target +output impedance. Thus set slew-rate = <0> for SDMMC (QSPI is not enabled +at the moment in device tree). + +Fixes: 7540629e2fc7 ("ARM: dts: at91: add sama7g5 SoC DT and sama7g5-ek") +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Signed-off-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20210915074836.6574-3-claudiu.beznea@microchip.com +--- + arch/arm/boot/dts/at91-sama7g5ek.dts | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/arch/arm/boot/dts/at91-sama7g5ek.dts b/arch/arm/boot/dts/at91-sama7g5ek.dts +index 30b67cad5f14..f3d6aaa3a78d 100644 +--- a/arch/arm/boot/dts/at91-sama7g5ek.dts ++++ b/arch/arm/boot/dts/at91-sama7g5ek.dts +@@ -558,6 +558,7 @@ cmd_data { + <PIN_PA8__SDMMC0_DAT5>, + <PIN_PA9__SDMMC0_DAT6>, + <PIN_PA10__SDMMC0_DAT7>; ++ slew-rate = <0>; + bias-pull-up; + }; + +@@ -565,6 +566,7 @@ ck_cd_rstn_vddsel { + pinmux = <PIN_PA0__SDMMC0_CK>, + <PIN_PA2__SDMMC0_RSTN>, + <PIN_PA11__SDMMC0_DS>; ++ slew-rate = <0>; + bias-pull-up; + }; + }; +@@ -576,6 +578,7 @@ cmd_data { + <PIN_PC0__SDMMC1_DAT1>, + <PIN_PC1__SDMMC1_DAT2>, + <PIN_PC2__SDMMC1_DAT3>; ++ slew-rate = <0>; + bias-pull-up; + }; + +@@ -584,6 +587,7 @@ ck_cd_rstn_vddsel { + <PIN_PB28__SDMMC1_RSTN>, + <PIN_PC5__SDMMC1_1V8SEL>, + <PIN_PC4__SDMMC1_CD>; ++ slew-rate = <0>; + bias-pull-up; + }; + }; +@@ -595,11 +599,13 @@ cmd_data { + <PIN_PD6__SDMMC2_DAT1>, + <PIN_PD7__SDMMC2_DAT2>, + <PIN_PD8__SDMMC2_DAT3>; ++ slew-rate = <0>; + bias-pull-up; + }; + + ck { + pinmux = <PIN_PD4__SDMMC2_CK>; ++ slew-rate = <0>; + bias-pull-up; + }; + }; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/234-clk-at91-re-factor-clocks-suspend-resume.patch b/target/linux/at91/patches-5.10/234-clk-at91-re-factor-clocks-suspend-resume.patch new file mode 100644 index 0000000000..9defd65c49 --- /dev/null +++ b/target/linux/at91/patches-5.10/234-clk-at91-re-factor-clocks-suspend-resume.patch @@ -0,0 +1,1369 @@ +From 65bb4687b2a5c6f02f44345540c3389d6e7523e7 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Mon, 11 Oct 2021 14:27:05 +0300 +Subject: [PATCH 234/247] clk: at91: re-factor clocks suspend/resume + +SAMA5D2 and SAMA7G5 have a special power saving mode (backup mode) where +most of the SoC's components are powered off (including PMC). Resuming +from this mode is done with the help of bootloader. Peripherals are not +aware of the power saving mode thus most of them are disabling clocks in +proper suspend API and re-enable them in resume API without taking into +account the previously setup rate. Moreover some of the peripherals are +acting as wakeup sources and are not disabling the clocks in this +scenario, when suspending. Since backup mode cuts the power for +peripherals, in resume part these clocks needs to be re-configured. + +The initial PMC suspend/resume code was designed only for SAMA5D2's PMC +(as it was the only one supporting backup mode). SAMA7G supports also +backup mode and its PMC is different (few new functionalities, different +registers offsets, different offsets in registers for each +functionalities). To address both SAMA5D2 and SAMA7G5 PMC add +.save_context()/.resume_context() support to each clocks driver and call +this from PMC driver. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/20211011112719.3951784-2-claudiu.beznea@microchip.com +Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/clk-generated.c | 46 +++++-- + drivers/clk/at91/clk-main.c | 66 ++++++++++ + drivers/clk/at91/clk-master.c | 194 ++++++++++++++++++++++++++-- + drivers/clk/at91/clk-peripheral.c | 40 +++++- + drivers/clk/at91/clk-pll.c | 39 ++++++ + drivers/clk/at91/clk-programmable.c | 29 ++++- + drivers/clk/at91/clk-sam9x60-pll.c | 68 +++++++++- + drivers/clk/at91/clk-system.c | 20 +++ + drivers/clk/at91/clk-usb.c | 27 ++++ + drivers/clk/at91/clk-utmi.c | 39 ++++++ + drivers/clk/at91/pmc.c | 147 +-------------------- + drivers/clk/at91/pmc.h | 24 ++-- + 12 files changed, 558 insertions(+), 181 deletions(-) + +diff --git a/drivers/clk/at91/clk-generated.c b/drivers/clk/at91/clk-generated.c +index b656d25a9767..23cc8297ec4c 100644 +--- a/drivers/clk/at91/clk-generated.c ++++ b/drivers/clk/at91/clk-generated.c +@@ -27,6 +27,7 @@ struct clk_generated { + u32 id; + u32 gckdiv; + const struct clk_pcr_layout *layout; ++ struct at91_clk_pms pms; + u8 parent_id; + int chg_pid; + }; +@@ -34,25 +35,35 @@ struct clk_generated { + #define to_clk_generated(hw) \ + container_of(hw, struct clk_generated, hw) + +-static int clk_generated_enable(struct clk_hw *hw) ++static int clk_generated_set(struct clk_generated *gck, int status) + { +- struct clk_generated *gck = to_clk_generated(hw); + unsigned long flags; +- +- pr_debug("GCLK: %s, gckdiv = %d, parent id = %d\n", +- __func__, gck->gckdiv, gck->parent_id); ++ unsigned int enable = status ? AT91_PMC_PCR_GCKEN : 0; + + spin_lock_irqsave(gck->lock, flags); + regmap_write(gck->regmap, gck->layout->offset, + (gck->id & gck->layout->pid_mask)); + regmap_update_bits(gck->regmap, gck->layout->offset, + AT91_PMC_PCR_GCKDIV_MASK | gck->layout->gckcss_mask | +- gck->layout->cmd | AT91_PMC_PCR_GCKEN, ++ gck->layout->cmd | enable, + field_prep(gck->layout->gckcss_mask, gck->parent_id) | + gck->layout->cmd | + FIELD_PREP(AT91_PMC_PCR_GCKDIV_MASK, gck->gckdiv) | +- AT91_PMC_PCR_GCKEN); ++ enable); + spin_unlock_irqrestore(gck->lock, flags); ++ ++ return 0; ++} ++ ++static int clk_generated_enable(struct clk_hw *hw) ++{ ++ struct clk_generated *gck = to_clk_generated(hw); ++ ++ pr_debug("GCLK: %s, gckdiv = %d, parent id = %d\n", ++ __func__, gck->gckdiv, gck->parent_id); ++ ++ clk_generated_set(gck, 1); ++ + return 0; + } + +@@ -245,6 +256,23 @@ static int clk_generated_set_rate(struct clk_hw *hw, + return 0; + } + ++static int clk_generated_save_context(struct clk_hw *hw) ++{ ++ struct clk_generated *gck = to_clk_generated(hw); ++ ++ gck->pms.status = clk_generated_is_enabled(&gck->hw); ++ ++ return 0; ++} ++ ++static void clk_generated_restore_context(struct clk_hw *hw) ++{ ++ struct clk_generated *gck = to_clk_generated(hw); ++ ++ if (gck->pms.status) ++ clk_generated_set(gck, gck->pms.status); ++} ++ + static const struct clk_ops generated_ops = { + .enable = clk_generated_enable, + .disable = clk_generated_disable, +@@ -254,6 +282,8 @@ static const struct clk_ops generated_ops = { + .get_parent = clk_generated_get_parent, + .set_parent = clk_generated_set_parent, + .set_rate = clk_generated_set_rate, ++ .save_context = clk_generated_save_context, ++ .restore_context = clk_generated_restore_context, + }; + + /** +@@ -320,8 +350,6 @@ at91_clk_register_generated(struct regmap *regmap, spinlock_t *lock, + if (ret) { + kfree(gck); + hw = ERR_PTR(ret); +- } else { +- pmc_register_id(id); + } + + return hw; +diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c +index cfae2f59df66..8601b27c1ae0 100644 +--- a/drivers/clk/at91/clk-main.c ++++ b/drivers/clk/at91/clk-main.c +@@ -28,6 +28,7 @@ + struct clk_main_osc { + struct clk_hw hw; + struct regmap *regmap; ++ struct at91_clk_pms pms; + }; + + #define to_clk_main_osc(hw) container_of(hw, struct clk_main_osc, hw) +@@ -37,6 +38,7 @@ struct clk_main_rc_osc { + struct regmap *regmap; + unsigned long frequency; + unsigned long accuracy; ++ struct at91_clk_pms pms; + }; + + #define to_clk_main_rc_osc(hw) container_of(hw, struct clk_main_rc_osc, hw) +@@ -51,6 +53,7 @@ struct clk_rm9200_main { + struct clk_sam9x5_main { + struct clk_hw hw; + struct regmap *regmap; ++ struct at91_clk_pms pms; + u8 parent; + }; + +@@ -120,10 +123,29 @@ static int clk_main_osc_is_prepared(struct clk_hw *hw) + return (status & AT91_PMC_MOSCS) && clk_main_parent_select(tmp); + } + ++static int clk_main_osc_save_context(struct clk_hw *hw) ++{ ++ struct clk_main_osc *osc = to_clk_main_osc(hw); ++ ++ osc->pms.status = clk_main_osc_is_prepared(hw); ++ ++ return 0; ++} ++ ++static void clk_main_osc_restore_context(struct clk_hw *hw) ++{ ++ struct clk_main_osc *osc = to_clk_main_osc(hw); ++ ++ if (osc->pms.status) ++ clk_main_osc_prepare(hw); ++} ++ + static const struct clk_ops main_osc_ops = { + .prepare = clk_main_osc_prepare, + .unprepare = clk_main_osc_unprepare, + .is_prepared = clk_main_osc_is_prepared, ++ .save_context = clk_main_osc_save_context, ++ .restore_context = clk_main_osc_restore_context, + }; + + struct clk_hw * __init +@@ -240,12 +262,31 @@ static unsigned long clk_main_rc_osc_recalc_accuracy(struct clk_hw *hw, + return osc->accuracy; + } + ++static int clk_main_rc_osc_save_context(struct clk_hw *hw) ++{ ++ struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); ++ ++ osc->pms.status = clk_main_rc_osc_is_prepared(hw); ++ ++ return 0; ++} ++ ++static void clk_main_rc_osc_restore_context(struct clk_hw *hw) ++{ ++ struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); ++ ++ if (osc->pms.status) ++ clk_main_rc_osc_prepare(hw); ++} ++ + static const struct clk_ops main_rc_osc_ops = { + .prepare = clk_main_rc_osc_prepare, + .unprepare = clk_main_rc_osc_unprepare, + .is_prepared = clk_main_rc_osc_is_prepared, + .recalc_rate = clk_main_rc_osc_recalc_rate, + .recalc_accuracy = clk_main_rc_osc_recalc_accuracy, ++ .save_context = clk_main_rc_osc_save_context, ++ .restore_context = clk_main_rc_osc_restore_context, + }; + + struct clk_hw * __init +@@ -465,12 +506,37 @@ static u8 clk_sam9x5_main_get_parent(struct clk_hw *hw) + return clk_main_parent_select(status); + } + ++static int clk_sam9x5_main_save_context(struct clk_hw *hw) ++{ ++ struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); ++ ++ clkmain->pms.status = clk_main_rc_osc_is_prepared(&clkmain->hw); ++ clkmain->pms.parent = clk_sam9x5_main_get_parent(&clkmain->hw); ++ ++ return 0; ++} ++ ++static void clk_sam9x5_main_restore_context(struct clk_hw *hw) ++{ ++ struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); ++ int ret; ++ ++ ret = clk_sam9x5_main_set_parent(hw, clkmain->pms.parent); ++ if (ret) ++ return; ++ ++ if (clkmain->pms.status) ++ clk_sam9x5_main_prepare(hw); ++} ++ + static const struct clk_ops sam9x5_main_ops = { + .prepare = clk_sam9x5_main_prepare, + .is_prepared = clk_sam9x5_main_is_prepared, + .recalc_rate = clk_sam9x5_main_recalc_rate, + .set_parent = clk_sam9x5_main_set_parent, + .get_parent = clk_sam9x5_main_get_parent, ++ .save_context = clk_sam9x5_main_save_context, ++ .restore_context = clk_sam9x5_main_restore_context, + }; + + struct clk_hw * __init +diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c +index a80427980bf7..f75549fff023 100644 +--- a/drivers/clk/at91/clk-master.c ++++ b/drivers/clk/at91/clk-master.c +@@ -37,6 +37,7 @@ struct clk_master { + spinlock_t *lock; + const struct clk_master_layout *layout; + const struct clk_master_characteristics *characteristics; ++ struct at91_clk_pms pms; + u32 *mux_table; + u32 mckr; + int chg_pid; +@@ -112,10 +113,52 @@ static unsigned long clk_master_div_recalc_rate(struct clk_hw *hw, + return rate; + } + ++static int clk_master_div_save_context(struct clk_hw *hw) ++{ ++ struct clk_master *master = to_clk_master(hw); ++ struct clk_hw *parent_hw = clk_hw_get_parent(hw); ++ unsigned long flags; ++ unsigned int mckr, div; ++ ++ spin_lock_irqsave(master->lock, flags); ++ regmap_read(master->regmap, master->layout->offset, &mckr); ++ spin_unlock_irqrestore(master->lock, flags); ++ ++ mckr &= master->layout->mask; ++ div = (mckr >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; ++ div = master->characteristics->divisors[div]; ++ ++ master->pms.parent_rate = clk_hw_get_rate(parent_hw); ++ master->pms.rate = DIV_ROUND_CLOSEST(master->pms.parent_rate, div); ++ ++ return 0; ++} ++ ++static void clk_master_div_restore_context(struct clk_hw *hw) ++{ ++ struct clk_master *master = to_clk_master(hw); ++ unsigned long flags; ++ unsigned int mckr; ++ u8 div; ++ ++ spin_lock_irqsave(master->lock, flags); ++ regmap_read(master->regmap, master->layout->offset, &mckr); ++ spin_unlock_irqrestore(master->lock, flags); ++ ++ mckr &= master->layout->mask; ++ div = (mckr >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; ++ div = master->characteristics->divisors[div]; ++ ++ if (div != DIV_ROUND_CLOSEST(master->pms.parent_rate, master->pms.rate)) ++ pr_warn("MCKR DIV not configured properly by firmware!\n"); ++} ++ + static const struct clk_ops master_div_ops = { + .prepare = clk_master_prepare, + .is_prepared = clk_master_is_prepared, + .recalc_rate = clk_master_div_recalc_rate, ++ .save_context = clk_master_div_save_context, ++ .restore_context = clk_master_div_restore_context, + }; + + static int clk_master_div_set_rate(struct clk_hw *hw, unsigned long rate, +@@ -125,7 +168,9 @@ static int clk_master_div_set_rate(struct clk_hw *hw, unsigned long rate, + const struct clk_master_characteristics *characteristics = + master->characteristics; + unsigned long flags; ++ unsigned int mckr, tmp; + int div, i; ++ int ret; + + div = DIV_ROUND_CLOSEST(parent_rate, rate); + if (div > ARRAY_SIZE(characteristics->divisors)) +@@ -145,11 +190,24 @@ static int clk_master_div_set_rate(struct clk_hw *hw, unsigned long rate, + return -EINVAL; + + spin_lock_irqsave(master->lock, flags); +- regmap_update_bits(master->regmap, master->layout->offset, +- (MASTER_DIV_MASK << MASTER_DIV_SHIFT), +- (div << MASTER_DIV_SHIFT)); ++ ret = regmap_read(master->regmap, master->layout->offset, &mckr); ++ if (ret) ++ goto unlock; ++ ++ tmp = mckr & master->layout->mask; ++ tmp = (tmp >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; ++ if (tmp == div) ++ goto unlock; ++ ++ mckr &= ~(MASTER_DIV_MASK << MASTER_DIV_SHIFT); ++ mckr |= (div << MASTER_DIV_SHIFT); ++ ret = regmap_write(master->regmap, master->layout->offset, mckr); ++ if (ret) ++ goto unlock; ++ + while (!clk_master_ready(master)) + cpu_relax(); ++unlock: + spin_unlock_irqrestore(master->lock, flags); + + return 0; +@@ -197,12 +255,25 @@ static int clk_master_div_determine_rate(struct clk_hw *hw, + return 0; + } + ++static void clk_master_div_restore_context_chg(struct clk_hw *hw) ++{ ++ struct clk_master *master = to_clk_master(hw); ++ int ret; ++ ++ ret = clk_master_div_set_rate(hw, master->pms.rate, ++ master->pms.parent_rate); ++ if (ret) ++ pr_warn("Failed to restore MCK DIV clock\n"); ++} ++ + static const struct clk_ops master_div_ops_chg = { + .prepare = clk_master_prepare, + .is_prepared = clk_master_is_prepared, + .recalc_rate = clk_master_div_recalc_rate, + .determine_rate = clk_master_div_determine_rate, + .set_rate = clk_master_div_set_rate, ++ .save_context = clk_master_div_save_context, ++ .restore_context = clk_master_div_restore_context_chg, + }; + + static void clk_sama7g5_master_best_diff(struct clk_rate_request *req, +@@ -272,7 +343,8 @@ static int clk_master_pres_set_rate(struct clk_hw *hw, unsigned long rate, + { + struct clk_master *master = to_clk_master(hw); + unsigned long flags; +- unsigned int pres; ++ unsigned int pres, mckr, tmp; ++ int ret; + + pres = DIV_ROUND_CLOSEST(parent_rate, rate); + if (pres > MASTER_PRES_MAX) +@@ -284,15 +356,27 @@ static int clk_master_pres_set_rate(struct clk_hw *hw, unsigned long rate, + pres = ffs(pres) - 1; + + spin_lock_irqsave(master->lock, flags); +- regmap_update_bits(master->regmap, master->layout->offset, +- (MASTER_PRES_MASK << master->layout->pres_shift), +- (pres << master->layout->pres_shift)); ++ ret = regmap_read(master->regmap, master->layout->offset, &mckr); ++ if (ret) ++ goto unlock; ++ ++ mckr &= master->layout->mask; ++ tmp = (mckr >> master->layout->pres_shift) & MASTER_PRES_MASK; ++ if (pres == tmp) ++ goto unlock; ++ ++ mckr &= ~(MASTER_PRES_MASK << master->layout->pres_shift); ++ mckr |= (pres << master->layout->pres_shift); ++ ret = regmap_write(master->regmap, master->layout->offset, mckr); ++ if (ret) ++ goto unlock; + + while (!clk_master_ready(master)) + cpu_relax(); ++unlock: + spin_unlock_irqrestore(master->lock, flags); + +- return 0; ++ return ret; + } + + static unsigned long clk_master_pres_recalc_rate(struct clk_hw *hw, +@@ -330,11 +414,68 @@ static u8 clk_master_pres_get_parent(struct clk_hw *hw) + return mckr & AT91_PMC_CSS; + } + ++static int clk_master_pres_save_context(struct clk_hw *hw) ++{ ++ struct clk_master *master = to_clk_master(hw); ++ struct clk_hw *parent_hw = clk_hw_get_parent(hw); ++ unsigned long flags; ++ unsigned int val, pres; ++ ++ spin_lock_irqsave(master->lock, flags); ++ regmap_read(master->regmap, master->layout->offset, &val); ++ spin_unlock_irqrestore(master->lock, flags); ++ ++ val &= master->layout->mask; ++ pres = (val >> master->layout->pres_shift) & MASTER_PRES_MASK; ++ if (pres == MASTER_PRES_MAX && master->characteristics->have_div3_pres) ++ pres = 3; ++ else ++ pres = (1 << pres); ++ ++ master->pms.parent = val & AT91_PMC_CSS; ++ master->pms.parent_rate = clk_hw_get_rate(parent_hw); ++ master->pms.rate = DIV_ROUND_CLOSEST_ULL(master->pms.parent_rate, pres); ++ ++ return 0; ++} ++ ++static void clk_master_pres_restore_context(struct clk_hw *hw) ++{ ++ struct clk_master *master = to_clk_master(hw); ++ unsigned long flags; ++ unsigned int val, pres; ++ ++ spin_lock_irqsave(master->lock, flags); ++ regmap_read(master->regmap, master->layout->offset, &val); ++ spin_unlock_irqrestore(master->lock, flags); ++ ++ val &= master->layout->mask; ++ pres = (val >> master->layout->pres_shift) & MASTER_PRES_MASK; ++ if (pres == MASTER_PRES_MAX && master->characteristics->have_div3_pres) ++ pres = 3; ++ else ++ pres = (1 << pres); ++ ++ if (master->pms.rate != ++ DIV_ROUND_CLOSEST_ULL(master->pms.parent_rate, pres) || ++ (master->pms.parent != (val & AT91_PMC_CSS))) ++ pr_warn("MCKR PRES was not configured properly by firmware!\n"); ++} ++ ++static void clk_master_pres_restore_context_chg(struct clk_hw *hw) ++{ ++ struct clk_master *master = to_clk_master(hw); ++ ++ clk_master_pres_set_rate(hw, master->pms.rate, master->pms.parent_rate); ++} ++ + static const struct clk_ops master_pres_ops = { + .prepare = clk_master_prepare, + .is_prepared = clk_master_is_prepared, + .recalc_rate = clk_master_pres_recalc_rate, + .get_parent = clk_master_pres_get_parent, ++ .save_context = clk_master_pres_save_context, ++ .restore_context = clk_master_pres_restore_context, + }; + + static const struct clk_ops master_pres_ops_chg = { +@@ -344,6 +485,8 @@ static const struct clk_ops master_pres_ops_chg = { + .recalc_rate = clk_master_pres_recalc_rate, + .get_parent = clk_master_pres_get_parent, + .set_rate = clk_master_pres_set_rate, ++ .save_context = clk_master_pres_save_context, ++ .restore_context = clk_master_pres_restore_context_chg, + }; + + static struct clk_hw * __init +@@ -539,20 +682,21 @@ static int clk_sama7g5_master_set_parent(struct clk_hw *hw, u8 index) + return 0; + } + +-static int clk_sama7g5_master_enable(struct clk_hw *hw) ++static void clk_sama7g5_master_set(struct clk_master *master, ++ unsigned int status) + { +- struct clk_master *master = to_clk_master(hw); + unsigned long flags; + unsigned int val, cparent; ++ unsigned int enable = status ? PMC_MCR_EN : 0; + + spin_lock_irqsave(master->lock, flags); + + regmap_write(master->regmap, PMC_MCR, PMC_MCR_ID(master->id)); + regmap_read(master->regmap, PMC_MCR, &val); + regmap_update_bits(master->regmap, PMC_MCR, +- PMC_MCR_EN | PMC_MCR_CSS | PMC_MCR_DIV | ++ enable | PMC_MCR_CSS | PMC_MCR_DIV | + PMC_MCR_CMD | PMC_MCR_ID_MSK, +- PMC_MCR_EN | (master->parent << PMC_MCR_CSS_SHIFT) | ++ enable | (master->parent << PMC_MCR_CSS_SHIFT) | + (master->div << MASTER_DIV_SHIFT) | + PMC_MCR_CMD | PMC_MCR_ID(master->id)); + +@@ -563,6 +707,13 @@ static int clk_sama7g5_master_enable(struct clk_hw *hw) + cpu_relax(); + + spin_unlock_irqrestore(master->lock, flags); ++} ++ ++static int clk_sama7g5_master_enable(struct clk_hw *hw) ++{ ++ struct clk_master *master = to_clk_master(hw); ++ ++ clk_sama7g5_master_set(master, 1); + + return 0; + } +@@ -620,6 +771,23 @@ static int clk_sama7g5_master_set_rate(struct clk_hw *hw, unsigned long rate, + return 0; + } + ++static int clk_sama7g5_master_save_context(struct clk_hw *hw) ++{ ++ struct clk_master *master = to_clk_master(hw); ++ ++ master->pms.status = clk_sama7g5_master_is_enabled(hw); ++ ++ return 0; ++} ++ ++static void clk_sama7g5_master_restore_context(struct clk_hw *hw) ++{ ++ struct clk_master *master = to_clk_master(hw); ++ ++ if (master->pms.status) ++ clk_sama7g5_master_set(master, master->pms.status); ++} ++ + static const struct clk_ops sama7g5_master_ops = { + .enable = clk_sama7g5_master_enable, + .disable = clk_sama7g5_master_disable, +@@ -629,6 +797,8 @@ static const struct clk_ops sama7g5_master_ops = { + .set_rate = clk_sama7g5_master_set_rate, + .get_parent = clk_sama7g5_master_get_parent, + .set_parent = clk_sama7g5_master_set_parent, ++ .save_context = clk_sama7g5_master_save_context, ++ .restore_context = clk_sama7g5_master_restore_context, + }; + + struct clk_hw * __init +diff --git a/drivers/clk/at91/clk-peripheral.c b/drivers/clk/at91/clk-peripheral.c +index 7a27ba8e0577..e14fa5ac734c 100644 +--- a/drivers/clk/at91/clk-peripheral.c ++++ b/drivers/clk/at91/clk-peripheral.c +@@ -37,6 +37,7 @@ struct clk_sam9x5_peripheral { + u32 id; + u32 div; + const struct clk_pcr_layout *layout; ++ struct at91_clk_pms pms; + bool auto_div; + int chg_pid; + }; +@@ -155,10 +156,11 @@ static void clk_sam9x5_peripheral_autodiv(struct clk_sam9x5_peripheral *periph) + periph->div = shift; + } + +-static int clk_sam9x5_peripheral_enable(struct clk_hw *hw) ++static int clk_sam9x5_peripheral_set(struct clk_sam9x5_peripheral *periph, ++ unsigned int status) + { +- struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); + unsigned long flags; ++ unsigned int enable = status ? AT91_PMC_PCR_EN : 0; + + if (periph->id < PERIPHERAL_ID_MIN) + return 0; +@@ -168,15 +170,21 @@ static int clk_sam9x5_peripheral_enable(struct clk_hw *hw) + (periph->id & periph->layout->pid_mask)); + regmap_update_bits(periph->regmap, periph->layout->offset, + periph->layout->div_mask | periph->layout->cmd | +- AT91_PMC_PCR_EN, ++ enable, + field_prep(periph->layout->div_mask, periph->div) | +- periph->layout->cmd | +- AT91_PMC_PCR_EN); ++ periph->layout->cmd | enable); + spin_unlock_irqrestore(periph->lock, flags); + + return 0; + } + ++static int clk_sam9x5_peripheral_enable(struct clk_hw *hw) ++{ ++ struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); ++ ++ return clk_sam9x5_peripheral_set(periph, 1); ++} ++ + static void clk_sam9x5_peripheral_disable(struct clk_hw *hw) + { + struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); +@@ -393,6 +401,23 @@ static int clk_sam9x5_peripheral_set_rate(struct clk_hw *hw, + return -EINVAL; + } + ++static int clk_sam9x5_peripheral_save_context(struct clk_hw *hw) ++{ ++ struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); ++ ++ periph->pms.status = clk_sam9x5_peripheral_is_enabled(hw); ++ ++ return 0; ++} ++ ++static void clk_sam9x5_peripheral_restore_context(struct clk_hw *hw) ++{ ++ struct clk_sam9x5_peripheral *periph = to_clk_sam9x5_peripheral(hw); ++ ++ if (periph->pms.status) ++ clk_sam9x5_peripheral_set(periph, periph->pms.status); ++} ++ + static const struct clk_ops sam9x5_peripheral_ops = { + .enable = clk_sam9x5_peripheral_enable, + .disable = clk_sam9x5_peripheral_disable, +@@ -400,6 +425,8 @@ static const struct clk_ops sam9x5_peripheral_ops = { + .recalc_rate = clk_sam9x5_peripheral_recalc_rate, + .round_rate = clk_sam9x5_peripheral_round_rate, + .set_rate = clk_sam9x5_peripheral_set_rate, ++ .save_context = clk_sam9x5_peripheral_save_context, ++ .restore_context = clk_sam9x5_peripheral_restore_context, + }; + + static const struct clk_ops sam9x5_peripheral_chg_ops = { +@@ -409,6 +436,8 @@ static const struct clk_ops sam9x5_peripheral_chg_ops = { + .recalc_rate = clk_sam9x5_peripheral_recalc_rate, + .determine_rate = clk_sam9x5_peripheral_determine_rate, + .set_rate = clk_sam9x5_peripheral_set_rate, ++ .save_context = clk_sam9x5_peripheral_save_context, ++ .restore_context = clk_sam9x5_peripheral_restore_context, + }; + + struct clk_hw * __init +@@ -460,7 +489,6 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock, + hw = ERR_PTR(ret); + } else { + clk_sam9x5_peripheral_autodiv(periph); +- pmc_register_id(id); + } + + return hw; +diff --git a/drivers/clk/at91/clk-pll.c b/drivers/clk/at91/clk-pll.c +index 6ed986d3eee0..249d6a53cedf 100644 +--- a/drivers/clk/at91/clk-pll.c ++++ b/drivers/clk/at91/clk-pll.c +@@ -40,6 +40,7 @@ struct clk_pll { + u16 mul; + const struct clk_pll_layout *layout; + const struct clk_pll_characteristics *characteristics; ++ struct at91_clk_pms pms; + }; + + static inline bool clk_pll_ready(struct regmap *regmap, int id) +@@ -260,6 +261,42 @@ static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, + return 0; + } + ++static int clk_pll_save_context(struct clk_hw *hw) ++{ ++ struct clk_pll *pll = to_clk_pll(hw); ++ struct clk_hw *parent_hw = clk_hw_get_parent(hw); ++ ++ pll->pms.parent_rate = clk_hw_get_rate(parent_hw); ++ pll->pms.rate = clk_pll_recalc_rate(&pll->hw, pll->pms.parent_rate); ++ pll->pms.status = clk_pll_ready(pll->regmap, PLL_REG(pll->id)); ++ ++ return 0; ++} ++ ++static void clk_pll_restore_context(struct clk_hw *hw) ++{ ++ struct clk_pll *pll = to_clk_pll(hw); ++ unsigned long calc_rate; ++ unsigned int pllr, pllr_out, pllr_count; ++ u8 out = 0; ++ ++ if (pll->characteristics->out) ++ out = pll->characteristics->out[pll->range]; ++ ++ regmap_read(pll->regmap, PLL_REG(pll->id), &pllr); ++ ++ calc_rate = (pll->pms.parent_rate / PLL_DIV(pllr)) * ++ (PLL_MUL(pllr, pll->layout) + 1); ++ pllr_count = (pllr >> PLL_COUNT_SHIFT) & PLL_MAX_COUNT; ++ pllr_out = (pllr >> PLL_OUT_SHIFT) & out; ++ ++ if (pll->pms.rate != calc_rate || ++ pll->pms.status != clk_pll_ready(pll->regmap, PLL_REG(pll->id)) || ++ pllr_count != PLL_MAX_COUNT || ++ (out && pllr_out != out)) ++ pr_warn("PLLAR was not configured properly by firmware\n"); ++} ++ + static const struct clk_ops pll_ops = { + .prepare = clk_pll_prepare, + .unprepare = clk_pll_unprepare, +@@ -267,6 +304,8 @@ static const struct clk_ops pll_ops = { + .recalc_rate = clk_pll_recalc_rate, + .round_rate = clk_pll_round_rate, + .set_rate = clk_pll_set_rate, ++ .save_context = clk_pll_save_context, ++ .restore_context = clk_pll_restore_context, + }; + + struct clk_hw * __init +diff --git a/drivers/clk/at91/clk-programmable.c b/drivers/clk/at91/clk-programmable.c +index fcf8f6a1c2c6..6c4b259d31d3 100644 +--- a/drivers/clk/at91/clk-programmable.c ++++ b/drivers/clk/at91/clk-programmable.c +@@ -24,6 +24,7 @@ struct clk_programmable { + u32 *mux_table; + u8 id; + const struct clk_programmable_layout *layout; ++ struct at91_clk_pms pms; + }; + + #define to_clk_programmable(hw) container_of(hw, struct clk_programmable, hw) +@@ -177,12 +178,38 @@ static int clk_programmable_set_rate(struct clk_hw *hw, unsigned long rate, + return 0; + } + ++static int clk_programmable_save_context(struct clk_hw *hw) ++{ ++ struct clk_programmable *prog = to_clk_programmable(hw); ++ struct clk_hw *parent_hw = clk_hw_get_parent(hw); ++ ++ prog->pms.parent = clk_programmable_get_parent(hw); ++ prog->pms.parent_rate = clk_hw_get_rate(parent_hw); ++ prog->pms.rate = clk_programmable_recalc_rate(hw, prog->pms.parent_rate); ++ ++ return 0; ++} ++ ++static void clk_programmable_restore_context(struct clk_hw *hw) ++{ ++ struct clk_programmable *prog = to_clk_programmable(hw); ++ int ret; ++ ++ ret = clk_programmable_set_parent(hw, prog->pms.parent); ++ if (ret) ++ return; ++ ++ clk_programmable_set_rate(hw, prog->pms.rate, prog->pms.parent_rate); ++} ++ + static const struct clk_ops programmable_ops = { + .recalc_rate = clk_programmable_recalc_rate, + .determine_rate = clk_programmable_determine_rate, + .get_parent = clk_programmable_get_parent, + .set_parent = clk_programmable_set_parent, + .set_rate = clk_programmable_set_rate, ++ .save_context = clk_programmable_save_context, ++ .restore_context = clk_programmable_restore_context, + }; + + struct clk_hw * __init +@@ -221,8 +248,6 @@ at91_clk_register_programmable(struct regmap *regmap, + if (ret) { + kfree(prog); + hw = ERR_PTR(ret); +- } else { +- pmc_register_pck(id); + } + + return hw; +diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c +index 1f52409475e9..a73d7c96ce1d 100644 +--- a/drivers/clk/at91/clk-sam9x60-pll.c ++++ b/drivers/clk/at91/clk-sam9x60-pll.c +@@ -38,12 +38,14 @@ struct sam9x60_pll_core { + + struct sam9x60_frac { + struct sam9x60_pll_core core; ++ struct at91_clk_pms pms; + u32 frac; + u16 mul; + }; + + struct sam9x60_div { + struct sam9x60_pll_core core; ++ struct at91_clk_pms pms; + u8 div; + }; + +@@ -75,9 +77,8 @@ static unsigned long sam9x60_frac_pll_recalc_rate(struct clk_hw *hw, + DIV_ROUND_CLOSEST_ULL((u64)parent_rate * frac->frac, (1 << 22)); + } + +-static int sam9x60_frac_pll_prepare(struct clk_hw *hw) ++static int sam9x60_frac_pll_set(struct sam9x60_pll_core *core) + { +- struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); + struct sam9x60_frac *frac = to_sam9x60_frac(core); + struct regmap *regmap = core->regmap; + unsigned int val, cfrac, cmul; +@@ -141,6 +142,13 @@ static int sam9x60_frac_pll_prepare(struct clk_hw *hw) + return 0; + } + ++static int sam9x60_frac_pll_prepare(struct clk_hw *hw) ++{ ++ struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); ++ ++ return sam9x60_frac_pll_set(core); ++} ++ + static void sam9x60_frac_pll_unprepare(struct clk_hw *hw) + { + struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); +@@ -280,6 +288,25 @@ static int sam9x60_frac_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate, + return ret; + } + ++static int sam9x60_frac_pll_save_context(struct clk_hw *hw) ++{ ++ struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); ++ struct sam9x60_frac *frac = to_sam9x60_frac(core); ++ ++ frac->pms.status = sam9x60_pll_ready(core->regmap, core->id); ++ ++ return 0; ++} ++ ++static void sam9x60_frac_pll_restore_context(struct clk_hw *hw) ++{ ++ struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); ++ struct sam9x60_frac *frac = to_sam9x60_frac(core); ++ ++ if (frac->pms.status) ++ sam9x60_frac_pll_set(core); ++} ++ + static const struct clk_ops sam9x60_frac_pll_ops = { + .prepare = sam9x60_frac_pll_prepare, + .unprepare = sam9x60_frac_pll_unprepare, +@@ -287,6 +314,8 @@ static const struct clk_ops sam9x60_frac_pll_ops = { + .recalc_rate = sam9x60_frac_pll_recalc_rate, + .round_rate = sam9x60_frac_pll_round_rate, + .set_rate = sam9x60_frac_pll_set_rate, ++ .save_context = sam9x60_frac_pll_save_context, ++ .restore_context = sam9x60_frac_pll_restore_context, + }; + + static const struct clk_ops sam9x60_frac_pll_ops_chg = { +@@ -296,11 +325,12 @@ static const struct clk_ops sam9x60_frac_pll_ops_chg = { + .recalc_rate = sam9x60_frac_pll_recalc_rate, + .round_rate = sam9x60_frac_pll_round_rate, + .set_rate = sam9x60_frac_pll_set_rate_chg, ++ .save_context = sam9x60_frac_pll_save_context, ++ .restore_context = sam9x60_frac_pll_restore_context, + }; + +-static int sam9x60_div_pll_prepare(struct clk_hw *hw) ++static int sam9x60_div_pll_set(struct sam9x60_pll_core *core) + { +- struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); + struct sam9x60_div *div = to_sam9x60_div(core); + struct regmap *regmap = core->regmap; + unsigned long flags; +@@ -334,6 +364,13 @@ static int sam9x60_div_pll_prepare(struct clk_hw *hw) + return 0; + } + ++static int sam9x60_div_pll_prepare(struct clk_hw *hw) ++{ ++ struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); ++ ++ return sam9x60_div_pll_set(core); ++} ++ + static void sam9x60_div_pll_unprepare(struct clk_hw *hw) + { + struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); +@@ -482,6 +519,25 @@ static int sam9x60_div_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate, + return 0; + } + ++static int sam9x60_div_pll_save_context(struct clk_hw *hw) ++{ ++ struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); ++ struct sam9x60_div *div = to_sam9x60_div(core); ++ ++ div->pms.status = sam9x60_div_pll_is_prepared(hw); ++ ++ return 0; ++} ++ ++static void sam9x60_div_pll_restore_context(struct clk_hw *hw) ++{ ++ struct sam9x60_pll_core *core = to_sam9x60_pll_core(hw); ++ struct sam9x60_div *div = to_sam9x60_div(core); ++ ++ if (div->pms.status) ++ sam9x60_div_pll_set(core); ++} ++ + static const struct clk_ops sam9x60_div_pll_ops = { + .prepare = sam9x60_div_pll_prepare, + .unprepare = sam9x60_div_pll_unprepare, +@@ -489,6 +545,8 @@ static const struct clk_ops sam9x60_div_pll_ops = { + .recalc_rate = sam9x60_div_pll_recalc_rate, + .round_rate = sam9x60_div_pll_round_rate, + .set_rate = sam9x60_div_pll_set_rate, ++ .save_context = sam9x60_div_pll_save_context, ++ .restore_context = sam9x60_div_pll_restore_context, + }; + + static const struct clk_ops sam9x60_div_pll_ops_chg = { +@@ -498,6 +556,8 @@ static const struct clk_ops sam9x60_div_pll_ops_chg = { + .recalc_rate = sam9x60_div_pll_recalc_rate, + .round_rate = sam9x60_div_pll_round_rate, + .set_rate = sam9x60_div_pll_set_rate_chg, ++ .save_context = sam9x60_div_pll_save_context, ++ .restore_context = sam9x60_div_pll_restore_context, + }; + + struct clk_hw * __init +diff --git a/drivers/clk/at91/clk-system.c b/drivers/clk/at91/clk-system.c +index f83ec0de86c3..80720fd1a9cf 100644 +--- a/drivers/clk/at91/clk-system.c ++++ b/drivers/clk/at91/clk-system.c +@@ -20,6 +20,7 @@ + struct clk_system { + struct clk_hw hw; + struct regmap *regmap; ++ struct at91_clk_pms pms; + u8 id; + }; + +@@ -77,10 +78,29 @@ static int clk_system_is_prepared(struct clk_hw *hw) + return !!(status & (1 << sys->id)); + } + ++static int clk_system_save_context(struct clk_hw *hw) ++{ ++ struct clk_system *sys = to_clk_system(hw); ++ ++ sys->pms.status = clk_system_is_prepared(hw); ++ ++ return 0; ++} ++ ++static void clk_system_restore_context(struct clk_hw *hw) ++{ ++ struct clk_system *sys = to_clk_system(hw); ++ ++ if (sys->pms.status) ++ clk_system_prepare(&sys->hw); ++} ++ + static const struct clk_ops system_ops = { + .prepare = clk_system_prepare, + .unprepare = clk_system_unprepare, + .is_prepared = clk_system_is_prepared, ++ .save_context = clk_system_save_context, ++ .restore_context = clk_system_restore_context, + }; + + struct clk_hw * __init +diff --git a/drivers/clk/at91/clk-usb.c b/drivers/clk/at91/clk-usb.c +index 31d5c45e30d7..b0696a928aa9 100644 +--- a/drivers/clk/at91/clk-usb.c ++++ b/drivers/clk/at91/clk-usb.c +@@ -24,6 +24,7 @@ + struct at91sam9x5_clk_usb { + struct clk_hw hw; + struct regmap *regmap; ++ struct at91_clk_pms pms; + u32 usbs_mask; + u8 num_parents; + }; +@@ -148,12 +149,38 @@ static int at91sam9x5_clk_usb_set_rate(struct clk_hw *hw, unsigned long rate, + return 0; + } + ++static int at91sam9x5_usb_save_context(struct clk_hw *hw) ++{ ++ struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); ++ struct clk_hw *parent_hw = clk_hw_get_parent(hw); ++ ++ usb->pms.parent = at91sam9x5_clk_usb_get_parent(hw); ++ usb->pms.parent_rate = clk_hw_get_rate(parent_hw); ++ usb->pms.rate = at91sam9x5_clk_usb_recalc_rate(hw, usb->pms.parent_rate); ++ ++ return 0; ++} ++ ++static void at91sam9x5_usb_restore_context(struct clk_hw *hw) ++{ ++ struct at91sam9x5_clk_usb *usb = to_at91sam9x5_clk_usb(hw); ++ int ret; ++ ++ ret = at91sam9x5_clk_usb_set_parent(hw, usb->pms.parent); ++ if (ret) ++ return; ++ ++ at91sam9x5_clk_usb_set_rate(hw, usb->pms.rate, usb->pms.parent_rate); ++} ++ + static const struct clk_ops at91sam9x5_usb_ops = { + .recalc_rate = at91sam9x5_clk_usb_recalc_rate, + .determine_rate = at91sam9x5_clk_usb_determine_rate, + .get_parent = at91sam9x5_clk_usb_get_parent, + .set_parent = at91sam9x5_clk_usb_set_parent, + .set_rate = at91sam9x5_clk_usb_set_rate, ++ .save_context = at91sam9x5_usb_save_context, ++ .restore_context = at91sam9x5_usb_restore_context, + }; + + static int at91sam9n12_clk_usb_enable(struct clk_hw *hw) +diff --git a/drivers/clk/at91/clk-utmi.c b/drivers/clk/at91/clk-utmi.c +index df9f3fc3b6a6..a22c10d9a1b9 100644 +--- a/drivers/clk/at91/clk-utmi.c ++++ b/drivers/clk/at91/clk-utmi.c +@@ -23,6 +23,7 @@ struct clk_utmi { + struct clk_hw hw; + struct regmap *regmap_pmc; + struct regmap *regmap_sfr; ++ struct at91_clk_pms pms; + }; + + #define to_clk_utmi(hw) container_of(hw, struct clk_utmi, hw) +@@ -113,11 +114,30 @@ static unsigned long clk_utmi_recalc_rate(struct clk_hw *hw, + return UTMI_RATE; + } + ++static int clk_utmi_save_context(struct clk_hw *hw) ++{ ++ struct clk_utmi *utmi = to_clk_utmi(hw); ++ ++ utmi->pms.status = clk_utmi_is_prepared(hw); ++ ++ return 0; ++} ++ ++static void clk_utmi_restore_context(struct clk_hw *hw) ++{ ++ struct clk_utmi *utmi = to_clk_utmi(hw); ++ ++ if (utmi->pms.status) ++ clk_utmi_prepare(hw); ++} ++ + static const struct clk_ops utmi_ops = { + .prepare = clk_utmi_prepare, + .unprepare = clk_utmi_unprepare, + .is_prepared = clk_utmi_is_prepared, + .recalc_rate = clk_utmi_recalc_rate, ++ .save_context = clk_utmi_save_context, ++ .restore_context = clk_utmi_restore_context, + }; + + static struct clk_hw * __init +@@ -232,10 +252,29 @@ static int clk_utmi_sama7g5_is_prepared(struct clk_hw *hw) + return 0; + } + ++static int clk_utmi_sama7g5_save_context(struct clk_hw *hw) ++{ ++ struct clk_utmi *utmi = to_clk_utmi(hw); ++ ++ utmi->pms.status = clk_utmi_sama7g5_is_prepared(hw); ++ ++ return 0; ++} ++ ++static void clk_utmi_sama7g5_restore_context(struct clk_hw *hw) ++{ ++ struct clk_utmi *utmi = to_clk_utmi(hw); ++ ++ if (utmi->pms.status) ++ clk_utmi_sama7g5_prepare(hw); ++} ++ + static const struct clk_ops sama7g5_utmi_ops = { + .prepare = clk_utmi_sama7g5_prepare, + .is_prepared = clk_utmi_sama7g5_is_prepared, + .recalc_rate = clk_utmi_recalc_rate, ++ .save_context = clk_utmi_sama7g5_save_context, ++ .restore_context = clk_utmi_sama7g5_restore_context, + }; + + struct clk_hw * __init +diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c +index b40035b011d0..b2806946a77a 100644 +--- a/drivers/clk/at91/pmc.c ++++ b/drivers/clk/at91/pmc.c +@@ -3,6 +3,7 @@ + * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> + */ + ++#include <linux/clk.h> + #include <linux/clk-provider.h> + #include <linux/clkdev.h> + #include <linux/clk/at91_pmc.h> +@@ -14,8 +15,6 @@ + + #include <asm/proc-fns.h> + +-#include <dt-bindings/clock/at91.h> +- + #include "pmc.h" + + #define PMC_MAX_IDS 128 +@@ -111,147 +110,19 @@ struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem, + } + + #ifdef CONFIG_PM +-static struct regmap *pmcreg; +- +-static u8 registered_ids[PMC_MAX_IDS]; +-static u8 registered_pcks[PMC_MAX_PCKS]; +- +-static struct +-{ +- u32 scsr; +- u32 pcsr0; +- u32 uckr; +- u32 mor; +- u32 mcfr; +- u32 pllar; +- u32 mckr; +- u32 usb; +- u32 imr; +- u32 pcsr1; +- u32 pcr[PMC_MAX_IDS]; +- u32 audio_pll0; +- u32 audio_pll1; +- u32 pckr[PMC_MAX_PCKS]; +-} pmc_cache; +- +-/* +- * As Peripheral ID 0 is invalid on AT91 chips, the identifier is stored +- * without alteration in the table, and 0 is for unused clocks. +- */ +-void pmc_register_id(u8 id) +-{ +- int i; +- +- for (i = 0; i < PMC_MAX_IDS; i++) { +- if (registered_ids[i] == 0) { +- registered_ids[i] = id; +- break; +- } +- if (registered_ids[i] == id) +- break; +- } +-} +- +-/* +- * As Programmable Clock 0 is valid on AT91 chips, there is an offset +- * of 1 between the stored value and the real clock ID. +- */ +-void pmc_register_pck(u8 pck) +-{ +- int i; +- +- for (i = 0; i < PMC_MAX_PCKS; i++) { +- if (registered_pcks[i] == 0) { +- registered_pcks[i] = pck + 1; +- break; +- } +- if (registered_pcks[i] == (pck + 1)) +- break; +- } +-} +- +-static int pmc_suspend(void) ++static int at91_pmc_suspend(void) + { +- int i; +- u8 num; +- +- regmap_read(pmcreg, AT91_PMC_SCSR, &pmc_cache.scsr); +- regmap_read(pmcreg, AT91_PMC_PCSR, &pmc_cache.pcsr0); +- regmap_read(pmcreg, AT91_CKGR_UCKR, &pmc_cache.uckr); +- regmap_read(pmcreg, AT91_CKGR_MOR, &pmc_cache.mor); +- regmap_read(pmcreg, AT91_CKGR_MCFR, &pmc_cache.mcfr); +- regmap_read(pmcreg, AT91_CKGR_PLLAR, &pmc_cache.pllar); +- regmap_read(pmcreg, AT91_PMC_MCKR, &pmc_cache.mckr); +- regmap_read(pmcreg, AT91_PMC_USB, &pmc_cache.usb); +- regmap_read(pmcreg, AT91_PMC_IMR, &pmc_cache.imr); +- regmap_read(pmcreg, AT91_PMC_PCSR1, &pmc_cache.pcsr1); +- +- for (i = 0; registered_ids[i]; i++) { +- regmap_write(pmcreg, AT91_PMC_PCR, +- (registered_ids[i] & AT91_PMC_PCR_PID_MASK)); +- regmap_read(pmcreg, AT91_PMC_PCR, +- &pmc_cache.pcr[registered_ids[i]]); +- } +- for (i = 0; registered_pcks[i]; i++) { +- num = registered_pcks[i] - 1; +- regmap_read(pmcreg, AT91_PMC_PCKR(num), &pmc_cache.pckr[num]); +- } +- +- return 0; ++ return clk_save_context(); + } + +-static bool pmc_ready(unsigned int mask) ++static void at91_pmc_resume(void) + { +- unsigned int status; +- +- regmap_read(pmcreg, AT91_PMC_SR, &status); +- +- return ((status & mask) == mask) ? 1 : 0; +-} +- +-static void pmc_resume(void) +-{ +- int i; +- u8 num; +- u32 tmp; +- u32 mask = AT91_PMC_MCKRDY | AT91_PMC_LOCKA; +- +- regmap_read(pmcreg, AT91_PMC_MCKR, &tmp); +- if (pmc_cache.mckr != tmp) +- pr_warn("MCKR was not configured properly by the firmware\n"); +- regmap_read(pmcreg, AT91_CKGR_PLLAR, &tmp); +- if (pmc_cache.pllar != tmp) +- pr_warn("PLLAR was not configured properly by the firmware\n"); +- +- regmap_write(pmcreg, AT91_PMC_SCER, pmc_cache.scsr); +- regmap_write(pmcreg, AT91_PMC_PCER, pmc_cache.pcsr0); +- regmap_write(pmcreg, AT91_CKGR_UCKR, pmc_cache.uckr); +- regmap_write(pmcreg, AT91_CKGR_MOR, pmc_cache.mor); +- regmap_write(pmcreg, AT91_CKGR_MCFR, pmc_cache.mcfr); +- regmap_write(pmcreg, AT91_PMC_USB, pmc_cache.usb); +- regmap_write(pmcreg, AT91_PMC_IMR, pmc_cache.imr); +- regmap_write(pmcreg, AT91_PMC_PCER1, pmc_cache.pcsr1); +- +- for (i = 0; registered_ids[i]; i++) { +- regmap_write(pmcreg, AT91_PMC_PCR, +- pmc_cache.pcr[registered_ids[i]] | +- AT91_PMC_PCR_CMD); +- } +- for (i = 0; registered_pcks[i]; i++) { +- num = registered_pcks[i] - 1; +- regmap_write(pmcreg, AT91_PMC_PCKR(num), pmc_cache.pckr[num]); +- } +- +- if (pmc_cache.uckr & AT91_PMC_UPLLEN) +- mask |= AT91_PMC_LOCKU; +- +- while (!pmc_ready(mask)) +- cpu_relax(); ++ clk_restore_context(); + } + + static struct syscore_ops pmc_syscore_ops = { +- .suspend = pmc_suspend, +- .resume = pmc_resume, ++ .suspend = at91_pmc_suspend, ++ .resume = at91_pmc_resume, + }; + + static const struct of_device_id sama5d2_pmc_dt_ids[] = { +@@ -271,11 +142,7 @@ static int __init pmc_register_ops(void) + of_node_put(np); + return -ENODEV; + } +- +- pmcreg = device_node_to_regmap(np); + of_node_put(np); +- if (IS_ERR(pmcreg)) +- return PTR_ERR(pmcreg); + + register_syscore_ops(&pmc_syscore_ops); + +diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h +index a49076c804a9..45df094498ce 100644 +--- a/drivers/clk/at91/pmc.h ++++ b/drivers/clk/at91/pmc.h +@@ -13,6 +13,8 @@ + #include <linux/regmap.h> + #include <linux/spinlock.h> + ++#include <dt-bindings/clock/at91.h> ++ + extern spinlock_t pmc_pcr_lock; + + struct pmc_data { +@@ -98,6 +100,20 @@ struct clk_pcr_layout { + u32 pid_mask; + }; + ++/** ++ * struct at91_clk_pms - Power management state for AT91 clock ++ * @rate: clock rate ++ * @parent_rate: clock parent rate ++ * @status: clock status (enabled or disabled) ++ * @parent: clock parent index ++ */ ++struct at91_clk_pms { ++ unsigned long rate; ++ unsigned long parent_rate; ++ unsigned int status; ++ unsigned int parent; ++}; ++ + #define field_get(_mask, _reg) (((_reg) & (_mask)) >> (ffs(_mask) - 1)) + #define field_prep(_mask, _val) (((_val) << (ffs(_mask) - 1)) & (_mask)) + +@@ -248,12 +264,4 @@ struct clk_hw * __init + at91_clk_sama7g5_register_utmi(struct regmap *regmap, const char *name, + const char *parent_name); + +-#ifdef CONFIG_PM +-void pmc_register_id(u8 id); +-void pmc_register_pck(u8 pck); +-#else +-static inline void pmc_register_id(u8 id) {} +-static inline void pmc_register_pck(u8 pck) {} +-#endif +- + #endif /* __PMC_H_ */ +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/235-clk-at91-pmc-execute-suspend-resume-only-for-backup-.patch b/target/linux/at91/patches-5.10/235-clk-at91-pmc-execute-suspend-resume-only-for-backup-.patch new file mode 100644 index 0000000000..2f8dcf6217 --- /dev/null +++ b/target/linux/at91/patches-5.10/235-clk-at91-pmc-execute-suspend-resume-only-for-backup-.patch @@ -0,0 +1,94 @@ +From 63a0c32028148e91ea91cfbf95841c4ecd69d21b Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Mon, 11 Oct 2021 14:27:06 +0300 +Subject: [PATCH 235/247] clk: at91: pmc: execute suspend/resume only for + backup mode + +Before going to backup mode architecture specific PM code sets the first +word in securam (file arch/arm/mach-at91/pm.c, function at91_pm_begin()). +Thus take this into account when suspending/resuming clocks. This will +avoid executing unnecessary instructions when suspending to non backup +modes. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/20211011112719.3951784-3-claudiu.beznea@microchip.com +Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/pmc.c | 39 +++++++++++++++++++++++++++++++++++++++ + 1 file changed, 39 insertions(+) + +diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c +index b2806946a77a..517973062719 100644 +--- a/drivers/clk/at91/pmc.c ++++ b/drivers/clk/at91/pmc.c +@@ -8,6 +8,7 @@ + #include <linux/clkdev.h> + #include <linux/clk/at91_pmc.h> + #include <linux/of.h> ++#include <linux/of_address.h> + #include <linux/mfd/syscon.h> + #include <linux/platform_device.h> + #include <linux/regmap.h> +@@ -110,13 +111,35 @@ struct pmc_data *pmc_data_allocate(unsigned int ncore, unsigned int nsystem, + } + + #ifdef CONFIG_PM ++ ++/* Address in SECURAM that say if we suspend to backup mode. */ ++static void __iomem *at91_pmc_backup_suspend; ++ + static int at91_pmc_suspend(void) + { ++ unsigned int backup; ++ ++ if (!at91_pmc_backup_suspend) ++ return 0; ++ ++ backup = readl_relaxed(at91_pmc_backup_suspend); ++ if (!backup) ++ return 0; ++ + return clk_save_context(); + } + + static void at91_pmc_resume(void) + { ++ unsigned int backup; ++ ++ if (!at91_pmc_backup_suspend) ++ return; ++ ++ backup = readl_relaxed(at91_pmc_backup_suspend); ++ if (!backup) ++ return; ++ + clk_restore_context(); + } + +@@ -144,6 +167,22 @@ static int __init pmc_register_ops(void) + } + of_node_put(np); + ++ np = of_find_compatible_node(NULL, NULL, "atmel,sama5d2-securam"); ++ if (!np) ++ return -ENODEV; ++ ++ if (!of_device_is_available(np)) { ++ of_node_put(np); ++ return -ENODEV; ++ } ++ of_node_put(np); ++ ++ at91_pmc_backup_suspend = of_iomap(np, 0); ++ if (!at91_pmc_backup_suspend) { ++ pr_warn("%s(): unable to map securam\n", __func__); ++ return -ENOMEM; ++ } ++ + register_syscore_ops(&pmc_syscore_ops); + + return 0; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/236-clk-at91-sama7g5-add-securam-s-peripheral-clock.patch b/target/linux/at91/patches-5.10/236-clk-at91-sama7g5-add-securam-s-peripheral-clock.patch new file mode 100644 index 0000000000..a2f91a842d --- /dev/null +++ b/target/linux/at91/patches-5.10/236-clk-at91-sama7g5-add-securam-s-peripheral-clock.patch @@ -0,0 +1,30 @@ +From 50edd53c26177e95995533b7d649801086a52f6c Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Mon, 11 Oct 2021 14:27:07 +0300 +Subject: [PATCH 236/247] clk: at91: sama7g5: add securam's peripheral clock + +Add SECURAM's peripheral clock. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Link: https://lore.kernel.org/r/20211011112719.3951784-4-claudiu.beznea@microchip.com +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/sama7g5.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c +index cf8c079aa086..970135e19a75 100644 +--- a/drivers/clk/at91/sama7g5.c ++++ b/drivers/clk/at91/sama7g5.c +@@ -377,6 +377,7 @@ static const struct { + u8 id; + } sama7g5_periphck[] = { + { .n = "pioA_clk", .p = "mck0", .id = 11, }, ++ { .n = "securam_clk", .p = "mck0", .id = 18, }, + { .n = "sfr_clk", .p = "mck1", .id = 19, }, + { .n = "hsmc_clk", .p = "mck1", .id = 21, }, + { .n = "xdmac0_clk", .p = "mck1", .id = 22, }, +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/237-clk-at91-clk-master-add-register-definition-for-sama.patch b/target/linux/at91/patches-5.10/237-clk-at91-clk-master-add-register-definition-for-sama.patch new file mode 100644 index 0000000000..026b65fc01 --- /dev/null +++ b/target/linux/at91/patches-5.10/237-clk-at91-clk-master-add-register-definition-for-sama.patch @@ -0,0 +1,129 @@ +From c716562753d1e51a1c53647aa77a332f97187d15 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Mon, 11 Oct 2021 14:27:08 +0300 +Subject: [PATCH 237/247] clk: at91: clk-master: add register definition for + sama7g5's master clock + +SAMA7G5 has 4 master clocks (MCK1..4) which are controlled though the +register at offset 0x30 (relative to PMC). In the last/first phase of +suspend/resume procedure (which is architecture specific) the parent +of master clocks are changed (via assembly code) for more power saving +(see file arch/arm/mach-at91/pm_suspend.S, macros at91_mckx_ps_enable +and at91_mckx_ps_restore). Thus the macros corresponding to register +at offset 0x30 need to be shared b/w clk-master.c and pm_suspend.S. +commit ec03f18cc222 ("clk: at91: add register definition for sama7g5's +master clock") introduced the proper macros but didn't adapted the +clk-master.c as well. Thus, this commit adapt the clk-master.c to use +the macros introduced in commit ec03f18cc222 ("clk: at91: add register +definition for sama7g5's master clock"). + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/20211011112719.3951784-5-claudiu.beznea@microchip.com +Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/clk-master.c | 50 ++++++++++++++++------------------- + 1 file changed, 23 insertions(+), 27 deletions(-) + +diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c +index f75549fff023..88f7af1bfff6 100644 +--- a/drivers/clk/at91/clk-master.c ++++ b/drivers/clk/at91/clk-master.c +@@ -17,15 +17,7 @@ + #define MASTER_DIV_SHIFT 8 + #define MASTER_DIV_MASK 0x7 + +-#define PMC_MCR 0x30 +-#define PMC_MCR_ID_MSK GENMASK(3, 0) +-#define PMC_MCR_CMD BIT(7) +-#define PMC_MCR_DIV GENMASK(10, 8) +-#define PMC_MCR_CSS GENMASK(20, 16) + #define PMC_MCR_CSS_SHIFT (16) +-#define PMC_MCR_EN BIT(28) +- +-#define PMC_MCR_ID(x) ((x) & PMC_MCR_ID_MSK) + + #define MASTER_MAX_ID 4 + +@@ -687,20 +679,22 @@ static void clk_sama7g5_master_set(struct clk_master *master, + { + unsigned long flags; + unsigned int val, cparent; +- unsigned int enable = status ? PMC_MCR_EN : 0; ++ unsigned int enable = status ? AT91_PMC_MCR_V2_EN : 0; + + spin_lock_irqsave(master->lock, flags); + +- regmap_write(master->regmap, PMC_MCR, PMC_MCR_ID(master->id)); +- regmap_read(master->regmap, PMC_MCR, &val); +- regmap_update_bits(master->regmap, PMC_MCR, +- enable | PMC_MCR_CSS | PMC_MCR_DIV | +- PMC_MCR_CMD | PMC_MCR_ID_MSK, ++ regmap_write(master->regmap, AT91_PMC_MCR_V2, ++ AT91_PMC_MCR_V2_ID(master->id)); ++ regmap_read(master->regmap, AT91_PMC_MCR_V2, &val); ++ regmap_update_bits(master->regmap, AT91_PMC_MCR_V2, ++ enable | AT91_PMC_MCR_V2_CSS | AT91_PMC_MCR_V2_DIV | ++ AT91_PMC_MCR_V2_CMD | AT91_PMC_MCR_V2_ID_MSK, + enable | (master->parent << PMC_MCR_CSS_SHIFT) | + (master->div << MASTER_DIV_SHIFT) | +- PMC_MCR_CMD | PMC_MCR_ID(master->id)); ++ AT91_PMC_MCR_V2_CMD | ++ AT91_PMC_MCR_V2_ID(master->id)); + +- cparent = (val & PMC_MCR_CSS) >> PMC_MCR_CSS_SHIFT; ++ cparent = (val & AT91_PMC_MCR_V2_CSS) >> PMC_MCR_CSS_SHIFT; + + /* Wait here only if parent is being changed. */ + while ((cparent != master->parent) && !clk_master_ready(master)) +@@ -725,10 +719,12 @@ static void clk_sama7g5_master_disable(struct clk_hw *hw) + + spin_lock_irqsave(master->lock, flags); + +- regmap_write(master->regmap, PMC_MCR, master->id); +- regmap_update_bits(master->regmap, PMC_MCR, +- PMC_MCR_EN | PMC_MCR_CMD | PMC_MCR_ID_MSK, +- PMC_MCR_CMD | PMC_MCR_ID(master->id)); ++ regmap_write(master->regmap, AT91_PMC_MCR_V2, master->id); ++ regmap_update_bits(master->regmap, AT91_PMC_MCR_V2, ++ AT91_PMC_MCR_V2_EN | AT91_PMC_MCR_V2_CMD | ++ AT91_PMC_MCR_V2_ID_MSK, ++ AT91_PMC_MCR_V2_CMD | ++ AT91_PMC_MCR_V2_ID(master->id)); + + spin_unlock_irqrestore(master->lock, flags); + } +@@ -741,12 +737,12 @@ static int clk_sama7g5_master_is_enabled(struct clk_hw *hw) + + spin_lock_irqsave(master->lock, flags); + +- regmap_write(master->regmap, PMC_MCR, master->id); +- regmap_read(master->regmap, PMC_MCR, &val); ++ regmap_write(master->regmap, AT91_PMC_MCR_V2, master->id); ++ regmap_read(master->regmap, AT91_PMC_MCR_V2, &val); + + spin_unlock_irqrestore(master->lock, flags); + +- return !!(val & PMC_MCR_EN); ++ return !!(val & AT91_PMC_MCR_V2_EN); + } + + static int clk_sama7g5_master_set_rate(struct clk_hw *hw, unsigned long rate, +@@ -842,10 +838,10 @@ at91_clk_sama7g5_register_master(struct regmap *regmap, + master->mux_table = mux_table; + + spin_lock_irqsave(master->lock, flags); +- regmap_write(master->regmap, PMC_MCR, master->id); +- regmap_read(master->regmap, PMC_MCR, &val); +- master->parent = (val & PMC_MCR_CSS) >> PMC_MCR_CSS_SHIFT; +- master->div = (val & PMC_MCR_DIV) >> MASTER_DIV_SHIFT; ++ regmap_write(master->regmap, AT91_PMC_MCR_V2, master->id); ++ regmap_read(master->regmap, AT91_PMC_MCR_V2, &val); ++ master->parent = (val & AT91_PMC_MCR_V2_CSS) >> PMC_MCR_CSS_SHIFT; ++ master->div = (val & AT91_PMC_MCR_V2_DIV) >> MASTER_DIV_SHIFT; + spin_unlock_irqrestore(master->lock, flags); + + hw = &master->hw; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/238-clk-at91-clk-master-improve-readability-by-using-loc.patch b/target/linux/at91/patches-5.10/238-clk-at91-clk-master-improve-readability-by-using-loc.patch new file mode 100644 index 0000000000..df53d453f8 --- /dev/null +++ b/target/linux/at91/patches-5.10/238-clk-at91-clk-master-improve-readability-by-using-loc.patch @@ -0,0 +1,45 @@ +From 17b53ad1574cb5f41789993289d3d94f7a50f0ce Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Mon, 11 Oct 2021 14:27:09 +0300 +Subject: [PATCH 238/247] clk: at91: clk-master: improve readability by using + local variables + +Improve readability in clk_sama7g5_master_set() by using local +variables. + +Suggested-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/20211011112719.3951784-6-claudiu.beznea@microchip.com +Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/clk-master.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c +index 88f7af1bfff6..9a2c8e64cacf 100644 +--- a/drivers/clk/at91/clk-master.c ++++ b/drivers/clk/at91/clk-master.c +@@ -680,6 +680,8 @@ static void clk_sama7g5_master_set(struct clk_master *master, + unsigned long flags; + unsigned int val, cparent; + unsigned int enable = status ? AT91_PMC_MCR_V2_EN : 0; ++ unsigned int parent = master->parent << PMC_MCR_CSS_SHIFT; ++ unsigned int div = master->div << MASTER_DIV_SHIFT; + + spin_lock_irqsave(master->lock, flags); + +@@ -689,9 +691,7 @@ static void clk_sama7g5_master_set(struct clk_master *master, + regmap_update_bits(master->regmap, AT91_PMC_MCR_V2, + enable | AT91_PMC_MCR_V2_CSS | AT91_PMC_MCR_V2_DIV | + AT91_PMC_MCR_V2_CMD | AT91_PMC_MCR_V2_ID_MSK, +- enable | (master->parent << PMC_MCR_CSS_SHIFT) | +- (master->div << MASTER_DIV_SHIFT) | +- AT91_PMC_MCR_V2_CMD | ++ enable | parent | div | AT91_PMC_MCR_V2_CMD | + AT91_PMC_MCR_V2_ID(master->id)); + + cparent = (val & AT91_PMC_MCR_V2_CSS) >> PMC_MCR_CSS_SHIFT; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/239-clk-at91-pmc-add-sama7g5-to-the-list-of-available-pm.patch b/target/linux/at91/patches-5.10/239-clk-at91-pmc-add-sama7g5-to-the-list-of-available-pm.patch new file mode 100644 index 0000000000..6569d7a9ee --- /dev/null +++ b/target/linux/at91/patches-5.10/239-clk-at91-pmc-add-sama7g5-to-the-list-of-available-pm.patch @@ -0,0 +1,44 @@ +From 8a38e0dda46c9d941a61d8b2e6c14704531b7871 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Mon, 11 Oct 2021 14:27:10 +0300 +Subject: [PATCH 239/247] clk: at91: pmc: add sama7g5 to the list of available + pmcs + +Add SAMA7G5 to the list of available PMCs such that the suspend/resume +code for clocks to be used on backup mode. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/20211011112719.3951784-7-claudiu.beznea@microchip.com +Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/pmc.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c +index 517973062719..5aa9c1f1c886 100644 +--- a/drivers/clk/at91/pmc.c ++++ b/drivers/clk/at91/pmc.c +@@ -148,8 +148,9 @@ static struct syscore_ops pmc_syscore_ops = { + .resume = at91_pmc_resume, + }; + +-static const struct of_device_id sama5d2_pmc_dt_ids[] = { ++static const struct of_device_id pmc_dt_ids[] = { + { .compatible = "atmel,sama5d2-pmc" }, ++ { .compatible = "microchip,sama7g5-pmc", }, + { /* sentinel */ } + }; + +@@ -157,7 +158,7 @@ static int __init pmc_register_ops(void) + { + struct device_node *np; + +- np = of_find_matching_node(NULL, sama5d2_pmc_dt_ids); ++ np = of_find_matching_node(NULL, pmc_dt_ids); + if (!np) + return -ENODEV; + +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/240-clk-at91-clk-master-check-if-div-or-pres-is-zero.patch b/target/linux/at91/patches-5.10/240-clk-at91-clk-master-check-if-div-or-pres-is-zero.patch new file mode 100644 index 0000000000..6bcc3df498 --- /dev/null +++ b/target/linux/at91/patches-5.10/240-clk-at91-clk-master-check-if-div-or-pres-is-zero.patch @@ -0,0 +1,44 @@ +From bb8e6ca274763fa98613dbe8b0833348a1d8fe4d Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Mon, 11 Oct 2021 14:27:12 +0300 +Subject: [PATCH 240/247] clk: at91: clk-master: check if div or pres is zero + +Check if div or pres is zero before using it as argument for ffs(). +In case div is zero ffs() will return 0 and thus substracting from +zero will lead to invalid values to be setup in registers. + +Fixes: 7a110b9107ed8 ("clk: at91: clk-master: re-factor master clock") +Fixes: 75c88143f3b87 ("clk: at91: clk-master: add master clock support for SAMA7G5") +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/20211011112719.3951784-9-claudiu.beznea@microchip.com +Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/clk-master.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c +index 9a2c8e64cacf..2093e13b5068 100644 +--- a/drivers/clk/at91/clk-master.c ++++ b/drivers/clk/at91/clk-master.c +@@ -344,7 +344,7 @@ static int clk_master_pres_set_rate(struct clk_hw *hw, unsigned long rate, + + else if (pres == 3) + pres = MASTER_PRES_MAX; +- else ++ else if (pres) + pres = ffs(pres) - 1; + + spin_lock_irqsave(master->lock, flags); +@@ -757,7 +757,7 @@ static int clk_sama7g5_master_set_rate(struct clk_hw *hw, unsigned long rate, + + if (div == 3) + div = MASTER_PRES_MAX; +- else ++ else if (div) + div = ffs(div) - 1; + + spin_lock_irqsave(master->lock, flags); +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/241-clk-at91-clk-master-mask-mckr-against-layout-mask.patch b/target/linux/at91/patches-5.10/241-clk-at91-clk-master-mask-mckr-against-layout-mask.patch new file mode 100644 index 0000000000..2f53a44eae --- /dev/null +++ b/target/linux/at91/patches-5.10/241-clk-at91-clk-master-mask-mckr-against-layout-mask.patch @@ -0,0 +1,51 @@ +From 27c11c09346b7b9f67eeb39db1b943f4a9742ff3 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Mon, 11 Oct 2021 14:27:13 +0300 +Subject: [PATCH 241/247] clk: at91: clk-master: mask mckr against layout->mask + +Mask values read/written from/to MCKR against layout->mask as this +mask may be different b/w PMC versions. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/20211011112719.3951784-10-claudiu.beznea@microchip.com +Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/clk-master.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c +index 2093e13b5068..6da9ae34313a 100644 +--- a/drivers/clk/at91/clk-master.c ++++ b/drivers/clk/at91/clk-master.c +@@ -186,8 +186,8 @@ static int clk_master_div_set_rate(struct clk_hw *hw, unsigned long rate, + if (ret) + goto unlock; + +- tmp = mckr & master->layout->mask; +- tmp = (tmp >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; ++ mckr &= master->layout->mask; ++ tmp = (mckr >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; + if (tmp == div) + goto unlock; + +@@ -384,6 +384,7 @@ static unsigned long clk_master_pres_recalc_rate(struct clk_hw *hw, + regmap_read(master->regmap, master->layout->offset, &val); + spin_unlock_irqrestore(master->lock, flags); + ++ val &= master->layout->mask; + pres = (val >> master->layout->pres_shift) & MASTER_PRES_MASK; + if (pres == 3 && characteristics->have_div3_pres) + pres = 3; +@@ -403,6 +404,8 @@ static u8 clk_master_pres_get_parent(struct clk_hw *hw) + regmap_read(master->regmap, master->layout->offset, &mckr); + spin_unlock_irqrestore(master->lock, flags); + ++ mckr &= master->layout->mask; ++ + return mckr & AT91_PMC_CSS; + } + +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/242-clk-at91-clk-master-fix-prescaler-logic.patch b/target/linux/at91/patches-5.10/242-clk-at91-clk-master-fix-prescaler-logic.patch new file mode 100644 index 0000000000..3562d4ec21 --- /dev/null +++ b/target/linux/at91/patches-5.10/242-clk-at91-clk-master-fix-prescaler-logic.patch @@ -0,0 +1,34 @@ +From 4375cd63b55860f5e82618dc5f50846b3129842a Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Mon, 11 Oct 2021 14:27:14 +0300 +Subject: [PATCH 242/247] clk: at91: clk-master: fix prescaler logic + +When prescaler value read from register is MASTER_PRES_MAX it means +that the input clock will be divided by 3. Fix the code to reflect +this. + +Fixes: 7a110b9107ed8 ("clk: at91: clk-master: re-factor master clock") +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/20211011112719.3951784-11-claudiu.beznea@microchip.com +Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/clk-master.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c +index 6da9ae34313a..e67bcd03a827 100644 +--- a/drivers/clk/at91/clk-master.c ++++ b/drivers/clk/at91/clk-master.c +@@ -386,7 +386,7 @@ static unsigned long clk_master_pres_recalc_rate(struct clk_hw *hw, + + val &= master->layout->mask; + pres = (val >> master->layout->pres_shift) & MASTER_PRES_MASK; +- if (pres == 3 && characteristics->have_div3_pres) ++ if (pres == MASTER_PRES_MAX && characteristics->have_div3_pres) + pres = 3; + else + pres = (1 << pres); +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/243-clk-at91-clk-sam9x60-pll-add-notifier-for-div-part-o.patch b/target/linux/at91/patches-5.10/243-clk-at91-clk-sam9x60-pll-add-notifier-for-div-part-o.patch new file mode 100644 index 0000000000..f101f71fcd --- /dev/null +++ b/target/linux/at91/patches-5.10/243-clk-at91-clk-sam9x60-pll-add-notifier-for-div-part-o.patch @@ -0,0 +1,323 @@ +From e76d2af5009f52aa02d3db7ae32d150ad66398f9 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Mon, 11 Oct 2021 14:27:15 +0300 +Subject: [PATCH 243/247] clk: at91: clk-sam9x60-pll: add notifier for div part + of PLL + +SAM9X60's PLL which is also part of SAMA7G5 is composed of 2 parts: +one fractional part and one divider. On SAMA7G5 the CPU PLL could be +changed at run-time to implement DVFS. The hardware clock tree on +SAMA7G5 for CPU PLL is as follows: + + +---- div1 ----------------> cpuck + | +FRAC PLL ---> DIV PLL -+-> prescaler ---> div0 ---> mck0 + +The div1 block is not implemented in Linux; on prescaler block it has +been discovered a bug on some scenarios and will be removed from Linux +in next commits. Thus, the final clock tree that will be used in Linux +will be as follows: + + +-----------> cpuck + | +FRAC PLL ---> DIV PLL -+-> div0 ---> mck0 + +It has been proposed in [1] to not introduce a new CPUFreq driver but +to overload the proper clock drivers with proper operation such that +cpufreq-dt to be used. To accomplish this DIV PLL and div0 implement +clock notifiers which applies safe dividers before FRAC PLL is changed. +The current commit treats only the DIV PLL by adding a notifier that +sets a safe divider on PRE_RATE_CHANGE events. The safe divider is +provided by initialization clock code (sama7g5.c). The div0 is treated +in next commits (to keep the changes as clean as possible). + +[1] https://lore.kernel.org/lkml/20210105104426.4tmgc2l3vyicwedd@vireshk-i7/ + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/20211011112719.3951784-12-claudiu.beznea@microchip.com +Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/clk-sam9x60-pll.c | 102 ++++++++++++++++++++++------- + drivers/clk/at91/pmc.h | 3 +- + drivers/clk/at91/sam9x60.c | 6 +- + drivers/clk/at91/sama7g5.c | 13 +++- + 4 files changed, 95 insertions(+), 29 deletions(-) + +diff --git a/drivers/clk/at91/clk-sam9x60-pll.c b/drivers/clk/at91/clk-sam9x60-pll.c +index a73d7c96ce1d..d757003004cb 100644 +--- a/drivers/clk/at91/clk-sam9x60-pll.c ++++ b/drivers/clk/at91/clk-sam9x60-pll.c +@@ -5,6 +5,7 @@ + */ + + #include <linux/bitfield.h> ++#include <linux/clk.h> + #include <linux/clk-provider.h> + #include <linux/clkdev.h> + #include <linux/clk/at91_pmc.h> +@@ -47,12 +48,15 @@ struct sam9x60_div { + struct sam9x60_pll_core core; + struct at91_clk_pms pms; + u8 div; ++ u8 safe_div; + }; + + #define to_sam9x60_pll_core(hw) container_of(hw, struct sam9x60_pll_core, hw) + #define to_sam9x60_frac(core) container_of(core, struct sam9x60_frac, core) + #define to_sam9x60_div(core) container_of(core, struct sam9x60_div, core) + ++static struct sam9x60_div *notifier_div; ++ + static inline bool sam9x60_pll_ready(struct regmap *regmap, int id) + { + unsigned int status; +@@ -329,6 +333,26 @@ static const struct clk_ops sam9x60_frac_pll_ops_chg = { + .restore_context = sam9x60_frac_pll_restore_context, + }; + ++/* This function should be called with spinlock acquired. */ ++static void sam9x60_div_pll_set_div(struct sam9x60_pll_core *core, u32 div, ++ bool enable) ++{ ++ struct regmap *regmap = core->regmap; ++ u32 ena_msk = enable ? core->layout->endiv_mask : 0; ++ u32 ena_val = enable ? (1 << core->layout->endiv_shift) : 0; ++ ++ regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, ++ core->layout->div_mask | ena_msk, ++ (div << core->layout->div_shift) | ena_val); ++ ++ regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, ++ AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, ++ AT91_PMC_PLL_UPDT_UPDATE | core->id); ++ ++ while (!sam9x60_pll_ready(regmap, core->id)) ++ cpu_relax(); ++} ++ + static int sam9x60_div_pll_set(struct sam9x60_pll_core *core) + { + struct sam9x60_div *div = to_sam9x60_div(core); +@@ -346,17 +370,7 @@ static int sam9x60_div_pll_set(struct sam9x60_pll_core *core) + if (!!(val & core->layout->endiv_mask) && cdiv == div->div) + goto unlock; + +- regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, +- core->layout->div_mask | core->layout->endiv_mask, +- (div->div << core->layout->div_shift) | +- (1 << core->layout->endiv_shift)); +- +- regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, +- AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, +- AT91_PMC_PLL_UPDT_UPDATE | core->id); +- +- while (!sam9x60_pll_ready(regmap, core->id)) +- cpu_relax(); ++ sam9x60_div_pll_set_div(core, div->div, 1); + + unlock: + spin_unlock_irqrestore(core->lock, flags); +@@ -502,16 +516,7 @@ static int sam9x60_div_pll_set_rate_chg(struct clk_hw *hw, unsigned long rate, + if (cdiv == div->div) + goto unlock; + +- regmap_update_bits(regmap, AT91_PMC_PLL_CTRL0, +- core->layout->div_mask, +- (div->div << core->layout->div_shift)); +- +- regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, +- AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MSK, +- AT91_PMC_PLL_UPDT_UPDATE | core->id); +- +- while (!sam9x60_pll_ready(regmap, core->id)) +- cpu_relax(); ++ sam9x60_div_pll_set_div(core, div->div, 0); + + unlock: + spin_unlock_irqrestore(core->lock, irqflags); +@@ -538,6 +543,48 @@ static void sam9x60_div_pll_restore_context(struct clk_hw *hw) + sam9x60_div_pll_set(core); + } + ++static int sam9x60_div_pll_notifier_fn(struct notifier_block *notifier, ++ unsigned long code, void *data) ++{ ++ struct sam9x60_div *div = notifier_div; ++ struct sam9x60_pll_core core = div->core; ++ struct regmap *regmap = core.regmap; ++ unsigned long irqflags; ++ u32 val, cdiv; ++ int ret = NOTIFY_DONE; ++ ++ if (code != PRE_RATE_CHANGE) ++ return ret; ++ ++ /* ++ * We switch to safe divider to avoid overclocking of other domains ++ * feed by us while the frac PLL (our parent) is changed. ++ */ ++ div->div = div->safe_div; ++ ++ spin_lock_irqsave(core.lock, irqflags); ++ regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, AT91_PMC_PLL_UPDT_ID_MSK, ++ core.id); ++ regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val); ++ cdiv = (val & core.layout->div_mask) >> core.layout->div_shift; ++ ++ /* Stop if nothing changed. */ ++ if (cdiv == div->safe_div) ++ goto unlock; ++ ++ sam9x60_div_pll_set_div(&core, div->div, 0); ++ ret = NOTIFY_OK; ++ ++unlock: ++ spin_unlock_irqrestore(core.lock, irqflags); ++ ++ return ret; ++} ++ ++static struct notifier_block sam9x60_div_pll_notifier = { ++ .notifier_call = sam9x60_div_pll_notifier_fn, ++}; ++ + static const struct clk_ops sam9x60_div_pll_ops = { + .prepare = sam9x60_div_pll_prepare, + .unprepare = sam9x60_div_pll_unprepare, +@@ -647,7 +694,8 @@ struct clk_hw * __init + sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock, + const char *name, const char *parent_name, u8 id, + const struct clk_pll_characteristics *characteristics, +- const struct clk_pll_layout *layout, u32 flags) ++ const struct clk_pll_layout *layout, u32 flags, ++ u32 safe_div) + { + struct sam9x60_div *div; + struct clk_hw *hw; +@@ -656,9 +704,13 @@ sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock, + unsigned int val; + int ret; + +- if (id > PLL_MAX_ID || !lock) ++ /* We only support one changeable PLL. */ ++ if (id > PLL_MAX_ID || !lock || (safe_div && notifier_div)) + return ERR_PTR(-EINVAL); + ++ if (safe_div >= PLL_DIV_MAX) ++ safe_div = PLL_DIV_MAX - 1; ++ + div = kzalloc(sizeof(*div), GFP_KERNEL); + if (!div) + return ERR_PTR(-ENOMEM); +@@ -678,6 +730,7 @@ sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock, + div->core.layout = layout; + div->core.regmap = regmap; + div->core.lock = lock; ++ div->safe_div = safe_div; + + spin_lock_irqsave(div->core.lock, irqflags); + +@@ -693,6 +746,9 @@ sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock, + if (ret) { + kfree(div); + hw = ERR_PTR(ret); ++ } else if (div->safe_div) { ++ notifier_div = div; ++ clk_notifier_register(hw->clk, &sam9x60_div_pll_notifier); + } + + return hw; +diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h +index 45df094498ce..207ecccef29f 100644 +--- a/drivers/clk/at91/pmc.h ++++ b/drivers/clk/at91/pmc.h +@@ -214,7 +214,8 @@ struct clk_hw * __init + sam9x60_clk_register_div_pll(struct regmap *regmap, spinlock_t *lock, + const char *name, const char *parent_name, u8 id, + const struct clk_pll_characteristics *characteristics, +- const struct clk_pll_layout *layout, u32 flags); ++ const struct clk_pll_layout *layout, u32 flags, ++ u32 safe_div); + + struct clk_hw * __init + sam9x60_clk_register_frac_pll(struct regmap *regmap, spinlock_t *lock, +diff --git a/drivers/clk/at91/sam9x60.c b/drivers/clk/at91/sam9x60.c +index 5f6fa89571b7..5c264185f261 100644 +--- a/drivers/clk/at91/sam9x60.c ++++ b/drivers/clk/at91/sam9x60.c +@@ -242,7 +242,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np) + * This feeds CPU. It should not + * be disabled. + */ +- CLK_IS_CRITICAL | CLK_SET_RATE_GATE); ++ CLK_IS_CRITICAL | CLK_SET_RATE_GATE, 0); + if (IS_ERR(hw)) + goto err_free; + +@@ -260,7 +260,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np) + &pll_div_layout, + CLK_SET_RATE_GATE | + CLK_SET_PARENT_GATE | +- CLK_SET_RATE_PARENT); ++ CLK_SET_RATE_PARENT, 0); + if (IS_ERR(hw)) + goto err_free; + +@@ -279,7 +279,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np) + hw = at91_clk_register_master_div(regmap, "masterck_div", + "masterck_pres", &sam9x60_master_layout, + &mck_characteristics, &mck_lock, +- CLK_SET_RATE_GATE); ++ CLK_SET_RATE_GATE, 0); + if (IS_ERR(hw)) + goto err_free; + +diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c +index 970135e19a75..ae52c10af040 100644 +--- a/drivers/clk/at91/sama7g5.c ++++ b/drivers/clk/at91/sama7g5.c +@@ -127,6 +127,8 @@ static const struct clk_pll_characteristics pll_characteristics = { + * @t: clock type + * @f: clock flags + * @eid: export index in sama7g5->chws[] array ++ * @safe_div: intermediate divider need to be set on PRE_RATE_CHANGE ++ * notification + */ + static const struct { + const char *n; +@@ -136,6 +138,7 @@ static const struct { + unsigned long f; + u8 t; + u8 eid; ++ u8 safe_div; + } sama7g5_plls[][PLL_ID_MAX] = { + [PLL_ID_CPU] = { + { .n = "cpupll_fracck", +@@ -156,7 +159,12 @@ static const struct { + .t = PLL_TYPE_DIV, + /* This feeds CPU. It should not be disabled. */ + .f = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT, +- .eid = PMC_CPUPLL, }, ++ .eid = PMC_CPUPLL, ++ /* ++ * Safe div=15 should be safe even for switching b/w 1GHz and ++ * 90MHz (frac pll might go up to 1.2GHz). ++ */ ++ .safe_div = 15, }, + }, + + [PLL_ID_SYS] = { +@@ -967,7 +975,8 @@ static void __init sama7g5_pmc_setup(struct device_node *np) + sama7g5_plls[i][j].p, i, + sama7g5_plls[i][j].c, + sama7g5_plls[i][j].l, +- sama7g5_plls[i][j].f); ++ sama7g5_plls[i][j].f, ++ sama7g5_plls[i][j].safe_div); + break; + + default: +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/244-clk-at91-clk-master-add-notifier-for-divider.patch b/target/linux/at91/patches-5.10/244-clk-at91-clk-master-add-notifier-for-divider.patch new file mode 100644 index 0000000000..9298d2f0c7 --- /dev/null +++ b/target/linux/at91/patches-5.10/244-clk-at91-clk-master-add-notifier-for-divider.patch @@ -0,0 +1,548 @@ +From 75d5d1d584ae73ba0c36d1d7255db6153ca4d3f3 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Mon, 11 Oct 2021 14:27:16 +0300 +Subject: [PATCH 244/247] clk: at91: clk-master: add notifier for divider + +SAMA7G5 supports DVFS by changing cpuck. On SAMA7G5 mck0 shares the same +parent with cpuck as seen in the following clock tree: + + +----------> cpuck + | +FRAC PLL ---> DIV PLL -+-> DIV ---> mck0 + +mck0 could go b/w 32KHz and 200MHz on SAMA7G5. To avoid mck0 overclocking +while changing FRAC PLL or DIV PLL the commit implements a notifier for +mck0 which applies a safe divider to register (maximum value of the divider +which is 5) on PRE_RATE_CHANGE events (such that changes on PLL to not +overclock mck0) and sets the maximum allowed rate on POST_RATE_CHANGE +events. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/20211011112719.3951784-13-claudiu.beznea@microchip.com +Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/at91rm9200.c | 2 +- + drivers/clk/at91/at91sam9260.c | 2 +- + drivers/clk/at91/at91sam9g45.c | 2 +- + drivers/clk/at91/at91sam9n12.c | 2 +- + drivers/clk/at91/at91sam9rl.c | 2 +- + drivers/clk/at91/at91sam9x5.c | 2 +- + drivers/clk/at91/clk-master.c | 244 +++++++++++++++++++++++---------- + drivers/clk/at91/dt-compat.c | 2 +- + drivers/clk/at91/pmc.h | 2 +- + drivers/clk/at91/sama5d2.c | 2 +- + drivers/clk/at91/sama5d3.c | 2 +- + drivers/clk/at91/sama5d4.c | 2 +- + drivers/clk/at91/sama7g5.c | 2 +- + 13 files changed, 186 insertions(+), 82 deletions(-) + +diff --git a/drivers/clk/at91/at91rm9200.c b/drivers/clk/at91/at91rm9200.c +index 428a6f4b9ebc..fff4fdda974f 100644 +--- a/drivers/clk/at91/at91rm9200.c ++++ b/drivers/clk/at91/at91rm9200.c +@@ -152,7 +152,7 @@ static void __init at91rm9200_pmc_setup(struct device_node *np) + "masterck_pres", + &at91rm9200_master_layout, + &rm9200_mck_characteristics, +- &rm9200_mck_lock, CLK_SET_RATE_GATE); ++ &rm9200_mck_lock, CLK_SET_RATE_GATE, 0); + if (IS_ERR(hw)) + goto err_free; + +diff --git a/drivers/clk/at91/at91sam9260.c b/drivers/clk/at91/at91sam9260.c +index b29843bea278..79802f864ee5 100644 +--- a/drivers/clk/at91/at91sam9260.c ++++ b/drivers/clk/at91/at91sam9260.c +@@ -429,7 +429,7 @@ static void __init at91sam926x_pmc_setup(struct device_node *np, + &at91rm9200_master_layout, + data->mck_characteristics, + &at91sam9260_mck_lock, +- CLK_SET_RATE_GATE); ++ CLK_SET_RATE_GATE, 0); + if (IS_ERR(hw)) + goto err_free; + +diff --git a/drivers/clk/at91/at91sam9g45.c b/drivers/clk/at91/at91sam9g45.c +index 15da0dfe3ef2..7ed984f8058c 100644 +--- a/drivers/clk/at91/at91sam9g45.c ++++ b/drivers/clk/at91/at91sam9g45.c +@@ -164,7 +164,7 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np) + &at91rm9200_master_layout, + &mck_characteristics, + &at91sam9g45_mck_lock, +- CLK_SET_RATE_GATE); ++ CLK_SET_RATE_GATE, 0); + if (IS_ERR(hw)) + goto err_free; + +diff --git a/drivers/clk/at91/at91sam9n12.c b/drivers/clk/at91/at91sam9n12.c +index 7fe435f4b46b..63cc58944b00 100644 +--- a/drivers/clk/at91/at91sam9n12.c ++++ b/drivers/clk/at91/at91sam9n12.c +@@ -191,7 +191,7 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np) + &at91sam9x5_master_layout, + &mck_characteristics, + &at91sam9n12_mck_lock, +- CLK_SET_RATE_GATE); ++ CLK_SET_RATE_GATE, 0); + if (IS_ERR(hw)) + goto err_free; + +diff --git a/drivers/clk/at91/at91sam9rl.c b/drivers/clk/at91/at91sam9rl.c +index ecbabf5162bd..4d4faf6c61d8 100644 +--- a/drivers/clk/at91/at91sam9rl.c ++++ b/drivers/clk/at91/at91sam9rl.c +@@ -132,7 +132,7 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np) + "masterck_pres", + &at91rm9200_master_layout, + &sam9rl_mck_characteristics, +- &sam9rl_mck_lock, CLK_SET_RATE_GATE); ++ &sam9rl_mck_lock, CLK_SET_RATE_GATE, 0); + if (IS_ERR(hw)) + goto err_free; + +diff --git a/drivers/clk/at91/at91sam9x5.c b/drivers/clk/at91/at91sam9x5.c +index 5cce48c64ea2..bd8007b4f3e0 100644 +--- a/drivers/clk/at91/at91sam9x5.c ++++ b/drivers/clk/at91/at91sam9x5.c +@@ -210,7 +210,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np, + "masterck_pres", + &at91sam9x5_master_layout, + &mck_characteristics, &mck_lock, +- CLK_SET_RATE_GATE); ++ CLK_SET_RATE_GATE, 0); + if (IS_ERR(hw)) + goto err_free; + +diff --git a/drivers/clk/at91/clk-master.c b/drivers/clk/at91/clk-master.c +index e67bcd03a827..b2d0a7f4f7f9 100644 +--- a/drivers/clk/at91/clk-master.c ++++ b/drivers/clk/at91/clk-master.c +@@ -5,6 +5,7 @@ + + #include <linux/clk-provider.h> + #include <linux/clkdev.h> ++#include <linux/clk.h> + #include <linux/clk/at91_pmc.h> + #include <linux/of.h> + #include <linux/mfd/syscon.h> +@@ -36,8 +37,12 @@ struct clk_master { + u8 id; + u8 parent; + u8 div; ++ u32 safe_div; + }; + ++/* MCK div reference to be used by notifier. */ ++static struct clk_master *master_div; ++ + static inline bool clk_master_ready(struct clk_master *master) + { + unsigned int bit = master->id ? AT91_PMC_MCKXRDY : AT91_PMC_MCKRDY; +@@ -153,107 +158,81 @@ static const struct clk_ops master_div_ops = { + .restore_context = clk_master_div_restore_context, + }; + +-static int clk_master_div_set_rate(struct clk_hw *hw, unsigned long rate, +- unsigned long parent_rate) ++/* This function must be called with lock acquired. */ ++static int clk_master_div_set(struct clk_master *master, ++ unsigned long parent_rate, int div) + { +- struct clk_master *master = to_clk_master(hw); + const struct clk_master_characteristics *characteristics = + master->characteristics; +- unsigned long flags; +- unsigned int mckr, tmp; +- int div, i; ++ unsigned long rate = parent_rate; ++ unsigned int max_div = 0, div_index = 0, max_div_index = 0; ++ unsigned int i, mckr, tmp; + int ret; + +- div = DIV_ROUND_CLOSEST(parent_rate, rate); +- if (div > ARRAY_SIZE(characteristics->divisors)) +- return -EINVAL; +- + for (i = 0; i < ARRAY_SIZE(characteristics->divisors); i++) { + if (!characteristics->divisors[i]) + break; + +- if (div == characteristics->divisors[i]) { +- div = i; +- break; ++ if (div == characteristics->divisors[i]) ++ div_index = i; ++ ++ if (max_div < characteristics->divisors[i]) { ++ max_div = characteristics->divisors[i]; ++ max_div_index = i; + } + } + +- if (i == ARRAY_SIZE(characteristics->divisors)) +- return -EINVAL; ++ if (div > max_div) ++ div_index = max_div_index; + +- spin_lock_irqsave(master->lock, flags); + ret = regmap_read(master->regmap, master->layout->offset, &mckr); + if (ret) +- goto unlock; ++ return ret; + + mckr &= master->layout->mask; + tmp = (mckr >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; +- if (tmp == div) +- goto unlock; ++ if (tmp == div_index) ++ return 0; ++ ++ rate /= characteristics->divisors[div_index]; ++ if (rate < characteristics->output.min) ++ pr_warn("master clk div is underclocked"); ++ else if (rate > characteristics->output.max) ++ pr_warn("master clk div is overclocked"); + + mckr &= ~(MASTER_DIV_MASK << MASTER_DIV_SHIFT); +- mckr |= (div << MASTER_DIV_SHIFT); ++ mckr |= (div_index << MASTER_DIV_SHIFT); + ret = regmap_write(master->regmap, master->layout->offset, mckr); + if (ret) +- goto unlock; ++ return ret; + + while (!clk_master_ready(master)) + cpu_relax(); +-unlock: +- spin_unlock_irqrestore(master->lock, flags); ++ ++ master->div = characteristics->divisors[div_index]; + + return 0; + } + +-static int clk_master_div_determine_rate(struct clk_hw *hw, +- struct clk_rate_request *req) ++static unsigned long clk_master_div_recalc_rate_chg(struct clk_hw *hw, ++ unsigned long parent_rate) + { + struct clk_master *master = to_clk_master(hw); +- const struct clk_master_characteristics *characteristics = +- master->characteristics; +- struct clk_hw *parent; +- unsigned long parent_rate, tmp_rate, best_rate = 0; +- int i, best_diff = INT_MIN, tmp_diff; +- +- parent = clk_hw_get_parent(hw); +- if (!parent) +- return -EINVAL; +- +- parent_rate = clk_hw_get_rate(parent); +- if (!parent_rate) +- return -EINVAL; +- +- for (i = 0; i < ARRAY_SIZE(characteristics->divisors); i++) { +- if (!characteristics->divisors[i]) +- break; + +- tmp_rate = DIV_ROUND_CLOSEST_ULL(parent_rate, +- characteristics->divisors[i]); +- tmp_diff = abs(tmp_rate - req->rate); +- +- if (!best_rate || best_diff > tmp_diff) { +- best_diff = tmp_diff; +- best_rate = tmp_rate; +- } +- +- if (!best_diff) +- break; +- } +- +- req->best_parent_rate = best_rate; +- req->best_parent_hw = parent; +- req->rate = best_rate; +- +- return 0; ++ return DIV_ROUND_CLOSEST_ULL(parent_rate, master->div); + } + + static void clk_master_div_restore_context_chg(struct clk_hw *hw) + { + struct clk_master *master = to_clk_master(hw); ++ unsigned long flags; + int ret; + +- ret = clk_master_div_set_rate(hw, master->pms.rate, +- master->pms.parent_rate); ++ spin_lock_irqsave(master->lock, flags); ++ ret = clk_master_div_set(master, master->pms.parent_rate, ++ DIV_ROUND_CLOSEST(master->pms.parent_rate, ++ master->pms.rate)); ++ spin_unlock_irqrestore(master->lock, flags); + if (ret) + pr_warn("Failed to restore MCK DIV clock\n"); + } +@@ -261,13 +240,116 @@ static void clk_master_div_restore_context_chg(struct clk_hw *hw) + static const struct clk_ops master_div_ops_chg = { + .prepare = clk_master_prepare, + .is_prepared = clk_master_is_prepared, +- .recalc_rate = clk_master_div_recalc_rate, +- .determine_rate = clk_master_div_determine_rate, +- .set_rate = clk_master_div_set_rate, ++ .recalc_rate = clk_master_div_recalc_rate_chg, + .save_context = clk_master_div_save_context, + .restore_context = clk_master_div_restore_context_chg, + }; + ++static int clk_master_div_notifier_fn(struct notifier_block *notifier, ++ unsigned long code, void *data) ++{ ++ const struct clk_master_characteristics *characteristics = ++ master_div->characteristics; ++ struct clk_notifier_data *cnd = data; ++ unsigned long flags, new_parent_rate, new_rate; ++ unsigned int mckr, div, new_div = 0; ++ int ret, i; ++ long tmp_diff; ++ long best_diff = -1; ++ ++ spin_lock_irqsave(master_div->lock, flags); ++ switch (code) { ++ case PRE_RATE_CHANGE: ++ /* ++ * We want to avoid any overclocking of MCK DIV domain. To do ++ * this we set a safe divider (the underclocking is not of ++ * interest as we can go as low as 32KHz). The relation ++ * b/w this clock and its parents are as follows: ++ * ++ * FRAC PLL -> DIV PLL -> MCK DIV ++ * ++ * With the proper safe divider we should be good even with FRAC ++ * PLL at its maximum value. ++ */ ++ ret = regmap_read(master_div->regmap, master_div->layout->offset, ++ &mckr); ++ if (ret) { ++ ret = NOTIFY_STOP_MASK; ++ goto unlock; ++ } ++ ++ mckr &= master_div->layout->mask; ++ div = (mckr >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; ++ ++ /* Switch to safe divider. */ ++ clk_master_div_set(master_div, ++ cnd->old_rate * characteristics->divisors[div], ++ master_div->safe_div); ++ break; ++ ++ case POST_RATE_CHANGE: ++ /* ++ * At this point we want to restore MCK DIV domain to its maximum ++ * allowed rate. ++ */ ++ ret = regmap_read(master_div->regmap, master_div->layout->offset, ++ &mckr); ++ if (ret) { ++ ret = NOTIFY_STOP_MASK; ++ goto unlock; ++ } ++ ++ mckr &= master_div->layout->mask; ++ div = (mckr >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; ++ new_parent_rate = cnd->new_rate * characteristics->divisors[div]; ++ ++ for (i = 0; i < ARRAY_SIZE(characteristics->divisors); i++) { ++ if (!characteristics->divisors[i]) ++ break; ++ ++ new_rate = DIV_ROUND_CLOSEST_ULL(new_parent_rate, ++ characteristics->divisors[i]); ++ ++ tmp_diff = characteristics->output.max - new_rate; ++ if (tmp_diff < 0) ++ continue; ++ ++ if (best_diff < 0 || best_diff > tmp_diff) { ++ new_div = characteristics->divisors[i]; ++ best_diff = tmp_diff; ++ } ++ ++ if (!tmp_diff) ++ break; ++ } ++ ++ if (!new_div) { ++ ret = NOTIFY_STOP_MASK; ++ goto unlock; ++ } ++ ++ /* Update the div to preserve MCK DIV clock rate. */ ++ clk_master_div_set(master_div, new_parent_rate, ++ new_div); ++ ++ ret = NOTIFY_OK; ++ break; ++ ++ default: ++ ret = NOTIFY_DONE; ++ break; ++ } ++ ++unlock: ++ spin_unlock_irqrestore(master_div->lock, flags); ++ ++ return ret; ++} ++ ++static struct notifier_block clk_master_div_notifier = { ++ .notifier_call = clk_master_div_notifier_fn, ++}; ++ + static void clk_sama7g5_master_best_diff(struct clk_rate_request *req, + struct clk_hw *parent, + unsigned long parent_rate, +@@ -496,6 +578,8 @@ at91_clk_register_master_internal(struct regmap *regmap, + struct clk_master *master; + struct clk_init_data init; + struct clk_hw *hw; ++ unsigned int mckr; ++ unsigned long irqflags; + int ret; + + if (!name || !num_parents || !parent_names || !lock) +@@ -518,6 +602,16 @@ at91_clk_register_master_internal(struct regmap *regmap, + master->chg_pid = chg_pid; + master->lock = lock; + ++ if (ops == &master_div_ops_chg) { ++ spin_lock_irqsave(master->lock, irqflags); ++ regmap_read(master->regmap, master->layout->offset, &mckr); ++ spin_unlock_irqrestore(master->lock, irqflags); ++ ++ mckr &= layout->mask; ++ mckr = (mckr >> MASTER_DIV_SHIFT) & MASTER_DIV_MASK; ++ master->div = characteristics->divisors[mckr]; ++ } ++ + hw = &master->hw; + ret = clk_hw_register(NULL, &master->hw); + if (ret) { +@@ -554,19 +648,29 @@ at91_clk_register_master_div(struct regmap *regmap, + const char *name, const char *parent_name, + const struct clk_master_layout *layout, + const struct clk_master_characteristics *characteristics, +- spinlock_t *lock, u32 flags) ++ spinlock_t *lock, u32 flags, u32 safe_div) + { + const struct clk_ops *ops; ++ struct clk_hw *hw; + + if (flags & CLK_SET_RATE_GATE) + ops = &master_div_ops; + else + ops = &master_div_ops_chg; + +- return at91_clk_register_master_internal(regmap, name, 1, +- &parent_name, layout, +- characteristics, ops, +- lock, flags, -EINVAL); ++ hw = at91_clk_register_master_internal(regmap, name, 1, ++ &parent_name, layout, ++ characteristics, ops, ++ lock, flags, -EINVAL); ++ ++ if (!IS_ERR(hw) && safe_div) { ++ master_div = to_clk_master(hw); ++ master_div->safe_div = safe_div; ++ clk_notifier_register(hw->clk, ++ &clk_master_div_notifier); ++ } ++ ++ return hw; + } + + static unsigned long +diff --git a/drivers/clk/at91/dt-compat.c b/drivers/clk/at91/dt-compat.c +index a97b99c2dc12..ca2dbb65b9df 100644 +--- a/drivers/clk/at91/dt-compat.c ++++ b/drivers/clk/at91/dt-compat.c +@@ -399,7 +399,7 @@ of_at91_clk_master_setup(struct device_node *np, + + hw = at91_clk_register_master_div(regmap, name, "masterck_pres", + layout, characteristics, +- &mck_lock, CLK_SET_RATE_GATE); ++ &mck_lock, CLK_SET_RATE_GATE, 0); + if (IS_ERR(hw)) + goto out_free_characteristics; + +diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h +index 207ecccef29f..3a1bf6194c28 100644 +--- a/drivers/clk/at91/pmc.h ++++ b/drivers/clk/at91/pmc.h +@@ -182,7 +182,7 @@ at91_clk_register_master_div(struct regmap *regmap, const char *name, + const char *parent_names, + const struct clk_master_layout *layout, + const struct clk_master_characteristics *characteristics, +- spinlock_t *lock, u32 flags); ++ spinlock_t *lock, u32 flags, u32 safe_div); + + struct clk_hw * __init + at91_clk_sama7g5_register_master(struct regmap *regmap, +diff --git a/drivers/clk/at91/sama5d2.c b/drivers/clk/at91/sama5d2.c +index 3d1f78176c3e..d027294a0089 100644 +--- a/drivers/clk/at91/sama5d2.c ++++ b/drivers/clk/at91/sama5d2.c +@@ -249,7 +249,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np) + "masterck_pres", + &at91sam9x5_master_layout, + &mck_characteristics, &mck_lock, +- CLK_SET_RATE_GATE); ++ CLK_SET_RATE_GATE, 0); + if (IS_ERR(hw)) + goto err_free; + +diff --git a/drivers/clk/at91/sama5d3.c b/drivers/clk/at91/sama5d3.c +index d376257807d2..339d0f382ff0 100644 +--- a/drivers/clk/at91/sama5d3.c ++++ b/drivers/clk/at91/sama5d3.c +@@ -184,7 +184,7 @@ static void __init sama5d3_pmc_setup(struct device_node *np) + "masterck_pres", + &at91sam9x5_master_layout, + &mck_characteristics, &mck_lock, +- CLK_SET_RATE_GATE); ++ CLK_SET_RATE_GATE, 0); + if (IS_ERR(hw)) + goto err_free; + +diff --git a/drivers/clk/at91/sama5d4.c b/drivers/clk/at91/sama5d4.c +index 5cbaac68da44..4af75b1e39e9 100644 +--- a/drivers/clk/at91/sama5d4.c ++++ b/drivers/clk/at91/sama5d4.c +@@ -199,7 +199,7 @@ static void __init sama5d4_pmc_setup(struct device_node *np) + "masterck_pres", + &at91sam9x5_master_layout, + &mck_characteristics, &mck_lock, +- CLK_SET_RATE_GATE); ++ CLK_SET_RATE_GATE, 0); + if (IS_ERR(hw)) + goto err_free; + +diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c +index ae52c10af040..c66bde6f7b47 100644 +--- a/drivers/clk/at91/sama7g5.c ++++ b/drivers/clk/at91/sama7g5.c +@@ -1003,7 +1003,7 @@ static void __init sama7g5_pmc_setup(struct device_node *np) + + hw = at91_clk_register_master_div(regmap, "mck0", "cpuck", + &mck0_layout, &mck0_characteristics, +- &pmc_mck0_lock, 0); ++ &pmc_mck0_lock, CLK_GET_RATE_NOCACHE, 5); + if (IS_ERR(hw)) + goto err_free; + +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/245-clk-at91-sama7g5-remove-prescaler-part-of-master-clo.patch b/target/linux/at91/patches-5.10/245-clk-at91-sama7g5-remove-prescaler-part-of-master-clo.patch new file mode 100644 index 0000000000..fc0947db8c --- /dev/null +++ b/target/linux/at91/patches-5.10/245-clk-at91-sama7g5-remove-prescaler-part-of-master-clo.patch @@ -0,0 +1,50 @@ +From 91a49481af7332853c4c921d46aded8210572210 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Mon, 11 Oct 2021 14:27:17 +0300 +Subject: [PATCH 245/247] clk: at91: sama7g5: remove prescaler part of master + clock + +On SAMA7G5 the prescaler part of master clock has been implemented as a +changeable one. Everytime the prescaler is changed the PMC_SR.MCKRDY bit +must be polled. Value 1 for PMC_SR.MCKRDY means the prescaler update is +done. Driver polls for this bit until it becomes 1. On SAMA7G5 it has +been discovered that in some conditions the PMC_SR.MCKRDY is not rising +but the rate it provides it's stable. The workaround is to add a timeout +when polling for PMC_SR.MCKRDY. At the moment, for SAMA7G5, the prescaler +will be removed from Linux clock tree as all the frequencies for CPU could +be obtained from PLL and also there will be less overhead when changing +frequency via DVFS. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/20211011112719.3951784-14-claudiu.beznea@microchip.com +Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/sama7g5.c | 11 +---------- + 1 file changed, 1 insertion(+), 10 deletions(-) + +diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c +index c66bde6f7b47..fd9d17eabf54 100644 +--- a/drivers/clk/at91/sama7g5.c ++++ b/drivers/clk/at91/sama7g5.c +@@ -992,16 +992,7 @@ static void __init sama7g5_pmc_setup(struct device_node *np) + } + + parent_names[0] = "cpupll_divpmcck"; +- hw = at91_clk_register_master_pres(regmap, "cpuck", 1, parent_names, +- &mck0_layout, &mck0_characteristics, +- &pmc_mck0_lock, +- CLK_SET_RATE_PARENT, 0); +- if (IS_ERR(hw)) +- goto err_free; +- +- sama7g5_pmc->chws[PMC_CPU] = hw; +- +- hw = at91_clk_register_master_div(regmap, "mck0", "cpuck", ++ hw = at91_clk_register_master_div(regmap, "mck0", "cpupll_divpmcck", + &mck0_layout, &mck0_characteristics, + &pmc_mck0_lock, CLK_GET_RATE_NOCACHE, 5); + if (IS_ERR(hw)) +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/246-clk-at91-sama7g5-set-low-limit-for-mck0-at-32KHz.patch b/target/linux/at91/patches-5.10/246-clk-at91-sama7g5-set-low-limit-for-mck0-at-32KHz.patch new file mode 100644 index 0000000000..a30173157f --- /dev/null +++ b/target/linux/at91/patches-5.10/246-clk-at91-sama7g5-set-low-limit-for-mck0-at-32KHz.patch @@ -0,0 +1,31 @@ +From 9fd5a49f6da9de5da83f4a53eccefad647ab15ed Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Mon, 11 Oct 2021 14:27:18 +0300 +Subject: [PATCH 246/247] clk: at91: sama7g5: set low limit for mck0 at 32KHz + +MCK0 could go as low as 32KHz. Set this limit. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/20211011112719.3951784-15-claudiu.beznea@microchip.com +Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com> +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/at91/sama7g5.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/at91/sama7g5.c b/drivers/clk/at91/sama7g5.c +index fd9d17eabf54..369dfafabbca 100644 +--- a/drivers/clk/at91/sama7g5.c ++++ b/drivers/clk/at91/sama7g5.c +@@ -850,7 +850,7 @@ static const struct { + + /* MCK0 characteristics. */ + static const struct clk_master_characteristics mck0_characteristics = { +- .output = { .min = 50000000, .max = 200000000 }, ++ .output = { .min = 32768, .max = 200000000 }, + .divisors = { 1, 2, 4, 3, 5 }, + .have_div3_pres = 1, + }; +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/247-clk-use-clk_core_get_rate_recalc-in-clk_rate_get.patch b/target/linux/at91/patches-5.10/247-clk-use-clk_core_get_rate_recalc-in-clk_rate_get.patch new file mode 100644 index 0000000000..103c597856 --- /dev/null +++ b/target/linux/at91/patches-5.10/247-clk-use-clk_core_get_rate_recalc-in-clk_rate_get.patch @@ -0,0 +1,37 @@ +From fe07791494a78d5a4be1363385e6ba7940740644 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Mon, 11 Oct 2021 14:27:19 +0300 +Subject: [PATCH 247/247] clk: use clk_core_get_rate_recalc() in clk_rate_get() + +In case clock flags contains CLK_GET_RATE_NOCACHE the clk_rate_get() +will return the cached rate. Thus, use clk_core_get_rate_recalc() which +takes proper action when clock flags contains CLK_GET_RATE_NOCACHE. + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +Link: https://lore.kernel.org/r/20211011112719.3951784-16-claudiu.beznea@microchip.com +Acked-by: Nicolas Ferre <nicolas.ferre@microchip.com> +[sboyd@kernel.org: Grab prepare lock around operation] +Signed-off-by: Stephen Boyd <sboyd@kernel.org> +--- + drivers/clk/clk.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c +index b8a0e3d23698..6e64332fd26d 100644 +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -3082,7 +3082,10 @@ static int clk_rate_get(void *data, u64 *val) + { + struct clk_core *core = data; + +- *val = core->rate; ++ clk_prepare_lock(); ++ *val = clk_core_get_rate_recalc(core); ++ clk_prepare_unlock(); ++ + return 0; + } + +-- +2.32.0 + diff --git a/target/linux/at91/patches-5.10/99-scripts-fix-compilation-error.patch b/target/linux/at91/patches-5.10/99-scripts-fix-compilation-error.patch new file mode 100644 index 0000000000..cd47fe3952 --- /dev/null +++ b/target/linux/at91/patches-5.10/99-scripts-fix-compilation-error.patch @@ -0,0 +1,26 @@ +From 6d18eaaaff92f928eab6fad2708b6d28785b4872 Mon Sep 17 00:00:00 2001 +From: Claudiu Beznea <claudiu.beznea@microchip.com> +Date: Wed, 13 Oct 2021 08:32:07 +0300 +Subject: [PATCH] scripts: fix compilation error + +Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> +--- + scripts/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/scripts/Makefile b/scripts/Makefile +index 9adb6d247818..035c1fe113ad 100644 +--- a/scripts/Makefile ++++ b/scripts/Makefile +@@ -21,7 +21,7 @@ HOSTCFLAGS_asn1_compiler.o = -I$(srctree)/include + HOSTCFLAGS_sign-file.o = $(CRYPTO_CFLAGS) + HOSTLDLIBS_sign-file = $(CRYPTO_LIBS) + HOSTCFLAGS_extract-cert.o = $(CRYPTO_CFLAGS) +-HOSTLDLIBS_extract-cert = $(CRYPTO_LIBS) ++HOSTLDLIBS_extract-cert = $(CRYPTO_LIBS) -lpthread + + ifdef CONFIG_UNWINDER_ORC + ifeq ($(ARCH),x86_64) +-- +2.25.1 + diff --git a/target/linux/at91/sam9x/config-default b/target/linux/at91/sam9x/config-default index e3d4c29e99..9f97e7542e 100644 --- a/target/linux/at91/sam9x/config-default +++ b/target/linux/at91/sam9x/config-default @@ -21,6 +21,7 @@ CONFIG_ARM_L1_CACHE_SHIFT=5 CONFIG_ARM_PATCH_PHYS_VIRT=y CONFIG_ARM_THUMB=y CONFIG_ARM_UNWIND=y +# CONFIG_ASN1 is not set # CONFIG_AT91RM9200_WATCHDOG is not set CONFIG_AT91SAM9X_WATCHDOG=y # CONFIG_AT91_ADC is not set @@ -76,10 +77,8 @@ CONFIG_CRC_CCITT=y CONFIG_CRC_ITU_T=y CONFIG_CRYPTO_CRC32C=y CONFIG_CRYPTO_DEFLATE=y -CONFIG_CRYPTO_GF128MUL=y CONFIG_CRYPTO_HASH_INFO=y CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_NULL2=y CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_ZSTD=y CONFIG_DEBUG_INFO=y diff --git a/target/linux/at91/sama5/config-default b/target/linux/at91/sama5/config-default index e294fd9e3b..0d02dd1922 100644 --- a/target/linux/at91/sama5/config-default +++ b/target/linux/at91/sama5/config-default @@ -25,6 +25,7 @@ CONFIG_ARM_PATCH_PHYS_VIRT=y CONFIG_ARM_THUMB=y CONFIG_ARM_UNWIND=y CONFIG_ARM_VIRT_EXT=y +# CONFIG_ASN1 is not set CONFIG_AT91SAM9X_WATCHDOG=y CONFIG_AT91_ADC=y CONFIG_AT91_SAMA5D2_ADC=y @@ -102,13 +103,11 @@ CONFIG_CRYPTO_DEFLATE=y CONFIG_CRYPTO_DRBG=y CONFIG_CRYPTO_DRBG_HMAC=y CONFIG_CRYPTO_DRBG_MENU=y -CONFIG_CRYPTO_GF128MUL=y CONFIG_CRYPTO_HASH_INFO=y CONFIG_CRYPTO_HMAC=y CONFIG_CRYPTO_JITTERENTROPY=y CONFIG_CRYPTO_LIB_SHA256=y CONFIG_CRYPTO_LZO=y -CONFIG_CRYPTO_NULL2=y CONFIG_CRYPTO_RNG=y CONFIG_CRYPTO_RNG2=y CONFIG_CRYPTO_RNG_DEFAULT=y @@ -401,6 +400,7 @@ CONFIG_SND_SOC=y CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y CONFIG_SND_SOC_I2C_AND_SPI=y CONFIG_SND_SOC_MIKROE_PROTO=y +# CONFIG_SND_SOC_PCM5102A is not set CONFIG_SND_SOC_WM8731=y CONFIG_SND_SOC_WM8904=y CONFIG_SND_SPI=y @@ -411,6 +411,7 @@ CONFIG_SOC_SAMA5=y CONFIG_SOC_SAMA5D2=y CONFIG_SOC_SAMA5D3=y CONFIG_SOC_SAMA5D4=y +# CONFIG_SOC_SAMA7G5 is not set CONFIG_SOC_SAM_V7=y CONFIG_SOUND=y CONFIG_SOUND_OSS_CORE=y @@ -473,8 +474,6 @@ CONFIG_VFAT_FS=y CONFIG_VFP=y CONFIG_VFPv3=y CONFIG_VIDEOMODE_HELPERS=y -# CONFIG_VIDEO_ATMEL_ISC is not set -# CONFIG_VIDEO_ATMEL_ISI is not set # CONFIG_VIDEO_CPIA2 is not set CONFIG_VIDEO_DEV=y CONFIG_VIDEO_V4L2=y diff --git a/target/linux/at91/sama7/config-default b/target/linux/at91/sama7/config-default new file mode 100644 index 0000000000..8c453659dc --- /dev/null +++ b/target/linux/at91/sama7/config-default @@ -0,0 +1,476 @@ +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_ALLOW_DEV_COREDUMP is not set +CONFIG_ARCH_32BIT_OFF_T=y +CONFIG_ARCH_AT91=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_ARCH_KEEP_MEMBLOCK=y +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +CONFIG_ARCH_MULTIPLATFORM=y +CONFIG_ARCH_MULTI_V6_V7=y +CONFIG_ARCH_MULTI_V7=y +CONFIG_ARCH_NR_GPIO=0 +CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y +CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y +CONFIG_ARCH_SELECT_MEMORY_MODEL=y +CONFIG_ARCH_SPARSEMEM_ENABLE=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM=y +CONFIG_ARM_GIC=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_L1_CACHE_SHIFT_6=y +# CONFIG_ARM_PATCH_IDIV is not set +CONFIG_ARM_PATCH_PHYS_VIRT=y +CONFIG_ARM_THUMB=y +CONFIG_ARM_UNWIND=y +CONFIG_ARM_VIRT_EXT=y +CONFIG_ASN1=y +CONFIG_ASSOCIATIVE_ARRAY=y +CONFIG_ASYMMETRIC_KEY_TYPE=y +CONFIG_ASYMMETRIC_PUBLIC_KEY_SUBTYPE=y +# CONFIG_AT91SAM9X_WATCHDOG is not set +# CONFIG_AT91_ADC is not set +CONFIG_AT91_SAMA5D2_ADC=y +CONFIG_AT91_SOC_ID=y +# CONFIG_AT91_SOC_SFR is not set +CONFIG_ATMEL_CLOCKSOURCE_TCB=y +# CONFIG_ATMEL_EBI is not set +CONFIG_ATMEL_SDRAMC=y +CONFIG_ATMEL_TCB_CLKSRC=y +# CONFIG_ATMEL_TCLIB is not set +# CONFIG_AT_HDMAC is not set +CONFIG_AT_XDMAC=y +CONFIG_AUTO_ZRELADDR=y +CONFIG_BINFMT_FLAT_ARGVP_ENVP_ON_STACK=y +# CONFIG_BLK_CGROUP is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=1 +CONFIG_BLK_DEV_RAM_SIZE=8192 +CONFIG_BLK_DEV_SD=y +CONFIG_BLK_SCSI_REQUEST=y +CONFIG_BRIDGE=m +CONFIG_BT=y +CONFIG_BT_DEBUGFS=y +CONFIG_BT_HCIUART=y +# CONFIG_BT_HCIUART_INTEL is not set +CONFIG_BT_HCIVHCI=y +# CONFIG_CACHE_L2X0 is not set +CONFIG_CAN=y +CONFIG_CFG80211=m +CONFIG_CFG80211_CRDA_SUPPORT=y +CONFIG_CFG80211_DEBUGFS=y +# CONFIG_CFG80211_DEFAULT_PS is not set +# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set +CONFIG_CFG80211_REQUIRE_SIGNED_REGDB=y +CONFIG_CFG80211_USE_KERNEL_REGDB_KEYS=y +CONFIG_CFG80211_WEXT=y +CONFIG_CGROUPS=y +# CONFIG_CGROUP_BPF is not set +# CONFIG_CGROUP_CPUACCT is not set +CONFIG_CGROUP_DEBUG=y +# CONFIG_CGROUP_DEVICE is not set +# CONFIG_CGROUP_FREEZER is not set +# CONFIG_CGROUP_NET_CLASSID is not set +# CONFIG_CGROUP_NET_PRIO is not set +# CONFIG_CGROUP_PIDS is not set +# CONFIG_CGROUP_RDMA is not set +# CONFIG_CGROUP_SCHED is not set +CONFIG_CLKDEV_LOOKUP=y +CONFIG_CLKSRC_MMIO=y +CONFIG_CLONE_BACKWARDS=y +CONFIG_CLZ_TAB=y +CONFIG_CMA=y +CONFIG_CMA_ALIGNMENT=9 +CONFIG_CMA_AREAS=7 +# CONFIG_CMA_DEBUG is not set +# CONFIG_CMA_DEBUGFS is not set +CONFIG_CMA_SIZE_MBYTES=256 +# CONFIG_CMA_SIZE_SEL_MAX is not set +CONFIG_CMA_SIZE_SEL_MBYTES=y +# CONFIG_CMA_SIZE_SEL_MIN is not set +# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set +CONFIG_CMDLINE="console=ttyS0,115200 earlyprintk nocache ignore_loglevel" +CONFIG_COMMON_CLK=y +CONFIG_COMMON_CLK_AT91=y +# CONFIG_COMPACTION is not set +CONFIG_COMPAT_32BIT_TIME=y +CONFIG_CONFIGFS_FS=y +CONFIG_CONSOLE_TRANSLATIONS=y +CONFIG_CONTIG_ALLOC=y +CONFIG_CPUFREQ_DT=y +CONFIG_CPUFREQ_DT_PLATDEV=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y +CONFIG_CPU_FREQ=y +CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE=y +# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set +CONFIG_CPU_FREQ_GOV_ATTR_SET=y +CONFIG_CPU_FREQ_GOV_COMMON=y +CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=y +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y +CONFIG_CPU_FREQ_GOV_POWERSAVE=y +CONFIG_CPU_FREQ_GOV_USERSPACE=y +CONFIG_CPU_FREQ_STAT=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_SPECTRE=y +# CONFIG_CPU_SW_DOMAIN_PAN is not set +CONFIG_CPU_THUMB_CAPABLE=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_V7=y +CONFIG_CRC16=y +CONFIG_CRC_CCITT=y +CONFIG_CRC_ITU_T=y +CONFIG_CRYPTO_CMAC=y +CONFIG_CRYPTO_CRC32C=y +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_DRBG=y +CONFIG_CRYPTO_DRBG_HMAC=y +CONFIG_CRYPTO_DRBG_MENU=y +CONFIG_CRYPTO_ECB=y +CONFIG_CRYPTO_ECC=y +CONFIG_CRYPTO_ECDH=y +CONFIG_CRYPTO_HASH_INFO=y +CONFIG_CRYPTO_HMAC=y +CONFIG_CRYPTO_JITTERENTROPY=y +CONFIG_CRYPTO_LIB_SHA256=y +CONFIG_CRYPTO_LZO=y +CONFIG_CRYPTO_RNG=y +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=y +CONFIG_CRYPTO_RSA=y +CONFIG_CRYPTO_SHA256=y +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_DEBUG_AT91_SAMA7G5_FLEXCOM3=y +CONFIG_DEBUG_AT91_UART=y +CONFIG_DEBUG_INFO=y +CONFIG_DEBUG_LL=y +CONFIG_DEBUG_LL_INCLUDE="debug/at91.S" +CONFIG_DEBUG_UART_PHYS=0xe1824200 +CONFIG_DEBUG_UART_VIRT=0xe0824200 +# CONFIG_DEBUG_UNCOMPRESS is not set +CONFIG_DEBUG_USER=y +CONFIG_DEVTMPFS=y +CONFIG_DEVTMPFS_MOUNT=y +CONFIG_DMADEVICES=y +CONFIG_DMATEST=y +CONFIG_DMA_CMA=y +CONFIG_DMA_ENGINE=y +CONFIG_DMA_ENGINE_RAID=y +CONFIG_DMA_OF=y +CONFIG_DMA_OPS=y +CONFIG_DMA_REMAP=y +CONFIG_DTC=y +CONFIG_DUMMY_CONSOLE=y +CONFIG_EARLY_PRINTK=y +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +CONFIG_EEPROM_AT24=y +# CONFIG_EFI_PARTITION is not set +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_POSIX_ACL is not set +# CONFIG_EXT2_FS_SECURITY is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_EXT4_FS=y +CONFIG_FANOTIFY=y +CONFIG_FAT_FS=y +CONFIG_FIXED_PHY=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_FORCE_MAX_ZONEORDER=15 +CONFIG_FS_IOMAP=y +CONFIG_FS_MBCACHE=y +CONFIG_FW_LOADER_PAGED_BUF=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_GENERIC_BUG=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_GENERIC_EARLY_IOREMAP=y +CONFIG_GENERIC_GETTIMEOFDAY=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_GENERIC_IRQ_MULTI_HANDLER=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_PCI_IOMAP=y +CONFIG_GENERIC_PINCONF=y +CONFIG_GENERIC_PINCTRL_GROUPS=y +CONFIG_GENERIC_PINMUX_FUNCTIONS=y +CONFIG_GENERIC_SCHED_CLOCK=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_STRNCPY_FROM_USER=y +CONFIG_GENERIC_STRNLEN_USER=y +CONFIG_GENERIC_TIME_VSYSCALL=y +CONFIG_GENERIC_VDSO_32=y +CONFIG_GLOB=y +CONFIG_GPIOLIB=y +CONFIG_GPIOLIB_IRQCHIP=y +CONFIG_GRACE_PERIOD=y +CONFIG_GRO_CELLS=y +CONFIG_HANDLE_DOMAIN_IRQ=y +CONFIG_HARDEN_BRANCH_PREDICTOR=y +CONFIG_HARDIRQS_SW_RESEND=y +CONFIG_HAS_DMA=y +CONFIG_HAS_IOMEM=y +CONFIG_HAS_IOPORT_MAP=y +CONFIG_HAVE_SMP=y +CONFIG_HW_CONSOLE=y +CONFIG_HW_RANDOM=y +CONFIG_HZ_FIXED=0 +CONFIG_I2C=y +CONFIG_I2C_AT91=y +# CONFIG_I2C_AT91_SLAVE_EXPERIMENTAL is not set +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_CHARDEV=y +CONFIG_IIO=y +CONFIG_IIO_BUFFER=y +CONFIG_IIO_CONFIGFS=y +# CONFIG_IIO_HRTIMER_TRIGGER is not set +CONFIG_IIO_KFIFO_BUF=y +CONFIG_IIO_SW_TRIGGER=y +# CONFIG_IIO_TIGHTLOOP_TRIGGER is not set +CONFIG_IIO_TRIGGER=y +CONFIG_IIO_TRIGGERED_BUFFER=y +CONFIG_INITRAMFS_SOURCE="" +CONFIG_INPUT=y +CONFIG_IP_PNP=y +# CONFIG_IP_PNP_BOOTP is not set +CONFIG_IP_PNP_DHCP=y +# CONFIG_IP_PNP_RARP is not set +CONFIG_IRQCHIP=y +CONFIG_IRQ_DOMAIN=y +CONFIG_IRQ_DOMAIN_HIERARCHY=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_IRQ_WORK=y +CONFIG_ISDN_CAPI=y +CONFIG_JBD2=y +CONFIG_KEYS=y +CONFIG_LEDS_GPIO=y +CONFIG_LIBFDT=y +CONFIG_LLC=m +CONFIG_LOCKD=y +CONFIG_LOCK_DEBUGGING_SUPPORT=y +CONFIG_LOG_BUF_SHIFT=16 +CONFIG_LSM="N" +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_MAC80211=m +# CONFIG_MAC80211_DEBUGFS is not set +# CONFIG_MAC80211_DEBUG_MENU is not set +CONFIG_MAC80211_HAS_RC=y +# CONFIG_MAC80211_HWSIM is not set +CONFIG_MAC80211_LEDS=y +# CONFIG_MAC80211_MESH is not set +CONFIG_MAC80211_RC_DEFAULT="minstrel_ht" +CONFIG_MAC80211_RC_DEFAULT_MINSTREL=y +CONFIG_MAC80211_RC_MINSTREL=y +CONFIG_MACB=y +CONFIG_MDIO_BUS=y +CONFIG_MDIO_DEVICE=y +CONFIG_MDIO_DEVRES=y +CONFIG_MEDIA_CAMERA_SUPPORT=y +CONFIG_MEDIA_CONTROLLER=y +CONFIG_MEDIA_PLATFORM_SUPPORT=y +CONFIG_MEDIA_SUPPORT=y +CONFIG_MEDIA_SUPPORT_FILTER=y +# CONFIG_MEMCG is not set +CONFIG_MEMFD_CREATE=y +CONFIG_MEMORY=y +CONFIG_MEMORY_ISOLATION=y +CONFIG_MESSAGE_LOGLEVEL_DEFAULT=7 +CONFIG_MFD_AT91_USART=y +CONFIG_MFD_ATMEL_FLEXCOM=y +CONFIG_MFD_CORE=y +CONFIG_MFD_SYSCON=y +CONFIG_MICREL_PHY=y +CONFIG_MICROCHIP_PIT64B=y +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +CONFIG_MIGRATION=y +CONFIG_MMC=y +# CONFIG_MMC_ATMELMCI is not set +CONFIG_MMC_BLOCK=y +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_OF_AT91=y +CONFIG_MMC_SDHCI_PLTFM=y +CONFIG_MODULES_USE_ELF_REL=y +CONFIG_MODULE_FORCE_LOAD=y +CONFIG_MODULE_FORCE_UNLOAD=y +CONFIG_MPILIB=y +CONFIG_MTD_CMDLINE_PARTS=y +CONFIG_NAMESPACES=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_NEED_PER_CPU_KM=y +CONFIG_NEON=y +# CONFIG_NET_CLS_CGROUP is not set +CONFIG_NET_DEVLINK=y +CONFIG_NET_DSA=m +CONFIG_NET_NS=y +CONFIG_NET_SWITCHDEV=y +CONFIG_NFS_FS=y +# CONFIG_NL80211_TESTMODE is not set +CONFIG_NLS=y +CONFIG_NLS_CODEPAGE_437=y +CONFIG_NLS_CODEPAGE_850=y +CONFIG_NLS_ISO8859_1=y +CONFIG_NLS_UTF8=y +CONFIG_NO_HZ_COMMON=y +CONFIG_NO_HZ_IDLE=y +CONFIG_NVMEM=y +CONFIG_NVMEM_SYSFS=y +CONFIG_OF=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_FLATTREE=y +CONFIG_OF_GPIO=y +CONFIG_OF_IRQ=y +CONFIG_OF_KOBJ=y +CONFIG_OF_MDIO=y +CONFIG_OF_NET=y +CONFIG_OID_REGISTRY=y +CONFIG_OLD_SIGACTION=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_PCCARD=y +CONFIG_PERF_USE_VMALLOC=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_PHYLIB=y +CONFIG_PHYLINK=y +CONFIG_PINCTRL=y +CONFIG_PINCTRL_AT91=y +CONFIG_PINCTRL_AT91PIO4=y +CONFIG_PKCS7_MESSAGE_PARSER=y +# CONFIG_PKCS7_TEST_KEY is not set +# CONFIG_PKCS8_PRIVATE_KEY_PARSER is not set +CONFIG_PM_OPP=y +CONFIG_POWER_RESET=y +# CONFIG_POWER_RESET_AT91_POWEROFF is not set +CONFIG_POWER_RESET_AT91_RESET=y +CONFIG_POWER_RESET_AT91_SAMA5D2_SHDWC=y +# CONFIG_PREVENT_FIRMWARE_BUILD is not set +CONFIG_PRINTK_TIME=y +CONFIG_PWM=y +CONFIG_PWM_ATMEL=y +CONFIG_PWM_SYSFS=y +CONFIG_RATIONAL=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +CONFIG_REGMAP_MMIO=y +CONFIG_REGMAP_SPI=y +CONFIG_REGULATOR=y +CONFIG_REGULATOR_FIXED_VOLTAGE=y +CONFIG_REGULATOR_MCP16502=y +CONFIG_ROOT_NFS=y +CONFIG_RTC_CLASS=y +CONFIG_RTC_DRV_AT91RM9200=y +CONFIG_RTC_DRV_AT91SAM9=y +CONFIG_RTC_I2C_AND_SPI=y +CONFIG_RTC_MC146818_LIB=y +# CONFIG_RTL8723BS is not set +# CONFIG_RUNTIME_TESTING_MENU is not set +CONFIG_SAMA5D4_WATCHDOG=y +CONFIG_SCSI=y +# CONFIG_SECONDARY_TRUSTED_KEYRING is not set +# CONFIG_SERIAL_8250 is not set +CONFIG_SERIAL_ATMEL=y +CONFIG_SERIAL_ATMEL_CONSOLE=y +CONFIG_SERIAL_ATMEL_PDC=y +# CONFIG_SERIAL_ATMEL_TTYAT is not set +CONFIG_SERIAL_MCTRL_GPIO=y +CONFIG_SGL_ALLOC=y +CONFIG_SG_POOL=y +CONFIG_SND=y +CONFIG_SND_ATMEL_SOC=y +# CONFIG_SND_ATMEL_SOC_CLASSD is not set +# CONFIG_SND_ATMEL_SOC_I2S is not set +# CONFIG_SND_ATMEL_SOC_PDMIC is not set +# CONFIG_SND_COMPRESS_OFFLOAD is not set +CONFIG_SND_DMAENGINE_PCM=y +CONFIG_SND_JACK=y +CONFIG_SND_JACK_INPUT_DEV=y +CONFIG_SND_MCHP_SOC_I2S_MCC=y +CONFIG_SND_MCHP_SOC_SPDIFRX=y +CONFIG_SND_MCHP_SOC_SPDIFTX=y +CONFIG_SND_PCM=y +CONFIG_SND_SIMPLE_CARD=y +CONFIG_SND_SIMPLE_CARD_UTILS=y +CONFIG_SND_SOC=y +CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y +CONFIG_SND_SOC_I2C_AND_SPI=y +CONFIG_SND_SOC_MIKROE_PROTO=m +CONFIG_SND_SOC_PCM5102A=y +CONFIG_SND_SOC_SPDIF=y +CONFIG_SND_SOC_WM8731=m +CONFIG_SOC_BUS=y +# CONFIG_SOC_SAMA5D2 is not set +# CONFIG_SOC_SAMA5D3 is not set +# CONFIG_SOC_SAMA5D4 is not set +CONFIG_SOC_SAMA7=y +CONFIG_SOC_SAMA7G5=y +CONFIG_SOC_SAM_V7=y +CONFIG_SOUND=y +CONFIG_SOUND_OSS_CORE=y +CONFIG_SPARSE_IRQ=y +CONFIG_SPI=y +# CONFIG_SPI_AT91_USART is not set +CONFIG_SPI_ATMEL=y +# CONFIG_SPI_ATMEL_QUADSPI is not set +CONFIG_SPI_MASTER=y +CONFIG_SPI_MEM=y +CONFIG_SPI_SPIDEV=m +CONFIG_SRCU=y +CONFIG_STACKTRACE=y +# CONFIG_STANDALONE is not set +CONFIG_STP=m +CONFIG_SUNRPC=y +# CONFIG_SWAP is not set +CONFIG_SWPHY=y +# CONFIG_SWP_EMULATE is not set +CONFIG_SYSFS_DEPRECATED=y +CONFIG_SYSFS_DEPRECATED_V2=y +CONFIG_SYSTEM_DATA_VERIFICATION=y +# CONFIG_SYSTEM_EXTRA_CERTIFICATE is not set +CONFIG_SYSTEM_TRUSTED_KEYRING=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_TICK_CPU_ACCOUNTING=y +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_TINY_SRCU=y +CONFIG_UACCESS_WITH_MEMCPY=y +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +CONFIG_UNWINDER_ARM=y +# CONFIG_USER_NS is not set +CONFIG_USE_OF=y +CONFIG_V4L2_FWNODE=m +CONFIG_V4L_PLATFORM_DRIVERS=y +CONFIG_VFAT_FS=y +CONFIG_VFP=y +CONFIG_VFPv3=y +# CONFIG_VIDEO_ATMEL_XISC is not set +CONFIG_VIDEO_DEV=y +CONFIG_VIDEO_IMX219=m +CONFIG_VIDEO_IMX274=m +CONFIG_VIDEO_OV5647=m +CONFIG_VIDEO_V4L2=y +CONFIG_VIDEO_V4L2_I2C=y +CONFIG_VIDEO_V4L2_SUBDEV_API=y +# CONFIG_VIRT_WIFI is not set +CONFIG_VLAN_8021Q=m +CONFIG_VT=y +CONFIG_VT_CONSOLE=y +# CONFIG_VT_HW_CONSOLE_BINDING is not set +CONFIG_WATCHDOG_CORE=y +# CONFIG_WFX is not set +CONFIG_X509_CERTIFICATE_PARSER=y +CONFIG_ZBOOT_ROM_BSS=0x0 +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZLIB_DEFLATE=y +CONFIG_ZLIB_INFLATE=y diff --git a/target/linux/at91/sama7/target.mk b/target/linux/at91/sama7/target.mk new file mode 100644 index 0000000000..386c4b9d54 --- /dev/null +++ b/target/linux/at91/sama7/target.mk @@ -0,0 +1,9 @@ +BOARDNAME:=SAMA7 boards (Cortex-A7) +CPU_TYPE:=cortex-a7 +CPU_SUBTYPE:=vfpv4 +FEATURES+=fpu + +define Target/Description + Build generic firmware for Microchip SAMA7G5 MPUs using the + ARMv7 instruction set. +endef |