xref: /rk3399_rockchip-uboot/arch/arm/mach-bcm283x/msg.c (revision 7cac2fced726c4865133b74ea73ef13df40a1884)
170997d88SSimon Glass /*
270997d88SSimon Glass  * (C) Copyright 2012 Stephen Warren
370997d88SSimon Glass  *
470997d88SSimon Glass  * SPDX-License-Identifier:	GPL-2.0+
570997d88SSimon Glass  */
670997d88SSimon Glass 
770997d88SSimon Glass #include <common.h>
870997d88SSimon Glass #include <memalign.h>
92e4170b6SSimon Glass #include <phys2bus.h>
1070997d88SSimon Glass #include <asm/arch/mbox.h>
1170997d88SSimon Glass 
1270997d88SSimon Glass struct msg_set_power_state {
1370997d88SSimon Glass 	struct bcm2835_mbox_hdr hdr;
1470997d88SSimon Glass 	struct bcm2835_mbox_tag_set_power_state set_power_state;
1570997d88SSimon Glass 	u32 end_tag;
1670997d88SSimon Glass };
1770997d88SSimon Glass 
18c6606515SSimon Glass struct msg_get_clock_rate {
19c6606515SSimon Glass 	struct bcm2835_mbox_hdr hdr;
20c6606515SSimon Glass 	struct bcm2835_mbox_tag_get_clock_rate get_clock_rate;
21c6606515SSimon Glass 	u32 end_tag;
22c6606515SSimon Glass };
23c6606515SSimon Glass 
242e4170b6SSimon Glass struct msg_query {
252e4170b6SSimon Glass 	struct bcm2835_mbox_hdr hdr;
262e4170b6SSimon Glass 	struct bcm2835_mbox_tag_physical_w_h physical_w_h;
272e4170b6SSimon Glass 	u32 end_tag;
282e4170b6SSimon Glass };
292e4170b6SSimon Glass 
30*7cac2fceSSimon Glass struct msg_setup {
31*7cac2fceSSimon Glass 	struct bcm2835_mbox_hdr hdr;
32*7cac2fceSSimon Glass 	struct bcm2835_mbox_tag_physical_w_h physical_w_h;
33*7cac2fceSSimon Glass 	struct bcm2835_mbox_tag_virtual_w_h virtual_w_h;
34*7cac2fceSSimon Glass 	struct bcm2835_mbox_tag_depth depth;
35*7cac2fceSSimon Glass 	struct bcm2835_mbox_tag_pixel_order pixel_order;
36*7cac2fceSSimon Glass 	struct bcm2835_mbox_tag_alpha_mode alpha_mode;
37*7cac2fceSSimon Glass 	struct bcm2835_mbox_tag_virtual_offset virtual_offset;
38*7cac2fceSSimon Glass 	struct bcm2835_mbox_tag_overscan overscan;
39*7cac2fceSSimon Glass 	struct bcm2835_mbox_tag_allocate_buffer allocate_buffer;
40*7cac2fceSSimon Glass 	struct bcm2835_mbox_tag_pitch pitch;
41*7cac2fceSSimon Glass 	u32 end_tag;
42*7cac2fceSSimon Glass };
43*7cac2fceSSimon Glass 
bcm2835_power_on_module(u32 module)4470997d88SSimon Glass int bcm2835_power_on_module(u32 module)
4570997d88SSimon Glass {
4670997d88SSimon Glass 	ALLOC_CACHE_ALIGN_BUFFER(struct msg_set_power_state, msg_pwr, 1);
4770997d88SSimon Glass 	int ret;
4870997d88SSimon Glass 
4970997d88SSimon Glass 	BCM2835_MBOX_INIT_HDR(msg_pwr);
5070997d88SSimon Glass 	BCM2835_MBOX_INIT_TAG(&msg_pwr->set_power_state,
5170997d88SSimon Glass 			      SET_POWER_STATE);
5270997d88SSimon Glass 	msg_pwr->set_power_state.body.req.device_id = module;
5370997d88SSimon Glass 	msg_pwr->set_power_state.body.req.state =
5470997d88SSimon Glass 		BCM2835_MBOX_SET_POWER_STATE_REQ_ON |
5570997d88SSimon Glass 		BCM2835_MBOX_SET_POWER_STATE_REQ_WAIT;
5670997d88SSimon Glass 
5770997d88SSimon Glass 	ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN,
5870997d88SSimon Glass 				     &msg_pwr->hdr);
5970997d88SSimon Glass 	if (ret) {
6070997d88SSimon Glass 		printf("bcm2835: Could not set module %u power state\n",
6170997d88SSimon Glass 		       module);
6270997d88SSimon Glass 		return -EIO;
6370997d88SSimon Glass 	}
6470997d88SSimon Glass 
6570997d88SSimon Glass 	return 0;
6670997d88SSimon Glass }
67c6606515SSimon Glass 
bcm2835_get_mmc_clock(void)68c6606515SSimon Glass int bcm2835_get_mmc_clock(void)
69c6606515SSimon Glass {
70c6606515SSimon Glass 	ALLOC_CACHE_ALIGN_BUFFER(struct msg_get_clock_rate, msg_clk, 1);
71c6606515SSimon Glass 	int ret;
72c6606515SSimon Glass 
73c6606515SSimon Glass 	ret = bcm2835_power_on_module(BCM2835_MBOX_POWER_DEVID_SDHCI);
74c6606515SSimon Glass 	if (ret)
75c6606515SSimon Glass 		return ret;
76c6606515SSimon Glass 
77c6606515SSimon Glass 	BCM2835_MBOX_INIT_HDR(msg_clk);
78c6606515SSimon Glass 	BCM2835_MBOX_INIT_TAG(&msg_clk->get_clock_rate, GET_CLOCK_RATE);
79c6606515SSimon Glass 	msg_clk->get_clock_rate.body.req.clock_id = BCM2835_MBOX_CLOCK_ID_EMMC;
80c6606515SSimon Glass 
81c6606515SSimon Glass 	ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg_clk->hdr);
82c6606515SSimon Glass 	if (ret) {
83c6606515SSimon Glass 		printf("bcm2835: Could not query eMMC clock rate\n");
84c6606515SSimon Glass 		return -EIO;
85c6606515SSimon Glass 	}
86c6606515SSimon Glass 
87c6606515SSimon Glass 	return msg_clk->get_clock_rate.body.resp.rate_hz;
88c6606515SSimon Glass }
892e4170b6SSimon Glass 
bcm2835_get_video_size(int * widthp,int * heightp)902e4170b6SSimon Glass int bcm2835_get_video_size(int *widthp, int *heightp)
912e4170b6SSimon Glass {
922e4170b6SSimon Glass 	ALLOC_CACHE_ALIGN_BUFFER(struct msg_query, msg_query, 1);
932e4170b6SSimon Glass 	int ret;
942e4170b6SSimon Glass 
952e4170b6SSimon Glass 	BCM2835_MBOX_INIT_HDR(msg_query);
962e4170b6SSimon Glass 	BCM2835_MBOX_INIT_TAG_NO_REQ(&msg_query->physical_w_h,
972e4170b6SSimon Glass 				     GET_PHYSICAL_W_H);
982e4170b6SSimon Glass 	ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg_query->hdr);
992e4170b6SSimon Glass 	if (ret) {
1002e4170b6SSimon Glass 		printf("bcm2835: Could not query display resolution\n");
1012e4170b6SSimon Glass 		return ret;
1022e4170b6SSimon Glass 	}
1032e4170b6SSimon Glass 	*widthp = msg_query->physical_w_h.body.resp.width;
1042e4170b6SSimon Glass 	*heightp = msg_query->physical_w_h.body.resp.height;
1052e4170b6SSimon Glass 
1062e4170b6SSimon Glass 	return 0;
1072e4170b6SSimon Glass }
108*7cac2fceSSimon Glass 
bcm2835_set_video_params(int * widthp,int * heightp,int depth_bpp,int pixel_order,int alpha_mode,ulong * fb_basep,ulong * fb_sizep,int * pitchp)109*7cac2fceSSimon Glass int bcm2835_set_video_params(int *widthp, int *heightp, int depth_bpp,
110*7cac2fceSSimon Glass 			     int pixel_order, int alpha_mode, ulong *fb_basep,
111*7cac2fceSSimon Glass 			     ulong *fb_sizep, int *pitchp)
112*7cac2fceSSimon Glass {
113*7cac2fceSSimon Glass 	ALLOC_CACHE_ALIGN_BUFFER(struct msg_setup, msg_setup, 1);
114*7cac2fceSSimon Glass 	int ret;
115*7cac2fceSSimon Glass 
116*7cac2fceSSimon Glass 	BCM2835_MBOX_INIT_HDR(msg_setup);
117*7cac2fceSSimon Glass 	BCM2835_MBOX_INIT_TAG(&msg_setup->physical_w_h, SET_PHYSICAL_W_H);
118*7cac2fceSSimon Glass 	msg_setup->physical_w_h.body.req.width = *widthp;
119*7cac2fceSSimon Glass 	msg_setup->physical_w_h.body.req.height = *heightp;
120*7cac2fceSSimon Glass 	BCM2835_MBOX_INIT_TAG(&msg_setup->virtual_w_h, SET_VIRTUAL_W_H);
121*7cac2fceSSimon Glass 	msg_setup->virtual_w_h.body.req.width = *widthp;
122*7cac2fceSSimon Glass 	msg_setup->virtual_w_h.body.req.height = *heightp;
123*7cac2fceSSimon Glass 	BCM2835_MBOX_INIT_TAG(&msg_setup->depth, SET_DEPTH);
124*7cac2fceSSimon Glass 	msg_setup->depth.body.req.bpp = 32;
125*7cac2fceSSimon Glass 	BCM2835_MBOX_INIT_TAG(&msg_setup->pixel_order, SET_PIXEL_ORDER);
126*7cac2fceSSimon Glass 	msg_setup->pixel_order.body.req.order = pixel_order;
127*7cac2fceSSimon Glass 	BCM2835_MBOX_INIT_TAG(&msg_setup->alpha_mode, SET_ALPHA_MODE);
128*7cac2fceSSimon Glass 	msg_setup->alpha_mode.body.req.alpha = alpha_mode;
129*7cac2fceSSimon Glass 	BCM2835_MBOX_INIT_TAG(&msg_setup->virtual_offset, SET_VIRTUAL_OFFSET);
130*7cac2fceSSimon Glass 	msg_setup->virtual_offset.body.req.x = 0;
131*7cac2fceSSimon Glass 	msg_setup->virtual_offset.body.req.y = 0;
132*7cac2fceSSimon Glass 	BCM2835_MBOX_INIT_TAG(&msg_setup->overscan, SET_OVERSCAN);
133*7cac2fceSSimon Glass 	msg_setup->overscan.body.req.top = 0;
134*7cac2fceSSimon Glass 	msg_setup->overscan.body.req.bottom = 0;
135*7cac2fceSSimon Glass 	msg_setup->overscan.body.req.left = 0;
136*7cac2fceSSimon Glass 	msg_setup->overscan.body.req.right = 0;
137*7cac2fceSSimon Glass 	BCM2835_MBOX_INIT_TAG(&msg_setup->allocate_buffer, ALLOCATE_BUFFER);
138*7cac2fceSSimon Glass 	msg_setup->allocate_buffer.body.req.alignment = 0x100;
139*7cac2fceSSimon Glass 	BCM2835_MBOX_INIT_TAG_NO_REQ(&msg_setup->pitch, GET_PITCH);
140*7cac2fceSSimon Glass 
141*7cac2fceSSimon Glass 	ret = bcm2835_mbox_call_prop(BCM2835_MBOX_PROP_CHAN, &msg_setup->hdr);
142*7cac2fceSSimon Glass 	if (ret) {
143*7cac2fceSSimon Glass 		printf("bcm2835: Could not configure display\n");
144*7cac2fceSSimon Glass 		return ret;
145*7cac2fceSSimon Glass 	}
146*7cac2fceSSimon Glass 	*widthp = msg_setup->physical_w_h.body.resp.width;
147*7cac2fceSSimon Glass 	*heightp = msg_setup->physical_w_h.body.resp.height;
148*7cac2fceSSimon Glass 	*pitchp = msg_setup->pitch.body.resp.pitch;
149*7cac2fceSSimon Glass 	*fb_basep = bus_to_phys(
150*7cac2fceSSimon Glass 			msg_setup->allocate_buffer.body.resp.fb_address);
151*7cac2fceSSimon Glass 	*fb_sizep = msg_setup->allocate_buffer.body.resp.fb_size;
152*7cac2fceSSimon Glass 
153*7cac2fceSSimon Glass 	return 0;
154*7cac2fceSSimon Glass }
155