185756a06SHans Verkuil /* 285756a06SHans Verkuil * Cobalt CPLD functions 385756a06SHans Verkuil * 485756a06SHans Verkuil * Copyright 2012-2015 Cisco Systems, Inc. and/or its affiliates. 585756a06SHans Verkuil * All rights reserved. 685756a06SHans Verkuil * 785756a06SHans Verkuil * This program is free software; you may redistribute it and/or modify 885756a06SHans Verkuil * it under the terms of the GNU General Public License as published by 985756a06SHans Verkuil * the Free Software Foundation; version 2 of the License. 1085756a06SHans Verkuil * 1185756a06SHans Verkuil * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 1285756a06SHans Verkuil * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 1385756a06SHans Verkuil * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 1485756a06SHans Verkuil * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 1585756a06SHans Verkuil * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 1685756a06SHans Verkuil * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 1785756a06SHans Verkuil * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 1885756a06SHans Verkuil * SOFTWARE. 1985756a06SHans Verkuil */ 2085756a06SHans Verkuil 2185756a06SHans Verkuil #include <linux/delay.h> 2285756a06SHans Verkuil 2385756a06SHans Verkuil #include "cobalt-driver.h" 2485756a06SHans Verkuil 2585756a06SHans Verkuil #define ADRS(offset) (COBALT_BUS_CPLD_BASE + offset) 2685756a06SHans Verkuil 2785756a06SHans Verkuil static u16 cpld_read(struct cobalt *cobalt, u32 offset) 2885756a06SHans Verkuil { 29*4a561c4bSHans Verkuil return cobalt_bus_read32(cobalt->bar1, ADRS(offset)); 3085756a06SHans Verkuil } 3185756a06SHans Verkuil 3285756a06SHans Verkuil static void cpld_write(struct cobalt *cobalt, u32 offset, u16 val) 3385756a06SHans Verkuil { 34*4a561c4bSHans Verkuil return cobalt_bus_write32(cobalt->bar1, ADRS(offset), val); 3585756a06SHans Verkuil } 3685756a06SHans Verkuil 3785756a06SHans Verkuil static void cpld_info_ver3(struct cobalt *cobalt) 3885756a06SHans Verkuil { 3985756a06SHans Verkuil u32 rd; 4085756a06SHans Verkuil u32 tmp; 4185756a06SHans Verkuil 4285756a06SHans Verkuil cobalt_info("CPLD System control register (read/write)\n"); 4385756a06SHans Verkuil cobalt_info("\t\tSystem control: 0x%04x (0x0f00)\n", 4485756a06SHans Verkuil cpld_read(cobalt, 0)); 4585756a06SHans Verkuil cobalt_info("CPLD Clock control register (read/write)\n"); 4685756a06SHans Verkuil cobalt_info("\t\tClock control: 0x%04x (0x0000)\n", 4785756a06SHans Verkuil cpld_read(cobalt, 0x04)); 4885756a06SHans Verkuil cobalt_info("CPLD HSMA Clk Osc register (read/write) - Must set wr trigger to load default values\n"); 4985756a06SHans Verkuil cobalt_info("\t\tRegister #7:\t0x%04x (0x0022)\n", 5085756a06SHans Verkuil cpld_read(cobalt, 0x08)); 5185756a06SHans Verkuil cobalt_info("\t\tRegister #8:\t0x%04x (0x0047)\n", 5285756a06SHans Verkuil cpld_read(cobalt, 0x0c)); 5385756a06SHans Verkuil cobalt_info("\t\tRegister #9:\t0x%04x (0x00fa)\n", 5485756a06SHans Verkuil cpld_read(cobalt, 0x10)); 5585756a06SHans Verkuil cobalt_info("\t\tRegister #10:\t0x%04x (0x0061)\n", 5685756a06SHans Verkuil cpld_read(cobalt, 0x14)); 5785756a06SHans Verkuil cobalt_info("\t\tRegister #11:\t0x%04x (0x001e)\n", 5885756a06SHans Verkuil cpld_read(cobalt, 0x18)); 5985756a06SHans Verkuil cobalt_info("\t\tRegister #12:\t0x%04x (0x0045)\n", 6085756a06SHans Verkuil cpld_read(cobalt, 0x1c)); 6185756a06SHans Verkuil cobalt_info("\t\tRegister #135:\t0x%04x\n", 6285756a06SHans Verkuil cpld_read(cobalt, 0x20)); 6385756a06SHans Verkuil cobalt_info("\t\tRegister #137:\t0x%04x\n", 6485756a06SHans Verkuil cpld_read(cobalt, 0x24)); 6585756a06SHans Verkuil cobalt_info("CPLD System status register (read only)\n"); 6685756a06SHans Verkuil cobalt_info("\t\tSystem status: 0x%04x\n", 6785756a06SHans Verkuil cpld_read(cobalt, 0x28)); 6885756a06SHans Verkuil cobalt_info("CPLD MAXII info register (read only)\n"); 6985756a06SHans Verkuil cobalt_info("\t\tBoard serial number: 0x%04x\n", 7085756a06SHans Verkuil cpld_read(cobalt, 0x2c)); 7185756a06SHans Verkuil cobalt_info("\t\tMAXII program revision: 0x%04x\n", 7285756a06SHans Verkuil cpld_read(cobalt, 0x30)); 7385756a06SHans Verkuil cobalt_info("CPLD temp and voltage ADT7411 registers (read only)\n"); 7485756a06SHans Verkuil cobalt_info("\t\tBoard temperature: %u Celcius\n", 7585756a06SHans Verkuil cpld_read(cobalt, 0x34) / 4); 7685756a06SHans Verkuil cobalt_info("\t\tFPGA temperature: %u Celcius\n", 7785756a06SHans Verkuil cpld_read(cobalt, 0x38) / 4); 7885756a06SHans Verkuil rd = cpld_read(cobalt, 0x3c); 7985756a06SHans Verkuil tmp = (rd * 33 * 1000) / (483 * 10); 8085756a06SHans Verkuil cobalt_info("\t\tVDD 3V3: %u,%03uV\n", tmp / 1000, tmp % 1000); 8185756a06SHans Verkuil rd = cpld_read(cobalt, 0x40); 8285756a06SHans Verkuil tmp = (rd * 74 * 2197) / (27 * 1000); 8385756a06SHans Verkuil cobalt_info("\t\tADC ch3 5V: %u,%03uV\n", tmp / 1000, tmp % 1000); 8485756a06SHans Verkuil rd = cpld_read(cobalt, 0x44); 8585756a06SHans Verkuil tmp = (rd * 74 * 2197) / (47 * 1000); 8685756a06SHans Verkuil cobalt_info("\t\tADC ch4 3V: %u,%03uV\n", tmp / 1000, tmp % 1000); 8785756a06SHans Verkuil rd = cpld_read(cobalt, 0x48); 8885756a06SHans Verkuil tmp = (rd * 57 * 2197) / (47 * 1000); 8985756a06SHans Verkuil cobalt_info("\t\tADC ch5 2V5: %u,%03uV\n", tmp / 1000, tmp % 1000); 9085756a06SHans Verkuil rd = cpld_read(cobalt, 0x4c); 9185756a06SHans Verkuil tmp = (rd * 2197) / 1000; 9285756a06SHans Verkuil cobalt_info("\t\tADC ch6 1V8: %u,%03uV\n", tmp / 1000, tmp % 1000); 9385756a06SHans Verkuil rd = cpld_read(cobalt, 0x50); 9485756a06SHans Verkuil tmp = (rd * 2197) / 1000; 9585756a06SHans Verkuil cobalt_info("\t\tADC ch7 1V5: %u,%03uV\n", tmp / 1000, tmp % 1000); 9685756a06SHans Verkuil rd = cpld_read(cobalt, 0x54); 9785756a06SHans Verkuil tmp = (rd * 2197) / 1000; 9885756a06SHans Verkuil cobalt_info("\t\tADC ch8 0V9: %u,%03uV\n", tmp / 1000, tmp % 1000); 9985756a06SHans Verkuil } 10085756a06SHans Verkuil 10185756a06SHans Verkuil void cobalt_cpld_status(struct cobalt *cobalt) 10285756a06SHans Verkuil { 10385756a06SHans Verkuil u32 rev = cpld_read(cobalt, 0x30); 10485756a06SHans Verkuil 10585756a06SHans Verkuil switch (rev) { 10685756a06SHans Verkuil case 3: 10785756a06SHans Verkuil case 4: 10885756a06SHans Verkuil case 5: 10985756a06SHans Verkuil cpld_info_ver3(cobalt); 11085756a06SHans Verkuil break; 11185756a06SHans Verkuil default: 11285756a06SHans Verkuil cobalt_info("CPLD revision %u is not supported!\n", rev); 11385756a06SHans Verkuil break; 11485756a06SHans Verkuil } 11585756a06SHans Verkuil } 11685756a06SHans Verkuil 11785756a06SHans Verkuil #define DCO_MIN 4850000000ULL 11885756a06SHans Verkuil #define DCO_MAX 5670000000ULL 11985756a06SHans Verkuil 12085756a06SHans Verkuil #define SI570_CLOCK_CTRL 0x04 12185756a06SHans Verkuil #define S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_WR_TRIGGER 0x200 12285756a06SHans Verkuil #define S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_RST_TRIGGER 0x100 12385756a06SHans Verkuil #define S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_FPGA_CTRL 0x80 12485756a06SHans Verkuil #define S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_EN 0x40 12585756a06SHans Verkuil 12685756a06SHans Verkuil #define SI570_REG7 0x08 12785756a06SHans Verkuil #define SI570_REG8 0x0c 12885756a06SHans Verkuil #define SI570_REG9 0x10 12985756a06SHans Verkuil #define SI570_REG10 0x14 13085756a06SHans Verkuil #define SI570_REG11 0x18 13185756a06SHans Verkuil #define SI570_REG12 0x1c 13285756a06SHans Verkuil #define SI570_REG135 0x20 13385756a06SHans Verkuil #define SI570_REG137 0x24 13485756a06SHans Verkuil 13585756a06SHans Verkuil struct multiplier { 13685756a06SHans Verkuil unsigned mult, hsdiv, n1; 13785756a06SHans Verkuil }; 13885756a06SHans Verkuil 13985756a06SHans Verkuil /* List all possible multipliers (= hsdiv * n1). There are lots of duplicates, 14085756a06SHans Verkuil which are all removed in this list to keep the list as short as possible. 14185756a06SHans Verkuil The values for hsdiv and n1 are the actual values, not the register values. 14285756a06SHans Verkuil */ 14385756a06SHans Verkuil static const struct multiplier multipliers[] = { 14485756a06SHans Verkuil { 4, 4, 1 }, { 5, 5, 1 }, { 6, 6, 1 }, 14585756a06SHans Verkuil { 7, 7, 1 }, { 8, 4, 2 }, { 9, 9, 1 }, 14685756a06SHans Verkuil { 10, 5, 2 }, { 11, 11, 1 }, { 12, 6, 2 }, 14785756a06SHans Verkuil { 14, 7, 2 }, { 16, 4, 4 }, { 18, 9, 2 }, 14885756a06SHans Verkuil { 20, 5, 4 }, { 22, 11, 2 }, { 24, 4, 6 }, 14985756a06SHans Verkuil { 28, 7, 4 }, { 30, 5, 6 }, { 32, 4, 8 }, 15085756a06SHans Verkuil { 36, 6, 6 }, { 40, 4, 10 }, { 42, 7, 6 }, 15185756a06SHans Verkuil { 44, 11, 4 }, { 48, 4, 12 }, { 50, 5, 10 }, 15285756a06SHans Verkuil { 54, 9, 6 }, { 56, 4, 14 }, { 60, 5, 12 }, 15385756a06SHans Verkuil { 64, 4, 16 }, { 66, 11, 6 }, { 70, 5, 14 }, 15485756a06SHans Verkuil { 72, 4, 18 }, { 80, 4, 20 }, { 84, 6, 14 }, 15585756a06SHans Verkuil { 88, 11, 8 }, { 90, 5, 18 }, { 96, 4, 24 }, 15685756a06SHans Verkuil { 98, 7, 14 }, { 100, 5, 20 }, { 104, 4, 26 }, 15785756a06SHans Verkuil { 108, 6, 18 }, { 110, 11, 10 }, { 112, 4, 28 }, 15885756a06SHans Verkuil { 120, 4, 30 }, { 126, 7, 18 }, { 128, 4, 32 }, 15985756a06SHans Verkuil { 130, 5, 26 }, { 132, 11, 12 }, { 136, 4, 34 }, 16085756a06SHans Verkuil { 140, 5, 28 }, { 144, 4, 36 }, { 150, 5, 30 }, 16185756a06SHans Verkuil { 152, 4, 38 }, { 154, 11, 14 }, { 156, 6, 26 }, 16285756a06SHans Verkuil { 160, 4, 40 }, { 162, 9, 18 }, { 168, 4, 42 }, 16385756a06SHans Verkuil { 170, 5, 34 }, { 176, 11, 16 }, { 180, 5, 36 }, 16485756a06SHans Verkuil { 182, 7, 26 }, { 184, 4, 46 }, { 190, 5, 38 }, 16585756a06SHans Verkuil { 192, 4, 48 }, { 196, 7, 28 }, { 198, 11, 18 }, 16685756a06SHans Verkuil { 198, 9, 22 }, { 200, 4, 50 }, { 204, 6, 34 }, 16785756a06SHans Verkuil { 208, 4, 52 }, { 210, 5, 42 }, { 216, 4, 54 }, 16885756a06SHans Verkuil { 220, 11, 20 }, { 224, 4, 56 }, { 228, 6, 38 }, 16985756a06SHans Verkuil { 230, 5, 46 }, { 232, 4, 58 }, { 234, 9, 26 }, 17085756a06SHans Verkuil { 238, 7, 34 }, { 240, 4, 60 }, { 242, 11, 22 }, 17185756a06SHans Verkuil { 248, 4, 62 }, { 250, 5, 50 }, { 252, 6, 42 }, 17285756a06SHans Verkuil { 256, 4, 64 }, { 260, 5, 52 }, { 264, 11, 24 }, 17385756a06SHans Verkuil { 266, 7, 38 }, { 270, 5, 54 }, { 272, 4, 68 }, 17485756a06SHans Verkuil { 276, 6, 46 }, { 280, 4, 70 }, { 286, 11, 26 }, 17585756a06SHans Verkuil { 288, 4, 72 }, { 290, 5, 58 }, { 294, 7, 42 }, 17685756a06SHans Verkuil { 296, 4, 74 }, { 300, 5, 60 }, { 304, 4, 76 }, 17785756a06SHans Verkuil { 306, 9, 34 }, { 308, 11, 28 }, { 310, 5, 62 }, 17885756a06SHans Verkuil { 312, 4, 78 }, { 320, 4, 80 }, { 322, 7, 46 }, 17985756a06SHans Verkuil { 324, 6, 54 }, { 328, 4, 82 }, { 330, 11, 30 }, 18085756a06SHans Verkuil { 336, 4, 84 }, { 340, 5, 68 }, { 342, 9, 38 }, 18185756a06SHans Verkuil { 344, 4, 86 }, { 348, 6, 58 }, { 350, 5, 70 }, 18285756a06SHans Verkuil { 352, 11, 32 }, { 360, 4, 90 }, { 364, 7, 52 }, 18385756a06SHans Verkuil { 368, 4, 92 }, { 370, 5, 74 }, { 372, 6, 62 }, 18485756a06SHans Verkuil { 374, 11, 34 }, { 376, 4, 94 }, { 378, 7, 54 }, 18585756a06SHans Verkuil { 380, 5, 76 }, { 384, 4, 96 }, { 390, 5, 78 }, 18685756a06SHans Verkuil { 392, 4, 98 }, { 396, 11, 36 }, { 400, 4, 100 }, 18785756a06SHans Verkuil { 406, 7, 58 }, { 408, 4, 102 }, { 410, 5, 82 }, 18885756a06SHans Verkuil { 414, 9, 46 }, { 416, 4, 104 }, { 418, 11, 38 }, 18985756a06SHans Verkuil { 420, 5, 84 }, { 424, 4, 106 }, { 430, 5, 86 }, 19085756a06SHans Verkuil { 432, 4, 108 }, { 434, 7, 62 }, { 440, 11, 40 }, 19185756a06SHans Verkuil { 444, 6, 74 }, { 448, 4, 112 }, { 450, 5, 90 }, 19285756a06SHans Verkuil { 456, 4, 114 }, { 460, 5, 92 }, { 462, 11, 42 }, 19385756a06SHans Verkuil { 464, 4, 116 }, { 468, 6, 78 }, { 470, 5, 94 }, 19485756a06SHans Verkuil { 472, 4, 118 }, { 476, 7, 68 }, { 480, 4, 120 }, 19585756a06SHans Verkuil { 484, 11, 44 }, { 486, 9, 54 }, { 488, 4, 122 }, 19685756a06SHans Verkuil { 490, 5, 98 }, { 492, 6, 82 }, { 496, 4, 124 }, 19785756a06SHans Verkuil { 500, 5, 100 }, { 504, 4, 126 }, { 506, 11, 46 }, 19885756a06SHans Verkuil { 510, 5, 102 }, { 512, 4, 128 }, { 516, 6, 86 }, 19985756a06SHans Verkuil { 518, 7, 74 }, { 520, 5, 104 }, { 522, 9, 58 }, 20085756a06SHans Verkuil { 528, 11, 48 }, { 530, 5, 106 }, { 532, 7, 76 }, 20185756a06SHans Verkuil { 540, 5, 108 }, { 546, 7, 78 }, { 550, 11, 50 }, 20285756a06SHans Verkuil { 552, 6, 92 }, { 558, 9, 62 }, { 560, 5, 112 }, 20385756a06SHans Verkuil { 564, 6, 94 }, { 570, 5, 114 }, { 572, 11, 52 }, 20485756a06SHans Verkuil { 574, 7, 82 }, { 576, 6, 96 }, { 580, 5, 116 }, 20585756a06SHans Verkuil { 588, 6, 98 }, { 590, 5, 118 }, { 594, 11, 54 }, 20685756a06SHans Verkuil { 600, 5, 120 }, { 602, 7, 86 }, { 610, 5, 122 }, 20785756a06SHans Verkuil { 612, 6, 102 }, { 616, 11, 56 }, { 620, 5, 124 }, 20885756a06SHans Verkuil { 624, 6, 104 }, { 630, 5, 126 }, { 636, 6, 106 }, 20985756a06SHans Verkuil { 638, 11, 58 }, { 640, 5, 128 }, { 644, 7, 92 }, 21085756a06SHans Verkuil { 648, 6, 108 }, { 658, 7, 94 }, { 660, 11, 60 }, 21185756a06SHans Verkuil { 666, 9, 74 }, { 672, 6, 112 }, { 682, 11, 62 }, 21285756a06SHans Verkuil { 684, 6, 114 }, { 686, 7, 98 }, { 696, 6, 116 }, 21385756a06SHans Verkuil { 700, 7, 100 }, { 702, 9, 78 }, { 704, 11, 64 }, 21485756a06SHans Verkuil { 708, 6, 118 }, { 714, 7, 102 }, { 720, 6, 120 }, 21585756a06SHans Verkuil { 726, 11, 66 }, { 728, 7, 104 }, { 732, 6, 122 }, 21685756a06SHans Verkuil { 738, 9, 82 }, { 742, 7, 106 }, { 744, 6, 124 }, 21785756a06SHans Verkuil { 748, 11, 68 }, { 756, 6, 126 }, { 768, 6, 128 }, 21885756a06SHans Verkuil { 770, 11, 70 }, { 774, 9, 86 }, { 784, 7, 112 }, 21985756a06SHans Verkuil { 792, 11, 72 }, { 798, 7, 114 }, { 810, 9, 90 }, 22085756a06SHans Verkuil { 812, 7, 116 }, { 814, 11, 74 }, { 826, 7, 118 }, 22185756a06SHans Verkuil { 828, 9, 92 }, { 836, 11, 76 }, { 840, 7, 120 }, 22285756a06SHans Verkuil { 846, 9, 94 }, { 854, 7, 122 }, { 858, 11, 78 }, 22385756a06SHans Verkuil { 864, 9, 96 }, { 868, 7, 124 }, { 880, 11, 80 }, 22485756a06SHans Verkuil { 882, 7, 126 }, { 896, 7, 128 }, { 900, 9, 100 }, 22585756a06SHans Verkuil { 902, 11, 82 }, { 918, 9, 102 }, { 924, 11, 84 }, 22685756a06SHans Verkuil { 936, 9, 104 }, { 946, 11, 86 }, { 954, 9, 106 }, 22785756a06SHans Verkuil { 968, 11, 88 }, { 972, 9, 108 }, { 990, 11, 90 }, 22885756a06SHans Verkuil { 1008, 9, 112 }, { 1012, 11, 92 }, { 1026, 9, 114 }, 22985756a06SHans Verkuil { 1034, 11, 94 }, { 1044, 9, 116 }, { 1056, 11, 96 }, 23085756a06SHans Verkuil { 1062, 9, 118 }, { 1078, 11, 98 }, { 1080, 9, 120 }, 23185756a06SHans Verkuil { 1098, 9, 122 }, { 1100, 11, 100 }, { 1116, 9, 124 }, 23285756a06SHans Verkuil { 1122, 11, 102 }, { 1134, 9, 126 }, { 1144, 11, 104 }, 23385756a06SHans Verkuil { 1152, 9, 128 }, { 1166, 11, 106 }, { 1188, 11, 108 }, 23485756a06SHans Verkuil { 1210, 11, 110 }, { 1232, 11, 112 }, { 1254, 11, 114 }, 23585756a06SHans Verkuil { 1276, 11, 116 }, { 1298, 11, 118 }, { 1320, 11, 120 }, 23685756a06SHans Verkuil { 1342, 11, 122 }, { 1364, 11, 124 }, { 1386, 11, 126 }, 23785756a06SHans Verkuil { 1408, 11, 128 }, 23885756a06SHans Verkuil }; 23985756a06SHans Verkuil 24085756a06SHans Verkuil bool cobalt_cpld_set_freq(struct cobalt *cobalt, unsigned f_out) 24185756a06SHans Verkuil { 24285756a06SHans Verkuil const unsigned f_xtal = 39170000; /* xtal for si598 */ 24385756a06SHans Verkuil unsigned long long dco; 24485756a06SHans Verkuil unsigned long long rfreq; 24585756a06SHans Verkuil unsigned delta = 0xffffffff; 24685756a06SHans Verkuil unsigned i_best = 0; 24785756a06SHans Verkuil unsigned i; 24885756a06SHans Verkuil u8 n1, hsdiv; 24985756a06SHans Verkuil u8 regs[6]; 25085756a06SHans Verkuil int found = 0; 25185756a06SHans Verkuil u16 clock_ctrl; 25285756a06SHans Verkuil int retries = 3; 25385756a06SHans Verkuil 25485756a06SHans Verkuil for (i = 0; i < ARRAY_SIZE(multipliers); i++) { 25585756a06SHans Verkuil unsigned mult = multipliers[i].mult; 25685756a06SHans Verkuil unsigned d; 25785756a06SHans Verkuil 25885756a06SHans Verkuil dco = (unsigned long long)f_out * mult; 25985756a06SHans Verkuil if (dco < DCO_MIN || dco > DCO_MAX) 26085756a06SHans Verkuil continue; 26185756a06SHans Verkuil d = ((dco << 28) + f_xtal / 2) % f_xtal; 26285756a06SHans Verkuil if (d < delta) { 26385756a06SHans Verkuil found = 1; 26485756a06SHans Verkuil i_best = i; 26585756a06SHans Verkuil delta = d; 26685756a06SHans Verkuil } 26785756a06SHans Verkuil } 26885756a06SHans Verkuil if (!found) 26985756a06SHans Verkuil return false; 27085756a06SHans Verkuil dco = (unsigned long long)f_out * multipliers[i_best].mult; 27185756a06SHans Verkuil n1 = multipliers[i_best].n1 - 1; 27285756a06SHans Verkuil hsdiv = multipliers[i_best].hsdiv - 4; 27385756a06SHans Verkuil rfreq = (dco << 28) / f_xtal; 27485756a06SHans Verkuil 27585756a06SHans Verkuil clock_ctrl = cpld_read(cobalt, SI570_CLOCK_CTRL); 27685756a06SHans Verkuil clock_ctrl |= S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_FPGA_CTRL; 27785756a06SHans Verkuil clock_ctrl |= S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_EN; 27885756a06SHans Verkuil 27985756a06SHans Verkuil regs[0] = (hsdiv << 5) | (n1 >> 2); 28085756a06SHans Verkuil regs[1] = ((n1 & 0x3) << 6) | (rfreq >> 32); 28185756a06SHans Verkuil regs[2] = (rfreq >> 24) & 0xff; 28285756a06SHans Verkuil regs[3] = (rfreq >> 16) & 0xff; 28385756a06SHans Verkuil regs[4] = (rfreq >> 8) & 0xff; 28485756a06SHans Verkuil regs[5] = rfreq & 0xff; 28585756a06SHans Verkuil 28685756a06SHans Verkuil /* The sequence of clock_ctrl flags to set is very weird. It looks 28785756a06SHans Verkuil like I have to reset it, then set the new frequency and reset it 28885756a06SHans Verkuil again. It shouldn't be necessary to do a reset, but if I don't, 28985756a06SHans Verkuil then a strange frequency is set (156.412034 MHz, or register values 29085756a06SHans Verkuil 0x01, 0xc7, 0xfc, 0x7f, 0x53, 0x62). 29185756a06SHans Verkuil */ 29285756a06SHans Verkuil 29385756a06SHans Verkuil cobalt_dbg(1, "%u: %02x %02x %02x %02x %02x %02x\n", f_out, 29485756a06SHans Verkuil regs[0], regs[1], regs[2], regs[3], regs[4], regs[5]); 29585756a06SHans Verkuil while (retries--) { 29685756a06SHans Verkuil u8 read_regs[6]; 29785756a06SHans Verkuil 29885756a06SHans Verkuil cpld_write(cobalt, SI570_CLOCK_CTRL, 29985756a06SHans Verkuil S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_EN | 30085756a06SHans Verkuil S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_FPGA_CTRL); 30185756a06SHans Verkuil usleep_range(10000, 15000); 30285756a06SHans Verkuil cpld_write(cobalt, SI570_REG7, regs[0]); 30385756a06SHans Verkuil cpld_write(cobalt, SI570_REG8, regs[1]); 30485756a06SHans Verkuil cpld_write(cobalt, SI570_REG9, regs[2]); 30585756a06SHans Verkuil cpld_write(cobalt, SI570_REG10, regs[3]); 30685756a06SHans Verkuil cpld_write(cobalt, SI570_REG11, regs[4]); 30785756a06SHans Verkuil cpld_write(cobalt, SI570_REG12, regs[5]); 30885756a06SHans Verkuil cpld_write(cobalt, SI570_CLOCK_CTRL, 30985756a06SHans Verkuil S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_EN | 31085756a06SHans Verkuil S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_WR_TRIGGER); 31185756a06SHans Verkuil usleep_range(10000, 15000); 31285756a06SHans Verkuil cpld_write(cobalt, SI570_CLOCK_CTRL, 31385756a06SHans Verkuil S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_EN | 31485756a06SHans Verkuil S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_FPGA_CTRL); 31585756a06SHans Verkuil usleep_range(10000, 15000); 31685756a06SHans Verkuil read_regs[0] = cpld_read(cobalt, SI570_REG7); 31785756a06SHans Verkuil read_regs[1] = cpld_read(cobalt, SI570_REG8); 31885756a06SHans Verkuil read_regs[2] = cpld_read(cobalt, SI570_REG9); 31985756a06SHans Verkuil read_regs[3] = cpld_read(cobalt, SI570_REG10); 32085756a06SHans Verkuil read_regs[4] = cpld_read(cobalt, SI570_REG11); 32185756a06SHans Verkuil read_regs[5] = cpld_read(cobalt, SI570_REG12); 32285756a06SHans Verkuil cpld_write(cobalt, SI570_CLOCK_CTRL, 32385756a06SHans Verkuil S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_EN | 32485756a06SHans Verkuil S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_FPGA_CTRL | 32585756a06SHans Verkuil S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_RST_TRIGGER); 32685756a06SHans Verkuil usleep_range(10000, 15000); 32785756a06SHans Verkuil cpld_write(cobalt, SI570_CLOCK_CTRL, 32885756a06SHans Verkuil S01755_REG_CLOCK_CTRL_BITMAP_CLKHSMA_EN); 32985756a06SHans Verkuil usleep_range(10000, 15000); 33085756a06SHans Verkuil 33185756a06SHans Verkuil if (!memcmp(read_regs, regs, sizeof(read_regs))) 33285756a06SHans Verkuil break; 33385756a06SHans Verkuil cobalt_dbg(1, "retry: %02x %02x %02x %02x %02x %02x\n", 33485756a06SHans Verkuil read_regs[0], read_regs[1], read_regs[2], 33585756a06SHans Verkuil read_regs[3], read_regs[4], read_regs[5]); 33685756a06SHans Verkuil } 33785756a06SHans Verkuil if (2 - retries) 33885756a06SHans Verkuil cobalt_info("Needed %d retries\n", 2 - retries); 33985756a06SHans Verkuil 34085756a06SHans Verkuil return true; 34185756a06SHans Verkuil } 342