mirror of
git://projects.qi-hardware.com/ben-blinkenlights.git
synced 2024-11-23 23:20:38 +02:00
libubb/mmcclk.c (mmcclk_first): add flags to relax clock selection constraints
This commit is contained in:
parent
14b7a9cdee
commit
591bb6427b
@ -19,15 +19,34 @@
|
|||||||
#define BEN_PLL_CLK_HZ 336000000
|
#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 {
|
struct mmcclk {
|
||||||
int sys_clk_hz; /* system clock speed in Hz */
|
int sys_clk_hz; /* system clock speed in Hz */
|
||||||
double bus_clk_hz; /* MMC bus clock in Hz */
|
double bus_clk_hz; /* MMC bus clock in Hz */
|
||||||
uint32_t clkdiv; /* MSC controller clock */
|
uint32_t clkdiv; /* MSC controller clock */
|
||||||
uint32_t clkrt; /* bus clock divider */
|
uint32_t clkrt; /* bus clock divider */
|
||||||
|
unsigned flags;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void mmcclk_first(struct mmcclk *dsc, int sys_clk_hz);
|
void mmcclk_first(struct mmcclk *dsc, int sys_clk_hz, unsigned flags);
|
||||||
int mmcclk_next(struct mmcclk *dsc);
|
int mmcclk_next(struct mmcclk *dsc);
|
||||||
|
|
||||||
void mmcclk_start(struct mmcclk *dsc);
|
void mmcclk_start(struct mmcclk *dsc);
|
||||||
|
@ -27,23 +27,30 @@
|
|||||||
* Some Bens still work fine at 84 MHz.
|
* Some Bens still work fine at 84 MHz.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define BUS_LIMIT_MHZ 56
|
#define BUS_SAFE_MHZ 56 /* always works */
|
||||||
|
#define BUS_UNSAFE_MHZ 84 /* some devices don't like this */
|
||||||
|
|
||||||
|
|
||||||
static int calculate_clock(struct mmcclk *dsc)
|
static int calculate_clock(struct mmcclk *dsc)
|
||||||
{
|
{
|
||||||
dsc->bus_clk_hz = dsc->sys_clk_hz/(dsc->clkdiv+1.0)/(1 << dsc->clkrt);
|
dsc->bus_clk_hz = dsc->sys_clk_hz/(dsc->clkdiv+1.0)/(1 << dsc->clkrt);
|
||||||
return dsc->bus_clk_hz <= BUS_LIMIT_MHZ*1000000;
|
if (dsc->flags & MMCCLK_FLAG_ALL)
|
||||||
|
return 1;
|
||||||
|
if ((dsc->flags & MMCCLK_FLAG_UNSAFE) &&
|
||||||
|
dsc->bus_clk_hz <= BUS_UNSAFE_MHZ*1000000)
|
||||||
|
return 1;
|
||||||
|
return dsc->bus_clk_hz <= BUS_SAFE_MHZ*1000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mmcclk_first(struct mmcclk *dsc, int sys_clk_hz)
|
void mmcclk_first(struct mmcclk *dsc, int sys_clk_hz, unsigned flags)
|
||||||
{
|
{
|
||||||
if (sys_clk_hz)
|
if (sys_clk_hz)
|
||||||
dsc->sys_clk_hz = sys_clk_hz;
|
dsc->sys_clk_hz = sys_clk_hz;
|
||||||
else
|
else
|
||||||
dsc->sys_clk_hz =
|
dsc->sys_clk_hz =
|
||||||
(CPCCR >> 21) & 1 ? BEN_PLL_CLK_HZ : BEN_PLL_CLK_HZ/2;
|
(CPCCR >> 21) & 1 ? BEN_PLL_CLK_HZ : BEN_PLL_CLK_HZ/2;
|
||||||
|
dsc->flags = flags;
|
||||||
dsc->clkdiv = dsc->clkrt = 0;
|
dsc->clkdiv = dsc->clkrt = 0;
|
||||||
if (calculate_clock(dsc))
|
if (calculate_clock(dsc))
|
||||||
return;
|
return;
|
||||||
|
Loading…
Reference in New Issue
Block a user