18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright (c) 2010 Broadcom Corporation 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * Permission to use, copy, modify, and/or distribute this software for any 58c2ecf20Sopenharmony_ci * purpose with or without fee is hereby granted, provided that the above 68c2ecf20Sopenharmony_ci * copyright notice and this permission notice appear in all copies. 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 98c2ecf20Sopenharmony_ci * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 108c2ecf20Sopenharmony_ci * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 118c2ecf20Sopenharmony_ci * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 128c2ecf20Sopenharmony_ci * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 138c2ecf20Sopenharmony_ci * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 148c2ecf20Sopenharmony_ci * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 158c2ecf20Sopenharmony_ci * 168c2ecf20Sopenharmony_ci * File contents: support functions for PCI/PCIe 178c2ecf20Sopenharmony_ci */ 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#include <linux/delay.h> 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#include <defs.h> 248c2ecf20Sopenharmony_ci#include <chipcommon.h> 258c2ecf20Sopenharmony_ci#include <brcmu_utils.h> 268c2ecf20Sopenharmony_ci#include <brcm_hw_ids.h> 278c2ecf20Sopenharmony_ci#include <soc.h> 288c2ecf20Sopenharmony_ci#include "types.h" 298c2ecf20Sopenharmony_ci#include "pub.h" 308c2ecf20Sopenharmony_ci#include "pmu.h" 318c2ecf20Sopenharmony_ci#include "aiutils.h" 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci/* slow_clk_ctl */ 348c2ecf20Sopenharmony_ci /* slow clock source mask */ 358c2ecf20Sopenharmony_ci#define SCC_SS_MASK 0x00000007 368c2ecf20Sopenharmony_ci /* source of slow clock is LPO */ 378c2ecf20Sopenharmony_ci#define SCC_SS_LPO 0x00000000 388c2ecf20Sopenharmony_ci /* source of slow clock is crystal */ 398c2ecf20Sopenharmony_ci#define SCC_SS_XTAL 0x00000001 408c2ecf20Sopenharmony_ci /* source of slow clock is PCI */ 418c2ecf20Sopenharmony_ci#define SCC_SS_PCI 0x00000002 428c2ecf20Sopenharmony_ci /* LPOFreqSel, 1: 160Khz, 0: 32KHz */ 438c2ecf20Sopenharmony_ci#define SCC_LF 0x00000200 448c2ecf20Sopenharmony_ci /* LPOPowerDown, 1: LPO is disabled, 0: LPO is enabled */ 458c2ecf20Sopenharmony_ci#define SCC_LP 0x00000400 468c2ecf20Sopenharmony_ci /* ForceSlowClk, 1: sb/cores running on slow clock, 0: power logic control */ 478c2ecf20Sopenharmony_ci#define SCC_FS 0x00000800 488c2ecf20Sopenharmony_ci /* IgnorePllOffReq, 1/0: 498c2ecf20Sopenharmony_ci * power logic ignores/honors PLL clock disable requests from core 508c2ecf20Sopenharmony_ci */ 518c2ecf20Sopenharmony_ci#define SCC_IP 0x00001000 528c2ecf20Sopenharmony_ci /* XtalControlEn, 1/0: 538c2ecf20Sopenharmony_ci * power logic does/doesn't disable crystal when appropriate 548c2ecf20Sopenharmony_ci */ 558c2ecf20Sopenharmony_ci#define SCC_XC 0x00002000 568c2ecf20Sopenharmony_ci /* XtalPU (RO), 1/0: crystal running/disabled */ 578c2ecf20Sopenharmony_ci#define SCC_XP 0x00004000 588c2ecf20Sopenharmony_ci /* ClockDivider (SlowClk = 1/(4+divisor)) */ 598c2ecf20Sopenharmony_ci#define SCC_CD_MASK 0xffff0000 608c2ecf20Sopenharmony_ci#define SCC_CD_SHIFT 16 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci/* system_clk_ctl */ 638c2ecf20Sopenharmony_ci /* ILPen: Enable Idle Low Power */ 648c2ecf20Sopenharmony_ci#define SYCC_IE 0x00000001 658c2ecf20Sopenharmony_ci /* ALPen: Enable Active Low Power */ 668c2ecf20Sopenharmony_ci#define SYCC_AE 0x00000002 678c2ecf20Sopenharmony_ci /* ForcePLLOn */ 688c2ecf20Sopenharmony_ci#define SYCC_FP 0x00000004 698c2ecf20Sopenharmony_ci /* Force ALP (or HT if ALPen is not set */ 708c2ecf20Sopenharmony_ci#define SYCC_AR 0x00000008 718c2ecf20Sopenharmony_ci /* Force HT */ 728c2ecf20Sopenharmony_ci#define SYCC_HR 0x00000010 738c2ecf20Sopenharmony_ci /* ClkDiv (ILP = 1/(4 * (divisor + 1)) */ 748c2ecf20Sopenharmony_ci#define SYCC_CD_MASK 0xffff0000 758c2ecf20Sopenharmony_ci#define SYCC_CD_SHIFT 16 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci#define CST4329_SPROM_OTP_SEL_MASK 0x00000003 788c2ecf20Sopenharmony_ci /* OTP is powered up, use def. CIS, no SPROM */ 798c2ecf20Sopenharmony_ci#define CST4329_DEFCIS_SEL 0 808c2ecf20Sopenharmony_ci /* OTP is powered up, SPROM is present */ 818c2ecf20Sopenharmony_ci#define CST4329_SPROM_SEL 1 828c2ecf20Sopenharmony_ci /* OTP is powered up, no SPROM */ 838c2ecf20Sopenharmony_ci#define CST4329_OTP_SEL 2 848c2ecf20Sopenharmony_ci /* OTP is powered down, SPROM is present */ 858c2ecf20Sopenharmony_ci#define CST4329_OTP_PWRDN 3 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci#define CST4329_SPI_SDIO_MODE_MASK 0x00000004 888c2ecf20Sopenharmony_ci#define CST4329_SPI_SDIO_MODE_SHIFT 2 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci/* 43224 chip-specific ChipControl register bits */ 918c2ecf20Sopenharmony_ci#define CCTRL43224_GPIO_TOGGLE 0x8000 928c2ecf20Sopenharmony_ci /* 12 mA drive strength */ 938c2ecf20Sopenharmony_ci#define CCTRL_43224A0_12MA_LED_DRIVE 0x00F000F0 948c2ecf20Sopenharmony_ci /* 12 mA drive strength for later 43224s */ 958c2ecf20Sopenharmony_ci#define CCTRL_43224B0_12MA_LED_DRIVE 0xF0 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci/* 43236 Chip specific ChipStatus register bits */ 988c2ecf20Sopenharmony_ci#define CST43236_SFLASH_MASK 0x00000040 998c2ecf20Sopenharmony_ci#define CST43236_OTP_MASK 0x00000080 1008c2ecf20Sopenharmony_ci#define CST43236_HSIC_MASK 0x00000100 /* USB/HSIC */ 1018c2ecf20Sopenharmony_ci#define CST43236_BP_CLK 0x00000200 /* 120/96Mbps */ 1028c2ecf20Sopenharmony_ci#define CST43236_BOOT_MASK 0x00001800 1038c2ecf20Sopenharmony_ci#define CST43236_BOOT_SHIFT 11 1048c2ecf20Sopenharmony_ci#define CST43236_BOOT_FROM_SRAM 0 /* boot from SRAM, ARM in reset */ 1058c2ecf20Sopenharmony_ci#define CST43236_BOOT_FROM_ROM 1 /* boot from ROM */ 1068c2ecf20Sopenharmony_ci#define CST43236_BOOT_FROM_FLASH 2 /* boot from FLASH */ 1078c2ecf20Sopenharmony_ci#define CST43236_BOOT_FROM_INVALID 3 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_ci/* 4331 chip-specific ChipControl register bits */ 1108c2ecf20Sopenharmony_ci /* 0 disable */ 1118c2ecf20Sopenharmony_ci#define CCTRL4331_BT_COEXIST (1<<0) 1128c2ecf20Sopenharmony_ci /* 0 SECI is disabled (JTAG functional) */ 1138c2ecf20Sopenharmony_ci#define CCTRL4331_SECI (1<<1) 1148c2ecf20Sopenharmony_ci /* 0 disable */ 1158c2ecf20Sopenharmony_ci#define CCTRL4331_EXT_LNA (1<<2) 1168c2ecf20Sopenharmony_ci /* sprom/gpio13-15 mux */ 1178c2ecf20Sopenharmony_ci#define CCTRL4331_SPROM_GPIO13_15 (1<<3) 1188c2ecf20Sopenharmony_ci /* 0 ext pa disable, 1 ext pa enabled */ 1198c2ecf20Sopenharmony_ci#define CCTRL4331_EXTPA_EN (1<<4) 1208c2ecf20Sopenharmony_ci /* set drive out GPIO_CLK on sprom_cs pin */ 1218c2ecf20Sopenharmony_ci#define CCTRL4331_GPIOCLK_ON_SPROMCS (1<<5) 1228c2ecf20Sopenharmony_ci /* use sprom_cs pin as PCIE mdio interface */ 1238c2ecf20Sopenharmony_ci#define CCTRL4331_PCIE_MDIO_ON_SPROMCS (1<<6) 1248c2ecf20Sopenharmony_ci /* aband extpa will be at gpio2/5 and sprom_dout */ 1258c2ecf20Sopenharmony_ci#define CCTRL4331_EXTPA_ON_GPIO2_5 (1<<7) 1268c2ecf20Sopenharmony_ci /* override core control on pipe_AuxClkEnable */ 1278c2ecf20Sopenharmony_ci#define CCTRL4331_OVR_PIPEAUXCLKEN (1<<8) 1288c2ecf20Sopenharmony_ci /* override core control on pipe_AuxPowerDown */ 1298c2ecf20Sopenharmony_ci#define CCTRL4331_OVR_PIPEAUXPWRDOWN (1<<9) 1308c2ecf20Sopenharmony_ci /* pcie_auxclkenable */ 1318c2ecf20Sopenharmony_ci#define CCTRL4331_PCIE_AUXCLKEN (1<<10) 1328c2ecf20Sopenharmony_ci /* pcie_pipe_pllpowerdown */ 1338c2ecf20Sopenharmony_ci#define CCTRL4331_PCIE_PIPE_PLLDOWN (1<<11) 1348c2ecf20Sopenharmony_ci /* enable bt_shd0 at gpio4 */ 1358c2ecf20Sopenharmony_ci#define CCTRL4331_BT_SHD0_ON_GPIO4 (1<<16) 1368c2ecf20Sopenharmony_ci /* enable bt_shd1 at gpio5 */ 1378c2ecf20Sopenharmony_ci#define CCTRL4331_BT_SHD1_ON_GPIO5 (1<<17) 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci/* 4331 Chip specific ChipStatus register bits */ 1408c2ecf20Sopenharmony_ci /* crystal frequency 20/40Mhz */ 1418c2ecf20Sopenharmony_ci#define CST4331_XTAL_FREQ 0x00000001 1428c2ecf20Sopenharmony_ci#define CST4331_SPROM_PRESENT 0x00000002 1438c2ecf20Sopenharmony_ci#define CST4331_OTP_PRESENT 0x00000004 1448c2ecf20Sopenharmony_ci#define CST4331_LDO_RF 0x00000008 1458c2ecf20Sopenharmony_ci#define CST4331_LDO_PAR 0x00000010 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci/* 4319 chip-specific ChipStatus register bits */ 1488c2ecf20Sopenharmony_ci#define CST4319_SPI_CPULESSUSB 0x00000001 1498c2ecf20Sopenharmony_ci#define CST4319_SPI_CLK_POL 0x00000002 1508c2ecf20Sopenharmony_ci#define CST4319_SPI_CLK_PH 0x00000008 1518c2ecf20Sopenharmony_ci /* gpio [7:6], SDIO CIS selection */ 1528c2ecf20Sopenharmony_ci#define CST4319_SPROM_OTP_SEL_MASK 0x000000c0 1538c2ecf20Sopenharmony_ci#define CST4319_SPROM_OTP_SEL_SHIFT 6 1548c2ecf20Sopenharmony_ci /* use default CIS, OTP is powered up */ 1558c2ecf20Sopenharmony_ci#define CST4319_DEFCIS_SEL 0x00000000 1568c2ecf20Sopenharmony_ci /* use SPROM, OTP is powered up */ 1578c2ecf20Sopenharmony_ci#define CST4319_SPROM_SEL 0x00000040 1588c2ecf20Sopenharmony_ci /* use OTP, OTP is powered up */ 1598c2ecf20Sopenharmony_ci#define CST4319_OTP_SEL 0x00000080 1608c2ecf20Sopenharmony_ci /* use SPROM, OTP is powered down */ 1618c2ecf20Sopenharmony_ci#define CST4319_OTP_PWRDN 0x000000c0 1628c2ecf20Sopenharmony_ci /* gpio [8], sdio/usb mode */ 1638c2ecf20Sopenharmony_ci#define CST4319_SDIO_USB_MODE 0x00000100 1648c2ecf20Sopenharmony_ci#define CST4319_REMAP_SEL_MASK 0x00000600 1658c2ecf20Sopenharmony_ci#define CST4319_ILPDIV_EN 0x00000800 1668c2ecf20Sopenharmony_ci#define CST4319_XTAL_PD_POL 0x00001000 1678c2ecf20Sopenharmony_ci#define CST4319_LPO_SEL 0x00002000 1688c2ecf20Sopenharmony_ci#define CST4319_RES_INIT_MODE 0x0000c000 1698c2ecf20Sopenharmony_ci /* PALDO is configured with external PNP */ 1708c2ecf20Sopenharmony_ci#define CST4319_PALDO_EXTPNP 0x00010000 1718c2ecf20Sopenharmony_ci#define CST4319_CBUCK_MODE_MASK 0x00060000 1728c2ecf20Sopenharmony_ci#define CST4319_CBUCK_MODE_BURST 0x00020000 1738c2ecf20Sopenharmony_ci#define CST4319_CBUCK_MODE_LPBURST 0x00060000 1748c2ecf20Sopenharmony_ci#define CST4319_RCAL_VALID 0x01000000 1758c2ecf20Sopenharmony_ci#define CST4319_RCAL_VALUE_MASK 0x3e000000 1768c2ecf20Sopenharmony_ci#define CST4319_RCAL_VALUE_SHIFT 25 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci/* 4336 chip-specific ChipStatus register bits */ 1798c2ecf20Sopenharmony_ci#define CST4336_SPI_MODE_MASK 0x00000001 1808c2ecf20Sopenharmony_ci#define CST4336_SPROM_PRESENT 0x00000002 1818c2ecf20Sopenharmony_ci#define CST4336_OTP_PRESENT 0x00000004 1828c2ecf20Sopenharmony_ci#define CST4336_ARMREMAP_0 0x00000008 1838c2ecf20Sopenharmony_ci#define CST4336_ILPDIV_EN_MASK 0x00000010 1848c2ecf20Sopenharmony_ci#define CST4336_ILPDIV_EN_SHIFT 4 1858c2ecf20Sopenharmony_ci#define CST4336_XTAL_PD_POL_MASK 0x00000020 1868c2ecf20Sopenharmony_ci#define CST4336_XTAL_PD_POL_SHIFT 5 1878c2ecf20Sopenharmony_ci#define CST4336_LPO_SEL_MASK 0x00000040 1888c2ecf20Sopenharmony_ci#define CST4336_LPO_SEL_SHIFT 6 1898c2ecf20Sopenharmony_ci#define CST4336_RES_INIT_MODE_MASK 0x00000180 1908c2ecf20Sopenharmony_ci#define CST4336_RES_INIT_MODE_SHIFT 7 1918c2ecf20Sopenharmony_ci#define CST4336_CBUCK_MODE_MASK 0x00000600 1928c2ecf20Sopenharmony_ci#define CST4336_CBUCK_MODE_SHIFT 9 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci/* 4313 chip-specific ChipStatus register bits */ 1958c2ecf20Sopenharmony_ci#define CST4313_SPROM_PRESENT 1 1968c2ecf20Sopenharmony_ci#define CST4313_OTP_PRESENT 2 1978c2ecf20Sopenharmony_ci#define CST4313_SPROM_OTP_SEL_MASK 0x00000002 1988c2ecf20Sopenharmony_ci#define CST4313_SPROM_OTP_SEL_SHIFT 0 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci/* 4313 Chip specific ChipControl register bits */ 2018c2ecf20Sopenharmony_ci /* 12 mA drive strengh for later 4313 */ 2028c2ecf20Sopenharmony_ci#define CCTRL_4313_12MA_LED_DRIVE 0x00000007 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci/* Manufacturer Ids */ 2058c2ecf20Sopenharmony_ci#define MFGID_ARM 0x43b 2068c2ecf20Sopenharmony_ci#define MFGID_BRCM 0x4bf 2078c2ecf20Sopenharmony_ci#define MFGID_MIPS 0x4a7 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_ci/* Enumeration ROM registers */ 2108c2ecf20Sopenharmony_ci#define ER_EROMENTRY 0x000 2118c2ecf20Sopenharmony_ci#define ER_REMAPCONTROL 0xe00 2128c2ecf20Sopenharmony_ci#define ER_REMAPSELECT 0xe04 2138c2ecf20Sopenharmony_ci#define ER_MASTERSELECT 0xe10 2148c2ecf20Sopenharmony_ci#define ER_ITCR 0xf00 2158c2ecf20Sopenharmony_ci#define ER_ITIP 0xf04 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci/* Erom entries */ 2188c2ecf20Sopenharmony_ci#define ER_TAG 0xe 2198c2ecf20Sopenharmony_ci#define ER_TAG1 0x6 2208c2ecf20Sopenharmony_ci#define ER_VALID 1 2218c2ecf20Sopenharmony_ci#define ER_CI 0 2228c2ecf20Sopenharmony_ci#define ER_MP 2 2238c2ecf20Sopenharmony_ci#define ER_ADD 4 2248c2ecf20Sopenharmony_ci#define ER_END 0xe 2258c2ecf20Sopenharmony_ci#define ER_BAD 0xffffffff 2268c2ecf20Sopenharmony_ci 2278c2ecf20Sopenharmony_ci/* EROM CompIdentA */ 2288c2ecf20Sopenharmony_ci#define CIA_MFG_MASK 0xfff00000 2298c2ecf20Sopenharmony_ci#define CIA_MFG_SHIFT 20 2308c2ecf20Sopenharmony_ci#define CIA_CID_MASK 0x000fff00 2318c2ecf20Sopenharmony_ci#define CIA_CID_SHIFT 8 2328c2ecf20Sopenharmony_ci#define CIA_CCL_MASK 0x000000f0 2338c2ecf20Sopenharmony_ci#define CIA_CCL_SHIFT 4 2348c2ecf20Sopenharmony_ci 2358c2ecf20Sopenharmony_ci/* EROM CompIdentB */ 2368c2ecf20Sopenharmony_ci#define CIB_REV_MASK 0xff000000 2378c2ecf20Sopenharmony_ci#define CIB_REV_SHIFT 24 2388c2ecf20Sopenharmony_ci#define CIB_NSW_MASK 0x00f80000 2398c2ecf20Sopenharmony_ci#define CIB_NSW_SHIFT 19 2408c2ecf20Sopenharmony_ci#define CIB_NMW_MASK 0x0007c000 2418c2ecf20Sopenharmony_ci#define CIB_NMW_SHIFT 14 2428c2ecf20Sopenharmony_ci#define CIB_NSP_MASK 0x00003e00 2438c2ecf20Sopenharmony_ci#define CIB_NSP_SHIFT 9 2448c2ecf20Sopenharmony_ci#define CIB_NMP_MASK 0x000001f0 2458c2ecf20Sopenharmony_ci#define CIB_NMP_SHIFT 4 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_ci/* EROM AddrDesc */ 2488c2ecf20Sopenharmony_ci#define AD_ADDR_MASK 0xfffff000 2498c2ecf20Sopenharmony_ci#define AD_SP_MASK 0x00000f00 2508c2ecf20Sopenharmony_ci#define AD_SP_SHIFT 8 2518c2ecf20Sopenharmony_ci#define AD_ST_MASK 0x000000c0 2528c2ecf20Sopenharmony_ci#define AD_ST_SHIFT 6 2538c2ecf20Sopenharmony_ci#define AD_ST_SLAVE 0x00000000 2548c2ecf20Sopenharmony_ci#define AD_ST_BRIDGE 0x00000040 2558c2ecf20Sopenharmony_ci#define AD_ST_SWRAP 0x00000080 2568c2ecf20Sopenharmony_ci#define AD_ST_MWRAP 0x000000c0 2578c2ecf20Sopenharmony_ci#define AD_SZ_MASK 0x00000030 2588c2ecf20Sopenharmony_ci#define AD_SZ_SHIFT 4 2598c2ecf20Sopenharmony_ci#define AD_SZ_4K 0x00000000 2608c2ecf20Sopenharmony_ci#define AD_SZ_8K 0x00000010 2618c2ecf20Sopenharmony_ci#define AD_SZ_16K 0x00000020 2628c2ecf20Sopenharmony_ci#define AD_SZ_SZD 0x00000030 2638c2ecf20Sopenharmony_ci#define AD_AG32 0x00000008 2648c2ecf20Sopenharmony_ci#define AD_ADDR_ALIGN 0x00000fff 2658c2ecf20Sopenharmony_ci#define AD_SZ_BASE 0x00001000 /* 4KB */ 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci/* EROM SizeDesc */ 2688c2ecf20Sopenharmony_ci#define SD_SZ_MASK 0xfffff000 2698c2ecf20Sopenharmony_ci#define SD_SG32 0x00000008 2708c2ecf20Sopenharmony_ci#define SD_SZ_ALIGN 0x00000fff 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci/* PCI config space bit 4 for 4306c0 slow clock source */ 2738c2ecf20Sopenharmony_ci#define PCI_CFG_GPIO_SCS 0x10 2748c2ecf20Sopenharmony_ci/* PCI config space GPIO 14 for Xtal power-up */ 2758c2ecf20Sopenharmony_ci#define PCI_CFG_GPIO_XTAL 0x40 2768c2ecf20Sopenharmony_ci/* PCI config space GPIO 15 for PLL power-down */ 2778c2ecf20Sopenharmony_ci#define PCI_CFG_GPIO_PLL 0x80 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci/* power control defines */ 2808c2ecf20Sopenharmony_ci#define PLL_DELAY 150 /* us pll on delay */ 2818c2ecf20Sopenharmony_ci#define FREF_DELAY 200 /* us fref change delay */ 2828c2ecf20Sopenharmony_ci#define XTAL_ON_DELAY 1000 /* us crystal power-on delay */ 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci/* resetctrl */ 2858c2ecf20Sopenharmony_ci#define AIRC_RESET 1 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci#define NOREV -1 /* Invalid rev */ 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_ci/* GPIO Based LED powersave defines */ 2908c2ecf20Sopenharmony_ci#define DEFAULT_GPIO_ONTIME 10 /* Default: 10% on */ 2918c2ecf20Sopenharmony_ci#define DEFAULT_GPIO_OFFTIME 90 /* Default: 10% on */ 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci/* When Srom support present, fields in sromcontrol */ 2948c2ecf20Sopenharmony_ci#define SRC_START 0x80000000 2958c2ecf20Sopenharmony_ci#define SRC_BUSY 0x80000000 2968c2ecf20Sopenharmony_ci#define SRC_OPCODE 0x60000000 2978c2ecf20Sopenharmony_ci#define SRC_OP_READ 0x00000000 2988c2ecf20Sopenharmony_ci#define SRC_OP_WRITE 0x20000000 2998c2ecf20Sopenharmony_ci#define SRC_OP_WRDIS 0x40000000 3008c2ecf20Sopenharmony_ci#define SRC_OP_WREN 0x60000000 3018c2ecf20Sopenharmony_ci#define SRC_OTPSEL 0x00000010 3028c2ecf20Sopenharmony_ci#define SRC_LOCK 0x00000008 3038c2ecf20Sopenharmony_ci#define SRC_SIZE_MASK 0x00000006 3048c2ecf20Sopenharmony_ci#define SRC_SIZE_1K 0x00000000 3058c2ecf20Sopenharmony_ci#define SRC_SIZE_4K 0x00000002 3068c2ecf20Sopenharmony_ci#define SRC_SIZE_16K 0x00000004 3078c2ecf20Sopenharmony_ci#define SRC_SIZE_SHIFT 1 3088c2ecf20Sopenharmony_ci#define SRC_PRESENT 0x00000001 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ci/* External PA enable mask */ 3118c2ecf20Sopenharmony_ci#define GPIO_CTRL_EPA_EN_MASK 0x40 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci#define DEFAULT_GPIOTIMERVAL \ 3148c2ecf20Sopenharmony_ci ((DEFAULT_GPIO_ONTIME << GPIO_ONTIME_SHIFT) | DEFAULT_GPIO_OFFTIME) 3158c2ecf20Sopenharmony_ci 3168c2ecf20Sopenharmony_ci#define BADIDX (SI_MAXCORES + 1) 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci#define IS_SIM(chippkg) \ 3198c2ecf20Sopenharmony_ci ((chippkg == HDLSIM_PKG_ID) || (chippkg == HWSIM_PKG_ID)) 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci#define GOODCOREADDR(x, b) \ 3228c2ecf20Sopenharmony_ci (((x) >= (b)) && ((x) < ((b) + SI_MAXCORES * SI_CORE_SIZE)) && \ 3238c2ecf20Sopenharmony_ci IS_ALIGNED((x), SI_CORE_SIZE)) 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_cistruct aidmp { 3268c2ecf20Sopenharmony_ci u32 oobselina30; /* 0x000 */ 3278c2ecf20Sopenharmony_ci u32 oobselina74; /* 0x004 */ 3288c2ecf20Sopenharmony_ci u32 PAD[6]; 3298c2ecf20Sopenharmony_ci u32 oobselinb30; /* 0x020 */ 3308c2ecf20Sopenharmony_ci u32 oobselinb74; /* 0x024 */ 3318c2ecf20Sopenharmony_ci u32 PAD[6]; 3328c2ecf20Sopenharmony_ci u32 oobselinc30; /* 0x040 */ 3338c2ecf20Sopenharmony_ci u32 oobselinc74; /* 0x044 */ 3348c2ecf20Sopenharmony_ci u32 PAD[6]; 3358c2ecf20Sopenharmony_ci u32 oobselind30; /* 0x060 */ 3368c2ecf20Sopenharmony_ci u32 oobselind74; /* 0x064 */ 3378c2ecf20Sopenharmony_ci u32 PAD[38]; 3388c2ecf20Sopenharmony_ci u32 oobselouta30; /* 0x100 */ 3398c2ecf20Sopenharmony_ci u32 oobselouta74; /* 0x104 */ 3408c2ecf20Sopenharmony_ci u32 PAD[6]; 3418c2ecf20Sopenharmony_ci u32 oobseloutb30; /* 0x120 */ 3428c2ecf20Sopenharmony_ci u32 oobseloutb74; /* 0x124 */ 3438c2ecf20Sopenharmony_ci u32 PAD[6]; 3448c2ecf20Sopenharmony_ci u32 oobseloutc30; /* 0x140 */ 3458c2ecf20Sopenharmony_ci u32 oobseloutc74; /* 0x144 */ 3468c2ecf20Sopenharmony_ci u32 PAD[6]; 3478c2ecf20Sopenharmony_ci u32 oobseloutd30; /* 0x160 */ 3488c2ecf20Sopenharmony_ci u32 oobseloutd74; /* 0x164 */ 3498c2ecf20Sopenharmony_ci u32 PAD[38]; 3508c2ecf20Sopenharmony_ci u32 oobsynca; /* 0x200 */ 3518c2ecf20Sopenharmony_ci u32 oobseloutaen; /* 0x204 */ 3528c2ecf20Sopenharmony_ci u32 PAD[6]; 3538c2ecf20Sopenharmony_ci u32 oobsyncb; /* 0x220 */ 3548c2ecf20Sopenharmony_ci u32 oobseloutben; /* 0x224 */ 3558c2ecf20Sopenharmony_ci u32 PAD[6]; 3568c2ecf20Sopenharmony_ci u32 oobsyncc; /* 0x240 */ 3578c2ecf20Sopenharmony_ci u32 oobseloutcen; /* 0x244 */ 3588c2ecf20Sopenharmony_ci u32 PAD[6]; 3598c2ecf20Sopenharmony_ci u32 oobsyncd; /* 0x260 */ 3608c2ecf20Sopenharmony_ci u32 oobseloutden; /* 0x264 */ 3618c2ecf20Sopenharmony_ci u32 PAD[38]; 3628c2ecf20Sopenharmony_ci u32 oobaextwidth; /* 0x300 */ 3638c2ecf20Sopenharmony_ci u32 oobainwidth; /* 0x304 */ 3648c2ecf20Sopenharmony_ci u32 oobaoutwidth; /* 0x308 */ 3658c2ecf20Sopenharmony_ci u32 PAD[5]; 3668c2ecf20Sopenharmony_ci u32 oobbextwidth; /* 0x320 */ 3678c2ecf20Sopenharmony_ci u32 oobbinwidth; /* 0x324 */ 3688c2ecf20Sopenharmony_ci u32 oobboutwidth; /* 0x328 */ 3698c2ecf20Sopenharmony_ci u32 PAD[5]; 3708c2ecf20Sopenharmony_ci u32 oobcextwidth; /* 0x340 */ 3718c2ecf20Sopenharmony_ci u32 oobcinwidth; /* 0x344 */ 3728c2ecf20Sopenharmony_ci u32 oobcoutwidth; /* 0x348 */ 3738c2ecf20Sopenharmony_ci u32 PAD[5]; 3748c2ecf20Sopenharmony_ci u32 oobdextwidth; /* 0x360 */ 3758c2ecf20Sopenharmony_ci u32 oobdinwidth; /* 0x364 */ 3768c2ecf20Sopenharmony_ci u32 oobdoutwidth; /* 0x368 */ 3778c2ecf20Sopenharmony_ci u32 PAD[37]; 3788c2ecf20Sopenharmony_ci u32 ioctrlset; /* 0x400 */ 3798c2ecf20Sopenharmony_ci u32 ioctrlclear; /* 0x404 */ 3808c2ecf20Sopenharmony_ci u32 ioctrl; /* 0x408 */ 3818c2ecf20Sopenharmony_ci u32 PAD[61]; 3828c2ecf20Sopenharmony_ci u32 iostatus; /* 0x500 */ 3838c2ecf20Sopenharmony_ci u32 PAD[127]; 3848c2ecf20Sopenharmony_ci u32 ioctrlwidth; /* 0x700 */ 3858c2ecf20Sopenharmony_ci u32 iostatuswidth; /* 0x704 */ 3868c2ecf20Sopenharmony_ci u32 PAD[62]; 3878c2ecf20Sopenharmony_ci u32 resetctrl; /* 0x800 */ 3888c2ecf20Sopenharmony_ci u32 resetstatus; /* 0x804 */ 3898c2ecf20Sopenharmony_ci u32 resetreadid; /* 0x808 */ 3908c2ecf20Sopenharmony_ci u32 resetwriteid; /* 0x80c */ 3918c2ecf20Sopenharmony_ci u32 PAD[60]; 3928c2ecf20Sopenharmony_ci u32 errlogctrl; /* 0x900 */ 3938c2ecf20Sopenharmony_ci u32 errlogdone; /* 0x904 */ 3948c2ecf20Sopenharmony_ci u32 errlogstatus; /* 0x908 */ 3958c2ecf20Sopenharmony_ci u32 errlogaddrlo; /* 0x90c */ 3968c2ecf20Sopenharmony_ci u32 errlogaddrhi; /* 0x910 */ 3978c2ecf20Sopenharmony_ci u32 errlogid; /* 0x914 */ 3988c2ecf20Sopenharmony_ci u32 errloguser; /* 0x918 */ 3998c2ecf20Sopenharmony_ci u32 errlogflags; /* 0x91c */ 4008c2ecf20Sopenharmony_ci u32 PAD[56]; 4018c2ecf20Sopenharmony_ci u32 intstatus; /* 0xa00 */ 4028c2ecf20Sopenharmony_ci u32 PAD[127]; 4038c2ecf20Sopenharmony_ci u32 config; /* 0xe00 */ 4048c2ecf20Sopenharmony_ci u32 PAD[63]; 4058c2ecf20Sopenharmony_ci u32 itcr; /* 0xf00 */ 4068c2ecf20Sopenharmony_ci u32 PAD[3]; 4078c2ecf20Sopenharmony_ci u32 itipooba; /* 0xf10 */ 4088c2ecf20Sopenharmony_ci u32 itipoobb; /* 0xf14 */ 4098c2ecf20Sopenharmony_ci u32 itipoobc; /* 0xf18 */ 4108c2ecf20Sopenharmony_ci u32 itipoobd; /* 0xf1c */ 4118c2ecf20Sopenharmony_ci u32 PAD[4]; 4128c2ecf20Sopenharmony_ci u32 itipoobaout; /* 0xf30 */ 4138c2ecf20Sopenharmony_ci u32 itipoobbout; /* 0xf34 */ 4148c2ecf20Sopenharmony_ci u32 itipoobcout; /* 0xf38 */ 4158c2ecf20Sopenharmony_ci u32 itipoobdout; /* 0xf3c */ 4168c2ecf20Sopenharmony_ci u32 PAD[4]; 4178c2ecf20Sopenharmony_ci u32 itopooba; /* 0xf50 */ 4188c2ecf20Sopenharmony_ci u32 itopoobb; /* 0xf54 */ 4198c2ecf20Sopenharmony_ci u32 itopoobc; /* 0xf58 */ 4208c2ecf20Sopenharmony_ci u32 itopoobd; /* 0xf5c */ 4218c2ecf20Sopenharmony_ci u32 PAD[4]; 4228c2ecf20Sopenharmony_ci u32 itopoobain; /* 0xf70 */ 4238c2ecf20Sopenharmony_ci u32 itopoobbin; /* 0xf74 */ 4248c2ecf20Sopenharmony_ci u32 itopoobcin; /* 0xf78 */ 4258c2ecf20Sopenharmony_ci u32 itopoobdin; /* 0xf7c */ 4268c2ecf20Sopenharmony_ci u32 PAD[4]; 4278c2ecf20Sopenharmony_ci u32 itopreset; /* 0xf90 */ 4288c2ecf20Sopenharmony_ci u32 PAD[15]; 4298c2ecf20Sopenharmony_ci u32 peripherialid4; /* 0xfd0 */ 4308c2ecf20Sopenharmony_ci u32 peripherialid5; /* 0xfd4 */ 4318c2ecf20Sopenharmony_ci u32 peripherialid6; /* 0xfd8 */ 4328c2ecf20Sopenharmony_ci u32 peripherialid7; /* 0xfdc */ 4338c2ecf20Sopenharmony_ci u32 peripherialid0; /* 0xfe0 */ 4348c2ecf20Sopenharmony_ci u32 peripherialid1; /* 0xfe4 */ 4358c2ecf20Sopenharmony_ci u32 peripherialid2; /* 0xfe8 */ 4368c2ecf20Sopenharmony_ci u32 peripherialid3; /* 0xfec */ 4378c2ecf20Sopenharmony_ci u32 componentid0; /* 0xff0 */ 4388c2ecf20Sopenharmony_ci u32 componentid1; /* 0xff4 */ 4398c2ecf20Sopenharmony_ci u32 componentid2; /* 0xff8 */ 4408c2ecf20Sopenharmony_ci u32 componentid3; /* 0xffc */ 4418c2ecf20Sopenharmony_ci}; 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_cistatic bool 4448c2ecf20Sopenharmony_ciai_buscore_setup(struct si_info *sii, struct bcma_device *cc) 4458c2ecf20Sopenharmony_ci{ 4468c2ecf20Sopenharmony_ci /* no cores found, bail out */ 4478c2ecf20Sopenharmony_ci if (cc->bus->nr_cores == 0) 4488c2ecf20Sopenharmony_ci return false; 4498c2ecf20Sopenharmony_ci 4508c2ecf20Sopenharmony_ci /* get chipcommon rev */ 4518c2ecf20Sopenharmony_ci sii->pub.ccrev = cc->id.rev; 4528c2ecf20Sopenharmony_ci 4538c2ecf20Sopenharmony_ci /* get chipcommon chipstatus */ 4548c2ecf20Sopenharmony_ci sii->chipst = bcma_read32(cc, CHIPCREGOFFS(chipstatus)); 4558c2ecf20Sopenharmony_ci 4568c2ecf20Sopenharmony_ci /* get chipcommon capabilites */ 4578c2ecf20Sopenharmony_ci sii->pub.cccaps = bcma_read32(cc, CHIPCREGOFFS(capabilities)); 4588c2ecf20Sopenharmony_ci 4598c2ecf20Sopenharmony_ci /* get pmu rev and caps */ 4608c2ecf20Sopenharmony_ci if (ai_get_cccaps(&sii->pub) & CC_CAP_PMU) { 4618c2ecf20Sopenharmony_ci sii->pub.pmucaps = bcma_read32(cc, 4628c2ecf20Sopenharmony_ci CHIPCREGOFFS(pmucapabilities)); 4638c2ecf20Sopenharmony_ci sii->pub.pmurev = sii->pub.pmucaps & PCAP_REV_MASK; 4648c2ecf20Sopenharmony_ci } 4658c2ecf20Sopenharmony_ci 4668c2ecf20Sopenharmony_ci return true; 4678c2ecf20Sopenharmony_ci} 4688c2ecf20Sopenharmony_ci 4698c2ecf20Sopenharmony_cistatic struct si_info *ai_doattach(struct si_info *sii, 4708c2ecf20Sopenharmony_ci struct bcma_bus *pbus) 4718c2ecf20Sopenharmony_ci{ 4728c2ecf20Sopenharmony_ci struct si_pub *sih = &sii->pub; 4738c2ecf20Sopenharmony_ci struct bcma_device *cc; 4748c2ecf20Sopenharmony_ci 4758c2ecf20Sopenharmony_ci sii->icbus = pbus; 4768c2ecf20Sopenharmony_ci sii->pcibus = pbus->host_pci; 4778c2ecf20Sopenharmony_ci 4788c2ecf20Sopenharmony_ci /* switch to Chipcommon core */ 4798c2ecf20Sopenharmony_ci cc = pbus->drv_cc.core; 4808c2ecf20Sopenharmony_ci 4818c2ecf20Sopenharmony_ci sih->chip = pbus->chipinfo.id; 4828c2ecf20Sopenharmony_ci sih->chiprev = pbus->chipinfo.rev; 4838c2ecf20Sopenharmony_ci sih->chippkg = pbus->chipinfo.pkg; 4848c2ecf20Sopenharmony_ci sih->boardvendor = pbus->boardinfo.vendor; 4858c2ecf20Sopenharmony_ci sih->boardtype = pbus->boardinfo.type; 4868c2ecf20Sopenharmony_ci 4878c2ecf20Sopenharmony_ci if (!ai_buscore_setup(sii, cc)) 4888c2ecf20Sopenharmony_ci goto exit; 4898c2ecf20Sopenharmony_ci 4908c2ecf20Sopenharmony_ci /* === NVRAM, clock is ready === */ 4918c2ecf20Sopenharmony_ci bcma_write32(cc, CHIPCREGOFFS(gpiopullup), 0); 4928c2ecf20Sopenharmony_ci bcma_write32(cc, CHIPCREGOFFS(gpiopulldown), 0); 4938c2ecf20Sopenharmony_ci 4948c2ecf20Sopenharmony_ci /* PMU specific initializations */ 4958c2ecf20Sopenharmony_ci if (ai_get_cccaps(sih) & CC_CAP_PMU) { 4968c2ecf20Sopenharmony_ci (void)si_pmu_measure_alpclk(sih); 4978c2ecf20Sopenharmony_ci } 4988c2ecf20Sopenharmony_ci 4998c2ecf20Sopenharmony_ci return sii; 5008c2ecf20Sopenharmony_ci 5018c2ecf20Sopenharmony_ci exit: 5028c2ecf20Sopenharmony_ci 5038c2ecf20Sopenharmony_ci return NULL; 5048c2ecf20Sopenharmony_ci} 5058c2ecf20Sopenharmony_ci 5068c2ecf20Sopenharmony_ci/* 5078c2ecf20Sopenharmony_ci * Allocate a si handle and do the attach. 5088c2ecf20Sopenharmony_ci */ 5098c2ecf20Sopenharmony_cistruct si_pub * 5108c2ecf20Sopenharmony_ciai_attach(struct bcma_bus *pbus) 5118c2ecf20Sopenharmony_ci{ 5128c2ecf20Sopenharmony_ci struct si_info *sii; 5138c2ecf20Sopenharmony_ci 5148c2ecf20Sopenharmony_ci /* alloc struct si_info */ 5158c2ecf20Sopenharmony_ci sii = kzalloc(sizeof(struct si_info), GFP_ATOMIC); 5168c2ecf20Sopenharmony_ci if (sii == NULL) 5178c2ecf20Sopenharmony_ci return NULL; 5188c2ecf20Sopenharmony_ci 5198c2ecf20Sopenharmony_ci if (ai_doattach(sii, pbus) == NULL) { 5208c2ecf20Sopenharmony_ci kfree(sii); 5218c2ecf20Sopenharmony_ci return NULL; 5228c2ecf20Sopenharmony_ci } 5238c2ecf20Sopenharmony_ci 5248c2ecf20Sopenharmony_ci return (struct si_pub *) sii; 5258c2ecf20Sopenharmony_ci} 5268c2ecf20Sopenharmony_ci 5278c2ecf20Sopenharmony_ci/* may be called with core in reset */ 5288c2ecf20Sopenharmony_civoid ai_detach(struct si_pub *sih) 5298c2ecf20Sopenharmony_ci{ 5308c2ecf20Sopenharmony_ci struct si_info *sii; 5318c2ecf20Sopenharmony_ci 5328c2ecf20Sopenharmony_ci sii = container_of(sih, struct si_info, pub); 5338c2ecf20Sopenharmony_ci 5348c2ecf20Sopenharmony_ci if (sii == NULL) 5358c2ecf20Sopenharmony_ci return; 5368c2ecf20Sopenharmony_ci 5378c2ecf20Sopenharmony_ci kfree(sii); 5388c2ecf20Sopenharmony_ci} 5398c2ecf20Sopenharmony_ci 5408c2ecf20Sopenharmony_ci/* 5418c2ecf20Sopenharmony_ci * read/modify chipcommon core register. 5428c2ecf20Sopenharmony_ci */ 5438c2ecf20Sopenharmony_ciuint ai_cc_reg(struct si_pub *sih, uint regoff, u32 mask, u32 val) 5448c2ecf20Sopenharmony_ci{ 5458c2ecf20Sopenharmony_ci struct bcma_device *cc; 5468c2ecf20Sopenharmony_ci u32 w; 5478c2ecf20Sopenharmony_ci struct si_info *sii; 5488c2ecf20Sopenharmony_ci 5498c2ecf20Sopenharmony_ci sii = container_of(sih, struct si_info, pub); 5508c2ecf20Sopenharmony_ci cc = sii->icbus->drv_cc.core; 5518c2ecf20Sopenharmony_ci 5528c2ecf20Sopenharmony_ci /* mask and set */ 5538c2ecf20Sopenharmony_ci if (mask || val) 5548c2ecf20Sopenharmony_ci bcma_maskset32(cc, regoff, ~mask, val); 5558c2ecf20Sopenharmony_ci 5568c2ecf20Sopenharmony_ci /* readback */ 5578c2ecf20Sopenharmony_ci w = bcma_read32(cc, regoff); 5588c2ecf20Sopenharmony_ci 5598c2ecf20Sopenharmony_ci return w; 5608c2ecf20Sopenharmony_ci} 5618c2ecf20Sopenharmony_ci 5628c2ecf20Sopenharmony_ci/* return the slow clock source - LPO, XTAL, or PCI */ 5638c2ecf20Sopenharmony_cistatic uint ai_slowclk_src(struct si_pub *sih, struct bcma_device *cc) 5648c2ecf20Sopenharmony_ci{ 5658c2ecf20Sopenharmony_ci return SCC_SS_XTAL; 5668c2ecf20Sopenharmony_ci} 5678c2ecf20Sopenharmony_ci 5688c2ecf20Sopenharmony_ci/* 5698c2ecf20Sopenharmony_ci* return the ILP (slowclock) min or max frequency 5708c2ecf20Sopenharmony_ci* precondition: we've established the chip has dynamic clk control 5718c2ecf20Sopenharmony_ci*/ 5728c2ecf20Sopenharmony_cistatic uint ai_slowclk_freq(struct si_pub *sih, bool max_freq, 5738c2ecf20Sopenharmony_ci struct bcma_device *cc) 5748c2ecf20Sopenharmony_ci{ 5758c2ecf20Sopenharmony_ci uint div; 5768c2ecf20Sopenharmony_ci 5778c2ecf20Sopenharmony_ci /* Chipc rev 10 is InstaClock */ 5788c2ecf20Sopenharmony_ci div = bcma_read32(cc, CHIPCREGOFFS(system_clk_ctl)); 5798c2ecf20Sopenharmony_ci div = 4 * ((div >> SYCC_CD_SHIFT) + 1); 5808c2ecf20Sopenharmony_ci return max_freq ? XTALMAXFREQ : (XTALMINFREQ / div); 5818c2ecf20Sopenharmony_ci} 5828c2ecf20Sopenharmony_ci 5838c2ecf20Sopenharmony_cistatic void 5848c2ecf20Sopenharmony_ciai_clkctl_setdelay(struct si_pub *sih, struct bcma_device *cc) 5858c2ecf20Sopenharmony_ci{ 5868c2ecf20Sopenharmony_ci uint slowmaxfreq, pll_delay, slowclk; 5878c2ecf20Sopenharmony_ci uint pll_on_delay, fref_sel_delay; 5888c2ecf20Sopenharmony_ci 5898c2ecf20Sopenharmony_ci pll_delay = PLL_DELAY; 5908c2ecf20Sopenharmony_ci 5918c2ecf20Sopenharmony_ci /* 5928c2ecf20Sopenharmony_ci * If the slow clock is not sourced by the xtal then 5938c2ecf20Sopenharmony_ci * add the xtal_on_delay since the xtal will also be 5948c2ecf20Sopenharmony_ci * powered down by dynamic clk control logic. 5958c2ecf20Sopenharmony_ci */ 5968c2ecf20Sopenharmony_ci 5978c2ecf20Sopenharmony_ci slowclk = ai_slowclk_src(sih, cc); 5988c2ecf20Sopenharmony_ci if (slowclk != SCC_SS_XTAL) 5998c2ecf20Sopenharmony_ci pll_delay += XTAL_ON_DELAY; 6008c2ecf20Sopenharmony_ci 6018c2ecf20Sopenharmony_ci /* Starting with 4318 it is ILP that is used for the delays */ 6028c2ecf20Sopenharmony_ci slowmaxfreq = 6038c2ecf20Sopenharmony_ci ai_slowclk_freq(sih, false, cc); 6048c2ecf20Sopenharmony_ci 6058c2ecf20Sopenharmony_ci pll_on_delay = ((slowmaxfreq * pll_delay) + 999999) / 1000000; 6068c2ecf20Sopenharmony_ci fref_sel_delay = ((slowmaxfreq * FREF_DELAY) + 999999) / 1000000; 6078c2ecf20Sopenharmony_ci 6088c2ecf20Sopenharmony_ci bcma_write32(cc, CHIPCREGOFFS(pll_on_delay), pll_on_delay); 6098c2ecf20Sopenharmony_ci bcma_write32(cc, CHIPCREGOFFS(fref_sel_delay), fref_sel_delay); 6108c2ecf20Sopenharmony_ci} 6118c2ecf20Sopenharmony_ci 6128c2ecf20Sopenharmony_ci/* initialize power control delay registers */ 6138c2ecf20Sopenharmony_civoid ai_clkctl_init(struct si_pub *sih) 6148c2ecf20Sopenharmony_ci{ 6158c2ecf20Sopenharmony_ci struct si_info *sii = container_of(sih, struct si_info, pub); 6168c2ecf20Sopenharmony_ci struct bcma_device *cc; 6178c2ecf20Sopenharmony_ci 6188c2ecf20Sopenharmony_ci if (!(ai_get_cccaps(sih) & CC_CAP_PWR_CTL)) 6198c2ecf20Sopenharmony_ci return; 6208c2ecf20Sopenharmony_ci 6218c2ecf20Sopenharmony_ci cc = sii->icbus->drv_cc.core; 6228c2ecf20Sopenharmony_ci if (cc == NULL) 6238c2ecf20Sopenharmony_ci return; 6248c2ecf20Sopenharmony_ci 6258c2ecf20Sopenharmony_ci /* set all Instaclk chip ILP to 1 MHz */ 6268c2ecf20Sopenharmony_ci bcma_maskset32(cc, CHIPCREGOFFS(system_clk_ctl), SYCC_CD_MASK, 6278c2ecf20Sopenharmony_ci (ILP_DIV_1MHZ << SYCC_CD_SHIFT)); 6288c2ecf20Sopenharmony_ci 6298c2ecf20Sopenharmony_ci ai_clkctl_setdelay(sih, cc); 6308c2ecf20Sopenharmony_ci} 6318c2ecf20Sopenharmony_ci 6328c2ecf20Sopenharmony_ci/* 6338c2ecf20Sopenharmony_ci * return the value suitable for writing to the 6348c2ecf20Sopenharmony_ci * dot11 core FAST_PWRUP_DELAY register 6358c2ecf20Sopenharmony_ci */ 6368c2ecf20Sopenharmony_ciu16 ai_clkctl_fast_pwrup_delay(struct si_pub *sih) 6378c2ecf20Sopenharmony_ci{ 6388c2ecf20Sopenharmony_ci struct si_info *sii; 6398c2ecf20Sopenharmony_ci struct bcma_device *cc; 6408c2ecf20Sopenharmony_ci uint slowminfreq; 6418c2ecf20Sopenharmony_ci u16 fpdelay; 6428c2ecf20Sopenharmony_ci 6438c2ecf20Sopenharmony_ci sii = container_of(sih, struct si_info, pub); 6448c2ecf20Sopenharmony_ci if (ai_get_cccaps(sih) & CC_CAP_PMU) { 6458c2ecf20Sopenharmony_ci fpdelay = si_pmu_fast_pwrup_delay(sih); 6468c2ecf20Sopenharmony_ci return fpdelay; 6478c2ecf20Sopenharmony_ci } 6488c2ecf20Sopenharmony_ci 6498c2ecf20Sopenharmony_ci if (!(ai_get_cccaps(sih) & CC_CAP_PWR_CTL)) 6508c2ecf20Sopenharmony_ci return 0; 6518c2ecf20Sopenharmony_ci 6528c2ecf20Sopenharmony_ci fpdelay = 0; 6538c2ecf20Sopenharmony_ci cc = sii->icbus->drv_cc.core; 6548c2ecf20Sopenharmony_ci if (cc) { 6558c2ecf20Sopenharmony_ci slowminfreq = ai_slowclk_freq(sih, false, cc); 6568c2ecf20Sopenharmony_ci fpdelay = (((bcma_read32(cc, CHIPCREGOFFS(pll_on_delay)) + 2) 6578c2ecf20Sopenharmony_ci * 1000000) + (slowminfreq - 1)) / slowminfreq; 6588c2ecf20Sopenharmony_ci } 6598c2ecf20Sopenharmony_ci return fpdelay; 6608c2ecf20Sopenharmony_ci} 6618c2ecf20Sopenharmony_ci 6628c2ecf20Sopenharmony_ci/* 6638c2ecf20Sopenharmony_ci * clock control policy function throught chipcommon 6648c2ecf20Sopenharmony_ci * 6658c2ecf20Sopenharmony_ci * set dynamic clk control mode (forceslow, forcefast, dynamic) 6668c2ecf20Sopenharmony_ci * returns true if we are forcing fast clock 6678c2ecf20Sopenharmony_ci * this is a wrapper over the next internal function 6688c2ecf20Sopenharmony_ci * to allow flexible policy settings for outside caller 6698c2ecf20Sopenharmony_ci */ 6708c2ecf20Sopenharmony_cibool ai_clkctl_cc(struct si_pub *sih, enum bcma_clkmode mode) 6718c2ecf20Sopenharmony_ci{ 6728c2ecf20Sopenharmony_ci struct si_info *sii; 6738c2ecf20Sopenharmony_ci struct bcma_device *cc; 6748c2ecf20Sopenharmony_ci 6758c2ecf20Sopenharmony_ci sii = container_of(sih, struct si_info, pub); 6768c2ecf20Sopenharmony_ci 6778c2ecf20Sopenharmony_ci cc = sii->icbus->drv_cc.core; 6788c2ecf20Sopenharmony_ci bcma_core_set_clockmode(cc, mode); 6798c2ecf20Sopenharmony_ci return mode == BCMA_CLKMODE_FAST; 6808c2ecf20Sopenharmony_ci} 6818c2ecf20Sopenharmony_ci 6828c2ecf20Sopenharmony_ci/* Enable BT-COEX & Ex-PA for 4313 */ 6838c2ecf20Sopenharmony_civoid ai_epa_4313war(struct si_pub *sih) 6848c2ecf20Sopenharmony_ci{ 6858c2ecf20Sopenharmony_ci struct si_info *sii = container_of(sih, struct si_info, pub); 6868c2ecf20Sopenharmony_ci struct bcma_device *cc; 6878c2ecf20Sopenharmony_ci 6888c2ecf20Sopenharmony_ci cc = sii->icbus->drv_cc.core; 6898c2ecf20Sopenharmony_ci 6908c2ecf20Sopenharmony_ci /* EPA Fix */ 6918c2ecf20Sopenharmony_ci bcma_set32(cc, CHIPCREGOFFS(gpiocontrol), GPIO_CTRL_EPA_EN_MASK); 6928c2ecf20Sopenharmony_ci} 6938c2ecf20Sopenharmony_ci 6948c2ecf20Sopenharmony_ci/* check if the device is removed */ 6958c2ecf20Sopenharmony_cibool ai_deviceremoved(struct si_pub *sih) 6968c2ecf20Sopenharmony_ci{ 6978c2ecf20Sopenharmony_ci u32 w = 0; 6988c2ecf20Sopenharmony_ci struct si_info *sii; 6998c2ecf20Sopenharmony_ci 7008c2ecf20Sopenharmony_ci sii = container_of(sih, struct si_info, pub); 7018c2ecf20Sopenharmony_ci 7028c2ecf20Sopenharmony_ci if (sii->icbus->hosttype != BCMA_HOSTTYPE_PCI) 7038c2ecf20Sopenharmony_ci return false; 7048c2ecf20Sopenharmony_ci 7058c2ecf20Sopenharmony_ci pci_read_config_dword(sii->pcibus, PCI_VENDOR_ID, &w); 7068c2ecf20Sopenharmony_ci if ((w & 0xFFFF) != PCI_VENDOR_ID_BROADCOM) 7078c2ecf20Sopenharmony_ci return true; 7088c2ecf20Sopenharmony_ci 7098c2ecf20Sopenharmony_ci return false; 7108c2ecf20Sopenharmony_ci} 711