|
69 | 69 | #define VC5_FEEDBACK_FRAC_DIV(n) (0x19 + (n))
|
70 | 70 | #define VC5_RC_CONTROL0 0x1e
|
71 | 71 | #define VC5_RC_CONTROL1 0x1f
|
72 |
| -/* Register 0x20 is factory reserved */ |
| 72 | + |
| 73 | +/* These registers are named "Unused Factory Reserved Registers" */ |
| 74 | +#define VC5_RESERVED_X0(idx) (0x20 + ((idx) * 0x10)) |
| 75 | +#define VC5_RESERVED_X0_BYPASS_SYNC BIT(7) /* bypass_sync<idx> bit */ |
73 | 76 |
|
74 | 77 | /* Output divider control for divider 1,2,3,4 */
|
75 | 78 | #define VC5_OUT_DIV_CONTROL(idx) (0x21 + ((idx) * 0x10))
|
|
87 | 90 | #define VC5_OUT_DIV_SKEW_INT(idx, n) (0x2b + ((idx) * 0x10) + (n))
|
88 | 91 | #define VC5_OUT_DIV_INT(idx, n) (0x2d + ((idx) * 0x10) + (n))
|
89 | 92 | #define VC5_OUT_DIV_SKEW_FRAC(idx) (0x2f + ((idx) * 0x10))
|
90 |
| -/* Registers 0x30, 0x40, 0x50 are factory reserved */ |
91 | 93 |
|
92 | 94 | /* Clock control register for clock 1,2 */
|
93 | 95 | #define VC5_CLK_OUTPUT_CFG(idx, n) (0x60 + ((idx) * 0x2) + (n))
|
|
140 | 142 | #define VC5_HAS_INTERNAL_XTAL BIT(0)
|
141 | 143 | /* chip has PFD requency doubler */
|
142 | 144 | #define VC5_HAS_PFD_FREQ_DBL BIT(1)
|
| 145 | +/* chip has bits to disable FOD sync */ |
| 146 | +#define VC5_HAS_BYPASS_SYNC_BIT BIT(2) |
143 | 147 |
|
144 | 148 | /* Supported IDT VC5 models. */
|
145 | 149 | enum vc5_model {
|
@@ -581,6 +585,23 @@ static int vc5_clk_out_prepare(struct clk_hw *hw)
|
581 | 585 | unsigned int src;
|
582 | 586 | int ret;
|
583 | 587 |
|
| 588 | + /* |
| 589 | + * When enabling a FOD, all currently enabled FODs are briefly |
| 590 | + * stopped in order to synchronize all of them. This causes a clock |
| 591 | + * disruption to any unrelated chips that might be already using |
| 592 | + * other clock outputs. Bypass the sync feature to avoid the issue, |
| 593 | + * which is possible on the VersaClock 6E family via reserved |
| 594 | + * registers. |
| 595 | + */ |
| 596 | + if (vc5->chip_info->flags & VC5_HAS_BYPASS_SYNC_BIT) { |
| 597 | + ret = regmap_update_bits(vc5->regmap, |
| 598 | + VC5_RESERVED_X0(hwdata->num), |
| 599 | + VC5_RESERVED_X0_BYPASS_SYNC, |
| 600 | + VC5_RESERVED_X0_BYPASS_SYNC); |
| 601 | + if (ret) |
| 602 | + return ret; |
| 603 | + } |
| 604 | + |
584 | 605 | /*
|
585 | 606 | * If the input mux is disabled, enable it first and
|
586 | 607 | * select source from matching FOD.
|
@@ -1166,7 +1187,7 @@ static const struct vc5_chip_info idt_5p49v6965_info = {
|
1166 | 1187 | .model = IDT_VC6_5P49V6965,
|
1167 | 1188 | .clk_fod_cnt = 4,
|
1168 | 1189 | .clk_out_cnt = 5,
|
1169 |
| - .flags = 0, |
| 1190 | + .flags = VC5_HAS_BYPASS_SYNC_BIT, |
1170 | 1191 | };
|
1171 | 1192 |
|
1172 | 1193 | static const struct i2c_device_id vc5_id[] = {
|
|
0 commit comments