/*

  Broadcom BCM43xx wireless driver

  Copyright (c) 2005 Martin Langer <martin-langer@gmx.de>,
                     Stefano Brivio <st3@riseup.net>
                     Michael Buesch <mbuesch@freenet.de>
                     Danny van Dyk <kugelfang@gentoo.org>
                     Andreas Jaggi <andreas.jaggi@waterwave.ch>

  Some parts of the code in this file are derived from the ipw2200
  driver  Copyright(c) 2003 - 2004 Intel Corporation.

  This program is free software; you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation; either version 2 of the License, or
  (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; see the file COPYING.  If not, write to
  the Free Software Foundation, Inc., 51 Franklin Steet, Fifth Floor,
  Boston, MA 02110-1301, USA.

*/

#include <linux/delay.h>

#include "bcm43xx.h"
#include "bcm43xx_power.h"
#include "bcm43xx_main.h"


/* Get the Slow Clock Source */
static int bcm43xx_pctl_get_slowclksrc(struct bcm43xx_private *bcm)
{
	u32 tmp;
	int err;

	assert(bcm->current_core == &bcm->core_chipcommon);
	if (bcm->current_core->rev < 6) {
		if (bcm->bustype == BCM43xx_BUSTYPE_PCMCIA ||
		    bcm->bustype == BCM43xx_BUSTYPE_SB)
			return BCM43xx_PCTL_CLKSRC_XTALOS;
		if (bcm->bustype == BCM43xx_BUSTYPE_PCI) {
			err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &tmp);
			assert(!err);
			if (tmp & 0x10)
				return BCM43xx_PCTL_CLKSRC_PCI;
			return BCM43xx_PCTL_CLKSRC_XTALOS;
		}
	}
	if (bcm->current_core->rev < 10) {
		tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL);
		tmp &= 0x7;
		if (tmp == 0)
			return BCM43xx_PCTL_CLKSRC_LOPWROS;
		if (tmp == 1)
			return BCM43xx_PCTL_CLKSRC_XTALOS;
		if (tmp == 2)
			return BCM43xx_PCTL_CLKSRC_PCI;
	}

	return BCM43xx_PCTL_CLKSRC_XTALOS;
}

/* Get max/min slowclock frequency
 * as described in http://bcm-specs.sipsolutions.net/PowerControl
 */
static int bcm43xx_pctl_clockfreqlimit(struct bcm43xx_private *bcm,
				       int get_max)
{
	int limit;
	int clocksrc;
	int divisor;
	u32 tmp;

	assert(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL);
	assert(bcm->current_core == &bcm->core_chipcommon);

	clocksrc = bcm43xx_pctl_get_slowclksrc(bcm);
	if (bcm->current_core->rev < 6) {
		switch (clocksrc) {
		case BCM43xx_PCTL_CLKSRC_PCI:
			divisor = 64;
			break;
		case BCM43xx_PCTL_CLKSRC_XTALOS:
			divisor = 32;
			break;
		default:
			assert(0);
			divisor = 1;
		}
	} else if (bcm->current_core->rev < 10) {
		switch (clocksrc) {
		case BCM43xx_PCTL_CLKSRC_LOPWROS:
			divisor = 1;
			break;
		case BCM43xx_PCTL_CLKSRC_XTALOS:
		case BCM43xx_PCTL_CLKSRC_PCI:
			tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL);
			divisor = ((tmp & 0xFFFF0000) >> 16) + 1;
			divisor *= 4;
			break;
		default:
			assert(0);
			divisor = 1;
		}
	} else {
		tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL);
		divisor = ((tmp & 0xFFFF0000) >> 16) + 1;
		divisor *= 4;
	}

	switch (clocksrc) {
	case BCM43xx_PCTL_CLKSRC_LOPWROS:
		if (get_max)
			limit = 43000;
		else
			limit = 25000;
		break;
	case BCM43xx_PCTL_CLKSRC_XTALOS:
		if (get_max)
			limit = 20200000;
		else
			limit = 19800000;
		break;
	case BCM43xx_PCTL_CLKSRC_PCI:
		if (get_max)
			limit = 34000000;
		else
			limit = 25000000;
		break;
	default:
		assert(0);
		limit = 0;
	}
	limit /= divisor;

	return limit;
}


