mirror of
git://projects.qi-hardware.com/ben-blinkenlights.git
synced 2024-11-27 17:05:20 +02:00
libubb/mmcclk.c: helper functions for selecting and configuring the MMC bus clock
Experimental.
This commit is contained in:
parent
a593da0cd0
commit
1eb8e64811
@ -20,8 +20,8 @@ LIB = libubb.a
|
|||||||
SHLIB = libubb.so
|
SHLIB = libubb.so
|
||||||
LIBVERSION = 0.0.0
|
LIBVERSION = 0.0.0
|
||||||
|
|
||||||
OBJS = ubb.o swuart.o
|
OBJS = ubb.o swuart.o mmcclk.o
|
||||||
HDRS = ubb/ubb.h ubb/regbase.h ubb/regs4740.h ubb/swuart.h
|
HDRS = ubb/ubb.h ubb/regbase.h ubb/regs4740.h ubb/swuart.h ubb/mmcclk.h
|
||||||
|
|
||||||
.PHONY: all clean spotless
|
.PHONY: all clean spotless
|
||||||
|
|
||||||
|
36
libubb/include/ubb/mmcclk.h
Normal file
36
libubb/include/ubb/mmcclk.h
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* 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_SYS_CLK_HZ 336000000
|
||||||
|
|
||||||
|
|
||||||
|
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 */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void mmcclk_first(struct mmcclk *dsc, int sys_clk_hz);
|
||||||
|
int mmcclk_next(struct mmcclk *dsc);
|
||||||
|
|
||||||
|
void mmcclk_start(struct mmcclk *dsc);
|
||||||
|
void mmcclk_stop(void);
|
||||||
|
|
||||||
|
#endif /* !UBB_MMCCLK_H */
|
67
libubb/mmcclk.c
Normal file
67
libubb/mmcclk.c
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* libubb/mmcclk.c - 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <ubb/regs4740.h>
|
||||||
|
#include <ubb/mmcclk.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define MSCCDR_MAX 32
|
||||||
|
#define CLKRT_MAX 8
|
||||||
|
|
||||||
|
#define BUS_LIMIT_MHZ 56 /* nominally, the limit is 20 MHz */
|
||||||
|
|
||||||
|
|
||||||
|
static int calculate_clock(struct mmcclk *dsc)
|
||||||
|
{
|
||||||
|
dsc->bus_clk_hz = dsc->sys_clk_hz/(dsc->clkdiv+1.0)/(1 << dsc->clkrt);
|
||||||
|
return dsc->bus_clk_hz <= BUS_LIMIT_MHZ*1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mmcclk_first(struct mmcclk *dsc, int sys_clk_hz)
|
||||||
|
{
|
||||||
|
dsc->sys_clk_hz = sys_clk_hz ? sys_clk_hz : BEN_SYS_CLK_HZ;
|
||||||
|
dsc->clkdiv = dsc->clkrt = 0;
|
||||||
|
if (calculate_clock(dsc))
|
||||||
|
return;
|
||||||
|
mmcclk_next(dsc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int mmcclk_next(struct mmcclk *dsc)
|
||||||
|
{
|
||||||
|
while (1) {
|
||||||
|
if (++dsc->clkdiv == MSCCDR_MAX) {
|
||||||
|
dsc->clkdiv = 0;
|
||||||
|
if (++dsc->clkrt == CLKRT_MAX)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (calculate_clock(dsc))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mmcclk_start(struct mmcclk *dsc)
|
||||||
|
{
|
||||||
|
MSCCDR = dsc->clkdiv; /* set controller clock */
|
||||||
|
CLKGR &= ~(1 << 7); /* enable MSC clock */
|
||||||
|
MSC_CLKRT = dsc->clkrt; /* set bus clock */
|
||||||
|
MSC_STRPCL = 2; /* start MMC bus clock output */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mmcclk_stop(void)
|
||||||
|
{
|
||||||
|
MSC_STRPCL = 1; /* stop MMC bus clock output */
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user