Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Rockchip Generic Register Files setup
0004  *
0005  * Copyright (c) 2016 Heiko Stuebner <heiko@sntech.de>
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      * Disable auto jtag/sdmmc switching that causes issues with the
0033      * clock-framework and the mmc controllers making them unreliable.
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     { /* sentinel */ },
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);