mirror of
git://projects.qi-hardware.com/ben-blinkenlights.git
synced 2024-11-27 15:20:16 +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
|
||||
LIBVERSION = 0.0.0
|
||||
|
||||
OBJS = ubb.o swuart.o
|
||||
HDRS = ubb/ubb.h ubb/regbase.h ubb/regs4740.h ubb/swuart.h
|
||||
OBJS = ubb.o swuart.o mmcclk.o
|
||||
HDRS = ubb/ubb.h ubb/regbase.h ubb/regs4740.h ubb/swuart.h ubb/mmcclk.h
|
||||
|
||||
.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