brintos

brintos / linux-shallow public Read only

0
0
Text · 3.1 KiB · 0fe6257 Raw
131 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* Atlantic Network Driver3 * Copyright (C) 2020 Marvell International Ltd.4 */5 6#include <linux/iopoll.h>7 8#include "aq_hw_utils.h"9#include "hw_atl/hw_atl_utils.h"10#include "hw_atl2_utils.h"11#include "hw_atl2_llh.h"12#include "hw_atl2_llh_internal.h"13 14#define HW_ATL2_FW_VER_1X          0x01000000U15 16#define AQ_A2_BOOT_STARTED         BIT(0x18)17#define AQ_A2_CRASH_INIT           BIT(0x1B)18#define AQ_A2_BOOT_CODE_FAILED     BIT(0x1C)19#define AQ_A2_FW_INIT_FAILED       BIT(0x1D)20#define AQ_A2_FW_INIT_COMP_SUCCESS BIT(0x1F)21 22#define AQ_A2_FW_BOOT_FAILED_MASK (AQ_A2_CRASH_INIT | \23				   AQ_A2_BOOT_CODE_FAILED | \24				   AQ_A2_FW_INIT_FAILED)25#define AQ_A2_FW_BOOT_COMPLETE_MASK (AQ_A2_FW_BOOT_FAILED_MASK | \26				     AQ_A2_FW_INIT_COMP_SUCCESS)27 28#define AQ_A2_FW_BOOT_REQ_REBOOT        BIT(0x0)29#define AQ_A2_FW_BOOT_REQ_HOST_BOOT     BIT(0x8)30#define AQ_A2_FW_BOOT_REQ_MAC_FAST_BOOT BIT(0xA)31#define AQ_A2_FW_BOOT_REQ_PHY_FAST_BOOT BIT(0xB)32 33int hw_atl2_utils_initfw(struct aq_hw_s *self, const struct aq_fw_ops **fw_ops)34{35	int err;36 37	self->fw_ver_actual = hw_atl2_utils_get_fw_version(self);38 39	if (hw_atl_utils_ver_match(HW_ATL2_FW_VER_1X, self->fw_ver_actual)) {40		*fw_ops = &aq_a2_fw_ops;41	} else {42		aq_pr_err("Bad FW version detected: %x, but continue\n",43			  self->fw_ver_actual);44		*fw_ops = &aq_a2_fw_ops;45	}46	aq_pr_trace("Detect ATL2FW %x\n", self->fw_ver_actual);47	self->aq_fw_ops = *fw_ops;48	err = self->aq_fw_ops->init(self);49 50	self->chip_features |= ATL_HW_CHIP_ANTIGUA;51 52	return err;53}54 55static bool hw_atl2_mcp_boot_complete(struct aq_hw_s *self)56{57	u32 rbl_status;58 59	rbl_status = hw_atl2_mif_mcp_boot_reg_get(self);60	if (rbl_status & AQ_A2_FW_BOOT_COMPLETE_MASK)61		return true;62 63	/* Host boot requested */64	if (hw_atl2_mif_host_req_int_get(self) & HW_ATL2_MCP_HOST_REQ_INT_READY)65		return true;66 67	return false;68}69 70int hw_atl2_utils_soft_reset(struct aq_hw_s *self)71{72	bool rbl_complete = false;73	u32 rbl_status = 0;74	u32 rbl_request;75	int err;76 77	hw_atl2_mif_host_req_int_clr(self, 0x01);78	rbl_request = AQ_A2_FW_BOOT_REQ_REBOOT;79#ifdef AQ_CFG_FAST_START80	rbl_request |= AQ_A2_FW_BOOT_REQ_MAC_FAST_BOOT;81#endif82	hw_atl2_mif_mcp_boot_reg_set(self, rbl_request);83 84	/* Wait for RBL boot */85	err = readx_poll_timeout_atomic(hw_atl2_mif_mcp_boot_reg_get, self,86				rbl_status,87				((rbl_status & AQ_A2_BOOT_STARTED) &&88				 (rbl_status != 0xFFFFFFFFu)),89				10, 200000);90	if (err) {91		aq_pr_err("Boot code hanged");92		goto err_exit;93	}94 95	err = readx_poll_timeout_atomic(hw_atl2_mcp_boot_complete, self,96					rbl_complete,97					rbl_complete,98					10, 2000000);99 100	if (err) {101		aq_pr_err("FW Restart timed out");102		goto err_exit;103	}104 105	rbl_status = hw_atl2_mif_mcp_boot_reg_get(self);106 107	if (rbl_status & AQ_A2_FW_BOOT_FAILED_MASK) {108		err = -EIO;109		aq_pr_err("FW Restart failed");110		goto err_exit;111	}112 113	if (hw_atl2_mif_host_req_int_get(self) &114	    HW_ATL2_MCP_HOST_REQ_INT_READY) {115		err = -EIO;116		aq_pr_err("No FW detected. Dynamic FW load not implemented");117		goto err_exit;118	}119 120	if (self->aq_fw_ops) {121		err = self->aq_fw_ops->init(self);122		if (err) {123			aq_pr_err("FW Init failed");124			goto err_exit;125		}126	}127 128err_exit:129	return err;130}131