/*
 * include/ubb/mmcclk.h -  Calculate MMC bus clock speed
 *
 * Written 2013 by Werner Almesberger
 * Copyright 2013 Werner Almesberger
 *
 * 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.
 */

#ifndef UBB_MMCCLK_H
#define UBB_MMCCLK_H

#include <stdint.h>


#define	BEN_PLL_CLK_HZ		336000000


/*
 * By default (flags = 0), only clocks that can be used with any mode of
 * operation will be generated. The following flags also include clocks ...
 */

#define	MMCCLK_FLAG_RD_ONLY	(1 << 0)	/* not suitable for writing */
#define	MMCCLK_FLAG_WR_ONLY	(1 << 1)	/* not suitable for reading */
#define	MMCCLK_FLAG_INTERNAL	(1 << 2)	/* not suitable for bus use */
#define	MMCCLK_FLAG_UNSAFE	(1 << 3)	/* that may hang the MSC */
#define	MMCCLK_FLAG_ALL		(1 << 4)	/* that will hang the MSC */

/*
 * For now, only MMCCLK_FLAG_UNSAFE and MMCCLK_FLAG_ALL are implemented, but
 * further research may also reveal limits that depend on the type of
 * operation.
 */


struct mmcclk {
	int sys_clk_hz;		/* system clock speed in Hz */
	double bus_clk_hz;	/* MMC bus clock in Hz */
	uint32_t clkdiv;	/* MSC controller clock */
	uint32_t clkrt;		/* bus clock divider */
	unsigned flags;
};


void mmcclk_first(struct mmcclk *dsc, int sys_clk_hz, unsigned flags);
int mmcclk_next(struct mmcclk *dsc);

void mmcclk_start(struct mmcclk *dsc);
void mmcclk_stop(void);

#endif /* !UBB_MMCCLK_H */