forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 61598093bbdd283a7edc367d900f223070ead8d2
kernel/drivers/clk/tegra/clk-dfll.c
....@@ -1,19 +1,11 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * clk-dfll.c - Tegra DFLL clock source common code
34 *
4
- * Copyright (C) 2012-2014 NVIDIA Corporation. All rights reserved.
5
+ * Copyright (C) 2012-2019 NVIDIA Corporation. All rights reserved.
56 *
67 * Aleksandr Frid <afrid@nvidia.com>
78 * Paul Walmsley <pwalmsley@nvidia.com>
8
- *
9
- * This program is free software; you can redistribute it and/or modify
10
- * it under the terms of the GNU General Public License version 2 as
11
- * published by the Free Software Foundation.
12
- *
13
- * This program is distributed in the hope that it will be useful, but WITHOUT
14
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16
- * more details.
179 *
1810 * This library is for the DVCO and DFLL IP blocks on the Tegra124
1911 * SoC. These IP blocks together are also known at NVIDIA as
....@@ -34,7 +26,6 @@
3426 * CPU cycle time will vary. This has implications for
3527 * performance-measurement code and any code that relies on the CPU
3628 * cycle time to delay for a certain length of time.
37
- *
3829 */
3930
4031 #include <linux/clk.h>
....@@ -47,6 +38,7 @@
4738 #include <linux/kernel.h>
4839 #include <linux/module.h>
4940 #include <linux/of.h>
41
+#include <linux/pinctrl/consumer.h>
5042 #include <linux/pm_opp.h>
5143 #include <linux/pm_runtime.h>
5244 #include <linux/regmap.h>
....@@ -243,6 +235,12 @@
243235 DFLL_TUNE_LOW = 1,
244236 };
245237
238
+
239
+enum tegra_dfll_pmu_if {
240
+ TEGRA_DFLL_PMU_I2C = 0,
241
+ TEGRA_DFLL_PMU_PWM = 1,
242
+};
243
+
246244 /**
247245 * struct dfll_rate_req - target DFLL rate request data
248246 * @rate: target frequency, after the postscaling
....@@ -300,10 +298,19 @@
300298 u32 i2c_reg;
301299 u32 i2c_slave_addr;
302300
303
- /* i2c_lut array entries are regulator framework selectors */
304
- unsigned i2c_lut[MAX_DFLL_VOLTAGES];
305
- int i2c_lut_size;
306
- u8 lut_min, lut_max, lut_safe;
301
+ /* lut array entries are regulator framework selectors or PWM values*/
302
+ unsigned lut[MAX_DFLL_VOLTAGES];
303
+ unsigned long lut_uv[MAX_DFLL_VOLTAGES];
304
+ int lut_size;
305
+ u8 lut_bottom, lut_min, lut_max, lut_safe;
306
+
307
+ /* PWM interface */
308
+ enum tegra_dfll_pmu_if pmu_if;
309
+ unsigned long pwm_rate;
310
+ struct pinctrl *pwm_pin;
311
+ struct pinctrl_state *pwm_enable_state;
312
+ struct pinctrl_state *pwm_disable_state;
313
+ u32 reg_init_uV;
307314 };
308315
309316 #define clk_hw_to_dfll(_hw) container_of(_hw, struct tegra_dfll, dfll_clk_hw)
....@@ -490,6 +497,34 @@
490497 }
491498
492499 /*
500
+ * DVCO rate control
501
+ */
502
+
503
+static unsigned long get_dvco_rate_below(struct tegra_dfll *td, u8 out_min)
504
+{
505
+ struct dev_pm_opp *opp;
506
+ unsigned long rate, prev_rate;
507
+ unsigned long uv, min_uv;
508
+
509
+ min_uv = td->lut_uv[out_min];
510
+ for (rate = 0, prev_rate = 0; ; rate++) {
511
+ opp = dev_pm_opp_find_freq_ceil(td->soc->dev, &rate);
512
+ if (IS_ERR(opp))
513
+ break;
514
+
515
+ uv = dev_pm_opp_get_voltage(opp);
516
+ dev_pm_opp_put(opp);
517
+
518
+ if (uv && uv > min_uv)
519
+ return prev_rate;
520
+
521
+ prev_rate = rate;
522
+ }
523
+
524
+ return prev_rate;
525
+}
526
+
527
+/*
493528 * DFLL-to-I2C controller interface
494529 */
495530
....@@ -518,6 +553,118 @@
518553 return 0;
519554 }
520555
556
+
557
+/*
558
+ * DFLL-to-PWM controller interface
559
+ */
560
+
561
+/**
562
+ * dfll_pwm_set_output_enabled - enable/disable PWM voltage requests
563
+ * @td: DFLL instance
564
+ * @enable: whether to enable or disable the PWM voltage requests
565
+ *
566
+ * Set the master enable control for PWM control value updates. If disabled,
567
+ * then the PWM signal is not driven. Also configure the PWM output pad
568
+ * to the appropriate state.
569
+ */
570
+static int dfll_pwm_set_output_enabled(struct tegra_dfll *td, bool enable)
571
+{
572
+ int ret;
573
+ u32 val, div;
574
+
575
+ if (enable) {
576
+ ret = pinctrl_select_state(td->pwm_pin, td->pwm_enable_state);
577
+ if (ret < 0) {
578
+ dev_err(td->dev, "setting enable state failed\n");
579
+ return -EINVAL;
580
+ }
581
+ val = dfll_readl(td, DFLL_OUTPUT_CFG);
582
+ val &= ~DFLL_OUTPUT_CFG_PWM_DIV_MASK;
583
+ div = DIV_ROUND_UP(td->ref_rate, td->pwm_rate);
584
+ val |= (div << DFLL_OUTPUT_CFG_PWM_DIV_SHIFT)
585
+ & DFLL_OUTPUT_CFG_PWM_DIV_MASK;
586
+ dfll_writel(td, val, DFLL_OUTPUT_CFG);
587
+ dfll_wmb(td);
588
+
589
+ val |= DFLL_OUTPUT_CFG_PWM_ENABLE;
590
+ dfll_writel(td, val, DFLL_OUTPUT_CFG);
591
+ dfll_wmb(td);
592
+ } else {
593
+ ret = pinctrl_select_state(td->pwm_pin, td->pwm_disable_state);
594
+ if (ret < 0)
595
+ dev_warn(td->dev, "setting disable state failed\n");
596
+
597
+ val = dfll_readl(td, DFLL_OUTPUT_CFG);
598
+ val &= ~DFLL_OUTPUT_CFG_PWM_ENABLE;
599
+ dfll_writel(td, val, DFLL_OUTPUT_CFG);
600
+ dfll_wmb(td);
601
+ }
602
+
603
+ return 0;
604
+}
605
+
606
+/**
607
+ * dfll_set_force_output_value - set fixed value for force output
608
+ * @td: DFLL instance
609
+ * @out_val: value to force output
610
+ *
611
+ * Set the fixed value for force output, DFLL will output this value when
612
+ * force output is enabled.
613
+ */
614
+static u32 dfll_set_force_output_value(struct tegra_dfll *td, u8 out_val)
615
+{
616
+ u32 val = dfll_readl(td, DFLL_OUTPUT_FORCE);
617
+
618
+ val = (val & DFLL_OUTPUT_FORCE_ENABLE) | (out_val & OUT_MASK);
619
+ dfll_writel(td, val, DFLL_OUTPUT_FORCE);
620
+ dfll_wmb(td);
621
+
622
+ return dfll_readl(td, DFLL_OUTPUT_FORCE);
623
+}
624
+
625
+/**
626
+ * dfll_set_force_output_enabled - enable/disable force output
627
+ * @td: DFLL instance
628
+ * @enable: whether to enable or disable the force output
629
+ *
630
+ * Set the enable control for fouce output with fixed value.
631
+ */
632
+static void dfll_set_force_output_enabled(struct tegra_dfll *td, bool enable)
633
+{
634
+ u32 val = dfll_readl(td, DFLL_OUTPUT_FORCE);
635
+
636
+ if (enable)
637
+ val |= DFLL_OUTPUT_FORCE_ENABLE;
638
+ else
639
+ val &= ~DFLL_OUTPUT_FORCE_ENABLE;
640
+
641
+ dfll_writel(td, val, DFLL_OUTPUT_FORCE);
642
+ dfll_wmb(td);
643
+}
644
+
645
+/**
646
+ * dfll_force_output - force output a fixed value
647
+ * @td: DFLL instance
648
+ * @out_sel: value to force output
649
+ *
650
+ * Set the fixed value for force output, DFLL will output this value.
651
+ */
652
+static int dfll_force_output(struct tegra_dfll *td, unsigned int out_sel)
653
+{
654
+ u32 val;
655
+
656
+ if (out_sel > OUT_MASK)
657
+ return -EINVAL;
658
+
659
+ val = dfll_set_force_output_value(td, out_sel);
660
+ if ((td->mode < DFLL_CLOSED_LOOP) &&
661
+ !(val & DFLL_OUTPUT_FORCE_ENABLE)) {
662
+ dfll_set_force_output_enabled(td, true);
663
+ }
664
+
665
+ return 0;
666
+}
667
+
521668 /**
522669 * dfll_load_lut - load the voltage lookup table
523670 * @td: struct tegra_dfll *
....@@ -539,7 +686,7 @@
539686 lut_index = i;
540687
541688 val = regulator_list_hardware_vsel(td->vdd_reg,
542
- td->i2c_lut[lut_index]);
689
+ td->lut[lut_index]);
543690 __raw_writel(val, td->lut_base + i * 4);
544691 }
545692
....@@ -594,24 +741,41 @@
594741 {
595742 u32 val;
596743
597
- td->lut_min = 0;
598
- td->lut_max = td->i2c_lut_size - 1;
599
- td->lut_safe = td->lut_min + 1;
744
+ td->lut_min = td->lut_bottom;
745
+ td->lut_max = td->lut_size - 1;
746
+ td->lut_safe = td->lut_min + (td->lut_min < td->lut_max ? 1 : 0);
600747
601
- dfll_i2c_writel(td, 0, DFLL_OUTPUT_CFG);
748
+ /* clear DFLL_OUTPUT_CFG before setting new value */
749
+ dfll_writel(td, 0, DFLL_OUTPUT_CFG);
750
+ dfll_wmb(td);
751
+
602752 val = (td->lut_safe << DFLL_OUTPUT_CFG_SAFE_SHIFT) |
603
- (td->lut_max << DFLL_OUTPUT_CFG_MAX_SHIFT) |
604
- (td->lut_min << DFLL_OUTPUT_CFG_MIN_SHIFT);
605
- dfll_i2c_writel(td, val, DFLL_OUTPUT_CFG);
606
- dfll_i2c_wmb(td);
753
+ (td->lut_max << DFLL_OUTPUT_CFG_MAX_SHIFT) |
754
+ (td->lut_min << DFLL_OUTPUT_CFG_MIN_SHIFT);
755
+ dfll_writel(td, val, DFLL_OUTPUT_CFG);
756
+ dfll_wmb(td);
607757
608758 dfll_writel(td, 0, DFLL_OUTPUT_FORCE);
609759 dfll_i2c_writel(td, 0, DFLL_INTR_EN);
610760 dfll_i2c_writel(td, DFLL_INTR_MAX_MASK | DFLL_INTR_MIN_MASK,
611761 DFLL_INTR_STS);
612762
613
- dfll_load_i2c_lut(td);
614
- dfll_init_i2c_if(td);
763
+ if (td->pmu_if == TEGRA_DFLL_PMU_PWM) {
764
+ u32 vinit = td->reg_init_uV;
765
+ int vstep = td->soc->alignment.step_uv;
766
+ unsigned long vmin = td->lut_uv[0];
767
+
768
+ /* set initial voltage */
769
+ if ((vinit >= vmin) && vstep) {
770
+ unsigned int vsel;
771
+
772
+ vsel = DIV_ROUND_UP((vinit - vmin), vstep);
773
+ dfll_force_output(td, vsel);
774
+ }
775
+ } else {
776
+ dfll_load_i2c_lut(td);
777
+ dfll_init_i2c_if(td);
778
+ }
615779 }
616780
617781 /*
....@@ -631,17 +795,17 @@
631795 static int find_lut_index_for_rate(struct tegra_dfll *td, unsigned long rate)
632796 {
633797 struct dev_pm_opp *opp;
634
- int i, uv;
798
+ int i, align_step;
635799
636800 opp = dev_pm_opp_find_freq_ceil(td->soc->dev, &rate);
637801 if (IS_ERR(opp))
638802 return PTR_ERR(opp);
639803
640
- uv = dev_pm_opp_get_voltage(opp);
804
+ align_step = dev_pm_opp_get_voltage(opp) / td->soc->alignment.step_uv;
641805 dev_pm_opp_put(opp);
642806
643
- for (i = 0; i < td->i2c_lut_size; i++) {
644
- if (regulator_list_voltage(td->vdd_reg, td->i2c_lut[i]) == uv)
807
+ for (i = td->lut_bottom; i < td->lut_size; i++) {
808
+ if ((td->lut_uv[i] / td->soc->alignment.step_uv) >= align_step)
645809 return i;
646810 }
647811
....@@ -863,9 +1027,14 @@
8631027 return -EINVAL;
8641028 }
8651029
866
- dfll_i2c_set_output_enabled(td, true);
1030
+ if (td->pmu_if == TEGRA_DFLL_PMU_PWM)
1031
+ dfll_pwm_set_output_enabled(td, true);
1032
+ else
1033
+ dfll_i2c_set_output_enabled(td, true);
1034
+
8671035 dfll_set_mode(td, DFLL_CLOSED_LOOP);
8681036 dfll_set_frequency_request(td, req);
1037
+ dfll_set_force_output_enabled(td, false);
8691038 return 0;
8701039
8711040 default:
....@@ -889,7 +1058,10 @@
8891058 case DFLL_CLOSED_LOOP:
8901059 dfll_set_open_loop_config(td);
8911060 dfll_set_mode(td, DFLL_OPEN_LOOP);
892
- dfll_i2c_set_output_enabled(td, false);
1061
+ if (td->pmu_if == TEGRA_DFLL_PMU_PWM)
1062
+ dfll_pwm_set_output_enabled(td, false);
1063
+ else
1064
+ dfll_i2c_set_output_enabled(td, false);
8931065 return 0;
8941066
8951067 case DFLL_OPEN_LOOP:
....@@ -1112,8 +1284,8 @@
11121284
11131285 return val ? dfll_enable(td) : dfll_disable(td);
11141286 }
1115
-DEFINE_SIMPLE_ATTRIBUTE(enable_fops, attr_enable_get, attr_enable_set,
1116
- "%llu\n");
1287
+DEFINE_DEBUGFS_ATTRIBUTE(enable_fops, attr_enable_get, attr_enable_set,
1288
+ "%llu\n");
11171289
11181290 static int attr_lock_get(void *data, u64 *val)
11191291 {
....@@ -1129,8 +1301,7 @@
11291301
11301302 return val ? dfll_lock(td) : dfll_unlock(td);
11311303 }
1132
-DEFINE_SIMPLE_ATTRIBUTE(lock_fops, attr_lock_get, attr_lock_set,
1133
- "%llu\n");
1304
+DEFINE_DEBUGFS_ATTRIBUTE(lock_fops, attr_lock_get, attr_lock_set, "%llu\n");
11341305
11351306 static int attr_rate_get(void *data, u64 *val)
11361307 {
....@@ -1147,7 +1318,7 @@
11471318
11481319 return dfll_request_rate(td, val);
11491320 }
1150
-DEFINE_SIMPLE_ATTRIBUTE(rate_fops, attr_rate_get, attr_rate_set, "%llu\n");
1321
+DEFINE_DEBUGFS_ATTRIBUTE(rate_fops, attr_rate_get, attr_rate_set, "%llu\n");
11511322
11521323 static int attr_registers_show(struct seq_file *s, void *data)
11531324 {
....@@ -1171,30 +1342,22 @@
11711342 seq_printf(s, "[0x%02x] = 0x%08x\n", offs,
11721343 dfll_i2c_readl(td, offs));
11731344
1174
- seq_puts(s, "\nINTEGRATED I2C CONTROLLER REGISTERS:\n");
1175
- offs = DFLL_I2C_CLK_DIVISOR;
1176
- seq_printf(s, "[0x%02x] = 0x%08x\n", offs,
1177
- __raw_readl(td->i2c_controller_base + offs));
1178
-
1179
- seq_puts(s, "\nLUT:\n");
1180
- for (offs = 0; offs < 4 * MAX_DFLL_VOLTAGES; offs += 4)
1345
+ if (td->pmu_if == TEGRA_DFLL_PMU_I2C) {
1346
+ seq_puts(s, "\nINTEGRATED I2C CONTROLLER REGISTERS:\n");
1347
+ offs = DFLL_I2C_CLK_DIVISOR;
11811348 seq_printf(s, "[0x%02x] = 0x%08x\n", offs,
1182
- __raw_readl(td->lut_base + offs));
1349
+ __raw_readl(td->i2c_controller_base + offs));
1350
+
1351
+ seq_puts(s, "\nLUT:\n");
1352
+ for (offs = 0; offs < 4 * MAX_DFLL_VOLTAGES; offs += 4)
1353
+ seq_printf(s, "[0x%02x] = 0x%08x\n", offs,
1354
+ __raw_readl(td->lut_base + offs));
1355
+ }
11831356
11841357 return 0;
11851358 }
11861359
1187
-static int attr_registers_open(struct inode *inode, struct file *file)
1188
-{
1189
- return single_open(file, attr_registers_show, inode->i_private);
1190
-}
1191
-
1192
-static const struct file_operations attr_registers_fops = {
1193
- .open = attr_registers_open,
1194
- .read = seq_read,
1195
- .llseek = seq_lseek,
1196
- .release = single_release,
1197
-};
1360
+DEFINE_SHOW_ATTRIBUTE(attr_registers);
11981361
11991362 static void dfll_debug_init(struct tegra_dfll *td)
12001363 {
....@@ -1206,10 +1369,11 @@
12061369 root = debugfs_create_dir("tegra_dfll_fcpu", NULL);
12071370 td->debugfs_dir = root;
12081371
1209
- debugfs_create_file("enable", S_IRUGO | S_IWUSR, root, td, &enable_fops);
1210
- debugfs_create_file("lock", S_IRUGO, root, td, &lock_fops);
1211
- debugfs_create_file("rate", S_IRUGO, root, td, &rate_fops);
1212
- debugfs_create_file("registers", S_IRUGO, root, td, &attr_registers_fops);
1372
+ debugfs_create_file_unsafe("enable", 0644, root, td,
1373
+ &enable_fops);
1374
+ debugfs_create_file_unsafe("lock", 0444, root, td, &lock_fops);
1375
+ debugfs_create_file_unsafe("rate", 0444, root, td, &rate_fops);
1376
+ debugfs_create_file("registers", 0444, root, td, &attr_registers_fops);
12131377 }
12141378
12151379 #else
....@@ -1349,6 +1513,61 @@
13491513 return ret;
13501514 }
13511515
1516
+/**
1517
+ * tegra_dfll_suspend - check DFLL is disabled
1518
+ * @dev: DFLL instance
1519
+ *
1520
+ * DFLL clock should be disabled by the CPUFreq driver. So, make
1521
+ * sure it is disabled and disable all clocks needed by the DFLL.
1522
+ */
1523
+int tegra_dfll_suspend(struct device *dev)
1524
+{
1525
+ struct tegra_dfll *td = dev_get_drvdata(dev);
1526
+
1527
+ if (dfll_is_running(td)) {
1528
+ dev_err(td->dev, "DFLL still enabled while suspending\n");
1529
+ return -EBUSY;
1530
+ }
1531
+
1532
+ reset_control_assert(td->dvco_rst);
1533
+
1534
+ return 0;
1535
+}
1536
+EXPORT_SYMBOL(tegra_dfll_suspend);
1537
+
1538
+/**
1539
+ * tegra_dfll_resume - reinitialize DFLL on resume
1540
+ * @dev: DFLL instance
1541
+ *
1542
+ * DFLL is disabled and reset during suspend and resume.
1543
+ * So, reinitialize the DFLL IP block back for use.
1544
+ * DFLL clock is enabled later in closed loop mode by CPUFreq
1545
+ * driver before switching its clock source to DFLL output.
1546
+ */
1547
+int tegra_dfll_resume(struct device *dev)
1548
+{
1549
+ struct tegra_dfll *td = dev_get_drvdata(dev);
1550
+
1551
+ reset_control_deassert(td->dvco_rst);
1552
+
1553
+ pm_runtime_get_sync(td->dev);
1554
+
1555
+ dfll_set_mode(td, DFLL_DISABLED);
1556
+ dfll_set_default_params(td);
1557
+
1558
+ if (td->soc->init_clock_trimmers)
1559
+ td->soc->init_clock_trimmers();
1560
+
1561
+ dfll_set_open_loop_config(td);
1562
+
1563
+ dfll_init_out_if(td);
1564
+
1565
+ pm_runtime_put_sync(td->dev);
1566
+
1567
+ return 0;
1568
+}
1569
+EXPORT_SYMBOL(tegra_dfll_resume);
1570
+
13521571 /*
13531572 * DT data fetch
13541573 */
....@@ -1359,15 +1578,21 @@
13591578 */
13601579 static int find_vdd_map_entry_exact(struct tegra_dfll *td, int uV)
13611580 {
1362
- int i, n_voltages, reg_uV;
1581
+ int i, n_voltages, reg_uV,reg_volt_id, align_step;
13631582
1583
+ if (WARN_ON(td->pmu_if == TEGRA_DFLL_PMU_PWM))
1584
+ return -EINVAL;
1585
+
1586
+ align_step = uV / td->soc->alignment.step_uv;
13641587 n_voltages = regulator_count_voltages(td->vdd_reg);
13651588 for (i = 0; i < n_voltages; i++) {
13661589 reg_uV = regulator_list_voltage(td->vdd_reg, i);
13671590 if (reg_uV < 0)
13681591 break;
13691592
1370
- if (uV == reg_uV)
1593
+ reg_volt_id = reg_uV / td->soc->alignment.step_uv;
1594
+
1595
+ if (align_step == reg_volt_id)
13711596 return i;
13721597 }
13731598
....@@ -1381,15 +1606,21 @@
13811606 * */
13821607 static int find_vdd_map_entry_min(struct tegra_dfll *td, int uV)
13831608 {
1384
- int i, n_voltages, reg_uV;
1609
+ int i, n_voltages, reg_uV, reg_volt_id, align_step;
13851610
1611
+ if (WARN_ON(td->pmu_if == TEGRA_DFLL_PMU_PWM))
1612
+ return -EINVAL;
1613
+
1614
+ align_step = uV / td->soc->alignment.step_uv;
13861615 n_voltages = regulator_count_voltages(td->vdd_reg);
13871616 for (i = 0; i < n_voltages; i++) {
13881617 reg_uV = regulator_list_voltage(td->vdd_reg, i);
13891618 if (reg_uV < 0)
13901619 break;
13911620
1392
- if (uV <= reg_uV)
1621
+ reg_volt_id = reg_uV / td->soc->alignment.step_uv;
1622
+
1623
+ if (align_step <= reg_volt_id)
13931624 return i;
13941625 }
13951626
....@@ -1397,9 +1628,61 @@
13971628 return -EINVAL;
13981629 }
13991630
1631
+/*
1632
+ * dfll_build_pwm_lut - build the PWM regulator lookup table
1633
+ * @td: DFLL instance
1634
+ * @v_max: Vmax from OPP table
1635
+ *
1636
+ * Look-up table in h/w is ignored when PWM is used as DFLL interface to PMIC.
1637
+ * In this case closed loop output is controlling duty cycle directly. The s/w
1638
+ * look-up that maps PWM duty cycle to voltage is still built by this function.
1639
+ */
1640
+static int dfll_build_pwm_lut(struct tegra_dfll *td, unsigned long v_max)
1641
+{
1642
+ int i;
1643
+ unsigned long rate, reg_volt;
1644
+ u8 lut_bottom = MAX_DFLL_VOLTAGES;
1645
+ int v_min = td->soc->cvb->min_millivolts * 1000;
1646
+
1647
+ for (i = 0; i < MAX_DFLL_VOLTAGES; i++) {
1648
+ reg_volt = td->lut_uv[i];
1649
+
1650
+ /* since opp voltage is exact mv */
1651
+ reg_volt = (reg_volt / 1000) * 1000;
1652
+ if (reg_volt > v_max)
1653
+ break;
1654
+
1655
+ td->lut[i] = i;
1656
+ if ((lut_bottom == MAX_DFLL_VOLTAGES) && (reg_volt >= v_min))
1657
+ lut_bottom = i;
1658
+ }
1659
+
1660
+ /* determine voltage boundaries */
1661
+ td->lut_size = i;
1662
+ if ((lut_bottom == MAX_DFLL_VOLTAGES) ||
1663
+ (lut_bottom + 1 >= td->lut_size)) {
1664
+ dev_err(td->dev, "no voltage above DFLL minimum %d mV\n",
1665
+ td->soc->cvb->min_millivolts);
1666
+ return -EINVAL;
1667
+ }
1668
+ td->lut_bottom = lut_bottom;
1669
+
1670
+ /* determine rate boundaries */
1671
+ rate = get_dvco_rate_below(td, td->lut_bottom);
1672
+ if (!rate) {
1673
+ dev_err(td->dev, "no opp below DFLL minimum voltage %d mV\n",
1674
+ td->soc->cvb->min_millivolts);
1675
+ return -EINVAL;
1676
+ }
1677
+ td->dvco_rate_min = rate;
1678
+
1679
+ return 0;
1680
+}
1681
+
14001682 /**
14011683 * dfll_build_i2c_lut - build the I2C voltage register lookup table
14021684 * @td: DFLL instance
1685
+ * @v_max: Vmax from OPP table
14031686 *
14041687 * The DFLL hardware has 33 bytes of look-up table RAM that must be filled with
14051688 * PMIC voltage register values that span the entire DFLL operating range.
....@@ -1407,33 +1690,24 @@
14071690 * the soc-specific platform driver (td->soc->opp_dev) and the PMIC
14081691 * register-to-voltage mapping queried from the regulator framework.
14091692 *
1410
- * On success, fills in td->i2c_lut and returns 0, or -err on failure.
1693
+ * On success, fills in td->lut and returns 0, or -err on failure.
14111694 */
1412
-static int dfll_build_i2c_lut(struct tegra_dfll *td)
1695
+static int dfll_build_i2c_lut(struct tegra_dfll *td, unsigned long v_max)
14131696 {
1697
+ unsigned long rate, v, v_opp;
14141698 int ret = -EINVAL;
1415
- int j, v, v_max, v_opp;
1416
- int selector;
1417
- unsigned long rate;
1418
- struct dev_pm_opp *opp;
1419
- int lut;
1420
-
1421
- rate = ULONG_MAX;
1422
- opp = dev_pm_opp_find_freq_floor(td->soc->dev, &rate);
1423
- if (IS_ERR(opp)) {
1424
- dev_err(td->dev, "couldn't get vmax opp, empty opp table?\n");
1425
- goto out;
1426
- }
1427
- v_max = dev_pm_opp_get_voltage(opp);
1428
- dev_pm_opp_put(opp);
1699
+ int j, selector, lut;
14291700
14301701 v = td->soc->cvb->min_millivolts * 1000;
14311702 lut = find_vdd_map_entry_exact(td, v);
14321703 if (lut < 0)
14331704 goto out;
1434
- td->i2c_lut[0] = lut;
1705
+ td->lut[0] = lut;
1706
+ td->lut_bottom = 0;
14351707
14361708 for (j = 1, rate = 0; ; rate++) {
1709
+ struct dev_pm_opp *opp;
1710
+
14371711 opp = dev_pm_opp_find_freq_ceil(td->soc->dev, &rate);
14381712 if (IS_ERR(opp))
14391713 break;
....@@ -1445,37 +1719,62 @@
14451719 dev_pm_opp_put(opp);
14461720
14471721 for (;;) {
1448
- v += max(1, (v_max - v) / (MAX_DFLL_VOLTAGES - j));
1722
+ v += max(1UL, (v_max - v) / (MAX_DFLL_VOLTAGES - j));
14491723 if (v >= v_opp)
14501724 break;
14511725
14521726 selector = find_vdd_map_entry_min(td, v);
14531727 if (selector < 0)
14541728 goto out;
1455
- if (selector != td->i2c_lut[j - 1])
1456
- td->i2c_lut[j++] = selector;
1729
+ if (selector != td->lut[j - 1])
1730
+ td->lut[j++] = selector;
14571731 }
14581732
14591733 v = (j == MAX_DFLL_VOLTAGES - 1) ? v_max : v_opp;
14601734 selector = find_vdd_map_entry_exact(td, v);
14611735 if (selector < 0)
14621736 goto out;
1463
- if (selector != td->i2c_lut[j - 1])
1464
- td->i2c_lut[j++] = selector;
1737
+ if (selector != td->lut[j - 1])
1738
+ td->lut[j++] = selector;
14651739
14661740 if (v >= v_max)
14671741 break;
14681742 }
1469
- td->i2c_lut_size = j;
1743
+ td->lut_size = j;
14701744
14711745 if (!td->dvco_rate_min)
14721746 dev_err(td->dev, "no opp above DFLL minimum voltage %d mV\n",
14731747 td->soc->cvb->min_millivolts);
1474
- else
1748
+ else {
14751749 ret = 0;
1750
+ for (j = 0; j < td->lut_size; j++)
1751
+ td->lut_uv[j] =
1752
+ regulator_list_voltage(td->vdd_reg,
1753
+ td->lut[j]);
1754
+ }
14761755
14771756 out:
14781757 return ret;
1758
+}
1759
+
1760
+static int dfll_build_lut(struct tegra_dfll *td)
1761
+{
1762
+ unsigned long rate, v_max;
1763
+ struct dev_pm_opp *opp;
1764
+
1765
+ rate = ULONG_MAX;
1766
+ opp = dev_pm_opp_find_freq_floor(td->soc->dev, &rate);
1767
+ if (IS_ERR(opp)) {
1768
+ dev_err(td->dev, "couldn't get vmax opp, empty opp table?\n");
1769
+ return -EINVAL;
1770
+ }
1771
+ v_max = dev_pm_opp_get_voltage(opp);
1772
+ dev_pm_opp_put(opp);
1773
+
1774
+ if (td->pmu_if == TEGRA_DFLL_PMU_PWM)
1775
+ return dfll_build_pwm_lut(td, v_max);
1776
+ else
1777
+ return dfll_build_i2c_lut(td, v_max);
14791778 }
14801779
14811780 /**
....@@ -1536,10 +1835,55 @@
15361835 }
15371836 td->i2c_reg = vsel_reg;
15381837
1539
- ret = dfll_build_i2c_lut(td);
1540
- if (ret) {
1541
- dev_err(td->dev, "couldn't build I2C LUT\n");
1542
- return ret;
1838
+ return 0;
1839
+}
1840
+
1841
+static int dfll_fetch_pwm_params(struct tegra_dfll *td)
1842
+{
1843
+ int ret, i;
1844
+ u32 pwm_period;
1845
+
1846
+ if (!td->soc->alignment.step_uv || !td->soc->alignment.offset_uv) {
1847
+ dev_err(td->dev,
1848
+ "Missing step or alignment info for PWM regulator");
1849
+ return -EINVAL;
1850
+ }
1851
+ for (i = 0; i < MAX_DFLL_VOLTAGES; i++)
1852
+ td->lut_uv[i] = td->soc->alignment.offset_uv +
1853
+ i * td->soc->alignment.step_uv;
1854
+
1855
+ ret = read_dt_param(td, "nvidia,pwm-tristate-microvolts",
1856
+ &td->reg_init_uV);
1857
+ if (!ret) {
1858
+ dev_err(td->dev, "couldn't get initialized voltage\n");
1859
+ return -EINVAL;
1860
+ }
1861
+
1862
+ ret = read_dt_param(td, "nvidia,pwm-period-nanoseconds", &pwm_period);
1863
+ if (!ret) {
1864
+ dev_err(td->dev, "couldn't get PWM period\n");
1865
+ return -EINVAL;
1866
+ }
1867
+ td->pwm_rate = (NSEC_PER_SEC / pwm_period) * (MAX_DFLL_VOLTAGES - 1);
1868
+
1869
+ td->pwm_pin = devm_pinctrl_get(td->dev);
1870
+ if (IS_ERR(td->pwm_pin)) {
1871
+ dev_err(td->dev, "DT: missing pinctrl device\n");
1872
+ return PTR_ERR(td->pwm_pin);
1873
+ }
1874
+
1875
+ td->pwm_enable_state = pinctrl_lookup_state(td->pwm_pin,
1876
+ "dvfs_pwm_enable");
1877
+ if (IS_ERR(td->pwm_enable_state)) {
1878
+ dev_err(td->dev, "DT: missing pwm enabled state\n");
1879
+ return PTR_ERR(td->pwm_enable_state);
1880
+ }
1881
+
1882
+ td->pwm_disable_state = pinctrl_lookup_state(td->pwm_pin,
1883
+ "dvfs_pwm_disable");
1884
+ if (IS_ERR(td->pwm_disable_state)) {
1885
+ dev_err(td->dev, "DT: missing pwm disabled state\n");
1886
+ return PTR_ERR(td->pwm_disable_state);
15431887 }
15441888
15451889 return 0;
....@@ -1607,12 +1951,6 @@
16071951
16081952 td->soc = soc;
16091953
1610
- td->vdd_reg = devm_regulator_get(td->dev, "vdd-cpu");
1611
- if (IS_ERR(td->vdd_reg)) {
1612
- dev_err(td->dev, "couldn't get vdd_cpu regulator\n");
1613
- return PTR_ERR(td->vdd_reg);
1614
- }
1615
-
16161954 td->dvco_rst = devm_reset_control_get(td->dev, "dvco");
16171955 if (IS_ERR(td->dvco_rst)) {
16181956 dev_err(td->dev, "couldn't get dvco reset\n");
....@@ -1625,10 +1963,27 @@
16251963 return ret;
16261964 }
16271965
1628
- ret = dfll_fetch_i2c_params(td);
1966
+ if (of_property_read_bool(td->dev->of_node, "nvidia,pwm-to-pmic")) {
1967
+ td->pmu_if = TEGRA_DFLL_PMU_PWM;
1968
+ ret = dfll_fetch_pwm_params(td);
1969
+ } else {
1970
+ td->vdd_reg = devm_regulator_get(td->dev, "vdd-cpu");
1971
+ if (IS_ERR(td->vdd_reg)) {
1972
+ dev_err(td->dev, "couldn't get vdd_cpu regulator\n");
1973
+ return PTR_ERR(td->vdd_reg);
1974
+ }
1975
+ td->pmu_if = TEGRA_DFLL_PMU_I2C;
1976
+ ret = dfll_fetch_i2c_params(td);
1977
+ }
16291978 if (ret)
16301979 return ret;
16311980
1981
+ ret = dfll_build_lut(td);
1982
+ if (ret) {
1983
+ dev_err(td->dev, "couldn't build LUT\n");
1984
+ return ret;
1985
+ }
1986
+
16321987 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
16331988 if (!mem) {
16341989 dev_err(td->dev, "no control register resource\n");