17174beb6SJohannes Berg /****************************************************************************** 27174beb6SJohannes Berg * 37174beb6SJohannes Berg * This file is provided under a dual BSD/GPLv2 license. When using or 47174beb6SJohannes Berg * redistributing this file, you may do so under either license. 57174beb6SJohannes Berg * 67174beb6SJohannes Berg * GPL LICENSE SUMMARY 77174beb6SJohannes Berg * 87174beb6SJohannes Berg * Copyright(c) 2017 Intel Deutschland GmbH 9a8eb340fSEmmanuel Grumbach * Copyright(c) 2019 - 2020 Intel Corporation 107174beb6SJohannes Berg * 117174beb6SJohannes Berg * This program is free software; you can redistribute it and/or modify 127174beb6SJohannes Berg * it under the terms of version 2 of the GNU General Public License as 137174beb6SJohannes Berg * published by the Free Software Foundation. 147174beb6SJohannes Berg * 157174beb6SJohannes Berg * This program is distributed in the hope that it will be useful, but 167174beb6SJohannes Berg * WITHOUT ANY WARRANTY; without even the implied warranty of 177174beb6SJohannes Berg * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 187174beb6SJohannes Berg * General Public License for more details. 197174beb6SJohannes Berg * 207174beb6SJohannes Berg * The full GNU General Public License is included in this distribution 217174beb6SJohannes Berg * in the file called COPYING. 227174beb6SJohannes Berg * 237174beb6SJohannes Berg * Contact Information: 247174beb6SJohannes Berg * Intel Linux Wireless <linuxwifi@intel.com> 257174beb6SJohannes Berg * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 267174beb6SJohannes Berg * 277174beb6SJohannes Berg * BSD LICENSE 287174beb6SJohannes Berg * 297174beb6SJohannes Berg * Copyright(c) 2017 Intel Deutschland GmbH 30a8eb340fSEmmanuel Grumbach * Copyright(c) 2019 - 2020 Intel Corporation 317174beb6SJohannes Berg * All rights reserved. 327174beb6SJohannes Berg * 337174beb6SJohannes Berg * Redistribution and use in source and binary forms, with or without 347174beb6SJohannes Berg * modification, are permitted provided that the following conditions 357174beb6SJohannes Berg * are met: 367174beb6SJohannes Berg * 377174beb6SJohannes Berg * * Redistributions of source code must retain the above copyright 387174beb6SJohannes Berg * notice, this list of conditions and the following disclaimer. 397174beb6SJohannes Berg * * Redistributions in binary form must reproduce the above copyright 407174beb6SJohannes Berg * notice, this list of conditions and the following disclaimer in 417174beb6SJohannes Berg * the documentation and/or other materials provided with the 427174beb6SJohannes Berg * distribution. 437174beb6SJohannes Berg * * Neither the name Intel Corporation nor the names of its 447174beb6SJohannes Berg * contributors may be used to endorse or promote products derived 457174beb6SJohannes Berg * from this software without specific prior written permission. 467174beb6SJohannes Berg * 477174beb6SJohannes Berg * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 487174beb6SJohannes Berg * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 497174beb6SJohannes Berg * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 507174beb6SJohannes Berg * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 517174beb6SJohannes Berg * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 527174beb6SJohannes Berg * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 537174beb6SJohannes Berg * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 547174beb6SJohannes Berg * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 557174beb6SJohannes Berg * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 567174beb6SJohannes Berg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 577174beb6SJohannes Berg * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 587174beb6SJohannes Berg * 597174beb6SJohannes Berg *****************************************************************************/ 607174beb6SJohannes Berg #include "iwl-drv.h" 617174beb6SJohannes Berg #include "runtime.h" 627174beb6SJohannes Berg #include "dbg.h" 6393b167c1SMordechay Goodstein #include "debugfs.h" 647174beb6SJohannes Berg 65a8eb340fSEmmanuel Grumbach #include "fw/api/soc.h" 66a8eb340fSEmmanuel Grumbach #include "fw/api/commands.h" 67a8eb340fSEmmanuel Grumbach 687174beb6SJohannes Berg void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans, 697174beb6SJohannes Berg const struct iwl_fw *fw, 7093b167c1SMordechay Goodstein const struct iwl_fw_runtime_ops *ops, void *ops_ctx, 7193b167c1SMordechay Goodstein struct dentry *dbgfs_dir) 727174beb6SJohannes Berg { 73c7ab138eSShahar S Matityahu int i; 74c7ab138eSShahar S Matityahu 757174beb6SJohannes Berg memset(fwrt, 0, sizeof(*fwrt)); 767174beb6SJohannes Berg fwrt->trans = trans; 777174beb6SJohannes Berg fwrt->fw = fw; 787174beb6SJohannes Berg fwrt->dev = trans->dev; 797174beb6SJohannes Berg fwrt->dump.conf = FW_DBG_INVALID; 807174beb6SJohannes Berg fwrt->ops = ops; 817174beb6SJohannes Berg fwrt->ops_ctx = ops_ctx; 82c7ab138eSShahar S Matityahu for (i = 0; i < IWL_FW_RUNTIME_DUMP_WK_NUM; i++) { 83c7ab138eSShahar S Matityahu fwrt->dump.wks[i].idx = i; 84c7ab138eSShahar S Matityahu INIT_DELAYED_WORK(&fwrt->dump.wks[i].wk, iwl_fw_error_dump_wk); 85c7ab138eSShahar S Matityahu } 8693b167c1SMordechay Goodstein iwl_fwrt_dbgfs_register(fwrt, dbgfs_dir); 877174beb6SJohannes Berg } 887174beb6SJohannes Berg IWL_EXPORT_SYMBOL(iwl_fw_runtime_init); 897f8ae00fSHaim Dreyfuss 907f8ae00fSHaim Dreyfuss void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt) 917f8ae00fSHaim Dreyfuss { 927f8ae00fSHaim Dreyfuss iwl_fw_suspend_timestamp(fwrt); 937f8ae00fSHaim Dreyfuss } 947f8ae00fSHaim Dreyfuss IWL_EXPORT_SYMBOL(iwl_fw_runtime_suspend); 957f8ae00fSHaim Dreyfuss 967f8ae00fSHaim Dreyfuss void iwl_fw_runtime_resume(struct iwl_fw_runtime *fwrt) 977f8ae00fSHaim Dreyfuss { 987f8ae00fSHaim Dreyfuss iwl_fw_resume_timestamp(fwrt); 997f8ae00fSHaim Dreyfuss } 1007f8ae00fSHaim Dreyfuss IWL_EXPORT_SYMBOL(iwl_fw_runtime_resume); 101a8eb340fSEmmanuel Grumbach 102a8eb340fSEmmanuel Grumbach /* set device type and latency */ 103a8eb340fSEmmanuel Grumbach int iwl_set_soc_latency(struct iwl_fw_runtime *fwrt) 104a8eb340fSEmmanuel Grumbach { 105a8eb340fSEmmanuel Grumbach struct iwl_soc_configuration_cmd cmd = {}; 106a8eb340fSEmmanuel Grumbach struct iwl_host_cmd hcmd = { 107a8eb340fSEmmanuel Grumbach .id = iwl_cmd_id(SOC_CONFIGURATION_CMD, SYSTEM_GROUP, 0), 108a8eb340fSEmmanuel Grumbach .data[0] = &cmd, 109a8eb340fSEmmanuel Grumbach .len[0] = sizeof(cmd), 110a8eb340fSEmmanuel Grumbach }; 111a8eb340fSEmmanuel Grumbach int ret; 112a8eb340fSEmmanuel Grumbach 113a8eb340fSEmmanuel Grumbach /* 114a8eb340fSEmmanuel Grumbach * In VER_1 of this command, the discrete value is considered 115a8eb340fSEmmanuel Grumbach * an integer; In VER_2, it's a bitmask. Since we have only 2 116a8eb340fSEmmanuel Grumbach * values in VER_1, this is backwards-compatible with VER_2, 117a8eb340fSEmmanuel Grumbach * as long as we don't set any other bits. 118a8eb340fSEmmanuel Grumbach */ 119a8eb340fSEmmanuel Grumbach if (!fwrt->trans->trans_cfg->integrated) 120a8eb340fSEmmanuel Grumbach cmd.flags = cpu_to_le32(SOC_CONFIG_CMD_FLAGS_DISCRETE); 121a8eb340fSEmmanuel Grumbach 122a8eb340fSEmmanuel Grumbach BUILD_BUG_ON(IWL_CFG_TRANS_LTR_DELAY_NONE != 123a8eb340fSEmmanuel Grumbach SOC_FLAGS_LTR_APPLY_DELAY_NONE); 124a8eb340fSEmmanuel Grumbach BUILD_BUG_ON(IWL_CFG_TRANS_LTR_DELAY_200US != 125a8eb340fSEmmanuel Grumbach SOC_FLAGS_LTR_APPLY_DELAY_200); 126a8eb340fSEmmanuel Grumbach BUILD_BUG_ON(IWL_CFG_TRANS_LTR_DELAY_2500US != 127a8eb340fSEmmanuel Grumbach SOC_FLAGS_LTR_APPLY_DELAY_2500); 128a8eb340fSEmmanuel Grumbach BUILD_BUG_ON(IWL_CFG_TRANS_LTR_DELAY_1820US != 129a8eb340fSEmmanuel Grumbach SOC_FLAGS_LTR_APPLY_DELAY_1820); 130a8eb340fSEmmanuel Grumbach 131a8eb340fSEmmanuel Grumbach if (fwrt->trans->trans_cfg->ltr_delay != IWL_CFG_TRANS_LTR_DELAY_NONE && 132a8eb340fSEmmanuel Grumbach !WARN_ON(!fwrt->trans->trans_cfg->integrated)) 133a8eb340fSEmmanuel Grumbach cmd.flags |= le32_encode_bits(fwrt->trans->trans_cfg->ltr_delay, 134a8eb340fSEmmanuel Grumbach SOC_FLAGS_LTR_APPLY_DELAY_MASK); 135a8eb340fSEmmanuel Grumbach 136a8eb340fSEmmanuel Grumbach if (iwl_fw_lookup_cmd_ver(fwrt->fw, IWL_ALWAYS_LONG_GROUP, 137*e80bfd11SMordechay Goodstein SCAN_REQ_UMAC, 138*e80bfd11SMordechay Goodstein IWL_FW_CMD_VER_UNKNOWN) >= 2 && 139a8eb340fSEmmanuel Grumbach fwrt->trans->trans_cfg->low_latency_xtal) 140a8eb340fSEmmanuel Grumbach cmd.flags |= cpu_to_le32(SOC_CONFIG_CMD_FLAGS_LOW_LATENCY); 141a8eb340fSEmmanuel Grumbach 142a8eb340fSEmmanuel Grumbach cmd.latency = cpu_to_le32(fwrt->trans->trans_cfg->xtal_latency); 143a8eb340fSEmmanuel Grumbach 144a8eb340fSEmmanuel Grumbach ret = iwl_trans_send_cmd(fwrt->trans, &hcmd); 145a8eb340fSEmmanuel Grumbach if (ret) 146a8eb340fSEmmanuel Grumbach IWL_ERR(fwrt, "Failed to set soc latency: %d\n", ret); 147a8eb340fSEmmanuel Grumbach return ret; 148a8eb340fSEmmanuel Grumbach } 149a8eb340fSEmmanuel Grumbach IWL_EXPORT_SYMBOL(iwl_set_soc_latency); 150