2 * Rockchip Generic Register Files setup
4 * Copyright (c) 2016 Heiko Stuebner <heiko@sntech.de>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
11 #include <linux/err.h>
12 #include <linux/mfd/syscon.h>
13 #include <linux/of_device.h>
14 #include <linux/platform_device.h>
15 #include <linux/regmap.h>
17 #define HIWORD_UPDATE(val, mask, shift) \
18 ((val) << (shift) | (mask) << ((shift) + 16))
20 struct rockchip_grf_value
{
26 struct rockchip_grf_info
{
27 const struct rockchip_grf_value
*values
;
31 #define RK3036_GRF_SOC_CON0 0x140
33 static const struct rockchip_grf_value rk3036_defaults
[] __initconst
= {
35 * Disable auto jtag/sdmmc switching that causes issues with the
36 * clock-framework and the mmc controllers making them unreliable.
38 { "jtag switching", RK3036_GRF_SOC_CON0
, HIWORD_UPDATE(0, 1, 11) },
41 static const struct rockchip_grf_info rk3036_grf __initconst
= {
42 .values
= rk3036_defaults
,
43 .num_values
= ARRAY_SIZE(rk3036_defaults
),
46 #define RK3288_GRF_SOC_CON0 0x244
48 static const struct rockchip_grf_value rk3288_defaults
[] __initconst
= {
49 { "jtag switching", RK3288_GRF_SOC_CON0
, HIWORD_UPDATE(0, 1, 12) },
52 static const struct rockchip_grf_info rk3288_grf __initconst
= {
53 .values
= rk3288_defaults
,
54 .num_values
= ARRAY_SIZE(rk3288_defaults
),
57 #define RK3368_GRF_SOC_CON15 0x43c
59 static const struct rockchip_grf_value rk3368_defaults
[] __initconst
= {
60 { "jtag switching", RK3368_GRF_SOC_CON15
, HIWORD_UPDATE(0, 1, 13) },
63 static const struct rockchip_grf_info rk3368_grf __initconst
= {
64 .values
= rk3368_defaults
,
65 .num_values
= ARRAY_SIZE(rk3368_defaults
),
68 #define RK3399_GRF_SOC_CON7 0xe21c
70 static const struct rockchip_grf_value rk3399_defaults
[] __initconst
= {
71 { "jtag switching", RK3399_GRF_SOC_CON7
, HIWORD_UPDATE(0, 1, 12) },
74 static const struct rockchip_grf_info rk3399_grf __initconst
= {
75 .values
= rk3399_defaults
,
76 .num_values
= ARRAY_SIZE(rk3399_defaults
),
79 static const struct of_device_id rockchip_grf_dt_match
[] __initconst
= {
81 .compatible
= "rockchip,rk3036-grf",
82 .data
= (void *)&rk3036_grf
,
84 .compatible
= "rockchip,rk3288-grf",
85 .data
= (void *)&rk3288_grf
,
87 .compatible
= "rockchip,rk3368-grf",
88 .data
= (void *)&rk3368_grf
,
90 .compatible
= "rockchip,rk3399-grf",
91 .data
= (void *)&rk3399_grf
,
96 static int __init
rockchip_grf_init(void)
98 const struct rockchip_grf_info
*grf_info
;
99 const struct of_device_id
*match
;
100 struct device_node
*np
;
104 np
= of_find_matching_node_and_match(NULL
, rockchip_grf_dt_match
,
108 if (!match
|| !match
->data
) {
109 pr_err("%s: missing grf data\n", __func__
);
113 grf_info
= match
->data
;
115 grf
= syscon_node_to_regmap(np
);
117 pr_err("%s: could not get grf syscon\n", __func__
);
121 for (i
= 0; i
< grf_info
->num_values
; i
++) {
122 const struct rockchip_grf_value
*val
= &grf_info
->values
[i
];
124 pr_debug("%s: adjusting %s in %#6x to %#10x\n", __func__
,
125 val
->desc
, val
->reg
, val
->val
);
126 ret
= regmap_write(grf
, val
->reg
, val
->val
);
128 pr_err("%s: write to %#6x failed with %d\n",
129 __func__
, val
->reg
, ret
);
134 postcore_initcall(rockchip_grf_init
);