merlin16_pwr_mgt.c (5494B)
1 /************************************************************************************** 2 ************************************************************************************** 3 * File Name : merlin16_pwr_mgt.c * 4 * Created On : 04 Nov 2015 * 5 * Created By : Brent Roberts * 6 * Description : APIs for Serdes IPs * 7 * Revision : * 8 * * 9 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 10 * 11 * Copyright 2007-2019 Broadcom Inc. All rights reserved. * 12 * No portions of this material may be reproduced in any form without * 13 * the written permission of: * 14 * Broadcom Corporation * 15 * 5300 California Avenue * 16 * Irvine, CA 92617 * 17 * * 18 * All information contained in this document is Broadcom Corporation * 19 * company private proprietary, and trade secret. * 20 */ 21 22 /** @file merlin16_pwr_mgt.c 23 * Implementation of API power management functions 24 */ 25 26 #include <phymod/phymod.h> 27 #include <phymod/phymod_system.h> 28 #include "merlin16_pwr_mgt.h" 29 #include "merlin16_common.h" 30 #include "merlin16_functions.h" 31 #include "merlin16_internal.h" 32 #include "merlin16_internal_error.h" 33 #include "merlin16_select_defns.h" 34 #include "merlin16_config.h" 35 36 37 38 /***************************/ 39 /* Configure Serdes IDDQ */ 40 /***************************/ 41 42 err_code_t merlin16_core_config_for_iddq(srds_access_t *sa__) { 43 44 EFUN(wrc_ams_pll_pwrdn(0x1)); 45 return (ERR_CODE_NONE); 46 } 47 48 49 err_code_t merlin16_lane_config_for_iddq(srds_access_t *sa__) { 50 51 /* Use frc/frc_val to force all RX and TX clk_vld signals to 0 */ 52 EFUN(wr_pmd_rx_clk_vld_frc_val(0x0)); 53 EFUN(wr_pmd_rx_clk_vld_frc(0x1)); 54 EFUN(wr_pmd_tx_clk_vld_frc_val(0x0)); 55 EFUN(wr_pmd_tx_clk_vld_frc(0x1)); 56 57 /* Use frc/frc_val to force all pmd_rx_lock signals to 0 */ 58 EFUN(wr_rx_dsc_lock_frc_val(0x0)); 59 EFUN(wr_rx_dsc_lock_frc(0x1)); 60 61 /* Switch all the lane clocks to comclk by writing to RX/TX comclk_sel registers */ 62 EFUN(wr_ln_rx_s_comclk_sel(0x1)); 63 EFUN(wr_ln_tx_s_comclk_sel(0x1)); 64 65 /* Assert all the AFE pwrdn/reset pins using frc/frc_val to make sure AFE is in lowest possible power mode */ 66 EFUN(wr_afe_tx_pwrdn_frc_val(0x1)); 67 EFUN(wr_afe_tx_pwrdn_frc(0x1)); 68 EFUN(wr_afe_rx_pwrdn_frc_val(0x1)); 69 EFUN(wr_afe_rx_pwrdn_frc(0x1)); 70 EFUN(wr_afe_tx_reset_frc_val(0x1)); 71 EFUN(wr_afe_tx_reset_frc(0x1)); 72 EFUN(wr_afe_rx_reset_frc_val(0x1)); 73 EFUN(wr_afe_rx_reset_frc(0x1)); 74 75 /* Set pmd_iddq pin to enable IDDQ */ 76 return (ERR_CODE_NONE); 77 } 78 79 /****************************************************/ 80 /* Serdes Powerdown, ClockGate and Deep_Powerdown */ 81 /****************************************************/ 82 83 err_code_t merlin16_core_pwrdn(srds_access_t *sa__, enum srds_core_pwrdn_mode_enum mode) { 84 switch(mode) { 85 case PWR_ON: 86 EFUN(merlin16_INTERNAL_core_clkgate(sa__, 0)); 87 EFUN(wrc_ams_pll_pwrdn(0x0)); 88 EFUN(wrc_afe_s_pll_pwrdn(0x0)); 89 EFUN(merlin16_core_dp_reset(sa__, 0x0)); 90 break; 91 case PWRDN: 92 EFUN(merlin16_core_dp_reset(sa__, 1)); 93 EFUN(USR_DELAY_NS(500)); /* wait >50 comclk cycles */ 94 EFUN(wrc_afe_s_pll_pwrdn(0x1)); 95 EFUN(USR_DELAY_NS(500)); /* wait >50 comclk cycles */ 96 EFUN(wrc_ams_pll_pwrdn(0x1)); 97 break; 98 case PWRDN_DEEP: 99 EFUN(merlin16_core_dp_reset(sa__, 1)); 100 EFUN(USR_DELAY_NS(500)); /* wait >50 comclk cycles */ 101 EFUN(wrc_afe_s_pll_pwrdn(0x1)); 102 EFUN(USR_DELAY_NS(500)); /* wait >50 comclk cycles */ 103 EFUN(wrc_ams_pll_pwrdn(0x1)); 104 EFUN(merlin16_INTERNAL_core_clkgate(sa__, 1)); 105 break; 106 default: 107 EFUN(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 108 break; 109 } 110 return ERR_CODE_NONE; 111 } 112 113 err_code_t merlin16_lane_pwrdn(srds_access_t *sa__, enum srds_core_pwrdn_mode_enum mode) { 114 115 switch(mode) { 116 case PWR_ON: 117 EFUN(wr_ln_tx_s_pwrdn(0x0)); 118 EFUN(wr_ln_rx_s_pwrdn(0x0)); 119 EFUN(merlin16_INTERNAL_lane_clkgate(sa__, 0)); 120 break; 121 case PWRDN: 122 /* do the RX first, since that is what is most users care about */ 123 EFUN(wr_ln_rx_s_pwrdn(0x1)); 124 EFUN(wr_ln_tx_s_pwrdn(0x1)); 125 break; 126 case PWRDN_DEEP: 127 /* do the RX first, since that is what is most users care about */ 128 EFUN(wr_ln_rx_s_pwrdn(0x1)); 129 EFUN(wr_ln_tx_s_pwrdn(0x1)); 130 EFUN(merlin16_INTERNAL_lane_clkgate(sa__, 1)); 131 EFUN(wr_ln_dp_s_rstb(0x0)); 132 break; 133 case PWRDN_TX: 134 EFUN(wr_ln_tx_s_pwrdn(0x1)); 135 break; 136 case PWRDN_RX: 137 EFUN(wr_ln_rx_s_pwrdn(0x1)); 138 break; 139 default : 140 return(_error(ERR_CODE_BAD_PTR_OR_INVALID_INPUT)); 141 } 142 return (ERR_CODE_NONE); 143 }