1*83d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+ 2a5b22518SShaveta Leekha /* 3a5b22518SShaveta Leekha * Copyright 2013 Freescale Semiconductor, Inc. 4a5b22518SShaveta Leekha * Author: Shaveta Leekha <shaveta@freescale.com> 5a5b22518SShaveta Leekha */ 6a5b22518SShaveta Leekha 7a5b22518SShaveta Leekha #include "idt8t49n222a_serdes_clk.h" 8a5b22518SShaveta Leekha 9a5b22518SShaveta Leekha #define DEVICE_ID_REG 0x00 10a5b22518SShaveta Leekha 11a5b22518SShaveta Leekha static int check_pll_status(u8 idt_addr) 12a5b22518SShaveta Leekha { 13a5b22518SShaveta Leekha u8 val = 0; 14a5b22518SShaveta Leekha int ret; 15a5b22518SShaveta Leekha 16a5b22518SShaveta Leekha ret = i2c_read(idt_addr, 0x17, 1, &val, 1); 17a5b22518SShaveta Leekha if (ret < 0) { 18a5b22518SShaveta Leekha printf("IDT:0x%x could not read status register from device.\n", 19a5b22518SShaveta Leekha idt_addr); 20a5b22518SShaveta Leekha return ret; 21a5b22518SShaveta Leekha } 22a5b22518SShaveta Leekha 23a5b22518SShaveta Leekha if (val & 0x04) { 24a5b22518SShaveta Leekha debug("idt8t49n222a PLL is LOCKED: %x\n", val); 25a5b22518SShaveta Leekha } else { 26a5b22518SShaveta Leekha printf("idt8t49n222a PLL is not LOCKED: %x\n", val); 27a5b22518SShaveta Leekha return -1; 28a5b22518SShaveta Leekha } 29a5b22518SShaveta Leekha 30a5b22518SShaveta Leekha return 0; 31a5b22518SShaveta Leekha } 32a5b22518SShaveta Leekha 33a5b22518SShaveta Leekha int set_serdes_refclk(u8 idt_addr, u8 serdes_num, 34a5b22518SShaveta Leekha enum serdes_refclk refclk1, 35a5b22518SShaveta Leekha enum serdes_refclk refclk2, u8 feedback) 36a5b22518SShaveta Leekha { 37a5b22518SShaveta Leekha u8 dev_id = 0; 38a5b22518SShaveta Leekha int i, ret; 39a5b22518SShaveta Leekha 40a5b22518SShaveta Leekha debug("IDT:Configuring idt8t49n222a device at I2C address: 0x%2x\n", 41a5b22518SShaveta Leekha idt_addr); 42a5b22518SShaveta Leekha 43a5b22518SShaveta Leekha ret = i2c_read(idt_addr, DEVICE_ID_REG, 1, &dev_id, 1); 44a5b22518SShaveta Leekha if (ret < 0) { 45a5b22518SShaveta Leekha debug("IDT:0x%x could not read DEV_ID from device.\n", 46a5b22518SShaveta Leekha idt_addr); 47a5b22518SShaveta Leekha return ret; 48a5b22518SShaveta Leekha } 49a5b22518SShaveta Leekha 50a5b22518SShaveta Leekha if ((dev_id != 0x00) && (dev_id != 0x24) && (dev_id != 0x2a)) { 51a5b22518SShaveta Leekha debug("IDT: device at address 0x%x is not idt8t49n222a.\n", 52a5b22518SShaveta Leekha idt_addr); 53a5b22518SShaveta Leekha } 54a5b22518SShaveta Leekha 55a5b22518SShaveta Leekha if (serdes_num != 1 && serdes_num != 2) { 56a5b22518SShaveta Leekha debug("serdes_num should be 1 for SerDes1 and" 57a5b22518SShaveta Leekha " 2 for SerDes2.\n"); 58a5b22518SShaveta Leekha return -1; 59a5b22518SShaveta Leekha } 60a5b22518SShaveta Leekha 61a5b22518SShaveta Leekha if ((refclk1 == SERDES_REFCLK_122_88 && refclk2 != SERDES_REFCLK_122_88) 62a5b22518SShaveta Leekha || (refclk1 != SERDES_REFCLK_122_88 63a5b22518SShaveta Leekha && refclk2 == SERDES_REFCLK_122_88)) { 64a5b22518SShaveta Leekha debug("Only one refclk at 122.88MHz is not supported." 65a5b22518SShaveta Leekha " Please set both refclk1 & refclk2 to 122.88MHz" 66a5b22518SShaveta Leekha " or both not to 122.88MHz.\n"); 67a5b22518SShaveta Leekha return -1; 68a5b22518SShaveta Leekha } 69a5b22518SShaveta Leekha 70a5b22518SShaveta Leekha if (refclk1 != SERDES_REFCLK_100 && refclk1 != SERDES_REFCLK_122_88 71a5b22518SShaveta Leekha && refclk1 != SERDES_REFCLK_125 72a5b22518SShaveta Leekha && refclk1 != SERDES_REFCLK_156_25) { 73a5b22518SShaveta Leekha debug("refclk1 should be 100MHZ, 122.88MHz, 125MHz" 74a5b22518SShaveta Leekha " or 156.25MHz.\n"); 75a5b22518SShaveta Leekha return -1; 76a5b22518SShaveta Leekha } 77a5b22518SShaveta Leekha 78a5b22518SShaveta Leekha if (refclk2 != SERDES_REFCLK_100 && refclk2 != SERDES_REFCLK_122_88 79a5b22518SShaveta Leekha && refclk2 != SERDES_REFCLK_125 80a5b22518SShaveta Leekha && refclk2 != SERDES_REFCLK_156_25) { 81a5b22518SShaveta Leekha debug("refclk2 should be 100MHZ, 122.88MHz, 125MHz" 82a5b22518SShaveta Leekha " or 156.25MHz.\n"); 83a5b22518SShaveta Leekha return -1; 84a5b22518SShaveta Leekha } 85a5b22518SShaveta Leekha 86a5b22518SShaveta Leekha if (feedback != 0 && feedback != 1) { 87a5b22518SShaveta Leekha debug("valid values for feedback are 0(default) or 1.\n"); 88a5b22518SShaveta Leekha return -1; 89a5b22518SShaveta Leekha } 90a5b22518SShaveta Leekha 91a5b22518SShaveta Leekha /* Configuring IDT for output refclks as 92a5b22518SShaveta Leekha * Refclk1 = 122.88MHz Refclk2 = 122.88MHz 93a5b22518SShaveta Leekha */ 94a5b22518SShaveta Leekha if (refclk1 == SERDES_REFCLK_122_88 && 95a5b22518SShaveta Leekha refclk2 == SERDES_REFCLK_122_88) { 96a5b22518SShaveta Leekha printf("Setting refclk1:122.88 and refclk2:122.88\n"); 97a5b22518SShaveta Leekha for (i = 0; i < NUM_IDT_REGS; i++) 98a5b22518SShaveta Leekha i2c_reg_write(idt_addr, idt_conf_122_88[i][0], 99a5b22518SShaveta Leekha idt_conf_122_88[i][1]); 100a5b22518SShaveta Leekha 101a5b22518SShaveta Leekha if (feedback) { 102a5b22518SShaveta Leekha for (i = 0; i < NUM_IDT_REGS_FEEDBACK; i++) 103a5b22518SShaveta Leekha i2c_reg_write(idt_addr, 104a5b22518SShaveta Leekha idt_conf_122_88_feedback[i][0], 105a5b22518SShaveta Leekha idt_conf_122_88_feedback[i][1]); 106a5b22518SShaveta Leekha } 107a5b22518SShaveta Leekha } 108a5b22518SShaveta Leekha 109a5b22518SShaveta Leekha if (refclk1 != SERDES_REFCLK_122_88 && 110a5b22518SShaveta Leekha refclk2 != SERDES_REFCLK_122_88) { 111a5b22518SShaveta Leekha for (i = 0; i < NUM_IDT_REGS; i++) 112a5b22518SShaveta Leekha i2c_reg_write(idt_addr, idt_conf_not_122_88[i][0], 113a5b22518SShaveta Leekha idt_conf_not_122_88[i][1]); 114a5b22518SShaveta Leekha } 115a5b22518SShaveta Leekha 116a5b22518SShaveta Leekha /* Configuring IDT for output refclks as 117a5b22518SShaveta Leekha * Refclk1 = 100MHz Refclk2 = 125MHz 118a5b22518SShaveta Leekha */ 119a5b22518SShaveta Leekha if (refclk1 == SERDES_REFCLK_100 && refclk2 == SERDES_REFCLK_125) { 120a5b22518SShaveta Leekha printf("Setting refclk1:100 and refclk2:125\n"); 121a5b22518SShaveta Leekha i2c_reg_write(idt_addr, 0x11, 0x10); 122a5b22518SShaveta Leekha } 123a5b22518SShaveta Leekha 124a5b22518SShaveta Leekha /* Configuring IDT for output refclks as 125a5b22518SShaveta Leekha * Refclk1 = 125MHz Refclk2 = 125MHz 126a5b22518SShaveta Leekha */ 127a5b22518SShaveta Leekha if (refclk1 == SERDES_REFCLK_125 && refclk2 == SERDES_REFCLK_125) { 128a5b22518SShaveta Leekha printf("Setting refclk1:125 and refclk2:125\n"); 129a5b22518SShaveta Leekha i2c_reg_write(idt_addr, 0x10, 0x10); 130a5b22518SShaveta Leekha i2c_reg_write(idt_addr, 0x11, 0x10); 131a5b22518SShaveta Leekha } 132a5b22518SShaveta Leekha 133a5b22518SShaveta Leekha /* Configuring IDT for output refclks as 134a5b22518SShaveta Leekha * Refclk1 = 125MHz Refclk2 = 100MHz 135a5b22518SShaveta Leekha */ 136a5b22518SShaveta Leekha if (refclk1 == SERDES_REFCLK_125 && refclk2 == SERDES_REFCLK_100) { 137a5b22518SShaveta Leekha printf("Setting refclk1:125 and refclk2:100\n"); 138a5b22518SShaveta Leekha i2c_reg_write(idt_addr, 0x10, 0x10); 139a5b22518SShaveta Leekha } 140a5b22518SShaveta Leekha 141a5b22518SShaveta Leekha /* Configuring IDT for output refclks as 142a5b22518SShaveta Leekha * Refclk1 = 156.25MHz Refclk2 = 156.25MHz 143a5b22518SShaveta Leekha */ 144a5b22518SShaveta Leekha if (refclk1 == SERDES_REFCLK_156_25 && 145a5b22518SShaveta Leekha refclk2 == SERDES_REFCLK_156_25) { 146a5b22518SShaveta Leekha printf("Setting refclk1:156.25 and refclk2:156.25\n"); 147a5b22518SShaveta Leekha for (i = 0; i < NUM_IDT_REGS_156_25; i++) 148a5b22518SShaveta Leekha i2c_reg_write(idt_addr, idt_conf_156_25[i][0], 149a5b22518SShaveta Leekha idt_conf_156_25[i][1]); 150a5b22518SShaveta Leekha } 151a5b22518SShaveta Leekha 152a5b22518SShaveta Leekha /* Configuring IDT for output refclks as 153a5b22518SShaveta Leekha * Refclk1 = 100MHz Refclk2 = 156.25MHz 154a5b22518SShaveta Leekha */ 155a5b22518SShaveta Leekha if (refclk1 == SERDES_REFCLK_100 && 156a5b22518SShaveta Leekha refclk2 == SERDES_REFCLK_156_25) { 157a5b22518SShaveta Leekha printf("Setting refclk1:100 and refclk2:156.25\n"); 158a5b22518SShaveta Leekha for (i = 0; i < NUM_IDT_REGS_156_25; i++) 159a5b22518SShaveta Leekha i2c_reg_write(idt_addr, idt_conf_100_156_25[i][0], 160a5b22518SShaveta Leekha idt_conf_100_156_25[i][1]); 161a5b22518SShaveta Leekha } 162a5b22518SShaveta Leekha 163a5b22518SShaveta Leekha /* Configuring IDT for output refclks as 164a5b22518SShaveta Leekha * Refclk1 = 125MHz Refclk2 = 156.25MHz 165a5b22518SShaveta Leekha */ 166a5b22518SShaveta Leekha if (refclk1 == SERDES_REFCLK_125 && 167a5b22518SShaveta Leekha refclk2 == SERDES_REFCLK_156_25) { 168a5b22518SShaveta Leekha printf("Setting refclk1:125 and refclk2:156.25\n"); 169a5b22518SShaveta Leekha for (i = 0; i < NUM_IDT_REGS_156_25; i++) 170a5b22518SShaveta Leekha i2c_reg_write(idt_addr, idt_conf_125_156_25[i][0], 171a5b22518SShaveta Leekha idt_conf_125_156_25[i][1]); 172a5b22518SShaveta Leekha } 173a5b22518SShaveta Leekha 174a5b22518SShaveta Leekha /* Configuring IDT for output refclks as 175a5b22518SShaveta Leekha * Refclk1 = 156.25MHz Refclk2 = 100MHz 176a5b22518SShaveta Leekha */ 177a5b22518SShaveta Leekha if (refclk1 == SERDES_REFCLK_156_25 && 178a5b22518SShaveta Leekha refclk2 == SERDES_REFCLK_100) { 179a5b22518SShaveta Leekha printf("Setting refclk1:156.25 and refclk2:100\n"); 180a5b22518SShaveta Leekha for (i = 0; i < NUM_IDT_REGS_156_25; i++) 181a5b22518SShaveta Leekha i2c_reg_write(idt_addr, idt_conf_156_25_100[i][0], 182a5b22518SShaveta Leekha idt_conf_156_25_100[i][1]); 183a5b22518SShaveta Leekha } 184a5b22518SShaveta Leekha 185a5b22518SShaveta Leekha /* Configuring IDT for output refclks as 186a5b22518SShaveta Leekha * Refclk1 = 156.25MHz Refclk2 = 125MHz 187a5b22518SShaveta Leekha */ 188a5b22518SShaveta Leekha if (refclk1 == SERDES_REFCLK_156_25 && 189a5b22518SShaveta Leekha refclk2 == SERDES_REFCLK_125) { 190a5b22518SShaveta Leekha printf("Setting refclk1:156.25 and refclk2:125\n"); 191a5b22518SShaveta Leekha for (i = 0; i < NUM_IDT_REGS_156_25; i++) 192a5b22518SShaveta Leekha i2c_reg_write(idt_addr, idt_conf_156_25_125[i][0], 193a5b22518SShaveta Leekha idt_conf_156_25_125[i][1]); 194a5b22518SShaveta Leekha } 195a5b22518SShaveta Leekha 196a5b22518SShaveta Leekha /* waiting for maximum of 1 second if PLL doesn'r get locked 197a5b22518SShaveta Leekha * initially. then check the status again. 198a5b22518SShaveta Leekha */ 199a5b22518SShaveta Leekha if (check_pll_status(idt_addr)) { 200a5b22518SShaveta Leekha mdelay(1000); 201a5b22518SShaveta Leekha if (check_pll_status(idt_addr)) 202a5b22518SShaveta Leekha return -1; 203a5b22518SShaveta Leekha } 204a5b22518SShaveta Leekha 205a5b22518SShaveta Leekha return 0; 206a5b22518SShaveta Leekha } 207