/* init power control
 * as described in http://bcm-specs.sipsolutions.net/PowerControl
 */
int bcm43xx_pctl_init(struct bcm43xx_private *bcm)
{
	int err, maxfreq;
	struct bcm43xx_coreinfo *old_core;

	old_core = bcm->current_core;
	err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
	if (err == -ENODEV)
		return 0;
	if (err)
		goto out;

	if (bcm->chip_id == 0x4321) {
		if (bcm->chip_rev == 0)
			bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_CTL, 0x03A4);
		if (bcm->chip_rev == 1)
			bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_CTL, 0x00A4);
	}

	if (bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL) {
		if (bcm->current_core->rev >= 10) {
			/* Set Idle Power clock rate to 1Mhz */
			bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL,
				       (bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL)
				       & 0x0000FFFF) | 0x40000);
		} else {
			maxfreq = bcm43xx_pctl_clockfreqlimit(bcm, 1);
			bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_PLLONDELAY,
				       (maxfreq * 150 + 999999) / 1000000);
			bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_FREFSELDELAY,
				       (maxfreq * 15 + 999999) / 1000000);
		}
	}

	err = bcm43xx_switch_core(bcm, old_core);
	assert(err == 0);

out:
	return err;
}

u16 bcm43xx_pctl_powerup_delay(struct bcm43xx_private *bcm)
{
	u16 delay = 0;
	int err;
	u32 pll_on_delay;
	struct bcm43xx_coreinfo *old_core;
	int minfreq;

	if (bcm->bustype != BCM43xx_BUSTYPE_PCI)
		goto out;
	if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL))
		goto out;
	old_core = bcm->current_core;
	err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
	if (err == -ENODEV)
		goto out;

	minfreq = bcm43xx_pctl_clockfreqlimit(bcm, 0);
	pll_on_delay = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_PLLONDELAY);
	delay = (((pll_on_delay + 2) * 1000000) + (minfreq - 1)) / minfreq;

	err = bcm43xx_switch_core(bcm, old_core);
	assert(err == 0);

out:
	return delay;
}

/* set the powercontrol clock
 * as described in http://bcm-specs.sipsolutions.net/PowerControl
 */
int bcm43xx_pctl_set_clock(struct bcm43xx_private *bcm, u16 mode)
{
	int err;
	struct bcm43xx_coreinfo *old_core;
	u32 tmp;

	old_core = bcm->current_core;
	err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
	if (err == -ENODEV)
		return 0;
	if (err)
		goto out;
	
	if (bcm->core_chipcommon.rev < 6) {
		if (mode == BCM43xx_PCTL_CLK_FAST) {
			err = bcm43xx_pctl_set_crystal(bcm, 1);
			if (err)
				goto out;
		}
	} else {
		if ((bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL) &&
			(bcm->core_chipcommon.rev < 10)) {
			switch (mode) {
			case BCM43xx_PCTL_CLK_FAST:
				tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL);
				tmp = (tmp & ~BCM43xx_PCTL_FORCE_SLOW) | BCM43xx_PCTL_FORCE_PLL;
				bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL, tmp);
				break;
			case BCM43xx_PCTL_CLK_SLOW:
				tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL);
				tmp |= BCM43xx_PCTL_FORCE_SLOW;
				bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL, tmp);
				break;
			case BCM43xx_PCTL_CLK_DYNAMIC:
				tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL);
				tmp &= ~BCM43xx_PCTL_FORCE_SLOW;
				tmp |= BCM43xx_PCTL_FORCE_PLL;
				tmp &= ~BCM43xx_PCTL_DYN_XTAL;
				bcm43xx_write32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL, tmp);
			}
		}
	}
	
	err = bcm43xx_switch_core(bcm, old_core);
	assert(err == 0);

