ath11k: read and write registers below unwindowed address
For QCA6390, host can read and write registers below unwindowed address directly without programming the window register. For registers below bar0 + 4k - 32, host can read and write regardless of the power save state. Shadow registers are located below bar0 + 4K - 32. Before MHI power up, there is no need to wakeup MHI so ini_done is added to indicate it. Tested-on: QCA6390 hw2.0 PCI WLAN.HST.1.0.1-01740-QCAHSTSWPLZ_V2_TO_X86-1 Signed-off-by: Carl Huang <cjhuang@codeaurora.org> Signed-off-by: Kalle Valo <kvalo@codeaurora.org> Link: https://lore.kernel.org/r/1601544890-13450-2-git-send-email-kvalo@codeaurora.org
This commit is contained in:
		
							parent
							
								
									089ba909f8
								
							
						
					
					
						commit
						a05bd85133
					
				| @ -28,6 +28,12 @@ | ||||
| #define TCSR_SOC_HW_VERSION_MAJOR_MASK	GENMASK(16, 8) | ||||
| #define TCSR_SOC_HW_VERSION_MINOR_MASK	GENMASK(7, 0) | ||||
| 
 | ||||
| /* BAR0 + 4k is always accessible, and no
 | ||||
|  * need to force wakeup. | ||||
|  * 4K - 32 = 0xFE0 | ||||
|  */ | ||||
| #define ACCESS_ALWAYS_OFF 0xFE0 | ||||
| 
 | ||||
| #define QCA6390_DEVICE_ID		0x1101 | ||||
| 
 | ||||
| static const struct pci_device_id ath11k_pci_id_table[] = { | ||||
| @ -128,6 +134,13 @@ void ath11k_pci_write32(struct ath11k_base *ab, u32 offset, u32 value) | ||||
| { | ||||
| 	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); | ||||
| 
 | ||||
| 	/* for offset beyond BAR + 4K - 32, may
 | ||||
| 	 * need to wakeup MHI to access. | ||||
| 	 */ | ||||
| 	if (test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && | ||||
| 	    offset >= ACCESS_ALWAYS_OFF) | ||||
| 		mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); | ||||
| 
 | ||||
| 	if (offset < WINDOW_START) { | ||||
| 		iowrite32(value, ab->mem  + offset); | ||||
| 	} else { | ||||
| @ -136,6 +149,10 @@ void ath11k_pci_write32(struct ath11k_base *ab, u32 offset, u32 value) | ||||
| 		iowrite32(value, ab->mem + WINDOW_START + (offset & WINDOW_RANGE_MASK)); | ||||
| 		spin_unlock_bh(&ab_pci->window_lock); | ||||
| 	} | ||||
| 
 | ||||
| 	if (test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && | ||||
| 	    offset >= ACCESS_ALWAYS_OFF) | ||||
| 		mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); | ||||
| } | ||||
| 
 | ||||
| u32 ath11k_pci_read32(struct ath11k_base *ab, u32 offset) | ||||
| @ -143,6 +160,13 @@ u32 ath11k_pci_read32(struct ath11k_base *ab, u32 offset) | ||||
| 	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); | ||||
| 	u32 val; | ||||
| 
 | ||||
| 	/* for offset beyond BAR + 4K - 32, may
 | ||||
| 	 * need to wakeup MHI to access. | ||||
| 	 */ | ||||
| 	if (test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && | ||||
| 	    offset >= ACCESS_ALWAYS_OFF) | ||||
| 		mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); | ||||
| 
 | ||||
| 	if (offset < WINDOW_START) { | ||||
| 		val = ioread32(ab->mem + offset); | ||||
| 	} else { | ||||
| @ -152,6 +176,10 @@ u32 ath11k_pci_read32(struct ath11k_base *ab, u32 offset) | ||||
| 		spin_unlock_bh(&ab_pci->window_lock); | ||||
| 	} | ||||
| 
 | ||||
| 	if (test_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags) && | ||||
| 	    offset >= ACCESS_ALWAYS_OFF) | ||||
| 		mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); | ||||
| 
 | ||||
| 	return val; | ||||
| } | ||||
| 
 | ||||
| @ -731,6 +759,8 @@ static int ath11k_pci_power_up(struct ath11k_base *ab) | ||||
| 	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); | ||||
| 	int ret; | ||||
| 
 | ||||
| 	ab_pci->register_window = 0; | ||||
| 	clear_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags); | ||||
| 	ath11k_pci_sw_reset(ab_pci->ab); | ||||
| 
 | ||||
| 	ret = ath11k_mhi_start(ab_pci); | ||||
| @ -747,6 +777,7 @@ static void ath11k_pci_power_down(struct ath11k_base *ab) | ||||
| 	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); | ||||
| 
 | ||||
| 	ath11k_mhi_stop(ab_pci); | ||||
| 	clear_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags); | ||||
| 	ath11k_pci_force_wake(ab_pci->ab); | ||||
| 	ath11k_pci_sw_reset(ab_pci->ab); | ||||
| } | ||||
| @ -775,6 +806,10 @@ static void ath11k_pci_stop(struct ath11k_base *ab) | ||||
| 
 | ||||
| static int ath11k_pci_start(struct ath11k_base *ab) | ||||
| { | ||||
| 	struct ath11k_pci *ab_pci = ath11k_pci_priv(ab); | ||||
| 
 | ||||
| 	set_bit(ATH11K_PCI_FLAG_INIT_DONE, &ab_pci->flags); | ||||
| 
 | ||||
| 	ath11k_pci_ce_irqs_enable(ab); | ||||
| 	ath11k_ce_rx_post_buf(ab); | ||||
| 
 | ||||
|  | ||||
| @ -36,6 +36,10 @@ struct ath11k_msi_config { | ||||
| 	struct ath11k_msi_user *users; | ||||
| }; | ||||
| 
 | ||||
| enum ath11k_pci_flags { | ||||
| 	ATH11K_PCI_FLAG_INIT_DONE, | ||||
| }; | ||||
| 
 | ||||
| struct ath11k_pci { | ||||
| 	struct pci_dev *pdev; | ||||
| 	struct ath11k_base *ab; | ||||
| @ -48,6 +52,9 @@ struct ath11k_pci { | ||||
| 
 | ||||
| 	/* protects register_window above */ | ||||
| 	spinlock_t window_lock; | ||||
| 
 | ||||
| 	/* enum ath11k_pci_flags */ | ||||
| 	unsigned long flags; | ||||
| }; | ||||
| 
 | ||||
| static inline struct ath11k_pci *ath11k_pci_priv(struct ath11k_base *ab) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user