11716bcf3SHauke Mehrtens /* 21716bcf3SHauke Mehrtens * Broadcom specific AMBA 31716bcf3SHauke Mehrtens * ChipCommon B Unit driver 41716bcf3SHauke Mehrtens * 51716bcf3SHauke Mehrtens * Copyright 2014, Hauke Mehrtens <hauke@hauke-m.de> 61716bcf3SHauke Mehrtens * 71716bcf3SHauke Mehrtens * Licensed under the GNU/GPL. See COPYING for details. 81716bcf3SHauke Mehrtens */ 91716bcf3SHauke Mehrtens 101716bcf3SHauke Mehrtens #include "bcma_private.h" 111716bcf3SHauke Mehrtens #include <linux/export.h> 121716bcf3SHauke Mehrtens #include <linux/bcma/bcma.h> 131716bcf3SHauke Mehrtens 141716bcf3SHauke Mehrtens static bool bcma_wait_reg(struct bcma_bus *bus, void __iomem *addr, u32 mask, 151716bcf3SHauke Mehrtens u32 value, int timeout) 161716bcf3SHauke Mehrtens { 171716bcf3SHauke Mehrtens unsigned long deadline = jiffies + timeout; 181716bcf3SHauke Mehrtens u32 val; 191716bcf3SHauke Mehrtens 201716bcf3SHauke Mehrtens do { 211716bcf3SHauke Mehrtens val = readl(addr); 221716bcf3SHauke Mehrtens if ((val & mask) == value) 231716bcf3SHauke Mehrtens return true; 241716bcf3SHauke Mehrtens cpu_relax(); 251716bcf3SHauke Mehrtens udelay(10); 261716bcf3SHauke Mehrtens } while (!time_after_eq(jiffies, deadline)); 271716bcf3SHauke Mehrtens 281716bcf3SHauke Mehrtens bcma_err(bus, "Timeout waiting for register %p\n", addr); 291716bcf3SHauke Mehrtens 301716bcf3SHauke Mehrtens return false; 311716bcf3SHauke Mehrtens } 321716bcf3SHauke Mehrtens 331716bcf3SHauke Mehrtens void bcma_chipco_b_mii_write(struct bcma_drv_cc_b *ccb, u32 offset, u32 value) 341716bcf3SHauke Mehrtens { 351716bcf3SHauke Mehrtens struct bcma_bus *bus = ccb->core->bus; 36cc2d1de0SRafał Miłecki void __iomem *mii = ccb->mii; 371716bcf3SHauke Mehrtens 38cc2d1de0SRafał Miłecki writel(offset, mii + BCMA_CCB_MII_MNG_CTL); 39cc2d1de0SRafał Miłecki bcma_wait_reg(bus, mii + BCMA_CCB_MII_MNG_CTL, 0x0100, 0x0000, 100); 40cc2d1de0SRafał Miłecki writel(value, mii + BCMA_CCB_MII_MNG_CMD_DATA); 41cc2d1de0SRafał Miłecki bcma_wait_reg(bus, mii + BCMA_CCB_MII_MNG_CTL, 0x0100, 0x0000, 100); 421716bcf3SHauke Mehrtens } 431716bcf3SHauke Mehrtens EXPORT_SYMBOL_GPL(bcma_chipco_b_mii_write); 441716bcf3SHauke Mehrtens 451716bcf3SHauke Mehrtens int bcma_core_chipcommon_b_init(struct bcma_drv_cc_b *ccb) 461716bcf3SHauke Mehrtens { 471716bcf3SHauke Mehrtens if (ccb->setup_done) 481716bcf3SHauke Mehrtens return 0; 491716bcf3SHauke Mehrtens 501716bcf3SHauke Mehrtens ccb->setup_done = 1; 51*4bdc0d67SChristoph Hellwig ccb->mii = ioremap(ccb->core->addr_s[1], BCMA_CORE_SIZE); 521716bcf3SHauke Mehrtens if (!ccb->mii) 531716bcf3SHauke Mehrtens return -ENOMEM; 541716bcf3SHauke Mehrtens 551716bcf3SHauke Mehrtens return 0; 561716bcf3SHauke Mehrtens } 571716bcf3SHauke Mehrtens 581716bcf3SHauke Mehrtens void bcma_core_chipcommon_b_free(struct bcma_drv_cc_b *ccb) 591716bcf3SHauke Mehrtens { 601716bcf3SHauke Mehrtens if (ccb->mii) 611716bcf3SHauke Mehrtens iounmap(ccb->mii); 621716bcf3SHauke Mehrtens } 63