1 /*
2  * Copyright (c) 2018-2021, ARM Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 #include <assert.h>
8 
9 #include <platform_def.h>
10 
11 #include <common/debug.h>
12 #include <drivers/console.h>
13 #include <drivers/mmc.h>
14 #include <lib/utils.h>
15 
16 #include <imx_caam.h>
17 #include <imx_clock.h>
18 #include <imx_io_mux.h>
19 #include <imx_uart.h>
20 #include <imx_usdhc.h>
21 #include <imx7_def.h>
22 
23 #define UART5_CLK_SELECT (CCM_TARGET_ROOT_ENABLE |\
24 			  CCM_TRGT_MUX_UART5_CLK_ROOT_OSC_24M)
25 
26 #define USDHC_CLK_SELECT (CCM_TARGET_ROOT_ENABLE |\
27 			  CCM_TRGT_MUX_NAND_USDHC_BUS_CLK_ROOT_AHB |\
28 			  CCM_TARGET_POST_PODF(2))
29 
30 #define USB_CLK_SELECT (CCM_TARGET_ROOT_ENABLE |\
31 			CCM_TRGT_MUX_USB_HSIC_CLK_ROOT_SYS_PLL)
32 
33 #define PICOPI_UART5_RX_MUX \
34 	IOMUXC_SW_MUX_CTL_PAD_I2C4_SCL_ALT1_UART5_RX_DATA
35 
36 #define PICOPI_UART5_TX_MUX \
37 	IOMUXC_SW_MUX_CTL_PAD_I2C4_SDA_ALT1_UART5_TX_DATA
38 
39 #define PICOPI_SD3_FEATURES \
40 	(IOMUXC_SW_PAD_CTL_PAD_SD3_PU_47K            | \
41 	 IOMUXC_SW_PAD_CTL_PAD_SD3_PE                | \
42 	 IOMUXC_SW_PAD_CTL_PAD_SD3_HYS               | \
43 	 IOMUXC_SW_PAD_CTL_PAD_SD3_SLEW_SLOW         | \
44 	 IOMUXC_SW_PAD_CTL_PAD_SD3_DSE_3_X6)
45 
46 static struct mmc_device_info mmc_info;
47 
picopi_setup_pinmux(void)48 static void picopi_setup_pinmux(void)
49 {
50 	/* Configure UART5 TX */
51 	imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_I2C4_SDA_OFFSET,
52 					 PICOPI_UART5_TX_MUX);
53 	/* Configure UART5 RX */
54 	imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_I2C4_SCL_OFFSET,
55 					 PICOPI_UART5_RX_MUX);
56 
57 	/* Configure USDHC3 */
58 	imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_SD3_CLK_OFFSET, 0);
59 	imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_SD3_CMD_OFFSET, 0);
60 	imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_SD3_DATA0_OFFSET, 0);
61 	imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_SD3_DATA1_OFFSET, 0);
62 	imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_SD3_DATA2_OFFSET, 0);
63 	imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_SD3_DATA3_OFFSET, 0);
64 	imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_SD3_DATA4_OFFSET, 0);
65 	imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_SD3_DATA5_OFFSET, 0);
66 	imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_SD3_DATA6_OFFSET, 0);
67 	imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_SD3_DATA7_OFFSET, 0);
68 	imx_io_muxc_set_pad_alt_function(IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO14_OFFSET,
69 					 IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO14_ALT1_SD3_CD_B);
70 
71 	imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_SD3_CLK_OFFSET,
72 				     PICOPI_SD3_FEATURES);
73 	imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_SD3_CMD_OFFSET,
74 				     PICOPI_SD3_FEATURES);
75 	imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_SD3_DATA0_OFFSET,
76 				     PICOPI_SD3_FEATURES);
77 	imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_SD3_DATA1_OFFSET,
78 				     PICOPI_SD3_FEATURES);
79 	imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_SD3_DATA2_OFFSET,
80 				     PICOPI_SD3_FEATURES);
81 	imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_SD3_DATA3_OFFSET,
82 				     PICOPI_SD3_FEATURES);
83 	imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_SD3_DATA4_OFFSET,
84 				     PICOPI_SD3_FEATURES);
85 	imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_SD3_DATA5_OFFSET,
86 				     PICOPI_SD3_FEATURES);
87 	imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_SD3_DATA6_OFFSET,
88 				     PICOPI_SD3_FEATURES);
89 	imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_SD3_DATA7_OFFSET,
90 				     PICOPI_SD3_FEATURES);
91 	imx_io_muxc_set_pad_features(IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO14_OFFSET,
92 				     PICOPI_SD3_FEATURES);
93 }
94 
picopi_usdhc_setup(void)95 static void picopi_usdhc_setup(void)
96 {
97 	imx_usdhc_params_t params;
98 
99 	zeromem(&params, sizeof(imx_usdhc_params_t));
100 	params.reg_base = PLAT_PICOPI_BOOT_MMC_BASE;
101 	params.clk_rate = 25000000;
102 	params.bus_width = MMC_BUS_WIDTH_8;
103 	mmc_info.mmc_dev_type = MMC_IS_EMMC;
104 	imx_usdhc_init(&params, &mmc_info);
105 }
106 
picopi_setup_usb_clocks(void)107 static void picopi_setup_usb_clocks(void)
108 {
109 	uint32_t usb_en_bits = (uint32_t)USB_CLK_SELECT;
110 
111 	imx_clock_set_usb_clk_root_bits(usb_en_bits);
112 	imx_clock_enable_usb(CCM_CCGR_ID_USB_IPG);
113 	imx_clock_enable_usb(CCM_CCGR_ID_USB_PHY_480MCLK);
114 	imx_clock_enable_usb(CCM_CCGR_ID_USB_OTG1_PHY);
115 	imx_clock_enable_usb(CCM_CCGR_ID_USB_OTG2_PHY);
116 }
117 
imx7_platform_setup(u_register_t arg1,u_register_t arg2,u_register_t arg3,u_register_t arg4)118 void imx7_platform_setup(u_register_t arg1, u_register_t arg2,
119 			 u_register_t arg3, u_register_t arg4)
120 {
121 	uint32_t uart5_en_bits = (uint32_t)UART5_CLK_SELECT;
122 	uint32_t usdhc_clock_sel = PLAT_PICOPI_SD - 1;
123 
124 	/* Initialize clocks etc */
125 	imx_clock_enable_uart(4, uart5_en_bits);
126 	imx_clock_enable_usdhc(usdhc_clock_sel, USDHC_CLK_SELECT);
127 
128 	picopi_setup_usb_clocks();
129 
130 	/* Setup pin-muxes */
131 	picopi_setup_pinmux();
132 
133 	picopi_usdhc_setup();
134 }
135