@@ -164,11 +164,11 @@ static const char *uart4_src[] __initdata = { "clk_tcxo", "clk_150m", };
static const char *hifi_src[] __initdata = { "syspll", "pll_media_gate", };
static struct hisi_gate_clock hi6220_separated_gate_clks_sys[] __initdata = {
- { HI6220_MMC0_CLK, "mmc0_clk", "mmc0_rst_clk", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x200, 0, 0, },
+ { HI6220_MMC0_CLK, "mmc0_clk", "mmc0_src", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x200, 0, 0, },
{ HI6220_MMC0_CIUCLK, "mmc0_ciuclk", "mmc0_smp_in", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x200, 0, 0, },
- { HI6220_MMC1_CLK, "mmc1_clk", "mmc1_rst_clk", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x200, 1, 0, },
+ { HI6220_MMC1_CLK, "mmc1_clk", "mmc1_src", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x200, 1, 0, },
{ HI6220_MMC1_CIUCLK, "mmc1_ciuclk", "mmc1_smp_in", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x200, 1, 0, },
- { HI6220_MMC2_CLK, "mmc2_clk", "mmc2_rst_clk", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x200, 2, 0, },
+ { HI6220_MMC2_CLK, "mmc2_clk", "mmc2_src", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x200, 2, 0, },
{ HI6220_MMC2_CIUCLK, "mmc2_ciuclk", "mmc2_smp_in", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x200, 2, 0, },
{ HI6220_USBOTG_HCLK, "usbotg_hclk", "clk_bus", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x200, 4, 0, },
{ HI6220_CLK_PICOPHY, "clk_picophy", "cs_dapb", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x200, 5, 0, },
@@ -199,12 +199,6 @@ static struct hisi_gate_clock hi6220_separated_gate_clks_sys[] __initdata = {
{ HI6220_CS_ATB_SYSPLL, "cs_atb_syspll", "syspll", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x270, 12, 0, },
};
-static struct hisi_gate_clock hi6220_reset_clks[] __initdata = {
- { 0, "mmc0_rst_clk", "mmc0_src", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x304, 0, 0, },
- { 0, "mmc1_rst_clk", "mmc1_src", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x304, 1, 0, },
- { 0, "mmc2_rst_clk", "mmc2_src", CLK_SET_RATE_PARENT|CLK_IGNORE_UNUSED, 0x304, 2, 0, },
-};
-
static struct hisi_mux_clock hi6220_mux_clks_sys[] __initdata = {
{ HI6220_MMC0_SRC, "mmc0_src", mmc0_src_p, ARRAY_SIZE(mmc0_src_p), CLK_SET_RATE_PARENT, 0x4, 0, 1, 0, },
{ HI6220_MMC0_SMP_IN, "mmc0_smp_in", mmc0_sample_in, ARRAY_SIZE(mmc0_sample_in), CLK_SET_RATE_PARENT, 0x4, 0, 1, 0, },
@@ -244,9 +238,6 @@ static void __init hi6220_clk_sys_init(struct device_node *np)
if (!clk_data)
return;
- hisi_clk_register_gate(hi6220_reset_clks,
- ARRAY_SIZE(hi6220_reset_clks), clk_data);
-
hisi_clk_register_gate_sep(hi6220_separated_gate_clks_sys,
ARRAY_SIZE(hi6220_separated_gate_clks_sys), clk_data);
@@ -1,7 +1,7 @@
/*
* Hisilicon Hi6220 reset controller driver
*
- * Copyright (c) 2015 Hisilicon Limited.
+ * Copyright (c) 2015-2016 Hisilicon Limited.
*
* Author: Feng Chen <puck.chen@hisilicon.com>
*
@@ -15,83 +15,138 @@
#include <linux/module.h>
#include <linux/bitops.h>
#include <linux/of.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
#include <linux/reset-controller.h>
#include <linux/reset.h>
#include <linux/platform_device.h>
-#define ASSERT_OFFSET 0x300
-#define DEASSERT_OFFSET 0x304
-#define MAX_INDEX 0x509
+/*
+ * peripheral ctrl regs
+ */
+#define PERIPH_ASSERT_OFFSET 0x300
+#define PERIPH_DEASSERT_OFFSET 0x304
+#define PERIPH_MAX_INDEX 0x509
+
+/*
+ * media ctrl regs
+ */
+#define SC_MEDIA_RSTEN 0x052C
+#define SC_MEDIA_RSTDIS 0x0530
+#define MEDIA_MAX_INDEX 8
+
+enum hi6220_reset_ctrl_type {
+ PERIPHERAL,
+ MEDIA,
+};
#define to_reset_data(x) container_of(x, struct hi6220_reset_data, rc_dev)
struct hi6220_reset_data {
- void __iomem *assert_base;
- void __iomem *deassert_base;
- struct reset_controller_dev rc_dev;
+ struct reset_controller_dev rc_dev;
+ enum hi6220_reset_ctrl_type type;
+ struct regmap *regmap;
};
-static int hi6220_reset_assert(struct reset_controller_dev *rc_dev,
+static int hi6220_media_assert(struct reset_controller_dev *rc_dev,
unsigned long idx)
{
struct hi6220_reset_data *data = to_reset_data(rc_dev);
+ struct regmap *regmap = data->regmap;
- int bank = idx >> 8;
- int offset = idx & 0xff;
+ return regmap_write(regmap, SC_MEDIA_RSTEN, BIT(idx));
+}
- writel(BIT(offset), data->assert_base + (bank * 0x10));
+static int hi6220_media_deassert(struct reset_controller_dev *rc_dev,
+ unsigned long idx)
+{
+ struct hi6220_reset_data *data = to_reset_data(rc_dev);
+ struct regmap *regmap = data->regmap;
- return 0;
+ return regmap_write(regmap, SC_MEDIA_RSTDIS, BIT(idx));
}
-static int hi6220_reset_deassert(struct reset_controller_dev *rc_dev,
- unsigned long idx)
+static int hi6220_peripheral_assert(struct reset_controller_dev *rc_dev,
+ unsigned long idx)
{
struct hi6220_reset_data *data = to_reset_data(rc_dev);
+ struct regmap *regmap = data->regmap;
+ u32 bank = idx >> 8;
+ u32 offset = idx & 0xff;
+ u32 reg = PERIPH_ASSERT_OFFSET + bank * 0x10;
- int bank = idx >> 8;
- int offset = idx & 0xff;
+ return regmap_write(regmap, reg, BIT(offset));
+}
- writel(BIT(offset), data->deassert_base + (bank * 0x10));
+static int hi6220_peripheral_deassert(struct reset_controller_dev *rc_dev,
+ unsigned long idx)
+{
+ struct hi6220_reset_data *data = to_reset_data(rc_dev);
+ struct regmap *regmap = data->regmap;
+ u32 bank = idx >> 8;
+ u32 offset = idx & 0xff;
+ u32 reg = PERIPH_DEASSERT_OFFSET + bank * 0x10;
- return 0;
+ return regmap_write(regmap, reg, BIT(offset));
}
-static struct reset_control_ops hi6220_reset_ops = {
- .assert = hi6220_reset_assert,
- .deassert = hi6220_reset_deassert,
+static const struct reset_control_ops hi6220_media_reset_ops = {
+ .assert = hi6220_media_assert,
+ .deassert = hi6220_media_deassert,
+};
+
+static const struct reset_control_ops hi6220_peripheral_reset_ops = {
+ .assert = hi6220_peripheral_assert,
+ .deassert = hi6220_peripheral_deassert,
};
static int hi6220_reset_probe(struct platform_device *pdev)
{
+ struct device_node *np = pdev->dev.of_node;
+ struct device *dev = &pdev->dev;
+ enum hi6220_reset_ctrl_type type;
struct hi6220_reset_data *data;
- struct resource *res;
- void __iomem *src_base;
+ struct regmap *regmap;
- data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+ data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
if (!data)
return -ENOMEM;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- src_base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(src_base))
- return PTR_ERR(src_base);
-
- data->assert_base = src_base + ASSERT_OFFSET;
- data->deassert_base = src_base + DEASSERT_OFFSET;
- data->rc_dev.nr_resets = MAX_INDEX;
- data->rc_dev.ops = &hi6220_reset_ops;
- data->rc_dev.of_node = pdev->dev.of_node;
-
- reset_controller_register(&data->rc_dev);
-
- return 0;
+ type = (enum hi6220_reset_ctrl_type)of_device_get_match_data(dev);
+
+ regmap = syscon_node_to_regmap(np);
+ if (IS_ERR(regmap)) {
+ dev_err(dev, "failed to get reset controller regmap\n");
+ return PTR_ERR(regmap);
+ }
+
+ data->type = type;
+ data->regmap = regmap;
+ data->rc_dev.of_node = np;
+ if (type == MEDIA) {
+ data->rc_dev.ops = &hi6220_media_reset_ops;
+ data->rc_dev.nr_resets = MEDIA_MAX_INDEX;
+ } else {
+ data->rc_dev.ops = &hi6220_peripheral_reset_ops;
+ data->rc_dev.nr_resets = PERIPH_MAX_INDEX;
+ }
+
+ return reset_controller_register(&data->rc_dev);
}
static const struct of_device_id hi6220_reset_match[] = {
- { .compatible = "hisilicon,hi6220-sysctrl" },
- { },
+ {
+ .compatible = "hisilicon,hi6220-sysctrl",
+ .data = (void *)PERIPHERAL,
+ },
+ {
+ .compatible = "hisilicon,hi6220-mediactrl",
+ .data = (void *)MEDIA,
+ },
+ { /* sentinel */ },
};
+MODULE_DEVICE_TABLE(of, hi6220_reset_match);
static struct platform_driver hi6220_reset_driver = {
.probe = hi6220_reset_probe,
@@ -64,4 +64,12 @@
#define PERIPH_RSDIST9_CARM_SOCDBG 0x507
#define PERIPH_RSDIST9_CARM_ETM 0x508
+#define MEDIA_G3D 0
+#define MEDIA_CODEC_VPU 2
+#define MEDIA_CODEC_JPEG 3
+#define MEDIA_ISP 4
+#define MEDIA_ADE 5
+#define MEDIA_MMU 6
+#define MEDIA_XG2RAM1 7
+
#endif /*_DT_BINDINGS_RESET_CONTROLLER_HI6220*/
In Guodong's rebase tree, an updated version of the reset driver has been added, along with support to reset some of the clks. This is necessary for the future drm driver resync to work. Signed-off-by: John Stultz <john.stultz@linaro.org> --- drivers/clk/hisilicon/clk-hi6220.c | 15 +-- drivers/reset/hisilicon/hi6220_reset.c | 135 +++++++++++++++++-------- include/dt-bindings/reset/hisi,hi6220-resets.h | 8 ++ 3 files changed, 106 insertions(+), 52 deletions(-) -- 1.9.1