siba_core.c revision 203319
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: head/sys/dev/siba/siba_core.c 203319 2010-01-31 21:18:22Z weongyo $"); 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 *); 136203319Sweongyodevice_t siba_add_child(device_t, struct siba_softc *, int, const char *, 137203319Sweongyo int); 138203319Sweongyoint siba_core_attach(struct siba_softc *); 139203319Sweongyoint siba_core_detach(struct siba_softc *); 140203319Sweongyoint siba_core_suspend(struct siba_softc *); 141203319Sweongyoint siba_core_resume(struct siba_softc *); 142203319Sweongyouint8_t siba_getncores(device_t, uint16_t); 143203319Sweongyo 144203319Sweongyostatic const struct siba_bus_ops siba_pci_ops = { 145203319Sweongyo .read_2 = siba_pci_read_2, 146203319Sweongyo .read_4 = siba_pci_read_4, 147203319Sweongyo .write_2 = siba_pci_write_2, 148203319Sweongyo .write_4 = siba_pci_write_4, 149203319Sweongyo .read_multi_1 = siba_pci_read_multi_1, 150203319Sweongyo .read_multi_2 = siba_pci_read_multi_2, 151203319Sweongyo .read_multi_4 = siba_pci_read_multi_4, 152203319Sweongyo .write_multi_1 = siba_pci_write_multi_1, 153203319Sweongyo .write_multi_2 = siba_pci_write_multi_2, 154203319Sweongyo .write_multi_4 = siba_pci_write_multi_4, 155203319Sweongyo}; 156203319Sweongyo 157203319Sweongyostatic const struct siba_cc_pmu_res_updown siba_cc_pmu_4325_updown[] = 158203319Sweongyo SIBA_CC_PMU_4325_RES_UPDOWN; 159203319Sweongyostatic const struct siba_cc_pmu_res_depend siba_cc_pmu_4325_depend[] = 160203319Sweongyo SIBA_CC_PMU_4325_RES_DEPEND; 161203319Sweongyostatic const struct siba_cc_pmu_res_updown siba_cc_pmu_4328_updown[] = 162203319Sweongyo SIBA_CC_PMU_4328_RES_UPDOWN; 163203319Sweongyostatic const struct siba_cc_pmu_res_depend siba_cc_pmu_4328_depend[] = 164203319Sweongyo SIBA_CC_PMU_4328_RES_DEPEND; 165203319Sweongyostatic const struct siba_cc_pmu0_plltab siba_cc_pmu0_plltab[] = 166203319Sweongyo SIBA_CC_PMU0_PLLTAB_ENTRY; 167203319Sweongyostatic const struct siba_cc_pmu1_plltab siba_cc_pmu1_plltab[] = 168203319Sweongyo SIBA_CC_PMU1_PLLTAB_ENTRY; 169203319Sweongyo 170203319Sweongyoint 171203319Sweongyosiba_core_attach(struct siba_softc *siba) 172203319Sweongyo{ 173203319Sweongyo struct siba_cc *scc; 174203319Sweongyo int error; 175203319Sweongyo 176203319Sweongyo KASSERT(siba->siba_type == SIBA_TYPE_PCI, 177203319Sweongyo ("unsupported BUS type (%#x)", siba->siba_type)); 178203319Sweongyo 179203319Sweongyo siba->siba_ops = &siba_pci_ops; 180203319Sweongyo 181203319Sweongyo siba_pci_gpio(siba, SIBA_GPIO_CRYSTAL | SIBA_GPIO_PLL, 1); 182203319Sweongyo siba_scan(siba); 183203319Sweongyo 184203319Sweongyo /* XXX init PCI or PCMCIA host devices */ 185203319Sweongyo 186203319Sweongyo siba_powerup(siba, 0); 187203319Sweongyo 188203319Sweongyo /* init ChipCommon */ 189203319Sweongyo scc = &siba->siba_cc; 190203319Sweongyo if (scc->scc_dev != NULL) { 191203319Sweongyo siba_cc_pmu_init(scc); 192203319Sweongyo siba_cc_power_init(scc); 193203319Sweongyo siba_cc_clock(scc, SIBA_CLOCK_FAST); 194203319Sweongyo siba_cc_powerup_delay(scc); 195203319Sweongyo } 196203319Sweongyo 197203319Sweongyo /* fetch various internal informations for PCI */ 198203319Sweongyo siba->siba_board_vendor = pci_read_config(siba->siba_dev, 199203319Sweongyo PCIR_SUBVEND_0, 2); 200203319Sweongyo siba->siba_board_type = pci_read_config(siba->siba_dev, PCIR_SUBDEV_0, 201203319Sweongyo 2); 202203319Sweongyo siba->siba_board_rev = pci_read_config(siba->siba_dev, PCIR_REVID, 2); 203203319Sweongyo error = siba_pci_sprom(siba, &siba->siba_sprom); 204203319Sweongyo if (error) { 205203319Sweongyo siba_powerdown(siba); 206203319Sweongyo return (error); 207203319Sweongyo } 208203319Sweongyo 209203319Sweongyo siba_powerdown(siba); 210203319Sweongyo return (0); 211203319Sweongyo} 212203319Sweongyo 213203319Sweongyoint 214203319Sweongyosiba_core_detach(struct siba_softc *siba) 215203319Sweongyo{ 216203319Sweongyo device_t *devlistp; 217203319Sweongyo int devcnt, error = 0, i; 218203319Sweongyo 219203319Sweongyo error = device_get_children(siba->siba_dev, &devlistp, &devcnt); 220203319Sweongyo if (error != 0) 221203319Sweongyo return (0); 222203319Sweongyo 223203319Sweongyo for ( i = 0 ; i < devcnt ; i++) 224203319Sweongyo device_delete_child(siba->siba_dev, devlistp[i]); 225203319Sweongyo free(devlistp, M_TEMP); 226203319Sweongyo return (0); 227203319Sweongyo} 228203319Sweongyo 229203319Sweongyostatic void 230203319Sweongyosiba_pci_gpio(struct siba_softc *siba, uint32_t what, int on) 231203319Sweongyo{ 232203319Sweongyo uint32_t in, out; 233203319Sweongyo uint16_t status; 234203319Sweongyo 235203319Sweongyo if (siba->siba_type != SIBA_TYPE_PCI) 236203319Sweongyo return; 237203319Sweongyo 238203319Sweongyo out = pci_read_config(siba->siba_dev, SIBA_GPIO_OUT, 4); 239203319Sweongyo if (on == 0) { 240203319Sweongyo if (what & SIBA_GPIO_PLL) 241203319Sweongyo out |= SIBA_GPIO_PLL; 242203319Sweongyo if (what & SIBA_GPIO_CRYSTAL) 243203319Sweongyo out &= ~SIBA_GPIO_CRYSTAL; 244203319Sweongyo pci_write_config(siba->siba_dev, SIBA_GPIO_OUT, out, 4); 245203319Sweongyo pci_write_config(siba->siba_dev, SIBA_GPIO_OUT_EN, 246203319Sweongyo pci_read_config(siba->siba_dev, 247203319Sweongyo SIBA_GPIO_OUT_EN, 4) | what, 4); 248203319Sweongyo return; 249203319Sweongyo } 250203319Sweongyo 251203319Sweongyo in = pci_read_config(siba->siba_dev, SIBA_GPIO_IN, 4); 252203319Sweongyo if ((in & SIBA_GPIO_CRYSTAL) != SIBA_GPIO_CRYSTAL) { 253203319Sweongyo if (what & SIBA_GPIO_CRYSTAL) { 254203319Sweongyo out |= SIBA_GPIO_CRYSTAL; 255203319Sweongyo if (what & SIBA_GPIO_PLL) 256203319Sweongyo out |= SIBA_GPIO_PLL; 257203319Sweongyo pci_write_config(siba->siba_dev, SIBA_GPIO_OUT, out, 4); 258203319Sweongyo pci_write_config(siba->siba_dev, 259203319Sweongyo SIBA_GPIO_OUT_EN, pci_read_config(siba->siba_dev, 260203319Sweongyo SIBA_GPIO_OUT_EN, 4) | what, 4); 261203319Sweongyo DELAY(1000); 262203319Sweongyo } 263203319Sweongyo if (what & SIBA_GPIO_PLL) { 264203319Sweongyo out &= ~SIBA_GPIO_PLL; 265203319Sweongyo pci_write_config(siba->siba_dev, SIBA_GPIO_OUT, out, 4); 266203319Sweongyo DELAY(5000); 267203319Sweongyo } 268203319Sweongyo } 269203319Sweongyo 270203319Sweongyo status = pci_read_config(siba->siba_dev, PCIR_STATUS, 2); 271203319Sweongyo status &= ~PCIM_STATUS_STABORT; 272203319Sweongyo pci_write_config(siba->siba_dev, PCIR_STATUS, status, 2); 273203319Sweongyo} 274203319Sweongyo 275203319Sweongyostatic void 276203319Sweongyosiba_scan(struct siba_softc *siba) 277203319Sweongyo{ 278203319Sweongyo struct siba_dev_softc *sd; 279203319Sweongyo uint32_t idhi, tmp; 280203319Sweongyo int base, dev_i = 0, error, i, is_pcie, n_80211 = 0, n_cc = 0, 281203319Sweongyo n_pci = 0; 282203319Sweongyo 283203319Sweongyo KASSERT(siba->siba_type == SIBA_TYPE_PCI, 284203319Sweongyo ("unsupported BUS type (%#x)", siba->siba_type)); 285203319Sweongyo 286203319Sweongyo siba->siba_ndevs = 0; 287203319Sweongyo error = siba_switchcore(siba, 0); /* need the first core */ 288203319Sweongyo if (error) 289203319Sweongyo return; 290203319Sweongyo 291203319Sweongyo idhi = siba_scan_read_4(siba, 0, SIBA_IDHIGH); 292203319Sweongyo if (SIBA_IDHIGH_CORECODE(idhi) == SIBA_DEVID_CHIPCOMMON) { 293203319Sweongyo tmp = siba_scan_read_4(siba, 0, SIBA_CC_CHIPID); 294203319Sweongyo siba->siba_chipid = SIBA_CC_ID(tmp); 295203319Sweongyo siba->siba_chiprev = SIBA_CC_REV(tmp); 296203319Sweongyo siba->siba_chippkg = SIBA_CC_PKG(tmp); 297203319Sweongyo if (SIBA_IDHIGH_REV(idhi) >= 4) 298203319Sweongyo siba->siba_ndevs = SIBA_CC_NCORES(tmp); 299203319Sweongyo siba->siba_cc.scc_caps = siba_scan_read_4(siba, 0, 300203319Sweongyo SIBA_CC_CAPS); 301203319Sweongyo } else { 302203319Sweongyo if (siba->siba_type == SIBA_TYPE_PCI) { 303203319Sweongyo siba->siba_chipid = siba_dev2chipid(siba); 304203319Sweongyo siba->siba_chiprev = pci_read_config(siba->siba_dev, 305203319Sweongyo PCIR_REVID, 2); 306203319Sweongyo siba->siba_chippkg = 0; 307203319Sweongyo } else { 308203319Sweongyo siba->siba_chipid = 0x4710; 309203319Sweongyo siba->siba_chiprev = 0; 310203319Sweongyo siba->siba_chippkg = 0; 311203319Sweongyo } 312203319Sweongyo } 313203319Sweongyo if (siba->siba_ndevs == 0) 314203319Sweongyo siba->siba_ndevs = siba_getncores(siba->siba_dev, 315203319Sweongyo siba->siba_chipid); 316203319Sweongyo if (siba->siba_ndevs > SIBA_MAX_CORES) { 317203319Sweongyo device_printf(siba->siba_dev, 318203319Sweongyo "too many siba cores (max %d %d)\n", 319203319Sweongyo SIBA_MAX_CORES, siba->siba_ndevs); 320203319Sweongyo return; 321203319Sweongyo } 322203319Sweongyo 323203319Sweongyo /* looking basic information about each cores/devices */ 324203319Sweongyo for (i = 0; i < siba->siba_ndevs; i++) { 325203319Sweongyo error = siba_switchcore(siba, i); 326203319Sweongyo if (error) 327203319Sweongyo return; 328203319Sweongyo sd = &(siba->siba_devs[dev_i]); 329203319Sweongyo idhi = siba_scan_read_4(siba, i, SIBA_IDHIGH); 330203319Sweongyo sd->sd_bus = siba; 331203319Sweongyo sd->sd_id.sd_device = SIBA_IDHIGH_CORECODE(idhi); 332203319Sweongyo sd->sd_id.sd_rev = SIBA_IDHIGH_REV(idhi); 333203319Sweongyo sd->sd_id.sd_vendor = SIBA_IDHIGH_VENDOR(idhi); 334203319Sweongyo sd->sd_ops = siba->siba_ops; 335203319Sweongyo sd->sd_coreidx = i; 336203319Sweongyo 337203319Sweongyo DPRINTF(siba, SIBA_DEBUG_SCAN, 338203319Sweongyo "core %d (%s) found (cc %#xrev %#x vendor %#x)\n", 339203319Sweongyo i, siba_core_name(sd->sd_id.sd_device), 340203319Sweongyo sd->sd_id.sd_device, sd->sd_id.sd_rev, sd->sd_id.vendor); 341203319Sweongyo 342203319Sweongyo switch (sd->sd_id.sd_device) { 343203319Sweongyo case SIBA_DEVID_CHIPCOMMON: 344203319Sweongyo n_cc++; 345203319Sweongyo if (n_cc > 1) { 346203319Sweongyo device_printf(siba->siba_dev, 347203319Sweongyo "warn: multiple ChipCommon\n"); 348203319Sweongyo break; 349203319Sweongyo } 350203319Sweongyo siba->siba_cc.scc_dev = sd; 351203319Sweongyo break; 352203319Sweongyo case SIBA_DEVID_80211: 353203319Sweongyo n_80211++; 354203319Sweongyo if (n_80211 > 1) { 355203319Sweongyo device_printf(siba->siba_dev, 356203319Sweongyo "warn: multiple 802.11 core\n"); 357203319Sweongyo continue; 358203319Sweongyo } 359203319Sweongyo break; 360203319Sweongyo case SIBA_DEVID_PCI: 361203319Sweongyo case SIBA_DEVID_PCIE: 362203319Sweongyo n_pci++; 363203319Sweongyo error = pci_find_extcap(siba->siba_dev, PCIY_EXPRESS, 364203319Sweongyo &base); 365203319Sweongyo is_pcie = (error == 0) ? 1 : 0; 366203319Sweongyo 367203319Sweongyo if (n_pci > 1) { 368203319Sweongyo device_printf(siba->siba_dev, 369203319Sweongyo "warn: multiple PCI(E) cores\n"); 370203319Sweongyo break; 371203319Sweongyo } 372203319Sweongyo if (sd->sd_id.sd_device == SIBA_DEVID_PCI && 373203319Sweongyo is_pcie == 1) 374203319Sweongyo continue; 375203319Sweongyo if (sd->sd_id.sd_device == SIBA_DEVID_PCIE && 376203319Sweongyo is_pcie == 0) 377203319Sweongyo continue; 378203319Sweongyo siba->siba_pci.spc_dev = sd; 379203319Sweongyo break; 380203319Sweongyo case SIBA_DEVID_MODEM: 381203319Sweongyo case SIBA_DEVID_PCMCIA: 382203319Sweongyo break; 383203319Sweongyo default: 384203319Sweongyo device_printf(siba->siba_dev, 385203319Sweongyo "unsupported coreid (%s)\n", 386203319Sweongyo siba_core_name(sd->sd_id.sd_device)); 387203319Sweongyo break; 388203319Sweongyo } 389203319Sweongyo dev_i++; 390203319Sweongyo } 391203319Sweongyo siba->siba_ndevs = dev_i; 392203319Sweongyo} 393203319Sweongyo 394203319Sweongyostatic int 395203319Sweongyosiba_switchcore(struct siba_softc *siba, uint8_t idx) 396203319Sweongyo{ 397203319Sweongyo 398203319Sweongyo switch (siba->siba_type) { 399203319Sweongyo case SIBA_TYPE_PCI: 400203319Sweongyo return (siba_pci_switchcore_sub(siba, idx)); 401203319Sweongyo default: 402203319Sweongyo KASSERT(0 == 1, 403203319Sweongyo ("%s: unsupported bustype %#x", __func__, 404203319Sweongyo siba->siba_type)); 405203319Sweongyo } 406203319Sweongyo return (0); 407203319Sweongyo} 408203319Sweongyo 409203319Sweongyostatic int 410203319Sweongyosiba_pci_switchcore_sub(struct siba_softc *siba, uint8_t idx) 411203319Sweongyo{ 412203319Sweongyo#define RETRY_MAX 50 413203319Sweongyo int i; 414203319Sweongyo uint32_t dir; 415203319Sweongyo 416203319Sweongyo dir = SIBA_REGWIN(idx); 417203319Sweongyo 418203319Sweongyo for (i = 0; i < RETRY_MAX; i++) { 419203319Sweongyo pci_write_config(siba->siba_dev, SIBA_BAR0, dir, 4); 420203319Sweongyo if (pci_read_config(siba->siba_dev, SIBA_BAR0, 4) == dir) 421203319Sweongyo return (0); 422203319Sweongyo DELAY(10); 423203319Sweongyo } 424203319Sweongyo return (ENODEV); 425203319Sweongyo#undef RETRY_MAX 426203319Sweongyo} 427203319Sweongyo 428203319Sweongyostatic int 429203319Sweongyosiba_pci_switchcore(struct siba_softc *siba, struct siba_dev_softc *sd) 430203319Sweongyo{ 431203319Sweongyo int error; 432203319Sweongyo 433203319Sweongyo DPRINTF(siba, SIBA_DEBUG_SWITCHCORE, "Switching to %s core, index %d\n", 434203319Sweongyo siba_core_name(sd->sd_id.sd_device), sd->sd_coreidx); 435203319Sweongyo 436203319Sweongyo error = siba_pci_switchcore_sub(siba, sd->sd_coreidx); 437203319Sweongyo if (error == 0) 438203319Sweongyo siba->siba_curdev = sd; 439203319Sweongyo 440203319Sweongyo return (error); 441203319Sweongyo} 442203319Sweongyo 443203319Sweongyostatic uint32_t 444203319Sweongyosiba_scan_read_4(struct siba_softc *siba, uint8_t coreidx, 445203319Sweongyo uint16_t offset) 446203319Sweongyo{ 447203319Sweongyo 448203319Sweongyo (void)coreidx; 449203319Sweongyo KASSERT(siba->siba_type == SIBA_TYPE_PCI, 450203319Sweongyo ("unsupported BUS type (%#x)", siba->siba_type)); 451203319Sweongyo 452203319Sweongyo return (SIBA_READ_4(siba, offset)); 453203319Sweongyo} 454203319Sweongyo 455203319Sweongyostatic uint16_t 456203319Sweongyosiba_dev2chipid(struct siba_softc *siba) 457203319Sweongyo{ 458203319Sweongyo uint16_t chipid = 0; 459203319Sweongyo 460203319Sweongyo switch (siba->siba_pci_did) { 461203319Sweongyo case 0x4301: 462203319Sweongyo chipid = 0x4301; 463203319Sweongyo break; 464203319Sweongyo case 0x4305: 465203319Sweongyo case 0x4306: 466203319Sweongyo case 0x4307: 467203319Sweongyo chipid = 0x4307; 468203319Sweongyo break; 469203319Sweongyo case 0x4403: 470203319Sweongyo chipid = 0x4402; 471203319Sweongyo break; 472203319Sweongyo case 0x4610: 473203319Sweongyo case 0x4611: 474203319Sweongyo case 0x4612: 475203319Sweongyo case 0x4613: 476203319Sweongyo case 0x4614: 477203319Sweongyo case 0x4615: 478203319Sweongyo chipid = 0x4610; 479203319Sweongyo break; 480203319Sweongyo case 0x4710: 481203319Sweongyo case 0x4711: 482203319Sweongyo case 0x4712: 483203319Sweongyo case 0x4713: 484203319Sweongyo case 0x4714: 485203319Sweongyo case 0x4715: 486203319Sweongyo chipid = 0x4710; 487203319Sweongyo break; 488203319Sweongyo case 0x4320: 489203319Sweongyo case 0x4321: 490203319Sweongyo case 0x4322: 491203319Sweongyo case 0x4323: 492203319Sweongyo case 0x4324: 493203319Sweongyo case 0x4325: 494203319Sweongyo chipid = 0x4309; 495203319Sweongyo break; 496203319Sweongyo case PCI_DEVICE_ID_BCM4401: 497203319Sweongyo case PCI_DEVICE_ID_BCM4401B0: 498203319Sweongyo case PCI_DEVICE_ID_BCM4401B1: 499203319Sweongyo chipid = 0x4401; 500203319Sweongyo break; 501203319Sweongyo default: 502203319Sweongyo device_printf(siba->siba_dev, "unknown PCI did (%d)\n", 503203319Sweongyo siba->siba_pci_did); 504203319Sweongyo } 505203319Sweongyo 506203319Sweongyo return (chipid); 507203319Sweongyo} 508203319Sweongyo 509203319Sweongyo/* 510203319Sweongyo * Earlier ChipCommon revisions have hardcoded number of cores 511203319Sweongyo * present dependent on the ChipCommon ID. 512203319Sweongyo */ 513203319Sweongyouint8_t 514203319Sweongyosiba_getncores(device_t dev, uint16_t chipid) 515203319Sweongyo{ 516203319Sweongyo switch (chipid) { 517203319Sweongyo case 0x4401: 518203319Sweongyo case 0x4402: 519203319Sweongyo return (3); 520203319Sweongyo case 0x4301: 521203319Sweongyo case 0x4307: 522203319Sweongyo return (5); 523203319Sweongyo case 0x4306: 524203319Sweongyo return (6); 525203319Sweongyo case SIBA_CCID_SENTRY5: 526203319Sweongyo return (7); 527203319Sweongyo case 0x4310: 528203319Sweongyo return (8); 529203319Sweongyo case SIBA_CCID_BCM4710: 530203319Sweongyo case 0x4610: 531203319Sweongyo case SIBA_CCID_BCM4704: 532203319Sweongyo return (9); 533203319Sweongyo default: 534203319Sweongyo device_printf(dev, "unknown the chipset ID %#x\n", chipid); 535203319Sweongyo } 536203319Sweongyo 537203319Sweongyo return (1); 538203319Sweongyo} 539203319Sweongyo 540203319Sweongyostatic const char * 541203319Sweongyosiba_core_name(uint16_t coreid) 542203319Sweongyo{ 543203319Sweongyo 544203319Sweongyo switch (coreid) { 545203319Sweongyo case SIBA_DEVID_CHIPCOMMON: 546203319Sweongyo return ("ChipCommon"); 547203319Sweongyo case SIBA_DEVID_ILINE20: 548203319Sweongyo return ("ILine 20"); 549203319Sweongyo case SIBA_DEVID_SDRAM: 550203319Sweongyo return ("SDRAM"); 551203319Sweongyo case SIBA_DEVID_PCI: 552203319Sweongyo return ("PCI"); 553203319Sweongyo case SIBA_DEVID_MIPS: 554203319Sweongyo return ("MIPS"); 555203319Sweongyo case SIBA_DEVID_ETHERNET: 556203319Sweongyo return ("Fast Ethernet"); 557203319Sweongyo case SIBA_DEVID_MODEM: 558203319Sweongyo return ("Modem"); 559203319Sweongyo case SIBA_DEVID_USB11_HOSTDEV: 560203319Sweongyo return ("USB 1.1 Hostdev"); 561203319Sweongyo case SIBA_DEVID_ADSL: 562203319Sweongyo return ("ADSL"); 563203319Sweongyo case SIBA_DEVID_ILINE100: 564203319Sweongyo return ("ILine 100"); 565203319Sweongyo case SIBA_DEVID_IPSEC: 566203319Sweongyo return ("IPSEC"); 567203319Sweongyo case SIBA_DEVID_PCMCIA: 568203319Sweongyo return ("PCMCIA"); 569203319Sweongyo case SIBA_DEVID_INTERNAL_MEM: 570203319Sweongyo return ("Internal Memory"); 571203319Sweongyo case SIBA_DEVID_SDRAMDDR: 572203319Sweongyo return ("MEMC SDRAM"); 573203319Sweongyo case SIBA_DEVID_EXTIF: 574203319Sweongyo return ("EXTIF"); 575203319Sweongyo case SIBA_DEVID_80211: 576203319Sweongyo return ("IEEE 802.11"); 577203319Sweongyo case SIBA_DEVID_MIPS_3302: 578203319Sweongyo return ("MIPS 3302"); 579203319Sweongyo case SIBA_DEVID_USB11_HOST: 580203319Sweongyo return ("USB 1.1 Host"); 581203319Sweongyo case SIBA_DEVID_USB11_DEV: 582203319Sweongyo return ("USB 1.1 Device"); 583203319Sweongyo case SIBA_DEVID_USB20_HOST: 584203319Sweongyo return ("USB 2.0 Host"); 585203319Sweongyo case SIBA_DEVID_USB20_DEV: 586203319Sweongyo return ("USB 2.0 Device"); 587203319Sweongyo case SIBA_DEVID_SDIO_HOST: 588203319Sweongyo return ("SDIO Host"); 589203319Sweongyo case SIBA_DEVID_ROBOSWITCH: 590203319Sweongyo return ("Roboswitch"); 591203319Sweongyo case SIBA_DEVID_PARA_ATA: 592203319Sweongyo return ("PATA"); 593203319Sweongyo case SIBA_DEVID_SATA_XORDMA: 594203319Sweongyo return ("SATA XOR-DMA"); 595203319Sweongyo case SIBA_DEVID_ETHERNET_GBIT: 596203319Sweongyo return ("GBit Ethernet"); 597203319Sweongyo case SIBA_DEVID_PCIE: 598203319Sweongyo return ("PCI-Express"); 599203319Sweongyo case SIBA_DEVID_MIMO_PHY: 600203319Sweongyo return ("MIMO PHY"); 601203319Sweongyo case SIBA_DEVID_SRAM_CTRLR: 602203319Sweongyo return ("SRAM Controller"); 603203319Sweongyo case SIBA_DEVID_MINI_MACPHY: 604203319Sweongyo return ("Mini MACPHY"); 605203319Sweongyo case SIBA_DEVID_ARM_1176: 606203319Sweongyo return ("ARM 1176"); 607203319Sweongyo case SIBA_DEVID_ARM_7TDMI: 608203319Sweongyo return ("ARM 7TDMI"); 609203319Sweongyo } 610203319Sweongyo return ("unknown"); 611203319Sweongyo} 612203319Sweongyo 613203319Sweongyostatic uint16_t 614203319Sweongyosiba_pci_read_2(struct siba_dev_softc *sd, uint16_t offset) 615203319Sweongyo{ 616203319Sweongyo struct siba_softc *siba = sd->sd_bus; 617203319Sweongyo 618203319Sweongyo if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0) 619203319Sweongyo return (0xffff); 620203319Sweongyo 621203319Sweongyo return (SIBA_READ_2(siba, offset)); 622203319Sweongyo} 623203319Sweongyo 624203319Sweongyostatic uint32_t 625203319Sweongyosiba_pci_read_4(struct siba_dev_softc *sd, uint16_t offset) 626203319Sweongyo{ 627203319Sweongyo struct siba_softc *siba = sd->sd_bus; 628203319Sweongyo 629203319Sweongyo if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0) 630203319Sweongyo return (0xffff); 631203319Sweongyo 632203319Sweongyo return (SIBA_READ_4(siba, offset)); 633203319Sweongyo} 634203319Sweongyo 635203319Sweongyostatic void 636203319Sweongyosiba_pci_write_2(struct siba_dev_softc *sd, uint16_t offset, uint16_t value) 637203319Sweongyo{ 638203319Sweongyo struct siba_softc *siba = sd->sd_bus; 639203319Sweongyo 640203319Sweongyo if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0) 641203319Sweongyo return; 642203319Sweongyo 643203319Sweongyo SIBA_WRITE_2(siba, offset, value); 644203319Sweongyo} 645203319Sweongyo 646203319Sweongyostatic void 647203319Sweongyosiba_pci_write_4(struct siba_dev_softc *sd, uint16_t offset, uint32_t value) 648203319Sweongyo{ 649203319Sweongyo struct siba_softc *siba = sd->sd_bus; 650203319Sweongyo 651203319Sweongyo if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0) 652203319Sweongyo return; 653203319Sweongyo 654203319Sweongyo SIBA_WRITE_4(siba, offset, value); 655203319Sweongyo} 656203319Sweongyo 657203319Sweongyostatic void 658203319Sweongyosiba_pci_read_multi_1(struct siba_dev_softc *sd, void *buffer, size_t count, 659203319Sweongyo uint16_t offset) 660203319Sweongyo{ 661203319Sweongyo struct siba_softc *siba = sd->sd_bus; 662203319Sweongyo 663203319Sweongyo if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0) { 664203319Sweongyo memset(buffer, 0xff, count); 665203319Sweongyo return; 666203319Sweongyo } 667203319Sweongyo 668203319Sweongyo SIBA_READ_MULTI_1(siba, offset, buffer, count); 669203319Sweongyo} 670203319Sweongyo 671203319Sweongyostatic void 672203319Sweongyosiba_pci_read_multi_2(struct siba_dev_softc *sd, void *buffer, size_t count, 673203319Sweongyo uint16_t offset) 674203319Sweongyo{ 675203319Sweongyo struct siba_softc *siba = sd->sd_bus; 676203319Sweongyo 677203319Sweongyo if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0) { 678203319Sweongyo memset(buffer, 0xff, count); 679203319Sweongyo return; 680203319Sweongyo } 681203319Sweongyo 682203319Sweongyo KASSERT(!(count & 1), ("%s:%d: fail", __func__, __LINE__)); 683203319Sweongyo SIBA_READ_MULTI_2(siba, offset, buffer, count >> 1); 684203319Sweongyo} 685203319Sweongyo 686203319Sweongyostatic void 687203319Sweongyosiba_pci_read_multi_4(struct siba_dev_softc *sd, void *buffer, size_t count, 688203319Sweongyo uint16_t offset) 689203319Sweongyo{ 690203319Sweongyo struct siba_softc *siba = sd->sd_bus; 691203319Sweongyo 692203319Sweongyo if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0) { 693203319Sweongyo memset(buffer, 0xff, count); 694203319Sweongyo return; 695203319Sweongyo } 696203319Sweongyo 697203319Sweongyo KASSERT(!(count & 3), ("%s:%d: fail", __func__, __LINE__)); 698203319Sweongyo SIBA_READ_MULTI_4(siba, offset, buffer, count >> 2); 699203319Sweongyo} 700203319Sweongyo 701203319Sweongyostatic void 702203319Sweongyosiba_pci_write_multi_1(struct siba_dev_softc *sd, const void *buffer, 703203319Sweongyo size_t count, uint16_t offset) 704203319Sweongyo{ 705203319Sweongyo struct siba_softc *siba = sd->sd_bus; 706203319Sweongyo 707203319Sweongyo if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0) 708203319Sweongyo return; 709203319Sweongyo 710203319Sweongyo SIBA_WRITE_MULTI_1(siba, offset, buffer, count); 711203319Sweongyo} 712203319Sweongyo 713203319Sweongyostatic void 714203319Sweongyosiba_pci_write_multi_2(struct siba_dev_softc *sd, const void *buffer, 715203319Sweongyo size_t count, uint16_t offset) 716203319Sweongyo{ 717203319Sweongyo struct siba_softc *siba = sd->sd_bus; 718203319Sweongyo 719203319Sweongyo if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0) 720203319Sweongyo return; 721203319Sweongyo 722203319Sweongyo KASSERT(!(count & 1), ("%s:%d: fail", __func__, __LINE__)); 723203319Sweongyo SIBA_WRITE_MULTI_2(siba, offset, buffer, count >> 1); 724203319Sweongyo} 725203319Sweongyo 726203319Sweongyostatic void 727203319Sweongyosiba_pci_write_multi_4(struct siba_dev_softc *sd, const void *buffer, 728203319Sweongyo size_t count, uint16_t offset) 729203319Sweongyo{ 730203319Sweongyo struct siba_softc *siba = sd->sd_bus; 731203319Sweongyo 732203319Sweongyo if (siba->siba_curdev != sd && siba_pci_switchcore(siba, sd) != 0) 733203319Sweongyo return; 734203319Sweongyo 735203319Sweongyo KASSERT(!(count & 3), ("%s:%d: fail", __func__, __LINE__)); 736203319Sweongyo SIBA_WRITE_MULTI_4(siba, offset, buffer, count >> 2); 737203319Sweongyo} 738203319Sweongyo 739203319Sweongyovoid 740203319Sweongyosiba_powerup(struct siba_softc *siba, int dynamic) 741203319Sweongyo{ 742203319Sweongyo 743203319Sweongyo siba_pci_gpio(siba, SIBA_GPIO_CRYSTAL | SIBA_GPIO_PLL, 1); 744203319Sweongyo siba_cc_clock(&siba->siba_cc, 745203319Sweongyo (dynamic != 0) ? SIBA_CLOCK_DYNAMIC : SIBA_CLOCK_FAST); 746203319Sweongyo} 747203319Sweongyo 748203319Sweongyostatic void 749203319Sweongyosiba_cc_clock(struct siba_cc *scc, enum siba_clock clock) 750203319Sweongyo{ 751203319Sweongyo struct siba_dev_softc *sd = scc->scc_dev; 752203319Sweongyo struct siba_softc *siba; 753203319Sweongyo uint32_t tmp; 754203319Sweongyo 755203319Sweongyo if (sd == NULL) 756203319Sweongyo return; 757203319Sweongyo siba = sd->sd_bus; 758203319Sweongyo /* 759203319Sweongyo * chipcommon < r6 (no dynamic clock control) 760203319Sweongyo * chipcommon >= r10 (unknown) 761203319Sweongyo */ 762203319Sweongyo if (sd->sd_id.sd_rev < 6 || sd->sd_id.sd_rev >= 10 || 763203319Sweongyo (scc->scc_caps & SIBA_CC_CAPS_PWCTL) == 0) 764203319Sweongyo return; 765203319Sweongyo 766203319Sweongyo switch (clock) { 767203319Sweongyo case SIBA_CLOCK_DYNAMIC: 768203319Sweongyo tmp = SIBA_CC_READ32(scc, SIBA_CC_CLKSLOW) & 769203319Sweongyo ~(SIBA_CC_CLKSLOW_ENXTAL | SIBA_CC_CLKSLOW_FSLOW | 770203319Sweongyo SIBA_CC_CLKSLOW_IPLL); 771203319Sweongyo if ((tmp & SIBA_CC_CLKSLOW_SRC) != SIBA_CC_CLKSLOW_SRC_CRYSTAL) 772203319Sweongyo tmp |= SIBA_CC_CLKSLOW_ENXTAL; 773203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_CLKSLOW, tmp); 774203319Sweongyo if (tmp & SIBA_CC_CLKSLOW_ENXTAL) 775203319Sweongyo siba_pci_gpio(siba, SIBA_GPIO_CRYSTAL, 0); 776203319Sweongyo break; 777203319Sweongyo case SIBA_CLOCK_SLOW: 778203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_CLKSLOW, 779203319Sweongyo SIBA_CC_READ32(scc, SIBA_CC_CLKSLOW) | 780203319Sweongyo SIBA_CC_CLKSLOW_FSLOW); 781203319Sweongyo break; 782203319Sweongyo case SIBA_CLOCK_FAST: 783203319Sweongyo /* crystal on */ 784203319Sweongyo siba_pci_gpio(siba, SIBA_GPIO_CRYSTAL, 1); 785203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_CLKSLOW, 786203319Sweongyo (SIBA_CC_READ32(scc, SIBA_CC_CLKSLOW) | 787203319Sweongyo SIBA_CC_CLKSLOW_IPLL) & ~SIBA_CC_CLKSLOW_FSLOW); 788203319Sweongyo break; 789203319Sweongyo default: 790203319Sweongyo KASSERT(0 == 1, 791203319Sweongyo ("%s: unsupported clock %#x", __func__, clock)); 792203319Sweongyo } 793203319Sweongyo} 794203319Sweongyo 795203319Sweongyouint16_t 796203319Sweongyosiba_read_2(struct siba_dev_softc *sd, uint16_t offset) 797203319Sweongyo{ 798203319Sweongyo 799203319Sweongyo return (sd->sd_ops->read_2(sd, offset)); 800203319Sweongyo} 801203319Sweongyo 802203319Sweongyouint32_t 803203319Sweongyosiba_read_4(struct siba_dev_softc *sd, uint16_t offset) 804203319Sweongyo{ 805203319Sweongyo 806203319Sweongyo return (sd->sd_ops->read_4(sd, offset)); 807203319Sweongyo} 808203319Sweongyo 809203319Sweongyovoid 810203319Sweongyosiba_write_2(struct siba_dev_softc *sd, uint16_t offset, uint16_t value) 811203319Sweongyo{ 812203319Sweongyo 813203319Sweongyo sd->sd_ops->write_2(sd, offset, value); 814203319Sweongyo} 815203319Sweongyo 816203319Sweongyovoid 817203319Sweongyosiba_write_4(struct siba_dev_softc *sd, uint16_t offset, uint32_t value) 818203319Sweongyo{ 819203319Sweongyo 820203319Sweongyo sd->sd_ops->write_4(sd, offset, value); 821203319Sweongyo} 822203319Sweongyo 823203319Sweongyovoid 824203319Sweongyosiba_read_multi_1(struct siba_dev_softc *sd, void *buffer, size_t count, 825203319Sweongyo uint16_t offset) 826203319Sweongyo{ 827203319Sweongyo 828203319Sweongyo sd->sd_ops->read_multi_1(sd, buffer, count, offset); 829203319Sweongyo} 830203319Sweongyo 831203319Sweongyovoid 832203319Sweongyosiba_read_multi_2(struct siba_dev_softc *sd, void *buffer, size_t count, 833203319Sweongyo uint16_t offset) 834203319Sweongyo{ 835203319Sweongyo 836203319Sweongyo sd->sd_ops->read_multi_2(sd, buffer, count, offset); 837203319Sweongyo} 838203319Sweongyo 839203319Sweongyovoid 840203319Sweongyosiba_read_multi_4(struct siba_dev_softc *sd, void *buffer, size_t count, 841203319Sweongyo uint16_t offset) 842203319Sweongyo{ 843203319Sweongyo 844203319Sweongyo sd->sd_ops->read_multi_4(sd, buffer, count, offset); 845203319Sweongyo} 846203319Sweongyo 847203319Sweongyovoid 848203319Sweongyosiba_write_multi_1(struct siba_dev_softc *sd, const void *buffer, 849203319Sweongyo size_t count, uint16_t offset) 850203319Sweongyo{ 851203319Sweongyo 852203319Sweongyo sd->sd_ops->write_multi_1(sd, buffer, count, offset); 853203319Sweongyo} 854203319Sweongyo 855203319Sweongyovoid 856203319Sweongyosiba_write_multi_2(struct siba_dev_softc *sd, const void *buffer, 857203319Sweongyo size_t count, uint16_t offset) 858203319Sweongyo{ 859203319Sweongyo 860203319Sweongyo sd->sd_ops->write_multi_2(sd, buffer, count, offset); 861203319Sweongyo} 862203319Sweongyo 863203319Sweongyovoid 864203319Sweongyosiba_write_multi_4(struct siba_dev_softc *sd, const void *buffer, 865203319Sweongyo size_t count, uint16_t offset) 866203319Sweongyo{ 867203319Sweongyo 868203319Sweongyo sd->sd_ops->write_multi_4(sd, buffer, count, offset); 869203319Sweongyo} 870203319Sweongyo 871203319Sweongyostatic void 872203319Sweongyosiba_cc_pmu_init(struct siba_cc *scc) 873203319Sweongyo{ 874203319Sweongyo const struct siba_cc_pmu_res_updown *updown = NULL; 875203319Sweongyo const struct siba_cc_pmu_res_depend *depend = NULL; 876203319Sweongyo struct siba_dev_softc *sd = scc->scc_dev; 877203319Sweongyo struct siba_softc *siba = sd->sd_bus; 878203319Sweongyo uint32_t min = 0, max = 0, pmucap; 879203319Sweongyo unsigned int i, updown_size, depend_size; 880203319Sweongyo 881203319Sweongyo if ((scc->scc_caps & SIBA_CC_CAPS_PMU) == 0) 882203319Sweongyo return; 883203319Sweongyo 884203319Sweongyo pmucap = SIBA_CC_READ32(scc, SIBA_CC_PMUCAPS); 885203319Sweongyo scc->scc_pmu.rev = (pmucap & SIBA_CC_PMUCAPS_REV); 886203319Sweongyo 887203319Sweongyo DPRINTF(siba, SIBA_DEBUG_PMU, "PMU(r%u) found (caps %#x)\n", 888203319Sweongyo scc->scc_pmu.rev, pmucap); 889203319Sweongyo 890203319Sweongyo if (scc->scc_pmu.rev >= 1) { 891203319Sweongyo if (siba->siba_chiprev < 2 && siba->siba_chipid == 0x4325) 892203319Sweongyo SIBA_CC_MASK32(scc, SIBA_CC_PMUCTL, 893203319Sweongyo ~SIBA_CC_PMUCTL_NOILP); 894203319Sweongyo else 895203319Sweongyo SIBA_CC_SET32(scc, SIBA_CC_PMUCTL, 896203319Sweongyo SIBA_CC_PMUCTL_NOILP); 897203319Sweongyo } 898203319Sweongyo 899203319Sweongyo /* initialize PLL & PMU resources */ 900203319Sweongyo switch (siba->siba_chipid) { 901203319Sweongyo case 0x4312: 902203319Sweongyo siba_cc_pmu1_pll0_init(scc, 0 /* use default */); 903203319Sweongyo /* use the default: min = 0xcbb max = 0x7ffff */ 904203319Sweongyo break; 905203319Sweongyo case 0x4325: 906203319Sweongyo siba_cc_pmu1_pll0_init(scc, 0 /* use default */); 907203319Sweongyo 908203319Sweongyo updown = siba_cc_pmu_4325_updown; 909203319Sweongyo updown_size = N(siba_cc_pmu_4325_updown); 910203319Sweongyo depend = siba_cc_pmu_4325_depend; 911203319Sweongyo depend_size = N(siba_cc_pmu_4325_depend); 912203319Sweongyo 913203319Sweongyo min = (1 << SIBA_CC_PMU_4325_BURST) | 914203319Sweongyo (1 << SIBA_CC_PMU_4325_LN); 915203319Sweongyo if (SIBA_CC_READ32(scc, SIBA_CC_CHIPSTAT) & 916203319Sweongyo SIBA_CC_CHST_4325_PMUTOP_2B) 917203319Sweongyo min |= (1 << SIBA_CC_PMU_4325_CLBURST); 918203319Sweongyo max = 0xfffff; 919203319Sweongyo break; 920203319Sweongyo case 0x4328: 921203319Sweongyo siba_cc_pmu0_pll0_init(scc, 0 /* use default */); 922203319Sweongyo 923203319Sweongyo updown = siba_cc_pmu_4328_updown; 924203319Sweongyo updown_size = N(siba_cc_pmu_4328_updown); 925203319Sweongyo depend = siba_cc_pmu_4328_depend; 926203319Sweongyo depend_size = N(siba_cc_pmu_4328_depend); 927203319Sweongyo 928203319Sweongyo min = (1 << SIBA_CC_PMU_4328_EXT_SWITCH_PWM) | 929203319Sweongyo (1 << SIBA_CC_PMU_4328_BB_SWITCH_PWM) | 930203319Sweongyo (1 << SIBA_CC_PMU_4328_CRYSTAL_EN); 931203319Sweongyo 932203319Sweongyo max = 0xfffff; 933203319Sweongyo break; 934203319Sweongyo case 0x5354: 935203319Sweongyo siba_cc_pmu0_pll0_init(scc, 0 /* use default */); 936203319Sweongyo 937203319Sweongyo max = 0xfffff; 938203319Sweongyo break; 939203319Sweongyo default: 940203319Sweongyo device_printf(siba->siba_dev, 941203319Sweongyo "unknown chipid %#x for PLL & PMU init\n", 942203319Sweongyo siba->siba_chipid); 943203319Sweongyo } 944203319Sweongyo 945203319Sweongyo if (updown) { 946203319Sweongyo for (i = 0; i < updown_size; i++) { 947203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PMU_TABSEL, 948203319Sweongyo updown[i].res); 949203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PMU_UPDNTM, 950203319Sweongyo updown[i].updown); 951203319Sweongyo } 952203319Sweongyo } 953203319Sweongyo if (depend) { 954203319Sweongyo for (i = 0; i < depend_size; i++) { 955203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PMU_TABSEL, 956203319Sweongyo depend[i].res); 957203319Sweongyo switch (depend[i].task) { 958203319Sweongyo case SIBA_CC_PMU_DEP_SET: 959203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PMU_DEPMSK, 960203319Sweongyo depend[i].depend); 961203319Sweongyo break; 962203319Sweongyo case SIBA_CC_PMU_DEP_ADD: 963203319Sweongyo SIBA_CC_SET32(scc, SIBA_CC_PMU_DEPMSK, 964203319Sweongyo depend[i].depend); 965203319Sweongyo break; 966203319Sweongyo case SIBA_CC_PMU_DEP_REMOVE: 967203319Sweongyo SIBA_CC_MASK32(scc, SIBA_CC_PMU_DEPMSK, 968203319Sweongyo ~(depend[i].depend)); 969203319Sweongyo break; 970203319Sweongyo default: 971203319Sweongyo KASSERT(0 == 1, 972203319Sweongyo ("%s:%d: assertion failed", 973203319Sweongyo __func__, __LINE__)); 974203319Sweongyo } 975203319Sweongyo } 976203319Sweongyo } 977203319Sweongyo 978203319Sweongyo if (min) 979203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PMU_MINRES, min); 980203319Sweongyo if (max) 981203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PMU_MAXRES, max); 982203319Sweongyo} 983203319Sweongyo 984203319Sweongyostatic void 985203319Sweongyosiba_cc_power_init(struct siba_cc *scc) 986203319Sweongyo{ 987203319Sweongyo struct siba_softc *siba = scc->scc_dev->sd_bus; 988203319Sweongyo int maxfreq; 989203319Sweongyo 990203319Sweongyo if (siba->siba_chipid == 0x4321) { 991203319Sweongyo if (siba->siba_chiprev == 0) 992203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_CHIPCTL, 0x3a4); 993203319Sweongyo else if (siba->siba_chiprev == 1) 994203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_CHIPCTL, 0xa4); 995203319Sweongyo } 996203319Sweongyo 997203319Sweongyo if ((scc->scc_caps & SIBA_CC_CAPS_PWCTL) == 0) 998203319Sweongyo return; 999203319Sweongyo 1000203319Sweongyo if (scc->scc_dev->sd_id.sd_rev >= 10) 1001203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_CLKSYSCTL, 1002203319Sweongyo (SIBA_CC_READ32(scc, SIBA_CC_CLKSYSCTL) & 1003203319Sweongyo 0xffff) | 0x40000); 1004203319Sweongyo else { 1005203319Sweongyo maxfreq = siba_cc_clockfreq(scc, 1); 1006203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PLLONDELAY, 1007203319Sweongyo (maxfreq * 150 + 999999) / 1000000); 1008203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_FREFSELDELAY, 1009203319Sweongyo (maxfreq * 15 + 999999) / 1000000); 1010203319Sweongyo } 1011203319Sweongyo} 1012203319Sweongyo 1013203319Sweongyostatic void 1014203319Sweongyosiba_cc_powerup_delay(struct siba_cc *scc) 1015203319Sweongyo{ 1016203319Sweongyo struct siba_softc *siba = scc->scc_dev->sd_bus; 1017203319Sweongyo int min; 1018203319Sweongyo 1019203319Sweongyo if (siba->siba_type != SIBA_TYPE_PCI || 1020203319Sweongyo !(scc->scc_caps & SIBA_CC_CAPS_PWCTL)) 1021203319Sweongyo return; 1022203319Sweongyo 1023203319Sweongyo min = siba_cc_clockfreq(scc, 0); 1024203319Sweongyo scc->scc_powerup_delay = 1025203319Sweongyo (((SIBA_CC_READ32(scc, SIBA_CC_PLLONDELAY) + 2) * 1000000) + 1026203319Sweongyo (min - 1)) / min; 1027203319Sweongyo} 1028203319Sweongyo 1029203319Sweongyostatic int 1030203319Sweongyosiba_cc_clockfreq(struct siba_cc *scc, int max) 1031203319Sweongyo{ 1032203319Sweongyo enum siba_clksrc src; 1033203319Sweongyo int div = 1, limit = 0; 1034203319Sweongyo 1035203319Sweongyo src = siba_cc_clksrc(scc); 1036203319Sweongyo if (scc->scc_dev->sd_id.sd_rev < 6) { 1037203319Sweongyo div = (src == SIBA_CC_CLKSRC_PCI) ? 64 : 1038203319Sweongyo (src == SIBA_CC_CLKSRC_CRYSTAL) ? 32 : 1; 1039203319Sweongyo KASSERT(div != 1, 1040203319Sweongyo ("%s: unknown clock %d", __func__, src)); 1041203319Sweongyo } else if (scc->scc_dev->sd_id.sd_rev < 10) { 1042203319Sweongyo switch (src) { 1043203319Sweongyo case SIBA_CC_CLKSRC_CRYSTAL: 1044203319Sweongyo case SIBA_CC_CLKSRC_PCI: 1045203319Sweongyo div = ((SIBA_CC_READ32(scc, SIBA_CC_CLKSLOW) >> 16) + 1046203319Sweongyo 1) * 4; 1047203319Sweongyo break; 1048203319Sweongyo case SIBA_CC_CLKSRC_LOWPW: 1049203319Sweongyo break; 1050203319Sweongyo } 1051203319Sweongyo } else 1052203319Sweongyo div = ((SIBA_CC_READ32(scc, SIBA_CC_CLKSYSCTL) >> 16) + 1) * 4; 1053203319Sweongyo 1054203319Sweongyo switch (src) { 1055203319Sweongyo case SIBA_CC_CLKSRC_CRYSTAL: 1056203319Sweongyo limit = (max) ? 20200000 : 19800000; 1057203319Sweongyo break; 1058203319Sweongyo case SIBA_CC_CLKSRC_LOWPW: 1059203319Sweongyo limit = (max) ? 43000 : 25000; 1060203319Sweongyo break; 1061203319Sweongyo case SIBA_CC_CLKSRC_PCI: 1062203319Sweongyo limit = (max) ? 34000000 : 25000000; 1063203319Sweongyo break; 1064203319Sweongyo } 1065203319Sweongyo 1066203319Sweongyo return (limit / div); 1067203319Sweongyo} 1068203319Sweongyo 1069203319Sweongyostatic void 1070203319Sweongyosiba_cc_pmu1_pll0_init(struct siba_cc *scc, uint32_t freq) 1071203319Sweongyo{ 1072203319Sweongyo struct siba_dev_softc *sd = scc->scc_dev; 1073203319Sweongyo struct siba_softc *siba = sd->sd_bus; 1074203319Sweongyo const struct siba_cc_pmu1_plltab *e = NULL; 1075203319Sweongyo uint32_t bufsth = 0, pll, pmu; 1076203319Sweongyo unsigned int i; 1077203319Sweongyo 1078203319Sweongyo KASSERT(freq == 0, ("%s:%d: assertion vail", __func__, __LINE__)); 1079203319Sweongyo if (siba->siba_chipid == 0x4312) { 1080203319Sweongyo scc->scc_pmu.freq = 20000; 1081203319Sweongyo return; 1082203319Sweongyo } 1083203319Sweongyo 1084203319Sweongyo e = siba_cc_pmu1_plltab_find(SIBA_CC_PMU1_DEFAULT_FREQ); 1085203319Sweongyo KASSERT(e != NULL, ("%s:%d: assertion vail", __func__, __LINE__)); 1086203319Sweongyo scc->scc_pmu.freq = e->freq; 1087203319Sweongyo 1088203319Sweongyo pmu = SIBA_CC_READ32(scc, SIBA_CC_PMUCTL); 1089203319Sweongyo if (SIBA_CC_PMUCTL_XF_VAL(pmu) == e->xf) 1090203319Sweongyo return; 1091203319Sweongyo 1092203319Sweongyo DPRINTF(siba, SIBA_DEBUG_PLL, "change PLL value to %u.%03u MHz\n", 1093203319Sweongyo (e->freq / 1000), (e->freq % 1000)); 1094203319Sweongyo 1095203319Sweongyo /* turn PLL off */ 1096203319Sweongyo switch (siba->siba_chipid) { 1097203319Sweongyo case 0x4325: 1098203319Sweongyo bufsth = 0x222222; 1099203319Sweongyo SIBA_CC_MASK32(scc, SIBA_CC_PMU_MINRES, 1100203319Sweongyo ~((1 << SIBA_CC_PMU_4325_BBPLL_PWR) | 1101203319Sweongyo (1 << SIBA_CC_PMU_4325_HT))); 1102203319Sweongyo SIBA_CC_MASK32(scc, SIBA_CC_PMU_MAXRES, 1103203319Sweongyo ~((1 << SIBA_CC_PMU_4325_BBPLL_PWR) | 1104203319Sweongyo (1 << SIBA_CC_PMU_4325_HT))); 1105203319Sweongyo break; 1106203319Sweongyo default: 1107203319Sweongyo KASSERT(0 == 1, 1108203319Sweongyo ("%s:%d: assertion failed", __func__, __LINE__)); 1109203319Sweongyo } 1110203319Sweongyo for (i = 0; i < 1500; i++) { 1111203319Sweongyo if (!(SIBA_CC_READ32(scc, SIBA_CC_CLKCTLSTATUS) & 1112203319Sweongyo SIBA_CC_CLKCTLSTATUS_HT)) 1113203319Sweongyo break; 1114203319Sweongyo DELAY(10); 1115203319Sweongyo } 1116203319Sweongyo if (SIBA_CC_READ32(scc, SIBA_CC_CLKCTLSTATUS) & SIBA_CC_CLKCTLSTATUS_HT) 1117203319Sweongyo device_printf(siba->siba_dev, "failed to turn PLL off!\n"); 1118203319Sweongyo 1119203319Sweongyo pll = siba_cc_pll_read(scc, SIBA_CC_PMU1_PLL0); 1120203319Sweongyo pll &= ~(SIBA_CC_PMU1_PLL0_P1DIV | SIBA_CC_PMU1_PLL0_P2DIV); 1121203319Sweongyo pll |= ((uint32_t)e->p1div << 20) & SIBA_CC_PMU1_PLL0_P1DIV; 1122203319Sweongyo pll |= ((uint32_t)e->p2div << 24) & SIBA_CC_PMU1_PLL0_P2DIV; 1123203319Sweongyo siba_cc_pll_write(scc, SIBA_CC_PMU1_PLL0, pll); 1124203319Sweongyo 1125203319Sweongyo pll = siba_cc_pll_read(scc, SIBA_CC_PMU1_PLL2); 1126203319Sweongyo pll &= ~(SIBA_CC_PMU1_PLL2_NDIVINT | SIBA_CC_PMU1_PLL2_NDIVMODE); 1127203319Sweongyo pll |= ((uint32_t)e->ndiv_int << 20) & SIBA_CC_PMU1_PLL2_NDIVINT; 1128203319Sweongyo pll |= (1 << 17) & SIBA_CC_PMU1_PLL2_NDIVMODE; 1129203319Sweongyo siba_cc_pll_write(scc, SIBA_CC_PMU1_PLL2, pll); 1130203319Sweongyo 1131203319Sweongyo pll = siba_cc_pll_read(scc, SIBA_CC_PMU1_PLL3); 1132203319Sweongyo pll &= ~SIBA_CC_PMU1_PLL3_NDIVFRAC; 1133203319Sweongyo pll |= ((uint32_t)e->ndiv_frac << 0) & SIBA_CC_PMU1_PLL3_NDIVFRAC; 1134203319Sweongyo siba_cc_pll_write(scc, SIBA_CC_PMU1_PLL3, pll); 1135203319Sweongyo 1136203319Sweongyo if (bufsth) { 1137203319Sweongyo pll = siba_cc_pll_read(scc, SIBA_CC_PMU1_PLL5); 1138203319Sweongyo pll &= ~SIBA_CC_PMU1_PLL5_CLKDRV; 1139203319Sweongyo pll |= (bufsth << 8) & SIBA_CC_PMU1_PLL5_CLKDRV; 1140203319Sweongyo siba_cc_pll_write(scc, SIBA_CC_PMU1_PLL5, pll); 1141203319Sweongyo } 1142203319Sweongyo 1143203319Sweongyo pmu = SIBA_CC_READ32(scc, SIBA_CC_PMUCTL); 1144203319Sweongyo pmu &= ~(SIBA_CC_PMUCTL_ILP | SIBA_CC_PMUCTL_XF); 1145203319Sweongyo pmu |= ((((uint32_t)e->freq + 127) / 128 - 1) << 16) & 1146203319Sweongyo SIBA_CC_PMUCTL_ILP; 1147203319Sweongyo pmu |= ((uint32_t)e->xf << 2) & SIBA_CC_PMUCTL_XF; 1148203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PMUCTL, pmu); 1149203319Sweongyo} 1150203319Sweongyo 1151203319Sweongyostatic void 1152203319Sweongyosiba_cc_pmu0_pll0_init(struct siba_cc *scc, uint32_t xtalfreq) 1153203319Sweongyo{ 1154203319Sweongyo struct siba_dev_softc *sd = scc->scc_dev; 1155203319Sweongyo struct siba_softc *siba = sd->sd_bus; 1156203319Sweongyo const struct siba_cc_pmu0_plltab *e = NULL; 1157203319Sweongyo uint32_t pmu, tmp, pll; 1158203319Sweongyo unsigned int i; 1159203319Sweongyo 1160203319Sweongyo if ((siba->siba_chipid == 0x5354) && !xtalfreq) 1161203319Sweongyo xtalfreq = 25000; 1162203319Sweongyo if (xtalfreq) 1163203319Sweongyo e = siba_cc_pmu0_plltab_findentry(xtalfreq); 1164203319Sweongyo if (!e) 1165203319Sweongyo e = siba_cc_pmu0_plltab_findentry( 1166203319Sweongyo SIBA_CC_PMU0_DEFAULT_XTALFREQ); 1167203319Sweongyo KASSERT(e != NULL, ("%s:%d: fail", __func__, __LINE__)); 1168203319Sweongyo xtalfreq = e->freq; 1169203319Sweongyo scc->scc_pmu.freq = e->freq; 1170203319Sweongyo 1171203319Sweongyo pmu = SIBA_CC_READ32(scc, SIBA_CC_PMUCTL); 1172203319Sweongyo if (((pmu & SIBA_CC_PMUCTL_XF) >> 2) == e->xf) 1173203319Sweongyo return; 1174203319Sweongyo 1175203319Sweongyo DPRINTF(siba, SIBA_DEBUG_PLL, "change PLL value to %u.%03u mhz\n", 1176203319Sweongyo (xtalfreq / 1000), (xtalfreq % 1000)); 1177203319Sweongyo 1178203319Sweongyo KASSERT(siba->siba_chipid == 0x4328 || siba->siba_chipid == 0x5354, 1179203319Sweongyo ("%s:%d: fail", __func__, __LINE__)); 1180203319Sweongyo 1181203319Sweongyo switch (siba->siba_chipid) { 1182203319Sweongyo case 0x4328: 1183203319Sweongyo SIBA_CC_MASK32(scc, SIBA_CC_PMU_MINRES, 1184203319Sweongyo ~(1 << SIBA_CC_PMU_4328_BB_PLL_PU)); 1185203319Sweongyo SIBA_CC_MASK32(scc, SIBA_CC_PMU_MAXRES, 1186203319Sweongyo ~(1 << SIBA_CC_PMU_4328_BB_PLL_PU)); 1187203319Sweongyo break; 1188203319Sweongyo case 0x5354: 1189203319Sweongyo SIBA_CC_MASK32(scc, SIBA_CC_PMU_MINRES, 1190203319Sweongyo ~(1 << SIBA_CC_PMU_5354_BB_PLL_PU)); 1191203319Sweongyo SIBA_CC_MASK32(scc, SIBA_CC_PMU_MAXRES, 1192203319Sweongyo ~(1 << SIBA_CC_PMU_5354_BB_PLL_PU)); 1193203319Sweongyo break; 1194203319Sweongyo } 1195203319Sweongyo for (i = 1500; i; i--) { 1196203319Sweongyo tmp = SIBA_CC_READ32(scc, SIBA_CC_CLKCTLSTATUS); 1197203319Sweongyo if (!(tmp & SIBA_CC_CLKCTLSTATUS_HT)) 1198203319Sweongyo break; 1199203319Sweongyo DELAY(10); 1200203319Sweongyo } 1201203319Sweongyo tmp = SIBA_CC_READ32(scc, SIBA_CC_CLKCTLSTATUS); 1202203319Sweongyo if (tmp & SIBA_CC_CLKCTLSTATUS_HT) 1203203319Sweongyo device_printf(siba->siba_dev, "failed to turn PLL off!\n"); 1204203319Sweongyo 1205203319Sweongyo /* set PDIV */ 1206203319Sweongyo pll = siba_cc_pll_read(scc, SIBA_CC_PMU0_PLL0); 1207203319Sweongyo if (xtalfreq >= SIBA_CC_PMU0_PLL0_PDIV_FREQ) 1208203319Sweongyo pll |= SIBA_CC_PMU0_PLL0_PDIV_MSK; 1209203319Sweongyo else 1210203319Sweongyo pll &= ~SIBA_CC_PMU0_PLL0_PDIV_MSK; 1211203319Sweongyo siba_cc_pll_write(scc, SIBA_CC_PMU0_PLL0, pll); 1212203319Sweongyo 1213203319Sweongyo /* set WILD */ 1214203319Sweongyo pll = siba_cc_pll_read(scc, SIBA_CC_PMU0_PLL1); 1215203319Sweongyo pll &= ~(SIBA_CC_PMU0_PLL1_STOPMOD | SIBA_CC_PMU0_PLL1_IMSK | 1216203319Sweongyo SIBA_CC_PMU0_PLL1_FMSK); 1217203319Sweongyo pll |= ((uint32_t)e->wb_int << 28) & SIBA_CC_PMU0_PLL1_IMSK; 1218203319Sweongyo pll |= ((uint32_t)e->wb_frac << 8) & SIBA_CC_PMU0_PLL1_FMSK; 1219203319Sweongyo if (e->wb_frac == 0) 1220203319Sweongyo pll |= SIBA_CC_PMU0_PLL1_STOPMOD; 1221203319Sweongyo siba_cc_pll_write(scc, SIBA_CC_PMU0_PLL1, pll); 1222203319Sweongyo 1223203319Sweongyo /* set WILD */ 1224203319Sweongyo pll = siba_cc_pll_read(scc, SIBA_CC_PMU0_PLL2); 1225203319Sweongyo pll &= ~SIBA_CC_PMU0_PLL2_IMSKHI; 1226203319Sweongyo pll |= (((uint32_t)e->wb_int >> 4) << 0) & SIBA_CC_PMU0_PLL2_IMSKHI; 1227203319Sweongyo siba_cc_pll_write(scc, SIBA_CC_PMU0_PLL2, pll); 1228203319Sweongyo 1229203319Sweongyo /* set freq and divisor. */ 1230203319Sweongyo pmu = SIBA_CC_READ32(scc, SIBA_CC_PMUCTL); 1231203319Sweongyo pmu &= ~SIBA_CC_PMUCTL_ILP; 1232203319Sweongyo pmu |= (((xtalfreq + 127) / 128 - 1) << 16) & SIBA_CC_PMUCTL_ILP; 1233203319Sweongyo pmu &= ~SIBA_CC_PMUCTL_XF; 1234203319Sweongyo pmu |= ((uint32_t)e->xf << 2) & SIBA_CC_PMUCTL_XF; 1235203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PMUCTL, pmu); 1236203319Sweongyo} 1237203319Sweongyo 1238203319Sweongyostatic enum siba_clksrc 1239203319Sweongyosiba_cc_clksrc(struct siba_cc *scc) 1240203319Sweongyo{ 1241203319Sweongyo struct siba_dev_softc *sd = scc->scc_dev; 1242203319Sweongyo struct siba_softc *siba = sd->sd_bus; 1243203319Sweongyo 1244203319Sweongyo if (sd->sd_id.sd_rev < 6) { 1245203319Sweongyo if (siba->siba_type == SIBA_TYPE_PCI) { 1246203319Sweongyo if (pci_read_config(siba->siba_dev, SIBA_GPIO_OUT, 4) & 1247203319Sweongyo 0x10) 1248203319Sweongyo return (SIBA_CC_CLKSRC_PCI); 1249203319Sweongyo return (SIBA_CC_CLKSRC_CRYSTAL); 1250203319Sweongyo } 1251203319Sweongyo if (siba->siba_type == SIBA_TYPE_SSB || 1252203319Sweongyo siba->siba_type == SIBA_TYPE_PCMCIA) 1253203319Sweongyo return (SIBA_CC_CLKSRC_CRYSTAL); 1254203319Sweongyo } 1255203319Sweongyo if (sd->sd_id.sd_rev < 10) { 1256203319Sweongyo switch (SIBA_CC_READ32(scc, SIBA_CC_CLKSLOW) & 0x7) { 1257203319Sweongyo case 0: 1258203319Sweongyo return (SIBA_CC_CLKSRC_LOWPW); 1259203319Sweongyo case 1: 1260203319Sweongyo return (SIBA_CC_CLKSRC_CRYSTAL); 1261203319Sweongyo case 2: 1262203319Sweongyo return (SIBA_CC_CLKSRC_PCI); 1263203319Sweongyo default: 1264203319Sweongyo break; 1265203319Sweongyo } 1266203319Sweongyo } 1267203319Sweongyo 1268203319Sweongyo return (SIBA_CC_CLKSRC_CRYSTAL); 1269203319Sweongyo} 1270203319Sweongyo 1271203319Sweongyostatic const struct siba_cc_pmu1_plltab * 1272203319Sweongyosiba_cc_pmu1_plltab_find(uint32_t crystalfreq) 1273203319Sweongyo{ 1274203319Sweongyo const struct siba_cc_pmu1_plltab *e; 1275203319Sweongyo unsigned int i; 1276203319Sweongyo 1277203319Sweongyo for (i = 0; i < N(siba_cc_pmu1_plltab); i++) { 1278203319Sweongyo e = &siba_cc_pmu1_plltab[i]; 1279203319Sweongyo if (crystalfreq == e->freq) 1280203319Sweongyo return (e); 1281203319Sweongyo } 1282203319Sweongyo 1283203319Sweongyo return (NULL); 1284203319Sweongyo} 1285203319Sweongyo 1286203319Sweongyostatic uint32_t 1287203319Sweongyosiba_cc_pll_read(struct siba_cc *scc, uint32_t offset) 1288203319Sweongyo{ 1289203319Sweongyo 1290203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PLLCTL_ADDR, offset); 1291203319Sweongyo return (SIBA_CC_READ32(scc, SIBA_CC_PLLCTL_DATA)); 1292203319Sweongyo} 1293203319Sweongyo 1294203319Sweongyostatic void 1295203319Sweongyosiba_cc_pll_write(struct siba_cc *scc, uint32_t offset, uint32_t value) 1296203319Sweongyo{ 1297203319Sweongyo 1298203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PLLCTL_ADDR, offset); 1299203319Sweongyo SIBA_CC_WRITE32(scc, SIBA_CC_PLLCTL_DATA, value); 1300203319Sweongyo} 1301203319Sweongyo 1302203319Sweongyostatic const struct siba_cc_pmu0_plltab * 1303203319Sweongyosiba_cc_pmu0_plltab_findentry(uint32_t crystalfreq) 1304203319Sweongyo{ 1305203319Sweongyo const struct siba_cc_pmu0_plltab *e; 1306203319Sweongyo unsigned int i; 1307203319Sweongyo 1308203319Sweongyo for (i = 0; i < N(siba_cc_pmu0_plltab); i++) { 1309203319Sweongyo e = &siba_cc_pmu0_plltab[i]; 1310203319Sweongyo if (e->freq == crystalfreq) 1311203319Sweongyo return (e); 1312203319Sweongyo } 1313203319Sweongyo 1314203319Sweongyo return (NULL); 1315203319Sweongyo} 1316203319Sweongyo 1317203319Sweongyostatic int 1318203319Sweongyosiba_pci_sprom(struct siba_softc *siba, struct siba_sprom *sprom) 1319203319Sweongyo{ 1320203319Sweongyo int error = ENOMEM; 1321203319Sweongyo uint16_t *buf; 1322203319Sweongyo 1323203319Sweongyo buf = malloc(SIBA_SPROMSIZE_R123 * sizeof(uint16_t), 1324203319Sweongyo M_DEVBUF, M_NOWAIT | M_ZERO); 1325203319Sweongyo if (buf == NULL) 1326203319Sweongyo return (ENOMEM); 1327203319Sweongyo siba_sprom_read(siba, buf, SIBA_SPROMSIZE_R123); 1328203319Sweongyo error = sprom_check_crc(buf, siba->siba_spromsize); 1329203319Sweongyo if (error) { 1330203319Sweongyo free(buf, M_DEVBUF); 1331203319Sweongyo buf = malloc(SIBA_SPROMSIZE_R4 * sizeof(uint16_t), 1332203319Sweongyo M_DEVBUF, M_NOWAIT | M_ZERO); 1333203319Sweongyo if (buf == NULL) 1334203319Sweongyo return (ENOMEM); 1335203319Sweongyo siba_sprom_read(siba, buf, SIBA_SPROMSIZE_R4); 1336203319Sweongyo error = sprom_check_crc(buf, siba->siba_spromsize); 1337203319Sweongyo if (error) 1338203319Sweongyo device_printf(siba->siba_dev, "warn: bad SPROM CRC\n"); 1339203319Sweongyo } 1340203319Sweongyo 1341203319Sweongyo bzero(sprom, sizeof(*sprom)); 1342203319Sweongyo 1343203319Sweongyo sprom->rev = buf[siba->siba_spromsize - 1] & 0x00FF; 1344203319Sweongyo DPRINTF(siba, SIBA_DEBUG_SPROM, "SPROM rev %d\n", 1345203319Sweongyo sprom->rev); 1346203319Sweongyo memset(sprom->mac_eth, 0xff, 6); 1347203319Sweongyo memset(sprom->mac_80211a, 0xff, 6); 1348203319Sweongyo if ((siba->siba_chipid & 0xff00) == 0x4400) { 1349203319Sweongyo sprom->rev = 1; 1350203319Sweongyo siba_sprom_r123(sprom, buf); 1351203319Sweongyo } else if (siba->siba_chipid == 0x4321) { 1352203319Sweongyo sprom->rev = 4; 1353203319Sweongyo siba_sprom_r45(sprom, buf); 1354203319Sweongyo } else { 1355203319Sweongyo switch (sprom->rev) { 1356203319Sweongyo case 1: 1357203319Sweongyo case 2: 1358203319Sweongyo case 3: 1359203319Sweongyo siba_sprom_r123(sprom, buf); 1360203319Sweongyo break; 1361203319Sweongyo case 4: 1362203319Sweongyo case 5: 1363203319Sweongyo siba_sprom_r45(sprom, buf); 1364203319Sweongyo break; 1365203319Sweongyo case 8: 1366203319Sweongyo siba_sprom_r8(sprom, buf); 1367203319Sweongyo break; 1368203319Sweongyo default: 1369203319Sweongyo device_printf(siba->siba_dev, 1370203319Sweongyo "unknown SPROM revision %d.\n", sprom->rev); 1371203319Sweongyo siba_sprom_r123(sprom, buf); 1372203319Sweongyo } 1373203319Sweongyo } 1374203319Sweongyo 1375203319Sweongyo if (sprom->bf_lo == 0xffff) 1376203319Sweongyo sprom->bf_lo = 0; 1377203319Sweongyo if (sprom->bf_hi == 0xffff) 1378203319Sweongyo sprom->bf_hi = 0; 1379203319Sweongyo 1380203319Sweongyo free(buf, M_DEVBUF); 1381203319Sweongyo return (error); 1382203319Sweongyo} 1383203319Sweongyo 1384203319Sweongyostatic int 1385203319Sweongyosiba_sprom_read(struct siba_softc *siba, uint16_t *sprom, uint16_t len) 1386203319Sweongyo{ 1387203319Sweongyo int i; 1388203319Sweongyo 1389203319Sweongyo for (i = 0; i < len; i++) 1390203319Sweongyo sprom[i] = SIBA_READ_2(siba, SIBA_SPROM_BASE + (i * 2)); 1391203319Sweongyo 1392203319Sweongyo siba->siba_spromsize = len; 1393203319Sweongyo return (0); 1394203319Sweongyo} 1395203319Sweongyo 1396203319Sweongyostatic int 1397203319Sweongyosprom_check_crc(const uint16_t *sprom, size_t size) 1398203319Sweongyo{ 1399203319Sweongyo int word; 1400203319Sweongyo uint8_t crc0, crc1 = 0xff; 1401203319Sweongyo 1402203319Sweongyo crc0 = (sprom[size - 1] & SIBA_SPROM_REV_CRC) >> 8; 1403203319Sweongyo for (word = 0; word < size - 1; word++) { 1404203319Sweongyo crc1 = siba_crc8(crc1, sprom[word] & 0x00ff); 1405203319Sweongyo crc1 = siba_crc8(crc1, (sprom[word] & 0xff00) >> 8); 1406203319Sweongyo } 1407203319Sweongyo crc1 = siba_crc8(crc1, sprom[size - 1] & 0x00ff); 1408203319Sweongyo crc1 ^= 0xff; 1409203319Sweongyo 1410203319Sweongyo return ((crc0 != crc1) ? EPROTO : 0); 1411203319Sweongyo} 1412203319Sweongyo 1413203319Sweongyostatic uint8_t 1414203319Sweongyosiba_crc8(uint8_t crc, uint8_t data) 1415203319Sweongyo{ 1416203319Sweongyo static const uint8_t ct[] = { 1417203319Sweongyo 0x00, 0xf7, 0xb9, 0x4e, 0x25, 0xd2, 0x9c, 0x6b, 1418203319Sweongyo 0x4a, 0xbd, 0xf3, 0x04, 0x6f, 0x98, 0xd6, 0x21, 1419203319Sweongyo 0x94, 0x63, 0x2d, 0xda, 0xb1, 0x46, 0x08, 0xff, 1420203319Sweongyo 0xde, 0x29, 0x67, 0x90, 0xfb, 0x0c, 0x42, 0xb5, 1421203319Sweongyo 0x7f, 0x88, 0xc6, 0x31, 0x5a, 0xad, 0xe3, 0x14, 1422203319Sweongyo 0x35, 0xc2, 0x8c, 0x7b, 0x10, 0xe7, 0xa9, 0x5e, 1423203319Sweongyo 0xeb, 0x1c, 0x52, 0xa5, 0xce, 0x39, 0x77, 0x80, 1424203319Sweongyo 0xa1, 0x56, 0x18, 0xef, 0x84, 0x73, 0x3d, 0xca, 1425203319Sweongyo 0xfe, 0x09, 0x47, 0xb0, 0xdb, 0x2c, 0x62, 0x95, 1426203319Sweongyo 0xb4, 0x43, 0x0d, 0xfa, 0x91, 0x66, 0x28, 0xdf, 1427203319Sweongyo 0x6a, 0x9d, 0xd3, 0x24, 0x4f, 0xb8, 0xf6, 0x01, 1428203319Sweongyo 0x20, 0xd7, 0x99, 0x6e, 0x05, 0xf2, 0xbc, 0x4b, 1429203319Sweongyo 0x81, 0x76, 0x38, 0xcf, 0xa4, 0x53, 0x1d, 0xea, 1430203319Sweongyo 0xcb, 0x3c, 0x72, 0x85, 0xee, 0x19, 0x57, 0xa0, 1431203319Sweongyo 0x15, 0xe2, 0xac, 0x5b, 0x30, 0xc7, 0x89, 0x7e, 1432203319Sweongyo 0x5f, 0xa8, 0xe6, 0x11, 0x7a, 0x8d, 0xc3, 0x34, 1433203319Sweongyo 0xab, 0x5c, 0x12, 0xe5, 0x8e, 0x79, 0x37, 0xc0, 1434203319Sweongyo 0xe1, 0x16, 0x58, 0xaf, 0xc4, 0x33, 0x7d, 0x8a, 1435203319Sweongyo 0x3f, 0xc8, 0x86, 0x71, 0x1a, 0xed, 0xa3, 0x54, 1436203319Sweongyo 0x75, 0x82, 0xcc, 0x3b, 0x50, 0xa7, 0xe9, 0x1e, 1437203319Sweongyo 0xd4, 0x23, 0x6d, 0x9a, 0xf1, 0x06, 0x48, 0xbf, 1438203319Sweongyo 0x9e, 0x69, 0x27, 0xd0, 0xbb, 0x4c, 0x02, 0xf5, 1439203319Sweongyo 0x40, 0xb7, 0xf9, 0x0e, 0x65, 0x92, 0xdc, 0x2b, 1440203319Sweongyo 0x0a, 0xfd, 0xb3, 0x44, 0x2f, 0xd8, 0x96, 0x61, 1441203319Sweongyo 0x55, 0xa2, 0xec, 0x1b, 0x70, 0x87, 0xc9, 0x3e, 1442203319Sweongyo 0x1f, 0xe8, 0xa6, 0x51, 0x3a, 0xcd, 0x83, 0x74, 1443203319Sweongyo 0xc1, 0x36, 0x78, 0x8f, 0xe4, 0x13, 0x5d, 0xaa, 1444203319Sweongyo 0x8b, 0x7c, 0x32, 0xc5, 0xae, 0x59, 0x17, 0xe0, 1445203319Sweongyo 0x2a, 0xdd, 0x93, 0x64, 0x0f, 0xf8, 0xb6, 0x41, 1446203319Sweongyo 0x60, 0x97, 0xd9, 0x2e, 0x45, 0xb2, 0xfc, 0x0b, 1447203319Sweongyo 0xbe, 0x49, 0x07, 0xf0, 0x9b, 0x6c, 0x22, 0xd5, 1448203319Sweongyo 0xf4, 0x03, 0x4d, 0xba, 0xd1, 0x26, 0x68, 0x9f, 1449203319Sweongyo }; 1450203319Sweongyo return (ct[crc ^ data]); 1451203319Sweongyo} 1452203319Sweongyo 1453203319Sweongyo#define SIBA_LOWEST_SET_BIT(__mask) ((((__mask) - 1) & (__mask)) ^ (__mask)) 1454203319Sweongyo#define SIBA_OFFSET(offset) \ 1455203319Sweongyo (((offset) - SIBA_SPROM_BASE) / sizeof(uint16_t)) 1456203319Sweongyo#define SIBA_SHIFTOUT_SUB(__x, __mask) \ 1457203319Sweongyo (((__x) & (__mask)) / SIBA_LOWEST_SET_BIT(__mask)) 1458203319Sweongyo#define SIBA_SHIFTOUT(_var, _offset, _mask) \ 1459203319Sweongyo out->_var = SIBA_SHIFTOUT_SUB(in[SIBA_OFFSET(_offset)], (_mask)) 1460203319Sweongyo 1461203319Sweongyostatic void 1462203319Sweongyosiba_sprom_r123(struct siba_sprom *out, const uint16_t *in) 1463203319Sweongyo{ 1464203319Sweongyo int i; 1465203319Sweongyo uint16_t v; 1466203319Sweongyo int8_t gain; 1467203319Sweongyo uint16_t loc[3]; 1468203319Sweongyo 1469203319Sweongyo if (out->rev == 3) 1470203319Sweongyo loc[0] = SIBA_SPROM3_MAC_80211BG; 1471203319Sweongyo else { 1472203319Sweongyo loc[0] = SIBA_SPROM1_MAC_80211BG; 1473203319Sweongyo loc[1] = SIBA_SPROM1_MAC_ETH; 1474203319Sweongyo loc[2] = SIBA_SPROM1_MAC_80211A; 1475203319Sweongyo } 1476203319Sweongyo for (i = 0; i < 3; i++) { 1477203319Sweongyo v = in[SIBA_OFFSET(loc[0]) + i]; 1478203319Sweongyo *(((uint16_t *)out->mac_80211bg) + i) = htobe16(v); 1479203319Sweongyo } 1480203319Sweongyo if (out->rev < 3) { 1481203319Sweongyo for (i = 0; i < 3; i++) { 1482203319Sweongyo v = in[SIBA_OFFSET(loc[1]) + i]; 1483203319Sweongyo *(((uint16_t *)out->mac_eth) + i) = htobe16(v); 1484203319Sweongyo } 1485203319Sweongyo for (i = 0; i < 3; i++) { 1486203319Sweongyo v = in[SIBA_OFFSET(loc[2]) + i]; 1487203319Sweongyo *(((uint16_t *)out->mac_80211a) + i) = htobe16(v); 1488203319Sweongyo } 1489203319Sweongyo } 1490203319Sweongyo SIBA_SHIFTOUT(mii_eth0, SIBA_SPROM1_ETHPHY, 1491203319Sweongyo SIBA_SPROM1_ETHPHY_MII_ETH0); 1492203319Sweongyo SIBA_SHIFTOUT(mii_eth1, SIBA_SPROM1_ETHPHY, 1493203319Sweongyo SIBA_SPROM1_ETHPHY_MII_ETH1); 1494203319Sweongyo SIBA_SHIFTOUT(mdio_eth0, SIBA_SPROM1_ETHPHY, 1495203319Sweongyo SIBA_SPROM1_ETHPHY_MDIO_ETH0); 1496203319Sweongyo SIBA_SHIFTOUT(mdio_eth1, SIBA_SPROM1_ETHPHY, 1497203319Sweongyo SIBA_SPROM1_ETHPHY_MDIO_ETH1); 1498203319Sweongyo SIBA_SHIFTOUT(brev, SIBA_SPROM1_BOARDINFO, SIBA_SPROM1_BOARDINFO_BREV); 1499203319Sweongyo SIBA_SHIFTOUT(ccode, SIBA_SPROM1_BOARDINFO, 1500203319Sweongyo SIBA_SPROM1_BOARDINFO_CCODE); 1501203319Sweongyo SIBA_SHIFTOUT(ant_a, SIBA_SPROM1_BOARDINFO, SIBA_SPROM1_BOARDINFO_ANTA); 1502203319Sweongyo SIBA_SHIFTOUT(ant_bg, SIBA_SPROM1_BOARDINFO, 1503203319Sweongyo SIBA_SPROM1_BOARDINFO_ANTBG); 1504203319Sweongyo SIBA_SHIFTOUT(pa0b0, SIBA_SPROM1_PA0B0, 0xffff); 1505203319Sweongyo SIBA_SHIFTOUT(pa0b1, SIBA_SPROM1_PA0B1, 0xffff); 1506203319Sweongyo SIBA_SHIFTOUT(pa0b2, SIBA_SPROM1_PA0B2, 0xffff); 1507203319Sweongyo SIBA_SHIFTOUT(pa1b0, SIBA_SPROM1_PA1B0, 0xffff); 1508203319Sweongyo SIBA_SHIFTOUT(pa1b1, SIBA_SPROM1_PA1B1, 0xffff); 1509203319Sweongyo SIBA_SHIFTOUT(pa1b2, SIBA_SPROM1_PA1B2, 0xffff); 1510203319Sweongyo SIBA_SHIFTOUT(gpio0, SIBA_SPROM1_GPIOA, SIBA_SPROM1_GPIOA_P0); 1511203319Sweongyo SIBA_SHIFTOUT(gpio1, SIBA_SPROM1_GPIOA, SIBA_SPROM1_GPIOA_P1); 1512203319Sweongyo SIBA_SHIFTOUT(gpio2, SIBA_SPROM1_GPIOB, SIBA_SPROM1_GPIOB_P2); 1513203319Sweongyo SIBA_SHIFTOUT(gpio3, SIBA_SPROM1_GPIOB, SIBA_SPROM1_GPIOB_P3); 1514203319Sweongyo SIBA_SHIFTOUT(maxpwr_a, SIBA_SPROM1_MAXPWR, SIBA_SPROM1_MAXPWR_A); 1515203319Sweongyo SIBA_SHIFTOUT(maxpwr_bg, SIBA_SPROM1_MAXPWR, SIBA_SPROM1_MAXPWR_BG); 1516203319Sweongyo SIBA_SHIFTOUT(tssi_a, SIBA_SPROM1_TSSI, SIBA_SPROM1_TSSI_A); 1517203319Sweongyo SIBA_SHIFTOUT(tssi_bg, SIBA_SPROM1_TSSI, SIBA_SPROM1_TSSI_BG); 1518203319Sweongyo SIBA_SHIFTOUT(bf_lo, SIBA_SPROM1_BFLOW, 0xffff); 1519203319Sweongyo if (out->rev >= 2) 1520203319Sweongyo SIBA_SHIFTOUT(bf_hi, SIBA_SPROM2_BFHIGH, 0xffff); 1521203319Sweongyo 1522203319Sweongyo /* antenna gain */ 1523203319Sweongyo gain = siba_sprom_r123_antgain(out->rev, in, SIBA_SPROM1_AGAIN_BG, 0); 1524203319Sweongyo out->again.ghz24.a0 = out->again.ghz24.a1 = gain; 1525203319Sweongyo out->again.ghz24.a2 = out->again.ghz24.a3 = gain; 1526203319Sweongyo gain = siba_sprom_r123_antgain(out->rev, in, SIBA_SPROM1_AGAIN_A, 8); 1527203319Sweongyo out->again.ghz5.a0 = out->again.ghz5.a1 = gain; 1528203319Sweongyo out->again.ghz5.a2 = out->again.ghz5.a3 = gain; 1529203319Sweongyo} 1530203319Sweongyo 1531203319Sweongyostatic void 1532203319Sweongyosiba_sprom_r45(struct siba_sprom *out, const uint16_t *in) 1533203319Sweongyo{ 1534203319Sweongyo int i; 1535203319Sweongyo uint16_t v; 1536203319Sweongyo uint16_t mac_80211bg_offset; 1537203319Sweongyo 1538203319Sweongyo if (out->rev == 4) 1539203319Sweongyo mac_80211bg_offset = SIBA_SPROM4_MAC_80211BG; 1540203319Sweongyo else 1541203319Sweongyo mac_80211bg_offset = SIBA_SPROM5_MAC_80211BG; 1542203319Sweongyo for (i = 0; i < 3; i++) { 1543203319Sweongyo v = in[SIBA_OFFSET(mac_80211bg_offset) + i]; 1544203319Sweongyo *(((uint16_t *)out->mac_80211bg) + i) = htobe16(v); 1545203319Sweongyo } 1546203319Sweongyo SIBA_SHIFTOUT(mii_eth0, SIBA_SPROM4_ETHPHY, SIBA_SPROM4_ETHPHY_ET0A); 1547203319Sweongyo SIBA_SHIFTOUT(mii_eth1, SIBA_SPROM4_ETHPHY, SIBA_SPROM4_ETHPHY_ET1A); 1548203319Sweongyo if (out->rev == 4) { 1549203319Sweongyo SIBA_SHIFTOUT(ccode, SIBA_SPROM4_CCODE, 0xffff); 1550203319Sweongyo SIBA_SHIFTOUT(bf_lo, SIBA_SPROM4_BFLOW, 0xffff); 1551203319Sweongyo SIBA_SHIFTOUT(bf_hi, SIBA_SPROM4_BFHIGH, 0xffff); 1552203319Sweongyo } else { 1553203319Sweongyo SIBA_SHIFTOUT(ccode, SIBA_SPROM5_CCODE, 0xffff); 1554203319Sweongyo SIBA_SHIFTOUT(bf_lo, SIBA_SPROM5_BFLOW, 0xffff); 1555203319Sweongyo SIBA_SHIFTOUT(bf_hi, SIBA_SPROM5_BFHIGH, 0xffff); 1556203319Sweongyo } 1557203319Sweongyo SIBA_SHIFTOUT(ant_a, SIBA_SPROM4_ANTAVAIL, SIBA_SPROM4_ANTAVAIL_A); 1558203319Sweongyo SIBA_SHIFTOUT(ant_bg, SIBA_SPROM4_ANTAVAIL, SIBA_SPROM4_ANTAVAIL_BG); 1559203319Sweongyo SIBA_SHIFTOUT(maxpwr_bg, SIBA_SPROM4_MAXP_BG, SIBA_SPROM4_MAXP_BG_MASK); 1560203319Sweongyo SIBA_SHIFTOUT(tssi_bg, SIBA_SPROM4_MAXP_BG, SIBA_SPROM4_TSSI_BG); 1561203319Sweongyo SIBA_SHIFTOUT(maxpwr_a, SIBA_SPROM4_MAXP_A, SIBA_SPROM4_MAXP_A_MASK); 1562203319Sweongyo SIBA_SHIFTOUT(tssi_a, SIBA_SPROM4_MAXP_A, SIBA_SPROM4_TSSI_A); 1563203319Sweongyo if (out->rev == 4) { 1564203319Sweongyo SIBA_SHIFTOUT(gpio0, SIBA_SPROM4_GPIOA, SIBA_SPROM4_GPIOA_P0); 1565203319Sweongyo SIBA_SHIFTOUT(gpio1, SIBA_SPROM4_GPIOA, SIBA_SPROM4_GPIOA_P1); 1566203319Sweongyo SIBA_SHIFTOUT(gpio2, SIBA_SPROM4_GPIOB, SIBA_SPROM4_GPIOB_P2); 1567203319Sweongyo SIBA_SHIFTOUT(gpio3, SIBA_SPROM4_GPIOB, SIBA_SPROM4_GPIOB_P3); 1568203319Sweongyo } else { 1569203319Sweongyo SIBA_SHIFTOUT(gpio0, SIBA_SPROM5_GPIOA, SIBA_SPROM5_GPIOA_P0); 1570203319Sweongyo SIBA_SHIFTOUT(gpio1, SIBA_SPROM5_GPIOA, SIBA_SPROM5_GPIOA_P1); 1571203319Sweongyo SIBA_SHIFTOUT(gpio2, SIBA_SPROM5_GPIOB, SIBA_SPROM5_GPIOB_P2); 1572203319Sweongyo SIBA_SHIFTOUT(gpio3, SIBA_SPROM5_GPIOB, SIBA_SPROM5_GPIOB_P3); 1573203319Sweongyo } 1574203319Sweongyo 1575203319Sweongyo /* antenna gain */ 1576203319Sweongyo SIBA_SHIFTOUT(again.ghz24.a0, SIBA_SPROM4_AGAIN01, SIBA_SPROM4_AGAIN0); 1577203319Sweongyo SIBA_SHIFTOUT(again.ghz24.a1, SIBA_SPROM4_AGAIN01, SIBA_SPROM4_AGAIN1); 1578203319Sweongyo SIBA_SHIFTOUT(again.ghz24.a2, SIBA_SPROM4_AGAIN23, SIBA_SPROM4_AGAIN2); 1579203319Sweongyo SIBA_SHIFTOUT(again.ghz24.a3, SIBA_SPROM4_AGAIN23, SIBA_SPROM4_AGAIN3); 1580203319Sweongyo bcopy(&out->again.ghz24, &out->again.ghz5, sizeof(out->again.ghz5)); 1581203319Sweongyo} 1582203319Sweongyo 1583203319Sweongyostatic void 1584203319Sweongyosiba_sprom_r8(struct siba_sprom *out, const uint16_t *in) 1585203319Sweongyo{ 1586203319Sweongyo int i; 1587203319Sweongyo uint16_t v; 1588203319Sweongyo 1589203319Sweongyo for (i = 0; i < 3; i++) { 1590203319Sweongyo v = in[SIBA_OFFSET(SIBA_SPROM1_MAC_80211BG) + i]; 1591203319Sweongyo *(((uint16_t *)out->mac_80211bg) + i) = htobe16(v); 1592203319Sweongyo } 1593203319Sweongyo SIBA_SHIFTOUT(ccode, SIBA_SPROM8_CCODE, 0xffff); 1594203319Sweongyo SIBA_SHIFTOUT(bf_lo, SIBA_SPROM8_BFLOW, 0xffff); 1595203319Sweongyo SIBA_SHIFTOUT(bf_hi, SIBA_SPROM8_BFHIGH, 0xffff); 1596203319Sweongyo SIBA_SHIFTOUT(ant_a, SIBA_SPROM8_ANTAVAIL, SIBA_SPROM8_ANTAVAIL_A); 1597203319Sweongyo SIBA_SHIFTOUT(ant_bg, SIBA_SPROM8_ANTAVAIL, SIBA_SPROM8_ANTAVAIL_BG); 1598203319Sweongyo SIBA_SHIFTOUT(maxpwr_bg, SIBA_SPROM8_MAXP_BG, SIBA_SPROM8_MAXP_BG_MASK); 1599203319Sweongyo SIBA_SHIFTOUT(tssi_bg, SIBA_SPROM8_MAXP_BG, SIBA_SPROM8_TSSI_BG); 1600203319Sweongyo SIBA_SHIFTOUT(maxpwr_a, SIBA_SPROM8_MAXP_A, SIBA_SPROM8_MAXP_A_MASK); 1601203319Sweongyo SIBA_SHIFTOUT(tssi_a, SIBA_SPROM8_MAXP_A, SIBA_SPROM8_TSSI_A); 1602203319Sweongyo SIBA_SHIFTOUT(gpio0, SIBA_SPROM8_GPIOA, SIBA_SPROM8_GPIOA_P0); 1603203319Sweongyo SIBA_SHIFTOUT(gpio1, SIBA_SPROM8_GPIOA, SIBA_SPROM8_GPIOA_P1); 1604203319Sweongyo SIBA_SHIFTOUT(gpio2, SIBA_SPROM8_GPIOB, SIBA_SPROM8_GPIOB_P2); 1605203319Sweongyo SIBA_SHIFTOUT(gpio3, SIBA_SPROM8_GPIOB, SIBA_SPROM8_GPIOB_P3); 1606203319Sweongyo 1607203319Sweongyo /* antenna gain */ 1608203319Sweongyo SIBA_SHIFTOUT(again.ghz24.a0, SIBA_SPROM8_AGAIN01, SIBA_SPROM8_AGAIN0); 1609203319Sweongyo SIBA_SHIFTOUT(again.ghz24.a1, SIBA_SPROM8_AGAIN01, SIBA_SPROM8_AGAIN1); 1610203319Sweongyo SIBA_SHIFTOUT(again.ghz24.a2, SIBA_SPROM8_AGAIN23, SIBA_SPROM8_AGAIN2); 1611203319Sweongyo SIBA_SHIFTOUT(again.ghz24.a3, SIBA_SPROM8_AGAIN23, SIBA_SPROM8_AGAIN3); 1612203319Sweongyo bcopy(&out->again.ghz24, &out->again.ghz5, sizeof(out->again.ghz5)); 1613203319Sweongyo} 1614203319Sweongyo 1615203319Sweongyostatic int8_t 1616203319Sweongyosiba_sprom_r123_antgain(uint8_t sprom_revision, const uint16_t *in, 1617203319Sweongyo uint16_t mask, uint16_t shift) 1618203319Sweongyo{ 1619203319Sweongyo uint16_t v; 1620203319Sweongyo uint8_t gain; 1621203319Sweongyo 1622203319Sweongyo v = in[SIBA_OFFSET(SIBA_SPROM1_AGAIN)]; 1623203319Sweongyo gain = (v & mask) >> shift; 1624203319Sweongyo gain = (gain == 0xff) ? 2 : (sprom_revision == 1) ? gain << 2 : 1625203319Sweongyo ((gain & 0xc0) >> 6) | ((gain & 0x3f) << 2); 1626203319Sweongyo 1627203319Sweongyo return ((int8_t)gain); 1628203319Sweongyo} 1629203319Sweongyo 1630203319Sweongyo#undef SIBA_LOWEST_SET_BIT 1631203319Sweongyo#undef SIBA_OFFSET 1632203319Sweongyo#undef SIBA_SHIFTOUT_SUB 1633203319Sweongyo#undef SIBA_SHIFTOUT 1634203319Sweongyo 1635203319Sweongyoint 1636203319Sweongyosiba_powerdown(struct siba_softc *siba) 1637203319Sweongyo{ 1638203319Sweongyo struct siba_cc *scc; 1639203319Sweongyo 1640203319Sweongyo if (siba->siba_type == SIBA_TYPE_SSB) 1641203319Sweongyo return (0); 1642203319Sweongyo 1643203319Sweongyo scc = &siba->siba_cc; 1644203319Sweongyo if (!scc->scc_dev || scc->scc_dev->sd_id.sd_rev < 5) 1645203319Sweongyo return (0); 1646203319Sweongyo siba_cc_clock(scc, SIBA_CLOCK_SLOW); 1647203319Sweongyo siba_pci_gpio(siba, SIBA_GPIO_CRYSTAL | SIBA_GPIO_PLL, 0); 1648203319Sweongyo return (0); 1649203319Sweongyo} 1650203319Sweongyo 1651203319Sweongyostatic void 1652203319Sweongyosiba_pcicore_init(struct siba_pci *spc) 1653203319Sweongyo{ 1654203319Sweongyo struct siba_dev_softc *sd = spc->spc_dev; 1655203319Sweongyo struct siba_softc *siba; 1656203319Sweongyo 1657203319Sweongyo if (sd == NULL) 1658203319Sweongyo return; 1659203319Sweongyo 1660203319Sweongyo siba = sd->sd_bus; 1661203319Sweongyo if (!siba_dev_isup(sd)) 1662203319Sweongyo siba_dev_up(sd, 0); 1663203319Sweongyo 1664203319Sweongyo KASSERT(spc->spc_hostmode == 0, 1665203319Sweongyo ("%s:%d: hostmode", __func__, __LINE__)); 1666203319Sweongyo /* disable PCI interrupt */ 1667203319Sweongyo siba_write_4(spc->spc_dev, SIBA_INTR_MASK, 0); 1668203319Sweongyo} 1669203319Sweongyo 1670203319Sweongyoint 1671203319Sweongyosiba_dev_isup(struct siba_dev_softc *sd) 1672203319Sweongyo{ 1673203319Sweongyo uint32_t reject, val; 1674203319Sweongyo 1675203319Sweongyo reject = siba_tmslow_reject_bitmask(sd); 1676203319Sweongyo val = siba_read_4(sd, SIBA_TGSLOW); 1677203319Sweongyo val &= SIBA_TGSLOW_CLOCK | SIBA_TGSLOW_RESET | reject; 1678203319Sweongyo 1679203319Sweongyo return (val == SIBA_TGSLOW_CLOCK); 1680203319Sweongyo} 1681203319Sweongyo 1682203319Sweongyovoid 1683203319Sweongyosiba_dev_up(struct siba_dev_softc *sd, uint32_t flags) 1684203319Sweongyo{ 1685203319Sweongyo uint32_t val; 1686203319Sweongyo 1687203319Sweongyo siba_dev_down(sd, flags); 1688203319Sweongyo siba_write_4(sd, SIBA_TGSLOW, SIBA_TGSLOW_RESET | SIBA_TGSLOW_CLOCK | 1689203319Sweongyo SIBA_TGSLOW_FGC | flags); 1690203319Sweongyo siba_read_4(sd, SIBA_TGSLOW); 1691203319Sweongyo DELAY(1); 1692203319Sweongyo 1693203319Sweongyo if (siba_read_4(sd, SIBA_TGSHIGH) & SIBA_TGSHIGH_SERR) 1694203319Sweongyo siba_write_4(sd, SIBA_TGSHIGH, 0); 1695203319Sweongyo 1696203319Sweongyo val = siba_read_4(sd, SIBA_IAS); 1697203319Sweongyo if (val & (SIBA_IAS_INBAND_ERR | SIBA_IAS_TIMEOUT)) { 1698203319Sweongyo val &= ~(SIBA_IAS_INBAND_ERR | SIBA_IAS_TIMEOUT); 1699203319Sweongyo siba_write_4(sd, SIBA_IAS, val); 1700203319Sweongyo } 1701203319Sweongyo 1702203319Sweongyo siba_write_4(sd, SIBA_TGSLOW, 1703203319Sweongyo SIBA_TGSLOW_CLOCK | SIBA_TGSLOW_FGC | flags); 1704203319Sweongyo siba_read_4(sd, SIBA_TGSLOW); 1705203319Sweongyo DELAY(1); 1706203319Sweongyo 1707203319Sweongyo siba_write_4(sd, SIBA_TGSLOW, SIBA_TGSLOW_CLOCK | flags); 1708203319Sweongyo siba_read_4(sd, SIBA_TGSLOW); 1709203319Sweongyo DELAY(1); 1710203319Sweongyo} 1711203319Sweongyo 1712203319Sweongyostatic uint32_t 1713203319Sweongyosiba_tmslow_reject_bitmask(struct siba_dev_softc *sd) 1714203319Sweongyo{ 1715203319Sweongyo uint32_t rev = siba_read_4(sd, SIBA_IDLOW) & SIBA_IDLOW_SSBREV; 1716203319Sweongyo 1717203319Sweongyo switch (rev) { 1718203319Sweongyo case SIBA_IDLOW_SSBREV_22: 1719203319Sweongyo return (SIBA_TGSLOW_REJECT_22); 1720203319Sweongyo case SIBA_IDLOW_SSBREV_23: 1721203319Sweongyo return (SIBA_TGSLOW_REJECT_23); 1722203319Sweongyo case SIBA_IDLOW_SSBREV_24: 1723203319Sweongyo case SIBA_IDLOW_SSBREV_25: 1724203319Sweongyo case SIBA_IDLOW_SSBREV_26: 1725203319Sweongyo case SIBA_IDLOW_SSBREV_27: 1726203319Sweongyo return (SIBA_TGSLOW_REJECT_23); 1727203319Sweongyo default: 1728203319Sweongyo KASSERT(0 == 1, 1729203319Sweongyo ("%s:%d: unknown backplane rev %#x\n", 1730203319Sweongyo __func__, __LINE__, rev)); 1731203319Sweongyo } 1732203319Sweongyo return (SIBA_TGSLOW_REJECT_22 | SIBA_TGSLOW_REJECT_23); 1733203319Sweongyo} 1734203319Sweongyo 1735203319Sweongyovoid 1736203319Sweongyosiba_dev_down(struct siba_dev_softc *sd, uint32_t flags) 1737203319Sweongyo{ 1738203319Sweongyo struct siba_softc *siba = sd->sd_bus; 1739203319Sweongyo uint32_t reject, val; 1740203319Sweongyo int i; 1741203319Sweongyo 1742203319Sweongyo if (siba_read_4(sd, SIBA_TGSLOW) & SIBA_TGSLOW_RESET) 1743203319Sweongyo return; 1744203319Sweongyo 1745203319Sweongyo reject = siba_tmslow_reject_bitmask(sd); 1746203319Sweongyo siba_write_4(sd, SIBA_TGSLOW, reject | SIBA_TGSLOW_CLOCK); 1747203319Sweongyo 1748203319Sweongyo for (i = 0; i < 1000; i++) { 1749203319Sweongyo val = siba_read_4(sd, SIBA_TGSLOW); 1750203319Sweongyo if (val & reject) 1751203319Sweongyo break; 1752203319Sweongyo DELAY(10); 1753203319Sweongyo } 1754203319Sweongyo if ((val & reject) == 0) { 1755203319Sweongyo device_printf(siba->siba_dev, "timeout (bit %#x reg %#x)\n", 1756203319Sweongyo reject, SIBA_TGSLOW); 1757203319Sweongyo } 1758203319Sweongyo for (i = 0; i < 1000; i++) { 1759203319Sweongyo val = siba_read_4(sd, SIBA_TGSHIGH); 1760203319Sweongyo if (!(val & SIBA_TGSHIGH_BUSY)) 1761203319Sweongyo break; 1762203319Sweongyo DELAY(10); 1763203319Sweongyo } 1764203319Sweongyo if ((val & SIBA_TGSHIGH_BUSY) != 0) { 1765203319Sweongyo device_printf(siba->siba_dev, "timeout (bit %#x reg %#x)\n", 1766203319Sweongyo SIBA_TGSHIGH_BUSY, SIBA_TGSHIGH); 1767203319Sweongyo } 1768203319Sweongyo 1769203319Sweongyo siba_write_4(sd, SIBA_TGSLOW, SIBA_TGSLOW_FGC | SIBA_TGSLOW_CLOCK | 1770203319Sweongyo reject | SIBA_TGSLOW_RESET | flags); 1771203319Sweongyo siba_read_4(sd, SIBA_TGSLOW); 1772203319Sweongyo DELAY(1); 1773203319Sweongyo siba_write_4(sd, SIBA_TGSLOW, reject | SIBA_TGSLOW_RESET | flags); 1774203319Sweongyo siba_read_4(sd, SIBA_TGSLOW); 1775203319Sweongyo DELAY(1); 1776203319Sweongyo} 1777203319Sweongyo 1778203319Sweongyostatic void 1779203319Sweongyosiba_pcicore_setup(struct siba_pci *spc, struct siba_dev_softc *sd) 1780203319Sweongyo{ 1781203319Sweongyo struct siba_dev_softc *psd = spc->spc_dev; 1782203319Sweongyo struct siba_softc *siba = psd->sd_bus; 1783203319Sweongyo uint32_t tmp; 1784203319Sweongyo 1785203319Sweongyo if (psd->sd_id.sd_device == SIBA_DEVID_PCI) { 1786203319Sweongyo siba_pcicore_write_4(spc, SIBA_PCICORE_SBTOPCI2, 1787203319Sweongyo siba_pcicore_read_4(spc, SIBA_PCICORE_SBTOPCI2) | 1788203319Sweongyo SIBA_PCICORE_SBTOPCI_PREF | SIBA_PCICORE_SBTOPCI_BURST); 1789203319Sweongyo 1790203319Sweongyo if (psd->sd_id.sd_rev < 5) { 1791203319Sweongyo tmp = siba_read_4(psd, SIBA_IMCFGLO); 1792203319Sweongyo tmp &= ~SIBA_IMCFGLO_SERTO; 1793203319Sweongyo tmp = (tmp | 2) & ~SIBA_IMCFGLO_REQTO; 1794203319Sweongyo tmp |= 3 << 4 /* SIBA_IMCFGLO_REQTO_SHIFT */; 1795203319Sweongyo siba_write_4(psd, SIBA_IMCFGLO, tmp); 1796203319Sweongyo 1797203319Sweongyo /* broadcast value */ 1798203319Sweongyo sd = (siba->siba_cc.scc_dev != NULL) ? 1799203319Sweongyo siba->siba_cc.scc_dev : siba->siba_pci.spc_dev; 1800203319Sweongyo if (sd != NULL) { 1801203319Sweongyo siba_write_4(sd, SIBA_PCICORE_BCAST_ADDR, 1802203319Sweongyo 0xfd8); 1803203319Sweongyo siba_read_4(sd, SIBA_PCICORE_BCAST_ADDR); 1804203319Sweongyo siba_write_4(sd, SIBA_PCICORE_BCAST_DATA, 0); 1805203319Sweongyo siba_read_4(sd, SIBA_PCICORE_BCAST_DATA); 1806203319Sweongyo } 1807203319Sweongyo } else if (psd->sd_id.sd_rev >= 11) { 1808203319Sweongyo tmp = siba_pcicore_read_4(spc, SIBA_PCICORE_SBTOPCI2); 1809203319Sweongyo tmp |= SIBA_PCICORE_SBTOPCI_MRM; 1810203319Sweongyo siba_pcicore_write_4(spc, SIBA_PCICORE_SBTOPCI2, tmp); 1811203319Sweongyo } 1812203319Sweongyo } else { 1813203319Sweongyo KASSERT(psd->sd_id.sd_device == SIBA_DEVID_PCIE, ("only PCIE")); 1814203319Sweongyo if ((psd->sd_id.sd_rev == 0) || (psd->sd_id.sd_rev == 1)) 1815203319Sweongyo siba_pcie_write(spc, 0x4, 1816203319Sweongyo siba_pcie_read(spc, 0x4) | 0x8); 1817203319Sweongyo if (psd->sd_id.sd_rev == 0) { 1818203319Sweongyo siba_pcie_mdio_write(spc, 0x1f, 2, 0x8128); /* Timer */ 1819203319Sweongyo siba_pcie_mdio_write(spc, 0x1f, 6, 0x0100); /* CDR */ 1820203319Sweongyo siba_pcie_mdio_write(spc, 0x1f, 7, 0x1466); /* CDR BW */ 1821203319Sweongyo } else if (psd->sd_id.sd_rev == 1) 1822203319Sweongyo siba_pcie_write(spc, 0x100, 1823203319Sweongyo siba_pcie_read(spc, 0x100) | 0x40); 1824203319Sweongyo } 1825203319Sweongyo spc->spc_inited = 1; 1826203319Sweongyo} 1827203319Sweongyo 1828203319Sweongyovoid 1829203319Sweongyosiba_pcicore_intr(struct siba_pci *spc, struct siba_dev_softc *sd) 1830203319Sweongyo{ 1831203319Sweongyo struct siba_dev_softc *psd = spc->spc_dev; 1832203319Sweongyo struct siba_softc *siba; 1833203319Sweongyo uint32_t tmp; 1834203319Sweongyo 1835203319Sweongyo if (sd->sd_bus->siba_type != SIBA_TYPE_PCI || !psd) 1836203319Sweongyo return; 1837203319Sweongyo 1838203319Sweongyo siba = psd->sd_bus; 1839203319Sweongyo /* enable interrupts */ 1840203319Sweongyo if (siba->siba_dev != NULL && 1841203319Sweongyo (psd->sd_id.sd_rev >= 6 || psd->sd_id.sd_device == SIBA_DEVID_PCIE)) { 1842203319Sweongyo tmp = pci_read_config(siba->siba_dev, SIBA_IRQMASK, 4); 1843203319Sweongyo tmp |= (1 << sd->sd_coreidx) << 8; 1844203319Sweongyo pci_write_config(siba->siba_dev, SIBA_IRQMASK, tmp, 4); 1845203319Sweongyo } else { 1846203319Sweongyo tmp = siba_read_4(sd, SIBA_TPS); 1847203319Sweongyo tmp &= SIBA_TPS_BPFLAG; 1848203319Sweongyo siba_write_4(psd, SIBA_INTR_MASK, 1849203319Sweongyo siba_read_4(psd, SIBA_INTR_MASK) | (1 << tmp)); 1850203319Sweongyo } 1851203319Sweongyo 1852203319Sweongyo /* setup PCIcore */ 1853203319Sweongyo if (spc->spc_inited == 0) 1854203319Sweongyo siba_pcicore_setup(spc, sd); 1855203319Sweongyo} 1856203319Sweongyo 1857203319Sweongyostatic uint32_t 1858203319Sweongyosiba_pcicore_read_4(struct siba_pci *spc, uint16_t offset) 1859203319Sweongyo{ 1860203319Sweongyo 1861203319Sweongyo return (siba_read_4(spc->spc_dev, offset)); 1862203319Sweongyo} 1863203319Sweongyo 1864203319Sweongyostatic void 1865203319Sweongyosiba_pcicore_write_4(struct siba_pci *spc, uint16_t offset, uint32_t value) 1866203319Sweongyo{ 1867203319Sweongyo 1868203319Sweongyo siba_write_4(spc->spc_dev, offset, value); 1869203319Sweongyo} 1870203319Sweongyo 1871203319Sweongyostatic uint32_t 1872203319Sweongyosiba_pcie_read(struct siba_pci *spc, uint32_t address) 1873203319Sweongyo{ 1874203319Sweongyo 1875203319Sweongyo siba_pcicore_write_4(spc, 0x130, address); 1876203319Sweongyo return (siba_pcicore_read_4(spc, 0x134)); 1877203319Sweongyo} 1878203319Sweongyo 1879203319Sweongyostatic void 1880203319Sweongyosiba_pcie_write(struct siba_pci *spc, uint32_t address, uint32_t data) 1881203319Sweongyo{ 1882203319Sweongyo 1883203319Sweongyo siba_pcicore_write_4(spc, 0x130, address); 1884203319Sweongyo siba_pcicore_write_4(spc, 0x134, data); 1885203319Sweongyo} 1886203319Sweongyo 1887203319Sweongyostatic void 1888203319Sweongyosiba_pcie_mdio_write(struct siba_pci *spc, uint8_t device, uint8_t address, 1889203319Sweongyo uint16_t data) 1890203319Sweongyo{ 1891203319Sweongyo int i; 1892203319Sweongyo 1893203319Sweongyo siba_pcicore_write_4(spc, SIBA_PCICORE_MDIO_CTL, 0x80 | 0x2); 1894203319Sweongyo siba_pcicore_write_4(spc, SIBA_PCICORE_MDIO_DATA, 1895203319Sweongyo (1 << 30) | (1 << 28) | 1896203319Sweongyo ((uint32_t)device << 22) | ((uint32_t)address << 18) | 1897203319Sweongyo (1 << 17) | data); 1898203319Sweongyo DELAY(10); 1899203319Sweongyo for (i = 0; i < 10; i++) { 1900203319Sweongyo if (siba_pcicore_read_4(spc, SIBA_PCICORE_MDIO_CTL) & 0x100) 1901203319Sweongyo break; 1902203319Sweongyo DELAY(1000); 1903203319Sweongyo } 1904203319Sweongyo siba_pcicore_write_4(spc, SIBA_PCICORE_MDIO_CTL, 0); 1905203319Sweongyo} 1906203319Sweongyo 1907203319Sweongyouint32_t 1908203319Sweongyosiba_dma_translation(struct siba_dev_softc *sd) 1909203319Sweongyo{ 1910203319Sweongyo 1911203319Sweongyo KASSERT(sd->sd_bus->siba_type == SIBA_TYPE_PCI, 1912203319Sweongyo ("unsupported bustype %d\n", sd->sd_bus->siba_type)); 1913203319Sweongyo return (SIBA_PCI_DMA); 1914203319Sweongyo} 1915203319Sweongyo 1916203319Sweongyovoid 1917203319Sweongyosiba_barrier(struct siba_dev_softc *sd, int flags) 1918203319Sweongyo{ 1919203319Sweongyo struct siba_softc *siba = sd->sd_bus; 1920203319Sweongyo 1921203319Sweongyo SIBA_BARRIER(siba, flags); 1922203319Sweongyo} 1923203319Sweongyo 1924203319Sweongyo/* 1925203319Sweongyo * Attach it as child. 1926203319Sweongyo */ 1927203319Sweongyodevice_t 1928203319Sweongyosiba_add_child(device_t dev, struct siba_softc *siba, int order, 1929203319Sweongyo const char *name, int unit) 1930203319Sweongyo{ 1931203319Sweongyo struct siba_dev_softc *sd; 1932203319Sweongyo device_t child; 1933203319Sweongyo int idx = 0, i; 1934203319Sweongyo 1935203319Sweongyo child = device_add_child(dev, name, unit); 1936203319Sweongyo if (child == NULL) 1937203319Sweongyo return (NULL); 1938203319Sweongyo 1939203319Sweongyo siba_powerup(siba, 0); 1940203319Sweongyo siba_pcicore_init(&siba->siba_pci); 1941203319Sweongyo siba_powerdown(siba); 1942203319Sweongyo 1943203319Sweongyo for (i = 0; i < siba->siba_ndevs; i++) { 1944203319Sweongyo sd = &(siba->siba_devs[i]); 1945203319Sweongyo 1946203319Sweongyo if (sd->sd_id.sd_device != SIBA_DEVID_80211) { 1947203319Sweongyo DPRINTF(siba, SIBA_DEBUG_CORE, 1948203319Sweongyo "skip to register coreid %#x (%s)\n", 1949203319Sweongyo sd->sd_id.sd_device, 1950203319Sweongyo siba_core_name(sd->sd_id.sd_device)); 1951203319Sweongyo continue; 1952203319Sweongyo } 1953203319Sweongyo 1954203319Sweongyo DPRINTF(siba, SIBA_DEBUG_CORE, 1955203319Sweongyo "siba: attaching coreid %#x (%s) idx %d\n", 1956203319Sweongyo sd->sd_id.sd_device, 1957203319Sweongyo siba_core_name(sd->sd_id.sd_device), idx); 1958203319Sweongyo 1959203319Sweongyo KASSERT(sd->sd_id.sd_device == SIBA_DEVID_80211, 1960203319Sweongyo ("%s:%d: SIBA_DEVID_80211 is only supportted currently.", 1961203319Sweongyo __func__, __LINE__)); 1962203319Sweongyo 1963203319Sweongyo device_set_ivars(child, sd); 1964203319Sweongyo device_probe_and_attach(child); 1965203319Sweongyo idx++; 1966203319Sweongyo } 1967203319Sweongyo return (child); 1968203319Sweongyo} 1969203319Sweongyo 1970203319Sweongyostatic void 1971203319Sweongyosiba_cc_suspend(struct siba_cc *scc) 1972203319Sweongyo{ 1973203319Sweongyo 1974203319Sweongyo siba_cc_clock(scc, SIBA_CLOCK_SLOW); 1975203319Sweongyo} 1976203319Sweongyo 1977203319Sweongyostatic void 1978203319Sweongyosiba_cc_resume(struct siba_cc *scc) 1979203319Sweongyo{ 1980203319Sweongyo 1981203319Sweongyo siba_cc_power_init(scc); 1982203319Sweongyo siba_cc_clock(scc, SIBA_CLOCK_FAST); 1983203319Sweongyo} 1984203319Sweongyo 1985203319Sweongyoint 1986203319Sweongyosiba_core_suspend(struct siba_softc *siba) 1987203319Sweongyo{ 1988203319Sweongyo 1989203319Sweongyo siba_cc_suspend(&siba->siba_cc); 1990203319Sweongyo siba_pci_gpio(siba, SIBA_GPIO_CRYSTAL | SIBA_GPIO_PLL, 0); 1991203319Sweongyo return (0); 1992203319Sweongyo} 1993203319Sweongyo 1994203319Sweongyoint 1995203319Sweongyosiba_core_resume(struct siba_softc *siba) 1996203319Sweongyo{ 1997203319Sweongyo 1998203319Sweongyo siba->siba_pci.spc_inited = 0; 1999203319Sweongyo siba->siba_curdev = NULL; 2000203319Sweongyo 2001203319Sweongyo siba_powerup(siba, 0); 2002203319Sweongyo /* XXX setup H/W for PCMCIA??? */ 2003203319Sweongyo siba_cc_resume(&siba->siba_cc); 2004203319Sweongyo siba_powerdown(siba); 2005203319Sweongyo 2006203319Sweongyo return (0); 2007203319Sweongyo} 2008