diff options
Diffstat (limited to 'target/linux/mediatek/patches')
76 files changed, 50121 insertions, 0 deletions
diff --git a/target/linux/mediatek/patches/0001-clk-make-strings-in-parent-name-arrays-const.patch b/target/linux/mediatek/patches/0001-clk-make-strings-in-parent-name-arrays-const.patch new file mode 100644 index 0000000000..3dca509648 --- /dev/null +++ b/target/linux/mediatek/patches/0001-clk-make-strings-in-parent-name-arrays-const.patch @@ -0,0 +1,100 @@ +From a38e86708141d75c643ffd58865c50a925134e4f Mon Sep 17 00:00:00 2001 +From: Sascha Hauer <s.hauer@pengutronix.de> +Date: Thu, 23 Apr 2015 10:35:38 +0200 +Subject: [PATCH 01/76] clk: make strings in parent name arrays const +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The clk functions and structs declare the parent_name arrays as +'const char **parent_names' which means the parent name strings +are const, but the array itself is not. Use +'const char * const * parent_names' instead which also makes +the array const. This allows us to put the parent_name arrays into +the __initconst section. + +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +Reviewed-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> +Tested-by: Krzysztof Kozlowski <k.kozlowski@samsung.com> +Acked-by: Uwe Kleine-König <u.kleine-koenig@pengutronix.de> +--- + drivers/clk/clk-composite.c | 2 +- + drivers/clk/clk-mux.c | 4 ++-- + include/linux/clk-provider.h | 8 ++++---- + 3 files changed, 7 insertions(+), 7 deletions(-) + +diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c +index 956b7e5..077f4c7 100644 +--- a/drivers/clk/clk-composite.c ++++ b/drivers/clk/clk-composite.c +@@ -188,7 +188,7 @@ static void clk_composite_disable(struct clk_hw *hw) + } + + struct clk *clk_register_composite(struct device *dev, const char *name, +- const char **parent_names, int num_parents, ++ const char * const *parent_names, int num_parents, + struct clk_hw *mux_hw, const struct clk_ops *mux_ops, + struct clk_hw *rate_hw, const struct clk_ops *rate_ops, + struct clk_hw *gate_hw, const struct clk_ops *gate_ops, +diff --git a/drivers/clk/clk-mux.c b/drivers/clk/clk-mux.c +index 69a094c..1fa2a8d 100644 +--- a/drivers/clk/clk-mux.c ++++ b/drivers/clk/clk-mux.c +@@ -114,7 +114,7 @@ const struct clk_ops clk_mux_ro_ops = { + EXPORT_SYMBOL_GPL(clk_mux_ro_ops); + + struct clk *clk_register_mux_table(struct device *dev, const char *name, +- const char **parent_names, u8 num_parents, unsigned long flags, ++ const char * const *parent_names, u8 num_parents, unsigned long flags, + void __iomem *reg, u8 shift, u32 mask, + u8 clk_mux_flags, u32 *table, spinlock_t *lock) + { +@@ -166,7 +166,7 @@ struct clk *clk_register_mux_table(struct device *dev, const char *name, + EXPORT_SYMBOL_GPL(clk_register_mux_table); + + struct clk *clk_register_mux(struct device *dev, const char *name, +- const char **parent_names, u8 num_parents, unsigned long flags, ++ const char * const *parent_names, u8 num_parents, unsigned long flags, + void __iomem *reg, u8 shift, u8 width, + u8 clk_mux_flags, spinlock_t *lock) + { +diff --git a/include/linux/clk-provider.h b/include/linux/clk-provider.h +index df69531..ec609e5 100644 +--- a/include/linux/clk-provider.h ++++ b/include/linux/clk-provider.h +@@ -209,7 +209,7 @@ struct clk_ops { + struct clk_init_data { + const char *name; + const struct clk_ops *ops; +- const char **parent_names; ++ const char * const *parent_names; + u8 num_parents; + unsigned long flags; + }; +@@ -426,12 +426,12 @@ extern const struct clk_ops clk_mux_ops; + extern const struct clk_ops clk_mux_ro_ops; + + struct clk *clk_register_mux(struct device *dev, const char *name, +- const char **parent_names, u8 num_parents, unsigned long flags, ++ const char * const *parent_names, u8 num_parents, unsigned long flags, + void __iomem *reg, u8 shift, u8 width, + u8 clk_mux_flags, spinlock_t *lock); + + struct clk *clk_register_mux_table(struct device *dev, const char *name, +- const char **parent_names, u8 num_parents, unsigned long flags, ++ const char * const *parent_names, u8 num_parents, unsigned long flags, + void __iomem *reg, u8 shift, u32 mask, + u8 clk_mux_flags, u32 *table, spinlock_t *lock); + +@@ -518,7 +518,7 @@ struct clk_composite { + }; + + struct clk *clk_register_composite(struct device *dev, const char *name, +- const char **parent_names, int num_parents, ++ const char * const *parent_names, int num_parents, + struct clk_hw *mux_hw, const struct clk_ops *mux_ops, + struct clk_hw *rate_hw, const struct clk_ops *rate_ops, + struct clk_hw *gate_hw, const struct clk_ops *gate_ops, +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0002-clk-mediatek-Add-initial-common-clock-support-for-Me.patch b/target/linux/mediatek/patches/0002-clk-mediatek-Add-initial-common-clock-support-for-Me.patch new file mode 100644 index 0000000000..d5f52d15e8 --- /dev/null +++ b/target/linux/mediatek/patches/0002-clk-mediatek-Add-initial-common-clock-support-for-Me.patch @@ -0,0 +1,977 @@ +From f851b4ea6cae9fd5875036b6d3968375882ce56b Mon Sep 17 00:00:00 2001 +From: James Liao <jamesjj.liao@mediatek.com> +Date: Thu, 23 Apr 2015 10:35:39 +0200 +Subject: [PATCH 02/76] clk: mediatek: Add initial common clock support for + Mediatek SoCs. + +This patch adds common clock support for Mediatek SoCs, including plls, +muxes and clock gates. + +Signed-off-by: James Liao <jamesjj.liao@mediatek.com> +Signed-off-by: Henry Chen <henryc.chen@mediatek.com> +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +--- + drivers/clk/Makefile | 1 + + drivers/clk/mediatek/Makefile | 1 + + drivers/clk/mediatek/clk-gate.c | 137 ++++++++++++++++ + drivers/clk/mediatek/clk-gate.h | 49 ++++++ + drivers/clk/mediatek/clk-mtk.c | 220 ++++++++++++++++++++++++++ + drivers/clk/mediatek/clk-mtk.h | 159 +++++++++++++++++++ + drivers/clk/mediatek/clk-pll.c | 332 +++++++++++++++++++++++++++++++++++++++ + 7 files changed, 899 insertions(+) + create mode 100644 drivers/clk/mediatek/Makefile + create mode 100644 drivers/clk/mediatek/clk-gate.c + create mode 100644 drivers/clk/mediatek/clk-gate.h + create mode 100644 drivers/clk/mediatek/clk-mtk.c + create mode 100644 drivers/clk/mediatek/clk-mtk.h + create mode 100644 drivers/clk/mediatek/clk-pll.c + +diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile +index 3d00c25..d965b3f 100644 +--- a/drivers/clk/Makefile ++++ b/drivers/clk/Makefile +@@ -51,6 +51,7 @@ obj-$(CONFIG_ARCH_HI3xxx) += hisilicon/ + obj-$(CONFIG_ARCH_HIP04) += hisilicon/ + obj-$(CONFIG_ARCH_HIX5HD2) += hisilicon/ + obj-$(CONFIG_COMMON_CLK_KEYSTONE) += keystone/ ++obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/ + ifeq ($(CONFIG_COMMON_CLK), y) + obj-$(CONFIG_ARCH_MMP) += mmp/ + endif +diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile +new file mode 100644 +index 0000000..c384e97 +--- /dev/null ++++ b/drivers/clk/mediatek/Makefile +@@ -0,0 +1 @@ ++obj-y += clk-mtk.o clk-pll.o clk-gate.o +diff --git a/drivers/clk/mediatek/clk-gate.c b/drivers/clk/mediatek/clk-gate.c +new file mode 100644 +index 0000000..9d77ee3 +--- /dev/null ++++ b/drivers/clk/mediatek/clk-gate.c +@@ -0,0 +1,137 @@ ++/* ++ * Copyright (c) 2014 MediaTek Inc. ++ * Author: James Liao <jamesjj.liao@mediatek.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/of.h> ++#include <linux/of_address.h> ++ ++#include <linux/io.h> ++#include <linux/slab.h> ++#include <linux/delay.h> ++#include <linux/clkdev.h> ++ ++#include "clk-mtk.h" ++#include "clk-gate.h" ++ ++static int mtk_cg_bit_is_cleared(struct clk_hw *hw) ++{ ++ struct mtk_clk_gate *cg = to_clk_gate(hw); ++ u32 val; ++ ++ regmap_read(cg->regmap, cg->sta_ofs, &val); ++ ++ val &= BIT(cg->bit); ++ ++ return val == 0; ++} ++ ++static int mtk_cg_bit_is_set(struct clk_hw *hw) ++{ ++ struct mtk_clk_gate *cg = to_clk_gate(hw); ++ u32 val; ++ ++ regmap_read(cg->regmap, cg->sta_ofs, &val); ++ ++ val &= BIT(cg->bit); ++ ++ return val != 0; ++} ++ ++static void mtk_cg_set_bit(struct clk_hw *hw) ++{ ++ struct mtk_clk_gate *cg = to_clk_gate(hw); ++ ++ regmap_write(cg->regmap, cg->set_ofs, BIT(cg->bit)); ++} ++ ++static void mtk_cg_clr_bit(struct clk_hw *hw) ++{ ++ struct mtk_clk_gate *cg = to_clk_gate(hw); ++ ++ regmap_write(cg->regmap, cg->clr_ofs, BIT(cg->bit)); ++} ++ ++static int mtk_cg_enable(struct clk_hw *hw) ++{ ++ mtk_cg_clr_bit(hw); ++ ++ return 0; ++} ++ ++static void mtk_cg_disable(struct clk_hw *hw) ++{ ++ mtk_cg_set_bit(hw); ++} ++ ++static int mtk_cg_enable_inv(struct clk_hw *hw) ++{ ++ mtk_cg_set_bit(hw); ++ ++ return 0; ++} ++ ++static void mtk_cg_disable_inv(struct clk_hw *hw) ++{ ++ mtk_cg_clr_bit(hw); ++} ++ ++const struct clk_ops mtk_clk_gate_ops_setclr = { ++ .is_enabled = mtk_cg_bit_is_cleared, ++ .enable = mtk_cg_enable, ++ .disable = mtk_cg_disable, ++}; ++ ++const struct clk_ops mtk_clk_gate_ops_setclr_inv = { ++ .is_enabled = mtk_cg_bit_is_set, ++ .enable = mtk_cg_enable_inv, ++ .disable = mtk_cg_disable_inv, ++}; ++ ++struct clk *mtk_clk_register_gate( ++ const char *name, ++ const char *parent_name, ++ struct regmap *regmap, ++ int set_ofs, ++ int clr_ofs, ++ int sta_ofs, ++ u8 bit, ++ const struct clk_ops *ops) ++{ ++ struct mtk_clk_gate *cg; ++ struct clk *clk; ++ struct clk_init_data init; ++ ++ cg = kzalloc(sizeof(*cg), GFP_KERNEL); ++ if (!cg) ++ return ERR_PTR(-ENOMEM); ++ ++ init.name = name; ++ init.flags = CLK_SET_RATE_PARENT; ++ init.parent_names = parent_name ? &parent_name : NULL; ++ init.num_parents = parent_name ? 1 : 0; ++ init.ops = ops; ++ ++ cg->regmap = regmap; ++ cg->set_ofs = set_ofs; ++ cg->clr_ofs = clr_ofs; ++ cg->sta_ofs = sta_ofs; ++ cg->bit = bit; ++ ++ cg->hw.init = &init; ++ ++ clk = clk_register(NULL, &cg->hw); ++ if (IS_ERR(clk)) ++ kfree(cg); ++ ++ return clk; ++} +diff --git a/drivers/clk/mediatek/clk-gate.h b/drivers/clk/mediatek/clk-gate.h +new file mode 100644 +index 0000000..6b6780b +--- /dev/null ++++ b/drivers/clk/mediatek/clk-gate.h +@@ -0,0 +1,49 @@ ++/* ++ * Copyright (c) 2014 MediaTek Inc. ++ * Author: James Liao <jamesjj.liao@mediatek.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __DRV_CLK_GATE_H ++#define __DRV_CLK_GATE_H ++ ++#include <linux/regmap.h> ++#include <linux/clk.h> ++#include <linux/clk-provider.h> ++ ++struct mtk_clk_gate { ++ struct clk_hw hw; ++ struct regmap *regmap; ++ int set_ofs; ++ int clr_ofs; ++ int sta_ofs; ++ u8 bit; ++}; ++ ++static inline struct mtk_clk_gate *to_clk_gate(struct clk_hw *hw) ++{ ++ return container_of(hw, struct mtk_clk_gate, hw); ++} ++ ++extern const struct clk_ops mtk_clk_gate_ops_setclr; ++extern const struct clk_ops mtk_clk_gate_ops_setclr_inv; ++ ++struct clk *mtk_clk_register_gate( ++ const char *name, ++ const char *parent_name, ++ struct regmap *regmap, ++ int set_ofs, ++ int clr_ofs, ++ int sta_ofs, ++ u8 bit, ++ const struct clk_ops *ops); ++ ++#endif /* __DRV_CLK_GATE_H */ +diff --git a/drivers/clk/mediatek/clk-mtk.c b/drivers/clk/mediatek/clk-mtk.c +new file mode 100644 +index 0000000..18444ae +--- /dev/null ++++ b/drivers/clk/mediatek/clk-mtk.c +@@ -0,0 +1,220 @@ ++/* ++ * Copyright (c) 2014 MediaTek Inc. ++ * Author: James Liao <jamesjj.liao@mediatek.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/of.h> ++#include <linux/of_address.h> ++#include <linux/err.h> ++#include <linux/io.h> ++#include <linux/slab.h> ++#include <linux/delay.h> ++#include <linux/clkdev.h> ++#include <linux/mfd/syscon.h> ++ ++#include "clk-mtk.h" ++#include "clk-gate.h" ++ ++struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num) ++{ ++ int i; ++ struct clk_onecell_data *clk_data; ++ ++ clk_data = kzalloc(sizeof(*clk_data), GFP_KERNEL); ++ if (!clk_data) ++ return NULL; ++ ++ clk_data->clks = kcalloc(clk_num, sizeof(*clk_data->clks), GFP_KERNEL); ++ if (!clk_data->clks) ++ goto err_out; ++ ++ clk_data->clk_num = clk_num; ++ ++ for (i = 0; i < clk_num; i++) ++ clk_data->clks[i] = ERR_PTR(-ENOENT); ++ ++ return clk_data; ++err_out: ++ kfree(clk_data); ++ ++ return NULL; ++} ++ ++void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, int num, ++ struct clk_onecell_data *clk_data) ++{ ++ int i; ++ struct clk *clk; ++ ++ for (i = 0; i < num; i++) { ++ const struct mtk_fixed_factor *ff = &clks[i]; ++ ++ clk = clk_register_fixed_factor(NULL, ff->name, ff->parent_name, ++ CLK_SET_RATE_PARENT, ff->mult, ff->div); ++ ++ if (IS_ERR(clk)) { ++ pr_err("Failed to register clk %s: %ld\n", ++ ff->name, PTR_ERR(clk)); ++ continue; ++ } ++ ++ if (clk_data) ++ clk_data->clks[ff->id] = clk; ++ } ++} ++ ++int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks, ++ int num, struct clk_onecell_data *clk_data) ++{ ++ int i; ++ struct clk *clk; ++ struct regmap *regmap; ++ ++ if (!clk_data) ++ return -ENOMEM; ++ ++ regmap = syscon_node_to_regmap(node); ++ if (IS_ERR(regmap)) { ++ pr_err("Cannot find regmap for %s: %ld\n", node->full_name, ++ PTR_ERR(regmap)); ++ return PTR_ERR(regmap); ++ } ++ ++ for (i = 0; i < num; i++) { ++ const struct mtk_gate *gate = &clks[i]; ++ ++ clk = mtk_clk_register_gate(gate->name, gate->parent_name, ++ regmap, ++ gate->regs->set_ofs, ++ gate->regs->clr_ofs, ++ gate->regs->sta_ofs, ++ gate->shift, gate->ops); ++ ++ if (IS_ERR(clk)) { ++ pr_err("Failed to register clk %s: %ld\n", ++ gate->name, PTR_ERR(clk)); ++ continue; ++ } ++ ++ clk_data->clks[gate->id] = clk; ++ } ++ ++ return 0; ++} ++ ++struct clk *mtk_clk_register_composite(const struct mtk_composite *mc, ++ void __iomem *base, spinlock_t *lock) ++{ ++ struct clk *clk; ++ struct clk_mux *mux = NULL; ++ struct clk_gate *gate = NULL; ++ struct clk_divider *div = NULL; ++ struct clk_hw *mux_hw = NULL, *gate_hw = NULL, *div_hw = NULL; ++ const struct clk_ops *mux_ops = NULL, *gate_ops = NULL, *div_ops = NULL; ++ const char * const *parent_names; ++ const char *parent; ++ int num_parents; ++ int ret; ++ ++ if (mc->mux_shift >= 0) { ++ mux = kzalloc(sizeof(*mux), GFP_KERNEL); ++ if (!mux) ++ return ERR_PTR(-ENOMEM); ++ ++ mux->reg = base + mc->mux_reg; ++ mux->mask = BIT(mc->mux_width) - 1; ++ mux->shift = mc->mux_shift; ++ mux->lock = lock; ++ ++ mux_hw = &mux->hw; ++ mux_ops = &clk_mux_ops; ++ ++ parent_names = mc->parent_names; ++ num_parents = mc->num_parents; ++ } else { ++ parent = mc->parent; ++ parent_names = &parent; ++ num_parents = 1; ++ } ++ ++ if (mc->gate_shift >= 0) { ++ gate = kzalloc(sizeof(*gate), GFP_KERNEL); ++ if (!gate) { ++ ret = -ENOMEM; ++ goto err_out; ++ } ++ ++ gate->reg = base + mc->gate_reg; ++ gate->bit_idx = mc->gate_shift; ++ gate->flags = CLK_GATE_SET_TO_DISABLE; ++ gate->lock = lock; ++ ++ gate_hw = &gate->hw; ++ gate_ops = &clk_gate_ops; ++ } ++ ++ if (mc->divider_shift >= 0) { ++ div = kzalloc(sizeof(*div), GFP_KERNEL); ++ if (!div) { ++ ret = -ENOMEM; ++ goto err_out; ++ } ++ ++ div->reg = base + mc->divider_reg; ++ div->shift = mc->divider_shift; ++ div->width = mc->divider_width; ++ div->lock = lock; ++ ++ div_hw = &div->hw; ++ div_ops = &clk_divider_ops; ++ } ++ ++ clk = clk_register_composite(NULL, mc->name, parent_names, num_parents, ++ mux_hw, mux_ops, ++ div_hw, div_ops, ++ gate_hw, gate_ops, ++ mc->flags); ++ ++ if (IS_ERR(clk)) { ++ kfree(gate); ++ kfree(mux); ++ } ++ ++ return clk; ++err_out: ++ kfree(mux); ++ ++ return ERR_PTR(ret); ++} ++ ++void mtk_clk_register_composites(const struct mtk_composite *mcs, ++ int num, void __iomem *base, spinlock_t *lock, ++ struct clk_onecell_data *clk_data) ++{ ++ struct clk *clk; ++ int i; ++ ++ for (i = 0; i < num; i++) { ++ const struct mtk_composite *mc = &mcs[i]; ++ ++ clk = mtk_clk_register_composite(mc, base, lock); ++ ++ if (IS_ERR(clk)) { ++ pr_err("Failed to register clk %s: %ld\n", ++ mc->name, PTR_ERR(clk)); ++ continue; ++ } ++ ++ if (clk_data) ++ clk_data->clks[mc->id] = clk; ++ } ++} +diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h +new file mode 100644 +index 0000000..694fc39 +--- /dev/null ++++ b/drivers/clk/mediatek/clk-mtk.h +@@ -0,0 +1,159 @@ ++/* ++ * Copyright (c) 2014 MediaTek Inc. ++ * Author: James Liao <jamesjj.liao@mediatek.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __DRV_CLK_MTK_H ++#define __DRV_CLK_MTK_H ++ ++#include <linux/regmap.h> ++#include <linux/bitops.h> ++#include <linux/clk.h> ++#include <linux/clk-provider.h> ++ ++#define MAX_MUX_GATE_BIT 31 ++#define INVALID_MUX_GATE_BIT (MAX_MUX_GATE_BIT + 1) ++ ++#define MHZ (1000 * 1000) ++ ++struct mtk_fixed_factor { ++ int id; ++ const char *name; ++ const char *parent_name; ++ int mult; ++ int div; ++}; ++ ++#define FACTOR(_id, _name, _parent, _mult, _div) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .mult = _mult, \ ++ .div = _div, \ ++ } ++ ++extern void mtk_clk_register_factors(const struct mtk_fixed_factor *clks, ++ int num, struct clk_onecell_data *clk_data); ++ ++struct mtk_composite { ++ int id; ++ const char *name; ++ const char * const * parent_names; ++ const char *parent; ++ unsigned flags; ++ ++ uint32_t mux_reg; ++ uint32_t divider_reg; ++ uint32_t gate_reg; ++ ++ signed char mux_shift; ++ signed char mux_width; ++ signed char gate_shift; ++ ++ signed char divider_shift; ++ signed char divider_width; ++ ++ signed char num_parents; ++}; ++ ++#define MUX_GATE(_id, _name, _parents, _reg, _shift, _width, _gate) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .mux_reg = _reg, \ ++ .mux_shift = _shift, \ ++ .mux_width = _width, \ ++ .gate_reg = _reg, \ ++ .gate_shift = _gate, \ ++ .divider_shift = -1, \ ++ .parent_names = _parents, \ ++ .num_parents = ARRAY_SIZE(_parents), \ ++ .flags = CLK_SET_RATE_PARENT, \ ++ } ++ ++#define MUX(_id, _name, _parents, _reg, _shift, _width) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .mux_reg = _reg, \ ++ .mux_shift = _shift, \ ++ .mux_width = _width, \ ++ .gate_shift = -1, \ ++ .divider_shift = -1, \ ++ .parent_names = _parents, \ ++ .num_parents = ARRAY_SIZE(_parents), \ ++ .flags = CLK_SET_RATE_PARENT, \ ++ } ++ ++#define DIV_GATE(_id, _name, _parent, _gate_reg, _gate_shift, _div_reg, _div_width, _div_shift) { \ ++ .id = _id, \ ++ .parent = _parent, \ ++ .name = _name, \ ++ .divider_reg = _div_reg, \ ++ .divider_shift = _div_shift, \ ++ .divider_width = _div_width, \ ++ .gate_reg = _gate_reg, \ ++ .gate_shift = _gate_shift, \ ++ .mux_shift = -1, \ ++ .flags = 0, \ ++ } ++ ++struct clk *mtk_clk_register_composite(const struct mtk_composite *mc, ++ void __iomem *base, spinlock_t *lock); ++ ++void mtk_clk_register_composites(const struct mtk_composite *mcs, ++ int num, void __iomem *base, spinlock_t *lock, ++ struct clk_onecell_data *clk_data); ++ ++struct mtk_gate_regs { ++ u32 sta_ofs; ++ u32 clr_ofs; ++ u32 set_ofs; ++}; ++ ++struct mtk_gate { ++ int id; ++ const char *name; ++ const char *parent_name; ++ const struct mtk_gate_regs *regs; ++ int shift; ++ const struct clk_ops *ops; ++}; ++ ++int mtk_clk_register_gates(struct device_node *node, const struct mtk_gate *clks, ++ int num, struct clk_onecell_data *clk_data); ++ ++struct clk_onecell_data *mtk_alloc_clk_data(unsigned int clk_num); ++ ++#define HAVE_RST_BAR BIT(0) ++ ++struct mtk_pll_data { ++ int id; ++ const char *name; ++ uint32_t reg; ++ uint32_t pwr_reg; ++ uint32_t en_mask; ++ uint32_t pd_reg; ++ uint32_t tuner_reg; ++ int pd_shift; ++ unsigned int flags; ++ const struct clk_ops *ops; ++ u32 rst_bar_mask; ++ unsigned long fmax; ++ int pcwbits; ++ uint32_t pcw_reg; ++ int pcw_shift; ++}; ++ ++void __init mtk_clk_register_plls(struct device_node *node, ++ const struct mtk_pll_data *plls, int num_plls, ++ struct clk_onecell_data *clk_data); ++ ++#endif /* __DRV_CLK_MTK_H */ +diff --git a/drivers/clk/mediatek/clk-pll.c b/drivers/clk/mediatek/clk-pll.c +new file mode 100644 +index 0000000..66154ca +--- /dev/null ++++ b/drivers/clk/mediatek/clk-pll.c +@@ -0,0 +1,332 @@ ++/* ++ * Copyright (c) 2014 MediaTek Inc. ++ * Author: James Liao <jamesjj.liao@mediatek.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/of.h> ++#include <linux/of_address.h> ++#include <linux/io.h> ++#include <linux/slab.h> ++#include <linux/clkdev.h> ++#include <linux/delay.h> ++ ++#include "clk-mtk.h" ++ ++#define REG_CON0 0 ++#define REG_CON1 4 ++ ++#define CON0_BASE_EN BIT(0) ++#define CON0_PWR_ON BIT(0) ++#define CON0_ISO_EN BIT(1) ++#define CON0_PCW_CHG BIT(31) ++ ++#define AUDPLL_TUNER_EN BIT(31) ++ ++#define POSTDIV_MASK 0x7 ++#define INTEGER_BITS 7 ++ ++/* ++ * MediaTek PLLs are configured through their pcw value. The pcw value describes ++ * a divider in the PLL feedback loop which consists of 7 bits for the integer ++ * part and the remaining bits (if present) for the fractional part. Also they ++ * have a 3 bit power-of-two post divider. ++ */ ++ ++struct mtk_clk_pll { ++ struct clk_hw hw; ++ void __iomem *base_addr; ++ void __iomem *pd_addr; ++ void __iomem *pwr_addr; ++ void __iomem *tuner_addr; ++ void __iomem *pcw_addr; ++ const struct mtk_pll_data *data; ++}; ++ ++static inline struct mtk_clk_pll *to_mtk_clk_pll(struct clk_hw *hw) ++{ ++ return container_of(hw, struct mtk_clk_pll, hw); ++} ++ ++static int mtk_pll_is_prepared(struct clk_hw *hw) ++{ ++ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw); ++ ++ return (readl(pll->base_addr + REG_CON0) & CON0_BASE_EN) != 0; ++} ++ ++static unsigned long __mtk_pll_recalc_rate(struct mtk_clk_pll *pll, u32 fin, ++ u32 pcw, int postdiv) ++{ ++ int pcwbits = pll->data->pcwbits; ++ int pcwfbits; ++ u64 vco; ++ u8 c = 0; ++ ++ /* The fractional part of the PLL divider. */ ++ pcwfbits = pcwbits > INTEGER_BITS ? pcwbits - INTEGER_BITS : 0; ++ ++ vco = (u64)fin * pcw; ++ ++ if (pcwfbits && (vco & GENMASK(pcwfbits - 1, 0))) ++ c = 1; ++ ++ vco >>= pcwfbits; ++ ++ if (c) ++ vco++; ++ ++ return ((unsigned long)vco + postdiv - 1) / postdiv; ++} ++ ++static void mtk_pll_set_rate_regs(struct mtk_clk_pll *pll, u32 pcw, ++ int postdiv) ++{ ++ u32 con1, pd, val; ++ int pll_en; ++ ++ /* set postdiv */ ++ pd = readl(pll->pd_addr); ++ pd &= ~(POSTDIV_MASK << pll->data->pd_shift); ++ pd |= (ffs(postdiv) - 1) << pll->data->pd_shift; ++ writel(pd, pll->pd_addr); ++ ++ pll_en = readl(pll->base_addr + REG_CON0) & CON0_BASE_EN; ++ ++ /* set pcw */ ++ val = readl(pll->pcw_addr); ++ ++ val &= ~GENMASK(pll->data->pcw_shift + pll->data->pcwbits - 1, ++ pll->data->pcw_shift); ++ val |= pcw << pll->data->pcw_shift; ++ writel(val, pll->pcw_addr); ++ ++ con1 = readl(pll->base_addr + REG_CON1); ++ ++ if (pll_en) ++ con1 |= CON0_PCW_CHG; ++ ++ writel(con1, pll->base_addr + REG_CON1); ++ if (pll->tuner_addr) ++ writel(con1 + 1, pll->tuner_addr); ++ ++ if (pll_en) ++ udelay(20); ++} ++ ++/* ++ * mtk_pll_calc_values - calculate good values for a given input frequency. ++ * @pll: The pll ++ * @pcw: The pcw value (output) ++ * @postdiv: The post divider (output) ++ * @freq: The desired target frequency ++ * @fin: The input frequency ++ * ++ */ ++static void mtk_pll_calc_values(struct mtk_clk_pll *pll, u32 *pcw, u32 *postdiv, ++ u32 freq, u32 fin) ++{ ++ unsigned long fmin = 1000 * MHZ; ++ u64 _pcw; ++ u32 val; ++ ++ if (freq > pll->data->fmax) ++ freq = pll->data->fmax; ++ ++ for (val = 0; val < 4; val++) { ++ *postdiv = 1 << val; ++ if (freq * *postdiv >= fmin) ++ break; ++ } ++ ++ /* _pcw = freq * postdiv / fin * 2^pcwfbits */ ++ _pcw = ((u64)freq << val) << (pll->data->pcwbits - INTEGER_BITS); ++ do_div(_pcw, fin); ++ ++ *pcw = (u32)_pcw; ++} ++ ++static int mtk_pll_set_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long parent_rate) ++{ ++ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw); ++ u32 pcw = 0; ++ u32 postdiv; ++ ++ mtk_pll_calc_values(pll, &pcw, &postdiv, rate, parent_rate); ++ mtk_pll_set_rate_regs(pll, pcw, postdiv); ++ ++ return 0; ++} ++ ++static unsigned long mtk_pll_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw); ++ u32 postdiv; ++ u32 pcw; ++ ++ postdiv = (readl(pll->pd_addr) >> pll->data->pd_shift) & POSTDIV_MASK; ++ postdiv = 1 << postdiv; ++ ++ pcw = readl(pll->pcw_addr) >> pll->data->pcw_shift; ++ pcw &= GENMASK(pll->data->pcwbits - 1, 0); ++ ++ return __mtk_pll_recalc_rate(pll, parent_rate, pcw, postdiv); ++} ++ ++static long mtk_pll_round_rate(struct clk_hw *hw, unsigned long rate, ++ unsigned long *prate) ++{ ++ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw); ++ u32 pcw = 0; ++ int postdiv; ++ ++ mtk_pll_calc_values(pll, &pcw, &postdiv, rate, *prate); ++ ++ return __mtk_pll_recalc_rate(pll, *prate, pcw, postdiv); ++} ++ ++static int mtk_pll_prepare(struct clk_hw *hw) ++{ ++ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw); ++ u32 r; ++ ++ r = readl(pll->pwr_addr) | CON0_PWR_ON; ++ writel(r, pll->pwr_addr); ++ udelay(1); ++ ++ r = readl(pll->pwr_addr) & ~CON0_ISO_EN; ++ writel(r, pll->pwr_addr); ++ udelay(1); ++ ++ r = readl(pll->base_addr + REG_CON0); ++ r |= pll->data->en_mask; ++ writel(r, pll->base_addr + REG_CON0); ++ ++ if (pll->tuner_addr) { ++ r = readl(pll->tuner_addr) | AUDPLL_TUNER_EN; ++ writel(r, pll->tuner_addr); ++ } ++ ++ udelay(20); ++ ++ if (pll->data->flags & HAVE_RST_BAR) { ++ r = readl(pll->base_addr + REG_CON0); ++ r |= pll->data->rst_bar_mask; ++ writel(r, pll->base_addr + REG_CON0); ++ } ++ ++ return 0; ++} ++ ++static void mtk_pll_unprepare(struct clk_hw *hw) ++{ ++ struct mtk_clk_pll *pll = to_mtk_clk_pll(hw); ++ u32 r; ++ ++ if (pll->data->flags & HAVE_RST_BAR) { ++ r = readl(pll->base_addr + REG_CON0); ++ r &= ~pll->data->rst_bar_mask; ++ writel(r, pll->base_addr + REG_CON0); ++ } ++ ++ if (pll->tuner_addr) { ++ r = readl(pll->tuner_addr) & ~AUDPLL_TUNER_EN; ++ writel(r, pll->tuner_addr); ++ } ++ ++ r = readl(pll->base_addr + REG_CON0); ++ r &= ~CON0_BASE_EN; ++ writel(r, pll->base_addr + REG_CON0); ++ ++ r = readl(pll->pwr_addr) | CON0_ISO_EN; ++ writel(r, pll->pwr_addr); ++ ++ r = readl(pll->pwr_addr) & ~CON0_PWR_ON; ++ writel(r, pll->pwr_addr); ++} ++ ++static const struct clk_ops mtk_pll_ops = { ++ .is_prepared = mtk_pll_is_prepared, ++ .prepare = mtk_pll_prepare, ++ .unprepare = mtk_pll_unprepare, ++ .recalc_rate = mtk_pll_recalc_rate, ++ .round_rate = mtk_pll_round_rate, ++ .set_rate = mtk_pll_set_rate, ++}; ++ ++static struct clk *mtk_clk_register_pll(const struct mtk_pll_data *data, ++ void __iomem *base) ++{ ++ struct mtk_clk_pll *pll; ++ struct clk_init_data init; ++ struct clk *clk; ++ const char *parent_name = "clk26m"; ++ ++ pll = kzalloc(sizeof(*pll), GFP_KERNEL); ++ if (!pll) ++ return ERR_PTR(-ENOMEM); ++ ++ pll->base_addr = base + data->reg; ++ pll->pwr_addr = base + data->pwr_reg; ++ pll->pd_addr = base + data->pd_reg; ++ pll->pcw_addr = base + data->pcw_reg; ++ if (data->tuner_reg) ++ pll->tuner_addr = base + data->tuner_reg; ++ pll->hw.init = &init; ++ pll->data = data; ++ ++ init.name = data->name; ++ init.ops = &mtk_pll_ops; ++ init.parent_names = &parent_name; ++ init.num_parents = 1; ++ ++ clk = clk_register(NULL, &pll->hw); ++ ++ if (IS_ERR(clk)) ++ kfree(pll); ++ ++ return clk; ++} ++ ++void __init mtk_clk_register_plls(struct device_node *node, ++ const struct mtk_pll_data *plls, int num_plls, struct clk_onecell_data *clk_data) ++{ ++ void __iomem *base; ++ int r, i; ++ struct clk *clk; ++ ++ base = of_iomap(node, 0); ++ if (!base) { ++ pr_err("%s(): ioremap failed\n", __func__); ++ return; ++ } ++ ++ for (i = 0; i < num_plls; i++) { ++ const struct mtk_pll_data *pll = &plls[i]; ++ ++ clk = mtk_clk_register_pll(pll, base); ++ ++ if (IS_ERR(clk)) { ++ pr_err("Failed to register clk %s: %ld\n", ++ pll->name, PTR_ERR(clk)); ++ continue; ++ } ++ ++ clk_data->clks[pll->id] = clk; ++ } ++ ++ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); ++ if (r) ++ pr_err("%s(): could not register clock provider: %d\n", ++ __func__, r); ++} +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0003-clk-mediatek-Add-reset-controller-support.patch b/target/linux/mediatek/patches/0003-clk-mediatek-Add-reset-controller-support.patch new file mode 100644 index 0000000000..bb6f64b9b2 --- /dev/null +++ b/target/linux/mediatek/patches/0003-clk-mediatek-Add-reset-controller-support.patch @@ -0,0 +1,155 @@ +From c91e8490e45c68ea517f70f24568034b7735e8b9 Mon Sep 17 00:00:00 2001 +From: Sascha Hauer <s.hauer@pengutronix.de> +Date: Thu, 23 Apr 2015 10:35:40 +0200 +Subject: [PATCH 03/76] clk: mediatek: Add reset controller support + +The pericfg and infracfg units also provide reset lines to several +other SoC internal units. This adds a function which can be called +from the pericfg and infracfg initialization functions which will +register the reset controller using reset_controller_register. The +reset controller will provide support for resetting the units +connected to the pericfg and infracfg controller. The units resetted +by this controller can use the standard reset device tree binding +to gain access to the reset lines. + +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +Acked-by: Philipp Zabel <p.zabel@pengutronix.de> +--- + drivers/clk/mediatek/Makefile | 1 + + drivers/clk/mediatek/clk-mtk.h | 10 +++++ + drivers/clk/mediatek/reset.c | 97 ++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 108 insertions(+) + create mode 100644 drivers/clk/mediatek/reset.c + +diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile +index c384e97..0b6f1c3 100644 +--- a/drivers/clk/mediatek/Makefile ++++ b/drivers/clk/mediatek/Makefile +@@ -1 +1,2 @@ + obj-y += clk-mtk.o clk-pll.o clk-gate.o ++obj-$(CONFIG_RESET_CONTROLLER) += reset.o +diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h +index 694fc39..61035b9 100644 +--- a/drivers/clk/mediatek/clk-mtk.h ++++ b/drivers/clk/mediatek/clk-mtk.h +@@ -156,4 +156,14 @@ void __init mtk_clk_register_plls(struct device_node *node, + const struct mtk_pll_data *plls, int num_plls, + struct clk_onecell_data *clk_data); + ++#ifdef CONFIG_RESET_CONTROLLER ++void mtk_register_reset_controller(struct device_node *np, ++ unsigned int num_regs, int regofs); ++#else ++static inline void mtk_register_reset_controller(struct device_node *np, ++ unsigned int num_regs, int regofs) ++{ ++} ++#endif ++ + #endif /* __DRV_CLK_MTK_H */ +diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c +new file mode 100644 +index 0000000..9e9fe4b +--- /dev/null ++++ b/drivers/clk/mediatek/reset.c +@@ -0,0 +1,97 @@ ++/* ++ * Copyright (c) 2014 MediaTek Inc. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/mfd/syscon.h> ++#include <linux/module.h> ++#include <linux/of.h> ++#include <linux/platform_device.h> ++#include <linux/regmap.h> ++#include <linux/reset-controller.h> ++#include <linux/slab.h> ++ ++#include "clk-mtk.h" ++ ++struct mtk_reset { ++ struct regmap *regmap; ++ int regofs; ++ struct reset_controller_dev rcdev; ++}; ++ ++static int mtk_reset_assert(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev); ++ ++ return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2), ++ BIT(id % 32), ~0); ++} ++ ++static int mtk_reset_deassert(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev); ++ ++ return regmap_update_bits(data->regmap, data->regofs + ((id / 32) << 2), ++ BIT(id % 32), 0); ++} ++ ++static int mtk_reset(struct reset_controller_dev *rcdev, ++ unsigned long id) ++{ ++ int ret; ++ ++ ret = mtk_reset_assert(rcdev, id); ++ if (ret) ++ return ret; ++ ++ return mtk_reset_deassert(rcdev, id); ++} ++ ++static struct reset_control_ops mtk_reset_ops = { ++ .assert = mtk_reset_assert, ++ .deassert = mtk_reset_deassert, ++ .reset = mtk_reset, ++}; ++ ++void mtk_register_reset_controller(struct device_node *np, ++ unsigned int num_regs, int regofs) ++{ ++ struct mtk_reset *data; ++ int ret; ++ struct regmap *regmap; ++ ++ regmap = syscon_node_to_regmap(np); ++ if (IS_ERR(regmap)) { ++ pr_err("Cannot find regmap for %s: %ld\n", np->full_name, ++ PTR_ERR(regmap)); ++ return; ++ } ++ ++ data = kzalloc(sizeof(*data), GFP_KERNEL); ++ if (!data) ++ return; ++ ++ data->regmap = regmap; ++ data->regofs = regofs; ++ data->rcdev.owner = THIS_MODULE; ++ data->rcdev.nr_resets = num_regs * 32; ++ data->rcdev.ops = &mtk_reset_ops; ++ data->rcdev.of_node = np; ++ ++ ret = reset_controller_register(&data->rcdev); ++ if (ret) { ++ pr_err("could not register reset controller: %d\n", ret); ++ kfree(data); ++ return; ++ } ++} +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0004-clk-mediatek-Add-basic-clocks-for-Mediatek-MT8135.patch b/target/linux/mediatek/patches/0004-clk-mediatek-Add-basic-clocks-for-Mediatek-MT8135.patch new file mode 100644 index 0000000000..8666128ddc --- /dev/null +++ b/target/linux/mediatek/patches/0004-clk-mediatek-Add-basic-clocks-for-Mediatek-MT8135.patch @@ -0,0 +1,952 @@ +From 242572135fdb513cba0506415c7e26a0909eb4b5 Mon Sep 17 00:00:00 2001 +From: James Liao <jamesjj.liao@mediatek.com> +Date: Thu, 23 Apr 2015 10:35:41 +0200 +Subject: [PATCH 04/76] clk: mediatek: Add basic clocks for Mediatek MT8135. + +This patch adds basic clocks for MT8135, including TOPCKGEN, PLLs, +INFRA and PERI clocks. + +Signed-off-by: James Liao <jamesjj.liao@mediatek.com> +Signed-off-by: Henry Chen <henryc.chen@mediatek.com> +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +--- + drivers/clk/mediatek/Makefile | 1 + + drivers/clk/mediatek/clk-mt8135.c | 644 ++++++++++++++++++++ + include/dt-bindings/clock/mt8135-clk.h | 194 ++++++ + .../dt-bindings/reset-controller/mt8135-resets.h | 64 ++ + 4 files changed, 903 insertions(+) + create mode 100644 drivers/clk/mediatek/clk-mt8135.c + create mode 100644 include/dt-bindings/clock/mt8135-clk.h + create mode 100644 include/dt-bindings/reset-controller/mt8135-resets.h + +diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile +index 0b6f1c3..12ce576 100644 +--- a/drivers/clk/mediatek/Makefile ++++ b/drivers/clk/mediatek/Makefile +@@ -1,2 +1,3 @@ + obj-y += clk-mtk.o clk-pll.o clk-gate.o + obj-$(CONFIG_RESET_CONTROLLER) += reset.o ++obj-y += clk-mt8135.o +diff --git a/drivers/clk/mediatek/clk-mt8135.c b/drivers/clk/mediatek/clk-mt8135.c +new file mode 100644 +index 0000000..a63435b +--- /dev/null ++++ b/drivers/clk/mediatek/clk-mt8135.c +@@ -0,0 +1,644 @@ ++/* ++ * Copyright (c) 2014 MediaTek Inc. ++ * Author: James Liao <jamesjj.liao@mediatek.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/of.h> ++#include <linux/of_address.h> ++#include <linux/slab.h> ++#include <linux/mfd/syscon.h> ++#include <dt-bindings/clock/mt8135-clk.h> ++ ++#include "clk-mtk.h" ++#include "clk-gate.h" ++ ++static DEFINE_SPINLOCK(mt8135_clk_lock); ++ ++static const struct mtk_fixed_factor root_clk_alias[] __initconst = { ++ FACTOR(CLK_TOP_DSI0_LNTC_DSICLK, "dsi0_lntc_dsiclk", "clk_null", 1, 1), ++ FACTOR(CLK_TOP_HDMITX_CLKDIG_CTS, "hdmitx_clkdig_cts", "clk_null", 1, 1), ++ FACTOR(CLK_TOP_CLKPH_MCK, "clkph_mck", "clk_null", 1, 1), ++ FACTOR(CLK_TOP_CPUM_TCK_IN, "cpum_tck_in", "clk_null", 1, 1), ++}; ++ ++static const struct mtk_fixed_factor top_divs[] __initconst = { ++ FACTOR(CLK_TOP_MAINPLL_806M, "mainpll_806m", "mainpll", 1, 2), ++ FACTOR(CLK_TOP_MAINPLL_537P3M, "mainpll_537p3m", "mainpll", 1, 3), ++ FACTOR(CLK_TOP_MAINPLL_322P4M, "mainpll_322p4m", "mainpll", 1, 5), ++ FACTOR(CLK_TOP_MAINPLL_230P3M, "mainpll_230p3m", "mainpll", 1, 7), ++ ++ FACTOR(CLK_TOP_UNIVPLL_624M, "univpll_624m", "univpll", 1, 2), ++ FACTOR(CLK_TOP_UNIVPLL_416M, "univpll_416m", "univpll", 1, 3), ++ FACTOR(CLK_TOP_UNIVPLL_249P6M, "univpll_249p6m", "univpll", 1, 5), ++ FACTOR(CLK_TOP_UNIVPLL_178P3M, "univpll_178p3m", "univpll", 1, 7), ++ FACTOR(CLK_TOP_UNIVPLL_48M, "univpll_48m", "univpll", 1, 26), ++ ++ FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2), ++ FACTOR(CLK_TOP_MMPLL_D3, "mmpll_d3", "mmpll", 1, 3), ++ FACTOR(CLK_TOP_MMPLL_D5, "mmpll_d5", "mmpll", 1, 5), ++ FACTOR(CLK_TOP_MMPLL_D7, "mmpll_d7", "mmpll", 1, 7), ++ FACTOR(CLK_TOP_MMPLL_D4, "mmpll_d4", "mmpll_d2", 1, 2), ++ FACTOR(CLK_TOP_MMPLL_D6, "mmpll_d6", "mmpll_d3", 1, 2), ++ ++ FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "mainpll_806m", 1, 1), ++ FACTOR(CLK_TOP_SYSPLL_D4, "syspll_d4", "mainpll_806m", 1, 2), ++ FACTOR(CLK_TOP_SYSPLL_D6, "syspll_d6", "mainpll_806m", 1, 3), ++ FACTOR(CLK_TOP_SYSPLL_D8, "syspll_d8", "mainpll_806m", 1, 4), ++ FACTOR(CLK_TOP_SYSPLL_D10, "syspll_d10", "mainpll_806m", 1, 5), ++ FACTOR(CLK_TOP_SYSPLL_D12, "syspll_d12", "mainpll_806m", 1, 6), ++ FACTOR(CLK_TOP_SYSPLL_D16, "syspll_d16", "mainpll_806m", 1, 8), ++ FACTOR(CLK_TOP_SYSPLL_D24, "syspll_d24", "mainpll_806m", 1, 12), ++ ++ FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "mainpll_537p3m", 1, 1), ++ ++ FACTOR(CLK_TOP_SYSPLL_D2P5, "syspll_d2p5", "mainpll_322p4m", 2, 1), ++ FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll_322p4m", 1, 1), ++ ++ FACTOR(CLK_TOP_SYSPLL_D3P5, "syspll_d3p5", "mainpll_230p3m", 2, 1), ++ ++ FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_624m", 1, 2), ++ FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_624m", 1, 4), ++ FACTOR(CLK_TOP_UNIVPLL1_D6, "univpll1_d6", "univpll_624m", 1, 6), ++ FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_624m", 1, 8), ++ FACTOR(CLK_TOP_UNIVPLL1_D10, "univpll1_d10", "univpll_624m", 1, 10), ++ ++ FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_416m", 1, 2), ++ FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_416m", 1, 4), ++ FACTOR(CLK_TOP_UNIVPLL2_D6, "univpll2_d6", "univpll_416m", 1, 6), ++ FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_416m", 1, 8), ++ ++ FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univpll_416m", 1, 1), ++ FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll_249p6m", 1, 1), ++ FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univpll_178p3m", 1, 1), ++ FACTOR(CLK_TOP_UNIVPLL_D10, "univpll_d10", "univpll_249p6m", 1, 2), ++ FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univpll_48m", 1, 1), ++ ++ FACTOR(CLK_TOP_APLL, "apll_ck", "audpll", 1, 1), ++ FACTOR(CLK_TOP_APLL_D4, "apll_d4", "audpll", 1, 4), ++ FACTOR(CLK_TOP_APLL_D8, "apll_d8", "audpll", 1, 8), ++ FACTOR(CLK_TOP_APLL_D16, "apll_d16", "audpll", 1, 16), ++ FACTOR(CLK_TOP_APLL_D24, "apll_d24", "audpll", 1, 24), ++ ++ FACTOR(CLK_TOP_LVDSPLL_D2, "lvdspll_d2", "lvdspll", 1, 2), ++ FACTOR(CLK_TOP_LVDSPLL_D4, "lvdspll_d4", "lvdspll", 1, 4), ++ FACTOR(CLK_TOP_LVDSPLL_D8, "lvdspll_d8", "lvdspll", 1, 8), ++ ++ FACTOR(CLK_TOP_LVDSTX_CLKDIG_CT, "lvdstx_clkdig_cts", "lvdspll", 1, 1), ++ FACTOR(CLK_TOP_VPLL_DPIX, "vpll_dpix_ck", "lvdspll", 1, 1), ++ ++ FACTOR(CLK_TOP_TVHDMI_H, "tvhdmi_h_ck", "tvdpll", 1, 1), ++ ++ FACTOR(CLK_TOP_HDMITX_CLKDIG_D2, "hdmitx_clkdig_d2", "hdmitx_clkdig_cts", 1, 2), ++ FACTOR(CLK_TOP_HDMITX_CLKDIG_D3, "hdmitx_clkdig_d3", "hdmitx_clkdig_cts", 1, 3), ++ ++ FACTOR(CLK_TOP_TVHDMI_D2, "tvhdmi_d2", "tvhdmi_h_ck", 1, 2), ++ FACTOR(CLK_TOP_TVHDMI_D4, "tvhdmi_d4", "tvhdmi_h_ck", 1, 4), ++ ++ FACTOR(CLK_TOP_MEMPLL_MCK_D4, "mempll_mck_d4", "clkph_mck", 1, 4), ++}; ++ ++static const char * const axi_parents[] __initconst = { ++ "clk26m", ++ "syspll_d3", ++ "syspll_d4", ++ "syspll_d6", ++ "univpll_d5", ++ "univpll2_d2", ++ "syspll_d3p5" ++}; ++ ++static const char * const smi_parents[] __initconst = { ++ "clk26m", ++ "clkph_mck", ++ "syspll_d2p5", ++ "syspll_d3", ++ "syspll_d8", ++ "univpll_d5", ++ "univpll1_d2", ++ "univpll1_d6", ++ "mmpll_d3", ++ "mmpll_d4", ++ "mmpll_d5", ++ "mmpll_d6", ++ "mmpll_d7", ++ "vdecpll", ++ "lvdspll" ++}; ++ ++static const char * const mfg_parents[] __initconst = { ++ "clk26m", ++ "univpll1_d4", ++ "syspll_d2", ++ "syspll_d2p5", ++ "syspll_d3", ++ "univpll_d5", ++ "univpll1_d2", ++ "mmpll_d2", ++ "mmpll_d3", ++ "mmpll_d4", ++ "mmpll_d5", ++ "mmpll_d6", ++ "mmpll_d7" ++}; ++ ++static const char * const irda_parents[] __initconst = { ++ "clk26m", ++ "univpll2_d8", ++ "univpll1_d6" ++}; ++ ++static const char * const cam_parents[] __initconst = { ++ "clk26m", ++ "syspll_d3", ++ "syspll_d3p5", ++ "syspll_d4", ++ "univpll_d5", ++ "univpll2_d2", ++ "univpll_d7", ++ "univpll1_d4" ++}; ++ ++static const char * const aud_intbus_parents[] __initconst = { ++ "clk26m", ++ "syspll_d6", ++ "univpll_d10" ++}; ++ ++static const char * const jpg_parents[] __initconst = { ++ "clk26m", ++ "syspll_d5", ++ "syspll_d4", ++ "syspll_d3", ++ "univpll_d7", ++ "univpll2_d2", ++ "univpll_d5" ++}; ++ ++static const char * const disp_parents[] __initconst = { ++ "clk26m", ++ "syspll_d3p5", ++ "syspll_d3", ++ "univpll2_d2", ++ "univpll_d5", ++ "univpll1_d2", ++ "lvdspll", ++ "vdecpll" ++}; ++ ++static const char * const msdc30_parents[] __initconst = { ++ "clk26m", ++ "syspll_d6", ++ "syspll_d5", ++ "univpll1_d4", ++ "univpll2_d4", ++ "msdcpll" ++}; ++ ++static const char * const usb20_parents[] __initconst = { ++ "clk26m", ++ "univpll2_d6", ++ "univpll1_d10" ++}; ++ ++static const char * const venc_parents[] __initconst = { ++ "clk26m", ++ "syspll_d3", ++ "syspll_d8", ++ "univpll_d5", ++ "univpll1_d6", ++ "mmpll_d4", ++ "mmpll_d5", ++ "mmpll_d6" ++}; ++ ++static const char * const spi_parents[] __initconst = { ++ "clk26m", ++ "syspll_d6", ++ "syspll_d8", ++ "syspll_d10", ++ "univpll1_d6", ++ "univpll1_d8" ++}; ++ ++static const char * const uart_parents[] __initconst = { ++ "clk26m", ++ "univpll2_d8" ++}; ++ ++static const char * const mem_parents[] __initconst = { ++ "clk26m", ++ "clkph_mck" ++}; ++ ++static const char * const camtg_parents[] __initconst = { ++ "clk26m", ++ "univpll_d26", ++ "univpll1_d6", ++ "syspll_d16", ++ "syspll_d8" ++}; ++ ++static const char * const audio_parents[] __initconst = { ++ "clk26m", ++ "syspll_d24" ++}; ++ ++static const char * const fix_parents[] __initconst = { ++ "rtc32k", ++ "clk26m", ++ "univpll_d5", ++ "univpll_d7", ++ "univpll1_d2", ++ "univpll1_d4", ++ "univpll1_d6", ++ "univpll1_d8" ++}; ++ ++static const char * const vdec_parents[] __initconst = { ++ "clk26m", ++ "vdecpll", ++ "clkph_mck", ++ "syspll_d2p5", ++ "syspll_d3", ++ "syspll_d3p5", ++ "syspll_d4", ++ "syspll_d5", ++ "syspll_d6", ++ "syspll_d8", ++ "univpll1_d2", ++ "univpll2_d2", ++ "univpll_d7", ++ "univpll_d10", ++ "univpll2_d4", ++ "lvdspll" ++}; ++ ++static const char * const ddrphycfg_parents[] __initconst = { ++ "clk26m", ++ "axi_sel", ++ "syspll_d12" ++}; ++ ++static const char * const dpilvds_parents[] __initconst = { ++ "clk26m", ++ "lvdspll", ++ "lvdspll_d2", ++ "lvdspll_d4", ++ "lvdspll_d8" ++}; ++ ++static const char * const pmicspi_parents[] __initconst = { ++ "clk26m", ++ "univpll2_d6", ++ "syspll_d8", ++ "syspll_d10", ++ "univpll1_d10", ++ "mempll_mck_d4", ++ "univpll_d26", ++ "syspll_d24" ++}; ++ ++static const char * const smi_mfg_as_parents[] __initconst = { ++ "clk26m", ++ "smi_sel", ++ "mfg_sel", ++ "mem_sel" ++}; ++ ++static const char * const gcpu_parents[] __initconst = { ++ "clk26m", ++ "syspll_d4", ++ "univpll_d7", ++ "syspll_d5", ++ "syspll_d6" ++}; ++ ++static const char * const dpi1_parents[] __initconst = { ++ "clk26m", ++ "tvhdmi_h_ck", ++ "tvhdmi_d2", ++ "tvhdmi_d4" ++}; ++ ++static const char * const cci_parents[] __initconst = { ++ "clk26m", ++ "mainpll_537p3m", ++ "univpll_d3", ++ "syspll_d2p5", ++ "syspll_d3", ++ "syspll_d5" ++}; ++ ++static const char * const apll_parents[] __initconst = { ++ "clk26m", ++ "apll_ck", ++ "apll_d4", ++ "apll_d8", ++ "apll_d16", ++ "apll_d24" ++}; ++ ++static const char * const hdmipll_parents[] __initconst = { ++ "clk26m", ++ "hdmitx_clkdig_cts", ++ "hdmitx_clkdig_d2", ++ "hdmitx_clkdig_d3" ++}; ++ ++static const struct mtk_composite top_muxes[] __initconst = { ++ /* CLK_CFG_0 */ ++ MUX_GATE(CLK_TOP_AXI_SEL, "axi_sel", axi_parents, ++ 0x0140, 0, 3, INVALID_MUX_GATE_BIT), ++ MUX_GATE(CLK_TOP_SMI_SEL, "smi_sel", smi_parents, 0x0140, 8, 4, 15), ++ MUX_GATE(CLK_TOP_MFG_SEL, "mfg_sel", mfg_parents, 0x0140, 16, 4, 23), ++ MUX_GATE(CLK_TOP_IRDA_SEL, "irda_sel", irda_parents, 0x0140, 24, 2, 31), ++ /* CLK_CFG_1 */ ++ MUX_GATE(CLK_TOP_CAM_SEL, "cam_sel", cam_parents, 0x0144, 0, 3, 7), ++ MUX_GATE(CLK_TOP_AUD_INTBUS_SEL, "aud_intbus_sel", aud_intbus_parents, ++ 0x0144, 8, 2, 15), ++ MUX_GATE(CLK_TOP_JPG_SEL, "jpg_sel", jpg_parents, 0x0144, 16, 3, 23), ++ MUX_GATE(CLK_TOP_DISP_SEL, "disp_sel", disp_parents, 0x0144, 24, 3, 31), ++ /* CLK_CFG_2 */ ++ MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_parents, 0x0148, 0, 3, 7), ++ MUX_GATE(CLK_TOP_MSDC30_2_SEL, "msdc30_2_sel", msdc30_parents, 0x0148, 8, 3, 15), ++ MUX_GATE(CLK_TOP_MSDC30_3_SEL, "msdc30_3_sel", msdc30_parents, 0x0148, 16, 3, 23), ++ MUX_GATE(CLK_TOP_MSDC30_4_SEL, "msdc30_4_sel", msdc30_parents, 0x0148, 24, 3, 31), ++ /* CLK_CFG_3 */ ++ MUX_GATE(CLK_TOP_USB20_SEL, "usb20_sel", usb20_parents, 0x014c, 0, 2, 7), ++ /* CLK_CFG_4 */ ++ MUX_GATE(CLK_TOP_VENC_SEL, "venc_sel", venc_parents, 0x0150, 8, 3, 15), ++ MUX_GATE(CLK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x0150, 16, 3, 23), ++ MUX_GATE(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x0150, 24, 2, 31), ++ /* CLK_CFG_6 */ ++ MUX_GATE(CLK_TOP_MEM_SEL, "mem_sel", mem_parents, 0x0158, 0, 2, 7), ++ MUX_GATE(CLK_TOP_CAMTG_SEL, "camtg_sel", camtg_parents, 0x0158, 8, 3, 15), ++ MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel", audio_parents, 0x0158, 24, 2, 31), ++ /* CLK_CFG_7 */ ++ MUX_GATE(CLK_TOP_FIX_SEL, "fix_sel", fix_parents, 0x015c, 0, 3, 7), ++ MUX_GATE(CLK_TOP_VDEC_SEL, "vdec_sel", vdec_parents, 0x015c, 8, 4, 15), ++ MUX_GATE(CLK_TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents, ++ 0x015c, 16, 2, 23), ++ MUX_GATE(CLK_TOP_DPILVDS_SEL, "dpilvds_sel", dpilvds_parents, 0x015c, 24, 3, 31), ++ /* CLK_CFG_8 */ ++ MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents, 0x0164, 0, 3, 7), ++ MUX_GATE(CLK_TOP_MSDC30_0_SEL, "msdc30_0_sel", msdc30_parents, 0x0164, 8, 3, 15), ++ MUX_GATE(CLK_TOP_SMI_MFG_AS_SEL, "smi_mfg_as_sel", smi_mfg_as_parents, ++ 0x0164, 16, 2, 23), ++ MUX_GATE(CLK_TOP_GCPU_SEL, "gcpu_sel", gcpu_parents, 0x0164, 24, 3, 31), ++ /* CLK_CFG_9 */ ++ MUX_GATE(CLK_TOP_DPI1_SEL, "dpi1_sel", dpi1_parents, 0x0168, 0, 2, 7), ++ MUX_GATE(CLK_TOP_CCI_SEL, "cci_sel", cci_parents, 0x0168, 8, 3, 15), ++ MUX_GATE(CLK_TOP_APLL_SEL, "apll_sel", apll_parents, 0x0168, 16, 3, 23), ++ MUX_GATE(CLK_TOP_HDMIPLL_SEL, "hdmipll_sel", hdmipll_parents, 0x0168, 24, 2, 31), ++}; ++ ++static const struct mtk_gate_regs infra_cg_regs = { ++ .set_ofs = 0x0040, ++ .clr_ofs = 0x0044, ++ .sta_ofs = 0x0048, ++}; ++ ++#define GATE_ICG(_id, _name, _parent, _shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .regs = &infra_cg_regs, \ ++ .shift = _shift, \ ++ .ops = &mtk_clk_gate_ops_setclr, \ ++ } ++ ++static const struct mtk_gate infra_clks[] __initconst = { ++ GATE_ICG(CLK_INFRA_PMIC_WRAP, "pmic_wrap_ck", "axi_sel", 23), ++ GATE_ICG(CLK_INFRA_PMICSPI, "pmicspi_ck", "pmicspi_sel", 22), ++ GATE_ICG(CLK_INFRA_CCIF1_AP_CTRL, "ccif1_ap_ctrl", "axi_sel", 21), ++ GATE_ICG(CLK_INFRA_CCIF0_AP_CTRL, "ccif0_ap_ctrl", "axi_sel", 20), ++ GATE_ICG(CLK_INFRA_KP, "kp_ck", "axi_sel", 16), ++ GATE_ICG(CLK_INFRA_CPUM, "cpum_ck", "cpum_tck_in", 15), ++ GATE_ICG(CLK_INFRA_M4U, "m4u_ck", "mem_sel", 8), ++ GATE_ICG(CLK_INFRA_MFGAXI, "mfgaxi_ck", "axi_sel", 7), ++ GATE_ICG(CLK_INFRA_DEVAPC, "devapc_ck", "axi_sel", 6), ++ GATE_ICG(CLK_INFRA_AUDIO, "audio_ck", "aud_intbus_sel", 5), ++ GATE_ICG(CLK_INFRA_MFG_BUS, "mfg_bus_ck", "axi_sel", 2), ++ GATE_ICG(CLK_INFRA_SMI, "smi_ck", "smi_sel", 1), ++ GATE_ICG(CLK_INFRA_DBGCLK, "dbgclk_ck", "axi_sel", 0), ++}; ++ ++static const struct mtk_gate_regs peri0_cg_regs = { ++ .set_ofs = 0x0008, ++ .clr_ofs = 0x0010, ++ .sta_ofs = 0x0018, ++}; ++ ++static const struct mtk_gate_regs peri1_cg_regs = { ++ .set_ofs = 0x000c, ++ .clr_ofs = 0x0014, ++ .sta_ofs = 0x001c, ++}; ++ ++#define GATE_PERI0(_id, _name, _parent, _shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .regs = &peri0_cg_regs, \ ++ .shift = _shift, \ ++ .ops = &mtk_clk_gate_ops_setclr, \ ++ } ++ ++#define GATE_PERI1(_id, _name, _parent, _shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .regs = &peri1_cg_regs, \ ++ .shift = _shift, \ ++ .ops = &mtk_clk_gate_ops_setclr, \ ++ } ++ ++static const struct mtk_gate peri_gates[] __initconst = { ++ /* PERI0 */ ++ GATE_PERI0(CLK_PERI_I2C5, "i2c5_ck", "axi_sel", 31), ++ GATE_PERI0(CLK_PERI_I2C4, "i2c4_ck", "axi_sel", 30), ++ GATE_PERI0(CLK_PERI_I2C3, "i2c3_ck", "axi_sel", 29), ++ GATE_PERI0(CLK_PERI_I2C2, "i2c2_ck", "axi_sel", 28), ++ GATE_PERI0(CLK_PERI_I2C1, "i2c1_ck", "axi_sel", 27), ++ GATE_PERI0(CLK_PERI_I2C0, "i2c0_ck", "axi_sel", 26), ++ GATE_PERI0(CLK_PERI_UART3, "uart3_ck", "axi_sel", 25), ++ GATE_PERI0(CLK_PERI_UART2, "uart2_ck", "axi_sel", 24), ++ GATE_PERI0(CLK_PERI_UART1, "uart1_ck", "axi_sel", 23), ++ GATE_PERI0(CLK_PERI_UART0, "uart0_ck", "axi_sel", 22), ++ GATE_PERI0(CLK_PERI_IRDA, "irda_ck", "irda_sel", 21), ++ GATE_PERI0(CLK_PERI_NLI, "nli_ck", "axi_sel", 20), ++ GATE_PERI0(CLK_PERI_MD_HIF, "md_hif_ck", "axi_sel", 19), ++ GATE_PERI0(CLK_PERI_AP_HIF, "ap_hif_ck", "axi_sel", 18), ++ GATE_PERI0(CLK_PERI_MSDC30_3, "msdc30_3_ck", "msdc30_4_sel", 17), ++ GATE_PERI0(CLK_PERI_MSDC30_2, "msdc30_2_ck", "msdc30_3_sel", 16), ++ GATE_PERI0(CLK_PERI_MSDC30_1, "msdc30_1_ck", "msdc30_2_sel", 15), ++ GATE_PERI0(CLK_PERI_MSDC20_2, "msdc20_2_ck", "msdc30_1_sel", 14), ++ GATE_PERI0(CLK_PERI_MSDC20_1, "msdc20_1_ck", "msdc30_0_sel", 13), ++ GATE_PERI0(CLK_PERI_AP_DMA, "ap_dma_ck", "axi_sel", 12), ++ GATE_PERI0(CLK_PERI_USB1, "usb1_ck", "usb20_sel", 11), ++ GATE_PERI0(CLK_PERI_USB0, "usb0_ck", "usb20_sel", 10), ++ GATE_PERI0(CLK_PERI_PWM, "pwm_ck", "axi_sel", 9), ++ GATE_PERI0(CLK_PERI_PWM7, "pwm7_ck", "axi_sel", 8), ++ GATE_PERI0(CLK_PERI_PWM6, "pwm6_ck", "axi_sel", 7), ++ GATE_PERI0(CLK_PERI_PWM5, "pwm5_ck", "axi_sel", 6), ++ GATE_PERI0(CLK_PERI_PWM4, "pwm4_ck", "axi_sel", 5), ++ GATE_PERI0(CLK_PERI_PWM3, "pwm3_ck", "axi_sel", 4), ++ GATE_PERI0(CLK_PERI_PWM2, "pwm2_ck", "axi_sel", 3), ++ GATE_PERI0(CLK_PERI_PWM1, "pwm1_ck", "axi_sel", 2), ++ GATE_PERI0(CLK_PERI_THERM, "therm_ck", "axi_sel", 1), ++ GATE_PERI0(CLK_PERI_NFI, "nfi_ck", "axi_sel", 0), ++ /* PERI1 */ ++ GATE_PERI1(CLK_PERI_USBSLV, "usbslv_ck", "axi_sel", 8), ++ GATE_PERI1(CLK_PERI_USB1_MCU, "usb1_mcu_ck", "axi_sel", 7), ++ GATE_PERI1(CLK_PERI_USB0_MCU, "usb0_mcu_ck", "axi_sel", 6), ++ GATE_PERI1(CLK_PERI_GCPU, "gcpu_ck", "gcpu_sel", 5), ++ GATE_PERI1(CLK_PERI_FHCTL, "fhctl_ck", "clk26m", 4), ++ GATE_PERI1(CLK_PERI_SPI1, "spi1_ck", "spi_sel", 3), ++ GATE_PERI1(CLK_PERI_AUXADC, "auxadc_ck", "clk26m", 2), ++ GATE_PERI1(CLK_PERI_PERI_PWRAP, "peri_pwrap_ck", "axi_sel", 1), ++ GATE_PERI1(CLK_PERI_I2C6, "i2c6_ck", "axi_sel", 0), ++}; ++ ++static const char * const uart_ck_sel_parents[] __initconst = { ++ "clk26m", ++ "uart_sel", ++}; ++ ++static const struct mtk_composite peri_clks[] __initconst = { ++ MUX(CLK_PERI_UART0_SEL, "uart0_ck_sel", uart_ck_sel_parents, 0x40c, 0, 1), ++ MUX(CLK_PERI_UART1_SEL, "uart1_ck_sel", uart_ck_sel_parents, 0x40c, 1, 1), ++ MUX(CLK_PERI_UART2_SEL, "uart2_ck_sel", uart_ck_sel_parents, 0x40c, 2, 1), ++ MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents, 0x40c, 3, 1), ++}; ++ ++static void __init mtk_topckgen_init(struct device_node *node) ++{ ++ struct clk_onecell_data *clk_data; ++ void __iomem *base; ++ int r; ++ ++ base = of_iomap(node, 0); ++ if (!base) { ++ pr_err("%s(): ioremap failed\n", __func__); ++ return; ++ } ++ ++ clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); ++ ++ mtk_clk_register_factors(root_clk_alias, ARRAY_SIZE(root_clk_alias), clk_data); ++ mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data); ++ mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base, ++ &mt8135_clk_lock, clk_data); ++ ++ clk_prepare_enable(clk_data->clks[CLK_TOP_CCI_SEL]); ++ ++ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); ++ if (r) ++ pr_err("%s(): could not register clock provider: %d\n", ++ __func__, r); ++} ++CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt8135-topckgen", mtk_topckgen_init); ++ ++static void __init mtk_infrasys_init(struct device_node *node) ++{ ++ struct clk_onecell_data *clk_data; ++ int r; ++ ++ clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK); ++ ++ mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks), ++ clk_data); ++ ++ clk_prepare_enable(clk_data->clks[CLK_INFRA_M4U]); ++ ++ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); ++ if (r) ++ pr_err("%s(): could not register clock provider: %d\n", ++ __func__, r); ++ ++ mtk_register_reset_controller(node, 2, 0x30); ++} ++CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt8135-infracfg", mtk_infrasys_init); ++ ++static void __init mtk_pericfg_init(struct device_node *node) ++{ ++ struct clk_onecell_data *clk_data; ++ int r; ++ void __iomem *base; ++ ++ base = of_iomap(node, 0); ++ if (!base) { ++ pr_err("%s(): ioremap failed\n", __func__); ++ return; ++ } ++ ++ clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK); ++ ++ mtk_clk_register_gates(node, peri_gates, ARRAY_SIZE(peri_gates), ++ clk_data); ++ mtk_clk_register_composites(peri_clks, ARRAY_SIZE(peri_clks), base, ++ &mt8135_clk_lock, clk_data); ++ ++ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); ++ if (r) ++ pr_err("%s(): could not register clock provider: %d\n", ++ __func__, r); ++ ++ mtk_register_reset_controller(node, 2, 0); ++} ++CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8135-pericfg", mtk_pericfg_init); ++ ++#define MT8135_PLL_FMAX (2000 * MHZ) ++#define CON0_MT8135_RST_BAR BIT(27) ++ ++#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .reg = _reg, \ ++ .pwr_reg = _pwr_reg, \ ++ .en_mask = _en_mask, \ ++ .flags = _flags, \ ++ .rst_bar_mask = CON0_MT8135_RST_BAR, \ ++ .fmax = MT8135_PLL_FMAX, \ ++ .pcwbits = _pcwbits, \ ++ .pd_reg = _pd_reg, \ ++ .pd_shift = _pd_shift, \ ++ .tuner_reg = _tuner_reg, \ ++ .pcw_reg = _pcw_reg, \ ++ .pcw_shift = _pcw_shift, \ ++ } ++ ++static const struct mtk_pll_data plls[] = { ++ PLL(CLK_APMIXED_ARMPLL1, "armpll1", 0x200, 0x218, 0x80000001, 0, 21, 0x204, 24, 0x0, 0x204, 0), ++ PLL(CLK_APMIXED_ARMPLL2, "armpll2", 0x2cc, 0x2e4, 0x80000001, 0, 21, 0x2d0, 24, 0x0, 0x2d0, 0), ++ PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x21c, 0x234, 0xf0000001, HAVE_RST_BAR, 21, 0x21c, 6, 0x0, 0x220, 0), ++ PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x238, 0x250, 0xf3000001, HAVE_RST_BAR, 7, 0x238, 6, 0x0, 0x238, 9), ++ PLL(CLK_APMIXED_MMPLL, "mmpll", 0x254, 0x26c, 0xf0000001, HAVE_RST_BAR, 21, 0x254, 6, 0x0, 0x258, 0), ++ PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x278, 0x290, 0x80000001, 0, 21, 0x278, 6, 0x0, 0x27c, 0), ++ PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x294, 0x2ac, 0x80000001, 0, 31, 0x294, 6, 0x0, 0x298, 0), ++ PLL(CLK_APMIXED_LVDSPLL, "lvdspll", 0x2b0, 0x2c8, 0x80000001, 0, 21, 0x2b0, 6, 0x0, 0x2b4, 0), ++ PLL(CLK_APMIXED_AUDPLL, "audpll", 0x2e8, 0x300, 0x80000001, 0, 31, 0x2e8, 6, 0x2f8, 0x2ec, 0), ++ PLL(CLK_APMIXED_VDECPLL, "vdecpll", 0x304, 0x31c, 0x80000001, 0, 21, 0x2b0, 6, 0x0, 0x308, 0), ++}; ++ ++static void __init mtk_apmixedsys_init(struct device_node *node) ++{ ++ struct clk_onecell_data *clk_data; ++ ++ clk_data = mtk_alloc_clk_data(ARRAY_SIZE(plls)); ++ if (!clk_data) ++ return; ++ ++ mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); ++} ++CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8135-apmixedsys", ++ mtk_apmixedsys_init); +diff --git a/include/dt-bindings/clock/mt8135-clk.h b/include/dt-bindings/clock/mt8135-clk.h +new file mode 100644 +index 0000000..6dac6c0 +--- /dev/null ++++ b/include/dt-bindings/clock/mt8135-clk.h +@@ -0,0 +1,194 @@ ++/* ++ * Copyright (c) 2014 MediaTek Inc. ++ * Author: James Liao <jamesjj.liao@mediatek.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _DT_BINDINGS_CLK_MT8135_H ++#define _DT_BINDINGS_CLK_MT8135_H ++ ++/* TOPCKGEN */ ++ ++#define CLK_TOP_DSI0_LNTC_DSICLK 1 ++#define CLK_TOP_HDMITX_CLKDIG_CTS 2 ++#define CLK_TOP_CLKPH_MCK 3 ++#define CLK_TOP_CPUM_TCK_IN 4 ++#define CLK_TOP_MAINPLL_806M 5 ++#define CLK_TOP_MAINPLL_537P3M 6 ++#define CLK_TOP_MAINPLL_322P4M 7 ++#define CLK_TOP_MAINPLL_230P3M 8 ++#define CLK_TOP_UNIVPLL_624M 9 ++#define CLK_TOP_UNIVPLL_416M 10 ++#define CLK_TOP_UNIVPLL_249P6M 11 ++#define CLK_TOP_UNIVPLL_178P3M 12 ++#define CLK_TOP_UNIVPLL_48M 13 ++#define CLK_TOP_MMPLL_D2 14 ++#define CLK_TOP_MMPLL_D3 15 ++#define CLK_TOP_MMPLL_D5 16 ++#define CLK_TOP_MMPLL_D7 17 ++#define CLK_TOP_MMPLL_D4 18 ++#define CLK_TOP_MMPLL_D6 19 ++#define CLK_TOP_SYSPLL_D2 20 ++#define CLK_TOP_SYSPLL_D4 21 ++#define CLK_TOP_SYSPLL_D6 22 ++#define CLK_TOP_SYSPLL_D8 23 ++#define CLK_TOP_SYSPLL_D10 24 ++#define CLK_TOP_SYSPLL_D12 25 ++#define CLK_TOP_SYSPLL_D16 26 ++#define CLK_TOP_SYSPLL_D24 27 ++#define CLK_TOP_SYSPLL_D3 28 ++#define CLK_TOP_SYSPLL_D2P5 29 ++#define CLK_TOP_SYSPLL_D5 30 ++#define CLK_TOP_SYSPLL_D3P5 31 ++#define CLK_TOP_UNIVPLL1_D2 32 ++#define CLK_TOP_UNIVPLL1_D4 33 ++#define CLK_TOP_UNIVPLL1_D6 34 ++#define CLK_TOP_UNIVPLL1_D8 35 ++#define CLK_TOP_UNIVPLL1_D10 36 ++#define CLK_TOP_UNIVPLL2_D2 37 ++#define CLK_TOP_UNIVPLL2_D4 38 ++#define CLK_TOP_UNIVPLL2_D6 39 ++#define CLK_TOP_UNIVPLL2_D8 40 ++#define CLK_TOP_UNIVPLL_D3 41 ++#define CLK_TOP_UNIVPLL_D5 42 ++#define CLK_TOP_UNIVPLL_D7 43 ++#define CLK_TOP_UNIVPLL_D10 44 ++#define CLK_TOP_UNIVPLL_D26 45 ++#define CLK_TOP_APLL 46 ++#define CLK_TOP_APLL_D4 47 ++#define CLK_TOP_APLL_D8 48 ++#define CLK_TOP_APLL_D16 49 ++#define CLK_TOP_APLL_D24 50 ++#define CLK_TOP_LVDSPLL_D2 51 ++#define CLK_TOP_LVDSPLL_D4 52 ++#define CLK_TOP_LVDSPLL_D8 53 ++#define CLK_TOP_LVDSTX_CLKDIG_CT 54 ++#define CLK_TOP_VPLL_DPIX 55 ++#define CLK_TOP_TVHDMI_H 56 ++#define CLK_TOP_HDMITX_CLKDIG_D2 57 ++#define CLK_TOP_HDMITX_CLKDIG_D3 58 ++#define CLK_TOP_TVHDMI_D2 59 ++#define CLK_TOP_TVHDMI_D4 60 ++#define CLK_TOP_MEMPLL_MCK_D4 61 ++#define CLK_TOP_AXI_SEL 62 ++#define CLK_TOP_SMI_SEL 63 ++#define CLK_TOP_MFG_SEL 64 ++#define CLK_TOP_IRDA_SEL 65 ++#define CLK_TOP_CAM_SEL 66 ++#define CLK_TOP_AUD_INTBUS_SEL 67 ++#define CLK_TOP_JPG_SEL 68 ++#define CLK_TOP_DISP_SEL 69 ++#define CLK_TOP_MSDC30_1_SEL 70 ++#define CLK_TOP_MSDC30_2_SEL 71 ++#define CLK_TOP_MSDC30_3_SEL 72 ++#define CLK_TOP_MSDC30_4_SEL 73 ++#define CLK_TOP_USB20_SEL 74 ++#define CLK_TOP_VENC_SEL 75 ++#define CLK_TOP_SPI_SEL 76 ++#define CLK_TOP_UART_SEL 77 ++#define CLK_TOP_MEM_SEL 78 ++#define CLK_TOP_CAMTG_SEL 79 ++#define CLK_TOP_AUDIO_SEL 80 ++#define CLK_TOP_FIX_SEL 81 ++#define CLK_TOP_VDEC_SEL 82 ++#define CLK_TOP_DDRPHYCFG_SEL 83 ++#define CLK_TOP_DPILVDS_SEL 84 ++#define CLK_TOP_PMICSPI_SEL 85 ++#define CLK_TOP_MSDC30_0_SEL 86 ++#define CLK_TOP_SMI_MFG_AS_SEL 87 ++#define CLK_TOP_GCPU_SEL 88 ++#define CLK_TOP_DPI1_SEL 89 ++#define CLK_TOP_CCI_SEL 90 ++#define CLK_TOP_APLL_SEL 91 ++#define CLK_TOP_HDMIPLL_SEL 92 ++#define CLK_TOP_NR_CLK 93 ++ ++/* APMIXED_SYS */ ++ ++#define CLK_APMIXED_ARMPLL1 1 ++#define CLK_APMIXED_ARMPLL2 2 ++#define CLK_APMIXED_MAINPLL 3 ++#define CLK_APMIXED_UNIVPLL 4 ++#define CLK_APMIXED_MMPLL 5 ++#define CLK_APMIXED_MSDCPLL 6 ++#define CLK_APMIXED_TVDPLL 7 ++#define CLK_APMIXED_LVDSPLL 8 ++#define CLK_APMIXED_AUDPLL 9 ++#define CLK_APMIXED_VDECPLL 10 ++#define CLK_APMIXED_NR_CLK 11 ++ ++/* INFRA_SYS */ ++ ++#define CLK_INFRA_PMIC_WRAP 1 ++#define CLK_INFRA_PMICSPI 2 ++#define CLK_INFRA_CCIF1_AP_CTRL 3 ++#define CLK_INFRA_CCIF0_AP_CTRL 4 ++#define CLK_INFRA_KP 5 ++#define CLK_INFRA_CPUM 6 ++#define CLK_INFRA_M4U 7 ++#define CLK_INFRA_MFGAXI 8 ++#define CLK_INFRA_DEVAPC 9 ++#define CLK_INFRA_AUDIO 10 ++#define CLK_INFRA_MFG_BUS 11 ++#define CLK_INFRA_SMI 12 ++#define CLK_INFRA_DBGCLK 13 ++#define CLK_INFRA_NR_CLK 14 ++ ++/* PERI_SYS */ ++ ++#define CLK_PERI_I2C5 1 ++#define CLK_PERI_I2C4 2 ++#define CLK_PERI_I2C3 3 ++#define CLK_PERI_I2C2 4 ++#define CLK_PERI_I2C1 5 ++#define CLK_PERI_I2C0 6 ++#define CLK_PERI_UART3 7 ++#define CLK_PERI_UART2 8 ++#define CLK_PERI_UART1 9 ++#define CLK_PERI_UART0 10 ++#define CLK_PERI_IRDA 11 ++#define CLK_PERI_NLI 12 ++#define CLK_PERI_MD_HIF 13 ++#define CLK_PERI_AP_HIF 14 ++#define CLK_PERI_MSDC30_3 15 ++#define CLK_PERI_MSDC30_2 16 ++#define CLK_PERI_MSDC30_1 17 ++#define CLK_PERI_MSDC20_2 18 ++#define CLK_PERI_MSDC20_1 19 ++#define CLK_PERI_AP_DMA 20 ++#define CLK_PERI_USB1 21 ++#define CLK_PERI_USB0 22 ++#define CLK_PERI_PWM 23 ++#define CLK_PERI_PWM7 24 ++#define CLK_PERI_PWM6 25 ++#define CLK_PERI_PWM5 26 ++#define CLK_PERI_PWM4 27 ++#define CLK_PERI_PWM3 28 ++#define CLK_PERI_PWM2 29 ++#define CLK_PERI_PWM1 30 ++#define CLK_PERI_THERM 31 ++#define CLK_PERI_NFI 32 ++#define CLK_PERI_USBSLV 33 ++#define CLK_PERI_USB1_MCU 34 ++#define CLK_PERI_USB0_MCU 35 ++#define CLK_PERI_GCPU 36 ++#define CLK_PERI_FHCTL 37 ++#define CLK_PERI_SPI1 38 ++#define CLK_PERI_AUXADC 39 ++#define CLK_PERI_PERI_PWRAP 40 ++#define CLK_PERI_I2C6 41 ++#define CLK_PERI_UART0_SEL 42 ++#define CLK_PERI_UART1_SEL 43 ++#define CLK_PERI_UART2_SEL 44 ++#define CLK_PERI_UART3_SEL 45 ++#define CLK_PERI_NR_CLK 46 ++ ++#endif /* _DT_BINDINGS_CLK_MT8135_H */ +diff --git a/include/dt-bindings/reset-controller/mt8135-resets.h b/include/dt-bindings/reset-controller/mt8135-resets.h +new file mode 100644 +index 0000000..1fb6295 +--- /dev/null ++++ b/include/dt-bindings/reset-controller/mt8135-resets.h +@@ -0,0 +1,64 @@ ++/* ++ * Copyright (c) 2014 MediaTek Inc. ++ * Author: Flora Fu, MediaTek ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT8135 ++#define _DT_BINDINGS_RESET_CONTROLLER_MT8135 ++ ++/* INFRACFG resets */ ++#define MT8135_INFRA_EMI_REG_RST 0 ++#define MT8135_INFRA_DRAMC0_A0_RST 1 ++#define MT8135_INFRA_CCIF0_RST 2 ++#define MT8135_INFRA_APCIRQ_EINT_RST 3 ++#define MT8135_INFRA_APXGPT_RST 4 ++#define MT8135_INFRA_SCPSYS_RST 5 ++#define MT8135_INFRA_CCIF1_RST 6 ++#define MT8135_INFRA_PMIC_WRAP_RST 7 ++#define MT8135_INFRA_KP_RST 8 ++#define MT8135_INFRA_EMI_RST 32 ++#define MT8135_INFRA_DRAMC0_RST 34 ++#define MT8135_INFRA_SMI_RST 35 ++#define MT8135_INFRA_M4U_RST 36 ++ ++/* PERICFG resets */ ++#define MT8135_PERI_UART0_SW_RST 0 ++#define MT8135_PERI_UART1_SW_RST 1 ++#define MT8135_PERI_UART2_SW_RST 2 ++#define MT8135_PERI_UART3_SW_RST 3 ++#define MT8135_PERI_IRDA_SW_RST 4 ++#define MT8135_PERI_PTP_SW_RST 5 ++#define MT8135_PERI_AP_HIF_SW_RST 6 ++#define MT8135_PERI_GPCU_SW_RST 7 ++#define MT8135_PERI_MD_HIF_SW_RST 8 ++#define MT8135_PERI_NLI_SW_RST 9 ++#define MT8135_PERI_AUXADC_SW_RST 10 ++#define MT8135_PERI_DMA_SW_RST 11 ++#define MT8135_PERI_NFI_SW_RST 14 ++#define MT8135_PERI_PWM_SW_RST 15 ++#define MT8135_PERI_THERM_SW_RST 16 ++#define MT8135_PERI_MSDC0_SW_RST 17 ++#define MT8135_PERI_MSDC1_SW_RST 18 ++#define MT8135_PERI_MSDC2_SW_RST 19 ++#define MT8135_PERI_MSDC3_SW_RST 20 ++#define MT8135_PERI_I2C0_SW_RST 22 ++#define MT8135_PERI_I2C1_SW_RST 23 ++#define MT8135_PERI_I2C2_SW_RST 24 ++#define MT8135_PERI_I2C3_SW_RST 25 ++#define MT8135_PERI_I2C4_SW_RST 26 ++#define MT8135_PERI_I2C5_SW_RST 27 ++#define MT8135_PERI_I2C6_SW_RST 28 ++#define MT8135_PERI_USB_SW_RST 29 ++#define MT8135_PERI_SPI1_SW_RST 33 ++#define MT8135_PERI_PWRAP_BRIDGE_SW_RST 34 ++ ++#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT8135 */ +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0005-clk-mediatek-Add-basic-clocks-for-Mediatek-MT8173.patch b/target/linux/mediatek/patches/0005-clk-mediatek-Add-basic-clocks-for-Mediatek-MT8173.patch new file mode 100644 index 0000000000..9c0e2891a7 --- /dev/null +++ b/target/linux/mediatek/patches/0005-clk-mediatek-Add-basic-clocks-for-Mediatek-MT8173.patch @@ -0,0 +1,1179 @@ +From 0efcd47787019284a334186fce134ee475c79211 Mon Sep 17 00:00:00 2001 +From: James Liao <jamesjj.liao@mediatek.com> +Date: Thu, 23 Apr 2015 10:35:42 +0200 +Subject: [PATCH 05/76] clk: mediatek: Add basic clocks for Mediatek MT8173. + +This patch adds basic clocks for MT8173, including TOPCKGEN, PLLs, +INFRA and PERI clocks. + +Signed-off-by: James Liao <jamesjj.liao@mediatek.com> +Signed-off-by: Henry Chen <henryc.chen@mediatek.com> +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +--- + drivers/clk/mediatek/Makefile | 1 + + drivers/clk/mediatek/clk-mt8173.c | 830 ++++++++++++++++++++ + include/dt-bindings/clock/mt8173-clk.h | 235 ++++++ + .../dt-bindings/reset-controller/mt8173-resets.h | 63 ++ + 4 files changed, 1129 insertions(+) + create mode 100644 drivers/clk/mediatek/clk-mt8173.c + create mode 100644 include/dt-bindings/clock/mt8173-clk.h + create mode 100644 include/dt-bindings/reset-controller/mt8173-resets.h + +diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile +index 12ce576..8e4b2a4 100644 +--- a/drivers/clk/mediatek/Makefile ++++ b/drivers/clk/mediatek/Makefile +@@ -1,3 +1,4 @@ + obj-y += clk-mtk.o clk-pll.o clk-gate.o + obj-$(CONFIG_RESET_CONTROLLER) += reset.o + obj-y += clk-mt8135.o ++obj-y += clk-mt8173.o +diff --git a/drivers/clk/mediatek/clk-mt8173.c b/drivers/clk/mediatek/clk-mt8173.c +new file mode 100644 +index 0000000..357b080 +--- /dev/null ++++ b/drivers/clk/mediatek/clk-mt8173.c +@@ -0,0 +1,830 @@ ++/* ++ * Copyright (c) 2014 MediaTek Inc. ++ * Author: James Liao <jamesjj.liao@mediatek.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/of.h> ++#include <linux/of_address.h> ++#include <linux/slab.h> ++#include <linux/mfd/syscon.h> ++ ++#include "clk-mtk.h" ++#include "clk-gate.h" ++ ++#include <dt-bindings/clock/mt8173-clk.h> ++ ++static DEFINE_SPINLOCK(mt8173_clk_lock); ++ ++static const struct mtk_fixed_factor root_clk_alias[] __initconst = { ++ FACTOR(CLK_TOP_CLKPH_MCK_O, "clkph_mck_o", "clk_null", 1, 1), ++ FACTOR(CLK_TOP_DPI, "dpi_ck", "clk_null", 1, 1), ++ FACTOR(CLK_TOP_USB_SYSPLL_125M, "usb_syspll_125m", "clk_null", 1, 1), ++ FACTOR(CLK_TOP_HDMITX_DIG_CTS, "hdmitx_dig_cts", "clk_null", 1, 1), ++}; ++ ++static const struct mtk_fixed_factor top_divs[] __initconst = { ++ FACTOR(CLK_TOP_ARMCA7PLL_754M, "armca7pll_754m", "armca7pll", 1, 2), ++ FACTOR(CLK_TOP_ARMCA7PLL_502M, "armca7pll_502m", "armca7pll", 1, 3), ++ ++ FACTOR(CLK_TOP_MAIN_H546M, "main_h546m", "mainpll", 1, 2), ++ FACTOR(CLK_TOP_MAIN_H364M, "main_h364m", "mainpll", 1, 3), ++ FACTOR(CLK_TOP_MAIN_H218P4M, "main_h218p4m", "mainpll", 1, 5), ++ FACTOR(CLK_TOP_MAIN_H156M, "main_h156m", "mainpll", 1, 7), ++ ++ FACTOR(CLK_TOP_TVDPLL_445P5M, "tvdpll_445p5m", "tvdpll", 1, 4), ++ FACTOR(CLK_TOP_TVDPLL_594M, "tvdpll_594m", "tvdpll", 1, 3), ++ ++ FACTOR(CLK_TOP_UNIV_624M, "univ_624m", "univpll", 1, 2), ++ FACTOR(CLK_TOP_UNIV_416M, "univ_416m", "univpll", 1, 3), ++ FACTOR(CLK_TOP_UNIV_249P6M, "univ_249p6m", "univpll", 1, 5), ++ FACTOR(CLK_TOP_UNIV_178P3M, "univ_178p3m", "univpll", 1, 7), ++ FACTOR(CLK_TOP_UNIV_48M, "univ_48m", "univpll", 1, 26), ++ ++ FACTOR(CLK_TOP_CLKRTC_EXT, "clkrtc_ext", "clk32k", 1, 1), ++ FACTOR(CLK_TOP_CLKRTC_INT, "clkrtc_int", "clk26m", 1, 793), ++ FACTOR(CLK_TOP_FPC, "fpc_ck", "clk26m", 1, 1), ++ ++ FACTOR(CLK_TOP_HDMITXPLL_D2, "hdmitxpll_d2", "hdmitx_dig_cts", 1, 2), ++ FACTOR(CLK_TOP_HDMITXPLL_D3, "hdmitxpll_d3", "hdmitx_dig_cts", 1, 3), ++ ++ FACTOR(CLK_TOP_ARMCA7PLL_D2, "armca7pll_d2", "armca7pll_754m", 1, 1), ++ FACTOR(CLK_TOP_ARMCA7PLL_D3, "armca7pll_d3", "armca7pll_502m", 1, 1), ++ ++ FACTOR(CLK_TOP_APLL1, "apll1_ck", "apll1", 1, 1), ++ FACTOR(CLK_TOP_APLL2, "apll2_ck", "apll2", 1, 1), ++ ++ FACTOR(CLK_TOP_DMPLL, "dmpll_ck", "clkph_mck_o", 1, 1), ++ FACTOR(CLK_TOP_DMPLL_D2, "dmpll_d2", "clkph_mck_o", 1, 2), ++ FACTOR(CLK_TOP_DMPLL_D4, "dmpll_d4", "clkph_mck_o", 1, 4), ++ FACTOR(CLK_TOP_DMPLL_D8, "dmpll_d8", "clkph_mck_o", 1, 8), ++ FACTOR(CLK_TOP_DMPLL_D16, "dmpll_d16", "clkph_mck_o", 1, 16), ++ ++ FACTOR(CLK_TOP_LVDSPLL_D2, "lvdspll_d2", "lvdspll", 1, 2), ++ FACTOR(CLK_TOP_LVDSPLL_D4, "lvdspll_d4", "lvdspll", 1, 4), ++ FACTOR(CLK_TOP_LVDSPLL_D8, "lvdspll_d8", "lvdspll", 1, 8), ++ ++ FACTOR(CLK_TOP_MMPLL, "mmpll_ck", "mmpll", 1, 1), ++ FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2), ++ ++ FACTOR(CLK_TOP_MSDCPLL, "msdcpll_ck", "msdcpll", 1, 1), ++ FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2), ++ FACTOR(CLK_TOP_MSDCPLL_D4, "msdcpll_d4", "msdcpll", 1, 4), ++ FACTOR(CLK_TOP_MSDCPLL2, "msdcpll2_ck", "msdcpll2", 1, 1), ++ FACTOR(CLK_TOP_MSDCPLL2_D2, "msdcpll2_d2", "msdcpll2", 1, 2), ++ FACTOR(CLK_TOP_MSDCPLL2_D4, "msdcpll2_d4", "msdcpll2", 1, 4), ++ ++ FACTOR(CLK_TOP_SYSPLL_D2, "syspll_d2", "main_h546m", 1, 1), ++ FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "main_h546m", 1, 2), ++ FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "main_h546m", 1, 4), ++ FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "main_h546m", 1, 8), ++ FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "main_h546m", 1, 16), ++ FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "main_h364m", 1, 1), ++ FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "main_h364m", 1, 2), ++ FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "main_h364m", 1, 4), ++ FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "main_h218p4m", 1, 1), ++ FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "main_h218p4m", 1, 2), ++ FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "main_h218p4m", 1, 4), ++ FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "main_h156m", 1, 1), ++ FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "main_h156m", 1, 2), ++ FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "main_h156m", 1, 4), ++ ++ FACTOR(CLK_TOP_TVDPLL, "tvdpll_ck", "tvdpll_594m", 1, 1), ++ FACTOR(CLK_TOP_TVDPLL_D2, "tvdpll_d2", "tvdpll_594m", 1, 2), ++ FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll_594m", 1, 4), ++ FACTOR(CLK_TOP_TVDPLL_D8, "tvdpll_d8", "tvdpll_594m", 1, 8), ++ FACTOR(CLK_TOP_TVDPLL_D16, "tvdpll_d16", "tvdpll_594m", 1, 16), ++ ++ FACTOR(CLK_TOP_UNIVPLL_D2, "univpll_d2", "univ_624m", 1, 1), ++ FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univ_624m", 1, 2), ++ FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univ_624m", 1, 4), ++ FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univ_624m", 1, 8), ++ FACTOR(CLK_TOP_UNIVPLL_D3, "univpll_d3", "univ_416m", 1, 1), ++ FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univ_416m", 1, 2), ++ FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univ_416m", 1, 4), ++ FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univ_416m", 1, 8), ++ FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univ_249p6m", 1, 1), ++ FACTOR(CLK_TOP_UNIVPLL3_D2, "univpll3_d2", "univ_249p6m", 1, 2), ++ FACTOR(CLK_TOP_UNIVPLL3_D4, "univpll3_d4", "univ_249p6m", 1, 4), ++ FACTOR(CLK_TOP_UNIVPLL3_D8, "univpll3_d8", "univ_249p6m", 1, 8), ++ FACTOR(CLK_TOP_UNIVPLL_D7, "univpll_d7", "univ_178p3m", 1, 1), ++ FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univ_48m", 1, 1), ++ FACTOR(CLK_TOP_UNIVPLL_D52, "univpll_d52", "univ_48m", 1, 2), ++ ++ FACTOR(CLK_TOP_VCODECPLL, "vcodecpll_ck", "vcodecpll", 1, 3), ++ FACTOR(CLK_TOP_VCODECPLL_370P5, "vcodecpll_370p5", "vcodecpll", 1, 4), ++ ++ FACTOR(CLK_TOP_VENCPLL, "vencpll_ck", "vencpll", 1, 1), ++ FACTOR(CLK_TOP_VENCPLL_D2, "vencpll_d2", "vencpll", 1, 2), ++ FACTOR(CLK_TOP_VENCPLL_D4, "vencpll_d4", "vencpll", 1, 4), ++}; ++ ++static const char * const axi_parents[] __initconst = { ++ "clk26m", ++ "syspll1_d2", ++ "syspll_d5", ++ "syspll1_d4", ++ "univpll_d5", ++ "univpll2_d2", ++ "dmpll_d2", ++ "dmpll_d4" ++}; ++ ++static const char * const mem_parents[] __initconst = { ++ "clk26m", ++ "dmpll_ck" ++}; ++ ++static const char * const ddrphycfg_parents[] __initconst = { ++ "clk26m", ++ "syspll1_d8" ++}; ++ ++static const char * const mm_parents[] __initconst = { ++ "clk26m", ++ "vencpll_d2", ++ "main_h364m", ++ "syspll1_d2", ++ "syspll_d5", ++ "syspll1_d4", ++ "univpll1_d2", ++ "univpll2_d2", ++ "dmpll_d2" ++}; ++ ++static const char * const pwm_parents[] __initconst = { ++ "clk26m", ++ "univpll2_d4", ++ "univpll3_d2", ++ "univpll1_d4" ++}; ++ ++static const char * const vdec_parents[] __initconst = { ++ "clk26m", ++ "vcodecpll_ck", ++ "tvdpll_445p5m", ++ "univpll_d3", ++ "vencpll_d2", ++ "syspll_d3", ++ "univpll1_d2", ++ "mmpll_d2", ++ "dmpll_d2", ++ "dmpll_d4" ++}; ++ ++static const char * const venc_parents[] __initconst = { ++ "clk26m", ++ "vcodecpll_ck", ++ "tvdpll_445p5m", ++ "univpll_d3", ++ "vencpll_d2", ++ "syspll_d3", ++ "univpll1_d2", ++ "univpll2_d2", ++ "dmpll_d2", ++ "dmpll_d4" ++}; ++ ++static const char * const mfg_parents[] __initconst = { ++ "clk26m", ++ "mmpll_ck", ++ "dmpll_ck", ++ "clk26m", ++ "clk26m", ++ "clk26m", ++ "clk26m", ++ "clk26m", ++ "clk26m", ++ "syspll_d3", ++ "syspll1_d2", ++ "syspll_d5", ++ "univpll_d3", ++ "univpll1_d2", ++ "univpll_d5", ++ "univpll2_d2" ++}; ++ ++static const char * const camtg_parents[] __initconst = { ++ "clk26m", ++ "univpll_d26", ++ "univpll2_d2", ++ "syspll3_d2", ++ "syspll3_d4", ++ "univpll1_d4" ++}; ++ ++static const char * const uart_parents[] __initconst = { ++ "clk26m", ++ "univpll2_d8" ++}; ++ ++static const char * const spi_parents[] __initconst = { ++ "clk26m", ++ "syspll3_d2", ++ "syspll1_d4", ++ "syspll4_d2", ++ "univpll3_d2", ++ "univpll2_d4", ++ "univpll1_d8" ++}; ++ ++static const char * const usb20_parents[] __initconst = { ++ "clk26m", ++ "univpll1_d8", ++ "univpll3_d4" ++}; ++ ++static const char * const usb30_parents[] __initconst = { ++ "clk26m", ++ "univpll3_d2", ++ "usb_syspll_125m", ++ "univpll2_d4" ++}; ++ ++static const char * const msdc50_0_h_parents[] __initconst = { ++ "clk26m", ++ "syspll1_d2", ++ "syspll2_d2", ++ "syspll4_d2", ++ "univpll_d5", ++ "univpll1_d4" ++}; ++ ++static const char * const msdc50_0_parents[] __initconst = { ++ "clk26m", ++ "msdcpll_ck", ++ "msdcpll_d2", ++ "univpll1_d4", ++ "syspll2_d2", ++ "syspll_d7", ++ "msdcpll_d4", ++ "vencpll_d4", ++ "tvdpll_ck", ++ "univpll_d2", ++ "univpll1_d2", ++ "mmpll_ck", ++ "msdcpll2_ck", ++ "msdcpll2_d2", ++ "msdcpll2_d4" ++}; ++ ++static const char * const msdc30_1_parents[] __initconst = { ++ "clk26m", ++ "univpll2_d2", ++ "msdcpll_d4", ++ "univpll1_d4", ++ "syspll2_d2", ++ "syspll_d7", ++ "univpll_d7", ++ "vencpll_d4" ++}; ++ ++static const char * const msdc30_2_parents[] __initconst = { ++ "clk26m", ++ "univpll2_d2", ++ "msdcpll_d4", ++ "univpll1_d4", ++ "syspll2_d2", ++ "syspll_d7", ++ "univpll_d7", ++ "vencpll_d2" ++}; ++ ++static const char * const msdc30_3_parents[] __initconst = { ++ "clk26m", ++ "msdcpll2_ck", ++ "msdcpll2_d2", ++ "univpll2_d2", ++ "msdcpll2_d4", ++ "msdcpll_d4", ++ "univpll1_d4", ++ "syspll2_d2", ++ "syspll_d7", ++ "univpll_d7", ++ "vencpll_d4", ++ "msdcpll_ck", ++ "msdcpll_d2", ++ "msdcpll_d4" ++}; ++ ++static const char * const audio_parents[] __initconst = { ++ "clk26m", ++ "syspll3_d4", ++ "syspll4_d4", ++ "syspll1_d16" ++}; ++ ++static const char * const aud_intbus_parents[] __initconst = { ++ "clk26m", ++ "syspll1_d4", ++ "syspll4_d2", ++ "univpll3_d2", ++ "univpll2_d8", ++ "dmpll_d4", ++ "dmpll_d8" ++}; ++ ++static const char * const pmicspi_parents[] __initconst = { ++ "clk26m", ++ "syspll1_d8", ++ "syspll3_d4", ++ "syspll1_d16", ++ "univpll3_d4", ++ "univpll_d26", ++ "dmpll_d8", ++ "dmpll_d16" ++}; ++ ++static const char * const scp_parents[] __initconst = { ++ "clk26m", ++ "syspll1_d2", ++ "univpll_d5", ++ "syspll_d5", ++ "dmpll_d2", ++ "dmpll_d4" ++}; ++ ++static const char * const atb_parents[] __initconst = { ++ "clk26m", ++ "syspll1_d2", ++ "univpll_d5", ++ "dmpll_d2" ++}; ++ ++static const char * const venc_lt_parents[] __initconst = { ++ "clk26m", ++ "univpll_d3", ++ "vcodecpll_ck", ++ "tvdpll_445p5m", ++ "vencpll_d2", ++ "syspll_d3", ++ "univpll1_d2", ++ "univpll2_d2", ++ "syspll1_d2", ++ "univpll_d5", ++ "vcodecpll_370p5", ++ "dmpll_ck" ++}; ++ ++static const char * const dpi0_parents[] __initconst = { ++ "clk26m", ++ "tvdpll_d2", ++ "tvdpll_d4", ++ "clk26m", ++ "clk26m", ++ "tvdpll_d8", ++ "tvdpll_d16" ++}; ++ ++static const char * const irda_parents[] __initconst = { ++ "clk26m", ++ "univpll2_d4", ++ "syspll2_d4" ++}; ++ ++static const char * const cci400_parents[] __initconst = { ++ "clk26m", ++ "vencpll_ck", ++ "armca7pll_754m", ++ "armca7pll_502m", ++ "univpll_d2", ++ "syspll_d2", ++ "msdcpll_ck", ++ "dmpll_ck" ++}; ++ ++static const char * const aud_1_parents[] __initconst = { ++ "clk26m", ++ "apll1_ck", ++ "univpll2_d4", ++ "univpll2_d8" ++}; ++ ++static const char * const aud_2_parents[] __initconst = { ++ "clk26m", ++ "apll2_ck", ++ "univpll2_d4", ++ "univpll2_d8" ++}; ++ ++static const char * const mem_mfg_in_parents[] __initconst = { ++ "clk26m", ++ "mmpll_ck", ++ "dmpll_ck", ++ "clk26m" ++}; ++ ++static const char * const axi_mfg_in_parents[] __initconst = { ++ "clk26m", ++ "axi_sel", ++ "dmpll_d2" ++}; ++ ++static const char * const scam_parents[] __initconst = { ++ "clk26m", ++ "syspll3_d2", ++ "univpll2_d4", ++ "dmpll_d4" ++}; ++ ++static const char * const spinfi_ifr_parents[] __initconst = { ++ "clk26m", ++ "univpll2_d8", ++ "univpll3_d4", ++ "syspll4_d2", ++ "univpll2_d4", ++ "univpll3_d2", ++ "syspll1_d4", ++ "univpll1_d4" ++}; ++ ++static const char * const hdmi_parents[] __initconst = { ++ "clk26m", ++ "hdmitx_dig_cts", ++ "hdmitxpll_d2", ++ "hdmitxpll_d3" ++}; ++ ++static const char * const dpilvds_parents[] __initconst = { ++ "clk26m", ++ "lvdspll", ++ "lvdspll_d2", ++ "lvdspll_d4", ++ "lvdspll_d8", ++ "fpc_ck" ++}; ++ ++static const char * const msdc50_2_h_parents[] __initconst = { ++ "clk26m", ++ "syspll1_d2", ++ "syspll2_d2", ++ "syspll4_d2", ++ "univpll_d5", ++ "univpll1_d4" ++}; ++ ++static const char * const hdcp_parents[] __initconst = { ++ "clk26m", ++ "syspll4_d2", ++ "syspll3_d4", ++ "univpll2_d4" ++}; ++ ++static const char * const hdcp_24m_parents[] __initconst = { ++ "clk26m", ++ "univpll_d26", ++ "univpll_d52", ++ "univpll2_d8" ++}; ++ ++static const char * const rtc_parents[] __initconst = { ++ "clkrtc_int", ++ "clkrtc_ext", ++ "clk26m", ++ "univpll3_d8" ++}; ++ ++static const char * const i2s0_m_ck_parents[] __initconst = { ++ "apll1_div1", ++ "apll2_div1" ++}; ++ ++static const char * const i2s1_m_ck_parents[] __initconst = { ++ "apll1_div2", ++ "apll2_div2" ++}; ++ ++static const char * const i2s2_m_ck_parents[] __initconst = { ++ "apll1_div3", ++ "apll2_div3" ++}; ++ ++static const char * const i2s3_m_ck_parents[] __initconst = { ++ "apll1_div4", ++ "apll2_div4" ++}; ++ ++static const char * const i2s3_b_ck_parents[] __initconst = { ++ "apll1_div5", ++ "apll2_div5" ++}; ++ ++static const struct mtk_composite top_muxes[] __initconst = { ++ /* CLK_CFG_0 */ ++ MUX(CLK_TOP_AXI_SEL, "axi_sel", axi_parents, 0x0040, 0, 3), ++ MUX(CLK_TOP_MEM_SEL, "mem_sel", mem_parents, 0x0040, 8, 1), ++ MUX_GATE(CLK_TOP_DDRPHYCFG_SEL, "ddrphycfg_sel", ddrphycfg_parents, 0x0040, 16, 1, 23), ++ MUX_GATE(CLK_TOP_MM_SEL, "mm_sel", mm_parents, 0x0040, 24, 4, 31), ++ /* CLK_CFG_1 */ ++ MUX_GATE(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x0050, 0, 2, 7), ++ MUX_GATE(CLK_TOP_VDEC_SEL, "vdec_sel", vdec_parents, 0x0050, 8, 4, 15), ++ MUX_GATE(CLK_TOP_VENC_SEL, "venc_sel", venc_parents, 0x0050, 16, 4, 23), ++ MUX_GATE(CLK_TOP_MFG_SEL, "mfg_sel", mfg_parents, 0x0050, 24, 4, 31), ++ /* CLK_CFG_2 */ ++ MUX_GATE(CLK_TOP_CAMTG_SEL, "camtg_sel", camtg_parents, 0x0060, 0, 3, 7), ++ MUX_GATE(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x0060, 8, 1, 15), ++ MUX_GATE(CLK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x0060, 16, 3, 23), ++ MUX_GATE(CLK_TOP_USB20_SEL, "usb20_sel", usb20_parents, 0x0060, 24, 2, 31), ++ /* CLK_CFG_3 */ ++ MUX_GATE(CLK_TOP_USB30_SEL, "usb30_sel", usb30_parents, 0x0070, 0, 2, 7), ++ MUX_GATE(CLK_TOP_MSDC50_0_H_SEL, "msdc50_0_h_sel", msdc50_0_h_parents, 0x0070, 8, 3, 15), ++ MUX_GATE(CLK_TOP_MSDC50_0_SEL, "msdc50_0_sel", msdc50_0_parents, 0x0070, 16, 4, 23), ++ MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc30_1_sel", msdc30_1_parents, 0x0070, 24, 3, 31), ++ /* CLK_CFG_4 */ ++ MUX_GATE(CLK_TOP_MSDC30_2_SEL, "msdc30_2_sel", msdc30_2_parents, 0x0080, 0, 3, 7), ++ MUX_GATE(CLK_TOP_MSDC30_3_SEL, "msdc30_3_sel", msdc30_3_parents, 0x0080, 8, 4, 15), ++ MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel", audio_parents, 0x0080, 16, 2, 23), ++ MUX_GATE(CLK_TOP_AUD_INTBUS_SEL, "aud_intbus_sel", aud_intbus_parents, 0x0080, 24, 3, 31), ++ /* CLK_CFG_5 */ ++ MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmicspi_parents, 0x0090, 0, 3, 7 /* 7:5 */), ++ MUX_GATE(CLK_TOP_SCP_SEL, "scp_sel", scp_parents, 0x0090, 8, 3, 15), ++ MUX_GATE(CLK_TOP_ATB_SEL, "atb_sel", atb_parents, 0x0090, 16, 2, 23), ++ MUX_GATE(CLK_TOP_VENC_LT_SEL, "venclt_sel", venc_lt_parents, 0x0090, 24, 4, 31), ++ /* CLK_CFG_6 */ ++ MUX_GATE(CLK_TOP_DPI0_SEL, "dpi0_sel", dpi0_parents, 0x00a0, 0, 3, 7), ++ MUX_GATE(CLK_TOP_IRDA_SEL, "irda_sel", irda_parents, 0x00a0, 8, 2, 15), ++ MUX_GATE(CLK_TOP_CCI400_SEL, "cci400_sel", cci400_parents, 0x00a0, 16, 3, 23), ++ MUX_GATE(CLK_TOP_AUD_1_SEL, "aud_1_sel", aud_1_parents, 0x00a0, 24, 2, 31), ++ /* CLK_CFG_7 */ ++ MUX_GATE(CLK_TOP_AUD_2_SEL, "aud_2_sel", aud_2_parents, 0x00b0, 0, 2, 7), ++ MUX_GATE(CLK_TOP_MEM_MFG_IN_SEL, "mem_mfg_in_sel", mem_mfg_in_parents, 0x00b0, 8, 2, 15), ++ MUX_GATE(CLK_TOP_AXI_MFG_IN_SEL, "axi_mfg_in_sel", axi_mfg_in_parents, 0x00b0, 16, 2, 23), ++ MUX_GATE(CLK_TOP_SCAM_SEL, "scam_sel", scam_parents, 0x00b0, 24, 2, 31), ++ /* CLK_CFG_12 */ ++ MUX_GATE(CLK_TOP_SPINFI_IFR_SEL, "spinfi_ifr_sel", spinfi_ifr_parents, 0x00c0, 0, 3, 7), ++ MUX_GATE(CLK_TOP_HDMI_SEL, "hdmi_sel", hdmi_parents, 0x00c0, 8, 2, 15), ++ MUX_GATE(CLK_TOP_DPILVDS_SEL, "dpilvds_sel", dpilvds_parents, 0x00c0, 24, 3, 31), ++ /* CLK_CFG_13 */ ++ MUX_GATE(CLK_TOP_MSDC50_2_H_SEL, "msdc50_2_h_sel", msdc50_2_h_parents, 0x00d0, 0, 3, 7), ++ MUX_GATE(CLK_TOP_HDCP_SEL, "hdcp_sel", hdcp_parents, 0x00d0, 8, 2, 15), ++ MUX_GATE(CLK_TOP_HDCP_24M_SEL, "hdcp_24m_sel", hdcp_24m_parents, 0x00d0, 16, 2, 23), ++ MUX(CLK_TOP_RTC_SEL, "rtc_sel", rtc_parents, 0x00d0, 24, 2), ++ ++ DIV_GATE(CLK_TOP_APLL1_DIV0, "apll1_div0", "aud_1_sel", 0x12c, 8, 0x120, 4, 24), ++ DIV_GATE(CLK_TOP_APLL1_DIV1, "apll1_div1", "aud_1_sel", 0x12c, 9, 0x124, 8, 0), ++ DIV_GATE(CLK_TOP_APLL1_DIV2, "apll1_div2", "aud_1_sel", 0x12c, 10, 0x124, 8, 8), ++ DIV_GATE(CLK_TOP_APLL1_DIV3, "apll1_div3", "aud_1_sel", 0x12c, 11, 0x124, 8, 16), ++ DIV_GATE(CLK_TOP_APLL1_DIV4, "apll1_div4", "aud_1_sel", 0x12c, 12, 0x124, 8, 24), ++ DIV_GATE(CLK_TOP_APLL1_DIV5, "apll1_div5", "apll1_div4", 0x12c, 13, 0x12c, 4, 0), ++ ++ DIV_GATE(CLK_TOP_APLL2_DIV0, "apll2_div0", "aud_2_sel", 0x12c, 16, 0x120, 4, 28), ++ DIV_GATE(CLK_TOP_APLL2_DIV1, "apll2_div1", "aud_2_sel", 0x12c, 17, 0x128, 8, 0), ++ DIV_GATE(CLK_TOP_APLL2_DIV2, "apll2_div2", "aud_2_sel", 0x12c, 18, 0x128, 8, 8), ++ DIV_GATE(CLK_TOP_APLL2_DIV3, "apll2_div3", "aud_2_sel", 0x12c, 19, 0x128, 8, 16), ++ DIV_GATE(CLK_TOP_APLL2_DIV4, "apll2_div4", "aud_2_sel", 0x12c, 20, 0x128, 8, 24), ++ DIV_GATE(CLK_TOP_APLL2_DIV5, "apll2_div5", "apll2_div4", 0x12c, 21, 0x12c, 4, 4), ++ ++ MUX(CLK_TOP_I2S0_M_SEL, "i2s0_m_ck_sel", i2s0_m_ck_parents, 0x120, 4, 1), ++ MUX(CLK_TOP_I2S1_M_SEL, "i2s1_m_ck_sel", i2s1_m_ck_parents, 0x120, 5, 1), ++ MUX(CLK_TOP_I2S2_M_SEL, "i2s2_m_ck_sel", i2s2_m_ck_parents, 0x120, 6, 1), ++ MUX(CLK_TOP_I2S3_M_SEL, "i2s3_m_ck_sel", i2s3_m_ck_parents, 0x120, 7, 1), ++ MUX(CLK_TOP_I2S3_B_SEL, "i2s3_b_ck_sel", i2s3_b_ck_parents, 0x120, 8, 1), ++}; ++ ++static const struct mtk_gate_regs infra_cg_regs = { ++ .set_ofs = 0x0040, ++ .clr_ofs = 0x0044, ++ .sta_ofs = 0x0048, ++}; ++ ++#define GATE_ICG(_id, _name, _parent, _shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .regs = &infra_cg_regs, \ ++ .shift = _shift, \ ++ .ops = &mtk_clk_gate_ops_setclr, \ ++ } ++ ++static const struct mtk_gate infra_clks[] __initconst = { ++ GATE_ICG(CLK_INFRA_DBGCLK, "infra_dbgclk", "axi_sel", 0), ++ GATE_ICG(CLK_INFRA_SMI, "infra_smi", "mm_sel", 1), ++ GATE_ICG(CLK_INFRA_AUDIO, "infra_audio", "aud_intbus_sel", 5), ++ GATE_ICG(CLK_INFRA_GCE, "infra_gce", "axi_sel", 6), ++ GATE_ICG(CLK_INFRA_L2C_SRAM, "infra_l2c_sram", "axi_sel", 7), ++ GATE_ICG(CLK_INFRA_M4U, "infra_m4u", "mem_sel", 8), ++ GATE_ICG(CLK_INFRA_CPUM, "infra_cpum", "clk_null", 15), ++ GATE_ICG(CLK_INFRA_KP, "infra_kp", "axi_sel", 16), ++ GATE_ICG(CLK_INFRA_CEC, "infra_cec", "clk26m", 18), ++ GATE_ICG(CLK_INFRA_PMICSPI, "infra_pmicspi", "pmicspi_sel", 22), ++ GATE_ICG(CLK_INFRA_PMICWRAP, "infra_pmicwrap", "axi_sel", 23), ++}; ++ ++static const struct mtk_gate_regs peri0_cg_regs = { ++ .set_ofs = 0x0008, ++ .clr_ofs = 0x0010, ++ .sta_ofs = 0x0018, ++}; ++ ++static const struct mtk_gate_regs peri1_cg_regs = { ++ .set_ofs = 0x000c, ++ .clr_ofs = 0x0014, ++ .sta_ofs = 0x001c, ++}; ++ ++#define GATE_PERI0(_id, _name, _parent, _shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .regs = &peri0_cg_regs, \ ++ .shift = _shift, \ ++ .ops = &mtk_clk_gate_ops_setclr, \ ++ } ++ ++#define GATE_PERI1(_id, _name, _parent, _shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .regs = &peri1_cg_regs, \ ++ .shift = _shift, \ ++ .ops = &mtk_clk_gate_ops_setclr, \ ++ } ++ ++static const struct mtk_gate peri_gates[] __initconst = { ++ /* PERI0 */ ++ GATE_PERI0(CLK_PERI_NFI, "peri_nfi", "axi_sel", 0), ++ GATE_PERI0(CLK_PERI_THERM, "peri_therm", "axi_sel", 1), ++ GATE_PERI0(CLK_PERI_PWM1, "peri_pwm1", "axi_sel", 2), ++ GATE_PERI0(CLK_PERI_PWM2, "peri_pwm2", "axi_sel", 3), ++ GATE_PERI0(CLK_PERI_PWM3, "peri_pwm3", "axi_sel", 4), ++ GATE_PERI0(CLK_PERI_PWM4, "peri_pwm4", "axi_sel", 5), ++ GATE_PERI0(CLK_PERI_PWM5, "peri_pwm5", "axi_sel", 6), ++ GATE_PERI0(CLK_PERI_PWM6, "peri_pwm6", "axi_sel", 7), ++ GATE_PERI0(CLK_PERI_PWM7, "peri_pwm7", "axi_sel", 8), ++ GATE_PERI0(CLK_PERI_PWM, "peri_pwm", "axi_sel", 9), ++ GATE_PERI0(CLK_PERI_USB0, "peri_usb0", "usb20_sel", 10), ++ GATE_PERI0(CLK_PERI_USB1, "peri_usb1", "usb20_sel", 11), ++ GATE_PERI0(CLK_PERI_AP_DMA, "peri_ap_dma", "axi_sel", 12), ++ GATE_PERI0(CLK_PERI_MSDC30_0, "peri_msdc30_0", "msdc50_0_sel", 13), ++ GATE_PERI0(CLK_PERI_MSDC30_1, "peri_msdc30_1", "msdc30_1_sel", 14), ++ GATE_PERI0(CLK_PERI_MSDC30_2, "peri_msdc30_2", "msdc30_2_sel", 15), ++ GATE_PERI0(CLK_PERI_MSDC30_3, "peri_msdc30_3", "msdc30_3_sel", 16), ++ GATE_PERI0(CLK_PERI_NLI_ARB, "peri_nli_arb", "axi_sel", 17), ++ GATE_PERI0(CLK_PERI_IRDA, "peri_irda", "irda_sel", 18), ++ GATE_PERI0(CLK_PERI_UART0, "peri_uart0", "axi_sel", 19), ++ GATE_PERI0(CLK_PERI_UART1, "peri_uart1", "axi_sel", 20), ++ GATE_PERI0(CLK_PERI_UART2, "peri_uart2", "axi_sel", 21), ++ GATE_PERI0(CLK_PERI_UART3, "peri_uart3", "axi_sel", 22), ++ GATE_PERI0(CLK_PERI_I2C0, "peri_i2c0", "axi_sel", 23), ++ GATE_PERI0(CLK_PERI_I2C1, "peri_i2c1", "axi_sel", 24), ++ GATE_PERI0(CLK_PERI_I2C2, "peri_i2c2", "axi_sel", 25), ++ GATE_PERI0(CLK_PERI_I2C3, "peri_i2c3", "axi_sel", 26), ++ GATE_PERI0(CLK_PERI_I2C4, "peri_i2c4", "axi_sel", 27), ++ GATE_PERI0(CLK_PERI_AUXADC, "peri_auxadc", "clk26m", 28), ++ GATE_PERI0(CLK_PERI_SPI0, "peri_spi0", "spi_sel", 29), ++ GATE_PERI0(CLK_PERI_I2C5, "peri_i2c5", "axi_sel", 30), ++ GATE_PERI0(CLK_PERI_NFIECC, "peri_nfiecc", "axi_sel", 31), ++ /* PERI1 */ ++ GATE_PERI1(CLK_PERI_SPI, "peri_spi", "spi_sel", 0), ++ GATE_PERI1(CLK_PERI_IRRX, "peri_irrx", "spi_sel", 1), ++ GATE_PERI1(CLK_PERI_I2C6, "peri_i2c6", "axi_sel", 2), ++}; ++ ++static const char * const uart_ck_sel_parents[] __initconst = { ++ "clk26m", ++ "uart_sel", ++}; ++ ++static const struct mtk_composite peri_clks[] __initconst = { ++ MUX(CLK_PERI_UART0_SEL, "uart0_ck_sel", uart_ck_sel_parents, 0x40c, 0, 1), ++ MUX(CLK_PERI_UART1_SEL, "uart1_ck_sel", uart_ck_sel_parents, 0x40c, 1, 1), ++ MUX(CLK_PERI_UART2_SEL, "uart2_ck_sel", uart_ck_sel_parents, 0x40c, 2, 1), ++ MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents, 0x40c, 3, 1), ++}; ++ ++static void __init mtk_topckgen_init(struct device_node *node) ++{ ++ struct clk_onecell_data *clk_data; ++ void __iomem *base; ++ int r; ++ ++ base = of_iomap(node, 0); ++ if (!base) { ++ pr_err("%s(): ioremap failed\n", __func__); ++ return; ++ } ++ ++ clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); ++ ++ mtk_clk_register_factors(root_clk_alias, ARRAY_SIZE(root_clk_alias), clk_data); ++ mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data); ++ mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base, ++ &mt8173_clk_lock, clk_data); ++ ++ clk_prepare_enable(clk_data->clks[CLK_TOP_CCI400_SEL]); ++ ++ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); ++ if (r) ++ pr_err("%s(): could not register clock provider: %d\n", ++ __func__, r); ++} ++CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt8173-topckgen", mtk_topckgen_init); ++ ++static void __init mtk_infrasys_init(struct device_node *node) ++{ ++ struct clk_onecell_data *clk_data; ++ int r; ++ ++ clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK); ++ ++ mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks), ++ clk_data); ++ ++ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); ++ if (r) ++ pr_err("%s(): could not register clock provider: %d\n", ++ __func__, r); ++ ++ mtk_register_reset_controller(node, 2, 0x30); ++} ++CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt8173-infracfg", mtk_infrasys_init); ++ ++static void __init mtk_pericfg_init(struct device_node *node) ++{ ++ struct clk_onecell_data *clk_data; ++ int r; ++ void __iomem *base; ++ ++ base = of_iomap(node, 0); ++ if (!base) { ++ pr_err("%s(): ioremap failed\n", __func__); ++ return; ++ } ++ ++ clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK); ++ ++ mtk_clk_register_gates(node, peri_gates, ARRAY_SIZE(peri_gates), ++ clk_data); ++ mtk_clk_register_composites(peri_clks, ARRAY_SIZE(peri_clks), base, ++ &mt8173_clk_lock, clk_data); ++ ++ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); ++ if (r) ++ pr_err("%s(): could not register clock provider: %d\n", ++ __func__, r); ++ ++ mtk_register_reset_controller(node, 2, 0); ++} ++CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt8173-pericfg", mtk_pericfg_init); ++ ++#define MT8173_PLL_FMAX (3000UL * MHZ) ++ ++#define CON0_MT8173_RST_BAR BIT(24) ++ ++#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, _pd_shift, \ ++ _tuner_reg, _pcw_reg, _pcw_shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .reg = _reg, \ ++ .pwr_reg = _pwr_reg, \ ++ .en_mask = _en_mask, \ ++ .flags = _flags, \ ++ .rst_bar_mask = CON0_MT8173_RST_BAR, \ ++ .fmax = MT8173_PLL_FMAX, \ ++ .pcwbits = _pcwbits, \ ++ .pd_reg = _pd_reg, \ ++ .pd_shift = _pd_shift, \ ++ .tuner_reg = _tuner_reg, \ ++ .pcw_reg = _pcw_reg, \ ++ .pcw_shift = _pcw_shift, \ ++ } ++ ++static const struct mtk_pll_data plls[] = { ++ PLL(CLK_APMIXED_ARMCA15PLL, "armca15pll", 0x200, 0x20c, 0x00000001, 0, 21, 0x204, 24, 0x0, 0x204, 0), ++ PLL(CLK_APMIXED_ARMCA7PLL, "armca7pll", 0x210, 0x21c, 0x00000001, 0, 21, 0x214, 24, 0x0, 0x214, 0), ++ PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x220, 0x22c, 0xf0000101, HAVE_RST_BAR, 21, 0x220, 4, 0x0, 0x224, 0), ++ PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x230, 0x23c, 0xfe000001, HAVE_RST_BAR, 7, 0x230, 4, 0x0, 0x234, 14), ++ PLL(CLK_APMIXED_MMPLL, "mmpll", 0x240, 0x24c, 0x00000001, 0, 21, 0x244, 24, 0x0, 0x244, 0), ++ PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x250, 0x25c, 0x00000001, 0, 21, 0x250, 4, 0x0, 0x254, 0), ++ PLL(CLK_APMIXED_VENCPLL, "vencpll", 0x260, 0x26c, 0x00000001, 0, 21, 0x260, 4, 0x0, 0x264, 0), ++ PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x270, 0x27c, 0x00000001, 0, 21, 0x270, 4, 0x0, 0x274, 0), ++ PLL(CLK_APMIXED_MPLL, "mpll", 0x280, 0x28c, 0x00000001, 0, 21, 0x280, 4, 0x0, 0x284, 0), ++ PLL(CLK_APMIXED_VCODECPLL, "vcodecpll", 0x290, 0x29c, 0x00000001, 0, 21, 0x290, 4, 0x0, 0x294, 0), ++ PLL(CLK_APMIXED_APLL1, "apll1", 0x2a0, 0x2b0, 0x00000001, 0, 31, 0x2a0, 4, 0x2a4, 0x2a4, 0), ++ PLL(CLK_APMIXED_APLL2, "apll2", 0x2b4, 0x2c4, 0x00000001, 0, 31, 0x2b4, 4, 0x2b8, 0x2b8, 0), ++ PLL(CLK_APMIXED_LVDSPLL, "lvdspll", 0x2d0, 0x2dc, 0x00000001, 0, 21, 0x2d0, 4, 0x0, 0x2d4, 0), ++ PLL(CLK_APMIXED_MSDCPLL2, "msdcpll2", 0x2f0, 0x2fc, 0x00000001, 0, 21, 0x2f0, 4, 0x0, 0x2f4, 0), ++}; ++ ++static void __init mtk_apmixedsys_init(struct device_node *node) ++{ ++ struct clk_onecell_data *clk_data; ++ ++ clk_data = mtk_alloc_clk_data(ARRAY_SIZE(plls)); ++ if (!clk_data) ++ return; ++ ++ mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); ++ ++ clk_prepare_enable(clk_data->clks[CLK_APMIXED_ARMCA15PLL]); ++} ++CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt8173-apmixedsys", ++ mtk_apmixedsys_init); +diff --git a/include/dt-bindings/clock/mt8173-clk.h b/include/dt-bindings/clock/mt8173-clk.h +new file mode 100644 +index 0000000..4ad76ed +--- /dev/null ++++ b/include/dt-bindings/clock/mt8173-clk.h +@@ -0,0 +1,235 @@ ++/* ++ * Copyright (c) 2014 MediaTek Inc. ++ * Author: James Liao <jamesjj.liao@mediatek.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _DT_BINDINGS_CLK_MT8173_H ++#define _DT_BINDINGS_CLK_MT8173_H ++ ++/* TOPCKGEN */ ++ ++#define CLK_TOP_CLKPH_MCK_O 1 ++#define CLK_TOP_DPI 2 ++#define CLK_TOP_USB_SYSPLL_125M 3 ++#define CLK_TOP_HDMITX_DIG_CTS 4 ++#define CLK_TOP_ARMCA7PLL_754M 5 ++#define CLK_TOP_ARMCA7PLL_502M 6 ++#define CLK_TOP_MAIN_H546M 7 ++#define CLK_TOP_MAIN_H364M 8 ++#define CLK_TOP_MAIN_H218P4M 9 ++#define CLK_TOP_MAIN_H156M 10 ++#define CLK_TOP_TVDPLL_445P5M 11 ++#define CLK_TOP_TVDPLL_594M 12 ++#define CLK_TOP_UNIV_624M 13 ++#define CLK_TOP_UNIV_416M 14 ++#define CLK_TOP_UNIV_249P6M 15 ++#define CLK_TOP_UNIV_178P3M 16 ++#define CLK_TOP_UNIV_48M 17 ++#define CLK_TOP_CLKRTC_EXT 18 ++#define CLK_TOP_CLKRTC_INT 19 ++#define CLK_TOP_FPC 20 ++#define CLK_TOP_HDMITXPLL_D2 21 ++#define CLK_TOP_HDMITXPLL_D3 22 ++#define CLK_TOP_ARMCA7PLL_D2 23 ++#define CLK_TOP_ARMCA7PLL_D3 24 ++#define CLK_TOP_APLL1 25 ++#define CLK_TOP_APLL2 26 ++#define CLK_TOP_DMPLL 27 ++#define CLK_TOP_DMPLL_D2 28 ++#define CLK_TOP_DMPLL_D4 29 ++#define CLK_TOP_DMPLL_D8 30 ++#define CLK_TOP_DMPLL_D16 31 ++#define CLK_TOP_LVDSPLL_D2 32 ++#define CLK_TOP_LVDSPLL_D4 33 ++#define CLK_TOP_LVDSPLL_D8 34 ++#define CLK_TOP_MMPLL 35 ++#define CLK_TOP_MMPLL_D2 36 ++#define CLK_TOP_MSDCPLL 37 ++#define CLK_TOP_MSDCPLL_D2 38 ++#define CLK_TOP_MSDCPLL_D4 39 ++#define CLK_TOP_MSDCPLL2 40 ++#define CLK_TOP_MSDCPLL2_D2 41 ++#define CLK_TOP_MSDCPLL2_D4 42 ++#define CLK_TOP_SYSPLL_D2 43 ++#define CLK_TOP_SYSPLL1_D2 44 ++#define CLK_TOP_SYSPLL1_D4 45 ++#define CLK_TOP_SYSPLL1_D8 46 ++#define CLK_TOP_SYSPLL1_D16 47 ++#define CLK_TOP_SYSPLL_D3 48 ++#define CLK_TOP_SYSPLL2_D2 49 ++#define CLK_TOP_SYSPLL2_D4 50 ++#define CLK_TOP_SYSPLL_D5 51 ++#define CLK_TOP_SYSPLL3_D2 52 ++#define CLK_TOP_SYSPLL3_D4 53 ++#define CLK_TOP_SYSPLL_D7 54 ++#define CLK_TOP_SYSPLL4_D2 55 ++#define CLK_TOP_SYSPLL4_D4 56 ++#define CLK_TOP_TVDPLL 57 ++#define CLK_TOP_TVDPLL_D2 58 ++#define CLK_TOP_TVDPLL_D4 59 ++#define CLK_TOP_TVDPLL_D8 60 ++#define CLK_TOP_TVDPLL_D16 61 ++#define CLK_TOP_UNIVPLL_D2 62 ++#define CLK_TOP_UNIVPLL1_D2 63 ++#define CLK_TOP_UNIVPLL1_D4 64 ++#define CLK_TOP_UNIVPLL1_D8 65 ++#define CLK_TOP_UNIVPLL_D3 66 ++#define CLK_TOP_UNIVPLL2_D2 67 ++#define CLK_TOP_UNIVPLL2_D4 68 ++#define CLK_TOP_UNIVPLL2_D8 69 ++#define CLK_TOP_UNIVPLL_D5 70 ++#define CLK_TOP_UNIVPLL3_D2 71 ++#define CLK_TOP_UNIVPLL3_D4 72 ++#define CLK_TOP_UNIVPLL3_D8 73 ++#define CLK_TOP_UNIVPLL_D7 74 ++#define CLK_TOP_UNIVPLL_D26 75 ++#define CLK_TOP_UNIVPLL_D52 76 ++#define CLK_TOP_VCODECPLL 77 ++#define CLK_TOP_VCODECPLL_370P5 78 ++#define CLK_TOP_VENCPLL 79 ++#define CLK_TOP_VENCPLL_D2 80 ++#define CLK_TOP_VENCPLL_D4 81 ++#define CLK_TOP_AXI_SEL 82 ++#define CLK_TOP_MEM_SEL 83 ++#define CLK_TOP_DDRPHYCFG_SEL 84 ++#define CLK_TOP_MM_SEL 85 ++#define CLK_TOP_PWM_SEL 86 ++#define CLK_TOP_VDEC_SEL 87 ++#define CLK_TOP_VENC_SEL 88 ++#define CLK_TOP_MFG_SEL 89 ++#define CLK_TOP_CAMTG_SEL 90 ++#define CLK_TOP_UART_SEL 91 ++#define CLK_TOP_SPI_SEL 92 ++#define CLK_TOP_USB20_SEL 93 ++#define CLK_TOP_USB30_SEL 94 ++#define CLK_TOP_MSDC50_0_H_SEL 95 ++#define CLK_TOP_MSDC50_0_SEL 96 ++#define CLK_TOP_MSDC30_1_SEL 97 ++#define CLK_TOP_MSDC30_2_SEL 98 ++#define CLK_TOP_MSDC30_3_SEL 99 ++#define CLK_TOP_AUDIO_SEL 100 ++#define CLK_TOP_AUD_INTBUS_SEL 101 ++#define CLK_TOP_PMICSPI_SEL 102 ++#define CLK_TOP_SCP_SEL 103 ++#define CLK_TOP_ATB_SEL 104 ++#define CLK_TOP_VENC_LT_SEL 105 ++#define CLK_TOP_DPI0_SEL 106 ++#define CLK_TOP_IRDA_SEL 107 ++#define CLK_TOP_CCI400_SEL 108 ++#define CLK_TOP_AUD_1_SEL 109 ++#define CLK_TOP_AUD_2_SEL 110 ++#define CLK_TOP_MEM_MFG_IN_SEL 111 ++#define CLK_TOP_AXI_MFG_IN_SEL 112 ++#define CLK_TOP_SCAM_SEL 113 ++#define CLK_TOP_SPINFI_IFR_SEL 114 ++#define CLK_TOP_HDMI_SEL 115 ++#define CLK_TOP_DPILVDS_SEL 116 ++#define CLK_TOP_MSDC50_2_H_SEL 117 ++#define CLK_TOP_HDCP_SEL 118 ++#define CLK_TOP_HDCP_24M_SEL 119 ++#define CLK_TOP_RTC_SEL 120 ++#define CLK_TOP_APLL1_DIV0 121 ++#define CLK_TOP_APLL1_DIV1 122 ++#define CLK_TOP_APLL1_DIV2 123 ++#define CLK_TOP_APLL1_DIV3 124 ++#define CLK_TOP_APLL1_DIV4 125 ++#define CLK_TOP_APLL1_DIV5 126 ++#define CLK_TOP_APLL2_DIV0 127 ++#define CLK_TOP_APLL2_DIV1 128 ++#define CLK_TOP_APLL2_DIV2 129 ++#define CLK_TOP_APLL2_DIV3 130 ++#define CLK_TOP_APLL2_DIV4 131 ++#define CLK_TOP_APLL2_DIV5 132 ++#define CLK_TOP_I2S0_M_SEL 133 ++#define CLK_TOP_I2S1_M_SEL 134 ++#define CLK_TOP_I2S2_M_SEL 135 ++#define CLK_TOP_I2S3_M_SEL 136 ++#define CLK_TOP_I2S3_B_SEL 137 ++#define CLK_TOP_NR_CLK 138 ++ ++/* APMIXED_SYS */ ++ ++#define CLK_APMIXED_ARMCA15PLL 1 ++#define CLK_APMIXED_ARMCA7PLL 2 ++#define CLK_APMIXED_MAINPLL 3 ++#define CLK_APMIXED_UNIVPLL 4 ++#define CLK_APMIXED_MMPLL 5 ++#define CLK_APMIXED_MSDCPLL 6 ++#define CLK_APMIXED_VENCPLL 7 ++#define CLK_APMIXED_TVDPLL 8 ++#define CLK_APMIXED_MPLL 9 ++#define CLK_APMIXED_VCODECPLL 10 ++#define CLK_APMIXED_APLL1 11 ++#define CLK_APMIXED_APLL2 12 ++#define CLK_APMIXED_LVDSPLL 13 ++#define CLK_APMIXED_MSDCPLL2 14 ++#define CLK_APMIXED_NR_CLK 15 ++ ++/* INFRA_SYS */ ++ ++#define CLK_INFRA_DBGCLK 1 ++#define CLK_INFRA_SMI 2 ++#define CLK_INFRA_AUDIO 3 ++#define CLK_INFRA_GCE 4 ++#define CLK_INFRA_L2C_SRAM 5 ++#define CLK_INFRA_M4U 6 ++#define CLK_INFRA_CPUM 7 ++#define CLK_INFRA_KP 8 ++#define CLK_INFRA_CEC 9 ++#define CLK_INFRA_PMICSPI 10 ++#define CLK_INFRA_PMICWRAP 11 ++#define CLK_INFRA_NR_CLK 12 ++ ++/* PERI_SYS */ ++ ++#define CLK_PERI_NFI 1 ++#define CLK_PERI_THERM 2 ++#define CLK_PERI_PWM1 3 ++#define CLK_PERI_PWM2 4 ++#define CLK_PERI_PWM3 5 ++#define CLK_PERI_PWM4 6 ++#define CLK_PERI_PWM5 7 ++#define CLK_PERI_PWM6 8 ++#define CLK_PERI_PWM7 9 ++#define CLK_PERI_PWM 10 ++#define CLK_PERI_USB0 11 ++#define CLK_PERI_USB1 12 ++#define CLK_PERI_AP_DMA 13 ++#define CLK_PERI_MSDC30_0 14 ++#define CLK_PERI_MSDC30_1 15 ++#define CLK_PERI_MSDC30_2 16 ++#define CLK_PERI_MSDC30_3 17 ++#define CLK_PERI_NLI_ARB 18 ++#define CLK_PERI_IRDA 19 ++#define CLK_PERI_UART0 20 ++#define CLK_PERI_UART1 21 ++#define CLK_PERI_UART2 22 ++#define CLK_PERI_UART3 23 ++#define CLK_PERI_I2C0 24 ++#define CLK_PERI_I2C1 25 ++#define CLK_PERI_I2C2 26 ++#define CLK_PERI_I2C3 27 ++#define CLK_PERI_I2C4 28 ++#define CLK_PERI_AUXADC 29 ++#define CLK_PERI_SPI0 30 ++#define CLK_PERI_I2C5 31 ++#define CLK_PERI_NFIECC 32 ++#define CLK_PERI_SPI 33 ++#define CLK_PERI_IRRX 34 ++#define CLK_PERI_I2C6 35 ++#define CLK_PERI_UART0_SEL 36 ++#define CLK_PERI_UART1_SEL 37 ++#define CLK_PERI_UART2_SEL 38 ++#define CLK_PERI_UART3_SEL 39 ++#define CLK_PERI_NR_CLK 40 ++ ++#endif /* _DT_BINDINGS_CLK_MT8173_H */ +diff --git a/include/dt-bindings/reset-controller/mt8173-resets.h b/include/dt-bindings/reset-controller/mt8173-resets.h +new file mode 100644 +index 0000000..9464b37 +--- /dev/null ++++ b/include/dt-bindings/reset-controller/mt8173-resets.h +@@ -0,0 +1,63 @@ ++/* ++ * Copyright (c) 2014 MediaTek Inc. ++ * Author: Flora Fu, MediaTek ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT8173 ++#define _DT_BINDINGS_RESET_CONTROLLER_MT8173 ++ ++/* INFRACFG resets */ ++#define MT8173_INFRA_EMI_REG_RST 0 ++#define MT8173_INFRA_DRAMC0_A0_RST 1 ++#define MT8173_INFRA_APCIRQ_EINT_RST 3 ++#define MT8173_INFRA_APXGPT_RST 4 ++#define MT8173_INFRA_SCPSYS_RST 5 ++#define MT8173_INFRA_KP_RST 6 ++#define MT8173_INFRA_PMIC_WRAP_RST 7 ++#define MT8173_INFRA_MPIP_RST 8 ++#define MT8173_INFRA_CEC_RST 9 ++#define MT8173_INFRA_EMI_RST 32 ++#define MT8173_INFRA_DRAMC0_RST 34 ++#define MT8173_INFRA_APMIXEDSYS_RST 35 ++#define MT8173_INFRA_MIPI_DSI_RST 36 ++#define MT8173_INFRA_TRNG_RST 37 ++#define MT8173_INFRA_SYSIRQ_RST 38 ++#define MT8173_INFRA_MIPI_CSI_RST 39 ++#define MT8173_INFRA_GCE_FAXI_RST 40 ++#define MT8173_INFRA_MMIOMMURST 47 ++ ++ ++/* PERICFG resets */ ++#define MT8173_PERI_UART0_SW_RST 0 ++#define MT8173_PERI_UART1_SW_RST 1 ++#define MT8173_PERI_UART2_SW_RST 2 ++#define MT8173_PERI_UART3_SW_RST 3 ++#define MT8173_PERI_IRRX_SW_RST 4 ++#define MT8173_PERI_PWM_SW_RST 8 ++#define MT8173_PERI_AUXADC_SW_RST 10 ++#define MT8173_PERI_DMA_SW_RST 11 ++#define MT8173_PERI_I2C6_SW_RST 13 ++#define MT8173_PERI_NFI_SW_RST 14 ++#define MT8173_PERI_THERM_SW_RST 16 ++#define MT8173_PERI_MSDC2_SW_RST 17 ++#define MT8173_PERI_MSDC3_SW_RST 18 ++#define MT8173_PERI_MSDC0_SW_RST 19 ++#define MT8173_PERI_MSDC1_SW_RST 20 ++#define MT8173_PERI_I2C0_SW_RST 22 ++#define MT8173_PERI_I2C1_SW_RST 23 ++#define MT8173_PERI_I2C2_SW_RST 24 ++#define MT8173_PERI_I2C3_SW_RST 25 ++#define MT8173_PERI_I2C4_SW_RST 26 ++#define MT8173_PERI_HDMI_SW_RST 29 ++#define MT8173_PERI_SPI0_SW_RST 33 ++ ++#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT8173 */ +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0006-soc-mediatek-Add-infracfg-misc-driver-support.patch b/target/linux/mediatek/patches/0006-soc-mediatek-Add-infracfg-misc-driver-support.patch new file mode 100644 index 0000000000..f47c19373e --- /dev/null +++ b/target/linux/mediatek/patches/0006-soc-mediatek-Add-infracfg-misc-driver-support.patch @@ -0,0 +1,179 @@ +From d6d7a7dc1b7db2e3d496bf67b30abc894edbc4bd Mon Sep 17 00:00:00 2001 +From: Sascha Hauer <s.hauer@pengutronix.de> +Date: Tue, 9 Jun 2015 10:46:59 +0200 +Subject: [PATCH 06/76] soc: mediatek: Add infracfg misc driver support + +This adds support for some miscellaneous bits of the infracfg controller. +The mtk_infracfg_set/clear_bus_protection functions are necessary for +the scpsys power domain driver to handle the bus protection bits which +are contained in the infacfg register space. + +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +--- + drivers/soc/mediatek/Kconfig | 9 ++++ + drivers/soc/mediatek/Makefile | 1 + + drivers/soc/mediatek/mtk-infracfg.c | 91 +++++++++++++++++++++++++++++++++ + include/linux/soc/mediatek/infracfg.h | 26 ++++++++++ + 4 files changed, 127 insertions(+) + create mode 100644 drivers/soc/mediatek/mtk-infracfg.c + create mode 100644 include/linux/soc/mediatek/infracfg.h + +diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig +index 3c18503..09da41e 100644 +--- a/drivers/soc/mediatek/Kconfig ++++ b/drivers/soc/mediatek/Kconfig +@@ -1,6 +1,15 @@ + # + # MediaTek SoC drivers + # ++config MTK_INFRACFG ++ bool "MediaTek INFRACFG Support" ++ depends on ARCH_MEDIATEK ++ select REGMAP ++ help ++ Say yes here to add support for the MediaTek INFRACFG controller. The ++ INFRACFG controller contains various infrastructure registers not ++ directly associated to any device. ++ + config MTK_PMIC_WRAP + tristate "MediaTek PMIC Wrapper Support" + depends on ARCH_MEDIATEK +diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile +index ecaf4de..3fa940f 100644 +--- a/drivers/soc/mediatek/Makefile ++++ b/drivers/soc/mediatek/Makefile +@@ -1 +1,2 @@ ++obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o + obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o +diff --git a/drivers/soc/mediatek/mtk-infracfg.c b/drivers/soc/mediatek/mtk-infracfg.c +new file mode 100644 +index 0000000..ca786e0 +--- /dev/null ++++ b/drivers/soc/mediatek/mtk-infracfg.c +@@ -0,0 +1,91 @@ ++/* ++ * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/export.h> ++#include <linux/jiffies.h> ++#include <linux/regmap.h> ++#include <linux/soc/mediatek/infracfg.h> ++#include <asm/processor.h> ++ ++#define INFRA_TOPAXI_PROTECTEN 0x0220 ++#define INFRA_TOPAXI_PROTECTSTA1 0x0228 ++ ++/** ++ * mtk_infracfg_set_bus_protection - enable bus protection ++ * @regmap: The infracfg regmap ++ * @mask: The mask containing the protection bits to be enabled. ++ * ++ * This function enables the bus protection bits for disabled power ++ * domains so that the system does not hanf when some unit accesses the ++ * bus while in power down. ++ */ ++int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask) ++{ ++ unsigned long expired; ++ u32 val; ++ int ret; ++ ++ regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, mask); ++ ++ expired = jiffies + HZ; ++ ++ while (1) { ++ ret = regmap_read(infracfg, INFRA_TOPAXI_PROTECTSTA1, &val); ++ if (ret) ++ return ret; ++ ++ if ((val & mask) == mask) ++ break; ++ ++ cpu_relax(); ++ if (time_after(jiffies, expired)) ++ return -EIO; ++ } ++ ++ return 0; ++} ++ ++/** ++ * mtk_infracfg_clear_bus_protection - disable bus protection ++ * @regmap: The infracfg regmap ++ * @mask: The mask containing the protection bits to be disabled. ++ * ++ * This function disables the bus protection bits previously enabled with ++ * mtk_infracfg_set_bus_protection. ++ */ ++int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask) ++{ ++ unsigned long expired; ++ int ret; ++ ++ regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0); ++ ++ expired = jiffies + HZ; ++ ++ while (1) { ++ u32 val; ++ ++ ret = regmap_read(infracfg, INFRA_TOPAXI_PROTECTSTA1, &val); ++ if (ret) ++ return ret; ++ ++ if (!(val & mask)) ++ break; ++ ++ cpu_relax(); ++ if (time_after(jiffies, expired)) ++ return -EIO; ++ } ++ ++ return 0; ++} +diff --git a/include/linux/soc/mediatek/infracfg.h b/include/linux/soc/mediatek/infracfg.h +new file mode 100644 +index 0000000..a5714e9 +--- /dev/null ++++ b/include/linux/soc/mediatek/infracfg.h +@@ -0,0 +1,26 @@ ++#ifndef __SOC_MEDIATEK_INFRACFG_H ++#define __SOC_MEDIATEK_INFRACFG_H ++ ++#define MT8173_TOP_AXI_PROT_EN_MCI_M2 BIT(0) ++#define MT8173_TOP_AXI_PROT_EN_MM_M0 BIT(1) ++#define MT8173_TOP_AXI_PROT_EN_MM_M1 BIT(2) ++#define MT8173_TOP_AXI_PROT_EN_MMAPB_S BIT(6) ++#define MT8173_TOP_AXI_PROT_EN_L2C_M2 BIT(9) ++#define MT8173_TOP_AXI_PROT_EN_L2SS_SMI BIT(11) ++#define MT8173_TOP_AXI_PROT_EN_L2SS_ADD BIT(12) ++#define MT8173_TOP_AXI_PROT_EN_CCI_M2 BIT(13) ++#define MT8173_TOP_AXI_PROT_EN_MFG_S BIT(14) ++#define MT8173_TOP_AXI_PROT_EN_PERI_M0 BIT(15) ++#define MT8173_TOP_AXI_PROT_EN_PERI_M1 BIT(16) ++#define MT8173_TOP_AXI_PROT_EN_DEBUGSYS BIT(17) ++#define MT8173_TOP_AXI_PROT_EN_CQ_DMA BIT(18) ++#define MT8173_TOP_AXI_PROT_EN_GCPU BIT(19) ++#define MT8173_TOP_AXI_PROT_EN_IOMMU BIT(20) ++#define MT8173_TOP_AXI_PROT_EN_MFG_M0 BIT(21) ++#define MT8173_TOP_AXI_PROT_EN_MFG_M1 BIT(22) ++#define MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT BIT(23) ++ ++int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask); ++int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask); ++ ++#endif /* __SOC_MEDIATEK_INFRACFG_H */ +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0007-dt-bindings-soc-Add-documentation-for-the-MediaTek-S.patch b/target/linux/mediatek/patches/0007-dt-bindings-soc-Add-documentation-for-the-MediaTek-S.patch new file mode 100644 index 0000000000..f7bdbd6e0c --- /dev/null +++ b/target/linux/mediatek/patches/0007-dt-bindings-soc-Add-documentation-for-the-MediaTek-S.patch @@ -0,0 +1,57 @@ +From 06a1fd8a198771abc7c5badcf43a49a715ba4c76 Mon Sep 17 00:00:00 2001 +From: Sascha Hauer <s.hauer@pengutronix.de> +Date: Tue, 9 Jun 2015 10:47:00 +0200 +Subject: [PATCH 07/76] dt-bindings: soc: Add documentation for the MediaTek + SCPSYS unit + +This adds documentation for the MediaTek SCPSYS unit found in MT8173 SoCs. + +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +--- + .../devicetree/bindings/soc/mediatek/scpsys.txt | 34 ++++++++++++++++++++ + 1 file changed, 34 insertions(+) + create mode 100644 Documentation/devicetree/bindings/soc/mediatek/scpsys.txt + +diff --git a/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt +new file mode 100644 +index 0000000..87f2091 +--- /dev/null ++++ b/Documentation/devicetree/bindings/soc/mediatek/scpsys.txt +@@ -0,0 +1,34 @@ ++MediaTek SCPSYS ++=============== ++ ++The System Control Processor System (SCPSYS) has several power management ++related tasks in the system. The tasks include thermal measurement, dynamic ++voltage frequency scaling (DVFS), interrupt filter and lowlevel sleep control. ++The System Power Manager (SPM) inside the SCPSYS is for the MTCMOS power ++domain control. ++ ++The driver implements the Generic PM domain bindings described in ++power/power_domain.txt. It provides the power domains defined in ++include/dt-bindings/power/mt8173-power.h. ++ ++Required properties: ++- compatible: Must be "mediatek,mt8173-scpsys" ++- #power-domain-cells: Must be 1 ++- reg: Address range of the SCPSYS unit ++- infracfg: must contain a phandle to the infracfg controller ++ ++Example: ++ ++ scpsys: scpsys@10006000 { ++ #power-domain-cells = <1>; ++ compatible = "mediatek,mt8173-scpsys"; ++ reg = <0 0x10006000 0 0x1000>; ++ infracfg = <&infracfg>; ++ }; ++ ++Example consumer: ++ ++ afe: mt8173-afe-pcm@11220000 { ++ compatible = "mediatek,mt8173-afe-pcm"; ++ power-domains = <&scpsys MT8173_POWER_DOMAIN_AUDIO>; ++ }; +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0008-soc-Mediatek-Add-SCPSYS-power-domain-driver.patch b/target/linux/mediatek/patches/0008-soc-Mediatek-Add-SCPSYS-power-domain-driver.patch new file mode 100644 index 0000000000..bbf5ad135e --- /dev/null +++ b/target/linux/mediatek/patches/0008-soc-Mediatek-Add-SCPSYS-power-domain-driver.patch @@ -0,0 +1,573 @@ +From 04e2e2a895a95dc9e75403c2e8ea190dce9dc387 Mon Sep 17 00:00:00 2001 +From: Sascha Hauer <s.hauer@pengutronix.de> +Date: Tue, 9 Jun 2015 10:47:01 +0200 +Subject: [PATCH 08/76] soc: Mediatek: Add SCPSYS power domain driver + +This adds a power domain driver for the Mediatek SCPSYS unit. + +The System Control Processor System (SCPSYS) has several power +management related tasks in the system. The tasks include thermal +measurement, dynamic voltage frequency scaling (DVFS), interrupt +filter and lowlevel sleep control. The System Power Manager (SPM) +inside the SCPSYS is for the MTCMOS power domain control. + +For now this driver only adds power domain support, the more +advanced features are not yet supported. The driver implements +the generic PM domain device tree bindings, the first user will +most likely be the Mediatek AFE audio driver. + +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +--- + drivers/soc/mediatek/Kconfig | 9 + + drivers/soc/mediatek/Makefile | 1 + + drivers/soc/mediatek/mtk-scpsys.c | 490 ++++++++++++++++++++++++++++++ + include/dt-bindings/power/mt8173-power.h | 15 + + 4 files changed, 515 insertions(+) + create mode 100644 drivers/soc/mediatek/mtk-scpsys.c + create mode 100644 include/dt-bindings/power/mt8173-power.h + +diff --git a/drivers/soc/mediatek/Kconfig b/drivers/soc/mediatek/Kconfig +index 09da41e..2dc5d90 100644 +--- a/drivers/soc/mediatek/Kconfig ++++ b/drivers/soc/mediatek/Kconfig +@@ -19,3 +19,12 @@ config MTK_PMIC_WRAP + Say yes here to add support for MediaTek PMIC Wrapper found + on different MediaTek SoCs. The PMIC wrapper is a proprietary + hardware to connect the PMIC. ++ ++config MTK_SCPSYS ++ bool "MediaTek SCPSYS Support" ++ depends on ARCH_MEDIATEK || COMPILE_TEST ++ select REGMAP ++ select MTK_INFRACFG ++ help ++ Say yes here to add support for the MediaTek SCPSYS power domain ++ driver. +diff --git a/drivers/soc/mediatek/Makefile b/drivers/soc/mediatek/Makefile +index 3fa940f..12998b0 100644 +--- a/drivers/soc/mediatek/Makefile ++++ b/drivers/soc/mediatek/Makefile +@@ -1,2 +1,3 @@ + obj-$(CONFIG_MTK_INFRACFG) += mtk-infracfg.o + obj-$(CONFIG_MTK_PMIC_WRAP) += mtk-pmic-wrap.o ++obj-$(CONFIG_MTK_SCPSYS) += mtk-scpsys.o +diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c +new file mode 100644 +index 0000000..b9eed37 +--- /dev/null ++++ b/drivers/soc/mediatek/mtk-scpsys.c +@@ -0,0 +1,490 @@ ++/* ++ * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++#include <linux/clk.h> ++#include <linux/delay.h> ++#include <linux/io.h> ++#include <linux/kernel.h> ++#include <linux/mfd/syscon.h> ++#include <linux/of_device.h> ++#include <linux/platform_device.h> ++#include <linux/pm_domain.h> ++#include <linux/regmap.h> ++#include <linux/soc/mediatek/infracfg.h> ++#include <dt-bindings/power/mt8173-power.h> ++ ++#define SPM_VDE_PWR_CON 0x0210 ++#define SPM_MFG_PWR_CON 0x0214 ++#define SPM_VEN_PWR_CON 0x0230 ++#define SPM_ISP_PWR_CON 0x0238 ++#define SPM_DIS_PWR_CON 0x023c ++#define SPM_VEN2_PWR_CON 0x0298 ++#define SPM_AUDIO_PWR_CON 0x029c ++#define SPM_MFG_2D_PWR_CON 0x02c0 ++#define SPM_MFG_ASYNC_PWR_CON 0x02c4 ++#define SPM_USB_PWR_CON 0x02cc ++#define SPM_PWR_STATUS 0x060c ++#define SPM_PWR_STATUS_2ND 0x0610 ++ ++#define PWR_RST_B_BIT BIT(0) ++#define PWR_ISO_BIT BIT(1) ++#define PWR_ON_BIT BIT(2) ++#define PWR_ON_2ND_BIT BIT(3) ++#define PWR_CLK_DIS_BIT BIT(4) ++ ++#define PWR_STATUS_DISP BIT(3) ++#define PWR_STATUS_MFG BIT(4) ++#define PWR_STATUS_ISP BIT(5) ++#define PWR_STATUS_VDEC BIT(7) ++#define PWR_STATUS_VENC_LT BIT(20) ++#define PWR_STATUS_VENC BIT(21) ++#define PWR_STATUS_MFG_2D BIT(22) ++#define PWR_STATUS_MFG_ASYNC BIT(23) ++#define PWR_STATUS_AUDIO BIT(24) ++#define PWR_STATUS_USB BIT(25) ++ ++enum clk_id { ++ MT8173_CLK_NONE, ++ MT8173_CLK_MM, ++ MT8173_CLK_MFG, ++ MT8173_CLK_MAX = MT8173_CLK_MFG, ++}; ++ ++struct scp_domain_data { ++ const char *name; ++ u32 sta_mask; ++ int ctl_offs; ++ u32 sram_pdn_bits; ++ u32 sram_pdn_ack_bits; ++ u32 bus_prot_mask; ++ enum clk_id clk_id; ++}; ++ ++static const struct scp_domain_data scp_domain_data[] __initconst = { ++ [MT8173_POWER_DOMAIN_VDEC] = { ++ .name = "vdec", ++ .sta_mask = PWR_STATUS_VDEC, ++ .ctl_offs = SPM_VDE_PWR_CON, ++ .sram_pdn_bits = GENMASK(11, 8), ++ .sram_pdn_ack_bits = GENMASK(12, 12), ++ .clk_id = MT8173_CLK_MM, ++ }, ++ [MT8173_POWER_DOMAIN_VENC] = { ++ .name = "venc", ++ .sta_mask = PWR_STATUS_VENC, ++ .ctl_offs = SPM_VEN_PWR_CON, ++ .sram_pdn_bits = GENMASK(11, 8), ++ .sram_pdn_ack_bits = GENMASK(15, 12), ++ .clk_id = MT8173_CLK_MM, ++ }, ++ [MT8173_POWER_DOMAIN_ISP] = { ++ .name = "isp", ++ .sta_mask = PWR_STATUS_ISP, ++ .ctl_offs = SPM_ISP_PWR_CON, ++ .sram_pdn_bits = GENMASK(11, 8), ++ .sram_pdn_ack_bits = GENMASK(13, 12), ++ .clk_id = MT8173_CLK_MM, ++ }, ++ [MT8173_POWER_DOMAIN_MM] = { ++ .name = "mm", ++ .sta_mask = PWR_STATUS_DISP, ++ .ctl_offs = SPM_DIS_PWR_CON, ++ .sram_pdn_bits = GENMASK(11, 8), ++ .sram_pdn_ack_bits = GENMASK(12, 12), ++ .clk_id = MT8173_CLK_MM, ++ .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 | ++ MT8173_TOP_AXI_PROT_EN_MM_M1, ++ }, ++ [MT8173_POWER_DOMAIN_VENC_LT] = { ++ .name = "venc_lt", ++ .sta_mask = PWR_STATUS_VENC_LT, ++ .ctl_offs = SPM_VEN2_PWR_CON, ++ .sram_pdn_bits = GENMASK(11, 8), ++ .sram_pdn_ack_bits = GENMASK(15, 12), ++ .clk_id = MT8173_CLK_MM, ++ }, ++ [MT8173_POWER_DOMAIN_AUDIO] = { ++ .name = "audio", ++ .sta_mask = PWR_STATUS_AUDIO, ++ .ctl_offs = SPM_AUDIO_PWR_CON, ++ .sram_pdn_bits = GENMASK(11, 8), ++ .sram_pdn_ack_bits = GENMASK(15, 12), ++ .clk_id = MT8173_CLK_NONE, ++ }, ++ [MT8173_POWER_DOMAIN_USB] = { ++ .name = "usb", ++ .sta_mask = PWR_STATUS_USB, ++ .ctl_offs = SPM_USB_PWR_CON, ++ .sram_pdn_bits = GENMASK(11, 8), ++ .sram_pdn_ack_bits = GENMASK(15, 12), ++ .clk_id = MT8173_CLK_NONE, ++ }, ++ [MT8173_POWER_DOMAIN_MFG_ASYNC] = { ++ .name = "mfg_async", ++ .sta_mask = PWR_STATUS_MFG_ASYNC, ++ .ctl_offs = SPM_MFG_ASYNC_PWR_CON, ++ .sram_pdn_bits = GENMASK(11, 8), ++ .sram_pdn_ack_bits = 0, ++ .clk_id = MT8173_CLK_MFG, ++ }, ++ [MT8173_POWER_DOMAIN_MFG_2D] = { ++ .name = "mfg_2d", ++ .sta_mask = PWR_STATUS_MFG_2D, ++ .ctl_offs = SPM_MFG_2D_PWR_CON, ++ .sram_pdn_bits = GENMASK(11, 8), ++ .sram_pdn_ack_bits = GENMASK(13, 12), ++ .clk_id = MT8173_CLK_NONE, ++ }, ++ [MT8173_POWER_DOMAIN_MFG] = { ++ .name = "mfg", ++ .sta_mask = PWR_STATUS_MFG, ++ .ctl_offs = SPM_MFG_PWR_CON, ++ .sram_pdn_bits = GENMASK(13, 8), ++ .sram_pdn_ack_bits = GENMASK(21, 16), ++ .clk_id = MT8173_CLK_NONE, ++ .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S | ++ MT8173_TOP_AXI_PROT_EN_MFG_M0 | ++ MT8173_TOP_AXI_PROT_EN_MFG_M1 | ++ MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT, ++ }, ++}; ++ ++#define NUM_DOMAINS ARRAY_SIZE(scp_domain_data) ++ ++struct scp; ++ ++struct scp_domain { ++ struct generic_pm_domain genpd; ++ struct scp *scp; ++ struct clk *clk; ++ u32 sta_mask; ++ void __iomem *ctl_addr; ++ u32 sram_pdn_bits; ++ u32 sram_pdn_ack_bits; ++ u32 bus_prot_mask; ++}; ++ ++struct scp { ++ struct scp_domain domains[NUM_DOMAINS]; ++ struct genpd_onecell_data pd_data; ++ struct device *dev; ++ void __iomem *base; ++ struct regmap *infracfg; ++ struct clk *clk[MT8173_CLK_MAX]; ++}; ++ ++static int scpsys_domain_is_on(struct scp_domain *scpd) ++{ ++ struct scp *scp = scpd->scp; ++ ++ u32 status = readl(scp->base + SPM_PWR_STATUS) & scpd->sta_mask; ++ u32 status2 = readl(scp->base + SPM_PWR_STATUS_2ND) & scpd->sta_mask; ++ ++ /* ++ * A domain is on when both status bits are set. If only one is set ++ * return an error. This happens while powering up a domain ++ */ ++ ++ if (status && status2) ++ return true; ++ if (!status && !status2) ++ return false; ++ ++ return -EINVAL; ++} ++ ++static int scpsys_power_on(struct generic_pm_domain *genpd) ++{ ++ struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd); ++ struct scp *scp = scpd->scp; ++ unsigned long timeout; ++ bool expired; ++ void __iomem *ctl_addr = scpd->ctl_addr; ++ u32 sram_pdn_ack = scpd->sram_pdn_ack_bits; ++ u32 val; ++ int ret; ++ ++ if (scpd->clk) { ++ ret = clk_prepare_enable(scpd->clk); ++ if (ret) ++ return ret; ++ } ++ ++ val = readl(ctl_addr); ++ val |= PWR_ON_BIT; ++ writel(val, ctl_addr); ++ val |= PWR_ON_2ND_BIT; ++ writel(val, ctl_addr); ++ ++ /* wait until PWR_ACK = 1 */ ++ timeout = jiffies + HZ; ++ expired = false; ++ while (1) { ++ ret = scpsys_domain_is_on(scpd); ++ if (ret > 0) ++ break; ++ ++ if (expired) { ++ ret = -ETIMEDOUT; ++ goto out; ++ } ++ ++ cpu_relax(); ++ ++ if (time_after(jiffies, timeout)) ++ expired = true; ++ } ++ ++ val &= ~PWR_CLK_DIS_BIT; ++ writel(val, ctl_addr); ++ ++ val &= ~PWR_ISO_BIT; ++ writel(val, ctl_addr); ++ ++ val |= PWR_RST_B_BIT; ++ writel(val, ctl_addr); ++ ++ val &= ~scpd->sram_pdn_bits; ++ writel(val, ctl_addr); ++ ++ /* wait until SRAM_PDN_ACK all 0 */ ++ timeout = jiffies + HZ; ++ expired = false; ++ while (sram_pdn_ack && (readl(ctl_addr) & sram_pdn_ack)) { ++ ++ if (expired) { ++ ret = -ETIMEDOUT; ++ goto out; ++ } ++ ++ cpu_relax(); ++ ++ if (time_after(jiffies, timeout)) ++ expired = true; ++ } ++ ++ if (scpd->bus_prot_mask) { ++ ret = mtk_infracfg_clear_bus_protection(scp->infracfg, ++ scpd->bus_prot_mask); ++ if (ret) ++ return ret; ++ } ++ ++ return 0; ++out: ++ dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name); ++ ++ return ret; ++} ++ ++static int scpsys_power_off(struct generic_pm_domain *genpd) ++{ ++ struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd); ++ struct scp *scp = scpd->scp; ++ unsigned long timeout; ++ bool expired; ++ void __iomem *ctl_addr = scpd->ctl_addr; ++ u32 pdn_ack = scpd->sram_pdn_ack_bits; ++ u32 val; ++ int ret; ++ ++ if (scpd->bus_prot_mask) { ++ ret = mtk_infracfg_set_bus_protection(scp->infracfg, ++ scpd->bus_prot_mask); ++ if (ret) ++ return ret; ++ } ++ ++ val = readl(ctl_addr); ++ val |= scpd->sram_pdn_bits; ++ writel(val, ctl_addr); ++ ++ /* wait until SRAM_PDN_ACK all 1 */ ++ timeout = jiffies + HZ; ++ expired = false; ++ while (pdn_ack && (readl(ctl_addr) & pdn_ack) != pdn_ack) { ++ if (expired) { ++ ret = -ETIMEDOUT; ++ goto out; ++ } ++ ++ cpu_relax(); ++ ++ if (time_after(jiffies, timeout)) ++ expired = true; ++ } ++ ++ val |= PWR_ISO_BIT; ++ writel(val, ctl_addr); ++ ++ val &= ~PWR_RST_B_BIT; ++ writel(val, ctl_addr); ++ ++ val |= PWR_CLK_DIS_BIT; ++ writel(val, ctl_addr); ++ ++ val &= ~PWR_ON_BIT; ++ writel(val, ctl_addr); ++ ++ val &= ~PWR_ON_2ND_BIT; ++ writel(val, ctl_addr); ++ ++ /* wait until PWR_ACK = 0 */ ++ timeout = jiffies + HZ; ++ expired = false; ++ while (1) { ++ ret = scpsys_domain_is_on(scpd); ++ if (ret == 0) ++ break; ++ ++ if (expired) { ++ ret = -ETIMEDOUT; ++ goto out; ++ } ++ ++ cpu_relax(); ++ ++ if (time_after(jiffies, timeout)) ++ expired = true; ++ } ++ ++ if (scpd->clk) ++ clk_disable_unprepare(scpd->clk); ++ ++ return 0; ++ ++out: ++ dev_err(scp->dev, "Failed to power off domain %s\n", genpd->name); ++ ++ return ret; ++} ++ ++static int __init scpsys_probe(struct platform_device *pdev) ++{ ++ struct genpd_onecell_data *pd_data; ++ struct resource *res; ++ int i, ret; ++ struct scp *scp; ++ ++ scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL); ++ if (!scp) ++ return -ENOMEM; ++ ++ scp->dev = &pdev->dev; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ scp->base = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(scp->base)) ++ return PTR_ERR(scp->base); ++ ++ pd_data = &scp->pd_data; ++ ++ pd_data->domains = devm_kzalloc(&pdev->dev, ++ sizeof(*pd_data->domains) * NUM_DOMAINS, GFP_KERNEL); ++ if (!pd_data->domains) ++ return -ENOMEM; ++ ++ scp->clk[MT8173_CLK_MM] = devm_clk_get(&pdev->dev, "mm"); ++ if (IS_ERR(scp->clk[MT8173_CLK_MM])) { ++ dev_err(&pdev->dev, "Failed to get mm clk: %ld\n", ++ PTR_ERR(scp->clk[MT8173_CLK_MM])); ++ return PTR_ERR(scp->clk[MT8173_CLK_MM]); ++ } ++ ++ scp->clk[MT8173_CLK_MFG] = devm_clk_get(&pdev->dev, "mfg"); ++ if (IS_ERR(scp->clk[MT8173_CLK_MFG])) { ++ dev_err(&pdev->dev, "Failed to get mfg clk: %ld\n", ++ PTR_ERR(scp->clk[MT8173_CLK_MFG])); ++ return PTR_ERR(scp->clk[MT8173_CLK_MFG]); ++ } ++ ++ scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, ++ "infracfg"); ++ if (IS_ERR(scp->infracfg)) { ++ dev_err(&pdev->dev, "Cannot find infracfg controller: %ld\n", ++ PTR_ERR(scp->infracfg)); ++ return PTR_ERR(scp->infracfg); ++ } ++ ++ pd_data->num_domains = NUM_DOMAINS; ++ ++ for (i = 0; i < NUM_DOMAINS; i++) { ++ struct scp_domain *scpd = &scp->domains[i]; ++ struct generic_pm_domain *genpd = &scpd->genpd; ++ const struct scp_domain_data *data = &scp_domain_data[i]; ++ ++ pd_data->domains[i] = genpd; ++ scpd->scp = scp; ++ ++ scpd->sta_mask = data->sta_mask; ++ scpd->ctl_addr = scp->base + data->ctl_offs; ++ scpd->sram_pdn_bits = data->sram_pdn_bits; ++ scpd->sram_pdn_ack_bits = data->sram_pdn_ack_bits; ++ scpd->bus_prot_mask = data->bus_prot_mask; ++ if (data->clk_id != MT8173_CLK_NONE) ++ scpd->clk = scp->clk[data->clk_id]; ++ ++ genpd->name = data->name; ++ genpd->power_off = scpsys_power_off; ++ genpd->power_on = scpsys_power_on; ++ ++ /* ++ * Initially turn on all domains to make the domains usable ++ * with !CONFIG_PM and to get the hardware in sync with the ++ * software. The unused domains will be switched off during ++ * late_init time. ++ */ ++ genpd->power_on(genpd); ++ ++ pm_genpd_init(genpd, NULL, false); ++ } ++ ++ /* ++ * We are not allowed to fail here since there is no way to unregister ++ * a power domain. Once registered above we have to keep the domains ++ * valid. ++ */ ++ ++ ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_ASYNC], ++ pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D]); ++ if (ret && IS_ENABLED(CONFIG_PM)) ++ dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret); ++ ++ ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D], ++ pd_data->domains[MT8173_POWER_DOMAIN_MFG]); ++ if (ret && IS_ENABLED(CONFIG_PM)) ++ dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret); ++ ++ ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data); ++ if (ret) ++ dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret); ++ ++ return 0; ++} ++ ++static const struct of_device_id of_scpsys_match_tbl[] = { ++ { ++ .compatible = "mediatek,mt8173-scpsys", ++ }, { ++ /* sentinel */ ++ } ++}; ++ ++static struct platform_driver scpsys_drv = { ++ .driver = { ++ .name = "mtk-scpsys", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(of_scpsys_match_tbl), ++ }, ++}; ++ ++module_platform_driver_probe(scpsys_drv, scpsys_probe); +diff --git a/include/dt-bindings/power/mt8173-power.h b/include/dt-bindings/power/mt8173-power.h +new file mode 100644 +index 0000000..b34cee9 +--- /dev/null ++++ b/include/dt-bindings/power/mt8173-power.h +@@ -0,0 +1,15 @@ ++#ifndef _DT_BINDINGS_POWER_MT8183_POWER_H ++#define _DT_BINDINGS_POWER_MT8183_POWER_H ++ ++#define MT8173_POWER_DOMAIN_VDEC 0 ++#define MT8173_POWER_DOMAIN_VENC 1 ++#define MT8173_POWER_DOMAIN_ISP 2 ++#define MT8173_POWER_DOMAIN_MM 3 ++#define MT8173_POWER_DOMAIN_VENC_LT 4 ++#define MT8173_POWER_DOMAIN_AUDIO 5 ++#define MT8173_POWER_DOMAIN_USB 6 ++#define MT8173_POWER_DOMAIN_MFG_ASYNC 7 ++#define MT8173_POWER_DOMAIN_MFG_2D 8 ++#define MT8173_POWER_DOMAIN_MFG 9 ++ ++#endif /* _DT_BINDINGS_POWER_MT8183_POWER_H */ +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0009-dt-bindings-ARM-Mediatek-Document-devicetree-binding.patch b/target/linux/mediatek/patches/0009-dt-bindings-ARM-Mediatek-Document-devicetree-binding.patch new file mode 100644 index 0000000000..6d7fd47577 --- /dev/null +++ b/target/linux/mediatek/patches/0009-dt-bindings-ARM-Mediatek-Document-devicetree-binding.patch @@ -0,0 +1,154 @@ +From 87043a64dd5185dc076b3c3ab2e421b3a8c47798 Mon Sep 17 00:00:00 2001 +From: Sascha Hauer <s.hauer@pengutronix.de> +Date: Thu, 23 Apr 2015 10:35:43 +0200 +Subject: [PATCH 09/76] dt-bindings: ARM: Mediatek: Document devicetree + bindings for clock/reset controllers + +This adds the binding documentation for the apmixedsys, perisys and +infracfg controllers found on Mediatek SoCs. + +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +--- + .../bindings/arm/mediatek/mediatek,apmixedsys.txt | 23 +++++++++++++++ + .../bindings/arm/mediatek/mediatek,infracfg.txt | 30 ++++++++++++++++++++ + .../bindings/arm/mediatek/mediatek,pericfg.txt | 30 ++++++++++++++++++++ + .../bindings/arm/mediatek/mediatek,topckgen.txt | 23 +++++++++++++++ + 4 files changed, 106 insertions(+) + create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt + create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt + create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt + create mode 100644 Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt + +diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt +new file mode 100644 +index 0000000..5af6d73 +--- /dev/null ++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,apmixedsys.txt +@@ -0,0 +1,23 @@ ++Mediatek apmixedsys controller ++============================== ++ ++The Mediatek apmixedsys controller provides the PLLs to the system. ++ ++Required Properties: ++ ++- compatible: Should be: ++ - "mediatek,mt8135-apmixedsys" ++ - "mediatek,mt8173-apmixedsys" ++- #clock-cells: Must be 1 ++ ++The apmixedsys controller uses the common clk binding from ++Documentation/devicetree/bindings/clock/clock-bindings.txt ++The available clocks are defined in dt-bindings/clock/mt*-clk.h. ++ ++Example: ++ ++apmixedsys: apmixedsys@10209000 { ++ compatible = "mediatek,mt8173-apmixedsys"; ++ reg = <0 0x10209000 0 0x1000>; ++ #clock-cells = <1>; ++}; +diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt +new file mode 100644 +index 0000000..684da473 +--- /dev/null ++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,infracfg.txt +@@ -0,0 +1,30 @@ ++Mediatek infracfg controller ++============================ ++ ++The Mediatek infracfg controller provides various clocks and reset ++outputs to the system. ++ ++Required Properties: ++ ++- compatible: Should be: ++ - "mediatek,mt8135-infracfg", "syscon" ++ - "mediatek,mt8173-infracfg", "syscon" ++- #clock-cells: Must be 1 ++- #reset-cells: Must be 1 ++ ++The infracfg controller uses the common clk binding from ++Documentation/devicetree/bindings/clock/clock-bindings.txt ++The available clocks are defined in dt-bindings/clock/mt*-clk.h. ++Also it uses the common reset controller binding from ++Documentation/devicetree/bindings/reset/reset.txt. ++The available reset outputs are defined in ++dt-bindings/reset-controller/mt*-resets.h ++ ++Example: ++ ++infracfg: infracfg@10001000 { ++ compatible = "mediatek,mt8173-infracfg", "syscon"; ++ reg = <0 0x10001000 0 0x1000>; ++ #clock-cells = <1>; ++ #reset-cells = <1>; ++}; +diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt +new file mode 100644 +index 0000000..fdb45c6 +--- /dev/null ++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,pericfg.txt +@@ -0,0 +1,30 @@ ++Mediatek pericfg controller ++=========================== ++ ++The Mediatek pericfg controller provides various clocks and reset ++outputs to the system. ++ ++Required Properties: ++ ++- compatible: Should be: ++ - "mediatek,mt8135-pericfg", "syscon" ++ - "mediatek,mt8173-pericfg", "syscon" ++- #clock-cells: Must be 1 ++- #reset-cells: Must be 1 ++ ++The pericfg controller uses the common clk binding from ++Documentation/devicetree/bindings/clock/clock-bindings.txt ++The available clocks are defined in dt-bindings/clock/mt*-clk.h. ++Also it uses the common reset controller binding from ++Documentation/devicetree/bindings/reset/reset.txt. ++The available reset outputs are defined in ++dt-bindings/reset-controller/mt*-resets.h ++ ++Example: ++ ++pericfg: pericfg@10003000 { ++ compatible = "mediatek,mt8173-pericfg", "syscon"; ++ reg = <0 0x10003000 0 0x1000>; ++ #clock-cells = <1>; ++ #reset-cells = <1>; ++}; +diff --git a/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt +new file mode 100644 +index 0000000..a425248 +--- /dev/null ++++ b/Documentation/devicetree/bindings/arm/mediatek/mediatek,topckgen.txt +@@ -0,0 +1,23 @@ ++Mediatek topckgen controller ++============================ ++ ++The Mediatek topckgen controller provides various clocks to the system. ++ ++Required Properties: ++ ++- compatible: Should be: ++ - "mediatek,mt8135-topckgen" ++ - "mediatek,mt8173-topckgen" ++- #clock-cells: Must be 1 ++ ++The topckgen controller uses the common clk binding from ++Documentation/devicetree/bindings/clock/clock-bindings.txt ++The available clocks are defined in dt-bindings/clock/mt*-clk.h. ++ ++Example: ++ ++topckgen: topckgen@10000000 { ++ compatible = "mediatek,mt8173-topckgen"; ++ reg = <0 0x10000000 0 0x1000>; ++ #clock-cells = <1>; ++}; +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0010-thermal-consistently-use-int-for-temperatures.patch b/target/linux/mediatek/patches/0010-thermal-consistently-use-int-for-temperatures.patch new file mode 100644 index 0000000000..2aa83abb93 --- /dev/null +++ b/target/linux/mediatek/patches/0010-thermal-consistently-use-int-for-temperatures.patch @@ -0,0 +1,1155 @@ +From 29e6031548373b9e7ec0c17e85da6a4cf4fee7f5 Mon Sep 17 00:00:00 2001 +From: Sascha Hauer <s.hauer@pengutronix.de> +Date: Wed, 13 May 2015 10:52:29 +0200 +Subject: [PATCH 10/76] thermal: consistently use int for temperatures + +The thermal code uses int, long and unsigned long for temperatures +in different places. Using an unsigned type limits the thermal framework +to positive temperatures without need. 'long' is 64bit on several +architectures which is not needed. Consistently use a plain 'int' +for temperatures. + +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +--- + drivers/acpi/thermal.c | 12 ++++----- + drivers/hwmon/lm75.c | 2 +- + drivers/hwmon/ntc_thermistor.c | 2 +- + drivers/hwmon/tmp102.c | 2 +- + drivers/input/touchscreen/sun4i-ts.c | 8 +++--- + drivers/platform/x86/acerhdf.c | 9 +++---- + drivers/power/power_supply_core.c | 2 +- + drivers/thermal/armada_thermal.c | 2 +- + drivers/thermal/db8500_thermal.c | 7 +++-- + drivers/thermal/dove_thermal.c | 2 +- + drivers/thermal/fair_share.c | 2 +- + drivers/thermal/gov_bang_bang.c | 5 ++-- + drivers/thermal/imx_thermal.c | 27 ++++++++++---------- + .../thermal/int340x_thermal/int340x_thermal_zone.c | 10 ++++---- + .../thermal/int340x_thermal/int340x_thermal_zone.h | 8 +++--- + drivers/thermal/intel_soc_dts_thermal.c | 7 +++-- + drivers/thermal/of-thermal.c | 14 +++++----- + drivers/thermal/rcar_thermal.c | 7 +++-- + drivers/thermal/rockchip_thermal.c | 10 ++++---- + drivers/thermal/samsung/exynos_tmu.c | 19 +++++++------- + drivers/thermal/spear_thermal.c | 2 +- + drivers/thermal/st/st_thermal.c | 5 ++-- + drivers/thermal/step_wise.c | 4 +-- + drivers/thermal/tegra_soctherm.c | 4 +-- + drivers/thermal/thermal_core.c | 26 +++++++++---------- + drivers/thermal/thermal_hwmon.c | 10 ++++---- + drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 10 ++++---- + drivers/thermal/x86_pkg_temp_thermal.c | 10 ++++---- + include/linux/thermal.h | 26 ++++++++----------- + 29 files changed, 120 insertions(+), 134 deletions(-) + +diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c +index d24fa19..68bff60 100644 +--- a/drivers/acpi/thermal.c ++++ b/drivers/acpi/thermal.c +@@ -529,8 +529,7 @@ static void acpi_thermal_check(void *data) + + /* sys I/F for generic thermal sysfs support */ + +-static int thermal_get_temp(struct thermal_zone_device *thermal, +- unsigned long *temp) ++static int thermal_get_temp(struct thermal_zone_device *thermal, int *temp) + { + struct acpi_thermal *tz = thermal->devdata; + int result; +@@ -637,7 +636,7 @@ static int thermal_get_trip_type(struct thermal_zone_device *thermal, + } + + static int thermal_get_trip_temp(struct thermal_zone_device *thermal, +- int trip, unsigned long *temp) ++ int trip, int *temp) + { + struct acpi_thermal *tz = thermal->devdata; + int i; +@@ -690,7 +689,8 @@ static int thermal_get_trip_temp(struct thermal_zone_device *thermal, + } + + static int thermal_get_crit_temp(struct thermal_zone_device *thermal, +- unsigned long *temperature) { ++ int *temperature) ++{ + struct acpi_thermal *tz = thermal->devdata; + + if (tz->trips.critical.flags.valid) { +@@ -713,8 +713,8 @@ static int thermal_get_trend(struct thermal_zone_device *thermal, + return -EINVAL; + + if (type == THERMAL_TRIP_ACTIVE) { +- unsigned long trip_temp; +- unsigned long temp = DECI_KELVIN_TO_MILLICELSIUS_WITH_OFFSET( ++ int trip_temp; ++ int temp = DECI_KELVIN_TO_MILLICELSIUS_WITH_OFFSET( + tz->temperature, tz->kelvin_offset); + if (thermal_get_trip_temp(thermal, trip, &trip_temp)) + return -EINVAL; +diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c +index fe41d5a..e4e57bb 100644 +--- a/drivers/hwmon/lm75.c ++++ b/drivers/hwmon/lm75.c +@@ -104,7 +104,7 @@ static inline long lm75_reg_to_mc(s16 temp, u8 resolution) + + /* sysfs attributes for hwmon */ + +-static int lm75_read_temp(void *dev, long *temp) ++static int lm75_read_temp(void *dev, int *temp) + { + struct lm75_data *data = lm75_update_device(dev); + +diff --git a/drivers/hwmon/ntc_thermistor.c b/drivers/hwmon/ntc_thermistor.c +index 6880011..3d9eab9 100644 +--- a/drivers/hwmon/ntc_thermistor.c ++++ b/drivers/hwmon/ntc_thermistor.c +@@ -439,7 +439,7 @@ static int ntc_thermistor_get_ohm(struct ntc_data *data) + return -EINVAL; + } + +-static int ntc_read_temp(void *dev, long *temp) ++static int ntc_read_temp(void *dev, int *temp) + { + struct ntc_data *data = dev_get_drvdata(dev); + int ohm; +diff --git a/drivers/hwmon/tmp102.c b/drivers/hwmon/tmp102.c +index 9da2735..6548262 100644 +--- a/drivers/hwmon/tmp102.c ++++ b/drivers/hwmon/tmp102.c +@@ -98,7 +98,7 @@ static struct tmp102 *tmp102_update_device(struct device *dev) + return tmp102; + } + +-static int tmp102_read_temp(void *dev, long *temp) ++static int tmp102_read_temp(void *dev, int *temp) + { + struct tmp102 *tmp102 = tmp102_update_device(dev); + +diff --git a/drivers/input/touchscreen/sun4i-ts.c b/drivers/input/touchscreen/sun4i-ts.c +index c011699..4857943 100644 +--- a/drivers/input/touchscreen/sun4i-ts.c ++++ b/drivers/input/touchscreen/sun4i-ts.c +@@ -191,7 +191,7 @@ static void sun4i_ts_close(struct input_dev *dev) + writel(TEMP_IRQ_EN(1), ts->base + TP_INT_FIFOC); + } + +-static int sun4i_get_temp(const struct sun4i_ts_data *ts, long *temp) ++static int sun4i_get_temp(const struct sun4i_ts_data *ts, int *temp) + { + /* No temp_data until the first irq */ + if (ts->temp_data == -1) +@@ -202,7 +202,7 @@ static int sun4i_get_temp(const struct sun4i_ts_data *ts, long *temp) + return 0; + } + +-static int sun4i_get_tz_temp(void *data, long *temp) ++static int sun4i_get_tz_temp(void *data, int *temp) + { + return sun4i_get_temp(data, temp); + } +@@ -215,14 +215,14 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, + char *buf) + { + struct sun4i_ts_data *ts = dev_get_drvdata(dev); +- long temp; ++ int temp; + int error; + + error = sun4i_get_temp(ts, &temp); + if (error) + return error; + +- return sprintf(buf, "%ld\n", temp); ++ return sprintf(buf, "%d\n", temp); + } + + static ssize_t show_temp_label(struct device *dev, +diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c +index 594c918..f2ce63c 100644 +--- a/drivers/platform/x86/acerhdf.c ++++ b/drivers/platform/x86/acerhdf.c +@@ -346,8 +346,7 @@ static void acerhdf_check_param(struct thermal_zone_device *thermal) + * as late as the polling interval is since we can't do that in the respective + * accessors of the module parameters. + */ +-static int acerhdf_get_ec_temp(struct thermal_zone_device *thermal, +- unsigned long *t) ++static int acerhdf_get_ec_temp(struct thermal_zone_device *thermal, int *t) + { + int temp, err = 0; + +@@ -452,7 +451,7 @@ static int acerhdf_get_trip_type(struct thermal_zone_device *thermal, int trip, + } + + static int acerhdf_get_trip_hyst(struct thermal_zone_device *thermal, int trip, +- unsigned long *temp) ++ int *temp) + { + if (trip != 0) + return -EINVAL; +@@ -463,7 +462,7 @@ static int acerhdf_get_trip_hyst(struct thermal_zone_device *thermal, int trip, + } + + static int acerhdf_get_trip_temp(struct thermal_zone_device *thermal, int trip, +- unsigned long *temp) ++ int *temp) + { + if (trip == 0) + *temp = fanon; +@@ -476,7 +475,7 @@ static int acerhdf_get_trip_temp(struct thermal_zone_device *thermal, int trip, + } + + static int acerhdf_get_crit_temp(struct thermal_zone_device *thermal, +- unsigned long *temperature) ++ int *temperature) + { + *temperature = ACERHDF_TEMP_CRIT; + return 0; +diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c +index 2ed4a4a..87e2fd1 100644 +--- a/drivers/power/power_supply_core.c ++++ b/drivers/power/power_supply_core.c +@@ -492,7 +492,7 @@ EXPORT_SYMBOL_GPL(power_supply_unreg_notifier); + + #ifdef CONFIG_THERMAL + static int power_supply_read_temp(struct thermal_zone_device *tzd, +- unsigned long *temp) ++ int *temp) + { + struct power_supply *psy; + union power_supply_propval val; +diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c +index 01255fd..26b8d32 100644 +--- a/drivers/thermal/armada_thermal.c ++++ b/drivers/thermal/armada_thermal.c +@@ -155,7 +155,7 @@ static bool armada_is_valid(struct armada_thermal_priv *priv) + } + + static int armada_get_temp(struct thermal_zone_device *thermal, +- unsigned long *temp) ++ int *temp) + { + struct armada_thermal_priv *priv = thermal->devdata; + unsigned long reg; +diff --git a/drivers/thermal/db8500_thermal.c b/drivers/thermal/db8500_thermal.c +index 20adfbe..b3eca71 100644 +--- a/drivers/thermal/db8500_thermal.c ++++ b/drivers/thermal/db8500_thermal.c +@@ -107,8 +107,7 @@ static int db8500_cdev_unbind(struct thermal_zone_device *thermal, + } + + /* Callback to get current temperature */ +-static int db8500_sys_get_temp(struct thermal_zone_device *thermal, +- unsigned long *temp) ++static int db8500_sys_get_temp(struct thermal_zone_device *thermal, int *temp) + { + struct db8500_thermal_zone *pzone = thermal->devdata; + +@@ -180,7 +179,7 @@ static int db8500_sys_get_trip_type(struct thermal_zone_device *thermal, + + /* Callback to get trip point temperature */ + static int db8500_sys_get_trip_temp(struct thermal_zone_device *thermal, +- int trip, unsigned long *temp) ++ int trip, int *temp) + { + struct db8500_thermal_zone *pzone = thermal->devdata; + struct db8500_thsens_platform_data *ptrips = pzone->trip_tab; +@@ -195,7 +194,7 @@ static int db8500_sys_get_trip_temp(struct thermal_zone_device *thermal, + + /* Callback to get critical trip point temperature */ + static int db8500_sys_get_crit_temp(struct thermal_zone_device *thermal, +- unsigned long *temp) ++ int *temp) + { + struct db8500_thermal_zone *pzone = thermal->devdata; + struct db8500_thsens_platform_data *ptrips = pzone->trip_tab; +diff --git a/drivers/thermal/dove_thermal.c b/drivers/thermal/dove_thermal.c +index 09f6e30..a0bc9de 100644 +--- a/drivers/thermal/dove_thermal.c ++++ b/drivers/thermal/dove_thermal.c +@@ -93,7 +93,7 @@ static int dove_init_sensor(const struct dove_thermal_priv *priv) + } + + static int dove_get_temp(struct thermal_zone_device *thermal, +- unsigned long *temp) ++ int *temp) + { + unsigned long reg; + struct dove_thermal_priv *priv = thermal->devdata; +diff --git a/drivers/thermal/fair_share.c b/drivers/thermal/fair_share.c +index 6e0a3fb..efad70e 100644 +--- a/drivers/thermal/fair_share.c ++++ b/drivers/thermal/fair_share.c +@@ -34,7 +34,7 @@ + static int get_trip_level(struct thermal_zone_device *tz) + { + int count = 0; +- unsigned long trip_temp; ++ int trip_temp; + enum thermal_trip_type trip_type; + + if (tz->trips == 0 || !tz->ops->get_trip_temp) +diff --git a/drivers/thermal/gov_bang_bang.c b/drivers/thermal/gov_bang_bang.c +index c5dd76b..70836c5 100644 +--- a/drivers/thermal/gov_bang_bang.c ++++ b/drivers/thermal/gov_bang_bang.c +@@ -25,14 +25,13 @@ + + static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip) + { +- long trip_temp; +- unsigned long trip_hyst; ++ int trip_temp, trip_hyst; + struct thermal_instance *instance; + + tz->ops->get_trip_temp(tz, trip, &trip_temp); + tz->ops->get_trip_hyst(tz, trip, &trip_hyst); + +- dev_dbg(&tz->device, "Trip%d[temp=%ld]:temp=%d:hyst=%ld\n", ++ dev_dbg(&tz->device, "Trip%d[temp=%d]:temp=%d:hyst=%d\n", + trip, trip_temp, tz->temperature, + trip_hyst); + +diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c +index 2ccbc07..f1424f0 100644 +--- a/drivers/thermal/imx_thermal.c ++++ b/drivers/thermal/imx_thermal.c +@@ -98,10 +98,10 @@ struct imx_thermal_data { + enum thermal_device_mode mode; + struct regmap *tempmon; + u32 c1, c2; /* See formula in imx_get_sensor_data() */ +- unsigned long temp_passive; +- unsigned long temp_critical; +- unsigned long alarm_temp; +- unsigned long last_temp; ++ int temp_passive; ++ int temp_critical; ++ int alarm_temp; ++ int last_temp; + bool irq_enabled; + int irq; + struct clk *thermal_clk; +@@ -109,7 +109,7 @@ struct imx_thermal_data { + }; + + static void imx_set_panic_temp(struct imx_thermal_data *data, +- signed long panic_temp) ++ int panic_temp) + { + struct regmap *map = data->tempmon; + int critical_value; +@@ -121,7 +121,7 @@ static void imx_set_panic_temp(struct imx_thermal_data *data, + } + + static void imx_set_alarm_temp(struct imx_thermal_data *data, +- signed long alarm_temp) ++ int alarm_temp) + { + struct regmap *map = data->tempmon; + int alarm_value; +@@ -133,7 +133,7 @@ static void imx_set_alarm_temp(struct imx_thermal_data *data, + TEMPSENSE0_ALARM_VALUE_SHIFT); + } + +-static int imx_get_temp(struct thermal_zone_device *tz, unsigned long *temp) ++static int imx_get_temp(struct thermal_zone_device *tz, int *temp) + { + struct imx_thermal_data *data = tz->devdata; + struct regmap *map = data->tempmon; +@@ -189,13 +189,13 @@ static int imx_get_temp(struct thermal_zone_device *tz, unsigned long *temp) + if (data->alarm_temp == data->temp_critical && + *temp < data->temp_passive) { + imx_set_alarm_temp(data, data->temp_passive); +- dev_dbg(&tz->device, "thermal alarm off: T < %lu\n", ++ dev_dbg(&tz->device, "thermal alarm off: T < %d\n", + data->alarm_temp / 1000); + } + } + + if (*temp != data->last_temp) { +- dev_dbg(&tz->device, "millicelsius: %ld\n", *temp); ++ dev_dbg(&tz->device, "millicelsius: %d\n", *temp); + data->last_temp = *temp; + } + +@@ -262,8 +262,7 @@ static int imx_get_trip_type(struct thermal_zone_device *tz, int trip, + return 0; + } + +-static int imx_get_crit_temp(struct thermal_zone_device *tz, +- unsigned long *temp) ++static int imx_get_crit_temp(struct thermal_zone_device *tz, int *temp) + { + struct imx_thermal_data *data = tz->devdata; + +@@ -272,7 +271,7 @@ static int imx_get_crit_temp(struct thermal_zone_device *tz, + } + + static int imx_get_trip_temp(struct thermal_zone_device *tz, int trip, +- unsigned long *temp) ++ int *temp) + { + struct imx_thermal_data *data = tz->devdata; + +@@ -282,7 +281,7 @@ static int imx_get_trip_temp(struct thermal_zone_device *tz, int trip, + } + + static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip, +- unsigned long temp) ++ int temp) + { + struct imx_thermal_data *data = tz->devdata; + +@@ -433,7 +432,7 @@ static irqreturn_t imx_thermal_alarm_irq_thread(int irq, void *dev) + { + struct imx_thermal_data *data = dev; + +- dev_dbg(&data->tz->device, "THERMAL ALARM: T > %lu\n", ++ dev_dbg(&data->tz->device, "THERMAL ALARM: T > %d\n", + data->alarm_temp / 1000); + + thermal_zone_device_update(data->tz); +diff --git a/drivers/thermal/int340x_thermal/int340x_thermal_zone.c b/drivers/thermal/int340x_thermal/int340x_thermal_zone.c +index 1e25133..b9b2666 100644 +--- a/drivers/thermal/int340x_thermal/int340x_thermal_zone.c ++++ b/drivers/thermal/int340x_thermal/int340x_thermal_zone.c +@@ -20,7 +20,7 @@ + #include "int340x_thermal_zone.h" + + static int int340x_thermal_get_zone_temp(struct thermal_zone_device *zone, +- unsigned long *temp) ++ int *temp) + { + struct int34x_thermal_zone *d = zone->devdata; + unsigned long long tmp; +@@ -49,7 +49,7 @@ static int int340x_thermal_get_zone_temp(struct thermal_zone_device *zone, + } + + static int int340x_thermal_get_trip_temp(struct thermal_zone_device *zone, +- int trip, unsigned long *temp) ++ int trip, int *temp) + { + struct int34x_thermal_zone *d = zone->devdata; + int i; +@@ -114,7 +114,7 @@ static int int340x_thermal_get_trip_type(struct thermal_zone_device *zone, + } + + static int int340x_thermal_set_trip_temp(struct thermal_zone_device *zone, +- int trip, unsigned long temp) ++ int trip, int temp) + { + struct int34x_thermal_zone *d = zone->devdata; + acpi_status status; +@@ -136,7 +136,7 @@ static int int340x_thermal_set_trip_temp(struct thermal_zone_device *zone, + + + static int int340x_thermal_get_trip_hyst(struct thermal_zone_device *zone, +- int trip, unsigned long *temp) ++ int trip, int *temp) + { + struct int34x_thermal_zone *d = zone->devdata; + acpi_status status; +@@ -163,7 +163,7 @@ static struct thermal_zone_device_ops int340x_thermal_zone_ops = { + }; + + static int int340x_thermal_get_trip_config(acpi_handle handle, char *name, +- unsigned long *temp) ++ int *temp) + { + unsigned long long r; + acpi_status status; +diff --git a/drivers/thermal/int340x_thermal/int340x_thermal_zone.h b/drivers/thermal/int340x_thermal/int340x_thermal_zone.h +index 9f38ab7..aaadf72 100644 +--- a/drivers/thermal/int340x_thermal/int340x_thermal_zone.h ++++ b/drivers/thermal/int340x_thermal/int340x_thermal_zone.h +@@ -21,7 +21,7 @@ + #define INT340X_THERMAL_MAX_ACT_TRIP_COUNT 10 + + struct active_trip { +- unsigned long temp; ++ int temp; + int id; + bool valid; + }; +@@ -31,11 +31,11 @@ struct int34x_thermal_zone { + struct active_trip act_trips[INT340X_THERMAL_MAX_ACT_TRIP_COUNT]; + unsigned long *aux_trips; + int aux_trip_nr; +- unsigned long psv_temp; ++ int psv_temp; + int psv_trip_id; +- unsigned long crt_temp; ++ int crt_temp; + int crt_trip_id; +- unsigned long hot_temp; ++ int hot_temp; + int hot_trip_id; + struct thermal_zone_device *zone; + struct thermal_zone_device_ops *override_ops; +diff --git a/drivers/thermal/intel_soc_dts_thermal.c b/drivers/thermal/intel_soc_dts_thermal.c +index 9013505..fd550b9 100644 +--- a/drivers/thermal/intel_soc_dts_thermal.c ++++ b/drivers/thermal/intel_soc_dts_thermal.c +@@ -106,7 +106,7 @@ err_ret: + } + + static int sys_get_trip_temp(struct thermal_zone_device *tzd, +- int trip, unsigned long *temp) ++ int trip, int *temp) + { + int status; + u32 out; +@@ -224,7 +224,7 @@ err_restore_ptps: + } + + static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, +- unsigned long temp) ++ int temp) + { + struct soc_sensor_entry *aux_entry = tzd->devdata; + int status; +@@ -250,8 +250,7 @@ static int sys_get_trip_type(struct thermal_zone_device *thermal, + return 0; + } + +-static int sys_get_curr_temp(struct thermal_zone_device *tzd, +- unsigned long *temp) ++static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp) + { + int status; + u32 out; +diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c +index 668fb1b..03839df 100644 +--- a/drivers/thermal/of-thermal.c ++++ b/drivers/thermal/of-thermal.c +@@ -87,7 +87,7 @@ struct __thermal_zone { + /*** DT thermal zone device callbacks ***/ + + static int of_thermal_get_temp(struct thermal_zone_device *tz, +- unsigned long *temp) ++ int *temp) + { + struct __thermal_zone *data = tz->devdata; + +@@ -173,7 +173,7 @@ EXPORT_SYMBOL_GPL(of_thermal_get_trip_points); + * Return: zero on success, error code otherwise + */ + static int of_thermal_set_emul_temp(struct thermal_zone_device *tz, +- unsigned long temp) ++ int temp) + { + struct __thermal_zone *data = tz->devdata; + +@@ -306,7 +306,7 @@ static int of_thermal_get_trip_type(struct thermal_zone_device *tz, int trip, + } + + static int of_thermal_get_trip_temp(struct thermal_zone_device *tz, int trip, +- unsigned long *temp) ++ int *temp) + { + struct __thermal_zone *data = tz->devdata; + +@@ -319,7 +319,7 @@ static int of_thermal_get_trip_temp(struct thermal_zone_device *tz, int trip, + } + + static int of_thermal_set_trip_temp(struct thermal_zone_device *tz, int trip, +- unsigned long temp) ++ int temp) + { + struct __thermal_zone *data = tz->devdata; + +@@ -333,7 +333,7 @@ static int of_thermal_set_trip_temp(struct thermal_zone_device *tz, int trip, + } + + static int of_thermal_get_trip_hyst(struct thermal_zone_device *tz, int trip, +- unsigned long *hyst) ++ int *hyst) + { + struct __thermal_zone *data = tz->devdata; + +@@ -346,7 +346,7 @@ static int of_thermal_get_trip_hyst(struct thermal_zone_device *tz, int trip, + } + + static int of_thermal_set_trip_hyst(struct thermal_zone_device *tz, int trip, +- unsigned long hyst) ++ int hyst) + { + struct __thermal_zone *data = tz->devdata; + +@@ -360,7 +360,7 @@ static int of_thermal_set_trip_hyst(struct thermal_zone_device *tz, int trip, + } + + static int of_thermal_get_crit_temp(struct thermal_zone_device *tz, +- unsigned long *temp) ++ int *temp) + { + struct __thermal_zone *data = tz->devdata; + int i; +diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c +index fe4e767..5d4ae7d 100644 +--- a/drivers/thermal/rcar_thermal.c ++++ b/drivers/thermal/rcar_thermal.c +@@ -200,8 +200,7 @@ err_out_unlock: + return ret; + } + +-static int rcar_thermal_get_temp(struct thermal_zone_device *zone, +- unsigned long *temp) ++static int rcar_thermal_get_temp(struct thermal_zone_device *zone, int *temp) + { + struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone); + +@@ -235,7 +234,7 @@ static int rcar_thermal_get_trip_type(struct thermal_zone_device *zone, + } + + static int rcar_thermal_get_trip_temp(struct thermal_zone_device *zone, +- int trip, unsigned long *temp) ++ int trip, int *temp) + { + struct rcar_thermal_priv *priv = rcar_zone_to_priv(zone); + struct device *dev = rcar_priv_to_dev(priv); +@@ -299,7 +298,7 @@ static void _rcar_thermal_irq_ctrl(struct rcar_thermal_priv *priv, int enable) + static void rcar_thermal_work(struct work_struct *work) + { + struct rcar_thermal_priv *priv; +- unsigned long cctemp, nctemp; ++ int cctemp, nctemp; + + priv = container_of(work, struct rcar_thermal_priv, work.work); + +diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c +index cd8f5f93..c89ffb2 100644 +--- a/drivers/thermal/rockchip_thermal.c ++++ b/drivers/thermal/rockchip_thermal.c +@@ -64,7 +64,7 @@ struct rockchip_tsadc_chip { + void (*control)(void __iomem *reg, bool on); + + /* Per-sensor methods */ +- int (*get_temp)(int chn, void __iomem *reg, long *temp); ++ int (*get_temp)(int chn, void __iomem *reg, int *temp); + void (*set_tshut_temp)(int chn, void __iomem *reg, long temp); + void (*set_tshut_mode)(int chn, void __iomem *reg, enum tshut_mode m); + }; +@@ -191,7 +191,7 @@ static u32 rk_tsadcv2_temp_to_code(long temp) + return 0; + } + +-static long rk_tsadcv2_code_to_temp(u32 code) ++static int rk_tsadcv2_code_to_temp(u32 code) + { + unsigned int low = 0; + unsigned int high = ARRAY_SIZE(v2_code_table) - 1; +@@ -277,7 +277,7 @@ static void rk_tsadcv2_control(void __iomem *regs, bool enable) + writel_relaxed(val, regs + TSADCV2_AUTO_CON); + } + +-static int rk_tsadcv2_get_temp(int chn, void __iomem *regs, long *temp) ++static int rk_tsadcv2_get_temp(int chn, void __iomem *regs, int *temp) + { + u32 val; + +@@ -366,7 +366,7 @@ static irqreturn_t rockchip_thermal_alarm_irq_thread(int irq, void *dev) + return IRQ_HANDLED; + } + +-static int rockchip_thermal_get_temp(void *_sensor, long *out_temp) ++static int rockchip_thermal_get_temp(void *_sensor, int *out_temp) + { + struct rockchip_thermal_sensor *sensor = _sensor; + struct rockchip_thermal_data *thermal = sensor->thermal; +@@ -374,7 +374,7 @@ static int rockchip_thermal_get_temp(void *_sensor, long *out_temp) + int retval; + + retval = tsadc->get_temp(sensor->id, thermal->regs, out_temp); +- dev_dbg(&thermal->pdev->dev, "sensor %d - temp: %ld, retval: %d\n", ++ dev_dbg(&thermal->pdev->dev, "sensor %d - temp: %d, retval: %d\n", + sensor->id, *out_temp, retval); + + return retval; +diff --git a/drivers/thermal/samsung/exynos_tmu.c b/drivers/thermal/samsung/exynos_tmu.c +index 1d30b09..29eaf4d 100644 +--- a/drivers/thermal/samsung/exynos_tmu.c ++++ b/drivers/thermal/samsung/exynos_tmu.c +@@ -181,8 +181,7 @@ struct exynos_tmu_data { + int (*tmu_initialize)(struct platform_device *pdev); + void (*tmu_control)(struct platform_device *pdev, bool on); + int (*tmu_read)(struct exynos_tmu_data *data); +- void (*tmu_set_emulation)(struct exynos_tmu_data *data, +- unsigned long temp); ++ void (*tmu_set_emulation)(struct exynos_tmu_data *data, int temp); + void (*tmu_clear_irqs)(struct exynos_tmu_data *data); + }; + +@@ -190,7 +189,7 @@ static void exynos_report_trigger(struct exynos_tmu_data *p) + { + char data[10], *envp[] = { data, NULL }; + struct thermal_zone_device *tz = p->tzd; +- unsigned long temp; ++ int temp; + unsigned int i; + + if (!tz) { +@@ -489,7 +488,7 @@ static int exynos5440_tmu_initialize(struct platform_device *pdev) + struct exynos_tmu_data *data = platform_get_drvdata(pdev); + unsigned int trim_info = 0, con, rising_threshold; + int ret = 0, threshold_code; +- unsigned long crit_temp = 0; ++ int crit_temp = 0; + + /* + * For exynos5440 soc triminfo value is swapped between TMU0 and +@@ -542,7 +541,7 @@ static int exynos7_tmu_initialize(struct platform_device *pdev) + unsigned int status, trim_info; + unsigned int rising_threshold = 0, falling_threshold = 0; + int ret = 0, threshold_code, i; +- unsigned long temp, temp_hist; ++ int temp, temp_hist; + unsigned int reg_off, bit_off; + + status = readb(data->base + EXYNOS_TMU_REG_STATUS); +@@ -713,7 +712,7 @@ static void exynos7_tmu_control(struct platform_device *pdev, bool on) + writel(con, data->base + EXYNOS_TMU_REG_CONTROL); + } + +-static int exynos_get_temp(void *p, long *temp) ++static int exynos_get_temp(void *p, int *temp) + { + struct exynos_tmu_data *data = p; + +@@ -733,7 +732,7 @@ static int exynos_get_temp(void *p, long *temp) + + #ifdef CONFIG_THERMAL_EMULATION + static u32 get_emul_con_reg(struct exynos_tmu_data *data, unsigned int val, +- unsigned long temp) ++ int temp) + { + if (temp) { + temp /= MCELSIUS; +@@ -763,7 +762,7 @@ static u32 get_emul_con_reg(struct exynos_tmu_data *data, unsigned int val, + } + + static void exynos4412_tmu_set_emulation(struct exynos_tmu_data *data, +- unsigned long temp) ++ int temp) + { + unsigned int val; + u32 emul_con; +@@ -781,7 +780,7 @@ static void exynos4412_tmu_set_emulation(struct exynos_tmu_data *data, + } + + static void exynos5440_tmu_set_emulation(struct exynos_tmu_data *data, +- unsigned long temp) ++ int temp) + { + unsigned int val; + +@@ -790,7 +789,7 @@ static void exynos5440_tmu_set_emulation(struct exynos_tmu_data *data, + writel(val, data->base + EXYNOS5440_TMU_S0_7_DEBUG); + } + +-static int exynos_tmu_set_emulation(void *drv_data, unsigned long temp) ++static int exynos_tmu_set_emulation(void *drv_data, int temp) + { + struct exynos_tmu_data *data = drv_data; + int ret = -EINVAL; +diff --git a/drivers/thermal/spear_thermal.c b/drivers/thermal/spear_thermal.c +index bddb717..534dd91 100644 +--- a/drivers/thermal/spear_thermal.c ++++ b/drivers/thermal/spear_thermal.c +@@ -38,7 +38,7 @@ struct spear_thermal_dev { + }; + + static inline int thermal_get_temp(struct thermal_zone_device *thermal, +- unsigned long *temp) ++ int *temp) + { + struct spear_thermal_dev *stdev = thermal->devdata; + +diff --git a/drivers/thermal/st/st_thermal.c b/drivers/thermal/st/st_thermal.c +index 76c515d..44cbba9 100644 +--- a/drivers/thermal/st/st_thermal.c ++++ b/drivers/thermal/st/st_thermal.c +@@ -111,8 +111,7 @@ static int st_thermal_calibration(struct st_thermal_sensor *sensor) + } + + /* Callback to get temperature from HW*/ +-static int st_thermal_get_temp(struct thermal_zone_device *th, +- unsigned long *temperature) ++static int st_thermal_get_temp(struct thermal_zone_device *th, int *temperature) + { + struct st_thermal_sensor *sensor = th->devdata; + struct device *dev = sensor->dev; +@@ -159,7 +158,7 @@ static int st_thermal_get_trip_type(struct thermal_zone_device *th, + } + + static int st_thermal_get_trip_temp(struct thermal_zone_device *th, +- int trip, unsigned long *temp) ++ int trip, int *temp) + { + struct st_thermal_sensor *sensor = th->devdata; + struct device *dev = sensor->dev; +diff --git a/drivers/thermal/step_wise.c b/drivers/thermal/step_wise.c +index 5a0f12d..2f9f708 100644 +--- a/drivers/thermal/step_wise.c ++++ b/drivers/thermal/step_wise.c +@@ -113,7 +113,7 @@ static void update_passive_instance(struct thermal_zone_device *tz, + + static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip) + { +- long trip_temp; ++ int trip_temp; + enum thermal_trip_type trip_type; + enum thermal_trend trend; + struct thermal_instance *instance; +@@ -135,7 +135,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz, int trip) + trace_thermal_zone_trip(tz, trip, trip_type); + } + +- dev_dbg(&tz->device, "Trip%d[type=%d,temp=%ld]:trend=%d,throttle=%d\n", ++ dev_dbg(&tz->device, "Trip%d[type=%d,temp=%d]:trend=%d,throttle=%d\n", + trip, trip_type, trip_temp, trend, throttle); + + mutex_lock(&tz->lock); +diff --git a/drivers/thermal/tegra_soctherm.c b/drivers/thermal/tegra_soctherm.c +index 9197fc0..74ea576 100644 +--- a/drivers/thermal/tegra_soctherm.c ++++ b/drivers/thermal/tegra_soctherm.c +@@ -293,7 +293,7 @@ static int enable_tsensor(struct tegra_soctherm *tegra, + * H denotes an addition of 0.5 Celsius and N denotes negation + * of the final value. + */ +-static long translate_temp(u16 val) ++static int translate_temp(u16 val) + { + long t; + +@@ -306,7 +306,7 @@ static long translate_temp(u16 val) + return t; + } + +-static int tegra_thermctl_get_temp(void *data, long *out_temp) ++static int tegra_thermctl_get_temp(void *data, int *out_temp) + { + struct tegra_thermctl_zone *zone = data; + u32 val; +diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c +index 4108db7..62cc82a 100644 +--- a/drivers/thermal/thermal_core.c ++++ b/drivers/thermal/thermal_core.c +@@ -363,7 +363,7 @@ static void handle_non_critical_trips(struct thermal_zone_device *tz, + static void handle_critical_trips(struct thermal_zone_device *tz, + int trip, enum thermal_trip_type trip_type) + { +- long trip_temp; ++ int trip_temp; + + tz->ops->get_trip_temp(tz, trip, &trip_temp); + +@@ -411,12 +411,12 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip) + * + * Return: On success returns 0, an error code otherwise + */ +-int thermal_zone_get_temp(struct thermal_zone_device *tz, unsigned long *temp) ++int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp) + { + int ret = -EINVAL; + #ifdef CONFIG_THERMAL_EMULATION + int count; +- unsigned long crit_temp = -1UL; ++ int crit_temp = INT_MAX; + enum thermal_trip_type type; + #endif + +@@ -453,8 +453,7 @@ EXPORT_SYMBOL_GPL(thermal_zone_get_temp); + + static void update_temperature(struct thermal_zone_device *tz) + { +- long temp; +- int ret; ++ int temp, ret; + + ret = thermal_zone_get_temp(tz, &temp); + if (ret) { +@@ -514,15 +513,14 @@ static ssize_t + temp_show(struct device *dev, struct device_attribute *attr, char *buf) + { + struct thermal_zone_device *tz = to_thermal_zone(dev); +- long temperature; +- int ret; ++ int temperature, ret; + + ret = thermal_zone_get_temp(tz, &temperature); + + if (ret) + return ret; + +- return sprintf(buf, "%ld\n", temperature); ++ return sprintf(buf, "%d\n", temperature); + } + + static ssize_t +@@ -626,7 +624,7 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr, + { + struct thermal_zone_device *tz = to_thermal_zone(dev); + int trip, ret; +- long temperature; ++ int temperature; + + if (!tz->ops->get_trip_temp) + return -EPERM; +@@ -639,7 +637,7 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr, + if (ret) + return ret; + +- return sprintf(buf, "%ld\n", temperature); ++ return sprintf(buf, "%d\n", temperature); + } + + static ssize_t +@@ -648,7 +646,7 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr, + { + struct thermal_zone_device *tz = to_thermal_zone(dev); + int trip, ret; +- unsigned long temperature; ++ int temperature; + + if (!tz->ops->set_trip_hyst) + return -EPERM; +@@ -656,7 +654,7 @@ trip_point_hyst_store(struct device *dev, struct device_attribute *attr, + if (!sscanf(attr->attr.name, "trip_point_%d_hyst", &trip)) + return -EINVAL; + +- if (kstrtoul(buf, 10, &temperature)) ++ if (kstrtoint(buf, 10, &temperature)) + return -EINVAL; + + /* +@@ -675,7 +673,7 @@ trip_point_hyst_show(struct device *dev, struct device_attribute *attr, + { + struct thermal_zone_device *tz = to_thermal_zone(dev); + int trip, ret; +- unsigned long temperature; ++ int temperature; + + if (!tz->ops->get_trip_hyst) + return -EPERM; +@@ -685,7 +683,7 @@ trip_point_hyst_show(struct device *dev, struct device_attribute *attr, + + ret = tz->ops->get_trip_hyst(tz, trip, &temperature); + +- return ret ? ret : sprintf(buf, "%ld\n", temperature); ++ return ret ? ret : sprintf(buf, "%d\n", temperature); + } + + static ssize_t +diff --git a/drivers/thermal/thermal_hwmon.c b/drivers/thermal/thermal_hwmon.c +index 1967bee..06fd2ed9 100644 +--- a/drivers/thermal/thermal_hwmon.c ++++ b/drivers/thermal/thermal_hwmon.c +@@ -69,7 +69,7 @@ static DEVICE_ATTR(name, 0444, name_show, NULL); + static ssize_t + temp_input_show(struct device *dev, struct device_attribute *attr, char *buf) + { +- long temperature; ++ int temperature; + int ret; + struct thermal_hwmon_attr *hwmon_attr + = container_of(attr, struct thermal_hwmon_attr, attr); +@@ -83,7 +83,7 @@ temp_input_show(struct device *dev, struct device_attribute *attr, char *buf) + if (ret) + return ret; + +- return sprintf(buf, "%ld\n", temperature); ++ return sprintf(buf, "%d\n", temperature); + } + + static ssize_t +@@ -95,14 +95,14 @@ temp_crit_show(struct device *dev, struct device_attribute *attr, char *buf) + = container_of(hwmon_attr, struct thermal_hwmon_temp, + temp_crit); + struct thermal_zone_device *tz = temp->tz; +- long temperature; ++ int temperature; + int ret; + + ret = tz->ops->get_trip_temp(tz, 0, &temperature); + if (ret) + return ret; + +- return sprintf(buf, "%ld\n", temperature); ++ return sprintf(buf, "%d\n", temperature); + } + + +@@ -142,7 +142,7 @@ thermal_hwmon_lookup_temp(const struct thermal_hwmon_device *hwmon, + + static bool thermal_zone_crit_temp_valid(struct thermal_zone_device *tz) + { +- unsigned long temp; ++ int temp; + return tz->ops->get_crit_temp && !tz->ops->get_crit_temp(tz, &temp); + } + +diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c +index a38c175..d3a42bf 100644 +--- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c ++++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c +@@ -76,14 +76,14 @@ static inline int ti_thermal_hotspot_temperature(int t, int s, int c) + + /* thermal zone ops */ + /* Get temperature callback function for thermal zone*/ +-static inline int __ti_thermal_get_temp(void *devdata, long *temp) ++static inline int __ti_thermal_get_temp(void *devdata, int *temp) + { + struct thermal_zone_device *pcb_tz = NULL; + struct ti_thermal_data *data = devdata; + struct ti_bandgap *bgp; + const struct ti_temp_sensor *s; + int ret, tmp, slope, constant; +- unsigned long pcb_temp; ++ int pcb_temp; + + if (!data) + return 0; +@@ -119,7 +119,7 @@ static inline int __ti_thermal_get_temp(void *devdata, long *temp) + } + + static inline int ti_thermal_get_temp(struct thermal_zone_device *thermal, +- unsigned long *temp) ++ int *temp) + { + struct ti_thermal_data *data = thermal->devdata; + +@@ -228,7 +228,7 @@ static int ti_thermal_get_trip_type(struct thermal_zone_device *thermal, + + /* Get trip temperature callback functions for thermal zone */ + static int ti_thermal_get_trip_temp(struct thermal_zone_device *thermal, +- int trip, unsigned long *temp) ++ int trip, int *temp) + { + if (!ti_thermal_is_valid_trip(trip)) + return -EINVAL; +@@ -279,7 +279,7 @@ static int ti_thermal_get_trend(struct thermal_zone_device *thermal, + + /* Get critical temperature callback functions for thermal zone */ + static int ti_thermal_get_crit_temp(struct thermal_zone_device *thermal, +- unsigned long *temp) ++ int *temp) + { + /* shutdown zone */ + return ti_thermal_get_trip_temp(thermal, OMAP_TRIP_NUMBER - 1, temp); +diff --git a/drivers/thermal/x86_pkg_temp_thermal.c b/drivers/thermal/x86_pkg_temp_thermal.c +index 9ea3d9d..054c6d45 100644 +--- a/drivers/thermal/x86_pkg_temp_thermal.c ++++ b/drivers/thermal/x86_pkg_temp_thermal.c +@@ -164,7 +164,7 @@ err_ret: + return err; + } + +-static int sys_get_curr_temp(struct thermal_zone_device *tzd, unsigned long *temp) ++static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp) + { + u32 eax, edx; + struct phy_dev_entry *phy_dev_entry; +@@ -175,7 +175,7 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, unsigned long *tem + if (eax & 0x80000000) { + *temp = phy_dev_entry->tj_max - + ((eax >> 16) & 0x7f) * 1000; +- pr_debug("sys_get_curr_temp %ld\n", *temp); ++ pr_debug("sys_get_curr_temp %d\n", *temp); + return 0; + } + +@@ -183,7 +183,7 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, unsigned long *tem + } + + static int sys_get_trip_temp(struct thermal_zone_device *tzd, +- int trip, unsigned long *temp) ++ int trip, int *temp) + { + u32 eax, edx; + struct phy_dev_entry *phy_dev_entry; +@@ -214,13 +214,13 @@ static int sys_get_trip_temp(struct thermal_zone_device *tzd, + *temp = phy_dev_entry->tj_max - thres_reg_value * 1000; + else + *temp = 0; +- pr_debug("sys_get_trip_temp %ld\n", *temp); ++ pr_debug("sys_get_trip_temp %d\n", *temp); + + return 0; + } + + static int sys_set_trip_temp(struct thermal_zone_device *tzd, int trip, +- unsigned long temp) ++ int temp) + { + u32 l, h; + struct phy_dev_entry *phy_dev_entry; +diff --git a/include/linux/thermal.h b/include/linux/thermal.h +index 5eac316..e9f2863 100644 +--- a/include/linux/thermal.h ++++ b/include/linux/thermal.h +@@ -86,23 +86,19 @@ struct thermal_zone_device_ops { + struct thermal_cooling_device *); + int (*unbind) (struct thermal_zone_device *, + struct thermal_cooling_device *); +- int (*get_temp) (struct thermal_zone_device *, unsigned long *); ++ int (*get_temp) (struct thermal_zone_device *, int *); + int (*get_mode) (struct thermal_zone_device *, + enum thermal_device_mode *); + int (*set_mode) (struct thermal_zone_device *, + enum thermal_device_mode); + int (*get_trip_type) (struct thermal_zone_device *, int, + enum thermal_trip_type *); +- int (*get_trip_temp) (struct thermal_zone_device *, int, +- unsigned long *); +- int (*set_trip_temp) (struct thermal_zone_device *, int, +- unsigned long); +- int (*get_trip_hyst) (struct thermal_zone_device *, int, +- unsigned long *); +- int (*set_trip_hyst) (struct thermal_zone_device *, int, +- unsigned long); +- int (*get_crit_temp) (struct thermal_zone_device *, unsigned long *); +- int (*set_emul_temp) (struct thermal_zone_device *, unsigned long); ++ int (*get_trip_temp) (struct thermal_zone_device *, int, int *); ++ int (*set_trip_temp) (struct thermal_zone_device *, int, int); ++ int (*get_trip_hyst) (struct thermal_zone_device *, int, int *); ++ int (*set_trip_hyst) (struct thermal_zone_device *, int, int); ++ int (*get_crit_temp) (struct thermal_zone_device *, int *); ++ int (*set_emul_temp) (struct thermal_zone_device *, int); + int (*get_trend) (struct thermal_zone_device *, int, + enum thermal_trend *); + int (*notify) (struct thermal_zone_device *, int, +@@ -272,9 +268,9 @@ struct thermal_genl_event { + * temperature. + */ + struct thermal_zone_of_device_ops { +- int (*get_temp)(void *, long *); ++ int (*get_temp)(void *, int *); + int (*get_trend)(void *, long *); +- int (*set_emul_temp)(void *, unsigned long); ++ int (*set_emul_temp)(void *, int); + }; + + /** +@@ -335,7 +331,7 @@ thermal_of_cooling_device_register(struct device_node *np, char *, void *, + const struct thermal_cooling_device_ops *); + void thermal_cooling_device_unregister(struct thermal_cooling_device *); + struct thermal_zone_device *thermal_zone_get_zone_by_name(const char *name); +-int thermal_zone_get_temp(struct thermal_zone_device *tz, unsigned long *temp); ++int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp); + + int get_tz_trend(struct thermal_zone_device *, int); + struct thermal_instance *get_thermal_instance(struct thermal_zone_device *, +@@ -378,7 +374,7 @@ static inline struct thermal_zone_device *thermal_zone_get_zone_by_name( + const char *name) + { return ERR_PTR(-ENODEV); } + static inline int thermal_zone_get_temp( +- struct thermal_zone_device *tz, unsigned long *temp) ++ struct thermal_zone_device *tz, int *temp) + { return -ENODEV; } + static inline int get_tz_trend(struct thermal_zone_device *tz, int trip) + { return -ENODEV; } +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0011-thermal-trivial-fix-typo-in-comment.patch b/target/linux/mediatek/patches/0011-thermal-trivial-fix-typo-in-comment.patch new file mode 100644 index 0000000000..4b9e0f9514 --- /dev/null +++ b/target/linux/mediatek/patches/0011-thermal-trivial-fix-typo-in-comment.patch @@ -0,0 +1,27 @@ +From a2214b951a1102ad2a2a72b6ae6e71c148f8249f Mon Sep 17 00:00:00 2001 +From: Sascha Hauer <s.hauer@pengutronix.de> +Date: Wed, 13 May 2015 10:52:30 +0200 +Subject: [PATCH 11/76] thermal: trivial: fix typo in comment + +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +Acked-by: Eduardo Valentin <edubezval@gmail.com> +--- + drivers/thermal/thermal_core.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c +index 62cc82a..244784f 100644 +--- a/drivers/thermal/thermal_core.c ++++ b/drivers/thermal/thermal_core.c +@@ -402,7 +402,7 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip) + } + + /** +- * thermal_zone_get_temp() - returns its the temperature of thermal zone ++ * thermal_zone_get_temp() - returns the temperature of a thermal zone + * @tz: a valid pointer to a struct thermal_zone_device + * @temp: a valid pointer to where to store the resulting temperature. + * +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0012-thermal-remove-useless-call-to-thermal_zone_device_s.patch b/target/linux/mediatek/patches/0012-thermal-remove-useless-call-to-thermal_zone_device_s.patch new file mode 100644 index 0000000000..2d64f4949c --- /dev/null +++ b/target/linux/mediatek/patches/0012-thermal-remove-useless-call-to-thermal_zone_device_s.patch @@ -0,0 +1,34 @@ +From 41adcc8cf217dfb4b70c2da061e70034b3c9add0 Mon Sep 17 00:00:00 2001 +From: Sascha Hauer <s.hauer@pengutronix.de> +Date: Wed, 13 May 2015 10:52:31 +0200 +Subject: [PATCH 12/76] thermal: remove useless call to + thermal_zone_device_set_polling + +When the thermal zone has no get_temp callback then thermal_zone_device_register() +calls thermal_zone_device_set_polling() with a polling delay of 0. This +only cancels the poll_queue. Since the poll_queue hasn't been scheduled this +is a no-op. Remove it. + +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +Acked-by: Eduardo Valentin <edubezval@gmail.com> +--- + drivers/thermal/thermal_core.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c +index 244784f..1b68d20 100644 +--- a/drivers/thermal/thermal_core.c ++++ b/drivers/thermal/thermal_core.c +@@ -1571,9 +1571,6 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type, + + INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check); + +- if (!tz->ops->get_temp) +- thermal_zone_device_set_polling(tz, 0); +- + thermal_zone_device_update(tz); + + return tz; +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0013-thermal-Use-IS_ENABLED-instead-of-ifdef.patch b/target/linux/mediatek/patches/0013-thermal-Use-IS_ENABLED-instead-of-ifdef.patch new file mode 100644 index 0000000000..0b033d65e1 --- /dev/null +++ b/target/linux/mediatek/patches/0013-thermal-Use-IS_ENABLED-instead-of-ifdef.patch @@ -0,0 +1,106 @@ +From bddcae2b66a23bfb6d381d089b0b862235480a9b Mon Sep 17 00:00:00 2001 +From: Sascha Hauer <s.hauer@pengutronix.de> +Date: Wed, 13 May 2015 10:52:32 +0200 +Subject: [PATCH 13/76] thermal: Use IS_ENABLED instead of #ifdef + +Use IS_ENABLED(CONFIG_THERMAL_EMULATION) to make the code more readable +and to get rid of the addtional #ifdef around the variable definitions +in thermal_zone_get_temp(). + +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +--- + drivers/thermal/thermal_core.c | 45 +++++++++++++++++----------------------- + 1 file changed, 19 insertions(+), 26 deletions(-) + +diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c +index 1b68d20..3e0fe55 100644 +--- a/drivers/thermal/thermal_core.c ++++ b/drivers/thermal/thermal_core.c +@@ -414,11 +414,9 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip) + int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp) + { + int ret = -EINVAL; +-#ifdef CONFIG_THERMAL_EMULATION + int count; + int crit_temp = INT_MAX; + enum thermal_trip_type type; +-#endif + + if (!tz || IS_ERR(tz) || !tz->ops->get_temp) + goto exit; +@@ -426,25 +424,21 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp) + mutex_lock(&tz->lock); + + ret = tz->ops->get_temp(tz, temp); +-#ifdef CONFIG_THERMAL_EMULATION +- if (!tz->emul_temperature) +- goto skip_emul; +- +- for (count = 0; count < tz->trips; count++) { +- ret = tz->ops->get_trip_type(tz, count, &type); +- if (!ret && type == THERMAL_TRIP_CRITICAL) { +- ret = tz->ops->get_trip_temp(tz, count, &crit_temp); +- break; +- } +- } + +- if (ret) +- goto skip_emul; ++ if (IS_ENABLED(CONFIG_THERMAL_EMULATION) && tz->emul_temperature) { ++ for (count = 0; count < tz->trips; count++) { ++ ret = tz->ops->get_trip_type(tz, count, &type); ++ if (!ret && type == THERMAL_TRIP_CRITICAL) { ++ ret = tz->ops->get_trip_temp(tz, count, ++ &crit_temp); ++ break; ++ } ++ } + +- if (*temp < crit_temp) +- *temp = tz->emul_temperature; +-skip_emul: +-#endif ++ if (!ret && *temp < crit_temp) ++ *temp = tz->emul_temperature; ++ } ++ + mutex_unlock(&tz->lock); + exit: + return ret; +@@ -780,7 +774,6 @@ policy_show(struct device *dev, struct device_attribute *devattr, char *buf) + return sprintf(buf, "%s\n", tz->governor->name); + } + +-#ifdef CONFIG_THERMAL_EMULATION + static ssize_t + emul_temp_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +@@ -806,7 +799,6 @@ emul_temp_store(struct device *dev, struct device_attribute *attr, + return ret ? ret : count; + } + static DEVICE_ATTR(emul_temp, S_IWUSR, NULL, emul_temp_store); +-#endif/*CONFIG_THERMAL_EMULATION*/ + + static DEVICE_ATTR(type, 0444, type_show, NULL); + static DEVICE_ATTR(temp, 0444, temp_show, NULL); +@@ -1536,11 +1528,12 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type, + goto unregister; + } + +-#ifdef CONFIG_THERMAL_EMULATION +- result = device_create_file(&tz->device, &dev_attr_emul_temp); +- if (result) +- goto unregister; +-#endif ++ if (IS_ENABLED(CONFIG_THERMAL_EMULATION)) { ++ result = device_create_file(&tz->device, &dev_attr_emul_temp); ++ if (result) ++ goto unregister; ++ } ++ + /* Create policy attribute */ + result = device_create_file(&tz->device, &dev_attr_policy); + if (result) +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0014-thermal-Add-comment-explaining-test-for-critical-tem.patch b/target/linux/mediatek/patches/0014-thermal-Add-comment-explaining-test-for-critical-tem.patch new file mode 100644 index 0000000000..56d3e4f21e --- /dev/null +++ b/target/linux/mediatek/patches/0014-thermal-Add-comment-explaining-test-for-critical-tem.patch @@ -0,0 +1,34 @@ +From 18f50eae474edc716b01959fad6898c8553b131c Mon Sep 17 00:00:00 2001 +From: Sascha Hauer <s.hauer@pengutronix.de> +Date: Wed, 13 May 2015 10:52:33 +0200 +Subject: [PATCH 14/76] thermal: Add comment explaining test for critical + temperature + +The code testing if a temperature should be emulated or not is +not obvious. Add a comment explaining why this test is done. + +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com> +--- + drivers/thermal/thermal_core.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c +index 3e0fe55..e204deb 100644 +--- a/drivers/thermal/thermal_core.c ++++ b/drivers/thermal/thermal_core.c +@@ -435,6 +435,11 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp) + } + } + ++ /* ++ * Only allow emulating a temperature when the real temperature ++ * is below the critical temperature so that the emulation code ++ * cannot hide critical conditions. ++ */ + if (!ret && *temp < crit_temp) + *temp = tz->emul_temperature; + } +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0015-thermal-inline-only-once-used-function.patch b/target/linux/mediatek/patches/0015-thermal-inline-only-once-used-function.patch new file mode 100644 index 0000000000..e050ae763a --- /dev/null +++ b/target/linux/mediatek/patches/0015-thermal-inline-only-once-used-function.patch @@ -0,0 +1,53 @@ +From 0b729a98127ef045096edf20dfe5c4eadac21d44 Mon Sep 17 00:00:00 2001 +From: Sascha Hauer <s.hauer@pengutronix.de> +Date: Wed, 13 May 2015 10:52:34 +0200 +Subject: [PATCH 15/76] thermal: inline only once used function + +Inline update_temperature into its only caller to make the code +more readable. + +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com> +--- + drivers/thermal/thermal_core.c | 17 +++++------------ + 1 file changed, 5 insertions(+), 12 deletions(-) + +diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c +index e204deb..19da022 100644 +--- a/drivers/thermal/thermal_core.c ++++ b/drivers/thermal/thermal_core.c +@@ -450,9 +450,12 @@ exit: + } + EXPORT_SYMBOL_GPL(thermal_zone_get_temp); + +-static void update_temperature(struct thermal_zone_device *tz) ++void thermal_zone_device_update(struct thermal_zone_device *tz) + { +- int temp, ret; ++ int temp, ret, count; ++ ++ if (!tz->ops->get_temp) ++ return; + + ret = thermal_zone_get_temp(tz, &temp); + if (ret) { +@@ -471,16 +474,6 @@ static void update_temperature(struct thermal_zone_device *tz) + trace_thermal_temperature(tz); + dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n", + tz->last_temperature, tz->temperature); +-} +- +-void thermal_zone_device_update(struct thermal_zone_device *tz) +-{ +- int count; +- +- if (!tz->ops->get_temp) +- return; +- +- update_temperature(tz); + + for (count = 0; count < tz->trips; count++) + handle_thermal_trip(tz, count); +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0016-thermal-streamline-get_trend-callbacks.patch b/target/linux/mediatek/patches/0016-thermal-streamline-get_trend-callbacks.patch new file mode 100644 index 0000000000..99d490f2bb --- /dev/null +++ b/target/linux/mediatek/patches/0016-thermal-streamline-get_trend-callbacks.patch @@ -0,0 +1,123 @@ +From 5da86f6a2b4c2c318e153649dc8fd34fe73f8292 Mon Sep 17 00:00:00 2001 +From: Sascha Hauer <s.hauer@pengutronix.de> +Date: Wed, 13 May 2015 10:52:35 +0200 +Subject: [PATCH 16/76] thermal: streamline get_trend callbacks + +The .get_trend callback in struct thermal_zone_device_ops has the prototype: + + int (*get_trend) (struct thermal_zone_device *, int, + enum thermal_trend *); + +whereas the .get_trend callback in struct thermal_zone_of_device_ops has: + + int (*get_trend)(void *, long *); + +Streamline both prototypes and add the trip argument to the OF callback +aswell and use enum thermal_trend * instead of an integer pointer. + +While the OF prototype may be the better one, this should be decided at +framework level and not on OF level. + +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +--- + drivers/thermal/of-thermal.c | 11 +-------- + drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 25 +++++++------------- + include/linux/thermal.h | 2 +- + 3 files changed, 10 insertions(+), 28 deletions(-) + +diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c +index 03839df..c84404d 100644 +--- a/drivers/thermal/of-thermal.c ++++ b/drivers/thermal/of-thermal.c +@@ -187,24 +187,15 @@ static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip, + enum thermal_trend *trend) + { + struct __thermal_zone *data = tz->devdata; +- long dev_trend; + int r; + + if (!data->ops->get_trend) + return -EINVAL; + +- r = data->ops->get_trend(data->sensor_data, &dev_trend); ++ r = data->ops->get_trend(data->sensor_data, trip, trend); + if (r) + return r; + +- /* TODO: These intervals might have some thresholds, but in core code */ +- if (dev_trend > 0) +- *trend = THERMAL_TREND_RAISING; +- else if (dev_trend < 0) +- *trend = THERMAL_TREND_DROPPING; +- else +- *trend = THERMAL_TREND_STABLE; +- + return 0; + } + +diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c +index d3a42bf..ade78eb 100644 +--- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c ++++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c +@@ -238,7 +238,7 @@ static int ti_thermal_get_trip_temp(struct thermal_zone_device *thermal, + return 0; + } + +-static int __ti_thermal_get_trend(void *p, long *trend) ++static int __ti_thermal_get_trend(void *p, int trip, enum thermal_trend *trend) + { + struct ti_thermal_data *data = p; + struct ti_bandgap *bgp; +@@ -251,22 +251,6 @@ static int __ti_thermal_get_trend(void *p, long *trend) + if (ret) + return ret; + +- *trend = tr; +- +- return 0; +-} +- +-/* Get the temperature trend callback functions for thermal zone */ +-static int ti_thermal_get_trend(struct thermal_zone_device *thermal, +- int trip, enum thermal_trend *trend) +-{ +- int ret; +- long tr; +- +- ret = __ti_thermal_get_trend(thermal->devdata, &tr); +- if (ret) +- return ret; +- + if (tr > 0) + *trend = THERMAL_TREND_RAISING; + else if (tr < 0) +@@ -277,6 +261,13 @@ static int ti_thermal_get_trend(struct thermal_zone_device *thermal, + return 0; + } + ++/* Get the temperature trend callback functions for thermal zone */ ++static int ti_thermal_get_trend(struct thermal_zone_device *thermal, ++ int trip, enum thermal_trend *trend) ++{ ++ return __ti_thermal_get_trend(thermal->devdata, trip, trend); ++} ++ + /* Get critical temperature callback functions for thermal zone */ + static int ti_thermal_get_crit_temp(struct thermal_zone_device *thermal, + int *temp) +diff --git a/include/linux/thermal.h b/include/linux/thermal.h +index e9f2863..5c6a589 100644 +--- a/include/linux/thermal.h ++++ b/include/linux/thermal.h +@@ -269,7 +269,7 @@ struct thermal_genl_event { + */ + struct thermal_zone_of_device_ops { + int (*get_temp)(void *, int *); +- int (*get_trend)(void *, long *); ++ int (*get_trend)(void *, int, enum thermal_trend *); + int (*set_emul_temp)(void *, int); + }; + +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0017-thermal-Allow-sensor-ops-to-fail-with-ENOSYS.patch b/target/linux/mediatek/patches/0017-thermal-Allow-sensor-ops-to-fail-with-ENOSYS.patch new file mode 100644 index 0000000000..f533a88319 --- /dev/null +++ b/target/linux/mediatek/patches/0017-thermal-Allow-sensor-ops-to-fail-with-ENOSYS.patch @@ -0,0 +1,90 @@ +From 5b622cb2d6ff44b1fb0750beee61f93f2c00548a Mon Sep 17 00:00:00 2001 +From: Sascha Hauer <s.hauer@pengutronix.de> +Date: Wed, 13 May 2015 10:52:36 +0200 +Subject: [PATCH 17/76] thermal: Allow sensor ops to fail with -ENOSYS + +The thermal core uses the existence of the .get_temp, .get_trend and +.set_emul_temp to detect whether this operation exists and should be +used or whether it should be emulated in software. This makes problems +for of-thermal which has to modify the struct thermal_zone_device_ops +during runtime whenever a sensor is registered or unregistered. + +Let the core test for -ENOSYS from these callbacks and treat it like +if the callbacks were not present. + +This allows of-thermal to always set the sensor related callbacks and +to make struct thermal_zone_device_ops const again. + +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +--- + drivers/thermal/thermal_core.c | 24 +++++++++++++++++------- + 1 file changed, 17 insertions(+), 7 deletions(-) + +diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c +index 19da022..3d8f9f9 100644 +--- a/drivers/thermal/thermal_core.c ++++ b/drivers/thermal/thermal_core.c +@@ -413,13 +413,16 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip) + */ + int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp) + { +- int ret = -EINVAL; ++ int ret; + int count; + int crit_temp = INT_MAX; + enum thermal_trip_type type; + +- if (!tz || IS_ERR(tz) || !tz->ops->get_temp) +- goto exit; ++ if (!tz || IS_ERR(tz)) ++ return -EINVAL; ++ ++ if (!tz->ops->get_temp) ++ return -ENOSYS; + + mutex_lock(&tz->lock); + +@@ -445,7 +448,7 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp) + } + + mutex_unlock(&tz->lock); +-exit: ++ + return ret; + } + EXPORT_SYMBOL_GPL(thermal_zone_get_temp); +@@ -454,10 +457,11 @@ void thermal_zone_device_update(struct thermal_zone_device *tz) + { + int temp, ret, count; + +- if (!tz->ops->get_temp) ++ ret = thermal_zone_get_temp(tz, &temp); ++ ++ if (ret == -ENOSYS) + return; + +- ret = thermal_zone_get_temp(tz, &temp); + if (ret) { + if (ret != -EAGAIN) + dev_warn(&tz->device, +@@ -783,10 +787,16 @@ emul_temp_store(struct device *dev, struct device_attribute *attr, + if (kstrtoul(buf, 10, &temperature)) + return -EINVAL; + +- if (!tz->ops->set_emul_temp) { ++ if (tz->ops->set_emul_temp) ++ ret = tz->ops->set_emul_temp(tz, temperature); ++ else ++ ret = -ENOSYS; ++ ++ if (ret == -ENOSYS) { + mutex_lock(&tz->lock); + tz->emul_temperature = temperature; + mutex_unlock(&tz->lock); ++ ret = 0; + } else { + ret = tz->ops->set_emul_temp(tz, temperature); + } +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0018-thermal-of-always-set-sensor-related-callbacks.patch b/target/linux/mediatek/patches/0018-thermal-of-always-set-sensor-related-callbacks.patch new file mode 100644 index 0000000000..e47e8a27f0 --- /dev/null +++ b/target/linux/mediatek/patches/0018-thermal-of-always-set-sensor-related-callbacks.patch @@ -0,0 +1,129 @@ +From 8c9c4ed500e92c10dc4965dcd00692b3102a328a Mon Sep 17 00:00:00 2001 +From: Sascha Hauer <s.hauer@pengutronix.de> +Date: Wed, 13 May 2015 10:52:37 +0200 +Subject: [PATCH 18/76] thermal: of: always set sensor related callbacks + +Now that the thermal core treats -ENOSYS like the callbacks were +not present at all we no longer have to overwrite the ops during +runtime but instead can always set them and return -ENOSYS if no +sensor is registered. + +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +--- + drivers/thermal/of-thermal.c | 33 +++++++++++++-------------------- + 1 file changed, 13 insertions(+), 20 deletions(-) + +diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c +index c84404d..b9c35bd 100644 +--- a/drivers/thermal/of-thermal.c ++++ b/drivers/thermal/of-thermal.c +@@ -91,7 +91,7 @@ static int of_thermal_get_temp(struct thermal_zone_device *tz, + { + struct __thermal_zone *data = tz->devdata; + +- if (!data->ops->get_temp) ++ if (!data->ops) + return -EINVAL; + + return data->ops->get_temp(data->sensor_data, temp); +@@ -178,7 +178,7 @@ static int of_thermal_set_emul_temp(struct thermal_zone_device *tz, + struct __thermal_zone *data = tz->devdata; + + if (!data->ops || !data->ops->set_emul_temp) +- return -EINVAL; ++ return -ENOSYS; + + return data->ops->set_emul_temp(data->sensor_data, temp); + } +@@ -189,8 +189,8 @@ static int of_thermal_get_trend(struct thermal_zone_device *tz, int trip, + struct __thermal_zone *data = tz->devdata; + int r; + +- if (!data->ops->get_trend) +- return -EINVAL; ++ if (!data->ops || !data->ops->get_trend) ++ return -ENOSYS; + + r = data->ops->get_trend(data->sensor_data, trip, trend); + if (r) +@@ -366,6 +366,10 @@ static int of_thermal_get_crit_temp(struct thermal_zone_device *tz, + } + + static struct thermal_zone_device_ops of_thermal_ops = { ++ .get_temp = of_thermal_get_temp, ++ .get_trend = of_thermal_get_trend, ++ .set_emul_temp = of_thermal_set_emul_temp, ++ + .get_mode = of_thermal_get_mode, + .set_mode = of_thermal_set_mode, + +@@ -399,13 +403,13 @@ thermal_zone_of_add_sensor(struct device_node *zone, + if (!ops) + return ERR_PTR(-EINVAL); + ++ if (!ops->get_temp) ++ return ERR_PTR(-EINVAL); ++ + mutex_lock(&tzd->lock); + tz->ops = ops; + tz->sensor_data = data; + +- tzd->ops->get_temp = of_thermal_get_temp; +- tzd->ops->get_trend = of_thermal_get_trend; +- tzd->ops->set_emul_temp = of_thermal_set_emul_temp; + mutex_unlock(&tzd->lock); + + return tzd; +@@ -535,9 +539,6 @@ void thermal_zone_of_sensor_unregister(struct device *dev, + return; + + mutex_lock(&tzd->lock); +- tzd->ops->get_temp = NULL; +- tzd->ops->get_trend = NULL; +- tzd->ops->set_emul_temp = NULL; + + tz->ops = NULL; + tz->sensor_data = NULL; +@@ -845,7 +846,6 @@ int __init of_parse_thermal_zones(void) + { + struct device_node *np, *child; + struct __thermal_zone *tz; +- struct thermal_zone_device_ops *ops; + + np = of_find_node_by_name(NULL, "thermal-zones"); + if (!np) { +@@ -869,29 +869,22 @@ int __init of_parse_thermal_zones(void) + continue; + } + +- ops = kmemdup(&of_thermal_ops, sizeof(*ops), GFP_KERNEL); +- if (!ops) +- goto exit_free; +- + tzp = kzalloc(sizeof(*tzp), GFP_KERNEL); +- if (!tzp) { +- kfree(ops); ++ if (!tzp) + goto exit_free; +- } + + /* No hwmon because there might be hwmon drivers registering */ + tzp->no_hwmon = true; + + zone = thermal_zone_device_register(child->name, tz->ntrips, + 0, tz, +- ops, tzp, ++ &of_thermal_ops, tzp, + tz->passive_delay, + tz->polling_delay); + if (IS_ERR(zone)) { + pr_err("Failed to build %s zone %ld\n", child->name, + PTR_ERR(zone)); + kfree(tzp); +- kfree(ops); + of_thermal_free_zone(tz); + /* attempting to build remaining zones still */ + } +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0019-thermal-Make-struct-thermal_zone_device_ops-const.patch b/target/linux/mediatek/patches/0019-thermal-Make-struct-thermal_zone_device_ops-const.patch new file mode 100644 index 0000000000..1ca9ab8c2f --- /dev/null +++ b/target/linux/mediatek/patches/0019-thermal-Make-struct-thermal_zone_device_ops-const.patch @@ -0,0 +1,327 @@ +From 7cbee588bc6eee59c025f89cf9324943fda98934 Mon Sep 17 00:00:00 2001 +From: Sascha Hauer <s.hauer@pengutronix.de> +Date: Wed, 13 May 2015 10:52:38 +0200 +Subject: [PATCH 19/76] thermal: Make struct thermal_zone_device_ops const + +Now that the of thermal support no longer changes the +thermal_zone_device_ops it can be const again. + +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +--- + Documentation/thermal/sysfs-api.txt | 2 +- + drivers/acpi/thermal.c | 2 +- + drivers/platform/x86/acerhdf.c | 2 +- + drivers/platform/x86/intel_mid_thermal.c | 2 +- + drivers/power/power_supply_core.c | 2 +- + drivers/thermal/armada_thermal.c | 2 +- + drivers/thermal/db8500_thermal.c | 2 +- + drivers/thermal/dove_thermal.c | 2 +- + drivers/thermal/imx_thermal.c | 2 +- + drivers/thermal/int340x_thermal/int3400_thermal.c | 2 +- + drivers/thermal/int340x_thermal/int340x_thermal_zone.c | 2 +- + drivers/thermal/intel_soc_dts_thermal.c | 2 +- + drivers/thermal/kirkwood_thermal.c | 2 +- + drivers/thermal/of-thermal.c | 2 +- + drivers/thermal/rcar_thermal.c | 2 +- + drivers/thermal/spear_thermal.c | 2 +- + drivers/thermal/st/st_thermal.c | 2 +- + drivers/thermal/thermal_core.c | 2 +- + drivers/thermal/ti-soc-thermal/ti-thermal-common.c | 2 +- + drivers/thermal/x86_pkg_temp_thermal.c | 2 +- + include/linux/thermal.h | 6 +++--- + 21 files changed, 23 insertions(+), 23 deletions(-) + +diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-api.txt +index 87519cb..bb346a2 100644 +--- a/Documentation/thermal/sysfs-api.txt ++++ b/Documentation/thermal/sysfs-api.txt +@@ -33,7 +33,7 @@ temperature) and throttle appropriate devices. + 1.1 thermal zone device interface + 1.1.1 struct thermal_zone_device *thermal_zone_device_register(char *type, + int trips, int mask, void *devdata, +- struct thermal_zone_device_ops *ops, ++ const struct thermal_zone_device_ops *ops, + const struct thermal_zone_params *tzp, + int passive_delay, int polling_delay)) + +diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c +index 68bff60..6b11462 100644 +--- a/drivers/acpi/thermal.c ++++ b/drivers/acpi/thermal.c +@@ -869,7 +869,7 @@ acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal, + return acpi_thermal_cooling_device_cb(thermal, cdev, false); + } + +-static struct thermal_zone_device_ops acpi_thermal_zone_ops = { ++static const struct thermal_zone_device_ops acpi_thermal_zone_ops = { + .bind = acpi_thermal_bind_cooling_device, + .unbind = acpi_thermal_unbind_cooling_device, + .get_temp = thermal_get_temp, +diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c +index f2ce63c..bae9ca0 100644 +--- a/drivers/platform/x86/acerhdf.c ++++ b/drivers/platform/x86/acerhdf.c +@@ -482,7 +482,7 @@ static int acerhdf_get_crit_temp(struct thermal_zone_device *thermal, + } + + /* bind callback functions to thermalzone */ +-static struct thermal_zone_device_ops acerhdf_dev_ops = { ++static const struct thermal_zone_device_ops acerhdf_dev_ops = { + .bind = acerhdf_bind, + .unbind = acerhdf_unbind, + .get_temp = acerhdf_get_ec_temp, +diff --git a/drivers/platform/x86/intel_mid_thermal.c b/drivers/platform/x86/intel_mid_thermal.c +index 0944e83..069d36b 100644 +--- a/drivers/platform/x86/intel_mid_thermal.c ++++ b/drivers/platform/x86/intel_mid_thermal.c +@@ -460,7 +460,7 @@ static int read_curr_temp(struct thermal_zone_device *tzd, unsigned long *temp) + } + + /* Can't be const */ +-static struct thermal_zone_device_ops tzd_ops = { ++static const struct thermal_zone_device_ops tzd_ops = { + .get_temp = read_curr_temp, + }; + +diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c +index 87e2fd1..878cb4e 100644 +--- a/drivers/power/power_supply_core.c ++++ b/drivers/power/power_supply_core.c +@@ -509,7 +509,7 @@ static int power_supply_read_temp(struct thermal_zone_device *tzd, + return ret; + } + +-static struct thermal_zone_device_ops psy_tzd_ops = { ++static const struct thermal_zone_device_ops psy_tzd_ops = { + .get_temp = power_supply_read_temp, + }; + +diff --git a/drivers/thermal/armada_thermal.c b/drivers/thermal/armada_thermal.c +index 26b8d32..3f59c8b 100644 +--- a/drivers/thermal/armada_thermal.c ++++ b/drivers/thermal/armada_thermal.c +@@ -183,7 +183,7 @@ static int armada_get_temp(struct thermal_zone_device *thermal, + return 0; + } + +-static struct thermal_zone_device_ops ops = { ++static const struct thermal_zone_device_ops ops = { + .get_temp = armada_get_temp, + }; + +diff --git a/drivers/thermal/db8500_thermal.c b/drivers/thermal/db8500_thermal.c +index b3eca71..38d6aab9 100644 +--- a/drivers/thermal/db8500_thermal.c ++++ b/drivers/thermal/db8500_thermal.c +@@ -210,7 +210,7 @@ static int db8500_sys_get_crit_temp(struct thermal_zone_device *thermal, + return -EINVAL; + } + +-static struct thermal_zone_device_ops thdev_ops = { ++static const struct thermal_zone_device_ops thdev_ops = { + .bind = db8500_cdev_bind, + .unbind = db8500_cdev_unbind, + .get_temp = db8500_sys_get_temp, +diff --git a/drivers/thermal/dove_thermal.c b/drivers/thermal/dove_thermal.c +index a0bc9de..e8fd627 100644 +--- a/drivers/thermal/dove_thermal.c ++++ b/drivers/thermal/dove_thermal.c +@@ -118,7 +118,7 @@ static int dove_get_temp(struct thermal_zone_device *thermal, + return 0; + } + +-static struct thermal_zone_device_ops ops = { ++static const struct thermal_zone_device_ops ops = { + .get_temp = dove_get_temp, + }; + +diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c +index f1424f0..8a3cfed 100644 +--- a/drivers/thermal/imx_thermal.c ++++ b/drivers/thermal/imx_thermal.c +@@ -332,7 +332,7 @@ static int imx_unbind(struct thermal_zone_device *tz, + return 0; + } + +-static struct thermal_zone_device_ops imx_tz_ops = { ++static const struct thermal_zone_device_ops imx_tz_ops = { + .bind = imx_bind, + .unbind = imx_unbind, + .get_temp = imx_get_temp, +diff --git a/drivers/thermal/int340x_thermal/int3400_thermal.c b/drivers/thermal/int340x_thermal/int3400_thermal.c +index 031018e..96bdf8a 100644 +--- a/drivers/thermal/int340x_thermal/int3400_thermal.c ++++ b/drivers/thermal/int340x_thermal/int3400_thermal.c +@@ -231,7 +231,7 @@ static int int3400_thermal_set_mode(struct thermal_zone_device *thermal, + return result; + } + +-static struct thermal_zone_device_ops int3400_thermal_ops = { ++static const struct thermal_zone_device_ops int3400_thermal_ops = { + .get_temp = int3400_thermal_get_temp, + }; + +diff --git a/drivers/thermal/int340x_thermal/int340x_thermal_zone.c b/drivers/thermal/int340x_thermal/int340x_thermal_zone.c +index b9b2666..bd9f9e8 100644 +--- a/drivers/thermal/int340x_thermal/int340x_thermal_zone.c ++++ b/drivers/thermal/int340x_thermal/int340x_thermal_zone.c +@@ -154,7 +154,7 @@ static int int340x_thermal_get_trip_hyst(struct thermal_zone_device *zone, + return 0; + } + +-static struct thermal_zone_device_ops int340x_thermal_zone_ops = { ++static const struct thermal_zone_device_ops int340x_thermal_zone_ops = { + .get_temp = int340x_thermal_get_zone_temp, + .get_trip_temp = int340x_thermal_get_trip_temp, + .get_trip_type = int340x_thermal_get_trip_type, +diff --git a/drivers/thermal/intel_soc_dts_thermal.c b/drivers/thermal/intel_soc_dts_thermal.c +index fd550b9..625ba6f 100644 +--- a/drivers/thermal/intel_soc_dts_thermal.c ++++ b/drivers/thermal/intel_soc_dts_thermal.c +@@ -270,7 +270,7 @@ static int sys_get_curr_temp(struct thermal_zone_device *tzd, int *temp) + return 0; + } + +-static struct thermal_zone_device_ops tzone_ops = { ++static const struct thermal_zone_device_ops tzone_ops = { + .get_temp = sys_get_curr_temp, + .get_trip_temp = sys_get_trip_temp, + .get_trip_type = sys_get_trip_type, +diff --git a/drivers/thermal/kirkwood_thermal.c b/drivers/thermal/kirkwood_thermal.c +index 11041fe..abba3e2 100644 +--- a/drivers/thermal/kirkwood_thermal.c ++++ b/drivers/thermal/kirkwood_thermal.c +@@ -60,7 +60,7 @@ static int kirkwood_get_temp(struct thermal_zone_device *thermal, + return 0; + } + +-static struct thermal_zone_device_ops ops = { ++static const struct thermal_zone_device_ops ops = { + .get_temp = kirkwood_get_temp, + }; + +diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c +index b9c35bd..bd3185e 100644 +--- a/drivers/thermal/of-thermal.c ++++ b/drivers/thermal/of-thermal.c +@@ -365,7 +365,7 @@ static int of_thermal_get_crit_temp(struct thermal_zone_device *tz, + return -EINVAL; + } + +-static struct thermal_zone_device_ops of_thermal_ops = { ++static const struct thermal_zone_device_ops of_thermal_ops = { + .get_temp = of_thermal_get_temp, + .get_trend = of_thermal_get_trend, + .set_emul_temp = of_thermal_set_emul_temp, +diff --git a/drivers/thermal/rcar_thermal.c b/drivers/thermal/rcar_thermal.c +index 5d4ae7d..320ceac 100644 +--- a/drivers/thermal/rcar_thermal.c ++++ b/drivers/thermal/rcar_thermal.c +@@ -270,7 +270,7 @@ static int rcar_thermal_notify(struct thermal_zone_device *zone, + return 0; + } + +-static struct thermal_zone_device_ops rcar_thermal_zone_ops = { ++static const struct thermal_zone_device_ops rcar_thermal_zone_ops = { + .get_temp = rcar_thermal_get_temp, + .get_trip_type = rcar_thermal_get_trip_type, + .get_trip_temp = rcar_thermal_get_trip_temp, +diff --git a/drivers/thermal/spear_thermal.c b/drivers/thermal/spear_thermal.c +index 534dd91..ec07743 100644 +--- a/drivers/thermal/spear_thermal.c ++++ b/drivers/thermal/spear_thermal.c +@@ -50,7 +50,7 @@ static inline int thermal_get_temp(struct thermal_zone_device *thermal, + return 0; + } + +-static struct thermal_zone_device_ops ops = { ++static const struct thermal_zone_device_ops ops = { + .get_temp = thermal_get_temp, + }; + +diff --git a/drivers/thermal/st/st_thermal.c b/drivers/thermal/st/st_thermal.c +index 44cbba9..0cb5c19 100644 +--- a/drivers/thermal/st/st_thermal.c ++++ b/drivers/thermal/st/st_thermal.c +@@ -175,7 +175,7 @@ static int st_thermal_get_trip_temp(struct thermal_zone_device *th, + return 0; + } + +-static struct thermal_zone_device_ops st_tz_ops = { ++static const struct thermal_zone_device_ops st_tz_ops = { + .get_temp = st_thermal_get_temp, + .get_trip_type = st_thermal_get_trip_type, + .get_trip_temp = st_thermal_get_trip_temp, +diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c +index 3d8f9f9..6bbf61f 100644 +--- a/drivers/thermal/thermal_core.c ++++ b/drivers/thermal/thermal_core.c +@@ -1451,7 +1451,7 @@ static void remove_trip_attrs(struct thermal_zone_device *tz) + */ + struct thermal_zone_device *thermal_zone_device_register(const char *type, + int trips, int mask, void *devdata, +- struct thermal_zone_device_ops *ops, ++ const struct thermal_zone_device_ops *ops, + const struct thermal_zone_params *tzp, + int passive_delay, int polling_delay) + { +diff --git a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c +index ade78eb..e9c82fc 100644 +--- a/drivers/thermal/ti-soc-thermal/ti-thermal-common.c ++++ b/drivers/thermal/ti-soc-thermal/ti-thermal-common.c +@@ -281,7 +281,7 @@ static const struct thermal_zone_of_device_ops ti_of_thermal_ops = { + .get_trend = __ti_thermal_get_trend, + }; + +-static struct thermal_zone_device_ops ti_thermal_ops = { ++static const struct thermal_zone_device_ops ti_thermal_ops = { + .get_temp = ti_thermal_get_temp, + .get_trend = ti_thermal_get_trend, + .bind = ti_thermal_bind, +diff --git a/drivers/thermal/x86_pkg_temp_thermal.c b/drivers/thermal/x86_pkg_temp_thermal.c +index 054c6d45..bb2b975 100644 +--- a/drivers/thermal/x86_pkg_temp_thermal.c ++++ b/drivers/thermal/x86_pkg_temp_thermal.c +@@ -274,7 +274,7 @@ static int sys_get_trip_type(struct thermal_zone_device *thermal, + } + + /* Thermal zone callback registry */ +-static struct thermal_zone_device_ops tzone_ops = { ++static const struct thermal_zone_device_ops tzone_ops = { + .get_temp = sys_get_curr_temp, + .get_trip_temp = sys_get_trip_temp, + .get_trip_type = sys_get_trip_type, +diff --git a/include/linux/thermal.h b/include/linux/thermal.h +index 5c6a589..07bd5e8 100644 +--- a/include/linux/thermal.h ++++ b/include/linux/thermal.h +@@ -181,7 +181,7 @@ struct thermal_zone_device { + int emul_temperature; + int passive; + unsigned int forced_passive; +- struct thermal_zone_device_ops *ops; ++ const struct thermal_zone_device_ops *ops; + const struct thermal_zone_params *tzp; + struct thermal_governor *governor; + struct list_head thermal_instances; +@@ -313,7 +313,7 @@ void thermal_zone_of_sensor_unregister(struct device *dev, + + #if IS_ENABLED(CONFIG_THERMAL) + struct thermal_zone_device *thermal_zone_device_register(const char *, int, int, +- void *, struct thermal_zone_device_ops *, ++ void *, const struct thermal_zone_device_ops *, + const struct thermal_zone_params *, int, int); + void thermal_zone_device_unregister(struct thermal_zone_device *); + +@@ -341,7 +341,7 @@ void thermal_notify_framework(struct thermal_zone_device *, int); + #else + static inline struct thermal_zone_device *thermal_zone_device_register( + const char *type, int trips, int mask, void *devdata, +- struct thermal_zone_device_ops *ops, ++ const struct thermal_zone_device_ops *ops, + const struct thermal_zone_params *tzp, + int passive_delay, int polling_delay) + { return ERR_PTR(-ENODEV); } +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0020-thermal-thermal-Add-support-for-hardware-tracked-tri.patch b/target/linux/mediatek/patches/0020-thermal-thermal-Add-support-for-hardware-tracked-tri.patch new file mode 100644 index 0000000000..6a48350039 --- /dev/null +++ b/target/linux/mediatek/patches/0020-thermal-thermal-Add-support-for-hardware-tracked-tri.patch @@ -0,0 +1,124 @@ +From 346632bc00fe71c269709702fecb474bb22e933e Mon Sep 17 00:00:00 2001 +From: Sascha Hauer <s.hauer@pengutronix.de> +Date: Wed, 13 May 2015 10:52:39 +0200 +Subject: [PATCH 20/76] thermal: thermal: Add support for hardware-tracked + trip points + +This adds support for hardware-tracked trip points to the device tree +thermal sensor framework. + +The framework supports an arbitrary number of trip points. Whenever +the current temperature is updated, the trip points immediately +below and above the current temperature are found. A .set_trips +callback is then called with the temperatures. If there is no trip +point above or below the current temperature, the passed trip +temperature will be -INT_MAX or INT_MAX respectively. In this callback, +the driver should program the hardware such that it is notified +when either of these trip points are triggered. When a trip point +is triggered, the driver should call `thermal_zone_device_update' +for the respective thermal zone. This will cause the trip points +to be updated again. + +If .set_trips is not implemented, the framework behaves as before. + +This patch is based on an earlier version from Mikko Perttunen +<mikko.perttunen@kapsi.fi> + +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +--- + drivers/thermal/thermal_core.c | 43 ++++++++++++++++++++++++++++++++++++++++ + include/linux/thermal.h | 3 +++ + 2 files changed, 46 insertions(+) + +diff --git a/drivers/thermal/thermal_core.c b/drivers/thermal/thermal_core.c +index 6bbf61f..3ae1795 100644 +--- a/drivers/thermal/thermal_core.c ++++ b/drivers/thermal/thermal_core.c +@@ -453,6 +453,45 @@ int thermal_zone_get_temp(struct thermal_zone_device *tz, int *temp) + } + EXPORT_SYMBOL_GPL(thermal_zone_get_temp); + ++static void thermal_zone_set_trips(struct thermal_zone_device *tz) ++{ ++ int low = -INT_MAX; ++ int high = INT_MAX; ++ int trip_temp, hysteresis; ++ int temp = tz->temperature; ++ int i; ++ ++ if (!tz->ops->set_trips) ++ return; ++ ++ /* No need to change trip points */ ++ if (temp > tz->prev_low_trip && temp < tz->prev_high_trip) ++ return; ++ ++ for (i = 0; i < tz->trips; i++) { ++ int trip_low; ++ ++ tz->ops->get_trip_temp(tz, i, &trip_temp); ++ tz->ops->get_trip_hyst(tz, i, &hysteresis); ++ ++ trip_low = trip_temp - hysteresis; ++ ++ if (trip_low < temp && trip_low > low) ++ low = trip_low; ++ ++ if (trip_temp > temp && trip_temp < high) ++ high = trip_temp; ++ } ++ ++ tz->prev_low_trip = low; ++ tz->prev_high_trip = high; ++ ++ dev_dbg(&tz->device, "new temperature boundaries: %d < x < %d\n", ++ low, high); ++ ++ tz->ops->set_trips(tz, low, high); ++} ++ + void thermal_zone_device_update(struct thermal_zone_device *tz) + { + int temp, ret, count; +@@ -479,6 +518,8 @@ void thermal_zone_device_update(struct thermal_zone_device *tz) + dev_dbg(&tz->device, "last_temperature=%d, current_temperature=%d\n", + tz->last_temperature, tz->temperature); + ++ thermal_zone_set_trips(tz); ++ + for (count = 0; count < tz->trips; count++) + handle_thermal_trip(tz, count); + } +@@ -1494,6 +1535,8 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type, + tz->trips = trips; + tz->passive_delay = passive_delay; + tz->polling_delay = polling_delay; ++ tz->prev_low_trip = INT_MAX; ++ tz->prev_high_trip = -INT_MAX; + + dev_set_name(&tz->device, "thermal_zone%d", tz->id); + result = device_register(&tz->device); +diff --git a/include/linux/thermal.h b/include/linux/thermal.h +index 07bd5e8..aef6e13 100644 +--- a/include/linux/thermal.h ++++ b/include/linux/thermal.h +@@ -87,6 +87,7 @@ struct thermal_zone_device_ops { + int (*unbind) (struct thermal_zone_device *, + struct thermal_cooling_device *); + int (*get_temp) (struct thermal_zone_device *, int *); ++ int (*set_trips) (struct thermal_zone_device *, int, int); + int (*get_mode) (struct thermal_zone_device *, + enum thermal_device_mode *); + int (*set_mode) (struct thermal_zone_device *, +@@ -180,6 +181,8 @@ struct thermal_zone_device { + int last_temperature; + int emul_temperature; + int passive; ++ int prev_low_trip; ++ int prev_high_trip; + unsigned int forced_passive; + const struct thermal_zone_device_ops *ops; + const struct thermal_zone_params *tzp; +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0021-thermal-of-implement-.set_trips-for-device-tree-ther.patch b/target/linux/mediatek/patches/0021-thermal-of-implement-.set_trips-for-device-tree-ther.patch new file mode 100644 index 0000000000..81b50431c6 --- /dev/null +++ b/target/linux/mediatek/patches/0021-thermal-of-implement-.set_trips-for-device-tree-ther.patch @@ -0,0 +1,65 @@ +From 525f68bb9d9f6334dbcd2b5ec99f9d797ff53618 Mon Sep 17 00:00:00 2001 +From: Sascha Hauer <s.hauer@pengutronix.de> +Date: Wed, 13 May 2015 10:52:40 +0200 +Subject: [PATCH 21/76] thermal: of: implement .set_trips for device tree + thermal zones + +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +--- + drivers/thermal/of-thermal.c | 12 ++++++++++++ + include/linux/thermal.h | 3 +++ + 2 files changed, 15 insertions(+) + +diff --git a/drivers/thermal/of-thermal.c b/drivers/thermal/of-thermal.c +index bd3185e..f8dd847 100644 +--- a/drivers/thermal/of-thermal.c ++++ b/drivers/thermal/of-thermal.c +@@ -97,6 +97,17 @@ static int of_thermal_get_temp(struct thermal_zone_device *tz, + return data->ops->get_temp(data->sensor_data, temp); + } + ++static int of_thermal_set_trips(struct thermal_zone_device *tz, ++ int low, int high) ++{ ++ struct __thermal_zone *data = tz->devdata; ++ ++ if (!data->ops || !data->ops->set_trips) ++ return -ENOSYS; ++ ++ return data->ops->set_trips(data->sensor_data, low, high); ++} ++ + /** + * of_thermal_get_ntrips - function to export number of available trip + * points. +@@ -367,6 +378,7 @@ static int of_thermal_get_crit_temp(struct thermal_zone_device *tz, + + static const struct thermal_zone_device_ops of_thermal_ops = { + .get_temp = of_thermal_get_temp, ++ .set_trips = of_thermal_set_trips, + .get_trend = of_thermal_get_trend, + .set_emul_temp = of_thermal_set_emul_temp, + +diff --git a/include/linux/thermal.h b/include/linux/thermal.h +index aef6e13..b751f6b 100644 +--- a/include/linux/thermal.h ++++ b/include/linux/thermal.h +@@ -267,12 +267,15 @@ struct thermal_genl_event { + * + * Optional: + * @get_trend: a pointer to a function that reads the sensor temperature trend. ++ * @set_trips: a pointer to a function that sets a temperature window which shall ++ * trigger an interrupt when it is left. + * @set_emul_temp: a pointer to a function that sets sensor emulated + * temperature. + */ + struct thermal_zone_of_device_ops { + int (*get_temp)(void *, int *); + int (*get_trend)(void *, int, enum thermal_trend *); ++ int (*set_trips)(void *, int, int); + int (*set_emul_temp)(void *, int); + }; + +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0022-dt-bindings-thermal-Add-binding-document-for-Mediate.patch b/target/linux/mediatek/patches/0022-dt-bindings-thermal-Add-binding-document-for-Mediate.patch new file mode 100644 index 0000000000..c556ac08b5 --- /dev/null +++ b/target/linux/mediatek/patches/0022-dt-bindings-thermal-Add-binding-document-for-Mediate.patch @@ -0,0 +1,57 @@ +From 9b799b8a4ecbf560f8fb996e8e5147a8f7b9a1b3 Mon Sep 17 00:00:00 2001 +From: Sascha Hauer <s.hauer@pengutronix.de> +Date: Wed, 13 May 2015 10:52:41 +0200 +Subject: [PATCH 22/76] dt-bindings: thermal: Add binding document for + Mediatek thermal controller + +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +--- + .../bindings/thermal/mediatek-thermal.txt | 36 ++++++++++++++++++++ + 1 file changed, 36 insertions(+) + create mode 100644 Documentation/devicetree/bindings/thermal/mediatek-thermal.txt + +diff --git a/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt +new file mode 100644 +index 0000000..adf5d2c +--- /dev/null ++++ b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt +@@ -0,0 +1,36 @@ ++* Mediatek Thermal ++ ++This describes the device tree binding for the Mediatek thermal controller ++which measures the on-SoC temperatures. This device does not have its own ADC, ++instead it directly controls the AUXADC via AHB bus accesses. For this reason ++this device needs phandles to the AUXADC. ++ ++Required properties: ++- compatible: "mediatek,mt8173-thermal" ++- reg: Address range of the thermal controller ++- interrupts: IRQ for the thermal controller ++- clocks, clock-names: Clocks needed for the thermal controller. required ++ clocks are: ++ "therm": Main clock needed for register access ++ "auxadc": The AUXADC clock ++- resets, reset-names: Reference to the reset controller controlling the thermal ++ controller. Required reset-names: ++ "therm": The main reset line ++- auxadc: A phandle to the AUXADC which the thermal controller uses ++- apmixedsys: A phandle to the APMIXEDSYS controller. ++- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description ++ ++Example: ++ ++ thermal: thermal@1100b000 { ++ #thermal-sensor-cells = <1>; ++ compatible = "mediatek,mt8173-thermal"; ++ reg = <0 0x1100b000 0 0x1000>; ++ interrupts = <0 70 IRQ_TYPE_LEVEL_LOW>; ++ clocks = <&pericfg CLK_PERI_THERM>, <&pericfg CLK_PERI_AUXADC>; ++ clock-names = "therm", "auxadc"; ++ resets = <&pericfg MT8173_PERI_THERM_SW_RST>; ++ reset-names = "therm"; ++ auxadc = <&auxadc>; ++ apmixedsys = <&apmixedsys>; ++ }; +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0023-thermal-Add-Mediatek-thermal-controller-support.patch b/target/linux/mediatek/patches/0023-thermal-Add-Mediatek-thermal-controller-support.patch new file mode 100644 index 0000000000..827d721138 --- /dev/null +++ b/target/linux/mediatek/patches/0023-thermal-Add-Mediatek-thermal-controller-support.patch @@ -0,0 +1,785 @@ +From 014330a304100782a26bc7df02778c8c386b2857 Mon Sep 17 00:00:00 2001 +From: Sascha Hauer <s.hauer@pengutronix.de> +Date: Wed, 13 May 2015 10:52:42 +0200 +Subject: [PATCH 23/76] thermal: Add Mediatek thermal controller support + +This adds support for the Mediatek thermal controller found on MT8173 +and likely other SoCs. +The controller is a bit special. It does not have its own ADC, instead +it controls the on-SoC AUXADC via AHB bus accesses. For this reason +we need the physical address of the AUXADC. Also it controls a mux +using AHB bus accesses, so we need the APMIXEDSYS physical address aswell. + +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +--- + drivers/thermal/Kconfig | 8 + + drivers/thermal/Makefile | 1 + + drivers/thermal/mtk_thermal.c | 728 +++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 737 insertions(+) + create mode 100644 drivers/thermal/mtk_thermal.c + +diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig +index af40db0..3aa5500 100644 +--- a/drivers/thermal/Kconfig ++++ b/drivers/thermal/Kconfig +@@ -285,6 +285,14 @@ config ACPI_THERMAL_REL + tristate + depends on ACPI + ++config MTK_THERMAL ++ tristate "Temperature sensor driver for mediatek SoCs" ++ depends on ARCH_MEDIATEK || COMPILE_TEST ++ default y ++ help ++ Enable this option if you want to have support for thermal management ++ controller present in Mediatek SoCs ++ + menu "Texas Instruments thermal drivers" + source "drivers/thermal/ti-soc-thermal/Kconfig" + endmenu +diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile +index fa0dc48..51cfab7 100644 +--- a/drivers/thermal/Makefile ++++ b/drivers/thermal/Makefile +@@ -39,3 +39,4 @@ obj-$(CONFIG_TI_SOC_THERMAL) += ti-soc-thermal/ + obj-$(CONFIG_INT340X_THERMAL) += int340x_thermal/ + obj-$(CONFIG_ST_THERMAL) += st/ + obj-$(CONFIG_TEGRA_SOCTHERM) += tegra_soctherm.o ++obj-$(CONFIG_MTK_THERMAL) += mtk_thermal.o +diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c +new file mode 100644 +index 0000000..27aab12 +--- /dev/null ++++ b/drivers/thermal/mtk_thermal.c +@@ -0,0 +1,728 @@ ++/* ++ * Copyright (c) 2014 MediaTek Inc. ++ * Author: Hanyi.Wu <hanyi.wu@mediatek.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/dmi.h> ++#include <linux/thermal.h> ++#include <linux/platform_device.h> ++#include <linux/types.h> ++#include <linux/delay.h> ++#include <linux/slab.h> ++#include <linux/clk.h> ++#include <linux/time.h> ++#include <linux/of.h> ++#include <linux/of_irq.h> ++#include <linux/of_address.h> ++#include <linux/interrupt.h> ++#include <linux/reset.h> ++ ++/* AUXADC Registers */ ++#define AUXADC_CON0_V 0x000 ++#define AUXADC_CON1_V 0x004 ++#define AUXADC_CON1_SET_V 0x008 ++#define AUXADC_CON1_CLR_V 0x00c ++#define AUXADC_CON2_V 0x010 ++#define AUXADC_DATA(channel) (0x14 + (channel) * 4) ++#define AUXADC_MISC_V 0x094 ++ ++#define AUXADC_CON1_CHANNEL(x) (1 << (x)) ++ ++/* Thermal Controller Registers */ ++#define TEMPMONCTL0 0x000 ++#define TEMPMONCTL1 0x004 ++#define TEMPMONCTL2 0x008 ++#define TEMPMONINT 0x00c ++#define TEMPMONINTSTS 0x010 ++#define TEMPMONIDET0 0x014 ++#define TEMPMONIDET1 0x018 ++#define TEMPMONIDET2 0x01c ++#define TEMPH2NTHRE 0x024 ++#define TEMPHTHRE 0x028 ++#define TEMPCTHRE 0x02c ++#define TEMPOFFSETH 0x030 ++#define TEMPOFFSETL 0x034 ++#define TEMPMSRCTL0 0x038 ++#define TEMPMSRCTL1 0x03c ++#define TEMPAHBPOLL 0x040 ++#define TEMPAHBTO 0x044 ++#define TEMPADCPNP0 0x048 ++#define TEMPADCPNP1 0x04c ++#define TEMPADCPNP2 0x050 ++#define TEMPADCPNP3 0x0b4 ++ ++#define TEMPADCMUX 0x054 ++#define TEMPADCEXT 0x058 ++#define TEMPADCEXT1 0x05c ++#define TEMPADCEN 0x060 ++#define TEMPPNPMUXADDR 0x064 ++#define TEMPADCMUXADDR 0x068 ++#define TEMPADCEXTADDR 0x06c ++#define TEMPADCEXT1ADDR 0x070 ++#define TEMPADCENADDR 0x074 ++#define TEMPADCVALIDADDR 0x078 ++#define TEMPADCVOLTADDR 0x07c ++#define TEMPRDCTRL 0x080 ++#define TEMPADCVALIDMASK 0x084 ++#define TEMPADCVOLTAGESHIFT 0x088 ++#define TEMPADCWRITECTRL 0x08c ++#define TEMPMSR0 0x090 ++#define TEMPMSR1 0x094 ++#define TEMPMSR2 0x098 ++#define TEMPMSR3 0x0B8 ++ ++#define TEMPIMMD0 0x0a0 ++#define TEMPIMMD1 0x0a4 ++#define TEMPIMMD2 0x0a8 ++ ++#define TEMPPROTCTL 0x0c0 ++#define TEMPPROTTA 0x0c4 ++#define TEMPPROTTB 0x0c8 ++#define TEMPPROTTC 0x0cc ++ ++#define TEMPSPARE0 0x0f0 ++#define TEMPSPARE1 0x0f4 ++#define TEMPSPARE2 0x0f8 ++#define TEMPSPARE3 0x0fc ++ ++#define PTPCORESEL 0x400 ++#define THERMINTST 0x404 ++#define PTPODINTST 0x408 ++#define THSTAGE0ST 0x40c ++#define THSTAGE1ST 0x410 ++#define THSTAGE2ST 0x414 ++#define THAHBST0 0x418 ++#define THAHBST1 0x41c /* Only for DE debug */ ++#define PTPSPARE0 0x420 ++#define PTPSPARE1 0x424 ++#define PTPSPARE2 0x428 ++#define PTPSPARE3 0x42c ++#define THSLPEVEB 0x430 ++ ++#define TEMPMONINT_COLD(sp) ((1 << 0) << ((sp) * 5)) ++#define TEMPMONINT_HOT(sp) ((1 << 1) << ((sp) * 5)) ++#define TEMPMONINT_LOW_OFS(sp) ((1 << 2) << ((sp) * 5)) ++#define TEMPMONINT_HIGH_OFS(sp) ((1 << 3) << ((sp) * 5)) ++#define TEMPMONINT_HOT_TO_NORM(sp) ((1 << 4) << ((sp) * 5)) ++#define TEMPMONINT_TIMEOUT (1 << 15) ++#define TEMPMONINT_IMMEDIATE_SENSE(sp) (1 << (16 + (sp))) ++#define TEMPMONINT_FILTER_SENSE(sp) (1 << (19 + (sp))) ++ ++#define TEMPADCWRITECTRL_ADC_PNP_WRITE (1 << 0) ++#define TEMPADCWRITECTRL_ADC_MUX_WRITE (1 << 1) ++#define TEMPADCWRITECTRL_ADC_EXTRA_WRITE (1 << 2) ++#define TEMPADCWRITECTRL_ADC_EXTRA1_WRITE (1 << 3) ++ ++#define TEMPADCVALIDMASK_VALID_HIGH (1 << 5) ++#define TEMPADCVALIDMASK_VALID_POS(bit) (bit) ++ ++#define TEMPPROTCTL_AVERAGE (0 << 16) ++#define TEMPPROTCTL_MAXIMUM (1 << 16) ++#define TEMPPROTCTL_SELECTED (2 << 16) ++ ++#define MT8173_THERMAL_ZONE_CA57 0 ++#define MT8173_THERMAL_ZONE_CA53 1 ++#define MT8173_THERMAL_ZONE_GPU 2 ++#define MT8173_THERMAL_ZONE_CORE 3 ++ ++#define MT8173_TS1 0 ++#define MT8173_TS2 1 ++#define MT8173_TS3 2 ++#define MT8173_TS4 3 ++#define MT8173_TSABB 4 ++ ++/* AUXADC channel 11 is used for the temperature sensors */ ++#define MT8173_TEMP_AUXADC_CHANNEL 11 ++ ++/* The total number of temperature sensors in the MT8173 */ ++#define MT8173_NUM_SENSORS 5 ++ ++/* The number of banks in the MT8173 */ ++#define MT8173_NUM_BANKS 4 ++ ++/* The number of sensing points per bank */ ++#define MT8173_NUM_SENSING_POINTS 4 ++ ++#define THERMAL_NAME "mtk-thermal" ++ ++struct mtk_thermal; ++ ++struct mtk_thermal_bank { ++ struct mtk_thermal *mt; ++ struct thermal_zone_device *tz; ++ int id; ++}; ++ ++struct mtk_thermal { ++ struct device *dev; ++ void __iomem *thermal_base; ++ void __iomem *auxadc_base; ++ ++ u64 auxadc_phys_base; ++ u64 apmixed_phys_base; ++ struct reset_control *reset; ++ struct clk *clk_peri_therm; ++ struct clk *clk_auxadc; ++ ++ struct mtk_thermal_bank banks[MT8173_NUM_BANKS]; ++ ++ struct mutex lock; ++ ++ /* Calibration values */ ++ s32 adc_ge; ++ s32 adc_oe; ++ s32 degc_cali; ++ s32 o_slope; ++ s32 vts; ++}; ++ ++struct mtk_thermal_bank_cfg { ++ unsigned int enable_mask; ++ unsigned int sensors[4]; ++}; ++ ++static int sensor_mux_values[MT8173_NUM_SENSORS] = { 0, 1, 2, 3, 16 }; ++ ++/* ++ * The MT8173 thermal controller has four banks. Each bank can read up to ++ * four temperature sensors simultaneously. The MT8173 has a total of 5 ++ * temperature sensors. We use each bank to measure a certain area of the ++ * SoC. Since TS2 is located centrally in the SoC it is influenced by multiple ++ * areas, hence is used in different banks. ++ */ ++static struct mtk_thermal_bank_cfg bank_data[] = { ++ { ++ .enable_mask = 3, ++ .sensors = { MT8173_TS2, MT8173_TS3 }, ++ }, { ++ .enable_mask = 3, ++ .sensors = { MT8173_TS2, MT8173_TS4 }, ++ }, { ++ .enable_mask = 7, ++ .sensors = { MT8173_TS1, MT8173_TS2, MT8173_TSABB }, ++ }, { ++ .enable_mask = 1, ++ .sensors = { MT8173_TS2 }, ++ }, ++}; ++ ++static int tempmsr_ofs[MT8173_NUM_SENSING_POINTS] = { ++ TEMPMSR0, TEMPMSR1, TEMPMSR2, TEMPMSR3 ++}; ++ ++static int tempadcpnp_ofs[MT8173_NUM_SENSING_POINTS] = { ++ TEMPADCPNP0, TEMPADCPNP1, TEMPADCPNP2, TEMPADCPNP3 ++}; ++ ++/** ++ * raw_to_mcelsius - convert a raw ADC value to mcelsius ++ * @mt: The thermal controller ++ * @raw: raw ADC value ++ * ++ * This converts the raw ADC value to mcelsius using the SoC specific ++ * calibration constants ++ */ ++static int raw_to_mcelsius(struct mtk_thermal *mt, u32 raw) ++{ ++ s32 format_1, format_2, format_3, format_4; ++ s32 xtoomt; ++ s32 gain; ++ ++ raw &= 0xfff; ++ ++ gain = (10000 + mt->adc_ge); ++ ++ xtoomt = ((((mt->vts + 3350 - mt->adc_oe) * 10000) / 4096) * 10000) / ++ gain; ++ ++ format_1 = ((mt->degc_cali * 10) >> 1); ++ format_2 = (raw - mt->adc_oe); ++ format_3 = (((((format_2) * 10000) >> 12) * 10000) / gain) - xtoomt; ++ format_3 = format_3 * 15 / 18; ++ format_4 = ((format_3 * 100) / (165 + mt->o_slope)); ++ format_4 = format_4 - (format_4 << 1); ++ ++ return (format_1 + format_4) * 100; ++} ++ ++/** ++ * mcelsius_to_raw - convert mcelsius to raw ADC value ++ * @mt: The thermal controller ++ * @temp: The temperature in mcelsius ++ * ++ * This converts a temperature in mcelsius to a raw ADC value, needed to ++ * calculate the trigger values for interrupt generation. ++ */ ++static u32 mcelsius_to_raw(struct mtk_thermal *mt, int temp) ++{ ++ s32 format_1, format_2, format_3, format_4; ++ s32 xtoomt; ++ s32 gain; ++ ++ gain = (10000 + mt->adc_ge); ++ ++ xtoomt = ((((mt->vts + 3350 - mt->adc_oe) * 10000) / 4096) * 10000) / ++ gain; ++ ++ format_1 = temp - (mt->degc_cali * 1000 / 2); ++ format_2 = format_1 * (165 + mt->o_slope) * 18 / 15; ++ format_2 = format_2 - 2 * format_2; ++ format_3 = format_2 / 1000 + xtoomt * 10; ++ format_4 = (format_3 * 4096 / 10000 * gain) / 100000 + mt->adc_oe; ++ ++ return format_4; ++} ++ ++/** ++ * mtk_thermal_get_bank - get bank ++ * @bank: The bank ++ * ++ * The bank registers are banked, we have to select a bank in the ++ * PTPCORESEL register to access it. ++ */ ++static void mtk_thermal_get_bank(struct mtk_thermal_bank *bank) ++{ ++ struct mtk_thermal *mt = bank->mt; ++ u32 val; ++ ++ mutex_lock(&mt->lock); ++ ++ val = readl(mt->thermal_base + PTPCORESEL); ++ val &= ~0xf; ++ val |= bank->id; ++ writel(val, mt->thermal_base + PTPCORESEL); ++} ++ ++/** ++ * mtk_thermal_put_bank - release bank ++ * @bank: The bank ++ * ++ * release a bank previously taken with mtk_thermal_get_bank, ++ */ ++static void mtk_thermal_put_bank(struct mtk_thermal_bank *bank) ++{ ++ struct mtk_thermal *mt = bank->mt; ++ ++ mutex_unlock(&mt->lock); ++} ++ ++/** ++ * mtk_thermal_bank_temperature - get the temperature of a bank ++ * @bank: The bank ++ * ++ * The temperature of a bank is considered the maximum temperature of ++ * the sensors associated to the bank. ++ */ ++static int mtk_thermal_bank_temperature(struct mtk_thermal_bank *bank) ++{ ++ struct mtk_thermal *mt = bank->mt; ++ int temp, i, max; ++ u32 raw; ++ ++ temp = max = -INT_MAX; ++ ++ for (i = 0; i < 4; i++) { ++ int sensno; ++ ++ if (!(bank_data[bank->id].enable_mask & (1 << i))) ++ continue; ++ ++ raw = readl(mt->thermal_base + tempmsr_ofs[i]); ++ ++ sensno = bank_data[bank->id].sensors[i]; ++ temp = raw_to_mcelsius(mt, raw); ++ ++ if (temp > max) ++ max = temp; ++ } ++ ++ return max; ++} ++ ++static void mtk_thermal_irq_bank(struct mtk_thermal_bank *bank) ++{ ++ struct mtk_thermal *mt = bank->mt; ++ int sp; ++ u32 irqstat; ++ bool update = false; ++ ++ mtk_thermal_get_bank(bank); ++ ++ irqstat = readl(mt->thermal_base + TEMPMONINTSTS); ++ ++ mtk_thermal_put_bank(bank); ++ ++ for (sp = 0; sp < 3; sp++) { ++ if (irqstat & TEMPMONINT_LOW_OFS(sp)) { ++ update = true; ++ dev_vdbg(mt->dev, "bank %d sensor %d low offset interrupt\n", ++ bank->id, sp); ++ } ++ ++ if (irqstat & TEMPMONINT_HIGH_OFS(sp)) { ++ update = true; ++ dev_vdbg(mt->dev, "bank %d sensor %d high offset interrupt\n", ++ bank->id, sp); ++ } ++ } ++ ++ if (update) ++ thermal_zone_device_update(bank->tz); ++} ++ ++static irqreturn_t mtk_thermal_irq(int irq, void *dev_id) ++{ ++ struct mtk_thermal *mt = dev_id; ++ u32 irqstat = 0; ++ int i; ++ ++ irqstat = readl(mt->thermal_base + THERMINTST); ++ ++ dev_vdbg(mt->dev, "thermal_interrupt_handler : THERMINTST = 0x%x\n", ++ irqstat); ++ ++ for (i = 0; i < MT8173_NUM_BANKS; i++) { ++ if (!(irqstat & (1 << i))) ++ mtk_thermal_irq_bank(&mt->banks[i]); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static int mtk_read_temp(void *data, int *temp) ++{ ++ struct mtk_thermal_bank *bank = data; ++ ++ mtk_thermal_get_bank(bank); ++ ++ *temp = mtk_thermal_bank_temperature(bank); ++ ++ mtk_thermal_put_bank(bank); ++ ++ return 0; ++} ++ ++static int mtk_set_trips(void *data, int low, int high) ++{ ++ struct mtk_thermal_bank *bank = data; ++ struct mtk_thermal *mt = bank->mt; ++ int i; ++ u32 val, enable_mask; ++ u32 raw_low, raw_high; ++ ++ raw_low = mcelsius_to_raw(mt, low); ++ raw_high = mcelsius_to_raw(mt, high); ++ ++ mtk_thermal_get_bank(bank); ++ ++ writel(0x0, mt->thermal_base + TEMPMONINT); ++ ++ writel(TEMPPROTCTL_SELECTED, mt->thermal_base + TEMPPROTCTL); ++ ++ writel(raw_low, mt->thermal_base + TEMPOFFSETL); ++ writel(raw_high, mt->thermal_base + TEMPOFFSETH); ++ ++ enable_mask = readl(mt->thermal_base + TEMPMONCTL0); ++ ++ val = 0; ++ for (i = 0; i < MT8173_NUM_SENSING_POINTS; i++) ++ if (enable_mask & (1 << i)) ++ val |= TEMPMONINT_LOW_OFS(i) | TEMPMONINT_HIGH_OFS(i); ++ ++ writel(val, mt->thermal_base + TEMPMONINT); ++ ++ mtk_thermal_put_bank(bank); ++ ++ dev_dbg(mt->dev, "new boundaries: %d (0x%04x) < x < %d (0x%04x)\n", ++ low, mcelsius_to_raw(mt, low), ++ high, mcelsius_to_raw(mt, high)); ++ ++ return 0; ++} ++ ++static const struct thermal_zone_of_device_ops mtk_thermal_ops = { ++ .get_temp = mtk_read_temp, ++ .set_trips = mtk_set_trips, ++}; ++ ++static void mtk_thermal_init_bank(struct mtk_thermal_bank *bank) ++{ ++ struct mtk_thermal *mt = bank->mt; ++ struct mtk_thermal_bank_cfg *cfg = &bank_data[bank->id]; ++ int i; ++ ++ mtk_thermal_get_bank(bank); ++ ++ /* bus clock 66M counting unit is 12 * 15.15ns * 256 = 46.540us */ ++ writel(0x0000000c, mt->thermal_base + TEMPMONCTL1); ++ ++ /* ++ * filt interval is 1 * 46.540us = 46.54us, ++ * sen interval is 429 * 46.540us = 19.96ms ++ */ ++ writel(0x000101ad, mt->thermal_base + TEMPMONCTL2); ++ ++ /* poll is set to 10u */ ++ writel(0x00000300, mt->thermal_base + TEMPAHBPOLL); ++ ++ /* temperature sampling control, 1 sample */ ++ writel(0x00000000, mt->thermal_base + TEMPMSRCTL0); ++ ++ /* exceed this polling time, IRQ would be inserted */ ++ writel(0xffffffff, mt->thermal_base + TEMPAHBTO); ++ ++ /* number of interrupts per event, 1 is enough */ ++ writel(0x0, mt->thermal_base + TEMPMONIDET0); ++ writel(0x0, mt->thermal_base + TEMPMONIDET1); ++ ++ /* ++ * The MT8173 thermal controller does not have its own ADC. Instead it ++ * uses AHB bus accesses to control the AUXADC. To do this the thermal ++ * controller has to be programmed with the physical addresses of the ++ * AUXADC registers and with the various bit positions in the AUXADC. ++ * Also the thermal controller controls a mux in the APMIXEDSYS register ++ * space. ++ */ ++ ++ /* ++ * this value will be stored to TEMPPNPMUXADDR (TEMPSPARE0) ++ * automatically by hw ++ */ ++ writel(1 << MT8173_TEMP_AUXADC_CHANNEL, mt->thermal_base + TEMPADCMUX); ++ ++ /* AHB address for auxadc mux selection */ ++ writel(mt->auxadc_phys_base + 0x00c, ++ mt->thermal_base + TEMPADCMUXADDR); ++ ++ /* AHB address for pnp sensor mux selection */ ++ writel(mt->apmixed_phys_base + 0x0604, ++ mt->thermal_base + TEMPPNPMUXADDR); ++ ++ /* AHB value for auxadc enable */ ++ writel(1 << MT8173_TEMP_AUXADC_CHANNEL, mt->thermal_base + TEMPADCEN); ++ ++ /* AHB address for auxadc enable (channel 0 immediate mode selected) */ ++ writel(mt->auxadc_phys_base + AUXADC_CON1_SET_V, ++ mt->thermal_base + TEMPADCENADDR); ++ ++ /* AHB address for auxadc valid bit */ ++ writel(mt->auxadc_phys_base + AUXADC_DATA(MT8173_TEMP_AUXADC_CHANNEL), ++ mt->thermal_base + TEMPADCVALIDADDR); ++ ++ /* AHB address for auxadc voltage output */ ++ writel(mt->auxadc_phys_base + AUXADC_DATA(MT8173_TEMP_AUXADC_CHANNEL), ++ mt->thermal_base + TEMPADCVOLTADDR); ++ ++ /* read valid & voltage are at the same register */ ++ writel(0x0, mt->thermal_base + TEMPRDCTRL); ++ ++ /* indicate where the valid bit is */ ++ writel(TEMPADCVALIDMASK_VALID_HIGH | TEMPADCVALIDMASK_VALID_POS(12), ++ mt->thermal_base + TEMPADCVALIDMASK); ++ ++ /* no shift */ ++ writel(0x0, mt->thermal_base + TEMPADCVOLTAGESHIFT); ++ ++ /* enable auxadc mux write transaction */ ++ writel(TEMPADCWRITECTRL_ADC_MUX_WRITE, ++ mt->thermal_base + TEMPADCWRITECTRL); ++ ++ for (i = 0; i < MT8173_NUM_SENSING_POINTS; i++) ++ writel(sensor_mux_values[cfg->sensors[i]], ++ mt->thermal_base + tempadcpnp_ofs[i]); ++ ++ writel(cfg->enable_mask, mt->thermal_base + TEMPMONCTL0); ++ ++ writel(TEMPADCWRITECTRL_ADC_PNP_WRITE | TEMPADCWRITECTRL_ADC_MUX_WRITE, ++ mt->thermal_base + TEMPADCWRITECTRL); ++ ++ mtk_thermal_put_bank(bank); ++} ++ ++static u64 of_get_phys_base(struct device_node *np) ++{ ++ u64 size64; ++ const __be32 *regaddr_p; ++ ++ regaddr_p = of_get_address(np, 0, &size64, NULL); ++ if (!regaddr_p) ++ return OF_BAD_ADDR; ++ ++ return of_translate_address(np, regaddr_p); ++} ++ ++static int mtk_thermal_probe(struct platform_device *pdev) ++{ ++ int ret, i; ++ struct device_node *auxadc, *apmixedsys, *np = pdev->dev.of_node; ++ int irq; ++ struct mtk_thermal *mt; ++ struct resource *res; ++ ++ mt = devm_kzalloc(&pdev->dev, sizeof(*mt), GFP_KERNEL); ++ if (!mt) ++ return -ENOMEM; ++ ++ mt->clk_peri_therm = devm_clk_get(&pdev->dev, "therm"); ++ if (IS_ERR(mt->clk_peri_therm)) ++ return PTR_ERR(mt->clk_peri_therm); ++ ++ mt->clk_auxadc = devm_clk_get(&pdev->dev, "auxadc"); ++ if (IS_ERR(mt->clk_auxadc)) ++ return PTR_ERR(mt->clk_auxadc); ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ mt->thermal_base = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(mt->thermal_base)) ++ return PTR_ERR(mt->thermal_base); ++ ++ mt->reset = devm_reset_control_get(&pdev->dev, "therm"); ++ if (IS_ERR(mt->reset)) { ++ ret = PTR_ERR(mt->reset); ++ dev_err(&pdev->dev, "cannot get reset: %d\n", ret); ++ return ret; ++ } ++ ++ mutex_init(&mt->lock); ++ ++ mt->dev = &pdev->dev; ++ ++ auxadc = of_parse_phandle(np, "auxadc", 0); ++ if (!auxadc) { ++ dev_err(&pdev->dev, "missing auxadc node\n"); ++ return -ENODEV; ++ } ++ ++ mt->auxadc_phys_base = of_get_phys_base(auxadc); ++ if (mt->auxadc_phys_base == OF_BAD_ADDR) { ++ dev_err(&pdev->dev, "Can't get auxadc phys address\n"); ++ return -EINVAL; ++ } ++ ++ apmixedsys = of_parse_phandle(np, "apmixedsys", 0); ++ if (!apmixedsys) { ++ dev_err(&pdev->dev, "missing apmixedsys node\n"); ++ return -ENODEV; ++ } ++ ++ mt->apmixed_phys_base = of_get_phys_base(apmixedsys); ++ if (mt->apmixed_phys_base == OF_BAD_ADDR) { ++ dev_err(&pdev->dev, "Can't get auxadc phys address\n"); ++ return -EINVAL; ++ } ++ ++ irq = platform_get_irq(pdev, 0); ++ if (!irq) { ++ dev_err(&pdev->dev, "Can't find irq\n"); ++ return -EINVAL; ++ } ++ ++ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, mtk_thermal_irq, ++ IRQF_ONESHOT, THERMAL_NAME, mt); ++ if (ret) { ++ dev_err(&pdev->dev, "Can't request irq %d: %d\n", irq, ret); ++ return ret; ++ } ++ ++ ret = clk_prepare_enable(mt->clk_auxadc); ++ if (ret) { ++ dev_err(&pdev->dev, "Can't enable auxadc clk: %d\n", ret); ++ return ret; ++ } ++ ++ reset_control_reset(mt->reset); ++ ++ ret = clk_prepare_enable(mt->clk_peri_therm); ++ if (ret) { ++ dev_err(&pdev->dev, "Can't enable peri clk: %d\n", ret); ++ goto err_enable_clk; ++ } ++ ++ /* ++ * These calibration values should finally be provided by the ++ * firmware or fuses. For now use default values. ++ */ ++ mt->adc_ge = ((512 - 512) * 10000) / 4096; ++ mt->adc_oe = 512 - 512; ++ mt->degc_cali = 40; ++ mt->o_slope = 0; ++ mt->vts = 260; ++ ++ for (i = 0; i < MT8173_NUM_BANKS; i++) { ++ struct mtk_thermal_bank *bank = &mt->banks[i]; ++ ++ bank->id = i; ++ bank->mt = mt; ++ mtk_thermal_init_bank(&mt->banks[i]); ++ } ++ ++ platform_set_drvdata(pdev, mt); ++ ++ /* ++ * This is needed after initialising the banks because otherwise ++ * the first temperature read contains bogus high temperatures which ++ * immediately cause a system shutdown. ++ */ ++ msleep(100); ++ ++ for (i = 0; i < MT8173_NUM_BANKS; i++) { ++ struct mtk_thermal_bank *bank = &mt->banks[i]; ++ ++ bank->tz = thermal_zone_of_sensor_register(&pdev->dev, i, bank, ++ &mtk_thermal_ops); ++ } ++ ++ return 0; ++ ++err_enable_clk: ++ clk_disable_unprepare(mt->clk_peri_therm); ++ ++ return ret; ++} ++ ++static int mtk_thermal_remove(struct platform_device *pdev) ++{ ++ struct mtk_thermal *mt = platform_get_drvdata(pdev); ++ int i; ++ ++ for (i = 0; i < MT8173_NUM_BANKS; i++) { ++ struct mtk_thermal_bank *bank = &mt->banks[i]; ++ ++ if (!IS_ERR(bank)) ++ thermal_zone_of_sensor_unregister(&pdev->dev, bank->tz); ++ } ++ ++ clk_disable_unprepare(mt->clk_peri_therm); ++ clk_disable_unprepare(mt->clk_auxadc); ++ ++ return 0; ++} ++ ++static const struct of_device_id mtk_thermal_of_match[] = { ++ { ++ .compatible = "mediatek,mt8173-thermal", ++ }, { ++ }, ++}; ++ ++static struct platform_driver mtk_thermal_driver = { ++ .probe = mtk_thermal_probe, ++ .remove = mtk_thermal_remove, ++ .driver = { ++ .name = THERMAL_NAME, ++ .of_match_table = mtk_thermal_of_match, ++ }, ++}; ++ ++module_platform_driver(mtk_thermal_driver); +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0024-ARM64-dts-mt8173-Add-thermal-auxadc-device-nodes.patch b/target/linux/mediatek/patches/0024-ARM64-dts-mt8173-Add-thermal-auxadc-device-nodes.patch new file mode 100644 index 0000000000..ef80497cec --- /dev/null +++ b/target/linux/mediatek/patches/0024-ARM64-dts-mt8173-Add-thermal-auxadc-device-nodes.patch @@ -0,0 +1,49 @@ +From 720e25e5c821336f7fa0c5fb564475c791c00340 Mon Sep 17 00:00:00 2001 +From: Sascha Hauer <s.hauer@pengutronix.de> +Date: Wed, 13 May 2015 10:52:43 +0200 +Subject: [PATCH 24/76] ARM64: dts: mt8173: Add thermal/auxadc device nodes + +Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de> +--- + arch/arm64/boot/dts/mediatek/mt8173.dtsi | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi +index 924fdb6..50d424f 100644 +--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi ++++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi +@@ -147,6 +147,11 @@ + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + }; + ++ auxadc: auxadc@11001000 { ++ compatible = "mediatek,mt8173-auxadc"; ++ reg = <0 0x11001000 0 0x1000>; ++ }; ++ + uart0: serial@11002000 { + compatible = "mediatek,mt8173-uart", + "mediatek,mt6577-uart"; +@@ -182,6 +187,19 @@ + clocks = <&uart_clk>; + status = "disabled"; + }; ++ ++ thermal: thermal@1100b000 { ++ #thermal-sensor-cells = <1>; ++ compatible = "mediatek,mt8173-thermal"; ++ reg = <0 0x1100b000 0 0x1000>; ++ interrupts = <0 70 IRQ_TYPE_LEVEL_LOW>; ++ clocks = <&pericfg CLK_PERI_THERM>, <&pericfg CLK_PERI_AUXADC>; ++ clock-names = "therm", "auxadc"; ++ resets = <&pericfg MT8173_PERI_THERM_SW_RST>; ++ reset-names = "therm"; ++ auxadc = <&auxadc>; ++ apmixedsys = <&apmixedsys>; ++ }; + }; + + }; +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0025-dt-bindings-ARM-Mediatek-Document-devicetree-binding.patch b/target/linux/mediatek/patches/0025-dt-bindings-ARM-Mediatek-Document-devicetree-binding.patch new file mode 100644 index 0000000000..ab8f2d5cee --- /dev/null +++ b/target/linux/mediatek/patches/0025-dt-bindings-ARM-Mediatek-Document-devicetree-binding.patch @@ -0,0 +1,53 @@ +From a6de66d3cf5add25f2b8913332117f3334db506e Mon Sep 17 00:00:00 2001 +From: Leilk Liu <leilk.liu@mediatek.com> +Date: Fri, 8 May 2015 16:55:41 +0800 +Subject: [PATCH 25/76] dt-bindings: ARM: Mediatek: Document devicetree + bindings for spi bus + +Signed-off-by: Leilk Liu <leilk.liu@mediatek.com> +--- + .../devicetree/bindings/spi/spi-mt65xx.txt | 32 ++++++++++++++++++++ + 1 file changed, 32 insertions(+) + create mode 100644 Documentation/devicetree/bindings/spi/spi-mt65xx.txt + +diff --git a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt +new file mode 100644 +index 0000000..04c28fd +--- /dev/null ++++ b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt +@@ -0,0 +1,32 @@ ++MTK SPI device ++ ++Required properties: ++- compatible: should be one of the following. ++ - mediatek,mt8173-spi: for mt8173 platforms ++ - mediatek,mt8135-spi: for mt8135 platforms ++ - mediatek,mt6589-spi: for mt6589 platforms ++ ++- reg: Address and length of the register set for the device ++ ++- interrupts: Should contain spi interrupt ++ ++- clock-names: tuple listing input clock names. ++ Required elements: "main" ++ ++- clocks: phandles to input clocks. ++ ++- pad-select: should specify spi pad used, only required for MT8173. ++ This value should be 0~3. ++ ++Example: ++ ++- SoC Specific Portion: ++spi: spi@1100a000 { ++ compatible = "mediatek,mt8173-spi"; ++ reg = <0 0x1100a000 0 0x1000>; ++ interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_LOW>; ++ clocks = <&pericfg PERI_SPI0>; ++ clock-names = "main"; ++ pad-select = <1>; ++ status = "disabled"; ++}; +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0026-spi-mediatek-Add-spi-bus-for-Mediatek-MT8173.patch b/target/linux/mediatek/patches/0026-spi-mediatek-Add-spi-bus-for-Mediatek-MT8173.patch new file mode 100644 index 0000000000..3466581e04 --- /dev/null +++ b/target/linux/mediatek/patches/0026-spi-mediatek-Add-spi-bus-for-Mediatek-MT8173.patch @@ -0,0 +1,679 @@ +From 047222cfefe97ef8706f03117bc8deada4cb4ddd Mon Sep 17 00:00:00 2001 +From: Leilk Liu <leilk.liu@mediatek.com> +Date: Fri, 8 May 2015 16:55:42 +0800 +Subject: [PATCH 26/76] spi: mediatek: Add spi bus for Mediatek MT8173 + +This patch adds basic spi bus for MT8173. + +Signed-off-by: Leilk Liu <leilk.liu@mediatek.com> +--- + drivers/spi/Kconfig | 10 + + drivers/spi/Makefile | 1 + + drivers/spi/spi-mt65xx.c | 622 ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 633 insertions(+) + create mode 100644 drivers/spi/spi-mt65xx.c + +diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig +index 72b0590..53dbea3 100644 +--- a/drivers/spi/Kconfig ++++ b/drivers/spi/Kconfig +@@ -325,6 +325,16 @@ config SPI_MESON_SPIFC + This enables master mode support for the SPIFC (SPI flash + controller) available in Amlogic Meson SoCs. + ++config SPI_MT65XX ++ tristate "MediaTek SPI controller" ++ depends on ARCH_MEDIATEK || COMPILE_TEST ++ select SPI_BITBANG ++ help ++ This selects the MediaTek(R) SPI bus driver. ++ If you want to use MediaTek(R) SPI interface, ++ say Y or M here.If you are not sure, say N. ++ SPI drivers for Mediatek mt65XX series ARM SoCs. ++ + config SPI_OC_TINY + tristate "OpenCores tiny SPI" + depends on GPIOLIB +diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile +index d8cbf65..ab332ef 100644 +--- a/drivers/spi/Makefile ++++ b/drivers/spi/Makefile +@@ -48,6 +48,7 @@ obj-$(CONFIG_SPI_MESON_SPIFC) += spi-meson-spifc.o + obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o + obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o + obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o ++obj-$(CONFIG_SPI_MT65XX) += spi-mt65xx.o + obj-$(CONFIG_SPI_MXS) += spi-mxs.o + obj-$(CONFIG_SPI_NUC900) += spi-nuc900.o + obj-$(CONFIG_SPI_OC_TINY) += spi-oc-tiny.o +diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c +new file mode 100644 +index 0000000..92c119d +--- /dev/null ++++ b/drivers/spi/spi-mt65xx.c +@@ -0,0 +1,622 @@ ++/* ++ * Copyright (c) 2015 MediaTek Inc. ++ * Author: Leilk Liu <leilk.liu@mediatek.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/init.h> ++#include <linux/module.h> ++#include <linux/device.h> ++#include <linux/ioport.h> ++#include <linux/errno.h> ++#include <linux/spi/spi.h> ++#include <linux/workqueue.h> ++#include <linux/dma-mapping.h> ++#include <linux/platform_device.h> ++#include <linux/interrupt.h> ++#include <linux/irqreturn.h> ++#include <linux/types.h> ++#include <linux/delay.h> ++#include <linux/clk.h> ++#include <linux/err.h> ++#include <linux/io.h> ++#include <linux/sched.h> ++#include <linux/of.h> ++#include <linux/of_irq.h> ++#include <linux/of_address.h> ++#include <linux/kernel.h> ++#include <linux/spi/spi_bitbang.h> ++#include <linux/gpio.h> ++#include <linux/module.h> ++#include <linux/of_gpio.h> ++ ++#define SPI_CFG0_REG 0x0000 ++#define SPI_CFG1_REG 0x0004 ++#define SPI_TX_SRC_REG 0x0008 ++#define SPI_RX_DST_REG 0x000c ++#define SPI_CMD_REG 0x0018 ++#define SPI_STATUS0_REG 0x001c ++#define SPI_PAD_SEL_REG 0x0024 ++ ++#define SPI_CFG0_SCK_HIGH_OFFSET 0 ++#define SPI_CFG0_SCK_LOW_OFFSET 8 ++#define SPI_CFG0_CS_HOLD_OFFSET 16 ++#define SPI_CFG0_CS_SETUP_OFFSET 24 ++ ++#define SPI_CFG0_SCK_HIGH_MASK 0xff ++#define SPI_CFG0_SCK_LOW_MASK 0xff00 ++#define SPI_CFG0_CS_HOLD_MASK 0xff0000 ++#define SPI_CFG0_CS_SETUP_MASK 0xff000000 ++ ++#define SPI_CFG1_CS_IDLE_OFFSET 0 ++#define SPI_CFG1_PACKET_LOOP_OFFSET 8 ++#define SPI_CFG1_PACKET_LENGTH_OFFSET 16 ++#define SPI_CFG1_GET_TICK_DLY_OFFSET 30 ++ ++#define SPI_CFG1_CS_IDLE_MASK 0xff ++#define SPI_CFG1_PACKET_LOOP_MASK 0xff00 ++#define SPI_CFG1_PACKET_LENGTH_MASK 0x3ff0000 ++#define SPI_CFG1_GET_TICK_DLY_MASK 0xc0000000 ++ ++#define SPI_CMD_ACT_OFFSET 0 ++#define SPI_CMD_RESUME_OFFSET 1 ++#define SPI_CMD_RST_OFFSET 2 ++#define SPI_CMD_PAUSE_EN_OFFSET 4 ++#define SPI_CMD_DEASSERT_OFFSET 5 ++#define SPI_CMD_CPHA_OFFSET 8 ++#define SPI_CMD_CPOL_OFFSET 9 ++#define SPI_CMD_RX_DMA_OFFSET 10 ++#define SPI_CMD_TX_DMA_OFFSET 11 ++#define SPI_CMD_TXMSBF_OFFSET 12 ++#define SPI_CMD_RXMSBF_OFFSET 13 ++#define SPI_CMD_RX_ENDIAN_OFFSET 14 ++#define SPI_CMD_TX_ENDIAN_OFFSET 15 ++#define SPI_CMD_FINISH_IE_OFFSET 16 ++#define SPI_CMD_PAUSE_IE_OFFSET 17 ++ ++#define SPI_CMD_RESUME_MASK 0x2 ++#define SPI_CMD_RST_MASK 0x4 ++#define SPI_CMD_PAUSE_EN_MASK 0x10 ++#define SPI_CMD_DEASSERT_MASK 0x20 ++#define SPI_CMD_CPHA_MASK 0x100 ++#define SPI_CMD_CPOL_MASK 0x200 ++#define SPI_CMD_RX_DMA_MASK 0x400 ++#define SPI_CMD_TX_DMA_MASK 0x800 ++#define SPI_CMD_TXMSBF_MASK 0x1000 ++#define SPI_CMD_RXMSBF_MASK 0x2000 ++#define SPI_CMD_RX_ENDIAN_MASK 0x4000 ++#define SPI_CMD_TX_ENDIAN_MASK 0x8000 ++#define SPI_CMD_FINISH_IE_MASK 0x10000 ++ ++#define COMPAT_MT6589 (0x1 << 0) ++#define COMPAT_MT8173 (0x1 << 1) ++ ++#define MT8173_MAX_PAD_SEL 3 ++ ++#define IDLE 0 ++#define INPROGRESS 1 ++#define PAUSED 2 ++ ++#define PACKET_SIZE 1024 ++ ++struct mtk_chip_config { ++ u32 setuptime; ++ u32 holdtime; ++ u32 high_time; ++ u32 low_time; ++ u32 cs_idletime; ++ u32 tx_mlsb; ++ u32 rx_mlsb; ++ u32 tx_endian; ++ u32 rx_endian; ++ u32 pause; ++ u32 finish_intr; ++ u32 deassert; ++ u32 tckdly; ++}; ++ ++struct mtk_spi_ddata { ++ struct spi_bitbang bitbang; ++ void __iomem *base; ++ u32 irq; ++ u32 state; ++ u32 platform_compat; ++ u32 pad_sel; ++ struct clk *clk; ++ ++ const u8 *tx_buf; ++ u8 *rx_buf; ++ u32 tx_len, rx_len; ++ struct completion done; ++}; ++ ++/* ++ * A piece of default chip info unless the platform ++ * supplies it. ++ */ ++static const struct mtk_chip_config mtk_default_chip_info = { ++ .setuptime = 10, ++ .holdtime = 12, ++ .high_time = 6, ++ .low_time = 6, ++ .cs_idletime = 12, ++ .rx_mlsb = 1, ++ .tx_mlsb = 1, ++ .tx_endian = 0, ++ .rx_endian = 0, ++ .pause = 0, ++ .finish_intr = 1, ++ .deassert = 0, ++ .tckdly = 0, ++}; ++ ++static const struct of_device_id mtk_spi_of_match[] = { ++ { .compatible = "mediatek,mt6589-spi", .data = (void *)COMPAT_MT6589}, ++ { .compatible = "mediatek,mt8173-spi", .data = (void *)COMPAT_MT8173}, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, mtk_spi_of_match); ++ ++static void mtk_spi_reset(struct mtk_spi_ddata *mdata) ++{ ++ u32 reg_val; ++ ++ /*set the software reset bit in SPI_CMD_REG.*/ ++ reg_val = readl(mdata->base + SPI_CMD_REG); ++ reg_val &= ~SPI_CMD_RST_MASK; ++ reg_val |= 1 << SPI_CMD_RST_OFFSET; ++ writel(reg_val, mdata->base + SPI_CMD_REG); ++ reg_val = readl(mdata->base + SPI_CMD_REG); ++ reg_val &= ~SPI_CMD_RST_MASK; ++ writel(reg_val, mdata->base + SPI_CMD_REG); ++} ++ ++static void mtk_set_pause_bit(struct mtk_spi_ddata *mdata) ++{ ++ u32 reg_val; ++ ++ reg_val = readl(mdata->base + SPI_CMD_REG); ++ reg_val |= 1 << SPI_CMD_PAUSE_EN_OFFSET; ++ reg_val |= 1 << SPI_CMD_PAUSE_IE_OFFSET; ++ writel(reg_val, mdata->base + SPI_CMD_REG); ++} ++ ++static void mtk_clear_pause_bit(struct mtk_spi_ddata *mdata) ++{ ++ u32 reg_val; ++ ++ reg_val = readl(mdata->base + SPI_CMD_REG); ++ reg_val &= ~SPI_CMD_PAUSE_EN_MASK; ++ writel(reg_val, mdata->base + SPI_CMD_REG); ++} ++ ++static int mtk_spi_config(struct mtk_spi_ddata *mdata, ++ struct mtk_chip_config *chip_config) ++{ ++ u32 reg_val; ++ ++ /* set the timing */ ++ reg_val = readl(mdata->base + SPI_CFG0_REG); ++ reg_val &= ~(SPI_CFG0_SCK_HIGH_MASK | SPI_CFG0_SCK_LOW_MASK); ++ reg_val &= ~(SPI_CFG0_CS_HOLD_MASK | SPI_CFG0_CS_SETUP_MASK); ++ reg_val |= ((chip_config->high_time - 1) << SPI_CFG0_SCK_HIGH_OFFSET); ++ reg_val |= ((chip_config->low_time - 1) << SPI_CFG0_SCK_LOW_OFFSET); ++ reg_val |= ((chip_config->holdtime - 1) << SPI_CFG0_CS_HOLD_OFFSET); ++ reg_val |= ((chip_config->setuptime - 1) << SPI_CFG0_CS_SETUP_OFFSET); ++ writel(reg_val, mdata->base + SPI_CFG0_REG); ++ ++ reg_val = readl(mdata->base + SPI_CFG1_REG); ++ reg_val &= ~SPI_CFG1_CS_IDLE_MASK; ++ reg_val |= ((chip_config->cs_idletime - 1) << SPI_CFG1_CS_IDLE_OFFSET); ++ reg_val &= ~SPI_CFG1_GET_TICK_DLY_MASK; ++ reg_val |= ((chip_config->tckdly) << SPI_CFG1_GET_TICK_DLY_OFFSET); ++ writel(reg_val, mdata->base + SPI_CFG1_REG); ++ ++ /* set the mlsbx and mlsbtx */ ++ reg_val = readl(mdata->base + SPI_CMD_REG); ++ reg_val &= ~(SPI_CMD_TX_ENDIAN_MASK | SPI_CMD_RX_ENDIAN_MASK); ++ reg_val &= ~(SPI_CMD_TXMSBF_MASK | SPI_CMD_RXMSBF_MASK); ++ reg_val |= (chip_config->tx_mlsb << SPI_CMD_TXMSBF_OFFSET); ++ reg_val |= (chip_config->rx_mlsb << SPI_CMD_RXMSBF_OFFSET); ++ reg_val |= (chip_config->tx_endian << SPI_CMD_TX_ENDIAN_OFFSET); ++ reg_val |= (chip_config->rx_endian << SPI_CMD_RX_ENDIAN_OFFSET); ++ writel(reg_val, mdata->base + SPI_CMD_REG); ++ ++ /* set finish and pause interrupt always enable */ ++ reg_val = readl(mdata->base + SPI_CMD_REG); ++ reg_val &= ~SPI_CMD_FINISH_IE_MASK; ++ reg_val |= (chip_config->finish_intr << SPI_CMD_FINISH_IE_OFFSET); ++ writel(reg_val, mdata->base + SPI_CMD_REG); ++ ++ reg_val = readl(mdata->base + SPI_CMD_REG); ++ reg_val |= 1 << SPI_CMD_TX_DMA_OFFSET; ++ reg_val |= 1 << SPI_CMD_RX_DMA_OFFSET; ++ writel(reg_val, mdata->base + SPI_CMD_REG); ++ ++ /* set deassert mode */ ++ reg_val = readl(mdata->base + SPI_CMD_REG); ++ reg_val &= ~SPI_CMD_DEASSERT_MASK; ++ reg_val |= (chip_config->deassert << SPI_CMD_DEASSERT_OFFSET); ++ writel(reg_val, mdata->base + SPI_CMD_REG); ++ ++ /* pad select */ ++ if (mdata->platform_compat & COMPAT_MT8173) ++ writel(mdata->pad_sel, mdata->base + SPI_PAD_SEL_REG); ++ ++ return 0; ++} ++ ++static int mtk_spi_setup_transfer(struct spi_device *spi, ++ struct spi_transfer *t) ++{ ++ u32 reg_val; ++ struct spi_master *master = spi->master; ++ struct mtk_spi_ddata *mdata = spi_master_get_devdata(master); ++ struct spi_message *m = master->cur_msg; ++ struct mtk_chip_config *chip_config; ++ ++ u8 cpha = spi->mode & SPI_CPHA ? 1 : 0; ++ u8 cpol = spi->mode & SPI_CPOL ? 1 : 0; ++ ++ reg_val = readl(mdata->base + SPI_CMD_REG); ++ reg_val &= ~(SPI_CMD_CPHA_MASK | SPI_CMD_CPOL_MASK); ++ reg_val |= (cpha << SPI_CMD_CPHA_OFFSET); ++ reg_val |= (cpol << SPI_CMD_CPOL_OFFSET); ++ writel(reg_val, mdata->base + SPI_CMD_REG); ++ ++ if (t->cs_change) { ++ if (!(list_is_last(&t->transfer_list, &m->transfers))) ++ mdata->state = IDLE; ++ } else { ++ mdata->state = IDLE; ++ mtk_spi_reset(mdata); ++ } ++ ++ chip_config = (struct mtk_chip_config *)spi->controller_data; ++ if (!chip_config) { ++ chip_config = (void *)&mtk_default_chip_info; ++ spi->controller_data = chip_config; ++ mdata->state = IDLE; ++ } ++ ++ mtk_spi_config(mdata, chip_config); ++ ++ return 0; ++} ++ ++static void mtk_spi_chipselect(struct spi_device *spi, int is_on) ++{ ++ struct mtk_spi_ddata *mdata = spi_master_get_devdata(spi->master); ++ ++ switch (is_on) { ++ case BITBANG_CS_ACTIVE: ++ mtk_set_pause_bit(mdata); ++ break; ++ case BITBANG_CS_INACTIVE: ++ mtk_clear_pause_bit(mdata); ++ break; ++ } ++} ++ ++static void mtk_spi_start_transfer(struct mtk_spi_ddata *mdata) ++{ ++ u32 reg_val; ++ ++ reg_val = readl(mdata->base + SPI_CMD_REG); ++ reg_val |= 1 << SPI_CMD_ACT_OFFSET; ++ writel(reg_val, mdata->base + SPI_CMD_REG); ++} ++ ++static void mtk_spi_resume_transfer(struct mtk_spi_ddata *mdata) ++{ ++ u32 reg_val; ++ ++ reg_val = readl(mdata->base + SPI_CMD_REG); ++ reg_val &= ~SPI_CMD_RESUME_MASK; ++ reg_val |= 1 << SPI_CMD_RESUME_OFFSET; ++ writel(reg_val, mdata->base + SPI_CMD_REG); ++} ++ ++static int mtk_spi_setup_packet(struct mtk_spi_ddata *mdata, ++ struct spi_transfer *xfer) ++{ ++ struct device *dev = &mdata->bitbang.master->dev; ++ u32 packet_size, packet_loop, reg_val; ++ ++ packet_size = min_t(unsigned, xfer->len, PACKET_SIZE); ++ ++ /* mtk hw has the restriction that xfer len must be a multiple of 1024, ++ * when it is greater than 1024bytes. ++ */ ++ if (xfer->len % packet_size) { ++ dev_err(dev, "ERROR!The lens must be a multiple of %d, your len %d\n", ++ PACKET_SIZE, xfer->len); ++ return -EINVAL; ++ } ++ ++ packet_loop = xfer->len / packet_size; ++ ++ reg_val = readl(mdata->base + SPI_CFG1_REG); ++ reg_val &= ~(SPI_CFG1_PACKET_LENGTH_MASK + SPI_CFG1_PACKET_LOOP_MASK); ++ reg_val |= (packet_size - 1) << SPI_CFG1_PACKET_LENGTH_OFFSET; ++ reg_val |= (packet_loop - 1) << SPI_CFG1_PACKET_LOOP_OFFSET; ++ writel(reg_val, mdata->base + SPI_CFG1_REG); ++ ++ return 0; ++} ++ ++static int mtk_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *xfer) ++{ ++ struct spi_master *master = spi->master; ++ struct mtk_spi_ddata *mdata = spi_master_get_devdata(master); ++ struct device *dev = &mdata->bitbang.master->dev; ++ int cmd, ret; ++ ++ /* mtk spi hw tx/rx have 4bytes aligned restriction, ++ * so kmalloc tx/rx buffer to workaround here. ++ */ ++ mdata->tx_buf = NULL; ++ mdata->rx_buf = NULL; ++ if (xfer->tx_buf) { ++ mdata->tx_buf = kmalloc(xfer->len, GFP_KERNEL); ++ if (!mdata->tx_buf) { ++ dev_err(dev, "malloc tx_buf failed.\n"); ++ ret = -ENOMEM; ++ goto err_free; ++ } ++ memcpy((void *)mdata->tx_buf, xfer->tx_buf, xfer->len); ++ } ++ if (xfer->rx_buf) { ++ mdata->rx_buf = kmalloc(xfer->len, GFP_KERNEL); ++ if (!mdata->rx_buf) { ++ dev_err(dev, "malloc rx_buf failed.\n"); ++ ret = -ENOMEM; ++ goto err_free; ++ } ++ } ++ ++ reinit_completion(&mdata->done); ++ ++ xfer->tx_dma = DMA_ERROR_CODE; ++ xfer->rx_dma = DMA_ERROR_CODE; ++ if (xfer->tx_buf) { ++ xfer->tx_dma = dma_map_single(dev, (void *)mdata->tx_buf, ++ xfer->len, DMA_TO_DEVICE); ++ if (dma_mapping_error(dev, xfer->tx_dma)) { ++ dev_err(dev, "dma mapping tx_buf error.\n"); ++ ret = -ENOMEM; ++ goto err_free; ++ } ++ } ++ if (xfer->rx_buf) { ++ xfer->rx_dma = dma_map_single(dev, mdata->rx_buf, ++ xfer->len, DMA_FROM_DEVICE); ++ if (dma_mapping_error(dev, xfer->rx_dma)) { ++ if (xfer->tx_buf) ++ dma_unmap_single(dev, xfer->tx_dma, ++ xfer->len, DMA_TO_DEVICE); ++ dev_err(dev, "dma mapping rx_buf error.\n"); ++ ret = -ENOMEM; ++ goto err_free; ++ } ++ } ++ ++ ret = mtk_spi_setup_packet(mdata, xfer); ++ if (ret != 0) ++ goto err_free; ++ ++ /* Here is mt8173 HW issue: RX must enable TX, then TX transfer ++ * dummy data; TX don't need to enable RX. so enable TX dma for ++ * RX to workaround. ++ */ ++ cmd = readl(mdata->base + SPI_CMD_REG); ++ if (xfer->tx_buf || (mdata->platform_compat & COMPAT_MT8173)) ++ cmd |= 1 << SPI_CMD_TX_DMA_OFFSET; ++ if (xfer->rx_buf) ++ cmd |= 1 << SPI_CMD_RX_DMA_OFFSET; ++ writel(cmd, mdata->base + SPI_CMD_REG); ++ ++ /* set up the DMA bus address */ ++ if (xfer->tx_dma != DMA_ERROR_CODE) ++ writel(cpu_to_le32(xfer->tx_dma), mdata->base + SPI_TX_SRC_REG); ++ if (xfer->rx_dma != DMA_ERROR_CODE) ++ writel(cpu_to_le32(xfer->rx_dma), mdata->base + SPI_RX_DST_REG); ++ ++ if (mdata->state == IDLE) ++ mtk_spi_start_transfer(mdata); ++ else if (mdata->state == PAUSED) ++ mtk_spi_resume_transfer(mdata); ++ else ++ mdata->state = INPROGRESS; ++ ++ wait_for_completion(&mdata->done); ++ ++ if (xfer->tx_dma != DMA_ERROR_CODE) { ++ dma_unmap_single(dev, xfer->tx_dma, xfer->len, DMA_TO_DEVICE); ++ xfer->tx_dma = DMA_ERROR_CODE; ++ } ++ if (xfer->rx_dma != DMA_ERROR_CODE) { ++ dma_unmap_single(dev, xfer->rx_dma, xfer->len, DMA_FROM_DEVICE); ++ xfer->rx_dma = DMA_ERROR_CODE; ++ } ++ ++ /* spi disable dma */ ++ cmd = readl(mdata->base + SPI_CMD_REG); ++ cmd &= ~SPI_CMD_TX_DMA_MASK; ++ cmd &= ~SPI_CMD_RX_DMA_MASK; ++ writel(cmd, mdata->base + SPI_CMD_REG); ++ ++ if (xfer->rx_buf) ++ memcpy(xfer->rx_buf, mdata->rx_buf, xfer->len); ++ ++ ret = xfer->len; ++ ++err_free: ++ kfree(mdata->tx_buf); ++ kfree(mdata->rx_buf); ++ return ret; ++} ++ ++static irqreturn_t mtk_spi_interrupt(int irq, void *dev_id) ++{ ++ struct mtk_spi_ddata *mdata = dev_id; ++ u32 reg_val; ++ ++ reg_val = readl(mdata->base + SPI_STATUS0_REG); ++ if (reg_val & 0x2) ++ mdata->state = PAUSED; ++ else ++ mdata->state = IDLE; ++ complete(&mdata->done); ++ ++ return IRQ_HANDLED; ++} ++ ++static unsigned long mtk_get_device_prop(struct platform_device *pdev) ++{ ++ const struct of_device_id *match; ++ ++ match = of_match_node(mtk_spi_of_match, pdev->dev.of_node); ++ return (unsigned long)match->data; ++} ++ ++static int mtk_spi_probe(struct platform_device *pdev) ++{ ++ struct spi_master *master; ++ struct mtk_spi_ddata *mdata; ++ struct resource *res; ++ int ret; ++ ++ master = spi_alloc_master(&pdev->dev, sizeof(struct mtk_spi_ddata)); ++ if (!master) { ++ dev_err(&pdev->dev, "failed to alloc spi master\n"); ++ return -ENOMEM; ++ } ++ ++ platform_set_drvdata(pdev, master); ++ ++ master->dev.of_node = pdev->dev.of_node; ++ master->bus_num = pdev->id; ++ master->num_chipselect = 1; ++ master->mode_bits = SPI_CPOL | SPI_CPHA; ++ ++ mdata = spi_master_get_devdata(master); ++ ++ mdata->bitbang.master = master; ++ mdata->bitbang.chipselect = mtk_spi_chipselect; ++ mdata->bitbang.setup_transfer = mtk_spi_setup_transfer; ++ mdata->bitbang.txrx_bufs = mtk_spi_txrx_bufs; ++ mdata->platform_compat = mtk_get_device_prop(pdev); ++ ++ if (mdata->platform_compat & COMPAT_MT8173) { ++ ret = of_property_read_u32(pdev->dev.of_node, "pad-select", ++ &mdata->pad_sel); ++ if (ret) { ++ dev_err(&pdev->dev, "failed to read pad select: %d\n", ++ ret); ++ goto err; ++ } ++ ++ if (mdata->pad_sel > MT8173_MAX_PAD_SEL) { ++ dev_err(&pdev->dev, "wrong pad-select: %u\n", ++ mdata->pad_sel); ++ goto err; ++ } ++ } ++ ++ init_completion(&mdata->done); ++ ++ mdata->clk = devm_clk_get(&pdev->dev, "main"); ++ if (IS_ERR(mdata->clk)) { ++ ret = PTR_ERR(mdata->clk); ++ dev_err(&pdev->dev, "failed to get clock: %d\n", ret); ++ goto err; ++ } ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ if (!res) { ++ ret = -ENODEV; ++ dev_err(&pdev->dev, "failed to determine base address\n"); ++ goto err; ++ } ++ ++ mdata->base = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(mdata->base)) { ++ ret = PTR_ERR(mdata->base); ++ goto err; ++ } ++ ++ ret = platform_get_irq(pdev, 0); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "failed to get irq (%d)\n", ret); ++ goto err; ++ } ++ ++ mdata->irq = ret; ++ ++ if (!pdev->dev.dma_mask) ++ pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; ++ ++ mdata->bitbang.master->dev.dma_mask = pdev->dev.dma_mask; ++ ++ ret = clk_prepare_enable(mdata->clk); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "failed to enable clock (%d)\n", ret); ++ goto err; ++ } ++ ++ ret = devm_request_irq(&pdev->dev, mdata->irq, mtk_spi_interrupt, ++ IRQF_TRIGGER_NONE, dev_name(&pdev->dev), mdata); ++ if (ret) { ++ dev_err(&pdev->dev, "failed to register irq (%d)\n", ret); ++ goto err_disable_clk; ++ } ++ ++ ret = spi_bitbang_start(&mdata->bitbang); ++ if (ret) { ++ dev_err(&pdev->dev, "spi_bitbang_start failed (%d)\n", ret); ++err_disable_clk: ++ clk_disable_unprepare(mdata->clk); ++err: ++ spi_master_put(master); ++ } ++ ++ return ret; ++} ++ ++static int mtk_spi_remove(struct platform_device *pdev) ++{ ++ struct spi_master *master = platform_get_drvdata(pdev); ++ struct mtk_spi_ddata *mdata = spi_master_get_devdata(master); ++ ++ spi_bitbang_stop(&mdata->bitbang); ++ mtk_spi_reset(mdata); ++ clk_disable_unprepare(mdata->clk); ++ spi_master_put(master); ++ ++ return 0; ++} ++ ++struct platform_driver mtk_spi_driver = { ++ .driver = { ++ .name = "mtk-spi", ++ .of_match_table = mtk_spi_of_match, ++ }, ++ .probe = mtk_spi_probe, ++ .remove = mtk_spi_remove, ++}; ++ ++module_platform_driver(mtk_spi_driver); ++ ++MODULE_DESCRIPTION("MTK SPI Controller driver"); ++MODULE_AUTHOR("Leilk Liu <leilk.liu@mediatek.com>"); ++MODULE_LICENSE("GPL v2"); ++MODULE_ALIAS("platform: mtk_spi"); +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0027-dt-bindings-pwm-add-Mediatek-display-PWM-bindings.patch b/target/linux/mediatek/patches/0027-dt-bindings-pwm-add-Mediatek-display-PWM-bindings.patch new file mode 100644 index 0000000000..1236a96782 --- /dev/null +++ b/target/linux/mediatek/patches/0027-dt-bindings-pwm-add-Mediatek-display-PWM-bindings.patch @@ -0,0 +1,47 @@ +From 908a87b47af8303c9aa8fb6aa183ca9f8b544d78 Mon Sep 17 00:00:00 2001 +From: YH Huang <yh.huang@mediatek.com> +Date: Mon, 11 May 2015 17:26:21 +0800 +Subject: [PATCH 27/76] dt-bindings: pwm: add Mediatek display PWM bindings + +Document the device-tree binding of Mediatek display PWM. + +Signed-off-by: YH Huang <yh.huang@mediatek.com> +--- + .../devicetree/bindings/pwm/pwm-disp-mediatek.txt | 25 ++++++++++++++++++++ + 1 file changed, 25 insertions(+) + create mode 100644 Documentation/devicetree/bindings/pwm/pwm-disp-mediatek.txt + +diff --git a/Documentation/devicetree/bindings/pwm/pwm-disp-mediatek.txt b/Documentation/devicetree/bindings/pwm/pwm-disp-mediatek.txt +new file mode 100644 +index 0000000..ef54e9d +--- /dev/null ++++ b/Documentation/devicetree/bindings/pwm/pwm-disp-mediatek.txt +@@ -0,0 +1,25 @@ ++Mediatek display PWM controller ++ ++Required properties: ++ - compatible: should be "mediatek,<name>-disp-pwm" ++ - "mediatek,mt8173-disp-pwm": found on mt8173 SoC ++ - "mediatek,mt6595-disp-pwm": found on mt6595 SoC ++ - reg: physical base address and length of the controller's registers ++ - #pwm-cells: must be 2. See pwm.txt in this directory ++ for a description of the cell format ++ - clocks: phandle and clock specifier of the PWM reference clock ++ - clock-names: must contain the following ++ - "main": clock used to generate PWM signals ++ - "mm": sync signals from the modules of mmsys ++ ++Example: ++ pwm0: pwm@1401e000 { ++ compatible = "mediatek,mt8173-disp-pwm", ++ "mediatek,mt6595-disp-pwm"; ++ reg = <0 0x1401e000 0 0x1000>; ++ #pwm-cells = <2>; ++ clocks = <&mmsys MM_DISP_PWM026M>, ++ <&mmsys MM_DISP_PWM0MM>; ++ clock-names = "main", ++ "mm"; ++ }; +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0028-pwm-add-Mediatek-display-PWM-driver-support.patch b/target/linux/mediatek/patches/0028-pwm-add-Mediatek-display-PWM-driver-support.patch new file mode 100644 index 0000000000..dbcca3e160 --- /dev/null +++ b/target/linux/mediatek/patches/0028-pwm-add-Mediatek-display-PWM-driver-support.patch @@ -0,0 +1,281 @@ +From 77e664940f6daa86965d16a2047188519341a31a Mon Sep 17 00:00:00 2001 +From: YH Huang <yh.huang@mediatek.com> +Date: Mon, 11 May 2015 17:26:22 +0800 +Subject: [PATCH 28/76] pwm: add Mediatek display PWM driver support + +Add display PWM driver support to modify backlight for MT8173/MT6595. + +Signed-off-by: YH Huang <yh.huang@mediatek.com> +--- + drivers/pwm/Kconfig | 9 ++ + drivers/pwm/Makefile | 1 + + drivers/pwm/pwm-disp-mediatek.c | 225 +++++++++++++++++++++++++++++++++++++++ + 3 files changed, 235 insertions(+) + create mode 100644 drivers/pwm/pwm-disp-mediatek.c + +diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig +index b1541f4..9edbb5a 100644 +--- a/drivers/pwm/Kconfig ++++ b/drivers/pwm/Kconfig +@@ -111,6 +111,15 @@ config PWM_CLPS711X + To compile this driver as a module, choose M here: the module + will be called pwm-clps711x. + ++config PWM_DISP_MEDIATEK ++ tristate "MEDIATEK display PWM driver" ++ depends on OF ++ help ++ Generic PWM framework driver for mediatek disp-pwm device. ++ ++ To compile this driver as a module, choose M here: the module ++ will be called pwm-disp-mediatek. ++ + config PWM_EP93XX + tristate "Cirrus Logic EP93xx PWM support" + depends on ARCH_EP93XX +diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile +index ec50eb5..c5ff72a 100644 +--- a/drivers/pwm/Makefile ++++ b/drivers/pwm/Makefile +@@ -8,6 +8,7 @@ obj-$(CONFIG_PWM_BCM_KONA) += pwm-bcm-kona.o + obj-$(CONFIG_PWM_BCM2835) += pwm-bcm2835.o + obj-$(CONFIG_PWM_BFIN) += pwm-bfin.o + obj-$(CONFIG_PWM_CLPS711X) += pwm-clps711x.o ++obj-$(CONFIG_PWM_DISP_MEDIATEK) += pwm-disp-mediatek.o + obj-$(CONFIG_PWM_EP93XX) += pwm-ep93xx.o + obj-$(CONFIG_PWM_FSL_FTM) += pwm-fsl-ftm.o + obj-$(CONFIG_PWM_IMG) += pwm-img.o +diff --git a/drivers/pwm/pwm-disp-mediatek.c b/drivers/pwm/pwm-disp-mediatek.c +new file mode 100644 +index 0000000..38293af +--- /dev/null ++++ b/drivers/pwm/pwm-disp-mediatek.c +@@ -0,0 +1,225 @@ ++/* ++ * Mediatek display pulse-width-modulation controller driver. ++ * Copyright (c) 2015 MediaTek Inc. ++ * Author: YH Huang <yh.huang@mediatek.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/clk.h> ++#include <linux/err.h> ++#include <linux/io.h> ++#include <linux/module.h> ++#include <linux/of.h> ++#include <linux/pwm.h> ++#include <linux/platform_device.h> ++#include <linux/slab.h> ++ ++#define DISP_PWM_EN_OFF (0x0) ++#define PWM_ENABLE_SHIFT (0x0) ++#define PWM_ENABLE_MASK (0x1 << PWM_ENABLE_SHIFT) ++ ++#define DISP_PWM_COMMIT_OFF (0x08) ++#define PWM_COMMIT_SHIFT (0x0) ++#define PWM_COMMIT_MASK (0x1 << PWM_COMMIT_SHIFT) ++ ++#define DISP_PWM_CON_0_OFF (0x10) ++#define PWM_CLKDIV_SHIFT (0x10) ++#define PWM_CLKDIV_MASK (0x3ff << PWM_CLKDIV_SHIFT) ++#define PWM_CLKDIV_MAX (0x000003ff) ++ ++#define DISP_PWM_CON_1_OFF (0x14) ++#define PWM_PERIOD_SHIFT (0x0) ++#define PWM_PERIOD_MASK (0xfff << PWM_PERIOD_SHIFT) ++#define PWM_PERIOD_MAX (0x00000fff) ++/* Shift log2(PWM_PERIOD_MAX + 1) as divisor */ ++#define PWM_PERIOD_BIT_SHIFT 12 ++ ++#define PWM_HIGH_WIDTH_SHIFT (0x10) ++#define PWM_HIGH_WIDTH_MASK (0x1fff << PWM_HIGH_WIDTH_SHIFT) ++ ++#define NUM_PWM 1 ++ ++struct mtk_disp_pwm_chip { ++ struct pwm_chip chip; ++ struct device *dev; ++ struct clk *clk_main; ++ struct clk *clk_mm; ++ void __iomem *mmio_base; ++}; ++ ++static void mtk_disp_pwm_setting(void __iomem *address, u32 value, u32 mask) ++{ ++ u32 val; ++ ++ val = readl(address); ++ val &= ~mask; ++ val |= value; ++ writel(val, address); ++} ++ ++static int mtk_disp_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, ++ int duty_ns, int period_ns) ++{ ++ struct mtk_disp_pwm_chip *mpc; ++ u64 div, rate; ++ u32 clk_div, period, high_width, rem; ++ ++ /* ++ * Find period, high_width and clk_div to suit duty_ns and period_ns. ++ * Calculate proper div value to keep period value in the bound. ++ * ++ * period_ns = 10^9 * (clk_div + 1) * (period +1) / PWM_CLK_RATE ++ * duty_ns = 10^9 * (clk_div + 1) * (high_width + 1) / PWM_CLK_RATE ++ * ++ * period = (PWM_CLK_RATE * period_ns) / (10^9 * (clk_div + 1)) - 1 ++ * high_width = (PWM_CLK_RATE * duty_ns) / (10^9 * (clk_div + 1)) - 1 ++ */ ++ mpc = container_of(chip, struct mtk_disp_pwm_chip, chip); ++ rate = clk_get_rate(mpc->clk_main); ++ clk_div = div_u64_rem(rate * period_ns, NSEC_PER_SEC, &rem) >> ++ PWM_PERIOD_BIT_SHIFT; ++ if (clk_div > PWM_CLKDIV_MAX) ++ return -EINVAL; ++ ++ div = clk_div + 1; ++ period = div64_u64(rate * period_ns, NSEC_PER_SEC * div); ++ if (period > 0) ++ period--; ++ high_width = div64_u64(rate * duty_ns, NSEC_PER_SEC * div); ++ if (high_width > 0) ++ high_width--; ++ ++ mtk_disp_pwm_setting(mpc->mmio_base + DISP_PWM_CON_0_OFF, ++ clk_div << PWM_CLKDIV_SHIFT, PWM_CLKDIV_MASK); ++ mtk_disp_pwm_setting(mpc->mmio_base + DISP_PWM_CON_1_OFF, ++ (period << PWM_PERIOD_SHIFT) | ++ (high_width << PWM_HIGH_WIDTH_SHIFT), ++ PWM_PERIOD_MASK | PWM_HIGH_WIDTH_MASK); ++ ++ mtk_disp_pwm_setting(mpc->mmio_base + DISP_PWM_COMMIT_OFF, ++ 1 << PWM_COMMIT_SHIFT, PWM_COMMIT_MASK); ++ mtk_disp_pwm_setting(mpc->mmio_base + DISP_PWM_COMMIT_OFF, ++ 0 << PWM_COMMIT_SHIFT, PWM_COMMIT_MASK); ++ ++ return 0; ++} ++ ++static int mtk_disp_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) ++{ ++ struct mtk_disp_pwm_chip *mpc; ++ ++ mpc = container_of(chip, struct mtk_disp_pwm_chip, chip); ++ mtk_disp_pwm_setting(mpc->mmio_base + DISP_PWM_EN_OFF, ++ 1 << PWM_ENABLE_SHIFT, PWM_ENABLE_MASK); ++ ++ return 0; ++} ++ ++static void mtk_disp_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) ++{ ++ struct mtk_disp_pwm_chip *mpc; ++ ++ mpc = container_of(chip, struct mtk_disp_pwm_chip, chip); ++ mtk_disp_pwm_setting(mpc->mmio_base + DISP_PWM_EN_OFF, ++ 0 << PWM_ENABLE_SHIFT, PWM_ENABLE_MASK); ++} ++ ++static const struct pwm_ops mtk_disp_pwm_ops = { ++ .config = mtk_disp_pwm_config, ++ .enable = mtk_disp_pwm_enable, ++ .disable = mtk_disp_pwm_disable, ++ .owner = THIS_MODULE, ++}; ++ ++static int mtk_disp_pwm_probe(struct platform_device *pdev) ++{ ++ struct mtk_disp_pwm_chip *pwm; ++ struct resource *r; ++ int ret; ++ ++ pwm = devm_kzalloc(&pdev->dev, sizeof(*pwm), GFP_KERNEL); ++ if (!pwm) ++ return -ENOMEM; ++ ++ pwm->dev = &pdev->dev; ++ ++ r = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ pwm->mmio_base = devm_ioremap_resource(&pdev->dev, r); ++ if (IS_ERR(pwm->mmio_base)) ++ return PTR_ERR(pwm->mmio_base); ++ ++ pwm->clk_main = devm_clk_get(&pdev->dev, "main"); ++ if (IS_ERR(pwm->clk_main)) ++ return PTR_ERR(pwm->clk_main); ++ pwm->clk_mm = devm_clk_get(&pdev->dev, "mm"); ++ if (IS_ERR(pwm->clk_mm)) ++ return PTR_ERR(pwm->clk_mm); ++ ++ ret = clk_prepare_enable(pwm->clk_main); ++ if (ret < 0) ++ return ret; ++ ret = clk_prepare_enable(pwm->clk_mm); ++ if (ret < 0) { ++ clk_disable_unprepare(pwm->clk_main); ++ return ret; ++ } ++ ++ platform_set_drvdata(pdev, pwm); ++ ++ pwm->chip.dev = &pdev->dev; ++ pwm->chip.ops = &mtk_disp_pwm_ops; ++ pwm->chip.base = -1; ++ pwm->chip.npwm = NUM_PWM; ++ ++ ret = pwmchip_add(&pwm->chip); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int mtk_disp_pwm_remove(struct platform_device *pdev) ++{ ++ struct mtk_disp_pwm_chip *pc = platform_get_drvdata(pdev); ++ ++ if (WARN_ON(!pc)) ++ return -ENODEV; ++ ++ clk_disable_unprepare(pc->clk_main); ++ clk_disable_unprepare(pc->clk_mm); ++ ++ return pwmchip_remove(&pc->chip); ++} ++ ++static const struct of_device_id mtk_disp_pwm_of_match[] = { ++ { .compatible = "mediatek,mt6595-disp-pwm" }, ++ { } ++}; ++ ++MODULE_DEVICE_TABLE(of, mtk_disp_pwm_of_match); ++ ++static struct platform_driver mtk_disp_pwm_driver = { ++ .driver = { ++ .name = "mediatek-disp-pwm", ++ .owner = THIS_MODULE, ++ .of_match_table = mtk_disp_pwm_of_match, ++ }, ++ .probe = mtk_disp_pwm_probe, ++ .remove = mtk_disp_pwm_remove, ++}; ++ ++module_platform_driver(mtk_disp_pwm_driver); ++ ++MODULE_AUTHOR("YH Huang <yh.huang@mediatek.com>"); ++MODULE_DESCRIPTION("MediaTek SoC display PWM driver"); ++MODULE_LICENSE("GPL v2"); +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0029-dt-bindings-Add-I2C-bindings-for-mt65xx-mt81xx.patch b/target/linux/mediatek/patches/0029-dt-bindings-Add-I2C-bindings-for-mt65xx-mt81xx.patch new file mode 100644 index 0000000000..03f03fb1dc --- /dev/null +++ b/target/linux/mediatek/patches/0029-dt-bindings-Add-I2C-bindings-for-mt65xx-mt81xx.patch @@ -0,0 +1,64 @@ +From d1447a6815913823ef5e75d70efc6f08f288ee40 Mon Sep 17 00:00:00 2001 +From: Xudong Chen <xudong.chen@mediatek.com> +Date: Wed, 6 May 2015 16:37:05 +0800 +Subject: [PATCH 29/76] dt-bindings: Add I2C bindings for mt65xx/mt81xx. + +Add devicetree bindings for Mediatek Soc I2C driver. + +Signed-off-by: Xudong Chen <xudong.chen@mediatek.com> +Signed-off-by: Eddie Huang <eddie.huang@mediatek.com> +--- + .../devicetree/bindings/i2c/i2c-mt6577.txt | 41 ++++++++++++++++++++ + 1 file changed, 41 insertions(+) + create mode 100644 Documentation/devicetree/bindings/i2c/i2c-mt6577.txt + +diff --git a/Documentation/devicetree/bindings/i2c/i2c-mt6577.txt b/Documentation/devicetree/bindings/i2c/i2c-mt6577.txt +new file mode 100644 +index 0000000..0ce6fa3 +--- /dev/null ++++ b/Documentation/devicetree/bindings/i2c/i2c-mt6577.txt +@@ -0,0 +1,41 @@ ++* Mediatek's I2C controller ++ ++The Mediatek's I2C controller is used to interface with I2C devices. ++ ++Required properties: ++ - compatible: value should be either of the following. ++ (a) "mediatek,mt6577-i2c", for i2c compatible with mt6577 i2c. ++ (b) "mediatek,mt6589-i2c", for i2c compatible with mt6589 i2c. ++ (c) "mediatek,mt8127-i2c", for i2c compatible with mt8127 i2c. ++ (d) "mediatek,mt8135-i2c", for i2c compatible with mt8135 i2c. ++ (e) "mediatek,mt8173-i2c", for i2c compatible with mt8173 i2c. ++ - reg: physical base address of the controller and dma base, length of memory ++ mapped region. ++ - interrupts: interrupt number to the cpu. ++ - clock-div: the fixed value for frequency divider of clock source in i2c ++ module. Each IC may be different. ++ - clocks: clock name from clock manager ++ - clock-names: Must include "main" and "dma", if enable have-pmic need include ++ "pmic" extra. ++ ++Optional properties: ++ - clock-frequency: Frequency in Hz of the bus when transfer, the default value ++ is 100000. ++ - mediatek,have-pmic: platform can control i2c form special pmic side. ++ Only mt6589 and mt8135 support this feature. ++ - mediatek,use-push-pull: IO config use push-pull mode. ++ ++Example: ++ ++ i2c0: i2c@1100d000 { ++ compatible = "mediatek,mt6577-i2c"; ++ reg = <0x1100d000 0x70>, ++ <0x11000300 0x80>; ++ interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_LOW>; ++ clock-frequency = <400000>; ++ mediatek,have-pmic; ++ clock-div = <16>; ++ clocks = <&i2c0_ck>, <&ap_dma_ck>; ++ clock-names = "main", "dma"; ++ }; ++ +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0030-I2C-mediatek-Add-driver-for-MediaTek-I2C-controller.patch b/target/linux/mediatek/patches/0030-I2C-mediatek-Add-driver-for-MediaTek-I2C-controller.patch new file mode 100644 index 0000000000..df22f08764 --- /dev/null +++ b/target/linux/mediatek/patches/0030-I2C-mediatek-Add-driver-for-MediaTek-I2C-controller.patch @@ -0,0 +1,760 @@ +From 2471bc43c6079ab956a04f29ffd1ab8371b7bd73 Mon Sep 17 00:00:00 2001 +From: Xudong Chen <xudong.chen@mediatek.com> +Date: Wed, 6 May 2015 16:37:06 +0800 +Subject: [PATCH 30/76] I2C: mediatek: Add driver for MediaTek I2C controller + +The mediatek SoCs have I2C controller that handle I2C transfer. +This patch include common I2C bus driver. +This driver is compatible with I2C controller on mt65xx/mt81xx. + +Signed-off-by: Xudong Chen <xudong.chen@mediatek.com> +Signed-off-by: Liguo Zhang <liguo.zhang@mediatek.com> +Signed-off-by: Eddie Huang <eddie.huang@mediatek.com> +--- + drivers/i2c/busses/Kconfig | 9 + + drivers/i2c/busses/Makefile | 1 + + drivers/i2c/busses/i2c-mt65xx.c | 700 +++++++++++++++++++++++++++++++++++++++ + 3 files changed, 710 insertions(+) + create mode 100644 drivers/i2c/busses/i2c-mt65xx.c + +diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig +index 2255af2..14c7266 100644 +--- a/drivers/i2c/busses/Kconfig ++++ b/drivers/i2c/busses/Kconfig +@@ -620,6 +620,15 @@ config I2C_MPC + This driver can also be built as a module. If so, the module + will be called i2c-mpc. + ++config I2C_MT65XX ++ tristate "MediaTek I2C adapter" ++ depends on ARCH_MEDIATEK || COMPILE_TEST ++ help ++ This selects the MediaTek(R) Integrated Inter Circuit bus driver ++ for MT65xx and MT81xx. ++ If you want to use MediaTek(R) I2C interface, say Y or M here. ++ If unsure, say N. ++ + config I2C_MV64XXX + tristate "Marvell mv64xxx I2C Controller" + depends on MV64X60 || PLAT_ORION || ARCH_SUNXI +diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile +index cdf941d..abbf422 100644 +--- a/drivers/i2c/busses/Makefile ++++ b/drivers/i2c/busses/Makefile +@@ -60,6 +60,7 @@ obj-$(CONFIG_I2C_JZ4780) += i2c-jz4780.o + obj-$(CONFIG_I2C_KEMPLD) += i2c-kempld.o + obj-$(CONFIG_I2C_MESON) += i2c-meson.o + obj-$(CONFIG_I2C_MPC) += i2c-mpc.o ++obj-$(CONFIG_I2C_MT65XX) += i2c-mt65xx.o + obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o + obj-$(CONFIG_I2C_MXS) += i2c-mxs.o + obj-$(CONFIG_I2C_NOMADIK) += i2c-nomadik.o +diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c +new file mode 100644 +index 0000000..faecf7e +--- /dev/null ++++ b/drivers/i2c/busses/i2c-mt65xx.c +@@ -0,0 +1,700 @@ ++/* ++ * Copyright (c) 2014 MediaTek Inc. ++ * Author: Xudong.chen <xudong.chen@mediatek.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/slab.h> ++#include <linux/i2c.h> ++#include <linux/init.h> ++#include <linux/interrupt.h> ++#include <linux/sched.h> ++#include <linux/delay.h> ++#include <linux/errno.h> ++#include <linux/err.h> ++#include <linux/device.h> ++#include <linux/platform_device.h> ++#include <linux/mm.h> ++#include <linux/dma-mapping.h> ++#include <linux/scatterlist.h> ++#include <linux/io.h> ++#include <linux/of_address.h> ++#include <linux/of_irq.h> ++#include <linux/clk.h> ++#include <linux/completion.h> ++ ++#define I2C_HS_NACKERR (1 << 2) ++#define I2C_ACKERR (1 << 1) ++#define I2C_TRANSAC_COMP (1 << 0) ++#define I2C_TRANSAC_START (1 << 0) ++#define I2C_TIMING_STEP_DIV_MASK (0x3f << 0) ++#define I2C_TIMING_SAMPLE_COUNT_MASK (0x7 << 0) ++#define I2C_TIMING_SAMPLE_DIV_MASK (0x7 << 8) ++#define I2C_TIMING_DATA_READ_MASK (0x7 << 12) ++#define I2C_DCM_DISABLE 0x0000 ++#define I2C_IO_CONFIG_OPEN_DRAIN 0x0003 ++#define I2C_IO_CONFIG_PUSH_PULL 0x0000 ++#define I2C_SOFT_RST 0x0001 ++#define I2C_FIFO_ADDR_CLR 0x0001 ++#define I2C_DELAY_LEN 0x0002 ++#define I2C_ST_START_CON 0x8001 ++#define I2C_FS_START_CON 0x1800 ++#define I2C_TIME_CLR_VALUE 0x0000 ++#define I2C_TIME_DEFAULT_VALUE 0x0003 ++#define I2C_FS_TIME_INIT_VALUE 0x1303 ++#define I2C_WRRD_TRANAC_VALUE 0x0002 ++#define I2C_RD_TRANAC_VALUE 0x0001 ++ ++#define I2C_DMA_CON_TX 0x0000 ++#define I2C_DMA_CON_RX 0x0001 ++#define I2C_DMA_START_EN 0x0001 ++#define I2C_DMA_INT_FLAG_NONE 0x0000 ++#define I2C_DMA_CLR_FLAG 0x0000 ++ ++#define I2C_DEFAUT_SPEED 100000 /* hz */ ++#define MAX_FS_MODE_SPEED 400000 ++#define MAX_HS_MODE_SPEED 3400000 ++#define MAX_MSG_NUM_MT6577 1 ++#define MAX_DMA_TRANS_SIZE_MT6577 255 ++#define MAX_WRRD_TRANS_SIZE_MT6577 31 ++#define MAX_SAMPLE_CNT_DIV 8 ++#define MAX_STEP_CNT_DIV 64 ++#define MAX_HS_STEP_CNT_DIV 8 ++ ++#define I2C_CONTROL_RS (0x1 << 1) ++#define I2C_CONTROL_DMA_EN (0x1 << 2) ++#define I2C_CONTROL_CLK_EXT_EN (0x1 << 3) ++#define I2C_CONTROL_DIR_CHANGE (0x1 << 4) ++#define I2C_CONTROL_ACKERR_DET_EN (0x1 << 5) ++#define I2C_CONTROL_TRANSFER_LEN_CHANGE (0x1 << 6) ++#define I2C_CONTROL_WRAPPER (0x1 << 0) ++ ++#define I2C_DRV_NAME "mt-i2c" ++ ++enum DMA_REGS_OFFSET { ++ OFFSET_INT_FLAG = 0x0, ++ OFFSET_INT_EN = 0x04, ++ OFFSET_EN = 0x08, ++ OFFSET_CON = 0x18, ++ OFFSET_TX_MEM_ADDR = 0x1c, ++ OFFSET_RX_MEM_ADDR = 0x20, ++ OFFSET_TX_LEN = 0x24, ++ OFFSET_RX_LEN = 0x28, ++}; ++ ++enum i2c_trans_st_rs { ++ I2C_TRANS_STOP = 0, ++ I2C_TRANS_REPEATED_START, ++}; ++ ++enum mtk_trans_op { ++ I2C_MASTER_WR = 1, ++ I2C_MASTER_RD, ++ I2C_MASTER_WRRD, ++}; ++ ++enum I2C_REGS_OFFSET { ++ OFFSET_DATA_PORT = 0x0, ++ OFFSET_SLAVE_ADDR = 0x04, ++ OFFSET_INTR_MASK = 0x08, ++ OFFSET_INTR_STAT = 0x0c, ++ OFFSET_CONTROL = 0x10, ++ OFFSET_TRANSFER_LEN = 0x14, ++ OFFSET_TRANSAC_LEN = 0x18, ++ OFFSET_DELAY_LEN = 0x1c, ++ OFFSET_TIMING = 0x20, ++ OFFSET_START = 0x24, ++ OFFSET_EXT_CONF = 0x28, ++ OFFSET_FIFO_STAT = 0x30, ++ OFFSET_FIFO_THRESH = 0x34, ++ OFFSET_FIFO_ADDR_CLR = 0x38, ++ OFFSET_IO_CONFIG = 0x40, ++ OFFSET_RSV_DEBUG = 0x44, ++ OFFSET_HS = 0x48, ++ OFFSET_SOFTRESET = 0x50, ++ OFFSET_DCM_EN = 0x54, ++ OFFSET_PATH_DIR = 0x60, ++ OFFSET_DEBUGSTAT = 0x64, ++ OFFSET_DEBUGCTRL = 0x68, ++ OFFSET_TRANSFER_LEN_AUX = 0x6c, ++}; ++ ++struct mtk_i2c_data { ++ unsigned int clk_frequency; /* bus speed in Hz */ ++ unsigned int flags; ++ unsigned int clk_src_div; ++}; ++ ++struct mtk_i2c_compatible { ++ const struct i2c_adapter_quirks *quirks; ++ unsigned char pmic_i2c; ++ unsigned char dcm; ++}; ++ ++struct mtk_i2c { ++ struct i2c_adapter adap; /* i2c host adapter */ ++ struct device *dev; ++ struct completion msg_complete; ++ ++ /* set in i2c probe */ ++ void __iomem *base; /* i2c base addr */ ++ void __iomem *pdmabase; /* dma base address*/ ++ struct clk *clk_main; /* main clock for i2c bus */ ++ struct clk *clk_dma; /* DMA clock for i2c via DMA */ ++ struct clk *clk_pmic; /* PMIC clock for i2c from PMIC */ ++ bool have_pmic; /* can use i2c pins from PMIC */ ++ bool use_push_pull; /* IO config push-pull mode */ ++ ++ u16 irq_stat; /* interrupt status */ ++ unsigned int speed_hz; /* The speed in transfer */ ++ enum mtk_trans_op op; ++ u16 timing_reg; ++ u16 high_speed_reg; ++ const struct mtk_i2c_compatible *dev_comp; ++}; ++ ++static const struct i2c_adapter_quirks mt6577_i2c_quirks = { ++ .flags = I2C_AQ_COMB_WRITE_THEN_READ, ++ .max_num_msgs = MAX_MSG_NUM_MT6577, ++ .max_write_len = MAX_DMA_TRANS_SIZE_MT6577, ++ .max_read_len = MAX_DMA_TRANS_SIZE_MT6577, ++ .max_comb_1st_msg_len = MAX_DMA_TRANS_SIZE_MT6577, ++ .max_comb_2nd_msg_len = MAX_WRRD_TRANS_SIZE_MT6577, ++}; ++ ++static const struct mtk_i2c_compatible mt6577_compat = { ++ .quirks = &mt6577_i2c_quirks, ++ .pmic_i2c = 0, ++ .dcm = 1, ++}; ++ ++static const struct mtk_i2c_compatible mt6589_compat = { ++ .quirks = &mt6577_i2c_quirks, ++ .pmic_i2c = 1, ++ .dcm = 0, ++}; ++ ++static const struct of_device_id mtk_i2c_of_match[] = { ++ { .compatible = "mediatek,mt6577-i2c", .data = (void *)&mt6577_compat }, ++ { .compatible = "mediatek,mt6589-i2c", .data = (void *)&mt6589_compat }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, mtk_i2c_of_match); ++ ++static inline void mtk_i2c_writew(u16 value, struct mtk_i2c *i2c, u8 offset) ++{ ++ writew(value, i2c->base + offset); ++} ++ ++static inline u16 mtk_i2c_readw(struct mtk_i2c *i2c, u8 offset) ++{ ++ return readw(i2c->base + offset); ++} ++ ++static inline void mtk_i2c_writel_dma(u32 value, struct mtk_i2c *i2c, u8 offset) ++{ ++ writel(value, i2c->pdmabase + offset); ++} ++ ++static int mtk_i2c_clock_enable(struct mtk_i2c *i2c) ++{ ++ int ret; ++ ++ ret = clk_prepare_enable(i2c->clk_dma); ++ if (ret) ++ return ret; ++ ++ ret = clk_prepare_enable(i2c->clk_main); ++ if (ret) ++ goto err_main; ++ ++ if (i2c->have_pmic) { ++ ret = clk_prepare_enable(i2c->clk_pmic); ++ if (ret) ++ goto err_pmic; ++ } ++ return 0; ++ ++err_pmic: ++ clk_disable_unprepare(i2c->clk_main); ++err_main: ++ clk_disable_unprepare(i2c->clk_dma); ++ ++ return ret; ++} ++ ++static void mtk_i2c_clock_disable(struct mtk_i2c *i2c) ++{ ++ if (i2c->have_pmic) ++ clk_disable_unprepare(i2c->clk_pmic); ++ ++ clk_disable_unprepare(i2c->clk_main); ++ clk_disable_unprepare(i2c->clk_dma); ++} ++ ++static void mtk_i2c_init_hw(struct mtk_i2c *i2c) ++{ ++ u16 control_reg; ++ ++ mtk_i2c_writew(I2C_SOFT_RST, i2c, OFFSET_SOFTRESET); ++ /* Set ioconfig */ ++ if (i2c->use_push_pull) ++ mtk_i2c_writew(I2C_IO_CONFIG_PUSH_PULL, i2c, OFFSET_IO_CONFIG); ++ else ++ mtk_i2c_writew(I2C_IO_CONFIG_OPEN_DRAIN, i2c, OFFSET_IO_CONFIG); ++ ++ if (i2c->dev_comp->dcm) ++ mtk_i2c_writew(I2C_DCM_DISABLE, i2c, OFFSET_DCM_EN); ++ ++ mtk_i2c_writew(i2c->timing_reg, i2c, OFFSET_TIMING); ++ mtk_i2c_writew(i2c->high_speed_reg, i2c, OFFSET_HS); ++ ++ /* If use i2c pin from PMIC mt6397 side, need set PATH_DIR first */ ++ if (i2c->have_pmic) ++ mtk_i2c_writew(I2C_CONTROL_WRAPPER, i2c, OFFSET_PATH_DIR); ++ ++ control_reg = I2C_CONTROL_ACKERR_DET_EN | ++ I2C_CONTROL_CLK_EXT_EN | I2C_CONTROL_DMA_EN; ++ mtk_i2c_writew(control_reg, i2c, OFFSET_CONTROL); ++ mtk_i2c_writew(I2C_DELAY_LEN, i2c, OFFSET_DELAY_LEN); ++} ++ ++/* calculate i2c port speed */ ++static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int clk_src_in_hz) ++{ ++ unsigned int khz; ++ unsigned int step_cnt; ++ unsigned int sample_cnt; ++ unsigned int sclk; ++ unsigned int hclk; ++ unsigned int max_step_cnt; ++ unsigned int sample_div = MAX_SAMPLE_CNT_DIV; ++ unsigned int step_div; ++ unsigned int min_div; ++ unsigned int best_mul; ++ unsigned int cnt_mul; ++ ++ if (i2c->speed_hz > MAX_HS_MODE_SPEED) ++ return -EINVAL; ++ else if (i2c->speed_hz > MAX_FS_MODE_SPEED) ++ max_step_cnt = MAX_HS_STEP_CNT_DIV; ++ else ++ max_step_cnt = MAX_STEP_CNT_DIV; ++ ++ step_div = max_step_cnt; ++ /* Find the best combination */ ++ khz = i2c->speed_hz / 1000; ++ hclk = clk_src_in_hz / 1000; ++ min_div = ((hclk >> 1) + khz - 1) / khz; ++ best_mul = MAX_SAMPLE_CNT_DIV * max_step_cnt; ++ ++ for (sample_cnt = 1; sample_cnt <= MAX_SAMPLE_CNT_DIV; sample_cnt++) { ++ step_cnt = (min_div + sample_cnt - 1) / sample_cnt; ++ cnt_mul = step_cnt * sample_cnt; ++ if (step_cnt > max_step_cnt) ++ continue; ++ ++ if (cnt_mul < best_mul) { ++ best_mul = cnt_mul; ++ sample_div = sample_cnt; ++ step_div = step_cnt; ++ if (best_mul == min_div) ++ break; ++ } ++ } ++ ++ sample_cnt = sample_div; ++ step_cnt = step_div; ++ sclk = hclk / (2 * sample_cnt * step_cnt); ++ if (sclk > khz) { ++ dev_dbg(i2c->dev, "%s mode: unsupported speed (%ldkhz)\n", ++ (i2c->speed_hz > MAX_HS_MODE_SPEED) ? "HS" : "ST/FT", ++ (long int)khz); ++ return -ENOTSUPP; ++ } ++ ++ step_cnt--; ++ sample_cnt--; ++ ++ if (i2c->speed_hz > MAX_FS_MODE_SPEED) { ++ /* Set the hign speed mode register */ ++ i2c->timing_reg = I2C_FS_TIME_INIT_VALUE; ++ i2c->high_speed_reg = I2C_TIME_DEFAULT_VALUE | ++ (sample_cnt & I2C_TIMING_SAMPLE_COUNT_MASK) << 12 | ++ (step_cnt & I2C_TIMING_SAMPLE_COUNT_MASK) << 8; ++ } else { ++ i2c->timing_reg = ++ (sample_cnt & I2C_TIMING_SAMPLE_COUNT_MASK) << 8 | ++ (step_cnt & I2C_TIMING_STEP_DIV_MASK) << 0; ++ /* Disable the high speed transaction */ ++ i2c->high_speed_reg = I2C_TIME_CLR_VALUE; ++ } ++ ++ return 0; ++} ++ ++static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs) ++{ ++ u16 addr_reg; ++ u16 control_reg; ++ dma_addr_t rpaddr = 0; ++ dma_addr_t wpaddr = 0; ++ int ret; ++ ++ i2c->irq_stat = 0; ++ ++ reinit_completion(&i2c->msg_complete); ++ ++ control_reg = mtk_i2c_readw(i2c, OFFSET_CONTROL) & ++ ~(I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS); ++ if (i2c->speed_hz > 400000) ++ control_reg |= I2C_CONTROL_RS; ++ if (i2c->op == I2C_MASTER_WRRD) ++ control_reg |= I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS; ++ mtk_i2c_writew(control_reg, i2c, OFFSET_CONTROL); ++ ++ /* set start condition */ ++ if (i2c->speed_hz <= 100000) ++ mtk_i2c_writew(I2C_ST_START_CON, i2c, OFFSET_EXT_CONF); ++ else ++ mtk_i2c_writew(I2C_FS_START_CON, i2c, OFFSET_EXT_CONF); ++ ++ addr_reg = msgs->addr << 1; ++ if (i2c->op == I2C_MASTER_RD) ++ addr_reg |= 0x1; ++ mtk_i2c_writew(addr_reg, i2c, OFFSET_SLAVE_ADDR); ++ ++ /* Clear interrupt status */ ++ mtk_i2c_writew(I2C_HS_NACKERR | I2C_ACKERR | I2C_TRANSAC_COMP, ++ i2c, OFFSET_INTR_STAT); ++ mtk_i2c_writew(I2C_FIFO_ADDR_CLR, i2c, OFFSET_FIFO_ADDR_CLR); ++ ++ /* Enable interrupt */ ++ mtk_i2c_writew(I2C_HS_NACKERR | I2C_ACKERR | I2C_TRANSAC_COMP, ++ i2c, OFFSET_INTR_MASK); ++ ++ /* Set transfer and transaction len */ ++ if (i2c->op == I2C_MASTER_WRRD) { ++ mtk_i2c_writew(msgs->len | ((msgs + 1)->len) << 8, ++ i2c, OFFSET_TRANSFER_LEN); ++ mtk_i2c_writew(I2C_WRRD_TRANAC_VALUE, i2c, OFFSET_TRANSAC_LEN); ++ } else { ++ mtk_i2c_writew(msgs->len, i2c, OFFSET_TRANSFER_LEN); ++ mtk_i2c_writew(I2C_RD_TRANAC_VALUE, i2c, OFFSET_TRANSAC_LEN); ++ } ++ ++ /* Prepare buffer data to start transfer */ ++ if (i2c->op == I2C_MASTER_RD) { ++ mtk_i2c_writel_dma(I2C_DMA_INT_FLAG_NONE, i2c, OFFSET_INT_FLAG); ++ mtk_i2c_writel_dma(I2C_DMA_CON_RX, i2c, OFFSET_CON); ++ rpaddr = dma_map_single(i2c->adap.dev.parent, msgs->buf, ++ msgs->len, DMA_FROM_DEVICE); ++ if (dma_mapping_error(i2c->adap.dev.parent, rpaddr)) ++ return -ENOMEM; ++ mtk_i2c_writel_dma((u32)rpaddr, i2c, OFFSET_RX_MEM_ADDR); ++ mtk_i2c_writel_dma(msgs->len, i2c, OFFSET_RX_LEN); ++ } else if (i2c->op == I2C_MASTER_WR) { ++ mtk_i2c_writel_dma(I2C_DMA_INT_FLAG_NONE, i2c, OFFSET_INT_FLAG); ++ mtk_i2c_writel_dma(I2C_DMA_CON_TX, i2c, OFFSET_CON); ++ wpaddr = dma_map_single(i2c->adap.dev.parent, msgs->buf, ++ msgs->len, DMA_TO_DEVICE); ++ if (dma_mapping_error(i2c->adap.dev.parent, wpaddr)) ++ return -ENOMEM; ++ mtk_i2c_writel_dma((u32)wpaddr, i2c, OFFSET_TX_MEM_ADDR); ++ mtk_i2c_writel_dma(msgs->len, i2c, OFFSET_TX_LEN); ++ } else { ++ mtk_i2c_writel_dma(I2C_DMA_CLR_FLAG, i2c, OFFSET_INT_FLAG); ++ mtk_i2c_writel_dma(I2C_DMA_CLR_FLAG, i2c, OFFSET_CON); ++ wpaddr = dma_map_single(i2c->adap.dev.parent, msgs->buf, ++ msgs->len, DMA_TO_DEVICE); ++ if (dma_mapping_error(i2c->adap.dev.parent, wpaddr)) ++ return -ENOMEM; ++ rpaddr = dma_map_single(i2c->adap.dev.parent, (msgs + 1)->buf, ++ (msgs + 1)->len, ++ DMA_FROM_DEVICE); ++ if (dma_mapping_error(i2c->adap.dev.parent, rpaddr)) { ++ dma_unmap_single(i2c->adap.dev.parent, wpaddr, ++ msgs->len, DMA_TO_DEVICE); ++ return -ENOMEM; ++ } ++ mtk_i2c_writel_dma((u32)wpaddr, i2c, OFFSET_TX_MEM_ADDR); ++ mtk_i2c_writel_dma((u32)rpaddr, i2c, OFFSET_RX_MEM_ADDR); ++ mtk_i2c_writel_dma(msgs->len, i2c, OFFSET_TX_LEN); ++ mtk_i2c_writel_dma((msgs + 1)->len, i2c, OFFSET_RX_LEN); ++ } ++ ++ /* flush before sending start */ ++ mb(); ++ mtk_i2c_writel_dma(I2C_DMA_START_EN, i2c, OFFSET_EN); ++ mtk_i2c_writew(I2C_TRANSAC_START, i2c, OFFSET_START); ++ ++ ret = wait_for_completion_timeout(&i2c->msg_complete, ++ i2c->adap.timeout); ++ ++ /* Clear interrupt mask */ ++ mtk_i2c_writew(~(I2C_HS_NACKERR | I2C_ACKERR ++ | I2C_TRANSAC_COMP), i2c, OFFSET_INTR_MASK); ++ ++ if (i2c->op == I2C_MASTER_WR) { ++ dma_unmap_single(i2c->adap.dev.parent, wpaddr, ++ msgs->len, DMA_TO_DEVICE); ++ } else if (i2c->op == I2C_MASTER_RD) { ++ dma_unmap_single(i2c->adap.dev.parent, rpaddr, ++ msgs->len, DMA_FROM_DEVICE); ++ } else { ++ dma_unmap_single(i2c->adap.dev.parent, wpaddr, msgs->len, ++ DMA_TO_DEVICE); ++ dma_unmap_single(i2c->adap.dev.parent, rpaddr, (msgs + 1)->len, ++ DMA_FROM_DEVICE); ++ } ++ ++ if (ret == 0) { ++ dev_dbg(i2c->dev, "addr: %x, transfer timeout\n", msgs->addr); ++ mtk_i2c_init_hw(i2c); ++ return -ETIMEDOUT; ++ } ++ ++ completion_done(&i2c->msg_complete); ++ ++ if (i2c->irq_stat & (I2C_HS_NACKERR | I2C_ACKERR)) { ++ dev_dbg(i2c->dev, "addr: %x, transfer ACK error\n", msgs->addr); ++ mtk_i2c_init_hw(i2c); ++ return -EREMOTEIO; ++ } ++ ++ return 0; ++} ++ ++static int mtk_i2c_transfer(struct i2c_adapter *adap, ++ struct i2c_msg msgs[], int num) ++{ ++ int ret; ++ int left_num = num; ++ struct mtk_i2c *i2c = i2c_get_adapdata(adap); ++ ++ ret = mtk_i2c_clock_enable(i2c); ++ if (ret) ++ return ret; ++ ++ if (msgs->buf == NULL) { ++ dev_dbg(i2c->dev, "data buffer is NULL.\n"); ++ ret = -EINVAL; ++ goto err_exit; ++ } ++ ++ if (msgs->flags & I2C_M_RD) ++ i2c->op = I2C_MASTER_RD; ++ else ++ i2c->op = I2C_MASTER_WR; ++ ++ if (num > 1) { ++ /* combined two messages into one transaction */ ++ i2c->op = I2C_MASTER_WRRD; ++ left_num--; ++ } ++ ++ /* always use DMA mode. */ ++ ret = mtk_i2c_do_transfer(i2c, msgs); ++ if (ret < 0) ++ goto err_exit; ++ ++ /* the return value is number of executed messages */ ++ ret = num; ++ ++err_exit: ++ mtk_i2c_clock_disable(i2c); ++ return ret; ++} ++ ++static irqreturn_t mtk_i2c_irq(int irqno, void *dev_id) ++{ ++ struct mtk_i2c *i2c = dev_id; ++ ++ i2c->irq_stat = mtk_i2c_readw(i2c, OFFSET_INTR_STAT); ++ mtk_i2c_writew(I2C_HS_NACKERR | I2C_ACKERR ++ | I2C_TRANSAC_COMP, i2c, OFFSET_INTR_STAT); ++ ++ complete(&i2c->msg_complete); ++ ++ return IRQ_HANDLED; ++} ++ ++static u32 mtk_i2c_functionality(struct i2c_adapter *adap) ++{ ++ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; ++} ++ ++static const struct i2c_algorithm mtk_i2c_algorithm = { ++ .master_xfer = mtk_i2c_transfer, ++ .functionality = mtk_i2c_functionality, ++}; ++ ++static int mtk_i2c_parse_dt(struct device_node *np, struct mtk_i2c *i2c, ++ unsigned int *clk_src_div) ++{ ++ int ret; ++ ++ ret = of_property_read_u32(np, "clock-frequency", &i2c->speed_hz); ++ if (ret < 0) ++ i2c->speed_hz = I2C_DEFAUT_SPEED; ++ ++ ret = of_property_read_u32(np, "clock-div", clk_src_div); ++ if (ret < 0) ++ return ret; ++ ++ if (*clk_src_div == 0) ++ return -EINVAL; ++ ++ i2c->have_pmic = of_property_read_bool(np, "mediatek,have-pmic"); ++ i2c->use_push_pull = ++ of_property_read_bool(np, "mediatek,use-push-pull"); ++ ++ return 0; ++} ++ ++static int mtk_i2c_probe(struct platform_device *pdev) ++{ ++ const struct of_device_id *of_id; ++ int ret = 0; ++ struct mtk_i2c *i2c; ++ struct clk *clk; ++ unsigned int clk_src_in_hz; ++ unsigned int clk_src_div; ++ struct resource *res; ++ int irq; ++ ++ i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); ++ if (i2c == NULL) ++ return -ENOMEM; ++ ++ ret = mtk_i2c_parse_dt(pdev->dev.of_node, i2c, &clk_src_div); ++ if (ret) ++ return -EINVAL; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ i2c->base = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(i2c->base)) ++ return PTR_ERR(i2c->base); ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ i2c->pdmabase = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(i2c->pdmabase)) ++ return PTR_ERR(i2c->pdmabase); ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq <= 0) ++ return irq; ++ ++ init_completion(&i2c->msg_complete); ++ ++ of_id = of_match_node(mtk_i2c_of_match, pdev->dev.of_node); ++ if (!of_id) ++ return -EINVAL; ++ ++ i2c->dev_comp = of_id->data; ++ i2c->adap.dev.of_node = pdev->dev.of_node; ++ i2c->dev = &i2c->adap.dev; ++ i2c->adap.dev.parent = &pdev->dev; ++ i2c->adap.owner = THIS_MODULE; ++ i2c->adap.algo = &mtk_i2c_algorithm; ++ i2c->adap.quirks = i2c->dev_comp->quirks; ++ i2c->adap.timeout = 2 * HZ; ++ i2c->adap.retries = 1; ++ ++ if (i2c->have_pmic && !i2c->dev_comp->pmic_i2c) ++ return -EINVAL; ++ ++ i2c->clk_main = devm_clk_get(&pdev->dev, "main"); ++ if (IS_ERR(i2c->clk_main)) { ++ dev_err(&pdev->dev, "cannot get main clock\n"); ++ return PTR_ERR(i2c->clk_main); ++ } ++ ++ i2c->clk_dma = devm_clk_get(&pdev->dev, "dma"); ++ if (IS_ERR(i2c->clk_dma)) { ++ dev_err(&pdev->dev, "cannot get dma clock\n"); ++ return PTR_ERR(i2c->clk_dma); ++ } ++ ++ clk = i2c->clk_main; ++ if (i2c->have_pmic) { ++ i2c->clk_pmic = devm_clk_get(&pdev->dev, "pmic"); ++ if (IS_ERR(i2c->clk_pmic)) { ++ dev_err(&pdev->dev, "cannot get pmic clock\n"); ++ return PTR_ERR(i2c->clk_pmic); ++ } ++ clk = i2c->clk_pmic; ++ } ++ clk_src_in_hz = clk_get_rate(clk) / clk_src_div; ++ ++ dev_dbg(&pdev->dev, "clock source %p,clock src frequency %d\n", ++ i2c->clk_main, clk_src_in_hz); ++ strlcpy(i2c->adap.name, I2C_DRV_NAME, sizeof(i2c->adap.name)); ++ ++ ret = mtk_i2c_set_speed(i2c, clk_src_in_hz); ++ if (ret) { ++ dev_err(&pdev->dev, "Failed to set the speed.\n"); ++ return -EINVAL; ++ } ++ ++ ret = mtk_i2c_clock_enable(i2c); ++ if (ret) { ++ dev_err(&pdev->dev, "clock enable failed!\n"); ++ return ret; ++ } ++ mtk_i2c_init_hw(i2c); ++ mtk_i2c_clock_disable(i2c); ++ ++ ret = devm_request_irq(&pdev->dev, irq, mtk_i2c_irq, ++ IRQF_TRIGGER_NONE, I2C_DRV_NAME, i2c); ++ if (ret < 0) { ++ dev_err(&pdev->dev, ++ "Request I2C IRQ %d fail\n", irq); ++ return ret; ++ } ++ ++ i2c_set_adapdata(&i2c->adap, i2c); ++ ret = i2c_add_adapter(&i2c->adap); ++ if (ret) { ++ dev_err(&pdev->dev, "Failed to add i2c bus to i2c core\n"); ++ return ret; ++ } ++ ++ platform_set_drvdata(pdev, i2c); ++ ++ return 0; ++} ++ ++static int mtk_i2c_remove(struct platform_device *pdev) ++{ ++ struct mtk_i2c *i2c = platform_get_drvdata(pdev); ++ ++ i2c_del_adapter(&i2c->adap); ++ ++ return 0; ++} ++ ++static struct platform_driver mtk_i2c_driver = { ++ .probe = mtk_i2c_probe, ++ .remove = mtk_i2c_remove, ++ .driver = { ++ .name = I2C_DRV_NAME, ++ .of_match_table = of_match_ptr(mtk_i2c_of_match), ++ }, ++}; ++ ++module_platform_driver(mtk_i2c_driver); ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_DESCRIPTION("MediaTek I2C Bus Driver"); ++MODULE_AUTHOR("Xudong Chen <xudong.chen@mediatek.com>"); +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0031-I2C-mediatek-Add-driver-for-MediaTek-MT8173-I2C-cont.patch b/target/linux/mediatek/patches/0031-I2C-mediatek-Add-driver-for-MediaTek-MT8173-I2C-cont.patch new file mode 100644 index 0000000000..25ea23ef23 --- /dev/null +++ b/target/linux/mediatek/patches/0031-I2C-mediatek-Add-driver-for-MediaTek-MT8173-I2C-cont.patch @@ -0,0 +1,244 @@ +From 5f33206ebe4fb4a2cc8634f29c3e3c9bc01e3416 Mon Sep 17 00:00:00 2001 +From: Eddie Huang <eddie.huang@mediatek.com> +Date: Wed, 6 May 2015 16:37:07 +0800 +Subject: [PATCH 31/76] I2C: mediatek: Add driver for MediaTek MT8173 I2C + controller + +Add mediatek MT8173 I2C controller driver. Compare to I2C controller +of earlier mediatek SoC, MT8173 fix write-then-read limitation, and +also increase message size to 64kb. + +Signed-off-by: Xudong Chen <xudong.chen@mediatek.com> +Signed-off-by: Liguo Zhang <liguo.zhang@mediatek.com> +Signed-off-by: Eddie Huang <eddie.huang@mediatek.com> +--- + drivers/i2c/busses/i2c-mt65xx.c | 104 ++++++++++++++++++++++++++++----------- + 1 file changed, 76 insertions(+), 28 deletions(-) + +diff --git a/drivers/i2c/busses/i2c-mt65xx.c b/drivers/i2c/busses/i2c-mt65xx.c +index faecf7e..c501421 100644 +--- a/drivers/i2c/busses/i2c-mt65xx.c ++++ b/drivers/i2c/busses/i2c-mt65xx.c +@@ -33,10 +33,13 @@ + #include <linux/clk.h> + #include <linux/completion.h> + ++#define I2C_RS_TRANSFER (1 << 4) + #define I2C_HS_NACKERR (1 << 2) + #define I2C_ACKERR (1 << 1) + #define I2C_TRANSAC_COMP (1 << 0) + #define I2C_TRANSAC_START (1 << 0) ++#define I2C_RS_MUL_CNFG (1 << 15) ++#define I2C_RS_MUL_TRIG (1 << 14) + #define I2C_TIMING_STEP_DIV_MASK (0x3f << 0) + #define I2C_TIMING_SAMPLE_COUNT_MASK (0x7 << 0) + #define I2C_TIMING_SAMPLE_DIV_MASK (0x7 << 8) +@@ -67,6 +70,9 @@ + #define MAX_MSG_NUM_MT6577 1 + #define MAX_DMA_TRANS_SIZE_MT6577 255 + #define MAX_WRRD_TRANS_SIZE_MT6577 31 ++#define MAX_MSG_NUM_MT8173 65535 ++#define MAX_DMA_TRANS_SIZE_MT8173 65535 ++#define MAX_WRRD_TRANS_SIZE_MT8173 65535 + #define MAX_SAMPLE_CNT_DIV 8 + #define MAX_STEP_CNT_DIV 64 + #define MAX_HS_STEP_CNT_DIV 8 +@@ -139,6 +145,7 @@ struct mtk_i2c_compatible { + const struct i2c_adapter_quirks *quirks; + unsigned char pmic_i2c; + unsigned char dcm; ++ unsigned char auto_restart; + }; + + struct mtk_i2c { +@@ -172,21 +179,39 @@ static const struct i2c_adapter_quirks mt6577_i2c_quirks = { + .max_comb_2nd_msg_len = MAX_WRRD_TRANS_SIZE_MT6577, + }; + ++static const struct i2c_adapter_quirks mt8173_i2c_quirks = { ++ .max_num_msgs = MAX_MSG_NUM_MT8173, ++ .max_write_len = MAX_DMA_TRANS_SIZE_MT8173, ++ .max_read_len = MAX_DMA_TRANS_SIZE_MT8173, ++ .max_comb_1st_msg_len = MAX_DMA_TRANS_SIZE_MT8173, ++ .max_comb_2nd_msg_len = MAX_WRRD_TRANS_SIZE_MT8173, ++}; ++ + static const struct mtk_i2c_compatible mt6577_compat = { + .quirks = &mt6577_i2c_quirks, + .pmic_i2c = 0, + .dcm = 1, ++ .auto_restart = 0, + }; + + static const struct mtk_i2c_compatible mt6589_compat = { + .quirks = &mt6577_i2c_quirks, + .pmic_i2c = 1, + .dcm = 0, ++ .auto_restart = 0, ++}; ++ ++static const struct mtk_i2c_compatible mt8173_compat = { ++ .quirks = &mt8173_i2c_quirks, ++ .pmic_i2c = 0, ++ .dcm = 1, ++ .auto_restart = 1, + }; + + static const struct of_device_id mtk_i2c_of_match[] = { + { .compatible = "mediatek,mt6577-i2c", .data = (void *)&mt6577_compat }, + { .compatible = "mediatek,mt6589-i2c", .data = (void *)&mt6589_compat }, ++ { .compatible = "mediatek,mt8173-i2c", .data = (void *)&mt8173_compat }, + {} + }; + MODULE_DEVICE_TABLE(of, mtk_i2c_of_match); +@@ -343,9 +368,11 @@ static int mtk_i2c_set_speed(struct mtk_i2c *i2c, unsigned int clk_src_in_hz) + return 0; + } + +-static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs) ++static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs, ++ int num, int left_num) + { + u16 addr_reg; ++ u16 start_reg; + u16 control_reg; + dma_addr_t rpaddr = 0; + dma_addr_t wpaddr = 0; +@@ -361,6 +388,8 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs) + control_reg |= I2C_CONTROL_RS; + if (i2c->op == I2C_MASTER_WRRD) + control_reg |= I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS; ++ if (left_num >= 1) ++ control_reg |= I2C_CONTROL_RS; + mtk_i2c_writew(control_reg, i2c, OFFSET_CONTROL); + + /* set start condition */ +@@ -375,13 +404,13 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs) + mtk_i2c_writew(addr_reg, i2c, OFFSET_SLAVE_ADDR); + + /* Clear interrupt status */ +- mtk_i2c_writew(I2C_HS_NACKERR | I2C_ACKERR | I2C_TRANSAC_COMP, +- i2c, OFFSET_INTR_STAT); ++ mtk_i2c_writew(I2C_RS_TRANSFER | I2C_HS_NACKERR | I2C_ACKERR ++ | I2C_TRANSAC_COMP, i2c, OFFSET_INTR_STAT); + mtk_i2c_writew(I2C_FIFO_ADDR_CLR, i2c, OFFSET_FIFO_ADDR_CLR); + + /* Enable interrupt */ +- mtk_i2c_writew(I2C_HS_NACKERR | I2C_ACKERR | I2C_TRANSAC_COMP, +- i2c, OFFSET_INTR_MASK); ++ mtk_i2c_writew(I2C_RS_TRANSFER | I2C_HS_NACKERR | I2C_ACKERR ++ | I2C_TRANSAC_COMP, i2c, OFFSET_INTR_MASK); + + /* Set transfer and transaction len */ + if (i2c->op == I2C_MASTER_WRRD) { +@@ -390,7 +419,7 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs) + mtk_i2c_writew(I2C_WRRD_TRANAC_VALUE, i2c, OFFSET_TRANSAC_LEN); + } else { + mtk_i2c_writew(msgs->len, i2c, OFFSET_TRANSFER_LEN); +- mtk_i2c_writew(I2C_RD_TRANAC_VALUE, i2c, OFFSET_TRANSAC_LEN); ++ mtk_i2c_writew(num, i2c, OFFSET_TRANSAC_LEN); + } + + /* Prepare buffer data to start transfer */ +@@ -436,13 +465,23 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs) + /* flush before sending start */ + mb(); + mtk_i2c_writel_dma(I2C_DMA_START_EN, i2c, OFFSET_EN); +- mtk_i2c_writew(I2C_TRANSAC_START, i2c, OFFSET_START); ++ ++ if (!i2c->dev_comp->auto_restart) { ++ start_reg = I2C_TRANSAC_START; ++ } else { ++ if (left_num >= 1) ++ start_reg = I2C_TRANSAC_START | I2C_RS_MUL_CNFG ++ | I2C_RS_MUL_TRIG; ++ else ++ start_reg = I2C_TRANSAC_START | I2C_RS_MUL_TRIG; ++ } ++ mtk_i2c_writew(start_reg, i2c, OFFSET_START); + + ret = wait_for_completion_timeout(&i2c->msg_complete, + i2c->adap.timeout); + + /* Clear interrupt mask */ +- mtk_i2c_writew(~(I2C_HS_NACKERR | I2C_ACKERR ++ mtk_i2c_writew(~(I2C_RS_TRANSFER | I2C_HS_NACKERR | I2C_ACKERR + | I2C_TRANSAC_COMP), i2c, OFFSET_INTR_MASK); + + if (i2c->op == I2C_MASTER_WR) { +@@ -472,6 +511,10 @@ static int mtk_i2c_do_transfer(struct mtk_i2c *i2c, struct i2c_msg *msgs) + return -EREMOTEIO; + } + ++ if (i2c->irq_stat & I2C_RS_TRANSFER) ++ dev_dbg(i2c->dev, "addr: %x, restart transfer interrupt.\n", ++ msgs->addr); ++ + return 0; + } + +@@ -486,28 +529,33 @@ static int mtk_i2c_transfer(struct i2c_adapter *adap, + if (ret) + return ret; + +- if (msgs->buf == NULL) { +- dev_dbg(i2c->dev, "data buffer is NULL.\n"); +- ret = -EINVAL; +- goto err_exit; +- } +- +- if (msgs->flags & I2C_M_RD) +- i2c->op = I2C_MASTER_RD; +- else +- i2c->op = I2C_MASTER_WR; ++ while (left_num--) { ++ if (msgs->buf == NULL) { ++ dev_dbg(i2c->dev, "data buffer is NULL.\n"); ++ ret = -EINVAL; ++ goto err_exit; ++ } + +- if (num > 1) { +- /* combined two messages into one transaction */ +- i2c->op = I2C_MASTER_WRRD; +- left_num--; +- } ++ if (msgs->flags & I2C_M_RD) ++ i2c->op = I2C_MASTER_RD; ++ else ++ i2c->op = I2C_MASTER_WR; ++ ++ if (!i2c->dev_comp->auto_restart) { ++ if (num > 1) { ++ /* combined two messages into one transaction */ ++ i2c->op = I2C_MASTER_WRRD; ++ left_num--; ++ } ++ } + +- /* always use DMA mode. */ +- ret = mtk_i2c_do_transfer(i2c, msgs); +- if (ret < 0) +- goto err_exit; ++ /* always use DMA mode. */ ++ ret = mtk_i2c_do_transfer(i2c, msgs, num, left_num); ++ if (ret < 0) ++ goto err_exit; + ++ msgs++; ++ } + /* the return value is number of executed messages */ + ret = num; + +@@ -521,7 +569,7 @@ static irqreturn_t mtk_i2c_irq(int irqno, void *dev_id) + struct mtk_i2c *i2c = dev_id; + + i2c->irq_stat = mtk_i2c_readw(i2c, OFFSET_INTR_STAT); +- mtk_i2c_writew(I2C_HS_NACKERR | I2C_ACKERR ++ mtk_i2c_writew(I2C_RS_TRANSFER | I2C_HS_NACKERR | I2C_ACKERR + | I2C_TRANSAC_COMP, i2c, OFFSET_INTR_STAT); + + complete(&i2c->msg_complete); +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0032-dt-bindings-mediatek-Add-MT8173-cpufreq-driver-bindi.patch b/target/linux/mediatek/patches/0032-dt-bindings-mediatek-Add-MT8173-cpufreq-driver-bindi.patch new file mode 100644 index 0000000000..7f3b249a05 --- /dev/null +++ b/target/linux/mediatek/patches/0032-dt-bindings-mediatek-Add-MT8173-cpufreq-driver-bindi.patch @@ -0,0 +1,150 @@ +From d83532fe7eb9cc7b8cc39dd9f2bbd9873d4e390b Mon Sep 17 00:00:00 2001 +From: "pi-cheng.chen" <pi-cheng.chen@linaro.org> +Date: Mon, 8 Jun 2015 20:29:20 +0800 +Subject: [PATCH 32/76] dt-bindings: mediatek: Add MT8173 cpufreq driver + binding + +This patch adds device tree binding document for MT8173 cpufreq driver. + +Signed-off-by: Pi-Cheng Chen <pi-cheng.chen@linaro.org> +--- + .../devicetree/bindings/cpufreq/cpufreq-mt8173.txt | 127 ++++++++++++++++++++ + 1 file changed, 127 insertions(+) + create mode 100644 Documentation/devicetree/bindings/cpufreq/cpufreq-mt8173.txt + +diff --git a/Documentation/devicetree/bindings/cpufreq/cpufreq-mt8173.txt b/Documentation/devicetree/bindings/cpufreq/cpufreq-mt8173.txt +new file mode 100644 +index 0000000..7708a65 +--- /dev/null ++++ b/Documentation/devicetree/bindings/cpufreq/cpufreq-mt8173.txt +@@ -0,0 +1,127 @@ ++ ++Mediatek MT8173 cpufreq driver ++------------------- ++ ++Mediatek MT8173 cpufreq driver for CPU frequency scaling. ++ ++Required properties: ++- clocks: A list of phandle + clock-specifier pairs for the clocks listed in clock names. ++- clock-names: Should contain the following: ++ "cpu" - The multiplexer for clock input of CPU cluster. ++ "intermediate" - A parent of "cpu" clock which is used as "intermediate" clock ++ source (usually MAINPLL) when the original CPU PLL is under ++ transition and not stable yet. ++- operating-points: Table of frequencies and voltage CPU could be transitioned into, ++ Frequency should be in KHz units and voltage should be in microvolts. ++- proc-supply: Regulator for Vproc of CPU cluster. ++ ++Optional properties: ++- sram-supply: Regulator for Vsram of CPU cluster. When present, the cpufreq driver ++ needs to do "voltage trace" to step by step scale up/down Vproc and ++ Vsram to fit SoC specific needs. When absent, the voltage scaling ++ flow is handled by hardware, hence no software "voltage trace" is ++ needed. ++ ++Example: ++-------- ++ cpu0: cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a53"; ++ reg = <0x000>; ++ enable-method = "psci"; ++ cpu-idle-states = <&CPU_SLEEP_0>; ++ clocks = <&infracfg CLK_INFRA_CA53SEL>, ++ <&apmixedsys CLK_APMIXED_MAINPLL>; ++ clock-names = "cpu", "intermediate"; ++ operating-points = < ++ 507000 859000 ++ 702000 908000 ++ 1001000 983000 ++ 1105000 1009000 ++ 1183000 1028000 ++ 1404000 1083000 ++ 1508000 1109000 ++ 1573000 1125000 ++ >; ++ }; ++ ++ cpu1: cpu@1 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a53"; ++ reg = <0x001>; ++ enable-method = "psci"; ++ cpu-idle-states = <&CPU_SLEEP_0>; ++ clocks = <&infracfg CLK_INFRA_CA53SEL>, ++ <&apmixedsys CLK_APMIXED_MAINPLL>; ++ clock-names = "cpu", "intermediate"; ++ operating-points = < ++ 507000 859000 ++ 702000 908000 ++ 1001000 983000 ++ 1105000 1009000 ++ 1183000 1028000 ++ 1404000 1083000 ++ 1508000 1109000 ++ 1573000 1125000 ++ >; ++ }; ++ ++ cpu2: cpu@100 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a57"; ++ reg = <0x100>; ++ enable-method = "psci"; ++ cpu-idle-states = <&CPU_SLEEP_0>; ++ clocks = <&infracfg CLK_INFRA_CA57SEL>, ++ <&apmixedsys CLK_APMIXED_MAINPLL>; ++ clock-names = "cpu", "intermediate"; ++ operating-points = < ++ 507000 828000 ++ 702000 867000 ++ 1001000 927000 ++ 1209000 968000 ++ 1404000 1007000 ++ 1612000 1049000 ++ 1807000 1089000 ++ 1989000 1125000 ++ >; ++ }; ++ ++ cpu3: cpu@101 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a57"; ++ reg = <0x101>; ++ enable-method = "psci"; ++ cpu-idle-states = <&CPU_SLEEP_0>; ++ clocks = <&infracfg CLK_INFRA_CA57SEL>, ++ <&apmixedsys CLK_APMIXED_MAINPLL>; ++ clock-names = "cpu", "intermediate"; ++ operating-points = < ++ 507000 828000 ++ 702000 867000 ++ 1001000 927000 ++ 1209000 968000 ++ 1404000 1007000 ++ 1612000 1049000 ++ 1807000 1089000 ++ 1989000 1125000 ++ >; ++ }; ++ ++ &cpu0 { ++ proc-supply = <&mt6397_vpca15_reg>; ++ }; ++ ++ &cpu1 { ++ proc-supply = <&mt6397_vpca15_reg>; ++ }; ++ ++ &cpu2 { ++ proc-supply = <&da9211_vcpu_reg>; ++ sram-supply = <&mt6397_vsramca7_reg>; ++ }; ++ ++ &cpu3 { ++ proc-supply = <&da9211_vcpu_reg>; ++ sram-supply = <&mt6397_vsramca7_reg>; ++ }; +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0033-cpufreq-mediatek-Add-MT8173-cpufreq-driver.patch b/target/linux/mediatek/patches/0033-cpufreq-mediatek-Add-MT8173-cpufreq-driver.patch new file mode 100644 index 0000000000..81ae4f8275 --- /dev/null +++ b/target/linux/mediatek/patches/0033-cpufreq-mediatek-Add-MT8173-cpufreq-driver.patch @@ -0,0 +1,604 @@ +From 2028cb37c941014f6a817d27a867ee1d37ccf2b6 Mon Sep 17 00:00:00 2001 +From: "pi-cheng.chen" <pi-cheng.chen@linaro.org> +Date: Mon, 8 Jun 2015 20:29:21 +0800 +Subject: [PATCH 33/76] cpufreq: mediatek: Add MT8173 cpufreq driver + +This patch implements MT8173 cpufreq driver. + +Signed-off-by: Pi-Cheng Chen <pi-cheng.chen@linaro.org> +--- + drivers/cpufreq/Kconfig.arm | 7 + + drivers/cpufreq/Makefile | 1 + + drivers/cpufreq/mt8173-cpufreq.c | 550 ++++++++++++++++++++++++++++++++++++++ + 3 files changed, 558 insertions(+) + create mode 100644 drivers/cpufreq/mt8173-cpufreq.c + +diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm +index 4f3dbc8..350752b 100644 +--- a/drivers/cpufreq/Kconfig.arm ++++ b/drivers/cpufreq/Kconfig.arm +@@ -141,6 +141,13 @@ config ARM_KIRKWOOD_CPUFREQ + This adds the CPUFreq driver for Marvell Kirkwood + SoCs. + ++config ARM_MT8173_CPUFREQ ++ bool "Mediatek MT8173 CPUFreq support" ++ depends on ARCH_MEDIATEK && REGULATOR ++ select PM_OPP ++ help ++ This adds the CPUFreq driver support for Mediatek MT8173 SoC. ++ + config ARM_OMAP2PLUS_CPUFREQ + bool "TI OMAP2+" + depends on ARCH_OMAP2PLUS +diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile +index cdce92a..97f9a9b 100644 +--- a/drivers/cpufreq/Makefile ++++ b/drivers/cpufreq/Makefile +@@ -63,6 +63,7 @@ obj-$(CONFIG_ARM_HISI_ACPU_CPUFREQ) += hisi-acpu-cpufreq.o + obj-$(CONFIG_ARM_IMX6Q_CPUFREQ) += imx6q-cpufreq.o + obj-$(CONFIG_ARM_INTEGRATOR) += integrator-cpufreq.o + obj-$(CONFIG_ARM_KIRKWOOD_CPUFREQ) += kirkwood-cpufreq.o ++obj-$(CONFIG_ARM_MT8173_CPUFREQ) += mt8173-cpufreq.o + obj-$(CONFIG_ARM_OMAP2PLUS_CPUFREQ) += omap-cpufreq.o + obj-$(CONFIG_ARM_PXA2xx_CPUFREQ) += pxa2xx-cpufreq.o + obj-$(CONFIG_PXA3xx) += pxa3xx-cpufreq.o +diff --git a/drivers/cpufreq/mt8173-cpufreq.c b/drivers/cpufreq/mt8173-cpufreq.c +new file mode 100644 +index 0000000..d539e7b +--- /dev/null ++++ b/drivers/cpufreq/mt8173-cpufreq.c +@@ -0,0 +1,550 @@ ++/* ++ * Copyright (c) 2015 Linaro Ltd. ++ * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/clk.h> ++#include <linux/cpu.h> ++#include <linux/cpufreq.h> ++#include <linux/cpumask.h> ++#include <linux/module.h> ++#include <linux/of.h> ++#include <linux/platform_device.h> ++#include <linux/pm_opp.h> ++#include <linux/regulator/consumer.h> ++#include <linux/slab.h> ++ ++#define MIN_VOLT_SHIFT (100000) ++#define MAX_VOLT_SHIFT (200000) ++#define MAX_VOLT_LIMIT (1150000) ++#define VOLT_TOL (10000) ++ ++/* ++ * The struct mtk_cpu_dvfs_info holds necessary information for doing CPU DVFS ++ * on each CPU power/clock domain of Mediatek SoCs. Each CPU cluster in ++ * Mediatek SoCs has two voltage inputs, Vproc and Vsram. In some cases the two ++ * voltage inputs need to be controlled under a hardware limitation: ++ * 100mV < Vsram - Vproc < 200mV ++ * ++ * When scaling the clock frequency of a CPU clock domain, the clock source ++ * needs to be switched to another stable PLL clock temporarily until ++ * the original PLL becomes stable at target frequency. ++ */ ++struct mtk_cpu_dvfs_info { ++ struct list_head node; ++ cpumask_var_t cpus; ++ struct cpufreq_frequency_table *freq_table; ++ struct device *cpu_dev; ++ struct regulator *proc_reg; ++ struct regulator *sram_reg; ++ struct clk *cpu_clk; ++ struct clk *inter_clk; ++ int intermediate_voltage; ++ bool need_voltage_trace; ++}; ++ ++static LIST_HEAD(cpu_dvfs_info_list); ++ ++static inline struct mtk_cpu_dvfs_info *to_mtk_cpu_dvfs_info( ++ struct list_head *list) ++{ ++ return list_entry(list, struct mtk_cpu_dvfs_info, node); ++} ++ ++static inline void mtk_cpu_dvfs_info_add(struct mtk_cpu_dvfs_info *info) ++{ ++ list_add(&info->node, &cpu_dvfs_info_list); ++} ++ ++static struct mtk_cpu_dvfs_info *mtk_cpu_dvfs_info_get(int cpu) ++{ ++ struct mtk_cpu_dvfs_info *info; ++ struct list_head *list; ++ ++ list_for_each(list, &cpu_dvfs_info_list) { ++ info = to_mtk_cpu_dvfs_info(list); ++ ++ if (cpumask_test_cpu(cpu, info->cpus)) ++ return info; ++ } ++ ++ return NULL; ++} ++ ++static void mtk_cpu_dvfs_info_release(void) ++{ ++ struct list_head *list, *tmp; ++ struct mtk_cpu_dvfs_info *info; ++ ++ list_for_each_safe(list, tmp, &cpu_dvfs_info_list) { ++ info = to_mtk_cpu_dvfs_info(list); ++ ++ dev_pm_opp_free_cpufreq_table(info->cpu_dev, ++ &info->freq_table); ++ ++ if (!IS_ERR(info->proc_reg)) ++ regulator_put(info->proc_reg); ++ if (!IS_ERR(info->sram_reg)) ++ regulator_put(info->sram_reg); ++ if (!IS_ERR(info->cpu_clk)) ++ clk_put(info->cpu_clk); ++ if (!IS_ERR(info->inter_clk)) ++ clk_put(info->inter_clk); ++ ++ of_free_opp_table(info->cpu_dev); ++ ++ list_del(list); ++ kfree(info); ++ } ++} ++ ++#define MIN(a, b) ((a) < (b) ? (a) : (b)) ++#define MAX(a, b) ((a) > (b) ? (a) : (b)) ++ ++static int mtk_cpufreq_voltage_trace(struct mtk_cpu_dvfs_info *info, ++ int new_vproc) ++{ ++ struct regulator *proc_reg = info->proc_reg; ++ struct regulator *sram_reg = info->sram_reg; ++ int old_vproc, old_vsram, new_vsram, vsram, vproc, ret; ++ ++ old_vproc = regulator_get_voltage(proc_reg); ++ old_vsram = regulator_get_voltage(sram_reg); ++ /* Vsram should not exceed the maximum allowed voltage of SoC. */ ++ new_vsram = min(new_vproc + MIN_VOLT_SHIFT, MAX_VOLT_LIMIT); ++ ++ if (old_vproc < new_vproc) { ++ /* ++ * When scaling up voltages, Vsram and Vproc scale up step ++ * by step. At each step, set Vsram to (Vproc + 200mV) first, ++ * then set Vproc to (Vsram - 100mV). ++ * Keep doing it until Vsram and Vproc hit target voltages. ++ */ ++ do { ++ old_vsram = regulator_get_voltage(sram_reg); ++ old_vproc = regulator_get_voltage(proc_reg); ++ ++ vsram = MIN(new_vsram, old_vproc + MAX_VOLT_SHIFT); ++ ++ if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT) { ++ vsram = MAX_VOLT_LIMIT; ++ ++ /* ++ * If the target Vsram hits the maximum voltage, ++ * try to set the exact voltage value first. ++ */ ++ ret = regulator_set_voltage(sram_reg, vsram, ++ vsram); ++ if (ret) ++ ret = regulator_set_voltage(sram_reg, ++ vsram - VOLT_TOL, ++ vsram); ++ ++ vproc = new_vproc; ++ } else { ++ ret = regulator_set_voltage(sram_reg, vsram, ++ vsram + VOLT_TOL); ++ ++ vproc = vsram - MIN_VOLT_SHIFT; ++ } ++ if (ret) ++ return ret; ++ ++ ret = regulator_set_voltage(proc_reg, vproc, ++ vproc + VOLT_TOL); ++ if (ret) { ++ regulator_set_voltage(sram_reg, old_vsram, ++ old_vsram); ++ return ret; ++ } ++ } while (vproc < new_vproc || vsram < new_vsram); ++ } else if (old_vproc > new_vproc) { ++ /* ++ * When scaling down voltages, Vsram and Vproc scale down step ++ * by step. At each step, set Vproc to (Vsram - 200mV) first, ++ * then set Vproc to (Vproc + 100mV). ++ * Keep doing it until Vsram and Vproc hit target voltages. ++ */ ++ do { ++ old_vproc = regulator_get_voltage(proc_reg); ++ old_vsram = regulator_get_voltage(sram_reg); ++ ++ vproc = MAX(new_vproc, old_vsram - MAX_VOLT_SHIFT); ++ ret = regulator_set_voltage(proc_reg, vproc, ++ vproc + VOLT_TOL); ++ if (ret) ++ return ret; ++ ++ if (vproc == new_vproc) ++ vsram = new_vsram; ++ else ++ vsram = MAX(new_vsram, vproc + MIN_VOLT_SHIFT); ++ ++ if (vsram + VOLT_TOL >= MAX_VOLT_LIMIT) { ++ vsram = MAX_VOLT_LIMIT; ++ ++ /* ++ * If the target Vsram hits the maximum voltage, ++ * try to set the exact voltage value first. ++ */ ++ ret = regulator_set_voltage(sram_reg, vsram, ++ vsram); ++ if (ret) ++ ret = regulator_set_voltage(sram_reg, ++ vsram - VOLT_TOL, ++ vsram); ++ } else { ++ ret = regulator_set_voltage(sram_reg, vsram, ++ vsram + VOLT_TOL); ++ } ++ ++ if (ret) { ++ regulator_set_voltage(proc_reg, old_vproc, ++ old_vproc); ++ return ret; ++ } ++ } while (vproc > new_vproc + VOLT_TOL || ++ vsram > new_vsram + VOLT_TOL); ++ } ++ ++ return 0; ++} ++ ++static int mtk_cpufreq_set_voltage(struct mtk_cpu_dvfs_info *info, int vproc) ++{ ++ if (info->need_voltage_trace) ++ return mtk_cpufreq_voltage_trace(info, vproc); ++ else ++ return regulator_set_voltage(info->proc_reg, vproc, ++ vproc + VOLT_TOL); ++} ++ ++static int mtk_cpufreq_set_target(struct cpufreq_policy *policy, ++ unsigned int index) ++{ ++ struct cpufreq_frequency_table *freq_table = policy->freq_table; ++ struct clk *cpu_clk = policy->clk; ++ struct clk *armpll = clk_get_parent(cpu_clk); ++ struct mtk_cpu_dvfs_info *info = policy->driver_data; ++ struct device *cpu_dev = info->cpu_dev; ++ struct dev_pm_opp *opp; ++ long freq_hz, old_freq_hz; ++ int vproc, old_vproc, inter_vproc, target_vproc, ret; ++ ++ inter_vproc = info->intermediate_voltage; ++ ++ old_freq_hz = clk_get_rate(cpu_clk); ++ old_vproc = regulator_get_voltage(info->proc_reg); ++ ++ freq_hz = freq_table[index].frequency * 1000; ++ rcu_read_lock(); ++ opp = dev_pm_opp_find_freq_ceil(cpu_dev, &freq_hz); ++ if (IS_ERR(opp)) { ++ rcu_read_unlock(); ++ pr_err("cpu%d: failed to find OPP for %ld\n", ++ policy->cpu, freq_hz); ++ return PTR_ERR(opp); ++ } ++ vproc = dev_pm_opp_get_voltage(opp); ++ rcu_read_unlock(); ++ ++ /* ++ * If the new voltage or the intermediate voltage is higher than the ++ * current voltage, scale up voltage first. ++ */ ++ target_vproc = (inter_vproc > vproc) ? inter_vproc : vproc; ++ if (old_vproc < target_vproc) { ++ ret = mtk_cpufreq_set_voltage(info, target_vproc); ++ if (ret) { ++ pr_err("cpu%d: failed to scale up voltage!\n", ++ policy->cpu); ++ mtk_cpufreq_set_voltage(info, old_vproc); ++ return ret; ++ } ++ } ++ ++ /* Reparent the CPU clock to intermediate clock. */ ++ ret = clk_set_parent(cpu_clk, info->inter_clk); ++ if (ret) { ++ pr_err("cpu%d: failed to re-parent cpu clock!\n", ++ policy->cpu); ++ mtk_cpufreq_set_voltage(info, old_vproc); ++ WARN_ON(1); ++ return ret; ++ } ++ ++ /* Set the original PLL to target rate. */ ++ ret = clk_set_rate(armpll, freq_hz); ++ if (ret) { ++ pr_err("cpu%d: failed to scale cpu clock rate!\n", ++ policy->cpu); ++ clk_set_parent(cpu_clk, armpll); ++ mtk_cpufreq_set_voltage(info, old_vproc); ++ return ret; ++ } ++ ++ /* Set parent of CPU clock back to the original PLL. */ ++ ret = clk_set_parent(cpu_clk, armpll); ++ if (ret) { ++ pr_err("cpu%d: failed to re-parent cpu clock!\n", ++ policy->cpu); ++ mtk_cpufreq_set_voltage(info, inter_vproc); ++ WARN_ON(1); ++ return ret; ++ } ++ ++ /* ++ * If the new voltage is lower than the intermediate voltage or the ++ * original voltage, scale down to the new voltage. ++ */ ++ if (vproc < inter_vproc || vproc < old_vproc) { ++ ret = mtk_cpufreq_set_voltage(info, vproc); ++ if (ret) { ++ pr_err("cpu%d: failed to scale down voltage!\n", ++ policy->cpu); ++ clk_set_parent(cpu_clk, info->inter_clk); ++ clk_set_rate(armpll, old_freq_hz); ++ clk_set_parent(cpu_clk, armpll); ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ ++static int mtk_cpufreq_init(struct cpufreq_policy *policy) ++{ ++ struct mtk_cpu_dvfs_info *info; ++ int ret; ++ ++ info = mtk_cpu_dvfs_info_get(policy->cpu); ++ if (!info) { ++ pr_err("%s: mtk cpu dvfs info for cpu%d is not initialized\n", ++ __func__, policy->cpu); ++ return -ENODEV; ++ } ++ ++ ret = cpufreq_table_validate_and_show(policy, info->freq_table); ++ if (ret) { ++ pr_err("%s: invalid frequency table: %d\n", __func__, ret); ++ return ret; ++ } ++ ++ cpumask_copy(policy->cpus, info->cpus); ++ policy->driver_data = info; ++ policy->clk = info->cpu_clk; ++ ++ return 0; ++} ++ ++static struct cpufreq_driver mt8173_cpufreq_driver = { ++ .flags = CPUFREQ_STICKY | CPUFREQ_NEED_INITIAL_FREQ_CHECK, ++ .verify = cpufreq_generic_frequency_table_verify, ++ .target_index = mtk_cpufreq_set_target, ++ .get = cpufreq_generic_get, ++ .init = mtk_cpufreq_init, ++ .name = "mtk-cpufreq", ++ .attr = cpufreq_generic_attr, ++}; ++ ++static int mtk_cpu_dvfs_info_init(int cpu) ++{ ++ struct device *cpu_dev; ++ struct regulator *proc_reg = ERR_PTR(-ENODEV); ++ struct regulator *sram_reg = ERR_PTR(-ENODEV); ++ struct clk *cpu_clk = ERR_PTR(-ENODEV); ++ struct clk *inter_clk = ERR_PTR(-ENODEV); ++ struct mtk_cpu_dvfs_info *info; ++ struct cpufreq_frequency_table *freq_table; ++ struct dev_pm_opp *opp; ++ unsigned long rate; ++ int ret; ++ ++ cpu_dev = get_cpu_device(cpu); ++ if (!cpu_dev) { ++ pr_err("failed to get cpu%d device\n", cpu); ++ return -ENODEV; ++ } ++ ++ ret = of_init_opp_table(cpu_dev); ++ if (ret) { ++ pr_warn("no OPP table for cpu%d\n", cpu); ++ return ret; ++ } ++ ++ cpu_clk = clk_get(cpu_dev, "cpu"); ++ if (IS_ERR(cpu_clk)) { ++ if (PTR_ERR(cpu_clk) == -EPROBE_DEFER) ++ pr_warn("cpu clk for cpu%d not ready, retry.\n", cpu); ++ else ++ pr_err("failed to get cpu clk for cpu%d\n", cpu); ++ ++ ret = PTR_ERR(cpu_clk); ++ goto out_free_opp_table; ++ } ++ ++ inter_clk = clk_get(cpu_dev, "intermediate"); ++ if (IS_ERR(inter_clk)) { ++ if (PTR_ERR(inter_clk) == -EPROBE_DEFER) ++ pr_warn("intermediate clk for cpu%d not ready, retry.\n", ++ cpu); ++ else ++ pr_err("failed to get intermediate clk for cpu%d\n", ++ cpu); ++ ++ ret = PTR_ERR(cpu_clk); ++ goto out_free_resources; ++ } ++ ++ proc_reg = regulator_get_exclusive(cpu_dev, "proc"); ++ if (IS_ERR(proc_reg)) { ++ if (PTR_ERR(proc_reg) == -EPROBE_DEFER) ++ pr_warn("proc regulator for cpu%d not ready, retry.\n", ++ cpu); ++ else ++ pr_err("failed to get proc regulator for cpu%d\n", ++ cpu); ++ ++ ret = PTR_ERR(proc_reg); ++ goto out_free_resources; ++ } ++ ++ /* Both presence and absence of sram regulator are valid cases. */ ++ sram_reg = regulator_get_exclusive(cpu_dev, "sram"); ++ ++ info = kzalloc(sizeof(*info), GFP_KERNEL); ++ if (!info) { ++ ret = -ENOMEM; ++ goto out_free_resources; ++ } ++ ++ ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &freq_table); ++ if (ret) { ++ pr_err("failed to init cpufreq table for cpu%d: %d\n", ++ cpu, ret); ++ goto out_free_mtk_cpu_dvfs_info; ++ } ++ ++ if (!alloc_cpumask_var(&info->cpus, GFP_KERNEL)) ++ goto out_free_cpufreq_table; ++ ++ /* Search a safe voltage for intermediate frequency. */ ++ rate = clk_get_rate(inter_clk); ++ rcu_read_lock(); ++ opp = dev_pm_opp_find_freq_ceil(cpu_dev, &rate); ++ if (IS_ERR(opp)) { ++ pr_err("failed to get intermediate opp for cpu%d\n", cpu); ++ ret = PTR_ERR(opp); ++ goto out_free_cpumask; ++ } ++ info->intermediate_voltage = dev_pm_opp_get_voltage(opp); ++ rcu_read_unlock(); ++ ++ /* CPUs in the same cluster share a clock and power domain. */ ++ cpumask_copy(info->cpus, &cpu_topology[cpu].core_sibling); ++ ++ info->cpu_dev = cpu_dev; ++ info->proc_reg = proc_reg; ++ info->sram_reg = IS_ERR(sram_reg) ? NULL : sram_reg; ++ info->cpu_clk = cpu_clk; ++ info->inter_clk = inter_clk; ++ info->freq_table = freq_table; ++ ++ /* ++ * If SRAM regulator is present, software "voltage trace" is needed ++ * for this CPU power domain. ++ */ ++ info->need_voltage_trace = !IS_ERR(sram_reg); ++ ++ mtk_cpu_dvfs_info_add(info); ++ ++ return 0; ++ ++out_free_cpumask: ++ free_cpumask_var(info->cpus); ++ ++out_free_cpufreq_table: ++ dev_pm_opp_free_cpufreq_table(cpu_dev, &freq_table); ++ ++out_free_mtk_cpu_dvfs_info: ++ kfree(info); ++ ++out_free_resources: ++ if (!IS_ERR(proc_reg)) ++ regulator_put(proc_reg); ++ if (!IS_ERR(sram_reg)) ++ regulator_put(sram_reg); ++ if (!IS_ERR(cpu_clk)) ++ clk_put(cpu_clk); ++ if (!IS_ERR(inter_clk)) ++ clk_put(inter_clk); ++ ++out_free_opp_table: ++ of_free_opp_table(cpu_dev); ++ ++ return ret; ++} ++ ++static int mt8173_cpufreq_probe(struct platform_device *pdev) ++{ ++ int cpu, ret; ++ ++ for_each_possible_cpu(cpu) { ++ /* ++ * If the struct mtk_cpu_dvfs_info for the cpu power domain ++ * is already initialized, skip this CPU. ++ */ ++ if (!mtk_cpu_dvfs_info_get(cpu)) { ++ ret = mtk_cpu_dvfs_info_init(cpu); ++ if (ret) { ++ if (ret != -EPROBE_DEFER) ++ pr_err("%s probe fail\n", __func__); ++ ++ mtk_cpu_dvfs_info_release(); ++ return ret; ++ } ++ } ++ } ++ ++ ret = cpufreq_register_driver(&mt8173_cpufreq_driver); ++ if (ret) { ++ pr_err("failed to register mtk cpufreq driver\n"); ++ mtk_cpu_dvfs_info_release(); ++ } ++ ++ return ret; ++} ++ ++static struct platform_driver mt8173_cpufreq_platdrv = { ++ .driver = { ++ .name = "mt8173-cpufreq", ++ }, ++ .probe = mt8173_cpufreq_probe, ++}; ++module_platform_driver(mt8173_cpufreq_platdrv); ++ ++static int mt8173_cpufreq_driver_init(void) ++{ ++ struct platform_device *pdev; ++ ++ if (!of_machine_is_compatible("mediatek,mt8173")) ++ return -ENODEV; ++ ++ pdev = platform_device_register_simple("mt8173-cpufreq", -1, NULL, 0); ++ if (IS_ERR(pdev)) { ++ pr_err("failed to register mtk-cpufreq platform device\n"); ++ return PTR_ERR(pdev); ++ } ++ ++ return 0; ++} ++module_init(mt8173_cpufreq_driver_init); +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0034-mmc-dt-bindings-add-Mediatek-MMC-bindings.patch b/target/linux/mediatek/patches/0034-mmc-dt-bindings-add-Mediatek-MMC-bindings.patch new file mode 100644 index 0000000000..02a153d7da --- /dev/null +++ b/target/linux/mediatek/patches/0034-mmc-dt-bindings-add-Mediatek-MMC-bindings.patch @@ -0,0 +1,54 @@ +From fe43da8836dbf8e48377d208000877a17e465f3f Mon Sep 17 00:00:00 2001 +From: Chaotian Jing <chaotian.jing@mediatek.com> +Date: Mon, 15 Jun 2015 19:20:47 +0800 +Subject: [PATCH 34/76] mmc: dt-bindings: add Mediatek MMC bindings + +Document the device-tree binding of Mediatek MMC host + +Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com> +--- + Documentation/devicetree/bindings/mmc/mtk-sd.txt | 32 ++++++++++++++++++++++ + 1 file changed, 32 insertions(+) + create mode 100644 Documentation/devicetree/bindings/mmc/mtk-sd.txt + +diff --git a/Documentation/devicetree/bindings/mmc/mtk-sd.txt b/Documentation/devicetree/bindings/mmc/mtk-sd.txt +new file mode 100644 +index 0000000..a1adfa4 +--- /dev/null ++++ b/Documentation/devicetree/bindings/mmc/mtk-sd.txt +@@ -0,0 +1,32 @@ ++* MTK MMC controller ++ ++The MTK MSDC can act as a MMC controller ++to support MMC, SD, and SDIO types of memory cards. ++ ++This file documents differences between the core properties in mmc.txt ++and the properties used by the msdc driver. ++ ++Required properties: ++- compatible: Should be "mediatek,mt8173-mmc","mediatek,mt8135-mmc" ++- interrupts: Should contain MSDC interrupt number ++- clocks: MSDC source clock, HCLK ++- clock-names: "source", "hclk" ++- pinctrl-names: should be "default", "state_uhs" ++- pinctrl-0: should contain default/high speed pin ctrl ++- pinctrl-1: should contain uhs mode pin ctrl ++- vmmc-supply: power to the Core ++- vqmmc-supply: power to the IO ++ ++Examples: ++mmc0: mmc@11230000 { ++ compatible = "mediatek,mt8173-mmc", "mediatek,mt8135-mmc"; ++ reg = <0 0x11230000 0 0x108>; ++ interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_LOW>; ++ vmmc-supply = <&mt6397_vemc_3v3_reg>; ++ vqmmc-supply = <&mt6397_vio18_reg>; ++ clocks = <&pericfg CLK_PERI_MSDC30_0>, <&topckgen CLK_TOP_MSDC50_0_H_SEL>; ++ clock-names = "source", "hclk"; ++ pinctrl-names = "default", "state_uhs"; ++ pinctrl-0 = <&mmc0_pins_default>; ++ pinctrl-1 = <&mmc0_pins_uhs>; ++}; +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0035-mmc-mediatek-Add-Mediatek-MMC-driver.patch b/target/linux/mediatek/patches/0035-mmc-mediatek-Add-Mediatek-MMC-driver.patch new file mode 100644 index 0000000000..d135ad0432 --- /dev/null +++ b/target/linux/mediatek/patches/0035-mmc-mediatek-Add-Mediatek-MMC-driver.patch @@ -0,0 +1,1422 @@ +From 0b71d2f1ee40313f58a3c6e9ed95add6f5a8192d Mon Sep 17 00:00:00 2001 +From: Chaotian Jing <chaotian.jing@mediatek.com> +Date: Mon, 15 Jun 2015 19:20:48 +0800 +Subject: [PATCH 35/76] mmc: mediatek: Add Mediatek MMC driver + +Add Mediatek MMC driver code +Support eMMC/SD/SDIO + +Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com> +--- + drivers/mmc/host/Kconfig | 8 + + drivers/mmc/host/Makefile | 1 + + drivers/mmc/host/mtk-sd.c | 1378 +++++++++++++++++++++++++++++++++++++++++++++ + include/linux/mmc/core.h | 1 + + 4 files changed, 1388 insertions(+) + create mode 100644 drivers/mmc/host/mtk-sd.c + +--- a/drivers/mmc/host/Kconfig ++++ b/drivers/mmc/host/Kconfig +@@ -800,3 +800,11 @@ + tristate "Toshiba Type A SD/MMC Card Interface Driver" + depends on PCI + help ++ ++config MMC_MTK ++ tristate "MediaTek SD/MMC Card Interface support" ++ help ++ This selects the MediaTek(R) Secure digital and Multimedia card Interface. ++ If you have a machine with a integrated SD/MMC card reader, say Y or M here. ++ This is needed if support for any SD/SDIO/MMC devices is required. ++ If unsure, say N. +--- a/drivers/mmc/host/Makefile ++++ b/drivers/mmc/host/Makefile +@@ -20,6 +20,7 @@ + obj-$(CONFIG_MMC_SDHCI_SPEAR) += sdhci-spear.o + obj-$(CONFIG_MMC_WBSD) += wbsd.o + obj-$(CONFIG_MMC_AU1X) += au1xmmc.o ++obj-$(CONFIG_MMC_MTK) += mtk-sd.o + obj-$(CONFIG_MMC_OMAP) += omap.o + obj-$(CONFIG_MMC_OMAP_HS) += omap_hsmmc.o + obj-$(CONFIG_MMC_ATMELMCI) += atmel-mci.o +--- /dev/null ++++ b/drivers/mmc/host/mtk-sd.c +@@ -0,0 +1,1378 @@ ++/* ++ * Copyright (c) 2014-2015 MediaTek Inc. ++ * Author: Chaotian.Jing <chaotian.jing@mediatek.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/clk.h> ++#include <linux/delay.h> ++#include <linux/dma-mapping.h> ++#include <linux/ioport.h> ++#include <linux/irq.h> ++#include <linux/of_address.h> ++#include <linux/of_irq.h> ++#include <linux/of_gpio.h> ++#include <linux/pinctrl/consumer.h> ++#include <linux/platform_device.h> ++#include <linux/regulator/consumer.h> ++#include <linux/spinlock.h> ++ ++#include <linux/mmc/card.h> ++#include <linux/mmc/core.h> ++#include <linux/mmc/host.h> ++#include <linux/mmc/mmc.h> ++#include <linux/mmc/sd.h> ++#include <linux/mmc/sdio.h> ++ ++#define MAX_BD_NUM 1024 ++ ++/*--------------------------------------------------------------------------*/ ++/* Common Definition */ ++/*--------------------------------------------------------------------------*/ ++#define MSDC_BUS_1BITS 0x0 ++#define MSDC_BUS_4BITS 0x1 ++#define MSDC_BUS_8BITS 0x2 ++ ++#define MSDC_BURST_64B 0x6 ++ ++/*--------------------------------------------------------------------------*/ ++/* Register Offset */ ++/*--------------------------------------------------------------------------*/ ++#define MSDC_CFG 0x0 ++#define MSDC_IOCON 0x04 ++#define MSDC_PS 0x08 ++#define MSDC_INT 0x0c ++#define MSDC_INTEN 0x10 ++#define MSDC_FIFOCS 0x14 ++#define SDC_CFG 0x30 ++#define SDC_CMD 0x34 ++#define SDC_ARG 0x38 ++#define SDC_STS 0x3c ++#define SDC_RESP0 0x40 ++#define SDC_RESP1 0x44 ++#define SDC_RESP2 0x48 ++#define SDC_RESP3 0x4c ++#define SDC_BLK_NUM 0x50 ++#define SDC_ACMD_RESP 0x80 ++#define MSDC_DMA_SA 0x90 ++#define MSDC_DMA_CTRL 0x98 ++#define MSDC_DMA_CFG 0x9c ++#define MSDC_PATCH_BIT 0xb0 ++#define MSDC_PATCH_BIT1 0xb4 ++#define MSDC_PAD_TUNE 0xec ++ ++/*--------------------------------------------------------------------------*/ ++/* Register Mask */ ++/*--------------------------------------------------------------------------*/ ++ ++/* MSDC_CFG mask */ ++#define MSDC_CFG_MODE (0x1 << 0) /* RW */ ++#define MSDC_CFG_CKPDN (0x1 << 1) /* RW */ ++#define MSDC_CFG_RST (0x1 << 2) /* RW */ ++#define MSDC_CFG_PIO (0x1 << 3) /* RW */ ++#define MSDC_CFG_CKDRVEN (0x1 << 4) /* RW */ ++#define MSDC_CFG_BV18SDT (0x1 << 5) /* RW */ ++#define MSDC_CFG_BV18PSS (0x1 << 6) /* R */ ++#define MSDC_CFG_CKSTB (0x1 << 7) /* R */ ++#define MSDC_CFG_CKDIV (0xff << 8) /* RW */ ++#define MSDC_CFG_CKMOD (0x3 << 16) /* RW */ ++ ++/* MSDC_IOCON mask */ ++#define MSDC_IOCON_SDR104CKS (0x1 << 0) /* RW */ ++#define MSDC_IOCON_RSPL (0x1 << 1) /* RW */ ++#define MSDC_IOCON_DSPL (0x1 << 2) /* RW */ ++#define MSDC_IOCON_DDLSEL (0x1 << 3) /* RW */ ++#define MSDC_IOCON_DDR50CKD (0x1 << 4) /* RW */ ++#define MSDC_IOCON_DSPLSEL (0x1 << 5) /* RW */ ++#define MSDC_IOCON_W_DSPL (0x1 << 8) /* RW */ ++#define MSDC_IOCON_D0SPL (0x1 << 16) /* RW */ ++#define MSDC_IOCON_D1SPL (0x1 << 17) /* RW */ ++#define MSDC_IOCON_D2SPL (0x1 << 18) /* RW */ ++#define MSDC_IOCON_D3SPL (0x1 << 19) /* RW */ ++#define MSDC_IOCON_D4SPL (0x1 << 20) /* RW */ ++#define MSDC_IOCON_D5SPL (0x1 << 21) /* RW */ ++#define MSDC_IOCON_D6SPL (0x1 << 22) /* RW */ ++#define MSDC_IOCON_D7SPL (0x1 << 23) /* RW */ ++#define MSDC_IOCON_RISCSZ (0x3 << 24) /* RW */ ++ ++/* MSDC_PS mask */ ++#define MSDC_PS_CDEN (0x1 << 0) /* RW */ ++#define MSDC_PS_CDSTS (0x1 << 1) /* R */ ++#define MSDC_PS_CDDEBOUNCE (0xf << 12) /* RW */ ++#define MSDC_PS_DAT (0xff << 16) /* R */ ++#define MSDC_PS_CMD (0x1 << 24) /* R */ ++#define MSDC_PS_WP (0x1 << 31) /* R */ ++ ++/* MSDC_INT mask */ ++#define MSDC_INT_MMCIRQ (0x1 << 0) /* W1C */ ++#define MSDC_INT_CDSC (0x1 << 1) /* W1C */ ++#define MSDC_INT_ACMDRDY (0x1 << 3) /* W1C */ ++#define MSDC_INT_ACMDTMO (0x1 << 4) /* W1C */ ++#define MSDC_INT_ACMDCRCERR (0x1 << 5) /* W1C */ ++#define MSDC_INT_DMAQ_EMPTY (0x1 << 6) /* W1C */ ++#define MSDC_INT_SDIOIRQ (0x1 << 7) /* W1C */ ++#define MSDC_INT_CMDRDY (0x1 << 8) /* W1C */ ++#define MSDC_INT_CMDTMO (0x1 << 9) /* W1C */ ++#define MSDC_INT_RSPCRCERR (0x1 << 10) /* W1C */ ++#define MSDC_INT_CSTA (0x1 << 11) /* R */ ++#define MSDC_INT_XFER_COMPL (0x1 << 12) /* W1C */ ++#define MSDC_INT_DXFER_DONE (0x1 << 13) /* W1C */ ++#define MSDC_INT_DATTMO (0x1 << 14) /* W1C */ ++#define MSDC_INT_DATCRCERR (0x1 << 15) /* W1C */ ++#define MSDC_INT_ACMD19_DONE (0x1 << 16) /* W1C */ ++#define MSDC_INT_DMA_BDCSERR (0x1 << 17) /* W1C */ ++#define MSDC_INT_DMA_GPDCSERR (0x1 << 18) /* W1C */ ++#define MSDC_INT_DMA_PROTECT (0x1 << 19) /* W1C */ ++ ++/* MSDC_INTEN mask */ ++#define MSDC_INTEN_MMCIRQ (0x1 << 0) /* RW */ ++#define MSDC_INTEN_CDSC (0x1 << 1) /* RW */ ++#define MSDC_INTEN_ACMDRDY (0x1 << 3) /* RW */ ++#define MSDC_INTEN_ACMDTMO (0x1 << 4) /* RW */ ++#define MSDC_INTEN_ACMDCRCERR (0x1 << 5) /* RW */ ++#define MSDC_INTEN_DMAQ_EMPTY (0x1 << 6) /* RW */ ++#define MSDC_INTEN_SDIOIRQ (0x1 << 7) /* RW */ ++#define MSDC_INTEN_CMDRDY (0x1 << 8) /* RW */ ++#define MSDC_INTEN_CMDTMO (0x1 << 9) /* RW */ ++#define MSDC_INTEN_RSPCRCERR (0x1 << 10) /* RW */ ++#define MSDC_INTEN_CSTA (0x1 << 11) /* RW */ ++#define MSDC_INTEN_XFER_COMPL (0x1 << 12) /* RW */ ++#define MSDC_INTEN_DXFER_DONE (0x1 << 13) /* RW */ ++#define MSDC_INTEN_DATTMO (0x1 << 14) /* RW */ ++#define MSDC_INTEN_DATCRCERR (0x1 << 15) /* RW */ ++#define MSDC_INTEN_ACMD19_DONE (0x1 << 16) /* RW */ ++#define MSDC_INTEN_DMA_BDCSERR (0x1 << 17) /* RW */ ++#define MSDC_INTEN_DMA_GPDCSERR (0x1 << 18) /* RW */ ++#define MSDC_INTEN_DMA_PROTECT (0x1 << 19) /* RW */ ++ ++/* MSDC_FIFOCS mask */ ++#define MSDC_FIFOCS_RXCNT (0xff << 0) /* R */ ++#define MSDC_FIFOCS_TXCNT (0xff << 16) /* R */ ++#define MSDC_FIFOCS_CLR (0x1 << 31) /* RW */ ++ ++/* SDC_CFG mask */ ++#define SDC_CFG_SDIOINTWKUP (0x1 << 0) /* RW */ ++#define SDC_CFG_INSWKUP (0x1 << 1) /* RW */ ++#define SDC_CFG_BUSWIDTH (0x3 << 16) /* RW */ ++#define SDC_CFG_SDIO (0x1 << 19) /* RW */ ++#define SDC_CFG_SDIOIDE (0x1 << 20) /* RW */ ++#define SDC_CFG_INTATGAP (0x1 << 21) /* RW */ ++#define SDC_CFG_DTOC (0xff << 24) /* RW */ ++ ++/* SDC_STS mask */ ++#define SDC_STS_SDCBUSY (0x1 << 0) /* RW */ ++#define SDC_STS_CMDBUSY (0x1 << 1) /* RW */ ++#define SDC_STS_SWR_COMPL (0x1 << 31) /* RW */ ++ ++/* MSDC_DMA_CTRL mask */ ++#define MSDC_DMA_CTRL_START (0x1 << 0) /* W */ ++#define MSDC_DMA_CTRL_STOP (0x1 << 1) /* W */ ++#define MSDC_DMA_CTRL_RESUME (0x1 << 2) /* W */ ++#define MSDC_DMA_CTRL_MODE (0x1 << 8) /* RW */ ++#define MSDC_DMA_CTRL_LASTBUF (0x1 << 10) /* RW */ ++#define MSDC_DMA_CTRL_BRUSTSZ (0x7 << 12) /* RW */ ++ ++/* MSDC_DMA_CFG mask */ ++#define MSDC_DMA_CFG_STS (0x1 << 0) /* R */ ++#define MSDC_DMA_CFG_DECSEN (0x1 << 1) /* RW */ ++#define MSDC_DMA_CFG_AHBHPROT2 (0x2 << 8) /* RW */ ++#define MSDC_DMA_CFG_ACTIVEEN (0x2 << 12) /* RW */ ++#define MSDC_DMA_CFG_CS12B16B (0x1 << 16) /* RW */ ++ ++/* MSDC_PATCH_BIT mask */ ++#define MSDC_PATCH_BIT_ODDSUPP (0x1 << 1) /* RW */ ++#define MSDC_INT_DAT_LATCH_CK_SEL (0x7 << 7) ++#define MSDC_CKGEN_MSDC_DLY_SEL (0x1f << 10) ++#define MSDC_PATCH_BIT_IODSSEL (0x1 << 16) /* RW */ ++#define MSDC_PATCH_BIT_IOINTSEL (0x1 << 17) /* RW */ ++#define MSDC_PATCH_BIT_BUSYDLY (0xf << 18) /* RW */ ++#define MSDC_PATCH_BIT_WDOD (0xf << 22) /* RW */ ++#define MSDC_PATCH_BIT_IDRTSEL (0x1 << 26) /* RW */ ++#define MSDC_PATCH_BIT_CMDFSEL (0x1 << 27) /* RW */ ++#define MSDC_PATCH_BIT_INTDLSEL (0x1 << 28) /* RW */ ++#define MSDC_PATCH_BIT_SPCPUSH (0x1 << 29) /* RW */ ++#define MSDC_PATCH_BIT_DECRCTMO (0x1 << 30) /* RW */ ++ ++#define REQ_CMD_EIO (0x1 << 0) ++#define REQ_CMD_TMO (0x1 << 1) ++#define REQ_DAT_ERR (0x1 << 2) ++#define REQ_STOP_EIO (0x1 << 3) ++#define REQ_STOP_TMO (0x1 << 4) ++#define REQ_CMD_BUSY (0x1 << 5) ++ ++#define MSDC_PREPARE_FLAG (0x1 << 0) ++#define MSDC_ASYNC_FLAG (0x1 << 1) ++#define MSDC_MMAP_FLAG (0x1 << 2) ++ ++#define CMD_TIMEOUT (HZ/10 * 5) /* 100ms x5 */ ++#define DAT_TIMEOUT (HZ * 5) /* 1000ms x5 */ ++ ++/*--------------------------------------------------------------------------*/ ++/* Descriptor Structure */ ++/*--------------------------------------------------------------------------*/ ++struct mt_gpdma_desc { ++ u32 gpd_info; ++#define GPDMA_DESC_HWO (0x1 << 0) ++#define GPDMA_DESC_BDP (0x1 << 1) ++#define GPDMA_DESC_CHECKSUM (0xff << 8) /* bit8 ~ bit15 */ ++#define GPDMA_DESC_INT (0x1 << 16) ++ u32 next; ++ u32 ptr; ++ u32 gpd_data_len; ++#define GPDMA_DESC_BUFLEN (0xffff) /* bit0 ~ bit15 */ ++#define GPDMA_DESC_EXTLEN (0xff << 16) /* bit16 ~ bit23 */ ++ u32 arg; ++ u32 blknum; ++ u32 cmd; ++}; ++ ++struct mt_bdma_desc { ++ u32 bd_info; ++#define BDMA_DESC_EOL (0x1 << 0) ++#define BDMA_DESC_CHECKSUM (0xff << 8) /* bit8 ~ bit15 */ ++#define BDMA_DESC_BLKPAD (0x1 << 17) ++#define BDMA_DESC_DWPAD (0x1 << 18) ++ u32 next; ++ u32 ptr; ++ u32 bd_data_len; ++#define BDMA_DESC_BUFLEN (0xffff) /* bit0 ~ bit15 */ ++}; ++ ++struct msdc_dma { ++ struct scatterlist *sg; /* I/O scatter list */ ++ struct mt_gpdma_desc *gpd; /* pointer to gpd array */ ++ struct mt_bdma_desc *bd; /* pointer to bd array */ ++ dma_addr_t gpd_addr; /* the physical address of gpd array */ ++ dma_addr_t bd_addr; /* the physical address of bd array */ ++}; ++ ++struct msdc_host { ++ struct device *dev; ++ struct mmc_host *mmc; /* mmc structure */ ++ int cmd_rsp; ++ ++ spinlock_t lock; ++ struct mmc_request *mrq; ++ struct mmc_command *cmd; ++ struct mmc_data *data; ++ int error; ++ ++ void __iomem *base; /* host base address */ ++ ++ struct msdc_dma dma; /* dma channel */ ++ u64 dma_mask; ++ ++ u32 timeout_ns; /* data timeout ns */ ++ u32 timeout_clks; /* data timeout clks */ ++ ++ struct pinctrl *pinctrl; ++ struct pinctrl_state *pins_default; ++ struct pinctrl_state *pins_uhs; ++ struct delayed_work req_timeout; ++ int irq; /* host interrupt */ ++ ++ struct clk *src_clk; /* msdc source clock */ ++ struct clk *h_clk; /* msdc h_clk */ ++ u32 mclk; /* mmc subsystem clock frequency */ ++ u32 src_clk_freq; /* source clock frequency */ ++ u32 sclk; /* SD/MS bus clock frequency */ ++ bool ddr; ++ bool vqmmc_enabled; ++}; ++ ++static void sdr_set_bits(void __iomem *reg, u32 bs) ++{ ++ u32 val = readl(reg); ++ ++ val |= bs; ++ writel(val, reg); ++} ++ ++static void sdr_clr_bits(void __iomem *reg, u32 bs) ++{ ++ u32 val = readl(reg); ++ ++ val &= ~bs; ++ writel(val, reg); ++} ++ ++static void sdr_set_field(void __iomem *reg, u32 field, u32 val) ++{ ++ unsigned int tv = readl(reg); ++ ++ tv &= ~field; ++ tv |= ((val) << (ffs((unsigned int)field) - 1)); ++ writel(tv, reg); ++} ++ ++static void sdr_get_field(void __iomem *reg, u32 field, u32 *val) ++{ ++ unsigned int tv = readl(reg); ++ ++ *val = ((tv & field) >> (ffs((unsigned int)field) - 1)); ++} ++ ++static void msdc_reset_hw(struct msdc_host *host) ++{ ++ u32 val; ++ ++ sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_RST); ++ while (readl(host->base + MSDC_CFG) & MSDC_CFG_RST) ++ cpu_relax(); ++ ++ sdr_set_bits(host->base + MSDC_FIFOCS, MSDC_FIFOCS_CLR); ++ while (readl(host->base + MSDC_FIFOCS) & MSDC_FIFOCS_CLR) ++ cpu_relax(); ++ ++ val = readl(host->base + MSDC_INT); ++ writel(val, host->base + MSDC_INT); ++} ++ ++static void msdc_cmd_next(struct msdc_host *host, ++ struct mmc_request *mrq, struct mmc_command *cmd); ++ ++static u32 data_ints_mask = MSDC_INTEN_XFER_COMPL | MSDC_INTEN_DATTMO | ++ MSDC_INTEN_DATCRCERR | MSDC_INTEN_DMA_BDCSERR | ++ MSDC_INTEN_DMA_GPDCSERR | MSDC_INTEN_DMA_PROTECT; ++ ++static u8 msdc_dma_calcs(u8 *buf, u32 len) ++{ ++ u32 i, sum = 0; ++ ++ for (i = 0; i < len; i++) ++ sum += buf[i]; ++ return 0xff - (u8) sum; ++} ++ ++static inline void msdc_dma_setup(struct msdc_host *host, struct msdc_dma *dma, ++ struct mmc_data *data) ++{ ++ unsigned int j, dma_len; ++ dma_addr_t dma_address; ++ u32 dma_ctrl; ++ struct scatterlist *sg; ++ struct mt_gpdma_desc *gpd; ++ struct mt_bdma_desc *bd; ++ ++ sg = data->sg; ++ ++ gpd = dma->gpd; ++ bd = dma->bd; ++ ++ /* modify gpd */ ++ gpd->gpd_info |= GPDMA_DESC_HWO; ++ gpd->gpd_info |= GPDMA_DESC_BDP; ++ /* need to clear first. use these bits to calc checksum */ ++ gpd->gpd_info &= ~GPDMA_DESC_CHECKSUM; ++ gpd->gpd_info |= msdc_dma_calcs((u8 *) gpd, 16) << 8; ++ ++ /* modify bd */ ++ for_each_sg(data->sg, sg, data->sg_count, j) { ++ dma_address = sg_dma_address(sg); ++ dma_len = sg_dma_len(sg); ++ ++ /* init bd */ ++ bd[j].bd_info &= ~BDMA_DESC_BLKPAD; ++ bd[j].bd_info &= ~BDMA_DESC_DWPAD; ++ bd[j].ptr = (u32)dma_address; ++ bd[j].bd_data_len &= ~BDMA_DESC_BUFLEN; ++ bd[j].bd_data_len |= (dma_len & BDMA_DESC_BUFLEN); ++ ++ if (j == data->sg_count - 1) /* the last bd */ ++ bd[j].bd_info |= BDMA_DESC_EOL; ++ else ++ bd[j].bd_info &= ~BDMA_DESC_EOL; ++ ++ /* checksume need to clear first */ ++ bd[j].bd_info &= ~BDMA_DESC_CHECKSUM; ++ bd[j].bd_info |= msdc_dma_calcs((u8 *)(&bd[j]), 16) << 8; ++ } ++ ++ sdr_set_field(host->base + MSDC_DMA_CFG, MSDC_DMA_CFG_DECSEN, 1); ++ dma_ctrl = readl_relaxed(host->base + MSDC_DMA_CTRL); ++ dma_ctrl &= ~(MSDC_DMA_CTRL_BRUSTSZ | MSDC_DMA_CTRL_MODE); ++ dma_ctrl |= (MSDC_BURST_64B << 12 | 1 << 8); ++ writel_relaxed(dma_ctrl, host->base + MSDC_DMA_CTRL); ++ writel((u32)dma->gpd_addr, host->base + MSDC_DMA_SA); ++} ++ ++static void msdc_prepare_data(struct msdc_host *host, struct mmc_request *mrq) ++{ ++ struct mmc_data *data = mrq->data; ++ ++ if (!(data->host_cookie & MSDC_PREPARE_FLAG)) { ++ bool read = (data->flags & MMC_DATA_READ) != 0; ++ ++ data->host_cookie |= MSDC_PREPARE_FLAG; ++ data->sg_count = dma_map_sg(host->dev, data->sg, data->sg_len, ++ read ? DMA_FROM_DEVICE : DMA_TO_DEVICE); ++ } ++} ++ ++static void msdc_unprepare_data(struct msdc_host *host, struct mmc_request *mrq) ++{ ++ struct mmc_data *data = mrq->data; ++ ++ if (data->host_cookie & MSDC_ASYNC_FLAG) ++ return; ++ ++ if (data->host_cookie & MSDC_PREPARE_FLAG) { ++ bool read = (data->flags & MMC_DATA_READ) != 0; ++ ++ dma_unmap_sg(host->dev, data->sg, data->sg_len, ++ read ? DMA_FROM_DEVICE : DMA_TO_DEVICE); ++ data->host_cookie &= ~MSDC_PREPARE_FLAG; ++ } ++} ++ ++/* clock control primitives */ ++static void msdc_set_timeout(struct msdc_host *host, u32 ns, u32 clks) ++{ ++ u32 timeout, clk_ns; ++ u32 mode = 0; ++ ++ host->timeout_ns = ns; ++ host->timeout_clks = clks; ++ if (host->sclk == 0) { ++ timeout = 0; ++ } else { ++ clk_ns = 1000000000UL / host->sclk; ++ timeout = (ns + clk_ns - 1) / clk_ns + clks; ++ /* in 1048576 sclk cycle unit */ ++ timeout = (timeout + (0x1 << 20) - 1) >> 20; ++ sdr_get_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD, &mode); ++ /*DDR mode will double the clk cycles for data timeout */ ++ timeout = mode >= 2 ? timeout * 2 : timeout; ++ timeout = timeout > 1 ? timeout - 1 : 0; ++ timeout = timeout > 255 ? 255 : timeout; ++ } ++ sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, timeout); ++} ++ ++static void msdc_gate_clock(struct msdc_host *host) ++{ ++ clk_disable_unprepare(host->src_clk); ++ clk_disable_unprepare(host->h_clk); ++} ++ ++static void msdc_ungate_clock(struct msdc_host *host) ++{ ++ clk_prepare_enable(host->h_clk); ++ clk_prepare_enable(host->src_clk); ++ while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB)) ++ cpu_relax(); ++} ++ ++static void msdc_set_mclk(struct msdc_host *host, int ddr, u32 hz) ++{ ++ u32 mode; ++ u32 flags; ++ u32 div; ++ u32 sclk; ++ ++ if (!hz) { ++ dev_dbg(host->dev, "set mclk to 0\n"); ++ host->mclk = 0; ++ sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN); ++ return; ++ } ++ ++ flags = readl(host->base + MSDC_INTEN); ++ sdr_clr_bits(host->base + MSDC_INTEN, flags); ++ if (ddr) { /* may need to modify later */ ++ mode = 0x2; /* ddr mode and use divisor */ ++ if (hz >= (host->src_clk_freq >> 2)) { ++ div = 0; /* mean div = 1/4 */ ++ sclk = host->src_clk_freq >> 2; /* sclk = clk / 4 */ ++ } else { ++ div = (host->src_clk_freq + ((hz << 2) - 1)) / (hz << 2); ++ sclk = (host->src_clk_freq >> 2) / div; ++ div = (div >> 1); ++ } ++ } else if (hz >= host->src_clk_freq) { ++ mode = 0x1; /* no divisor */ ++ div = 0; ++ sclk = host->src_clk_freq; ++ } else { ++ mode = 0x0; /* use divisor */ ++ if (hz >= (host->src_clk_freq >> 1)) { ++ div = 0; /* mean div = 1/2 */ ++ sclk = host->src_clk_freq >> 1; /* sclk = clk / 2 */ ++ } else { ++ div = (host->src_clk_freq + ((hz << 2) - 1)) / (hz << 2); ++ sclk = (host->src_clk_freq >> 2) / div; ++ } ++ } ++ sdr_set_field(host->base + MSDC_CFG, MSDC_CFG_CKMOD | MSDC_CFG_CKDIV, ++ (mode << 8) | (div % 0xff)); ++ sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN); ++ while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB)) ++ cpu_relax(); ++ host->sclk = sclk; ++ host->mclk = hz; ++ host->ddr = ddr; ++ /* need because clk changed. */ ++ msdc_set_timeout(host, host->timeout_ns, host->timeout_clks); ++ sdr_set_bits(host->base + MSDC_INTEN, flags); ++ ++ dev_dbg(host->dev, "sclk: %d, ddr: %d\n", host->sclk, ddr); ++} ++ ++static inline u32 msdc_cmd_find_resp(struct msdc_host *host, ++ struct mmc_request *mrq, struct mmc_command *cmd) ++{ ++ u32 resp; ++ ++ switch (mmc_resp_type(cmd)) { ++ /* Actually, R1, R5, R6, R7 are the same */ ++ case MMC_RSP_R1: ++ resp = 0x1; ++ break; ++ case MMC_RSP_R1B: ++ resp = 0x7; ++ break; ++ case MMC_RSP_R2: ++ resp = 0x2; ++ break; ++ case MMC_RSP_R3: ++ resp = 0x3; ++ break; ++ case MMC_RSP_NONE: ++ default: ++ resp = 0x0; ++ break; ++ } ++ ++ return resp; ++} ++ ++static inline u32 msdc_cmd_prepare_raw_cmd(struct msdc_host *host, ++ struct mmc_request *mrq, struct mmc_command *cmd) ++{ ++ /* rawcmd : ++ * vol_swt << 30 | auto_cmd << 28 | blklen << 16 | go_irq << 15 | ++ * stop << 14 | rw << 13 | dtype << 11 | rsptyp << 7 | brk << 6 | opcode ++ */ ++ u32 opcode = cmd->opcode; ++ u32 resp = msdc_cmd_find_resp(host, mrq, cmd); ++ u32 rawcmd = (opcode & 0x3f) | ((resp & 0x7) << 7); ++ ++ host->cmd_rsp = resp; ++ ++ if ((opcode == SD_IO_RW_DIRECT && cmd->flags == (unsigned int) -1) || ++ opcode == MMC_STOP_TRANSMISSION) ++ rawcmd |= (0x1 << 14); ++ else if (opcode == SD_SWITCH_VOLTAGE) ++ rawcmd |= (0x1 << 30); ++ else if (opcode == SD_APP_SEND_SCR || ++ opcode == SD_APP_SEND_NUM_WR_BLKS || ++ (opcode == SD_SWITCH && mmc_cmd_type(cmd) == MMC_CMD_ADTC) || ++ (opcode == SD_APP_SD_STATUS && mmc_cmd_type(cmd) == MMC_CMD_ADTC) || ++ (opcode == MMC_SEND_EXT_CSD && mmc_cmd_type(cmd) == MMC_CMD_ADTC)) ++ rawcmd |= (0x1 << 11); ++ ++ if (cmd->data) { ++ struct mmc_data *data = cmd->data; ++ ++ if (mmc_op_multi(opcode)) { ++ if (mmc_card_mmc(host->mmc->card) && mrq->sbc && ++ !(mrq->sbc->arg & 0xFFFF0000)) ++ rawcmd |= 0x2 << 28; /* AutoCMD23 */ ++ } ++ ++ rawcmd |= ((data->blksz & 0xFFF) << 16); ++ if (data->flags & MMC_DATA_WRITE) ++ rawcmd |= (0x1 << 13); ++ if (data->blocks > 1) ++ rawcmd |= (0x2 << 11); ++ else ++ rawcmd |= (0x1 << 11); ++ /* Always use dma mode */ ++ sdr_clr_bits(host->base + MSDC_CFG, MSDC_CFG_PIO); ++ ++ if (host->timeout_ns != data->timeout_ns || ++ host->timeout_clks != data->timeout_clks) ++ msdc_set_timeout(host, data->timeout_ns, ++ data->timeout_clks); ++ ++ writel(data->blocks, host->base + SDC_BLK_NUM); ++ } ++ return rawcmd; ++} ++ ++static void msdc_start_data(struct msdc_host *host, struct mmc_request *mrq, ++ struct mmc_command *cmd, struct mmc_data *data) ++{ ++ bool read; ++ ++ WARN_ON(host->data); ++ host->data = data; ++ read = data->flags & MMC_DATA_READ; ++ ++ mod_delayed_work(system_wq, &host->req_timeout, DAT_TIMEOUT); ++ msdc_dma_setup(host, &host->dma, data); ++ sdr_set_bits(host->base + MSDC_INTEN, data_ints_mask); ++ sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_START, 1); ++ dev_dbg(host->dev, "DMA start\n"); ++ dev_dbg(host->dev, "%s: cmd=%d DMA data: %d blocks; read=%d\n", ++ __func__, cmd->opcode, data->blocks, read); ++} ++ ++static int msdc_auto_cmd_done(struct msdc_host *host, int events, ++ struct mmc_command *cmd) ++{ ++ u32 *rsp = cmd->resp; ++ ++ rsp[0] = readl(host->base + SDC_ACMD_RESP); ++ ++ if (events & MSDC_INT_ACMDRDY) { ++ cmd->error = 0; ++ } else { ++ msdc_reset_hw(host); ++ if (events & MSDC_INT_ACMDCRCERR) { ++ cmd->error = -EILSEQ; ++ host->error |= REQ_STOP_EIO; ++ } else if (events & MSDC_INT_ACMDTMO) { ++ cmd->error = -ETIMEDOUT; ++ host->error |= REQ_STOP_TMO; ++ } ++ dev_err(host->dev, ++ "%s: AUTO_CMD%d arg=%08X; rsp %08X; cmd_error=%d\n", ++ __func__, cmd->opcode, cmd->arg, rsp[0], cmd->error); ++ } ++ return cmd->error; ++} ++ ++static void msdc_track_cmd_data(struct msdc_host *host, ++ struct mmc_command *cmd, struct mmc_data *data) ++{ ++ if (host->error) ++ dev_dbg(host->dev, "%s: cmd=%d arg=%08X; host->error=0x%08X\n", ++ __func__, cmd->opcode, cmd->arg, host->error); ++} ++ ++static void msdc_request_done(struct msdc_host *host, struct mmc_request *mrq) ++{ ++ unsigned long flags; ++ bool ret; ++ ++ ret = cancel_delayed_work(&host->req_timeout); ++ if (!ret) { ++ /* delay work already running */ ++ return; ++ } ++ spin_lock_irqsave(&host->lock, flags); ++ host->mrq = NULL; ++ spin_unlock_irqrestore(&host->lock, flags); ++ ++ msdc_track_cmd_data(host, mrq->cmd, mrq->data); ++ if (mrq->data) ++ msdc_unprepare_data(host, mrq); ++ mmc_request_done(host->mmc, mrq); ++} ++ ++/* returns true if command is fully handled; returns false otherwise */ ++static bool msdc_cmd_done(struct msdc_host *host, int events, ++ struct mmc_request *mrq, struct mmc_command *cmd) ++{ ++ bool done = false; ++ bool sbc_error; ++ unsigned long flags; ++ u32 *rsp = cmd->resp; ++ ++ if (mrq->sbc && cmd == mrq->cmd && ++ (events & (MSDC_INT_ACMDRDY | MSDC_INT_ACMDCRCERR ++ | MSDC_INT_ACMDTMO))) ++ msdc_auto_cmd_done(host, events, mrq->sbc); ++ ++ sbc_error = mrq->sbc && mrq->sbc->error; ++ ++ if (!sbc_error && !(events & (MSDC_INT_CMDRDY ++ | MSDC_INT_RSPCRCERR ++ | MSDC_INT_CMDTMO))) ++ return done; ++ ++ spin_lock_irqsave(&host->lock, flags); ++ done = !host->cmd; ++ host->cmd = NULL; ++ spin_unlock_irqrestore(&host->lock, flags); ++ ++ if (done) ++ return true; ++ ++ sdr_clr_bits(host->base + MSDC_INTEN, MSDC_INTEN_CMDRDY | ++ MSDC_INTEN_RSPCRCERR | MSDC_INTEN_CMDTMO | ++ MSDC_INTEN_ACMDRDY | MSDC_INTEN_ACMDCRCERR | ++ MSDC_INTEN_ACMDTMO); ++ writel(cmd->arg, host->base + SDC_ARG); ++ ++ if (cmd->flags & MMC_RSP_PRESENT) { ++ if (cmd->flags & MMC_RSP_136) { ++ rsp[0] = readl(host->base + SDC_RESP3); ++ rsp[1] = readl(host->base + SDC_RESP2); ++ rsp[2] = readl(host->base + SDC_RESP1); ++ rsp[3] = readl(host->base + SDC_RESP0); ++ } else { ++ rsp[0] = readl(host->base + SDC_RESP0); ++ } ++ } ++ ++ if (!sbc_error && !(events & MSDC_INT_CMDRDY)) { ++ msdc_reset_hw(host); ++ if (events & MSDC_INT_RSPCRCERR) { ++ cmd->error = -EILSEQ; ++ host->error |= REQ_CMD_EIO; ++ } else if (events & MSDC_INT_CMDTMO) { ++ cmd->error = -ETIMEDOUT; ++ host->error |= REQ_CMD_TMO; ++ } ++ } ++ if (cmd->error) ++ dev_dbg(host->dev, ++ "%s: cmd=%d arg=%08X; rsp %08X; cmd_error=%d\n", ++ __func__, cmd->opcode, cmd->arg, rsp[0], ++ cmd->error); ++ ++ msdc_cmd_next(host, mrq, cmd); ++ return true; ++} ++ ++/* It is the core layer's responsibility to ensure card status ++ * is correct before issue a request. but host design do below ++ * checks recommended. ++ */ ++static inline bool msdc_cmd_is_ready(struct msdc_host *host, ++ struct mmc_request *mrq, struct mmc_command *cmd) ++{ ++ /* The max busy time we can endure is 20ms */ ++ unsigned long tmo = jiffies + msecs_to_jiffies(20); ++ ++ while ((readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) && ++ time_before(jiffies, tmo)) ++ cpu_relax(); ++ if (readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) { ++ dev_err(host->dev, "CMD bus busy detected\n"); ++ host->error |= REQ_CMD_BUSY; ++ msdc_cmd_done(host, MSDC_INT_CMDTMO, mrq, cmd); ++ return false; ++ } ++ ++ if (mmc_resp_type(cmd) == MMC_RSP_R1B || cmd->data) { ++ tmo = jiffies + msecs_to_jiffies(20); ++ /* R1B or with data, should check SDCBUSY */ ++ while ((readl(host->base + SDC_STS) & SDC_STS_SDCBUSY) && ++ time_before(jiffies, tmo)) ++ cpu_relax(); ++ if (readl(host->base + SDC_STS) & SDC_STS_SDCBUSY) { ++ dev_err(host->dev, "Controller busy detected\n"); ++ host->error |= REQ_CMD_BUSY; ++ msdc_cmd_done(host, MSDC_INT_CMDTMO, mrq, cmd); ++ return false; ++ } ++ } ++ return true; ++} ++ ++static void msdc_start_command(struct msdc_host *host, ++ struct mmc_request *mrq, struct mmc_command *cmd) ++{ ++ u32 rawcmd; ++ ++ WARN_ON(host->cmd); ++ host->cmd = cmd; ++ ++ if (!msdc_cmd_is_ready(host, mrq, cmd)) ++ return; ++ ++ if ((readl(host->base + MSDC_FIFOCS) & MSDC_FIFOCS_TXCNT) >> 16 || ++ readl(host->base + MSDC_FIFOCS) & MSDC_FIFOCS_RXCNT) { ++ dev_err(host->dev, "TX/RX FIFO non-empty before start of IO. Reset\n"); ++ msdc_reset_hw(host); ++ } ++ ++ cmd->error = 0; ++ rawcmd = msdc_cmd_prepare_raw_cmd(host, mrq, cmd); ++ mod_delayed_work(system_wq, &host->req_timeout, DAT_TIMEOUT); ++ ++ sdr_set_bits(host->base + MSDC_INTEN, MSDC_INTEN_CMDRDY | ++ MSDC_INTEN_RSPCRCERR | MSDC_INTEN_CMDTMO | ++ MSDC_INTEN_ACMDRDY | MSDC_INTEN_ACMDCRCERR | ++ MSDC_INTEN_ACMDTMO); ++ writel(cmd->arg, host->base + SDC_ARG); ++ writel(rawcmd, host->base + SDC_CMD); ++} ++ ++static void msdc_cmd_next(struct msdc_host *host, ++ struct mmc_request *mrq, struct mmc_command *cmd) ++{ ++ if (cmd->error || (mrq->sbc && mrq->sbc->error)) ++ msdc_request_done(host, mrq); ++ else if (cmd == mrq->sbc) ++ msdc_start_command(host, mrq, mrq->cmd); ++ else if (!cmd->data) ++ msdc_request_done(host, mrq); ++ else ++ msdc_start_data(host, mrq, cmd, cmd->data); ++} ++ ++static void msdc_ops_request(struct mmc_host *mmc, struct mmc_request *mrq) ++{ ++ struct msdc_host *host = mmc_priv(mmc); ++ ++ host->error = 0; ++ WARN_ON(host->mrq); ++ host->mrq = mrq; ++ ++ if (mrq->data) ++ msdc_prepare_data(host, mrq); ++ ++ /* if SBC is required, we have HW option and SW option. ++ * if HW option is enabled, and SBC does not have "special" flags, ++ * use HW option, otherwise use SW option ++ */ ++ if (mrq->sbc && (!mmc_card_mmc(mmc->card) || ++ (mrq->sbc->arg & 0xFFFF0000))) ++ msdc_start_command(host, mrq, mrq->sbc); ++ else ++ msdc_start_command(host, mrq, mrq->cmd); ++} ++ ++static void msdc_pre_req(struct mmc_host *mmc, struct mmc_request *mrq, ++ bool is_first_req) ++{ ++ struct msdc_host *host = mmc_priv(mmc); ++ struct mmc_data *data = mrq->data; ++ ++ if (!data) ++ return; ++ ++ msdc_prepare_data(host, mrq); ++ data->host_cookie |= MSDC_ASYNC_FLAG; ++} ++ ++static void msdc_post_req(struct mmc_host *mmc, struct mmc_request *mrq, ++ int err) ++{ ++ struct msdc_host *host = mmc_priv(mmc); ++ struct mmc_data *data; ++ ++ data = mrq->data; ++ if (!data) ++ return; ++ if (data->host_cookie) { ++ data->host_cookie &= ~MSDC_ASYNC_FLAG; ++ msdc_unprepare_data(host, mrq); ++ } ++} ++ ++static void msdc_data_xfer_next(struct msdc_host *host, ++ struct mmc_request *mrq, struct mmc_data *data) ++{ ++ if (mmc_op_multi(mrq->cmd->opcode) && mrq->stop && !mrq->stop->error && ++ (!data->bytes_xfered || !mrq->sbc)) ++ msdc_start_command(host, mrq, mrq->stop); ++ else ++ msdc_request_done(host, mrq); ++} ++ ++static bool msdc_data_xfer_done(struct msdc_host *host, u32 events, ++ struct mmc_request *mrq, struct mmc_data *data) ++{ ++ struct mmc_command *stop = data->stop; ++ unsigned long flags; ++ bool done; ++ unsigned int check_data = events & ++ (MSDC_INT_XFER_COMPL | MSDC_INT_DATCRCERR | MSDC_INT_DATTMO ++ | MSDC_INT_DMA_BDCSERR | MSDC_INT_DMA_GPDCSERR ++ | MSDC_INT_DMA_PROTECT); ++ ++ spin_lock_irqsave(&host->lock, flags); ++ done = !host->data; ++ if (check_data) ++ host->data = NULL; ++ spin_unlock_irqrestore(&host->lock, flags); ++ ++ if (done) ++ return true; ++ ++ if (check_data || (stop && stop->error)) { ++ dev_dbg(host->dev, "DMA status: 0x%8X\n", ++ readl(host->base + MSDC_DMA_CFG)); ++ sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_STOP, ++ 1); ++ while (readl(host->base + MSDC_DMA_CFG) & MSDC_DMA_CFG_STS) ++ cpu_relax(); ++ sdr_clr_bits(host->base + MSDC_INTEN, data_ints_mask); ++ dev_dbg(host->dev, "DMA stop\n"); ++ ++ if ((events & MSDC_INT_XFER_COMPL) && (!stop || !stop->error)) { ++ data->bytes_xfered = data->blocks * data->blksz; ++ } else { ++ dev_err(host->dev, "interrupt events: %x\n", events); ++ msdc_reset_hw(host); ++ host->error |= REQ_DAT_ERR; ++ data->bytes_xfered = 0; ++ ++ if (events & MSDC_INT_DATTMO) ++ data->error = -ETIMEDOUT; ++ ++ dev_err(host->dev, "%s: cmd=%d; blocks=%d", ++ __func__, mrq->cmd->opcode, data->blocks); ++ dev_err(host->dev, "data_error=%d xfer_size=%d\n", ++ (int)data->error, data->bytes_xfered); ++ } ++ ++ msdc_data_xfer_next(host, mrq, data); ++ done = true; ++ } ++ return done; ++} ++ ++static void msdc_set_buswidth(struct msdc_host *host, u32 width) ++{ ++ u32 val = readl(host->base + SDC_CFG); ++ ++ val &= ~SDC_CFG_BUSWIDTH; ++ ++ switch (width) { ++ default: ++ case MMC_BUS_WIDTH_1: ++ val |= (MSDC_BUS_1BITS << 16); ++ break; ++ case MMC_BUS_WIDTH_4: ++ val |= (MSDC_BUS_4BITS << 16); ++ break; ++ case MMC_BUS_WIDTH_8: ++ val |= (MSDC_BUS_8BITS << 16); ++ break; ++ } ++ ++ writel(val, host->base + SDC_CFG); ++ dev_dbg(host->dev, "Bus Width = %d", width); ++} ++ ++static int msdc_ops_switch_volt(struct mmc_host *mmc, struct mmc_ios *ios) ++{ ++ struct msdc_host *host = mmc_priv(mmc); ++ int min_uv, max_uv; ++ int ret = 0; ++ ++ if (!IS_ERR(mmc->supply.vqmmc)) { ++ if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) { ++ min_uv = 3300000; ++ max_uv = 3300000; ++ } else if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) { ++ min_uv = 1800000; ++ max_uv = 1800000; ++ } else { ++ dev_err(host->dev, "Unsupported signal voltage!\n"); ++ return -EINVAL; ++ } ++ ++ ret = regulator_set_voltage(mmc->supply.vqmmc, min_uv, max_uv); ++ if (ret) { ++ dev_err(host->dev, ++ "Regulator set error %d: %d - %d\n", ++ ret, min_uv, max_uv); ++ } else { ++ /* Apply different pinctrl settings for different signal voltage */ ++ if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180) ++ pinctrl_select_state(host->pinctrl, host->pins_uhs); ++ else ++ pinctrl_select_state(host->pinctrl, host->pins_default); ++ } ++ } ++ return ret; ++} ++ ++static int msdc_card_busy(struct mmc_host *mmc) ++{ ++ struct msdc_host *host = mmc_priv(mmc); ++ u32 status = readl(host->base + MSDC_PS); ++ ++ /* check if any pin between dat[0:3] is low */ ++ if (((status >> 16) & 0xf) != 0xf) ++ return 1; ++ ++ return 0; ++} ++ ++static void msdc_request_timeout(struct work_struct *work) ++{ ++ struct msdc_host *host = container_of(work, struct msdc_host, ++ req_timeout.work); ++ ++ /* simulate HW timeout status */ ++ dev_err(host->dev, "%s: aborting cmd/data/mrq\n", __func__); ++ if (host->mrq) { ++ dev_err(host->dev, "%s: aborting mrq=%p cmd=%d\n", __func__, ++ host->mrq, host->mrq->cmd->opcode); ++ if (host->cmd) { ++ dev_err(host->dev, "%s: aborting cmd=%d\n", ++ __func__, host->cmd->opcode); ++ msdc_cmd_done(host, MSDC_INT_CMDTMO, host->mrq, ++ host->cmd); ++ } else if (host->data) { ++ dev_err(host->dev, "%s: abort data: cmd%d; %d blocks\n", ++ __func__, host->mrq->cmd->opcode, ++ host->data->blocks); ++ msdc_data_xfer_done(host, MSDC_INT_DATTMO, host->mrq, ++ host->data); ++ } ++ } ++} ++ ++static irqreturn_t msdc_irq(int irq, void *dev_id) ++{ ++ struct msdc_host *host = (struct msdc_host *) dev_id; ++ ++ while (true) { ++ unsigned long flags; ++ struct mmc_request *mrq; ++ struct mmc_command *cmd; ++ struct mmc_data *data; ++ u32 events, event_mask; ++ ++ spin_lock_irqsave(&host->lock, flags); ++ events = readl(host->base + MSDC_INT); ++ event_mask = readl(host->base + MSDC_INTEN); ++ /* clear interrupts */ ++ writel(events & event_mask, host->base + MSDC_INT); ++ ++ mrq = host->mrq; ++ cmd = host->cmd; ++ data = host->data; ++ spin_unlock_irqrestore(&host->lock, flags); ++ ++ if (!(events & event_mask)) ++ break; ++ ++ if (!mrq) { ++ dev_err(host->dev, ++ "%s: MRQ=NULL; events=%08X; event_mask=%08X\n", ++ __func__, events, event_mask); ++ WARN_ON(1); ++ break; ++ } ++ ++ dev_dbg(host->dev, "%s: events=%08X\n", __func__, events); ++ ++ if (cmd) ++ msdc_cmd_done(host, events, mrq, cmd); ++ else if (data) ++ msdc_data_xfer_done(host, events, mrq, data); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static void msdc_init_hw(struct msdc_host *host) ++{ ++ u32 val; ++ ++ /* Configure to MMC/SD mode, clock free running */ ++ sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_MODE | MSDC_CFG_CKPDN); ++ ++ /* Reset */ ++ msdc_reset_hw(host); ++ ++ /* Disable card detection */ ++ sdr_clr_bits(host->base + MSDC_PS, MSDC_PS_CDEN); ++ ++ /* Disable and clear all interrupts */ ++ writel(0, host->base + MSDC_INTEN); ++ val = readl(host->base + MSDC_INT); ++ writel(val, host->base + MSDC_INT); ++ ++ writel(0, host->base + MSDC_PAD_TUNE); ++ writel(0, host->base + MSDC_IOCON); ++ sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 1); ++ writel(0x403c004f, host->base + MSDC_PATCH_BIT); ++ sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL, 1); ++ writel(0xffff0089, host->base + MSDC_PATCH_BIT1); ++ /* Configure to enable SDIO mode. ++ * it's must otherwise sdio cmd5 failed ++ */ ++ sdr_set_bits(host->base + SDC_CFG, SDC_CFG_SDIO); ++ ++ /* disable detect SDIO device interrupt function */ ++ sdr_clr_bits(host->base + SDC_CFG, SDC_CFG_SDIOIDE); ++ ++ /* Configure to default data timeout */ ++ sdr_set_field(host->base + SDC_CFG, SDC_CFG_DTOC, 3); ++ ++ dev_dbg(host->dev, "init hardware done!"); ++} ++ ++static void msdc_deinit_hw(struct msdc_host *host) ++{ ++ u32 val; ++ /* Disable and clear all interrupts */ ++ writel(0, host->base + MSDC_INTEN); ++ ++ val = readl(host->base + MSDC_INT); ++ writel(val, host->base + MSDC_INT); ++} ++ ++/* init gpd and bd list in msdc_drv_probe */ ++static void msdc_init_gpd_bd(struct msdc_host *host, struct msdc_dma *dma) ++{ ++ struct mt_gpdma_desc *gpd = dma->gpd; ++ struct mt_bdma_desc *bd = dma->bd; ++ int i; ++ ++ memset(gpd, 0, sizeof(struct mt_gpdma_desc)); ++ ++ gpd->gpd_info = GPDMA_DESC_BDP; /* hwo, cs, bd pointer */ ++ gpd->ptr = (u32)dma->bd_addr; /* physical address */ ++ ++ memset(bd, 0, sizeof(struct mt_bdma_desc) * MAX_BD_NUM); ++ for (i = 0; i < (MAX_BD_NUM - 1); i++) ++ bd[i].next = (u32)dma->bd_addr + sizeof(*bd) * (i + 1); ++} ++ ++static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) ++{ ++ struct msdc_host *host = mmc_priv(mmc); ++ int ret; ++ u32 ddr = 0; ++ ++ if (ios->timing == MMC_TIMING_UHS_DDR50 || ++ ios->timing == MMC_TIMING_MMC_DDR52) ++ ddr = 1; ++ ++ msdc_set_buswidth(host, ios->bus_width); ++ ++ /* Suspend/Resume will do power off/on */ ++ switch (ios->power_mode) { ++ case MMC_POWER_UP: ++ if (!IS_ERR(mmc->supply.vmmc)) { ++ ret = mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ++ ios->vdd); ++ if (ret) { ++ dev_err(host->dev, "Failed to set vmmc power!\n"); ++ return; ++ } ++ } ++ break; ++ case MMC_POWER_ON: ++ if (!IS_ERR(mmc->supply.vqmmc) && !host->vqmmc_enabled) { ++ ret = regulator_enable(mmc->supply.vqmmc); ++ if (ret) ++ dev_err(host->dev, "Failed to set vqmmc power!\n"); ++ else ++ host->vqmmc_enabled = true; ++ } ++ break; ++ case MMC_POWER_OFF: ++ if (!IS_ERR(mmc->supply.vmmc)) ++ mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0); ++ ++ if (!IS_ERR(mmc->supply.vqmmc) && host->vqmmc_enabled) { ++ regulator_disable(mmc->supply.vqmmc); ++ host->vqmmc_enabled = false; ++ } ++ break; ++ default: ++ break; ++ } ++ ++ if (host->mclk != ios->clock || host->ddr != ddr) ++ msdc_set_mclk(host, ddr, ios->clock); ++} ++ ++static struct mmc_host_ops mt_msdc_ops = { ++ .post_req = msdc_post_req, ++ .pre_req = msdc_pre_req, ++ .request = msdc_ops_request, ++ .set_ios = msdc_ops_set_ios, ++ .start_signal_voltage_switch = msdc_ops_switch_volt, ++ .card_busy = msdc_card_busy, ++}; ++ ++static int msdc_drv_probe(struct platform_device *pdev) ++{ ++ struct mmc_host *mmc; ++ struct msdc_host *host; ++ struct resource *res; ++ int ret; ++ ++ if (!pdev->dev.of_node) { ++ dev_err(&pdev->dev, "No DT found\n"); ++ return -EINVAL; ++ } ++ /* Allocate MMC host for this device */ ++ mmc = mmc_alloc_host(sizeof(struct msdc_host), &pdev->dev); ++ if (!mmc) ++ return -ENOMEM; ++ ++ host = mmc_priv(mmc); ++ ret = mmc_of_parse(mmc); ++ if (ret) ++ goto host_free; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ host->base = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(host->base)) { ++ ret = PTR_ERR(host->base); ++ goto host_free; ++ } ++ ++ ret = mmc_regulator_get_supply(mmc); ++ if (ret == -EPROBE_DEFER) ++ goto host_free; ++ ++ host->src_clk = devm_clk_get(&pdev->dev, "source"); ++ if (IS_ERR(host->src_clk)) { ++ ret = PTR_ERR(host->src_clk); ++ goto host_free; ++ } ++ ++ host->h_clk = devm_clk_get(&pdev->dev, "hclk"); ++ if (IS_ERR(host->h_clk)) { ++ ret = PTR_ERR(host->h_clk); ++ goto host_free; ++ } ++ ++ host->irq = platform_get_irq(pdev, 0); ++ if (host->irq < 0) { ++ ret = -EINVAL; ++ goto host_free; ++ } ++ ++ host->pinctrl = devm_pinctrl_get(&pdev->dev); ++ if (IS_ERR(host->pinctrl)) { ++ ret = PTR_ERR(host->pinctrl); ++ dev_err(&pdev->dev, "Cannot find pinctrl!\n"); ++ goto host_free; ++ } ++ ++ host->pins_default = pinctrl_lookup_state(host->pinctrl, "default"); ++ if (IS_ERR(host->pins_default)) { ++ ret = PTR_ERR(host->pins_default); ++ dev_err(&pdev->dev, "Cannot find pinctrl default!\n"); ++ goto host_free; ++ } ++ ++ host->pins_uhs = pinctrl_lookup_state(host->pinctrl, "state_uhs"); ++ if (IS_ERR(host->pins_uhs)) { ++ ret = PTR_ERR(host->pins_uhs); ++ dev_err(&pdev->dev, "Cannot find pinctrl uhs!\n"); ++ goto host_free; ++ } ++ ++ host->dev = &pdev->dev; ++ host->mmc = mmc; ++ host->src_clk_freq = clk_get_rate(host->src_clk); ++ /* Set host parameters to mmc */ ++ mmc->ops = &mt_msdc_ops; ++ mmc->f_min = host->src_clk_freq / (4 * 255); ++ ++ mmc->caps |= MMC_CAP_ERASE | MMC_CAP_CMD23; ++ /* MMC core transfer sizes tunable parameters */ ++ mmc->max_segs = MAX_BD_NUM; ++ mmc->max_seg_size = BDMA_DESC_BUFLEN; ++ mmc->max_blk_size = 2048; ++ mmc->max_req_size = 512 * 1024; ++ mmc->max_blk_count = mmc->max_req_size / 512; ++ host->dma_mask = DMA_BIT_MASK(32); ++ mmc_dev(mmc)->dma_mask = &host->dma_mask; ++ ++ host->timeout_clks = 3 * 1048576; ++ host->dma.gpd = dma_alloc_coherent(&pdev->dev, ++ sizeof(struct mt_gpdma_desc), ++ &host->dma.gpd_addr, GFP_KERNEL); ++ host->dma.bd = dma_alloc_coherent(&pdev->dev, ++ MAX_BD_NUM * sizeof(struct mt_bdma_desc), ++ &host->dma.bd_addr, GFP_KERNEL); ++ if (!host->dma.gpd || !host->dma.bd) { ++ ret = -ENOMEM; ++ goto release_mem; ++ } ++ msdc_init_gpd_bd(host, &host->dma); ++ INIT_DELAYED_WORK(&host->req_timeout, msdc_request_timeout); ++ spin_lock_init(&host->lock); ++ ++ platform_set_drvdata(pdev, mmc); ++ msdc_ungate_clock(host); ++ msdc_init_hw(host); ++ ++ ret = devm_request_irq(&pdev->dev, host->irq, msdc_irq, ++ IRQF_TRIGGER_LOW | IRQF_ONESHOT, pdev->name, host); ++ if (ret) ++ goto release; ++ ++ ret = mmc_add_host(mmc); ++ if (ret) ++ goto release; ++ ++ return 0; ++ ++release: ++ platform_set_drvdata(pdev, NULL); ++ msdc_deinit_hw(host); ++ msdc_gate_clock(host); ++release_mem: ++ if (host->dma.gpd) ++ dma_free_coherent(&pdev->dev, ++ sizeof(struct mt_gpdma_desc), ++ host->dma.gpd, host->dma.gpd_addr); ++ if (host->dma.bd) ++ dma_free_coherent(&pdev->dev, ++ MAX_BD_NUM * sizeof(struct mt_bdma_desc), ++ host->dma.bd, host->dma.bd_addr); ++host_free: ++ mmc_free_host(mmc); ++ ++ return ret; ++} ++ ++static int msdc_drv_remove(struct platform_device *pdev) ++{ ++ struct mmc_host *mmc; ++ struct msdc_host *host; ++ ++ mmc = platform_get_drvdata(pdev); ++ host = mmc_priv(mmc); ++ ++ platform_set_drvdata(pdev, NULL); ++ mmc_remove_host(host->mmc); ++ msdc_deinit_hw(host); ++ msdc_gate_clock(host); ++ ++ dma_free_coherent(&pdev->dev, ++ sizeof(struct mt_gpdma_desc), ++ host->dma.gpd, host->dma.gpd_addr); ++ dma_free_coherent(&pdev->dev, MAX_BD_NUM * sizeof(struct mt_bdma_desc), ++ host->dma.bd, host->dma.bd_addr); ++ ++ mmc_free_host(host->mmc); ++ ++ return 0; ++} ++ ++static const struct of_device_id msdc_of_ids[] = { ++ { .compatible = "mediatek,mt8135-mmc", }, ++ {} ++}; ++ ++static struct platform_driver mt_msdc_driver = { ++ .probe = msdc_drv_probe, ++ .remove = msdc_drv_remove, ++ .driver = { ++ .name = "mtk-msdc", ++ .of_match_table = msdc_of_ids, ++ }, ++}; ++ ++module_platform_driver(mt_msdc_driver); ++MODULE_LICENSE("GPL v2"); ++MODULE_DESCRIPTION("MediaTek SD/MMC Card Driver"); diff --git a/target/linux/mediatek/patches/0036-mmc-mediatek-Add-PM-support-for-MMC-driver.patch b/target/linux/mediatek/patches/0036-mmc-mediatek-Add-PM-support-for-MMC-driver.patch new file mode 100644 index 0000000000..e9ba31d76f --- /dev/null +++ b/target/linux/mediatek/patches/0036-mmc-mediatek-Add-PM-support-for-MMC-driver.patch @@ -0,0 +1,209 @@ +From 4ca0e8a959569852b520b607d39ce6ceeeb0f518 Mon Sep 17 00:00:00 2001 +From: Chaotian Jing <chaotian.jing@mediatek.com> +Date: Mon, 15 Jun 2015 19:20:49 +0800 +Subject: [PATCH 36/76] mmc: mediatek: Add PM support for MMC driver + +Add PM support for Mediatek MMC driver +Save/restore registers when PM + +Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com> +--- + drivers/mmc/host/mtk-sd.c | 89 +++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 86 insertions(+), 3 deletions(-) + +diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c +index 952be2e..7c20f28 100644 +--- a/drivers/mmc/host/mtk-sd.c ++++ b/drivers/mmc/host/mtk-sd.c +@@ -22,6 +22,8 @@ + #include <linux/of_gpio.h> + #include <linux/pinctrl/consumer.h> + #include <linux/platform_device.h> ++#include <linux/pm.h> ++#include <linux/pm_runtime.h> + #include <linux/regulator/consumer.h> + #include <linux/spinlock.h> + +@@ -212,6 +214,7 @@ + #define MSDC_ASYNC_FLAG (0x1 << 1) + #define MSDC_MMAP_FLAG (0x1 << 2) + ++#define MTK_MMC_AUTOSUSPEND_DELAY 50 + #define CMD_TIMEOUT (HZ/10 * 5) /* 100ms x5 */ + #define DAT_TIMEOUT (HZ * 5) /* 1000ms x5 */ + +@@ -254,6 +257,15 @@ struct msdc_dma { + dma_addr_t bd_addr; /* the physical address of bd array */ + }; + ++struct msdc_save_para { ++ u32 msdc_cfg; ++ u32 iocon; ++ u32 sdc_cfg; ++ u32 pad_tune; ++ u32 patch_bit0; ++ u32 patch_bit1; ++}; ++ + struct msdc_host { + struct device *dev; + struct mmc_host *mmc; /* mmc structure */ +@@ -286,6 +298,7 @@ struct msdc_host { + u32 sclk; /* SD/MS bus clock frequency */ + bool ddr; + bool vqmmc_enabled; ++ struct msdc_save_para save_para; /* used when gate HCLK */ + }; + + static void sdr_set_bits(void __iomem *reg, u32 bs) +@@ -677,6 +690,9 @@ static void msdc_request_done(struct msdc_host *host, struct mmc_request *mrq) + if (mrq->data) + msdc_unprepare_data(host, mrq); + mmc_request_done(host->mmc, mrq); ++ ++ pm_runtime_mark_last_busy(host->dev); ++ pm_runtime_put_autosuspend(host->dev); + } + + /* returns true if command is fully handled; returns false otherwise */ +@@ -831,6 +847,8 @@ static void msdc_ops_request(struct mmc_host *mmc, struct mmc_request *mrq) + WARN_ON(host->mrq); + host->mrq = mrq; + ++ pm_runtime_get_sync(host->dev); ++ + if (mrq->data) + msdc_prepare_data(host, mrq); + +@@ -1145,6 +1163,8 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) + int ret; + u32 ddr = 0; + ++ pm_runtime_get_sync(host->dev); ++ + if (ios->timing == MMC_TIMING_UHS_DDR50 || + ios->timing == MMC_TIMING_MMC_DDR52) + ddr = 1; +@@ -1159,7 +1179,7 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) + ios->vdd); + if (ret) { + dev_err(host->dev, "Failed to set vmmc power!\n"); +- return; ++ goto end; + } + } + break; +@@ -1187,6 +1207,10 @@ static void msdc_ops_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) + + if (host->mclk != ios->clock || host->ddr != ddr) + msdc_set_mclk(host, ddr, ios->clock); ++ ++end: ++ pm_runtime_mark_last_busy(host->dev); ++ pm_runtime_put_autosuspend(host->dev); + } + + static struct mmc_host_ops mt_msdc_ops = { +@@ -1310,12 +1334,18 @@ static int msdc_drv_probe(struct platform_device *pdev) + if (ret) + goto release; + ++ pm_runtime_set_active(host->dev); ++ pm_runtime_set_autosuspend_delay(host->dev, MTK_MMC_AUTOSUSPEND_DELAY); ++ pm_runtime_use_autosuspend(host->dev); ++ pm_runtime_enable(host->dev); + ret = mmc_add_host(mmc); ++ + if (ret) +- goto release; ++ goto end; + + return 0; +- ++end: ++ pm_runtime_disable(host->dev); + release: + platform_set_drvdata(pdev, NULL); + msdc_deinit_hw(host); +@@ -1343,11 +1373,15 @@ static int msdc_drv_remove(struct platform_device *pdev) + mmc = platform_get_drvdata(pdev); + host = mmc_priv(mmc); + ++ pm_runtime_get_sync(host->dev); ++ + platform_set_drvdata(pdev, NULL); + mmc_remove_host(host->mmc); + msdc_deinit_hw(host); + msdc_gate_clock(host); + ++ pm_runtime_disable(host->dev); ++ pm_runtime_put_noidle(host->dev); + dma_free_coherent(&pdev->dev, + sizeof(struct mt_gpdma_desc), + host->dma.gpd, host->dma.gpd_addr); +@@ -1359,6 +1393,54 @@ static int msdc_drv_remove(struct platform_device *pdev) + return 0; + } + ++#ifdef CONFIG_PM ++static void msdc_save_reg(struct msdc_host *host) ++{ ++ host->save_para.msdc_cfg = readl(host->base + MSDC_CFG); ++ host->save_para.iocon = readl(host->base + MSDC_IOCON); ++ host->save_para.sdc_cfg = readl(host->base + SDC_CFG); ++ host->save_para.pad_tune = readl(host->base + MSDC_PAD_TUNE); ++ host->save_para.patch_bit0 = readl(host->base + MSDC_PATCH_BIT); ++ host->save_para.patch_bit1 = readl(host->base + MSDC_PATCH_BIT1); ++} ++ ++static void msdc_restore_reg(struct msdc_host *host) ++{ ++ writel(host->save_para.msdc_cfg, host->base + MSDC_CFG); ++ writel(host->save_para.iocon, host->base + MSDC_IOCON); ++ writel(host->save_para.sdc_cfg, host->base + SDC_CFG); ++ writel(host->save_para.pad_tune, host->base + MSDC_PAD_TUNE); ++ writel(host->save_para.patch_bit0, host->base + MSDC_PATCH_BIT); ++ writel(host->save_para.patch_bit1, host->base + MSDC_PATCH_BIT1); ++} ++ ++static int msdc_runtime_suspend(struct device *dev) ++{ ++ struct mmc_host *mmc = dev_get_drvdata(dev); ++ struct msdc_host *host = mmc_priv(mmc); ++ ++ msdc_save_reg(host); ++ msdc_gate_clock(host); ++ return 0; ++} ++ ++static int msdc_runtime_resume(struct device *dev) ++{ ++ struct mmc_host *mmc = dev_get_drvdata(dev); ++ struct msdc_host *host = mmc_priv(mmc); ++ ++ msdc_ungate_clock(host); ++ msdc_restore_reg(host); ++ return 0; ++} ++#endif ++ ++static const struct dev_pm_ops msdc_dev_pm_ops = { ++ SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, ++ pm_runtime_force_resume) ++ SET_RUNTIME_PM_OPS(msdc_runtime_suspend, msdc_runtime_resume, NULL) ++}; ++ + static const struct of_device_id msdc_of_ids[] = { + { .compatible = "mediatek,mt8135-mmc", }, + {} +@@ -1370,6 +1452,7 @@ static struct platform_driver mt_msdc_driver = { + .driver = { + .name = "mtk-msdc", + .of_match_table = msdc_of_ids, ++ .pm = &msdc_dev_pm_ops, + }, + }; + +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0037-arm64-mediatek-Add-Mediatek-MMC-support-in-defconfig.patch b/target/linux/mediatek/patches/0037-arm64-mediatek-Add-Mediatek-MMC-support-in-defconfig.patch new file mode 100644 index 0000000000..7d9143f2f6 --- /dev/null +++ b/target/linux/mediatek/patches/0037-arm64-mediatek-Add-Mediatek-MMC-support-in-defconfig.patch @@ -0,0 +1,28 @@ +From 0435517df474d830711b7e1dc56e2d47ae5083b5 Mon Sep 17 00:00:00 2001 +From: Eddie Huang <eddie.huang@mediatek.com> +Date: Mon, 15 Jun 2015 19:20:52 +0800 +Subject: [PATCH 37/76] arm64: mediatek: Add Mediatek MMC support in defconfig + +Add CONFIG_MMC_MTK=y in defconfig + +Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com> +Signed-off-by: Eddie Huang <eddie.huang@mediatek.com> +--- + arch/arm64/configs/defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig +index 2ed7449..e03288a 100644 +--- a/arch/arm64/configs/defconfig ++++ b/arch/arm64/configs/defconfig +@@ -138,6 +138,7 @@ CONFIG_MMC_ARMMMCI=y + CONFIG_MMC_SDHCI=y + CONFIG_MMC_SDHCI_PLTFM=y + CONFIG_MMC_SPI=y ++CONFIG_MMC_MTK=y + CONFIG_RTC_CLASS=y + CONFIG_RTC_DRV_EFI=y + CONFIG_RTC_DRV_XGENE=y +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0038-ARM-multi_v7_defconfig-Enable-Mediatek-MMC-support-m.patch b/target/linux/mediatek/patches/0038-ARM-multi_v7_defconfig-Enable-Mediatek-MMC-support-m.patch new file mode 100644 index 0000000000..35dc99faf9 --- /dev/null +++ b/target/linux/mediatek/patches/0038-ARM-multi_v7_defconfig-Enable-Mediatek-MMC-support-m.patch @@ -0,0 +1,29 @@ +From 3069c2bfe0da7c6c13a61b0e1d457fd0e021e27b Mon Sep 17 00:00:00 2001 +From: Yingjoe Chen <yingjoe.chen@mediatek.com> +Date: Mon, 15 Jun 2015 19:20:53 +0800 +Subject: [PATCH 38/76] ARM: multi_v7_defconfig: Enable Mediatek MMC support + multi-v7 + +Add CONFIG_MMC_MTK=y in defconfig + +Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com> +Signed-off-by: Chaotian Jing <chaotian.jing@mediatek.com> +--- + arch/arm/configs/multi_v7_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig +index fbbb191..bfa09ab 100644 +--- a/arch/arm/configs/multi_v7_defconfig ++++ b/arch/arm/configs/multi_v7_defconfig +@@ -477,6 +477,7 @@ CONFIG_MMC_DW_EXYNOS=y + CONFIG_MMC_DW_ROCKCHIP=y + CONFIG_MMC_SH_MMCIF=y + CONFIG_MMC_SUNXI=y ++CONFIG_MMC_MTK=y + CONFIG_NEW_LEDS=y + CONFIG_LEDS_CLASS=y + CONFIG_LEDS_GPIO=y +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0039-clocksource-mediatek-Don-t-run-event_handler-if-it-i.patch b/target/linux/mediatek/patches/0039-clocksource-mediatek-Don-t-run-event_handler-if-it-i.patch new file mode 100644 index 0000000000..aabe8497f3 --- /dev/null +++ b/target/linux/mediatek/patches/0039-clocksource-mediatek-Don-t-run-event_handler-if-it-i.patch @@ -0,0 +1,32 @@ +From 9d4cba66a74cbdf25f43a7a8cc360370214ba5fc Mon Sep 17 00:00:00 2001 +From: "Joe.C" <yingjoe.chen@mediatek.com> +Date: Fri, 1 May 2015 15:43:24 +0800 +Subject: [PATCH 39/76] clocksource: mediatek: Don't run event_handler if it + is NULL + +Spurious timer interrupt is noticed in mtk timer and cause kernel +crash. In mtk_timer_interrupt(), only run event_handler if it is +not NULL. + +Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com> +--- + drivers/clocksource/mtk_timer.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/clocksource/mtk_timer.c b/drivers/clocksource/mtk_timer.c +index 68ab423..85e0ab5 100644 +--- a/drivers/clocksource/mtk_timer.c ++++ b/drivers/clocksource/mtk_timer.c +@@ -143,7 +143,8 @@ static irqreturn_t mtk_timer_interrupt(int irq, void *dev_id) + + /* Acknowledge timer0 irq */ + writel(GPT_IRQ_ACK(GPT_CLK_EVT), evt->gpt_base + GPT_IRQ_ACK_REG); +- evt->dev.event_handler(&evt->dev); ++ if (evt->dev.event_handler) ++ evt->dev.event_handler(&evt->dev); + + return IRQ_HANDLED; + } +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0040-clocksource-mediatek-Use-GPT-as-sched-clock-source.patch b/target/linux/mediatek/patches/0040-clocksource-mediatek-Use-GPT-as-sched-clock-source.patch new file mode 100644 index 0000000000..c6b66afc05 --- /dev/null +++ b/target/linux/mediatek/patches/0040-clocksource-mediatek-Use-GPT-as-sched-clock-source.patch @@ -0,0 +1,51 @@ +From 3b3c2406dd9797bc806e0ce756142a33d209c4e8 Mon Sep 17 00:00:00 2001 +From: "Joe.C" <yingjoe.chen@mediatek.com> +Date: Fri, 1 May 2015 15:43:25 +0800 +Subject: [PATCH 40/76] clocksource: mediatek: Use GPT as sched clock source + +When cpu is in deep idle, arch timer will stop counting. Setup GPT as +sched clock source so it can keep counting in idle. + +Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com> +--- + drivers/clocksource/mtk_timer.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/drivers/clocksource/mtk_timer.c b/drivers/clocksource/mtk_timer.c +index 85e0ab5..9a90c7b 100644 +--- a/drivers/clocksource/mtk_timer.c ++++ b/drivers/clocksource/mtk_timer.c +@@ -24,6 +24,7 @@ + #include <linux/of.h> + #include <linux/of_address.h> + #include <linux/of_irq.h> ++#include <linux/sched_clock.h> + #include <linux/slab.h> + + #define GPT_IRQ_EN_REG 0x00 +@@ -59,6 +60,13 @@ struct mtk_clock_event_device { + struct clock_event_device dev; + }; + ++static void __iomem *gpt_base __read_mostly; ++ ++static u64 notrace mtk_read_sched_clock(void) ++{ ++ return readl_relaxed(gpt_base + TIMER_CNT_REG(GPT_CLK_SRC)); ++} ++ + static inline struct mtk_clock_event_device *to_mtk_clk( + struct clock_event_device *c) + { +@@ -239,6 +247,8 @@ static void __init mtk_timer_init(struct device_node *node) + mtk_timer_setup(evt, GPT_CLK_SRC, TIMER_CTRL_OP_FREERUN); + clocksource_mmio_init(evt->gpt_base + TIMER_CNT_REG(GPT_CLK_SRC), + node->name, rate, 300, 32, clocksource_mmio_readl_up); ++ gpt_base = evt->gpt_base; ++ sched_clock_register(mtk_read_sched_clock, 32, rate); + + /* Configure clock event */ + mtk_timer_setup(evt, GPT_CLK_EVT, TIMER_CTRL_OP_REPEAT); +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0041-arm-mediatek-enable-gpt6-on-boot-up-to-make-arch-tim.patch b/target/linux/mediatek/patches/0041-arm-mediatek-enable-gpt6-on-boot-up-to-make-arch-tim.patch new file mode 100644 index 0000000000..728792c2a8 --- /dev/null +++ b/target/linux/mediatek/patches/0041-arm-mediatek-enable-gpt6-on-boot-up-to-make-arch-tim.patch @@ -0,0 +1,63 @@ +From eec99287ace37015ed313b4fc27ba205a158b66c Mon Sep 17 00:00:00 2001 +From: Matthias Brugger <matthias.bgg@gmail.com> +Date: Fri, 1 May 2015 15:43:26 +0800 +Subject: [PATCH 41/76] arm: mediatek: enable gpt6 on boot up to make arch + timer working + +We enable GTP6 which ungates the arch timer clock. +In the future this should be done in the bootloader. + +Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com> +Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com> +--- + arch/arm/mach-mediatek/mediatek.c | 29 +++++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) + +diff --git a/arch/arm/mach-mediatek/mediatek.c b/arch/arm/mach-mediatek/mediatek.c +index a954900..6b38d67 100644 +--- a/arch/arm/mach-mediatek/mediatek.c ++++ b/arch/arm/mach-mediatek/mediatek.c +@@ -16,6 +16,34 @@ + */ + #include <linux/init.h> + #include <asm/mach/arch.h> ++#include <linux/of.h> ++#include <linux/clk-provider.h> ++#include <linux/clocksource.h> ++ ++ ++#define GPT6_CON_MT65xx 0x10008060 ++#define GPT_ENABLE 0x31 ++ ++static void __init mediatek_timer_init(void) ++{ ++ void __iomem *gpt_base = 0; ++ ++ if (of_machine_is_compatible("mediatek,mt6589") || ++ of_machine_is_compatible("mediatek,mt8135") || ++ of_machine_is_compatible("mediatek,mt8127")) { ++ /* turn on GPT6 which ungates arch timer clocks */ ++ gpt_base = ioremap(GPT6_CON_MT65xx, 0x04); ++ } ++ ++ /* enabel clock and set to free-run */ ++ if (gpt_base) { ++ writel(GPT_ENABLE, gpt_base); ++ iounmap(gpt_base); ++ } ++ ++ of_clk_init(NULL); ++ clocksource_of_init(); ++}; + + static const char * const mediatek_board_dt_compat[] = { + "mediatek,mt6589", +@@ -27,4 +55,5 @@ static const char * const mediatek_board_dt_compat[] = { + + DT_MACHINE_START(MEDIATEK_DT, "Mediatek Cortex-A7 (Device Tree)") + .dt_compat = mediatek_board_dt_compat, ++ .init_time = mediatek_timer_init, + MACHINE_END +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0042-ARM-mediatek-add-smp-bringup-code.patch b/target/linux/mediatek/patches/0042-ARM-mediatek-add-smp-bringup-code.patch new file mode 100644 index 0000000000..8910532e18 --- /dev/null +++ b/target/linux/mediatek/patches/0042-ARM-mediatek-add-smp-bringup-code.patch @@ -0,0 +1,178 @@ +From daa2c1f9202f08628d4f91a1cf4dafb44c9bcafe Mon Sep 17 00:00:00 2001 +From: "Joe.C" <yingjoe.chen@mediatek.com> +Date: Fri, 1 May 2015 15:43:28 +0800 +Subject: [PATCH 42/76] ARM: mediatek: add smp bringup code + +Add support for booting secondary CPUs on mt6589, mt8127 +and mt8135. + +Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com> +--- + arch/arm/mach-mediatek/Makefile | 3 + + arch/arm/mach-mediatek/platsmp.c | 145 ++++++++++++++++++++++++++++++++++++++ + 2 files changed, 148 insertions(+) + create mode 100644 arch/arm/mach-mediatek/platsmp.c + +diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile +index 43e619f..2116460 100644 +--- a/arch/arm/mach-mediatek/Makefile ++++ b/arch/arm/mach-mediatek/Makefile +@@ -1 +1,4 @@ ++ifeq ($(CONFIG_SMP),y) ++obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o ++endif + obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o +diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c +new file mode 100644 +index 0000000..e266b3d +--- /dev/null ++++ b/arch/arm/mach-mediatek/platsmp.c +@@ -0,0 +1,145 @@ ++/* ++ * arch/arm/mach-mediatek/platsmp.c ++ * ++ * Copyright (c) 2014 Mediatek Inc. ++ * Author: Shunli Wang <shunli.wang@mediatek.com> ++ * Yingjoe Chen <yingjoe.chen@mediatek.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++#include <linux/io.h> ++#include <linux/memblock.h> ++#include <linux/of.h> ++#include <linux/of_address.h> ++#include <linux/string.h> ++#include <linux/threads.h> ++ ++#define MTK_MAX_CPU 8 ++#define MTK_SMP_REG_SIZE 0x1000 ++ ++struct mtk_smp_boot_info { ++ unsigned long smp_base; ++ unsigned int jump_reg; ++ unsigned int boot_reg; ++ unsigned int core_keys[MTK_MAX_CPU - 1]; ++ unsigned int core_regs[MTK_MAX_CPU - 1]; ++}; ++ ++static const struct mtk_smp_boot_info mtk_mt8135_tz_boot = { ++ 0x80002000, 1020, 1012, ++ { 0x534c4131, 0x4c415332, 0x41534c33 }, ++ { 1016, 1016, 1016}, ++}; ++ ++static const struct mtk_smp_boot_info mtk_mt6589_boot = { ++ 0x10002000, 0x34, 0x30, ++ { 0x534c4131, 0x4c415332, 0x41534c33 }, ++ { 0x38, 0x3c, 0x40 }, ++}; ++ ++static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = { ++ { .compatible = "mediatek,mt8135", .data = &mtk_mt8135_tz_boot }, ++ { .compatible = "mediatek,mt8127", .data = &mtk_mt8135_tz_boot }, ++}; ++ ++static const struct of_device_id mtk_smp_boot_infos[] __initconst = { ++ { .compatible = "mediatek,mt6589", .data = &mtk_mt6589_boot }, ++}; ++ ++static void __iomem *mtk_smp_base; ++static const struct mtk_smp_boot_info *mtk_smp_info; ++ ++static int mtk_boot_secondary(unsigned int cpu, struct task_struct *idle) ++{ ++ if (!mtk_smp_base) ++ return -EINVAL; ++ ++ if (!mtk_smp_info->core_keys[cpu-1]) ++ return -EINVAL; ++ ++ writel_relaxed(mtk_smp_info->core_keys[cpu-1], ++ mtk_smp_base + mtk_smp_info->core_regs[cpu-1]); ++ ++ arch_send_wakeup_ipi_mask(cpumask_of(cpu)); ++ ++ return 0; ++} ++ ++static void __init __mtk_smp_prepare_cpus(unsigned int max_cpus, int trustzone) ++{ ++ int i, num; ++ const struct of_device_id *infos; ++ ++ if (trustzone) { ++ num = ARRAY_SIZE(mtk_tz_smp_boot_infos); ++ infos = mtk_tz_smp_boot_infos; ++ } else { ++ num = ARRAY_SIZE(mtk_smp_boot_infos); ++ infos = mtk_smp_boot_infos; ++ } ++ ++ /* Find smp boot info for this SoC */ ++ for (i = 0; i < num; i++) { ++ if (of_machine_is_compatible(infos[i].compatible)) { ++ mtk_smp_info = infos[i].data; ++ break; ++ } ++ } ++ ++ if (!mtk_smp_info) { ++ pr_err("%s: Device is not supported\n", __func__); ++ return; ++ } ++ ++ if (trustzone) { ++ if (memblock_reserve(mtk_smp_info->smp_base, MTK_SMP_REG_SIZE)) { ++ pr_err("%s: Can't reserve smp memory\n", __func__); ++ return; ++ } ++ mtk_smp_base = phys_to_virt(mtk_smp_info->smp_base); ++ } else { ++ mtk_smp_base = ioremap(mtk_smp_info->smp_base, MTK_SMP_REG_SIZE); ++ if (!mtk_smp_base) { ++ pr_err("%s: Can't remap %lx\n", __func__, ++ mtk_smp_info->smp_base); ++ return; ++ } ++ } ++ ++ /* ++ * write the address of slave startup address into the system-wide ++ * jump register ++ */ ++ writel_relaxed(virt_to_phys(secondary_startup), ++ mtk_smp_base + mtk_smp_info->jump_reg); ++} ++ ++static void __init mtk_tz_smp_prepare_cpus(unsigned int max_cpus) ++{ ++ __mtk_smp_prepare_cpus(max_cpus, 1); ++} ++ ++static void __init mtk_smp_prepare_cpus(unsigned int max_cpus) ++{ ++ __mtk_smp_prepare_cpus(max_cpus, 0); ++} ++ ++static struct smp_operations mt81xx_tz_smp_ops __initdata = { ++ .smp_prepare_cpus = mtk_tz_smp_prepare_cpus, ++ .smp_boot_secondary = mtk_boot_secondary, ++}; ++CPU_METHOD_OF_DECLARE(mt81xx_tz_smp, "mediatek,mt81xx-tz-smp", &mt81xx_tz_smp_ops); ++ ++static struct smp_operations mt65xx_smp_ops __initdata = { ++ .smp_prepare_cpus = mtk_smp_prepare_cpus, ++ .smp_boot_secondary = mtk_boot_secondary, ++}; ++CPU_METHOD_OF_DECLARE(mt65xx_smp, "mediatek,mt65xx-smp", &mt65xx_smp_ops); +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0043-ARM-dts-mt8127-enable-basic-SMP-bringup-for-mt8127.patch b/target/linux/mediatek/patches/0043-ARM-dts-mt8127-enable-basic-SMP-bringup-for-mt8127.patch new file mode 100644 index 0000000000..60990c3282 --- /dev/null +++ b/target/linux/mediatek/patches/0043-ARM-dts-mt8127-enable-basic-SMP-bringup-for-mt8127.patch @@ -0,0 +1,53 @@ +From e75f8b666c976aff2aa30b967f74df021d800993 Mon Sep 17 00:00:00 2001 +From: "Joe.C" <yingjoe.chen@mediatek.com> +Date: Fri, 1 May 2015 15:43:30 +0800 +Subject: [PATCH 43/76] ARM: dts: mt8127: enable basic SMP bringup for mt8127 + +Add arch timer node to enable arch-timer support. MT8127 firmware +doesn't correctly setup arch-timer frequency and CNTVOFF, add +properties to workaround this. + +This also set cpu enable-method to enable SMP. + +Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com> +--- + arch/arm/boot/dts/mt8127.dtsi | 16 ++++++++++++++++ + 1 file changed, 16 insertions(+) + +diff --git a/arch/arm/boot/dts/mt8127.dtsi b/arch/arm/boot/dts/mt8127.dtsi +index aaa7862..7c2090d 100644 +--- a/arch/arm/boot/dts/mt8127.dtsi ++++ b/arch/arm/boot/dts/mt8127.dtsi +@@ -23,6 +23,7 @@ + cpus { + #address-cells = <1>; + #size-cells = <0>; ++ enable-method = "mediatek,mt81xx-tz-smp"; + + cpu@0 { + device_type = "cpu"; +@@ -72,6 +73,21 @@ + }; + }; + ++ timer { ++ compatible = "arm,armv7-timer"; ++ interrupt-parent = <&gic>; ++ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | ++ IRQ_TYPE_LEVEL_LOW)>, ++ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | ++ IRQ_TYPE_LEVEL_LOW)>, ++ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | ++ IRQ_TYPE_LEVEL_LOW)>, ++ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | ++ IRQ_TYPE_LEVEL_LOW)>; ++ clock-frequency = <13000000>; ++ arm,cpu-registers-not-fw-configured; ++ }; ++ + soc { + #address-cells = <2>; + #size-cells = <2>; +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0044-dt-bindings-Add-usb3.0-phy-binding-for-MT65xx-SoCs.patch b/target/linux/mediatek/patches/0044-dt-bindings-Add-usb3.0-phy-binding-for-MT65xx-SoCs.patch new file mode 100644 index 0000000000..1783e089ae --- /dev/null +++ b/target/linux/mediatek/patches/0044-dt-bindings-Add-usb3.0-phy-binding-for-MT65xx-SoCs.patch @@ -0,0 +1,60 @@ +From 8d61eb953496aba51b94dac07c31c7e069c784bd Mon Sep 17 00:00:00 2001 +From: Chunfeng Yun <chunfeng.yun@mediatek.com> +Date: Wed, 27 May 2015 19:47:58 +0800 +Subject: [PATCH 44/76] dt-bindings: Add usb3.0 phy binding for MT65xx SoCs + +add a DT binding documentation of usb3.0 phy for MT65xx +SoCs from Mediatek. + +Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> +--- + .../devicetree/bindings/usb/mt65xx-u3phy.txt | 37 ++++++++++++++++++++ + 1 file changed, 37 insertions(+) + create mode 100644 Documentation/devicetree/bindings/usb/mt65xx-u3phy.txt + +diff --git a/Documentation/devicetree/bindings/usb/mt65xx-u3phy.txt b/Documentation/devicetree/bindings/usb/mt65xx-u3phy.txt +new file mode 100644 +index 0000000..b0b91b0 +--- /dev/null ++++ b/Documentation/devicetree/bindings/usb/mt65xx-u3phy.txt +@@ -0,0 +1,37 @@ ++MT65xx U3PHY ++ ++The device node for Mediatek SOC usb3.0 phy ++ ++Required properties: ++ - compatible : Should be "mediatek,mt8173-u3phy" ++ - reg : Offset and length of registers, the first is for mac domain, ++ another for phy domain ++ - power-domains: to enable usb's mtcmos ++ - reg-vusb33-supply: regulator of usb avdd3.3v ++ - clocks : must support all clocks that phy need ++ - clock-names: should be "wakeup_deb_p0", "wakeup_deb_p1" for wakeup ++ debounce control clocks, "sys_mac" for sys and mac clocks and ++ "u3phya_ref" for u3phya reference clock. ++ ++Optional properties: ++ - disable-usb2-p1 : disable port1 of usb2.0 which has two ports. ++ - reg-p1-vbus-supply : regulator of port1's vbus; ++ ++Example: ++ ++u3phy: usb-phy@11271000 { ++ compatible = "mediatek,mt8173-u3phy"; ++ reg = <0 0x11271000 0 0x3000>, ++ <0 0x11280000 0 0x20000>; ++ power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>; ++ reg-vusb33-supply = <&mt6397_usb_reg>; ++ clocks = <&perisys PERI_USB0>, ++ <&perisys PERI_USB1>, ++ <&topckgen CLK_TOP_USB30_SEL>, ++ <&apmixedsys CLK_APMIXED_REF2USB_TX>; ++ clock-names = "wakeup_deb_p0", ++ "wakeup_deb_p1", ++ "sys_mac", ++ "u3phya_ref"; ++ disable-usb2-p1; ++}; +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0045-dt-bindings-Add-a-binding-for-Mediatek-xHCI-host-con.patch b/target/linux/mediatek/patches/0045-dt-bindings-Add-a-binding-for-Mediatek-xHCI-host-con.patch new file mode 100644 index 0000000000..6c1d7b3759 --- /dev/null +++ b/target/linux/mediatek/patches/0045-dt-bindings-Add-a-binding-for-Mediatek-xHCI-host-con.patch @@ -0,0 +1,43 @@ +From 8629bcb28208ef5b9f5eeb6d4b669651c9521b30 Mon Sep 17 00:00:00 2001 +From: Chunfeng Yun <chunfeng.yun@mediatek.com> +Date: Wed, 27 May 2015 19:47:59 +0800 +Subject: [PATCH 45/76] dt-bindings: Add a binding for Mediatek xHCI host + controller + +add a DT binding documentation of xHCI host controller for +the MT8173 SoC from Mediatek. + +Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> +--- + .../devicetree/bindings/usb/mt8173-xhci.txt | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + create mode 100644 Documentation/devicetree/bindings/usb/mt8173-xhci.txt + +diff --git a/Documentation/devicetree/bindings/usb/mt8173-xhci.txt b/Documentation/devicetree/bindings/usb/mt8173-xhci.txt +new file mode 100644 +index 0000000..da28570 +--- /dev/null ++++ b/Documentation/devicetree/bindings/usb/mt8173-xhci.txt +@@ -0,0 +1,19 @@ ++MT65XX xhci ++ ++The device node for Mediatek SOC usb3.0 host controller ++ ++Required properties: ++ - compatible : supports "mediatek,mt8173-xhci", "generic-xhci" ++ - reg : Offset and length of registers ++ - interrupts : Interrupt; mode, number and trigger ++ - usb-phy : the phy that xhci will bind ++ - usb3-lpm-capable: suppots USB3 LPM ++ ++Example: ++usb: usb30@11270000 { ++ compatible = "mediatek,mt8173-xhci", "generic-xhci"; ++ reg = <0 0x11270000 0 0x1000>; ++ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_LOW>; ++ usb-phy = <&u3phy>; ++ usb3-lpm-capable; ++}; +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0046-usb-phy-add-usb3.0-phy-driver-for-mt65xx-SoCs.patch b/target/linux/mediatek/patches/0046-usb-phy-add-usb3.0-phy-driver-for-mt65xx-SoCs.patch new file mode 100644 index 0000000000..40ba24d552 --- /dev/null +++ b/target/linux/mediatek/patches/0046-usb-phy-add-usb3.0-phy-driver-for-mt65xx-SoCs.patch @@ -0,0 +1,779 @@ +From cee7c5a343bdecf407c876289327c567bfd34fd4 Mon Sep 17 00:00:00 2001 +From: Chunfeng Yun <chunfeng.yun@mediatek.com> +Date: Wed, 27 May 2015 19:48:01 +0800 +Subject: [PATCH 46/76] usb: phy: add usb3.0 phy driver for mt65xx SoCs + +Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> +--- + drivers/usb/phy/Kconfig | 10 + + drivers/usb/phy/Makefile | 1 + + drivers/usb/phy/phy-mt65xx-usb3.c | 724 +++++++++++++++++++++++++++++++++++++ + 3 files changed, 735 insertions(+) + create mode 100644 drivers/usb/phy/phy-mt65xx-usb3.c + +diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig +index 2175678..dfca566 100644 +--- a/drivers/usb/phy/Kconfig ++++ b/drivers/usb/phy/Kconfig +@@ -151,6 +151,16 @@ config USB_MSM_OTG + This driver is not supported on boards like trout which + has an external PHY. + ++config USB_MT65XX_USB3_PHY ++ tristate "Mediatek USB3.0 PHY controller Driver" ++ depends on ARCH_MEDIATEK || COMPILE_TEST ++ select USB_PHY ++ help ++ Say 'Y' here to add support for Mediatek USB3.0 PHY driver ++ for mt65xx SoCs. it supports two usb2.0 ports and ++ one usb3.0 port. ++ To compile this driver as a module, choose M here ++ + config USB_MV_OTG + tristate "Marvell USB OTG support" + depends on USB_EHCI_MV && USB_MV_UDC && PM +diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile +index 75f2bba..d6113a4 100644 +--- a/drivers/usb/phy/Makefile ++++ b/drivers/usb/phy/Makefile +@@ -20,6 +20,7 @@ obj-$(CONFIG_USB_EHCI_TEGRA) += phy-tegra-usb.o + obj-$(CONFIG_USB_GPIO_VBUS) += phy-gpio-vbus-usb.o + obj-$(CONFIG_USB_ISP1301) += phy-isp1301.o + obj-$(CONFIG_USB_MSM_OTG) += phy-msm-usb.o ++obj-$(CONFIG_USB_MT65XX_USB3_PHY) += phy-mt65xx-usb3.o + obj-$(CONFIG_USB_MV_OTG) += phy-mv-usb.o + obj-$(CONFIG_USB_MXS_PHY) += phy-mxs-usb.o + obj-$(CONFIG_USB_RCAR_PHY) += phy-rcar-usb.o +diff --git a/drivers/usb/phy/phy-mt65xx-usb3.c b/drivers/usb/phy/phy-mt65xx-usb3.c +new file mode 100644 +index 0000000..ec5cf24 +--- /dev/null ++++ b/drivers/usb/phy/phy-mt65xx-usb3.c +@@ -0,0 +1,724 @@ ++/* ++ * Copyright (c) 2015 MediaTek Inc. ++ * Author: Chunfeng.Yun <chunfeng.yun@mediatek.com> ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include <linux/resource.h> ++#include <linux/delay.h> ++#include <linux/slab.h> ++#include <linux/err.h> ++#include <linux/export.h> ++#include <linux/module.h> ++#include <linux/platform_device.h> ++#include <linux/regulator/consumer.h> ++#include <linux/pm_runtime.h> ++#include <linux/io.h> ++#include <linux/gpio.h> ++#include <linux/of.h> ++#include <linux/of_device.h> ++#include <linux/of_gpio.h> ++#include <linux/of_address.h> ++#include <linux/usb/otg.h> ++#include <linux/usb/of.h> ++#include <linux/usb/phy.h> ++#include <linux/clk.h> ++#include <linux/iopoll.h> ++ ++/* ++ * relative to MAC base address ++ */ ++#define SSUSB_USB3_MAC_CSR_BASE (0x1400) ++#define SSUSB_USB3_SYS_CSR_BASE (0x1400) ++#define SSUSB_USB2_CSR_BASE (0x2400) ++ ++/* ++ * for sifslv1 register ++ * relative to USB3_SIF_BASE base address ++ */ ++#define SSUSB_SIFSLV_IPPC_BASE (0x700) ++ ++/* ++ * for sifslv2 register ++ * relative to USB3_SIF_BASE base address ++ */ ++#define SSUSB_SIFSLV_U2PHY_COM_BASE (0x10800) ++#define SSUSB_SIFSLV_U3PHYD_BASE (0x10900) ++#define SSUSB_SIFSLV_U2FREQ_BASE (0x10f00) ++#define SSUSB_USB30_PHYA_SIV_B_BASE (0x10b00) ++#define SSUSB_SIFSLV_U3PHYA_DA_BASE (0x10c00) ++#define SSUSB_SIFSLV_SPLLC (0x10000) ++ ++/*port1 refs. +0x800(refer to port0)*/ ++#define U3P_PORT_OFFSET (0x800) /*based on port0 */ ++#define U3P_PHY_BASE(index) ((U3P_PORT_OFFSET) * (index)) ++ ++#define U3P_IP_PW_CTRL0 (SSUSB_SIFSLV_IPPC_BASE+0x0000) ++#define CTRL0_IP_SW_RST (0x1<<0) ++ ++#define U3P_IP_PW_CTRL1 (SSUSB_SIFSLV_IPPC_BASE+0x0004) ++#define CTRL1_IP_HOST_PDN (0x1<<0) ++ ++#define U3P_IP_PW_STS1 (SSUSB_SIFSLV_IPPC_BASE+0x0010) ++#define STS1_U3_MAC_RST (0x1 << 16) ++#define STS1_SYS125_RST (0x1 << 10) ++#define STS1_REF_RST (0x1 << 8) ++#define STS1_SYSPLL_STABLE (0x1 << 0) ++ ++#define U3P_IP_PW_STS2 (SSUSB_SIFSLV_IPPC_BASE+0x0014) ++#define STS2_U2_MAC_RST (0x1 << 0) ++ ++#define U3P_IP_XHCI_CAP (SSUSB_SIFSLV_IPPC_BASE + 0x24) ++#define CAP_U3_PORT_NUM(p) ((p) & 0xff) ++#define CAP_U2_PORT_NUM(p) (((p) >> 8) & 0xff) ++ ++#define U3P_U3_CTRL_0P (SSUSB_SIFSLV_IPPC_BASE+0x0030) ++#define CTRL_U3_PORT_HOST_SEL (0x1<<2) ++#define CTRL_U3_PORT_PDN (0x1<<1) ++#define CTRL_U3_PORT_DIS (0x1<<0) ++ ++#define U3P_U2_CTRL_0P (SSUSB_SIFSLV_IPPC_BASE+0x0050) ++#define CTRL_U2_PORT_HOST_SEL (0x1<<2) ++#define CTRL_U2_PORT_PDN (0x1<<1) ++#define CTRL_U2_PORT_DIS (0x1<<0) ++ ++#define U3P_U3_CTRL(p) (U3P_U3_CTRL_0P + ((p) * 0x08)) ++#define U3P_U2_CTRL(p) (U3P_U2_CTRL_0P + ((p) * 0x08)) ++ ++#define U3P_USBPHYACR5 (SSUSB_SIFSLV_U2PHY_COM_BASE+0x0014) ++#define PA5_RG_U2_HSTX_SRCTRL (0x7<<12) ++#define PA5_RG_U2_HSTX_SRCTRL_VAL(x) ((0x7 & (x)) << 12) ++#define PA5_RG_U2_HS_100U_U3_EN (0x1<<11) ++ ++#define U3P_USBPHYACR6 (SSUSB_SIFSLV_U2PHY_COM_BASE+0x0018) ++#define PA6_RG_U2_ISO_EN (0x1<<31) ++#define PA6_RG_U2_BC11_SW_EN (0x1<<23) ++#define PA6_RG_U2_OTG_VBUSCMP_EN (0x1<<20) ++ ++#define U3P_U2PHYACR4 (SSUSB_SIFSLV_U2PHY_COM_BASE+0x0020) ++#define P2C_RG_USB20_GPIO_CTL (0x1<<9) ++#define P2C_USB20_GPIO_MODE (0x1<<8) ++#define P2C_U2_GPIO_CTR_MSK (P2C_RG_USB20_GPIO_CTL | P2C_USB20_GPIO_MODE) ++ ++#define U3P_U2PHYDTM0 (SSUSB_SIFSLV_U2PHY_COM_BASE+0x0068) ++#define P2C_FORCE_UART_EN (0x1<<26) ++#define P2C_FORCE_DATAIN (0x1<<23) ++#define P2C_FORCE_DM_PULLDOWN (0x1<<21) ++#define P2C_FORCE_DP_PULLDOWN (0x1<<20) ++#define P2C_FORCE_XCVRSEL (0x1<<19) ++#define P2C_FORCE_SUSPENDM (0x1<<18) ++#define P2C_FORCE_TERMSEL (0x1<<17) ++#define P2C_RG_DATAIN (0xf<<10) ++#define P2C_RG_DATAIN_VAL(x) ((0xf & (x)) << 10) ++#define P2C_RG_DMPULLDOWN (0x1<<7) ++#define P2C_RG_DPPULLDOWN (0x1<<6) ++#define P2C_RG_XCVRSEL (0x3<<4) ++#define P2C_RG_XCVRSEL_VAL(x) ((0x3 & (x)) << 4) ++#define P2C_RG_SUSPENDM (0x1<<3) ++#define P2C_RG_TERMSEL (0x1<<2) ++#define P2C_DTM0_PART_MASK \ ++ (P2C_FORCE_DATAIN | P2C_FORCE_DM_PULLDOWN | \ ++ P2C_FORCE_DP_PULLDOWN | P2C_FORCE_XCVRSEL | \ ++ P2C_FORCE_TERMSEL | P2C_RG_DMPULLDOWN | \ ++ P2C_RG_TERMSEL) ++ ++#define U3P_U2PHYDTM1 (SSUSB_SIFSLV_U2PHY_COM_BASE+0x006C) ++#define P2C_RG_UART_EN (0x1<<16) ++#define P2C_RG_VBUSVALID (0x1<<5) ++#define P2C_RG_SESSEND (0x1<<4) ++#define P2C_RG_AVALID (0x1<<2) ++ ++#define U3P_U3_PHYA_REG0 (SSUSB_USB30_PHYA_SIV_B_BASE+0x0000) ++#define P3A_RG_U3_VUSB10_ON (1<<5) ++ ++#define U3P_U3_PHYA_REG6 (SSUSB_USB30_PHYA_SIV_B_BASE+0x0018) ++#define P3A_RG_TX_EIDLE_CM (0xf<<28) ++#define P3A_RG_TX_EIDLE_CM_VAL(x) ((0xf & (x)) << 28) ++ ++#define U3P_U3_PHYA_REG9 (SSUSB_USB30_PHYA_SIV_B_BASE+0x0024) ++#define P3A_RG_RX_DAC_MUX (0x1f<<1) ++#define P3A_RG_RX_DAC_MUX_VAL(x) ((0x1f & (x)) << 1) ++ ++#define U3P_U3PHYA_DA_REG0 (SSUSB_SIFSLV_U3PHYA_DA_BASE + 0x0) ++#define P3A_RG_XTAL_EXT_EN_U3 (0x3<<10) ++#define P3A_RG_XTAL_EXT_EN_U3_VAL(x) ((0x3 & (x)) << 10) ++ ++#define U3P_PHYD_CDR1 (SSUSB_SIFSLV_U3PHYD_BASE+0x5c) ++#define P3D_RG_CDR_BIR_LTD1 (0x1f<<24) ++#define P3D_RG_CDR_BIR_LTD1_VAL(x) ((0x1f & (x)) << 24) ++#define P3D_RG_CDR_BIR_LTD0 (0x1f<<8) ++#define P3D_RG_CDR_BIR_LTD0_VAL(x) ((0x1f & (x)) << 8) ++ ++#define U3P_XTALCTL3 (SSUSB_SIFSLV_SPLLC + 0x18) ++#define XC3_RG_U3_XTAL_RX_PWD (0x1<<9) ++#define XC3_RG_U3_FRC_XTAL_RX_PWD (0x1<<8) ++ ++#define U3P_UX_EXIT_LFPS_PARAM (SSUSB_USB3_MAC_CSR_BASE+0x00A0) ++#define RX_UX_EXIT_REF (0xff<<8) ++#define RX_UX_EXIT_REF_VAL (0x3 << 8) ++ ++#define U3P_REF_CLK_PARAM (SSUSB_USB3_MAC_CSR_BASE+0x00B0) ++#define REF_CLK_1000NS (0xff << 0) ++#define REF_CLK_VAL_DEF (0xa << 0) ++ ++#define U3P_LINK_PM_TIMER (SSUSB_USB3_SYS_CSR_BASE+0x0208) ++#define PM_LC_TIMEOUT (0xf<<0) ++#define PM_LC_TIMEOUT_VAL (0x3 << 0) ++ ++#define U3P_TIMING_PULSE_CTRL (SSUSB_USB3_SYS_CSR_BASE+0x02B4) ++#define U3T_CNT_1US (0xff << 0) ++#define U3T_CNT_1US_VAL (0x3f << 0) /* 62.5MHz: 63 */ ++ ++#define U3P_U2_TIMING_PARAM (SSUSB_USB2_CSR_BASE+0x0040) ++#define U2T_VAL_1US (0xff<<0) ++#define U2T_VAL_1US_VAL (0x3f << 0) /* 62.5MHz: 63 */ ++ ++ ++struct mt65xx_u3phy { ++ struct usb_phy phy; ++ struct device *dev; ++ struct regulator *vusb33; ++ struct regulator *p1_vbus; ++ void __iomem *mac_base; /* only device-mac regs, exclude xhci's */ ++ void __iomem *sif_base; /* include sif & sif2 */ ++ struct clk *wk_deb_p0; /* port0's wakeup debounce clock */ ++ struct clk *wk_deb_p1; ++ struct clk *sys_mac; /* sys and mac clock */ ++ struct clk *u3phya_ref; /* reference clock of usb3 anolog phy */ ++ bool enable_usb2_p1; ++}; ++ ++ ++static void u3p_writel(void __iomem *base, u32 offset, u32 data) ++{ ++ writel(data, base + offset); ++} ++ ++static u32 u3p_readl(void __iomem *base, u32 offset) ++{ ++ return readl(base + offset); ++} ++ ++static void u3p_setmsk(void __iomem *base, u32 offset, u32 msk) ++{ ++ void __iomem *addr = base + offset; ++ ++ writel((readl(addr) | msk), addr); ++} ++ ++static void u3p_clrmsk(void __iomem *base, u32 offset, u32 msk) ++{ ++ void __iomem *addr = base + offset; ++ ++ writel((readl(addr) & ~msk), addr); ++} ++ ++static void u3p_setval(void __iomem *base, u32 offset, ++ u32 mask, u32 value) ++{ ++ void __iomem *addr = base + offset; ++ unsigned int new_value; ++ ++ new_value = (readl(addr) & ~mask) | value; ++ writel(new_value, addr); ++} ++ ++static void phy_index_power_on(struct mt65xx_u3phy *u3phy, int index) ++{ ++ void __iomem *sif_base = u3phy->sif_base + U3P_PHY_BASE(index); ++ ++ if (!index) { ++ /* Set RG_SSUSB_VUSB10_ON as 1 after VUSB10 ready */ ++ u3p_setmsk(sif_base, U3P_U3_PHYA_REG0, P3A_RG_U3_VUSB10_ON); ++ /* power domain iso disable */ ++ u3p_clrmsk(sif_base, U3P_USBPHYACR6, PA6_RG_U2_ISO_EN); ++ } ++ ++ /* switch to USB function. (system register, force ip into usb mode) */ ++ u3p_clrmsk(sif_base, U3P_U2PHYDTM0, P2C_FORCE_UART_EN); ++ u3p_clrmsk(sif_base, U3P_U2PHYDTM1, P2C_RG_UART_EN); ++ if (!index) ++ u3p_clrmsk(sif_base, U3P_U2PHYACR4, P2C_U2_GPIO_CTR_MSK); ++ ++ /* (force_suspendm=0) (let suspendm=1, enable usb 480MHz pll) */ ++ u3p_clrmsk(sif_base, U3P_U2PHYDTM0, P2C_FORCE_SUSPENDM); ++ u3p_clrmsk(sif_base, U3P_U2PHYDTM0, ++ P2C_RG_XCVRSEL | P2C_RG_DATAIN | P2C_DTM0_PART_MASK); ++ ++ /* DP/DM BC1.1 path Disable */ ++ u3p_clrmsk(sif_base, U3P_USBPHYACR6, PA6_RG_U2_BC11_SW_EN); ++ /* OTG Enable */ ++ u3p_setmsk(sif_base, U3P_USBPHYACR6, PA6_RG_U2_OTG_VBUSCMP_EN); ++ u3p_setval(sif_base, U3P_U3PHYA_DA_REG0, P3A_RG_XTAL_EXT_EN_U3, ++ P3A_RG_XTAL_EXT_EN_U3_VAL(2)); ++ u3p_setval(sif_base, U3P_U3_PHYA_REG9, P3A_RG_RX_DAC_MUX, ++ P3A_RG_RX_DAC_MUX_VAL(4)); ++ ++ if (!index) { ++ u3p_setmsk(sif_base, U3P_XTALCTL3, XC3_RG_U3_XTAL_RX_PWD); ++ u3p_setmsk(sif_base, U3P_XTALCTL3, XC3_RG_U3_FRC_XTAL_RX_PWD); ++ /* [mt8173]disable Change 100uA current from SSUSB */ ++ u3p_clrmsk(sif_base, U3P_USBPHYACR5, PA5_RG_U2_HS_100U_U3_EN); ++ } ++ u3p_setval(sif_base, U3P_U3_PHYA_REG6, P3A_RG_TX_EIDLE_CM, ++ P3A_RG_TX_EIDLE_CM_VAL(0xe)); ++ u3p_setval(sif_base, U3P_PHYD_CDR1, P3D_RG_CDR_BIR_LTD0, ++ P3D_RG_CDR_BIR_LTD0_VAL(0xc)); ++ u3p_setval(sif_base, U3P_PHYD_CDR1, P3D_RG_CDR_BIR_LTD1, ++ P3D_RG_CDR_BIR_LTD1_VAL(0x3)); ++ ++ udelay(800); ++ u3p_setmsk(sif_base, U3P_U2PHYDTM1, P2C_RG_VBUSVALID | P2C_RG_AVALID); ++ u3p_clrmsk(sif_base, U3P_U2PHYDTM1, P2C_RG_SESSEND); ++ ++ /* USB 2.0 slew rate calibration */ ++ u3p_setval(sif_base, U3P_USBPHYACR5, PA5_RG_U2_HSTX_SRCTRL, ++ PA5_RG_U2_HSTX_SRCTRL_VAL(4)); ++ ++ dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index); ++} ++ ++ ++static void phy_index_power_off(struct mt65xx_u3phy *u3phy, int index) ++{ ++ void __iomem *sif_base = u3phy->sif_base + U3P_PHY_BASE(index); ++ ++ /* switch to USB function. (system register, force ip into usb mode) */ ++ u3p_clrmsk(sif_base, U3P_U2PHYDTM0, P2C_FORCE_UART_EN); ++ u3p_clrmsk(sif_base, U3P_U2PHYDTM1, P2C_RG_UART_EN); ++ if (!index) ++ u3p_clrmsk(sif_base, U3P_U2PHYACR4, P2C_U2_GPIO_CTR_MSK); ++ ++ u3p_setmsk(sif_base, U3P_U2PHYDTM0, P2C_FORCE_SUSPENDM); ++ u3p_setval(sif_base, U3P_U2PHYDTM0, ++ P2C_RG_XCVRSEL, P2C_RG_XCVRSEL_VAL(1)); ++ u3p_setval(sif_base, U3P_U2PHYDTM0, ++ P2C_RG_DATAIN, P2C_RG_DATAIN_VAL(0)); ++ u3p_setmsk(sif_base, U3P_U2PHYDTM0, P2C_DTM0_PART_MASK); ++ /* DP/DM BC1.1 path Disable */ ++ u3p_clrmsk(sif_base, U3P_USBPHYACR6, PA6_RG_U2_BC11_SW_EN); ++ /* OTG Disable */ ++ u3p_clrmsk(sif_base, U3P_USBPHYACR6, PA6_RG_U2_OTG_VBUSCMP_EN); ++ if (!index) { ++ /* Change 100uA current switch to USB2.0 */ ++ u3p_clrmsk(sif_base, U3P_USBPHYACR5, PA5_RG_U2_HS_100U_U3_EN); ++ } ++ udelay(800); ++ ++ /* let suspendm=0, set utmi into analog power down */ ++ u3p_clrmsk(sif_base, U3P_U2PHYDTM0, P2C_RG_SUSPENDM); ++ udelay(1); ++ ++ u3p_clrmsk(sif_base, U3P_U2PHYDTM1, P2C_RG_VBUSVALID | P2C_RG_AVALID); ++ u3p_setmsk(sif_base, U3P_U2PHYDTM1, P2C_RG_SESSEND); ++ if (!index) { ++ /* Set RG_SSUSB_VUSB10_ON as 1 after VUSB10 ready */ ++ u3p_clrmsk(sif_base, U3P_U3_PHYA_REG0, P3A_RG_U3_VUSB10_ON); ++ } ++ dev_dbg(u3phy->dev, "%s(%d)\n", __func__, index); ++} ++ ++ ++static int check_ip_clk_status(struct mt65xx_u3phy *u3phy) ++{ ++ int ret; ++ int u3_port_num; ++ int u2_port_num; ++ u32 xhci_cap; ++ u32 val; ++ void __iomem *sif_base = u3phy->sif_base; ++ ++ xhci_cap = u3p_readl(sif_base, U3P_IP_XHCI_CAP); ++ u3_port_num = CAP_U3_PORT_NUM(xhci_cap); ++ u2_port_num = CAP_U2_PORT_NUM(xhci_cap); ++ ++ ret = readl_poll_timeout(sif_base + U3P_IP_PW_STS1, val, ++ (val & STS1_SYSPLL_STABLE), 100, 10000); ++ if (ret) { ++ dev_err(u3phy->dev, "sypll is not stable!!!\n"); ++ return ret; ++ } ++ ++ ret = readl_poll_timeout(sif_base + U3P_IP_PW_STS1, val, ++ (val & STS1_REF_RST), 100, 10000); ++ if (ret) { ++ dev_err(u3phy->dev, "ref_clk is still active!!!\n"); ++ return ret; ++ } ++ ++ ret = readl_poll_timeout(sif_base + U3P_IP_PW_STS1, val, ++ (val & STS1_SYS125_RST), 100, 10000); ++ if (ret) { ++ dev_err(u3phy->dev, "sys125_ck is still active!!!\n"); ++ return ret; ++ } ++ ++ if (u3_port_num) { ++ ret = readl_poll_timeout(sif_base + U3P_IP_PW_STS1, val, ++ (val & STS1_U3_MAC_RST), 100, 10000); ++ if (ret) { ++ dev_err(u3phy->dev, "mac3_mac_ck is still active!!!\n"); ++ return ret; ++ } ++ } ++ ++ if (u2_port_num) { ++ ret = readl_poll_timeout(sif_base + U3P_IP_PW_STS2, val, ++ (val & STS2_U2_MAC_RST), 100, 10000); ++ if (ret) { ++ dev_err(u3phy->dev, "mac2_sys_ck is still active!!!\n"); ++ return ret; ++ } ++ } ++ ++ return 0; ++} ++ ++static int u3phy_ports_enable(struct mt65xx_u3phy *u3phy) ++{ ++ int i; ++ u32 temp; ++ int u3_port_num; ++ int u2_port_num; ++ void __iomem *sif_base = u3phy->sif_base; ++ ++ temp = u3p_readl(sif_base, U3P_IP_XHCI_CAP); ++ u3_port_num = CAP_U3_PORT_NUM(temp); ++ u2_port_num = CAP_U2_PORT_NUM(temp); ++ dev_dbg(u3phy->dev, "%s u2p:%d, u3p:%d\n", ++ __func__, u2_port_num, u3_port_num); ++ ++ /* power on host ip */ ++ u3p_clrmsk(sif_base, U3P_IP_PW_CTRL1, CTRL1_IP_HOST_PDN); ++ ++ /* power on and enable all u3 ports */ ++ for (i = 0; i < u3_port_num; i++) { ++ temp = u3p_readl(sif_base, U3P_U3_CTRL(i)); ++ temp &= ~(CTRL_U3_PORT_PDN | CTRL_U3_PORT_DIS); ++ temp |= CTRL_U3_PORT_HOST_SEL; ++ u3p_writel(sif_base, U3P_U3_CTRL(i), temp); ++ } ++ ++ /* power on and enable all u2 ports */ ++ for (i = 0; i < u2_port_num; i++) { ++ temp = u3p_readl(sif_base, U3P_U2_CTRL(i)); ++ temp &= ~(CTRL_U2_PORT_PDN | CTRL_U2_PORT_DIS); ++ temp |= CTRL_U2_PORT_HOST_SEL; ++ u3p_writel(sif_base, U3P_U2_CTRL(i), temp); ++ } ++ return check_ip_clk_status(u3phy); ++} ++ ++ ++static void u3phy_timing_init(struct mt65xx_u3phy *u3phy) ++{ ++ void __iomem *mbase = u3phy->mac_base; ++ int u3_port_num; ++ u32 temp; ++ ++ temp = u3p_readl(u3phy->sif_base, U3P_IP_XHCI_CAP); ++ u3_port_num = CAP_U3_PORT_NUM(temp); ++ ++ if (u3_port_num) { ++ /* set MAC reference clock speed */ ++ u3p_setval(mbase, U3P_UX_EXIT_LFPS_PARAM, ++ RX_UX_EXIT_REF, RX_UX_EXIT_REF_VAL); ++ /* set REF_CLK */ ++ u3p_setval(mbase, U3P_REF_CLK_PARAM, ++ REF_CLK_1000NS, REF_CLK_VAL_DEF); ++ /* set SYS_CLK */ ++ u3p_setval(mbase, U3P_TIMING_PULSE_CTRL, ++ U3T_CNT_1US, U3T_CNT_1US_VAL); ++ /* set LINK_PM_TIMER=3 */ ++ u3p_setval(mbase, U3P_LINK_PM_TIMER, ++ PM_LC_TIMEOUT, PM_LC_TIMEOUT_VAL); ++ } ++ u3p_setval(mbase, U3P_U2_TIMING_PARAM, U2T_VAL_1US, U2T_VAL_1US_VAL); ++} ++ ++ ++static int u3phy_clks_enable(struct mt65xx_u3phy *u3phy) ++{ ++ int ret; ++ ++ ret = clk_prepare_enable(u3phy->sys_mac); ++ if (ret) { ++ dev_err(u3phy->dev, "failed to enable sys_mac\n"); ++ goto sys_mac_err; ++ } ++ ++ ret = clk_prepare_enable(u3phy->u3phya_ref); ++ if (ret) { ++ dev_err(u3phy->dev, "failed to enable u3phya_ref\n"); ++ goto u3phya_ref_err; ++ } ++ ret = clk_prepare_enable(u3phy->wk_deb_p0); ++ if (ret) { ++ dev_err(u3phy->dev, "failed to enable wk_deb_p0\n"); ++ goto usb_p0_err; ++ } ++ if (u3phy->enable_usb2_p1) { ++ ret = clk_prepare_enable(u3phy->wk_deb_p1); ++ if (ret) { ++ dev_err(u3phy->dev, "failed to enable wk_deb_p1\n"); ++ goto usb_p1_err; ++ } ++ } ++ udelay(50); ++ ++ return 0; ++ ++usb_p1_err: ++ clk_disable_unprepare(u3phy->wk_deb_p0); ++usb_p0_err: ++ clk_disable_unprepare(u3phy->u3phya_ref); ++u3phya_ref_err: ++ clk_disable_unprepare(u3phy->sys_mac); ++sys_mac_err: ++ return -EINVAL; ++} ++ ++static void u3phy_clks_disable(struct mt65xx_u3phy *u3phy) ++{ ++ if (u3phy->enable_usb2_p1) ++ clk_disable_unprepare(u3phy->wk_deb_p1); ++ clk_disable_unprepare(u3phy->wk_deb_p0); ++ clk_disable_unprepare(u3phy->u3phya_ref); ++ clk_disable_unprepare(u3phy->sys_mac); ++} ++ ++ ++static int mt65xx_u3phy_init(struct usb_phy *phy) ++{ ++ struct mt65xx_u3phy *u3phy; ++ int ret; ++ ++ u3phy = container_of(phy, struct mt65xx_u3phy, phy); ++ dev_dbg(u3phy->dev, "%s+\n", __func__); ++ ++ if (u3phy->enable_usb2_p1) { ++ ret = regulator_enable(u3phy->p1_vbus); ++ if (ret) { ++ dev_err(u3phy->dev, "failed to enable p1-vbus\n"); ++ goto reg_p1_err; ++ } ++ } ++ ++ ret = regulator_enable(u3phy->vusb33); ++ if (ret) { ++ dev_err(u3phy->dev, "failed to enable vusb33\n"); ++ goto reg_err; ++ } ++ ++ ret = pm_runtime_get_sync(u3phy->dev); ++ if (ret < 0) ++ goto pm_err; ++ ++ ret = u3phy_clks_enable(u3phy); ++ if (ret) { ++ dev_err(u3phy->dev, "failed to enable clks\n"); ++ goto clks_err; ++ } ++ ++ /* reset whole ip */ ++ u3p_setmsk(u3phy->sif_base, U3P_IP_PW_CTRL0, CTRL0_IP_SW_RST); ++ u3p_clrmsk(u3phy->sif_base, U3P_IP_PW_CTRL0, CTRL0_IP_SW_RST); ++ ++ ret = u3phy_ports_enable(u3phy); ++ if (ret) { ++ dev_err(u3phy->dev, "failed to enable ports\n"); ++ goto port_err; ++ } ++ u3phy_timing_init(u3phy); ++ phy_index_power_on(u3phy, 0); ++ if (u3phy->enable_usb2_p1) ++ phy_index_power_on(u3phy, 1); ++ ++ return 0; ++ ++port_err: ++ u3phy_clks_disable(u3phy); ++clks_err: ++ pm_runtime_put_sync(u3phy->dev); ++pm_err: ++ regulator_disable(u3phy->vusb33); ++reg_err: ++ if (u3phy->enable_usb2_p1) ++ regulator_disable(u3phy->p1_vbus); ++reg_p1_err: ++ return ret; ++} ++ ++ ++static void mt65xx_u3phy_shutdown(struct usb_phy *phy) ++{ ++ struct mt65xx_u3phy *u3phy; ++ ++ u3phy = container_of(phy, struct mt65xx_u3phy, phy); ++ dev_dbg(u3phy->dev, "%s+\n", __func__); ++ ++ phy_index_power_off(u3phy, 0); ++ if (u3phy->enable_usb2_p1) { ++ phy_index_power_off(u3phy, 1); ++ regulator_disable(u3phy->p1_vbus); ++ } ++ u3phy_clks_disable(u3phy); ++ pm_runtime_put_sync(u3phy->dev); ++ regulator_disable(u3phy->vusb33); ++} ++ ++ ++static int mt65xx_u3phy_suspend(struct usb_phy *x, int suspend) ++{ ++ struct mt65xx_u3phy *u3phy = container_of(x, struct mt65xx_u3phy, phy); ++ ++ if (suspend) { ++ mt65xx_u3phy_shutdown(&u3phy->phy); ++ return 0; ++ } else { ++ return mt65xx_u3phy_init(&u3phy->phy); ++ } ++} ++ ++ ++static const struct of_device_id mt65xx_u3phy_id_table[] = { ++ { .compatible = "mediatek,mt8173-u3phy",}, ++ { }, ++}; ++MODULE_DEVICE_TABLE(of, mt65xx_u3phy_id_table); ++ ++ ++static int mt65xx_u3phy_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *np = dev->of_node; ++ struct resource *mac_res; ++ struct resource *sif_res; ++ struct mt65xx_u3phy *u3phy; ++ int retval = -ENOMEM; ++ ++ u3phy = devm_kzalloc(&pdev->dev, sizeof(*u3phy), GFP_KERNEL); ++ if (!u3phy) ++ goto err; ++ ++ u3phy->dev = &pdev->dev; ++ ++ mac_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ u3phy->mac_base = devm_ioremap_resource(dev, mac_res); ++ if (IS_ERR(u3phy->mac_base)) { ++ dev_err(dev, "failed to remap mac regs\n"); ++ retval = PTR_ERR(u3phy->mac_base); ++ goto err; ++ } ++ ++ sif_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ u3phy->sif_base = devm_ioremap_resource(dev, sif_res); ++ if (IS_ERR(u3phy->sif_base)) { ++ dev_err(dev, "failed to remap sif regs\n"); ++ retval = PTR_ERR(u3phy->sif_base); ++ goto err; ++ } ++ ++ u3phy->enable_usb2_p1 = !of_property_read_bool(np, "disable-usb2-p1"); ++ dev_dbg(dev, "enable_usb2_p1 - %d\n", u3phy->enable_usb2_p1); ++ ++ u3phy->sys_mac = devm_clk_get(u3phy->dev, "sys_mac"); ++ if (IS_ERR(u3phy->sys_mac)) { ++ dev_err(dev, "error to get sys_mac\n"); ++ retval = PTR_ERR(u3phy->sys_mac); ++ goto err; ++ } ++ ++ u3phy->u3phya_ref = devm_clk_get(u3phy->dev, "u3phya_ref"); ++ if (IS_ERR(u3phy->u3phya_ref)) { ++ dev_err(dev, "error to get u3phya_ref\n"); ++ retval = PTR_ERR(u3phy->u3phya_ref); ++ goto err; ++ } ++ ++ u3phy->wk_deb_p0 = devm_clk_get(u3phy->dev, "wakeup_deb_p0"); ++ if (IS_ERR(u3phy->wk_deb_p0)) { ++ dev_err(dev, "error to get wakeup_deb_p0\n"); ++ retval = PTR_ERR(u3phy->wk_deb_p0); ++ goto err; ++ } ++ ++ if (u3phy->enable_usb2_p1) { ++ u3phy->wk_deb_p1 = devm_clk_get(u3phy->dev, "wakeup_deb_p1"); ++ if (IS_ERR(u3phy->wk_deb_p1)) { ++ dev_err(dev, "error to get wakeup_deb_p1\n"); ++ retval = PTR_ERR(u3phy->wk_deb_p1); ++ goto err; ++ } ++ ++ u3phy->p1_vbus = devm_regulator_get(u3phy->dev, "reg-p1-vbus"); ++ if (IS_ERR_OR_NULL(u3phy->p1_vbus)) { ++ dev_err(dev, "fail to get p1-vbus\n"); ++ retval = PTR_ERR(u3phy->p1_vbus); ++ goto err; ++ } ++ } ++ ++ u3phy->vusb33 = devm_regulator_get(u3phy->dev, "reg-vusb33"); ++ if (IS_ERR_OR_NULL(u3phy->vusb33)) { ++ dev_err(dev, "fail to get vusb33\n"); ++ retval = PTR_ERR(u3phy->vusb33); ++ goto err; ++ } ++ ++ pm_runtime_enable(dev); ++ u3phy->phy.dev = u3phy->dev; ++ u3phy->phy.label = "mt65xx-usb3phy"; ++ u3phy->phy.type = USB_PHY_TYPE_USB3; ++ u3phy->phy.init = mt65xx_u3phy_init; ++ u3phy->phy.shutdown = mt65xx_u3phy_shutdown; ++ u3phy->phy.set_suspend = mt65xx_u3phy_suspend; ++ ++ platform_set_drvdata(pdev, u3phy); ++ retval = usb_add_phy_dev(&u3phy->phy); ++ if (retval) { ++ dev_err(dev, "failed to add phy\n"); ++ goto add_phy_err; ++ } ++ ++ return 0; ++ ++add_phy_err: ++ pm_runtime_disable(dev); ++err: ++ return retval; ++} ++ ++static int mt65xx_u3phy_remove(struct platform_device *pdev) ++{ ++ struct mt65xx_u3phy *u3phy = platform_get_drvdata(pdev); ++ ++ mt65xx_u3phy_shutdown(&u3phy->phy); ++ pm_runtime_disable(&pdev->dev); ++ usb_remove_phy(&u3phy->phy); ++ ++ return 0; ++} ++ ++static struct platform_driver mt65xx_u3phy_driver = { ++ .probe = mt65xx_u3phy_probe, ++ .remove = mt65xx_u3phy_remove, ++ .driver = { ++ .name = "mt65xx-u3phy", ++ .of_match_table = mt65xx_u3phy_id_table, ++ }, ++}; ++ ++module_platform_driver(mt65xx_u3phy_driver); ++ ++MODULE_DESCRIPTION("Mt65xx USB PHY driver"); ++MODULE_LICENSE("GPL v2"); +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0047-xhci-mediatek-support-MTK-xHCI-host-controller.patch b/target/linux/mediatek/patches/0047-xhci-mediatek-support-MTK-xHCI-host-controller.patch new file mode 100644 index 0000000000..ea3289ed7e --- /dev/null +++ b/target/linux/mediatek/patches/0047-xhci-mediatek-support-MTK-xHCI-host-controller.patch @@ -0,0 +1,832 @@ +From e604b6c864f2e3b6fe0706c4bef886533d92f67a Mon Sep 17 00:00:00 2001 +From: Chunfeng Yun <chunfeng.yun@mediatek.com> +Date: Wed, 27 May 2015 19:48:02 +0800 +Subject: [PATCH 47/76] xhci: mediatek: support MTK xHCI host controller + +MTK xhci host controller defines some extra SW scheduling +parameters for HW to minimize the scheduling effort for +synchronous and interrupt endpoints. The parameters are +put into reseved DWs of slot context and endpoint context. + +Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> +--- + drivers/usb/host/Kconfig | 9 + + drivers/usb/host/Makefile | 3 + + drivers/usb/host/xhci-mtk.c | 470 ++++++++++++++++++++++++++++++++++++++++++ + drivers/usb/host/xhci-mtk.h | 119 +++++++++++ + drivers/usb/host/xhci-plat.c | 22 +- + drivers/usb/host/xhci-ring.c | 35 +++- + drivers/usb/host/xhci.c | 16 +- + drivers/usb/host/xhci.h | 1 + + 8 files changed, 667 insertions(+), 8 deletions(-) + create mode 100644 drivers/usb/host/xhci-mtk.c + create mode 100644 drivers/usb/host/xhci-mtk.h + +--- a/drivers/usb/host/Kconfig ++++ b/drivers/usb/host/Kconfig +@@ -41,6 +41,15 @@ + + If unsure, say N. + ++config USB_XHCI_MTK ++ tristate "xHCI support for Mediatek MT65xx" ++ select USB_XHCI_PLATFORM ++ depends on ARCH_MEDIATEK || COMPILE_TEST ++ ---help--- ++ Say 'Y' to enable the support for the xHCI host controller ++ found in Mediatek MT65xx SoCs. ++ If unsure, say N. ++ + config USB_XHCI_MVEBU + tristate "xHCI support for Marvell Armada 375/38x" + select USB_XHCI_PLATFORM +--- a/drivers/usb/host/Makefile ++++ b/drivers/usb/host/Makefile +@@ -15,6 +15,9 @@ + xhci-hcd-y += xhci-trace.o + + xhci-plat-hcd-y := xhci-plat.o ++ifneq ($(CONFIG_USB_XHCI_MTK), ) ++ xhci-plat-hcd-y += xhci-mtk.o ++endif + ifneq ($(CONFIG_USB_XHCI_MVEBU), ) + xhci-plat-hcd-y += xhci-mvebu.o + endif +--- /dev/null ++++ b/drivers/usb/host/xhci-mtk.c +@@ -0,0 +1,470 @@ ++/* ++ * Copyright (c) 2015 MediaTek Inc. ++ * Author: ++ * Zhigang.Wei <zhigang.wei@mediatek.com> ++ * Chunfeng.Yun <chunfeng.yun@mediatek.com> ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/slab.h> ++#include "xhci-mtk.h" ++ ++ ++#define SS_BW_BOUNDARY 51000 ++/* table 5-5. High-speed Isoc Transaction Limits in usb_20 spec */ ++#define HS_BW_BOUNDARY 6144 ++/* usb2 spec section11.18.1: at most 188 FS bytes per microframe */ ++#define FS_PAYLOAD_MAX 188 ++ ++/* mtk scheduler bitmasks */ ++#define EP_BPKTS(p) ((p) & 0x3f) ++#define EP_BCSCOUNT(p) (((p) & 0x7) << 8) ++#define EP_BBM(p) ((p) << 11) ++#define EP_BOFFSET(p) ((p) & 0x3fff) ++#define EP_BREPEAT(p) (((p) & 0x7fff) << 16) ++ ++static int is_fs_or_ls(enum usb_device_speed speed) ++{ ++ return speed == USB_SPEED_FULL || speed == USB_SPEED_LOW; ++} ++ ++static int get_bw_index(struct xhci_hcd *xhci, struct usb_device *udev, ++ struct usb_host_endpoint *ep) ++{ ++ int bw_index; ++ int port_id; ++ struct xhci_virt_device *virt_dev; ++ ++ virt_dev = xhci->devs[udev->slot_id]; ++ port_id = virt_dev->real_port; ++ ++ if (udev->speed == USB_SPEED_SUPER) { ++ if (usb_endpoint_dir_out(&ep->desc)) ++ bw_index = (port_id - 1) * 2; ++ else ++ bw_index = (port_id - 1) * 2 + 1; ++ } else { ++ bw_index = port_id + xhci->num_usb3_ports - 1; ++ } ++ ++ return bw_index; ++} ++ ++ ++static void setup_sch_info(struct usb_device *udev, ++ struct xhci_ep_ctx *ep_ctx, struct mu3h_sch_ep_info *sch_ep) ++{ ++ u32 ep_type; ++ u32 ep_interval; ++ u32 max_packet_size; ++ u32 max_burst; ++ u32 mult; ++ u32 esit_pkts; ++ ++ ep_type = CTX_TO_EP_TYPE(le32_to_cpu(ep_ctx->ep_info2)); ++ ep_interval = CTX_TO_EP_INTERVAL(le32_to_cpu(ep_ctx->ep_info)); ++ max_packet_size = MAX_PACKET_DECODED(le32_to_cpu(ep_ctx->ep_info2)); ++ max_burst = CTX_TO_MAX_BURST(le32_to_cpu(ep_ctx->ep_info2)); ++ mult = CTX_TO_EP_MULT(le32_to_cpu(ep_ctx->ep_info)); ++ pr_debug("%s: max_burst = %d, mult = %d\n", __func__, max_burst, mult); ++ ++ sch_ep->ep_type = ep_type; ++ sch_ep->max_packet_size = max_packet_size; ++ sch_ep->esit = 1 << ep_interval; ++ sch_ep->offset = 0; ++ sch_ep->burst_mode = 0; ++ ++ if (udev->speed == USB_SPEED_HIGH) { ++ sch_ep->cs_count = 0; ++ /* ++ * usb_20 spec section5.9 ++ * a single microframe is enough for HS synchromous endpoints ++ * in a interval ++ */ ++ sch_ep->num_budget_microframes = 1; ++ sch_ep->repeat = 0; ++ /* ++ * xHCI spec section6.2.3.4 ++ * @max_busrt is the number of additional transactions opportunities ++ * per microframe ++ */ ++ sch_ep->pkts = max_burst + 1; ++ sch_ep->bw_cost_per_microframe = max_packet_size * sch_ep->pkts; ++ } else if (udev->speed == USB_SPEED_SUPER) { ++ /* usb3_r1 spec section4.4.7 & 4.4.8 */ ++ sch_ep->cs_count = 0; ++ esit_pkts = (mult + 1) * (max_burst + 1); ++ if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) { ++ sch_ep->pkts = esit_pkts; ++ sch_ep->num_budget_microframes = 1; ++ sch_ep->repeat = 0; ++ } ++ ++ if (ep_type == ISOC_IN_EP || ep_type == ISOC_OUT_EP) { ++ if (esit_pkts <= sch_ep->esit) ++ sch_ep->pkts = 1; ++ else ++ sch_ep->pkts = roundup_pow_of_two(esit_pkts) ++ / sch_ep->esit; ++ ++ sch_ep->num_budget_microframes = ++ DIV_ROUND_UP(esit_pkts, sch_ep->pkts); ++ ++ if (sch_ep->num_budget_microframes > 1) ++ sch_ep->repeat = 1; ++ else ++ sch_ep->repeat = 0; ++ } ++ sch_ep->bw_cost_per_microframe = max_packet_size * sch_ep->pkts; ++ } else if (is_fs_or_ls(udev->speed)) { ++ /* ++ * usb_20 spec section11.18.4 ++ * assume worst cases ++ */ ++ sch_ep->repeat = 0; ++ sch_ep->pkts = 1; /* at most one packet for each microframe */ ++ if (ep_type == INT_IN_EP || ep_type == INT_OUT_EP) { ++ sch_ep->cs_count = 3; /* at most need 3 CS*/ ++ /* one for SS and one for budgeted transaction */ ++ sch_ep->num_budget_microframes = sch_ep->cs_count + 2; ++ sch_ep->bw_cost_per_microframe = max_packet_size; ++ } ++ if (ep_type == ISOC_OUT_EP) { ++ /* must never schedule a cs ISOC OUT ep */ ++ sch_ep->cs_count = 0; ++ /* ++ * the best case FS budget assumes that 188 FS bytes ++ * occur in each microframe ++ */ ++ sch_ep->num_budget_microframes = DIV_ROUND_UP( ++ sch_ep->max_packet_size, FS_PAYLOAD_MAX); ++ sch_ep->bw_cost_per_microframe = FS_PAYLOAD_MAX; ++ } ++ if (ep_type == ISOC_IN_EP) { ++ /* at most need additional two CS. */ ++ sch_ep->cs_count = DIV_ROUND_UP( ++ sch_ep->max_packet_size, FS_PAYLOAD_MAX) + 2; ++ sch_ep->num_budget_microframes = sch_ep->cs_count + 2; ++ sch_ep->bw_cost_per_microframe = FS_PAYLOAD_MAX; ++ } ++ } ++} ++ ++/* Get maximum bandwidth when we schedule at offset slot. */ ++static u32 get_max_bw(struct mu3h_sch_bw_info *sch_bw, ++ struct mu3h_sch_ep_info *sch_ep, u32 offset) ++{ ++ u32 num_esit; ++ u32 max_bw = 0; ++ int i; ++ int j; ++ ++ num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; ++ for (i = 0; i < num_esit; i++) { ++ u32 base = offset + i * sch_ep->esit; ++ ++ for (j = 0; j < sch_ep->num_budget_microframes; j++) { ++ if (sch_bw->bus_bw[base + j] > max_bw) ++ max_bw = sch_bw->bus_bw[base + j]; ++ } ++ } ++ return max_bw; ++} ++ ++static void update_bus_bw(struct mu3h_sch_bw_info *sch_bw, ++ struct mu3h_sch_ep_info *sch_ep, int bw_cost) ++{ ++ u32 num_esit; ++ u32 base; ++ int i; ++ int j; ++ ++ num_esit = XHCI_MTK_MAX_ESIT / sch_ep->esit; ++ for (i = 0; i < num_esit; i++) { ++ base = sch_ep->offset + i * sch_ep->esit; ++ for (j = 0; j < sch_ep->num_budget_microframes; j++) ++ sch_bw->bus_bw[base + j] += bw_cost; ++ } ++ ++} ++ ++static void debug_sch_ep(struct mu3h_sch_ep_info *sch_ep) ++{ ++ pr_debug("sch_ep->ep_type = %d\n", sch_ep->ep_type); ++ pr_debug("sch_ep->max_packet_size = %d\n", sch_ep->max_packet_size); ++ pr_debug("sch_ep->esit = %d\n", sch_ep->esit); ++ pr_debug("sch_ep->num_budget_microframes = %d\n", ++ sch_ep->num_budget_microframes); ++ pr_debug("sch_ep->bw_cost_per_microframe = %d\n", ++ sch_ep->bw_cost_per_microframe); ++ pr_debug("sch_ep->ep = %p\n", sch_ep->ep); ++ pr_debug("sch_ep->offset = %d\n", sch_ep->offset); ++ pr_debug("sch_ep->repeat = %d\n", sch_ep->repeat); ++ pr_debug("sch_ep->pkts = %d\n", sch_ep->pkts); ++ pr_debug("sch_ep->cs_count = %d\n", sch_ep->cs_count); ++} ++ ++static int check_sch_bw(struct usb_device *udev, ++ struct mu3h_sch_bw_info *sch_bw, struct mu3h_sch_ep_info *sch_ep) ++{ ++ u32 offset; ++ u32 esit; ++ u32 num_budget_microframes; ++ u32 min_bw; ++ u32 min_index; ++ u32 worst_bw; ++ u32 bw_boundary; ++ ++ if (sch_ep->esit > XHCI_MTK_MAX_ESIT) ++ sch_ep->esit = XHCI_MTK_MAX_ESIT; ++ ++ esit = sch_ep->esit; ++ num_budget_microframes = sch_ep->num_budget_microframes; ++ ++ /* ++ * Search through all possible schedule microframes. ++ * and find a microframe where its worst bandwidth is minimum. ++ */ ++ min_bw = ~0; ++ min_index = 0; ++ for (offset = 0; offset < esit; offset++) { ++ if ((offset + num_budget_microframes) > sch_ep->esit) ++ break; ++ /* ++ * usb_20 spec section11.18: ++ * must never schedule Start-Split in Y6 ++ */ ++ if (is_fs_or_ls(udev->speed) && (offset % 8 == 6)) ++ continue; ++ ++ worst_bw = get_max_bw(sch_bw, sch_ep, offset); ++ if (min_bw > worst_bw) { ++ min_bw = worst_bw; ++ min_index = offset; ++ } ++ if (min_bw == 0) ++ break; ++ } ++ sch_ep->offset = min_index; ++ ++ debug_sch_ep(sch_ep); ++ ++ bw_boundary = (udev->speed == USB_SPEED_SUPER) ++ ? SS_BW_BOUNDARY : HS_BW_BOUNDARY; ++ ++ /* check bandwidth */ ++ if (min_bw + sch_ep->bw_cost_per_microframe > bw_boundary) ++ return -1; ++ ++ /* update bus bandwidth info */ ++ update_bus_bw(sch_bw, sch_ep, sch_ep->bw_cost_per_microframe); ++ ++ return 0; ++} ++ ++static void debug_sch_bw(struct mu3h_sch_bw_info *sch_bw) ++{ ++ int i; ++ ++ pr_debug("xhci_mtk_scheduler :bus_bw_info\n"); ++ for (i = 0; i < XHCI_MTK_MAX_ESIT; i++) ++ pr_debug("%d ", sch_bw->bus_bw[i]); ++ ++ pr_debug("\n"); ++} ++ ++ ++static int need_bw_sch(struct usb_host_endpoint *ep, ++ enum usb_device_speed speed, int has_tt) ++{ ++ /* only for synchronous endpoints */ ++ if (usb_endpoint_xfer_control(&ep->desc) ++ || usb_endpoint_xfer_bulk(&ep->desc)) ++ return 0; ++ /* ++ * for LS & FS synchronous endpoints which its device don't attach ++ * to TT are also ignored, root-hub will schedule them directly ++ */ ++ if (is_fs_or_ls(speed) && !has_tt) ++ return 0; ++ ++ return 1; ++} ++ ++int xhci_mtk_init_quirk(struct xhci_hcd *xhci) ++{ ++ struct usb_hcd *hcd = xhci_to_hcd(xhci); ++ struct device *dev = hcd->self.controller; ++ struct mu3h_sch_bw_info *sch_array; ++ size_t array_size; ++ int num_usb_bus; ++ int i; ++ ++ /* ss IN and OUT are separated */ ++ num_usb_bus = xhci->num_usb3_ports * 2 + xhci->num_usb2_ports; ++ array_size = sizeof(*sch_array) * num_usb_bus; ++ ++ sch_array = kzalloc(array_size, GFP_KERNEL); ++ if (sch_array == NULL) ++ return -ENOMEM; ++ ++ for (i = 0; i < num_usb_bus; i++) ++ INIT_LIST_HEAD(&sch_array[i].bw_ep_list); ++ ++ dev->platform_data = sch_array; ++ xhci->quirks |= XHCI_MTK_HOST; ++ /* ++ * MTK host controller gives a spurious successful event after a ++ * short transfer. Ignore it. ++ */ ++ xhci->quirks |= XHCI_SPURIOUS_SUCCESS; ++ ++ return 0; ++} ++ ++ ++void xhci_mtk_exit_quirk(struct xhci_hcd *xhci) ++{ ++ struct usb_hcd *hcd = xhci_to_hcd(xhci); ++ struct mu3h_sch_bw_info *sch_array; ++ ++ sch_array = dev_get_platdata(hcd->self.controller); ++ kfree(sch_array); ++} ++ ++ ++int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, ++ struct usb_host_endpoint *ep) ++{ ++ int ret = 0; ++ int port_id; ++ int bw_index; ++ struct xhci_hcd *xhci; ++ unsigned int ep_index; ++ struct xhci_ep_ctx *ep_ctx; ++ struct xhci_slot_ctx *slot_ctx; ++ struct xhci_virt_device *virt_dev; ++ struct mu3h_sch_bw_info *sch_bw; ++ struct mu3h_sch_ep_info *sch_ep; ++ struct mu3h_sch_bw_info *sch_array; ++ ++ xhci = hcd_to_xhci(hcd); ++ virt_dev = xhci->devs[udev->slot_id]; ++ ep_index = xhci_get_endpoint_index(&ep->desc); ++ slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); ++ ep_ctx = xhci_get_ep_ctx(xhci, virt_dev->in_ctx, ep_index); ++ sch_array = dev_get_platdata(hcd->self.controller); ++ ++ port_id = virt_dev->real_port; ++ xhci_dbg(xhci, "%s() xfer_type: %d, speed:%d, ep:%p\n", __func__, ++ usb_endpoint_type(&ep->desc), udev->speed, ep); ++ ++ if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT)) ++ return 0; ++ ++ bw_index = get_bw_index(xhci, udev, ep); ++ sch_bw = &sch_array[bw_index]; ++ ++ sch_ep = kzalloc(sizeof(struct mu3h_sch_ep_info), GFP_KERNEL); ++ if (!sch_ep) ++ return -ENOMEM; ++ ++ setup_sch_info(udev, ep_ctx, sch_ep); ++ ++ ret = check_sch_bw(udev, sch_bw, sch_ep); ++ if (ret) { ++ xhci_err(xhci, "Not enough bandwidth!\n"); ++ kfree(sch_ep); ++ return -ENOSPC; ++ } ++ ++ list_add_tail(&sch_ep->endpoint, &sch_bw->bw_ep_list); ++ sch_ep->ep = ep; ++ ++ ep_ctx->reserved[0] |= cpu_to_le32(EP_BPKTS(sch_ep->pkts) ++ | EP_BCSCOUNT(sch_ep->cs_count) | EP_BBM(sch_ep->burst_mode)); ++ ep_ctx->reserved[1] |= cpu_to_le32(EP_BOFFSET(sch_ep->offset) ++ | EP_BREPEAT(sch_ep->repeat)); ++ ++ debug_sch_bw(sch_bw); ++ return 0; ++} ++ ++void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, ++ struct usb_host_endpoint *ep) ++{ ++ int bw_index; ++ struct xhci_hcd *xhci; ++ struct xhci_slot_ctx *slot_ctx; ++ struct xhci_virt_device *virt_dev; ++ struct mu3h_sch_bw_info *sch_array; ++ struct mu3h_sch_bw_info *sch_bw; ++ struct mu3h_sch_ep_info *sch_ep; ++ ++ xhci = hcd_to_xhci(hcd); ++ virt_dev = xhci->devs[udev->slot_id]; ++ slot_ctx = xhci_get_slot_ctx(xhci, virt_dev->in_ctx); ++ sch_array = dev_get_platdata(hcd->self.controller); ++ ++ xhci_dbg(xhci, "%s() xfer_type: %d, speed:%d, ep:%p\n", __func__, ++ usb_endpoint_type(&ep->desc), udev->speed, ep); ++ ++ if (!need_bw_sch(ep, udev->speed, slot_ctx->tt_info & TT_SLOT)) ++ return; ++ ++ bw_index = get_bw_index(xhci, udev, ep); ++ sch_bw = &sch_array[bw_index]; ++ ++ list_for_each_entry(sch_ep, &sch_bw->bw_ep_list, endpoint) { ++ if (sch_ep->ep == ep) { ++ update_bus_bw(sch_bw, sch_ep, ++ -sch_ep->bw_cost_per_microframe); ++ list_del(&sch_ep->endpoint); ++ kfree(sch_ep); ++ break; ++ } ++ } ++ debug_sch_bw(sch_bw); ++} ++ ++ ++/* ++ * The TD size is the number of bytes remaining in the TD (including this TRB), ++ * right shifted by 10. ++ * It must fit in bits 21:17, so it can't be bigger than 31. ++ */ ++u32 xhci_mtk_td_remainder_quirk(unsigned int td_running_total, ++ unsigned trb_buffer_length, struct urb *urb) ++{ ++ u32 max = 31; ++ int remainder, td_packet_count, packet_transferred; ++ unsigned int td_transfer_size = urb->transfer_buffer_length; ++ unsigned int maxp; ++ ++ maxp = GET_MAX_PACKET(usb_endpoint_maxp(&urb->ep->desc)); ++ ++ /* 0 for the last TRB */ ++ if (td_running_total + trb_buffer_length == td_transfer_size) ++ return 0; ++ ++ packet_transferred = td_running_total / maxp; ++ td_packet_count = DIV_ROUND_UP(td_transfer_size, maxp); ++ remainder = td_packet_count - packet_transferred; ++ ++ if (remainder > max) ++ return max << 17; ++ else ++ return remainder << 17; ++} ++ ++ +--- /dev/null ++++ b/drivers/usb/host/xhci-mtk.h +@@ -0,0 +1,119 @@ ++/* ++ * Copyright (c) 2015 MediaTek Inc. ++ * Author: ++ * Zhigang.Wun <zhigang.wei@mediatek.com> ++ * Chunfeng.Yun <chunfeng.yun@mediatek.com> ++ * ++ * This software is licensed under the terms of the GNU General Public ++ * License version 2, as published by the Free Software Foundation, and ++ * may be copied, distributed, and modified under those terms. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++ ++#ifndef _XHCI_MTK_H_ ++#define _XHCI_MTK_H_ ++ ++#include "xhci.h" ++ ++/** ++ * To simplify scheduler algorithm, set a upper limit for ESIT, ++ * if a synchromous ep's ESIT is larger than @XHCI_MTK_MAX_ESIT, ++ * round down to the limit value, that means allocating more ++ * bandwidth to it. ++ */ ++#define XHCI_MTK_MAX_ESIT 64 ++ ++/** ++ * struct mu3h_sch_bw_info ++ * @bus_bw: array to keep track of bandwidth already used at each uframes ++ * @bw_ep_list: eps in the bandwidth domain ++ * ++ * treat a HS root port as a bandwidth domain, but treat a SS root port as ++ * two bandwidth domains, one for IN eps and another for OUT eps. ++ */ ++struct mu3h_sch_bw_info { ++ u32 bus_bw[XHCI_MTK_MAX_ESIT]; ++ struct list_head bw_ep_list; ++}; ++ ++/** ++ * struct mu3h_sch_ep_info ++ * @esit: unit is 125us, equal to 2 << Interval field in ep-context ++ * @num_budget_microframes: number of continuous uframes ++ * (@repeat==1) scheduled within the interval ++ * @ep: address of usb_host_endpoint ++ * @offset: which uframe of the interval that transfer should be ++ * scheduled first time within the interval ++ * @repeat: the time gap between two uframes that transfers are ++ * scheduled within a interval. in the simple algorithm, only ++ * assign 0 or 1 to it; 0 means using only one uframe in a ++ * interval, and1 means using @num_budget_microframes ++ * continuous uframes ++ * @pkts: number of packets to be transferred in the scheduled uframes ++ * @cs_count: number of CS that host will trigger ++ */ ++struct mu3h_sch_ep_info { ++ u32 ep_type; ++ u32 max_packet_size; ++ u32 esit; ++ u32 num_budget_microframes; ++ u32 bw_cost_per_microframe; ++ void *ep; ++ struct list_head endpoint; ++ ++ /* mtk xhci scheduling info */ ++ u32 offset; ++ u32 repeat; ++ u32 pkts; ++ u32 cs_count; ++ u32 burst_mode; ++}; ++ ++ ++#if IS_ENABLED(CONFIG_USB_XHCI_MTK) ++ ++int xhci_mtk_init_quirk(struct xhci_hcd *xhci); ++void xhci_mtk_exit_quirk(struct xhci_hcd *xhci); ++int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, ++ struct usb_host_endpoint *ep); ++void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, struct usb_device *udev, ++ struct usb_host_endpoint *ep); ++u32 xhci_mtk_td_remainder_quirk(unsigned int td_running_total, ++ unsigned trb_buffer_length, struct urb *urb); ++ ++#else ++static inline int xhci_mtk_init_quirk(struct xhci_hcd *xhci) ++{ ++ return 0; ++} ++ ++static inline void xhci_mtk_exit_quirk(struct xhci_hcd *xhci) ++{ ++} ++ ++static inline int xhci_mtk_add_ep_quirk(struct usb_hcd *hcd, ++ struct usb_device *udev, struct usb_host_endpoint *ep) ++{ ++ return 0; ++} ++ ++static inline void xhci_mtk_drop_ep_quirk(struct usb_hcd *hcd, ++ struct usb_device *udev, struct usb_host_endpoint *ep) ++{ ++ return 0; ++} ++ ++static inline u32 xhci_mtk_td_remainder_quirk(unsigned int td_running_total, ++ unsigned trb_buffer_length, struct urb *urb) ++{ ++ return 0; ++} ++ ++#endif ++ ++#endif /* _XHCI_MTK_H_ */ +--- a/drivers/usb/host/xhci-plat.c ++++ b/drivers/usb/host/xhci-plat.c +@@ -23,6 +23,7 @@ + #include "xhci.h" + #include "xhci-mvebu.h" + #include "xhci-rcar.h" ++#include "xhci-mtk.h" + + static struct hc_driver __read_mostly xhci_plat_hc_driver; + +@@ -49,7 +50,23 @@ + return ret; + } + +- return xhci_gen_setup(hcd, xhci_plat_quirks); ++ ret = xhci_gen_setup(hcd, xhci_plat_quirks); ++ if (ret) ++ return ret; ++ ++ if (of_device_is_compatible(of_node, "mediatek,mt8173-xhci")) { ++ struct xhci_hcd *xhci = hcd_to_xhci(hcd); ++ ++ if (!usb_hcd_is_primary_hcd(hcd)) ++ return 0; ++ ret = xhci_mtk_init_quirk(xhci); ++ if (ret) { ++ kfree(xhci); ++ return ret; ++ } ++ } ++ ++ return ret; + } + + static int xhci_plat_start(struct usb_hcd *hcd) +@@ -207,6 +224,8 @@ + if (!IS_ERR(clk)) + clk_disable_unprepare(clk); + usb_put_hcd(hcd); ++ if (xhci->quirks & XHCI_MTK_HOST) ++ xhci_mtk_exit_quirk(xhci); + kfree(xhci); + + return 0; +@@ -253,6 +272,7 @@ + { .compatible = "marvell,armada-380-xhci"}, + { .compatible = "renesas,xhci-r8a7790"}, + { .compatible = "renesas,xhci-r8a7791"}, ++ { .compatible = "mediatek,mt8173-xhci"}, + { }, + }; + MODULE_DEVICE_TABLE(of, usb_xhci_of_match); +--- a/drivers/usb/host/xhci-ring.c ++++ b/drivers/usb/host/xhci-ring.c +@@ -68,6 +68,7 @@ + #include <linux/slab.h> + #include "xhci.h" + #include "xhci-trace.h" ++#include "xhci-mtk.h" + + /* + * Returns zero if the TRB isn't in this segment, otherwise it returns the DMA +@@ -3163,9 +3164,14 @@ + + /* Set the TRB length, TD size, and interrupter fields. */ + if (xhci->hci_version < 0x100) { +- remainder = xhci_td_remainder( ++ if (xhci->quirks & XHCI_MTK_HOST) { ++ remainder = xhci_mtk_td_remainder_quirk( ++ running_total, trb_buff_len, urb); ++ } else { ++ remainder = xhci_td_remainder( + urb->transfer_buffer_length - + running_total); ++ } + } else { + remainder = xhci_v1_0_td_remainder(running_total, + trb_buff_len, total_packet_count, urb, +@@ -3336,9 +3342,14 @@ + + /* Set the TRB length, TD size, and interrupter fields. */ + if (xhci->hci_version < 0x100) { +- remainder = xhci_td_remainder( ++ if (xhci->quirks & XHCI_MTK_HOST) { ++ remainder = xhci_mtk_td_remainder_quirk( ++ running_total, trb_buff_len, urb); ++ } else { ++ remainder = xhci_td_remainder( + urb->transfer_buffer_length - + running_total); ++ } + } else { + remainder = xhci_v1_0_td_remainder(running_total, + trb_buff_len, total_packet_count, urb, +@@ -3457,8 +3468,14 @@ + field = TRB_TYPE(TRB_DATA); + + length_field = TRB_LEN(urb->transfer_buffer_length) | +- xhci_td_remainder(urb->transfer_buffer_length) | + TRB_INTR_TARGET(0); ++ ++ if (xhci->quirks & XHCI_MTK_HOST) ++ length_field |= xhci_mtk_td_remainder_quirk(0, ++ urb->transfer_buffer_length, urb); ++ else ++ length_field |= xhci_td_remainder(urb->transfer_buffer_length); ++ + if (urb->transfer_buffer_length > 0) { + if (setup->bRequestType & USB_DIR_IN) + field |= TRB_DIR_IN; +@@ -3682,8 +3699,14 @@ + + /* Set the TRB length, TD size, & interrupter fields. */ + if (xhci->hci_version < 0x100) { +- remainder = xhci_td_remainder( +- td_len - running_total); ++ if (xhci->quirks & XHCI_MTK_HOST) { ++ remainder = xhci_mtk_td_remainder_quirk( ++ running_total, trb_buff_len, ++ urb); ++ } else { ++ remainder = xhci_td_remainder( ++ td_len - running_total); ++ } + } else { + remainder = xhci_v1_0_td_remainder( + running_total, trb_buff_len, +--- a/drivers/usb/host/xhci.c ++++ b/drivers/usb/host/xhci.c +@@ -31,6 +31,7 @@ + + #include "xhci.h" + #include "xhci-trace.h" ++#include "xhci-mtk.h" + + #define DRIVER_AUTHOR "Sarah Sharp" + #define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver" +@@ -624,7 +625,11 @@ + "// Set the interrupt modulation register"); + temp = readl(&xhci->ir_set->irq_control); + temp &= ~ER_IRQ_INTERVAL_MASK; +- temp |= (u32) 160; ++ /* ++ * the increment interval is 8 times as much as that defined ++ * in xHCI spec on MTK's controller ++ */ ++ temp |= (u32) ((xhci->quirks & XHCI_MTK_HOST) ? 20 : 160); + writel(temp, &xhci->ir_set->irq_control); + + /* Set the HCD state before we enable the irqs */ +@@ -1698,6 +1703,9 @@ + + xhci_endpoint_zero(xhci, xhci->devs[udev->slot_id], ep); + ++ if (xhci->quirks & XHCI_MTK_HOST) ++ xhci_mtk_drop_ep_quirk(hcd, udev, ep); ++ + xhci_dbg(xhci, "drop ep 0x%x, slot id %d, new drop flags = %#x, new add flags = %#x\n", + (unsigned int) ep->desc.bEndpointAddress, + udev->slot_id, +@@ -1793,6 +1801,12 @@ + return -ENOMEM; + } + ++ if (xhci->quirks & XHCI_MTK_HOST) { ++ ret = xhci_mtk_add_ep_quirk(hcd, udev, ep); ++ if (ret < 0) ++ return ret; ++ } ++ + ctrl_ctx->add_flags |= cpu_to_le32(added_ctxs); + new_add_flags = le32_to_cpu(ctrl_ctx->add_flags); + +--- a/drivers/usb/host/xhci.h ++++ b/drivers/usb/host/xhci.h +@@ -1568,6 +1568,7 @@ + /* For controllers with a broken beyond repair streams implementation */ + #define XHCI_BROKEN_STREAMS (1 << 19) + #define XHCI_PME_STUCK_QUIRK (1 << 20) ++#define XHCI_MTK_HOST (1 << 21) + unsigned int num_active_eps; + unsigned int limit_active_eps; + /* There are two roothubs to keep track of bus suspend info for */ diff --git a/target/linux/mediatek/patches/0048-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt6.patch b/target/linux/mediatek/patches/0048-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt6.patch new file mode 100644 index 0000000000..40303c0e92 --- /dev/null +++ b/target/linux/mediatek/patches/0048-dt-bindings-mediatek-Modify-pinctrl-bindings-for-mt6.patch @@ -0,0 +1,46 @@ +From 69b78182d6d7777153323abe3cff8e533ca01143 Mon Sep 17 00:00:00 2001 +From: Hongzhou Yang <hongzhou.yang@mediatek.com> +Date: Mon, 18 May 2015 23:11:12 -0700 +Subject: [PATCH 48/76] dt-bindings: mediatek: Modify pinctrl bindings for + mt6397. + +Since 6397 is no need to support interrupt controller, +moving interrupt controller relate property to optional list. +Also adding mt8173 and mt8127 to bindings. + +Signed-off-by: Hongzhou Yang <hongzhou.yang@mediatek.com> +--- + Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt +index 5868a0f..0480bc3 100644 +--- a/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt ++++ b/Documentation/devicetree/bindings/pinctrl/pinctrl-mt65xx.txt +@@ -3,9 +3,11 @@ + The Mediatek's Pin controller is used to control SoC pins. + + Required properties: +-- compatible: value should be either of the following. ++- compatible: value should be one of the following. + (a) "mediatek,mt8135-pinctrl", compatible with mt8135 pinctrl. +-- mediatek,pctl-regmap: Should be a phandle of the syscfg node. ++ (b) "mediatek,mt8173-pinctrl", compatible with mt8173 pinctrl. ++ (c) "mediatek,mt6397-pinctrl", compatible with mt6397 pinctrl. ++ (d) "mediatek,mt8127-pinctrl", compatible with mt8127 pinctrl. + - pins-are-numbered: Specify the subnodes are using numbered pinmux to + specify pins. + - gpio-controller : Marks the device node as a gpio controller. +@@ -24,6 +26,9 @@ Required properties: + Only the following flags are supported: + 0 - GPIO_ACTIVE_HIGH + 1 - GPIO_ACTIVE_LOW ++ ++Optional properties: ++- mediatek,pctl-regmap: Should be a phandle of the syscfg node. + - reg: physicall address base for EINT registers + - interrupt-controller: Marks the device node as an interrupt controller + - #interrupt-cells: Should be two. +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0049-pinctrl-dt-bindings-mt6397-Add-pinfunc-header-file-f.patch b/target/linux/mediatek/patches/0049-pinctrl-dt-bindings-mt6397-Add-pinfunc-header-file-f.patch new file mode 100644 index 0000000000..8178761677 --- /dev/null +++ b/target/linux/mediatek/patches/0049-pinctrl-dt-bindings-mt6397-Add-pinfunc-header-file-f.patch @@ -0,0 +1,279 @@ +From 54596fafa4ce2723314d0381c7c1a525bda148ef Mon Sep 17 00:00:00 2001 +From: Hongzhou Yang <hongzhou.yang@mediatek.com> +Date: Mon, 18 May 2015 23:11:13 -0700 +Subject: [PATCH 49/76] pinctrl: dt bindings: mt6397: Add pinfunc header file + for mt6397. + +Add pinfunc header file, mt8135/mt8173 relate dts will include it. + +Signed-off-by: Hongzhou Yang <hongzhou.yang@mediatek.com> +--- + include/dt-bindings/pinctrl/mt6397-pinfunc.h | 256 ++++++++++++++++++++++++++ + 1 file changed, 256 insertions(+) + create mode 100644 include/dt-bindings/pinctrl/mt6397-pinfunc.h + +diff --git a/include/dt-bindings/pinctrl/mt6397-pinfunc.h b/include/dt-bindings/pinctrl/mt6397-pinfunc.h +new file mode 100644 +index 0000000..85739b3 +--- /dev/null ++++ b/include/dt-bindings/pinctrl/mt6397-pinfunc.h +@@ -0,0 +1,256 @@ ++#ifndef __DTS_MT6397_PINFUNC_H ++#define __DTS_MT6397_PINFUNC_H ++ ++#include <dt-bindings/pinctrl/mt65xx.h> ++ ++#define MT6397_PIN_0_INT__FUNC_GPIO0 (MTK_PIN_NO(0) | 0) ++#define MT6397_PIN_0_INT__FUNC_INT (MTK_PIN_NO(0) | 1) ++ ++#define MT6397_PIN_1_SRCVOLTEN__FUNC_GPIO1 (MTK_PIN_NO(1) | 0) ++#define MT6397_PIN_1_SRCVOLTEN__FUNC_SRCVOLTEN (MTK_PIN_NO(1) | 1) ++#define MT6397_PIN_1_SRCVOLTEN__FUNC_TEST_CK1 (MTK_PIN_NO(1) | 6) ++ ++#define MT6397_PIN_2_SRCLKEN_PERI__FUNC_GPIO2 (MTK_PIN_NO(2) | 0) ++#define MT6397_PIN_2_SRCLKEN_PERI__FUNC_SRCLKEN_PERI (MTK_PIN_NO(2) | 1) ++#define MT6397_PIN_2_SRCLKEN_PERI__FUNC_TEST_CK2 (MTK_PIN_NO(2) | 6) ++ ++#define MT6397_PIN_3_RTC_32K1V8__FUNC_GPIO3 (MTK_PIN_NO(3) | 0) ++#define MT6397_PIN_3_RTC_32K1V8__FUNC_RTC_32K1V8 (MTK_PIN_NO(3) | 1) ++#define MT6397_PIN_3_RTC_32K1V8__FUNC_TEST_CK3 (MTK_PIN_NO(3) | 6) ++ ++#define MT6397_PIN_4_WRAP_EVENT__FUNC_GPIO4 (MTK_PIN_NO(4) | 0) ++#define MT6397_PIN_4_WRAP_EVENT__FUNC_WRAP_EVENT (MTK_PIN_NO(4) | 1) ++ ++#define MT6397_PIN_5_SPI_CLK__FUNC_GPIO5 (MTK_PIN_NO(5) | 0) ++#define MT6397_PIN_5_SPI_CLK__FUNC_SPI_CLK (MTK_PIN_NO(5) | 1) ++ ++#define MT6397_PIN_6_SPI_CSN__FUNC_GPIO6 (MTK_PIN_NO(6) | 0) ++#define MT6397_PIN_6_SPI_CSN__FUNC_SPI_CSN (MTK_PIN_NO(6) | 1) ++ ++#define MT6397_PIN_7_SPI_MOSI__FUNC_GPIO7 (MTK_PIN_NO(7) | 0) ++#define MT6397_PIN_7_SPI_MOSI__FUNC_SPI_MOSI (MTK_PIN_NO(7) | 1) ++ ++#define MT6397_PIN_8_SPI_MISO__FUNC_GPIO8 (MTK_PIN_NO(8) | 0) ++#define MT6397_PIN_8_SPI_MISO__FUNC_SPI_MISO (MTK_PIN_NO(8) | 1) ++ ++#define MT6397_PIN_9_AUD_CLK_MOSI__FUNC_GPIO9 (MTK_PIN_NO(9) | 0) ++#define MT6397_PIN_9_AUD_CLK_MOSI__FUNC_AUD_CLK (MTK_PIN_NO(9) | 1) ++#define MT6397_PIN_9_AUD_CLK_MOSI__FUNC_TEST_IN0 (MTK_PIN_NO(9) | 6) ++#define MT6397_PIN_9_AUD_CLK_MOSI__FUNC_TEST_OUT0 (MTK_PIN_NO(9) | 7) ++ ++#define MT6397_PIN_10_AUD_DAT_MISO__FUNC_GPIO10 (MTK_PIN_NO(10) | 0) ++#define MT6397_PIN_10_AUD_DAT_MISO__FUNC_AUD_MISO (MTK_PIN_NO(10) | 1) ++#define MT6397_PIN_10_AUD_DAT_MISO__FUNC_TEST_IN1 (MTK_PIN_NO(10) | 6) ++#define MT6397_PIN_10_AUD_DAT_MISO__FUNC_TEST_OUT1 (MTK_PIN_NO(10) | 7) ++ ++#define MT6397_PIN_11_AUD_DAT_MOSI__FUNC_GPIO11 (MTK_PIN_NO(11) | 0) ++#define MT6397_PIN_11_AUD_DAT_MOSI__FUNC_AUD_MOSI (MTK_PIN_NO(11) | 1) ++#define MT6397_PIN_11_AUD_DAT_MOSI__FUNC_TEST_IN2 (MTK_PIN_NO(11) | 6) ++#define MT6397_PIN_11_AUD_DAT_MOSI__FUNC_TEST_OUT2 (MTK_PIN_NO(11) | 7) ++ ++#define MT6397_PIN_12_COL0__FUNC_GPIO12 (MTK_PIN_NO(12) | 0) ++#define MT6397_PIN_12_COL0__FUNC_COL0_USBDL (MTK_PIN_NO(12) | 1) ++#define MT6397_PIN_12_COL0__FUNC_EINT10_1X (MTK_PIN_NO(12) | 2) ++#define MT6397_PIN_12_COL0__FUNC_PWM1_3X (MTK_PIN_NO(12) | 3) ++#define MT6397_PIN_12_COL0__FUNC_TEST_IN3 (MTK_PIN_NO(12) | 6) ++#define MT6397_PIN_12_COL0__FUNC_TEST_OUT3 (MTK_PIN_NO(12) | 7) ++ ++#define MT6397_PIN_13_COL1__FUNC_GPIO13 (MTK_PIN_NO(13) | 0) ++#define MT6397_PIN_13_COL1__FUNC_COL1 (MTK_PIN_NO(13) | 1) ++#define MT6397_PIN_13_COL1__FUNC_EINT11_1X (MTK_PIN_NO(13) | 2) ++#define MT6397_PIN_13_COL1__FUNC_SCL0_2X (MTK_PIN_NO(13) | 3) ++#define MT6397_PIN_13_COL1__FUNC_TEST_IN4 (MTK_PIN_NO(13) | 6) ++#define MT6397_PIN_13_COL1__FUNC_TEST_OUT4 (MTK_PIN_NO(13) | 7) ++ ++#define MT6397_PIN_14_COL2__FUNC_GPIO14 (MTK_PIN_NO(14) | 0) ++#define MT6397_PIN_14_COL2__FUNC_COL2 (MTK_PIN_NO(14) | 1) ++#define MT6397_PIN_14_COL2__FUNC_EINT12_1X (MTK_PIN_NO(14) | 2) ++#define MT6397_PIN_14_COL2__FUNC_SDA0_2X (MTK_PIN_NO(14) | 3) ++#define MT6397_PIN_14_COL2__FUNC_TEST_IN5 (MTK_PIN_NO(14) | 6) ++#define MT6397_PIN_14_COL2__FUNC_TEST_OUT5 (MTK_PIN_NO(14) | 7) ++ ++#define MT6397_PIN_15_COL3__FUNC_GPIO15 (MTK_PIN_NO(15) | 0) ++#define MT6397_PIN_15_COL3__FUNC_COL3 (MTK_PIN_NO(15) | 1) ++#define MT6397_PIN_15_COL3__FUNC_EINT13_1X (MTK_PIN_NO(15) | 2) ++#define MT6397_PIN_15_COL3__FUNC_SCL1_2X (MTK_PIN_NO(15) | 3) ++#define MT6397_PIN_15_COL3__FUNC_TEST_IN6 (MTK_PIN_NO(15) | 6) ++#define MT6397_PIN_15_COL3__FUNC_TEST_OUT6 (MTK_PIN_NO(15) | 7) ++ ++#define MT6397_PIN_16_COL4__FUNC_GPIO16 (MTK_PIN_NO(16) | 0) ++#define MT6397_PIN_16_COL4__FUNC_COL4 (MTK_PIN_NO(16) | 1) ++#define MT6397_PIN_16_COL4__FUNC_EINT14_1X (MTK_PIN_NO(16) | 2) ++#define MT6397_PIN_16_COL4__FUNC_SDA1_2X (MTK_PIN_NO(16) | 3) ++#define MT6397_PIN_16_COL4__FUNC_TEST_IN7 (MTK_PIN_NO(16) | 6) ++#define MT6397_PIN_16_COL4__FUNC_TEST_OUT7 (MTK_PIN_NO(16) | 7) ++ ++#define MT6397_PIN_17_COL5__FUNC_GPIO17 (MTK_PIN_NO(17) | 0) ++#define MT6397_PIN_17_COL5__FUNC_COL5 (MTK_PIN_NO(17) | 1) ++#define MT6397_PIN_17_COL5__FUNC_EINT15_1X (MTK_PIN_NO(17) | 2) ++#define MT6397_PIN_17_COL5__FUNC_SCL2_2X (MTK_PIN_NO(17) | 3) ++#define MT6397_PIN_17_COL5__FUNC_TEST_IN8 (MTK_PIN_NO(17) | 6) ++#define MT6397_PIN_17_COL5__FUNC_TEST_OUT8 (MTK_PIN_NO(17) | 7) ++ ++#define MT6397_PIN_18_COL6__FUNC_GPIO18 (MTK_PIN_NO(18) | 0) ++#define MT6397_PIN_18_COL6__FUNC_COL6 (MTK_PIN_NO(18) | 1) ++#define MT6397_PIN_18_COL6__FUNC_EINT16_1X (MTK_PIN_NO(18) | 2) ++#define MT6397_PIN_18_COL6__FUNC_SDA2_2X (MTK_PIN_NO(18) | 3) ++#define MT6397_PIN_18_COL6__FUNC_GPIO32K_0 (MTK_PIN_NO(18) | 4) ++#define MT6397_PIN_18_COL6__FUNC_GPIO26M_0 (MTK_PIN_NO(18) | 5) ++#define MT6397_PIN_18_COL6__FUNC_TEST_IN9 (MTK_PIN_NO(18) | 6) ++#define MT6397_PIN_18_COL6__FUNC_TEST_OUT9 (MTK_PIN_NO(18) | 7) ++ ++#define MT6397_PIN_19_COL7__FUNC_GPIO19 (MTK_PIN_NO(19) | 0) ++#define MT6397_PIN_19_COL7__FUNC_COL7 (MTK_PIN_NO(19) | 1) ++#define MT6397_PIN_19_COL7__FUNC_EINT17_1X (MTK_PIN_NO(19) | 2) ++#define MT6397_PIN_19_COL7__FUNC_PWM2_3X (MTK_PIN_NO(19) | 3) ++#define MT6397_PIN_19_COL7__FUNC_GPIO32K_1 (MTK_PIN_NO(19) | 4) ++#define MT6397_PIN_19_COL7__FUNC_GPIO26M_1 (MTK_PIN_NO(19) | 5) ++#define MT6397_PIN_19_COL7__FUNC_TEST_IN10 (MTK_PIN_NO(19) | 6) ++#define MT6397_PIN_19_COL7__FUNC_TEST_OUT10 (MTK_PIN_NO(19) | 7) ++ ++#define MT6397_PIN_20_ROW0__FUNC_GPIO20 (MTK_PIN_NO(20) | 0) ++#define MT6397_PIN_20_ROW0__FUNC_ROW0 (MTK_PIN_NO(20) | 1) ++#define MT6397_PIN_20_ROW0__FUNC_EINT18_1X (MTK_PIN_NO(20) | 2) ++#define MT6397_PIN_20_ROW0__FUNC_SCL0_3X (MTK_PIN_NO(20) | 3) ++#define MT6397_PIN_20_ROW0__FUNC_TEST_IN11 (MTK_PIN_NO(20) | 6) ++#define MT6397_PIN_20_ROW0__FUNC_TEST_OUT11 (MTK_PIN_NO(20) | 7) ++ ++#define MT6397_PIN_21_ROW1__FUNC_GPIO21 (MTK_PIN_NO(21) | 0) ++#define MT6397_PIN_21_ROW1__FUNC_ROW1 (MTK_PIN_NO(21) | 1) ++#define MT6397_PIN_21_ROW1__FUNC_EINT19_1X (MTK_PIN_NO(21) | 2) ++#define MT6397_PIN_21_ROW1__FUNC_SDA0_3X (MTK_PIN_NO(21) | 3) ++#define MT6397_PIN_21_ROW1__FUNC_AUD_TSTCK (MTK_PIN_NO(21) | 4) ++#define MT6397_PIN_21_ROW1__FUNC_TEST_IN12 (MTK_PIN_NO(21) | 6) ++#define MT6397_PIN_21_ROW1__FUNC_TEST_OUT12 (MTK_PIN_NO(21) | 7) ++ ++#define MT6397_PIN_22_ROW2__FUNC_GPIO22 (MTK_PIN_NO(22) | 0) ++#define MT6397_PIN_22_ROW2__FUNC_ROW2 (MTK_PIN_NO(22) | 1) ++#define MT6397_PIN_22_ROW2__FUNC_EINT20_1X (MTK_PIN_NO(22) | 2) ++#define MT6397_PIN_22_ROW2__FUNC_SCL1_3X (MTK_PIN_NO(22) | 3) ++#define MT6397_PIN_22_ROW2__FUNC_TEST_IN13 (MTK_PIN_NO(22) | 6) ++#define MT6397_PIN_22_ROW2__FUNC_TEST_OUT13 (MTK_PIN_NO(22) | 7) ++ ++#define MT6397_PIN_23_ROW3__FUNC_GPIO23 (MTK_PIN_NO(23) | 0) ++#define MT6397_PIN_23_ROW3__FUNC_ROW3 (MTK_PIN_NO(23) | 1) ++#define MT6397_PIN_23_ROW3__FUNC_EINT21_1X (MTK_PIN_NO(23) | 2) ++#define MT6397_PIN_23_ROW3__FUNC_SDA1_3X (MTK_PIN_NO(23) | 3) ++#define MT6397_PIN_23_ROW3__FUNC_TEST_IN14 (MTK_PIN_NO(23) | 6) ++#define MT6397_PIN_23_ROW3__FUNC_TEST_OUT14 (MTK_PIN_NO(23) | 7) ++ ++#define MT6397_PIN_24_ROW4__FUNC_GPIO24 (MTK_PIN_NO(24) | 0) ++#define MT6397_PIN_24_ROW4__FUNC_ROW4 (MTK_PIN_NO(24) | 1) ++#define MT6397_PIN_24_ROW4__FUNC_EINT22_1X (MTK_PIN_NO(24) | 2) ++#define MT6397_PIN_24_ROW4__FUNC_SCL2_3X (MTK_PIN_NO(24) | 3) ++#define MT6397_PIN_24_ROW4__FUNC_TEST_IN15 (MTK_PIN_NO(24) | 6) ++#define MT6397_PIN_24_ROW4__FUNC_TEST_OUT15 (MTK_PIN_NO(24) | 7) ++ ++#define MT6397_PIN_25_ROW5__FUNC_GPIO25 (MTK_PIN_NO(25) | 0) ++#define MT6397_PIN_25_ROW5__FUNC_ROW5 (MTK_PIN_NO(25) | 1) ++#define MT6397_PIN_25_ROW5__FUNC_EINT23_1X (MTK_PIN_NO(25) | 2) ++#define MT6397_PIN_25_ROW5__FUNC_SDA2_3X (MTK_PIN_NO(25) | 3) ++#define MT6397_PIN_25_ROW5__FUNC_TEST_IN16 (MTK_PIN_NO(25) | 6) ++#define MT6397_PIN_25_ROW5__FUNC_TEST_OUT16 (MTK_PIN_NO(25) | 7) ++ ++#define MT6397_PIN_26_ROW6__FUNC_GPIO26 (MTK_PIN_NO(26) | 0) ++#define MT6397_PIN_26_ROW6__FUNC_ROW6 (MTK_PIN_NO(26) | 1) ++#define MT6397_PIN_26_ROW6__FUNC_EINT24_1X (MTK_PIN_NO(26) | 2) ++#define MT6397_PIN_26_ROW6__FUNC_PWM3_3X (MTK_PIN_NO(26) | 3) ++#define MT6397_PIN_26_ROW6__FUNC_GPIO32K_2 (MTK_PIN_NO(26) | 4) ++#define MT6397_PIN_26_ROW6__FUNC_GPIO26M_2 (MTK_PIN_NO(26) | 5) ++#define MT6397_PIN_26_ROW6__FUNC_TEST_IN17 (MTK_PIN_NO(26) | 6) ++#define MT6397_PIN_26_ROW6__FUNC_TEST_OUT17 (MTK_PIN_NO(26) | 7) ++ ++#define MT6397_PIN_27_ROW7__FUNC_GPIO27 (MTK_PIN_NO(27) | 0) ++#define MT6397_PIN_27_ROW7__FUNC_ROW7 (MTK_PIN_NO(27) | 1) ++#define MT6397_PIN_27_ROW7__FUNC_EINT3_1X (MTK_PIN_NO(27) | 2) ++#define MT6397_PIN_27_ROW7__FUNC_CBUS (MTK_PIN_NO(27) | 3) ++#define MT6397_PIN_27_ROW7__FUNC_GPIO32K_3 (MTK_PIN_NO(27) | 4) ++#define MT6397_PIN_27_ROW7__FUNC_GPIO26M_3 (MTK_PIN_NO(27) | 5) ++#define MT6397_PIN_27_ROW7__FUNC_TEST_IN18 (MTK_PIN_NO(27) | 6) ++#define MT6397_PIN_27_ROW7__FUNC_TEST_OUT18 (MTK_PIN_NO(27) | 7) ++ ++#define MT6397_PIN_28_PWM1__FUNC_GPIO28 (MTK_PIN_NO(28) | 0) ++#define MT6397_PIN_28_PWM1__FUNC_PWM1 (MTK_PIN_NO(28) | 1) ++#define MT6397_PIN_28_PWM1__FUNC_EINT4_1X (MTK_PIN_NO(28) | 2) ++#define MT6397_PIN_28_PWM1__FUNC_GPIO32K_4 (MTK_PIN_NO(28) | 4) ++#define MT6397_PIN_28_PWM1__FUNC_GPIO26M_4 (MTK_PIN_NO(28) | 5) ++#define MT6397_PIN_28_PWM1__FUNC_TEST_IN19 (MTK_PIN_NO(28) | 6) ++#define MT6397_PIN_28_PWM1__FUNC_TEST_OUT19 (MTK_PIN_NO(28) | 7) ++ ++#define MT6397_PIN_29_PWM2__FUNC_GPIO29 (MTK_PIN_NO(29) | 0) ++#define MT6397_PIN_29_PWM2__FUNC_PWM2 (MTK_PIN_NO(29) | 1) ++#define MT6397_PIN_29_PWM2__FUNC_EINT5_1X (MTK_PIN_NO(29) | 2) ++#define MT6397_PIN_29_PWM2__FUNC_GPIO32K_5 (MTK_PIN_NO(29) | 4) ++#define MT6397_PIN_29_PWM2__FUNC_GPIO26M_5 (MTK_PIN_NO(29) | 5) ++#define MT6397_PIN_29_PWM2__FUNC_TEST_IN20 (MTK_PIN_NO(29) | 6) ++#define MT6397_PIN_29_PWM2__FUNC_TEST_OUT20 (MTK_PIN_NO(29) | 7) ++ ++#define MT6397_PIN_30_PWM3__FUNC_GPIO30 (MTK_PIN_NO(30) | 0) ++#define MT6397_PIN_30_PWM3__FUNC_PWM3 (MTK_PIN_NO(30) | 1) ++#define MT6397_PIN_30_PWM3__FUNC_EINT6_1X (MTK_PIN_NO(30) | 2) ++#define MT6397_PIN_30_PWM3__FUNC_COL0 (MTK_PIN_NO(30) | 3) ++#define MT6397_PIN_30_PWM3__FUNC_GPIO32K_6 (MTK_PIN_NO(30) | 4) ++#define MT6397_PIN_30_PWM3__FUNC_GPIO26M_6 (MTK_PIN_NO(30) | 5) ++#define MT6397_PIN_30_PWM3__FUNC_TEST_IN21 (MTK_PIN_NO(30) | 6) ++#define MT6397_PIN_30_PWM3__FUNC_TEST_OUT21 (MTK_PIN_NO(30) | 7) ++ ++#define MT6397_PIN_31_SCL0__FUNC_GPIO31 (MTK_PIN_NO(31) | 0) ++#define MT6397_PIN_31_SCL0__FUNC_SCL0 (MTK_PIN_NO(31) | 1) ++#define MT6397_PIN_31_SCL0__FUNC_EINT7_1X (MTK_PIN_NO(31) | 2) ++#define MT6397_PIN_31_SCL0__FUNC_PWM1_2X (MTK_PIN_NO(31) | 3) ++#define MT6397_PIN_31_SCL0__FUNC_TEST_IN22 (MTK_PIN_NO(31) | 6) ++#define MT6397_PIN_31_SCL0__FUNC_TEST_OUT22 (MTK_PIN_NO(31) | 7) ++ ++#define MT6397_PIN_32_SDA0__FUNC_GPIO32 (MTK_PIN_NO(32) | 0) ++#define MT6397_PIN_32_SDA0__FUNC_SDA0 (MTK_PIN_NO(32) | 1) ++#define MT6397_PIN_32_SDA0__FUNC_EINT8_1X (MTK_PIN_NO(32) | 2) ++#define MT6397_PIN_32_SDA0__FUNC_TEST_IN23 (MTK_PIN_NO(32) | 6) ++#define MT6397_PIN_32_SDA0__FUNC_TEST_OUT23 (MTK_PIN_NO(32) | 7) ++ ++#define MT6397_PIN_33_SCL1__FUNC_GPIO33 (MTK_PIN_NO(33) | 0) ++#define MT6397_PIN_33_SCL1__FUNC_SCL1 (MTK_PIN_NO(33) | 1) ++#define MT6397_PIN_33_SCL1__FUNC_EINT9_1X (MTK_PIN_NO(33) | 2) ++#define MT6397_PIN_33_SCL1__FUNC_PWM2_2X (MTK_PIN_NO(33) | 3) ++#define MT6397_PIN_33_SCL1__FUNC_TEST_IN24 (MTK_PIN_NO(33) | 6) ++#define MT6397_PIN_33_SCL1__FUNC_TEST_OUT24 (MTK_PIN_NO(33) | 7) ++ ++#define MT6397_PIN_34_SDA1__FUNC_GPIO34 (MTK_PIN_NO(34) | 0) ++#define MT6397_PIN_34_SDA1__FUNC_SDA1 (MTK_PIN_NO(34) | 1) ++#define MT6397_PIN_34_SDA1__FUNC_EINT0_1X (MTK_PIN_NO(34) | 2) ++#define MT6397_PIN_34_SDA1__FUNC_TEST_IN25 (MTK_PIN_NO(34) | 6) ++#define MT6397_PIN_34_SDA1__FUNC_TEST_OUT25 (MTK_PIN_NO(34) | 7) ++ ++#define MT6397_PIN_35_SCL2__FUNC_GPIO35 (MTK_PIN_NO(35) | 0) ++#define MT6397_PIN_35_SCL2__FUNC_SCL2 (MTK_PIN_NO(35) | 1) ++#define MT6397_PIN_35_SCL2__FUNC_EINT1_1X (MTK_PIN_NO(35) | 2) ++#define MT6397_PIN_35_SCL2__FUNC_PWM3_2X (MTK_PIN_NO(35) | 3) ++#define MT6397_PIN_35_SCL2__FUNC_TEST_IN26 (MTK_PIN_NO(35) | 6) ++#define MT6397_PIN_35_SCL2__FUNC_TEST_OUT26 (MTK_PIN_NO(35) | 7) ++ ++#define MT6397_PIN_36_SDA2__FUNC_GPIO36 (MTK_PIN_NO(36) | 0) ++#define MT6397_PIN_36_SDA2__FUNC_SDA2 (MTK_PIN_NO(36) | 1) ++#define MT6397_PIN_36_SDA2__FUNC_EINT2_1X (MTK_PIN_NO(36) | 2) ++#define MT6397_PIN_36_SDA2__FUNC_TEST_IN27 (MTK_PIN_NO(36) | 6) ++#define MT6397_PIN_36_SDA2__FUNC_TEST_OUT27 (MTK_PIN_NO(36) | 7) ++ ++#define MT6397_PIN_37_HDMISD__FUNC_GPIO37 (MTK_PIN_NO(37) | 0) ++#define MT6397_PIN_37_HDMISD__FUNC_HDMISD (MTK_PIN_NO(37) | 1) ++#define MT6397_PIN_37_HDMISD__FUNC_TEST_IN28 (MTK_PIN_NO(37) | 6) ++#define MT6397_PIN_37_HDMISD__FUNC_TEST_OUT28 (MTK_PIN_NO(37) | 7) ++ ++#define MT6397_PIN_38_HDMISCK__FUNC_GPIO38 (MTK_PIN_NO(38) | 0) ++#define MT6397_PIN_38_HDMISCK__FUNC_HDMISCK (MTK_PIN_NO(38) | 1) ++#define MT6397_PIN_38_HDMISCK__FUNC_TEST_IN29 (MTK_PIN_NO(38) | 6) ++#define MT6397_PIN_38_HDMISCK__FUNC_TEST_OUT29 (MTK_PIN_NO(38) | 7) ++ ++#define MT6397_PIN_39_HTPLG__FUNC_GPIO39 (MTK_PIN_NO(39) | 0) ++#define MT6397_PIN_39_HTPLG__FUNC_HTPLG (MTK_PIN_NO(39) | 1) ++#define MT6397_PIN_39_HTPLG__FUNC_TEST_IN30 (MTK_PIN_NO(39) | 6) ++#define MT6397_PIN_39_HTPLG__FUNC_TEST_OUT30 (MTK_PIN_NO(39) | 7) ++ ++#define MT6397_PIN_40_CEC__FUNC_GPIO40 (MTK_PIN_NO(40) | 0) ++#define MT6397_PIN_40_CEC__FUNC_CEC (MTK_PIN_NO(40) | 1) ++#define MT6397_PIN_40_CEC__FUNC_TEST_IN31 (MTK_PIN_NO(40) | 6) ++#define MT6397_PIN_40_CEC__FUNC_TEST_OUT31 (MTK_PIN_NO(40) | 7) ++ ++#endif /* __DTS_MT6397_PINFUNC_H */ +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0050-pinctrl-mediatek-data-struct-optimize-and-remove-unu.patch b/target/linux/mediatek/patches/0050-pinctrl-mediatek-data-struct-optimize-and-remove-unu.patch new file mode 100644 index 0000000000..7399746783 --- /dev/null +++ b/target/linux/mediatek/patches/0050-pinctrl-mediatek-data-struct-optimize-and-remove-unu.patch @@ -0,0 +1,116 @@ +From 3eeb897a627e26083472f14e7512f53276a5e7ce Mon Sep 17 00:00:00 2001 +From: Yingjoe Chen <yingjoe.chen@mediatek.com> +Date: Mon, 18 May 2015 23:11:14 -0700 +Subject: [PATCH 50/76] pinctrl: mediatek: data struct optimize and remove + unused member + +struct mtk_desc_pin.chip, mtk_pinctrl_devdata.invser_offset +and mtk_pinctrl_devdata.chip_type are never used in code. +Remove them. + +Some per-pin data are using int for pin number and offsets. +Change to short and rearrange to reduce const data size. + +Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com> +Signed-off-by: Hongzhou Yang <hongzhou.yang@mediatek.com> +--- + drivers/pinctrl/mediatek/pinctrl-mt8135.c | 10 ++++------ + drivers/pinctrl/mediatek/pinctrl-mtk-common.h | 10 ++-------- + 2 files changed, 6 insertions(+), 14 deletions(-) + +diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8135.c b/drivers/pinctrl/mediatek/pinctrl-mt8135.c +index f1e1e18..8e6abd5 100644 +--- a/drivers/pinctrl/mediatek/pinctrl-mt8135.c ++++ b/drivers/pinctrl/mediatek/pinctrl-mt8135.c +@@ -32,12 +32,12 @@ + #define R1_BASE2 0x250 + + struct mtk_spec_pull_set { +- unsigned int pin; +- unsigned int pupd_offset; ++ unsigned char pin; + unsigned char pupd_bit; +- unsigned int r0_offset; ++ unsigned short pupd_offset; ++ unsigned short r0_offset; ++ unsigned short r1_offset; + unsigned char r0_bit; +- unsigned int r1_offset; + unsigned char r1_bit; + }; + +@@ -305,7 +305,6 @@ static const struct mtk_pinctrl_devdata mt8135_pinctrl_data = { + .pullen_offset = 0x0200, + .smt_offset = 0x0300, + .pullsel_offset = 0x0400, +- .invser_offset = 0x0600, + .dout_offset = 0x0800, + .din_offset = 0x0A00, + .pinmux_offset = 0x0C00, +@@ -314,7 +313,6 @@ static const struct mtk_pinctrl_devdata mt8135_pinctrl_data = { + .port_shf = 4, + .port_mask = 0xf, + .port_align = 4, +- .chip_type = MTK_CHIP_TYPE_BASE, + .eint_offsets = { + .name = "mt8135_eint", + .stat = 0x000, +diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h +index 375771d..1508849 100644 +--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h ++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h +@@ -19,8 +19,6 @@ + #include <linux/regmap.h> + + #define NO_EINT_SUPPORT 255 +-#define MTK_CHIP_TYPE_BASE 0 +-#define MTK_CHIP_TYPE_PMIC 1 + #define MT_EDGE_SENSITIVE 0 + #define MT_LEVEL_SENSITIVE 1 + #define EINT_DBNC_SET_DBNC_BITS 4 +@@ -39,7 +37,6 @@ struct mtk_desc_eint { + + struct mtk_desc_pin { + struct pinctrl_pin_desc pin; +- const char *chip; + const struct mtk_desc_eint eint; + const struct mtk_desc_function *functions; + }; +@@ -47,7 +44,6 @@ struct mtk_desc_pin { + #define MTK_PIN(_pin, _pad, _chip, _eint, ...) \ + { \ + .pin = _pin, \ +- .chip = _chip, \ + .eint = _eint, \ + .functions = (struct mtk_desc_function[]){ \ + __VA_ARGS__, { } }, \ +@@ -107,8 +103,8 @@ struct mtk_drv_group_desc { + * @grp: The group for this pin belongs to. + */ + struct mtk_pin_drv_grp { +- unsigned int pin; +- unsigned int offset; ++ unsigned short pin; ++ unsigned short offset; + unsigned char bit; + unsigned char grp; + }; +@@ -193,7 +189,6 @@ struct mtk_pinctrl_devdata { + unsigned int pullen_offset; + unsigned int pullsel_offset; + unsigned int drv_offset; +- unsigned int invser_offset; + unsigned int dout_offset; + unsigned int din_offset; + unsigned int pinmux_offset; +@@ -202,7 +197,6 @@ struct mtk_pinctrl_devdata { + unsigned char port_shf; + unsigned char port_mask; + unsigned char port_align; +- unsigned char chip_type; + struct mtk_eint_offsets eint_offsets; + unsigned int ap_num; + unsigned int db_cnt; +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0051-pinctrl-mediatek-add-mtk_pctrl_spec_pull_set_samereg.patch b/target/linux/mediatek/patches/0051-pinctrl-mediatek-add-mtk_pctrl_spec_pull_set_samereg.patch new file mode 100644 index 0000000000..2e9eb60b5b --- /dev/null +++ b/target/linux/mediatek/patches/0051-pinctrl-mediatek-add-mtk_pctrl_spec_pull_set_samereg.patch @@ -0,0 +1,328 @@ +From aefbeb75a32e080445d72ddd4b9ab28c258597d0 Mon Sep 17 00:00:00 2001 +From: Yingjoe Chen <yingjoe.chen@mediatek.com> +Date: Mon, 18 May 2015 23:11:15 -0700 +Subject: [PATCH 51/76] pinctrl: mediatek: add mtk_pctrl_spec_pull_set_samereg + common code + +Several mediatek soc use similar pull setting procedure as mt8173, +the pupd enable and resistance setting are in the same register. +Add common code mtk_pctrl_spec_pull_set_samereg out of spec_pull_set +in mt8173 to handle this case, so future soc driver can use it. + +Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com> +Signed-off-by: Hongzhou Yang <hongzhou.yang@mediatek.com> +--- + drivers/pinctrl/mediatek/pinctrl-mt8173.c | 166 +++++++------------------ + drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 60 +++++++++ + drivers/pinctrl/mediatek/pinctrl-mtk-common.h | 31 +++++ + 3 files changed, 136 insertions(+), 121 deletions(-) + +diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8173.c b/drivers/pinctrl/mediatek/pinctrl-mt8173.c +index 412ea84..cc44b27 100644 +--- a/drivers/pinctrl/mediatek/pinctrl-mt8173.c ++++ b/drivers/pinctrl/mediatek/pinctrl-mt8173.c +@@ -47,130 +47,54 @@ struct mtk_pin_ies_smt_set { + .offset = _offset, \ + } + +-/** +- * struct mtk_pin_spec_pupd_set - For special pins' pull up/down setting. +- * @pin: The pin number. +- * @offset: The offset of special pull up/down setting register. +- * @pupd_bit: The pull up/down bit in this register. +- * @r0_bit: The r0 bit of pull resistor. +- * @r1_bit: The r1 bit of pull resistor. +- */ +-struct mtk_pin_spec_pupd_set { +- unsigned int pin; +- unsigned int offset; +- unsigned char pupd_bit; +- unsigned char r1_bit; +- unsigned char r0_bit; +-}; +- +-#define MTK_PIN_PUPD_SPEC(_pin, _offset, _pupd, _r1, _r0) \ +- { \ +- .pin = _pin, \ +- .offset = _offset, \ +- .pupd_bit = _pupd, \ +- .r1_bit = _r1, \ +- .r0_bit = _r0, \ +- } +- +-static const struct mtk_pin_spec_pupd_set mt8173_spec_pupd[] = { +- MTK_PIN_PUPD_SPEC(119, 0xe00, 2, 1, 0), /* KROW0 */ +- MTK_PIN_PUPD_SPEC(120, 0xe00, 6, 5, 4), /* KROW1 */ +- MTK_PIN_PUPD_SPEC(121, 0xe00, 10, 9, 8), /* KROW2 */ +- MTK_PIN_PUPD_SPEC(122, 0xe10, 2, 1, 0), /* KCOL0 */ +- MTK_PIN_PUPD_SPEC(123, 0xe10, 6, 5, 4), /* KCOL1 */ +- MTK_PIN_PUPD_SPEC(124, 0xe10, 10, 9, 8), /* KCOL2 */ +- +- MTK_PIN_PUPD_SPEC(67, 0xd10, 2, 1, 0), /* ms0 DS */ +- MTK_PIN_PUPD_SPEC(68, 0xd00, 2, 1, 0), /* ms0 RST */ +- MTK_PIN_PUPD_SPEC(66, 0xc10, 2, 1, 0), /* ms0 cmd */ +- MTK_PIN_PUPD_SPEC(65, 0xc00, 2, 1, 0), /* ms0 clk */ +- MTK_PIN_PUPD_SPEC(57, 0xc20, 2, 1, 0), /* ms0 data0 */ +- MTK_PIN_PUPD_SPEC(58, 0xc20, 2, 1, 0), /* ms0 data1 */ +- MTK_PIN_PUPD_SPEC(59, 0xc20, 2, 1, 0), /* ms0 data2 */ +- MTK_PIN_PUPD_SPEC(60, 0xc20, 2, 1, 0), /* ms0 data3 */ +- MTK_PIN_PUPD_SPEC(61, 0xc20, 2, 1, 0), /* ms0 data4 */ +- MTK_PIN_PUPD_SPEC(62, 0xc20, 2, 1, 0), /* ms0 data5 */ +- MTK_PIN_PUPD_SPEC(63, 0xc20, 2, 1, 0), /* ms0 data6 */ +- MTK_PIN_PUPD_SPEC(64, 0xc20, 2, 1, 0), /* ms0 data7 */ +- +- MTK_PIN_PUPD_SPEC(78, 0xc50, 2, 1, 0), /* ms1 cmd */ +- MTK_PIN_PUPD_SPEC(73, 0xd20, 2, 1, 0), /* ms1 dat0 */ +- MTK_PIN_PUPD_SPEC(74, 0xd20, 6, 5, 4), /* ms1 dat1 */ +- MTK_PIN_PUPD_SPEC(75, 0xd20, 10, 9, 8), /* ms1 dat2 */ +- MTK_PIN_PUPD_SPEC(76, 0xd20, 14, 13, 12), /* ms1 dat3 */ +- MTK_PIN_PUPD_SPEC(77, 0xc40, 2, 1, 0), /* ms1 clk */ +- +- MTK_PIN_PUPD_SPEC(100, 0xd40, 2, 1, 0), /* ms2 dat0 */ +- MTK_PIN_PUPD_SPEC(101, 0xd40, 6, 5, 4), /* ms2 dat1 */ +- MTK_PIN_PUPD_SPEC(102, 0xd40, 10, 9, 8), /* ms2 dat2 */ +- MTK_PIN_PUPD_SPEC(103, 0xd40, 14, 13, 12), /* ms2 dat3 */ +- MTK_PIN_PUPD_SPEC(104, 0xc80, 2, 1, 0), /* ms2 clk */ +- MTK_PIN_PUPD_SPEC(105, 0xc90, 2, 1, 0), /* ms2 cmd */ +- +- MTK_PIN_PUPD_SPEC(22, 0xd60, 2, 1, 0), /* ms3 dat0 */ +- MTK_PIN_PUPD_SPEC(23, 0xd60, 6, 5, 4), /* ms3 dat1 */ +- MTK_PIN_PUPD_SPEC(24, 0xd60, 10, 9, 8), /* ms3 dat2 */ +- MTK_PIN_PUPD_SPEC(25, 0xd60, 14, 13, 12), /* ms3 dat3 */ +- MTK_PIN_PUPD_SPEC(26, 0xcc0, 2, 1, 0), /* ms3 clk */ +- MTK_PIN_PUPD_SPEC(27, 0xcd0, 2, 1, 0) /* ms3 cmd */ ++static const struct mtk_pin_spec_pupd_set_samereg mt8173_spec_pupd[] = { ++ MTK_PIN_PUPD_SPEC_SR(119, 0xe00, 2, 1, 0), /* KROW0 */ ++ MTK_PIN_PUPD_SPEC_SR(120, 0xe00, 6, 5, 4), /* KROW1 */ ++ MTK_PIN_PUPD_SPEC_SR(121, 0xe00, 10, 9, 8), /* KROW2 */ ++ MTK_PIN_PUPD_SPEC_SR(122, 0xe10, 2, 1, 0), /* KCOL0 */ ++ MTK_PIN_PUPD_SPEC_SR(123, 0xe10, 6, 5, 4), /* KCOL1 */ ++ MTK_PIN_PUPD_SPEC_SR(124, 0xe10, 10, 9, 8), /* KCOL2 */ ++ ++ MTK_PIN_PUPD_SPEC_SR(67, 0xd10, 2, 1, 0), /* ms0 DS */ ++ MTK_PIN_PUPD_SPEC_SR(68, 0xd00, 2, 1, 0), /* ms0 RST */ ++ MTK_PIN_PUPD_SPEC_SR(66, 0xc10, 2, 1, 0), /* ms0 cmd */ ++ MTK_PIN_PUPD_SPEC_SR(65, 0xc00, 2, 1, 0), /* ms0 clk */ ++ MTK_PIN_PUPD_SPEC_SR(57, 0xc20, 2, 1, 0), /* ms0 data0 */ ++ MTK_PIN_PUPD_SPEC_SR(58, 0xc20, 2, 1, 0), /* ms0 data1 */ ++ MTK_PIN_PUPD_SPEC_SR(59, 0xc20, 2, 1, 0), /* ms0 data2 */ ++ MTK_PIN_PUPD_SPEC_SR(60, 0xc20, 2, 1, 0), /* ms0 data3 */ ++ MTK_PIN_PUPD_SPEC_SR(61, 0xc20, 2, 1, 0), /* ms0 data4 */ ++ MTK_PIN_PUPD_SPEC_SR(62, 0xc20, 2, 1, 0), /* ms0 data5 */ ++ MTK_PIN_PUPD_SPEC_SR(63, 0xc20, 2, 1, 0), /* ms0 data6 */ ++ MTK_PIN_PUPD_SPEC_SR(64, 0xc20, 2, 1, 0), /* ms0 data7 */ ++ ++ MTK_PIN_PUPD_SPEC_SR(78, 0xc50, 2, 1, 0), /* ms1 cmd */ ++ MTK_PIN_PUPD_SPEC_SR(73, 0xd20, 2, 1, 0), /* ms1 dat0 */ ++ MTK_PIN_PUPD_SPEC_SR(74, 0xd20, 6, 5, 4), /* ms1 dat1 */ ++ MTK_PIN_PUPD_SPEC_SR(75, 0xd20, 10, 9, 8), /* ms1 dat2 */ ++ MTK_PIN_PUPD_SPEC_SR(76, 0xd20, 14, 13, 12), /* ms1 dat3 */ ++ MTK_PIN_PUPD_SPEC_SR(77, 0xc40, 2, 1, 0), /* ms1 clk */ ++ ++ MTK_PIN_PUPD_SPEC_SR(100, 0xd40, 2, 1, 0), /* ms2 dat0 */ ++ MTK_PIN_PUPD_SPEC_SR(101, 0xd40, 6, 5, 4), /* ms2 dat1 */ ++ MTK_PIN_PUPD_SPEC_SR(102, 0xd40, 10, 9, 8), /* ms2 dat2 */ ++ MTK_PIN_PUPD_SPEC_SR(103, 0xd40, 14, 13, 12), /* ms2 dat3 */ ++ MTK_PIN_PUPD_SPEC_SR(104, 0xc80, 2, 1, 0), /* ms2 clk */ ++ MTK_PIN_PUPD_SPEC_SR(105, 0xc90, 2, 1, 0), /* ms2 cmd */ ++ ++ MTK_PIN_PUPD_SPEC_SR(22, 0xd60, 2, 1, 0), /* ms3 dat0 */ ++ MTK_PIN_PUPD_SPEC_SR(23, 0xd60, 6, 5, 4), /* ms3 dat1 */ ++ MTK_PIN_PUPD_SPEC_SR(24, 0xd60, 10, 9, 8), /* ms3 dat2 */ ++ MTK_PIN_PUPD_SPEC_SR(25, 0xd60, 14, 13, 12), /* ms3 dat3 */ ++ MTK_PIN_PUPD_SPEC_SR(26, 0xcc0, 2, 1, 0), /* ms3 clk */ ++ MTK_PIN_PUPD_SPEC_SR(27, 0xcd0, 2, 1, 0) /* ms3 cmd */ + }; + +-static int spec_pull_set(struct regmap *regmap, unsigned int pin, ++static int mt8173_spec_pull_set(struct regmap *regmap, unsigned int pin, + unsigned char align, bool isup, unsigned int r1r0) + { +- unsigned int i; +- unsigned int reg_pupd, reg_set, reg_rst; +- unsigned int bit_pupd, bit_r0, bit_r1; +- const struct mtk_pin_spec_pupd_set *spec_pupd_pin; +- bool find = false; +- +- for (i = 0; i < ARRAY_SIZE(mt8173_spec_pupd); i++) { +- if (pin == mt8173_spec_pupd[i].pin) { +- find = true; +- break; +- } +- } +- +- if (!find) +- return -EINVAL; +- +- spec_pupd_pin = mt8173_spec_pupd + i; +- reg_set = spec_pupd_pin->offset + align; +- reg_rst = spec_pupd_pin->offset + (align << 1); +- +- if (isup) +- reg_pupd = reg_rst; +- else +- reg_pupd = reg_set; +- +- bit_pupd = BIT(spec_pupd_pin->pupd_bit); +- regmap_write(regmap, reg_pupd, bit_pupd); +- +- bit_r0 = BIT(spec_pupd_pin->r0_bit); +- bit_r1 = BIT(spec_pupd_pin->r1_bit); +- +- switch (r1r0) { +- case MTK_PUPD_SET_R1R0_00: +- regmap_write(regmap, reg_rst, bit_r0); +- regmap_write(regmap, reg_rst, bit_r1); +- break; +- case MTK_PUPD_SET_R1R0_01: +- regmap_write(regmap, reg_set, bit_r0); +- regmap_write(regmap, reg_rst, bit_r1); +- break; +- case MTK_PUPD_SET_R1R0_10: +- regmap_write(regmap, reg_rst, bit_r0); +- regmap_write(regmap, reg_set, bit_r1); +- break; +- case MTK_PUPD_SET_R1R0_11: +- regmap_write(regmap, reg_set, bit_r0); +- regmap_write(regmap, reg_set, bit_r1); +- break; +- default: +- return -EINVAL; +- } +- +- return 0; ++ return mtk_pctrl_spec_pull_set_samereg(regmap, mt8173_spec_pupd, ++ ARRAY_SIZE(mt8173_spec_pupd), pin, align, isup, r1r0); + } + + static const struct mtk_pin_ies_smt_set mt8173_ies_smt_set[] = { +@@ -382,7 +306,7 @@ static const struct mtk_pinctrl_devdata mt8173_pinctrl_data = { + .n_grp_cls = ARRAY_SIZE(mt8173_drv_grp), + .pin_drv_grp = mt8173_pin_drv, + .n_pin_drv_grps = ARRAY_SIZE(mt8173_pin_drv), +- .spec_pull_set = spec_pull_set, ++ .spec_pull_set = mt8173_spec_pull_set, + .spec_ies_smt_set = spec_ies_smt_set, + .dir_offset = 0x0000, + .pullen_offset = 0x0100, +diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c +index 474812e..0d51145 100644 +--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c ++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c +@@ -186,6 +186,66 @@ static int mtk_pconf_set_driving(struct mtk_pinctrl *pctl, + return -EINVAL; + } + ++int mtk_pctrl_spec_pull_set_samereg(struct regmap *regmap, ++ const struct mtk_pin_spec_pupd_set_samereg *pupd_infos, ++ unsigned int info_num, unsigned int pin, ++ unsigned char align, bool isup, unsigned int r1r0) ++{ ++ unsigned int i; ++ unsigned int reg_pupd, reg_set, reg_rst; ++ unsigned int bit_pupd, bit_r0, bit_r1; ++ const struct mtk_pin_spec_pupd_set_samereg *spec_pupd_pin; ++ bool find = false; ++ ++ for (i = 0; i < info_num; i++) { ++ if (pin == pupd_infos[i].pin) { ++ find = true; ++ break; ++ } ++ } ++ ++ if (!find) ++ return -EINVAL; ++ ++ spec_pupd_pin = pupd_infos + i; ++ reg_set = spec_pupd_pin->offset + align; ++ reg_rst = spec_pupd_pin->offset + (align << 1); ++ ++ if (isup) ++ reg_pupd = reg_rst; ++ else ++ reg_pupd = reg_set; ++ ++ bit_pupd = BIT(spec_pupd_pin->pupd_bit); ++ regmap_write(regmap, reg_pupd, bit_pupd); ++ ++ bit_r0 = BIT(spec_pupd_pin->r0_bit); ++ bit_r1 = BIT(spec_pupd_pin->r1_bit); ++ ++ switch (r1r0) { ++ case MTK_PUPD_SET_R1R0_00: ++ regmap_write(regmap, reg_rst, bit_r0); ++ regmap_write(regmap, reg_rst, bit_r1); ++ break; ++ case MTK_PUPD_SET_R1R0_01: ++ regmap_write(regmap, reg_set, bit_r0); ++ regmap_write(regmap, reg_rst, bit_r1); ++ break; ++ case MTK_PUPD_SET_R1R0_10: ++ regmap_write(regmap, reg_rst, bit_r0); ++ regmap_write(regmap, reg_set, bit_r1); ++ break; ++ case MTK_PUPD_SET_R1R0_11: ++ regmap_write(regmap, reg_set, bit_r0); ++ regmap_write(regmap, reg_set, bit_r1); ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ + static int mtk_pconf_set_pull_select(struct mtk_pinctrl *pctl, + unsigned int pin, bool enable, bool isup, unsigned int arg) + { +diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h +index 1508849..2a4b7be 100644 +--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h ++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h +@@ -117,6 +117,32 @@ struct mtk_pin_drv_grp { + .grp = _grp, \ + } + ++/** ++ * struct mtk_pin_spec_pupd_set_samereg ++ * - For special pins' pull up/down setting which resides in same register ++ * @pin: The pin number. ++ * @offset: The offset of special pull up/down setting register. ++ * @pupd_bit: The pull up/down bit in this register. ++ * @r0_bit: The r0 bit of pull resistor. ++ * @r1_bit: The r1 bit of pull resistor. ++ */ ++struct mtk_pin_spec_pupd_set_samereg { ++ unsigned short pin; ++ unsigned short offset; ++ unsigned char pupd_bit; ++ unsigned char r1_bit; ++ unsigned char r0_bit; ++}; ++ ++#define MTK_PIN_PUPD_SPEC_SR(_pin, _offset, _pupd, _r1, _r0) \ ++ { \ ++ .pin = _pin, \ ++ .offset = _offset, \ ++ .pupd_bit = _pupd, \ ++ .r1_bit = _r1, \ ++ .r0_bit = _r0, \ ++ } ++ + struct mtk_eint_offsets { + const char *name; + unsigned int stat; +@@ -220,4 +246,9 @@ struct mtk_pinctrl { + int mtk_pctrl_init(struct platform_device *pdev, + const struct mtk_pinctrl_devdata *data); + ++int mtk_pctrl_spec_pull_set_samereg(struct regmap *regmap, ++ const struct mtk_pin_spec_pupd_set_samereg *pupd_infos, ++ unsigned int info_num, unsigned int pin, ++ unsigned char align, bool isup, unsigned int r1r0); ++ + #endif /* __PINCTRL_MTK_COMMON_H */ +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0052-pinctrl-mediatek-add-ies-smt-control-to-common-code.patch b/target/linux/mediatek/patches/0052-pinctrl-mediatek-add-ies-smt-control-to-common-code.patch new file mode 100644 index 0000000000..5467c216b8 --- /dev/null +++ b/target/linux/mediatek/patches/0052-pinctrl-mediatek-add-ies-smt-control-to-common-code.patch @@ -0,0 +1,479 @@ +From 32ea3b91046bea40cd1a7a4f16a24d75f53ca92a Mon Sep 17 00:00:00 2001 +From: Hongzhou Yang <hongzhou.yang@mediatek.com> +Date: Mon, 18 May 2015 23:11:16 -0700 +Subject: [PATCH 52/76] pinctrl: mediatek: add ies/smt control to common code. + +Input enable and smt setting have different register, +modify code to fix it. + +Several mediatek soc use similar input enable/smt setting +procedure as mt8173, some soc use generic input enable/smt +setting, some soc has no input enable/smt setting. Adding +common code to handle all those cases, so future soc driver +can use it. + +Signed-off-by: Hongzhou Yang <hongzhou.yang@mediatek.com> +--- + drivers/pinctrl/mediatek/pinctrl-mt8173.c | 201 +++++++++++++------------ + drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 82 +++++++--- + drivers/pinctrl/mediatek/pinctrl-mtk-common.h | 31 +++- + 3 files changed, 198 insertions(+), 116 deletions(-) + +diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8173.c b/drivers/pinctrl/mediatek/pinctrl-mt8173.c +index cc44b27..a7e5b24 100644 +--- a/drivers/pinctrl/mediatek/pinctrl-mt8173.c ++++ b/drivers/pinctrl/mediatek/pinctrl-mt8173.c +@@ -18,6 +18,7 @@ + #include <linux/of_device.h> + #include <linux/pinctrl/pinctrl.h> + #include <linux/regmap.h> ++#include <linux/pinctrl/pinconf-generic.h> + #include <dt-bindings/pinctrl/mt65xx.h> + + #include "pinctrl-mtk-common.h" +@@ -25,28 +26,6 @@ + + #define DRV_BASE 0xb00 + +-/** +- * struct mtk_pin_ies_smt_set - For special pins' ies and smt setting. +- * @start: The start pin number of those special pins. +- * @end: The end pin number of those special pins. +- * @offset: The offset of special setting register. +- * @bit: The bit of special setting register. +- */ +-struct mtk_pin_ies_smt_set { +- unsigned int start; +- unsigned int end; +- unsigned int offset; +- unsigned char bit; +-}; +- +-#define MTK_PIN_IES_SMT_SET(_start, _end, _offset, _bit) \ +- { \ +- .start = _start, \ +- .end = _end, \ +- .bit = _bit, \ +- .offset = _offset, \ +- } +- + static const struct mtk_pin_spec_pupd_set_samereg mt8173_spec_pupd[] = { + MTK_PIN_PUPD_SPEC_SR(119, 0xe00, 2, 1, 0), /* KROW0 */ + MTK_PIN_PUPD_SPEC_SR(120, 0xe00, 6, 5, 4), /* KROW1 */ +@@ -97,80 +76,114 @@ static int mt8173_spec_pull_set(struct regmap *regmap, unsigned int pin, + ARRAY_SIZE(mt8173_spec_pupd), pin, align, isup, r1r0); + } + +-static const struct mtk_pin_ies_smt_set mt8173_ies_smt_set[] = { +- MTK_PIN_IES_SMT_SET(0, 4, 0x930, 1), +- MTK_PIN_IES_SMT_SET(5, 9, 0x930, 2), +- MTK_PIN_IES_SMT_SET(10, 13, 0x930, 10), +- MTK_PIN_IES_SMT_SET(14, 15, 0x940, 10), +- MTK_PIN_IES_SMT_SET(16, 16, 0x930, 0), +- MTK_PIN_IES_SMT_SET(17, 17, 0x950, 2), +- MTK_PIN_IES_SMT_SET(18, 21, 0x940, 3), +- MTK_PIN_IES_SMT_SET(29, 32, 0x930, 3), +- MTK_PIN_IES_SMT_SET(33, 33, 0x930, 4), +- MTK_PIN_IES_SMT_SET(34, 36, 0x930, 5), +- MTK_PIN_IES_SMT_SET(37, 38, 0x930, 6), +- MTK_PIN_IES_SMT_SET(39, 39, 0x930, 7), +- MTK_PIN_IES_SMT_SET(40, 41, 0x930, 9), +- MTK_PIN_IES_SMT_SET(42, 42, 0x940, 0), +- MTK_PIN_IES_SMT_SET(43, 44, 0x930, 11), +- MTK_PIN_IES_SMT_SET(45, 46, 0x930, 12), +- MTK_PIN_IES_SMT_SET(57, 64, 0xc20, 13), +- MTK_PIN_IES_SMT_SET(65, 65, 0xc10, 13), +- MTK_PIN_IES_SMT_SET(66, 66, 0xc00, 13), +- MTK_PIN_IES_SMT_SET(67, 67, 0xd10, 13), +- MTK_PIN_IES_SMT_SET(68, 68, 0xd00, 13), +- MTK_PIN_IES_SMT_SET(69, 72, 0x940, 14), +- MTK_PIN_IES_SMT_SET(73, 76, 0xc60, 13), +- MTK_PIN_IES_SMT_SET(77, 77, 0xc40, 13), +- MTK_PIN_IES_SMT_SET(78, 78, 0xc50, 13), +- MTK_PIN_IES_SMT_SET(79, 82, 0x940, 15), +- MTK_PIN_IES_SMT_SET(83, 83, 0x950, 0), +- MTK_PIN_IES_SMT_SET(84, 85, 0x950, 1), +- MTK_PIN_IES_SMT_SET(86, 91, 0x950, 2), +- MTK_PIN_IES_SMT_SET(92, 92, 0x930, 13), +- MTK_PIN_IES_SMT_SET(93, 95, 0x930, 14), +- MTK_PIN_IES_SMT_SET(96, 99, 0x930, 15), +- MTK_PIN_IES_SMT_SET(100, 103, 0xca0, 13), +- MTK_PIN_IES_SMT_SET(104, 104, 0xc80, 13), +- MTK_PIN_IES_SMT_SET(105, 105, 0xc90, 13), +- MTK_PIN_IES_SMT_SET(106, 107, 0x940, 4), +- MTK_PIN_IES_SMT_SET(108, 112, 0x940, 1), +- MTK_PIN_IES_SMT_SET(113, 116, 0x940, 2), +- MTK_PIN_IES_SMT_SET(117, 118, 0x940, 5), +- MTK_PIN_IES_SMT_SET(119, 124, 0x940, 6), +- MTK_PIN_IES_SMT_SET(125, 126, 0x940, 7), +- MTK_PIN_IES_SMT_SET(127, 127, 0x940, 0), +- MTK_PIN_IES_SMT_SET(128, 128, 0x950, 8), +- MTK_PIN_IES_SMT_SET(129, 130, 0x950, 9), +- MTK_PIN_IES_SMT_SET(131, 132, 0x950, 8), +- MTK_PIN_IES_SMT_SET(133, 134, 0x910, 8) ++static const struct mtk_pin_ies_smt_set mt8173_smt_set[] = { ++ MTK_PIN_IES_SMT_SPEC(0, 4, 0x930, 1), ++ MTK_PIN_IES_SMT_SPEC(5, 9, 0x930, 2), ++ MTK_PIN_IES_SMT_SPEC(10, 13, 0x930, 10), ++ MTK_PIN_IES_SMT_SPEC(14, 15, 0x940, 10), ++ MTK_PIN_IES_SMT_SPEC(16, 16, 0x930, 0), ++ MTK_PIN_IES_SMT_SPEC(17, 17, 0x950, 2), ++ MTK_PIN_IES_SMT_SPEC(18, 21, 0x940, 3), ++ MTK_PIN_IES_SMT_SPEC(29, 32, 0x930, 3), ++ MTK_PIN_IES_SMT_SPEC(33, 33, 0x930, 4), ++ MTK_PIN_IES_SMT_SPEC(34, 36, 0x930, 5), ++ MTK_PIN_IES_SMT_SPEC(37, 38, 0x930, 6), ++ MTK_PIN_IES_SMT_SPEC(39, 39, 0x930, 7), ++ MTK_PIN_IES_SMT_SPEC(40, 41, 0x930, 9), ++ MTK_PIN_IES_SMT_SPEC(42, 42, 0x940, 0), ++ MTK_PIN_IES_SMT_SPEC(43, 44, 0x930, 11), ++ MTK_PIN_IES_SMT_SPEC(45, 46, 0x930, 12), ++ MTK_PIN_IES_SMT_SPEC(57, 64, 0xc20, 13), ++ MTK_PIN_IES_SMT_SPEC(65, 65, 0xc10, 13), ++ MTK_PIN_IES_SMT_SPEC(66, 66, 0xc00, 13), ++ MTK_PIN_IES_SMT_SPEC(67, 67, 0xd10, 13), ++ MTK_PIN_IES_SMT_SPEC(68, 68, 0xd00, 13), ++ MTK_PIN_IES_SMT_SPEC(69, 72, 0x940, 14), ++ MTK_PIN_IES_SMT_SPEC(73, 76, 0xc60, 13), ++ MTK_PIN_IES_SMT_SPEC(77, 77, 0xc40, 13), ++ MTK_PIN_IES_SMT_SPEC(78, 78, 0xc50, 13), ++ MTK_PIN_IES_SMT_SPEC(79, 82, 0x940, 15), ++ MTK_PIN_IES_SMT_SPEC(83, 83, 0x950, 0), ++ MTK_PIN_IES_SMT_SPEC(84, 85, 0x950, 1), ++ MTK_PIN_IES_SMT_SPEC(86, 91, 0x950, 2), ++ MTK_PIN_IES_SMT_SPEC(92, 92, 0x930, 13), ++ MTK_PIN_IES_SMT_SPEC(93, 95, 0x930, 14), ++ MTK_PIN_IES_SMT_SPEC(96, 99, 0x930, 15), ++ MTK_PIN_IES_SMT_SPEC(100, 103, 0xca0, 13), ++ MTK_PIN_IES_SMT_SPEC(104, 104, 0xc80, 13), ++ MTK_PIN_IES_SMT_SPEC(105, 105, 0xc90, 13), ++ MTK_PIN_IES_SMT_SPEC(106, 107, 0x940, 4), ++ MTK_PIN_IES_SMT_SPEC(108, 112, 0x940, 1), ++ MTK_PIN_IES_SMT_SPEC(113, 116, 0x940, 2), ++ MTK_PIN_IES_SMT_SPEC(117, 118, 0x940, 5), ++ MTK_PIN_IES_SMT_SPEC(119, 124, 0x940, 6), ++ MTK_PIN_IES_SMT_SPEC(125, 126, 0x940, 7), ++ MTK_PIN_IES_SMT_SPEC(127, 127, 0x940, 0), ++ MTK_PIN_IES_SMT_SPEC(128, 128, 0x950, 8), ++ MTK_PIN_IES_SMT_SPEC(129, 130, 0x950, 9), ++ MTK_PIN_IES_SMT_SPEC(131, 132, 0x950, 8), ++ MTK_PIN_IES_SMT_SPEC(133, 134, 0x910, 8) + }; + +-static int spec_ies_smt_set(struct regmap *regmap, unsigned int pin, +- unsigned char align, int value) +-{ +- unsigned int i, reg_addr, bit; +- bool find = false; +- +- for (i = 0; i < ARRAY_SIZE(mt8173_ies_smt_set); i++) { +- if (pin >= mt8173_ies_smt_set[i].start && +- pin <= mt8173_ies_smt_set[i].end) { +- find = true; +- break; +- } +- } +- +- if (!find) +- return -EINVAL; +- +- if (value) +- reg_addr = mt8173_ies_smt_set[i].offset + align; +- else +- reg_addr = mt8173_ies_smt_set[i].offset + (align << 1); ++static const struct mtk_pin_ies_smt_set mt8173_ies_set[] = { ++ MTK_PIN_IES_SMT_SPEC(0, 4, 0x900, 1), ++ MTK_PIN_IES_SMT_SPEC(5, 9, 0x900, 2), ++ MTK_PIN_IES_SMT_SPEC(10, 13, 0x900, 10), ++ MTK_PIN_IES_SMT_SPEC(14, 15, 0x910, 10), ++ MTK_PIN_IES_SMT_SPEC(16, 16, 0x900, 0), ++ MTK_PIN_IES_SMT_SPEC(17, 17, 0x920, 2), ++ MTK_PIN_IES_SMT_SPEC(18, 21, 0x910, 3), ++ MTK_PIN_IES_SMT_SPEC(29, 32, 0x900, 3), ++ MTK_PIN_IES_SMT_SPEC(33, 33, 0x900, 4), ++ MTK_PIN_IES_SMT_SPEC(34, 36, 0x900, 5), ++ MTK_PIN_IES_SMT_SPEC(37, 38, 0x900, 6), ++ MTK_PIN_IES_SMT_SPEC(39, 39, 0x900, 7), ++ MTK_PIN_IES_SMT_SPEC(40, 41, 0x900, 9), ++ MTK_PIN_IES_SMT_SPEC(42, 42, 0x910, 0), ++ MTK_PIN_IES_SMT_SPEC(43, 44, 0x900, 11), ++ MTK_PIN_IES_SMT_SPEC(45, 46, 0x900, 12), ++ MTK_PIN_IES_SMT_SPEC(57, 64, 0xc20, 14), ++ MTK_PIN_IES_SMT_SPEC(65, 65, 0xc10, 14), ++ MTK_PIN_IES_SMT_SPEC(66, 66, 0xc00, 14), ++ MTK_PIN_IES_SMT_SPEC(67, 67, 0xd10, 14), ++ MTK_PIN_IES_SMT_SPEC(68, 68, 0xd00, 14), ++ MTK_PIN_IES_SMT_SPEC(69, 72, 0x910, 14), ++ MTK_PIN_IES_SMT_SPEC(73, 76, 0xc60, 14), ++ MTK_PIN_IES_SMT_SPEC(77, 77, 0xc40, 14), ++ MTK_PIN_IES_SMT_SPEC(78, 78, 0xc50, 14), ++ MTK_PIN_IES_SMT_SPEC(79, 82, 0x910, 15), ++ MTK_PIN_IES_SMT_SPEC(83, 83, 0x920, 0), ++ MTK_PIN_IES_SMT_SPEC(84, 85, 0x920, 1), ++ MTK_PIN_IES_SMT_SPEC(86, 91, 0x920, 2), ++ MTK_PIN_IES_SMT_SPEC(92, 92, 0x900, 13), ++ MTK_PIN_IES_SMT_SPEC(93, 95, 0x900, 14), ++ MTK_PIN_IES_SMT_SPEC(96, 99, 0x900, 15), ++ MTK_PIN_IES_SMT_SPEC(100, 103, 0xca0, 14), ++ MTK_PIN_IES_SMT_SPEC(104, 104, 0xc80, 14), ++ MTK_PIN_IES_SMT_SPEC(105, 105, 0xc90, 14), ++ MTK_PIN_IES_SMT_SPEC(106, 107, 0x91, 4), ++ MTK_PIN_IES_SMT_SPEC(108, 112, 0x910, 1), ++ MTK_PIN_IES_SMT_SPEC(113, 116, 0x910, 2), ++ MTK_PIN_IES_SMT_SPEC(117, 118, 0x910, 5), ++ MTK_PIN_IES_SMT_SPEC(119, 124, 0x910, 6), ++ MTK_PIN_IES_SMT_SPEC(125, 126, 0x910, 7), ++ MTK_PIN_IES_SMT_SPEC(127, 127, 0x910, 0), ++ MTK_PIN_IES_SMT_SPEC(128, 128, 0x920, 8), ++ MTK_PIN_IES_SMT_SPEC(129, 130, 0x920, 9), ++ MTK_PIN_IES_SMT_SPEC(131, 132, 0x920, 8), ++ MTK_PIN_IES_SMT_SPEC(133, 134, 0x910, 8) ++}; + +- bit = BIT(mt8173_ies_smt_set[i].bit); +- regmap_write(regmap, reg_addr, bit); +- return 0; ++static int mt8173_ies_smt_set(struct regmap *regmap, unsigned int pin, ++ unsigned char align, int value, enum pin_config_param arg) ++{ ++ if (arg == PIN_CONFIG_INPUT_ENABLE) ++ return mtk_pconf_spec_set_ies_smt_range(regmap, mt8173_ies_set, ++ ARRAY_SIZE(mt8173_ies_set), pin, align, value); ++ else if (arg == PIN_CONFIG_INPUT_SCHMITT_ENABLE) ++ return mtk_pconf_spec_set_ies_smt_range(regmap, mt8173_smt_set, ++ ARRAY_SIZE(mt8173_smt_set), pin, align, value); ++ return -EINVAL; + } + + static const struct mtk_drv_group_desc mt8173_drv_grp[] = { +@@ -307,7 +320,7 @@ static const struct mtk_pinctrl_devdata mt8173_pinctrl_data = { + .pin_drv_grp = mt8173_pin_drv, + .n_pin_drv_grps = ARRAY_SIZE(mt8173_pin_drv), + .spec_pull_set = mt8173_spec_pull_set, +- .spec_ies_smt_set = spec_ies_smt_set, ++ .spec_ies_smt_set = mt8173_ies_smt_set, + .dir_offset = 0x0000, + .pullen_offset = 0x0100, + .pullsel_offset = 0x0200, +diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c +index 0d51145..97fe2ab 100644 +--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c ++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c +@@ -107,28 +107,38 @@ static void mtk_gpio_set(struct gpio_chip *chip, unsigned offset, int value) + regmap_write(mtk_get_regmap(pctl, offset), reg_addr, bit); + } + +-static void mtk_pconf_set_ies_smt(struct mtk_pinctrl *pctl, unsigned pin, +- int value, enum pin_config_param param) ++static int mtk_pconf_set_ies_smt(struct mtk_pinctrl *pctl, unsigned pin, ++ int value, enum pin_config_param arg) + { + unsigned int reg_addr, offset; + unsigned int bit; +- int ret; ++ ++ /** ++ * Due to some soc are not support ies/smt config, add this special ++ * control to handle it. ++ */ ++ if (!pctl->devdata->spec_ies_smt_set && ++ pctl->devdata->ies_offset == MTK_PINCTRL_NOT_SUPPORT && ++ arg == PIN_CONFIG_INPUT_ENABLE) ++ return -EINVAL; ++ ++ if (!pctl->devdata->spec_ies_smt_set && ++ pctl->devdata->smt_offset == MTK_PINCTRL_NOT_SUPPORT && ++ arg == PIN_CONFIG_INPUT_SCHMITT_ENABLE) ++ return -EINVAL; + + /* + * Due to some pins are irregular, their input enable and smt +- * control register are discontinuous, but they are mapping together. +- * So we need this special handle. ++ * control register are discontinuous, so we need this special handle. + */ + if (pctl->devdata->spec_ies_smt_set) { +- ret = pctl->devdata->spec_ies_smt_set(mtk_get_regmap(pctl, pin), +- pin, pctl->devdata->port_align, value); +- if (!ret) +- return; ++ return pctl->devdata->spec_ies_smt_set(mtk_get_regmap(pctl, pin), ++ pin, pctl->devdata->port_align, value, arg); + } + + bit = BIT(pin & 0xf); + +- if (param == PIN_CONFIG_INPUT_ENABLE) ++ if (arg == PIN_CONFIG_INPUT_ENABLE) + offset = pctl->devdata->ies_offset; + else + offset = pctl->devdata->smt_offset; +@@ -139,6 +149,33 @@ static void mtk_pconf_set_ies_smt(struct mtk_pinctrl *pctl, unsigned pin, + reg_addr = CLR_ADDR(mtk_get_port(pctl, pin) + offset, pctl); + + regmap_write(mtk_get_regmap(pctl, pin), reg_addr, bit); ++ return 0; ++} ++ ++int mtk_pconf_spec_set_ies_smt_range(struct regmap *regmap, ++ const struct mtk_pin_ies_smt_set *ies_smt_infos, unsigned int info_num, ++ unsigned int pin, unsigned char align, int value) ++{ ++ unsigned int i, reg_addr, bit; ++ ++ for (i = 0; i < info_num; i++) { ++ if (pin >= ies_smt_infos[i].start && ++ pin <= ies_smt_infos[i].end) { ++ break; ++ } ++ } ++ ++ if (i == info_num) ++ return -EINVAL; ++ ++ if (value) ++ reg_addr = ies_smt_infos[i].offset + align; ++ else ++ reg_addr = ies_smt_infos[i].offset + (align << 1); ++ ++ bit = BIT(ies_smt_infos[i].bit); ++ regmap_write(regmap, reg_addr, bit); ++ return 0; + } + + static const struct mtk_pin_drv_grp *mtk_find_pin_drv_grp_by_pin( +@@ -295,36 +332,37 @@ static int mtk_pconf_parse_conf(struct pinctrl_dev *pctldev, + unsigned int pin, enum pin_config_param param, + enum pin_config_param arg) + { ++ int ret = 0; + struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + + switch (param) { + case PIN_CONFIG_BIAS_DISABLE: +- mtk_pconf_set_pull_select(pctl, pin, false, false, arg); ++ ret = mtk_pconf_set_pull_select(pctl, pin, false, false, arg); + break; + case PIN_CONFIG_BIAS_PULL_UP: +- mtk_pconf_set_pull_select(pctl, pin, true, true, arg); ++ ret = mtk_pconf_set_pull_select(pctl, pin, true, true, arg); + break; + case PIN_CONFIG_BIAS_PULL_DOWN: +- mtk_pconf_set_pull_select(pctl, pin, true, false, arg); ++ ret = mtk_pconf_set_pull_select(pctl, pin, true, false, arg); + break; + case PIN_CONFIG_INPUT_ENABLE: +- mtk_pconf_set_ies_smt(pctl, pin, arg, param); ++ ret = mtk_pconf_set_ies_smt(pctl, pin, arg, param); + break; + case PIN_CONFIG_OUTPUT: + mtk_gpio_set(pctl->chip, pin, arg); +- mtk_pmx_gpio_set_direction(pctldev, NULL, pin, false); ++ ret = mtk_pmx_gpio_set_direction(pctldev, NULL, pin, false); + break; + case PIN_CONFIG_INPUT_SCHMITT_ENABLE: +- mtk_pconf_set_ies_smt(pctl, pin, arg, param); ++ ret = mtk_pconf_set_ies_smt(pctl, pin, arg, param); + break; + case PIN_CONFIG_DRIVE_STRENGTH: +- mtk_pconf_set_driving(pctl, pin, arg); ++ ret = mtk_pconf_set_driving(pctl, pin, arg); + break; + default: +- return -EINVAL; ++ ret = -EINVAL; + } + +- return 0; ++ return ret; + } + + static int mtk_pconf_group_get(struct pinctrl_dev *pctldev, +@@ -343,12 +381,14 @@ static int mtk_pconf_group_set(struct pinctrl_dev *pctldev, unsigned group, + { + struct mtk_pinctrl *pctl = pinctrl_dev_get_drvdata(pctldev); + struct mtk_pinctrl_group *g = &pctl->groups[group]; +- int i; ++ int i, ret; + + for (i = 0; i < num_configs; i++) { +- mtk_pconf_parse_conf(pctldev, g->pin, ++ ret = mtk_pconf_parse_conf(pctldev, g->pin, + pinconf_to_config_param(configs[i]), + pinconf_to_config_argument(configs[i])); ++ if (ret < 0) ++ return ret; + + g->config = configs[i]; + } +diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h +index 2a4b7be..c703e7d 100644 +--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h ++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h +@@ -17,6 +17,7 @@ + + #include <linux/pinctrl/pinctrl.h> + #include <linux/regmap.h> ++#include <linux/pinctrl/pinconf-generic.h> + + #define NO_EINT_SUPPORT 255 + #define MT_EDGE_SENSITIVE 0 +@@ -25,6 +26,8 @@ + #define EINT_DBNC_RST_BIT (0x1 << 1) + #define EINT_DBNC_SET_EN (0x1 << 0) + ++#define MTK_PINCTRL_NOT_SUPPORT (0xffff) ++ + struct mtk_desc_function { + const char *name; + unsigned char muxval; +@@ -143,6 +146,28 @@ struct mtk_pin_spec_pupd_set_samereg { + .r0_bit = _r0, \ + } + ++/** ++ * struct mtk_pin_ies_set - For special pins' ies and smt setting. ++ * @start: The start pin number of those special pins. ++ * @end: The end pin number of those special pins. ++ * @offset: The offset of special setting register. ++ * @bit: The bit of special setting register. ++ */ ++struct mtk_pin_ies_smt_set { ++ unsigned short start; ++ unsigned short end; ++ unsigned short offset; ++ unsigned char bit; ++}; ++ ++#define MTK_PIN_IES_SMT_SPEC(_start, _end, _offset, _bit) \ ++ { \ ++ .start = _start, \ ++ .end = _end, \ ++ .bit = _bit, \ ++ .offset = _offset, \ ++ } ++ + struct mtk_eint_offsets { + const char *name; + unsigned int stat; +@@ -208,7 +233,7 @@ struct mtk_pinctrl_devdata { + int (*spec_pull_set)(struct regmap *reg, unsigned int pin, + unsigned char align, bool isup, unsigned int arg); + int (*spec_ies_smt_set)(struct regmap *reg, unsigned int pin, +- unsigned char align, int value); ++ unsigned char align, int value, enum pin_config_param arg); + unsigned int dir_offset; + unsigned int ies_offset; + unsigned int smt_offset; +@@ -251,4 +276,8 @@ int mtk_pctrl_spec_pull_set_samereg(struct regmap *regmap, + unsigned int info_num, unsigned int pin, + unsigned char align, bool isup, unsigned int r1r0); + ++int mtk_pconf_spec_set_ies_smt_range(struct regmap *regmap, ++ const struct mtk_pin_ies_smt_set *ies_smt_infos, unsigned int info_num, ++ unsigned int pin, unsigned char align, int value); ++ + #endif /* __PINCTRL_MTK_COMMON_H */ +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0053-pinctrl-mediatek-Add-Pinctrl-GPIO-driver-for-mt6397.patch b/target/linux/mediatek/patches/0053-pinctrl-mediatek-Add-Pinctrl-GPIO-driver-for-mt6397.patch new file mode 100644 index 0000000000..2813f407d5 --- /dev/null +++ b/target/linux/mediatek/patches/0053-pinctrl-mediatek-Add-Pinctrl-GPIO-driver-for-mt6397.patch @@ -0,0 +1,654 @@ +From 3031cefd8cd323e04be11a8058616d8cf21c1313 Mon Sep 17 00:00:00 2001 +From: Hongzhou Yang <hongzhou.yang@mediatek.com> +Date: Mon, 18 May 2015 23:11:17 -0700 +Subject: [PATCH 53/76] pinctrl: mediatek: Add Pinctrl/GPIO driver for mt6397. + +Add mt6397 support using mediatek common pinctrl driver. + +mt6397 is a PMIC, and pinctrl/GPIO is part of 6397 chip. +Pinctrl/GPIO driver should obtain regmap from PMIC, +so adding this support to common code. + +Also, mt6397 is no need to support interrupt controller, +so changing common code to skip it. + +Signed-off-by: Hongzhou Yang <hongzhou.yang@mediatek.com> +--- + drivers/pinctrl/mediatek/Kconfig | 6 + + drivers/pinctrl/mediatek/Makefile | 1 + + drivers/pinctrl/mediatek/pinctrl-mt6397.c | 78 +++++ + drivers/pinctrl/mediatek/pinctrl-mt8135.c | 2 +- + drivers/pinctrl/mediatek/pinctrl-mt8173.c | 2 +- + drivers/pinctrl/mediatek/pinctrl-mtk-common.c | 13 +- + drivers/pinctrl/mediatek/pinctrl-mtk-common.h | 3 +- + drivers/pinctrl/mediatek/pinctrl-mtk-mt6397.h | 424 +++++++++++++++++++++++++ + 8 files changed, 524 insertions(+), 5 deletions(-) + create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt6397.c + create mode 100644 drivers/pinctrl/mediatek/pinctrl-mtk-mt6397.h + +diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig +index 6b3551c..ddae479 100644 +--- a/drivers/pinctrl/mediatek/Kconfig ++++ b/drivers/pinctrl/mediatek/Kconfig +@@ -23,4 +23,10 @@ config PINCTRL_MT8173 + default ARM64 && ARCH_MEDIATEK + select PINCTRL_MTK_COMMON + ++# For PMIC ++config PINCTRL_MT6397 ++ bool "Mediatek MT6397 pin control" if COMPILE_TEST && !MFD_MT6397 ++ default MFD_MT6397 ++ select PINCTRL_MTK_COMMON ++ + endif +diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile +index d8606a2..ad0180c 100644 +--- a/drivers/pinctrl/mediatek/Makefile ++++ b/drivers/pinctrl/mediatek/Makefile +@@ -4,3 +4,4 @@ obj-$(CONFIG_PINCTRL_MTK_COMMON) += pinctrl-mtk-common.o + # SoC Drivers + obj-$(CONFIG_PINCTRL_MT8135) += pinctrl-mt8135.o + obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o ++obj-$(CONFIG_PINCTRL_MT6397) += pinctrl-mt6397.o +diff --git a/drivers/pinctrl/mediatek/pinctrl-mt6397.c b/drivers/pinctrl/mediatek/pinctrl-mt6397.c +new file mode 100644 +index 0000000..767bbdf +--- /dev/null ++++ b/drivers/pinctrl/mediatek/pinctrl-mt6397.c +@@ -0,0 +1,78 @@ ++/* ++ * Copyright (c) 2015 MediaTek Inc. ++ * Author: Hongzhou.Yang <hongzhou.yang@mediatek.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/module.h> ++#include <linux/platform_device.h> ++#include <linux/of.h> ++#include <linux/of_device.h> ++#include <linux/pinctrl/pinctrl.h> ++#include <linux/pinctrl/pinconf-generic.h> ++#include <linux/mfd/mt6397/core.h> ++ ++#include "pinctrl-mtk-common.h" ++#include "pinctrl-mtk-mt6397.h" ++ ++#define MT6397_PIN_REG_BASE 0xc000 ++ ++static const struct mtk_pinctrl_devdata mt6397_pinctrl_data = { ++ .pins = mtk_pins_mt6397, ++ .npins = ARRAY_SIZE(mtk_pins_mt6397), ++ .dir_offset = (MT6397_PIN_REG_BASE + 0x000), ++ .ies_offset = MTK_PINCTRL_NOT_SUPPORT, ++ .smt_offset = MTK_PINCTRL_NOT_SUPPORT, ++ .pullen_offset = (MT6397_PIN_REG_BASE + 0x020), ++ .pullsel_offset = (MT6397_PIN_REG_BASE + 0x040), ++ .dout_offset = (MT6397_PIN_REG_BASE + 0x080), ++ .din_offset = (MT6397_PIN_REG_BASE + 0x0a0), ++ .pinmux_offset = (MT6397_PIN_REG_BASE + 0x0c0), ++ .type1_start = 41, ++ .type1_end = 41, ++ .port_shf = 3, ++ .port_mask = 0x3, ++ .port_align = 2, ++}; ++ ++static int mt6397_pinctrl_probe(struct platform_device *pdev) ++{ ++ struct mt6397_chip *mt6397; ++ ++ mt6397 = dev_get_drvdata(pdev->dev.parent); ++ return mtk_pctrl_init(pdev, &mt6397_pinctrl_data, mt6397->regmap); ++} ++ ++static const struct of_device_id mt6397_pctrl_match[] = { ++ { .compatible = "mediatek,mt6397-pinctrl", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, mt6397_pctrl_match); ++ ++static struct platform_driver mtk_pinctrl_driver = { ++ .probe = mt6397_pinctrl_probe, ++ .driver = { ++ .name = "mediatek-mt6397-pinctrl", ++ .owner = THIS_MODULE, ++ .of_match_table = mt6397_pctrl_match, ++ }, ++}; ++ ++static int __init mtk_pinctrl_init(void) ++{ ++ return platform_driver_register(&mtk_pinctrl_driver); ++} ++ ++module_init(mtk_pinctrl_init); ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_DESCRIPTION("MediaTek MT6397 Pinctrl Driver"); ++MODULE_AUTHOR("Hongzhou Yang <hongzhou.yang@mediatek.com>"); +diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8135.c b/drivers/pinctrl/mediatek/pinctrl-mt8135.c +index 8e6abd5..203bd2a 100644 +--- a/drivers/pinctrl/mediatek/pinctrl-mt8135.c ++++ b/drivers/pinctrl/mediatek/pinctrl-mt8135.c +@@ -342,7 +342,7 @@ static const struct mtk_pinctrl_devdata mt8135_pinctrl_data = { + + static int mt8135_pinctrl_probe(struct platform_device *pdev) + { +- return mtk_pctrl_init(pdev, &mt8135_pinctrl_data); ++ return mtk_pctrl_init(pdev, &mt8135_pinctrl_data, NULL); + } + + static const struct of_device_id mt8135_pctrl_match[] = { +diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8173.c b/drivers/pinctrl/mediatek/pinctrl-mt8173.c +index a7e5b24..cf4ed6e 100644 +--- a/drivers/pinctrl/mediatek/pinctrl-mt8173.c ++++ b/drivers/pinctrl/mediatek/pinctrl-mt8173.c +@@ -361,7 +361,7 @@ static const struct mtk_pinctrl_devdata mt8173_pinctrl_data = { + + static int mt8173_pinctrl_probe(struct platform_device *pdev) + { +- return mtk_pctrl_init(pdev, &mt8173_pinctrl_data); ++ return mtk_pctrl_init(pdev, &mt8173_pinctrl_data, NULL); + } + + static const struct of_device_id mt8173_pctrl_match[] = { +diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c +index 97fe2ab..e772cef 100644 +--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.c ++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.c +@@ -1209,7 +1209,8 @@ static struct pinctrl_desc mtk_pctrl_desc = { + }; + + int mtk_pctrl_init(struct platform_device *pdev, +- const struct mtk_pinctrl_devdata *data) ++ const struct mtk_pinctrl_devdata *data, ++ struct regmap *regmap) + { + struct pinctrl_pin_desc *pins; + struct mtk_pinctrl *pctl; +@@ -1235,6 +1236,11 @@ int mtk_pctrl_init(struct platform_device *pdev, + pctl->regmap1 = syscon_node_to_regmap(node); + if (IS_ERR(pctl->regmap1)) + return PTR_ERR(pctl->regmap1); ++ } else if (regmap) { ++ pctl->regmap1 = regmap; ++ } else { ++ dev_err(&pdev->dev, "Pinctrl node has not register regmap.\n"); ++ return -EINVAL; + } + + /* Only 8135 has two base addr, other SoCs have only one. */ +@@ -1280,7 +1286,7 @@ int mtk_pctrl_init(struct platform_device *pdev, + pctl->chip->ngpio = pctl->devdata->npins; + pctl->chip->label = dev_name(&pdev->dev); + pctl->chip->dev = &pdev->dev; +- pctl->chip->base = 0; ++ pctl->chip->base = -1; + + ret = gpiochip_add(pctl->chip); + if (ret) { +@@ -1296,6 +1302,9 @@ int mtk_pctrl_init(struct platform_device *pdev, + goto chip_error; + } + ++ if (of_find_property(np, "interrupt-controller", NULL)) ++ return 0; ++ + /* Get EINT register base from dts. */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { +diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h +index c703e7d..30213e5 100644 +--- a/drivers/pinctrl/mediatek/pinctrl-mtk-common.h ++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-common.h +@@ -269,7 +269,8 @@ struct mtk_pinctrl { + }; + + int mtk_pctrl_init(struct platform_device *pdev, +- const struct mtk_pinctrl_devdata *data); ++ const struct mtk_pinctrl_devdata *data, ++ struct regmap *regmap); + + int mtk_pctrl_spec_pull_set_samereg(struct regmap *regmap, + const struct mtk_pin_spec_pupd_set_samereg *pupd_infos, +diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-mt6397.h b/drivers/pinctrl/mediatek/pinctrl-mtk-mt6397.h +new file mode 100644 +index 0000000..4eb98dd +--- /dev/null ++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-mt6397.h +@@ -0,0 +1,424 @@ ++#ifndef __PINCTRL_MTK_MT6397_H ++#define __PINCTRL_MTK_MT6397_H ++ ++#include <linux/pinctrl/pinctrl.h> ++#include "pinctrl-mtk-common.h" ++ ++static const struct mtk_desc_pin mtk_pins_mt6397[] = { ++ MTK_PIN( ++ PINCTRL_PIN(0, "INT"), ++ "N2", "mt6397", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO0"), ++ MTK_FUNCTION(1, "INT") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(1, "SRCVOLTEN"), ++ "M4", "mt6397", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO1"), ++ MTK_FUNCTION(1, "SRCVOLTEN"), ++ MTK_FUNCTION(6, "TEST_CK1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(2, "SRCLKEN_PERI"), ++ "M2", "mt6397", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO2"), ++ MTK_FUNCTION(1, "SRCLKEN_PERI"), ++ MTK_FUNCTION(6, "TEST_CK2") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(3, "RTC_32K1V8"), ++ "K3", "mt6397", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO3"), ++ MTK_FUNCTION(1, "RTC_32K1V8"), ++ MTK_FUNCTION(6, "TEST_CK3") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(4, "WRAP_EVENT"), ++ "J2", "mt6397", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO4"), ++ MTK_FUNCTION(1, "WRAP_EVENT") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(5, "SPI_CLK"), ++ "L4", "mt6397", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO5"), ++ MTK_FUNCTION(1, "SPI_CLK") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(6, "SPI_CSN"), ++ "J3", "mt6397", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO6"), ++ MTK_FUNCTION(1, "SPI_CSN") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(7, "SPI_MOSI"), ++ "J1", "mt6397", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO7"), ++ MTK_FUNCTION(1, "SPI_MOSI") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(8, "SPI_MISO"), ++ "L3", "mt6397", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO8"), ++ MTK_FUNCTION(1, "SPI_MISO") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(9, "AUD_CLK_MOSI"), ++ "H2", "mt6397", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO9"), ++ MTK_FUNCTION(1, "AUD_CLK"), ++ MTK_FUNCTION(6, "TEST_IN0"), ++ MTK_FUNCTION(7, "TEST_OUT0") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(10, "AUD_DAT_MISO"), ++ "H3", "mt6397", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO10"), ++ MTK_FUNCTION(1, "AUD_MISO"), ++ MTK_FUNCTION(6, "TEST_IN1"), ++ MTK_FUNCTION(7, "TEST_OUT1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(11, "AUD_DAT_MOSI"), ++ "H1", "mt6397", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO11"), ++ MTK_FUNCTION(1, "AUD_MOSI"), ++ MTK_FUNCTION(6, "TEST_IN2"), ++ MTK_FUNCTION(7, "TEST_OUT2") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(12, "COL0"), ++ "F3", "mt6397", ++ MTK_EINT_FUNCTION(2, 10), ++ MTK_FUNCTION(0, "GPIO12"), ++ MTK_FUNCTION(1, "COL0_USBDL"), ++ MTK_FUNCTION(2, "EINT10_1X"), ++ MTK_FUNCTION(3, "PWM1_3X"), ++ MTK_FUNCTION(6, "TEST_IN3"), ++ MTK_FUNCTION(7, "TEST_OUT3") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(13, "COL1"), ++ "G8", "mt6397", ++ MTK_EINT_FUNCTION(2, 11), ++ MTK_FUNCTION(0, "GPIO13"), ++ MTK_FUNCTION(1, "COL1"), ++ MTK_FUNCTION(2, "EINT11_1X"), ++ MTK_FUNCTION(3, "SCL0_2X"), ++ MTK_FUNCTION(6, "TEST_IN4"), ++ MTK_FUNCTION(7, "TEST_OUT4") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(14, "COL2"), ++ "H4", "mt6397", ++ MTK_EINT_FUNCTION(2, 12), ++ MTK_FUNCTION(0, "GPIO14"), ++ MTK_FUNCTION(1, "COL2"), ++ MTK_FUNCTION(2, "EINT12_1X"), ++ MTK_FUNCTION(3, "SDA0_2X"), ++ MTK_FUNCTION(6, "TEST_IN5"), ++ MTK_FUNCTION(7, "TEST_OUT5") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(15, "COL3"), ++ "G2", "mt6397", ++ MTK_EINT_FUNCTION(2, 13), ++ MTK_FUNCTION(0, "GPIO15"), ++ MTK_FUNCTION(1, "COL3"), ++ MTK_FUNCTION(2, "EINT13_1X"), ++ MTK_FUNCTION(3, "SCL1_2X"), ++ MTK_FUNCTION(6, "TEST_IN6"), ++ MTK_FUNCTION(7, "TEST_OUT6") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(16, "COL4"), ++ "F2", "mt6397", ++ MTK_EINT_FUNCTION(2, 14), ++ MTK_FUNCTION(0, "GPIO16"), ++ MTK_FUNCTION(1, "COL4"), ++ MTK_FUNCTION(2, "EINT14_1X"), ++ MTK_FUNCTION(3, "SDA1_2X"), ++ MTK_FUNCTION(6, "TEST_IN7"), ++ MTK_FUNCTION(7, "TEST_OUT7") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(17, "COL5"), ++ "G7", "mt6397", ++ MTK_EINT_FUNCTION(2, 15), ++ MTK_FUNCTION(0, "GPIO17"), ++ MTK_FUNCTION(1, "COL5"), ++ MTK_FUNCTION(2, "EINT15_1X"), ++ MTK_FUNCTION(3, "SCL2_2X"), ++ MTK_FUNCTION(6, "TEST_IN8"), ++ MTK_FUNCTION(7, "TEST_OUT8") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(18, "COL6"), ++ "J6", "mt6397", ++ MTK_EINT_FUNCTION(2, 16), ++ MTK_FUNCTION(0, "GPIO18"), ++ MTK_FUNCTION(1, "COL6"), ++ MTK_FUNCTION(2, "EINT16_1X"), ++ MTK_FUNCTION(3, "SDA2_2X"), ++ MTK_FUNCTION(4, "GPIO32K_0"), ++ MTK_FUNCTION(5, "GPIO26M_0"), ++ MTK_FUNCTION(6, "TEST_IN9"), ++ MTK_FUNCTION(7, "TEST_OUT9") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(19, "COL7"), ++ "J5", "mt6397", ++ MTK_EINT_FUNCTION(2, 17), ++ MTK_FUNCTION(0, "GPIO19"), ++ MTK_FUNCTION(1, "COL7"), ++ MTK_FUNCTION(2, "EINT17_1X"), ++ MTK_FUNCTION(3, "PWM2_3X"), ++ MTK_FUNCTION(4, "GPIO32K_1"), ++ MTK_FUNCTION(5, "GPIO26M_1"), ++ MTK_FUNCTION(6, "TEST_IN10"), ++ MTK_FUNCTION(7, "TEST_OUT10") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(20, "ROW0"), ++ "L7", "mt6397", ++ MTK_EINT_FUNCTION(2, 18), ++ MTK_FUNCTION(0, "GPIO20"), ++ MTK_FUNCTION(1, "ROW0"), ++ MTK_FUNCTION(2, "EINT18_1X"), ++ MTK_FUNCTION(3, "SCL0_3X"), ++ MTK_FUNCTION(6, "TEST_IN11"), ++ MTK_FUNCTION(7, "TEST_OUT11") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(21, "ROW1"), ++ "P1", "mt6397", ++ MTK_EINT_FUNCTION(2, 19), ++ MTK_FUNCTION(0, "GPIO21"), ++ MTK_FUNCTION(1, "ROW1"), ++ MTK_FUNCTION(2, "EINT19_1X"), ++ MTK_FUNCTION(3, "SDA0_3X"), ++ MTK_FUNCTION(4, "AUD_TSTCK"), ++ MTK_FUNCTION(6, "TEST_IN12"), ++ MTK_FUNCTION(7, "TEST_OUT12") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(22, "ROW2"), ++ "J8", "mt6397", ++ MTK_EINT_FUNCTION(2, 20), ++ MTK_FUNCTION(0, "GPIO22"), ++ MTK_FUNCTION(1, "ROW2"), ++ MTK_FUNCTION(2, "EINT20_1X"), ++ MTK_FUNCTION(3, "SCL1_3X"), ++ MTK_FUNCTION(6, "TEST_IN13"), ++ MTK_FUNCTION(7, "TEST_OUT13") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(23, "ROW3"), ++ "J7", "mt6397", ++ MTK_EINT_FUNCTION(2, 21), ++ MTK_FUNCTION(0, "GPIO23"), ++ MTK_FUNCTION(1, "ROW3"), ++ MTK_FUNCTION(2, "EINT21_1X"), ++ MTK_FUNCTION(3, "SDA1_3X"), ++ MTK_FUNCTION(6, "TEST_IN14"), ++ MTK_FUNCTION(7, "TEST_OUT14") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(24, "ROW4"), ++ "L5", "mt6397", ++ MTK_EINT_FUNCTION(2, 22), ++ MTK_FUNCTION(0, "GPIO24"), ++ MTK_FUNCTION(1, "ROW4"), ++ MTK_FUNCTION(2, "EINT22_1X"), ++ MTK_FUNCTION(3, "SCL2_3X"), ++ MTK_FUNCTION(6, "TEST_IN15"), ++ MTK_FUNCTION(7, "TEST_OUT15") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(25, "ROW5"), ++ "N6", "mt6397", ++ MTK_EINT_FUNCTION(2, 23), ++ MTK_FUNCTION(0, "GPIO25"), ++ MTK_FUNCTION(1, "ROW5"), ++ MTK_FUNCTION(2, "EINT23_1X"), ++ MTK_FUNCTION(3, "SDA2_3X"), ++ MTK_FUNCTION(6, "TEST_IN16"), ++ MTK_FUNCTION(7, "TEST_OUT16") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(26, "ROW6"), ++ "L6", "mt6397", ++ MTK_EINT_FUNCTION(2, 24), ++ MTK_FUNCTION(0, "GPIO26"), ++ MTK_FUNCTION(1, "ROW6"), ++ MTK_FUNCTION(2, "EINT24_1X"), ++ MTK_FUNCTION(3, "PWM3_3X"), ++ MTK_FUNCTION(4, "GPIO32K_2"), ++ MTK_FUNCTION(5, "GPIO26M_2"), ++ MTK_FUNCTION(6, "TEST_IN17"), ++ MTK_FUNCTION(7, "TEST_OUT17") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(27, "ROW7"), ++ "P2", "mt6397", ++ MTK_EINT_FUNCTION(2, 3), ++ MTK_FUNCTION(0, "GPIO27"), ++ MTK_FUNCTION(1, "ROW7"), ++ MTK_FUNCTION(2, "EINT3_1X"), ++ MTK_FUNCTION(3, "CBUS"), ++ MTK_FUNCTION(4, "GPIO32K_3"), ++ MTK_FUNCTION(5, "GPIO26M_3"), ++ MTK_FUNCTION(6, "TEST_IN18"), ++ MTK_FUNCTION(7, "TEST_OUT18") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(28, "PWM1(VMSEL1)"), ++ "J4", "mt6397", ++ MTK_EINT_FUNCTION(2, 4), ++ MTK_FUNCTION(0, "GPIO28"), ++ MTK_FUNCTION(1, "PWM1"), ++ MTK_FUNCTION(2, "EINT4_1X"), ++ MTK_FUNCTION(4, "GPIO32K_4"), ++ MTK_FUNCTION(5, "GPIO26M_4"), ++ MTK_FUNCTION(6, "TEST_IN19"), ++ MTK_FUNCTION(7, "TEST_OUT19") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(29, "PWM2(VMSEL2)"), ++ "N5", "mt6397", ++ MTK_EINT_FUNCTION(2, 5), ++ MTK_FUNCTION(0, "GPIO29"), ++ MTK_FUNCTION(1, "PWM2"), ++ MTK_FUNCTION(2, "EINT5_1X"), ++ MTK_FUNCTION(4, "GPIO32K_5"), ++ MTK_FUNCTION(5, "GPIO26M_5"), ++ MTK_FUNCTION(6, "TEST_IN20"), ++ MTK_FUNCTION(7, "TEST_OUT20") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(30, "PWM3(PWM)"), ++ "R3", "mt6397", ++ MTK_EINT_FUNCTION(2, 6), ++ MTK_FUNCTION(0, "GPIO30"), ++ MTK_FUNCTION(1, "PWM3"), ++ MTK_FUNCTION(2, "EINT6_1X"), ++ MTK_FUNCTION(3, "COL0"), ++ MTK_FUNCTION(4, "GPIO32K_6"), ++ MTK_FUNCTION(5, "GPIO26M_6"), ++ MTK_FUNCTION(6, "TEST_IN21"), ++ MTK_FUNCTION(7, "TEST_OUT21") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(31, "SCL0"), ++ "N1", "mt6397", ++ MTK_EINT_FUNCTION(2, 7), ++ MTK_FUNCTION(0, "GPIO31"), ++ MTK_FUNCTION(1, "SCL0"), ++ MTK_FUNCTION(2, "EINT7_1X"), ++ MTK_FUNCTION(3, "PWM1_2X"), ++ MTK_FUNCTION(6, "TEST_IN22"), ++ MTK_FUNCTION(7, "TEST_OUT22") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(32, "SDA0"), ++ "N3", "mt6397", ++ MTK_EINT_FUNCTION(2, 8), ++ MTK_FUNCTION(0, "GPIO32"), ++ MTK_FUNCTION(1, "SDA0"), ++ MTK_FUNCTION(2, "EINT8_1X"), ++ MTK_FUNCTION(6, "TEST_IN23"), ++ MTK_FUNCTION(7, "TEST_OUT23") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(33, "SCL1"), ++ "T1", "mt6397", ++ MTK_EINT_FUNCTION(2, 9), ++ MTK_FUNCTION(0, "GPIO33"), ++ MTK_FUNCTION(1, "SCL1"), ++ MTK_FUNCTION(2, "EINT9_1X"), ++ MTK_FUNCTION(3, "PWM2_2X"), ++ MTK_FUNCTION(6, "TEST_IN24"), ++ MTK_FUNCTION(7, "TEST_OUT24") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(34, "SDA1"), ++ "T2", "mt6397", ++ MTK_EINT_FUNCTION(2, 0), ++ MTK_FUNCTION(0, "GPIO34"), ++ MTK_FUNCTION(1, "SDA1"), ++ MTK_FUNCTION(2, "EINT0_1X"), ++ MTK_FUNCTION(6, "TEST_IN25"), ++ MTK_FUNCTION(7, "TEST_OUT25") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(35, "SCL2"), ++ "T3", "mt6397", ++ MTK_EINT_FUNCTION(2, 1), ++ MTK_FUNCTION(0, "GPIO35"), ++ MTK_FUNCTION(1, "SCL2"), ++ MTK_FUNCTION(2, "EINT1_1X"), ++ MTK_FUNCTION(3, "PWM3_2X"), ++ MTK_FUNCTION(6, "TEST_IN26"), ++ MTK_FUNCTION(7, "TEST_OUT26") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(36, "SDA2"), ++ "U2", "mt6397", ++ MTK_EINT_FUNCTION(2, 2), ++ MTK_FUNCTION(0, "GPIO36"), ++ MTK_FUNCTION(1, "SDA2"), ++ MTK_FUNCTION(2, "EINT2_1X"), ++ MTK_FUNCTION(6, "TEST_IN27"), ++ MTK_FUNCTION(7, "TEST_OUT27") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(37, "HDMISD"), ++ "H6", "mt6397", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO37"), ++ MTK_FUNCTION(1, "HDMISD"), ++ MTK_FUNCTION(6, "TEST_IN28"), ++ MTK_FUNCTION(7, "TEST_OUT28") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(38, "HDMISCK"), ++ "H5", "mt6397", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO38"), ++ MTK_FUNCTION(1, "HDMISCK"), ++ MTK_FUNCTION(6, "TEST_IN29"), ++ MTK_FUNCTION(7, "TEST_OUT29") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(39, "HTPLG"), ++ "H7", "mt6397", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO39"), ++ MTK_FUNCTION(1, "HTPLG"), ++ MTK_FUNCTION(6, "TEST_IN30"), ++ MTK_FUNCTION(7, "TEST_OUT30") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(40, "CEC"), ++ "J9", "mt6397", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO40"), ++ MTK_FUNCTION(1, "CEC"), ++ MTK_FUNCTION(6, "TEST_IN31"), ++ MTK_FUNCTION(7, "TEST_OUT31") ++ ), ++}; ++ ++#endif /* __PINCTRL_MTK_MT6397_H */ +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0054-pinctrl-mediatek-add-pinctrl-GPIO-EINT-driver-for-mt.patch b/target/linux/mediatek/patches/0054-pinctrl-mediatek-add-pinctrl-GPIO-EINT-driver-for-mt.patch new file mode 100644 index 0000000000..763037ceaa --- /dev/null +++ b/target/linux/mediatek/patches/0054-pinctrl-mediatek-add-pinctrl-GPIO-EINT-driver-for-mt.patch @@ -0,0 +1,1740 @@ +From 0fabcb34ad6506e9d8dadf373f4ebfe1b5129765 Mon Sep 17 00:00:00 2001 +From: Yingjoe Chen <yingjoe.chen@mediatek.com> +Date: Mon, 18 May 2015 23:11:18 -0700 +Subject: [PATCH 54/76] pinctrl: mediatek: add pinctrl/GPIO/EINT driver for + mt8127 + +MT8127 pinctrl/eint are similar to mt8135 and mt8173, add +support for mt8127 using mediatek common pinctrl driver. + +Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com> +Signed-off-by: Hongzhou Yang <hongzhou.yang@mediatek.com> +--- + drivers/pinctrl/mediatek/Kconfig | 6 + + drivers/pinctrl/mediatek/Makefile | 1 + + drivers/pinctrl/mediatek/pinctrl-mt8127.c | 359 +++++++ + drivers/pinctrl/mediatek/pinctrl-mtk-mt8127.h | 1318 +++++++++++++++++++++++++ + 4 files changed, 1684 insertions(+) + create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt8127.c + create mode 100644 drivers/pinctrl/mediatek/pinctrl-mtk-mt8127.h + +diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig +index ddae479..0bc84fb 100644 +--- a/drivers/pinctrl/mediatek/Kconfig ++++ b/drivers/pinctrl/mediatek/Kconfig +@@ -15,6 +15,12 @@ config PINCTRL_MT8135 + default MACH_MT8135 + select PINCTRL_MTK_COMMON + ++config PINCTRL_MT8127 ++ bool "Mediatek MT8127 pin control" if COMPILE_TEST && !MACH_MT8127 ++ depends on OF ++ default MACH_MT8127 ++ select PINCTRL_MTK_COMMON ++ + # For ARMv8 SoCs + config PINCTRL_MT8173 + bool "Mediatek MT8173 pin control" +diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile +index ad0180c..eb923d6 100644 +--- a/drivers/pinctrl/mediatek/Makefile ++++ b/drivers/pinctrl/mediatek/Makefile +@@ -3,5 +3,6 @@ obj-$(CONFIG_PINCTRL_MTK_COMMON) += pinctrl-mtk-common.o + + # SoC Drivers + obj-$(CONFIG_PINCTRL_MT8135) += pinctrl-mt8135.o ++obj-$(CONFIG_PINCTRL_MT8127) += pinctrl-mt8127.o + obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o + obj-$(CONFIG_PINCTRL_MT6397) += pinctrl-mt6397.o +diff --git a/drivers/pinctrl/mediatek/pinctrl-mt8127.c b/drivers/pinctrl/mediatek/pinctrl-mt8127.c +new file mode 100644 +index 0000000..6a26cfa +--- /dev/null ++++ b/drivers/pinctrl/mediatek/pinctrl-mt8127.c +@@ -0,0 +1,359 @@ ++/* ++ * Copyright (c) 2015 MediaTek Inc. ++ * Author: Hongzhou.Yang <hongzhou.yang@mediatek.com> ++ * Yingjoe Chen <yingjoe.chen@mediatek.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/module.h> ++#include <linux/platform_device.h> ++#include <linux/of.h> ++#include <linux/of_device.h> ++#include <linux/pinctrl/pinctrl.h> ++#include <linux/regmap.h> ++#include <dt-bindings/pinctrl/mt65xx.h> ++ ++#include "pinctrl-mtk-common.h" ++#include "pinctrl-mtk-mt8127.h" ++ ++static const struct mtk_drv_group_desc mt8127_drv_grp[] = { ++ /* 0E4E8SR 4/8/12/16 */ ++ MTK_DRV_GRP(4, 16, 1, 2, 4), ++ /* 0E2E4SR 2/4/6/8 */ ++ MTK_DRV_GRP(2, 8, 1, 2, 2), ++ /* E8E4E2 2/4/6/8/10/12/14/16 */ ++ MTK_DRV_GRP(2, 16, 0, 2, 2) ++}; ++ ++static const struct mtk_pin_drv_grp mt8127_pin_drv[] = { ++ MTK_PIN_DRV_GRP(0, 0xb00, 0, 1), ++ MTK_PIN_DRV_GRP(1, 0xb00, 0, 1), ++ MTK_PIN_DRV_GRP(2, 0xb00, 0, 1), ++ MTK_PIN_DRV_GRP(3, 0xb00, 0, 1), ++ MTK_PIN_DRV_GRP(4, 0xb00, 0, 1), ++ MTK_PIN_DRV_GRP(5, 0xb00, 0, 1), ++ MTK_PIN_DRV_GRP(6, 0xb00, 0, 1), ++ MTK_PIN_DRV_GRP(7, 0xb00, 12, 1), ++ MTK_PIN_DRV_GRP(8, 0xb00, 12, 1), ++ MTK_PIN_DRV_GRP(9, 0xb00, 12, 1), ++ MTK_PIN_DRV_GRP(10, 0xb00, 8, 1), ++ MTK_PIN_DRV_GRP(11, 0xb00, 8, 1), ++ MTK_PIN_DRV_GRP(12, 0xb00, 8, 1), ++ MTK_PIN_DRV_GRP(13, 0xb00, 8, 1), ++ MTK_PIN_DRV_GRP(14, 0xb10, 4, 0), ++ MTK_PIN_DRV_GRP(15, 0xb10, 4, 0), ++ MTK_PIN_DRV_GRP(16, 0xb10, 4, 0), ++ MTK_PIN_DRV_GRP(17, 0xb10, 4, 0), ++ MTK_PIN_DRV_GRP(18, 0xb10, 8, 0), ++ MTK_PIN_DRV_GRP(19, 0xb10, 8, 0), ++ MTK_PIN_DRV_GRP(20, 0xb10, 8, 0), ++ MTK_PIN_DRV_GRP(21, 0xb10, 8, 0), ++ MTK_PIN_DRV_GRP(22, 0xb20, 0, 0), ++ MTK_PIN_DRV_GRP(23, 0xb20, 0, 0), ++ MTK_PIN_DRV_GRP(24, 0xb20, 0, 0), ++ MTK_PIN_DRV_GRP(25, 0xb20, 0, 0), ++ MTK_PIN_DRV_GRP(26, 0xb20, 0, 0), ++ MTK_PIN_DRV_GRP(27, 0xb20, 4, 0), ++ MTK_PIN_DRV_GRP(28, 0xb20, 4, 0), ++ MTK_PIN_DRV_GRP(29, 0xb20, 4, 0), ++ MTK_PIN_DRV_GRP(30, 0xb20, 4, 0), ++ MTK_PIN_DRV_GRP(31, 0xb20, 4, 0), ++ MTK_PIN_DRV_GRP(32, 0xb20, 4, 0), ++ MTK_PIN_DRV_GRP(33, 0xb30, 4, 1), ++ MTK_PIN_DRV_GRP(34, 0xb30, 8, 1), ++ MTK_PIN_DRV_GRP(35, 0xb30, 8, 1), ++ MTK_PIN_DRV_GRP(36, 0xb30, 8, 1), ++ MTK_PIN_DRV_GRP(37, 0xb30, 8, 1), ++ MTK_PIN_DRV_GRP(38, 0xb30, 8, 1), ++ MTK_PIN_DRV_GRP(39, 0xb30, 12, 1), ++ MTK_PIN_DRV_GRP(40, 0xb30, 12, 1), ++ MTK_PIN_DRV_GRP(41, 0xb30, 12, 1), ++ MTK_PIN_DRV_GRP(42, 0xb30, 12, 1), ++ MTK_PIN_DRV_GRP(43, 0xb40, 12, 0), ++ MTK_PIN_DRV_GRP(44, 0xb40, 12, 0), ++ MTK_PIN_DRV_GRP(45, 0xb40, 12, 0), ++ MTK_PIN_DRV_GRP(46, 0xb50, 0, 2), ++ MTK_PIN_DRV_GRP(47, 0xb50, 0, 2), ++ MTK_PIN_DRV_GRP(48, 0xb50, 0, 2), ++ MTK_PIN_DRV_GRP(49, 0xb50, 0, 2), ++ MTK_PIN_DRV_GRP(50, 0xb70, 0, 1), ++ MTK_PIN_DRV_GRP(51, 0xb70, 0, 1), ++ MTK_PIN_DRV_GRP(52, 0xb70, 0, 1), ++ MTK_PIN_DRV_GRP(53, 0xb50, 12, 1), ++ MTK_PIN_DRV_GRP(54, 0xb50, 12, 1), ++ MTK_PIN_DRV_GRP(55, 0xb50, 12, 1), ++ MTK_PIN_DRV_GRP(56, 0xb50, 12, 1), ++ MTK_PIN_DRV_GRP(59, 0xb40, 4, 1), ++ MTK_PIN_DRV_GRP(60, 0xb40, 0, 1), ++ MTK_PIN_DRV_GRP(61, 0xb40, 0, 1), ++ MTK_PIN_DRV_GRP(62, 0xb40, 0, 1), ++ MTK_PIN_DRV_GRP(63, 0xb40, 4, 1), ++ MTK_PIN_DRV_GRP(64, 0xb40, 4, 1), ++ MTK_PIN_DRV_GRP(65, 0xb40, 4, 1), ++ MTK_PIN_DRV_GRP(66, 0xb40, 8, 1), ++ MTK_PIN_DRV_GRP(67, 0xb40, 8, 1), ++ MTK_PIN_DRV_GRP(68, 0xb40, 8, 1), ++ MTK_PIN_DRV_GRP(69, 0xb40, 8, 1), ++ MTK_PIN_DRV_GRP(70, 0xb40, 8, 1), ++ MTK_PIN_DRV_GRP(71, 0xb40, 8, 1), ++ MTK_PIN_DRV_GRP(72, 0xb50, 4, 1), ++ MTK_PIN_DRV_GRP(73, 0xb50, 4, 1), ++ MTK_PIN_DRV_GRP(74, 0xb50, 4, 1), ++ MTK_PIN_DRV_GRP(79, 0xb50, 8, 1), ++ MTK_PIN_DRV_GRP(80, 0xb50, 8, 1), ++ MTK_PIN_DRV_GRP(81, 0xb50, 8, 1), ++ MTK_PIN_DRV_GRP(82, 0xb50, 8, 1), ++ MTK_PIN_DRV_GRP(83, 0xb50, 8, 1), ++ MTK_PIN_DRV_GRP(84, 0xb50, 8, 1), ++ MTK_PIN_DRV_GRP(85, 0xce0, 0, 2), ++ MTK_PIN_DRV_GRP(86, 0xcd0, 0, 2), ++ MTK_PIN_DRV_GRP(87, 0xcf0, 0, 2), ++ MTK_PIN_DRV_GRP(88, 0xcf0, 0, 2), ++ MTK_PIN_DRV_GRP(89, 0xcf0, 0, 2), ++ MTK_PIN_DRV_GRP(90, 0xcf0, 0, 2), ++ MTK_PIN_DRV_GRP(117, 0xb60, 12, 1), ++ MTK_PIN_DRV_GRP(118, 0xb60, 12, 1), ++ MTK_PIN_DRV_GRP(119, 0xb60, 12, 1), ++ MTK_PIN_DRV_GRP(120, 0xb60, 12, 1), ++ MTK_PIN_DRV_GRP(121, 0xc80, 0, 2), ++ MTK_PIN_DRV_GRP(122, 0xc70, 0, 2), ++ MTK_PIN_DRV_GRP(123, 0xc90, 0, 2), ++ MTK_PIN_DRV_GRP(124, 0xc90, 0, 2), ++ MTK_PIN_DRV_GRP(125, 0xc90, 0, 2), ++ MTK_PIN_DRV_GRP(126, 0xc90, 0, 2), ++ MTK_PIN_DRV_GRP(127, 0xc20, 0, 2), ++ MTK_PIN_DRV_GRP(128, 0xc20, 0, 2), ++ MTK_PIN_DRV_GRP(129, 0xc20, 0, 2), ++ MTK_PIN_DRV_GRP(130, 0xc20, 0, 2), ++ MTK_PIN_DRV_GRP(131, 0xc20, 0, 2), ++ MTK_PIN_DRV_GRP(132, 0xc10, 0, 2), ++ MTK_PIN_DRV_GRP(133, 0xc00, 0, 2), ++ MTK_PIN_DRV_GRP(134, 0xc20, 0, 2), ++ MTK_PIN_DRV_GRP(135, 0xc20, 0, 2), ++ MTK_PIN_DRV_GRP(136, 0xc20, 0, 2), ++ MTK_PIN_DRV_GRP(137, 0xc20, 0, 2), ++ MTK_PIN_DRV_GRP(142, 0xb50, 0, 2), ++}; ++ ++static const struct mtk_pin_spec_pupd_set_samereg mt8127_spec_pupd[] = { ++ MTK_PIN_PUPD_SPEC_SR(33, 0xd90, 2, 0, 1), /* KPROW0 */ ++ MTK_PIN_PUPD_SPEC_SR(34, 0xd90, 6, 4, 5), /* KPROW1 */ ++ MTK_PIN_PUPD_SPEC_SR(35, 0xd90, 10, 8, 9), /* KPROW2 */ ++ MTK_PIN_PUPD_SPEC_SR(36, 0xda0, 2, 0, 1), /* KPCOL0 */ ++ MTK_PIN_PUPD_SPEC_SR(37, 0xda0, 6, 4, 5), /* KPCOL1 */ ++ MTK_PIN_PUPD_SPEC_SR(38, 0xda0, 10, 8, 9), /* KPCOL2 */ ++ MTK_PIN_PUPD_SPEC_SR(46, 0xdb0, 2, 0, 1), /* EINT14 */ ++ MTK_PIN_PUPD_SPEC_SR(47, 0xdb0, 6, 4, 5), /* EINT15 */ ++ MTK_PIN_PUPD_SPEC_SR(48, 0xdb0, 10, 8, 9), /* EINT16 */ ++ MTK_PIN_PUPD_SPEC_SR(49, 0xdb0, 14, 12, 13), /* EINT17 */ ++ MTK_PIN_PUPD_SPEC_SR(85, 0xce0, 8, 10, 9), /* MSDC2_CMD */ ++ MTK_PIN_PUPD_SPEC_SR(86, 0xcd0, 8, 10, 9), /* MSDC2_CLK */ ++ MTK_PIN_PUPD_SPEC_SR(87, 0xd00, 0, 2, 1), /* MSDC2_DAT0 */ ++ MTK_PIN_PUPD_SPEC_SR(88, 0xd00, 4, 6, 5), /* MSDC2_DAT1 */ ++ MTK_PIN_PUPD_SPEC_SR(89, 0xd00, 8, 10, 9), /* MSDC2_DAT2 */ ++ MTK_PIN_PUPD_SPEC_SR(90, 0xd00, 12, 14, 13), /* MSDC2_DAT3 */ ++ MTK_PIN_PUPD_SPEC_SR(121, 0xc80, 8, 10, 9), /* MSDC1_CMD */ ++ MTK_PIN_PUPD_SPEC_SR(122, 0xc70, 8, 10, 9), /* MSDC1_CLK */ ++ MTK_PIN_PUPD_SPEC_SR(123, 0xca0, 0, 2, 1), /* MSDC1_DAT0 */ ++ MTK_PIN_PUPD_SPEC_SR(124, 0xca0, 4, 6, 5), /* MSDC1_DAT1 */ ++ MTK_PIN_PUPD_SPEC_SR(125, 0xca0, 8, 10, 9), /* MSDC1_DAT2 */ ++ MTK_PIN_PUPD_SPEC_SR(126, 0xca0, 12, 14, 13), /* MSDC1_DAT3 */ ++ MTK_PIN_PUPD_SPEC_SR(127, 0xc40, 12, 14, 13), /* MSDC0_DAT7 */ ++ MTK_PIN_PUPD_SPEC_SR(128, 0xc40, 8, 10, 9), /* MSDC0_DAT6 */ ++ MTK_PIN_PUPD_SPEC_SR(129, 0xc40, 4, 6, 5), /* MSDC0_DAT5 */ ++ MTK_PIN_PUPD_SPEC_SR(130, 0xc40, 0, 2, 1), /* MSDC0_DAT4 */ ++ MTK_PIN_PUPD_SPEC_SR(131, 0xc50, 0, 2, 1), /* MSDC0_RSTB */ ++ MTK_PIN_PUPD_SPEC_SR(132, 0xc10, 8, 10, 9), /* MSDC0_CMD */ ++ MTK_PIN_PUPD_SPEC_SR(133, 0xc00, 8, 10, 9), /* MSDC0_CLK */ ++ MTK_PIN_PUPD_SPEC_SR(134, 0xc30, 12, 14, 13), /* MSDC0_DAT3 */ ++ MTK_PIN_PUPD_SPEC_SR(135, 0xc30, 8, 10, 9), /* MSDC0_DAT2 */ ++ MTK_PIN_PUPD_SPEC_SR(136, 0xc30, 4, 6, 5), /* MSDC0_DAT1 */ ++ MTK_PIN_PUPD_SPEC_SR(137, 0xc30, 0, 2, 1), /* MSDC0_DAT0 */ ++ MTK_PIN_PUPD_SPEC_SR(142, 0xdc0, 2, 0, 1), /* EINT21 */ ++}; ++ ++static int mt8127_spec_pull_set(struct regmap *regmap, unsigned int pin, ++ unsigned char align, bool isup, unsigned int r1r0) ++{ ++ return mtk_pctrl_spec_pull_set_samereg(regmap, mt8127_spec_pupd, ++ ARRAY_SIZE(mt8127_spec_pupd), pin, align, isup, r1r0); ++} ++ ++static const struct mtk_pin_ies_smt_set mt8127_ies_set[] = { ++ MTK_PIN_IES_SMT_SPEC(0, 9, 0x900, 0), ++ MTK_PIN_IES_SMT_SPEC(10, 13, 0x900, 1), ++ MTK_PIN_IES_SMT_SPEC(14, 28, 0x900, 2), ++ MTK_PIN_IES_SMT_SPEC(29, 32, 0x900, 3), ++ MTK_PIN_IES_SMT_SPEC(33, 33, 0x910, 11), ++ MTK_PIN_IES_SMT_SPEC(34, 38, 0x900, 10), ++ MTK_PIN_IES_SMT_SPEC(39, 42, 0x900, 11), ++ MTK_PIN_IES_SMT_SPEC(43, 45, 0x900, 12), ++ MTK_PIN_IES_SMT_SPEC(46, 49, 0x900, 13), ++ MTK_PIN_IES_SMT_SPEC(50, 52, 0x910, 10), ++ MTK_PIN_IES_SMT_SPEC(53, 56, 0x900, 14), ++ MTK_PIN_IES_SMT_SPEC(57, 58, 0x910, 0), ++ MTK_PIN_IES_SMT_SPEC(59, 65, 0x910, 2), ++ MTK_PIN_IES_SMT_SPEC(66, 71, 0x910, 3), ++ MTK_PIN_IES_SMT_SPEC(72, 74, 0x910, 4), ++ MTK_PIN_IES_SMT_SPEC(75, 76, 0x900, 15), ++ MTK_PIN_IES_SMT_SPEC(77, 78, 0x910, 1), ++ MTK_PIN_IES_SMT_SPEC(79, 82, 0x910, 5), ++ MTK_PIN_IES_SMT_SPEC(83, 84, 0x910, 6), ++ MTK_PIN_IES_SMT_SPEC(117, 120, 0x910, 7), ++ MTK_PIN_IES_SMT_SPEC(121, 121, 0xc80, 4), ++ MTK_PIN_IES_SMT_SPEC(122, 122, 0xc70, 4), ++ MTK_PIN_IES_SMT_SPEC(123, 126, 0xc90, 4), ++ MTK_PIN_IES_SMT_SPEC(127, 131, 0xc20, 4), ++ MTK_PIN_IES_SMT_SPEC(132, 132, 0xc10, 4), ++ MTK_PIN_IES_SMT_SPEC(133, 133, 0xc00, 4), ++ MTK_PIN_IES_SMT_SPEC(134, 137, 0xc20, 4), ++ MTK_PIN_IES_SMT_SPEC(138, 141, 0x910, 9), ++ MTK_PIN_IES_SMT_SPEC(142, 142, 0x900, 13), ++}; ++ ++static const struct mtk_pin_ies_smt_set mt8127_smt_set[] = { ++ MTK_PIN_IES_SMT_SPEC(0, 9, 0x920, 0), ++ MTK_PIN_IES_SMT_SPEC(10, 13, 0x920, 1), ++ MTK_PIN_IES_SMT_SPEC(14, 28, 0x920, 2), ++ MTK_PIN_IES_SMT_SPEC(29, 32, 0x920, 3), ++ MTK_PIN_IES_SMT_SPEC(33, 33, 0x930, 11), ++ MTK_PIN_IES_SMT_SPEC(34, 38, 0x920, 10), ++ MTK_PIN_IES_SMT_SPEC(39, 42, 0x920, 11), ++ MTK_PIN_IES_SMT_SPEC(43, 45, 0x920, 12), ++ MTK_PIN_IES_SMT_SPEC(46, 49, 0x920, 13), ++ MTK_PIN_IES_SMT_SPEC(50, 52, 0x930, 10), ++ MTK_PIN_IES_SMT_SPEC(53, 56, 0x920, 14), ++ MTK_PIN_IES_SMT_SPEC(57, 58, 0x930, 0), ++ MTK_PIN_IES_SMT_SPEC(59, 65, 0x930, 2), ++ MTK_PIN_IES_SMT_SPEC(66, 71, 0x930, 3), ++ MTK_PIN_IES_SMT_SPEC(72, 74, 0x930, 4), ++ MTK_PIN_IES_SMT_SPEC(75, 76, 0x920, 15), ++ MTK_PIN_IES_SMT_SPEC(77, 78, 0x930, 1), ++ MTK_PIN_IES_SMT_SPEC(79, 82, 0x930, 5), ++ MTK_PIN_IES_SMT_SPEC(83, 84, 0x930, 6), ++ MTK_PIN_IES_SMT_SPEC(85, 85, 0xce0, 11), ++ MTK_PIN_IES_SMT_SPEC(86, 86, 0xcd0, 11), ++ MTK_PIN_IES_SMT_SPEC(87, 87, 0xd00, 3), ++ MTK_PIN_IES_SMT_SPEC(88, 88, 0xd00, 7), ++ MTK_PIN_IES_SMT_SPEC(89, 89, 0xd00, 11), ++ MTK_PIN_IES_SMT_SPEC(90, 90, 0xd00, 15), ++ MTK_PIN_IES_SMT_SPEC(117, 120, 0x930, 7), ++ MTK_PIN_IES_SMT_SPEC(121, 121, 0xc80, 11), ++ MTK_PIN_IES_SMT_SPEC(122, 122, 0xc70, 11), ++ MTK_PIN_IES_SMT_SPEC(123, 123, 0xca0, 3), ++ MTK_PIN_IES_SMT_SPEC(124, 124, 0xca0, 7), ++ MTK_PIN_IES_SMT_SPEC(125, 125, 0xca0, 11), ++ MTK_PIN_IES_SMT_SPEC(126, 126, 0xca0, 15), ++ MTK_PIN_IES_SMT_SPEC(127, 127, 0xc40, 15), ++ MTK_PIN_IES_SMT_SPEC(128, 128, 0xc40, 11), ++ MTK_PIN_IES_SMT_SPEC(129, 129, 0xc40, 7), ++ MTK_PIN_IES_SMT_SPEC(130, 130, 0xc40, 3), ++ MTK_PIN_IES_SMT_SPEC(131, 131, 0xc50, 3), ++ MTK_PIN_IES_SMT_SPEC(132, 132, 0xc10, 11), ++ MTK_PIN_IES_SMT_SPEC(133, 133, 0xc00, 11), ++ MTK_PIN_IES_SMT_SPEC(134, 134, 0xc30, 15), ++ MTK_PIN_IES_SMT_SPEC(135, 135, 0xc30, 11), ++ MTK_PIN_IES_SMT_SPEC(136, 136, 0xc30, 7), ++ MTK_PIN_IES_SMT_SPEC(137, 137, 0xc30, 3), ++ MTK_PIN_IES_SMT_SPEC(138, 141, 0x930, 9), ++ MTK_PIN_IES_SMT_SPEC(142, 142, 0x920, 13), ++}; ++ ++static int mt8127_ies_smt_set(struct regmap *regmap, unsigned int pin, ++ unsigned char align, int value, enum pin_config_param arg) ++{ ++ if (arg == PIN_CONFIG_INPUT_ENABLE) ++ return mtk_pconf_spec_set_ies_smt_range(regmap, mt8127_ies_set, ++ ARRAY_SIZE(mt8127_ies_set), pin, align, value); ++ else if (arg == PIN_CONFIG_INPUT_SCHMITT_ENABLE) ++ return mtk_pconf_spec_set_ies_smt_range(regmap, mt8127_smt_set, ++ ARRAY_SIZE(mt8127_smt_set), pin, align, value); ++ return -EINVAL; ++} ++ ++ ++static const struct mtk_pinctrl_devdata mt8127_pinctrl_data = { ++ .pins = mtk_pins_mt8127, ++ .npins = ARRAY_SIZE(mtk_pins_mt8127), ++ .grp_desc = mt8127_drv_grp, ++ .n_grp_cls = ARRAY_SIZE(mt8127_drv_grp), ++ .pin_drv_grp = mt8127_pin_drv, ++ .n_pin_drv_grps = ARRAY_SIZE(mt8127_pin_drv), ++ .spec_pull_set = mt8127_spec_pull_set, ++ .spec_ies_smt_set = mt8127_ies_smt_set, ++ .dir_offset = 0x0000, ++ .pullen_offset = 0x0100, ++ .pullsel_offset = 0x0200, ++ .dout_offset = 0x0400, ++ .din_offset = 0x0500, ++ .pinmux_offset = 0x0600, ++ .type1_start = 143, ++ .type1_end = 143, ++ .port_shf = 4, ++ .port_mask = 0xf, ++ .port_align = 4, ++ .eint_offsets = { ++ .name = "mt8127_eint", ++ .stat = 0x000, ++ .ack = 0x040, ++ .mask = 0x080, ++ .mask_set = 0x0c0, ++ .mask_clr = 0x100, ++ .sens = 0x140, ++ .sens_set = 0x180, ++ .sens_clr = 0x1c0, ++ .soft = 0x200, ++ .soft_set = 0x240, ++ .soft_clr = 0x280, ++ .pol = 0x300, ++ .pol_set = 0x340, ++ .pol_clr = 0x380, ++ .dom_en = 0x400, ++ .dbnc_ctrl = 0x500, ++ .dbnc_set = 0x600, ++ .dbnc_clr = 0x700, ++ .port_mask = 7, ++ .ports = 6, ++ }, ++ .ap_num = 143, ++ .db_cnt = 16, ++}; ++ ++static int mt8127_pinctrl_probe(struct platform_device *pdev) ++{ ++ return mtk_pctrl_init(pdev, &mt8127_pinctrl_data, NULL); ++} ++ ++static const struct of_device_id mt8127_pctrl_match[] = { ++ { .compatible = "mediatek,mt8127-pinctrl", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, mt8127_pctrl_match); ++ ++static struct platform_driver mtk_pinctrl_driver = { ++ .probe = mt8127_pinctrl_probe, ++ .driver = { ++ .name = "mediatek-mt8127-pinctrl", ++ .owner = THIS_MODULE, ++ .of_match_table = mt8127_pctrl_match, ++ }, ++}; ++ ++static int __init mtk_pinctrl_init(void) ++{ ++ return platform_driver_register(&mtk_pinctrl_driver); ++} ++ ++module_init(mtk_pinctrl_init); ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_DESCRIPTION("MediaTek MT8127 Pinctrl Driver"); ++MODULE_AUTHOR("Yingjoe Chen <yingjoe.chen@mediatek.com>"); +diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-mt8127.h b/drivers/pinctrl/mediatek/pinctrl-mtk-mt8127.h +new file mode 100644 +index 0000000..212559c +--- /dev/null ++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-mt8127.h +@@ -0,0 +1,1318 @@ ++#ifndef __PINCTRL_MTK_MT8127_H ++#define __PINCTRL_MTK_MT8127_H ++ ++#include <linux/pinctrl/pinctrl.h> ++#include "pinctrl-mtk-common.h" ++ ++static const struct mtk_desc_pin mtk_pins_mt8127[] = { ++ MTK_PIN( ++ PINCTRL_PIN(0, "PWRAP_SPI0_MI"), ++ "P22", "mt8127", ++ MTK_EINT_FUNCTION(0, 22), ++ MTK_FUNCTION(0, "GPIO0"), ++ MTK_FUNCTION(1, "PWRAP_SPIDO"), ++ MTK_FUNCTION(2, "PWRAP_SPIDI") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(1, "PWRAP_SPI0_MO"), ++ "M22", "mt8127", ++ MTK_EINT_FUNCTION(0, 23), ++ MTK_FUNCTION(0, "GPIO1"), ++ MTK_FUNCTION(1, "PWRAP_SPIDI"), ++ MTK_FUNCTION(2, "PWRAP_SPIDO") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(2, "PWRAP_INT"), ++ "L23", "mt8127", ++ MTK_EINT_FUNCTION(0, 24), ++ MTK_FUNCTION(0, "GPIO2") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(3, "PWRAP_SPI0_CK"), ++ "N23", "mt8127", ++ MTK_EINT_FUNCTION(0, 25), ++ MTK_FUNCTION(0, "GPIO3"), ++ MTK_FUNCTION(1, "PWRAP_SPICK_I") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(4, "PWRAP_SPI0_CSN"), ++ "N22", "mt8127", ++ MTK_EINT_FUNCTION(0, 26), ++ MTK_FUNCTION(0, "GPIO4"), ++ MTK_FUNCTION(1, "PWRAP_SPICS_B_I") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(5, "PWRAP_SPI0_CK2"), ++ "L19", "mt8127", ++ MTK_EINT_FUNCTION(0, 27), ++ MTK_FUNCTION(0, "GPIO5"), ++ MTK_FUNCTION(1, "PWRAP_SPICK2_I"), ++ MTK_FUNCTION(2, "ANT_SEL1"), ++ MTK_FUNCTION(3, "VDEC_TEST_CK"), ++ MTK_FUNCTION(7, "DBG_MON_B[0]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(6, "PWRAP_SPI0_CSN2"), ++ "M23", "mt8127", ++ MTK_EINT_FUNCTION(0, 28), ++ MTK_FUNCTION(0, "GPIO6"), ++ MTK_FUNCTION(1, "PWRAP_SPICS2_B_I"), ++ MTK_FUNCTION(2, "ANT_SEL0"), ++ MTK_FUNCTION(3, "MM_TEST_CK"), ++ MTK_FUNCTION(7, "DBG_MON_B[1]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(7, "AUD_CLK_MOSI"), ++ "K23", "mt8127", ++ MTK_EINT_FUNCTION(0, 29), ++ MTK_FUNCTION(0, "GPIO7"), ++ MTK_FUNCTION(1, "AUD_CLK"), ++ MTK_FUNCTION(2, "ADC_CK") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(8, "AUD_DAT_MISO"), ++ "K24", "mt8127", ++ MTK_EINT_FUNCTION(0, 30), ++ MTK_FUNCTION(0, "GPIO8"), ++ MTK_FUNCTION(1, "AUD_MISO"), ++ MTK_FUNCTION(2, "ADC_DAT_IN"), ++ MTK_FUNCTION(3, "AUD_MOSI") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(9, "AUD_DAT_MOSI"), ++ "K22", "mt8127", ++ MTK_EINT_FUNCTION(0, 31), ++ MTK_FUNCTION(0, "GPIO9"), ++ MTK_FUNCTION(1, "AUD_MOSI"), ++ MTK_FUNCTION(2, "ADC_WS"), ++ MTK_FUNCTION(3, "AUD_MISO") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(10, "RTC32K_CK"), ++ "R21", "mt8127", ++ MTK_EINT_FUNCTION(0, 32), ++ MTK_FUNCTION(0, "GPIO10"), ++ MTK_FUNCTION(1, "RTC32K_CK") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(11, "WATCHDOG"), ++ "P24", "mt8127", ++ MTK_EINT_FUNCTION(0, 33), ++ MTK_FUNCTION(0, "GPIO11"), ++ MTK_FUNCTION(1, "WATCHDOG") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(12, "SRCLKENA"), ++ "R22", "mt8127", ++ MTK_EINT_FUNCTION(0, 34), ++ MTK_FUNCTION(0, "GPIO12"), ++ MTK_FUNCTION(1, "SRCLKENA") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(13, "SRCLKENAI"), ++ "P23", "mt8127", ++ MTK_EINT_FUNCTION(0, 35), ++ MTK_FUNCTION(0, "GPIO13"), ++ MTK_FUNCTION(1, "SRCLKENAI") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(14, "URXD2"), ++ "U19", "mt8127", ++ MTK_EINT_FUNCTION(0, 36), ++ MTK_FUNCTION(0, "GPIO14"), ++ MTK_FUNCTION(1, "URXD2"), ++ MTK_FUNCTION(2, "DPI_D5"), ++ MTK_FUNCTION(3, "UTXD2"), ++ MTK_FUNCTION(5, "SRCCLKENAI2"), ++ MTK_FUNCTION(6, "KROW4") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(15, "UTXD2"), ++ "U20", "mt8127", ++ MTK_EINT_FUNCTION(0, 37), ++ MTK_FUNCTION(0, "GPIO15"), ++ MTK_FUNCTION(1, "UTXD2"), ++ MTK_FUNCTION(2, "DPI_HSYNC"), ++ MTK_FUNCTION(3, "URXD2"), ++ MTK_FUNCTION(6, "KROW5") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(16, "URXD3"), ++ "U18", "mt8127", ++ MTK_EINT_FUNCTION(0, 38), ++ MTK_FUNCTION(0, "GPIO16"), ++ MTK_FUNCTION(1, "URXD3"), ++ MTK_FUNCTION(2, "DPI_DE"), ++ MTK_FUNCTION(3, "UTXD3"), ++ MTK_FUNCTION(4, "UCTS2"), ++ MTK_FUNCTION(5, "PWM3"), ++ MTK_FUNCTION(6, "KROW6") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(17, "UTXD3"), ++ "R18", "mt8127", ++ MTK_EINT_FUNCTION(0, 39), ++ MTK_FUNCTION(0, "GPIO17"), ++ MTK_FUNCTION(1, "UTXD3"), ++ MTK_FUNCTION(2, "DPI_VSYNC"), ++ MTK_FUNCTION(3, "URXD3"), ++ MTK_FUNCTION(4, "URTS2"), ++ MTK_FUNCTION(5, "PWM4"), ++ MTK_FUNCTION(6, "KROW7") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(18, "PCM_CLK"), ++ "U22", "mt8127", ++ MTK_EINT_FUNCTION(0, 40), ++ MTK_FUNCTION(0, "GPIO18"), ++ MTK_FUNCTION(1, "PCM_CLK0"), ++ MTK_FUNCTION(2, "DPI_D4"), ++ MTK_FUNCTION(3, "I2SIN1_BCK0"), ++ MTK_FUNCTION(4, "I2SOUT_BCK"), ++ MTK_FUNCTION(5, "CONN_DSP_JCK"), ++ MTK_FUNCTION(6, "IR"), ++ MTK_FUNCTION(7, "DBG_MON_A[0]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(19, "PCM_SYNC"), ++ "U23", "mt8127", ++ MTK_EINT_FUNCTION(0, 41), ++ MTK_FUNCTION(0, "GPIO19"), ++ MTK_FUNCTION(1, "PCM_SYNC"), ++ MTK_FUNCTION(2, "DPI_D3"), ++ MTK_FUNCTION(3, "I2SIN1_LRCK"), ++ MTK_FUNCTION(4, "I2SOUT_LRCK"), ++ MTK_FUNCTION(5, "CONN_DSP_JINTP"), ++ MTK_FUNCTION(6, "EXT_COL"), ++ MTK_FUNCTION(7, "DBG_MON_A[1]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(20, "PCM_RX"), ++ "V22", "mt8127", ++ MTK_EINT_FUNCTION(0, 42), ++ MTK_FUNCTION(0, "GPIO20"), ++ MTK_FUNCTION(1, "PCM_RX"), ++ MTK_FUNCTION(2, "DPI_D1"), ++ MTK_FUNCTION(3, "I2SIN1_DATA_IN"), ++ MTK_FUNCTION(4, "PCM_TX"), ++ MTK_FUNCTION(5, "CONN_DSP_JDI"), ++ MTK_FUNCTION(6, "EXT_MDIO"), ++ MTK_FUNCTION(7, "DBG_MON_A[2]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(21, "PCM_TX"), ++ "U21", "mt8127", ++ MTK_EINT_FUNCTION(0, 43), ++ MTK_FUNCTION(0, "GPIO21"), ++ MTK_FUNCTION(1, "PCM_TX"), ++ MTK_FUNCTION(2, "DPI_D2"), ++ MTK_FUNCTION(3, "I2SOUT_DATA_OUT"), ++ MTK_FUNCTION(4, "PCM_RX"), ++ MTK_FUNCTION(5, "CONN_DSP_JMS"), ++ MTK_FUNCTION(6, "EXT_MDC"), ++ MTK_FUNCTION(7, "DBG_MON_A[3]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(22, "EINT0"), ++ "AB19", "mt8127", ++ MTK_EINT_FUNCTION(0, 0), ++ MTK_FUNCTION(0, "GPIO22"), ++ MTK_FUNCTION(1, "PWM1"), ++ MTK_FUNCTION(2, "DPI_CK"), ++ MTK_FUNCTION(4, "EXT_TXD0"), ++ MTK_FUNCTION(5, "CONN_DSP_JDO"), ++ MTK_FUNCTION(7, "DBG_MON_A[4]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(23, "EINT1"), ++ "AA21", "mt8127", ++ MTK_EINT_FUNCTION(0, 1), ++ MTK_FUNCTION(0, "GPIO23"), ++ MTK_FUNCTION(1, "PWM2"), ++ MTK_FUNCTION(2, "DPI_D12"), ++ MTK_FUNCTION(4, "EXT_TXD1"), ++ MTK_FUNCTION(5, "CONN_MCU_TDO"), ++ MTK_FUNCTION(7, "DBG_MON_A[5]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(24, "EINT2"), ++ "AA19", "mt8127", ++ MTK_EINT_FUNCTION(0, 2), ++ MTK_FUNCTION(0, "GPIO24"), ++ MTK_FUNCTION(1, "CLKM0"), ++ MTK_FUNCTION(2, "DPI_D13"), ++ MTK_FUNCTION(4, "EXT_TXD2"), ++ MTK_FUNCTION(5, "CONN_MCU_DBGACK_N"), ++ MTK_FUNCTION(6, "KCOL4"), ++ MTK_FUNCTION(7, "DBG_MON_A[6]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(25, "EINT3"), ++ "Y19", "mt8127", ++ MTK_EINT_FUNCTION(0, 3), ++ MTK_FUNCTION(0, "GPIO25"), ++ MTK_FUNCTION(1, "CLKM1"), ++ MTK_FUNCTION(2, "DPI_D14"), ++ MTK_FUNCTION(3, "SPI_MI"), ++ MTK_FUNCTION(4, "EXT_TXD3"), ++ MTK_FUNCTION(5, "CONN_MCU_DBGI_N"), ++ MTK_FUNCTION(6, "KCOL5"), ++ MTK_FUNCTION(7, "DBG_MON_A[7]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(26, "EINT4"), ++ "V21", "mt8127", ++ MTK_EINT_FUNCTION(0, 4), ++ MTK_FUNCTION(0, "GPIO26"), ++ MTK_FUNCTION(1, "CLKM2"), ++ MTK_FUNCTION(2, "DPI_D15"), ++ MTK_FUNCTION(3, "SPI_MO"), ++ MTK_FUNCTION(4, "EXT_TXC"), ++ MTK_FUNCTION(5, "CONN_MCU_TCK0"), ++ MTK_FUNCTION(6, "CONN_MCU_AICE_JCKC"), ++ MTK_FUNCTION(7, "DBG_MON_A[8]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(27, "EINT5"), ++ "AB22", "mt8127", ++ MTK_EINT_FUNCTION(0, 5), ++ MTK_FUNCTION(0, "GPIO27"), ++ MTK_FUNCTION(1, "UCTS2"), ++ MTK_FUNCTION(2, "DPI_D16"), ++ MTK_FUNCTION(3, "SPI_CS"), ++ MTK_FUNCTION(4, "EXT_RXER"), ++ MTK_FUNCTION(5, "CONN_MCU_TDI"), ++ MTK_FUNCTION(6, "KCOL6"), ++ MTK_FUNCTION(7, "DBG_MON_A[9]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(28, "EINT6"), ++ "AA23", "mt8127", ++ MTK_EINT_FUNCTION(0, 6), ++ MTK_FUNCTION(0, "GPIO28"), ++ MTK_FUNCTION(1, "URTS2"), ++ MTK_FUNCTION(2, "DPI_D17"), ++ MTK_FUNCTION(3, "SPI_CK"), ++ MTK_FUNCTION(4, "EXT_RXC"), ++ MTK_FUNCTION(5, "CONN_MCU_TRST_B"), ++ MTK_FUNCTION(6, "KCOL7"), ++ MTK_FUNCTION(7, "DBG_MON_A[10]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(29, "EINT7"), ++ "Y23", "mt8127", ++ MTK_EINT_FUNCTION(0, 7), ++ MTK_FUNCTION(0, "GPIO29"), ++ MTK_FUNCTION(1, "UCTS3"), ++ MTK_FUNCTION(2, "DPI_D6"), ++ MTK_FUNCTION(3, "SDA1"), ++ MTK_FUNCTION(4, "EXT_RXDV"), ++ MTK_FUNCTION(5, "CONN_MCU_TMS"), ++ MTK_FUNCTION(6, "CONN_MCU_AICE_JMSC"), ++ MTK_FUNCTION(7, "DBG_MON_A[11]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(30, "EINT8"), ++ "Y24", "mt8127", ++ MTK_EINT_FUNCTION(0, 8), ++ MTK_FUNCTION(0, "GPIO30"), ++ MTK_FUNCTION(1, "URTS3"), ++ MTK_FUNCTION(2, "CLKM3"), ++ MTK_FUNCTION(3, "SCL1"), ++ MTK_FUNCTION(4, "EXT_RXD0"), ++ MTK_FUNCTION(5, "ANT_SEL0"), ++ MTK_FUNCTION(6, "DPI_D7"), ++ MTK_FUNCTION(7, "DBG_MON_B[2]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(31, "EINT9"), ++ "W23", "mt8127", ++ MTK_EINT_FUNCTION(0, 9), ++ MTK_FUNCTION(0, "GPIO31"), ++ MTK_FUNCTION(1, "CLKM4"), ++ MTK_FUNCTION(2, "SDA2"), ++ MTK_FUNCTION(3, "EXT_FRAME_SYNC"), ++ MTK_FUNCTION(4, "EXT_RXD1"), ++ MTK_FUNCTION(5, "ANT_SEL1"), ++ MTK_FUNCTION(6, "DPI_D8"), ++ MTK_FUNCTION(7, "DBG_MON_B[3]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(32, "EINT10"), ++ "W24", "mt8127", ++ MTK_EINT_FUNCTION(0, 10), ++ MTK_FUNCTION(0, "GPIO32"), ++ MTK_FUNCTION(1, "CLKM5"), ++ MTK_FUNCTION(2, "SCL2"), ++ MTK_FUNCTION(3, "EXT_FRAME_SYNC"), ++ MTK_FUNCTION(4, "EXT_RXD2"), ++ MTK_FUNCTION(5, "ANT_SEL2"), ++ MTK_FUNCTION(6, "DPI_D9"), ++ MTK_FUNCTION(7, "DBG_MON_B[4]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(33, "KPROW0"), ++ "AB24", "mt8127", ++ MTK_EINT_FUNCTION(0, 44), ++ MTK_FUNCTION(0, "GPIO33"), ++ MTK_FUNCTION(1, "KROW0"), ++ MTK_FUNCTION(4, "IMG_TEST_CK"), ++ MTK_FUNCTION(7, "DBG_MON_A[12]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(34, "KPROW1"), ++ "AC24", "mt8127", ++ MTK_EINT_FUNCTION(0, 45), ++ MTK_FUNCTION(0, "GPIO34"), ++ MTK_FUNCTION(1, "KROW1"), ++ MTK_FUNCTION(2, "IDDIG"), ++ MTK_FUNCTION(3, "EXT_FRAME_SYNC"), ++ MTK_FUNCTION(4, "MFG_TEST_CK"), ++ MTK_FUNCTION(7, "DBG_MON_B[5]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(35, "KPROW2"), ++ "AD24", "mt8127", ++ MTK_EINT_FUNCTION(0, 46), ++ MTK_FUNCTION(0, "GPIO35"), ++ MTK_FUNCTION(1, "KROW2"), ++ MTK_FUNCTION(2, "DRV_VBUS"), ++ MTK_FUNCTION(3, "EXT_FRAME_SYNC"), ++ MTK_FUNCTION(4, "CONN_TEST_CK"), ++ MTK_FUNCTION(7, "DBG_MON_B[6]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(36, "KPCOL0"), ++ "AB23", "mt8127", ++ MTK_EINT_FUNCTION(0, 47), ++ MTK_FUNCTION(0, "GPIO36"), ++ MTK_FUNCTION(1, "KCOL0"), ++ MTK_FUNCTION(7, "DBG_MON_A[13]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(37, "KPCOL1"), ++ "AC22", "mt8127", ++ MTK_EINT_FUNCTION(0, 48), ++ MTK_FUNCTION(0, "GPIO37"), ++ MTK_FUNCTION(1, "KCOL1"), ++ MTK_FUNCTION(7, "DBG_MON_B[7]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(38, "KPCOL2"), ++ "AC23", "mt8127", ++ MTK_EINT_FUNCTION(0, 49), ++ MTK_FUNCTION(0, "GPIO38"), ++ MTK_FUNCTION(1, "KCOL2"), ++ MTK_FUNCTION(2, "IDDIG"), ++ MTK_FUNCTION(3, "EXT_FRAME_SYNC"), ++ MTK_FUNCTION(7, "DBG_MON_B[8]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(39, "JTMS"), ++ "V18", "mt8127", ++ MTK_EINT_FUNCTION(0, 50), ++ MTK_FUNCTION(0, "GPIO39"), ++ MTK_FUNCTION(1, "JTMS"), ++ MTK_FUNCTION(2, "CONN_MCU_TMS"), ++ MTK_FUNCTION(3, "CONN_MCU_AICE_JMSC") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(40, "JTCK"), ++ "AA18", "mt8127", ++ MTK_EINT_FUNCTION(0, 51), ++ MTK_FUNCTION(0, "GPIO40"), ++ MTK_FUNCTION(1, "JTCK"), ++ MTK_FUNCTION(2, "CONN_MCU_TCK1"), ++ MTK_FUNCTION(3, "CONN_MCU_AICE_JCKC") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(41, "JTDI"), ++ "W18", "mt8127", ++ MTK_EINT_FUNCTION(0, 52), ++ MTK_FUNCTION(0, "GPIO41"), ++ MTK_FUNCTION(1, "JTDI"), ++ MTK_FUNCTION(2, "CONN_MCU_TDI") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(42, "JTDO"), ++ "Y18", "mt8127", ++ MTK_EINT_FUNCTION(0, 53), ++ MTK_FUNCTION(0, "GPIO42"), ++ MTK_FUNCTION(1, "JTDO"), ++ MTK_FUNCTION(2, "CONN_MCU_TDO") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(43, "EINT11"), ++ "W22", "mt8127", ++ MTK_EINT_FUNCTION(0, 11), ++ MTK_FUNCTION(0, "GPIO43"), ++ MTK_FUNCTION(1, "CLKM4"), ++ MTK_FUNCTION(2, "PWM2"), ++ MTK_FUNCTION(3, "KROW3"), ++ MTK_FUNCTION(4, "ANT_SEL3"), ++ MTK_FUNCTION(5, "DPI_D10"), ++ MTK_FUNCTION(6, "EXT_RXD3"), ++ MTK_FUNCTION(7, "DBG_MON_B[9]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(44, "EINT12"), ++ "V23", "mt8127", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO44"), ++ MTK_FUNCTION(1, "CLKM5"), ++ MTK_FUNCTION(2, "PWM0"), ++ MTK_FUNCTION(3, "KCOL3"), ++ MTK_FUNCTION(4, "ANT_SEL4"), ++ MTK_FUNCTION(5, "DPI_D11"), ++ MTK_FUNCTION(6, "EXT_TXEN"), ++ MTK_FUNCTION(7, "DBG_MON_B[10]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(45, "EINT13"), ++ "Y21", "mt8127", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO45"), ++ MTK_FUNCTION(4, "ANT_SEL5"), ++ MTK_FUNCTION(5, "DPI_D0"), ++ MTK_FUNCTION(6, "SPDIF"), ++ MTK_FUNCTION(7, "DBG_MON_B[11]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(46, "EINT14"), ++ "F23", "mt8127", ++ MTK_EINT_FUNCTION(0, 14), ++ MTK_FUNCTION(0, "GPIO46"), ++ MTK_FUNCTION(2, "DAC_DAT_OUT"), ++ MTK_FUNCTION(4, "ANT_SEL1"), ++ MTK_FUNCTION(5, "CONN_MCU_DBGACK_N"), ++ MTK_FUNCTION(6, "NCLE"), ++ MTK_FUNCTION(7, "DBG_MON_A[14]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(47, "EINT15"), ++ "G23", "mt8127", ++ MTK_EINT_FUNCTION(0, 15), ++ MTK_FUNCTION(0, "GPIO47"), ++ MTK_FUNCTION(2, "DAC_WS"), ++ MTK_FUNCTION(4, "ANT_SEL2"), ++ MTK_FUNCTION(5, "CONN_MCU_DBGI_N"), ++ MTK_FUNCTION(6, "NCEB1"), ++ MTK_FUNCTION(7, "DBG_MON_A[15]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(48, "EINT16"), ++ "H23", "mt8127", ++ MTK_EINT_FUNCTION(0, 16), ++ MTK_FUNCTION(0, "GPIO48"), ++ MTK_FUNCTION(2, "DAC_CK"), ++ MTK_FUNCTION(4, "ANT_SEL3"), ++ MTK_FUNCTION(5, "CONN_MCU_TRST_B"), ++ MTK_FUNCTION(6, "NCEB0"), ++ MTK_FUNCTION(7, "DBG_MON_A[16]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(49, "EINT17"), ++ "J22", "mt8127", ++ MTK_EINT_FUNCTION(0, 17), ++ MTK_FUNCTION(0, "GPIO49"), ++ MTK_FUNCTION(1, "UCTS0"), ++ MTK_FUNCTION(3, "CLKM0"), ++ MTK_FUNCTION(4, "IDDIG"), ++ MTK_FUNCTION(5, "ANT_SEL4"), ++ MTK_FUNCTION(6, "NREB"), ++ MTK_FUNCTION(7, "DBG_MON_A[17]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(50, "EINT18"), ++ "AD20", "mt8127", ++ MTK_EINT_FUNCTION(0, 18), ++ MTK_FUNCTION(0, "GPIO50"), ++ MTK_FUNCTION(1, "URTS0"), ++ MTK_FUNCTION(2, "CLKM3"), ++ MTK_FUNCTION(3, "I2SOUT_LRCK"), ++ MTK_FUNCTION(4, "DRV_VBUS"), ++ MTK_FUNCTION(5, "ANT_SEL3"), ++ MTK_FUNCTION(6, "ADC_CK"), ++ MTK_FUNCTION(7, "DBG_MON_B[12]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(51, "EINT19"), ++ "AC21", "mt8127", ++ MTK_EINT_FUNCTION(0, 19), ++ MTK_FUNCTION(0, "GPIO51"), ++ MTK_FUNCTION(1, "UCTS1"), ++ MTK_FUNCTION(3, "I2SOUT_BCK"), ++ MTK_FUNCTION(4, "CLKM1"), ++ MTK_FUNCTION(5, "ANT_SEL4"), ++ MTK_FUNCTION(6, "ADC_DAT_IN"), ++ MTK_FUNCTION(7, "DBG_MON_B[13]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(52, "EINT20"), ++ "V20", "mt8127", ++ MTK_EINT_FUNCTION(0, 20), ++ MTK_FUNCTION(0, "GPIO52"), ++ MTK_FUNCTION(1, "URTS1"), ++ MTK_FUNCTION(2, "PCM_TX"), ++ MTK_FUNCTION(3, "I2SOUT_DATA_OUT"), ++ MTK_FUNCTION(4, "CLKM2"), ++ MTK_FUNCTION(5, "ANT_SEL5"), ++ MTK_FUNCTION(6, "ADC_WS"), ++ MTK_FUNCTION(7, "DBG_MON_B[14]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(53, "SPI_CS"), ++ "AD19", "mt8127", ++ MTK_EINT_FUNCTION(0, 54), ++ MTK_FUNCTION(0, "GPIO53"), ++ MTK_FUNCTION(1, "SPI_CS"), ++ MTK_FUNCTION(3, "I2SIN1_DATA_IN"), ++ MTK_FUNCTION(4, "ADC_CK"), ++ MTK_FUNCTION(7, "DBG_MON_B[15]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(54, "SPI_CK"), ++ "AC18", "mt8127", ++ MTK_EINT_FUNCTION(0, 55), ++ MTK_FUNCTION(0, "GPIO54"), ++ MTK_FUNCTION(1, "SPI_CK"), ++ MTK_FUNCTION(3, "I2SIN1_LRCK"), ++ MTK_FUNCTION(4, "ADC_DAT_IN"), ++ MTK_FUNCTION(7, "DBG_MON_B[16]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(55, "SPI_MI"), ++ "AC19", "mt8127", ++ MTK_EINT_FUNCTION(0, 56), ++ MTK_FUNCTION(0, "GPIO55"), ++ MTK_FUNCTION(1, "SPI_MI"), ++ MTK_FUNCTION(2, "SPI_MO"), ++ MTK_FUNCTION(3, "I2SIN1_BCK1"), ++ MTK_FUNCTION(4, "ADC_WS"), ++ MTK_FUNCTION(7, "DBG_MON_B[17]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(56, "SPI_MO"), ++ "AD18", "mt8127", ++ MTK_EINT_FUNCTION(0, 57), ++ MTK_FUNCTION(0, "GPIO56"), ++ MTK_FUNCTION(1, "SPI_MO"), ++ MTK_FUNCTION(2, "SPI_MI"), ++ MTK_FUNCTION(7, "DBG_MON_B[18]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(57, "SDA1"), ++ "AE23", "mt8127", ++ MTK_EINT_FUNCTION(0, 58), ++ MTK_FUNCTION(0, "GPIO57"), ++ MTK_FUNCTION(1, "SDA1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(58, "SCL1"), ++ "AD23", "mt8127", ++ MTK_EINT_FUNCTION(0, 59), ++ MTK_FUNCTION(0, "GPIO58"), ++ MTK_FUNCTION(1, "SCL1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(59, "DISP_PWM"), ++ "AC20", "mt8127", ++ MTK_EINT_FUNCTION(0, 60), ++ MTK_FUNCTION(0, "GPIO59"), ++ MTK_FUNCTION(1, "DISP_PWM"), ++ MTK_FUNCTION(2, "PWM1"), ++ MTK_FUNCTION(7, "DBG_MON_A[18]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(60, "WB_RSTB"), ++ "AD7", "mt8127", ++ MTK_EINT_FUNCTION(0, 61), ++ MTK_FUNCTION(0, "GPIO60"), ++ MTK_FUNCTION(1, "WB_RSTB"), ++ MTK_FUNCTION(7, "DBG_MON_A[19]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(61, "F2W_DATA"), ++ "Y10", "mt8127", ++ MTK_EINT_FUNCTION(0, 62), ++ MTK_FUNCTION(0, "GPIO61"), ++ MTK_FUNCTION(1, "F2W_DATA"), ++ MTK_FUNCTION(7, "DBG_MON_A[20]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(62, "F2W_CLK"), ++ "W10", "mt8127", ++ MTK_EINT_FUNCTION(0, 63), ++ MTK_FUNCTION(0, "GPIO62"), ++ MTK_FUNCTION(1, "F2W_CK"), ++ MTK_FUNCTION(7, "DBG_MON_A[21]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(63, "WB_SCLK"), ++ "AB7", "mt8127", ++ MTK_EINT_FUNCTION(0, 64), ++ MTK_FUNCTION(0, "GPIO63"), ++ MTK_FUNCTION(1, "WB_SCLK"), ++ MTK_FUNCTION(7, "DBG_MON_A[22]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(64, "WB_SDATA"), ++ "AA7", "mt8127", ++ MTK_EINT_FUNCTION(0, 65), ++ MTK_FUNCTION(0, "GPIO64"), ++ MTK_FUNCTION(1, "WB_SDATA"), ++ MTK_FUNCTION(7, "DBG_MON_A[23]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(65, "WB_SEN"), ++ "Y7", "mt8127", ++ MTK_EINT_FUNCTION(0, 66), ++ MTK_FUNCTION(0, "GPIO65"), ++ MTK_FUNCTION(1, "WB_SEN"), ++ MTK_FUNCTION(7, "DBG_MON_A[24]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(66, "WB_CRTL0"), ++ "AA1", "mt8127", ++ MTK_EINT_FUNCTION(0, 67), ++ MTK_FUNCTION(0, "GPIO66"), ++ MTK_FUNCTION(1, "WB_CRTL0"), ++ MTK_FUNCTION(2, "DFD_NTRST_XI"), ++ MTK_FUNCTION(7, "DBG_MON_A[25]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(67, "WB_CRTL1"), ++ "AA2", "mt8127", ++ MTK_EINT_FUNCTION(0, 68), ++ MTK_FUNCTION(0, "GPIO67"), ++ MTK_FUNCTION(1, "WB_CRTL1"), ++ MTK_FUNCTION(2, "DFD_TMS_XI"), ++ MTK_FUNCTION(7, "DBG_MON_A[26]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(68, "WB_CRTL2"), ++ "Y1", "mt8127", ++ MTK_EINT_FUNCTION(0, 69), ++ MTK_FUNCTION(0, "GPIO68"), ++ MTK_FUNCTION(1, "WB_CRTL2"), ++ MTK_FUNCTION(2, "DFD_TCK_XI"), ++ MTK_FUNCTION(7, "DBG_MON_A[27]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(69, "WB_CRTL3"), ++ "Y2", "mt8127", ++ MTK_EINT_FUNCTION(0, 70), ++ MTK_FUNCTION(0, "GPIO69"), ++ MTK_FUNCTION(1, "WB_CRTL3"), ++ MTK_FUNCTION(2, "DFD_TDI_XI"), ++ MTK_FUNCTION(7, "DBG_MON_A[28]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(70, "WB_CRTL4"), ++ "Y3", "mt8127", ++ MTK_EINT_FUNCTION(0, 71), ++ MTK_FUNCTION(0, "GPIO70"), ++ MTK_FUNCTION(1, "WB_CRTL4"), ++ MTK_FUNCTION(2, "DFD_TDO"), ++ MTK_FUNCTION(7, "DBG_MON_A[29]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(71, "WB_CRTL5"), ++ "Y4", "mt8127", ++ MTK_EINT_FUNCTION(0, 72), ++ MTK_FUNCTION(0, "GPIO71"), ++ MTK_FUNCTION(1, "WB_CRTL5"), ++ MTK_FUNCTION(7, "DBG_MON_A[30]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(72, "I2S_DATA_IN"), ++ "K21", "mt8127", ++ MTK_EINT_FUNCTION(0, 73), ++ MTK_FUNCTION(0, "GPIO72"), ++ MTK_FUNCTION(1, "I2SIN1_DATA_IN"), ++ MTK_FUNCTION(2, "PCM_RX"), ++ MTK_FUNCTION(3, "I2SOUT_DATA_OUT"), ++ MTK_FUNCTION(4, "DAC_DAT_OUT"), ++ MTK_FUNCTION(5, "PWM0"), ++ MTK_FUNCTION(6, "ADC_CK"), ++ MTK_FUNCTION(7, "DBG_MON_B[19]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(73, "I2S_LRCK"), ++ "L21", "mt8127", ++ MTK_EINT_FUNCTION(0, 74), ++ MTK_FUNCTION(0, "GPIO73"), ++ MTK_FUNCTION(1, "I2SIN1_LRCK"), ++ MTK_FUNCTION(2, "PCM_SYNC"), ++ MTK_FUNCTION(3, "I2SOUT_LRCK"), ++ MTK_FUNCTION(4, "DAC_WS"), ++ MTK_FUNCTION(5, "PWM3"), ++ MTK_FUNCTION(6, "ADC_DAT_IN"), ++ MTK_FUNCTION(7, "DBG_MON_B[20]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(74, "I2S_BCK"), ++ "L20", "mt8127", ++ MTK_EINT_FUNCTION(0, 75), ++ MTK_FUNCTION(0, "GPIO74"), ++ MTK_FUNCTION(1, "I2SIN1_BCK2"), ++ MTK_FUNCTION(2, "PCM_CLK1"), ++ MTK_FUNCTION(3, "I2SOUT_BCK"), ++ MTK_FUNCTION(4, "DAC_CK"), ++ MTK_FUNCTION(5, "PWM4"), ++ MTK_FUNCTION(6, "ADC_WS"), ++ MTK_FUNCTION(7, "DBG_MON_B[21]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(75, "SDA0"), ++ "W3", "mt8127", ++ MTK_EINT_FUNCTION(0, 76), ++ MTK_FUNCTION(0, "GPIO75"), ++ MTK_FUNCTION(1, "SDA0") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(76, "SCL0"), ++ "W4", "mt8127", ++ MTK_EINT_FUNCTION(0, 77), ++ MTK_FUNCTION(0, "GPIO76"), ++ MTK_FUNCTION(1, "SCL0") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(77, "SDA2"), ++ "K19", "mt8127", ++ MTK_EINT_FUNCTION(0, 78), ++ MTK_FUNCTION(0, "GPIO77"), ++ MTK_FUNCTION(1, "SDA2"), ++ MTK_FUNCTION(2, "PWM1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(78, "SCL2"), ++ "K20", "mt8127", ++ MTK_EINT_FUNCTION(0, 79), ++ MTK_FUNCTION(0, "GPIO78"), ++ MTK_FUNCTION(1, "SCL2"), ++ MTK_FUNCTION(2, "PWM2") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(79, "URXD0"), ++ "K18", "mt8127", ++ MTK_EINT_FUNCTION(0, 80), ++ MTK_FUNCTION(0, "GPIO79"), ++ MTK_FUNCTION(1, "URXD0"), ++ MTK_FUNCTION(2, "UTXD0") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(80, "UTXD0"), ++ "K17", "mt8127", ++ MTK_EINT_FUNCTION(0, 81), ++ MTK_FUNCTION(0, "GPIO80"), ++ MTK_FUNCTION(1, "UTXD0"), ++ MTK_FUNCTION(2, "URXD0") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(81, "URXD1"), ++ "L17", "mt8127", ++ MTK_EINT_FUNCTION(0, 82), ++ MTK_FUNCTION(0, "GPIO81"), ++ MTK_FUNCTION(1, "URXD1"), ++ MTK_FUNCTION(2, "UTXD1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(82, "UTXD1"), ++ "L18", "mt8127", ++ MTK_EINT_FUNCTION(0, 83), ++ MTK_FUNCTION(0, "GPIO82"), ++ MTK_FUNCTION(1, "UTXD1"), ++ MTK_FUNCTION(2, "URXD1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(83, "LCM_RST"), ++ "W5", "mt8127", ++ MTK_EINT_FUNCTION(0, 84), ++ MTK_FUNCTION(0, "GPIO83"), ++ MTK_FUNCTION(1, "LCM_RST"), ++ MTK_FUNCTION(2, "VDAC_CK_XI"), ++ MTK_FUNCTION(7, "DBG_MON_A[31]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(84, "DSI_TE"), ++ "W6", "mt8127", ++ MTK_EINT_FUNCTION(0, 85), ++ MTK_FUNCTION(0, "GPIO84"), ++ MTK_FUNCTION(1, "DSI_TE"), ++ MTK_FUNCTION(7, "DBG_MON_A[32]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(85, "MSDC2_CMD"), ++ "U7", "mt8127", ++ MTK_EINT_FUNCTION(0, 86), ++ MTK_FUNCTION(0, "GPIO85"), ++ MTK_FUNCTION(1, "MSDC2_CMD"), ++ MTK_FUNCTION(2, "ANT_SEL0"), ++ MTK_FUNCTION(3, "SDA1"), ++ MTK_FUNCTION(6, "I2SOUT_BCK"), ++ MTK_FUNCTION(7, "DBG_MON_B[22]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(86, "MSDC2_CLK"), ++ "T8", "mt8127", ++ MTK_EINT_FUNCTION(0, 87), ++ MTK_FUNCTION(0, "GPIO86"), ++ MTK_FUNCTION(1, "MSDC2_CLK"), ++ MTK_FUNCTION(2, "ANT_SEL1"), ++ MTK_FUNCTION(3, "SCL1"), ++ MTK_FUNCTION(6, "I2SOUT_LRCK"), ++ MTK_FUNCTION(7, "DBG_MON_B[23]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(87, "MSDC2_DAT0"), ++ "V3", "mt8127", ++ MTK_EINT_FUNCTION(0, 88), ++ MTK_FUNCTION(0, "GPIO87"), ++ MTK_FUNCTION(1, "MSDC2_DAT0"), ++ MTK_FUNCTION(2, "ANT_SEL2"), ++ MTK_FUNCTION(5, "UTXD0"), ++ MTK_FUNCTION(6, "I2SOUT_DATA_OUT"), ++ MTK_FUNCTION(7, "DBG_MON_B[24]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(88, "MSDC2_DAT1"), ++ "V4", "mt8127", ++ MTK_EINT_FUNCTION(0, 89), ++ MTK_FUNCTION(0, "GPIO88"), ++ MTK_FUNCTION(1, "MSDC2_DAT1"), ++ MTK_FUNCTION(2, "ANT_SEL3"), ++ MTK_FUNCTION(3, "PWM0"), ++ MTK_FUNCTION(5, "URXD0"), ++ MTK_FUNCTION(6, "PWM1"), ++ MTK_FUNCTION(7, "DBG_MON_B[25]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(89, "MSDC2_DAT2"), ++ "U5", "mt8127", ++ MTK_EINT_FUNCTION(0, 90), ++ MTK_FUNCTION(0, "GPIO89"), ++ MTK_FUNCTION(1, "MSDC2_DAT2"), ++ MTK_FUNCTION(2, "ANT_SEL4"), ++ MTK_FUNCTION(3, "SDA2"), ++ MTK_FUNCTION(5, "UTXD1"), ++ MTK_FUNCTION(6, "PWM2"), ++ MTK_FUNCTION(7, "DBG_MON_B[26]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(90, "MSDC2_DAT3"), ++ "U6", "mt8127", ++ MTK_EINT_FUNCTION(0, 91), ++ MTK_FUNCTION(0, "GPIO90"), ++ MTK_FUNCTION(1, "MSDC2_DAT3"), ++ MTK_FUNCTION(2, "ANT_SEL5"), ++ MTK_FUNCTION(3, "SCL2"), ++ MTK_FUNCTION(4, "EXT_FRAME_SYNC"), ++ MTK_FUNCTION(5, "URXD1"), ++ MTK_FUNCTION(6, "PWM3"), ++ MTK_FUNCTION(7, "DBG_MON_B[27]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(91, "TDN3"), ++ "U2", "mt8127", ++ MTK_EINT_FUNCTION(0, 92), ++ MTK_FUNCTION(0, "GPI91"), ++ MTK_FUNCTION(1, "TDN3") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(92, "TDP3"), ++ "U1", "mt8127", ++ MTK_EINT_FUNCTION(0, 93), ++ MTK_FUNCTION(0, "GPI92"), ++ MTK_FUNCTION(1, "TDP3") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(93, "TDN2"), ++ "T2", "mt8127", ++ MTK_EINT_FUNCTION(0, 94), ++ MTK_FUNCTION(0, "GPI93"), ++ MTK_FUNCTION(1, "TDN2") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(94, "TDP2"), ++ "T1", "mt8127", ++ MTK_EINT_FUNCTION(0, 95), ++ MTK_FUNCTION(0, "GPI94"), ++ MTK_FUNCTION(1, "TDP2") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(95, "TCN"), ++ "R5", "mt8127", ++ MTK_EINT_FUNCTION(0, 96), ++ MTK_FUNCTION(0, "GPI95"), ++ MTK_FUNCTION(1, "TCN") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(96, "TCP"), ++ "R4", "mt8127", ++ MTK_EINT_FUNCTION(0, 97), ++ MTK_FUNCTION(0, "GPI96"), ++ MTK_FUNCTION(1, "TCP") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(97, "TDN1"), ++ "R3", "mt8127", ++ MTK_EINT_FUNCTION(0, 98), ++ MTK_FUNCTION(0, "GPI97"), ++ MTK_FUNCTION(1, "TDN1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(98, "TDP1"), ++ "R2", "mt8127", ++ MTK_EINT_FUNCTION(0, 99), ++ MTK_FUNCTION(0, "GPI98"), ++ MTK_FUNCTION(1, "TDP1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(99, "TDN0"), ++ "P3", "mt8127", ++ MTK_EINT_FUNCTION(0, 100), ++ MTK_FUNCTION(0, "GPI99"), ++ MTK_FUNCTION(1, "TDN0") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(100, "TDP0"), ++ "P2", "mt8127", ++ MTK_EINT_FUNCTION(0, 101), ++ MTK_FUNCTION(0, "GPI100"), ++ MTK_FUNCTION(1, "TDP0") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(101, "RDN0"), ++ "K1", "mt8127", ++ MTK_EINT_FUNCTION(0, 102), ++ MTK_FUNCTION(0, "GPI101"), ++ MTK_FUNCTION(1, "RDN0") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(102, "RDP0"), ++ "K2", "mt8127", ++ MTK_EINT_FUNCTION(0, 103), ++ MTK_FUNCTION(0, "GPI102"), ++ MTK_FUNCTION(1, "RDP0") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(103, "RDN1"), ++ "L2", "mt8127", ++ MTK_EINT_FUNCTION(0, 104), ++ MTK_FUNCTION(0, "GPI103"), ++ MTK_FUNCTION(1, "RDN1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(104, "RDP1"), ++ "L3", "mt8127", ++ MTK_EINT_FUNCTION(0, 105), ++ MTK_FUNCTION(0, "GPI104"), ++ MTK_FUNCTION(1, "RDP1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(105, "RCN"), ++ "M4", "mt8127", ++ MTK_EINT_FUNCTION(0, 106), ++ MTK_FUNCTION(0, "GPI105"), ++ MTK_FUNCTION(1, "RCN") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(106, "RCP"), ++ "M5", "mt8127", ++ MTK_EINT_FUNCTION(0, 107), ++ MTK_FUNCTION(0, "GPI106"), ++ MTK_FUNCTION(1, "RCP") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(107, "RDN2"), ++ "M2", "mt8127", ++ MTK_EINT_FUNCTION(0, 108), ++ MTK_FUNCTION(0, "GPI107"), ++ MTK_FUNCTION(1, "RDN2"), ++ MTK_FUNCTION(2, "CMDAT8") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(108, "RDP2"), ++ "M3", "mt8127", ++ MTK_EINT_FUNCTION(0, 109), ++ MTK_FUNCTION(0, "GPI108"), ++ MTK_FUNCTION(1, "RDP2"), ++ MTK_FUNCTION(2, "CMDAT9") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(109, "RDN3"), ++ "N2", "mt8127", ++ MTK_EINT_FUNCTION(0, 110), ++ MTK_FUNCTION(0, "GPI109"), ++ MTK_FUNCTION(1, "RDN3"), ++ MTK_FUNCTION(2, "CMDAT4") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(110, "RDP3"), ++ "N3", "mt8127", ++ MTK_EINT_FUNCTION(0, 111), ++ MTK_FUNCTION(0, "GPI110"), ++ MTK_FUNCTION(1, "RDP3"), ++ MTK_FUNCTION(2, "CMDAT5") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(111, "RCN_A"), ++ "J5", "mt8127", ++ MTK_EINT_FUNCTION(0, 112), ++ MTK_FUNCTION(0, "GPI111"), ++ MTK_FUNCTION(1, "RCN_A"), ++ MTK_FUNCTION(2, "CMDAT6") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(112, "RCP_A"), ++ "J4", "mt8127", ++ MTK_EINT_FUNCTION(0, 113), ++ MTK_FUNCTION(0, "GPI112"), ++ MTK_FUNCTION(1, "RCP_A"), ++ MTK_FUNCTION(2, "CMDAT7") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(113, "RDN1_A"), ++ "J2", "mt8127", ++ MTK_EINT_FUNCTION(0, 114), ++ MTK_FUNCTION(0, "GPI113"), ++ MTK_FUNCTION(1, "RDN1_A"), ++ MTK_FUNCTION(2, "CMDAT2"), ++ MTK_FUNCTION(3, "CMCSD2") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(114, "RDP1_A"), ++ "J3", "mt8127", ++ MTK_EINT_FUNCTION(0, 115), ++ MTK_FUNCTION(0, "GPI114"), ++ MTK_FUNCTION(1, "RDP1_A"), ++ MTK_FUNCTION(2, "CMDAT3"), ++ MTK_FUNCTION(3, "CMCSD3") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(115, "RDN0_A"), ++ "H2", "mt8127", ++ MTK_EINT_FUNCTION(0, 116), ++ MTK_FUNCTION(0, "GPI115"), ++ MTK_FUNCTION(1, "RDN0_A"), ++ MTK_FUNCTION(2, "CMHSYNC") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(116, "RDP0_A"), ++ "H3", "mt8127", ++ MTK_EINT_FUNCTION(0, 117), ++ MTK_FUNCTION(0, "GPI116"), ++ MTK_FUNCTION(1, "RDP0_A"), ++ MTK_FUNCTION(2, "CMVSYNC") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(117, "CMDAT0"), ++ "G5", "mt8127", ++ MTK_EINT_FUNCTION(0, 118), ++ MTK_FUNCTION(0, "GPIO117"), ++ MTK_FUNCTION(1, "CMDAT0"), ++ MTK_FUNCTION(2, "CMCSD0"), ++ MTK_FUNCTION(3, "ANT_SEL2"), ++ MTK_FUNCTION(7, "DBG_MON_B[28]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(118, "CMDAT1"), ++ "G4", "mt8127", ++ MTK_EINT_FUNCTION(0, 119), ++ MTK_FUNCTION(0, "GPIO118"), ++ MTK_FUNCTION(1, "CMDAT1"), ++ MTK_FUNCTION(2, "CMCSD1"), ++ MTK_FUNCTION(3, "ANT_SEL3"), ++ MTK_FUNCTION(7, "DBG_MON_B[29]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(119, "CMMCLK"), ++ "F3", "mt8127", ++ MTK_EINT_FUNCTION(0, 120), ++ MTK_FUNCTION(0, "GPIO119"), ++ MTK_FUNCTION(1, "CMMCLK"), ++ MTK_FUNCTION(3, "ANT_SEL4"), ++ MTK_FUNCTION(7, "DBG_MON_B[30]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(120, "CMPCLK"), ++ "G6", "mt8127", ++ MTK_EINT_FUNCTION(0, 121), ++ MTK_FUNCTION(0, "GPIO120"), ++ MTK_FUNCTION(1, "CMPCLK"), ++ MTK_FUNCTION(2, "CMCSK"), ++ MTK_FUNCTION(3, "ANT_SEL5"), ++ MTK_FUNCTION(7, "DBG_MON_B[31]") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(121, "MSDC1_CMD"), ++ "E3", "mt8127", ++ MTK_EINT_FUNCTION(0, 122), ++ MTK_FUNCTION(0, "GPIO121"), ++ MTK_FUNCTION(1, "MSDC1_CMD") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(122, "MSDC1_CLK"), ++ "D1", "mt8127", ++ MTK_EINT_FUNCTION(0, 123), ++ MTK_FUNCTION(0, "GPIO122"), ++ MTK_FUNCTION(1, "MSDC1_CLK") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(123, "MSDC1_DAT0"), ++ "D2", "mt8127", ++ MTK_EINT_FUNCTION(0, 124), ++ MTK_FUNCTION(0, "GPIO123"), ++ MTK_FUNCTION(1, "MSDC1_DAT0") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(124, "MSDC1_DAT1"), ++ "D3", "mt8127", ++ MTK_EINT_FUNCTION(0, 125), ++ MTK_FUNCTION(0, "GPIO124"), ++ MTK_FUNCTION(1, "MSDC1_DAT1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(125, "MSDC1_DAT2"), ++ "F2", "mt8127", ++ MTK_EINT_FUNCTION(0, 126), ++ MTK_FUNCTION(0, "GPIO125"), ++ MTK_FUNCTION(1, "MSDC1_DAT2") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(126, "MSDC1_DAT3"), ++ "E2", "mt8127", ++ MTK_EINT_FUNCTION(0, 127), ++ MTK_FUNCTION(0, "GPIO126"), ++ MTK_FUNCTION(1, "MSDC1_DAT3") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(127, "MSDC0_DAT7"), ++ "C23", "mt8127", ++ MTK_EINT_FUNCTION(0, 128), ++ MTK_FUNCTION(0, "GPIO127"), ++ MTK_FUNCTION(1, "MSDC0_DAT7"), ++ MTK_FUNCTION(4, "NLD7") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(128, "MSDC0_DAT6"), ++ "C24", "mt8127", ++ MTK_EINT_FUNCTION(0, 129), ++ MTK_FUNCTION(0, "GPIO128"), ++ MTK_FUNCTION(1, "MSDC0_DAT6"), ++ MTK_FUNCTION(4, "NLD6") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(129, "MSDC0_DAT5"), ++ "D22", "mt8127", ++ MTK_EINT_FUNCTION(0, 130), ++ MTK_FUNCTION(0, "GPIO129"), ++ MTK_FUNCTION(1, "MSDC0_DAT5"), ++ MTK_FUNCTION(4, "NLD4") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(130, "MSDC0_DAT4"), ++ "D24", "mt8127", ++ MTK_EINT_FUNCTION(0, 131), ++ MTK_FUNCTION(0, "GPIO130"), ++ MTK_FUNCTION(1, "MSDC0_DAT4"), ++ MTK_FUNCTION(4, "NLD3") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(131, "MSDC0_RSTB"), ++ "F24", "mt8127", ++ MTK_EINT_FUNCTION(0, 132), ++ MTK_FUNCTION(0, "GPIO131"), ++ MTK_FUNCTION(1, "MSDC0_RSTB"), ++ MTK_FUNCTION(4, "NLD0") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(132, "MSDC0_CMD"), ++ "G20", "mt8127", ++ MTK_EINT_FUNCTION(0, 133), ++ MTK_FUNCTION(0, "GPIO132"), ++ MTK_FUNCTION(1, "MSDC0_CMD"), ++ MTK_FUNCTION(4, "NALE") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(133, "MSDC0_CLK"), ++ "G21", "mt8127", ++ MTK_EINT_FUNCTION(0, 134), ++ MTK_FUNCTION(0, "GPIO133"), ++ MTK_FUNCTION(1, "MSDC0_CLK"), ++ MTK_FUNCTION(4, "NWEB") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(134, "MSDC0_DAT3"), ++ "D23", "mt8127", ++ MTK_EINT_FUNCTION(0, 135), ++ MTK_FUNCTION(0, "GPIO134"), ++ MTK_FUNCTION(1, "MSDC0_DAT3"), ++ MTK_FUNCTION(4, "NLD1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(135, "MSDC0_DAT2"), ++ "E22", "mt8127", ++ MTK_EINT_FUNCTION(0, 136), ++ MTK_FUNCTION(0, "GPIO135"), ++ MTK_FUNCTION(1, "MSDC0_DAT2"), ++ MTK_FUNCTION(4, "NLD5") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(136, "MSDC0_DAT1"), ++ "E23", "mt8127", ++ MTK_EINT_FUNCTION(0, 137), ++ MTK_FUNCTION(0, "GPIO136"), ++ MTK_FUNCTION(1, "MSDC0_DAT1"), ++ MTK_FUNCTION(4, "NLD8") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(137, "MSDC0_DAT0"), ++ "F22", "mt8127", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO137"), ++ MTK_FUNCTION(1, "MSDC0_DAT0"), ++ MTK_FUNCTION(4, "WATCHDOG"), ++ MTK_FUNCTION(5, "NLD2") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(138, "CEC"), ++ "AE21", "mt8127", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO138"), ++ MTK_FUNCTION(1, "CEC") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(139, "HTPLG"), ++ "AD21", "mt8127", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO139"), ++ MTK_FUNCTION(1, "HTPLG") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(140, "HDMISCK"), ++ "AE22", "mt8127", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO140"), ++ MTK_FUNCTION(1, "HDMISCK") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(141, "HDMISD"), ++ "AD22", "mt8127", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO141"), ++ MTK_FUNCTION(1, "HDMISD") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(142, "EINT21"), ++ "J23", "mt8127", ++ MTK_EINT_FUNCTION(0, 21), ++ MTK_FUNCTION(0, "GPIO142"), ++ MTK_FUNCTION(1, "NRNB"), ++ MTK_FUNCTION(2, "ANT_SEL0"), ++ MTK_FUNCTION(7, "DBG_MON_B[32]") ++ ), ++}; ++ ++#endif /* __PINCTRL_MTK_MT8127_H */ +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0055-mfd-mediatek-Add-GPIO-sub-module-support-into-mfd.patch b/target/linux/mediatek/patches/0055-mfd-mediatek-Add-GPIO-sub-module-support-into-mfd.patch new file mode 100644 index 0000000000..d9c0676c81 --- /dev/null +++ b/target/linux/mediatek/patches/0055-mfd-mediatek-Add-GPIO-sub-module-support-into-mfd.patch @@ -0,0 +1,30 @@ +From e5de6556a25d4b2e2d30683d629095bce102c792 Mon Sep 17 00:00:00 2001 +From: Hongzhou Yang <hongzhou.yang@mediatek.com> +Date: Mon, 18 May 2015 23:11:19 -0700 +Subject: [PATCH 55/76] mfd: mediatek: Add GPIO sub module support into mfd. + +Register pinctrl subnode into 6397 mfd cell. + +Signed-off-by: Hongzhou Yang <hongzhou.yang@mediatek.com> +Acked-by: Linus Walleij <linus.walleij@linaro.org> +--- + drivers/mfd/mt6397-core.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/mfd/mt6397-core.c b/drivers/mfd/mt6397-core.c +index 09bc780..012c620 100644 +--- a/drivers/mfd/mt6397-core.c ++++ b/drivers/mfd/mt6397-core.c +@@ -34,6 +34,9 @@ static const struct mfd_cell mt6397_devs[] = { + }, { + .name = "mt6397-clk", + .of_compatible = "mediatek,mt6397-clk", ++ }, { ++ .name = "mediatek-mt6397-pinctrl", ++ .of_compatible = "mediatek,mt6397-pinctrl", + }, + }; + +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0056-ARM-dts-mt8127-add-pinctrl-GPIO-EINT-node-for-mt8127.patch b/target/linux/mediatek/patches/0056-ARM-dts-mt8127-add-pinctrl-GPIO-EINT-node-for-mt8127.patch new file mode 100644 index 0000000000..a59d2c609b --- /dev/null +++ b/target/linux/mediatek/patches/0056-ARM-dts-mt8127-add-pinctrl-GPIO-EINT-node-for-mt8127.patch @@ -0,0 +1,809 @@ +From 619e31dbd73885249f3db545ed0b7678ca98c248 Mon Sep 17 00:00:00 2001 +From: Yingjoe Chen <yingjoe.chen@mediatek.com> +Date: Mon, 18 May 2015 23:11:20 -0700 +Subject: [PATCH 56/76] ARM: dts: mt8127: add pinctrl/GPIO/EINT node for + mt8127 + +Add pinctrl,GPIO and EINT node to mt8127.dtsi. + +Signed-off-by: Yingjoe Chen <yingjoe.chen@mediatek.com> +Signed-off-by: Hongzhou Yang <hongzhou.yang@mediatek.com> +Acked-by: Linus Walleij <linus.walleij@linaro.org> +Acked-by: Matthias Brugger <matthias.bgg@gmail.com> +--- + arch/arm/boot/dts/mt8127-pinfunc.h | 742 ++++++++++++++++++++++++++++++++++++ + arch/arm/boot/dts/mt8127.dtsi | 22 ++ + 2 files changed, 764 insertions(+) + create mode 100644 arch/arm/boot/dts/mt8127-pinfunc.h + +diff --git a/arch/arm/boot/dts/mt8127-pinfunc.h b/arch/arm/boot/dts/mt8127-pinfunc.h +new file mode 100644 +index 0000000..9198331 +--- /dev/null ++++ b/arch/arm/boot/dts/mt8127-pinfunc.h +@@ -0,0 +1,742 @@ ++#ifndef __DTS_MT8127_PINFUNC_H ++#define __DTS_MT8127_PINFUNC_H ++ ++#include <dt-bindings/pinctrl/mt65xx.h> ++ ++#define MT8127_PIN_0_PWRAP_SPI0_MI__FUNC_GPIO0 (MTK_PIN_NO(0) | 0) ++#define MT8127_PIN_0_PWRAP_SPI0_MI__FUNC_PWRAP_SPIDO (MTK_PIN_NO(0) | 1) ++#define MT8127_PIN_0_PWRAP_SPI0_MI__FUNC_PWRAP_SPIDI (MTK_PIN_NO(0) | 2) ++ ++#define MT8127_PIN_1_PWRAP_SPI0_MO__FUNC_GPIO1 (MTK_PIN_NO(1) | 0) ++#define MT8127_PIN_1_PWRAP_SPI0_MO__FUNC_PWRAP_SPIDI (MTK_PIN_NO(1) | 1) ++#define MT8127_PIN_1_PWRAP_SPI0_MO__FUNC_PWRAP_SPIDO (MTK_PIN_NO(1) | 2) ++ ++#define MT8127_PIN_2_PWRAP_INT__FUNC_GPIO2 (MTK_PIN_NO(2) | 0) ++ ++#define MT8127_PIN_3_PWRAP_SPI0_CK__FUNC_GPIO3 (MTK_PIN_NO(3) | 0) ++#define MT8127_PIN_3_PWRAP_SPI0_CK__FUNC_PWRAP_SPICK_I (MTK_PIN_NO(3) | 1) ++ ++#define MT8127_PIN_4_PWRAP_SPI0_CSN__FUNC_GPIO4 (MTK_PIN_NO(4) | 0) ++#define MT8127_PIN_4_PWRAP_SPI0_CSN__FUNC_PWRAP_SPICS_B_I (MTK_PIN_NO(4) | 1) ++ ++#define MT8127_PIN_5_PWRAP_SPI0_CK2__FUNC_GPIO5 (MTK_PIN_NO(5) | 0) ++#define MT8127_PIN_5_PWRAP_SPI0_CK2__FUNC_PWRAP_SPICK2_I (MTK_PIN_NO(5) | 1) ++#define MT8127_PIN_5_PWRAP_SPI0_CK2__FUNC_ANT_SEL1 (MTK_PIN_NO(5) | 2) ++#define MT8127_PIN_5_PWRAP_SPI0_CK2__FUNC_VDEC_TEST_CK (MTK_PIN_NO(5) | 3) ++#define MT8127_PIN_5_PWRAP_SPI0_CK2__FUNC_DBG_MON_B_0 (MTK_PIN_NO(5) | 7) ++ ++#define MT8127_PIN_6_PWRAP_SPI0_CSN2__FUNC_GPIO6 (MTK_PIN_NO(6) | 0) ++#define MT8127_PIN_6_PWRAP_SPI0_CSN2__FUNC_PWRAP_SPICS2_B_I (MTK_PIN_NO(6) | 1) ++#define MT8127_PIN_6_PWRAP_SPI0_CSN2__FUNC_ANT_SEL0 (MTK_PIN_NO(6) | 2) ++#define MT8127_PIN_6_PWRAP_SPI0_CSN2__FUNC_MM_TEST_CK (MTK_PIN_NO(6) | 3) ++#define MT8127_PIN_6_PWRAP_SPI0_CSN2__FUNC_DBG_MON_B_1 (MTK_PIN_NO(6) | 7) ++ ++#define MT8127_PIN_7_AUD_CLK_MOSI__FUNC_GPIO7 (MTK_PIN_NO(7) | 0) ++#define MT8127_PIN_7_AUD_CLK_MOSI__FUNC_AUD_CLK (MTK_PIN_NO(7) | 1) ++#define MT8127_PIN_7_AUD_CLK_MOSI__FUNC_ADC_CK (MTK_PIN_NO(7) | 2) ++ ++#define MT8127_PIN_8_AUD_DAT_MISO__FUNC_GPIO8 (MTK_PIN_NO(8) | 0) ++#define MT8127_PIN_8_AUD_DAT_MISO__FUNC_AUD_MISO (MTK_PIN_NO(8) | 1) ++#define MT8127_PIN_8_AUD_DAT_MISO__FUNC_ADC_DAT_IN (MTK_PIN_NO(8) | 2) ++#define MT8127_PIN_8_AUD_DAT_MISO__FUNC_AUD_MOSI (MTK_PIN_NO(8) | 3) ++ ++#define MT8127_PIN_9_AUD_DAT_MOSI__FUNC_GPIO9 (MTK_PIN_NO(9) | 0) ++#define MT8127_PIN_9_AUD_DAT_MOSI__FUNC_AUD_MOSI (MTK_PIN_NO(9) | 1) ++#define MT8127_PIN_9_AUD_DAT_MOSI__FUNC_ADC_WS (MTK_PIN_NO(9) | 2) ++#define MT8127_PIN_9_AUD_DAT_MOSI__FUNC_AUD_MISO (MTK_PIN_NO(9) | 3) ++ ++#define MT8127_PIN_10_RTC32K_CK__FUNC_GPIO10 (MTK_PIN_NO(10) | 0) ++#define MT8127_PIN_10_RTC32K_CK__FUNC_RTC32K_CK (MTK_PIN_NO(10) | 1) ++ ++#define MT8127_PIN_11_WATCHDOG__FUNC_GPIO11 (MTK_PIN_NO(11) | 0) ++#define MT8127_PIN_11_WATCHDOG__FUNC_WATCHDOG (MTK_PIN_NO(11) | 1) ++ ++#define MT8127_PIN_12_SRCLKENA__FUNC_GPIO12 (MTK_PIN_NO(12) | 0) ++#define MT8127_PIN_12_SRCLKENA__FUNC_SRCLKENA (MTK_PIN_NO(12) | 1) ++ ++#define MT8127_PIN_13_SRCLKENAI__FUNC_GPIO13 (MTK_PIN_NO(13) | 0) ++#define MT8127_PIN_13_SRCLKENAI__FUNC_SRCLKENAI (MTK_PIN_NO(13) | 1) ++ ++#define MT8127_PIN_14_URXD2__FUNC_GPIO14 (MTK_PIN_NO(14) | 0) ++#define MT8127_PIN_14_URXD2__FUNC_URXD2 (MTK_PIN_NO(14) | 1) ++#define MT8127_PIN_14_URXD2__FUNC_DPI_D5 (MTK_PIN_NO(14) | 2) ++#define MT8127_PIN_14_URXD2__FUNC_UTXD2 (MTK_PIN_NO(14) | 3) ++#define MT8127_PIN_14_URXD2__FUNC_SRCCLKENAI2 (MTK_PIN_NO(14) | 5) ++#define MT8127_PIN_14_URXD2__FUNC_KROW4 (MTK_PIN_NO(14) | 6) ++ ++#define MT8127_PIN_15_UTXD2__FUNC_GPIO15 (MTK_PIN_NO(15) | 0) ++#define MT8127_PIN_15_UTXD2__FUNC_UTXD2 (MTK_PIN_NO(15) | 1) ++#define MT8127_PIN_15_UTXD2__FUNC_DPI_HSYNC (MTK_PIN_NO(15) | 2) ++#define MT8127_PIN_15_UTXD2__FUNC_URXD2 (MTK_PIN_NO(15) | 3) ++#define MT8127_PIN_15_UTXD2__FUNC_KROW5 (MTK_PIN_NO(15) | 6) ++ ++#define MT8127_PIN_16_URXD3__FUNC_GPIO16 (MTK_PIN_NO(16) | 0) ++#define MT8127_PIN_16_URXD3__FUNC_URXD3 (MTK_PIN_NO(16) | 1) ++#define MT8127_PIN_16_URXD3__FUNC_DPI_DE (MTK_PIN_NO(16) | 2) ++#define MT8127_PIN_16_URXD3__FUNC_UTXD3 (MTK_PIN_NO(16) | 3) ++#define MT8127_PIN_16_URXD3__FUNC_UCTS2 (MTK_PIN_NO(16) | 4) ++#define MT8127_PIN_16_URXD3__FUNC_PWM3 (MTK_PIN_NO(16) | 5) ++#define MT8127_PIN_16_URXD3__FUNC_KROW6 (MTK_PIN_NO(16) | 6) ++ ++#define MT8127_PIN_17_UTXD3__FUNC_GPIO17 (MTK_PIN_NO(17) | 0) ++#define MT8127_PIN_17_UTXD3__FUNC_UTXD3 (MTK_PIN_NO(17) | 1) ++#define MT8127_PIN_17_UTXD3__FUNC_DPI_VSYNC (MTK_PIN_NO(17) | 2) ++#define MT8127_PIN_17_UTXD3__FUNC_URXD3 (MTK_PIN_NO(17) | 3) ++#define MT8127_PIN_17_UTXD3__FUNC_URTS2 (MTK_PIN_NO(17) | 4) ++#define MT8127_PIN_17_UTXD3__FUNC_PWM4 (MTK_PIN_NO(17) | 5) ++#define MT8127_PIN_17_UTXD3__FUNC_KROW7 (MTK_PIN_NO(17) | 6) ++ ++#define MT8127_PIN_18_PCM_CLK__FUNC_GPIO18 (MTK_PIN_NO(18) | 0) ++#define MT8127_PIN_18_PCM_CLK__FUNC_PCM_CLK0 (MTK_PIN_NO(18) | 1) ++#define MT8127_PIN_18_PCM_CLK__FUNC_DPI_D4 (MTK_PIN_NO(18) | 2) ++#define MT8127_PIN_18_PCM_CLK__FUNC_I2SIN1_BCK0 (MTK_PIN_NO(18) | 3) ++#define MT8127_PIN_18_PCM_CLK__FUNC_I2SOUT_BCK (MTK_PIN_NO(18) | 4) ++#define MT8127_PIN_18_PCM_CLK__FUNC_CONN_DSP_JCK (MTK_PIN_NO(18) | 5) ++#define MT8127_PIN_18_PCM_CLK__FUNC_IR (MTK_PIN_NO(18) | 6) ++#define MT8127_PIN_18_PCM_CLK__FUNC_DBG_MON_A_0 (MTK_PIN_NO(18) | 7) ++ ++#define MT8127_PIN_19_PCM_SYNC__FUNC_GPIO19 (MTK_PIN_NO(19) | 0) ++#define MT8127_PIN_19_PCM_SYNC__FUNC_PCM_SYNC (MTK_PIN_NO(19) | 1) ++#define MT8127_PIN_19_PCM_SYNC__FUNC_DPI_D3 (MTK_PIN_NO(19) | 2) ++#define MT8127_PIN_19_PCM_SYNC__FUNC_I2SIN1_LRCK (MTK_PIN_NO(19) | 3) ++#define MT8127_PIN_19_PCM_SYNC__FUNC_I2SOUT_LRCK (MTK_PIN_NO(19) | 4) ++#define MT8127_PIN_19_PCM_SYNC__FUNC_CONN_DSP_JINTP (MTK_PIN_NO(19) | 5) ++#define MT8127_PIN_19_PCM_SYNC__FUNC_EXT_COL (MTK_PIN_NO(19) | 6) ++#define MT8127_PIN_19_PCM_SYNC__FUNC_DBG_MON_A_1 (MTK_PIN_NO(19) | 7) ++ ++#define MT8127_PIN_20_PCM_RX__FUNC_GPIO20 (MTK_PIN_NO(20) | 0) ++#define MT8127_PIN_20_PCM_RX__FUNC_PCM_RX (MTK_PIN_NO(20) | 1) ++#define MT8127_PIN_20_PCM_RX__FUNC_DPI_D1 (MTK_PIN_NO(20) | 2) ++#define MT8127_PIN_20_PCM_RX__FUNC_I2SIN1_DATA_IN (MTK_PIN_NO(20) | 3) ++#define MT8127_PIN_20_PCM_RX__FUNC_PCM_TX (MTK_PIN_NO(20) | 4) ++#define MT8127_PIN_20_PCM_RX__FUNC_CONN_DSP_JDI (MTK_PIN_NO(20) | 5) ++#define MT8127_PIN_20_PCM_RX__FUNC_EXT_MDIO (MTK_PIN_NO(20) | 6) ++#define MT8127_PIN_20_PCM_RX__FUNC_DBG_MON_A_2 (MTK_PIN_NO(20) | 7) ++ ++#define MT8127_PIN_21_PCM_TX__FUNC_GPIO21 (MTK_PIN_NO(21) | 0) ++#define MT8127_PIN_21_PCM_TX__FUNC_PCM_TX (MTK_PIN_NO(21) | 1) ++#define MT8127_PIN_21_PCM_TX__FUNC_DPI_D2 (MTK_PIN_NO(21) | 2) ++#define MT8127_PIN_21_PCM_TX__FUNC_I2SOUT_DATA_OUT (MTK_PIN_NO(21) | 3) ++#define MT8127_PIN_21_PCM_TX__FUNC_PCM_RX (MTK_PIN_NO(21) | 4) ++#define MT8127_PIN_21_PCM_TX__FUNC_CONN_DSP_JMS (MTK_PIN_NO(21) | 5) ++#define MT8127_PIN_21_PCM_TX__FUNC_EXT_MDC (MTK_PIN_NO(21) | 6) ++#define MT8127_PIN_21_PCM_TX__FUNC_DBG_MON_A_3 (MTK_PIN_NO(21) | 7) ++ ++#define MT8127_PIN_22_EINT0__FUNC_GPIO22 (MTK_PIN_NO(22) | 0) ++#define MT8127_PIN_22_EINT0__FUNC_PWM1 (MTK_PIN_NO(22) | 1) ++#define MT8127_PIN_22_EINT0__FUNC_DPI_CK (MTK_PIN_NO(22) | 2) ++#define MT8127_PIN_22_EINT0__FUNC_EXT_TXD0 (MTK_PIN_NO(22) | 4) ++#define MT8127_PIN_22_EINT0__FUNC_CONN_DSP_JDO (MTK_PIN_NO(22) | 5) ++#define MT8127_PIN_22_EINT0__FUNC_DBG_MON_A_4 (MTK_PIN_NO(22) | 7) ++ ++#define MT8127_PIN_23_EINT1__FUNC_GPIO23 (MTK_PIN_NO(23) | 0) ++#define MT8127_PIN_23_EINT1__FUNC_PWM2 (MTK_PIN_NO(23) | 1) ++#define MT8127_PIN_23_EINT1__FUNC_DPI_D12 (MTK_PIN_NO(23) | 2) ++#define MT8127_PIN_23_EINT1__FUNC_EXT_TXD1 (MTK_PIN_NO(23) | 4) ++#define MT8127_PIN_23_EINT1__FUNC_CONN_MCU_TDO (MTK_PIN_NO(23) | 5) ++#define MT8127_PIN_23_EINT1__FUNC_DBG_MON_A_5 (MTK_PIN_NO(23) | 7) ++ ++#define MT8127_PIN_24_EINT2__FUNC_GPIO24 (MTK_PIN_NO(24) | 0) ++#define MT8127_PIN_24_EINT2__FUNC_CLKM0 (MTK_PIN_NO(24) | 1) ++#define MT8127_PIN_24_EINT2__FUNC_DPI_D13 (MTK_PIN_NO(24) | 2) ++#define MT8127_PIN_24_EINT2__FUNC_EXT_TXD2 (MTK_PIN_NO(24) | 4) ++#define MT8127_PIN_24_EINT2__FUNC_CONN_MCU_DBGACK_N (MTK_PIN_NO(24) | 5) ++#define MT8127_PIN_24_EINT2__FUNC_KCOL4 (MTK_PIN_NO(24) | 6) ++#define MT8127_PIN_24_EINT2__FUNC_DBG_MON_A_6 (MTK_PIN_NO(24) | 7) ++ ++#define MT8127_PIN_25_EINT3__FUNC_GPIO25 (MTK_PIN_NO(25) | 0) ++#define MT8127_PIN_25_EINT3__FUNC_CLKM1 (MTK_PIN_NO(25) | 1) ++#define MT8127_PIN_25_EINT3__FUNC_DPI_D14 (MTK_PIN_NO(25) | 2) ++#define MT8127_PIN_25_EINT3__FUNC_SPI_MI (MTK_PIN_NO(25) | 3) ++#define MT8127_PIN_25_EINT3__FUNC_EXT_TXD3 (MTK_PIN_NO(25) | 4) ++#define MT8127_PIN_25_EINT3__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(25) | 5) ++#define MT8127_PIN_25_EINT3__FUNC_KCOL5 (MTK_PIN_NO(25) | 6) ++#define MT8127_PIN_25_EINT3__FUNC_DBG_MON_A_7 (MTK_PIN_NO(25) | 7) ++ ++#define MT8127_PIN_26_EINT4__FUNC_GPIO26 (MTK_PIN_NO(26) | 0) ++#define MT8127_PIN_26_EINT4__FUNC_CLKM2 (MTK_PIN_NO(26) | 1) ++#define MT8127_PIN_26_EINT4__FUNC_DPI_D15 (MTK_PIN_NO(26) | 2) ++#define MT8127_PIN_26_EINT4__FUNC_SPI_MO (MTK_PIN_NO(26) | 3) ++#define MT8127_PIN_26_EINT4__FUNC_EXT_TXC (MTK_PIN_NO(26) | 4) ++#define MT8127_PIN_26_EINT4__FUNC_CONN_MCU_TCK0 (MTK_PIN_NO(26) | 5) ++#define MT8127_PIN_26_EINT4__FUNC_CONN_MCU_AICE_JCKC (MTK_PIN_NO(26) | 6) ++#define MT8127_PIN_26_EINT4__FUNC_DBG_MON_A_8 (MTK_PIN_NO(26) | 7) ++ ++#define MT8127_PIN_27_EINT5__FUNC_GPIO27 (MTK_PIN_NO(27) | 0) ++#define MT8127_PIN_27_EINT5__FUNC_UCTS2 (MTK_PIN_NO(27) | 1) ++#define MT8127_PIN_27_EINT5__FUNC_DPI_D16 (MTK_PIN_NO(27) | 2) ++#define MT8127_PIN_27_EINT5__FUNC_SPI_CS (MTK_PIN_NO(27) | 3) ++#define MT8127_PIN_27_EINT5__FUNC_EXT_RXER (MTK_PIN_NO(27) | 4) ++#define MT8127_PIN_27_EINT5__FUNC_CONN_MCU_TDI (MTK_PIN_NO(27) | 5) ++#define MT8127_PIN_27_EINT5__FUNC_KCOL6 (MTK_PIN_NO(27) | 6) ++#define MT8127_PIN_27_EINT5__FUNC_DBG_MON_A_9 (MTK_PIN_NO(27) | 7) ++ ++#define MT8127_PIN_28_EINT6__FUNC_GPIO28 (MTK_PIN_NO(28) | 0) ++#define MT8127_PIN_28_EINT6__FUNC_URTS2 (MTK_PIN_NO(28) | 1) ++#define MT8127_PIN_28_EINT6__FUNC_DPI_D17 (MTK_PIN_NO(28) | 2) ++#define MT8127_PIN_28_EINT6__FUNC_SPI_CK (MTK_PIN_NO(28) | 3) ++#define MT8127_PIN_28_EINT6__FUNC_EXT_RXC (MTK_PIN_NO(28) | 4) ++#define MT8127_PIN_28_EINT6__FUNC_CONN_MCU_TRST_B (MTK_PIN_NO(28) | 5) ++#define MT8127_PIN_28_EINT6__FUNC_KCOL7 (MTK_PIN_NO(28) | 6) ++#define MT8127_PIN_28_EINT6__FUNC_DBG_MON_A_10 (MTK_PIN_NO(28) | 7) ++ ++#define MT8127_PIN_29_EINT7__FUNC_GPIO29 (MTK_PIN_NO(29) | 0) ++#define MT8127_PIN_29_EINT7__FUNC_UCTS3 (MTK_PIN_NO(29) | 1) ++#define MT8127_PIN_29_EINT7__FUNC_DPI_D6 (MTK_PIN_NO(29) | 2) ++#define MT8127_PIN_29_EINT7__FUNC_SDA1 (MTK_PIN_NO(29) | 3) ++#define MT8127_PIN_29_EINT7__FUNC_EXT_RXDV (MTK_PIN_NO(29) | 4) ++#define MT8127_PIN_29_EINT7__FUNC_CONN_MCU_TMS (MTK_PIN_NO(29) | 5) ++#define MT8127_PIN_29_EINT7__FUNC_CONN_MCU_AICE_JMSC (MTK_PIN_NO(29) | 6) ++#define MT8127_PIN_29_EINT7__FUNC_DBG_MON_A_11 (MTK_PIN_NO(29) | 7) ++ ++#define MT8127_PIN_30_EINT8__FUNC_GPIO30 (MTK_PIN_NO(30) | 0) ++#define MT8127_PIN_30_EINT8__FUNC_URTS3 (MTK_PIN_NO(30) | 1) ++#define MT8127_PIN_30_EINT8__FUNC_CLKM3 (MTK_PIN_NO(30) | 2) ++#define MT8127_PIN_30_EINT8__FUNC_SCL1 (MTK_PIN_NO(30) | 3) ++#define MT8127_PIN_30_EINT8__FUNC_EXT_RXD0 (MTK_PIN_NO(30) | 4) ++#define MT8127_PIN_30_EINT8__FUNC_ANT_SEL0 (MTK_PIN_NO(30) | 5) ++#define MT8127_PIN_30_EINT8__FUNC_DPI_D7 (MTK_PIN_NO(30) | 6) ++#define MT8127_PIN_30_EINT8__FUNC_DBG_MON_B_2 (MTK_PIN_NO(30) | 7) ++ ++#define MT8127_PIN_31_EINT9__FUNC_GPIO31 (MTK_PIN_NO(31) | 0) ++#define MT8127_PIN_31_EINT9__FUNC_CLKM4 (MTK_PIN_NO(31) | 1) ++#define MT8127_PIN_31_EINT9__FUNC_SDA2 (MTK_PIN_NO(31) | 2) ++#define MT8127_PIN_31_EINT9__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(31) | 3) ++#define MT8127_PIN_31_EINT9__FUNC_EXT_RXD1 (MTK_PIN_NO(31) | 4) ++#define MT8127_PIN_31_EINT9__FUNC_ANT_SEL1 (MTK_PIN_NO(31) | 5) ++#define MT8127_PIN_31_EINT9__FUNC_DPI_D8 (MTK_PIN_NO(31) | 6) ++#define MT8127_PIN_31_EINT9__FUNC_DBG_MON_B_3 (MTK_PIN_NO(31) | 7) ++ ++#define MT8127_PIN_32_EINT10__FUNC_GPIO32 (MTK_PIN_NO(32) | 0) ++#define MT8127_PIN_32_EINT10__FUNC_CLKM5 (MTK_PIN_NO(32) | 1) ++#define MT8127_PIN_32_EINT10__FUNC_SCL2 (MTK_PIN_NO(32) | 2) ++#define MT8127_PIN_32_EINT10__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(32) | 3) ++#define MT8127_PIN_32_EINT10__FUNC_EXT_RXD2 (MTK_PIN_NO(32) | 4) ++#define MT8127_PIN_32_EINT10__FUNC_ANT_SEL2 (MTK_PIN_NO(32) | 5) ++#define MT8127_PIN_32_EINT10__FUNC_DPI_D9 (MTK_PIN_NO(32) | 6) ++#define MT8127_PIN_32_EINT10__FUNC_DBG_MON_B_4 (MTK_PIN_NO(32) | 7) ++ ++#define MT8127_PIN_33_KPROW0__FUNC_GPIO33 (MTK_PIN_NO(33) | 0) ++#define MT8127_PIN_33_KPROW0__FUNC_KROW0 (MTK_PIN_NO(33) | 1) ++#define MT8127_PIN_33_KPROW0__FUNC_IMG_TEST_CK (MTK_PIN_NO(33) | 4) ++#define MT8127_PIN_33_KPROW0__FUNC_DBG_MON_A_12 (MTK_PIN_NO(33) | 7) ++ ++#define MT8127_PIN_34_KPROW1__FUNC_GPIO34 (MTK_PIN_NO(34) | 0) ++#define MT8127_PIN_34_KPROW1__FUNC_KROW1 (MTK_PIN_NO(34) | 1) ++#define MT8127_PIN_34_KPROW1__FUNC_IDDIG (MTK_PIN_NO(34) | 2) ++#define MT8127_PIN_34_KPROW1__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(34) | 3) ++#define MT8127_PIN_34_KPROW1__FUNC_MFG_TEST_CK (MTK_PIN_NO(34) | 4) ++#define MT8127_PIN_34_KPROW1__FUNC_DBG_MON_B_5 (MTK_PIN_NO(34) | 7) ++ ++#define MT8127_PIN_35_KPROW2__FUNC_GPIO35 (MTK_PIN_NO(35) | 0) ++#define MT8127_PIN_35_KPROW2__FUNC_KROW2 (MTK_PIN_NO(35) | 1) ++#define MT8127_PIN_35_KPROW2__FUNC_DRV_VBUS (MTK_PIN_NO(35) | 2) ++#define MT8127_PIN_35_KPROW2__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(35) | 3) ++#define MT8127_PIN_35_KPROW2__FUNC_CONN_TEST_CK (MTK_PIN_NO(35) | 4) ++#define MT8127_PIN_35_KPROW2__FUNC_DBG_MON_B_6 (MTK_PIN_NO(35) | 7) ++ ++#define MT8127_PIN_36_KPCOL0__FUNC_GPIO36 (MTK_PIN_NO(36) | 0) ++#define MT8127_PIN_36_KPCOL0__FUNC_KCOL0 (MTK_PIN_NO(36) | 1) ++#define MT8127_PIN_36_KPCOL0__FUNC_DBG_MON_A_13 (MTK_PIN_NO(36) | 7) ++ ++#define MT8127_PIN_37_KPCOL1__FUNC_GPIO37 (MTK_PIN_NO(37) | 0) ++#define MT8127_PIN_37_KPCOL1__FUNC_KCOL1 (MTK_PIN_NO(37) | 1) ++#define MT8127_PIN_37_KPCOL1__FUNC_DBG_MON_B_7 (MTK_PIN_NO(37) | 7) ++ ++#define MT8127_PIN_38_KPCOL2__FUNC_GPIO38 (MTK_PIN_NO(38) | 0) ++#define MT8127_PIN_38_KPCOL2__FUNC_KCOL2 (MTK_PIN_NO(38) | 1) ++#define MT8127_PIN_38_KPCOL2__FUNC_IDDIG (MTK_PIN_NO(38) | 2) ++#define MT8127_PIN_38_KPCOL2__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(38) | 3) ++#define MT8127_PIN_38_KPCOL2__FUNC_DBG_MON_B_8 (MTK_PIN_NO(38) | 7) ++ ++#define MT8127_PIN_39_JTMS__FUNC_GPIO39 (MTK_PIN_NO(39) | 0) ++#define MT8127_PIN_39_JTMS__FUNC_JTMS (MTK_PIN_NO(39) | 1) ++#define MT8127_PIN_39_JTMS__FUNC_CONN_MCU_TMS (MTK_PIN_NO(39) | 2) ++#define MT8127_PIN_39_JTMS__FUNC_CONN_MCU_AICE_JMSC (MTK_PIN_NO(39) | 3) ++ ++#define MT8127_PIN_40_JTCK__FUNC_GPIO40 (MTK_PIN_NO(40) | 0) ++#define MT8127_PIN_40_JTCK__FUNC_JTCK (MTK_PIN_NO(40) | 1) ++#define MT8127_PIN_40_JTCK__FUNC_CONN_MCU_TCK1 (MTK_PIN_NO(40) | 2) ++#define MT8127_PIN_40_JTCK__FUNC_CONN_MCU_AICE_JCKC (MTK_PIN_NO(40) | 3) ++ ++#define MT8127_PIN_41_JTDI__FUNC_GPIO41 (MTK_PIN_NO(41) | 0) ++#define MT8127_PIN_41_JTDI__FUNC_JTDI (MTK_PIN_NO(41) | 1) ++#define MT8127_PIN_41_JTDI__FUNC_CONN_MCU_TDI (MTK_PIN_NO(41) | 2) ++ ++#define MT8127_PIN_42_JTDO__FUNC_GPIO42 (MTK_PIN_NO(42) | 0) ++#define MT8127_PIN_42_JTDO__FUNC_JTDO (MTK_PIN_NO(42) | 1) ++#define MT8127_PIN_42_JTDO__FUNC_CONN_MCU_TDO (MTK_PIN_NO(42) | 2) ++ ++#define MT8127_PIN_43_EINT11__FUNC_GPIO43 (MTK_PIN_NO(43) | 0) ++#define MT8127_PIN_43_EINT11__FUNC_CLKM4 (MTK_PIN_NO(43) | 1) ++#define MT8127_PIN_43_EINT11__FUNC_PWM2 (MTK_PIN_NO(43) | 2) ++#define MT8127_PIN_43_EINT11__FUNC_KROW3 (MTK_PIN_NO(43) | 3) ++#define MT8127_PIN_43_EINT11__FUNC_ANT_SEL3 (MTK_PIN_NO(43) | 4) ++#define MT8127_PIN_43_EINT11__FUNC_DPI_D10 (MTK_PIN_NO(43) | 5) ++#define MT8127_PIN_43_EINT11__FUNC_EXT_RXD3 (MTK_PIN_NO(43) | 6) ++#define MT8127_PIN_43_EINT11__FUNC_DBG_MON_B_9 (MTK_PIN_NO(43) | 7) ++ ++#define MT8127_PIN_44_EINT12__FUNC_GPIO44 (MTK_PIN_NO(44) | 0) ++#define MT8127_PIN_44_EINT12__FUNC_CLKM5 (MTK_PIN_NO(44) | 1) ++#define MT8127_PIN_44_EINT12__FUNC_PWM0 (MTK_PIN_NO(44) | 2) ++#define MT8127_PIN_44_EINT12__FUNC_KCOL3 (MTK_PIN_NO(44) | 3) ++#define MT8127_PIN_44_EINT12__FUNC_ANT_SEL4 (MTK_PIN_NO(44) | 4) ++#define MT8127_PIN_44_EINT12__FUNC_DPI_D11 (MTK_PIN_NO(44) | 5) ++#define MT8127_PIN_44_EINT12__FUNC_EXT_TXEN (MTK_PIN_NO(44) | 6) ++#define MT8127_PIN_44_EINT12__FUNC_DBG_MON_B_10 (MTK_PIN_NO(44) | 7) ++ ++#define MT8127_PIN_45_EINT13__FUNC_GPIO45 (MTK_PIN_NO(45) | 0) ++#define MT8127_PIN_45_EINT13__FUNC_ANT_SEL5 (MTK_PIN_NO(45) | 4) ++#define MT8127_PIN_45_EINT13__FUNC_DPI_D0 (MTK_PIN_NO(45) | 5) ++#define MT8127_PIN_45_EINT13__FUNC_SPDIF (MTK_PIN_NO(45) | 6) ++#define MT8127_PIN_45_EINT13__FUNC_DBG_MON_B_11 (MTK_PIN_NO(45) | 7) ++ ++#define MT8127_PIN_46_EINT14__FUNC_GPIO46 (MTK_PIN_NO(46) | 0) ++#define MT8127_PIN_46_EINT14__FUNC_DAC_DAT_OUT (MTK_PIN_NO(46) | 2) ++#define MT8127_PIN_46_EINT14__FUNC_ANT_SEL1 (MTK_PIN_NO(46) | 4) ++#define MT8127_PIN_46_EINT14__FUNC_CONN_MCU_DBGACK_N (MTK_PIN_NO(46) | 5) ++#define MT8127_PIN_46_EINT14__FUNC_NCLE (MTK_PIN_NO(46) | 6) ++#define MT8127_PIN_46_EINT14__FUNC_DBG_MON_A_14 (MTK_PIN_NO(46) | 7) ++ ++#define MT8127_PIN_47_EINT15__FUNC_GPIO47 (MTK_PIN_NO(47) | 0) ++#define MT8127_PIN_47_EINT15__FUNC_DAC_WS (MTK_PIN_NO(47) | 2) ++#define MT8127_PIN_47_EINT15__FUNC_ANT_SEL2 (MTK_PIN_NO(47) | 4) ++#define MT8127_PIN_47_EINT15__FUNC_CONN_MCU_DBGI_N (MTK_PIN_NO(47) | 5) ++#define MT8127_PIN_47_EINT15__FUNC_NCEB1 (MTK_PIN_NO(47) | 6) ++#define MT8127_PIN_47_EINT15__FUNC_DBG_MON_A_15 (MTK_PIN_NO(47) | 7) ++ ++#define MT8127_PIN_48_EINT16__FUNC_GPIO48 (MTK_PIN_NO(48) | 0) ++#define MT8127_PIN_48_EINT16__FUNC_DAC_CK (MTK_PIN_NO(48) | 2) ++#define MT8127_PIN_48_EINT16__FUNC_ANT_SEL3 (MTK_PIN_NO(48) | 4) ++#define MT8127_PIN_48_EINT16__FUNC_CONN_MCU_TRST_B (MTK_PIN_NO(48) | 5) ++#define MT8127_PIN_48_EINT16__FUNC_NCEB0 (MTK_PIN_NO(48) | 6) ++#define MT8127_PIN_48_EINT16__FUNC_DBG_MON_A_16 (MTK_PIN_NO(48) | 7) ++ ++#define MT8127_PIN_49_EINT17__FUNC_GPIO49 (MTK_PIN_NO(49) | 0) ++#define MT8127_PIN_49_EINT17__FUNC_UCTS0 (MTK_PIN_NO(49) | 1) ++#define MT8127_PIN_49_EINT17__FUNC_CLKM0 (MTK_PIN_NO(49) | 3) ++#define MT8127_PIN_49_EINT17__FUNC_IDDIG (MTK_PIN_NO(49) | 4) ++#define MT8127_PIN_49_EINT17__FUNC_ANT_SEL4 (MTK_PIN_NO(49) | 5) ++#define MT8127_PIN_49_EINT17__FUNC_NREB (MTK_PIN_NO(49) | 6) ++#define MT8127_PIN_49_EINT17__FUNC_DBG_MON_A_17 (MTK_PIN_NO(49) | 7) ++ ++#define MT8127_PIN_50_EINT18__FUNC_GPIO50 (MTK_PIN_NO(50) | 0) ++#define MT8127_PIN_50_EINT18__FUNC_URTS0 (MTK_PIN_NO(50) | 1) ++#define MT8127_PIN_50_EINT18__FUNC_CLKM3 (MTK_PIN_NO(50) | 2) ++#define MT8127_PIN_50_EINT18__FUNC_I2SOUT_LRCK (MTK_PIN_NO(50) | 3) ++#define MT8127_PIN_50_EINT18__FUNC_DRV_VBUS (MTK_PIN_NO(50) | 4) ++#define MT8127_PIN_50_EINT18__FUNC_ANT_SEL3 (MTK_PIN_NO(50) | 5) ++#define MT8127_PIN_50_EINT18__FUNC_ADC_CK (MTK_PIN_NO(50) | 6) ++#define MT8127_PIN_50_EINT18__FUNC_DBG_MON_B_12 (MTK_PIN_NO(50) | 7) ++ ++#define MT8127_PIN_51_EINT19__FUNC_GPIO51 (MTK_PIN_NO(51) | 0) ++#define MT8127_PIN_51_EINT19__FUNC_UCTS1 (MTK_PIN_NO(51) | 1) ++#define MT8127_PIN_51_EINT19__FUNC_I2SOUT_BCK (MTK_PIN_NO(51) | 3) ++#define MT8127_PIN_51_EINT19__FUNC_CLKM1 (MTK_PIN_NO(51) | 4) ++#define MT8127_PIN_51_EINT19__FUNC_ANT_SEL4 (MTK_PIN_NO(51) | 5) ++#define MT8127_PIN_51_EINT19__FUNC_ADC_DAT_IN (MTK_PIN_NO(51) | 6) ++#define MT8127_PIN_51_EINT19__FUNC_DBG_MON_B_13 (MTK_PIN_NO(51) | 7) ++ ++#define MT8127_PIN_52_EINT20__FUNC_GPIO52 (MTK_PIN_NO(52) | 0) ++#define MT8127_PIN_52_EINT20__FUNC_URTS1 (MTK_PIN_NO(52) | 1) ++#define MT8127_PIN_52_EINT20__FUNC_PCM_TX (MTK_PIN_NO(52) | 2) ++#define MT8127_PIN_52_EINT20__FUNC_I2SOUT_DATA_OUT (MTK_PIN_NO(52) | 3) ++#define MT8127_PIN_52_EINT20__FUNC_CLKM2 (MTK_PIN_NO(52) | 4) ++#define MT8127_PIN_52_EINT20__FUNC_ANT_SEL5 (MTK_PIN_NO(52) | 5) ++#define MT8127_PIN_52_EINT20__FUNC_ADC_WS (MTK_PIN_NO(52) | 6) ++#define MT8127_PIN_52_EINT20__FUNC_DBG_MON_B_14 (MTK_PIN_NO(52) | 7) ++ ++#define MT8127_PIN_53_SPI_CS__FUNC_GPIO53 (MTK_PIN_NO(53) | 0) ++#define MT8127_PIN_53_SPI_CS__FUNC_SPI_CS (MTK_PIN_NO(53) | 1) ++#define MT8127_PIN_53_SPI_CS__FUNC_I2SIN1_DATA_IN (MTK_PIN_NO(53) | 3) ++#define MT8127_PIN_53_SPI_CS__FUNC_ADC_CK (MTK_PIN_NO(53) | 4) ++#define MT8127_PIN_53_SPI_CS__FUNC_DBG_MON_B_15 (MTK_PIN_NO(53) | 7) ++ ++#define MT8127_PIN_54_SPI_CK__FUNC_GPIO54 (MTK_PIN_NO(54) | 0) ++#define MT8127_PIN_54_SPI_CK__FUNC_SPI_CK (MTK_PIN_NO(54) | 1) ++#define MT8127_PIN_54_SPI_CK__FUNC_I2SIN1_LRCK (MTK_PIN_NO(54) | 3) ++#define MT8127_PIN_54_SPI_CK__FUNC_ADC_DAT_IN (MTK_PIN_NO(54) | 4) ++#define MT8127_PIN_54_SPI_CK__FUNC_DBG_MON_B_16 (MTK_PIN_NO(54) | 7) ++ ++#define MT8127_PIN_55_SPI_MI__FUNC_GPIO55 (MTK_PIN_NO(55) | 0) ++#define MT8127_PIN_55_SPI_MI__FUNC_SPI_MI (MTK_PIN_NO(55) | 1) ++#define MT8127_PIN_55_SPI_MI__FUNC_SPI_MO (MTK_PIN_NO(55) | 2) ++#define MT8127_PIN_55_SPI_MI__FUNC_I2SIN1_BCK1 (MTK_PIN_NO(55) | 3) ++#define MT8127_PIN_55_SPI_MI__FUNC_ADC_WS (MTK_PIN_NO(55) | 4) ++#define MT8127_PIN_55_SPI_MI__FUNC_DBG_MON_B_17 (MTK_PIN_NO(55) | 7) ++ ++#define MT8127_PIN_56_SPI_MO__FUNC_GPIO56 (MTK_PIN_NO(56) | 0) ++#define MT8127_PIN_56_SPI_MO__FUNC_SPI_MO (MTK_PIN_NO(56) | 1) ++#define MT8127_PIN_56_SPI_MO__FUNC_SPI_MI (MTK_PIN_NO(56) | 2) ++#define MT8127_PIN_56_SPI_MO__FUNC_DBG_MON_B_18 (MTK_PIN_NO(56) | 7) ++ ++#define MT8127_PIN_57_SDA1__FUNC_GPIO57 (MTK_PIN_NO(57) | 0) ++#define MT8127_PIN_57_SDA1__FUNC_SDA1 (MTK_PIN_NO(57) | 1) ++ ++#define MT8127_PIN_58_SCL1__FUNC_GPIO58 (MTK_PIN_NO(58) | 0) ++#define MT8127_PIN_58_SCL1__FUNC_SCL1 (MTK_PIN_NO(58) | 1) ++ ++#define MT8127_PIN_59_DISP_PWM__FUNC_GPIO59 (MTK_PIN_NO(59) | 0) ++#define MT8127_PIN_59_DISP_PWM__FUNC_DISP_PWM (MTK_PIN_NO(59) | 1) ++#define MT8127_PIN_59_DISP_PWM__FUNC_PWM1 (MTK_PIN_NO(59) | 2) ++#define MT8127_PIN_59_DISP_PWM__FUNC_DBG_MON_A_18 (MTK_PIN_NO(59) | 7) ++ ++#define MT8127_PIN_60_WB_RSTB__FUNC_GPIO60 (MTK_PIN_NO(60) | 0) ++#define MT8127_PIN_60_WB_RSTB__FUNC_WB_RSTB (MTK_PIN_NO(60) | 1) ++#define MT8127_PIN_60_WB_RSTB__FUNC_DBG_MON_A_19 (MTK_PIN_NO(60) | 7) ++ ++#define MT8127_PIN_61_F2W_DATA__FUNC_GPIO61 (MTK_PIN_NO(61) | 0) ++#define MT8127_PIN_61_F2W_DATA__FUNC_F2W_DATA (MTK_PIN_NO(61) | 1) ++#define MT8127_PIN_61_F2W_DATA__FUNC_DBG_MON_A_20 (MTK_PIN_NO(61) | 7) ++ ++#define MT8127_PIN_62_F2W_CLK__FUNC_GPIO62 (MTK_PIN_NO(62) | 0) ++#define MT8127_PIN_62_F2W_CLK__FUNC_F2W_CK (MTK_PIN_NO(62) | 1) ++#define MT8127_PIN_62_F2W_CLK__FUNC_DBG_MON_A_21 (MTK_PIN_NO(62) | 7) ++ ++#define MT8127_PIN_63_WB_SCLK__FUNC_GPIO63 (MTK_PIN_NO(63) | 0) ++#define MT8127_PIN_63_WB_SCLK__FUNC_WB_SCLK (MTK_PIN_NO(63) | 1) ++#define MT8127_PIN_63_WB_SCLK__FUNC_DBG_MON_A_22 (MTK_PIN_NO(63) | 7) ++ ++#define MT8127_PIN_64_WB_SDATA__FUNC_GPIO64 (MTK_PIN_NO(64) | 0) ++#define MT8127_PIN_64_WB_SDATA__FUNC_WB_SDATA (MTK_PIN_NO(64) | 1) ++#define MT8127_PIN_64_WB_SDATA__FUNC_DBG_MON_A_23 (MTK_PIN_NO(64) | 7) ++ ++#define MT8127_PIN_65_WB_SEN__FUNC_GPIO65 (MTK_PIN_NO(65) | 0) ++#define MT8127_PIN_65_WB_SEN__FUNC_WB_SEN (MTK_PIN_NO(65) | 1) ++#define MT8127_PIN_65_WB_SEN__FUNC_DBG_MON_A_24 (MTK_PIN_NO(65) | 7) ++ ++#define MT8127_PIN_66_WB_CRTL0__FUNC_GPIO66 (MTK_PIN_NO(66) | 0) ++#define MT8127_PIN_66_WB_CRTL0__FUNC_WB_CRTL0 (MTK_PIN_NO(66) | 1) ++#define MT8127_PIN_66_WB_CRTL0__FUNC_DFD_NTRST_XI (MTK_PIN_NO(66) | 2) ++#define MT8127_PIN_66_WB_CRTL0__FUNC_DBG_MON_A_25 (MTK_PIN_NO(66) | 7) ++ ++#define MT8127_PIN_67_WB_CRTL1__FUNC_GPIO67 (MTK_PIN_NO(67) | 0) ++#define MT8127_PIN_67_WB_CRTL1__FUNC_WB_CRTL1 (MTK_PIN_NO(67) | 1) ++#define MT8127_PIN_67_WB_CRTL1__FUNC_DFD_TMS_XI (MTK_PIN_NO(67) | 2) ++#define MT8127_PIN_67_WB_CRTL1__FUNC_DBG_MON_A_26 (MTK_PIN_NO(67) | 7) ++ ++#define MT8127_PIN_68_WB_CRTL2__FUNC_GPIO68 (MTK_PIN_NO(68) | 0) ++#define MT8127_PIN_68_WB_CRTL2__FUNC_WB_CRTL2 (MTK_PIN_NO(68) | 1) ++#define MT8127_PIN_68_WB_CRTL2__FUNC_DFD_TCK_XI (MTK_PIN_NO(68) | 2) ++#define MT8127_PIN_68_WB_CRTL2__FUNC_DBG_MON_A_27 (MTK_PIN_NO(68) | 7) ++ ++#define MT8127_PIN_69_WB_CRTL3__FUNC_GPIO69 (MTK_PIN_NO(69) | 0) ++#define MT8127_PIN_69_WB_CRTL3__FUNC_WB_CRTL3 (MTK_PIN_NO(69) | 1) ++#define MT8127_PIN_69_WB_CRTL3__FUNC_DFD_TDI_XI (MTK_PIN_NO(69) | 2) ++#define MT8127_PIN_69_WB_CRTL3__FUNC_DBG_MON_A_28 (MTK_PIN_NO(69) | 7) ++ ++#define MT8127_PIN_70_WB_CRTL4__FUNC_GPIO70 (MTK_PIN_NO(70) | 0) ++#define MT8127_PIN_70_WB_CRTL4__FUNC_WB_CRTL4 (MTK_PIN_NO(70) | 1) ++#define MT8127_PIN_70_WB_CRTL4__FUNC_DFD_TDO (MTK_PIN_NO(70) | 2) ++#define MT8127_PIN_70_WB_CRTL4__FUNC_DBG_MON_A_29 (MTK_PIN_NO(70) | 7) ++ ++#define MT8127_PIN_71_WB_CRTL5__FUNC_GPIO71 (MTK_PIN_NO(71) | 0) ++#define MT8127_PIN_71_WB_CRTL5__FUNC_WB_CRTL5 (MTK_PIN_NO(71) | 1) ++#define MT8127_PIN_71_WB_CRTL5__FUNC_DBG_MON_A_30 (MTK_PIN_NO(71) | 7) ++ ++#define MT8127_PIN_72_I2S_DATA_IN__FUNC_GPIO72 (MTK_PIN_NO(72) | 0) ++#define MT8127_PIN_72_I2S_DATA_IN__FUNC_I2SIN1_DATA_IN (MTK_PIN_NO(72) | 1) ++#define MT8127_PIN_72_I2S_DATA_IN__FUNC_PCM_RX (MTK_PIN_NO(72) | 2) ++#define MT8127_PIN_72_I2S_DATA_IN__FUNC_I2SOUT_DATA_OUT (MTK_PIN_NO(72) | 3) ++#define MT8127_PIN_72_I2S_DATA_IN__FUNC_DAC_DAT_OUT (MTK_PIN_NO(72) | 4) ++#define MT8127_PIN_72_I2S_DATA_IN__FUNC_PWM0 (MTK_PIN_NO(72) | 5) ++#define MT8127_PIN_72_I2S_DATA_IN__FUNC_ADC_CK (MTK_PIN_NO(72) | 6) ++#define MT8127_PIN_72_I2S_DATA_IN__FUNC_DBG_MON_B_19 (MTK_PIN_NO(72) | 7) ++ ++#define MT8127_PIN_73_I2S_LRCK__FUNC_GPIO73 (MTK_PIN_NO(73) | 0) ++#define MT8127_PIN_73_I2S_LRCK__FUNC_I2SIN1_LRCK (MTK_PIN_NO(73) | 1) ++#define MT8127_PIN_73_I2S_LRCK__FUNC_PCM_SYNC (MTK_PIN_NO(73) | 2) ++#define MT8127_PIN_73_I2S_LRCK__FUNC_I2SOUT_LRCK (MTK_PIN_NO(73) | 3) ++#define MT8127_PIN_73_I2S_LRCK__FUNC_DAC_WS (MTK_PIN_NO(73) | 4) ++#define MT8127_PIN_73_I2S_LRCK__FUNC_PWM3 (MTK_PIN_NO(73) | 5) ++#define MT8127_PIN_73_I2S_LRCK__FUNC_ADC_DAT_IN (MTK_PIN_NO(73) | 6) ++#define MT8127_PIN_73_I2S_LRCK__FUNC_DBG_MON_B_20 (MTK_PIN_NO(73) | 7) ++ ++#define MT8127_PIN_74_I2S_BCK__FUNC_GPIO74 (MTK_PIN_NO(74) | 0) ++#define MT8127_PIN_74_I2S_BCK__FUNC_I2SIN1_BCK2 (MTK_PIN_NO(74) | 1) ++#define MT8127_PIN_74_I2S_BCK__FUNC_PCM_CLK1 (MTK_PIN_NO(74) | 2) ++#define MT8127_PIN_74_I2S_BCK__FUNC_I2SOUT_BCK (MTK_PIN_NO(74) | 3) ++#define MT8127_PIN_74_I2S_BCK__FUNC_DAC_CK (MTK_PIN_NO(74) | 4) ++#define MT8127_PIN_74_I2S_BCK__FUNC_PWM4 (MTK_PIN_NO(74) | 5) ++#define MT8127_PIN_74_I2S_BCK__FUNC_ADC_WS (MTK_PIN_NO(74) | 6) ++#define MT8127_PIN_74_I2S_BCK__FUNC_DBG_MON_B_21 (MTK_PIN_NO(74) | 7) ++ ++#define MT8127_PIN_75_SDA0__FUNC_GPIO75 (MTK_PIN_NO(75) | 0) ++#define MT8127_PIN_75_SDA0__FUNC_SDA0 (MTK_PIN_NO(75) | 1) ++ ++#define MT8127_PIN_76_SCL0__FUNC_GPIO76 (MTK_PIN_NO(76) | 0) ++#define MT8127_PIN_76_SCL0__FUNC_SCL0 (MTK_PIN_NO(76) | 1) ++ ++#define MT8127_PIN_77_SDA2__FUNC_GPIO77 (MTK_PIN_NO(77) | 0) ++#define MT8127_PIN_77_SDA2__FUNC_SDA2 (MTK_PIN_NO(77) | 1) ++#define MT8127_PIN_77_SDA2__FUNC_PWM1 (MTK_PIN_NO(77) | 2) ++ ++#define MT8127_PIN_78_SCL2__FUNC_GPIO78 (MTK_PIN_NO(78) | 0) ++#define MT8127_PIN_78_SCL2__FUNC_SCL2 (MTK_PIN_NO(78) | 1) ++#define MT8127_PIN_78_SCL2__FUNC_PWM2 (MTK_PIN_NO(78) | 2) ++ ++#define MT8127_PIN_79_URXD0__FUNC_GPIO79 (MTK_PIN_NO(79) | 0) ++#define MT8127_PIN_79_URXD0__FUNC_URXD0 (MTK_PIN_NO(79) | 1) ++#define MT8127_PIN_79_URXD0__FUNC_UTXD0 (MTK_PIN_NO(79) | 2) ++ ++#define MT8127_PIN_80_UTXD0__FUNC_GPIO80 (MTK_PIN_NO(80) | 0) ++#define MT8127_PIN_80_UTXD0__FUNC_UTXD0 (MTK_PIN_NO(80) | 1) ++#define MT8127_PIN_80_UTXD0__FUNC_URXD0 (MTK_PIN_NO(80) | 2) ++ ++#define MT8127_PIN_81_URXD1__FUNC_GPIO81 (MTK_PIN_NO(81) | 0) ++#define MT8127_PIN_81_URXD1__FUNC_URXD1 (MTK_PIN_NO(81) | 1) ++#define MT8127_PIN_81_URXD1__FUNC_UTXD1 (MTK_PIN_NO(81) | 2) ++ ++#define MT8127_PIN_82_UTXD1__FUNC_GPIO82 (MTK_PIN_NO(82) | 0) ++#define MT8127_PIN_82_UTXD1__FUNC_UTXD1 (MTK_PIN_NO(82) | 1) ++#define MT8127_PIN_82_UTXD1__FUNC_URXD1 (MTK_PIN_NO(82) | 2) ++ ++#define MT8127_PIN_83_LCM_RST__FUNC_GPIO83 (MTK_PIN_NO(83) | 0) ++#define MT8127_PIN_83_LCM_RST__FUNC_LCM_RST (MTK_PIN_NO(83) | 1) ++#define MT8127_PIN_83_LCM_RST__FUNC_VDAC_CK_XI (MTK_PIN_NO(83) | 2) ++#define MT8127_PIN_83_LCM_RST__FUNC_DBG_MON_A_31 (MTK_PIN_NO(83) | 7) ++ ++#define MT8127_PIN_84_DSI_TE__FUNC_GPIO84 (MTK_PIN_NO(84) | 0) ++#define MT8127_PIN_84_DSI_TE__FUNC_DSI_TE (MTK_PIN_NO(84) | 1) ++#define MT8127_PIN_84_DSI_TE__FUNC_DBG_MON_A_32 (MTK_PIN_NO(84) | 7) ++ ++#define MT8127_PIN_85_MSDC2_CMD__FUNC_GPIO85 (MTK_PIN_NO(85) | 0) ++#define MT8127_PIN_85_MSDC2_CMD__FUNC_MSDC2_CMD (MTK_PIN_NO(85) | 1) ++#define MT8127_PIN_85_MSDC2_CMD__FUNC_ANT_SEL0 (MTK_PIN_NO(85) | 2) ++#define MT8127_PIN_85_MSDC2_CMD__FUNC_SDA1 (MTK_PIN_NO(85) | 3) ++#define MT8127_PIN_85_MSDC2_CMD__FUNC_I2SOUT_BCK (MTK_PIN_NO(85) | 6) ++#define MT8127_PIN_85_MSDC2_CMD__FUNC_DBG_MON_B_22 (MTK_PIN_NO(85) | 7) ++ ++#define MT8127_PIN_86_MSDC2_CLK__FUNC_GPIO86 (MTK_PIN_NO(86) | 0) ++#define MT8127_PIN_86_MSDC2_CLK__FUNC_MSDC2_CLK (MTK_PIN_NO(86) | 1) ++#define MT8127_PIN_86_MSDC2_CLK__FUNC_ANT_SEL1 (MTK_PIN_NO(86) | 2) ++#define MT8127_PIN_86_MSDC2_CLK__FUNC_SCL1 (MTK_PIN_NO(86) | 3) ++#define MT8127_PIN_86_MSDC2_CLK__FUNC_I2SOUT_LRCK (MTK_PIN_NO(86) | 6) ++#define MT8127_PIN_86_MSDC2_CLK__FUNC_DBG_MON_B_23 (MTK_PIN_NO(86) | 7) ++ ++#define MT8127_PIN_87_MSDC2_DAT0__FUNC_GPIO87 (MTK_PIN_NO(87) | 0) ++#define MT8127_PIN_87_MSDC2_DAT0__FUNC_MSDC2_DAT0 (MTK_PIN_NO(87) | 1) ++#define MT8127_PIN_87_MSDC2_DAT0__FUNC_ANT_SEL2 (MTK_PIN_NO(87) | 2) ++#define MT8127_PIN_87_MSDC2_DAT0__FUNC_UTXD0 (MTK_PIN_NO(87) | 5) ++#define MT8127_PIN_87_MSDC2_DAT0__FUNC_I2SOUT_DATA_OUT (MTK_PIN_NO(87) | 6) ++#define MT8127_PIN_87_MSDC2_DAT0__FUNC_DBG_MON_B_24 (MTK_PIN_NO(87) | 7) ++ ++#define MT8127_PIN_88_MSDC2_DAT1__FUNC_GPIO88 (MTK_PIN_NO(88) | 0) ++#define MT8127_PIN_88_MSDC2_DAT1__FUNC_MSDC2_DAT1 (MTK_PIN_NO(88) | 1) ++#define MT8127_PIN_88_MSDC2_DAT1__FUNC_ANT_SEL3 (MTK_PIN_NO(88) | 2) ++#define MT8127_PIN_88_MSDC2_DAT1__FUNC_PWM0 (MTK_PIN_NO(88) | 3) ++#define MT8127_PIN_88_MSDC2_DAT1__FUNC_URXD0 (MTK_PIN_NO(88) | 5) ++#define MT8127_PIN_88_MSDC2_DAT1__FUNC_PWM1 (MTK_PIN_NO(88) | 6) ++#define MT8127_PIN_88_MSDC2_DAT1__FUNC_DBG_MON_B_25 (MTK_PIN_NO(88) | 7) ++ ++#define MT8127_PIN_89_MSDC2_DAT2__FUNC_GPIO89 (MTK_PIN_NO(89) | 0) ++#define MT8127_PIN_89_MSDC2_DAT2__FUNC_MSDC2_DAT2 (MTK_PIN_NO(89) | 1) ++#define MT8127_PIN_89_MSDC2_DAT2__FUNC_ANT_SEL4 (MTK_PIN_NO(89) | 2) ++#define MT8127_PIN_89_MSDC2_DAT2__FUNC_SDA2 (MTK_PIN_NO(89) | 3) ++#define MT8127_PIN_89_MSDC2_DAT2__FUNC_UTXD1 (MTK_PIN_NO(89) | 5) ++#define MT8127_PIN_89_MSDC2_DAT2__FUNC_PWM2 (MTK_PIN_NO(89) | 6) ++#define MT8127_PIN_89_MSDC2_DAT2__FUNC_DBG_MON_B_26 (MTK_PIN_NO(89) | 7) ++ ++#define MT8127_PIN_90_MSDC2_DAT3__FUNC_GPIO90 (MTK_PIN_NO(90) | 0) ++#define MT8127_PIN_90_MSDC2_DAT3__FUNC_MSDC2_DAT3 (MTK_PIN_NO(90) | 1) ++#define MT8127_PIN_90_MSDC2_DAT3__FUNC_ANT_SEL5 (MTK_PIN_NO(90) | 2) ++#define MT8127_PIN_90_MSDC2_DAT3__FUNC_SCL2 (MTK_PIN_NO(90) | 3) ++#define MT8127_PIN_90_MSDC2_DAT3__FUNC_EXT_FRAME_SYNC (MTK_PIN_NO(90) | 4) ++#define MT8127_PIN_90_MSDC2_DAT3__FUNC_URXD1 (MTK_PIN_NO(90) | 5) ++#define MT8127_PIN_90_MSDC2_DAT3__FUNC_PWM3 (MTK_PIN_NO(90) | 6) ++#define MT8127_PIN_90_MSDC2_DAT3__FUNC_DBG_MON_B_27 (MTK_PIN_NO(90) | 7) ++ ++#define MT8127_PIN_91_TDN3__FUNC_GPI91 (MTK_PIN_NO(91) | 0) ++#define MT8127_PIN_91_TDN3__FUNC_TDN3 (MTK_PIN_NO(91) | 1) ++ ++#define MT8127_PIN_92_TDP3__FUNC_GPI92 (MTK_PIN_NO(92) | 0) ++#define MT8127_PIN_92_TDP3__FUNC_TDP3 (MTK_PIN_NO(92) | 1) ++ ++#define MT8127_PIN_93_TDN2__FUNC_GPI93 (MTK_PIN_NO(93) | 0) ++#define MT8127_PIN_93_TDN2__FUNC_TDN2 (MTK_PIN_NO(93) | 1) ++ ++#define MT8127_PIN_94_TDP2__FUNC_GPI94 (MTK_PIN_NO(94) | 0) ++#define MT8127_PIN_94_TDP2__FUNC_TDP2 (MTK_PIN_NO(94) | 1) ++ ++#define MT8127_PIN_95_TCN__FUNC_GPI95 (MTK_PIN_NO(95) | 0) ++#define MT8127_PIN_95_TCN__FUNC_TCN (MTK_PIN_NO(95) | 1) ++ ++#define MT8127_PIN_96_TCP__FUNC_GPI96 (MTK_PIN_NO(96) | 0) ++#define MT8127_PIN_96_TCP__FUNC_TCP (MTK_PIN_NO(96) | 1) ++ ++#define MT8127_PIN_97_TDN1__FUNC_GPI97 (MTK_PIN_NO(97) | 0) ++#define MT8127_PIN_97_TDN1__FUNC_TDN1 (MTK_PIN_NO(97) | 1) ++ ++#define MT8127_PIN_98_TDP1__FUNC_GPI98 (MTK_PIN_NO(98) | 0) ++#define MT8127_PIN_98_TDP1__FUNC_TDP1 (MTK_PIN_NO(98) | 1) ++ ++#define MT8127_PIN_99_TDN0__FUNC_GPI99 (MTK_PIN_NO(99) | 0) ++#define MT8127_PIN_99_TDN0__FUNC_TDN0 (MTK_PIN_NO(99) | 1) ++ ++#define MT8127_PIN_100_TDP0__FUNC_GPI100 (MTK_PIN_NO(100) | 0) ++#define MT8127_PIN_100_TDP0__FUNC_TDP0 (MTK_PIN_NO(100) | 1) ++ ++#define MT8127_PIN_101_RDN0__FUNC_GPI101 (MTK_PIN_NO(101) | 0) ++#define MT8127_PIN_101_RDN0__FUNC_RDN0 (MTK_PIN_NO(101) | 1) ++ ++#define MT8127_PIN_102_RDP0__FUNC_GPI102 (MTK_PIN_NO(102) | 0) ++#define MT8127_PIN_102_RDP0__FUNC_RDP0 (MTK_PIN_NO(102) | 1) ++ ++#define MT8127_PIN_103_RDN1__FUNC_GPI103 (MTK_PIN_NO(103) | 0) ++#define MT8127_PIN_103_RDN1__FUNC_RDN1 (MTK_PIN_NO(103) | 1) ++ ++#define MT8127_PIN_104_RDP1__FUNC_GPI104 (MTK_PIN_NO(104) | 0) ++#define MT8127_PIN_104_RDP1__FUNC_RDP1 (MTK_PIN_NO(104) | 1) ++ ++#define MT8127_PIN_105_RCN__FUNC_GPI105 (MTK_PIN_NO(105) | 0) ++#define MT8127_PIN_105_RCN__FUNC_RCN (MTK_PIN_NO(105) | 1) ++ ++#define MT8127_PIN_106_RCP__FUNC_GPI106 (MTK_PIN_NO(106) | 0) ++#define MT8127_PIN_106_RCP__FUNC_RCP (MTK_PIN_NO(106) | 1) ++ ++#define MT8127_PIN_107_RDN2__FUNC_GPI107 (MTK_PIN_NO(107) | 0) ++#define MT8127_PIN_107_RDN2__FUNC_RDN2 (MTK_PIN_NO(107) | 1) ++#define MT8127_PIN_107_RDN2__FUNC_CMDAT8 (MTK_PIN_NO(107) | 2) ++ ++#define MT8127_PIN_108_RDP2__FUNC_GPI108 (MTK_PIN_NO(108) | 0) ++#define MT8127_PIN_108_RDP2__FUNC_RDP2 (MTK_PIN_NO(108) | 1) ++#define MT8127_PIN_108_RDP2__FUNC_CMDAT9 (MTK_PIN_NO(108) | 2) ++ ++#define MT8127_PIN_109_RDN3__FUNC_GPI109 (MTK_PIN_NO(109) | 0) ++#define MT8127_PIN_109_RDN3__FUNC_RDN3 (MTK_PIN_NO(109) | 1) ++#define MT8127_PIN_109_RDN3__FUNC_CMDAT4 (MTK_PIN_NO(109) | 2) ++ ++#define MT8127_PIN_110_RDP3__FUNC_GPI110 (MTK_PIN_NO(110) | 0) ++#define MT8127_PIN_110_RDP3__FUNC_RDP3 (MTK_PIN_NO(110) | 1) ++#define MT8127_PIN_110_RDP3__FUNC_CMDAT5 (MTK_PIN_NO(110) | 2) ++ ++#define MT8127_PIN_111_RCN_A__FUNC_GPI111 (MTK_PIN_NO(111) | 0) ++#define MT8127_PIN_111_RCN_A__FUNC_RCN_A (MTK_PIN_NO(111) | 1) ++#define MT8127_PIN_111_RCN_A__FUNC_CMDAT6 (MTK_PIN_NO(111) | 2) ++ ++#define MT8127_PIN_112_RCP_A__FUNC_GPI112 (MTK_PIN_NO(112) | 0) ++#define MT8127_PIN_112_RCP_A__FUNC_RCP_A (MTK_PIN_NO(112) | 1) ++#define MT8127_PIN_112_RCP_A__FUNC_CMDAT7 (MTK_PIN_NO(112) | 2) ++ ++#define MT8127_PIN_113_RDN1_A__FUNC_GPI113 (MTK_PIN_NO(113) | 0) ++#define MT8127_PIN_113_RDN1_A__FUNC_RDN1_A (MTK_PIN_NO(113) | 1) ++#define MT8127_PIN_113_RDN1_A__FUNC_CMDAT2 (MTK_PIN_NO(113) | 2) ++#define MT8127_PIN_113_RDN1_A__FUNC_CMCSD2 (MTK_PIN_NO(113) | 3) ++ ++#define MT8127_PIN_114_RDP1_A__FUNC_GPI114 (MTK_PIN_NO(114) | 0) ++#define MT8127_PIN_114_RDP1_A__FUNC_RDP1_A (MTK_PIN_NO(114) | 1) ++#define MT8127_PIN_114_RDP1_A__FUNC_CMDAT3 (MTK_PIN_NO(114) | 2) ++#define MT8127_PIN_114_RDP1_A__FUNC_CMCSD3 (MTK_PIN_NO(114) | 3) ++ ++#define MT8127_PIN_115_RDN0_A__FUNC_GPI115 (MTK_PIN_NO(115) | 0) ++#define MT8127_PIN_115_RDN0_A__FUNC_RDN0_A (MTK_PIN_NO(115) | 1) ++#define MT8127_PIN_115_RDN0_A__FUNC_CMHSYNC (MTK_PIN_NO(115) | 2) ++ ++#define MT8127_PIN_116_RDP0_A__FUNC_GPI116 (MTK_PIN_NO(116) | 0) ++#define MT8127_PIN_116_RDP0_A__FUNC_RDP0_A (MTK_PIN_NO(116) | 1) ++#define MT8127_PIN_116_RDP0_A__FUNC_CMVSYNC (MTK_PIN_NO(116) | 2) ++ ++#define MT8127_PIN_117_CMDAT0__FUNC_GPIO117 (MTK_PIN_NO(117) | 0) ++#define MT8127_PIN_117_CMDAT0__FUNC_CMDAT0 (MTK_PIN_NO(117) | 1) ++#define MT8127_PIN_117_CMDAT0__FUNC_CMCSD0 (MTK_PIN_NO(117) | 2) ++#define MT8127_PIN_117_CMDAT0__FUNC_ANT_SEL2 (MTK_PIN_NO(117) | 3) ++#define MT8127_PIN_117_CMDAT0__FUNC_DBG_MON_B_28 (MTK_PIN_NO(117) | 7) ++ ++#define MT8127_PIN_118_CMDAT1__FUNC_GPIO118 (MTK_PIN_NO(118) | 0) ++#define MT8127_PIN_118_CMDAT1__FUNC_CMDAT1 (MTK_PIN_NO(118) | 1) ++#define MT8127_PIN_118_CMDAT1__FUNC_CMCSD1 (MTK_PIN_NO(118) | 2) ++#define MT8127_PIN_118_CMDAT1__FUNC_ANT_SEL3 (MTK_PIN_NO(118) | 3) ++#define MT8127_PIN_118_CMDAT1__FUNC_DBG_MON_B_29 (MTK_PIN_NO(118) | 7) ++ ++#define MT8127_PIN_119_CMMCLK__FUNC_GPIO119 (MTK_PIN_NO(119) | 0) ++#define MT8127_PIN_119_CMMCLK__FUNC_CMMCLK (MTK_PIN_NO(119) | 1) ++#define MT8127_PIN_119_CMMCLK__FUNC_ANT_SEL4 (MTK_PIN_NO(119) | 3) ++#define MT8127_PIN_119_CMMCLK__FUNC_DBG_MON_B_30 (MTK_PIN_NO(119) | 7) ++ ++#define MT8127_PIN_120_CMPCLK__FUNC_GPIO120 (MTK_PIN_NO(120) | 0) ++#define MT8127_PIN_120_CMPCLK__FUNC_CMPCLK (MTK_PIN_NO(120) | 1) ++#define MT8127_PIN_120_CMPCLK__FUNC_CMCSK (MTK_PIN_NO(120) | 2) ++#define MT8127_PIN_120_CMPCLK__FUNC_ANT_SEL5 (MTK_PIN_NO(120) | 3) ++#define MT8127_PIN_120_CMPCLK__FUNC_DBG_MON_B_31 (MTK_PIN_NO(120) | 7) ++ ++#define MT8127_PIN_121_MSDC1_CMD__FUNC_GPIO121 (MTK_PIN_NO(121) | 0) ++#define MT8127_PIN_121_MSDC1_CMD__FUNC_MSDC1_CMD (MTK_PIN_NO(121) | 1) ++ ++#define MT8127_PIN_122_MSDC1_CLK__FUNC_GPIO122 (MTK_PIN_NO(122) | 0) ++#define MT8127_PIN_122_MSDC1_CLK__FUNC_MSDC1_CLK (MTK_PIN_NO(122) | 1) ++ ++#define MT8127_PIN_123_MSDC1_DAT0__FUNC_GPIO123 (MTK_PIN_NO(123) | 0) ++#define MT8127_PIN_123_MSDC1_DAT0__FUNC_MSDC1_DAT0 (MTK_PIN_NO(123) | 1) ++ ++#define MT8127_PIN_124_MSDC1_DAT1__FUNC_GPIO124 (MTK_PIN_NO(124) | 0) ++#define MT8127_PIN_124_MSDC1_DAT1__FUNC_MSDC1_DAT1 (MTK_PIN_NO(124) | 1) ++ ++#define MT8127_PIN_125_MSDC1_DAT2__FUNC_GPIO125 (MTK_PIN_NO(125) | 0) ++#define MT8127_PIN_125_MSDC1_DAT2__FUNC_MSDC1_DAT2 (MTK_PIN_NO(125) | 1) ++ ++#define MT8127_PIN_126_MSDC1_DAT3__FUNC_GPIO126 (MTK_PIN_NO(126) | 0) ++#define MT8127_PIN_126_MSDC1_DAT3__FUNC_MSDC1_DAT3 (MTK_PIN_NO(126) | 1) ++ ++#define MT8127_PIN_127_MSDC0_DAT7__FUNC_GPIO127 (MTK_PIN_NO(127) | 0) ++#define MT8127_PIN_127_MSDC0_DAT7__FUNC_MSDC0_DAT7 (MTK_PIN_NO(127) | 1) ++#define MT8127_PIN_127_MSDC0_DAT7__FUNC_NLD7 (MTK_PIN_NO(127) | 4) ++ ++#define MT8127_PIN_128_MSDC0_DAT6__FUNC_GPIO128 (MTK_PIN_NO(128) | 0) ++#define MT8127_PIN_128_MSDC0_DAT6__FUNC_MSDC0_DAT6 (MTK_PIN_NO(128) | 1) ++#define MT8127_PIN_128_MSDC0_DAT6__FUNC_NLD6 (MTK_PIN_NO(128) | 4) ++ ++#define MT8127_PIN_129_MSDC0_DAT5__FUNC_GPIO129 (MTK_PIN_NO(129) | 0) ++#define MT8127_PIN_129_MSDC0_DAT5__FUNC_MSDC0_DAT5 (MTK_PIN_NO(129) | 1) ++#define MT8127_PIN_129_MSDC0_DAT5__FUNC_NLD4 (MTK_PIN_NO(129) | 4) ++ ++#define MT8127_PIN_130_MSDC0_DAT4__FUNC_GPIO130 (MTK_PIN_NO(130) | 0) ++#define MT8127_PIN_130_MSDC0_DAT4__FUNC_MSDC0_DAT4 (MTK_PIN_NO(130) | 1) ++#define MT8127_PIN_130_MSDC0_DAT4__FUNC_NLD3 (MTK_PIN_NO(130) | 4) ++ ++#define MT8127_PIN_131_MSDC0_RSTB__FUNC_GPIO131 (MTK_PIN_NO(131) | 0) ++#define MT8127_PIN_131_MSDC0_RSTB__FUNC_MSDC0_RSTB (MTK_PIN_NO(131) | 1) ++#define MT8127_PIN_131_MSDC0_RSTB__FUNC_NLD0 (MTK_PIN_NO(131) | 4) ++ ++#define MT8127_PIN_132_MSDC0_CMD__FUNC_GPIO132 (MTK_PIN_NO(132) | 0) ++#define MT8127_PIN_132_MSDC0_CMD__FUNC_MSDC0_CMD (MTK_PIN_NO(132) | 1) ++#define MT8127_PIN_132_MSDC0_CMD__FUNC_NALE (MTK_PIN_NO(132) | 4) ++ ++#define MT8127_PIN_133_MSDC0_CLK__FUNC_GPIO133 (MTK_PIN_NO(133) | 0) ++#define MT8127_PIN_133_MSDC0_CLK__FUNC_MSDC0_CLK (MTK_PIN_NO(133) | 1) ++#define MT8127_PIN_133_MSDC0_CLK__FUNC_NWEB (MTK_PIN_NO(133) | 4) ++ ++#define MT8127_PIN_134_MSDC0_DAT3__FUNC_GPIO134 (MTK_PIN_NO(134) | 0) ++#define MT8127_PIN_134_MSDC0_DAT3__FUNC_MSDC0_DAT3 (MTK_PIN_NO(134) | 1) ++#define MT8127_PIN_134_MSDC0_DAT3__FUNC_NLD1 (MTK_PIN_NO(134) | 4) ++ ++#define MT8127_PIN_135_MSDC0_DAT2__FUNC_GPIO135 (MTK_PIN_NO(135) | 0) ++#define MT8127_PIN_135_MSDC0_DAT2__FUNC_MSDC0_DAT2 (MTK_PIN_NO(135) | 1) ++#define MT8127_PIN_135_MSDC0_DAT2__FUNC_NLD5 (MTK_PIN_NO(135) | 4) ++ ++#define MT8127_PIN_136_MSDC0_DAT1__FUNC_GPIO136 (MTK_PIN_NO(136) | 0) ++#define MT8127_PIN_136_MSDC0_DAT1__FUNC_MSDC0_DAT1 (MTK_PIN_NO(136) | 1) ++#define MT8127_PIN_136_MSDC0_DAT1__FUNC_NLD8 (MTK_PIN_NO(136) | 4) ++ ++#define MT8127_PIN_137_MSDC0_DAT0__FUNC_GPIO137 (MTK_PIN_NO(137) | 0) ++#define MT8127_PIN_137_MSDC0_DAT0__FUNC_MSDC0_DAT0 (MTK_PIN_NO(137) | 1) ++#define MT8127_PIN_137_MSDC0_DAT0__FUNC_WATCHDOG (MTK_PIN_NO(137) | 4) ++#define MT8127_PIN_137_MSDC0_DAT0__FUNC_NLD2 (MTK_PIN_NO(137) | 5) ++ ++#define MT8127_PIN_138_CEC__FUNC_GPIO138 (MTK_PIN_NO(138) | 0) ++#define MT8127_PIN_138_CEC__FUNC_CEC (MTK_PIN_NO(138) | 1) ++ ++#define MT8127_PIN_139_HTPLG__FUNC_GPIO139 (MTK_PIN_NO(139) | 0) ++#define MT8127_PIN_139_HTPLG__FUNC_HTPLG (MTK_PIN_NO(139) | 1) ++ ++#define MT8127_PIN_140_HDMISCK__FUNC_GPIO140 (MTK_PIN_NO(140) | 0) ++#define MT8127_PIN_140_HDMISCK__FUNC_HDMISCK (MTK_PIN_NO(140) | 1) ++ ++#define MT8127_PIN_141_HDMISD__FUNC_GPIO141 (MTK_PIN_NO(141) | 0) ++#define MT8127_PIN_141_HDMISD__FUNC_HDMISD (MTK_PIN_NO(141) | 1) ++ ++#define MT8127_PIN_142_EINT21__FUNC_GPIO142 (MTK_PIN_NO(142) | 0) ++#define MT8127_PIN_142_EINT21__FUNC_NRNB (MTK_PIN_NO(142) | 1) ++#define MT8127_PIN_142_EINT21__FUNC_ANT_SEL0 (MTK_PIN_NO(142) | 2) ++#define MT8127_PIN_142_EINT21__FUNC_DBG_MON_B_32 (MTK_PIN_NO(142) | 7) ++ ++#endif /* __DTS_MT8127_PINFUNC_H */ +diff --git a/arch/arm/boot/dts/mt8127.dtsi b/arch/arm/boot/dts/mt8127.dtsi +index 7c2090d..1d429ed 100644 +--- a/arch/arm/boot/dts/mt8127.dtsi ++++ b/arch/arm/boot/dts/mt8127.dtsi +@@ -14,6 +14,7 @@ + + #include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/interrupt-controller/arm-gic.h> ++#include "mt8127-pinfunc.h" + #include "skeleton64.dtsi" + + / { +@@ -94,6 +95,27 @@ + compatible = "simple-bus"; + ranges; + ++ /* ++ * Pinctrl access register at 0x10005000 through regmap. ++ * Register 0x1000b000 is used by EINT. ++ */ ++ pio: pinctrl@10005000 { ++ compatible = "mediatek,mt8127-pinctrl"; ++ reg = <0 0x1000b000 0 0x1000>; ++ mediatek,pctl-regmap = <&syscfg_pctl_a>; ++ pins-are-numbered; ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; ++ }; ++ ++ syscfg_pctl_a: syscfg_pctl_a@10005000 { ++ compatible = "mediatek,mt8127-pctl-a-syscfg", "syscon"; ++ reg = <0 0x10005000 0 0x1000>; ++ }; ++ + timer: timer@10008000 { + compatible = "mediatek,mt8127-timer", + "mediatek,mt6577-timer"; +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0057-thermal-oops.patch b/target/linux/mediatek/patches/0057-thermal-oops.patch new file mode 100644 index 0000000000..e7684f155d --- /dev/null +++ b/target/linux/mediatek/patches/0057-thermal-oops.patch @@ -0,0 +1,27 @@ +From d1a856804b84affae30274b391b3c685e901093f Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Sat, 27 Jun 2015 11:35:29 +0200 +Subject: [PATCH 57/76] thermal oops + +Signed-off-by: John Crispin <blogic@openwrt.org> +--- + drivers/thermal/mtk_thermal.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c +index 27aab12..5fdcbf6 100644 +--- a/drivers/thermal/mtk_thermal.c ++++ b/drivers/thermal/mtk_thermal.c +@@ -394,7 +394,8 @@ static irqreturn_t mtk_thermal_irq(int irq, void *dev_id) + + for (i = 0; i < MT8173_NUM_BANKS; i++) { + if (!(irqstat & (1 << i))) +- mtk_thermal_irq_bank(&mt->banks[i]); ++ if (!IS_ERR(mt->banks[i].tz)) ++ mtk_thermal_irq_bank(&mt->banks[i]); + } + + return IRQ_HANDLED; +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0058-dont-disable-clocks.patch b/target/linux/mediatek/patches/0058-dont-disable-clocks.patch new file mode 100644 index 0000000000..e30d5dc1aa --- /dev/null +++ b/target/linux/mediatek/patches/0058-dont-disable-clocks.patch @@ -0,0 +1,25 @@ +From b1c69201563ae3ff878abf4ba192e73031de8653 Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Tue, 23 Jun 2015 23:46:00 +0200 +Subject: [PATCH 58/76] dont disable clocks + +--- + drivers/clk/clk.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c +index 5b0f418..360e6e4 100644 +--- a/drivers/clk/clk.c ++++ b/drivers/clk/clk.c +@@ -541,7 +541,7 @@ unlock_out: + clk_enable_unlock(flags); + } + +-static bool clk_ignore_unused; ++static bool clk_ignore_unused = true; + static int __init clk_ignore_unused_setup(char *__unused) + { + clk_ignore_unused = true; +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0059-arm-mediatek-basic-mt6323-pmic-support.patch b/target/linux/mediatek/patches/0059-arm-mediatek-basic-mt6323-pmic-support.patch new file mode 100644 index 0000000000..ca28251d2a --- /dev/null +++ b/target/linux/mediatek/patches/0059-arm-mediatek-basic-mt6323-pmic-support.patch @@ -0,0 +1,1099 @@ +From 7f157285f2a01921917e0eed79b5d8cf734f5d27 Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Wed, 24 Jun 2015 15:24:45 +0200 +Subject: [PATCH 59/76] arm: mediatek: basic mt6323 pmic support + +Signed-off-by: John Crispin <blogic@openwrt.org> +--- + drivers/mfd/Kconfig | 10 + + drivers/mfd/Makefile | 1 + + drivers/mfd/mt6323-core.c | 230 +++++++++++++++++++++ + drivers/regulator/Kconfig | 9 + + drivers/regulator/Makefile | 1 + + drivers/regulator/mt6323-regulator.c | 332 +++++++++++++++++++++++++++++++ + include/linux/mfd/mt6323/core.h | 64 ++++++ + include/linux/mfd/mt6323/registers.h | 362 ++++++++++++++++++++++++++++++++++ + 8 files changed, 1009 insertions(+) + create mode 100644 drivers/mfd/mt6323-core.c + create mode 100644 drivers/regulator/mt6323-regulator.c + create mode 100644 include/linux/mfd/mt6323/core.h + create mode 100644 include/linux/mfd/mt6323/registers.h + +diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig +index d5ad04d..ff2c14e 100644 +--- a/drivers/mfd/Kconfig ++++ b/drivers/mfd/Kconfig +@@ -529,6 +529,16 @@ config MFD_MAX8998 + additional drivers must be enabled in order to use the functionality + of the device. + ++config MFD_MT6323 ++ tristate "MediaTek MT6323 PMIC Support" ++ select MFD_CORE ++ select IRQ_DOMAIN ++ help ++ Say yes here to add support for MediaTek MT6323 PMIC. This is ++ a Power Management IC. This driver provides common support for ++ accessing the device; additional drivers must be enabled in order ++ to use the functionality of the device. ++ + config MFD_MT6397 + tristate "MediaTek MT6397 PMIC Support" + select MFD_CORE +diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile +index 0e5cfeb..6e91123 100644 +--- a/drivers/mfd/Makefile ++++ b/drivers/mfd/Makefile +@@ -184,4 +184,5 @@ obj-$(CONFIG_MFD_SKY81452) += sky81452.o + + intel-soc-pmic-objs := intel_soc_pmic_core.o intel_soc_pmic_crc.o + obj-$(CONFIG_INTEL_SOC_PMIC) += intel-soc-pmic.o ++obj-$(CONFIG_MFD_MT6323) += mt6323-core.o + obj-$(CONFIG_MFD_MT6397) += mt6397-core.o +diff --git a/drivers/mfd/mt6323-core.c b/drivers/mfd/mt6323-core.c +new file mode 100644 +index 0000000..012c620 +--- /dev/null ++++ b/drivers/mfd/mt6323-core.c +@@ -0,0 +1,230 @@ ++/* ++ * Copyright (c) 2014 MediaTek Inc. ++ * Author: Flora Fu, MediaTek ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/interrupt.h> ++#include <linux/module.h> ++#include <linux/of_device.h> ++#include <linux/of_irq.h> ++#include <linux/regmap.h> ++#include <linux/mfd/core.h> ++#include <linux/mfd/mt6397/core.h> ++#include <linux/mfd/mt6397/registers.h> ++ ++static const struct mfd_cell mt6397_devs[] = { ++ { ++ .name = "mt6397-rtc", ++ .of_compatible = "mediatek,mt6397-rtc", ++ }, { ++ .name = "mt6397-regulator", ++ .of_compatible = "mediatek,mt6397-regulator", ++ }, { ++ .name = "mt6397-codec", ++ .of_compatible = "mediatek,mt6397-codec", ++ }, { ++ .name = "mt6397-clk", ++ .of_compatible = "mediatek,mt6397-clk", ++ }, { ++ .name = "mediatek-mt6397-pinctrl", ++ .of_compatible = "mediatek,mt6397-pinctrl", ++ }, ++}; ++ ++static void mt6397_irq_lock(struct irq_data *data) ++{ ++ struct mt6397_chip *mt6397 = irq_get_chip_data(data->irq); ++ ++ mutex_lock(&mt6397->irqlock); ++} ++ ++static void mt6397_irq_sync_unlock(struct irq_data *data) ++{ ++ struct mt6397_chip *mt6397 = irq_get_chip_data(data->irq); ++ ++ regmap_write(mt6397->regmap, MT6397_INT_CON0, mt6397->irq_masks_cur[0]); ++ regmap_write(mt6397->regmap, MT6397_INT_CON1, mt6397->irq_masks_cur[1]); ++ ++ mutex_unlock(&mt6397->irqlock); ++} ++ ++static void mt6397_irq_disable(struct irq_data *data) ++{ ++ struct mt6397_chip *mt6397 = irq_get_chip_data(data->irq); ++ int shift = data->hwirq & 0xf; ++ int reg = data->hwirq >> 4; ++ ++ mt6397->irq_masks_cur[reg] &= ~BIT(shift); ++} ++ ++static void mt6397_irq_enable(struct irq_data *data) ++{ ++ struct mt6397_chip *mt6397 = irq_get_chip_data(data->irq); ++ int shift = data->hwirq & 0xf; ++ int reg = data->hwirq >> 4; ++ ++ mt6397->irq_masks_cur[reg] |= BIT(shift); ++} ++ ++static struct irq_chip mt6397_irq_chip = { ++ .name = "mt6397-irq", ++ .irq_bus_lock = mt6397_irq_lock, ++ .irq_bus_sync_unlock = mt6397_irq_sync_unlock, ++ .irq_enable = mt6397_irq_enable, ++ .irq_disable = mt6397_irq_disable, ++}; ++ ++static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg, ++ int irqbase) ++{ ++ unsigned int status; ++ int i, irq, ret; ++ ++ ret = regmap_read(mt6397->regmap, reg, &status); ++ if (ret) { ++ dev_err(mt6397->dev, "Failed to read irq status: %d\n", ret); ++ return; ++ } ++ ++ for (i = 0; i < 16; i++) { ++ if (status & BIT(i)) { ++ irq = irq_find_mapping(mt6397->irq_domain, irqbase + i); ++ if (irq) ++ handle_nested_irq(irq); ++ } ++ } ++ ++ regmap_write(mt6397->regmap, reg, status); ++} ++ ++static irqreturn_t mt6397_irq_thread(int irq, void *data) ++{ ++ struct mt6397_chip *mt6397 = data; ++ ++ mt6397_irq_handle_reg(mt6397, MT6397_INT_STATUS0, 0); ++ mt6397_irq_handle_reg(mt6397, MT6397_INT_STATUS1, 16); ++ ++ return IRQ_HANDLED; ++} ++ ++static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq, ++ irq_hw_number_t hw) ++{ ++ struct mt6397_chip *mt6397 = d->host_data; ++ ++ irq_set_chip_data(irq, mt6397); ++ irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq); ++ irq_set_nested_thread(irq, 1); ++#ifdef CONFIG_ARM ++ set_irq_flags(irq, IRQF_VALID); ++#else ++ irq_set_noprobe(irq); ++#endif ++ ++ return 0; ++} ++ ++static struct irq_domain_ops mt6397_irq_domain_ops = { ++ .map = mt6397_irq_domain_map, ++}; ++ ++static int mt6397_irq_init(struct mt6397_chip *mt6397) ++{ ++ int ret; ++ ++ mutex_init(&mt6397->irqlock); ++ ++ /* Mask all interrupt sources */ ++ regmap_write(mt6397->regmap, MT6397_INT_CON0, 0x0); ++ regmap_write(mt6397->regmap, MT6397_INT_CON1, 0x0); ++ ++ mt6397->irq_domain = irq_domain_add_linear(mt6397->dev->of_node, ++ MT6397_IRQ_NR, &mt6397_irq_domain_ops, mt6397); ++ if (!mt6397->irq_domain) { ++ dev_err(mt6397->dev, "could not create irq domain\n"); ++ return -ENOMEM; ++ } ++ ++ ret = devm_request_threaded_irq(mt6397->dev, mt6397->irq, NULL, ++ mt6397_irq_thread, IRQF_ONESHOT, "mt6397-pmic", mt6397); ++ if (ret) { ++ dev_err(mt6397->dev, "failed to register irq=%d; err: %d\n", ++ mt6397->irq, ret); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int mt6397_probe(struct platform_device *pdev) ++{ ++ int ret; ++ struct mt6397_chip *mt6397; ++ ++ mt6397 = devm_kzalloc(&pdev->dev, sizeof(*mt6397), GFP_KERNEL); ++ if (!mt6397) ++ return -ENOMEM; ++ ++ mt6397->dev = &pdev->dev; ++ /* ++ * mt6397 MFD is child device of soc pmic wrapper. ++ * Regmap is set from its parent. ++ */ ++ mt6397->regmap = dev_get_regmap(pdev->dev.parent, NULL); ++ if (!mt6397->regmap) ++ return -ENODEV; ++ ++ platform_set_drvdata(pdev, mt6397); ++ ++ mt6397->irq = platform_get_irq(pdev, 0); ++ if (mt6397->irq > 0) { ++ ret = mt6397_irq_init(mt6397); ++ if (ret) ++ return ret; ++ } ++ ++ ret = mfd_add_devices(&pdev->dev, -1, mt6397_devs, ++ ARRAY_SIZE(mt6397_devs), NULL, 0, NULL); ++ if (ret) ++ dev_err(&pdev->dev, "failed to add child devices: %d\n", ret); ++ ++ return ret; ++} ++ ++static int mt6397_remove(struct platform_device *pdev) ++{ ++ mfd_remove_devices(&pdev->dev); ++ ++ return 0; ++} ++ ++static const struct of_device_id mt6397_of_match[] = { ++ { .compatible = "mediatek,mt6397" }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, mt6397_of_match); ++ ++static struct platform_driver mt6397_driver = { ++ .probe = mt6397_probe, ++ .remove = mt6397_remove, ++ .driver = { ++ .name = "mt6397", ++ .of_match_table = of_match_ptr(mt6397_of_match), ++ }, ++}; ++ ++module_platform_driver(mt6397_driver); ++ ++MODULE_AUTHOR("Flora Fu, MediaTek"); ++MODULE_DESCRIPTION("Driver for MediaTek MT6397 PMIC"); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS("platform:mt6397"); +diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig +index a6f116a..336d4c6 100644 +--- a/drivers/regulator/Kconfig ++++ b/drivers/regulator/Kconfig +@@ -441,6 +441,15 @@ config REGULATOR_MC13892 + Say y here to support the regulators found on the Freescale MC13892 + PMIC. + ++config REGULATOR_MT6323 ++ tristate "MediaTek MT6323 PMIC" ++ depends on MFD_MT6323 ++ help ++ Say y here to select this option to enable the power regulator of ++ MediaTek MT6323 PMIC. ++ This driver supports the control of different power rails of device ++ through regulator interface. ++ + config REGULATOR_MT6397 + tristate "MediaTek MT6397 PMIC" + depends on MFD_MT6397 +diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile +index 2c4da15..ac6a9da 100644 +--- a/drivers/regulator/Makefile ++++ b/drivers/regulator/Makefile +@@ -59,6 +59,7 @@ obj-$(CONFIG_REGULATOR_MAX77843) += max77843.o + obj-$(CONFIG_REGULATOR_MC13783) += mc13783-regulator.o + obj-$(CONFIG_REGULATOR_MC13892) += mc13892-regulator.o + obj-$(CONFIG_REGULATOR_MC13XXX_CORE) += mc13xxx-regulator-core.o ++obj-$(CONFIG_REGULATOR_MT6323) += mt6323-regulator.o + obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o + obj-$(CONFIG_REGULATOR_QCOM_RPM) += qcom_rpm-regulator.o + obj-$(CONFIG_REGULATOR_PALMAS) += palmas-regulator.o +diff --git a/drivers/regulator/mt6323-regulator.c b/drivers/regulator/mt6323-regulator.c +new file mode 100644 +index 0000000..a5b2f47 +--- /dev/null ++++ b/drivers/regulator/mt6323-regulator.c +@@ -0,0 +1,332 @@ ++/* ++ * Copyright (c) 2014 MediaTek Inc. ++ * Author: Flora Fu <flora.fu@mediatek.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/module.h> ++#include <linux/of.h> ++#include <linux/platform_device.h> ++#include <linux/regmap.h> ++#include <linux/mfd/mt6397/core.h> ++#include <linux/mfd/mt6397/registers.h> ++#include <linux/regulator/driver.h> ++#include <linux/regulator/machine.h> ++#include <linux/regulator/mt6397-regulator.h> ++#include <linux/regulator/of_regulator.h> ++ ++/* ++ * MT6397 regulators' information ++ * ++ * @desc: standard fields of regulator description. ++ * @qi: Mask for query enable signal status of regulators ++ * @vselon_reg: Register sections for hardware control mode of bucks ++ * @vselctrl_reg: Register for controlling the buck control mode. ++ * @vselctrl_mask: Mask for query buck's voltage control mode. ++ */ ++struct mt6397_regulator_info { ++ struct regulator_desc desc; ++ u32 qi; ++ u32 vselon_reg; ++ u32 vselctrl_reg; ++ u32 vselctrl_mask; ++}; ++ ++#define MT6397_BUCK(match, vreg, min, max, step, volt_ranges, enreg, \ ++ vosel, vosel_mask, voselon, vosel_ctrl) \ ++[MT6397_ID_##vreg] = { \ ++ .desc = { \ ++ .name = #vreg, \ ++ .of_match = of_match_ptr(match), \ ++ .ops = &mt6397_volt_range_ops, \ ++ .type = REGULATOR_VOLTAGE, \ ++ .id = MT6397_ID_##vreg, \ ++ .owner = THIS_MODULE, \ ++ .n_voltages = (max - min)/step + 1, \ ++ .linear_ranges = volt_ranges, \ ++ .n_linear_ranges = ARRAY_SIZE(volt_ranges), \ ++ .vsel_reg = vosel, \ ++ .vsel_mask = vosel_mask, \ ++ .enable_reg = enreg, \ ++ .enable_mask = BIT(0), \ ++ }, \ ++ .qi = BIT(13), \ ++ .vselon_reg = voselon, \ ++ .vselctrl_reg = vosel_ctrl, \ ++ .vselctrl_mask = BIT(1), \ ++} ++ ++#define MT6397_LDO(match, vreg, ldo_volt_table, enreg, enbit, vosel, \ ++ vosel_mask) \ ++[MT6397_ID_##vreg] = { \ ++ .desc = { \ ++ .name = #vreg, \ ++ .of_match = of_match_ptr(match), \ ++ .ops = &mt6397_volt_table_ops, \ ++ .type = REGULATOR_VOLTAGE, \ ++ .id = MT6397_ID_##vreg, \ ++ .owner = THIS_MODULE, \ ++ .n_voltages = ARRAY_SIZE(ldo_volt_table), \ ++ .volt_table = ldo_volt_table, \ ++ .vsel_reg = vosel, \ ++ .vsel_mask = vosel_mask, \ ++ .enable_reg = enreg, \ ++ .enable_mask = BIT(enbit), \ ++ }, \ ++ .qi = BIT(15), \ ++} ++ ++#define MT6397_REG_FIXED(match, vreg, enreg, enbit, volt) \ ++[MT6397_ID_##vreg] = { \ ++ .desc = { \ ++ .name = #vreg, \ ++ .of_match = of_match_ptr(match), \ ++ .ops = &mt6397_volt_fixed_ops, \ ++ .type = REGULATOR_VOLTAGE, \ ++ .id = MT6397_ID_##vreg, \ ++ .owner = THIS_MODULE, \ ++ .n_voltages = 1, \ ++ .enable_reg = enreg, \ ++ .enable_mask = BIT(enbit), \ ++ .min_uV = volt, \ ++ }, \ ++ .qi = BIT(15), \ ++} ++ ++static const struct regulator_linear_range buck_volt_range1[] = { ++ REGULATOR_LINEAR_RANGE(700000, 0, 0x7f, 6250), ++}; ++ ++static const struct regulator_linear_range buck_volt_range2[] = { ++ REGULATOR_LINEAR_RANGE(800000, 0, 0x7f, 6250), ++}; ++ ++static const struct regulator_linear_range buck_volt_range3[] = { ++ REGULATOR_LINEAR_RANGE(1500000, 0, 0x1f, 20000), ++}; ++ ++static const u32 ldo_volt_table1[] = { ++ 1500000, 1800000, 2500000, 2800000, ++}; ++ ++static const u32 ldo_volt_table2[] = { ++ 1800000, 3300000, ++}; ++ ++static const u32 ldo_volt_table3[] = { ++ 3000000, 3300000, ++}; ++ ++static const u32 ldo_volt_table4[] = { ++ 1220000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000, ++}; ++ ++static const u32 ldo_volt_table5[] = { ++ 1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000, ++}; ++ ++static const u32 ldo_volt_table5_v2[] = { ++ 1200000, 1000000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000, ++}; ++ ++static const u32 ldo_volt_table6[] = { ++ 1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 2000000, ++}; ++ ++static const u32 ldo_volt_table7[] = { ++ 1300000, 1500000, 1800000, 2000000, 2500000, 2800000, 3000000, 3300000, ++}; ++ ++static int mt6397_get_status(struct regulator_dev *rdev) ++{ ++ int ret; ++ u32 regval; ++ struct mt6397_regulator_info *info = rdev_get_drvdata(rdev); ++ ++ ret = regmap_read(rdev->regmap, info->desc.enable_reg, ®val); ++ if (ret != 0) { ++ dev_err(&rdev->dev, "Failed to get enable reg: %d\n", ret); ++ return ret; ++ } ++ ++ return (regval & info->qi) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF; ++} ++ ++static struct regulator_ops mt6397_volt_range_ops = { ++ .list_voltage = regulator_list_voltage_linear_range, ++ .map_voltage = regulator_map_voltage_linear_range, ++ .set_voltage_sel = regulator_set_voltage_sel_regmap, ++ .get_voltage_sel = regulator_get_voltage_sel_regmap, ++ .set_voltage_time_sel = regulator_set_voltage_time_sel, ++ .enable = regulator_enable_regmap, ++ .disable = regulator_disable_regmap, ++ .is_enabled = regulator_is_enabled_regmap, ++ .get_status = mt6397_get_status, ++}; ++ ++static struct regulator_ops mt6397_volt_table_ops = { ++ .list_voltage = regulator_list_voltage_table, ++ .map_voltage = regulator_map_voltage_iterate, ++ .set_voltage_sel = regulator_set_voltage_sel_regmap, ++ .get_voltage_sel = regulator_get_voltage_sel_regmap, ++ .set_voltage_time_sel = regulator_set_voltage_time_sel, ++ .enable = regulator_enable_regmap, ++ .disable = regulator_disable_regmap, ++ .is_enabled = regulator_is_enabled_regmap, ++ .get_status = mt6397_get_status, ++}; ++ ++static struct regulator_ops mt6397_volt_fixed_ops = { ++ .list_voltage = regulator_list_voltage_linear, ++ .enable = regulator_enable_regmap, ++ .disable = regulator_disable_regmap, ++ .is_enabled = regulator_is_enabled_regmap, ++ .get_status = mt6397_get_status, ++}; ++ ++/* The array is indexed by id(MT6397_ID_XXX) */ ++static struct mt6397_regulator_info mt6397_regulators[] = { ++ MT6397_BUCK("buck_vpca15", VPCA15, 700000, 1493750, 6250, ++ buck_volt_range1, MT6397_VCA15_CON7, MT6397_VCA15_CON9, 0x7f, ++ MT6397_VCA15_CON10, MT6397_VCA15_CON5), ++ MT6397_BUCK("buck_vpca7", VPCA7, 700000, 1493750, 6250, ++ buck_volt_range1, MT6397_VPCA7_CON7, MT6397_VPCA7_CON9, 0x7f, ++ MT6397_VPCA7_CON10, MT6397_VPCA7_CON5), ++ MT6397_BUCK("buck_vsramca15", VSRAMCA15, 700000, 1493750, 6250, ++ buck_volt_range1, MT6397_VSRMCA15_CON7, MT6397_VSRMCA15_CON9, ++ 0x7f, MT6397_VSRMCA15_CON10, MT6397_VSRMCA15_CON5), ++ MT6397_BUCK("buck_vsramca7", VSRAMCA7, 700000, 1493750, 6250, ++ buck_volt_range1, MT6397_VSRMCA7_CON7, MT6397_VSRMCA7_CON9, ++ 0x7f, MT6397_VSRMCA7_CON10, MT6397_VSRMCA7_CON5), ++ MT6397_BUCK("buck_vcore", VCORE, 700000, 1493750, 6250, ++ buck_volt_range1, MT6397_VCORE_CON7, MT6397_VCORE_CON9, 0x7f, ++ MT6397_VCORE_CON10, MT6397_VCORE_CON5), ++ MT6397_BUCK("buck_vgpu", VGPU, 700000, 1493750, 6250, buck_volt_range1, ++ MT6397_VGPU_CON7, MT6397_VGPU_CON9, 0x7f, ++ MT6397_VGPU_CON10, MT6397_VGPU_CON5), ++ MT6397_BUCK("buck_vdrm", VDRM, 800000, 1593750, 6250, buck_volt_range2, ++ MT6397_VDRM_CON7, MT6397_VDRM_CON9, 0x7f, ++ MT6397_VDRM_CON10, MT6397_VDRM_CON5), ++ MT6397_BUCK("buck_vio18", VIO18, 1500000, 2120000, 20000, ++ buck_volt_range3, MT6397_VIO18_CON7, MT6397_VIO18_CON9, 0x1f, ++ MT6397_VIO18_CON10, MT6397_VIO18_CON5), ++ MT6397_REG_FIXED("ldo_vtcxo", VTCXO, MT6397_ANALDO_CON0, 10, 2800000), ++ MT6397_REG_FIXED("ldo_va28", VA28, MT6397_ANALDO_CON1, 14, 2800000), ++ MT6397_LDO("ldo_vcama", VCAMA, ldo_volt_table1, ++ MT6397_ANALDO_CON2, 15, MT6397_ANALDO_CON6, 0xC0), ++ MT6397_REG_FIXED("ldo_vio28", VIO28, MT6397_DIGLDO_CON0, 14, 2800000), ++ MT6397_REG_FIXED("ldo_vusb", VUSB, MT6397_DIGLDO_CON1, 14, 3300000), ++ MT6397_LDO("ldo_vmc", VMC, ldo_volt_table2, ++ MT6397_DIGLDO_CON2, 12, MT6397_DIGLDO_CON29, 0x10), ++ MT6397_LDO("ldo_vmch", VMCH, ldo_volt_table3, ++ MT6397_DIGLDO_CON3, 14, MT6397_DIGLDO_CON17, 0x80), ++ MT6397_LDO("ldo_vemc3v3", VEMC3V3, ldo_volt_table3, ++ MT6397_DIGLDO_CON4, 14, MT6397_DIGLDO_CON18, 0x10), ++ MT6397_LDO("ldo_vgp1", VGP1, ldo_volt_table4, ++ MT6397_DIGLDO_CON5, 15, MT6397_DIGLDO_CON19, 0xE0), ++ MT6397_LDO("ldo_vgp2", VGP2, ldo_volt_table5, ++ MT6397_DIGLDO_CON6, 15, MT6397_DIGLDO_CON20, 0xE0), ++ MT6397_LDO("ldo_vgp3", VGP3, ldo_volt_table5, ++ MT6397_DIGLDO_CON7, 15, MT6397_DIGLDO_CON21, 0xE0), ++ MT6397_LDO("ldo_vgp4", VGP4, ldo_volt_table5, ++ MT6397_DIGLDO_CON8, 15, MT6397_DIGLDO_CON22, 0xE0), ++ MT6397_LDO("ldo_vgp5", VGP5, ldo_volt_table6, ++ MT6397_DIGLDO_CON9, 15, MT6397_DIGLDO_CON23, 0xE0), ++ MT6397_LDO("ldo_vgp6", VGP6, ldo_volt_table5, ++ MT6397_DIGLDO_CON10, 15, MT6397_DIGLDO_CON33, 0xE0), ++ MT6397_LDO("ldo_vibr", VIBR, ldo_volt_table7, ++ MT6397_DIGLDO_CON24, 15, MT6397_DIGLDO_CON25, 0xE00), ++}; ++ ++static int mt6397_set_buck_vosel_reg(struct platform_device *pdev) ++{ ++ struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent); ++ int i; ++ u32 regval; ++ ++ for (i = 0; i < MT6397_MAX_REGULATOR; i++) { ++ if (mt6397_regulators[i].vselctrl_reg) { ++ if (regmap_read(mt6397->regmap, ++ mt6397_regulators[i].vselctrl_reg, ++ ®val) < 0) { ++ dev_err(&pdev->dev, ++ "Failed to read buck ctrl\n"); ++ return -EIO; ++ } ++ ++ if (regval & mt6397_regulators[i].vselctrl_mask) { ++ mt6397_regulators[i].desc.vsel_reg = ++ mt6397_regulators[i].vselon_reg; ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++static int mt6397_regulator_probe(struct platform_device *pdev) ++{ ++ struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent); ++ struct regulator_config config = {}; ++ struct regulator_dev *rdev; ++ int i; ++ u32 reg_value, version; ++ ++ /* Query buck controller to select activated voltage register part */ ++ if (mt6397_set_buck_vosel_reg(pdev)) ++ return -EIO; ++ ++ /* Read PMIC chip revision to update constraints and voltage table */ ++ if (regmap_read(mt6397->regmap, MT6397_CID, ®_value) < 0) { ++ dev_err(&pdev->dev, "Failed to read Chip ID\n"); ++ return -EIO; ++ } ++ dev_info(&pdev->dev, "Chip ID = 0x%x\n", reg_value); ++ ++ version = (reg_value & 0xFF); ++ switch (version) { ++ case MT6397_REGULATOR_ID91: ++ mt6397_regulators[MT6397_ID_VGP2].desc.volt_table = ++ ldo_volt_table5_v2; ++ break; ++ default: ++ break; ++ } ++ ++ for (i = 0; i < MT6397_MAX_REGULATOR; i++) { ++ config.dev = &pdev->dev; ++ config.driver_data = &mt6397_regulators[i]; ++ config.regmap = mt6397->regmap; ++ rdev = devm_regulator_register(&pdev->dev, ++ &mt6397_regulators[i].desc, &config); ++ if (IS_ERR(rdev)) { ++ dev_err(&pdev->dev, "failed to register %s\n", ++ mt6397_regulators[i].desc.name); ++ return PTR_ERR(rdev); ++ } ++ } ++ ++ return 0; ++} ++ ++static struct platform_driver mt6397_regulator_driver = { ++ .driver = { ++ .name = "mt6397-regulator", ++ }, ++ .probe = mt6397_regulator_probe, ++}; ++ ++module_platform_driver(mt6397_regulator_driver); ++ ++MODULE_AUTHOR("Flora Fu <flora.fu@mediatek.com>"); ++MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6397 PMIC"); ++MODULE_LICENSE("GPL"); ++MODULE_ALIAS("platform:mt6397-regulator"); +diff --git a/include/linux/mfd/mt6323/core.h b/include/linux/mfd/mt6323/core.h +new file mode 100644 +index 0000000..cf5265b +--- /dev/null ++++ b/include/linux/mfd/mt6323/core.h +@@ -0,0 +1,64 @@ ++/* ++ * Copyright (c) 2014 MediaTek Inc. ++ * Author: Flora Fu, MediaTek ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __MFD_MT6397_CORE_H__ ++#define __MFD_MT6397_CORE_H__ ++ ++enum mt6397_irq_numbers { ++ MT6397_IRQ_SPKL_AB = 0, ++ MT6397_IRQ_SPKR_AB, ++ MT6397_IRQ_SPKL, ++ MT6397_IRQ_SPKR, ++ MT6397_IRQ_BAT_L, ++ MT6397_IRQ_BAT_H, ++ MT6397_IRQ_FG_BAT_L, ++ MT6397_IRQ_FG_BAT_H, ++ MT6397_IRQ_WATCHDOG, ++ MT6397_IRQ_PWRKEY, ++ MT6397_IRQ_THR_L, ++ MT6397_IRQ_THR_H, ++ MT6397_IRQ_VBATON_UNDET, ++ MT6397_IRQ_BVALID_DET, ++ MT6397_IRQ_CHRDET, ++ MT6397_IRQ_OV, ++ MT6397_IRQ_LDO, ++ MT6397_IRQ_HOMEKEY, ++ MT6397_IRQ_ACCDET, ++ MT6397_IRQ_AUDIO, ++ MT6397_IRQ_RTC, ++ MT6397_IRQ_PWRKEY_RSTB, ++ MT6397_IRQ_HDMI_SIFM, ++ MT6397_IRQ_HDMI_CEC, ++ MT6397_IRQ_VCA15, ++ MT6397_IRQ_VSRMCA15, ++ MT6397_IRQ_VCORE, ++ MT6397_IRQ_VGPU, ++ MT6397_IRQ_VIO18, ++ MT6397_IRQ_VPCA7, ++ MT6397_IRQ_VSRMCA7, ++ MT6397_IRQ_VDRM, ++ MT6397_IRQ_NR, ++}; ++ ++struct mt6397_chip { ++ struct device *dev; ++ struct regmap *regmap; ++ int irq; ++ struct irq_domain *irq_domain; ++ struct mutex irqlock; ++ u16 irq_masks_cur[2]; ++ u16 irq_masks_cache[2]; ++}; ++ ++#endif /* __MFD_MT6397_CORE_H__ */ +diff --git a/include/linux/mfd/mt6323/registers.h b/include/linux/mfd/mt6323/registers.h +new file mode 100644 +index 0000000..f23a0a6 +--- /dev/null ++++ b/include/linux/mfd/mt6323/registers.h +@@ -0,0 +1,362 @@ ++/* ++ * Copyright (c) 2014 MediaTek Inc. ++ * Author: Flora Fu, MediaTek ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __MFD_MT6397_REGISTERS_H__ ++#define __MFD_MT6397_REGISTERS_H__ ++ ++/* PMIC Registers */ ++#define MT6397_CID 0x0100 ++#define MT6397_TOP_CKPDN 0x0102 ++#define MT6397_TOP_CKPDN_SET 0x0104 ++#define MT6397_TOP_CKPDN_CLR 0x0106 ++#define MT6397_TOP_CKPDN2 0x0108 ++#define MT6397_TOP_CKPDN2_SET 0x010A ++#define MT6397_TOP_CKPDN2_CLR 0x010C ++#define MT6397_TOP_GPIO_CKPDN 0x010E ++#define MT6397_TOP_RST_CON 0x0114 ++#define MT6397_WRP_CKPDN 0x011A ++#define MT6397_WRP_RST_CON 0x0120 ++#define MT6397_TOP_RST_MISC 0x0126 ++#define MT6397_TOP_CKCON1 0x0128 ++#define MT6397_TOP_CKCON2 0x012A ++#define MT6397_TOP_CKTST1 0x012C ++#define MT6397_TOP_CKTST2 0x012E ++#define MT6397_OC_DEG_EN 0x0130 ++#define MT6397_OC_CTL0 0x0132 ++#define MT6397_OC_CTL1 0x0134 ++#define MT6397_OC_CTL2 0x0136 ++#define MT6397_INT_RSV 0x0138 ++#define MT6397_TEST_CON0 0x013A ++#define MT6397_TEST_CON1 0x013C ++#define MT6397_STATUS0 0x013E ++#define MT6397_STATUS1 0x0140 ++#define MT6397_PGSTATUS 0x0142 ++#define MT6397_CHRSTATUS 0x0144 ++#define MT6397_OCSTATUS0 0x0146 ++#define MT6397_OCSTATUS1 0x0148 ++#define MT6397_OCSTATUS2 0x014A ++#define MT6397_HDMI_PAD_IE 0x014C ++#define MT6397_TEST_OUT_L 0x014E ++#define MT6397_TEST_OUT_H 0x0150 ++#define MT6397_TDSEL_CON 0x0152 ++#define MT6397_RDSEL_CON 0x0154 ++#define MT6397_GPIO_SMT_CON0 0x0156 ++#define MT6397_GPIO_SMT_CON1 0x0158 ++#define MT6397_GPIO_SMT_CON2 0x015A ++#define MT6397_GPIO_SMT_CON3 0x015C ++#define MT6397_DRV_CON0 0x015E ++#define MT6397_DRV_CON1 0x0160 ++#define MT6397_DRV_CON2 0x0162 ++#define MT6397_DRV_CON3 0x0164 ++#define MT6397_DRV_CON4 0x0166 ++#define MT6397_DRV_CON5 0x0168 ++#define MT6397_DRV_CON6 0x016A ++#define MT6397_DRV_CON7 0x016C ++#define MT6397_DRV_CON8 0x016E ++#define MT6397_DRV_CON9 0x0170 ++#define MT6397_DRV_CON10 0x0172 ++#define MT6397_DRV_CON11 0x0174 ++#define MT6397_DRV_CON12 0x0176 ++#define MT6397_INT_CON0 0x0178 ++#define MT6397_INT_CON1 0x017E ++#define MT6397_INT_STATUS0 0x0184 ++#define MT6397_INT_STATUS1 0x0186 ++#define MT6397_FQMTR_CON0 0x0188 ++#define MT6397_FQMTR_CON1 0x018A ++#define MT6397_FQMTR_CON2 0x018C ++#define MT6397_EFUSE_DOUT_0_15 0x01C4 ++#define MT6397_EFUSE_DOUT_16_31 0x01C6 ++#define MT6397_EFUSE_DOUT_32_47 0x01C8 ++#define MT6397_EFUSE_DOUT_48_63 0x01CA ++#define MT6397_SPI_CON 0x01CC ++#define MT6397_TOP_CKPDN3 0x01CE ++#define MT6397_TOP_CKCON3 0x01D4 ++#define MT6397_EFUSE_DOUT_64_79 0x01D6 ++#define MT6397_EFUSE_DOUT_80_95 0x01D8 ++#define MT6397_EFUSE_DOUT_96_111 0x01DA ++#define MT6397_EFUSE_DOUT_112_127 0x01DC ++#define MT6397_EFUSE_DOUT_128_143 0x01DE ++#define MT6397_EFUSE_DOUT_144_159 0x01E0 ++#define MT6397_EFUSE_DOUT_160_175 0x01E2 ++#define MT6397_EFUSE_DOUT_176_191 0x01E4 ++#define MT6397_EFUSE_DOUT_192_207 0x01E6 ++#define MT6397_EFUSE_DOUT_208_223 0x01E8 ++#define MT6397_EFUSE_DOUT_224_239 0x01EA ++#define MT6397_EFUSE_DOUT_240_255 0x01EC ++#define MT6397_EFUSE_DOUT_256_271 0x01EE ++#define MT6397_EFUSE_DOUT_272_287 0x01F0 ++#define MT6397_EFUSE_DOUT_288_300 0x01F2 ++#define MT6397_EFUSE_DOUT_304_319 0x01F4 ++#define MT6397_BUCK_CON0 0x0200 ++#define MT6397_BUCK_CON1 0x0202 ++#define MT6397_BUCK_CON2 0x0204 ++#define MT6397_BUCK_CON3 0x0206 ++#define MT6397_BUCK_CON4 0x0208 ++#define MT6397_BUCK_CON5 0x020A ++#define MT6397_BUCK_CON6 0x020C ++#define MT6397_BUCK_CON7 0x020E ++#define MT6397_BUCK_CON8 0x0210 ++#define MT6397_BUCK_CON9 0x0212 ++#define MT6397_VCA15_CON0 0x0214 ++#define MT6397_VCA15_CON1 0x0216 ++#define MT6397_VCA15_CON2 0x0218 ++#define MT6397_VCA15_CON3 0x021A ++#define MT6397_VCA15_CON4 0x021C ++#define MT6397_VCA15_CON5 0x021E ++#define MT6397_VCA15_CON6 0x0220 ++#define MT6397_VCA15_CON7 0x0222 ++#define MT6397_VCA15_CON8 0x0224 ++#define MT6397_VCA15_CON9 0x0226 ++#define MT6397_VCA15_CON10 0x0228 ++#define MT6397_VCA15_CON11 0x022A ++#define MT6397_VCA15_CON12 0x022C ++#define MT6397_VCA15_CON13 0x022E ++#define MT6397_VCA15_CON14 0x0230 ++#define MT6397_VCA15_CON15 0x0232 ++#define MT6397_VCA15_CON16 0x0234 ++#define MT6397_VCA15_CON17 0x0236 ++#define MT6397_VCA15_CON18 0x0238 ++#define MT6397_VSRMCA15_CON0 0x023A ++#define MT6397_VSRMCA15_CON1 0x023C ++#define MT6397_VSRMCA15_CON2 0x023E ++#define MT6397_VSRMCA15_CON3 0x0240 ++#define MT6397_VSRMCA15_CON4 0x0242 ++#define MT6397_VSRMCA15_CON5 0x0244 ++#define MT6397_VSRMCA15_CON6 0x0246 ++#define MT6397_VSRMCA15_CON7 0x0248 ++#define MT6397_VSRMCA15_CON8 0x024A ++#define MT6397_VSRMCA15_CON9 0x024C ++#define MT6397_VSRMCA15_CON10 0x024E ++#define MT6397_VSRMCA15_CON11 0x0250 ++#define MT6397_VSRMCA15_CON12 0x0252 ++#define MT6397_VSRMCA15_CON13 0x0254 ++#define MT6397_VSRMCA15_CON14 0x0256 ++#define MT6397_VSRMCA15_CON15 0x0258 ++#define MT6397_VSRMCA15_CON16 0x025A ++#define MT6397_VSRMCA15_CON17 0x025C ++#define MT6397_VSRMCA15_CON18 0x025E ++#define MT6397_VSRMCA15_CON19 0x0260 ++#define MT6397_VSRMCA15_CON20 0x0262 ++#define MT6397_VSRMCA15_CON21 0x0264 ++#define MT6397_VCORE_CON0 0x0266 ++#define MT6397_VCORE_CON1 0x0268 ++#define MT6397_VCORE_CON2 0x026A ++#define MT6397_VCORE_CON3 0x026C ++#define MT6397_VCORE_CON4 0x026E ++#define MT6397_VCORE_CON5 0x0270 ++#define MT6397_VCORE_CON6 0x0272 ++#define MT6397_VCORE_CON7 0x0274 ++#define MT6397_VCORE_CON8 0x0276 ++#define MT6397_VCORE_CON9 0x0278 ++#define MT6397_VCORE_CON10 0x027A ++#define MT6397_VCORE_CON11 0x027C ++#define MT6397_VCORE_CON12 0x027E ++#define MT6397_VCORE_CON13 0x0280 ++#define MT6397_VCORE_CON14 0x0282 ++#define MT6397_VCORE_CON15 0x0284 ++#define MT6397_VCORE_CON16 0x0286 ++#define MT6397_VCORE_CON17 0x0288 ++#define MT6397_VCORE_CON18 0x028A ++#define MT6397_VGPU_CON0 0x028C ++#define MT6397_VGPU_CON1 0x028E ++#define MT6397_VGPU_CON2 0x0290 ++#define MT6397_VGPU_CON3 0x0292 ++#define MT6397_VGPU_CON4 0x0294 ++#define MT6397_VGPU_CON5 0x0296 ++#define MT6397_VGPU_CON6 0x0298 ++#define MT6397_VGPU_CON7 0x029A ++#define MT6397_VGPU_CON8 0x029C ++#define MT6397_VGPU_CON9 0x029E ++#define MT6397_VGPU_CON10 0x02A0 ++#define MT6397_VGPU_CON11 0x02A2 ++#define MT6397_VGPU_CON12 0x02A4 ++#define MT6397_VGPU_CON13 0x02A6 ++#define MT6397_VGPU_CON14 0x02A8 ++#define MT6397_VGPU_CON15 0x02AA ++#define MT6397_VGPU_CON16 0x02AC ++#define MT6397_VGPU_CON17 0x02AE ++#define MT6397_VGPU_CON18 0x02B0 ++#define MT6397_VIO18_CON0 0x0300 ++#define MT6397_VIO18_CON1 0x0302 ++#define MT6397_VIO18_CON2 0x0304 ++#define MT6397_VIO18_CON3 0x0306 ++#define MT6397_VIO18_CON4 0x0308 ++#define MT6397_VIO18_CON5 0x030A ++#define MT6397_VIO18_CON6 0x030C ++#define MT6397_VIO18_CON7 0x030E ++#define MT6397_VIO18_CON8 0x0310 ++#define MT6397_VIO18_CON9 0x0312 ++#define MT6397_VIO18_CON10 0x0314 ++#define MT6397_VIO18_CON11 0x0316 ++#define MT6397_VIO18_CON12 0x0318 ++#define MT6397_VIO18_CON13 0x031A ++#define MT6397_VIO18_CON14 0x031C ++#define MT6397_VIO18_CON15 0x031E ++#define MT6397_VIO18_CON16 0x0320 ++#define MT6397_VIO18_CON17 0x0322 ++#define MT6397_VIO18_CON18 0x0324 ++#define MT6397_VPCA7_CON0 0x0326 ++#define MT6397_VPCA7_CON1 0x0328 ++#define MT6397_VPCA7_CON2 0x032A ++#define MT6397_VPCA7_CON3 0x032C ++#define MT6397_VPCA7_CON4 0x032E ++#define MT6397_VPCA7_CON5 0x0330 ++#define MT6397_VPCA7_CON6 0x0332 ++#define MT6397_VPCA7_CON7 0x0334 ++#define MT6397_VPCA7_CON8 0x0336 ++#define MT6397_VPCA7_CON9 0x0338 ++#define MT6397_VPCA7_CON10 0x033A ++#define MT6397_VPCA7_CON11 0x033C ++#define MT6397_VPCA7_CON12 0x033E ++#define MT6397_VPCA7_CON13 0x0340 ++#define MT6397_VPCA7_CON14 0x0342 ++#define MT6397_VPCA7_CON15 0x0344 ++#define MT6397_VPCA7_CON16 0x0346 ++#define MT6397_VPCA7_CON17 0x0348 ++#define MT6397_VPCA7_CON18 0x034A ++#define MT6397_VSRMCA7_CON0 0x034C ++#define MT6397_VSRMCA7_CON1 0x034E ++#define MT6397_VSRMCA7_CON2 0x0350 ++#define MT6397_VSRMCA7_CON3 0x0352 ++#define MT6397_VSRMCA7_CON4 0x0354 ++#define MT6397_VSRMCA7_CON5 0x0356 ++#define MT6397_VSRMCA7_CON6 0x0358 ++#define MT6397_VSRMCA7_CON7 0x035A ++#define MT6397_VSRMCA7_CON8 0x035C ++#define MT6397_VSRMCA7_CON9 0x035E ++#define MT6397_VSRMCA7_CON10 0x0360 ++#define MT6397_VSRMCA7_CON11 0x0362 ++#define MT6397_VSRMCA7_CON12 0x0364 ++#define MT6397_VSRMCA7_CON13 0x0366 ++#define MT6397_VSRMCA7_CON14 0x0368 ++#define MT6397_VSRMCA7_CON15 0x036A ++#define MT6397_VSRMCA7_CON16 0x036C ++#define MT6397_VSRMCA7_CON17 0x036E ++#define MT6397_VSRMCA7_CON18 0x0370 ++#define MT6397_VSRMCA7_CON19 0x0372 ++#define MT6397_VSRMCA7_CON20 0x0374 ++#define MT6397_VSRMCA7_CON21 0x0376 ++#define MT6397_VDRM_CON0 0x0378 ++#define MT6397_VDRM_CON1 0x037A ++#define MT6397_VDRM_CON2 0x037C ++#define MT6397_VDRM_CON3 0x037E ++#define MT6397_VDRM_CON4 0x0380 ++#define MT6397_VDRM_CON5 0x0382 ++#define MT6397_VDRM_CON6 0x0384 ++#define MT6397_VDRM_CON7 0x0386 ++#define MT6397_VDRM_CON8 0x0388 ++#define MT6397_VDRM_CON9 0x038A ++#define MT6397_VDRM_CON10 0x038C ++#define MT6397_VDRM_CON11 0x038E ++#define MT6397_VDRM_CON12 0x0390 ++#define MT6397_VDRM_CON13 0x0392 ++#define MT6397_VDRM_CON14 0x0394 ++#define MT6397_VDRM_CON15 0x0396 ++#define MT6397_VDRM_CON16 0x0398 ++#define MT6397_VDRM_CON17 0x039A ++#define MT6397_VDRM_CON18 0x039C ++#define MT6397_BUCK_K_CON0 0x039E ++#define MT6397_BUCK_K_CON1 0x03A0 ++#define MT6397_ANALDO_CON0 0x0400 ++#define MT6397_ANALDO_CON1 0x0402 ++#define MT6397_ANALDO_CON2 0x0404 ++#define MT6397_ANALDO_CON3 0x0406 ++#define MT6397_ANALDO_CON4 0x0408 ++#define MT6397_ANALDO_CON5 0x040A ++#define MT6397_ANALDO_CON6 0x040C ++#define MT6397_ANALDO_CON7 0x040E ++#define MT6397_DIGLDO_CON0 0x0410 ++#define MT6397_DIGLDO_CON1 0x0412 ++#define MT6397_DIGLDO_CON2 0x0414 ++#define MT6397_DIGLDO_CON3 0x0416 ++#define MT6397_DIGLDO_CON4 0x0418 ++#define MT6397_DIGLDO_CON5 0x041A ++#define MT6397_DIGLDO_CON6 0x041C ++#define MT6397_DIGLDO_CON7 0x041E ++#define MT6397_DIGLDO_CON8 0x0420 ++#define MT6397_DIGLDO_CON9 0x0422 ++#define MT6397_DIGLDO_CON10 0x0424 ++#define MT6397_DIGLDO_CON11 0x0426 ++#define MT6397_DIGLDO_CON12 0x0428 ++#define MT6397_DIGLDO_CON13 0x042A ++#define MT6397_DIGLDO_CON14 0x042C ++#define MT6397_DIGLDO_CON15 0x042E ++#define MT6397_DIGLDO_CON16 0x0430 ++#define MT6397_DIGLDO_CON17 0x0432 ++#define MT6397_DIGLDO_CON18 0x0434 ++#define MT6397_DIGLDO_CON19 0x0436 ++#define MT6397_DIGLDO_CON20 0x0438 ++#define MT6397_DIGLDO_CON21 0x043A ++#define MT6397_DIGLDO_CON22 0x043C ++#define MT6397_DIGLDO_CON23 0x043E ++#define MT6397_DIGLDO_CON24 0x0440 ++#define MT6397_DIGLDO_CON25 0x0442 ++#define MT6397_DIGLDO_CON26 0x0444 ++#define MT6397_DIGLDO_CON27 0x0446 ++#define MT6397_DIGLDO_CON28 0x0448 ++#define MT6397_DIGLDO_CON29 0x044A ++#define MT6397_DIGLDO_CON30 0x044C ++#define MT6397_DIGLDO_CON31 0x044E ++#define MT6397_DIGLDO_CON32 0x0450 ++#define MT6397_DIGLDO_CON33 0x045A ++#define MT6397_SPK_CON0 0x0600 ++#define MT6397_SPK_CON1 0x0602 ++#define MT6397_SPK_CON2 0x0604 ++#define MT6397_SPK_CON3 0x0606 ++#define MT6397_SPK_CON4 0x0608 ++#define MT6397_SPK_CON5 0x060A ++#define MT6397_SPK_CON6 0x060C ++#define MT6397_SPK_CON7 0x060E ++#define MT6397_SPK_CON8 0x0610 ++#define MT6397_SPK_CON9 0x0612 ++#define MT6397_SPK_CON10 0x0614 ++#define MT6397_SPK_CON11 0x0616 ++#define MT6397_AUDDAC_CON0 0x0700 ++#define MT6397_AUDBUF_CFG0 0x0702 ++#define MT6397_AUDBUF_CFG1 0x0704 ++#define MT6397_AUDBUF_CFG2 0x0706 ++#define MT6397_AUDBUF_CFG3 0x0708 ++#define MT6397_AUDBUF_CFG4 0x070A ++#define MT6397_IBIASDIST_CFG0 0x070C ++#define MT6397_AUDACCDEPOP_CFG0 0x070E ++#define MT6397_AUD_IV_CFG0 0x0710 ++#define MT6397_AUDCLKGEN_CFG0 0x0712 ++#define MT6397_AUDLDO_CFG0 0x0714 ++#define MT6397_AUDLDO_CFG1 0x0716 ++#define MT6397_AUDNVREGGLB_CFG0 0x0718 ++#define MT6397_AUD_NCP0 0x071A ++#define MT6397_AUDPREAMP_CON0 0x071C ++#define MT6397_AUDADC_CON0 0x071E ++#define MT6397_AUDADC_CON1 0x0720 ++#define MT6397_AUDADC_CON2 0x0722 ++#define MT6397_AUDADC_CON3 0x0724 ++#define MT6397_AUDADC_CON4 0x0726 ++#define MT6397_AUDADC_CON5 0x0728 ++#define MT6397_AUDADC_CON6 0x072A ++#define MT6397_AUDDIGMI_CON0 0x072C ++#define MT6397_AUDLSBUF_CON0 0x072E ++#define MT6397_AUDLSBUF_CON1 0x0730 ++#define MT6397_AUDENCSPARE_CON0 0x0732 ++#define MT6397_AUDENCCLKSQ_CON0 0x0734 ++#define MT6397_AUDPREAMPGAIN_CON0 0x0736 ++#define MT6397_ZCD_CON0 0x0738 ++#define MT6397_ZCD_CON1 0x073A ++#define MT6397_ZCD_CON2 0x073C ++#define MT6397_ZCD_CON3 0x073E ++#define MT6397_ZCD_CON4 0x0740 ++#define MT6397_ZCD_CON5 0x0742 ++#define MT6397_NCP_CLKDIV_CON0 0x0744 ++#define MT6397_NCP_CLKDIV_CON1 0x0746 ++ ++#endif /* __MFD_MT6397_REGISTERS_H__ */ +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0060-arm-mediatek-select-the-arm-timer-by-default.patch b/target/linux/mediatek/patches/0060-arm-mediatek-select-the-arm-timer-by-default.patch new file mode 100644 index 0000000000..2b6418613d --- /dev/null +++ b/target/linux/mediatek/patches/0060-arm-mediatek-select-the-arm-timer-by-default.patch @@ -0,0 +1,26 @@ +From 46c695d8285b73d39b0e16fcfd7da332fd2398d4 Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Sat, 27 Jun 2015 13:00:27 +0200 +Subject: [PATCH 60/76] arm: mediatek: select the arm timer by default + +select ARM_ARCH_TIMER inside the Kconfig + +Signed-off-by: John Crispin <blogic@openwrt.org> +--- + arch/arm/mach-mediatek/Kconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig +index 9f59e58..7704818 100644 +--- a/arch/arm/mach-mediatek/Kconfig ++++ b/arch/arm/mach-mediatek/Kconfig +@@ -1,5 +1,6 @@ + menuconfig ARCH_MEDIATEK + bool "Mediatek MT65xx & MT81xx SoC" if ARCH_MULTI_V7 ++ select ARM_ARCH_TIMER + select ARM_GIC + select PINCTRL + select MTK_TIMER +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0061-arm-mediatek-add-mt7623-clock.patch b/target/linux/mediatek/patches/0061-arm-mediatek-add-mt7623-clock.patch new file mode 100644 index 0000000000..f12ebb14cf --- /dev/null +++ b/target/linux/mediatek/patches/0061-arm-mediatek-add-mt7623-clock.patch @@ -0,0 +1,846 @@ +From 7342787e992a70443081b9203d2131cbf6bc3562 Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Sat, 27 Jun 2015 13:12:38 +0200 +Subject: [PATCH 61/76] arm: mediatek: add mt7623 clock + +Signed-off-by: John Crispin <blogic@openwrt.org> +--- + drivers/clk/mediatek/Makefile | 1 + + drivers/clk/mediatek/clk-mt7623.c | 634 ++++++++++++++++++++++++++++++++ + include/dt-bindings/clock/mt7623-clk.h | 173 +++++++++ + 3 files changed, 808 insertions(+) + create mode 100644 drivers/clk/mediatek/clk-mt7623.c + create mode 100644 include/dt-bindings/clock/mt7623-clk.h + +diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile +index 8e4b2a4..19a3763 100644 +--- a/drivers/clk/mediatek/Makefile ++++ b/drivers/clk/mediatek/Makefile +@@ -1,4 +1,5 @@ + obj-y += clk-mtk.o clk-pll.o clk-gate.o + obj-$(CONFIG_RESET_CONTROLLER) += reset.o ++obj-y += clk-mt7623.o + obj-y += clk-mt8135.o + obj-y += clk-mt8173.o +diff --git a/drivers/clk/mediatek/clk-mt7623.c b/drivers/clk/mediatek/clk-mt7623.c +new file mode 100644 +index 0000000..07843bb +--- /dev/null ++++ b/drivers/clk/mediatek/clk-mt7623.c +@@ -0,0 +1,634 @@ ++/* ++ * Copyright (c) 2014 MediaTek Inc. ++ * Author: James Liao <jamesjj.liao@mediatek.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/of.h> ++#include <linux/of_address.h> ++#include <linux/slab.h> ++#include <linux/mfd/syscon.h> ++#include <dt-bindings/clock/mt7623-clk.h> ++ ++#include "clk-mtk.h" ++#include "clk-gate.h" ++ ++static DEFINE_SPINLOCK(mt7623_clk_lock); ++ ++static struct clk_onecell_data *mt7623_top_clk_data; ++static struct clk_onecell_data *mt7623_pll_clk_data; ++ ++static void mtk_clk_enable_critical(void) ++{ ++ if (!mt7623_top_clk_data || !mt7623_pll_clk_data) ++ return; ++ ++ clk_prepare_enable(mt7623_pll_clk_data->clks[CLK_APMIXED_ARMPLL]); ++ clk_prepare_enable(mt7623_top_clk_data->clks[CLK_TOP_MEM_SEL]); ++ clk_prepare_enable(mt7623_top_clk_data->clks[CLK_TOP_DDR_SEL]); ++ clk_prepare_enable(mt7623_top_clk_data->clks[CLK_TOP_RTC_SEL]); ++} ++ ++static const struct mtk_fixed_factor root_clk_alias[] __initconst = { ++ FACTOR(CLK_TOP_DSI0_LNTC_DSICLK, "dsi0_lntc_dsiclk", "clk_null", 1, 1), ++ FACTOR(CLK_TOP_HDMITX_CLKDIG_CTS, "hdmitx_clkdig_cts", "clk_null", 1, 1), ++ FACTOR(CLK_TOP_CLKPH_MCK, "clkph_mck", "clk_null", 1, 1), ++ FACTOR(CLK_TOP_CPUM_TCK_IN, "cpum_tck_in", "clk_null", 1, 1), ++}; ++ ++static const struct mtk_fixed_factor top_divs[] __initconst = { ++ FACTOR(CLK_TOP_MAINPLL_806M, "mainpll_650m", "mainpll", 1, 2), ++ FACTOR(CLK_TOP_MAINPLL_537P3M, "mainpll_433p3m", "mainpll", 1, 3), ++ FACTOR(CLK_TOP_MAINPLL_322P4M, "mainpll_260m", "mainpll", 1, 5), ++ FACTOR(CLK_TOP_MAINPLL_230P3M, "mainpll_185p6m", "mainpll", 1, 7), ++ ++ FACTOR(CLK_TOP_UNIVPLL_624M, "univpll_624m", "univpll", 1, 2), ++ FACTOR(CLK_TOP_UNIVPLL_416M, "univpll_416m", "univpll", 1, 3), ++ FACTOR(CLK_TOP_UNIVPLL_249P6M, "univpll_249p6m", "univpll", 1, 5), ++ FACTOR(CLK_TOP_UNIVPLL_178P3M, "univpll_178p3m", "univpll", 1, 7), ++ FACTOR(CLK_TOP_UNIVPLL_48M, "univpll_48m", "univpll", 1, 26), ++ ++ FACTOR(CLK_TOP_AUDPLL_D4, "audpll_d4", "audpll", 1, 4), ++ FACTOR(CLK_TOP_AUDPLL_D8, "audpll_d8", "audpll", 1, 8), ++ FACTOR(CLK_TOP_AUDPLL_D16, "audpll_d16", "audpll", 1, 16), ++ FACTOR(CLK_TOP_AUDPLL_24, "audpll_d24", "audpll", 1, 24), ++ ++ FACTOR(CLK_TOP_LVDSPLL_D2, "lvdspll_d2", "lvdspll", 1, 2), ++ FACTOR(CLK_TOP_LVDSPLL_D4, "lvdspll_d4", "lvdspll", 1, 4), ++ FACTOR(CLK_TOP_LVDSPLL_D8, "lvdspll_d8", "lvdspll", 1, 8), ++ FACTOR(CLK_TOP_LVDS_ETH, "lvdspll_eth", "lvdspll", 1, 16), ++ ++ FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2), ++ ++ FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2), ++ ++ FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "mainpll_650m", 1, 2), ++ FACTOR(CLK_TOP_SYSPLL1_D4, "syspll1_d4", "mainpll_650m", 1, 4), ++ FACTOR(CLK_TOP_SYSPLL1_D8, "syspll1_d8", "mainpll_650m", 1, 8), ++ FACTOR(CLK_TOP_SYSPLL1_D16, "syspll1_d16", "mainpll_650m", 1, 16), ++ FACTOR(CLK_TOP_SYSPLL2_D2, "syspll2_d2", "mainpll_650m", 1, 2), ++ FACTOR(CLK_TOP_SYSPLL2_D4, "syspll2_d4", "mainpll_650m", 1, 4), ++ FACTOR(CLK_TOP_SYSPLL2_D8, "syspll2_d8", "mainpll_650m", 1, 8), ++ FACTOR(CLK_TOP_SYSPLL3_D2, "syspll3_d2", "mainpll_650m", 1, 2), ++ FACTOR(CLK_TOP_SYSPLL3_D4, "syspll3_d4", "mainpll_650m", 1, 4), ++ FACTOR(CLK_TOP_SYSPLL4_D2, "syspll4_d2", "mainpll_650m", 1, 2), ++ FACTOR(CLK_TOP_SYSPLL4_D4, "syspll4_d4", "mainpll_650m", 1, 4), ++ FACTOR(CLK_TOP_SYSPLL_D3, "syspll_d3", "mainpll_433p3m", 1, 1), ++ FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll_260m", 1, 1), ++ FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "mainpll_185p6m", 1, 1), ++ ++ FACTOR(CLK_TOP_TVDPLL_d2, "tvdpll_d2", "tvdpll", 1, 2), ++ FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll", 1, 4), ++ ++ FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_624m", 1, 2), ++ FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_624m", 1, 4), ++ FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_624m", 1, 8), ++ FACTOR(CLK_TOP_UNIVPLL1_D10, "univpll1_d10", "univpll_624m", 1, 10), ++ ++ FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_416m", 1, 2), ++ FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_416m", 1, 4), ++ FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_416m", 1, 8), ++ ++ FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_624m", 1, 2), ++ FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_624m", 1, 4), ++ FACTOR(CLK_TOP_UNIVPLL1_D6, "univpll1_d6", "univpll_624m", 1, 6), ++ FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_624m", 1, 8), ++ FACTOR(CLK_TOP_UNIVPLL1_D10, "univpll1_d10", "univpll_624m", 1, 10), ++ ++ FACTOR(CLK_TOP_UNIVPLL2_D2, "univpll2_d2", "univpll_416m", 1, 2), ++ FACTOR(CLK_TOP_UNIVPLL2_D4, "univpll2_d4", "univpll_416m", 1, 4), ++ FACTOR(CLK_TOP_UNIVPLL2_D6, "univpll2_d6", "univpll_416m", 1, 6), ++ FACTOR(CLK_TOP_UNIVPLL2_D8, "univpll2_d8", "univpll_416m", 1, 8), ++ ++ FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll_249p6m", 1, 1), ++ FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univpll_48m", 1, 1), ++ ++ ++ FACTOR(CLK_TOP_MEMPLL_MCK_D4, "mempll_mck_d4", "clkph_mck", 1, 4), ++}; ++ ++static const char * const axi_parents[] __initconst = { ++ "clk26m", ++ "syspll1_d2", ++ "syspll_d5", ++ "syspll1_d4", ++ "univpll_d5", ++ "univpll2_d2", ++ "dmpll_ck", ++ "dmpll_d2" ++}; ++ ++static const char * const mem_parents[] __initconst = { ++ "clk26m", ++ "dmpll_ck", ++}; ++ ++static const char * const ddr_parents[] __initconst = { ++ "clk26m", ++ "syspll1_d8", ++}; ++ ++static const char * const mm_parents[] __initconst = { ++ "clk26m", ++ "clk26m", ++ "vencpll_ck", ++ "syspll1_d2", ++ "syspll1_d4", ++ "univpll_d5", ++ "univpll1_d2", ++ "univpll2_d2", ++ "dmpll_ck" ++}; ++ ++static const char * const pwm_parents[] __initconst = { ++ "clk26m", ++ "univpll2_d4", ++ "univpll3_d2", ++ "univpll1_d4", ++}; ++ ++static const char * const vdec_parents[] __initconst = { ++ "clk26m", ++ "syspll1_d2", ++ "syspll_d5", ++ "syspll1_d4", ++ "univpll_d5", ++ "univpll2_d2", ++ "univpll2_d4", ++ "msdcpll_d2", ++ "mmpll_d2", ++}; ++ ++static const char * const mfg_parents[] __initconst = { ++ "clk26m", ++ "mmpll_ck", ++ "dmpll_x2_ck", ++ "msdcpll_ck", ++ "clk26m", ++ "syspll_d3", ++ "univpll_d3", ++ "univpll1_d2", ++}; ++ ++static const char * const cam_parents[] __initconst = { ++ "clk26m", ++ "univpll_d26", ++ "univpll2_d2", ++ "syspll3_d2", ++ "syspll3_d4", ++ "msdcpll_d2", ++ "mmpll_d2", ++ "clk26m", ++}; ++ ++static const char * const uart_parents[] __initconst = { ++ "clk26m", ++ "univpll2_d8", ++}; ++ ++static const char * const spi_parents[] __initconst = { ++ "clk26m", ++ "syspll3_d2", ++ "syspll4_d2", ++ "univpll2_d4", ++ "univpll1_d8", ++}; ++ ++static const char * const usb20_parents[] __initconst = { ++ "clk26m", ++ "univpll1_d8", ++ "univpll3_d4", ++ "clk26m", ++}; ++ ++static const char * const msdc_30_0_parents[] __initconst = { ++ "clk26m", ++ "msdcpll_d2", ++ "syspll2_d2", ++ "syspll1_d4", ++ "univpll1_d4", ++ "univpll2_d4", ++ "clk26m", ++ "clk26m", ++}; ++ ++static const char * const msdc_30_1_parents[] __initconst = { ++ "clk26m", ++ "msdcpll_d2", ++ "syspll2_d2", ++ "syspll1_d4", ++ "univpll1_d4", ++ "univpll2_d4", ++ "clk26m", ++ "clk26m", ++}; ++ ++static const char * const msdc_30_2_parents[] __initconst = { ++ "clk26m", ++ "msdcpll_d2", ++ "syspll2_d2", ++ "syspll1_d4", ++ "univpll1_d4", ++ "univpll2_d4", ++ "clk26m", ++ "clk26m", ++}; ++ ++static const char * const audio_parents[] __initconst = { ++ "f_f26m_ck", ++ "syspll1_d16", ++}; ++ ++static const char * const audio_intbus_parents[] __initconst = { ++ "clk26m", ++ "syspll1_d4", ++ "syspll3_d2", ++ "syspll4_d2", ++ "univpll3_d2", ++ "univpll2_d4", ++}; ++ ++static const char * const pmic_spi_parents[] __initconst = { ++ "clk26m", ++ "syspll1_d8", ++ "syspll2_d4", ++ "syspll4_d2", ++ "syspll3_d4", ++ "syspll2_d8", ++ "syspll1_d16", ++ "univpll3_d4", ++ "univpll_d26", ++ "dmpll_d2", ++ "dmpll_d4", ++}; ++ ++static const char * const scp_parents[] __initconst = { ++ "clk26m", ++ "syspll1_d8", ++ "dmpll_d2", ++ "dmpll_d4", ++}; ++ ++static const char * const dpi0_parents[] __initconst = { ++ "clk26m", ++ "mipipll", ++ "mipipll_d2", ++ "mipipll_d4", ++ "lvdspll", ++ "lvdspll_d2", ++ "lvdspll_d4", ++ "lvdspll_d8", ++}; ++ ++static const char * const dpi1_parents[] __initconst = { ++ "clk26m", ++ "tvdpll", ++ "tvdpll_d2", ++ "tvdpll_d4", ++}; ++ ++static const char * const tve_parents[] __initconst = { ++ "clk26m", ++ "mipipll", ++ "mipipll_d2", ++ "mipipll_d4", ++ "clk26m", ++ "tvdpll", ++ "tvdpll_d2", ++ "tvdpll_d4", ++}; ++ ++static const char * const apll_parents[] __initconst = { ++ "clk26m", ++ "audpll", ++ "audpll_d4", ++ "audpll_d8", ++ "audpll_d16", ++ "audpll_d24", ++ "clk26m", ++ "clk26m", ++}; ++ ++static const char * const dpilvds_parents[] __initconst = { ++ "clk26m", ++ "lvdspll", ++ "lvdspll_d2", ++ "lvdspll_d4", ++ "lvdspll_d8", ++ "fpc_ck", ++ "clk26m", ++ "clk26m", ++}; ++ ++static const char * const rtc_parents[] __initconst = { ++ "clk32k", ++ "external_32k", ++ "clk26m", ++ "univpll3_d8", ++}; ++ ++static const char * const nfi2x_parents[] __initconst = { ++ "clk26m", ++ "syspll2_d2", ++ "syspll_d7", ++ "univpll3_d2", ++ "syspll2_d4", ++ "univpll3_d4", ++ "syspll4_d4", ++ "clk26m", ++}; ++ ++static const char * const eth_parents[] __initconst = { ++ "clk26m", ++ "syspll3_d4", ++ "univpll2_d8", ++ "lvdspll_eth", ++ "univpll_d26", ++ "syspll2_d8", ++ "syspll4_d4", ++ "univpll3_d8", ++}; ++ ++static const struct mtk_composite top_muxes[] __initconst = { ++ /* CLK_CFG_0 */ ++ MUX_GATE(CLK_TOP_AXI_SEL, "axi_sel", axi_parents, ++ 0x0140, 0, 3, INVALID_MUX_GATE_BIT), ++ MUX_GATE(CLK_TOP_MEM_SEL, "mem_sel", mem_parents, 0x0040, 8, 2, 15), ++ MUX_GATE(CLK_TOP_DDR_SEL, "ddr_sel", ddr_parents, 0x0040, 16, 2, 23), ++ MUX_GATE(CLK_TOP_MM_SEL, "mm_sel", mm_parents, ++ 0x0140, 24, 3, INVALID_MUX_GATE_BIT), ++ /* CLK_CFG_1 */ ++ MUX_GATE(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x0050, 0, 2, 7), ++ MUX_GATE(CLK_TOP_VDEC_SEL, "vdec_sel", vdec_parents, 0x0050, 8, 4, 15), ++ MUX_GATE(CLK_TOP_MFG_SEL, "mfg_sel", mfg_parents, 0x0050, 16, 3, 23), ++ MUX_GATE(CLK_TOP_CAM_SEL, "cam_sel", cam_parents, 0x0050, 24, 3, 31), ++ /* CLK_CFG_2 */ ++ MUX_GATE(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x0060, 0, 1, 7), ++ MUX_GATE(CLK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x0060, 8, 3, 15), ++ MUX_GATE(CLK_TOP_USB20_SEL, "usb20_sel", usb20_parents, 0x0060, 16, 2, 23), ++ MUX_GATE(CLK_TOP_MSDC30_0_SEL, "msdc_30_0_sel", msdc_30_0_parents, 0x0060, 24, 3, 31), ++ /* CLK_CFG_3 */ ++ MUX_GATE(CLK_TOP_MSDC30_1_SEL, "msdc_30_1_sel", msdc_30_1_parents, 0x0070, 0, 3, 7), ++ MUX_GATE(CLK_TOP_MSDC30_2_SEL, "msdc_30_2_sel", msdc_30_2_parents, 0x0070, 8, 3, 15), ++ MUX_GATE(CLK_TOP_AUDIO_SEL, "audio_sel", audio_parents, 0x0070, 16, 1, 23), ++ MUX_GATE(CLK_TOP_AUDIO_INTBUS_SEL, ++ "audio_intbus_sel", audio_intbus_parents, 0x0070, 24, 3, 31), ++ /* CLK_CFG_4 */ ++ MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmic_spi_parents, 0x0080, 0, 4, 7), ++ MUX_GATE(CLK_TOP_SCP_SEL, "scp_sel", scp_parents, 0x0080, 8, 2, 15), ++ MUX_GATE(CLK_TOP_DPI0_SEL, "dpi0_sel", dpi0_parents, 0x0080, 16, 3, 23), ++ MUX_GATE(CLK_TOP_DPI1_SEL, "dpi1_sel", dpi1_parents, 0x0080, 24, 2, 31), ++ /* CLK_CFG_5 */ ++ MUX_GATE(CLK_TOP_TVE_SEL, "tve_sel", tve_parents, 0x0090, 0, 3, 7), ++ MUX_GATE(CLK_TOP_APLL_SEL, "apll_sel", apll_parents, 0x0090, 16, 3, 23), ++ MUX_GATE(CLK_TOP_DPILVDS_SEL, "dpilvds_sel", dpilvds_parents, 0x0090, 24, 3, 31), ++ /* CLK_CFG_6 */ ++ MUX_GATE(CLK_TOP_RTC_SEL, "rtc_sel", rtc_parents, 0x00a0, 0, 2, 7), ++ MUX_GATE(CLK_TOP_NFI2X_SEL, "nfi2x_sel", nfi2x_parents, 0x00a0, 8, 3, 15), ++ MUX_GATE(CLK_TOP_ETH_SEL, "eth_sel", eth_parents, 0x00a0, 16, 3, 23), ++}; ++ ++static const struct mtk_gate_regs infra_cg_regs = { ++ .set_ofs = 0x0040, ++ .clr_ofs = 0x0044, ++ .sta_ofs = 0x0048, ++}; ++ ++#define GATE_ICG(_id, _name, _parent, _shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .regs = &infra_cg_regs, \ ++ .shift = _shift, \ ++ .ops = &mtk_clk_gate_ops_setclr, \ ++ } ++ ++static const struct mtk_gate infra_clks[] __initconst = { ++ GATE_ICG(CLK_INFRA_DBGCLK, "dbgclk_ck", "axi_sel", 0), ++ GATE_ICG(CLK_INFRA_SMI, "smi_ck", "smi_sel", 1), ++ GATE_ICG(CLK_INFRA_AUDIO, "audio_ck", "aud_intbus_sel", 5), ++ GATE_ICG(CLK_INFRA_EFUSE, "efuse_ck", "axi_sel", 5), ++ GATE_ICG(CLK_INFRA_EFUSE, "l2c_sram_ck", "axi_sel", 5), ++ GATE_ICG(CLK_INFRA_M4U, "m4u_ck", "mem_sel", 8), ++ GATE_ICG(CLK_INFRA_CONNMCU, "connmcu_ck", "axi_sel", 8), ++ GATE_ICG(CLK_INFRA_TRNG, "trng_ck", "axi_sel", 8), ++ GATE_ICG(CLK_INFRA_CPUM, "cpum_ck", "cpum_tck_in", 15), ++ GATE_ICG(CLK_INFRA_KP, "kp_ck", "axi_sel", 16), ++ GATE_ICG(CLK_INFRA_CEC, "cec_ck", "axi_sel", 16), ++ GATE_ICG(CLK_INFRA_IRRX, "irrx_ck", "axi_sel", 16), ++ GATE_ICG(CLK_INFRA_PMICSPI, "pmicspi_ck", "pmicspi_sel", 22), ++ GATE_ICG(CLK_INFRA_PMIC_WRAP, "pmic_wrap_ck", "axi_sel", 23), ++}; ++ ++static const struct mtk_gate_regs peri0_cg_regs = { ++ .set_ofs = 0x0008, ++ .clr_ofs = 0x0010, ++ .sta_ofs = 0x0018, ++}; ++ ++static const struct mtk_gate_regs peri1_cg_regs = { ++ .set_ofs = 0x000c, ++ .clr_ofs = 0x0014, ++ .sta_ofs = 0x001c, ++}; ++ ++#define GATE_PERI0(_id, _name, _parent, _shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .regs = &peri0_cg_regs, \ ++ .shift = _shift, \ ++ .ops = &mtk_clk_gate_ops_setclr, \ ++ } ++ ++#define GATE_PERI1(_id, _name, _parent, _shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .regs = &peri1_cg_regs, \ ++ .shift = _shift, \ ++ .ops = &mtk_clk_gate_ops_setclr, \ ++ } ++ ++static const struct mtk_gate peri_gates[] __initconst = { ++ /* PERI0 */ ++ GATE_PERI0(CLK_PERI_NFI, "nfi_ck", "axi_sel", 0), ++ GATE_PERI0(CLK_PERI_THERM, "therm_ck", "axi_sel", 1), ++ GATE_PERI0(CLK_PERI_PWM1, "pwm1_ck", "axi_sel", 2), ++ GATE_PERI0(CLK_PERI_PWM2, "pwm2_ck", "axi_sel", 3), ++ GATE_PERI0(CLK_PERI_PWM3, "pwm3_ck", "axi_sel", 4), ++ GATE_PERI0(CLK_PERI_PWM4, "pwm4_ck", "axi_sel", 5), ++ GATE_PERI0(CLK_PERI_PWM5, "pwm5_ck", "axi_sel", 6), ++ GATE_PERI0(CLK_PERI_PWM6, "pwm6_ck", "axi_sel", 7), ++ GATE_PERI0(CLK_PERI_PWM7, "pwm7_ck", "axi_sel", 8), ++ GATE_PERI0(CLK_PERI_PWM, "pwm_ck", "axi_sel", 9), ++ GATE_PERI0(CLK_PERI_USB0, "usb0_ck", "usb20_sel", 10), ++ GATE_PERI0(CLK_PERI_USB1, "usb1_ck", "usb20_sel", 11), ++ GATE_PERI0(CLK_PERI_AP_DMA, "ap_dma_ck", "axi_sel", 12), ++ GATE_PERI0(CLK_PERI_MSDC20_1, "msdc_20_1_ck", "msdc_30_0_sel", 13), ++ GATE_PERI0(CLK_PERI_MSDC20_2, "msdc_20_2_ck", "msdc_30_1_sel", 14), ++ GATE_PERI0(CLK_PERI_MSDC30_1, "msdc_30_1_ck", "msdc_30_2_sel", 15), ++ GATE_PERI0(CLK_PERI_NLI, "nli_ck", "axi_sel", 16), ++ GATE_PERI0(CLK_PERI_UART0, "uart0_ck", "axi_sel", 17), ++ GATE_PERI0(CLK_PERI_UART1, "uart1_ck", "axi_sel", 18), ++ GATE_PERI0(CLK_PERI_UART2, "uart2_ck", "axi_sel", 19), ++ GATE_PERI0(CLK_PERI_UART3, "uart3_ck", "axi_sel", 20), ++ GATE_PERI0(CLK_PERI_BTIF, "btif_ck", "axi_sel", 21), ++ GATE_PERI0(CLK_PERI_I2C0, "i2c0_ck", "axi_sel", 22), ++ GATE_PERI0(CLK_PERI_I2C1, "i2c1_ck", "axi_sel", 23), ++ GATE_PERI0(CLK_PERI_I2C2, "i2c2_ck", "axi_sel", 24), ++ GATE_PERI0(CLK_PERI_I2C3, "i2c3_ck", "axi_sel", 25), ++ GATE_PERI0(CLK_PERI_AUXADC, "auxadc_ck", "axi_sel", 26), ++ GATE_PERI0(CLK_PERI_SPI0, "spi0_ck", "spi0_sel", 27), ++ GATE_PERI0(CLK_PERI_ETH, "eth_ck", "eth_sel", 28), ++ GATE_PERI0(CLK_PERI_USB0_MCU, "usb0_mcu", "axi_sel", 29), ++ GATE_PERI0(CLK_PERI_USB1_MCU, "usb1_mcu","axi_sel", 30), ++ GATE_PERI0(CLK_PERI_USB_SLV, "usb_slv", "axi_sel", 31), ++ ++ /* PERI1 */ ++ GATE_PERI1(CLK_PERI_GCPU, "gcpu_ck", "axi_sel", 0), ++ GATE_PERI1(CLK_PERI_NFI_ECC, "nfi_ecc_ck", "axi_sel", 1), ++ GATE_PERI1(CLK_PERI_NFI_PAD, "nfi_pad_ck", "axi_sel", 2), ++}; ++ ++static const char * const uart_ck_sel_parents[] __initconst = { ++ "clk26m", ++ "uart_sel", ++}; ++ ++static const struct mtk_composite peri_clks[] __initconst = { ++ MUX(CLK_PERI_UART0_SEL, "uart0_ck_sel", uart_ck_sel_parents, 0x40c, 0, 1), ++ MUX(CLK_PERI_UART1_SEL, "uart1_ck_sel", uart_ck_sel_parents, 0x40c, 1, 1), ++ MUX(CLK_PERI_UART2_SEL, "uart2_ck_sel", uart_ck_sel_parents, 0x40c, 2, 1), ++ MUX(CLK_PERI_UART3_SEL, "uart3_ck_sel", uart_ck_sel_parents, 0x40c, 3, 1), ++}; ++ ++static void __init mtk_topckgen_init(struct device_node *node) ++{ ++ struct clk_onecell_data *clk_data; ++ void __iomem *base; ++ int r; ++ ++ base = of_iomap(node, 0); ++ if (!base) { ++ pr_err("%s(): ioremap failed\n", __func__); ++ return; ++ } ++ ++ mt7623_top_clk_data = clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); ++ ++ mtk_clk_register_factors(root_clk_alias, ARRAY_SIZE(root_clk_alias), clk_data); ++ mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data); ++ mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base, ++ &mt7623_clk_lock, clk_data); ++ ++ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); ++ if (r) ++ pr_err("%s(): could not register clock provider: %d\n", ++ __func__, r); ++ ++ mtk_clk_enable_critical(); ++} ++CLK_OF_DECLARE(mtk_topckgen, "mediatek,mt7623-topckgen", mtk_topckgen_init); ++ ++static void __init mtk_infrasys_init(struct device_node *node) ++{ ++ struct clk_onecell_data *clk_data; ++ int r; ++ ++ clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK); ++ ++ mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks), ++ clk_data); ++ ++ clk_prepare_enable(clk_data->clks[CLK_INFRA_M4U]); ++ ++ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); ++ if (r) ++ pr_err("%s(): could not register clock provider: %d\n", ++ __func__, r); ++ ++ mtk_register_reset_controller(node, 2, 0x30); ++} ++CLK_OF_DECLARE(mtk_infrasys, "mediatek,mt7623-infracfg", mtk_infrasys_init); ++ ++static void __init mtk_pericfg_init(struct device_node *node) ++{ ++ struct clk_onecell_data *clk_data; ++ int r; ++ void __iomem *base; ++ ++ base = of_iomap(node, 0); ++ if (!base) { ++ pr_err("%s(): ioremap failed\n", __func__); ++ return; ++ } ++ ++ clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK); ++ ++ mtk_clk_register_gates(node, peri_gates, ARRAY_SIZE(peri_gates), ++ clk_data); ++ mtk_clk_register_composites(peri_clks, ARRAY_SIZE(peri_clks), base, ++ &mt7623_clk_lock, clk_data); ++ ++ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); ++ if (r) ++ pr_err("%s(): could not register clock provider: %d\n", ++ __func__, r); ++ ++ mtk_register_reset_controller(node, 2, 0); ++} ++CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt7623-pericfg", mtk_pericfg_init); ++ ++#define MT7623_PLL_FMAX (2000 * MHZ) ++#define CON0_MT7623_RST_BAR BIT(27) ++ ++#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .reg = _reg, \ ++ .pwr_reg = _pwr_reg, \ ++ .en_mask = _en_mask, \ ++ .flags = _flags, \ ++ .rst_bar_mask = CON0_MT7623_RST_BAR, \ ++ .fmax = MT7623_PLL_FMAX, \ ++ .pcwbits = _pcwbits, \ ++ .pd_reg = _pd_reg, \ ++ .pd_shift = _pd_shift, \ ++ .tuner_reg = _tuner_reg, \ ++ .pcw_reg = _pcw_reg, \ ++ .pcw_shift = _pcw_shift, \ ++ } ++ ++static const struct mtk_pll_data plls[] = { ++ PLL(CLK_APMIXED_ARMPLL, "armpll", 0x200, 0x20c, 0x00000001, 0, 21, 0x204, 24, 0x0, 0x204, 0), ++ PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x210, 0x21c, 0x78000001, HAVE_RST_BAR, 21, 0x214, 6, 0x0, 0x214, 0), ++ PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x220, 0x22c, 0xFC000001, HAVE_RST_BAR, 7, 0x224, 6, 0x0, 0x224, 0), ++ PLL(CLK_APMIXED_MMPLL, "mmpll", 0x230, 0x23c, 0x00000001, 0, 21, 0x254, 6, 0x0, 0x258, 0), ++ PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x240, 0x24c, 0x00000001, 0, 21, 0x244, 6, 0x0, 0x244, 0), ++ PLL(CLK_APMIXED_AUDPLL, "audpll", 0x250, 0x25c, 0x00000001, 0, 31, 0x2e8, 6, 0x2f8, 0x254, 0), ++ PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x260, 0x26c, 0x00000001, 0, 31, 0x294, 6, 0x0, 0x298, 0), ++ PLL(CLK_APMIXED_LVDSPLL, "lvdspll", 0x270, 0x27c, 0x00000001, 0, 21, 0x2b0, 6, 0x0, 0x2b4, 0), ++}; ++ ++static void __init mtk_apmixedsys_init(struct device_node *node) ++{ ++ struct clk_onecell_data *clk_data; ++ ++ mt7623_pll_clk_data = clk_data = mtk_alloc_clk_data(ARRAY_SIZE(plls)); ++ if (!clk_data) ++ return; ++ ++ mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data); ++ mtk_clk_enable_critical(); ++} ++CLK_OF_DECLARE(mtk_apmixedsys, "mediatek,mt7623-apmixedsys", ++ mtk_apmixedsys_init); +diff --git a/include/dt-bindings/clock/mt7623-clk.h b/include/dt-bindings/clock/mt7623-clk.h +new file mode 100644 +index 0000000..cb1e8a9 +--- /dev/null ++++ b/include/dt-bindings/clock/mt7623-clk.h +@@ -0,0 +1,173 @@ ++/* ++ * Copyright c 2014 MediaTek Inc. ++ * Author: James Liao <jamesjj.liao@mediatek.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _DT_BINDINGS_CLK_MT7623_H ++#define _DT_BINDINGS_CLK_MT7623_H ++ ++/* TOPCKGEN */ ++ ++#define CLK_TOP_AUDPLL_24 1 ++#define CLK_TOP_AUDPLL_D16 2 ++#define CLK_TOP_AUDPLL_D4 3 ++#define CLK_TOP_AUDPLL_D8 4 ++#define CLK_TOP_CLKPH_MCK 5 ++#define CLK_TOP_CPUM_TCK_IN 6 ++#define CLK_TOP_DSI0_LNTC_DSICLK 7 ++#define CLK_TOP_HDMITX_CLKDIG_CTS 8 ++#define CLK_TOP_LVDS_ETH 9 ++#define CLK_TOP_LVDSPLL_D2 10 ++#define CLK_TOP_LVDSPLL_D4 11 ++#define CLK_TOP_LVDSPLL_D8 12 ++#define CLK_TOP_MAINPLL_230P3M 13 ++#define CLK_TOP_MAINPLL_322P4M 14 ++#define CLK_TOP_MAINPLL_537P3M 15 ++#define CLK_TOP_MAINPLL_806M 16 ++#define CLK_TOP_MEMPLL_MCK_D4 17 ++#define CLK_TOP_MMPLL_D2 18 ++#define CLK_TOP_MSDCPLL_D2 19 ++#define CLK_TOP_SYSPLL1_D16 20 ++#define CLK_TOP_SYSPLL1_D2 21 ++#define CLK_TOP_SYSPLL1_D4 22 ++#define CLK_TOP_SYSPLL1_D8 23 ++#define CLK_TOP_SYSPLL2_D2 24 ++#define CLK_TOP_SYSPLL2_D4 25 ++#define CLK_TOP_SYSPLL2_D8 26 ++#define CLK_TOP_SYSPLL3_D2 27 ++#define CLK_TOP_SYSPLL3_D4 28 ++#define CLK_TOP_SYSPLL4_D2 29 ++#define CLK_TOP_SYSPLL4_D4 30 ++#define CLK_TOP_SYSPLL_D3 31 ++#define CLK_TOP_SYSPLL_D5 32 ++#define CLK_TOP_SYSPLL_D7 33 ++#define CLK_TOP_TVDPLL_d2 34 ++#define CLK_TOP_TVDPLL_D4 35 ++#define CLK_TOP_UNIVPLL_178P3M 36 ++#define CLK_TOP_UNIVPLL1_D10 37 ++#define CLK_TOP_UNIVPLL1_D2 38 ++#define CLK_TOP_UNIVPLL1_D4 39 ++#define CLK_TOP_UNIVPLL1_D6 40 ++#define CLK_TOP_UNIVPLL1_D8 41 ++#define CLK_TOP_UNIVPLL_249P6M 42 ++#define CLK_TOP_UNIVPLL2_D2 43 ++#define CLK_TOP_UNIVPLL2_D4 44 ++#define CLK_TOP_UNIVPLL2_D6 45 ++#define CLK_TOP_UNIVPLL2_D8 46 ++#define CLK_TOP_UNIVPLL_416M 47 ++#define CLK_TOP_UNIVPLL_48M 48 ++#define CLK_TOP_UNIVPLL_624M 49 ++#define CLK_TOP_UNIVPLL_D26 50 ++#define CLK_TOP_UNIVPLL_D5 51 ++#define CLK_TOP_APLL_SEL 52 ++#define CLK_TOP_AUDIO_INTBUS_SEL 53 ++#define CLK_TOP_AUDIO_SEL 54 ++#define CLK_TOP_AXI_SEL 55 ++#define CLK_TOP_CAM_SEL 56 ++#define CLK_TOP_DDR_SEL 57 ++#define CLK_TOP_DPI0_SEL 58 ++#define CLK_TOP_DPI1_SEL 59 ++#define CLK_TOP_DPILVDS_SEL 60 ++#define CLK_TOP_ETH_SEL 61 ++#define CLK_TOP_MEM_SEL 62 ++#define CLK_TOP_MFG_SEL 63 ++#define CLK_TOP_MM_SEL 64 ++#define CLK_TOP_MSDC30_0_SEL 65 ++#define CLK_TOP_MSDC30_1_SEL 66 ++#define CLK_TOP_MSDC30_2_SEL 67 ++#define CLK_TOP_NFI2X_SEL 68 ++#define CLK_TOP_PMICSPI_SEL 69 ++#define CLK_TOP_PWM_SEL 70 ++#define CLK_TOP_RTC_SEL 71 ++#define CLK_TOP_SCP_SEL 72 ++#define CLK_TOP_SPI_SEL 73 ++#define CLK_TOP_TVE_SEL 74 ++#define CLK_TOP_UART_SEL 75 ++#define CLK_TOP_USB20_SEL 76 ++#define CLK_TOP_VDEC_SEL 77 ++#define CLK_TOP_NR_CLK 78 ++ ++/* APMIXED_SYS */ ++ ++#define CLK_APMIXED_ARMPLL 1 ++#define CLK_APMIXED_MAINPLL 2 ++#define CLK_APMIXED_MSDCPLL 3 ++#define CLK_APMIXED_UNIVPLL 4 ++#define CLK_APMIXED_MMPLL 5 ++#define CLK_APMIXED_VENCPLL 6 ++#define CLK_APMIXED_TVDPLL 7 ++#define CLK_APMIXED_LVDSPLL 8 ++#define CLK_APMIXED_AUDPLL 9 ++ ++/* INFRA_SYS */ ++ ++#define CLK_INFRA_DBGCLK 0 ++#define CLK_INFRA_SMI 1 ++#define CLK_INFRA_AUDIO 5 ++#define CLK_INFRA_EFUSE 6 ++#define CLK_INFRA_L2C_SRAM 7 ++#define CLK_INFRA_M4U 8 ++#define CLK_INFRA_CONNMCU 12 ++#define CLK_INFRA_TRNG 13 ++#define CLK_INFRA_CPUM 15 ++#define CLK_INFRA_KP 16 ++#define CLK_INFRA_CEC 18 ++#define CLK_INFRA_IRRX 19 ++#define CLK_INFRA_PMICSPI 22 ++#define CLK_INFRA_PMIC_WRAP 23 ++#define CLK_INFRA_NR_CLK 24 ++ ++/* PERI_SYS */ ++ ++#define CLK_PERI_NFI 0 ++#define CLK_PERI_THERM 1 ++#define CLK_PERI_PWM1 2 ++#define CLK_PERI_PWM2 3 ++#define CLK_PERI_PWM3 4 ++#define CLK_PERI_PWM4 5 ++#define CLK_PERI_PWM5 6 ++#define CLK_PERI_PWM6 7 ++#define CLK_PERI_PWM7 8 ++#define CLK_PERI_PWM 9 ++#define CLK_PERI_USB0 10 ++#define CLK_PERI_USB1 11 ++#define CLK_PERI_AP_DMA 12 ++#define CLK_PERI_MSDC20_1 13 ++#define CLK_PERI_MSDC20_2 14 ++#define CLK_PERI_MSDC30_1 15 ++#define CLK_PERI_NLI 16 ++#define CLK_PERI_UART0 17 ++#define CLK_PERI_UART1 18 ++#define CLK_PERI_UART2 19 ++#define CLK_PERI_UART3 20 ++#define CLK_PERI_BTIF 21 ++#define CLK_PERI_I2C0 22 ++#define CLK_PERI_I2C1 23 ++#define CLK_PERI_I2C2 24 ++#define CLK_PERI_I2C3 25 ++#define CLK_PERI_AUXADC 26 ++#define CLK_PERI_SPI0 27 ++#define CLK_PERI_ETH 28 ++#define CLK_PERI_USB0_MCU 29 ++#define CLK_PERI_USB1_MCU 30 ++#define CLK_PERI_USB_SLV 31 ++#define CLK_PERI_GCPU 32 ++#define CLK_PERI_NFI_ECC 33 ++#define CLK_PERI_NFI_PAD 34 ++#define CLK_PERI_UART0_SEL 35 ++#define CLK_PERI_UART1_SEL 36 ++#define CLK_PERI_UART2_SEL 37 ++#define CLK_PERI_UART3_SEL 38 ++#define CLK_PERI_NR_CLK 39 ++ ++#endif /* _DT_BINDINGS_CLK_MT7623_H */ ++ +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0062-arm-mediatek-add-mt7623-pinctrl-supoort.patch b/target/linux/mediatek/patches/0062-arm-mediatek-add-mt7623-pinctrl-supoort.patch new file mode 100644 index 0000000000..c9ea40eac9 --- /dev/null +++ b/target/linux/mediatek/patches/0062-arm-mediatek-add-mt7623-pinctrl-supoort.patch @@ -0,0 +1,2889 @@ +From 718f377d37a737b133a3d904f5a038d6aa55c23e Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Sat, 27 Jun 2015 13:13:05 +0200 +Subject: [PATCH 62/76] arm: mediatek: add mt7623 pinctrl supoort + +Signed-off-by: John Crispin <blogic@openwrt.org> +--- + drivers/pinctrl/mediatek/Kconfig | 6 + + drivers/pinctrl/mediatek/Makefile | 1 + + drivers/pinctrl/mediatek/pinctrl-mt7623.c | 368 +++++ + drivers/pinctrl/mediatek/pinctrl-mtk-mt7623.h | 1926 +++++++++++++++++++++++++ + include/dt-bindings/pinctrl/mt7623-pinfunc.h | 526 +++++++ + 5 files changed, 2827 insertions(+) + create mode 100644 drivers/pinctrl/mediatek/pinctrl-mt7623.c + create mode 100644 drivers/pinctrl/mediatek/pinctrl-mtk-mt7623.h + create mode 100644 include/dt-bindings/pinctrl/mt7623-pinfunc.h + +diff --git a/drivers/pinctrl/mediatek/Kconfig b/drivers/pinctrl/mediatek/Kconfig +index 0bc84fb..27c5673 100644 +--- a/drivers/pinctrl/mediatek/Kconfig ++++ b/drivers/pinctrl/mediatek/Kconfig +@@ -9,6 +9,12 @@ config PINCTRL_MTK_COMMON + select OF_GPIO + + # For ARMv7 SoCs ++config PINCTRL_MT7623 ++ bool "Mediatek MT7623 pin control" if COMPILE_TEST && !MACH_MT7623 ++ depends on OF ++ default MACH_MT7623 ++ select PINCTRL_MTK_COMMON ++ + config PINCTRL_MT8135 + bool "Mediatek MT8135 pin control" if COMPILE_TEST && !MACH_MT8135 + depends on OF +diff --git a/drivers/pinctrl/mediatek/Makefile b/drivers/pinctrl/mediatek/Makefile +index eb923d6..8998433 100644 +--- a/drivers/pinctrl/mediatek/Makefile ++++ b/drivers/pinctrl/mediatek/Makefile +@@ -2,6 +2,7 @@ + obj-$(CONFIG_PINCTRL_MTK_COMMON) += pinctrl-mtk-common.o + + # SoC Drivers ++obj-$(CONFIG_PINCTRL_MT7623) += pinctrl-mt7623.o + obj-$(CONFIG_PINCTRL_MT8135) += pinctrl-mt8135.o + obj-$(CONFIG_PINCTRL_MT8127) += pinctrl-mt8127.o + obj-$(CONFIG_PINCTRL_MT8173) += pinctrl-mt8173.o +diff --git a/drivers/pinctrl/mediatek/pinctrl-mt7623.c b/drivers/pinctrl/mediatek/pinctrl-mt7623.c +new file mode 100644 +index 0000000..77e1a66 +--- /dev/null ++++ b/drivers/pinctrl/mediatek/pinctrl-mt7623.c +@@ -0,0 +1,368 @@ ++/* ++ * Copyright (c) 2014-2015 MediaTek Inc. ++ * Author: Hongzhou.Yang <hongzhou.yang@mediatek.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/module.h> ++#include <linux/platform_device.h> ++#include <linux/of.h> ++#include <linux/of_device.h> ++#include <linux/pinctrl/pinctrl.h> ++#include <linux/regmap.h> ++#include <linux/pinctrl/pinconf-generic.h> ++#include <dt-bindings/pinctrl/mt65xx.h> ++ ++#include "pinctrl-mtk-common.h" ++#include "pinctrl-mtk-mt7623.h" ++ ++#define DRV_BASE 0xb00 ++ ++static const struct mtk_pin_spec_pupd_set_samereg mt7623_spec_pupd[] = { ++ MTK_PIN_PUPD_SPEC_SR(65, 0xcc0, 8, 9, 10), /* ms0 clk */ ++ MTK_PIN_PUPD_SPEC_SR(57, 0xcd0, 8, 9, 10), /* ms0 cmd */ ++ MTK_PIN_PUPD_SPEC_SR(60, 0xcf0, 0, 1, 2), /* ms0 data0 */ ++ MTK_PIN_PUPD_SPEC_SR(59, 0xcf0, 4, 5, 6), /* ms0 data1 */ ++ MTK_PIN_PUPD_SPEC_SR(58, 0xcf0, 8, 9, 10), /* ms0 data2 */ ++ MTK_PIN_PUPD_SPEC_SR(57, 0xcf0, 12, 13, 14), /* ms0 data3 */ ++ MTK_PIN_PUPD_SPEC_SR(61, 0xd00, 0, 1, 2), /* ms0 data4 */ ++ MTK_PIN_PUPD_SPEC_SR(62, 0xd00, 4, 5, 6), /* ms0 data5 */ ++ MTK_PIN_PUPD_SPEC_SR(63, 0xd00, 8, 9, 10), /* ms0 data6 */ ++ MTK_PIN_PUPD_SPEC_SR(64, 0xd00, 12, 13, 14), /* ms0 data7 */ ++ MTK_PIN_PUPD_SPEC_SR(67, 0xd10, 0, 1, 2), /* ms0 RST */ ++ ++ MTK_PIN_PUPD_SPEC_SR(78, 0xc50, 2, 1, 0), /* ms1 cmd */ ++ MTK_PIN_PUPD_SPEC_SR(73, 0xd20, 2, 1, 0), /* ms1 dat0 */ ++ MTK_PIN_PUPD_SPEC_SR(74, 0xd20, 6, 5, 4), /* ms1 dat1 */ ++ MTK_PIN_PUPD_SPEC_SR(75, 0xd20, 10, 9, 8), /* ms1 dat2 */ ++ MTK_PIN_PUPD_SPEC_SR(76, 0xd20, 14, 13, 12), /* ms1 dat3 */ ++ MTK_PIN_PUPD_SPEC_SR(77, 0xc40, 2, 1, 0), /* ms1 clk */ ++}; ++ ++static int mt7623_spec_pull_set(struct regmap *regmap, unsigned int pin, ++ unsigned char align, bool isup, unsigned int r1r0) ++{ ++ return mtk_pctrl_spec_pull_set_samereg(regmap, mt7623_spec_pupd, ++ ARRAY_SIZE(mt7623_spec_pupd), pin, align, isup, r1r0); ++} ++ ++/*static const struct mtk_pin_ies_smt_set mt7623_smt_set[] = { ++ MTK_PIN_IES_SMT_SPEC(0, 4, 0x930, 1), ++ MTK_PIN_IES_SMT_SPEC(5, 9, 0x930, 2), ++ MTK_PIN_IES_SMT_SPEC(10, 13, 0x930, 10), ++ MTK_PIN_IES_SMT_SPEC(14, 15, 0x940, 10), ++ MTK_PIN_IES_SMT_SPEC(16, 16, 0x930, 0), ++ MTK_PIN_IES_SMT_SPEC(17, 17, 0x950, 2), ++ MTK_PIN_IES_SMT_SPEC(18, 21, 0x940, 3), ++ MTK_PIN_IES_SMT_SPEC(29, 32, 0x930, 3), ++ MTK_PIN_IES_SMT_SPEC(33, 33, 0x930, 4), ++ MTK_PIN_IES_SMT_SPEC(34, 36, 0x930, 5), ++ MTK_PIN_IES_SMT_SPEC(37, 38, 0x930, 6), ++ MTK_PIN_IES_SMT_SPEC(39, 39, 0x930, 7), ++ MTK_PIN_IES_SMT_SPEC(40, 41, 0x930, 9), ++ MTK_PIN_IES_SMT_SPEC(42, 42, 0x940, 0), ++ MTK_PIN_IES_SMT_SPEC(43, 44, 0x930, 11), ++ MTK_PIN_IES_SMT_SPEC(45, 46, 0x930, 12), ++ MTK_PIN_IES_SMT_SPEC(57, 64, 0xc20, 13), ++ MTK_PIN_IES_SMT_SPEC(65, 65, 0xc10, 13), ++ MTK_PIN_IES_SMT_SPEC(66, 66, 0xc00, 13), ++ MTK_PIN_IES_SMT_SPEC(67, 67, 0xd10, 13), ++ MTK_PIN_IES_SMT_SPEC(68, 68, 0xd00, 13), ++ MTK_PIN_IES_SMT_SPEC(69, 72, 0x940, 14), ++ MTK_PIN_IES_SMT_SPEC(73, 76, 0xc60, 13), ++ MTK_PIN_IES_SMT_SPEC(77, 77, 0xc40, 13), ++ MTK_PIN_IES_SMT_SPEC(78, 78, 0xc50, 13), ++ MTK_PIN_IES_SMT_SPEC(79, 82, 0x940, 15), ++ MTK_PIN_IES_SMT_SPEC(83, 83, 0x950, 0), ++ MTK_PIN_IES_SMT_SPEC(84, 85, 0x950, 1), ++ MTK_PIN_IES_SMT_SPEC(86, 91, 0x950, 2), ++ MTK_PIN_IES_SMT_SPEC(92, 92, 0x930, 13), ++ MTK_PIN_IES_SMT_SPEC(93, 95, 0x930, 14), ++ MTK_PIN_IES_SMT_SPEC(96, 99, 0x930, 15), ++ MTK_PIN_IES_SMT_SPEC(100, 103, 0xca0, 13), ++ MTK_PIN_IES_SMT_SPEC(104, 104, 0xc80, 13), ++ MTK_PIN_IES_SMT_SPEC(105, 105, 0xc90, 13), ++ MTK_PIN_IES_SMT_SPEC(106, 107, 0x940, 4), ++ MTK_PIN_IES_SMT_SPEC(108, 112, 0x940, 1), ++ MTK_PIN_IES_SMT_SPEC(113, 116, 0x940, 2), ++ MTK_PIN_IES_SMT_SPEC(117, 118, 0x940, 5), ++ MTK_PIN_IES_SMT_SPEC(119, 124, 0x940, 6), ++ MTK_PIN_IES_SMT_SPEC(125, 126, 0x940, 7), ++ MTK_PIN_IES_SMT_SPEC(127, 127, 0x940, 0), ++ MTK_PIN_IES_SMT_SPEC(128, 128, 0x950, 8), ++ MTK_PIN_IES_SMT_SPEC(129, 130, 0x950, 9), ++ MTK_PIN_IES_SMT_SPEC(131, 132, 0x950, 8), ++ MTK_PIN_IES_SMT_SPEC(133, 134, 0x910, 8) ++}; ++ ++static const struct mtk_pin_ies_smt_set mt7623_ies_set[] = { ++ MTK_PIN_IES_SMT_SPEC(0, 4, 0x900, 1), ++ MTK_PIN_IES_SMT_SPEC(5, 9, 0x900, 2), ++ MTK_PIN_IES_SMT_SPEC(10, 13, 0x900, 10), ++ MTK_PIN_IES_SMT_SPEC(14, 15, 0x910, 10), ++ MTK_PIN_IES_SMT_SPEC(16, 16, 0x900, 0), ++ MTK_PIN_IES_SMT_SPEC(17, 17, 0x920, 2), ++ MTK_PIN_IES_SMT_SPEC(18, 21, 0x910, 3), ++ MTK_PIN_IES_SMT_SPEC(29, 32, 0x900, 3), ++ MTK_PIN_IES_SMT_SPEC(33, 33, 0x900, 4), ++ MTK_PIN_IES_SMT_SPEC(34, 36, 0x900, 5), ++ MTK_PIN_IES_SMT_SPEC(37, 38, 0x900, 6), ++ MTK_PIN_IES_SMT_SPEC(39, 39, 0x900, 7), ++ MTK_PIN_IES_SMT_SPEC(40, 41, 0x900, 9), ++ MTK_PIN_IES_SMT_SPEC(42, 42, 0x910, 0), ++ MTK_PIN_IES_SMT_SPEC(43, 44, 0x900, 11), ++ MTK_PIN_IES_SMT_SPEC(45, 46, 0x900, 12), ++ MTK_PIN_IES_SMT_SPEC(57, 64, 0xc20, 14), ++ MTK_PIN_IES_SMT_SPEC(65, 65, 0xc10, 14), ++ MTK_PIN_IES_SMT_SPEC(66, 66, 0xc00, 14), ++ MTK_PIN_IES_SMT_SPEC(67, 67, 0xd10, 14), ++ MTK_PIN_IES_SMT_SPEC(68, 68, 0xd00, 14), ++ MTK_PIN_IES_SMT_SPEC(69, 72, 0x910, 14), ++ MTK_PIN_IES_SMT_SPEC(73, 76, 0xc60, 14), ++ MTK_PIN_IES_SMT_SPEC(77, 77, 0xc40, 14), ++ MTK_PIN_IES_SMT_SPEC(78, 78, 0xc50, 14), ++ MTK_PIN_IES_SMT_SPEC(79, 82, 0x910, 15), ++ MTK_PIN_IES_SMT_SPEC(83, 83, 0x920, 0), ++ MTK_PIN_IES_SMT_SPEC(84, 85, 0x920, 1), ++ MTK_PIN_IES_SMT_SPEC(86, 91, 0x920, 2), ++ MTK_PIN_IES_SMT_SPEC(92, 92, 0x900, 13), ++ MTK_PIN_IES_SMT_SPEC(93, 95, 0x900, 14), ++ MTK_PIN_IES_SMT_SPEC(96, 99, 0x900, 15), ++ MTK_PIN_IES_SMT_SPEC(100, 103, 0xca0, 14), ++ MTK_PIN_IES_SMT_SPEC(104, 104, 0xc80, 14), ++ MTK_PIN_IES_SMT_SPEC(105, 105, 0xc90, 14), ++ MTK_PIN_IES_SMT_SPEC(106, 107, 0x91, 4), ++ MTK_PIN_IES_SMT_SPEC(108, 112, 0x910, 1), ++ MTK_PIN_IES_SMT_SPEC(113, 116, 0x910, 2), ++ MTK_PIN_IES_SMT_SPEC(117, 118, 0x910, 5), ++ MTK_PIN_IES_SMT_SPEC(119, 124, 0x910, 6), ++ MTK_PIN_IES_SMT_SPEC(125, 126, 0x910, 7), ++ MTK_PIN_IES_SMT_SPEC(127, 127, 0x910, 0), ++ MTK_PIN_IES_SMT_SPEC(128, 128, 0x920, 8), ++ MTK_PIN_IES_SMT_SPEC(129, 130, 0x920, 9), ++ MTK_PIN_IES_SMT_SPEC(131, 132, 0x920, 8), ++ MTK_PIN_IES_SMT_SPEC(133, 134, 0x910, 8) ++}; ++ ++static int mt7623_ies_smt_set(struct regmap *regmap, unsigned int pin, ++ unsigned char align, int value, enum pin_config_param arg) ++{ ++ if (arg == PIN_CONFIG_INPUT_ENABLE) ++ return mtk_pconf_spec_set_ies_smt_range(regmap, mt7623_ies_set, ++ ARRAY_SIZE(mt7623_ies_set), pin, align, value); ++ else if (arg == PIN_CONFIG_INPUT_SCHMITT_ENABLE) ++ return mtk_pconf_spec_set_ies_smt_range(regmap, mt7623_smt_set, ++ ARRAY_SIZE(mt7623_smt_set), pin, align, value); ++ return -EINVAL; ++} ++*/ ++static const struct mtk_drv_group_desc mt7623_drv_grp[] = { ++ /* 0E4E8SR 4/8/12/16 */ ++ MTK_DRV_GRP(4, 16, 1, 2, 4), ++ /* 0E2E4SR 2/4/6/8 */ ++ MTK_DRV_GRP(2, 8, 1, 2, 2), ++ /* E8E4E2 2/4/6/8/10/12/14/16 */ ++ MTK_DRV_GRP(2, 16, 0, 2, 2) ++}; ++ ++/*static const struct mtk_pin_drv_grp mt7623_pin_drv[] = { ++ MTK_PIN_DRV_GRP(0, DRV_BASE+0x20, 12, 0), ++ MTK_PIN_DRV_GRP(1, DRV_BASE+0x20, 12, 0), ++ MTK_PIN_DRV_GRP(2, DRV_BASE+0x20, 12, 0), ++ MTK_PIN_DRV_GRP(3, DRV_BASE+0x20, 12, 0), ++ MTK_PIN_DRV_GRP(4, DRV_BASE+0x20, 12, 0), ++ MTK_PIN_DRV_GRP(5, DRV_BASE+0x30, 0, 0), ++ MTK_PIN_DRV_GRP(6, DRV_BASE+0x30, 0, 0), ++ MTK_PIN_DRV_GRP(7, DRV_BASE+0x30, 0, 0), ++ MTK_PIN_DRV_GRP(8, DRV_BASE+0x30, 0, 0), ++ MTK_PIN_DRV_GRP(9, DRV_BASE+0x30, 0, 0), ++ MTK_PIN_DRV_GRP(10, DRV_BASE+0x30, 4, 1), ++ MTK_PIN_DRV_GRP(11, DRV_BASE+0x30, 4, 1), ++ MTK_PIN_DRV_GRP(12, DRV_BASE+0x30, 4, 1), ++ MTK_PIN_DRV_GRP(13, DRV_BASE+0x30, 4, 1), ++ MTK_PIN_DRV_GRP(14, DRV_BASE+0x40, 8, 1), ++ MTK_PIN_DRV_GRP(15, DRV_BASE+0x40, 8, 1), ++ MTK_PIN_DRV_GRP(16, DRV_BASE, 8, 1), ++ MTK_PIN_DRV_GRP(17, 0xce0, 8, 2), ++ MTK_PIN_DRV_GRP(22, 0xce0, 8, 2), ++ MTK_PIN_DRV_GRP(23, 0xce0, 8, 2), ++ MTK_PIN_DRV_GRP(24, 0xce0, 8, 2), ++ MTK_PIN_DRV_GRP(25, 0xce0, 8, 2), ++ MTK_PIN_DRV_GRP(26, 0xcc0, 8, 2), ++ MTK_PIN_DRV_GRP(27, 0xcd0, 8, 2), ++ MTK_PIN_DRV_GRP(28, 0xd70, 8, 2), ++ MTK_PIN_DRV_GRP(29, DRV_BASE+0x80, 12, 1), ++ MTK_PIN_DRV_GRP(30, DRV_BASE+0x80, 12, 1), ++ MTK_PIN_DRV_GRP(31, DRV_BASE+0x80, 12, 1), ++ MTK_PIN_DRV_GRP(32, DRV_BASE+0x80, 12, 1), ++ MTK_PIN_DRV_GRP(33, DRV_BASE+0x10, 12, 1), ++ MTK_PIN_DRV_GRP(34, DRV_BASE+0x10, 8, 1), ++ MTK_PIN_DRV_GRP(35, DRV_BASE+0x10, 8, 1), ++ MTK_PIN_DRV_GRP(36, DRV_BASE+0x10, 8, 1), ++ MTK_PIN_DRV_GRP(37, DRV_BASE+0x10, 4, 1), ++ MTK_PIN_DRV_GRP(38, DRV_BASE+0x10, 4, 1), ++ MTK_PIN_DRV_GRP(39, DRV_BASE+0x20, 0, 0), ++ MTK_PIN_DRV_GRP(40, DRV_BASE+0x20, 8, 0), ++ MTK_PIN_DRV_GRP(41, DRV_BASE+0x20, 8, 0), ++ MTK_PIN_DRV_GRP(42, DRV_BASE+0x50, 8, 1), ++ MTK_PIN_DRV_GRP(57, 0xc20, 8, 2), ++ MTK_PIN_DRV_GRP(58, 0xc20, 8, 2), ++ MTK_PIN_DRV_GRP(59, 0xc20, 8, 2), ++ MTK_PIN_DRV_GRP(60, 0xc20, 8, 2), ++ MTK_PIN_DRV_GRP(61, 0xc20, 8, 2), ++ MTK_PIN_DRV_GRP(62, 0xc20, 8, 2), ++ MTK_PIN_DRV_GRP(63, 0xc20, 8, 2), ++ MTK_PIN_DRV_GRP(64, 0xc20, 8, 2), ++ MTK_PIN_DRV_GRP(65, 0xc00, 8, 2), ++ MTK_PIN_DRV_GRP(66, 0xc10, 8, 2), ++ MTK_PIN_DRV_GRP(67, 0xd10, 8, 2), ++ MTK_PIN_DRV_GRP(68, 0xd00, 8, 2), ++ MTK_PIN_DRV_GRP(69, DRV_BASE+0x80, 0, 1), ++ MTK_PIN_DRV_GRP(70, DRV_BASE+0x80, 0, 1), ++ MTK_PIN_DRV_GRP(71, DRV_BASE+0x80, 0, 1), ++ MTK_PIN_DRV_GRP(72, DRV_BASE+0x80, 0, 1), ++ MTK_PIN_DRV_GRP(73, 0xc60, 8, 2), ++ MTK_PIN_DRV_GRP(74, 0xc60, 8, 2), ++ MTK_PIN_DRV_GRP(75, 0xc60, 8, 2), ++ MTK_PIN_DRV_GRP(76, 0xc60, 8, 2), ++ MTK_PIN_DRV_GRP(77, 0xc40, 8, 2), ++ MTK_PIN_DRV_GRP(78, 0xc50, 8, 2), ++ MTK_PIN_DRV_GRP(79, DRV_BASE+0x70, 12, 1), ++ MTK_PIN_DRV_GRP(80, DRV_BASE+0x70, 12, 1), ++ MTK_PIN_DRV_GRP(81, DRV_BASE+0x70, 12, 1), ++ MTK_PIN_DRV_GRP(82, DRV_BASE+0x70, 12, 1), ++ MTK_PIN_DRV_GRP(83, DRV_BASE, 4, 1), ++ MTK_PIN_DRV_GRP(84, DRV_BASE, 0, 1), ++ MTK_PIN_DRV_GRP(85, DRV_BASE, 0, 1), ++ MTK_PIN_DRV_GRP(85, DRV_BASE+0x60, 8, 1), ++ MTK_PIN_DRV_GRP(86, DRV_BASE+0x60, 8, 1), ++ MTK_PIN_DRV_GRP(87, DRV_BASE+0x60, 8, 1), ++ MTK_PIN_DRV_GRP(88, DRV_BASE+0x60, 8, 1), ++ MTK_PIN_DRV_GRP(89, DRV_BASE+0x60, 8, 1), ++ MTK_PIN_DRV_GRP(90, DRV_BASE+0x60, 8, 1), ++ MTK_PIN_DRV_GRP(91, DRV_BASE+0x60, 8, 1), ++ MTK_PIN_DRV_GRP(92, DRV_BASE+0x60, 4, 0), ++ MTK_PIN_DRV_GRP(93, DRV_BASE+0x60, 0, 0), ++ MTK_PIN_DRV_GRP(94, DRV_BASE+0x60, 0, 0), ++ MTK_PIN_DRV_GRP(95, DRV_BASE+0x60, 0, 0), ++ MTK_PIN_DRV_GRP(96, DRV_BASE+0x80, 8, 1), ++ MTK_PIN_DRV_GRP(97, DRV_BASE+0x80, 8, 1), ++ MTK_PIN_DRV_GRP(98, DRV_BASE+0x80, 8, 1), ++ MTK_PIN_DRV_GRP(99, DRV_BASE+0x80, 8, 1), ++ MTK_PIN_DRV_GRP(100, 0xca0, 8, 2), ++ MTK_PIN_DRV_GRP(101, 0xca0, 8, 2), ++ MTK_PIN_DRV_GRP(102, 0xca0, 8, 2), ++ MTK_PIN_DRV_GRP(103, 0xca0, 8, 2), ++ MTK_PIN_DRV_GRP(104, 0xc80, 8, 2), ++ MTK_PIN_DRV_GRP(105, 0xc90, 8, 2), ++ MTK_PIN_DRV_GRP(108, DRV_BASE+0x50, 0, 1), ++ MTK_PIN_DRV_GRP(109, DRV_BASE+0x50, 0, 1), ++ MTK_PIN_DRV_GRP(110, DRV_BASE+0x50, 0, 1), ++ MTK_PIN_DRV_GRP(111, DRV_BASE+0x50, 0, 1), ++ MTK_PIN_DRV_GRP(112, DRV_BASE+0x50, 0, 1), ++ MTK_PIN_DRV_GRP(113, DRV_BASE+0x80, 4, 1), ++ MTK_PIN_DRV_GRP(114, DRV_BASE+0x80, 4, 1), ++ MTK_PIN_DRV_GRP(115, DRV_BASE+0x80, 4, 1), ++ MTK_PIN_DRV_GRP(116, DRV_BASE+0x80, 4, 1), ++ MTK_PIN_DRV_GRP(117, DRV_BASE+0x90, 0, 1), ++ MTK_PIN_DRV_GRP(118, DRV_BASE+0x90, 0, 1), ++ MTK_PIN_DRV_GRP(119, DRV_BASE+0x50, 4, 1), ++ MTK_PIN_DRV_GRP(120, DRV_BASE+0x50, 4, 1), ++ MTK_PIN_DRV_GRP(121, DRV_BASE+0x50, 4, 1), ++ MTK_PIN_DRV_GRP(122, DRV_BASE+0x50, 4, 1), ++ MTK_PIN_DRV_GRP(123, DRV_BASE+0x50, 4, 1), ++ MTK_PIN_DRV_GRP(124, DRV_BASE+0x50, 4, 1), ++ MTK_PIN_DRV_GRP(125, DRV_BASE+0x30, 12, 1), ++ MTK_PIN_DRV_GRP(126, DRV_BASE+0x30, 12, 1), ++ MTK_PIN_DRV_GRP(127, DRV_BASE+0x50, 8, 1), ++ MTK_PIN_DRV_GRP(128, DRV_BASE+0x40, 0, 1), ++ MTK_PIN_DRV_GRP(129, DRV_BASE+0x40, 0, 1), ++ MTK_PIN_DRV_GRP(130, DRV_BASE+0x40, 0, 1), ++ MTK_PIN_DRV_GRP(131, DRV_BASE+0x40, 0, 1), ++ MTK_PIN_DRV_GRP(132, DRV_BASE+0x40, 0, 1) ++}; ++*/ ++static const struct mtk_pinctrl_devdata mt7623_pinctrl_data = { ++ .pins = mtk_pins_mt7623, ++ .npins = ARRAY_SIZE(mtk_pins_mt7623), ++ .grp_desc = mt7623_drv_grp, ++ .n_grp_cls = ARRAY_SIZE(mt7623_drv_grp), ++// .pin_drv_grp = mt7623_pin_drv, ++// .n_pin_drv_grps = ARRAY_SIZE(mt7623_pin_drv), ++ .spec_pull_set = mt7623_spec_pull_set, ++ //.spec_ies_smt_set = mt7623_ies_smt_set, ++ .dir_offset = 0x0000, ++ .pullen_offset = 0x0150, ++ .pullsel_offset = 0x0280, ++ .dout_offset = 0x0550, ++ .din_offset = 0x0630, ++ .pinmux_offset = 0x0760, ++ .port_shf = 4, ++ .port_mask = 0xf, ++ .port_align = 4, ++ .eint_offsets = { ++ .name = "mt7623_eint", ++ .stat = 0x000, ++ .ack = 0x040, ++ .mask = 0x080, ++ .mask_set = 0x0c0, ++ .mask_clr = 0x100, ++ .sens = 0x140, ++ .sens_set = 0x180, ++ .sens_clr = 0x1c0, ++ .soft = 0x200, ++ .soft_set = 0x240, ++ .soft_clr = 0x280, ++ .pol = 0x300, ++ .pol_set = 0x340, ++ .pol_clr = 0x380, ++ .dom_en = 0x400, ++ .dbnc_ctrl = 0x500, ++ .dbnc_set = 0x600, ++ .dbnc_clr = 0x700, ++ .port_mask = 7, ++ .ports = 6, ++ }, ++ .ap_num = 224, ++ .db_cnt = 16, ++}; ++ ++static int mt7623_pinctrl_probe(struct platform_device *pdev) ++{ ++ return mtk_pctrl_init(pdev, &mt7623_pinctrl_data, NULL); ++} ++ ++static const struct of_device_id mt7623_pctrl_match[] = { ++ { ++ .compatible = "mediatek,mt7623-pinctrl", ++ }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, mt7623_pctrl_match); ++ ++static struct platform_driver mtk_pinctrl_driver = { ++ .probe = mt7623_pinctrl_probe, ++ .driver = { ++ .name = "mediatek-mt7623-pinctrl", ++ .of_match_table = mt7623_pctrl_match, ++ }, ++}; ++ ++static int __init mtk_pinctrl_init(void) ++{ ++ return platform_driver_register(&mtk_pinctrl_driver); ++} ++ ++module_init(mtk_pinctrl_init); ++ ++MODULE_LICENSE("GPL v2"); ++MODULE_DESCRIPTION("MediaTek Pinctrl Driver"); ++MODULE_AUTHOR("John Crispin <blogic@openwrt.org>"); +diff --git a/drivers/pinctrl/mediatek/pinctrl-mtk-mt7623.h b/drivers/pinctrl/mediatek/pinctrl-mtk-mt7623.h +new file mode 100644 +index 0000000..4b65668 +--- /dev/null ++++ b/drivers/pinctrl/mediatek/pinctrl-mtk-mt7623.h +@@ -0,0 +1,1926 @@ ++#ifndef __PINCTRL_MTK_MT7623_H ++#define __PINCTRL_MTK_MT7623_H ++ ++#include <linux/pinctrl/pinctrl.h> ++#include "pinctrl-mtk-common.h" ++ ++static const struct mtk_desc_pin mtk_pins_mt7623[] = { ++ MTK_PIN( ++ PINCTRL_PIN(0, "PWRAP_SPI0_MI"), ++ "F11", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO0"), ++ MTK_FUNCTION(1, "PWRAP_SPIDO"), ++ MTK_FUNCTION(2, "PWRAP_SPIDI") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(1, "PWRAP_SPI0_MO"), ++ "D10", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO1"), ++ MTK_FUNCTION(1, "PWRAP_SPIDI"), ++ MTK_FUNCTION(2, "PWRAP_SPIDO") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(2, "PWRAP_INT"), ++ "E11", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO2"), ++ MTK_FUNCTION(1, "PWRAP_INT") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(3, "PWRAP_SPI0_CK"), ++ "H12", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO3"), ++ MTK_FUNCTION(1, "PWRAP_SPICK_I") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(4, "PWRAP_SPI0_CSN"), ++ "E12", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO4"), ++ MTK_FUNCTION(1, "PWRAP_SPICS_B_I") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(5, "PWRAP_SPI0_CK2"), ++ "H11", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO5"), ++ MTK_FUNCTION(1, "PWRAP_SPICK2_I") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(6, "PWRAP_SPI0_CSN2"), ++ "G11", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO6"), ++ MTK_FUNCTION(1, "PWRAP_SPICS2_B_I") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(7, "SPI1_CSN"), ++ "G19", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO7"), ++ MTK_FUNCTION(1, "SPI1_CS") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(8, "SPI1_MI"), ++ "F19", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO8"), ++ MTK_FUNCTION(1, "SPI1_MI"), ++ MTK_FUNCTION(2, "SPI1_MO") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(9, "SPI1_MO"), ++ "G20", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO9"), ++ MTK_FUNCTION(1, "SPI1_MO"), ++ MTK_FUNCTION(2, "SPI1_MI") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(10, "RTC32K_CK"), ++ "A13", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO10"), ++ MTK_FUNCTION(1, "RTC32K_CK") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(11, "WATCHDOG"), ++ "D14", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO11"), ++ MTK_FUNCTION(1, "WATCHDOG") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(12, "SRCLKENA"), ++ "C13", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO12"), ++ MTK_FUNCTION(1, "SRCLKENA") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(13, "SRCLKENAI"), ++ "B13", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO13"), ++ MTK_FUNCTION(1, "SRCLKENAI") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(14, "GPIO14"), ++ "E18", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO14"), ++ MTK_FUNCTION(1, "URXD2"), ++ MTK_FUNCTION(2, "UTXD2") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(15, "GPIO15"), ++ "E17", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO15"), ++ MTK_FUNCTION(1, "UTXD2"), ++ MTK_FUNCTION(2, "URXD2") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(16, "GPIO16"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO16") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(17, "GPIO17"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO17") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(18, "PCM_CLK"), ++ "C19", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO18"), ++ MTK_FUNCTION(1, "PCM_CLK0"), ++ MTK_FUNCTION(6, "AP_PCM_CLKO") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(19, "PCM_SYNC"), ++ "D19", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO19"), ++ MTK_FUNCTION(1, "PCM_SYNC"), ++ MTK_FUNCTION(6, "AP_PCM_SYNC") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(20, "PCM_RX"), ++ "D18", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO20"), ++ MTK_FUNCTION(1, "PCM_RX"), ++ MTK_FUNCTION(4, "PCM_TX"), ++ MTK_FUNCTION(6, "AP_PCM_RX") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(21, "PCM_TX"), ++ "C18", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO21"), ++ MTK_FUNCTION(1, "PCM_TX"), ++ MTK_FUNCTION(4, "PCM_RX"), ++ MTK_FUNCTION(6, "AP_PCM_TX") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(22, "EINT0"), ++ "H15", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO22"), ++ MTK_FUNCTION(1, "UCTS0"), ++ MTK_FUNCTION(2, "PCIE0_PERST_N") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(23, "EINT1"), ++ "J16", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO23"), ++ MTK_FUNCTION(1, "URTS0"), ++ MTK_FUNCTION(2, "PCIE1_PERST_N") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(24, "EINT2"), ++ "H16", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO24"), ++ MTK_FUNCTION(1, "UCTS1"), ++ MTK_FUNCTION(2, "PCIE2_PERST_N") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(25, "EINT3"), ++ "K15", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO25"), ++ MTK_FUNCTION(1, "URTS1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(26, "EINT4"), ++ "G15", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO26"), ++ MTK_FUNCTION(1, "UCTS3"), ++ MTK_FUNCTION(6, "PCIE2_WAKE_N") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(27, "EINT5"), ++ "F15", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO27"), ++ MTK_FUNCTION(1, "URTS3"), ++ MTK_FUNCTION(6, "PCIE1_WAKE_N") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(28, "EINT6"), ++ "J15", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO28"), ++ MTK_FUNCTION(1, "DRV_VBUS"), ++ MTK_FUNCTION(6, "PCIE0_WAKE_N") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(29, "EINT7"), ++ "E15", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO29"), ++ MTK_FUNCTION(1, "IDDIG"), ++ MTK_FUNCTION(2, "MSDC1_WP"), ++ MTK_FUNCTION(6, "PCIE2_PERST_N") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(30, "GPIO30"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO30") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(31, "GPIO31"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO31") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(32, "GPIO32"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO32") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(33, "I2S1_DATA"), ++ "Y18", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO33"), ++ MTK_FUNCTION(1, "I2S1_DATA"), ++ MTK_FUNCTION(3, "PCM_TX"), ++ MTK_FUNCTION(6, "AP_PCM_TX") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(34, "I2S1_DATA_IN"), ++ "Y17", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO34"), ++ MTK_FUNCTION(1, "I2S1_DATA_IN"), ++ MTK_FUNCTION(3, "PCM_RX"), ++ MTK_FUNCTION(6, "AP_PCM_RX") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(35, "I2S1_BCK"), ++ "V17", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO35"), ++ MTK_FUNCTION(1, "I2S1_BCK"), ++ MTK_FUNCTION(3, "PCM_CLK0"), ++ MTK_FUNCTION(6, "AP_PCM_CLKO") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(36, "I2S1_LRCK"), ++ "W17", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO36"), ++ MTK_FUNCTION(1, "I2S1_LRCK"), ++ MTK_FUNCTION(3, "PCM_SYNC"), ++ MTK_FUNCTION(6, "AP_PCM_SYNC") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(37, "I2S1_MCLK"), ++ "AA18", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO37"), ++ MTK_FUNCTION(1, "I2S1_MCLK") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(38, "GPIO38"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO38") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(39, "JTMS"), ++ "G21", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO39"), ++ MTK_FUNCTION(1, "JTMS") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(40, "JTCK"), ++ "J20", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO40"), ++ MTK_FUNCTION(1, "JTCK") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(41, "JTDI"), ++ "H22", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO41"), ++ MTK_FUNCTION(1, "JTDI") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(42, "JTDO"), ++ "H21", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO42"), ++ MTK_FUNCTION(1, "JTDO") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(43, "NCLE"), ++ "C7", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO43"), ++ MTK_FUNCTION(1, "NCLE"), ++ MTK_FUNCTION(2, "EXT_XCS2") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(44, "NCEB1"), ++ "C6", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO44"), ++ MTK_FUNCTION(1, "NCEB1"), ++ MTK_FUNCTION(2, "IDDIG") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(45, "NCEB0"), ++ "D7", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO45"), ++ MTK_FUNCTION(1, "NCEB0"), ++ MTK_FUNCTION(2, "DRV_VBUS") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(46, "IR"), ++ "D15", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO46"), ++ MTK_FUNCTION(1, "IR") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(47, "NREB"), ++ "A6", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO47"), ++ MTK_FUNCTION(1, "NREB") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(48, "NRNB"), ++ "B6", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO48"), ++ MTK_FUNCTION(1, "NRNB") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(49, "I2S0_DATA"), ++ "AB18", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO49"), ++ MTK_FUNCTION(1, "I2S0_DATA"), ++ MTK_FUNCTION(3, "PCM_TX"), ++ MTK_FUNCTION(6, "AP_I2S_DO") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(50, "GPIO50"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO50") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(51, "GPIO51"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO51") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(52, "GPIO52"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO52") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(53, "SPI0_CSN"), ++ "E7", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO53"), ++ MTK_FUNCTION(1, "SPI0_CS"), ++ MTK_FUNCTION(5, "PWM1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(54, "SPI0_CK"), ++ "F7", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO54"), ++ MTK_FUNCTION(1, "SPI0_CK") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(55, "SPI0_MI"), ++ "E6", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO55"), ++ MTK_FUNCTION(1, "SPI0_MI"), ++ MTK_FUNCTION(2, "SPI0_MO"), ++ MTK_FUNCTION(3, "MSDC1_WP"), ++ MTK_FUNCTION(5, "PWM2") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(56, "SPI0_MO"), ++ "G7", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO56"), ++ MTK_FUNCTION(1, "SPI0_MO"), ++ MTK_FUNCTION(2, "SPI0_MI") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(57, "GPIO57"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO57") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(58, "GPIO58"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO58") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(59, "GPIO59"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO59") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(60, "WB_RSTB"), ++ "Y21", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO60"), ++ MTK_FUNCTION(1, "WB_RSTB") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(61, "GPIO61"), ++ "AA21", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO61"), ++ MTK_FUNCTION(1, "TEST_FD") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(62, "GPIO62"), ++ "AB22", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO62"), ++ MTK_FUNCTION(1, "TEST_FC") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(63, "WB_SCLK"), ++ "AC23", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO63"), ++ MTK_FUNCTION(1, "WB_SCLK") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(64, "WB_SDATA"), ++ "AB21", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO64"), ++ MTK_FUNCTION(1, "WB_SDATA") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(65, "WB_SEN"), ++ "AB24", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO65"), ++ MTK_FUNCTION(1, "WB_SEN") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(66, "WB_CRTL0"), ++ "AB20", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO66"), ++ MTK_FUNCTION(1, "WB_CRTL0") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(67, "WB_CRTL1"), ++ "AC20", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO67"), ++ MTK_FUNCTION(1, "WB_CRTL1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(68, "WB_CRTL2"), ++ "AB19", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO68"), ++ MTK_FUNCTION(1, "WB_CRTL2") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(69, "WB_CRTL3"), ++ "AC19", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO69"), ++ MTK_FUNCTION(1, "WB_CRTL3") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(70, "WB_CRTL4"), ++ "AD19", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO70"), ++ MTK_FUNCTION(1, "WB_CRTL4") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(71, "WB_CRTL5"), ++ "AE19", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO71"), ++ MTK_FUNCTION(1, "WB_CRTL5") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(72, "I2S0_DATA_IN"), ++ "AA20", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO72"), ++ MTK_FUNCTION(1, "I2S0_DATA_IN"), ++ MTK_FUNCTION(3, "PCM_RX"), ++ MTK_FUNCTION(4, "PWM0"), ++ MTK_FUNCTION(5, "DISP_PWM"), ++ MTK_FUNCTION(6, "AP_I2S_DI") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(73, "I2S0_LRCK"), ++ "Y20", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO73"), ++ MTK_FUNCTION(1, "I2S0_LRCK"), ++ MTK_FUNCTION(3, "PCM_SYNC"), ++ MTK_FUNCTION(6, "AP_I2S_LRCK") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(74, "I2S0_BCK"), ++ "Y19", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO74"), ++ MTK_FUNCTION(1, "I2S0_BCK"), ++ MTK_FUNCTION(3, "PCM_CLK0"), ++ MTK_FUNCTION(6, "AP_I2S_BCK") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(75, "SDA0"), ++ "K19", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO75"), ++ MTK_FUNCTION(1, "SDA0") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(76, "SCL0"), ++ "K20", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO76"), ++ MTK_FUNCTION(1, "SCL0") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(77, "GPIO77"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO77") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(78, "GPIO78"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO78") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(79, "GPIO79"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO79") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(80, "GPIO80"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO80") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(81, "GPIO81"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO81") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(82, "GPIO82"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO82") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(83, "LCM_RST"), ++ "V16", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO83"), ++ MTK_FUNCTION(1, "LCM_RST") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(84, "DSI_TE"), ++ "V14", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO84"), ++ MTK_FUNCTION(1, "DSI_TE") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(85, "GPIO85"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO85") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(86, "GPIO86"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO86") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(87, "GPIO87"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO87") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(88, "GPIO88"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO88") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(89, "GPIO89"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO89") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(90, "GPIO90"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO90") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(91, "GPIO91"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO91") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(92, "GPIO92"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO92") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(93, "GPIO93"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO93") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(94, "GPIO94"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO94") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(95, "MIPI_TCN"), ++ "AB14", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO95"), ++ MTK_FUNCTION(1, "TCN") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(96, "MIPI_TCP"), ++ "AC14", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO96"), ++ MTK_FUNCTION(1, "TCP") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(97, "MIPI_TDN1"), ++ "AE15", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO97"), ++ MTK_FUNCTION(1, "TDN1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(98, "MIPI_TDP1"), ++ "AD15", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO98"), ++ MTK_FUNCTION(1, "TDP1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(99, "MIPI_TDN0"), ++ "AB15", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO99"), ++ MTK_FUNCTION(1, "TDN0") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(100, "MIPI_TDP0"), ++ "AC15", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO100"), ++ MTK_FUNCTION(1, "TDP0") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(101, "GPIO101"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO101") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(102, "GPIO102"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO102") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(103, "GPIO103"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO103") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(104, "GPIO104"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO104") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(105, "MSDC1_CMD"), ++ "AD2", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO105"), ++ MTK_FUNCTION(1, "MSDC1_CMD"), ++ MTK_FUNCTION(3, "SDA1"), ++ MTK_FUNCTION(6, "I2SOUT_BCK") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(106, "MSDC1_CLK"), ++ "AD3", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO106"), ++ MTK_FUNCTION(1, "MSDC1_CLK"), ++ MTK_FUNCTION(3, "SCL1"), ++ MTK_FUNCTION(6, "I2SOUT_LRCK") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(107, "MSDC1_DAT0"), ++ "AE2", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO107"), ++ MTK_FUNCTION(1, "MSDC1_DAT0"), ++ MTK_FUNCTION(5, "UTXD0"), ++ MTK_FUNCTION(6, "I2SOUT_DATA_OUT") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(108, "MSDC1_DAT1"), ++ "AC1", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO108"), ++ MTK_FUNCTION(1, "MSDC1_DAT1"), ++ MTK_FUNCTION(3, "PWM0"), ++ MTK_FUNCTION(5, "URXD0"), ++ MTK_FUNCTION(6, "PWM1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(109, "MSDC1_DAT2"), ++ "AC3", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO109"), ++ MTK_FUNCTION(1, "MSDC1_DAT2"), ++ MTK_FUNCTION(3, "SDA2"), ++ MTK_FUNCTION(5, "UTXD1"), ++ MTK_FUNCTION(6, "PWM2") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(110, "MSDC1_DAT3"), ++ "AC4", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO110"), ++ MTK_FUNCTION(1, "MSDC1_DAT3"), ++ MTK_FUNCTION(3, "SCL2"), ++ MTK_FUNCTION(5, "URXD1"), ++ MTK_FUNCTION(6, "PWM3") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(111, "MSDC0_DAT7"), ++ "A2", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO111"), ++ MTK_FUNCTION(1, "MSDC0_DAT7"), ++ MTK_FUNCTION(4, "NLD7") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(112, "MSDC0_DAT6"), ++ "B3", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO112"), ++ MTK_FUNCTION(1, "MSDC0_DAT6"), ++ MTK_FUNCTION(4, "NLD6") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(113, "MSDC0_DAT5"), ++ "C4", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO113"), ++ MTK_FUNCTION(1, "MSDC0_DAT5"), ++ MTK_FUNCTION(4, "NLD5") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(114, "MSDC0_DAT4"), ++ "A4", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO114"), ++ MTK_FUNCTION(1, "MSDC0_DAT4"), ++ MTK_FUNCTION(4, "NLD4") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(115, "MSDC0_RSTB"), ++ "C5", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO115"), ++ MTK_FUNCTION(1, "MSDC0_RSTB"), ++ MTK_FUNCTION(4, "NLD8") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(116, "MSDC0_CMD"), ++ "D5", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO116"), ++ MTK_FUNCTION(1, "MSDC0_CMD"), ++ MTK_FUNCTION(4, "NALE") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(117, "MSDC0_CLK"), ++ "B1", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO117"), ++ MTK_FUNCTION(1, "MSDC0_CLK"), ++ MTK_FUNCTION(4, "NWEB") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(118, "MSDC0_DAT3"), ++ "D6", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO118"), ++ MTK_FUNCTION(1, "MSDC0_DAT3"), ++ MTK_FUNCTION(4, "NLD3") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(119, "MSDC0_DAT2"), ++ "B2", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO119"), ++ MTK_FUNCTION(1, "MSDC0_DAT2"), ++ MTK_FUNCTION(4, "NLD2") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(120, "MSDC0_DAT1"), ++ "A3", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO120"), ++ MTK_FUNCTION(1, "MSDC0_DAT1"), ++ MTK_FUNCTION(4, "NLD1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(121, "MSDC0_DAT0"), ++ "B4", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO121"), ++ MTK_FUNCTION(1, "MSDC0_DAT0"), ++ MTK_FUNCTION(4, "NLD0"), ++ MTK_FUNCTION(5, "WATCHDOG") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(122, "GPIO122"), ++ "H17", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO122"), ++ MTK_FUNCTION(1, "TEST"), ++ MTK_FUNCTION(4, "SDA2"), ++ MTK_FUNCTION(5, "URXD0") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(123, "GPIO123"), ++ "F17", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO123"), ++ MTK_FUNCTION(1, "TEST"), ++ MTK_FUNCTION(4, "SCL2"), ++ MTK_FUNCTION(5, "UTXD0") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(124, "GPIO124"), ++ "H18", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO124"), ++ MTK_FUNCTION(1, "TEST"), ++ MTK_FUNCTION(4, "SDA1"), ++ MTK_FUNCTION(5, "PWM3") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(125, "GPIO125"), ++ "G17", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO125"), ++ MTK_FUNCTION(1, "TEST"), ++ MTK_FUNCTION(4, "SCL1"), ++ MTK_FUNCTION(5, "PWM4") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(126, "I2S0_MCLK"), ++ "AA19", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO126"), ++ MTK_FUNCTION(1, "I2S0_MCLK"), ++ MTK_FUNCTION(6, "AP_I2S_MCLK") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(127, "GPIO127"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO127") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(128, "GPIO128"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO128") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(129, "GPIO129"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO129") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(130, "GPIO130"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO130") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(131, "GPIO131"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO131") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(132, "GPIO132"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO132") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(133, "GPIO133"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO133") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(134, "GPIO134"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO134") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(135, "GPIO135"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO135") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(136, "GPIO136"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO136") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(137, "GPIO137"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO137") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(138, "GPIO138"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO138") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(139, "GPIO139"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO139") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(140, "GPIO140"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO140") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(141, "GPIO141"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO141") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(142, "GPIO142"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO142") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(143, "GPIO143"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO143") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(144, "GPIO144"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO144") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(145, "GPIO145"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO145") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(146, "GPIO146"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO146") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(147, "GPIO147"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO147") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(148, "GPIO148"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO148") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(149, "GPIO149"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO149") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(150, "GPIO150"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO150") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(151, "GPIO151"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO151") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(152, "GPIO152"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO152") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(153, "GPIO153"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO153") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(154, "GPIO154"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO154") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(155, "GPIO155"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO155") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(156, "GPIO156"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO156") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(157, "GPIO157"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO157") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(158, "GPIO158"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO158") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(159, "GPIO159"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO159") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(160, "GPIO160"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO160") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(161, "GPIO161"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO161") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(162, "GPIO162"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO162") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(163, "GPIO163"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO163") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(164, "GPIO164"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO164") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(165, "GPIO165"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO165") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(166, "GPIO166"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO166") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(167, "GPIO167"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO167") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(168, "GPIO168"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO168") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(169, "GPIO169"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO169") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(170, "GPIO170"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO170") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(171, "GPIO171"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO171") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(172, "GPIO172"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO172") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(173, "GPIO173"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO173") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(174, "GPIO174"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO174") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(175, "GPIO175"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO175") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(176, "GPIO176"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO176") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(177, "GPIO177"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO177") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(178, "GPIO178"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO178") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(179, "GPIO179"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO179") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(180, "GPIO180"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO180") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(181, "GPIO181"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO181") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(182, "GPIO182"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO182") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(183, "GPIO183"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO183") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(184, "GPIO184"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO184") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(185, "GPIO185"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO185") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(186, "GPIO186"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO186") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(187, "GPIO187"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO187") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(188, "GPIO188"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO188") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(189, "GPIO189"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO189") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(190, "GPIO190"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO190") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(191, "GPIO191"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO191") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(192, "GPIO192"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO192") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(193, "GPIO193"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO193") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(194, "GPIO194"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO194") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(195, "GPIO195"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO195") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(196, "GPIO196"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO196") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(197, "GPIO197"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO197") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(198, "GPIO198"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO198") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(199, "SPI1_CK"), ++ "E19", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO199"), ++ MTK_FUNCTION(1, "SPI1_CK") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(200, "URXD2"), ++ "K18", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO200"), ++ MTK_FUNCTION(6, "URXD2") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(201, "UTXD2"), ++ "L18", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO201"), ++ MTK_FUNCTION(6, "UTXD2") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(202, "GPIO202"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO202") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(203, "PWM0"), ++ "AA16", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO203"), ++ MTK_FUNCTION(1, "PWM0"), ++ MTK_FUNCTION(2, "DISP_PWM") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(204, "PWM1"), ++ "Y16", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO204"), ++ MTK_FUNCTION(1, "PWM1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(205, "PWM2"), ++ "AA15", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO205"), ++ MTK_FUNCTION(1, "PWM2") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(206, "PWM3"), ++ "AA17", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO206"), ++ MTK_FUNCTION(1, "PWM3") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(207, "PWM4"), ++ "Y15", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO207"), ++ MTK_FUNCTION(1, "PWM4") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(208, "AUD_EXT_CK1"), ++ "W14", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO208"), ++ MTK_FUNCTION(1, "AUD_EXT_CK1"), ++ MTK_FUNCTION(2, "PWM0"), ++ MTK_FUNCTION(3, "PCIE0_PERST_N"), ++ MTK_FUNCTION(5, "DISP_PWM") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(209, "AUD_EXT_CK2"), ++ "V15", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO209"), ++ MTK_FUNCTION(1, "AUD_EXT_CK2"), ++ MTK_FUNCTION(2, "MSDC1_WP"), ++ MTK_FUNCTION(3, "PCIE1_PERST_N"), ++ MTK_FUNCTION(5, "PWM1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(210, "GPIO210"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO210") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(211, "GPIO211"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO211") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(212, "GPIO212"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO212") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(213, "GPIO213"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO213") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(214, "GPIO214"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO214") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(215, "GPIO215"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO215") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(216, "GPIO216"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO216") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(217, "GPIO217"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO217") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(218, "GPIO218"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO218") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(219, "GPIO219"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO219") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(220, "GPIO220"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO220") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(221, "GPIO221"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO221") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(222, "GPIO222"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO222") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(223, "GPIO223"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO223") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(224, "GPIO224"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO224") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(225, "GPIO225"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO225") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(226, "GPIO226"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO226") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(227, "GPIO227"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO227") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(228, "GPIO228"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO228") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(229, "GPIO229"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO229") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(230, "GPIO230"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO230") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(231, "GPIO231"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO231") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(232, "GPIO232"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO232") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(233, "GPIO233"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO233") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(234, "GPIO234"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO234") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(235, "GPIO235"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO235") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(236, "EXT_SDIO3"), ++ "A8", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO236"), ++ MTK_FUNCTION(1, "EXT_SDIO3"), ++ MTK_FUNCTION(2, "IDDIG") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(237, "EXT_SDIO2"), ++ "D8", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO237"), ++ MTK_FUNCTION(1, "EXT_SDIO2"), ++ MTK_FUNCTION(2, "DRV_VBUS") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(238, "EXT_SDIO1"), ++ "D9", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO238"), ++ MTK_FUNCTION(1, "EXT_SDIO1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(239, "EXT_SDIO0"), ++ "B8", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO239"), ++ MTK_FUNCTION(1, "EXT_SDIO0") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(240, "EXT_XCS"), ++ "C9", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO240"), ++ MTK_FUNCTION(1, "EXT_XCS") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(241, "EXT_SCK"), ++ "C8", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO241"), ++ MTK_FUNCTION(1, "EXT_SCK") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(242, "URTS2"), ++ "G18", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO242"), ++ MTK_FUNCTION(1, "URTS2"), ++ MTK_FUNCTION(2, "UTXD3"), ++ MTK_FUNCTION(3, "URXD3"), ++ MTK_FUNCTION(4, "SCL1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(243, "UCTS2"), ++ "H19", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO243"), ++ MTK_FUNCTION(1, "UCTS2"), ++ MTK_FUNCTION(2, "URXD3"), ++ MTK_FUNCTION(3, "UTXD3"), ++ MTK_FUNCTION(4, "SDA1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(244, "GPIO244"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO244") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(245, "GPIO245"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO245") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(246, "GPIO246"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO246") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(247, "GPIO247"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO247") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(248, "GPIO248"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO248") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(249, "GPIO249"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO249") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(250, "GPIO250"), ++ "A15", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO250"), ++ MTK_FUNCTION(1, "TEST_MD7"), ++ MTK_FUNCTION(6, "PCIE0_CLKREQ_N") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(251, "GPIO251"), ++ "B15", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO251"), ++ MTK_FUNCTION(1, "TEST_MD6"), ++ MTK_FUNCTION(6, "PCIE0_WAKE_N") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(252, "GPIO252"), ++ "C16", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO252"), ++ MTK_FUNCTION(1, "TEST_MD5"), ++ MTK_FUNCTION(6, "PCIE1_CLKREQ_N") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(253, "GPIO253"), ++ "D17", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO253"), ++ MTK_FUNCTION(1, "TEST_MD4"), ++ MTK_FUNCTION(6, "PCIE1_WAKE_N") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(254, "GPIO254"), ++ "D16", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO254"), ++ MTK_FUNCTION(1, "TEST_MD3"), ++ MTK_FUNCTION(6, "PCIE2_CLKREQ_N") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(255, "GPIO255"), ++ "C17", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO255"), ++ MTK_FUNCTION(1, "TEST_MD2"), ++ MTK_FUNCTION(6, "PCIE2_WAKE_N") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(256, "GPIO256"), ++ "B17", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO256"), ++ MTK_FUNCTION(1, "TEST_MD1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(257, "GPIO257"), ++ "C15", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO257"), ++ MTK_FUNCTION(1, "TEST_MD0") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(258, "GPIO258"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO258") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(259, "GPIO259"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO259") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(260, "GPIO260"), ++ "N/C", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), MTK_FUNCTION(0, "GPIO260") ++ ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(261, "MSDC1_INS"), ++ "AD1", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO261"), ++ MTK_FUNCTION(1, "MSDC1_INS") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(262, "G2_TXEN"), ++ "A23", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO262"), ++ MTK_FUNCTION(1, "G2_TXEN") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(263, "G2_TXD3"), ++ "N/A", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO263"), ++ MTK_FUNCTION(1, "G2_TXD3") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(264, "G2_TXD2"), ++ "C24", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO264"), ++ MTK_FUNCTION(1, "G2_TXD2") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(265, "G2_TXD1"), ++ "B25", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO265"), ++ MTK_FUNCTION(1, "G2_TXD1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(266, "G2_TXD0"), ++ "A24", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO266"), ++ MTK_FUNCTION(1, "G2_TXD0") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(267, "G2_TXCLK"), ++ "C23", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO267"), ++ MTK_FUNCTION(1, "G2_TXC") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(268, "G2_RXCLK"), ++ "B23", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO268"), ++ MTK_FUNCTION(1, "G2_RXC") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(269, "G2_RXD0"), ++ "D21", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO269"), ++ MTK_FUNCTION(1, "G2_RXD0") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(270, "G2_RXD1"), ++ "B22", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO270"), ++ MTK_FUNCTION(1, "G2_RXD1") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(271, "G2_RXD2"), ++ "A22", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO271"), ++ MTK_FUNCTION(1, "G2_RXD2") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(272, "G2_RXD3"), ++ "C22", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO272"), ++ MTK_FUNCTION(1, "G2_RXD3") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(273, "D2D_ESW_INT"), ++ "N/A", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO273"), ++ MTK_FUNCTION(1, "ESW_INT") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(274, "G2_RXDV"), ++ "C21", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO274"), ++ MTK_FUNCTION(1, "G2_RXDV") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(275, "G2_MDC"), ++ "N/A", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO275"), ++ MTK_FUNCTION(1, "MDC") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(276, "G2_MDIO"), ++ "N/A", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO276"), ++ MTK_FUNCTION(1, "MDIO") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(277, "D2D_ESW_RSTN"), ++ "N/A", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO277"), ++ MTK_FUNCTION(1, "ESW_RST") ++ ), ++ MTK_PIN( ++ PINCTRL_PIN(278, "JTAG_RESET"), ++ "H20", "mt7623", ++ MTK_EINT_FUNCTION(NO_EINT_SUPPORT, NO_EINT_SUPPORT), ++ MTK_FUNCTION(0, "GPIO278"), ++ MTK_FUNCTION(1, "JTAG_RESET") ++ ), ++}; ++ ++#endif /* __PINCTRL_MTK_MT7623_H */ +\ No newline at end of file +diff --git a/include/dt-bindings/pinctrl/mt7623-pinfunc.h b/include/dt-bindings/pinctrl/mt7623-pinfunc.h +new file mode 100644 +index 0000000..826835c +--- /dev/null ++++ b/include/dt-bindings/pinctrl/mt7623-pinfunc.h +@@ -0,0 +1,526 @@ ++#ifndef __DTS_MT7623_PINFUNC_H ++#define __DTS_MT7623_PINFUNC_H ++ ++#include <dt-bindings/pinctrl/mt65xx.h> ++ ++#define MT7623_PIN_0_PWRAP_SPI0_MI_FUNC_GPIO0 (MTK_PIN_NO(0) | 0) ++#define MT7623_PIN_0_PWRAP_SPI0_MI_FUNC_PWRAP_SPIDO (MTK_PIN_NO(0) | 1) ++#define MT7623_PIN_0_PWRAP_SPI0_MI_FUNC_PWRAP_SPIDI (MTK_PIN_NO(0) | 2) ++ ++#define MT7623_PIN_1_PWRAP_SPI0_MO_FUNC_GPIO1 (MTK_PIN_NO(1) | 0) ++#define MT7623_PIN_1_PWRAP_SPI0_MO_FUNC_PWRAP_SPIDI (MTK_PIN_NO(1) | 1) ++#define MT7623_PIN_1_PWRAP_SPI0_MO_FUNC_PWRAP_SPIDO (MTK_PIN_NO(1) | 2) ++ ++#define MT7623_PIN_2_PWRAP_INT_FUNC_GPIO2 (MTK_PIN_NO(2) | 0) ++#define MT7623_PIN_2_PWRAP_INT_FUNC_PWRAP_INT (MTK_PIN_NO(2) | 1) ++ ++#define MT7623_PIN_3_PWRAP_SPI0_CK_FUNC_GPIO3 (MTK_PIN_NO(3) | 0) ++#define MT7623_PIN_3_PWRAP_SPI0_CK_FUNC_PWRAP_SPICK_I (MTK_PIN_NO(3) | 1) ++ ++#define MT7623_PIN_4_PWRAP_SPI0_CSN_FUNC_GPIO4 (MTK_PIN_NO(4) | 0) ++#define MT7623_PIN_4_PWRAP_SPI0_CSN_FUNC_PWRAP_SPICS_B_I (MTK_PIN_NO(4) | 1) ++ ++#define MT7623_PIN_5_PWRAP_SPI0_CK2_FUNC_GPIO5 (MTK_PIN_NO(5) | 0) ++#define MT7623_PIN_5_PWRAP_SPI0_CK2_FUNC_PWRAP_SPICK2_I (MTK_PIN_NO(5) | 1) ++ ++#define MT7623_PIN_6_PWRAP_SPI0_CSN2_FUNC_GPIO6 (MTK_PIN_NO(6) | 0) ++#define MT7623_PIN_6_PWRAP_SPI0_CSN2_FUNC_PWRAP_SPICS2_B_I (MTK_PIN_NO(6) | 1) ++ ++#define MT7623_PIN_7_SPI1_CSN_FUNC_GPIO7 (MTK_PIN_NO(7) | 0) ++#define MT7623_PIN_7_SPI1_CSN_FUNC_SPI1_CS (MTK_PIN_NO(7) | 1) ++ ++#define MT7623_PIN_8_SPI1_MI_FUNC_GPIO8 (MTK_PIN_NO(8) | 0) ++#define MT7623_PIN_8_SPI1_MI_FUNC_SPI1_MI (MTK_PIN_NO(8) | 1) ++#define MT7623_PIN_8_SPI1_MI_FUNC_SPI1_MO (MTK_PIN_NO(8) | 2) ++ ++#define MT7623_PIN_9_SPI1_MO_FUNC_GPIO9 (MTK_PIN_NO(9) | 0) ++#define MT7623_PIN_9_SPI1_MO_FUNC_SPI1_MO (MTK_PIN_NO(9) | 1) ++#define MT7623_PIN_9_SPI1_MO_FUNC_SPI1_MI (MTK_PIN_NO(9) | 2) ++ ++#define MT7623_PIN_10_RTC32K_CK_FUNC_GPIO10 (MTK_PIN_NO(10) | 0) ++#define MT7623_PIN_10_RTC32K_CK_FUNC_RTC32K_CK (MTK_PIN_NO(10) | 1) ++ ++#define MT7623_PIN_11_WATCHDOG_FUNC_GPIO11 (MTK_PIN_NO(11) | 0) ++#define MT7623_PIN_11_WATCHDOG_FUNC_WATCHDOG (MTK_PIN_NO(11) | 1) ++ ++#define MT7623_PIN_12_SRCLKENA_FUNC_GPIO12 (MTK_PIN_NO(12) | 0) ++#define MT7623_PIN_12_SRCLKENA_FUNC_SRCLKENA (MTK_PIN_NO(12) | 1) ++ ++#define MT7623_PIN_13_SRCLKENAI_FUNC_GPIO13 (MTK_PIN_NO(13) | 0) ++#define MT7623_PIN_13_SRCLKENAI_FUNC_SRCLKENAI (MTK_PIN_NO(13) | 1) ++ ++#define MT7623_PIN_14_GPIO14_FUNC_GPIO14 (MTK_PIN_NO(14) | 0) ++#define MT7623_PIN_14_GPIO14_FUNC_URXD2 (MTK_PIN_NO(14) | 1) ++#define MT7623_PIN_14_GPIO14_FUNC_UTXD2 (MTK_PIN_NO(14) | 2) ++ ++#define MT7623_PIN_15_GPIO15_FUNC_GPIO15 (MTK_PIN_NO(15) | 0) ++#define MT7623_PIN_15_GPIO15_FUNC_UTXD2 (MTK_PIN_NO(15) | 1) ++#define MT7623_PIN_15_GPIO15_FUNC_URXD2 (MTK_PIN_NO(15) | 2) ++ ++#define MT7623_PIN_18_PCM_CLK_FUNC_GPIO18 (MTK_PIN_NO(18) | 0) ++#define MT7623_PIN_18_PCM_CLK_FUNC_PCM_CLK0 (MTK_PIN_NO(18) | 1) ++#define MT7623_PIN_18_PCM_CLK_FUNC_AP_PCM_CLKO (MTK_PIN_NO(18) | 6) ++ ++#define MT7623_PIN_19_PCM_SYNC_FUNC_GPIO19 (MTK_PIN_NO(19) | 0) ++#define MT7623_PIN_19_PCM_SYNC_FUNC_PCM_SYNC (MTK_PIN_NO(19) | 1) ++#define MT7623_PIN_19_PCM_SYNC_FUNC_AP_PCM_SYNC (MTK_PIN_NO(19) | 6) ++ ++#define MT7623_PIN_20_PCM_RX_FUNC_GPIO20 (MTK_PIN_NO(20) | 0) ++#define MT7623_PIN_20_PCM_RX_FUNC_PCM_RX (MTK_PIN_NO(20) | 1) ++#define MT7623_PIN_20_PCM_RX_FUNC_PCM_TX (MTK_PIN_NO(20) | 4) ++#define MT7623_PIN_20_PCM_RX_FUNC_AP_PCM_RX (MTK_PIN_NO(20) | 6) ++ ++#define MT7623_PIN_21_PCM_TX_FUNC_GPIO21 (MTK_PIN_NO(21) | 0) ++#define MT7623_PIN_21_PCM_TX_FUNC_PCM_TX (MTK_PIN_NO(21) | 1) ++#define MT7623_PIN_21_PCM_TX_FUNC_PCM_RX (MTK_PIN_NO(21) | 4) ++#define MT7623_PIN_21_PCM_TX_FUNC_AP_PCM_TX (MTK_PIN_NO(21) | 6) ++ ++#define MT7623_PIN_22_EINT0_FUNC_GPIO22 (MTK_PIN_NO(22) | 0) ++#define MT7623_PIN_22_EINT0_FUNC_UCTS0 (MTK_PIN_NO(22) | 1) ++#define MT7623_PIN_22_EINT0_FUNC_PCIE0_PERST_N (MTK_PIN_NO(22) | 2) ++ ++#define MT7623_PIN_23_EINT1_FUNC_GPIO23 (MTK_PIN_NO(23) | 0) ++#define MT7623_PIN_23_EINT1_FUNC_URTS0 (MTK_PIN_NO(23) | 1) ++#define MT7623_PIN_23_EINT1_FUNC_PCIE1_PERST_N (MTK_PIN_NO(23) | 2) ++ ++#define MT7623_PIN_24_EINT2_FUNC_GPIO24 (MTK_PIN_NO(24) | 0) ++#define MT7623_PIN_24_EINT2_FUNC_UCTS1 (MTK_PIN_NO(24) | 1) ++#define MT7623_PIN_24_EINT2_FUNC_PCIE2_PERST_N (MTK_PIN_NO(24) | 2) ++ ++#define MT7623_PIN_25_EINT3_FUNC_GPIO25 (MTK_PIN_NO(25) | 0) ++#define MT7623_PIN_25_EINT3_FUNC_URTS1 (MTK_PIN_NO(25) | 1) ++ ++#define MT7623_PIN_26_EINT4_FUNC_GPIO26 (MTK_PIN_NO(26) | 0) ++#define MT7623_PIN_26_EINT4_FUNC_UCTS3 (MTK_PIN_NO(26) | 1) ++#define MT7623_PIN_26_EINT4_FUNC_PCIE2_WAKE_N (MTK_PIN_NO(26) | 6) ++ ++#define MT7623_PIN_27_EINT5_FUNC_GPIO27 (MTK_PIN_NO(27) | 0) ++#define MT7623_PIN_27_EINT5_FUNC_URTS3 (MTK_PIN_NO(27) | 1) ++#define MT7623_PIN_27_EINT5_FUNC_PCIE1_WAKE_N (MTK_PIN_NO(27) | 6) ++ ++#define MT7623_PIN_28_EINT6_FUNC_GPIO28 (MTK_PIN_NO(28) | 0) ++#define MT7623_PIN_28_EINT6_FUNC_DRV_VBUS (MTK_PIN_NO(28) | 1) ++#define MT7623_PIN_28_EINT6_FUNC_PCIE0_WAKE_N (MTK_PIN_NO(28) | 6) ++ ++#define MT7623_PIN_29_EINT7_FUNC_GPIO29 (MTK_PIN_NO(29) | 0) ++#define MT7623_PIN_29_EINT7_FUNC_IDDIG (MTK_PIN_NO(29) | 1) ++#define MT7623_PIN_29_EINT7_FUNC_MSDC1_WP (MTK_PIN_NO(29) | 2) ++#define MT7623_PIN_29_EINT7_FUNC_PCIE2_PERST_N (MTK_PIN_NO(29) | 6) ++ ++#define MT7623_PIN_33_I2S1_DATA_FUNC_GPIO33 (MTK_PIN_NO(33) | 0) ++#define MT7623_PIN_33_I2S1_DATA_FUNC_I2S1_DATA (MTK_PIN_NO(33) | 1) ++#define MT7623_PIN_33_I2S1_DATA_FUNC_PCM_TX (MTK_PIN_NO(33) | 3) ++#define MT7623_PIN_33_I2S1_DATA_FUNC_AP_PCM_TX (MTK_PIN_NO(33) | 6) ++ ++#define MT7623_PIN_34_I2S1_DATA_IN_FUNC_GPIO34 (MTK_PIN_NO(34) | 0) ++#define MT7623_PIN_34_I2S1_DATA_IN_FUNC_I2S1_DATA_IN (MTK_PIN_NO(34) | 1) ++#define MT7623_PIN_34_I2S1_DATA_IN_FUNC_PCM_RX (MTK_PIN_NO(34) | 3) ++#define MT7623_PIN_34_I2S1_DATA_IN_FUNC_AP_PCM_RX (MTK_PIN_NO(34) | 6) ++ ++#define MT7623_PIN_35_I2S1_BCK_FUNC_GPIO35 (MTK_PIN_NO(35) | 0) ++#define MT7623_PIN_35_I2S1_BCK_FUNC_I2S1_BCK (MTK_PIN_NO(35) | 1) ++#define MT7623_PIN_35_I2S1_BCK_FUNC_PCM_CLK0 (MTK_PIN_NO(35) | 3) ++#define MT7623_PIN_35_I2S1_BCK_FUNC_AP_PCM_CLKO (MTK_PIN_NO(35) | 6) ++ ++#define MT7623_PIN_36_I2S1_LRCK_FUNC_GPIO36 (MTK_PIN_NO(36) | 0) ++#define MT7623_PIN_36_I2S1_LRCK_FUNC_I2S1_LRCK (MTK_PIN_NO(36) | 1) ++#define MT7623_PIN_36_I2S1_LRCK_FUNC_PCM_SYNC (MTK_PIN_NO(36) | 3) ++#define MT7623_PIN_36_I2S1_LRCK_FUNC_AP_PCM_SYNC (MTK_PIN_NO(36) | 6) ++ ++#define MT7623_PIN_37_I2S1_MCLK_FUNC_GPIO37 (MTK_PIN_NO(37) | 0) ++#define MT7623_PIN_37_I2S1_MCLK_FUNC_I2S1_MCLK (MTK_PIN_NO(37) | 1) ++ ++#define MT7623_PIN_39_JTMS_FUNC_GPIO39 (MTK_PIN_NO(39) | 0) ++#define MT7623_PIN_39_JTMS_FUNC_JTMS (MTK_PIN_NO(39) | 1) ++ ++#define MT7623_PIN_40_JTCK_FUNC_GPIO40 (MTK_PIN_NO(40) | 0) ++#define MT7623_PIN_40_JTCK_FUNC_JTCK (MTK_PIN_NO(40) | 1) ++ ++#define MT7623_PIN_41_JTDI_FUNC_GPIO41 (MTK_PIN_NO(41) | 0) ++#define MT7623_PIN_41_JTDI_FUNC_JTDI (MTK_PIN_NO(41) | 1) ++ ++#define MT7623_PIN_42_JTDO_FUNC_GPIO42 (MTK_PIN_NO(42) | 0) ++#define MT7623_PIN_42_JTDO_FUNC_JTDO (MTK_PIN_NO(42) | 1) ++ ++#define MT7623_PIN_43_NCLE_FUNC_GPIO43 (MTK_PIN_NO(43) | 0) ++#define MT7623_PIN_43_NCLE_FUNC_NCLE (MTK_PIN_NO(43) | 1) ++#define MT7623_PIN_43_NCLE_FUNC_EXT_XCS2 (MTK_PIN_NO(43) | 2) ++ ++#define MT7623_PIN_44_NCEB1_FUNC_GPIO44 (MTK_PIN_NO(44) | 0) ++#define MT7623_PIN_44_NCEB1_FUNC_NCEB1 (MTK_PIN_NO(44) | 1) ++#define MT7623_PIN_44_NCEB1_FUNC_IDDIG (MTK_PIN_NO(44) | 2) ++ ++#define MT7623_PIN_45_NCEB0_FUNC_GPIO45 (MTK_PIN_NO(45) | 0) ++#define MT7623_PIN_45_NCEB0_FUNC_NCEB0 (MTK_PIN_NO(45) | 1) ++#define MT7623_PIN_45_NCEB0_FUNC_DRV_VBUS (MTK_PIN_NO(45) | 2) ++ ++#define MT7623_PIN_46_IR_FUNC_GPIO46 (MTK_PIN_NO(46) | 0) ++#define MT7623_PIN_46_IR_FUNC_IR (MTK_PIN_NO(46) | 1) ++ ++#define MT7623_PIN_47_NREB_FUNC_GPIO47 (MTK_PIN_NO(47) | 0) ++#define MT7623_PIN_47_NREB_FUNC_NREB (MTK_PIN_NO(47) | 1) ++ ++#define MT7623_PIN_48_NRNB_FUNC_GPIO48 (MTK_PIN_NO(48) | 0) ++#define MT7623_PIN_48_NRNB_FUNC_NRNB (MTK_PIN_NO(48) | 1) ++ ++#define MT7623_PIN_49_I2S0_DATA_FUNC_GPIO49 (MTK_PIN_NO(49) | 0) ++#define MT7623_PIN_49_I2S0_DATA_FUNC_I2S0_DATA (MTK_PIN_NO(49) | 1) ++#define MT7623_PIN_49_I2S0_DATA_FUNC_PCM_TX (MTK_PIN_NO(49) | 3) ++#define MT7623_PIN_49_I2S0_DATA_FUNC_AP_I2S_DO (MTK_PIN_NO(49) | 6) ++ ++#define MT7623_PIN_53_SPI0_CSN_FUNC_GPIO53 (MTK_PIN_NO(53) | 0) ++#define MT7623_PIN_53_SPI0_CSN_FUNC_SPI0_CS (MTK_PIN_NO(53) | 1) ++#define MT7623_PIN_53_SPI0_CSN_FUNC_PWM1 (MTK_PIN_NO(53) | 5) ++ ++#define MT7623_PIN_54_SPI0_CK_FUNC_GPIO54 (MTK_PIN_NO(54) | 0) ++#define MT7623_PIN_54_SPI0_CK_FUNC_SPI0_CK (MTK_PIN_NO(54) | 1) ++ ++#define MT7623_PIN_55_SPI0_MI_FUNC_GPIO55 (MTK_PIN_NO(55) | 0) ++#define MT7623_PIN_55_SPI0_MI_FUNC_SPI0_MI (MTK_PIN_NO(55) | 1) ++#define MT7623_PIN_55_SPI0_MI_FUNC_SPI0_MO (MTK_PIN_NO(55) | 2) ++#define MT7623_PIN_55_SPI0_MI_FUNC_MSDC1_WP (MTK_PIN_NO(55) | 3) ++#define MT7623_PIN_55_SPI0_MI_FUNC_PWM2 (MTK_PIN_NO(55) | 5) ++ ++#define MT7623_PIN_56_SPI0_MO_FUNC_GPIO56 (MTK_PIN_NO(56) | 0) ++#define MT7623_PIN_56_SPI0_MO_FUNC_SPI0_MO (MTK_PIN_NO(56) | 1) ++#define MT7623_PIN_56_SPI0_MO_FUNC_SPI0_MI (MTK_PIN_NO(56) | 2) ++ ++#define MT7623_PIN_60_WB_RSTB_FUNC_GPIO60 (MTK_PIN_NO(60) | 0) ++#define MT7623_PIN_60_WB_RSTB_FUNC_WB_RSTB (MTK_PIN_NO(60) | 1) ++ ++#define MT7623_PIN_61_GPIO61_FUNC_GPIO61 (MTK_PIN_NO(61) | 0) ++#define MT7623_PIN_61_GPIO61_FUNC_TEST_FD (MTK_PIN_NO(61) | 1) ++ ++#define MT7623_PIN_62_GPIO62_FUNC_GPIO62 (MTK_PIN_NO(62) | 0) ++#define MT7623_PIN_62_GPIO62_FUNC_TEST_FC (MTK_PIN_NO(62) | 1) ++ ++#define MT7623_PIN_63_WB_SCLK_FUNC_GPIO63 (MTK_PIN_NO(63) | 0) ++#define MT7623_PIN_63_WB_SCLK_FUNC_WB_SCLK (MTK_PIN_NO(63) | 1) ++ ++#define MT7623_PIN_64_WB_SDATA_FUNC_GPIO64 (MTK_PIN_NO(64) | 0) ++#define MT7623_PIN_64_WB_SDATA_FUNC_WB_SDATA (MTK_PIN_NO(64) | 1) ++ ++#define MT7623_PIN_65_WB_SEN_FUNC_GPIO65 (MTK_PIN_NO(65) | 0) ++#define MT7623_PIN_65_WB_SEN_FUNC_WB_SEN (MTK_PIN_NO(65) | 1) ++ ++#define MT7623_PIN_66_WB_CRTL0_FUNC_GPIO66 (MTK_PIN_NO(66) | 0) ++#define MT7623_PIN_66_WB_CRTL0_FUNC_WB_CRTL0 (MTK_PIN_NO(66) | 1) ++ ++#define MT7623_PIN_67_WB_CRTL1_FUNC_GPIO67 (MTK_PIN_NO(67) | 0) ++#define MT7623_PIN_67_WB_CRTL1_FUNC_WB_CRTL1 (MTK_PIN_NO(67) | 1) ++ ++#define MT7623_PIN_68_WB_CRTL2_FUNC_GPIO68 (MTK_PIN_NO(68) | 0) ++#define MT7623_PIN_68_WB_CRTL2_FUNC_WB_CRTL2 (MTK_PIN_NO(68) | 1) ++ ++#define MT7623_PIN_69_WB_CRTL3_FUNC_GPIO69 (MTK_PIN_NO(69) | 0) ++#define MT7623_PIN_69_WB_CRTL3_FUNC_WB_CRTL3 (MTK_PIN_NO(69) | 1) ++ ++#define MT7623_PIN_70_WB_CRTL4_FUNC_GPIO70 (MTK_PIN_NO(70) | 0) ++#define MT7623_PIN_70_WB_CRTL4_FUNC_WB_CRTL4 (MTK_PIN_NO(70) | 1) ++ ++#define MT7623_PIN_71_WB_CRTL5_FUNC_GPIO71 (MTK_PIN_NO(71) | 0) ++#define MT7623_PIN_71_WB_CRTL5_FUNC_WB_CRTL5 (MTK_PIN_NO(71) | 1) ++ ++#define MT7623_PIN_72_I2S0_DATA_IN_FUNC_GPIO72 (MTK_PIN_NO(72) | 0) ++#define MT7623_PIN_72_I2S0_DATA_IN_FUNC_I2S0_DATA_IN (MTK_PIN_NO(72) | 1) ++#define MT7623_PIN_72_I2S0_DATA_IN_FUNC_PCM_RX (MTK_PIN_NO(72) | 3) ++#define MT7623_PIN_72_I2S0_DATA_IN_FUNC_PWM0 (MTK_PIN_NO(72) | 4) ++#define MT7623_PIN_72_I2S0_DATA_IN_FUNC_DISP_PWM (MTK_PIN_NO(72) | 5) ++#define MT7623_PIN_72_I2S0_DATA_IN_FUNC_AP_I2S_DI (MTK_PIN_NO(72) | 6) ++ ++#define MT7623_PIN_73_I2S0_LRCK_FUNC_GPIO73 (MTK_PIN_NO(73) | 0) ++#define MT7623_PIN_73_I2S0_LRCK_FUNC_I2S0_LRCK (MTK_PIN_NO(73) | 1) ++#define MT7623_PIN_73_I2S0_LRCK_FUNC_PCM_SYNC (MTK_PIN_NO(73) | 3) ++#define MT7623_PIN_73_I2S0_LRCK_FUNC_AP_I2S_LRCK (MTK_PIN_NO(73) | 6) ++ ++#define MT7623_PIN_74_I2S0_BCK_FUNC_GPIO74 (MTK_PIN_NO(74) | 0) ++#define MT7623_PIN_74_I2S0_BCK_FUNC_I2S0_BCK (MTK_PIN_NO(74) | 1) ++#define MT7623_PIN_74_I2S0_BCK_FUNC_PCM_CLK0 (MTK_PIN_NO(74) | 3) ++#define MT7623_PIN_74_I2S0_BCK_FUNC_AP_I2S_BCK (MTK_PIN_NO(74) | 6) ++ ++#define MT7623_PIN_75_SDA0_FUNC_GPIO75 (MTK_PIN_NO(75) | 0) ++#define MT7623_PIN_75_SDA0_FUNC_SDA0 (MTK_PIN_NO(75) | 1) ++ ++#define MT7623_PIN_76_SCL0_FUNC_GPIO76 (MTK_PIN_NO(76) | 0) ++#define MT7623_PIN_76_SCL0_FUNC_SCL0 (MTK_PIN_NO(76) | 1) ++ ++#define MT7623_PIN_83_LCM_RST_FUNC_GPIO83 (MTK_PIN_NO(83) | 0) ++#define MT7623_PIN_83_LCM_RST_FUNC_LCM_RST (MTK_PIN_NO(83) | 1) ++ ++#define MT7623_PIN_84_DSI_TE_FUNC_GPIO84 (MTK_PIN_NO(84) | 0) ++#define MT7623_PIN_84_DSI_TE_FUNC_DSI_TE (MTK_PIN_NO(84) | 1) ++ ++#define MT7623_PIN_95_MIPI_TCN_FUNC_GPIO95 (MTK_PIN_NO(95) | 0) ++#define MT7623_PIN_95_MIPI_TCN_FUNC_TCN (MTK_PIN_NO(95) | 1) ++ ++#define MT7623_PIN_96_MIPI_TCP_FUNC_GPIO96 (MTK_PIN_NO(96) | 0) ++#define MT7623_PIN_96_MIPI_TCP_FUNC_TCP (MTK_PIN_NO(96) | 1) ++ ++#define MT7623_PIN_97_MIPI_TDN1_FUNC_GPIO97 (MTK_PIN_NO(97) | 0) ++#define MT7623_PIN_97_MIPI_TDN1_FUNC_TDN1 (MTK_PIN_NO(97) | 1) ++ ++#define MT7623_PIN_98_MIPI_TDP1_FUNC_GPIO98 (MTK_PIN_NO(98) | 0) ++#define MT7623_PIN_98_MIPI_TDP1_FUNC_TDP1 (MTK_PIN_NO(98) | 1) ++ ++#define MT7623_PIN_99_MIPI_TDN0_FUNC_GPIO99 (MTK_PIN_NO(99) | 0) ++#define MT7623_PIN_99_MIPI_TDN0_FUNC_TDN0 (MTK_PIN_NO(99) | 1) ++ ++#define MT7623_PIN_100_MIPI_TDP0_FUNC_GPIO100 (MTK_PIN_NO(100) | 0) ++#define MT7623_PIN_100_MIPI_TDP0_FUNC_TDP0 (MTK_PIN_NO(100) | 1) ++ ++#define MT7623_PIN_105_MSDC1_CMD_FUNC_GPIO105 (MTK_PIN_NO(105) | 0) ++#define MT7623_PIN_105_MSDC1_CMD_FUNC_MSDC1_CMD (MTK_PIN_NO(105) | 1) ++#define MT7623_PIN_105_MSDC1_CMD_FUNC_SDA1 (MTK_PIN_NO(105) | 3) ++#define MT7623_PIN_105_MSDC1_CMD_FUNC_I2SOUT_BCK (MTK_PIN_NO(105) | 6) ++ ++#define MT7623_PIN_106_MSDC1_CLK_FUNC_GPIO106 (MTK_PIN_NO(106) | 0) ++#define MT7623_PIN_106_MSDC1_CLK_FUNC_MSDC1_CLK (MTK_PIN_NO(106) | 1) ++#define MT7623_PIN_106_MSDC1_CLK_FUNC_SCL1 (MTK_PIN_NO(106) | 3) ++#define MT7623_PIN_106_MSDC1_CLK_FUNC_I2SOUT_LRCK (MTK_PIN_NO(106) | 6) ++ ++#define MT7623_PIN_107_MSDC1_DAT0_FUNC_GPIO107 (MTK_PIN_NO(107) | 0) ++#define MT7623_PIN_107_MSDC1_DAT0_FUNC_MSDC1_DAT0 (MTK_PIN_NO(107) | 1) ++#define MT7623_PIN_107_MSDC1_DAT0_FUNC_UTXD0 (MTK_PIN_NO(107) | 5) ++#define MT7623_PIN_107_MSDC1_DAT0_FUNC_I2SOUT_DATA_OUT (MTK_PIN_NO(107) | 6) ++ ++#define MT7623_PIN_108_MSDC1_DAT1_FUNC_GPIO108 (MTK_PIN_NO(108) | 0) ++#define MT7623_PIN_108_MSDC1_DAT1_FUNC_MSDC1_DAT1 (MTK_PIN_NO(108) | 1) ++#define MT7623_PIN_108_MSDC1_DAT1_FUNC_PWM0 (MTK_PIN_NO(108) | 3) ++#define MT7623_PIN_108_MSDC1_DAT1_FUNC_URXD0 (MTK_PIN_NO(108) | 5) ++#define MT7623_PIN_108_MSDC1_DAT1_FUNC_PWM1 (MTK_PIN_NO(108) | 6) ++ ++#define MT7623_PIN_109_MSDC1_DAT2_FUNC_GPIO109 (MTK_PIN_NO(109) | 0) ++#define MT7623_PIN_109_MSDC1_DAT2_FUNC_MSDC1_DAT2 (MTK_PIN_NO(109) | 1) ++#define MT7623_PIN_109_MSDC1_DAT2_FUNC_SDA2 (MTK_PIN_NO(109) | 3) ++#define MT7623_PIN_109_MSDC1_DAT2_FUNC_UTXD1 (MTK_PIN_NO(109) | 5) ++#define MT7623_PIN_109_MSDC1_DAT2_FUNC_PWM2 (MTK_PIN_NO(109) | 6) ++ ++#define MT7623_PIN_110_MSDC1_DAT3_FUNC_GPIO110 (MTK_PIN_NO(110) | 0) ++#define MT7623_PIN_110_MSDC1_DAT3_FUNC_MSDC1_DAT3 (MTK_PIN_NO(110) | 1) ++#define MT7623_PIN_110_MSDC1_DAT3_FUNC_SCL2 (MTK_PIN_NO(110) | 3) ++#define MT7623_PIN_110_MSDC1_DAT3_FUNC_URXD1 (MTK_PIN_NO(110) | 5) ++#define MT7623_PIN_110_MSDC1_DAT3_FUNC_PWM3 (MTK_PIN_NO(110) | 6) ++ ++#define MT7623_PIN_111_MSDC0_DAT7_FUNC_GPIO111 (MTK_PIN_NO(111) | 0) ++#define MT7623_PIN_111_MSDC0_DAT7_FUNC_MSDC0_DAT7 (MTK_PIN_NO(111) | 1) ++#define MT7623_PIN_111_MSDC0_DAT7_FUNC_NLD7 (MTK_PIN_NO(111) | 4) ++ ++#define MT7623_PIN_112_MSDC0_DAT6_FUNC_GPIO112 (MTK_PIN_NO(112) | 0) ++#define MT7623_PIN_112_MSDC0_DAT6_FUNC_MSDC0_DAT6 (MTK_PIN_NO(112) | 1) ++#define MT7623_PIN_112_MSDC0_DAT6_FUNC_NLD6 (MTK_PIN_NO(112) | 4) ++ ++#define MT7623_PIN_113_MSDC0_DAT5_FUNC_GPIO113 (MTK_PIN_NO(113) | 0) ++#define MT7623_PIN_113_MSDC0_DAT5_FUNC_MSDC0_DAT5 (MTK_PIN_NO(113) | 1) ++#define MT7623_PIN_113_MSDC0_DAT5_FUNC_NLD5 (MTK_PIN_NO(113) | 4) ++ ++#define MT7623_PIN_114_MSDC0_DAT4_FUNC_GPIO114 (MTK_PIN_NO(114) | 0) ++#define MT7623_PIN_114_MSDC0_DAT4_FUNC_MSDC0_DAT4 (MTK_PIN_NO(114) | 1) ++#define MT7623_PIN_114_MSDC0_DAT4_FUNC_NLD4 (MTK_PIN_NO(114) | 4) ++ ++#define MT7623_PIN_115_MSDC0_RSTB_FUNC_GPIO115 (MTK_PIN_NO(115) | 0) ++#define MT7623_PIN_115_MSDC0_RSTB_FUNC_MSDC0_RSTB (MTK_PIN_NO(115) | 1) ++#define MT7623_PIN_115_MSDC0_RSTB_FUNC_NLD8 (MTK_PIN_NO(115) | 4) ++ ++#define MT7623_PIN_116_MSDC0_CMD_FUNC_GPIO116 (MTK_PIN_NO(116) | 0) ++#define MT7623_PIN_116_MSDC0_CMD_FUNC_MSDC0_CMD (MTK_PIN_NO(116) | 1) ++#define MT7623_PIN_116_MSDC0_CMD_FUNC_NALE (MTK_PIN_NO(116) | 4) ++ ++#define MT7623_PIN_117_MSDC0_CLK_FUNC_GPIO117 (MTK_PIN_NO(117) | 0) ++#define MT7623_PIN_117_MSDC0_CLK_FUNC_MSDC0_CLK (MTK_PIN_NO(117) | 1) ++#define MT7623_PIN_117_MSDC0_CLK_FUNC_NWEB (MTK_PIN_NO(117) | 4) ++ ++#define MT7623_PIN_118_MSDC0_DAT3_FUNC_GPIO118 (MTK_PIN_NO(118) | 0) ++#define MT7623_PIN_118_MSDC0_DAT3_FUNC_MSDC0_DAT3 (MTK_PIN_NO(118) | 1) ++#define MT7623_PIN_118_MSDC0_DAT3_FUNC_NLD3 (MTK_PIN_NO(118) | 4) ++ ++#define MT7623_PIN_119_MSDC0_DAT2_FUNC_GPIO119 (MTK_PIN_NO(119) | 0) ++#define MT7623_PIN_119_MSDC0_DAT2_FUNC_MSDC0_DAT2 (MTK_PIN_NO(119) | 1) ++#define MT7623_PIN_119_MSDC0_DAT2_FUNC_NLD2 (MTK_PIN_NO(119) | 4) ++ ++#define MT7623_PIN_120_MSDC0_DAT1_FUNC_GPIO120 (MTK_PIN_NO(120) | 0) ++#define MT7623_PIN_120_MSDC0_DAT1_FUNC_MSDC0_DAT1 (MTK_PIN_NO(120) | 1) ++#define MT7623_PIN_120_MSDC0_DAT1_FUNC_NLD1 (MTK_PIN_NO(120) | 4) ++ ++#define MT7623_PIN_121_MSDC0_DAT0_FUNC_GPIO121 (MTK_PIN_NO(121) | 0) ++#define MT7623_PIN_121_MSDC0_DAT0_FUNC_MSDC0_DAT0 (MTK_PIN_NO(121) | 1) ++#define MT7623_PIN_121_MSDC0_DAT0_FUNC_NLD0 (MTK_PIN_NO(121) | 4) ++#define MT7623_PIN_121_MSDC0_DAT0_FUNC_WATCHDOG (MTK_PIN_NO(121) | 5) ++ ++#define MT7623_PIN_122_GPIO122_FUNC_GPIO122 (MTK_PIN_NO(122) | 0) ++#define MT7623_PIN_122_GPIO122_FUNC_TEST (MTK_PIN_NO(122) | 1) ++#define MT7623_PIN_122_GPIO122_FUNC_SDA2 (MTK_PIN_NO(122) | 4) ++#define MT7623_PIN_122_GPIO122_FUNC_URXD0 (MTK_PIN_NO(122) | 5) ++ ++#define MT7623_PIN_123_GPIO123_FUNC_GPIO123 (MTK_PIN_NO(123) | 0) ++#define MT7623_PIN_123_GPIO123_FUNC_TEST (MTK_PIN_NO(123) | 1) ++#define MT7623_PIN_123_GPIO123_FUNC_SCL2 (MTK_PIN_NO(123) | 4) ++#define MT7623_PIN_123_GPIO123_FUNC_UTXD0 (MTK_PIN_NO(123) | 5) ++ ++#define MT7623_PIN_124_GPIO124_FUNC_GPIO124 (MTK_PIN_NO(124) | 0) ++#define MT7623_PIN_124_GPIO124_FUNC_TEST (MTK_PIN_NO(124) | 1) ++#define MT7623_PIN_124_GPIO124_FUNC_SDA1 (MTK_PIN_NO(124) | 4) ++#define MT7623_PIN_124_GPIO124_FUNC_PWM3 (MTK_PIN_NO(124) | 5) ++ ++#define MT7623_PIN_125_GPIO125_FUNC_GPIO125 (MTK_PIN_NO(125) | 0) ++#define MT7623_PIN_125_GPIO125_FUNC_TEST (MTK_PIN_NO(125) | 1) ++#define MT7623_PIN_125_GPIO125_FUNC_SCL1 (MTK_PIN_NO(125) | 4) ++#define MT7623_PIN_125_GPIO125_FUNC_PWM4 (MTK_PIN_NO(125) | 5) ++ ++#define MT7623_PIN_126_I2S0_MCLK_FUNC_GPIO126 (MTK_PIN_NO(126) | 0) ++#define MT7623_PIN_126_I2S0_MCLK_FUNC_I2S0_MCLK (MTK_PIN_NO(126) | 1) ++#define MT7623_PIN_126_I2S0_MCLK_FUNC_AP_I2S_MCLK (MTK_PIN_NO(126) | 6) ++ ++#define MT7623_PIN_199_SPI1_CK_FUNC_GPIO199 (MTK_PIN_NO(199) | 0) ++#define MT7623_PIN_199_SPI1_CK_FUNC_SPI1_CK (MTK_PIN_NO(199) | 1) ++ ++#define MT7623_PIN_200_URXD2_FUNC_GPIO200 (MTK_PIN_NO(200) | 0) ++#define MT7623_PIN_200_URXD2_FUNC_URXD2 (MTK_PIN_NO(200) | 6) ++ ++#define MT7623_PIN_201_UTXD2_FUNC_GPIO201 (MTK_PIN_NO(201) | 0) ++#define MT7623_PIN_201_UTXD2_FUNC_UTXD2 (MTK_PIN_NO(201) | 6) ++ ++#define MT7623_PIN_203_PWM0_FUNC_GPIO203 (MTK_PIN_NO(203) | 0) ++#define MT7623_PIN_203_PWM0_FUNC_PWM0 (MTK_PIN_NO(203) | 1) ++#define MT7623_PIN_203_PWM0_FUNC_DISP_PWM (MTK_PIN_NO(203) | 2) ++ ++#define MT7623_PIN_204_PWM1_FUNC_GPIO204 (MTK_PIN_NO(204) | 0) ++#define MT7623_PIN_204_PWM1_FUNC_PWM1 (MTK_PIN_NO(204) | 1) ++ ++#define MT7623_PIN_205_PWM2_FUNC_GPIO205 (MTK_PIN_NO(205) | 0) ++#define MT7623_PIN_205_PWM2_FUNC_PWM2 (MTK_PIN_NO(205) | 1) ++ ++#define MT7623_PIN_206_PWM3_FUNC_GPIO206 (MTK_PIN_NO(206) | 0) ++#define MT7623_PIN_206_PWM3_FUNC_PWM3 (MTK_PIN_NO(206) | 1) ++ ++#define MT7623_PIN_207_PWM4_FUNC_GPIO207 (MTK_PIN_NO(207) | 0) ++#define MT7623_PIN_207_PWM4_FUNC_PWM4 (MTK_PIN_NO(207) | 1) ++ ++#define MT7623_PIN_208_AUD_EXT_CK1_FUNC_GPIO208 (MTK_PIN_NO(208) | 0) ++#define MT7623_PIN_208_AUD_EXT_CK1_FUNC_AUD_EXT_CK1 (MTK_PIN_NO(208) | 1) ++#define MT7623_PIN_208_AUD_EXT_CK1_FUNC_PWM0 (MTK_PIN_NO(208) | 2) ++#define MT7623_PIN_208_AUD_EXT_CK1_FUNC_PCIE0_PERST_N (MTK_PIN_NO(208) | 3) ++#define MT7623_PIN_208_AUD_EXT_CK1_FUNC_DISP_PWM (MTK_PIN_NO(208) | 5) ++ ++#define MT7623_PIN_209_AUD_EXT_CK2_FUNC_GPIO209 (MTK_PIN_NO(209) | 0) ++#define MT7623_PIN_209_AUD_EXT_CK2_FUNC_AUD_EXT_CK2 (MTK_PIN_NO(209) | 1) ++#define MT7623_PIN_209_AUD_EXT_CK2_FUNC_MSDC1_WP (MTK_PIN_NO(209) | 2) ++#define MT7623_PIN_209_AUD_EXT_CK2_FUNC_PCIE1_PERST_N (MTK_PIN_NO(209) | 3) ++#define MT7623_PIN_209_AUD_EXT_CK2_FUNC_PWM1 (MTK_PIN_NO(209) | 5) ++ ++#define MT7623_PIN_236_EXT_SDIO3_FUNC_GPIO236 (MTK_PIN_NO(236) | 0) ++#define MT7623_PIN_236_EXT_SDIO3_FUNC_EXT_SDIO3 (MTK_PIN_NO(236) | 1) ++#define MT7623_PIN_236_EXT_SDIO3_FUNC_IDDIG (MTK_PIN_NO(236) | 2) ++ ++#define MT7623_PIN_237_EXT_SDIO2_FUNC_GPIO237 (MTK_PIN_NO(237) | 0) ++#define MT7623_PIN_237_EXT_SDIO2_FUNC_EXT_SDIO2 (MTK_PIN_NO(237) | 1) ++#define MT7623_PIN_237_EXT_SDIO2_FUNC_DRV_VBUS (MTK_PIN_NO(237) | 2) ++ ++#define MT7623_PIN_238_EXT_SDIO1_FUNC_GPIO238 (MTK_PIN_NO(238) | 0) ++#define MT7623_PIN_238_EXT_SDIO1_FUNC_EXT_SDIO1 (MTK_PIN_NO(238) | 1) ++ ++#define MT7623_PIN_239_EXT_SDIO0_FUNC_GPIO239 (MTK_PIN_NO(239) | 0) ++#define MT7623_PIN_239_EXT_SDIO0_FUNC_EXT_SDIO0 (MTK_PIN_NO(239) | 1) ++ ++#define MT7623_PIN_240_EXT_XCS_FUNC_GPIO240 (MTK_PIN_NO(240) | 0) ++#define MT7623_PIN_240_EXT_XCS_FUNC_EXT_XCS (MTK_PIN_NO(240) | 1) ++ ++#define MT7623_PIN_241_EXT_SCK_FUNC_GPIO241 (MTK_PIN_NO(241) | 0) ++#define MT7623_PIN_241_EXT_SCK_FUNC_EXT_SCK (MTK_PIN_NO(241) | 1) ++ ++#define MT7623_PIN_242_URTS2_FUNC_GPIO242 (MTK_PIN_NO(242) | 0) ++#define MT7623_PIN_242_URTS2_FUNC_URTS2 (MTK_PIN_NO(242) | 1) ++#define MT7623_PIN_242_URTS2_FUNC_UTXD3 (MTK_PIN_NO(242) | 2) ++#define MT7623_PIN_242_URTS2_FUNC_URXD3 (MTK_PIN_NO(242) | 3) ++#define MT7623_PIN_242_URTS2_FUNC_SCL1 (MTK_PIN_NO(242) | 4) ++ ++#define MT7623_PIN_243_UCTS2_FUNC_GPIO243 (MTK_PIN_NO(243) | 0) ++#define MT7623_PIN_243_UCTS2_FUNC_UCTS2 (MTK_PIN_NO(243) | 1) ++#define MT7623_PIN_243_UCTS2_FUNC_URXD3 (MTK_PIN_NO(243) | 2) ++#define MT7623_PIN_243_UCTS2_FUNC_UTXD3 (MTK_PIN_NO(243) | 3) ++#define MT7623_PIN_243_UCTS2_FUNC_SDA1 (MTK_PIN_NO(243) | 4) ++ ++#define MT7623_PIN_250_GPIO250_FUNC_GPIO250 (MTK_PIN_NO(250) | 0) ++#define MT7623_PIN_250_GPIO250_FUNC_TEST_MD7 (MTK_PIN_NO(250) | 1) ++#define MT7623_PIN_250_GPIO250_FUNC_PCIE0_CLKREQ_N (MTK_PIN_NO(250) | 6) ++ ++#define MT7623_PIN_251_GPIO251_FUNC_GPIO251 (MTK_PIN_NO(251) | 0) ++#define MT7623_PIN_251_GPIO251_FUNC_TEST_MD6 (MTK_PIN_NO(251) | 1) ++#define MT7623_PIN_251_GPIO251_FUNC_PCIE0_WAKE_N (MTK_PIN_NO(251) | 6) ++ ++#define MT7623_PIN_252_GPIO252_FUNC_GPIO252 (MTK_PIN_NO(252) | 0) ++#define MT7623_PIN_252_GPIO252_FUNC_TEST_MD5 (MTK_PIN_NO(252) | 1) ++#define MT7623_PIN_252_GPIO252_FUNC_PCIE1_CLKREQ_N (MTK_PIN_NO(252) | 6) ++ ++#define MT7623_PIN_253_GPIO253_FUNC_GPIO253 (MTK_PIN_NO(253) | 0) ++#define MT7623_PIN_253_GPIO253_FUNC_TEST_MD4 (MTK_PIN_NO(253) | 1) ++#define MT7623_PIN_253_GPIO253_FUNC_PCIE1_WAKE_N (MTK_PIN_NO(253) | 6) ++ ++#define MT7623_PIN_254_GPIO254_FUNC_GPIO254 (MTK_PIN_NO(254) | 0) ++#define MT7623_PIN_254_GPIO254_FUNC_TEST_MD3 (MTK_PIN_NO(254) | 1) ++#define MT7623_PIN_254_GPIO254_FUNC_PCIE2_CLKREQ_N (MTK_PIN_NO(254) | 6) ++ ++#define MT7623_PIN_255_GPIO255_FUNC_GPIO255 (MTK_PIN_NO(255) | 0) ++#define MT7623_PIN_255_GPIO255_FUNC_TEST_MD2 (MTK_PIN_NO(255) | 1) ++#define MT7623_PIN_255_GPIO255_FUNC_PCIE2_WAKE_N (MTK_PIN_NO(255) | 6) ++ ++#define MT7623_PIN_256_GPIO256_FUNC_GPIO256 (MTK_PIN_NO(256) | 0) ++#define MT7623_PIN_256_GPIO256_FUNC_TEST_MD1 (MTK_PIN_NO(256) | 1) ++ ++#define MT7623_PIN_257_GPIO257_FUNC_GPIO257 (MTK_PIN_NO(257) | 0) ++#define MT7623_PIN_257_GPIO257_FUNC_TEST_MD0 (MTK_PIN_NO(257) | 1) ++ ++#define MT7623_PIN_261_MSDC1_INS_FUNC_GPIO261 (MTK_PIN_NO(261) | 0) ++#define MT7623_PIN_261_MSDC1_INS_FUNC_MSDC1_INS (MTK_PIN_NO(261) | 1) ++ ++#define MT7623_PIN_262_G2_TXEN_FUNC_GPIO262 (MTK_PIN_NO(262) | 0) ++#define MT7623_PIN_262_G2_TXEN_FUNC_G2_TXEN (MTK_PIN_NO(262) | 1) ++ ++#define MT7623_PIN_263_G2_TXD3_FUNC_GPIO263 (MTK_PIN_NO(263) | 0) ++#define MT7623_PIN_263_G2_TXD3_FUNC_G2_TXD3 (MTK_PIN_NO(263) | 1) ++ ++#define MT7623_PIN_264_G2_TXD2_FUNC_GPIO264 (MTK_PIN_NO(264) | 0) ++#define MT7623_PIN_264_G2_TXD2_FUNC_G2_TXD2 (MTK_PIN_NO(264) | 1) ++ ++#define MT7623_PIN_265_G2_TXD1_FUNC_GPIO265 (MTK_PIN_NO(265) | 0) ++#define MT7623_PIN_265_G2_TXD1_FUNC_G2_TXD1 (MTK_PIN_NO(265) | 1) ++ ++#define MT7623_PIN_266_G2_TXD0_FUNC_GPIO266 (MTK_PIN_NO(266) | 0) ++#define MT7623_PIN_266_G2_TXD0_FUNC_G2_TXD0 (MTK_PIN_NO(266) | 1) ++ ++#define MT7623_PIN_267_G2_TXCLK_FUNC_GPIO267 (MTK_PIN_NO(267) | 0) ++#define MT7623_PIN_267_G2_TXCLK_FUNC_G2_TXC (MTK_PIN_NO(267) | 1) ++ ++#define MT7623_PIN_268_G2_RXCLK_FUNC_GPIO268 (MTK_PIN_NO(268) | 0) ++#define MT7623_PIN_268_G2_RXCLK_FUNC_G2_RXC (MTK_PIN_NO(268) | 1) ++ ++#define MT7623_PIN_269_G2_RXD0_FUNC_GPIO269 (MTK_PIN_NO(269) | 0) ++#define MT7623_PIN_269_G2_RXD0_FUNC_G2_RXD0 (MTK_PIN_NO(269) | 1) ++ ++#define MT7623_PIN_270_G2_RXD1_FUNC_GPIO270 (MTK_PIN_NO(270) | 0) ++#define MT7623_PIN_270_G2_RXD1_FUNC_G2_RXD1 (MTK_PIN_NO(270) | 1) ++ ++#define MT7623_PIN_271_G2_RXD2_FUNC_GPIO271 (MTK_PIN_NO(271) | 0) ++#define MT7623_PIN_271_G2_RXD2_FUNC_G2_RXD2 (MTK_PIN_NO(271) | 1) ++ ++#define MT7623_PIN_272_G2_RXD3_FUNC_GPIO272 (MTK_PIN_NO(272) | 0) ++#define MT7623_PIN_272_G2_RXD3_FUNC_G2_RXD3 (MTK_PIN_NO(272) | 1) ++ ++#define MT7623_PIN_273_D2D_ESW_INT_FUNC_GPIO273 (MTK_PIN_NO(273) | 0) ++#define MT7623_PIN_273_D2D_ESW_INT_FUNC_ESW_INT (MTK_PIN_NO(273) | 1) ++ ++#define MT7623_PIN_274_G2_RXDV_FUNC_GPIO274 (MTK_PIN_NO(274) | 0) ++#define MT7623_PIN_274_G2_RXDV_FUNC_G2_RXDV (MTK_PIN_NO(274) | 1) ++ ++#define MT7623_PIN_275_G2_MDC_FUNC_GPIO275 (MTK_PIN_NO(275) | 0) ++#define MT7623_PIN_275_G2_MDC_FUNC_MDC (MTK_PIN_NO(275) | 1) ++ ++#define MT7623_PIN_276_G2_MDIO_FUNC_GPIO276 (MTK_PIN_NO(276) | 0) ++#define MT7623_PIN_276_G2_MDIO_FUNC_MDIO (MTK_PIN_NO(276) | 1) ++ ++#define MT7623_PIN_277_D2D_ESW_RSTN_FUNC_GPIO277 (MTK_PIN_NO(277) | 0) ++#define MT7623_PIN_277_D2D_ESW_RSTN_FUNC_ESW_RST (MTK_PIN_NO(277) | 1) ++ ++#define MT7623_PIN_278_JTAG_RESET_FUNC_GPIO278 (MTK_PIN_NO(278) | 0) ++#define MT7623_PIN_278_JTAG_RESET_FUNC_JTAG_RESET (MTK_PIN_NO(278) | 1) ++ ++#endif /* __DTS_MT7623_PINFUNC_H */ +\ No newline at end of file +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0063-arm-mediatek-add-SDK-ethernet.patch b/target/linux/mediatek/patches/0063-arm-mediatek-add-SDK-ethernet.patch new file mode 100644 index 0000000000..7263bb2181 --- /dev/null +++ b/target/linux/mediatek/patches/0063-arm-mediatek-add-SDK-ethernet.patch @@ -0,0 +1,20654 @@ +From e3aece79d5003b6879298b05551e113117d5cdd8 Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Sat, 27 Jun 2015 13:13:36 +0200 +Subject: [PATCH 63/76] arm: mediatek: add SDK ethernet + +Signed-off-by: John Crispin <blogic@openwrt.org> +--- + drivers/net/ethernet/Kconfig | 1 + + drivers/net/ethernet/Makefile | 1 + + drivers/net/ethernet/raeth/Kconfig | 415 ++ + drivers/net/ethernet/raeth/Makefile | 67 + + drivers/net/ethernet/raeth/Makefile.release | 60 + + drivers/net/ethernet/raeth/csr_netlink.h | 27 + + drivers/net/ethernet/raeth/dvt/pkt_gen.c | 88 + + drivers/net/ethernet/raeth/dvt/pkt_gen_tcp_frag.c | 138 + + drivers/net/ethernet/raeth/dvt/pkt_gen_udp_frag.c | 191 + + drivers/net/ethernet/raeth/dvt/raether_pdma_dvt.c | 1527 +++++ + drivers/net/ethernet/raeth/dvt/raether_pdma_dvt.h | 75 + + drivers/net/ethernet/raeth/ethtool_readme.txt | 44 + + drivers/net/ethernet/raeth/mcast.c | 187 + + drivers/net/ethernet/raeth/mii_mgr.c | 603 ++ + drivers/net/ethernet/raeth/ra2882ethreg.h | 1985 +++++++ + drivers/net/ethernet/raeth/ra_ethtool.c | 515 ++ + drivers/net/ethernet/raeth/ra_ethtool.h | 13 + + drivers/net/ethernet/raeth/ra_ioctl.h | 102 + + drivers/net/ethernet/raeth/ra_mac.c | 2645 +++++++++ + drivers/net/ethernet/raeth/ra_mac.h | 57 + + drivers/net/ethernet/raeth/ra_netlink.c | 142 + + drivers/net/ethernet/raeth/ra_netlink.h | 10 + + drivers/net/ethernet/raeth/ra_qos.c | 655 +++ + drivers/net/ethernet/raeth/ra_qos.h | 18 + + drivers/net/ethernet/raeth/ra_rfrw.c | 66 + + drivers/net/ethernet/raeth/ra_rfrw.h | 6 + + drivers/net/ethernet/raeth/raether.c | 6401 +++++++++++++++++++++ + drivers/net/ethernet/raeth/raether.h | 126 + + drivers/net/ethernet/raeth/raether_hwlro.c | 347 ++ + drivers/net/ethernet/raeth/raether_pdma.c | 1121 ++++ + drivers/net/ethernet/raeth/raether_qdma.c | 1407 +++++ + drivers/net/ethernet/raeth/raether_qdma_mt7623.c | 1020 ++++ + drivers/net/ethernet/raeth/smb_hook.c | 17 + + drivers/net/ethernet/raeth/smb_nf.c | 177 + + drivers/net/ethernet/raeth/sync_write.h | 103 + + 35 files changed, 20357 insertions(+) + create mode 100644 drivers/net/ethernet/raeth/Kconfig + create mode 100644 drivers/net/ethernet/raeth/Makefile + create mode 100644 drivers/net/ethernet/raeth/Makefile.release + create mode 100644 drivers/net/ethernet/raeth/csr_netlink.h + create mode 100755 drivers/net/ethernet/raeth/dvt/pkt_gen.c + create mode 100755 drivers/net/ethernet/raeth/dvt/pkt_gen_tcp_frag.c + create mode 100755 drivers/net/ethernet/raeth/dvt/pkt_gen_udp_frag.c + create mode 100755 drivers/net/ethernet/raeth/dvt/raether_pdma_dvt.c + create mode 100755 drivers/net/ethernet/raeth/dvt/raether_pdma_dvt.h + create mode 100644 drivers/net/ethernet/raeth/ethtool_readme.txt + create mode 100644 drivers/net/ethernet/raeth/mcast.c + create mode 100644 drivers/net/ethernet/raeth/mii_mgr.c + create mode 100644 drivers/net/ethernet/raeth/ra2882ethreg.h + create mode 100644 drivers/net/ethernet/raeth/ra_ethtool.c + create mode 100644 drivers/net/ethernet/raeth/ra_ethtool.h + create mode 100644 drivers/net/ethernet/raeth/ra_ioctl.h + create mode 100644 drivers/net/ethernet/raeth/ra_mac.c + create mode 100644 drivers/net/ethernet/raeth/ra_mac.h + create mode 100644 drivers/net/ethernet/raeth/ra_netlink.c + create mode 100644 drivers/net/ethernet/raeth/ra_netlink.h + create mode 100644 drivers/net/ethernet/raeth/ra_qos.c + create mode 100644 drivers/net/ethernet/raeth/ra_qos.h + create mode 100644 drivers/net/ethernet/raeth/ra_rfrw.c + create mode 100644 drivers/net/ethernet/raeth/ra_rfrw.h + create mode 100644 drivers/net/ethernet/raeth/raether.c + create mode 100644 drivers/net/ethernet/raeth/raether.h + create mode 100755 drivers/net/ethernet/raeth/raether_hwlro.c + create mode 100755 drivers/net/ethernet/raeth/raether_pdma.c + create mode 100644 drivers/net/ethernet/raeth/raether_qdma.c + create mode 100644 drivers/net/ethernet/raeth/raether_qdma_mt7623.c + create mode 100644 drivers/net/ethernet/raeth/smb_hook.c + create mode 100644 drivers/net/ethernet/raeth/smb_nf.c + create mode 100644 drivers/net/ethernet/raeth/sync_write.h + +diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig +index eadcb05..627e1d4 100644 +--- a/drivers/net/ethernet/Kconfig ++++ b/drivers/net/ethernet/Kconfig +@@ -17,6 +17,7 @@ config MDIO + config SUNGEM_PHY + tristate + ++source "drivers/net/ethernet/raeth/Kconfig" + source "drivers/net/ethernet/3com/Kconfig" + source "drivers/net/ethernet/adaptec/Kconfig" + source "drivers/net/ethernet/aeroflex/Kconfig" +diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile +index 1367afc..abdd636 100644 +--- a/drivers/net/ethernet/Makefile ++++ b/drivers/net/ethernet/Makefile +@@ -84,3 +84,4 @@ obj-$(CONFIG_NET_VENDOR_VIA) += via/ + obj-$(CONFIG_NET_VENDOR_WIZNET) += wiznet/ + obj-$(CONFIG_NET_VENDOR_XILINX) += xilinx/ + obj-$(CONFIG_NET_VENDOR_XIRCOM) += xircom/ ++obj-$(CONFIG_RAETH) += raeth/ +diff --git a/drivers/net/ethernet/raeth/Kconfig b/drivers/net/ethernet/raeth/Kconfig +new file mode 100644 +index 0000000..c252c85 +--- /dev/null ++++ b/drivers/net/ethernet/raeth/Kconfig +@@ -0,0 +1,415 @@ ++config ARCH_MT7623 ++ bool ++ default y ++ ++config RA_NAT_NONE ++ bool ++ default y ++ ++config RAETH ++ tristate "Ralink GMAC" ++ ---help--- ++ This driver supports Ralink gigabit ethernet family of ++ adapters. ++ ++config PDMA_NEW ++ bool ++ default y if (RALINK_MT7620 || RALINK_MT7621 || ARCH_MT7623) ++ depends on RAETH ++ ++config RAETH_SCATTER_GATHER_RX_DMA ++ bool ++ default y if (RALINK_MT7620 || RALINK_MT7621 || ARCH_MT7623) ++ depends on RAETH ++ ++ ++choice ++ prompt "Network BottomHalves" ++ depends on RAETH ++ default RA_NETWORK_WORKQUEUE_BH ++ ++ config RA_NETWORK_TASKLET_BH ++ bool "Tasklet" ++ ++ config RA_NETWORK_WORKQUEUE_BH ++ bool "Work Queue" ++ ++ config RAETH_NAPI ++ bool "NAPI" ++ ++endchoice ++ ++#config TASKLET_WORKQUEUE_SW ++# bool "Tasklet and Workqueue switch" ++# depends on RA_NETWORK_TASKLET_BH ++ ++config RAETH_SKB_RECYCLE_2K ++ bool "SKB Recycling" ++ depends on RAETH ++ ++config RAETH_SPECIAL_TAG ++ bool "Ralink Special Tag (0x810x)" ++ depends on RAETH && RT_3052_ESW ++ ++#config RAETH_JUMBOFRAME ++# bool "Jumbo Frame up to 4K bytes" ++# depends on RAETH && !(RALINK_RT3052 || RALINK_RT3352 || RALINK_RT5350 || RALINK_MT7628) ++ ++config RAETH_CHECKSUM_OFFLOAD ++ bool "TCP/UDP/IP checksum offload" ++ default y ++ depends on RAETH && !RALINK_RT2880 ++ ++#config RAETH_SW_FC ++# bool "When TX ring is full, inform kernel stop transmit and stop RX handler" ++# default n ++# depends on RAETH ++ ++#config RAETH_8023AZ_EEE ++# bool "Enable Embeded Switch EEE" ++# default n ++# depends on RAETH && (RALINK_MT7620 || RALINK_MT7621 || RALINK_MT7628) ++ ++ ++ ++config 32B_DESC ++ bool "32bytes TX/RX description" ++ default n ++ depends on RAETH && (RALINK_MT7620 || RALINK_MT7621) ++ ---help--- ++ At this moment, you cannot enable 32B description with Multiple RX ring at the same time. ++ ++config RAETH_LRO ++ bool "LRO (Large Receive Offload )" ++ select INET_LRO ++ depends on RAETH && (RALINK_RT6855A || RALINK_MT7620 || RALINK_MT7621 || ARCH_MT7623) ++ ++config RAETH_HW_LRO ++ bool "HW LRO (Large Receive Offload)" ++ default n ++ depends on RAETH ++ ++config RAETH_HW_LRO_DBG ++ bool "HW LRO Debug" ++ default n ++ depends on RAETH_HW_LRO ++ ++config RAETH_HW_LRO_AUTO_ADJ_DBG ++ bool "HW LRO Auto Adjustment Debug" ++ default y ++ depends on RAETH_HW_LRO ++ ++config RAETH_HW_LRO_REASON_DBG ++ bool "HW LRO Flush Reason Debug" ++ default n ++ depends on RAETH_HW_LRO ++ ++config RAETH_HW_VLAN_TX ++ bool "Transmit VLAN HW (DoubleVLAN is not supported)" ++ depends on RAETH && !(RALINK_RT5350 || RALINK_MT7628) ++ ---help--- ++ Please disable HW_VLAN_TX if you need double vlan ++ ++config RAETH_HW_VLAN_RX ++ bool "Receive VLAN HW (DoubleVLAN is not supported)" ++ depends on RAETH && RALINK_MT7621 ++ ---help--- ++ Please disable HW_VLAN_RX if you need double vlan ++ ++config RAETH_TSO ++ bool "TSOV4 (Tcp Segmentaton Offload)" ++ depends on (RAETH_HW_VLAN_TX && (RALINK_RT6855 || RALINK_RT6855A || RALINK_MT7620))||((RALINK_MT7621 || ARCH_MT7623) &&(RAETH_HW_VLAN_TX || RAETH_GMAC2 )) ++ ++config RAETH_TSOV6 ++ bool "TSOV6 (Tcp Segmentaton Offload)" ++ depends on RAETH_TSO ++ ++config RAETH_RW_PDMAPTR_FROM_VAR ++ bool ++ default y if RALINK_RT6855A || RALINK_MT7620 ++ depends on RAETH ++ ++config MTK_SMB_HOOK ++ bool "Samba Speedup Module" ++ depends on RAETH ++ ++config SPLICE_NET_SUPPORT ++ default y if MTK_SMB_HOOK ++ depends on MTK_SMB_HOOK ++ bool ++ ++ ++config RAETH_DVT ++ bool "RAETH DVT" ++ depends on RAETH && (RALINK_MT7621 || ARCH_MT7623) ++ ++config RAETH_PDMA_DVT ++ bool "PDMA DVT" ++ depends on RAETH_DVT ++ ++config RAETH_PDMA_LEGACY_MODE ++ bool "PDMA legacy mode" ++ depends on RAETH_PDMA_DVT ++ ++#config RAETH_QOS ++# bool "QoS Feature" ++# depends on RAETH && !RALINK_RT2880 && !RALINK_MT7620 && !RALINK_MT7621 && !RAETH_TSO ++ ++choice ++ prompt "QoS Type" ++ depends on RAETH_QOS ++ default DSCP_QOS_DSCP ++ ++config RAETH_QOS_DSCP_BASED ++ bool "DSCP-based" ++ depends on RAETH_QOS ++ ++config RAETH_QOS_VPRI_BASED ++ bool "VPRI-based" ++ depends on RAETH_QOS ++ ++endchoice ++ ++config RAETH_QDMA ++ bool "Choose QDMA instead PDMA" ++ default n ++ depends on RAETH && (RALINK_MT7621 || ARCH_MT7623) ++ ++config RAETH_QDMATX_QDMARX ++ bool "Choose QDMA RX instead PDMA RX" ++ default n ++ depends on RAETH_QDMA && !RALINK_MT7621 ++ ++ ++ ++choice ++ prompt "GMAC is connected to" ++ depends on RAETH ++ default GE1_RGMII_FORCE_1000 ++ ++config GE1_MII_FORCE_100 ++ bool "MII_FORCE_100 (10/100M Switch)" ++ depends on (RALINK_RT2880 || RALINK_RT3883 || RALINK_MT7621) ++ ++config GE1_MII_AN ++ bool "MII_AN (100Phy)" ++ depends on (RALINK_RT2880 || RALINK_RT3883 || RALINK_MT7621) ++ ++config GE1_RVMII_FORCE_100 ++ bool "RvMII_FORCE_100 (CPU)" ++ depends on (RALINK_RT2880 || RALINK_RT3883 || RALINK_MT7621) ++ ++config GE1_RGMII_FORCE_1000 ++ bool "RGMII_FORCE_1000 (GigaSW, CPU)" ++ depends on (RALINK_RT2880 || RALINK_RT3883) ++ select RALINK_SPI ++ ++config GE1_RGMII_FORCE_1000 ++ bool "RGMII_FORCE_1000 (GigaSW, CPU)" ++ depends on (RALINK_MT7621 || ARCH_MT7623) ++ select RT_3052_ESW ++ ++config GE1_TRGMII_FORCE_1200 ++ bool "TRGMII_FORCE_1200 (GigaSW, CPU)" ++ depends on (RALINK_MT7621) ++ select RT_3052_ESW ++ ++config GE1_TRGMII_FORCE_2000 ++ bool "TRGMII_FORCE_2000 (GigaSW, CPU, for MT7623 and MT7683)" ++ depends on (ARCH_MT7623) ++ select RT_3052_ESW ++ ++config GE1_TRGMII_FORCE_2600 ++ bool "TRGMII_FORCE_2600 (GigaSW, CPU, MT7623 only)" ++ depends on (ARCH_MT7623) ++ select RT_3052_ESW ++ ++config GE1_RGMII_AN ++ bool "RGMII_AN (GigaPhy)" ++ depends on (RALINK_RT2880 || RALINK_RT3883 || RALINK_MT7621 || ARCH_MT7623) ++ ++config GE1_RGMII_NONE ++ bool "NONE (NO CONNECT)" ++ depends on (RALINK_MT7621 || ARCH_MT7623) ++ ++endchoice ++ ++config HW_SFQ ++ bool "HW_SFQ" ++ default n ++ depends on RAETH_QDMA && (ARCH_MT7623) ++ ++ ++config RT_3052_ESW ++ bool "Ralink Embedded Switch" ++ default y ++ depends on RAETH && (RALINK_RT3052 || RALINK_RT3352 || RALINK_RT5350 || RALINK_RT6855 || RALINK_RT6855A || RALINK_MT7620 || RALINK_MT7621 || RALINK_MT7628 || ARCH_MT7623) ++ ++config LAN_WAN_SUPPORT ++ bool "LAN/WAN Partition" ++ depends on RAETH && (RAETH_ROUTER || RT_3052_ESW) ++ ++config ETH_MEMORY_OPTIMIZATION ++ bool "Ethernet memory optimization" ++ depends on RALINK_MT7628 ++ ++config ETH_ONE_PORT_ONLY ++ bool "One Port Only" ++ depends on RALINK_MT7628 ++ ++choice ++ prompt "Switch Board Layout Type" ++ depends on LAN_WAN_SUPPORT || P5_RGMII_TO_MAC_MODE || GE1_RGMII_FORCE_1000 || GE1_TRGMII_FORCE_1200 || GE2_RGMII_FORCE_1000 ++ default WAN_AT_P0 ++ ++ config WAN_AT_P4 ++ bool "LLLL/W" ++ ++ config WAN_AT_P0 ++ bool "W/LLLL" ++endchoice ++ ++config RALINK_VISTA_BASIC ++ bool 'Vista Basic Logo for IC+ 175C' ++ depends on LAN_WAN_SUPPORT && (RALINK_RT2880 || RALINK_RT3883) ++ ++config ESW_DOUBLE_VLAN_TAG ++ bool ++ default y if RT_3052_ESW ++ ++config RAETH_HAS_PORT4 ++ bool "Port 4 Support" ++ depends on RAETH && RALINK_MT7620 ++choice ++ prompt "Target Mode" ++ depends on RAETH_HAS_PORT4 ++ default P4_RGMII_TO_MAC_MODE ++ ++ config P4_MAC_TO_PHY_MODE ++ bool "Giga_Phy (RGMII)" ++ config GE_RGMII_MT7530_P0_AN ++ bool "GE_RGMII_MT7530_P0_AN (MT7530 Internal GigaPhy)" ++ config GE_RGMII_MT7530_P4_AN ++ bool "GE_RGMII_MT7530_P4_AN (MT7530 Internal GigaPhy)" ++ config P4_RGMII_TO_MAC_MODE ++ bool "Giga_SW/iNIC (RGMII)" ++ config P4_MII_TO_MAC_MODE ++ bool "External_CPU (MII_RvMII)" ++ config P4_RMII_TO_MAC_MODE ++ bool "External_CPU (RvMII_MII)" ++endchoice ++ ++config MAC_TO_GIGAPHY_MODE_ADDR2 ++ hex "Port4 Phy Address" ++ default 0x4 ++ depends on P4_MAC_TO_PHY_MODE ++ ++config RAETH_HAS_PORT5 ++ bool "Port 5 Support" ++ depends on RAETH && (RALINK_RT3052 || RALINK_RT3352 || RALINK_RT6855 || RALINK_RT6855A || RALINK_MT7620) ++choice ++ prompt "Target Mode" ++ depends on RAETH_HAS_PORT5 ++ default P5_RGMII_TO_MAC_MODE ++ ++ config P5_MAC_TO_PHY_MODE ++ bool "Giga_Phy (RGMII)" ++ config P5_RGMII_TO_MAC_MODE ++ bool "Giga_SW/iNIC (RGMII)" ++ config P5_RGMII_TO_MT7530_MODE ++ bool "MT7530 Giga_SW (RGMII)" ++ depends on RALINK_MT7620 ++ config P5_MII_TO_MAC_MODE ++ bool "External_CPU (MII_RvMII)" ++ config P5_RMII_TO_MAC_MODE ++ bool "External_CPU (RvMII_MII)" ++endchoice ++ ++config MAC_TO_GIGAPHY_MODE_ADDR ++ hex "GE1 Phy Address" ++ default 0x1F ++ depends on GE1_MII_AN || GE1_RGMII_AN ++ ++config MAC_TO_GIGAPHY_MODE_ADDR ++ hex "Port5 Phy Address" ++ default 0x5 ++ depends on P5_MAC_TO_PHY_MODE ++ ++config RAETH_GMAC2 ++ bool "GMAC2 Support" ++ depends on RAETH && (RALINK_RT3883 || RALINK_MT7621 || ARCH_MT7623) ++ ++choice ++ prompt "GMAC2 is connected to" ++ depends on RAETH_GMAC2 ++ default GE2_RGMII_AN ++ ++config GE2_MII_FORCE_100 ++ bool "MII_FORCE_100 (10/100M Switch)" ++ depends on RAETH_GMAC2 ++ ++config GE2_MII_AN ++ bool "MII_AN (100Phy)" ++ depends on RAETH_GMAC2 ++ ++config GE2_RVMII_FORCE_100 ++ bool "RvMII_FORCE_100 (CPU)" ++ depends on RAETH_GMAC2 ++ ++config GE2_RGMII_FORCE_1000 ++ bool "RGMII_FORCE_1000 (GigaSW, CPU)" ++ depends on RAETH_GMAC2 ++ select RALINK_SPI ++ ++config GE2_RGMII_AN ++ bool "RGMII_AN (External GigaPhy)" ++ depends on RAETH_GMAC2 ++ ++config GE2_INTERNAL_GPHY ++ bool "RGMII_AN (Internal GigaPny)" ++ depends on RAETH_GMAC2 ++ select LAN_WAN_SUPPORT ++ ++endchoice ++ ++config GE_RGMII_INTERNAL_P0_AN ++ bool ++ depends on GE2_INTERNAL_GPHY ++ default y if WAN_AT_P0 ++ ++config GE_RGMII_INTERNAL_P4_AN ++ bool ++ depends on GE2_INTERNAL_GPHY ++ default y if WAN_AT_P4 ++ ++config MAC_TO_GIGAPHY_MODE_ADDR2 ++ hex ++ default 0 if GE_RGMII_INTERNAL_P0_AN ++ default 4 if GE_RGMII_INTERNAL_P4_AN ++ depends on GE_RGMII_INTERNAL_P0_AN || GE_RGMII_INTERNAL_P4_AN ++ ++config MAC_TO_GIGAPHY_MODE_ADDR2 ++ hex "GE2 Phy Address" ++ default 0x1E ++ depends on GE2_MII_AN || GE2_RGMII_AN ++ ++#force 100M ++config RAETH_ROUTER ++bool ++default y if GE1_MII_FORCE_100 || GE2_MII_FORCE_100 || GE1_RVMII_FORCE_100 || GE2_RVMII_FORCE_100 ++ ++#force 1000M ++config MAC_TO_MAC_MODE ++bool ++default y if GE1_RGMII_FORCE_1000 || GE2_RGMII_FORCE_1000 ++depends on (RALINK_RT2880 || RALINK_RT3883) ++ ++#AN ++config GIGAPHY ++bool ++default y if GE1_RGMII_AN || GE2_RGMII_AN ++ ++#AN ++config 100PHY ++bool ++default y if GE1_MII_AN || GE2_MII_AN +diff --git a/drivers/net/ethernet/raeth/Makefile b/drivers/net/ethernet/raeth/Makefile +new file mode 100644 +index 0000000..563af05 +--- /dev/null ++++ b/drivers/net/ethernet/raeth/Makefile +@@ -0,0 +1,67 @@ ++obj-$(CONFIG_RAETH) += raeth.o ++raeth-objs := ra_mac.o mii_mgr.o ra_rfrw.o ++ ++ifeq ($(CONFIG_MTK_SMB_HOOK),y) ++obj-y += smb_hook.o ++obj-m += smb.o ++smb-objs := smb_nf.o ++endif ++ ++#EXTRA_CFLAGS += -DCONFIG_RAETH_MULTIPLE_RX_RING ++ ++ifeq ($(CONFIG_RAETH_QOS),y) ++raeth-objs += ra_qos.o ++endif ++ ++ifeq ($(CONFIG_RAETH_QDMA),y) ++raeth-objs += raether_qdma.o ++endif ++ ++ifneq ($(CONFIG_RAETH_QDMA),y) ++raeth-objs += raether_pdma.o ++endif ++ ++raeth-objs += raether.o ++ ++ifeq ($(CONFIG_ETHTOOL),y) ++raeth-objs += ra_ethtool.o ++endif ++ ++ifeq ($(CONFIG_RALINK_RT3052_MP2),y) ++raeth-objs += mcast.o ++endif ++ ++ifeq ($(CONFIG_RAETH_NETLINK),y) ++raeth-objs += ra_netlink.o ++endif ++ ++ifeq ($(CONFIG_RAETH_PDMA_DVT),y) ++raeth-objs += dvt/raether_pdma_dvt.o ++obj-m += dvt/pkt_gen.o ++obj-m += dvt/pkt_gen_udp_frag.o ++obj-m += dvt/pkt_gen_tcp_frag.o ++endif ++ ++ifeq ($(CONFIG_RAETH_HW_LRO),y) ++raeth-objs += raether_hwlro.o ++endif ++ ++ifeq ($(CONFIG_RAETH_GMAC2),y) ++EXTRA_CFLAGS += -DCONFIG_PSEUDO_SUPPORT ++endif ++ ++ifeq ($(CONFIG_ETH_MEMORY_OPTIMIZATION),y) ++EXTRA_CFLAGS += -DMEMORY_OPTIMIZATION ++endif ++ ++ifeq ($(CONFIG_RT2860V2_AP_MEMORY_OPTIMIZATION),y) ++EXTRA_CFLAGS += -DMEMORY_OPTIMIZATION ++endif ++ ++ifeq ($(CONFIG_RA_NETWORK_WORKQUEUE_BH),y) ++EXTRA_CFLAGS += -DWORKQUEUE_BH ++endif ++ ++ifeq ($(CONFIG_TASKLET_WORKQUEUE_SW),y) ++EXTRA_CFLAGS += -DTASKLET_WORKQUEUE_SW ++endif +diff --git a/drivers/net/ethernet/raeth/Makefile.release b/drivers/net/ethernet/raeth/Makefile.release +new file mode 100644 +index 0000000..ecdeeda +--- /dev/null ++++ b/drivers/net/ethernet/raeth/Makefile.release +@@ -0,0 +1,60 @@ ++obj-$(CONFIG_RAETH) += raeth.o ++raeth-objs := ra_mac.o mii_mgr.o ra_rfrw.o ++ ++ifeq ($(CONFIG_MTK_SMB_HOOK),y) ++obj-y += smb_hook.o ++obj-m += smb.o ++smb-objs := smb_nf.o ++endif ++ ++#EXTRA_CFLAGS += -DCONFIG_RAETH_MULTIPLE_RX_RING ++ ++ifeq ($(CONFIG_RAETH_QOS),y) ++raeth-objs += ra_qos.o ++endif ++ ++ifeq ($(CONFIG_RAETH_QDMA),y) ++raeth-objs += raether_qdma.o ++endif ++ ++ifneq ($(CONFIG_RAETH_QDMA),y) ++raeth-objs += raether_pdma.o ++endif ++ ++raeth-objs += raether.o ++ ++ifeq ($(CONFIG_ETHTOOL),y) ++raeth-objs += ra_ethtool.o ++endif ++ ++ifeq ($(CONFIG_RALINK_RT3052_MP2),y) ++raeth-objs += mcast.o ++endif ++ ++ifeq ($(CONFIG_RAETH_NETLINK),y) ++raeth-objs += ra_netlink.o ++endif ++ ++ifeq ($(CONFIG_RAETH_HW_LRO),y) ++raeth-objs += raether_hwlro.o ++endif ++ ++ifeq ($(CONFIG_RAETH_GMAC2),y) ++EXTRA_CFLAGS += -DCONFIG_PSEUDO_SUPPORT ++endif ++ ++ifeq ($(CONFIG_ETH_MEMORY_OPTIMIZATION),y) ++EXTRA_CFLAGS += -DMEMORY_OPTIMIZATION ++endif ++ ++ifeq ($(CONFIG_RT2860V2_AP_MEMORY_OPTIMIZATION),y) ++EXTRA_CFLAGS += -DMEMORY_OPTIMIZATION ++endif ++ ++ifeq ($(CONFIG_RA_NETWORK_WORKQUEUE_BH),y) ++EXTRA_CFLAGS += -DWORKQUEUE_BH ++endif ++ ++ifeq ($(CONFIG_TASKLET_WORKQUEUE_SW),y) ++EXTRA_CFLAGS += -DTASKLET_WORKQUEUE_SW ++endif +diff --git a/drivers/net/ethernet/raeth/csr_netlink.h b/drivers/net/ethernet/raeth/csr_netlink.h +new file mode 100644 +index 0000000..add7745 +--- /dev/null ++++ b/drivers/net/ethernet/raeth/csr_netlink.h +@@ -0,0 +1,27 @@ ++#ifndef CSR_NETLINK_H ++#define CSR_NETLINK_H ++ ++#define CSR_NETLINK 30 ++#define CSR_READ 0 ++#define CSR_WRITE 1 ++#define CSR_TEST 2 ++ ++#define RALINK_CSR_GROUP 2882 ++ ++typedef struct rt2880_csr_msg { ++ int enable; ++ char reg_name[32]; ++ unsigned long address; ++ unsigned long default_value; ++ unsigned long reserved_bits; /* 1 : not reserved, 0 : reserved */ ++ unsigned long write_mask; ++ unsigned long write_value; ++ int status; ++} CSR_MSG; ++ ++int csr_msg_send(CSR_MSG* msg); ++int csr_msg_recv(void); ++ ++// static CSR_MSG input_csr_msg; ++ ++#endif +diff --git a/drivers/net/ethernet/raeth/dvt/pkt_gen.c b/drivers/net/ethernet/raeth/dvt/pkt_gen.c +new file mode 100755 +index 0000000..b351b21 +--- /dev/null ++++ b/drivers/net/ethernet/raeth/dvt/pkt_gen.c +@@ -0,0 +1,88 @@ ++//#include <linux/config.h> ++#include <linux/version.h> ++#include <linux/module.h> ++#include <linux/skbuff.h> ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/netfilter.h> ++#include <linux/netdevice.h> ++#include <linux/types.h> ++#include <asm/uaccess.h> ++#include <linux/moduleparam.h> ++ ++char *ifname="eth3"; ++ ++static int32_t PktGenInitMod(void) ++{ ++ ++ struct net_dev *dev; ++ struct sk_buff *skb; ++ int i=0; ++ ++ unsigned char pkt[]={ ++ //0xff, 0xff, 0xff, 0xff, 0xff, 0xff, // dest bcast mac ++ 0x00, 0x21, 0x86, 0xee, 0xe3, 0x95, // dest macA ++ //0x00, 0x30, 0xdb, 0x02, 0x02, 0x01, // dest macB ++ 0x00, 0x0c, 0x43, 0x28, 0x80, 0x33, // src mac ++ 0x81, 0x00, // vlan tag ++ //0x81, 0x10, // vlan tag ++ //0x87, 0x39, // do not learn ++ //0xc1, 0x03, // vlan tag SA=0, VID=2, LV=1 ++ 0x00, 0x03, // pri=0, vlan=3 ++ 0x08, 0x00, // eth type=ip ++ 0x45, 0x00, 0x00, 0x30, 0x12, 0x34, 0x40, 0x00, 0xff, 0x06, ++ 0x40, 0x74, 0x0a, 0x0a, 0x1e, 0x0a, 0x0a, 0x0a, 0x1e, 0x0b, ++ 0x00, 0x1e, 0x00, 0x28, 0x00, 0x1c, 0x81, 0x06, 0x00, 0x00, ++ 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; ++ ++ skb = alloc_skb(256, GFP_ATOMIC); ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ if((dev=dev_get_by_name(&init_net,ifname))){ ++#else ++ if((dev=dev_get_by_name(ifname))){ ++#endif ++ ++ ++ ++ skb->dev=dev; ++ skb_put(skb,sizeof(pkt)); ++ memcpy(skb->data, pkt, sizeof(pkt)); ++ ++ printk("send pkt(len=%d) to %s\n", skb->len, skb->dev->name); ++ ++ ++ for(i=0;i<sizeof(pkt);i++){ ++ if(i%16==0) { ++ printk("\n"); ++ } ++ printk("%02X-",skb->data[i]); ++ } ++ ++ dev_queue_xmit(skb); ++ }else{ ++ printk("interface %s not found\n",ifname); ++ return 1; ++ } ++ ++ return 0; ++} ++ ++static void PktGenCleanupMod(void) ++{ ++} ++ ++module_init(PktGenInitMod); ++module_exit(PktGenCleanupMod); ++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12) ++MODULE_PARM (ifname, "s"); ++#else ++module_param (ifname, charp, 0); ++#endif ++ ++MODULE_DESCRIPTION("Ralink PktGen Module"); ++MODULE_AUTHOR("Steven Liu"); ++MODULE_LICENSE("Proprietary"); ++MODULE_PARM_DESC (ifname, "interface name"); ++ +diff --git a/drivers/net/ethernet/raeth/dvt/pkt_gen_tcp_frag.c b/drivers/net/ethernet/raeth/dvt/pkt_gen_tcp_frag.c +new file mode 100755 +index 0000000..e78c65a +--- /dev/null ++++ b/drivers/net/ethernet/raeth/dvt/pkt_gen_tcp_frag.c +@@ -0,0 +1,138 @@ ++//#include <linux/config.h> ++#include <linux/version.h> ++#include <linux/module.h> ++#include <linux/skbuff.h> ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/netfilter.h> ++#include <linux/netdevice.h> ++#include <linux/types.h> ++#include <asm/uaccess.h> ++#include <linux/moduleparam.h> ++ ++char *ifname="eth3"; ++ ++ ++static int32_t PktGenInitMod(void) ++{ ++ unsigned char pkt_1[]={ ++ 0x00, 0x21, 0x86, 0xee, 0xe3, 0x90, // dest mac ++ 0x00, 0x0c, 0x43, 0x28, 0x80, 0x33, // src mac ++ 0x08, 0x00, // type: ip ++ 0x45, 0x00, 0x00, 0x34, // ip: ..., total len (0x034 = 52) ++ 0xa1, 0x78, 0x20, 0x00, // ip: id, frag, frag offset ++ 0x80, 0x06, 0x63, 0x07, // ip: ttl, protocol, hdr checksum (0x6307) ++ 0x0a, 0x0a, 0x1e, 0x7b, // src ip (10.10.30.123) ++ 0x0a, 0x0a, 0x1e, 0x05, // dst ip (10.10.30.5) ++ 0x0d, 0xd5, //tcp src port ++ 0x13, 0x89, //tcp dst port ++ 0x40, 0xf5, 0x15, 0x04, //tcp sequence number ++ 0xf6, 0x4f, 0x1e, 0x31, //tcp ack number ++ 0x50, 0x10, 0xfc, 0x00, //tcp flags, win size ++ 0xf1, 0xfe, 0x00, 0x00, //tcp checksum (0xf1fe) ++ 0x01, 0x02, 0x03, 0x04, 0x05, //payload (12 bytes) ++ 0x06, 0x07, 0x08, 0x09, 0x0a, ++ 0x0b, 0x0c ++ }; ++ ++ unsigned char pkt_2[]={ ++ 0x00, 0x21, 0x86, 0xee, 0xe3, 0x90, // dest mac ++ 0x00, 0x0c, 0x43, 0x28, 0x80, 0x33, // src mac ++ 0x08, 0x00, // type: ip ++ 0x45, 0x00, 0x00, 0x20, // ip: ..., total len (0x020 = 32) ++ 0xa1, 0x78, 0x00, 0x04, // ip: id, frag, frag offset (32) ++ 0x40, 0x11, 0x63, 0x07, // ip: ttl, protocol, hdr checksum (0x6307) ++ 0x0a, 0x0a, 0x1e, 0x7b, // src ip (10.10.30.123) ++ 0x0a, 0x0a, 0x1e, 0x05, // dst ip (10.10.30.5) ++ 0x11, 0x12, 0x13, 0x14, 0x15, //payload (12 bytes) ++ 0x16, 0x17, 0x18, 0x19, 0x1a, ++ 0x1b, 0x1c ++ }; ++ ++ struct net_dev *dev; ++ struct sk_buff *skb_1; ++ struct sk_buff *skb_2; ++ int i=0; ++ ++ skb_1 = alloc_skb(256, GFP_ATOMIC); ++ skb_2 = alloc_skb(256, GFP_ATOMIC); ++ ++ ++#if 1 ++/* send packet 1 */ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ if((dev=dev_get_by_name(&init_net,ifname))){ ++#else ++ if((dev=dev_get_by_name(ifname))){ ++#endif ++ ++ skb_1->dev=dev; ++ skb_put(skb_1,sizeof(pkt_1)); ++ memcpy(skb_1->data, pkt_1, sizeof(pkt_1)); ++ ++ printk("send pkt(len=%d) to %s\n", skb_1->len, skb_1->dev->name); ++ ++ ++ for(i=0;i<sizeof(pkt_1);i++){ ++ if(i%16==0) { ++ printk("\n"); ++ } ++ printk("%02X-",skb_1->data[i]); ++ } ++ ++ dev_queue_xmit(skb_1); ++ }else{ ++ printk("interface %s not found\n",ifname); ++ return 1; ++ } ++#endif ++ ++#if 1 ++/* send packet 2 */ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ if((dev=dev_get_by_name(&init_net,ifname))){ ++#else ++ if((dev=dev_get_by_name(ifname))){ ++#endif ++ ++ skb_2->dev=dev; ++ skb_put(skb_2,sizeof(pkt_2)); ++ memcpy(skb_2->data, pkt_2, sizeof(pkt_2)); ++ ++ printk("send pkt(len=%d) to %s\n", skb_2->len, skb_2->dev->name); ++ ++ ++ for(i=0;i<sizeof(pkt_2);i++){ ++ if(i%16==0) { ++ printk("\n"); ++ } ++ printk("%02X-",skb_2->data[i]); ++ } ++ ++ dev_queue_xmit(skb_2); ++ }else{ ++ printk("interface %s not found\n",ifname); ++ return 1; ++ } ++#endif ++ ++ return 0; ++} ++ ++static void PktGenCleanupMod(void) ++{ ++} ++ ++module_init(PktGenInitMod); ++module_exit(PktGenCleanupMod); ++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12) ++MODULE_PARM (ifname, "s"); ++#else ++module_param (ifname, charp, 0); ++#endif ++ ++MODULE_DESCRIPTION("Ralink PktGen Module"); ++MODULE_AUTHOR("Steven Liu"); ++MODULE_LICENSE("Proprietary"); ++MODULE_PARM_DESC (ifname, "interface name"); ++ +diff --git a/drivers/net/ethernet/raeth/dvt/pkt_gen_udp_frag.c b/drivers/net/ethernet/raeth/dvt/pkt_gen_udp_frag.c +new file mode 100755 +index 0000000..917e7ad +--- /dev/null ++++ b/drivers/net/ethernet/raeth/dvt/pkt_gen_udp_frag.c +@@ -0,0 +1,191 @@ ++//#include <linux/config.h> ++#include <linux/version.h> ++#include <linux/module.h> ++#include <linux/skbuff.h> ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/netfilter.h> ++#include <linux/netdevice.h> ++#include <linux/types.h> ++#include <asm/uaccess.h> ++#include <linux/moduleparam.h> ++ ++char *ifname="eth3"; ++ ++ ++static int32_t PktGenInitMod(void) ++{ ++#if 0 ++ unsigned char pkt_0[]={ ++// 0x00, 0x21, 0x86, 0xee, 0xe3, 0x95, // dest mac ++ 0x00, 0x21, 0x86, 0xee, 0xe3, 0x90, // dest mac ++ 0x00, 0x0c, 0x43, 0x28, 0x80, 0x33, // src mac ++ 0x08, 0x00, // type: ip ++ 0x45, 0x00, 0x00, 0x26, // ip: ..., total len (0x026 = 38) ++// 0xa1, 0x78, 0x20, 0x00, // ip: id, frag, frag offset ++ 0xa1, 0x78, 0x40, 0x00, // ip: id, frag, frag offset ++ 0x40, 0x11, 0x63, 0x07, // ip: ttl, protocol, hdr checksum (0x6307) ++ 0x0a, 0x0a, 0x1e, 0x7b, // src ip (10.10.30.123) ++// 0x0a, 0x0a, 0x1e, 0x03, // dst ip (10.10.30.3) ++ 0x0a, 0x0a, 0x1e, 0x05, // dst ip (10.10.30.5) ++ 0xca, 0x7b, //udp src port ++ 0x13, 0x89, //udp dst port ++ 0x00, 0x12, //udp len (0x01c = 18) ++ 0x2f, 0x96, //udp checksum (0x2f96) ++ 0x01, 0x02, 0x03, 0x04, 0x05, //payload (10 bytes) ++ 0x06, 0x07, 0x08, 0x09, 0x0a ++ }; ++#endif ++ ++ unsigned char pkt_1[]={ ++// 0x00, 0x21, 0x86, 0xee, 0xe3, 0x95, // dest mac ++ 0x00, 0x21, 0x86, 0xee, 0xe3, 0x90, // dest mac ++ 0x00, 0x0c, 0x43, 0x28, 0x80, 0x33, // src mac ++ 0x08, 0x00, // type: ip ++ 0x45, 0x00, 0x00, 0x24, // ip: ..., total len (0x024 = 36) ++ 0xa1, 0x78, 0x20, 0x00, // ip: id, frag, frag offset ++// 0xa1, 0x78, 0x40, 0x00, // ip: id, frag, frag offset ++ 0x40, 0x11, 0x63, 0x07, // ip: ttl, protocol, hdr checksum (0x6307) ++ 0x0a, 0x0a, 0x1e, 0x7b, // src ip (10.10.30.123) ++// 0x0a, 0x0a, 0x1e, 0x03, // dst ip (10.10.30.3) ++ 0x0a, 0x0a, 0x1e, 0x05, // dst ip (10.10.30.5) ++ 0xca, 0x7b, //udp src port ++ 0x13, 0x89, //udp dst port ++ 0x00, 0x1a, //udp len (0x01a = 26) ++ 0x2f, 0x96, //udp checksum (0x2f96) ++ 0x01, 0x02, 0x03, 0x04, 0x05, //payload (8 bytes) ++ 0x06, 0x07, 0x08 ++ }; ++ ++ unsigned char pkt_2[]={ ++// 0x00, 0x21, 0x86, 0xee, 0xe3, 0x95, // dest mac ++ 0x00, 0x21, 0x86, 0xee, 0xe3, 0x90, // dest mac ++ 0x00, 0x0c, 0x43, 0x28, 0x80, 0x33, // src mac ++ 0x08, 0x00, // type: ip ++ 0x45, 0x00, 0x00, 0x1e, // ip: ..., total len (0x01e = 30) ++ 0xa1, 0x78, 0x00, 0x02, // ip: id, frag, frag offset (16) ++ 0x40, 0x11, 0x63, 0x07, // ip: ttl, protocol, hdr checksum (0x6307) ++ 0x0a, 0x0a, 0x1e, 0x7b, // src ip (10.10.30.123) ++// 0x0a, 0x0a, 0x1e, 0x03, // dst ip (10.10.30.3) ++ 0x0a, 0x0a, 0x1e, 0x05, // dst ip (10.10.30.5) ++ 0x11, 0x12, 0x13, 0x14, 0x15, //payload (10 bytes) ++ 0x16, 0x17, 0x18, 0x19, 0x1a ++ }; ++ ++ struct net_dev *dev; ++// struct sk_buff *skb_0; ++ struct sk_buff *skb_1; ++ struct sk_buff *skb_2; ++ int i=0; ++ ++// skb_0 = alloc_skb(256, GFP_ATOMIC); ++ skb_1 = alloc_skb(256, GFP_ATOMIC); ++ skb_2 = alloc_skb(256, GFP_ATOMIC); ++ ++#if 0 ++/* send packet 0 */ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ if((dev=dev_get_by_name(&init_net,ifname))){ ++#else ++ if((dev=dev_get_by_name(ifname))){ ++#endif ++ ++ skb_0->dev=dev; ++ skb_put(skb_0,sizeof(pkt_0)); ++ memcpy(skb_0->data, pkt_0, sizeof(pkt_0)); ++ ++ printk("send pkt(len=%d) to %s\n", skb_0->len, skb_0->dev->name); ++ ++ ++ for(i=0;i<sizeof(pkt_0);i++){ ++ if(i%16==0) { ++ printk("\n"); ++ } ++ printk("%02X-",skb_0->data[i]); ++ } ++ ++ dev_queue_xmit(skb_0); ++ }else{ ++ printk("interface %s not found\n",ifname); ++ return 1; ++ } ++#endif ++ ++#if 1 ++/* send packet 1 */ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ if((dev=dev_get_by_name(&init_net,ifname))){ ++#else ++ if((dev=dev_get_by_name(ifname))){ ++#endif ++ ++ skb_1->dev=dev; ++ skb_put(skb_1,sizeof(pkt_1)); ++ memcpy(skb_1->data, pkt_1, sizeof(pkt_1)); ++ ++ printk("send pkt(len=%d) to %s\n", skb_1->len, skb_1->dev->name); ++ ++ ++ for(i=0;i<sizeof(pkt_1);i++){ ++ if(i%16==0) { ++ printk("\n"); ++ } ++ printk("%02X-",skb_1->data[i]); ++ } ++ ++ dev_queue_xmit(skb_1); ++ }else{ ++ printk("interface %s not found\n",ifname); ++ return 1; ++ } ++#endif ++ ++#if 1 ++/* send packet 2 */ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ if((dev=dev_get_by_name(&init_net,ifname))){ ++#else ++ if((dev=dev_get_by_name(ifname))){ ++#endif ++ ++ skb_2->dev=dev; ++ skb_put(skb_2,sizeof(pkt_2)); ++ memcpy(skb_2->data, pkt_2, sizeof(pkt_2)); ++ ++ printk("send pkt(len=%d) to %s\n", skb_2->len, skb_2->dev->name); ++ ++ ++ for(i=0;i<sizeof(pkt_2);i++){ ++ if(i%16==0) { ++ printk("\n"); ++ } ++ printk("%02X-",skb_2->data[i]); ++ } ++ ++ dev_queue_xmit(skb_2); ++ }else{ ++ printk("interface %s not found\n",ifname); ++ return 1; ++ } ++#endif ++ ++ return 0; ++} ++ ++static void PktGenCleanupMod(void) ++{ ++} ++ ++module_init(PktGenInitMod); ++module_exit(PktGenCleanupMod); ++#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,12) ++MODULE_PARM (ifname, "s"); ++#else ++module_param (ifname, charp, 0); ++#endif ++ ++MODULE_DESCRIPTION("Ralink PktGen Module"); ++MODULE_AUTHOR("Steven Liu"); ++MODULE_LICENSE("Proprietary"); ++MODULE_PARM_DESC (ifname, "interface name"); ++ +diff --git a/drivers/net/ethernet/raeth/dvt/raether_pdma_dvt.c b/drivers/net/ethernet/raeth/dvt/raether_pdma_dvt.c +new file mode 100755 +index 0000000..971a821 +--- /dev/null ++++ b/drivers/net/ethernet/raeth/dvt/raether_pdma_dvt.c +@@ -0,0 +1,1527 @@ ++#include <linux/module.h> ++#include <linux/version.h> ++#include <linux/kernel.h> ++#include <linux/types.h> ++#include <linux/pci.h> ++#include <linux/init.h> ++#include <linux/skbuff.h> ++#include <linux/if_vlan.h> ++#include <linux/if_ether.h> ++#include <linux/fs.h> ++#include <asm/uaccess.h> ++#include <asm/rt2880/surfboardint.h> ++#if defined(CONFIG_RAETH_TSO) ++#include <linux/tcp.h> ++#include <net/ipv6.h> ++#include <linux/ip.h> ++#include <net/ip.h> ++#include <net/tcp.h> ++#include <linux/in.h> ++#include <linux/ppp_defs.h> ++#include <linux/if_pppox.h> ++#endif ++#if defined(CONFIG_RAETH_LRO) ++#include <linux/inet_lro.h> ++#endif ++#include <linux/delay.h> ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 35) ++#include <linux/sched.h> ++#endif ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 0) ++#include <asm/rt2880/rt_mmap.h> ++#else ++#include <linux/libata-compat.h> ++#endif ++ ++#include "../ra2882ethreg.h" ++#include "../raether.h" ++#include "../ra_mac.h" ++#include "../ra_ioctl.h" ++#include "../ra_rfrw.h" ++#ifdef CONFIG_RAETH_NETLINK ++#include "../ra_netlink.h" ++#endif ++#if defined(CONFIG_RAETH_QOS) ++#include "../ra_qos.h" ++#endif ++#include "raether_pdma_dvt.h" ++ ++/* Global variables */ ++static unsigned int g_pdma_dvt_show_config; ++static unsigned int g_pdma_dvt_rx_test_config; ++static unsigned int g_pdma_dvt_tx_test_config; ++static unsigned int g_pdma_dvt_debug_test_config; ++static unsigned int g_pdma_dvt_lro_test_config; ++ ++unsigned int g_pdma_dev_lanport = 0; ++unsigned int g_pdma_dev_wanport = 0; ++ ++void skb_dump(struct sk_buff *sk) ++{ ++ unsigned int i; ++ ++ printk("skb_dump: from %s with len %d (%d) headroom=%d tailroom=%d\n", ++ sk->dev ? sk->dev->name : "ip stack", sk->len, sk->truesize, ++ skb_headroom(sk), skb_tailroom(sk)); ++ ++ /* for(i=(unsigned int)sk->head;i<=(unsigned int)sk->tail;i++) { */ ++ /* for(i=(unsigned int)sk->head;i<=(unsigned int)sk->data+20;i++) { */ ++ for (i = (unsigned int)sk->head; i <= (unsigned int)sk->data + 60; i++) { ++ if ((i % 20) == 0) ++ printk("\n"); ++ if (i == (unsigned int)sk->data) ++ printk("{"); ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 21) ++ if (i == (unsigned int)sk->transport_header) ++ printk("#"); ++ if (i == (unsigned int)sk->network_header) ++ printk("|"); ++ if (i == (unsigned int)sk->mac_header) ++ printk("*"); ++#else ++ if (i == (unsigned int)sk->h.raw) ++ printk("#"); ++ if (i == (unsigned int)sk->nh.raw) ++ printk("|"); ++ if (i == (unsigned int)sk->mac.raw) ++ printk("*"); ++#endif ++ printk("%02X-", *((unsigned char *)i)); ++ if (i == (unsigned int)sk->tail) ++ printk("}"); ++ } ++ printk("\n"); ++} ++ ++#if defined(CONFIG_RAETH_HW_LRO) ++/* PDMA LRO test functions start */ ++int pdma_lro_disable_dvt(void) ++{ ++ unsigned int regVal = 0; ++ ++ printk("pdma_lro_disable_dvt()\n"); ++ ++ /* 1. Invalid LRO ring1~3 */ ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING1, 0); ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING2, 0); ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING3, 0); ++ ++ /* 2 Polling relinguish */ ++ while (sysRegRead(ADMA_LRO_CTRL_DW0) & PDMA_LRO_RELINGUISH) {; ++ } ++ ++ /* 3. Disable LRO */ ++ regVal = sysRegRead(ADMA_LRO_CTRL_DW0); ++ regVal &= ~(PDMA_LRO_EN); ++ sysRegWrite(ADMA_LRO_CTRL_DW0, regVal); ++ ++#if 0 ++ /* 4. Disable non-lro multiple rx */ ++ SET_PDMA_NON_LRO_MULTI_EN(0); ++ ++ /* 5.1. Set GDM1 to ring0 */ ++ SET_GDM_PID1_RXID_SEL(0); ++ /* 5.2. Set GDM2 to ring0 */ ++ SET_GDM_PID2_RXID_SEL(0); ++#endif ++ ++ return 0; ++} ++ ++int pdma_lro_force_aggre_dvt(void) ++{ ++ unsigned int regVal = 0; ++ unsigned int ip; ++ ++ printk("pdma_lro_force_aggre_dvt()\n"); ++ ++/* pdma rx ring1 */ ++ /* 1. Set RX ring mode to force port */ ++ SET_PDMA_RXRING_MODE(ADMA_RX_RING1, PDMA_RX_FORCE_PORT); ++ ++ /* 2. Configure lro ring */ ++ /* 2.1 set src/destination TCP ports */ ++ SET_PDMA_RXRING_TCP_SRC_PORT(ADMA_RX_RING1, 3423); ++ SET_PDMA_RXRING_TCP_DEST_PORT(ADMA_RX_RING1, 2301); ++ /* 2.2 set src/destination IPs */ ++ str_to_ip(&ip, "10.10.10.3"); ++ sysRegWrite(LRO_RX_RING1_SIP_DW0, ip); ++ str_to_ip(&ip, "10.10.10.100"); ++ sysRegWrite(LRO_RX_RING1_DIP_DW0, ip); ++ SET_PDMA_RXRING_MYIP_VALID(ADMA_RX_RING1, 1); ++ ++ /* 2.3 Valid LRO ring */ ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING1, 1); ++ ++ /* 2.4 Set AGE timer */ ++ SET_PDMA_RXRING_AGE_TIME(ADMA_RX_RING1, 0); ++ ++ /* 2.5 Set max AGG timer */ ++ SET_PDMA_RXRING_AGG_TIME(ADMA_RX_RING1, 0); ++ ++ /* 2.6 Set max LRO agg count */ ++ SET_PDMA_RXRING_MAX_AGG_CNT(ADMA_RX_RING1, HW_LRO_MAX_AGG_CNT); ++ ++ /* 3. IPv4 checksum update enable */ ++ SET_PDMA_LRO_IPV4_CSUM_UPDATE_EN(1); ++ ++ /* 4. Polling relinguish */ ++ while (sysRegRead(ADMA_LRO_CTRL_DW0) & PDMA_LRO_RELINGUISH) {; ++ } ++ ++ /* 5. Enable LRO */ ++ regVal = sysRegRead(ADMA_LRO_CTRL_DW0); ++ regVal |= PDMA_LRO_EN; ++ sysRegWrite(ADMA_LRO_CTRL_DW0, regVal); ++ ++ return 0; ++} ++ ++int pdma_lro_auto_aggre_dvt(void) ++{ ++ unsigned int regVal = 0; ++ unsigned int ip; ++ ++ printk("pdma_lro_auto_aggre_dvt()\n"); ++ ++ /* 1.1 Set my IP_1 */ ++ str_to_ip(&ip, "10.10.10.254"); ++ sysRegWrite(LRO_RX_RING0_DIP_DW0, ip); ++ sysRegWrite(LRO_RX_RING0_DIP_DW1, 0); ++ sysRegWrite(LRO_RX_RING0_DIP_DW2, 0); ++ sysRegWrite(LRO_RX_RING0_DIP_DW3, 0); ++ SET_PDMA_RXRING_MYIP_VALID(ADMA_RX_RING0, 1); ++ ++ /* 1.2 Set my IP_2 */ ++ str_to_ip(&ip, "10.10.20.254"); ++ sysRegWrite(LRO_RX_RING1_DIP_DW0, ip); ++ sysRegWrite(LRO_RX_RING1_DIP_DW1, 0); ++ sysRegWrite(LRO_RX_RING1_DIP_DW2, 0); ++ sysRegWrite(LRO_RX_RING1_DIP_DW3, 0); ++ SET_PDMA_RXRING_MYIP_VALID(ADMA_RX_RING1, 1); ++ ++ /* 1.3 Set my IP_3 */ ++ sysRegWrite(LRO_RX_RING2_DIP_DW3, 0x20010238); ++ sysRegWrite(LRO_RX_RING2_DIP_DW2, 0x08000000); ++ sysRegWrite(LRO_RX_RING2_DIP_DW1, 0x00000000); ++ sysRegWrite(LRO_RX_RING2_DIP_DW0, 0x00000254); ++ SET_PDMA_RXRING_MYIP_VALID(ADMA_RX_RING2, 1); ++ ++ /* 1.4 Set my IP_4 */ ++ sysRegWrite(LRO_RX_RING3_DIP_DW3, 0x20010238); ++ sysRegWrite(LRO_RX_RING3_DIP_DW2, 0x08010000); ++ sysRegWrite(LRO_RX_RING3_DIP_DW1, 0x00000000); ++ sysRegWrite(LRO_RX_RING3_DIP_DW0, 0x00000254); ++ SET_PDMA_RXRING_MYIP_VALID(ADMA_RX_RING3, 1); ++ ++ /* 2.1 Set RX ring1~3 to auto-learn modes */ ++ SET_PDMA_RXRING_MODE(ADMA_RX_RING1, PDMA_RX_AUTO_LEARN); ++ SET_PDMA_RXRING_MODE(ADMA_RX_RING2, PDMA_RX_AUTO_LEARN); ++ SET_PDMA_RXRING_MODE(ADMA_RX_RING3, PDMA_RX_AUTO_LEARN); ++ ++ /* 2.2 Valid LRO ring */ ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING0, 1); ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING1, 1); ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING2, 1); ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING3, 1); ++ ++ /* 2.3 Set AGE timer */ ++ SET_PDMA_RXRING_AGE_TIME(ADMA_RX_RING1, 0); ++ SET_PDMA_RXRING_AGE_TIME(ADMA_RX_RING2, 0); ++ SET_PDMA_RXRING_AGE_TIME(ADMA_RX_RING3, 0); ++ ++ /* 2.4 Set max AGG timer */ ++ SET_PDMA_RXRING_AGG_TIME(ADMA_RX_RING1, 0); ++ SET_PDMA_RXRING_AGG_TIME(ADMA_RX_RING2, 0); ++ SET_PDMA_RXRING_AGG_TIME(ADMA_RX_RING3, 0); ++ ++ /* 2.5 Set max LRO agg count */ ++ SET_PDMA_RXRING_MAX_AGG_CNT(ADMA_RX_RING1, HW_LRO_MAX_AGG_CNT); ++ SET_PDMA_RXRING_MAX_AGG_CNT(ADMA_RX_RING2, HW_LRO_MAX_AGG_CNT); ++ SET_PDMA_RXRING_MAX_AGG_CNT(ADMA_RX_RING3, HW_LRO_MAX_AGG_CNT); ++ ++ /* 3.0 IPv6 LRO enable */ ++ SET_PDMA_LRO_IPV6_EN(1); ++ ++ /* 3.1 IPv4 checksum update disable */ ++ SET_PDMA_LRO_IPV4_CSUM_UPDATE_EN(1); ++ ++ /* 3.2 switch priority comparision to byte count mode */ ++ SET_PDMA_LRO_ALT_SCORE_MODE(PDMA_LRO_ALT_BYTE_CNT_MODE); ++ ++ /* 3.3 bandwidth threshold setting */ ++ SET_PDMA_LRO_BW_THRESHOLD(0); ++ ++ /* 3.4 auto-learn score delta setting */ ++ sysRegWrite(LRO_ALT_SCORE_DELTA, 0); ++ ++ /* 3.5 Set ALT timer to 20us: (unit: 20us) */ ++ SET_PDMA_LRO_ALT_REFRESH_TIMER_UNIT(HW_LRO_TIMER_UNIT); ++ /* 3.6 Set ALT refresh timer to 1 sec. (unit: 20us) */ ++ SET_PDMA_LRO_ALT_REFRESH_TIMER(HW_LRO_REFRESH_TIME); ++ ++ /* 4. Polling relinguish */ ++ while (sysRegRead(ADMA_LRO_CTRL_DW0) & PDMA_LRO_RELINGUISH) {; ++ } ++ ++ /* 5. Enable LRO */ ++ regVal = sysRegRead(ADMA_LRO_CTRL_DW0); ++ regVal |= PDMA_LRO_EN; ++ sysRegWrite(ADMA_LRO_CTRL_DW0, regVal); ++ ++ return 0; ++} ++ ++int pdma_lro_auto_ipv6_dvt(void) ++{ ++ unsigned int regVal = 0; ++ ++ printk("pdma_lro_auto_ipv6_dvt()\n"); ++ ++ /* 1. Set my IP */ ++ sysRegWrite(LRO_RX_RING1_DIP_DW3, 0x20010238); ++ sysRegWrite(LRO_RX_RING1_DIP_DW2, 0x08000000); ++ sysRegWrite(LRO_RX_RING1_DIP_DW1, 0x00000000); ++ sysRegWrite(LRO_RX_RING1_DIP_DW0, 0x00000254); ++ ++ /* 2.1 Set RX ring1~3 to auto-learn modes */ ++ SET_PDMA_RXRING_MODE(ADMA_RX_RING1, PDMA_RX_AUTO_LEARN); ++ SET_PDMA_RXRING_MODE(ADMA_RX_RING2, PDMA_RX_AUTO_LEARN); ++ SET_PDMA_RXRING_MODE(ADMA_RX_RING3, PDMA_RX_AUTO_LEARN); ++ ++ /* 2.2 Valid LRO ring */ ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING1, 1); ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING2, 1); ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING3, 1); ++ ++ /* 2.3 Set AGE timer */ ++ SET_PDMA_RXRING_AGE_TIME(ADMA_RX_RING1, HW_LRO_AGE_TIME); ++ SET_PDMA_RXRING_AGE_TIME(ADMA_RX_RING2, HW_LRO_AGE_TIME); ++ SET_PDMA_RXRING_AGE_TIME(ADMA_RX_RING3, HW_LRO_AGE_TIME); ++ ++ /* 3.0 IPv6 LRO enable */ ++ SET_PDMA_LRO_IPV6_EN(1); ++ ++ /* 3.1 IPv4 checksum update disable */ ++ SET_PDMA_LRO_IPV4_CSUM_UPDATE_EN(1); ++ ++ /* 3.2 switch priority comparision to byte count mode */ ++ SET_PDMA_LRO_ALT_SCORE_MODE(PDMA_LRO_ALT_BYTE_CNT_MODE); ++ ++ /* 3.3 bandwidth threshold setting */ ++ SET_PDMA_LRO_BW_THRESHOLD(0); ++ ++ /* 3.4 auto-learn score delta setting */ ++ sysRegWrite(LRO_ALT_SCORE_DELTA, 0); ++ ++ /* 3.5 Set ALT timer to 500us: (unit: 20us) */ ++ SET_PDMA_LRO_ALT_REFRESH_TIMER_UNIT(25); ++ /* 3.6 Set ALT refresh timer to 1 sec. (unit: 500us) */ ++ SET_PDMA_LRO_ALT_REFRESH_TIMER(2000); ++ ++ /* 3.7 Set max AGG timer: 10 msec. */ ++ SET_PDMA_LRO_MAX_AGG_TIME(HW_LRO_AGG_TIME); ++ ++ /* 4. Polling relinguish */ ++ while (sysRegRead(ADMA_LRO_CTRL_DW0) & PDMA_LRO_RELINGUISH) {; ++ } ++ ++ /* 5. Enable LRO */ ++ regVal = sysRegRead(ADMA_LRO_CTRL_DW0); ++ regVal |= PDMA_LRO_EN; ++ sysRegWrite(ADMA_LRO_CTRL_DW0, regVal); ++ ++ return 0; ++} ++ ++int pdma_lro_auto_myIP_dvt(void) ++{ ++ unsigned int regVal = 0; ++ unsigned int ip; ++ ++ printk("pdma_lro_auto_myIP_dvt()\n"); ++ ++ /* 1.1 Set my IP_1 */ ++ str_to_ip(&ip, "10.10.10.254"); ++ sysRegWrite(LRO_RX_RING0_DIP_DW0, ip); ++ sysRegWrite(LRO_RX_RING0_DIP_DW1, 0); ++ sysRegWrite(LRO_RX_RING0_DIP_DW2, 0); ++ sysRegWrite(LRO_RX_RING0_DIP_DW3, 0); ++ SET_PDMA_RXRING_MYIP_VALID(ADMA_RX_RING0, 1); ++ /* 1.2 Set my IP_2 */ ++ str_to_ip(&ip, "10.10.20.254"); ++ sysRegWrite(LRO_RX_RING1_DIP_DW0, ip); ++ sysRegWrite(LRO_RX_RING1_DIP_DW1, 0); ++ sysRegWrite(LRO_RX_RING1_DIP_DW2, 0); ++ sysRegWrite(LRO_RX_RING1_DIP_DW3, 0); ++ SET_PDMA_RXRING_MYIP_VALID(ADMA_RX_RING1, 1); ++ /* 1.3 Set my IP_3 */ ++ sysRegWrite(LRO_RX_RING2_DIP_DW3, 0x20010238); ++ sysRegWrite(LRO_RX_RING2_DIP_DW2, 0x08000000); ++ sysRegWrite(LRO_RX_RING2_DIP_DW1, 0x00000000); ++ sysRegWrite(LRO_RX_RING2_DIP_DW0, 0x00000254); ++ SET_PDMA_RXRING_MYIP_VALID(ADMA_RX_RING2, 1); ++ /* 1.4 Set my IP_4 */ ++ sysRegWrite(LRO_RX_RING3_DIP_DW3, 0x20010238); ++ sysRegWrite(LRO_RX_RING3_DIP_DW2, 0x08010000); ++ sysRegWrite(LRO_RX_RING3_DIP_DW1, 0x00000000); ++ sysRegWrite(LRO_RX_RING3_DIP_DW0, 0x00000254); ++ SET_PDMA_RXRING_MYIP_VALID(ADMA_RX_RING3, 1); ++ ++ /* 2.1 Set RX ring1~3 to auto-learn modes */ ++ SET_PDMA_RXRING_MODE(ADMA_RX_RING1, PDMA_RX_AUTO_LEARN); ++ SET_PDMA_RXRING_MODE(ADMA_RX_RING2, PDMA_RX_AUTO_LEARN); ++ SET_PDMA_RXRING_MODE(ADMA_RX_RING3, PDMA_RX_AUTO_LEARN); ++ ++ /* 2.2 Valid LRO ring */ ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING0, 1); ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING1, 1); ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING2, 1); ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING3, 1); ++ ++ /* 2.3 Set AGE timer */ ++ SET_PDMA_RXRING_AGE_TIME(ADMA_RX_RING1, HW_LRO_AGE_TIME); ++ SET_PDMA_RXRING_AGE_TIME(ADMA_RX_RING2, HW_LRO_AGE_TIME); ++ SET_PDMA_RXRING_AGE_TIME(ADMA_RX_RING3, HW_LRO_AGE_TIME); ++ ++ /* 3.0 IPv6 LRO enable */ ++ SET_PDMA_LRO_IPV6_EN(1); ++ ++ /* 3.1 IPv4 checksum update disable */ ++ SET_PDMA_LRO_IPV4_CSUM_UPDATE_EN(1); ++ ++ /* 3.2 switch priority comparision to byte count mode */ ++ SET_PDMA_LRO_ALT_SCORE_MODE(PDMA_LRO_ALT_BYTE_CNT_MODE); ++ ++ /* 3.3 bandwidth threshold setting */ ++ SET_PDMA_LRO_BW_THRESHOLD(0); ++ ++ /* 3.4 auto-learn score delta setting */ ++ sysRegWrite(LRO_ALT_SCORE_DELTA, 0); ++ ++ /* 3.5 Set ALT timer to 500us: (unit: 20us) */ ++ SET_PDMA_LRO_ALT_REFRESH_TIMER_UNIT(25); ++ /* 3.6 Set ALT refresh timer to 1 sec. (unit: 500us) */ ++ SET_PDMA_LRO_ALT_REFRESH_TIMER(2000); ++ ++ /* 3.7 Set max AGG timer: 10 msec. */ ++ SET_PDMA_LRO_MAX_AGG_TIME(HW_LRO_AGG_TIME); ++ ++ /* 4. Polling relinguish */ ++ while (sysRegRead(ADMA_LRO_CTRL_DW0) & PDMA_LRO_RELINGUISH) {; ++ } ++ ++ /* 5. Enable LRO */ ++ regVal = sysRegRead(ADMA_LRO_CTRL_DW0); ++ regVal |= PDMA_LRO_EN; ++ sysRegWrite(ADMA_LRO_CTRL_DW0, regVal); ++ ++ return 0; ++} ++ ++int pdma_lro_dly_int_dvt(int index) ++{ ++ unsigned int regVal = 0; ++ unsigned int ip; ++ ++ printk("pdma_lro_dly_int_dvt(%d)\n", index); ++ ++#if 0 ++ /* 1.1 Set my IP_1 */ ++ /* str_to_ip( &ip, "10.10.10.254" ); */ ++ str_to_ip(&ip, "10.10.10.100"); ++ sysRegWrite(LRO_RX_RING0_DIP_DW0, ip); ++ sysRegWrite(LRO_RX_RING0_DIP_DW1, 0); ++ sysRegWrite(LRO_RX_RING0_DIP_DW2, 0); ++ sysRegWrite(LRO_RX_RING0_DIP_DW3, 0); ++#else ++ /* 1.1 set src/destination TCP ports */ ++ SET_PDMA_RXRING_TCP_SRC_PORT(ADMA_RX_RING1, 3423); ++ SET_PDMA_RXRING_TCP_DEST_PORT(ADMA_RX_RING1, 2301); ++ SET_PDMA_RXRING_TCP_SRC_PORT(ADMA_RX_RING2, 3423); ++ SET_PDMA_RXRING_TCP_DEST_PORT(ADMA_RX_RING2, 2301); ++ SET_PDMA_RXRING_TCP_SRC_PORT(ADMA_RX_RING3, 3423); ++ SET_PDMA_RXRING_TCP_DEST_PORT(ADMA_RX_RING3, 2301); ++ /* 1.2 set src/destination IPs */ ++ str_to_ip(&ip, "10.10.10.3"); ++ sysRegWrite(LRO_RX_RING1_SIP_DW0, ip); ++ str_to_ip(&ip, "10.10.10.100"); ++ sysRegWrite(LRO_RX_RING1_DIP_DW0, ip); ++ str_to_ip(&ip, "10.10.10.3"); ++ sysRegWrite(LRO_RX_RING2_SIP_DW0, ip); ++ str_to_ip(&ip, "10.10.10.100"); ++ sysRegWrite(LRO_RX_RING2_DIP_DW0, ip); ++ str_to_ip(&ip, "10.10.10.3"); ++ sysRegWrite(LRO_RX_RING3_SIP_DW0, ip); ++ str_to_ip(&ip, "10.10.10.100"); ++ sysRegWrite(LRO_RX_RING3_DIP_DW0, ip); ++ SET_PDMA_RXRING_MYIP_VALID(ADMA_RX_RING1, 1); ++ SET_PDMA_RXRING_MYIP_VALID(ADMA_RX_RING2, 1); ++ SET_PDMA_RXRING_MYIP_VALID(ADMA_RX_RING3, 1); ++#endif ++ ++ if (index == 0) { ++ /* 1.2 Disable DLY_INT for lro ring */ ++ SET_PDMA_LRO_DLY_INT_EN(0); ++ } else { ++ /* 1.2 Enable DLY_INT for lro ring */ ++ SET_PDMA_LRO_DLY_INT_EN(1); ++ } ++ ++ /* 1.3 LRO ring DLY_INT setting */ ++ if (index == 1) { ++ sysRegWrite(LRO_RX1_DLY_INT, DELAY_INT_INIT); ++ } else if (index == 2) { ++ sysRegWrite(LRO_RX2_DLY_INT, DELAY_INT_INIT); ++ } else if (index == 3) { ++ sysRegWrite(LRO_RX3_DLY_INT, DELAY_INT_INIT); ++ } ++#if 0 ++ /* 2.1 Set RX rings to auto-learn modes */ ++ SET_PDMA_RXRING_MODE(ADMA_RX_RING1, PDMA_RX_AUTO_LEARN); ++ SET_PDMA_RXRING_MODE(ADMA_RX_RING2, PDMA_RX_AUTO_LEARN); ++ SET_PDMA_RXRING_MODE(ADMA_RX_RING3, PDMA_RX_AUTO_LEARN); ++#else ++ /* 2.0 set rx ring mode */ ++ SET_PDMA_RXRING_MODE(ADMA_RX_RING1, PDMA_RX_FORCE_PORT); ++ SET_PDMA_RXRING_MODE(ADMA_RX_RING2, PDMA_RX_FORCE_PORT); ++ SET_PDMA_RXRING_MODE(ADMA_RX_RING3, PDMA_RX_FORCE_PORT); ++ ++ /* 2.1 IPv4 force port mode */ ++ SET_PDMA_RXRING_IPV4_FORCE_MODE(ADMA_RX_RING1, 1); ++ SET_PDMA_RXRING_IPV4_FORCE_MODE(ADMA_RX_RING2, 1); ++ SET_PDMA_RXRING_IPV4_FORCE_MODE(ADMA_RX_RING3, 1); ++#endif ++ ++ /* 2.2 Valid LRO ring */ ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING0, 1); ++ if ((index == 0) || (index == 1)) { ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING1, 1); ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING2, 0); ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING3, 0); ++ } else if (index == 2) { ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING1, 0); ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING2, 1); ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING3, 0); ++ } else { ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING1, 0); ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING2, 0); ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING3, 1); ++ } ++ ++ /* 2.3 Set AGE timer */ ++ SET_PDMA_RXRING_AGE_TIME(ADMA_RX_RING1, HW_LRO_AGE_TIME); ++ SET_PDMA_RXRING_AGE_TIME(ADMA_RX_RING2, HW_LRO_AGE_TIME); ++ SET_PDMA_RXRING_AGE_TIME(ADMA_RX_RING3, HW_LRO_AGE_TIME); ++ ++ /* 3.1 IPv4 checksum update enable */ ++ SET_PDMA_LRO_IPV4_CSUM_UPDATE_EN(1); ++ ++ /* 3.2 switch priority comparision to byte count mode */ ++ SET_PDMA_LRO_ALT_SCORE_MODE(PDMA_LRO_ALT_BYTE_CNT_MODE); ++ ++ /* 3.3 bandwidth threshold setting */ ++ SET_PDMA_LRO_BW_THRESHOLD(0); ++ ++ /* 3.4 auto-learn score delta setting */ ++ sysRegWrite(LRO_ALT_SCORE_DELTA, 0); ++ ++ /* 3.5 Set ALT timer to 500us: (unit: 20us) */ ++ SET_PDMA_LRO_ALT_REFRESH_TIMER_UNIT(25); ++ /* 3.6 Set ALT refresh timer to 1 sec. (unit: 500us) */ ++ SET_PDMA_LRO_ALT_REFRESH_TIMER(2000); ++ ++ /* 3.7 Set max AGG timer */ ++ SET_PDMA_LRO_MAX_AGG_TIME(HW_LRO_AGG_TIME); ++ ++ /* 4. Polling relinguish */ ++ while (sysRegRead(ADMA_LRO_CTRL_DW0) & PDMA_LRO_RELINGUISH) {; ++ } ++ ++ /* 5. Enable LRO */ ++ regVal = sysRegRead(ADMA_LRO_CTRL_DW0); ++ regVal |= PDMA_LRO_EN; ++ sysRegWrite(ADMA_LRO_CTRL_DW0, regVal); ++ ++ return 0; ++} ++ ++int pdma_lro_dly_int0_dvt(void) ++{ ++ return pdma_lro_dly_int_dvt(0); ++} ++ ++int pdma_lro_dly_int1_dvt(void) ++{ ++ return pdma_lro_dly_int_dvt(1); ++} ++ ++int pdma_lro_dly_int2_dvt(void) ++{ ++ return pdma_lro_dly_int_dvt(2); ++} ++ ++int pdma_lro_dly_int3_dvt(void) ++{ ++ return pdma_lro_dly_int_dvt(3); ++} ++ ++#endif /* CONFIG_RAETH_HW_LRO */ ++ ++#if defined(CONFIG_RAETH_MULTIPLE_RX_RING) ++int pdma_gdm_rxid_config(void) ++{ ++ unsigned int regVal = 0; ++ ++ printk("pdma_gdm_rxid_config()\n"); ++ ++ /* 1. Set RX ring1~3 to pse modes */ ++ SET_PDMA_RXRING_MODE(ADMA_RX_RING1, PDMA_RX_PSE_MODE); ++ SET_PDMA_RXRING_MODE(ADMA_RX_RING2, PDMA_RX_PSE_MODE); ++ SET_PDMA_RXRING_MODE(ADMA_RX_RING3, PDMA_RX_PSE_MODE); ++ ++ /* 2. Enable non-lro multiple rx */ ++ SET_PDMA_NON_LRO_MULTI_EN(1); ++ ++ return 0; ++} ++ ++int pdma_non_lro_portid_dvt(void) ++{ ++ unsigned int regVal = 0; ++ ++ printk("pdma_non_lro_portid_dvt()\n"); ++ ++ /* 1. Set GDM1 to ring3 */ ++ SET_GDM_PID1_RXID_SEL(3); ++#if 0 ++ /* 2. Set GDM2 to ring1 */ ++ SET_GDM_PID2_RXID_SEL(1); ++#endif ++ ++ /* 3. Set priority rule: pid */ ++ SET_GDM_RXID_PRI_SEL(GDM_PRI_PID); ++ ++ /* PDMA multi-rx enable */ ++ pdma_gdm_rxid_config(); ++ ++ return 0; ++} ++ ++int pdma_non_lro_stag_dvt(void) ++{ ++ unsigned int regVal = 0; ++ ++ printk("pdma_non_lro_stag_dvt()\n"); ++ ++ /* 1. Set STAG4 to ring0 */ ++ GDM_STAG_RXID_SEL(4, 0); ++ /* 2. Set STAG3 to ring1 */ ++ GDM_STAG_RXID_SEL(3, 1); ++ /* 3. Set STAG2 to ring2 */ ++ GDM_STAG_RXID_SEL(2, 2); ++ /* 4. Set STAG1 to ring3 */ ++ GDM_STAG_RXID_SEL(1, 3); ++ ++ /* 5. Set priority rule: stag/pid */ ++ SET_GDM_RXID_PRI_SEL(GDM_PRI_PID); ++ ++ /* PDMA multi-rx enable */ ++ pdma_gdm_rxid_config(); ++ ++ return 0; ++} ++ ++int pdma_non_lro_vlan_dvt(void) ++{ ++ unsigned int regVal = 0; ++ ++ printk("pdma_non_lro_vlan_dvt()\n"); ++ ++ /* 1. Set vlan priority=3 to ring1 */ ++ SET_GDM_VLAN_PRI_RXID_SEL(3, 1); ++ /* 2. Set vlan priority=2 to ring2 */ ++ SET_GDM_VLAN_PRI_RXID_SEL(2, 2); ++ /* 3. Set vlan priority=1 to ring3 */ ++ SET_GDM_VLAN_PRI_RXID_SEL(1, 3); ++ /* 4. Set vlan priority=0 to ring3 */ ++ SET_GDM_VLAN_PRI_RXID_SEL(0, 3); ++ ++ /* 1. Set vlan priority=4 to ring1 */ ++ SET_GDM_VLAN_PRI_RXID_SEL(4, 1); ++ /* 2. Set vlan priority=5 to ring2 */ ++ SET_GDM_VLAN_PRI_RXID_SEL(5, 2); ++ /* 3. Set vlan priority=6 to ring3 */ ++ SET_GDM_VLAN_PRI_RXID_SEL(6, 3); ++ /* 4. Set vlan priority=7 to ring3 */ ++ SET_GDM_VLAN_PRI_RXID_SEL(7, 3); ++ ++ /* 4. Set priority rule: vlan > pid */ ++ SET_GDM_RXID_PRI_SEL(GDM_PRI_VLAN_PID); ++ ++ /* PDMA multi-rx enable */ ++ pdma_gdm_rxid_config(); ++ ++ return 0; ++} ++ ++int pdma_non_lro_tcpack_dvt(void) ++{ ++ unsigned int regVal = 0; ++ ++ printk("pdma_non_lro_tcpack_dvt()\n"); ++ ++ /* 1. Enable TCP ACK with zero payload check */ ++ SET_GDM_TCP_ACK_WZPC(1); ++ /* 2. Set TCP ACK to ring3 */ ++ SET_GDM_TCP_ACK_RXID_SEL(3); ++ ++ /* 3. Set priority rule: ack > pid */ ++ SET_GDM_RXID_PRI_SEL(GDM_PRI_ACK_PID); ++ ++ /* PDMA multi-rx enable */ ++ pdma_gdm_rxid_config(); ++ ++ return 0; ++} ++ ++int pdma_non_lro_pri1_dvt(void) ++{ ++ unsigned int regVal = 0; ++ ++ printk("pdma_non_lro_pri1_dvt()\n"); ++ ++ /* 1. Set GDM1 to ring0 */ ++ SET_GDM_PID1_RXID_SEL(0); ++ ++ /* 2.1 Disable TCP ACK with zero payload check */ ++ SET_GDM_TCP_ACK_WZPC(0); ++ /* 2.2 Set TCP ACK to ring1 */ ++ SET_GDM_TCP_ACK_RXID_SEL(1); ++ ++ /* 3. Set vlan priority=1 to ring2 */ ++ SET_GDM_VLAN_PRI_RXID_SEL(1, 2); ++ ++ /* 4. Set priority rule: vlan > ack > pid */ ++ SET_GDM_RXID_PRI_SEL(GDM_PRI_VLAN_ACK_PID); ++ ++ /* PDMA multi-rx enable */ ++ pdma_gdm_rxid_config(); ++ ++ return 0; ++} ++ ++int pdma_non_lro_pri2_dvt(void) ++{ ++ unsigned int regVal = 0; ++ ++ printk("pdma_non_lro_pri2_dvt()\n"); ++ ++ /* 1. Set GDM1 to ring0 */ ++ SET_GDM_PID1_RXID_SEL(0); ++ ++ /* 2.1 Disable TCP ACK with zero payload check */ ++ SET_GDM_TCP_ACK_WZPC(0); ++ /* 2.2 Set TCP ACK to ring1 */ ++ SET_GDM_TCP_ACK_RXID_SEL(1); ++ ++ /* 3. Set vlan priority=1 to ring2 */ ++ SET_GDM_VLAN_PRI_RXID_SEL(1, 2); ++ ++ /* 4. Set priority rule: ack > vlan > pid */ ++ SET_GDM_RXID_PRI_SEL(GDM_PRI_ACK_VLAN_PID); ++ ++ /* PDMA multi-rx enable */ ++ pdma_gdm_rxid_config(); ++ ++ return 0; ++} ++#endif /* CONFIG_RAETH_MULTIPLE_RX_RING */ ++const static PDMA_LRO_DVT_FUNC pdma_dvt_lro_func[] = { ++#if defined(CONFIG_RAETH_HW_LRO) ++ [0] = pdma_lro_disable_dvt, /* PDMA_TEST_LRO_DISABLE */ ++ [1] = pdma_lro_force_aggre_dvt, /* PDMA_TEST_LRO_FORCE_PORT */ ++ [2] = pdma_lro_auto_aggre_dvt, /* PDMA_TEST_LRO_AUTO_LEARN */ ++ [3] = pdma_lro_auto_ipv6_dvt, /* PDMA_TEST_LRO_AUTO_IPV6 */ ++ [4] = pdma_lro_auto_myIP_dvt, /* PDMA_TEST_LRO_AUTO_MYIP */ ++ [5] = pdma_lro_force_aggre_dvt, /* PDMA_TEST_LRO_FORCE_AGGREGATE */ ++#endif /* CONFIG_RAETH_HW_LRO */ ++#if defined(CONFIG_RAETH_MULTIPLE_RX_RING) ++ [6] = pdma_non_lro_portid_dvt, /* PDMA_TEST_NON_LRO_PORT_ID */ ++ [7] = pdma_non_lro_stag_dvt, /* PDMA_TEST_NON_LRO_STAG */ ++ [8] = pdma_non_lro_vlan_dvt, /* PDMA_TEST_NON_LRO_VLAN */ ++ [9] = pdma_non_lro_tcpack_dvt, /* PDMA_TEST_NON_LRO_TCP_ACK */ ++ [10] = pdma_non_lro_pri1_dvt, /* PDMA_TEST_NON_LRO_PRI1 */ ++ [11] = pdma_non_lro_pri2_dvt, /* PDMA_TEST_NON_LRO_PRI2 */ ++#endif /* CONFIG_RAETH_MULTIPLE_RX_RING */ ++#if defined(CONFIG_RAETH_HW_LRO) ++ [12] = pdma_lro_dly_int0_dvt, /* PDMA_TEST_LRO_DLY_INT0 */ ++ [13] = pdma_lro_dly_int1_dvt, /* PDMA_TEST_LRO_DLY_INT1 */ ++ [14] = pdma_lro_dly_int2_dvt, /* PDMA_TEST_LRO_DLY_INT2 */ ++ [15] = pdma_lro_dly_int3_dvt, /* PDMA_TEST_LRO_DLY_INT3 */ ++#endif /* CONFIG_RAETH_HW_LRO */ ++}; ++ ++/* PDMA LRO test functions end */ ++ ++#if defined(CONFIG_RAETH_HW_LRO) || defined(CONFIG_RAETH_MULTIPLE_RX_RING) ++void raeth_pdma_lro_dvt(int rx_ring_no, END_DEVICE *ei_local, ++ int rx_dma_owner_idx0) ++{ ++ if (pdma_dvt_get_show_config() & PDMA_SHOW_RX_DESC) { ++ if (rx_ring_no == 1) { ++ printk("------- rt2880_eth_recv (ring1) --------\n"); ++ printk("rx_info1=0x%x\n", ++ *(unsigned int *) ++ &ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info1); ++ printk("rx_info2=0x%x\n", ++ *(unsigned int *) ++ &ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info2); ++ printk("rx_info3=0x%x\n", ++ *(unsigned int *) ++ &ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info3); ++ printk("rx_info4=0x%x\n", ++ *(unsigned int *) ++ &ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info4); ++ printk("-------------------------------\n"); ++ } else if (rx_ring_no == 2) { ++ printk("------- rt2880_eth_recv (ring2) --------\n"); ++ printk("rx_info1=0x%x\n", ++ *(unsigned int *) ++ &ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info1); ++ printk("rx_info2=0x%x\n", ++ *(unsigned int *) ++ &ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info2); ++ printk("rx_info3=0x%x\n", ++ *(unsigned int *) ++ &ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info3); ++ printk("rx_info4=0x%x\n", ++ *(unsigned int *) ++ &ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info4); ++ printk("-------------------------------\n"); ++ } else if (rx_ring_no == 3) { ++ printk("------- rt2880_eth_recv (ring3) --------\n"); ++ printk("rx_info1=0x%x\n", ++ *(unsigned int *) ++ &ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info1); ++ printk("rx_info2=0x%x\n", ++ *(unsigned int *) ++ &ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info2); ++ printk("rx_info3=0x%x\n", ++ *(unsigned int *) ++ &ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info3); ++ printk("rx_info4=0x%x\n", ++ *(unsigned int *) ++ &ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info4); ++ printk("-------------------------------\n"); ++ } ++#if 0 ++ else { ++ printk("------- rt2880_eth_recv (ring0) --------\n"); ++ printk("rx_info1=0x%x\n", ++ *(unsigned int *) ++ &ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info1); ++ printk("rx_info2=0x%x\n", ++ *(unsigned int *) ++ &ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info2); ++ printk("rx_info3=0x%x\n", ++ *(unsigned int *) ++ &ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info3); ++ printk("rx_info4=0x%x\n", ++ *(unsigned int *) ++ &ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info4); ++ printk("-------------------------------\n"); ++ } ++#endif ++ } ++ if ((pdma_dvt_get_show_config() & PDMA_SHOW_DETAIL_RX_DESC) || ++ (pdma_dvt_get_lro_test_config()==PDMA_TEST_LRO_FORCE_PORT)) { ++ if (rx_ring_no == 1) { ++ printk("------- rt2880_eth_recv (ring1) --------\n"); ++ printk("rx_info1.PDP0=0x%x\n", ++ ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info1.PDP0); ++ printk("rx_info2.DDONE_bit=0x%x\n", ++ ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info2.DDONE_bit); ++ printk("rx_info2.LS0=0x%x\n", ++ ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info2.LS0); ++ printk("rx_info2.PLEN0=0x%x\n", ++ ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info2.PLEN0); ++ printk("rx_info2.TAG=0x%x\n", ++ ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info2.TAG); ++#if defined(CONFIG_ARCH_MT7623) ++ printk("rx_info2.LRO_AGG_CNT=0x%x\n", ++ ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info2.LRO_AGG_CNT); ++ printk("rx_info2.REV=0x%x\n", ++ ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info2.REV); ++#else ++ printk("rx_info2.LS1=0x%x\n", ++ ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info2.LS1); ++#endif /* CONFIG_RAETH_HW_LRO */ ++ printk("rx_info2.PLEN1=0x%x\n", ++ ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info2.PLEN1); ++ printk("rx_info3.TPID=0x%x\n", ++ ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info3.TPID); ++ printk("rx_info3.VID=0x%x\n", ++ ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info3.VID); ++ printk("rx_info4.IP6=0x%x\n", ++ ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info4.IP6); ++ printk("rx_info4.IP4=0x%x\n", ++ ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info4.IP4); ++ printk("rx_info4.IP4F=0x%x\n", ++ ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info4.IP4F); ++ printk("rx_info4.TACK=0x%x\n", ++ ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info4.TACK); ++ printk("rx_info4.L4VLD=0x%x\n", ++ ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info4.L4VLD); ++ printk("rx_info4.L4F=0x%x\n", ++ ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info4.L4F); ++ printk("rx_info4.SPORT=0x%x\n", ++ ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info4.SP); ++ printk("rx_info4.CRSN=0x%x\n", ++ ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info4.CRSN); ++ printk("rx_info4.FOE_Entry=0x%x\n", ++ ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info4.FOE_Entry); ++ printk("-------------------------------\n"); ++ } else if (rx_ring_no == 2) { ++ printk("------- rt2880_eth_recv (ring2) --------\n"); ++ printk("rx_info1.PDP0=0x%x\n", ++ ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info1.PDP0); ++ printk("rx_info2.DDONE_bit=0x%x\n", ++ ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info2.DDONE_bit); ++ printk("rx_info2.LS0=0x%x\n", ++ ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info2.LS0); ++ printk("rx_info2.PLEN0=0x%x\n", ++ ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info2.PLEN0); ++ printk("rx_info2.TAG=0x%x\n", ++ ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info2.TAG); ++#if defined(CONFIG_ARCH_MT7623) ++ printk("rx_info2.LRO_AGG_CNT=0x%x\n", ++ ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info2.LRO_AGG_CNT); ++ printk("rx_info2.REV=0x%x\n", ++ ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info2.REV); ++#else ++ printk("rx_info2.LS1=0x%x\n", ++ ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info2.LS1); ++#endif /* CONFIG_RAETH_HW_LRO */ ++ printk("rx_info2.PLEN1=0x%x\n", ++ ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info2.PLEN1); ++ printk("rx_info3.TPID=0x%x\n", ++ ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info3.TPID); ++ printk("rx_info3.VID=0x%x\n", ++ ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info3.VID); ++ printk("rx_info4.IP6=0x%x\n", ++ ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info4.IP6); ++ printk("rx_info4.IP4=0x%x\n", ++ ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info4.IP4); ++ printk("rx_info4.IP4F=0x%x\n", ++ ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info4.IP4F); ++ printk("rx_info4.TACK=0x%x\n", ++ ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info4.TACK); ++ printk("rx_info4.L4VLD=0x%x\n", ++ ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info4.L4VLD); ++ printk("rx_info4.L4F=0x%x\n", ++ ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info4.L4F); ++ printk("rx_info4.SPORT=0x%x\n", ++ ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info4.SP); ++ printk("rx_info4.CRSN=0x%x\n", ++ ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info4.CRSN); ++ printk("rx_info4.FOE_Entry=0x%x\n", ++ ei_local->rx_ring2[rx_dma_owner_idx0]. ++ rxd_info4.FOE_Entry); ++ printk("-------------------------------\n"); ++ } else if (rx_ring_no == 3) { ++ printk("------- rt2880_eth_recv (ring3) --------\n"); ++ printk("rx_info1.PDP0=0x%x\n", ++ ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info1.PDP0); ++ printk("rx_info2.DDONE_bit=0x%x\n", ++ ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info2.DDONE_bit); ++ printk("rx_info2.LS0=0x%x\n", ++ ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info2.LS0); ++ printk("rx_info2.PLEN0=0x%x\n", ++ ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info2.PLEN0); ++ printk("rx_info2.TAG=0x%x\n", ++ ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info2.TAG); ++#if defined(CONFIG_ARCH_MT7623) ++ printk("rx_info2.LRO_AGG_CNT=0x%x\n", ++ ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info2.LRO_AGG_CNT); ++ printk("rx_info2.REV=0x%x\n", ++ ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info2.REV); ++#else ++ printk("rx_info2.LS1=0x%x\n", ++ ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info2.LS1); ++#endif /* CONFIG_RAETH_HW_LRO */ ++ printk("rx_info2.PLEN1=0x%x\n", ++ ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info2.PLEN1); ++ printk("rx_info3.TPID=0x%x\n", ++ ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info3.TPID); ++ printk("rx_info3.VID=0x%x\n", ++ ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info3.VID); ++ printk("rx_info4.IP6=0x%x\n", ++ ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info4.IP6); ++ printk("rx_info4.IP4=0x%x\n", ++ ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info4.IP4); ++ printk("rx_info4.IP4F=0x%x\n", ++ ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info4.IP4F); ++ printk("rx_info4.TACK=0x%x\n", ++ ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info4.TACK); ++ printk("rx_info4.L4VLD=0x%x\n", ++ ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info4.L4VLD); ++ printk("rx_info4.L4F=0x%x\n", ++ ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info4.L4F); ++ printk("rx_info4.SPORT=0x%x\n", ++ ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info4.SP); ++ printk("rx_info4.CRSN=0x%x\n", ++ ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info4.CRSN); ++ printk("rx_info4.FOE_Entry=0x%x\n", ++ ei_local->rx_ring3[rx_dma_owner_idx0]. ++ rxd_info4.FOE_Entry); ++ printk("-------------------------------\n"); ++ } ++#if 0 ++ else { ++ printk("------- rt2880_eth_recv (ring0) --------\n"); ++ printk("rx_info1.PDP0=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info1.PDP0); ++ printk("rx_info2.DDONE_bit=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info2.DDONE_bit); ++ printk("rx_info2.LS0=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info2.LS0); ++ printk("rx_info2.PLEN0=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info2.PLEN0); ++ printk("rx_info2.TAG=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info2.TAG); ++ printk("rx_info2.LS1=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info2.LS1); ++ printk("rx_info2.PLEN1=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info2.PLEN1); ++ printk("rx_info3.TPID=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info3.TPID); ++ printk("rx_info3.VID=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info3.VID); ++ printk("rx_info4.IP6=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info4.IP6); ++ printk("rx_info4.IP4=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info4.IP4); ++ printk("rx_info4.IP4F=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info4.IP4F); ++ printk("rx_info4.TACK=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info4.TACK); ++ printk("rx_info4.L4VLD=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info4.L4VLD); ++ printk("rx_info4.L4F=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info4.L4F); ++ printk("rx_info4.SPORT=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info4.SP); ++ printk("rx_info4.CRSN=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info4.CRSN); ++ printk("rx_info4.FOE_Entry=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info4.FOE_Entry); ++ printk("-------------------------------\n"); ++ } ++#endif ++ } ++ if (pdma_dvt_get_lro_test_config() == PDMA_TEST_LRO_FORCE_AGGREGATE) { ++ if (rx_ring_no == 1) { ++ printk("PASS!!! => RING1: rxd_info1.PDP0=0x%x\n", ++ ei_local->rx_ring1[rx_dma_owner_idx0]. ++ rxd_info1.PDP0); ++ skb_dump(ei_local->netrx1_skbuf[rx_dma_owner_idx0]); ++ pdma_dvt_reset_config(); ++ } ++ } ++} ++#endif ++ ++int pdma_dvt_show_ctrl(int par1, int par2) ++{ ++ if (par2 == 0) ++ g_pdma_dvt_show_config = 0; ++ else ++ g_pdma_dvt_show_config |= (1 << par2); ++ ++ return 0; ++} ++ ++int pdma_dvt_test_rx_ctrl(int par1, int par2) ++{ ++ if (par2 == 0) ++ g_pdma_dvt_rx_test_config = 0; ++ else ++ g_pdma_dvt_rx_test_config |= (1 << par2); ++ ++ return 0; ++} ++ ++int pdma_dvt_test_tx_ctrl(int par1, int par2) ++{ ++ if (par2 == 0) ++ g_pdma_dvt_tx_test_config = 0; ++ else ++ g_pdma_dvt_tx_test_config |= (1 << par2); ++ ++ return 0; ++} ++ ++int pdma_dvt_test_debug_ctrl(int par1, int par2) ++{ ++ if (par2 == 0) ++ g_pdma_dvt_debug_test_config = 0; ++ else ++ g_pdma_dvt_debug_test_config |= (1 << par2); ++ ++ return 0; ++} ++ ++int pdma_dvt_test_lro_ctrl(int par1, int par2) ++{ ++ g_pdma_dvt_lro_test_config = par2; ++ ++#if defined(CONFIG_RAETH_HW_LRO) || defined(CONFIG_RAETH_MULTIPLE_RX_RING) ++ if (pdma_dvt_lro_func[par2]) ++ (*pdma_dvt_lro_func[par2]) (); ++#endif /* #if defined (CONFIG_RAETH_HW_LRO) */ ++ ++ return 0; ++} ++ ++unsigned int pdma_dvt_get_show_config() ++{ ++ return g_pdma_dvt_show_config; ++} ++ ++unsigned int pdma_dvt_get_rx_test_config() ++{ ++ return g_pdma_dvt_rx_test_config; ++} ++ ++unsigned int pdma_dvt_get_tx_test_config() ++{ ++ return g_pdma_dvt_tx_test_config; ++} ++ ++unsigned int pdma_dvt_get_debug_test_config() ++{ ++ return g_pdma_dvt_debug_test_config; ++} ++ ++unsigned int pdma_dvt_get_lro_test_config() ++{ ++ return g_pdma_dvt_lro_test_config; ++} ++ ++void pdma_dvt_reset_config() ++{ ++ g_pdma_dvt_show_config = 0; ++ g_pdma_dvt_rx_test_config = 0; ++ g_pdma_dvt_tx_test_config = 0; ++ g_pdma_dvt_lro_test_config = 0; ++} ++ ++void raeth_pdma_rx_desc_dvt(END_DEVICE *ei_local, int rx_dma_owner_idx0) ++{ ++#if 0 ++ unsigned int udf = 0; ++#endif ++ ++ if (pdma_dvt_get_show_config() & PDMA_SHOW_RX_DESC) { ++ printk("------- rt2880_eth_recv --------\n"); ++ printk("rx_info1=0x%x\n", ++ *(unsigned int *)&ei_local-> ++ rx_ring0[rx_dma_owner_idx0].rxd_info1); ++ printk("rx_info2=0x%x\n", ++ *(unsigned int *)&ei_local-> ++ rx_ring0[rx_dma_owner_idx0].rxd_info2); ++ printk("rx_info3=0x%x\n", ++ *(unsigned int *)&ei_local-> ++ rx_ring0[rx_dma_owner_idx0].rxd_info3); ++ printk("rx_info4=0x%x\n", ++ *(unsigned int *)&ei_local-> ++ rx_ring0[rx_dma_owner_idx0].rxd_info4); ++ printk("-------------------------------\n"); ++ } ++ if ((pdma_dvt_get_show_config() & PDMA_SHOW_DETAIL_RX_DESC) || ++ pdma_dvt_get_rx_test_config()) { ++#if 0 ++ udf = ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info4.IP6 << 5 | ++ ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info4.IP4 << 4 | ++ ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info4.IP4F << 3 | ++ ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info4.TACK << 2 | ++ ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info4.L4VLD << 1 | ++ ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info4.L4F; ++#endif ++ printk("------- rt2880_eth_recv --------\n"); ++ printk("rx_info1.PDP0=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info1.PDP0); ++ printk("rx_info2.DDONE_bit=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info2.DDONE_bit); ++ printk("rx_info2.LS0=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info2.LS0); ++ printk("rx_info2.PLEN0=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info2.PLEN0); ++ printk("rx_info2.TAG=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info2.TAG); ++#if defined(CONFIG_ARCH_MT7623) ++ printk("rx_info2.LRO_AGG_CNT=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info2.LRO_AGG_CNT); ++#else ++ printk("rx_info2.LS1=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info2.LS1); ++#endif /* CONFIG_RAETH_HW_LRO */ ++ printk("rx_info2.PLEN1=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info2.PLEN1); ++ printk("rx_info3.TPID=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info3.TPID); ++ printk("rx_info3.VID=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info3.VID); ++#if 0 ++ printk("rx_info4.UDF=0x%x\n", udf); ++#endif ++ printk("rx_info4.IP6=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info4.IP6); ++ printk("rx_info4.IP4=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info4.IP4); ++ printk("rx_info4.IP4F=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info4.IP4F); ++ printk("rx_info4.TACK=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info4.TACK); ++ printk("rx_info4.L4VLD=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info4.L4VLD); ++ printk("rx_info4.L4F=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info4.L4F); ++ printk("rx_info4.SPORT=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info4.SP); ++ printk("rx_info4.CRSN=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info4.CRSN); ++ printk("rx_info4.FOE_Entry=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info4.FOE_Entry); ++ printk("-------------------------------\n"); ++ } ++ if ((pdma_dvt_get_rx_test_config() & PDMA_TEST_RX_IPV6)) { ++ if (ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info4.IP6) { ++ printk("PASS!!! => rx_info4.IP6=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info4.IP6); ++ pdma_dvt_reset_config(); ++ } ++ } else if ((pdma_dvt_get_rx_test_config() & PDMA_TEST_RX_IPV4)) { ++ if (ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info4.IP4) { ++ printk("PASS!!! => rx_info4.IP4=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info4.IP4); ++ pdma_dvt_reset_config(); ++ } ++ } else if ((pdma_dvt_get_rx_test_config() & PDMA_TEST_RX_IPV4F)) { ++ if (ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info4.IP4F) { ++ printk("PASS!!! => rx_info4.IP4F=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info4.IP4F); ++ pdma_dvt_reset_config(); ++ } ++ } else if ((pdma_dvt_get_rx_test_config() & PDMA_TEST_RX_L4VLD)) { ++ if (ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info4.L4VLD) { ++ printk("PASS!!! => rx_info4.L4VLD=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info4.L4VLD); ++ pdma_dvt_reset_config(); ++ } ++ } else if ((pdma_dvt_get_rx_test_config() & PDMA_TEST_RX_L4F)) { ++ if (ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info4.L4F) { ++ printk("PASS!!! => rx_info4.L4F=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info4.L4F); ++ pdma_dvt_reset_config(); ++ } ++ } else if ((pdma_dvt_get_rx_test_config() & PDMA_TEST_RX_SPORT)) { ++ if (ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info4.SP == 1) { ++ g_pdma_dev_lanport++; ++ } else if (ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info4.SP == ++ 2) { ++ g_pdma_dev_wanport++; ++ } ++ if (g_pdma_dev_lanport && g_pdma_dev_wanport) { ++ printk ++ ("PASS!!! => g_pdma_dev_lanport=0x%x, g_pdma_dev_wanport=0x%x", ++ g_pdma_dev_lanport, g_pdma_dev_wanport); ++ ++ g_pdma_dev_lanport = 0; ++ g_pdma_dev_wanport = 0; ++ pdma_dvt_reset_config(); ++ } ++ } else if ((pdma_dvt_get_rx_test_config() & PDMA_TEST_RX_VID_OFF)) { ++ if (!ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info3.VID) { ++ printk("PASS!!! => rxd_info3.VID=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info3.VID); ++ pdma_dvt_reset_config(); ++ } ++ } else if ((pdma_dvt_get_rx_test_config() & PDMA_TEST_RX_VID_ON)) { ++ printk("RX data: (PDP0=%x)\n", ++ (unsigned int)ei_local-> ++ netrx0_skbuf[rx_dma_owner_idx0]->data); ++ ++ skb_dump(ei_local->netrx0_skbuf[rx_dma_owner_idx0]); ++ ++ if (ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info3.VID && ++ ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info2.TAG) { ++ printk("PASS!!! => rxd_info2.TAG=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info2.TAG); ++ printk("PASS!!! => rxd_info3.VID=0x%x\n", ++ ei_local->rx_ring0[rx_dma_owner_idx0]. ++ rxd_info3.VID); ++ pdma_dvt_reset_config(); ++ } ++ } ++} ++ ++void raeth_pdma_tx_vlan_dvt(END_DEVICE *ei_local, ++ unsigned long tx_cpu_owner_idx0) ++{ ++ if ((pdma_dvt_get_tx_test_config() & PDMA_TEST_TX_VLAN_ON)) { ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.VLAN_TAG = 0x10000 | 0xE007; /* VLAN_TAG = 0x1E007 */ ++ } else if ((pdma_dvt_get_tx_test_config() & PDMA_TEST_TX_VLAN_ZERO)) { ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.VLAN_TAG = 0x10000 | 0x0000; /* VLAN_TAG = 0x10000 */ ++ } else if ((pdma_dvt_get_tx_test_config() & PDMA_TEST_TX_VLAN_MAX)) { ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.VLAN_TAG = 0x10000 | 0xFFFF; /* VLAN_TAG = 0x1FFFF */ ++ } ++} ++ ++void raeth_pdma_tx_desc_dvt(END_DEVICE *ei_local, ++ unsigned long tx_cpu_owner_idx0) ++{ ++ if (PDMA_TEST_RX_UDF == pdma_dvt_get_rx_test_config()) { ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.FPORT = 4; /* PPE */ ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.UDF = 0x2F; ++ } ++ if (pdma_dvt_get_show_config() & PDMA_SHOW_TX_DESC) { ++ printk("------- rt2880_eth_send --------\n"); ++ printk("tx_info1=%x\n", ++ *(unsigned int *)&ei_local-> ++ tx_ring0[tx_cpu_owner_idx0].txd_info1); ++ printk("tx_info2=%x\n", ++ *(unsigned int *)&ei_local-> ++ tx_ring0[tx_cpu_owner_idx0].txd_info2); ++ printk("tx_info3=%x\n", ++ *(unsigned int *)&ei_local-> ++ tx_ring0[tx_cpu_owner_idx0].txd_info3); ++ printk("tx_info4=%x\n", ++ *(unsigned int *)&ei_local-> ++ tx_ring0[tx_cpu_owner_idx0].txd_info4); ++ printk("--------------------------------\n"); ++ } ++ if ((pdma_dvt_get_show_config() & PDMA_SHOW_DETAIL_TX_DESC) || ++ pdma_dvt_get_tx_test_config()) { ++ printk("------- rt2880_eth_send --------\n"); ++ printk("tx_info1.SDP0=%x\n", ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info1.SDP0); ++ printk("tx_info2.DDONE_bit=%x\n", ++ ei_local->tx_ring0[tx_cpu_owner_idx0]. ++ txd_info2.DDONE_bit); ++ printk("tx_info2.LS0_bit=%x\n", ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info2.LS0_bit); ++ printk("tx_info2.SDL0=%x\n", ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info2.SDL0); ++ printk("tx_info2.BURST_bit=%x\n", ++ ei_local->tx_ring0[tx_cpu_owner_idx0]. ++ txd_info2.BURST_bit); ++ printk("tx_info2.LS1_bit=%x\n", ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info2.LS1_bit); ++ printk("tx_info2.SDL1=%x\n", ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info2.SDL1); ++ printk("tx_info3.SDP1=%x\n", ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info3.SDP1); ++ printk("tx_info4.TUI_CO=%x\n", ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.TUI_CO); ++ printk("tx_info4.TSO=%x\n", ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.TSO); ++ printk("tx_info4.FPORT=%x\n", ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.FPORT); ++ printk("tx_info4.UDF=%x\n", ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.UDF); ++ printk("tx_info4.RESV=%x\n", ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.RESV); ++ printk("tx_info4.VLAN_TAG=%x\n", ++ ei_local->tx_ring0[tx_cpu_owner_idx0]. ++ txd_info4.VLAN_TAG); ++ printk("--------------------------------\n"); ++ } ++ if ((pdma_dvt_get_tx_test_config() & PDMA_TEST_TX_LAN_SPORT)) { ++ if (ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.FPORT == 1) { ++ printk("PASS!!! => txd_info4.FPORT=0x%x\n", ++ ei_local->tx_ring0[tx_cpu_owner_idx0]. ++ txd_info4.FPORT); ++ pdma_dvt_reset_config(); ++ } ++ } else if ((pdma_dvt_get_tx_test_config() & PDMA_TEST_TX_WAN_SPORT)) { ++ if (ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.FPORT == 2) { ++ printk("PASS!!! => txd_info4.FPORT=0x%x\n", ++ ei_local->tx_ring0[tx_cpu_owner_idx0]. ++ txd_info4.FPORT); ++ pdma_dvt_reset_config(); ++ } ++ } else if ((pdma_dvt_get_tx_test_config() & PDMA_TEST_TX_VLAN_ON)) { ++ if (ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.VLAN_TAG) { ++ printk("PASS!!! => txd_info4.VLAN_TAG=0x%x\n", ++ ei_local->tx_ring0[tx_cpu_owner_idx0]. ++ txd_info4.VLAN_TAG); ++ /* pdma_dvt_reset_config(); */ ++ } ++ } else if ((pdma_dvt_get_tx_test_config() & PDMA_TEST_TX_VLAN_OFF)) { ++ if (!ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.VLAN_TAG) { ++ printk("PASS!!! => txd_info4.VLAN_TAG=0x%x\n", ++ ei_local->tx_ring0[tx_cpu_owner_idx0]. ++ txd_info4.VLAN_TAG); ++ pdma_dvt_reset_config(); ++ } ++ } else if ((pdma_dvt_get_tx_test_config() & PDMA_TEST_TX_VLAN_ZERO)) { ++ if (ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.VLAN_TAG) { ++ printk("PASS!!! => txd_info4.VLAN_TAG=0x%x\n", ++ ei_local->tx_ring0[tx_cpu_owner_idx0]. ++ txd_info4.VLAN_TAG); ++ /* pdma_dvt_reset_config(); */ ++ } ++ } else if ((pdma_dvt_get_tx_test_config() & PDMA_TEST_TX_VLAN_MAX)) { ++ if (ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.VLAN_TAG) { ++ printk("PASS!!! => txd_info4.VLAN_TAG=0x%x\n", ++ ei_local->tx_ring0[tx_cpu_owner_idx0]. ++ txd_info4.VLAN_TAG); ++ /* pdma_dvt_reset_config(); */ ++ } ++ } ++} ++ ++void raeth_pdma_lro_dly_int_dvt(void) ++{ ++ unsigned int reg_int_val; ++ ++ reg_int_val = sysRegRead(RAETH_FE_INT_STATUS); ++ ++ if (pdma_dvt_get_lro_test_config() == PDMA_TEST_LRO_DLY_INT0) { ++ if ((reg_int_val & RX_DLY_INT)) { ++ printk("PASS!!! => reg_int_val=0x%x\n", reg_int_val); ++ pdma_dvt_reset_config(); ++ } ++ } else if (pdma_dvt_get_lro_test_config() == PDMA_TEST_LRO_DLY_INT1) { ++ if ((reg_int_val & RING1_RX_DLY_INT)) { ++ printk("PASS!!! => reg_int_val=0x%x\n", reg_int_val); ++ pdma_dvt_reset_config(); ++ } ++ } else if (pdma_dvt_get_lro_test_config() == PDMA_TEST_LRO_DLY_INT2) { ++ if ((reg_int_val & RING2_RX_DLY_INT)) { ++ printk("PASS!!! => reg_int_val=0x%x\n", reg_int_val); ++ pdma_dvt_reset_config(); ++ } ++ } else if (pdma_dvt_get_lro_test_config() == PDMA_TEST_LRO_DLY_INT3) { ++ if ((reg_int_val & RING3_RX_DLY_INT)) { ++ printk("PASS!!! => reg_int_val=0x%x\n", reg_int_val); ++ pdma_dvt_reset_config(); ++ } ++ } ++} ++ ++void pdma_dvt_set_dma_mode(void) ++{ ++#if defined(CONFIG_RAETH_PDMA_LEGACY_MODE) ++ unsigned int regVal; ++ regVal = sysRegRead(ADMA_LRO_CTRL_DW3); ++ regVal &= ~(BIT(15)); ++ sysRegWrite(ADMA_LRO_CTRL_DW3, regVal); ++#endif /* CONFIG_RAETH_PDMA_DVT */ ++} ++ +diff --git a/drivers/net/ethernet/raeth/dvt/raether_pdma_dvt.h b/drivers/net/ethernet/raeth/dvt/raether_pdma_dvt.h +new file mode 100755 +index 0000000..600aab7 +--- /dev/null ++++ b/drivers/net/ethernet/raeth/dvt/raether_pdma_dvt.h +@@ -0,0 +1,75 @@ ++/* Show controls */ ++#define PDMA_SHOW_RX_DESC (1 << 1) ++#define PDMA_SHOW_TX_DESC (1 << 2) ++#define PDMA_SHOW_DETAIL_RX_DESC (1 << 3) ++#define PDMA_SHOW_DETAIL_TX_DESC (1 << 4) ++ ++/* Rx test controls */ ++#define PDMA_TEST_RX_UDF (1 << 1) ++#define PDMA_TEST_RX_IPV6 (1 << 2) ++#define PDMA_TEST_RX_IPV4 (1 << 3) ++#define PDMA_TEST_RX_IPV4F (1 << 4) ++#define PDMA_TEST_RX_L4VLD (1 << 5) ++#define PDMA_TEST_RX_L4F (1 << 6) ++#define PDMA_TEST_RX_SPORT (1 << 7) ++#define PDMA_TEST_RX_VID_ON (1 << 8) ++#define PDMA_TEST_RX_VID_OFF (1 << 9) ++ ++/* Tx test controls */ ++#define PDMA_TEST_TX_LAN_SPORT (1 << 1) ++#define PDMA_TEST_TX_WAN_SPORT (1 << 2) ++#define PDMA_TEST_TX_VLAN_ON (1 << 3) ++#define PDMA_TEST_TX_VLAN_OFF (1 << 4) ++#define PDMA_TEST_TX_VLAN_ZERO (1 << 5) ++#define PDMA_TEST_TX_VLAN_MAX (1 << 6) ++#define PDMA_TEST_TX_PDMA_LPK (1 << 31) ++ ++/* Debug controls */ ++#define PDMA_TEST_TSO_DEBUG (1 << 1) ++ ++/* LRO test controls */ ++typedef int (*PDMA_LRO_DVT_FUNC) (void); ++ ++#define PDMA_TEST_LRO_DISABLE (0) ++#define PDMA_TEST_LRO_FORCE_PORT (1) ++#define PDMA_TEST_LRO_AUTO_LEARN (2) ++#define PDMA_TEST_LRO_AUTO_IPV6 (3) ++#define PDMA_TEST_LRO_AUTO_MYIP (4) ++#define PDMA_TEST_LRO_FORCE_AGGREGATE (5) ++#define PDMA_TEST_NON_LRO_PORT_ID (6) ++#define PDMA_TEST_NON_LRO_STAG (7) ++#define PDMA_TEST_NON_LRO_VLAN (8) ++#define PDMA_TEST_NON_LRO_TCP_ACK (9) ++#define PDMA_TEST_NON_LRO_PRI1 (10) ++#define PDMA_TEST_NON_LRO_PRI2 (11) ++#define PDMA_TEST_LRO_DLY_INT0 (12) ++#define PDMA_TEST_LRO_DLY_INT1 (13) ++#define PDMA_TEST_LRO_DLY_INT2 (14) ++#define PDMA_TEST_LRO_DLY_INT3 (15) ++ ++void skb_dump(struct sk_buff *sk); ++ ++int pdma_dvt_show_ctrl(int par1, int par2); ++int pdma_dvt_test_rx_ctrl(int par1, int par2); ++int pdma_dvt_test_tx_ctrl(int par1, int par2); ++int pdma_dvt_test_debug_ctrl(int par1, int par2); ++int pdma_dvt_test_lro_ctrl(int par1, int par2); ++ ++unsigned int pdma_dvt_get_show_config(void); ++unsigned int pdma_dvt_get_rx_test_config(void); ++unsigned int pdma_dvt_get_tx_test_config(void); ++unsigned int pdma_dvt_get_debug_test_config(void); ++unsigned int pdma_dvt_get_lro_test_config(void); ++void pdma_dvt_reset_config(void); ++ ++void raeth_pdma_rx_desc_dvt(END_DEVICE *ei_local, int rx_dma_owner_idx0); ++void raeth_pdma_tx_vlan_dvt(END_DEVICE *ei_local, ++ unsigned long tx_cpu_owner_idx0); ++void raeth_pdma_tx_desc_dvt(END_DEVICE *ei_local, ++ unsigned long tx_cpu_owner_idx0); ++ ++void raeth_pdma_lro_dvt(int rx_ring_no, END_DEVICE *ei_local, ++ int rx_dma_owner_idx0); ++void raeth_pdma_lro_dly_int_dvt(void); ++void pdma_dvt_set_dma_mode(void); ++ +diff --git a/drivers/net/ethernet/raeth/ethtool_readme.txt b/drivers/net/ethernet/raeth/ethtool_readme.txt +new file mode 100644 +index 0000000..10e918b +--- /dev/null ++++ b/drivers/net/ethernet/raeth/ethtool_readme.txt +@@ -0,0 +1,44 @@ ++ ++Ethtool readme for selecting different PHY address. ++ ++Before doing any ethtool command you should make sure the current PHY ++address is expected. The default PHY address is 1(port 1). ++ ++You can change current PHY address to X(0~4) by doing follow command: ++# echo X > /proc/rt2880/gmac ++ ++Ethtool command also would show the current PHY address as following. ++ ++# ethtool eth2 ++Settings for eth2: ++ Supported ports: [ TP MII ] ++ Supported link modes: 10baseT/Half 10baseT/Full ++ 100baseT/Half 100baseT/Full ++ Supports auto-negotiation: Yes ++ Advertised link modes: 10baseT/Half 10baseT/Full ++ 100baseT/Half 100baseT/Full ++ Advertised auto-negotiation: No ++ Speed: 10Mb/s ++ Duplex: Full ++ Port: MII ++ PHYAD: 1 ++ Transceiver: internal ++ Auto-negotiation: off ++ Current message level: 0x00000000 (0) ++ Link detected: no ++ ++ ++The "PHYAD" field shows the current PHY address. ++ ++ ++ ++Usage example ++1) show port1 info ++# echo 1 > /proc/rt2880/gmac # change phy address to 1 ++# ethtool eth2 ++ ++2) show port0 info ++# echo 0 > /proc/rt2880/gmac # change phy address to 0 ++# ethtool eth2 ++ ++ +diff --git a/drivers/net/ethernet/raeth/mcast.c b/drivers/net/ethernet/raeth/mcast.c +new file mode 100644 +index 0000000..d796b03 +--- /dev/null ++++ b/drivers/net/ethernet/raeth/mcast.c +@@ -0,0 +1,187 @@ ++#include <linux/config.h> ++#include <linux/version.h> ++#include <linux/module.h> ++#include <linux/skbuff.h> ++#include <linux/kernel.h> ++#include <linux/init.h> ++#include <linux/types.h> ++#include <linux/netdevice.h> ++#include <linux/if_vlan.h> ++ ++ ++#define MAX_MCAST_ENTRY 16 ++#define AGEING_TIME 5 //Unit: Sec ++#define MAC_ARG(x) ((u8*)(x))[0],((u8*)(x))[1],((u8*)(x))[2], \ ++ ((u8*)(x))[3],((u8*)(x))[4],((u8*)(x))[5] ++ ++//#define MCAST_DEBUG ++#ifdef MCAST_DEBUG ++#define MCAST_PRINT(fmt, args...) printk(KERN_INFO fmt, ## args) ++#else ++#define MCAST_PRINT(fmt, args...) { } ++#endif ++ ++typedef struct { ++ uint8_t src_mac[6]; ++ uint8_t dst_mac[6]; ++ uint16_t vlan_id; ++ uint32_t valid; ++ uint32_t use_count; ++ unsigned long ageout; ++} mcast_entry; ++ ++mcast_entry mcast_tbl[MAX_MCAST_ENTRY]; ++atomic_t mcast_entry_num=ATOMIC_INIT(0); ++DECLARE_MUTEX(mtbl_lock); ++ ++uint32_t inline is_multicast_pkt(uint8_t *mac) ++{ ++ if(mac[0]==0x01 && mac[1]==0x00 && mac[2]==0x5E) { ++ return 1; ++ }else{ ++ return 0; ++ } ++} ++ ++int32_t inline mcast_entry_get(uint16_t vlan_id, uint8_t *src_mac, uint8_t *dst_mac) ++{ ++ int i=0; ++ ++ for(i=0;i<MAX_MCAST_ENTRY;i++) { ++ if( (mcast_tbl[i].vlan_id == vlan_id) && ++ memcmp(mcast_tbl[i].src_mac,src_mac, 6)==0 && ++ memcmp(mcast_tbl[i].dst_mac, dst_mac, 6)==0 && ++ mcast_tbl[i].valid == 1) { ++ return i; ++ } ++ } ++ return -1; ++} ++ ++int inline __add_mcast_entry(uint16_t vlan_id, uint8_t *src_mac, uint8_t *dst_mac) ++{ ++ int i=0; ++ ++ // use empty or ageout entry ++ for(i=0;i<MAX_MCAST_ENTRY;i++) { ++ if( mcast_tbl[i].valid==0 || ++ time_after(jiffies, mcast_tbl[i].ageout)) { ++ ++ if(mcast_tbl[i].valid==0) { ++ atomic_inc(&mcast_entry_num); ++ } ++ mcast_tbl[i].vlan_id = vlan_id; ++ memcpy(mcast_tbl[i].src_mac, src_mac, 6); ++ memcpy(mcast_tbl[i].dst_mac, dst_mac, 6); ++ mcast_tbl[i].valid=1; ++ mcast_tbl[i].use_count=1; ++ mcast_tbl[i].ageout=jiffies + AGEING_TIME * HZ; ++ ++ return 1; ++ } ++ } ++ ++ MCAST_PRINT("RAETH: Multicast Table is FULL!!\n"); ++ return 0; ++} ++ ++int inline mcast_entry_ins(uint16_t vlan_id, uint8_t *src_mac, uint8_t *dst_mac) ++{ ++ int entry_num=0, ret=0; ++ ++ down(&mtbl_lock); ++ if((entry_num = mcast_entry_get(vlan_id, src_mac, dst_mac)) >=0) { ++ mcast_tbl[entry_num].use_count++; ++ mcast_tbl[entry_num].ageout=jiffies + AGEING_TIME * HZ; ++ MCAST_PRINT("%s: Update %0X:%0X:%0X:%0X:%0X:%0X's use_count=%d\n" \ ++ ,__FUNCTION__, MAC_ARG(dst_mac), mcast_tbl[entry_num].use_count); ++ ret = 1; ++ }else { //if entry not found, create new entry. ++ MCAST_PRINT("%s: Create new entry %0X:%0X:%0X:%0X:%0X:%0X\n", \ ++ __FUNCTION__, MAC_ARG(dst_mac)); ++ ret = __add_mcast_entry(vlan_id, src_mac,dst_mac); ++ } ++ ++ up(&mtbl_lock); ++ return ret; ++ ++} ++ ++ ++/* ++ * Return: ++ * 0: entry found ++ * 1: entry not found ++ */ ++int inline mcast_entry_del(uint16_t vlan_id, uint8_t *src_mac, uint8_t *dst_mac) ++{ ++ int entry_num; ++ ++ down(&mtbl_lock); ++ if((entry_num = mcast_entry_get(vlan_id, src_mac, dst_mac)) >=0) { ++ if((--mcast_tbl[entry_num].use_count)==0) { ++ MCAST_PRINT("%s: %0X:%0X:%0X:%0X:%0X:%0X (entry_num=%d)\n", \ ++ __FUNCTION__, MAC_ARG(dst_mac), entry_num); ++ mcast_tbl[entry_num].valid=0; ++ atomic_dec(&mcast_entry_num); ++ } ++ up(&mtbl_lock); ++ return 0; ++ }else { ++ /* this multicast packet was not sent by meself, just ignore it */ ++ up(&mtbl_lock); ++ return 1; ++ } ++} ++ ++/* ++ * Return ++ * 0: drop packet ++ * 1: continue ++ */ ++int32_t mcast_rx(struct sk_buff * skb) ++{ ++ struct vlan_ethhdr *eth = (struct vlan_ethhdr *)(skb->data-ETH_HLEN); ++ ++ /* if we do not send multicast packet before, ++ * we don't need to check re-inject multicast packet. ++ */ ++ if (atomic_read(&mcast_entry_num)==0) { ++ return 1; ++ } ++ ++ ++ if(is_multicast_pkt(eth->h_dest)) { ++ MCAST_PRINT("%s: %0X:%0X:%0X:%0X:%0X:%0X\n", __FUNCTION__, \ ++ MAC_ARG(eth->h_dest)); ++ ++ if(ntohs(eth->h_vlan_proto)==0x8100) { ++ return mcast_entry_del(eth->h_vlan_TCI, eth->h_source, eth->h_dest); ++ } else { ++ return mcast_entry_del(0, eth->h_source, eth->h_dest); ++ } ++ } ++ ++ return 1; ++} ++ ++ ++int32_t mcast_tx(struct sk_buff *skb) ++{ ++ struct vlan_ethhdr *eth = (struct vlan_ethhdr *)(skb->data); ++ ++ ++ if(is_multicast_pkt(eth->h_dest)) { ++ MCAST_PRINT("%s: %0X:%0X:%0X:%0X:%0X:%0X\n", __FUNCTION__,\ ++ MAC_ARG(eth->h_dest)); ++ ++ if(ntohs(eth->h_vlan_proto)==0x8100) { ++ mcast_entry_ins(eth->h_vlan_TCI, eth->h_source, eth->h_dest); ++ } else { ++ mcast_entry_ins(0, eth->h_source, eth->h_dest); ++ } ++ } ++ ++ return 1; ++} ++ +diff --git a/drivers/net/ethernet/raeth/mii_mgr.c b/drivers/net/ethernet/raeth/mii_mgr.c +new file mode 100644 +index 0000000..77a47f1 +--- /dev/null ++++ b/drivers/net/ethernet/raeth/mii_mgr.c +@@ -0,0 +1,603 @@ ++#include <linux/module.h> ++#include <linux/version.h> ++#include <linux/netdevice.h> ++ ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++#include <asm/rt2880/rt_mmap.h> ++#endif ++ ++#include "ra2882ethreg.h" ++#include "raether.h" ++ ++ ++#if defined (CONFIG_RALINK_RT3052) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_MT7628) ++#define PHY_CONTROL_0 0xC0 ++#define PHY_CONTROL_1 0xC4 ++#define MDIO_PHY_CONTROL_0 (RALINK_ETH_SW_BASE + PHY_CONTROL_0) ++#define MDIO_PHY_CONTROL_1 (RALINK_ETH_SW_BASE + PHY_CONTROL_1) ++ ++#define GPIO_MDIO_BIT (1<<7) ++#define GPIO_PURPOSE_SELECT 0x60 ++#define GPIO_PRUPOSE (RALINK_SYSCTL_BASE + GPIO_PURPOSE_SELECT) ++ ++#elif defined (CONFIG_RALINK_RT6855) || defined (CONFIG_RALINK_RT6855A) ++ ++#define PHY_CONTROL_0 0x7004 ++#define MDIO_PHY_CONTROL_0 (RALINK_ETH_SW_BASE + PHY_CONTROL_0) ++#define enable_mdio(x) ++ ++#elif defined (CONFIG_RALINK_MT7620) ++ ++#define PHY_CONTROL_0 0x7004 ++#define MDIO_PHY_CONTROL_0 (RALINK_ETH_SW_BASE + PHY_CONTROL_0) ++#define enable_mdio(x) ++ ++#elif defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++ ++#define PHY_CONTROL_0 0x0004 ++#define MDIO_PHY_CONTROL_0 (RALINK_ETH_SW_BASE + PHY_CONTROL_0) ++#define enable_mdio(x) ++ ++#else ++#define PHY_CONTROL_0 0x00 ++#define PHY_CONTROL_1 0x04 ++#define MDIO_PHY_CONTROL_0 (RALINK_FRAME_ENGINE_BASE + PHY_CONTROL_0) ++#define MDIO_PHY_CONTROL_1 (RALINK_FRAME_ENGINE_BASE + PHY_CONTROL_1) ++#define enable_mdio(x) ++#endif ++ ++#if defined (CONFIG_RALINK_RT3052) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_MT7628) ++void enable_mdio(int enable) ++{ ++#if !defined (CONFIG_P5_MAC_TO_PHY_MODE) && !defined(CONFIG_GE1_RGMII_AN) && !defined(CONFIG_GE2_RGMII_AN) && \ ++ !defined (CONFIG_GE1_MII_AN) && !defined (CONFIG_GE2_MII_AN) && !defined (CONFIG_RALINK_MT7628) ++ u32 data = sysRegRead(GPIO_PRUPOSE); ++ if (enable) ++ data &= ~GPIO_MDIO_BIT; ++ else ++ data |= GPIO_MDIO_BIT; ++ sysRegWrite(GPIO_PRUPOSE, data); ++#endif ++} ++#endif ++ ++#if defined (CONFIG_RALINK_RT6855) || defined (CONFIG_RALINK_RT6855A) ++ ++u32 mii_mgr_read(u32 phy_addr, u32 phy_register, u32 *read_data) ++{ ++ u32 volatile status = 0; ++ u32 rc = 0; ++ unsigned long volatile t_start = jiffies; ++ u32 volatile data = 0; ++ ++ /* We enable mdio gpio purpose register, and disable it when exit. */ ++ enable_mdio(1); ++ ++ // make sure previous read operation is complete ++ while (1) { ++ // 0 : Read/write operation complete ++ if(!( sysRegRead(MDIO_PHY_CONTROL_0) & (0x1 << 31))) ++ { ++ break; ++ } ++ else if (time_after(jiffies, t_start + 5*HZ)) { ++ enable_mdio(0); ++ printk("\n MDIO Read operation is ongoing !!\n"); ++ return rc; ++ } ++ } ++ ++ data = (0x01 << 16) | (0x02 << 18) | (phy_addr << 20) | (phy_register << 25); ++ sysRegWrite(MDIO_PHY_CONTROL_0, data); ++ data |= (1<<31); ++ sysRegWrite(MDIO_PHY_CONTROL_0, data); ++ //printk("\n Set Command [0x%08X] to PHY !!\n",MDIO_PHY_CONTROL_0); ++ ++ ++ // make sure read operation is complete ++ t_start = jiffies; ++ while (1) { ++ if (!(sysRegRead(MDIO_PHY_CONTROL_0) & (0x1 << 31))) { ++ status = sysRegRead(MDIO_PHY_CONTROL_0); ++ *read_data = (u32)(status & 0x0000FFFF); ++ ++ enable_mdio(0); ++ return 1; ++ } ++ else if (time_after(jiffies, t_start+5*HZ)) { ++ enable_mdio(0); ++ printk("\n MDIO Read operation is ongoing and Time Out!!\n"); ++ return 0; ++ } ++ } ++} ++ ++u32 mii_mgr_write(u32 phy_addr, u32 phy_register, u32 write_data) ++{ ++ unsigned long volatile t_start=jiffies; ++ u32 volatile data; ++ ++ enable_mdio(1); ++ ++ // make sure previous write operation is complete ++ while(1) { ++ if (!(sysRegRead(MDIO_PHY_CONTROL_0) & (0x1 << 31))) ++ { ++ break; ++ } ++ else if (time_after(jiffies, t_start + 5 * HZ)) { ++ enable_mdio(0); ++ printk("\n MDIO Write operation ongoing\n"); ++ return 0; ++ } ++ } ++ ++ data = (0x01 << 16)| (1<<18) | (phy_addr << 20) | (phy_register << 25) | write_data; ++ sysRegWrite(MDIO_PHY_CONTROL_0, data); ++ data |= (1<<31); ++ sysRegWrite(MDIO_PHY_CONTROL_0, data); //start operation ++ //printk("\n Set Command [0x%08X] to PHY !!\n",MDIO_PHY_CONTROL_0); ++ ++ t_start = jiffies; ++ ++ // make sure write operation is complete ++ while (1) { ++ if (!(sysRegRead(MDIO_PHY_CONTROL_0) & (0x1 << 31))) //0 : Read/write operation complete ++ { ++ enable_mdio(0); ++ return 1; ++ } ++ else if (time_after(jiffies, t_start + 5 * HZ)) { ++ enable_mdio(0); ++ printk("\n MDIO Write operation Time Out\n"); ++ return 0; ++ } ++ } ++} ++#elif defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7620) || defined (CONFIG_ARCH_MT7623) ++ ++u32 __mii_mgr_read(u32 phy_addr, u32 phy_register, u32 *read_data) ++{ ++ u32 volatile status = 0; ++ u32 rc = 0; ++ unsigned long volatile t_start = jiffies; ++ u32 volatile data = 0; ++ ++ /* We enable mdio gpio purpose register, and disable it when exit. */ ++ enable_mdio(1); ++ ++ // make sure previous read operation is complete ++ while (1) { ++ // 0 : Read/write operation complete ++ if(!( sysRegRead(MDIO_PHY_CONTROL_0) & (0x1 << 31))) ++ { ++ break; ++ } ++ else if (time_after(jiffies, t_start + 5*HZ)) { ++ enable_mdio(0); ++ printk("\n MDIO Read operation is ongoing !!\n"); ++ return rc; ++ } ++ } ++ ++ data = (0x01 << 16) | (0x02 << 18) | (phy_addr << 20) | (phy_register << 25); ++ sysRegWrite(MDIO_PHY_CONTROL_0, data); ++ data |= (1<<31); ++ sysRegWrite(MDIO_PHY_CONTROL_0, data); ++ //printk("\n Set Command [0x%08X] = [0x%08X] to PHY !!\n",MDIO_PHY_CONTROL_0, data); ++ ++ ++ // make sure read operation is complete ++ t_start = jiffies; ++ while (1) { ++ if (!(sysRegRead(MDIO_PHY_CONTROL_0) & (0x1 << 31))) { ++ status = sysRegRead(MDIO_PHY_CONTROL_0); ++ *read_data = (u32)(status & 0x0000FFFF); ++ ++ enable_mdio(0); ++ return 1; ++ } ++ else if (time_after(jiffies, t_start+5*HZ)) { ++ enable_mdio(0); ++ printk("\n MDIO Read operation is ongoing and Time Out!!\n"); ++ return 0; ++ } ++ } ++} ++ ++u32 __mii_mgr_write(u32 phy_addr, u32 phy_register, u32 write_data) ++{ ++ unsigned long volatile t_start=jiffies; ++ u32 volatile data; ++ ++ enable_mdio(1); ++ ++ // make sure previous write operation is complete ++ while(1) { ++ if (!(sysRegRead(MDIO_PHY_CONTROL_0) & (0x1 << 31))) ++ { ++ break; ++ } ++ else if (time_after(jiffies, t_start + 5 * HZ)) { ++ enable_mdio(0); ++ printk("\n MDIO Write operation ongoing\n"); ++ return 0; ++ } ++ } ++ ++ data = (0x01 << 16)| (1<<18) | (phy_addr << 20) | (phy_register << 25) | write_data; ++ sysRegWrite(MDIO_PHY_CONTROL_0, data); ++ data |= (1<<31); ++ sysRegWrite(MDIO_PHY_CONTROL_0, data); //start operation ++ //printk("\n Set Command [0x%08X] to PHY !!\n",MDIO_PHY_CONTROL_0); ++ ++ t_start = jiffies; ++ ++ // make sure write operation is complete ++ while (1) { ++ if (!(sysRegRead(MDIO_PHY_CONTROL_0) & (0x1 << 31))) //0 : Read/write operation complete ++ { ++ enable_mdio(0); ++ return 1; ++ } ++ else if (time_after(jiffies, t_start + 5 * HZ)) { ++ enable_mdio(0); ++ printk("\n MDIO Write operation Time Out\n"); ++ return 0; ++ } ++ } ++} ++ ++u32 mii_mgr_read(u32 phy_addr, u32 phy_register, u32 *read_data) ++{ ++#if defined (CONFIG_GE1_RGMII_FORCE_1000) || defined (CONFIG_GE1_TRGMII_FORCE_1200) || defined (CONFIG_GE1_TRGMII_FORCE_2000) || defined (CONFIG_GE1_TRGMII_FORCE_2600) || defined (CONFIG_P5_RGMII_TO_MT7530_MODE) ++ u32 low_word; ++ u32 high_word; ++ u32 an_status = 0; ++ ++ if(phy_addr==31) ++ { ++ an_status = (*(unsigned long *)(ESW_PHY_POLLING) & (1<<31)); ++ if(an_status){ ++ *(unsigned long *)(ESW_PHY_POLLING) &= ~(1<<31);//(AN polling off) ++ } ++ //phase1: write page address phase ++ if(__mii_mgr_write(phy_addr, 0x1f, ((phy_register >> 6) & 0x3FF))) { ++ //phase2: write address & read low word phase ++ if(__mii_mgr_read(phy_addr, (phy_register >> 2) & 0xF, &low_word)) { ++ //phase3: write address & read high word phase ++ if(__mii_mgr_read(phy_addr, (0x1 << 4), &high_word)) { ++ *read_data = (high_word << 16) | (low_word & 0xFFFF); ++ if(an_status){ ++ *(unsigned long *)(ESW_PHY_POLLING) |= (1<<31);//(AN polling on) ++ } ++ return 1; ++ } ++ } ++ } ++ if(an_status){ ++ *(unsigned long *)(ESW_PHY_POLLING) |= (1<<31);//(AN polling on) ++ } ++ } else ++#endif ++ { ++ if(__mii_mgr_read(phy_addr, phy_register, read_data)) { ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ ++u32 mii_mgr_write(u32 phy_addr, u32 phy_register, u32 write_data) ++{ ++#if defined (CONFIG_GE1_RGMII_FORCE_1000) || defined (CONFIG_GE1_TRGMII_FORCE_1200) || defined (CONFIG_GE1_TRGMII_FORCE_2000) || defined (CONFIG_GE1_TRGMII_FORCE_2600) || defined (CONFIG_P5_RGMII_TO_MT7530_MODE) ++ u32 an_status = 0; ++ ++ if(phy_addr == 31) ++ { ++ an_status = (*(unsigned long *)(ESW_PHY_POLLING) & (1<<31)); ++ if(an_status){ ++ *(unsigned long *)(ESW_PHY_POLLING) &= ~(1<<31);//(AN polling off) ++ } ++ //phase1: write page address phase ++ if(__mii_mgr_write(phy_addr, 0x1f, (phy_register >> 6) & 0x3FF)) { ++ //phase2: write address & read low word phase ++ if(__mii_mgr_write(phy_addr, ((phy_register >> 2) & 0xF), write_data & 0xFFFF)) { ++ //phase3: write address & read high word phase ++ if(__mii_mgr_write(phy_addr, (0x1 << 4), write_data >> 16)) { ++ if(an_status){ ++ *(unsigned long *)(ESW_PHY_POLLING) |= (1<<31);//(AN polling on) ++ } ++ return 1; ++ } ++ } ++ } ++ if(an_status){ ++ *(unsigned long *)(ESW_PHY_POLLING) |= (1<<31);//(AN polling on) ++ } ++ } else ++#endif ++ { ++ if(__mii_mgr_write(phy_addr, phy_register, write_data)) { ++ return 1; ++ } ++ } ++ ++ return 0; ++} ++ ++u32 mii_mgr_cl45_set_address(u32 port_num, u32 dev_addr, u32 reg_addr) ++{ ++ u32 rc = 0; ++ unsigned long volatile t_start = jiffies; ++ u32 volatile data = 0; ++ ++ enable_mdio(1); ++ ++ while (1) { ++ if(!( sysRegRead(MDIO_PHY_CONTROL_0) & (0x1 << 31))) ++ { ++ break; ++ } ++ else if (time_after(jiffies, t_start + 5*HZ)) { ++ enable_mdio(0); ++ printk("\n MDIO Read operation is ongoing !!\n"); ++ return rc; ++ } ++ } ++ data = (dev_addr << 25) | (port_num << 20) | (0x00 << 18) | (0x00 << 16) | reg_addr; ++ sysRegWrite(MDIO_PHY_CONTROL_0, data); ++ data |= (1<<31); ++ sysRegWrite(MDIO_PHY_CONTROL_0, data); ++ ++ t_start = jiffies; ++ while (1) { ++ if (!(sysRegRead(MDIO_PHY_CONTROL_0) & (0x1 << 31))) //0 : Read/write operation complete ++ { ++ enable_mdio(0); ++ return 1; ++ } ++ else if (time_after(jiffies, t_start + 5 * HZ)) { ++ enable_mdio(0); ++ printk("\n MDIO Write operation Time Out\n"); ++ return 0; ++ } ++ } ++ ++} ++ ++ ++u32 mii_mgr_read_cl45(u32 port_num, u32 dev_addr, u32 reg_addr, u32 *read_data) ++{ ++ u32 volatile status = 0; ++ u32 rc = 0; ++ unsigned long volatile t_start = jiffies; ++ u32 volatile data = 0; ++ ++ // set address first ++ mii_mgr_cl45_set_address(port_num, dev_addr, reg_addr); ++ //udelay(10); ++ ++ enable_mdio(1); ++ ++ while (1) { ++ if(!( sysRegRead(MDIO_PHY_CONTROL_0) & (0x1 << 31))) ++ { ++ break; ++ } ++ else if (time_after(jiffies, t_start + 5*HZ)) { ++ enable_mdio(0); ++ printk("\n MDIO Read operation is ongoing !!\n"); ++ return rc; ++ } ++ } ++ data = (dev_addr << 25) | (port_num << 20) | (0x03 << 18) | (0x00 << 16) | reg_addr; ++ sysRegWrite(MDIO_PHY_CONTROL_0, data); ++ data |= (1<<31); ++ sysRegWrite(MDIO_PHY_CONTROL_0, data); ++ t_start = jiffies; ++ while (1) { ++ if (!(sysRegRead(MDIO_PHY_CONTROL_0) & (0x1 << 31))) { ++ *read_data = (sysRegRead(MDIO_PHY_CONTROL_0) & 0x0000FFFF); ++ enable_mdio(0); ++ return 1; ++ } ++ else if (time_after(jiffies, t_start+5*HZ)) { ++ enable_mdio(0); ++ printk("\n Set Operation: MDIO Read operation is ongoing and Time Out!!\n"); ++ return 0; ++ } ++ status = sysRegRead(MDIO_PHY_CONTROL_0); ++ } ++ ++} ++ ++u32 mii_mgr_write_cl45 (u32 port_num, u32 dev_addr, u32 reg_addr, u32 write_data) ++{ ++ u32 rc = 0; ++ unsigned long volatile t_start = jiffies; ++ u32 volatile data = 0; ++ ++ // set address first ++ mii_mgr_cl45_set_address(port_num, dev_addr, reg_addr); ++ //udelay(10); ++ ++ enable_mdio(1); ++ while (1) { ++ if(!( sysRegRead(MDIO_PHY_CONTROL_0) & (0x1 << 31))) ++ { ++ break; ++ } ++ else if (time_after(jiffies, t_start + 5*HZ)) { ++ enable_mdio(0); ++ printk("\n MDIO Read operation is ongoing !!\n"); ++ return rc; ++ } ++ } ++ ++ data = (dev_addr << 25) | (port_num << 20) | (0x01 << 18) | (0x00 << 16) | write_data; ++ sysRegWrite(MDIO_PHY_CONTROL_0, data); ++ data |= (1<<31); ++ sysRegWrite(MDIO_PHY_CONTROL_0, data); ++ ++ t_start = jiffies; ++ ++ while (1) { ++ if (!(sysRegRead(MDIO_PHY_CONTROL_0) & (0x1 << 31))) ++ { ++ enable_mdio(0); ++ return 1; ++ } ++ else if (time_after(jiffies, t_start + 5 * HZ)) { ++ enable_mdio(0); ++ printk("\n MDIO Write operation Time Out\n"); ++ return 0; ++ } ++ ++ } ++} ++ ++#else // not rt6855 ++ ++u32 mii_mgr_read(u32 phy_addr, u32 phy_register, u32 *read_data) ++{ ++ u32 volatile status = 0; ++ u32 rc = 0; ++ unsigned long volatile t_start = jiffies; ++#if !defined (CONFIG_RALINK_RT3052) && !defined (CONFIG_RALINK_RT3352) && !defined (CONFIG_RALINK_RT5350) && !defined (CONFIG_RALINK_MT7628) ++ u32 volatile data = 0; ++#endif ++ ++ /* We enable mdio gpio purpose register, and disable it when exit. */ ++ enable_mdio(1); ++ ++ // make sure previous read operation is complete ++ while (1) { ++#if defined (CONFIG_RALINK_RT3052) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_MT7628) ++ // rd_rdy: read operation is complete ++ if(!( sysRegRead(MDIO_PHY_CONTROL_1) & (0x1 << 1))) ++#else ++ // 0 : Read/write operation complet ++ if(!( sysRegRead(MDIO_PHY_CONTROL_0) & (0x1 << 31))) ++#endif ++ { ++ break; ++ } ++ else if (time_after(jiffies, t_start + 5*HZ)) { ++ enable_mdio(0); ++ printk("\n MDIO Read operation is ongoing !!\n"); ++ return rc; ++ } ++ } ++ ++#if defined (CONFIG_RALINK_RT3052) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_MT7628) ++ sysRegWrite(MDIO_PHY_CONTROL_0 , (1<<14) | (phy_register << 8) | (phy_addr)); ++#else ++ data = (phy_addr << 24) | (phy_register << 16); ++ sysRegWrite(MDIO_PHY_CONTROL_0, data); ++ data |= (1<<31); ++ sysRegWrite(MDIO_PHY_CONTROL_0, data); ++#endif ++ //printk("\n Set Command [0x%08X] to PHY !!\n",MDIO_PHY_CONTROL_0); ++ ++ ++ // make sure read operation is complete ++ t_start = jiffies; ++ while (1) { ++#if defined (CONFIG_RALINK_RT3052) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_MT7628) ++ if (sysRegRead(MDIO_PHY_CONTROL_1) & (0x1 << 1)) { ++ status = sysRegRead(MDIO_PHY_CONTROL_1); ++ *read_data = (u32)(status >>16); ++ ++ enable_mdio(0); ++ return 1; ++ } ++#else ++ if (!(sysRegRead(MDIO_PHY_CONTROL_0) & (0x1 << 31))) { ++ status = sysRegRead(MDIO_PHY_CONTROL_0); ++ *read_data = (u32)(status & 0x0000FFFF); ++ ++ enable_mdio(0); ++ return 1; ++ } ++#endif ++ else if (time_after(jiffies, t_start+5*HZ)) { ++ enable_mdio(0); ++ printk("\n MDIO Read operation is ongoing and Time Out!!\n"); ++ return 0; ++ } ++ } ++} ++ ++ ++u32 mii_mgr_write(u32 phy_addr, u32 phy_register, u32 write_data) ++{ ++ unsigned long volatile t_start=jiffies; ++ u32 volatile data; ++ ++ enable_mdio(1); ++ ++ // make sure previous write operation is complete ++ while(1) { ++#if defined (CONFIG_RALINK_RT3052) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_MT7628) ++ if (!(sysRegRead(MDIO_PHY_CONTROL_1) & (0x1 << 0))) ++#else ++ if (!(sysRegRead(MDIO_PHY_CONTROL_0) & (0x1 << 31))) ++#endif ++ { ++ break; ++ } ++ else if (time_after(jiffies, t_start + 5 * HZ)) { ++ enable_mdio(0); ++ printk("\n MDIO Write operation ongoing\n"); ++ return 0; ++ } ++ } ++ ++#if defined (CONFIG_RALINK_RT3052) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_MT7628) ++ data = ((write_data & 0xFFFF) << 16); ++ data |= (phy_register << 8) | (phy_addr); ++ data |= (1<<13); ++ sysRegWrite(MDIO_PHY_CONTROL_0, data); ++#else ++ data = (1<<30) | (phy_addr << 24) | (phy_register << 16) | write_data; ++ sysRegWrite(MDIO_PHY_CONTROL_0, data); ++ data |= (1<<31); ++ sysRegWrite(MDIO_PHY_CONTROL_0, data); //start operation ++#endif ++ //printk("\n Set Command [0x%08X] to PHY !!\n",MDIO_PHY_CONTROL_0); ++ ++ t_start = jiffies; ++ ++ // make sure write operation is complete ++ while (1) { ++#if defined (CONFIG_RALINK_RT3052) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_MT7628) ++ if (sysRegRead(MDIO_PHY_CONTROL_1) & (0x1 << 0)) //wt_done ?= 1 ++#else ++ if (!(sysRegRead(MDIO_PHY_CONTROL_0) & (0x1 << 31))) //0 : Read/write operation complete ++#endif ++ { ++ enable_mdio(0); ++ return 1; ++ } ++ else if (time_after(jiffies, t_start + 5 * HZ)) { ++ enable_mdio(0); ++ printk("\n MDIO Write operation Time Out\n"); ++ return 0; ++ } ++ } ++} ++ ++ ++ ++ ++#endif ++ ++ ++ ++ ++EXPORT_SYMBOL(mii_mgr_write); ++EXPORT_SYMBOL(mii_mgr_read); +diff --git a/drivers/net/ethernet/raeth/ra2882ethreg.h b/drivers/net/ethernet/raeth/ra2882ethreg.h +new file mode 100644 +index 0000000..c67a042 +--- /dev/null ++++ b/drivers/net/ethernet/raeth/ra2882ethreg.h +@@ -0,0 +1,1985 @@ ++#ifndef RA2882ETHREG_H ++#define RA2882ETHREG_H ++ ++#include <linux/mii.h> // for struct mii_if_info in ra2882ethreg.h ++#include <linux/version.h> /* check linux version for 2.4 and 2.6 compatibility */ ++#include <linux/interrupt.h> /* for "struct tasklet_struct" in linux-3.10.14 */ ++#if defined (CONFIG_HW_SFQ) ++#include <linux/ip.h> ++#include <linux/ipv6.h> ++#endif ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) ++#include <asm/rt2880/rt_mmap.h> ++#endif ++#include "raether.h" ++ ++#ifdef WORKQUEUE_BH ++#include <linux/workqueue.h> ++#endif // WORKQUEUE_BH // ++#ifdef CONFIG_RAETH_LRO ++#include <linux/inet_lro.h> ++#endif ++ ++#define MAX_PACKET_SIZE 1514 ++#define MIN_PACKET_SIZE 60 ++#define MAX_TXD_LEN 0x3fff ++ ++#if defined (CONFIG_ARCH_MT7623) ++#define phys_to_bus(a) (a) ++#else ++#define phys_to_bus(a) (a & 0x1FFFFFFF) ++#endif ++ ++ ++ ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ++#define BIT(x) ((1 << x)) ++#endif ++/* bits range: for example BITS(16,23) = 0xFF0000 ++ * ==> (BIT(m)-1) = 0x0000FFFF ~(BIT(m)-1) => 0xFFFF0000 ++ * ==> (BIT(n+1)-1) = 0x00FFFFFF ++ */ ++#define BITS(m,n) (~(BIT(m)-1) & ((BIT(n) - 1) | BIT(n))) ++ ++#define ETHER_ADDR_LEN 6 ++ ++/* Phy Vender ID list */ ++ ++#define EV_ICPLUS_PHY_ID0 0x0243 ++#define EV_ICPLUS_PHY_ID1 0x0D90 ++#define EV_MARVELL_PHY_ID0 0x0141 ++#define EV_MARVELL_PHY_ID1 0x0CC2 ++#define EV_VTSS_PHY_ID0 0x0007 ++#define EV_VTSS_PHY_ID1 0x0421 ++ ++/* ++ FE_INT_STATUS ++*/ ++#if defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A) || \ ++ defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || \ ++ defined (CONFIG_ARCH_MT7623) ++ ++#define RX_COHERENT BIT(31) ++#define RX_DLY_INT BIT(30) ++#define TX_COHERENT BIT(29) ++#define TX_DLY_INT BIT(28) ++#define RING3_RX_DLY_INT BIT(27) ++#define RING2_RX_DLY_INT BIT(26) ++#define RING1_RX_DLY_INT BIT(25) ++ ++#define ALT_RPLC_INT3 BIT(23) ++#define ALT_RPLC_INT2 BIT(22) ++#define ALT_RPLC_INT1 BIT(21) ++ ++#define RX_DONE_INT3 BIT(19) ++#define RX_DONE_INT2 BIT(18) ++#define RX_DONE_INT1 BIT(17) ++#define RX_DONE_INT0 BIT(16) ++ ++#define TX_DONE_INT3 BIT(3) ++#define TX_DONE_INT2 BIT(2) ++#define TX_DONE_INT1 BIT(1) ++#define TX_DONE_INT0 BIT(0) ++ ++#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++#define RLS_COHERENT BIT(29) ++#define RLS_DLY_INT BIT(28) ++#define RLS_DONE_INT BIT(0) ++#endif ++ ++#else ++//#define CNT_PPE_AF BIT(31) ++//#define CNT_GDM_AF BIT(29) ++#define PSE_P2_FC BIT(26) ++#define GDM_CRC_DROP BIT(25) ++#define PSE_BUF_DROP BIT(24) ++#define GDM_OTHER_DROP BIT(23) ++#define PSE_P1_FC BIT(22) ++#define PSE_P0_FC BIT(21) ++#define PSE_FQ_EMPTY BIT(20) ++#define GE1_STA_CHG BIT(18) ++#define TX_COHERENT BIT(17) ++#define RX_COHERENT BIT(16) ++ ++#define TX_DONE_INT3 BIT(11) ++#define TX_DONE_INT2 BIT(10) ++#define TX_DONE_INT1 BIT(9) ++#define TX_DONE_INT0 BIT(8) ++#define RX_DONE_INT1 RX_DONE_INT0 ++#define RX_DONE_INT0 BIT(2) ++#define TX_DLY_INT BIT(1) ++#define RX_DLY_INT BIT(0) ++#endif ++ ++#define FE_INT_ALL (TX_DONE_INT3 | TX_DONE_INT2 | \ ++ TX_DONE_INT1 | TX_DONE_INT0 | \ ++ RX_DONE_INT0 | RX_DONE_INT1 | \ ++ RX_DONE_INT2 | RX_DONE_INT3) ++ ++#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++#define QFE_INT_ALL (RLS_DONE_INT | RX_DONE_INT0 | RX_DONE_INT1) ++#define QFE_INT_DLY_INIT (RLS_DLY_INT | RX_DLY_INT) ++ ++#define NUM_QDMA_PAGE 512 ++#define QDMA_PAGE_SIZE 2048 ++#endif ++/* ++ * SW_INT_STATUS ++ */ ++#if defined (CONFIG_RALINK_RT3052) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_MT7628) ++#define PORT0_QUEUE_FULL BIT(14) //port0 queue full ++#define PORT1_QUEUE_FULL BIT(15) //port1 queue full ++#define PORT2_QUEUE_FULL BIT(16) //port2 queue full ++#define PORT3_QUEUE_FULL BIT(17) //port3 queue full ++#define PORT4_QUEUE_FULL BIT(18) //port4 queue full ++#define PORT5_QUEUE_FULL BIT(19) //port5 queue full ++#define PORT6_QUEUE_FULL BIT(20) //port6 queue full ++#define SHARED_QUEUE_FULL BIT(23) //shared queue full ++#define QUEUE_EXHAUSTED BIT(24) //global queue is used up and all packets are dropped ++#define BC_STROM BIT(25) //the device is undergoing broadcast storm ++#define PORT_ST_CHG BIT(26) //Port status change ++#define UNSECURED_ALERT BIT(27) //Intruder alert ++#define ABNORMAL_ALERT BIT(28) //Abnormal ++ ++#define ESW_ISR (RALINK_ETH_SW_BASE + 0x00) ++#define ESW_IMR (RALINK_ETH_SW_BASE + 0x04) ++#define ESW_INT_ALL (PORT_ST_CHG) ++ ++#elif defined (CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A) || \ ++ defined (CONFIG_RALINK_MT7620) ++#define MIB_INT BIT(25) ++#define ACL_INT BIT(24) ++#define P5_LINK_CH BIT(5) ++#define P4_LINK_CH BIT(4) ++#define P3_LINK_CH BIT(3) ++#define P2_LINK_CH BIT(2) ++#define P1_LINK_CH BIT(1) ++#define P0_LINK_CH BIT(0) ++ ++#define RX_GOCT_CNT BIT(4) ++#define RX_GOOD_CNT BIT(6) ++#define TX_GOCT_CNT BIT(17) ++#define TX_GOOD_CNT BIT(19) ++ ++#define MSK_RX_GOCT_CNT BIT(4) ++#define MSK_RX_GOOD_CNT BIT(6) ++#define MSK_TX_GOCT_CNT BIT(17) ++#define MSK_TX_GOOD_CNT BIT(19) ++#define MSK_CNT_INT_ALL (MSK_RX_GOCT_CNT | MSK_RX_GOOD_CNT | MSK_TX_GOCT_CNT | MSK_TX_GOOD_CNT) ++//#define MSK_CNT_INT_ALL (MSK_RX_GOOD_CNT | MSK_TX_GOOD_CNT) ++ ++ ++#define ESW_IMR (RALINK_ETH_SW_BASE + 0x7000 + 0x8) ++#define ESW_ISR (RALINK_ETH_SW_BASE + 0x7000 + 0xC) ++#define ESW_INT_ALL (P0_LINK_CH | P1_LINK_CH | P2_LINK_CH | P3_LINK_CH | P4_LINK_CH | P5_LINK_CH | ACL_INT | MIB_INT) ++#define ESW_AISR (RALINK_ETH_SW_BASE + 0x8) ++#define ESW_P0_IntSn (RALINK_ETH_SW_BASE + 0x4004) ++#define ESW_P1_IntSn (RALINK_ETH_SW_BASE + 0x4104) ++#define ESW_P2_IntSn (RALINK_ETH_SW_BASE + 0x4204) ++#define ESW_P3_IntSn (RALINK_ETH_SW_BASE + 0x4304) ++#define ESW_P4_IntSn (RALINK_ETH_SW_BASE + 0x4404) ++#define ESW_P5_IntSn (RALINK_ETH_SW_BASE + 0x4504) ++#define ESW_P6_IntSn (RALINK_ETH_SW_BASE + 0x4604) ++#define ESW_P0_IntMn (RALINK_ETH_SW_BASE + 0x4008) ++#define ESW_P1_IntMn (RALINK_ETH_SW_BASE + 0x4108) ++#define ESW_P2_IntMn (RALINK_ETH_SW_BASE + 0x4208) ++#define ESW_P3_IntMn (RALINK_ETH_SW_BASE + 0x4308) ++#define ESW_P4_IntMn (RALINK_ETH_SW_BASE + 0x4408) ++#define ESW_P5_IntMn (RALINK_ETH_SW_BASE + 0x4508) ++#define ESW_P6_IntMn (RALINK_ETH_SW_BASE + 0x4608) ++ ++#if defined (CONFIG_RALINK_MT7620) ++#define ESW_P7_IntSn (RALINK_ETH_SW_BASE + 0x4704) ++#define ESW_P7_IntMn (RALINK_ETH_SW_BASE + 0x4708) ++#endif ++ ++ ++#define ESW_PHY_POLLING (RALINK_ETH_SW_BASE + 0x7000) ++ ++#elif defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++ ++#define ESW_PHY_POLLING (RALINK_ETH_SW_BASE + 0x0000) ++ ++#define P5_LINK_CH BIT(5) ++#define P4_LINK_CH BIT(4) ++#define P3_LINK_CH BIT(3) ++#define P2_LINK_CH BIT(2) ++#define P1_LINK_CH BIT(1) ++#define P0_LINK_CH BIT(0) ++ ++ ++#endif // CONFIG_RALINK_RT3052 || CONFIG_RALINK_RT3352 || CONFIG_RALINK_RT5350 || defined (CONFIG_RALINK_MT7628)// ++ ++#define RX_BUF_ALLOC_SIZE 2000 ++#define FASTPATH_HEADROOM 64 ++ ++#define ETHER_BUFFER_ALIGN 32 ///// Align on a cache line ++ ++#define ETHER_ALIGNED_RX_SKB_ADDR(addr) \ ++ ((((unsigned long)(addr) + ETHER_BUFFER_ALIGN - 1) & \ ++ ~(ETHER_BUFFER_ALIGN - 1)) - (unsigned long)(addr)) ++ ++#ifdef CONFIG_PSEUDO_SUPPORT ++typedef struct _PSEUDO_ADAPTER { ++ struct net_device *RaethDev; ++ struct net_device *PseudoDev; ++ struct net_device_stats stat; ++#if defined (CONFIG_ETHTOOL) /*&& defined (CONFIG_RAETH_ROUTER)*/ ++ struct mii_if_info mii_info; ++#endif ++ ++} PSEUDO_ADAPTER, PPSEUDO_ADAPTER; ++ ++#define MAX_PSEUDO_ENTRY 1 ++#endif ++ ++ ++ ++/* Register Categories Definition */ ++#define RAFRAMEENGINE_OFFSET 0x0000 ++#define RAGDMA_OFFSET 0x0020 ++#define RAPSE_OFFSET 0x0040 ++#define RAGDMA2_OFFSET 0x0060 ++#define RACDMA_OFFSET 0x0080 ++#if defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A) || \ ++ defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || \ ++ defined (CONFIG_ARCH_MT7623) ++ ++#define RAPDMA_OFFSET 0x0800 ++#define SDM_OFFSET 0x0C00 ++#else ++#define RAPDMA_OFFSET 0x0100 ++#endif ++#define RAPPE_OFFSET 0x0200 ++#define RACMTABLE_OFFSET 0x0400 ++#define RAPOLICYTABLE_OFFSET 0x1000 ++ ++ ++/* Register Map Detail */ ++/* RT3883 */ ++#define SYSCFG1 (RALINK_SYSCTL_BASE + 0x14) ++ ++#if defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_MT7628) ++ ++/* 1. PDMA */ ++#define TX_BASE_PTR0 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x000) ++#define TX_MAX_CNT0 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x004) ++#define TX_CTX_IDX0 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x008) ++#define TX_DTX_IDX0 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x00C) ++ ++#define TX_BASE_PTR1 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x010) ++#define TX_MAX_CNT1 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x014) ++#define TX_CTX_IDX1 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x018) ++#define TX_DTX_IDX1 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x01C) ++ ++#define TX_BASE_PTR2 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x020) ++#define TX_MAX_CNT2 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x024) ++#define TX_CTX_IDX2 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x028) ++#define TX_DTX_IDX2 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x02C) ++ ++#define TX_BASE_PTR3 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x030) ++#define TX_MAX_CNT3 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x034) ++#define TX_CTX_IDX3 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x038) ++#define TX_DTX_IDX3 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x03C) ++ ++#define RX_BASE_PTR0 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x100) ++#define RX_MAX_CNT0 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x104) ++#define RX_CALC_IDX0 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x108) ++#define RX_DRX_IDX0 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x10C) ++ ++#define RX_BASE_PTR1 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x110) ++#define RX_MAX_CNT1 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x114) ++#define RX_CALC_IDX1 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x118) ++#define RX_DRX_IDX1 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x11C) ++ ++#define PDMA_INFO (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x200) ++#define PDMA_GLO_CFG (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x204) ++#define PDMA_RST_IDX (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x208) ++#define PDMA_RST_CFG (PDMA_RST_IDX) ++#define DLY_INT_CFG (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x20C) ++#define FREEQ_THRES (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x210) ++#define INT_STATUS (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x220) ++#define FE_INT_STATUS (INT_STATUS) ++#define INT_MASK (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x228) ++#define FE_INT_ENABLE (INT_MASK) ++#define PDMA_WRR (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x280) ++#define PDMA_SCH_CFG (PDMA_WRR) ++ ++#define SDM_CON (RALINK_FRAME_ENGINE_BASE+SDM_OFFSET+0x00) //Switch DMA configuration ++#define SDM_RRING (RALINK_FRAME_ENGINE_BASE+SDM_OFFSET+0x04) //Switch DMA Rx Ring ++#define SDM_TRING (RALINK_FRAME_ENGINE_BASE+SDM_OFFSET+0x08) //Switch DMA Tx Ring ++#define SDM_MAC_ADRL (RALINK_FRAME_ENGINE_BASE+SDM_OFFSET+0x0C) //Switch MAC address LSB ++#define SDM_MAC_ADRH (RALINK_FRAME_ENGINE_BASE+SDM_OFFSET+0x10) //Switch MAC Address MSB ++#define SDM_TPCNT (RALINK_FRAME_ENGINE_BASE+SDM_OFFSET+0x100) //Switch DMA Tx packet count ++#define SDM_TBCNT (RALINK_FRAME_ENGINE_BASE+SDM_OFFSET+0x104) //Switch DMA Tx byte count ++#define SDM_RPCNT (RALINK_FRAME_ENGINE_BASE+SDM_OFFSET+0x108) //Switch DMA rx packet count ++#define SDM_RBCNT (RALINK_FRAME_ENGINE_BASE+SDM_OFFSET+0x10C) //Switch DMA rx byte count ++#define SDM_CS_ERR (RALINK_FRAME_ENGINE_BASE+SDM_OFFSET+0x110) //Switch DMA rx checksum error count ++ ++#elif defined (CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A) || \ ++ defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || \ ++ defined (CONFIG_ARCH_MT7623) ++ ++/* Old FE with New PDMA */ ++#define PDMA_RELATED 0x0800 ++/* 1. PDMA */ ++#define TX_BASE_PTR0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x000) ++#define TX_MAX_CNT0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x004) ++#define TX_CTX_IDX0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x008) ++#define TX_DTX_IDX0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x00C) ++ ++#define TX_BASE_PTR1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x010) ++#define TX_MAX_CNT1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x014) ++#define TX_CTX_IDX1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x018) ++#define TX_DTX_IDX1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x01C) ++ ++#define TX_BASE_PTR2 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x020) ++#define TX_MAX_CNT2 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x024) ++#define TX_CTX_IDX2 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x028) ++#define TX_DTX_IDX2 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x02C) ++ ++#define TX_BASE_PTR3 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x030) ++#define TX_MAX_CNT3 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x034) ++#define TX_CTX_IDX3 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x038) ++#define TX_DTX_IDX3 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x03C) ++ ++#define RX_BASE_PTR0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x100) ++#define RX_MAX_CNT0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x104) ++#define RX_CALC_IDX0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x108) ++#define RX_DRX_IDX0 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x10C) ++ ++#define RX_BASE_PTR1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x110) ++#define RX_MAX_CNT1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x114) ++#define RX_CALC_IDX1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x118) ++#define RX_DRX_IDX1 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x11C) ++ ++#define RX_BASE_PTR2 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x120) ++#define RX_MAX_CNT2 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x124) ++#define RX_CALC_IDX2 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x128) ++#define RX_DRX_IDX12 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x12C) ++ ++#define RX_BASE_PTR3 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x130) ++#define RX_MAX_CNT3 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x134) ++#define RX_CALC_IDX3 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x138) ++#define RX_DRX_IDX3 (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x13C) ++ ++#define PDMA_INFO (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x200) ++#define PDMA_GLO_CFG (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x204) ++#define PDMA_RST_IDX (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x208) ++#define PDMA_RST_CFG (PDMA_RST_IDX) ++#define DLY_INT_CFG (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x20C) ++#define FREEQ_THRES (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x210) ++#define INT_STATUS (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x220) ++#define FE_INT_STATUS (INT_STATUS) ++#define INT_MASK (RALINK_FRAME_ENGINE_BASE + PDMA_RELATED+0x228) ++#define FE_INT_ENABLE (INT_MASK) ++#define SCH_Q01_CFG (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x280) ++#define SCH_Q23_CFG (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x284) ++ ++#define FE_GLO_CFG RALINK_FRAME_ENGINE_BASE + 0x00 ++#define FE_RST_GL RALINK_FRAME_ENGINE_BASE + 0x04 ++#define FE_INT_STATUS2 RALINK_FRAME_ENGINE_BASE + 0x08 ++#define FE_INT_ENABLE2 RALINK_FRAME_ENGINE_BASE + 0x0c ++//#define FC_DROP_STA RALINK_FRAME_ENGINE_BASE + 0x18 ++#define FOE_TS_T RALINK_FRAME_ENGINE_BASE + 0x10 ++ ++#if defined (CONFIG_RALINK_MT7620) ++#define GDMA1_RELATED 0x0600 ++#define GDMA1_FWD_CFG (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x00) ++#define GDMA1_SHPR_CFG (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x04) ++#define GDMA1_MAC_ADRL (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x08) ++#define GDMA1_MAC_ADRH (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x0C) ++#elif defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++#define GDMA1_RELATED 0x0500 ++#define GDMA1_FWD_CFG (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x00) ++#define GDMA1_SHPR_CFG (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x04) ++#define GDMA1_MAC_ADRL (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x08) ++#define GDMA1_MAC_ADRH (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x0C) ++ ++#define GDMA2_RELATED 0x1500 ++#define GDMA2_FWD_CFG (RALINK_FRAME_ENGINE_BASE + GDMA2_RELATED + 0x00) ++#define GDMA2_SHPR_CFG (RALINK_FRAME_ENGINE_BASE + GDMA2_RELATED + 0x04) ++#define GDMA2_MAC_ADRL (RALINK_FRAME_ENGINE_BASE + GDMA2_RELATED + 0x08) ++#define GDMA2_MAC_ADRH (RALINK_FRAME_ENGINE_BASE + GDMA2_RELATED + 0x0C) ++#else ++#define GDMA1_RELATED 0x0020 ++#define GDMA1_FWD_CFG (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x00) ++#define GDMA1_SCH_CFG (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x04) ++#define GDMA1_SHPR_CFG (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x08) ++#define GDMA1_MAC_ADRL (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x0C) ++#define GDMA1_MAC_ADRH (RALINK_FRAME_ENGINE_BASE + GDMA1_RELATED + 0x10) ++ ++#define GDMA2_RELATED 0x0060 ++#define GDMA2_FWD_CFG (RALINK_FRAME_ENGINE_BASE + GDMA2_RELATED + 0x00) ++#define GDMA2_SCH_CFG (RALINK_FRAME_ENGINE_BASE + GDMA2_RELATED + 0x04) ++#define GDMA2_SHPR_CFG (RALINK_FRAME_ENGINE_BASE + GDMA2_RELATED + 0x08) ++#define GDMA2_MAC_ADRL (RALINK_FRAME_ENGINE_BASE + GDMA2_RELATED + 0x0C) ++#define GDMA2_MAC_ADRH (RALINK_FRAME_ENGINE_BASE + GDMA2_RELATED + 0x10) ++#endif ++ ++#if defined (CONFIG_RALINK_MT7620) ++#define PSE_RELATED 0x0500 ++#define PSE_FQFC_CFG (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x00) ++#define PSE_IQ_CFG (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x04) ++#define PSE_QUE_STA (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x08) ++#else ++#define PSE_RELATED 0x0040 ++#define PSE_FQ_CFG (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x00) ++#define CDMA_FC_CFG (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x04) ++#define GDMA1_FC_CFG (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x08) ++#define GDMA2_FC_CFG (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x0C) ++#define CDMA_OQ_STA (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x10) ++#define GDMA1_OQ_STA (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x14) ++#define GDMA2_OQ_STA (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x18) ++#define PSE_IQ_STA (RALINK_FRAME_ENGINE_BASE + PSE_RELATED + 0x1C) ++#endif ++ ++ ++#if defined (CONFIG_RALINK_MT7620) ++#define CDMA_RELATED 0x0400 ++#define CDMA_CSG_CFG (RALINK_FRAME_ENGINE_BASE + CDMA_RELATED + 0x00) ++#define SMACCR0 (RALINK_ETH_SW_BASE + 0x3FE4) ++#define SMACCR1 (RALINK_ETH_SW_BASE + 0x3FE8) ++#define CKGCR (RALINK_ETH_SW_BASE + 0x3FF0) ++#elif defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++#define CDMA_RELATED 0x0400 ++#define CDMA_CSG_CFG (RALINK_FRAME_ENGINE_BASE + CDMA_RELATED + 0x00) //fake definition ++#define CDMP_IG_CTRL (RALINK_FRAME_ENGINE_BASE + CDMA_RELATED + 0x00) ++#define CDMP_EG_CTRL (RALINK_FRAME_ENGINE_BASE + CDMA_RELATED + 0x04) ++#else ++#define CDMA_RELATED 0x0080 ++#define CDMA_CSG_CFG (RALINK_FRAME_ENGINE_BASE + CDMA_RELATED + 0x00) ++#define CDMA_SCH_CFG (RALINK_FRAME_ENGINE_BASE + CDMA_RELATED + 0x04) ++#define SMACCR0 (RALINK_ETH_SW_BASE + 0x30E4) ++#define SMACCR1 (RALINK_ETH_SW_BASE + 0x30E8) ++#define CKGCR (RALINK_ETH_SW_BASE + 0x30F0) ++#endif ++ ++#define PDMA_FC_CFG (RALINK_FRAME_ENGINE_BASE+0x100) ++ ++ ++#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++/*kurtis: add QDMA define*/ ++ ++#define CLK_CFG_0 (RALINK_SYSCTL_BASE + 0x2C) ++#define PAD_RGMII2_MDIO_CFG (RALINK_SYSCTL_BASE + 0x58) ++ ++#define QDMA_RELATED 0x1800 ++#define QTX_CFG_0 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x000) ++#define QTX_SCH_0 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x004) ++#define QTX_HEAD_0 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x008) ++#define QTX_TAIL_0 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x00C) ++#define QTX_CFG_1 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x010) ++#define QTX_SCH_1 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x014) ++#define QTX_HEAD_1 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x018) ++#define QTX_TAIL_1 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x01C) ++#define QTX_CFG_2 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x020) ++#define QTX_SCH_2 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x024) ++#define QTX_HEAD_2 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x028) ++#define QTX_TAIL_2 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x02C) ++#define QTX_CFG_3 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x030) ++#define QTX_SCH_3 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x034) ++#define QTX_HEAD_3 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x038) ++#define QTX_TAIL_3 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x03C) ++#define QTX_CFG_4 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x040) ++#define QTX_SCH_4 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x044) ++#define QTX_HEAD_4 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x048) ++#define QTX_TAIL_4 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x04C) ++#define QTX_CFG_5 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x050) ++#define QTX_SCH_5 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x054) ++#define QTX_HEAD_5 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x058) ++#define QTX_TAIL_5 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x05C) ++#define QTX_CFG_6 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x060) ++#define QTX_SCH_6 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x064) ++#define QTX_HEAD_6 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x068) ++#define QTX_TAIL_6 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x06C) ++#define QTX_CFG_7 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x070) ++#define QTX_SCH_7 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x074) ++#define QTX_HEAD_7 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x078) ++#define QTX_TAIL_7 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x07C) ++#define QTX_CFG_8 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x080) ++#define QTX_SCH_8 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x084) ++#define QTX_HEAD_8 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x088) ++#define QTX_TAIL_8 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x08C) ++#define QTX_CFG_9 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x090) ++#define QTX_SCH_9 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x094) ++#define QTX_HEAD_9 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x098) ++#define QTX_TAIL_9 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x09C) ++#define QTX_CFG_10 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0A0) ++#define QTX_SCH_10 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0A4) ++#define QTX_HEAD_10 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0A8) ++#define QTX_TAIL_10 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0AC) ++#define QTX_CFG_11 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0B0) ++#define QTX_SCH_11 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0B4) ++#define QTX_HEAD_11 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0B8) ++#define QTX_TAIL_11 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0BC) ++#define QTX_CFG_12 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0C0) ++#define QTX_SCH_12 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0C4) ++#define QTX_HEAD_12 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0C8) ++#define QTX_TAIL_12 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0CC) ++#define QTX_CFG_13 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0D0) ++#define QTX_SCH_13 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0D4) ++#define QTX_HEAD_13 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0D8) ++#define QTX_TAIL_13 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0DC) ++#define QTX_CFG_14 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0E0) ++#define QTX_SCH_14 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0E4) ++#define QTX_HEAD_14 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0E8) ++#define QTX_TAIL_14 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0EC) ++#define QTX_CFG_15 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0F0) ++#define QTX_SCH_15 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0F4) ++#define QTX_HEAD_15 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0F8) ++#define QTX_TAIL_15 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x0FC) ++#define QRX_BASE_PTR_0 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x100) ++#define QRX_MAX_CNT_0 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x104) ++#define QRX_CRX_IDX_0 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x108) ++#define QRX_DRX_IDX_0 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x10C) ++#define QRX_BASE_PTR_1 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x110) ++#define QRX_MAX_CNT_1 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x114) ++#define QRX_CRX_IDX_1 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x118) ++#define QRX_DRX_IDX_1 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x11C) ++#if defined (CONFIG_ARCH_MT7623) ++#define VQTX_TB_BASE_0 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x180) ++#define VQTX_TB_BASE_1 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x184) ++#define VQTX_TB_BASE_2 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x188) ++#define VQTX_TB_BASE_3 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x18C) ++#endif ++#define QDMA_INFO (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x200) ++#define QDMA_GLO_CFG (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x204) ++#define QDMA_RST_IDX (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x208) ++#define QDMA_RST_CFG (QDMA_RST_IDX) ++#define QDMA_DELAY_INT (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x20C) ++#define QDMA_FC_THRES (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x210) ++#define QDMA_TX_SCH (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x214) ++#define QDMA_INT_STS (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x218) ++#define QFE_INT_STATUS (QDMA_INT_STS) ++#define QDMA_INT_MASK (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x21C) ++#define QFE_INT_ENABLE (QDMA_INT_MASK) ++#define QDMA_TRTCM (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x220) ++#define QDMA_DATA0 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x224) ++#define QDMA_DATA1 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x228) ++#define QDMA_RED_THRES (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x22C) ++#define QDMA_TEST (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x230) ++#define QDMA_DMA (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x234) ++#define QDMA_BMU (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x238) ++#define QDMA_HRED1 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x240) ++#define QDMA_HRED2 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x244) ++#define QDMA_SRED1 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x248) ++#define QDMA_SRED2 (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x24C) ++#define QTX_CTX_PTR (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x300) ++#define QTX_DTX_PTR (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x304) ++#define QTX_FWD_CNT (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x308) ++#define QTX_CRX_PTR (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x310) ++#define QTX_DRX_PTR (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x314) ++#define QTX_RLS_CNT (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x318) ++#define QDMA_FQ_HEAD (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x320) ++#define QDMA_FQ_TAIL (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x324) ++#define QDMA_FQ_CNT (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x328) ++#define QDMA_FQ_BLEN (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x32C) ++#define QTX_Q0MIN_BK (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x350) ++#define QTX_Q1MIN_BK (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x354) ++#define QTX_Q2MIN_BK (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x358) ++#define QTX_Q3MIN_BK (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x35C) ++#define QTX_Q0MAX_BK (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x360) ++#define QTX_Q1MAX_BK (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x364) ++#define QTX_Q2MAX_BK (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x368) ++#define QTX_Q3MAX_BK (RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + 0x36C) ++ ++ ++#endif/*MT7621 QDMA*/ ++ ++#else ++ ++/* 1. Frame Engine Global Registers */ ++#define MDIO_ACCESS (RALINK_FRAME_ENGINE_BASE+RAFRAMEENGINE_OFFSET+0x00) ++#define MDIO_CFG (RALINK_FRAME_ENGINE_BASE+RAFRAMEENGINE_OFFSET+0x04) ++#define FE_GLO_CFG (RALINK_FRAME_ENGINE_BASE+RAFRAMEENGINE_OFFSET+0x08) ++#define FE_RST_GL (RALINK_FRAME_ENGINE_BASE+RAFRAMEENGINE_OFFSET+0x0C) ++#define FE_INT_STATUS (RALINK_FRAME_ENGINE_BASE+RAFRAMEENGINE_OFFSET+0x10) ++#define FE_INT_ENABLE (RALINK_FRAME_ENGINE_BASE+RAFRAMEENGINE_OFFSET+0x14) ++#define MDIO_CFG2 (RALINK_FRAME_ENGINE_BASE+RAFRAMEENGINE_OFFSET+0x18) //Original:FC_DROP_STA ++#define FOC_TS_T (RALINK_FRAME_ENGINE_BASE+RAFRAMEENGINE_OFFSET+0x1C) ++ ++ ++/* 2. GDMA Registers */ ++#define GDMA1_FWD_CFG (RALINK_FRAME_ENGINE_BASE+RAGDMA_OFFSET+0x00) ++#define GDMA1_SCH_CFG (RALINK_FRAME_ENGINE_BASE+RAGDMA_OFFSET+0x04) ++#define GDMA1_SHPR_CFG (RALINK_FRAME_ENGINE_BASE+RAGDMA_OFFSET+0x08) ++#define GDMA1_MAC_ADRL (RALINK_FRAME_ENGINE_BASE+RAGDMA_OFFSET+0x0C) ++#define GDMA1_MAC_ADRH (RALINK_FRAME_ENGINE_BASE+RAGDMA_OFFSET+0x10) ++ ++#define GDMA2_FWD_CFG (RALINK_FRAME_ENGINE_BASE+RAGDMA2_OFFSET+0x00) ++#define GDMA2_SCH_CFG (RALINK_FRAME_ENGINE_BASE+RAGDMA2_OFFSET+0x04) ++#define GDMA2_SHPR_CFG (RALINK_FRAME_ENGINE_BASE+RAGDMA2_OFFSET+0x08) ++#define GDMA2_MAC_ADRL (RALINK_FRAME_ENGINE_BASE+RAGDMA2_OFFSET+0x0C) ++#define GDMA2_MAC_ADRH (RALINK_FRAME_ENGINE_BASE+RAGDMA2_OFFSET+0x10) ++ ++/* 3. PSE */ ++#define PSE_FQ_CFG (RALINK_FRAME_ENGINE_BASE+RAPSE_OFFSET+0x00) ++#define CDMA_FC_CFG (RALINK_FRAME_ENGINE_BASE+RAPSE_OFFSET+0x04) ++#define GDMA1_FC_CFG (RALINK_FRAME_ENGINE_BASE+RAPSE_OFFSET+0x08) ++#define GDMA2_FC_CFG (RALINK_FRAME_ENGINE_BASE+RAPSE_OFFSET+0x0C) ++#define PDMA_FC_CFG (RALINK_FRAME_ENGINE_BASE+0x1f0) ++ ++/* 4. CDMA */ ++#define CDMA_CSG_CFG (RALINK_FRAME_ENGINE_BASE+RACDMA_OFFSET+0x00) ++#define CDMA_SCH_CFG (RALINK_FRAME_ENGINE_BASE+RACDMA_OFFSET+0x04) ++/* skip ppoe sid and vlan id definition */ ++ ++ ++/* 5. PDMA */ ++#define PDMA_GLO_CFG (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x00) ++#define PDMA_RST_CFG (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x04) ++#define PDMA_SCH_CFG (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x08) ++ ++#define DLY_INT_CFG (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x0C) ++ ++#define TX_BASE_PTR0 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x10) ++#define TX_MAX_CNT0 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x14) ++#define TX_CTX_IDX0 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x18) ++#define TX_DTX_IDX0 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x1C) ++ ++#define TX_BASE_PTR1 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x20) ++#define TX_MAX_CNT1 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x24) ++#define TX_CTX_IDX1 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x28) ++#define TX_DTX_IDX1 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x2C) ++ ++#define TX_BASE_PTR2 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x40) ++#define TX_MAX_CNT2 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x44) ++#define TX_CTX_IDX2 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x48) ++#define TX_DTX_IDX2 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x4C) ++ ++#define TX_BASE_PTR3 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x50) ++#define TX_MAX_CNT3 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x54) ++#define TX_CTX_IDX3 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x58) ++#define TX_DTX_IDX3 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x5C) ++ ++#define RX_BASE_PTR0 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x30) ++#define RX_MAX_CNT0 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x34) ++#define RX_CALC_IDX0 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x38) ++#define RX_DRX_IDX0 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x3C) ++ ++#define RX_BASE_PTR1 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x40) ++#define RX_MAX_CNT1 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x44) ++#define RX_CALC_IDX1 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x48) ++#define RX_DRX_IDX1 (RALINK_FRAME_ENGINE_BASE+RAPDMA_OFFSET+0x4C) ++ ++#endif ++ ++#define DELAY_INT_INIT 0x84048404 ++#define FE_INT_DLY_INIT (TX_DLY_INT | RX_DLY_INT) ++ ++ ++#if !defined (CONFIG_RALINK_RT5350) && !defined (CONFIG_RALINK_MT7628) ++ ++/* 6. Counter and Meter Table */ ++#define PPE_AC_BCNT0 (RALINK_FRAME_ENGINE_BASE+RACMTABLE_OFFSET+0x000) /* PPE Accounting Group 0 Byte Cnt */ ++#define PPE_AC_PCNT0 (RALINK_FRAME_ENGINE_BASE+RACMTABLE_OFFSET+0x004) /* PPE Accounting Group 0 Packet Cnt */ ++/* 0 ~ 63 */ ++ ++#define PPE_MTR_CNT0 (RALINK_FRAME_ENGINE_BASE+RACMTABLE_OFFSET+0x200) /* 0 ~ 63 */ ++/* skip... */ ++#define PPE_MTR_CNT63 (RALINK_FRAME_ENGINE_BASE+RACMTABLE_OFFSET+0x2FC) ++ ++#define GDMA_TX_GBCNT0 (RALINK_FRAME_ENGINE_BASE+RACMTABLE_OFFSET+0x300) /* Transmit good byte cnt for GEport */ ++#define GDMA_TX_GPCNT0 (RALINK_FRAME_ENGINE_BASE+RACMTABLE_OFFSET+0x304) /* Transmit good pkt cnt for GEport */ ++#define GDMA_TX_SKIPCNT0 (RALINK_FRAME_ENGINE_BASE+RACMTABLE_OFFSET+0x308) /* Transmit skip cnt for GEport */ ++#define GDMA_TX_COLCNT0 (RALINK_FRAME_ENGINE_BASE+RACMTABLE_OFFSET+0x30C) /* Transmit collision cnt for GEport */ ++ ++/* update these address mapping to fit data sheet v0.26, by bobtseng, 2007.6.14 */ ++#define GDMA_RX_GBCNT0 (RALINK_FRAME_ENGINE_BASE+RACMTABLE_OFFSET+0x320) ++#define GDMA_RX_GPCNT0 (RALINK_FRAME_ENGINE_BASE+RACMTABLE_OFFSET+0x324) ++#define GDMA_RX_OERCNT0 (RALINK_FRAME_ENGINE_BASE+RACMTABLE_OFFSET+0x328) ++#define GDMA_RX_FERCNT0 (RALINK_FRAME_ENGINE_BASE+RACMTABLE_OFFSET+0x32C) ++#define GDMA_RX_SERCNT0 (RALINK_FRAME_ENGINE_BASE+RACMTABLE_OFFSET+0x330) ++#define GDMA_RX_LERCNT0 (RALINK_FRAME_ENGINE_BASE+RACMTABLE_OFFSET+0x334) ++#define GDMA_RX_CERCNT0 (RALINK_FRAME_ENGINE_BASE+RACMTABLE_OFFSET+0x338) ++#define GDMA_RX_FCCNT1 (RALINK_FRAME_ENGINE_BASE+RACMTABLE_OFFSET+0x33C) ++ ++#endif ++ ++/* LRO global control */ ++/* Bits [15:0]:LRO_ALT_RFSH_TIMER, Bits [20:16]:LRO_ALT_TICK_TIMER */ ++#define LRO_ALT_REFRESH_TIMER (RALINK_FRAME_ENGINE_BASE+0x001C) ++ ++/* LRO auto-learn table info */ ++#define PDMA_FE_ALT_CF8 (RALINK_FRAME_ENGINE_BASE+0x0300) ++#define PDMA_FE_ALT_SGL_CFC (RALINK_FRAME_ENGINE_BASE+0x0304) ++#define PDMA_FE_ALT_SEQ_CFC (RALINK_FRAME_ENGINE_BASE+0x0308) ++ ++/* LRO controls */ ++#define ADMA_LRO_CTRL_OFFSET 0x0980 ++/* ++ * Bit [0]:LRO_EN, Bit [1]:LRO_IPv6_EN, Bit [2]:MULTIPLE_NON_LRO_RX_RING_EN, Bit [3]:MULTIPLE_RXD_PREFETCH_EN, ++ * Bit [4]:RXD_PREFETCH_EN, Bit [5]:LRO_DLY_INT_EN, Bit [6]:LRO_CRSN_BNW, Bit [7]:L3_CKS_UPD_EN, ++ * Bit [20]:first_ineligible_pkt_redirect_en, Bit [21]:cr_lro_alt_score_mode, Bit [22]:cr_lro_alt_rplc_mode, ++ * Bit [23]:cr_lro_l4_ctrl_psh_en, Bits [28:26]:LRO_RING_RELINGUISH_REQ, Bits [31:29]:LRO_RING_RELINGUISH_DONE ++ */ ++#define ADMA_LRO_CTRL_DW0 (RALINK_FRAME_ENGINE_BASE+ADMA_LRO_CTRL_OFFSET+0x00) ++/* Bits [31:0]:LRO_CPU_REASON */ ++#define ADMA_LRO_CTRL_DW1 (RALINK_FRAME_ENGINE_BASE+ADMA_LRO_CTRL_OFFSET+0x04) ++/* Bits [31:0]:AUTO_LEARN_LRO_ELIGIBLE_THRESHOLD */ ++#define ADMA_LRO_CTRL_DW2 (RALINK_FRAME_ENGINE_BASE+ADMA_LRO_CTRL_OFFSET+0x08) ++/* ++ * Bits [7:0]:LRO_MAX_AGGREGATED_CNT, Bits [11:8]:LRO_VLAN_EN, Bits [13:12]:LRO_VLAN_VID_CMP_DEPTH, ++ * Bit [14]:ADMA_FW_RSTN_REQ, Bit [15]:ADMA_MODE, Bits [31:16]:LRO_MIN_RXD_SDL0 ++ */ ++#define ADMA_LRO_CTRL_DW3 (RALINK_FRAME_ENGINE_BASE+ADMA_LRO_CTRL_OFFSET+0x0C) ++ ++/* LRO RX delay interrupt configurations */ ++#define LRO_RX1_DLY_INT (RALINK_FRAME_ENGINE_BASE+0x0a70) ++#define LRO_RX2_DLY_INT (RALINK_FRAME_ENGINE_BASE+0x0a74) ++#define LRO_RX3_DLY_INT (RALINK_FRAME_ENGINE_BASE+0x0a78) ++ ++/* LRO auto-learn configurations */ ++#define PDMA_LRO_ATL_OVERFLOW_ADJ_OFFSET 0x0990 ++#define PDMA_LRO_ATL_OVERFLOW_ADJ (RALINK_FRAME_ENGINE_BASE+PDMA_LRO_ATL_OVERFLOW_ADJ_OFFSET) ++#define LRO_ALT_SCORE_DELTA (RALINK_FRAME_ENGINE_BASE+0x0a4c) ++ ++/* LRO agg timer configurations */ ++#define LRO_MAX_AGG_TIME (RALINK_FRAME_ENGINE_BASE+0x0a5c) ++ ++/* LRO configurations of RX ring #0 */ ++#define LRO_RXRING0_OFFSET 0x0b00 ++#define LRO_RX_RING0_DIP_DW0 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING0_OFFSET+0x04) ++#define LRO_RX_RING0_DIP_DW1 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING0_OFFSET+0x08) ++#define LRO_RX_RING0_DIP_DW2 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING0_OFFSET+0x0C) ++#define LRO_RX_RING0_DIP_DW3 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING0_OFFSET+0x10) ++#define LRO_RX_RING0_CTRL_DW1 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING0_OFFSET+0x28) ++/* Bit [8]:RING0_VLD, Bit [9]:RING0_MYIP_VLD */ ++#define LRO_RX_RING0_CTRL_DW2 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING0_OFFSET+0x2C) ++#define LRO_RX_RING0_CTRL_DW3 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING0_OFFSET+0x30) ++/* LRO configurations of RX ring #1 */ ++#define LRO_RXRING1_OFFSET 0x0b40 ++#define LRO_RX_RING1_STP_DTP_DW (RALINK_FRAME_ENGINE_BASE+LRO_RXRING1_OFFSET+0x00) ++#define LRO_RX_RING1_DIP_DW0 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING1_OFFSET+0x04) ++#define LRO_RX_RING1_DIP_DW1 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING1_OFFSET+0x08) ++#define LRO_RX_RING1_DIP_DW2 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING1_OFFSET+0x0C) ++#define LRO_RX_RING1_DIP_DW3 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING1_OFFSET+0x10) ++#define LRO_RX_RING1_SIP_DW0 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING1_OFFSET+0x14) ++#define LRO_RX_RING1_SIP_DW1 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING1_OFFSET+0x18) ++#define LRO_RX_RING1_SIP_DW2 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING1_OFFSET+0x1C) ++#define LRO_RX_RING1_SIP_DW3 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING1_OFFSET+0x20) ++#define LRO_RX_RING1_CTRL_DW0 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING1_OFFSET+0x24) ++#define LRO_RX_RING1_CTRL_DW1 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING1_OFFSET+0x28) ++#define LRO_RX_RING1_CTRL_DW2 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING1_OFFSET+0x2C) ++#define LRO_RX_RING1_CTRL_DW3 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING1_OFFSET+0x30) ++#define LRO_RXRING2_OFFSET 0x0b80 ++#define LRO_RX_RING2_STP_DTP_DW (RALINK_FRAME_ENGINE_BASE+LRO_RXRING2_OFFSET+0x00) ++#define LRO_RX_RING2_DIP_DW0 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING2_OFFSET+0x04) ++#define LRO_RX_RING2_DIP_DW1 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING2_OFFSET+0x08) ++#define LRO_RX_RING2_DIP_DW2 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING2_OFFSET+0x0C) ++#define LRO_RX_RING2_DIP_DW3 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING2_OFFSET+0x10) ++#define LRO_RX_RING2_SIP_DW0 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING2_OFFSET+0x14) ++#define LRO_RX_RING2_SIP_DW1 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING2_OFFSET+0x18) ++#define LRO_RX_RING2_SIP_DW2 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING2_OFFSET+0x1C) ++#define LRO_RX_RING2_SIP_DW3 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING2_OFFSET+0x20) ++#define LRO_RX_RING2_CTRL_DW0 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING2_OFFSET+0x24) ++#define LRO_RX_RING2_CTRL_DW1 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING2_OFFSET+0x28) ++#define LRO_RX_RING2_CTRL_DW2 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING2_OFFSET+0x2C) ++#define LRO_RX_RING2_CTRL_DW3 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING2_OFFSET+0x30) ++#define LRO_RXRING3_OFFSET 0x0bc0 ++#define LRO_RX_RING3_STP_DTP_DW (RALINK_FRAME_ENGINE_BASE+LRO_RXRING3_OFFSET+0x00) ++#define LRO_RX_RING3_DIP_DW0 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING3_OFFSET+0x04) ++#define LRO_RX_RING3_DIP_DW1 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING3_OFFSET+0x08) ++#define LRO_RX_RING3_DIP_DW2 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING3_OFFSET+0x0C) ++#define LRO_RX_RING3_DIP_DW3 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING3_OFFSET+0x10) ++#define LRO_RX_RING3_SIP_DW0 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING3_OFFSET+0x14) ++#define LRO_RX_RING3_SIP_DW1 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING3_OFFSET+0x18) ++#define LRO_RX_RING3_SIP_DW2 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING3_OFFSET+0x1C) ++#define LRO_RX_RING3_SIP_DW3 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING3_OFFSET+0x20) ++#define LRO_RX_RING3_CTRL_DW0 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING3_OFFSET+0x24) ++#define LRO_RX_RING3_CTRL_DW1 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING3_OFFSET+0x28) ++#define LRO_RX_RING3_CTRL_DW2 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING3_OFFSET+0x2C) ++#define LRO_RX_RING3_CTRL_DW3 (RALINK_FRAME_ENGINE_BASE+LRO_RXRING3_OFFSET+0x30) ++ ++/* LRO RX ring mode */ ++#define PDMA_RX_NORMAL_MODE (0x0) ++#define PDMA_RX_PSE_MODE (0x1) ++#define PDMA_RX_FORCE_PORT (0x2) ++#define PDMA_RX_AUTO_LEARN (0x3) ++ ++#define ADMA_RX_RING0 (0) ++#define ADMA_RX_RING1 (1) ++#define ADMA_RX_RING2 (2) ++#define ADMA_RX_RING3 (3) ++ ++#define ADMA_RX_LEN0_MASK (0x3fff) ++#define ADMA_RX_LEN1_MASK (0x3) ++ ++#define PDMA_LRO_EN BIT(0) ++#define PDMA_LRO_IPV6_EN BIT(1) ++#define PDMA_LRO_IPV4_CSUM_UPDATE_EN BIT(7) ++#define PDMA_LRO_IPV4_CTRL_PUSH_EN BIT(23) ++#define PDMA_LRO_RXD_PREFETCH_EN BITS(3,4) ++#define PDMA_NON_LRO_MULTI_EN BIT(2) ++#define PDMA_LRO_DLY_INT_EN BIT(5) ++#define PDMA_LRO_FUSH_REQ BITS(26,28) ++#define PDMA_LRO_RELINGUISH BITS(29,31) ++#define PDMA_LRO_FREQ_PRI_ADJ BITS(16,19) ++#define PDMA_LRO_TPUT_PRE_ADJ BITS(8,11) ++#define PDMA_LRO_TPUT_PRI_ADJ BITS(12,15) ++#define PDMA_LRO_ALT_SCORE_MODE BIT(21) ++#define PDMA_LRO_RING_AGE1 BITS(22,31) ++#define PDMA_LRO_RING_AGE2 BITS(0,5) ++#define PDMA_LRO_RING_AGG BITS(10,25) ++#define PDMA_LRO_RING_AGG_CNT1 BITS(26,31) ++#define PDMA_LRO_RING_AGG_CNT2 BITS(0,1) ++#define PDMA_LRO_ALT_TICK_TIMER BITS(16,20) ++#define PDMA_LRO_LRO_MIN_RXD_SDL0 BITS(16,31) ++ ++#define PDMA_LRO_DLY_INT_EN_OFFSET (5) ++#define PDMA_LRO_TPUT_PRE_ADJ_OFFSET (8) ++#define PDMA_LRO_FREQ_PRI_ADJ_OFFSET (16) ++#define PDMA_LRO_LRO_MIN_RXD_SDL0_OFFSET (16) ++#define PDMA_LRO_TPUT_PRI_ADJ_OFFSET (12) ++#define PDMA_LRO_ALT_SCORE_MODE_OFFSET (21) ++#define PDMA_LRO_FUSH_REQ_OFFSET (26) ++#define PDMA_NON_LRO_MULTI_EN_OFFSET (2) ++#define PDMA_LRO_IPV6_EN_OFFSET (1) ++#define PDMA_LRO_RXD_PREFETCH_EN_OFFSET (3) ++#define PDMA_LRO_IPV4_CSUM_UPDATE_EN_OFFSET (7) ++#define PDMA_LRO_IPV4_CTRL_PUSH_EN_OFFSET (23) ++#define PDMA_LRO_ALT_TICK_TIMER_OFFSET (16) ++ ++#define PDMA_LRO_TPUT_OVERFLOW_ADJ BITS(12,31) ++#define PDMA_LRO_CNT_OVERFLOW_ADJ BITS(0,11) ++ ++#define PDMA_LRO_TPUT_OVERFLOW_ADJ_OFFSET (12) ++#define PDMA_LRO_CNT_OVERFLOW_ADJ_OFFSET (0) ++ ++#define PDMA_LRO_ALT_BYTE_CNT_MODE (0) ++#define PDMA_LRO_ALT_PKT_CNT_MODE (1) ++ ++/* LRO_RX_RING1_CTRL_DW1 offsets */ ++#define PDMA_LRO_AGE_H_OFFSET (10) ++#define PDMA_LRO_RING_AGE1_OFFSET (22) ++#define PDMA_LRO_RING_AGG_CNT1_OFFSET (26) ++/* LRO_RX_RING1_CTRL_DW2 offsets */ ++#define PDMA_RX_MODE_OFFSET (6) ++#define PDMA_RX_PORT_VALID_OFFSET (8) ++#define PDMA_RX_MYIP_VALID_OFFSET (9) ++#define PDMA_LRO_RING_AGE2_OFFSET (0) ++#define PDMA_LRO_RING_AGG_OFFSET (10) ++#define PDMA_LRO_RING_AGG_CNT2_OFFSET (0) ++/* LRO_RX_RING1_CTRL_DW3 offsets */ ++#define PDMA_LRO_AGG_CNT_H_OFFSET (6) ++/* LRO_RX_RING1_STP_DTP_DW offsets */ ++#define PDMA_RX_TCP_SRC_PORT_OFFSET (16) ++#define PDMA_RX_TCP_DEST_PORT_OFFSET (0) ++/* LRO_RX_RING1_CTRL_DW0 offsets */ ++#define PDMA_RX_IPV4_FORCE_OFFSET (1) ++#define PDMA_RX_IPV6_FORCE_OFFSET (0) ++ ++#define SET_ADMA_RX_LEN0(x) ((x)&ADMA_RX_LEN0_MASK) ++#define SET_ADMA_RX_LEN1(x) ((x)&ADMA_RX_LEN1_MASK) ++ ++#define SET_PDMA_LRO_MAX_AGG_CNT(x) \ ++ { volatile unsigned int *addr = (unsigned int*)ADMA_LRO_CTRL_DW3; \ ++ *addr &= ~0xff; \ ++ *addr |= ((x) & 0xff); \ ++ } ++#define SET_PDMA_LRO_FLUSH_REQ(x) \ ++ { volatile unsigned int *addr = (unsigned int*)ADMA_LRO_CTRL_DW0; \ ++ *addr &= ~PDMA_LRO_FUSH_REQ; \ ++ *addr |= ((x) & 0x7)<<PDMA_LRO_FUSH_REQ_OFFSET; \ ++ } ++#define SET_PDMA_LRO_IPV6_EN(x) \ ++ { volatile unsigned int *addr = (unsigned int*)ADMA_LRO_CTRL_DW0; \ ++ *addr &= ~PDMA_LRO_IPV6_EN; \ ++ *addr |= ((x) & 0x1)<<PDMA_LRO_IPV6_EN_OFFSET; \ ++ } ++#if defined(CONFIG_RAETH_HW_LRO_PREFETCH) ++#define SET_PDMA_LRO_RXD_PREFETCH_EN(x) \ ++ { volatile unsigned int *addr = (unsigned int*)ADMA_LRO_CTRL_DW0; \ ++ *addr &= ~PDMA_LRO_RXD_PREFETCH_EN; \ ++ *addr |= ((x) & 0x3)<<PDMA_LRO_RXD_PREFETCH_EN_OFFSET; \ ++ } ++#else ++#define SET_PDMA_LRO_RXD_PREFETCH_EN(x) ++#endif ++#define SET_PDMA_LRO_IPV4_CSUM_UPDATE_EN(x) \ ++ { volatile unsigned int *addr = (unsigned int*)ADMA_LRO_CTRL_DW0; \ ++ *addr &= ~PDMA_LRO_IPV4_CSUM_UPDATE_EN; \ ++ *addr |= ((x) & 0x1)<<PDMA_LRO_IPV4_CSUM_UPDATE_EN_OFFSET; \ ++ } ++#define SET_PDMA_LRO_IPV4_CTRL_PUSH_EN(x) \ ++ { volatile unsigned int *addr = (unsigned int*)ADMA_LRO_CTRL_DW0; \ ++ *addr &= ~PDMA_LRO_IPV4_CTRL_PUSH_EN; \ ++ *addr |= ((x) & 0x1)<<PDMA_LRO_IPV4_CTRL_PUSH_EN_OFFSET; \ ++ } ++#define SET_PDMA_NON_LRO_MULTI_EN(x) \ ++ { volatile unsigned int *addr = (unsigned int*)ADMA_LRO_CTRL_DW0; \ ++ *addr &= ~(PDMA_NON_LRO_MULTI_EN); \ ++ *addr |= ((x) & 0x1)<<PDMA_NON_LRO_MULTI_EN_OFFSET; \ ++ } ++#define SET_PDMA_LRO_FREQ_PRI_ADJ(x) \ ++ { volatile unsigned int *addr = (unsigned int*)ADMA_LRO_CTRL_DW0; \ ++ *addr &= ~PDMA_LRO_FREQ_PRI_ADJ; \ ++ *addr |= ((x) & 0xf)<<PDMA_LRO_FREQ_PRI_ADJ_OFFSET; \ ++ } ++#define SET_PDMA_LRO_TPUT_PRE_ADJ(x) \ ++ { volatile unsigned int *addr = (unsigned int*)ADMA_LRO_CTRL_DW0; \ ++ *addr &= ~PDMA_LRO_TPUT_PRE_ADJ; \ ++ *addr |= ((x) & 0xf)<<PDMA_LRO_TPUT_PRE_ADJ_OFFSET; \ ++ } ++#define SET_PDMA_LRO_TPUT_PRI_ADJ(x) \ ++ { volatile unsigned int *addr = (unsigned int*)ADMA_LRO_CTRL_DW0; \ ++ *addr &= ~PDMA_LRO_TPUT_PRI_ADJ; \ ++ *addr |= ((x) & 0xf)<<PDMA_LRO_TPUT_PRI_ADJ_OFFSET; \ ++ } ++#define SET_PDMA_LRO_ALT_SCORE_MODE(x) \ ++ { volatile unsigned int *addr = (unsigned int*)ADMA_LRO_CTRL_DW0; \ ++ *addr &= ~PDMA_LRO_ALT_SCORE_MODE; \ ++ *addr |= ((x) & 0x1)<<PDMA_LRO_ALT_SCORE_MODE_OFFSET; \ ++ } ++#define SET_PDMA_LRO_DLY_INT_EN(x) \ ++ { volatile unsigned int *addr = (unsigned int*)ADMA_LRO_CTRL_DW0; \ ++ *addr &= ~PDMA_LRO_DLY_INT_EN; \ ++ *addr |= ((x) & 0x1)<<PDMA_LRO_DLY_INT_EN_OFFSET; \ ++ } ++#define SET_PDMA_LRO_BW_THRESHOLD(x) \ ++ { volatile unsigned int *addr = (unsigned int*)ADMA_LRO_CTRL_DW2; \ ++ *addr = (x); \ ++ } ++#define SET_PDMA_LRO_MIN_RXD_SDL(x) \ ++ { volatile unsigned int *addr = (unsigned int*)ADMA_LRO_CTRL_DW3; \ ++ *addr &= ~PDMA_LRO_LRO_MIN_RXD_SDL0; \ ++ *addr |= ((x) & 0xffff)<<PDMA_LRO_LRO_MIN_RXD_SDL0_OFFSET; \ ++ } ++#define SET_PDMA_LRO_TPUT_OVERFLOW_ADJ(x) \ ++ { volatile unsigned int *addr = (unsigned int*)PDMA_LRO_ATL_OVERFLOW_ADJ; \ ++ *addr &= ~PDMA_LRO_TPUT_OVERFLOW_ADJ; \ ++ *addr |= ((x) & 0xfffff)<<PDMA_LRO_TPUT_OVERFLOW_ADJ_OFFSET; \ ++ } ++#define SET_PDMA_LRO_CNT_OVERFLOW_ADJ(x) \ ++ { volatile unsigned int *addr = (unsigned int*)PDMA_LRO_ATL_OVERFLOW_ADJ; \ ++ *addr &= ~PDMA_LRO_CNT_OVERFLOW_ADJ; \ ++ *addr |= ((x) & 0xfff)<<PDMA_LRO_CNT_OVERFLOW_ADJ_OFFSET; \ ++ } ++#define SET_PDMA_LRO_ALT_REFRESH_TIMER_UNIT(x) \ ++ { volatile unsigned int *addr = (unsigned int*)LRO_ALT_REFRESH_TIMER; \ ++ *addr &= ~PDMA_LRO_ALT_TICK_TIMER; \ ++ *addr |= ((x) & 0x1f)<<PDMA_LRO_ALT_TICK_TIMER_OFFSET; \ ++ } ++#define SET_PDMA_LRO_ALT_REFRESH_TIMER(x) \ ++ { volatile unsigned int *addr = (unsigned int*)LRO_ALT_REFRESH_TIMER; \ ++ *addr &= ~0xffff; \ ++ *addr |= ((x) & 0xffff); \ ++ } ++#define SET_PDMA_LRO_MAX_AGG_TIME(x) \ ++ { volatile unsigned int *addr = (unsigned int*)LRO_MAX_AGG_TIME; \ ++ *addr &= ~0xffff; \ ++ *addr |= ((x) & 0xffff); \ ++ } ++#define SET_PDMA_RXRING_MODE(x,y) \ ++ { volatile unsigned int *addr = (unsigned int*)(LRO_RX_RING0_CTRL_DW2 + ((x) << 6)); \ ++ *addr &= ~(0x3<<PDMA_RX_MODE_OFFSET); \ ++ *addr |= (y)<<PDMA_RX_MODE_OFFSET; \ ++ } ++#define SET_PDMA_RXRING_MYIP_VALID(x,y) \ ++ { volatile unsigned int *addr = (unsigned int*)(LRO_RX_RING0_CTRL_DW2 + ((x) << 6)); \ ++ *addr &= ~(0x1<<PDMA_RX_MYIP_VALID_OFFSET); \ ++ *addr |= ((y)&0x1)<<PDMA_RX_MYIP_VALID_OFFSET; \ ++ } ++#define SET_PDMA_RXRING_VALID(x,y) \ ++ { volatile unsigned int *addr = (unsigned int*)(LRO_RX_RING0_CTRL_DW2 + ((x) << 6)); \ ++ *addr &= ~(0x1<<PDMA_RX_PORT_VALID_OFFSET); \ ++ *addr |= ((y)&0x1)<<PDMA_RX_PORT_VALID_OFFSET; \ ++ } ++#define SET_PDMA_RXRING_TCP_SRC_PORT(x,y) \ ++ { volatile unsigned int *addr = (unsigned int*)(LRO_RX_RING1_STP_DTP_DW + (((x)-1) << 6)); \ ++ *addr &= ~(0xffff<<PDMA_RX_TCP_SRC_PORT_OFFSET); \ ++ *addr |= (y)<<PDMA_RX_TCP_SRC_PORT_OFFSET; \ ++ } ++#define SET_PDMA_RXRING_TCP_DEST_PORT(x,y) \ ++ { volatile unsigned int *addr = (unsigned int*)(LRO_RX_RING1_STP_DTP_DW + (((x)-1) << 6)); \ ++ *addr &= ~(0xffff<<PDMA_RX_TCP_DEST_PORT_OFFSET); \ ++ *addr |= (y)<<PDMA_RX_TCP_DEST_PORT_OFFSET; \ ++ } ++#define SET_PDMA_RXRING_IPV4_FORCE_MODE(x,y) \ ++ { volatile unsigned int *addr = (unsigned int*)(LRO_RX_RING1_CTRL_DW0 + (((x)-1) << 6)); \ ++ *addr &= ~(0x1<<PDMA_RX_IPV4_FORCE_OFFSET); \ ++ *addr |= (y)<<PDMA_RX_IPV4_FORCE_OFFSET; \ ++ } ++#define SET_PDMA_RXRING_IPV6_FORCE_MODE(x,y) \ ++ { volatile unsigned int *addr = (unsigned int*)(LRO_RX_RING1_CTRL_DW0 + (((x)-1) << 6)); \ ++ *addr &= ~(0x1<<PDMA_RX_IPV6_FORCE_OFFSET); \ ++ *addr |= (y)<<PDMA_RX_IPV6_FORCE_OFFSET; \ ++ } ++#define SET_PDMA_RXRING_AGE_TIME(x,y) \ ++ { volatile unsigned int *addr1 = (unsigned int*)(LRO_RX_RING0_CTRL_DW1 + ((x) << 6)); \ ++ volatile unsigned int *addr2 = (unsigned int*)(LRO_RX_RING0_CTRL_DW2 + ((x) << 6)); \ ++ *addr1 &= ~PDMA_LRO_RING_AGE1; \ ++ *addr2 &= ~PDMA_LRO_RING_AGE2; \ ++ *addr1 |= ((y) & 0x3ff)<<PDMA_LRO_RING_AGE1_OFFSET; \ ++ *addr2 |= (((y)>>PDMA_LRO_AGE_H_OFFSET) & 0x03f)<<PDMA_LRO_RING_AGE2_OFFSET; \ ++ } ++#define SET_PDMA_RXRING_AGG_TIME(x,y) \ ++ { volatile unsigned int *addr = (unsigned int*)(LRO_RX_RING0_CTRL_DW2 + ((x) << 6)); \ ++ *addr &= ~PDMA_LRO_RING_AGG; \ ++ *addr |= ((y) & 0xffff)<<PDMA_LRO_RING_AGG_OFFSET; \ ++ } ++#define SET_PDMA_RXRING_MAX_AGG_CNT(x,y) \ ++ { volatile unsigned int *addr1 = (unsigned int*)(LRO_RX_RING1_CTRL_DW2 + (((x)-1) << 6)); \ ++ volatile unsigned int *addr2 = (unsigned int*)(LRO_RX_RING1_CTRL_DW3 + (((x)-1) << 6)); \ ++ *addr1 &= ~PDMA_LRO_RING_AGG_CNT1; \ ++ *addr2 &= ~PDMA_LRO_RING_AGG_CNT2; \ ++ *addr1 |= ((y) & 0x3f)<<PDMA_LRO_RING_AGG_CNT1_OFFSET; \ ++ *addr2 |= (((y)>>PDMA_LRO_AGG_CNT_H_OFFSET) & 0x03)<<PDMA_LRO_RING_AGG_CNT2_OFFSET; \ ++ } ++ ++typedef struct _PDMA_LRO_AUTO_TLB_INFO0_ PDMA_LRO_AUTO_TLB_INFO0_T; ++typedef struct _PDMA_LRO_AUTO_TLB_INFO1_ PDMA_LRO_AUTO_TLB_INFO1_T; ++typedef struct _PDMA_LRO_AUTO_TLB_INFO2_ PDMA_LRO_AUTO_TLB_INFO2_T; ++typedef struct _PDMA_LRO_AUTO_TLB_INFO3_ PDMA_LRO_AUTO_TLB_INFO3_T; ++typedef struct _PDMA_LRO_AUTO_TLB_INFO4_ PDMA_LRO_AUTO_TLB_INFO4_T; ++typedef struct _PDMA_LRO_AUTO_TLB_INFO5_ PDMA_LRO_AUTO_TLB_INFO5_T; ++typedef struct _PDMA_LRO_AUTO_TLB_INFO6_ PDMA_LRO_AUTO_TLB_INFO6_T; ++typedef struct _PDMA_LRO_AUTO_TLB_INFO7_ PDMA_LRO_AUTO_TLB_INFO7_T; ++typedef struct _PDMA_LRO_AUTO_TLB_INFO8_ PDMA_LRO_AUTO_TLB_INFO8_T; ++ ++struct _PDMA_LRO_AUTO_TLB_INFO0_ ++{ ++ unsigned int DTP : 16; ++ unsigned int STP : 16; ++}; ++struct _PDMA_LRO_AUTO_TLB_INFO1_ ++{ ++ unsigned int SIP0 : 32; ++}; ++struct _PDMA_LRO_AUTO_TLB_INFO2_ ++{ ++ unsigned int SIP1 : 32; ++}; ++struct _PDMA_LRO_AUTO_TLB_INFO3_ ++{ ++ unsigned int SIP2 : 32; ++}; ++struct _PDMA_LRO_AUTO_TLB_INFO4_ ++{ ++ unsigned int SIP3 : 32; ++}; ++struct _PDMA_LRO_AUTO_TLB_INFO5_ ++{ ++ unsigned int VLAN_VID0 : 32; ++}; ++struct _PDMA_LRO_AUTO_TLB_INFO6_ ++{ ++ unsigned int VLAN_VID1 : 16; ++ unsigned int VLAN_VID_VLD : 4; ++ unsigned int CNT : 12; ++}; ++struct _PDMA_LRO_AUTO_TLB_INFO7_ ++{ ++ unsigned int DW_LEN : 32; ++}; ++struct _PDMA_LRO_AUTO_TLB_INFO8_ ++{ ++ unsigned int DIP_ID : 2; ++ unsigned int IPV6 : 1; ++ unsigned int IPV4 : 1; ++ unsigned int RESV : 27; ++ unsigned int VALID : 1; ++}; ++struct PDMA_LRO_AUTO_TLB_INFO { ++ PDMA_LRO_AUTO_TLB_INFO0_T auto_tlb_info0; ++ PDMA_LRO_AUTO_TLB_INFO1_T auto_tlb_info1; ++ PDMA_LRO_AUTO_TLB_INFO2_T auto_tlb_info2; ++ PDMA_LRO_AUTO_TLB_INFO3_T auto_tlb_info3; ++ PDMA_LRO_AUTO_TLB_INFO4_T auto_tlb_info4; ++ PDMA_LRO_AUTO_TLB_INFO5_T auto_tlb_info5; ++ PDMA_LRO_AUTO_TLB_INFO6_T auto_tlb_info6; ++ PDMA_LRO_AUTO_TLB_INFO7_T auto_tlb_info7; ++ PDMA_LRO_AUTO_TLB_INFO8_T auto_tlb_info8; ++}; ++ ++#if defined (CONFIG_HW_SFQ) ++#define VQTX_TB_BASE0 (ETHDMASYS_FRAME_ENGINE_BASE + 0x1980) ++#define VQTX_TB_BASE1 (ETHDMASYS_FRAME_ENGINE_BASE + 0x1984) ++#define VQTX_TB_BASE2 (ETHDMASYS_FRAME_ENGINE_BASE + 0x1988) ++#define VQTX_TB_BASE3 (ETHDMASYS_FRAME_ENGINE_BASE + 0x198C) ++#define SFQ_OFFSET 0x1A80 ++#define VQTX_GLO (ETHDMASYS_FRAME_ENGINE_BASE + SFQ_OFFSET) ++#define VQTX_INVLD_PTR (ETHDMASYS_FRAME_ENGINE_BASE + SFQ_OFFSET + 0x0C) ++#define VQTX_NUM (ETHDMASYS_FRAME_ENGINE_BASE + SFQ_OFFSET + 0x10) ++#define VQTX_SCH (ETHDMASYS_FRAME_ENGINE_BASE + SFQ_OFFSET + 0x18) ++#define VQTX_HASH_CFG (ETHDMASYS_FRAME_ENGINE_BASE + SFQ_OFFSET + 0x20) ++#define VQTX_HASH_SD (ETHDMASYS_FRAME_ENGINE_BASE + SFQ_OFFSET + 0x24) ++#define VQTX_VLD_CFG (ETHDMASYS_FRAME_ENGINE_BASE + SFQ_OFFSET + 0x30) ++#define VQTX_MIB_IF (ETHDMASYS_FRAME_ENGINE_BASE + SFQ_OFFSET + 0x3C) ++#define VQTX_MIB_PCNT (ETHDMASYS_FRAME_ENGINE_BASE + SFQ_OFFSET + 0x40) ++#define VQTX_MIB_BCNT0 (ETHDMASYS_FRAME_ENGINE_BASE + SFQ_OFFSET + 0x44) ++#define VQTX_MIB_BCNT1 (ETHDMASYS_FRAME_ENGINE_BASE + SFQ_OFFSET + 0x48) ++ ++#define VQTX_MIB_EN (1<<17) ++#define VQTX_NUM_0 (4<<0) ++#define VQTX_NUM_1 (4<<4) ++#define VQTX_NUM_2 (4<<8) ++#define VQTX_NUM_3 (4<<12) ++ ++/*========================================= ++ SFQ Table Format define ++=========================================*/ ++typedef struct _SFQ_INFO1_ SFQ_INFO1_T; ++ ++struct _SFQ_INFO1_ ++{ ++ unsigned int VQHPTR; ++}; ++//------------------------------------------------- ++typedef struct _SFQ_INFO2_ SFQ_INFO2_T; ++ ++struct _SFQ_INFO2_ ++{ ++ unsigned int VQTPTR; ++}; ++//------------------------------------------------- ++typedef struct _SFQ_INFO3_ SFQ_INFO3_T; ++ ++struct _SFQ_INFO3_ ++{ ++ unsigned int QUE_DEPTH:16; ++ unsigned int DEFICIT_CNT:16; ++}; ++//------------------------------------------------- ++typedef struct _SFQ_INFO4_ SFQ_INFO4_T; ++ ++struct _SFQ_INFO4_ ++{ ++ unsigned int RESV; ++}; ++//------------------------------------------------- ++ ++typedef struct _SFQ_INFO5_ SFQ_INFO5_T; ++ ++struct _SFQ_INFO5_ ++{ ++ unsigned int PKT_CNT; ++}; ++//------------------------------------------------- ++ ++typedef struct _SFQ_INFO6_ SFQ_INFO6_T; ++ ++struct _SFQ_INFO6_ ++{ ++ unsigned int BYTE_CNT; ++}; ++//------------------------------------------------- ++ ++typedef struct _SFQ_INFO7_ SFQ_INFO7_T; ++ ++struct _SFQ_INFO7_ ++{ ++ unsigned int BYTE_CNT; ++}; ++//------------------------------------------------- ++ ++typedef struct _SFQ_INFO8_ SFQ_INFO8_T; ++ ++struct _SFQ_INFO8_ ++{ ++ unsigned int RESV; ++}; ++ ++ ++struct SFQ_table { ++ SFQ_INFO1_T sfq_info1; ++ SFQ_INFO2_T sfq_info2; ++ SFQ_INFO3_T sfq_info3; ++ SFQ_INFO4_T sfq_info4; ++ SFQ_INFO5_T sfq_info5; ++ SFQ_INFO6_T sfq_info6; ++ SFQ_INFO7_T sfq_info7; ++ SFQ_INFO8_T sfq_info8; ++ ++}; ++#endif ++#if defined (CONFIG_RAETH_HW_LRO) || defined (CONFIG_RAETH_MULTIPLE_RX_RING) ++#define FE_GDM_RXID1_OFFSET (0x0130) ++#define FE_GDM_RXID1 (RALINK_FRAME_ENGINE_BASE+FE_GDM_RXID1_OFFSET) ++#define GDM_VLAN_PRI7_RXID_SEL BITS(30,31) ++#define GDM_VLAN_PRI6_RXID_SEL BITS(28,29) ++#define GDM_VLAN_PRI5_RXID_SEL BITS(26,27) ++#define GDM_VLAN_PRI4_RXID_SEL BITS(24,25) ++#define GDM_VLAN_PRI3_RXID_SEL BITS(22,23) ++#define GDM_VLAN_PRI2_RXID_SEL BITS(20,21) ++#define GDM_VLAN_PRI1_RXID_SEL BITS(18,19) ++#define GDM_VLAN_PRI0_RXID_SEL BITS(16,17) ++#define GDM_TCP_ACK_RXID_SEL BITS(4,5) ++#define GDM_TCP_ACK_WZPC BIT(3) ++#define GDM_RXID_PRI_SEL BITS(0,2) ++ ++#define FE_GDM_RXID2_OFFSET (0x0134) ++#define FE_GDM_RXID2 (RALINK_FRAME_ENGINE_BASE+FE_GDM_RXID2_OFFSET) ++#define GDM_STAG7_RXID_SEL BITS(30,31) ++#define GDM_STAG6_RXID_SEL BITS(28,29) ++#define GDM_STAG5_RXID_SEL BITS(26,27) ++#define GDM_STAG4_RXID_SEL BITS(24,25) ++#define GDM_STAG3_RXID_SEL BITS(22,23) ++#define GDM_STAG2_RXID_SEL BITS(20,21) ++#define GDM_STAG1_RXID_SEL BITS(18,19) ++#define GDM_STAG0_RXID_SEL BITS(16,17) ++#define GDM_PID2_RXID_SEL BITS(2,3) ++#define GDM_PID1_RXID_SEL BITS(0,1) ++ ++#define GDM_PRI_PID (0) ++#define GDM_PRI_VLAN_PID (1) ++#define GDM_PRI_ACK_PID (2) ++#define GDM_PRI_VLAN_ACK_PID (3) ++#define GDM_PRI_ACK_VLAN_PID (4) ++ ++#define SET_GDM_VLAN_PRI_RXID_SEL(x,y) \ ++ { volatile unsigned int *addr = (unsigned int *)FE_GDM_RXID1; \ ++ *addr &= ~(0x03 << (((x) << 1)+16)); \ ++ *addr |= ((y) & 0x3) << (((x) << 1)+16); \ ++ } ++#define SET_GDM_TCP_ACK_RXID_SEL(x) \ ++ { volatile unsigned int *addr = (unsigned int *)FE_GDM_RXID1; \ ++ *addr &= ~(GDM_TCP_ACK_RXID_SEL); \ ++ *addr |= ((x) & 0x3) << 4; \ ++ } ++#define SET_GDM_TCP_ACK_WZPC(x) \ ++ { volatile unsigned int *addr = (unsigned int *)FE_GDM_RXID1; \ ++ *addr &= ~(GDM_TCP_ACK_WZPC); \ ++ *addr |= ((x) & 0x1) << 3; \ ++ } ++#define SET_GDM_RXID_PRI_SEL(x) \ ++ { volatile unsigned int *addr = (unsigned int *)FE_GDM_RXID1; \ ++ *addr &= ~(GDM_RXID_PRI_SEL); \ ++ *addr |= (x) & 0x7; \ ++ } ++#define GDM_STAG_RXID_SEL(x,y) \ ++ { volatile unsigned int *addr = (unsigned int *)FE_GDM_RXID2; \ ++ *addr &= ~(0x03 << (((x) << 1)+16)); \ ++ *addr |= ((y) & 0x3) << (((x) << 1)+16); \ ++ } ++#define SET_GDM_PID2_RXID_SEL(x) \ ++ { volatile unsigned int *addr = (unsigned int *)FE_GDM_RXID2; \ ++ *addr &= ~(GDM_PID2_RXID_SEL); \ ++ *addr |= ((x) & 0x3) << 2; \ ++ } ++#define SET_GDM_PID1_RXID_SEL(x) \ ++ { volatile unsigned int *addr = (unsigned int *)FE_GDM_RXID2; \ ++ *addr &= ~(GDM_PID1_RXID_SEL); \ ++ *addr |= ((x) & 0x3); \ ++ } ++#endif /* CONFIG_RAETH_MULTIPLE_RX_RING */ ++/* Per Port Packet Counts in RT3052, added by bobtseng 2009.4.17. */ ++#define PORT0_PKCOUNT (0xb01100e8) ++#define PORT1_PKCOUNT (0xb01100ec) ++#define PORT2_PKCOUNT (0xb01100f0) ++#define PORT3_PKCOUNT (0xb01100f4) ++#define PORT4_PKCOUNT (0xb01100f8) ++#define PORT5_PKCOUNT (0xb01100fc) ++ ++#if defined (CONFIG_ARCH_MT7623) ++#include "sync_write.h" ++#define sysRegRead(phys) (*(volatile unsigned int *)((phys))) ++#define sysRegWrite(phys, val) mt65xx_reg_sync_writel((val), (phys)) ++#else ++#define PHYS_TO_K1(physaddr) KSEG1ADDR(physaddr) ++#define sysRegRead(phys) (*(volatile unsigned int *)PHYS_TO_K1(phys)) ++#define sysRegWrite(phys, val) ((*(volatile unsigned int *)PHYS_TO_K1(phys)) = (val)) ++#endif ++ ++#define u_long unsigned long ++#define u32 unsigned int ++#define u16 unsigned short ++ ++ ++/* ====================================== */ ++#define GDM1_DISPAD BIT(18) ++#define GDM1_DISCRC BIT(17) ++ ++//GDMA1 uni-cast frames destination port ++#define GDM1_ICS_EN (0x1 << 22) ++#define GDM1_TCS_EN (0x1 << 21) ++#define GDM1_UCS_EN (0x1 << 20) ++#define GDM1_JMB_EN (0x1 << 19) ++#define GDM1_STRPCRC (0x1 << 16) ++#define GDM1_UFRC_P_CPU (0 << 12) ++#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++#define GDM1_UFRC_P_PPE (4 << 12) ++#else ++#define GDM1_UFRC_P_PPE (6 << 12) ++#endif ++ ++//GDMA1 broad-cast MAC address frames ++#define GDM1_BFRC_P_CPU (0 << 8) ++#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++#define GDM1_BFRC_P_PPE (4 << 8) ++#else ++#define GDM1_BFRC_P_PPE (6 << 8) ++#endif ++ ++//GDMA1 multi-cast MAC address frames ++#define GDM1_MFRC_P_CPU (0 << 4) ++#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++#define GDM1_MFRC_P_PPE (4 << 4) ++#else ++#define GDM1_MFRC_P_PPE (6 << 4) ++#endif ++ ++//GDMA1 other MAC address frames destination port ++#define GDM1_OFRC_P_CPU (0 << 0) ++#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++#define GDM1_OFRC_P_PPE (4 << 0) ++#else ++#define GDM1_OFRC_P_PPE (6 << 0) ++#endif ++ ++#if defined (CONFIG_RALINK_RT6856) || defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++/* checksum generator registers are removed */ ++#define ICS_GEN_EN (0 << 2) ++#define UCS_GEN_EN (0 << 1) ++#define TCS_GEN_EN (0 << 0) ++#else ++#define ICS_GEN_EN (1 << 2) ++#define UCS_GEN_EN (1 << 1) ++#define TCS_GEN_EN (1 << 0) ++#endif ++ ++// MDIO_CFG bit ++#define MDIO_CFG_GP1_FC_TX (1 << 11) ++#define MDIO_CFG_GP1_FC_RX (1 << 10) ++ ++/* ====================================== */ ++/* ====================================== */ ++#define GP1_LNK_DWN BIT(9) ++#define GP1_AN_FAIL BIT(8) ++/* ====================================== */ ++/* ====================================== */ ++#define PSE_RESET BIT(0) ++/* ====================================== */ ++#define PST_DRX_IDX3 BIT(19) ++#define PST_DRX_IDX2 BIT(18) ++#define PST_DRX_IDX1 BIT(17) ++#define PST_DRX_IDX0 BIT(16) ++#define PST_DTX_IDX3 BIT(3) ++#define PST_DTX_IDX2 BIT(2) ++#define PST_DTX_IDX1 BIT(1) ++#define PST_DTX_IDX0 BIT(0) ++ ++#define RX_2B_OFFSET BIT(31) ++#define DESC_32B_EN BIT(8) ++#define TX_WB_DDONE BIT(6) ++#define RX_DMA_BUSY BIT(3) ++#define TX_DMA_BUSY BIT(1) ++#define RX_DMA_EN BIT(2) ++#define TX_DMA_EN BIT(0) ++ ++#define PDMA_BT_SIZE_4DWORDS (0<<4) ++#define PDMA_BT_SIZE_8DWORDS (1<<4) ++#define PDMA_BT_SIZE_16DWORDS (2<<4) ++#define PDMA_BT_SIZE_32DWORDS (3<<4) ++ ++#define ADMA_RX_BT_SIZE_4DWORDS (0<<11) ++#define ADMA_RX_BT_SIZE_8DWORDS (1<<11) ++#define ADMA_RX_BT_SIZE_16DWORDS (2<<11) ++#define ADMA_RX_BT_SIZE_32DWORDS (3<<11) ++ ++/* Register bits. ++ */ ++ ++#define MACCFG_RXEN (1<<2) ++#define MACCFG_TXEN (1<<3) ++#define MACCFG_PROMISC (1<<18) ++#define MACCFG_RXMCAST (1<<19) ++#define MACCFG_FDUPLEX (1<<20) ++#define MACCFG_PORTSEL (1<<27) ++#define MACCFG_HBEATDIS (1<<28) ++ ++ ++#define DMACTL_SR (1<<1) /* Start/Stop Receive */ ++#define DMACTL_ST (1<<13) /* Start/Stop Transmission Command */ ++ ++#define DMACFG_SWR (1<<0) /* Software Reset */ ++#define DMACFG_BURST32 (32<<8) ++ ++#define DMASTAT_TS 0x00700000 /* Transmit Process State */ ++#define DMASTAT_RS 0x000e0000 /* Receive Process State */ ++ ++#define MACCFG_INIT 0 //(MACCFG_FDUPLEX) // | MACCFG_PORTSEL) ++ ++ ++ ++/* Descriptor bits. ++ */ ++#define R_OWN 0x80000000 /* Own Bit */ ++#define RD_RER 0x02000000 /* Receive End Of Ring */ ++#define RD_LS 0x00000100 /* Last Descriptor */ ++#define RD_ES 0x00008000 /* Error Summary */ ++#define RD_CHAIN 0x01000000 /* Chained */ ++ ++/* Word 0 */ ++#define T_OWN 0x80000000 /* Own Bit */ ++#define TD_ES 0x00008000 /* Error Summary */ ++ ++/* Word 1 */ ++#define TD_LS 0x40000000 /* Last Segment */ ++#define TD_FS 0x20000000 /* First Segment */ ++#define TD_TER 0x08000000 /* Transmit End Of Ring */ ++#define TD_CHAIN 0x01000000 /* Chained */ ++ ++ ++#define TD_SET 0x08000000 /* Setup Packet */ ++ ++ ++#define POLL_DEMAND 1 ++ ++#define RSTCTL (0x34) ++#define RSTCTL_RSTENET1 (1<<19) ++#define RSTCTL_RSTENET2 (1<<20) ++ ++#define INIT_VALUE_OF_RT2883_PSE_FQ_CFG 0xff908000 ++#define INIT_VALUE_OF_PSE_FQFC_CFG 0x80504000 ++#define INIT_VALUE_OF_FORCE_100_FD 0x1001BC01 ++#define INIT_VALUE_OF_FORCE_1000_FD 0x1F01DC01 ++ ++// Define Whole FE Reset Register ++#define RSTCTRL (RALINK_SYSCTL_BASE + 0x34) ++#define RT2880_AGPIOCFG_REG (RALINK_SYSCTL_BASE + 0x3C) ++ ++/*========================================= ++ PDMA RX Descriptor Format define ++=========================================*/ ++ ++//------------------------------------------------- ++typedef struct _PDMA_RXD_INFO1_ PDMA_RXD_INFO1_T; ++ ++struct _PDMA_RXD_INFO1_ ++{ ++ unsigned int PDP0; ++}; ++//------------------------------------------------- ++typedef struct _PDMA_RXD_INFO2_ PDMA_RXD_INFO2_T; ++ ++struct _PDMA_RXD_INFO2_ ++{ ++#if defined (CONFIG_ARCH_MT7623) ++ unsigned int PLEN1 : 2; ++ unsigned int LRO_AGG_CNT : 8; ++ unsigned int REV : 5; ++#else ++ unsigned int PLEN1 : 14; ++ unsigned int LS1 : 1; ++#endif /* CONFIG_RAETH_HW_LRO */ ++ unsigned int TAG : 1; ++ unsigned int PLEN0 : 14; ++ unsigned int LS0 : 1; ++ unsigned int DDONE_bit : 1; ++}; ++//------------------------------------------------- ++typedef struct _PDMA_RXD_INFO3_ PDMA_RXD_INFO3_T; ++ ++struct _PDMA_RXD_INFO3_ ++{ ++ unsigned int VID:16; ++ unsigned int TPID:16; ++}; ++//------------------------------------------------- ++typedef struct _PDMA_RXD_INFO4_ PDMA_RXD_INFO4_T; ++ ++struct _PDMA_RXD_INFO4_ ++{ ++#if defined (CONFIG_RALINK_MT7620) ++ unsigned int FOE_Entry : 14; ++ unsigned int CRSN : 5; ++ unsigned int SPORT : 3; ++ unsigned int L4F : 1; ++ unsigned int L4VLD : 1; ++ unsigned int TACK : 1; ++ unsigned int IP4F : 1; ++ unsigned int IP4 : 1; ++ unsigned int IP6 : 1; ++ unsigned int UN_USE1 : 4; ++#elif defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++ unsigned int FOE_Entry : 14; ++ unsigned int CRSN : 5; ++ unsigned int SP : 4; ++ unsigned int L4F : 1; ++ unsigned int L4VLD : 1; ++ unsigned int TACK : 1; ++ unsigned int IP4F : 1; ++ unsigned int IP4 : 1; ++ unsigned int IP6 : 1; ++ unsigned int UN_USE1 : 3; ++#else ++ unsigned int FOE_Entry : 14; ++ unsigned int FVLD : 1; ++ unsigned int UN_USE1 : 1; ++ unsigned int AI : 8; ++ unsigned int SP : 3; ++ unsigned int AIS : 1; ++ unsigned int L4F : 1; ++ unsigned int IPF : 1; ++ unsigned int L4FVLD_bit : 1; ++ unsigned int IPFVLD_bit : 1; ++#endif ++}; ++ ++ ++struct PDMA_rxdesc { ++ PDMA_RXD_INFO1_T rxd_info1; ++ PDMA_RXD_INFO2_T rxd_info2; ++ PDMA_RXD_INFO3_T rxd_info3; ++ PDMA_RXD_INFO4_T rxd_info4; ++#ifdef CONFIG_32B_DESC ++ unsigned int rxd_info5; ++ unsigned int rxd_info6; ++ unsigned int rxd_info7; ++ unsigned int rxd_info8; ++#endif ++}; ++ ++/*========================================= ++ PDMA TX Descriptor Format define ++=========================================*/ ++//------------------------------------------------- ++typedef struct _PDMA_TXD_INFO1_ PDMA_TXD_INFO1_T; ++ ++struct _PDMA_TXD_INFO1_ ++{ ++ unsigned int SDP0; ++}; ++//------------------------------------------------- ++typedef struct _PDMA_TXD_INFO2_ PDMA_TXD_INFO2_T; ++ ++struct _PDMA_TXD_INFO2_ ++{ ++ unsigned int SDL1 : 14; ++ unsigned int LS1_bit : 1; ++ unsigned int BURST_bit : 1; ++ unsigned int SDL0 : 14; ++ unsigned int LS0_bit : 1; ++ unsigned int DDONE_bit : 1; ++}; ++//------------------------------------------------- ++typedef struct _PDMA_TXD_INFO3_ PDMA_TXD_INFO3_T; ++ ++struct _PDMA_TXD_INFO3_ ++{ ++ unsigned int SDP1; ++}; ++//------------------------------------------------- ++typedef struct _PDMA_TXD_INFO4_ PDMA_TXD_INFO4_T; ++ ++struct _PDMA_TXD_INFO4_ ++{ ++#if defined (CONFIG_RALINK_MT7620) ++ unsigned int VPRI_VIDX : 8; ++ unsigned int SIDX : 4; ++ unsigned int INSP : 1; ++ unsigned int RESV : 2; ++ unsigned int UDF : 5; ++ unsigned int FP_BMAP : 8; ++ unsigned int TSO : 1; ++ unsigned int TUI_CO : 3; ++#elif defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++ unsigned int VLAN_TAG :17; // INSV(1)+VPRI(3)+CFI(1)+VID(12) ++ unsigned int RESV : 2; ++ unsigned int UDF : 6; ++ unsigned int FPORT : 3; ++ unsigned int TSO : 1; ++ unsigned int TUI_CO : 3; ++#else ++ unsigned int VPRI_VIDX : 8; ++ unsigned int SIDX : 4; ++ unsigned int INSP : 1; ++ unsigned int RESV : 1; ++ unsigned int UN_USE3 : 2; ++ unsigned int QN : 3; ++ unsigned int UN_USE2 : 1; ++ unsigned int UDF : 4; ++ unsigned int PN : 3; ++ unsigned int UN_USE1 : 1; ++ unsigned int TSO : 1; ++ unsigned int TUI_CO : 3; ++#endif ++}; ++ ++ ++struct PDMA_txdesc { ++ PDMA_TXD_INFO1_T txd_info1; ++ PDMA_TXD_INFO2_T txd_info2; ++ PDMA_TXD_INFO3_T txd_info3; ++ PDMA_TXD_INFO4_T txd_info4; ++#ifdef CONFIG_32B_DESC ++ unsigned int txd_info5; ++ unsigned int txd_info6; ++ unsigned int txd_info7; ++ unsigned int txd_info8; ++#endif ++}; ++ ++ ++#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++/*========================================= ++ QDMA TX Descriptor Format define ++=========================================*/ ++//------------------------------------------------- ++typedef struct _QDMA_TXD_INFO1_ QDMA_TXD_INFO1_T; ++ ++struct _QDMA_TXD_INFO1_ ++{ ++ unsigned int SDP; ++}; ++//------------------------------------------------- ++typedef struct _QDMA_TXD_INFO2_ QDMA_TXD_INFO2_T; ++ ++struct _QDMA_TXD_INFO2_ ++{ ++ unsigned int NDP; ++}; ++//------------------------------------------------- ++typedef struct _QDMA_TXD_INFO3_ QDMA_TXD_INFO3_T; ++ ++struct _QDMA_TXD_INFO3_ ++{ ++ unsigned int QID : 4; ++#if defined (CONFIG_HW_SFQ) ++ //unsigned int VQID : 10; ++ unsigned int PROT : 3; ++ unsigned int IPOFST : 7; ++#else ++ unsigned int RESV : 10; ++#endif ++ unsigned int SWC_bit : 1; ++ unsigned int BURST_bit : 1; ++ unsigned int SDL : 14; ++ unsigned int LS_bit : 1; ++ unsigned int OWN_bit : 1; ++}; ++//------------------------------------------------- ++typedef struct _QDMA_TXD_INFO4_ QDMA_TXD_INFO4_T; ++ ++struct _QDMA_TXD_INFO4_ ++{ ++ unsigned int VLAN_TAG :17; // INSV(1)+VPRI(3)+CFI(1)+VID(12) ++#if defined (CONFIG_RALINK_MT7621) ++ unsigned int RESV : 2; ++ unsigned int UDF : 6; ++#elif defined(CONFIG_ARCH_MT7623) ++ unsigned int VQID0 : 1; ++ unsigned int RESV : 7; ++#endif ++ unsigned int FPORT : 3; ++ unsigned int TSO : 1; ++ unsigned int TUI_CO : 3; ++}; ++ ++ ++struct QDMA_txdesc { ++ QDMA_TXD_INFO1_T txd_info1; ++ QDMA_TXD_INFO2_T txd_info2; ++ QDMA_TXD_INFO3_T txd_info3; ++ QDMA_TXD_INFO4_T txd_info4; ++#ifdef CONFIG_32B_DESC ++ unsigned int txd_info5; ++ unsigned int txd_info6; ++ unsigned int txd_info7; ++ unsigned int txd_info8; ++#endif ++}; ++#endif ++ ++#if defined (CONFIG_ARCH_MT7623) ++#define phys_to_bus(a) (a) ++#else ++#define phys_to_bus(a) (a & 0x1FFFFFFF) ++#endif ++ ++#define PHY_Enable_Auto_Nego 0x1000 ++#define PHY_Restart_Auto_Nego 0x0200 ++ ++/* PHY_STAT_REG = 1; */ ++#define PHY_Auto_Neco_Comp 0x0020 ++#define PHY_Link_Status 0x0004 ++ ++/* PHY_AUTO_NEGO_REG = 4; */ ++#define PHY_Cap_10_Half 0x0020 ++#define PHY_Cap_10_Full 0x0040 ++#define PHY_Cap_100_Half 0x0080 ++#define PHY_Cap_100_Full 0x0100 ++ ++/* proc definition */ ++ ++#if !defined (CONFIG_RALINK_RT6855) && !defined(CONFIG_RALINK_RT6855A) && \ ++ !defined (CONFIG_RALINK_MT7620) && !defined (CONFIG_RALINK_MT7621) && \ ++ !defined (CONFIG_ARCH_MT7623) ++#define CDMA_OQ_STA (RALINK_FRAME_ENGINE_BASE+RAPSE_OFFSET+0x4c) ++#define GDMA1_OQ_STA (RALINK_FRAME_ENGINE_BASE+RAPSE_OFFSET+0x50) ++#define PPE_OQ_STA (RALINK_FRAME_ENGINE_BASE+RAPSE_OFFSET+0x54) ++#define PSE_IQ_STA (RALINK_FRAME_ENGINE_BASE+RAPSE_OFFSET+0x58) ++#endif ++ ++#define PROCREG_CONTROL_FILE "/var/run/procreg_control" ++#if defined (CONFIG_RALINK_RT2880) ++#define PROCREG_DIR "rt2880" ++#elif defined (CONFIG_RALINK_RT3052) ++#define PROCREG_DIR "rt3052" ++#elif defined (CONFIG_RALINK_RT3352) ++#define PROCREG_DIR "rt3352" ++#elif defined (CONFIG_RALINK_RT5350) ++#define PROCREG_DIR "rt5350" ++#elif defined (CONFIG_RALINK_RT2883) ++#define PROCREG_DIR "rt2883" ++#elif defined (CONFIG_RALINK_RT3883) ++#define PROCREG_DIR "rt3883" ++#elif defined (CONFIG_RALINK_RT6855) ++#define PROCREG_DIR "rt6855" ++#elif defined (CONFIG_RALINK_MT7620) ++#define PROCREG_DIR "mt7620" ++#elif defined (CONFIG_RALINK_MT7621) ++#define PROCREG_DIR "mt7621" ++#elif defined (CONFIG_ARCH_MT7623) ++#define PROCREG_DIR "mt7623" ++#elif defined (CONFIG_RALINK_MT7628) ++#define PROCREG_DIR "mt7628" ++#elif defined (CONFIG_RALINK_RT6855A) ++#define PROCREG_DIR "rt6855a" ++#else ++#define PROCREG_DIR "rt2880" ++#endif ++#define PROCREG_SKBFREE "skb_free" ++#define PROCREG_TXRING "tx_ring" ++#define PROCREG_RXRING "rx_ring" ++#define PROCREG_RXRING1 "rx_ring1" ++#define PROCREG_RXRING2 "rx_ring2" ++#define PROCREG_RXRING3 "rx_ring3" ++#define PROCREG_NUM_OF_TXD "num_of_txd" ++#define PROCREG_TSO_LEN "tso_len" ++#define PROCREG_LRO_STATS "lro_stats" ++#define PROCREG_HW_LRO_STATS "hw_lro_stats" ++#define PROCREG_HW_LRO_AUTO_TLB "hw_lro_auto_tlb" ++#define PROCREG_GMAC "gmac" ++#define PROCREG_GMAC2 "gmac2" ++#define PROCREG_CP0 "cp0" ++#define PROCREG_RAQOS "qos" ++#define PROCREG_READ_VAL "regread_value" ++#define PROCREG_WRITE_VAL "regwrite_value" ++#define PROCREG_ADDR "reg_addr" ++#define PROCREG_CTL "procreg_control" ++#define PROCREG_RXDONE_INTR "rxdone_intr_count" ++#define PROCREG_ESW_INTR "esw_intr_count" ++#define PROCREG_ESW_CNT "esw_cnt" ++#define PROCREG_SNMP "snmp" ++#if defined (TASKLET_WORKQUEUE_SW) ++#define PROCREG_SCHE "schedule" ++#endif ++#define PROCREG_QDMA "qdma" ++#if defined(CONFIG_RAETH_PDMA_DVT) ++#define PROCREG_PDMA_DVT "pdma_dvt" ++#endif //#if defined(CONFIG_RAETH_PDMA_DVT) ++struct rt2880_reg_op_data { ++ char name[64]; ++ unsigned int reg_addr; ++ unsigned int op; ++ unsigned int reg_value; ++}; ++ ++#ifdef CONFIG_RAETH_LRO ++struct lro_counters { ++ u32 lro_aggregated; ++ u32 lro_flushed; ++ u32 lro_no_desc; ++}; ++ ++struct lro_para_struct { ++ unsigned int lan_ip1; ++}; ++ ++#endif // CONFIG_RAETH_LRO // ++ ++ ++#if defined (CONFIG_HW_SFQ) ++typedef struct { ++ //layer2 header ++ uint8_t dmac[6]; ++ uint8_t smac[6]; ++ ++ //vlan header ++ uint16_t vlan_tag; ++ uint16_t vlan1_gap; ++ uint16_t vlan1; ++ uint16_t vlan2_gap; ++ uint16_t vlan2; ++ uint16_t vlan_layer; ++ ++ //pppoe header ++ uint32_t pppoe_gap; ++ uint16_t ppp_tag; ++ uint16_t pppoe_sid; ++ ++ //layer3 header ++ uint16_t eth_type; ++ struct iphdr iph; ++ struct ipv6hdr ip6h; ++ ++ //layer4 header ++ struct tcphdr th; ++ struct udphdr uh; ++ ++ uint32_t pkt_type; ++ uint8_t is_mcast; ++ ++} ParseResult; ++#endif ++typedef struct end_device ++{ ++ ++ unsigned int tx_cpu_owner_idx0; ++ unsigned int rx_cpu_owner_idx0; ++ unsigned int fe_int_status; ++ unsigned int tx_full; ++ ++#if !defined (CONFIG_RAETH_QDMA) ++ unsigned int phy_tx_ring0; ++#else ++ /* QDMA Tx PTR */ ++ struct sk_buff *free_skb[NUM_TX_DESC]; ++ unsigned int tx_dma_ptr; ++ unsigned int tx_cpu_ptr; ++ unsigned int free_txd_num; ++ unsigned int free_txd_head; ++ unsigned int free_txd_tail; ++ struct QDMA_txdesc *txd_pool; ++ dma_addr_t phy_txd_pool; ++ unsigned int txd_pool_info[NUM_TX_DESC]; ++ struct QDMA_txdesc *free_head; ++ unsigned int phy_free_head; ++ unsigned int *free_page_head; ++ unsigned int phy_free_page_head; ++ struct PDMA_rxdesc *qrx_ring; ++ unsigned int phy_qrx_ring; ++#ifdef CONFIG_RAETH_PDMATX_QDMARX /* QDMA RX */ ++ unsigned int phy_tx_ring0; ++#endif ++#endif ++ ++ unsigned int phy_rx_ring0, phy_rx_ring1, phy_rx_ring2, phy_rx_ring3; ++ ++#if defined (CONFIG_RALINK_RT3052) || defined (CONFIG_RALINK_RT3352) || \ ++ defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_RT6855) || \ ++ defined(CONFIG_RALINK_RT6855A) || defined (CONFIG_RALINK_MT7620) || \ ++ defined(CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7628) || \ ++ defined (CONFIG_ARCH_MT7623) ++ //send signal to user application to notify link status changed ++ struct work_struct kill_sig_wq; ++#endif ++ ++ struct work_struct reset_task; ++#ifdef WORKQUEUE_BH ++ struct work_struct rx_wq; ++#else ++#if defined (TASKLET_WORKQUEUE_SW) ++ struct work_struct rx_wq; ++#endif ++ struct tasklet_struct rx_tasklet; ++ struct tasklet_struct tx_tasklet; ++#endif // WORKQUEUE_BH // ++ ++#if defined(CONFIG_RAETH_QOS) ++ struct sk_buff * skb_free[NUM_TX_RINGS][NUM_TX_DESC]; ++ unsigned int free_idx[NUM_TX_RINGS]; ++#else ++ struct sk_buff* skb_free[NUM_TX_DESC]; ++ unsigned int free_idx; ++#endif ++ ++ struct net_device_stats stat; /* The new statistics table. */ ++ spinlock_t page_lock; /* Page register locks */ ++ struct PDMA_txdesc *tx_ring0; ++#if defined(CONFIG_RAETH_QOS) ++ struct PDMA_txdesc *tx_ring1; ++ struct PDMA_txdesc *tx_ring2; ++ struct PDMA_txdesc *tx_ring3; ++#endif ++ struct PDMA_rxdesc *rx_ring0; ++ struct sk_buff *netrx0_skbuf[NUM_RX_DESC]; ++#if defined (CONFIG_RAETH_HW_LRO) ++ struct PDMA_rxdesc *rx_ring3; ++ struct sk_buff *netrx3_skbuf[NUM_RX_DESC]; ++ struct PDMA_rxdesc *rx_ring2; ++ struct sk_buff *netrx2_skbuf[NUM_RX_DESC]; ++ struct PDMA_rxdesc *rx_ring1; ++ struct sk_buff *netrx1_skbuf[NUM_RX_DESC]; ++#elif defined (CONFIG_RAETH_MULTIPLE_RX_RING) ++ struct PDMA_rxdesc *rx_ring1; ++ struct sk_buff *netrx1_skbuf[NUM_RX_DESC]; ++#if defined(CONFIG_ARCH_MT7623) ++ struct PDMA_rxdesc *rx_ring2; ++ struct sk_buff *netrx2_skbuf[NUM_RX_DESC]; ++ struct PDMA_rxdesc *rx_ring3; ++ struct sk_buff *netrx3_skbuf[NUM_RX_DESC]; ++#endif /* CONFIG_ARCH_MT7623 */ ++#endif ++#ifdef CONFIG_RAETH_NAPI ++ atomic_t irq_sem; ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ struct napi_struct napi; ++#endif ++#endif ++#ifdef CONFIG_PSEUDO_SUPPORT ++ struct net_device *PseudoDev; ++ unsigned int isPseudo; ++#endif ++#if defined (CONFIG_ETHTOOL) /*&& defined (CONFIG_RAETH_ROUTER)*/ ++ struct mii_if_info mii_info; ++#endif ++#ifdef CONFIG_RAETH_LRO ++ struct lro_counters lro_counters; ++ struct net_lro_mgr lro_mgr; ++ struct net_lro_desc lro_arr[8]; ++#endif ++#ifdef CONFIG_RAETH_HW_VLAN_RX ++ struct vlan_group *vlgrp; ++#endif ++#if defined (CONFIG_RAETH_HW_LRO) ++ struct work_struct hw_lro_wq; ++ unsigned int hw_lro_pkt_interval[3]; ++ unsigned int hw_lro_alpha; /* 0 < packet interval alpha <= 10 */ ++ unsigned int hw_lro_fix_setting; /* 0: dynamical AGG/AGE time, 1: fixed AGG/AGE time */ ++#endif /* CONFIG_RAETH_HW_LRO */ ++} END_DEVICE, *pEND_DEVICE; ++ ++ ++#define RAETH_VERSION "v3.1" ++ ++#endif ++ ++#define DMA_GLO_CFG PDMA_GLO_CFG ++ ++#if defined(CONFIG_RAETH_QDMATX_QDMARX) ++#define GDMA1_FWD_PORT 0x5555 ++#define GDMA2_FWD_PORT 0x5555 ++#elif defined(CONFIG_RAETH_PDMATX_QDMARX) ++#define GDMA1_FWD_PORT 0x5555 ++#define GDMA2_FWD_PORT 0x5555 ++#else ++#define GDMA1_FWD_PORT 0x0000 ++#define GDMA2_FWD_PORT 0x0000 ++#endif ++ ++#if defined(CONFIG_RAETH_QDMATX_QDMARX) ++#define RAETH_RX_CALC_IDX0 QRX_CRX_IDX_0 ++#define RAETH_RX_CALC_IDX1 QRX_CRX_IDX_1 ++#elif defined(CONFIG_RAETH_PDMATX_QDMARX) ++#define RAETH_RX_CALC_IDX0 QRX_CRX_IDX_0 ++#define RAETH_RX_CALC_IDX1 QRX_CRX_IDX_1 ++#else ++#define RAETH_RX_CALC_IDX0 RX_CALC_IDX0 ++#define RAETH_RX_CALC_IDX1 RX_CALC_IDX1 ++#endif ++#define RAETH_RX_CALC_IDX2 RX_CALC_IDX2 ++#define RAETH_RX_CALC_IDX3 RX_CALC_IDX3 ++#define RAETH_FE_INT_STATUS FE_INT_STATUS ++#define RAETH_FE_INT_ALL FE_INT_ALL ++#define RAETH_FE_INT_ENABLE FE_INT_ENABLE ++#define RAETH_FE_INT_DLY_INIT FE_INT_DLY_INIT ++#define RAETH_FE_INT_SETTING RX_DONE_INT0 | RX_DONE_INT1 | TX_DONE_INT0 | TX_DONE_INT1 | TX_DONE_INT2 | TX_DONE_INT3 ++#define QFE_INT_SETTING RX_DONE_INT0 | RX_DONE_INT1 | TX_DONE_INT0 | TX_DONE_INT1 | TX_DONE_INT2 | TX_DONE_INT3 ++#define RAETH_TX_DLY_INT TX_DLY_INT ++#define RAETH_TX_DONE_INT0 TX_DONE_INT0 ++#define RAETH_DLY_INT_CFG DLY_INT_CFG +diff --git a/drivers/net/ethernet/raeth/ra_ethtool.c b/drivers/net/ethernet/raeth/ra_ethtool.c +new file mode 100644 +index 0000000..ff13e59 +--- /dev/null ++++ b/drivers/net/ethernet/raeth/ra_ethtool.c +@@ -0,0 +1,515 @@ ++#include <linux/module.h> ++#include <linux/version.h> ++ ++#include <linux/kernel.h> ++#include <linux/sched.h> ++ ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/skbuff.h> ++#include <linux/if_ether.h> ++#include <linux/ethtool.h> ++ ++#include "ra2882ethreg.h" ++#include "raether.h" ++#include "ra_mac.h" ++#include "ra_ethtool.h" ++ ++#define RAETHER_DRIVER_NAME "raether" ++#define RA_NUM_STATS 4 ++ ++ ++static struct { ++ const char str[ETH_GSTRING_LEN]; ++} ethtool_stats_keys[] = { ++ { "statistic1" }, ++ { "statistic2" }, ++ { "statistic3" }, ++ { "statistic4" }, ++}; ++ ++unsigned char get_current_phy_address(void) ++{ ++ struct net_device *cur_dev_p; ++ END_DEVICE *ei_local; ++#if 0 ++ for(cur_dev_p=dev_base; cur_dev_p!=NULL; cur_dev_p=cur_dev_p->next){ ++ if (strncmp(cur_dev_p->name, DEV_NAME /* "eth2" usually */, 4) == 0) ++ break; ++ } ++#else ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ cur_dev_p = dev_get_by_name(&init_net, DEV_NAME); ++#else ++ cur_dev_p = dev_get_by_name(DEV_NAME); ++#endif ++#endif ++ if(!cur_dev_p) ++ return 0; ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ ei_local = netdev_priv(cur_dev_p); ++#else ++ ei_local = cur_dev_p->priv; ++#endif ++ return ei_local->mii_info.phy_id; ++} ++#if 0 ++static u32 et_get_tx_csum(struct net_device *dev) ++{ ++ return (sysRegRead(GDMA1_FWD_CFG) & GDM1_DISCRC) ? 0 : 1; // a pitfall here, "0" means to enable. ++} ++ ++static u32 et_get_rx_csum(struct net_device *dev) ++{ ++ return (sysRegRead(GDMA1_FWD_CFG) & GDM1_STRPCRC) ? 1 : 0; ++} ++ ++static int et_set_tx_csum(struct net_device *dev, u32 data) ++{ ++ int value; ++ //printk("et_set_tx_csum(): data = %d\n", data); ++ ++ value = sysRegRead(GDMA1_FWD_CFG); ++ if(data) ++ value |= GDM1_DISCRC; ++ else ++ value &= ~GDM1_DISCRC; ++ ++ sysRegWrite(GDMA1_FWD_CFG, value); ++ return 0; ++} ++ ++static int et_set_rx_csum(struct net_device *dev, u32 data) ++{ ++ int value; ++ //printk("et_set_rx_csum(): data = %d\n", data); ++ ++ value = sysRegRead(GDMA1_FWD_CFG); ++ if(data) ++ value |= GDM1_STRPCRC; ++ else ++ value &= ~GDM1_STRPCRC; ++ ++ sysRegWrite(GDMA1_FWD_CFG, value); ++ return 0; ++} ++#endif ++ ++#define MII_CR_ADDR 0x00 ++#define MII_CR_MR_AUTONEG_ENABLE (1 << 12) ++#define MII_CR_MR_RESTART_NEGOTIATION (1 << 9) ++ ++#define AUTO_NEGOTIATION_ADVERTISEMENT 0x04 ++#define AN_PAUSE (1 << 10) ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) ++static void et_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) ++{ ++ int mii_an_reg; ++ int mdio_cfg_reg; ++ END_DEVICE *ei_local = dev->priv; ++ ++ // get mii auto-negotiation register ++ mii_mgr_read(ei_local->mii_info.phy_id, AUTO_NEGOTIATION_ADVERTISEMENT, &mii_an_reg); ++ epause->autoneg = (mii_an_reg & AN_PAUSE) ? 1 : 0; //get autonet_enable flag bit ++ ++ mdio_cfg_reg = sysRegRead(MDIO_CFG); ++ epause->tx_pause = (mdio_cfg_reg & MDIO_CFG_GP1_FC_TX) ? 1 : 0; ++ epause->rx_pause = (mdio_cfg_reg & MDIO_CFG_GP1_FC_RX) ? 1 : 0; ++ ++ //printk("et_get_pauseparam(): autoneg=%d, tx_pause=%d, rx_pause=%d\n", epause->autoneg, epause->tx_pause, epause->rx_pause); ++} ++ ++static int et_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) ++{ ++ int mdio_cfg_reg; ++ int mii_an_reg; ++ END_DEVICE *ei_local = dev->priv; ++ ++ //printk("et_set_pauseparam(): autoneg=%d, tx_pause=%d, rx_pause=%d\n", epause->autoneg, epause->tx_pause, epause->rx_pause); ++ ++ // auto-neg pause ++ mii_mgr_read(ei_local->mii_info.phy_id, AUTO_NEGOTIATION_ADVERTISEMENT, &mii_an_reg); ++ if(epause->autoneg) ++ mii_an_reg |= AN_PAUSE; ++ else ++ mii_an_reg &= ~AN_PAUSE; ++ mii_mgr_write(ei_local->mii_info.phy_id, AUTO_NEGOTIATION_ADVERTISEMENT, mii_an_reg); ++ ++ // tx/rx pause ++ mdio_cfg_reg = sysRegRead(MDIO_CFG); ++ if(epause->tx_pause) ++ mdio_cfg_reg |= MDIO_CFG_GP1_FC_TX; ++ else ++ mdio_cfg_reg &= ~MDIO_CFG_GP1_FC_TX; ++ if(epause->rx_pause) ++ mdio_cfg_reg |= MDIO_CFG_GP1_FC_RX; ++ else ++ mdio_cfg_reg &= ~MDIO_CFG_GP1_FC_RX; ++ sysRegWrite(MDIO_CFG, mdio_cfg_reg); ++ ++ return 0; ++} ++ ++static int et_nway_reset(struct net_device *dev) ++{ ++ END_DEVICE *ei_local = dev->priv; ++ return mii_nway_restart(&ei_local->mii_info); ++} ++#endif ++ ++static u32 et_get_link(struct net_device *dev) ++{ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ END_DEVICE *ei_local = netdev_priv(dev); ++#else ++ END_DEVICE *ei_local = dev->priv; ++#endif ++ return mii_link_ok(&ei_local->mii_info); ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) ++static int et_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) ++{ ++ END_DEVICE *ei_local = dev->priv; ++ int rc; ++ rc = mii_ethtool_sset(&ei_local->mii_info, cmd); ++ return rc; ++} ++#endif ++ ++static int et_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) ++{ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ END_DEVICE *ei_local = netdev_priv(dev); ++#else ++ END_DEVICE *ei_local = dev->priv; ++#endif ++ mii_ethtool_gset(&ei_local->mii_info, cmd); ++ return 0; ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) ++static u32 et_get_msglevel(struct net_device *dev) ++{ ++ return 0; ++} ++ ++static void et_set_msglevel(struct net_device *dev, u32 datum) ++{ ++ return; ++} ++ ++static void et_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) ++{ ++ //END_DEVICE *ei_local = dev->priv; ++ strcpy(info->driver, RAETHER_DRIVER_NAME); ++ strcpy(info->version, RAETH_VERSION); ++ strcpy(info->bus_info, "n/a"); ++ info->n_stats = RA_NUM_STATS; ++ info->eedump_len = 0; ++ info->regdump_len = 0; ++} ++ ++static int et_get_stats_count(struct net_device *dev) ++{ ++ return RA_NUM_STATS; ++} ++ ++static void et_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data) ++{ ++// END_DEVICE *ei_local = dev->priv; ++ data[0] = 0;//np->xstats.early_rx; ++ data[1] = 0;//np->xstats.tx_buf_mapped; ++ data[2] = 0;//np->xstats.tx_timeouts; ++ data[3] = 0;//np->xstats.rx_lost_in_ring; ++} ++ ++static void et_get_strings(struct net_device *dev, u32 stringset, u8 *data) ++{ ++ memcpy(data, ethtool_stats_keys, sizeof(ethtool_stats_keys)); ++} ++#endif ++ ++/* ++ * mii_mgr_read wrapper for mii.o ethtool ++ */ ++int mdio_read(struct net_device *dev, int phy_id, int location) ++{ ++ unsigned int result; ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ END_DEVICE *ei_local = netdev_priv(dev); ++#else ++ END_DEVICE *ei_local = dev->priv; ++#endif ++ mii_mgr_read( (unsigned int) ei_local->mii_info.phy_id, (unsigned int)location, &result); ++ //printk("\n%s mii.o query= phy_id:%d, address:%d retval:%x\n", dev->name, phy_id, location, result); ++ return (int)result; ++} ++ ++/* ++ * mii_mgr_write wrapper for mii.o ethtool ++ */ ++void mdio_write(struct net_device *dev, int phy_id, int location, int value) ++{ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ END_DEVICE *ei_local = netdev_priv(dev); ++#else ++ END_DEVICE *ei_local = dev->priv; ++#endif ++ //printk("mii.o write= phy_id:%d, address:%d value:%x\n", phy_id, location, value); ++ mii_mgr_write( (unsigned int) ei_local->mii_info.phy_id, (unsigned int)location, (unsigned int)value); ++ return; ++} ++ ++struct ethtool_ops ra_ethtool_ops = { ++ ++ .get_settings = et_get_settings, ++ .get_link = et_get_link, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) ++ .get_drvinfo = et_get_drvinfo, ++ .set_settings = et_set_settings, ++ .get_pauseparam = et_get_pauseparam, ++ .set_pauseparam = et_set_pauseparam, ++// .get_rx_csum = et_get_rx_csum, ++// .set_rx_csum = et_set_rx_csum, ++// .get_tx_csum = et_get_tx_csum, ++// .set_tx_csum = et_set_tx_csum, ++ .nway_reset = et_nway_reset, ++ .get_msglevel = et_get_msglevel, ++ .set_msglevel = et_set_msglevel, ++ .get_strings = et_get_strings, ++ .get_stats_count = et_get_stats_count, ++ .get_ethtool_stats = et_get_ethtool_stats, ++/* .get_regs_len = et_get_regs_len, ++ .get_regs = et_get_regs, ++*/ ++#endif ++}; ++ ++#ifdef CONFIG_PSEUDO_SUPPORT ++/* ++ * We unable to re-use the Raether functions because it is hard to tell ++ * where the calling from is. From eth2 or eth3? ++ * ++ * These code size is around 950 bytes. ++ */ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) ++static void et_virt_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) ++{ ++ // PSEUDO_ADAPTER *pseudo = dev->priv; ++ return et_get_drvinfo(dev, info); ++} ++ ++static void et_virt_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) ++{ ++ int mii_an_reg, mdio_cfg_reg; ++ PSEUDO_ADAPTER *pseudo = dev->priv; ++ ++ // get mii auto-negotiation register ++ mii_mgr_read(pseudo->mii_info.phy_id, AUTO_NEGOTIATION_ADVERTISEMENT, &mii_an_reg); ++ epause->autoneg = (mii_an_reg & AN_PAUSE) ? 1 : 0; //get autonet_enable flag bit ++ ++ mdio_cfg_reg = sysRegRead(MDIO_CFG); ++ epause->tx_pause = (mdio_cfg_reg & MDIO_CFG_GP1_FC_TX) ? 1 : 0; ++ epause->rx_pause = (mdio_cfg_reg & MDIO_CFG_GP1_FC_RX) ? 1 : 0; ++ ++ //printk("et_get_pauseparam(): autoneg=%d, tx_pause=%d, rx_pause=%d\n", epause->autoneg, epause->tx_pause, epause->rx_pause); ++} ++ ++static int et_virt_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) ++{ ++ int mdio_cfg_reg; ++ int mii_an_reg; ++ PSEUDO_ADAPTER *pseudo = dev->priv; ++ ++ //printk("et_set_pauseparam(): autoneg=%d, tx_pause=%d, rx_pause=%d\n", epause->autoneg, epause->tx_pause, epause->rx_pause); ++ // auto-neg pause ++ mii_mgr_read(pseudo->mii_info.phy_id, AUTO_NEGOTIATION_ADVERTISEMENT, &mii_an_reg); ++ if(epause->autoneg) ++ mii_an_reg |= AN_PAUSE; ++ else ++ mii_an_reg &= ~AN_PAUSE; ++ mii_mgr_write(pseudo->mii_info.phy_id, AUTO_NEGOTIATION_ADVERTISEMENT, mii_an_reg); ++ ++ // tx/rx pause ++ mdio_cfg_reg = sysRegRead(MDIO_CFG); ++ if(epause->tx_pause) ++ mdio_cfg_reg |= MDIO_CFG_GP1_FC_TX; ++ else ++ mdio_cfg_reg &= ~MDIO_CFG_GP1_FC_TX; ++ if(epause->rx_pause) ++ mdio_cfg_reg |= MDIO_CFG_GP1_FC_RX; ++ else ++ mdio_cfg_reg &= ~MDIO_CFG_GP1_FC_RX; ++ sysRegWrite(MDIO_CFG, mdio_cfg_reg); ++ ++ return 0; ++} ++ ++static u32 et_virt_get_tx_csum(struct net_device *dev) ++{ ++ return (sysRegRead(GDMA2_FWD_CFG) & GDM1_DISCRC) ? 0 : 1; // a pitfall here, "0" means to enable. ++} ++ ++static u32 et_virt_get_rx_csum(struct net_device *dev) ++{ ++ return (sysRegRead(GDMA2_FWD_CFG) & GDM1_STRPCRC) ? 1 : 0; ++} ++ ++static int et_virt_set_tx_csum(struct net_device *dev, u32 data) ++{ ++ int value; ++ //printk("et_set_tx_csum(): data = %d\n", data); ++ value = sysRegRead(GDMA2_FWD_CFG); ++ if(data) ++ value |= GDM1_DISCRC; ++ else ++ value &= ~GDM1_DISCRC; ++ sysRegWrite(GDMA1_FWD_CFG, value); ++ return 0; ++} ++ ++static int et_virt_set_rx_csum(struct net_device *dev, u32 data) ++{ ++ int value; ++ //printk("et_set_rx_csum(): data = %d\n", data); ++ value = sysRegRead(GDMA2_FWD_CFG); ++ if(data) ++ value |= GDM1_STRPCRC; ++ else ++ value &= ~GDM1_STRPCRC; ++ sysRegWrite(GDMA1_FWD_CFG, value); ++ return 0; ++} ++ ++static int et_virt_nway_reset(struct net_device *dev) ++{ ++ PSEUDO_ADAPTER *pseudo = dev->priv; ++ return mii_nway_restart(&pseudo->mii_info); ++} ++#endif ++ ++static u32 et_virt_get_link(struct net_device *dev) ++{ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ PSEUDO_ADAPTER *pseudo = netdev_priv(dev); ++#else ++ PSEUDO_ADAPTER *pseudo = dev->priv; ++#endif ++ return mii_link_ok(&pseudo->mii_info); ++} ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) ++static int et_virt_set_settings(struct net_device *dev, struct ethtool_cmd *cmd) ++{ ++ PSEUDO_ADAPTER *pseudo = dev->priv; ++ int rc = mii_ethtool_sset(&pseudo->mii_info, cmd); ++ return rc; ++} ++#endif ++ ++static int et_virt_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) ++{ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ PSEUDO_ADAPTER *pseudo = netdev_priv(dev); ++#else ++ PSEUDO_ADAPTER *pseudo = dev->priv; ++#endif ++ mii_ethtool_gset(&pseudo->mii_info, cmd); ++ return 0; ++} ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) ++static u32 et_virt_get_msglevel(struct net_device *dev) ++{ ++ return 0; ++} ++ ++static void et_virt_set_msglevel(struct net_device *dev, u32 datum) ++{ ++ return; ++} ++ ++static void et_virt_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *stats, u64 *data) ++{ ++// PSEUDO_ADAPTER *pseudo = dev->priv; ++ data[0] = 0;//np->xstats.early_rx; ++ data[1] = 0;//np->xstats.tx_buf_mapped; ++ data[2] = 0;//np->xstats.tx_timeouts; ++ data[3] = 0;//np->xstats.rx_lost_in_ring; ++} ++ ++/* for virtual interface dedicated */ ++#define RA_VIRT_NUM_STATS 4 ++static struct { ++ const char str[ETH_GSTRING_LEN]; ++} ethtool_stats_keys_2[] = { ++ { "statistic1" }, ++ { "statistic2" }, ++ { "statistic3" }, ++ { "statistic4" }, ++}; ++ ++static int et_virt_get_stats_count(struct net_device *dev) ++{ ++ return RA_VIRT_NUM_STATS; ++} ++ ++static void et_virt_get_strings(struct net_device *dev, u32 stringset, u8 *data) ++{ ++ memcpy(data, ethtool_stats_keys_2, sizeof(ethtool_stats_keys_2)); ++} ++#endif ++ ++struct ethtool_ops ra_virt_ethtool_ops = { ++ .get_settings = et_virt_get_settings, ++ .get_link = et_virt_get_link, ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) ++ .get_drvinfo = et_virt_get_drvinfo, ++ .set_settings = et_virt_set_settings, ++ .get_pauseparam = et_virt_get_pauseparam, ++ .set_pauseparam = et_virt_set_pauseparam, ++ .get_rx_csum = et_virt_get_rx_csum, ++ .set_rx_csum = et_virt_set_rx_csum, ++ .get_tx_csum = et_virt_get_tx_csum, ++ .set_tx_csum = et_virt_set_tx_csum, ++ .nway_reset = et_virt_nway_reset, ++ .get_msglevel = et_virt_get_msglevel, ++ .set_msglevel = et_virt_set_msglevel, ++ .get_strings = et_virt_get_strings, ++ .get_stats_count = et_virt_get_stats_count, ++ .get_ethtool_stats = et_virt_get_ethtool_stats, ++/* .get_regs_len = et_virt_get_regs_len, ++ .get_regs = et_virt_get_regs, ++*/ ++#endif ++}; ++ ++int mdio_virt_read(struct net_device *dev, int phy_id, int location) ++{ ++ unsigned int result; ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ PSEUDO_ADAPTER *pseudo = netdev_priv(dev); ++#else ++ PSEUDO_ADAPTER *pseudo = dev->priv; ++#endif ++ mii_mgr_read( (unsigned int) pseudo->mii_info.phy_id, (unsigned int)location, &result); ++// printk("%s mii.o query= phy_id:%d, address:%d retval:%d\n", dev->name, phy_id, location, result); ++ return (int)result; ++} ++ ++void mdio_virt_write(struct net_device *dev, int phy_id, int location, int value) ++{ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ PSEUDO_ADAPTER *pseudo = netdev_priv(dev); ++#else ++ PSEUDO_ADAPTER *pseudo = dev->priv; ++#endif ++// printk("mii.o write= phy_id:%d, address:%d value:%d\n", phy_id, location, value); ++ mii_mgr_write( (unsigned int) pseudo->mii_info.phy_id, (unsigned int)location, (unsigned int)value); ++ return; ++} ++ ++#endif /* CONFIG_PSEUDO_SUPPORT */ ++ ++ +diff --git a/drivers/net/ethernet/raeth/ra_ethtool.h b/drivers/net/ethernet/raeth/ra_ethtool.h +new file mode 100644 +index 0000000..d64a1ab +--- /dev/null ++++ b/drivers/net/ethernet/raeth/ra_ethtool.h +@@ -0,0 +1,13 @@ ++#ifndef RA_ETHTOOL_H ++#define RA_ETHTOOL_H ++ ++/* ethtool related */ ++unsigned char get_current_phy_address(void); ++int mdio_read(struct net_device *dev, int phy_id, int location); ++void mdio_write(struct net_device *dev, int phy_id, int location, int value); ++ ++/* for pseudo interface */ ++int mdio_virt_read(struct net_device *dev, int phy_id, int location); ++void mdio_virt_write(struct net_device *dev, int phy_id, int location, int value); ++ ++#endif +diff --git a/drivers/net/ethernet/raeth/ra_ioctl.h b/drivers/net/ethernet/raeth/ra_ioctl.h +new file mode 100644 +index 0000000..83b806a +--- /dev/null ++++ b/drivers/net/ethernet/raeth/ra_ioctl.h +@@ -0,0 +1,102 @@ ++#ifndef _RAETH_IOCTL_H ++#define _RAETH_IOCTL_H ++ ++/* ioctl commands */ ++#define RAETH_ESW_REG_READ 0x89F1 ++#define RAETH_ESW_REG_WRITE 0x89F2 ++#define RAETH_MII_READ 0x89F3 ++#define RAETH_MII_WRITE 0x89F4 ++#define RAETH_ESW_INGRESS_RATE 0x89F5 ++#define RAETH_ESW_EGRESS_RATE 0x89F6 ++#define RAETH_ESW_PHY_DUMP 0x89F7 ++#define RAETH_QDMA_REG_READ 0x89F8 ++#define RAETH_QDMA_REG_WRITE 0x89F9 ++#define RAETH_QDMA_QUEUE_MAPPING 0x89FA ++#define RAETH_QDMA_READ_CPU_CLK 0x89FB ++#define RAETH_MII_READ_CL45 0x89FC ++#define RAETH_MII_WRITE_CL45 0x89FD ++#if defined(CONFIG_HW_SFQ) ++#define RAETH_QDMA_SFQ_WEB_ENABLE 0x89FE ++#endif ++ ++#if defined (CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A) || \ ++ defined (CONFIG_RALINK_MT7620) || defined(CONFIG_RALINK_MT7621) || \ ++ defined (CONFIG_ARCH_MT7623) ++ ++#define REG_ESW_WT_MAC_MFC 0x10 ++#define REG_ESW_ISC 0x18 ++#define REG_ESW_WT_MAC_ATA1 0x74 ++#define REG_ESW_WT_MAC_ATA2 0x78 ++#define REG_ESW_WT_MAC_ATWD 0x7C ++#define REG_ESW_WT_MAC_ATC 0x80 ++ ++#define REG_ESW_TABLE_TSRA1 0x84 ++#define REG_ESW_TABLE_TSRA2 0x88 ++#define REG_ESW_TABLE_ATRD 0x8C ++ ++ ++#define REG_ESW_VLAN_VTCR 0x90 ++#define REG_ESW_VLAN_VAWD1 0x94 ++#define REG_ESW_VLAN_VAWD2 0x98 ++ ++ ++#define REG_ESW_VLAN_ID_BASE 0x100 ++ ++//#define REG_ESW_VLAN_ID_BASE 0x50 ++#define REG_ESW_VLAN_MEMB_BASE 0x70 ++#define REG_ESW_TABLE_SEARCH 0x24 ++#define REG_ESW_TABLE_STATUS0 0x28 ++#define REG_ESW_TABLE_STATUS1 0x2C ++#define REG_ESW_TABLE_STATUS2 0x30 ++#define REG_ESW_WT_MAC_AD0 0x34 ++#define REG_ESW_WT_MAC_AD1 0x38 ++#define REG_ESW_WT_MAC_AD2 0x3C ++ ++#else ++/* rt3052 embedded ethernet switch registers */ ++#define REG_ESW_VLAN_ID_BASE 0x50 ++#define REG_ESW_VLAN_MEMB_BASE 0x70 ++#define REG_ESW_TABLE_SEARCH 0x24 ++#define REG_ESW_TABLE_STATUS0 0x28 ++#define REG_ESW_TABLE_STATUS1 0x2C ++#define REG_ESW_TABLE_STATUS2 0x30 ++#define REG_ESW_WT_MAC_AD0 0x34 ++#define REG_ESW_WT_MAC_AD1 0x38 ++#define REG_ESW_WT_MAC_AD2 0x3C ++#endif ++ ++ ++#if defined(CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_MT7628) ++#define REG_ESW_MAX 0x16C ++#elif defined (CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A) || \ ++ defined (CONFIG_RALINK_MT7620) ++#define REG_ESW_MAX 0x7FFFF ++#else //RT305x, RT3350 ++#define REG_ESW_MAX 0xFC ++#endif ++#define REG_HQOS_MAX 0x3FFF ++ ++ ++typedef struct rt3052_esw_reg { ++ unsigned int off; ++ unsigned int val; ++} esw_reg; ++ ++typedef struct ralink_mii_ioctl_data { ++ __u32 phy_id; ++ __u32 reg_num; ++ __u32 val_in; ++ __u32 val_out; ++ __u32 port_num; ++ __u32 dev_addr; ++ __u32 reg_addr; ++} ra_mii_ioctl_data; ++ ++typedef struct rt335x_esw_reg { ++ unsigned int on_off; ++ unsigned int port; ++ unsigned int bw;/*Mbps*/ ++} esw_rate; ++ ++ ++#endif +diff --git a/drivers/net/ethernet/raeth/ra_mac.c b/drivers/net/ethernet/raeth/ra_mac.c +new file mode 100644 +index 0000000..e8e978d +--- /dev/null ++++ b/drivers/net/ethernet/raeth/ra_mac.c +@@ -0,0 +1,2645 @@ ++#include <linux/module.h> ++#include <linux/version.h> ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/types.h> ++#include <linux/fcntl.h> ++#include <linux/interrupt.h> ++#include <linux/ptrace.h> ++#include <linux/ioport.h> ++#include <linux/in.h> ++#include <linux/slab.h> ++#include <linux/string.h> ++#include <linux/signal.h> ++#include <linux/irq.h> ++#include <linux/ctype.h> ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,4) ++#include <asm/system.h> ++#include <linux/mca.h> ++#endif ++#include <asm/io.h> ++#include <asm/bitops.h> ++#include <asm/io.h> ++#include <asm/dma.h> ++ ++#include <asm/rt2880/surfboardint.h> /* for cp0 reg access, added by bobtseng */ ++ ++#include <linux/errno.h> ++#include <linux/init.h> ++ ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/skbuff.h> ++ ++#include <linux/init.h> ++#include <linux/module.h> ++#include <linux/proc_fs.h> ++#include <asm/uaccess.h> ++ ++#include <linux/seq_file.h> ++ ++ ++#if defined(CONFIG_RAETH_LRO) ++#include <linux/inet_lro.h> ++#endif ++ ++#include "ra2882ethreg.h" ++#include "raether.h" ++#include "ra_mac.h" ++#include "ra_ethtool.h" ++#if defined(CONFIG_RAETH_PDMA_DVT) ++#include "dvt/raether_pdma_dvt.h" ++#endif //#if defined(CONFIG_RAETH_PDMA_DVT) ++ ++extern struct net_device *dev_raether; ++ ++#if defined (CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A) || \ ++ defined (CONFIG_RALINK_MT7620) ++extern unsigned short p0_rx_good_cnt; ++extern unsigned short p0_tx_good_cnt; ++extern unsigned short p1_rx_good_cnt; ++extern unsigned short p1_tx_good_cnt; ++extern unsigned short p2_rx_good_cnt; ++extern unsigned short p2_tx_good_cnt; ++extern unsigned short p3_rx_good_cnt; ++extern unsigned short p3_tx_good_cnt; ++extern unsigned short p4_rx_good_cnt; ++extern unsigned short p4_tx_good_cnt; ++extern unsigned short p5_rx_good_cnt; ++extern unsigned short p5_tx_good_cnt; ++extern unsigned short p6_rx_good_cnt; ++extern unsigned short p6_tx_good_cnt; ++ ++extern unsigned short p0_rx_byte_cnt; ++extern unsigned short p1_rx_byte_cnt; ++extern unsigned short p2_rx_byte_cnt; ++extern unsigned short p3_rx_byte_cnt; ++extern unsigned short p4_rx_byte_cnt; ++extern unsigned short p5_rx_byte_cnt; ++extern unsigned short p6_rx_byte_cnt; ++extern unsigned short p0_tx_byte_cnt; ++extern unsigned short p1_tx_byte_cnt; ++extern unsigned short p2_tx_byte_cnt; ++extern unsigned short p3_tx_byte_cnt; ++extern unsigned short p4_tx_byte_cnt; ++extern unsigned short p5_tx_byte_cnt; ++extern unsigned short p6_tx_byte_cnt; ++ ++#if defined(CONFIG_RALINK_MT7620) ++extern unsigned short p7_rx_good_cnt; ++extern unsigned short p7_tx_good_cnt; ++extern unsigned short p7_rx_byte_cnt; ++extern unsigned short p7_tx_byte_cnt; ++#endif ++#endif ++ ++ ++ ++#if defined(CONFIG_RAETH_TSO) ++int txd_cnt[MAX_SKB_FRAGS/2 + 1]; ++int tso_cnt[16]; ++#endif ++ ++#if defined(CONFIG_RAETH_LRO) ++#define MAX_AGGR 64 ++#define MAX_DESC 8 ++int lro_stats_cnt[MAX_AGGR + 1]; ++int lro_flush_cnt[MAX_AGGR + 1]; ++int lro_len_cnt1[16]; ++//int lro_len_cnt2[16]; ++int aggregated[MAX_DESC]; ++int lro_aggregated; ++int lro_flushed; ++int lro_nodesc; ++int force_flush; ++int tot_called1; ++int tot_called2; ++#endif ++ ++#if defined(CONFIG_RAETH_HW_LRO) ++#define HW_LRO_RING_NUM 3 ++#define MAX_HW_LRO_AGGR 64 ++unsigned int hw_lro_agg_num_cnt[HW_LRO_RING_NUM][MAX_HW_LRO_AGGR + 1]; ++unsigned int hw_lro_agg_size_cnt[HW_LRO_RING_NUM][16]; ++unsigned int hw_lro_tot_agg_cnt[HW_LRO_RING_NUM]; ++unsigned int hw_lro_tot_flush_cnt[HW_LRO_RING_NUM]; ++#if defined(CONFIG_RAETH_HW_LRO_REASON_DBG) ++unsigned int hw_lro_agg_flush_cnt[HW_LRO_RING_NUM]; ++unsigned int hw_lro_age_flush_cnt[HW_LRO_RING_NUM]; ++unsigned int hw_lro_seq_flush_cnt[HW_LRO_RING_NUM]; ++unsigned int hw_lro_timestamp_flush_cnt[HW_LRO_RING_NUM]; ++unsigned int hw_lro_norule_flush_cnt[HW_LRO_RING_NUM]; ++#endif /* CONFIG_RAETH_HW_LRO_REASON_DBG */ ++#endif /* CONFIG_RAETH_HW_LRO */ ++ ++#if defined(CONFIG_RAETH_QDMA) ++extern unsigned int M2Q_table[64]; ++extern struct QDMA_txdesc *free_head; ++#endif ++#if defined (CONFIG_ARCH_MT7623) ++extern struct SFQ_table *sfq0; ++extern struct SFQ_table *sfq1; ++extern struct SFQ_table *sfq2; ++extern struct SFQ_table *sfq3; ++#endif ++ ++#if defined(CONFIG_USER_SNMPD) ++ ++static int ra_snmp_seq_show(struct seq_file *seq, void *v) ++{ ++#if !defined(CONFIG_RALINK_RT5350) && !defined(CONFIG_RALINK_MT7620) && !defined (CONFIG_RALINK_MT7628) ++ ++ seq_printf(seq, "rx counters: %x %x %x %x %x %x %x\n", sysRegRead(GDMA_RX_GBCNT0), sysRegRead(GDMA_RX_GPCNT0),sysRegRead(GDMA_RX_OERCNT0), sysRegRead(GDMA_RX_FERCNT0), sysRegRead(GDMA_RX_SERCNT0), sysRegRead(GDMA_RX_LERCNT0), sysRegRead(GDMA_RX_CERCNT0)); ++ ++ seq_printf(seq, "fc config: %x %x %x %x\n", sysRegRead(CDMA_FC_CFG), sysRegRead(GDMA1_FC_CFG), PDMA_FC_CFG, sysRegRead(PDMA_FC_CFG)); ++ ++ seq_printf(seq, "scheduler: %x %x %x\n", sysRegRead(GDMA1_SCH_CFG), sysRegRead(GDMA2_SCH_CFG), sysRegRead(PDMA_SCH_CFG)); ++ ++#endif ++ seq_printf(seq, "ports: %x %x %x %x %x %x\n", sysRegRead(PORT0_PKCOUNT), sysRegRead(PORT1_PKCOUNT), sysRegRead(PORT2_PKCOUNT), sysRegRead(PORT3_PKCOUNT), sysRegRead(PORT4_PKCOUNT), sysRegRead(PORT5_PKCOUNT)); ++ ++ return 0; ++} ++ ++static int ra_snmp_seq_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, ra_snmp_seq_show, NULL); ++} ++ ++static const struct file_operations ra_snmp_seq_fops = { ++ .owner = THIS_MODULE, ++ .open = ra_snmp_seq_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release ++}; ++#endif ++ ++ ++#if defined (CONFIG_GIGAPHY) || defined (CONFIG_100PHY) || \ ++ defined (CONFIG_P5_MAC_TO_PHY_MODE) || defined (CONFIG_RAETH_GMAC2) ++#if defined (CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A) || \ ++ defined (CONFIG_RALINK_MT7620) || defined(CONFIG_RALINK_MT7621) || \ ++ defined (CONFIG_ARCH_MT7623) ++void enable_auto_negotiate(int unused) ++{ ++ u32 regValue; ++#if !defined (CONFIG_RALINK_MT7621) && !defined (CONFIG_ARCH_MT7623) ++ u32 addr = CONFIG_MAC_TO_GIGAPHY_MODE_ADDR; ++#endif ++ ++#if defined (CONFIG_RALINK_MT7621) ++ //enable MDIO mode all the time ++ regValue = le32_to_cpu(*(volatile u_long *)(RALINK_SYSCTL_BASE + 0x60)); ++ regValue &= ~(0x3 << 12); ++ *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x60) = regValue; ++#endif ++ ++ /* FIXME: we don't know how to deal with PHY end addr */ ++ regValue = sysRegRead(ESW_PHY_POLLING); ++ regValue |= (1<<31); ++ regValue &= ~(0x1f); ++ regValue &= ~(0x1f<<8); ++#if defined (CONFIG_RALINK_MT7620) ++ regValue |= ((addr-1) << 0);//setup PHY address for auto polling (Start Addr). ++ regValue |= (addr << 8);// setup PHY address for auto polling (End Addr). ++#elif defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++#if defined (CONFIG_GE_RGMII_INTERNAL_P0_AN)|| defined (CONFIG_GE_RGMII_INTERNAL_P4_AN) || defined (CONFIG_GE2_RGMII_AN) ++ regValue |= ((CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2-1)&0x1f << 0);//setup PHY address for auto polling (Start Addr). ++ regValue |= (CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2 << 8);// setup PHY address for auto polling (End Addr). ++#else ++ regValue |= (CONFIG_MAC_TO_GIGAPHY_MODE_ADDR << 0);//setup PHY address for auto polling (Start Addr). ++ regValue |= (CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2 << 8);// setup PHY address for auto polling (End Addr). ++#endif ++#else ++ regValue |= (addr << 0);// setup PHY address for auto polling (start Addr). ++ regValue |= (addr << 8);// setup PHY address for auto polling (End Addr). ++#endif ++ ++ /*kurtis: AN is strange*/ ++ sysRegWrite(ESW_PHY_POLLING, regValue); ++ ++#if defined (CONFIG_P4_MAC_TO_PHY_MODE) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3400) = 0x56330; ++#endif ++#if defined (CONFIG_P5_MAC_TO_PHY_MODE) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3500) = 0x56330; ++#endif ++} ++#elif defined (CONFIG_RALINK_RT2880) || defined(CONFIG_RALINK_RT3883) || \ ++ defined (CONFIG_RALINK_RT3052) || defined(CONFIG_RALINK_RT3352) ++ ++void enable_auto_negotiate(int ge) ++{ ++#if defined (CONFIG_RALINK_RT3052) || defined (CONFIG_RALINK_RT3352) ++ u32 regValue = sysRegRead(0xb01100C8); ++#else ++ u32 regValue; ++ regValue = (ge == 2)? sysRegRead(MDIO_CFG2) : sysRegRead(MDIO_CFG); ++#endif ++ ++ regValue &= 0xe0ff7fff; // clear auto polling related field: ++ // (MD_PHY1ADDR & GP1_FRC_EN). ++ regValue |= 0x20000000; // force to enable MDC/MDIO auto polling. ++ ++#if defined (CONFIG_GE2_RGMII_AN) || defined (CONFIG_GE2_MII_AN) ++ if(ge==2) { ++ regValue |= (CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2 << 24); // setup PHY address for auto polling. ++ } ++#endif ++#if defined (CONFIG_GE1_RGMII_AN) || defined (CONFIG_GE1_MII_AN) || defined (CONFIG_P5_MAC_TO_PHY_MODE) ++ if(ge==1) { ++ regValue |= (CONFIG_MAC_TO_GIGAPHY_MODE_ADDR << 24); // setup PHY address for auto polling. ++ } ++#endif ++ ++#if defined (CONFIG_RALINK_RT3052) || defined (CONFIG_RALINK_RT3352) ++ sysRegWrite(0xb01100C8, regValue); ++#else ++ if (ge == 2) ++ sysRegWrite(MDIO_CFG2, regValue); ++ else ++ sysRegWrite(MDIO_CFG, regValue); ++#endif ++} ++#endif ++#endif ++void ra2880stop(END_DEVICE *ei_local) ++{ ++ unsigned int regValue; ++ printk("ra2880stop()..."); ++ ++ regValue = sysRegRead(DMA_GLO_CFG); ++ regValue &= ~(TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN); ++ sysRegWrite(DMA_GLO_CFG, regValue); ++ ++ printk("Done\n"); ++ // printk("Done0x%x...\n", readreg(DMA_GLO_CFG)); ++} ++ ++void ei_irq_clear(void) ++{ ++ sysRegWrite(FE_INT_STATUS, 0xFFFFFFFF); ++} ++ ++void rt2880_gmac_hard_reset(void) ++{ ++#if !defined (CONFIG_RALINK_RT6855A) ++ //FIXME ++ sysRegWrite(RSTCTRL, RALINK_FE_RST); ++ sysRegWrite(RSTCTRL, 0); ++#endif ++} ++ ++void ra2880EnableInterrupt() ++{ ++ unsigned int regValue = sysRegRead(FE_INT_ENABLE); ++ RAETH_PRINT("FE_INT_ENABLE -- : 0x%08x\n", regValue); ++// regValue |= (RX_DONE_INT0 | TX_DONE_INT0); ++ ++ sysRegWrite(FE_INT_ENABLE, regValue); ++} ++ ++void ra2880MacAddressSet(unsigned char p[6]) ++{ ++ unsigned long regValue; ++ ++ regValue = (p[0] << 8) | (p[1]); ++#if defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_MT7628) ++ sysRegWrite(SDM_MAC_ADRH, regValue); ++ printk("GMAC1_MAC_ADRH -- : 0x%08x\n", sysRegRead(SDM_MAC_ADRH)); ++#elif defined (CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A) ++ sysRegWrite(GDMA1_MAC_ADRH, regValue); ++ printk("GMAC1_MAC_ADRH -- : 0x%08x\n", sysRegRead(GDMA1_MAC_ADRH)); ++ ++ /* To keep the consistence between RT6855 and RT62806, GSW should keep the register. */ ++ sysRegWrite(SMACCR1, regValue); ++ printk("SMACCR1 -- : 0x%08x\n", sysRegRead(SMACCR1)); ++#elif defined (CONFIG_RALINK_MT7620) ++ sysRegWrite(SMACCR1, regValue); ++ printk("SMACCR1 -- : 0x%08x\n", sysRegRead(SMACCR1)); ++#else ++ sysRegWrite(GDMA1_MAC_ADRH, regValue); ++ printk("GMAC1_MAC_ADRH -- : 0x%08x\n", sysRegRead(GDMA1_MAC_ADRH)); ++#endif ++ ++ regValue = (p[2] << 24) | (p[3] <<16) | (p[4] << 8) | p[5]; ++#if defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_MT7628) ++ sysRegWrite(SDM_MAC_ADRL, regValue); ++ printk("GMAC1_MAC_ADRL -- : 0x%08x\n", sysRegRead(SDM_MAC_ADRL)); ++#elif defined (CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A) ++ sysRegWrite(GDMA1_MAC_ADRL, regValue); ++ printk("GMAC1_MAC_ADRL -- : 0x%08x\n", sysRegRead(GDMA1_MAC_ADRL)); ++ ++ /* To keep the consistence between RT6855 and RT62806, GSW should keep the register. */ ++ sysRegWrite(SMACCR0, regValue); ++ printk("SMACCR0 -- : 0x%08x\n", sysRegRead(SMACCR0)); ++#elif defined (CONFIG_RALINK_MT7620) ++ sysRegWrite(SMACCR0, regValue); ++ printk("SMACCR0 -- : 0x%08x\n", sysRegRead(SMACCR0)); ++#else ++ sysRegWrite(GDMA1_MAC_ADRL, regValue); ++ printk("GMAC1_MAC_ADRL -- : 0x%08x\n", sysRegRead(GDMA1_MAC_ADRL)); ++#endif ++ ++ return; ++} ++ ++#ifdef CONFIG_PSEUDO_SUPPORT ++void ra2880Mac2AddressSet(unsigned char p[6]) ++{ ++ unsigned long regValue; ++ ++ regValue = (p[0] << 8) | (p[1]); ++ sysRegWrite(GDMA2_MAC_ADRH, regValue); ++ ++ regValue = (p[2] << 24) | (p[3] <<16) | (p[4] << 8) | p[5]; ++ sysRegWrite(GDMA2_MAC_ADRL, regValue); ++ ++ printk("GDMA2_MAC_ADRH -- : 0x%08x\n", sysRegRead(GDMA2_MAC_ADRH)); ++ printk("GDMA2_MAC_ADRL -- : 0x%08x\n", sysRegRead(GDMA2_MAC_ADRL)); ++ return; ++} ++#endif ++ ++/** ++ * hard_init - Called by raeth_probe to inititialize network device ++ * @dev: device pointer ++ * ++ * ethdev_init initilize dev->priv and set to END_DEVICE structure ++ * ++ */ ++void ethtool_init(struct net_device *dev) ++{ ++#if defined (CONFIG_ETHTOOL) /*&& defined (CONFIG_RAETH_ROUTER)*/ ++ END_DEVICE *ei_local = netdev_priv(dev); ++ ++ // init mii structure ++ ei_local->mii_info.dev = dev; ++ ei_local->mii_info.mdio_read = mdio_read; ++ ei_local->mii_info.mdio_write = mdio_write; ++ ei_local->mii_info.phy_id_mask = 0x1f; ++ ei_local->mii_info.reg_num_mask = 0x1f; ++ ei_local->mii_info.supports_gmii = mii_check_gmii_support(&ei_local->mii_info); ++ // TODO: phy_id: 0~4 ++ ei_local->mii_info.phy_id = 1; ++#endif ++ return; ++} ++ ++/* ++ * Routine Name : get_idx(mode, index) ++ * Description: calculate ring usage for tx/rx rings ++ * Mode 1 : Tx Ring ++ * Mode 2 : Rx Ring ++ */ ++int get_ring_usage(int mode, int i) ++{ ++ unsigned long tx_ctx_idx, tx_dtx_idx, tx_usage; ++ unsigned long rx_calc_idx, rx_drx_idx, rx_usage; ++ ++ struct PDMA_rxdesc* rxring; ++ struct PDMA_txdesc* txring; ++ ++ END_DEVICE *ei_local = netdev_priv(dev_raether); ++ ++ ++ if (mode == 2 ) { ++ /* cpu point to the next descriptor of rx dma ring */ ++ rx_calc_idx = *(unsigned long*)RX_CALC_IDX0; ++ rx_drx_idx = *(unsigned long*)RX_DRX_IDX0; ++ rxring = (struct PDMA_rxdesc*)RX_BASE_PTR0; ++ ++ rx_usage = (rx_drx_idx - rx_calc_idx -1 + NUM_RX_DESC) % NUM_RX_DESC; ++ if ( rx_calc_idx == rx_drx_idx ) { ++ if ( rxring[rx_drx_idx].rxd_info2.DDONE_bit == 1) ++ tx_usage = NUM_RX_DESC; ++ else ++ tx_usage = 0; ++ } ++ return rx_usage; ++ } ++ ++ ++ switch (i) { ++ case 0: ++ tx_ctx_idx = *(unsigned long*)TX_CTX_IDX0; ++ tx_dtx_idx = *(unsigned long*)TX_DTX_IDX0; ++ txring = ei_local->tx_ring0; ++ break; ++#if defined(CONFIG_RAETH_QOS) ++ case 1: ++ tx_ctx_idx = *(unsigned long*)TX_CTX_IDX1; ++ tx_dtx_idx = *(unsigned long*)TX_DTX_IDX1; ++ txring = ei_local->tx_ring1; ++ break; ++ case 2: ++ tx_ctx_idx = *(unsigned long*)TX_CTX_IDX2; ++ tx_dtx_idx = *(unsigned long*)TX_DTX_IDX2; ++ txring = ei_local->tx_ring2; ++ break; ++ case 3: ++ tx_ctx_idx = *(unsigned long*)TX_CTX_IDX3; ++ tx_dtx_idx = *(unsigned long*)TX_DTX_IDX3; ++ txring = ei_local->tx_ring3; ++ break; ++#endif ++ default: ++ printk("get_tx_idx failed %d %d\n", mode, i); ++ return 0; ++ }; ++ ++ tx_usage = (tx_ctx_idx - tx_dtx_idx + NUM_TX_DESC) % NUM_TX_DESC; ++ if ( tx_ctx_idx == tx_dtx_idx ) { ++ if ( txring[tx_ctx_idx].txd_info2.DDONE_bit == 1) ++ tx_usage = 0; ++ else ++ tx_usage = NUM_TX_DESC; ++ } ++ return tx_usage; ++ ++} ++ ++#if defined(CONFIG_RAETH_QOS) ++void dump_qos(struct seq_file *s) ++{ ++ int usage; ++ int i; ++ ++ seq_printf(s, "\n-----Raeth QOS -----\n\n"); ++ ++ for ( i = 0; i < 4; i++) { ++ usage = get_ring_usage(1,i); ++ seq_printf(s, "Tx Ring%d Usage : %d/%d\n", i, usage, NUM_TX_DESC); ++ } ++ ++ usage = get_ring_usage(2,0); ++ seq_printf(s, "RX Usage : %d/%d\n\n", usage, NUM_RX_DESC); ++#if defined (CONFIG_RALINK_MT7620) ++ seq_printf(s, "PSE_FQFC_CFG(0x%08x) : 0x%08x\n", PSE_FQFC_CFG, sysRegRead(PSE_FQFC_CFG)); ++ seq_printf(s, "PSE_IQ_CFG(0x%08x) : 0x%08x\n", PSE_IQ_CFG, sysRegRead(PSE_IQ_CFG)); ++ seq_printf(s, "PSE_QUE_STA(0x%08x) : 0x%08x\n", PSE_QUE_STA, sysRegRead(PSE_QUE_STA)); ++#elif defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_MT7628) ++ ++#else ++ seq_printf(s, "GDMA1_FC_CFG(0x%08x) : 0x%08x\n", GDMA1_FC_CFG, sysRegRead(GDMA1_FC_CFG)); ++ seq_printf(s, "GDMA2_FC_CFG(0x%08x) : 0x%08x\n", GDMA2_FC_CFG, sysRegRead(GDMA2_FC_CFG)); ++ seq_printf(s, "PDMA_FC_CFG(0x%08x) : 0x%08x\n", PDMA_FC_CFG, sysRegRead(PDMA_FC_CFG)); ++ seq_printf(s, "PSE_FQ_CFG(0x%08x) : 0x%08x\n", PSE_FQ_CFG, sysRegRead(PSE_FQ_CFG)); ++#endif ++ seq_printf(s, "\n\nTX_CTX_IDX0 : 0x%08x\n", sysRegRead(TX_CTX_IDX0)); ++ seq_printf(s, "TX_DTX_IDX0 : 0x%08x\n", sysRegRead(TX_DTX_IDX0)); ++ seq_printf(s, "TX_CTX_IDX1 : 0x%08x\n", sysRegRead(TX_CTX_IDX1)); ++ seq_printf(s, "TX_DTX_IDX1 : 0x%08x\n", sysRegRead(TX_DTX_IDX1)); ++ seq_printf(s, "TX_CTX_IDX2 : 0x%08x\n", sysRegRead(TX_CTX_IDX2)); ++ seq_printf(s, "TX_DTX_IDX2 : 0x%08x\n", sysRegRead(TX_DTX_IDX2)); ++ seq_printf(s, "TX_CTX_IDX3 : 0x%08x\n", sysRegRead(TX_CTX_IDX3)); ++ seq_printf(s, "TX_DTX_IDX3 : 0x%08x\n", sysRegRead(TX_DTX_IDX3)); ++ seq_printf(s, "RX_CALC_IDX0 : 0x%08x\n", sysRegRead(RX_CALC_IDX0)); ++ seq_printf(s, "RX_DRX_IDX0 : 0x%08x\n", sysRegRead(RX_DRX_IDX0)); ++ ++ seq_printf(s, "\n------------------------------\n\n"); ++} ++#endif ++ ++void dump_reg(struct seq_file *s) ++{ ++ int fe_int_enable; ++ int rx_usage; ++ int dly_int_cfg; ++ int rx_base_ptr0; ++ int rx_max_cnt0; ++ int rx_calc_idx0; ++ int rx_drx_idx0; ++#if !defined (CONFIG_RAETH_QDMA) ++ int tx_usage; ++ int tx_base_ptr[4]; ++ int tx_max_cnt[4]; ++ int tx_ctx_idx[4]; ++ int tx_dtx_idx[4]; ++ int i; ++#endif ++ ++ fe_int_enable = sysRegRead(FE_INT_ENABLE); ++ rx_usage = get_ring_usage(2,0); ++ ++ dly_int_cfg = sysRegRead(DLY_INT_CFG); ++ ++#if !defined (CONFIG_RAETH_QDMA) ++ tx_usage = get_ring_usage(1,0); ++ ++ tx_base_ptr[0] = sysRegRead(TX_BASE_PTR0); ++ tx_max_cnt[0] = sysRegRead(TX_MAX_CNT0); ++ tx_ctx_idx[0] = sysRegRead(TX_CTX_IDX0); ++ tx_dtx_idx[0] = sysRegRead(TX_DTX_IDX0); ++ ++ tx_base_ptr[1] = sysRegRead(TX_BASE_PTR1); ++ tx_max_cnt[1] = sysRegRead(TX_MAX_CNT1); ++ tx_ctx_idx[1] = sysRegRead(TX_CTX_IDX1); ++ tx_dtx_idx[1] = sysRegRead(TX_DTX_IDX1); ++ ++ tx_base_ptr[2] = sysRegRead(TX_BASE_PTR2); ++ tx_max_cnt[2] = sysRegRead(TX_MAX_CNT2); ++ tx_ctx_idx[2] = sysRegRead(TX_CTX_IDX2); ++ tx_dtx_idx[2] = sysRegRead(TX_DTX_IDX2); ++ ++ tx_base_ptr[3] = sysRegRead(TX_BASE_PTR3); ++ tx_max_cnt[3] = sysRegRead(TX_MAX_CNT3); ++ tx_ctx_idx[3] = sysRegRead(TX_CTX_IDX3); ++ tx_dtx_idx[3] = sysRegRead(TX_DTX_IDX3); ++#endif ++ ++ rx_base_ptr0 = sysRegRead(RX_BASE_PTR0); ++ rx_max_cnt0 = sysRegRead(RX_MAX_CNT0); ++ rx_calc_idx0 = sysRegRead(RX_CALC_IDX0); ++ rx_drx_idx0 = sysRegRead(RX_DRX_IDX0); ++ ++ seq_printf(s, "\n\nFE_INT_ENABLE : 0x%08x\n", fe_int_enable); ++#if !defined (CONFIG_RAETH_QDMA) ++ seq_printf(s, "TxRing PktCnt: %d/%d\n", tx_usage, NUM_TX_DESC); ++#endif ++ seq_printf(s, "RxRing PktCnt: %d/%d\n\n", rx_usage, NUM_RX_DESC); ++ seq_printf(s, "DLY_INT_CFG : 0x%08x\n", dly_int_cfg); ++ ++#if !defined (CONFIG_RAETH_QDMA) ++ for(i=0;i<4;i++) { ++ seq_printf(s, "TX_BASE_PTR%d : 0x%08x\n", i, tx_base_ptr[i]); ++ seq_printf(s, "TX_MAX_CNT%d : 0x%08x\n", i, tx_max_cnt[i]); ++ seq_printf(s, "TX_CTX_IDX%d : 0x%08x\n", i, tx_ctx_idx[i]); ++ seq_printf(s, "TX_DTX_IDX%d : 0x%08x\n", i, tx_dtx_idx[i]); ++ } ++#endif ++ ++ seq_printf(s, "RX_BASE_PTR0 : 0x%08x\n", rx_base_ptr0); ++ seq_printf(s, "RX_MAX_CNT0 : 0x%08x\n", rx_max_cnt0); ++ seq_printf(s, "RX_CALC_IDX0 : 0x%08x\n", rx_calc_idx0); ++ seq_printf(s, "RX_DRX_IDX0 : 0x%08x\n", rx_drx_idx0); ++ ++#if defined (CONFIG_ETHTOOL) && defined (CONFIG_RAETH_ROUTER) ++ seq_printf(s, "The current PHY address selected by ethtool is %d\n", get_current_phy_address()); ++#endif ++ ++#if defined (CONFIG_RALINK_RT2883) || defined(CONFIG_RALINK_RT3883) ++ seq_printf(s, "GDMA_RX_FCCNT1(0x%08x) : 0x%08x\n\n", GDMA_RX_FCCNT1, sysRegRead(GDMA_RX_FCCNT1)); ++#endif ++} ++ ++#if 0 ++void dump_cp0(void) ++{ ++ printk("CP0 Register dump --\n"); ++ printk("CP0_INDEX\t: 0x%08x\n", read_32bit_cp0_register(CP0_INDEX)); ++ printk("CP0_RANDOM\t: 0x%08x\n", read_32bit_cp0_register(CP0_RANDOM)); ++ printk("CP0_ENTRYLO0\t: 0x%08x\n", read_32bit_cp0_register(CP0_ENTRYLO0)); ++ printk("CP0_ENTRYLO1\t: 0x%08x\n", read_32bit_cp0_register(CP0_ENTRYLO1)); ++ printk("CP0_CONF\t: 0x%08x\n", read_32bit_cp0_register(CP0_CONF)); ++ printk("CP0_CONTEXT\t: 0x%08x\n", read_32bit_cp0_register(CP0_CONTEXT)); ++ printk("CP0_PAGEMASK\t: 0x%08x\n", read_32bit_cp0_register(CP0_PAGEMASK)); ++ printk("CP0_WIRED\t: 0x%08x\n", read_32bit_cp0_register(CP0_WIRED)); ++ printk("CP0_INFO\t: 0x%08x\n", read_32bit_cp0_register(CP0_INFO)); ++ printk("CP0_BADVADDR\t: 0x%08x\n", read_32bit_cp0_register(CP0_BADVADDR)); ++ printk("CP0_COUNT\t: 0x%08x\n", read_32bit_cp0_register(CP0_COUNT)); ++ printk("CP0_ENTRYHI\t: 0x%08x\n", read_32bit_cp0_register(CP0_ENTRYHI)); ++ printk("CP0_COMPARE\t: 0x%08x\n", read_32bit_cp0_register(CP0_COMPARE)); ++ printk("CP0_STATUS\t: 0x%08x\n", read_32bit_cp0_register(CP0_STATUS)); ++ printk("CP0_CAUSE\t: 0x%08x\n", read_32bit_cp0_register(CP0_CAUSE)); ++ printk("CP0_EPC\t: 0x%08x\n", read_32bit_cp0_register(CP0_EPC)); ++ printk("CP0_PRID\t: 0x%08x\n", read_32bit_cp0_register(CP0_PRID)); ++ printk("CP0_CONFIG\t: 0x%08x\n", read_32bit_cp0_register(CP0_CONFIG)); ++ printk("CP0_LLADDR\t: 0x%08x\n", read_32bit_cp0_register(CP0_LLADDR)); ++ printk("CP0_WATCHLO\t: 0x%08x\n", read_32bit_cp0_register(CP0_WATCHLO)); ++ printk("CP0_WATCHHI\t: 0x%08x\n", read_32bit_cp0_register(CP0_WATCHHI)); ++ printk("CP0_XCONTEXT\t: 0x%08x\n", read_32bit_cp0_register(CP0_XCONTEXT)); ++ printk("CP0_FRAMEMASK\t: 0x%08x\n", read_32bit_cp0_register(CP0_FRAMEMASK)); ++ printk("CP0_DIAGNOSTIC\t: 0x%08x\n", read_32bit_cp0_register(CP0_DIAGNOSTIC)); ++ printk("CP0_DEBUG\t: 0x%08x\n", read_32bit_cp0_register(CP0_DEBUG)); ++ printk("CP0_DEPC\t: 0x%08x\n", read_32bit_cp0_register(CP0_DEPC)); ++ printk("CP0_PERFORMANCE\t: 0x%08x\n", read_32bit_cp0_register(CP0_PERFORMANCE)); ++ printk("CP0_ECC\t: 0x%08x\n", read_32bit_cp0_register(CP0_ECC)); ++ printk("CP0_CACHEERR\t: 0x%08x\n", read_32bit_cp0_register(CP0_CACHEERR)); ++ printk("CP0_TAGLO\t: 0x%08x\n", read_32bit_cp0_register(CP0_TAGLO)); ++ printk("CP0_TAGHI\t: 0x%08x\n", read_32bit_cp0_register(CP0_TAGHI)); ++ printk("CP0_ERROREPC\t: 0x%08x\n", read_32bit_cp0_register(CP0_ERROREPC)); ++ printk("CP0_DESAVE\t: 0x%08x\n\n", read_32bit_cp0_register(CP0_DESAVE)); ++} ++#endif ++ ++struct proc_dir_entry *procRegDir; ++static struct proc_dir_entry *procGmac, *procSysCP0, *procTxRing, *procRxRing, *procSkbFree; ++#if defined(CONFIG_PSEUDO_SUPPORT) && defined(CONFIG_ETHTOOL) ++static struct proc_dir_entry *procGmac2; ++#endif ++#if defined(CONFIG_USER_SNMPD) ++static struct proc_dir_entry *procRaSnmp; ++#endif ++#if defined(CONFIG_RAETH_TSO) ++static struct proc_dir_entry *procNumOfTxd, *procTsoLen; ++#endif ++ ++#if defined(CONFIG_RAETH_LRO) ++static struct proc_dir_entry *procLroStats; ++#endif ++#if defined(CONFIG_RAETH_HW_LRO) || defined (CONFIG_RAETH_MULTIPLE_RX_RING) ++static struct proc_dir_entry *procRxRing1, *procRxRing2, *procRxRing3; ++static struct proc_dir_entry *procHwLroStats, *procHwLroAutoTlb; ++const static HWLRO_DBG_FUNC hw_lro_dbg_func[] = ++{ ++ [0] = hwlro_agg_cnt_ctrl, ++ [1] = hwlro_agg_time_ctrl, ++ [2] = hwlro_age_time_ctrl, ++ [3] = hwlro_pkt_int_alpha_ctrl, ++ [4] = hwlro_threshold_ctrl, ++ [5] = hwlro_fix_setting_switch_ctrl, ++}; ++#endif /* CONFIG_RAETH_HW_LRO */ ++#if defined (TASKLET_WORKQUEUE_SW) ++static struct proc_dir_entry *procSCHE; ++#endif ++ ++#if defined(CONFIG_RAETH_PDMA_DVT) ++static struct proc_dir_entry *procPdmaDvt; ++ ++const static PDMA_DBG_FUNC pdma_dvt_dbg_func[] = ++{ ++ [0] = pdma_dvt_show_ctrl, ++ [1] = pdma_dvt_test_rx_ctrl, ++ [2] = pdma_dvt_test_tx_ctrl, ++ [3] = pdma_dvt_test_debug_ctrl, ++ [4] = pdma_dvt_test_lro_ctrl, ++}; ++#endif //#if defined(CONFIG_RAETH_PDMA_DVT) ++ ++int RegReadMain(struct seq_file *seq, void *v) ++{ ++ dump_reg(seq); ++ return 0; ++} ++ ++static void *seq_SkbFree_start(struct seq_file *seq, loff_t *pos) ++{ ++ if (*pos < NUM_TX_DESC) ++ return pos; ++ return NULL; ++} ++ ++static void *seq_SkbFree_next(struct seq_file *seq, void *v, loff_t *pos) ++{ ++ (*pos)++; ++ if (*pos >= NUM_TX_DESC) ++ return NULL; ++ return pos; ++} ++ ++static void seq_SkbFree_stop(struct seq_file *seq, void *v) ++{ ++ /* Nothing to do */ ++} ++ ++static int seq_SkbFree_show(struct seq_file *seq, void *v) ++{ ++ int i = *(loff_t *) v; ++ END_DEVICE *ei_local = netdev_priv(dev_raether); ++ ++ seq_printf(seq, "%d: %08x\n",i, *(int *)&ei_local->skb_free[i]); ++ ++ return 0; ++} ++ ++static const struct seq_operations seq_skb_free_ops = { ++ .start = seq_SkbFree_start, ++ .next = seq_SkbFree_next, ++ .stop = seq_SkbFree_stop, ++ .show = seq_SkbFree_show ++}; ++ ++static int skb_free_open(struct inode *inode, struct file *file) ++{ ++ return seq_open(file, &seq_skb_free_ops); ++} ++ ++static const struct file_operations skb_free_fops = { ++ .owner = THIS_MODULE, ++ .open = skb_free_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = seq_release ++}; ++ ++#if defined (CONFIG_RAETH_QDMA) ++int QDMARead(struct seq_file *seq, void *v) ++{ ++ unsigned int temp,i; ++ unsigned int sw_fq, hw_fq; ++ unsigned int min_en, min_rate, max_en, max_rate, sch, weight; ++ unsigned int queue, tx_des_cnt, hw_resv, sw_resv, queue_head, queue_tail; ++ struct net_device *dev = dev_raether; ++ END_DEVICE *ei_local = netdev_priv(dev); ++ ++ seq_printf(seq, "==== General Information ====\n"); ++ temp = sysRegRead(QDMA_FQ_CNT); ++ sw_fq = (temp&0xFFFF0000)>>16; ++ hw_fq = (temp&0x0000FFFF); ++ seq_printf(seq, "SW TXD: %d/%d; HW TXD: %d/%d\n", sw_fq, NUM_TX_DESC, hw_fq,NUM_QDMA_PAGE); ++ seq_printf(seq, "SW TXD virtual start address: 0x%08x\n", ei_local->txd_pool); ++ seq_printf(seq, "HW TXD virtual start address: 0x%08x\n\n", free_head); ++ ++ seq_printf(seq, "==== Scheduler Information ====\n"); ++ temp = sysRegRead(QDMA_TX_SCH); ++ max_en = (temp&0x00000800)>>11; ++ max_rate = (temp&0x000007F0)>>4; ++ for(i=0;i<(temp&0x0000000F);i++) ++ max_rate *= 10; ++ seq_printf(seq, "SCH1 rate control:%d. Rate is %dKbps.\n", max_en, max_rate); ++ max_en = (temp&0x08000000)>>27; ++ max_rate = (temp&0x07F00000)>>20; ++ for(i=0;i<(temp&0x000F0000);i++) ++ max_rate *= 10; ++ seq_printf(seq, "SCH2 rate control:%d. Rate is %dKbps.\n\n", max_en, max_rate); ++ ++ seq_printf(seq, "==== Physical Queue Information ====\n"); ++ for (queue = 0; queue < 16; queue++){ ++ temp = sysRegRead(QTX_CFG_0 + 0x10 * queue); ++ tx_des_cnt = (temp & 0xffff0000) >> 16; ++ hw_resv = (temp & 0xff00) >> 8; ++ sw_resv = (temp & 0xff); ++ temp = sysRegRead(QTX_CFG_0 +(0x10 * queue) + 0x4); ++ sch = (temp >> 31) + 1 ; ++ min_en = (temp & 0x8000000) >> 27; ++ min_rate = (temp & 0x7f00000) >> 20; ++ for (i = 0; i< (temp & 0xf0000) >> 16; i++) ++ min_rate *= 10; ++ max_en = (temp & 0x800) >> 11; ++ max_rate = (temp & 0x7f0) >> 4; ++ for (i = 0; i< (temp & 0xf); i++) ++ max_rate *= 10; ++ weight = (temp & 0xf000) >> 12; ++ queue_head = sysRegRead(QTX_HEAD_0 + 0x10 * queue); ++ queue_tail = sysRegRead(QTX_TAIL_0 + 0x10 * queue); ++ ++ seq_printf(seq, "Queue#%d Information:\n", queue); ++ seq_printf(seq, "%d packets in the queue; head address is 0x%08x, tail address is 0x%08x.\n", tx_des_cnt, queue_head, queue_tail); ++ seq_printf(seq, "HW_RESV: %d; SW_RESV: %d; SCH: %d; Weighting: %d\n", hw_resv, sw_resv, sch, weight); ++ seq_printf(seq, "Min_Rate_En is %d, Min_Rate is %dKbps; Max_Rate_En is %d, Max_Rate is %dKbps.\n\n", min_en, min_rate, max_en, max_rate); ++ } ++#if defined (CONFIG_ARCH_MT7623) && defined(CONFIG_HW_SFQ) ++ seq_printf(seq, "==== Virtual Queue Information ====\n"); ++ seq_printf(seq, "VQTX_TB_BASE_0:0x%08x;VQTX_TB_BASE_1:0x%08x;VQTX_TB_BASE_2:0x%08x;VQTX_TB_BASE_3:0x%08x\n", \ ++ sfq0, sfq1, sfq2, sfq3); ++ temp = sysRegRead(VQTX_NUM); ++ seq_printf(seq, "VQTX_NUM_0:0x%01x;VQTX_NUM_1:0x%01x;VQTX_NUM_2:0x%01x;VQTX_NUM_3:0x%01x\n\n", \ ++ temp&0xF, (temp&0xF0)>>4, (temp&0xF00)>>8, (temp&0xF000)>>12); ++ ++#endif ++ ++ seq_printf(seq, "==== Flow Control Information ====\n"); ++ temp = sysRegRead(QDMA_FC_THRES); ++ seq_printf(seq, "SW_DROP_EN:%x; SW_DROP_FFA:%d; SW_DROP_MODE:%d\n", \ ++ (temp&0x1000000)>>24, (temp&0x200000)>>25, (temp&0x30000000)>>28); ++ seq_printf(seq, "WH_DROP_EN:%x; HW_DROP_FFA:%d; HW_DROP_MODE:%d\n", \ ++ (temp&0x10000)>>16, (temp&0x2000)>>17, (temp&0x300000)>>20); ++#if defined (CONFIG_ARCH_MT7623) ++ seq_printf(seq, "SW_DROP_FSTVQ_MODE:%d;SW_DROP_FSTVQ:%d\n", \ ++ (temp&0xC0000000)>>30, (temp&0x08000000)>>27); ++ seq_printf(seq, "HW_DROP_FSTVQ_MODE:%d;HW_DROP_FSTVQ:%d\n", \ ++ (temp&0xC00000)>>22, (temp&0x080000)>>19); ++#endif ++ ++ seq_printf(seq, "\n==== FSM Information\n"); ++ temp = sysRegRead(QDMA_DMA); ++#if defined (CONFIG_ARCH_MT7623) ++ seq_printf(seq, "VQTB_FSM:0x%01x\n", (temp&0x0F000000)>>24); ++#endif ++ seq_printf(seq, "FQ_FSM:0x%01x\n", (temp&0x000F0000)>>16); ++ seq_printf(seq, "TX_FSM:0x%01x\n", (temp&0x00000F00)>>12); ++ seq_printf(seq, "RX_FSM:0x%01x\n\n", (temp&0x0000000f)); ++ ++ seq_printf(seq, "==== M2Q Information ====\n"); ++ for (i = 0; i < 64; i+=8){ ++ seq_printf(seq, " (%d,%d)(%d,%d)(%d,%d)(%d,%d)(%d,%d)(%d,%d)(%d,%d)(%d,%d)\n", ++ i, M2Q_table[i], i+1, M2Q_table[i+1], i+2, M2Q_table[i+2], i+3, M2Q_table[i+3], ++ i+4, M2Q_table[i+4], i+5, M2Q_table[i+5], i+6, M2Q_table[i+6], i+7, M2Q_table[i+7]); ++ } ++ ++ return 0; ++ ++} ++ ++static int qdma_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, QDMARead, NULL); ++} ++ ++static const struct file_operations qdma_fops = { ++ .owner = THIS_MODULE, ++ .open = qdma_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release ++}; ++#endif ++ ++int TxRingRead(struct seq_file *seq, void *v) ++{ ++ END_DEVICE *ei_local = netdev_priv(dev_raether); ++ struct PDMA_txdesc *tx_ring; ++ int i = 0; ++ ++ tx_ring = kmalloc(sizeof(struct PDMA_txdesc) * NUM_TX_DESC, GFP_KERNEL); ++ if(tx_ring==NULL){ ++ seq_printf(seq, " allocate temp tx_ring fail.\n"); ++ return 0; ++ } ++ ++ for (i=0; i < NUM_TX_DESC; i++) { ++ tx_ring[i] = ei_local->tx_ring0[i]; ++ } ++ ++ for (i=0; i < NUM_TX_DESC; i++) { ++#ifdef CONFIG_32B_DESC ++ seq_printf(seq, "%d: %08x %08x %08x %08x %08x %08x %08x %08x\n",i, *(int *)&tx_ring[i].txd_info1, ++ *(int *)&tx_ring[i].txd_info2, *(int *)&tx_ring[i].txd_info3, ++ *(int *)&tx_ring[i].txd_info4, *(int *)&tx_ring[i].txd_info5, ++ *(int *)&tx_ring[i].txd_info6, *(int *)&tx_ring[i].txd_info7, ++ *(int *)&tx_ring[i].txd_info8); ++#else ++ seq_printf(seq, "%d: %08x %08x %08x %08x\n",i, *(int *)&tx_ring[i].txd_info1, *(int *)&tx_ring[i].txd_info2, ++ *(int *)&tx_ring[i].txd_info3, *(int *)&tx_ring[i].txd_info4); ++#endif ++ } ++ ++ kfree(tx_ring); ++ return 0; ++} ++ ++static int tx_ring_open(struct inode *inode, struct file *file) ++{ ++#if !defined (CONFIG_RAETH_QDMA) ++ return single_open(file, TxRingRead, NULL); ++#else ++ return single_open(file, QDMARead, NULL); ++#endif ++} ++ ++static const struct file_operations tx_ring_fops = { ++ .owner = THIS_MODULE, ++ .open = tx_ring_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release ++}; ++ ++int RxRingRead(struct seq_file *seq, void *v) ++{ ++ END_DEVICE *ei_local = netdev_priv(dev_raether); ++ struct PDMA_rxdesc *rx_ring; ++ int i = 0; ++ ++ rx_ring = kmalloc(sizeof(struct PDMA_rxdesc) * NUM_RX_DESC, GFP_KERNEL); ++ if(rx_ring==NULL){ ++ seq_printf(seq, " allocate temp rx_ring fail.\n"); ++ return 0; ++ } ++ ++ for (i=0; i < NUM_RX_DESC; i++) { ++ memcpy(&rx_ring[i], &ei_local->rx_ring0[i], sizeof(struct PDMA_rxdesc)); ++ } ++ ++ for (i=0; i < NUM_RX_DESC; i++) { ++#ifdef CONFIG_32B_DESC ++ seq_printf(seq, "%d: %08x %08x %08x %08x %08x %08x %08x %08x\n",i, *(int *)&rx_ring[i].rxd_info1, ++ *(int *)&rx_ring[i].rxd_info2, *(int *)&rx_ring[i].rxd_info3, ++ *(int *)&rx_ring[i].rxd_info4, *(int *)&rx_ring[i].rxd_info5, ++ *(int *)&rx_ring[i].rxd_info6, *(int *)&rx_ring[i].rxd_info7, ++ *(int *)&rx_ring[i].rxd_info8); ++#else ++ seq_printf(seq, "%d: %08x %08x %08x %08x\n",i, *(int *)&rx_ring[i].rxd_info1, *(int *)&rx_ring[i].rxd_info2, ++ *(int *)&rx_ring[i].rxd_info3, *(int *)&rx_ring[i].rxd_info4); ++#endif ++ } ++ ++ kfree(rx_ring); ++ return 0; ++} ++ ++static int rx_ring_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, RxRingRead, NULL); ++} ++ ++static const struct file_operations rx_ring_fops = { ++ .owner = THIS_MODULE, ++ .open = rx_ring_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release ++}; ++ ++#if defined(CONFIG_RAETH_HW_LRO) || defined (CONFIG_RAETH_MULTIPLE_RX_RING) ++int RxLRORingRead(struct seq_file *seq, void *v, struct PDMA_rxdesc *rx_ring_p) ++{ ++ struct PDMA_rxdesc *rx_ring; ++ int i = 0; ++ ++ rx_ring = kmalloc(sizeof(struct PDMA_rxdesc) * NUM_LRO_RX_DESC, GFP_KERNEL); ++ if(rx_ring==NULL){ ++ seq_printf(seq, " allocate temp rx_ring fail.\n"); ++ return 0; ++ } ++ ++ for (i=0; i < NUM_LRO_RX_DESC; i++) { ++ memcpy(&rx_ring[i], &rx_ring_p[i], sizeof(struct PDMA_rxdesc)); ++ } ++ ++ for (i=0; i < NUM_LRO_RX_DESC; i++) { ++#ifdef CONFIG_32B_DESC ++ seq_printf(seq, "%d: %08x %08x %08x %08x %08x %08x %08x %08x\n",i, *(int *)&rx_ring[i].rxd_info1, ++ *(int *)&rx_ring[i].rxd_info2, *(int *)&rx_ring[i].rxd_info3, ++ *(int *)&rx_ring[i].rxd_info4, *(int *)&rx_ring[i].rxd_info5, ++ *(int *)&rx_ring[i].rxd_info6, *(int *)&rx_ring[i].rxd_info7, ++ *(int *)&rx_ring[i].rxd_info8); ++#else ++ seq_printf(seq, "%d: %08x %08x %08x %08x\n",i, *(int *)&rx_ring[i].rxd_info1, *(int *)&rx_ring[i].rxd_info2, ++ *(int *)&rx_ring[i].rxd_info3, *(int *)&rx_ring[i].rxd_info4); ++#endif ++ } ++ ++ kfree(rx_ring); ++ return 0; ++} ++ ++int RxRing1Read(struct seq_file *seq, void *v) ++{ ++ END_DEVICE *ei_local = netdev_priv(dev_raether); ++ RxLRORingRead(seq, v, ei_local->rx_ring1); ++ ++ return 0; ++} ++ ++int RxRing2Read(struct seq_file *seq, void *v) ++{ ++ END_DEVICE *ei_local = netdev_priv(dev_raether); ++ RxLRORingRead(seq, v, ei_local->rx_ring2); ++ ++ return 0; ++} ++ ++int RxRing3Read(struct seq_file *seq, void *v) ++{ ++ END_DEVICE *ei_local = netdev_priv(dev_raether); ++ RxLRORingRead(seq, v, ei_local->rx_ring3); ++ ++ return 0; ++} ++ ++static int rx_ring1_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, RxRing1Read, NULL); ++} ++ ++static int rx_ring2_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, RxRing2Read, NULL); ++} ++ ++static int rx_ring3_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, RxRing3Read, NULL); ++} ++ ++static const struct file_operations rx_ring1_fops = { ++ .owner = THIS_MODULE, ++ .open = rx_ring1_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release ++}; ++ ++static const struct file_operations rx_ring2_fops = { ++ .owner = THIS_MODULE, ++ .open = rx_ring2_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release ++}; ++ ++static const struct file_operations rx_ring3_fops = { ++ .owner = THIS_MODULE, ++ .open = rx_ring3_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release ++}; ++#endif /* CONFIG_RAETH_HW_LRO */ ++ ++#if defined(CONFIG_RAETH_TSO) ++ ++int NumOfTxdUpdate(int num_of_txd) ++{ ++ ++ txd_cnt[num_of_txd]++; ++ ++ return 0; ++} ++ ++static void *seq_TsoTxdNum_start(struct seq_file *seq, loff_t *pos) ++{ ++ seq_printf(seq, "TXD | Count\n"); ++ if (*pos < (MAX_SKB_FRAGS/2 + 1)) ++ return pos; ++ return NULL; ++} ++ ++static void *seq_TsoTxdNum_next(struct seq_file *seq, void *v, loff_t *pos) ++{ ++ (*pos)++; ++ if (*pos >= (MAX_SKB_FRAGS/2 + 1)) ++ return NULL; ++ return pos; ++} ++ ++static void seq_TsoTxdNum_stop(struct seq_file *seq, void *v) ++{ ++ /* Nothing to do */ ++} ++ ++static int seq_TsoTxdNum_show(struct seq_file *seq, void *v) ++{ ++ int i = *(loff_t *) v; ++ seq_printf(seq, "%d: %d\n",i , txd_cnt[i]); ++ ++ return 0; ++} ++ ++ssize_t NumOfTxdWrite(struct file *file, const char __user *buffer, ++ size_t count, loff_t *data) ++{ ++ memset(txd_cnt, 0, sizeof(txd_cnt)); ++ printk("clear txd cnt table\n"); ++ ++ return count; ++} ++ ++int TsoLenUpdate(int tso_len) ++{ ++ ++ if(tso_len > 70000) { ++ tso_cnt[14]++; ++ }else if(tso_len > 65000) { ++ tso_cnt[13]++; ++ }else if(tso_len > 60000) { ++ tso_cnt[12]++; ++ }else if(tso_len > 55000) { ++ tso_cnt[11]++; ++ }else if(tso_len > 50000) { ++ tso_cnt[10]++; ++ }else if(tso_len > 45000) { ++ tso_cnt[9]++; ++ }else if(tso_len > 40000) { ++ tso_cnt[8]++; ++ }else if(tso_len > 35000) { ++ tso_cnt[7]++; ++ }else if(tso_len > 30000) { ++ tso_cnt[6]++; ++ }else if(tso_len > 25000) { ++ tso_cnt[5]++; ++ }else if(tso_len > 20000) { ++ tso_cnt[4]++; ++ }else if(tso_len > 15000) { ++ tso_cnt[3]++; ++ }else if(tso_len > 10000) { ++ tso_cnt[2]++; ++ }else if(tso_len > 5000) { ++ tso_cnt[1]++; ++ }else { ++ tso_cnt[0]++; ++ } ++ ++ return 0; ++} ++ ++ssize_t TsoLenWrite(struct file *file, const char __user *buffer, ++ size_t count, loff_t *data) ++{ ++ memset(tso_cnt, 0, sizeof(tso_cnt)); ++ printk("clear tso cnt table\n"); ++ ++ return count; ++} ++ ++static void *seq_TsoLen_start(struct seq_file *seq, loff_t *pos) ++{ ++ seq_printf(seq, " Length | Count\n"); ++ if (*pos < 15) ++ return pos; ++ return NULL; ++} ++ ++static void *seq_TsoLen_next(struct seq_file *seq, void *v, loff_t *pos) ++{ ++ (*pos)++; ++ if (*pos >= 15) ++ return NULL; ++ return pos; ++} ++ ++static void seq_TsoLen_stop(struct seq_file *seq, void *v) ++{ ++ /* Nothing to do */ ++} ++ ++static int seq_TsoLen_show(struct seq_file *seq, void *v) ++{ ++ int i = *(loff_t *) v; ++ ++ seq_printf(seq, "%d~%d: %d\n", i*5000, (i+1)*5000, tso_cnt[i]); ++ ++ return 0; ++} ++ ++static const struct seq_operations seq_tso_txd_num_ops = { ++ .start = seq_TsoTxdNum_start, ++ .next = seq_TsoTxdNum_next, ++ .stop = seq_TsoTxdNum_stop, ++ .show = seq_TsoTxdNum_show ++}; ++ ++static int tso_txd_num_open(struct inode *inode, struct file *file) ++{ ++ return seq_open(file, &seq_tso_txd_num_ops); ++} ++ ++static struct file_operations tso_txd_num_fops = { ++ .owner = THIS_MODULE, ++ .open = tso_txd_num_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .write = NumOfTxdWrite, ++ .release = seq_release ++}; ++ ++static const struct seq_operations seq_tso_len_ops = { ++ .start = seq_TsoLen_start, ++ .next = seq_TsoLen_next, ++ .stop = seq_TsoLen_stop, ++ .show = seq_TsoLen_show ++}; ++ ++static int tso_len_open(struct inode *inode, struct file *file) ++{ ++ return seq_open(file, &seq_tso_len_ops); ++} ++ ++static struct file_operations tso_len_fops = { ++ .owner = THIS_MODULE, ++ .open = tso_len_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .write = TsoLenWrite, ++ .release = seq_release ++}; ++#endif ++ ++#if defined(CONFIG_RAETH_LRO) ++static int LroLenUpdate(struct net_lro_desc *lro_desc) ++{ ++ int len_idx; ++ ++ if(lro_desc->ip_tot_len > 65000) { ++ len_idx = 13; ++ }else if(lro_desc->ip_tot_len > 60000) { ++ len_idx = 12; ++ }else if(lro_desc->ip_tot_len > 55000) { ++ len_idx = 11; ++ }else if(lro_desc->ip_tot_len > 50000) { ++ len_idx = 10; ++ }else if(lro_desc->ip_tot_len > 45000) { ++ len_idx = 9; ++ }else if(lro_desc->ip_tot_len > 40000) { ++ len_idx = 8; ++ }else if(lro_desc->ip_tot_len > 35000) { ++ len_idx = 7; ++ }else if(lro_desc->ip_tot_len > 30000) { ++ len_idx = 6; ++ }else if(lro_desc->ip_tot_len > 25000) { ++ len_idx = 5; ++ }else if(lro_desc->ip_tot_len > 20000) { ++ len_idx = 4; ++ }else if(lro_desc->ip_tot_len > 15000) { ++ len_idx = 3; ++ }else if(lro_desc->ip_tot_len > 10000) { ++ len_idx = 2; ++ }else if(lro_desc->ip_tot_len > 5000) { ++ len_idx = 1; ++ }else { ++ len_idx = 0; ++ } ++ ++ return len_idx; ++} ++int LroStatsUpdate(struct net_lro_mgr *lro_mgr, bool all_flushed) ++{ ++ struct net_lro_desc *tmp; ++ int len_idx; ++ int i, j; ++ ++ if (all_flushed) { ++ for (i=0; i< MAX_DESC; i++) { ++ tmp = & lro_mgr->lro_arr[i]; ++ if (tmp->pkt_aggr_cnt !=0) { ++ for(j=0; j<=MAX_AGGR; j++) { ++ if(tmp->pkt_aggr_cnt == j) { ++ lro_flush_cnt[j]++; ++ } ++ } ++ len_idx = LroLenUpdate(tmp); ++ lro_len_cnt1[len_idx]++; ++ tot_called1++; ++ } ++ aggregated[i] = 0; ++ } ++ } else { ++ if (lro_flushed != lro_mgr->stats.flushed) { ++ if (lro_aggregated != lro_mgr->stats.aggregated) { ++ for (i=0; i<MAX_DESC; i++) { ++ tmp = &lro_mgr->lro_arr[i]; ++ if ((aggregated[i]!= tmp->pkt_aggr_cnt) ++ && (tmp->pkt_aggr_cnt == 0)) { ++ aggregated[i] ++; ++ for (j=0; j<=MAX_AGGR; j++) { ++ if (aggregated[i] == j) { ++ lro_stats_cnt[j] ++; ++ } ++ } ++ aggregated[i] = 0; ++ //len_idx = LroLenUpdate(tmp); ++ //lro_len_cnt2[len_idx]++; ++ tot_called2++; ++ } ++ } ++ } else { ++ for (i=0; i<MAX_DESC; i++) { ++ tmp = &lro_mgr->lro_arr[i]; ++ if ((aggregated[i] != 0) && (tmp->pkt_aggr_cnt==0)) { ++ for (j=0; j<=MAX_AGGR; j++) { ++ if (aggregated[i] == j) { ++ lro_stats_cnt[j] ++; ++ } ++ } ++ aggregated[i] = 0; ++ //len_idx = LroLenUpdate(tmp); ++ //lro_len_cnt2[len_idx]++; ++ force_flush ++; ++ tot_called2++; ++ } ++ } ++ } ++ } else { ++ if (lro_aggregated != lro_mgr->stats.aggregated) { ++ for (i=0; i<MAX_DESC; i++) { ++ tmp = &lro_mgr->lro_arr[i]; ++ if (tmp->active) { ++ if (aggregated[i] != tmp->pkt_aggr_cnt) ++ aggregated[i] = tmp->pkt_aggr_cnt; ++ } else ++ aggregated[i] = 0; ++ } ++ } ++ } ++ ++ } ++ ++ lro_aggregated = lro_mgr->stats.aggregated; ++ lro_flushed = lro_mgr->stats.flushed; ++ lro_nodesc = lro_mgr->stats.no_desc; ++ ++ return 0; ++ ++} ++ ++ ++ssize_t LroStatsWrite(struct file *file, const char __user *buffer, ++ size_t count, loff_t *data) ++{ ++ memset(lro_stats_cnt, 0, sizeof(lro_stats_cnt)); ++ memset(lro_flush_cnt, 0, sizeof(lro_flush_cnt)); ++ memset(lro_len_cnt1, 0, sizeof(lro_len_cnt1)); ++ //memset(lro_len_cnt2, 0, sizeof(lro_len_cnt2)); ++ memset(aggregated, 0, sizeof(aggregated)); ++ lro_aggregated = 0; ++ lro_flushed = 0; ++ lro_nodesc = 0; ++ force_flush = 0; ++ tot_called1 = 0; ++ tot_called2 = 0; ++ printk("clear lro cnt table\n"); ++ ++ return count; ++} ++ ++int LroStatsRead(struct seq_file *seq, void *v) ++{ ++ int i; ++ int tot_cnt=0; ++ int tot_aggr=0; ++ int ave_aggr=0; ++ ++ seq_printf(seq, "LRO statistic dump:\n"); ++ seq_printf(seq, "Cnt: Kernel | Driver\n"); ++ for(i=0; i<=MAX_AGGR; i++) { ++ tot_cnt = tot_cnt + lro_stats_cnt[i] + lro_flush_cnt[i]; ++ seq_printf(seq, " %d : %d %d\n", i, lro_stats_cnt[i], lro_flush_cnt[i]); ++ tot_aggr = tot_aggr + i * (lro_stats_cnt[i] + lro_flush_cnt[i]); ++ } ++ ave_aggr = lro_aggregated/lro_flushed; ++ seq_printf(seq, "Total aggregated pkt: %d\n", lro_aggregated); ++ seq_printf(seq, "Flushed pkt: %d %d\n", lro_flushed, force_flush); ++ seq_printf(seq, "Average flush cnt: %d\n", ave_aggr); ++ seq_printf(seq, "No descriptor pkt: %d\n\n\n", lro_nodesc); ++ ++ seq_printf(seq, "Driver flush pkt len:\n"); ++ seq_printf(seq, " Length | Count\n"); ++ for(i=0; i<15; i++) { ++ seq_printf(seq, "%d~%d: %d\n", i*5000, (i+1)*5000, lro_len_cnt1[i]); ++ } ++ seq_printf(seq, "Kernel flush: %d; Driver flush: %d\n", tot_called2, tot_called1); ++ return 0; ++} ++ ++static int lro_stats_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, LroStatsRead, NULL); ++} ++ ++static struct file_operations lro_stats_fops = { ++ .owner = THIS_MODULE, ++ .open = lro_stats_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .write = LroStatsWrite, ++ .release = single_release ++}; ++#endif ++ ++int getnext(const char *src, int separator, char *dest) ++{ ++ char *c; ++ int len; ++ ++ if ( (src == NULL) || (dest == NULL) ) { ++ return -1; ++ } ++ ++ c = strchr(src, separator); ++ if (c == NULL) { ++ strcpy(dest, src); ++ return -1; ++ } ++ len = c - src; ++ strncpy(dest, src, len); ++ dest[len] = '\0'; ++ return len + 1; ++} ++ ++int str_to_ip(unsigned int *ip, const char *str) ++{ ++ int len; ++ const char *ptr = str; ++ char buf[128]; ++ unsigned char c[4]; ++ int i; ++ ++ for (i = 0; i < 3; ++i) { ++ if ((len = getnext(ptr, '.', buf)) == -1) { ++ return 1; /* parse error */ ++ } ++ c[i] = simple_strtoul(buf, NULL, 10); ++ ptr += len; ++ } ++ c[3] = simple_strtoul(ptr, NULL, 0); ++ *ip = (c[0]<<24) + (c[1]<<16) + (c[2]<<8) + c[3]; ++ return 0; ++} ++ ++#if defined(CONFIG_RAETH_HW_LRO) ++static int HwLroLenUpdate(unsigned int agg_size) ++{ ++ int len_idx; ++ ++ if(agg_size > 65000) { ++ len_idx = 13; ++ }else if(agg_size > 60000) { ++ len_idx = 12; ++ }else if(agg_size > 55000) { ++ len_idx = 11; ++ }else if(agg_size > 50000) { ++ len_idx = 10; ++ }else if(agg_size > 45000) { ++ len_idx = 9; ++ }else if(agg_size > 40000) { ++ len_idx = 8; ++ }else if(agg_size > 35000) { ++ len_idx = 7; ++ }else if(agg_size > 30000) { ++ len_idx = 6; ++ }else if(agg_size > 25000) { ++ len_idx = 5; ++ }else if(agg_size > 20000) { ++ len_idx = 4; ++ }else if(agg_size > 15000) { ++ len_idx = 3; ++ }else if(agg_size > 10000) { ++ len_idx = 2; ++ }else if(agg_size > 5000) { ++ len_idx = 1; ++ }else { ++ len_idx = 0; ++ } ++ ++ return len_idx; ++} ++ ++int HwLroStatsUpdate(unsigned int ring_num, unsigned int agg_cnt, unsigned int agg_size) ++{ ++ if( (ring_num > 0) && (ring_num < 4) ) ++ { ++ hw_lro_agg_size_cnt[ring_num-1][HwLroLenUpdate(agg_size)]++; ++ hw_lro_agg_num_cnt[ring_num-1][agg_cnt]++; ++ hw_lro_tot_flush_cnt[ring_num-1]++; ++ hw_lro_tot_agg_cnt[ring_num-1] += agg_cnt; ++ } ++ ++ return 0; ++} ++ ++#if defined(CONFIG_RAETH_HW_LRO_REASON_DBG) ++int HwLroFlushStatsUpdate(unsigned int ring_num, unsigned int flush_reason) ++{ ++ if( (ring_num > 0) && (ring_num < 4) ) ++ { ++#if 1 ++ if ( (flush_reason & 0x7) == HW_LRO_AGG_FLUSH ) ++ hw_lro_agg_flush_cnt[ring_num-1]++; ++ else if ( (flush_reason & 0x7) == HW_LRO_AGE_FLUSH ) ++ hw_lro_age_flush_cnt[ring_num-1]++; ++ else if ( (flush_reason & 0x7) == HW_LRO_NOT_IN_SEQ_FLUSH ) ++ hw_lro_seq_flush_cnt[ring_num-1]++; ++ else if ( (flush_reason & 0x7) == HW_LRO_TIMESTAMP_FLUSH ) ++ hw_lro_timestamp_flush_cnt[ring_num-1]++; ++ else if ( (flush_reason & 0x7) == HW_LRO_NON_RULE_FLUSH ) ++ hw_lro_norule_flush_cnt[ring_num-1]++; ++#else ++ if ( flush_reason & BIT(4) ) ++ hw_lro_agg_flush_cnt[ring_num-1]++; ++ else if ( flush_reason & BIT(3) ) ++ hw_lro_age_flush_cnt[ring_num-1]++; ++ else if ( flush_reason & BIT(2) ) ++ hw_lro_seq_flush_cnt[ring_num-1]++; ++ else if ( flush_reason & BIT(1) ) ++ hw_lro_timestamp_flush_cnt[ring_num-1]++; ++ else if ( flush_reason & BIT(0) ) ++ hw_lro_norule_flush_cnt[ring_num-1]++; ++#endif ++ } ++ ++ return 0; ++} ++#endif /* CONFIG_RAETH_HW_LRO_REASON_DBG */ ++ ++ssize_t HwLroStatsWrite(struct file *file, const char __user *buffer, ++ size_t count, loff_t *data) ++{ ++ memset(hw_lro_agg_num_cnt, 0, sizeof(hw_lro_agg_num_cnt)); ++ memset(hw_lro_agg_size_cnt, 0, sizeof(hw_lro_agg_size_cnt)); ++ memset(hw_lro_tot_agg_cnt, 0, sizeof(hw_lro_tot_agg_cnt)); ++ memset(hw_lro_tot_flush_cnt, 0, sizeof(hw_lro_tot_flush_cnt)); ++#if defined(CONFIG_RAETH_HW_LRO_REASON_DBG) ++ memset(hw_lro_agg_flush_cnt, 0, sizeof(hw_lro_agg_flush_cnt)); ++ memset(hw_lro_age_flush_cnt, 0, sizeof(hw_lro_age_flush_cnt)); ++ memset(hw_lro_seq_flush_cnt, 0, sizeof(hw_lro_seq_flush_cnt)); ++ memset(hw_lro_timestamp_flush_cnt, 0, sizeof(hw_lro_timestamp_flush_cnt)); ++ memset(hw_lro_norule_flush_cnt, 0, sizeof(hw_lro_norule_flush_cnt)); ++#endif /* CONFIG_RAETH_HW_LRO_REASON_DBG */ ++ ++ printk("clear hw lro cnt table\n"); ++ ++ return count; ++} ++ ++int HwLroStatsRead(struct seq_file *seq, void *v) ++{ ++ int i; ++ ++ seq_printf(seq, "HW LRO statistic dump:\n"); ++ ++ /* Agg number count */ ++ seq_printf(seq, "Cnt: RING1 | RING2 | RING3 | Total\n"); ++ for(i=0; i<=MAX_HW_LRO_AGGR; i++) { ++ seq_printf(seq, " %d : %d %d %d %d\n", ++ i, hw_lro_agg_num_cnt[0][i], hw_lro_agg_num_cnt[1][i], hw_lro_agg_num_cnt[2][i], ++ hw_lro_agg_num_cnt[0][i]+hw_lro_agg_num_cnt[1][i]+hw_lro_agg_num_cnt[2][i]); ++ } ++ ++ /* Total agg count */ ++ seq_printf(seq, "Total agg: RING1 | RING2 | RING3 | Total\n"); ++ seq_printf(seq, " %d %d %d %d\n", ++ hw_lro_tot_agg_cnt[0], hw_lro_tot_agg_cnt[1], hw_lro_tot_agg_cnt[2], ++ hw_lro_tot_agg_cnt[0]+hw_lro_tot_agg_cnt[1]+hw_lro_tot_agg_cnt[2]); ++ ++ /* Total flush count */ ++ seq_printf(seq, "Total flush: RING1 | RING2 | RING3 | Total\n"); ++ seq_printf(seq, " %d %d %d %d\n", ++ hw_lro_tot_flush_cnt[0], hw_lro_tot_flush_cnt[1], hw_lro_tot_flush_cnt[2], ++ hw_lro_tot_flush_cnt[0]+hw_lro_tot_flush_cnt[1]+hw_lro_tot_flush_cnt[2]); ++ ++ /* Avg agg count */ ++ seq_printf(seq, "Avg agg: RING1 | RING2 | RING3 | Total\n"); ++ seq_printf(seq, " %d %d %d %d\n", ++ (hw_lro_tot_flush_cnt[0]) ? hw_lro_tot_agg_cnt[0]/hw_lro_tot_flush_cnt[0] : 0, ++ (hw_lro_tot_flush_cnt[1]) ? hw_lro_tot_agg_cnt[1]/hw_lro_tot_flush_cnt[1] : 0, ++ (hw_lro_tot_flush_cnt[2]) ? hw_lro_tot_agg_cnt[2]/hw_lro_tot_flush_cnt[2] : 0, ++ (hw_lro_tot_flush_cnt[0]+hw_lro_tot_flush_cnt[1]+hw_lro_tot_flush_cnt[2]) ? \ ++ ((hw_lro_tot_agg_cnt[0]+hw_lro_tot_agg_cnt[1]+hw_lro_tot_agg_cnt[2])/(hw_lro_tot_flush_cnt[0]+hw_lro_tot_flush_cnt[1]+hw_lro_tot_flush_cnt[2])) : 0 ++ ); ++ ++ /* Statistics of aggregation size counts */ ++ seq_printf(seq, "HW LRO flush pkt len:\n"); ++ seq_printf(seq, " Length | RING1 | RING2 | RING3 | Total\n"); ++ for(i=0; i<15; i++) { ++ seq_printf(seq, "%d~%d: %d %d %d %d\n", i*5000, (i+1)*5000, ++ hw_lro_agg_size_cnt[0][i], hw_lro_agg_size_cnt[1][i], hw_lro_agg_size_cnt[2][i], ++ hw_lro_agg_size_cnt[0][i]+hw_lro_agg_size_cnt[1][i]+hw_lro_agg_size_cnt[2][i]); ++ } ++#if defined(CONFIG_RAETH_HW_LRO_REASON_DBG) ++ seq_printf(seq, "Flush reason: RING1 | RING2 | RING3 | Total\n"); ++ seq_printf(seq, "AGG timeout: %d %d %d %d\n", ++ hw_lro_agg_flush_cnt[0], hw_lro_agg_flush_cnt[1], hw_lro_agg_flush_cnt[2], ++ (hw_lro_agg_flush_cnt[0]+hw_lro_agg_flush_cnt[1]+hw_lro_agg_flush_cnt[2]) ++ ); ++ seq_printf(seq, "AGE timeout: %d %d %d %d\n", ++ hw_lro_age_flush_cnt[0], hw_lro_age_flush_cnt[1], hw_lro_age_flush_cnt[2], ++ (hw_lro_age_flush_cnt[0]+hw_lro_age_flush_cnt[1]+hw_lro_age_flush_cnt[2]) ++ ); ++ seq_printf(seq, "Not in-sequence: %d %d %d %d\n", ++ hw_lro_seq_flush_cnt[0], hw_lro_seq_flush_cnt[1], hw_lro_seq_flush_cnt[2], ++ (hw_lro_seq_flush_cnt[0]+hw_lro_seq_flush_cnt[1]+hw_lro_seq_flush_cnt[2]) ++ ); ++ seq_printf(seq, "Timestamp: %d %d %d %d\n", ++ hw_lro_timestamp_flush_cnt[0], hw_lro_timestamp_flush_cnt[1], hw_lro_timestamp_flush_cnt[2], ++ (hw_lro_timestamp_flush_cnt[0]+hw_lro_timestamp_flush_cnt[1]+hw_lro_timestamp_flush_cnt[2]) ++ ); ++ seq_printf(seq, "No LRO rule: %d %d %d %d\n", ++ hw_lro_norule_flush_cnt[0], hw_lro_norule_flush_cnt[1], hw_lro_norule_flush_cnt[2], ++ (hw_lro_norule_flush_cnt[0]+hw_lro_norule_flush_cnt[1]+hw_lro_norule_flush_cnt[2]) ++ ); ++#endif /* CONFIG_RAETH_HW_LRO_REASON_DBG */ ++ ++ return 0; ++} ++ ++static int hw_lro_stats_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, HwLroStatsRead, NULL); ++} ++ ++static struct file_operations hw_lro_stats_fops = { ++ .owner = THIS_MODULE, ++ .open = hw_lro_stats_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .write = HwLroStatsWrite, ++ .release = single_release ++}; ++ ++int hwlro_agg_cnt_ctrl(int par1, int par2) ++{ ++ SET_PDMA_RXRING_MAX_AGG_CNT(ADMA_RX_RING1, par2); ++ SET_PDMA_RXRING_MAX_AGG_CNT(ADMA_RX_RING2, par2); ++ SET_PDMA_RXRING_MAX_AGG_CNT(ADMA_RX_RING3, par2); ++ return 0; ++} ++ ++int hwlro_agg_time_ctrl(int par1, int par2) ++{ ++ SET_PDMA_RXRING_AGG_TIME(ADMA_RX_RING1, par2); ++ SET_PDMA_RXRING_AGG_TIME(ADMA_RX_RING2, par2); ++ SET_PDMA_RXRING_AGG_TIME(ADMA_RX_RING3, par2); ++ return 0; ++} ++ ++int hwlro_age_time_ctrl(int par1, int par2) ++{ ++ SET_PDMA_RXRING_AGE_TIME(ADMA_RX_RING1, par2); ++ SET_PDMA_RXRING_AGE_TIME(ADMA_RX_RING2, par2); ++ SET_PDMA_RXRING_AGE_TIME(ADMA_RX_RING3, par2); ++ return 0; ++} ++ ++int hwlro_pkt_int_alpha_ctrl(int par1, int par2) ++{ ++ END_DEVICE *ei_local = netdev_priv(dev_raether); ++ ++ ei_local->hw_lro_alpha = par2; ++ printk("[hwlro_pkt_int_alpha_ctrl]ei_local->hw_lro_alpha = %d\n", ei_local->hw_lro_alpha); ++ ++ return 0; ++} ++ ++int hwlro_threshold_ctrl(int par1, int par2) ++{ ++ /* bandwidth threshold setting */ ++ SET_PDMA_LRO_BW_THRESHOLD(par2); ++ return 0; ++} ++ ++int hwlro_fix_setting_switch_ctrl(int par1, int par2) ++{ ++#if defined (CONFIG_RAETH_HW_LRO_AUTO_ADJ_DBG) ++ END_DEVICE *ei_local = netdev_priv(dev_raether); ++ ++ ei_local->hw_lro_fix_setting = par2; ++ printk("[hwlro_pkt_int_alpha_ctrl]ei_local->hw_lro_fix_setting = %d\n", ei_local->hw_lro_fix_setting); ++#endif /* CONFIG_RAETH_HW_LRO_AUTO_ADJ_DBG */ ++ ++ return 0; ++} ++ ++ssize_t HwLroAutoTlbWrite(struct file *file, const char __user *buffer, ++ size_t count, loff_t *data) ++{ ++ char buf[32]; ++ char *pBuf; ++ int len = count; ++ int x = 0,y = 0; ++ char *pToken = NULL; ++ char *pDelimiter = " \t"; ++ ++ printk("[HwLroAutoTlbWrite]write parameter len = %d\n\r", (int)len); ++ if(len >= sizeof(buf)){ ++ printk("input handling fail!\n"); ++ len = sizeof(buf) - 1; ++ return -1; ++ } ++ ++ if(copy_from_user(buf, buffer, len)){ ++ return -EFAULT; ++ } ++ buf[len] = '\0'; ++ printk("[HwLroAutoTlbWrite]write parameter data = %s\n\r", buf); ++ ++ pBuf = buf; ++ pToken = strsep(&pBuf, pDelimiter); ++ x = NULL != pToken ? simple_strtol(pToken, NULL, 16) : 0; ++ ++ pToken = strsep(&pBuf, "\t\n "); ++ if(pToken != NULL){ ++ y = NULL != pToken ? simple_strtol(pToken, NULL, 16) : 0; ++ printk("y = 0x%08x \n\r", y); ++ } ++ ++ if ( (sizeof(hw_lro_dbg_func)/sizeof(hw_lro_dbg_func[0]) > x) && NULL != hw_lro_dbg_func[x]) ++ { ++ (*hw_lro_dbg_func[x])(x, y); ++ } ++ ++ return count; ++} ++ ++void HwLroAutoTlbDump(struct seq_file *seq, unsigned int index) ++{ ++ int i; ++ struct PDMA_LRO_AUTO_TLB_INFO pdma_lro_auto_tlb; ++ unsigned int tlb_info[9]; ++ unsigned int dw_len, cnt, priority; ++ unsigned int entry; ++ ++ if( index > 4 ) ++ index = index - 1; ++ entry = (index * 9) + 1; ++ ++ /* read valid entries of the auto-learn table */ ++ sysRegWrite( PDMA_FE_ALT_CF8, entry ); ++ ++ //seq_printf(seq, "\nEntry = %d\n", entry); ++ for(i=0; i<9; i++){ ++ tlb_info[i] = sysRegRead(PDMA_FE_ALT_SEQ_CFC); ++ //seq_printf(seq, "tlb_info[%d] = 0x%x\n", i, tlb_info[i]); ++ } ++ memcpy(&pdma_lro_auto_tlb, tlb_info, sizeof(struct PDMA_LRO_AUTO_TLB_INFO)); ++ ++ dw_len = pdma_lro_auto_tlb.auto_tlb_info7.DW_LEN; ++ cnt = pdma_lro_auto_tlb.auto_tlb_info6.CNT; ++ ++ if ( sysRegRead(ADMA_LRO_CTRL_DW0) & PDMA_LRO_ALT_SCORE_MODE ) /* packet count */ ++ priority = cnt; ++ else /* byte count */ ++ priority = dw_len; ++ ++ /* dump valid entries of the auto-learn table */ ++ if( index >= 4 ) ++ seq_printf(seq, "\n===== TABLE Entry: %d (Act) =====\n", index); ++ else ++ seq_printf(seq, "\n===== TABLE Entry: %d (LRU) =====\n", index); ++ if( pdma_lro_auto_tlb.auto_tlb_info8.IPV4 ){ ++ seq_printf(seq, "SIP = 0x%x:0x%x:0x%x:0x%x (IPv4)\n", ++ pdma_lro_auto_tlb.auto_tlb_info4.SIP3, ++ pdma_lro_auto_tlb.auto_tlb_info3.SIP2, ++ pdma_lro_auto_tlb.auto_tlb_info2.SIP1, ++ pdma_lro_auto_tlb.auto_tlb_info1.SIP0); ++ } ++ else{ ++ seq_printf(seq, "SIP = 0x%x:0x%x:0x%x:0x%x (IPv6)\n", ++ pdma_lro_auto_tlb.auto_tlb_info4.SIP3, ++ pdma_lro_auto_tlb.auto_tlb_info3.SIP2, ++ pdma_lro_auto_tlb.auto_tlb_info2.SIP1, ++ pdma_lro_auto_tlb.auto_tlb_info1.SIP0); ++ } ++ seq_printf(seq, "DIP_ID = %d\n", pdma_lro_auto_tlb.auto_tlb_info8.DIP_ID); ++ seq_printf(seq, "TCP SPORT = %d | TCP DPORT = %d\n", ++ pdma_lro_auto_tlb.auto_tlb_info0.STP, ++ pdma_lro_auto_tlb.auto_tlb_info0.DTP); ++ seq_printf(seq, "VLAN1 = %d | VLAN2 = %d | VLAN3 = %d | VLAN4 =%d \n", ++ pdma_lro_auto_tlb.auto_tlb_info5.VLAN_VID0, ++ (pdma_lro_auto_tlb.auto_tlb_info5.VLAN_VID0 << 12), ++ (pdma_lro_auto_tlb.auto_tlb_info5.VLAN_VID0 << 24), ++ pdma_lro_auto_tlb.auto_tlb_info6.VLAN_VID1); ++ seq_printf(seq, "TPUT = %d | FREQ = %d\n", dw_len, cnt); ++ seq_printf(seq, "PRIORITY = %d\n", priority); ++} ++ ++int HwLroAutoTlbRead(struct seq_file *seq, void *v) ++{ ++ int i; ++ unsigned int regVal; ++ unsigned int regOp1, regOp2, regOp3, regOp4; ++ unsigned int agg_cnt, agg_time, age_time; ++ ++ /* Read valid entries of the auto-learn table */ ++ sysRegWrite(PDMA_FE_ALT_CF8, 0); ++ regVal = sysRegRead(PDMA_FE_ALT_SEQ_CFC); ++ ++ seq_printf(seq, "HW LRO Auto-learn Table: (PDMA_LRO_ALT_CFC_RSEQ_DBG=0x%x)\n", regVal); ++ ++ for(i = 7; i >= 0; i--) ++ { ++ if( regVal & (1 << i) ) ++ HwLroAutoTlbDump(seq, i); ++ } ++ ++ /* Read the agg_time/age_time/agg_cnt of LRO rings */ ++ seq_printf(seq, "\nHW LRO Ring Settings\n"); ++ for(i = 1; i <= 3; i++) ++ { ++ regOp1 = sysRegRead( LRO_RX_RING0_CTRL_DW1 + (i * 0x40) ); ++ regOp2 = sysRegRead( LRO_RX_RING0_CTRL_DW2 + (i * 0x40) ); ++ regOp3 = sysRegRead( LRO_RX_RING0_CTRL_DW3 + (i * 0x40) ); ++ regOp4 = sysRegRead( ADMA_LRO_CTRL_DW2 ); ++ agg_cnt = ((regOp3 & 0x03) << PDMA_LRO_AGG_CNT_H_OFFSET) | ((regOp2 >> PDMA_LRO_RING_AGG_CNT1_OFFSET) & 0x3f); ++ agg_time = (regOp2 >> PDMA_LRO_RING_AGG_OFFSET) & 0xffff; ++ age_time = ((regOp2 & 0x03f) << PDMA_LRO_AGE_H_OFFSET) | ((regOp1 >> PDMA_LRO_RING_AGE1_OFFSET) & 0x3ff); ++ seq_printf(seq, "Ring[%d]: MAX_AGG_CNT=%d, AGG_TIME=%d, AGE_TIME=%d, Threshold=%d\n", ++ i, agg_cnt, agg_time, age_time, regOp4); ++ } ++ ++ return 0; ++} ++ ++static int hw_lro_auto_tlb_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, HwLroAutoTlbRead, NULL); ++} ++ ++static struct file_operations hw_lro_auto_tlb_fops = { ++ .owner = THIS_MODULE, ++ .open = hw_lro_auto_tlb_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .write = HwLroAutoTlbWrite, ++ .release = single_release ++}; ++#endif /* CONFIG_RAETH_HW_LRO */ ++ ++#if defined (CONFIG_MIPS) ++int CP0RegRead(struct seq_file *seq, void *v) ++{ ++ seq_printf(seq, "CP0 Register dump --\n"); ++ seq_printf(seq, "CP0_INDEX\t: 0x%08x\n", read_32bit_cp0_register(CP0_INDEX)); ++ seq_printf(seq, "CP0_RANDOM\t: 0x%08x\n", read_32bit_cp0_register(CP0_RANDOM)); ++ seq_printf(seq, "CP0_ENTRYLO0\t: 0x%08x\n", read_32bit_cp0_register(CP0_ENTRYLO0)); ++ seq_printf(seq, "CP0_ENTRYLO1\t: 0x%08x\n", read_32bit_cp0_register(CP0_ENTRYLO1)); ++ seq_printf(seq, "CP0_CONF\t: 0x%08x\n", read_32bit_cp0_register(CP0_CONF)); ++ seq_printf(seq, "CP0_CONTEXT\t: 0x%08x\n", read_32bit_cp0_register(CP0_CONTEXT)); ++ seq_printf(seq, "CP0_PAGEMASK\t: 0x%08x\n", read_32bit_cp0_register(CP0_PAGEMASK)); ++ seq_printf(seq, "CP0_WIRED\t: 0x%08x\n", read_32bit_cp0_register(CP0_WIRED)); ++ seq_printf(seq, "CP0_INFO\t: 0x%08x\n", read_32bit_cp0_register(CP0_INFO)); ++ seq_printf(seq, "CP0_BADVADDR\t: 0x%08x\n", read_32bit_cp0_register(CP0_BADVADDR)); ++ seq_printf(seq, "CP0_COUNT\t: 0x%08x\n", read_32bit_cp0_register(CP0_COUNT)); ++ seq_printf(seq, "CP0_ENTRYHI\t: 0x%08x\n", read_32bit_cp0_register(CP0_ENTRYHI)); ++ seq_printf(seq, "CP0_COMPARE\t: 0x%08x\n", read_32bit_cp0_register(CP0_COMPARE)); ++ seq_printf(seq, "CP0_STATUS\t: 0x%08x\n", read_32bit_cp0_register(CP0_STATUS)); ++ seq_printf(seq, "CP0_CAUSE\t: 0x%08x\n", read_32bit_cp0_register(CP0_CAUSE)); ++ seq_printf(seq, "CP0_EPC\t: 0x%08x\n", read_32bit_cp0_register(CP0_EPC)); ++ seq_printf(seq, "CP0_PRID\t: 0x%08x\n", read_32bit_cp0_register(CP0_PRID)); ++ seq_printf(seq, "CP0_CONFIG\t: 0x%08x\n", read_32bit_cp0_register(CP0_CONFIG)); ++ seq_printf(seq, "CP0_LLADDR\t: 0x%08x\n", read_32bit_cp0_register(CP0_LLADDR)); ++ seq_printf(seq, "CP0_WATCHLO\t: 0x%08x\n", read_32bit_cp0_register(CP0_WATCHLO)); ++ seq_printf(seq, "CP0_WATCHHI\t: 0x%08x\n", read_32bit_cp0_register(CP0_WATCHHI)); ++ seq_printf(seq, "CP0_XCONTEXT\t: 0x%08x\n", read_32bit_cp0_register(CP0_XCONTEXT)); ++ seq_printf(seq, "CP0_FRAMEMASK\t: 0x%08x\n", read_32bit_cp0_register(CP0_FRAMEMASK)); ++ seq_printf(seq, "CP0_DIAGNOSTIC\t: 0x%08x\n", read_32bit_cp0_register(CP0_DIAGNOSTIC)); ++ seq_printf(seq, "CP0_DEBUG\t: 0x%08x\n", read_32bit_cp0_register(CP0_DEBUG)); ++ seq_printf(seq, "CP0_DEPC\t: 0x%08x\n", read_32bit_cp0_register(CP0_DEPC)); ++ seq_printf(seq, "CP0_PERFORMANCE\t: 0x%08x\n", read_32bit_cp0_register(CP0_PERFORMANCE)); ++ seq_printf(seq, "CP0_ECC\t: 0x%08x\n", read_32bit_cp0_register(CP0_ECC)); ++ seq_printf(seq, "CP0_CACHEERR\t: 0x%08x\n", read_32bit_cp0_register(CP0_CACHEERR)); ++ seq_printf(seq, "CP0_TAGLO\t: 0x%08x\n", read_32bit_cp0_register(CP0_TAGLO)); ++ seq_printf(seq, "CP0_TAGHI\t: 0x%08x\n", read_32bit_cp0_register(CP0_TAGHI)); ++ seq_printf(seq, "CP0_ERROREPC\t: 0x%08x\n", read_32bit_cp0_register(CP0_ERROREPC)); ++ seq_printf(seq, "CP0_DESAVE\t: 0x%08x\n\n", read_32bit_cp0_register(CP0_DESAVE)); ++ ++ return 0; ++} ++ ++static int cp0_reg_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, CP0RegRead, NULL); ++} ++ ++static const struct file_operations cp0_reg_fops = { ++ .owner = THIS_MODULE, ++ .open = cp0_reg_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release ++}; ++#endif ++ ++#if defined(CONFIG_RAETH_QOS) ++static struct proc_dir_entry *procRaQOS, *procRaFeIntr, *procRaEswIntr; ++extern uint32_t num_of_rxdone_intr; ++extern uint32_t num_of_esw_intr; ++ ++int RaQOSRegRead(struct seq_file *seq, void *v) ++{ ++ dump_qos(seq); ++ return 0; ++} ++ ++static int raeth_qos_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, RaQOSRegRead, NULL); ++} ++ ++static const struct file_operations raeth_qos_fops = { ++ .owner = THIS_MODULE, ++ .open = raeth_qos_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release ++}; ++#endif ++ ++static struct proc_dir_entry *procEswCnt; ++ ++int EswCntRead(struct seq_file *seq, void *v) ++{ ++#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_P5_RGMII_TO_MT7530_MODE) || defined (CONFIG_ARCH_MT7623) ++ unsigned int pkt_cnt = 0; ++ int i = 0; ++#endif ++ seq_printf(seq, "\n <<CPU>> \n"); ++ seq_printf(seq, " | \n"); ++#if defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_MT7628) ++ seq_printf(seq, "+-----------------------------------------------+\n"); ++ seq_printf(seq, "| <<PDMA>> |\n"); ++ seq_printf(seq, "+-----------------------------------------------+\n"); ++#else ++ seq_printf(seq, "+-----------------------------------------------+\n"); ++ seq_printf(seq, "| <<PSE>> |\n"); ++ seq_printf(seq, "+-----------------------------------------------+\n"); ++ seq_printf(seq, " | \n"); ++ seq_printf(seq, "+-----------------------------------------------+\n"); ++ seq_printf(seq, "| <<GDMA>> |\n"); ++#if defined (CONFIG_RALINK_MT7620) ++ seq_printf(seq, "| GDMA1_TX_GPCNT : %010u (Tx Good Pkts) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x1304)); ++ seq_printf(seq, "| GDMA1_RX_GPCNT : %010u (Rx Good Pkts) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x1324)); ++ seq_printf(seq, "| |\n"); ++ seq_printf(seq, "| GDMA1_TX_SKIPCNT: %010u (skip) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x1308)); ++ seq_printf(seq, "| GDMA1_TX_COLCNT : %010u (collision) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x130c)); ++ seq_printf(seq, "| GDMA1_RX_OERCNT : %010u (overflow) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x1328)); ++ seq_printf(seq, "| GDMA1_RX_FERCNT : %010u (FCS error) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x132c)); ++ seq_printf(seq, "| GDMA1_RX_SERCNT : %010u (too short) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x1330)); ++ seq_printf(seq, "| GDMA1_RX_LERCNT : %010u (too long) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x1334)); ++ seq_printf(seq, "| GDMA1_RX_CERCNT : %010u (l3/l4 checksum) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x1338)); ++ seq_printf(seq, "| GDMA1_RX_FCCNT : %010u (flow control) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x133c)); ++ ++ seq_printf(seq, "| |\n"); ++ seq_printf(seq, "| GDMA2_TX_GPCNT : %010u (Tx Good Pkts) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x1344)); ++ seq_printf(seq, "| GDMA2_RX_GPCNT : %010u (Rx Good Pkts) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x1364)); ++ seq_printf(seq, "| |\n"); ++ seq_printf(seq, "| GDMA2_TX_SKIPCNT: %010u (skip) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x1348)); ++ seq_printf(seq, "| GDMA2_TX_COLCNT : %010u (collision) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x134c)); ++ seq_printf(seq, "| GDMA2_RX_OERCNT : %010u (overflow) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x1368)); ++ seq_printf(seq, "| GDMA2_RX_FERCNT : %010u (FCS error) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x136c)); ++ seq_printf(seq, "| GDMA2_RX_SERCNT : %010u (too short) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x1370)); ++ seq_printf(seq, "| GDMA2_RX_LERCNT : %010u (too long) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x1374)); ++ seq_printf(seq, "| GDMA2_RX_CERCNT : %010u (l3/l4 checksum) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x1378)); ++ seq_printf(seq, "| GDMA2_RX_FCCNT : %010u (flow control) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x137c)); ++#elif defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++ seq_printf(seq, "| GDMA1_RX_GBCNT : %010u (Rx Good Bytes) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x2400)); ++ seq_printf(seq, "| GDMA1_RX_GPCNT : %010u (Rx Good Pkts) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x2408)); ++ seq_printf(seq, "| GDMA1_RX_OERCNT : %010u (overflow error) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x2410)); ++ seq_printf(seq, "| GDMA1_RX_FERCNT : %010u (FCS error) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x2414)); ++ seq_printf(seq, "| GDMA1_RX_SERCNT : %010u (too short) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x2418)); ++ seq_printf(seq, "| GDMA1_RX_LERCNT : %010u (too long) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x241C)); ++ seq_printf(seq, "| GDMA1_RX_CERCNT : %010u (checksum error) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x2420)); ++ seq_printf(seq, "| GDMA1_RX_FCCNT : %010u (flow control) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x2424)); ++ seq_printf(seq, "| GDMA1_TX_SKIPCNT: %010u (about count) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x2428)); ++ seq_printf(seq, "| GDMA1_TX_COLCNT : %010u (collision count) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x242C)); ++ seq_printf(seq, "| GDMA1_TX_GBCNT : %010u (Tx Good Bytes) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x2430)); ++ seq_printf(seq, "| GDMA1_TX_GPCNT : %010u (Tx Good Pkts) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x2438)); ++ seq_printf(seq, "| |\n"); ++ seq_printf(seq, "| GDMA2_RX_GBCNT : %010u (Rx Good Bytes) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x2440)); ++ seq_printf(seq, "| GDMA2_RX_GPCNT : %010u (Rx Good Pkts) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x2448)); ++ seq_printf(seq, "| GDMA2_RX_OERCNT : %010u (overflow error) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x2450)); ++ seq_printf(seq, "| GDMA2_RX_FERCNT : %010u (FCS error) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x2454)); ++ seq_printf(seq, "| GDMA2_RX_SERCNT : %010u (too short) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x2458)); ++ seq_printf(seq, "| GDMA2_RX_LERCNT : %010u (too long) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x245C)); ++ seq_printf(seq, "| GDMA2_RX_CERCNT : %010u (checksum error) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x2460)); ++ seq_printf(seq, "| GDMA2_RX_FCCNT : %010u (flow control) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x2464)); ++ seq_printf(seq, "| GDMA2_TX_SKIPCNT: %010u (skip) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x2468)); ++ seq_printf(seq, "| GDMA2_TX_COLCNT : %010u (collision) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x246C)); ++ seq_printf(seq, "| GDMA2_TX_GBCNT : %010u (Tx Good Bytes) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x2470)); ++ seq_printf(seq, "| GDMA2_TX_GPCNT : %010u (Tx Good Pkts) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x2478)); ++#else ++ seq_printf(seq, "| GDMA_TX_GPCNT1 : %010u (Tx Good Pkts) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x704)); ++ seq_printf(seq, "| GDMA_RX_GPCNT1 : %010u (Rx Good Pkts) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x724)); ++ seq_printf(seq, "| |\n"); ++ seq_printf(seq, "| GDMA_TX_SKIPCNT1: %010u (skip) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x708)); ++ seq_printf(seq, "| GDMA_TX_COLCNT1 : %010u (collision) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x70c)); ++ seq_printf(seq, "| GDMA_RX_OERCNT1 : %010u (overflow) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x728)); ++ seq_printf(seq, "| GDMA_RX_FERCNT1 : %010u (FCS error) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x72c)); ++ seq_printf(seq, "| GDMA_RX_SERCNT1 : %010u (too short) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x730)); ++ seq_printf(seq, "| GDMA_RX_LERCNT1 : %010u (too long) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x734)); ++ seq_printf(seq, "| GDMA_RX_CERCNT1 : %010u (l3/l4 checksum) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x738)); ++ seq_printf(seq, "| GDMA_RX_FCCNT1 : %010u (flow control) |\n", sysRegRead(RALINK_FRAME_ENGINE_BASE+0x73c)); ++ ++#endif ++ seq_printf(seq, "+-----------------------------------------------+\n"); ++#endif ++ ++#if defined (CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A) || \ ++ defined (CONFIG_RALINK_MT7620) ++ ++ seq_printf(seq, " ^ \n"); ++ seq_printf(seq, " | Port6 Rx:%010u Good Pkt \n", ((p6_rx_good_cnt << 16) | (sysRegRead(RALINK_ETH_SW_BASE+0x4620)&0xFFFF))); ++ seq_printf(seq, " | Port6 Rx:%010u Bad Pkt \n", sysRegRead(RALINK_ETH_SW_BASE+0x4620)>>16); ++ seq_printf(seq, " | Port6 Tx:%010u Good Pkt \n", ((p6_tx_good_cnt << 16) | (sysRegRead(RALINK_ETH_SW_BASE+0x4610)&0xFFFF))); ++ seq_printf(seq, " | Port6 Tx:%010u Bad Pkt \n", sysRegRead(RALINK_ETH_SW_BASE+0x4610)>>16); ++#if defined (CONFIG_RALINK_MT7620) ++ ++ seq_printf(seq, " | Port7 Rx:%010u Good Pkt \n", ((p7_rx_good_cnt << 16) | (sysRegRead(RALINK_ETH_SW_BASE+0x4720)&0xFFFF))); ++ seq_printf(seq, " | Port7 Rx:%010u Bad Pkt \n", sysRegRead(RALINK_ETH_SW_BASE+0x4720)>>16); ++ seq_printf(seq, " | Port7 Tx:%010u Good Pkt \n", ((p7_tx_good_cnt << 16) | (sysRegRead(RALINK_ETH_SW_BASE+0x4710)&0xFFFF))); ++ seq_printf(seq, " | Port7 Tx:%010u Bad Pkt \n", sysRegRead(RALINK_ETH_SW_BASE+0x4710)>>16); ++#endif ++ seq_printf(seq, "+---------------------v-------------------------+\n"); ++ seq_printf(seq, "| P6 |\n"); ++ seq_printf(seq, "| <<10/100/1000 Embedded Switch>> |\n"); ++ seq_printf(seq, "| P0 P1 P2 P3 P4 P5 |\n"); ++ seq_printf(seq, "+-----------------------------------------------+\n"); ++ seq_printf(seq, " | | | | | | \n"); ++#elif defined (CONFIG_RALINK_RT3883) || defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++ /* no built-in switch */ ++#else ++ seq_printf(seq, " ^ \n"); ++ seq_printf(seq, " | Port6 Rx:%08u Good Pkt \n", sysRegRead(RALINK_ETH_SW_BASE+0xE0)&0xFFFF); ++ seq_printf(seq, " | Port6 Tx:%08u Good Pkt \n", sysRegRead(RALINK_ETH_SW_BASE+0xE0)>>16); ++ seq_printf(seq, "+---------------------v-------------------------+\n"); ++ seq_printf(seq, "| P6 |\n"); ++ seq_printf(seq, "| <<10/100 Embedded Switch>> |\n"); ++ seq_printf(seq, "| P0 P1 P2 P3 P4 P5 |\n"); ++ seq_printf(seq, "+-----------------------------------------------+\n"); ++ seq_printf(seq, " | | | | | | \n"); ++#endif ++ ++#if defined (CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A) || \ ++ defined (CONFIG_RALINK_MT7620) ++ ++ seq_printf(seq, "Port0 Good RX=%010u Tx=%010u (Bad Rx=%010u Tx=%010u)\n", ((p0_rx_good_cnt << 16) | (sysRegRead(RALINK_ETH_SW_BASE+0x4020)&0xFFFF)), ((p0_tx_good_cnt << 16)| (sysRegRead(RALINK_ETH_SW_BASE+0x4010)&0xFFFF)), sysRegRead(RALINK_ETH_SW_BASE+0x4020)>>16, sysRegRead(RALINK_ETH_SW_BASE+0x4010)>>16); ++ ++ seq_printf(seq, "Port1 Good RX=%010u Tx=%010u (Bad Rx=%010u Tx=%010u)\n", ((p1_rx_good_cnt << 16) | (sysRegRead(RALINK_ETH_SW_BASE+0x4120)&0xFFFF)), ((p1_tx_good_cnt << 16)| (sysRegRead(RALINK_ETH_SW_BASE+0x4110)&0xFFFF)), sysRegRead(RALINK_ETH_SW_BASE+0x4120)>>16, sysRegRead(RALINK_ETH_SW_BASE+0x4110)>>16); ++ ++ seq_printf(seq, "Port2 Good RX=%010u Tx=%010u (Bad Rx=%010u Tx=%010u)\n", ((p2_rx_good_cnt << 16) | (sysRegRead(RALINK_ETH_SW_BASE+0x4220)&0xFFFF)), ((p2_tx_good_cnt << 16)| (sysRegRead(RALINK_ETH_SW_BASE+0x4210)&0xFFFF)), sysRegRead(RALINK_ETH_SW_BASE+0x4220)>>16, sysRegRead(RALINK_ETH_SW_BASE+0x4210)>>16); ++ ++ seq_printf(seq, "Port3 Good RX=%010u Tx=%010u (Bad Rx=%010u Tx=%010u)\n", ((p3_rx_good_cnt << 16) | (sysRegRead(RALINK_ETH_SW_BASE+0x4320)&0xFFFF)), ((p3_tx_good_cnt << 16)| (sysRegRead(RALINK_ETH_SW_BASE+0x4310)&0xFFFF)), sysRegRead(RALINK_ETH_SW_BASE+0x4320)>>16, sysRegRead(RALINK_ETH_SW_BASE+0x4310)>>16); ++ ++ seq_printf(seq, "Port4 Good RX=%010u Tx=%010u (Bad Rx=%010u Tx=%010u)\n", ((p4_rx_good_cnt << 16) | (sysRegRead(RALINK_ETH_SW_BASE+0x4420)&0xFFFF)), ((p4_tx_good_cnt << 16)| (sysRegRead(RALINK_ETH_SW_BASE+0x4410)&0xFFFF)), sysRegRead(RALINK_ETH_SW_BASE+0x4420)>>16, sysRegRead(RALINK_ETH_SW_BASE+0x4410)>>16); ++ ++ seq_printf(seq, "Port5 Good RX=%010u Tx=%010u (Bad Rx=%010u Tx=%010u)\n", ((p5_rx_good_cnt << 16) | (sysRegRead(RALINK_ETH_SW_BASE+0x4520)&0xFFFF)), ((p5_tx_good_cnt << 16)| (sysRegRead(RALINK_ETH_SW_BASE+0x4510)&0xFFFF)), sysRegRead(RALINK_ETH_SW_BASE+0x4520)>>16, sysRegRead(RALINK_ETH_SW_BASE+0x4510)>>16); ++ ++ seq_printf(seq, "Port0 KBytes RX=%010u Tx=%010u \n", ((p0_rx_byte_cnt << 22) + (sysRegRead(RALINK_ETH_SW_BASE+0x4028) >> 10)), ((p0_tx_byte_cnt << 22) + (sysRegRead(RALINK_ETH_SW_BASE+0x4018) >> 10))); ++ ++ seq_printf(seq, "Port1 KBytes RX=%010u Tx=%010u \n", ((p1_rx_byte_cnt << 22) + (sysRegRead(RALINK_ETH_SW_BASE+0x4128) >> 10)), ((p1_tx_byte_cnt << 22) + (sysRegRead(RALINK_ETH_SW_BASE+0x4118) >> 10))); ++ ++ seq_printf(seq, "Port2 KBytes RX=%010u Tx=%010u \n", ((p2_rx_byte_cnt << 22) + (sysRegRead(RALINK_ETH_SW_BASE+0x4228) >> 10)), ((p2_tx_byte_cnt << 22) + (sysRegRead(RALINK_ETH_SW_BASE+0x4218) >> 10))); ++ ++ seq_printf(seq, "Port3 KBytes RX=%010u Tx=%010u \n", ((p3_rx_byte_cnt << 22) + (sysRegRead(RALINK_ETH_SW_BASE+0x4328) >> 10)), ((p3_tx_byte_cnt << 22) + (sysRegRead(RALINK_ETH_SW_BASE+0x4318) >> 10))); ++ ++ seq_printf(seq, "Port4 KBytes RX=%010u Tx=%010u \n", ((p4_rx_byte_cnt << 22) + (sysRegRead(RALINK_ETH_SW_BASE+0x4428) >> 10)), ((p4_tx_byte_cnt << 22) + (sysRegRead(RALINK_ETH_SW_BASE+0x4418) >> 10))); ++ ++ seq_printf(seq, "Port5 KBytes RX=%010u Tx=%010u \n", ((p5_rx_byte_cnt << 22) + (sysRegRead(RALINK_ETH_SW_BASE+0x4528) >> 10)), ((p5_tx_byte_cnt << 22) + (sysRegRead(RALINK_ETH_SW_BASE+0x4518) >> 10))); ++ ++#if defined (CONFIG_P5_RGMII_TO_MT7530_MODE) ++#define DUMP_EACH_PORT(base) \ ++ for(i=0; i < 7;i++) { \ ++ mii_mgr_read(31, (base) + (i*0x100), &pkt_cnt); \ ++ seq_printf(seq, "%8u ", pkt_cnt); \ ++ } \ ++ seq_printf(seq, "\n"); ++ seq_printf(seq, "========================================[MT7530] READ CLEAR========================\n"); ++ ++ seq_printf(seq, "===================== %8s %8s %8s %8s %8s %8s %8s\n","Port0", "Port1", "Port2", "Port3", "Port4", "Port5", "Port6"); ++ seq_printf(seq, "Tx Drop Packet :"); DUMP_EACH_PORT(0x4000); ++ //seq_printf(seq, "Tx CRC Error :"); DUMP_EACH_PORT(0x4004); ++ seq_printf(seq, "Tx Unicast Packet :"); DUMP_EACH_PORT(0x4008); ++ seq_printf(seq, "Tx Multicast Packet :"); DUMP_EACH_PORT(0x400C); ++ seq_printf(seq, "Tx Broadcast Packet :"); DUMP_EACH_PORT(0x4010); ++ //seq_printf(seq, "Tx Collision Event :"); DUMP_EACH_PORT(0x4014); ++ seq_printf(seq, "Tx Pause Packet :"); DUMP_EACH_PORT(0x402C); ++ seq_printf(seq, "Rx Drop Packet :"); DUMP_EACH_PORT(0x4060); ++ seq_printf(seq, "Rx Filtering Packet :"); DUMP_EACH_PORT(0x4064); ++ seq_printf(seq, "Rx Unicast Packet :"); DUMP_EACH_PORT(0x4068); ++ seq_printf(seq, "Rx Multicast Packet :"); DUMP_EACH_PORT(0x406C); ++ seq_printf(seq, "Rx Broadcast Packet :"); DUMP_EACH_PORT(0x4070); ++ seq_printf(seq, "Rx Alignment Error :"); DUMP_EACH_PORT(0x4074); ++ seq_printf(seq, "Rx CRC Error :"); DUMP_EACH_PORT(0x4078); ++ seq_printf(seq, "Rx Undersize Error :"); DUMP_EACH_PORT(0x407C); ++ //seq_printf(seq, "Rx Fragment Error :"); DUMP_EACH_PORT(0x4080); ++ //seq_printf(seq, "Rx Oversize Error :"); DUMP_EACH_PORT(0x4084); ++ //seq_printf(seq, "Rx Jabber Error :"); DUMP_EACH_PORT(0x4088); ++ seq_printf(seq, "Rx Pause Packet :"); DUMP_EACH_PORT(0x408C); ++ mii_mgr_write(31, 0x4fe0, 0xf0); ++ mii_mgr_write(31, 0x4fe0, 0x800000f0); ++#endif ++ ++ ++#elif defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_MT7628) ++ seq_printf(seq, "Port0 Good Pkt Cnt: RX=%08u Tx=%08u (Bad Pkt Cnt: Rx=%08u Tx=%08u)\n", sysRegRead(RALINK_ETH_SW_BASE+0xE8)&0xFFFF,sysRegRead(RALINK_ETH_SW_BASE+0x150)&0xFFFF,sysRegRead(RALINK_ETH_SW_BASE+0xE8)>>16, sysRegRead(RALINK_ETH_SW_BASE+0x150)>>16); ++ ++ seq_printf(seq, "Port1 Good Pkt Cnt: RX=%08u Tx=%08u (Bad Pkt Cnt: Rx=%08u Tx=%08u)\n", sysRegRead(RALINK_ETH_SW_BASE+0xEC)&0xFFFF,sysRegRead(RALINK_ETH_SW_BASE+0x154)&0xFFFF,sysRegRead(RALINK_ETH_SW_BASE+0xEC)>>16, sysRegRead(RALINK_ETH_SW_BASE+0x154)>>16); ++ ++ seq_printf(seq, "Port2 Good Pkt Cnt: RX=%08u Tx=%08u (Bad Pkt Cnt: Rx=%08u Tx=%08u)\n", sysRegRead(RALINK_ETH_SW_BASE+0xF0)&0xFFFF,sysRegRead(RALINK_ETH_SW_BASE+0x158)&0xFFFF,sysRegRead(RALINK_ETH_SW_BASE+0xF0)>>16, sysRegRead(RALINK_ETH_SW_BASE+0x158)>>16); ++ ++ seq_printf(seq, "Port3 Good Pkt Cnt: RX=%08u Tx=%08u (Bad Pkt Cnt: Rx=%08u Tx=%08u)\n", sysRegRead(RALINK_ETH_SW_BASE+0xF4)&0xFFFF,sysRegRead(RALINK_ETH_SW_BASE+0x15C)&0xFFFF,sysRegRead(RALINK_ETH_SW_BASE+0xF4)>>16, sysRegRead(RALINK_ETH_SW_BASE+0x15c)>>16); ++ ++ seq_printf(seq, "Port4 Good Pkt Cnt: RX=%08u Tx=%08u (Bad Pkt Cnt: Rx=%08u Tx=%08u)\n", sysRegRead(RALINK_ETH_SW_BASE+0xF8)&0xFFFF,sysRegRead(RALINK_ETH_SW_BASE+0x160)&0xFFFF,sysRegRead(RALINK_ETH_SW_BASE+0xF8)>>16, sysRegRead(RALINK_ETH_SW_BASE+0x160)>>16); ++ ++ seq_printf(seq, "Port5 Good Pkt Cnt: RX=%08u Tx=%08u (Bad Pkt Cnt: Rx=%08u Tx=%08u)\n", sysRegRead(RALINK_ETH_SW_BASE+0xFC)&0xFFFF,sysRegRead(RALINK_ETH_SW_BASE+0x164)&0xFFFF,sysRegRead(RALINK_ETH_SW_BASE+0xFC)>>16, sysRegRead(RALINK_ETH_SW_BASE+0x164)>>16); ++#elif defined (CONFIG_RALINK_RT3883) ++ /* no built-in switch */ ++#elif defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++ ++#define DUMP_EACH_PORT(base) \ ++ for(i=0; i < 7;i++) { \ ++ mii_mgr_read(31, (base) + (i*0x100), &pkt_cnt); \ ++ seq_printf(seq, "%8u ", pkt_cnt); \ ++ } \ ++ seq_printf(seq, "\n"); ++ ++#if defined (CONFIG_RALINK_MT7621) /* TODO: need to update to use MT7530 compiler flag */ ++ if(sysRegRead(0xbe00000c & (1<<16)))//MCM ++#endif ++ { ++ seq_printf(seq, "===================== %8s %8s %8s %8s %8s %8s %8s\n","Port0", "Port1", "Port2", "Port3", "Port4", "Port5", "Port6"); ++ seq_printf(seq, "Tx Drop Packet :"); DUMP_EACH_PORT(0x4000); ++ seq_printf(seq, "Tx CRC Error :"); DUMP_EACH_PORT(0x4004); ++ seq_printf(seq, "Tx Unicast Packet :"); DUMP_EACH_PORT(0x4008); ++ seq_printf(seq, "Tx Multicast Packet :"); DUMP_EACH_PORT(0x400C); ++ seq_printf(seq, "Tx Broadcast Packet :"); DUMP_EACH_PORT(0x4010); ++ seq_printf(seq, "Tx Collision Event :"); DUMP_EACH_PORT(0x4014); ++ seq_printf(seq, "Tx Pause Packet :"); DUMP_EACH_PORT(0x402C); ++ seq_printf(seq, "Rx Drop Packet :"); DUMP_EACH_PORT(0x4060); ++ seq_printf(seq, "Rx Filtering Packet :"); DUMP_EACH_PORT(0x4064); ++ seq_printf(seq, "Rx Unicast Packet :"); DUMP_EACH_PORT(0x4068); ++ seq_printf(seq, "Rx Multicast Packet :"); DUMP_EACH_PORT(0x406C); ++ seq_printf(seq, "Rx Broadcast Packet :"); DUMP_EACH_PORT(0x4070); ++ seq_printf(seq, "Rx Alignment Error :"); DUMP_EACH_PORT(0x4074); ++ seq_printf(seq, "Rx CRC Error :"); DUMP_EACH_PORT(0x4078); ++ seq_printf(seq, "Rx Undersize Error :"); DUMP_EACH_PORT(0x407C); ++ seq_printf(seq, "Rx Fragment Error :"); DUMP_EACH_PORT(0x4080); ++ seq_printf(seq, "Rx Oversize Error :"); DUMP_EACH_PORT(0x4084); ++ seq_printf(seq, "Rx Jabber Error :"); DUMP_EACH_PORT(0x4088); ++ seq_printf(seq, "Rx Pause Packet :"); DUMP_EACH_PORT(0x408C); ++ mii_mgr_write(31, 0x4fe0, 0xf0); ++ mii_mgr_write(31, 0x4fe0, 0x800000f0); ++ } ++#if defined (CONFIG_RALINK_MT7621) /* TODO: need to update to use MT7530 compiler flag */ ++ else { ++ seq_printf(seq, "no built-in switch\n"); ++ } ++#endif ++ ++#else /* RT305x, RT3352 */ ++ seq_printf(seq, "Port0: Good Pkt Cnt: RX=%08u (Bad Pkt Cnt: Rx=%08u)\n", sysRegRead(RALINK_ETH_SW_BASE+0xE8)&0xFFFF,sysRegRead(RALINK_ETH_SW_BASE+0xE8)>>16); ++ seq_printf(seq, "Port1: Good Pkt Cnt: RX=%08u (Bad Pkt Cnt: Rx=%08u)\n", sysRegRead(RALINK_ETH_SW_BASE+0xEC)&0xFFFF,sysRegRead(RALINK_ETH_SW_BASE+0xEC)>>16); ++ seq_printf(seq, "Port2: Good Pkt Cnt: RX=%08u (Bad Pkt Cnt: Rx=%08u)\n", sysRegRead(RALINK_ETH_SW_BASE+0xF0)&0xFFFF,sysRegRead(RALINK_ETH_SW_BASE+0xF0)>>16); ++ seq_printf(seq, "Port3: Good Pkt Cnt: RX=%08u (Bad Pkt Cnt: Rx=%08u)\n", sysRegRead(RALINK_ETH_SW_BASE+0xF4)&0xFFFF,sysRegRead(RALINK_ETH_SW_BASE+0xF4)>>16); ++ seq_printf(seq, "Port4: Good Pkt Cnt: RX=%08u (Bad Pkt Cnt: Rx=%08u)\n", sysRegRead(RALINK_ETH_SW_BASE+0xF8)&0xFFFF,sysRegRead(RALINK_ETH_SW_BASE+0xF8)>>16); ++ seq_printf(seq, "Port5: Good Pkt Cnt: RX=%08u (Bad Pkt Cnt: Rx=%08u)\n", sysRegRead(RALINK_ETH_SW_BASE+0xFC)&0xFFFF,sysRegRead(RALINK_ETH_SW_BASE+0xFC)>>16); ++#endif ++ seq_printf(seq, "\n"); ++ ++ return 0; ++} ++ ++static int switch_count_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, EswCntRead, NULL); ++} ++ ++static const struct file_operations switch_count_fops = { ++ .owner = THIS_MODULE, ++ .open = switch_count_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release ++}; ++ ++#if defined (CONFIG_ETHTOOL) /*&& defined (CONFIG_RAETH_ROUTER)*/ ++/* ++ * proc write procedure ++ */ ++static ssize_t change_phyid(struct file *file, const char __user *buffer, ++ size_t count, loff_t *data) ++{ ++ char buf[32]; ++ struct net_device *cur_dev_p; ++ END_DEVICE *ei_local; ++ char if_name[64]; ++ unsigned int phy_id; ++ ++ if (count > 32) ++ count = 32; ++ memset(buf, 0, 32); ++ if (copy_from_user(buf, buffer, count)) ++ return -EFAULT; ++ ++ /* determine interface name */ ++ strcpy(if_name, DEV_NAME); /* "eth2" by default */ ++ if(isalpha(buf[0])) ++ sscanf(buf, "%s %d", if_name, &phy_id); ++ else ++ phy_id = simple_strtol(buf, 0, 10); ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ cur_dev_p = dev_get_by_name(&init_net, DEV_NAME); ++#else ++ cur_dev_p = dev_get_by_name(DEV_NAME); ++#endif ++ if (cur_dev_p == NULL) ++ return -EFAULT; ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ ei_local = netdev_priv(cur_dev_p); ++#else ++ ei_local = cur_dev_p->priv; ++#endif ++ ei_local->mii_info.phy_id = (unsigned char)phy_id; ++ return count; ++} ++ ++#if defined(CONFIG_PSEUDO_SUPPORT) ++static ssize_t change_gmac2_phyid(struct file *file, const char __user *buffer, ++ size_t count, loff_t *data) ++{ ++ char buf[32]; ++ struct net_device *cur_dev_p; ++ PSEUDO_ADAPTER *pPseudoAd; ++ char if_name[64]; ++ unsigned int phy_id; ++ ++ if (count > 32) ++ count = 32; ++ memset(buf, 0, 32); ++ if (copy_from_user(buf, buffer, count)) ++ return -EFAULT; ++ /* determine interface name */ ++ strcpy(if_name, DEV2_NAME); /* "eth3" by default */ ++ if(isalpha(buf[0])) ++ sscanf(buf, "%s %d", if_name, &phy_id); ++ else ++ phy_id = simple_strtol(buf, 0, 10); ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ cur_dev_p = dev_get_by_name(&init_net, DEV2_NAME); ++#else ++ cur_dev_p = dev_get_by_name(DEV2_NAMEj); ++#endif ++ if (cur_dev_p == NULL) ++ return -EFAULT; ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ pPseudoAd = netdev_priv(cur_dev_p); ++#else ++ pPseudoAd = cur_dev_p->priv; ++#endif ++ pPseudoAd->mii_info.phy_id = (unsigned char)phy_id; ++ return count; ++} ++ ++static struct file_operations gmac2_fops = { ++ .owner = THIS_MODULE, ++ .write = change_gmac2_phyid ++}; ++#endif ++#endif ++ ++static int gmac_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, RegReadMain, NULL); ++} ++ ++static struct file_operations gmac_fops = { ++ .owner = THIS_MODULE, ++ .open = gmac_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++#if defined (CONFIG_ETHTOOL) ++ .write = change_phyid, ++#endif ++ .release = single_release ++}; ++ ++#if defined (TASKLET_WORKQUEUE_SW) ++extern int init_schedule; ++extern int working_schedule; ++static int ScheduleRead(struct seq_file *seq, void *v) ++{ ++ if (init_schedule == 1) ++ seq_printf(seq, "Initialize Raeth with workqueque<%d>\n", init_schedule); ++ else ++ seq_printf(seq, "Initialize Raeth with tasklet<%d>\n", init_schedule); ++ if (working_schedule == 1) ++ seq_printf(seq, "Raeth is running at workqueque<%d>\n", working_schedule); ++ else ++ seq_printf(seq, "Raeth is running at tasklet<%d>\n", working_schedule); ++ ++ return 0; ++} ++ ++static ssize_t ScheduleWrite(struct file *file, const char __user *buffer, ++ size_t count, loff_t *data) ++{ ++ char buf[2]; ++ int old; ++ ++ if (copy_from_user(buf, buffer, count)) ++ return -EFAULT; ++ old = init_schedule; ++ init_schedule = simple_strtol(buf, 0, 10); ++ printk("Change Raeth initial schedule from <%d> to <%d>\n! Not running schedule at present !\n", ++ old, init_schedule); ++ ++ return count; ++} ++ ++static int schedule_switch_open(struct inode *inode, struct file *file) ++{ ++ return single_open(file, ScheduleRead, NULL); ++} ++ ++static const struct file_operations schedule_sw_fops = { ++ .owner = THIS_MODULE, ++ .open = schedule_switch_open, ++ .read = seq_read, ++ .write = ScheduleWrite, ++ .llseek = seq_lseek, ++ .release = single_release ++}; ++#endif ++ ++#if defined(CONFIG_RAETH_PDMA_DVT) ++static int PdmaDvtRead(struct seq_file *seq, void *v) ++{ ++ seq_printf(seq, "g_pdma_dvt_show_config = 0x%x\n", pdma_dvt_get_show_config()); ++ seq_printf(seq, "g_pdma_dvt_rx_test_config = 0x%x\n", pdma_dvt_get_rx_test_config()); ++ seq_printf(seq, "g_pdma_dvt_tx_test_config = 0x%x\n", pdma_dvt_get_tx_test_config()); ++ ++ return 0; ++} ++ ++static int PdmaDvtOpen(struct inode *inode, struct file *file) ++{ ++ return single_open(file, PdmaDvtRead, NULL); ++} ++ ++static ssize_t PdmaDvtWrite(struct file *file, const char __user *buffer, ++ size_t count, loff_t *data) ++{ ++ char buf[32]; ++ char *pBuf; ++ int len = count; ++ int x = 0,y = 0; ++ char *pToken = NULL; ++ char *pDelimiter = " \t"; ++ ++ printk("write parameter len = %d\n\r", (int)len); ++ if(len >= sizeof(buf)){ ++ printk("input handling fail!\n"); ++ len = sizeof(buf) - 1; ++ return -1; ++ } ++ ++ if(copy_from_user(buf, buffer, len)){ ++ return -EFAULT; ++ } ++ buf[len] = '\0'; ++ printk("write parameter data = %s\n\r", buf); ++ ++ pBuf = buf; ++ pToken = strsep(&pBuf, pDelimiter); ++ x = NULL != pToken ? simple_strtol(pToken, NULL, 16) : 0; ++ ++ pToken = strsep(&pBuf, "\t\n "); ++ if(pToken != NULL){ ++ y = NULL != pToken ? simple_strtol(pToken, NULL, 16) : 0; ++ printk("y = 0x%08x \n\r", y); ++ } ++ ++ if ( (sizeof(pdma_dvt_dbg_func)/sizeof(pdma_dvt_dbg_func[0]) > x) && NULL != pdma_dvt_dbg_func[x]) ++ { ++ (*pdma_dvt_dbg_func[x])(x, y); ++ } ++ else ++ { ++ printk("no handler defined for command id(0x%08x)\n\r", x); ++ } ++ ++ printk("x(0x%08x), y(0x%08x)\n", x, y); ++ ++ return len; ++} ++ ++static const struct file_operations pdma_dev_sw_fops = { ++ .owner = THIS_MODULE, ++ .open = PdmaDvtOpen, ++ .read = seq_read, ++ .write = PdmaDvtWrite ++}; ++#endif //#if defined(CONFIG_RAETH_PDMA_DVT) ++ ++int debug_proc_init(void) ++{ ++ if (procRegDir == NULL) ++ procRegDir = proc_mkdir(PROCREG_DIR, NULL); ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ++ if ((procGmac = create_proc_entry(PROCREG_GMAC, 0, procRegDir))) ++ procGmac->proc_fops = &gmac_fops; ++ else ++#else ++ if (!(procGmac = proc_create(PROCREG_GMAC, 0, procRegDir, &gmac_fops))) ++#endif ++ printk("!! FAIL to create %s PROC !!\n", PROCREG_GMAC); ++#if defined (CONFIG_ETHTOOL) /*&& defined (CONFIG_RAETH_ROUTER)*/ ++#if defined(CONFIG_PSEUDO_SUPPORT) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ++ if ((procGmac2 = create_proc_entry(PROCREG_GMAC2, 0, procRegDir))) ++ procGmac2->proc_fops = &gmac2_fops; ++ else ++#else ++ if (!(procGmac2 = proc_create(PROCREG_GMAC2, 0, procRegDir, &gmac2_fops))) ++#endif ++ printk("!! FAIL to create %s PROC !!\n", PROCREG_GMAC2); ++#endif ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ++ if ((procSkbFree = create_proc_entry(PROCREG_SKBFREE, 0, procRegDir))) ++ procSkbFree->proc_fops = &skb_free_fops; ++ else ++#else ++ if (!(procSkbFree = proc_create(PROCREG_SKBFREE, 0, procRegDir, &skb_free_fops))) ++#endif ++ printk("!! FAIL to create %s PROC !!\n", PROCREG_SKBFREE); ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ++ if ((procTxRing = create_proc_entry(PROCREG_TXRING, 0, procRegDir))) ++ procTxRing->proc_fops = &tx_ring_fops; ++ else ++#else ++ if (!(procTxRing = proc_create(PROCREG_TXRING, 0, procRegDir, &tx_ring_fops))) ++#endif ++ printk("!! FAIL to create %s PROC !!\n", PROCREG_TXRING); ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ++ if ((procRxRing = create_proc_entry(PROCREG_RXRING, 0, procRegDir))) ++ procRxRing->proc_fops = &rx_ring_fops; ++ else ++#else ++ if (!(procRxRing = proc_create(PROCREG_RXRING, 0, procRegDir, &rx_ring_fops))) ++#endif ++ printk("!! FAIL to create %s PROC !!\n", PROCREG_RXRING); ++ ++#if defined (CONFIG_RAETH_HW_LRO) || defined (CONFIG_RAETH_MULTIPLE_RX_RING) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ++ if ((procRxRing1 = create_proc_entry(PROCREG_RXRING1, 0, procRegDir))) ++ procRxRing1->proc_fops = &rx_ring1_fops; ++ else ++#else ++ if (!(procRxRing1 = proc_create(PROCREG_RXRING1, 0, procRegDir, &rx_ring1_fops))) ++#endif ++ printk("!! FAIL to create %s PROC !!\n", PROCREG_RXRING1); ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ++ if ((procRxRing2 = create_proc_entry(PROCREG_RXRING2, 0, procRegDir))) ++ procRxRing2->proc_fops = &rx_ring2_fops; ++ else ++#else ++ if (!(procRxRing2 = proc_create(PROCREG_RXRING2, 0, procRegDir, &rx_ring2_fops))) ++#endif ++ printk("!! FAIL to create %s PROC !!\n", PROCREG_RXRING2); ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ++ if ((procRxRing3 = create_proc_entry(PROCREG_RXRING3, 0, procRegDir))) ++ procRxRing3->proc_fops = &rx_ring3_fops; ++ else ++#else ++ if (!(procRxRing3 = proc_create(PROCREG_RXRING3, 0, procRegDir, &rx_ring3_fops))) ++#endif ++ printk("!! FAIL to create %s PROC !!\n", PROCREG_RXRING3); ++#endif /* CONFIG_RAETH_HW_LRO */ ++ ++#if defined (CONFIG_MIPS) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ++ if ((procSysCP0 = create_proc_entry(PROCREG_CP0, 0, procRegDir))) ++ procSysCP0->proc_fops = &cp0_reg_fops; ++ else ++#else ++ if (!(procSysCP0 = proc_create(PROCREG_CP0, 0, procRegDir, &cp0_reg_fops))) ++#endif ++ printk("!! FAIL to create %s PROC !!\n", PROCREG_CP0); ++#endif ++ ++#if defined(CONFIG_RAETH_TSO) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ++ if ((procNumOfTxd = create_proc_entry(PROCREG_NUM_OF_TXD, 0, procRegDir))) ++ procNumOfTxd->proc_fops = &tso_txd_num_fops; ++ else ++#else ++ if (!(procNumOfTxd = proc_create(PROCREG_NUM_OF_TXD, 0, procRegDir, &tso_txd_num_fops))) ++#endif ++ printk("!! FAIL to create %s PROC !!\n", PROCREG_NUM_OF_TXD); ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ++ if ((procTsoLen = create_proc_entry(PROCREG_TSO_LEN, 0, procRegDir))) ++ procTsoLen->proc_fops = &tso_len_fops; ++ else ++#else ++ if (!(procTsoLen = proc_create(PROCREG_TSO_LEN, 0, procRegDir, &tso_len_fops))) ++#endif ++ printk("!! FAIL to create %s PROC !!\n", PROCREG_TSO_LEN); ++#endif ++ ++#if defined(CONFIG_RAETH_LRO) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ++ if ((procLroStats = create_proc_entry(PROCREG_LRO_STATS, 0, procRegDir))) ++ procLroStats->proc_fops = &lro_stats_fops; ++ else ++#else ++ if (!(procLroStats = proc_create(PROCREG_LRO_STATS, 0, procRegDir, &lro_stats_fops))) ++#endif ++ printk("!! FAIL to create %s PROC !!\n", PROCREG_LRO_STATS); ++#endif ++ ++#if defined(CONFIG_RAETH_HW_LRO) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ++ if ((procHwLroStats = create_proc_entry(PROCREG_HW_LRO_STATS, 0, procRegDir))) ++ procHwLroStats->proc_fops = &hw_lro_stats_fops; ++ else ++#else ++ if (!(procHwLroStats = proc_create(PROCREG_HW_LRO_STATS, 0, procRegDir, &hw_lro_stats_fops))) ++#endif ++ printk("!! FAIL to create %s PROC !!\n", PROCREG_HW_LRO_STATS); ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ++ if ((procHwLroAutoTlb = create_proc_entry(PROCREG_HW_LRO_AUTO_TLB, 0, procRegDir))) ++ procHwLroAutoTlb->proc_fops = &hw_lro_auto_tlb_fops; ++ else ++#else ++ if (!(procHwLroAutoTlb = proc_create(PROCREG_HW_LRO_AUTO_TLB, 0, procRegDir, &hw_lro_auto_tlb_fops))) ++#endif ++ printk("!! FAIL to create %s PROC !!\n", PROCREG_HW_LRO_AUTO_TLB); ++#endif /* CONFIG_RAETH_HW_LRO */ ++ ++#if defined(CONFIG_RAETH_QOS) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ++ if ((procRaQOS = create_proc_entry(PROCREG_RAQOS, 0, procRegDir))) ++ procRaQOS->proc_fops = &raeth_qos_fops; ++ else ++#else ++ if (!(procRaQOS = proc_create(PROCREG_RAQOS, 0, procRegDir, &raeth_qos_fops))) ++#endif ++ printk("!! FAIL to create %s PROC !!\n", PROCREG_RAQOS); ++#endif ++ ++#if defined(CONFIG_USER_SNMPD) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ++ if ((procRaSnmp = create_proc_entry(PROCREG_SNMP, S_IRUGO, procRegDir))) ++ procRaSnmp->proc_fops = &ra_snmp_seq_fops; ++ else ++#else ++ if (!(procRaSnmp = proc_create(PROCREG_SNMP, S_IRUGO, procRegDir, &ra_snmp_seq_fops))) ++#endif ++ printk("!! FAIL to create %s PROC !!\n", PROCREG_SNMP); ++#endif ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ++ if ((procEswCnt = create_proc_entry(PROCREG_ESW_CNT, 0, procRegDir))) ++ procEswCnt->proc_fops = &switch_count_fops; ++ else ++#else ++ if (!(procEswCnt = proc_create(PROCREG_ESW_CNT, 0, procRegDir, &switch_count_fops))) ++#endif ++ printk("!! FAIL to create %s PROC !!\n", PROCREG_ESW_CNT); ++ ++#if defined (TASKLET_WORKQUEUE_SW) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ++ if ((procSCHE = create_proc_entry(PROCREG_SCHE, 0, procRegDir))) ++ procSCHE->proc_fops = &schedule_sw_fops; ++ else ++#else ++ if (!(procSCHE = proc_create(PROCREG_SCHE, 0, procRegDir, &schedule_sw_fops))) ++#endif ++ printk("!! FAIL to create %s PROC !!\n", PROCREG_SCHE); ++#endif ++ ++#if defined(CONFIG_RAETH_PDMA_DVT) ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36) ++ if ((procPdmaDvt = create_proc_entry(PROCREG_PDMA_DVT, 0, procRegDir))) ++ procPdmaDvt->proc_fops = &pdma_dev_sw_fops; ++ else ++#else ++ if (!(procPdmaDvt = proc_create(PROCREG_PDMA_DVT, 0, procRegDir, &pdma_dev_sw_fops ))) ++#endif ++ printk("!! FAIL to create %s PROC !!\n", PROCREG_PDMA_DVT); ++#endif //#if defined(CONFIG_RAETH_PDMA_DVT) ++ ++ printk(KERN_ALERT "PROC INIT OK!\n"); ++ return 0; ++} ++ ++void debug_proc_exit(void) ++{ ++ ++ if (procSysCP0) ++ remove_proc_entry(PROCREG_CP0, procRegDir); ++ ++ if (procGmac) ++ remove_proc_entry(PROCREG_GMAC, procRegDir); ++#if defined(CONFIG_PSEUDO_SUPPORT) && defined(CONFIG_ETHTOOL) ++ if (procGmac) ++ remove_proc_entry(PROCREG_GMAC, procRegDir); ++#endif ++ if (procSkbFree) ++ remove_proc_entry(PROCREG_SKBFREE, procRegDir); ++ ++ if (procTxRing) ++ remove_proc_entry(PROCREG_TXRING, procRegDir); ++ ++ if (procRxRing) ++ remove_proc_entry(PROCREG_RXRING, procRegDir); ++ ++#if defined(CONFIG_RAETH_TSO) ++ if (procNumOfTxd) ++ remove_proc_entry(PROCREG_NUM_OF_TXD, procRegDir); ++ ++ if (procTsoLen) ++ remove_proc_entry(PROCREG_TSO_LEN, procRegDir); ++#endif ++ ++#if defined(CONFIG_RAETH_LRO) ++ if (procLroStats) ++ remove_proc_entry(PROCREG_LRO_STATS, procRegDir); ++#endif ++ ++#if defined(CONFIG_RAETH_QOS) ++ if (procRaQOS) ++ remove_proc_entry(PROCREG_RAQOS, procRegDir); ++ if (procRaFeIntr) ++ remove_proc_entry(PROCREG_RXDONE_INTR, procRegDir); ++ if (procRaEswIntr) ++ remove_proc_entry(PROCREG_ESW_INTR, procRegDir); ++#endif ++ ++#if defined(CONFIG_USER_SNMPD) ++ if (procRaSnmp) ++ remove_proc_entry(PROCREG_SNMP, procRegDir); ++#endif ++ ++ if (procEswCnt) ++ remove_proc_entry(PROCREG_ESW_CNT, procRegDir); ++ ++ //if (procRegDir) ++ //remove_proc_entry(PROCREG_DIR, 0); ++ ++ printk(KERN_ALERT "proc exit\n"); ++} ++EXPORT_SYMBOL(procRegDir); +diff --git a/drivers/net/ethernet/raeth/ra_mac.h b/drivers/net/ethernet/raeth/ra_mac.h +new file mode 100644 +index 0000000..66b32d3 +--- /dev/null ++++ b/drivers/net/ethernet/raeth/ra_mac.h +@@ -0,0 +1,57 @@ ++#ifndef RA_MAC_H ++#define RA_MAC_H ++ ++void ra2880stop(END_DEVICE *ei_local); ++void ra2880MacAddressSet(unsigned char p[6]); ++void ra2880Mac2AddressSet(unsigned char p[6]); ++void ethtool_init(struct net_device *dev); ++ ++void ra2880EnableInterrupt(void); ++ ++void dump_qos(void); ++void dump_reg(struct seq_file *s); ++void dump_cp0(void); ++ ++int debug_proc_init(void); ++void debug_proc_exit(void); ++ ++#if defined (CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A) || \ ++ defined (CONFIG_RALINK_MT7620) || defined(CONFIG_RALINK_MT7621) ++void enable_auto_negotiate(int unused); ++#else ++void enable_auto_negotiate(int ge); ++#endif ++ ++void rt2880_gmac_hard_reset(void); ++ ++int TsoLenUpdate(int tso_len); ++int NumOfTxdUpdate(int num_of_txd); ++ ++#ifdef CONFIG_RAETH_LRO ++int LroStatsUpdate(struct net_lro_mgr *lro_mgr, bool all_flushed); ++#endif ++#ifdef CONFIG_RAETH_HW_LRO ++int HwLroStatsUpdate(unsigned int ring_num, unsigned int agg_cnt, unsigned int agg_size); ++#if defined(CONFIG_RAETH_HW_LRO_REASON_DBG) ++#define HW_LRO_AGG_FLUSH (1) ++#define HW_LRO_AGE_FLUSH (2) ++#define HW_LRO_NOT_IN_SEQ_FLUSH (3) ++#define HW_LRO_TIMESTAMP_FLUSH (4) ++#define HW_LRO_NON_RULE_FLUSH (5) ++int HwLroFlushStatsUpdate(unsigned int ring_num, unsigned int flush_reason); ++#endif /* CONFIG_RAETH_HW_LRO_REASON_DBG */ ++typedef int (*HWLRO_DBG_FUNC)(int par1, int par2); ++int hwlro_agg_cnt_ctrl(int par1, int par2); ++int hwlro_agg_time_ctrl(int par1, int par2); ++int hwlro_age_time_ctrl(int par1, int par2); ++int hwlro_pkt_int_alpha_ctrl(int par1, int par2); ++int hwlro_threshold_ctrl(int par1, int par2); ++int hwlro_fix_setting_switch_ctrl(int par1, int par2); ++#endif /* CONFIG_RAETH_HW_LRO */ ++int getnext(const char *src, int separator, char *dest); ++int str_to_ip(unsigned int *ip, const char *str); ++ ++#if defined(CONFIG_RAETH_PDMA_DVT) ++typedef int (*PDMA_DBG_FUNC)(int par1, int par2); ++#endif //#if defined(CONFIG_RAETH_PDMA_DVT) ++#endif +diff --git a/drivers/net/ethernet/raeth/ra_netlink.c b/drivers/net/ethernet/raeth/ra_netlink.c +new file mode 100644 +index 0000000..f7c3650 +--- /dev/null ++++ b/drivers/net/ethernet/raeth/ra_netlink.c +@@ -0,0 +1,142 @@ ++// for netlink header ++#include <asm/types.h> ++#include <net/sock.h> ++#include <linux/socket.h> ++#include <linux/netlink.h> ++#include <linux/skbuff.h> ++#include <linux/net.h> ++#include <linux/version.h> ++ ++#include "csr_netlink.h" ++#include "ra2882ethreg.h" ++#include "ra_netlink.h" ++ ++static struct sock *csr_msg_socket = NULL; // synchronize socket for netlink use ++unsigned int flags; ++ ++void rt2880_csr_receiver(struct sock *sk, int len) ++{ ++ struct sk_buff *skb; ++ int err; ++ struct nlmsghdr *nlh; ++ unsigned int reg_value = 0; ++ CSR_MSG *csrmsg; ++ RAETH_PRINT("csr netlink receiver!\n"); ++ skb = skb_recv_datagram(sk, 0, 1, &err); ++ ++ RAETH_PRINT("error no : %d\n", err); ++ ++ if (skb == NULL) { ++ printk("rt2880_csr_receiver(): No data received, error!\n"); ++ return; ++ } ++ ++ nlh = (struct nlmsghdr*)skb->data; ++ ++ csrmsg = NLMSG_DATA(nlh); ++ ++ if (csrmsg->enable == CSR_READ ) { ++ reg_value = sysRegRead(csrmsg->address); ++#if 0 ++ printk("raeth -- 0x%08x: 0x%08x\n", csrmsg->address, reg_value); ++#endif ++ } else if ( csrmsg->enable == CSR_WRITE ) { ++ sysRegWrite(csrmsg->address, csrmsg->default_value); ++ reg_value = sysRegRead(csrmsg->address); ++ } else if ( csrmsg->enable == CSR_TEST ) { ++ reg_value = sysRegRead(csrmsg->address); ++ printk("0x%08x: 0x%08x\n", (unsigned int)csrmsg->address, reg_value); ++ } ++ else ++ printk("drv: Command format error!\n"); ++ ++ csrmsg->default_value = reg_value; ++ ++ RAETH_PRINT("drv: rt2880_csr_msgsend() - msg to send!\n"); ++ ++ err = rt2880_csr_msgsend(csrmsg); ++ ++ if ( err == -2 ) ++ printk("drv: msg send error!\n"); ++ ++ skb_free_datagram(sk, skb); ++} ++ ++int rt2880_csr_msgsend(CSR_MSG* csrmsg) ++{ ++ struct sk_buff *skb; ++ struct nlmsghdr *nlh = NULL; ++ size_t size = 0; ++ struct sock *send_syncnl = csr_msg_socket; ++ ++ CSR_MSG* csr_reg; ++ if (send_syncnl == NULL) { ++ printk("drv: netlink_kernel_create() failed!\n"); ++ return -1; ++ } ++ ++ size = NLMSG_SPACE(sizeof(CSR_MSG)); ++ skb = alloc_skb(size, GFP_ATOMIC); ++ ++ if(!skb) ++ { ++ printk("rt2880_csr_msgsend() : error! msg structure not available\n"); ++ return -1; ++ } ++ ++ nlh = NLMSG_PUT(skb, 0, 0, RALINK_CSR_GROUP, size - sizeof(struct nlmsghdr)); ++ ++ if (!nlh) ++ { ++ printk("rt2880_csr_msgsend() : error! nlh structure not available\n"); ++ return -1; ++ } ++ ++ csr_reg = NLMSG_DATA(nlh); ++ if (!csr_reg) ++ { ++ printk("rt2880_csr_msgsend() : error! nlh structure not available\n"); ++ return -1; ++ } ++ ++ csr_reg->address = csrmsg->address; ++ csr_reg->default_value = csrmsg->default_value; ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) ++ NETLINK_CB(skb).dst_group = RALINK_CSR_GROUP; ++#else ++ NETLINK_CB(skb).dst_groups = RALINK_CSR_GROUP; ++#endif ++ netlink_broadcast(send_syncnl, skb, 0, RALINK_CSR_GROUP, GFP_ATOMIC); ++ return 0; ++ ++nlmsg_failure: ++ return -2; ++} ++ ++int csr_netlink_init() ++{ ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) ++ csr_msg_socket = netlink_kernel_create(NETLINK_CSR, RALINK_CSR_GROUP, rt2880_csr_receiver, THIS_MODULE); ++#else ++ csr_msg_socket = netlink_kernel_create(NETLINK_CSR, rt2880_csr_receiver); ++#endif ++ ++ if ( csr_msg_socket == NULL ) ++ printk("unable to create netlink socket!\n"); ++ else ++ printk("Netlink init ok!\n"); ++ return 0; ++} ++ ++void csr_netlink_end() ++{ ++ if (csr_msg_socket != NULL){ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) ++ sock_release(csr_msg_socket->sk_socket); ++#else ++ sock_release(csr_msg_socket->socket); ++#endif ++ printk("Netlink end...\n"); ++ } ++} +diff --git a/drivers/net/ethernet/raeth/ra_netlink.h b/drivers/net/ethernet/raeth/ra_netlink.h +new file mode 100644 +index 0000000..19ca71f +--- /dev/null ++++ b/drivers/net/ethernet/raeth/ra_netlink.h +@@ -0,0 +1,10 @@ ++#ifndef RA_NETLINK ++#define RA_NETLINK ++ ++#include "csr_netlink.h" ++int rt2880_csr_msgsend(CSR_MSG* csrmsg); ++void rt2880_csr_receiver(struct sock *sk, int len); ++int csr_netlink_init(void); ++void csr_netlink_end(void); ++ ++#endif +diff --git a/drivers/net/ethernet/raeth/ra_qos.c b/drivers/net/ethernet/raeth/ra_qos.c +new file mode 100644 +index 0000000..0a7d9c5 +--- /dev/null ++++ b/drivers/net/ethernet/raeth/ra_qos.c +@@ -0,0 +1,655 @@ ++#include <asm/io.h> ++#include <linux/pci.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/net.h> ++#include <linux/in.h> ++#include "ra_qos.h" ++#include "raether.h" ++#include "ra2882ethreg.h" ++ ++#include <asm/types.h> ++#include <net/sock.h> ++#include <linux/socket.h> ++#include <linux/skbuff.h> ++#include <linux/net.h> ++#include <linux/if_vlan.h> ++#include <linux/ip.h> ++ ++ ++#if defined (CONFIG_RA_HW_NAT) || defined (CONFIG_RA_HW_NAT_MODULE) ++#include "../../../net/nat/hw_nat/ra_nat.h" ++#endif ++ ++#define CONTI_TX_SEND_MAX_SIZE 1440 ++ ++/* ++ * set tx queue # to descriptor ++ */ ++void rt3052_tx_queue_init(unsigned long data) ++{ ++ /* define qos p */ ++ ++} ++ ++void rt3052_pse_port0_fc_clear(unsigned long data) ++{ ++ /* clear FE_INT_STATUS.PSE_P0_FC */ ++ ++} ++ ++inline int get_tx_ctx_idx(unsigned int ring_no, unsigned long *idx) ++{ ++ switch (ring_no) { ++ case RING0: ++ *idx = *(unsigned long*)TX_CTX_IDX0; ++ break; ++ case RING1: ++ *idx = *(unsigned long*)TX_CTX_IDX1; ++ break; ++ case RING2: ++ *idx = *(unsigned long*)TX_CTX_IDX2; ++ break; ++ case RING3: ++ *idx = *(unsigned long*)TX_CTX_IDX3; ++ break; ++ default: ++ printk("set_tx_ctx_idex error\n"); ++ return -1; ++ }; ++ return 0; ++} ++ ++inline int set_tx_ctx_idx(unsigned int ring_no, unsigned int idx) ++{ ++ switch (ring_no ) { ++ case RING0: ++ *(unsigned long*)TX_CTX_IDX0 = cpu_to_le32((u32)idx); ++ break; ++ case RING1: ++ *(unsigned long*)TX_CTX_IDX1 = cpu_to_le32((u32)idx); ++ break; ++ case RING2: ++ *(unsigned long*)TX_CTX_IDX2 = cpu_to_le32((u32)idx); ++ break; ++ case RING3: ++ *(unsigned long*)TX_CTX_IDX3 = cpu_to_le32((u32)idx); ++ break; ++ default: ++ printk("set_tx_ctx_idex error\n"); ++ return -1; ++ }; ++ ++ return 1; ++} ++ ++void get_tx_desc_and_dtx_idx(END_DEVICE* ei_local, int ring_no, unsigned long *tx_dtx_idx, struct PDMA_txdesc **tx_desc) ++{ ++ switch (ring_no) { ++ case RING0: ++ *tx_desc = ei_local->tx_ring0; ++ *tx_dtx_idx = *(unsigned long*)TX_DTX_IDX0; ++ break; ++ case RING1: ++ *tx_desc = ei_local->tx_ring1; ++ *tx_dtx_idx = *(unsigned long*)TX_DTX_IDX1; ++ break; ++ case RING2: ++ *tx_desc = ei_local->tx_ring2; ++ *tx_dtx_idx = *(unsigned long*)TX_DTX_IDX2; ++ break; ++ case RING3: ++ *tx_desc = ei_local->tx_ring3; ++ *tx_dtx_idx = *(unsigned long*)TX_DTX_IDX3; ++ break; ++ default: ++ printk("ring_no input error... %d\n", ring_no); ++ }; ++} ++ ++int fe_qos_packet_send(struct net_device *dev, struct sk_buff* skb, unsigned int ring_no, unsigned int qn, unsigned pn) ++{ ++ END_DEVICE* ei_local = netdev_priv(dev); ++ struct PDMA_txdesc* tx_desc; ++ unsigned int tx_cpu_owner_idx, tx_dtx_idx; ++ ++ unsigned int length=skb->len; ++ int ret; ++ unsigned long flags; ++ ++ //printk("fe_qos_packet_send: ring_no=%d qn=%d pn=%d\n", ring_no, qn, pn); ++ ++ switch ( ring_no ) { ++ case 0: ++ tx_desc = ei_local->tx_ring0; ++ tx_cpu_owner_idx = *(unsigned long*)TX_CTX_IDX0; ++ tx_dtx_idx = *(unsigned long*)TX_DTX_IDX0; ++ break; ++ case 1: ++ tx_desc = ei_local->tx_ring1; ++ tx_cpu_owner_idx = *(unsigned long*)TX_CTX_IDX1; ++ tx_dtx_idx = *(unsigned long*)TX_DTX_IDX1; ++ break; ++ case 2: ++ tx_desc = ei_local->tx_ring2; ++ tx_cpu_owner_idx = *(unsigned long*)TX_CTX_IDX2; ++ tx_dtx_idx = *(unsigned long*)TX_DTX_IDX2; ++ break; ++ case 3: ++ tx_desc = ei_local->tx_ring3; ++ tx_cpu_owner_idx = *(unsigned long*)TX_CTX_IDX3; ++ tx_dtx_idx = *(unsigned long*)TX_DTX_IDX3; ++ break; ++ default: ++ printk("ring_no input error... %d\n", ring_no); ++ return -1; ++ }; ++ ++ //printk("tx_cpu_owner_idx=%d tx_dtx_idx=%d\n", tx_cpu_owner_idx, tx_dtx_idx); ++ ++ if(tx_desc == NULL) { ++ printk("%s : txdesc is NULL\n", dev->name); ++ return -1; ++ } ++ ++ tx_desc[tx_cpu_owner_idx].txd_info1.SDP0 = virt_to_phys(skb->data); ++ tx_desc[tx_cpu_owner_idx].txd_info2.SDL0 = length; ++ tx_desc[tx_cpu_owner_idx].txd_info2.DDONE_bit = 0; ++ tx_desc[tx_cpu_owner_idx].txd_info4.PN = pn; ++ tx_desc[tx_cpu_owner_idx].txd_info4.QN = qn; ++ ++#ifdef CONFIG_RAETH_CHECKSUM_OFFLOAD ++ ei_local->tx_ring0[tx_cpu_owner_idx].txd_info4.TCO = 1; ++ ei_local->tx_ring0[tx_cpu_owner_idx].txd_info4.UCO = 1; ++ ei_local->tx_ring0[tx_cpu_owner_idx].txd_info4.ICO = 1; ++#endif ++ ++#if defined (CONFIG_RA_HW_NAT) || defined (CONFIG_RA_HW_NAT_MODULE) ++ if(FOE_MAGIC_TAG(skb) == FOE_MAGIC_PPE) { ++ tx_desc[tx_cpu_owner_idx].txd_info4.PN = 6; /* PPE */ ++ } else { ++ tx_desc[tx_cpu_owner_idx].txd_info4.PN = pn; ++ } ++ ++#endif ++ ++ spin_lock_irqsave(&ei_local->page_lock, flags); ++ ei_local->skb_free[ring_no][tx_cpu_owner_idx] = skb; ++ tx_cpu_owner_idx = (tx_cpu_owner_idx +1) % NUM_TX_DESC; ++ ret = set_tx_ctx_idx(ring_no, tx_cpu_owner_idx); ++ spin_unlock_irqrestore(&ei_local->page_lock, flags); ++ ++ ei_local->stat.tx_packets++; ++ ei_local->stat.tx_bytes += length; ++ ++#ifdef CONFIG_RAETH_NAPI ++ switch ( ring_no ) { ++ case 0: ++ if ( ei_local->tx0_full == 1) { ++ ei_local->tx0_full = 0; ++ netif_wake_queue(dev); ++ } ++ break; ++ case 1: ++ if ( ei_local->tx1_full == 1) { ++ ei_local->tx1_full = 0; ++ netif_wake_queue(dev); ++ } ++ break; ++ case 2: ++ if ( ei_local->tx2_full == 1) { ++ ei_local->tx2_full = 0; ++ netif_wake_queue(dev); ++ } ++ break; ++ case 3: ++ if ( ei_local->tx3_full == 1) { ++ ei_local->tx3_full = 0; ++ netif_wake_queue(dev); ++ } ++ break; ++ default : ++ printk("ring_no input error %d\n", ring_no); ++ }; ++#endif ++ return length; ++} ++ ++int fe_tx_desc_init(struct net_device *dev, unsigned int ring_no, unsigned int qn, unsigned int pn) ++{ ++ END_DEVICE* ei_local = netdev_priv(dev); ++ struct PDMA_txdesc *tx_desc; ++ unsigned int tx_cpu_owner_idx = 0; ++ int i; ++ unsigned int phy_tx_ring; ++ ++ // sanity check ++ if ( ring_no > 3 ){ ++ printk("%s : ring_no - %d, please under 4...\n", dev->name, ring_no); ++ return 0; ++ } ++ ++ if ( pn > 2 ){ ++ printk("%s : pn - %d, please under 2...\n", dev->name, pn); ++ return 0; ++ } ++ ++ tx_desc = pci_alloc_consistent(NULL, NUM_TX_DESC*sizeof(struct PDMA_txdesc), &phy_tx_ring); ++ ei_local->tx_cpu_owner_idx0 = tx_cpu_owner_idx; ++ ++ switch (ring_no) { ++ case 0: ++ ei_local->tx_ring0 = tx_desc; ++ ei_local->phy_tx_ring0 = phy_tx_ring; ++ break; ++ case 1: ++ ei_local->phy_tx_ring1 = phy_tx_ring; ++ ei_local->tx_ring1 = tx_desc; ++ break; ++ case 2: ++ ei_local->phy_tx_ring2 = phy_tx_ring; ++ ei_local->tx_ring2 = tx_desc; ++ break; ++ case 3: ++ ei_local->phy_tx_ring3 = phy_tx_ring; ++ ei_local->tx_ring3 = tx_desc; ++ break; ++ default: ++ printk("ring_no input error! %d\n", ring_no); ++ pci_free_consistent(NULL, NUM_TX_DESC*sizeof(struct PDMA_txdesc), tx_desc, phy_tx_ring); ++ return 0; ++ }; ++ ++ if ( tx_desc == NULL) ++ { ++ printk("tx desc allocation failed!\n"); ++ return 0; ++ } ++ ++ for( i = 0; i < NUM_TX_DESC; i++) { ++ memset( &tx_desc[i], 0, sizeof(struct PDMA_txdesc)); ++ tx_desc[i].txd_info2.LS0_bit = 1; ++ tx_desc[i].txd_info2.DDONE_bit = 1; ++ tx_desc[i].txd_info4.PN = pn; ++ tx_desc[i].txd_info4.QN = qn; ++ } ++ ++ switch ( ring_no ) { ++ case 0 : ++ *(unsigned long*)TX_BASE_PTR0 = phys_to_bus((u32) phy_tx_ring); ++ *(unsigned long*)TX_MAX_CNT0 = cpu_to_le32((u32)NUM_TX_DESC); ++ *(unsigned long*)TX_CTX_IDX0 = cpu_to_le32((u32) tx_cpu_owner_idx); ++ sysRegWrite(PDMA_RST_CFG, PST_DTX_IDX0); ++ break; ++ case 1 : ++ *(unsigned long*)TX_BASE_PTR1 = phys_to_bus((u32) phy_tx_ring); ++ *(unsigned long*)TX_MAX_CNT1 = cpu_to_le32((u32)NUM_TX_DESC); ++ *(unsigned long*)TX_CTX_IDX1 = cpu_to_le32((u32) tx_cpu_owner_idx); ++ sysRegWrite(PDMA_RST_CFG, PST_DTX_IDX1); ++ break; ++ case 2 : ++ *(unsigned long*)TX_BASE_PTR2 = phys_to_bus((u32) phy_tx_ring); ++ *(unsigned long*)TX_MAX_CNT2 = cpu_to_le32((u32)NUM_TX_DESC); ++ *(unsigned long*)TX_CTX_IDX2 = cpu_to_le32((u32) tx_cpu_owner_idx); ++ sysRegWrite(PDMA_RST_CFG, PST_DTX_IDX2); ++ break; ++ case 3 : ++ *(unsigned long*)TX_BASE_PTR3 = phys_to_bus((u32) phy_tx_ring); ++ *(unsigned long*)TX_MAX_CNT3 = cpu_to_le32((u32)NUM_TX_DESC); ++ *(unsigned long*)TX_CTX_IDX3 = cpu_to_le32((u32) tx_cpu_owner_idx); ++ sysRegWrite(PDMA_RST_CFG, PST_DTX_IDX3); ++ break; ++ default : ++ printk("tx descriptor init failed %d\n", ring_no); ++ return 0; ++ }; ++ return 1; ++} ++ ++/* ++ DSCP | AC | WMM_AC (Access Category) ++ ------+----+-------- ++ 00-07| 1 | BE ++ 24-31| 1 | BE ++ 08-15| 0 | BG ++ 16-23| 0 | BG ++ 32-39| 2 | VI ++ 40-47| 2 | VI ++ 48-55| 3 | VO ++ 56-63| 3 | VO ++ ++ | TOS | ++ DSCP |(bit5~bit7)| WMM ++ -------+-----------+------- ++ 0x00 | 000 | BE ++ 0x18 | 011 | BE ++ 0x08 | 001 | BG ++ 0x10 | 010 | BG ++ 0x20 | 100 | VI ++ 0x28 | 101 | VI ++ 0x30 | 110 | VO ++ 0x38 | 111 | VO ++ ++ Notes: BE should be mapped to AC1, but mapped to AC0 in linux kernel. ++ ++ */ ++ ++int pkt_classifier(struct sk_buff *skb,int gmac_no, int *ring_no, int *queue_no, int *port_no) ++{ ++#if defined(CONFIG_RALINK_RT2880) ++ /* RT2880 -- Assume using 1 Ring (Ring0), Queue 0, and Port 0 */ ++ *port_no = 0; ++ *ring_no = 0; ++ *queue_no = 0; ++#else ++ unsigned int ac=0; ++ unsigned int bridge_traffic=0, lan_traffic=0; ++ struct iphdr *iph=NULL; ++ struct vlan_ethhdr *veth=NULL; ++ unsigned int vlan_id=0; ++#if defined (CONFIG_RAETH_QOS_DSCP_BASED) ++ static char DscpToAcMap[8]={1,0,0,1,2,2,3,3}; ++#elif defined (CONFIG_RAETH_QOS_VPRI_BASED) ++ static char VlanPriToAcMap[8]={1,0,0,1,2,2,3,3}; ++#endif ++ ++ /* Bridge:: {BG,BE,VI,VO} */ ++ /* GateWay:: WAN: {BG,BE,VI,VO}, LAN: {BG,BE,VI,VO} */ ++#if defined (CONFIG_RALINK_RT3883) && defined (CONFIG_RAETH_GMAC2) ++ /* ++ * 1) Bridge: ++ * 1.1) GMAC1 ONLY: ++ * VO/VI->Ring3, BG/BE->Ring2 ++ * 1.2) GMAC1+GMAC2: ++ * GMAC1:: VO/VI->Ring3, BG/BE->Ring2 ++ * GMAC2:: VO/VI->Ring1, BG/BE->Ring0 ++ * 2) GateWay: ++ * 2.1) GMAC1 ONLY: ++ * GMAC1:: LAN:VI/VO->Ring2, BE/BK->Ring2 ++ * WAN:VI/VO->Ring3, BE/BK->Ring3 ++ * 2.2)GMAC1+GMAC2: ++ * GMAC1:: LAN:VI/VO/BE/BK->Ring2, WAN:VI/VO/BE/BK->Ring3 ++ * GMAC2:: VI/VO->Ring1, BE/BK->Ring0 ++ */ ++ static unsigned char AcToRing_BridgeMap[4] = {2, 2, 3, 3}; ++ static unsigned char AcToRing_GE1Map[2][4] = {{3, 3, 3, 3},{2, 2, 2, 2}}; ++ static unsigned char AcToRing_GE2Map[4] = {0, 0, 1, 1}; ++#elif defined (CONFIG_RALINK_RT3052) || defined (CONFIG_RALINK_RT2883) || \ ++ defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || \ ++ defined (CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A) || \ ++ defined (CONFIG_RALINK_MT7620) || defined(CONFIG_RALINK_MT7621) || \ ++ defined (CONFIG_RALINK_MT7628) || \ ++ (defined (CONFIG_RALINK_RT3883) && !defined(CONFIG_RAETH_GMAC2)) ++ /* ++ * 1) Bridge: VO->Ring3, VI->Ring2, BG->Ring1, BE->Ring0 ++ * 2) GateWay: ++ * 2.1) GMAC1:: LAN:VI/VO->Ring1, BE/BK->Ring0 ++ * WAN:VI/VO->Ring3, BE/BK->Ring2 ++ */ ++ static unsigned char AcToRing_BridgeMap[4] = {0, 1, 2, 3}; ++ static unsigned char AcToRing_GE1Map[2][4] = {{2, 2, 3, 3},{0, 0, 1, 1}}; ++#endif // CONFIG_RALINK_RT2883 ++ ++ /* ++ * Set queue no - QN field in TX Descriptor ++ * always use queue 3 for the packet from CPU to GMAC ++ */ ++ *queue_no = 3; ++ ++ /* Get access category */ ++ veth = (struct vlan_ethhdr *)(skb->data); ++ if(veth->h_vlan_proto == htons(ETH_P_8021Q)) { // VLAN traffic ++ iph= (struct iphdr *)(skb->data + VLAN_ETH_HLEN); ++ ++ vlan_id = ntohs(veth->h_vlan_TCI & VLAN_VID_MASK); ++ if(vlan_id==1) { //LAN ++ lan_traffic = 1; ++ } else { //WAN ++ lan_traffic = 0; ++ } ++ ++ if (veth->h_vlan_encapsulated_proto == htons(ETH_P_IP)) { //IPv4 ++#if defined (CONFIG_RAETH_QOS_DSCP_BASED) ++ ac = DscpToAcMap[(iph->tos & 0xe0) >> 5]; ++#elif defined (CONFIG_RAETH_QOS_VPRI_BASED) ++ ac = VlanPriToAcMap[skb->priority]; ++#endif ++ }else { //Ipv6, ARP ...etc ++ ac = 0; ++ } ++ }else { // non-VLAN traffic ++ if (veth->h_vlan_proto == htons(ETH_P_IP)) { //IPv4 ++#if defined (CONFIG_RAETH_QOS_DSCP_BASED) ++ iph= (struct iphdr *)(skb->data + ETH_HLEN); ++ ac = DscpToAcMap[(iph->tos & 0xe0) >> 5]; ++#elif defined (CONFIG_RAETH_QOS_VPRI_BASED) ++ ac= VlanPriToAcMap[skb->priority]; ++#endif ++ }else { // IPv6, ARP ...etc ++ ac = 0; ++ } ++ ++ bridge_traffic=1; ++ } ++ ++ ++ /* Set Tx Ring no */ ++ if(gmac_no==1) { //GMAC1 ++ if(bridge_traffic) { //Bridge Mode ++ *ring_no = AcToRing_BridgeMap[ac]; ++ }else { //GateWay Mode ++ *ring_no = AcToRing_GE1Map[lan_traffic][ac]; ++ } ++ }else { //GMAC2 ++#if defined (CONFIG_RALINK_RT3883) && defined (CONFIG_RAETH_GMAC2) ++ *ring_no = AcToRing_GE2Map[ac]; ++#endif ++ } ++ ++ ++ /* Set Port No - PN field in Tx Descriptor*/ ++#if defined(CONFIG_RAETH_GMAC2) ++ *port_no = gmac_no; ++#else ++ if(bridge_traffic) { ++ *port_no = 1; ++ }else { ++ if(lan_traffic==1) { //LAN use VP1 ++ *port_no = 1; ++ }else { //WAN use VP2 ++ *port_no = 2; ++ } ++ } ++#endif // CONFIG_RAETH_GMAC2 // ++ ++#endif ++ ++ return 1; ++ ++} ++ ++ ++/* ++ * Routine Description : ++ * Hi/Li Rings and Queues definition for QoS Purpose ++ * ++ * Related registers: (Detail information refer to pp106 of RT3052_DS_20080226.doc) ++ * Priority High/Low Definition - PDMA_FC_CFG, GDMA1_FC_CFG, GDMA2_FC_CFG ++ * Bit 28 - Allows high priority Q to share low priority Q's reserved pages ++ * Bit 27:24 - Px high priority definition bitmap ++ * Weight Configuration - GDMA1_SCH_CFG, GDMA2_SCH_CFG, PDMA_SCH_CFG -> default 3210 ++ * ++ * Parameter: ++ * NONE ++ * ++*/ ++#define PSE_P1_LQ_FULL (1<<2) ++#define PSE_P1_HQ_FULL (1<<3) ++#define PSE_P2_LQ_FULL (1<<4) ++#define PSE_P2_HQ_FULL (1<<5) ++ ++#define HIGH_QUEUE(queue) (1<<(queue)) ++#define LOW_QUEUE(queue) (0<<(queue)) ++#define PAGES_SHARING (1<<28) ++#define RSEV_PAGE_COUNT_HQ 0x10 /* Reserved page count for high priority Q */ ++#define RSEV_PAGE_COUNT_LQ 0x10 /* Reserved page count for low priority Q */ ++#define VIQ_FC_ASRT 0x10 /* Virtual input Q FC assertion threshold */ ++ ++#define QUEUE_WEIGHT_1 0 ++#define QUEUE_WEIGHT_2 1 ++#define QUEUE_WEIGHT_4 2 ++#define QUEUE_WEIGHT_8 3 ++#define QUEUE_WEIGHT_16 4 ++ ++#define WRR_SCH 0 /*WRR */ ++#define STRICT_PRI_SCH 1 /* Strict Priority */ ++#define MIX_SCH 2 /* Mixed : Q3>WRR(Q2,Q1,Q0) */ ++ ++/* ++ * Ring3 Ring2 Ring1 Ring0 ++ * | | | | | | | | ++ * | | | | | | | | ++ * -------------------------------- ++ * | WRR Scheduler | ++ * -------------------------------- ++ * | ++ * --------------------------------------- ++ * | PDMA | ++ * --------------------------------------- ++ * |Q3||Q2||Q1||Q0| |Q3||Q2||Q1||Q0| ++ * | || || || | | || || || | ++ * ------------------- ------------------- ++ * | GDMA2 | | GDMA1 | ++ * ------------------- ------------------- ++ * | | ++ * ------------------------------------ ++ * | GMAC | ++ * ------------------------------------ ++ * | ++ * ++ */ ++void set_scheduler_weight(void) ++{ ++#if !defined (CONFIG_RALINK_RT5350) && !defined (CONFIG_RALINK_MT7628) ++ /* ++ * STEP1: Queue scheduling configuration ++ */ ++ *(unsigned long *)GDMA1_SCH_CFG = (WRR_SCH << 24) | ++ (QUEUE_WEIGHT_16 << 12) | /* queue 3 weight */ ++ (QUEUE_WEIGHT_8 << 8) | /* queue 2 weight */ ++ (QUEUE_WEIGHT_4 << 4) | /* queue 1 weight */ ++ (QUEUE_WEIGHT_2 << 0); /* queue 0 weight */ ++ ++ *(unsigned long *)GDMA2_SCH_CFG = (WRR_SCH << 24) | ++ (QUEUE_WEIGHT_16 << 12) | /* queue 3 weight */ ++ (QUEUE_WEIGHT_8 << 8) | /* queue 2 weight */ ++ (QUEUE_WEIGHT_4 << 4) | /* queue 1 weight */ ++ (QUEUE_WEIGHT_2 << 0); /* queue 0 weight */ ++ ++#endif ++ /* ++ * STEP2: Ring scheduling configuration ++ */ ++#if defined (CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A) || \ ++ defined (CONFIG_RALINK_MT7620) || defined(CONFIG_RALINK_MT7621) ++ /* MIN_RATE_RATIO0=0, MAX_RATE_ULMT0=1, Weight0=1 */ ++ *(unsigned long *)SCH_Q01_CFG = (0 << 10) | (1<<14) | (0 << 12); ++ /* MIN_RATE_RATIO1=0, MAX_RATE_ULMT1=1, Weight1=4 */ ++ *(unsigned long *)SCH_Q01_CFG |= (0 << 26) | (1<<30) | (2 << 28); ++ ++ /* MIN_RATE_RATIO2=0, MAX_RATE_ULMT2=1, Weight0=1 */ ++ *(unsigned long *)SCH_Q23_CFG = (0 << 10) | (1<<14) | (0 << 12); ++ /* MIN_RATE_RATIO3=0, MAX_RATE_ULMT3=1, Weight1=4 */ ++ *(unsigned long *)SCH_Q23_CFG |= (0 << 26) | (1<<30) | (2 << 28); ++#else ++ *(unsigned long *)PDMA_SCH_CFG = (WRR_SCH << 24) | ++ (QUEUE_WEIGHT_16 << 12) | /* ring 3 weight */ ++ (QUEUE_WEIGHT_4 << 8) | /* ring 2 weight */ ++ (QUEUE_WEIGHT_16 << 4) | /* ring 1 weight */ ++ (QUEUE_WEIGHT_4 << 0); /* ring 0 weight */ ++#endif ++} ++ ++/* ++ * Routine Description : ++ * Bucket size and related information from ASIC Designer, ++ * please check Max Lee to update these values ++ * ++ * Related Registers ++ * FE_GLO_CFG - initialize clock rate for rate limiting ++ * PDMA_FC_CFG - Pause mechanism for Rings (Ref to pp116 in datasheet) ++ * : ++ * Parameter: ++ * NONE ++ */ ++/* ++ * Bit 29:24 - Q3 flow control pause condition ++ * Bit 21:16 - Q2 flow control pause condition ++ * Bit 13:8 - Q1 flow control pause condition ++ * Bit 5:0 - Q0 flow control pause condition ++ * ++ * detail bitmap - ++ * Bit[5] - Pause Qx when PSE p2 HQ full ++ * Bit[4] - Pause Qx when PSE p2 LQ full ++ * Bit[3] - Pause Qx when PSE p1 HQ full ++ * Bit[2] - Pause Qx when PSE p1 LQ full ++ * Bit[1] - Pause Qx when PSE p0 HQ full ++ * Bit[0] - Pause Qx when PSE p0 LQ full ++ */ ++void set_schedule_pause_condition(void) ++{ ++#if defined (CONFIG_RALINK_MT7620) ++ ++#elif defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_MT7628) ++ *(unsigned long *)SDM_TRING = (0xC << 28) | (0x3 << 24) | (0xC << 4) | 0x3; ++#else ++ /* ++ * STEP1: Set queue priority is high or low ++ * ++ * Set queue 3 as high queue in GMAC1/GMAC2 ++ */ ++ *(unsigned long *)GDMA1_FC_CFG = ((HIGH_QUEUE(3)|LOW_QUEUE(2) | ++ LOW_QUEUE(1)|LOW_QUEUE(0))<<24) | ++ (RSEV_PAGE_COUNT_HQ << 16) | ++ (RSEV_PAGE_COUNT_LQ <<8) | ++ VIQ_FC_ASRT | PAGES_SHARING; ++ ++ *(unsigned long *)GDMA2_FC_CFG = ((HIGH_QUEUE(3)|LOW_QUEUE(2) | ++ LOW_QUEUE(1)|LOW_QUEUE(0))<<24) | ++ (RSEV_PAGE_COUNT_HQ << 16) | ++ (RSEV_PAGE_COUNT_LQ <<8) | ++ VIQ_FC_ASRT | PAGES_SHARING; ++ ++ /* ++ * STEP2: Set flow control pause condition ++ * ++ * CPU always use queue 3, and queue3 is high queue. ++ * If P2(GMAC2) high queue is full, pause ring3/ring2 ++ * If P1(GMAC1) high queue is full, pause ring1/ring0 ++ */ ++ *(unsigned long *)PDMA_FC_CFG = ( PSE_P2_HQ_FULL << 24 ) | /* queue 3 */ ++ ( PSE_P2_HQ_FULL << 16 ) | /* queue 2 */ ++ ( PSE_P1_HQ_FULL << 8 ) | /* queue 1 */ ++ ( PSE_P1_HQ_FULL << 0 ); /* queue 0 */ ++#endif ++ ++} ++ ++ ++void set_output_shaper(void) ++{ ++#define GDMA1_TOKEN_RATE 16 /* unit=64bits/ms */ ++#define GDMA2_TOKEN_RATE 16 /* unit=64bits/ms */ ++ ++#if 0 ++ *(unsigned long *)GDMA1_SHPR_CFG = (1 << 24) | /* output shaper enable */ ++ (128 << 16) | /* bucket size (unit=1KB) */ ++ (GDMA1_TOKEN_RATE << 0); /* token rate (unit=8B/ms) */ ++#endif ++ ++#if 0 ++ *(unsigned long *)GDMA2_SHPR_CFG = (1 << 24) | /* output shaper enable */ ++ (128 << 16) | /* bucket size (unit=1KB) */ ++ (GDMA2_TOKEN_RATE << 0); /* token rate (unit=8B/ms) */ ++#endif ++} +diff --git a/drivers/net/ethernet/raeth/ra_qos.h b/drivers/net/ethernet/raeth/ra_qos.h +new file mode 100644 +index 0000000..7f2a8a1 +--- /dev/null ++++ b/drivers/net/ethernet/raeth/ra_qos.h +@@ -0,0 +1,18 @@ ++#ifndef RA_QOS_H ++#define RA_QOS_H ++ ++#include "ra2882ethreg.h" ++#define RING0 0 ++#define RING1 1 ++#define RING2 2 ++#define RING3 3 ++void get_tx_desc_and_dtx_idx(END_DEVICE* ei_local, int ring_no, unsigned long *tx_dtx_idx, struct PDMA_txdesc **tx_desc); ++int get_tx_ctx_idx(unsigned int ring_no, unsigned long *idx); ++int fe_tx_desc_init(struct net_device *dev, unsigned int ring_no, unsigned int qn, unsigned int pn); ++int fe_qos_packet_send(struct net_device *dev, struct sk_buff* skb, unsigned int ring_no, unsigned int qn, unsigned int pn); ++ ++int pkt_classifier(struct sk_buff *skb,int gmac_no, int *ring_no, int *queue_no, int *port_no); ++void set_schedule_pause_condition(void); ++void set_scheduler_weight(void); ++void set_output_shaper(void); ++#endif +diff --git a/drivers/net/ethernet/raeth/ra_rfrw.c b/drivers/net/ethernet/raeth/ra_rfrw.c +new file mode 100644 +index 0000000..d73db01 +--- /dev/null ++++ b/drivers/net/ethernet/raeth/ra_rfrw.c +@@ -0,0 +1,66 @@ ++#include <linux/module.h> ++#include <linux/version.h> ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/types.h> ++#include <linux/fcntl.h> ++#include <linux/interrupt.h> ++#include <linux/ptrace.h> ++#include <linux/ioport.h> ++#include <linux/in.h> ++#include <linux/slab.h> ++#include <linux/string.h> ++#include <linux/signal.h> ++#include <linux/irq.h> ++#include <linux/netdevice.h> ++#include <linux/etherdevice.h> ++#include <linux/skbuff.h> ++ ++#include "ra2882ethreg.h" ++#include "raether.h" ++#include "ra_mac.h" ++ ++#define RF_CSR_CFG 0xb0180500 ++#define RF_CSR_KICK (1<<17) ++int rw_rf_reg(int write, int reg, int *data) ++{ ++ unsigned long rfcsr, i = 0; ++ ++ while (1) { ++ rfcsr = sysRegRead(RF_CSR_CFG); ++ if (! (rfcsr & (u32)RF_CSR_KICK) ) ++ break; ++ if (++i > 10000) { ++ printk("Warning: Abort rw rf register: too busy\n"); ++ return -1; ++ } ++ } ++ ++ rfcsr = (u32)(RF_CSR_KICK | ((reg&0x3f) << 8) | (*data & 0xff)); ++ if (write) ++ rfcsr |= 0x10000; ++ ++ sysRegRead(RF_CSR_CFG) = cpu_to_le32(rfcsr); ++ ++ i = 0; ++ while (1) { ++ rfcsr = sysRegRead(RF_CSR_CFG); ++ if (! (rfcsr & (u32)RF_CSR_KICK) ) ++ break; ++ if (++i > 10000) { ++ printk("Warning: still busy\n"); ++ return -1; ++ } ++ } ++ ++ rfcsr = sysRegRead(RF_CSR_CFG); ++ ++ if (((rfcsr&0x1f00) >> 8) != (reg & 0x1f)) { ++ printk("Error: rw register failed\n"); ++ return -1; ++ } ++ *data = (int)(rfcsr & 0xff); ++ ++ return 0; ++} ++ +diff --git a/drivers/net/ethernet/raeth/ra_rfrw.h b/drivers/net/ethernet/raeth/ra_rfrw.h +new file mode 100644 +index 0000000..da5a371 +--- /dev/null ++++ b/drivers/net/ethernet/raeth/ra_rfrw.h +@@ -0,0 +1,6 @@ ++#ifndef RA_RFRW_H ++#define RA_RFRW_H ++ ++int rw_rf_reg(int write, int reg, int *data); ++ ++#endif +diff --git a/drivers/net/ethernet/raeth/raether.c b/drivers/net/ethernet/raeth/raether.c +new file mode 100644 +index 0000000..328285a +--- /dev/null ++++ b/drivers/net/ethernet/raeth/raether.c +@@ -0,0 +1,6401 @@ ++#include <linux/module.h> ++#include <linux/version.h> ++#include <linux/kernel.h> ++#include <linux/types.h> ++#include <linux/pci.h> ++#include <linux/init.h> ++#include <linux/skbuff.h> ++#include <linux/if_vlan.h> ++#include <linux/if_ether.h> ++#include <linux/fs.h> ++#include <asm/uaccess.h> ++#include <asm/rt2880/surfboardint.h> ++#include <linux/platform_device.h> ++#if defined (CONFIG_RAETH_TSO) ++#include <linux/tcp.h> ++#include <net/ipv6.h> ++#include <linux/ip.h> ++#include <net/ip.h> ++#include <net/tcp.h> ++#include <linux/in.h> ++#include <linux/ppp_defs.h> ++#include <linux/if_pppox.h> ++#endif ++#if defined (CONFIG_RAETH_LRO) ++#include <linux/inet_lro.h> ++#endif ++#include <linux/delay.h> ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++#include <linux/sched.h> ++#endif ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++#include <asm/rt2880/rt_mmap.h> ++#else ++#include <linux/libata-compat.h> ++#endif ++ ++#include "ra2882ethreg.h" ++#include "raether.h" ++#include "ra_mac.h" ++#include "ra_ioctl.h" ++#include "ra_rfrw.h" ++#ifdef CONFIG_RAETH_NETLINK ++#include "ra_netlink.h" ++#endif ++#if defined (CONFIG_RAETH_QOS) ++#include "ra_qos.h" ++#endif ++ ++#if defined (CONFIG_RA_HW_NAT) || defined (CONFIG_RA_HW_NAT_MODULE) ++#include "../../../net/nat/hw_nat/ra_nat.h" ++#endif ++#if defined(CONFIG_RAETH_PDMA_DVT) ++#include "dvt/raether_pdma_dvt.h" ++#endif /* CONFIG_RAETH_PDMA_DVT */ ++ ++static int fe_irq = 0; ++ ++#if defined (TASKLET_WORKQUEUE_SW) ++int init_schedule; ++int working_schedule; ++#endif ++ ++#ifdef CONFIG_RAETH_NAPI ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++static int raeth_clean(struct napi_struct *napi, int budget); ++#else ++static int raeth_clean(struct net_device *dev, int *budget); ++#endif ++ ++static int rt2880_eth_recv(struct net_device* dev, int *work_done, int work_to_do); ++#else ++static int rt2880_eth_recv(struct net_device* dev); ++#endif ++ ++#if !defined(CONFIG_RA_NAT_NONE) ++/* bruce+ ++ */ ++extern int (*ra_sw_nat_hook_rx)(struct sk_buff *skb); ++extern int (*ra_sw_nat_hook_tx)(struct sk_buff *skb, int gmac_no); ++#endif ++ ++#if defined(CONFIG_RA_CLASSIFIER)||defined(CONFIG_RA_CLASSIFIER_MODULE) ++/* Qwert+ ++ */ ++#include <asm/mipsregs.h> ++extern int (*ra_classifier_hook_tx)(struct sk_buff *skb, unsigned long cur_cycle); ++extern int (*ra_classifier_hook_rx)(struct sk_buff *skb, unsigned long cur_cycle); ++#endif /* CONFIG_RA_CLASSIFIER */ ++ ++#if defined (CONFIG_RALINK_RT3052_MP2) ++int32_t mcast_rx(struct sk_buff * skb); ++int32_t mcast_tx(struct sk_buff * skb); ++#endif ++ ++int ra_mtd_read_nm(char *name, loff_t from, size_t len, u_char *buf) ++{ ++ /* TODO */ ++ return 0; ++} ++ ++#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_P5_RGMII_TO_MT7530_MODE) || defined (CONFIG_ARCH_MT7623) ++void setup_internal_gsw(void); ++#if defined (CONFIG_GE1_TRGMII_FORCE_1200) ++void apll_xtal_enable(void); ++#define REGBIT(x, n) (x << n) ++#endif ++#endif ++ ++#if defined (CONFIG_MT7623_FPGA) ++void setup_fpga_gsw(void); ++#endif ++ ++/* gmac driver feature set config */ ++#if defined (CONFIG_RAETH_NAPI) || defined (CONFIG_RAETH_QOS) ++#undef DELAY_INT ++#else ++#if defined (CONFIG_ARCH_MT7623) ++#undef DELAY_INT ++#else ++#define DELAY_INT 1 ++#endif ++#endif ++ ++//#define CONFIG_UNH_TEST ++/* end of config */ ++ ++#if defined (CONFIG_RAETH_JUMBOFRAME) ++#define MAX_RX_LENGTH 4096 ++#else ++#define MAX_RX_LENGTH 1536 ++#endif ++ ++struct net_device *dev_raether; ++ ++static int rx_dma_owner_idx; ++static int rx_dma_owner_idx0; ++#if defined (CONFIG_RAETH_HW_LRO) ++static int rx_dma_owner_lro1; ++static int rx_dma_owner_lro2; ++static int rx_dma_owner_lro3; ++#elif defined (CONFIG_RAETH_MULTIPLE_RX_RING) ++static int rx_dma_owner_idx1; ++#if defined(CONFIG_ARCH_MT7623) ++static int rx_dma_owner_idx2; ++static int rx_dma_owner_idx3; ++#endif /* CONFIG_ARCH_MT7623 */ ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++int rx_calc_idx1; ++#endif ++#endif ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++int rx_calc_idx0; ++#endif ++static int pending_recv; ++static struct PDMA_rxdesc *rx_ring; ++unsigned long tx_ring_full=0; ++ ++#if defined(CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A) || \ ++ defined(CONFIG_RALINK_MT7620) ++unsigned short p0_rx_good_cnt = 0; ++unsigned short p1_rx_good_cnt = 0; ++unsigned short p2_rx_good_cnt = 0; ++unsigned short p3_rx_good_cnt = 0; ++unsigned short p4_rx_good_cnt = 0; ++unsigned short p5_rx_good_cnt = 0; ++unsigned short p6_rx_good_cnt = 0; ++unsigned short p0_tx_good_cnt = 0; ++unsigned short p1_tx_good_cnt = 0; ++unsigned short p2_tx_good_cnt = 0; ++unsigned short p3_tx_good_cnt = 0; ++unsigned short p4_tx_good_cnt = 0; ++unsigned short p5_tx_good_cnt = 0; ++unsigned short p6_tx_good_cnt = 0; ++ ++unsigned short p0_rx_byte_cnt = 0; ++unsigned short p1_rx_byte_cnt = 0; ++unsigned short p2_rx_byte_cnt = 0; ++unsigned short p3_rx_byte_cnt = 0; ++unsigned short p4_rx_byte_cnt = 0; ++unsigned short p5_rx_byte_cnt = 0; ++unsigned short p6_rx_byte_cnt = 0; ++unsigned short p0_tx_byte_cnt = 0; ++unsigned short p1_tx_byte_cnt = 0; ++unsigned short p2_tx_byte_cnt = 0; ++unsigned short p3_tx_byte_cnt = 0; ++unsigned short p4_tx_byte_cnt = 0; ++unsigned short p5_tx_byte_cnt = 0; ++unsigned short p6_tx_byte_cnt = 0; ++ ++#if defined(CONFIG_RALINK_MT7620) ++unsigned short p7_rx_good_cnt = 0; ++unsigned short p7_tx_good_cnt = 0; ++ ++unsigned short p7_rx_byte_cnt = 0; ++unsigned short p7_tx_byte_cnt = 0; ++#endif ++#endif ++ ++ ++ ++ ++#if defined (CONFIG_ETHTOOL) /*&& defined (CONFIG_RAETH_ROUTER)*/ ++#include "ra_ethtool.h" ++extern struct ethtool_ops ra_ethtool_ops; ++#ifdef CONFIG_PSEUDO_SUPPORT ++extern struct ethtool_ops ra_virt_ethtool_ops; ++#endif // CONFIG_PSEUDO_SUPPORT // ++#endif // (CONFIG_ETHTOOL // ++ ++#ifdef CONFIG_RALINK_VISTA_BASIC ++int is_switch_175c = 1; ++#endif ++ ++unsigned int M2Q_table[64] = {0}; ++unsigned int lan_wan_separate = 0; ++ ++#if defined(CONFIG_HW_SFQ) ++unsigned int web_sfq_enable = 0; ++EXPORT_SYMBOL(web_sfq_enable); ++#endif ++ ++EXPORT_SYMBOL(M2Q_table); ++EXPORT_SYMBOL(lan_wan_separate); ++#if defined (CONFIG_RAETH_LRO) ++unsigned int lan_ip; ++struct lro_para_struct lro_para; ++int lro_flush_needed; ++extern char const *nvram_get(int index, char *name); ++#endif ++ ++#define KSEG1 0xa0000000 ++#if defined (CONFIG_MIPS) ++#define PHYS_TO_VIRT(x) ((void *)((x) | KSEG1)) ++#define VIRT_TO_PHYS(x) ((unsigned long)(x) & ~KSEG1) ++#else ++#define PHYS_TO_VIRT(x) phys_to_virt(x) ++#define VIRT_TO_PHYS(x) virt_to_phys(x) ++#endif ++ ++extern int fe_dma_init(struct net_device *dev); ++extern int ei_start_xmit(struct sk_buff* skb, struct net_device *dev, int gmac_no); ++extern void ei_xmit_housekeeping(unsigned long unused); ++extern inline int rt2880_eth_send(struct net_device* dev, struct sk_buff *skb, int gmac_no); ++#if defined (CONFIG_RAETH_HW_LRO) ++extern int fe_hw_lro_init(struct net_device *dev); ++#endif /* CONFIG_RAETH_HW_LRO */ ++ ++#if 0 ++void skb_dump(struct sk_buff* sk) { ++ unsigned int i; ++ ++ printk("skb_dump: from %s with len %d (%d) headroom=%d tailroom=%d\n", ++ sk->dev?sk->dev->name:"ip stack",sk->len,sk->truesize, ++ skb_headroom(sk),skb_tailroom(sk)); ++ ++ //for(i=(unsigned int)sk->head;i<=(unsigned int)sk->tail;i++) { ++ for(i=(unsigned int)sk->head;i<=(unsigned int)sk->data+20;i++) { ++ if((i % 20) == 0) ++ printk("\n"); ++ if(i==(unsigned int)sk->data) printk("{"); ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21) ++ if(i==(unsigned int)sk->transport_header) printk("#"); ++ if(i==(unsigned int)sk->network_header) printk("|"); ++ if(i==(unsigned int)sk->mac_header) printk("*"); ++#else ++ if(i==(unsigned int)sk->h.raw) printk("#"); ++ if(i==(unsigned int)sk->nh.raw) printk("|"); ++ if(i==(unsigned int)sk->mac.raw) printk("*"); ++#endif ++ printk("%02X-",*((unsigned char*)i)); ++ if(i==(unsigned int)sk->tail) printk("}"); ++ } ++ printk("\n"); ++} ++#endif ++ ++ ++ ++#if defined (CONFIG_GIGAPHY) || defined (CONFIG_P5_MAC_TO_PHY_MODE) ++int isICPlusGigaPHY(int ge) ++{ ++ u32 phy_id0 = 0, phy_id1 = 0; ++ ++#ifdef CONFIG_GE2_RGMII_AN ++ if (ge == 2) { ++ if (!mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 2, &phy_id0)) { ++ printk("\n Read PhyID 1 is Fail!!\n"); ++ phy_id0 =0; ++ } ++ if (!mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 3, &phy_id1)) { ++ printk("\n Read PhyID 1 is Fail!!\n"); ++ phy_id1 = 0; ++ } ++ } ++ else ++#endif ++#if defined (CONFIG_GE1_RGMII_AN) || defined (CONFIG_P5_MAC_TO_PHY_MODE) ++ { ++ if (!mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 2, &phy_id0)) { ++ printk("\n Read PhyID 0 is Fail!!\n"); ++ phy_id0 =0; ++ } ++ if (!mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 3, &phy_id1)) { ++ printk("\n Read PhyID 0 is Fail!!\n"); ++ phy_id1 = 0; ++ } ++ } ++#endif ++ ++ if ((phy_id0 == EV_ICPLUS_PHY_ID0) && ((phy_id1 & 0xfff0) == EV_ICPLUS_PHY_ID1)) ++ return 1; ++ return 0; ++} ++ ++ ++int isMarvellGigaPHY(int ge) ++{ ++ u32 phy_id0 = 0, phy_id1 = 0; ++ ++#if defined (CONFIG_GE2_RGMII_AN) || defined (CONFIG_P4_MAC_TO_PHY_MODE) ++ if (ge == 2) { ++ if (!mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 2, &phy_id0)) { ++ printk("\n Read PhyID 1 is Fail!!\n"); ++ phy_id0 =0; ++ } ++ if (!mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 3, &phy_id1)) { ++ printk("\n Read PhyID 1 is Fail!!\n"); ++ phy_id1 = 0; ++ } ++ } ++ else ++#endif ++#if defined (CONFIG_GE1_RGMII_AN) || defined (CONFIG_P5_MAC_TO_PHY_MODE) ++ { ++ if (!mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 2, &phy_id0)) { ++ printk("\n Read PhyID 0 is Fail!!\n"); ++ phy_id0 =0; ++ } ++ if (!mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 3, &phy_id1)) { ++ printk("\n Read PhyID 0 is Fail!!\n"); ++ phy_id1 = 0; ++ } ++ } ++#endif ++ ; ++ if ((phy_id0 == EV_MARVELL_PHY_ID0) && (phy_id1 == EV_MARVELL_PHY_ID1)) ++ return 1; ++ return 0; ++} ++ ++int isVtssGigaPHY(int ge) ++{ ++ u32 phy_id0 = 0, phy_id1 = 0; ++ ++#if defined (CONFIG_GE2_RGMII_AN) || defined (CONFIG_P4_MAC_TO_PHY_MODE) ++ if (ge == 2) { ++ if (!mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 2, &phy_id0)) { ++ printk("\n Read PhyID 1 is Fail!!\n"); ++ phy_id0 =0; ++ } ++ if (!mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 3, &phy_id1)) { ++ printk("\n Read PhyID 1 is Fail!!\n"); ++ phy_id1 = 0; ++ } ++ } ++ else ++#endif ++#if defined (CONFIG_GE1_RGMII_AN) || defined (CONFIG_P5_MAC_TO_PHY_MODE) ++ { ++ if (!mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 2, &phy_id0)) { ++ printk("\n Read PhyID 0 is Fail!!\n"); ++ phy_id0 =0; ++ } ++ if (!mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 3, &phy_id1)) { ++ printk("\n Read PhyID 0 is Fail!!\n"); ++ phy_id1 = 0; ++ } ++ } ++#endif ++ ; ++ if ((phy_id0 == EV_VTSS_PHY_ID0) && (phy_id1 == EV_VTSS_PHY_ID1)) ++ return 1; ++ return 0; ++} ++#endif ++ ++/* ++ * Set the hardware MAC address. ++ */ ++static int ei_set_mac_addr(struct net_device *dev, void *p) ++{ ++ struct sockaddr *addr = p; ++ ++ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); ++ ++ if(netif_running(dev)) ++ return -EBUSY; ++ ++ ra2880MacAddressSet(addr->sa_data); ++ return 0; ++} ++ ++#ifdef CONFIG_PSEUDO_SUPPORT ++static int ei_set_mac2_addr(struct net_device *dev, void *p) ++{ ++ struct sockaddr *addr = p; ++ ++ memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); ++ ++ if(netif_running(dev)) ++ return -EBUSY; ++ ++ ra2880Mac2AddressSet(addr->sa_data); ++ return 0; ++} ++#endif ++ ++void set_fe_dma_glo_cfg(void) ++{ ++ int dma_glo_cfg=0; ++#if defined (CONFIG_RALINK_RT2880) || defined(CONFIG_RALINK_RT2883) || \ ++ defined (CONFIG_RALINK_RT3052) || defined (CONFIG_RALINK_RT3883) ++ int fe_glo_cfg=0; ++#endif ++ ++#if defined (CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A) ++ dma_glo_cfg = (TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN | PDMA_BT_SIZE_32DWORDS); ++#elif defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7621) ++ dma_glo_cfg = (TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN | PDMA_BT_SIZE_16DWORDS); ++#elif defined (CONFIG_ARCH_MT7623) ++ dma_glo_cfg = (TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN | PDMA_BT_SIZE_16DWORDS | ADMA_RX_BT_SIZE_32DWORDS); ++#else ++ dma_glo_cfg = (TX_WB_DDONE | RX_DMA_EN | TX_DMA_EN | PDMA_BT_SIZE_4DWORDS); ++#endif ++ ++#if defined (CONFIG_RAETH_SCATTER_GATHER_RX_DMA) ++ dma_glo_cfg |= (RX_2B_OFFSET); ++#endif ++ ++#if defined (CONFIG_32B_DESC) ++ dma_glo_cfg |= (DESC_32B_EN); ++#endif ++ sysRegWrite(DMA_GLO_CFG, dma_glo_cfg); ++#ifdef CONFIG_RAETH_QDMA ++ sysRegWrite(QDMA_GLO_CFG, dma_glo_cfg); ++#endif ++ ++ /* only the following chipset need to set it */ ++#if defined (CONFIG_RALINK_RT2880) || defined(CONFIG_RALINK_RT2883) || \ ++ defined (CONFIG_RALINK_RT3052) || defined (CONFIG_RALINK_RT3883) ++ //set 1us timer count in unit of clock cycle ++ fe_glo_cfg = sysRegRead(FE_GLO_CFG); ++ fe_glo_cfg &= ~(0xff << 8); //clear bit8-bit15 ++ fe_glo_cfg |= (((get_surfboard_sysclk()/1000000)) << 8); ++ sysRegWrite(FE_GLO_CFG, fe_glo_cfg); ++#endif ++} ++ ++int forward_config(struct net_device *dev) ++{ ++ ++#if defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_MT7628) ++ ++ /* RT5350: No GDMA, PSE, CDMA, PPE */ ++ unsigned int sdmVal; ++ sdmVal = sysRegRead(SDM_CON); ++ ++#ifdef CONFIG_RAETH_CHECKSUM_OFFLOAD ++ sdmVal |= 0x7<<16; // UDPCS, TCPCS, IPCS=1 ++#endif // CONFIG_RAETH_CHECKSUM_OFFLOAD // ++ ++#if defined (CONFIG_RAETH_SPECIAL_TAG) ++ sdmVal |= 0x1<<20; // TCI_81XX ++#endif // CONFIG_RAETH_SPECIAL_TAG // ++ ++ sysRegWrite(SDM_CON, sdmVal); ++ ++#else //Non RT5350 chipset ++ ++ unsigned int regVal, regCsg; ++ ++#ifdef CONFIG_PSEUDO_SUPPORT ++ unsigned int regVal2; ++#endif ++ ++#ifdef CONFIG_RAETH_HW_VLAN_TX ++#if defined(CONFIG_RALINK_MT7620) ++ /* frame engine will push VLAN tag regarding to VIDX feild in Tx desc. */ ++ *(unsigned long *)(RALINK_FRAME_ENGINE_BASE + 0x430) = 0x00010000; ++ *(unsigned long *)(RALINK_FRAME_ENGINE_BASE + 0x434) = 0x00030002; ++ *(unsigned long *)(RALINK_FRAME_ENGINE_BASE + 0x438) = 0x00050004; ++ *(unsigned long *)(RALINK_FRAME_ENGINE_BASE + 0x43C) = 0x00070006; ++ *(unsigned long *)(RALINK_FRAME_ENGINE_BASE + 0x440) = 0x00090008; ++ *(unsigned long *)(RALINK_FRAME_ENGINE_BASE + 0x444) = 0x000b000a; ++ *(unsigned long *)(RALINK_FRAME_ENGINE_BASE + 0x448) = 0x000d000c; ++ *(unsigned long *)(RALINK_FRAME_ENGINE_BASE + 0x44C) = 0x000f000e; ++#else ++ /* ++ * VLAN_IDX 0 = VLAN_ID 0 ++ * ......... ++ * VLAN_IDX 15 = VLAN ID 15 ++ * ++ */ ++ /* frame engine will push VLAN tag regarding to VIDX feild in Tx desc. */ ++ *(unsigned long *)(RALINK_FRAME_ENGINE_BASE + 0xa8) = 0x00010000; ++ *(unsigned long *)(RALINK_FRAME_ENGINE_BASE + 0xac) = 0x00030002; ++ *(unsigned long *)(RALINK_FRAME_ENGINE_BASE + 0xb0) = 0x00050004; ++ *(unsigned long *)(RALINK_FRAME_ENGINE_BASE + 0xb4) = 0x00070006; ++ *(unsigned long *)(RALINK_FRAME_ENGINE_BASE + 0xb8) = 0x00090008; ++ *(unsigned long *)(RALINK_FRAME_ENGINE_BASE + 0xbc) = 0x000b000a; ++ *(unsigned long *)(RALINK_FRAME_ENGINE_BASE + 0xc0) = 0x000d000c; ++ *(unsigned long *)(RALINK_FRAME_ENGINE_BASE + 0xc4) = 0x000f000e; ++#endif ++#endif ++ ++ regVal = sysRegRead(GDMA1_FWD_CFG); ++ regCsg = sysRegRead(CDMA_CSG_CFG); ++ ++#ifdef CONFIG_PSEUDO_SUPPORT ++ regVal2 = sysRegRead(GDMA2_FWD_CFG); ++#endif ++ ++ //set unicast/multicast/broadcast frame to cpu ++#if defined (CONFIG_RALINK_MT7620) ++ /* GDMA1 frames destination port is port0 CPU*/ ++ regVal &= ~0x7; ++#else ++ regVal &= ~0xFFFF; ++ regVal |= GDMA1_FWD_PORT; ++#endif ++ regCsg &= ~0x7; ++ ++#if defined (CONFIG_RAETH_SPECIAL_TAG) ++ regVal |= (1 << 24); //GDM1_TCI_81xx ++#endif ++ ++ ++#ifdef CONFIG_RAETH_HW_VLAN_TX ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) ++ dev->features |= NETIF_F_HW_VLAN_TX; ++#else ++ dev->features |= NETIF_F_HW_VLAN_CTAG_TX; ++#endif ++#endif ++#ifdef CONFIG_RAETH_HW_VLAN_RX ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0) ++ dev->features |= NETIF_F_HW_VLAN_RX; ++#else ++ dev->features |= NETIF_F_HW_VLAN_CTAG_RX; ++#endif ++#endif ++ ++#ifdef CONFIG_RAETH_CHECKSUM_OFFLOAD ++ //enable ipv4 header checksum check ++ regVal |= GDM1_ICS_EN; ++ regCsg |= ICS_GEN_EN; ++ ++ //enable tcp checksum check ++ regVal |= GDM1_TCS_EN; ++ regCsg |= TCS_GEN_EN; ++ ++ //enable udp checksum check ++ regVal |= GDM1_UCS_EN; ++ regCsg |= UCS_GEN_EN; ++ ++#ifdef CONFIG_PSEUDO_SUPPORT ++ regVal2 &= ~0xFFFF; ++ regVal2 |= GDMA2_FWD_PORT; ++ ++ regVal2 |= GDM1_ICS_EN; ++ regVal2 |= GDM1_TCS_EN; ++ regVal2 |= GDM1_UCS_EN; ++#endif ++ ++#if defined (CONFIG_RAETH_HW_LRO) ++ dev->features |= NETIF_F_HW_CSUM; ++#else ++ dev->features |= NETIF_F_IP_CSUM; /* Can checksum TCP/UDP over IPv4 */ ++#endif /* CONFIG_RAETH_HW_LRO */ ++//#if LINUX_VERSION_CODE > KERNEL_VERSION(3,10,0) ++// dev->vlan_features |= NETIF_F_IP_CSUM; ++//#endif ++ ++#if defined(CONFIG_RALINK_MT7620) ++#if defined (CONFIG_RAETH_TSO) ++ if ((sysRegRead(0xB000000C) & 0xf) >= 0x5) { ++ dev->features |= NETIF_F_SG; ++ dev->features |= NETIF_F_TSO; ++ } ++#endif // CONFIG_RAETH_TSO // ++ ++#if defined (CONFIG_RAETH_TSOV6) ++ if ((sysRegRead(0xB000000C) & 0xf) >= 0x5) { ++ dev->features |= NETIF_F_TSO6; ++ dev->features |= NETIF_F_IPV6_CSUM; /* Can checksum TCP/UDP over IPv6 */ ++ } ++#endif // CONFIG_RAETH_TSOV6 // ++#else ++#if defined (CONFIG_RAETH_TSO) ++ dev->features |= NETIF_F_SG; ++ dev->features |= NETIF_F_TSO; ++#endif // CONFIG_RAETH_TSO // ++ ++#if defined (CONFIG_RAETH_TSOV6) ++ dev->features |= NETIF_F_TSO6; ++ dev->features |= NETIF_F_IPV6_CSUM; /* Can checksum TCP/UDP over IPv6 */ ++#endif // CONFIG_RAETH_TSOV6 // ++#endif // CONFIG_RALINK_MT7620 // ++#else // Checksum offload disabled ++ ++ //disable ipv4 header checksum check ++ regVal &= ~GDM1_ICS_EN; ++ regCsg &= ~ICS_GEN_EN; ++ ++ //disable tcp checksum check ++ regVal &= ~GDM1_TCS_EN; ++ regCsg &= ~TCS_GEN_EN; ++ ++ //disable udp checksum check ++ regVal &= ~GDM1_UCS_EN; ++ regCsg &= ~UCS_GEN_EN; ++ ++#ifdef CONFIG_PSEUDO_SUPPORT ++ regVal2 &= ~GDM1_ICS_EN; ++ regVal2 &= ~GDM1_TCS_EN; ++ regVal2 &= ~GDM1_UCS_EN; ++#endif ++ ++ dev->features &= ~NETIF_F_IP_CSUM; /* disable checksum TCP/UDP over IPv4 */ ++#endif // CONFIG_RAETH_CHECKSUM_OFFLOAD // ++ ++#ifdef CONFIG_RAETH_JUMBOFRAME ++ regVal |= GDM1_JMB_EN; ++#ifdef CONFIG_PSEUDO_SUPPORT ++ regVal2 |= GDM1_JMB_EN; ++#endif ++#endif ++ ++ sysRegWrite(GDMA1_FWD_CFG, regVal); ++ sysRegWrite(CDMA_CSG_CFG, regCsg); ++#ifdef CONFIG_PSEUDO_SUPPORT ++ sysRegWrite(GDMA2_FWD_CFG, regVal2); ++#endif ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(3,10,0) ++ dev->vlan_features = dev->features; ++#endif ++ ++/* ++ * PSE_FQ_CFG register definition - ++ * ++ * Define max free queue page count in PSE. (31:24) ++ * RT2883/RT3883 - 0xff908000 (255 pages) ++ * RT3052 - 0x80504000 (128 pages) ++ * RT2880 - 0x80504000 (128 pages) ++ * ++ * In each page, there are 128 bytes in each page. ++ * ++ * 23:16 - free queue flow control release threshold ++ * 15:8 - free queue flow control assertion threshold ++ * 7:0 - free queue empty threshold ++ * ++ * The register affects QOS correctness in frame engine! ++ */ ++ ++#if defined(CONFIG_RALINK_RT2883) || defined(CONFIG_RALINK_RT3883) ++ sysRegWrite(PSE_FQ_CFG, cpu_to_le32(INIT_VALUE_OF_RT2883_PSE_FQ_CFG)); ++#elif defined(CONFIG_RALINK_RT3352) || defined(CONFIG_RALINK_RT5350) || \ ++ defined(CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A) || \ ++ defined(CONFIG_RALINK_MT7620) || defined(CONFIG_RALINK_MT7621) || \ ++ defined (CONFIG_RALINK_MT7628) || defined(CONFIG_ARCH_MT7623) ++ /*use default value*/ ++#else ++ sysRegWrite(PSE_FQ_CFG, cpu_to_le32(INIT_VALUE_OF_PSE_FQFC_CFG)); ++#endif ++ ++ /* ++ *FE_RST_GLO register definition - ++ *Bit 0: PSE Rest ++ *Reset PSE after re-programming PSE_FQ_CFG. ++ */ ++ regVal = 0x1; ++ sysRegWrite(FE_RST_GL, regVal); ++ sysRegWrite(FE_RST_GL, 0); // update for RSTCTL issue ++ ++ regCsg = sysRegRead(CDMA_CSG_CFG); ++ printk("CDMA_CSG_CFG = %0X\n",regCsg); ++ regVal = sysRegRead(GDMA1_FWD_CFG); ++ printk("GDMA1_FWD_CFG = %0X\n",regVal); ++ ++#ifdef CONFIG_PSEUDO_SUPPORT ++ regVal = sysRegRead(GDMA2_FWD_CFG); ++ printk("GDMA2_FWD_CFG = %0X\n",regVal); ++#endif ++#endif ++ return 1; ++} ++ ++#ifdef CONFIG_RAETH_LRO ++static int ++rt_get_skb_header(struct sk_buff *skb, void **iphdr, void **tcph, ++ u64 *hdr_flags, void *priv) ++{ ++ struct iphdr *iph = NULL; ++ int vhdr_len = 0; ++ ++ /* ++ * Make sure that this packet is Ethernet II, is not VLAN ++ * tagged, is IPv4, has a valid IP header, and is TCP. ++ */ ++ if (skb->protocol == 0x0081) { ++ vhdr_len = VLAN_HLEN; ++ } ++ ++ iph = (struct iphdr *)(skb->data + vhdr_len); ++ if (iph->daddr != lro_para.lan_ip1) { ++ return -1; ++ } ++ ++ if(iph->protocol != IPPROTO_TCP) { ++ return -1; ++ } else { ++ *iphdr = iph; ++ *tcph = skb->data + (iph->ihl << 2) + vhdr_len; ++ *hdr_flags = LRO_IPV4 | LRO_TCP; ++ ++ lro_flush_needed = 1; ++ return 0; ++ } ++} ++#endif // CONFIG_RAETH_LRO // ++ ++#ifdef CONFIG_RAETH_NAPI ++static int rt2880_eth_recv(struct net_device* dev, int *work_done, int work_to_do) ++#else ++static int rt2880_eth_recv(struct net_device* dev) ++#endif ++{ ++ struct sk_buff *skb, *rx_skb; ++ unsigned int length = 0; ++ unsigned long RxProcessed; ++ ++ int bReschedule = 0; ++ END_DEVICE* ei_local = netdev_priv(dev); ++#if defined (CONFIG_RAETH_MULTIPLE_RX_RING) || defined (CONFIG_RAETH_HW_LRO) ++ int rx_ring_no=0; ++#endif ++ ++#if defined (CONFIG_RAETH_SPECIAL_TAG) ++ struct vlan_ethhdr *veth=NULL; ++#endif ++ ++#ifdef CONFIG_PSEUDO_SUPPORT ++ PSEUDO_ADAPTER *pAd; ++#endif ++ ++ RxProcessed = 0; ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ rx_dma_owner_idx0 = (rx_calc_idx0 + 1) % NUM_RX_DESC; ++#else ++ rx_dma_owner_idx0 = (sysRegRead(RAETH_RX_CALC_IDX0) + 1) % NUM_RX_DESC; ++#endif ++ ++#if defined (CONFIG_32B_DESC) ++ dma_cache_sync(NULL, &ei_local->rx_ring0[rx_dma_owner_idx0], sizeof(struct PDMA_rxdesc), DMA_FROM_DEVICE); ++#endif ++#if defined (CONFIG_RAETH_HW_LRO) ++ rx_dma_owner_lro1 = (sysRegRead(RX_CALC_IDX1) + 1) % NUM_LRO_RX_DESC; ++ rx_dma_owner_lro2 = (sysRegRead(RX_CALC_IDX2) + 1) % NUM_LRO_RX_DESC; ++ rx_dma_owner_lro3 = (sysRegRead(RX_CALC_IDX3) + 1) % NUM_LRO_RX_DESC; ++#elif defined (CONFIG_RAETH_MULTIPLE_RX_RING) ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ rx_dma_owner_idx1 = (rx_calc_idx1 + 1) % NUM_RX_DESC; ++#else ++ rx_dma_owner_idx1 = (sysRegRead(RX_CALC_IDX1) + 1) % NUM_RX_DESC; ++#endif /* CONFIG_RAETH_RW_PDMAPTR_FROM_VAR */ ++#if defined(CONFIG_ARCH_MT7623) ++ rx_dma_owner_idx2 = (sysRegRead(RX_CALC_IDX2) + 1) % NUM_RX_DESC; ++ rx_dma_owner_idx3 = (sysRegRead(RX_CALC_IDX3) + 1) % NUM_RX_DESC; ++#endif ++#if defined (CONFIG_32B_DESC) ++ dma_cache_sync(NULL, &ei_local->rx_ring1[rx_dma_owner_idx1], sizeof(struct PDMA_rxdesc), DMA_FROM_DEVICE); ++#endif ++#endif ++ for ( ; ; ) { ++ ++ ++#ifdef CONFIG_RAETH_NAPI ++ if(*work_done >= work_to_do) ++ break; ++ (*work_done)++; ++#else ++ if (RxProcessed++ > NUM_RX_MAX_PROCESS) ++ { ++ // need to reschedule rx handle ++ bReschedule = 1; ++ break; ++ } ++#endif ++ ++ ++#if defined (CONFIG_RAETH_HW_LRO) ++ if (ei_local->rx_ring3[rx_dma_owner_lro3].rxd_info2.DDONE_bit == 1) { ++ rx_ring = ei_local->rx_ring3; ++ rx_dma_owner_idx = rx_dma_owner_lro3; ++ // printk("rx_dma_owner_lro3=%x\n",rx_dma_owner_lro3); ++ rx_ring_no=3; ++ } ++ else if (ei_local->rx_ring2[rx_dma_owner_lro2].rxd_info2.DDONE_bit == 1) { ++ rx_ring = ei_local->rx_ring2; ++ rx_dma_owner_idx = rx_dma_owner_lro2; ++ // printk("rx_dma_owner_lro2=%x\n",rx_dma_owner_lro2); ++ rx_ring_no=2; ++ } ++ else if (ei_local->rx_ring1[rx_dma_owner_lro1].rxd_info2.DDONE_bit == 1) { ++ rx_ring = ei_local->rx_ring1; ++ rx_dma_owner_idx = rx_dma_owner_lro1; ++ // printk("rx_dma_owner_lro1=%x\n",rx_dma_owner_lro1); ++ rx_ring_no=1; ++ } ++ else if (ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info2.DDONE_bit == 1) { ++ rx_ring = ei_local->rx_ring0; ++ rx_dma_owner_idx = rx_dma_owner_idx0; ++ // printk("rx_dma_owner_idx0=%x\n",rx_dma_owner_idx0); ++ rx_ring_no=0; ++ } else { ++ break; ++ } ++ #if defined (CONFIG_RAETH_HW_LRO_DBG) ++ HwLroStatsUpdate(rx_ring_no, rx_ring[rx_dma_owner_idx].rxd_info2.LRO_AGG_CNT, \ ++ (rx_ring[rx_dma_owner_idx].rxd_info2.PLEN1 << 14) | rx_ring[rx_dma_owner_idx].rxd_info2.PLEN0); ++ #endif ++ #if defined(CONFIG_RAETH_HW_LRO_REASON_DBG) ++ HwLroFlushStatsUpdate(rx_ring_no, rx_ring[rx_dma_owner_idx].rxd_info2.REV); ++ #endif ++#elif defined (CONFIG_RAETH_MULTIPLE_RX_RING) ++ if (ei_local->rx_ring1[rx_dma_owner_idx1].rxd_info2.DDONE_bit == 1) { ++ rx_ring = ei_local->rx_ring1; ++ rx_dma_owner_idx = rx_dma_owner_idx1; ++ // printk("rx_dma_owner_idx1=%x\n",rx_dma_owner_idx1); ++ rx_ring_no=1; ++ } ++#if defined(CONFIG_ARCH_MT7623) ++ else if (ei_local->rx_ring2[rx_dma_owner_idx2].rxd_info2.DDONE_bit == 1) { ++ rx_ring = ei_local->rx_ring2; ++ rx_dma_owner_idx = rx_dma_owner_idx2; ++ // printk("rx_dma_owner_idx2=%x\n",rx_dma_owner_idx2); ++ rx_ring_no=2; ++ } ++ else if (ei_local->rx_ring3[rx_dma_owner_idx3].rxd_info2.DDONE_bit == 1) { ++ rx_ring = ei_local->rx_ring3; ++ rx_dma_owner_idx = rx_dma_owner_idx3; ++ // printk("rx_dma_owner_idx3=%x\n",rx_dma_owner_idx3); ++ rx_ring_no=3; ++ } ++#endif /* CONFIG_ARCH_MT7623 */ ++ else if (ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info2.DDONE_bit == 1) { ++ rx_ring = ei_local->rx_ring0; ++ rx_dma_owner_idx = rx_dma_owner_idx0; ++ // printk("rx_dma_owner_idx0=%x\n",rx_dma_owner_idx0); ++ rx_ring_no=0; ++ } else { ++ break; ++ } ++#else ++ ++ if (ei_local->rx_ring0[rx_dma_owner_idx0].rxd_info2.DDONE_bit == 1) { ++ rx_ring = ei_local->rx_ring0; ++ rx_dma_owner_idx = rx_dma_owner_idx0; ++ } else { ++ break; ++ } ++#endif ++ ++#if defined (CONFIG_32B_DESC) ++ prefetch(&rx_ring[(rx_dma_owner_idx + 1) % NUM_RX_DESC]); ++#endif ++ /* skb processing */ ++#if defined (CONFIG_RAETH_HW_LRO) ++ length = (rx_ring[rx_dma_owner_idx].rxd_info2.PLEN1 << 14) | rx_ring[rx_dma_owner_idx].rxd_info2.PLEN0; ++#else ++ length = rx_ring[rx_dma_owner_idx].rxd_info2.PLEN0; ++#endif /* CONFIG_RAETH_HW_LRO */ ++ ++#if defined (CONFIG_ARCH_MT7623) ++ dma_unmap_single(NULL, rx_ring[rx_dma_owner_idx].rxd_info1.PDP0, length, DMA_FROM_DEVICE); ++#endif ++ ++#if defined (CONFIG_RAETH_HW_LRO) ++ if(rx_ring_no==3) { ++ rx_skb = ei_local->netrx3_skbuf[rx_dma_owner_idx]; ++ rx_skb->data = ei_local->netrx3_skbuf[rx_dma_owner_idx]->data; ++ } ++ else if(rx_ring_no==2) { ++ rx_skb = ei_local->netrx2_skbuf[rx_dma_owner_idx]; ++ rx_skb->data = ei_local->netrx2_skbuf[rx_dma_owner_idx]->data; ++ } ++ else if(rx_ring_no==1) { ++ rx_skb = ei_local->netrx1_skbuf[rx_dma_owner_idx]; ++ rx_skb->data = ei_local->netrx1_skbuf[rx_dma_owner_idx]->data; ++ } ++ else { ++ rx_skb = ei_local->netrx0_skbuf[rx_dma_owner_idx]; ++ rx_skb->data = ei_local->netrx0_skbuf[rx_dma_owner_idx]->data; ++ } ++ #if defined(CONFIG_RAETH_PDMA_DVT) ++ raeth_pdma_lro_dvt( rx_ring_no, ei_local, rx_dma_owner_idx ); ++ #endif /* CONFIG_RAETH_PDMA_DVT */ ++#elif defined (CONFIG_RAETH_MULTIPLE_RX_RING) ++ if(rx_ring_no==1) { ++ rx_skb = ei_local->netrx1_skbuf[rx_dma_owner_idx]; ++ rx_skb->data = ei_local->netrx1_skbuf[rx_dma_owner_idx]->data; ++ } ++#if defined(CONFIG_ARCH_MT7623) ++ else if(rx_ring_no==2) { ++ rx_skb = ei_local->netrx2_skbuf[rx_dma_owner_idx]; ++ rx_skb->data = ei_local->netrx2_skbuf[rx_dma_owner_idx]->data; ++ } ++ else if(rx_ring_no==3) { ++ rx_skb = ei_local->netrx3_skbuf[rx_dma_owner_idx]; ++ rx_skb->data = ei_local->netrx3_skbuf[rx_dma_owner_idx]->data; ++ } ++#endif /* CONFIG_ARCH_MT7623 */ ++ else { ++ rx_skb = ei_local->netrx0_skbuf[rx_dma_owner_idx]; ++ rx_skb->data = ei_local->netrx0_skbuf[rx_dma_owner_idx]->data; ++ } ++ #if defined(CONFIG_RAETH_PDMA_DVT) ++ raeth_pdma_lro_dvt( rx_ring_no, ei_local, rx_dma_owner_idx ); ++ #endif /* CONFIG_RAETH_PDMA_DVT */ ++#else ++ rx_skb = ei_local->netrx0_skbuf[rx_dma_owner_idx]; ++ rx_skb->data = ei_local->netrx0_skbuf[rx_dma_owner_idx]->data; ++ #if defined(CONFIG_RAETH_PDMA_DVT) ++ raeth_pdma_rx_desc_dvt( ei_local, rx_dma_owner_idx0 ); ++ #endif /* CONFIG_RAETH_PDMA_DVT */ ++#endif ++ rx_skb->len = length; ++/*TODO*/ ++#if defined (CONFIG_RAETH_SCATTER_GATHER_RX_DMA) ++ rx_skb->data += NET_IP_ALIGN; ++#endif ++ rx_skb->tail = rx_skb->data + length; ++ ++#ifdef CONFIG_PSEUDO_SUPPORT ++ if(rx_ring[rx_dma_owner_idx].rxd_info4.SP == 2) { ++ if(ei_local->PseudoDev!=NULL) { ++ rx_skb->dev = ei_local->PseudoDev; ++ rx_skb->protocol = eth_type_trans(rx_skb,ei_local->PseudoDev); ++ }else { ++ printk("ERROR: PseudoDev is still not initialize but receive packet from GMAC2\n"); ++ } ++ }else{ ++ rx_skb->dev = dev; ++ rx_skb->protocol = eth_type_trans(rx_skb,dev); ++ } ++#else ++ rx_skb->dev = dev; ++ rx_skb->protocol = eth_type_trans(rx_skb,dev); ++#endif ++ ++#ifdef CONFIG_RAETH_CHECKSUM_OFFLOAD ++#if defined (CONFIG_PDMA_NEW) ++ if(rx_ring[rx_dma_owner_idx].rxd_info4.L4VLD) { ++ rx_skb->ip_summed = CHECKSUM_UNNECESSARY; ++ }else { ++ rx_skb->ip_summed = CHECKSUM_NONE; ++ } ++#else ++ if(rx_ring[rx_dma_owner_idx].rxd_info4.IPFVLD_bit) { ++ rx_skb->ip_summed = CHECKSUM_UNNECESSARY; ++ }else { ++ rx_skb->ip_summed = CHECKSUM_NONE; ++ } ++#endif ++#else ++ rx_skb->ip_summed = CHECKSUM_NONE; ++#endif ++ ++#if defined(CONFIG_RA_CLASSIFIER)||defined(CONFIG_RA_CLASSIFIER_MODULE) ++ /* Qwert+ ++ */ ++ if(ra_classifier_hook_rx!= NULL) ++ { ++#if defined(CONFIG_RALINK_EXTERNAL_TIMER) ++ ra_classifier_hook_rx(rx_skb, (*((volatile u32 *)(0xB0000D08))&0x0FFFF)); ++#else ++ ra_classifier_hook_rx(rx_skb, read_c0_count()); ++#endif ++ } ++#endif /* CONFIG_RA_CLASSIFIER */ ++ ++#if defined (CONFIG_RA_HW_NAT) || defined (CONFIG_RA_HW_NAT_MODULE) ++ if(ra_sw_nat_hook_rx != NULL) { ++ FOE_MAGIC_TAG(rx_skb)= FOE_MAGIC_GE; ++ *(uint32_t *)(FOE_INFO_START_ADDR(rx_skb)+2) = *(uint32_t *)&rx_ring[rx_dma_owner_idx].rxd_info4; ++ FOE_ALG(rx_skb) = 0; ++ } ++#endif ++ ++ /* We have to check the free memory size is big enough ++ * before pass the packet to cpu*/ ++#if defined (CONFIG_RAETH_SKB_RECYCLE_2K) ++#if defined (CONFIG_RAETH_HW_LRO) ++ if( rx_ring != ei_local->rx_ring0 ) ++ skb = __dev_alloc_skb(MAX_LRO_RX_LENGTH + NET_IP_ALIGN, GFP_ATOMIC); ++ else ++#endif /* CONFIG_RAETH_HW_LRO */ ++ skb = skbmgr_dev_alloc_skb2k(); ++#else ++#if defined (CONFIG_RAETH_HW_LRO) ++ if( rx_ring != ei_local->rx_ring0 ) ++ skb = __dev_alloc_skb(MAX_LRO_RX_LENGTH + NET_IP_ALIGN, GFP_ATOMIC); ++ else ++#endif /* CONFIG_RAETH_HW_LRO */ ++ skb = __dev_alloc_skb(MAX_RX_LENGTH + NET_IP_ALIGN, GFP_ATOMIC); ++#endif ++ ++ if (unlikely(skb == NULL)) ++ { ++ printk(KERN_ERR "skb not available...\n"); ++#ifdef CONFIG_PSEUDO_SUPPORT ++ if (rx_ring[rx_dma_owner_idx].rxd_info4.SP == 2) { ++ if (ei_local->PseudoDev != NULL) { ++ pAd = netdev_priv(ei_local->PseudoDev); ++ pAd->stat.rx_dropped++; ++ } ++ } else ++#endif ++ ei_local->stat.rx_dropped++; ++ bReschedule = 1; ++ break; ++ } ++#if !defined (CONFIG_RAETH_SCATTER_GATHER_RX_DMA) ++ skb_reserve(skb, NET_IP_ALIGN); ++#endif ++ ++#if defined (CONFIG_RAETH_SPECIAL_TAG) ++ // port0: 0x8100 => 0x8100 0001 ++ // port1: 0x8101 => 0x8100 0002 ++ // port2: 0x8102 => 0x8100 0003 ++ // port3: 0x8103 => 0x8100 0004 ++ // port4: 0x8104 => 0x8100 0005 ++ // port5: 0x8105 => 0x8100 0006 ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,21) ++ veth = (struct vlan_ethhdr *)(rx_skb->mac_header); ++#else ++ veth = (struct vlan_ethhdr *)(rx_skb->mac.raw); ++#endif ++ /*donot check 0x81 due to MT7530 SPEC*/ ++ //if((veth->h_vlan_proto & 0xFF) == 0x81) ++ { ++ veth->h_vlan_TCI = htons( (((veth->h_vlan_proto >> 8) & 0xF) + 1) ); ++ rx_skb->protocol = veth->h_vlan_proto = htons(ETH_P_8021Q); ++ } ++#endif ++ ++/* ra_sw_nat_hook_rx return 1 --> continue ++ * ra_sw_nat_hook_rx return 0 --> FWD & without netif_rx ++ */ ++#if !defined(CONFIG_RA_NAT_NONE) ++ if((ra_sw_nat_hook_rx == NULL) || ++ (ra_sw_nat_hook_rx!= NULL && ra_sw_nat_hook_rx(rx_skb))) ++#endif ++ { ++#if defined (CONFIG_RALINK_RT3052_MP2) ++ if(mcast_rx(rx_skb)==0) { ++ kfree_skb(rx_skb); ++ }else ++#endif ++#if defined (CONFIG_RAETH_LRO) ++ if (rx_skb->ip_summed == CHECKSUM_UNNECESSARY) { ++ lro_receive_skb(&ei_local->lro_mgr, rx_skb, NULL); ++ //LroStatsUpdate(&ei_local->lro_mgr,0); ++ } else ++#endif ++#ifdef CONFIG_RAETH_NAPI ++ netif_receive_skb(rx_skb); ++#else ++#ifdef CONFIG_RAETH_HW_VLAN_RX ++ if(ei_local->vlgrp && rx_ring[rx_dma_owner_idx].rxd_info2.TAG) { ++ vlan_hwaccel_rx(rx_skb, ei_local->vlgrp, rx_ring[rx_dma_owner_idx].rxd_info3.VID); ++ } else { ++ netif_rx(rx_skb); ++ } ++#else ++#ifdef CONFIG_RAETH_CPU_LOOPBACK ++ skb_push(rx_skb,ETH_HLEN); ++ ei_start_xmit(rx_skb, dev, 1); ++#else ++ netif_rx(rx_skb); ++#endif ++#endif ++#endif ++ } ++ ++#ifdef CONFIG_PSEUDO_SUPPORT ++ if (rx_ring[rx_dma_owner_idx].rxd_info4.SP == 2) { ++ if (ei_local->PseudoDev != NULL) { ++ pAd = netdev_priv(ei_local->PseudoDev); ++ pAd->stat.rx_packets++; ++ pAd->stat.rx_bytes += length; ++ } ++ } else ++#endif ++ { ++ ei_local->stat.rx_packets++; ++ ei_local->stat.rx_bytes += length; ++ } ++ ++ ++#if defined (CONFIG_RAETH_SCATTER_GATHER_RX_DMA) ++#if defined (CONFIG_RAETH_HW_LRO) ++ if( rx_ring != ei_local->rx_ring0 ){ ++ rx_ring[rx_dma_owner_idx].rxd_info2.PLEN0 = SET_ADMA_RX_LEN0(MAX_LRO_RX_LENGTH); ++ rx_ring[rx_dma_owner_idx].rxd_info2.PLEN1 = SET_ADMA_RX_LEN1(MAX_LRO_RX_LENGTH >> 14); ++ } ++ else ++#endif /* CONFIG_RAETH_HW_LRO */ ++ rx_ring[rx_dma_owner_idx].rxd_info2.PLEN0 = MAX_RX_LENGTH; ++ rx_ring[rx_dma_owner_idx].rxd_info2.LS0 = 0; ++#endif ++ rx_ring[rx_dma_owner_idx].rxd_info2.DDONE_bit = 0; ++#if defined (CONFIG_RAETH_HW_LRO) ++ if( rx_ring != ei_local->rx_ring0 ) ++ rx_ring[rx_dma_owner_idx].rxd_info1.PDP0 = dma_map_single(NULL, skb->data, MAX_LRO_RX_LENGTH, PCI_DMA_FROMDEVICE); ++ else ++#endif /* CONFIG_RAETH_HW_LRO */ ++ rx_ring[rx_dma_owner_idx].rxd_info1.PDP0 = dma_map_single(NULL, skb->data, MAX_RX_LENGTH, PCI_DMA_FROMDEVICE); ++#ifdef CONFIG_32B_DESC ++ dma_cache_sync(NULL, &rx_ring[rx_dma_owner_idx], sizeof(struct PDMA_rxdesc), DMA_TO_DEVICE); ++#endif ++ /* Move point to next RXD which wants to alloc*/ ++#if defined (CONFIG_RAETH_HW_LRO) ++ if(rx_ring_no==3) { ++ sysRegWrite(RAETH_RX_CALC_IDX3, rx_dma_owner_idx); ++ ei_local->netrx3_skbuf[rx_dma_owner_idx] = skb; ++ } ++ else if(rx_ring_no==2) { ++ sysRegWrite(RAETH_RX_CALC_IDX2, rx_dma_owner_idx); ++ ei_local->netrx2_skbuf[rx_dma_owner_idx] = skb; ++ } ++ else if(rx_ring_no==1) { ++ sysRegWrite(RAETH_RX_CALC_IDX1, rx_dma_owner_idx); ++ ei_local->netrx1_skbuf[rx_dma_owner_idx] = skb; ++ } ++ else if(rx_ring_no==0) { ++ sysRegWrite(RAETH_RX_CALC_IDX0, rx_dma_owner_idx); ++ ei_local->netrx0_skbuf[rx_dma_owner_idx] = skb; ++ } ++#elif defined (CONFIG_RAETH_MULTIPLE_RX_RING) ++ if(rx_ring_no==0) { ++ sysRegWrite(RAETH_RX_CALC_IDX0, rx_dma_owner_idx); ++ ei_local->netrx0_skbuf[rx_dma_owner_idx] = skb; ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ rx_calc_idx0 = rx_dma_owner_idx; ++#endif ++ } ++#if defined(CONFIG_ARCH_MT7623) ++ else if(rx_ring_no==3) { ++ sysRegWrite(RAETH_RX_CALC_IDX3, rx_dma_owner_idx); ++ ei_local->netrx3_skbuf[rx_dma_owner_idx] = skb; ++ } ++ else if(rx_ring_no==2) { ++ sysRegWrite(RAETH_RX_CALC_IDX2, rx_dma_owner_idx); ++ ei_local->netrx2_skbuf[rx_dma_owner_idx] = skb; ++ } ++#endif /* CONFIG_ARCH_MT7623 */ ++ else { ++ sysRegWrite(RAETH_RX_CALC_IDX1, rx_dma_owner_idx); ++ ei_local->netrx1_skbuf[rx_dma_owner_idx] = skb; ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ rx_calc_idx1 = rx_dma_owner_idx; ++#endif ++ } ++#else ++ sysRegWrite(RAETH_RX_CALC_IDX0, rx_dma_owner_idx); ++ ei_local->netrx0_skbuf[rx_dma_owner_idx] = skb; ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ rx_calc_idx0 = rx_dma_owner_idx; ++#endif ++#endif ++ ++ ++ /* Update to Next packet point that was received. ++ */ ++#if defined (CONFIG_RAETH_HW_LRO) ++ if(rx_ring_no==3) ++ rx_dma_owner_lro3 = (sysRegRead(RAETH_RX_CALC_IDX3) + 1) % NUM_LRO_RX_DESC; ++ else if(rx_ring_no==2) ++ rx_dma_owner_lro2 = (sysRegRead(RAETH_RX_CALC_IDX2) + 1) % NUM_LRO_RX_DESC; ++ else if(rx_ring_no==1) ++ rx_dma_owner_lro1 = (sysRegRead(RAETH_RX_CALC_IDX1) + 1) % NUM_LRO_RX_DESC; ++ else if(rx_ring_no==0) ++ rx_dma_owner_idx0 = (sysRegRead(RAETH_RX_CALC_IDX0) + 1) % NUM_RX_DESC; ++ else { ++ } ++#elif defined (CONFIG_RAETH_MULTIPLE_RX_RING) ++ if(rx_ring_no==0) { ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ rx_dma_owner_idx0 = (rx_dma_owner_idx + 1) % NUM_RX_DESC; ++#else ++ rx_dma_owner_idx0 = (sysRegRead(RAETH_RX_CALC_IDX0) + 1) % NUM_RX_DESC; ++#endif ++#if defined(CONFIG_ARCH_MT7623) ++ }else if(rx_ring_no==3) { ++ rx_dma_owner_idx3 = (sysRegRead(RAETH_RX_CALC_IDX3) + 1) % NUM_RX_DESC; ++ }else if(rx_ring_no==2) { ++ rx_dma_owner_idx2 = (sysRegRead(RAETH_RX_CALC_IDX2) + 1) % NUM_RX_DESC; ++#endif /* CONFIG_ARCH_MT7623 */ ++ }else { ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ rx_dma_owner_idx1 = (rx_dma_owner_idx + 1) % NUM_RX_DESC; ++#else ++ rx_dma_owner_idx1 = (sysRegRead(RAETH_RX_CALC_IDX1) + 1) % NUM_RX_DESC; ++#endif ++ } ++#else ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ rx_dma_owner_idx0 = (rx_dma_owner_idx + 1) % NUM_RX_DESC; ++#else ++ rx_dma_owner_idx0 = (sysRegRead(RAETH_RX_CALC_IDX0) + 1) % NUM_RX_DESC; ++#endif ++#endif ++ } /* for */ ++ ++#if defined (CONFIG_RAETH_LRO) ++ if (lro_flush_needed) { ++ //LroStatsUpdate(&ei_local->lro_mgr,1); ++ lro_flush_all(&ei_local->lro_mgr); ++ lro_flush_needed = 0; ++ } ++#endif ++ return bReschedule; ++} ++ ++ ++/////////////////////////////////////////////////////////////////// ++///// ++///// ra_get_stats - gather packet information for management plane ++///// ++///// Pass net_device_stats to the upper layer. ++///// ++///// ++///// RETURNS: pointer to net_device_stats ++/////////////////////////////////////////////////////////////////// ++ ++struct net_device_stats *ra_get_stats(struct net_device *dev) ++{ ++ END_DEVICE *ei_local = netdev_priv(dev); ++ return &ei_local->stat; ++} ++ ++#if defined (CONFIG_RT_3052_ESW) ++void kill_sig_workq(struct work_struct *work) ++{ ++ struct file *fp; ++ char pid[8]; ++ struct task_struct *p = NULL; ++ ++ //read udhcpc pid from file, and send signal USR2,USR1 to get a new IP ++ fp = filp_open("/var/run/udhcpc.pid", O_RDONLY, 0); ++ if (IS_ERR(fp)) ++ return; ++ ++ if (fp->f_op && fp->f_op->read) { ++ if (fp->f_op->read(fp, pid, 8, &fp->f_pos) > 0) { ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ p = pid_task(find_get_pid(simple_strtoul(pid, NULL, 10)), PIDTYPE_PID); ++#else ++ p = find_task_by_pid(simple_strtoul(pid, NULL, 10)); ++#endif ++ ++ if (NULL != p) { ++ send_sig(SIGUSR2, p, 0); ++ send_sig(SIGUSR1, p, 0); ++ } ++ } ++ } ++ filp_close(fp, NULL); ++ ++} ++#endif ++ ++ ++/////////////////////////////////////////////////////////////////// ++///// ++///// ra2880Recv - process the next incoming packet ++///// ++///// Handle one incoming packet. The packet is checked for errors and sent ++///// to the upper layer. ++///// ++///// RETURNS: OK on success or ERROR. ++/////////////////////////////////////////////////////////////////// ++ ++#ifndef CONFIG_RAETH_NAPI ++#if defined WORKQUEUE_BH || defined (TASKLET_WORKQUEUE_SW) ++void ei_receive_workq(struct work_struct *work) ++#else ++void ei_receive(unsigned long unused) // device structure ++#endif // WORKQUEUE_BH // ++{ ++ struct net_device *dev = dev_raether; ++ END_DEVICE *ei_local = netdev_priv(dev); ++ unsigned long reg_int_mask=0; ++ int bReschedule=0; ++ ++ ++ if(tx_ring_full==0){ ++ bReschedule = rt2880_eth_recv(dev); ++ if(bReschedule) ++ { ++#ifdef WORKQUEUE_BH ++ schedule_work(&ei_local->rx_wq); ++#else ++#if defined (TASKLET_WORKQUEUE_SW) ++ if (working_schedule == 1) ++ schedule_work(&ei_local->rx_wq); ++ else ++#endif ++ tasklet_hi_schedule(&ei_local->rx_tasklet); ++#endif // WORKQUEUE_BH // ++ }else{ ++ reg_int_mask=sysRegRead(RAETH_FE_INT_ENABLE); ++#if defined(DELAY_INT) ++ sysRegWrite(RAETH_FE_INT_ENABLE, reg_int_mask| RX_DLY_INT); ++#else ++ sysRegWrite(RAETH_FE_INT_ENABLE, (reg_int_mask | RX_DONE_INT0 | RX_DONE_INT1 | RX_DONE_INT2 | RX_DONE_INT3)); ++#endif ++#ifdef CONFIG_RAETH_QDMA ++ reg_int_mask=sysRegRead(QFE_INT_ENABLE); ++#if defined(DELAY_INT) ++ sysRegWrite(QFE_INT_ENABLE, reg_int_mask| RX_DLY_INT); ++#else ++ sysRegWrite(QFE_INT_ENABLE, (reg_int_mask | RX_DONE_INT0 | RX_DONE_INT1)); ++#endif ++ ++#endif ++ ++ } ++ }else{ ++#ifdef WORKQUEUE_BH ++ schedule_work(&ei_local->rx_wq); ++#else ++#if defined (TASKLET_WORKQUEUE_SW) ++ if (working_schedule == 1) ++ schedule_work(&ei_local->rx_wq); ++ else ++#endif ++ tasklet_schedule(&ei_local->rx_tasklet); ++#endif // WORKQUEUE_BH // ++ } ++} ++#endif ++ ++#if defined (CONFIG_RAETH_HW_LRO) ++void ei_hw_lro_auto_adj(unsigned int index, END_DEVICE* ei_local) ++{ ++ unsigned int entry; ++ unsigned int pkt_cnt; ++ unsigned int tick_cnt; ++ unsigned int duration_us; ++ unsigned int byte_cnt; ++ ++ /* read packet count statitics of the auto-learn table */ ++ entry = index + 68; ++ sysRegWrite( PDMA_FE_ALT_CF8, entry ); ++ pkt_cnt = sysRegRead(PDMA_FE_ALT_SGL_CFC) & 0xfff; ++ tick_cnt = (sysRegRead(PDMA_FE_ALT_SGL_CFC) >> 16) & 0xffff; ++#if defined (CONFIG_RAETH_HW_LRO_AUTO_ADJ_DBG) ++ printk("[HW LRO] ei_hw_lro_auto_adj(): pkt_cnt[%d]=%d, tick_cnt[%d]=%d\n", index, pkt_cnt, index, tick_cnt); ++ printk("[HW LRO] ei_hw_lro_auto_adj(): packet_interval[%d]=%d (ticks/pkt)\n", index, tick_cnt/pkt_cnt); ++#endif ++ ++ /* read byte count statitics of the auto-learn table */ ++ entry = index + 64; ++ sysRegWrite( PDMA_FE_ALT_CF8, entry ); ++ byte_cnt = sysRegRead(PDMA_FE_ALT_SGL_CFC); ++#if defined (CONFIG_RAETH_HW_LRO_AUTO_ADJ_DBG) ++ printk("[HW LRO] ei_hw_lro_auto_adj(): byte_cnt[%d]=%d\n", index, byte_cnt); ++#endif ++ ++ /* calculate the packet interval of the rx flow */ ++ duration_us = tick_cnt * HW_LRO_TIMER_UNIT; ++ ei_local->hw_lro_pkt_interval[index - 1] = (duration_us/pkt_cnt) * ei_local->hw_lro_alpha / 100; ++#if defined (CONFIG_RAETH_HW_LRO_AUTO_ADJ_DBG) ++ printk("[HW LRO] ei_hw_lro_auto_adj(): packet_interval[%d]=%d (20us)\n", index, duration_us/pkt_cnt); ++#endif ++ ++ if ( !ei_local->hw_lro_fix_setting ){ ++ /* adjust age_time, agg_time for the lro ring */ ++ if(ei_local->hw_lro_pkt_interval[index - 1] > 0){ ++ SET_PDMA_RXRING_AGE_TIME(index, (ei_local->hw_lro_pkt_interval[index - 1] * HW_LRO_MAX_AGG_CNT)); ++ SET_PDMA_RXRING_AGG_TIME(index, (ei_local->hw_lro_pkt_interval[index - 1] * HW_LRO_AGG_DELTA)); ++ } ++ else{ ++ SET_PDMA_RXRING_AGE_TIME(index, HW_LRO_MAX_AGG_CNT); ++ SET_PDMA_RXRING_AGG_TIME(index, HW_LRO_AGG_DELTA); ++ } ++ } ++} ++ ++void ei_hw_lro_workq(struct work_struct *work) ++{ ++ END_DEVICE *ei_local; ++ unsigned int reg_int_val; ++ unsigned int reg_int_mask; ++ ++ ei_local = container_of(work, struct end_device, hw_lro_wq); ++ ++ reg_int_val = sysRegRead(RAETH_FE_INT_STATUS); ++#if defined (CONFIG_RAETH_HW_LRO_AUTO_ADJ_DBG) ++ printk("[HW LRO] ei_hw_lro_workq(): RAETH_FE_INT_STATUS=0x%x\n", reg_int_val); ++#endif ++ if((reg_int_val & ALT_RPLC_INT3)){ ++#if defined (CONFIG_RAETH_HW_LRO_AUTO_ADJ_DBG) ++ printk("[HW LRO] ALT_RPLC_INT3 occurred!\n"); ++#endif ++ sysRegWrite(RAETH_FE_INT_STATUS, ALT_RPLC_INT3); ++ ei_hw_lro_auto_adj(3, ei_local); ++ } ++ if((reg_int_val & ALT_RPLC_INT2)){ ++#if defined (CONFIG_RAETH_HW_LRO_AUTO_ADJ_DBG) ++ printk("[HW LRO] ALT_RPLC_INT2 occurred!\n"); ++#endif ++ sysRegWrite(RAETH_FE_INT_STATUS, ALT_RPLC_INT2); ++ ei_hw_lro_auto_adj(2, ei_local); ++ } ++ if((reg_int_val & ALT_RPLC_INT1)){ ++#if defined (CONFIG_RAETH_HW_LRO_AUTO_ADJ_DBG) ++ printk("[HW LRO] ALT_RPLC_INT1 occurred!\n"); ++#endif ++ sysRegWrite(RAETH_FE_INT_STATUS, ALT_RPLC_INT1); ++ ei_hw_lro_auto_adj(1, ei_local); ++ } ++ ++ /* unmask interrupts of rx flow to hw lor rings */ ++ reg_int_mask = sysRegRead(RAETH_FE_INT_ENABLE); ++ sysRegWrite(RAETH_FE_INT_ENABLE, reg_int_mask | ALT_RPLC_INT3 | ALT_RPLC_INT2 | ALT_RPLC_INT1); ++} ++#endif /* CONFIG_RAETH_HW_LRO */ ++ ++#ifdef CONFIG_RAETH_NAPI ++static int ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++raeth_clean(struct napi_struct *napi, int budget) ++#else ++raeth_clean(struct net_device *netdev, int *budget) ++#endif ++{ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ struct net_device *netdev=dev_raether; ++ int work_to_do = budget; ++#else ++ int work_to_do = min(*budget, netdev->quota); ++#endif ++ END_DEVICE *ei_local =netdev_priv(netdev); ++ int work_done = 0; ++ unsigned long reg_int_mask=0; ++ ++ ei_xmit_housekeeping(0); ++ ++ rt2880_eth_recv(netdev, &work_done, work_to_do); ++ ++ /* this could control when to re-enable interrupt, 0-> mean never enable interrupt*/ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,35) ++ *budget -= work_done; ++ netdev->quota -= work_done; ++#endif ++ /* if no Tx and not enough Rx work done, exit the polling mode */ ++ if(( (work_done < work_to_do)) || !netif_running(netdev)) { ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ napi_complete(&ei_local->napi); ++#else ++ netif_rx_complete(netdev); ++#endif ++ atomic_dec_and_test(&ei_local->irq_sem); ++ ++ sysRegWrite(RAETH_FE_INT_STATUS, RAETH_FE_INT_ALL); // ack all fe interrupts ++ reg_int_mask=sysRegRead(RAETH_FE_INT_ENABLE); ++ ++#ifdef DELAY_INT ++ sysRegWrite(RAETH_FE_INT_ENABLE, reg_int_mask |RAETH_FE_INT_DLY_INIT); // init delay interrupt only ++#else ++ sysRegWrite(RAETH_FE_INT_ENABLE,reg_int_mask | RAETH_FE_INT_SETTING); ++#endif ++ ++#ifdef CONFIG_RAETH_QDMA ++ sysRegWrite(QFE_INT_STATUS, QFE_INT_ALL); ++ reg_int_mask=sysRegRead(QFE_INT_ENABLE); ++#ifdef DELAY_INT ++ sysRegWrite(QFE_INT_ENABLE, reg_int_mask |QFE_INT_DLY_INIT); // init delay interrupt only ++#else ++ sysRegWrite(QFE_INT_ENABLE,reg_int_mask | (RX_DONE_INT0 | RX_DONE_INT1 | RLS_DONE_INT)); ++#endif ++#endif // CONFIG_RAETH_QDMA // ++ ++ return 0; ++ } ++ ++ return 1; ++} ++ ++#endif ++ ++ ++void gsw_delay_setting(void) ++{ ++#if defined (CONFIG_GE_RGMII_INTERNAL_P0_AN) || defined (CONFIG_GE_RGMII_INTERNAL_P4_AN) ++ END_DEVICE *ei_local = netdev_priv(dev_raether); ++ int reg_int_val = 0; ++ int link_speed = 0; ++ ++ reg_int_val = sysRegRead(FE_INT_STATUS2); ++#if defined (CONFIG_RALINK_MT7621) ++ if( reg_int_val & BIT(25)) ++ { ++ if(sysRegRead(RALINK_ETH_SW_BASE+0x0208) & 0x1) // link up ++ { ++ link_speed = (sysRegRead(RALINK_ETH_SW_BASE+0x0208)>>2 & 0x3); ++ if(link_speed == 1) ++ { ++ // delay setting for 100M ++ if((sysRegRead(0xbe00000c)&0xFFFF)==0x0101) ++ mii_mgr_write(31, 0x7b00, 8); ++ printk("MT7621 GE2 link rate to 100M\n"); ++ } else ++ { ++ //delay setting for 10/1000M ++ if((sysRegRead(0xbe00000c)&0xFFFF)==0x0101) ++ mii_mgr_write(31, 0x7b00, 0x102); ++ printk("MT7621 GE2 link rate to 10M/1G\n"); ++ } ++ schedule_work(&ei_local->kill_sig_wq); ++ } ++ } ++#endif ++ sysRegWrite(FE_INT_STATUS2, reg_int_val); ++#endif ++} ++ ++/** ++ * ei_interrupt - handle controler interrupt ++ * ++ * This routine is called at interrupt level in response to an interrupt from ++ * the controller. ++ * ++ * RETURNS: N/A. ++ */ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,21) ++static irqreturn_t ei_interrupt(int irq, void *dev_id) ++#else ++static irqreturn_t ei_interrupt(int irq, void *dev_id, struct pt_regs * regs) ++#endif ++{ ++#if !defined(CONFIG_RAETH_NAPI) ++ unsigned long reg_int_val; ++ unsigned long reg_int_mask=0; ++ unsigned int recv = 0; ++ unsigned int transmit __maybe_unused = 0; ++ unsigned long flags; ++#endif ++ ++ struct net_device *dev = (struct net_device *) dev_id; ++ END_DEVICE *ei_local = netdev_priv(dev); ++ ++ //Qwert ++ /* ++ unsigned long old,cur,dcycle; ++ static int cnt = 0; ++ static unsigned long max_dcycle = 0,tcycle = 0; ++ old = read_c0_count(); ++ */ ++ if (dev == NULL) ++ { ++ printk (KERN_ERR "net_interrupt(): irq %x for unknown device.\n", IRQ_ENET0); ++ return IRQ_NONE; ++ } ++ ++#ifdef CONFIG_RAETH_NAPI ++ gsw_delay_setting(); ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ if(napi_schedule_prep(&ei_local->napi)) { ++#else ++ if(netif_rx_schedule_prep(dev)) { ++#endif ++ atomic_inc(&ei_local->irq_sem); ++ sysRegWrite(RAETH_FE_INT_ENABLE, 0); ++#ifdef CONFIG_RAETH_QDMA ++ sysRegWrite(QFE_INT_ENABLE, 0); ++#endif ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ __napi_schedule(&ei_local->napi); ++#else ++ __netif_rx_schedule(dev); ++#endif ++ } ++#else ++ ++ spin_lock_irqsave(&(ei_local->page_lock), flags); ++ reg_int_val = sysRegRead(RAETH_FE_INT_STATUS); ++#ifdef CONFIG_RAETH_QDMA ++ reg_int_val |= sysRegRead(QFE_INT_STATUS); ++#endif ++#if defined (DELAY_INT) ++ if((reg_int_val & RX_DLY_INT)) ++ recv = 1; ++ ++ if (reg_int_val & RAETH_TX_DLY_INT) ++ transmit = 1; ++ ++#if defined(CONFIG_RAETH_PDMA_DVT) ++ raeth_pdma_lro_dly_int_dvt(); ++#endif /* CONFIG_RAETH_PDMA_DVT */ ++ ++#else ++ if((reg_int_val & (RX_DONE_INT0 | RX_DONE_INT3 | RX_DONE_INT2 | RX_DONE_INT1))) ++ recv = 1; ++ ++#if defined (CONFIG_RAETH_MULTIPLE_RX_RING) ++#if defined(CONFIG_ARCH_MT7623) ++ if((reg_int_val & RX_DONE_INT3)) ++ recv = 3; ++ if((reg_int_val & RX_DONE_INT2)) ++ recv = 2; ++#endif /* CONFIG_ARCH_MT7623 */ ++ if((reg_int_val & RX_DONE_INT1)) ++ recv = 1; ++#endif ++ ++ if (reg_int_val & RAETH_TX_DONE_INT0) ++ transmit |= RAETH_TX_DONE_INT0; ++#if defined (CONFIG_RAETH_QOS) ++ if (reg_int_val & TX_DONE_INT1) ++ transmit |= TX_DONE_INT1; ++ if (reg_int_val & TX_DONE_INT2) ++ transmit |= TX_DONE_INT2; ++ if (reg_int_val & TX_DONE_INT3) ++ transmit |= TX_DONE_INT3; ++#endif //CONFIG_RAETH_QOS ++ ++#endif //DELAY_INT ++ ++#if defined (DELAY_INT) ++ sysRegWrite(RAETH_FE_INT_STATUS, RAETH_FE_INT_DLY_INIT); ++#else ++ sysRegWrite(RAETH_FE_INT_STATUS, RAETH_FE_INT_ALL); ++#endif ++#ifdef CONFIG_RAETH_QDMA ++#if defined (DELAY_INT) ++ sysRegWrite(QFE_INT_STATUS, QFE_INT_DLY_INIT); ++#else ++ sysRegWrite(QFE_INT_STATUS, QFE_INT_ALL); ++#endif ++#endif ++ ++#if defined (CONFIG_RAETH_HW_LRO) ++ if( reg_int_val & (ALT_RPLC_INT3 | ALT_RPLC_INT2 | ALT_RPLC_INT1) ){ ++ /* mask interrupts of rx flow to hw lor rings */ ++ reg_int_mask = sysRegRead(RAETH_FE_INT_ENABLE); ++ sysRegWrite(RAETH_FE_INT_ENABLE, reg_int_mask & ~(ALT_RPLC_INT3 | ALT_RPLC_INT2 | ALT_RPLC_INT1)); ++ schedule_work(&ei_local->hw_lro_wq); ++ } ++#endif /* CONFIG_RAETH_HW_LRO */ ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(3,10,0) ++ if(transmit) ++ ei_xmit_housekeeping(0); ++#else ++ ei_xmit_housekeeping(0); ++#endif ++ ++ if (((recv == 1) || (pending_recv ==1)) && (tx_ring_full==0)) ++ { ++ reg_int_mask = sysRegRead(RAETH_FE_INT_ENABLE); ++#if defined (DELAY_INT) ++ sysRegWrite(RAETH_FE_INT_ENABLE, reg_int_mask & ~(RX_DLY_INT)); ++#else ++ sysRegWrite(RAETH_FE_INT_ENABLE, reg_int_mask & ~(RX_DONE_INT0 | RX_DONE_INT1 | RX_DONE_INT2 | RX_DONE_INT3)); ++#endif //DELAY_INT ++#ifdef CONFIG_RAETH_QDMA ++ reg_int_mask = sysRegRead(QFE_INT_ENABLE); ++#if defined (DELAY_INT) ++ sysRegWrite(QFE_INT_ENABLE, reg_int_mask & ~(RX_DLY_INT)); ++#else ++ sysRegWrite(QFE_INT_ENABLE, reg_int_mask & ~(RX_DONE_INT0 | RX_DONE_INT1 | RX_DONE_INT2 | RX_DONE_INT3)); ++#endif //DELAY_INT ++#endif ++ ++ pending_recv=0; ++#ifdef WORKQUEUE_BH ++ schedule_work(&ei_local->rx_wq); ++#else ++#if defined (TASKLET_WORKQUEUE_SW) ++ if (working_schedule == 1) ++ schedule_work(&ei_local->rx_wq); ++ else ++#endif ++ tasklet_hi_schedule(&ei_local->rx_tasklet); ++#endif // WORKQUEUE_BH // ++ } ++ else if (recv == 1 && tx_ring_full==1) ++ { ++ pending_recv=1; ++ } ++ else if((recv == 0) && (transmit == 0)) ++ { ++ gsw_delay_setting(); ++ } ++ spin_unlock_irqrestore(&(ei_local->page_lock), flags); ++#endif ++ ++ return IRQ_HANDLED; ++} ++ ++#if defined (CONFIG_RALINK_RT6855) || defined (CONFIG_RALINK_RT6855A) || \ ++ defined (CONFIG_RALINK_MT7620)|| defined (CONFIG_RALINK_MT7621) ++static void esw_link_status_changed(int port_no, void *dev_id) ++{ ++ unsigned int reg_val; ++ struct net_device *dev = (struct net_device *) dev_id; ++ END_DEVICE *ei_local = netdev_priv(dev); ++ ++#if defined (CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A) || \ ++ defined (CONFIG_RALINK_MT7620) ++ reg_val = *((volatile u32 *)(RALINK_ETH_SW_BASE+ 0x3008 + (port_no*0x100))); ++#elif defined (CONFIG_RALINK_MT7621) ++ mii_mgr_read(31, (0x3008 + (port_no*0x100)), ®_val); ++#endif ++ if(reg_val & 0x1) { ++ printk("ESW: Link Status Changed - Port%d Link UP\n", port_no); ++#if defined (CONFIG_RALINK_MT7621) && defined (CONFIG_RAETH_8023AZ_EEE) ++ mii_mgr_write(port_no, 31, 0x52b5); ++ mii_mgr_write(port_no, 16, 0xb780); ++ mii_mgr_write(port_no, 17, 0x00e0); ++ mii_mgr_write(port_no, 16, 0x9780); ++#endif ++ ++#if defined (CONFIG_WAN_AT_P0) ++ if(port_no==0) { ++ schedule_work(&ei_local->kill_sig_wq); ++ } ++#elif defined (CONFIG_WAN_AT_P4) ++ if(port_no==4) { ++ schedule_work(&ei_local->kill_sig_wq); ++ } ++#endif ++ } else { ++ printk("ESW: Link Status Changed - Port%d Link Down\n", port_no); ++#if defined (CONFIG_RALINK_MT7621) && defined (CONFIG_RAETH_8023AZ_EEE) ++ mii_mgr_write(port_no, 31, 0x52b5); ++ mii_mgr_write(port_no, 16, 0xb780); ++ mii_mgr_write(port_no, 17, 0x0000); ++ mii_mgr_write(port_no, 16, 0x9780); ++#endif ++ ++ } ++} ++#endif ++ ++#if defined (CONFIG_RT_3052_ESW) && ! defined(CONFIG_RALINK_MT7621) && ! defined(CONFIG_ARCH_MT7623) ++static irqreturn_t esw_interrupt(int irq, void *dev_id) ++{ ++ unsigned long flags; ++ unsigned long reg_int_val; ++#if defined (CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A) || \ ++ defined(CONFIG_RALINK_MT7620) ++ unsigned long acl_int_val; ++ unsigned long mib_int_val; ++#else ++ static unsigned long stat; ++ unsigned long stat_curr; ++#endif ++ ++ struct net_device *dev = (struct net_device *) dev_id; ++ END_DEVICE *ei_local = netdev_priv(dev); ++ ++ ++ spin_lock_irqsave(&(ei_local->page_lock), flags); ++ reg_int_val = (*((volatile u32 *)(ESW_ISR))); //Interrupt Status Register ++ ++#if defined (CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A) || \ ++ defined(CONFIG_RALINK_MT7620) ++ if (reg_int_val & P5_LINK_CH) { ++ esw_link_status_changed(5, dev_id); ++ } ++ if (reg_int_val & P4_LINK_CH) { ++ esw_link_status_changed(4, dev_id); ++ } ++ if (reg_int_val & P3_LINK_CH) { ++ esw_link_status_changed(3, dev_id); ++ } ++ if (reg_int_val & P2_LINK_CH) { ++ esw_link_status_changed(2, dev_id); ++ } ++ if (reg_int_val & P1_LINK_CH) { ++ esw_link_status_changed(1, dev_id); ++ } ++ if (reg_int_val & P0_LINK_CH) { ++ esw_link_status_changed(0, dev_id); ++ } ++ if (reg_int_val & ACL_INT) { ++ acl_int_val = sysRegRead(ESW_AISR); ++ sysRegWrite(ESW_AISR, acl_int_val); ++ } ++ if (reg_int_val & MIB_INT) { ++ ++ mib_int_val = sysRegRead(ESW_P0_IntSn); ++ if(mib_int_val){ ++ sysRegWrite(ESW_P0_IntSn, mib_int_val); ++ if(mib_int_val & RX_GOOD_CNT) ++ p0_rx_good_cnt ++; ++ if(mib_int_val & TX_GOOD_CNT) ++ p0_tx_good_cnt ++; ++ if(mib_int_val & RX_GOCT_CNT) ++ p0_rx_byte_cnt ++; ++ if(mib_int_val & TX_GOCT_CNT) ++ p0_tx_byte_cnt ++; ++ } ++ ++ mib_int_val = sysRegRead(ESW_P1_IntSn); ++ if(mib_int_val){ ++ sysRegWrite(ESW_P1_IntSn, mib_int_val); ++ if(mib_int_val & RX_GOOD_CNT) ++ p1_rx_good_cnt ++; ++ if(mib_int_val & TX_GOOD_CNT) ++ p1_tx_good_cnt ++; ++ if(mib_int_val & RX_GOCT_CNT) ++ p1_rx_byte_cnt ++; ++ if(mib_int_val & TX_GOCT_CNT) ++ p1_tx_byte_cnt ++; ++ } ++ ++ mib_int_val = sysRegRead(ESW_P2_IntSn); ++ if(mib_int_val){ ++ sysRegWrite(ESW_P2_IntSn, mib_int_val); ++ if(mib_int_val & RX_GOOD_CNT) ++ p2_rx_good_cnt ++; ++ if(mib_int_val & TX_GOOD_CNT) ++ p2_tx_good_cnt ++; ++ if(mib_int_val & RX_GOCT_CNT) ++ p2_rx_byte_cnt ++; ++ if(mib_int_val & TX_GOCT_CNT) ++ p2_tx_byte_cnt ++; ++ } ++ ++ ++ mib_int_val = sysRegRead(ESW_P3_IntSn); ++ if(mib_int_val){ ++ sysRegWrite(ESW_P3_IntSn, mib_int_val); ++ if(mib_int_val & RX_GOOD_CNT) ++ p3_rx_good_cnt ++; ++ if(mib_int_val & TX_GOOD_CNT) ++ p3_tx_good_cnt ++; ++ if(mib_int_val & RX_GOCT_CNT) ++ p3_rx_byte_cnt ++; ++ if(mib_int_val & TX_GOCT_CNT) ++ p3_tx_byte_cnt ++; ++ } ++ ++ mib_int_val = sysRegRead(ESW_P4_IntSn); ++ if(mib_int_val){ ++ sysRegWrite(ESW_P4_IntSn, mib_int_val); ++ if(mib_int_val & RX_GOOD_CNT) ++ p4_rx_good_cnt ++; ++ if(mib_int_val & TX_GOOD_CNT) ++ p4_tx_good_cnt ++; ++ if(mib_int_val & RX_GOCT_CNT) ++ p4_rx_byte_cnt ++; ++ if(mib_int_val & TX_GOCT_CNT) ++ p4_tx_byte_cnt ++; ++ } ++ ++ mib_int_val = sysRegRead(ESW_P5_IntSn); ++ if(mib_int_val){ ++ sysRegWrite(ESW_P5_IntSn, mib_int_val); ++ if(mib_int_val & RX_GOOD_CNT) ++ p5_rx_good_cnt ++; ++ if(mib_int_val & TX_GOOD_CNT) ++ p5_tx_good_cnt ++; ++ if(mib_int_val & RX_GOCT_CNT) ++ p5_rx_byte_cnt ++; ++ if(mib_int_val & TX_GOCT_CNT) ++ p5_tx_byte_cnt ++; ++ } ++ ++ mib_int_val = sysRegRead(ESW_P6_IntSn); ++ if(mib_int_val){ ++ sysRegWrite(ESW_P6_IntSn, mib_int_val); ++ if(mib_int_val & RX_GOOD_CNT) ++ p6_rx_good_cnt ++; ++ if(mib_int_val & TX_GOOD_CNT) ++ p6_tx_good_cnt ++; ++ if(mib_int_val & RX_GOCT_CNT) ++ p6_rx_byte_cnt ++; ++ if(mib_int_val & TX_GOCT_CNT) ++ p6_tx_byte_cnt ++; ++ } ++#if defined (CONFIG_RALINK_MT7620) ++ mib_int_val = sysRegRead(ESW_P7_IntSn); ++ if(mib_int_val){ ++ sysRegWrite(ESW_P7_IntSn, mib_int_val); ++ if(mib_int_val & RX_GOOD_CNT) ++ p7_rx_good_cnt ++; ++ if(mib_int_val & TX_GOOD_CNT) ++ p7_tx_good_cnt ++; ++ if(mib_int_val & RX_GOCT_CNT) ++ p7_rx_byte_cnt ++; ++ if(mib_int_val & TX_GOCT_CNT) ++ p7_tx_byte_cnt ++; ++ ++ } ++#endif ++ } ++ ++#else // not RT6855 ++ if (reg_int_val & PORT_ST_CHG) { ++ printk("RT305x_ESW: Link Status Changed\n"); ++ ++ stat_curr = *((volatile u32 *)(RALINK_ETH_SW_BASE+0x80)); ++#ifdef CONFIG_WAN_AT_P0 ++ //link down --> link up : send signal to user application ++ //link up --> link down : ignore ++ if ((stat & (1<<25)) || !(stat_curr & (1<<25))) ++#else ++ if ((stat & (1<<29)) || !(stat_curr & (1<<29))) ++#endif ++ goto out; ++ ++ schedule_work(&ei_local->kill_sig_wq); ++out: ++ stat = stat_curr; ++ } ++ ++#endif // defined(CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A)// ++ ++ sysRegWrite(ESW_ISR, reg_int_val); ++ ++ spin_unlock_irqrestore(&(ei_local->page_lock), flags); ++ return IRQ_HANDLED; ++} ++ ++ ++ ++#elif defined (CONFIG_RT_3052_ESW) && defined(CONFIG_RALINK_MT7621) ++ ++static irqreturn_t esw_interrupt(int irq, void *dev_id) ++{ ++ unsigned long flags; ++ unsigned int reg_int_val; ++ struct net_device *dev = (struct net_device *) dev_id; ++ END_DEVICE *ei_local = netdev_priv(dev); ++ ++ spin_lock_irqsave(&(ei_local->page_lock), flags); ++ mii_mgr_read(31, 0x700c, ®_int_val); ++ ++ if (reg_int_val & P4_LINK_CH) { ++ esw_link_status_changed(4, dev_id); ++ } ++ ++ if (reg_int_val & P3_LINK_CH) { ++ esw_link_status_changed(3, dev_id); ++ } ++ if (reg_int_val & P2_LINK_CH) { ++ esw_link_status_changed(2, dev_id); ++ } ++ if (reg_int_val & P1_LINK_CH) { ++ esw_link_status_changed(1, dev_id); ++ } ++ if (reg_int_val & P0_LINK_CH) { ++ esw_link_status_changed(0, dev_id); ++ } ++ ++ mii_mgr_write(31, 0x700c, 0x1f); //ack switch link change ++ ++ spin_unlock_irqrestore(&(ei_local->page_lock), flags); ++ return IRQ_HANDLED; ++} ++ ++#endif ++ ++ ++static int ei_start_xmit_fake(struct sk_buff* skb, struct net_device *dev) ++{ ++ return ei_start_xmit(skb, dev, 1); ++} ++ ++ ++#if defined (CONFIG_RALINK_RT3052) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) ++void dump_phy_reg(int port_no, int from, int to, int is_local) ++{ ++ u32 i=0; ++ u32 temp=0; ++ ++ if(is_local==0) { ++ printk("Global Register\n"); ++ printk("==============="); ++ mii_mgr_write(0, 31, 0); //select global register ++ for(i=from;i<=to;i++) { ++ if(i%8==0) { ++ printk("\n"); ++ } ++ mii_mgr_read(port_no,i, &temp); ++ printk("%02d: %04X ",i, temp); ++ } ++ } else { ++ mii_mgr_write(0, 31, 0x8000); //select local register ++ printk("\n\nLocal Register Port %d\n",port_no); ++ printk("==============="); ++ for(i=from;i<=to;i++) { ++ if(i%8==0) { ++ printk("\n"); ++ } ++ mii_mgr_read(port_no,i, &temp); ++ printk("%02d: %04X ",i, temp); ++ } ++ } ++ printk("\n"); ++} ++#else ++void dump_phy_reg(int port_no, int from, int to, int is_local, int page_no) ++{ ++ ++ u32 i=0; ++ u32 temp=0; ++ u32 r31=0; ++ ++ ++ if(is_local==0) { ++ ++ printk("\n\nGlobal Register Page %d\n",page_no); ++ printk("==============="); ++ r31 |= 0 << 15; //global ++ r31 |= ((page_no&0x7) << 12); //page no ++ mii_mgr_write(port_no, 31, r31); //select global page x ++ for(i=16;i<32;i++) { ++ if(i%8==0) { ++ printk("\n"); ++ } ++ mii_mgr_read(port_no,i, &temp); ++ printk("%02d: %04X ",i, temp); ++ } ++ }else { ++ printk("\n\nLocal Register Port %d Page %d\n",port_no, page_no); ++ printk("==============="); ++ r31 |= 1 << 15; //local ++ r31 |= ((page_no&0x7) << 12); //page no ++ mii_mgr_write(port_no, 31, r31); //select local page x ++ for(i=16;i<32;i++) { ++ if(i%8==0) { ++ printk("\n"); ++ } ++ mii_mgr_read(port_no,i, &temp); ++ printk("%02d: %04X ",i, temp); ++ } ++ } ++ printk("\n"); ++} ++ ++#endif ++ ++int ei_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) ++{ ++#if defined(CONFIG_RT_3052_ESW) || defined(CONFIG_RAETH_QDMA) ++ esw_reg reg; ++#endif ++#if defined(CONFIG_RALINK_RT3352) || defined(CONFIG_RALINK_RT5350) || \ ++ defined (CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A) || \ ++ defined(CONFIG_RALINK_MT7620) || defined(CONFIG_RALINK_MT7621) || \ ++ defined (CONFIG_RALINK_MT7628) || defined (CONFIG_ARCH_MT7623) ++ esw_rate ratelimit; ++#endif ++#if defined(CONFIG_RT_3052_ESW) ++ unsigned int offset = 0; ++ unsigned int value = 0; ++#endif ++ ++ int ret = 0; ++ END_DEVICE *ei_local = netdev_priv(dev); ++ ra_mii_ioctl_data mii; ++ spin_lock_irq(&ei_local->page_lock); ++ ++ switch (cmd) { ++#if defined(CONFIG_RAETH_QDMA) ++#define _HQOS_REG(x) (*((volatile u32 *)(RALINK_FRAME_ENGINE_BASE + QDMA_RELATED + x))) ++ case RAETH_QDMA_REG_READ: ++ copy_from_user(®, ifr->ifr_data, sizeof(reg)); ++ if (reg.off > REG_HQOS_MAX) { ++ ret = -EINVAL; ++ break; ++ } ++ reg.val = _HQOS_REG(reg.off); ++ //printk("read reg off:%x val:%x\n", reg.off, reg.val); ++ copy_to_user(ifr->ifr_data, ®, sizeof(reg)); ++ break; ++ case RAETH_QDMA_REG_WRITE: ++ copy_from_user(®, ifr->ifr_data, sizeof(reg)); ++ if (reg.off > REG_HQOS_MAX) { ++ ret = -EINVAL; ++ break; ++ } ++ _HQOS_REG(reg.off) = reg.val; ++ //printk("write reg off:%x val:%x\n", reg.off, reg.val); ++ break; ++#if 0 ++ case RAETH_QDMA_READ_CPU_CLK: ++ copy_from_user(®, ifr->ifr_data, sizeof(reg)); ++ reg.val = get_surfboard_sysclk(); ++ //printk("read reg off:%x val:%x\n", reg.off, reg.val); ++ copy_to_user(ifr->ifr_data, ®, sizeof(reg)); ++ break; ++#endif ++ case RAETH_QDMA_QUEUE_MAPPING: ++ copy_from_user(®, ifr->ifr_data, sizeof(reg)); ++ if((reg.off&0x100) == 0x100){ ++ lan_wan_separate = 1; ++ reg.off &= 0xff; ++ }else{ ++ lan_wan_separate = 0; ++ } ++ M2Q_table[reg.off] = reg.val; ++ break; ++#if defined(CONFIG_HW_SFQ) ++ case RAETH_QDMA_SFQ_WEB_ENABLE: ++ copy_from_user(®, ifr->ifr_data, sizeof(reg)); ++ if((reg.val) == 0x1){ ++ web_sfq_enable = 1; ++ ++ }else{ ++ web_sfq_enable = 0; ++ } ++ break; ++#endif ++ ++ ++#endif ++ case RAETH_MII_READ: ++ copy_from_user(&mii, ifr->ifr_data, sizeof(mii)); ++ mii_mgr_read(mii.phy_id, mii.reg_num, &mii.val_out); ++ //printk("phy %d, reg %d, val 0x%x\n", mii.phy_id, mii.reg_num, mii.val_out); ++ copy_to_user(ifr->ifr_data, &mii, sizeof(mii)); ++ break; ++ ++ case RAETH_MII_WRITE: ++ copy_from_user(&mii, ifr->ifr_data, sizeof(mii)); ++ //printk("phy %d, reg %d, val 0x%x\n", mii.phy_id, mii.reg_num, mii.val_in); ++ mii_mgr_write(mii.phy_id, mii.reg_num, mii.val_in); ++ break; ++#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_RALINK_MT7620) || defined (CONFIG_ARCH_MT7623) ++ case RAETH_MII_READ_CL45: ++ copy_from_user(&mii, ifr->ifr_data, sizeof(mii)); ++ //mii_mgr_cl45_set_address(mii.port_num, mii.dev_addr, mii.reg_addr); ++ mii_mgr_read_cl45(mii.port_num, mii.dev_addr, mii.reg_addr, &mii.val_out); ++ copy_to_user(ifr->ifr_data, &mii, sizeof(mii)); ++ break; ++ case RAETH_MII_WRITE_CL45: ++ copy_from_user(&mii, ifr->ifr_data, sizeof(mii)); ++ //mii_mgr_cl45_set_address(mii.port_num, mii.dev_addr, mii.reg_addr); ++ mii_mgr_write_cl45(mii.port_num, mii.dev_addr, mii.reg_addr, mii.val_in); ++ break; ++#endif ++ ++#if defined(CONFIG_RT_3052_ESW) ++#define _ESW_REG(x) (*((volatile u32 *)(RALINK_ETH_SW_BASE + x))) ++ case RAETH_ESW_REG_READ: ++ copy_from_user(®, ifr->ifr_data, sizeof(reg)); ++ if (reg.off > REG_ESW_MAX) { ++ ret = -EINVAL; ++ break; ++ } ++ reg.val = _ESW_REG(reg.off); ++ //printk("read reg off:%x val:%x\n", reg.off, reg.val); ++ copy_to_user(ifr->ifr_data, ®, sizeof(reg)); ++ break; ++ case RAETH_ESW_REG_WRITE: ++ copy_from_user(®, ifr->ifr_data, sizeof(reg)); ++ if (reg.off > REG_ESW_MAX) { ++ ret = -EINVAL; ++ break; ++ } ++ _ESW_REG(reg.off) = reg.val; ++ //printk("write reg off:%x val:%x\n", reg.off, reg.val); ++ break; ++ case RAETH_ESW_PHY_DUMP: ++ copy_from_user(®, ifr->ifr_data, sizeof(reg)); ++#if defined (CONFIG_RALINK_RT3052) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) ++ if (reg.val ==32 ) {//dump all phy register ++ /* Global Register 0~31 ++ * Local Register 0~31 ++ */ ++ dump_phy_reg(0, 0, 31, 0); //dump global register ++ for(offset=0;offset<5;offset++) { ++ dump_phy_reg(offset, 0, 31, 1); //dump local register ++ } ++ } else { ++ dump_phy_reg(reg.val, 0, 31, 0); //dump global register ++ dump_phy_reg(reg.val, 0, 31, 1); //dump local register ++ } ++#else ++ /* SPEC defined Register 0~15 ++ * Global Register 16~31 for each page ++ * Local Register 16~31 for each page ++ */ ++ printk("SPEC defined Register"); ++ if (reg.val ==32 ) {//dump all phy register ++ int i = 0; ++ for(i=0; i<5; i++){ ++ printk("\n[Port %d]===============",i); ++ for(offset=0;offset<16;offset++) { ++ if(offset%8==0) { ++ printk("\n"); ++ } ++ mii_mgr_read(i,offset, &value); ++ printk("%02d: %04X ",offset, value); ++ } ++ } ++ } ++ else{ ++ printk("\n[Port %d]===============",reg.val); ++ for(offset=0;offset<16;offset++) { ++ if(offset%8==0) { ++ printk("\n"); ++ } ++ mii_mgr_read(reg.val,offset, &value); ++ printk("%02d: %04X ",offset, value); ++ } ++ } ++ ++#if defined (CONFIG_RALINK_MT7628) ++ for(offset=0;offset<7;offset++) { //global register page 0~6 ++#else ++ for(offset=0;offset<5;offset++) { //global register page 0~4 ++#endif ++ if(reg.val == 32) //dump all phy register ++ dump_phy_reg(0, 16, 31, 0, offset); ++ else ++ dump_phy_reg(reg.val, 16, 31, 0, offset); ++ } ++ ++ if (reg.val == 32) {//dump all phy register ++#if !defined (CONFIG_RAETH_HAS_PORT4) ++ for(offset=0;offset<5;offset++) { //local register port 0-port4 ++#else ++ for(offset=0;offset<4;offset++) { //local register port 0-port3 ++#endif ++ dump_phy_reg(offset, 16, 31, 1, 0); //dump local page 0 ++ dump_phy_reg(offset, 16, 31, 1, 1); //dump local page 1 ++ dump_phy_reg(offset, 16, 31, 1, 2); //dump local page 2 ++ dump_phy_reg(offset, 16, 31, 1, 3); //dump local page 3 ++ } ++ }else { ++ dump_phy_reg(reg.val, 16, 31, 1, 0); //dump local page 0 ++ dump_phy_reg(reg.val, 16, 31, 1, 1); //dump local page 1 ++ dump_phy_reg(reg.val, 16, 31, 1, 2); //dump local page 2 ++ dump_phy_reg(reg.val, 16, 31, 1, 3); //dump local page 3 ++ } ++#endif ++ break; ++ ++#if defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_MT7628) ++#define _ESW_REG(x) (*((volatile u32 *)(RALINK_ETH_SW_BASE + x))) ++ case RAETH_ESW_INGRESS_RATE: ++ copy_from_user(&ratelimit, ifr->ifr_data, sizeof(ratelimit)); ++ offset = 0x11c + (4 * (ratelimit.port / 2)); ++ value = _ESW_REG(offset); ++ ++ if((ratelimit.port % 2) == 0) ++ { ++ value &= 0xffff0000; ++ if(ratelimit.on_off == 1) ++ { ++ value |= (ratelimit.on_off << 14); ++ value |= (0x07 << 10); ++ value |= ratelimit.bw; ++ } ++ } ++ else if((ratelimit.port % 2) == 1) ++ { ++ value &= 0x0000ffff; ++ if(ratelimit.on_off == 1) ++ { ++ value |= (ratelimit.on_off << 30); ++ value |= (0x07 << 26); ++ value |= (ratelimit.bw << 16); ++ } ++ } ++ printk("offset = 0x%4x value=0x%x\n\r", offset, value); ++ ++ _ESW_REG(offset) = value; ++ break; ++ ++ case RAETH_ESW_EGRESS_RATE: ++ copy_from_user(&ratelimit, ifr->ifr_data, sizeof(ratelimit)); ++ offset = 0x140 + (4 * (ratelimit.port / 2)); ++ value = _ESW_REG(offset); ++ ++ if((ratelimit.port % 2) == 0) ++ { ++ value &= 0xffff0000; ++ if(ratelimit.on_off == 1) ++ { ++ value |= (ratelimit.on_off << 12); ++ value |= (0x03 << 10); ++ value |= ratelimit.bw; ++ } ++ } ++ else if((ratelimit.port % 2) == 1) ++ { ++ value &= 0x0000ffff; ++ if(ratelimit.on_off == 1) ++ { ++ value |= (ratelimit.on_off << 28); ++ value |= (0x03 << 26); ++ value |= (ratelimit.bw << 16); ++ } ++ } ++ printk("offset = 0x%4x value=0x%x\n\r", offset, value); ++ _ESW_REG(offset) = value; ++ break; ++#elif defined (CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_RT6855A) || \ ++ defined(CONFIG_RALINK_MT7620) || defined(CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++#define _ESW_REG(x) (*((volatile u32 *)(RALINK_ETH_SW_BASE + x))) ++ case RAETH_ESW_INGRESS_RATE: ++ copy_from_user(&ratelimit, ifr->ifr_data, sizeof(ratelimit)); ++#if defined(CONFIG_RALINK_RT6855A) || defined(CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++ offset = 0x1800 + (0x100 * ratelimit.port); ++#else ++ offset = 0x1080 + (0x100 * ratelimit.port); ++#endif ++ value = _ESW_REG(offset); ++ ++ value &= 0xffff0000; ++ if(ratelimit.on_off == 1) ++ { ++ value |= (ratelimit.on_off << 15); ++ if (ratelimit.bw < 100) ++ { ++ value |= (0x0 << 8); ++ value |= ratelimit.bw; ++ }else if(ratelimit.bw < 1000) ++ { ++ value |= (0x1 << 8); ++ value |= ratelimit.bw/10; ++ }else if(ratelimit.bw < 10000) ++ { ++ value |= (0x2 << 8); ++ value |= ratelimit.bw/100; ++ }else if(ratelimit.bw < 100000) ++ { ++ value |= (0x3 << 8); ++ value |= ratelimit.bw/1000; ++ }else ++ { ++ value |= (0x4 << 8); ++ value |= ratelimit.bw/10000; ++ } ++ } ++ printk("offset = 0x%4x value=0x%x\n\r", offset, value); ++#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++ mii_mgr_write(0x1f, offset, value); ++#else ++ _ESW_REG(offset) = value; ++#endif ++ break; ++ ++ case RAETH_ESW_EGRESS_RATE: ++ copy_from_user(&ratelimit, ifr->ifr_data, sizeof(ratelimit)); ++ offset = 0x1040 + (0x100 * ratelimit.port); ++ value = _ESW_REG(offset); ++ ++ value &= 0xffff0000; ++ if(ratelimit.on_off == 1) ++ { ++ value |= (ratelimit.on_off << 15); ++ if (ratelimit.bw < 100) ++ { ++ value |= (0x0 << 8); ++ value |= ratelimit.bw; ++ }else if(ratelimit.bw < 1000) ++ { ++ value |= (0x1 << 8); ++ value |= ratelimit.bw/10; ++ }else if(ratelimit.bw < 10000) ++ { ++ value |= (0x2 << 8); ++ value |= ratelimit.bw/100; ++ }else if(ratelimit.bw < 100000) ++ { ++ value |= (0x3 << 8); ++ value |= ratelimit.bw/1000; ++ }else ++ { ++ value |= (0x4 << 8); ++ value |= ratelimit.bw/10000; ++ } ++ } ++ printk("offset = 0x%4x value=0x%x\n\r", offset, value); ++#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++ mii_mgr_write(0x1f, offset, value); ++#else ++ _ESW_REG(offset) = value; ++#endif ++ break; ++#endif ++#endif // CONFIG_RT_3052_ESW ++ default: ++ ret = -EOPNOTSUPP; ++ break; ++ ++ } ++ ++ spin_unlock_irq(&ei_local->page_lock); ++ return ret; ++} ++ ++/* ++ * Set new MTU size ++ * Change the mtu of Raeth Ethernet Device ++ */ ++static int ei_change_mtu(struct net_device *dev, int new_mtu) ++{ ++ END_DEVICE *ei_local = netdev_priv(dev); // get priv ei_local pointer from net_dev structure ++ ++ if ( ei_local == NULL ) { ++ printk(KERN_EMERG "%s: ei_change_mtu passed a non-existent private pointer from net_dev!\n", dev->name); ++ return -ENXIO; ++ } ++ ++ ++ if ( (new_mtu > 4096) || (new_mtu < 64)) { ++ return -EINVAL; ++ } ++ ++#ifndef CONFIG_RAETH_JUMBOFRAME ++ if ( new_mtu > 1500 ) { ++ return -EINVAL; ++ } ++#endif ++ ++ dev->mtu = new_mtu; ++ ++ return 0; ++} ++ ++#ifdef CONFIG_RAETH_HW_VLAN_RX ++static void ei_vlan_rx_register(struct net_device *dev, struct vlan_group *grp) ++{ ++ END_DEVICE *ei_local = netdev_priv(dev); ++ ++ ei_local->vlgrp = grp; ++ ++ /* enable HW VLAN RX */ ++ sysRegWrite(CDMP_EG_CTRL, 1); ++ ++} ++#endif ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++static const struct net_device_ops ei_netdev_ops = { ++ .ndo_init = rather_probe, ++ .ndo_open = ei_open, ++ .ndo_stop = ei_close, ++ .ndo_start_xmit = ei_start_xmit_fake, ++ .ndo_get_stats = ra_get_stats, ++ .ndo_set_mac_address = eth_mac_addr, ++ .ndo_change_mtu = ei_change_mtu, ++ .ndo_do_ioctl = ei_ioctl, ++ .ndo_validate_addr = eth_validate_addr, ++#ifdef CONFIG_RAETH_HW_VLAN_RX ++ .ndo_vlan_rx_register = ei_vlan_rx_register, ++#endif ++#ifdef CONFIG_NET_POLL_CONTROLLER ++ .ndo_poll_controller = raeth_clean, ++#endif ++// .ndo_tx_timeout = ei_tx_timeout, ++}; ++#endif ++ ++void ra2880_setup_dev_fptable(struct net_device *dev) ++{ ++ RAETH_PRINT(__FUNCTION__ "is called!\n"); ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ dev->netdev_ops = &ei_netdev_ops; ++#else ++ dev->open = ei_open; ++ dev->stop = ei_close; ++ dev->hard_start_xmit = ei_start_xmit_fake; ++ dev->get_stats = ra_get_stats; ++ dev->set_mac_address = ei_set_mac_addr; ++ dev->change_mtu = ei_change_mtu; ++ dev->mtu = 1500; ++ dev->do_ioctl = ei_ioctl; ++// dev->tx_timeout = ei_tx_timeout; ++ ++#ifdef CONFIG_RAETH_NAPI ++ dev->poll = &raeth_clean; ++#if defined (CONFIG_RAETH_ROUTER) ++ dev->weight = 32; ++#elif defined (CONFIG_RT_3052_ESW) ++ dev->weight = 32; ++#else ++ dev->weight = 128; ++#endif ++#endif ++#endif ++#if defined (CONFIG_ETHTOOL) /*&& defined (CONFIG_RAETH_ROUTER)*/ ++ dev->ethtool_ops = &ra_ethtool_ops; ++#endif ++#define TX_TIMEOUT (5*HZ) ++ dev->watchdog_timeo = TX_TIMEOUT; ++ ++} ++ ++/* reset frame engine */ ++void fe_reset(void) ++{ ++#if defined (CONFIG_RALINK_RT6855A) ++ /* FIXME */ ++#else ++ u32 val; ++ ++ //val = *(volatile u32 *)(0x1b000000); ++ //printk("0x1b000000 is 0x%x\n", val); ++ //val = sysRegRead(0xFB110100); ++ //val = 0x8000; ++ //sysRegWrite(0xFB110100, val); ++ ++ ++ ++ val = sysRegRead(RSTCTRL); ++ ++// RT5350 need to reset ESW and FE at the same to avoid PDMA panic // ++#if defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_MT7628) ++ val = val | RALINK_FE_RST | RALINK_ESW_RST ; ++#else ++ val = val | RALINK_FE_RST; ++#endif ++ sysRegWrite(RSTCTRL, val); ++#if defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_MT7620) || defined (CONFIG_RALINK_MT7628) ++ val = val & ~(RALINK_FE_RST | RALINK_ESW_RST); ++#else ++ val = val & ~(RALINK_FE_RST); ++#endif ++ ++ sysRegWrite(RSTCTRL, val); ++#endif ++} ++ ++/* set TRGMII */ ++#if defined (CONFIG_GE1_TRGMII_FORCE_1200) && defined (CONFIG_MT7621_ASIC) ++void trgmii_set_7621(void) ++{ ++ u32 val = 0; ++ u32 val_0 = 0; ++ ++ val = sysRegRead(RSTCTRL); ++// MT7621 need to reset GMAC and FE first // ++ val = val | RALINK_FE_RST | RALINK_ETH_RST ; ++ sysRegWrite(RSTCTRL, val); ++ ++//set TRGMII clock// ++ val_0 = sysRegRead(CLK_CFG_0); ++ val_0 &= 0xffffff9f; ++ val_0 |= (0x1 << 5); ++ sysRegWrite(CLK_CFG_0, val_0); ++ mdelay(1); ++ val_0 = sysRegRead(CLK_CFG_0); ++ printk("set CLK_CFG_0 = 0x%x!!!!!!!!!!!!!!!!!!1\n",val_0); ++ val = val & ~(RALINK_FE_RST | RALINK_ETH_RST); ++ sysRegWrite(RSTCTRL, val); ++} ++ ++void trgmii_set_7530(void) ++{ ++// set MT7530 // ++#if 0 ++ ++ mii_mgr_write(31, 103, 0x0020); ++ ++ ++ //disable EEE ++ mii_mgr_write(0, 0x16, 0); ++ mii_mgr_write(1, 0x16, 0); ++ mii_mgr_write(2, 0x16, 0); ++ mii_mgr_write(3, 0x16, 0); ++ mii_mgr_write(4, 0x16, 0); ++ ++ ++ //PLL reset for E2 ++ mii_mgr_write(31, 104, 0x0608); ++ mii_mgr_write(31, 104, 0x2608); ++ ++ mii_mgr_write(31, 0x7808, 0x0); ++ mdelay(1); ++ mii_mgr_write(31, 0x7804, 0x01017e8f); ++ mdelay(1); ++ mii_mgr_write(31, 0x7808, 0x1); ++ mdelay(1); ++ ++#endif ++#if 1 ++ //CL45 command ++ //PLL to 150Mhz ++ mii_mgr_write(0, 13, 0x1f); ++ mii_mgr_write(0, 14, 0x404); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_read(31, 0x7800, ®Value); ++ regValue = (regValue >> 9) & 0x3; ++ if(regValue == 0x3) { //25Mhz Xtal ++ mii_mgr_write(0, 14, 0x0A00);//25Mhz XTAL for 150Mhz CLK ++ } else if(regValue == 0x2) { //40Mhz ++ mii_mgr_write(0, 14, 0x0780);//40Mhz XTAL for 150Mhz CLK ++ } ++ //mii_mgr_write(0, 14, 0x0C00);//ori ++ mdelay(1); ++ ++ mii_mgr_write(0, 13, 0x1f); ++ mii_mgr_write(0, 14, 0x409); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0x57); ++ mdelay(1); ++ ++ mii_mgr_write(0, 13, 0x1f); ++ mii_mgr_write(0, 14, 0x40a); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0x57); ++ ++//PLL BIAS en ++ mii_mgr_write(0, 13, 0x1f); ++ mii_mgr_write(0, 14, 0x403); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0x1800); ++ mdelay(1); ++ ++//BIAS LPF en ++ mii_mgr_write(0, 13, 0x1f); ++ mii_mgr_write(0, 14, 0x403); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0x1c00); ++ ++//sys PLL en ++ mii_mgr_write(0, 13, 0x1f); ++ mii_mgr_write(0, 14, 0x401); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0xc020); ++ ++//LCDDDS PWDS ++ mii_mgr_write(0, 13, 0x1f); ++ mii_mgr_write(0, 14, 0x406); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0xa030); ++ mdelay(1); ++ ++//GSW_2X_CLK ++ mii_mgr_write(0, 13, 0x1f); ++ mii_mgr_write(0, 14, 0x410); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0x0003); ++ ++//enable P6 ++ mii_mgr_write(31, 0x3600, 0x5e33b); ++ ++//enable TRGMII ++ mii_mgr_write(31, 0x7830, 0x1); ++#endif ++ ++} ++#endif ++ ++void ei_reset_task(struct work_struct *work) ++{ ++ struct net_device *dev = dev_raether; ++ ++ ei_close(dev); ++ ei_open(dev); ++ ++ return; ++} ++ ++void ei_tx_timeout(struct net_device *dev) ++{ ++ END_DEVICE *ei_local = netdev_priv(dev); ++ ++ schedule_work(&ei_local->reset_task); ++} ++ ++void setup_statistics(END_DEVICE* ei_local) ++{ ++ ei_local->stat.tx_packets = 0; ++ ei_local->stat.tx_bytes = 0; ++ ei_local->stat.tx_dropped = 0; ++ ei_local->stat.tx_errors = 0; ++ ei_local->stat.tx_aborted_errors= 0; ++ ei_local->stat.tx_carrier_errors= 0; ++ ei_local->stat.tx_fifo_errors = 0; ++ ei_local->stat.tx_heartbeat_errors = 0; ++ ei_local->stat.tx_window_errors = 0; ++ ++ ei_local->stat.rx_packets = 0; ++ ei_local->stat.rx_bytes = 0; ++ ei_local->stat.rx_dropped = 0; ++ ei_local->stat.rx_errors = 0; ++ ei_local->stat.rx_length_errors = 0; ++ ei_local->stat.rx_over_errors = 0; ++ ei_local->stat.rx_crc_errors = 0; ++ ei_local->stat.rx_frame_errors = 0; ++ ei_local->stat.rx_fifo_errors = 0; ++ ei_local->stat.rx_missed_errors = 0; ++ ++ ei_local->stat.collisions = 0; ++#if defined (CONFIG_RAETH_QOS) ++ ei_local->tx3_full = 0; ++ ei_local->tx2_full = 0; ++ ei_local->tx1_full = 0; ++ ei_local->tx0_full = 0; ++#else ++ ei_local->tx_full = 0; ++#endif ++#ifdef CONFIG_RAETH_NAPI ++ atomic_set(&ei_local->irq_sem, 1); ++#endif ++ ++} ++ ++/** ++ * rather_probe - pick up ethernet port at boot time ++ * @dev: network device to probe ++ * ++ * This routine probe the ethernet port at boot time. ++ * ++ * ++ */ ++ ++int __init rather_probe(struct net_device *dev) ++{ ++ int i; ++ END_DEVICE *ei_local = netdev_priv(dev); ++ struct sockaddr addr; ++ unsigned char zero1[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; ++ unsigned char zero2[6]={0x00,0x00,0x00,0x00,0x00,0x00}; ++ ++ fe_reset(); ++ ++ //Get mac0 address from flash ++#ifdef RA_MTD_RW_BY_NUM ++ i = ra_mtd_read(2, GMAC0_OFFSET, 6, addr.sa_data); ++#else ++ i = ra_mtd_read_nm("Factory", GMAC0_OFFSET, 6, addr.sa_data); ++#endif ++ //If reading mtd failed or mac0 is empty, generate a mac address ++ if (i < 0 || ((memcmp(addr.sa_data, zero1, 6) == 0) || (addr.sa_data[0] & 0x1)) || ++ (memcmp(addr.sa_data, zero2, 6) == 0)) { ++ unsigned char mac_addr01234[5] = {0x00, 0x0C, 0x43, 0x28, 0x80}; ++ // net_srandom(jiffies); ++ memcpy(addr.sa_data, mac_addr01234, 5); ++ // addr.sa_data[5] = net_random()&0xFF; ++ } ++ ++#ifdef CONFIG_RAETH_NAPI ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ netif_napi_add(dev, &ei_local->napi, raeth_clean, 128); ++#endif ++#endif ++ ei_set_mac_addr(dev, &addr); ++ spin_lock_init(&ei_local->page_lock); ++ ether_setup(dev); ++ ++#ifdef CONFIG_RAETH_LRO ++ ei_local->lro_mgr.dev = dev; ++ memset(&ei_local->lro_mgr.stats, 0, sizeof(ei_local->lro_mgr.stats)); ++ ei_local->lro_mgr.features = LRO_F_NAPI; ++ ei_local->lro_mgr.ip_summed = CHECKSUM_UNNECESSARY; ++ ei_local->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY; ++ ei_local->lro_mgr.max_desc = ARRAY_SIZE(ei_local->lro_arr); ++ ei_local->lro_mgr.max_aggr = 64; ++ ei_local->lro_mgr.frag_align_pad = 0; ++ ei_local->lro_mgr.lro_arr = ei_local->lro_arr; ++ ei_local->lro_mgr.get_skb_header = rt_get_skb_header; ++#endif ++ ++ setup_statistics(ei_local); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PSEUDO_SUPPORT ++int VirtualIF_ioctl(struct net_device * net_dev, ++ struct ifreq * ifr, int cmd) ++{ ++ ra_mii_ioctl_data mii; ++ ++ switch (cmd) { ++ case RAETH_MII_READ: ++ copy_from_user(&mii, ifr->ifr_data, sizeof(mii)); ++ mii_mgr_read(mii.phy_id, mii.reg_num, &mii.val_out); ++ //printk("phy %d, reg %d, val 0x%x\n", mii.phy_id, mii.reg_num, mii.val_out); ++ copy_to_user(ifr->ifr_data, &mii, sizeof(mii)); ++ break; ++ ++ case RAETH_MII_WRITE: ++ copy_from_user(&mii, ifr->ifr_data, sizeof(mii)); ++ //printk("phy %d, reg %d, val 0x%x\n", mii.phy_id, mii.reg_num, mii.val_in); ++ mii_mgr_write(mii.phy_id, mii.reg_num, mii.val_in); ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ return 0; ++} ++ ++struct net_device_stats *VirtualIF_get_stats(struct net_device *dev) ++{ ++ PSEUDO_ADAPTER *pAd = netdev_priv(dev); ++ return &pAd->stat; ++} ++ ++int VirtualIF_open(struct net_device * dev) ++{ ++ PSEUDO_ADAPTER *pPesueoAd = netdev_priv(dev); ++ ++ printk("%s: ===> VirtualIF_open\n", dev->name); ++ ++#if defined (CONFIG_GE_RGMII_INTERNAL_P0_AN) || defined (CONFIG_GE_RGMII_INTERNAL_P4_AN) ++ *((volatile u32 *)(FE_INT_ENABLE2)) |= (1<<25); //enable GE2 link change intr for MT7530 delay setting ++#endif ++ ++ netif_start_queue(pPesueoAd->PseudoDev); ++ ++ return 0; ++} ++ ++int VirtualIF_close(struct net_device * dev) ++{ ++ PSEUDO_ADAPTER *pPesueoAd = netdev_priv(dev); ++ ++ printk("%s: ===> VirtualIF_close\n", dev->name); ++ ++ netif_stop_queue(pPesueoAd->PseudoDev); ++ ++ return 0; ++} ++ ++int VirtualIFSendPackets(struct sk_buff * pSkb, ++ struct net_device * dev) ++{ ++ PSEUDO_ADAPTER *pPesueoAd = netdev_priv(dev); ++ END_DEVICE *ei_local __maybe_unused; ++ ++ ++ //printk("VirtualIFSendPackets --->\n"); ++ ++ ei_local = netdev_priv(dev); ++ if (!(pPesueoAd->RaethDev->flags & IFF_UP)) { ++ dev_kfree_skb_any(pSkb); ++ return 0; ++ } ++ //pSkb->cb[40]=0x5a; ++ pSkb->dev = pPesueoAd->RaethDev; ++ ei_start_xmit(pSkb, pPesueoAd->RaethDev, 2); ++ return 0; ++} ++ ++void virtif_setup_statistics(PSEUDO_ADAPTER* pAd) ++{ ++ pAd->stat.tx_packets = 0; ++ pAd->stat.tx_bytes = 0; ++ pAd->stat.tx_dropped = 0; ++ pAd->stat.tx_errors = 0; ++ pAd->stat.tx_aborted_errors= 0; ++ pAd->stat.tx_carrier_errors= 0; ++ pAd->stat.tx_fifo_errors = 0; ++ pAd->stat.tx_heartbeat_errors = 0; ++ pAd->stat.tx_window_errors = 0; ++ ++ pAd->stat.rx_packets = 0; ++ pAd->stat.rx_bytes = 0; ++ pAd->stat.rx_dropped = 0; ++ pAd->stat.rx_errors = 0; ++ pAd->stat.rx_length_errors = 0; ++ pAd->stat.rx_over_errors = 0; ++ pAd->stat.rx_crc_errors = 0; ++ pAd->stat.rx_frame_errors = 0; ++ pAd->stat.rx_fifo_errors = 0; ++ pAd->stat.rx_missed_errors = 0; ++ ++ pAd->stat.collisions = 0; ++} ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++static const struct net_device_ops VirtualIF_netdev_ops = { ++ .ndo_open = VirtualIF_open, ++ .ndo_stop = VirtualIF_close, ++ .ndo_start_xmit = VirtualIFSendPackets, ++ .ndo_get_stats = VirtualIF_get_stats, ++ .ndo_set_mac_address = ei_set_mac2_addr, ++ .ndo_change_mtu = ei_change_mtu, ++ .ndo_do_ioctl = VirtualIF_ioctl, ++ .ndo_validate_addr = eth_validate_addr, ++}; ++#endif ++// Register pseudo interface ++void RAETH_Init_PSEUDO(pEND_DEVICE pAd, struct net_device *net_dev) ++{ ++ int index; ++ struct net_device *dev; ++ PSEUDO_ADAPTER *pPseudoAd; ++ int i = 0; ++ struct sockaddr addr; ++ unsigned char zero1[6]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}; ++ unsigned char zero2[6]={0x00,0x00,0x00,0x00,0x00,0x00}; ++ ++ for (index = 0; index < MAX_PSEUDO_ENTRY; index++) { ++ ++ dev = alloc_etherdev(sizeof(PSEUDO_ADAPTER)); ++ if (NULL == dev) ++ { ++ printk(" alloc_etherdev for PSEUDO_ADAPTER failed.\n"); ++ return; ++ } ++ strcpy(dev->name, DEV2_NAME); ++ ++ //Get mac2 address from flash ++#ifdef RA_MTD_RW_BY_NUM ++ i = ra_mtd_read(2, GMAC2_OFFSET, 6, addr.sa_data); ++#else ++ i = ra_mtd_read_nm("Factory", GMAC2_OFFSET, 6, addr.sa_data); ++#endif ++ ++ //If reading mtd failed or mac0 is empty, generate a mac address ++ if (i < 0 || ((memcmp(addr.sa_data, zero1, 6) == 0) || (addr.sa_data[0] & 0x1)) || ++ (memcmp(addr.sa_data, zero2, 6) == 0)) { ++ unsigned char mac_addr01234[5] = {0x00, 0x0C, 0x43, 0x28, 0x80}; ++ // net_srandom(jiffies); ++ memcpy(addr.sa_data, mac_addr01234, 5); ++ // addr.sa_data[5] = net_random()&0xFF; ++ } ++ ++ ei_set_mac2_addr(dev, &addr); ++ ether_setup(dev); ++ pPseudoAd = netdev_priv(dev); ++ ++ pPseudoAd->PseudoDev = dev; ++ pPseudoAd->RaethDev = net_dev; ++ virtif_setup_statistics(pPseudoAd); ++ pAd->PseudoDev = dev; ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ dev->netdev_ops = &VirtualIF_netdev_ops; ++#else ++ dev->hard_start_xmit = VirtualIFSendPackets; ++ dev->stop = VirtualIF_close; ++ dev->open = VirtualIF_open; ++ dev->do_ioctl = VirtualIF_ioctl; ++ dev->set_mac_address = ei_set_mac2_addr; ++ dev->get_stats = VirtualIF_get_stats; ++ dev->change_mtu = ei_change_mtu; ++ dev->mtu = 1500; ++#endif ++ ++#if defined (CONFIG_RAETH_HW_LRO) ++ dev->features |= NETIF_F_HW_CSUM; ++#else ++ dev->features |= NETIF_F_IP_CSUM; /* Can checksum TCP/UDP over IPv4 */ ++#endif /* CONFIG_RAETH_HW_LRO */ ++ ++#if defined(CONFIG_RALINK_MT7620) ++#if defined (CONFIG_RAETH_TSO) ++ if ((sysRegRead(0xB000000C) & 0xf) >= 0x5) { ++ dev->features |= NETIF_F_SG; ++ dev->features |= NETIF_F_TSO; ++ } ++#endif // CONFIG_RAETH_TSO // ++ ++#if defined (CONFIG_RAETH_TSOV6) ++ if ((sysRegRead(0xB000000C) & 0xf) >= 0x5) { ++ dev->features |= NETIF_F_TSO6; ++ dev->features |= NETIF_F_IPV6_CSUM; /* Can checksum TCP/UDP over IPv6 */ ++ } ++#endif ++#else ++#if defined (CONFIG_RAETH_TSO) ++ dev->features |= NETIF_F_SG; ++ dev->features |= NETIF_F_TSO; ++#endif // CONFIG_RAETH_TSO // ++ ++#if defined (CONFIG_RAETH_TSOV6) ++ dev->features |= NETIF_F_TSO6; ++ dev->features |= NETIF_F_IPV6_CSUM; /* Can checksum TCP/UDP over IPv6 */ ++#endif ++#endif // CONFIG_RALINK_MT7620 // ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(3,10,0) ++ dev->vlan_features = dev->features; ++#endif ++ ++ ++#if defined (CONFIG_ETHTOOL) /*&& defined (CONFIG_RAETH_ROUTER)*/ ++ dev->ethtool_ops = &ra_virt_ethtool_ops; ++ // init mii structure ++ pPseudoAd->mii_info.dev = dev; ++ pPseudoAd->mii_info.mdio_read = mdio_virt_read; ++ pPseudoAd->mii_info.mdio_write = mdio_virt_write; ++ pPseudoAd->mii_info.phy_id_mask = 0x1f; ++ pPseudoAd->mii_info.reg_num_mask = 0x1f; ++ pPseudoAd->mii_info.phy_id = 0x1e; ++ pPseudoAd->mii_info.supports_gmii = mii_check_gmii_support(&pPseudoAd->mii_info); ++#endif ++ ++ // Register this device ++ register_netdevice(dev); ++ } ++} ++#endif ++ ++/** ++ * ei_open - Open/Initialize the ethernet port. ++ * @dev: network device to initialize ++ * ++ * This routine goes all-out, setting everything ++ * up a new at each open, even though many of these registers should only need to be set once at boot. ++ */ ++int ei_open(struct net_device *dev) ++{ ++ int i, err; ++#if !defined (CONFIG_MT7623_FPGA) ++ unsigned long flags; ++#endif ++ END_DEVICE *ei_local; ++ ++#ifdef CONFIG_RAETH_LRO ++ const char *lan_ip_tmp; ++#ifdef CONFIG_DUAL_IMAGE ++#define RT2860_NVRAM 1 ++#else ++#define RT2860_NVRAM 0 ++#endif ++#endif // CONFIG_RAETH_LRO // ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) ++ if (!try_module_get(THIS_MODULE)) ++ { ++ printk("%s: Cannot reserve module\n", __FUNCTION__); ++ return -1; ++ } ++#else ++ MOD_INC_USE_COUNT; ++#endif ++ ++ printk("Raeth %s (",RAETH_VERSION); ++#if defined (CONFIG_RAETH_NAPI) ++ printk("NAPI\n"); ++#elif defined (CONFIG_RA_NETWORK_TASKLET_BH) ++ printk("Tasklet"); ++#elif defined (CONFIG_RA_NETWORK_WORKQUEUE_BH) ++ printk("Workqueue"); ++#endif ++ ++#if defined (CONFIG_RAETH_SKB_RECYCLE_2K) ++ printk(",SkbRecycle"); ++#endif ++ printk(")\n"); ++ ++ ++ ei_local = netdev_priv(dev); // get device pointer from System ++ // unsigned int flags; ++ ++ if (ei_local == NULL) ++ { ++ printk(KERN_EMERG "%s: ei_open passed a non-existent device!\n", dev->name); ++ return -ENXIO; ++ } ++ ++ /* receiving packet buffer allocation - NUM_RX_DESC x MAX_RX_LENGTH */ ++ for ( i = 0; i < NUM_RX_DESC; i++) ++ { ++#if defined (CONFIG_RAETH_SKB_RECYCLE_2K) ++ ei_local->netrx0_skbuf[i] = skbmgr_dev_alloc_skb2k(); ++#else ++ ei_local->netrx0_skbuf[i] = dev_alloc_skb(MAX_RX_LENGTH + NET_IP_ALIGN); ++#endif ++ if (ei_local->netrx0_skbuf[i] == NULL ) { ++ printk("rx skbuff buffer allocation failed!"); ++ } else { ++#if !defined (CONFIG_RAETH_SCATTER_GATHER_RX_DMA) ++ skb_reserve(ei_local->netrx0_skbuf[i], NET_IP_ALIGN); ++#endif ++ } ++ ++ ++#if defined (CONFIG_RAETH_HW_LRO) ++ ei_local->netrx3_skbuf[i] = dev_alloc_skb(MAX_LRO_RX_LENGTH + NET_IP_ALIGN); ++ if (ei_local->netrx3_skbuf[i] == NULL ) { ++ printk("rx3 skbuff buffer allocation failed!"); ++ } else { ++#if !defined (CONFIG_RAETH_SCATTER_GATHER_RX_DMA) ++ skb_reserve(ei_local->netrx3_skbuf[i], NET_IP_ALIGN); ++#endif ++ } ++ ei_local->netrx2_skbuf[i] = dev_alloc_skb(MAX_LRO_RX_LENGTH + NET_IP_ALIGN); ++ if (ei_local->netrx2_skbuf[i] == NULL ) { ++ printk("rx2 skbuff buffer allocation failed!"); ++ } else { ++#if !defined (CONFIG_RAETH_SCATTER_GATHER_RX_DMA) ++ skb_reserve(ei_local->netrx2_skbuf[i], NET_IP_ALIGN); ++#endif ++ } ++ ei_local->netrx1_skbuf[i] = dev_alloc_skb(MAX_LRO_RX_LENGTH + NET_IP_ALIGN); ++ if (ei_local->netrx1_skbuf[i] == NULL ) { ++ printk("rx1 skbuff buffer allocation failed!"); ++ } else { ++#if !defined (CONFIG_RAETH_SCATTER_GATHER_RX_DMA) ++ skb_reserve(ei_local->netrx1_skbuf[i], NET_IP_ALIGN); ++#endif ++ } ++#elif defined (CONFIG_RAETH_MULTIPLE_RX_RING) ++#if defined(CONFIG_ARCH_MT7623) ++ ei_local->netrx3_skbuf[i] = dev_alloc_skb(MAX_RX_LENGTH + NET_IP_ALIGN); ++ if (ei_local->netrx3_skbuf[i] == NULL ) { ++ printk("rx3 skbuff buffer allocation failed!"); ++ } else { ++#if !defined (CONFIG_RAETH_SCATTER_GATHER_RX_DMA) ++ skb_reserve(ei_local->netrx3_skbuf[i], NET_IP_ALIGN); ++#endif ++ } ++ ei_local->netrx2_skbuf[i] = dev_alloc_skb(MAX_RX_LENGTH + NET_IP_ALIGN); ++ if (ei_local->netrx2_skbuf[i] == NULL ) { ++ printk("rx2 skbuff buffer allocation failed!"); ++ } else { ++#if !defined (CONFIG_RAETH_SCATTER_GATHER_RX_DMA) ++ skb_reserve(ei_local->netrx2_skbuf[i], NET_IP_ALIGN); ++#endif ++ } ++#endif /* CONFIG_ARCH_MT7623 */ ++ ei_local->netrx1_skbuf[i] = dev_alloc_skb(MAX_RX_LENGTH + NET_IP_ALIGN); ++ if (ei_local->netrx1_skbuf[i] == NULL ) { ++ printk("rx1 skbuff buffer allocation failed!"); ++ } else { ++#if !defined (CONFIG_RAETH_SCATTER_GATHER_RX_DMA) ++ skb_reserve(ei_local->netrx1_skbuf[i], NET_IP_ALIGN); ++#endif ++ } ++#endif ++ } ++#if defined (CONFIG_GE1_TRGMII_FORCE_1200) && defined (CONFIG_MT7621_ASIC) ++ trgmii_set_7621(); //reset FE/GMAC in this function ++#endif ++ ++ fe_dma_init(dev); ++ ++#if defined (CONFIG_RAETH_HW_LRO) ++ fe_hw_lro_init(dev); ++#endif /* CONFIG_RAETH_HW_LRO */ ++ ++ fe_sw_init(); //initialize fe and switch register ++#if defined (CONFIG_MIPS) ++ err = request_irq( dev->irq, ei_interrupt, IRQF_DISABLED, dev->name, dev); // try to fix irq in open ++#else ++ err = request_irq(dev->irq, ei_interrupt, /*IRQF_TRIGGER_LOW*/ 0, dev->name, dev); // try to fix irq in open ++#endif ++ if (err) ++ return err; ++ ++ if ( dev->dev_addr != NULL) { ++ ra2880MacAddressSet((void *)(dev->dev_addr)); ++ } else { ++ printk("dev->dev_addr is empty !\n"); ++ } ++/*TODO: MT7623 MCM INT */ ++#if defined (CONFIG_RT_3052_ESW) && !defined(CONFIG_ARCH_MT7623) ++ err = request_irq(SURFBOARDINT_ESW, esw_interrupt, IRQF_DISABLED, "Ralink_ESW", dev); ++ if (err) ++ return err; ++ INIT_WORK(&ei_local->kill_sig_wq, kill_sig_workq); ++#if defined (CONFIG_RALINK_MT7621) ++ mii_mgr_write(31, 0x7008, 0x1f); //enable switch link change intr ++ ++#else ++ *((volatile u32 *)(RALINK_INTCL_BASE + 0x34)) = (1<<17); ++ *((volatile u32 *)(ESW_IMR)) &= ~(ESW_INT_ALL); ++ ++#if defined (CONFIG_RALINK_RT6855) || defined (CONFIG_RALINK_RT6855A) || \ ++ defined (CONFIG_RALINK_MT7620) ++ *((volatile u32 *)(ESW_P0_IntMn)) &= ~(MSK_CNT_INT_ALL); ++ *((volatile u32 *)(ESW_P1_IntMn)) &= ~(MSK_CNT_INT_ALL); ++ *((volatile u32 *)(ESW_P2_IntMn)) &= ~(MSK_CNT_INT_ALL); ++ *((volatile u32 *)(ESW_P3_IntMn)) &= ~(MSK_CNT_INT_ALL); ++ *((volatile u32 *)(ESW_P4_IntMn)) &= ~(MSK_CNT_INT_ALL); ++ *((volatile u32 *)(ESW_P5_IntMn)) &= ~(MSK_CNT_INT_ALL); ++ *((volatile u32 *)(ESW_P6_IntMn)) &= ~(MSK_CNT_INT_ALL); ++#endif ++#if defined(CONFIG_RALINK_MT7620) ++ *((volatile u32 *)(ESW_P7_IntMn)) &= ~(MSK_CNT_INT_ALL); ++#endif ++ ++#endif ++#endif // CONFIG_RT_3052_ESW // ++ ++/*TODO*/ ++#if !defined (CONFIG_MT7623_FPGA) ++ spin_lock_irqsave(&(ei_local->page_lock), flags); ++#endif ++ ++ ++#ifdef DELAY_INT ++ sysRegWrite(RAETH_DLY_INT_CFG, DELAY_INT_INIT); ++ sysRegWrite(RAETH_FE_INT_ENABLE, RAETH_FE_INT_DLY_INIT); ++ #if defined (CONFIG_RAETH_HW_LRO) ++ sysRegWrite(RAETH_FE_INT_ENABLE, RAETH_FE_INT_DLY_INIT | ALT_RPLC_INT3 | ALT_RPLC_INT2 | ALT_RPLC_INT1); ++ #endif /* CONFIG_RAETH_HW_LRO */ ++#else ++ sysRegWrite(RAETH_FE_INT_ENABLE, RAETH_FE_INT_ALL); ++ #if defined (CONFIG_RAETH_HW_LRO) ++ sysRegWrite(RAETH_FE_INT_ENABLE, RAETH_FE_INT_ALL | ALT_RPLC_INT3 | ALT_RPLC_INT2 | ALT_RPLC_INT1); ++ #endif /* CONFIG_RAETH_HW_LRO */ ++#endif ++ ++#ifdef CONFIG_RAETH_QDMA ++#ifdef DELAY_INT ++ sysRegWrite(QDMA_DELAY_INT, DELAY_INT_INIT); ++ sysRegWrite(QFE_INT_ENABLE, QFE_INT_DLY_INIT); ++#else ++ sysRegWrite(QFE_INT_ENABLE, QFE_INT_ALL); ++ ++#endif ++#endif ++ ++ INIT_WORK(&ei_local->reset_task, ei_reset_task); ++ ++#ifdef WORKQUEUE_BH ++#ifndef CONFIG_RAETH_NAPI ++ INIT_WORK(&ei_local->rx_wq, ei_receive_workq); ++#endif // CONFIG_RAETH_NAPI // ++#else ++#ifndef CONFIG_RAETH_NAPI ++#if defined (TASKLET_WORKQUEUE_SW) ++ working_schedule = init_schedule; ++ INIT_WORK(&ei_local->rx_wq, ei_receive_workq); ++ tasklet_init(&ei_local->rx_tasklet, ei_receive_workq, 0); ++#else ++ tasklet_init(&ei_local->rx_tasklet, ei_receive, 0); ++#endif ++#endif // CONFIG_RAETH_NAPI // ++#endif // WORKQUEUE_BH // ++ ++ netif_start_queue(dev); ++ ++#ifdef CONFIG_RAETH_NAPI ++ atomic_dec(&ei_local->irq_sem); ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ napi_enable(&ei_local->napi); ++#else ++ netif_poll_enable(dev); ++#endif ++#endif ++//*TODO*/ ++#if !defined (CONFIG_MT7623_FPGA) ++ spin_unlock_irqrestore(&(ei_local->page_lock), flags); ++#endif ++ ++#ifdef CONFIG_PSEUDO_SUPPORT ++ if(ei_local->PseudoDev == NULL) { ++ RAETH_Init_PSEUDO(ei_local, dev); ++ } ++ ++ if(ei_local->PseudoDev == NULL) ++ printk("Open PseudoDev failed.\n"); ++ else ++ VirtualIF_open(ei_local->PseudoDev); ++ ++#endif ++ ++#ifdef CONFIG_RAETH_LRO ++ lan_ip_tmp = nvram_get(RT2860_NVRAM, "lan_ipaddr"); ++ str_to_ip(&lan_ip, lan_ip_tmp); ++ lro_para.lan_ip1 = lan_ip = htonl(lan_ip); ++#endif // CONFIG_RAETH_LRO // ++ ++#if defined (CONFIG_RAETH_HW_LRO) ++ INIT_WORK(&ei_local->hw_lro_wq, ei_hw_lro_workq); ++#endif /* CONFIG_RAETH_HW_LRO */ ++ ++ forward_config(dev); ++ return 0; ++} ++ ++/** ++ * ei_close - shut down network device ++ * @dev: network device to clear ++ * ++ * This routine shut down network device. ++ * ++ * ++ */ ++int ei_close(struct net_device *dev) ++{ ++ int i; ++ END_DEVICE *ei_local = netdev_priv(dev); // device pointer ++ ++ netif_stop_queue(dev); ++ ra2880stop(ei_local); ++ ++ free_irq(dev->irq, dev); ++ ++/*TODO: MT7623 MCM INT */ ++#if defined (CONFIG_RT_3052_ESW) && !defined(CONFIG_ARCH_MT7623) ++ free_irq(SURFBOARDINT_ESW, dev); ++#endif ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ cancel_work_sync(&ei_local->reset_task); ++#endif ++ ++#ifdef CONFIG_PSEUDO_SUPPORT ++ VirtualIF_close(ei_local->PseudoDev); ++#endif ++ ++ ++#ifdef WORKQUEUE_BH ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ cancel_work_sync(&ei_local->rx_wq); ++#endif ++#else ++#if defined (TASKLET_WORKQUEUE_SW) ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ cancel_work_sync(&ei_local->rx_wq); ++#endif ++#endif ++ tasklet_kill(&ei_local->tx_tasklet); ++ tasklet_kill(&ei_local->rx_tasklet); ++#endif // WORKQUEUE_BH // ++ ++#ifdef CONFIG_RAETH_NAPI ++ atomic_inc(&ei_local->irq_sem); ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ napi_disable(&ei_local->napi); ++#else ++ netif_poll_disable(dev); ++#endif ++#endif ++ ++ ++#if defined (CONFIG_RAETH_HW_LRO) ++ cancel_work_sync(&ei_local->hw_lro_wq); ++#endif /* CONFIG_RAETH_HW_LRO */ ++ ++ for ( i = 0; i < NUM_RX_DESC; i++) ++ { ++ if (ei_local->netrx0_skbuf[i] != NULL) { ++ dev_kfree_skb(ei_local->netrx0_skbuf[i]); ++ ei_local->netrx0_skbuf[i] = NULL; ++ } ++#if defined (CONFIG_RAETH_HW_LRO) ++ if (ei_local->netrx3_skbuf[i] != NULL) { ++ dev_kfree_skb(ei_local->netrx3_skbuf[i]); ++ ei_local->netrx3_skbuf[i] = NULL; ++ } ++ if (ei_local->netrx2_skbuf[i] != NULL) { ++ dev_kfree_skb(ei_local->netrx2_skbuf[i]); ++ ei_local->netrx2_skbuf[i] = NULL; ++ } ++ if (ei_local->netrx1_skbuf[i] != NULL) { ++ dev_kfree_skb(ei_local->netrx1_skbuf[i]); ++ ei_local->netrx1_skbuf[i] = NULL; ++ } ++#elif defined (CONFIG_RAETH_MULTIPLE_RX_RING) ++#if defined(CONFIG_ARCH_MT7623) ++ if (ei_local->netrx3_skbuf[i] != NULL) { ++ dev_kfree_skb(ei_local->netrx3_skbuf[i]); ++ ei_local->netrx3_skbuf[i] = NULL; ++ } ++ if (ei_local->netrx2_skbuf[i] != NULL) { ++ dev_kfree_skb(ei_local->netrx2_skbuf[i]); ++ ei_local->netrx2_skbuf[i] = NULL; ++ } ++#endif /* CONFIG_ARCH_MT7623 */ ++ if (ei_local->netrx1_skbuf[i] != NULL) { ++ dev_kfree_skb(ei_local->netrx1_skbuf[i]); ++ ei_local->netrx1_skbuf[i] = NULL; ++ } ++#endif ++ } ++ ++ for ( i = 0; i < NUM_TX_DESC; i++) ++ { ++ if((ei_local->skb_free[i]!=(struct sk_buff *)0xFFFFFFFF) && (ei_local->skb_free[i]!= 0)) ++ { ++ dev_kfree_skb_any(ei_local->skb_free[i]); ++ } ++ } ++ ++ /* TX Ring */ ++#ifdef CONFIG_RAETH_QDMA ++ if (ei_local->txd_pool != NULL) { ++ pci_free_consistent(NULL, NUM_TX_DESC*sizeof(struct QDMA_txdesc), ei_local->txd_pool, ei_local->phy_txd_pool); ++ } ++ if (ei_local->free_head != NULL){ ++ pci_free_consistent(NULL, NUM_QDMA_PAGE * sizeof(struct QDMA_txdesc), ei_local->free_head, ei_local->phy_free_head); ++ } ++ if (ei_local->free_page_head != NULL){ ++ pci_free_consistent(NULL, NUM_QDMA_PAGE * QDMA_PAGE_SIZE, ei_local->free_page_head, ei_local->phy_free_page_head); ++ } ++#else ++ if (ei_local->tx_ring0 != NULL) { ++ pci_free_consistent(NULL, NUM_TX_DESC*sizeof(struct PDMA_txdesc), ei_local->tx_ring0, ei_local->phy_tx_ring0); ++ } ++#endif ++ ++#if defined (CONFIG_RAETH_QOS) ++ if (ei_local->tx_ring1 != NULL) { ++ pci_free_consistent(NULL, NUM_TX_DESC*sizeof(struct PDMA_txdesc), ei_local->tx_ring1, ei_local->phy_tx_ring1); ++ } ++ ++#if !defined (CONFIG_RALINK_RT2880) ++ if (ei_local->tx_ring2 != NULL) { ++ pci_free_consistent(NULL, NUM_TX_DESC*sizeof(struct PDMA_txdesc), ei_local->tx_ring2, ei_local->phy_tx_ring2); ++ } ++ ++ if (ei_local->tx_ring3 != NULL) { ++ pci_free_consistent(NULL, NUM_TX_DESC*sizeof(struct PDMA_txdesc), ei_local->tx_ring3, ei_local->phy_tx_ring3); ++ } ++#endif ++#endif ++ /* RX Ring */ ++#ifdef CONFIG_32B_DESC ++ kfree(ei_local->rx_ring0); ++#else ++ pci_free_consistent(NULL, NUM_RX_DESC*sizeof(struct PDMA_rxdesc), ei_local->rx_ring0, ei_local->phy_rx_ring0); ++#endif ++#if defined CONFIG_RAETH_QDMA && !defined(CONFIG_RAETH_QDMATX_QDMARX) ++#ifdef CONFIG_32B_DESC ++ kfree(ei_local->qrx_ring); ++#else ++ pci_free_consistent(NULL, NUM_QRX_DESC*sizeof(struct PDMA_rxdesc), ei_local->qrx_ring, ei_local->phy_qrx_ring); ++#endif ++#endif ++#if defined (CONFIG_RAETH_HW_LRO) ++ pci_free_consistent(NULL, NUM_LRO_RX_DESC*sizeof(struct PDMA_rxdesc), ei_local->rx_ring3, ei_local->phy_rx_ring3); ++ pci_free_consistent(NULL, NUM_LRO_RX_DESC*sizeof(struct PDMA_rxdesc), ei_local->rx_ring2, ei_local->phy_rx_ring2); ++ pci_free_consistent(NULL, NUM_LRO_RX_DESC*sizeof(struct PDMA_rxdesc), ei_local->rx_ring1, ei_local->phy_rx_ring1); ++#elif defined (CONFIG_RAETH_MULTIPLE_RX_RING) ++#ifdef CONFIG_32B_DESC ++ kfree(ei_local->rx_ring1); ++#else ++#if defined(CONFIG_ARCH_MT7623) ++ pci_free_consistent(NULL, NUM_RX_DESC*sizeof(struct PDMA_rxdesc), ei_local->rx_ring3, ei_local->phy_rx_ring3); ++ pci_free_consistent(NULL, NUM_RX_DESC*sizeof(struct PDMA_rxdesc), ei_local->rx_ring2, ei_local->phy_rx_ring2); ++#endif /* CONFIG_ARCH_MT7623 */ ++ pci_free_consistent(NULL, NUM_RX_DESC*sizeof(struct PDMA_rxdesc), ei_local->rx_ring1, ei_local->phy_rx_ring1); ++#endif ++#endif ++ ++ printk("Free TX/RX Ring Memory!\n"); ++ ++ fe_reset(); ++ ++#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) ++ module_put(THIS_MODULE); ++#else ++ MOD_DEC_USE_COUNT; ++#endif ++ return 0; ++} ++ ++#if defined (CONFIG_RT6855A_FPGA) ++void rt6855A_eth_gpio_reset(void) ++{ ++ u8 ether_gpio = 12; ++ ++ /* Load the ethernet gpio value to reset Ethernet PHY */ ++ *(unsigned long *)(RALINK_PIO_BASE + 0x00) |= 1<<(ether_gpio<<1); ++ *(unsigned long *)(RALINK_PIO_BASE + 0x14) |= 1<<(ether_gpio); ++ *(unsigned long *)(RALINK_PIO_BASE + 0x04) &= ~(1<<ether_gpio); ++ ++ udelay(100000); ++ ++ *(unsigned long *)(RALINK_PIO_BASE + 0x04) |= (1<<ether_gpio); ++ ++ /* must wait for 0.6 seconds after reset*/ ++ udelay(600000); ++} ++#endif ++ ++#if defined(CONFIG_RALINK_RT6855A) ++void rt6855A_gsw_init(void) ++{ ++ u32 phy_val=0; ++ u32 rev=0; ++ ++#if defined (CONFIG_RT6855A_FPGA) ++ /*keep dump switch mode */ ++ rt6855A_eth_gpio_reset(); ++ ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3000) = 0x5e353;//(P0,Force mode,Link Up,100Mbps,Full-Duplex,FC ON) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3100) = 0x5e353;//(P1,Force mode,Link Up,100Mbps,Full-Duplex,FC ON) ++ //*(unsigned long *)(RALINK_ETH_SW_BASE+0x3000) = 0x5e333;//(P0,Force mode,Link Up,10Mbps,Full-Duplex,FC ON) ++ //*(unsigned long *)(RALINK_ETH_SW_BASE+0x3100) = 0x5e333;//(P1,Force mode,Link Up,10Mbps,Full-Duplex,FC ON) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3200) = 0x8000;//link down ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3300) = 0x8000;//link down ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3400) = 0x8000;//link down ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3500) = 0x8000;//link down ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3600) = 0x5e33b;//CPU Port6 Force Link 1G, FC ON ++ ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x0010) = 0xffffffe0;//Set Port6 CPU Port ++ ++ /* In order to use 10M/Full on FPGA board. We configure phy capable to ++ * 10M Full/Half duplex, so we can use auto-negotiation on PC side */ ++ for(i=6;i<8;i++){ ++ mii_mgr_write(i, 4, 0x07e1); //Capable of 10M&100M Full/Half Duplex, flow control on/off ++ //mii_mgr_write(i, 4, 0x0461); //Capable of 10M Full/Half Duplex, flow control on/off ++ mii_mgr_write(i, 0, 0xB100); //reset all digital logic, except phy_reg ++ mii_mgr_read(i, 9, &phy_val); ++ phy_val &= ~(3<<8); //turn off 1000Base-T Advertisement (9.9=1000Full, 9.8=1000Half) ++ mii_mgr_write(i, 9, phy_val); ++ } ++#elif defined (CONFIG_RT6855A_ASIC) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3600) = 0x5e33b;//CPU Port6 Force Link 1G, FC ON ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x0010) = 0xffffffe0;//Set Port6 CPU Port ++ ++ *(unsigned long *)(RALINK_FRAME_ENGINE_BASE+0x1ec) = 0x0fffffff;//Set PSE should pause 4 tx ring as default ++ *(unsigned long *)(RALINK_FRAME_ENGINE_BASE+0x1f0) = 0x0fffffff;//switch IOT more stable ++ ++ *(unsigned long *)(CKGCR) &= ~(0x3 << 4); //keep rx/tx port clock ticking, disable internal clock-gating to avoid switch stuck ++ ++ /* ++ *Reg 31: Page Control ++ * Bit 15 => PortPageSel, 1=local, 0=global ++ * Bit 14:12 => PageSel, local:0~3, global:0~4 ++ * ++ *Reg16~30:Local/Global registers ++ * ++ */ ++ /*correct PHY setting J8.0*/ ++ mii_mgr_read(0, 31, &rev); ++ rev &= (0x0f); ++ ++ mii_mgr_write(1, 31, 0x4000); //global, page 4 ++ ++ mii_mgr_write(1, 16, 0xd4cc); ++ mii_mgr_write(1, 17, 0x7444); ++ mii_mgr_write(1, 19, 0x0112); ++ mii_mgr_write(1, 21, 0x7160); ++ mii_mgr_write(1, 22, 0x10cf); ++ mii_mgr_write(1, 26, 0x0777); ++ ++ if(rev == 0){ ++ mii_mgr_write(1, 25, 0x0102); ++ mii_mgr_write(1, 29, 0x8641); ++ } ++ else{ ++ mii_mgr_write(1, 25, 0x0212); ++ mii_mgr_write(1, 29, 0x4640); ++ } ++ ++ mii_mgr_write(1, 31, 0x2000); //global, page 2 ++ mii_mgr_write(1, 21, 0x0655); ++ mii_mgr_write(1, 22, 0x0fd3); ++ mii_mgr_write(1, 23, 0x003d); ++ mii_mgr_write(1, 24, 0x096e); ++ mii_mgr_write(1, 25, 0x0fed); ++ mii_mgr_write(1, 26, 0x0fc4); ++ ++ mii_mgr_write(1, 31, 0x1000); //global, page 1 ++ mii_mgr_write(1, 17, 0xe7f8); ++ ++ ++ mii_mgr_write(1, 31, 0xa000); //local, page 2 ++ ++ mii_mgr_write(0, 16, 0x0e0e); ++ mii_mgr_write(1, 16, 0x0c0c); ++ mii_mgr_write(2, 16, 0x0f0f); ++ mii_mgr_write(3, 16, 0x1010); ++ mii_mgr_write(4, 16, 0x0909); ++ ++ mii_mgr_write(0, 17, 0x0000); ++ mii_mgr_write(1, 17, 0x0000); ++ mii_mgr_write(2, 17, 0x0000); ++ mii_mgr_write(3, 17, 0x0000); ++ mii_mgr_write(4, 17, 0x0000); ++#endif ++ ++#if defined (CONFIG_RT6855A_ASIC) ++ ++#if defined (CONFIG_P5_RGMII_TO_MAC_MODE) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3500) = 0x5e33b;//(P5, Force mode, Link Up, 1000Mbps, Full-Duplex, FC ON) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x7014) = 0x1f0c000c;//disable port0-port4 internal phy, set phy base address to 12 ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x250c) = 0x000fff10;//disable port5 mac learning ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x260c) = 0x000fff10;//disable port6 mac learning ++ ++#elif defined (CONFIG_P5_MII_TO_MAC_MODE) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3500) = 0x5e337;//(P5, Force mode, Link Up, 100Mbps, Full-Duplex, FC ON) ++#elif defined (CONFIG_P5_MAC_TO_PHY_MODE) ++ //rt6855/6 need to modify TX/RX phase ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x7014) = 0xc;//TX/RX CLOCK Phase select ++ ++ enable_auto_negotiate(1); ++ ++ if (isICPlusGigaPHY(1)) { ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 4, &phy_val); ++ phy_val |= 1<<10; //enable pause ability ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 4, phy_val); ++ ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 0, &phy_val); ++ phy_val |= 1<<9; //restart AN ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 0, phy_val); ++ } ++ ++ if (isMarvellGigaPHY(1)) { ++ printk("Reset MARVELL phy1\n"); ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 20, &phy_val); ++ phy_val |= 1<<7; //Add delay to RX_CLK for RXD Outputs ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 20, phy_val); ++ ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 0, &phy_val); ++ phy_val |= 1<<15; //PHY Software Reset ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 0, phy_val); ++ } ++ if (isVtssGigaPHY(1)) { ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 31, 0x0001); //extended page ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 28, &phy_val); ++ printk("Vitesse phy skew: %x --> ", phy_val); ++ phy_val |= (0x3<<12); // RGMII RX skew compensation= 2.0 ns ++ phy_val &= ~(0x3<<14);// RGMII TX skew compensation= 0 ns ++ printk("%x\n", phy_val); ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 28, phy_val); ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 31, 0x0000); //main registers ++ } ++#elif defined (CONFIG_P5_RMII_TO_MAC_MODE) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3500) = 0x5e337;//(P5, Force mode, Link Up, 100Mbps, Full-Duplex, FC ON) ++#else // Port 5 Disabled // ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3500) = 0x8000;//link down ++#endif ++#endif ++} ++#endif ++ ++ ++ ++ ++#if defined (CONFIG_MT7623_FPGA) ++void setup_fpga_gsw(void) ++{ ++ u32 i; ++ u32 regValue; ++ ++ /* reduce RGMII2 PAD driving strength */ ++ *(volatile u_long *)(PAD_RGMII2_MDIO_CFG) &= ~(0x3 << 4); ++ ++ //RGMII1=Normal mode ++ *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x60) &= ~(0x1 << 14); ++ ++ //GMAC1= RGMII mode ++ *(volatile u_long *)(SYSCFG1) &= ~(0x3 << 12); ++ ++ //enable MDIO to control MT7530 ++ regValue = le32_to_cpu(*(volatile u_long *)(RALINK_SYSCTL_BASE + 0x60)); ++ regValue &= ~(0x3 << 12); ++ *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x60) = regValue; ++ ++ for(i=0;i<=4;i++) ++ { ++ //turn off PHY ++ mii_mgr_read(i, 0x0 ,®Value); ++ regValue |= (0x1<<11); ++ mii_mgr_write(i, 0x0, regValue); ++ } ++ mii_mgr_write(31, 0x7000, 0x3); //reset switch ++ udelay(10); ++ sysRegWrite(RALINK_ETH_SW_BASE+0x100, 0x2105e337);//(GE1, Force 100M/FD, FC ON) ++ mii_mgr_write(31, 0x3600, 0x5e337); ++ ++ sysRegWrite(RALINK_ETH_SW_BASE+0x200, 0x00008000);//(GE2, Link down) ++ mii_mgr_write(31, 0x3500, 0x8000); ++ ++#if defined (CONFIG_GE1_RGMII_FORCE_1000) || defined (CONFIG_GE1_TRGMII_FORCE_1200) || defined (CONFIG_GE1_TRGMII_FORCE_2000) || defined (CONFIG_GE1_TRGMII_FORCE_2600) ++ //regValue = 0x117ccf; //Enable Port 6, P5 as GMAC5, P5 disable*/ ++ mii_mgr_read(31, 0x7804 ,®Value); ++ regValue &= ~(1<<8); //Enable Port 6 ++ regValue |= (1<<6); //Disable Port 5 ++ regValue |= (1<<13); //Port 5 as GMAC, no Internal PHY ++ ++#if defined (CONFIG_RAETH_GMAC2) ++ //RGMII2=Normal mode ++ *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x60) &= ~(0x1 << 15); ++ ++ //GMAC2= RGMII mode ++ *(volatile u_long *)(SYSCFG1) &= ~(0x3 << 14); ++ ++ mii_mgr_write(31, 0x3500, 0x56300); //MT7530 P5 AN, we can ignore this setting?????? ++ sysRegWrite(RALINK_ETH_SW_BASE+0x200, 0x21056300);//(GE2, auto-polling) ++ ++ enable_auto_negotiate(0);//set polling address ++ /* set MT7530 Port 5 to PHY 0/4 mode */ ++#if defined (CONFIG_GE_RGMII_INTERNAL_P0_AN) ++ regValue &= ~((1<<13)|(1<<6)); ++ regValue |= ((1<<7)|(1<<16)|(1<<20)); ++#elif defined (CONFIG_GE_RGMII_INTERNAL_P4_AN) ++ regValue &= ~((1<<13)|(1<<6)|((1<<20))); ++ regValue |= ((1<<7)|(1<<16)); ++#endif ++ ++ //sysRegWrite(GDMA2_FWD_CFG, 0x20710000); ++#endif ++ regValue |= (1<<16);//change HW-TRAP ++ printk("change HW-TRAP to 0x%x\n",regValue); ++ mii_mgr_write(31, 0x7804 ,regValue); ++#endif ++ mii_mgr_write(0, 14, 0x1); /*RGMII*/ ++/* set MT7530 central align */ ++ mii_mgr_read(31, 0x7830, ®Value); ++ regValue &= ~1; ++ regValue |= 1<<1; ++ mii_mgr_write(31, 0x7830, regValue); ++ ++ mii_mgr_read(31, 0x7a40, ®Value); ++ regValue &= ~(1<<30); ++ mii_mgr_write(31, 0x7a40, regValue); ++ ++ regValue = 0x855; ++ mii_mgr_write(31, 0x7a78, regValue); ++ ++/*to check!!*/ ++ mii_mgr_write(31, 0x7b00, 0x102); //delay setting for 10/1000M ++ mii_mgr_write(31, 0x7b04, 0x14); //delay setting for 10/1000M ++ ++ for(i=0;i<=4;i++) { ++ mii_mgr_read(i, 4, ®Value); ++ regValue |= (3<<7); //turn on 100Base-T Advertisement ++ //regValue &= ~(3<<7); //turn off 100Base-T Advertisement ++ mii_mgr_write(i, 4, regValue); ++ ++ mii_mgr_read(i, 9, ®Value); ++ //regValue |= (3<<8); //turn on 1000Base-T Advertisement ++ regValue &= ~(3<<8); //turn off 1000Base-T Advertisement ++ mii_mgr_write(i, 9, regValue); ++ ++ //restart AN ++ mii_mgr_read(i, 0, ®Value); ++ regValue |= (1 << 9); ++ mii_mgr_write(i, 0, regValue); ++ } ++ ++ /*Tx Driving*/ ++ mii_mgr_write(31, 0x7a54, 0x44); //lower driving ++ mii_mgr_write(31, 0x7a5c, 0x44); //lower driving ++ mii_mgr_write(31, 0x7a64, 0x44); //lower driving ++ mii_mgr_write(31, 0x7a6c, 0x44); //lower driving ++ mii_mgr_write(31, 0x7a74, 0x44); //lower driving ++ mii_mgr_write(31, 0x7a7c, 0x44); //lower driving ++ ++ for(i=0;i<=4;i++) ++ { ++ //turn on PHY ++ mii_mgr_read(i, 0x0 ,®Value); ++ regValue &= ~(0x1<<11); ++ mii_mgr_write(i, 0x0, regValue); ++ } ++} ++#endif ++ ++ ++#if defined (CONFIG_RALINK_MT7621) ++ ++ ++void setup_external_gsw(void) ++{ ++ u32 regValue; ++ ++ /* reduce RGMII2 PAD driving strength */ ++ *(volatile u_long *)(PAD_RGMII2_MDIO_CFG) &= ~(0x3 << 4); ++ //enable MDIO ++ regValue = le32_to_cpu(*(volatile u_long *)(RALINK_SYSCTL_BASE + 0x60)); ++ regValue &= ~(0x3 << 12); ++ *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x60) = regValue; ++ ++ //RGMII1=Normal mode ++ *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x60) &= ~(0x1 << 14); ++ //GMAC1= RGMII mode ++ *(volatile u_long *)(SYSCFG1) &= ~(0x3 << 12); ++ ++ sysRegWrite(RALINK_ETH_SW_BASE+0x100, 0x00008000);//(GE1, Link down) ++ ++ //RGMII2=Normal mode ++ *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x60) &= ~(0x1 << 15); ++ //GMAC2= RGMII mode ++ *(volatile u_long *)(SYSCFG1) &= ~(0x3 << 14); ++ ++ sysRegWrite(RALINK_ETH_SW_BASE+0x200, 0x2105e33b);//(GE2, Force 1000M/FD, FC ON) ++ ++} ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++void IsSwitchVlanTableBusy(void) ++{ ++ int j = 0; ++ unsigned int value = 0; ++ ++ for (j = 0; j < 20; j++) { ++ mii_mgr_read(31, 0x90, &value); ++ if ((value & 0x80000000) == 0 ){ //table busy ++ break; ++ } ++ udelay(70000); ++ } ++ if (j == 20) ++ printk("set vlan timeout value=0x%x.\n", value); ++} ++ ++void LANWANPartition(void) ++{ ++/*Set MT7530 */ ++#ifdef CONFIG_WAN_AT_P0 ++ printk("set LAN/WAN WLLLL\n"); ++ //WLLLL, wan at P0 ++ //LAN/WAN ports as security mode ++ mii_mgr_write(31, 0x2004, 0xff0003);//port0 ++ mii_mgr_write(31, 0x2104, 0xff0003);//port1 ++ mii_mgr_write(31, 0x2204, 0xff0003);//port2 ++ mii_mgr_write(31, 0x2304, 0xff0003);//port3 ++ mii_mgr_write(31, 0x2404, 0xff0003);//port4 ++ ++ //set PVID ++ mii_mgr_write(31, 0x2014, 0x10002);//port0 ++ mii_mgr_write(31, 0x2114, 0x10001);//port1 ++ mii_mgr_write(31, 0x2214, 0x10001);//port2 ++ mii_mgr_write(31, 0x2314, 0x10001);//port3 ++ mii_mgr_write(31, 0x2414, 0x10001);//port4 ++ /*port6 */ ++ //VLAN member ++ IsSwitchVlanTableBusy(); ++ mii_mgr_write(31, 0x94, 0x407e0001);//VAWD1 ++ mii_mgr_write(31, 0x90, 0x80001001);//VTCR, VID=1 ++ IsSwitchVlanTableBusy(); ++ ++ mii_mgr_write(31, 0x94, 0x40610001);//VAWD1 ++ mii_mgr_write(31, 0x90, 0x80001002);//VTCR, VID=2 ++ IsSwitchVlanTableBusy(); ++#endif ++#ifdef CONFIG_WAN_AT_P4 ++ printk("set LAN/WAN LLLLW\n"); ++ //LLLLW, wan at P4 ++ //LAN/WAN ports as security mode ++ mii_mgr_write(31, 0x2004, 0xff0003);//port0 ++ mii_mgr_write(31, 0x2104, 0xff0003);//port1 ++ mii_mgr_write(31, 0x2204, 0xff0003);//port2 ++ mii_mgr_write(31, 0x2304, 0xff0003);//port3 ++ mii_mgr_write(31, 0x2404, 0xff0003);//port4 ++ ++ //set PVID ++ mii_mgr_write(31, 0x2014, 0x10001);//port0 ++ mii_mgr_write(31, 0x2114, 0x10001);//port1 ++ mii_mgr_write(31, 0x2214, 0x10001);//port2 ++ mii_mgr_write(31, 0x2314, 0x10001);//port3 ++ mii_mgr_write(31, 0x2414, 0x10002);//port4 ++ ++ //VLAN member ++ IsSwitchVlanTableBusy(); ++ mii_mgr_write(31, 0x94, 0x404f0001);//VAWD1 ++ mii_mgr_write(31, 0x90, 0x80001001);//VTCR, VID=1 ++ IsSwitchVlanTableBusy(); ++ mii_mgr_write(31, 0x94, 0x40500001);//VAWD1 ++ mii_mgr_write(31, 0x90, 0x80001002);//VTCR, VID=2 ++ IsSwitchVlanTableBusy(); ++#endif ++} ++ ++#if defined (CONFIG_RAETH_8023AZ_EEE) && defined (CONFIG_RALINK_MT7621) ++void mt7621_eee_patch(void) ++{ ++ u32 i; ++ ++ for(i=0;i<5;i++) ++ { ++ /* Enable EEE */ ++ mii_mgr_write(i, 13, 0x07); ++ mii_mgr_write(i, 14, 0x3c); ++ mii_mgr_write(i, 13, 0x4007); ++ mii_mgr_write(i, 14, 0x6); ++ ++ /* Forced Slave mode */ ++ mii_mgr_write(i, 31, 0x0); ++ mii_mgr_write(i, 9, 0x1600); ++ /* Increase SlvDPSready time */ ++ mii_mgr_write(i, 31, 0x52b5); ++ mii_mgr_write(i, 16, 0xafae); ++ mii_mgr_write(i, 18, 0x2f); ++ mii_mgr_write(i, 16, 0x8fae); ++ /* Incease post_update_timer */ ++ mii_mgr_write(i, 31, 0x3); ++ mii_mgr_write(i, 17, 0x4b); ++ /* Adjust 100_mse_threshold */ ++ mii_mgr_write(i, 13, 0x1e); ++ mii_mgr_write(i, 14, 0x123); ++ mii_mgr_write(i, 13, 0x401e); ++ mii_mgr_write(i, 14, 0xffff); ++ /* Disable mcc ++ mii_mgr_write(i, 13, 0x1e); ++ mii_mgr_write(i, 14, 0xa6); ++ mii_mgr_write(i, 13, 0x401e); ++ mii_mgr_write(i, 14, 0x300); ++ */ ++ } ++ ++} ++#endif ++ ++ ++#if defined (CONFIG_RALINK_MT7621) ++void setup_internal_gsw(void) ++{ ++ u32 i; ++ u32 regValue; ++ ++#if defined (CONFIG_GE1_RGMII_FORCE_1000) || defined (CONFIG_GE1_TRGMII_FORCE_1200) || defined (CONFIG_GE1_TRGMII_FORCE_2000) || defined (CONFIG_GE1_TRGMII_FORCE_2600) ++ /*Hardware reset Switch*/ ++ *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x34) |= (0x1 << 2); ++ udelay(1000); ++ *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x34) &= ~(0x1 << 2); ++ udelay(10000); ++ ++ /* reduce RGMII2 PAD driving strength */ ++ *(volatile u_long *)(PAD_RGMII2_MDIO_CFG) &= ~(0x3 << 4); ++ ++ //RGMII1=Normal mode ++ *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x60) &= ~(0x1 << 14); ++ ++ //GMAC1= RGMII mode ++ *(volatile u_long *)(SYSCFG1) &= ~(0x3 << 12); ++ ++ //enable MDIO to control MT7530 ++ regValue = le32_to_cpu(*(volatile u_long *)(RALINK_SYSCTL_BASE + 0x60)); ++ regValue &= ~(0x3 << 12); ++ *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x60) = regValue; ++ ++ for(i=0;i<=4;i++) ++ { ++ //turn off PHY ++ mii_mgr_read(i, 0x0 ,®Value); ++ regValue |= (0x1<<11); ++ mii_mgr_write(i, 0x0, regValue); ++ } ++ mii_mgr_write(31, 0x7000, 0x3); //reset switch ++ udelay(100); ++ ++ ++#if defined (CONFIG_GE1_TRGMII_FORCE_1200) && defined (CONFIG_MT7621_ASIC) ++ trgmii_set_7530(); //reset FE, config MDIO again ++ ++ //enable MDIO to control MT7530 ++ regValue = le32_to_cpu(*(volatile u_long *)(RALINK_SYSCTL_BASE + 0x60)); ++ regValue &= ~(0x3 << 12); ++ *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x60) = regValue; ++ ++ // switch to APLL if TRGMII and DDR2 ++ if ((sysRegRead(0xBE000010)>>4)&0x1) ++ { ++ apll_xtal_enable(); ++ } ++#endif ++ ++#if defined (CONFIG_MT7621_ASIC) ++ if((sysRegRead(0xbe00000c)&0xFFFF)==0x0101) { ++ sysRegWrite(RALINK_ETH_SW_BASE+0x100, 0x2105e30b);//(GE1, Force 1000M/FD, FC ON) ++ mii_mgr_write(31, 0x3600, 0x5e30b); ++ } else { ++ sysRegWrite(RALINK_ETH_SW_BASE+0x100, 0x2105e33b);//(GE1, Force 1000M/FD, FC ON) ++ mii_mgr_write(31, 0x3600, 0x5e33b); ++ } ++#elif defined (CONFIG_MT7621_FPGA) ++ sysRegWrite(RALINK_ETH_SW_BASE+0x100, 0x2105e337);//(GE1, Force 100M/FD, FC ON) ++ mii_mgr_write(31, 0x3600, 0x5e337); ++#endif ++ ++ sysRegWrite(RALINK_ETH_SW_BASE+0x200, 0x00008000);//(GE2, Link down) ++#endif ++ ++#if defined (CONFIG_GE1_RGMII_FORCE_1000) || defined (CONFIG_GE1_TRGMII_FORCE_1200) || defined (CONFIG_GE1_TRGMII_FORCE_2000) || defined (CONFIG_GE1_TRGMII_FORCE_2600) ++ //regValue = 0x117ccf; //Enable Port 6, P5 as GMAC5, P5 disable*/ ++ mii_mgr_read(31, 0x7804 ,®Value); ++ regValue &= ~(1<<8); //Enable Port 6 ++ regValue |= (1<<6); //Disable Port 5 ++ regValue |= (1<<13); //Port 5 as GMAC, no Internal PHY ++ ++#if defined (CONFIG_RAETH_GMAC2) ++ //RGMII2=Normal mode ++ *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x60) &= ~(0x1 << 15); ++ ++ //GMAC2= RGMII mode ++ *(volatile u_long *)(SYSCFG1) &= ~(0x3 << 14); ++#if !defined (CONFIG_RAETH_8023AZ_EEE) ++ mii_mgr_write(31, 0x3500, 0x56300); //MT7530 P5 AN, we can ignore this setting?????? ++ sysRegWrite(RALINK_ETH_SW_BASE+0x200, 0x21056300);//(GE2, auto-polling) ++ ++ enable_auto_negotiate(0);//set polling address ++#endif ++#if defined (CONFIG_RAETH_8023AZ_EEE) ++ mii_mgr_write(31, 0x3500, 0x5e33b); //MT7530 P5 Force 1000, we can ignore this setting?????? ++ sysRegWrite(RALINK_ETH_SW_BASE+0x200, 0x2105e33b);//(GE2, Force 1000) ++#endif ++ ++ ++ ++ /* set MT7530 Port 5 to PHY 0/4 mode */ ++#if defined (CONFIG_GE_RGMII_INTERNAL_P0_AN) ++ regValue &= ~((1<<13)|(1<<6)); ++ regValue |= ((1<<7)|(1<<16)|(1<<20)); ++#elif defined (CONFIG_GE_RGMII_INTERNAL_P4_AN) ++ regValue &= ~((1<<13)|(1<<6)|(1<<20)); ++ regValue |= ((1<<7)|(1<<16)); ++#endif ++ ++#if defined (CONFIG_RAETH_8023AZ_EEE) ++ regValue |= (1<<13); //Port 5 as GMAC, no Internal PHY ++#endif ++ //sysRegWrite(GDMA2_FWD_CFG, 0x20710000); ++#endif ++ regValue |= (1<<16);//change HW-TRAP ++ //printk("change HW-TRAP to 0x%x\n",regValue); ++ mii_mgr_write(31, 0x7804 ,regValue); ++#endif ++ mii_mgr_read(31, 0x7800, ®Value); ++ regValue = (regValue >> 9) & 0x3; ++ if(regValue == 0x3) { //25Mhz Xtal ++ /* do nothing */ ++ } else if(regValue == 0x2) { //40Mhz ++ ++ mii_mgr_write(0, 13, 0x1f); // disable MT7530 core clock ++ mii_mgr_write(0, 14, 0x410); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0x0); ++ ++ mii_mgr_write(0, 13, 0x1f); // disable MT7530 PLL ++ mii_mgr_write(0, 14, 0x40d); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0x2020); ++ ++ mii_mgr_write(0, 13, 0x1f); // for MT7530 core clock = 500Mhz ++ mii_mgr_write(0, 14, 0x40e); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0x119); ++ ++ mii_mgr_write(0, 13, 0x1f); // enable MT7530 PLL ++ mii_mgr_write(0, 14, 0x40d); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0x2820); ++ ++ udelay(20); //suggest by CD ++ ++ mii_mgr_write(0, 13, 0x1f); // enable MT7530 core clock ++ mii_mgr_write(0, 14, 0x410); ++ mii_mgr_write(0, 13, 0x401f); ++ }else { //20Mhz Xtal ++ ++ /* TODO */ ++ ++ } ++#if defined (CONFIG_GE1_TRGMII_FORCE_1200) && defined (CONFIG_MT7621_ASIC) ++ mii_mgr_write(0, 14, 0x3); /*TRGMII*/ ++#else ++ mii_mgr_write(0, 14, 0x1); /*RGMII*/ ++/* set MT7530 central align */ ++ mii_mgr_read(31, 0x7830, ®Value); ++ regValue &= ~1; ++ regValue |= 1<<1; ++ mii_mgr_write(31, 0x7830, regValue); ++ ++ mii_mgr_read(31, 0x7a40, ®Value); ++ regValue &= ~(1<<30); ++ mii_mgr_write(31, 0x7a40, regValue); ++ ++ regValue = 0x855; ++ mii_mgr_write(31, 0x7a78, regValue); ++ ++#endif ++#if !defined (CONFIG_RAETH_8023AZ_EEE) ++ mii_mgr_write(31, 0x7b00, 0x102); //delay setting for 10/1000M ++ mii_mgr_write(31, 0x7b04, 0x14); //delay setting for 10/1000M ++#endif ++#if 0 ++ for(i=0;i<=4;i++) { ++ mii_mgr_read(i, 4, ®Value); ++ regValue |= (3<<7); //turn on 100Base-T Advertisement ++ //regValue &= ~(3<<7); //turn off 100Base-T Advertisement ++ mii_mgr_write(i, 4, regValue); ++ ++ mii_mgr_read(i, 9, ®Value); ++ regValue |= (3<<8); //turn on 1000Base-T Advertisement ++ //regValue &= ~(3<<8); //turn off 1000Base-T Advertisement ++ mii_mgr_write(i, 9, regValue); ++ ++ //restart AN ++ mii_mgr_read(i, 0, ®Value); ++ regValue |= (1 << 9); ++ mii_mgr_write(i, 0, regValue); ++ } ++#endif ++ ++ /*Tx Driving*/ ++ mii_mgr_write(31, 0x7a54, 0x44); //lower driving ++ mii_mgr_write(31, 0x7a5c, 0x44); //lower driving ++ mii_mgr_write(31, 0x7a64, 0x44); //lower driving ++ mii_mgr_write(31, 0x7a6c, 0x44); //lower driving ++ mii_mgr_write(31, 0x7a74, 0x44); //lower driving ++ mii_mgr_write(31, 0x7a7c, 0x44); //lower driving ++ ++ ++ LANWANPartition(); ++ ++#if !defined (CONFIG_RAETH_8023AZ_EEE) ++ //disable EEE ++ for(i=0;i<=4;i++) ++ { ++ mii_mgr_write(i, 13, 0x7); ++ mii_mgr_write(i, 14, 0x3C); ++ mii_mgr_write(i, 13, 0x4007); ++ mii_mgr_write(i, 14, 0x0); ++ } ++ ++ //Disable EEE 10Base-Te: ++ for(i=0;i<=4;i++) ++ { ++ mii_mgr_write(i, 13, 0x1f); ++ mii_mgr_write(i, 14, 0x027b); ++ mii_mgr_write(i, 13, 0x401f); ++ mii_mgr_write(i, 14, 0x1177); ++ } ++#endif ++ ++ for(i=0;i<=4;i++) ++ { ++ //turn on PHY ++ mii_mgr_read(i, 0x0 ,®Value); ++ regValue &= ~(0x1<<11); ++ mii_mgr_write(i, 0x0, regValue); ++ } ++ ++ mii_mgr_read(31, 0x7808 ,®Value); ++ regValue |= (3<<16); //Enable INTR ++ mii_mgr_write(31, 0x7808 ,regValue); ++#if defined (CONFIG_RAETH_8023AZ_EEE) && defined (CONFIG_RALINK_MT7621) ++ mt7621_eee_patch(); ++#endif ++} ++#endif ++ ++#if defined (CONFIG_GE1_TRGMII_FORCE_1200) ++void apll_xtal_enable(void) ++{ ++ unsigned long data = 0; ++ unsigned long regValue = 0; ++ ++ /* Firstly, reset all required register to default value */ ++ sysRegWrite(RALINK_ANA_CTRL_BASE, 0x00008000); ++ sysRegWrite(RALINK_ANA_CTRL_BASE+0x0014, 0x01401d61); ++ sysRegWrite(RALINK_ANA_CTRL_BASE+0x0018, 0x38233d0e); ++ sysRegWrite(RALINK_ANA_CTRL_BASE+0x001c, 0x80120004); ++ sysRegWrite(RALINK_ANA_CTRL_BASE+0x0020, 0x1c7dbf48); ++ ++ /* toggle RG_XPTL_CHG */ ++ sysRegWrite(RALINK_ANA_CTRL_BASE, 0x00008800); ++ sysRegWrite(RALINK_ANA_CTRL_BASE, 0x00008c00); ++ ++ data = sysRegRead(RALINK_ANA_CTRL_BASE+0x0014); ++ data &= ~(0x0000ffc0); ++ ++ regValue = *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x10); ++ regValue = (regValue >> 6) & 0x7; ++ if(regValue < 6) { //20/40Mhz Xtal ++ data |= REGBIT(0x1d, 8); ++ }else { ++ data |= REGBIT(0x17, 8); ++ } ++ ++ if(regValue < 6) { //20/40Mhz Xtal ++ data |= REGBIT(0x1, 6); ++ } ++ ++ sysRegWrite(RALINK_ANA_CTRL_BASE+0x0014, data); ++ ++ data = sysRegRead(RALINK_ANA_CTRL_BASE+0x0018); ++ data &= ~(0xf0773f00); ++ data |= REGBIT(0x3, 28); ++ data |= REGBIT(0x2, 20); ++ if(regValue < 6) { //20/40Mhz Xtal ++ data |= REGBIT(0x3, 16); ++ }else { ++ data |= REGBIT(0x2, 16); ++ } ++ data |= REGBIT(0x3, 12); ++ ++ if(regValue < 6) { //20/40Mhz Xtal ++ data |= REGBIT(0xd, 8); ++ }else { ++ data |= REGBIT(0x7, 8); ++ } ++ sysRegWrite(RALINK_ANA_CTRL_BASE+0x0018, data); ++ ++ if(regValue < 6) { //20/40Mhz Xtal ++ sysRegWrite(RALINK_ANA_CTRL_BASE+0x0020, 0x1c7dbf48); ++ }else { ++ sysRegWrite(RALINK_ANA_CTRL_BASE+0x0020, 0x1697cc39); ++ } ++ //*Common setting - Set PLLGP_CTRL_4 *// ++ ///* 1. Bit 31 */ ++ data = sysRegRead(RALINK_ANA_CTRL_BASE+0x001c); ++ data &= ~(REGBIT(0x1, 31)); ++ sysRegWrite(RALINK_ANA_CTRL_BASE+0x001c, data); ++ ++ /* 2. Bit 0 */ ++ data = sysRegRead(RALINK_ANA_CTRL_BASE+0x001c); ++ data |= REGBIT(0x1, 0); ++ sysRegWrite(RALINK_ANA_CTRL_BASE+0x001c, data); ++ ++ /* 3. Bit 3 */ ++ data = sysRegRead(RALINK_ANA_CTRL_BASE+0x001c); ++ data |= REGBIT(0x1, 3); ++ sysRegWrite(RALINK_ANA_CTRL_BASE+0x001c, data); ++ ++ /* 4. Bit 8 */ ++ data = sysRegRead(RALINK_ANA_CTRL_BASE+0x001c); ++ data |= REGBIT(0x1, 8); ++ sysRegWrite(RALINK_ANA_CTRL_BASE+0x001c, data); ++ ++ /* 5. Bit 6 */ ++ data = sysRegRead(RALINK_ANA_CTRL_BASE+0x001c); ++ data |= REGBIT(0x1, 6); ++ sysRegWrite(RALINK_ANA_CTRL_BASE+0x001c, data); ++ ++ /* 6. Bit 7 */ ++ data = sysRegRead(RALINK_ANA_CTRL_BASE+0x001c); ++ data |= REGBIT(0x1, 5); ++ data |= REGBIT(0x1, 7); ++ sysRegWrite(RALINK_ANA_CTRL_BASE+0x001c, data); ++ ++ /* 7. Bit 17 */ ++ data = sysRegRead(RALINK_ANA_CTRL_BASE+0x001c); ++ data &= ~REGBIT(0x1, 17); ++ sysRegWrite(RALINK_ANA_CTRL_BASE+0x001c, data); ++ ++ /* 8. TRGMII TX CLK SEL APLL */ ++ data = sysRegRead(0xbe00002c); ++ data &= 0xffffff9f; ++ data |= 0x40; ++ sysRegWrite(0xbe00002c, data); ++ ++} ++#endif ++ ++#endif ++#if defined(CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_MT7620) ++void rt_gsw_init(void) ++{ ++#if defined (CONFIG_P4_MAC_TO_PHY_MODE) || defined (CONFIG_P5_MAC_TO_PHY_MODE) ++ u32 phy_val=0; ++#endif ++#if defined (CONFIG_RT6855_FPGA) || defined (CONFIG_MT7620_FPGA) ++ u32 i=0; ++#elif defined (CONFIG_MT7620_ASIC) ++ u32 is_BGA=0; ++#endif ++#if defined (CONFIG_P5_RGMII_TO_MT7530_MODE) ++ unsigned int regValue = 0; ++#endif ++#if defined (CONFIG_RT6855_FPGA) || defined (CONFIG_MT7620_FPGA) ++ /*keep dump switch mode */ ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3000) = 0x5e333;//(P0, Force mode, Link Up, 10Mbps, Full-Duplex, FC ON) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3100) = 0x5e333;//(P1, Force mode, Link Up, 10Mbps, Full-Duplex, FC ON) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3200) = 0x5e333;//(P2, Force mode, Link Up, 10Mbps, Full-Duplex, FC ON) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3300) = 0x5e333;//(P3, Force mode, Link Up, 10Mbps, Full-Duplex, FC ON) ++#if defined (CONFIG_RAETH_HAS_PORT4) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3400) = 0x5e337;//(P4, Force mode, Link Up, 100Mbps, Full-Duplex, FC ON) ++#else ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3400) = 0x5e333;//(P4, Force mode, Link Up, 10Mbps, Full-Duplex, FC ON) ++#endif ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3500) = 0x5e337;//(P5, Force mode, Link Up, 100Mbps, Full-Duplex, FC ON) ++ ++ /* In order to use 10M/Full on FPGA board. We configure phy capable to ++ * 10M Full/Half duplex, so we can use auto-negotiation on PC side */ ++#if defined (CONFIG_RAETH_HAS_PORT4) ++ for(i=0;i<4;i++){ ++#else ++ for(i=0;i<5;i++){ ++#endif ++ mii_mgr_write(i, 4, 0x0461); //Capable of 10M Full/Half Duplex, flow control on/off ++ mii_mgr_write(i, 0, 0xB100); //reset all digital logic, except phy_reg ++ } ++ ++#endif ++ ++#if defined (CONFIG_PDMA_NEW) ++ *(unsigned long *)(SYSCFG1) |= (0x1 << 8); //PCIE_RC_MODE=1 ++#endif ++ ++ ++#if defined (CONFIG_MT7620_ASIC) && !defined (CONFIG_P5_RGMII_TO_MT7530_MODE) ++ is_BGA = (sysRegRead(RALINK_SYSCTL_BASE + 0xc) >> 16) & 0x1; ++ /* ++ * Reg 31: Page Control ++ * Bit 15 => PortPageSel, 1=local, 0=global ++ * Bit 14:12 => PageSel, local:0~3, global:0~4 ++ * ++ * Reg16~30:Local/Global registers ++ * ++ */ ++ /*correct PHY setting L3.0 BGA*/ ++ mii_mgr_write(1, 31, 0x4000); //global, page 4 ++ ++ mii_mgr_write(1, 17, 0x7444); ++ if(is_BGA){ ++ mii_mgr_write(1, 19, 0x0114); ++ }else{ ++ mii_mgr_write(1, 19, 0x0117); ++ } ++ ++ mii_mgr_write(1, 22, 0x10cf); ++ mii_mgr_write(1, 25, 0x6212); ++ mii_mgr_write(1, 26, 0x0777); ++ mii_mgr_write(1, 29, 0x4000); ++ mii_mgr_write(1, 28, 0xc077); ++ mii_mgr_write(1, 24, 0x0000); ++ ++ mii_mgr_write(1, 31, 0x3000); //global, page 3 ++ mii_mgr_write(1, 17, 0x4838); ++ ++ mii_mgr_write(1, 31, 0x2000); //global, page 2 ++ if(is_BGA){ ++ mii_mgr_write(1, 21, 0x0515); ++ mii_mgr_write(1, 22, 0x0053); ++ mii_mgr_write(1, 23, 0x00bf); ++ mii_mgr_write(1, 24, 0x0aaf); ++ mii_mgr_write(1, 25, 0x0fad); ++ mii_mgr_write(1, 26, 0x0fc1); ++ }else{ ++ mii_mgr_write(1, 21, 0x0517); ++ mii_mgr_write(1, 22, 0x0fd2); ++ mii_mgr_write(1, 23, 0x00bf); ++ mii_mgr_write(1, 24, 0x0aab); ++ mii_mgr_write(1, 25, 0x00ae); ++ mii_mgr_write(1, 26, 0x0fff); ++ } ++ mii_mgr_write(1, 31, 0x1000); //global, page 1 ++ mii_mgr_write(1, 17, 0xe7f8); ++ ++ mii_mgr_write(1, 31, 0x8000); //local, page 0 ++ mii_mgr_write(0, 30, 0xa000); ++ mii_mgr_write(1, 30, 0xa000); ++ mii_mgr_write(2, 30, 0xa000); ++ mii_mgr_write(3, 30, 0xa000); ++#if !defined (CONFIG_RAETH_HAS_PORT4) ++ mii_mgr_write(4, 30, 0xa000); ++#endif ++ ++ mii_mgr_write(0, 4, 0x05e1); ++ mii_mgr_write(1, 4, 0x05e1); ++ mii_mgr_write(2, 4, 0x05e1); ++ mii_mgr_write(3, 4, 0x05e1); ++#if !defined (CONFIG_RAETH_HAS_PORT4) ++ mii_mgr_write(4, 4, 0x05e1); ++#endif ++ ++ mii_mgr_write(1, 31, 0xa000); //local, page 2 ++ mii_mgr_write(0, 16, 0x1111); ++ mii_mgr_write(1, 16, 0x1010); ++ mii_mgr_write(2, 16, 0x1515); ++ mii_mgr_write(3, 16, 0x0f0f); ++#if !defined (CONFIG_RAETH_HAS_PORT4) ++ mii_mgr_write(4, 16, 0x1313); ++#endif ++ ++#if !defined (CONFIG_RAETH_8023AZ_EEE) ++ mii_mgr_write(1, 31, 0xb000); //local, page 3 ++ mii_mgr_write(0, 17, 0x0); ++ mii_mgr_write(1, 17, 0x0); ++ mii_mgr_write(2, 17, 0x0); ++ mii_mgr_write(3, 17, 0x0); ++#if !defined (CONFIG_RAETH_HAS_PORT4) ++ mii_mgr_write(4, 17, 0x0); ++#endif ++#endif ++ ++ ++ ++#if 0 ++ // for ethernet extended mode ++ mii_mgr_write(1, 31, 0x3000); ++ mii_mgr_write(1, 19, 0x122); ++ mii_mgr_write(1, 20, 0x0044); ++ mii_mgr_write(1, 23, 0xa80c); ++ mii_mgr_write(1, 24, 0x129d); ++ mii_mgr_write(1, 31, 9000); ++ mii_mgr_write(0, 18, 0x140c); ++ mii_mgr_write(1, 18, 0x140c); ++ mii_mgr_write(2, 18, 0x140c); ++ mii_mgr_write(3, 18, 0x140c); ++ mii_mgr_write(0, 0, 0x3300); ++ mii_mgr_write(1, 0, 0x3300); ++ mii_mgr_write(2, 0, 0x3300); ++ mii_mgr_write(3, 0, 0x3300); ++#if !defined (CONFIG_RAETH_HAS_PORT4) ++ mii_mgr_write(4, 18, 0x140c); ++ mii_mgr_write(4, 0, 0x3300); ++#endif ++#endif ++ ++#endif ++ ++#if defined(CONFIG_RALINK_MT7620) ++ if ((sysRegRead(0xB000000C) & 0xf) >= 0x5) { ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x701c) = 0x800000c; //enlarge FE2SW_IPG ++ } ++#endif // CONFIG_RAETH_7620 // ++ ++ ++ ++#if defined (CONFIG_MT7620_FPGA)|| defined (CONFIG_MT7620_ASIC) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3600) = 0x5e33b;//CPU Port6 Force Link 1G, FC ON ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x0010) = 0x7f7f7fe0;//Set Port6 CPU Port ++ ++#if defined (CONFIG_P5_RGMII_TO_MAC_MODE) || defined (CONFIG_P5_RGMII_TO_MT7530_MODE) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3500) = 0x5e33b;//(P5, Force mode, Link Up, 1000Mbps, Full-Duplex, FC ON) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x7014) = 0x1f0c000c; //disable port 0 ~ 4 internal phy, set phy base address to 12 ++ /*MT7620 need mac learning for PPE*/ ++ //*(unsigned long *)(RALINK_ETH_SW_BASE+0x250c) = 0x000fff10;//disable port5 mac learning ++ //*(unsigned long *)(RALINK_ETH_SW_BASE+0x260c) = 0x000fff10;//disable port6 mac learning ++ *(unsigned long *)(0xb0000060) &= ~(1 << 9); //set RGMII to Normal mode ++ //rxclk_skew, txclk_skew = 0 ++ *(unsigned long *)(SYSCFG1) &= ~(0x3 << 12); //GE1_MODE=RGMii Mode ++#if defined (CONFIG_P5_RGMII_TO_MT7530_MODE) ++ ++ *(unsigned long *)(0xb0000060) &= ~(3 << 7); //set MDIO to Normal mode ++ ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3400) = 0x56330;//(P4, AN) ++ *(unsigned long *)(0xb0000060) &= ~(1 << 10); //set GE2 to Normal mode ++ //rxclk_skew, txclk_skew = 0 ++ *(unsigned long *)(SYSCFG1) &= ~(0x3 << 14); //GE2_MODE=RGMii Mode ++ ++ ++ /* set MT7530 Port 0 to PHY mode */ ++ mii_mgr_read(31, 0x7804 ,®Value); ++#if defined (CONFIG_GE_RGMII_MT7530_P0_AN) ++ regValue &= ~((1<<13)|(1<<6)|(1<<5)|(1<<15)); ++ regValue |= ((1<<7)|(1<<16)|(1<<20)|(1<<24)); ++ //mii_mgr_write(31, 0x7804 ,0x115c8f); ++#elif defined (CONFIG_GE_RGMII_MT7530_P4_AN) ++ regValue &= ~((1<<13)|(1<<6)|(1<<20)|(1<<5)|(1<<15)); ++ regValue |= ((1<<7)|(1<<16)|(1<<24)); ++#endif ++ regValue &= ~(1<<8); //Enable Port 6 ++ mii_mgr_write(31, 0x7804 ,regValue); //bit 24 standalone switch ++ ++/* set MT7530 central align */ ++ mii_mgr_read(31, 0x7830, ®Value); ++ regValue &= ~1; ++ regValue |= 1<<1; ++ mii_mgr_write(31, 0x7830, regValue); ++ ++ mii_mgr_read(31, 0x7a40, ®Value); ++ regValue &= ~(1<<30); ++ mii_mgr_write(31, 0x7a40, regValue); ++ ++ regValue = 0x855; ++ mii_mgr_write(31, 0x7a78, regValue); ++ ++ /*AN should be set after MT7530 HWSTRAP*/ ++#if defined (CONFIG_GE_RGMII_MT7530_P0_AN) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x7000) = 0xc5000100;//(P0, AN polling) ++#elif defined (CONFIG_GE_RGMII_MT7530_P4_AN) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x7000) = 0xc5000504;//(P4, AN polling) ++#endif ++#endif ++ ++#elif defined (CONFIG_P5_MII_TO_MAC_MODE) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3500) = 0x5e337;//(P5, Force mode, Link Up, 100Mbps, Full-Duplex, FC ON) ++ *(unsigned long *)(0xb0000060) &= ~(1 << 9); //set RGMII to Normal mode ++ *(unsigned long *)(SYSCFG1) &= ~(0x3 << 12); //GE1_MODE=Mii Mode ++ *(unsigned long *)(SYSCFG1) |= (0x1 << 12); ++ ++#elif defined (CONFIG_P5_MAC_TO_PHY_MODE) ++ *(unsigned long *)(0xb0000060) &= ~(1 << 9); //set RGMII to Normal mode ++ *(unsigned long *)(0xb0000060) &= ~(3 << 7); //set MDIO to Normal mode ++ *(unsigned long *)(SYSCFG1) &= ~(0x3 << 12); //GE1_MODE=RGMii Mode ++ ++ enable_auto_negotiate(1); ++ ++ if (isICPlusGigaPHY(1)) { ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 4, &phy_val); ++ phy_val |= 1<<10; //enable pause ability ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 4, phy_val); ++ ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 0, &phy_val); ++ phy_val |= 1<<9; //restart AN ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 0, phy_val); ++ }else if (isMarvellGigaPHY(1)) { ++#if defined (CONFIG_MT7620_FPGA) ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 9, &phy_val); ++ phy_val &= ~(3<<8); //turn off 1000Base-T Advertisement (9.9=1000Full, 9.8=1000Half) ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 9, phy_val); ++#endif ++ printk("Reset MARVELL phy1\n"); ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 20, &phy_val); ++ phy_val |= 1<<7; //Add delay to RX_CLK for RXD Outputs ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 20, phy_val); ++ ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 0, &phy_val); ++ phy_val |= 1<<15; //PHY Software Reset ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 0, phy_val); ++ }else if (isVtssGigaPHY(1)) { ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 31, 0x0001); //extended page ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 28, &phy_val); ++ printk("Vitesse phy skew: %x --> ", phy_val); ++ phy_val |= (0x3<<12); // RGMII RX skew compensation= 2.0 ns ++ phy_val &= ~(0x3<<14);// RGMII TX skew compensation= 0 ns ++ printk("%x\n", phy_val); ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 28, phy_val); ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 31, 0x0000); //main registers ++ } ++ ++ ++#elif defined (CONFIG_P5_RMII_TO_MAC_MODE) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3500) = 0x5e337;//(P5, Force mode, Link Up, 100Mbps, Full-Duplex, FC ON) ++ *(unsigned long *)(0xb0000060) &= ~(1 << 9); //set RGMII to Normal mode ++ *(unsigned long *)(SYSCFG1) &= ~(0x3 << 12); //GE1_MODE=RvMii Mode ++ *(unsigned long *)(SYSCFG1) |= (0x2 << 12); ++ ++#else // Port 5 Disabled // ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3500) = 0x8000;//link down ++ *(unsigned long *)(0xb0000060) |= (1 << 9); //set RGMII to GPIO mode ++#endif ++#endif ++ ++#if defined (CONFIG_P4_RGMII_TO_MAC_MODE) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3400) = 0x5e33b;//(P4, Force mode, Link Up, 1000Mbps, Full-Duplex, FC ON) ++ *(unsigned long *)(0xb0000060) &= ~(1 << 10); //set GE2 to Normal mode ++ //rxclk_skew, txclk_skew = 0 ++ *(unsigned long *)(SYSCFG1) &= ~(0x3 << 14); //GE2_MODE=RGMii Mode ++ ++#elif defined (CONFIG_P4_MII_TO_MAC_MODE) ++ *(unsigned long *)(0xb0000060) &= ~(1 << 10); //set GE2 to Normal mode ++ *(unsigned long *)(SYSCFG1) &= ~(0x3 << 14); //GE2_MODE=Mii Mode ++ *(unsigned long *)(SYSCFG1) |= (0x1 << 14); ++ ++#elif defined (CONFIG_P4_MAC_TO_PHY_MODE) ++ *(unsigned long *)(0xb0000060) &= ~(1 << 10); //set GE2 to Normal mode ++ *(unsigned long *)(0xb0000060) &= ~(3 << 7); //set MDIO to Normal mode ++ *(unsigned long *)(SYSCFG1) &= ~(0x3 << 14); //GE2_MODE=RGMii Mode ++ ++ enable_auto_negotiate(1); ++ ++ if (isICPlusGigaPHY(2)) { ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 4, &phy_val); ++ phy_val |= 1<<10; //enable pause ability ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 4, phy_val); ++ ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 0, &phy_val); ++ phy_val |= 1<<9; //restart AN ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 0, phy_val); ++ }else if (isMarvellGigaPHY(2)) { ++#if defined (CONFIG_MT7620_FPGA) ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 9, &phy_val); ++ phy_val &= ~(3<<8); //turn off 1000Base-T Advertisement (9.9=1000Full, 9.8=1000Half) ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 9, phy_val); ++#endif ++ printk("Reset MARVELL phy2\n"); ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 20, &phy_val); ++ phy_val |= 1<<7; //Add delay to RX_CLK for RXD Outputs ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 20, phy_val); ++ ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 0, &phy_val); ++ phy_val |= 1<<15; //PHY Software Reset ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 0, phy_val); ++ }else if (isVtssGigaPHY(2)) { ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 31, 0x0001); //extended page ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 28, &phy_val); ++ printk("Vitesse phy skew: %x --> ", phy_val); ++ phy_val |= (0x3<<12); // RGMII RX skew compensation= 2.0 ns ++ phy_val &= ~(0x3<<14);// RGMII TX skew compensation= 0 ns ++ printk("%x\n", phy_val); ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 28, phy_val); ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 31, 0x0000); //main registers ++ } ++ ++#elif defined (CONFIG_P4_RMII_TO_MAC_MODE) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x3400) = 0x5e337;//(P5, Force mode, Link Up, 100Mbps, Full-Duplex, FC ON) ++ *(unsigned long *)(0xb0000060) &= ~(1 << 10); //set GE2 to Normal mode ++ *(unsigned long *)(SYSCFG1) &= ~(0x3 << 14); //GE1_MODE=RvMii Mode ++ *(unsigned long *)(SYSCFG1) |= (0x2 << 14); ++#elif defined (CONFIG_GE_RGMII_MT7530_P0_AN) || defined (CONFIG_GE_RGMII_MT7530_P4_AN) ++#else // Port 4 Disabled // ++ *(unsigned long *)(SYSCFG1) |= (0x3 << 14); //GE2_MODE=RJ45 Mode ++ *(unsigned long *)(0xb0000060) |= (1 << 10); //set RGMII2 to GPIO mode ++#endif ++ ++} ++#endif ++ ++#if defined (CONFIG_RALINK_MT7628) ++ ++void mt7628_ephy_init(void) ++{ ++ int i; ++ u32 phy_val; ++ mii_mgr_write(0, 31, 0x2000); //change G2 page ++ mii_mgr_write(0, 26, 0x0000); ++ ++ for(i=0; i<5; i++){ ++ mii_mgr_write(i, 31, 0x8000); //change L0 page ++ mii_mgr_write(i, 0, 0x3100); ++ ++#if defined (CONFIG_RAETH_8023AZ_EEE) ++ mii_mgr_read(i, 26, &phy_val);// EEE setting ++ phy_val |= (1 << 5); ++ mii_mgr_write(i, 26, phy_val); ++#else ++ //disable EEE ++ mii_mgr_write(i, 13, 0x7); ++ mii_mgr_write(i, 14, 0x3C); ++ mii_mgr_write(i, 13, 0x4007); ++ mii_mgr_write(i, 14, 0x0); ++#endif ++ mii_mgr_write(i, 30, 0xa000); ++ mii_mgr_write(i, 31, 0xa000); // change L2 page ++ mii_mgr_write(i, 16, 0x0606); ++ mii_mgr_write(i, 23, 0x0f0e); ++ mii_mgr_write(i, 24, 0x1610); ++ mii_mgr_write(i, 30, 0x1f15); ++ mii_mgr_write(i, 28, 0x6111); ++ ++ mii_mgr_read(i, 4, &phy_val); ++ phy_val |= (1 << 10); ++ mii_mgr_write(i, 4, phy_val); ++ } ++ ++ //100Base AOI setting ++ mii_mgr_write(0, 31, 0x5000); //change G5 page ++ mii_mgr_write(0, 19, 0x004a); ++ mii_mgr_write(0, 20, 0x015a); ++ mii_mgr_write(0, 21, 0x00ee); ++ mii_mgr_write(0, 22, 0x0033); ++ mii_mgr_write(0, 23, 0x020a); ++ mii_mgr_write(0, 24, 0x0000); ++ mii_mgr_write(0, 25, 0x024a); ++ mii_mgr_write(0, 26, 0x035a); ++ mii_mgr_write(0, 27, 0x02ee); ++ mii_mgr_write(0, 28, 0x0233); ++ mii_mgr_write(0, 29, 0x000a); ++ mii_mgr_write(0, 30, 0x0000); ++ /* Fix EPHY idle state abnormal behavior */ ++ mii_mgr_write(0, 31, 0x4000); //change G4 page ++ mii_mgr_write(0, 29, 0x000d); ++ mii_mgr_write(0, 30, 0x0500); ++ ++} ++ ++#endif ++ ++ ++#if defined (CONFIG_RALINK_RT3052) || defined (CONFIG_RALINK_RT3352) || defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_MT7628) ++void rt305x_esw_init(void) ++{ ++ int i=0; ++ u32 phy_val=0, val=0; ++#if defined (CONFIG_RT3052_ASIC) ++ u32 phy_val2; ++#endif ++ ++#if defined (CONFIG_RT5350_ASIC) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x0168) = 0x17; ++#endif ++ ++ /* ++ * FC_RLS_TH=200, FC_SET_TH=160 ++ * DROP_RLS=120, DROP_SET_TH=80 ++ */ ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x0008) = 0xC8A07850; ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x00E4) = 0x00000000; ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x0014) = 0x00405555; ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x0050) = 0x00002001; ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x0090) = 0x00007f7f; ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x0098) = 0x00007f3f; //disable VLAN ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x00CC) = 0x0002500c; ++#ifndef CONFIG_UNH_TEST ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x009C) = 0x0008a301; //hashing algorithm=XOR48, aging interval=300sec ++#else ++ /* ++ * bit[30]:1 Backoff Algorithm Option: The latest one to pass UNH test ++ * bit[29]:1 Length of Received Frame Check Enable ++ * bit[8]:0 Enable collision 16 packet abort and late collision abort ++ * bit[7:6]:01 Maximum Packet Length: 1518 ++ */ ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x009C) = 0x6008a241; ++#endif ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x008C) = 0x02404040; ++#if defined (CONFIG_RT3052_ASIC) || defined (CONFIG_RT3352_ASIC) || defined (CONFIG_RT5350_ASIC) || defined (CONFIG_MT7628_ASIC) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x00C8) = 0x3f502b28; //Change polling Ext PHY Addr=0x1F ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x0084) = 0x00000000; ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x0110) = 0x7d000000; //1us cycle number=125 (FE's clock=125Mhz) ++#elif defined (CONFIG_RT3052_FPGA) || defined (CONFIG_RT3352_FPGA) || defined (CONFIG_RT5350_FPGA) || defined (CONFIG_MT7628_FPGA) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x00C8) = 0x00f03ff9; //polling Ext PHY Addr=0x0, force port5 as 100F/D (disable auto-polling) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x0084) = 0xffdf1f00; ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x0110) = 0x0d000000; //1us cycle number=13 (FE's clock=12.5Mhz) ++ ++ /* In order to use 10M/Full on FPGA board. We configure phy capable to ++ * 10M Full/Half duplex, so we can use auto-negotiation on PC side */ ++ for(i=0;i<5;i++){ ++ mii_mgr_write(i, 4, 0x0461); //Capable of 10M Full/Half Duplex, flow control on/off ++ mii_mgr_write(i, 0, 0xB100); //reset all digital logic, except phy_reg ++ } ++#endif ++ ++ /* ++ * set port 5 force to 1000M/Full when connecting to switch or iNIC ++ */ ++#if defined (CONFIG_P5_RGMII_TO_MAC_MODE) ++ *(unsigned long *)(0xb0000060) &= ~(1 << 9); //set RGMII to Normal mode ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x00C8) &= ~(1<<29); //disable port 5 auto-polling ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x00C8) |= 0x3fff; //force 1000M full duplex ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x00C8) &= ~(0xf<<20); //rxclk_skew, txclk_skew = 0 ++#elif defined (CONFIG_P5_MII_TO_MAC_MODE) ++ *(unsigned long *)(0xb0000060) &= ~(1 << 9); //set RGMII to Normal mode ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x00C8) &= ~(1<<29); //disable port 5 auto-polling ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x00C8) &= ~(0x3fff); ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x00C8) |= 0x3ffd; //force 100M full duplex ++ ++#if defined (CONFIG_RALINK_RT3352) ++ *(unsigned long *)(SYSCFG1) &= ~(0x3 << 12); //GE1_MODE=Mii Mode ++ *(unsigned long *)(SYSCFG1) |= (0x1 << 12); ++#endif ++ ++#elif defined (CONFIG_P5_MAC_TO_PHY_MODE) ++ *(unsigned long *)(0xb0000060) &= ~(1 << 9); //set RGMII to Normal mode ++ *(unsigned long *)(0xb0000060) &= ~(1 << 7); //set MDIO to Normal mode ++#if defined (CONFIG_RT3052_ASIC) || defined (CONFIG_RT3352_ASIC) ++ enable_auto_negotiate(1); ++#endif ++ if (isMarvellGigaPHY(1)) { ++#if defined (CONFIG_RT3052_FPGA) || defined (CONFIG_RT3352_FPGA) ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 9, &phy_val); ++ phy_val &= ~(3<<8); //turn off 1000Base-T Advertisement (9.9=1000Full, 9.8=1000Half) ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 9, phy_val); ++#endif ++ printk("\n Reset MARVELL phy\n"); ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 20, &phy_val); ++ phy_val |= 1<<7; //Add delay to RX_CLK for RXD Outputs ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 20, phy_val); ++ ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 0, &phy_val); ++ phy_val |= 1<<15; //PHY Software Reset ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 0, phy_val); ++ } ++ if (isVtssGigaPHY(1)) { ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 31, 0x0001); //extended page ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 28, &phy_val); ++ printk("Vitesse phy skew: %x --> ", phy_val); ++ phy_val |= (0x3<<12); // RGMII RX skew compensation= 2.0 ns ++ phy_val &= ~(0x3<<14);// RGMII TX skew compensation= 0 ns ++ printk("%x\n", phy_val); ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 28, phy_val); ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 31, 0x0000); //main registers ++ } ++ ++#elif defined (CONFIG_P5_RMII_TO_MAC_MODE) ++ *(unsigned long *)(0xb0000060) &= ~(1 << 9); //set RGMII to Normal mode ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x00C8) &= ~(1<<29); //disable port 5 auto-polling ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x00C8) &= ~(0x3fff); ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x00C8) |= 0x3ffd; //force 100M full duplex ++ ++#if defined (CONFIG_RALINK_RT3352) ++ *(unsigned long *)(SYSCFG1) &= ~(0x3 << 12); //GE1_MODE=RvMii Mode ++ *(unsigned long *)(SYSCFG1) |= (0x2 << 12); ++#endif ++#else // Port 5 Disabled // ++ ++#if defined (CONFIG_RALINK_RT3052) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x00C8) &= ~(1 << 29); //port5 auto polling disable ++ *(unsigned long *)(0xb0000060) |= (1 << 7); //set MDIO to GPIO mode (GPIO22-GPIO23) ++ *(unsigned long *)(0xb0000060) |= (1 << 9); //set RGMII to GPIO mode (GPIO41-GPIO50) ++ *(unsigned long *)(0xb0000674) = 0xFFF; //GPIO41-GPIO50 output mode ++ *(unsigned long *)(0xb000067C) = 0x0; //GPIO41-GPIO50 output low ++#elif defined (CONFIG_RALINK_RT3352) ++ *(unsigned long *)(RALINK_ETH_SW_BASE+0x00C8) &= ~(1 << 29); //port5 auto polling disable ++ *(unsigned long *)(0xb0000060) |= (1 << 7); //set MDIO to GPIO mode (GPIO22-GPIO23) ++ *(unsigned long *)(0xb0000624) = 0xC0000000; //GPIO22-GPIO23 output mode ++ *(unsigned long *)(0xb000062C) = 0xC0000000; //GPIO22-GPIO23 output high ++ ++ *(unsigned long *)(0xb0000060) |= (1 << 9); //set RGMII to GPIO mode (GPIO24-GPIO35) ++ *(unsigned long *)(0xb000064C) = 0xFFF; //GPIO24-GPIO35 output mode ++ *(unsigned long *)(0xb0000654) = 0xFFF; //GPIO24-GPIO35 output high ++#elif defined (CONFIG_RALINK_RT5350) || defined (CONFIG_RALINK_MT7628) ++ /* do nothing */ ++#endif ++#endif // CONFIG_P5_RGMII_TO_MAC_MODE // ++ ++ ++#if defined (CONFIG_RT3052_ASIC) ++ rw_rf_reg(0, 0, &phy_val); ++ phy_val = phy_val >> 4; ++ ++ if(phy_val > 0x5) { ++ ++ rw_rf_reg(0, 26, &phy_val); ++ phy_val2 = (phy_val | (0x3 << 5)); ++ rw_rf_reg(1, 26, &phy_val2); ++ ++ // reset EPHY ++ val = sysRegRead(RSTCTRL); ++ val = val | RALINK_EPHY_RST; ++ sysRegWrite(RSTCTRL, val); ++ val = val & ~(RALINK_EPHY_RST); ++ sysRegWrite(RSTCTRL, val); ++ ++ rw_rf_reg(1, 26, &phy_val); ++ ++ //select local register ++ mii_mgr_write(0, 31, 0x8000); ++ for(i=0;i<5;i++){ ++ mii_mgr_write(i, 26, 0x1600); //TX10 waveform coefficient //LSB=0 disable PHY ++ mii_mgr_write(i, 29, 0x7058); //TX100/TX10 AD/DA current bias ++ mii_mgr_write(i, 30, 0x0018); //TX100 slew rate control ++ } ++ ++ //select global register ++ mii_mgr_write(0, 31, 0x0); ++ mii_mgr_write(0, 1, 0x4a40); //enlarge agcsel threshold 3 and threshold 2 ++ mii_mgr_write(0, 2, 0x6254); //enlarge agcsel threshold 5 and threshold 4 ++ mii_mgr_write(0, 3, 0xa17f); //enlarge agcsel threshold 6 ++//#define ENABLE_LDPS ++#if defined (ENABLE_LDPS) ++ mii_mgr_write(0, 12, 0x7eaa); ++ mii_mgr_write(0, 22, 0x252f); //tune TP_IDL tail and head waveform, enable power down slew rate control ++#else ++ mii_mgr_write(0, 12, 0x0); ++ mii_mgr_write(0, 22, 0x052f); ++#endif ++ mii_mgr_write(0, 14, 0x65); //longer TP_IDL tail length ++ mii_mgr_write(0, 16, 0x0684); //increased squelch pulse count threshold. ++ mii_mgr_write(0, 17, 0x0fe0); //set TX10 signal amplitude threshold to minimum ++ mii_mgr_write(0, 18, 0x40ba); //set squelch amplitude to higher threshold ++ mii_mgr_write(0, 27, 0x2fce); //set PLL/Receive bias current are calibrated ++ mii_mgr_write(0, 28, 0xc410); //change PLL/Receive bias current to internal(RT3350) ++ mii_mgr_write(0, 29, 0x598b); //change PLL bias current to internal(RT3052_MP3) ++ mii_mgr_write(0, 31, 0x8000); //select local register ++ ++ for(i=0;i<5;i++){ ++ //LSB=1 enable PHY ++ mii_mgr_read(i, 26, &phy_val); ++ phy_val |= 0x0001; ++ mii_mgr_write(i, 26, phy_val); ++ } ++ } else { ++ //select local register ++ mii_mgr_write(0, 31, 0x8000); ++ for(i=0;i<5;i++){ ++ mii_mgr_write(i, 26, 0x1600); //TX10 waveform coefficient //LSB=0 disable PHY ++ mii_mgr_write(i, 29, 0x7058); //TX100/TX10 AD/DA current bias ++ mii_mgr_write(i, 30, 0x0018); //TX100 slew rate control ++ } ++ ++ //select global register ++ mii_mgr_write(0, 31, 0x0); ++ mii_mgr_write(0, 1, 0x4a40); //enlarge agcsel threshold 3 and threshold 2 ++ mii_mgr_write(0, 2, 0x6254); //enlarge agcsel threshold 5 and threshold 4 ++ mii_mgr_write(0, 3, 0xa17f); //enlarge agcsel threshold 6 ++ mii_mgr_write(0, 14, 0x65); //longer TP_IDL tail length ++ mii_mgr_write(0, 16, 0x0684); //increased squelch pulse count threshold. ++ mii_mgr_write(0, 17, 0x0fe0); //set TX10 signal amplitude threshold to minimum ++ mii_mgr_write(0, 18, 0x40ba); //set squelch amplitude to higher threshold ++ mii_mgr_write(0, 22, 0x052f); //tune TP_IDL tail and head waveform ++ mii_mgr_write(0, 27, 0x2fce); //set PLL/Receive bias current are calibrated ++ mii_mgr_write(0, 28, 0xc410); //change PLL/Receive bias current to internal(RT3350) ++ mii_mgr_write(0, 29, 0x598b); //change PLL bias current to internal(RT3052_MP3) ++ mii_mgr_write(0, 31, 0x8000); //select local register ++ ++ for(i=0;i<5;i++){ ++ //LSB=1 enable PHY ++ mii_mgr_read(i, 26, &phy_val); ++ phy_val |= 0x0001; ++ mii_mgr_write(i, 26, phy_val); ++ } ++ } ++#elif defined (CONFIG_RT3352_ASIC) ++ //PHY IOT ++ // reset EPHY ++ val = sysRegRead(RSTCTRL); ++ val = val | RALINK_EPHY_RST; ++ sysRegWrite(RSTCTRL, val); ++ val = val & ~(RALINK_EPHY_RST); ++ sysRegWrite(RSTCTRL, val); ++ ++ //select local register ++ mii_mgr_write(0, 31, 0x8000); ++ for(i=0;i<5;i++){ ++ mii_mgr_write(i, 26, 0x1600); //TX10 waveform coefficient //LSB=0 disable PHY ++ mii_mgr_write(i, 29, 0x7016); //TX100/TX10 AD/DA current bias ++ mii_mgr_write(i, 30, 0x0038); //TX100 slew rate control ++ } ++ ++ //select global register ++ mii_mgr_write(0, 31, 0x0); ++ mii_mgr_write(0, 1, 0x4a40); //enlarge agcsel threshold 3 and threshold 2 ++ mii_mgr_write(0, 2, 0x6254); //enlarge agcsel threshold 5 and threshold 4 ++ mii_mgr_write(0, 3, 0xa17f); //enlarge agcsel threshold 6 ++ mii_mgr_write(0, 12, 0x7eaa); ++ mii_mgr_write(0, 14, 0x65); //longer TP_IDL tail length ++ mii_mgr_write(0, 16, 0x0684); //increased squelch pulse count threshold. ++ mii_mgr_write(0, 17, 0x0fe0); //set TX10 signal amplitude threshold to minimum ++ mii_mgr_write(0, 18, 0x40ba); //set squelch amplitude to higher threshold ++ mii_mgr_write(0, 22, 0x253f); //tune TP_IDL tail and head waveform, enable power down slew rate control ++ mii_mgr_write(0, 27, 0x2fda); //set PLL/Receive bias current are calibrated ++ mii_mgr_write(0, 28, 0xc410); //change PLL/Receive bias current to internal(RT3350) ++ mii_mgr_write(0, 29, 0x598b); //change PLL bias current to internal(RT3052_MP3) ++ mii_mgr_write(0, 31, 0x8000); //select local register ++ ++ for(i=0;i<5;i++){ ++ //LSB=1 enable PHY ++ mii_mgr_read(i, 26, &phy_val); ++ phy_val |= 0x0001; ++ mii_mgr_write(i, 26, phy_val); ++ } ++ ++#elif defined (CONFIG_RT5350_ASIC) ++ //PHY IOT ++ // reset EPHY ++ val = sysRegRead(RSTCTRL); ++ val = val | RALINK_EPHY_RST; ++ sysRegWrite(RSTCTRL, val); ++ val = val & ~(RALINK_EPHY_RST); ++ sysRegWrite(RSTCTRL, val); ++ ++ //select local register ++ mii_mgr_write(0, 31, 0x8000); ++ for(i=0;i<5;i++){ ++ mii_mgr_write(i, 26, 0x1600); //TX10 waveform coefficient //LSB=0 disable PHY ++ mii_mgr_write(i, 29, 0x7015); //TX100/TX10 AD/DA current bias ++ mii_mgr_write(i, 30, 0x0038); //TX100 slew rate control ++ } ++ ++ //select global register ++ mii_mgr_write(0, 31, 0x0); ++ mii_mgr_write(0, 1, 0x4a40); //enlarge agcsel threshold 3 and threshold 2 ++ mii_mgr_write(0, 2, 0x6254); //enlarge agcsel threshold 5 and threshold 4 ++ mii_mgr_write(0, 3, 0xa17f); //enlarge agcsel threshold 6 ++ mii_mgr_write(0, 12, 0x7eaa); ++ mii_mgr_write(0, 14, 0x65); //longer TP_IDL tail length ++ mii_mgr_write(0, 16, 0x0684); //increased squelch pulse count threshold. ++ mii_mgr_write(0, 17, 0x0fe0); //set TX10 signal amplitude threshold to minimum ++ mii_mgr_write(0, 18, 0x40ba); //set squelch amplitude to higher threshold ++ mii_mgr_write(0, 22, 0x253f); //tune TP_IDL tail and head waveform, enable power down slew rate control ++ mii_mgr_write(0, 27, 0x2fda); //set PLL/Receive bias current are calibrated ++ mii_mgr_write(0, 28, 0xc410); //change PLL/Receive bias current to internal(RT3350) ++ mii_mgr_write(0, 29, 0x598b); //change PLL bias current to internal(RT3052_MP3) ++ mii_mgr_write(0, 31, 0x8000); //select local register ++ ++ for(i=0;i<5;i++){ ++ //LSB=1 enable PHY ++ mii_mgr_read(i, 26, &phy_val); ++ phy_val |= 0x0001; ++ mii_mgr_write(i, 26, phy_val); ++ } ++#elif defined (CONFIG_MT7628_ASIC) ++/*INIT MT7628 PHY HERE*/ ++ val = sysRegRead(RT2880_AGPIOCFG_REG); ++#if defined (CONFIG_ETH_ONE_PORT_ONLY) ++ val |= (MT7628_P0_EPHY_AIO_EN | MT7628_P1_EPHY_AIO_EN | MT7628_P2_EPHY_AIO_EN | MT7628_P3_EPHY_AIO_EN | MT7628_P4_EPHY_AIO_EN); ++ val = val & ~(MT7628_P0_EPHY_AIO_EN); ++#else ++ val = val & ~(MT7628_P0_EPHY_AIO_EN | MT7628_P1_EPHY_AIO_EN | MT7628_P2_EPHY_AIO_EN | MT7628_P3_EPHY_AIO_EN | MT7628_P4_EPHY_AIO_EN); ++#endif ++ if ((*((volatile u32 *)(RALINK_SYSCTL_BASE + 0x8))) & 0x10000) ++ val &= ~0x1f0000; ++ sysRegWrite(RT2880_AGPIOCFG_REG, val); ++ ++ val = sysRegRead(RSTCTRL); ++ val = val | RALINK_EPHY_RST; ++ sysRegWrite(RSTCTRL, val); ++ val = val & ~(RALINK_EPHY_RST); ++ sysRegWrite(RSTCTRL, val); ++ ++ ++ val = sysRegRead(RALINK_SYSCTL_BASE + 0x64); ++#if defined (CONFIG_ETH_ONE_PORT_ONLY) ++ val &= 0xf003f003; ++ val |= 0x05540554; ++ sysRegWrite(RALINK_SYSCTL_BASE + 0x64, val); // set P0 EPHY LED mode ++#else ++ val &= 0xf003f003; ++ sysRegWrite(RALINK_SYSCTL_BASE + 0x64, val); // set P0~P4 EPHY LED mode ++#endif ++ ++ udelay(5000); ++ mt7628_ephy_init(); ++ ++#endif ++} ++#endif ++ ++#if defined (CONFIG_ARCH_MT7623) /* TODO: just for bring up, should be removed!!! */ ++void mt7623_pinmux_set(void) ++{ ++ unsigned long regValue; ++ ++ //printk("[mt7623_pinmux_set]start\n"); ++ /* Pin277: ESW_RST (1) */ ++ regValue = le32_to_cpu(*(volatile u_long *)(0xf0005ad0)); ++ regValue &= ~(BITS(6,8)); ++ regValue |= BIT(6); ++ *(volatile u_long *)(0xf0005ad0) = regValue; ++ ++ /* Pin262: G2_TXEN (1) */ ++ regValue = le32_to_cpu(*(volatile u_long *)(0xf0005aa0)); ++ regValue &= ~(BITS(6,8)); ++ regValue |= BIT(6); ++ *(volatile u_long *)(0xf0005aa0) = regValue; ++ /* Pin263: G2_TXD3 (1) */ ++ regValue = le32_to_cpu(*(volatile u_long *)(0xf0005aa0)); ++ regValue &= ~(BITS(9,11)); ++ regValue |= BIT(9); ++ *(volatile u_long *)(0xf0005aa0) = regValue; ++ /* Pin264: G2_TXD2 (1) */ ++ regValue = le32_to_cpu(*(volatile u_long *)(0xf0005aa0)); ++ regValue &= ~(BITS(12,14)); ++ regValue |= BIT(12); ++ *(volatile u_long *)(0xf0005aa0) = regValue; ++ /* Pin265: G2_TXD1 (1) */ ++ regValue = le32_to_cpu(*(volatile u_long *)(0xf0005ab0)); ++ regValue &= ~(BITS(0,2)); ++ regValue |= BIT(0); ++ *(volatile u_long *)(0xf0005ab0) = regValue; ++ /* Pin266: G2_TXD0 (1) */ ++ regValue = le32_to_cpu(*(volatile u_long *)(0xf0005ab0)); ++ regValue &= ~(BITS(3,5)); ++ regValue |= BIT(3); ++ *(volatile u_long *)(0xf0005ab0) = regValue; ++ /* Pin267: G2_TXC (1) */ ++ regValue = le32_to_cpu(*(volatile u_long *)(0xf0005ab0)); ++ regValue &= ~(BITS(6,8)); ++ regValue |= BIT(6); ++ *(volatile u_long *)(0xf0005ab0) = regValue; ++ /* Pin268: G2_RXC (1) */ ++ regValue = le32_to_cpu(*(volatile u_long *)(0xf0005ab0)); ++ regValue &= ~(BITS(9,11)); ++ regValue |= BIT(9); ++ *(volatile u_long *)(0xf0005ab0) = regValue; ++ /* Pin269: G2_RXD0 (1) */ ++ regValue = le32_to_cpu(*(volatile u_long *)(0xf0005ab0)); ++ regValue &= ~(BITS(12,14)); ++ regValue |= BIT(12); ++ *(volatile u_long *)(0xf0005ab0) = regValue; ++ /* Pin270: G2_RXD1 (1) */ ++ regValue = le32_to_cpu(*(volatile u_long *)(0xf0005ac0)); ++ regValue &= ~(BITS(0,2)); ++ regValue |= BIT(0); ++ *(volatile u_long *)(0xf0005ac0) = regValue; ++ /* Pin271: G2_RXD2 (1) */ ++ regValue = le32_to_cpu(*(volatile u_long *)(0xf0005ac0)); ++ regValue &= ~(BITS(3,5)); ++ regValue |= BIT(3); ++ *(volatile u_long *)(0xf0005ac0) = regValue; ++ /* Pin272: G2_RXD3 (1) */ ++ regValue = le32_to_cpu(*(volatile u_long *)(0xf0005ac0)); ++ regValue &= ~(BITS(6,8)); ++ regValue |= BIT(6); ++ *(volatile u_long *)(0xf0005ac0) = regValue; ++ /* Pin274: G2_RXDV (1) */ ++ regValue = le32_to_cpu(*(volatile u_long *)(0xf0005ac0)); ++ regValue &= ~(BITS(12,14)); ++ regValue |= BIT(12); ++ *(volatile u_long *)(0xf0005ac0) = regValue; ++ ++ /* Pin275: MDC (1) */ ++ regValue = le32_to_cpu(*(volatile u_long *)(0xf0005ad0)); ++ regValue &= ~(BITS(0,2)); ++ regValue |= BIT(0); ++ *(volatile u_long *)(0xf0005ad0) = regValue; ++ /* Pin276: MDIO (1) */ ++ regValue = le32_to_cpu(*(volatile u_long *)(0xf0005ad0)); ++ regValue &= ~(BITS(3,5)); ++ regValue |= BIT(3); ++ *(volatile u_long *)(0xf0005ad0) = regValue; ++ //printk("[mt7623_pinmux_set]end\n"); ++} ++ ++void wait_loop(void) { ++ int i,j; ++ int read_data; ++ j =0; ++ while (j< 10) { ++ for(i = 0; i<32; i = i+1){ ++ read_data = *(volatile u_long *)(0xFB110610); ++ } ++ j++; ++ } ++} ++ ++void trgmii_calibration_7623(void) { ++ ++ unsigned int tap_a[5]; // minumum delay for all correct ++ unsigned int tap_b[5]; // maximum delay for all correct ++ unsigned int final_tap[5]; ++ unsigned int bslip_en; ++ unsigned int rxc_step_size; ++ unsigned int rxd_step_size; ++ unsigned int read_data; ++ unsigned int tmp; ++ unsigned int rd_wd; ++ int i; ++ unsigned int err_cnt[5]; ++ unsigned int init_toggle_data; ++ unsigned int err_flag[5]; ++ unsigned int err_total_flag; ++ unsigned int training_word; ++ unsigned int rd_tap; ++ ++ u32 TRGMII_7623_base; ++ u32 TRGMII_7623_RD_0; ++ u32 TRGMII_RD_1; ++ u32 TRGMII_RD_2; ++ u32 TRGMII_RD_3; ++ u32 TRGMII_RXCTL; ++ u32 TRGMII_RCK_CTRL; ++ u32 TRGMII_7530_base; ++ TRGMII_7623_base = 0xFB110300; ++ TRGMII_7623_RD_0 = TRGMII_7623_base + 0x10; ++ TRGMII_RCK_CTRL = TRGMII_7623_base; ++ rxd_step_size =0x1; ++ rxc_step_size =0x4; ++ init_toggle_data = 0x00000055; ++ training_word = 0x000000AC; ++ ++ //printk("Calibration begin ........"); ++ *(volatile u_long *)(TRGMII_7623_base +0x04) &= 0x3fffffff; // RX clock gating in MT7623 ++ *(volatile u_long *)(TRGMII_7623_base +0x00) |= 0x80000000; // Assert RX reset in MT7623 ++ *(volatile u_long *)(TRGMII_7623_base +0x78) |= 0x00002000; // Set TX OE edge in MT7623 ++ *(volatile u_long *)(TRGMII_7623_base +0x04) |= 0xC0000000; // Disable RX clock gating in MT7623 ++ *(volatile u_long *)(TRGMII_7623_base ) &= 0x7fffffff; // Release RX reset in MT7623 ++ //printk("Check Point 1 .....\n"); ++ for (i = 0 ; i<5 ; i++) { ++ *(volatile u_long *)(TRGMII_7623_RD_0 + i*8) |= 0x80000000; // Set bslip_en = 1 ++ } ++ ++ //printk("Enable Training Mode in MT7530\n"); ++ mii_mgr_read(0x1F,0x7A40,&read_data); ++ read_data |= 0xc0000000; ++ mii_mgr_write(0x1F,0x7A40,read_data); //Enable Training Mode in MT7530 ++ err_total_flag = 0; ++ //printk("Adjust RXC delay in MT7623\n"); ++ read_data =0x0; ++ while (err_total_flag == 0 && read_data != 0x68) { ++ //printk("2nd Enable EDGE CHK in MT7623\n"); ++ /* Enable EDGE CHK in MT7623*/ ++ for (i = 0 ; i<5 ; i++) { ++ tmp = *(volatile u_long *)(TRGMII_7623_RD_0 + i*8); ++ tmp |= 0x40000000; ++ *(volatile u_long *)(TRGMII_7623_RD_0 + i*8) = tmp & 0x4fffffff; ++ } ++ wait_loop(); ++ err_total_flag = 1; ++ for (i = 0 ; i<5 ; i++) { ++ err_cnt[i] = ((*(volatile u_long *)(TRGMII_7623_RD_0 + i*8)) >> 8) & 0x0000000f; ++ rd_wd = ((*(volatile u_long *)(TRGMII_7623_RD_0 + i*8)) >> 16) & 0x000000ff; ++ //printk("ERR_CNT = %d, RD_WD =%x\n",err_cnt[i],rd_wd); ++ if ( err_cnt[i] !=0 ) { ++ err_flag[i] = 1; ++ } ++ else if (rd_wd != 0x55) { ++ err_flag[i] = 1; ++ } ++ else { ++ err_flag[i] = 0; ++ } ++ err_total_flag = err_flag[i] & err_total_flag; ++ } ++ ++ //printk("2nd Disable EDGE CHK in MT7623\n"); ++ /* Disable EDGE CHK in MT7623*/ ++ for (i = 0 ; i<5 ; i++) { ++ tmp = *(volatile u_long *)(TRGMII_7623_RD_0 + i*8); ++ tmp |= 0x40000000; ++ *(volatile u_long *)(TRGMII_7623_RD_0 + i*8) = tmp & 0x4fffffff; ++ } ++ wait_loop(); ++ //printk("2nd Disable EDGE CHK in MT7623\n"); ++ /* Adjust RXC delay */ ++ *(volatile u_long *)(TRGMII_7623_base +0x00) |= 0x80000000; // Assert RX reset in MT7623 ++ *(volatile u_long *)(TRGMII_7623_base +0x04) &= 0x3fffffff; // RX clock gating in MT7623 ++ read_data = *(volatile u_long *)(TRGMII_7623_base); ++ if (err_total_flag == 0) { ++ tmp = (read_data & 0x0000007f) + rxc_step_size; ++ //printk(" RXC delay = %d\n", tmp); ++ read_data >>= 8; ++ read_data &= 0xffffff80; ++ read_data |= tmp; ++ read_data <<=8; ++ read_data &= 0xffffff80; ++ read_data |=tmp; ++ *(volatile u_long *)(TRGMII_7623_base) = read_data; ++ } ++ read_data &=0x000000ff; ++ *(volatile u_long *)(TRGMII_7623_base ) &= 0x7fffffff; // Release RX reset in MT7623 ++ *(volatile u_long *)(TRGMII_7623_base +0x04) |= 0xC0000000; // Disable RX clock gating in MT7623 ++ for (i = 0 ; i<5 ; i++) { ++ *(volatile u_long *)(TRGMII_7623_RD_0 + i*8) = (*(volatile u_long *)(TRGMII_7623_RD_0 + i*8)) | 0x80000000; // Set bslip_en = ~bit_slip_en ++ } ++ } ++ //printk("Finish RXC Adjustment while loop\n"); ++ //printk("Read RD_WD MT7623\n"); ++ /* Read RD_WD MT7623*/ ++ for (i = 0 ; i<5 ; i++) { ++ rd_tap=0; ++ while (err_flag[i] != 0) { ++ /* Enable EDGE CHK in MT7623*/ ++ tmp = *(volatile u_long *)(TRGMII_7623_RD_0 + i*8); ++ tmp |= 0x40000000; ++ *(volatile u_long *)(TRGMII_7623_RD_0 + i*8) = tmp & 0x4fffffff; ++ wait_loop(); ++ read_data = *(volatile u_long *)(TRGMII_7623_RD_0 + i*8); ++ err_cnt[i] = (read_data >> 8) & 0x0000000f; // Read MT7623 Errcnt ++ rd_wd = (read_data >> 16) & 0x000000ff; ++ if (err_cnt[i] != 0 || rd_wd !=0x55){ ++ err_flag [i] = 1; ++ } ++ else { ++ err_flag[i] =0; ++ } ++ /* Disable EDGE CHK in MT7623*/ ++ *(volatile u_long *)(TRGMII_7623_RD_0 + i*8) &= 0x4fffffff; ++ tmp |= 0x40000000; ++ *(volatile u_long *)(TRGMII_7623_RD_0 + i*8) = tmp & 0x4fffffff; ++ wait_loop(); ++ //err_cnt[i] = ((read_data) >> 8) & 0x0000000f; // Read MT7623 Errcnt ++ if (err_flag[i] !=0) { ++ rd_tap = (read_data & 0x0000007f) + rxd_step_size; // Add RXD delay in MT7623 ++ read_data = (read_data & 0xffffff80) | rd_tap; ++ *(volatile u_long *)(TRGMII_7623_RD_0 + i*8) = read_data; ++ tap_a[i] = rd_tap; ++ } else { ++ rd_tap = (read_data & 0x0000007f) + 4; ++ read_data = (read_data & 0xffffff80) | rd_tap; ++ *(volatile u_long *)(TRGMII_7623_RD_0 + i*8) = read_data; ++ } ++ //err_cnt[i] = (*(volatile u_long *)(TRGMII_7623_RD_0 + i*8) >> 8) & 0x0000000f; // Read MT7623 Errcnt ++ ++ } ++ //printk("%dth bit Tap_a = %d\n", i, tap_a[i]); ++ } ++ //printk("Last While Loop\n"); ++ for (i = 0 ; i<5 ; i++) { ++ //printk(" Bit%d\n", i); ++ rd_tap =0; ++ while ((err_cnt[i] == 0) && (rd_tap !=128)) { ++ read_data = *(volatile u_long *)(TRGMII_7623_RD_0 + i*8); ++ rd_tap = (read_data & 0x0000007f) + rxd_step_size; // Add RXD delay in MT7623 ++ read_data = (read_data & 0xffffff80) | rd_tap; ++ *(volatile u_long *)(TRGMII_7623_RD_0 + i*8) = read_data; ++ /* Enable EDGE CHK in MT7623*/ ++ tmp = *(volatile u_long *)(TRGMII_7623_RD_0 + i*8); ++ tmp |= 0x40000000; ++ *(volatile u_long *)(TRGMII_7623_RD_0 + i*8) = tmp & 0x4fffffff; ++ wait_loop(); ++ err_cnt[i] = ((*(volatile u_long *)(TRGMII_7623_RD_0 + i*8)) >> 8) & 0x0000000f; // Read MT7623 Errcnt ++ /* Disable EDGE CHK in MT7623*/ ++ tmp = *(volatile u_long *)(TRGMII_7623_RD_0 + i*8); ++ tmp |= 0x40000000; ++ *(volatile u_long *)(TRGMII_7623_RD_0 + i*8) = tmp & 0x4fffffff; ++ wait_loop(); ++ //err_cnt[i] = ((*(volatile u_long *)(TRGMII_7623_RD_0 + i*8)) >> 8) & 0x0000000f; // Read MT7623 Errcnt ++ ++ } ++ tap_b[i] = rd_tap;// -rxd_step_size; // Record the max delay TAP_B ++ //printk("tap_b[%d] is %d \n", i,tap_b[i]); ++ final_tap[i] = (tap_a[i]+tap_b[i])/2; // Calculate RXD delay = (TAP_A + TAP_B)/2 ++ //printk("%dth bit Final Tap = %d\n", i, final_tap[i]); ++ read_data = (read_data & 0xffffff80) | final_tap[i]; ++ *(volatile u_long *)(TRGMII_7623_RD_0 + i*8) = read_data; ++ } ++// /*word alignment*/ ++// mii_mgr_read(0x1F,0x7A50,&read_data); ++// read_data &= ~(0xff); ++// read_data |= 0xac; ++// mii_mgr_write(0x1F,0x7A50,read_data); ++// while (i <10) { ++// i++; ++// wait_loop(); ++// } ++// /* Enable EDGE CHK in MT7623*/ ++// for (i=0; i<5; i++) { ++// tmp = *(volatile u_long *)(TRGMII_7623_RD_0 + i*8); ++// tmp |= 0x40000000; ++// *(volatile u_long *)(TRGMII_7623_RD_0 + i*8) = tmp & 0x4fffffff; ++// wait_loop(); ++// /* Disable EDGE CHK in MT7623*/ ++// tmp = *(volatile u_long *)(TRGMII_7623_RD_0 + i*8); ++// tmp |= 0x40000000; ++// *(volatile u_long *)(TRGMII_7623_RD_0 + i*8) = tmp & 0x4fffffff; ++// wait_loop(); ++// read_data = *(volatile u_long *)(TRGMII_7623_RD_0+i*8); ++// printk(" MT7623 training word = %x\n", read_data); ++// } ++ ++ ++ mii_mgr_read(0x1F,0x7A40,&read_data); ++ //printk(" MT7530 0x7A40 = %x\n", read_data); ++ read_data &=0x3fffffff; ++ mii_mgr_write(0x1F,0x7A40,read_data); ++} ++ ++ ++void trgmii_calibration_7530(void){ ++ ++ unsigned int tap_a[5]; ++ unsigned int tap_b[5]; ++ unsigned int final_tap[5]; ++ unsigned int bslip_en; ++ unsigned int rxc_step_size; ++ unsigned int rxd_step_size; ++ unsigned int read_data; ++ unsigned int tmp; ++ int i,j; ++ unsigned int err_cnt[5]; ++ unsigned int rd_wd; ++ unsigned int init_toggle_data; ++ unsigned int err_flag[5]; ++ unsigned int err_total_flag; ++ unsigned int training_word; ++ unsigned int rd_tap; ++ ++ u32 TRGMII_7623_base; ++ u32 TRGMII_7530_RD_0; ++ u32 TRGMII_RD_1; ++ u32 TRGMII_RD_2; ++ u32 TRGMII_RD_3; ++ u32 TRGMII_RXCTL; ++ u32 TRGMII_RCK_CTRL; ++ u32 TRGMII_7530_base; ++ u32 TRGMII_7530_TX_base; ++ TRGMII_7623_base = 0xFB110300; ++ TRGMII_7530_base = 0x7A00; ++ TRGMII_7530_RD_0 = TRGMII_7530_base + 0x10; ++ TRGMII_RCK_CTRL = TRGMII_7623_base; ++ rxd_step_size = 0x1; ++ rxc_step_size = 0x8; ++ init_toggle_data = 0x00000055; ++ training_word = 0x000000AC; ++ ++ TRGMII_7530_TX_base = TRGMII_7530_base + 0x50; ++ ++ //printk("Calibration begin ........\n"); ++ *(volatile u_long *)(TRGMII_7623_base + 0x40) |= 0x80000000; ++ mii_mgr_read(0x1F, 0x7a10, &read_data); ++ //printk("TRGMII_7530_RD_0 is %x\n", read_data); ++ ++ mii_mgr_read(0x1F,TRGMII_7530_base+0x04,&read_data); ++ read_data &= 0x3fffffff; ++ mii_mgr_write(0x1F,TRGMII_7530_base+0x04,read_data); // RX clock gating in MT7530 ++ ++ mii_mgr_read(0x1F,TRGMII_7530_base+0x78,&read_data); ++ read_data |= 0x00002000; ++ mii_mgr_write(0x1F,TRGMII_7530_base+0x78,read_data); // Set TX OE edge in MT7530 ++ ++ mii_mgr_read(0x1F,TRGMII_7530_base,&read_data); ++ read_data |= 0x80000000; ++ mii_mgr_write(0x1F,TRGMII_7530_base,read_data); // Assert RX reset in MT7530 ++ ++ ++ mii_mgr_read(0x1F,TRGMII_7530_base,&read_data); ++ read_data &= 0x7fffffff; ++ mii_mgr_write(0x1F,TRGMII_7530_base,read_data); // Release RX reset in MT7530 ++ ++ mii_mgr_read(0x1F,TRGMII_7530_base+0x04,&read_data); ++ read_data |= 0xC0000000; ++ mii_mgr_write(0x1F,TRGMII_7530_base+0x04,read_data); // Disable RX clock gating in MT7530 ++ ++ //printk("Enable Training Mode in MT7623\n"); ++ /*Enable Training Mode in MT7623*/ ++ *(volatile u_long *)(TRGMII_7623_base + 0x40) &= 0xbfffffff; ++ *(volatile u_long *)(TRGMII_7623_base + 0x40) |= 0x80000000; ++ *(volatile u_long *)(TRGMII_7623_base + 0x78) &= 0xfffff0ff; ++ *(volatile u_long *)(TRGMII_7623_base + 0x78) |= 0x00000400; ++ ++ err_total_flag =0; ++ //printk("Adjust RXC delay in MT7530\n"); ++ read_data =0x0; ++ while (err_total_flag == 0 && (read_data != 0x68)) { ++ //printk("2nd Enable EDGE CHK in MT7530\n"); ++ /* Enable EDGE CHK in MT7530*/ ++ for (i = 0 ; i<5 ; i++) { ++ mii_mgr_read(0x1F,TRGMII_7530_RD_0+i*8,&read_data); ++ read_data |= 0x40000000; ++ read_data &= 0x4fffffff; ++ mii_mgr_write(0x1F,TRGMII_7530_RD_0+i*8,read_data); ++ wait_loop(); ++ //printk("2nd Disable EDGE CHK in MT7530\n"); ++ mii_mgr_read(0x1F,TRGMII_7530_RD_0+i*8,&err_cnt[i]); ++ //printk("***** MT7530 %dth bit ERR_CNT =%x\n",i, err_cnt[i]); ++ //printk("MT7530 %dth bit ERR_CNT =%x\n",i, err_cnt[i]); ++ err_cnt[i] >>= 8; ++ err_cnt[i] &= 0x0000ff0f; ++ rd_wd = err_cnt[i] >> 8; ++ rd_wd &= 0x000000ff; ++ err_cnt[i] &= 0x0000000f; ++ //mii_mgr_read(0x1F,0x7a10,&read_data); ++ if ( err_cnt[i] !=0 ) { ++ err_flag[i] = 1; ++ } ++ else if (rd_wd != 0x55) { ++ err_flag[i] = 1; ++ } else { ++ err_flag[i] = 0; ++ } ++ if (i==0) { ++ err_total_flag = err_flag[i]; ++ } else { ++ err_total_flag = err_flag[i] & err_total_flag; ++ } ++ /* Disable EDGE CHK in MT7530*/ ++ mii_mgr_read(0x1F,TRGMII_7530_RD_0+i*8,&read_data); ++ read_data |= 0x40000000; ++ read_data &= 0x4fffffff; ++ mii_mgr_write(0x1F,TRGMII_7530_RD_0+i*8,read_data); ++ wait_loop(); ++ } ++ /*Adjust RXC delay*/ ++ if (err_total_flag ==0) { ++ mii_mgr_read(0x1F,TRGMII_7530_base,&read_data); ++ read_data |= 0x80000000; ++ mii_mgr_write(0x1F,TRGMII_7530_base,read_data); // Assert RX reset in MT7530 ++ ++ mii_mgr_read(0x1F,TRGMII_7530_base+0x04,&read_data); ++ read_data &= 0x3fffffff; ++ mii_mgr_write(0x1F,TRGMII_7530_base+0x04,read_data); // RX clock gating in MT7530 ++ ++ mii_mgr_read(0x1F,TRGMII_7530_base,&read_data); ++ tmp = read_data; ++ tmp &= 0x0000007f; ++ tmp += rxc_step_size; ++ //printk("Current rxc delay = %d\n", tmp); ++ read_data &= 0xffffff80; ++ read_data |= tmp; ++ mii_mgr_write (0x1F,TRGMII_7530_base,read_data); ++ mii_mgr_read(0x1F,TRGMII_7530_base,&read_data); ++ //printk("Current RXC delay = %x\n", read_data); ++ ++ mii_mgr_read(0x1F,TRGMII_7530_base,&read_data); ++ read_data &= 0x7fffffff; ++ mii_mgr_write(0x1F,TRGMII_7530_base,read_data); // Release RX reset in MT7530 ++ ++ mii_mgr_read(0x1F,TRGMII_7530_base+0x04,&read_data); ++ read_data |= 0xc0000000; ++ mii_mgr_write(0x1F,TRGMII_7530_base+0x04,read_data); // Disable RX clock gating in MT7530 ++ } ++ read_data = tmp; ++ } ++ //printk("RXC delay is %d\n", tmp); ++ //printk("Finish RXC Adjustment while loop\n"); ++ ++ //printk("Read RD_WD MT7530\n"); ++ /* Read RD_WD MT7530*/ ++ for (i = 0 ; i<5 ; i++) { ++ rd_tap = 0; ++ while (err_flag[i] != 0) { ++ /* Enable EDGE CHK in MT7530*/ ++ mii_mgr_read(0x1F,TRGMII_7530_RD_0+i*8,&read_data); ++ read_data |= 0x40000000; ++ read_data &= 0x4fffffff; ++ mii_mgr_write(0x1F,TRGMII_7530_RD_0+i*8,read_data); ++ wait_loop(); ++ err_cnt[i] = (read_data >> 8) & 0x0000000f; ++ rd_wd = (read_data >> 16) & 0x000000ff; ++ //printk("##### %dth bit ERR_CNT = %x RD_WD =%x ######\n", i, err_cnt[i],rd_wd); ++ if (err_cnt[i] != 0 || rd_wd !=0x55){ ++ err_flag [i] = 1; ++ } ++ else { ++ err_flag[i] =0; ++ } ++ if (err_flag[i] !=0 ) { ++ rd_tap = (read_data & 0x0000007f) + rxd_step_size; // Add RXD delay in MT7530 ++ read_data = (read_data & 0xffffff80) | rd_tap; ++ mii_mgr_write(0x1F,TRGMII_7530_RD_0+i*8,read_data); ++ tap_a[i] = rd_tap; ++ } else { ++ tap_a[i] = (read_data & 0x0000007f); // Record the min delay TAP_A ++ rd_tap = tap_a[i] + 0x4; ++ read_data = (read_data & 0xffffff80) | rd_tap ; ++ mii_mgr_write(0x1F,TRGMII_7530_RD_0+i*8,read_data); ++ } ++ ++ /* Disable EDGE CHK in MT7530*/ ++ mii_mgr_read(0x1F,TRGMII_7530_RD_0+i*8,&read_data); ++ read_data |= 0x40000000; ++ read_data &= 0x4fffffff; ++ mii_mgr_write(0x1F,TRGMII_7530_RD_0+i*8,read_data); ++ wait_loop(); ++ ++ } ++ //printk("%dth bit Tap_a = %d\n", i, tap_a[i]); ++ } ++ //printk("Last While Loop\n"); ++ for (i = 0 ; i<5 ; i++) { ++ rd_tap =0; ++ while (err_cnt[i] == 0 && (rd_tap!=128)) { ++ /* Enable EDGE CHK in MT7530*/ ++ mii_mgr_read(0x1F,TRGMII_7530_RD_0+i*8,&read_data); ++ read_data |= 0x40000000; ++ read_data &= 0x4fffffff; ++ mii_mgr_write(0x1F,TRGMII_7530_RD_0+i*8,read_data); ++ wait_loop(); ++ err_cnt[i] = (read_data >> 8) & 0x0000000f; ++ //rd_tap = (read_data & 0x0000007f) + 0x4; // Add RXD delay in MT7530 ++ if (err_cnt[i] == 0 && (rd_tap!=128)) { ++ rd_tap = (read_data & 0x0000007f) + rxd_step_size; // Add RXD delay in MT7530 ++ read_data = (read_data & 0xffffff80) | rd_tap; ++ mii_mgr_write(0x1F,TRGMII_7530_RD_0+i*8,read_data); ++ } ++ /* Disable EDGE CHK in MT7530*/ ++ mii_mgr_read(0x1F,TRGMII_7530_RD_0+i*8,&read_data); ++ read_data |= 0x40000000; ++ read_data &= 0x4fffffff; ++ mii_mgr_write(0x1F,TRGMII_7530_RD_0+i*8,read_data); ++ wait_loop(); ++ } ++ tap_b[i] = rd_tap;// - rxd_step_size; // Record the max delay TAP_B ++ //printk("%dth bit Tap_b = %d, ERR_CNT=%d\n", i, tap_b[i],err_cnt[i]); ++ final_tap[i] = (tap_a[i]+tap_b[i])/2; // Calculate RXD delay = (TAP_A + TAP_B)/2 ++ //printk("%dth bit Final Tap = %d\n", i, final_tap[i]); ++ ++ read_data = ( read_data & 0xffffff80) | final_tap[i]; ++ mii_mgr_write(0x1F,TRGMII_7530_RD_0+i*8,read_data); ++ } ++ *(volatile u_long *)(TRGMII_7623_base + 0x40) &=0x3fffffff; ++ ++} ++ ++void set_trgmii_325_delay_setting(void) ++{ ++ /*mt7530 side*/ ++ *(volatile u_long *)(0xfb110300) = 0x80020050; ++ *(volatile u_long *)(0xfb110304) = 0x00980000; ++ *(volatile u_long *)(0xfb110300) = 0x40020050; ++ *(volatile u_long *)(0xfb110304) = 0xc0980000; ++ *(volatile u_long *)(0xfb110310) = 0x00000028; ++ *(volatile u_long *)(0xfb110318) = 0x0000002e; ++ *(volatile u_long *)(0xfb110320) = 0x0000002d; ++ *(volatile u_long *)(0xfb110328) = 0x0000002b; ++ *(volatile u_long *)(0xfb110330) = 0x0000002a; ++ *(volatile u_long *)(0xfb110340) = 0x00020000; ++ /*mt7530 side*/ ++ mii_mgr_write(31, 0x7a00, 0x10); ++ mii_mgr_write(31, 0x7a10, 0x23); ++ mii_mgr_write(31, 0x7a18, 0x27); ++ mii_mgr_write(31, 0x7a20, 0x24); ++ mii_mgr_write(31, 0x7a28, 0x29); ++ mii_mgr_write(31, 0x7a30, 0x24); ++ ++} ++ ++ ++void setup_internal_gsw(void) ++{ ++ u32 i; ++ u32 regValue; ++ u32 xtal_mode; ++ ++ mt7623_pinmux_set(); /* TODO: just for bring up, should be removed!!! */ ++ ++#if 0 ++ /* GE1: RGMII mode setting */ ++ *(volatile u_long *)(0xfb110300) = 0x80020000; ++ *(volatile u_long *)(0xfb110304) = 0x00980000; ++ *(volatile u_long *)(0xfb110300) = 0x40020000; ++ *(volatile u_long *)(0xfb110304) = 0xc0980000; ++ *(volatile u_long *)(0xfb110310) = 0x00000041; ++ *(volatile u_long *)(0xfb110318) = 0x00000044; ++ *(volatile u_long *)(0xfb110320) = 0x00000043; ++ *(volatile u_long *)(0xfb110328) = 0x00000042; ++ *(volatile u_long *)(0xfb110330) = 0x00000042; ++ *(volatile u_long *)(0xfb110340) = 0x00020000; ++ *(volatile u_long *)(0xfb110390) &= 0xfffffff8; //RGMII mode ++#else ++ /* GE1: TRGMII mode setting */ ++ *(volatile u_long *)(0xfb110390) |= 0x00000002; //TRGMII mode ++#endif ++ ++ /*Todo: Hardware reset Switch*/ ++ /*Hardware reset Switch*/ ++#if defined(CONFIG_ARCH_MT7623) ++ regValue = *(volatile u_long *)(0xfb00000c); ++ /*MT7530 Reset. Flows for MT7623 and MT7683 are both excuted.*/ ++ /* Should Modify this section if EFUSE is ready*/ ++ /*For MT7683 reset MT7530*/ ++ if(!(regValue & (1<<16))) ++ { ++ *(volatile u_long *)(0xf0005520) &= ~(1<<1); ++ udelay(1000); ++ *(volatile u_long *)(0xf0005520) |= (1<<1); ++ mdelay(100); ++ } ++ //printk("Assert MT7623 RXC reset\n"); ++ *(volatile u_long *)(0xfb110300) |= 0x80000000; // Assert MT7623 RXC reset ++ /*For MT7623 reset MT7530*/ ++ *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x34) |= (0x1 << 2); ++ udelay(1000); ++ *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x34) &= ~(0x1 << 2); ++ mdelay(100); ++#endif ++ ++#if defined (CONFIG_GE1_RGMII_FORCE_1000) || defined (CONFIG_GE1_TRGMII_FORCE_1200) || defined (CONFIG_GE1_TRGMII_FORCE_2000) || defined (CONFIG_GE1_TRGMII_FORCE_2600) ++ for(i=0;i<=4;i++) ++ { ++ //turn off PHY ++ mii_mgr_read(i, 0x0 ,®Value); ++ regValue |= (0x1<<11); ++ mii_mgr_write(i, 0x0, regValue); ++ } ++ mii_mgr_write(31, 0x7000, 0x3); //reset switch ++ udelay(100); ++ ++#if defined (CONFIG_MT7621_ASIC) || defined (CONFIG_ARCH_MT7623) ++#if 0 ++ if((sysRegRead(0xbe00000c)&0xFFFF)==0x0101) { ++ sysRegWrite(RALINK_ETH_SW_BASE+0x100, 0x2105e30b);//(GE1, Force 1000M/FD, FC ON) ++ mii_mgr_write(31, 0x3600, 0x5e30b); ++ } else ++#endif ++ { ++ sysRegWrite(RALINK_ETH_SW_BASE+0x100, 0x2105e33b);//(GE1, Force 1000M/FD, FC ON) ++ mii_mgr_write(31, 0x3600, 0x5e33b); ++ mii_mgr_read(31, 0x3600 ,®Value); ++ } ++#endif ++ sysRegWrite(RALINK_ETH_SW_BASE+0x200, 0x00008000);//(GE2, Link down) ++#endif ++ ++#if defined (CONFIG_GE1_RGMII_FORCE_1000) || defined (CONFIG_GE1_TRGMII_FORCE_1200) || defined (CONFIG_GE1_TRGMII_FORCE_2000) || defined (CONFIG_GE1_TRGMII_FORCE_2600) ++ //regValue = 0x117ccf; //Enable Port 6, P5 as GMAC5, P5 disable*/ ++ mii_mgr_read(31, 0x7804 ,®Value); ++ regValue &= ~(1<<8); //Enable Port 6 ++ regValue |= (1<<6); //Disable Port 5 ++ regValue |= (1<<13); //Port 5 as GMAC, no Internal PHY ++ ++#if defined (CONFIG_RAETH_GMAC2) ++ //RGMII2=Normal mode ++ *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x60) &= ~(0x1 << 15); ++ ++ //GMAC2= RGMII mode ++ *(volatile u_long *)(SYSCFG1) &= ~(0x3 << 14); ++ mii_mgr_write(31, 0x3500, 0x56300); //MT7530 P5 AN, we can ignore this setting?????? ++ sysRegWrite(RALINK_ETH_SW_BASE+0x200, 0x21056300);//(GE2, auto-polling) ++ enable_auto_negotiate(0);//set polling address ++ ++ /* set MT7530 Port 5 to PHY 0/4 mode */ ++#if defined (CONFIG_GE_RGMII_INTERNAL_P0_AN) ++ regValue &= ~((1<<13)|(1<<6)); ++ regValue |= ((1<<7)|(1<<16)|(1<<20)); ++#elif defined (CONFIG_GE_RGMII_INTERNAL_P4_AN) ++ regValue &= ~((1<<13)|(1<<6)|(1<<20)); ++ regValue |= ((1<<7)|(1<<16)); ++#endif ++ /*Set MT7530 phy direct access mode**/ ++ regValue &= ~(1<<5); ++ ++ //sysRegWrite(GDMA2_FWD_CFG, 0x20710000); ++#endif ++ regValue |= (1<<16);//change HW-TRAP ++ printk("change HW-TRAP to 0x%x\n",regValue); ++ mii_mgr_write(31, 0x7804 ,regValue); ++#endif ++ mii_mgr_read(31, 0x7800, ®Value); ++ regValue = (regValue >> 9) & 0x3; ++ if(regValue == 0x3)//25Mhz Xtal ++ xtal_mode = 1; ++ else if(regValue == 0x2) //40Mhz ++ xtal_mode = 2; ++ else ++ xtal_mode = 3; ++ ++ if(xtal_mode == 1) { //25Mhz Xtal ++ /* do nothing */ ++ } else if(xtal_mode = 2) { //40Mhz ++ mii_mgr_write(0, 13, 0x1f); // disable MT7530 core clock ++ mii_mgr_write(0, 14, 0x410); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0x0); ++ ++ mii_mgr_write(0, 13, 0x1f); // disable MT7530 PLL ++ mii_mgr_write(0, 14, 0x40d); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0x2020); ++ ++ mii_mgr_write(0, 13, 0x1f); // for MT7530 core clock = 500Mhz ++ mii_mgr_write(0, 14, 0x40e); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0x119); ++ ++ mii_mgr_write(0, 13, 0x1f); // enable MT7530 PLL ++ mii_mgr_write(0, 14, 0x40d); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0x2820); ++ ++ udelay(20); //suggest by CD ++ ++ mii_mgr_write(0, 13, 0x1f); // enable MT7530 core clock ++ mii_mgr_write(0, 14, 0x410); ++ mii_mgr_write(0, 13, 0x401f); ++ }else {//20MHz ++ /*TODO*/ ++ } ++ ++#if defined (CONFIG_GE1_TRGMII_FORCE_1200) && defined (CONFIG_MT7621_ASIC) ++ mii_mgr_write(0, 14, 0x3); /*TRGMII*/ ++#else ++ mii_mgr_write(0, 14, 0x1); /*RGMII*/ ++/* set MT7530 central align */ ++ mii_mgr_read(31, 0x7830, ®Value); ++ regValue &= ~1; ++ regValue |= 1<<1; ++ mii_mgr_write(31, 0x7830, regValue); ++ ++ mii_mgr_read(31, 0x7a40, ®Value); ++ regValue &= ~(1<<30); ++ mii_mgr_write(31, 0x7a40, regValue); ++ ++ regValue = 0x855; ++ mii_mgr_write(31, 0x7a78, regValue); ++ ++#endif ++ mii_mgr_write(31, 0x7b00, 0x104); //delay setting for 10/1000M ++ mii_mgr_write(31, 0x7b04, 0x10); //delay setting for 10/1000M ++ ++ /*Tx Driving*/ ++ mii_mgr_write(31, 0x7a54, 0x88); //lower GE1 driving ++ mii_mgr_write(31, 0x7a5c, 0x88); //lower GE1 driving ++ mii_mgr_write(31, 0x7a64, 0x88); //lower GE1 driving ++ mii_mgr_write(31, 0x7a6c, 0x88); //lower GE1 driving ++ mii_mgr_write(31, 0x7a74, 0x88); //lower GE1 driving ++ mii_mgr_write(31, 0x7a7c, 0x88); //lower GE1 driving ++ mii_mgr_write(31, 0x7810, 0x11); //lower GE2 driving ++ /*Set MT7623/MT7683 TX Driving*/ ++ *(volatile u_long *)(0xfb110354) = 0x88; ++ *(volatile u_long *)(0xfb11035c) = 0x88; ++ *(volatile u_long *)(0xfb110364) = 0x88; ++ *(volatile u_long *)(0xfb11036c) = 0x88; ++ *(volatile u_long *)(0xfb110374) = 0x88; ++ *(volatile u_long *)(0xfb11037c) = 0x88; ++#if defined (CONFIG_GE2_RGMII_AN) ++ *(volatile u_long *)(0xf0005f00) = 0xe00; //Set GE2 driving and slew rate ++#else ++ *(volatile u_long *)(0xf0005f00) = 0xa00; //Set GE2 driving and slew rate ++#endif ++ *(volatile u_long *)(0xf00054c0) = 0x5; //set GE2 TDSEL ++ *(volatile u_long *)(0xf0005ed0) = 0; //set GE2 TUNE ++ ++ /* TRGMII Clock */ ++// printk("Set TRGMII mode clock stage 1\n"); ++ mii_mgr_write(0, 13, 0x1f); ++ mii_mgr_write(0, 14, 0x404); ++ mii_mgr_write(0, 13, 0x401f); ++ if (xtal_mode == 1){ //25MHz ++#if defined (CONFIG_GE1_TRGMII_FORCE_2900) ++ mii_mgr_write(0, 14, 0x1d00); // 362.5MHz ++#elif defined (CONFIG_GE1_TRGMII_FORCE_2600) ++ mii_mgr_write(0, 14, 0x1a00); // 325MHz ++#elif defined (CONFIG_GE1_TRGMII_FORCE_2000) ++ mii_mgr_write(0, 14, 0x1400); //250MHz ++#elif defined (CONFIG_GE1_RGMII_FORCE_1000) ++ mii_mgr_write(0, 14, 0x00a0); //125MHz ++#endif ++ }else if(xtal_mode == 2){//40MHz ++#if defined (CONFIG_GE1_TRGMII_FORCE_2900) ++ mii_mgr_write(0, 14, 0x1220); // 362.5MHz ++#elif defined (CONFIG_GE1_TRGMII_FORCE_2600) ++ mii_mgr_write(0, 14, 0x1040); // 325MHz ++#elif defined (CONFIG_GE1_TRGMII_FORCE_2000) ++ mii_mgr_write(0, 14, 0x0c80); //250MHz ++#elif defined (CONFIG_GE1_RGMII_FORCE_1000) ++ mii_mgr_write(0, 14, 0x0640); //125MHz ++#endif ++ } ++// printk("Set TRGMII mode clock stage 2\n"); ++ mii_mgr_write(0, 13, 0x1f); ++ mii_mgr_write(0, 14, 0x405); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0x0); ++ ++// printk("Set TRGMII mode clock stage 3\n"); ++ mii_mgr_write(0, 13, 0x1f); ++ mii_mgr_write(0, 14, 0x409); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0x0087); ++ ++// printk("Set TRGMII mode clock stage 4\n"); ++ mii_mgr_write(0, 13, 0x1f); ++ mii_mgr_write(0, 14, 0x40a); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0x0087); ++ ++// printk("Set TRGMII mode clock stage 5\n"); ++ mii_mgr_write(0, 13, 0x1f); ++ mii_mgr_write(0, 14, 0x403); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0x1800); ++ ++// printk("Set TRGMII mode clock stage 6\n"); ++ mii_mgr_write(0, 13, 0x1f); ++ mii_mgr_write(0, 14, 0x403); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0x1c00); ++ ++// printk("Set TRGMII mode clock stage 7\n"); ++ mii_mgr_write(0, 13, 0x1f); ++ mii_mgr_write(0, 14, 0x401); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0xc020); ++ ++// printk("Set TRGMII mode clock stage 8\n"); ++ mii_mgr_write(0, 13, 0x1f); ++ mii_mgr_write(0, 14, 0x406); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0xa030); ++ ++// printk("Set TRGMII mode clock stage 9\n"); ++ mii_mgr_write(0, 13, 0x1f); ++ mii_mgr_write(0, 14, 0x406); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0xa038); ++ ++ udelay(120); // for MT7623 bring up test ++ ++// printk("Set TRGMII mode clock stage 10\n"); ++ mii_mgr_write(0, 13, 0x1f); ++ mii_mgr_write(0, 14, 0x410); ++ mii_mgr_write(0, 13, 0x401f); ++ mii_mgr_write(0, 14, 0x3); ++ ++// printk("Set TRGMII mode clock stage 11\n"); ++ ++ mii_mgr_read(31, 0x7830 ,®Value); ++ regValue &=0xFFFFFFFC; ++ regValue |=0x00000001; ++ mii_mgr_write(31, 0x7830, regValue); ++ ++// printk("Set TRGMII mode clock stage 12\n"); ++ mii_mgr_read(31, 0x7a40 ,®Value); ++ regValue &= ~(0x1<<30); ++ regValue &= ~(0x1<<28); ++ mii_mgr_write(31, 0x7a40, regValue); ++ ++ //mii_mgr_write(31, 0x7a78, 0x855); ++ mii_mgr_write(31, 0x7a78, 0x55); ++// printk(" Adjust MT7530 TXC delay\n"); ++ udelay(100); // for mt7623 bring up test ++ ++// printk(" Release MT7623 RXC Reset\n"); ++ *(volatile u_long *)(0xfb110300) &= 0x7fffffff; // Release MT7623 RXC reset ++ //disable EEE ++ for(i=0;i<=4;i++) ++ { ++ mii_mgr_write(i, 13, 0x7); ++ mii_mgr_write(i, 14, 0x3C); ++ mii_mgr_write(i, 13, 0x4007); ++ mii_mgr_write(i, 14, 0x0); ++ } ++ ++ //Disable EEE 10Base-Te: ++ for(i=0;i<=4;i++) ++ { ++ mii_mgr_write(i, 13, 0x1f); ++ mii_mgr_write(i, 14, 0x027b); ++ mii_mgr_write(i, 13, 0x401f); ++ mii_mgr_write(i, 14, 0x1177); ++ } ++ ++ for(i=0;i<=4;i++) ++ { ++ //turn on PHY ++ mii_mgr_read(i, 0x0 ,®Value); ++ regValue &= ~(0x1<<11); ++ mii_mgr_write(i, 0x0, regValue); ++ } ++ ++ for(i=0;i<=4;i++) { ++ mii_mgr_read(i, 4, ®Value); ++ regValue |= (3<<7); //turn on 100Base-T Advertisement ++ mii_mgr_write(i, 4, regValue); ++ ++ mii_mgr_read(i, 9, ®Value); ++ regValue |= (3<<8); //turn on 1000Base-T Advertisement ++ mii_mgr_write(i, 9, regValue); ++ ++ //restart AN ++ mii_mgr_read(i, 0, ®Value); ++ regValue |= (1 << 9); ++ mii_mgr_write(i, 0, regValue); ++ } ++ ++ mii_mgr_read(31, 0x7808 ,®Value); ++ regValue |= (3<<16); //Enable INTR ++ mii_mgr_write(31, 0x7808 ,regValue); ++} ++ ++void mt7623_ethifsys_init(void) ++{ ++#define TRGPLL_CON0 (0xF0209280) ++#define TRGPLL_CON1 (0xF0209284) ++#define TRGPLL_CON2 (0xF0209288) ++#define TRGPLL_PWR_CON0 (0xF020928C) ++#define ETHPLL_CON0 (0xF0209290) ++#define ETHPLL_CON1 (0xF0209294) ++#define ETHPLL_CON2 (0xF0209298) ++#define ETHPLL_PWR_CON0 (0xF020929C) ++#define ETH_PWR_CON (0xF00062A0) ++#define HIF_PWR_CON (0xF00062A4) ++ ++ u32 temp, pwr_ack_status; ++ /*=========================================================================*/ ++ /* Enable ETHPLL & TRGPLL*/ ++ /*=========================================================================*/ ++ /* xPLL PWR ON*/ ++ temp = sysRegRead(ETHPLL_PWR_CON0); ++ sysRegWrite(ETHPLL_PWR_CON0, temp | 0x1); ++ ++ temp = sysRegRead(TRGPLL_PWR_CON0); ++ sysRegWrite(TRGPLL_PWR_CON0, temp | 0x1); ++ ++ udelay(5); /* wait for xPLL_PWR_ON ready (min delay is 1us)*/ ++ ++ /* xPLL ISO Disable*/ ++ temp = sysRegRead(ETHPLL_PWR_CON0); ++ sysRegWrite(ETHPLL_PWR_CON0, temp & ~0x2); ++ ++ temp = sysRegRead(TRGPLL_PWR_CON0); ++ sysRegWrite(TRGPLL_PWR_CON0, temp & ~0x2); ++ ++ /* xPLL Frequency Set*/ ++ temp = sysRegRead(ETHPLL_CON0); ++ sysRegWrite(ETHPLL_CON0, temp | 0x1); ++#if defined (CONFIG_GE1_TRGMII_FORCE_2900) ++ temp = sysRegRead(TRGPLL_CON0); ++ sysRegWrite(TRGPLL_CON0, temp | 0x1); ++#elif defined (CONFIG_GE1_TRGMII_FORCE_2600) ++ sysRegWrite(TRGPLL_CON1, 0xB2000000); ++ temp = sysRegRead(TRGPLL_CON0); ++ sysRegWrite(TRGPLL_CON0, temp | 0x1); ++#elif defined (CONFIG_GE1_TRGMII_FORCE_2000) ++ sysRegWrite(TRGPLL_CON1, 0xCCEC4EC5); ++ sysRegWrite(TRGPLL_CON0, 0x121); ++#endif ++ udelay(40); /* wait for PLL stable (min delay is 20us)*/ ++ ++ ++ /*=========================================================================*/ ++ /* Power on ETHDMASYS and HIFSYS*/ ++ /*=========================================================================*/ ++ /* Power on ETHDMASYS*/ ++ sysRegWrite(0xF0006000, 0x0b160001); ++ pwr_ack_status = (sysRegRead(ETH_PWR_CON) & 0x0000f000) >> 12; ++ ++ if(pwr_ack_status == 0x0) { ++ printk("ETH already turn on and power on flow will be skipped...\n"); ++ }else { ++ temp = sysRegRead(ETH_PWR_CON) ; ++ sysRegWrite(ETH_PWR_CON, temp | 0x4); /* PWR_ON*/ ++ temp = sysRegRead(ETH_PWR_CON) ; ++ sysRegWrite(ETH_PWR_CON, temp | 0x8); /* PWR_ON_S*/ ++ ++ udelay(5); /* wait power settle time (min delay is 1us)*/ ++ ++ temp = sysRegRead(ETH_PWR_CON) ; ++ sysRegWrite(ETH_PWR_CON, temp & ~0x10); /* PWR_CLK_DIS*/ ++ temp = sysRegRead(ETH_PWR_CON) ; ++ sysRegWrite(ETH_PWR_CON, temp & ~0x2); /* PWR_ISO*/ ++ temp = sysRegRead(ETH_PWR_CON) ; ++ sysRegWrite(ETH_PWR_CON, temp & ~0x100); /* SRAM_PDN 0*/ ++ temp = sysRegRead(ETH_PWR_CON) ; ++ sysRegWrite(ETH_PWR_CON, temp & ~0x200); /* SRAM_PDN 1*/ ++ temp = sysRegRead(ETH_PWR_CON) ; ++ sysRegWrite(ETH_PWR_CON, temp & ~0x400); /* SRAM_PDN 2*/ ++ temp = sysRegRead(ETH_PWR_CON) ; ++ sysRegWrite(ETH_PWR_CON, temp & ~0x800); /* SRAM_PDN 3*/ ++ ++ udelay(5); /* wait SRAM settle time (min delay is 1Us)*/ ++ ++ temp = sysRegRead(ETH_PWR_CON) ; ++ sysRegWrite(ETH_PWR_CON, temp | 0x1); /* PWR_RST_B*/ ++ } ++ ++ /* Power on HIFSYS*/ ++ pwr_ack_status = (sysRegRead(HIF_PWR_CON) & 0x0000f000) >> 12; ++ if(pwr_ack_status == 0x0) { ++ printk("HIF already turn on and power on flow will be skipped...\n"); ++ } ++ else { ++ temp = sysRegRead(HIF_PWR_CON) ; ++ sysRegWrite(HIF_PWR_CON, temp | 0x4); /* PWR_ON*/ ++ temp = sysRegRead(HIF_PWR_CON) ; ++ sysRegWrite(HIF_PWR_CON, temp | 0x8); /* PWR_ON_S*/ ++ ++ udelay(5); /* wait power settle time (min delay is 1us)*/ ++ ++ temp = sysRegRead(HIF_PWR_CON) ; ++ sysRegWrite(HIF_PWR_CON, temp & ~0x10); /* PWR_CLK_DIS*/ ++ temp = sysRegRead(HIF_PWR_CON) ; ++ sysRegWrite(HIF_PWR_CON, temp & ~0x2); /* PWR_ISO*/ ++ temp = sysRegRead(HIF_PWR_CON) ; ++ sysRegWrite(HIF_PWR_CON, temp & ~0x100); /* SRAM_PDN 0*/ ++ temp = sysRegRead(HIF_PWR_CON) ; ++ sysRegWrite(HIF_PWR_CON, temp & ~0x200); /* SRAM_PDN 1*/ ++ temp = sysRegRead(HIF_PWR_CON) ; ++ sysRegWrite(HIF_PWR_CON, temp & ~0x400); /* SRAM_PDN 2*/ ++ temp = sysRegRead(HIF_PWR_CON) ; ++ sysRegWrite(HIF_PWR_CON, temp & ~0x800); /* SRAM_PDN 3*/ ++ ++ udelay(5); /* wait SRAM settle time (min delay is 1Us)*/ ++ ++ temp = sysRegRead(HIF_PWR_CON) ; ++ sysRegWrite(HIF_PWR_CON, temp | 0x1); /* PWR_RST_B*/ ++ } ++ ++ /* Release mt7530 reset */ ++ temp = le32_to_cpu(*(volatile u_long *)(0xfb000034)); ++ temp &= ~(BIT(2)); ++ *(volatile u_long *)(0xfb000034) = temp; ++} ++#endif ++ ++/** ++ * ra2882eth_init - Module Init code ++ * ++ * Called by kernel to register net_device ++ * ++ */ ++ ++static int fe_probe(struct platform_device *pdev) ++{ ++ int ret; ++ struct net_device *dev = alloc_etherdev(sizeof(END_DEVICE)); ++ ++ fe_irq = platform_get_irq(pdev, 0); ++ ++#ifdef CONFIG_RALINK_VISTA_BASIC ++ int sw_id=0; ++ mii_mgr_read(29, 31, &sw_id); ++ is_switch_175c = (sw_id == 0x175c) ? 1:0; ++#endif ++ ++ if (!dev) ++ return -ENOMEM; ++ ++ strcpy(dev->name, DEV_NAME); ++ printk("%s:%s[%d]%d\n", __FILE__, __func__, __LINE__, fe_irq); ++ dev->irq = fe_irq; ++ dev->addr_len = 6; ++ dev->base_addr = RALINK_FRAME_ENGINE_BASE; ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ rather_probe(dev); ++#else ++ dev->init = rather_probe; ++#endif ++ ra2880_setup_dev_fptable(dev); ++ ++ /* net_device structure Init */ ++ ethtool_init(dev); ++ printk("Ralink APSoC Ethernet Driver Initilization. %s %d rx/tx descriptors allocated, mtu = %d!\n", RAETH_VERSION, NUM_RX_DESC, dev->mtu); ++#ifdef CONFIG_RAETH_NAPI ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ printk("NAPI enable, Tx Ring = %d, Rx Ring = %d\n", NUM_TX_DESC, NUM_RX_DESC); ++#else ++ printk("NAPI enable, weight = %d, Tx Ring = %d, Rx Ring = %d\n", dev->weight, NUM_TX_DESC, NUM_RX_DESC); ++#endif ++#endif ++ ++ /* Register net device for the driver */ ++ if ( register_netdev(dev) != 0) { ++ printk(KERN_WARNING " " __FILE__ ": No ethernet port found.\n"); ++ return -ENXIO; ++ } ++ ++ ++#ifdef CONFIG_RAETH_NETLINK ++ csr_netlink_init(); ++#endif ++ ret = debug_proc_init(); ++ ++ dev_raether = dev; ++#ifdef CONFIG_ARCH_MT7623 ++ mt7623_ethifsys_init(); ++#endif ++ return ret; ++} ++ ++ ++ ++ ++ ++ ++ ++void fe_sw_init(void) ++{ ++#if defined (CONFIG_GIGAPHY) || defined (CONFIG_RAETH_ROUTER) || defined (CONFIG_100PHY) ++ unsigned int regValue = 0; ++#endif ++ ++ // Case1: RT288x/RT3883/MT7621 GE1 + GigaPhy ++#if defined (CONFIG_GE1_RGMII_AN) ++ enable_auto_negotiate(1); ++ if (isMarvellGigaPHY(1)) { ++#if defined (CONFIG_RT3883_FPGA) ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 9, ®Value); ++ regValue &= ~(3<<8); //turn off 1000Base-T Advertisement (9.9=1000Full, 9.8=1000Half) ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 9, regValue); ++ ++ printk("\n Reset MARVELL phy\n"); ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 20, ®Value); ++ regValue |= 1<<7; //Add delay to RX_CLK for RXD Outputs ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 20, regValue); ++ ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 0, ®Value); ++ regValue |= 1<<15; //PHY Software Reset ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 0, regValue); ++#elif defined (CONFIG_MT7621_FPGA) || defined (CONFIG_MT7623_FPGA) ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 9, ®Value); ++ regValue &= ~(3<<8); //turn off 1000Base-T Advertisement (9.9=1000Full, 9.8=1000Half) ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 9, regValue); ++ ++ /*10Mbps, debug*/ ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 4, 0x461); ++ ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 0, ®Value); ++ regValue |= 1<<9; //restart AN ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 0, regValue); ++#endif ++ ++ } ++ if (isVtssGigaPHY(1)) { ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 31, 1); ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 28, ®Value); ++ printk("Vitesse phy skew: %x --> ", regValue); ++ regValue |= (0x3<<12); ++ regValue &= ~(0x3<<14); ++ printk("%x\n", regValue); ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 28, regValue); ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR, 31, 0); ++ } ++#if defined (CONFIG_RALINK_MT7621) ++ sysRegWrite(RALINK_ETH_SW_BASE+0x100, 0x21056300);//(P0, Auto mode) ++#endif ++#endif // CONFIG_GE1_RGMII_AN // ++ ++ // Case2: RT3883/MT7621 GE2 + GigaPhy ++#if defined (CONFIG_GE2_RGMII_AN) ++ enable_auto_negotiate(2); ++ if (isMarvellGigaPHY(2)) { ++#if defined (CONFIG_RT3883_FPGA) ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 9, ®Value); ++ regValue &= ~(3<<8); //turn off 1000Base-T Advertisement (9.9=1000Full, 9.8=1000Half) ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 9, regValue); ++ ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 20, ®Value); ++ regValue |= 1<<7; //Add delay to RX_CLK for RXD Outputs ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 20, regValue); ++ ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 0, ®Value); ++ regValue |= 1<<15; //PHY Software Reset ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 0, regValue); ++#elif defined (CONFIG_MT7621_FPGA) || defined (CONFIG_MT7623_FPGA) ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 9, ®Value); ++ regValue &= ~(3<<8); //turn off 1000Base-T Advertisement (9.9=1000Full, 9.8=1000Half) ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 9, regValue); ++ ++ /*10Mbps, debug*/ ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 4, 0x461); ++ ++ ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 0, ®Value); ++ regValue |= 1<<9; //restart AN ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 0, regValue); ++#endif ++ ++ } ++ if (isVtssGigaPHY(2)) { ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 31, 1); ++ mii_mgr_read(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 28, ®Value); ++ printk("Vitesse phy skew: %x --> ", regValue); ++ regValue |= (0x3<<12); ++ regValue &= ~(0x3<<14); ++ printk("%x\n", regValue); ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 28, regValue); ++ mii_mgr_write(CONFIG_MAC_TO_GIGAPHY_MODE_ADDR2, 31, 0); ++ } ++#if defined (CONFIG_RALINK_MT7621) ++ //RGMII2=Normal mode ++ *(volatile u_long *)(RALINK_SYSCTL_BASE + 0x60) &= ~(0x1 << 15); ++ //GMAC2= RGMII mode ++ *(volatile u_long *)(SYSCFG1) &= ~(0x3 << 14); ++ ++ sysRegWrite(RALINK_ETH_SW_BASE+0x200, 0x21056300);//(P1, Auto mode) ++#endif ++#endif // CONFIG_GE2_RGMII_AN // ++ ++ // Case3: RT305x/RT335x/RT6855/RT6855A/MT7620 + EmbeddedSW ++#if defined (CONFIG_RT_3052_ESW) && !defined(CONFIG_RALINK_MT7621) && !defined(CONFIG_ARCH_MT7623) ++#if defined (CONFIG_RALINK_RT6855) || defined(CONFIG_RALINK_MT7620) ++ rt_gsw_init(); ++#elif defined(CONFIG_RALINK_RT6855A) ++ rt6855A_gsw_init(); ++#else ++ rt305x_esw_init(); ++#endif ++#endif ++ // Case4: RT288x/RT388x/MT7621 GE1 + Internal GigaSW ++#if defined (CONFIG_GE1_RGMII_FORCE_1000) || defined (CONFIG_GE1_TRGMII_FORCE_1200) || defined (CONFIG_GE1_TRGMII_FORCE_2000) || defined (CONFIG_GE1_TRGMII_FORCE_2600) ++#if defined (CONFIG_RALINK_MT7621) ++ setup_internal_gsw(); ++ /*MT7530 Init*/ ++#elif defined (CONFIG_ARCH_MT7623) ++#if defined (CONFIG_GE1_TRGMII_FORCE_2000) || defined (CONFIG_GE1_TRGMII_FORCE_2600) ++ *(volatile u_long *)(0xfb00002c) |= (1<<11); ++#else ++ *(volatile u_long *)(0xfb00002c) &= ~(1<<11); ++#endif ++ setup_internal_gsw(); ++ trgmii_calibration_7623(); ++ trgmii_calibration_7530(); ++ //*(volatile u_long *)(0xfb110300) |= (0x1f << 24); //Just only for 312.5/325MHz ++ *(volatile u_long *)(0xfb110340) = 0x00020000; ++ *(volatile u_long *)(0xfb110304) &= 0x3fffffff; // RX clock gating in MT7623 ++ *(volatile u_long *)(0xfb110300) |= 0x80000000; // Assert RX reset in MT7623 ++ *(volatile u_long *)(0xfb110300 ) &= 0x7fffffff; // Release RX reset in MT7623 ++ *(volatile u_long *)(0xfb110300 +0x04) |= 0xC0000000; // Disable RX clock gating in MT7623 ++/*GE1@125MHz(RGMII mode) TX delay adjustment*/ ++#if defined (CONFIG_GE1_RGMII_FORCE_1000) ++ *(volatile u_long *)(0xfb110350) = 0x55; ++ *(volatile u_long *)(0xfb110358) = 0x55; ++ *(volatile u_long *)(0xfb110360) = 0x55; ++ *(volatile u_long *)(0xfb110368) = 0x55; ++ *(volatile u_long *)(0xfb110370) = 0x55; ++ *(volatile u_long *)(0xfb110378) = 0x855; ++#endif ++ ++ ++#elif defined (CONFIG_MT7623_FPGA) /* Nelson: remove for bring up, should be added!!! */ ++ setup_fpga_gsw(); ++#else ++ sysRegWrite(MDIO_CFG, INIT_VALUE_OF_FORCE_1000_FD); ++#endif ++#endif ++ ++ // Case5: RT388x/MT7621 GE2 + GigaSW ++#if defined (CONFIG_GE2_RGMII_FORCE_1000) ++#if defined (CONFIG_RALINK_MT7621) ++ setup_external_gsw(); ++#else ++ sysRegWrite(MDIO_CFG2, INIT_VALUE_OF_FORCE_1000_FD); ++#endif ++#endif ++ ++ // Case6: RT288x GE1 /RT388x,MT7621 GE1/GE2 + (10/100 Switch or 100PHY) ++#if defined (CONFIG_RAETH_ROUTER) || defined (CONFIG_100PHY) ++ ++ //set GMAC to MII or RvMII mode ++#if defined (CONFIG_RALINK_RT3883) ++ regValue = sysRegRead(SYSCFG1); ++#if defined (CONFIG_GE1_MII_FORCE_100) || defined (CONFIG_GE1_MII_AN) ++ regValue &= ~(0x3 << 12); ++ regValue |= 0x1 << 12; // GE1 MII Mode ++#elif defined (CONFIG_GE1_RVMII_FORCE_100) ++ regValue &= ~(0x3 << 12); ++ regValue |= 0x2 << 12; // GE1 RvMII Mode ++#endif ++ ++#if defined (CONFIG_GE2_MII_FORCE_100) || defined (CONFIG_GE2_MII_AN) ++ regValue &= ~(0x3 << 14); ++ regValue |= 0x1 << 14; // GE2 MII Mode ++#elif defined (CONFIG_GE2_RVMII_FORCE_100) ++ regValue &= ~(0x3 << 14); ++ regValue |= 0x2 << 14; // GE2 RvMII Mode ++#endif ++ sysRegWrite(SYSCFG1, regValue); ++#endif // CONFIG_RALINK_RT3883 // ++ ++#elif defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++ ++#if defined (CONFIG_GE1_MII_FORCE_100) ++ sysRegWrite(RALINK_ETH_SW_BASE+0x100, 0x5e337);//(P0, Force mode, Link Up, 100Mbps, Full-Duplex, FC ON) ++#endif ++#if defined (CONFIG_GE2_MII_FORCE_100) ++ sysRegWrite(RALINK_ETH_SW_BASE+0x200, 0x5e337);//(P1, Force mode, Link Up, 100Mbps, Full-Duplex, FC ON) ++#endif ++#if defined (CONFIG_GE1_MII_AN) || defined (CONFIG_GE1_RGMII_AN) ++ enable_auto_negotiate(1); ++#if defined (CONFIG_RALINK_MT7621) ++ sysRegWrite(RALINK_ETH_SW_BASE+0x100, 0x21056300);//(P0, Auto mode) ++#endif ++#endif ++#if defined (CONFIG_GE2_MII_AN) || defined (CONFIG_GE1_RGMII_AN) ++ enable_auto_negotiate(2); ++#if defined (CONFIG_RALINK_MT7621) ++ sysRegWrite(RALINK_ETH_SW_BASE+0x200, 0x21056300);//(P1, Auto mode) ++#endif ++#endif ++ ++#else ++#if defined (CONFIG_GE1_MII_FORCE_100) ++#if defined (CONFIG_RALINK_MT7621) ++#else ++ sysRegWrite(MDIO_CFG, INIT_VALUE_OF_FORCE_100_FD); ++#endif ++#endif ++#if defined (CONFIG_GE2_MII_FORCE_100) ++#if defined (CONFIG_RALINK_MT7621) ++#else ++ sysRegWrite(MDIO_CFG2, INIT_VALUE_OF_FORCE_100_FD); ++#endif ++#endif ++ //add switch configuration here for other switch chips. ++#if defined (CONFIG_GE1_MII_FORCE_100) || defined (CONFIG_GE2_MII_FORCE_100) ++ // IC+ 175x: force IC+ switch cpu port is 100/FD ++ mii_mgr_write(29, 22, 0x8420); ++#endif ++ ++ ++#endif // defined (CONFIG_RAETH_ROUTER) || defined (CONFIG_100PHY) // ++ ++} ++ ++ ++/** ++ * ra2882eth_cleanup_module - Module Exit code ++ * ++ * Cmd 'rmmod' will invode the routine to exit the module ++ * ++ */ ++#if 0 ++ void ra2882eth_cleanup_module(void) ++{ ++ struct net_device *dev = dev_raether; ++ END_DEVICE *ei_local; ++ ++ ei_local = netdev_priv(dev); ++ ++#ifdef CONFIG_PSEUDO_SUPPORT ++ unregister_netdev(ei_local->PseudoDev); ++ free_netdev(ei_local->PseudoDev); ++#endif ++ unregister_netdev(dev); ++ RAETH_PRINT("Free ei_local and unregister netdev...\n"); ++ ++ free_netdev(dev); ++ debug_proc_exit(); ++#ifdef CONFIG_RAETH_NETLINK ++ csr_netlink_end(); ++#endif ++} ++#endif ++EXPORT_SYMBOL(set_fe_dma_glo_cfg); ++//module_init(ra2882eth_init); ++//module_exit(ra2882eth_cleanup_module); ++ ++const struct of_device_id of_fe_match[] = { ++ { .compatible = "mediatek,mt7623-net", }, ++ {}, ++}; ++ ++MODULE_DEVICE_TABLE(of, of_fe_match); ++ ++static struct platform_driver fe_driver = { ++ .probe = fe_probe, ++// .remove = ra2882eth_cleanup_module, ++ .driver = { ++ .name = "ralink_soc_eth", ++ .owner = THIS_MODULE, ++ .of_match_table = of_fe_match, ++ }, ++}; ++ ++static int __init init_rtfe(void) ++{ ++ int ret; ++ ret = platform_driver_register(&fe_driver); ++ return ret; ++} ++ ++static void __exit exit_rtfe(void) ++{ ++ platform_driver_unregister(&fe_driver); ++} ++ ++module_init(init_rtfe); ++module_exit(exit_rtfe); ++ ++ ++MODULE_LICENSE("GPL"); +diff --git a/drivers/net/ethernet/raeth/raether.h b/drivers/net/ethernet/raeth/raether.h +new file mode 100644 +index 0000000..7a97109 +--- /dev/null ++++ b/drivers/net/ethernet/raeth/raether.h +@@ -0,0 +1,126 @@ ++#ifndef RA2882ETHEND_H ++#define RA2882ETHEND_H ++ ++#ifdef DSP_VIA_NONCACHEABLE ++#define ESRAM_BASE 0xa0800000 /* 0x0080-0000 ~ 0x00807FFF */ ++#else ++#define ESRAM_BASE 0x80800000 /* 0x0080-0000 ~ 0x00807FFF */ ++#endif ++ ++#define RX_RING_BASE ((int)(ESRAM_BASE + 0x7000)) ++#define TX_RING_BASE ((int)(ESRAM_BASE + 0x7800)) ++ ++#if defined(CONFIG_RALINK_RT2880) ++#define NUM_TX_RINGS 1 ++#else ++#define NUM_TX_RINGS 4 ++#endif ++#ifdef MEMORY_OPTIMIZATION ++#ifdef CONFIG_RAETH_ROUTER ++#define NUM_RX_DESC 32 //128 ++#define NUM_TX_DESC 32 //128 ++#elif CONFIG_RT_3052_ESW ++#define NUM_RX_DESC 16 //64 ++#define NUM_TX_DESC 16 //64 ++#else ++#define NUM_RX_DESC 32 //128 ++#define NUM_TX_DESC 32 //128 ++#endif ++//#define NUM_RX_MAX_PROCESS 32 ++#define NUM_RX_MAX_PROCESS 32 ++#else ++#if defined (CONFIG_RAETH_ROUTER) ++#define NUM_RX_DESC 256 ++#define NUM_TX_DESC 256 ++#elif defined (CONFIG_RT_3052_ESW) ++#if defined (CONFIG_RALINK_MT7621) ++#define NUM_RX_DESC 512 ++#define NUM_QRX_DESC 16 ++#define NUM_TX_DESC 512 ++#else ++#define NUM_RX_DESC 256 ++#define NUM_QRX_DESC NUM_RX_DESC ++#define NUM_TX_DESC 256 ++#endif ++#else ++#define NUM_RX_DESC 256 ++#define NUM_QRX_DESC NUM_RX_DESC ++#define NUM_TX_DESC 256 ++#endif ++#if defined(CONFIG_RALINK_RT3883) || defined(CONFIG_RALINK_MT7620) ++#define NUM_RX_MAX_PROCESS 2 ++#else ++#define NUM_RX_MAX_PROCESS 16 ++#endif ++#endif ++#define NUM_LRO_RX_DESC 16 ++ ++#if defined (CONFIG_SUPPORT_OPENWRT) ++#define DEV_NAME "eth0" ++#define DEV2_NAME "eth1" ++#else ++#define DEV_NAME "eth2" ++#define DEV2_NAME "eth3" ++#endif ++ ++#if defined (CONFIG_RALINK_RT6855A) || defined (CONFIG_RALINK_MT7621) ++#define GMAC0_OFFSET 0xE000 ++#define GMAC2_OFFSET 0xE006 ++#else ++#define GMAC0_OFFSET 0x28 ++#define GMAC2_OFFSET 0x22 ++#endif ++ ++#if defined(CONFIG_RALINK_RT6855A) ++#define IRQ_ENET0 22 ++#elif defined(CONFIG_ARCH_MT7623) ++#define IRQ_ENET0 232 ++#else ++#define IRQ_ENET0 3 /* hardware interrupt #3, defined in RT2880 Soc Design Spec Rev 0.03, pp43 */ ++#endif ++ ++#if defined (CONFIG_RAETH_HW_LRO) ++#define HW_LRO_TIMER_UNIT 1 ++#define HW_LRO_REFRESH_TIME 50000 ++#define HW_LRO_MAX_AGG_CNT 64 ++#define HW_LRO_AGG_DELTA 1 ++#if defined(CONFIG_RAETH_PDMA_DVT) ++#define MAX_LRO_RX_LENGTH 10240 ++#else ++#define MAX_LRO_RX_LENGTH (PAGE_SIZE - SKB_DATA_ALIGN(NET_SKB_PAD + sizeof(struct skb_shared_info))) ++#endif ++#define HW_LRO_AGG_TIME 10 /* 200us */ ++#define HW_LRO_AGE_TIME 50 ++#define HW_LRO_BW_THRE 3000 ++#define HW_LRO_PKT_INT_ALPHA 100 ++#endif /* CONFIG_RAETH_HW_LRO */ ++#define FE_INT_STATUS_REG (*(volatile unsigned long *)(FE_INT_STATUS)) ++#define FE_INT_STATUS_CLEAN(reg) (*(volatile unsigned long *)(FE_INT_STATUS)) = reg ++ ++//#define RAETH_DEBUG ++#ifdef RAETH_DEBUG ++#define RAETH_PRINT(fmt, args...) printk(KERN_INFO fmt, ## args) ++#else ++#define RAETH_PRINT(fmt, args...) { } ++#endif ++ ++struct net_device_stats *ra_get_stats(struct net_device *dev); ++ ++void ei_tx_timeout(struct net_device *dev); ++int rather_probe(struct net_device *dev); ++int ei_open(struct net_device *dev); ++int ei_close(struct net_device *dev); ++ ++int ra2882eth_init(void); ++void ra2882eth_cleanup_module(void); ++ ++void ei_xmit_housekeeping(unsigned long data); ++ ++u32 mii_mgr_read(u32 phy_addr, u32 phy_register, u32 *read_data); ++u32 mii_mgr_write(u32 phy_addr, u32 phy_register, u32 write_data); ++u32 mii_mgr_cl45_set_address(u32 port_num, u32 dev_addr, u32 reg_addr); ++u32 mii_mgr_read_cl45(u32 port_num, u32 dev_addr, u32 reg_addr, u32 *read_data); ++u32 mii_mgr_write_cl45(u32 port_num, u32 dev_addr, u32 reg_addr, u32 write_data); ++void fe_sw_init(void); ++ ++#endif +diff --git a/drivers/net/ethernet/raeth/raether_hwlro.c b/drivers/net/ethernet/raeth/raether_hwlro.c +new file mode 100755 +index 0000000..5fc4f36 +--- /dev/null ++++ b/drivers/net/ethernet/raeth/raether_hwlro.c +@@ -0,0 +1,347 @@ ++#include <linux/module.h> ++#include <linux/version.h> ++#include <linux/kernel.h> ++#include <linux/types.h> ++#include <linux/pci.h> ++#include <linux/init.h> ++#include <linux/skbuff.h> ++#include <linux/if_vlan.h> ++#include <linux/if_ether.h> ++#include <linux/fs.h> ++#include <asm/uaccess.h> ++#include <asm/rt2880/surfboardint.h> ++#include <linux/delay.h> ++#include <linux/sched.h> ++#include <asm/rt2880/rt_mmap.h> ++#include "ra2882ethreg.h" ++#include "raether.h" ++#include "ra_mac.h" ++#include "ra_ioctl.h" ++#include "ra_rfrw.h" ++ ++#if defined(CONFIG_RAETH_HW_LRO_FORCE) ++int set_fe_lro_ring1_cfg(struct net_device *dev) ++{ ++ unsigned int ip; ++ ++ netdev_printk(KERN_CRIT, dev, "set_fe_lro_ring1_cfg()\n"); ++ ++ /* 1. Set RX ring mode to force port */ ++ SET_PDMA_RXRING_MODE(ADMA_RX_RING1, PDMA_RX_FORCE_PORT); ++ ++ /* 2. Configure lro ring */ ++ /* 2.1 set src/destination TCP ports */ ++ SET_PDMA_RXRING_TCP_SRC_PORT(ADMA_RX_RING1, 1122); ++ SET_PDMA_RXRING_TCP_DEST_PORT(ADMA_RX_RING1, 3344); ++ /* 2.2 set src/destination IPs */ ++ str_to_ip(&ip, "10.10.10.3"); ++ sysRegWrite(LRO_RX_RING1_SIP_DW0, ip); ++ str_to_ip(&ip, "10.10.10.254"); ++ sysRegWrite(LRO_RX_RING1_DIP_DW0, ip); ++ /* 2.3 IPv4 force port mode */ ++ SET_PDMA_RXRING_IPV4_FORCE_MODE(ADMA_RX_RING1, 1); ++ /* 2.4 IPv6 force port mode */ ++ SET_PDMA_RXRING_IPV6_FORCE_MODE(ADMA_RX_RING1, 1); ++ ++ /* 3. Set Age timer: 10 msec. */ ++ SET_PDMA_RXRING_AGE_TIME(ADMA_RX_RING1, HW_LRO_AGE_TIME); ++ ++ /* 4. Valid LRO ring */ ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING1, 1); ++ ++ return 0; ++} ++ ++int set_fe_lro_ring2_cfg(struct net_device *dev) ++{ ++ unsigned int ip; ++ ++ netdev_printk(KERN_CRIT, dev, "set_fe_lro_ring2_cfg()\n"); ++ ++ /* 1. Set RX ring mode to force port */ ++ SET_PDMA_RXRING2_MODE(PDMA_RX_FORCE_PORT); ++ ++ /* 2. Configure lro ring */ ++ /* 2.1 set src/destination TCP ports */ ++ SET_PDMA_RXRING_TCP_SRC_PORT(ADMA_RX_RING2, 5566); ++ SET_PDMA_RXRING_TCP_DEST_PORT(ADMA_RX_RING2, 7788); ++ /* 2.2 set src/destination IPs */ ++ str_to_ip(&ip, "10.10.10.3"); ++ sysRegWrite(LRO_RX_RING2_SIP_DW0, ip); ++ str_to_ip(&ip, "10.10.10.254"); ++ sysRegWrite(LRO_RX_RING2_DIP_DW0, ip); ++ /* 2.3 IPv4 force port mode */ ++ SET_PDMA_RXRING_IPV4_FORCE_MODE(ADMA_RX_RING2, 1); ++ /* 2.4 IPv6 force port mode */ ++ SET_PDMA_RXRING_IPV6_FORCE_MODE(ADMA_RX_RING2, 1); ++ ++ /* 3. Set Age timer: 10 msec. */ ++ SET_PDMA_RXRING_AGE_TIME(ADMA_RX_RING2, HW_LRO_AGE_TIME); ++ ++ /* 4. Valid LRO ring */ ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING2, 1); ++ ++ return 0; ++} ++ ++int set_fe_lro_ring3_cfg(struct net_device *dev) ++{ ++ unsigned int ip; ++ ++ netdev_printk(KERN_CRIT, dev, "set_fe_lro_ring3_cfg()\n"); ++ ++ /* 1. Set RX ring mode to force port */ ++ SET_PDMA_RXRING3_MODE(PDMA_RX_FORCE_PORT); ++ ++ /* 2. Configure lro ring */ ++ /* 2.1 set src/destination TCP ports */ ++ SET_PDMA_RXRING_TCP_SRC_PORT(ADMA_RX_RING3, 9900); ++ SET_PDMA_RXRING_TCP_DEST_PORT(ADMA_RX_RING3, 99); ++ /* 2.2 set src/destination IPs */ ++ str_to_ip(&ip, "10.10.10.3"); ++ sysRegWrite(LRO_RX_RING3_SIP_DW0, ip); ++ str_to_ip(&ip, "10.10.10.254"); ++ sysRegWrite(LRO_RX_RING3_DIP_DW0, ip); ++ /* 2.3 IPv4 force port mode */ ++ SET_PDMA_RXRING_IPV4_FORCE_MODE(ADMA_RX_RING3, 1); ++ /* 2.4 IPv6 force port mode */ ++ SET_PDMA_RXRING_IPV6_FORCE_MODE(ADMA_RX_RING3, 1); ++ ++ /* 3. Set Age timer: 10 msec. */ ++ SET_PDMA_RXRING_AGE_TIME(ADMA_RX_RING3, HW_LRO_AGE_TIME); ++ ++ /* 4. Valid LRO ring */ ++ SET_PDMA_RXRING3_VALID(1); ++ ++ return 0; ++} ++ ++int set_fe_lro_glo_cfg(struct net_device *dev) ++{ ++ unsigned int regVal = 0; ++ ++ netdev_printk(KERN_CRIT, dev, "set_fe_lro_glo_cfg()\n"); ++ ++ /* 1 Set max AGG timer: 10 msec. */ ++ SET_PDMA_LRO_MAX_AGG_TIME(HW_LRO_AGG_TIME); ++ ++ /* 2. Set max LRO agg count */ ++ SET_PDMA_LRO_MAX_AGG_CNT(HW_LRO_MAX_AGG_CNT); ++ ++ /* PDMA prefetch enable setting */ ++ SET_PDMA_LRO_RXD_PREFETCH_EN(0x3); ++ ++ /* 2.1 IPv4 checksum update enable */ ++ SET_PDMA_LRO_IPV4_CSUM_UPDATE_EN(1); ++ ++ /* 3. Polling relinguish */ ++ while (sysRegRead(ADMA_LRO_CTRL_DW0) & PDMA_LRO_RELINGUISH) ++ ; ++ ++ /* 4. Enable LRO */ ++ regVal = sysRegRead(ADMA_LRO_CTRL_DW0); ++ regVal |= PDMA_LRO_EN; ++ sysRegWrite(ADMA_LRO_CTRL_DW0, regVal); ++ ++ return 0; ++} ++#else ++int set_fe_lro_auto_cfg(struct net_device *dev) ++{ ++ unsigned int regVal = 0; ++ unsigned int ip; ++ ++ netdev_printk(KERN_CRIT, dev, "set_fe_lro_auto_cfg()\n"); ++ ++ /* 1.1 Set my IP_1 */ ++ str_to_ip(&ip, "10.10.10.254"); ++ sysRegWrite(LRO_RX_RING0_DIP_DW0, ip); ++ sysRegWrite(LRO_RX_RING0_DIP_DW1, 0); ++ sysRegWrite(LRO_RX_RING0_DIP_DW2, 0); ++ sysRegWrite(LRO_RX_RING0_DIP_DW3, 0); ++ SET_PDMA_RXRING_MYIP_VALID(ADMA_RX_RING0, 1); ++ ++ /* 1.2 Set my IP_2 */ ++ str_to_ip(&ip, "10.10.20.254"); ++ sysRegWrite(LRO_RX_RING1_DIP_DW0, ip); ++ sysRegWrite(LRO_RX_RING1_DIP_DW1, 0); ++ sysRegWrite(LRO_RX_RING1_DIP_DW2, 0); ++ sysRegWrite(LRO_RX_RING1_DIP_DW3, 0); ++ SET_PDMA_RXRING_MYIP_VALID(ADMA_RX_RING1, 1); ++ ++ /* 1.3 Set my IP_3 */ ++ sysRegWrite(LRO_RX_RING2_DIP_DW3, 0x20010238); ++ sysRegWrite(LRO_RX_RING2_DIP_DW2, 0x08000000); ++ sysRegWrite(LRO_RX_RING2_DIP_DW1, 0x00000000); ++ sysRegWrite(LRO_RX_RING2_DIP_DW0, 0x00000254); ++ SET_PDMA_RXRING_MYIP_VALID(ADMA_RX_RING2, 1); ++ ++ /* 1.4 Set my IP_4 */ ++ sysRegWrite(LRO_RX_RING3_DIP_DW3, 0x20010238); ++ sysRegWrite(LRO_RX_RING3_DIP_DW2, 0x08010000); ++ sysRegWrite(LRO_RX_RING3_DIP_DW1, 0x00000000); ++ sysRegWrite(LRO_RX_RING3_DIP_DW0, 0x00000254); ++ SET_PDMA_RXRING_MYIP_VALID(ADMA_RX_RING3, 1); ++ ++ /* 2.1 Set RX ring1~3 to auto-learn modes */ ++ SET_PDMA_RXRING_MODE(ADMA_RX_RING1, PDMA_RX_AUTO_LEARN); ++ SET_PDMA_RXRING_MODE(ADMA_RX_RING2, PDMA_RX_AUTO_LEARN); ++ SET_PDMA_RXRING_MODE(ADMA_RX_RING3, PDMA_RX_AUTO_LEARN); ++ ++ /* 2.2 Valid LRO ring */ ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING0, 1); ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING1, 1); ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING2, 1); ++ SET_PDMA_RXRING_VALID(ADMA_RX_RING3, 1); ++ ++ /* 2.3 Set AGE timer */ ++ SET_PDMA_RXRING_AGE_TIME(ADMA_RX_RING1, HW_LRO_AGE_TIME); ++ SET_PDMA_RXRING_AGE_TIME(ADMA_RX_RING2, HW_LRO_AGE_TIME); ++ SET_PDMA_RXRING_AGE_TIME(ADMA_RX_RING3, HW_LRO_AGE_TIME); ++ ++ /* 2.4 Set max AGG timer */ ++ SET_PDMA_RXRING_AGG_TIME(ADMA_RX_RING1, HW_LRO_AGG_TIME); ++ SET_PDMA_RXRING_AGG_TIME(ADMA_RX_RING2, HW_LRO_AGG_TIME); ++ SET_PDMA_RXRING_AGG_TIME(ADMA_RX_RING3, HW_LRO_AGG_TIME); ++ ++ /* 2.5 Set max LRO agg count */ ++ SET_PDMA_RXRING_MAX_AGG_CNT(ADMA_RX_RING1, HW_LRO_MAX_AGG_CNT); ++ SET_PDMA_RXRING_MAX_AGG_CNT(ADMA_RX_RING2, HW_LRO_MAX_AGG_CNT); ++ SET_PDMA_RXRING_MAX_AGG_CNT(ADMA_RX_RING3, HW_LRO_MAX_AGG_CNT); ++ ++ /* 3.0 IPv6 LRO enable */ ++ SET_PDMA_LRO_IPV6_EN(1); ++ ++ /* 3.1 IPv4 checksum update enable */ ++ SET_PDMA_LRO_IPV4_CSUM_UPDATE_EN(1); ++ ++ /* 3.2 TCP push option check disable */ ++ //SET_PDMA_LRO_IPV4_CTRL_PUSH_EN(0); ++ ++ /* PDMA prefetch enable setting */ ++ SET_PDMA_LRO_RXD_PREFETCH_EN(0x3); ++ ++ /* 3.2 switch priority comparison to byte count mode */ ++/* SET_PDMA_LRO_ALT_SCORE_MODE(PDMA_LRO_ALT_BYTE_CNT_MODE); */ ++ SET_PDMA_LRO_ALT_SCORE_MODE(PDMA_LRO_ALT_PKT_CNT_MODE); ++ ++ /* 3.3 bandwidth threshold setting */ ++ SET_PDMA_LRO_BW_THRESHOLD(HW_LRO_BW_THRE); ++ ++ /* 3.4 auto-learn score delta setting */ ++ sysRegWrite(LRO_ALT_SCORE_DELTA, 0); ++ ++ /* 3.5 Set ALT timer to 20us: (unit: 20us) */ ++ SET_PDMA_LRO_ALT_REFRESH_TIMER_UNIT(HW_LRO_TIMER_UNIT); ++ /* 3.6 Set ALT refresh timer to 1 sec. (unit: 20us) */ ++ SET_PDMA_LRO_ALT_REFRESH_TIMER(HW_LRO_REFRESH_TIME); ++ ++ /* 3.7 the least remaining room of SDL0 in RXD for lro aggregation */ ++ SET_PDMA_LRO_MIN_RXD_SDL(1522); ++ ++ /* 4. Polling relinguish */ ++ while (sysRegRead(ADMA_LRO_CTRL_DW0) & PDMA_LRO_RELINGUISH) ++ ; ++ ++ /* 5. Enable LRO */ ++ regVal = sysRegRead(ADMA_LRO_CTRL_DW0); ++ regVal |= PDMA_LRO_EN; ++ sysRegWrite(ADMA_LRO_CTRL_DW0, regVal); ++ ++ return 0; ++} ++#endif /* CONFIG_RAETH_HW_LRO_FORCE */ ++ ++int fe_hw_lro_init(struct net_device *dev) ++{ ++ int i; ++ END_DEVICE *ei_local = netdev_priv(dev); ++ ++ /* Initial RX Ring 3 */ ++ ei_local->rx_ring3 = ++ pci_alloc_consistent(NULL, NUM_LRO_RX_DESC * sizeof(struct PDMA_rxdesc), ++ &ei_local->phy_rx_ring3); ++ for (i = 0; i < NUM_LRO_RX_DESC; i++) { ++ memset(&ei_local->rx_ring3[i], 0, sizeof(struct PDMA_rxdesc)); ++ ei_local->rx_ring3[i].rxd_info2.DDONE_bit = 0; ++ ei_local->rx_ring3[i].rxd_info2.LS0 = 0; ++ ei_local->rx_ring3[i].rxd_info2.PLEN0 = ++ SET_ADMA_RX_LEN0(MAX_LRO_RX_LENGTH); ++ ei_local->rx_ring3[i].rxd_info2.PLEN1 = ++ SET_ADMA_RX_LEN1(MAX_LRO_RX_LENGTH >> 14); ++ ei_local->rx_ring3[i].rxd_info1.PDP0 = ++ dma_map_single(NULL, ei_local->netrx3_skbuf[i]->data, ++ MAX_LRO_RX_LENGTH, PCI_DMA_FROMDEVICE); ++ } ++ netdev_printk(KERN_CRIT, dev, ++ "\nphy_rx_ring3 = 0x%08x, rx_ring3 = 0x%p\n", ++ ei_local->phy_rx_ring3, ei_local->rx_ring3); ++ /* Initial RX Ring 2 */ ++ ei_local->rx_ring2 = ++ pci_alloc_consistent(NULL, NUM_LRO_RX_DESC * sizeof(struct PDMA_rxdesc), ++ &ei_local->phy_rx_ring2); ++ for (i = 0; i < NUM_LRO_RX_DESC; i++) { ++ memset(&ei_local->rx_ring2[i], 0, sizeof(struct PDMA_rxdesc)); ++ ei_local->rx_ring2[i].rxd_info2.DDONE_bit = 0; ++ ei_local->rx_ring2[i].rxd_info2.LS0 = 0; ++ ei_local->rx_ring2[i].rxd_info2.PLEN0 = ++ SET_ADMA_RX_LEN0(MAX_LRO_RX_LENGTH); ++ ei_local->rx_ring2[i].rxd_info2.PLEN1 = ++ SET_ADMA_RX_LEN1(MAX_LRO_RX_LENGTH >> 14); ++ ei_local->rx_ring2[i].rxd_info1.PDP0 = ++ dma_map_single(NULL, ei_local->netrx2_skbuf[i]->data, ++ MAX_LRO_RX_LENGTH, PCI_DMA_FROMDEVICE); ++ } ++ netdev_printk(KERN_CRIT, dev, ++ "\nphy_rx_ring2 = 0x%08x, rx_ring2 = 0x%p\n", ++ ei_local->phy_rx_ring2, ei_local->rx_ring2); ++ /* Initial RX Ring 1 */ ++ ei_local->rx_ring1 = ++ pci_alloc_consistent(NULL, NUM_LRO_RX_DESC * sizeof(struct PDMA_rxdesc), ++ &ei_local->phy_rx_ring1); ++ for (i = 0; i < NUM_LRO_RX_DESC; i++) { ++ memset(&ei_local->rx_ring1[i], 0, sizeof(struct PDMA_rxdesc)); ++ ei_local->rx_ring1[i].rxd_info2.DDONE_bit = 0; ++ ei_local->rx_ring1[i].rxd_info2.LS0 = 0; ++ ei_local->rx_ring1[i].rxd_info2.PLEN0 = ++ SET_ADMA_RX_LEN0(MAX_LRO_RX_LENGTH); ++ ei_local->rx_ring1[i].rxd_info2.PLEN1 = ++ SET_ADMA_RX_LEN1(MAX_LRO_RX_LENGTH >> 14); ++ ei_local->rx_ring1[i].rxd_info1.PDP0 = ++ dma_map_single(NULL, ei_local->netrx1_skbuf[i]->data, ++ MAX_LRO_RX_LENGTH, PCI_DMA_FROMDEVICE); ++ } ++ netdev_printk(KERN_CRIT, dev, ++ "\nphy_rx_ring1 = 0x%08x, rx_ring1 = 0x%p\n", ++ ei_local->phy_rx_ring1, ei_local->rx_ring1); ++ ++ sysRegWrite(RX_BASE_PTR3, phys_to_bus((u32) ei_local->phy_rx_ring3)); ++ sysRegWrite(RX_MAX_CNT3, cpu_to_le32((u32) NUM_LRO_RX_DESC)); ++ sysRegWrite(RX_CALC_IDX3, cpu_to_le32((u32) (NUM_LRO_RX_DESC - 1))); ++ sysRegWrite(PDMA_RST_CFG, PST_DRX_IDX3); ++ sysRegWrite(RX_BASE_PTR2, phys_to_bus((u32) ei_local->phy_rx_ring2)); ++ sysRegWrite(RX_MAX_CNT2, cpu_to_le32((u32) NUM_LRO_RX_DESC)); ++ sysRegWrite(RX_CALC_IDX2, cpu_to_le32((u32) (NUM_LRO_RX_DESC - 1))); ++ sysRegWrite(PDMA_RST_CFG, PST_DRX_IDX2); ++ sysRegWrite(RX_BASE_PTR1, phys_to_bus((u32) ei_local->phy_rx_ring1)); ++ sysRegWrite(RX_MAX_CNT1, cpu_to_le32((u32) NUM_LRO_RX_DESC)); ++ sysRegWrite(RX_CALC_IDX1, cpu_to_le32((u32) (NUM_LRO_RX_DESC - 1))); ++ sysRegWrite(PDMA_RST_CFG, PST_DRX_IDX1); ++ ++#if defined(CONFIG_RAETH_HW_LRO_FORCE) ++ set_fe_lro_ring1_cfg(dev); ++ set_fe_lro_ring2_cfg(dev); ++ set_fe_lro_ring3_cfg(dev); ++ set_fe_lro_glo_cfg(dev); ++#else ++ set_fe_lro_auto_cfg(dev); ++#endif /* CONFIG_RAETH_HW_LRO_FORCE */ ++ ++ /* HW LRO parameter settings */ ++ ei_local->hw_lro_alpha = HW_LRO_PKT_INT_ALPHA; ++ ei_local->hw_lro_fix_setting = 1; ++ ++ return 1; ++} ++EXPORT_SYMBOL(fe_hw_lro_init); ++ +diff --git a/drivers/net/ethernet/raeth/raether_pdma.c b/drivers/net/ethernet/raeth/raether_pdma.c +new file mode 100755 +index 0000000..4d47ee2 +--- /dev/null ++++ b/drivers/net/ethernet/raeth/raether_pdma.c +@@ -0,0 +1,1121 @@ ++#include <linux/module.h> ++#include <linux/version.h> ++#include <linux/kernel.h> ++#include <linux/types.h> ++#include <linux/pci.h> ++#include <linux/init.h> ++#include <linux/skbuff.h> ++#include <linux/if_vlan.h> ++#include <linux/if_ether.h> ++#include <linux/fs.h> ++#include <asm/uaccess.h> ++#include <asm/rt2880/surfboardint.h> ++#if defined (CONFIG_RAETH_TSO) ++#include <linux/tcp.h> ++#include <net/ipv6.h> ++#include <linux/ip.h> ++#include <net/ip.h> ++#include <net/tcp.h> ++#include <linux/in.h> ++#include <linux/ppp_defs.h> ++#include <linux/if_pppox.h> ++#endif ++#if defined (CONFIG_RAETH_LRO) ++#include <linux/inet_lro.h> ++#endif ++#include <linux/delay.h> ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++#include <linux/sched.h> ++#endif ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++#include <asm/rt2880/rt_mmap.h> ++#else ++#include <linux/libata-compat.h> ++#endif ++ ++#include "ra2882ethreg.h" ++#include "raether.h" ++#include "ra_mac.h" ++#include "ra_ioctl.h" ++#include "ra_rfrw.h" ++#ifdef CONFIG_RAETH_NETLINK ++#include "ra_netlink.h" ++#endif ++#if defined (CONFIG_RAETH_QOS) ++#include "ra_qos.h" ++#endif ++ ++#if defined (CONFIG_RA_HW_NAT) || defined (CONFIG_RA_HW_NAT_MODULE) ++#include "../../../net/nat/hw_nat/ra_nat.h" ++#endif ++#if defined(CONFIG_RAETH_PDMA_DVT) ++#include "dvt/raether_pdma_dvt.h" ++#endif /* CONFIG_RAETH_PDMA_DVT */ ++ ++#if !defined(CONFIG_RA_NAT_NONE) ++/* bruce+ ++ */ ++extern int (*ra_sw_nat_hook_rx)(struct sk_buff *skb); ++extern int (*ra_sw_nat_hook_tx)(struct sk_buff *skb, int gmac_no); ++#endif ++ ++#if defined(CONFIG_RA_CLASSIFIER)||defined(CONFIG_RA_CLASSIFIER_MODULE) ++/* Qwert+ ++ */ ++#include <asm/mipsregs.h> ++extern int (*ra_classifier_hook_tx)(struct sk_buff *skb, unsigned long cur_cycle); ++extern int (*ra_classifier_hook_rx)(struct sk_buff *skb, unsigned long cur_cycle); ++#endif /* CONFIG_RA_CLASSIFIER */ ++ ++#if defined (CONFIG_RALINK_RT3052_MP2) ++int32_t mcast_rx(struct sk_buff * skb); ++int32_t mcast_tx(struct sk_buff * skb); ++#endif ++ ++#if 0 ++#ifdef RA_MTD_RW_BY_NUM ++int ra_mtd_read(int num, loff_t from, size_t len, u_char *buf); ++#else ++int ra_mtd_read_nm(char *name, loff_t from, size_t len, u_char *buf); ++#endif ++#endif ++/* gmac driver feature set config */ ++#if defined (CONFIG_RAETH_NAPI) || defined (CONFIG_RAETH_QOS) ++#undef DELAY_INT ++#else ++#if defined (CONFIG_ARCH_MT7623) ++#undef DELAY_INT ++#else ++#define DELAY_INT 1 ++#endif ++#endif ++ ++//#define CONFIG_UNH_TEST ++/* end of config */ ++ ++#if defined (CONFIG_RAETH_JUMBOFRAME) ++#define MAX_RX_LENGTH 4096 ++#else ++#define MAX_RX_LENGTH 1536 ++#endif ++ ++extern struct net_device *dev_raether; ++ ++ ++#if defined (CONFIG_RAETH_MULTIPLE_RX_RING) ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++extern int rx_calc_idx1; ++#endif ++#endif ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++extern int rx_calc_idx0; ++static unsigned long tx_cpu_owner_idx0=0; ++#endif ++extern unsigned long tx_ring_full; ++ ++#if defined (CONFIG_ETHTOOL) /*&& defined (CONFIG_RAETH_ROUTER)*/ ++#include "ra_ethtool.h" ++extern struct ethtool_ops ra_ethtool_ops; ++#ifdef CONFIG_PSEUDO_SUPPORT ++extern struct ethtool_ops ra_virt_ethtool_ops; ++#endif // CONFIG_PSEUDO_SUPPORT // ++#endif // (CONFIG_ETHTOOL // ++ ++#ifdef CONFIG_RALINK_VISTA_BASIC ++int is_switch_175c = 1; ++#endif ++ ++#ifdef CONFIG_RAETH_PDMATX_QDMARX /* QDMA RX */ ++struct QDMA_txdesc *free_head = NULL; ++#endif ++ ++//#if defined (CONFIG_RAETH_LRO) ++#if 0 ++unsigned int lan_ip; ++struct lro_para_struct lro_para; ++int lro_flush_needed; ++extern char const *nvram_get(int index, char *name); ++#endif ++ ++#define KSEG1 0xa0000000 ++#define PHYS_TO_VIRT(x) ((void *)((x) | KSEG1)) ++#define VIRT_TO_PHYS(x) ((unsigned long)(x) & ~KSEG1) ++ ++extern void set_fe_dma_glo_cfg(void); ++ ++/* ++ * @brief cal txd number for a page ++ * ++ * @parm size ++ * ++ * @return frag_txd_num ++ */ ++ ++unsigned int cal_frag_txd_num(unsigned int size) ++{ ++ unsigned int frag_txd_num = 0; ++ if(size == 0) ++ return 0; ++ while(size > 0){ ++ if(size > MAX_TXD_LEN){ ++ frag_txd_num++; ++ size -= MAX_TXD_LEN; ++ }else{ ++ frag_txd_num++; ++ size = 0; ++ } ++ } ++ return frag_txd_num; ++ ++} ++ ++#ifdef CONFIG_RAETH_PDMATX_QDMARX /* QDMA RX */ ++bool fq_qdma_init(struct net_device *dev) ++{ ++ END_DEVICE* ei_local = netdev_priv(dev); ++ unsigned int phy_free_head; ++ unsigned int phy_free_tail; ++ unsigned int *free_page_head = NULL; ++ unsigned int phy_free_page_head; ++ int i; ++ ++ free_head = pci_alloc_consistent(NULL, NUM_QDMA_PAGE * sizeof(struct QDMA_txdesc), &phy_free_head); ++ if (unlikely(free_head == NULL)){ ++ printk(KERN_ERR "QDMA FQ decriptor not available...\n"); ++ return 0; ++ } ++ memset(free_head, 0x0, sizeof(struct QDMA_txdesc) * NUM_QDMA_PAGE); ++ ++ free_page_head = pci_alloc_consistent(NULL, NUM_QDMA_PAGE * QDMA_PAGE_SIZE, &phy_free_page_head); ++ if (unlikely(free_page_head == NULL)){ ++ printk(KERN_ERR "QDMA FQ page not available...\n"); ++ return 0; ++ } ++ for (i=0; i < NUM_QDMA_PAGE; i++) { ++ free_head[i].txd_info1.SDP = (phy_free_page_head + (i * QDMA_PAGE_SIZE)); ++ if(i < (NUM_QDMA_PAGE-1)){ ++ free_head[i].txd_info2.NDP = (phy_free_head + ((i+1) * sizeof(struct QDMA_txdesc))); ++ ++ ++#if 0 ++ printk("free_head_phy[%d] is 0x%x!!!\n",i, VIRT_TO_PHYS(&free_head[i]) ); ++ printk("free_head[%d] is 0x%x!!!\n",i, &free_head[i] ); ++ printk("free_head[%d].txd_info1.SDP is 0x%x!!!\n",i, free_head[i].txd_info1.SDP ); ++ printk("free_head[%d].txd_info2.NDP is 0x%x!!!\n",i, free_head[i].txd_info2.NDP ); ++#endif ++ } ++ free_head[i].txd_info3.SDL = QDMA_PAGE_SIZE; ++ ++ } ++ phy_free_tail = (phy_free_head + (u32)((NUM_QDMA_PAGE-1) * sizeof(struct QDMA_txdesc))); ++ ++ printk("phy_free_head is 0x%x!!!\n", phy_free_head); ++ printk("phy_free_tail_phy is 0x%x!!!\n", phy_free_tail); ++ sysRegWrite(QDMA_FQ_HEAD, (u32)phy_free_head); ++ sysRegWrite(QDMA_FQ_TAIL, (u32)phy_free_tail); ++ sysRegWrite(QDMA_FQ_CNT, ((NUM_TX_DESC << 16) | NUM_QDMA_PAGE)); ++ sysRegWrite(QDMA_FQ_BLEN, QDMA_PAGE_SIZE << 16); ++ ++ ei_local->free_head = free_head; ++ ei_local->phy_free_head = phy_free_head; ++ ei_local->free_page_head = free_page_head; ++ ei_local->phy_free_page_head = phy_free_page_head; ++ return 1; ++} ++#endif ++ ++int fe_dma_init(struct net_device *dev) ++{ ++ ++ int i; ++ unsigned int regVal; ++ END_DEVICE* ei_local = netdev_priv(dev); ++#if defined (CONFIG_RAETH_QOS) ++ int j; ++#endif ++ ++ while(1) ++ { ++ regVal = sysRegRead(PDMA_GLO_CFG); ++ if((regVal & RX_DMA_BUSY)) ++ { ++ printk("\n RX_DMA_BUSY !!! "); ++ continue; ++ } ++ if((regVal & TX_DMA_BUSY)) ++ { ++ printk("\n TX_DMA_BUSY !!! "); ++ continue; ++ } ++ break; ++ } ++ ++#if defined(CONFIG_RAETH_PDMA_DVT) ++ pdma_dvt_set_dma_mode(); ++#endif /* CONFIG_RAETH_PDMA_DVT */ ++ ++#if defined (CONFIG_RAETH_QOS) ++ for (i=0;i<NUM_TX_RINGS;i++){ ++ for (j=0;j<NUM_TX_DESC;j++){ ++ ei_local->skb_free[i][j]=0; ++ } ++ ei_local->free_idx[i]=0; ++ } ++ /* ++ * RT2880: 2 x TX_Ring, 1 x Rx_Ring ++ * RT2883: 4 x TX_Ring, 1 x Rx_Ring ++ * RT3883: 4 x TX_Ring, 1 x Rx_Ring ++ * RT3052: 4 x TX_Ring, 1 x Rx_Ring ++ */ ++ fe_tx_desc_init(dev, 0, 3, 1); ++ if (ei_local->tx_ring0 == NULL) { ++ printk("RAETH: tx ring0 allocation failed\n"); ++ return 0; ++ } ++ ++ fe_tx_desc_init(dev, 1, 3, 1); ++ if (ei_local->tx_ring1 == NULL) { ++ printk("RAETH: tx ring1 allocation failed\n"); ++ return 0; ++ } ++ ++ printk("\nphy_tx_ring0 = %08x, tx_ring0 = %p, size: %d bytes\n", ei_local->phy_tx_ring0, ei_local->tx_ring0, sizeof(struct PDMA_txdesc)); ++ ++ printk("\nphy_tx_ring1 = %08x, tx_ring1 = %p, size: %d bytes\n", ei_local->phy_tx_ring1, ei_local->tx_ring1, sizeof(struct PDMA_txdesc)); ++ ++#if ! defined (CONFIG_RALINK_RT2880) ++ fe_tx_desc_init(dev, 2, 3, 1); ++ if (ei_local->tx_ring2 == NULL) { ++ printk("RAETH: tx ring2 allocation failed\n"); ++ return 0; ++ } ++ ++ fe_tx_desc_init(dev, 3, 3, 1); ++ if (ei_local->tx_ring3 == NULL) { ++ printk("RAETH: tx ring3 allocation failed\n"); ++ return 0; ++ } ++ ++ printk("\nphy_tx_ring2 = %08x, tx_ring2 = %p, size: %d bytes\n", ei_local->phy_tx_ring2, ei_local->tx_ring2, sizeof(struct PDMA_txdesc)); ++ ++ printk("\nphy_tx_ring3 = %08x, tx_ring3 = %p, size: %d bytes\n", ei_local->phy_tx_ring3, ei_local->tx_ring3, sizeof(struct PDMA_txdesc)); ++ ++#endif // CONFIG_RALINK_RT2880 // ++#else ++ for (i=0;i<NUM_TX_DESC;i++){ ++ ei_local->skb_free[i]=0; ++ } ++ ei_local->free_idx =0; ++#if defined (CONFIG_MIPS) ++ ei_local->tx_ring0 = pci_alloc_consistent(NULL, NUM_TX_DESC * sizeof(struct PDMA_txdesc), &ei_local->phy_tx_ring0); ++#else ++ ei_local->tx_ring0 = dma_alloc_coherent(NULL, NUM_TX_DESC * sizeof(struct PDMA_txdesc), &ei_local->phy_tx_ring0, GFP_KERNEL); ++#endif ++ printk("\nphy_tx_ring = 0x%08x, tx_ring = 0x%p\n", ei_local->phy_tx_ring0, ei_local->tx_ring0); ++ ++ for (i=0; i < NUM_TX_DESC; i++) { ++ memset(&ei_local->tx_ring0[i],0,sizeof(struct PDMA_txdesc)); ++ ei_local->tx_ring0[i].txd_info2.LS0_bit = 1; ++ ei_local->tx_ring0[i].txd_info2.DDONE_bit = 1; ++ ++ } ++#endif // CONFIG_RAETH_QOS ++ ++#ifdef CONFIG_RAETH_PDMATX_QDMARX /* QDMA RX */ ++ ++ fq_qdma_init(dev); ++ ++ while(1) ++ { ++ regVal = sysRegRead(QDMA_GLO_CFG); ++ if((regVal & RX_DMA_BUSY)) ++ { ++ printk("\n RX_DMA_BUSY !!! "); ++ continue; ++ } ++ if((regVal & TX_DMA_BUSY)) ++ { ++ printk("\n TX_DMA_BUSY !!! "); ++ continue; ++ } ++ break; ++ } ++ ++ /* Initial RX Ring 0*/ ++ ++#ifdef CONFIG_32B_DESC ++ ei_local->qrx_ring = kmalloc(NUM_QRX_DESC * sizeof(struct PDMA_rxdesc), GFP_KERNEL); ++ ei_local->phy_qrx_ring = virt_to_phys(ei_local->qrx_ring); ++#else ++ ei_local->qrx_ring = pci_alloc_consistent(NULL, NUM_QRX_DESC * sizeof(struct PDMA_rxdesc), &ei_local->phy_qrx_ring); ++#endif ++ for (i = 0; i < NUM_QRX_DESC; i++) { ++ memset(&ei_local->qrx_ring[i],0,sizeof(struct PDMA_rxdesc)); ++ ei_local->qrx_ring[i].rxd_info2.DDONE_bit = 0; ++#if defined (CONFIG_RAETH_SCATTER_GATHER_RX_DMA) ++ ei_local->qrx_ring[i].rxd_info2.LS0 = 0; ++ ei_local->qrx_ring[i].rxd_info2.PLEN0 = MAX_RX_LENGTH; ++#else ++ ei_local->qrx_ring[i].rxd_info2.LS0 = 1; ++#endif ++ ei_local->qrx_ring[i].rxd_info1.PDP0 = dma_map_single(NULL, ei_local->netrx0_skbuf[i]->data, MAX_RX_LENGTH, PCI_DMA_FROMDEVICE); ++ } ++ printk("\nphy_qrx_ring = 0x%08x, qrx_ring = 0x%p\n",ei_local->phy_qrx_ring,ei_local->qrx_ring); ++ ++ regVal = sysRegRead(QDMA_GLO_CFG); ++ regVal &= 0x000000FF; ++ ++ sysRegWrite(QDMA_GLO_CFG, regVal); ++ regVal=sysRegRead(QDMA_GLO_CFG); ++ ++ /* Tell the adapter where the TX/RX rings are located. */ ++ ++ sysRegWrite(QRX_BASE_PTR_0, phys_to_bus((u32) ei_local->phy_qrx_ring)); ++ sysRegWrite(QRX_MAX_CNT_0, cpu_to_le32((u32) NUM_QRX_DESC)); ++ sysRegWrite(QRX_CRX_IDX_0, cpu_to_le32((u32) (NUM_QRX_DESC - 1))); ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ rx_calc_idx0 = rx_dma_owner_idx0 = sysRegRead(QRX_CRX_IDX_0); ++#endif ++ sysRegWrite(QDMA_RST_CFG, PST_DRX_IDX0); ++ ++ ei_local->rx_ring0 = ei_local->qrx_ring; ++ ++#else /* PDMA RX */ ++ ++ /* Initial RX Ring 0*/ ++#ifdef CONFIG_32B_DESC ++ ei_local->rx_ring0 = kmalloc(NUM_RX_DESC * sizeof(struct PDMA_rxdesc), GFP_KERNEL); ++ ei_local->phy_rx_ring0 = virt_to_phys(ei_local->rx_ring0); ++#else ++#if defined (CONFIG_MIPS) ++ ei_local->rx_ring0 = pci_alloc_consistent(NULL, NUM_RX_DESC * sizeof(struct PDMA_rxdesc), &ei_local->phy_rx_ring0); ++#else ++ ei_local->rx_ring0 = dma_alloc_coherent(NULL, NUM_RX_DESC * sizeof(struct PDMA_rxdesc), &ei_local->phy_rx_ring0, GFP_KERNEL); ++#endif ++#endif ++ for (i = 0; i < NUM_RX_DESC; i++) { ++ memset(&ei_local->rx_ring0[i],0,sizeof(struct PDMA_rxdesc)); ++ ei_local->rx_ring0[i].rxd_info2.DDONE_bit = 0; ++#if defined (CONFIG_RAETH_SCATTER_GATHER_RX_DMA) ++ ei_local->rx_ring0[i].rxd_info2.LS0 = 0; ++ ei_local->rx_ring0[i].rxd_info2.PLEN0 = MAX_RX_LENGTH; ++#else ++ ei_local->rx_ring0[i].rxd_info2.LS0 = 1; ++#endif ++ ei_local->rx_ring0[i].rxd_info1.PDP0 = dma_map_single(NULL, ei_local->netrx0_skbuf[i]->data, MAX_RX_LENGTH, PCI_DMA_FROMDEVICE); ++ } ++ printk("\nphy_rx_ring0 = 0x%08x, rx_ring0 = 0x%p\n",ei_local->phy_rx_ring0,ei_local->rx_ring0); ++ ++#if defined (CONFIG_RAETH_MULTIPLE_RX_RING) ++ /* Initial RX Ring 1*/ ++#ifdef CONFIG_32B_DESC ++ ei_local->rx_ring1 = kmalloc(NUM_RX_DESC * sizeof(struct PDMA_rxdesc), GFP_KERNEL); ++ ei_local->phy_rx_ring1 = virt_to_phys(ei_local->rx_ring1); ++#else ++#if defined (CONFIG_MIPS) ++ ei_local->rx_ring1 = pci_alloc_consistent(NULL, NUM_RX_DESC * sizeof(struct PDMA_rxdesc), &ei_local->phy_rx_ring1); ++#else ++ ei_local->rx_ring1 = dma_alloc_coherent(NULL, NUM_RX_DESC * sizeof(struct PDMA_rxdesc), &ei_local->phy_rx_ring1, GFP_KERNEL); ++ ++#endif ++#endif ++ for (i = 0; i < NUM_RX_DESC; i++) { ++ memset(&ei_local->rx_ring1[i],0,sizeof(struct PDMA_rxdesc)); ++ ei_local->rx_ring1[i].rxd_info2.DDONE_bit = 0; ++#if defined (CONFIG_RAETH_SCATTER_GATHER_RX_DMA) ++ ei_local->rx_ring1[i].rxd_info2.LS0 = 0; ++ ei_local->rx_ring1[i].rxd_info2.PLEN0 = MAX_RX_LENGTH; ++#else ++ ei_local->rx_ring1[i].rxd_info2.LS0 = 1; ++#endif ++ ei_local->rx_ring1[i].rxd_info1.PDP0 = dma_map_single(NULL, ei_local->netrx1_skbuf[i]->data, MAX_RX_LENGTH, PCI_DMA_FROMDEVICE); ++ } ++ printk("\nphy_rx_ring1 = 0x%08x, rx_ring1 = 0x%p\n",ei_local->phy_rx_ring1,ei_local->rx_ring1); ++#if defined(CONFIG_ARCH_MT7623) ++ /* Initial RX Ring 2*/ ++ ei_local->rx_ring2 = pci_alloc_consistent(NULL, NUM_RX_DESC * sizeof(struct PDMA_rxdesc), &ei_local->phy_rx_ring2); ++ for (i = 0; i < NUM_RX_DESC; i++) { ++ memset(&ei_local->rx_ring2[i],0,sizeof(struct PDMA_rxdesc)); ++ ei_local->rx_ring2[i].rxd_info2.DDONE_bit = 0; ++ ei_local->rx_ring2[i].rxd_info2.LS0 = 0; ++ ei_local->rx_ring2[i].rxd_info2.PLEN0 = SET_ADMA_RX_LEN0(MAX_RX_LENGTH); ++ ei_local->rx_ring2[i].rxd_info2.PLEN1 = SET_ADMA_RX_LEN1(MAX_RX_LENGTH >> 14); ++ ei_local->rx_ring2[i].rxd_info1.PDP0 = dma_map_single(NULL, ei_local->netrx2_skbuf[i]->data, MAX_RX_LENGTH, PCI_DMA_FROMDEVICE); ++ } ++ printk("\nphy_rx_ring2 = 0x%08x, rx_ring2 = 0x%p\n",ei_local->phy_rx_ring2,ei_local->rx_ring2); ++ /* Initial RX Ring 3*/ ++ ei_local->rx_ring3 = pci_alloc_consistent(NULL, NUM_RX_DESC * sizeof(struct PDMA_rxdesc), &ei_local->phy_rx_ring3); ++ for (i = 0; i < NUM_RX_DESC; i++) { ++ memset(&ei_local->rx_ring3[i],0,sizeof(struct PDMA_rxdesc)); ++ ei_local->rx_ring3[i].rxd_info2.DDONE_bit = 0; ++ ei_local->rx_ring3[i].rxd_info2.LS0 = 0; ++ ei_local->rx_ring3[i].rxd_info2.PLEN0 = SET_ADMA_RX_LEN0(MAX_RX_LENGTH); ++ ei_local->rx_ring3[i].rxd_info2.PLEN1 = SET_ADMA_RX_LEN1(MAX_RX_LENGTH >> 14); ++ ei_local->rx_ring3[i].rxd_info1.PDP0 = dma_map_single(NULL, ei_local->netrx3_skbuf[i]->data, MAX_RX_LENGTH, PCI_DMA_FROMDEVICE); ++ } ++ printk("\nphy_rx_ring3 = 0x%08x, rx_ring3 = 0x%p\n",ei_local->phy_rx_ring3,ei_local->rx_ring3); ++#endif /* CONFIG_ARCH_MT7623 */ ++#endif ++ ++#endif ++ ++ regVal = sysRegRead(PDMA_GLO_CFG); ++ regVal &= 0x000000FF; ++ sysRegWrite(PDMA_GLO_CFG, regVal); ++ regVal=sysRegRead(PDMA_GLO_CFG); ++ ++ /* Tell the adapter where the TX/RX rings are located. */ ++#if !defined (CONFIG_RAETH_QOS) ++ sysRegWrite(TX_BASE_PTR0, phys_to_bus((u32) ei_local->phy_tx_ring0)); ++ sysRegWrite(TX_MAX_CNT0, cpu_to_le32((u32) NUM_TX_DESC)); ++ sysRegWrite(TX_CTX_IDX0, 0); ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ tx_cpu_owner_idx0 = 0; ++#endif ++ sysRegWrite(PDMA_RST_CFG, PST_DTX_IDX0); ++#endif ++ ++#ifdef CONFIG_RAETH_PDMATX_QDMARX /* QDMA RX */ ++ sysRegWrite(QRX_BASE_PTR_0, phys_to_bus((u32) ei_local->phy_qrx_ring)); ++ sysRegWrite(QRX_MAX_CNT_0, cpu_to_le32((u32) NUM_QRX_DESC)); ++ sysRegWrite(QRX_CRX_IDX_0, cpu_to_le32((u32) (NUM_QRX_DESC - 1))); ++#else /* PDMA RX */ ++ sysRegWrite(RX_BASE_PTR0, phys_to_bus((u32) ei_local->phy_rx_ring0)); ++ sysRegWrite(RX_MAX_CNT0, cpu_to_le32((u32) NUM_RX_DESC)); ++ sysRegWrite(RX_CALC_IDX0, cpu_to_le32((u32) (NUM_RX_DESC - 1))); ++#endif ++ ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ rx_calc_idx0 = sysRegRead(RX_CALC_IDX0); ++#endif ++ sysRegWrite(PDMA_RST_CFG, PST_DRX_IDX0); ++#if defined (CONFIG_RAETH_MULTIPLE_RX_RING) ++ sysRegWrite(RX_BASE_PTR1, phys_to_bus((u32) ei_local->phy_rx_ring1)); ++ sysRegWrite(RX_MAX_CNT1, cpu_to_le32((u32) NUM_RX_DESC)); ++ sysRegWrite(RX_CALC_IDX1, cpu_to_le32((u32) (NUM_RX_DESC - 1))); ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ rx_calc_idx1 = sysRegRead(RX_CALC_IDX1); ++#endif ++ sysRegWrite(PDMA_RST_CFG, PST_DRX_IDX1); ++#if defined(CONFIG_ARCH_MT7623) ++ sysRegWrite(RX_BASE_PTR2, phys_to_bus((u32) ei_local->phy_rx_ring2)); ++ sysRegWrite(RX_MAX_CNT2, cpu_to_le32((u32) NUM_RX_DESC)); ++ sysRegWrite(RX_CALC_IDX2, cpu_to_le32((u32) (NUM_RX_DESC - 1))); ++ sysRegWrite(PDMA_RST_CFG, PST_DRX_IDX2); ++ sysRegWrite(RX_BASE_PTR3, phys_to_bus((u32) ei_local->phy_rx_ring3)); ++ sysRegWrite(RX_MAX_CNT3, cpu_to_le32((u32) NUM_RX_DESC)); ++ sysRegWrite(RX_CALC_IDX3, cpu_to_le32((u32) (NUM_RX_DESC - 1))); ++ sysRegWrite(PDMA_RST_CFG, PST_DRX_IDX3); ++#endif /* CONFIG_ARCH_MT7623 */ ++#endif ++#if defined (CONFIG_RALINK_RT6855A) ++ regVal = sysRegRead(RX_DRX_IDX0); ++ regVal = (regVal == 0)? (NUM_RX_DESC - 1) : (regVal - 1); ++ sysRegWrite(RX_CALC_IDX0, cpu_to_le32(regVal)); ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ rx_calc_idx0 = sysRegRead(RX_CALC_IDX0); ++#endif ++ regVal = sysRegRead(TX_DTX_IDX0); ++ sysRegWrite(TX_CTX_IDX0, cpu_to_le32(regVal)); ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ tx_cpu_owner_idx0 = regVal; ++#endif ++ ei_local->free_idx = regVal; ++#endif ++ ++#if defined (CONFIG_RAETH_QOS) ++ set_scheduler_weight(); ++ set_schedule_pause_condition(); ++ set_output_shaper(); ++#endif ++ ++ set_fe_dma_glo_cfg(); ++ ++ return 1; ++} ++ ++inline int rt2880_eth_send(struct net_device* dev, struct sk_buff *skb, int gmac_no) ++{ ++ unsigned int length=skb->len; ++ END_DEVICE* ei_local = netdev_priv(dev); ++#ifndef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ unsigned long tx_cpu_owner_idx0 = sysRegRead(TX_CTX_IDX0); ++#endif ++#if defined (CONFIG_RAETH_TSO) ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ unsigned long ctx_idx_start_addr = tx_cpu_owner_idx0; ++#endif ++ struct iphdr *iph = NULL; ++ struct tcphdr *th = NULL; ++ struct skb_frag_struct *frag; ++ unsigned int nr_frags = skb_shinfo(skb)->nr_frags; ++ int i=0; ++ unsigned int len, size, offset, frag_txd_num, skb_txd_num ; ++#endif // CONFIG_RAETH_TSO // ++ ++#if defined (CONFIG_RAETH_TSOV6) ++ struct ipv6hdr *ip6h = NULL; ++#endif ++ ++#ifdef CONFIG_PSEUDO_SUPPORT ++ PSEUDO_ADAPTER *pAd; ++#endif ++ ++ while(ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info2.DDONE_bit == 0) ++ { ++#ifdef CONFIG_PSEUDO_SUPPORT ++ if (gmac_no == 2) { ++ if (ei_local->PseudoDev != NULL) { ++ pAd = netdev_priv(ei_local->PseudoDev); ++ pAd->stat.tx_errors++; ++ } ++ } else ++#endif ++ ei_local->stat.tx_errors++; ++ } ++ ++#if !defined (CONFIG_RAETH_TSO) ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info1.SDP0 = virt_to_phys(skb->data); ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info2.SDL0 = length; ++#if defined (CONFIG_RALINK_MT7620) ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.FP_BMAP = 0; ++#elif defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++ if (gmac_no == 1) { ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.FPORT = 1; ++ }else { ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.FPORT = 2; ++ } ++#else ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.PN = gmac_no; ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.QN = 3; ++#endif ++ ++#if defined (CONFIG_RAETH_CHECKSUM_OFFLOAD) && ! defined(CONFIG_RALINK_RT5350) && !defined(CONFIG_RALINK_MT7628) ++ if (skb->ip_summed == CHECKSUM_PARTIAL){ ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.TUI_CO = 7; ++ }else { ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.TUI_CO = 0; ++ } ++#endif ++ ++#ifdef CONFIG_RAETH_HW_VLAN_TX ++ if(vlan_tx_tag_present(skb)) { ++#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.VLAN_TAG = 0x10000 | vlan_tx_tag_get(skb); ++#else ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.VPRI_VIDX = 0x80 | (vlan_tx_tag_get(skb) >> 13) << 4 | (vlan_tx_tag_get(skb) & 0xF); ++#endif ++ }else { ++#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.VLAN_TAG = 0; ++#else ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.VPRI_VIDX = 0; ++#endif ++ } ++#endif ++ ++#if defined(CONFIG_RAETH_PDMA_DVT) ++ raeth_pdma_tx_vlan_dvt( ei_local, tx_cpu_owner_idx0 ); ++#endif /* CONFIG_RAETH_PDMA_DVT */ ++ ++#if defined (CONFIG_RA_HW_NAT) || defined (CONFIG_RA_HW_NAT_MODULE) ++ if(FOE_MAGIC_TAG(skb) == FOE_MAGIC_PPE) { ++ if(ra_sw_nat_hook_rx!= NULL){ ++#if defined (CONFIG_RALINK_MT7620) ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.FP_BMAP = (1 << 7); /* PPE */ ++#elif defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.FPORT = 4; /* PPE */ ++#else ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.PN = 6; /* PPE */ ++#endif ++ FOE_MAGIC_TAG(skb) = 0; ++ } ++ } ++#endif ++ ++#if defined(CONFIG_RAETH_PDMA_DVT) ++ raeth_pdma_tx_desc_dvt( ei_local, tx_cpu_owner_idx0 ); ++#endif /* CONFIG_RAETH_PDMA_DVT */ ++ ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info2.DDONE_bit = 0; ++ ++#if 0 ++ printk("---------------\n"); ++ printk("tx_info1=%x\n",ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info1); ++ printk("tx_info2=%x\n",ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info2); ++ printk("tx_info3=%x\n",ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info3); ++ printk("tx_info4=%x\n",ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4); ++#endif ++ ++#else ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info1.SDP0 = virt_to_phys(skb->data); ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info2.SDL0 = (length - skb->data_len); ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info2.LS0_bit = nr_frags ? 0:1; ++#if defined (CONFIG_RALINK_MT7620) ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.FP_BMAP = 0; ++#elif defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++ if (gmac_no == 1) { ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.FPORT = 1; ++ }else { ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.FPORT = 2; ++ } ++#else ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.PN = gmac_no; ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.QN = 3; ++#endif ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.TSO = 0; ++ ++#if defined (CONFIG_RAETH_CHECKSUM_OFFLOAD) && ! defined(CONFIG_RALINK_RT5350) && !defined(CONFIG_RALINK_MT7628) ++ if (skb->ip_summed == CHECKSUM_PARTIAL){ ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.TUI_CO = 7; ++ }else { ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.TUI_CO = 0; ++ } ++#endif ++ ++#ifdef CONFIG_RAETH_HW_VLAN_TX ++ if(vlan_tx_tag_present(skb)) { ++#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.VLAN_TAG = 0x10000 | vlan_tx_tag_get(skb); ++#else ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.VPRI_VIDX = 0x80 | (vlan_tx_tag_get(skb) >> 13) << 4 | (vlan_tx_tag_get(skb) & 0xF); ++#endif ++ }else { ++#if defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.VLAN_TAG = 0; ++#else ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.VPRI_VIDX = 0; ++#endif ++ } ++#endif ++ ++#if defined(CONFIG_RAETH_PDMA_DVT) ++ raeth_pdma_tx_vlan_dvt( ei_local, tx_cpu_owner_idx0 ); ++#endif /* CONFIG_RAETH_PDMA_DVT */ ++ ++#if defined (CONFIG_RA_HW_NAT) || defined (CONFIG_RA_HW_NAT_MODULE) ++ if(FOE_MAGIC_TAG(skb) == FOE_MAGIC_PPE) { ++ if(ra_sw_nat_hook_rx!= NULL){ ++#if defined (CONFIG_RALINK_MT7620) ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.FP_BMAP = (1 << 7); /* PPE */ ++#elif defined (CONFIG_RALINK_MT7621) || defined (CONFIG_ARCH_MT7623) ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.FPORT = 4; /* PPE */ ++#else ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info4.PN = 6; /* PPE */ ++#endif ++ FOE_MAGIC_TAG(skb) = 0; ++ } ++ } ++#endif ++ ++ skb_txd_num = 1; ++ ++ if(nr_frags > 0) { ++ ++ for(i=0;i<nr_frags;i++) { ++ frag = &skb_shinfo(skb)->frags[i]; ++ offset = frag->page_offset; ++ len = frag->size; ++ frag_txd_num = cal_frag_txd_num(len); ++ ++ while(frag_txd_num > 0){ ++ if(len < MAX_TXD_LEN) ++ size = len; ++ else ++ size = MAX_TXD_LEN; ++ if(skb_txd_num%2 == 0) { ++ tx_cpu_owner_idx0 = (tx_cpu_owner_idx0+1) % NUM_TX_DESC; ++ ++ while(ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info2.DDONE_bit == 0) ++ { ++#ifdef config_pseudo_support ++ if (gmac_no == 2) { ++ if (ei_local->pseudodev != null) { ++ pad = netdev_priv(ei_local->pseudodev); ++ pad->stat.tx_errors++; ++ } ++ } else ++#endif ++ ei_local->stat.tx_errors++; ++ } ++ ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info1.SDP0 = pci_map_page(NULL, frag->page, offset, size, PCI_DMA_TODEVICE); ++#else ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info1.SDP0 = pci_map_page(NULL, frag->page.p, offset, size, PCI_DMA_TODEVICE); ++#endif ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info2.SDL0 = size; ++ ++ if( (i==(nr_frags-1)) && (frag_txd_num == 1)) ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info2.LS0_bit = 1; ++ else ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info2.LS0_bit = 0; ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info2.DDONE_bit = 0; ++ }else { ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info3.SDP1 = pci_map_page(NULL, frag->page, offset, size, PCI_DMA_TODEVICE); ++#else ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info3.SDP1 = pci_map_page(NULL, frag->page.p, offset, size, PCI_DMA_TODEVICE); ++ ++#endif ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info2.SDL1 = size; ++ if( (i==(nr_frags-1)) && (frag_txd_num == 1)) ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info2.LS1_bit = 1; ++ else ++ ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info2.LS1_bit = 0; ++ } ++ offset += size; ++ len -= size; ++ frag_txd_num--; ++ skb_txd_num++; ++ } ++ } ++ } ++ ++#if defined(CONFIG_RAETH_PDMA_DVT) ++ if( (pdma_dvt_get_debug_test_config() & PDMA_TEST_TSO_DEBUG) ){ ++ printk("skb_shinfo(skb)->gso_segs = %d\n", skb_shinfo(skb)->gso_segs); ++ } ++#endif /* CONFIG_RAETH_PDMA_DVT */ ++ /* fill in MSS info in tcp checksum field */ ++ if(skb_shinfo(skb)->gso_segs > 1) { ++ ++// TsoLenUpdate(skb->len); ++ ++ /* TCP over IPv4 */ ++ iph = (struct iphdr *)skb_network_header(skb); ++#if defined (CONFIG_RAETH_TSOV6) ++ /* TCP over IPv6 */ ++ ip6h = (struct ipv6hdr *)skb_network_header(skb); ++#endif ++ if((iph->version == 4) && (iph->protocol == IPPROTO_TCP)) { ++ th = (struct tcphdr *)skb_transport_header(skb); ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ ei_local->tx_ring0[ctx_idx_start_addr].txd_info4.TSO = 1; ++#else ++ ei_local->tx_ring0[sysRegRead(TX_CTX_IDX0)].txd_info4.TSO = 1; ++#endif ++ th->check = htons(skb_shinfo(skb)->gso_size); ++#if defined (CONFIG_MIPS) ++ dma_cache_sync(NULL, th, sizeof(struct tcphdr), DMA_TO_DEVICE); ++#else ++ dma_sync_single_for_device(NULL, virt_to_phys(th), sizeof(struct tcphdr), DMA_TO_DEVICE); ++#endif ++ } ++ ++#if defined (CONFIG_RAETH_TSOV6) ++ /* TCP over IPv6 */ ++ else if ((ip6h->version == 6) && (ip6h->nexthdr == NEXTHDR_TCP)) { ++ th = (struct tcphdr *)skb_transport_header(skb); ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ ei_local->tx_ring0[ctx_idx_start_addr].txd_info4.TSO = 1; ++#else ++ ei_local->tx_ring0[sysRegRead(TX_CTX_IDX0)].txd_info4.TSO = 1; ++#endif ++ th->check = htons(skb_shinfo(skb)->gso_size); ++#if defined (CONFIG_MIPS) ++ dma_cache_sync(NULL, th, sizeof(struct tcphdr), DMA_TO_DEVICE); ++#else ++ dma_sync_single_for_device(NULL, virt_to_phys(th), sizeof(struct tcphdr), DMA_TO_DEVICE); ++#endif ++ } ++#endif // CONFIG_RAETH_TSOV6 // ++ } ++ ++#if defined(CONFIG_RAETH_PDMA_DVT) ++ raeth_pdma_tx_desc_dvt( ei_local, tx_cpu_owner_idx0 ); ++#endif /* CONFIG_RAETH_PDMA_DVT */ ++ ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ ei_local->tx_ring0[ctx_idx_start_addr].txd_info2.DDONE_bit = 0; ++#else ++ ei_local->tx_ring0[sysRegRead(TX_CTX_IDX0)].txd_info2.DDONE_bit = 0; ++#endif ++#endif // CONFIG_RAETH_TSO // ++ ++ tx_cpu_owner_idx0 = (tx_cpu_owner_idx0+1) % NUM_TX_DESC; ++ while(ei_local->tx_ring0[tx_cpu_owner_idx0].txd_info2.DDONE_bit == 0) ++ { ++// printk(KERN_ERR "%s: TXD=%lu TX DMA is Busy !!\n", dev->name, tx_cpu_owner_idx0); ++#ifdef CONFIG_PSEUDO_SUPPORT ++ if (gmac_no == 2) { ++ if (ei_local->PseudoDev != NULL) { ++ pAd = netdev_priv(ei_local->PseudoDev); ++ pAd->stat.tx_errors++; ++ } ++ } else ++#endif ++ ei_local->stat.tx_errors++; ++ } ++ sysRegWrite(TX_CTX_IDX0, cpu_to_le32((u32)tx_cpu_owner_idx0)); ++ ++#ifdef CONFIG_PSEUDO_SUPPORT ++ if (gmac_no == 2) { ++ if (ei_local->PseudoDev != NULL) { ++ pAd = netdev_priv(ei_local->PseudoDev); ++ pAd->stat.tx_packets++; ++ pAd->stat.tx_bytes += length; ++ } ++ } else ++#endif ++ { ++ ei_local->stat.tx_packets++; ++ ei_local->stat.tx_bytes += length; ++ } ++#ifdef CONFIG_RAETH_NAPI ++ if ( ei_local->tx_full == 1) { ++ ei_local->tx_full = 0; ++ netif_wake_queue(dev); ++ } ++#endif ++ ++ return length; ++} ++ ++int ei_start_xmit(struct sk_buff* skb, struct net_device *dev, int gmac_no) ++{ ++ END_DEVICE *ei_local = netdev_priv(dev); ++ unsigned long flags; ++ unsigned long tx_cpu_owner_idx; ++ unsigned int tx_cpu_owner_idx_next; ++ unsigned int num_of_txd = 0; ++#if defined (CONFIG_RAETH_TSO) ++ unsigned int nr_frags = skb_shinfo(skb)->nr_frags, i; ++ struct skb_frag_struct *frag; ++#endif ++#if !defined(CONFIG_RAETH_QOS) ++ unsigned int tx_cpu_owner_idx_next2; ++#else ++ int ring_no, queue_no, port_no; ++#endif ++#ifdef CONFIG_RALINK_VISTA_BASIC ++ struct vlan_ethhdr *veth; ++#endif ++#ifdef CONFIG_PSEUDO_SUPPORT ++ PSEUDO_ADAPTER *pAd; ++#endif ++ ++#if !defined(CONFIG_RA_NAT_NONE) ++ if(ra_sw_nat_hook_tx!= NULL) ++ { ++#if defined (CONFIG_RA_HW_NAT) || defined (CONFIG_RA_HW_NAT_MODULE) ++ if(FOE_MAGIC_TAG(skb) != FOE_MAGIC_PPE) ++#endif ++ { ++ //spin_lock_irqsave(&ei_local->page_lock, flags); ++ if(ra_sw_nat_hook_tx(skb, gmac_no)==1){ ++ //spin_unlock_irqrestore(&ei_local->page_lock, flags); ++ }else{ ++ kfree_skb(skb); ++ //spin_unlock_irqrestore(&ei_local->page_lock, flags); ++ return 0; ++ } ++ } ++ } ++#endif ++#if defined(CONFIG_RA_CLASSIFIER)||defined(CONFIG_RA_CLASSIFIER_MODULE) ++ /* Qwert+ ++ */ ++ if(ra_classifier_hook_tx!= NULL) ++ { ++#if defined(CONFIG_RALINK_EXTERNAL_TIMER) ++ ra_classifier_hook_tx(skb, (*((volatile u32 *)(0xB0000D08))&0x0FFFF)); ++#else ++ ra_classifier_hook_tx(skb, read_c0_count()); ++#endif ++ } ++#endif /* CONFIG_RA_CLASSIFIER */ ++ ++#if defined (CONFIG_RALINK_RT3052_MP2) ++ mcast_tx(skb); ++#endif ++ ++#if !defined (CONFIG_RALINK_RT6855) && !defined (CONFIG_RALINK_RT6855A) && \ ++ !defined(CONFIG_RALINK_MT7621) && !defined (CONFIG_ARCH_MT7623) ++ ++#define MIN_PKT_LEN 60 ++ if (skb->len < MIN_PKT_LEN) { ++ if (skb_padto(skb, MIN_PKT_LEN)) { ++ printk("raeth: skb_padto failed\n"); ++ return 0; ++ } ++ skb_put(skb, MIN_PKT_LEN - skb->len); ++ } ++#endif ++ ++ dev->trans_start = jiffies; /* save the timestamp */ ++ spin_lock_irqsave(&ei_local->page_lock, flags); ++#if defined (CONFIG_MIPS) ++ dma_cache_sync(NULL, skb->data, skb->len, DMA_TO_DEVICE); ++#else ++ dma_sync_single_for_device(NULL, virt_to_phys(skb->data), skb->len, DMA_TO_DEVICE); ++ ++#endif ++ ++#ifdef CONFIG_RALINK_VISTA_BASIC ++ veth = (struct vlan_ethhdr *)(skb->data); ++ if (is_switch_175c && veth->h_vlan_proto == __constant_htons(ETH_P_8021Q)) { ++ if ((veth->h_vlan_TCI & __constant_htons(VLAN_VID_MASK)) == 0) { ++ veth->h_vlan_TCI |= htons(VLAN_DEV_INFO(dev)->vlan_id); ++ } ++ } ++#endif ++ ++#if defined (CONFIG_RAETH_QOS) ++ if(pkt_classifier(skb, gmac_no, &ring_no, &queue_no, &port_no)) { ++ get_tx_ctx_idx(ring_no, &tx_cpu_owner_idx); ++ tx_cpu_owner_idx_next = (tx_cpu_owner_idx + 1) % NUM_TX_DESC; ++ if(((ei_local->skb_free[ring_no][tx_cpu_owner_idx]) ==0) && (ei_local->skb_free[ring_no][tx_cpu_owner_idx_next]==0)){ ++ fe_qos_packet_send(dev, skb, ring_no, queue_no, port_no); ++ }else{ ++ ei_local->stat.tx_dropped++; ++ kfree_skb(skb); ++ spin_unlock_irqrestore(&ei_local->page_lock, flags); ++ return 0; ++ } ++ } ++#else ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ tx_cpu_owner_idx = tx_cpu_owner_idx0; ++#else ++ tx_cpu_owner_idx = sysRegRead(TX_CTX_IDX0); ++#endif ++#if defined (CONFIG_RAETH_TSO) ++// num_of_txd = (nr_frags==0) ? 1 : ((nr_frags>>1) + 1); ++// NumOfTxdUpdate(num_of_txd); ++ if(nr_frags != 0){ ++ for(i=0;i<nr_frags;i++) { ++ frag = &skb_shinfo(skb)->frags[i]; ++ num_of_txd += cal_frag_txd_num(frag->size); ++ } ++ num_of_txd = (num_of_txd >> 1) + 1; ++ }else ++ num_of_txd = 1; ++ ++#else ++ num_of_txd = 1; ++#endif ++ tx_cpu_owner_idx_next = (tx_cpu_owner_idx + num_of_txd) % NUM_TX_DESC; ++ ++ if(((ei_local->skb_free[tx_cpu_owner_idx]) ==0) && (ei_local->skb_free[tx_cpu_owner_idx_next]==0)){ ++ rt2880_eth_send(dev, skb, gmac_no); ++ ++ tx_cpu_owner_idx_next2 = (tx_cpu_owner_idx_next + 1) % NUM_TX_DESC; ++ ++ if(ei_local->skb_free[tx_cpu_owner_idx_next2]!=0){ ++#if defined (CONFIG_RAETH_SW_FC) ++ netif_stop_queue(dev); ++#ifdef CONFIG_PSEUDO_SUPPORT ++ netif_stop_queue(ei_local->PseudoDev); ++#endif ++ tx_ring_full=1; ++#endif ++ } ++ }else { ++#ifdef CONFIG_PSEUDO_SUPPORT ++ if (gmac_no == 2) { ++ if (ei_local->PseudoDev != NULL) { ++ pAd = netdev_priv(ei_local->PseudoDev); ++ pAd->stat.tx_dropped++; ++ } ++ } else ++#endif ++ ei_local->stat.tx_dropped++; ++#if defined (CONFIG_RAETH_SW_FC) ++ printk("tx_ring_full, drop packet\n"); ++#endif ++ kfree_skb(skb); ++ spin_unlock_irqrestore(&ei_local->page_lock, flags); ++ return 0; ++ } ++ ++#if defined (CONFIG_RAETH_TSO) ++ /* SG: use multiple TXD to send the packet (only have one skb) */ ++ ei_local->skb_free[(tx_cpu_owner_idx + num_of_txd - 1) % NUM_TX_DESC] = skb; ++ while(--num_of_txd) { ++ ei_local->skb_free[(tx_cpu_owner_idx + num_of_txd -1) % NUM_TX_DESC] = (struct sk_buff *)0xFFFFFFFF; //MAGIC ID ++ } ++#else ++ ei_local->skb_free[tx_cpu_owner_idx] = skb; ++#endif ++#endif ++ spin_unlock_irqrestore(&ei_local->page_lock, flags); ++ return 0; ++} ++ ++void ei_xmit_housekeeping(unsigned long unused) ++{ ++ struct net_device *dev = dev_raether; ++ END_DEVICE *ei_local = netdev_priv(dev); ++ struct PDMA_txdesc *tx_desc; ++ unsigned long skb_free_idx; ++ unsigned long tx_dtx_idx __maybe_unused; ++#ifndef CONFIG_RAETH_NAPI ++ unsigned long reg_int_mask=0; ++#endif ++ ++#ifdef CONFIG_RAETH_QOS ++ int i; ++ for (i=0;i<NUM_TX_RINGS;i++){ ++ skb_free_idx = ei_local->free_idx[i]; ++ if((ei_local->skb_free[i][skb_free_idx])==0){ ++ continue; ++ } ++ ++ get_tx_desc_and_dtx_idx(ei_local, i, &tx_dtx_idx, &tx_desc); ++ ++ while(tx_desc[skb_free_idx].txd_info2.DDONE_bit==1 && (ei_local->skb_free[i][skb_free_idx])!=0 ){ ++ dev_kfree_skb_any((ei_local->skb_free[i][skb_free_idx])); ++ ++ ei_local->skb_free[i][skb_free_idx]=0; ++ skb_free_idx = (skb_free_idx +1) % NUM_TX_DESC; ++ } ++ ei_local->free_idx[i] = skb_free_idx; ++ } ++#else ++ tx_dtx_idx = sysRegRead(TX_DTX_IDX0); ++ tx_desc = ei_local->tx_ring0; ++ skb_free_idx = ei_local->free_idx; ++ if ((ei_local->skb_free[skb_free_idx]) != 0 && tx_desc[skb_free_idx].txd_info2.DDONE_bit==1) { ++ while(tx_desc[skb_free_idx].txd_info2.DDONE_bit==1 && (ei_local->skb_free[skb_free_idx])!=0 ){ ++#if defined (CONFIG_RAETH_TSO) ++ if(ei_local->skb_free[skb_free_idx]!=(struct sk_buff *)0xFFFFFFFF) { ++ dev_kfree_skb_any(ei_local->skb_free[skb_free_idx]); ++ } ++#else ++ dev_kfree_skb_any(ei_local->skb_free[skb_free_idx]); ++#endif ++ ei_local->skb_free[skb_free_idx]=0; ++ skb_free_idx = (skb_free_idx +1) % NUM_TX_DESC; ++ } ++ ++ netif_wake_queue(dev); ++#ifdef CONFIG_PSEUDO_SUPPORT ++ netif_wake_queue(ei_local->PseudoDev); ++#endif ++ tx_ring_full=0; ++ ei_local->free_idx = skb_free_idx; ++ } /* if skb_free != 0 */ ++#endif ++ ++#ifndef CONFIG_RAETH_NAPI ++ reg_int_mask=sysRegRead(FE_INT_ENABLE); ++#if defined (DELAY_INT) ++ sysRegWrite(FE_INT_ENABLE, reg_int_mask| TX_DLY_INT); ++#else ++ ++ sysRegWrite(FE_INT_ENABLE, reg_int_mask | TX_DONE_INT0 \ ++ | TX_DONE_INT1 \ ++ | TX_DONE_INT2 \ ++ | TX_DONE_INT3); ++#endif ++#endif //CONFIG_RAETH_NAPI// ++} ++ ++ ++ ++EXPORT_SYMBOL(ei_start_xmit); ++EXPORT_SYMBOL(ei_xmit_housekeeping); ++EXPORT_SYMBOL(fe_dma_init); ++EXPORT_SYMBOL(rt2880_eth_send); +diff --git a/drivers/net/ethernet/raeth/raether_qdma.c b/drivers/net/ethernet/raeth/raether_qdma.c +new file mode 100644 +index 0000000..acf8bfe +--- /dev/null ++++ b/drivers/net/ethernet/raeth/raether_qdma.c +@@ -0,0 +1,1407 @@ ++#include <linux/module.h> ++#include <linux/version.h> ++#include <linux/kernel.h> ++#include <linux/types.h> ++#include <linux/pci.h> ++#include <linux/init.h> ++#include <linux/skbuff.h> ++#include <linux/if_vlan.h> ++#include <linux/if_ether.h> ++#include <linux/fs.h> ++#include <asm/uaccess.h> ++#include <asm/rt2880/surfboardint.h> ++#if defined (CONFIG_RAETH_TSO) ++#include <linux/tcp.h> ++#include <net/ipv6.h> ++#include <linux/ip.h> ++#include <net/ip.h> ++#include <net/tcp.h> ++#include <linux/in.h> ++#include <linux/ppp_defs.h> ++#include <linux/if_pppox.h> ++#endif ++#include <linux/delay.h> ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++#include <linux/sched.h> ++#endif ++#if defined (CONFIG_HW_SFQ) ++#include <linux/if_vlan.h> ++#include <net/ipv6.h> ++#include <net/ip.h> ++#include <linux/if_pppox.h> ++#include <linux/ppp_defs.h> ++#endif ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++#include <asm/rt2880/rt_mmap.h> ++#else ++#include <linux/libata-compat.h> ++#endif ++ ++#include "ra2882ethreg.h" ++#include "raether.h" ++#include "ra_mac.h" ++#include "ra_ioctl.h" ++#include "ra_rfrw.h" ++#ifdef CONFIG_RAETH_NETLINK ++#include "ra_netlink.h" ++#endif ++#if defined (CONFIG_RAETH_QOS) ++#include "ra_qos.h" ++#endif ++ ++#if defined (CONFIG_RA_HW_NAT) || defined (CONFIG_RA_HW_NAT_MODULE) ++#include "../../../net/nat/hw_nat/ra_nat.h" ++#endif ++ ++ ++#if !defined(CONFIG_RA_NAT_NONE) ++/* bruce+ ++ */ ++extern int (*ra_sw_nat_hook_rx)(struct sk_buff *skb); ++extern int (*ra_sw_nat_hook_tx)(struct sk_buff *skb, int gmac_no); ++#endif ++ ++#if defined(CONFIG_RA_CLASSIFIER)||defined(CONFIG_RA_CLASSIFIER_MODULE) ++/* Qwert+ ++ */ ++#include <asm/mipsregs.h> ++extern int (*ra_classifier_hook_tx)(struct sk_buff *skb, unsigned long cur_cycle); ++extern int (*ra_classifier_hook_rx)(struct sk_buff *skb, unsigned long cur_cycle); ++#endif /* CONFIG_RA_CLASSIFIER */ ++ ++#if defined (CONFIG_RALINK_RT3052_MP2) ++int32_t mcast_rx(struct sk_buff * skb); ++int32_t mcast_tx(struct sk_buff * skb); ++#endif ++ ++#ifdef RA_MTD_RW_BY_NUM ++int ra_mtd_read(int num, loff_t from, size_t len, u_char *buf); ++#else ++int ra_mtd_read_nm(char *name, loff_t from, size_t len, u_char *buf); ++#endif ++ ++/* gmac driver feature set config */ ++#if defined (CONFIG_RAETH_NAPI) || defined (CONFIG_RAETH_QOS) ++#undef DELAY_INT ++#else ++#if defined (CONFIG_ARCH_MT7623) ++#undef DELAY_INT ++#else ++#define DELAY_INT 1 ++#endif ++#endif ++ ++//#define CONFIG_UNH_TEST ++/* end of config */ ++ ++#if defined (CONFIG_RAETH_JUMBOFRAME) ++#define MAX_RX_LENGTH 4096 ++#else ++#define MAX_RX_LENGTH 1536 ++#endif ++ ++extern struct net_device *dev_raether; ++ ++#if defined (CONFIG_RAETH_MULTIPLE_RX_RING) ++static int rx_dma_owner_idx1; ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++static int rx_calc_idx1; ++#endif ++#endif ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++static int rx_calc_idx0; ++static unsigned long tx_cpu_owner_idx0=0; ++#endif ++extern unsigned long tx_ring_full; ++ ++#if defined (CONFIG_ETHTOOL) && defined (CONFIG_RAETH_ROUTER) ++#include "ra_ethtool.h" ++extern struct ethtool_ops ra_ethtool_ops; ++#ifdef CONFIG_PSEUDO_SUPPORT ++extern struct ethtool_ops ra_virt_ethtool_ops; ++#endif // CONFIG_PSEUDO_SUPPORT // ++#endif // (CONFIG_ETHTOOL // ++ ++#ifdef CONFIG_RALINK_VISTA_BASIC ++int is_switch_175c = 1; ++#endif ++ ++//skb->mark to queue mapping table ++extern unsigned int M2Q_table[64]; ++struct QDMA_txdesc *free_head = NULL; ++extern unsigned int lan_wan_separate; ++#if defined (CONFIG_HW_SFQ) ++extern unsigned int web_sfq_enable; ++#define HwSfqQUp 3 ++#define HwSfqQDl 1 ++#endif ++int dbg =0;//debug used ++#if defined (CONFIG_HW_SFQ) ++struct SFQ_table *sfq0; ++struct SFQ_table *sfq1; ++struct SFQ_table *sfq2; ++struct SFQ_table *sfq3; ++#endif ++ ++#define KSEG1 0xa0000000 ++#if defined (CONFIG_MIPS) ++#define PHYS_TO_VIRT(x) ((void *)((x) | KSEG1)) ++#define VIRT_TO_PHYS(x) ((unsigned long)(x) & ~KSEG1) ++#else ++#define PHYS_TO_VIRT(x) phys_to_virt(x) ++#define VIRT_TO_PHYS(x) virt_to_phys(x) ++#endif ++ ++extern void set_fe_dma_glo_cfg(void); ++ ++#if defined (CONFIG_HW_SFQ) ++ParseResult SfqParseResult; ++#endif ++ ++/** ++ * ++ * @brief: get the TXD index from its address ++ * ++ * @param: cpu_ptr ++ * ++ * @return: TXD index ++*/ ++ ++static unsigned int GET_TXD_OFFSET(struct QDMA_txdesc **cpu_ptr) ++{ ++ struct net_device *dev = dev_raether; ++ END_DEVICE *ei_local = netdev_priv(dev); ++ int ctx_offset; ++ //ctx_offset = (((((u32)*cpu_ptr) <<8)>>8) - ((((u32)ei_local->txd_pool)<<8)>>8))/ sizeof(struct QDMA_txdesc); ++ //ctx_offset = (*cpu_ptr - ei_local->txd_pool); ++ ctx_offset = (((((u32)*cpu_ptr) <<8)>>8) - ((((u32)ei_local->phy_txd_pool)<<8)>>8))/ sizeof(struct QDMA_txdesc); ++ ++ return ctx_offset; ++} ++ ++ ++ ++ ++/** ++ * @brief cal txd number for a page ++ * ++ * @parm size ++ * ++ * @return frag_txd_num ++ */ ++ ++unsigned int cal_frag_txd_num(unsigned int size) ++{ ++ unsigned int frag_txd_num = 0; ++ if(size == 0) ++ return 0; ++ while(size > 0){ ++ if(size > MAX_TXD_LEN){ ++ frag_txd_num++; ++ size -= MAX_TXD_LEN; ++ }else{ ++ frag_txd_num++; ++ size = 0; ++ } ++ } ++ return frag_txd_num; ++ ++} ++ ++/** ++ * @brief get free TXD from TXD queue ++ * ++ * @param free_txd ++ * ++ * @return ++ */ ++static int get_free_txd(struct QDMA_txdesc **free_txd) ++{ ++ struct net_device *dev = dev_raether; ++ END_DEVICE *ei_local = netdev_priv(dev); ++ unsigned int tmp_idx; ++ ++ if(ei_local->free_txd_num > 0){ ++ tmp_idx = ei_local->free_txd_head; ++ ei_local->free_txd_head = ei_local->txd_pool_info[tmp_idx]; ++ ei_local->free_txd_num -= 1; ++ //*free_txd = &ei_local->txd_pool[tmp_idx]; ++ *free_txd = ei_local->phy_txd_pool + (sizeof(struct QDMA_txdesc) * tmp_idx); ++ return tmp_idx; ++ }else ++ return NUM_TX_DESC; ++} ++ ++ ++/** ++ * @brief add free TXD into TXD queue ++ * ++ * @param free_txd ++ * ++ * @return ++ */ ++int put_free_txd(int free_txd_idx) ++{ ++ struct net_device *dev = dev_raether; ++ END_DEVICE *ei_local = netdev_priv(dev); ++ ei_local->txd_pool_info[ei_local->free_txd_tail] = free_txd_idx; ++ ei_local->free_txd_tail = free_txd_idx; ++ ei_local->txd_pool_info[free_txd_idx] = NUM_TX_DESC; ++ ei_local->free_txd_num += 1; ++ return 1; ++} ++ ++/*define qdma initial alloc*/ ++/** ++ * @brief ++ * ++ * @param net_dev ++ * ++ * @return 0: fail ++ * 1: success ++ */ ++bool qdma_tx_desc_alloc(void) ++{ ++ struct net_device *dev = dev_raether; ++ END_DEVICE *ei_local = netdev_priv(dev); ++ struct QDMA_txdesc *free_txd = NULL; ++ unsigned int txd_idx; ++ int i = 0; ++ ++ ++ ei_local->txd_pool = pci_alloc_consistent(NULL, sizeof(struct QDMA_txdesc) * NUM_TX_DESC, &ei_local->phy_txd_pool); ++ printk("txd_pool=%p phy_txd_pool=%08X\n", ei_local->txd_pool , ei_local->phy_txd_pool); ++ ++ if (ei_local->txd_pool == NULL) { ++ printk("adapter->txd_pool allocation failed!\n"); ++ return 0; ++ } ++ printk("ei_local->skb_free start address is 0x%p.\n", ei_local->skb_free); ++ //set all txd_pool_info to 0. ++ for ( i = 0; i < NUM_TX_DESC; i++) ++ { ++ ei_local->skb_free[i]= 0; ++ ei_local->txd_pool_info[i] = i + 1; ++ ei_local->txd_pool[i].txd_info3.LS_bit = 1; ++ ei_local->txd_pool[i].txd_info3.OWN_bit = 1; ++ } ++ ++ ei_local->free_txd_head = 0; ++ ei_local->free_txd_tail = NUM_TX_DESC - 1; ++ ei_local->free_txd_num = NUM_TX_DESC; ++ ++ ++ //get free txd from txd pool ++ txd_idx = get_free_txd(&free_txd); ++ if( txd_idx == NUM_TX_DESC) { ++ printk("get_free_txd fail\n"); ++ return 0; ++ } ++ ++ //add null TXD for transmit ++ //ei_local->tx_dma_ptr = VIRT_TO_PHYS(free_txd); ++ //ei_local->tx_cpu_ptr = VIRT_TO_PHYS(free_txd); ++ ei_local->tx_dma_ptr = free_txd; ++ ei_local->tx_cpu_ptr = free_txd; ++ sysRegWrite(QTX_CTX_PTR, ei_local->tx_cpu_ptr); ++ sysRegWrite(QTX_DTX_PTR, ei_local->tx_dma_ptr); ++ ++ //get free txd from txd pool ++ ++ txd_idx = get_free_txd(&free_txd); ++ if( txd_idx == NUM_TX_DESC) { ++ printk("get_free_txd fail\n"); ++ return 0; ++ } ++ // add null TXD for release ++ //sysRegWrite(QTX_CRX_PTR, VIRT_TO_PHYS(free_txd)); ++ //sysRegWrite(QTX_DRX_PTR, VIRT_TO_PHYS(free_txd)); ++ sysRegWrite(QTX_CRX_PTR, free_txd); ++ sysRegWrite(QTX_DRX_PTR, free_txd); ++ printk("free_txd: %p, ei_local->cpu_ptr: %08X\n", free_txd, ei_local->tx_cpu_ptr); ++ ++ printk(" POOL HEAD_PTR | DMA_PTR | CPU_PTR \n"); ++ printk("----------------+---------+--------\n"); ++ printk(" 0x%p 0x%08X 0x%08X\n",ei_local->txd_pool, ei_local->tx_dma_ptr, ei_local->tx_cpu_ptr); ++ return 1; ++} ++#if defined (CONFIG_HW_SFQ) ++bool sfq_init(void) ++{ ++ unsigned int regVal; ++ ++ unsigned int sfq_phy0; ++ unsigned int sfq_phy1; ++ unsigned int sfq_phy2; ++ unsigned int sfq_phy3; ++ struct SFQ_table *sfq0; ++ struct SFQ_table *sfq1; ++ struct SFQ_table *sfq2; ++ struct SFQ_table *sfq3; ++ int i = 0; ++ regVal = sysRegRead(VQTX_GLO); ++ regVal = regVal | VQTX_MIB_EN |(1<<16) ; ++ sysRegWrite(VQTX_GLO, regVal);// Virtual table extends to 32bytes ++ regVal = sysRegRead(VQTX_GLO); ++ sysRegWrite(VQTX_NUM, (VQTX_NUM_0) | (VQTX_NUM_1) | (VQTX_NUM_2) | (VQTX_NUM_3)); ++ sysRegWrite(VQTX_HASH_CFG, 0xF002710); //10 s change hash algorithm ++ sysRegWrite(VQTX_VLD_CFG, 0x00); ++ sysRegWrite(VQTX_HASH_SD, 0x0D); ++ sysRegWrite(QDMA_FC_THRES, 0x9b9b4444); ++ sysRegWrite(QDMA_HRED1, 0); ++ sysRegWrite(QDMA_HRED2, 0); ++ sysRegWrite(QDMA_SRED1, 0); ++ sysRegWrite(QDMA_SRED2, 0); ++ sfq0 = pci_alloc_consistent(NULL, 256*sizeof(struct SFQ_table), &sfq_phy0); ++ memset(sfq0, 0x0, 256*sizeof(struct SFQ_table) ); ++ for (i=0; i < 256; i++) { ++ sfq0[i].sfq_info1.VQHPTR = 0xdeadbeef; ++ sfq0[i].sfq_info2.VQTPTR = 0xdeadbeef; ++ } ++#if(1) ++ sfq1 = pci_alloc_consistent(NULL, 256*sizeof(struct SFQ_table), &sfq_phy1); ++ ++ memset(sfq1, 0x0, 256*sizeof(struct SFQ_table) ); ++ for (i=0; i < 256; i++) { ++ sfq1[i].sfq_info1.VQHPTR = 0xdeadbeef; ++ sfq1[i].sfq_info2.VQTPTR = 0xdeadbeef; ++ } ++ ++ sfq2 = pci_alloc_consistent(NULL, 256*sizeof(struct SFQ_table), &sfq_phy2); ++ memset(sfq2, 0x0, 256*sizeof(struct SFQ_table) ); ++ for (i=0; i < 256; i++) { ++ sfq2[i].sfq_info1.VQHPTR = 0xdeadbeef; ++ sfq2[i].sfq_info2.VQTPTR = 0xdeadbeef; ++ } ++ ++ sfq3 = pci_alloc_consistent(NULL, 256*sizeof(struct SFQ_table), &sfq_phy3); ++ memset(sfq3, 0x0, 256*sizeof(struct SFQ_table) ); ++ for (i=0; i < 256; i++) { ++ sfq3[i].sfq_info1.VQHPTR = 0xdeadbeef; ++ sfq3[i].sfq_info2.VQTPTR = 0xdeadbeef; ++ } ++ ++#endif ++ printk("*****sfq_phy0 is 0x%x!!!*******\n", sfq_phy0); ++ printk("*****sfq_phy1 is 0x%x!!!*******\n", sfq_phy1); ++ printk("*****sfq_phy2 is 0x%x!!!*******\n", sfq_phy2); ++ printk("*****sfq_phy3 is 0x%x!!!*******\n", sfq_phy3); ++ printk("*****sfq_virt0 is 0x%x!!!*******\n", sfq0); ++ printk("*****sfq_virt1 is 0x%x!!!*******\n", sfq1); ++ printk("*****sfq_virt2 is 0x%x!!!*******\n", sfq2); ++ printk("*****sfq_virt3 is 0x%x!!!*******\n", sfq3); ++ printk("*****sfq_virt0 is 0x%x!!!*******\n", sfq0); ++ sysRegWrite(VQTX_TB_BASE0, (u32)sfq_phy0); ++ sysRegWrite(VQTX_TB_BASE1, (u32)sfq_phy1); ++ sysRegWrite(VQTX_TB_BASE2, (u32)sfq_phy2); ++ sysRegWrite(VQTX_TB_BASE3, (u32)sfq_phy3); ++ ++ return 1; ++} ++#endif ++bool fq_qdma_init(struct net_device *dev) ++{ ++ END_DEVICE* ei_local = netdev_priv(dev); ++ //struct QDMA_txdesc *free_head = NULL; ++ unsigned int phy_free_head; ++ unsigned int phy_free_tail; ++ unsigned int *free_page_head = NULL; ++ unsigned int phy_free_page_head; ++ int i; ++ ++ free_head = pci_alloc_consistent(NULL, NUM_QDMA_PAGE * sizeof(struct QDMA_txdesc), &phy_free_head); ++ if (unlikely(free_head == NULL)){ ++ printk(KERN_ERR "QDMA FQ decriptor not available...\n"); ++ return 0; ++ } ++ memset(free_head, 0x0, sizeof(struct QDMA_txdesc) * NUM_QDMA_PAGE); ++ ++ free_page_head = pci_alloc_consistent(NULL, NUM_QDMA_PAGE * QDMA_PAGE_SIZE, &phy_free_page_head); ++ if (unlikely(free_page_head == NULL)){ ++ printk(KERN_ERR "QDMA FQ page not available...\n"); ++ return 0; ++ } ++ for (i=0; i < NUM_QDMA_PAGE; i++) { ++ free_head[i].txd_info1.SDP = (phy_free_page_head + (i * QDMA_PAGE_SIZE)); ++ if(i < (NUM_QDMA_PAGE-1)){ ++ free_head[i].txd_info2.NDP = (phy_free_head + ((i+1) * sizeof(struct QDMA_txdesc))); ++ ++ ++#if 0 ++ printk("free_head_phy[%d] is 0x%x!!!\n",i, VIRT_TO_PHYS(&free_head[i]) ); ++ printk("free_head[%d] is 0x%x!!!\n",i, &free_head[i] ); ++ printk("free_head[%d].txd_info1.SDP is 0x%x!!!\n",i, free_head[i].txd_info1.SDP ); ++ printk("free_head[%d].txd_info2.NDP is 0x%x!!!\n",i, free_head[i].txd_info2.NDP ); ++#endif ++ } ++ free_head[i].txd_info3.SDL = QDMA_PAGE_SIZE; ++ ++ } ++ phy_free_tail = (phy_free_head + (u32)((NUM_QDMA_PAGE-1) * sizeof(struct QDMA_txdesc))); ++ ++ printk("phy_free_head is 0x%x!!!\n", phy_free_head); ++ printk("phy_free_tail_phy is 0x%x!!!\n", phy_free_tail); ++ sysRegWrite(QDMA_FQ_HEAD, (u32)phy_free_head); ++ sysRegWrite(QDMA_FQ_TAIL, (u32)phy_free_tail); ++ sysRegWrite(QDMA_FQ_CNT, ((NUM_TX_DESC << 16) | NUM_QDMA_PAGE)); ++ sysRegWrite(QDMA_FQ_BLEN, QDMA_PAGE_SIZE << 16); ++ ++ ei_local->free_head = free_head; ++ ei_local->phy_free_head = phy_free_head; ++ ei_local->free_page_head = free_page_head; ++ ei_local->phy_free_page_head = phy_free_page_head; ++ return 1; ++} ++ ++int fe_dma_init(struct net_device *dev) ++{ ++ ++ int i; ++ unsigned int regVal; ++ END_DEVICE* ei_local = netdev_priv(dev); ++ ++ ++ #if defined (CONFIG_HW_SFQ) ++ sfq_init(); ++ #endif ++ fq_qdma_init(dev); ++ ++ while(1) ++ { ++ regVal = sysRegRead(QDMA_GLO_CFG); ++ if((regVal & RX_DMA_BUSY)) ++ { ++ printk("\n RX_DMA_BUSY !!! "); ++ continue; ++ } ++ if((regVal & TX_DMA_BUSY)) ++ { ++ printk("\n TX_DMA_BUSY !!! "); ++ continue; ++ } ++ break; ++ } ++ /*tx desc alloc, add a NULL TXD to HW*/ ++ ++ qdma_tx_desc_alloc(); ++ ++ /* Initial RX Ring 0*/ ++ ++#ifdef CONFIG_32B_DESC ++ ei_local->qrx_ring = kmalloc(NUM_QRX_DESC * sizeof(struct PDMA_rxdesc), GFP_KERNEL); ++ ei_local->phy_qrx_ring = virt_to_phys(ei_local->qrx_ring); ++#else ++ ei_local->qrx_ring = pci_alloc_consistent(NULL, NUM_QRX_DESC * sizeof(struct PDMA_rxdesc), &ei_local->phy_qrx_ring); ++#endif ++ for (i = 0; i < NUM_QRX_DESC; i++) { ++ memset(&ei_local->qrx_ring[i],0,sizeof(struct PDMA_rxdesc)); ++ ei_local->qrx_ring[i].rxd_info2.DDONE_bit = 0; ++#if defined (CONFIG_RAETH_SCATTER_GATHER_RX_DMA) ++ ei_local->qrx_ring[i].rxd_info2.LS0 = 0; ++ ei_local->qrx_ring[i].rxd_info2.PLEN0 = MAX_RX_LENGTH; ++#else ++ ei_local->qrx_ring[i].rxd_info2.LS0 = 1; ++#endif ++ ei_local->qrx_ring[i].rxd_info1.PDP0 = dma_map_single(NULL, ei_local->netrx0_skbuf[i]->data, MAX_RX_LENGTH, PCI_DMA_FROMDEVICE); ++ } ++ printk("\nphy_qrx_ring = 0x%08x, qrx_ring = 0x%p\n",ei_local->phy_qrx_ring,ei_local->qrx_ring); ++ ++ regVal = sysRegRead(QDMA_GLO_CFG); ++ regVal &= 0x000000FF; ++ ++ sysRegWrite(QDMA_GLO_CFG, regVal); ++ regVal=sysRegRead(QDMA_GLO_CFG); ++ ++ /* Tell the adapter where the TX/RX rings are located. */ ++ ++ sysRegWrite(QRX_BASE_PTR_0, phys_to_bus((u32) ei_local->phy_qrx_ring)); ++ sysRegWrite(QRX_MAX_CNT_0, cpu_to_le32((u32) NUM_QRX_DESC)); ++ sysRegWrite(QRX_CRX_IDX_0, cpu_to_le32((u32) (NUM_QRX_DESC - 1))); ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ rx_calc_idx0 = rx_dma_owner_idx0 = sysRegRead(QRX_CRX_IDX_0); ++#endif ++ sysRegWrite(QDMA_RST_CFG, PST_DRX_IDX0); ++ ++ ei_local->rx_ring0 = ei_local->qrx_ring; ++#if !defined (CONFIG_RAETH_QDMATX_QDMARX) ++ /* Initial PDMA RX Ring 0*/ ++#ifdef CONFIG_32B_DESC ++ ei_local->rx_ring0 = kmalloc(NUM_RX_DESC * sizeof(struct PDMA_rxdesc), GFP_KERNEL); ++ ei_local->phy_rx_ring0 = virt_to_phys(ei_local->rx_ring0); ++#else ++ ei_local->rx_ring0 = pci_alloc_consistent(NULL, NUM_RX_DESC * sizeof(struct PDMA_rxdesc), &ei_local->phy_rx_ring0); ++#endif ++ for (i = 0; i < NUM_RX_DESC; i++) { ++ memset(&ei_local->rx_ring0[i],0,sizeof(struct PDMA_rxdesc)); ++ ei_local->rx_ring0[i].rxd_info2.DDONE_bit = 0; ++#if defined (CONFIG_RAETH_SCATTER_GATHER_RX_DMA) ++ ei_local->rx_ring0[i].rxd_info2.LS0 = 0; ++ ei_local->rx_ring0[i].rxd_info2.PLEN0 = MAX_RX_LENGTH; ++#else ++ ei_local->rx_ring0[i].rxd_info2.LS0 = 1; ++#endif ++ ei_local->rx_ring0[i].rxd_info1.PDP0 = dma_map_single(NULL, ei_local->netrx0_skbuf[i]->data, MAX_RX_LENGTH, PCI_DMA_FROMDEVICE); ++ } ++ printk("\nphy_rx_ring0 = 0x%08x, rx_ring0 = 0x%p\n",ei_local->phy_rx_ring0,ei_local->rx_ring0); ++ ++ regVal = sysRegRead(PDMA_GLO_CFG); ++ regVal &= 0x000000FF; ++ sysRegWrite(PDMA_GLO_CFG, regVal); ++ regVal=sysRegRead(PDMA_GLO_CFG); ++ ++ sysRegWrite(RX_BASE_PTR0, phys_to_bus((u32) ei_local->phy_rx_ring0)); ++ sysRegWrite(RX_MAX_CNT0, cpu_to_le32((u32) NUM_RX_DESC)); ++ sysRegWrite(RX_CALC_IDX0, cpu_to_le32((u32) (NUM_RX_DESC - 1))); ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ rx_calc_idx0 = sysRegRead(RX_CALC_IDX0); ++#endif ++ sysRegWrite(PDMA_RST_CFG, PST_DRX_IDX0); ++#endif ++#if !defined (CONFIG_HW_SFQ) ++ /* Enable randon early drop and set drop threshold automatically */ ++ sysRegWrite(QDMA_FC_THRES, 0x174444); ++#endif ++ sysRegWrite(QDMA_HRED2, 0x0); ++ set_fe_dma_glo_cfg(); ++#if defined (CONFIG_ARCH_MT7623) ++ printk("Enable QDMA TX NDP coherence check and re-read mechanism\n"); ++ regVal=sysRegRead(QDMA_GLO_CFG); ++ regVal = regVal | 0x400; ++ sysRegWrite(QDMA_GLO_CFG, regVal); ++ printk("***********QDMA_GLO_CFG=%x\n", sysRegRead(QDMA_GLO_CFG)); ++#endif ++ ++ return 1; ++} ++ ++#if defined (CONFIG_HW_SFQ) ++ ++int sfq_prot = 0; ++int proto_id=0; ++int udp_source_port=0; ++int tcp_source_port=0; ++int ack_packt =0; ++int SfqParseLayerInfo(struct sk_buff * skb) ++{ ++ ++ struct vlan_hdr *vh_sfq = NULL; ++ struct ethhdr *eth_sfq = NULL; ++ struct iphdr *iph_sfq = NULL; ++ struct ipv6hdr *ip6h_sfq = NULL; ++ struct tcphdr *th_sfq = NULL; ++ struct udphdr *uh_sfq = NULL; ++#ifdef CONFIG_RAETH_HW_VLAN_TX ++ struct vlan_hdr pseudo_vhdr_sfq; ++#endif ++ ++ memset(&SfqParseResult, 0, sizeof(SfqParseResult)); ++ ++ eth_sfq = (struct ethhdr *)skb->data; ++ memcpy(SfqParseResult.dmac, eth_sfq->h_dest, ETH_ALEN); ++ memcpy(SfqParseResult.smac, eth_sfq->h_source, ETH_ALEN); ++ SfqParseResult.eth_type = eth_sfq->h_proto; ++ ++ ++ if (SfqParseResult.eth_type == htons(ETH_P_8021Q)){ ++ SfqParseResult.vlan1_gap = VLAN_HLEN; ++ vh_sfq = (struct vlan_hdr *)(skb->data + ETH_HLEN); ++ SfqParseResult.eth_type = vh_sfq->h_vlan_encapsulated_proto; ++ }else{ ++ SfqParseResult.vlan1_gap = 0; ++ } ++ ++ ++ ++ LAYER2_HEADER(skb) = skb->data; ++ LAYER3_HEADER(skb) = (skb->data + ETH_HLEN + (SfqParseResult.vlan1_gap)); ++ ++ ++ ++ /* set layer4 start addr */ ++ if ((SfqParseResult.eth_type == htons(ETH_P_IP)) || (SfqParseResult.eth_type == htons(ETH_P_PPP_SES) ++ && SfqParseResult.ppp_tag == htons(PPP_IP))) { ++ iph_sfq = (struct iphdr *)LAYER3_HEADER(skb); ++ ++ //prepare layer3/layer4 info ++ memcpy(&SfqParseResult.iph, iph_sfq, sizeof(struct iphdr)); ++ if (iph_sfq->protocol == IPPROTO_TCP) { ++ ++ LAYER4_HEADER(skb) = ((uint8_t *) iph_sfq + (iph_sfq->ihl * 4)); ++ th_sfq = (struct tcphdr *)LAYER4_HEADER(skb); ++ memcpy(&SfqParseResult.th, th_sfq, sizeof(struct tcphdr)); ++ SfqParseResult.pkt_type = IPV4_HNAPT; ++ //printk("tcp parsing\n"); ++ tcp_source_port = ntohs(SfqParseResult.th.source); ++ udp_source_port = 0; ++ #if(0) //for TCP ack, test use ++ if(ntohl(SfqParseResult.iph.saddr) == 0xa0a0a04){ // tcp ack packet ++ ack_packt = 1; ++ }else { ++ ack_packt = 0; ++ } ++ #endif ++ sfq_prot = 2;//IPV4_HNAPT ++ proto_id = 1;//TCP ++ if(iph_sfq->frag_off & htons(IP_MF|IP_OFFSET)) { ++ //return 1; ++ } ++ } else if (iph_sfq->protocol == IPPROTO_UDP) { ++ LAYER4_HEADER(skb) = ((uint8_t *) iph_sfq + iph_sfq->ihl * 4); ++ uh_sfq = (struct udphdr *)LAYER4_HEADER(skb); ++ memcpy(&SfqParseResult.uh, uh_sfq, sizeof(struct udphdr)); ++ SfqParseResult.pkt_type = IPV4_HNAPT; ++ udp_source_port = ntohs(SfqParseResult.uh.source); ++ tcp_source_port = 0; ++ ack_packt = 0; ++ sfq_prot = 2;//IPV4_HNAPT ++ proto_id =2;//UDP ++ if(iph_sfq->frag_off & htons(IP_MF|IP_OFFSET)) { ++ return 1; ++ } ++ }else{ ++ sfq_prot = 1; ++ } ++ }else if (SfqParseResult.eth_type == htons(ETH_P_IPV6) || ++ (SfqParseResult.eth_type == htons(ETH_P_PPP_SES) && ++ SfqParseResult.ppp_tag == htons(PPP_IPV6))) { ++ ip6h_sfq = (struct ipv6hdr *)LAYER3_HEADER(skb); ++ memcpy(&SfqParseResult.ip6h, ip6h_sfq, sizeof(struct ipv6hdr)); ++ ++ if (ip6h_sfq->nexthdr == NEXTHDR_TCP) { ++ LAYER4_HEADER(skb) = ((uint8_t *) ip6h_sfq + sizeof(struct ipv6hdr)); ++ th_sfq = (struct tcphdr *)LAYER4_HEADER(skb); ++ memcpy(&SfqParseResult.th, th_sfq, sizeof(struct tcphdr)); ++ SfqParseResult.pkt_type = IPV6_5T_ROUTE; ++ sfq_prot = 4;//IPV6_5T ++ #if(0) //for TCP ack, test use ++ if(ntohl(SfqParseResult.ip6h.saddr.s6_addr32[3]) == 8){ ++ ack_packt = 1; ++ }else { ++ ack_packt = 0; ++ } ++ #endif ++ } else if (ip6h_sfq->nexthdr == NEXTHDR_UDP) { ++ LAYER4_HEADER(skb) = ((uint8_t *) ip6h_sfq + sizeof(struct ipv6hdr)); ++ uh_sfq = (struct udphdr *)LAYER4_HEADER(skb); ++ memcpy(&SfqParseResult.uh, uh_sfq, sizeof(struct udphdr)); ++ SfqParseResult.pkt_type = IPV6_5T_ROUTE; ++ ack_packt = 0; ++ sfq_prot = 4;//IPV6_5T ++ ++ }else{ ++ sfq_prot = 3;//IPV6_3T ++ } ++ } ++ ++ return 0; ++} ++#endif ++ ++inline int rt2880_eth_send(struct net_device* dev, struct sk_buff *skb, int gmac_no) ++{ ++ unsigned int length=skb->len; ++ END_DEVICE* ei_local = netdev_priv(dev); ++ ++ struct QDMA_txdesc *cpu_ptr; ++ ++ struct QDMA_txdesc *dma_ptr __maybe_unused; ++ struct QDMA_txdesc *free_txd; ++ int ctx_offset; ++#if defined (CONFIG_RAETH_TSO) ++ struct iphdr *iph = NULL; ++ struct QDMA_txdesc *init_cpu_ptr; ++ struct tcphdr *th = NULL; ++ struct skb_frag_struct *frag; ++ unsigned int nr_frags = skb_shinfo(skb)->nr_frags; ++ unsigned int len, size, offset, frag_txd_num; ++ int init_txd_idx, i; ++#endif // CONFIG_RAETH_TSO // ++ ++#if defined (CONFIG_RAETH_TSOV6) ++ struct ipv6hdr *ip6h = NULL; ++#endif ++ ++#ifdef CONFIG_PSEUDO_SUPPORT ++ PSEUDO_ADAPTER *pAd; ++#endif ++ //cpu_ptr = PHYS_TO_VIRT(ei_local->tx_cpu_ptr); ++ //dma_ptr = PHYS_TO_VIRT(ei_local->tx_dma_ptr); ++ //ctx_offset = GET_TXD_OFFSET(&cpu_ptr); ++ cpu_ptr = (ei_local->tx_cpu_ptr); ++ ctx_offset = GET_TXD_OFFSET(&cpu_ptr); ++ cpu_ptr = phys_to_virt(ei_local->tx_cpu_ptr); ++ dma_ptr = phys_to_virt(ei_local->tx_dma_ptr); ++ cpu_ptr = (ei_local->txd_pool + (ctx_offset)); ++ ei_local->skb_free[ctx_offset] = skb; ++#if defined (CONFIG_RAETH_TSO) ++ init_cpu_ptr = cpu_ptr; ++ init_txd_idx = ctx_offset; ++#endif ++ ++#if !defined (CONFIG_RAETH_TSO) ++ ++ //2. prepare data ++ //cpu_ptr->txd_info1.SDP = VIRT_TO_PHYS(skb->data); ++ cpu_ptr->txd_info1.SDP = virt_to_phys(skb->data); ++ cpu_ptr->txd_info3.SDL = skb->len; ++#if defined (CONFIG_HW_SFQ) ++ SfqParseLayerInfo(skb); ++ cpu_ptr->txd_info4.VQID0 = 1;//1:HW hash 0:CPU ++ ++ ++#if(0)// for tcp ack use, test use ++ if (ack_packt==1){ ++ cpu_ptr->txd_info3.QID = 0x0a; ++ //cpu_ptr->txd_info3.VQID = 0; ++ }else{ ++ cpu_ptr->txd_info3.QID = 0; ++ } ++#endif ++ cpu_ptr->txd_info3.PROT = sfq_prot; ++ cpu_ptr->txd_info3.IPOFST = 14 + (SfqParseResult.vlan1_gap); //no vlan ++ ++#endif ++ if (gmac_no == 1) { ++ cpu_ptr->txd_info4.FPORT = 1; ++ }else { ++ cpu_ptr->txd_info4.FPORT = 2; ++ } ++ ++ cpu_ptr->txd_info3.QID = M2Q_table[skb->mark]; ++#ifdef CONFIG_PSEUDO_SUPPORT ++ if((lan_wan_separate==1) && (gmac_no==2)){ ++ cpu_ptr->txd_info3.QID += 8; ++#if defined (CONFIG_HW_SFQ) ++ if(web_sfq_enable==1 &&(skb->mark == 2)){ ++ cpu_ptr->txd_info3.QID = HwSfqQUp; ++ } ++#endif ++ } ++#if defined (CONFIG_HW_SFQ) ++ if((lan_wan_separate==1) && (gmac_no==1)){ ++ if(web_sfq_enable==1 &&(skb->mark == 2)){ ++ cpu_ptr->txd_info3.QID = HwSfqQDl; ++ } ++ } ++#endif ++#endif //end CONFIG_PSEUDO_SUPPORT ++ ++ if(dbg==1){ ++ printk("M2Q_table[%d]=%d\n", skb->mark, M2Q_table[skb->mark]); ++ printk("cpu_ptr->txd_info3.QID = %d\n", cpu_ptr->txd_info3.QID); ++ } ++#if 0 ++ iph = (struct iphdr *)skb_network_header(skb); ++ if (iph->tos == 0xe0) ++ cpu_ptr->txd_info3.QID = 3; ++ else if (iph->tos == 0xa0) ++ cpu_ptr->txd_info3.QID = 2; ++ else if (iph->tos == 0x20) ++ cpu_ptr->txd_info3.QID = 1; ++ else ++ cpu_ptr->txd_info3.QID = 0; ++#endif ++ ++#if defined (CONFIG_RAETH_CHECKSUM_OFFLOAD) && ! defined(CONFIG_RALINK_RT5350) && !defined (CONFIG_RALINK_MT7628) ++ if (skb->ip_summed == CHECKSUM_PARTIAL){ ++ cpu_ptr->txd_info4.TUI_CO = 7; ++ }else { ++ cpu_ptr->txd_info4.TUI_CO = 0; ++ } ++#endif ++ ++#ifdef CONFIG_RAETH_HW_VLAN_TX ++ if(vlan_tx_tag_present(skb)) { ++ cpu_ptr->txd_info4.VLAN_TAG = 0x10000 | vlan_tx_tag_get(skb); ++ }else { ++ cpu_ptr->txd_info4.VLAN_TAG = 0; ++ } ++#endif ++ ++#ifdef CONFIG_RAETH_HW_VLAN_TX // QoS Web UI used ++ ++ if((lan_wan_separate==1) && (vlan_tx_tag_get(skb)==2)){ ++ cpu_ptr->txd_info3.QID += 8; ++#if defined (CONFIG_HW_SFQ) ++ if(web_sfq_enable==1 &&(skb->mark == 2)){ ++ cpu_ptr->txd_info3.QID = HwSfqQUp; ++ } ++#endif ++ } ++#if defined (CONFIG_HW_SFQ) ++ if((lan_wan_separate==1) && (vlan_tx_tag_get(skb)==1)){ ++ if(web_sfq_enable==1 &&(skb->mark == 2)){ ++ cpu_ptr->txd_info3.QID = HwSfqQDl; ++ } ++ } ++#endif ++#endif // CONFIG_RAETH_HW_VLAN_TX ++ ++ ++//no hw van, no GE2, web UI used ++#ifndef CONFIG_PSEUDO_SUPPORT ++#ifndef CONFIG_RAETH_HW_VLAN_TX ++ if(lan_wan_separate==1){ ++ struct vlan_hdr *vh = NULL; ++ unsigned short vlanid = 0; ++ unsigned short vlan_TCI; ++ vh = (struct vlan_hdr *)(skb->data + ETH_HLEN); ++ vlan_TCI = vh->h_vlan_TCI; ++ vlanid = (vlan_TCI & VLAN_VID_MASK)>>8; ++ if(vlanid == 2)//to wan ++ { ++ cpu_ptr->txd_info3.QID += 8; ++#if defined (CONFIG_HW_SFQ) ++ if(web_sfq_enable==1 &&(skb->mark == 2)){ ++ cpu_ptr->txd_info3.QID = HwSfqQUp; ++ } ++#endif ++ }else if(vlanid == 1){ //to lan ++#if defined (CONFIG_HW_SFQ) ++ if(web_sfq_enable==1 &&(skb->mark == 2)){ ++ cpu_ptr->txd_info3.QID = HwSfqQDl; ++ } ++#endif ++ } ++ } ++#endif ++#endif ++#if defined (CONFIG_RA_HW_NAT) || defined (CONFIG_RA_HW_NAT_MODULE) ++ if(FOE_MAGIC_TAG(skb) == FOE_MAGIC_PPE) { ++ if(ra_sw_nat_hook_rx!= NULL){ ++ cpu_ptr->txd_info4.FPORT = 4; /* PPE */ ++ FOE_MAGIC_TAG(skb) = 0; ++ } ++ } ++#endif ++#if 0 ++ cpu_ptr->txd_info4.FPORT = 4; /* PPE */ ++ cpu_ptr->txd_info4.UDF = 0x2F; ++#endif ++ ++#if defined (CONFIG_MIPS) ++ dma_cache_sync(NULL, skb->data, skb->len, DMA_TO_DEVICE); ++#else ++ dma_sync_single_for_device(NULL, virt_to_phys(skb->data), skb->len, DMA_TO_DEVICE); ++#endif ++ cpu_ptr->txd_info3.SWC_bit = 1; ++ ++ //3. get NULL TXD and decrease free_tx_num by 1. ++ ctx_offset = get_free_txd(&free_txd); ++ if(ctx_offset == NUM_TX_DESC) { ++ printk("get_free_txd fail\n"); // this should not happen. free_txd_num is 2 at least. ++ return 0; ++ } ++ ++ //4. hook new TXD in the end of queue ++ //cpu_ptr->txd_info2.NDP = VIRT_TO_PHYS(free_txd); ++ cpu_ptr->txd_info2.NDP = (free_txd); ++ ++ ++ //5. move CPU_PTR to new TXD ++ //ei_local->tx_cpu_ptr = VIRT_TO_PHYS(free_txd); ++ ei_local->tx_cpu_ptr = (free_txd); ++ cpu_ptr->txd_info3.OWN_bit = 0; ++ sysRegWrite(QTX_CTX_PTR, ei_local->tx_cpu_ptr); ++ ++#if 0 ++ printk("----------------------------------------------\n"); ++ printk("txd_info1:%08X \n",*(int *)&cpu_ptr->txd_info1); ++ printk("txd_info2:%08X \n",*(int *)&cpu_ptr->txd_info2); ++ printk("txd_info3:%08X \n",*(int *)&cpu_ptr->txd_info3); ++ printk("txd_info4:%08X \n",*(int *)&cpu_ptr->txd_info4); ++#endif ++ ++#else //#if !defined (CONFIG_RAETH_TSO) ++ cpu_ptr->txd_info1.SDP = virt_to_phys(skb->data); ++ cpu_ptr->txd_info3.SDL = (length - skb->data_len); ++ cpu_ptr->txd_info3.LS_bit = nr_frags ? 0:1; ++#if defined (CONFIG_HW_SFQ) ++ SfqParseLayerInfo(skb); ++ // printk("tcp_source_port=%d\n", tcp_source_port); ++#if(0) ++ cpu_ptr->txd_info4.VQID0 = 0;//1:HW hash 0:CPU ++ if (tcp_source_port==1000) cpu_ptr->txd_info3.VQID = 0; ++ else if (tcp_source_port==1100) cpu_ptr->txd_info3.VQID = 1; ++ else if (tcp_source_port==1200) cpu_ptr->txd_info3.VQID = 2; ++ else cpu_ptr->txd_info3.VQID = 0; ++ #else ++ cpu_ptr->txd_info4.VQID0 = 1; ++ cpu_ptr->txd_info3.PROT = sfq_prot; ++ cpu_ptr->txd_info3.IPOFST = 14 + (SfqParseResult.vlan1_gap); //no vlan ++#endif ++#endif ++ if (gmac_no == 1) { ++ cpu_ptr->txd_info4.FPORT = 1; ++ }else { ++ cpu_ptr->txd_info4.FPORT = 2; ++ } ++ ++ cpu_ptr->txd_info4.TSO = 0; ++ cpu_ptr->txd_info3.QID = M2Q_table[skb->mark]; ++#ifdef CONFIG_PSEUDO_SUPPORT //web UI used tso ++ if((lan_wan_separate==1) && (gmac_no==2)){ ++ cpu_ptr->txd_info3.QID += 8; ++#if defined (CONFIG_HW_SFQ) ++ if(web_sfq_enable == 1 &&(skb->mark == 2)){ ++ cpu_ptr->txd_info3.QID = HwSfqQUp; ++ } ++#endif ++ } ++#if defined (CONFIG_HW_SFQ) ++ if((lan_wan_separate==1) && (gmac_no==1)){ ++ if(web_sfq_enable==1 &&(skb->mark == 2)){ ++ cpu_ptr->txd_info3.QID = HwSfqQDl; ++ } ++ } ++#endif ++#endif //CONFIG_PSEUDO_SUPPORT ++ if(dbg==1){ ++ printk("M2Q_table[%d]=%d\n", skb->mark, M2Q_table[skb->mark]); ++ printk("cpu_ptr->txd_info3.QID = %d\n", cpu_ptr->txd_info3.QID); ++ } ++#if defined (CONFIG_RAETH_CHECKSUM_OFFLOAD) && ! defined(CONFIG_RALINK_RT5350) && !defined (CONFIG_RALINK_MT7628) ++ if (skb->ip_summed == CHECKSUM_PARTIAL){ ++ cpu_ptr->txd_info4.TUI_CO = 7; ++ }else { ++ cpu_ptr->txd_info4.TUI_CO = 0; ++ } ++#endif ++ ++#ifdef CONFIG_RAETH_HW_VLAN_TX ++ if(vlan_tx_tag_present(skb)) { ++ cpu_ptr->txd_info4.VLAN_TAG = 0x10000 | vlan_tx_tag_get(skb); ++ }else { ++ cpu_ptr->txd_info4.VLAN_TAG = 0; ++ } ++#endif ++#ifdef CONFIG_RAETH_HW_VLAN_TX // QoS Web UI used tso ++ ++ if((lan_wan_separate==1) && (vlan_tx_tag_get(skb)==2)){ ++ //cpu_ptr->txd_info3.QID += 8; ++ cpu_ptr->txd_info3.QID += 8; ++#if defined (CONFIG_HW_SFQ) ++ if(web_sfq_enable==1 &&(skb->mark == 2)){ ++ cpu_ptr->txd_info3.QID = HwSfqQUp; ++ } ++#endif ++ } ++#if defined (CONFIG_HW_SFQ) ++ if((lan_wan_separate==1) && (vlan_tx_tag_get(skb)==1)){ ++ if(web_sfq_enable==1 &&(skb->mark == 2)){ ++ cpu_ptr->txd_info3.QID = HwSfqQDl; ++ } ++ } ++#endif ++#endif // CONFIG_RAETH_HW_VLAN_TX ++ ++ ++//no hw van, no GE2, web UI used ++#ifndef CONFIG_PSEUDO_SUPPORT ++#ifndef CONFIG_RAETH_HW_VLAN_TX ++ if(lan_wan_separate==1){ ++ struct vlan_hdr *vh = NULL; ++ unsigned short vlanid = 0; ++ unsigned short vlan_TCI; ++ vh = (struct vlan_hdr *)(skb->data + ETH_HLEN); ++ vlan_TCI = vh->h_vlan_TCI; ++ vlanid = (vlan_TCI & VLAN_VID_MASK)>>8; ++ if(vlanid == 2)//eth2.2 to wan ++ { ++ cpu_ptr->txd_info3.QID += 8; ++#if defined (CONFIG_HW_SFQ) ++ if(web_sfq_enable==1 &&(skb->mark == 2)){ ++ cpu_ptr->txd_info3.QID = HwSfqQUp; ++ } ++#endif ++ }else if(!strcmp(netdev, "eth2.1")){ // eth2.1 to lan ++#if defined (CONFIG_HW_SFQ) ++ if(web_sfq_enable==1 &&(skb->mark == 2)){ ++ cpu_ptr->txd_info3.QID = HwSfqQDl; ++ } ++#endif ++ } ++} ++#endif ++#endif ++ ++#if defined (CONFIG_RA_HW_NAT) || defined (CONFIG_RA_HW_NAT_MODULE) ++ if(FOE_MAGIC_TAG(skb) == FOE_MAGIC_PPE) { ++ if(ra_sw_nat_hook_rx!= NULL){ ++ cpu_ptr->txd_info4.FPORT = 4; /* PPE */ ++ FOE_MAGIC_TAG(skb) = 0; ++ } ++ } ++#endif ++ ++ cpu_ptr->txd_info3.SWC_bit = 1; ++ ++ ctx_offset = get_free_txd(&free_txd); ++ if(ctx_offset == NUM_TX_DESC) { ++ printk("get_free_txd fail\n"); ++ return 0; ++ } ++ //cpu_ptr->txd_info2.NDP = VIRT_TO_PHYS(free_txd); ++ //ei_local->tx_cpu_ptr = VIRT_TO_PHYS(free_txd); ++ cpu_ptr->txd_info2.NDP = free_txd; ++ ei_local->tx_cpu_ptr = free_txd; ++ ++ ++ if(nr_frags > 0) { ++ for(i=0;i<nr_frags;i++) { ++ // 1. set or get init value for current fragment ++ offset = 0; ++ frag = &skb_shinfo(skb)->frags[i]; ++ len = frag->size; ++ frag_txd_num = cal_frag_txd_num(len); // calculate the needed TXD numbers for this fragment ++ for(frag_txd_num = frag_txd_num;frag_txd_num > 0; frag_txd_num --){ ++ // 2. size will be assigned to SDL and can't be larger than MAX_TXD_LEN ++ if(len < MAX_TXD_LEN) ++ size = len; ++ else ++ size = MAX_TXD_LEN; ++ ++ //3. Update TXD info ++ cpu_ptr = (ei_local->txd_pool + (ctx_offset)); ++ cpu_ptr->txd_info3.QID = M2Q_table[skb->mark]; ++#ifdef CONFIG_PSEUDO_SUPPORT //QoS Web UI used , nr_frags ++ if((lan_wan_separate==1) && (gmac_no==2)){ ++ //cpu_ptr->txd_info3.QID += 8; ++ cpu_ptr->txd_info3.QID += 8; ++#if defined (CONFIG_HW_SFQ) ++ if(web_sfq_enable==1 &&(skb->mark == 2)){ ++ cpu_ptr->txd_info3.QID = HwSfqQUp; ++ } ++#endif ++ } ++#if defined (CONFIG_HW_SFQ) ++ if((lan_wan_separate==1) && (gmac_no==1)){ ++ if(web_sfq_enable==1 &&(skb->mark == 2)){ ++ cpu_ptr->txd_info3.QID = HwSfqQDl; ++ } ++ } ++#endif ++#endif //CONFIG_PSEUDO_SUPPORT ++ ++//QoS web used, nr_frags ++#ifdef CONFIG_RAETH_HW_VLAN_TX ++ if((lan_wan_separate==1) && (vlan_tx_tag_get(skb)==2)){ ++ cpu_ptr->txd_info3.QID += 8; ++#if defined (CONFIG_HW_SFQ) ++ if(web_sfq_enable==1 &&(skb->mark == 2)){ ++ cpu_ptr->txd_info3.QID = HwSfqQUp; ++ } ++#endif ++ } ++#if defined (CONFIG_HW_SFQ) ++ if((lan_wan_separate==1) && (vlan_tx_tag_get(skb)==1)){ ++ if(web_sfq_enable==1 &&(skb->mark == 2)){ ++ cpu_ptr->txd_info3.QID = HwSfqQDl; ++ } ++ } ++#endif ++#endif // CONFIG_RAETH_HW_VLAN_TX ++//no hw van, no GE2, web UI used ++#ifndef CONFIG_PSEUDO_SUPPORT ++#ifndef CONFIG_RAETH_HW_VLAN_TX ++ if(lan_wan_separate==1){ ++ struct vlan_hdr *vh = NULL; ++ unsigned short vlanid = 0; ++ unsigned short vlan_TCI; ++ vh = (struct vlan_hdr *)(skb->data + ETH_HLEN); ++ vlan_TCI = vh->h_vlan_TCI; ++ vlanid = (vlan_TCI & VLAN_VID_MASK)>>8; ++ if(vlanid == 2))//eth2.2 to wan ++ { ++ cpu_ptr->txd_info3.QID += 8; ++#if defined (CONFIG_HW_SFQ) ++ if(web_sfq_enable==1 &&(skb->mark == 2)){ ++ cpu_ptr->txd_info3.QID = HwSfqQUp; ++ } ++#endif ++ } ++ }else if(vlanid == 1){ // eth2.1 to lan ++#if defined (CONFIG_HW_SFQ) ++ if(web_sfq_enable==1 &&(skb->mark == 2)){ ++ cpu_ptr->txd_info3.QID = HwSfqQDl; ++ } ++#endif ++ } ++ } ++#endif ++#endif ++ if(dbg==1){ ++ printk("M2Q_table[%d]=%d\n", skb->mark, M2Q_table[skb->mark]); ++ printk("cpu_ptr->txd_info3.QID = %d\n", cpu_ptr->txd_info3.QID); ++ } ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) ++ cpu_ptr->txd_info1.SDP = pci_map_page(NULL, frag->page, frag->page_offset, frag->size, PCI_DMA_TODEVICE); ++#else ++ cpu_ptr->txd_info1.SDP = pci_map_page(NULL, frag->page.p, frag->page_offset + offset, size, PCI_DMA_TODEVICE); ++// printk(" frag->page = %08x. frag->page_offset = %08x. frag->size = % 08x.\n", frag->page, (frag->page_offset+offset), size); ++#endif ++ cpu_ptr->txd_info3.SDL = size; ++ if( (i==(nr_frags-1)) && (frag_txd_num == 1)) ++ cpu_ptr->txd_info3.LS_bit = 1; ++ else ++ cpu_ptr->txd_info3.LS_bit = 0; ++ cpu_ptr->txd_info3.OWN_bit = 0; ++ cpu_ptr->txd_info3.SWC_bit = 1; ++ //4. Update skb_free for housekeeping ++ ei_local->skb_free[ctx_offset] = (cpu_ptr->txd_info3.LS_bit == 1)?skb:(struct sk_buff *)0xFFFFFFFF; //MAGIC ID ++ ++ //5. Get next TXD ++ ctx_offset = get_free_txd(&free_txd); ++ //cpu_ptr->txd_info2.NDP = VIRT_TO_PHYS(free_txd); ++ //ei_local->tx_cpu_ptr = VIRT_TO_PHYS(free_txd); ++ cpu_ptr->txd_info2.NDP = free_txd; ++ ei_local->tx_cpu_ptr = free_txd; ++ //6. Update offset and len. ++ offset += size; ++ len -= size; ++ } ++ } ++ ei_local->skb_free[init_txd_idx]= (struct sk_buff *)0xFFFFFFFF; //MAGIC ID ++ } ++ ++ if(skb_shinfo(skb)->gso_segs > 1) { ++ ++// TsoLenUpdate(skb->len); ++ ++ /* TCP over IPv4 */ ++ iph = (struct iphdr *)skb_network_header(skb); ++#if defined (CONFIG_RAETH_TSOV6) ++ /* TCP over IPv6 */ ++ ip6h = (struct ipv6hdr *)skb_network_header(skb); ++#endif ++ if((iph->version == 4) && (iph->protocol == IPPROTO_TCP)) { ++ th = (struct tcphdr *)skb_transport_header(skb); ++#if defined (CONFIG_HW_SFQ) ++#if(0) ++ init_cpu_ptr->txd_info4.VQID0 = 0;//1:HW hash 0:CPU ++ if (tcp_source_port==1000) init_cpu_ptr->txd_info3.VQID = 0; ++ else if (tcp_source_port==1100) init_cpu_ptr->txd_info3.VQID = 1; ++ else if (tcp_source_port==1200) init_cpu_ptr->txd_info3.VQID = 2; ++ else cpu_ptr->txd_info3.VQID = 0; ++ #else ++ init_cpu_ptr->txd_info4.VQID0 = 1; ++ init_cpu_ptr->txd_info3.PROT = sfq_prot; ++ init_cpu_ptr->txd_info3.IPOFST = 14 + (SfqParseResult.vlan1_gap); //no vlan ++#endif ++#endif ++ init_cpu_ptr->txd_info4.TSO = 1; ++ ++ th->check = htons(skb_shinfo(skb)->gso_size); ++#if defined (CONFIG_MIPS) ++ dma_cache_sync(NULL, th, sizeof(struct tcphdr), DMA_TO_DEVICE); ++#else ++ dma_sync_single_for_device(NULL, virt_to_phys(th), sizeof(struct tcphdr), DMA_TO_DEVICE); ++#endif ++ } ++ ++#if defined (CONFIG_RAETH_TSOV6) ++ /* TCP over IPv6 */ ++ //ip6h = (struct ipv6hdr *)skb_network_header(skb); ++ else if ((ip6h->version == 6) && (ip6h->nexthdr == NEXTHDR_TCP)) { ++ th = (struct tcphdr *)skb_transport_header(skb); ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ init_cpu_ptr->txd_info4.TSO = 1; ++#else ++ init_cpu_ptr->txd_info4.TSO = 1; ++#endif ++ th->check = htons(skb_shinfo(skb)->gso_size); ++#if defined (CONFIG_MIPS) ++ dma_cache_sync(NULL, th, sizeof(struct tcphdr), DMA_TO_DEVICE); ++#else ++ dma_sync_single_for_device(NULL, virt_to_phys(th), sizeof(struct tcphdr), DMA_TO_DEVICE); ++#endif ++ } ++#endif ++ } ++ ++ ++// dma_cache_sync(NULL, skb->data, skb->len, DMA_TO_DEVICE); ++ ++ init_cpu_ptr->txd_info3.OWN_bit = 0; ++#endif // CONFIG_RAETH_TSO // ++ ++ sysRegWrite(QTX_CTX_PTR, ei_local->tx_cpu_ptr); ++ ++#ifdef CONFIG_PSEUDO_SUPPORT ++ if (gmac_no == 2) { ++ if (ei_local->PseudoDev != NULL) { ++ pAd = netdev_priv(ei_local->PseudoDev); ++ pAd->stat.tx_packets++; ++ pAd->stat.tx_bytes += length; ++ } ++ } else ++ ++#endif ++ { ++ ei_local->stat.tx_packets++; ++ ei_local->stat.tx_bytes += skb->len; ++ } ++#ifdef CONFIG_RAETH_NAPI ++ if ( ei_local->tx_full == 1) { ++ ei_local->tx_full = 0; ++ netif_wake_queue(dev); ++ } ++#endif ++ ++ return length; ++} ++ ++int ei_start_xmit(struct sk_buff* skb, struct net_device *dev, int gmac_no) ++{ ++ END_DEVICE *ei_local = netdev_priv(dev); ++ unsigned long flags; ++ unsigned int num_of_txd = 0; ++#if defined (CONFIG_RAETH_TSO) ++ unsigned int nr_frags = skb_shinfo(skb)->nr_frags, i; ++ struct skb_frag_struct *frag; ++#endif ++#ifdef CONFIG_PSEUDO_SUPPORT ++ PSEUDO_ADAPTER *pAd; ++#endif ++ ++#if !defined(CONFIG_RA_NAT_NONE) ++ if(ra_sw_nat_hook_tx!= NULL) ++ { ++// spin_lock_irqsave(&ei_local->page_lock, flags); ++ if(ra_sw_nat_hook_tx(skb, gmac_no)==1){ ++// spin_unlock_irqrestore(&ei_local->page_lock, flags); ++ }else{ ++ kfree_skb(skb); ++// spin_unlock_irqrestore(&ei_local->page_lock, flags); ++ return 0; ++ } ++ } ++#endif ++ ++ ++ ++ dev->trans_start = jiffies; /* save the timestamp */ ++ spin_lock_irqsave(&ei_local->page_lock, flags); ++#if defined (CONFIG_MIPS) ++ dma_cache_sync(NULL, skb->data, skb->len, DMA_TO_DEVICE); ++#else ++ dma_sync_single_for_device(NULL, virt_to_phys(skb->data), skb->len, DMA_TO_DEVICE); ++#endif ++ ++ ++//check free_txd_num before calling rt288_eth_send() ++ ++#if defined (CONFIG_RAETH_TSO) ++ // num_of_txd = (nr_frags==0) ? 1 : (nr_frags + 1); ++ if(nr_frags != 0){ ++ for(i=0;i<nr_frags;i++) { ++ frag = &skb_shinfo(skb)->frags[i]; ++ num_of_txd += cal_frag_txd_num(frag->size); ++ } ++ }else ++ num_of_txd = 1; ++#else ++ num_of_txd = 1; ++#endif ++ ++#if defined(CONFIG_RALINK_MT7621) ++ if((sysRegRead(0xbe00000c)&0xFFFF) == 0x0101) { ++ ei_xmit_housekeeping(0); ++ } ++#endif ++ ++ ++ if ((ei_local->free_txd_num > num_of_txd + 1) && (ei_local->free_txd_num != NUM_TX_DESC)) ++ { ++ rt2880_eth_send(dev, skb, gmac_no); // need to modify rt2880_eth_send() for QDMA ++ if (ei_local->free_txd_num < 3) ++ { ++#if defined (CONFIG_RAETH_STOP_RX_WHEN_TX_FULL) ++ netif_stop_queue(dev); ++#ifdef CONFIG_PSEUDO_SUPPORT ++ netif_stop_queue(ei_local->PseudoDev); ++#endif ++ tx_ring_full = 1; ++#endif ++ } ++ } else { ++#ifdef CONFIG_PSEUDO_SUPPORT ++ if (gmac_no == 2) ++ { ++ if (ei_local->PseudoDev != NULL) ++ { ++ pAd = netdev_priv(ei_local->PseudoDev); ++ pAd->stat.tx_dropped++; ++ } ++ } else ++#endif ++ ei_local->stat.tx_dropped++; ++ kfree_skb(skb); ++ spin_unlock_irqrestore(&ei_local->page_lock, flags); ++ return 0; ++ } ++ spin_unlock_irqrestore(&ei_local->page_lock, flags); ++ return 0; ++} ++ ++void ei_xmit_housekeeping(unsigned long unused) ++{ ++ struct net_device *dev = dev_raether; ++ END_DEVICE *ei_local = netdev_priv(dev); ++#ifndef CONFIG_RAETH_NAPI ++ unsigned long reg_int_mask=0; ++#endif ++ struct QDMA_txdesc *dma_ptr = NULL; ++ struct QDMA_txdesc *cpu_ptr = NULL; ++ struct QDMA_txdesc *tmp_ptr = NULL; ++ unsigned int ctx_offset = 0; ++ unsigned int dtx_offset = 0; ++ ++ cpu_ptr = sysRegRead(QTX_CRX_PTR); ++ dma_ptr = sysRegRead(QTX_DRX_PTR); ++ ctx_offset = GET_TXD_OFFSET(&cpu_ptr); ++ dtx_offset = GET_TXD_OFFSET(&dma_ptr); ++ cpu_ptr = (ei_local->txd_pool + (ctx_offset)); ++ dma_ptr = (ei_local->txd_pool + (dtx_offset)); ++ ++ while(cpu_ptr != dma_ptr && (cpu_ptr->txd_info3.OWN_bit == 1)) { ++ //1. keep cpu next TXD ++ tmp_ptr = cpu_ptr->txd_info2.NDP; ++ //2. release TXD ++ put_free_txd(ctx_offset); ++ //3. update ctx_offset and free skb memory ++ ctx_offset = GET_TXD_OFFSET(&tmp_ptr); ++#if defined (CONFIG_RAETH_TSO) ++ if(ei_local->skb_free[ctx_offset]!=(struct sk_buff *)0xFFFFFFFF) { ++ dev_kfree_skb_any(ei_local->skb_free[ctx_offset]); ++ } ++#else ++ dev_kfree_skb_any(ei_local->skb_free[ctx_offset]); ++#endif ++ ei_local->skb_free[ctx_offset] = 0; ++ ++ netif_wake_queue(dev); ++#ifdef CONFIG_PSEUDO_SUPPORT ++ netif_wake_queue(ei_local->PseudoDev); ++#endif ++ tx_ring_full=0; ++ //4. update cpu_ptr ++ cpu_ptr = (ei_local->txd_pool + ctx_offset); ++ } ++ sysRegWrite(QTX_CRX_PTR, (ei_local->phy_txd_pool + (ctx_offset << 4))); ++#ifndef CONFIG_RAETH_NAPI ++ reg_int_mask=sysRegRead(QFE_INT_ENABLE); ++#if defined (DELAY_INT) ++ sysRegWrite(QFE_INT_ENABLE, reg_int_mask| RLS_DLY_INT); ++#else ++ ++ sysRegWrite(QFE_INT_ENABLE, reg_int_mask | RLS_DONE_INT); ++#endif ++#endif //CONFIG_RAETH_NAPI// ++} ++ ++EXPORT_SYMBOL(ei_start_xmit); ++EXPORT_SYMBOL(ei_xmit_housekeeping); ++EXPORT_SYMBOL(fe_dma_init); ++EXPORT_SYMBOL(rt2880_eth_send); +diff --git a/drivers/net/ethernet/raeth/raether_qdma_mt7623.c b/drivers/net/ethernet/raeth/raether_qdma_mt7623.c +new file mode 100644 +index 0000000..b465b75 +--- /dev/null ++++ b/drivers/net/ethernet/raeth/raether_qdma_mt7623.c +@@ -0,0 +1,1020 @@ ++#include <linux/module.h> ++#include <linux/version.h> ++#include <linux/kernel.h> ++#include <linux/types.h> ++#include <linux/pci.h> ++#include <linux/init.h> ++#include <linux/skbuff.h> ++#include <linux/if_vlan.h> ++#include <linux/if_ether.h> ++#include <linux/fs.h> ++#include <asm/uaccess.h> ++#include <asm/rt2880/surfboardint.h> ++#if defined (CONFIG_RAETH_TSO) ++#include <linux/tcp.h> ++#include <net/ipv6.h> ++#include <linux/ip.h> ++#include <net/ip.h> ++#include <net/tcp.h> ++#include <linux/in.h> ++#include <linux/ppp_defs.h> ++#include <linux/if_pppox.h> ++#endif ++#include <linux/delay.h> ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++#include <linux/sched.h> ++#endif ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0) ++#include <asm/rt2880/rt_mmap.h> ++#else ++#include <linux/libata-compat.h> ++#endif ++ ++#include "ra2882ethreg.h" ++#include "raether.h" ++#include "ra_mac.h" ++#include "ra_ioctl.h" ++#include "ra_rfrw.h" ++#ifdef CONFIG_RAETH_NETLINK ++#include "ra_netlink.h" ++#endif ++#if defined (CONFIG_RAETH_QOS) ++#include "ra_qos.h" ++#endif ++ ++#if defined (CONFIG_RA_HW_NAT) || defined (CONFIG_RA_HW_NAT_MODULE) ++#include "../../../net/nat/hw_nat/ra_nat.h" ++#endif ++ ++ ++#if !defined(CONFIG_RA_NAT_NONE) ++/* bruce+ ++ */ ++extern int (*ra_sw_nat_hook_rx)(struct sk_buff *skb); ++extern int (*ra_sw_nat_hook_tx)(struct sk_buff *skb, int gmac_no); ++#endif ++ ++#if defined(CONFIG_RA_CLASSIFIER)||defined(CONFIG_RA_CLASSIFIER_MODULE) ++/* Qwert+ ++ */ ++#include <asm/mipsregs.h> ++extern int (*ra_classifier_hook_tx)(struct sk_buff *skb, unsigned long cur_cycle); ++extern int (*ra_classifier_hook_rx)(struct sk_buff *skb, unsigned long cur_cycle); ++#endif /* CONFIG_RA_CLASSIFIER */ ++ ++#if defined (CONFIG_RALINK_RT3052_MP2) ++int32_t mcast_rx(struct sk_buff * skb); ++int32_t mcast_tx(struct sk_buff * skb); ++#endif ++ ++#ifdef RA_MTD_RW_BY_NUM ++int ra_mtd_read(int num, loff_t from, size_t len, u_char *buf); ++#else ++int ra_mtd_read_nm(char *name, loff_t from, size_t len, u_char *buf); ++#endif ++ ++/* gmac driver feature set config */ ++#if defined (CONFIG_RAETH_NAPI) || defined (CONFIG_RAETH_QOS) ++#undef DELAY_INT ++#else ++#define DELAY_INT 1 ++#endif ++ ++//#define CONFIG_UNH_TEST ++/* end of config */ ++ ++#if defined (CONFIG_RAETH_JUMBOFRAME) ++#define MAX_RX_LENGTH 4096 ++#else ++#define MAX_RX_LENGTH 1536 ++#endif ++ ++extern struct net_device *dev_raether; ++ ++#if defined (CONFIG_RAETH_MULTIPLE_RX_RING) ++static int rx_dma_owner_idx1; ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++static int rx_calc_idx1; ++#endif ++#endif ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++static int rx_calc_idx0; ++static unsigned long tx_cpu_owner_idx0=0; ++#endif ++static unsigned long tx_ring_full=0; ++ ++#if defined (CONFIG_ETHTOOL) && defined (CONFIG_RAETH_ROUTER) ++#include "ra_ethtool.h" ++extern struct ethtool_ops ra_ethtool_ops; ++#ifdef CONFIG_PSEUDO_SUPPORT ++extern struct ethtool_ops ra_virt_ethtool_ops; ++#endif // CONFIG_PSEUDO_SUPPORT // ++#endif // (CONFIG_ETHTOOL // ++ ++#ifdef CONFIG_RALINK_VISTA_BASIC ++int is_switch_175c = 1; ++#endif ++ ++//skb->mark to queue mapping table ++extern unsigned int M2Q_table[64]; ++ ++ ++#define KSEG1 0xa0000000 ++#if defined (CONFIG_MIPS) ++#define PHYS_TO_VIRT(x) ((void *)((x) | KSEG1)) ++#define VIRT_TO_PHYS(x) ((unsigned long)(x) & ~KSEG1) ++#else ++#define PHYS_TO_VIRT(x) phys_to_virt(x) ++#define VIRT_TO_PHYS(x) virt_to_phys(x) ++#endif ++ ++ ++extern void set_fe_dma_glo_cfg(void); ++ ++ ++/** ++ * ++ * @brief: get the TXD index from its address ++ * ++ * @param: cpu_ptr ++ * ++ * @return: TXD index ++*/ ++ ++static unsigned int GET_TXD_OFFSET(struct QDMA_txdesc **cpu_ptr) ++{ ++ struct net_device *dev = dev_raether; ++ END_DEVICE *ei_local = netdev_priv(dev); ++ int ctx_offset; ++ //ctx_offset = (((((u32)*cpu_ptr) <<8)>>8) - ((((u32)ei_local->txd_pool)<<8)>>8))/ sizeof(struct QDMA_txdesc); ++ //ctx_offset = (*cpu_ptr - ei_local->txd_pool); ++ /*kurtis*/ ++ ctx_offset = (((((u32)*cpu_ptr) <<8)>>8) - ((((u32)ei_local->phy_txd_pool)<<8)>>8))/ sizeof(struct QDMA_txdesc); ++ return ctx_offset; ++} ++ ++ ++ ++ ++/** ++ * @brief cal txd number for a page ++ * ++ * @parm size ++ * ++ * @return frag_txd_num ++ */ ++ ++unsigned int cal_frag_txd_num(unsigned int size) ++{ ++ unsigned int frag_txd_num = 0; ++ if(size == 0) ++ return 0; ++ while(size > 0){ ++ if(size > MAX_TXD_LEN){ ++ frag_txd_num++; ++ size -= MAX_TXD_LEN; ++ }else{ ++ frag_txd_num++; ++ size = 0; ++ } ++ } ++ return frag_txd_num; ++ ++} ++ ++/** ++ * @brief get free TXD from TXD queue ++ * ++ * @param free_txd ++ * ++ * @return ++ */ ++static int get_free_txd(struct QDMA_txdesc **free_txd) ++{ ++ struct net_device *dev = dev_raether; ++ END_DEVICE *ei_local = netdev_priv(dev); ++ unsigned int tmp_idx; ++ ++ if(ei_local->free_txd_num > 0){ ++ tmp_idx = ei_local->free_txd_head; ++ ei_local->free_txd_head = ei_local->txd_pool_info[tmp_idx]; ++ ei_local->free_txd_num -= 1; ++ //*free_txd = &ei_local->txd_pool[tmp_idx]; ++ *free_txd = ei_local->phy_txd_pool + (sizeof(struct QDMA_txdesc) * tmp_idx); ++ return tmp_idx; ++ }else ++ return NUM_TX_DESC; ++} ++ ++ ++/** ++ * @brief add free TXD into TXD queue ++ * ++ * @param free_txd ++ * ++ * @return ++ */ ++int put_free_txd(int free_txd_idx) ++{ ++ struct net_device *dev = dev_raether; ++ END_DEVICE *ei_local = netdev_priv(dev); ++ ei_local->txd_pool_info[ei_local->free_txd_tail] = free_txd_idx; ++ ei_local->free_txd_tail = free_txd_idx; ++ ei_local->txd_pool_info[free_txd_idx] = NUM_TX_DESC; ++ ei_local->free_txd_num += 1; ++ return 1; ++} ++ ++/*define qdma initial alloc*/ ++/** ++ * @brief ++ * ++ * @param net_dev ++ * ++ * @return 0: fail ++ * 1: success ++ */ ++bool qdma_tx_desc_alloc(void) ++{ ++ struct net_device *dev = dev_raether; ++ END_DEVICE *ei_local = netdev_priv(dev); ++ struct QDMA_txdesc *free_txd = NULL; ++ unsigned int txd_idx; ++ int i = 0; ++ ++ ++ ei_local->txd_pool = pci_alloc_consistent(NULL, sizeof(struct QDMA_txdesc) * NUM_TX_DESC, &ei_local->phy_txd_pool); ++ printk("txd_pool=%p phy_txd_pool=%08X\n", ei_local->txd_pool , ei_local->phy_txd_pool); ++ ++ if (ei_local->txd_pool == NULL) { ++ printk("adapter->txd_pool allocation failed!\n"); ++ return 0; ++ } ++ printk("ei_local->skb_free start address is 0x%p.\n", ei_local->skb_free); ++ //set all txd_pool_info to 0. ++ for ( i = 0; i < NUM_TX_DESC; i++) ++ { ++ ei_local->skb_free[i]= 0; ++ ei_local->txd_pool_info[i] = i + 1; ++ ei_local->txd_pool[i].txd_info3.LS_bit = 1; ++ ei_local->txd_pool[i].txd_info3.OWN_bit = 1; ++ } ++ ++ ei_local->free_txd_head = 0; ++ ei_local->free_txd_tail = NUM_TX_DESC - 1; ++ ei_local->free_txd_num = NUM_TX_DESC; ++ ++ ++ //get free txd from txd pool ++ txd_idx = get_free_txd(&free_txd); ++ if( txd_idx == NUM_TX_DESC) { ++ printk("get_free_txd fail\n"); ++ return 0; ++ } ++ ++ //add null TXD for transmit ++ ++ /*kurtis test*/ ++ ei_local->tx_dma_ptr = free_txd; ++ ei_local->tx_cpu_ptr = free_txd; ++ //ei_local->tx_dma_ptr = virt_to_phys(free_txd); ++ //ei_local->tx_cpu_ptr = virt_to_phys(free_txd); ++ sysRegWrite(QTX_CTX_PTR, ei_local->tx_cpu_ptr); ++ sysRegWrite(QTX_DTX_PTR, ei_local->tx_dma_ptr); ++ ++ printk("kurtis: free_txd = 0x%x!!!\n", free_txd); ++ printk("kurtis: ei_local->tx_dma_ptr = 0x%x!!!\n", ei_local->tx_dma_ptr); ++ ++ //get free txd from txd pool ++ ++ txd_idx = get_free_txd(&free_txd); ++ if( txd_idx == NUM_TX_DESC) { ++ printk("get_free_txd fail\n"); ++ return 0; ++ } ++ // add null TXD for release ++ //sysRegWrite(QTX_CRX_PTR, virt_to_phys(free_txd)); ++ //sysRegWrite(QTX_DRX_PTR, virt_to_phys(free_txd)); ++ sysRegWrite(QTX_CRX_PTR, free_txd); ++ sysRegWrite(QTX_DRX_PTR, free_txd); ++ ++ printk("free_txd: %p, ei_local->cpu_ptr: %08X\n", free_txd, ei_local->tx_cpu_ptr); ++ ++ printk(" POOL HEAD_PTR | DMA_PTR | CPU_PTR \n"); ++ printk("----------------+---------+--------\n"); ++#if 1 ++ printk(" 0x%p 0x%08X 0x%08X\n",ei_local->txd_pool, ++ ei_local->tx_dma_ptr, ei_local->tx_cpu_ptr); ++#endif ++ return 1; ++} ++ ++bool fq_qdma_init(void) ++{ ++ struct QDMA_txdesc *free_head = NULL; ++ unsigned int free_head_phy; ++ unsigned int free_tail_phy; ++ unsigned int *free_page_head = NULL; ++ unsigned int free_page_head_phy; ++ int i; ++ ++ free_head = pci_alloc_consistent(NULL, NUM_QDMA_PAGE * sizeof(struct QDMA_txdesc), &free_head_phy); ++ if (unlikely(free_head == NULL)){ ++ printk(KERN_ERR "QDMA FQ decriptor not available...\n"); ++ return 0; ++ } ++ memset(free_head, 0x0, sizeof(struct QDMA_txdesc) * NUM_QDMA_PAGE); ++ ++ free_page_head = pci_alloc_consistent(NULL, NUM_QDMA_PAGE * QDMA_PAGE_SIZE, &free_page_head_phy); ++ if (unlikely(free_page_head == NULL)){ ++ printk(KERN_ERR "QDMA FQ pager not available...\n"); ++ return 0; ++ } ++ for (i=0; i < NUM_QDMA_PAGE; i++) { ++ free_head[i].txd_info1.SDP = (free_page_head_phy + (i * QDMA_PAGE_SIZE)); ++ if(i < (NUM_QDMA_PAGE-1)){ ++ free_head[i].txd_info2.NDP = (free_head_phy + ((i+1) * sizeof(struct QDMA_txdesc))); ++ ++ ++#if 0 ++ printk("free_head_phy[%d] is 0x%x!!!\n",i, VIRT_TO_PHYS(&free_head[i]) ); ++ printk("free_head[%d] is 0x%x!!!\n",i, &free_head[i] ); ++ printk("free_head[%d].txd_info1.SDP is 0x%x!!!\n",i, free_head[i].txd_info1.SDP ); ++ printk("free_head[%d].txd_info2.NDP is 0x%x!!!\n",i, free_head[i].txd_info2.NDP ); ++#endif ++ } ++ free_head[i].txd_info3.SDL = QDMA_PAGE_SIZE; ++ ++ } ++ free_tail_phy = (free_head_phy + (u32)((NUM_QDMA_PAGE-1) * sizeof(struct QDMA_txdesc))); ++ ++ printk("free_head_phy is 0x%x!!!\n", free_head_phy); ++ printk("free_tail_phy is 0x%x!!!\n", free_tail_phy); ++ sysRegWrite(QDMA_FQ_HEAD, (u32)free_head_phy); ++ sysRegWrite(QDMA_FQ_TAIL, (u32)free_tail_phy); ++ sysRegWrite(QDMA_FQ_CNT, ((NUM_TX_DESC << 16) | NUM_QDMA_PAGE)); ++ sysRegWrite(QDMA_FQ_BLEN, QDMA_PAGE_SIZE << 16); ++ return 1; ++} ++ ++int fe_dma_init(struct net_device *dev) ++{ ++ ++ int i; ++ unsigned int regVal; ++ END_DEVICE* ei_local = netdev_priv(dev); ++ ++ fq_qdma_init(); ++ ++ while(1) ++ { ++ regVal = sysRegRead(QDMA_GLO_CFG); ++ if((regVal & RX_DMA_BUSY)) ++ { ++ printk("\n RX_DMA_BUSY !!! "); ++ continue; ++ } ++ if((regVal & TX_DMA_BUSY)) ++ { ++ printk("\n TX_DMA_BUSY !!! "); ++ continue; ++ } ++ break; ++ } ++ /*tx desc alloc, add a NULL TXD to HW*/ ++ ++ qdma_tx_desc_alloc(); ++ ++ ++ /* Initial RX Ring 0*/ ++#ifdef CONFIG_32B_DESC ++ ei_local->rx_ring0 = kmalloc(NUM_QRX_DESC * sizeof(struct PDMA_rxdesc), GFP_KERNEL); ++ ei_local->phy_rx_ring0 = virt_to_phys(ei_local->rx_ring0); ++#else ++ ei_local->rx_ring0 = pci_alloc_consistent(NULL, NUM_QRX_DESC * sizeof(struct PDMA_rxdesc), &ei_local->phy_rx_ring0); ++#endif ++ for (i = 0; i < NUM_QRX_DESC; i++) { ++ memset(&ei_local->rx_ring0[i],0,sizeof(struct PDMA_rxdesc)); ++ ei_local->rx_ring0[i].rxd_info2.DDONE_bit = 0; ++#if defined (CONFIG_RAETH_SCATTER_GATHER_RX_DMA) ++ ei_local->rx_ring0[i].rxd_info2.LS0 = 0; ++ ei_local->rx_ring0[i].rxd_info2.PLEN0 = MAX_RX_LENGTH; ++#else ++ ei_local->rx_ring0[i].rxd_info2.LS0 = 1; ++#endif ++ ei_local->rx_ring0[i].rxd_info1.PDP0 = dma_map_single(NULL, ei_local->netrx0_skbuf[i]->data, MAX_RX_LENGTH, PCI_DMA_FROMDEVICE); ++ } ++ printk("QDMA_RX:phy_rx_ring0 = 0x%08x, rx_ring0 = 0x%p\n",ei_local->phy_rx_ring0,ei_local->rx_ring0); ++ ++#if defined (CONFIG_RAETH_MULTIPLE_RX_RING) ++ /* Initial RX Ring 1*/ ++#ifdef CONFIG_32B_DESC ++ ei_local->rx_ring1 = kmalloc(NUM_QRX_DESC * sizeof(struct PDMA_rxdesc), GFP_KERNEL); ++ ei_local->phy_rx_ring1 = virt_to_phys(ei_local->rx_ring1); ++#else ++ ei_local->rx_ring1 = pci_alloc_consistent(NULL, NUM_QRX_DESC * sizeof(struct PDMA_rxdesc), &ei_local->phy_rx_ring1); ++#endif ++ for (i = 0; i < NUM_QRX_DESC; i++) { ++ memset(&ei_local->rx_ring1[i],0,sizeof(struct PDMA_rxdesc)); ++ ei_local->rx_ring1[i].rxd_info2.DDONE_bit = 0; ++#if defined (CONFIG_RAETH_SCATTER_GATHER_RX_DMA) ++ ei_local->rx_ring0[i].rxd_info2.LS0 = 0; ++ ei_local->rx_ring0[i].rxd_info2.PLEN0 = MAX_RX_LENGTH; ++#else ++ ei_local->rx_ring1[i].rxd_info2.LS0 = 1; ++#endif ++ ei_local->rx_ring1[i].rxd_info1.PDP0 = dma_map_single(NULL, ei_local->netrx1_skbuf[i]->data, MAX_RX_LENGTH, PCI_DMA_FROMDEVICE); ++ } ++ printk("\nphy_rx_ring1 = 0x%08x, rx_ring1 = 0x%p\n",ei_local->phy_rx_ring1,ei_local->rx_ring1); ++#endif ++ ++ regVal = sysRegRead(QDMA_GLO_CFG); ++ regVal &= 0x000000FF; ++ sysRegWrite(QDMA_GLO_CFG, regVal); ++ regVal=sysRegRead(QDMA_GLO_CFG); ++ ++ /* Tell the adapter where the TX/RX rings are located. */ ++ ++ sysRegWrite(QRX_BASE_PTR_0, phys_to_bus((u32) ei_local->phy_rx_ring0)); ++ sysRegWrite(QRX_MAX_CNT_0, cpu_to_le32((u32) NUM_QRX_DESC)); ++ sysRegWrite(QRX_CRX_IDX_0, cpu_to_le32((u32) (NUM_QRX_DESC - 1))); ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ rx_calc_idx0 = rx_dma_owner_idx0 = sysRegRead(QRX_CRX_IDX_0); ++#endif ++ sysRegWrite(QDMA_RST_CFG, PST_DRX_IDX0); ++#if defined (CONFIG_RAETH_MULTIPLE_RX_RING) ++ sysRegWrite(QRX_BASE_PTR_1, phys_to_bus((u32) ei_local->phy_rx_ring1)); ++ sysRegWrite(QRX_MAX_CNT_1, cpu_to_le32((u32) NUM_QRX_DESC)); ++ sysRegWrite(QRX_CRX_IDX_1, cpu_to_le32((u32) (NUM_QRX_DESC - 1))); ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ rx_calc_idx1 = rx_dma_owner_idx1 = sysRegRead(QRX_CRX_IDX_1); ++#endif ++ sysRegWrite(QDMA_RST_CFG, PST_DRX_IDX1); ++#endif ++ ++#if !defined (CONFIG_RAETH_QDMATX_QDMARX) ++ /* Initial PDMA RX Ring 0*/ ++#ifdef CONFIG_32B_DESC ++ ei_local->rx_ring0 = kmalloc(NUM_RX_DESC * sizeof(struct PDMA_rxdesc), GFP_KERNEL); ++ ei_local->phy_rx_ring0 = virt_to_phys(ei_local->rx_ring0); ++#else ++ ei_local->rx_ring0 = pci_alloc_consistent(NULL, NUM_RX_DESC * sizeof(struct PDMA_rxdesc), &ei_local->phy_rx_ring0); ++#endif ++ for (i = 0; i < NUM_RX_DESC; i++) { ++ memset(&ei_local->rx_ring0[i],0,sizeof(struct PDMA_rxdesc)); ++ ei_local->rx_ring0[i].rxd_info2.DDONE_bit = 0; ++#if defined (CONFIG_RAETH_SCATTER_GATHER_RX_DMA) ++ ei_local->rx_ring0[i].rxd_info2.LS0 = 0; ++ ei_local->rx_ring0[i].rxd_info2.PLEN0 = MAX_RX_LENGTH; ++#else ++ ei_local->rx_ring0[i].rxd_info2.LS0 = 1; ++#endif ++ ei_local->rx_ring0[i].rxd_info1.PDP0 = dma_map_single(NULL, ei_local->netrx0_skbuf[i]->data, MAX_RX_LENGTH, PCI_DMA_FROMDEVICE); ++ } ++ printk("PDMA_RX:phy_rx_ring0 = 0x%08x, rx_ring0 = 0x%p\n",ei_local->phy_rx_ring0,ei_local->rx_ring0); ++ ++ regVal = sysRegRead(PDMA_GLO_CFG); ++ regVal &= 0x000000FF; ++ sysRegWrite(PDMA_GLO_CFG, regVal); ++ regVal=sysRegRead(PDMA_GLO_CFG); ++ ++ sysRegWrite(RX_BASE_PTR0, phys_to_bus((u32) ei_local->phy_rx_ring0)); ++ sysRegWrite(RX_MAX_CNT0, cpu_to_le32((u32) NUM_RX_DESC)); ++ sysRegWrite(RX_CALC_IDX0, cpu_to_le32((u32) (NUM_RX_DESC - 1))); ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ rx_calc_idx0 = sysRegRead(RX_CALC_IDX0); ++#endif ++ sysRegWrite(PDMA_RST_CFG, PST_DRX_IDX0); ++ ++#endif/*kurtis*/ ++ /* Enable randon early drop and set drop threshold automatically */ ++ sysRegWrite(QDMA_FC_THRES, 0x174444); ++ sysRegWrite(QDMA_HRED2, 0x0); ++ set_fe_dma_glo_cfg(); ++ ++ return 1; ++} ++ ++inline int rt2880_eth_send(struct net_device* dev, struct sk_buff *skb, int gmac_no) ++{ ++ unsigned int length=skb->len; ++ END_DEVICE* ei_local = netdev_priv(dev); ++ ++ struct QDMA_txdesc *cpu_ptr; ++ ++ struct QDMA_txdesc *dma_ptr __maybe_unused; ++ struct QDMA_txdesc *free_txd; ++ unsigned int ctx_offset = 0; ++ unsigned int dtx_offset = 0; ++#if defined (CONFIG_RAETH_TSO) ++ struct iphdr *iph = NULL; ++ struct QDMA_txdesc *init_cpu_ptr; ++ struct tcphdr *th = NULL; ++ struct skb_frag_struct *frag; ++ unsigned int nr_frags = skb_shinfo(skb)->nr_frags; ++ unsigned int len, size, offset, frag_txd_num; ++ int init_txd_idx, i; ++#endif // CONFIG_RAETH_TSO // ++ ++#if defined (CONFIG_RAETH_TSOV6) ++ struct ipv6hdr *ip6h = NULL; ++#endif ++ ++#ifdef CONFIG_PSEUDO_SUPPORT ++ PSEUDO_ADAPTER *pAd; ++#endif ++ cpu_ptr = (ei_local->tx_cpu_ptr); ++ ctx_offset = GET_TXD_OFFSET(&cpu_ptr); ++ cpu_ptr = phys_to_virt(ei_local->tx_cpu_ptr); ++ dma_ptr = phys_to_virt(ei_local->tx_dma_ptr); ++/*kurtis test*/ ++ //dma_ptr = (ei_local->tx_dma_ptr); ++ ++ ++ /*only modify virtual address*/ ++ //cpu_ptr = (ei_local->txd_pool) + (ctx_offset * sizeof(struct QDMA_txdesc)); ++ cpu_ptr = (ei_local->txd_pool + (ctx_offset)); ++ ++ //dtx_offset = GET_TXD_OFFSET(&dma_ptr); ++ //dma_ptr = (ei_local->txd_pool) + (dtx_offset * sizeof(struct QDMA_txdesc)); ++ ++ //printk("eth_send ctx_offset = 0x%x!!!\n", ctx_offset); ++ //printk("eth_send dtx_offset = 0x%x!!!\n", dtx_offset); ++ //printk("eth_send ei_local->txd_pool = 0x%x!!!\n", ei_local->txd_pool); ++ //printk("eth_send cpu_ptr = 0x%x!!!\n", cpu_ptr); ++ //printk("eth_send ctx_offset = 0x%x!!!\n", ctx_offset); ++ //printk("eth_send ei_local->skb_free[ctx_offset] = 0x%x!!!\n", skb); ++ ++ ++ ei_local->skb_free[ctx_offset] = skb; ++#if defined (CONFIG_RAETH_TSO) ++ init_cpu_ptr = cpu_ptr; ++ init_txd_idx = ctx_offset; ++#endif ++ ++#if !defined (CONFIG_RAETH_TSO) ++ ++ //2. prepare data ++ cpu_ptr->txd_info1.SDP = virt_to_phys(skb->data); ++ cpu_ptr->txd_info3.SDL = skb->len; ++ ++ if (gmac_no == 1) { ++ cpu_ptr->txd_info4.FPORT = 1; ++ }else { ++ cpu_ptr->txd_info4.FPORT = 2; ++ } ++ ++ ++ cpu_ptr->txd_info3.QID = M2Q_table[skb->mark]; ++#if 0 ++ iph = (struct iphdr *)skb_network_header(skb); ++ if (iph->tos == 0xe0) ++ cpu_ptr->txd_info3.QID = 3; ++ else if (iph->tos == 0xa0) ++ cpu_ptr->txd_info3.QID = 2; ++ else if (iph->tos == 0x20) ++ cpu_ptr->txd_info3.QID = 1; ++ else ++ cpu_ptr->txd_info3.QID = 0; ++#endif ++ ++#if defined (CONFIG_RAETH_CHECKSUM_OFFLOAD) && ! defined(CONFIG_RALINK_RT5350) && !defined (CONFIG_RALINK_MT7628) ++ if (skb->ip_summed == CHECKSUM_PARTIAL){ ++ cpu_ptr->txd_info4.TUI_CO = 7; ++ }else { ++ cpu_ptr->txd_info4.TUI_CO = 0; ++ } ++#endif ++ ++#ifdef CONFIG_RAETH_HW_VLAN_TX ++ if(vlan_tx_tag_present(skb)) { ++ cpu_ptr->txd_info4.VLAN_TAG = 0x10000 | vlan_tx_tag_get(skb); ++ }else { ++ cpu_ptr->txd_info4.VLAN_TAG = 0; ++ } ++#endif ++ ++#if defined (CONFIG_RA_HW_NAT) || defined (CONFIG_RA_HW_NAT_MODULE) ++ if(FOE_MAGIC_TAG(skb) == FOE_MAGIC_PPE) { ++ if(ra_sw_nat_hook_rx!= NULL){ ++ cpu_ptr->txd_info4.FPORT = 4; /* PPE */ ++ FOE_MAGIC_TAG(skb) = 0; ++ } ++ } ++#endif ++#if 0 ++ cpu_ptr->txd_info4.FPORT = 4; /* PPE */ ++ cpu_ptr->txd_info4.UDF = 0x2F; ++#endif ++ ++#if defined (CONFIG_MIPS) ++ dma_cache_sync(NULL, skb->data, skb->len, DMA_TO_DEVICE); ++#else ++ dma_sync_single_for_device(NULL, virt_to_phys(skb->data), skb->len, DMA_TO_DEVICE); ++#endif ++ cpu_ptr->txd_info3.SWC_bit = 1; ++ ++ //3. get NULL TXD and decrease free_tx_num by 1. ++ ctx_offset = get_free_txd(&free_txd); ++ if(ctx_offset == NUM_TX_DESC) { ++ printk("get_free_txd fail\n"); // this should not happen. free_txd_num is 2 at least. ++ return 0; ++ } ++ ++ //4. hook new TXD in the end of queue ++ //cpu_ptr->txd_info2.NDP = virt_to_phys(free_txd); ++ cpu_ptr->txd_info2.NDP = (free_txd); ++ ++ ++ //5. move CPU_PTR to new TXD ++ //ei_local->tx_cpu_ptr = virt_to_phys(free_txd); ++ ei_local->tx_cpu_ptr = (free_txd); ++ cpu_ptr->txd_info3.OWN_bit = 0; ++ sysRegWrite(QTX_CTX_PTR, ei_local->tx_cpu_ptr); ++ ++#if 0 ++ printk("----------------------------------------------\n"); ++ printk("txd_info1:%08X \n",*(int *)&cpu_ptr->txd_info1); ++ printk("txd_info2:%08X \n",*(int *)&cpu_ptr->txd_info2); ++ printk("txd_info3:%08X \n",*(int *)&cpu_ptr->txd_info3); ++ printk("txd_info4:%08X \n",*(int *)&cpu_ptr->txd_info4); ++#endif ++ ++#else //#if !defined (CONFIG_RAETH_TSO) ++ cpu_ptr->txd_info1.SDP = virt_to_phys(skb->data); ++ cpu_ptr->txd_info3.SDL = (length - skb->data_len); ++ cpu_ptr->txd_info3.LS_bit = nr_frags ? 0:1; ++ if (gmac_no == 1) { ++ cpu_ptr->txd_info4.FPORT = 1; ++ }else { ++ cpu_ptr->txd_info4.FPORT = 2; ++ } ++ ++ cpu_ptr->txd_info4.TSO = 0; ++ cpu_ptr->txd_info3.QID = M2Q_table[skb->mark]; ++#if defined (CONFIG_RAETH_CHECKSUM_OFFLOAD) && ! defined(CONFIG_RALINK_RT5350) && !defined (CONFIG_RALINK_MT7628) ++ if (skb->ip_summed == CHECKSUM_PARTIAL){ ++ cpu_ptr->txd_info4.TUI_CO = 7; ++ }else { ++ cpu_ptr->txd_info4.TUI_CO = 0; ++ } ++#endif ++ ++#ifdef CONFIG_RAETH_HW_VLAN_TX ++ if(vlan_tx_tag_present(skb)) { ++ cpu_ptr->txd_info4.VLAN_TAG = 0x10000 | vlan_tx_tag_get(skb); ++ }else { ++ cpu_ptr->txd_info4.VLAN_TAG = 0; ++ } ++#endif ++ ++#if defined (CONFIG_RA_HW_NAT) || defined (CONFIG_RA_HW_NAT_MODULE) ++ if(FOE_MAGIC_TAG(skb) == FOE_MAGIC_PPE) { ++ if(ra_sw_nat_hook_rx!= NULL){ ++ cpu_ptr->txd_info4.FPORT = 4; /* PPE */ ++ FOE_MAGIC_TAG(skb) = 0; ++ } ++ } ++#endif ++ ++ cpu_ptr->txd_info3.SWC_bit = 1; ++ ++ ctx_offset = get_free_txd(&free_txd); ++ if(ctx_offset == NUM_TX_DESC) { ++ printk("get_free_txd fail\n"); ++ return 0; ++ } ++ //cpu_ptr->txd_info2.NDP = virt_to_phys(free_txd); ++ //ei_local->tx_cpu_ptr = virt_to_phys(free_txd); ++ cpu_ptr->txd_info2.NDP = free_txd; ++ ei_local->tx_cpu_ptr = free_txd; ++ ++ if(nr_frags > 0) { ++ for(i=0;i<nr_frags;i++) { ++ // 1. set or get init value for current fragment ++ offset = 0; ++ frag = &skb_shinfo(skb)->frags[i]; ++ len = frag->size; ++ frag_txd_num = cal_frag_txd_num(len); // calculate the needed TXD numbers for this fragment ++ for(frag_txd_num = frag_txd_num;frag_txd_num > 0; frag_txd_num --){ ++ // 2. size will be assigned to SDL and can't be larger than MAX_TXD_LEN ++ if(len < MAX_TXD_LEN) ++ size = len; ++ else ++ size = MAX_TXD_LEN; ++ ++ //3. Update TXD info ++ cpu_ptr = (ei_local->txd_pool + (ctx_offset)); ++ cpu_ptr->txd_info3.QID = M2Q_table[skb->mark]; ++#if LINUX_VERSION_CODE < KERNEL_VERSION(3,2,0) ++ cpu_ptr->txd_info1.SDP = pci_map_page(NULL, frag->page, frag->page_offset, frag->size, PCI_DMA_TODEVICE); ++#else ++ cpu_ptr->txd_info1.SDP = pci_map_page(NULL, frag->page.p, frag->page_offset + offset, size, PCI_DMA_TODEVICE); ++// printk(" frag->page = %08x. frag->page_offset = %08x. frag->size = % 08x.\n", frag->page, (frag->page_offset+offset), size); ++#endif ++ cpu_ptr->txd_info3.SDL = size; ++ if( (i==(nr_frags-1)) && (frag_txd_num == 1)) ++ cpu_ptr->txd_info3.LS_bit = 1; ++ else ++ cpu_ptr->txd_info3.LS_bit = 0; ++ cpu_ptr->txd_info3.OWN_bit = 0; ++ cpu_ptr->txd_info3.SWC_bit = 1; ++ //4. Update skb_free for housekeeping ++ ei_local->skb_free[ctx_offset] = (cpu_ptr->txd_info3.LS_bit == 1)?skb:(struct sk_buff *)0xFFFFFFFF; //MAGIC ID ++ ++ //5. Get next TXD ++ ctx_offset = get_free_txd(&free_txd); ++ //cpu_ptr->txd_info2.NDP = virt_to_phys(free_txd); ++ //ei_local->tx_cpu_ptr = virt_to_phys(free_txd); ++ cpu_ptr->txd_info2.NDP = free_txd; ++ ei_local->tx_cpu_ptr = free_txd; ++ //6. Update offset and len. ++ offset += size; ++ len -= size; ++ } ++ } ++ ei_local->skb_free[init_txd_idx]= (struct sk_buff *)0xFFFFFFFF; //MAGIC ID ++ } ++ ++ if(skb_shinfo(skb)->gso_segs > 1) { ++ ++// TsoLenUpdate(skb->len); ++ ++ /* TCP over IPv4 */ ++ iph = (struct iphdr *)skb_network_header(skb); ++#if defined (CONFIG_RAETH_TSOV6) ++ /* TCP over IPv6 */ ++ ip6h = (struct ipv6hdr *)skb_network_header(skb); ++#endif ++ if((iph->version == 4) && (iph->protocol == IPPROTO_TCP)) { ++ th = (struct tcphdr *)skb_transport_header(skb); ++ ++ init_cpu_ptr->txd_info4.TSO = 1; ++ ++ th->check = htons(skb_shinfo(skb)->gso_size); ++#if defined (CONFIG_MIPS) ++ dma_cache_sync(NULL, th, sizeof(struct tcphdr), DMA_TO_DEVICE); ++#else ++ dma_sync_single_for_device(NULL, virt_to_phys(th), sizeof(struct tcphdr), DMA_TO_DEVICE); ++#endif ++ } ++ ++#if defined (CONFIG_RAETH_TSOV6) ++ /* TCP over IPv6 */ ++ //ip6h = (struct ipv6hdr *)skb_network_header(skb); ++ else if ((ip6h->version == 6) && (ip6h->nexthdr == NEXTHDR_TCP)) { ++ th = (struct tcphdr *)skb_transport_header(skb); ++#ifdef CONFIG_RAETH_RW_PDMAPTR_FROM_VAR ++ init_cpu_ptr->txd_info4.TSO = 1; ++#else ++ init_cpu_ptr->txd_info4.TSO = 1; ++#endif ++ th->check = htons(skb_shinfo(skb)->gso_size); ++#if defined (CONFIG_MIPS) ++ dma_cache_sync(NULL, th, sizeof(struct tcphdr), DMA_TO_DEVICE); ++#else ++ dma_sync_single_for_device(NULL, virt_to_phys(th), sizeof(struct tcphdr), DMA_TO_DEVICE); ++#endif ++ } ++#endif ++ } ++ ++ ++// dma_cache_sync(NULL, skb->data, skb->len, DMA_TO_DEVICE); ++ ++ init_cpu_ptr->txd_info3.OWN_bit = 0; ++#endif // CONFIG_RAETH_TSO // ++ ++ sysRegWrite(QTX_CTX_PTR, ei_local->tx_cpu_ptr); ++ ++#ifdef CONFIG_PSEUDO_SUPPORT ++ if (gmac_no == 2) { ++ if (ei_local->PseudoDev != NULL) { ++ pAd = netdev_priv(ei_local->PseudoDev); ++ pAd->stat.tx_packets++; ++ pAd->stat.tx_bytes += length; ++ } ++ } else ++ ++#endif ++ { ++ ei_local->stat.tx_packets++; ++ ei_local->stat.tx_bytes += skb->len; ++ } ++#ifdef CONFIG_RAETH_NAPI ++ if ( ei_local->tx_full == 1) { ++ ei_local->tx_full = 0; ++ netif_wake_queue(dev); ++ } ++#endif ++ ++ return length; ++} ++ ++int ei_start_xmit(struct sk_buff* skb, struct net_device *dev, int gmac_no) ++{ ++ END_DEVICE *ei_local = netdev_priv(dev); ++ unsigned long flags; ++ unsigned int num_of_txd = 0; ++#if defined (CONFIG_RAETH_TSO) ++ unsigned int nr_frags = skb_shinfo(skb)->nr_frags, i; ++ struct skb_frag_struct *frag; ++#endif ++#ifdef CONFIG_PSEUDO_SUPPORT ++ PSEUDO_ADAPTER *pAd; ++#endif ++ ++#if !defined(CONFIG_RA_NAT_NONE) ++ if(ra_sw_nat_hook_tx!= NULL) ++ { ++// spin_lock_irqsave(&ei_local->page_lock, flags); ++ if(ra_sw_nat_hook_tx(skb, gmac_no)==1){ ++// spin_unlock_irqrestore(&ei_local->page_lock, flags); ++ }else{ ++ kfree_skb(skb); ++// spin_unlock_irqrestore(&ei_local->page_lock, flags); ++ return 0; ++ } ++ } ++#endif ++ ++#if defined(CONFIG_RALINK_MT7621) || defined(CONFIG_ARCH_MT7623) ++#define MIN_PKT_LEN 64 ++ if (skb->len < MIN_PKT_LEN) { ++ if (skb_padto(skb, MIN_PKT_LEN)) { ++ printk("raeth: skb_padto failed\n"); ++ return 0; ++ } ++ skb_put(skb, MIN_PKT_LEN - skb->len); ++ } ++#endif ++ ++ ++ dev->trans_start = jiffies; /* save the timestamp */ ++ spin_lock_irqsave(&ei_local->page_lock, flags); ++#if defined (CONFIG_MIPS) ++ dma_cache_sync(NULL, skb->data, skb->len, DMA_TO_DEVICE); ++#else ++ dma_sync_single_for_device(NULL, virt_to_phys(skb->data), skb->len, DMA_TO_DEVICE); ++#endif ++ ++ ++//check free_txd_num before calling rt288_eth_send() ++ ++#if defined (CONFIG_RAETH_TSO) ++ // num_of_txd = (nr_frags==0) ? 1 : (nr_frags + 1); ++ if(nr_frags != 0){ ++ for(i=0;i<nr_frags;i++) { ++ frag = &skb_shinfo(skb)->frags[i]; ++ num_of_txd += cal_frag_txd_num(frag->size); ++ } ++ }else ++ num_of_txd = 1; ++#else ++ num_of_txd = 1; ++#endif ++ ++#if defined(CONFIG_RALINK_MT7621) ++ if((sysRegRead(0xbe00000c)&0xFFFF) == 0x0101) { ++ ei_xmit_housekeeping(0); ++ } ++#endif ++ ++ ei_xmit_housekeeping(0); ++ ++ //if ((ei_local->free_txd_num > num_of_txd + 1) && (ei_local->free_txd_num != NUM_TX_DESC)) ++ if ((ei_local->free_txd_num > num_of_txd + 5) && (ei_local->free_txd_num != NUM_TX_DESC)) ++ { ++ rt2880_eth_send(dev, skb, gmac_no); // need to modify rt2880_eth_send() for QDMA ++ if (ei_local->free_txd_num < 3) ++ { ++#if defined (CONFIG_RAETH_STOP_RX_WHEN_TX_FULL) ++ netif_stop_queue(dev); ++#ifdef CONFIG_PSEUDO_SUPPORT ++ netif_stop_queue(ei_local->PseudoDev); ++#endif ++ tx_ring_full = 1; ++#endif ++ } ++ } else { ++#ifdef CONFIG_PSEUDO_SUPPORT ++ if (gmac_no == 2) ++ { ++ if (ei_local->PseudoDev != NULL) ++ { ++ pAd = netdev_priv(ei_local->PseudoDev); ++ pAd->stat.tx_dropped++; ++ } ++ } else ++#endif ++ ei_local->stat.tx_dropped++; ++ kfree_skb(skb); ++ spin_unlock_irqrestore(&ei_local->page_lock, flags); ++ return 0; ++ } ++ spin_unlock_irqrestore(&ei_local->page_lock, flags); ++ return 0; ++} ++ ++void ei_xmit_housekeeping(unsigned long unused) ++{ ++ struct net_device *dev = dev_raether; ++ END_DEVICE *ei_local = netdev_priv(dev); ++#ifndef CONFIG_RAETH_NAPI ++ unsigned long reg_int_mask=0; ++#endif ++ struct QDMA_txdesc *dma_ptr = NULL; ++ struct QDMA_txdesc *cpu_ptr = NULL; ++ struct QDMA_txdesc *tmp_ptr = NULL; ++ unsigned int htx_offset = 0; ++ unsigned int ctx_offset = 0; ++ unsigned int dtx_offset = 0; ++ ++ //dma_ptr = phys_to_virt(sysRegRead(QTX_DRX_PTR)); ++ //cpu_ptr = phys_to_virt(sysRegRead(QTX_CRX_PTR)); ++ //printk("kurtis:housekeeping QTX_DRX_PTR = 0x%x!!!\n", sysRegRead(QTX_DRX_PTR)); ++ //printk("kurtis:housekeeping DMA_PTR = 0x%x!!!\n", dma_ptr); ++ ++ cpu_ptr = sysRegRead(QTX_CRX_PTR); ++ dma_ptr = sysRegRead(QTX_DRX_PTR); ++ ++ //printk("kurtis:housekeeping QTX_CRX_PTR = 0x%x!!!\n", cpu_ptr); ++ //printk("kurtis:housekeeping QTX_DRX_PTR = 0x%x!!!\n", dma_ptr); ++ ctx_offset = GET_TXD_OFFSET(&cpu_ptr); ++ dtx_offset = GET_TXD_OFFSET(&dma_ptr); ++ htx_offset = ctx_offset; ++ cpu_ptr = (ei_local->txd_pool + (ctx_offset)); ++ dma_ptr = (ei_local->txd_pool + (dtx_offset)); ++ ++ ++ //printk("kurtis:housekeeping CPU_PTR = 0x%x!!!\n", cpu_ptr); ++ //printk("kurtis:housekeeping DMA_PTR = 0x%x!!!\n", dma_ptr); ++ ++/*temp mark*/ ++#if 1 ++ ++ ++ if(cpu_ptr != dma_ptr && (cpu_ptr->txd_info3.OWN_bit == 1)) { ++ while(cpu_ptr != dma_ptr && (cpu_ptr->txd_info3.OWN_bit == 1)) { ++ ++ //1. keep cpu next TXD ++ //tmp_ptr = phys_to_virt(cpu_ptr->txd_info2.NDP); ++ tmp_ptr = cpu_ptr->txd_info2.NDP; ++ htx_offset = GET_TXD_OFFSET(&tmp_ptr); ++ //printk("kurtis:housekeeping cpu_ptr->txd_info2.NDP = 0x%x!!!\n", cpu_ptr->txd_info2.NDP); ++ //printk("kurtis:housekeeping tmp_ptr = 0x%x!!!\n", tmp_ptr); ++ //printk("kurtis:housekeeping htx_offset = 0x%x!!!\n", htx_offset); ++ //2. free skb meomry ++#if defined (CONFIG_RAETH_TSO) ++ if(ei_local->skb_free[htx_offset]!=(struct sk_buff *)0xFFFFFFFF) { ++ dev_kfree_skb_any(ei_local->skb_free[htx_offset]); ++ } ++#else ++ dev_kfree_skb_any(ei_local->skb_free[htx_offset]); ++#endif ++ ++ //3. release TXD ++ //htx_offset = GET_TXD_OFFSET(&cpu_ptr); ++ //put_free_txd(htx_offset); ++ put_free_txd(ctx_offset); ++ ++ ++ ++ netif_wake_queue(dev); ++#ifdef CONFIG_PSEUDO_SUPPORT ++ netif_wake_queue(ei_local->PseudoDev); ++#endif ++ tx_ring_full=0; ++ ++ //4. update cpu_ptr to next ptr ++ //cpu_ptr = tmp_ptr; ++ cpu_ptr = (ei_local->txd_pool + htx_offset); ++ ctx_offset = htx_offset; ++ //cpu_ptr = (cpu_ptr + (htx_offset)); ++ //printk("kurtis:housekeeping 4. update cpu_ptr = 0x%x!!!\n", cpu_ptr); ++ } ++ } ++ //sysRegWrite(QTX_CRX_PTR, virt_to_phys(cpu_ptr)); ++ //sysRegWrite(QTX_CRX_PTR, cpu_ptr); ++ tmp_ptr = (ei_local->phy_txd_pool + (htx_offset << 4)); ++ //printk("kurtis:housekeeping 5. update QTX_CRX_PTR = 0x%x!!!\n", tmp_ptr); ++ sysRegWrite(QTX_CRX_PTR, tmp_ptr); ++ ++#endif ++ ++#ifndef CONFIG_RAETH_NAPI ++ reg_int_mask=sysRegRead(QFE_INT_ENABLE); ++#if defined (DELAY_INT) ++ sysRegWrite(FE_INT_ENABLE, reg_int_mask| RLS_DLY_INT); ++#else ++ ++ sysRegWrite(FE_INT_ENABLE, reg_int_mask | RLS_DONE_INT); ++#endif ++#endif //CONFIG_RAETH_NAPI// ++} ++ ++EXPORT_SYMBOL(ei_start_xmit); ++EXPORT_SYMBOL(ei_xmit_housekeeping); ++EXPORT_SYMBOL(fe_dma_init); ++EXPORT_SYMBOL(rt2880_eth_send); +diff --git a/drivers/net/ethernet/raeth/smb_hook.c b/drivers/net/ethernet/raeth/smb_hook.c +new file mode 100644 +index 0000000..617139c +--- /dev/null ++++ b/drivers/net/ethernet/raeth/smb_hook.c +@@ -0,0 +1,17 @@ ++#include <linux/version.h> ++#include <linux/module.h> ++#include <linux/kernel.h> ++#include <linux/types.h> ++#include <linux/skbuff.h> ++ ++ ++int (*smb_nf_local_in_hook)(struct sk_buff *skb) = NULL; ++int (*smb_nf_pre_routing_hook)(struct sk_buff *skb) = NULL; ++int (*smb_nf_local_out_hook)(struct sk_buff *skb) = NULL; ++int (*smb_nf_post_routing_hook)(struct sk_buff *skb) = NULL; ++EXPORT_SYMBOL(smb_nf_local_in_hook); ++EXPORT_SYMBOL(smb_nf_pre_routing_hook); ++EXPORT_SYMBOL(smb_nf_local_out_hook); ++EXPORT_SYMBOL(smb_nf_post_routing_hook); ++ ++ +diff --git a/drivers/net/ethernet/raeth/smb_nf.c b/drivers/net/ethernet/raeth/smb_nf.c +new file mode 100644 +index 0000000..86250eb +--- /dev/null ++++ b/drivers/net/ethernet/raeth/smb_nf.c +@@ -0,0 +1,177 @@ ++#include <linux/module.h> ++#include <linux/version.h> ++#include <linux/kernel.h> ++#include <linux/types.h> ++ ++#include <linux/inetdevice.h> ++#include <linux/tcp.h> ++#include <linux/ip.h> ++#include <net/tcp.h> ++#include <net/ip.h> ++ ++extern int (*smb_nf_local_in_hook)(struct sk_buff *skb); ++extern int (*smb_nf_pre_routing_hook)(struct sk_buff *skb); ++extern int (*smb_nf_local_out_hook)(struct sk_buff *skb); ++extern int (*smb_nf_post_routing_hook)(struct sk_buff *skb); ++ ++struct net_device *lan_int = NULL; ++struct in_ifaddr *lan_ifa = NULL; ++ ++ ++int mtk_smb_nf_local_in_hook(struct sk_buff *skb) ++{ ++ struct iphdr *iph = ip_hdr(skb); ++ ++ if (skb->protocol == htons(ETH_P_IP)) { ++ struct iphdr *iph = ip_hdr(skb); ++ ++ if (iph->protocol == IPPROTO_TCP) { ++ struct tcphdr *th = tcp_hdr(skb); ++ unsigned short sport, dport; ++ ++ th = tcp_hdr(skb); ++ th = (struct tcphdr *)(((unsigned char *)iph) + iph->ihl*4); ++ ++ if ((iph->daddr == lan_ifa->ifa_local) ++ && ((th->dest == 0xbd01) || (th->dest == 0x8900) ++ || (th->dest == 0x8a00) || (th->dest == 0x8b00))) ++ return 1; ++ else ++ return 0; ++ } ++ ++ } ++ ++ return 0; ++} ++ ++int mtk_smb_nf_pre_routing_hook(struct sk_buff *skb) ++{ ++ struct iphdr *iph = ip_hdr(skb); ++ ++ if (skb->protocol == htons(ETH_P_IP)) { ++ struct iphdr *iph = ip_hdr(skb); ++ ++ if (iph->protocol == IPPROTO_TCP) { ++ struct tcphdr *th = tcp_hdr(skb); ++ unsigned short sport, dport; ++ ++ th = tcp_hdr(skb); ++ th = (struct tcphdr *)(((unsigned char *)iph) + iph->ihl*4); ++ if ((iph->daddr == lan_ifa->ifa_local) ++ && ((th->dest == 0xbd01) || (th->dest == 0x8900) ++ || (th->dest == 0x8a00) || (th->dest == 0x8b00))) ++ return 1; ++ else ++ return 0; ++ } ++ ++ } ++ ++ return 0; ++} ++ ++int mtk_smb_nf_local_out_hook(struct sk_buff *skb) ++{ ++ struct iphdr *iph = ip_hdr(skb); ++ ++ if (iph->protocol == IPPROTO_TCP) { ++ struct tcphdr *th = tcp_hdr(skb); ++ ++ th = tcp_hdr(skb); ++ th = (struct tcphdr *)(((unsigned char *)iph) + iph->ihl*4); ++ ++ if ((iph->saddr == lan_ifa->ifa_local) ++ && ((th->source == 0xbd01) || (th->source == 0x8900) ++ || (th->source == 0x8a00) || (th->source == 0x8b00))) ++ return 1; ++ else ++ return 0; ++ } ++ ++ return 0; ++} ++ ++int mtk_smb_nf_post_routing_hook(struct sk_buff *skb) ++{ ++ struct iphdr *iph = ip_hdr(skb); ++ ++ if (skb->protocol == htons(ETH_P_IP)) { ++ struct iphdr *iph = ip_hdr(skb); ++ ++ if (iph->protocol == IPPROTO_TCP) { ++ struct tcphdr *th = tcp_hdr(skb); ++ ++ th = tcp_hdr(skb); ++ th = (struct tcphdr *)(((unsigned char *)iph) + iph->ihl*4); ++ ++ if ((iph->saddr == lan_ifa->ifa_local) ++ && ((th->source == 0xbd01) || (th->source == 0x8900) ++ || (th->source == 0x8a00) || (th->source == 0x8b00))) ++ return 1; ++ else ++ return 0; ++ } ++ ++ } ++ ++ return 0; ++} ++ ++int __init mtk_smb_hook_init(void) ++{ ++ struct in_device *in_dev; ++ struct in_ifaddr **ifap = NULL; ++ struct in_ifaddr *ifa = NULL; ++ ++#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35) ++ lan_int = dev_get_by_name(&init_net, "br0"); ++#else ++ lan_int = dev_get_by_name("br0"); ++#endif ++ if (lan_int) ++ in_dev = __in_dev_get_rtnl(lan_int); ++ else ++ return 0; ++ ++ if (in_dev) { ++ for (ifap = &in_dev->ifa_list; (ifa = *ifap) != NULL; ++ ifap = &ifa->ifa_next) { ++ if (!strcmp("br0", ifa->ifa_label)) ++ { ++ lan_ifa = ifa; ++ break; /* found */ ++ } ++ } ++ } ++ else ++ return 0; ++ ++ if (lan_ifa) { ++ smb_nf_local_in_hook = mtk_smb_nf_local_in_hook; ++ smb_nf_pre_routing_hook = mtk_smb_nf_pre_routing_hook; ++ smb_nf_local_out_hook = mtk_smb_nf_local_out_hook; ++ smb_nf_post_routing_hook = mtk_smb_nf_post_routing_hook; ++ } ++ ++ printk("Samba Netfilter Hook Enabled\n"); ++ ++ return 0; ++} ++ ++void mtk_smb_hook_cleanup(void) ++{ ++ lan_int = NULL; ++ lan_ifa = NULL; ++ smb_nf_local_in_hook = NULL; ++ smb_nf_pre_routing_hook = NULL; ++ smb_nf_local_out_hook = NULL; ++ smb_nf_post_routing_hook = NULL; ++ ++ return; ++} ++ ++module_init(mtk_smb_hook_init); ++module_exit(mtk_smb_hook_cleanup); ++ ++MODULE_LICENSE("GPL"); +diff --git a/drivers/net/ethernet/raeth/sync_write.h b/drivers/net/ethernet/raeth/sync_write.h +new file mode 100644 +index 0000000..8b800e6 +--- /dev/null ++++ b/drivers/net/ethernet/raeth/sync_write.h +@@ -0,0 +1,103 @@ ++#ifndef _MT_SYNC_WRITE_H ++#define _MT_SYNC_WRITE_H ++ ++#if defined(__KERNEL__) ++ ++#include <linux/io.h> ++#include <asm/cacheflush.h> ++//#include <asm/system.h> ++ ++/* ++ * Define macros. ++ */ ++ ++#define mt65xx_reg_sync_writel(v, a) \ ++ do { \ ++ __raw_writel((v), IOMEM((a))); \ ++ dsb(); \ ++ } while (0) ++ ++#define mt65xx_reg_sync_writew(v, a) \ ++ do { \ ++ __raw_writew((v), IOMEM((a))); \ ++ dsb(); \ ++ } while (0) ++ ++#define mt65xx_reg_sync_writeb(v, a) \ ++ do { \ ++ __raw_writeb((v), IOMEM((a))); \ ++ dsb(); \ ++ } while (0) ++ ++#define mt_reg_sync_writel(v, a) \ ++ do { \ ++ __raw_writel((v), IOMEM((a))); \ ++ dsb(); \ ++ } while (0) ++ ++#define mt_reg_sync_writew(v, a) \ ++ do { \ ++ __raw_writew((v), IOMEM((a))); \ ++ dsb(); \ ++ } while (0) ++ ++#define mt_reg_sync_writeb(v, a) \ ++ do { \ ++ __raw_writeb((v), IOMEM((a))); \ ++ dsb(); \ ++ } while (0) ++ ++ ++#else /* __KERNEL__ */ ++ ++#include <sys/types.h> ++#include <sys/stat.h> ++#include <fcntl.h> ++#include <unistd.h> ++#include <string.h> ++ ++#define dsb() \ ++ do { \ ++ __asm__ __volatile__ ("dsb" : : : "memory"); \ ++ } while (0) ++ ++#define mt65xx_reg_sync_writel(v, a) \ ++ do { \ ++ *(volatile unsigned int *)(a) = (v); \ ++ dsb(); \ ++ } while (0) ++ ++#define mt65xx_reg_sync_writew(v, a) \ ++ do { \ ++ *(volatile unsigned short *)(a) = (v); \ ++ dsb(); \ ++ } while (0) ++ ++#define mt65xx_reg_sync_writeb(v, a) \ ++ do { \ ++ *(volatile unsigned char *)(a) = (v); \ ++ dsb(); \ ++ } while (0) ++ ++#define mt_reg_sync_writel(v, a) \ ++ do { \ ++ *(volatile unsigned int *)(a) = (v); \ ++ dsb(); \ ++ } while (0) ++ ++#define mt_reg_sync_writew(v, a) \ ++ do { \ ++ *(volatile unsigned short *)(a) = (v); \ ++ dsb(); \ ++ } while (0) ++ ++#define mt_reg_sync_writeb(v, a) \ ++ do { \ ++ *(volatile unsigned char *)(a) = (v); \ ++ dsb(); \ ++ } while (0) ++ ++ ++#endif /* __KERNEL__ */ ++ ++#endif /* !_MT_SYNC_WRITE_H */ +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0064-arm-mediatek-add-mt7623-pcie-support.patch b/target/linux/mediatek/patches/0064-arm-mediatek-add-mt7623-pcie-support.patch new file mode 100644 index 0000000000..ee82f9c9d7 --- /dev/null +++ b/target/linux/mediatek/patches/0064-arm-mediatek-add-mt7623-pcie-support.patch @@ -0,0 +1,436 @@ +From 29ceb2449cb3622ccfba9eb1c77bf2ac4162464b Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Sat, 27 Jun 2015 13:15:29 +0200 +Subject: [PATCH 64/76] arm: mediatek: add mt7623 pcie support + +Signed-off-by: John Crispin <blogic@openwrt.org> +--- + arch/arm/mach-mediatek/Makefile | 2 +- + arch/arm/mach-mediatek/pcie.c | 383 +++++++++++++++++++++++++++++++++++++++ + arch/arm/mach-mediatek/pcie.h | 14 ++ + 3 files changed, 398 insertions(+), 1 deletion(-) + create mode 100644 arch/arm/mach-mediatek/pcie.c + create mode 100644 arch/arm/mach-mediatek/pcie.h + +diff --git a/arch/arm/mach-mediatek/Makefile b/arch/arm/mach-mediatek/Makefile +index 2116460..aca28a2 100644 +--- a/arch/arm/mach-mediatek/Makefile ++++ b/arch/arm/mach-mediatek/Makefile +@@ -1,4 +1,4 @@ + ifeq ($(CONFIG_SMP),y) + obj-$(CONFIG_ARCH_MEDIATEK) += platsmp.o + endif +-obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o ++obj-$(CONFIG_ARCH_MEDIATEK) += mediatek.o pcie.o +diff --git a/arch/arm/mach-mediatek/pcie.c b/arch/arm/mach-mediatek/pcie.c +new file mode 100644 +index 0000000..8394712 +--- /dev/null ++++ b/arch/arm/mach-mediatek/pcie.c +@@ -0,0 +1,383 @@ ++/* ++ * Mediatek MT7623 SoC PCIE support ++ * ++ * Copyright (C) 2015 Mediatek ++ * Copyright (C) 2015 John Crispin <blogic@openwrt.org> ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License version 2 as published ++ * by the Free Software Foundation. ++ */ ++ ++#include <linux/kernel.h> ++#include <linux/pci.h> ++#include <linux/ioport.h> ++#include <linux/interrupt.h> ++#include <linux/spinlock.h> ++#include <linux/init.h> ++#include <linux/io.h> ++#include <linux/delay.h> ++#include <asm/irq.h> ++#include <asm/mach/pci.h> ++#include <linux/module.h> ++#include <linux/of.h> ++#include <linux/of_irq.h> ++#include <linux/of_pci.h> ++#include <linux/reset.h> ++#include <linux/platform_device.h> ++ ++#include "pcie.h" ++ ++#define PCICFG 0x00 ++#define PCIINT 0x08 ++#define PCIENA 0x0C ++#define CFGADDR 0x20 ++#define CFGDATA 0x24 ++#define MEMBASE 0x28 ++#define IOBASE 0x2C ++ ++#define BAR0SETUP 0x10 ++#define IMBASEBAR0 0x18 ++#define PCIE_CLASS 0x34 ++#define PCIE_SISTAT 0x50 ++ ++#define MTK_PCIE_HIGH_PERF BIT(14) ++#define PCIEP0_BASE 0x2000 ++#define PCIEP1_BASE 0x3000 ++#define PCIEP2_BASE 0x4000 ++ ++#define PHY_P0_CTL 0x9000 ++#define PHY_P1_CTL 0xA000 ++#define PHY_P2_CTL 0x4000 ++ ++#define RSTCTL_PCIE0_RST BIT(24) ++#define RSTCTL_PCIE1_RST BIT(25) ++#define RSTCTL_PCIE2_RST BIT(26) ++ ++static void __iomem *pcie_base; ++static int pcie_card_link; ++ ++static struct mtk_pcie_port { ++ int id; ++ int enable; ++ u32 base; ++ u32 phy_base; ++ u32 perst_n; ++ u32 reset; ++ u32 interrupt; ++ u32 link; ++} mtk_pcie_port[] = { ++ { 0, 1, PCIEP0_BASE, PHY_P0_CTL, BIT(1), RSTCTL_PCIE0_RST, BIT(20) }, ++ { 1, 1, PCIEP1_BASE, PHY_P1_CTL, BIT(2), RSTCTL_PCIE1_RST, BIT(21) }, ++ { 2, 0, PCIEP2_BASE, PHY_P2_CTL, BIT(3), RSTCTL_PCIE2_RST, BIT(22) }, ++}; ++ ++#define mtk_foreach_port(p) \ ++ for (p = mtk_pcie_port; p != &mtk_pcie_port[ARRAY_SIZE(mtk_pcie_port)]; p++) ++ ++#define mtk_foreach_port_enabled(p) \ ++ mtk_foreach_port(p) \ ++ if (p->enable) ++ ++#define mtk_foreach_port_link(p) \ ++ mtk_foreach_port(p) \ ++ if (p->link) ++ ++static struct mtk_phy_init { ++ uint32_t reg; ++ uint32_t mask; ++ uint32_t val; ++} mtk_phy_init[] = { ++ { 0xC00, 0x33000, 0x22000 }, ++ { 0xB04, 0xe0000000, 0x40000000 }, ++ { 0xB00, 0xe, 0x4 }, ++ { 0xC3C, 0xffff0000, 0x3c0000 }, ++ { 0xC48, 0xffff, 0x36 }, ++ { 0xC0C, 0x30000000, 0x10000000 }, ++ { 0xC08, 0x3800c0, 0xc0 }, ++ { 0xC10, 0xf0000, 0x20000 }, ++ { 0xC0C, 0xf000, 0x1000 }, ++ { 0xC14, 0xf0000, 0xa0000 }, ++}; ++ ++static inline void pcie_w32(u32 val, unsigned reg) ++{ ++ iowrite32(val, pcie_base + reg); ++} ++ ++static inline u32 pcie_r32(unsigned reg) ++{ ++ return ioread32(pcie_base + reg); ++} ++ ++static inline void pcie_m32(u32 mask, u32 val, unsigned reg) ++{ ++ u32 v = pcie_r32(reg); ++ ++ v &= mask; ++ v |= val; ++ pcie_w32(v, reg); ++} ++ ++static int pcie_config_read(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 * val) ++{ ++ unsigned int slot = PCI_SLOT(devfn); ++ u8 func = PCI_FUNC(devfn); ++ u32 address; ++ u32 data; ++ u32 num = 0; ++ ++ if (bus) ++ num = bus->number; ++ ++ address = (((where & 0xF00) >> 8) << 24) | (num << 16) | (slot << 11) | (func << 8) | (where & 0xfc); ++ pcie_m32(0xf0000000, address, CFGADDR); ++ data = pcie_r32(CFGDATA); ++ ++ switch (size) { ++ case 1: ++ *val = (data >> ((where & 3) << 3)) & 0xff; ++ break; ++ case 2: ++ *val = (data >> ((where & 3) << 3)) & 0xffff; ++ break; ++ case 4: ++ *val = data; ++ break; ++ } ++ ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++static int pcie_config_write(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val) ++{ ++ unsigned int slot = PCI_SLOT(devfn); ++ u8 func = PCI_FUNC(devfn); ++ u32 address; ++ u32 data; ++ u32 num = 0; ++ ++ if (bus) ++ num = bus->number; ++ ++ address = (((where & 0xF00) >> 8) << 24) | (num << 16) | (slot << 11) | (func << 8) | (where & 0xfc); ++ pcie_m32(0xf0000000, address, CFGADDR); ++ data = pcie_r32(CFGDATA); ++ ++ switch (size) { ++ case 1: ++ data = (data & ~(0xff << ((where & 3) << 3))) | ++ (val << ((where & 3) << 3)); ++ break; ++ case 2: ++ data = (data & ~(0xffff << ((where & 3) << 3))) | ++ (val << ((where & 3) << 3)); ++ break; ++ case 4: ++ data = val; ++ break; ++ } ++ ++ pcie_w32(data, CFGDATA); ++ ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++static struct pci_ops mtk_pcie_ops = { ++ .read = pcie_config_read, ++ .write = pcie_config_write, ++}; ++ ++static struct resource pci_mem = { ++ .name = "PCIe Memory space", ++ .start = MEM_DIRECT1, ++ .end = (u32) (MEM_DIRECT1 + (unsigned char *) 0x0fffffff), ++ .flags = IORESOURCE_MEM, ++}; ++ ++static struct resource pci_io = { ++ .name = "PCIe IO space", ++ .start = IO_WIN, ++ .end = (u32) (IO_WIN + (unsigned char *) 0x0ffff), ++ .flags = IORESOURCE_IO, ++}; ++ ++static int __init mtk_pcie_setup(int nr, struct pci_sys_data *sys) ++{ ++ sys->mem_offset = 0; ++ sys->io_offset = 0; ++ ++ request_resource(&ioport_resource, &pci_io); ++ request_resource(&iomem_resource, &pci_mem); ++ ++ pci_add_resource_offset(&sys->resources, &pci_io, sys->io_offset); ++ pci_add_resource_offset(&sys->resources, &pci_mem, sys->mem_offset); ++ ++ return 1; ++} ++ ++static struct pci_bus * __init mtk_pcie_scan_bus(int nr, struct pci_sys_data *sys) ++{ ++ return pci_scan_root_bus(NULL, sys->busnr, &mtk_pcie_ops, sys, ++ &sys->resources); ++} ++ ++static int __init mtk_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) ++{ ++ u16 cmd; ++ u32 val; ++ ++ if (dev->bus->number == 0) { ++ pcie_config_write(NULL, slot, 0, PCI_BASE_ADDRESS_0, MEMORY_BASE); ++ pcie_config_read(NULL, slot, 0, PCI_BASE_ADDRESS_0, &val); ++ printk("BAR0 at bus %d, slot %d\n", dev->bus->number, slot); ++ } ++ ++ printk("bus=0x%x, slot = 0x%x, pin=0x%x, irq=0x%x\n", dev->bus->number, slot, pin, dev->irq); ++ ++ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, 0x14); ++ pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xFF); ++ pci_read_config_word(dev, PCI_COMMAND, &cmd); ++ cmd = cmd | PCI_COMMAND_MASTER | PCI_COMMAND_IO | PCI_COMMAND_MEMORY; ++ pci_write_config_word(dev, PCI_COMMAND, cmd); ++ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); ++ ++ return dev->irq; ++} ++ ++static void __init mtk_pcie_preinit(void) ++{ ++ struct mtk_pcie_port *port; ++ u32 val = 0; ++ int i; ++ ++ pcibios_min_io = 0; ++ pcibios_min_mem = 0; ++ ++#if defined (CONFIG_PCIE_PORT2) ++ printk("%s: PCIe/USB3 combo PHY mode (%x) =%x\n", __func__, SYSCFG1, REGDATA(SYSCFG1)); ++ REGDATA(SYSCFG1) &= ~(0x300000); ++ printk("%s: PCIe/USB3 combo PHY mode (%x) =%x\n", __func__, SYSCFG1, REGDATA(SYSCFG1)); ++#endif ++ ++ /* PCIe RC Reset */ ++ val = 0; ++ mtk_foreach_port_enabled(port) ++ val |= port->reset; ++ REGDATA(RSTCTL) |= val; ++ mdelay(10); ++ REGDATA(RSTCTL) &= ~val; ++ mdelay(10); ++ ++ /* Configure PCIe PHY */ ++ mtk_foreach_port_enabled(port) { ++ for (i = 0; i < ARRAY_SIZE(mtk_phy_init); i++) { ++ u32 val = pcie_r32(port->phy_base + mtk_phy_init[i].reg); ++ val &= ~mtk_phy_init[i].mask; ++ val |= mtk_phy_init[i].val; ++ pcie_w32(val, port->phy_base + mtk_phy_init[i].reg); ++ } ++ mdelay(10); ++ } ++ ++ /* Enable RC */ ++ mtk_foreach_port_enabled(port) { ++ val = 0; ++ pcie_config_read(NULL, port->id, 0, 0x73c, &val); ++ val &= ~(0x9fff)<<16; ++ val |= 0x806c<<16; ++ pcie_config_write(NULL, port->id, 0, 0x73c, val); ++ } ++ ++ /* PCIe EP reset */ ++ val = 0; ++ mtk_foreach_port_enabled(port) ++ val |= port->perst_n; ++ val |= MTK_PCIE_HIGH_PERF; ++ pcie_w32(pcie_r32(PCICFG) | val, PCICFG); ++ mdelay(10); ++ pcie_w32(pcie_r32(PCICFG) & ~val, PCICFG); ++ mdelay(10); ++ ++ /* check the link status */ ++ val = 0; ++ mtk_foreach_port_enabled(port) { ++ if ((pcie_r32(port->base + PCIE_SISTAT) & 0x1)) ++ port->link = 1; ++ else ++ val |= port->reset; ++ } ++ REGDATA(RSTCTL) |= val; ++ ++ mtk_foreach_port_link(port) ++ pcie_card_link++; ++ ++ printk("PCIe Link count = %d\n", pcie_card_link); ++ if (!pcie_card_link) ++ return; ++ ++ pcie_w32(MEM_WIN, MEMBASE); ++ pcie_w32(IO_WIN, IOBASE); ++ ++ mtk_foreach_port_link(port) { ++ pcie_m32(0, port->interrupt, PCIENA); ++ pcie_w32(0x7FFF0001, port->base + BAR0SETUP); ++ pcie_w32(MEMORY_BASE, port->base + IMBASEBAR0); ++ pcie_w32(0x06040001, port->base + PCIE_CLASS); ++ printk("PCIE%d Setup OK\n", port->id); ++ } ++ val = 0; ++ ++ pcie_config_read(NULL, pcie_card_link - 1, 0, 0x4, &val); ++ pcie_config_write(NULL, pcie_card_link - 1, 0, 0x4, val|0x4); ++ pcie_config_read(NULL, pcie_card_link - 1, 0, 0x70c, &val); ++ val &= ~(0xff3) << 8; ++ val |= 0x50 << 8; ++ pcie_config_write(NULL, pcie_card_link - 1, 0, 0x70c, val); ++ pcie_config_read(NULL, pcie_card_link - 1, 0, 0x70c, &val); ++} ++ ++static struct hw_pci mtk_pci __initdata = { ++ .nr_controllers = 1, ++ .map_irq = mtk_pcie_map_irq, ++ .setup = mtk_pcie_setup, ++ .scan = mtk_pcie_scan_bus, ++ .preinit = mtk_pcie_preinit, ++}; ++ ++extern void mt7623_ethifsys_init(void); ++static int mtk_pcie_probe(struct platform_device *pdev) ++{ ++ struct resource *pcie_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ ++ pcie_base = devm_ioremap_resource(&pdev->dev, pcie_res); ++ if (!pcie_base) ++ return -ENOMEM; ++ ++ mt7623_ethifsys_init(); ++ pci_common_init_dev(&pdev->dev, &mtk_pci); ++ ++ return 0; ++} ++ ++static const struct of_device_id mtk_pcie_ids[] = { ++ { .compatible = "mediatek,mt7623-pcie" }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, mtk_pcie_ids); ++ ++static struct platform_driver mtk_pcie_driver = { ++ .probe = mtk_pcie_probe, ++ .driver = { ++ .name = "mt7623-pcie", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(mtk_pcie_ids), ++ }, ++}; ++ ++static int __init mtk_pcie_init(void) ++{ ++ return platform_driver_register(&mtk_pcie_driver); ++} ++ ++late_initcall(mtk_pcie_init); +diff --git a/arch/arm/mach-mediatek/pcie.h b/arch/arm/mach-mediatek/pcie.h +new file mode 100644 +index 0000000..400a760e +--- /dev/null ++++ b/arch/arm/mach-mediatek/pcie.h +@@ -0,0 +1,14 @@ ++#define SYSCTL_BASE 0xFA000000 ++#define MEM_WIN 0x1A150000 ++#define IO_WIN 0x1A160000 ++#define MEM_DIRECT1 0x60000000 ++#define MEMORY_BASE 0x80000000 ++ ++#define REGADDR(x, y) (x##_BASE + y) ++#define REGDATA(x) *((volatile unsigned int *)(x)) ++ ++#define SYSCFG1 REGADDR(SYSCTL, 0x14) ++#define RSTCTL REGADDR(SYSCTL, 0x34) ++ ++ ++ +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0065-arm-mediatek-add-mt7623-smp-support.patch b/target/linux/mediatek/patches/0065-arm-mediatek-add-mt7623-smp-support.patch new file mode 100644 index 0000000000..98f8acb63c --- /dev/null +++ b/target/linux/mediatek/patches/0065-arm-mediatek-add-mt7623-smp-support.patch @@ -0,0 +1,38 @@ +From 3f181d60fcd80b0d98849076ed2aa43de2cb6d8c Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Sat, 27 Jun 2015 13:16:27 +0200 +Subject: [PATCH 65/76] arm: mediatek: add mt7623 smp support + +Signed-off-by: John Crispin <blogic@openwrt.org> +--- + arch/arm/mach-mediatek/platsmp.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/arch/arm/mach-mediatek/platsmp.c b/arch/arm/mach-mediatek/platsmp.c +index e266b3d..81fdcff 100644 +--- a/arch/arm/mach-mediatek/platsmp.c ++++ b/arch/arm/mach-mediatek/platsmp.c +@@ -45,6 +45,12 @@ static const struct mtk_smp_boot_info mtk_mt6589_boot = { + { 0x38, 0x3c, 0x40 }, + }; + ++static const struct mtk_smp_boot_info mtk_mt7623_boot = { ++ 0x10202000, 0x34, 0x30, ++ { 0x534c4131, 0x4c415332, 0x41534c33 }, ++ { 0x38, 0x3c, 0x40 }, ++}; ++ + static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = { + { .compatible = "mediatek,mt8135", .data = &mtk_mt8135_tz_boot }, + { .compatible = "mediatek,mt8127", .data = &mtk_mt8135_tz_boot }, +@@ -52,6 +58,7 @@ static const struct of_device_id mtk_tz_smp_boot_infos[] __initconst = { + + static const struct of_device_id mtk_smp_boot_infos[] __initconst = { + { .compatible = "mediatek,mt6589", .data = &mtk_mt6589_boot }, ++ { .compatible = "mediatek,mt7623", .data = &mtk_mt7623_boot }, + }; + + static void __iomem *mtk_smp_base; +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0066-arm-mediatek-add-m7623-devicetree.patch b/target/linux/mediatek/patches/0066-arm-mediatek-add-m7623-devicetree.patch new file mode 100644 index 0000000000..4516561b3f --- /dev/null +++ b/target/linux/mediatek/patches/0066-arm-mediatek-add-m7623-devicetree.patch @@ -0,0 +1,551 @@ +From a6bf117b5fe3acd76bbc45cc87fd80f589136e59 Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Sat, 27 Jun 2015 13:14:42 +0200 +Subject: [PATCH 66/76] arm: mediatek: add m7623 devicetree + +Signed-off-by: John Crispin <blogic@openwrt.org> +--- + arch/arm/boot/dts/Makefile | 1 + + arch/arm/boot/dts/mt7623-evb.dts | 162 ++++++++++++++++++ + arch/arm/boot/dts/mt7623.dtsi | 348 ++++++++++++++++++++++++++++++++++++++ + 3 files changed, 511 insertions(+) + create mode 100644 arch/arm/boot/dts/mt7623-evb.dts + create mode 100644 arch/arm/boot/dts/mt7623.dtsi + +diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +index 992736b..525392e 100644 +--- a/arch/arm/boot/dts/Makefile ++++ b/arch/arm/boot/dts/Makefile +@@ -658,6 +658,7 @@ dtb-$(CONFIG_MACH_DOVE) += \ + dtb-$(CONFIG_ARCH_MEDIATEK) += \ + mt6589-aquaris5.dtb \ + mt6592-evb.dtb \ ++ mt7623-evb.dtb \ + mt8127-moose.dtb \ + mt8135-evbp1.dtb + endif +diff --git a/arch/arm/boot/dts/mt7623-evb.dts b/arch/arm/boot/dts/mt7623-evb.dts +new file mode 100644 +index 0000000..759142f +--- /dev/null ++++ b/arch/arm/boot/dts/mt7623-evb.dts +@@ -0,0 +1,162 @@ ++/* ++ * Copyright (c) 2014 MediaTek Inc. ++ * Author: Joe.C <yingjoe.chen@mediatek.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++/dts-v1/; ++#include <dt-bindings/gpio/gpio.h> ++#include "mt7623.dtsi" ++ ++/ { ++ model = "MediaTek MT7623 Evaluation Board"; ++ compatible = "mediatek,mt7623-evb", "mediatek,mt7623"; ++ ++ chosen { ++ stdout-path = &uart2; ++ }; ++ ++ memory { ++ reg = <0 0x80000000 0 0x10000000>; ++ }; ++ ++ usb_p1_vbus: fixedregulator@0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "usb_vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ gpio = <&pio 130 GPIO_ACTIVE_HIGH>; ++ enable-active-high; ++ }; ++}; ++ ++ ++&pio { ++ pinctrl_uart2_default: uart2@0 { ++ pins { ++ pinmux = <MT7623_PIN_14_GPIO14_FUNC_URXD2>, ++ <MT7623_PIN_15_GPIO15_FUNC_UTXD2>; ++ }; ++ }; ++ ++ pinctrl_i2c0_default: i2c@0 { ++ pins { ++ pinmux = <MT7623_PIN_75_SDA0_FUNC_SDA0>, ++ <MT7623_PIN_76_SCL0_FUNC_SCL0>; ++ }; ++ }; ++ ++ pinctrl_pcie_default: pcie@0 { ++ pins { ++ pinmux = <MT7623_PIN_24_EINT2_FUNC_PCIE2_PERST_N>, ++ <MT7623_PIN_208_AUD_EXT_CK1_FUNC_PCIE0_PERST_N>, ++ <MT7623_PIN_209_AUD_EXT_CK2_FUNC_PCIE1_PERST_N>, ++ <MT7623_PIN_250_GPIO250_FUNC_PCIE0_CLKREQ_N>, ++ <MT7623_PIN_251_GPIO251_FUNC_PCIE0_WAKE_N>, ++ <MT7623_PIN_252_GPIO252_FUNC_PCIE1_CLKREQ_N>, ++ <MT7623_PIN_253_GPIO253_FUNC_PCIE1_WAKE_N>, ++ <MT7623_PIN_254_GPIO254_FUNC_PCIE2_CLKREQ_N>, ++ <MT7623_PIN_255_GPIO255_FUNC_PCIE2_WAKE_N>; ++ }; ++ }; ++ ++ pinctrl_spi_default: spi@0 { ++ pins { ++ pinmux = <MT7623_PIN_7_SPI1_CSN_FUNC_SPI1_CS>, ++ <MT7623_PIN_8_SPI1_MI_FUNC_SPI1_MI>, ++ <MT7623_PIN_9_SPI1_MO_FUNC_SPI1_MO>, ++ <MT7623_PIN_199_SPI1_CK_FUNC_SPI1_CK>; ++ bias-disable; ++ }; ++ }; ++}; ++ ++&thermal { ++ status = "okay"; ++}; ++ ++&uart2 { ++ status = "okay"; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_uart2_default>; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_i2c0_default>; ++}; ++ ++&spi { ++ status = "okay"; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_spi_default>; ++ ++ m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "mx25l12805d"; ++ reg = <0 0 0 0>; ++ linux,modalias = "m25p80", "w25q128"; ++ spi-max-frequency = <10000000>; ++ ++ partition@0 { ++ label = "u-boot"; ++ reg = <0x0 0x30000>; ++ read-only; ++ }; ++ ++ partition@30000 { ++ label = "u-boot-env"; ++ reg = <0x30000 0x10000>; ++ read-only; ++ }; ++ ++ factory: partition@40000 { ++ label = "factory"; ++ reg = <0x40000 0x10000>; ++ read-only; ++ }; ++ ++ partition@50000 { ++ label = "firmware"; ++ reg = <0x50000 0xfb0000>; ++ }; ++ }; ++}; ++ ++&mmc0 { ++ status = "okay"; ++ ++// pinctrl-names = "default", "state_uhs"; ++// pinctrl-0 = <&mmc0_pins_default>; ++// pinctrl-1 = <&mmc0_pins_uhs>; ++ bus-width = <8>; ++ max-frequency = <50000000>; ++ cap-mmc-highspeed; ++// vmmc-supply = <&mt6397_vemc_3v3_reg>; ++// vqmmc-supply = <&mt6397_vio18_reg>; ++ non-removable; ++}; ++ ++&u3phy { ++ reg-p1-vbus-supply = <&usb_p1_vbus>; ++}; ++ ++&pcie { ++ status = "okay"; ++ ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_pcie_default>; ++}; +diff --git a/arch/arm/boot/dts/mt7623.dtsi b/arch/arm/boot/dts/mt7623.dtsi +new file mode 100644 +index 0000000..ba74ed9 +--- /dev/null ++++ b/arch/arm/boot/dts/mt7623.dtsi +@@ -0,0 +1,348 @@ ++/* ++ * Copyright (c) 2014 MediaTek Inc. ++ * Author: Joe.C <yingjoe.chen@mediatek.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <dt-bindings/clock/mt7623-clk.h> ++#include <dt-bindings/interrupt-controller/irq.h> ++#include <dt-bindings/interrupt-controller/arm-gic.h> ++#include <dt-bindings/pinctrl/mt7623-pinfunc.h> ++#include <dt-bindings/reset-controller/mt7623-resets.h> ++#include "skeleton64.dtsi" ++ ++/ { ++ compatible = "mediatek,mt7623"; ++ interrupt-parent = <&sysirq>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ enable-method = "mediatek,mt65xx-smp"; ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0x0>; ++ }; ++ cpu@1 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0x1>; ++ }; ++ cpu@2 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0x2>; ++ }; ++ cpu@3 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a7"; ++ reg = <0x3>; ++ }; ++ ++ }; ++ ++ clk26m: oscillator@0 { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <26000000>; ++ clock-output-names = "clk26m"; ++ }; ++ ++ clk32k: oscillator@1 { ++ compatible = "fixed-clock"; ++ #clock-cells = <0>; ++ clock-frequency = <32000>; ++ clock-output-names = "clk32k"; ++ }; ++ ++ timer { ++ compatible = "arm,armv7-timer"; ++ interrupt-parent = <&gic>; ++ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(4) | ++ IRQ_TYPE_LEVEL_LOW)>, ++ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(4) | ++ IRQ_TYPE_LEVEL_LOW)>, ++ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | ++ IRQ_TYPE_LEVEL_LOW)>, ++ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | ++ IRQ_TYPE_LEVEL_LOW)>; ++ clock-frequency = <13000000>; ++ arm,cpu-registers-not-fw-configured; ++ }; ++ ++ thermal-zones { ++ cpu_thermal: cpu_thermal { ++ polling-delay-passive = <1000>; ++ polling-delay = <5000>; ++ ++ thermal-sensors = <&thermal 1>; ++ }; ++ }; ++ ++ soc { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ compatible = "simple-bus"; ++ ranges; ++ ++ topckgen: topckgen@10000000 { ++ compatible = "mediatek,mt7623-topckgen"; ++ reg = <0 0x10000000 0 0x1000>; ++ #clock-cells = <1>; ++ }; ++ ++ infracfg: infracfg@10001000 { ++ compatible = "mediatek,mt7623-infracfg", "syscon"; ++ reg = <0 0x10001000 0 0x1000>; ++ #clock-cells = <1>; ++ #reset-cells = <1>; ++ }; ++ ++ pericfg: pericfg@10003000 { ++ compatible = "mediatek,mt7623-pericfg", "syscon"; ++ reg = <0 0x10003000 0 0x1000>; ++ #clock-cells = <1>; ++ #reset-cells = <1>; ++ }; ++ ++ /* ++ * Pinctrl access register at 0x10005000 through regmap. ++ * Register 0x1000b000 is used by EINT. ++ */ ++ pio: pinctrl@10005000 { ++ compatible = "mediatek,mt7623-pinctrl"; ++ reg = <0 0x1000b000 0 0x1000>; ++ mediatek,pctl-regmap = <&syscfg_pctl_a>; ++ pins-are-numbered; ++ gpio-controller; ++ #gpio-cells = <2>; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; ++ }; ++ ++ syscfg_pctl_a: syscfg_pctl_a@10005000 { ++ compatible = "mediatek,mt7623-pctl-a-syscfg", "syscon"; ++ reg = <0 0x10005000 0 0x1000>; ++ }; ++ ++ wdt: watchdog@10007000 { ++ compatible = "mediatek,mt7623-wdt", "mediatek,mt6589-wdt"; ++ reg = <0 0x10007000 0 0x18>; ++ }; ++ ++ timer: timer@10008000 { ++ compatible = "mediatek,mt7623-timer", ++ "mediatek,mt6577-timer"; ++ reg = <0 0x10008000 0 0x80>; ++ interrupts = <GIC_SPI 112 IRQ_TYPE_LEVEL_LOW>; ++ clocks = <&topckgen CLK_TOP_AXI_SEL>, ++ <&topckgen CLK_TOP_RTC_SEL>; ++ clock-names = "system-clk", "rtc-clk"; ++ }; ++ ++ sysirq: interrupt-controller@10200100 { ++ compatible = "mediatek,mt7623-sysirq", ++ "mediatek,mt6577-sysirq"; ++ interrupt-controller; ++ #interrupt-cells = <3>; ++ interrupt-parent = <&gic>; ++ reg = <0 0x10200100 0 0x1c>; ++ }; ++ ++ apmixedsys: apmixedsys@10209000 { ++ compatible = "mediatek,mt7623-apmixedsys"; ++ reg = <0 0x10209000 0 0x1000>; ++ #clock-cells = <1>; ++ }; ++ ++ gic: interrupt-controller@10211000 { ++ compatible = "arm,cortex-a7-gic"; ++ interrupt-controller; ++ #interrupt-cells = <3>; ++ interrupt-parent = <&gic>; ++ reg = <0 0x10211000 0 0x1000>, ++ <0 0x10212000 0 0x1000>, ++ <0 0x10214000 0 0x2000>, ++ <0 0x10216000 0 0x2000>; ++ }; ++ ++ auxadc: auxadc@11001000 { ++ compatible = "mediatek,mt7623-auxadc", "mediatek,mt8173-auxadc"; ++ reg = <0 0x11001000 0 0x1000>; ++ }; ++ ++ uart0: serial@11006000 { ++ compatible = "mediatek,mt7623-uart","mediatek,mt6577-uart"; ++ reg = <0 0x11002000 0 0x400>; ++ interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_LOW>; ++ clocks = <&pericfg CLK_PERI_UART0_SEL>, <&pericfg CLK_PERI_UART0>; ++ clock-names = "baud", "bus"; ++ ++ status = "disabled"; ++ }; ++ ++ uart1: serial@11007000 { ++ compatible = "mediatek,mt7623-uart","mediatek,mt6577-uart"; ++ reg = <0 0x11003000 0 0x400>; ++ interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_LOW>; ++ clocks = <&pericfg CLK_PERI_UART1_SEL>, <&pericfg CLK_PERI_UART1>; ++ clock-names = "baud", "bus"; ++ ++ status = "disabled"; ++ }; ++ ++ uart2: serial@11008000 { ++ compatible = "mediatek,mt7623-uart","mediatek,mt6577-uart"; ++ reg = <0 0x11004000 0 0x400>; ++ interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_LOW>; ++ clocks = <&pericfg CLK_PERI_UART2_SEL>, <&pericfg CLK_PERI_UART2>; ++ clock-names = "baud", "bus"; ++ ++ status = "disabled"; ++ }; ++ ++ uart3: serial@11009000 { ++ compatible = "mediatek,mt7623-uart","mediatek,mt6577-uart"; ++ reg = <0 0x11005000 0 0x400>; ++ interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_LOW>; ++ clocks = <&pericfg CLK_PERI_UART3_SEL>, <&pericfg CLK_PERI_UART3>; ++ clock-names = "baud", "bus"; ++ ++ status = "disabled"; ++ }; ++ ++ spi: spi@1100a000 { ++ compatible = "medi/THEatek,mt7623-spi", "mediatek,mt6589-spi"; ++ reg = <0 0x1100a000 0 0x1000>; ++ interrupts = <GIC_SPI 78 IRQ_TYPE_LEVEL_LOW>; ++ clocks = <&pericfg CLK_PERI_SPI0>; ++ clock-names = "main"; ++ ++ status = "disabled"; ++ }; ++ ++ thermal: thermal@1100b000 { ++ #thermal-sensor-cells = <1>; ++ compatible = "mediatek,mt7623-thermal", "mediatek,mt8173-thermal"; ++ reg = <0 0x1100b000 0 0x1000>; ++ interrupts = <0 38 IRQ_TYPE_LEVEL_LOW>; ++ clocks = <&pericfg CLK_PERI_THERM>, <&pericfg CLK_PERI_AUXADC>; ++ clock-names = "therm", "auxadc"; ++ resets = <&pericfg MT7623_PERI_THERM_SW_RST>; ++ reset-names = "therm"; ++ auxadc = <&auxadc>; ++ apmixedsys = <&apmixedsys>; ++ ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@11007000 { ++ compatible = "mediatek,mt7623-i2c", "mediatek,mt6577-i2c"; ++ reg = <0 0x11007000 0 0x70>, ++ <0 0x11000300 0 0x80>; ++ interrupts = <0 44 IRQ_TYPE_LEVEL_LOW>; ++ clock-frequency = <400000>; ++ clock-div = <16>; ++ clocks = <&pericfg CLK_PERI_I2C0>, <&pericfg CLK_PERI_AP_DMA>; ++ clock-names = "main", "dma"; ++ ++ status = "disabled"; ++ }; ++ ++ mmc0: mmc@11230000 { ++ compatible = "mediatek,mt7623-mmc", ++ "mediatek,mt8135-mmc"; ++ reg = <0 0x11230000 0 0x1000>; ++ interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_LOW>; ++ clocks = <&pericfg CLK_PERI_MSDC20_1>, ++ <&topckgen CLK_TOP_MSDC30_0_SEL>; ++ clock-names = "source", "hclk"; ++ status = "disabled"; ++ }; ++ ++ usb: usb30@11270000 { ++ compatible = "mediatek,mt7623-xhci", "mediatek,mt8173-xhci", "generic-xhci"; ++ reg = <0 0x11270000 0 0x1000>; ++ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_LOW>; ++ usb-phy = <&u3phy>; ++ usb3-lpm-capable; ++ }; ++ ++ u3phy: usb-phy@11271000 { ++ compatible = "mediatek,mt7623-u3phy", "mediatek,mt8173-u3phy"; ++ reg = <0 0x11271000 0 0x3000>, ++ <0 0x11280000 0 0x20000>; ++// power-domains = <&scpsys MT8173_POWER_DOMAIN_USB>; ++// reg-vusb33-supply = <&mt6397_vusb_reg>; ++ clocks = <&pericfg CLK_PERI_USB0>, ++ <&pericfg CLK_PERI_USB1>, ++ <&topckgen CLK_TOP_USB20_SEL>; ++// <&apmixedsys CLK_APMIXED_REF2USB_TX>; ++ clock-names = "wakeup_deb_p0", ++ "wakeup_deb_p1", ++ "sys_mac"; ++// "u3phya_ref"; ++ disable-usb2-p1; ++ }; ++ }; ++ ++ ethernet@1B100000 { ++ compatible = "mediatek,mt7623-net"; ++ interrupts = <0 200 IRQ_TYPE_LEVEL_LOW>; ++ }; ++ ++ pcie: pcie@1a140000 { ++ compatible = "mediatek,mt7623-pcie"; ++ reg = <0 0x1a140000 0 0x10000>; ++ ++ #address-cells = <3>; ++ #size-cells = <2>; ++ ++ device_type = "pci"; ++ ++ bus-range = <0 255>; ++ ranges = < ++ 0x02000000 0 0 0x00000000 0x60000000 0 0x10000000 /* pci memory */ ++ 0x01000000 0 0 0x00000000 0x1A160000 0 0x00010000 /* io space */ ++ >; ++ ++ pcie0 { ++ reg = <0x0000 0 0 0 0>; ++ ++ #address-cells = <3>; ++ #size-cells = <2>; ++ ++ device_type = "pci"; ++ }; ++ ++ pcie1 { ++ reg = <0x0800 0 0 0 0>; ++ ++ #address-cells = <3>; ++ #size-cells = <2>; ++ ++ device_type = "pci"; ++ }; ++ ++ pcie2 { ++ reg = <0x1000 0 0 0 0>; ++ ++ #address-cells = <3>; ++ #size-cells = <2>; ++ ++ device_type = "pci"; ++ }; ++ ++ status = "disabled"; ++ }; ++}; +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0067-arm-mediatek-add-mt7623-support.patch b/target/linux/mediatek/patches/0067-arm-mediatek-add-mt7623-support.patch new file mode 100644 index 0000000000..28193cc86c --- /dev/null +++ b/target/linux/mediatek/patches/0067-arm-mediatek-add-mt7623-support.patch @@ -0,0 +1,118 @@ +From 89556b1a4d98fbfe498c8f26e988cbb8266f7dfe Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Sat, 27 Jun 2015 13:17:35 +0200 +Subject: [PATCH 67/76] arm: mediatek: add mt7623 support + +Signed-off-by: John Crispin <blogic@openwrt.org> +--- + arch/arm/mach-mediatek/Kconfig | 6 ++ + arch/arm/mach-mediatek/mediatek.c | 2 + + .../dt-bindings/reset-controller/mt7623-resets.h | 59 ++++++++++++++++++++ + 3 files changed, 67 insertions(+) + create mode 100644 include/dt-bindings/reset-controller/mt7623-resets.h + +diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig +index 7704818..5393d25 100644 +--- a/arch/arm/mach-mediatek/Kconfig ++++ b/arch/arm/mach-mediatek/Kconfig +@@ -17,6 +17,12 @@ config MACH_MT6592 + bool "MediaTek MT6592 SoCs support" + default ARCH_MEDIATEK + ++config MACH_MT7623 ++ bool "MediaTek MT7623 SoCs support" ++ default ARCH_MEDIATEK ++ select ARCH_HAS_PCI ++ select PCI ++ + config MACH_MT8127 + bool "MediaTek MT8127 SoCs support" + default ARCH_MEDIATEK +diff --git a/arch/arm/mach-mediatek/mediatek.c b/arch/arm/mach-mediatek/mediatek.c +index 6b38d67..ab8cf21 100644 +--- a/arch/arm/mach-mediatek/mediatek.c ++++ b/arch/arm/mach-mediatek/mediatek.c +@@ -29,6 +29,7 @@ static void __init mediatek_timer_init(void) + void __iomem *gpt_base = 0; + + if (of_machine_is_compatible("mediatek,mt6589") || ++ of_machine_is_compatible("mediatek,mt7623") || + of_machine_is_compatible("mediatek,mt8135") || + of_machine_is_compatible("mediatek,mt8127")) { + /* turn on GPT6 which ungates arch timer clocks */ +@@ -48,6 +49,7 @@ static void __init mediatek_timer_init(void) + static const char * const mediatek_board_dt_compat[] = { + "mediatek,mt6589", + "mediatek,mt6592", ++ "mediatek,mt7623", + "mediatek,mt8127", + "mediatek,mt8135", + NULL, +diff --git a/include/dt-bindings/reset-controller/mt7623-resets.h b/include/dt-bindings/reset-controller/mt7623-resets.h +new file mode 100644 +index 0000000..28a7d69 +--- /dev/null ++++ b/include/dt-bindings/reset-controller/mt7623-resets.h +@@ -0,0 +1,59 @@ ++/* ++ * Copyright (c) 2015 OpenWrt ++ * Author: John Crispin ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _DT_BINDINGS_RESET_CONTROLLER_MT7623 ++#define _DT_BINDINGS_RESET_CONTROLLER_MT7623 ++ ++/* INFRACFG resets */ ++#define MT7623_INFRA_EMI_REG_RST 0 ++#define MT7623_INFRA_DRAMC0_A0_RST 1 ++#define MT7623_INFRA_FHCTL_RST 2 ++#define MT7623_INFRA_APCIRQ_EINT_RST 3 ++#define MT7623_INFRA_APXGPT_RST 4 ++#define MT7623_INFRA_SCPSYS_RST 5 ++#define MT7623_INFRA_KP_RST 6 ++#define MT7623_INFRA_PMIC_WRAP_RST 7 ++#define MT7623_INFRA_MIPI_RST 8 ++#define MT7623_INFRA_IRRX_RST 9 ++#define MT7623_INFRA_CEC_RST 10 ++#define MT7623_INFRA_EMI_RST 32 ++#define MT7623_INFRA_DRAMC0_RST 34 ++#define MT7623_INFRA_SMI_RST 37 ++#define MT7623_INFRA_M4U_RST 38 ++ ++/* PERICFG resets */ ++#define MT7623_PERI_UART0_SW_RST 0 ++#define MT7623_PERI_UART1_SW_RST 1 ++#define MT7623_PERI_UART2_SW_RST 2 ++#define MT7623_PERI_UART3_SW_RST 3 ++#define MT7623_PERI_GCPU_SW_RST 5 ++#define MT7623_PERI_BTIF_SW_RST 6 ++#define MT7623_PERI_PWM_SW_RST 8 ++#define MT7623_PERI_AUXADC_SW_RST 10 ++#define MT7623_PERI_DMA_SW_RST 11 ++#define MT7623_PERI_NFI_SW_RST 14 ++#define MT7623_PERI_NLI_SW_RST 15 ++#define MT7623_PERI_THERM_SW_RST 16 ++#define MT7623_PERI_MSDC0_SW_RST 17 ++#define MT7623_PERI_MSDC1_SW_RST 19 ++#define MT7623_PERI_MSDC2_SW_RST 20 ++#define MT7623_PERI_I2C0_SW_RST 22 ++#define MT7623_PERI_I2C1_SW_RST 23 ++#define MT7623_PERI_I2C2_SW_RST 24 ++#define MT7623_PERI_I2C3_SW_RST 25 ++#define MT7623_PERI_USB_SW_RST 28 ++#define MT7623_PERI_ETH_SW_RST 29 ++#define MT7623_PERI_SPI0_SW_RST 33 ++ ++#endif /* _DT_BINDINGS_RESET_CONTROLLER_MT7623 */ +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0068-SDK_compat.patch b/target/linux/mediatek/patches/0068-SDK_compat.patch new file mode 100644 index 0000000000..2800dbd009 --- /dev/null +++ b/target/linux/mediatek/patches/0068-SDK_compat.patch @@ -0,0 +1,1579 @@ +From 4c48177826502673737609ffa04b66051a1e0f75 Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Sat, 27 Jun 2015 17:05:12 +0200 +Subject: [PATCH 68/76] SDK_compat + +--- + arch/arm/include/asm/mach/mt_irq.h | 174 ++++++++ + arch/arm/include/asm/rt2880/mt_irq.h | 174 ++++++++ + arch/arm/include/asm/rt2880/rt_mmap.h | 58 +++ + arch/arm/include/asm/rt2880/surfboardint.h | 42 ++ + arch/arm/include/asm/rt2880/x_define_irq.h | 160 +++++++ + arch/arm/mach-mediatek/mediatek.c | 186 ++++++++ + arch/arm/mach-mediatek/mt_reg_base.h | 640 ++++++++++++++++++++++++++++ + arch/arm/mach-mediatek/rt_mmap.h | 58 +++ + 8 files changed, 1492 insertions(+) + create mode 100644 arch/arm/include/asm/mach/mt_irq.h + create mode 100644 arch/arm/include/asm/rt2880/mt_irq.h + create mode 100644 arch/arm/include/asm/rt2880/rt_mmap.h + create mode 100644 arch/arm/include/asm/rt2880/surfboardint.h + create mode 100644 arch/arm/include/asm/rt2880/x_define_irq.h + create mode 100644 arch/arm/mach-mediatek/mt_reg_base.h + create mode 100644 arch/arm/mach-mediatek/rt_mmap.h + +diff --git a/arch/arm/include/asm/mach/mt_irq.h b/arch/arm/include/asm/mach/mt_irq.h +new file mode 100644 +index 0000000..ff265e0 +--- /dev/null ++++ b/arch/arm/include/asm/mach/mt_irq.h +@@ -0,0 +1,174 @@ ++#ifndef __MT_IRQ_H ++#define __MT_IRQ_H ++ ++#define GIC_PRIVATE_SIGNALS (32) ++#define NR_GIC_SGI (16) ++#define NR_GIC_PPI (16) ++#define GIC_PPI_OFFSET (27) ++#define MT_NR_PPI (5) ++#define MT_NR_SPI (224) ++#define NR_MT_IRQ_LINE (GIC_PPI_OFFSET + MT_NR_PPI + MT_NR_SPI) ++ ++#define MT65xx_EDGE_SENSITIVE 0 ++#define MT65xx_LEVEL_SENSITIVE 1 ++ ++#define MT65xx_POLARITY_LOW 0 ++#define MT65xx_POLARITY_HIGH 1 ++ ++#define GIC_PPI_GLOBAL_TIMER (GIC_PPI_OFFSET + 0) ++#define GIC_PPI_LEGACY_FIQ (GIC_PPI_OFFSET + 1) ++#define GIC_PPI_PRIVATE_TIMER (GIC_PPI_OFFSET + 2) ++#define GIC_PPI_NS_PRIVATE_TIMER (GIC_PPI_OFFSET + 3) ++#define GIC_PPI_LEGACY_IRQ (GIC_PPI_OFFSET + 4) ++ ++#define MT_BTIF_IRQ_ID (GIC_PRIVATE_SIGNALS + 50) ++#define MT_DMA_BTIF_TX_IRQ_ID (GIC_PRIVATE_SIGNALS + 71) ++#define MT_DMA_BTIF_RX_IRQ_ID (GIC_PRIVATE_SIGNALS + 72) ++ ++#if !defined(CONFIG_MT8127_FPGA) ++ ++#if !defined(__ASSEMBLY__) ++#define X_DEFINE_IRQ(__name, __num, __pol, __sens) __name = __num, ++enum ++{ ++#include "x_define_irq.h" ++}; ++#undef X_DEFINE_IRQ ++#define MT6582_AHB_SLAVE_HIF_IRQ_ID WF_HIF_IRQ_ID /* FIXME */ ++ ++#endif ++ ++#else ++ ++#define MT6582_USB0_IRQ_ID (GIC_PRIVATE_SIGNALS + 32) ++#define MT6582_USB1_IRQ_ID (GIC_PRIVATE_SIGNALS + 33) ++#define MT_PTP_THERM_IRQ_ID (GIC_PRIVATE_SIGNALS + 38) ++#define MT_MSDC0_IRQ_ID (GIC_PRIVATE_SIGNALS + 39) ++#define MT_MSDC1_IRQ_ID (GIC_PRIVATE_SIGNALS + 40) ++//#define MT_MSDC2_IRQ_ID (GIC_PRIVATE_SIGNALS + 41) //6582 take off ++//#define MT_MSDC3_IRQ_ID (GIC_PRIVATE_SIGNALS + 42) //6582 take off ++#define MT6582_AP_HIF_IRQ_ID (GIC_PRIVATE_SIGNALS + 43) ++#define MT_I2C0_IRQ_ID (GIC_PRIVATE_SIGNALS + 44) ++#define MT_I2C1_IRQ_ID (GIC_PRIVATE_SIGNALS + 45) ++#define MT_I2C2_IRQ_ID (GIC_PRIVATE_SIGNALS + 46) ++#define MT_UART1_IRQ_ID (GIC_PRIVATE_SIGNALS + 51) ++#define MT_UART2_IRQ_ID (GIC_PRIVATE_SIGNALS + 52) ++#define MT_UART3_IRQ_ID (GIC_PRIVATE_SIGNALS + 53) ++#define MT_UART4_IRQ_ID (GIC_PRIVATE_SIGNALS + 54) ++#define MT_NFIECC_IRQ_ID (GIC_PRIVATE_SIGNALS + 55) ++#define MT_NFI_IRQ_ID (GIC_PRIVATE_SIGNALS + 56) ++#define MT_GDMA1_IRQ_ID (GIC_PRIVATE_SIGNALS + 57) ++#define MT_GDMA2_IRQ_ID (GIC_PRIVATE_SIGNALS + 58) ++#define MT_DMA_UART0_TX_IRQ_ID (GIC_PRIVATE_SIGNALS + 63) ++#define MT_DMA_UART0_RX_IRQ_ID (GIC_PRIVATE_SIGNALS + 64) ++#define MT_DMA_UART1_TX_IRQ_ID (GIC_PRIVATE_SIGNALS + 65) ++#define MT_DMA_UART1_RX_IRQ_ID (GIC_PRIVATE_SIGNALS + 66) ++#define MT_DMA_UART2_TX_IRQ_ID (GIC_PRIVATE_SIGNALS + 67) ++#define MT_DMA_UART2_RX_IRQ_ID (GIC_PRIVATE_SIGNALS + 68) ++#define MT6582_SPI1_IRQ_ID (GIC_PRIVATE_SIGNALS + 78) ++//#define MT_MSDC4_IRQ_ID (GIC_PRIVATE_SIGNALS + 83) //6582 take off ++#define MT_PTP_FSM_IRQ_ID (GIC_PRIVATE_SIGNALS + 85) ++#define MT_WDT_IRQ_ID (GIC_PRIVATE_SIGNALS + 88)//TBD:For build pass ++#define MT_APARM_DOMAIN_IRQ_ID (GIC_PRIVATE_SIGNALS + 94) ++#define MT_APARM_DECERR_IRQ_ID (GIC_PRIVATE_SIGNALS + 95) ++#if 1 //cliff ++#define MT6582_GPT_IRQ_ID (GIC_PRIVATE_SIGNALS + 112)//10.2 update ++#define MT_EINT_IRQ_ID (GIC_PRIVATE_SIGNALS + 113)//10.2 update ++#else ++#define MT6582_GPT_IRQ_ID (GIC_PRIVATE_SIGNALS + 113)//10.2 update ++#define MT_EINT_IRQ_ID (GIC_PRIVATE_SIGNALS + 116)//10.2 update ++#endif ++#define MT6582_PMIC_WRAP_IRQ_ID (GIC_PRIVATE_SIGNALS + 115)//0x80 ++#define MT_KP_IRQ_ID (GIC_PRIVATE_SIGNALS + 116) ++#define MT_SPM_IRQ_ID (GIC_PRIVATE_SIGNALS + 117) ++#define MT_SPM1_IRQ_ID (GIC_PRIVATE_SIGNALS + 118) ++#define MT_VENC_IRQ_ID (GIC_PRIVATE_SIGNALS + 139) ++#define MT_VDEC_IRQ_ID (GIC_PRIVATE_SIGNALS + 140) ++#define CAMERA_ISP_IRQ0_ID (GIC_PRIVATE_SIGNALS + 143) // cam_irq_b ++#define CAMERA_ISP_IRQ1_ID (GIC_PRIVATE_SIGNALS + 144) // cam_irq1_b ++#define CAMERA_ISP_IRQ2_ID (GIC_PRIVATE_SIGNALS + 145) // cam_irq2_b ++//#define CAMERA_ISP_IRQ3_ID (GIC_PRIVATE_SIGNALS + 144) // cam_irq3_b 6582 take off ++#define MT6582_JPEG_ENC_IRQ_ID (GIC_PRIVATE_SIGNALS + 141) ++//#define MT6582_JPEG_DEC_IRQ_ID (GIC_PRIVATE_SIGNALS + 148) //6582 take off ++/* Not sure and comments for early porting */ ++#define MT_EINT_DIRECT0_IRQ_ID (GIC_PRIVATE_SIGNALS + 121) ++ ++#if 0 ++#define MT_MFG_IRQ_GP_ID (GIC_PRIVATE_SIGNALS + 170) ++#define MT_MFG_IRQ_GPMMU_ID (GIC_PRIVATE_SIGNALS + 171) ++#define MT_MFG_IRQ_PP0_ID (GIC_PRIVATE_SIGNALS + 172) ++#define MT_MFG_IRQ_PPMMU0_ID (GIC_PRIVATE_SIGNALS + 173) ++#define MT_MFG_IRQ_PP1_ID (GIC_PRIVATE_SIGNALS + 174) ++#define MT_MFG_IRQ_PPMMU1_ID (GIC_PRIVATE_SIGNALS + 175) ++#else ++#define MT_MFG_IRQ0_ID (GIC_PRIVATE_SIGNALS + 170) ++#define MT_MFG_IRQ1_ID (GIC_PRIVATE_SIGNALS + 171) ++#define MT_MFG_IRQ2_ID (GIC_PRIVATE_SIGNALS + 172) ++#define MT_MFG_IRQ3_ID (GIC_PRIVATE_SIGNALS + 173) ++#define MT_MFG_IRQ4_ID (GIC_PRIVATE_SIGNALS + 174) ++#define MT_MFG_IRQ5_ID (GIC_PRIVATE_SIGNALS + 175) ++#define MT_MFG_IRQ6_ID (GIC_PRIVATE_SIGNALS + 176) ++#define MT_MFG_IRQ7_ID (GIC_PRIVATE_SIGNALS + 177) ++#define MT_MFG_IRQ8_ID (GIC_PRIVATE_SIGNALS + 178) ++#define MT_MFG_IRQ9_ID (GIC_PRIVATE_SIGNALS + 179) ++#define MT_MFG_IRQ10_ID (GIC_PRIVATE_SIGNALS + 180) ++#endif ++ ++ ++#if 0 ++#define MT6582_DISP_MUTEX_IRQ_ID (GIC_PRIVATE_SIGNALS + 160) ++#define MT6582_DISP_ROT_IRQ_ID (GIC_PRIVATE_SIGNALS + 161) ++#define MT6582_DISP_SCL_IRQ_ID (GIC_PRIVATE_SIGNALS + 162) ++#define MT6582_DISP_OVL_IRQ_ID (GIC_PRIVATE_SIGNALS + 163) ++#define MT6582_DISP_WDMA0_IRQ_ID (GIC_PRIVATE_SIGNALS + 164) ++#define MT6582_DISP_WDMA1_IRQ_ID (GIC_PRIVATE_SIGNALS + 165) ++#define MT6582_DISP_RDMA0_IRQ_ID (GIC_PRIVATE_SIGNALS + 166) ++#define MT6582_DISP_RDMA1_IRQ_ID (GIC_PRIVATE_SIGNALS + 167) ++#define MT6582_DISP_BLS_IRQ_ID (GIC_PRIVATE_SIGNALS + 168) ++#define MT6582_DISP_COLOR_IRQ_ID (GIC_PRIVATE_SIGNALS + 169) ++#define MT6582_DISP_TDSHP_IRQ_ID (GIC_PRIVATE_SIGNALS + 170) ++#define MT6582_DISP_DBI_IRQ_ID (GIC_PRIVATE_SIGNALS + 171) ++#define MT6582_DISP_DSI_IRQ_ID (GIC_PRIVATE_SIGNALS + 172) ++#define MT6582_DISP_DPI0_IRQ_ID (GIC_PRIVATE_SIGNALS + 173) ++#define MT6582_DISP_DPI1_IRQ_ID (GIC_PRIVATE_SIGNALS + 174) ++#define MT6582_DISP_CMDQ_IRQ_ID (GIC_PRIVATE_SIGNALS + 176) ++#else ++#define MT6582_DISP_MDP_RDMA_IRQ_ID (GIC_PRIVATE_SIGNALS+146) ++#define MT6582_DISP_MDP_RSZ0_IRQ_ID (GIC_PRIVATE_SIGNALS+147) ++#define MT6582_DISP_MDP_RSZ1_IRQ_ID (GIC_PRIVATE_SIGNALS+148) ++#define MT6582_DISP_MDP_TDSHP_IRQ_ID (GIC_PRIVATE_SIGNALS+149) ++#define MT6582_DISP_MDP_WDMA_IRQ_ID (GIC_PRIVATE_SIGNALS+150) ++#define MT6582_DISP_MDP_WROT_IRQ_ID (GIC_PRIVATE_SIGNALS+151) ++#define MT6582_DISP_RDMA_IRQ_ID (GIC_PRIVATE_SIGNALS+152) ++#define MT6582_DISP_OVL_IRQ_ID (GIC_PRIVATE_SIGNALS+153) ++#define MT6582_DISP_WDMA_IRQ_ID (GIC_PRIVATE_SIGNALS+154) ++#define MT6582_DISP_BLS_IRQ_ID (GIC_PRIVATE_SIGNALS+155) ++#define MT6582_DISP_COLOR_IRQ_ID (GIC_PRIVATE_SIGNALS+156) ++#define MT6582_DISP_DSI_IRQ_ID (GIC_PRIVATE_SIGNALS+157) ++#define MT6582_DISP_DPI0_IRQ_ID (GIC_PRIVATE_SIGNALS+158) ++#define MT6582_DISP_CMDQ_IRQ_ID (GIC_PRIVATE_SIGNALS+159) ++#define MT6582_DISP_CMDQ_SECURE_IRQ_ID (GIC_PRIVATE_SIGNALS+160) ++#define MT6582_DISP_MUTEX_IRQ_ID (GIC_PRIVATE_SIGNALS+161) ++#define MT6582_DISP_SMI_LARB0_IRQ_ID (GIC_PRIVATE_SIGNALS+162) ++#define MT_CIRQ_IRQ_ID (GIC_PRIVATE_SIGNALS+187) ++#endif ++#define MT6582_APARM_GPTTIMER_IRQ_LINE MT6582_GPT_IRQ_ID ++ ++// MT6582 Wifi AHB Slave HIF ++#define MT6582_AHB_SLAVE_HIF_IRQ_ID (GIC_PRIVATE_SIGNALS + 160) ++#define MT6582_HIF_PDMA_IRQ_ID (GIC_PRIVATE_SIGNALS + 59) ++ ++/* These are defined for solving compile errors only. They are not existing on FPGA */ ++#define TS_IRQ_ID (GIC_PRIVATE_SIGNALS + 163) ++#define CONN_WDT_IRQ_ID (GIC_PRIVATE_SIGNALS + 163) ++#define LOWBATTERY_IRQ_ID (GIC_PRIVATE_SIGNALS + 163) ++#define MD_WDT_IRQ_ID (GIC_PRIVATE_SIGNALS + 163) ++ ++#define WF_HIF_IRQ_ID (GIC_PRIVATE_SIGNALS + 184) ++#define MT_CONN2AP_BTIF_WAKEUP_IRQ_ID (GIC_PRIVATE_SIGNALS + 185) ++#define BT_CVSD_IRQ_ID (GIC_PRIVATE_SIGNALS + 186) ++ ++#define CCIF0_AP_IRQ_ID (GIC_PRIVATE_SIGNALS + 100) ++#endif ++ ++#endif +diff --git a/arch/arm/include/asm/rt2880/mt_irq.h b/arch/arm/include/asm/rt2880/mt_irq.h +new file mode 100644 +index 0000000..ff265e0 +--- /dev/null ++++ b/arch/arm/include/asm/rt2880/mt_irq.h +@@ -0,0 +1,174 @@ ++#ifndef __MT_IRQ_H ++#define __MT_IRQ_H ++ ++#define GIC_PRIVATE_SIGNALS (32) ++#define NR_GIC_SGI (16) ++#define NR_GIC_PPI (16) ++#define GIC_PPI_OFFSET (27) ++#define MT_NR_PPI (5) ++#define MT_NR_SPI (224) ++#define NR_MT_IRQ_LINE (GIC_PPI_OFFSET + MT_NR_PPI + MT_NR_SPI) ++ ++#define MT65xx_EDGE_SENSITIVE 0 ++#define MT65xx_LEVEL_SENSITIVE 1 ++ ++#define MT65xx_POLARITY_LOW 0 ++#define MT65xx_POLARITY_HIGH 1 ++ ++#define GIC_PPI_GLOBAL_TIMER (GIC_PPI_OFFSET + 0) ++#define GIC_PPI_LEGACY_FIQ (GIC_PPI_OFFSET + 1) ++#define GIC_PPI_PRIVATE_TIMER (GIC_PPI_OFFSET + 2) ++#define GIC_PPI_NS_PRIVATE_TIMER (GIC_PPI_OFFSET + 3) ++#define GIC_PPI_LEGACY_IRQ (GIC_PPI_OFFSET + 4) ++ ++#define MT_BTIF_IRQ_ID (GIC_PRIVATE_SIGNALS + 50) ++#define MT_DMA_BTIF_TX_IRQ_ID (GIC_PRIVATE_SIGNALS + 71) ++#define MT_DMA_BTIF_RX_IRQ_ID (GIC_PRIVATE_SIGNALS + 72) ++ ++#if !defined(CONFIG_MT8127_FPGA) ++ ++#if !defined(__ASSEMBLY__) ++#define X_DEFINE_IRQ(__name, __num, __pol, __sens) __name = __num, ++enum ++{ ++#include "x_define_irq.h" ++}; ++#undef X_DEFINE_IRQ ++#define MT6582_AHB_SLAVE_HIF_IRQ_ID WF_HIF_IRQ_ID /* FIXME */ ++ ++#endif ++ ++#else ++ ++#define MT6582_USB0_IRQ_ID (GIC_PRIVATE_SIGNALS + 32) ++#define MT6582_USB1_IRQ_ID (GIC_PRIVATE_SIGNALS + 33) ++#define MT_PTP_THERM_IRQ_ID (GIC_PRIVATE_SIGNALS + 38) ++#define MT_MSDC0_IRQ_ID (GIC_PRIVATE_SIGNALS + 39) ++#define MT_MSDC1_IRQ_ID (GIC_PRIVATE_SIGNALS + 40) ++//#define MT_MSDC2_IRQ_ID (GIC_PRIVATE_SIGNALS + 41) //6582 take off ++//#define MT_MSDC3_IRQ_ID (GIC_PRIVATE_SIGNALS + 42) //6582 take off ++#define MT6582_AP_HIF_IRQ_ID (GIC_PRIVATE_SIGNALS + 43) ++#define MT_I2C0_IRQ_ID (GIC_PRIVATE_SIGNALS + 44) ++#define MT_I2C1_IRQ_ID (GIC_PRIVATE_SIGNALS + 45) ++#define MT_I2C2_IRQ_ID (GIC_PRIVATE_SIGNALS + 46) ++#define MT_UART1_IRQ_ID (GIC_PRIVATE_SIGNALS + 51) ++#define MT_UART2_IRQ_ID (GIC_PRIVATE_SIGNALS + 52) ++#define MT_UART3_IRQ_ID (GIC_PRIVATE_SIGNALS + 53) ++#define MT_UART4_IRQ_ID (GIC_PRIVATE_SIGNALS + 54) ++#define MT_NFIECC_IRQ_ID (GIC_PRIVATE_SIGNALS + 55) ++#define MT_NFI_IRQ_ID (GIC_PRIVATE_SIGNALS + 56) ++#define MT_GDMA1_IRQ_ID (GIC_PRIVATE_SIGNALS + 57) ++#define MT_GDMA2_IRQ_ID (GIC_PRIVATE_SIGNALS + 58) ++#define MT_DMA_UART0_TX_IRQ_ID (GIC_PRIVATE_SIGNALS + 63) ++#define MT_DMA_UART0_RX_IRQ_ID (GIC_PRIVATE_SIGNALS + 64) ++#define MT_DMA_UART1_TX_IRQ_ID (GIC_PRIVATE_SIGNALS + 65) ++#define MT_DMA_UART1_RX_IRQ_ID (GIC_PRIVATE_SIGNALS + 66) ++#define MT_DMA_UART2_TX_IRQ_ID (GIC_PRIVATE_SIGNALS + 67) ++#define MT_DMA_UART2_RX_IRQ_ID (GIC_PRIVATE_SIGNALS + 68) ++#define MT6582_SPI1_IRQ_ID (GIC_PRIVATE_SIGNALS + 78) ++//#define MT_MSDC4_IRQ_ID (GIC_PRIVATE_SIGNALS + 83) //6582 take off ++#define MT_PTP_FSM_IRQ_ID (GIC_PRIVATE_SIGNALS + 85) ++#define MT_WDT_IRQ_ID (GIC_PRIVATE_SIGNALS + 88)//TBD:For build pass ++#define MT_APARM_DOMAIN_IRQ_ID (GIC_PRIVATE_SIGNALS + 94) ++#define MT_APARM_DECERR_IRQ_ID (GIC_PRIVATE_SIGNALS + 95) ++#if 1 //cliff ++#define MT6582_GPT_IRQ_ID (GIC_PRIVATE_SIGNALS + 112)//10.2 update ++#define MT_EINT_IRQ_ID (GIC_PRIVATE_SIGNALS + 113)//10.2 update ++#else ++#define MT6582_GPT_IRQ_ID (GIC_PRIVATE_SIGNALS + 113)//10.2 update ++#define MT_EINT_IRQ_ID (GIC_PRIVATE_SIGNALS + 116)//10.2 update ++#endif ++#define MT6582_PMIC_WRAP_IRQ_ID (GIC_PRIVATE_SIGNALS + 115)//0x80 ++#define MT_KP_IRQ_ID (GIC_PRIVATE_SIGNALS + 116) ++#define MT_SPM_IRQ_ID (GIC_PRIVATE_SIGNALS + 117) ++#define MT_SPM1_IRQ_ID (GIC_PRIVATE_SIGNALS + 118) ++#define MT_VENC_IRQ_ID (GIC_PRIVATE_SIGNALS + 139) ++#define MT_VDEC_IRQ_ID (GIC_PRIVATE_SIGNALS + 140) ++#define CAMERA_ISP_IRQ0_ID (GIC_PRIVATE_SIGNALS + 143) // cam_irq_b ++#define CAMERA_ISP_IRQ1_ID (GIC_PRIVATE_SIGNALS + 144) // cam_irq1_b ++#define CAMERA_ISP_IRQ2_ID (GIC_PRIVATE_SIGNALS + 145) // cam_irq2_b ++//#define CAMERA_ISP_IRQ3_ID (GIC_PRIVATE_SIGNALS + 144) // cam_irq3_b 6582 take off ++#define MT6582_JPEG_ENC_IRQ_ID (GIC_PRIVATE_SIGNALS + 141) ++//#define MT6582_JPEG_DEC_IRQ_ID (GIC_PRIVATE_SIGNALS + 148) //6582 take off ++/* Not sure and comments for early porting */ ++#define MT_EINT_DIRECT0_IRQ_ID (GIC_PRIVATE_SIGNALS + 121) ++ ++#if 0 ++#define MT_MFG_IRQ_GP_ID (GIC_PRIVATE_SIGNALS + 170) ++#define MT_MFG_IRQ_GPMMU_ID (GIC_PRIVATE_SIGNALS + 171) ++#define MT_MFG_IRQ_PP0_ID (GIC_PRIVATE_SIGNALS + 172) ++#define MT_MFG_IRQ_PPMMU0_ID (GIC_PRIVATE_SIGNALS + 173) ++#define MT_MFG_IRQ_PP1_ID (GIC_PRIVATE_SIGNALS + 174) ++#define MT_MFG_IRQ_PPMMU1_ID (GIC_PRIVATE_SIGNALS + 175) ++#else ++#define MT_MFG_IRQ0_ID (GIC_PRIVATE_SIGNALS + 170) ++#define MT_MFG_IRQ1_ID (GIC_PRIVATE_SIGNALS + 171) ++#define MT_MFG_IRQ2_ID (GIC_PRIVATE_SIGNALS + 172) ++#define MT_MFG_IRQ3_ID (GIC_PRIVATE_SIGNALS + 173) ++#define MT_MFG_IRQ4_ID (GIC_PRIVATE_SIGNALS + 174) ++#define MT_MFG_IRQ5_ID (GIC_PRIVATE_SIGNALS + 175) ++#define MT_MFG_IRQ6_ID (GIC_PRIVATE_SIGNALS + 176) ++#define MT_MFG_IRQ7_ID (GIC_PRIVATE_SIGNALS + 177) ++#define MT_MFG_IRQ8_ID (GIC_PRIVATE_SIGNALS + 178) ++#define MT_MFG_IRQ9_ID (GIC_PRIVATE_SIGNALS + 179) ++#define MT_MFG_IRQ10_ID (GIC_PRIVATE_SIGNALS + 180) ++#endif ++ ++ ++#if 0 ++#define MT6582_DISP_MUTEX_IRQ_ID (GIC_PRIVATE_SIGNALS + 160) ++#define MT6582_DISP_ROT_IRQ_ID (GIC_PRIVATE_SIGNALS + 161) ++#define MT6582_DISP_SCL_IRQ_ID (GIC_PRIVATE_SIGNALS + 162) ++#define MT6582_DISP_OVL_IRQ_ID (GIC_PRIVATE_SIGNALS + 163) ++#define MT6582_DISP_WDMA0_IRQ_ID (GIC_PRIVATE_SIGNALS + 164) ++#define MT6582_DISP_WDMA1_IRQ_ID (GIC_PRIVATE_SIGNALS + 165) ++#define MT6582_DISP_RDMA0_IRQ_ID (GIC_PRIVATE_SIGNALS + 166) ++#define MT6582_DISP_RDMA1_IRQ_ID (GIC_PRIVATE_SIGNALS + 167) ++#define MT6582_DISP_BLS_IRQ_ID (GIC_PRIVATE_SIGNALS + 168) ++#define MT6582_DISP_COLOR_IRQ_ID (GIC_PRIVATE_SIGNALS + 169) ++#define MT6582_DISP_TDSHP_IRQ_ID (GIC_PRIVATE_SIGNALS + 170) ++#define MT6582_DISP_DBI_IRQ_ID (GIC_PRIVATE_SIGNALS + 171) ++#define MT6582_DISP_DSI_IRQ_ID (GIC_PRIVATE_SIGNALS + 172) ++#define MT6582_DISP_DPI0_IRQ_ID (GIC_PRIVATE_SIGNALS + 173) ++#define MT6582_DISP_DPI1_IRQ_ID (GIC_PRIVATE_SIGNALS + 174) ++#define MT6582_DISP_CMDQ_IRQ_ID (GIC_PRIVATE_SIGNALS + 176) ++#else ++#define MT6582_DISP_MDP_RDMA_IRQ_ID (GIC_PRIVATE_SIGNALS+146) ++#define MT6582_DISP_MDP_RSZ0_IRQ_ID (GIC_PRIVATE_SIGNALS+147) ++#define MT6582_DISP_MDP_RSZ1_IRQ_ID (GIC_PRIVATE_SIGNALS+148) ++#define MT6582_DISP_MDP_TDSHP_IRQ_ID (GIC_PRIVATE_SIGNALS+149) ++#define MT6582_DISP_MDP_WDMA_IRQ_ID (GIC_PRIVATE_SIGNALS+150) ++#define MT6582_DISP_MDP_WROT_IRQ_ID (GIC_PRIVATE_SIGNALS+151) ++#define MT6582_DISP_RDMA_IRQ_ID (GIC_PRIVATE_SIGNALS+152) ++#define MT6582_DISP_OVL_IRQ_ID (GIC_PRIVATE_SIGNALS+153) ++#define MT6582_DISP_WDMA_IRQ_ID (GIC_PRIVATE_SIGNALS+154) ++#define MT6582_DISP_BLS_IRQ_ID (GIC_PRIVATE_SIGNALS+155) ++#define MT6582_DISP_COLOR_IRQ_ID (GIC_PRIVATE_SIGNALS+156) ++#define MT6582_DISP_DSI_IRQ_ID (GIC_PRIVATE_SIGNALS+157) ++#define MT6582_DISP_DPI0_IRQ_ID (GIC_PRIVATE_SIGNALS+158) ++#define MT6582_DISP_CMDQ_IRQ_ID (GIC_PRIVATE_SIGNALS+159) ++#define MT6582_DISP_CMDQ_SECURE_IRQ_ID (GIC_PRIVATE_SIGNALS+160) ++#define MT6582_DISP_MUTEX_IRQ_ID (GIC_PRIVATE_SIGNALS+161) ++#define MT6582_DISP_SMI_LARB0_IRQ_ID (GIC_PRIVATE_SIGNALS+162) ++#define MT_CIRQ_IRQ_ID (GIC_PRIVATE_SIGNALS+187) ++#endif ++#define MT6582_APARM_GPTTIMER_IRQ_LINE MT6582_GPT_IRQ_ID ++ ++// MT6582 Wifi AHB Slave HIF ++#define MT6582_AHB_SLAVE_HIF_IRQ_ID (GIC_PRIVATE_SIGNALS + 160) ++#define MT6582_HIF_PDMA_IRQ_ID (GIC_PRIVATE_SIGNALS + 59) ++ ++/* These are defined for solving compile errors only. They are not existing on FPGA */ ++#define TS_IRQ_ID (GIC_PRIVATE_SIGNALS + 163) ++#define CONN_WDT_IRQ_ID (GIC_PRIVATE_SIGNALS + 163) ++#define LOWBATTERY_IRQ_ID (GIC_PRIVATE_SIGNALS + 163) ++#define MD_WDT_IRQ_ID (GIC_PRIVATE_SIGNALS + 163) ++ ++#define WF_HIF_IRQ_ID (GIC_PRIVATE_SIGNALS + 184) ++#define MT_CONN2AP_BTIF_WAKEUP_IRQ_ID (GIC_PRIVATE_SIGNALS + 185) ++#define BT_CVSD_IRQ_ID (GIC_PRIVATE_SIGNALS + 186) ++ ++#define CCIF0_AP_IRQ_ID (GIC_PRIVATE_SIGNALS + 100) ++#endif ++ ++#endif +diff --git a/arch/arm/include/asm/rt2880/rt_mmap.h b/arch/arm/include/asm/rt2880/rt_mmap.h +new file mode 100644 +index 0000000..e86b3bb +--- /dev/null ++++ b/arch/arm/include/asm/rt2880/rt_mmap.h +@@ -0,0 +1,58 @@ ++#define HIFSYS_BASE 0xFA000000 //for PCIe/USB ++#define ETHDMASYS_BASE 0xFB000000 //for I2S/PCM/GDMA/HSDMA/FE/GMAC ++ ++#define HIFSYS_PCI_BASE 0xFA140000 ++#define HIFSYS_USB_HOST_BASE 0xFA1C0000 ++#define HIFSYS_USB_HOST2_BASE 0xFA240000 ++ ++#define ETHDMASYS_SYSCTL_BASE 0xFB000000 ++#define ETHDMASYS_RBUS_MATRIXCTL_BASE 0xFB000400 ++#define ETHDMASYS_I2S_BASE 0xFB000A00 ++#define ETHDMASYS_PCM_BASE 0xFB002000 ++#define ETHDMASYS_GDMA_BASE 0xFB002800 ++#define ETHDMASYS_HS_DMA_BASE 0xFB007000 ++#define ETHDMASYS_FRAME_ENGINE_BASE 0xFB100000 ++#define ETHDMASYS_PPE_BASE 0xFB100C00 ++#define ETHDMASYS_ETH_SW_BASE 0xFB110000 ++#define ETHDMASYS_CRYPTO_ENGINE_BASE 0xFB240000 ++ ++//for backward-compatible ++#define RALINK_FRAME_ENGINE_BASE ETHDMASYS_FRAME_ENGINE_BASE ++#define RALINK_PPE_BASE ETHDMASYS_PPE_BASE ++#define RALINK_SYSCTL_BASE ETHDMASYS_SYSCTL_BASE ++#define RALINK_ETH_SW_BASE ETHDMASYS_ETH_SW_BASE ++#define RALINK_GDMA_BASE ETHDMASYS_GDMA_BASE ++#define RALINK_HS_DMA_BASE ETHDMASYS_HS_DMA_BASE ++#define RALINK_11N_MAC_BASE 0 //unused for rt_rdm usage ++ ++//Reset Control Register ++#define RSTCTL_SYS_RST (1<<0) ++#define RSTCTL_MCM_RST (1<<2) ++#define RSTCTL_HSDMA_RST (1<<5) ++#define RSTCTL_FE_RST (1<<6) ++#define RSTCTL_SPDIF_RST (1<<7) ++#define RSTCTL_TIMER_RST (1<<8) ++#define RSTCTL_CIRQ_RST (1<<9) ++#define RSTCTL_MC_RST (1<<10) ++#define RSTCTL_PCM_RST (1<<11) ++#define RSTCTL_GPIO_RST (1<<13) ++#define RSTCTL_GDMA_RST (1<<14) ++#define RSTCTL_NAND_RST (1<<15) ++#define RSTCTL_I2C_RST (1<<16) ++#define RSTCTL_I2S_RST (1<<17) ++#define RSTCTL_SPI_RST (1<<18) ++#define RSTCTL_UART0_RST (1<<19) ++#define RSTCTL_UART1_RST (1<<20) ++#define RSTCTL_UART2_RST (1<<21) ++#define RSTCTL_UPHY_RST (1<<22) ++#define RSTCTL_ETH_RST (1<<23) ++#define RSTCTL_PCIE0_RST (1<<24) ++#define RSTCTL_PCIE1_RST (1<<25) ++#define RSTCTL_PCIE2_RST (1<<26) ++#define RSTCTL_AUX_STCK_RST (1<<28) ++#define RSTCTL_CRYPT_RST (1<<29) ++#define RSTCTL_SDXC_RST (1<<30) ++#define RSTCTL_PWM_RST (1<<31) ++ ++//for backward-compatible ++#define RALINK_FE_RST RSTCTL_FE_RST +diff --git a/arch/arm/include/asm/rt2880/surfboardint.h b/arch/arm/include/asm/rt2880/surfboardint.h +new file mode 100644 +index 0000000..4581598 +--- /dev/null ++++ b/arch/arm/include/asm/rt2880/surfboardint.h +@@ -0,0 +1,42 @@ ++#include "mt_irq.h" ++ ++//#define SURFBOARDINT_SYSCTL 0 /* SYSCTL */ ++#define SURFBOARDINT_FE MT_FE_ORIG_IRQ_ID /* FE */ ++#define SURFBOARDINT_PCM MT_PCM_IRQ_ID /* PCM */ ++//#define SURFBOARDINT_GPIO 6 /* GPIO */ ++#define SURFBOARDINT_HSGDMA MT_HSDMA_IRQ_ID /* HSGDMA */ ++#define SURFBOARDINT_DMA MT_GDMA_IRQ_ID /* DMA */ ++//#define SURFBOARDINT_PC 9 /* Performance counter */ ++#define SURFBOARDINT_I2S MT_I2S_IRQ_ID /* I2S */ ++//#define SURFBOARDINT_SPI 11 /* SPI */ ++//#define SURFBOARDINT_AES 13 /* AES */ ++//#define SURFBOARDINT_AESENGINE 13 /* AES Engine */ ++#define SURFBOARDINT_CRYPTO MT_CRYPTO_IRQ_ID /* CryptoEngine */ ++//#define SURFBOARDINT_SDXC 14 /* SDXC */ ++//#define SURFBOARDINT_ESW 17 /* ESW */ ++#define SURFBOARDINT_USB0 MT_SSUSB_XHCI0_IRQ_ID /* USB0 */ ++#define SURFBOARDINT_USB1 MT_SSUSB_XHCI1_IRQ_ID /* USB1 */ ++//#define SURFBOARDINT_UART_LITE1 20 /* UART Lite */ ++//#define SURFBOARDINT_UART_LITE2 21 /* UART Lite */ ++//#define SURFBOARDINT_UART_LITE3 22 /* UART Lite */ ++//#define SURFBOARDINT_UART1 SURFBOARDINT_UART_LITE1 ++//#define SURFBOARDINT_UART SURFBOARDINT_UART_LITE2 ++//#define SURFBOARDINT_WDG 23 /* WDG timer */ ++//#define SURFBOARDINT_TIMER0 24 /* Timer0 */ ++//#define SURFBOARDINT_TIMER1 25 /* Timer1 */ ++//#define SURFBOARDINT_ILL_ACC 35 /* illegal access */ ++#define RALINK_INT_PCIE0 MT_PCIE0_IRQ_ID /* PCIE0 */ ++#define RALINK_INT_PCIE1 MT_PCIE1_IRQ_ID /* PCIE1 */ ++#define RALINK_INT_PCIE2 MT_PCIE2_IRQ_ID /* PCIE2 */ ++ ++// Wait for RD to define IRQ source ++ ++//#define RALINK_INT_xxx MT_CRYPTO_RING0_IRQ_ID /* */ ++//#define RALINK_INT_xxx MT_CRYPTO_RING1_IRQ_ID /* */ ++//#define RALINK_INT_xxx MT_CRYPTO_RING2_IRQ_ID /* */ ++//#define RALINK_INT_xxx MT_FE_PDMA_IRQ_ID /* */ ++//#define RALINK_INT_xxx MT_FE_QDMA_IRQ_ID /* */ ++//#define RALINK_INT_xxx MT_PCIE_LINK_DOWN_RST_IRQ_ID /* */ ++ ++ ++ +diff --git a/arch/arm/include/asm/rt2880/x_define_irq.h b/arch/arm/include/asm/rt2880/x_define_irq.h +new file mode 100644 +index 0000000..4b2e669 +--- /dev/null ++++ b/arch/arm/include/asm/rt2880/x_define_irq.h +@@ -0,0 +1,160 @@ ++/* ++ * This file is generated automatically according to the design of silicon. ++ * Don't modify it directly. ++ */ ++ ++X_DEFINE_IRQ(MT6582_USB0_IRQ_ID , 64, L,LEVEL) ++X_DEFINE_IRQ(MT6582_USB1_IRQ_ID , 65, L,LEVEL) ++X_DEFINE_IRQ(TS_IRQ_ID , 66, L,EDGE) ++X_DEFINE_IRQ(TS_BATCH_IRQ_ID , 67, L,EDGE) ++X_DEFINE_IRQ(LOWBATTERY_IRQ_ID , 68, L,EDGE) ++X_DEFINE_IRQ(PWM_IRQ_ID , 69, L,LEVEL) ++X_DEFINE_IRQ(THERM_CTRL_IRQ_ID , 70, L,LEVEL) ++X_DEFINE_IRQ(MT_MSDC0_IRQ_ID , 71, L,LEVEL) ++X_DEFINE_IRQ(MT_MSDC1_IRQ_ID , 72, L,LEVEL) ++X_DEFINE_IRQ(MT_MSDC2_IRQ_ID , 73, L,LEVEL) ++X_DEFINE_IRQ(MT_MSDC3_IRQ_ID , 74, L,LEVEL) ++X_DEFINE_IRQ(MT_I2C0_IRQ_ID , 76, L,LEVEL) ++X_DEFINE_IRQ(MT_I2C1_IRQ_ID , 77, L,LEVEL) ++X_DEFINE_IRQ(MT_I2C2_IRQ_ID , 78, L,LEVEL) ++X_DEFINE_IRQ(BITF_IRQ_ID , 82, L,LEVEL) ++X_DEFINE_IRQ(MT_UART1_IRQ_ID , 83, L,LEVEL) ++X_DEFINE_IRQ(MT_UART2_IRQ_ID , 84, L,LEVEL) ++X_DEFINE_IRQ(MT_UART3_IRQ_ID , 85, L,LEVEL) ++X_DEFINE_IRQ(MT_UART4_IRQ_ID , 86, L,LEVEL) ++X_DEFINE_IRQ(MT_NFIECC_IRQ_ID , 87, L,LEVEL) ++X_DEFINE_IRQ(MT_NFI_IRQ_ID , 88, L,LEVEL) ++X_DEFINE_IRQ(MT_GDMA1_IRQ_ID , 89, L,LEVEL) ++X_DEFINE_IRQ(MT_GDMA2_IRQ_ID , 90, L,LEVEL) ++X_DEFINE_IRQ(MT6582_HIF_PDMA_IRQ_ID , 91, L,LEVEL) ++X_DEFINE_IRQ(AP_DMA_I2C0_IRQ_ID , 92, L,LEVEL) ++X_DEFINE_IRQ(AP_DMA_I2C1_IRQ_ID , 93, L,LEVEL) ++X_DEFINE_IRQ(AP_DMA_I2C2_IRQ_ID , 94, L,LEVEL) ++X_DEFINE_IRQ(MT_DMA_UART0_TX_IRQ_ID , 95, L,LEVEL) ++X_DEFINE_IRQ(MT_DMA_UART0_RX_IRQ_ID , 96, L,LEVEL) ++X_DEFINE_IRQ(MT_DMA_UART1_TX_IRQ_ID , 97, L,LEVEL) ++X_DEFINE_IRQ(MT_DMA_UART1_RX_IRQ_ID , 98, L,LEVEL) ++X_DEFINE_IRQ(MT_DMA_UART2_TX_IRQ_ID , 99, L,LEVEL) ++X_DEFINE_IRQ(MT_DMA_UART2_RX_IRQ_ID , 100, L,LEVEL) ++X_DEFINE_IRQ(MT_DMA_UART3_TX_IRQ_ID , 101, L,LEVEL) ++X_DEFINE_IRQ(MT_DMA_UART3_RX_IRQ_ID , 102, L,LEVEL) ++X_DEFINE_IRQ(AP_DMA_BTIF_TX_IRQ_ID , 103, L,LEVEL) ++X_DEFINE_IRQ(AP_DMA_BTIF_RX_IRQ_ID , 104, L,LEVEL) ++X_DEFINE_IRQ(MT_GCPU_IRQ_ID , 105, L,LEVEL) ++X_DEFINE_IRQ(MT_GCPU_DMX_IRQ_ID , 106, L,LEVEL) ++X_DEFINE_IRQ(MT_GCPU_MMU_IRQ_ID , 107, L,LEVEL) ++X_DEFINE_IRQ(MT_GCPU_MMU_SEC_IRQ_ID , 108, L,LEVEL) ++X_DEFINE_IRQ(MT_ETHER_NIC_WRAP_IRQ_ID , 109, L,LEVEL) ++X_DEFINE_IRQ(MT6582_SPI1_IRQ_ID , 110, L,LEVEL) ++X_DEFINE_IRQ(MSDC0_WAKEUP_PS_IRQ_ID , 111, H,EDGE) ++X_DEFINE_IRQ(MSDC1_WAKEUP_PS_IRQ_ID , 112, H,EDGE) ++X_DEFINE_IRQ(MSDC2_WAKEUP_PS_IRQ_ID , 113, H,EDGE) ++X_DEFINE_IRQ(MT_CRYPTO_RING0_IRQ_ID , 114, H,LEVEL) ++X_DEFINE_IRQ(MT_CRYPTO_RING1_IRQ_ID , 115, H,LEVEL) ++X_DEFINE_IRQ(MT_CRYPTO_RING2_IRQ_ID , 116, H,LEVEL) ++X_DEFINE_IRQ(MT_PTP_FSM_IRQ_ID , 117, L,LEVEL) ++X_DEFINE_IRQ(BTIF_WAKEUP_IRQ_ID , 118, L,LEVEL) ++X_DEFINE_IRQ(MT_IRRX_IRQ_ID , 119, L,LEVEL) ++X_DEFINE_IRQ(MT_WDT_IRQ_ID , 120, L,EDGE) ++X_DEFINE_IRQ(MT_CRYPTO_RING3_IRQ_ID , 123, H,LEVEL) ++X_DEFINE_IRQ(DCC_APARM_IRQ_ID , 124, L,LEVEL) ++X_DEFINE_IRQ(APARM_CTI_IRQ_ID , 125, L,LEVEL) ++X_DEFINE_IRQ(MT_APARM_DOMAIN_IRQ_ID , 126, L,LEVEL) ++X_DEFINE_IRQ(MT_APARM_DECERR_IRQ_ID , 127, L,LEVEL) ++X_DEFINE_IRQ(DOMAIN_ABORT_IRQ_ID0 , 128, L,LEVEL) ++X_DEFINE_IRQ(MT_CRYPTO_IRQ_ID , 129, H,LEVEL) ++X_DEFINE_IRQ(MT_HSDMA_IRQ_ID , 130, H,LEVEL) ++X_DEFINE_IRQ(MT_GDMA_IRQ_ID , 131, H,LEVEL) ++X_DEFINE_IRQ(CCIF0_AP_IRQ_ID , 132, L,LEVEL) ++X_DEFINE_IRQ(MT_I2S_IRQ_ID , 134, H,LEVEL) ++X_DEFINE_IRQ(MT_PCM_IRQ_ID , 135, H,LEVEL) ++X_DEFINE_IRQ(AFE_MCU_IRQ_ID , 136, L,LEVEL) ++X_DEFINE_IRQ(M4U1_IRQ_ID , 138, L,LEVEL) ++X_DEFINE_IRQ(M4UL2_IRQ_ID , 139, L,LEVEL) ++X_DEFINE_IRQ(M4UL2_SEC_IRQ_ID , 140, L,LEVEL) ++X_DEFINE_IRQ(REFRESH_RATE_IRQ_ID , 141, L,EDGE) ++X_DEFINE_IRQ(MT6582_APARM_GPTTIMER_IRQ_LINE, 144, L,LEVEL) ++X_DEFINE_IRQ(MT_EINT_IRQ_ID , 145, H,LEVEL) ++X_DEFINE_IRQ(EINT_EVENT_IRQ_ID , 146, L,LEVEL) ++X_DEFINE_IRQ(MT6582_PMIC_WRAP_IRQ_ID , 147, H,LEVEL) ++X_DEFINE_IRQ(MT_KP_IRQ_ID , 148, L,EDGE) ++X_DEFINE_IRQ(MT_SPM_IRQ_ID , 149, L,LEVEL) ++X_DEFINE_IRQ(MT_SPM1_IRQ_ID , 150, L,LEVEL) ++X_DEFINE_IRQ(MT_SPM2_IRQ_ID , 151, L,LEVEL) ++X_DEFINE_IRQ(MT_SPM3_IRQ_ID , 152, L,LEVEL) ++X_DEFINE_IRQ(MT_EINT_DIRECT0_IRQ_ID , 153, H,LEVEL) ++X_DEFINE_IRQ(MT_EINT_DIRECT1_IRQ_ID , 154, H,LEVEL) ++X_DEFINE_IRQ(MT_EINT_DIRECT2_IRQ_ID , 155, H,LEVEL) ++X_DEFINE_IRQ(MT_EINT_DIRECT3_IRQ_ID , 156, H,LEVEL) ++X_DEFINE_IRQ(MT_EINT_DIRECT4_IRQ_ID , 157, H,LEVEL) ++X_DEFINE_IRQ(MT_EINT_DIRECT5_IRQ_ID , 158, H,LEVEL) ++X_DEFINE_IRQ(MT_EINT_DIRECT6_IRQ_ID , 159, H,LEVEL) ++X_DEFINE_IRQ(MT_EINT_DIRECT7_IRQ_ID , 160, H,LEVEL) ++X_DEFINE_IRQ(MT_EINT_DIRECT8_IRQ_ID , 161, H,LEVEL) ++X_DEFINE_IRQ(MT_EINT_DIRECT9_IRQ_ID , 162, H,LEVEL) ++X_DEFINE_IRQ(MT_EINT_DIRECT10_IRQ_ID , 163, H,LEVEL) ++X_DEFINE_IRQ(MT_EINT_DIRECT11_IRQ_ID , 164, H,LEVEL) ++X_DEFINE_IRQ(MT_EINT_DIRECT12_IRQ_ID , 165, H,LEVEL) ++X_DEFINE_IRQ(MT_EINT_DIRECT13_IRQ_ID , 166, H,LEVEL) ++X_DEFINE_IRQ(MT_EINT_DIRECT14_IRQ_ID , 167, H,LEVEL) ++X_DEFINE_IRQ(SMI_LARB0_IRQ_ID , 168, L,LEVEL) ++X_DEFINE_IRQ(SMI_LARB1_IRQ_ID , 169, L,LEVEL) ++X_DEFINE_IRQ(SMI_LARB2_IRQ_ID , 170, L,LEVEL) ++X_DEFINE_IRQ(MT_VDEC_IRQ_ID , 171, L,LEVEL) ++X_DEFINE_IRQ(MT_VENC_IRQ_ID , 172, L,LEVEL) ++X_DEFINE_IRQ(MT6582_JPEG_ENC_IRQ_ID , 173, L,LEVEL) ++X_DEFINE_IRQ(SENINF_IRQ_ID , 174, L,LEVEL) ++X_DEFINE_IRQ(CAMERA_ISP_IRQ0_ID , 175, L,LEVEL) ++X_DEFINE_IRQ(CAMERA_ISP_IRQ1_ID , 176, L,LEVEL) ++X_DEFINE_IRQ(CAMERA_ISP_IRQ2_ID , 177, L,LEVEL) ++X_DEFINE_IRQ(MT6582_DISP_MDP_RDMA_IRQ_ID , 178, L,LEVEL) ++X_DEFINE_IRQ(MT6582_DISP_MDP_RSZ0_IRQ_ID , 179, L,LEVEL) ++X_DEFINE_IRQ(MT6582_DISP_MDP_RSZ1_IRQ_ID , 180, L,LEVEL) ++X_DEFINE_IRQ(MT6582_DISP_MDP_TDSHP_IRQ_ID , 181, L,LEVEL) ++X_DEFINE_IRQ(MT6582_DISP_MDP_WDMA_IRQ_ID , 182, L,LEVEL) ++X_DEFINE_IRQ(MT6582_DISP_MDP_WROT_IRQ_ID , 183, L,LEVEL) ++X_DEFINE_IRQ(MT6582_DISP_RDMA_IRQ_ID , 184, L,LEVEL) ++X_DEFINE_IRQ(MT6582_DISP_OVL_IRQ_ID , 185, L,LEVEL) ++X_DEFINE_IRQ(MT6582_DISP_WDMA_IRQ_ID , 186, L,LEVEL) ++X_DEFINE_IRQ(MT6582_DISP_BLS_IRQ_ID , 187, L,LEVEL) ++X_DEFINE_IRQ(MT6582_DISP_COLOR_IRQ_ID , 188, L,LEVEL) ++X_DEFINE_IRQ(MT6582_DISP_DSI_IRQ_ID , 189, L,LEVEL) ++X_DEFINE_IRQ(MT6582_DISP_DPI0_IRQ_ID , 190, L,LEVEL) ++X_DEFINE_IRQ(MT6582_DISP_CMDQ_IRQ_ID , 191, L,LEVEL) ++X_DEFINE_IRQ(MT6582_DISP_CMDQ_SECURE_IRQ_ID, 192, L,LEVEL) ++X_DEFINE_IRQ(MT6582_DISP_MUTEX_IRQ_ID , 193, L,LEVEL) ++X_DEFINE_IRQ(MM_DUMMY0_IRQ_ID , 194, L,LEVEL) ++X_DEFINE_IRQ(MM_DUMMY1_IRQ_ID , 195, L,LEVEL) ++X_DEFINE_IRQ(MT6582_DISP_RDMA1_IRQ_ID , 196, L,LEVEL) ++X_DEFINE_IRQ(MM_DUMMY3_IRQ_ID , 197, L,LEVEL) ++X_DEFINE_IRQ(MM_DUMMY4_IRQ_ID , 198, L,LEVEL) ++X_DEFINE_IRQ(MM_DUMMY5_IRQ_ID , 199, L,LEVEL) ++X_DEFINE_IRQ(MM_DUMMY6_IRQ_ID , 200, L,LEVEL) ++X_DEFINE_IRQ(MM_DUMMY7_IRQ_ID , 201, L,LEVEL) ++X_DEFINE_IRQ(MT_MFG_IRQ0_ID , 202, L,LEVEL) ++X_DEFINE_IRQ(MT_MFG_IRQ1_ID , 203, L,LEVEL) ++X_DEFINE_IRQ(MT_MFG_IRQ2_ID , 204, L,LEVEL) ++X_DEFINE_IRQ(MT_MFG_IRQ3_ID , 205, L,LEVEL) ++X_DEFINE_IRQ(MT_MFG_IRQ4_ID , 206, L,LEVEL) ++X_DEFINE_IRQ(MT_MFG_IRQ5_ID , 207, L,LEVEL) ++X_DEFINE_IRQ(MT_MFG_IRQ6_ID , 208, L,LEVEL) ++X_DEFINE_IRQ(MT_MFG_IRQ7_ID , 209, L,LEVEL) ++X_DEFINE_IRQ(MT_MFG_IRQ8_ID , 210, L,LEVEL) ++X_DEFINE_IRQ(MT_MFG_IRQ9_ID , 211, L,LEVEL) ++X_DEFINE_IRQ(MT_MFG_IRQ10_ID , 212, L,LEVEL) ++X_DEFINE_IRQ(MT_APXGPT_SECURE_IRQ_ID , 213, L,LEVEL) ++X_DEFINE_IRQ(MT_CEC_IRQ_ID , 214, L,LEVEL) ++X_DEFINE_IRQ(CONN_WDT_IRQ_ID , 215, L,EDGE) ++X_DEFINE_IRQ(WF_HIF_IRQ_ID , 216, L,LEVEL) ++X_DEFINE_IRQ(MT_CONN2AP_BTIF_WAKEUP_IRQ_ID , 217, L,LEVEL) ++X_DEFINE_IRQ(BT_CVSD_IRQ_ID , 218, L,LEVEL) ++X_DEFINE_IRQ(MT_CIRQ_IRQ_ID , 219, L,LEVEL) ++X_DEFINE_IRQ(MT_PCIE_LINK_DOWN_RST_IRQ_ID , 224, H,EDGE) ++X_DEFINE_IRQ(MT_PCIE0_IRQ_ID , 225, H,LEVEL) ++X_DEFINE_IRQ(MT_PCIE1_IRQ_ID , 226, H,LEVEL) ++X_DEFINE_IRQ(MT_PCIE2_IRQ_ID , 227, H,LEVEL) ++X_DEFINE_IRQ(MT_SSUSB_XHCI0_IRQ_ID , 228, H,LEVEL) ++X_DEFINE_IRQ(MT_SSUSB_XHCI1_IRQ_ID , 229, H,LEVEL) ++X_DEFINE_IRQ(MT_FE_PDMA_IRQ_ID , 230, H,LEVEL) ++X_DEFINE_IRQ(MT_FE_QDMA_IRQ_ID , 231, H,LEVEL) ++X_DEFINE_IRQ(MT_FE_ORIG_IRQ_ID , 232, H,LEVEL) +diff --git a/arch/arm/mach-mediatek/mediatek.c b/arch/arm/mach-mediatek/mediatek.c +index ab8cf21..c0e373b 100644 +--- a/arch/arm/mach-mediatek/mediatek.c ++++ b/arch/arm/mach-mediatek/mediatek.c +@@ -19,6 +19,186 @@ + #include <linux/of.h> + #include <linux/clk-provider.h> + #include <linux/clocksource.h> ++#include <asm/mach/map.h> ++#include "rt_mmap.h" ++#include "mt_reg_base.h" ++ ++#define IO_VIRT_TO_PHYS(v) (0x10000000 | ((v) & 0x0fffffff)) ++ ++static struct map_desc mt_io_desc[] __initdata = ++{ ++#if !defined(CONFIG_MT8127_FPGA) ++ { ++ .virtual = INFRA_BASE, ++ .pfn = __phys_to_pfn(IO_VIRT_TO_PHYS(INFRA_BASE)), ++ .length = (SZ_1M - SZ_4K), ++ .type = MT_DEVICE ++ }, ++ /* Skip the mapping of 0xF0130000~0xF013FFFF to protect access from APMCU */ ++ { ++ .virtual = (DEBUGTOP_BASE - SZ_4K), ++ .pfn = __phys_to_pfn(IO_VIRT_TO_PHYS((DEBUGTOP_BASE - SZ_4K))), ++ .length = (0x30000 + SZ_4K), ++ .type = MT_DEVICE ++ }, ++ { ++ .virtual = (DEBUGTOP_BASE + 0x40000), ++ .pfn = __phys_to_pfn(IO_VIRT_TO_PHYS(DEBUGTOP_BASE + 0x40000)), ++ .length = 0xC0000, ++ .type = MT_DEVICE ++ }, ++ { ++ .virtual = MCUSYS_CFGREG_BASE, ++ .pfn = __phys_to_pfn(IO_VIRT_TO_PHYS(MCUSYS_CFGREG_BASE)), ++ .length = SZ_2M, ++ .type = MT_DEVICE ++ }, ++ /* //// */ ++ { ++ .virtual = AP_DMA_BASE, ++ .pfn = __phys_to_pfn(IO_VIRT_TO_PHYS(AP_DMA_BASE)), ++ .length = SZ_2M + SZ_1M, ++ .type = MT_DEVICE ++ }, ++ { ++ /* virtual 0xF2000000, physical 0x00200000 */ ++ .virtual = SYSRAM_BASE, ++ .pfn = __phys_to_pfn(0x00200000), ++ .length = SZ_128K, ++ .type = MT_DEVICE ++ }, ++ { ++ .virtual = G3D_CONFIG_BASE, ++ .pfn = __phys_to_pfn(IO_VIRT_TO_PHYS(G3D_CONFIG_BASE)), ++ .length = SZ_128K, ++ .type = MT_DEVICE ++ }, ++ { ++ .virtual = DISPSYS_BASE, ++ .pfn = __phys_to_pfn(IO_VIRT_TO_PHYS(DISPSYS_BASE)), ++ .length = SZ_16M, ++ .type = MT_DEVICE ++ }, ++ { ++ .virtual = IMGSYS_CONFG_BASE, ++ .pfn = __phys_to_pfn(IO_VIRT_TO_PHYS(IMGSYS_CONFG_BASE)), ++ .length = SZ_16M, ++ .type = MT_DEVICE ++ }, ++ { ++ .virtual = VDEC_GCON_BASE, ++ .pfn = __phys_to_pfn(IO_VIRT_TO_PHYS(VDEC_GCON_BASE)), ++ .length = SZ_16M, ++ .type = MT_DEVICE ++ }, ++ { ++ /* virtual 0xF7000000, physical 0x08000000 */ ++ .virtual = DEVINFO_BASE, ++ .pfn = __phys_to_pfn(0x08000000), ++ .length = SZ_64K, ++ .type = MT_DEVICE ++ }, ++ { ++ .virtual = CONN_BTSYS_PKV_BASE, ++ .pfn = __phys_to_pfn(IO_VIRT_TO_PHYS(CONN_BTSYS_PKV_BASE)), ++ .length = SZ_1M, ++ .type = MT_DEVICE ++ }, ++ { ++ /* virtual 0xF9000000, physical 0x00100000 */ ++ .virtual = INTER_SRAM, ++ .pfn = __phys_to_pfn(0x00100000), ++ .length = SZ_64K, ++ .type = MT_DEVICE ++ }, ++ { ++ .virtual = HIFSYS_BASE, ++ .pfn = __phys_to_pfn(IO_VIRT_TO_PHYS(HIFSYS_BASE)), ++ .length = SZ_16M, ++ .type = MT_DEVICE ++ }, ++ { ++ .virtual = ETHDMASYS_BASE, ++ .pfn = __phys_to_pfn(IO_VIRT_TO_PHYS(ETHDMASYS_BASE)), ++ .length = SZ_16M, ++ .type = MT_DEVICE ++ }, ++#if 0 ++ { ++ .virtual = BDP_DISPSYS_BASE, ++ .pfn = __phys_to_pfn(IO_VIRT_TO_PHYS(BDP_DISPSYS_BASE)), ++ .length = SZ_32K + SZ_16K, ++ .type = MT_DEVICE ++ }, ++#endif ++#else ++ { ++ .virtual = INFRA_BASE, ++ .pfn = __phys_to_pfn(IO_VIRT_TO_PHYS(INFRA_BASE)), ++ .length = SZ_4M, ++ .type = MT_DEVICE ++ }, ++ { ++ .virtual = AP_DMA_BASE, ++ .pfn = __phys_to_pfn(IO_VIRT_TO_PHYS(AP_DMA_BASE)), ++ .length = SZ_2M + SZ_1M, ++ .type = MT_DEVICE ++ }, ++ #if 0 ++ { ++ .virtual = MMSYS1_CONFIG_BASE, ++ .pfn = __phys_to_pfn(IO_VIRT_TO_PHYS(MMSYS1_CONFIG_BASE)), ++ .length = SZ_16M, ++ .type = MT_DEVICE ++ }, ++ #endif ++ { ++ /* From: 0xF2000000 to 0xF2020000*/ ++ .virtual = SYSRAM_BASE, ++ .pfn = __phys_to_pfn(0x00200000), ++ .length = SZ_128K, ++ .type = MT_DEVICE ++ }, ++ { ++ .virtual = DISPSYS_BASE, ++ .pfn = __phys_to_pfn(IO_VIRT_TO_PHYS(DISPSYS_BASE)), ++ .length = SZ_16M, ++ .type = MT_DEVICE ++ }, ++ { ++ .virtual = IMGSYS_CONFG_BASE, ++ .pfn = __phys_to_pfn(IO_VIRT_TO_PHYS(IMGSYS_CONFG_BASE)), ++ .length = SZ_16M, ++ .type = MT_DEVICE ++ }, ++ /* G3DSYS */ ++ { ++ .virtual = G3D_CONFIG_BASE, ++ .pfn = __phys_to_pfn(IO_VIRT_TO_PHYS(G3D_CONFIG_BASE)), ++ .length = SZ_4K, ++ .type = MT_DEVICE ++ }, ++ { ++ .virtual = DEVINFO_BASE, ++ .pfn = __phys_to_pfn(0x08000000), ++ .length = SZ_64K, ++ .type = MT_DEVICE ++ }, ++ { ++ .virtual = MALI_BASE, ++ .pfn = __phys_to_pfn(IO_VIRT_TO_PHYS(MALI_BASE)), ++ .length = SZ_64K, ++ .type = MT_DEVICE ++ }, ++ { ++ .virtual = INTER_SRAM, ++ .pfn = __phys_to_pfn(0x00100000), ++ .length = SZ_64K, ++ .type = MT_DEVICE ++ }, ++#endif ++}; ++ + + + #define GPT6_CON_MT65xx 0x10008060 +@@ -55,7 +235,13 @@ static const char * const mediatek_board_dt_compat[] = { + NULL, + }; + ++void __init mt_map_io(void) ++{ ++ iotable_init(mt_io_desc, ARRAY_SIZE(mt_io_desc)); ++} ++ + DT_MACHINE_START(MEDIATEK_DT, "Mediatek Cortex-A7 (Device Tree)") + .dt_compat = mediatek_board_dt_compat, + .init_time = mediatek_timer_init, ++ .map_io = mt_map_io, + MACHINE_END +diff --git a/arch/arm/mach-mediatek/mt_reg_base.h b/arch/arm/mach-mediatek/mt_reg_base.h +new file mode 100644 +index 0000000..cf2bb9e +--- /dev/null ++++ b/arch/arm/mach-mediatek/mt_reg_base.h +@@ -0,0 +1,640 @@ ++/* ++ * This file is generated automatically according to the design of silicon. ++ * Don't modify it directly. ++ */ ++ ++#ifndef __MT_REG_BASE ++#define __MT_REG_BASE ++ ++#if !defined(CONFIG_MT8127_FPGA) ++ ++// APB Module cksys ++#define INFRA_BASE (0xF0000000) ++ ++// APB Module infracfg_ao ++#define INFRACFG_AO_BASE (0xF0001000) ++ ++// APB Module fhctl ++#define FHCTL_BASE (0xF0002000) ++ ++// APB Module pericfg ++#define PERICFG_BASE (0xF0003000) ++ ++// APB Module dramc ++#define DRAMC0_BASE (0xF0004000) ++ ++// APB Module gpio ++#define GPIO_BASE (0xF0005000) ++ ++// APB Module sleep ++#define SPM_BASE (0xF0006000) ++ ++// APB Module toprgu ++#define TOPRGU_BASE (0xF0007000) ++#define AP_RGU_BASE TOPRGU_BASE ++ ++// APB Module apxgpt ++#define APMCU_GPTIMER_BASE (0xF0008000) ++ ++// APB Module rsvd ++#define RSVD_BASE (0xF0009000) ++ ++// APB Module sej ++#define HACC_BASE (0xF000A000) ++ ++// APB Module ap_cirq_eint ++#define AP_CIRQ_EINT (0xF000B000) ++ ++// APB Module ap_cirq_eint ++#define EINT_BASE (0xF000B000) ++ ++// APB Module smi ++#define SMI1_BASE (0xF000C000) ++ ++// APB Module pmic_wrap ++#define PWRAP_BASE (0xF000D000) ++ ++// APB Module device_apc_ao ++#define DEVAPC_AO_BASE (0xF000E000) ++ ++// APB Module ddrphy ++#define DDRPHY_BASE (0xF000F000) ++ ++// APB Module vencpll ++#define VENCPLL_BASE (0xF000F000) ++ ++// APB Module mipi_tx_config ++#define MIPI_CONFIG_BASE (0xF0010000) ++ ++// APB Module LVDS ANA ++#define LVDS_ANA_BASE (0xF0010400) ++ ++// APB Module mipi_rx_ana ++#define MIPI_RX_ANA_BASE (0xF0215000) ++ ++// APB Module kp ++#define KP_BASE (0xF0011000) ++ ++// APB Module dbgapb ++#define DEBUGTOP_BASE (0xF0100000) ++ ++// APB Module mcucfg ++#define MCUSYS_CFGREG_BASE (0xF0200000) ++ ++// APB Module infracfg ++#define INFRACFG_BASE (0xF0201000) ++ ++// APB Module sramrom ++#define SRAMROM_BASE (0xF0202000) ++ ++// APB Module emi ++#define EMI_BASE (0xF0203000) ++ ++// APB Module sys_cirq ++#define SYS_CIRQ_BASE (0xF0204000) ++ ++// APB Module m4u ++#define SMI_MMU_TOP_BASE (0xF0205000) ++ ++// APB Module nb_mmu ++#define NB_MMU0_BASE (0xF0205200) ++ ++// APB Module nb_mmu ++#define NB_MMU1_BASE (0xF0205800) ++ ++// APB Module efusec ++#define EFUSEC_BASE (0xF0206000) ++ ++// APB Module device_apc ++#define DEVAPC_BASE (0xF0207000) ++ ++// APB Module mcu_biu_cfg ++#define MCU_BIU_BASE (0xF0208000) ++ ++// APB Module apmixed ++#define APMIXEDSYS_BASE (0xF0209000) ++ ++// APB Module ccif ++#define AP_CCIF_BASE (0xF020A000) ++ ++// APB Module ccif ++#define MD_CCIF_BASE (0xF020B000) ++ ++// APB Module gpio1 ++#define GPIO1_BASE (0xF020C000) ++ ++// APB Module infra_mbist ++#define INFRA_TOP_MBIST_CTRL_BASE (0xF020D000) ++ ++// APB Module dramc_conf_nao ++#define DRAMC_NAO_BASE (0xF020E000) ++ ++// APB Module trng ++#define TRNG_BASE (0xF020F000) ++ ++// APB Module ca9 ++#define CORTEXA7MP_BASE (0xF0210000) ++ ++// APB Module ap_dma ++#define AP_DMA_BASE (0xF1000000) ++ ++// APB Module auxadc ++#define AUXADC_BASE (0xF1001000) ++ ++// APB Module uart ++#define UART1_BASE (0xF1002000) ++ ++// APB Module uart ++#define UART2_BASE (0xF1003000) ++ ++// APB Module uart ++#define UART3_BASE (0xF1004000) ++ ++// APB Module uart ++#define UART4_BASE (0xF1005000) ++ ++// APB Module pwm ++#define PWM_BASE (0xF1006000) ++ ++// APB Module i2c ++#define I2C0_BASE (0xF1007000) ++ ++// APB Module i2c ++#define I2C1_BASE (0xF1008000) ++ ++// APB Module i2c ++#define I2C2_BASE (0xF1009000) ++ ++// APB Module spi ++#define SPI0_BASE (0xF100A000) ++#define SPI1_BASE (0xF100A000) ++ ++// APB Module therm_ctrl ++#define THERMAL_BASE (0xF100B000) ++ ++// APB Module btif ++#define BTIF_BASE (0xF100C000) ++ ++// APB Module nfi ++#define NFI_BASE (0xF100D000) ++ ++// APB Module nfiecc_16bit ++#define NFIECC_BASE (0xF100E000) ++ ++// APB Module nli_arb ++#define NLI_ARB_BASE (0xF100F000) ++ ++// APB Module peri_pwrap_bridge ++#define PERI_PWRAP_BRIDGE_BASE (0xF1017000) ++ ++// APB Module usb2 ++#define USB_BASE (0xF1200000) ++#define USB1_BASE (0xF1270000) ++ ++// APB Module usb_sif ++#define USB_SIF_BASE (0xF1210000) ++ ++// APB Module msdc ++#define MSDC_0_BASE (0xF1230000) ++ ++// APB Module msdc ++#define MSDC_1_BASE (0xF1240000) ++ ++// APB Module msdc ++#define MSDC_2_BASE (0xF1250000) ++ ++// APB Module msdc ++#define MSDC_3_BASE (0xF12C0000) ++ ++// APB Module wcn_ahb ++#define WCN_AHB_BASE (0xF1260000) ++ ++// ARB Module ethernet ++#define ETHERNET_BASE (0xF1280000) ++// APB Module mfg_top ++#define G3D_CONFIG_BASE (0xF3000000) ++ ++// APB Module mali ++#define MALI_BASE (0xF3040000) ++ ++// APB Module mali_tb_cmd ++#define MALI_TB_BASE (0xF301f000) ++ ++// APB Module mmsys_config ++#define DISPSYS_BASE (0xF4000000) ++ ++// APB Module mdp_rdma ++#define MDP_RDMA_BASE (0xF4001000) ++ ++// APB Module mdp_rsz ++#define MDP_RSZ0_BASE (0xF4002000) ++ ++// APB Module mdp_rsz ++#define MDP_RSZ1_BASE (0xF4003000) ++ ++// APB Module disp_wdma ++#define MDP_WDMA_BASE (0xF4004000) ++ ++// APB Module disp_wdma ++#define WDMA1_BASE (0xF4004000) ++ ++// APB Module mdp_wrot ++#define MDP_WROT_BASE (0xF4005000) ++ ++// APB Module mdp_tdshp ++#define MDP_TDSHP_BASE (0xF4006000) ++ ++// APB Module ovl ++#define DISP_OVL_BASE (0xF4007000) ++ ++// APB Module ovl ++#define OVL0_BASE (0xF4007000) ++ ++// APB Module ovl ++#define OVL1_BASE (0xF4007000) ++ ++// APB Module disp_rdma ++#define DISP_RDMA_BASE (0xF4008000) ++ ++// APB Module disp_rdma ++#define R_DMA1_BASE (0xF4008000) ++ ++// APB Module disp_rdma ++#define R_DMA0_BASE (0xF4008000) ++ ++// APB Module disp_wdma ++#define DISP_WDMA_BASE (0xF4009000) ++ ++// APB Module disp_wdma ++#define WDMA0_BASE (0xF4009000) ++ ++// APB Module disp_bls ++#define DISP_BLS_BASE (0xF400A000) ++ ++// APB Module disp_color_config ++#define DISP_COLOR_BASE (0xF400B000) ++ ++// APB Module dsi ++#define DSI_BASE (0xF400C000) ++ ++// APB Module disp_dpi ++#define DPI_BASE (0xF400D000) ++ ++// APB Module disp_mutex ++#define MMSYS_MUTEX_BASE (0xF400E000) ++ ++// APB Module mm_cmdq ++#define MMSYS_CMDQ_BASE (0xF400F000) ++ ++#define DPI1_BASE (0xF4014000) ++ ++ ++// APB Module smi_larb ++#define SMI_LARB0_BASE (0xF4010000) ++ ++// APB Module smi ++#define SMI_BASE (0xF4011000) ++ ++// LVDS TX ++#define LVDS_TX_BASE (0xF4016200) ++ ++// APB Module smi_larb ++#define SMILARB2_BASE (0xF5001000) ++ ++// APB Module smi_larb ++#define SMI_LARB3_BASE (0xF5001000) ++ ++// APB Module mmu ++#define SMI_LARB3_MMU_BASE (0xF5001800) ++ ++// APB Module smi_larb ++#define SMI_LARB4_BASE (0xF5002000) ++ ++// APB Module fake_eng ++#define FAKE_ENG_BASE (0xF5002000) ++ ++// APB Module mmu ++#define SMI_LARB4_MMU_BASE (0xF5002800) ++ ++// APB Module smi ++#define VENC_BASE (0xF5009000) ++ ++// APB Module jpgenc ++#define JPGENC_BASE (0xF500A000) ++ ++// APB Module vdecsys_config ++#define VDEC_GCON_BASE (0xF6000000) ++ ++// APB Module smi_larb ++#define SMI_LARB1_BASE (0xF6010000) ++ ++// APB Module mmu ++#define SMI_LARB1_MMU_BASE (0xF6010800) ++ ++// APB Module vdtop ++#define VDEC_BASE (0xF6020000) ++ ++// APB Module vdtop ++#define VDTOP_BASE (0xF6020000) ++ ++// APB Module vld ++#define VLD_BASE (0xF6021000) ++ ++// APB Module vld_top ++#define VLD_TOP_BASE (0xF6021800) ++ ++// APB Module mc ++#define MC_BASE (0xF6022000) ++ ++// APB Module avc_vld ++#define AVC_VLD_BASE (0xF6023000) ++ ++// APB Module avc_mv ++#define AVC_MV_BASE (0xF6024000) ++ ++// APB Module vdec_pp ++#define VDEC_PP_BASE (0xF6025000) ++ ++// APB Module vp8_vld ++#define VP8_VLD_BASE (0xF6026800) ++ ++// APB Module vp6 ++#define VP6_BASE (0xF6027000) ++ ++// APB Module vld2 ++#define VLD2_BASE (0xF6027800) ++ ++// APB Module mc_vmmu ++#define MC_VMMU_BASE (0xF6028000) ++ ++// APB Module pp_vmmu ++#define PP_VMMU_BASE (0xF6029000) ++ ++// APB Module imgsys ++#define IMGSYS_CONFG_BASE (0xF5000000) ++ ++// APB Module cam ++#define CAMINF_BASE (0xF5000000) ++ ++// APB Module csi2 ++#define CSI2_BASE (0xF5000000) ++ ++// APB Module seninf ++#define SENINF_BASE (0xF5000000) ++ ++// APB Module seninf_tg ++#define SENINF_TG_BASE (0xF5000000) ++ ++// APB Module seninf_top ++#define SENINF_TOP_BASE (0xF5000000) ++ ++// APB Module mipi_rx_config ++#define MIPI_RX_CONFIG_BASE (0xF500C000) ++ ++// APB Module scam ++#define SCAM_BASE (0xF5008000) ++ ++// APB Module ncsi2 ++#define NCSI2_BASE (0xF5008000) ++ ++// APB Module ccir656 ++#define CCIR656_BASE (0xF5000000) ++ ++// APB Module n3d_ctl ++#define N3D_CTL_BASE (0xF5000000) ++ ++// APB Module fdvt ++#define FDVT_BASE (0xF500B000) ++ ++// APB Module audiosys ++#define AUDIO_BASE (0xF1221000) ++#define AUDIO_REG_BASE (0xF1220000) ++ ++// CONNSYS ++#define CONN_BTSYS_PKV_BASE (0xF8000000) ++#define CONN_BTSYS_TIMCON_BASE (0xF8010000) ++#define CONN_BTSYS_RF_CONTROL_BASE (0xF8020000) ++#define CONN_BTSYS_MODEM_BASE (0xF8030000) ++#define CONN_BTSYS_BT_CONFIG_BASE (0xF8040000) ++#define CONN_MCU_CONFIG_BASE (0xF8070000) ++#define CONN_TOP_CR_BASE (0xF80B0000) ++#define CONN_HIF_CR_BASE (0xF80F0000) ++ ++/* ++ * Addresses below are added manually. ++ * They cannot be mapped via IO_VIRT_TO_PHYS(). ++ */ ++ ++#define GIC_CPU_BASE (CORTEXA7MP_BASE + 0x2000) ++#define GIC_DIST_BASE (CORTEXA7MP_BASE + 0x1000) ++#define SYSRAM_BASE 0xF2000000 /* L2 cache shared RAM */ ++#define DEVINFO_BASE 0xF7000000 ++#define INTER_SRAM 0xF9000000 ++ ++#else ++ ++#define SMI_MMU_TOP_BASE 0xF0205000 ++#define SMILARB2_BASE 0xF5001000 ++ ++/* on-chip SRAM */ ++#define INTER_SRAM 0xF9000000 ++ ++/* infrasys */ ++//#define TOPRGU_BASE 0xF0000000 ++#define INFRA_BASE 0xF0000000 ++#define INFRACFG_BASE 0xF0001000 ++#define INFRACFG_AO_BASE 0xF0001000 ++#define FHCTL_BASE 0xF0002000 ++#define PERICFG_BASE 0xF0003000 ++#define DRAMC0_BASE 0xF0004000 ++#define DDRPHY_BASE 0xF000F000 ++#define DRAMC_NAO_BASE 0xF020E000 ++#define GPIO_BASE 0xF0005000 ++#define GPIO1_BASE 0xF020C000 ++#define TOPSM_BASE 0xF0006000 ++#define SPM_BASE 0xF0006000 ++#define TOPRGU_BASE 0xF0007000 ++#define AP_RGU_BASE TOPRGU_BASE ++#define APMCU_GPTIMER_BASE 0xF0008000 ++#define HACC_BASE 0xF000A000 ++#define AP_CIRQ_EINT 0xF000B000 ++#define SMI1_BASE 0xF000C000 ++#define MIPI_CONFIG_BASE 0xF0010000 ++// APB Module LVDS ANA ++#define LVDS_ANA_BASE (0xF0010400) ++ ++ ++#define KP_BASE 0xF0011000 ++#if 0 ++#define DEVICE_APC_0_BASE 0xF0010000 ++#define DEVICE_APC_1_BASE 0xF0011000 ++#define DEVICE_APC_2_BASE 0xF0012000 ++#define DEVICE_APC_3_BASE 0xF0013000 ++#define DEVICE_APC_4_BASE 0xF0014000 ++#define SMI0_BASE 0xF0208000 ++#endif ++#define EINT_BASE 0xF000B000 ++ ++ ++#define DEBUGTOP_BASE 0xF0100000 ++#define MCUSYS_CFGREG_BASE 0xF0200000 ++#define SRAMROM_BASE 0xF0202000 ++#define EMI_BASE 0xF0203000 ++#define EFUSEC_BASE 0xF0206000 ++#define MCU_BIU_BASE 0xF0208000 ++#define APMIXED_BASE 0xF0209000 ++#define APMIXEDSYS_BASE 0xF0209000 ++#define AP_CCIF_BASE 0xF020A000 ++#define MD_CCIF_BASE 0xF020B000 ++#define INFRA_TOP_MBIST_CTRL_BASE 0xF020D000 ++#define DRAMC_NAO_BASE 0xF020E000 ++#define CORTEXA7MP_BASE 0xF0210000 ++#define GIC_CPU_BASE (CORTEXA7MP_BASE + 0x2000) ++#define GIC_DIST_BASE (CORTEXA7MP_BASE + 0x1000) ++//#define SMI_LARB_BASE 0xF0211000 ++//#define MCUSYS_AVS_BASE 0xF0212000 ++ ++/* perisys */ ++/*avalaible*/ ++#define AP_DMA_BASE 0xF1000000 ++#define AUXADC_BASE 0xF1001000 ++#define UART1_BASE 0xF1002000 ++#define UART2_BASE 0xF1003000 ++#define UART3_BASE 0xF1004000 ++#define UART4_BASE 0xF1005000 ++#define PWM_BASE 0xF1006000 ++#define I2C0_BASE 0xF1007000 ++#define I2C1_BASE 0xF1008000 ++#define I2C2_BASE 0xF1009000 ++#define SPI0_BASE 0xF100A000 ++#define BTIF_BASE (0xF100C000) ++#define NFI_BASE 0xF100D000 ++#define NFIECC_BASE 0xF100E000 ++#define NLI_ARB_BASE 0xF100F000 ++#define I2C3_BASE 0xF1010000 //FIXME 6582 take off ++#define SPI1_BASE 0xF100A000 ++#define THERMAL_BASE 0xF100B000 ++ ++// APB Module pmic_wrap ++#define PWRAP_BASE (0xF000D000) ++ ++#if 0 ++//#define IRDA_BASE 0xF1007000 ++#define I2C4_BASE 0xF1014000 ++#define I2CDUAL_BASE 0xF1015000 ++#define ACCDET_BASE 0xF1016000 ++#define AP_HIF_BASE 0xF1017000 ++#define MD_HIF_BASE 0xF1018000 ++#define GCPU_BASE 0xF101B000 ++#define GCPU_NS_BASE 0xF01C000 ++#define GCPU_MMU_BASE 0xF01D000 ++#define SATA_BASE 0xF01E000 ++#define CEC_BASE 0xF01F000 ++//#define SPI1_BASE 0xF1022000 ++#endif ++ ++#define USB1_BASE 0xF1270000 ++#define USB2_BASE 0xF1200000 ++#define USB_BASE 0xF1200000 ++#define USB_SIF_BASE 0xF1210000 ++//#define USB3_BASE 0xF1220000 ++#define MSDC_0_BASE 0xF1230000 ++#define MSDC_1_BASE 0xF1240000 ++#define MSDC_2_BASE 0xF1250000 ++#define MSDC_3_BASE 0xF12C0000 ++#define MSDC_4_BASE 0xF1270000 ++//#define ETHERNET_BASE 0xF1290000 ++ ++//#define ETB_BASE 0xF0111000 ++//#define ETM_BASE 0xF017C000 ++ ++ ++/* SMI common subsystem */ ++#define SYSRAM_BASE 0xF2000000 ++#define AUDIO_REG_BASE 0xF2030000 ++#define MFG_AXI_BASE 0xF2060000 ++#define CONN_MCU_CONFIG_BASE 0xF8070000 ++#define AUDIO_BASE 0xF1200000 //0xF2071000 ++#define MMSYS1_CONFIG_BASE 0xF2080000 ++#define SMI_LARB0_BASE 0xF2081000 ++// APB Module smi ++#define SMI_BASE (0xF4011000) ++#define SMI_LARB1_BASE 0xF2082000 ++#define SMI_LARB2_BASE 0xF2083000 ++#define VDEC_GCON_BASE 0xF6000000 //0xF4000000 ++#define VDEC_BASE 0xF4020000 ++#define VENC_TOP_BASE 0xF7000000 ++#define VENC_BASE 0xF7002000 ++#define JPGENC_BASE 0xF500A000 ++#define R_DMA0_BASE 0xF2086000 ++#define R_DMA1_BASE 0xF2087000 ++#define VDO_ROT0_BASE 0xF2088000 ++#define RGB_ROT0_BASE 0xF2089000 ++#define VDO_ROT1_BASE 0xF208A000 ++#define RGB_ROT1_BASE 0xF208B000 ++//#define DPI_BASE 0xF208C000 ++#define BRZ_BASE 0xF208D000 ++#define JPG_DMA_BASE 0xF208E000 ++#define OVL_DMA_BASE 0xF208F000 ++#define CSI2_BASE 0xF2092000 ++#define CRZ_BASE 0xF2093000 ++#define VRZ0_BASE 0xF2094000 ++#define IMGPROC_BASE 0xF2095000 ++#define EIS_BASE 0xF2096000 ++#define SPI_BASE 0xF2097000 ++#define SCAM_BASE 0xF2098000 ++#define PRZ0_BASE 0xF2099000 ++#define PRZ1_BASE 0xF209A000 ++#define JPG_CODEC_BASE 0xF209B000 ++//#define DSI_BASE 0xF209C000 ++#define TVC_BASE 0xF209D000 ++#define TVE_BASE 0xF209E000 ++#define TV_ROT_BASE 0xF209F000 ++#define RGB_ROT2_BASE 0xF20A0000 ++//#define LCD_BASE 0xF20A1000 ++#define FD_BASE 0xF20A2000 ++#define MIPI_CONFG_BASE 0xF20A3000 ++#define VRZ1_BASE 0xF20A4000 ++#define MMSYS2_CONFG_BASE 0xF20C0000 ++#define SMI_LARB3_BASE 0xF20C1000 ++#define MFG_APB_BASE 0xF20C4000 ++#define G2D_BASE 0xF20C6000 ++ ++#define DISPSYS_BASE 0xF4000000 ++#define ROT_BASE 0xF4001000 ++#define SCL_BASE 0xF4002000 ++#define OVL_BASE 0xF4007000 ++#define WDMA0_BASE 0xF4009000 ++#define WDMA1_BASE 0xF4005000 ++#define RDMA0_BASE 0xF4008000 ++//#define RDMA1_BASE 0xF4007000 ++#define BLS_BASE 0xF400A000 ++//#define GAMMA_BASE 0xF400000 ++#define COLOR_BASE 0xF400B000 ++#define TDSHP_BASE 0xF4006000 ++#define LCD_BASE 0xF4012000// only exist on FPGA ++#define DSI_BASE 0xF400C000 ++#define DPI_BASE 0xF400D000 ++ ++#define DPI1_BASE 0xF4014000 ++ ++// LVDS TX ++#define LVDS_TX_BASE (0xF4016200) ++ ++#define SMILARB1_BASE 0xF4010000 ++#define DISP_MUTEX_BASE 0xF400E000 ++#define DISP_CMDQ_BASE 0xF400F000 ++ ++/* imgsys */ ++#define IMGSYS_CONFG_BASE 0xF5000000 ++#define CAMINF_BASE IMGSYS_CONFG_BASE ++ ++/* G3DSYS */ ++#define G3D_CONFIG_BASE 0xF3000000 ++#define MALI_BASE 0xF3040000 ++ ++#define DEVINFO_BASE 0xF8000000 ++ ++#endif ++ ++#endif +diff --git a/arch/arm/mach-mediatek/rt_mmap.h b/arch/arm/mach-mediatek/rt_mmap.h +new file mode 100644 +index 0000000..e86b3bb +--- /dev/null ++++ b/arch/arm/mach-mediatek/rt_mmap.h +@@ -0,0 +1,58 @@ ++#define HIFSYS_BASE 0xFA000000 //for PCIe/USB ++#define ETHDMASYS_BASE 0xFB000000 //for I2S/PCM/GDMA/HSDMA/FE/GMAC ++ ++#define HIFSYS_PCI_BASE 0xFA140000 ++#define HIFSYS_USB_HOST_BASE 0xFA1C0000 ++#define HIFSYS_USB_HOST2_BASE 0xFA240000 ++ ++#define ETHDMASYS_SYSCTL_BASE 0xFB000000 ++#define ETHDMASYS_RBUS_MATRIXCTL_BASE 0xFB000400 ++#define ETHDMASYS_I2S_BASE 0xFB000A00 ++#define ETHDMASYS_PCM_BASE 0xFB002000 ++#define ETHDMASYS_GDMA_BASE 0xFB002800 ++#define ETHDMASYS_HS_DMA_BASE 0xFB007000 ++#define ETHDMASYS_FRAME_ENGINE_BASE 0xFB100000 ++#define ETHDMASYS_PPE_BASE 0xFB100C00 ++#define ETHDMASYS_ETH_SW_BASE 0xFB110000 ++#define ETHDMASYS_CRYPTO_ENGINE_BASE 0xFB240000 ++ ++//for backward-compatible ++#define RALINK_FRAME_ENGINE_BASE ETHDMASYS_FRAME_ENGINE_BASE ++#define RALINK_PPE_BASE ETHDMASYS_PPE_BASE ++#define RALINK_SYSCTL_BASE ETHDMASYS_SYSCTL_BASE ++#define RALINK_ETH_SW_BASE ETHDMASYS_ETH_SW_BASE ++#define RALINK_GDMA_BASE ETHDMASYS_GDMA_BASE ++#define RALINK_HS_DMA_BASE ETHDMASYS_HS_DMA_BASE ++#define RALINK_11N_MAC_BASE 0 //unused for rt_rdm usage ++ ++//Reset Control Register ++#define RSTCTL_SYS_RST (1<<0) ++#define RSTCTL_MCM_RST (1<<2) ++#define RSTCTL_HSDMA_RST (1<<5) ++#define RSTCTL_FE_RST (1<<6) ++#define RSTCTL_SPDIF_RST (1<<7) ++#define RSTCTL_TIMER_RST (1<<8) ++#define RSTCTL_CIRQ_RST (1<<9) ++#define RSTCTL_MC_RST (1<<10) ++#define RSTCTL_PCM_RST (1<<11) ++#define RSTCTL_GPIO_RST (1<<13) ++#define RSTCTL_GDMA_RST (1<<14) ++#define RSTCTL_NAND_RST (1<<15) ++#define RSTCTL_I2C_RST (1<<16) ++#define RSTCTL_I2S_RST (1<<17) ++#define RSTCTL_SPI_RST (1<<18) ++#define RSTCTL_UART0_RST (1<<19) ++#define RSTCTL_UART1_RST (1<<20) ++#define RSTCTL_UART2_RST (1<<21) ++#define RSTCTL_UPHY_RST (1<<22) ++#define RSTCTL_ETH_RST (1<<23) ++#define RSTCTL_PCIE0_RST (1<<24) ++#define RSTCTL_PCIE1_RST (1<<25) ++#define RSTCTL_PCIE2_RST (1<<26) ++#define RSTCTL_AUX_STCK_RST (1<<28) ++#define RSTCTL_CRYPT_RST (1<<29) ++#define RSTCTL_SDXC_RST (1<<30) ++#define RSTCTL_PWM_RST (1<<31) ++ ++//for backward-compatible ++#define RALINK_FE_RST RSTCTL_FE_RST +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0069-arm-mediatek-add-mt7623-support-to-pmic-wrapper.patch b/target/linux/mediatek/patches/0069-arm-mediatek-add-mt7623-support-to-pmic-wrapper.patch new file mode 100644 index 0000000000..b724682433 --- /dev/null +++ b/target/linux/mediatek/patches/0069-arm-mediatek-add-mt7623-support-to-pmic-wrapper.patch @@ -0,0 +1,554 @@ +From 0ec1ddd9233579b6d6dc0df325e870c5560344be Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Sun, 28 Jun 2015 19:50:51 +0200 +Subject: [PATCH 69/76] arm: mediatek: add mt7623 support to pmic-wrapper + +Signed-off-by: John Crispin <blogic@openwrt.org> +--- + drivers/soc/mediatek/mtk-pmic-wrap.c | 345 +++++++++++++++++++++++++++++----- + 1 file changed, 296 insertions(+), 49 deletions(-) + +diff --git a/drivers/soc/mediatek/mtk-pmic-wrap.c b/drivers/soc/mediatek/mtk-pmic-wrap.c +index f432291..9ff02a1 100644 +--- a/drivers/soc/mediatek/mtk-pmic-wrap.c ++++ b/drivers/soc/mediatek/mtk-pmic-wrap.c +@@ -31,6 +31,13 @@ + #define PWRAP_MT8135_BRIDGE_WDT_UNIT 0x50 + #define PWRAP_MT8135_BRIDGE_WDT_SRC_EN 0x54 + ++#define PWRAP_MT7623_AUXADC_CON21 0x076C ++#define PWRAP_MT7623_AUXADC_ADC12 0x072C ++#define PWRAP_MT7623_AUXADC_ADC13 0x072E ++#define PWRAP_MT7623_AUXADC_ADC14 0x0730 ++#define PWRAP_MT7623_AUXADC_CON2 0x0746 ++#define PWRAP_MT7623_AUXADC_CON3 0x0748 ++ + /* macro for wrapper status */ + #define PWRAP_GET_WACS_RDATA(x) (((x) >> 0) & 0x0000ffff) + #define PWRAP_GET_WACS_FSM(x) (((x) >> 16) & 0x00000007) +@@ -61,32 +68,104 @@ + #define PWRAP_MAN_CMD_OP_OUTQ (0xa << 8) + + /* macro for slave device wrapper registers */ +-#define PWRAP_DEW_BASE 0xbc00 +-#define PWRAP_DEW_EVENT_OUT_EN (PWRAP_DEW_BASE + 0x0) +-#define PWRAP_DEW_DIO_EN (PWRAP_DEW_BASE + 0x2) +-#define PWRAP_DEW_EVENT_SRC_EN (PWRAP_DEW_BASE + 0x4) +-#define PWRAP_DEW_EVENT_SRC (PWRAP_DEW_BASE + 0x6) +-#define PWRAP_DEW_EVENT_FLAG (PWRAP_DEW_BASE + 0x8) +-#define PWRAP_DEW_READ_TEST (PWRAP_DEW_BASE + 0xa) +-#define PWRAP_DEW_WRITE_TEST (PWRAP_DEW_BASE + 0xc) +-#define PWRAP_DEW_CRC_EN (PWRAP_DEW_BASE + 0xe) +-#define PWRAP_DEW_CRC_VAL (PWRAP_DEW_BASE + 0x10) +-#define PWRAP_DEW_MON_GRP_SEL (PWRAP_DEW_BASE + 0x12) +-#define PWRAP_DEW_MON_FLAG_SEL (PWRAP_DEW_BASE + 0x14) +-#define PWRAP_DEW_EVENT_TEST (PWRAP_DEW_BASE + 0x16) +-#define PWRAP_DEW_CIPHER_KEY_SEL (PWRAP_DEW_BASE + 0x18) +-#define PWRAP_DEW_CIPHER_IV_SEL (PWRAP_DEW_BASE + 0x1a) +-#define PWRAP_DEW_CIPHER_LOAD (PWRAP_DEW_BASE + 0x1c) +-#define PWRAP_DEW_CIPHER_START (PWRAP_DEW_BASE + 0x1e) +-#define PWRAP_DEW_CIPHER_RDY (PWRAP_DEW_BASE + 0x20) +-#define PWRAP_DEW_CIPHER_MODE (PWRAP_DEW_BASE + 0x22) +-#define PWRAP_DEW_CIPHER_SWRST (PWRAP_DEW_BASE + 0x24) +-#define PWRAP_MT8173_DEW_CIPHER_IV0 (PWRAP_DEW_BASE + 0x26) +-#define PWRAP_MT8173_DEW_CIPHER_IV1 (PWRAP_DEW_BASE + 0x28) +-#define PWRAP_MT8173_DEW_CIPHER_IV2 (PWRAP_DEW_BASE + 0x2a) +-#define PWRAP_MT8173_DEW_CIPHER_IV3 (PWRAP_DEW_BASE + 0x2c) +-#define PWRAP_MT8173_DEW_CIPHER_IV4 (PWRAP_DEW_BASE + 0x2e) +-#define PWRAP_MT8173_DEW_CIPHER_IV5 (PWRAP_DEW_BASE + 0x30) ++enum pwrap_dew_regs { ++ PWRAP_DEW_EVENT_OUT_EN, ++ PWRAP_DEW_DIO_EN, ++ PWRAP_DEW_EVENT_SRC_EN, ++ PWRAP_DEW_EVENT_SRC, ++ PWRAP_DEW_EVENT_FLAG, ++ PWRAP_DEW_READ_TEST, ++ PWRAP_DEW_WRITE_TEST, ++ PWRAP_DEW_CRC_EN, ++ PWRAP_DEW_CRC_VAL, ++ PWRAP_DEW_MON_GRP_SEL, ++ PWRAP_DEW_MON_FLAG_SEL, ++ PWRAP_DEW_EVENT_TEST, ++ PWRAP_DEW_CIPHER_KEY_SEL, ++ PWRAP_DEW_CIPHER_IV_SEL, ++ PWRAP_DEW_CIPHER_LOAD, ++ PWRAP_DEW_CIPHER_START, ++ PWRAP_DEW_CIPHER_RDY, ++ PWRAP_DEW_CIPHER_MODE, ++ PWRAP_DEW_CIPHER_SWRST, ++ ++ /* MT7623 only regs */ ++ PWRAP_DEW_CIPHER_EN, ++ PWRAP_DEW_RDDMY_NO, ++ ++ /* MT8173 only regs */ ++ PWRAP_DEW_CIPHER_IV0, ++ PWRAP_DEW_CIPHER_IV1, ++ PWRAP_DEW_CIPHER_IV2, ++ PWRAP_DEW_CIPHER_IV3, ++ PWRAP_DEW_CIPHER_IV4, ++ PWRAP_DEW_CIPHER_IV5, ++}; ++ ++static int mt7623_dew_regs[] = { ++ [PWRAP_DEW_DIO_EN] = 0x18a, ++ [PWRAP_DEW_READ_TEST] = 0x18c, ++ [PWRAP_DEW_WRITE_TEST] = 0x18e, ++ [PWRAP_DEW_CRC_EN] = 0x192, ++ [PWRAP_DEW_CRC_VAL] = 0x194, ++ [PWRAP_DEW_CIPHER_KEY_SEL] = 0x198, ++ [PWRAP_DEW_CIPHER_IV_SEL] = 0x19a, ++ [PWRAP_DEW_CIPHER_EN] = 0x19c, ++ [PWRAP_DEW_CIPHER_RDY] = 0x19e, ++ [PWRAP_DEW_CIPHER_MODE] = 0x1a0, ++ [PWRAP_DEW_CIPHER_SWRST] = 0x1a2, ++ [PWRAP_DEW_RDDMY_NO] = 0x1a4, ++}; ++ ++static int mt8135_dew_regs[] = { ++ [PWRAP_DEW_EVENT_OUT_EN] = 0x0, ++ [PWRAP_DEW_DIO_EN] = 0x2, ++ [PWRAP_DEW_EVENT_SRC_EN] = 0x4, ++ [PWRAP_DEW_EVENT_SRC] = 0x6, ++ [PWRAP_DEW_EVENT_FLAG] = 0x8, ++ [PWRAP_DEW_READ_TEST] = 0xa, ++ [PWRAP_DEW_WRITE_TEST] = 0xc, ++ [PWRAP_DEW_CRC_EN] = 0xe, ++ [PWRAP_DEW_CRC_VAL] = 0x10, ++ [PWRAP_DEW_MON_GRP_SEL] = 0x12, ++ [PWRAP_DEW_MON_FLAG_SEL] = 0x14, ++ [PWRAP_DEW_EVENT_TEST] = 0x16, ++ [PWRAP_DEW_CIPHER_KEY_SEL] = 0x18, ++ [PWRAP_DEW_CIPHER_IV_SEL] = 0x1a, ++ [PWRAP_DEW_CIPHER_LOAD] = 0x1c, ++ [PWRAP_DEW_CIPHER_START] = 0x1e, ++ [PWRAP_DEW_CIPHER_RDY] = 0x20, ++ [PWRAP_DEW_CIPHER_MODE] = 0x22, ++ [PWRAP_DEW_CIPHER_SWRST] = 0x24, ++}; ++ ++static int mt8173_dew_regs[] = { ++ [PWRAP_DEW_EVENT_OUT_EN] = 0x0, ++ [PWRAP_DEW_DIO_EN] = 0x2, ++ [PWRAP_DEW_EVENT_SRC_EN] = 0x4, ++ [PWRAP_DEW_EVENT_SRC] = 0x6, ++ [PWRAP_DEW_EVENT_FLAG] = 0x8, ++ [PWRAP_DEW_READ_TEST] = 0xa, ++ [PWRAP_DEW_WRITE_TEST] = 0xc, ++ [PWRAP_DEW_CRC_EN] = 0xe, ++ [PWRAP_DEW_CRC_VAL] = 0x10, ++ [PWRAP_DEW_MON_GRP_SEL] = 0x12, ++ [PWRAP_DEW_MON_FLAG_SEL] = 0x14, ++ [PWRAP_DEW_EVENT_TEST] = 0x16, ++ [PWRAP_DEW_CIPHER_KEY_SEL] = 0x18, ++ [PWRAP_DEW_CIPHER_IV_SEL] = 0x1a, ++ [PWRAP_DEW_CIPHER_LOAD] = 0x1c, ++ [PWRAP_DEW_CIPHER_START] = 0x1e, ++ [PWRAP_DEW_CIPHER_RDY] = 0x20, ++ [PWRAP_DEW_CIPHER_MODE] = 0x22, ++ [PWRAP_DEW_CIPHER_SWRST] = 0x24, ++ [PWRAP_DEW_CIPHER_IV0] = 0x26, ++ [PWRAP_DEW_CIPHER_IV1] = 0x28, ++ [PWRAP_DEW_CIPHER_IV2] = 0x2a, ++ [PWRAP_DEW_CIPHER_IV3] = 0x2c, ++ [PWRAP_DEW_CIPHER_IV4] = 0x2e, ++ [PWRAP_DEW_CIPHER_IV5] = 0x30, ++}; + + enum pwrap_regs { + PWRAP_MUX_SEL, +@@ -162,7 +241,7 @@ enum pwrap_regs { + PWRAP_CIPHER_LOAD, + PWRAP_CIPHER_START, + +- /* MT8173 only regs */ ++ /* MT7623/MT8173 only regs */ + PWRAP_RDDMY, + PWRAP_SI_CK_CON, + PWRAP_DVFS_ADR0, +@@ -183,6 +262,107 @@ enum pwrap_regs { + PWRAP_DVFS_WDATA7, + PWRAP_SPMINF_STA, + PWRAP_CIPHER_EN, ++ ++ /* MT7623 only regs */ ++ PWRAP_OP_TYPE, ++ PWRAP_MSB_FIRST, ++ PWRAP_TOP_CKCON1, ++ PWRAP_TOP_CKCON1_CLR, ++ PWRAP_ADC_CMD_ADDR, ++ PWRAP_ADC_CMD, ++ PWRAP_ADC_RDY_ADDR, ++ PWRAP_ADC_RDATA_ADDR1, ++ PWRAP_ADC_RDATA_ADDR2, ++}; ++ ++static int mt7623_regs[] = { ++ [PWRAP_MUX_SEL] = 0x0, ++ [PWRAP_WRAP_EN] = 0x4, ++ [PWRAP_DIO_EN] = 0x8, ++ [PWRAP_SIDLY] = 0xc, ++ [PWRAP_OP_TYPE] = 0x10, ++ [PWRAP_MSB_FIRST] = 0x14, ++ [PWRAP_RDDMY] = 0x18, ++ [PWRAP_SI_CK_CON] = 0x1c, ++ [PWRAP_CSHEXT_WRITE] = 0x20, ++ [PWRAP_CSHEXT_READ] = 0x24, ++ [PWRAP_CSLEXT_START] = 0x28, ++ [PWRAP_CSLEXT_END] = 0x2c, ++ [PWRAP_STAUPD_PRD] = 0x30, ++ [PWRAP_STAUPD_GRPEN] = 0x34, ++ [PWRAP_STAUPD_MAN_TRIG] = 0x38, ++ [PWRAP_STAUPD_STA] = 0x3C, ++ [PWRAP_WRAP_STA] = 0x44, ++ [PWRAP_HARB_INIT] = 0x48, ++ [PWRAP_HARB_HPRIO] = 0x4c, ++ [PWRAP_HIPRIO_ARB_EN] = 0x50, ++ [PWRAP_HARB_STA0] = 0x54, ++ [PWRAP_HARB_STA1] = 0x58, ++ [PWRAP_MAN_EN] = 0x5c, ++ [PWRAP_MAN_CMD] = 0x60, ++ [PWRAP_MAN_RDATA] = 0x6c, ++ [PWRAP_MAN_VLDCLR] = 0x68, ++ [PWRAP_WACS0_EN] = 0x6c, ++ [PWRAP_INIT_DONE0] = 0x70, ++ [PWRAP_WACS0_CMD] = 0x74, ++ [PWRAP_WACS0_RDATA] = 0x78, ++ [PWRAP_WACS0_VLDCLR] = 0x7c, ++ [PWRAP_WACS1_EN] = 0x80, ++ [PWRAP_INIT_DONE1] = 0x84, ++ [PWRAP_WACS1_CMD] = 0x88, ++ [PWRAP_WACS1_RDATA] = 0x9c, ++ [PWRAP_WACS1_VLDCLR] = 0x90, ++ [PWRAP_WACS2_EN] = 0x94, ++ [PWRAP_INIT_DONE2] = 0x98, ++ [PWRAP_WACS2_CMD] = 0x9c, ++ [PWRAP_WACS2_RDATA] = 0xa0, ++ [PWRAP_WACS2_VLDCLR] = 0xa4, ++ [PWRAP_INT_EN] = 0xa8, ++ [PWRAP_INT_FLG_RAW] = 0xac, ++ [PWRAP_INT_FLG] = 0xb0, ++ [PWRAP_INT_CLR] = 0xb4, ++ [PWRAP_SIG_ADR] = 0xb8, ++ [PWRAP_SIG_MODE] = 0xbc, ++ [PWRAP_SIG_VALUE] = 0xc0, ++ [PWRAP_SIG_ERRVAL] = 0xc4, ++ [PWRAP_CRC_EN] = 0xc8, ++ [PWRAP_TIMER_EN] = 0xcc, ++ [PWRAP_TIMER_STA] = 0xd0, ++ [PWRAP_WDT_UNIT] = 0xd4, ++ [PWRAP_WDT_SRC_EN] = 0xd8, ++ [PWRAP_WDT_FLG] = 0xdc, ++ [PWRAP_DEBUG_INT_SEL] = 0xe0, ++ [PWRAP_DVFS_ADR0] = 0xe4, ++ [PWRAP_DVFS_WDATA0] = 0xe8, ++ [PWRAP_DVFS_ADR1] = 0xec, ++ [PWRAP_DVFS_WDATA1] = 0xf0, ++ [PWRAP_DVFS_ADR2] = 0xf4, ++ [PWRAP_DVFS_WDATA2] = 0xf8, ++ [PWRAP_DVFS_ADR3] = 0xfc, ++ [PWRAP_DVFS_WDATA3] = 0x100, ++ [PWRAP_DVFS_ADR4] = 0x104, ++ [PWRAP_DVFS_WDATA4] = 0x108, ++ [PWRAP_DVFS_ADR5] = 0x10c, ++ [PWRAP_DVFS_WDATA5] = 0x110, ++ [PWRAP_DVFS_ADR6] = 0x114, ++ [PWRAP_DVFS_WDATA6] = 0x118, ++ [PWRAP_DVFS_ADR7] = 0x11c, ++ [PWRAP_DVFS_WDATA7] = 0x120, ++ [PWRAP_CIPHER_KEY_SEL] = 0x124, ++ [PWRAP_TOP_CKCON1] = 0x126, ++ [PWRAP_CIPHER_IV_SEL] = 0x128, ++ [PWRAP_TOP_CKCON1_CLR] = 0x12a, ++ [PWRAP_CIPHER_EN] = 0x12c, ++ [PWRAP_CIPHER_RDY] = 0x130, ++ [PWRAP_CIPHER_MODE] = 0x134, ++ [PWRAP_CIPHER_SWRST] = 0x138, ++ [PWRAP_DCM_EN] = 0x13c, ++ [PWRAP_DCM_DBC_PRD] = 0x140, ++ [PWRAP_ADC_CMD_ADDR] = 0x144, ++ [PWRAP_ADC_CMD] = 0x148, ++ [PWRAP_ADC_RDY_ADDR] = 0x14C, ++ [PWRAP_ADC_RDATA_ADDR1] = 0x150, ++ [PWRAP_ADC_RDATA_ADDR2] = 0x154, + }; + + static int mt8173_regs[] = { +@@ -341,24 +521,39 @@ static int mt8135_regs[] = { + }; + + enum pwrap_type { ++ PWRAP_MT7623, + PWRAP_MT8135, + PWRAP_MT8173, + }; + + struct pmic_wrapper_type { + int *regs; ++ int *dew_regs; ++ u32 dew_base; + enum pwrap_type type; + u32 arb_en_all; + }; + ++static struct pmic_wrapper_type pwrap_mt7623 = { ++ .regs = mt7623_regs, ++ .dew_regs = mt7623_dew_regs, ++ .dew_base = 0x0, ++ .type = PWRAP_MT7623, ++ .arb_en_all = 0x3f, ++}; ++ + static struct pmic_wrapper_type pwrap_mt8135 = { + .regs = mt8135_regs, ++ .dew_regs = mt8135_dew_regs, ++ .dew_base = 0xbc00, + .type = PWRAP_MT8135, + .arb_en_all = 0x1ff, + }; + + static struct pmic_wrapper_type pwrap_mt8173 = { + .regs = mt8173_regs, ++ .dew_regs = mt8173_dew_regs, ++ .dew_base = 0xbc00, + .type = PWRAP_MT8173, + .arb_en_all = 0x3f, + }; +@@ -368,6 +563,8 @@ struct pmic_wrapper { + void __iomem *base; + struct regmap *regmap; + int *regs; ++ int *dew_regs; ++ u32 dew_base; + enum pwrap_type type; + u32 arb_en_all; + struct clk *clk_spi; +@@ -378,6 +575,11 @@ struct pmic_wrapper { + void __iomem *bridge_base; + }; + ++static inline int pwrap_is_mt7623(struct pmic_wrapper *wrp) ++{ ++ return wrp->type == PWRAP_MT7623; ++} ++ + static inline int pwrap_is_mt8135(struct pmic_wrapper *wrp) + { + return wrp->type == PWRAP_MT8135; +@@ -475,6 +677,16 @@ static int pwrap_read(struct pmic_wrapper *wrp, u32 adr, u32 *rdata) + return 0; + } + ++static int pwrap_dew_write(struct pmic_wrapper *wrp, enum pwrap_dew_regs reg, u32 wdata) ++{ ++ return pwrap_write(wrp, wrp->dew_base + wrp->dew_regs[reg], wdata); ++} ++ ++static int pwrap_dew_read(struct pmic_wrapper *wrp, enum pwrap_dew_regs reg, u32 *rdata) ++{ ++ return pwrap_read(wrp, wrp->dew_base + wrp->dew_regs[reg], rdata); ++} ++ + static int pwrap_regmap_read(void *context, u32 adr, u32 *rdata) + { + return pwrap_read(context, adr, rdata); +@@ -535,7 +747,7 @@ static int pwrap_init_sidly(struct pmic_wrapper *wrp) + + for (i = 0; i < 4; i++) { + pwrap_writel(wrp, i, PWRAP_SIDLY); +- pwrap_read(wrp, PWRAP_DEW_READ_TEST, &rdata); ++ pwrap_dew_read(wrp, PWRAP_DEW_READ_TEST, &rdata); + if (rdata == PWRAP_DEW_READ_TEST_VAL) { + dev_dbg(wrp->dev, "[Read Test] pass, SIDLY=%x\n", i); + pass |= 1 << i; +@@ -561,6 +773,14 @@ static int pwrap_init_reg_clock(struct pmic_wrapper *wrp) + pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_READ); + pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_START); + pwrap_writel(wrp, 0x0, PWRAP_CSLEXT_END); ++ } else if (pwrap_is_mt7623(wrp)) { ++ pwrap_writel(wrp, 0x3, PWRAP_TOP_CKCON1_CLR); ++ pwrap_dew_write(wrp, 0x8, PWRAP_DEW_RDDMY_NO); ++ pwrap_writel(wrp, 0x8, PWRAP_RDDMY); ++ pwrap_writel(wrp, 0x5, PWRAP_CSHEXT_WRITE); ++ pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_READ); ++ pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_START); ++ pwrap_writel(wrp, 0x2, PWRAP_CSLEXT_END); + } else { + pwrap_writel(wrp, 0x0, PWRAP_CSHEXT_WRITE); + pwrap_writel(wrp, 0x4, PWRAP_CSHEXT_READ); +@@ -581,7 +801,7 @@ static bool pwrap_is_pmic_cipher_ready(struct pmic_wrapper *wrp) + u32 rdata; + int ret; + +- ret = pwrap_read(wrp, PWRAP_DEW_CIPHER_RDY, &rdata); ++ ret = pwrap_dew_read(wrp, PWRAP_DEW_CIPHER_RDY, &rdata); + if (ret) + return 0; + +@@ -606,12 +826,16 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp) + } + + /* Config cipher mode @PMIC */ +- pwrap_write(wrp, PWRAP_DEW_CIPHER_SWRST, 0x1); +- pwrap_write(wrp, PWRAP_DEW_CIPHER_SWRST, 0x0); +- pwrap_write(wrp, PWRAP_DEW_CIPHER_KEY_SEL, 0x1); +- pwrap_write(wrp, PWRAP_DEW_CIPHER_IV_SEL, 0x2); +- pwrap_write(wrp, PWRAP_DEW_CIPHER_LOAD, 0x1); +- pwrap_write(wrp, PWRAP_DEW_CIPHER_START, 0x1); ++ pwrap_dew_write(wrp, PWRAP_DEW_CIPHER_SWRST, 0x1); ++ pwrap_dew_write(wrp, PWRAP_DEW_CIPHER_SWRST, 0x0); ++ pwrap_dew_write(wrp, PWRAP_DEW_CIPHER_KEY_SEL, 0x1); ++ pwrap_dew_write(wrp, PWRAP_DEW_CIPHER_IV_SEL, 0x2); ++ if (pwrap_is_mt7623(wrp)) { ++ pwrap_dew_write(wrp, PWRAP_DEW_CIPHER_EN, 0x1); ++ } else { ++ pwrap_dew_write(wrp, PWRAP_DEW_CIPHER_LOAD, 0x1); ++ pwrap_dew_write(wrp, PWRAP_DEW_CIPHER_START, 0x1); ++ } + + /* wait for cipher data ready@AP */ + ret = pwrap_wait_for_state(wrp, pwrap_is_cipher_ready); +@@ -628,7 +852,7 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp) + } + + /* wait for cipher mode idle */ +- pwrap_write(wrp, PWRAP_DEW_CIPHER_MODE, 0x1); ++ pwrap_dew_write(wrp, PWRAP_DEW_CIPHER_MODE, 0x1); + ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle_and_sync_idle); + if (ret) { + dev_err(wrp->dev, "cipher mode idle fail, ret=%d\n", ret); +@@ -638,8 +862,8 @@ static int pwrap_init_cipher(struct pmic_wrapper *wrp) + pwrap_writel(wrp, 1, PWRAP_CIPHER_MODE); + + /* Write Test */ +- if (pwrap_write(wrp, PWRAP_DEW_WRITE_TEST, PWRAP_DEW_WRITE_TEST_VAL) || +- pwrap_read(wrp, PWRAP_DEW_WRITE_TEST, &rdata) || ++ if (pwrap_dew_write(wrp, PWRAP_DEW_WRITE_TEST, PWRAP_DEW_WRITE_TEST_VAL) || ++ pwrap_dew_read(wrp, PWRAP_DEW_WRITE_TEST, &rdata) || + (rdata != PWRAP_DEW_WRITE_TEST_VAL)) { + dev_err(wrp->dev, "rdata=0x%04X\n", rdata); + return -EFAULT; +@@ -657,12 +881,17 @@ static int pwrap_init(struct pmic_wrapper *wrp) + if (wrp->rstc_bridge) + reset_control_reset(wrp->rstc_bridge); + +- if (pwrap_is_mt8173(wrp)) { ++ if (pwrap_is_mt7623(wrp) || pwrap_is_mt8173(wrp)) { + /* Enable DCM */ + pwrap_writel(wrp, 3, PWRAP_DCM_EN); + pwrap_writel(wrp, 0, PWRAP_DCM_DBC_PRD); + } + ++ if (pwrap_is_mt7623(wrp)) { ++ pwrap_writel(wrp, 0, PWRAP_OP_TYPE); ++ pwrap_writel(wrp, 1, PWRAP_MSB_FIRST); ++ } ++ + /* Reset SPI slave */ + ret = pwrap_reset_spislave(wrp); + if (ret) +@@ -674,6 +903,9 @@ static int pwrap_init(struct pmic_wrapper *wrp) + + pwrap_writel(wrp, 1, PWRAP_WACS2_EN); + ++ if (pwrap_is_mt7623(wrp)) ++ pwrap_writel(wrp, 0xf, PWRAP_RDDMY); ++ + ret = pwrap_init_reg_clock(wrp); + if (ret) + return ret; +@@ -684,7 +916,7 @@ static int pwrap_init(struct pmic_wrapper *wrp) + return ret; + + /* Enable dual IO mode */ +- pwrap_write(wrp, PWRAP_DEW_DIO_EN, 1); ++ pwrap_dew_write(wrp, PWRAP_DEW_DIO_EN, 1); + + /* Check IDLE & INIT_DONE in advance */ + ret = pwrap_wait_for_state(wrp, pwrap_is_fsm_idle_and_sync_idle); +@@ -696,7 +928,7 @@ static int pwrap_init(struct pmic_wrapper *wrp) + pwrap_writel(wrp, 1, PWRAP_DIO_EN); + + /* Read Test */ +- pwrap_read(wrp, PWRAP_DEW_READ_TEST, &rdata); ++ pwrap_dew_read(wrp, PWRAP_DEW_READ_TEST, &rdata); + if (rdata != PWRAP_DEW_READ_TEST_VAL) { + dev_err(wrp->dev, "Read test failed after switch to DIO mode: 0x%04x != 0x%04x\n", + PWRAP_DEW_READ_TEST_VAL, rdata); +@@ -709,12 +941,13 @@ static int pwrap_init(struct pmic_wrapper *wrp) + return ret; + + /* Signature checking - using CRC */ +- if (pwrap_write(wrp, PWRAP_DEW_CRC_EN, 0x1)) ++ if (pwrap_dew_write(wrp, PWRAP_DEW_CRC_EN, 0x1)) + return -EFAULT; + + pwrap_writel(wrp, 0x1, PWRAP_CRC_EN); + pwrap_writel(wrp, 0x0, PWRAP_SIG_MODE); +- pwrap_writel(wrp, PWRAP_DEW_CRC_VAL, PWRAP_SIG_ADR); ++ pwrap_writel(wrp, wrp->dew_base + wrp->dew_regs[PWRAP_DEW_CRC_VAL], ++ PWRAP_SIG_ADR); + pwrap_writel(wrp, wrp->arb_en_all, PWRAP_HIPRIO_ARB_EN); + + if (pwrap_is_mt8135(wrp)) +@@ -728,7 +961,16 @@ static int pwrap_init(struct pmic_wrapper *wrp) + pwrap_writel(wrp, 0xf, PWRAP_WDT_UNIT); + pwrap_writel(wrp, 0xffffffff, PWRAP_WDT_SRC_EN); + pwrap_writel(wrp, 0x1, PWRAP_TIMER_EN); +- pwrap_writel(wrp, ~((1 << 31) | (1 << 1)), PWRAP_INT_EN); ++// pwrap_writel(wrp, ~((1 << 31) | (1 << 1)), PWRAP_INT_EN); ++ pwrap_writel(wrp, ~(BIT(31) | BIT(2)), PWRAP_INT_EN); ++ ++ if (pwrap_is_mt7623(wrp)) { ++ pwrap_writel(wrp, PWRAP_MT7623_AUXADC_CON21, PWRAP_ADC_CMD_ADDR); ++ pwrap_writel(wrp, 0x8000, PWRAP_ADC_CMD); ++ pwrap_writel(wrp, PWRAP_MT7623_AUXADC_ADC12, PWRAP_ADC_RDY_ADDR); ++ pwrap_writel(wrp, PWRAP_MT7623_AUXADC_ADC13, PWRAP_ADC_RDATA_ADDR1); ++ pwrap_writel(wrp, PWRAP_MT7623_AUXADC_ADC14, PWRAP_ADC_RDATA_ADDR2); ++ } + + if (pwrap_is_mt8135(wrp)) { + /* enable pwrap events and pwrap bridge in AP side */ +@@ -743,15 +985,15 @@ static int pwrap_init(struct pmic_wrapper *wrp) + writel(0x7ff, wrp->bridge_base + PWRAP_MT8135_BRIDGE_INT_EN); + + /* enable PMIC event out and sources */ +- if (pwrap_write(wrp, PWRAP_DEW_EVENT_OUT_EN, 0x1) || +- pwrap_write(wrp, PWRAP_DEW_EVENT_SRC_EN, 0xffff)) { ++ if (pwrap_dew_write(wrp, PWRAP_DEW_EVENT_OUT_EN, 0x1) || ++ pwrap_dew_write(wrp, PWRAP_DEW_EVENT_SRC_EN, 0xffff)) { + dev_err(wrp->dev, "enable dewrap fail\n"); + return -EFAULT; + } +- } else { ++ } else if (!pwrap_is_mt7623(wrp)) { + /* PMIC_DEWRAP enables */ +- if (pwrap_write(wrp, PWRAP_DEW_EVENT_OUT_EN, 0x1) || +- pwrap_write(wrp, PWRAP_DEW_EVENT_SRC_EN, 0xffff)) { ++ if (pwrap_dew_write(wrp, PWRAP_DEW_EVENT_OUT_EN, 0x1) || ++ pwrap_dew_write(wrp, PWRAP_DEW_EVENT_SRC_EN, 0xffff)) { + dev_err(wrp->dev, "enable dewrap fail\n"); + return -EFAULT; + } +@@ -795,6 +1037,9 @@ static const struct regmap_config pwrap_regmap_config = { + + static struct of_device_id of_pwrap_match_tbl[] = { + { ++ .compatible = "mediatek,mt7623-pwrap", ++ .data = &pwrap_mt7623, ++ }, { + .compatible = "mediatek,mt8135-pwrap", + .data = &pwrap_mt8135, + }, { +@@ -824,6 +1069,8 @@ static int pwrap_probe(struct platform_device *pdev) + + type = of_id->data; + wrp->regs = type->regs; ++ wrp->dew_regs = type->dew_regs; ++ wrp->dew_base = type->dew_base; + wrp->type = type->type; + wrp->arb_en_all = type->arb_en_all; + wrp->dev = &pdev->dev; +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0070-clk-mediatek-Export-CPU-mux-clocks-for-CPU-frequency.patch b/target/linux/mediatek/patches/0070-clk-mediatek-Export-CPU-mux-clocks-for-CPU-frequency.patch new file mode 100644 index 0000000000..87de0f9436 --- /dev/null +++ b/target/linux/mediatek/patches/0070-clk-mediatek-Export-CPU-mux-clocks-for-CPU-frequency.patch @@ -0,0 +1,199 @@ +From ac825c0dd7370ae1b9a1a4346f895728e09d9cc7 Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Wed, 1 Jul 2015 07:58:44 +0200 +Subject: [PATCH 70/76] clk: mediatek: Export CPU mux clocks for CPU frequency + control + +This patch adds CPU mux clocks which are used by Mediatek cpufreq driver +for intermediate clock source switching. + +Changes in v3: +- Rebase to 4.2-rc1 +- Fix some issues of v2 + +Changes in v2: +- Remove use of .determine_rate callback + +Signed-off-by: Pi-Cheng Chen <pi-cheng.chen@linaro.org> +--- + drivers/clk/mediatek/Makefile | 2 +- + drivers/clk/mediatek/clk-cpumux.c | 119 +++++++++++++++++++++++++++++++++++++ + drivers/clk/mediatek/clk-cpumux.h | 30 ++++++++++ + 3 files changed, 150 insertions(+), 1 deletion(-) + create mode 100644 drivers/clk/mediatek/clk-cpumux.c + create mode 100644 drivers/clk/mediatek/clk-cpumux.h + +diff --git a/drivers/clk/mediatek/Makefile b/drivers/clk/mediatek/Makefile +index 19a3763..fe07e26 100644 +--- a/drivers/clk/mediatek/Makefile ++++ b/drivers/clk/mediatek/Makefile +@@ -1,4 +1,4 @@ +-obj-y += clk-mtk.o clk-pll.o clk-gate.o ++obj-y += clk-mtk.o clk-pll.o clk-gate.o clk-cpumux.o + obj-$(CONFIG_RESET_CONTROLLER) += reset.o + obj-y += clk-mt7623.o + obj-y += clk-mt8135.o +diff --git a/drivers/clk/mediatek/clk-cpumux.c b/drivers/clk/mediatek/clk-cpumux.c +new file mode 100644 +index 0000000..593df45 +--- /dev/null ++++ b/drivers/clk/mediatek/clk-cpumux.c +@@ -0,0 +1,119 @@ ++/* ++ * Copyright (c) 2015 Linaro Ltd. ++ * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include <linux/clk-provider.h> ++#include <linux/mfd/syscon.h> ++#include <linux/slab.h> ++ ++#include "clk-mtk.h" ++#include "clk-cpumux.h" ++ ++static inline struct mtk_clk_cpumux *to_clk_mux(struct clk_hw *_hw) ++{ ++ return container_of(_hw, struct mtk_clk_cpumux, hw); ++} ++ ++static u8 clk_cpumux_get_parent(struct clk_hw *hw) ++{ ++ struct mtk_clk_cpumux *mux = to_clk_mux(hw); ++ int num_parents = __clk_get_num_parents(hw->clk); ++ unsigned int val; ++ ++ regmap_read(mux->regmap, mux->reg, &val); ++ ++ val >>= mux->shift; ++ val &= mux->mask; ++ ++ if (val >= num_parents) ++ return -EINVAL; ++ ++ return val; ++} ++ ++static int clk_cpumux_set_parent(struct clk_hw *hw, u8 index) ++{ ++ struct mtk_clk_cpumux *mux = to_clk_mux(hw); ++ u32 mask, val; ++ ++ val = index << mux->shift; ++ mask = mux->mask << mux->shift; ++ ++ return regmap_update_bits(mux->regmap, mux->reg, mask, val); ++} ++ ++static const struct clk_ops clk_cpumux_ops = { ++ .get_parent = clk_cpumux_get_parent, ++ .set_parent = clk_cpumux_set_parent, ++}; ++ ++static struct clk *mtk_clk_register_cpumux(const struct mtk_composite *mux, ++ struct regmap *regmap) ++{ ++ struct mtk_clk_cpumux *cpumux; ++ struct clk *clk; ++ struct clk_init_data init; ++ ++ cpumux = kzalloc(sizeof(*cpumux), GFP_KERNEL); ++ if (!cpumux) ++ return ERR_PTR(-ENOMEM); ++ ++ init.name = mux->name; ++ init.ops = &clk_cpumux_ops; ++ init.parent_names = mux->parent_names; ++ init.num_parents = mux->num_parents; ++ init.flags = mux->flags; ++ ++ cpumux->reg = mux->mux_reg; ++ cpumux->shift = mux->mux_shift; ++ cpumux->mask = BIT(mux->mux_width) - 1; ++ cpumux->regmap = regmap; ++ cpumux->hw.init = &init; ++ ++ clk = clk_register(NULL, &cpumux->hw); ++ if (IS_ERR(clk)) ++ kfree(cpumux); ++ ++ return clk; ++} ++ ++int mtk_clk_register_cpumuxes(struct device_node *node, ++ const struct mtk_composite *clks, int num, ++ struct clk_onecell_data *clk_data) ++{ ++ int i; ++ struct clk *clk; ++ struct regmap *regmap; ++ ++ regmap = syscon_node_to_regmap(node); ++ if (IS_ERR(regmap)) { ++ pr_err("Cannot find regmap for %s: %d\n", node->full_name, ++ PTR_ERR(regmap)); ++ return PTR_ERR(regmap); ++ } ++ ++ for (i = 0; i < num; i++) { ++ const struct mtk_composite *mux = &clks[i]; ++ ++ clk = mtk_clk_register_cpumux(mux, regmap); ++ if (IS_ERR(clk)) { ++ pr_err("Failed to register clk %s: %ld\n", ++ mux->name, PTR_ERR(clk)); ++ continue; ++ } ++ ++ clk_data->clks[mux->id] = clk; ++ } ++ ++ return 0; ++} +diff --git a/drivers/clk/mediatek/clk-cpumux.h b/drivers/clk/mediatek/clk-cpumux.h +new file mode 100644 +index 0000000..dddaad5 +--- /dev/null ++++ b/drivers/clk/mediatek/clk-cpumux.h +@@ -0,0 +1,30 @@ ++/* ++ * Copyright (c) 2015 Linaro Ltd. ++ * Author: Pi-Cheng Chen <pi-cheng.chen@linaro.org> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __DRV_CLK_CPUMUX_H ++#define __DRV_CLK_CPUMUX_H ++ ++struct mtk_clk_cpumux { ++ struct clk_hw hw; ++ struct regmap *regmap; ++ u32 reg; ++ u32 mask; ++ u8 shift; ++}; ++ ++int mtk_clk_register_cpumuxes(struct device_node *node, ++ const struct mtk_composite *clks, int num, ++ struct clk_onecell_data *clk_data); ++ ++#endif /* __DRV_CLK_CPUMUX_H */ +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0071-clk.patch b/target/linux/mediatek/patches/0071-clk.patch new file mode 100644 index 0000000000..f920dcee43 --- /dev/null +++ b/target/linux/mediatek/patches/0071-clk.patch @@ -0,0 +1,342 @@ +From c3a3617a8c37b43db7ff622a31f171d3ce870173 Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Fri, 3 Jul 2015 05:44:57 +0200 +Subject: [PATCH 71/76] clk + +--- + drivers/clk/mediatek/clk-mt7623.c | 194 ++++++++++++++++--------------------- + 1 file changed, 83 insertions(+), 111 deletions(-) + +diff --git a/drivers/clk/mediatek/clk-mt7623.c b/drivers/clk/mediatek/clk-mt7623.c +index 07843bb..d46b2ad 100644 +--- a/drivers/clk/mediatek/clk-mt7623.c ++++ b/drivers/clk/mediatek/clk-mt7623.c +@@ -20,6 +20,7 @@ + + #include "clk-mtk.h" + #include "clk-gate.h" ++#include "clk-cpumux.h" + + static DEFINE_SPINLOCK(mt7623_clk_lock); + +@@ -37,18 +38,11 @@ static void mtk_clk_enable_critical(void) + clk_prepare_enable(mt7623_top_clk_data->clks[CLK_TOP_RTC_SEL]); + } + +-static const struct mtk_fixed_factor root_clk_alias[] __initconst = { +- FACTOR(CLK_TOP_DSI0_LNTC_DSICLK, "dsi0_lntc_dsiclk", "clk_null", 1, 1), +- FACTOR(CLK_TOP_HDMITX_CLKDIG_CTS, "hdmitx_clkdig_cts", "clk_null", 1, 1), +- FACTOR(CLK_TOP_CLKPH_MCK, "clkph_mck", "clk_null", 1, 1), +- FACTOR(CLK_TOP_CPUM_TCK_IN, "cpum_tck_in", "clk_null", 1, 1), +-}; +- + static const struct mtk_fixed_factor top_divs[] __initconst = { +- FACTOR(CLK_TOP_MAINPLL_806M, "mainpll_650m", "mainpll", 1, 2), +- FACTOR(CLK_TOP_MAINPLL_537P3M, "mainpll_433p3m", "mainpll", 1, 3), +- FACTOR(CLK_TOP_MAINPLL_322P4M, "mainpll_260m", "mainpll", 1, 5), +- FACTOR(CLK_TOP_MAINPLL_230P3M, "mainpll_185p6m", "mainpll", 1, 7), ++ FACTOR(CLK_TOP_MAINPLL_650M, "mainpll_650m", "mainpll", 1, 2), ++ FACTOR(CLK_TOP_MAINPLL_433P3M, "mainpll_433p3m", "mainpll", 1, 3), ++ FACTOR(CLK_TOP_MAINPLL_260M, "mainpll_260m", "mainpll", 1, 5), ++ FACTOR(CLK_TOP_MAINPLL_185P6M, "mainpll_185p6m", "mainpll", 1, 7), + + FACTOR(CLK_TOP_UNIVPLL_624M, "univpll_624m", "univpll", 1, 2), + FACTOR(CLK_TOP_UNIVPLL_416M, "univpll_416m", "univpll", 1, 3), +@@ -61,13 +55,6 @@ static const struct mtk_fixed_factor top_divs[] __initconst = { + FACTOR(CLK_TOP_AUDPLL_D16, "audpll_d16", "audpll", 1, 16), + FACTOR(CLK_TOP_AUDPLL_24, "audpll_d24", "audpll", 1, 24), + +- FACTOR(CLK_TOP_LVDSPLL_D2, "lvdspll_d2", "lvdspll", 1, 2), +- FACTOR(CLK_TOP_LVDSPLL_D4, "lvdspll_d4", "lvdspll", 1, 4), +- FACTOR(CLK_TOP_LVDSPLL_D8, "lvdspll_d8", "lvdspll", 1, 8), +- FACTOR(CLK_TOP_LVDS_ETH, "lvdspll_eth", "lvdspll", 1, 16), +- +- FACTOR(CLK_TOP_MMPLL_D2, "mmpll_d2", "mmpll", 1, 2), +- + FACTOR(CLK_TOP_MSDCPLL_D2, "msdcpll_d2", "msdcpll", 1, 2), + + FACTOR(CLK_TOP_SYSPLL1_D2, "syspll1_d2", "mainpll_650m", 1, 2), +@@ -85,9 +72,6 @@ static const struct mtk_fixed_factor top_divs[] __initconst = { + FACTOR(CLK_TOP_SYSPLL_D5, "syspll_d5", "mainpll_260m", 1, 1), + FACTOR(CLK_TOP_SYSPLL_D7, "syspll_d7", "mainpll_185p6m", 1, 1), + +- FACTOR(CLK_TOP_TVDPLL_d2, "tvdpll_d2", "tvdpll", 1, 2), +- FACTOR(CLK_TOP_TVDPLL_D4, "tvdpll_d4", "tvdpll", 1, 4), +- + FACTOR(CLK_TOP_UNIVPLL1_D2, "univpll1_d2", "univpll_624m", 1, 2), + FACTOR(CLK_TOP_UNIVPLL1_D4, "univpll1_d4", "univpll_624m", 1, 4), + FACTOR(CLK_TOP_UNIVPLL1_D8, "univpll1_d8", "univpll_624m", 1, 8), +@@ -110,9 +94,6 @@ static const struct mtk_fixed_factor top_divs[] __initconst = { + + FACTOR(CLK_TOP_UNIVPLL_D5, "univpll_d5", "univpll_249p6m", 1, 1), + FACTOR(CLK_TOP_UNIVPLL_D26, "univpll_d26", "univpll_48m", 1, 1), +- +- +- FACTOR(CLK_TOP_MEMPLL_MCK_D4, "mempll_mck_d4", "clkph_mck", 1, 4), + }; + + static const char * const axi_parents[] __initconst = { +@@ -155,18 +136,6 @@ static const char * const pwm_parents[] __initconst = { + "univpll1_d4", + }; + +-static const char * const vdec_parents[] __initconst = { +- "clk26m", +- "syspll1_d2", +- "syspll_d5", +- "syspll1_d4", +- "univpll_d5", +- "univpll2_d2", +- "univpll2_d4", +- "msdcpll_d2", +- "mmpll_d2", +-}; +- + static const char * const mfg_parents[] __initconst = { + "clk26m", + "mmpll_ck", +@@ -178,17 +147,6 @@ static const char * const mfg_parents[] __initconst = { + "univpll1_d2", + }; + +-static const char * const cam_parents[] __initconst = { +- "clk26m", +- "univpll_d26", +- "univpll2_d2", +- "syspll3_d2", +- "syspll3_d4", +- "msdcpll_d2", +- "mmpll_d2", +- "clk26m", +-}; +- + static const char * const uart_parents[] __initconst = { + "clk26m", + "univpll2_d8", +@@ -277,35 +235,6 @@ static const char * const scp_parents[] __initconst = { + "dmpll_d4", + }; + +-static const char * const dpi0_parents[] __initconst = { +- "clk26m", +- "mipipll", +- "mipipll_d2", +- "mipipll_d4", +- "lvdspll", +- "lvdspll_d2", +- "lvdspll_d4", +- "lvdspll_d8", +-}; +- +-static const char * const dpi1_parents[] __initconst = { +- "clk26m", +- "tvdpll", +- "tvdpll_d2", +- "tvdpll_d4", +-}; +- +-static const char * const tve_parents[] __initconst = { +- "clk26m", +- "mipipll", +- "mipipll_d2", +- "mipipll_d4", +- "clk26m", +- "tvdpll", +- "tvdpll_d2", +- "tvdpll_d4", +-}; +- + static const char * const apll_parents[] __initconst = { + "clk26m", + "audpll", +@@ -317,17 +246,6 @@ static const char * const apll_parents[] __initconst = { + "clk26m", + }; + +-static const char * const dpilvds_parents[] __initconst = { +- "clk26m", +- "lvdspll", +- "lvdspll_d2", +- "lvdspll_d4", +- "lvdspll_d8", +- "fpc_ck", +- "clk26m", +- "clk26m", +-}; +- + static const char * const rtc_parents[] __initconst = { + "clk32k", + "external_32k", +@@ -367,9 +285,7 @@ static const struct mtk_composite top_muxes[] __initconst = { + 0x0140, 24, 3, INVALID_MUX_GATE_BIT), + /* CLK_CFG_1 */ + MUX_GATE(CLK_TOP_PWM_SEL, "pwm_sel", pwm_parents, 0x0050, 0, 2, 7), +- MUX_GATE(CLK_TOP_VDEC_SEL, "vdec_sel", vdec_parents, 0x0050, 8, 4, 15), + MUX_GATE(CLK_TOP_MFG_SEL, "mfg_sel", mfg_parents, 0x0050, 16, 3, 23), +- MUX_GATE(CLK_TOP_CAM_SEL, "cam_sel", cam_parents, 0x0050, 24, 3, 31), + /* CLK_CFG_2 */ + MUX_GATE(CLK_TOP_UART_SEL, "uart_sel", uart_parents, 0x0060, 0, 1, 7), + MUX_GATE(CLK_TOP_SPI_SEL, "spi_sel", spi_parents, 0x0060, 8, 3, 15), +@@ -384,12 +300,8 @@ static const struct mtk_composite top_muxes[] __initconst = { + /* CLK_CFG_4 */ + MUX_GATE(CLK_TOP_PMICSPI_SEL, "pmicspi_sel", pmic_spi_parents, 0x0080, 0, 4, 7), + MUX_GATE(CLK_TOP_SCP_SEL, "scp_sel", scp_parents, 0x0080, 8, 2, 15), +- MUX_GATE(CLK_TOP_DPI0_SEL, "dpi0_sel", dpi0_parents, 0x0080, 16, 3, 23), +- MUX_GATE(CLK_TOP_DPI1_SEL, "dpi1_sel", dpi1_parents, 0x0080, 24, 2, 31), + /* CLK_CFG_5 */ +- MUX_GATE(CLK_TOP_TVE_SEL, "tve_sel", tve_parents, 0x0090, 0, 3, 7), + MUX_GATE(CLK_TOP_APLL_SEL, "apll_sel", apll_parents, 0x0090, 16, 3, 23), +- MUX_GATE(CLK_TOP_DPILVDS_SEL, "dpilvds_sel", dpilvds_parents, 0x0090, 24, 3, 31), + /* CLK_CFG_6 */ + MUX_GATE(CLK_TOP_RTC_SEL, "rtc_sel", rtc_parents, 0x00a0, 0, 2, 7), + MUX_GATE(CLK_TOP_NFI2X_SEL, "nfi2x_sel", nfi2x_parents, 0x00a0, 8, 3, 15), +@@ -428,6 +340,17 @@ static const struct mtk_gate infra_clks[] __initconst = { + GATE_ICG(CLK_INFRA_PMIC_WRAP, "pmic_wrap_ck", "axi_sel", 23), + }; + ++static const char * const ca7_parents[] __initconst = { ++ "clk26m", ++ "armpll", ++ "mainpll", ++ "univpll" ++}; ++ ++static struct mtk_composite cpu_muxes[] __initdata = { ++ MUX(CLK_INFRA_CA7SEL, "infra_ca7_sel", ca7_parents, 0x0000, 2, 2), ++}; ++ + static const struct mtk_gate_regs peri0_cg_regs = { + .set_ofs = 0x0008, + .clr_ofs = 0x0010, +@@ -499,6 +422,29 @@ static const struct mtk_gate peri_gates[] __initconst = { + GATE_PERI1(CLK_PERI_NFI_PAD, "nfi_pad_ck", "axi_sel", 2), + }; + ++static const struct mtk_gate_regs hifsys_cg_regs = { ++ .set_ofs = 0x0034, ++ .clr_ofs = 0x0014, ++ .sta_ofs = 0x0038, ++}; ++ ++#define GATE_HIFSYS(_id, _name, _parent, _shift) { \ ++ .id = _id, \ ++ .name = _name, \ ++ .parent_name = _parent, \ ++ .regs = &hifsys_cg_regs, \ ++ .shift = _shift, \ ++ .ops = &mtk_clk_gate_ops_setclr, \ ++ } ++ ++static const struct mtk_gate hifsys_gates[] __initconst = { ++ GATE_HIFSYS(CLK_HIFSYS_USB0_PHY, "usb0_phy_ck", "axi_sel", 21), ++ GATE_HIFSYS(CLK_HIFSYS_USB1_PHY, "usb1_phy_ck", "axi_sel", 22), ++ GATE_HIFSYS(CLK_HIFSYS_PCIE0, "pcie0_ck", "axi_sel", 24), ++ GATE_HIFSYS(CLK_HIFSYS_PCIE1, "pcie1_ck", "axi_sel", 25), ++ GATE_HIFSYS(CLK_HIFSYS_PCIE2, "pcie2_ck", "axi_sel", 26), ++}; ++ + static const char * const uart_ck_sel_parents[] __initconst = { + "clk26m", + "uart_sel", +@@ -525,10 +471,9 @@ static void __init mtk_topckgen_init(struct device_node *node) + + mt7623_top_clk_data = clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK); + +- mtk_clk_register_factors(root_clk_alias, ARRAY_SIZE(root_clk_alias), clk_data); + mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data); + mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base, +- &mt7623_clk_lock, clk_data); ++ &mt7623_clk_lock, clk_data); + + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); + if (r) +@@ -547,7 +492,10 @@ static void __init mtk_infrasys_init(struct device_node *node) + clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK); + + mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks), +- clk_data); ++ clk_data); ++ ++ mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes), ++ clk_data); + + clk_prepare_enable(clk_data->clks[CLK_INFRA_M4U]); + +@@ -588,35 +536,59 @@ static void __init mtk_pericfg_init(struct device_node *node) + } + CLK_OF_DECLARE(mtk_pericfg, "mediatek,mt7623-pericfg", mtk_pericfg_init); + +-#define MT7623_PLL_FMAX (2000 * MHZ) +-#define CON0_MT7623_RST_BAR BIT(27) ++static void __init mtk_hifsys_init(struct device_node *node) ++{ ++ struct clk_onecell_data *clk_data; ++ int r; ++ void __iomem *base; ++ ++ base = of_iomap(node, 0); ++ if (!base) { ++ pr_err("%s(): ioremap failed\n", __func__); ++ return; ++ } ++ ++ clk_data = mtk_alloc_clk_data(CLK_HIFSYS_NR_CLK); ++ ++ mtk_clk_register_gates(node, hifsys_gates, ARRAY_SIZE(hifsys_gates), ++ clk_data); ++ ++ r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); ++ if (r) ++ pr_err("%s(): could not register clock provider: %d\n", ++ __func__, r); ++ ++ mtk_register_reset_controller(node, 1, 0x34); ++} ++CLK_OF_DECLARE(mtk_hifsys, "mediatek,mt7623-hifsys", mtk_hifsys_init); ++ ++#define MT7623_PLL_FMAX (1300 * MHZ) ++#define CON0_MT7623_RST_BAR BIT(24) + +-#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pd_reg, _pd_shift, _tuner_reg, _pcw_reg, _pcw_shift) { \ ++#define PLL(_id, _name, _con0_reg, _con1_reg, _pwr_reg, _en_mask, _flags, _pcwbits, _pcw_shift, _pd_shift) { \ + .id = _id, \ + .name = _name, \ +- .reg = _reg, \ ++ .reg = _con0_reg, \ + .pwr_reg = _pwr_reg, \ + .en_mask = _en_mask, \ + .flags = _flags, \ + .rst_bar_mask = CON0_MT7623_RST_BAR, \ + .fmax = MT7623_PLL_FMAX, \ + .pcwbits = _pcwbits, \ +- .pd_reg = _pd_reg, \ ++ .pd_reg = _con0_reg, \ + .pd_shift = _pd_shift, \ +- .tuner_reg = _tuner_reg, \ +- .pcw_reg = _pcw_reg, \ ++ .pcw_reg = _con1_reg, \ + .pcw_shift = _pcw_shift, \ + } + + static const struct mtk_pll_data plls[] = { +- PLL(CLK_APMIXED_ARMPLL, "armpll", 0x200, 0x20c, 0x00000001, 0, 21, 0x204, 24, 0x0, 0x204, 0), +- PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x210, 0x21c, 0x78000001, HAVE_RST_BAR, 21, 0x214, 6, 0x0, 0x214, 0), +- PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x220, 0x22c, 0xFC000001, HAVE_RST_BAR, 7, 0x224, 6, 0x0, 0x224, 0), +- PLL(CLK_APMIXED_MMPLL, "mmpll", 0x230, 0x23c, 0x00000001, 0, 21, 0x254, 6, 0x0, 0x258, 0), +- PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x240, 0x24c, 0x00000001, 0, 21, 0x244, 6, 0x0, 0x244, 0), +- PLL(CLK_APMIXED_AUDPLL, "audpll", 0x250, 0x25c, 0x00000001, 0, 31, 0x2e8, 6, 0x2f8, 0x254, 0), +- PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x260, 0x26c, 0x00000001, 0, 31, 0x294, 6, 0x0, 0x298, 0), +- PLL(CLK_APMIXED_LVDSPLL, "lvdspll", 0x270, 0x27c, 0x00000001, 0, 21, 0x2b0, 6, 0x0, 0x2b4, 0), ++ PLL(CLK_APMIXED_ARMPLL, "armpll", 0x200, 0x204, 0x20c, 0x00000001, 0, 21, 0, 4 ), ++ PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x210, 0x214, 0x21c, 0x78000001, HAVE_RST_BAR, 21, 0, 4 ), ++ PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x220, 0x224, 0x22c, 0xFC000001, HAVE_RST_BAR, 7, 14, 4 ), ++ PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x240, 0x244, 0x24c, 0x00000001, 0, 21, 0, 4 ), ++ PLL(CLK_APMIXED_AUDPLL, "audpll", 0x270, 0x274, 0x27c, 0x00000001, 0, 31, 0, 4 ), ++ PLL(CLK_APMIXED_TRGPLL, "trgpll", 0x280, 0x284, 0x28c, 0x00000001, 0, 31, 0, 4 ), ++ PLL(CLK_APMIXED_ETHPLL, "ethpll", 0x290, 0x294, 0x29c, 0x00000001, 0, 31, 0, 4 ), + }; + + static void __init mtk_apmixedsys_init(struct device_node *node) +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0072-mfd.patch b/target/linux/mediatek/patches/0072-mfd.patch new file mode 100644 index 0000000000..cbcadb7de7 --- /dev/null +++ b/target/linux/mediatek/patches/0072-mfd.patch @@ -0,0 +1,1591 @@ +From 1a4dcc30578512d687528adcf963203faee50d83 Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Fri, 3 Jul 2015 05:45:17 +0200 +Subject: [PATCH 72/76] mfd + +--- + drivers/mfd/mt6323-core.c | 168 +++---- + drivers/regulator/mt6323-regulator.c | 218 ++++---- + include/linux/mfd/mt6323/core.h | 76 +-- + include/linux/mfd/mt6323/registers.h | 745 +++++++++++++++------------- + include/linux/regulator/mt6323-regulator.h | 37 ++ + 5 files changed, 636 insertions(+), 608 deletions(-) + create mode 100644 include/linux/regulator/mt6323-regulator.h + +diff --git a/drivers/mfd/mt6323-core.c b/drivers/mfd/mt6323-core.c +index 012c620..9b7f5b9 100644 +--- a/drivers/mfd/mt6323-core.c ++++ b/drivers/mfd/mt6323-core.c +@@ -18,111 +18,99 @@ + #include <linux/of_irq.h> + #include <linux/regmap.h> + #include <linux/mfd/core.h> +-#include <linux/mfd/mt6397/core.h> +-#include <linux/mfd/mt6397/registers.h> ++#include <linux/mfd/mt6323/core.h> ++#include <linux/mfd/mt6323/registers.h> + +-static const struct mfd_cell mt6397_devs[] = { ++static const struct mfd_cell mt6323_devs[] = { + { +- .name = "mt6397-rtc", +- .of_compatible = "mediatek,mt6397-rtc", +- }, { +- .name = "mt6397-regulator", +- .of_compatible = "mediatek,mt6397-regulator", +- }, { +- .name = "mt6397-codec", +- .of_compatible = "mediatek,mt6397-codec", +- }, { +- .name = "mt6397-clk", +- .of_compatible = "mediatek,mt6397-clk", +- }, { +- .name = "mediatek-mt6397-pinctrl", +- .of_compatible = "mediatek,mt6397-pinctrl", ++ .name = "mt6323-regulator", ++ .of_compatible = "mediatek,mt6323-regulator", + }, + }; + +-static void mt6397_irq_lock(struct irq_data *data) ++static void mt6323_irq_lock(struct irq_data *data) + { +- struct mt6397_chip *mt6397 = irq_get_chip_data(data->irq); ++ struct mt6323_chip *mt6323 = irq_get_chip_data(data->irq); + +- mutex_lock(&mt6397->irqlock); ++ mutex_lock(&mt6323->irqlock); + } + +-static void mt6397_irq_sync_unlock(struct irq_data *data) ++static void mt6323_irq_sync_unlock(struct irq_data *data) + { +- struct mt6397_chip *mt6397 = irq_get_chip_data(data->irq); ++ struct mt6323_chip *mt6323 = irq_get_chip_data(data->irq); + +- regmap_write(mt6397->regmap, MT6397_INT_CON0, mt6397->irq_masks_cur[0]); +- regmap_write(mt6397->regmap, MT6397_INT_CON1, mt6397->irq_masks_cur[1]); ++ regmap_write(mt6323->regmap, MT6323_INT_CON0, mt6323->irq_masks_cur[0]); ++ regmap_write(mt6323->regmap, MT6323_INT_CON1, mt6323->irq_masks_cur[1]); + +- mutex_unlock(&mt6397->irqlock); ++ mutex_unlock(&mt6323->irqlock); + } + +-static void mt6397_irq_disable(struct irq_data *data) ++static void mt6323_irq_disable(struct irq_data *data) + { +- struct mt6397_chip *mt6397 = irq_get_chip_data(data->irq); ++ struct mt6323_chip *mt6323 = irq_get_chip_data(data->irq); + int shift = data->hwirq & 0xf; + int reg = data->hwirq >> 4; + +- mt6397->irq_masks_cur[reg] &= ~BIT(shift); ++ mt6323->irq_masks_cur[reg] &= ~BIT(shift); + } + +-static void mt6397_irq_enable(struct irq_data *data) ++static void mt6323_irq_enable(struct irq_data *data) + { +- struct mt6397_chip *mt6397 = irq_get_chip_data(data->irq); ++ struct mt6323_chip *mt6323 = irq_get_chip_data(data->irq); + int shift = data->hwirq & 0xf; + int reg = data->hwirq >> 4; + +- mt6397->irq_masks_cur[reg] |= BIT(shift); ++ mt6323->irq_masks_cur[reg] |= BIT(shift); + } + +-static struct irq_chip mt6397_irq_chip = { +- .name = "mt6397-irq", +- .irq_bus_lock = mt6397_irq_lock, +- .irq_bus_sync_unlock = mt6397_irq_sync_unlock, +- .irq_enable = mt6397_irq_enable, +- .irq_disable = mt6397_irq_disable, ++static struct irq_chip mt6323_irq_chip = { ++ .name = "mt6323-irq", ++ .irq_bus_lock = mt6323_irq_lock, ++ .irq_bus_sync_unlock = mt6323_irq_sync_unlock, ++ .irq_enable = mt6323_irq_enable, ++ .irq_disable = mt6323_irq_disable, + }; + +-static void mt6397_irq_handle_reg(struct mt6397_chip *mt6397, int reg, ++static void mt6323_irq_handle_reg(struct mt6323_chip *mt6323, int reg, + int irqbase) + { + unsigned int status; + int i, irq, ret; + +- ret = regmap_read(mt6397->regmap, reg, &status); ++ ret = regmap_read(mt6323->regmap, reg, &status); + if (ret) { +- dev_err(mt6397->dev, "Failed to read irq status: %d\n", ret); ++ dev_err(mt6323->dev, "Failed to read irq status: %d\n", ret); + return; + } + + for (i = 0; i < 16; i++) { + if (status & BIT(i)) { +- irq = irq_find_mapping(mt6397->irq_domain, irqbase + i); ++ irq = irq_find_mapping(mt6323->irq_domain, irqbase + i); + if (irq) + handle_nested_irq(irq); + } + } + +- regmap_write(mt6397->regmap, reg, status); ++ regmap_write(mt6323->regmap, reg, status); + } + +-static irqreturn_t mt6397_irq_thread(int irq, void *data) ++static irqreturn_t mt6323_irq_thread(int irq, void *data) + { +- struct mt6397_chip *mt6397 = data; ++ struct mt6323_chip *mt6323 = data; + +- mt6397_irq_handle_reg(mt6397, MT6397_INT_STATUS0, 0); +- mt6397_irq_handle_reg(mt6397, MT6397_INT_STATUS1, 16); ++ mt6323_irq_handle_reg(mt6323, MT6323_INT_STATUS0, 0); ++ mt6323_irq_handle_reg(mt6323, MT6323_INT_STATUS1, 16); + + return IRQ_HANDLED; + } + +-static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq, ++static int mt6323_irq_domain_map(struct irq_domain *d, unsigned int irq, + irq_hw_number_t hw) + { +- struct mt6397_chip *mt6397 = d->host_data; ++ struct mt6323_chip *mt6323 = d->host_data; + +- irq_set_chip_data(irq, mt6397); +- irq_set_chip_and_handler(irq, &mt6397_irq_chip, handle_level_irq); ++ irq_set_chip_data(irq, mt6323); ++ irq_set_chip_and_handler(irq, &mt6323_irq_chip, handle_level_irq); + irq_set_nested_thread(irq, 1); + #ifdef CONFIG_ARM + set_irq_flags(irq, IRQF_VALID); +@@ -133,98 +121,98 @@ static int mt6397_irq_domain_map(struct irq_domain *d, unsigned int irq, + return 0; + } + +-static struct irq_domain_ops mt6397_irq_domain_ops = { +- .map = mt6397_irq_domain_map, ++static struct irq_domain_ops mt6323_irq_domain_ops = { ++ .map = mt6323_irq_domain_map, + }; + +-static int mt6397_irq_init(struct mt6397_chip *mt6397) ++static int mt6323_irq_init(struct mt6323_chip *mt6323) + { + int ret; + +- mutex_init(&mt6397->irqlock); ++ mutex_init(&mt6323->irqlock); + + /* Mask all interrupt sources */ +- regmap_write(mt6397->regmap, MT6397_INT_CON0, 0x0); +- regmap_write(mt6397->regmap, MT6397_INT_CON1, 0x0); ++ regmap_write(mt6323->regmap, MT6323_INT_CON0, 0x0); ++ regmap_write(mt6323->regmap, MT6323_INT_CON1, 0x0); + +- mt6397->irq_domain = irq_domain_add_linear(mt6397->dev->of_node, +- MT6397_IRQ_NR, &mt6397_irq_domain_ops, mt6397); +- if (!mt6397->irq_domain) { +- dev_err(mt6397->dev, "could not create irq domain\n"); ++ mt6323->irq_domain = irq_domain_add_linear(mt6323->dev->of_node, ++ MT6323_IRQ_NR, &mt6323_irq_domain_ops, mt6323); ++ if (!mt6323->irq_domain) { ++ dev_err(mt6323->dev, "could not create irq domain\n"); + return -ENOMEM; + } + +- ret = devm_request_threaded_irq(mt6397->dev, mt6397->irq, NULL, +- mt6397_irq_thread, IRQF_ONESHOT, "mt6397-pmic", mt6397); ++ ret = devm_request_threaded_irq(mt6323->dev, mt6323->irq, NULL, ++ mt6323_irq_thread, IRQF_ONESHOT, "mt6323-pmic", mt6323); + if (ret) { +- dev_err(mt6397->dev, "failed to register irq=%d; err: %d\n", +- mt6397->irq, ret); ++ dev_err(mt6323->dev, "failed to register irq=%d; err: %d\n", ++ mt6323->irq, ret); + return ret; + } + + return 0; + } + +-static int mt6397_probe(struct platform_device *pdev) ++static int mt6323_probe(struct platform_device *pdev) + { + int ret; +- struct mt6397_chip *mt6397; ++ struct mt6323_chip *mt6323; + +- mt6397 = devm_kzalloc(&pdev->dev, sizeof(*mt6397), GFP_KERNEL); +- if (!mt6397) ++ mt6323 = devm_kzalloc(&pdev->dev, sizeof(*mt6323), GFP_KERNEL); ++ if (!mt6323) + return -ENOMEM; + +- mt6397->dev = &pdev->dev; ++ mt6323->dev = &pdev->dev; + /* +- * mt6397 MFD is child device of soc pmic wrapper. ++ * mt6323 MFD is child device of soc pmic wrapper. + * Regmap is set from its parent. + */ +- mt6397->regmap = dev_get_regmap(pdev->dev.parent, NULL); +- if (!mt6397->regmap) ++ mt6323->regmap = dev_get_regmap(pdev->dev.parent, NULL); ++ if (!mt6323->regmap) + return -ENODEV; + +- platform_set_drvdata(pdev, mt6397); ++ platform_set_drvdata(pdev, mt6323); + +- mt6397->irq = platform_get_irq(pdev, 0); +- if (mt6397->irq > 0) { +- ret = mt6397_irq_init(mt6397); ++ mt6323->irq = platform_get_irq(pdev, 0); ++ if (mt6323->irq > 0) { ++ ret = mt6323_irq_init(mt6323); + if (ret) + return ret; + } + +- ret = mfd_add_devices(&pdev->dev, -1, mt6397_devs, +- ARRAY_SIZE(mt6397_devs), NULL, 0, NULL); ++ ret = mfd_add_devices(&pdev->dev, -1, mt6323_devs, ++ ARRAY_SIZE(mt6323_devs), NULL, 0, NULL); + if (ret) + dev_err(&pdev->dev, "failed to add child devices: %d\n", ret); + + return ret; + } + +-static int mt6397_remove(struct platform_device *pdev) ++static int mt6323_remove(struct platform_device *pdev) + { + mfd_remove_devices(&pdev->dev); + + return 0; + } + +-static const struct of_device_id mt6397_of_match[] = { +- { .compatible = "mediatek,mt6397" }, ++static const struct of_device_id mt6323_of_match[] = { ++ { .compatible = "mediatek,mt6323" }, + { } + }; +-MODULE_DEVICE_TABLE(of, mt6397_of_match); ++MODULE_DEVICE_TABLE(of, mt6323_of_match); + +-static struct platform_driver mt6397_driver = { +- .probe = mt6397_probe, +- .remove = mt6397_remove, ++static struct platform_driver mt6323_driver = { ++ .probe = mt6323_probe, ++ .remove = mt6323_remove, + .driver = { +- .name = "mt6397", +- .of_match_table = of_match_ptr(mt6397_of_match), ++ .name = "mt6323", ++ .of_match_table = of_match_ptr(mt6323_of_match), + }, + }; + +-module_platform_driver(mt6397_driver); ++module_platform_driver(mt6323_driver); + + MODULE_AUTHOR("Flora Fu, MediaTek"); +-MODULE_DESCRIPTION("Driver for MediaTek MT6397 PMIC"); ++MODULE_DESCRIPTION("Driver for MediaTek MT6323 PMIC"); + MODULE_LICENSE("GPL"); +-MODULE_ALIAS("platform:mt6397"); ++MODULE_ALIAS("platform:mt6323"); +diff --git a/drivers/regulator/mt6323-regulator.c b/drivers/regulator/mt6323-regulator.c +index a5b2f47..f5e3f67 100644 +--- a/drivers/regulator/mt6323-regulator.c ++++ b/drivers/regulator/mt6323-regulator.c +@@ -16,15 +16,15 @@ + #include <linux/of.h> + #include <linux/platform_device.h> + #include <linux/regmap.h> +-#include <linux/mfd/mt6397/core.h> +-#include <linux/mfd/mt6397/registers.h> ++#include <linux/mfd/mt6323/core.h> ++#include <linux/mfd/mt6323/registers.h> + #include <linux/regulator/driver.h> + #include <linux/regulator/machine.h> +-#include <linux/regulator/mt6397-regulator.h> ++#include <linux/regulator/mt6323-regulator.h> + #include <linux/regulator/of_regulator.h> + + /* +- * MT6397 regulators' information ++ * MT6323 regulators' information + * + * @desc: standard fields of regulator description. + * @qi: Mask for query enable signal status of regulators +@@ -32,7 +32,7 @@ + * @vselctrl_reg: Register for controlling the buck control mode. + * @vselctrl_mask: Mask for query buck's voltage control mode. + */ +-struct mt6397_regulator_info { ++struct mt6323_regulator_info { + struct regulator_desc desc; + u32 qi; + u32 vselon_reg; +@@ -40,15 +40,15 @@ struct mt6397_regulator_info { + u32 vselctrl_mask; + }; + +-#define MT6397_BUCK(match, vreg, min, max, step, volt_ranges, enreg, \ ++#define MT6323_BUCK(match, vreg, min, max, step, volt_ranges, enreg, \ + vosel, vosel_mask, voselon, vosel_ctrl) \ +-[MT6397_ID_##vreg] = { \ ++[MT6323_ID_##vreg] = { \ + .desc = { \ + .name = #vreg, \ + .of_match = of_match_ptr(match), \ +- .ops = &mt6397_volt_range_ops, \ ++ .ops = &mt6323_volt_range_ops, \ + .type = REGULATOR_VOLTAGE, \ +- .id = MT6397_ID_##vreg, \ ++ .id = MT6323_ID_##vreg, \ + .owner = THIS_MODULE, \ + .n_voltages = (max - min)/step + 1, \ + .linear_ranges = volt_ranges, \ +@@ -64,15 +64,15 @@ struct mt6397_regulator_info { + .vselctrl_mask = BIT(1), \ + } + +-#define MT6397_LDO(match, vreg, ldo_volt_table, enreg, enbit, vosel, \ ++#define MT6323_LDO(match, vreg, ldo_volt_table, enreg, enbit, vosel, \ + vosel_mask) \ +-[MT6397_ID_##vreg] = { \ ++[MT6323_ID_##vreg] = { \ + .desc = { \ + .name = #vreg, \ + .of_match = of_match_ptr(match), \ +- .ops = &mt6397_volt_table_ops, \ ++ .ops = &mt6323_volt_table_ops, \ + .type = REGULATOR_VOLTAGE, \ +- .id = MT6397_ID_##vreg, \ ++ .id = MT6323_ID_##vreg, \ + .owner = THIS_MODULE, \ + .n_voltages = ARRAY_SIZE(ldo_volt_table), \ + .volt_table = ldo_volt_table, \ +@@ -84,14 +84,14 @@ struct mt6397_regulator_info { + .qi = BIT(15), \ + } + +-#define MT6397_REG_FIXED(match, vreg, enreg, enbit, volt) \ +-[MT6397_ID_##vreg] = { \ ++#define MT6323_REG_FIXED(match, vreg, enreg, enbit, volt) \ ++[MT6323_ID_##vreg] = { \ + .desc = { \ + .name = #vreg, \ + .of_match = of_match_ptr(match), \ +- .ops = &mt6397_volt_fixed_ops, \ ++ .ops = &mt6323_volt_fixed_ops, \ + .type = REGULATOR_VOLTAGE, \ +- .id = MT6397_ID_##vreg, \ ++ .id = MT6323_ID_##vreg, \ + .owner = THIS_MODULE, \ + .n_voltages = 1, \ + .enable_reg = enreg, \ +@@ -106,50 +106,34 @@ static const struct regulator_linear_range buck_volt_range1[] = { + }; + + static const struct regulator_linear_range buck_volt_range2[] = { +- REGULATOR_LINEAR_RANGE(800000, 0, 0x7f, 6250), ++ REGULATOR_LINEAR_RANGE(1400000, 0, 0x7f, 12500), + }; + + static const struct regulator_linear_range buck_volt_range3[] = { +- REGULATOR_LINEAR_RANGE(1500000, 0, 0x1f, 20000), ++ REGULATOR_LINEAR_RANGE(500000, 0, 0x3f, 50000), + }; + + static const u32 ldo_volt_table1[] = { +- 1500000, 1800000, 2500000, 2800000, ++ 1800000, 3300000, + }; + + static const u32 ldo_volt_table2[] = { +- 1800000, 3300000, ++ 3000000, 3300000, + }; + + static const u32 ldo_volt_table3[] = { +- 3000000, 3300000, ++ 1200000, 1300000, 1500000, 1800000, 2000000, 2800000, 3000000, + }; + + static const u32 ldo_volt_table4[] = { +- 1220000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000, +-}; +- +-static const u32 ldo_volt_table5[] = { + 1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000, + }; + +-static const u32 ldo_volt_table5_v2[] = { +- 1200000, 1000000, 1500000, 1800000, 2500000, 2800000, 3000000, 3300000, +-}; +- +-static const u32 ldo_volt_table6[] = { +- 1200000, 1300000, 1500000, 1800000, 2500000, 2800000, 3000000, 2000000, +-}; +- +-static const u32 ldo_volt_table7[] = { +- 1300000, 1500000, 1800000, 2000000, 2500000, 2800000, 3000000, 3300000, +-}; +- +-static int mt6397_get_status(struct regulator_dev *rdev) ++static int mt6323_get_status(struct regulator_dev *rdev) + { + int ret; + u32 regval; +- struct mt6397_regulator_info *info = rdev_get_drvdata(rdev); ++ struct mt6323_regulator_info *info = rdev_get_drvdata(rdev); + + ret = regmap_read(rdev->regmap, info->desc.enable_reg, ®val); + if (ret != 0) { +@@ -160,7 +144,7 @@ static int mt6397_get_status(struct regulator_dev *rdev) + return (regval & info->qi) ? REGULATOR_STATUS_ON : REGULATOR_STATUS_OFF; + } + +-static struct regulator_ops mt6397_volt_range_ops = { ++static struct regulator_ops mt6323_volt_range_ops = { + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, + .set_voltage_sel = regulator_set_voltage_sel_regmap, +@@ -169,10 +153,10 @@ static struct regulator_ops mt6397_volt_range_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, +- .get_status = mt6397_get_status, ++ .get_status = mt6323_get_status, + }; + +-static struct regulator_ops mt6397_volt_table_ops = { ++static struct regulator_ops mt6323_volt_table_ops = { + .list_voltage = regulator_list_voltage_table, + .map_voltage = regulator_map_voltage_iterate, + .set_voltage_sel = regulator_set_voltage_sel_regmap, +@@ -181,90 +165,68 @@ static struct regulator_ops mt6397_volt_table_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, +- .get_status = mt6397_get_status, ++ .get_status = mt6323_get_status, + }; + +-static struct regulator_ops mt6397_volt_fixed_ops = { ++static struct regulator_ops mt6323_volt_fixed_ops = { + .list_voltage = regulator_list_voltage_linear, + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, +- .get_status = mt6397_get_status, ++ .get_status = mt6323_get_status, + }; + +-/* The array is indexed by id(MT6397_ID_XXX) */ +-static struct mt6397_regulator_info mt6397_regulators[] = { +- MT6397_BUCK("buck_vpca15", VPCA15, 700000, 1493750, 6250, +- buck_volt_range1, MT6397_VCA15_CON7, MT6397_VCA15_CON9, 0x7f, +- MT6397_VCA15_CON10, MT6397_VCA15_CON5), +- MT6397_BUCK("buck_vpca7", VPCA7, 700000, 1493750, 6250, +- buck_volt_range1, MT6397_VPCA7_CON7, MT6397_VPCA7_CON9, 0x7f, +- MT6397_VPCA7_CON10, MT6397_VPCA7_CON5), +- MT6397_BUCK("buck_vsramca15", VSRAMCA15, 700000, 1493750, 6250, +- buck_volt_range1, MT6397_VSRMCA15_CON7, MT6397_VSRMCA15_CON9, +- 0x7f, MT6397_VSRMCA15_CON10, MT6397_VSRMCA15_CON5), +- MT6397_BUCK("buck_vsramca7", VSRAMCA7, 700000, 1493750, 6250, +- buck_volt_range1, MT6397_VSRMCA7_CON7, MT6397_VSRMCA7_CON9, +- 0x7f, MT6397_VSRMCA7_CON10, MT6397_VSRMCA7_CON5), +- MT6397_BUCK("buck_vcore", VCORE, 700000, 1493750, 6250, +- buck_volt_range1, MT6397_VCORE_CON7, MT6397_VCORE_CON9, 0x7f, +- MT6397_VCORE_CON10, MT6397_VCORE_CON5), +- MT6397_BUCK("buck_vgpu", VGPU, 700000, 1493750, 6250, buck_volt_range1, +- MT6397_VGPU_CON7, MT6397_VGPU_CON9, 0x7f, +- MT6397_VGPU_CON10, MT6397_VGPU_CON5), +- MT6397_BUCK("buck_vdrm", VDRM, 800000, 1593750, 6250, buck_volt_range2, +- MT6397_VDRM_CON7, MT6397_VDRM_CON9, 0x7f, +- MT6397_VDRM_CON10, MT6397_VDRM_CON5), +- MT6397_BUCK("buck_vio18", VIO18, 1500000, 2120000, 20000, +- buck_volt_range3, MT6397_VIO18_CON7, MT6397_VIO18_CON9, 0x1f, +- MT6397_VIO18_CON10, MT6397_VIO18_CON5), +- MT6397_REG_FIXED("ldo_vtcxo", VTCXO, MT6397_ANALDO_CON0, 10, 2800000), +- MT6397_REG_FIXED("ldo_va28", VA28, MT6397_ANALDO_CON1, 14, 2800000), +- MT6397_LDO("ldo_vcama", VCAMA, ldo_volt_table1, +- MT6397_ANALDO_CON2, 15, MT6397_ANALDO_CON6, 0xC0), +- MT6397_REG_FIXED("ldo_vio28", VIO28, MT6397_DIGLDO_CON0, 14, 2800000), +- MT6397_REG_FIXED("ldo_vusb", VUSB, MT6397_DIGLDO_CON1, 14, 3300000), +- MT6397_LDO("ldo_vmc", VMC, ldo_volt_table2, +- MT6397_DIGLDO_CON2, 12, MT6397_DIGLDO_CON29, 0x10), +- MT6397_LDO("ldo_vmch", VMCH, ldo_volt_table3, +- MT6397_DIGLDO_CON3, 14, MT6397_DIGLDO_CON17, 0x80), +- MT6397_LDO("ldo_vemc3v3", VEMC3V3, ldo_volt_table3, +- MT6397_DIGLDO_CON4, 14, MT6397_DIGLDO_CON18, 0x10), +- MT6397_LDO("ldo_vgp1", VGP1, ldo_volt_table4, +- MT6397_DIGLDO_CON5, 15, MT6397_DIGLDO_CON19, 0xE0), +- MT6397_LDO("ldo_vgp2", VGP2, ldo_volt_table5, +- MT6397_DIGLDO_CON6, 15, MT6397_DIGLDO_CON20, 0xE0), +- MT6397_LDO("ldo_vgp3", VGP3, ldo_volt_table5, +- MT6397_DIGLDO_CON7, 15, MT6397_DIGLDO_CON21, 0xE0), +- MT6397_LDO("ldo_vgp4", VGP4, ldo_volt_table5, +- MT6397_DIGLDO_CON8, 15, MT6397_DIGLDO_CON22, 0xE0), +- MT6397_LDO("ldo_vgp5", VGP5, ldo_volt_table6, +- MT6397_DIGLDO_CON9, 15, MT6397_DIGLDO_CON23, 0xE0), +- MT6397_LDO("ldo_vgp6", VGP6, ldo_volt_table5, +- MT6397_DIGLDO_CON10, 15, MT6397_DIGLDO_CON33, 0xE0), +- MT6397_LDO("ldo_vibr", VIBR, ldo_volt_table7, +- MT6397_DIGLDO_CON24, 15, MT6397_DIGLDO_CON25, 0xE00), ++/* The array is indexed by id(MT6323_ID_XXX) */ ++static struct mt6323_regulator_info mt6323_regulators[] = { ++ /* buck */ ++ MT6323_BUCK("buck_vproc", VPROC, 700000, 1493750, 6250, ++ buck_volt_range1, MT6323_VPROC_CON7, MT6323_VPROC_CON9, 0x7f, ++ MT6323_VPROC_CON10, MT6323_VPROC_CON5), ++ MT6323_BUCK("buck_vsys", VSYS, 1400000, 3000000, 12500, ++ buck_volt_range2, MT6323_VSYS_CON7, MT6323_VSYS_CON9, ++ 0x7f, MT6323_VSYS_CON10, MT6323_VSYS_CON5), ++ MT6323_BUCK("buck_vpa", VPA, 500000, 3650000, 50000, ++ buck_volt_range3, MT6323_VPA_CON7, MT6323_VPA_CON9, 0x7f, ++ MT6323_VPA_CON10, MT6323_VPA_CON5), ++ ++ /* analog */ ++ MT6323_REG_FIXED("ldo_vtcxo", VTCXO, MT6323_ANALDO_CON1, 10, 2800000), ++ MT6323_REG_FIXED("ldo_va", VA, MT6323_ANALDO_CON2, 14, 2800000), ++ MT6323_REG_FIXED("ldo_vcn28", VCN28, MT6323_ANALDO_CON19, 12, 2800000), ++ MT6323_REG_FIXED("ldo_vcn33", VCN33, MT6323_ANALDO_CON21, 12, 3300000), ++ ++ /* digital */ ++ MT6323_REG_FIXED("ldo_vio28", VIO28, MT6323_DIGLDO_CON0, 15, 2800000), ++ MT6323_REG_FIXED("ldo_vusb", VUSB, MT6323_DIGLDO_CON2, 15, 3300000), ++ MT6323_LDO("ldo_vmc", VMC, ldo_volt_table1, ++ MT6323_DIGLDO_CON3, 12, MT6323_DIGLDO_CON24, 0x10), ++ MT6323_LDO("ldo_vmch", VMCH, ldo_volt_table2, ++ MT6323_DIGLDO_CON5, 14, MT6323_DIGLDO_CON26, 0x80), ++ MT6323_LDO("ldo_vgp1", VGP1, ldo_volt_table3, ++ MT6323_DIGLDO_CON7, 15, MT6323_DIGLDO_CON28, 0xE0), ++ MT6323_LDO("ldo_vgp2", VGP2, ldo_volt_table4, ++ MT6323_DIGLDO_CON8, 15, MT6323_DIGLDO_CON29, 0xE0), + }; + +-static int mt6397_set_buck_vosel_reg(struct platform_device *pdev) ++static int mt6323_set_buck_vosel_reg(struct platform_device *pdev) + { +- struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent); ++ struct mt6323_chip *mt6323 = dev_get_drvdata(pdev->dev.parent); + int i; + u32 regval; + +- for (i = 0; i < MT6397_MAX_REGULATOR; i++) { +- if (mt6397_regulators[i].vselctrl_reg) { +- if (regmap_read(mt6397->regmap, +- mt6397_regulators[i].vselctrl_reg, ++ for (i = 0; i < MT6323_MAX_REGULATOR; i++) { ++ if (mt6323_regulators[i].vselctrl_reg) { ++ if (regmap_read(mt6323->regmap, ++ mt6323_regulators[i].vselctrl_reg, + ®val) < 0) { + dev_err(&pdev->dev, + "Failed to read buck ctrl\n"); + return -EIO; + } + +- if (regval & mt6397_regulators[i].vselctrl_mask) { +- mt6397_regulators[i].desc.vsel_reg = +- mt6397_regulators[i].vselon_reg; ++ if (regval & mt6323_regulators[i].vselctrl_mask) { ++ mt6323_regulators[i].desc.vsel_reg = ++ mt6323_regulators[i].vselon_reg; + } + } + } +@@ -272,44 +234,34 @@ static int mt6397_set_buck_vosel_reg(struct platform_device *pdev) + return 0; + } + +-static int mt6397_regulator_probe(struct platform_device *pdev) ++static int mt6323_regulator_probe(struct platform_device *pdev) + { +- struct mt6397_chip *mt6397 = dev_get_drvdata(pdev->dev.parent); ++ struct mt6323_chip *mt6323 = dev_get_drvdata(pdev->dev.parent); + struct regulator_config config = {}; + struct regulator_dev *rdev; + int i; +- u32 reg_value, version; ++ u32 reg_value; + + /* Query buck controller to select activated voltage register part */ +- if (mt6397_set_buck_vosel_reg(pdev)) ++ if (mt6323_set_buck_vosel_reg(pdev)) + return -EIO; + + /* Read PMIC chip revision to update constraints and voltage table */ +- if (regmap_read(mt6397->regmap, MT6397_CID, ®_value) < 0) { ++ if (regmap_read(mt6323->regmap, MT6323_CID, ®_value) < 0) { + dev_err(&pdev->dev, "Failed to read Chip ID\n"); + return -EIO; + } + dev_info(&pdev->dev, "Chip ID = 0x%x\n", reg_value); + +- version = (reg_value & 0xFF); +- switch (version) { +- case MT6397_REGULATOR_ID91: +- mt6397_regulators[MT6397_ID_VGP2].desc.volt_table = +- ldo_volt_table5_v2; +- break; +- default: +- break; +- } +- +- for (i = 0; i < MT6397_MAX_REGULATOR; i++) { ++ for (i = 0; i < MT6323_MAX_REGULATOR; i++) { + config.dev = &pdev->dev; +- config.driver_data = &mt6397_regulators[i]; +- config.regmap = mt6397->regmap; ++ config.driver_data = &mt6323_regulators[i]; ++ config.regmap = mt6323->regmap; + rdev = devm_regulator_register(&pdev->dev, +- &mt6397_regulators[i].desc, &config); ++ &mt6323_regulators[i].desc, &config); + if (IS_ERR(rdev)) { + dev_err(&pdev->dev, "failed to register %s\n", +- mt6397_regulators[i].desc.name); ++ mt6323_regulators[i].desc.name); + return PTR_ERR(rdev); + } + } +@@ -317,16 +269,16 @@ static int mt6397_regulator_probe(struct platform_device *pdev) + return 0; + } + +-static struct platform_driver mt6397_regulator_driver = { ++static struct platform_driver mt6323_regulator_driver = { + .driver = { +- .name = "mt6397-regulator", ++ .name = "mt6323-regulator", + }, +- .probe = mt6397_regulator_probe, ++ .probe = mt6323_regulator_probe, + }; + +-module_platform_driver(mt6397_regulator_driver); ++module_platform_driver(mt6323_regulator_driver); + + MODULE_AUTHOR("Flora Fu <flora.fu@mediatek.com>"); +-MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6397 PMIC"); ++MODULE_DESCRIPTION("Regulator Driver for MediaTek MT6323 PMIC"); + MODULE_LICENSE("GPL"); +-MODULE_ALIAS("platform:mt6397-regulator"); ++MODULE_ALIAS("platform:mt6323-regulator"); +diff --git a/include/linux/mfd/mt6323/core.h b/include/linux/mfd/mt6323/core.h +index cf5265b..5bb2d32 100644 +--- a/include/linux/mfd/mt6323/core.h ++++ b/include/linux/mfd/mt6323/core.h +@@ -12,46 +12,46 @@ + * GNU General Public License for more details. + */ + +-#ifndef __MFD_MT6397_CORE_H__ +-#define __MFD_MT6397_CORE_H__ ++#ifndef __MFD_MT6323_CORE_H__ ++#define __MFD_MT6323_CORE_H__ + +-enum mt6397_irq_numbers { +- MT6397_IRQ_SPKL_AB = 0, +- MT6397_IRQ_SPKR_AB, +- MT6397_IRQ_SPKL, +- MT6397_IRQ_SPKR, +- MT6397_IRQ_BAT_L, +- MT6397_IRQ_BAT_H, +- MT6397_IRQ_FG_BAT_L, +- MT6397_IRQ_FG_BAT_H, +- MT6397_IRQ_WATCHDOG, +- MT6397_IRQ_PWRKEY, +- MT6397_IRQ_THR_L, +- MT6397_IRQ_THR_H, +- MT6397_IRQ_VBATON_UNDET, +- MT6397_IRQ_BVALID_DET, +- MT6397_IRQ_CHRDET, +- MT6397_IRQ_OV, +- MT6397_IRQ_LDO, +- MT6397_IRQ_HOMEKEY, +- MT6397_IRQ_ACCDET, +- MT6397_IRQ_AUDIO, +- MT6397_IRQ_RTC, +- MT6397_IRQ_PWRKEY_RSTB, +- MT6397_IRQ_HDMI_SIFM, +- MT6397_IRQ_HDMI_CEC, +- MT6397_IRQ_VCA15, +- MT6397_IRQ_VSRMCA15, +- MT6397_IRQ_VCORE, +- MT6397_IRQ_VGPU, +- MT6397_IRQ_VIO18, +- MT6397_IRQ_VPCA7, +- MT6397_IRQ_VSRMCA7, +- MT6397_IRQ_VDRM, +- MT6397_IRQ_NR, ++enum mt6323_irq_numbers { ++ MT6323_IRQ_SPKL_AB = 0, ++ MT6323_IRQ_SPKR_AB, ++ MT6323_IRQ_SPKL, ++ MT6323_IRQ_SPKR, ++ MT6323_IRQ_BAT_L, ++ MT6323_IRQ_BAT_H, ++ MT6323_IRQ_FG_BAT_L, ++ MT6323_IRQ_FG_BAT_H, ++ MT6323_IRQ_WATCHDOG, ++ MT6323_IRQ_PWRKEY, ++ MT6323_IRQ_THR_L, ++ MT6323_IRQ_THR_H, ++ MT6323_IRQ_VBATON_UNDET, ++ MT6323_IRQ_BVALID_DET, ++ MT6323_IRQ_CHRDET, ++ MT6323_IRQ_OV, ++ MT6323_IRQ_LDO, ++ MT6323_IRQ_HOMEKEY, ++ MT6323_IRQ_ACCDET, ++ MT6323_IRQ_AUDIO, ++ MT6323_IRQ_RTC, ++ MT6323_IRQ_PWRKEY_RSTB, ++ MT6323_IRQ_HDMI_SIFM, ++ MT6323_IRQ_HDMI_CEC, ++ MT6323_IRQ_VCA15, ++ MT6323_IRQ_VSRMCA15, ++ MT6323_IRQ_VCORE, ++ MT6323_IRQ_VGPU, ++ MT6323_IRQ_VIO18, ++ MT6323_IRQ_VPCA7, ++ MT6323_IRQ_VSRMCA7, ++ MT6323_IRQ_VDRM, ++ MT6323_IRQ_NR, + }; + +-struct mt6397_chip { ++struct mt6323_chip { + struct device *dev; + struct regmap *regmap; + int irq; +@@ -61,4 +61,4 @@ struct mt6397_chip { + u16 irq_masks_cache[2]; + }; + +-#endif /* __MFD_MT6397_CORE_H__ */ ++#endif /* __MFD_MT6323_CORE_H__ */ +diff --git a/include/linux/mfd/mt6323/registers.h b/include/linux/mfd/mt6323/registers.h +index f23a0a6..4ee5e1f0 100644 +--- a/include/linux/mfd/mt6323/registers.h ++++ b/include/linux/mfd/mt6323/registers.h +@@ -1,6 +1,5 @@ + /* +- * Copyright (c) 2014 MediaTek Inc. +- * Author: Flora Fu, MediaTek ++ * Copyright (c) 2015 - John Crispin <blogic@openwrt.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as +@@ -12,351 +11,403 @@ + * GNU General Public License for more details. + */ + +-#ifndef __MFD_MT6397_REGISTERS_H__ +-#define __MFD_MT6397_REGISTERS_H__ ++#ifndef __MFD_MT6323_REGISTERS_H__ ++#define __MFD_MT6323_REGISTERS_H__ + + /* PMIC Registers */ +-#define MT6397_CID 0x0100 +-#define MT6397_TOP_CKPDN 0x0102 +-#define MT6397_TOP_CKPDN_SET 0x0104 +-#define MT6397_TOP_CKPDN_CLR 0x0106 +-#define MT6397_TOP_CKPDN2 0x0108 +-#define MT6397_TOP_CKPDN2_SET 0x010A +-#define MT6397_TOP_CKPDN2_CLR 0x010C +-#define MT6397_TOP_GPIO_CKPDN 0x010E +-#define MT6397_TOP_RST_CON 0x0114 +-#define MT6397_WRP_CKPDN 0x011A +-#define MT6397_WRP_RST_CON 0x0120 +-#define MT6397_TOP_RST_MISC 0x0126 +-#define MT6397_TOP_CKCON1 0x0128 +-#define MT6397_TOP_CKCON2 0x012A +-#define MT6397_TOP_CKTST1 0x012C +-#define MT6397_TOP_CKTST2 0x012E +-#define MT6397_OC_DEG_EN 0x0130 +-#define MT6397_OC_CTL0 0x0132 +-#define MT6397_OC_CTL1 0x0134 +-#define MT6397_OC_CTL2 0x0136 +-#define MT6397_INT_RSV 0x0138 +-#define MT6397_TEST_CON0 0x013A +-#define MT6397_TEST_CON1 0x013C +-#define MT6397_STATUS0 0x013E +-#define MT6397_STATUS1 0x0140 +-#define MT6397_PGSTATUS 0x0142 +-#define MT6397_CHRSTATUS 0x0144 +-#define MT6397_OCSTATUS0 0x0146 +-#define MT6397_OCSTATUS1 0x0148 +-#define MT6397_OCSTATUS2 0x014A +-#define MT6397_HDMI_PAD_IE 0x014C +-#define MT6397_TEST_OUT_L 0x014E +-#define MT6397_TEST_OUT_H 0x0150 +-#define MT6397_TDSEL_CON 0x0152 +-#define MT6397_RDSEL_CON 0x0154 +-#define MT6397_GPIO_SMT_CON0 0x0156 +-#define MT6397_GPIO_SMT_CON1 0x0158 +-#define MT6397_GPIO_SMT_CON2 0x015A +-#define MT6397_GPIO_SMT_CON3 0x015C +-#define MT6397_DRV_CON0 0x015E +-#define MT6397_DRV_CON1 0x0160 +-#define MT6397_DRV_CON2 0x0162 +-#define MT6397_DRV_CON3 0x0164 +-#define MT6397_DRV_CON4 0x0166 +-#define MT6397_DRV_CON5 0x0168 +-#define MT6397_DRV_CON6 0x016A +-#define MT6397_DRV_CON7 0x016C +-#define MT6397_DRV_CON8 0x016E +-#define MT6397_DRV_CON9 0x0170 +-#define MT6397_DRV_CON10 0x0172 +-#define MT6397_DRV_CON11 0x0174 +-#define MT6397_DRV_CON12 0x0176 +-#define MT6397_INT_CON0 0x0178 +-#define MT6397_INT_CON1 0x017E +-#define MT6397_INT_STATUS0 0x0184 +-#define MT6397_INT_STATUS1 0x0186 +-#define MT6397_FQMTR_CON0 0x0188 +-#define MT6397_FQMTR_CON1 0x018A +-#define MT6397_FQMTR_CON2 0x018C +-#define MT6397_EFUSE_DOUT_0_15 0x01C4 +-#define MT6397_EFUSE_DOUT_16_31 0x01C6 +-#define MT6397_EFUSE_DOUT_32_47 0x01C8 +-#define MT6397_EFUSE_DOUT_48_63 0x01CA +-#define MT6397_SPI_CON 0x01CC +-#define MT6397_TOP_CKPDN3 0x01CE +-#define MT6397_TOP_CKCON3 0x01D4 +-#define MT6397_EFUSE_DOUT_64_79 0x01D6 +-#define MT6397_EFUSE_DOUT_80_95 0x01D8 +-#define MT6397_EFUSE_DOUT_96_111 0x01DA +-#define MT6397_EFUSE_DOUT_112_127 0x01DC +-#define MT6397_EFUSE_DOUT_128_143 0x01DE +-#define MT6397_EFUSE_DOUT_144_159 0x01E0 +-#define MT6397_EFUSE_DOUT_160_175 0x01E2 +-#define MT6397_EFUSE_DOUT_176_191 0x01E4 +-#define MT6397_EFUSE_DOUT_192_207 0x01E6 +-#define MT6397_EFUSE_DOUT_208_223 0x01E8 +-#define MT6397_EFUSE_DOUT_224_239 0x01EA +-#define MT6397_EFUSE_DOUT_240_255 0x01EC +-#define MT6397_EFUSE_DOUT_256_271 0x01EE +-#define MT6397_EFUSE_DOUT_272_287 0x01F0 +-#define MT6397_EFUSE_DOUT_288_300 0x01F2 +-#define MT6397_EFUSE_DOUT_304_319 0x01F4 +-#define MT6397_BUCK_CON0 0x0200 +-#define MT6397_BUCK_CON1 0x0202 +-#define MT6397_BUCK_CON2 0x0204 +-#define MT6397_BUCK_CON3 0x0206 +-#define MT6397_BUCK_CON4 0x0208 +-#define MT6397_BUCK_CON5 0x020A +-#define MT6397_BUCK_CON6 0x020C +-#define MT6397_BUCK_CON7 0x020E +-#define MT6397_BUCK_CON8 0x0210 +-#define MT6397_BUCK_CON9 0x0212 +-#define MT6397_VCA15_CON0 0x0214 +-#define MT6397_VCA15_CON1 0x0216 +-#define MT6397_VCA15_CON2 0x0218 +-#define MT6397_VCA15_CON3 0x021A +-#define MT6397_VCA15_CON4 0x021C +-#define MT6397_VCA15_CON5 0x021E +-#define MT6397_VCA15_CON6 0x0220 +-#define MT6397_VCA15_CON7 0x0222 +-#define MT6397_VCA15_CON8 0x0224 +-#define MT6397_VCA15_CON9 0x0226 +-#define MT6397_VCA15_CON10 0x0228 +-#define MT6397_VCA15_CON11 0x022A +-#define MT6397_VCA15_CON12 0x022C +-#define MT6397_VCA15_CON13 0x022E +-#define MT6397_VCA15_CON14 0x0230 +-#define MT6397_VCA15_CON15 0x0232 +-#define MT6397_VCA15_CON16 0x0234 +-#define MT6397_VCA15_CON17 0x0236 +-#define MT6397_VCA15_CON18 0x0238 +-#define MT6397_VSRMCA15_CON0 0x023A +-#define MT6397_VSRMCA15_CON1 0x023C +-#define MT6397_VSRMCA15_CON2 0x023E +-#define MT6397_VSRMCA15_CON3 0x0240 +-#define MT6397_VSRMCA15_CON4 0x0242 +-#define MT6397_VSRMCA15_CON5 0x0244 +-#define MT6397_VSRMCA15_CON6 0x0246 +-#define MT6397_VSRMCA15_CON7 0x0248 +-#define MT6397_VSRMCA15_CON8 0x024A +-#define MT6397_VSRMCA15_CON9 0x024C +-#define MT6397_VSRMCA15_CON10 0x024E +-#define MT6397_VSRMCA15_CON11 0x0250 +-#define MT6397_VSRMCA15_CON12 0x0252 +-#define MT6397_VSRMCA15_CON13 0x0254 +-#define MT6397_VSRMCA15_CON14 0x0256 +-#define MT6397_VSRMCA15_CON15 0x0258 +-#define MT6397_VSRMCA15_CON16 0x025A +-#define MT6397_VSRMCA15_CON17 0x025C +-#define MT6397_VSRMCA15_CON18 0x025E +-#define MT6397_VSRMCA15_CON19 0x0260 +-#define MT6397_VSRMCA15_CON20 0x0262 +-#define MT6397_VSRMCA15_CON21 0x0264 +-#define MT6397_VCORE_CON0 0x0266 +-#define MT6397_VCORE_CON1 0x0268 +-#define MT6397_VCORE_CON2 0x026A +-#define MT6397_VCORE_CON3 0x026C +-#define MT6397_VCORE_CON4 0x026E +-#define MT6397_VCORE_CON5 0x0270 +-#define MT6397_VCORE_CON6 0x0272 +-#define MT6397_VCORE_CON7 0x0274 +-#define MT6397_VCORE_CON8 0x0276 +-#define MT6397_VCORE_CON9 0x0278 +-#define MT6397_VCORE_CON10 0x027A +-#define MT6397_VCORE_CON11 0x027C +-#define MT6397_VCORE_CON12 0x027E +-#define MT6397_VCORE_CON13 0x0280 +-#define MT6397_VCORE_CON14 0x0282 +-#define MT6397_VCORE_CON15 0x0284 +-#define MT6397_VCORE_CON16 0x0286 +-#define MT6397_VCORE_CON17 0x0288 +-#define MT6397_VCORE_CON18 0x028A +-#define MT6397_VGPU_CON0 0x028C +-#define MT6397_VGPU_CON1 0x028E +-#define MT6397_VGPU_CON2 0x0290 +-#define MT6397_VGPU_CON3 0x0292 +-#define MT6397_VGPU_CON4 0x0294 +-#define MT6397_VGPU_CON5 0x0296 +-#define MT6397_VGPU_CON6 0x0298 +-#define MT6397_VGPU_CON7 0x029A +-#define MT6397_VGPU_CON8 0x029C +-#define MT6397_VGPU_CON9 0x029E +-#define MT6397_VGPU_CON10 0x02A0 +-#define MT6397_VGPU_CON11 0x02A2 +-#define MT6397_VGPU_CON12 0x02A4 +-#define MT6397_VGPU_CON13 0x02A6 +-#define MT6397_VGPU_CON14 0x02A8 +-#define MT6397_VGPU_CON15 0x02AA +-#define MT6397_VGPU_CON16 0x02AC +-#define MT6397_VGPU_CON17 0x02AE +-#define MT6397_VGPU_CON18 0x02B0 +-#define MT6397_VIO18_CON0 0x0300 +-#define MT6397_VIO18_CON1 0x0302 +-#define MT6397_VIO18_CON2 0x0304 +-#define MT6397_VIO18_CON3 0x0306 +-#define MT6397_VIO18_CON4 0x0308 +-#define MT6397_VIO18_CON5 0x030A +-#define MT6397_VIO18_CON6 0x030C +-#define MT6397_VIO18_CON7 0x030E +-#define MT6397_VIO18_CON8 0x0310 +-#define MT6397_VIO18_CON9 0x0312 +-#define MT6397_VIO18_CON10 0x0314 +-#define MT6397_VIO18_CON11 0x0316 +-#define MT6397_VIO18_CON12 0x0318 +-#define MT6397_VIO18_CON13 0x031A +-#define MT6397_VIO18_CON14 0x031C +-#define MT6397_VIO18_CON15 0x031E +-#define MT6397_VIO18_CON16 0x0320 +-#define MT6397_VIO18_CON17 0x0322 +-#define MT6397_VIO18_CON18 0x0324 +-#define MT6397_VPCA7_CON0 0x0326 +-#define MT6397_VPCA7_CON1 0x0328 +-#define MT6397_VPCA7_CON2 0x032A +-#define MT6397_VPCA7_CON3 0x032C +-#define MT6397_VPCA7_CON4 0x032E +-#define MT6397_VPCA7_CON5 0x0330 +-#define MT6397_VPCA7_CON6 0x0332 +-#define MT6397_VPCA7_CON7 0x0334 +-#define MT6397_VPCA7_CON8 0x0336 +-#define MT6397_VPCA7_CON9 0x0338 +-#define MT6397_VPCA7_CON10 0x033A +-#define MT6397_VPCA7_CON11 0x033C +-#define MT6397_VPCA7_CON12 0x033E +-#define MT6397_VPCA7_CON13 0x0340 +-#define MT6397_VPCA7_CON14 0x0342 +-#define MT6397_VPCA7_CON15 0x0344 +-#define MT6397_VPCA7_CON16 0x0346 +-#define MT6397_VPCA7_CON17 0x0348 +-#define MT6397_VPCA7_CON18 0x034A +-#define MT6397_VSRMCA7_CON0 0x034C +-#define MT6397_VSRMCA7_CON1 0x034E +-#define MT6397_VSRMCA7_CON2 0x0350 +-#define MT6397_VSRMCA7_CON3 0x0352 +-#define MT6397_VSRMCA7_CON4 0x0354 +-#define MT6397_VSRMCA7_CON5 0x0356 +-#define MT6397_VSRMCA7_CON6 0x0358 +-#define MT6397_VSRMCA7_CON7 0x035A +-#define MT6397_VSRMCA7_CON8 0x035C +-#define MT6397_VSRMCA7_CON9 0x035E +-#define MT6397_VSRMCA7_CON10 0x0360 +-#define MT6397_VSRMCA7_CON11 0x0362 +-#define MT6397_VSRMCA7_CON12 0x0364 +-#define MT6397_VSRMCA7_CON13 0x0366 +-#define MT6397_VSRMCA7_CON14 0x0368 +-#define MT6397_VSRMCA7_CON15 0x036A +-#define MT6397_VSRMCA7_CON16 0x036C +-#define MT6397_VSRMCA7_CON17 0x036E +-#define MT6397_VSRMCA7_CON18 0x0370 +-#define MT6397_VSRMCA7_CON19 0x0372 +-#define MT6397_VSRMCA7_CON20 0x0374 +-#define MT6397_VSRMCA7_CON21 0x0376 +-#define MT6397_VDRM_CON0 0x0378 +-#define MT6397_VDRM_CON1 0x037A +-#define MT6397_VDRM_CON2 0x037C +-#define MT6397_VDRM_CON3 0x037E +-#define MT6397_VDRM_CON4 0x0380 +-#define MT6397_VDRM_CON5 0x0382 +-#define MT6397_VDRM_CON6 0x0384 +-#define MT6397_VDRM_CON7 0x0386 +-#define MT6397_VDRM_CON8 0x0388 +-#define MT6397_VDRM_CON9 0x038A +-#define MT6397_VDRM_CON10 0x038C +-#define MT6397_VDRM_CON11 0x038E +-#define MT6397_VDRM_CON12 0x0390 +-#define MT6397_VDRM_CON13 0x0392 +-#define MT6397_VDRM_CON14 0x0394 +-#define MT6397_VDRM_CON15 0x0396 +-#define MT6397_VDRM_CON16 0x0398 +-#define MT6397_VDRM_CON17 0x039A +-#define MT6397_VDRM_CON18 0x039C +-#define MT6397_BUCK_K_CON0 0x039E +-#define MT6397_BUCK_K_CON1 0x03A0 +-#define MT6397_ANALDO_CON0 0x0400 +-#define MT6397_ANALDO_CON1 0x0402 +-#define MT6397_ANALDO_CON2 0x0404 +-#define MT6397_ANALDO_CON3 0x0406 +-#define MT6397_ANALDO_CON4 0x0408 +-#define MT6397_ANALDO_CON5 0x040A +-#define MT6397_ANALDO_CON6 0x040C +-#define MT6397_ANALDO_CON7 0x040E +-#define MT6397_DIGLDO_CON0 0x0410 +-#define MT6397_DIGLDO_CON1 0x0412 +-#define MT6397_DIGLDO_CON2 0x0414 +-#define MT6397_DIGLDO_CON3 0x0416 +-#define MT6397_DIGLDO_CON4 0x0418 +-#define MT6397_DIGLDO_CON5 0x041A +-#define MT6397_DIGLDO_CON6 0x041C +-#define MT6397_DIGLDO_CON7 0x041E +-#define MT6397_DIGLDO_CON8 0x0420 +-#define MT6397_DIGLDO_CON9 0x0422 +-#define MT6397_DIGLDO_CON10 0x0424 +-#define MT6397_DIGLDO_CON11 0x0426 +-#define MT6397_DIGLDO_CON12 0x0428 +-#define MT6397_DIGLDO_CON13 0x042A +-#define MT6397_DIGLDO_CON14 0x042C +-#define MT6397_DIGLDO_CON15 0x042E +-#define MT6397_DIGLDO_CON16 0x0430 +-#define MT6397_DIGLDO_CON17 0x0432 +-#define MT6397_DIGLDO_CON18 0x0434 +-#define MT6397_DIGLDO_CON19 0x0436 +-#define MT6397_DIGLDO_CON20 0x0438 +-#define MT6397_DIGLDO_CON21 0x043A +-#define MT6397_DIGLDO_CON22 0x043C +-#define MT6397_DIGLDO_CON23 0x043E +-#define MT6397_DIGLDO_CON24 0x0440 +-#define MT6397_DIGLDO_CON25 0x0442 +-#define MT6397_DIGLDO_CON26 0x0444 +-#define MT6397_DIGLDO_CON27 0x0446 +-#define MT6397_DIGLDO_CON28 0x0448 +-#define MT6397_DIGLDO_CON29 0x044A +-#define MT6397_DIGLDO_CON30 0x044C +-#define MT6397_DIGLDO_CON31 0x044E +-#define MT6397_DIGLDO_CON32 0x0450 +-#define MT6397_DIGLDO_CON33 0x045A +-#define MT6397_SPK_CON0 0x0600 +-#define MT6397_SPK_CON1 0x0602 +-#define MT6397_SPK_CON2 0x0604 +-#define MT6397_SPK_CON3 0x0606 +-#define MT6397_SPK_CON4 0x0608 +-#define MT6397_SPK_CON5 0x060A +-#define MT6397_SPK_CON6 0x060C +-#define MT6397_SPK_CON7 0x060E +-#define MT6397_SPK_CON8 0x0610 +-#define MT6397_SPK_CON9 0x0612 +-#define MT6397_SPK_CON10 0x0614 +-#define MT6397_SPK_CON11 0x0616 +-#define MT6397_AUDDAC_CON0 0x0700 +-#define MT6397_AUDBUF_CFG0 0x0702 +-#define MT6397_AUDBUF_CFG1 0x0704 +-#define MT6397_AUDBUF_CFG2 0x0706 +-#define MT6397_AUDBUF_CFG3 0x0708 +-#define MT6397_AUDBUF_CFG4 0x070A +-#define MT6397_IBIASDIST_CFG0 0x070C +-#define MT6397_AUDACCDEPOP_CFG0 0x070E +-#define MT6397_AUD_IV_CFG0 0x0710 +-#define MT6397_AUDCLKGEN_CFG0 0x0712 +-#define MT6397_AUDLDO_CFG0 0x0714 +-#define MT6397_AUDLDO_CFG1 0x0716 +-#define MT6397_AUDNVREGGLB_CFG0 0x0718 +-#define MT6397_AUD_NCP0 0x071A +-#define MT6397_AUDPREAMP_CON0 0x071C +-#define MT6397_AUDADC_CON0 0x071E +-#define MT6397_AUDADC_CON1 0x0720 +-#define MT6397_AUDADC_CON2 0x0722 +-#define MT6397_AUDADC_CON3 0x0724 +-#define MT6397_AUDADC_CON4 0x0726 +-#define MT6397_AUDADC_CON5 0x0728 +-#define MT6397_AUDADC_CON6 0x072A +-#define MT6397_AUDDIGMI_CON0 0x072C +-#define MT6397_AUDLSBUF_CON0 0x072E +-#define MT6397_AUDLSBUF_CON1 0x0730 +-#define MT6397_AUDENCSPARE_CON0 0x0732 +-#define MT6397_AUDENCCLKSQ_CON0 0x0734 +-#define MT6397_AUDPREAMPGAIN_CON0 0x0736 +-#define MT6397_ZCD_CON0 0x0738 +-#define MT6397_ZCD_CON1 0x073A +-#define MT6397_ZCD_CON2 0x073C +-#define MT6397_ZCD_CON3 0x073E +-#define MT6397_ZCD_CON4 0x0740 +-#define MT6397_ZCD_CON5 0x0742 +-#define MT6397_NCP_CLKDIV_CON0 0x0744 +-#define MT6397_NCP_CLKDIV_CON1 0x0746 ++#define MT6323_CHR_CON0 0x0000 ++#define MT6323_CHR_CON1 0x0002 ++#define MT6323_CHR_CON2 0x0004 ++#define MT6323_CHR_CON3 0x0006 ++#define MT6323_CHR_CON4 0x0008 ++#define MT6323_CHR_CON5 0x000A ++#define MT6323_CHR_CON6 0x000C ++#define MT6323_CHR_CON7 0x000E ++#define MT6323_CHR_CON8 0x0010 ++#define MT6323_CHR_CON9 0x0012 ++#define MT6323_CHR_CON10 0x0014 ++#define MT6323_CHR_CON11 0x0016 ++#define MT6323_CHR_CON12 0x0018 ++#define MT6323_CHR_CON13 0x001A ++#define MT6323_CHR_CON14 0x001C ++#define MT6323_CHR_CON15 0x001E ++#define MT6323_CHR_CON16 0x0020 ++#define MT6323_CHR_CON17 0x0022 ++#define MT6323_CHR_CON18 0x0024 ++#define MT6323_CHR_CON19 0x0026 ++#define MT6323_CHR_CON20 0x0028 ++#define MT6323_CHR_CON21 0x002A ++#define MT6323_CHR_CON22 0x002C ++#define MT6323_CHR_CON23 0x002E ++#define MT6323_CHR_CON24 0x0030 ++#define MT6323_CHR_CON25 0x0032 ++#define MT6323_CHR_CON26 0x0034 ++#define MT6323_CHR_CON27 0x0036 ++#define MT6323_CHR_CON28 0x0038 ++#define MT6323_CHR_CON29 0x003A ++#define MT6323_STRUP_CON0 0x003C ++#define MT6323_STRUP_CON2 0x003E ++#define MT6323_STRUP_CON3 0x0040 ++#define MT6323_STRUP_CON4 0x0042 ++#define MT6323_STRUP_CON5 0x0044 ++#define MT6323_STRUP_CON6 0x0046 ++#define MT6323_STRUP_CON7 0x0048 ++#define MT6323_STRUP_CON8 0x004A ++#define MT6323_STRUP_CON9 0x004C ++#define MT6323_STRUP_CON10 0x004E ++#define MT6323_STRUP_CON11 0x0050 ++#define MT6323_SPK_CON0 0x0052 ++#define MT6323_SPK_CON1 0x0054 ++#define MT6323_SPK_CON2 0x0056 ++#define MT6323_SPK_CON6 0x005E ++#define MT6323_SPK_CON7 0x0060 ++#define MT6323_SPK_CON8 0x0062 ++#define MT6323_SPK_CON9 0x0064 ++#define MT6323_SPK_CON10 0x0066 ++#define MT6323_SPK_CON11 0x0068 ++#define MT6323_SPK_CON12 0x006A ++#define MT6323_CID 0x0100 ++#define MT6323_TOP_CKPDN0 0x0102 ++#define MT6323_TOP_CKPDN0_SET 0x0104 ++#define MT6323_TOP_CKPDN0_CLR 0x0106 ++#define MT6323_TOP_CKPDN1 0x0108 ++#define MT6323_TOP_CKPDN1_SET 0x010A ++#define MT6323_TOP_CKPDN1_CLR 0x010C ++#define MT6323_TOP_CKPDN2 0x010E ++#define MT6323_TOP_CKPDN2_SET 0x0110 ++#define MT6323_TOP_CKPDN2_CLR 0x0112 ++#define MT6323_TOP_RST_CON 0x0114 ++#define MT6323_TOP_RST_CON_SET 0x0116 ++#define MT6323_TOP_RST_CON_CLR 0x0118 ++#define MT6323_TOP_RST_MISC 0x011A ++#define MT6323_TOP_RST_MISC_SET 0x011C ++#define MT6323_TOP_RST_MISC_CLR 0x011E ++#define MT6323_TOP_CKCON0 0x0120 ++#define MT6323_TOP_CKCON0_SET 0x0122 ++#define MT6323_TOP_CKCON0_CLR 0x0124 ++#define MT6323_TOP_CKCON1 0x0126 ++#define MT6323_TOP_CKCON1_SET 0x0128 ++#define MT6323_TOP_CKCON1_CLR 0x012A ++#define MT6323_TOP_CKTST0 0x012C ++#define MT6323_TOP_CKTST1 0x012E ++#define MT6323_TOP_CKTST2 0x0130 ++#define MT6323_TEST_OUT 0x0132 ++#define MT6323_TEST_CON0 0x0134 ++#define MT6323_TEST_CON1 0x0136 ++#define MT6323_EN_STATUS0 0x0138 ++#define MT6323_EN_STATUS1 0x013A ++#define MT6323_OCSTATUS0 0x013C ++#define MT6323_OCSTATUS1 0x013E ++#define MT6323_PGSTATUS 0x0140 ++#define MT6323_CHRSTATUS 0x0142 ++#define MT6323_TDSEL_CON 0x0144 ++#define MT6323_RDSEL_CON 0x0146 ++#define MT6323_SMT_CON0 0x0148 ++#define MT6323_SMT_CON1 0x014A ++#define MT6323_SMT_CON2 0x014C ++#define MT6323_SMT_CON3 0x014E ++#define MT6323_SMT_CON4 0x0150 ++#define MT6323_DRV_CON0 0x0152 ++#define MT6323_DRV_CON1 0x0154 ++#define MT6323_DRV_CON2 0x0156 ++#define MT6323_DRV_CON3 0x0158 ++#define MT6323_DRV_CON4 0x015A ++#define MT6323_SIMLS1_CON 0x015C ++#define MT6323_SIMLS2_CON 0x015E ++#define MT6323_INT_CON0 0x0160 ++#define MT6323_INT_CON0_SET 0x0162 ++#define MT6323_INT_CON0_CLR 0x0164 ++#define MT6323_INT_CON1 0x0166 ++#define MT6323_INT_CON1_SET 0x0168 ++#define MT6323_INT_CON1_CLR 0x016A ++#define MT6323_INT_MISC_CON 0x016C ++#define MT6323_INT_MISC_CON_SET 0x016E ++#define MT6323_INT_MISC_CON_CLR 0x0170 ++#define MT6323_INT_STATUS0 0x0172 ++#define MT6323_INT_STATUS1 0x0174 ++#define MT6323_OC_GEAR_0 0x0176 ++#define MT6323_OC_GEAR_1 0x0178 ++#define MT6323_OC_GEAR_2 0x017A ++#define MT6323_OC_CTL_VPROC 0x017C ++#define MT6323_OC_CTL_VSYS 0x017E ++#define MT6323_OC_CTL_VPA 0x0180 ++#define MT6323_FQMTR_CON0 0x0182 ++#define MT6323_FQMTR_CON1 0x0184 ++#define MT6323_FQMTR_CON2 0x0186 ++#define MT6323_RG_SPI_CON 0x0188 ++#define MT6323_DEW_DIO_EN 0x018A ++#define MT6323_DEW_READ_TEST 0x018C ++#define MT6323_DEW_WRITE_TEST 0x018E ++#define MT6323_DEW_CRC_SWRST 0x0190 ++#define MT6323_DEW_CRC_EN 0x0192 ++#define MT6323_DEW_CRC_VAL 0x0194 ++#define MT6323_DEW_DBG_MON_SEL 0x0196 ++#define MT6323_DEW_CIPHER_KEY_SEL 0x0198 ++#define MT6323_DEW_CIPHER_IV_SEL 0x019A ++#define MT6323_DEW_CIPHER_EN 0x019C ++#define MT6323_DEW_CIPHER_RDY 0x019E ++#define MT6323_DEW_CIPHER_MODE 0x01A0 ++#define MT6323_DEW_CIPHER_SWRST 0x01A2 ++#define MT6323_DEW_RDDMY_NO 0x01A4 ++#define MT6323_DEW_RDATA_DLY_SEL 0x01A6 ++#define MT6323_BUCK_CON0 0x0200 ++#define MT6323_BUCK_CON1 0x0202 ++#define MT6323_BUCK_CON2 0x0204 ++#define MT6323_BUCK_CON3 0x0206 ++#define MT6323_BUCK_CON4 0x0208 ++#define MT6323_BUCK_CON5 0x020A ++#define MT6323_VPROC_CON0 0x020C ++#define MT6323_VPROC_CON1 0x020E ++#define MT6323_VPROC_CON2 0x0210 ++#define MT6323_VPROC_CON3 0x0212 ++#define MT6323_VPROC_CON4 0x0214 ++#define MT6323_VPROC_CON5 0x0216 ++#define MT6323_VPROC_CON7 0x021A ++#define MT6323_VPROC_CON8 0x021C ++#define MT6323_VPROC_CON9 0x021E ++#define MT6323_VPROC_CON10 0x0220 ++#define MT6323_VPROC_CON11 0x0222 ++#define MT6323_VPROC_CON12 0x0224 ++#define MT6323_VPROC_CON13 0x0226 ++#define MT6323_VPROC_CON14 0x0228 ++#define MT6323_VPROC_CON15 0x022A ++#define MT6323_VPROC_CON18 0x0230 ++#define MT6323_VSYS_CON0 0x0232 ++#define MT6323_VSYS_CON1 0x0234 ++#define MT6323_VSYS_CON2 0x0236 ++#define MT6323_VSYS_CON3 0x0238 ++#define MT6323_VSYS_CON4 0x023A ++#define MT6323_VSYS_CON5 0x023C ++#define MT6323_VSYS_CON7 0x0240 ++#define MT6323_VSYS_CON8 0x0242 ++#define MT6323_VSYS_CON9 0x0244 ++#define MT6323_VSYS_CON10 0x0246 ++#define MT6323_VSYS_CON11 0x0248 ++#define MT6323_VSYS_CON12 0x024A ++#define MT6323_VSYS_CON13 0x024C ++#define MT6323_VSYS_CON14 0x024E ++#define MT6323_VSYS_CON15 0x0250 ++#define MT6323_VSYS_CON18 0x0256 ++#define MT6323_VPA_CON0 0x0300 ++#define MT6323_VPA_CON1 0x0302 ++#define MT6323_VPA_CON2 0x0304 ++#define MT6323_VPA_CON3 0x0306 ++#define MT6323_VPA_CON4 0x0308 ++#define MT6323_VPA_CON5 0x030A ++#define MT6323_VPA_CON7 0x030E ++#define MT6323_VPA_CON8 0x0310 ++#define MT6323_VPA_CON9 0x0312 ++#define MT6323_VPA_CON10 0x0314 ++#define MT6323_VPA_CON11 0x0316 ++#define MT6323_VPA_CON12 0x0318 ++#define MT6323_VPA_CON14 0x031C ++#define MT6323_VPA_CON16 0x0320 ++#define MT6323_VPA_CON17 0x0322 ++#define MT6323_VPA_CON18 0x0324 ++#define MT6323_VPA_CON19 0x0326 ++#define MT6323_VPA_CON20 0x0328 ++#define MT6323_BUCK_K_CON0 0x032A ++#define MT6323_BUCK_K_CON1 0x032C ++#define MT6323_BUCK_K_CON2 0x032E ++#define MT6323_ISINK0_CON0 0x0330 ++#define MT6323_ISINK0_CON1 0x0332 ++#define MT6323_ISINK0_CON2 0x0334 ++#define MT6323_ISINK0_CON3 0x0336 ++#define MT6323_ISINK1_CON0 0x0338 ++#define MT6323_ISINK1_CON1 0x033A ++#define MT6323_ISINK1_CON2 0x033C ++#define MT6323_ISINK1_CON3 0x033E ++#define MT6323_ISINK2_CON0 0x0340 ++#define MT6323_ISINK2_CON1 0x0342 ++#define MT6323_ISINK2_CON2 0x0344 ++#define MT6323_ISINK2_CON3 0x0346 ++#define MT6323_ISINK3_CON0 0x0348 ++#define MT6323_ISINK3_CON1 0x034A ++#define MT6323_ISINK3_CON2 0x034C ++#define MT6323_ISINK3_CON3 0x034E ++#define MT6323_ISINK_ANA0 0x0350 ++#define MT6323_ISINK_ANA1 0x0352 ++#define MT6323_ISINK_PHASE_DLY 0x0354 ++#define MT6323_ISINK_EN_CTRL 0x0356 ++#define MT6323_ANALDO_CON0 0x0400 ++#define MT6323_ANALDO_CON1 0x0402 ++#define MT6323_ANALDO_CON2 0x0404 ++#define MT6323_ANALDO_CON3 0x0406 ++#define MT6323_ANALDO_CON4 0x0408 ++#define MT6323_ANALDO_CON5 0x040A ++#define MT6323_ANALDO_CON6 0x040C ++#define MT6323_ANALDO_CON7 0x040E ++#define MT6323_ANALDO_CON8 0x0410 ++#define MT6323_ANALDO_CON10 0x0412 ++#define MT6323_ANALDO_CON15 0x0414 ++#define MT6323_ANALDO_CON16 0x0416 ++#define MT6323_ANALDO_CON17 0x0418 ++#define MT6323_ANALDO_CON18 0x041A ++#define MT6323_ANALDO_CON19 0x041C ++#define MT6323_ANALDO_CON20 0x041E ++#define MT6323_ANALDO_CON21 0x0420 ++#define MT6323_DIGLDO_CON0 0x0500 ++#define MT6323_DIGLDO_CON2 0x0502 ++#define MT6323_DIGLDO_CON3 0x0504 ++#define MT6323_DIGLDO_CON5 0x0506 ++#define MT6323_DIGLDO_CON6 0x0508 ++#define MT6323_DIGLDO_CON7 0x050A ++#define MT6323_DIGLDO_CON8 0x050C ++#define MT6323_DIGLDO_CON9 0x050E ++#define MT6323_DIGLDO_CON10 0x0510 ++#define MT6323_DIGLDO_CON11 0x0512 ++#define MT6323_DIGLDO_CON12 0x0514 ++#define MT6323_DIGLDO_CON13 0x0516 ++#define MT6323_DIGLDO_CON14 0x0518 ++#define MT6323_DIGLDO_CON15 0x051A ++#define MT6323_DIGLDO_CON16 0x051C ++#define MT6323_DIGLDO_CON17 0x051E ++#define MT6323_DIGLDO_CON18 0x0520 ++#define MT6323_DIGLDO_CON19 0x0522 ++#define MT6323_DIGLDO_CON20 0x0524 ++#define MT6323_DIGLDO_CON21 0x0526 ++#define MT6323_DIGLDO_CON23 0x0528 ++#define MT6323_DIGLDO_CON24 0x052A ++#define MT6323_DIGLDO_CON26 0x052C ++#define MT6323_DIGLDO_CON27 0x052E ++#define MT6323_DIGLDO_CON28 0x0530 ++#define MT6323_DIGLDO_CON29 0x0532 ++#define MT6323_DIGLDO_CON30 0x0534 ++#define MT6323_DIGLDO_CON31 0x0536 ++#define MT6323_DIGLDO_CON32 0x0538 ++#define MT6323_DIGLDO_CON33 0x053A ++#define MT6323_DIGLDO_CON34 0x053C ++#define MT6323_DIGLDO_CON35 0x053E ++#define MT6323_DIGLDO_CON36 0x0540 ++#define MT6323_DIGLDO_CON39 0x0542 ++#define MT6323_DIGLDO_CON40 0x0544 ++#define MT6323_DIGLDO_CON41 0x0546 ++#define MT6323_DIGLDO_CON42 0x0548 ++#define MT6323_DIGLDO_CON43 0x054A ++#define MT6323_DIGLDO_CON44 0x054C ++#define MT6323_DIGLDO_CON45 0x054E ++#define MT6323_DIGLDO_CON46 0x0550 ++#define MT6323_DIGLDO_CON47 0x0552 ++#define MT6323_DIGLDO_CON48 0x0554 ++#define MT6323_DIGLDO_CON49 0x0556 ++#define MT6323_DIGLDO_CON50 0x0558 ++#define MT6323_DIGLDO_CON51 0x055A ++#define MT6323_DIGLDO_CON52 0x055C ++#define MT6323_DIGLDO_CON53 0x055E ++#define MT6323_DIGLDO_CON54 0x0560 ++#define MT6323_EFUSE_CON0 0x0600 ++#define MT6323_EFUSE_CON1 0x0602 ++#define MT6323_EFUSE_CON2 0x0604 ++#define MT6323_EFUSE_CON3 0x0606 ++#define MT6323_EFUSE_CON4 0x0608 ++#define MT6323_EFUSE_CON5 0x060A ++#define MT6323_EFUSE_CON6 0x060C ++#define MT6323_EFUSE_VAL_0_15 0x060E ++#define MT6323_EFUSE_VAL_16_31 0x0610 ++#define MT6323_EFUSE_VAL_32_47 0x0612 ++#define MT6323_EFUSE_VAL_48_63 0x0614 ++#define MT6323_EFUSE_VAL_64_79 0x0616 ++#define MT6323_EFUSE_VAL_80_95 0x0618 ++#define MT6323_EFUSE_VAL_96_111 0x061A ++#define MT6323_EFUSE_VAL_112_127 0x061C ++#define MT6323_EFUSE_VAL_128_143 0x061E ++#define MT6323_EFUSE_VAL_144_159 0x0620 ++#define MT6323_EFUSE_VAL_160_175 0x0622 ++#define MT6323_EFUSE_VAL_176_191 0x0624 ++#define MT6323_EFUSE_DOUT_0_15 0x0626 ++#define MT6323_EFUSE_DOUT_16_31 0x0628 ++#define MT6323_EFUSE_DOUT_32_47 0x062A ++#define MT6323_EFUSE_DOUT_48_63 0x062C ++#define MT6323_EFUSE_DOUT_64_79 0x062E ++#define MT6323_EFUSE_DOUT_80_95 0x0630 ++#define MT6323_EFUSE_DOUT_96_111 0x0632 ++#define MT6323_EFUSE_DOUT_112_127 0x0634 ++#define MT6323_EFUSE_DOUT_128_143 0x0636 ++#define MT6323_EFUSE_DOUT_144_159 0x0638 ++#define MT6323_EFUSE_DOUT_160_175 0x063A ++#define MT6323_EFUSE_DOUT_176_191 0x063C ++#define MT6323_EFUSE_CON7 0x063E ++#define MT6323_EFUSE_CON8 0x0640 ++#define MT6323_EFUSE_CON9 0x0642 ++#define MT6323_RTC_MIX_CON0 0x0644 ++#define MT6323_RTC_MIX_CON1 0x0646 ++#define MT6323_AUDTOP_CON0 0x0700 ++#define MT6323_AUDTOP_CON1 0x0702 ++#define MT6323_AUDTOP_CON2 0x0704 ++#define MT6323_AUDTOP_CON3 0x0706 ++#define MT6323_AUDTOP_CON4 0x0708 ++#define MT6323_AUDTOP_CON5 0x070A ++#define MT6323_AUDTOP_CON6 0x070C ++#define MT6323_AUDTOP_CON7 0x070E ++#define MT6323_AUDTOP_CON8 0x0710 ++#define MT6323_AUDTOP_CON9 0x0712 ++#define MT6323_AUXADC_ADC0 0x0714 ++#define MT6323_AUXADC_ADC1 0x0716 ++#define MT6323_AUXADC_ADC2 0x0718 ++#define MT6323_AUXADC_ADC3 0x071A ++#define MT6323_AUXADC_ADC4 0x071C ++#define MT6323_AUXADC_ADC5 0x071E ++#define MT6323_AUXADC_ADC6 0x0720 ++#define MT6323_AUXADC_ADC7 0x0722 ++#define MT6323_AUXADC_ADC8 0x0724 ++#define MT6323_AUXADC_ADC9 0x0726 ++#define MT6323_AUXADC_ADC10 0x0728 ++#define MT6323_AUXADC_ADC11 0x072A ++#define MT6323_AUXADC_ADC12 0x072C ++#define MT6323_AUXADC_ADC13 0x072E ++#define MT6323_AUXADC_ADC14 0x0730 ++#define MT6323_AUXADC_ADC15 0x0732 ++#define MT6323_AUXADC_ADC16 0x0734 ++#define MT6323_AUXADC_ADC17 0x0736 ++#define MT6323_AUXADC_ADC18 0x0738 ++#define MT6323_AUXADC_ADC19 0x073A ++#define MT6323_AUXADC_ADC20 0x073C ++#define MT6323_AUXADC_RSV1 0x073E ++#define MT6323_AUXADC_RSV2 0x0740 ++#define MT6323_AUXADC_CON0 0x0742 ++#define MT6323_AUXADC_CON1 0x0744 ++#define MT6323_AUXADC_CON2 0x0746 ++#define MT6323_AUXADC_CON3 0x0748 ++#define MT6323_AUXADC_CON4 0x074A ++#define MT6323_AUXADC_CON5 0x074C ++#define MT6323_AUXADC_CON6 0x074E ++#define MT6323_AUXADC_CON7 0x0750 ++#define MT6323_AUXADC_CON8 0x0752 ++#define MT6323_AUXADC_CON9 0x0754 ++#define MT6323_AUXADC_CON10 0x0756 ++#define MT6323_AUXADC_CON11 0x0758 ++#define MT6323_AUXADC_CON12 0x075A ++#define MT6323_AUXADC_CON13 0x075C ++#define MT6323_AUXADC_CON14 0x075E ++#define MT6323_AUXADC_CON15 0x0760 ++#define MT6323_AUXADC_CON16 0x0762 ++#define MT6323_AUXADC_CON17 0x0764 ++#define MT6323_AUXADC_CON18 0x0766 ++#define MT6323_AUXADC_CON19 0x0768 ++#define MT6323_AUXADC_CON20 0x076A ++#define MT6323_AUXADC_CON21 0x076C ++#define MT6323_AUXADC_CON22 0x076E ++#define MT6323_AUXADC_CON23 0x0770 ++#define MT6323_AUXADC_CON24 0x0772 ++#define MT6323_AUXADC_CON25 0x0774 ++#define MT6323_AUXADC_CON26 0x0776 ++#define MT6323_AUXADC_CON27 0x0778 ++#define MT6323_ACCDET_CON0 0x077A ++#define MT6323_ACCDET_CON1 0x077C ++#define MT6323_ACCDET_CON2 0x077E ++#define MT6323_ACCDET_CON3 0x0780 ++#define MT6323_ACCDET_CON4 0x0782 ++#define MT6323_ACCDET_CON5 0x0784 ++#define MT6323_ACCDET_CON6 0x0786 ++#define MT6323_ACCDET_CON7 0x0788 ++#define MT6323_ACCDET_CON8 0x078A ++#define MT6323_ACCDET_CON9 0x078C ++#define MT6323_ACCDET_CON10 0x078E ++#define MT6323_ACCDET_CON11 0x0790 ++#define MT6323_ACCDET_CON12 0x0792 ++#define MT6323_ACCDET_CON13 0x0794 ++#define MT6323_ACCDET_CON14 0x0796 ++#define MT6323_ACCDET_CON15 0x0798 ++#define MT6323_ACCDET_CON16 0x079A + +-#endif /* __MFD_MT6397_REGISTERS_H__ */ ++#endif +diff --git a/include/linux/regulator/mt6323-regulator.h b/include/linux/regulator/mt6323-regulator.h +new file mode 100644 +index 0000000..620b0e3 +--- /dev/null ++++ b/include/linux/regulator/mt6323-regulator.h +@@ -0,0 +1,37 @@ ++/* ++ * Copyright (c) 2015 MediaTek Inc. ++ * Author: John Crispin <blogic@openwrt.org> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __LINUX_REGULATOR_MT6323_H ++#define __LINUX_REGULATOR_MT6323_H ++ ++enum { ++ MT6323_ID_VPROC = 0, ++ MT6323_ID_VSYS, ++ MT6323_ID_VPA, ++ MT6323_ID_VTCXO, ++ MT6323_ID_VA, ++ MT6323_ID_VCN28, ++ MT6323_ID_VCN33, ++ MT6323_ID_VIO28, ++ MT6323_ID_VUSB, ++ MT6323_ID_VMC, ++ MT6323_ID_VMCH, ++ MT6323_ID_VGP1, ++ MT6323_ID_VGP2, ++ MT6323_ID_RG_MAX, ++}; ++ ++#define MT6323_MAX_REGULATOR MT6323_ID_RG_MAX ++ ++#endif /* __LINUX_REGULATOR_MT6323_H */ +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0073-clk.patch b/target/linux/mediatek/patches/0073-clk.patch new file mode 100644 index 0000000000..a3b36a5dae --- /dev/null +++ b/target/linux/mediatek/patches/0073-clk.patch @@ -0,0 +1,200 @@ +From a4df453fbfa6199ad33435cee6ce2dfcc65321b0 Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Fri, 3 Jul 2015 05:45:58 +0200 +Subject: [PATCH 73/76] clk + +--- + include/dt-bindings/clock/mt7623-clk.h | 158 +++++++++++++++----------------- + 1 file changed, 73 insertions(+), 85 deletions(-) + +diff --git a/include/dt-bindings/clock/mt7623-clk.h b/include/dt-bindings/clock/mt7623-clk.h +index cb1e8a9..410ef31 100644 +--- a/include/dt-bindings/clock/mt7623-clk.h ++++ b/include/dt-bindings/clock/mt7623-clk.h +@@ -17,96 +17,76 @@ + + /* TOPCKGEN */ + +-#define CLK_TOP_AUDPLL_24 1 +-#define CLK_TOP_AUDPLL_D16 2 +-#define CLK_TOP_AUDPLL_D4 3 +-#define CLK_TOP_AUDPLL_D8 4 +-#define CLK_TOP_CLKPH_MCK 5 +-#define CLK_TOP_CPUM_TCK_IN 6 +-#define CLK_TOP_DSI0_LNTC_DSICLK 7 +-#define CLK_TOP_HDMITX_CLKDIG_CTS 8 +-#define CLK_TOP_LVDS_ETH 9 +-#define CLK_TOP_LVDSPLL_D2 10 +-#define CLK_TOP_LVDSPLL_D4 11 +-#define CLK_TOP_LVDSPLL_D8 12 +-#define CLK_TOP_MAINPLL_230P3M 13 +-#define CLK_TOP_MAINPLL_322P4M 14 +-#define CLK_TOP_MAINPLL_537P3M 15 +-#define CLK_TOP_MAINPLL_806M 16 +-#define CLK_TOP_MEMPLL_MCK_D4 17 +-#define CLK_TOP_MMPLL_D2 18 +-#define CLK_TOP_MSDCPLL_D2 19 +-#define CLK_TOP_SYSPLL1_D16 20 +-#define CLK_TOP_SYSPLL1_D2 21 +-#define CLK_TOP_SYSPLL1_D4 22 +-#define CLK_TOP_SYSPLL1_D8 23 +-#define CLK_TOP_SYSPLL2_D2 24 +-#define CLK_TOP_SYSPLL2_D4 25 +-#define CLK_TOP_SYSPLL2_D8 26 +-#define CLK_TOP_SYSPLL3_D2 27 +-#define CLK_TOP_SYSPLL3_D4 28 +-#define CLK_TOP_SYSPLL4_D2 29 +-#define CLK_TOP_SYSPLL4_D4 30 +-#define CLK_TOP_SYSPLL_D3 31 +-#define CLK_TOP_SYSPLL_D5 32 +-#define CLK_TOP_SYSPLL_D7 33 +-#define CLK_TOP_TVDPLL_d2 34 +-#define CLK_TOP_TVDPLL_D4 35 +-#define CLK_TOP_UNIVPLL_178P3M 36 +-#define CLK_TOP_UNIVPLL1_D10 37 +-#define CLK_TOP_UNIVPLL1_D2 38 +-#define CLK_TOP_UNIVPLL1_D4 39 +-#define CLK_TOP_UNIVPLL1_D6 40 +-#define CLK_TOP_UNIVPLL1_D8 41 +-#define CLK_TOP_UNIVPLL_249P6M 42 +-#define CLK_TOP_UNIVPLL2_D2 43 +-#define CLK_TOP_UNIVPLL2_D4 44 +-#define CLK_TOP_UNIVPLL2_D6 45 +-#define CLK_TOP_UNIVPLL2_D8 46 +-#define CLK_TOP_UNIVPLL_416M 47 +-#define CLK_TOP_UNIVPLL_48M 48 +-#define CLK_TOP_UNIVPLL_624M 49 +-#define CLK_TOP_UNIVPLL_D26 50 +-#define CLK_TOP_UNIVPLL_D5 51 +-#define CLK_TOP_APLL_SEL 52 ++#define CLK_TOP_MAINPLL_650M 1 ++#define CLK_TOP_MAINPLL_433P3M 2 ++#define CLK_TOP_MAINPLL_260M 3 ++#define CLK_TOP_MAINPLL_185P6M 4 ++#define CLK_TOP_UNIVPLL_624M 5 ++#define CLK_TOP_UNIVPLL_416M 6 ++#define CLK_TOP_UNIVPLL_249P6M 7 ++#define CLK_TOP_UNIVPLL_178P3M 8 ++#define CLK_TOP_UNIVPLL_48M 9 ++#define CLK_TOP_AUDPLL_D4 10 ++#define CLK_TOP_AUDPLL_D8 11 ++#define CLK_TOP_AUDPLL_D16 12 ++#define CLK_TOP_AUDPLL_24 13 ++#define CLK_TOP_MSDCPLL_D2 14 ++#define CLK_TOP_SYSPLL1_D2 15 ++#define CLK_TOP_SYSPLL1_D4 16 ++#define CLK_TOP_SYSPLL1_D8 17 ++#define CLK_TOP_SYSPLL1_D16 18 ++#define CLK_TOP_SYSPLL2_D2 19 ++#define CLK_TOP_SYSPLL2_D4 20 ++#define CLK_TOP_SYSPLL2_D8 21 ++#define CLK_TOP_SYSPLL3_D2 22 ++#define CLK_TOP_SYSPLL3_D4 23 ++#define CLK_TOP_SYSPLL4_D2 24 ++#define CLK_TOP_SYSPLL4_D4 25 ++#define CLK_TOP_SYSPLL_D3 26 ++#define CLK_TOP_SYSPLL_D5 27 ++#define CLK_TOP_SYSPLL_D7 28 ++#define CLK_TOP_UNIVPLL1_D2 29 ++#define CLK_TOP_UNIVPLL1_D4 30 ++#define CLK_TOP_UNIVPLL1_D6 31 ++#define CLK_TOP_UNIVPLL1_D8 32 ++#define CLK_TOP_UNIVPLL1_D10 33 ++#define CLK_TOP_UNIVPLL2_D2 34 ++#define CLK_TOP_UNIVPLL2_D4 35 ++#define CLK_TOP_UNIVPLL2_D6 36 ++#define CLK_TOP_UNIVPLL2_D8 37 ++#define CLK_TOP_UNIVPLL_D5 38 ++#define CLK_TOP_UNIVPLL_D26 39 ++#define CLK_TOP_AXI_SEL 40 ++#define CLK_TOP_MEM_SEL 41 ++#define CLK_TOP_DDR_SEL 42 ++#define CLK_TOP_MM_SEL 43 ++#define CLK_TOP_PWM_SEL 44 ++#define CLK_TOP_MFG_SEL 45 ++#define CLK_TOP_UART_SEL 46 ++#define CLK_TOP_SPI_SEL 47 ++#define CLK_TOP_USB20_SEL 48 ++#define CLK_TOP_MSDC30_0_SEL 49 ++#define CLK_TOP_MSDC30_1_SEL 50 ++#define CLK_TOP_MSDC30_2_SEL 51 ++#define CLK_TOP_AUDIO_SEL 52 + #define CLK_TOP_AUDIO_INTBUS_SEL 53 +-#define CLK_TOP_AUDIO_SEL 54 +-#define CLK_TOP_AXI_SEL 55 +-#define CLK_TOP_CAM_SEL 56 +-#define CLK_TOP_DDR_SEL 57 +-#define CLK_TOP_DPI0_SEL 58 +-#define CLK_TOP_DPI1_SEL 59 +-#define CLK_TOP_DPILVDS_SEL 60 +-#define CLK_TOP_ETH_SEL 61 +-#define CLK_TOP_MEM_SEL 62 +-#define CLK_TOP_MFG_SEL 63 +-#define CLK_TOP_MM_SEL 64 +-#define CLK_TOP_MSDC30_0_SEL 65 +-#define CLK_TOP_MSDC30_1_SEL 66 +-#define CLK_TOP_MSDC30_2_SEL 67 +-#define CLK_TOP_NFI2X_SEL 68 +-#define CLK_TOP_PMICSPI_SEL 69 +-#define CLK_TOP_PWM_SEL 70 +-#define CLK_TOP_RTC_SEL 71 +-#define CLK_TOP_SCP_SEL 72 +-#define CLK_TOP_SPI_SEL 73 +-#define CLK_TOP_TVE_SEL 74 +-#define CLK_TOP_UART_SEL 75 +-#define CLK_TOP_USB20_SEL 76 +-#define CLK_TOP_VDEC_SEL 77 +-#define CLK_TOP_NR_CLK 78 ++#define CLK_TOP_PMICSPI_SEL 54 ++#define CLK_TOP_SCP_SEL 55 ++#define CLK_TOP_APLL_SEL 56 ++#define CLK_TOP_RTC_SEL 57 ++#define CLK_TOP_NFI2X_SEL 58 ++#define CLK_TOP_ETH_SEL 59 ++#define CLK_TOP_NR_CLK 60 + + /* APMIXED_SYS */ + + #define CLK_APMIXED_ARMPLL 1 + #define CLK_APMIXED_MAINPLL 2 +-#define CLK_APMIXED_MSDCPLL 3 +-#define CLK_APMIXED_UNIVPLL 4 +-#define CLK_APMIXED_MMPLL 5 +-#define CLK_APMIXED_VENCPLL 6 +-#define CLK_APMIXED_TVDPLL 7 +-#define CLK_APMIXED_LVDSPLL 8 +-#define CLK_APMIXED_AUDPLL 9 ++#define CLK_APMIXED_UNIVPLL 3 ++#define CLK_APMIXED_MSDCPLL 4 ++#define CLK_APMIXED_AUDPLL 5 ++#define CLK_APMIXED_TRGPLL 6 ++#define CLK_APMIXED_ETHPLL 7 + + /* INFRA_SYS */ + +@@ -124,7 +104,8 @@ + #define CLK_INFRA_IRRX 19 + #define CLK_INFRA_PMICSPI 22 + #define CLK_INFRA_PMIC_WRAP 23 +-#define CLK_INFRA_NR_CLK 24 ++#define CLK_INFRA_CA7SEL 24 ++#define CLK_INFRA_NR_CLK 25 + + /* PERI_SYS */ + +@@ -169,5 +150,12 @@ + #define CLK_PERI_UART3_SEL 38 + #define CLK_PERI_NR_CLK 39 + ++#define CLK_HIFSYS_USB0_PHY 1 ++#define CLK_HIFSYS_USB1_PHY 2 ++#define CLK_HIFSYS_PCIE0 3 ++#define CLK_HIFSYS_PCIE1 4 ++#define CLK_HIFSYS_PCIE2 5 ++#define CLK_HIFSYS_NR_CLK 6 ++ + #endif /* _DT_BINDINGS_CLK_MT7623_H */ + +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0074-dts.patch b/target/linux/mediatek/patches/0074-dts.patch new file mode 100644 index 0000000000..eddafb61cd --- /dev/null +++ b/target/linux/mediatek/patches/0074-dts.patch @@ -0,0 +1,182 @@ +From df59c3b7030b6d7802fe5e5abda81467fcdf2178 Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Fri, 3 Jul 2015 05:46:13 +0200 +Subject: [PATCH 74/76] dts + +--- + arch/arm/boot/dts/mt7623-evb.dts | 124 +++++++++++++++++++++++++++++++++++++- + arch/arm/boot/dts/mt7623.dtsi | 11 ++++ + 2 files changed, 133 insertions(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/mt7623-evb.dts ++++ b/arch/arm/boot/dts/mt7623-evb.dts +@@ -145,8 +145,8 @@ + bus-width = <8>; + max-frequency = <50000000>; + cap-mmc-highspeed; +-// vmmc-supply = <&mt6397_vemc_3v3_reg>; +-// vqmmc-supply = <&mt6397_vio18_reg>; ++// vmmc-supply = <&mt6323_vemc_3v3_reg>; ++// vqmmc-supply = <&mt6323_vio18_reg>; + non-removable; + }; + +@@ -160,3 +160,123 @@ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_default>; + }; ++ ++&pwrap { ++ pmic: mt6323 { ++ compatible = "mediatek,mt6323"; ++ ++ mt6323regulator: mt6323regulator { ++ compatible = "mediatek,mt6323-regulator"; ++ ++ mt6323_vproc_reg: buck_vproc { ++ regulator-compatible = "buck_vproc"; ++ regulator-name = "vproc"; ++ regulator-min-microvolt = < 700000>; ++ regulator-max-microvolt = <1493750>; ++ regulator-ramp-delay = <6250>; ++ regulator-always-on; ++ }; ++ ++ mt6323_vsys_reg: buck_vsys { ++ regulator-compatible = "buck_vsys"; ++ regulator-name = "vsys"; ++ regulator-min-microvolt = <1400000>; ++ regulator-max-microvolt = <3000000>; ++ regulator-ramp-delay = <12500>; ++ regulator-always-on; ++ }; ++ ++ mt6323_vpa_reg: buck_vpa { ++ regulator-compatible = "buck_vpa"; ++ regulator-name = "vpa"; ++ regulator-min-microvolt = < 500000>; ++ regulator-max-microvolt = <3650000>; ++ regulator-ramp-delay = <50000>; ++ regulator-always-on; ++ }; ++ ++ mt6323_vtcxo_reg: ldo_vtcxo { ++ regulator-compatible = "ldo_vtcxo"; ++ regulator-name = "vtcxo"; ++ regulator-always-on; ++ }; ++ ++ mt6323_va_reg: ldo_va { ++ regulator-compatible = "ldo_va"; ++ regulator-name = "va"; ++ regulator-always-on; ++ }; ++ ++ mt6323_vcn28_reg: ldo_vcn28 { ++ regulator-compatible = "ldo_vcn28"; ++ regulator-name = "vcn28"; ++ regulator-always-on; ++ }; ++ ++ mt6323_vcn33_reg: ldo_vcn33 { ++ regulator-compatible = "ldo_vcn33"; ++ regulator-name = "vcn33"; ++ regulator-always-on; ++ }; ++ ++ mt6323_vcama_reg: ldo_vcama { ++ regulator-compatible = "ldo_vcama"; ++ regulator-name = "vcama"; ++ regulator-min-microvolt = <1500000>; ++ regulator-max-microvolt = <2800000>; ++ regulator-enable-ramp-delay = <218>; ++ }; ++ ++ mt6323_vio28_reg: ldo_vio28 { ++ regulator-compatible = "ldo_vio28"; ++ regulator-name = "vio28"; ++ regulator-always-on; ++ }; ++ ++ mt6323_vusb_reg: ldo_vusb { ++ regulator-compatible = "ldo_vusb"; ++ regulator-name = "vusb"; ++ }; ++ ++ mt6323_vmc_reg: ldo_vmc { ++ regulator-compatible = "ldo_vmc"; ++ regulator-name = "vmc"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-enable-ramp-delay = <218>; ++ }; ++ ++ mt6323_vmch_reg: ldo_vmch { ++ regulator-compatible = "ldo_vmch"; ++ regulator-name = "vmch"; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-enable-ramp-delay = <218>; ++ }; ++ ++ mt6323_vemc_3v3_reg: ldo_vemc3v3 { ++ regulator-compatible = "ldo_vemc3v3"; ++ regulator-name = "vemc_3v3"; ++ regulator-min-microvolt = <3000000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-enable-ramp-delay = <218>; ++ }; ++ ++ mt6323_vgp1_reg: ldo_vgp1 { ++ regulator-compatible = "ldo_vgp1"; ++ regulator-name = "vcamd"; ++ regulator-min-microvolt = <1220000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-enable-ramp-delay = <240>; ++ }; ++ ++ mt6323_vgp2_reg: ldo_vgp2 { ++ regulator-compatible = "ldo_vgp2"; ++ regulator-name = "vcamio"; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-enable-ramp-delay = <218>; ++ }; ++ }; ++ }; ++}; +--- a/arch/arm/boot/dts/mt7623.dtsi ++++ b/arch/arm/boot/dts/mt7623.dtsi +@@ -150,6 +150,17 @@ + clock-names = "system-clk", "rtc-clk"; + }; + ++ pwrap: pwrap@1000f000 { ++ compatible = "mediatek,mt7623-pwrap"; ++ reg = <0 0x1000f000 0 0x1000>; ++ reg-names = "pwrap"; ++ interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>; ++ resets = <&infracfg MT7623_INFRA_PMIC_WRAP_RST>; ++ reset-names = "pwrap"; ++ clocks = <&clk26m>, <&clk26m>; ++ clock-names = "spi", "wrap"; ++ }; ++ + sysirq: interrupt-controller@10200100 { + compatible = "mediatek,mt7623-sysirq", + "mediatek,mt6577-sysirq"; +@@ -311,6 +322,7 @@ + device_type = "pci"; + + bus-range = <0 255>; ++ status = "disabled"; + ranges = < + 0x02000000 0 0 0x00000000 0x60000000 0 0x10000000 /* pci memory */ + 0x01000000 0 0 0x00000000 0x1A160000 0 0x00010000 /* io space */ +@@ -343,6 +355,5 @@ + device_type = "pci"; + }; + +- status = "disabled"; + }; + }; diff --git a/target/linux/mediatek/patches/0075-sd.patch b/target/linux/mediatek/patches/0075-sd.patch new file mode 100644 index 0000000000..1dcfae397f --- /dev/null +++ b/target/linux/mediatek/patches/0075-sd.patch @@ -0,0 +1,55 @@ +From a5982c5e4b58c4335e789969e04f9e24b894f510 Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Fri, 3 Jul 2015 05:46:39 +0200 +Subject: [PATCH 75/76] sd + +--- + drivers/mmc/host/mtk-sd.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c +index 7c20f28..be2b00c 100644 +--- a/drivers/mmc/host/mtk-sd.c ++++ b/drivers/mmc/host/mtk-sd.c +@@ -227,11 +227,13 @@ struct mt_gpdma_desc { + #define GPDMA_DESC_BDP (0x1 << 1) + #define GPDMA_DESC_CHECKSUM (0xff << 8) /* bit8 ~ bit15 */ + #define GPDMA_DESC_INT (0x1 << 16) ++#define GPDMA_DESC_GPDH4B (0x1 << 24) ++#define GPDMA_DESC_BDH4B (0x1 << 28) + u32 next; + u32 ptr; + u32 gpd_data_len; +-#define GPDMA_DESC_BUFLEN (0xffff) /* bit0 ~ bit15 */ +-#define GPDMA_DESC_EXTLEN (0xff << 16) /* bit16 ~ bit23 */ ++#define GPDMA_DESC_BUFLEN (0xffffff) /* bit0 ~ bit15 */ ++#define GPDMA_DESC_EXTLEN (0xff << 24) /* bit16 ~ bit23 */ + u32 arg; + u32 blknum; + u32 cmd; +@@ -243,10 +245,12 @@ struct mt_bdma_desc { + #define BDMA_DESC_CHECKSUM (0xff << 8) /* bit8 ~ bit15 */ + #define BDMA_DESC_BLKPAD (0x1 << 17) + #define BDMA_DESC_DWPAD (0x1 << 18) ++#define BDMA_DESC_GPDH4B (0x1 << 24) ++#define BDMA_DESC_BDH4B (0x1 << 28) + u32 next; + u32 ptr; + u32 bd_data_len; +-#define BDMA_DESC_BUFLEN (0xffff) /* bit0 ~ bit15 */ ++#define BDMA_DESC_BUFLEN (0xffffff) /* bit0 ~ bit15 */ + }; + + struct msdc_dma { +@@ -1115,7 +1119,7 @@ static void msdc_init_hw(struct msdc_host *host) + sdr_set_field(host->base + MSDC_IOCON, MSDC_IOCON_DDLSEL, 1); + writel(0x403c004f, host->base + MSDC_PATCH_BIT); + sdr_set_field(host->base + MSDC_PATCH_BIT, MSDC_CKGEN_MSDC_DLY_SEL, 1); +- writel(0xffff0089, host->base + MSDC_PATCH_BIT1); ++// writel(0xffff0089, host->base + MSDC_PATCH_BIT1); + /* Configure to enable SDIO mode. + * it's must otherwise sdio cmd5 failed + */ +-- +1.7.10.4 + diff --git a/target/linux/mediatek/patches/0076-reset.patch b/target/linux/mediatek/patches/0076-reset.patch new file mode 100644 index 0000000000..615777920c --- /dev/null +++ b/target/linux/mediatek/patches/0076-reset.patch @@ -0,0 +1,30 @@ +From 1671d902f8dcfce70f920ad3dfebb1031a7a38de Mon Sep 17 00:00:00 2001 +From: John Crispin <blogic@openwrt.org> +Date: Fri, 3 Jul 2015 05:46:51 +0200 +Subject: [PATCH 76/76] reset + +--- + include/dt-bindings/reset-controller/mt7623-resets.h | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/include/dt-bindings/reset-controller/mt7623-resets.h b/include/dt-bindings/reset-controller/mt7623-resets.h +index 28a7d69..3e0f39a 100644 +--- a/include/dt-bindings/reset-controller/mt7623-resets.h ++++ b/include/dt-bindings/reset-controller/mt7623-resets.h +@@ -56,4 +56,13 @@ + #define MT7623_PERI_ETH_SW_RST 29 + #define MT7623_PERI_SPI0_SW_RST 33 + ++/* high speed interface resets */ ++#define MT7623_HIFSYS_UHOST0_SW_RST 3 ++#define MT7623_HIFSYS_UHOST1_SW_RST 4 ++#define MT7623_HIFSYS_UPHY0_SW_RST 21 ++#define MT7623_HIFSYS_UPHY1_SW_RST 22 ++#define MT7623_HIFSYS_PCIE0_SW_RST 24 ++#define MT7623_HIFSYS_PCIE0_SW_RST 25 ++#define MT7623_HIFSYS_PCIE0_SW_RST 26 ++ + #endif /* _DT_BINDINGS_RESET_CONTROLLER_MT7623 */ +-- +1.7.10.4 + |