0001
0002
0003
0004
0005
0006
0007
0008 #include <linux/err.h>
0009 #include <linux/mfd/syscon.h>
0010 #include <linux/of_device.h>
0011 #include <linux/platform_device.h>
0012 #include <linux/regmap.h>
0013
0014 #define HIWORD_UPDATE(val, mask, shift) \
0015 ((val) << (shift) | (mask) << ((shift) + 16))
0016
0017 struct rockchip_grf_value {
0018 const char *desc;
0019 u32 reg;
0020 u32 val;
0021 };
0022
0023 struct rockchip_grf_info {
0024 const struct rockchip_grf_value *values;
0025 int num_values;
0026 };
0027
0028 #define RK3036_GRF_SOC_CON0 0x140
0029
0030 static const struct rockchip_grf_value rk3036_defaults[] __initconst = {
0031
0032
0033
0034
0035 { "jtag switching", RK3036_GRF_SOC_CON0, HIWORD_UPDATE(0, 1, 11) },
0036 };
0037
0038 static const struct rockchip_grf_info rk3036_grf __initconst = {
0039 .values = rk3036_defaults,
0040 .num_values = ARRAY_SIZE(rk3036_defaults),
0041 };
0042
0043 #define RK3128_GRF_SOC_CON0 0x140
0044
0045 static const struct rockchip_grf_value rk3128_defaults[] __initconst = {
0046 { "jtag switching", RK3128_GRF_SOC_CON0, HIWORD_UPDATE(0, 1, 8) },
0047 };
0048
0049 static const struct rockchip_grf_info rk3128_grf __initconst = {
0050 .values = rk3128_defaults,
0051 .num_values = ARRAY_SIZE(rk3128_defaults),
0052 };
0053
0054 #define RK3228_GRF_SOC_CON6 0x418
0055
0056 static const struct rockchip_grf_value rk3228_defaults[] __initconst = {
0057 { "jtag switching", RK3228_GRF_SOC_CON6, HIWORD_UPDATE(0, 1, 8) },
0058 };
0059
0060 static const struct rockchip_grf_info rk3228_grf __initconst = {
0061 .values = rk3228_defaults,
0062 .num_values = ARRAY_SIZE(rk3228_defaults),
0063 };
0064
0065 #define RK3288_GRF_SOC_CON0 0x244
0066 #define RK3288_GRF_SOC_CON2 0x24c
0067
0068 static const struct rockchip_grf_value rk3288_defaults[] __initconst = {
0069 { "jtag switching", RK3288_GRF_SOC_CON0, HIWORD_UPDATE(0, 1, 12) },
0070 { "pwm select", RK3288_GRF_SOC_CON2, HIWORD_UPDATE(1, 1, 0) },
0071 };
0072
0073 static const struct rockchip_grf_info rk3288_grf __initconst = {
0074 .values = rk3288_defaults,
0075 .num_values = ARRAY_SIZE(rk3288_defaults),
0076 };
0077
0078 #define RK3328_GRF_SOC_CON4 0x410
0079
0080 static const struct rockchip_grf_value rk3328_defaults[] __initconst = {
0081 { "jtag switching", RK3328_GRF_SOC_CON4, HIWORD_UPDATE(0, 1, 12) },
0082 };
0083
0084 static const struct rockchip_grf_info rk3328_grf __initconst = {
0085 .values = rk3328_defaults,
0086 .num_values = ARRAY_SIZE(rk3328_defaults),
0087 };
0088
0089 #define RK3368_GRF_SOC_CON15 0x43c
0090
0091 static const struct rockchip_grf_value rk3368_defaults[] __initconst = {
0092 { "jtag switching", RK3368_GRF_SOC_CON15, HIWORD_UPDATE(0, 1, 13) },
0093 };
0094
0095 static const struct rockchip_grf_info rk3368_grf __initconst = {
0096 .values = rk3368_defaults,
0097 .num_values = ARRAY_SIZE(rk3368_defaults),
0098 };
0099
0100 #define RK3399_GRF_SOC_CON7 0xe21c
0101
0102 static const struct rockchip_grf_value rk3399_defaults[] __initconst = {
0103 { "jtag switching", RK3399_GRF_SOC_CON7, HIWORD_UPDATE(0, 1, 12) },
0104 };
0105
0106 static const struct rockchip_grf_info rk3399_grf __initconst = {
0107 .values = rk3399_defaults,
0108 .num_values = ARRAY_SIZE(rk3399_defaults),
0109 };
0110
0111 #define RK3566_GRF_USB3OTG0_CON1 0x0104
0112
0113 static const struct rockchip_grf_value rk3566_defaults[] __initconst = {
0114 { "usb3otg port switch", RK3566_GRF_USB3OTG0_CON1, HIWORD_UPDATE(0, 1, 12) },
0115 { "usb3otg clock switch", RK3566_GRF_USB3OTG0_CON1, HIWORD_UPDATE(1, 1, 7) },
0116 { "usb3otg disable usb3", RK3566_GRF_USB3OTG0_CON1, HIWORD_UPDATE(1, 1, 0) },
0117 };
0118
0119 static const struct rockchip_grf_info rk3566_pipegrf __initconst = {
0120 .values = rk3566_defaults,
0121 .num_values = ARRAY_SIZE(rk3566_defaults),
0122 };
0123
0124
0125 static const struct of_device_id rockchip_grf_dt_match[] __initconst = {
0126 {
0127 .compatible = "rockchip,rk3036-grf",
0128 .data = (void *)&rk3036_grf,
0129 }, {
0130 .compatible = "rockchip,rk3128-grf",
0131 .data = (void *)&rk3128_grf,
0132 }, {
0133 .compatible = "rockchip,rk3228-grf",
0134 .data = (void *)&rk3228_grf,
0135 }, {
0136 .compatible = "rockchip,rk3288-grf",
0137 .data = (void *)&rk3288_grf,
0138 }, {
0139 .compatible = "rockchip,rk3328-grf",
0140 .data = (void *)&rk3328_grf,
0141 }, {
0142 .compatible = "rockchip,rk3368-grf",
0143 .data = (void *)&rk3368_grf,
0144 }, {
0145 .compatible = "rockchip,rk3399-grf",
0146 .data = (void *)&rk3399_grf,
0147 }, {
0148 .compatible = "rockchip,rk3566-pipe-grf",
0149 .data = (void *)&rk3566_pipegrf,
0150 },
0151 { },
0152 };
0153
0154 static int __init rockchip_grf_init(void)
0155 {
0156 const struct rockchip_grf_info *grf_info;
0157 const struct of_device_id *match;
0158 struct device_node *np;
0159 struct regmap *grf;
0160 int ret, i;
0161
0162 np = of_find_matching_node_and_match(NULL, rockchip_grf_dt_match,
0163 &match);
0164 if (!np)
0165 return -ENODEV;
0166 if (!match || !match->data) {
0167 pr_err("%s: missing grf data\n", __func__);
0168 of_node_put(np);
0169 return -EINVAL;
0170 }
0171
0172 grf_info = match->data;
0173
0174 grf = syscon_node_to_regmap(np);
0175 of_node_put(np);
0176 if (IS_ERR(grf)) {
0177 pr_err("%s: could not get grf syscon\n", __func__);
0178 return PTR_ERR(grf);
0179 }
0180
0181 for (i = 0; i < grf_info->num_values; i++) {
0182 const struct rockchip_grf_value *val = &grf_info->values[i];
0183
0184 pr_debug("%s: adjusting %s in %#6x to %#10x\n", __func__,
0185 val->desc, val->reg, val->val);
0186 ret = regmap_write(grf, val->reg, val->val);
0187 if (ret < 0)
0188 pr_err("%s: write to %#6x failed with %d\n",
0189 __func__, val->reg, ret);
0190 }
0191
0192 return 0;
0193 }
0194 postcore_initcall(rockchip_grf_init);