out:
	return err;
}

int bcm43xx_pctl_set_crystal(struct bcm43xx_private *bcm, int on)
{
	int err;
	u32 in, out, outenable;

	err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_IN, &in);
	if (err)
		goto err_pci;
	err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &out);
	if (err)
		goto err_pci;
	err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUTENABLE, &outenable);
	if (err)
		goto err_pci;

	outenable |= (BCM43xx_PCTL_XTAL_POWERUP | BCM43xx_PCTL_PLL_POWERDOWN);

	if (on) {
		if (in & 0x40)
			return 0;

		out |= (BCM43xx_PCTL_XTAL_POWERUP | BCM43xx_PCTL_PLL_POWERDOWN);

		err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUT, out);
		if (err)
			goto err_pci;
		err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUTENABLE, outenable);
		if (err)
			goto err_pci;
		udelay(1000);

		out &= ~BCM43xx_PCTL_PLL_POWERDOWN;
		err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUT, out);
		if (err)
			goto err_pci;
		udelay(5000);
	} else {
		if (bcm->current_core->rev < 5)
			return 0;
		if (bcm->sprom.boardflags & BCM43xx_BFL_XTAL_NOSLOW)
			return 0;

/*		XXX: Why BCM43xx_MMIO_RADIO_HWENABLED_xx can't be read at this time?
 *		err = bcm43xx_switch_core(bcm, bcm->active_80211_core);
 *		if (err)
 *			return err;
 *		if (((bcm->current_core->rev >= 3) &&
 *			(bcm43xx_read32(bcm, BCM43xx_MMIO_RADIO_HWENABLED_HI) & (1 << 16))) ||
 *		      ((bcm->current_core->rev < 3) &&
 *			!(bcm43xx_read16(bcm, BCM43xx_MMIO_RADIO_HWENABLED_LO) & (1 << 4))))
 *			return 0;
 *		err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
 *		if (err)
 *			return err;
 */
		
		err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_SLOW);
		if (err)
			goto out;
		out &= ~BCM43xx_PCTL_XTAL_POWERUP;
		out |= BCM43xx_PCTL_PLL_POWERDOWN;
		err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUT, out);
		if (err)
			goto err_pci;
		err = bcm43xx_pci_write_config32(bcm, BCM43xx_PCTL_OUTENABLE, outenable);
		if (err)
			goto err_pci;
	}

out:
	return err;

err_pci:
	printk(KERN_ERR PFX "Error: pctl_set_clock() could not access PCI config space!\n");
	err = -EBUSY;
	goto out;
}

/* Set the PowerSavingControlBits.
 * Bitvalues:
 *   0  => unset the bit
 *   1  => set the bit
 *   -1 => calculate the bit
 */
void bcm43xx_power_saving_ctl_bits(struct bcm43xx_private *bcm,
				   int bit25, int bit26)
{
	int i;
	u32 status;

//FIXME: Force 25 to off and 26 to on for now:
bit25 = 0;
bit26 = 1;

	if (bit25 == -1) {
		//TODO: If powersave is not off and FIXME is not set and we are not in adhoc
		//	and thus is not an AP and we are associated, set bit 25
	}
	if (bit26 == -1) {
		//TODO: If the device is awake or this is an AP, or we are scanning, or FIXME,
		//	or we are associated, or FIXME, or the latest PS-Poll packet sent was
		//	successful, set bit26
	}
	status = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
	if (bit25)
		status |= BCM43xx_SBF_PS1;
	else
		status &= ~BCM43xx_SBF_PS1;
	if (bit26)
		status |= BCM43xx_SBF_PS2;
	else
		status &= ~BCM43xx_SBF_PS2;
	bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, status);
	if (bit26 && bcm->current_core->rev >= 5) {
		for (i = 0; i < 100; i++) {
			if (bcm43xx_shm_read32(bcm, BCM43xx_SHM_SHARED, 0x0040) != 4)
				break;
			udelay(10);
		}
	}
}
