diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2013-11-07 08:31:47 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2013-11-07 08:31:47 +0100 |
commit | ded25480d8c5e56d9dcbf53a88d05f023b9740c4 (patch) | |
tree | 8691bdf7f0fc801b08b114204c83d25007eb8fba /drivers/mci | |
parent | b3055b0f6b1687089b914eb8cde5bbb73cfca7a1 (diff) | |
parent | 97607e85cdc44824e9617c74325bc9bc6405c383 (diff) | |
download | barebox-ded25480d8c5e56d9dcbf53a88d05f023b9740c4.tar.gz barebox-ded25480d8c5e56d9dcbf53a88d05f023b9740c4.tar.xz |
Merge branch 'for-next/rpi'
Diffstat (limited to 'drivers/mci')
-rw-r--r-- | drivers/mci/mci-bcm2835.c | 90 | ||||
-rw-r--r-- | drivers/mci/mci-bcm2835.h | 48 |
2 files changed, 25 insertions, 113 deletions
diff --git a/drivers/mci/mci-bcm2835.c b/drivers/mci/mci-bcm2835.c index abd38a35c9..7d8997c04c 100644 --- a/drivers/mci/mci-bcm2835.c +++ b/drivers/mci/mci-bcm2835.c @@ -34,6 +34,8 @@ #include <io.h> #include <malloc.h> #include <clock.h> +#include <linux/clk.h> + #include "mci-bcm2835.h" #include "sdhci.h" @@ -468,53 +470,32 @@ int bcm2835_mci_reset(struct mci_host *mci, struct device_d *mci_dev) return bcm2835_mci_wait_command_done(host); } -static u32 bcm2835_mci_get_emmc_clock(struct msg_get_clock_rate *clk_data) +static int bcm2835_mci_detect(struct device_d *dev) { - u32 val; - struct bcm2835_mbox_regs *regs = - (struct bcm2835_mbox_regs *) BCM2835_MBOX_PHYSADDR; - - /*Read out old msg*/ - while (true) { - val = readl(®s->status); - if (val & BCM2835_MBOX_STATUS_RD_EMPTY) - break; - val = readl(®s->read); - } - - /*Check for ok to write*/ - while (true) { - val = readl(®s->status); - if (!(val & BCM2835_MBOX_STATUS_WR_FULL)) - break; - } - val = BCM2835_MBOX_PROP_CHAN + ((u32) &clk_data->hdr); - writel(val, ®s->write); - - while (true) { - /* Wait for the response */ - while (true) { - val = readl(®s->status); - if (!(val & BCM2835_MBOX_STATUS_RD_EMPTY)) - break; - } + struct bcm2835_mci_host *host = dev->priv; - /* Read the response */ - val = readl(®s->read); - if ((val & 0x0F) == BCM2835_MBOX_PROP_CHAN) - break; - } - if ((val & ~0x0F) == ((u32) &clk_data->hdr)) - if (clk_data->get_clock_rate.tag_hdr.val_len - & BCM2835_MBOX_TAG_VAL_LEN_RESPONSE) - return 1; - return 0; + return mci_detect_card(&host->mci); } static int bcm2835_mci_probe(struct device_d *hw_dev) { struct bcm2835_mci_host *host; - struct msg_get_clock_rate *clk_data; + static struct clk *clk; + int ret; + + clk = clk_get(hw_dev, NULL); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + dev_err(hw_dev, "clock not found: %d\n", ret); + return ret; + } + + ret = clk_enable(clk); + if (ret) { + dev_err(hw_dev, "clock failed to enable: %d\n", ret); + clk_put(clk); + return ret; + } host = xzalloc(sizeof(*host)); host->mci.send_cmd = bcm2835_mci_request; @@ -522,31 +503,7 @@ static int bcm2835_mci_probe(struct device_d *hw_dev) host->mci.init = bcm2835_mci_reset; host->mci.hw_dev = hw_dev; host->hw_dev = hw_dev; - - /* Allocate a buffer thats 16 bytes aligned in memory - * Of the 32 bits address passed into the mbox 28 bits - * are the address of the buffer, lower 4 bits is channel - */ - clk_data = memalign(16, sizeof(struct msg_get_clock_rate)); - memset(clk_data, 0, sizeof(struct msg_get_clock_rate)); - clk_data->hdr.buf_size = sizeof(struct msg_get_clock_rate); - clk_data->get_clock_rate.tag_hdr.tag = BCM2835_MBOX_TAG_GET_CLOCK_RATE; - clk_data->get_clock_rate.tag_hdr.val_buf_size = - sizeof(clk_data->get_clock_rate.body); - clk_data->get_clock_rate.tag_hdr.val_len = - sizeof(clk_data->get_clock_rate.body.req); - clk_data->get_clock_rate.body.req.clock_id = BCM2835_MBOX_CLOCK_ID_EMMC; - - if (!bcm2835_mci_get_emmc_clock(clk_data)) { - dev_warn(host->hw_dev, - "Failed getting emmc clock, lets go anyway with 50MHz\n"); - host->max_clock = 50000000; - } else { - host->max_clock = clk_data->get_clock_rate.body.resp.rate_hz; - dev_info(host->hw_dev, "Got emmc clock at %d Hz\n", - host->max_clock); - } - + host->max_clock = clk_get_rate(clk); host->regs = dev_request_mem_region(hw_dev, 0); if (host->regs == NULL) { dev_err(host->hw_dev, "Failed request mem region, aborting...\n"); @@ -561,6 +518,9 @@ static int bcm2835_mci_probe(struct device_d *hw_dev) host->mci.f_min = MIN_FREQ; host->mci.f_max = host->max_clock; + hw_dev->priv = host; + hw_dev->detect = bcm2835_mci_detect, + /* * The Arasan has a bugette whereby it may lose the content of * successive writes to registers that are within two SD-card clock diff --git a/drivers/mci/mci-bcm2835.h b/drivers/mci/mci-bcm2835.h index 4158a18065..2c95e03c64 100644 --- a/drivers/mci/mci-bcm2835.h +++ b/drivers/mci/mci-bcm2835.h @@ -23,51 +23,3 @@ #define MAX_CLK_DIVIDER_V3 2046 #define MAX_CLK_DIVIDER_V2 256 - -/*this is only for mbox comms*/ -#define BCM2835_MBOX_PHYSADDR 0x2000b880 -#define BCM2835_MBOX_TAG_GET_CLOCK_RATE 0x00030002 -#define BCM2835_MBOX_CLOCK_ID_EMMC 1 -#define BCM2835_MBOX_STATUS_WR_FULL 0x80000000 -#define BCM2835_MBOX_STATUS_RD_EMPTY 0x40000000 -#define BCM2835_MBOX_PROP_CHAN 8 -#define BCM2835_MBOX_TAG_VAL_LEN_RESPONSE 0x80000000 - -struct bcm2835_mbox_regs { - u32 read; - u32 rsvd0[5]; - u32 status; - u32 config; - u32 write; -}; - - -struct bcm2835_mbox_hdr { - u32 buf_size; - u32 code; -}; - -struct bcm2835_mbox_tag_hdr { - u32 tag; - u32 val_buf_size; - u32 val_len; -}; - -struct bcm2835_mbox_tag_get_clock_rate { - struct bcm2835_mbox_tag_hdr tag_hdr; - union { - struct { - u32 clock_id; - } req; - struct { - u32 clock_id; - u32 rate_hz; - } resp; - } body; -}; - -struct msg_get_clock_rate { - struct bcm2835_mbox_hdr hdr; - struct bcm2835_mbox_tag_get_clock_rate get_clock_rate; - u32 end_tag; -}; |