1203319Sweongyo/*- 2203319Sweongyo * Copyright (c) 2009-2010 Weongyo Jeong <weongyo@freebsd.org> 3203319Sweongyo * All rights reserved. 4203319Sweongyo * 5203319Sweongyo * Redistribution and use in source and binary forms, with or without 6203319Sweongyo * modification, are permitted provided that the following conditions 7203319Sweongyo * are met: 8203319Sweongyo * 1. Redistributions of source code must retain the above copyright 9203319Sweongyo * notice, this list of conditions and the following disclaimer, 10203319Sweongyo * without modification. 11203319Sweongyo * 2. Redistributions in binary form must reproduce at minimum a disclaimer 12203319Sweongyo * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any 13203319Sweongyo * redistribution must be conditioned upon including a substantially 14203319Sweongyo * similar Disclaimer requirement for further binary redistribution. 15203319Sweongyo * 16203319Sweongyo * NO WARRANTY 17203319Sweongyo * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18203319Sweongyo * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19203319Sweongyo * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY 20203319Sweongyo * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 21203319Sweongyo * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, 22203319Sweongyo * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23203319Sweongyo * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24203319Sweongyo * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25203319Sweongyo * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26203319Sweongyo * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 27203319Sweongyo * THE POSSIBILITY OF SUCH DAMAGES. 28203319Sweongyo */ 29203319Sweongyo 30203319Sweongyo#include <sys/cdefs.h> 31203319Sweongyo__FBSDID("$FreeBSD$"); 32203319Sweongyo 33203319Sweongyo/* 34203319Sweongyo * the Sonics Silicon Backplane driver. 35203319Sweongyo */ 36203319Sweongyo 37203319Sweongyo#include <sys/param.h> 38203319Sweongyo#include <sys/systm.h> 39203319Sweongyo#include <sys/module.h> 40203319Sweongyo#include <sys/kernel.h> 41203319Sweongyo#include <sys/endian.h> 42203319Sweongyo#include <sys/errno.h> 43203319Sweongyo#include <sys/lock.h> 44203319Sweongyo#include <sys/mutex.h> 45203319Sweongyo#include <machine/bus.h> 46203319Sweongyo#include <machine/resource.h> 47203319Sweongyo#include <sys/bus.h> 48203319Sweongyo#include <sys/rman.h> 49203319Sweongyo#include <sys/socket.h> 50203319Sweongyo 51203319Sweongyo#include <net/if.h> 52203319Sweongyo#include <net/if_media.h> 53203319Sweongyo#include <net/if_arp.h> 54203319Sweongyo 55203319Sweongyo#include <dev/pci/pcivar.h> 56203319Sweongyo#include <dev/pci/pcireg.h> 57203319Sweongyo 58203319Sweongyo#include <dev/siba/siba_ids.h> 59203319Sweongyo#include <dev/siba/sibareg.h> 60203319Sweongyo#include <dev/siba/sibavar.h> 61203319Sweongyo 62203319Sweongyo#ifdef SIBA_DEBUG 63203319Sweongyoenum { 64203319Sweongyo SIBA_DEBUG_SCAN = 0x00000001, /* scan */ 65203319Sweongyo SIBA_DEBUG_PMU = 0x00000002, /* PMU */ 66203319Sweongyo SIBA_DEBUG_PLL = 0x00000004, /* PLL */ 67203319Sweongyo SIBA_DEBUG_SWITCHCORE = 0x00000008, /* switching core */ 68203319Sweongyo SIBA_DEBUG_SPROM = 0x00000010, /* SPROM */ 69203319Sweongyo SIBA_DEBUG_CORE = 0x00000020, /* handling cores */ 70203319Sweongyo SIBA_DEBUG_ANY = 0xffffffff 71203319Sweongyo}; 72203319Sweongyo#define DPRINTF(siba, m, fmt, ...) do { \ 73203319Sweongyo if (siba->siba_debug & (m)) \ 74203319Sweongyo printf(fmt, __VA_ARGS__); \ 75203319Sweongyo} while (0) 76203319Sweongyo#else 77203319Sweongyo#define DPRINTF(siba, m, fmt, ...) do { (void) siba; } while (0) 78203319Sweongyo#endif 79203319Sweongyo#define N(a) (sizeof(a) / sizeof(a[0])) 80203319Sweongyo 81203319Sweongyostatic void siba_pci_gpio(struct siba_softc *, uint32_t, int); 82203319Sweongyostatic void siba_scan(struct siba_softc *); 83203319Sweongyostatic int siba_switchcore(struct siba_softc *, uint8_t); 84203319Sweongyostatic int siba_pci_switchcore_sub(struct siba_softc *, uint8_t); 85203319Sweongyostatic uint32_t siba_scan_read_4(struct siba_softc *, uint8_t, uint16_t); 86203319Sweongyostatic uint16_t siba_dev2chipid(struct siba_softc *); 87203319Sweongyostatic uint16_t siba_pci_read_2(struct siba_dev_softc *, uint16_t); 88203319Sweongyostatic uint32_t siba_pci_read_4(struct siba_dev_softc *, uint16_t); 89203319Sweongyostatic void siba_pci_write_2(struct siba_dev_softc *, uint16_t, uint16_t); 90203319Sweongyostatic void siba_pci_write_4(struct siba_dev_softc *, uint16_t, uint32_t); 91203319Sweongyostatic void siba_cc_clock(struct siba_cc *, 92203319Sweongyo enum siba_clock); 93203319Sweongyostatic void siba_cc_pmu_init(struct siba_cc *); 94203319Sweongyostatic void siba_cc_power_init(struct siba_cc *); 95203319Sweongyostatic void siba_cc_powerup_delay(struct siba_cc *); 96203319Sweongyostatic int siba_cc_clockfreq(struct siba_cc *, int); 97203319Sweongyostatic void siba_cc_pmu1_pll0_init(struct siba_cc *, uint32_t); 98203319Sweongyostatic void siba_cc_pmu0_pll0_init(struct siba_cc *, uint32_t); 99203319Sweongyostatic enum siba_clksrc siba_cc_clksrc(struct siba_cc *); 100203319Sweongyostatic const struct siba_cc_pmu1_plltab *siba_cc_pmu1_plltab_find(uint32_t); 101203319Sweongyostatic uint32_t siba_cc_pll_read(struct siba_cc *, uint32_t); 102203319Sweongyostatic void siba_cc_pll_write(struct siba_cc *, uint32_t, 103203319Sweongyo uint32_t); 104203319Sweongyostatic const struct siba_cc_pmu0_plltab * 105203319Sweongyo siba_cc_pmu0_plltab_findentry(uint32_t); 106203319Sweongyostatic int siba_pci_sprom(struct siba_softc *, struct siba_sprom *); 107203319Sweongyostatic int siba_sprom_read(struct siba_softc *, uint16_t *, uint16_t); 108203319Sweongyostatic int sprom_check_crc(const uint16_t *, size_t); 109203319Sweongyostatic uint8_t siba_crc8(uint8_t, uint8_t); 110203319Sweongyostatic void siba_sprom_r123(struct siba_sprom *, const uint16_t *); 111203319Sweongyostatic void siba_sprom_r45(struct siba_sprom *, const uint16_t *); 112203319Sweongyostatic void siba_sprom_r8(struct siba_sprom *, const uint16_t *); 113203319Sweongyostatic int8_t siba_sprom_r123_antgain(uint8_t, const uint16_t *, uint16_t, 114203319Sweongyo uint16_t); 115203319Sweongyostatic uint32_t siba_tmslow_reject_bitmask(struct siba_dev_softc *); 116203319Sweongyostatic uint32_t siba_pcicore_read_4(struct siba_pci *, uint16_t); 117203319Sweongyostatic void siba_pcicore_write_4(struct siba_pci *, uint16_t, uint32_t); 118203319Sweongyostatic uint32_t siba_pcie_read(struct siba_pci *, uint32_t); 119203319Sweongyostatic void siba_pcie_write(struct siba_pci *, uint32_t, uint32_t); 120203319Sweongyostatic void siba_pcie_mdio_write(struct siba_pci *, uint8_t, uint8_t, 121203319Sweongyo uint16_t); 122203319Sweongyostatic void siba_pci_read_multi_1(struct siba_dev_softc *, void *, size_t, 123203319Sweongyo uint16_t); 124203319Sweongyostatic void siba_pci_read_multi_2(struct siba_dev_softc *, void *, size_t, 125203319Sweongyo uint16_t); 126203319Sweongyostatic void siba_pci_read_multi_4(struct siba_dev_softc *, void *, size_t, 127203319Sweongyo uint16_t); 128203319Sweongyostatic void siba_pci_write_multi_1(struct siba_dev_softc *, const void *, 129203319Sweongyo size_t, uint16_t); 130203319Sweongyostatic void siba_pci_write_multi_2(struct siba_dev_softc *, const void *, 131203319Sweongyo size_t, uint16_t); 132203319Sweongyostatic void siba_pci_write_multi_4(struct siba_dev_softc *, const void *, 133203319Sweongyo size_t, uint16_t); 134203319Sweongyostatic const char *siba_core_name(uint16_t); 135203319Sweongyostatic void siba_pcicore_init(struct siba_pci *); 136204922Sweongyostatic uint32_t siba_read_4_sub(struct siba_dev_softc *, uint16_t); 137204922Sweongyostatic void siba_write_4_sub(struct siba_dev_softc *, uint16_t, uint32_t); 138204922Sweongyostatic void siba_powerup_sub(struct siba_softc *, int); 139204922Sweongyostatic int siba_powerdown_sub(struct siba_softc *); 140204922Sweongyostatic int siba_dev_isup_sub(struct siba_dev_softc *); 141204922Sweongyostatic void siba_dev_up_sub(struct siba_dev_softc *, uint32_t); 142204922Sweongyostatic void siba_dev_down_sub(struct siba_dev_softc *, uint32_t); 143203319Sweongyoint siba_core_attach(struct siba_softc *); 144203319Sweongyoint siba_core_detach(struct siba_softc *); 145203319Sweongyoint siba_core_suspend(struct siba_softc *); 146203319Sweongyoint siba_core_resume(struct siba_softc *); 147203319Sweongyouint8_t siba_getncores(device_t, uint16_t); 148203319Sweongyo 149203319Sweongyostatic const struct siba_bus_ops siba_pci_ops = { 150203319Sweongyo .read_2 = siba_pci_read_2, 151203319Sweongyo .read_4 = siba_pci_read_4, 152203319Sweongyo .write_2 = siba_pci_write_2, 153203319Sweongyo .write_4 = siba_pci_write_4, 154203319Sweongyo .read_multi_1 = siba_pci_read_multi_1, 155203319Sweongyo .read_multi_2 = siba_pci_read_multi_2, 156203319Sweongyo .read_multi_4 = siba_pci_read_multi_4, 157203319Sweongyo .write_multi_1 = siba_pci_write_multi_1, 158203319Sweongyo .write_multi_2 = siba_pci_write_multi_2, 159203319Sweongyo .write_multi_4 = siba_pci_write_multi_4, 160203319Sweongyo}; 161203319Sweongyo 162203319Sweongyostatic const struct siba_cc_pmu_res_updown siba_cc_pmu_4325_updown[] = 163203319Sweongyo SIBA_CC_PMU_4325_RES_UPDOWN; 164203319Sweongyostatic const struct siba_cc_pmu_res_depend siba_cc_pmu_4325_depend[] = 165203319Sweongyo SIBA_CC_PMU_4325_RES_DEPEND; 166203319Sweongyostatic const struct siba_cc_pmu_res_updown siba_cc_pmu_4328_updown[] = 167203319Sweongyo SIBA_CC_PMU_4328_RES_UPDOWN; 168203319Sweongyostatic const struct siba_cc_pmu_res_depend siba_cc_pmu_4328_depend[] = 169203319Sweongyo SIBA_CC_PMU_4328_RES_DEPEND; 170203319Sweongyostatic const struct siba_cc_pmu0_plltab siba_cc_pmu0_plltab[] = 171203319Sweongyo SIBA_CC_PMU0_PLLTAB_ENTRY; 172203319Sweongyostatic const struct siba_cc_pmu1_plltab siba_cc_pmu1_plltab[] = 173203319Sweongyo SIBA_CC_PMU1_PLLTAB_ENTRY; 174203319Sweongyo 175203319Sweongyoint 176203319Sweongyosiba_core_attach(struct siba_softc *siba) 177203319Sweongyo{ 178203319Sweongyo struct siba_cc *scc; 179203319Sweongyo int error; 180203319Sweongyo 181203319Sweongyo KASSERT(siba->siba_type == SIBA_TYPE_PCI, 182203319Sweongyo ("unsupported BUS type (%#x)", siba->siba_type)); 183203319Sweongyo 184203319Sweongyo siba->siba_ops = &siba_pci_ops; 185203319Sweongyo 186203319Sweongyo siba_pci_gpio(siba, SIBA_GPIO_CRYSTAL | SIBA_GPIO_PLL, 1); 187203319Sweongyo siba_scan(siba); 188203319Sweongyo 189203319Sweongyo /* XXX init PCI or PCMCIA host devices */ 190203319Sweongyo 191204922Sweongyo siba_powerup_sub(siba, 0); 192203319Sweongyo 193203319Sweongyo /* init ChipCommon */ 194203319Sweongyo scc = &siba->siba_cc; 195203319Sweongyo if (scc->scc_dev != NULL) { 196203319Sweongyo siba_cc_pmu_init(scc); 197203319Sweongyo siba_cc_power_init(scc); 198203319Sweongyo siba_cc_clock(scc, SIBA_CLOCK_FAST); 199203319Sweongyo siba_cc_powerup_delay(scc); 200203319Sweongyo } 201203319Sweongyo 202203319Sweongyo error = siba_pci_sprom(siba, &siba->siba_sprom); 203203319Sweongyo if (error) { 204204922Sweongyo siba_powerdown_sub(siba); 205203319Sweongyo return (error); 206203319Sweongyo } 207203319Sweongyo 208204657Sweongyo siba_pcicore_init(&siba->siba_pci); 209204922Sweongyo siba_powerdown_sub(siba); 210204922Sweongyo 211204657Sweongyo return (bus_generic_attach(siba->siba_dev)); 212203319Sweongyo} 213203319Sweongyo 214203319Sweongyoint 215203319Sweongyosiba_core_detach(struct siba_softc *siba) 216203319Sweongyo{ 217227701Shselasky /* detach & delete all children */ 218227849Shselasky device_delete_children(siba->siba_dev); 219203319Sweongyo return (0); 220203319Sweongyo} 221203319Sweongyo 222203319Sweongyostatic void 223203319Sweongyosiba_pci_gpio(struct siba_softc *siba, uint32_t what, int on) 224203319Sweongyo{ 225203319Sweongyo uint32_t in, out; 226203319Sweongyo uint16_t status; 227203319Sweongyo 228203319Sweongyo if (siba->siba_type != SIBA_TYPE_PCI) 229203319Sweongyo return; 230203319Sweongyo 231203319Sweongyo out = pci_read_config(siba->siba_dev, SIBA_GPIO_OUT, 4); 232203319Sweongyo if (on == 0) { 233203319Sweongyo if (what & SIBA_GPIO_PLL) 234203319Sweongyo out |= SIBA_GPIO_PLL; 235203319Sweongyo if (what & SIBA_GPIO_CRYSTAL) 236203319Sweongyo out &= ~SIBA_GPIO_CRYSTAL; 237203319Sweongyo pci_write_config(siba->siba_dev, SIBA_GPIO_OUT, out, 4); 238203319Sweongyo pci_write_config(siba->siba_dev, SIBA_GPIO_OUT_EN, 239203319Sweongyo pci_read_config(siba->siba_dev, 240203319Sweongyo SIBA_GPIO_OUT_EN, 4) | what, 4); 241203319Sweongyo return; 242203319Sweongyo } 243203319Sweongyo 244203319Sweongyo in = pci_read_config(siba->siba_dev, SIBA_GPIO_IN, 4); 245203319Sweongyo if ((in & SIBA_GPIO_CRYSTAL) != SIBA_GPIO_CRYSTAL) { 246203319Sweongyo if (what & SIBA_GPIO_CRYSTAL) { 247203319Sweongyo out |= SIBA_GPIO_CRYSTAL; 248203319Sweongyo if (what & SIBA_GPIO_PLL) 249203319Sweongyo out |= SIBA_GPIO_PLL; 250203319Sweongyo pci_write_config(siba->siba_dev, SIBA_GPIO_OUT, out, 4); 251203319Sweongyo pci_write_config(siba->siba_dev, 252203319Sweongyo SIBA_GPIO_OUT_EN, pci_read_config(siba->siba_dev, 253203319Sweongyo SIBA_GPIO_OUT_EN, 4) | what, 4); 254203319Sweongyo DELAY(1000); 255203319Sweongyo } 256203319Sweongyo if (what & SIBA_GPIO_PLL) { 257203319Sweongyo out &= ~SIBA_GPIO_PLL; 258203319Sweongyo pci_write_config(siba->siba_dev, SIBA_GPIO_OUT, out, 4); 259203319Sweongyo DELAY(5000); 260203319Sweongyo } 261203319Sweongyo } 262203319Sweongyo 263203319Sweongyo status = pci_read_config(siba->siba_dev, PCIR_STATUS, 2); 264203319Sweongyo status &= ~PCIM_STATUS_STABORT; 265203319Sweongyo pci_write_config(siba->siba_dev, PCIR_STATUS, status, 2); 266203319Sweongyo} 267203319Sweongyo 268203319Sweongyostatic void 269203319Sweongyosiba_scan(struct siba_softc *siba) 270203319Sweongyo{ 271203319Sweongyo struct siba_dev_softc *sd; 272203319Sweongyo uint32_t idhi, tmp; 273204657Sweongyo device_t child; 274203319Sweongyo int base, dev_i = 0, error, i, is_pcie, n_80211 = 0, n_cc = 0, 275203319Sweongyo n_pci = 0; 276203319Sweongyo 277203319Sweongyo KASSERT(siba->siba_type == SIBA_TYPE_PCI, 278203319Sweongyo ("unsupported BUS type (%#x)", siba->siba_type)); 279203319Sweongyo 280203319Sweongyo siba->siba_ndevs = 0; 281203319Sweongyo error = siba_switchcore(siba, 0); /* need the first core */ 282203319Sweongyo if (error) 283203319Sweongyo return; 284203319Sweongyo 285203319Sweongyo idhi = siba_scan_read_4(siba, 0, SIBA_IDHIGH); 286203319Sweongyo if (SIBA_IDHIGH_CORECODE(idhi) == SIBA_DEVID_CHIPCOMMON) { 287203319Sweongyo tmp = siba_scan_read_4(siba, 0, SIBA_CC_CHIPID); 288203319Sweongyo siba->siba_chipid = SIBA_CC_ID(tmp); 289203319Sweongyo siba->siba_chiprev = SIBA_CC_REV(tmp); 290203319Sweongyo siba->siba_chippkg = SIBA_CC_PKG(tmp); 291203319Sweongyo if (SIBA_IDHIGH_REV(idhi) >= 4) 292203319Sweongyo siba->siba_ndevs = SIBA_CC_NCORES(tmp); 293203319Sweongyo siba->siba_cc.scc_caps = siba_scan_read_4(siba, 0, 294203319Sweongyo SIBA_CC_CAPS); 295203319Sweongyo } else { 296203319Sweongyo if (siba->siba_type == SIBA_TYPE_PCI) { 297203319Sweongyo siba->siba_chipid = siba_dev2chipid(siba); 298203319Sweongyo siba->siba_chiprev = pci_read_config(siba->siba_dev, 299203319Sweongyo PCIR_REVID, 2); 300203319Sweongyo siba->siba_chippkg = 0; 301203319Sweongyo } else { 302203319Sweongyo siba->siba_chipid = 0x4710; 303203319Sweongyo siba->siba_chiprev = 0; 304203319Sweongyo siba->siba_chippkg = 0; 305203319Sweongyo } 306203319Sweongyo } 307203319Sweongyo if (siba->siba_ndevs == 0) 308203319Sweongyo siba->siba_ndevs = siba_getncores(siba->siba_dev, 309203319Sweongyo siba->siba_chipid); 310203319Sweongyo if (siba->siba_ndevs > SIBA_MAX_CORES) { 311203319Sweongyo device_printf(siba->siba_dev, 312203319Sweongyo "too many siba cores (max %d %d)\n", 313203319Sweongyo SIBA_MAX_CORES, siba->siba_ndevs); 314203319Sweongyo return; 315203319Sweongyo } 316203319Sweongyo 317203319Sweongyo /* looking basic information about each cores/devices */ 318203319Sweongyo for (i = 0; i < siba->siba_ndevs; i++) { 319203319Sweongyo error = siba_switchcore(siba, i); 320203319Sweongyo if (error) 321203319Sweongyo return; 322203319Sweongyo sd = &(siba->siba_devs[dev_i]); 323203319Sweongyo idhi = siba_scan_read_4(siba, i, SIBA_IDHIGH); 324203319Sweongyo sd->sd_bus = siba; 325203319Sweongyo sd->sd_id.sd_device = SIBA_IDHIGH_CORECODE(idhi); 326203319Sweongyo sd->sd_id.sd_rev = SIBA_IDHIGH_REV(idhi); 327203319Sweongyo sd->sd_id.sd_vendor = SIBA_IDHIGH_VENDOR(idhi); 328203319Sweongyo sd->sd_ops = siba->siba_ops; 329203319Sweongyo sd->sd_coreidx = i; 330203319Sweongyo 331203319Sweongyo DPRINTF(siba, SIBA_DEBUG_SCAN, 332203319Sweongyo "core %d (%s) found (cc %#xrev %#x vendor %#x)\n", 333203319Sweongyo i, siba_core_name(sd->sd_id.sd_device), 334203319Sweongyo sd->sd_id.sd_device, sd->sd_id.sd_rev, sd->sd_id.vendor); 335203319Sweongyo 336203319Sweongyo switch (sd->sd_id.sd_device) { 337203319Sweongyo case SIBA_DEVID_CHIPCOMMON: 338203319Sweongyo n_cc++; 339203319Sweongyo if (n_cc > 1) { 340203319Sweongyo device_printf(siba->siba_dev, 341203319Sweongyo "warn: multiple ChipCommon\n"); 342203319Sweongyo break; 343203319Sweongyo } 344203319Sweongyo siba->siba_cc.scc_dev = sd; 345203319Sweongyo break; 346203319Sweongyo case SIBA_DEVID_80211: 347203319Sweongyo n_80211++; 348203319Sweongyo if (n_80211 > 1) { 349203319Sweongyo device_printf(siba->siba_dev, 350203319Sweongyo "warn: multiple 802.11 core\n"); 351203319Sweongyo continue; 352203319Sweongyo } 353203319Sweongyo break; 354203319Sweongyo case SIBA_DEVID_PCI: 355203319Sweongyo case SIBA_DEVID_PCIE: 356203319Sweongyo n_pci++; 357219902Sjhb error = pci_find_cap(siba->siba_dev, PCIY_EXPRESS, 358203319Sweongyo &base); 359203319Sweongyo is_pcie = (error == 0) ? 1 : 0; 360203319Sweongyo 361203319Sweongyo if (n_pci > 1) { 362203319Sweongyo device_printf(siba->siba_dev, 363203319Sweongyo "warn: multiple PCI(E) cores\n"); 364203319Sweongyo break; 365203319Sweongyo } 366203319Sweongyo if (sd->sd_id.sd_device == SIBA_DEVID_PCI && 367203319Sweongyo is_pcie == 1) 368203319Sweongyo continue; 369203319Sweongyo if (sd->sd_id.sd_device == SIBA_DEVID_PCIE && 370203319Sweongyo is_pcie == 0) 371203319Sweongyo continue; 372203319Sweongyo siba->siba_pci.spc_dev = sd; 373203319Sweongyo break; 374203319Sweongyo case SIBA_DEVID_MODEM: 375203319Sweongyo case SIBA_DEVID_PCMCIA: 376203319Sweongyo break; 377203319Sweongyo default: 378203319Sweongyo device_printf(siba->siba_dev, 379203319Sweongyo "unsupported coreid (%s)\n", 380203319Sweongyo siba_core_name(sd->sd_id.sd_device)); 381203319Sweongyo break; 382203319Sweongyo } 383203319Sweongyo dev_i++; 384204657Sweongyo 385204657Sweongyo child = device_add_child(siba->siba_dev, NULL, -1); 386204657Sweongyo if (child == NULL) { 387204657Sweongyo device_printf(siba->siba_dev, "child attach failed\n"); 388204657Sweongyo continue; 389204657Sweongyo } 390204657Sweongyo 391204657Sweongyo device_set_ivars(child, sd); 392203319Sweongyo } 393203319Sweongyo siba->siba_ndevs = dev_i; 394203319Sweongyo} 395203319Sweongyo 396203319Sweongyostatic int 397203319Sweongyosiba_switchcore(struct siba_softc *siba, uint8_t idx) 398203319Sweongyo{ 399203319Sweongyo 400203319Sweongyo switch (siba->siba_type) { 401203319Sweongyo case SIBA_TYPE_PCI: 402203319Sweongyo return (siba_pci_switchcore_sub(siba, idx)); 403203319Sweongyo default: 404203319Sweongyo KASSERT(0 == 1, 405203319Sweongyo ("%s: unsupported bustype %#x", __func__, 406203319Sweongyo siba->siba_type)); 407203319Sweongyo } 408203319Sweongyo return (0); 409203319Sweongyo} 410203319Sweongyo 411203319Sweongyostatic int 412203319Sweongyosiba_pci_switchcore_sub(struct siba_softc *siba, uint8_t idx) 413203319Sweongyo{ 414203319Sweongyo#define RETRY_MAX 50 415203319Sweongyo int i; 416203319Sweongyo uint32_t dir; 417203319Sweongyo 418203319Sweongyo dir = SIBA_REGWIN(idx); 419203319Sweongyo 420203319Sweongyo for (i = 0; i < RETRY_MAX; i++) { 421203319Sweongyo pci_write_config(siba->siba_dev, SIBA_BAR0, dir, 4); 422203319Sweongyo if (pci_read_config(siba->siba_dev, SIBA_BAR0, 4) == dir) 423203319Sweongyo return (0); 424203319Sweongyo DELAY(10); 425203319Sweongyo } 426203319Sweongyo return (ENODEV); 427203319Sweongyo#undef RETRY_MAX 428203319Sweongyo} 429203319Sweongyo 430203319Sweongyostatic int 431203319Sweongyosiba_pci_switchcore(struct siba_softc *siba, struct siba_dev_softc *sd) 432203319Sweongyo{ 433203319Sweongyo int error; 434203319Sweongyo 435203319Sweongyo DPRINTF(siba, SIBA_DEBUG_SWITCHCORE, "Switching to %s core, index %d\n", 436203319Sweongyo siba_core_name(sd->sd_id.sd_device), sd->sd_coreidx); 437203319Sweongyo 438203319Sweongyo error = siba_pci_switchcore_sub(siba, sd->sd_coreidx); 439203319Sweongyo if (error == 0) 440203319Sweongyo siba->siba_curdev = sd; 441203319Sweongyo 442203319Sweongyo return (error); 443203319Sweongyo} 444203319Sweongyo 445203319Sweongyostatic uint32_t 446203319Sweongyosiba_scan_read_4(struct siba_softc *siba, uint8_t coreidx, 447203319Sweongyo uint16_t offset) 448203319Sweongyo{ 449203319Sweongyo 450203319Sweongyo (void)coreidx; 451203319Sweongyo KASSERT(siba->siba_type == SIBA_TYPE_PCI, 452203319Sweongyo ("unsupported BUS type (%#x)", siba->siba_type)); 453203319Sweongyo 454203319Sweongyo return (SIBA_READ_4(siba, offset)); 455203319Sweongyo} 456203319Sweongyo 457203319Sweongyostatic uint16_t 458203319Sweongyosiba_dev2chipid(struct siba_softc *siba) 459203319Sweongyo{ 460203319Sweongyo uint16_t chipid = 0; 461203319Sweongyo 462203319Sweongyo switch (siba->siba_pci_did) { 463203319Sweongyo case 0x4301: 464203319Sweongyo chipid = 0x4301; 465203319Sweongyo break; 466203319Sweongyo case 0x4305: 467203319Sweongyo case 0x4306: 468203319Sweongyo case 0x4307: 469203319Sweongyo chipid = 0x4307; 470203319Sweongyo break; 471203319Sweongyo case 0x4403: 472203319Sweongyo chipid = 0x4402; 473203319Sweongyo break; 474203319Sweongyo case 0x4610: 475203319Sweongyo case 0x4611: 476203319Sweongyo case 0x4612: 477203319Sweongyo case 0x4613: 478203319Sweongyo case 0x4614: 479203319Sweongyo case 0x4615: 480203319Sweongyo chipid = 0x4610; 481203319Sweongyo break; 482203319Sweongyo case 0x4710: 483203319Sweongyo case 0x4711: 484203319Sweongyo case 0x4712: 485203319Sweongyo case 0x4713: 486203319Sweongyo case 0x4714: 487203319Sweongyo case 0x4715: 488203319Sweongyo chipid = 0x4710; 489203319Sweongyo break; 490203319Sweongyo case 0x4320: 491203319Sweongyo case 0x4321: 492203319Sweongyo case 0x4322: 493203319Sweongyo case 0x4323: 494203319Sweongyo case 0x4324: 495203319Sweongyo case 0x4325: 496203319Sweongyo chipid = 0x4309; 497203319Sweongyo break; 498203319Sweongyo case PCI_DEVICE_ID_BCM4401: 499203319Sweongyo case PCI_DEVICE_ID_BCM4401B0: 500203319Sweongyo case PCI_DEVICE_ID_BCM4401B1: 501203319Sweongyo chipid = 0x4401; 502203319Sweongyo break; 503203319Sweongyo default: 504203319Sweongyo device_printf(siba->siba_dev, "unknown PCI did (%d)\n", 505203319Sweongyo siba->siba_pci_did); 506203319Sweongyo } 507203319Sweongyo 508203319Sweongyo return (chipid); 509203319Sweongyo} 510203319Sweongyo 511203319Sweongyo/* 512203319Sweongyo * Earlier ChipCommon revisions have hardcoded number of cores 513203319Sweongyo * present dependent on the ChipCommon ID. 514203319Sweongyo */ 515203319Sweongyouint8_t 516203319Sweongyosiba_getncores(device_t dev, uint16_t chipid) 517203319Sweongyo{ 518203319Sweongyo switch (chipid) { 519203319Sweongyo case 0x4401: 520203319Sweongyo case 0x4402: 521203319Sweongyo return (3); 522203319Sweongyo case 0x4301: 523203319Sweongyo case 0x4307: 524203319Sweongyo return (5); 525203319Sweongyo case 0x4306: 526203319Sweongyo return (6); 527203319Sweongyo case SIBA_CCID_SENTRY5: 528203319Sweongyo return (7); 529203319Sweongyo case 0x4310: 530203319Sweongyo return (8); 531203319Sweongyo case SIBA_CCID_BCM4710: 532203319Sweongyo case 0x4610: 533203319Sweongyo case SIBA_CCID_BCM4704: 534203319Sweongyo return (9); 535203319Sweongyo default: 536203319Sweongyo device_printf(dev, "unknown the chipset ID %#x\n", chipid); 537203319Sweongyo } 538203319Sweongyo 539203319Sweongyo return (1); 540203319Sweongyo} 541203319Sweongyo 542203319Sweongyostatic const char * 543203319Sweongyosiba_core_name(uint16_t coreid) 544203319Sweongyo{ 545203319Sweongyo 546203319Sweongyo switch (coreid) { 547203319Sweongyo case SIBA_DEVID_CHIPCOMMON: 548203319Sweongyo return ("ChipCommon"); 549203319Sweongyo case SIBA_DEVID_ILINE20: 550203319Sweongyo return ("ILine 20"); 551203319Sweongyo case SIBA_DEVID_SDRAM: 552203319Sweongyo return ("SDRAM"); 553203319Sweongyo case SIBA_DEVID_PCI: 554203319Sweongyo return ("PCI"); 555203319Sweongyo case SIBA_DEVID_MIPS: 556203319Sweongyo return ("MIPS"); 557203319Sweongyo case SIBA_DEVID_ETHERNET: 558203319Sweongyo return ("Fast Ethernet"); 559203319Sweongyo case SIBA_DEVID_MODEM: 560203319Sweongyo return ("Modem"); 561203319Sweongyo case SIBA_DEVID_USB11_HOSTDEV: 562203319Sweongyo return ("USB 1.1 Hostdev"); 563203319Sweongyo case SIBA_DEVID_ADSL: 564203319Sweongyo return ("ADSL"); 565203319Sweongyo case SIBA_DEVID_ILINE100: 566203319Sweongyo return ("ILine 100"); 567203319Sweongyo case SIBA_DEVID_IPSEC: 568203319Sweongyo return ("IPSEC"); 569203319Sweongyo case SIBA_DEVID_PCMCIA: 570203319Sweongyo return ("PCMCIA"); 571203319Sweongyo case SIBA_DEVID_INTERNAL_MEM: 572203319Sweongyo return ("Internal Memory"); 573203319Sweongyo case SIBA_DEVID_SDRAMDDR: 574203319Sweongyo return ("MEMC SDRAM"); 575203319Sweongyo case SIBA_DEVID_EXTIF: 576203319Sweongyo return ("EXTIF"); 577203319Sweongyo case SIBA_DEVID_80211: 578203319Sweongyo return ("IEEE 802.11"); 579203319Sweongyo case SIBA_DEVID_MIPS_3302: 580203319Sweongyo return ("MIPS 3302"); 581203319Sweongyo case SIBA_DEVID_USB11_HOST: 582203319Sweongyo return ("USB 1.1 Host"); 583203319Sweongyo case SIBA_DEVID_USB11_DEV: 584203319Sweongyo return ("USB 1.1 Device"); 585203319Sweongyo case SIBA_DEVID_USB20_HOST: 586203319Sweongyo return ("USB 2.0 Host"); 587203319Sweongyo case SIBA_DEVID_USB20_DEV: 588203319Sweongyo return ("USB 2.0 Device"); 589203319Sweongyo case SIBA_DEVID_SDIO_HOST: 590203319Sweongyo return ("SDIO Host"); 591203319Sweongyo case SIBA_DEVID_ROBOSWITCH: 592203319Sweongyo return ("Roboswitch"); 593203319Sweongyo case SIBA_DEVID_PARA_ATA: 594203319Sweongyo return ("PATA"); 595203319Sweongyo case SIBA_DEVID_SATA_XORDMA: 596203319Sweongyo return ("SATA XOR-DMA"); 597203319Sweongyo case SIBA_DEVID_ETHERNET_GBIT: 598203319Sweongyo return ("GBit Ethernet"); 599203319Sweongyo case SIBA_DEVID_PCIE: 600203319Sweongyo return ("PCI-Express"); 601203319Sweongyo case SIBA_DEVID_MIMO_PHY: 602203319Sweongyo return ("MIMO PHY"); 603203319Sweongyo case SIBA_DEVID_SRAM_CTRLR: 604203319Sweongyo return ("SRAM Controller"); 605203319Sweongyo case SIBA_DEVID_MINI_MACPHY: 606203319Sweongyo return ("Mini MACPHY"); 607203319Sweongyo case SIBA_DEVID_ARM_1176: 608203319Sweongyo return ("ARM 1176"); 609203319Sweongyo case SIBA_DEVID_ARM_7TDMI: 610203319Sweongyo return ("ARM 7TDMI"); 611203319Sweongyo } 612203319Sweongyo return ("unknown"); 613203319Sweongyo} 614203319Sweongyo 615203319Sweongyostatic uint16_t 616203319Sweongyosiba_pci_read_2(struct siba_dev_softc *sd, uint16_t offset) 617203319Sweongyo{ 618203319Sweongyo struct siba_softc *siba = sd->sd_bus; 619203319Sweongyo 620203319Sweongyo if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0) 621203319Sweongyo return (0xffff); 622203319Sweongyo 623203319Sweongyo return (SIBA_READ_2(siba, offset)); 624203319Sweongyo} 625203319Sweongyo 626203319Sweongyostatic uint32_t 627203319Sweongyosiba_pci_read_4(struct siba_dev_softc *sd, uint16_t offset) 628203319Sweongyo{ 629203319Sweongyo struct siba_softc *siba = sd->sd_bus; 630203319Sweongyo 631203319Sweongyo if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0) 632203319Sweongyo return (0xffff); 633203319Sweongyo 634203319Sweongyo return (SIBA_READ_4(siba, offset)); 635203319Sweongyo} 636203319Sweongyo 637203319Sweongyostatic void 638203319Sweongyosiba_pci_write_2(struct siba_dev_softc *sd, uint16_t offset, uint16_t value) 639203319Sweongyo{ 640203319Sweongyo struct siba_softc *siba = sd->sd_bus; 641203319Sweongyo 642203319Sweongyo if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0) 643203319Sweongyo return; 644203319Sweongyo 645203319Sweongyo SIBA_WRITE_2(siba, offset, value); 646203319Sweongyo} 647203319Sweongyo 648203319Sweongyostatic void 649203319Sweongyosiba_pci_write_4(struct siba_dev_softc *sd, uint16_t offset, uint32_t value) 650203319Sweongyo{ 651203319Sweongyo struct siba_softc *siba = sd->sd_bus; 652203319Sweongyo 653203319Sweongyo if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0) 654203319Sweongyo return; 655203319Sweongyo 656203319Sweongyo SIBA_WRITE_4(siba, offset, value); 657203319Sweongyo} 658203319Sweongyo 659203319Sweongyostatic void 660203319Sweongyosiba_pci_read_multi_1(struct siba_dev_softc *sd, void *buffer, size_t count, 661203319Sweongyo uint16_t offset) 662203319Sweongyo{ 663203319Sweongyo struct siba_softc *siba = sd->sd_bus; 664203319Sweongyo 665203319Sweongyo if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0) { 666203319Sweongyo memset(buffer, 0xff, count); 667203319Sweongyo return; 668203319Sweongyo } 669203319Sweongyo 670203319Sweongyo SIBA_READ_MULTI_1(siba, offset, buffer, count); 671203319Sweongyo} 672203319Sweongyo 673203319Sweongyostatic void 674203319Sweongyosiba_pci_read_multi_2(struct siba_dev_softc *sd, void *buffer, size_t count, 675203319Sweongyo uint16_t offset) 676203319Sweongyo{ 677203319Sweongyo struct siba_softc *siba = sd->sd_bus; 678203319Sweongyo 679203319Sweongyo if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0) { 680203319Sweongyo memset(buffer, 0xff, count); 681203319Sweongyo return; 682203319Sweongyo } 683203319Sweongyo 684203319Sweongyo KASSERT(!(count & 1), ("%s:%d: fail", __func__, __LINE__)); 685203319Sweongyo SIBA_READ_MULTI_2(siba, offset, buffer, count >> 1); 686203319Sweongyo} 687203319Sweongyo 688203319Sweongyostatic void 689203319Sweongyosiba_pci_read_multi_4(struct siba_dev_softc *sd, void *buffer, size_t count, 690203319Sweongyo uint16_t offset) 691203319Sweongyo{ 692203319Sweongyo struct siba_softc *siba = sd->sd_bus; 693203319Sweongyo 694203319Sweongyo if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0) { 695203319Sweongyo memset(buffer, 0xff, count); 696203319Sweongyo return; 697203319Sweongyo } 698203319Sweongyo 699203319Sweongyo KASSERT(!(count & 3), ("%s:%d: fail", __func__, __LINE__)); 700203319Sweongyo SIBA_READ_MULTI_4(siba, offset, buffer, count >> 2); 701203319Sweongyo} 702203319Sweongyo 703203319Sweongyostatic void 704203319Sweongyosiba_pci_write_multi_1(struct siba_dev_softc *sd, const void *buffer, 705203319Sweongyo size_t count, uint16_t offset) 706203319Sweongyo{ 707203319Sweongyo struct siba_softc *siba = sd->sd_bus; 708203319Sweongyo 709203319Sweongyo if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0) 710203319Sweongyo return; 711203319Sweongyo 712203319Sweongyo SIBA_WRITE_MULTI_1(siba, offset, buffer, count); 713203319Sweongyo} 714203319Sweongyo 715203319Sweongyostatic void 716203319Sweongyosiba_pci_write_multi_2(struct siba_dev_softc *sd, const void *buffer, 717203319Sweongyo size_t count, uint16_t offset) 718203319Sweongyo{ 719203319Sweongyo struct siba_softc *siba = sd->sd_bus; 720203319Sweongyo 721203319Sweongyo if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0) 722203319Sweongyo return; 723203319Sweongyo 724203319Sweongyo KASSERT(!(count & 1), ("%s:%d: fail", __func__, __LINE__)); 725203319Sweongyo SIBA_WRITE_MULTI_2(siba, offset, buffer, count >> 1); 726203319Sweongyo} 727203319Sweongyo 728203319Sweongyostatic void 729203319Sweongyosiba_pci_write_multi_4(struct siba_dev_softc *sd, const void *buffer, 730203319Sweongyo size_t count, uint16_t offset) 731203319Sweongyo{ 732203319Sweongyo struct siba_softc *siba = sd->sd_bus; 733203319Sweongyo 734203319Sweongyo if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0) 735203319Sweongyo return; 736203319Sweongyo 737203319Sweongyo KASSERT(!(count & 3), ("%s:%d: fail", __func__, __LINE__)); 738203319Sweongyo SIBA_WRITE_MULTI_4(siba, offset, buffer, count >> 2); 739203319Sweongyo} 740203319Sweongyo 741203319Sweongyovoid 742204922Sweongyosiba_powerup(device_t dev, int dynamic) 743203319Sweongyo{ 744204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(dev); 745204922Sweongyo struct siba_softc *siba = sd->sd_bus; 746203319Sweongyo 747204922Sweongyo siba_powerup_sub(siba, dynamic); 748204922Sweongyo} 749204922Sweongyo 750204922Sweongyostatic void 751204922Sweongyosiba_powerup_sub(struct siba_softc *siba, int dynamic) 752204922Sweongyo{ 753204922Sweongyo 754203319Sweongyo siba_pci_gpio(siba, SIBA_GPIO_CRYSTAL | SIBA_GPIO_PLL, 1); 755203319Sweongyo siba_cc_clock(&siba->siba_cc, 756203319Sweongyo (dynamic != 0) ? SIBA_CLOCK_DYNAMIC : SIBA_CLOCK_FAST); 757203319Sweongyo} 758203319Sweongyo 759203319Sweongyostatic void 760203319Sweongyosiba_cc_clock(struct siba_cc *scc, enum siba_clock clock) 761203319Sweongyo{ 762203319Sweongyo struct siba_dev_softc *sd = scc->scc_dev; 763203319Sweongyo struct siba_softc *siba; 764203319Sweongyo uint32_t tmp; 765203319Sweongyo 766203319Sweongyo if (sd == NULL) 767203319Sweongyo return; 768203319Sweongyo siba = sd->sd_bus; 769203319Sweongyo /* 770203319Sweongyo * chipcommon < r6 (no dynamic clock control) 771203319Sweongyo * chipcommon >= r10 (unknown) 772203319Sweongyo */ 773203319Sweongyo if (sd->sd_id.sd_rev < 6 || sd->sd_id.sd_rev >= 10 || 774203319Sweongyo (scc->scc_caps & SIBA_CC_CAPS_PWCTL) == 0) 775203319Sweongyo return; 776203319Sweongyo 777203319Sweongyo switch (clock) { 778203319Sweongyo case SIBA_CLOCK_DYNAMIC: 779203319Sweongyo tmp = SIBA_CC_READ32(scc, SIBA_CC_CLKSLOW) & 780203319Sweongyo ~(SIBA_CC_CLKSLOW_ENXTAL | SIBA_CC_CLKSLOW_FSLOW | 781203319Sweongyo SIBA_CC_CLKSLOW_IPLL); 782203319Sweongyo if ((tmp & SIBA_CC_CLKSLOW_SRC) != SIBA_CC_CLKSLOW_SRC_CRYSTAL) 783203319Sweongyo tmp |= SIBA_CC_CLKSLOW_ENXTAL; 784203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_CLKSLOW, tmp); 785203319Sweongyo if (tmp & SIBA_CC_CLKSLOW_ENXTAL) 786203319Sweongyo siba_pci_gpio(siba, SIBA_GPIO_CRYSTAL, 0); 787203319Sweongyo break; 788203319Sweongyo case SIBA_CLOCK_SLOW: 789203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_CLKSLOW, 790203319Sweongyo SIBA_CC_READ32(scc, SIBA_CC_CLKSLOW) | 791203319Sweongyo SIBA_CC_CLKSLOW_FSLOW); 792203319Sweongyo break; 793203319Sweongyo case SIBA_CLOCK_FAST: 794203319Sweongyo /* crystal on */ 795203319Sweongyo siba_pci_gpio(siba, SIBA_GPIO_CRYSTAL, 1); 796203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_CLKSLOW, 797203319Sweongyo (SIBA_CC_READ32(scc, SIBA_CC_CLKSLOW) | 798203319Sweongyo SIBA_CC_CLKSLOW_IPLL) & ~SIBA_CC_CLKSLOW_FSLOW); 799203319Sweongyo break; 800203319Sweongyo default: 801203319Sweongyo KASSERT(0 == 1, 802203319Sweongyo ("%s: unsupported clock %#x", __func__, clock)); 803203319Sweongyo } 804203319Sweongyo} 805203319Sweongyo 806203319Sweongyouint16_t 807204922Sweongyosiba_read_2(device_t dev, uint16_t offset) 808203319Sweongyo{ 809204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(dev); 810203319Sweongyo 811203319Sweongyo return (sd->sd_ops->read_2(sd, offset)); 812203319Sweongyo} 813203319Sweongyo 814203319Sweongyouint32_t 815204922Sweongyosiba_read_4(device_t dev, uint16_t offset) 816203319Sweongyo{ 817204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(dev); 818203319Sweongyo 819204922Sweongyo return (siba_read_4_sub(sd, offset)); 820204922Sweongyo} 821204922Sweongyo 822204922Sweongyostatic uint32_t 823204922Sweongyosiba_read_4_sub(struct siba_dev_softc *sd, uint16_t offset) 824204922Sweongyo{ 825204922Sweongyo 826203319Sweongyo return (sd->sd_ops->read_4(sd, offset)); 827203319Sweongyo} 828203319Sweongyo 829203319Sweongyovoid 830204922Sweongyosiba_write_2(device_t dev, uint16_t offset, uint16_t value) 831203319Sweongyo{ 832204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(dev); 833203319Sweongyo 834203319Sweongyo sd->sd_ops->write_2(sd, offset, value); 835203319Sweongyo} 836203319Sweongyo 837203319Sweongyovoid 838204922Sweongyosiba_write_4(device_t dev, uint16_t offset, uint32_t value) 839203319Sweongyo{ 840204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(dev); 841203319Sweongyo 842204922Sweongyo return (siba_write_4_sub(sd, offset, value)); 843204922Sweongyo} 844204922Sweongyo 845204922Sweongyostatic void 846204922Sweongyosiba_write_4_sub(struct siba_dev_softc *sd, uint16_t offset, uint32_t value) 847204922Sweongyo{ 848204922Sweongyo 849203319Sweongyo sd->sd_ops->write_4(sd, offset, value); 850203319Sweongyo} 851203319Sweongyo 852203319Sweongyovoid 853204922Sweongyosiba_read_multi_1(device_t dev, void *buffer, size_t count, 854203319Sweongyo uint16_t offset) 855203319Sweongyo{ 856204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(dev); 857203319Sweongyo 858203319Sweongyo sd->sd_ops->read_multi_1(sd, buffer, count, offset); 859203319Sweongyo} 860203319Sweongyo 861203319Sweongyovoid 862204922Sweongyosiba_read_multi_2(device_t dev, void *buffer, size_t count, 863203319Sweongyo uint16_t offset) 864203319Sweongyo{ 865204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(dev); 866203319Sweongyo 867203319Sweongyo sd->sd_ops->read_multi_2(sd, buffer, count, offset); 868203319Sweongyo} 869203319Sweongyo 870203319Sweongyovoid 871204922Sweongyosiba_read_multi_4(device_t dev, void *buffer, size_t count, 872203319Sweongyo uint16_t offset) 873203319Sweongyo{ 874204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(dev); 875203319Sweongyo 876203319Sweongyo sd->sd_ops->read_multi_4(sd, buffer, count, offset); 877203319Sweongyo} 878203319Sweongyo 879203319Sweongyovoid 880204922Sweongyosiba_write_multi_1(device_t dev, const void *buffer, size_t count, 881204922Sweongyo uint16_t offset) 882203319Sweongyo{ 883204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(dev); 884203319Sweongyo 885203319Sweongyo sd->sd_ops->write_multi_1(sd, buffer, count, offset); 886203319Sweongyo} 887203319Sweongyo 888203319Sweongyovoid 889204922Sweongyosiba_write_multi_2(device_t dev, const void *buffer, size_t count, 890204922Sweongyo uint16_t offset) 891203319Sweongyo{ 892204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(dev); 893203319Sweongyo 894203319Sweongyo sd->sd_ops->write_multi_2(sd, buffer, count, offset); 895203319Sweongyo} 896203319Sweongyo 897203319Sweongyovoid 898204922Sweongyosiba_write_multi_4(device_t dev, const void *buffer, size_t count, 899204922Sweongyo uint16_t offset) 900203319Sweongyo{ 901204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(dev); 902203319Sweongyo 903203319Sweongyo sd->sd_ops->write_multi_4(sd, buffer, count, offset); 904203319Sweongyo} 905203319Sweongyo 906203319Sweongyostatic void 907203319Sweongyosiba_cc_pmu_init(struct siba_cc *scc) 908203319Sweongyo{ 909203319Sweongyo const struct siba_cc_pmu_res_updown *updown = NULL; 910203319Sweongyo const struct siba_cc_pmu_res_depend *depend = NULL; 911203319Sweongyo struct siba_dev_softc *sd = scc->scc_dev; 912203319Sweongyo struct siba_softc *siba = sd->sd_bus; 913203319Sweongyo uint32_t min = 0, max = 0, pmucap; 914203319Sweongyo unsigned int i, updown_size, depend_size; 915203319Sweongyo 916203319Sweongyo if ((scc->scc_caps & SIBA_CC_CAPS_PMU) == 0) 917203319Sweongyo return; 918203319Sweongyo 919203319Sweongyo pmucap = SIBA_CC_READ32(scc, SIBA_CC_PMUCAPS); 920203319Sweongyo scc->scc_pmu.rev = (pmucap & SIBA_CC_PMUCAPS_REV); 921203319Sweongyo 922203319Sweongyo DPRINTF(siba, SIBA_DEBUG_PMU, "PMU(r%u) found (caps %#x)\n", 923203319Sweongyo scc->scc_pmu.rev, pmucap); 924203319Sweongyo 925203319Sweongyo if (scc->scc_pmu.rev >= 1) { 926203319Sweongyo if (siba->siba_chiprev < 2 && siba->siba_chipid == 0x4325) 927203319Sweongyo SIBA_CC_MASK32(scc, SIBA_CC_PMUCTL, 928203319Sweongyo ~SIBA_CC_PMUCTL_NOILP); 929203319Sweongyo else 930203319Sweongyo SIBA_CC_SET32(scc, SIBA_CC_PMUCTL, 931203319Sweongyo SIBA_CC_PMUCTL_NOILP); 932203319Sweongyo } 933203319Sweongyo 934203319Sweongyo /* initialize PLL & PMU resources */ 935203319Sweongyo switch (siba->siba_chipid) { 936203319Sweongyo case 0x4312: 937203319Sweongyo siba_cc_pmu1_pll0_init(scc, 0 /* use default */); 938203319Sweongyo /* use the default: min = 0xcbb max = 0x7ffff */ 939203319Sweongyo break; 940203319Sweongyo case 0x4325: 941203319Sweongyo siba_cc_pmu1_pll0_init(scc, 0 /* use default */); 942203319Sweongyo 943203319Sweongyo updown = siba_cc_pmu_4325_updown; 944203319Sweongyo updown_size = N(siba_cc_pmu_4325_updown); 945203319Sweongyo depend = siba_cc_pmu_4325_depend; 946203319Sweongyo depend_size = N(siba_cc_pmu_4325_depend); 947203319Sweongyo 948203319Sweongyo min = (1 << SIBA_CC_PMU_4325_BURST) | 949203319Sweongyo (1 << SIBA_CC_PMU_4325_LN); 950203319Sweongyo if (SIBA_CC_READ32(scc, SIBA_CC_CHIPSTAT) & 951203319Sweongyo SIBA_CC_CHST_4325_PMUTOP_2B) 952203319Sweongyo min |= (1 << SIBA_CC_PMU_4325_CLBURST); 953203319Sweongyo max = 0xfffff; 954203319Sweongyo break; 955203319Sweongyo case 0x4328: 956203319Sweongyo siba_cc_pmu0_pll0_init(scc, 0 /* use default */); 957203319Sweongyo 958203319Sweongyo updown = siba_cc_pmu_4328_updown; 959203319Sweongyo updown_size = N(siba_cc_pmu_4328_updown); 960203319Sweongyo depend = siba_cc_pmu_4328_depend; 961203319Sweongyo depend_size = N(siba_cc_pmu_4328_depend); 962203319Sweongyo 963203319Sweongyo min = (1 << SIBA_CC_PMU_4328_EXT_SWITCH_PWM) | 964203319Sweongyo (1 << SIBA_CC_PMU_4328_BB_SWITCH_PWM) | 965203319Sweongyo (1 << SIBA_CC_PMU_4328_CRYSTAL_EN); 966203319Sweongyo 967203319Sweongyo max = 0xfffff; 968203319Sweongyo break; 969203319Sweongyo case 0x5354: 970203319Sweongyo siba_cc_pmu0_pll0_init(scc, 0 /* use default */); 971203319Sweongyo 972203319Sweongyo max = 0xfffff; 973203319Sweongyo break; 974203319Sweongyo default: 975203319Sweongyo device_printf(siba->siba_dev, 976203319Sweongyo "unknown chipid %#x for PLL & PMU init\n", 977203319Sweongyo siba->siba_chipid); 978203319Sweongyo } 979203319Sweongyo 980203319Sweongyo if (updown) { 981203319Sweongyo for (i = 0; i < updown_size; i++) { 982203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PMU_TABSEL, 983203319Sweongyo updown[i].res); 984203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PMU_UPDNTM, 985203319Sweongyo updown[i].updown); 986203319Sweongyo } 987203319Sweongyo } 988203319Sweongyo if (depend) { 989203319Sweongyo for (i = 0; i < depend_size; i++) { 990203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PMU_TABSEL, 991203319Sweongyo depend[i].res); 992203319Sweongyo switch (depend[i].task) { 993203319Sweongyo case SIBA_CC_PMU_DEP_SET: 994203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PMU_DEPMSK, 995203319Sweongyo depend[i].depend); 996203319Sweongyo break; 997203319Sweongyo case SIBA_CC_PMU_DEP_ADD: 998203319Sweongyo SIBA_CC_SET32(scc, SIBA_CC_PMU_DEPMSK, 999203319Sweongyo depend[i].depend); 1000203319Sweongyo break; 1001203319Sweongyo case SIBA_CC_PMU_DEP_REMOVE: 1002203319Sweongyo SIBA_CC_MASK32(scc, SIBA_CC_PMU_DEPMSK, 1003203319Sweongyo ~(depend[i].depend)); 1004203319Sweongyo break; 1005203319Sweongyo default: 1006203319Sweongyo KASSERT(0 == 1, 1007203319Sweongyo ("%s:%d: assertion failed", 1008203319Sweongyo __func__, __LINE__)); 1009203319Sweongyo } 1010203319Sweongyo } 1011203319Sweongyo } 1012203319Sweongyo 1013203319Sweongyo if (min) 1014203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PMU_MINRES, min); 1015203319Sweongyo if (max) 1016203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PMU_MAXRES, max); 1017203319Sweongyo} 1018203319Sweongyo 1019203319Sweongyostatic void 1020203319Sweongyosiba_cc_power_init(struct siba_cc *scc) 1021203319Sweongyo{ 1022203319Sweongyo struct siba_softc *siba = scc->scc_dev->sd_bus; 1023203319Sweongyo int maxfreq; 1024203319Sweongyo 1025203319Sweongyo if (siba->siba_chipid == 0x4321) { 1026203319Sweongyo if (siba->siba_chiprev == 0) 1027203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_CHIPCTL, 0x3a4); 1028203319Sweongyo else if (siba->siba_chiprev == 1) 1029203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_CHIPCTL, 0xa4); 1030203319Sweongyo } 1031203319Sweongyo 1032203319Sweongyo if ((scc->scc_caps & SIBA_CC_CAPS_PWCTL) == 0) 1033203319Sweongyo return; 1034203319Sweongyo 1035203319Sweongyo if (scc->scc_dev->sd_id.sd_rev >= 10) 1036203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_CLKSYSCTL, 1037203319Sweongyo (SIBA_CC_READ32(scc, SIBA_CC_CLKSYSCTL) & 1038203319Sweongyo 0xffff) | 0x40000); 1039203319Sweongyo else { 1040203319Sweongyo maxfreq = siba_cc_clockfreq(scc, 1); 1041203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PLLONDELAY, 1042203319Sweongyo (maxfreq * 150 + 999999) / 1000000); 1043203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_FREFSELDELAY, 1044203319Sweongyo (maxfreq * 15 + 999999) / 1000000); 1045203319Sweongyo } 1046203319Sweongyo} 1047203319Sweongyo 1048203319Sweongyostatic void 1049203319Sweongyosiba_cc_powerup_delay(struct siba_cc *scc) 1050203319Sweongyo{ 1051203319Sweongyo struct siba_softc *siba = scc->scc_dev->sd_bus; 1052203319Sweongyo int min; 1053203319Sweongyo 1054203319Sweongyo if (siba->siba_type != SIBA_TYPE_PCI || 1055203319Sweongyo !(scc->scc_caps & SIBA_CC_CAPS_PWCTL)) 1056203319Sweongyo return; 1057203319Sweongyo 1058203319Sweongyo min = siba_cc_clockfreq(scc, 0); 1059203319Sweongyo scc->scc_powerup_delay = 1060203319Sweongyo (((SIBA_CC_READ32(scc, SIBA_CC_PLLONDELAY) + 2) * 1000000) + 1061203319Sweongyo (min - 1)) / min; 1062203319Sweongyo} 1063203319Sweongyo 1064203319Sweongyostatic int 1065203319Sweongyosiba_cc_clockfreq(struct siba_cc *scc, int max) 1066203319Sweongyo{ 1067203319Sweongyo enum siba_clksrc src; 1068203319Sweongyo int div = 1, limit = 0; 1069203319Sweongyo 1070203319Sweongyo src = siba_cc_clksrc(scc); 1071203319Sweongyo if (scc->scc_dev->sd_id.sd_rev < 6) { 1072203319Sweongyo div = (src == SIBA_CC_CLKSRC_PCI) ? 64 : 1073203319Sweongyo (src == SIBA_CC_CLKSRC_CRYSTAL) ? 32 : 1; 1074203319Sweongyo KASSERT(div != 1, 1075203319Sweongyo ("%s: unknown clock %d", __func__, src)); 1076203319Sweongyo } else if (scc->scc_dev->sd_id.sd_rev < 10) { 1077203319Sweongyo switch (src) { 1078203319Sweongyo case SIBA_CC_CLKSRC_CRYSTAL: 1079203319Sweongyo case SIBA_CC_CLKSRC_PCI: 1080203319Sweongyo div = ((SIBA_CC_READ32(scc, SIBA_CC_CLKSLOW) >> 16) + 1081203319Sweongyo 1) * 4; 1082203319Sweongyo break; 1083203319Sweongyo case SIBA_CC_CLKSRC_LOWPW: 1084203319Sweongyo break; 1085203319Sweongyo } 1086203319Sweongyo } else 1087203319Sweongyo div = ((SIBA_CC_READ32(scc, SIBA_CC_CLKSYSCTL) >> 16) + 1) * 4; 1088203319Sweongyo 1089203319Sweongyo switch (src) { 1090203319Sweongyo case SIBA_CC_CLKSRC_CRYSTAL: 1091203319Sweongyo limit = (max) ? 20200000 : 19800000; 1092203319Sweongyo break; 1093203319Sweongyo case SIBA_CC_CLKSRC_LOWPW: 1094203319Sweongyo limit = (max) ? 43000 : 25000; 1095203319Sweongyo break; 1096203319Sweongyo case SIBA_CC_CLKSRC_PCI: 1097203319Sweongyo limit = (max) ? 34000000 : 25000000; 1098203319Sweongyo break; 1099203319Sweongyo } 1100203319Sweongyo 1101203319Sweongyo return (limit / div); 1102203319Sweongyo} 1103203319Sweongyo 1104203319Sweongyostatic void 1105203319Sweongyosiba_cc_pmu1_pll0_init(struct siba_cc *scc, uint32_t freq) 1106203319Sweongyo{ 1107203319Sweongyo struct siba_dev_softc *sd = scc->scc_dev; 1108203319Sweongyo struct siba_softc *siba = sd->sd_bus; 1109203319Sweongyo const struct siba_cc_pmu1_plltab *e = NULL; 1110203319Sweongyo uint32_t bufsth = 0, pll, pmu; 1111203319Sweongyo unsigned int i; 1112203319Sweongyo 1113203319Sweongyo KASSERT(freq == 0, ("%s:%d: assertion vail", __func__, __LINE__)); 1114203319Sweongyo if (siba->siba_chipid == 0x4312) { 1115203319Sweongyo scc->scc_pmu.freq = 20000; 1116203319Sweongyo return; 1117203319Sweongyo } 1118203319Sweongyo 1119203319Sweongyo e = siba_cc_pmu1_plltab_find(SIBA_CC_PMU1_DEFAULT_FREQ); 1120203319Sweongyo KASSERT(e != NULL, ("%s:%d: assertion vail", __func__, __LINE__)); 1121203319Sweongyo scc->scc_pmu.freq = e->freq; 1122203319Sweongyo 1123203319Sweongyo pmu = SIBA_CC_READ32(scc, SIBA_CC_PMUCTL); 1124203319Sweongyo if (SIBA_CC_PMUCTL_XF_VAL(pmu) == e->xf) 1125203319Sweongyo return; 1126203319Sweongyo 1127203319Sweongyo DPRINTF(siba, SIBA_DEBUG_PLL, "change PLL value to %u.%03u MHz\n", 1128203319Sweongyo (e->freq / 1000), (e->freq % 1000)); 1129203319Sweongyo 1130203319Sweongyo /* turn PLL off */ 1131203319Sweongyo switch (siba->siba_chipid) { 1132203319Sweongyo case 0x4325: 1133203319Sweongyo bufsth = 0x222222; 1134203319Sweongyo SIBA_CC_MASK32(scc, SIBA_CC_PMU_MINRES, 1135203319Sweongyo ~((1 << SIBA_CC_PMU_4325_BBPLL_PWR) | 1136203319Sweongyo (1 << SIBA_CC_PMU_4325_HT))); 1137203319Sweongyo SIBA_CC_MASK32(scc, SIBA_CC_PMU_MAXRES, 1138203319Sweongyo ~((1 << SIBA_CC_PMU_4325_BBPLL_PWR) | 1139203319Sweongyo (1 << SIBA_CC_PMU_4325_HT))); 1140203319Sweongyo break; 1141203319Sweongyo default: 1142203319Sweongyo KASSERT(0 == 1, 1143203319Sweongyo ("%s:%d: assertion failed", __func__, __LINE__)); 1144203319Sweongyo } 1145203319Sweongyo for (i = 0; i < 1500; i++) { 1146203319Sweongyo if (!(SIBA_CC_READ32(scc, SIBA_CC_CLKCTLSTATUS) & 1147203319Sweongyo SIBA_CC_CLKCTLSTATUS_HT)) 1148203319Sweongyo break; 1149203319Sweongyo DELAY(10); 1150203319Sweongyo } 1151203319Sweongyo if (SIBA_CC_READ32(scc, SIBA_CC_CLKCTLSTATUS) & SIBA_CC_CLKCTLSTATUS_HT) 1152203319Sweongyo device_printf(siba->siba_dev, "failed to turn PLL off!\n"); 1153203319Sweongyo 1154203319Sweongyo pll = siba_cc_pll_read(scc, SIBA_CC_PMU1_PLL0); 1155203319Sweongyo pll &= ~(SIBA_CC_PMU1_PLL0_P1DIV | SIBA_CC_PMU1_PLL0_P2DIV); 1156203319Sweongyo pll |= ((uint32_t)e->p1div << 20) & SIBA_CC_PMU1_PLL0_P1DIV; 1157203319Sweongyo pll |= ((uint32_t)e->p2div << 24) & SIBA_CC_PMU1_PLL0_P2DIV; 1158203319Sweongyo siba_cc_pll_write(scc, SIBA_CC_PMU1_PLL0, pll); 1159203319Sweongyo 1160203319Sweongyo pll = siba_cc_pll_read(scc, SIBA_CC_PMU1_PLL2); 1161203319Sweongyo pll &= ~(SIBA_CC_PMU1_PLL2_NDIVINT | SIBA_CC_PMU1_PLL2_NDIVMODE); 1162203319Sweongyo pll |= ((uint32_t)e->ndiv_int << 20) & SIBA_CC_PMU1_PLL2_NDIVINT; 1163203319Sweongyo pll |= (1 << 17) & SIBA_CC_PMU1_PLL2_NDIVMODE; 1164203319Sweongyo siba_cc_pll_write(scc, SIBA_CC_PMU1_PLL2, pll); 1165203319Sweongyo 1166203319Sweongyo pll = siba_cc_pll_read(scc, SIBA_CC_PMU1_PLL3); 1167203319Sweongyo pll &= ~SIBA_CC_PMU1_PLL3_NDIVFRAC; 1168203319Sweongyo pll |= ((uint32_t)e->ndiv_frac << 0) & SIBA_CC_PMU1_PLL3_NDIVFRAC; 1169203319Sweongyo siba_cc_pll_write(scc, SIBA_CC_PMU1_PLL3, pll); 1170203319Sweongyo 1171203319Sweongyo if (bufsth) { 1172203319Sweongyo pll = siba_cc_pll_read(scc, SIBA_CC_PMU1_PLL5); 1173203319Sweongyo pll &= ~SIBA_CC_PMU1_PLL5_CLKDRV; 1174203319Sweongyo pll |= (bufsth << 8) & SIBA_CC_PMU1_PLL5_CLKDRV; 1175203319Sweongyo siba_cc_pll_write(scc, SIBA_CC_PMU1_PLL5, pll); 1176203319Sweongyo } 1177203319Sweongyo 1178203319Sweongyo pmu = SIBA_CC_READ32(scc, SIBA_CC_PMUCTL); 1179203319Sweongyo pmu &= ~(SIBA_CC_PMUCTL_ILP | SIBA_CC_PMUCTL_XF); 1180203319Sweongyo pmu |= ((((uint32_t)e->freq + 127) / 128 - 1) << 16) & 1181203319Sweongyo SIBA_CC_PMUCTL_ILP; 1182203319Sweongyo pmu |= ((uint32_t)e->xf << 2) & SIBA_CC_PMUCTL_XF; 1183203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PMUCTL, pmu); 1184203319Sweongyo} 1185203319Sweongyo 1186203319Sweongyostatic void 1187203319Sweongyosiba_cc_pmu0_pll0_init(struct siba_cc *scc, uint32_t xtalfreq) 1188203319Sweongyo{ 1189203319Sweongyo struct siba_dev_softc *sd = scc->scc_dev; 1190203319Sweongyo struct siba_softc *siba = sd->sd_bus; 1191203319Sweongyo const struct siba_cc_pmu0_plltab *e = NULL; 1192203319Sweongyo uint32_t pmu, tmp, pll; 1193203319Sweongyo unsigned int i; 1194203319Sweongyo 1195203319Sweongyo if ((siba->siba_chipid == 0x5354) && !xtalfreq) 1196203319Sweongyo xtalfreq = 25000; 1197203319Sweongyo if (xtalfreq) 1198203319Sweongyo e = siba_cc_pmu0_plltab_findentry(xtalfreq); 1199203319Sweongyo if (!e) 1200203319Sweongyo e = siba_cc_pmu0_plltab_findentry( 1201203319Sweongyo SIBA_CC_PMU0_DEFAULT_XTALFREQ); 1202203319Sweongyo KASSERT(e != NULL, ("%s:%d: fail", __func__, __LINE__)); 1203203319Sweongyo xtalfreq = e->freq; 1204203319Sweongyo scc->scc_pmu.freq = e->freq; 1205203319Sweongyo 1206203319Sweongyo pmu = SIBA_CC_READ32(scc, SIBA_CC_PMUCTL); 1207203319Sweongyo if (((pmu & SIBA_CC_PMUCTL_XF) >> 2) == e->xf) 1208203319Sweongyo return; 1209203319Sweongyo 1210232250Sgavin DPRINTF(siba, SIBA_DEBUG_PLL, "change PLL value to %u.%03u MHz\n", 1211203319Sweongyo (xtalfreq / 1000), (xtalfreq % 1000)); 1212203319Sweongyo 1213203319Sweongyo KASSERT(siba->siba_chipid == 0x4328 || siba->siba_chipid == 0x5354, 1214203319Sweongyo ("%s:%d: fail", __func__, __LINE__)); 1215203319Sweongyo 1216203319Sweongyo switch (siba->siba_chipid) { 1217203319Sweongyo case 0x4328: 1218203319Sweongyo SIBA_CC_MASK32(scc, SIBA_CC_PMU_MINRES, 1219203319Sweongyo ~(1 << SIBA_CC_PMU_4328_BB_PLL_PU)); 1220203319Sweongyo SIBA_CC_MASK32(scc, SIBA_CC_PMU_MAXRES, 1221203319Sweongyo ~(1 << SIBA_CC_PMU_4328_BB_PLL_PU)); 1222203319Sweongyo break; 1223203319Sweongyo case 0x5354: 1224203319Sweongyo SIBA_CC_MASK32(scc, SIBA_CC_PMU_MINRES, 1225203319Sweongyo ~(1 << SIBA_CC_PMU_5354_BB_PLL_PU)); 1226203319Sweongyo SIBA_CC_MASK32(scc, SIBA_CC_PMU_MAXRES, 1227203319Sweongyo ~(1 << SIBA_CC_PMU_5354_BB_PLL_PU)); 1228203319Sweongyo break; 1229203319Sweongyo } 1230203319Sweongyo for (i = 1500; i; i--) { 1231203319Sweongyo tmp = SIBA_CC_READ32(scc, SIBA_CC_CLKCTLSTATUS); 1232203319Sweongyo if (!(tmp & SIBA_CC_CLKCTLSTATUS_HT)) 1233203319Sweongyo break; 1234203319Sweongyo DELAY(10); 1235203319Sweongyo } 1236203319Sweongyo tmp = SIBA_CC_READ32(scc, SIBA_CC_CLKCTLSTATUS); 1237203319Sweongyo if (tmp & SIBA_CC_CLKCTLSTATUS_HT) 1238203319Sweongyo device_printf(siba->siba_dev, "failed to turn PLL off!\n"); 1239203319Sweongyo 1240203319Sweongyo /* set PDIV */ 1241203319Sweongyo pll = siba_cc_pll_read(scc, SIBA_CC_PMU0_PLL0); 1242203319Sweongyo if (xtalfreq >= SIBA_CC_PMU0_PLL0_PDIV_FREQ) 1243203319Sweongyo pll |= SIBA_CC_PMU0_PLL0_PDIV_MSK; 1244203319Sweongyo else 1245203319Sweongyo pll &= ~SIBA_CC_PMU0_PLL0_PDIV_MSK; 1246203319Sweongyo siba_cc_pll_write(scc, SIBA_CC_PMU0_PLL0, pll); 1247203319Sweongyo 1248203319Sweongyo /* set WILD */ 1249203319Sweongyo pll = siba_cc_pll_read(scc, SIBA_CC_PMU0_PLL1); 1250203319Sweongyo pll &= ~(SIBA_CC_PMU0_PLL1_STOPMOD | SIBA_CC_PMU0_PLL1_IMSK | 1251203319Sweongyo SIBA_CC_PMU0_PLL1_FMSK); 1252203319Sweongyo pll |= ((uint32_t)e->wb_int << 28) & SIBA_CC_PMU0_PLL1_IMSK; 1253203319Sweongyo pll |= ((uint32_t)e->wb_frac << 8) & SIBA_CC_PMU0_PLL1_FMSK; 1254203319Sweongyo if (e->wb_frac == 0) 1255203319Sweongyo pll |= SIBA_CC_PMU0_PLL1_STOPMOD; 1256203319Sweongyo siba_cc_pll_write(scc, SIBA_CC_PMU0_PLL1, pll); 1257203319Sweongyo 1258203319Sweongyo /* set WILD */ 1259203319Sweongyo pll = siba_cc_pll_read(scc, SIBA_CC_PMU0_PLL2); 1260203319Sweongyo pll &= ~SIBA_CC_PMU0_PLL2_IMSKHI; 1261203319Sweongyo pll |= (((uint32_t)e->wb_int >> 4) << 0) & SIBA_CC_PMU0_PLL2_IMSKHI; 1262203319Sweongyo siba_cc_pll_write(scc, SIBA_CC_PMU0_PLL2, pll); 1263203319Sweongyo 1264203319Sweongyo /* set freq and divisor. */ 1265203319Sweongyo pmu = SIBA_CC_READ32(scc, SIBA_CC_PMUCTL); 1266203319Sweongyo pmu &= ~SIBA_CC_PMUCTL_ILP; 1267203319Sweongyo pmu |= (((xtalfreq + 127) / 128 - 1) << 16) & SIBA_CC_PMUCTL_ILP; 1268203319Sweongyo pmu &= ~SIBA_CC_PMUCTL_XF; 1269203319Sweongyo pmu |= ((uint32_t)e->xf << 2) & SIBA_CC_PMUCTL_XF; 1270203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PMUCTL, pmu); 1271203319Sweongyo} 1272203319Sweongyo 1273203319Sweongyostatic enum siba_clksrc 1274203319Sweongyosiba_cc_clksrc(struct siba_cc *scc) 1275203319Sweongyo{ 1276203319Sweongyo struct siba_dev_softc *sd = scc->scc_dev; 1277203319Sweongyo struct siba_softc *siba = sd->sd_bus; 1278203319Sweongyo 1279203319Sweongyo if (sd->sd_id.sd_rev < 6) { 1280203319Sweongyo if (siba->siba_type == SIBA_TYPE_PCI) { 1281203319Sweongyo if (pci_read_config(siba->siba_dev, SIBA_GPIO_OUT, 4) & 1282203319Sweongyo 0x10) 1283203319Sweongyo return (SIBA_CC_CLKSRC_PCI); 1284203319Sweongyo return (SIBA_CC_CLKSRC_CRYSTAL); 1285203319Sweongyo } 1286203319Sweongyo if (siba->siba_type == SIBA_TYPE_SSB || 1287203319Sweongyo siba->siba_type == SIBA_TYPE_PCMCIA) 1288203319Sweongyo return (SIBA_CC_CLKSRC_CRYSTAL); 1289203319Sweongyo } 1290203319Sweongyo if (sd->sd_id.sd_rev < 10) { 1291203319Sweongyo switch (SIBA_CC_READ32(scc, SIBA_CC_CLKSLOW) & 0x7) { 1292203319Sweongyo case 0: 1293203319Sweongyo return (SIBA_CC_CLKSRC_LOWPW); 1294203319Sweongyo case 1: 1295203319Sweongyo return (SIBA_CC_CLKSRC_CRYSTAL); 1296203319Sweongyo case 2: 1297203319Sweongyo return (SIBA_CC_CLKSRC_PCI); 1298203319Sweongyo default: 1299203319Sweongyo break; 1300203319Sweongyo } 1301203319Sweongyo } 1302203319Sweongyo 1303203319Sweongyo return (SIBA_CC_CLKSRC_CRYSTAL); 1304203319Sweongyo} 1305203319Sweongyo 1306203319Sweongyostatic const struct siba_cc_pmu1_plltab * 1307203319Sweongyosiba_cc_pmu1_plltab_find(uint32_t crystalfreq) 1308203319Sweongyo{ 1309203319Sweongyo const struct siba_cc_pmu1_plltab *e; 1310203319Sweongyo unsigned int i; 1311203319Sweongyo 1312203319Sweongyo for (i = 0; i < N(siba_cc_pmu1_plltab); i++) { 1313203319Sweongyo e = &siba_cc_pmu1_plltab[i]; 1314203319Sweongyo if (crystalfreq == e->freq) 1315203319Sweongyo return (e); 1316203319Sweongyo } 1317203319Sweongyo 1318203319Sweongyo return (NULL); 1319203319Sweongyo} 1320203319Sweongyo 1321203319Sweongyostatic uint32_t 1322203319Sweongyosiba_cc_pll_read(struct siba_cc *scc, uint32_t offset) 1323203319Sweongyo{ 1324203319Sweongyo 1325203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PLLCTL_ADDR, offset); 1326203319Sweongyo return (SIBA_CC_READ32(scc, SIBA_CC_PLLCTL_DATA)); 1327203319Sweongyo} 1328203319Sweongyo 1329203319Sweongyostatic void 1330203319Sweongyosiba_cc_pll_write(struct siba_cc *scc, uint32_t offset, uint32_t value) 1331203319Sweongyo{ 1332203319Sweongyo 1333203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PLLCTL_ADDR, offset); 1334203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PLLCTL_DATA, value); 1335203319Sweongyo} 1336203319Sweongyo 1337203319Sweongyostatic const struct siba_cc_pmu0_plltab * 1338203319Sweongyosiba_cc_pmu0_plltab_findentry(uint32_t crystalfreq) 1339203319Sweongyo{ 1340203319Sweongyo const struct siba_cc_pmu0_plltab *e; 1341203319Sweongyo unsigned int i; 1342203319Sweongyo 1343203319Sweongyo for (i = 0; i < N(siba_cc_pmu0_plltab); i++) { 1344203319Sweongyo e = &siba_cc_pmu0_plltab[i]; 1345203319Sweongyo if (e->freq == crystalfreq) 1346203319Sweongyo return (e); 1347203319Sweongyo } 1348203319Sweongyo 1349203319Sweongyo return (NULL); 1350203319Sweongyo} 1351203319Sweongyo 1352203319Sweongyostatic int 1353203319Sweongyosiba_pci_sprom(struct siba_softc *siba, struct siba_sprom *sprom) 1354203319Sweongyo{ 1355203319Sweongyo int error = ENOMEM; 1356203319Sweongyo uint16_t *buf; 1357203319Sweongyo 1358203319Sweongyo buf = malloc(SIBA_SPROMSIZE_R123 * sizeof(uint16_t), 1359203319Sweongyo M_DEVBUF, M_NOWAIT | M_ZERO); 1360203319Sweongyo if (buf == NULL) 1361203319Sweongyo return (ENOMEM); 1362203319Sweongyo siba_sprom_read(siba, buf, SIBA_SPROMSIZE_R123); 1363203319Sweongyo error = sprom_check_crc(buf, siba->siba_spromsize); 1364203319Sweongyo if (error) { 1365203319Sweongyo free(buf, M_DEVBUF); 1366203319Sweongyo buf = malloc(SIBA_SPROMSIZE_R4 * sizeof(uint16_t), 1367203319Sweongyo M_DEVBUF, M_NOWAIT | M_ZERO); 1368203319Sweongyo if (buf == NULL) 1369203319Sweongyo return (ENOMEM); 1370203319Sweongyo siba_sprom_read(siba, buf, SIBA_SPROMSIZE_R4); 1371203319Sweongyo error = sprom_check_crc(buf, siba->siba_spromsize); 1372203319Sweongyo if (error) 1373203319Sweongyo device_printf(siba->siba_dev, "warn: bad SPROM CRC\n"); 1374203319Sweongyo } 1375203319Sweongyo 1376203319Sweongyo bzero(sprom, sizeof(*sprom)); 1377203319Sweongyo 1378203319Sweongyo sprom->rev = buf[siba->siba_spromsize - 1] & 0x00FF; 1379203319Sweongyo DPRINTF(siba, SIBA_DEBUG_SPROM, "SPROM rev %d\n", 1380203319Sweongyo sprom->rev); 1381203319Sweongyo memset(sprom->mac_eth, 0xff, 6); 1382203319Sweongyo memset(sprom->mac_80211a, 0xff, 6); 1383203319Sweongyo if ((siba->siba_chipid & 0xff00) == 0x4400) { 1384203319Sweongyo sprom->rev = 1; 1385203319Sweongyo siba_sprom_r123(sprom, buf); 1386203319Sweongyo } else if (siba->siba_chipid == 0x4321) { 1387203319Sweongyo sprom->rev = 4; 1388203319Sweongyo siba_sprom_r45(sprom, buf); 1389203319Sweongyo } else { 1390203319Sweongyo switch (sprom->rev) { 1391203319Sweongyo case 1: 1392203319Sweongyo case 2: 1393203319Sweongyo case 3: 1394203319Sweongyo siba_sprom_r123(sprom, buf); 1395203319Sweongyo break; 1396203319Sweongyo case 4: 1397203319Sweongyo case 5: 1398203319Sweongyo siba_sprom_r45(sprom, buf); 1399203319Sweongyo break; 1400203319Sweongyo case 8: 1401203319Sweongyo siba_sprom_r8(sprom, buf); 1402203319Sweongyo break; 1403203319Sweongyo default: 1404203319Sweongyo device_printf(siba->siba_dev, 1405203319Sweongyo "unknown SPROM revision %d.\n", sprom->rev); 1406203319Sweongyo siba_sprom_r123(sprom, buf); 1407203319Sweongyo } 1408203319Sweongyo } 1409203319Sweongyo 1410203319Sweongyo if (sprom->bf_lo == 0xffff) 1411203319Sweongyo sprom->bf_lo = 0; 1412203319Sweongyo if (sprom->bf_hi == 0xffff) 1413203319Sweongyo sprom->bf_hi = 0; 1414203319Sweongyo 1415203319Sweongyo free(buf, M_DEVBUF); 1416203319Sweongyo return (error); 1417203319Sweongyo} 1418203319Sweongyo 1419203319Sweongyostatic int 1420203319Sweongyosiba_sprom_read(struct siba_softc *siba, uint16_t *sprom, uint16_t len) 1421203319Sweongyo{ 1422203319Sweongyo int i; 1423203319Sweongyo 1424203319Sweongyo for (i = 0; i < len; i++) 1425203319Sweongyo sprom[i] = SIBA_READ_2(siba, SIBA_SPROM_BASE + (i * 2)); 1426203319Sweongyo 1427203319Sweongyo siba->siba_spromsize = len; 1428203319Sweongyo return (0); 1429203319Sweongyo} 1430203319Sweongyo 1431203319Sweongyostatic int 1432203319Sweongyosprom_check_crc(const uint16_t *sprom, size_t size) 1433203319Sweongyo{ 1434203319Sweongyo int word; 1435203319Sweongyo uint8_t crc0, crc1 = 0xff; 1436203319Sweongyo 1437203319Sweongyo crc0 = (sprom[size - 1] & SIBA_SPROM_REV_CRC) >> 8; 1438203319Sweongyo for (word = 0; word < size - 1; word++) { 1439203319Sweongyo crc1 = siba_crc8(crc1, sprom[word] & 0x00ff); 1440203319Sweongyo crc1 = siba_crc8(crc1, (sprom[word] & 0xff00) >> 8); 1441203319Sweongyo } 1442203319Sweongyo crc1 = siba_crc8(crc1, sprom[size - 1] & 0x00ff); 1443203319Sweongyo crc1 ^= 0xff; 1444203319Sweongyo 1445203319Sweongyo return ((crc0 != crc1) ? EPROTO : 0); 1446203319Sweongyo} 1447203319Sweongyo 1448203319Sweongyostatic uint8_t 1449203319Sweongyosiba_crc8(uint8_t crc, uint8_t data) 1450203319Sweongyo{ 1451203319Sweongyo static const uint8_t ct[] = { 1452203319Sweongyo 0x00, 0xf7, 0xb9, 0x4e, 0x25, 0xd2, 0x9c, 0x6b, 1453203319Sweongyo 0x4a, 0xbd, 0xf3, 0x04, 0x6f, 0x98, 0xd6, 0x21, 1454203319Sweongyo 0x94, 0x63, 0x2d, 0xda, 0xb1, 0x46, 0x08, 0xff, 1455203319Sweongyo 0xde, 0x29, 0x67, 0x90, 0xfb, 0x0c, 0x42, 0xb5, 1456203319Sweongyo 0x7f, 0x88, 0xc6, 0x31, 0x5a, 0xad, 0xe3, 0x14, 1457203319Sweongyo 0x35, 0xc2, 0x8c, 0x7b, 0x10, 0xe7, 0xa9, 0x5e, 1458203319Sweongyo 0xeb, 0x1c, 0x52, 0xa5, 0xce, 0x39, 0x77, 0x80, 1459203319Sweongyo 0xa1, 0x56, 0x18, 0xef, 0x84, 0x73, 0x3d, 0xca, 1460203319Sweongyo 0xfe, 0x09, 0x47, 0xb0, 0xdb, 0x2c, 0x62, 0x95, 1461203319Sweongyo 0xb4, 0x43, 0x0d, 0xfa, 0x91, 0x66, 0x28, 0xdf, 1462203319Sweongyo 0x6a, 0x9d, 0xd3, 0x24, 0x4f, 0xb8, 0xf6, 0x01, 1463203319Sweongyo 0x20, 0xd7, 0x99, 0x6e, 0x05, 0xf2, 0xbc, 0x4b, 1464203319Sweongyo 0x81, 0x76, 0x38, 0xcf, 0xa4, 0x53, 0x1d, 0xea, 1465203319Sweongyo 0xcb, 0x3c, 0x72, 0x85, 0xee, 0x19, 0x57, 0xa0, 1466203319Sweongyo 0x15, 0xe2, 0xac, 0x5b, 0x30, 0xc7, 0x89, 0x7e, 1467203319Sweongyo 0x5f, 0xa8, 0xe6, 0x11, 0x7a, 0x8d, 0xc3, 0x34, 1468203319Sweongyo 0xab, 0x5c, 0x12, 0xe5, 0x8e, 0x79, 0x37, 0xc0, 1469203319Sweongyo 0xe1, 0x16, 0x58, 0xaf, 0xc4, 0x33, 0x7d, 0x8a, 1470203319Sweongyo 0x3f, 0xc8, 0x86, 0x71, 0x1a, 0xed, 0xa3, 0x54, 1471203319Sweongyo 0x75, 0x82, 0xcc, 0x3b, 0x50, 0xa7, 0xe9, 0x1e, 1472203319Sweongyo 0xd4, 0x23, 0x6d, 0x9a, 0xf1, 0x06, 0x48, 0xbf, 1473203319Sweongyo 0x9e, 0x69, 0x27, 0xd0, 0xbb, 0x4c, 0x02, 0xf5, 1474203319Sweongyo 0x40, 0xb7, 0xf9, 0x0e, 0x65, 0x92, 0xdc, 0x2b, 1475203319Sweongyo 0x0a, 0xfd, 0xb3, 0x44, 0x2f, 0xd8, 0x96, 0x61, 1476203319Sweongyo 0x55, 0xa2, 0xec, 0x1b, 0x70, 0x87, 0xc9, 0x3e, 1477203319Sweongyo 0x1f, 0xe8, 0xa6, 0x51, 0x3a, 0xcd, 0x83, 0x74, 1478203319Sweongyo 0xc1, 0x36, 0x78, 0x8f, 0xe4, 0x13, 0x5d, 0xaa, 1479203319Sweongyo 0x8b, 0x7c, 0x32, 0xc5, 0xae, 0x59, 0x17, 0xe0, 1480203319Sweongyo 0x2a, 0xdd, 0x93, 0x64, 0x0f, 0xf8, 0xb6, 0x41, 1481203319Sweongyo 0x60, 0x97, 0xd9, 0x2e, 0x45, 0xb2, 0xfc, 0x0b, 1482203319Sweongyo 0xbe, 0x49, 0x07, 0xf0, 0x9b, 0x6c, 0x22, 0xd5, 1483203319Sweongyo 0xf4, 0x03, 0x4d, 0xba, 0xd1, 0x26, 0x68, 0x9f, 1484203319Sweongyo }; 1485203319Sweongyo return (ct[crc ^ data]); 1486203319Sweongyo} 1487203319Sweongyo 1488203319Sweongyo#define SIBA_LOWEST_SET_BIT(__mask) ((((__mask) - 1) & (__mask)) ^ (__mask)) 1489203319Sweongyo#define SIBA_OFFSET(offset) \ 1490203319Sweongyo (((offset) - SIBA_SPROM_BASE) / sizeof(uint16_t)) 1491203319Sweongyo#define SIBA_SHIFTOUT_SUB(__x, __mask) \ 1492203319Sweongyo (((__x) & (__mask)) / SIBA_LOWEST_SET_BIT(__mask)) 1493203319Sweongyo#define SIBA_SHIFTOUT(_var, _offset, _mask) \ 1494203319Sweongyo out->_var = SIBA_SHIFTOUT_SUB(in[SIBA_OFFSET(_offset)], (_mask)) 1495203944Sweongyo#define SIBA_SHIFTOUT_4(_var, _offset, _mask, _shift) \ 1496203944Sweongyo out->_var = ((((uint32_t)in[SIBA_OFFSET((_offset)+2)] << 16 | \ 1497203944Sweongyo in[SIBA_OFFSET(_offset)]) & (_mask)) >> (_shift)) 1498203319Sweongyo 1499203319Sweongyostatic void 1500203319Sweongyosiba_sprom_r123(struct siba_sprom *out, const uint16_t *in) 1501203319Sweongyo{ 1502203319Sweongyo int i; 1503203319Sweongyo uint16_t v; 1504203319Sweongyo int8_t gain; 1505203319Sweongyo uint16_t loc[3]; 1506203319Sweongyo 1507203319Sweongyo if (out->rev == 3) 1508203319Sweongyo loc[0] = SIBA_SPROM3_MAC_80211BG; 1509203319Sweongyo else { 1510203319Sweongyo loc[0] = SIBA_SPROM1_MAC_80211BG; 1511203319Sweongyo loc[1] = SIBA_SPROM1_MAC_ETH; 1512203319Sweongyo loc[2] = SIBA_SPROM1_MAC_80211A; 1513203319Sweongyo } 1514203319Sweongyo for (i = 0; i < 3; i++) { 1515203319Sweongyo v = in[SIBA_OFFSET(loc[0]) + i]; 1516203319Sweongyo *(((uint16_t *)out->mac_80211bg) + i) = htobe16(v); 1517203319Sweongyo } 1518203319Sweongyo if (out->rev < 3) { 1519203319Sweongyo for (i = 0; i < 3; i++) { 1520203319Sweongyo v = in[SIBA_OFFSET(loc[1]) + i]; 1521203319Sweongyo *(((uint16_t *)out->mac_eth) + i) = htobe16(v); 1522203319Sweongyo } 1523203319Sweongyo for (i = 0; i < 3; i++) { 1524203319Sweongyo v = in[SIBA_OFFSET(loc[2]) + i]; 1525203319Sweongyo *(((uint16_t *)out->mac_80211a) + i) = htobe16(v); 1526203319Sweongyo } 1527203319Sweongyo } 1528203319Sweongyo SIBA_SHIFTOUT(mii_eth0, SIBA_SPROM1_ETHPHY, 1529203319Sweongyo SIBA_SPROM1_ETHPHY_MII_ETH0); 1530203319Sweongyo SIBA_SHIFTOUT(mii_eth1, SIBA_SPROM1_ETHPHY, 1531203319Sweongyo SIBA_SPROM1_ETHPHY_MII_ETH1); 1532203319Sweongyo SIBA_SHIFTOUT(mdio_eth0, SIBA_SPROM1_ETHPHY, 1533203319Sweongyo SIBA_SPROM1_ETHPHY_MDIO_ETH0); 1534203319Sweongyo SIBA_SHIFTOUT(mdio_eth1, SIBA_SPROM1_ETHPHY, 1535203319Sweongyo SIBA_SPROM1_ETHPHY_MDIO_ETH1); 1536203319Sweongyo SIBA_SHIFTOUT(brev, SIBA_SPROM1_BOARDINFO, SIBA_SPROM1_BOARDINFO_BREV); 1537203319Sweongyo SIBA_SHIFTOUT(ccode, SIBA_SPROM1_BOARDINFO, 1538203319Sweongyo SIBA_SPROM1_BOARDINFO_CCODE); 1539203319Sweongyo SIBA_SHIFTOUT(ant_a, SIBA_SPROM1_BOARDINFO, SIBA_SPROM1_BOARDINFO_ANTA); 1540203319Sweongyo SIBA_SHIFTOUT(ant_bg, SIBA_SPROM1_BOARDINFO, 1541203319Sweongyo SIBA_SPROM1_BOARDINFO_ANTBG); 1542203319Sweongyo SIBA_SHIFTOUT(pa0b0, SIBA_SPROM1_PA0B0, 0xffff); 1543203319Sweongyo SIBA_SHIFTOUT(pa0b1, SIBA_SPROM1_PA0B1, 0xffff); 1544203319Sweongyo SIBA_SHIFTOUT(pa0b2, SIBA_SPROM1_PA0B2, 0xffff); 1545203319Sweongyo SIBA_SHIFTOUT(pa1b0, SIBA_SPROM1_PA1B0, 0xffff); 1546203319Sweongyo SIBA_SHIFTOUT(pa1b1, SIBA_SPROM1_PA1B1, 0xffff); 1547203319Sweongyo SIBA_SHIFTOUT(pa1b2, SIBA_SPROM1_PA1B2, 0xffff); 1548203319Sweongyo SIBA_SHIFTOUT(gpio0, SIBA_SPROM1_GPIOA, SIBA_SPROM1_GPIOA_P0); 1549203319Sweongyo SIBA_SHIFTOUT(gpio1, SIBA_SPROM1_GPIOA, SIBA_SPROM1_GPIOA_P1); 1550203319Sweongyo SIBA_SHIFTOUT(gpio2, SIBA_SPROM1_GPIOB, SIBA_SPROM1_GPIOB_P2); 1551203319Sweongyo SIBA_SHIFTOUT(gpio3, SIBA_SPROM1_GPIOB, SIBA_SPROM1_GPIOB_P3); 1552203944Sweongyo 1553203319Sweongyo SIBA_SHIFTOUT(maxpwr_a, SIBA_SPROM1_MAXPWR, SIBA_SPROM1_MAXPWR_A); 1554203319Sweongyo SIBA_SHIFTOUT(maxpwr_bg, SIBA_SPROM1_MAXPWR, SIBA_SPROM1_MAXPWR_BG); 1555203319Sweongyo SIBA_SHIFTOUT(tssi_a, SIBA_SPROM1_TSSI, SIBA_SPROM1_TSSI_A); 1556203319Sweongyo SIBA_SHIFTOUT(tssi_bg, SIBA_SPROM1_TSSI, SIBA_SPROM1_TSSI_BG); 1557203319Sweongyo SIBA_SHIFTOUT(bf_lo, SIBA_SPROM1_BFLOW, 0xffff); 1558203319Sweongyo if (out->rev >= 2) 1559203319Sweongyo SIBA_SHIFTOUT(bf_hi, SIBA_SPROM2_BFHIGH, 0xffff); 1560203319Sweongyo 1561203319Sweongyo /* antenna gain */ 1562203319Sweongyo gain = siba_sprom_r123_antgain(out->rev, in, SIBA_SPROM1_AGAIN_BG, 0); 1563203319Sweongyo out->again.ghz24.a0 = out->again.ghz24.a1 = gain; 1564203319Sweongyo out->again.ghz24.a2 = out->again.ghz24.a3 = gain; 1565203319Sweongyo gain = siba_sprom_r123_antgain(out->rev, in, SIBA_SPROM1_AGAIN_A, 8); 1566203319Sweongyo out->again.ghz5.a0 = out->again.ghz5.a1 = gain; 1567203319Sweongyo out->again.ghz5.a2 = out->again.ghz5.a3 = gain; 1568203319Sweongyo} 1569203319Sweongyo 1570203319Sweongyostatic void 1571203319Sweongyosiba_sprom_r45(struct siba_sprom *out, const uint16_t *in) 1572203319Sweongyo{ 1573203319Sweongyo int i; 1574203319Sweongyo uint16_t v; 1575203319Sweongyo uint16_t mac_80211bg_offset; 1576203319Sweongyo 1577203319Sweongyo if (out->rev == 4) 1578203319Sweongyo mac_80211bg_offset = SIBA_SPROM4_MAC_80211BG; 1579203319Sweongyo else 1580203319Sweongyo mac_80211bg_offset = SIBA_SPROM5_MAC_80211BG; 1581203319Sweongyo for (i = 0; i < 3; i++) { 1582203319Sweongyo v = in[SIBA_OFFSET(mac_80211bg_offset) + i]; 1583203319Sweongyo *(((uint16_t *)out->mac_80211bg) + i) = htobe16(v); 1584203319Sweongyo } 1585203319Sweongyo SIBA_SHIFTOUT(mii_eth0, SIBA_SPROM4_ETHPHY, SIBA_SPROM4_ETHPHY_ET0A); 1586203319Sweongyo SIBA_SHIFTOUT(mii_eth1, SIBA_SPROM4_ETHPHY, SIBA_SPROM4_ETHPHY_ET1A); 1587203319Sweongyo if (out->rev == 4) { 1588203319Sweongyo SIBA_SHIFTOUT(ccode, SIBA_SPROM4_CCODE, 0xffff); 1589203319Sweongyo SIBA_SHIFTOUT(bf_lo, SIBA_SPROM4_BFLOW, 0xffff); 1590203319Sweongyo SIBA_SHIFTOUT(bf_hi, SIBA_SPROM4_BFHIGH, 0xffff); 1591203319Sweongyo } else { 1592203319Sweongyo SIBA_SHIFTOUT(ccode, SIBA_SPROM5_CCODE, 0xffff); 1593203319Sweongyo SIBA_SHIFTOUT(bf_lo, SIBA_SPROM5_BFLOW, 0xffff); 1594203319Sweongyo SIBA_SHIFTOUT(bf_hi, SIBA_SPROM5_BFHIGH, 0xffff); 1595203319Sweongyo } 1596203319Sweongyo SIBA_SHIFTOUT(ant_a, SIBA_SPROM4_ANTAVAIL, SIBA_SPROM4_ANTAVAIL_A); 1597203319Sweongyo SIBA_SHIFTOUT(ant_bg, SIBA_SPROM4_ANTAVAIL, SIBA_SPROM4_ANTAVAIL_BG); 1598203319Sweongyo SIBA_SHIFTOUT(maxpwr_bg, SIBA_SPROM4_MAXP_BG, SIBA_SPROM4_MAXP_BG_MASK); 1599203319Sweongyo SIBA_SHIFTOUT(tssi_bg, SIBA_SPROM4_MAXP_BG, SIBA_SPROM4_TSSI_BG); 1600203319Sweongyo SIBA_SHIFTOUT(maxpwr_a, SIBA_SPROM4_MAXP_A, SIBA_SPROM4_MAXP_A_MASK); 1601203319Sweongyo SIBA_SHIFTOUT(tssi_a, SIBA_SPROM4_MAXP_A, SIBA_SPROM4_TSSI_A); 1602203319Sweongyo if (out->rev == 4) { 1603203319Sweongyo SIBA_SHIFTOUT(gpio0, SIBA_SPROM4_GPIOA, SIBA_SPROM4_GPIOA_P0); 1604203319Sweongyo SIBA_SHIFTOUT(gpio1, SIBA_SPROM4_GPIOA, SIBA_SPROM4_GPIOA_P1); 1605203319Sweongyo SIBA_SHIFTOUT(gpio2, SIBA_SPROM4_GPIOB, SIBA_SPROM4_GPIOB_P2); 1606203319Sweongyo SIBA_SHIFTOUT(gpio3, SIBA_SPROM4_GPIOB, SIBA_SPROM4_GPIOB_P3); 1607203319Sweongyo } else { 1608203319Sweongyo SIBA_SHIFTOUT(gpio0, SIBA_SPROM5_GPIOA, SIBA_SPROM5_GPIOA_P0); 1609203319Sweongyo SIBA_SHIFTOUT(gpio1, SIBA_SPROM5_GPIOA, SIBA_SPROM5_GPIOA_P1); 1610203319Sweongyo SIBA_SHIFTOUT(gpio2, SIBA_SPROM5_GPIOB, SIBA_SPROM5_GPIOB_P2); 1611203319Sweongyo SIBA_SHIFTOUT(gpio3, SIBA_SPROM5_GPIOB, SIBA_SPROM5_GPIOB_P3); 1612203319Sweongyo } 1613203319Sweongyo 1614203319Sweongyo /* antenna gain */ 1615203319Sweongyo SIBA_SHIFTOUT(again.ghz24.a0, SIBA_SPROM4_AGAIN01, SIBA_SPROM4_AGAIN0); 1616203319Sweongyo SIBA_SHIFTOUT(again.ghz24.a1, SIBA_SPROM4_AGAIN01, SIBA_SPROM4_AGAIN1); 1617203319Sweongyo SIBA_SHIFTOUT(again.ghz24.a2, SIBA_SPROM4_AGAIN23, SIBA_SPROM4_AGAIN2); 1618203319Sweongyo SIBA_SHIFTOUT(again.ghz24.a3, SIBA_SPROM4_AGAIN23, SIBA_SPROM4_AGAIN3); 1619203319Sweongyo bcopy(&out->again.ghz24, &out->again.ghz5, sizeof(out->again.ghz5)); 1620203319Sweongyo} 1621203319Sweongyo 1622203319Sweongyostatic void 1623203319Sweongyosiba_sprom_r8(struct siba_sprom *out, const uint16_t *in) 1624203319Sweongyo{ 1625203319Sweongyo int i; 1626203319Sweongyo uint16_t v; 1627203319Sweongyo 1628203319Sweongyo for (i = 0; i < 3; i++) { 1629203944Sweongyo v = in[SIBA_OFFSET(SIBA_SPROM8_MAC_80211BG) + i]; 1630203319Sweongyo *(((uint16_t *)out->mac_80211bg) + i) = htobe16(v); 1631203319Sweongyo } 1632203319Sweongyo SIBA_SHIFTOUT(ccode, SIBA_SPROM8_CCODE, 0xffff); 1633203319Sweongyo SIBA_SHIFTOUT(bf_lo, SIBA_SPROM8_BFLOW, 0xffff); 1634203319Sweongyo SIBA_SHIFTOUT(bf_hi, SIBA_SPROM8_BFHIGH, 0xffff); 1635203944Sweongyo SIBA_SHIFTOUT(bf2_lo, SIBA_SPROM8_BFL2LO, 0xffff); 1636203944Sweongyo SIBA_SHIFTOUT(bf2_hi, SIBA_SPROM8_BFL2HI, 0xffff); 1637203319Sweongyo SIBA_SHIFTOUT(ant_a, SIBA_SPROM8_ANTAVAIL, SIBA_SPROM8_ANTAVAIL_A); 1638203319Sweongyo SIBA_SHIFTOUT(ant_bg, SIBA_SPROM8_ANTAVAIL, SIBA_SPROM8_ANTAVAIL_BG); 1639203319Sweongyo SIBA_SHIFTOUT(maxpwr_bg, SIBA_SPROM8_MAXP_BG, SIBA_SPROM8_MAXP_BG_MASK); 1640203319Sweongyo SIBA_SHIFTOUT(tssi_bg, SIBA_SPROM8_MAXP_BG, SIBA_SPROM8_TSSI_BG); 1641203319Sweongyo SIBA_SHIFTOUT(maxpwr_a, SIBA_SPROM8_MAXP_A, SIBA_SPROM8_MAXP_A_MASK); 1642203319Sweongyo SIBA_SHIFTOUT(tssi_a, SIBA_SPROM8_MAXP_A, SIBA_SPROM8_TSSI_A); 1643203944Sweongyo SIBA_SHIFTOUT(maxpwr_ah, SIBA_SPROM8_MAXP_AHL, 1644203944Sweongyo SIBA_SPROM8_MAXP_AH_MASK); 1645203944Sweongyo SIBA_SHIFTOUT(maxpwr_al, SIBA_SPROM8_MAXP_AHL, 1646203944Sweongyo SIBA_SPROM8_MAXP_AL_MASK); 1647203319Sweongyo SIBA_SHIFTOUT(gpio0, SIBA_SPROM8_GPIOA, SIBA_SPROM8_GPIOA_P0); 1648203319Sweongyo SIBA_SHIFTOUT(gpio1, SIBA_SPROM8_GPIOA, SIBA_SPROM8_GPIOA_P1); 1649203319Sweongyo SIBA_SHIFTOUT(gpio2, SIBA_SPROM8_GPIOB, SIBA_SPROM8_GPIOB_P2); 1650203319Sweongyo SIBA_SHIFTOUT(gpio3, SIBA_SPROM8_GPIOB, SIBA_SPROM8_GPIOB_P3); 1651203944Sweongyo SIBA_SHIFTOUT(tri2g, SIBA_SPROM8_TRI25G, SIBA_SPROM8_TRI2G); 1652203944Sweongyo SIBA_SHIFTOUT(tri5g, SIBA_SPROM8_TRI25G, SIBA_SPROM8_TRI5G); 1653203944Sweongyo SIBA_SHIFTOUT(tri5gl, SIBA_SPROM8_TRI5GHL, SIBA_SPROM8_TRI5GL); 1654203944Sweongyo SIBA_SHIFTOUT(tri5gh, SIBA_SPROM8_TRI5GHL, SIBA_SPROM8_TRI5GH); 1655203944Sweongyo SIBA_SHIFTOUT(rxpo2g, SIBA_SPROM8_RXPO, SIBA_SPROM8_RXPO2G); 1656203944Sweongyo SIBA_SHIFTOUT(rxpo5g, SIBA_SPROM8_RXPO, SIBA_SPROM8_RXPO5G); 1657203944Sweongyo SIBA_SHIFTOUT(rssismf2g, SIBA_SPROM8_RSSIPARM2G, SIBA_SPROM8_RSSISMF2G); 1658203944Sweongyo SIBA_SHIFTOUT(rssismc2g, SIBA_SPROM8_RSSIPARM2G, SIBA_SPROM8_RSSISMC2G); 1659203944Sweongyo SIBA_SHIFTOUT(rssisav2g, SIBA_SPROM8_RSSIPARM2G, SIBA_SPROM8_RSSISAV2G); 1660203944Sweongyo SIBA_SHIFTOUT(bxa2g, SIBA_SPROM8_RSSIPARM2G, SIBA_SPROM8_BXA2G); 1661203944Sweongyo SIBA_SHIFTOUT(rssismf5g, SIBA_SPROM8_RSSIPARM5G, SIBA_SPROM8_RSSISMF5G); 1662203944Sweongyo SIBA_SHIFTOUT(rssismc5g, SIBA_SPROM8_RSSIPARM5G, SIBA_SPROM8_RSSISMC5G); 1663203944Sweongyo SIBA_SHIFTOUT(rssisav5g, SIBA_SPROM8_RSSIPARM5G, SIBA_SPROM8_RSSISAV5G); 1664203944Sweongyo SIBA_SHIFTOUT(bxa5g, SIBA_SPROM8_RSSIPARM5G, SIBA_SPROM8_BXA5G); 1665203319Sweongyo 1666203944Sweongyo SIBA_SHIFTOUT(pa0b0, SIBA_SPROM8_PA0B0, 0xffff); 1667203944Sweongyo SIBA_SHIFTOUT(pa0b1, SIBA_SPROM8_PA0B1, 0xffff); 1668203944Sweongyo SIBA_SHIFTOUT(pa0b2, SIBA_SPROM8_PA0B2, 0xffff); 1669203944Sweongyo SIBA_SHIFTOUT(pa1b0, SIBA_SPROM8_PA1B0, 0xffff); 1670203944Sweongyo SIBA_SHIFTOUT(pa1b1, SIBA_SPROM8_PA1B1, 0xffff); 1671203944Sweongyo SIBA_SHIFTOUT(pa1b2, SIBA_SPROM8_PA1B2, 0xffff); 1672203944Sweongyo SIBA_SHIFTOUT(pa1lob0, SIBA_SPROM8_PA1LOB0, 0xffff); 1673203944Sweongyo SIBA_SHIFTOUT(pa1lob1, SIBA_SPROM8_PA1LOB1, 0xffff); 1674203944Sweongyo SIBA_SHIFTOUT(pa1lob2, SIBA_SPROM8_PA1LOB2, 0xffff); 1675203944Sweongyo SIBA_SHIFTOUT(pa1hib0, SIBA_SPROM8_PA1HIB0, 0xffff); 1676203944Sweongyo SIBA_SHIFTOUT(pa1hib1, SIBA_SPROM8_PA1HIB1, 0xffff); 1677203944Sweongyo SIBA_SHIFTOUT(pa1hib2, SIBA_SPROM8_PA1HIB2, 0xffff); 1678203944Sweongyo SIBA_SHIFTOUT(cck2gpo, SIBA_SPROM8_CCK2GPO, 0xffff); 1679203944Sweongyo 1680203944Sweongyo SIBA_SHIFTOUT_4(ofdm2gpo, SIBA_SPROM8_OFDM2GPO, 0xffffffff, 0); 1681203944Sweongyo SIBA_SHIFTOUT_4(ofdm5glpo, SIBA_SPROM8_OFDM5GLPO, 0xffffffff, 0); 1682203944Sweongyo SIBA_SHIFTOUT_4(ofdm5gpo, SIBA_SPROM8_OFDM5GPO, 0xffffffff, 0); 1683203944Sweongyo SIBA_SHIFTOUT_4(ofdm5ghpo, SIBA_SPROM8_OFDM5GHPO, 0xffffffff, 0); 1684203944Sweongyo 1685203319Sweongyo /* antenna gain */ 1686203319Sweongyo SIBA_SHIFTOUT(again.ghz24.a0, SIBA_SPROM8_AGAIN01, SIBA_SPROM8_AGAIN0); 1687203319Sweongyo SIBA_SHIFTOUT(again.ghz24.a1, SIBA_SPROM8_AGAIN01, SIBA_SPROM8_AGAIN1); 1688203319Sweongyo SIBA_SHIFTOUT(again.ghz24.a2, SIBA_SPROM8_AGAIN23, SIBA_SPROM8_AGAIN2); 1689203319Sweongyo SIBA_SHIFTOUT(again.ghz24.a3, SIBA_SPROM8_AGAIN23, SIBA_SPROM8_AGAIN3); 1690203319Sweongyo bcopy(&out->again.ghz24, &out->again.ghz5, sizeof(out->again.ghz5)); 1691203319Sweongyo} 1692203319Sweongyo 1693203319Sweongyostatic int8_t 1694203319Sweongyosiba_sprom_r123_antgain(uint8_t sprom_revision, const uint16_t *in, 1695203319Sweongyo uint16_t mask, uint16_t shift) 1696203319Sweongyo{ 1697203319Sweongyo uint16_t v; 1698203319Sweongyo uint8_t gain; 1699203319Sweongyo 1700203319Sweongyo v = in[SIBA_OFFSET(SIBA_SPROM1_AGAIN)]; 1701203319Sweongyo gain = (v & mask) >> shift; 1702203319Sweongyo gain = (gain == 0xff) ? 2 : (sprom_revision == 1) ? gain << 2 : 1703203319Sweongyo ((gain & 0xc0) >> 6) | ((gain & 0x3f) << 2); 1704203319Sweongyo 1705203319Sweongyo return ((int8_t)gain); 1706203319Sweongyo} 1707203319Sweongyo 1708203319Sweongyo#undef SIBA_LOWEST_SET_BIT 1709203319Sweongyo#undef SIBA_OFFSET 1710203319Sweongyo#undef SIBA_SHIFTOUT_SUB 1711203319Sweongyo#undef SIBA_SHIFTOUT 1712203319Sweongyo 1713203319Sweongyoint 1714204922Sweongyosiba_powerdown(device_t dev) 1715203319Sweongyo{ 1716204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(dev); 1717204922Sweongyo struct siba_softc *siba = sd->sd_bus; 1718204922Sweongyo 1719204922Sweongyo return (siba_powerdown_sub(siba)); 1720204922Sweongyo} 1721204922Sweongyo 1722204922Sweongyostatic int 1723204922Sweongyosiba_powerdown_sub(struct siba_softc *siba) 1724204922Sweongyo{ 1725203319Sweongyo struct siba_cc *scc; 1726203319Sweongyo 1727203319Sweongyo if (siba->siba_type == SIBA_TYPE_SSB) 1728203319Sweongyo return (0); 1729203319Sweongyo 1730203319Sweongyo scc = &siba->siba_cc; 1731203319Sweongyo if (!scc->scc_dev || scc->scc_dev->sd_id.sd_rev < 5) 1732203319Sweongyo return (0); 1733203319Sweongyo siba_cc_clock(scc, SIBA_CLOCK_SLOW); 1734203319Sweongyo siba_pci_gpio(siba, SIBA_GPIO_CRYSTAL | SIBA_GPIO_PLL, 0); 1735203319Sweongyo return (0); 1736203319Sweongyo} 1737203319Sweongyo 1738203319Sweongyostatic void 1739203319Sweongyosiba_pcicore_init(struct siba_pci *spc) 1740203319Sweongyo{ 1741203319Sweongyo struct siba_dev_softc *sd = spc->spc_dev; 1742203319Sweongyo 1743203319Sweongyo if (sd == NULL) 1744203319Sweongyo return; 1745203319Sweongyo 1746204922Sweongyo if (!siba_dev_isup_sub(sd)) 1747204922Sweongyo siba_dev_up_sub(sd, 0); 1748203319Sweongyo 1749203319Sweongyo KASSERT(spc->spc_hostmode == 0, 1750203319Sweongyo ("%s:%d: hostmode", __func__, __LINE__)); 1751203319Sweongyo /* disable PCI interrupt */ 1752204922Sweongyo siba_write_4_sub(spc->spc_dev, SIBA_INTR_MASK, 0); 1753203319Sweongyo} 1754203319Sweongyo 1755203319Sweongyoint 1756204922Sweongyosiba_dev_isup(device_t dev) 1757203319Sweongyo{ 1758204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(dev); 1759204922Sweongyo 1760204922Sweongyo return (siba_dev_isup_sub(sd)); 1761204922Sweongyo} 1762204922Sweongyo 1763204922Sweongyostatic int 1764204922Sweongyosiba_dev_isup_sub(struct siba_dev_softc *sd) 1765204922Sweongyo{ 1766203319Sweongyo uint32_t reject, val; 1767203319Sweongyo 1768203319Sweongyo reject = siba_tmslow_reject_bitmask(sd); 1769204922Sweongyo val = siba_read_4_sub(sd, SIBA_TGSLOW); 1770203319Sweongyo val &= SIBA_TGSLOW_CLOCK | SIBA_TGSLOW_RESET | reject; 1771203319Sweongyo 1772203319Sweongyo return (val == SIBA_TGSLOW_CLOCK); 1773203319Sweongyo} 1774203319Sweongyo 1775203319Sweongyovoid 1776204922Sweongyosiba_dev_up(device_t dev, uint32_t flags) 1777203319Sweongyo{ 1778204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(dev); 1779204922Sweongyo 1780204922Sweongyo siba_dev_up_sub(sd, flags); 1781204922Sweongyo} 1782204922Sweongyo 1783204922Sweongyostatic void 1784204922Sweongyosiba_dev_up_sub(struct siba_dev_softc *sd, uint32_t flags) 1785204922Sweongyo{ 1786203319Sweongyo uint32_t val; 1787203319Sweongyo 1788204922Sweongyo siba_dev_down_sub(sd, flags); 1789204922Sweongyo siba_write_4_sub(sd, SIBA_TGSLOW, 1790204922Sweongyo SIBA_TGSLOW_RESET | SIBA_TGSLOW_CLOCK | SIBA_TGSLOW_FGC | flags); 1791204922Sweongyo siba_read_4_sub(sd, SIBA_TGSLOW); 1792203319Sweongyo DELAY(1); 1793203319Sweongyo 1794204922Sweongyo if (siba_read_4_sub(sd, SIBA_TGSHIGH) & SIBA_TGSHIGH_SERR) 1795204922Sweongyo siba_write_4_sub(sd, SIBA_TGSHIGH, 0); 1796203319Sweongyo 1797204922Sweongyo val = siba_read_4_sub(sd, SIBA_IAS); 1798203319Sweongyo if (val & (SIBA_IAS_INBAND_ERR | SIBA_IAS_TIMEOUT)) { 1799203319Sweongyo val &= ~(SIBA_IAS_INBAND_ERR | SIBA_IAS_TIMEOUT); 1800204922Sweongyo siba_write_4_sub(sd, SIBA_IAS, val); 1801203319Sweongyo } 1802203319Sweongyo 1803204922Sweongyo siba_write_4_sub(sd, SIBA_TGSLOW, 1804203319Sweongyo SIBA_TGSLOW_CLOCK | SIBA_TGSLOW_FGC | flags); 1805204922Sweongyo siba_read_4_sub(sd, SIBA_TGSLOW); 1806203319Sweongyo DELAY(1); 1807203319Sweongyo 1808204922Sweongyo siba_write_4_sub(sd, SIBA_TGSLOW, SIBA_TGSLOW_CLOCK | flags); 1809204922Sweongyo siba_read_4_sub(sd, SIBA_TGSLOW); 1810203319Sweongyo DELAY(1); 1811203319Sweongyo} 1812203319Sweongyo 1813203319Sweongyostatic uint32_t 1814203319Sweongyosiba_tmslow_reject_bitmask(struct siba_dev_softc *sd) 1815203319Sweongyo{ 1816204922Sweongyo uint32_t rev = siba_read_4_sub(sd, SIBA_IDLOW) & SIBA_IDLOW_SSBREV; 1817203319Sweongyo 1818203319Sweongyo switch (rev) { 1819203319Sweongyo case SIBA_IDLOW_SSBREV_22: 1820203319Sweongyo return (SIBA_TGSLOW_REJECT_22); 1821203319Sweongyo case SIBA_IDLOW_SSBREV_23: 1822203319Sweongyo return (SIBA_TGSLOW_REJECT_23); 1823203319Sweongyo case SIBA_IDLOW_SSBREV_24: 1824203319Sweongyo case SIBA_IDLOW_SSBREV_25: 1825203319Sweongyo case SIBA_IDLOW_SSBREV_26: 1826203319Sweongyo case SIBA_IDLOW_SSBREV_27: 1827203319Sweongyo return (SIBA_TGSLOW_REJECT_23); 1828203319Sweongyo default: 1829203319Sweongyo KASSERT(0 == 1, 1830203319Sweongyo ("%s:%d: unknown backplane rev %#x\n", 1831203319Sweongyo __func__, __LINE__, rev)); 1832203319Sweongyo } 1833203319Sweongyo return (SIBA_TGSLOW_REJECT_22 | SIBA_TGSLOW_REJECT_23); 1834203319Sweongyo} 1835203319Sweongyo 1836203319Sweongyovoid 1837204922Sweongyosiba_dev_down(device_t dev, uint32_t flags) 1838203319Sweongyo{ 1839204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(dev); 1840204922Sweongyo 1841204922Sweongyo siba_dev_down_sub(sd, flags); 1842204922Sweongyo} 1843204922Sweongyo 1844204922Sweongyostatic void 1845204922Sweongyosiba_dev_down_sub(struct siba_dev_softc *sd, uint32_t flags) 1846204922Sweongyo{ 1847203319Sweongyo struct siba_softc *siba = sd->sd_bus; 1848203319Sweongyo uint32_t reject, val; 1849203319Sweongyo int i; 1850203319Sweongyo 1851204922Sweongyo if (siba_read_4_sub(sd, SIBA_TGSLOW) & SIBA_TGSLOW_RESET) 1852203319Sweongyo return; 1853203319Sweongyo 1854203319Sweongyo reject = siba_tmslow_reject_bitmask(sd); 1855204922Sweongyo siba_write_4_sub(sd, SIBA_TGSLOW, reject | SIBA_TGSLOW_CLOCK); 1856203319Sweongyo 1857203319Sweongyo for (i = 0; i < 1000; i++) { 1858204922Sweongyo val = siba_read_4_sub(sd, SIBA_TGSLOW); 1859203319Sweongyo if (val & reject) 1860203319Sweongyo break; 1861203319Sweongyo DELAY(10); 1862203319Sweongyo } 1863203319Sweongyo if ((val & reject) == 0) { 1864203319Sweongyo device_printf(siba->siba_dev, "timeout (bit %#x reg %#x)\n", 1865203319Sweongyo reject, SIBA_TGSLOW); 1866203319Sweongyo } 1867203319Sweongyo for (i = 0; i < 1000; i++) { 1868204922Sweongyo val = siba_read_4_sub(sd, SIBA_TGSHIGH); 1869203319Sweongyo if (!(val & SIBA_TGSHIGH_BUSY)) 1870203319Sweongyo break; 1871203319Sweongyo DELAY(10); 1872203319Sweongyo } 1873203319Sweongyo if ((val & SIBA_TGSHIGH_BUSY) != 0) { 1874203319Sweongyo device_printf(siba->siba_dev, "timeout (bit %#x reg %#x)\n", 1875203319Sweongyo SIBA_TGSHIGH_BUSY, SIBA_TGSHIGH); 1876203319Sweongyo } 1877203319Sweongyo 1878204922Sweongyo siba_write_4_sub(sd, SIBA_TGSLOW, SIBA_TGSLOW_FGC | SIBA_TGSLOW_CLOCK | 1879203319Sweongyo reject | SIBA_TGSLOW_RESET | flags); 1880204922Sweongyo siba_read_4_sub(sd, SIBA_TGSLOW); 1881203319Sweongyo DELAY(1); 1882204922Sweongyo siba_write_4_sub(sd, SIBA_TGSLOW, reject | SIBA_TGSLOW_RESET | flags); 1883204922Sweongyo siba_read_4_sub(sd, SIBA_TGSLOW); 1884203319Sweongyo DELAY(1); 1885203319Sweongyo} 1886203319Sweongyo 1887203319Sweongyostatic void 1888203319Sweongyosiba_pcicore_setup(struct siba_pci *spc, struct siba_dev_softc *sd) 1889203319Sweongyo{ 1890203319Sweongyo struct siba_dev_softc *psd = spc->spc_dev; 1891203319Sweongyo struct siba_softc *siba = psd->sd_bus; 1892203319Sweongyo uint32_t tmp; 1893203319Sweongyo 1894203319Sweongyo if (psd->sd_id.sd_device == SIBA_DEVID_PCI) { 1895203319Sweongyo siba_pcicore_write_4(spc, SIBA_PCICORE_SBTOPCI2, 1896203319Sweongyo siba_pcicore_read_4(spc, SIBA_PCICORE_SBTOPCI2) | 1897203319Sweongyo SIBA_PCICORE_SBTOPCI_PREF | SIBA_PCICORE_SBTOPCI_BURST); 1898203319Sweongyo 1899203319Sweongyo if (psd->sd_id.sd_rev < 5) { 1900204922Sweongyo tmp = siba_read_4_sub(psd, SIBA_IMCFGLO); 1901203319Sweongyo tmp &= ~SIBA_IMCFGLO_SERTO; 1902203319Sweongyo tmp = (tmp | 2) & ~SIBA_IMCFGLO_REQTO; 1903203319Sweongyo tmp |= 3 << 4 /* SIBA_IMCFGLO_REQTO_SHIFT */; 1904204922Sweongyo siba_write_4_sub(psd, SIBA_IMCFGLO, tmp); 1905203319Sweongyo 1906203319Sweongyo /* broadcast value */ 1907203319Sweongyo sd = (siba->siba_cc.scc_dev != NULL) ? 1908203319Sweongyo siba->siba_cc.scc_dev : siba->siba_pci.spc_dev; 1909203319Sweongyo if (sd != NULL) { 1910204922Sweongyo siba_write_4_sub(sd, SIBA_PCICORE_BCAST_ADDR, 1911203319Sweongyo 0xfd8); 1912204922Sweongyo siba_read_4_sub(sd, SIBA_PCICORE_BCAST_ADDR); 1913204922Sweongyo siba_write_4_sub(sd, 1914204922Sweongyo SIBA_PCICORE_BCAST_DATA, 0); 1915204922Sweongyo siba_read_4_sub(sd, SIBA_PCICORE_BCAST_DATA); 1916203319Sweongyo } 1917203319Sweongyo } else if (psd->sd_id.sd_rev >= 11) { 1918203319Sweongyo tmp = siba_pcicore_read_4(spc, SIBA_PCICORE_SBTOPCI2); 1919203319Sweongyo tmp |= SIBA_PCICORE_SBTOPCI_MRM; 1920203319Sweongyo siba_pcicore_write_4(spc, SIBA_PCICORE_SBTOPCI2, tmp); 1921203319Sweongyo } 1922203319Sweongyo } else { 1923203319Sweongyo KASSERT(psd->sd_id.sd_device == SIBA_DEVID_PCIE, ("only PCIE")); 1924203319Sweongyo if ((psd->sd_id.sd_rev == 0) || (psd->sd_id.sd_rev == 1)) 1925203319Sweongyo siba_pcie_write(spc, 0x4, 1926203319Sweongyo siba_pcie_read(spc, 0x4) | 0x8); 1927203319Sweongyo if (psd->sd_id.sd_rev == 0) { 1928203319Sweongyo siba_pcie_mdio_write(spc, 0x1f, 2, 0x8128); /* Timer */ 1929203319Sweongyo siba_pcie_mdio_write(spc, 0x1f, 6, 0x0100); /* CDR */ 1930203319Sweongyo siba_pcie_mdio_write(spc, 0x1f, 7, 0x1466); /* CDR BW */ 1931203319Sweongyo } else if (psd->sd_id.sd_rev == 1) 1932203319Sweongyo siba_pcie_write(spc, 0x100, 1933203319Sweongyo siba_pcie_read(spc, 0x100) | 0x40); 1934203319Sweongyo } 1935203319Sweongyo spc->spc_inited = 1; 1936203319Sweongyo} 1937203319Sweongyo 1938203319Sweongyovoid 1939204922Sweongyosiba_pcicore_intr(device_t dev) 1940203319Sweongyo{ 1941204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(dev); 1942204922Sweongyo struct siba_softc *siba = sd->sd_bus; 1943204922Sweongyo struct siba_pci *spc = &siba->siba_pci; 1944203319Sweongyo struct siba_dev_softc *psd = spc->spc_dev; 1945203319Sweongyo uint32_t tmp; 1946203319Sweongyo 1947204922Sweongyo if (siba->siba_type != SIBA_TYPE_PCI || !psd) 1948203319Sweongyo return; 1949203319Sweongyo 1950204922Sweongyo KASSERT(siba == psd->sd_bus, ("different pointers")); 1951204922Sweongyo 1952203319Sweongyo /* enable interrupts */ 1953203319Sweongyo if (siba->siba_dev != NULL && 1954204922Sweongyo (psd->sd_id.sd_rev >= 6 || 1955204922Sweongyo psd->sd_id.sd_device == SIBA_DEVID_PCIE)) { 1956203319Sweongyo tmp = pci_read_config(siba->siba_dev, SIBA_IRQMASK, 4); 1957203319Sweongyo tmp |= (1 << sd->sd_coreidx) << 8; 1958203319Sweongyo pci_write_config(siba->siba_dev, SIBA_IRQMASK, tmp, 4); 1959203319Sweongyo } else { 1960204922Sweongyo tmp = siba_read_4_sub(sd, SIBA_TPS); 1961203319Sweongyo tmp &= SIBA_TPS_BPFLAG; 1962204922Sweongyo siba_write_4_sub(psd, SIBA_INTR_MASK, 1963204922Sweongyo siba_read_4_sub(psd, SIBA_INTR_MASK) | (1 << tmp)); 1964203319Sweongyo } 1965203319Sweongyo 1966203319Sweongyo /* setup PCIcore */ 1967203319Sweongyo if (spc->spc_inited == 0) 1968203319Sweongyo siba_pcicore_setup(spc, sd); 1969203319Sweongyo} 1970203319Sweongyo 1971203319Sweongyostatic uint32_t 1972203319Sweongyosiba_pcicore_read_4(struct siba_pci *spc, uint16_t offset) 1973203319Sweongyo{ 1974203319Sweongyo 1975204922Sweongyo return (siba_read_4_sub(spc->spc_dev, offset)); 1976203319Sweongyo} 1977203319Sweongyo 1978203319Sweongyostatic void 1979203319Sweongyosiba_pcicore_write_4(struct siba_pci *spc, uint16_t offset, uint32_t value) 1980203319Sweongyo{ 1981203319Sweongyo 1982204922Sweongyo siba_write_4_sub(spc->spc_dev, offset, value); 1983203319Sweongyo} 1984203319Sweongyo 1985203319Sweongyostatic uint32_t 1986203319Sweongyosiba_pcie_read(struct siba_pci *spc, uint32_t address) 1987203319Sweongyo{ 1988203319Sweongyo 1989203319Sweongyo siba_pcicore_write_4(spc, 0x130, address); 1990203319Sweongyo return (siba_pcicore_read_4(spc, 0x134)); 1991203319Sweongyo} 1992203319Sweongyo 1993203319Sweongyostatic void 1994203319Sweongyosiba_pcie_write(struct siba_pci *spc, uint32_t address, uint32_t data) 1995203319Sweongyo{ 1996203319Sweongyo 1997203319Sweongyo siba_pcicore_write_4(spc, 0x130, address); 1998203319Sweongyo siba_pcicore_write_4(spc, 0x134, data); 1999203319Sweongyo} 2000203319Sweongyo 2001203319Sweongyostatic void 2002203319Sweongyosiba_pcie_mdio_write(struct siba_pci *spc, uint8_t device, uint8_t address, 2003203319Sweongyo uint16_t data) 2004203319Sweongyo{ 2005203319Sweongyo int i; 2006203319Sweongyo 2007203319Sweongyo siba_pcicore_write_4(spc, SIBA_PCICORE_MDIO_CTL, 0x80 | 0x2); 2008203319Sweongyo siba_pcicore_write_4(spc, SIBA_PCICORE_MDIO_DATA, 2009203319Sweongyo (1 << 30) | (1 << 28) | 2010203319Sweongyo ((uint32_t)device << 22) | ((uint32_t)address << 18) | 2011203319Sweongyo (1 << 17) | data); 2012203319Sweongyo DELAY(10); 2013203319Sweongyo for (i = 0; i < 10; i++) { 2014203319Sweongyo if (siba_pcicore_read_4(spc, SIBA_PCICORE_MDIO_CTL) & 0x100) 2015203319Sweongyo break; 2016203319Sweongyo DELAY(1000); 2017203319Sweongyo } 2018203319Sweongyo siba_pcicore_write_4(spc, SIBA_PCICORE_MDIO_CTL, 0); 2019203319Sweongyo} 2020203319Sweongyo 2021203319Sweongyouint32_t 2022204922Sweongyosiba_dma_translation(device_t dev) 2023203319Sweongyo{ 2024205003Sthompsa#ifdef INVARIANTS 2025205003Sthompsa struct siba_dev_softc *sd = device_get_ivars(dev); 2026205003Sthompsa struct siba_softc *siba = sd->sd_bus; 2027203319Sweongyo 2028205003Sthompsa KASSERT(siba->siba_type == SIBA_TYPE_PCI, 2029205003Sthompsa ("unsupported bustype %d\n", siba->siba_type)); 2030205003Sthompsa#endif 2031203319Sweongyo return (SIBA_PCI_DMA); 2032203319Sweongyo} 2033203319Sweongyo 2034203319Sweongyovoid 2035204922Sweongyosiba_barrier(device_t dev, int flags) 2036203319Sweongyo{ 2037204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(dev); 2038203319Sweongyo struct siba_softc *siba = sd->sd_bus; 2039203319Sweongyo 2040203319Sweongyo SIBA_BARRIER(siba, flags); 2041203319Sweongyo} 2042203319Sweongyo 2043203319Sweongyostatic void 2044203319Sweongyosiba_cc_suspend(struct siba_cc *scc) 2045203319Sweongyo{ 2046203319Sweongyo 2047203319Sweongyo siba_cc_clock(scc, SIBA_CLOCK_SLOW); 2048203319Sweongyo} 2049203319Sweongyo 2050203319Sweongyostatic void 2051203319Sweongyosiba_cc_resume(struct siba_cc *scc) 2052203319Sweongyo{ 2053203319Sweongyo 2054203319Sweongyo siba_cc_power_init(scc); 2055203319Sweongyo siba_cc_clock(scc, SIBA_CLOCK_FAST); 2056203319Sweongyo} 2057203319Sweongyo 2058203319Sweongyoint 2059203319Sweongyosiba_core_suspend(struct siba_softc *siba) 2060203319Sweongyo{ 2061203319Sweongyo 2062203319Sweongyo siba_cc_suspend(&siba->siba_cc); 2063203319Sweongyo siba_pci_gpio(siba, SIBA_GPIO_CRYSTAL | SIBA_GPIO_PLL, 0); 2064203319Sweongyo return (0); 2065203319Sweongyo} 2066203319Sweongyo 2067203319Sweongyoint 2068203319Sweongyosiba_core_resume(struct siba_softc *siba) 2069203319Sweongyo{ 2070203319Sweongyo 2071203319Sweongyo siba->siba_pci.spc_inited = 0; 2072203319Sweongyo siba->siba_curdev = NULL; 2073203319Sweongyo 2074204922Sweongyo siba_powerup_sub(siba, 0); 2075203319Sweongyo /* XXX setup H/W for PCMCIA??? */ 2076203319Sweongyo siba_cc_resume(&siba->siba_cc); 2077204922Sweongyo siba_powerdown_sub(siba); 2078203319Sweongyo 2079203319Sweongyo return (0); 2080203319Sweongyo} 2081203944Sweongyo 2082203944Sweongyostatic void 2083203944Sweongyosiba_cc_regctl_setmask(struct siba_cc *cc, uint32_t offset, uint32_t mask, 2084203944Sweongyo uint32_t set) 2085203944Sweongyo{ 2086203944Sweongyo 2087203944Sweongyo SIBA_CC_READ32(cc, SIBA_CC_REGCTL_ADDR); 2088203944Sweongyo SIBA_CC_WRITE32(cc, SIBA_CC_REGCTL_ADDR, offset); 2089203944Sweongyo SIBA_CC_READ32(cc, SIBA_CC_REGCTL_ADDR); 2090203944Sweongyo SIBA_CC_WRITE32(cc, SIBA_CC_REGCTL_DATA, 2091203944Sweongyo (SIBA_CC_READ32(cc, SIBA_CC_REGCTL_DATA) & mask) | set); 2092203944Sweongyo SIBA_CC_READ32(cc, SIBA_CC_REGCTL_DATA); 2093203944Sweongyo} 2094203944Sweongyo 2095203944Sweongyovoid 2096204922Sweongyosiba_cc_pmu_set_ldovolt(device_t dev, int id, uint32_t volt) 2097203944Sweongyo{ 2098204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(dev); 2099204922Sweongyo struct siba_softc *siba = sd->sd_bus; 2100204922Sweongyo struct siba_cc *scc = &siba->siba_cc; 2101203944Sweongyo uint32_t *p = NULL, info[5][3] = { 2102203944Sweongyo { 2, 25, 0xf }, 2103203944Sweongyo { 3, 1, 0xf }, 2104203944Sweongyo { 3, 9, 0xf }, 2105203944Sweongyo { 3, 17, 0x3f }, 2106203944Sweongyo { 0, 21, 0x3f } 2107203944Sweongyo }; 2108203944Sweongyo 2109203944Sweongyo if (siba->siba_chipid == 0x4312) { 2110203944Sweongyo if (id != SIBA_LDO_PAREF) 2111203944Sweongyo return; 2112203944Sweongyo p = info[4]; 2113203944Sweongyo siba_cc_regctl_setmask(scc, p[0], ~(p[2] << p[1]), 2114203944Sweongyo (volt & p[2]) << p[1]); 2115203944Sweongyo return; 2116203944Sweongyo } 2117203944Sweongyo if (siba->siba_chipid == 0x4328 || siba->siba_chipid == 0x5354) { 2118203944Sweongyo switch (id) { 2119203944Sweongyo case SIBA_LDO_PAREF: 2120203944Sweongyo p = info[3]; 2121203944Sweongyo break; 2122203944Sweongyo case SIBA_LDO_VOLT1: 2123203944Sweongyo p = info[0]; 2124203944Sweongyo break; 2125203944Sweongyo case SIBA_LDO_VOLT2: 2126203944Sweongyo p = info[1]; 2127203944Sweongyo break; 2128203944Sweongyo case SIBA_LDO_VOLT3: 2129203944Sweongyo p = info[2]; 2130203944Sweongyo break; 2131203944Sweongyo default: 2132203944Sweongyo KASSERT(0 == 1, 2133203944Sweongyo ("%s: unsupported voltage ID %#x", __func__, id)); 2134203944Sweongyo return; 2135203944Sweongyo } 2136203944Sweongyo siba_cc_regctl_setmask(scc, p[0], ~(p[2] << p[1]), 2137203944Sweongyo (volt & p[2]) << p[1]); 2138203944Sweongyo } 2139203944Sweongyo} 2140203944Sweongyo 2141203944Sweongyovoid 2142204922Sweongyosiba_cc_pmu_set_ldoparef(device_t dev, uint8_t on) 2143203944Sweongyo{ 2144204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(dev); 2145204922Sweongyo struct siba_softc *siba = sd->sd_bus; 2146204922Sweongyo struct siba_cc *scc = &siba->siba_cc; 2147203944Sweongyo int ldo; 2148203944Sweongyo 2149203944Sweongyo ldo = ((siba->siba_chipid == 0x4312) ? SIBA_CC_PMU_4312_PA_REF : 2150203944Sweongyo ((siba->siba_chipid == 0x4328) ? SIBA_CC_PMU_4328_PA_REF : 2151203944Sweongyo ((siba->siba_chipid == 0x5354) ? SIBA_CC_PMU_5354_PA_REF : -1))); 2152203944Sweongyo if (ldo == -1) 2153203944Sweongyo return; 2154203944Sweongyo 2155203944Sweongyo if (on) 2156203944Sweongyo SIBA_CC_SET32(scc, SIBA_CC_PMU_MINRES, 1 << ldo); 2157203944Sweongyo else 2158203944Sweongyo SIBA_CC_MASK32(scc, SIBA_CC_PMU_MINRES, ~(1 << ldo)); 2159203944Sweongyo SIBA_CC_READ32(scc, SIBA_CC_PMU_MINRES); 2160203944Sweongyo} 2161204922Sweongyo 2162204922Sweongyoint 2163204922Sweongyosiba_read_sprom(device_t dev, device_t child, int which, uintptr_t *result) 2164204922Sweongyo{ 2165204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(child); 2166204922Sweongyo struct siba_softc *siba = sd->sd_bus; 2167204922Sweongyo 2168204922Sweongyo switch (which) { 2169204922Sweongyo case SIBA_SPROMVAR_REV: 2170204922Sweongyo *result = siba->siba_sprom.rev; 2171204922Sweongyo break; 2172204922Sweongyo case SIBA_SPROMVAR_MAC_80211BG: 2173204922Sweongyo *((uint8_t **) result) = siba->siba_sprom.mac_80211bg; 2174204922Sweongyo break; 2175204922Sweongyo case SIBA_SPROMVAR_MAC_ETH: 2176204922Sweongyo *((uint8_t **) result) = siba->siba_sprom.mac_eth; 2177204922Sweongyo break; 2178204922Sweongyo case SIBA_SPROMVAR_MAC_80211A: 2179204922Sweongyo *((uint8_t **) result) = siba->siba_sprom.mac_80211a; 2180204922Sweongyo break; 2181204922Sweongyo case SIBA_SPROMVAR_MII_ETH0: 2182204922Sweongyo *result = siba->siba_sprom.mii_eth0; 2183204922Sweongyo break; 2184204922Sweongyo case SIBA_SPROMVAR_MII_ETH1: 2185204922Sweongyo *result = siba->siba_sprom.mii_eth1; 2186204922Sweongyo break; 2187204922Sweongyo case SIBA_SPROMVAR_MDIO_ETH0: 2188204922Sweongyo *result = siba->siba_sprom.mdio_eth0; 2189204922Sweongyo break; 2190204922Sweongyo case SIBA_SPROMVAR_MDIO_ETH1: 2191204922Sweongyo *result = siba->siba_sprom.mdio_eth1; 2192204922Sweongyo break; 2193204922Sweongyo case SIBA_SPROMVAR_BREV: 2194204922Sweongyo *result = siba->siba_sprom.brev; 2195204922Sweongyo break; 2196204922Sweongyo case SIBA_SPROMVAR_CCODE: 2197204922Sweongyo *result = siba->siba_sprom.ccode; 2198204922Sweongyo break; 2199204922Sweongyo case SIBA_SPROMVAR_ANT_A: 2200204922Sweongyo *result = siba->siba_sprom.ant_a; 2201204922Sweongyo break; 2202204922Sweongyo case SIBA_SPROMVAR_ANT_BG: 2203204922Sweongyo *result = siba->siba_sprom.ant_bg; 2204204922Sweongyo break; 2205204922Sweongyo case SIBA_SPROMVAR_PA0B0: 2206204922Sweongyo *result = siba->siba_sprom.pa0b0; 2207204922Sweongyo break; 2208204922Sweongyo case SIBA_SPROMVAR_PA0B1: 2209204922Sweongyo *result = siba->siba_sprom.pa0b1; 2210204922Sweongyo break; 2211204922Sweongyo case SIBA_SPROMVAR_PA0B2: 2212204922Sweongyo *result = siba->siba_sprom.pa0b2; 2213204922Sweongyo break; 2214204922Sweongyo case SIBA_SPROMVAR_PA1B0: 2215204922Sweongyo *result = siba->siba_sprom.pa1b0; 2216204922Sweongyo break; 2217204922Sweongyo case SIBA_SPROMVAR_PA1B1: 2218204922Sweongyo *result = siba->siba_sprom.pa1b1; 2219204922Sweongyo break; 2220204922Sweongyo case SIBA_SPROMVAR_PA1B2: 2221204922Sweongyo *result = siba->siba_sprom.pa1b2; 2222204922Sweongyo break; 2223204922Sweongyo case SIBA_SPROMVAR_PA1LOB0: 2224204922Sweongyo *result = siba->siba_sprom.pa1lob0; 2225204922Sweongyo break; 2226204922Sweongyo case SIBA_SPROMVAR_PA1LOB1: 2227204922Sweongyo *result = siba->siba_sprom.pa1lob1; 2228204922Sweongyo break; 2229204922Sweongyo case SIBA_SPROMVAR_PA1LOB2: 2230204922Sweongyo *result = siba->siba_sprom.pa1lob2; 2231204922Sweongyo break; 2232204922Sweongyo case SIBA_SPROMVAR_PA1HIB0: 2233204922Sweongyo *result = siba->siba_sprom.pa1hib0; 2234204922Sweongyo break; 2235204922Sweongyo case SIBA_SPROMVAR_PA1HIB1: 2236204922Sweongyo *result = siba->siba_sprom.pa1hib1; 2237204922Sweongyo break; 2238204922Sweongyo case SIBA_SPROMVAR_PA1HIB2: 2239204922Sweongyo *result = siba->siba_sprom.pa1hib2; 2240204922Sweongyo break; 2241204922Sweongyo case SIBA_SPROMVAR_GPIO0: 2242204922Sweongyo *result = siba->siba_sprom.gpio0; 2243204922Sweongyo break; 2244204922Sweongyo case SIBA_SPROMVAR_GPIO1: 2245204922Sweongyo *result = siba->siba_sprom.gpio1; 2246204922Sweongyo break; 2247204922Sweongyo case SIBA_SPROMVAR_GPIO2: 2248204922Sweongyo *result = siba->siba_sprom.gpio2; 2249204922Sweongyo break; 2250204922Sweongyo case SIBA_SPROMVAR_GPIO3: 2251204922Sweongyo *result = siba->siba_sprom.gpio3; 2252204922Sweongyo break; 2253204922Sweongyo case SIBA_SPROMVAR_MAXPWR_AL: 2254204922Sweongyo *result = siba->siba_sprom.maxpwr_al; 2255204922Sweongyo break; 2256204922Sweongyo case SIBA_SPROMVAR_MAXPWR_A: 2257204922Sweongyo *result = siba->siba_sprom.maxpwr_a; 2258204922Sweongyo break; 2259204922Sweongyo case SIBA_SPROMVAR_MAXPWR_AH: 2260204922Sweongyo *result = siba->siba_sprom.maxpwr_ah; 2261204922Sweongyo break; 2262204922Sweongyo case SIBA_SPROMVAR_MAXPWR_BG: 2263204922Sweongyo *result = siba->siba_sprom.maxpwr_bg; 2264204922Sweongyo break; 2265204922Sweongyo case SIBA_SPROMVAR_RXPO2G: 2266204922Sweongyo *result = siba->siba_sprom.rxpo2g; 2267204922Sweongyo break; 2268204922Sweongyo case SIBA_SPROMVAR_RXPO5G: 2269204922Sweongyo *result = siba->siba_sprom.rxpo5g; 2270204922Sweongyo break; 2271204922Sweongyo case SIBA_SPROMVAR_TSSI_A: 2272204922Sweongyo *result = siba->siba_sprom.tssi_a; 2273204922Sweongyo break; 2274204922Sweongyo case SIBA_SPROMVAR_TSSI_BG: 2275204922Sweongyo *result = siba->siba_sprom.tssi_bg; 2276204922Sweongyo break; 2277204922Sweongyo case SIBA_SPROMVAR_TRI2G: 2278204922Sweongyo *result = siba->siba_sprom.tri2g; 2279204922Sweongyo break; 2280204922Sweongyo case SIBA_SPROMVAR_TRI5GL: 2281204922Sweongyo *result = siba->siba_sprom.tri5gl; 2282204922Sweongyo break; 2283204922Sweongyo case SIBA_SPROMVAR_TRI5G: 2284204922Sweongyo *result = siba->siba_sprom.tri5g; 2285204922Sweongyo break; 2286204922Sweongyo case SIBA_SPROMVAR_TRI5GH: 2287204922Sweongyo *result = siba->siba_sprom.tri5gh; 2288204922Sweongyo break; 2289204922Sweongyo case SIBA_SPROMVAR_RSSISAV2G: 2290204922Sweongyo *result = siba->siba_sprom.rssisav2g; 2291204922Sweongyo break; 2292204922Sweongyo case SIBA_SPROMVAR_RSSISMC2G: 2293204922Sweongyo *result = siba->siba_sprom.rssismc2g; 2294204922Sweongyo break; 2295204922Sweongyo case SIBA_SPROMVAR_RSSISMF2G: 2296204922Sweongyo *result = siba->siba_sprom.rssismf2g; 2297204922Sweongyo break; 2298204922Sweongyo case SIBA_SPROMVAR_BXA2G: 2299204922Sweongyo *result = siba->siba_sprom.bxa2g; 2300204922Sweongyo break; 2301204922Sweongyo case SIBA_SPROMVAR_RSSISAV5G: 2302204922Sweongyo *result = siba->siba_sprom.rssisav5g; 2303204922Sweongyo break; 2304204922Sweongyo case SIBA_SPROMVAR_RSSISMC5G: 2305204922Sweongyo *result = siba->siba_sprom.rssismc5g; 2306204922Sweongyo break; 2307204922Sweongyo case SIBA_SPROMVAR_RSSISMF5G: 2308204922Sweongyo *result = siba->siba_sprom.rssismf5g; 2309204922Sweongyo break; 2310204922Sweongyo case SIBA_SPROMVAR_BXA5G: 2311204922Sweongyo *result = siba->siba_sprom.bxa5g; 2312204922Sweongyo break; 2313204922Sweongyo case SIBA_SPROMVAR_CCK2GPO: 2314204922Sweongyo *result = siba->siba_sprom.cck2gpo; 2315204922Sweongyo break; 2316204922Sweongyo case SIBA_SPROMVAR_OFDM2GPO: 2317204922Sweongyo *result = siba->siba_sprom.ofdm2gpo; 2318204922Sweongyo break; 2319204922Sweongyo case SIBA_SPROMVAR_OFDM5GLPO: 2320204922Sweongyo *result = siba->siba_sprom.ofdm5glpo; 2321204922Sweongyo break; 2322204922Sweongyo case SIBA_SPROMVAR_OFDM5GPO: 2323204922Sweongyo *result = siba->siba_sprom.ofdm5gpo; 2324204922Sweongyo break; 2325204922Sweongyo case SIBA_SPROMVAR_OFDM5GHPO: 2326204922Sweongyo *result = siba->siba_sprom.ofdm5ghpo; 2327204922Sweongyo break; 2328204922Sweongyo case SIBA_SPROMVAR_BF_LO: 2329204922Sweongyo *result = siba->siba_sprom.bf_lo; 2330204922Sweongyo break; 2331204922Sweongyo case SIBA_SPROMVAR_BF_HI: 2332204922Sweongyo *result = siba->siba_sprom.bf_hi; 2333204922Sweongyo break; 2334204922Sweongyo case SIBA_SPROMVAR_BF2_LO: 2335204922Sweongyo *result = siba->siba_sprom.bf2_lo; 2336204922Sweongyo break; 2337204922Sweongyo case SIBA_SPROMVAR_BF2_HI: 2338204922Sweongyo *result = siba->siba_sprom.bf2_hi; 2339204922Sweongyo break; 2340204922Sweongyo default: 2341204922Sweongyo return (ENOENT); 2342204922Sweongyo } 2343204922Sweongyo return (0); 2344204922Sweongyo} 2345204922Sweongyo 2346204922Sweongyoint 2347204922Sweongyosiba_write_sprom(device_t dev, device_t child, int which, uintptr_t value) 2348204922Sweongyo{ 2349204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(child); 2350204922Sweongyo struct siba_softc *siba = sd->sd_bus; 2351204922Sweongyo 2352204922Sweongyo switch (which) { 2353204922Sweongyo case SIBA_SPROMVAR_REV: 2354204922Sweongyo siba->siba_sprom.rev = value; 2355204922Sweongyo break; 2356204922Sweongyo case SIBA_SPROMVAR_MII_ETH0: 2357204922Sweongyo siba->siba_sprom.mii_eth0 = value; 2358204922Sweongyo break; 2359204922Sweongyo case SIBA_SPROMVAR_MII_ETH1: 2360204922Sweongyo siba->siba_sprom.mii_eth1 = value; 2361204922Sweongyo break; 2362204922Sweongyo case SIBA_SPROMVAR_MDIO_ETH0: 2363204922Sweongyo siba->siba_sprom.mdio_eth0 = value; 2364204922Sweongyo break; 2365204922Sweongyo case SIBA_SPROMVAR_MDIO_ETH1: 2366204922Sweongyo siba->siba_sprom.mdio_eth1 = value; 2367204922Sweongyo break; 2368204922Sweongyo case SIBA_SPROMVAR_BREV: 2369204922Sweongyo siba->siba_sprom.brev = value; 2370204922Sweongyo break; 2371204922Sweongyo case SIBA_SPROMVAR_CCODE: 2372204922Sweongyo siba->siba_sprom.ccode = value; 2373204922Sweongyo break; 2374204922Sweongyo case SIBA_SPROMVAR_ANT_A: 2375204922Sweongyo siba->siba_sprom.ant_a = value; 2376204922Sweongyo break; 2377204922Sweongyo case SIBA_SPROMVAR_ANT_BG: 2378204922Sweongyo siba->siba_sprom.ant_bg = value; 2379204922Sweongyo break; 2380204922Sweongyo case SIBA_SPROMVAR_PA0B0: 2381204922Sweongyo siba->siba_sprom.pa0b0 = value; 2382204922Sweongyo break; 2383204922Sweongyo case SIBA_SPROMVAR_PA0B1: 2384204922Sweongyo siba->siba_sprom.pa0b1 = value; 2385204922Sweongyo break; 2386204922Sweongyo case SIBA_SPROMVAR_PA0B2: 2387204922Sweongyo siba->siba_sprom.pa0b2 = value; 2388204922Sweongyo break; 2389204922Sweongyo case SIBA_SPROMVAR_PA1B0: 2390204922Sweongyo siba->siba_sprom.pa1b0 = value; 2391204922Sweongyo break; 2392204922Sweongyo case SIBA_SPROMVAR_PA1B1: 2393204922Sweongyo siba->siba_sprom.pa1b1 = value; 2394204922Sweongyo break; 2395204922Sweongyo case SIBA_SPROMVAR_PA1B2: 2396204922Sweongyo siba->siba_sprom.pa1b2 = value; 2397204922Sweongyo break; 2398204922Sweongyo case SIBA_SPROMVAR_PA1LOB0: 2399204922Sweongyo siba->siba_sprom.pa1lob0 = value; 2400204922Sweongyo break; 2401204922Sweongyo case SIBA_SPROMVAR_PA1LOB1: 2402204922Sweongyo siba->siba_sprom.pa1lob1 = value; 2403204922Sweongyo break; 2404204922Sweongyo case SIBA_SPROMVAR_PA1LOB2: 2405204922Sweongyo siba->siba_sprom.pa1lob2 = value; 2406204922Sweongyo break; 2407204922Sweongyo case SIBA_SPROMVAR_PA1HIB0: 2408204922Sweongyo siba->siba_sprom.pa1hib0 = value; 2409204922Sweongyo break; 2410204922Sweongyo case SIBA_SPROMVAR_PA1HIB1: 2411204922Sweongyo siba->siba_sprom.pa1hib1 = value; 2412204922Sweongyo break; 2413204922Sweongyo case SIBA_SPROMVAR_PA1HIB2: 2414204922Sweongyo siba->siba_sprom.pa1hib2 = value; 2415204922Sweongyo break; 2416204922Sweongyo case SIBA_SPROMVAR_GPIO0: 2417204922Sweongyo siba->siba_sprom.gpio0 = value; 2418204922Sweongyo break; 2419204922Sweongyo case SIBA_SPROMVAR_GPIO1: 2420204922Sweongyo siba->siba_sprom.gpio1 = value; 2421204922Sweongyo break; 2422204922Sweongyo case SIBA_SPROMVAR_GPIO2: 2423204922Sweongyo siba->siba_sprom.gpio2 = value; 2424204922Sweongyo break; 2425204922Sweongyo case SIBA_SPROMVAR_GPIO3: 2426204922Sweongyo siba->siba_sprom.gpio3 = value; 2427204922Sweongyo break; 2428204922Sweongyo case SIBA_SPROMVAR_MAXPWR_AL: 2429204922Sweongyo siba->siba_sprom.maxpwr_al = value; 2430204922Sweongyo break; 2431204922Sweongyo case SIBA_SPROMVAR_MAXPWR_A: 2432204922Sweongyo siba->siba_sprom.maxpwr_a = value; 2433204922Sweongyo break; 2434204922Sweongyo case SIBA_SPROMVAR_MAXPWR_AH: 2435204922Sweongyo siba->siba_sprom.maxpwr_ah = value; 2436204922Sweongyo break; 2437204922Sweongyo case SIBA_SPROMVAR_MAXPWR_BG: 2438204922Sweongyo siba->siba_sprom.maxpwr_bg = value; 2439204922Sweongyo break; 2440204922Sweongyo case SIBA_SPROMVAR_RXPO2G: 2441204922Sweongyo siba->siba_sprom.rxpo2g = value; 2442204922Sweongyo break; 2443204922Sweongyo case SIBA_SPROMVAR_RXPO5G: 2444204922Sweongyo siba->siba_sprom.rxpo5g = value; 2445204922Sweongyo break; 2446204922Sweongyo case SIBA_SPROMVAR_TSSI_A: 2447204922Sweongyo siba->siba_sprom.tssi_a = value; 2448204922Sweongyo break; 2449204922Sweongyo case SIBA_SPROMVAR_TSSI_BG: 2450204922Sweongyo siba->siba_sprom.tssi_bg = value; 2451204922Sweongyo break; 2452204922Sweongyo case SIBA_SPROMVAR_TRI2G: 2453204922Sweongyo siba->siba_sprom.tri2g = value; 2454204922Sweongyo break; 2455204922Sweongyo case SIBA_SPROMVAR_TRI5GL: 2456204922Sweongyo siba->siba_sprom.tri5gl = value; 2457204922Sweongyo break; 2458204922Sweongyo case SIBA_SPROMVAR_TRI5G: 2459204922Sweongyo siba->siba_sprom.tri5g = value; 2460204922Sweongyo break; 2461204922Sweongyo case SIBA_SPROMVAR_TRI5GH: 2462204922Sweongyo siba->siba_sprom.tri5gh = value; 2463204922Sweongyo break; 2464204922Sweongyo case SIBA_SPROMVAR_RSSISAV2G: 2465204922Sweongyo siba->siba_sprom.rssisav2g = value; 2466204922Sweongyo break; 2467204922Sweongyo case SIBA_SPROMVAR_RSSISMC2G: 2468204922Sweongyo siba->siba_sprom.rssismc2g = value; 2469204922Sweongyo break; 2470204922Sweongyo case SIBA_SPROMVAR_RSSISMF2G: 2471204922Sweongyo siba->siba_sprom.rssismf2g = value; 2472204922Sweongyo break; 2473204922Sweongyo case SIBA_SPROMVAR_BXA2G: 2474204922Sweongyo siba->siba_sprom.bxa2g = value; 2475204922Sweongyo break; 2476204922Sweongyo case SIBA_SPROMVAR_RSSISAV5G: 2477204922Sweongyo siba->siba_sprom.rssisav5g = value; 2478204922Sweongyo break; 2479204922Sweongyo case SIBA_SPROMVAR_RSSISMC5G: 2480204922Sweongyo siba->siba_sprom.rssismc5g = value; 2481204922Sweongyo break; 2482204922Sweongyo case SIBA_SPROMVAR_RSSISMF5G: 2483204922Sweongyo siba->siba_sprom.rssismf5g = value; 2484204922Sweongyo break; 2485204922Sweongyo case SIBA_SPROMVAR_BXA5G: 2486204922Sweongyo siba->siba_sprom.bxa5g = value; 2487204922Sweongyo break; 2488204922Sweongyo case SIBA_SPROMVAR_CCK2GPO: 2489204922Sweongyo siba->siba_sprom.cck2gpo = value; 2490204922Sweongyo break; 2491204922Sweongyo case SIBA_SPROMVAR_OFDM2GPO: 2492204922Sweongyo siba->siba_sprom.ofdm2gpo = value; 2493204922Sweongyo break; 2494204922Sweongyo case SIBA_SPROMVAR_OFDM5GLPO: 2495204922Sweongyo siba->siba_sprom.ofdm5glpo = value; 2496204922Sweongyo break; 2497204922Sweongyo case SIBA_SPROMVAR_OFDM5GPO: 2498204922Sweongyo siba->siba_sprom.ofdm5gpo = value; 2499204922Sweongyo break; 2500204922Sweongyo case SIBA_SPROMVAR_OFDM5GHPO: 2501204922Sweongyo siba->siba_sprom.ofdm5ghpo = value; 2502204922Sweongyo break; 2503204922Sweongyo case SIBA_SPROMVAR_BF_LO: 2504204922Sweongyo siba->siba_sprom.bf_lo = value; 2505204922Sweongyo break; 2506204922Sweongyo case SIBA_SPROMVAR_BF_HI: 2507204922Sweongyo siba->siba_sprom.bf_hi = value; 2508204922Sweongyo break; 2509204922Sweongyo case SIBA_SPROMVAR_BF2_LO: 2510204922Sweongyo siba->siba_sprom.bf2_lo = value; 2511204922Sweongyo break; 2512204922Sweongyo case SIBA_SPROMVAR_BF2_HI: 2513204922Sweongyo siba->siba_sprom.bf2_hi = value; 2514204922Sweongyo break; 2515204922Sweongyo default: 2516204922Sweongyo return (ENOENT); 2517204922Sweongyo } 2518204922Sweongyo return (0); 2519204922Sweongyo} 2520204922Sweongyo 2521204922Sweongyo#define SIBA_GPIOCTL 0x06c 2522204922Sweongyo 2523204922Sweongyouint32_t 2524204922Sweongyosiba_gpio_get(device_t dev) 2525204922Sweongyo{ 2526204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(dev); 2527204922Sweongyo struct siba_softc *siba = sd->sd_bus; 2528204922Sweongyo struct siba_dev_softc *gpiodev, *pcidev = NULL; 2529204922Sweongyo 2530204922Sweongyo pcidev = siba->siba_pci.spc_dev; 2531204922Sweongyo gpiodev = siba->siba_cc.scc_dev ? siba->siba_cc.scc_dev : pcidev; 2532204922Sweongyo if (!gpiodev) 2533204922Sweongyo return (-1); 2534204922Sweongyo return (siba_read_4_sub(gpiodev, SIBA_GPIOCTL)); 2535204922Sweongyo} 2536204922Sweongyo 2537204922Sweongyovoid 2538204922Sweongyosiba_gpio_set(device_t dev, uint32_t value) 2539204922Sweongyo{ 2540204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(dev); 2541204922Sweongyo struct siba_softc *siba = sd->sd_bus; 2542204922Sweongyo struct siba_dev_softc *gpiodev, *pcidev = NULL; 2543204922Sweongyo 2544204922Sweongyo pcidev = siba->siba_pci.spc_dev; 2545204922Sweongyo gpiodev = siba->siba_cc.scc_dev ? siba->siba_cc.scc_dev : pcidev; 2546204922Sweongyo if (!gpiodev) 2547204922Sweongyo return; 2548204922Sweongyo siba_write_4_sub(gpiodev, SIBA_GPIOCTL, value); 2549204922Sweongyo} 2550204922Sweongyo 2551204922Sweongyovoid 2552204922Sweongyosiba_fix_imcfglobug(device_t dev) 2553204922Sweongyo{ 2554204922Sweongyo struct siba_dev_softc *sd = device_get_ivars(dev); 2555204922Sweongyo struct siba_softc *siba = sd->sd_bus; 2556204922Sweongyo uint32_t tmp; 2557204922Sweongyo 2558204922Sweongyo if (siba->siba_pci.spc_dev == NULL) 2559204922Sweongyo return; 2560204922Sweongyo if (siba->siba_pci.spc_dev->sd_id.sd_device != SIBA_DEVID_PCI || 2561204922Sweongyo siba->siba_pci.spc_dev->sd_id.sd_rev > 5) 2562204922Sweongyo return; 2563204922Sweongyo 2564204922Sweongyo tmp = siba_read_4_sub(sd, SIBA_IMCFGLO) & 2565204922Sweongyo ~(SIBA_IMCFGLO_REQTO | SIBA_IMCFGLO_SERTO); 2566204922Sweongyo switch (siba->siba_type) { 2567204922Sweongyo case SIBA_TYPE_PCI: 2568204922Sweongyo case SIBA_TYPE_PCMCIA: 2569204922Sweongyo tmp |= 0x32; 2570204922Sweongyo break; 2571204922Sweongyo case SIBA_TYPE_SSB: 2572204922Sweongyo tmp |= 0x53; 2573204922Sweongyo break; 2574204922Sweongyo } 2575204922Sweongyo siba_write_4_sub(sd, SIBA_IMCFGLO, tmp); 2576204922Sweongyo} 2577