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 RK3328_GRF_SOC_CON4 0x410
59 static const struct rockchip_grf_value rk3328_defaults
[] __initconst
= {
60 { "jtag switching", RK3328_GRF_SOC_CON4
, HIWORD_UPDATE(0, 1, 12) },
63 static const struct rockchip_grf_info rk3328_grf __initconst
= {
64 .values
= rk3328_defaults
,
65 .num_values
= ARRAY_SIZE(rk3328_defaults
),
68 #define RK3368_GRF_SOC_CON15 0x43c
70 static const struct rockchip_grf_value rk3368_defaults
[] __initconst
= {
71 { "jtag switching", RK3368_GRF_SOC_CON15
, HIWORD_UPDATE(0, 1, 13) },
74 static const struct rockchip_grf_info rk3368_grf __initconst
= {
75 .values
= rk3368_defaults
,
76 .num_values
= ARRAY_SIZE(rk3368_defaults
),
79 #define RK3399_GRF_SOC_CON7 0xe21c
81 static const struct rockchip_grf_value rk3399_defaults
[] __initconst
= {
82 { "jtag switching", RK3399_GRF_SOC_CON7
, HIWORD_UPDATE(0, 1, 12) },
85 static const struct rockchip_grf_info rk3399_grf __initconst
= {
86 .values
= rk3399_defaults
,
87 .num_values
= ARRAY_SIZE(rk3399_defaults
),
90 static const struct of_device_id rockchip_grf_dt_match
[] __initconst
= {
92 .compatible
= "rockchip,rk3036-grf",
93 .data
= (void *)&rk3036_grf
,
95 .compatible
= "rockchip,rk3288-grf",
96 .data
= (void *)&rk3288_grf
,
98 .compatible
= "rockchip,rk3328-grf",
99 .data
= (void *)&rk3328_grf
,
101 .compatible
= "rockchip,rk3368-grf",
102 .data
= (void *)&rk3368_grf
,
104 .compatible
= "rockchip,rk3399-grf",
105 .data
= (void *)&rk3399_grf
,
110 static int __init
rockchip_grf_init(void)
112 const struct rockchip_grf_info
*grf_info
;
113 const struct of_device_id
*match
;
114 struct device_node
*np
;
118 np
= of_find_matching_node_and_match(NULL
, rockchip_grf_dt_match
,
122 if (!match
|| !match
->data
) {
123 pr_err("%s: missing grf data\n", __func__
);
127 grf_info
= match
->data
;
129 grf
= syscon_node_to_regmap(np
);
131 pr_err("%s: could not get grf syscon\n", __func__
);
135 for (i
= 0; i
< grf_info
->num_values
; i
++) {
136 const struct rockchip_grf_value
*val
= &grf_info
->values
[i
];
138 pr_debug("%s: adjusting %s in %#6x to %#10x\n", __func__
,
139 val
->desc
, val
->reg
, val
->val
);
140 ret
= regmap_write(grf
, val
->reg
, val
->val
);
142 pr_err("%s: write to %#6x failed with %d\n",
143 __func__
, val
->reg
, ret
);
148 postcore_initcall(rockchip_grf_init
);