Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Driver for Renesas 9-series PCIe clock generator driver
0004  *
0005  * The following series can be supported:
0006  *   - 9FGV/9DBV/9DMV/9FGL/9DML/9QXL/9SQ
0007  * Currently supported:
0008  *   - 9FGV0241
0009  *
0010  * Copyright (C) 2022 Marek Vasut <marex@denx.de>
0011  */
0012 
0013 #include <linux/clk-provider.h>
0014 #include <linux/i2c.h>
0015 #include <linux/mod_devicetable.h>
0016 #include <linux/module.h>
0017 #include <linux/of.h>
0018 #include <linux/regmap.h>
0019 
0020 #define RS9_REG_OE              0x0
0021 #define RS9_REG_OE_DIF_OE(n)            BIT((n) + 1)
0022 #define RS9_REG_SS              0x1
0023 #define RS9_REG_SS_AMP_0V6          0x0
0024 #define RS9_REG_SS_AMP_0V7          0x1
0025 #define RS9_REG_SS_AMP_0V8          0x2
0026 #define RS9_REG_SS_AMP_0V9          0x3
0027 #define RS9_REG_SS_AMP_MASK         0x3
0028 #define RS9_REG_SS_SSC_100          0
0029 #define RS9_REG_SS_SSC_M025         (1 << 3)
0030 #define RS9_REG_SS_SSC_M050         (3 << 3)
0031 #define RS9_REG_SS_SSC_MASK         (3 << 3)
0032 #define RS9_REG_SS_SSC_LOCK         BIT(5)
0033 #define RS9_REG_SR              0x2
0034 #define RS9_REG_SR_2V0_DIF(n)           0
0035 #define RS9_REG_SR_3V0_DIF(n)           BIT((n) + 1)
0036 #define RS9_REG_SR_DIF_MASK(n)      BIT((n) + 1)
0037 #define RS9_REG_REF             0x3
0038 #define RS9_REG_REF_OE              BIT(4)
0039 #define RS9_REG_REF_OD              BIT(5)
0040 #define RS9_REG_REF_SR_SLOWEST          0
0041 #define RS9_REG_REF_SR_SLOW         (1 << 6)
0042 #define RS9_REG_REF_SR_FAST         (2 << 6)
0043 #define RS9_REG_REF_SR_FASTER           (3 << 6)
0044 #define RS9_REG_VID             0x5
0045 #define RS9_REG_DID             0x6
0046 #define RS9_REG_BCP             0x7
0047 
0048 /* Supported Renesas 9-series models. */
0049 enum rs9_model {
0050     RENESAS_9FGV0241,
0051 };
0052 
0053 /* Structure to describe features of a particular 9-series model */
0054 struct rs9_chip_info {
0055     const enum rs9_model    model;
0056     unsigned int        num_clks;
0057 };
0058 
0059 struct rs9_driver_data {
0060     struct i2c_client   *client;
0061     struct regmap       *regmap;
0062     const struct rs9_chip_info *chip_info;
0063     struct clk      *pin_xin;
0064     struct clk_hw       *clk_dif[2];
0065     u8          pll_amplitude;
0066     u8          pll_ssc;
0067     u8          clk_dif_sr;
0068 };
0069 
0070 /*
0071  * Renesas 9-series i2c regmap
0072  */
0073 static const struct regmap_range rs9_readable_ranges[] = {
0074     regmap_reg_range(RS9_REG_OE, RS9_REG_REF),
0075     regmap_reg_range(RS9_REG_VID, RS9_REG_BCP),
0076 };
0077 
0078 static const struct regmap_access_table rs9_readable_table = {
0079     .yes_ranges = rs9_readable_ranges,
0080     .n_yes_ranges = ARRAY_SIZE(rs9_readable_ranges),
0081 };
0082 
0083 static const struct regmap_range rs9_writeable_ranges[] = {
0084     regmap_reg_range(RS9_REG_OE, RS9_REG_REF),
0085     regmap_reg_range(RS9_REG_BCP, RS9_REG_BCP),
0086 };
0087 
0088 static const struct regmap_access_table rs9_writeable_table = {
0089     .yes_ranges = rs9_writeable_ranges,
0090     .n_yes_ranges = ARRAY_SIZE(rs9_writeable_ranges),
0091 };
0092 
0093 static const struct regmap_config rs9_regmap_config = {
0094     .reg_bits = 8,
0095     .val_bits = 8,
0096     .cache_type = REGCACHE_FLAT,
0097     .max_register = 0x8,
0098     .rd_table = &rs9_readable_table,
0099     .wr_table = &rs9_writeable_table,
0100 };
0101 
0102 static int rs9_get_output_config(struct rs9_driver_data *rs9, int idx)
0103 {
0104     struct i2c_client *client = rs9->client;
0105     unsigned char name[5] = "DIF0";
0106     struct device_node *np;
0107     int ret;
0108     u32 sr;
0109 
0110     /* Set defaults */
0111     rs9->clk_dif_sr &= ~RS9_REG_SR_DIF_MASK(idx);
0112     rs9->clk_dif_sr |= RS9_REG_SR_3V0_DIF(idx);
0113 
0114     snprintf(name, 5, "DIF%d", idx);
0115     np = of_get_child_by_name(client->dev.of_node, name);
0116     if (!np)
0117         return 0;
0118 
0119     /* Output clock slew rate */
0120     ret = of_property_read_u32(np, "renesas,slew-rate", &sr);
0121     of_node_put(np);
0122     if (!ret) {
0123         if (sr == 2000000) {        /* 2V/ns */
0124             rs9->clk_dif_sr &= ~RS9_REG_SR_DIF_MASK(idx);
0125             rs9->clk_dif_sr |= RS9_REG_SR_2V0_DIF(idx);
0126         } else if (sr == 3000000) { /* 3V/ns (default) */
0127             rs9->clk_dif_sr &= ~RS9_REG_SR_DIF_MASK(idx);
0128             rs9->clk_dif_sr |= RS9_REG_SR_3V0_DIF(idx);
0129         } else
0130             ret = dev_err_probe(&client->dev, -EINVAL,
0131                         "Invalid renesas,slew-rate value\n");
0132     }
0133 
0134     return ret;
0135 }
0136 
0137 static int rs9_get_common_config(struct rs9_driver_data *rs9)
0138 {
0139     struct i2c_client *client = rs9->client;
0140     struct device_node *np = client->dev.of_node;
0141     unsigned int amp, ssc;
0142     int ret;
0143 
0144     /* Set defaults */
0145     rs9->pll_amplitude = RS9_REG_SS_AMP_0V7;
0146     rs9->pll_ssc = RS9_REG_SS_SSC_100;
0147 
0148     /* Output clock amplitude */
0149     ret = of_property_read_u32(np, "renesas,out-amplitude-microvolt",
0150                    &amp);
0151     if (!ret) {
0152         if (amp == 600000)  /* 0.6V */
0153             rs9->pll_amplitude = RS9_REG_SS_AMP_0V6;
0154         else if (amp == 700000) /* 0.7V (default) */
0155             rs9->pll_amplitude = RS9_REG_SS_AMP_0V7;
0156         else if (amp == 800000) /* 0.8V */
0157             rs9->pll_amplitude = RS9_REG_SS_AMP_0V8;
0158         else if (amp == 900000) /* 0.9V */
0159             rs9->pll_amplitude = RS9_REG_SS_AMP_0V9;
0160         else
0161             return dev_err_probe(&client->dev, -EINVAL,
0162                          "Invalid renesas,out-amplitude-microvolt value\n");
0163     }
0164 
0165     /* Output clock spread spectrum */
0166     ret = of_property_read_u32(np, "renesas,out-spread-spectrum", &ssc);
0167     if (!ret) {
0168         if (ssc == 100000)  /* 100% ... no spread (default) */
0169             rs9->pll_ssc = RS9_REG_SS_SSC_100;
0170         else if (ssc == 99750)  /* -0.25% ... down spread */
0171             rs9->pll_ssc = RS9_REG_SS_SSC_M025;
0172         else if (ssc == 99500)  /* -0.50% ... down spread */
0173             rs9->pll_ssc = RS9_REG_SS_SSC_M050;
0174         else
0175             return dev_err_probe(&client->dev, -EINVAL,
0176                          "Invalid renesas,out-spread-spectrum value\n");
0177     }
0178 
0179     return 0;
0180 }
0181 
0182 static void rs9_update_config(struct rs9_driver_data *rs9)
0183 {
0184     int i;
0185 
0186     /* If amplitude is non-default, update it. */
0187     if (rs9->pll_amplitude != RS9_REG_SS_AMP_0V7) {
0188         regmap_update_bits(rs9->regmap, RS9_REG_SS, RS9_REG_SS_AMP_MASK,
0189                    rs9->pll_amplitude);
0190     }
0191 
0192     /* If SSC is non-default, update it. */
0193     if (rs9->pll_ssc != RS9_REG_SS_SSC_100) {
0194         regmap_update_bits(rs9->regmap, RS9_REG_SS, RS9_REG_SS_SSC_MASK,
0195                    rs9->pll_ssc);
0196     }
0197 
0198     for (i = 0; i < rs9->chip_info->num_clks; i++) {
0199         if (rs9->clk_dif_sr & RS9_REG_SR_3V0_DIF(i))
0200             continue;
0201 
0202         regmap_update_bits(rs9->regmap, RS9_REG_SR, RS9_REG_SR_3V0_DIF(i),
0203                    rs9->clk_dif_sr & RS9_REG_SR_3V0_DIF(i));
0204     }
0205 }
0206 
0207 static struct clk_hw *
0208 rs9_of_clk_get(struct of_phandle_args *clkspec, void *data)
0209 {
0210     struct rs9_driver_data *rs9 = data;
0211     unsigned int idx = clkspec->args[0];
0212 
0213     return rs9->clk_dif[idx];
0214 }
0215 
0216 static int rs9_probe(struct i2c_client *client)
0217 {
0218     unsigned char name[5] = "DIF0";
0219     struct rs9_driver_data *rs9;
0220     struct clk_hw *hw;
0221     int i, ret;
0222 
0223     rs9 = devm_kzalloc(&client->dev, sizeof(*rs9), GFP_KERNEL);
0224     if (!rs9)
0225         return -ENOMEM;
0226 
0227     i2c_set_clientdata(client, rs9);
0228     rs9->client = client;
0229     rs9->chip_info = device_get_match_data(&client->dev);
0230     if (!rs9->chip_info)
0231         return -EINVAL;
0232 
0233     /* Fetch common configuration from DT (if specified) */
0234     ret = rs9_get_common_config(rs9);
0235     if (ret)
0236         return ret;
0237 
0238     /* Fetch DIFx output configuration from DT (if specified) */
0239     for (i = 0; i < rs9->chip_info->num_clks; i++) {
0240         ret = rs9_get_output_config(rs9, i);
0241         if (ret)
0242             return ret;
0243     }
0244 
0245     rs9->regmap = devm_regmap_init_i2c(client, &rs9_regmap_config);
0246     if (IS_ERR(rs9->regmap))
0247         return dev_err_probe(&client->dev, PTR_ERR(rs9->regmap),
0248                      "Failed to allocate register map\n");
0249 
0250     /* Register clock */
0251     for (i = 0; i < rs9->chip_info->num_clks; i++) {
0252         snprintf(name, 5, "DIF%d", i);
0253         hw = devm_clk_hw_register_fixed_factor_index(&client->dev, name,
0254                             0, 0, 4, 1);
0255         if (IS_ERR(hw))
0256             return PTR_ERR(hw);
0257 
0258         rs9->clk_dif[i] = hw;
0259     }
0260 
0261     ret = devm_of_clk_add_hw_provider(&client->dev, rs9_of_clk_get, rs9);
0262     if (!ret)
0263         rs9_update_config(rs9);
0264 
0265     return ret;
0266 }
0267 
0268 static int __maybe_unused rs9_suspend(struct device *dev)
0269 {
0270     struct rs9_driver_data *rs9 = dev_get_drvdata(dev);
0271 
0272     regcache_cache_only(rs9->regmap, true);
0273     regcache_mark_dirty(rs9->regmap);
0274 
0275     return 0;
0276 }
0277 
0278 static int __maybe_unused rs9_resume(struct device *dev)
0279 {
0280     struct rs9_driver_data *rs9 = dev_get_drvdata(dev);
0281     int ret;
0282 
0283     regcache_cache_only(rs9->regmap, false);
0284     ret = regcache_sync(rs9->regmap);
0285     if (ret)
0286         dev_err(dev, "Failed to restore register map: %d\n", ret);
0287     return ret;
0288 }
0289 
0290 static const struct rs9_chip_info renesas_9fgv0241_info = {
0291     .model      = RENESAS_9FGV0241,
0292     .num_clks   = 2,
0293 };
0294 
0295 static const struct i2c_device_id rs9_id[] = {
0296     { "9fgv0241", .driver_data = RENESAS_9FGV0241 },
0297     { }
0298 };
0299 MODULE_DEVICE_TABLE(i2c, rs9_id);
0300 
0301 static const struct of_device_id clk_rs9_of_match[] = {
0302     { .compatible = "renesas,9fgv0241", .data = &renesas_9fgv0241_info },
0303     { }
0304 };
0305 MODULE_DEVICE_TABLE(of, clk_rs9_of_match);
0306 
0307 static SIMPLE_DEV_PM_OPS(rs9_pm_ops, rs9_suspend, rs9_resume);
0308 
0309 static struct i2c_driver rs9_driver = {
0310     .driver = {
0311         .name = "clk-renesas-pcie-9series",
0312         .pm = &rs9_pm_ops,
0313         .of_match_table = clk_rs9_of_match,
0314     },
0315     .probe_new  = rs9_probe,
0316     .id_table   = rs9_id,
0317 };
0318 module_i2c_driver(rs9_driver);
0319 
0320 MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
0321 MODULE_DESCRIPTION("Renesas 9-series PCIe clock generator driver");
0322 MODULE_LICENSE("GPL");