1 /* 2 * (C) Copyright 2012 Stephen Warren 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <memalign.h> 9 #include <asm/arch/mbox.h> 10 11 struct msg_set_power_state { 12 struct bcm2835_mbox_hdr hdr; 13 struct bcm2835_mbox_tag_set_power_state set_power_state; 14 u32 end_tag; 15 }; 16 17 struct msg_get_clock_rate { 18 struct bcm2835_mbox_hdr hdr; 19 struct bcm2835_mbox_tag_get_clock_rate get_clock_rate; 20 u32 end_tag; 21 }; 22 23 int bcm2835_power_on_module(u32 module) 24 { 25 ALLOC_CACHE_ALIGN_BUFFER(struct msg_set_power_state, msg_pwr, 1); 26 int ret; 27 28 BCM2835_MBOX_INIT_HDR(msg_pwr); 29 BCM2835_MBOX_INIT_TAG(&msg_pwr->set_power_state, 30 SET_POWER_STATE); 31 msg_pwr->set_power_state.body.req.device_id = module; 32 msg_pwr->set_power_state.body.req.state = 33 BCM2835_MBOX_SET_POWER_STATE_REQ_ON | 34 BCM2835_MBOX_SET_POWER_STATE_REQ_WAIT; 35 36 ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, 37 &msg_pwr->hdr); 38 if (ret) { 39 printf("bcm2835: Could not set module %u power state\n", 40 module); 41 return -EIO; 42 } 43 44 return 0; 45 } 46 47 int bcm2835_get_mmc_clock(void) 48 { 49 ALLOC_CACHE_ALIGN_BUFFER(struct msg_get_clock_rate, msg_clk, 1); 50 int ret; 51 52 ret = bcm2835_power_on_module(BCM2835_MBOX_POWER_DEVID_SDHCI); 53 if (ret) 54 return ret; 55 56 BCM2835_MBOX_INIT_HDR(msg_clk); 57 BCM2835_MBOX_INIT_TAG(&msg_clk->get_clock_rate, GET_CLOCK_RATE); 58 msg_clk->get_clock_rate.body.req.clock_id = BCM2835_MBOX_CLOCK_ID_EMMC; 59 60 ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg_clk->hdr); 61 if (ret) { 62 printf("bcm2835: Could not query eMMC clock rate\n"); 63 return -EIO; 64 } 65 66 return msg_clk->get_clock_rate.body.resp.rate_hz; 67 } 68