3457b9aa291f3a24e846374141abe0cf8e0cfae4
[depthcharge.git] / src / drivers / bus / i2c / ipq40xx_blsp.c
1 /*
2  * This file is part of the depthcharge project.
3  *
4  * Copyright (C) 2014 - 2015 The Linux Foundation. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are
8  * met:
9  *     * Redistributions of source code must retain the above copyright
10  *       notice, this list of conditions and the following disclaimer.
11  *     * Redistributions in binary form must reproduce the above
12  *       copyright notice, this list of conditions and the following
13  *       disclaimer in the documentation and/or other materials provided
14  *       with the distribution.
15  *     * Neither the name of The Linux Foundation nor the names of its
16  *       contributors may be used to endorse or promote products derived
17  *       from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
26  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
28  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
29  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #include <libpayload.h>
33 #include <arch/io.h>
34 #include "base/container_of.h"
35 #include "base/init_funcs.h"
36 #include "drivers/gpio/ipq40xx.h"
37 #include "drivers/bus/spi/ipq40xx.h"
38 #include "ipq40xx_blsp.h"
39
40 #define SCL_GPIO        20
41 #define SDA_GPIO        21
42 #define GPIO_FUNC_SCL   0x1
43 #define GPIO_FUNC_SDA   0x1
44
45 int blsp_init_board(blsp_qup_id_t id)
46 {
47         switch (id) {
48         case BLSP_QUP_ID_0:
49         case BLSP_QUP_ID_1:
50         case BLSP_QUP_ID_2:
51         case BLSP_QUP_ID_3:
52                 /* Configure GPIOs 20 - SCL, 21 - SDA, 2mA gpio_en */
53                 gpio_tlmm_config_set(SDA_GPIO, GPIO_FUNC_SDA,
54                         GPIO_NO_PULL, GPIO_2MA, 1);
55                 gpio_tlmm_config_set(SCL_GPIO, GPIO_FUNC_SCL,
56                         GPIO_NO_PULL, GPIO_2MA, 1);
57
58                 break;
59         default:
60                 return 1;
61         }
62
63         return 0;
64 }
65
66 int blsp_i2c_clock_config(blsp_qup_id_t id)
67 {
68 #if 0
69 Not sure if this is needed. Coreboot has done this
70
71         int i;
72         const int max_tries = 200;
73         struct { void *cbcr, *cmd, *cfg; } clk[] = {
74                 {
75                         GCC_BLSP1_QUP1_I2C_APPS_CBCR,
76                         GCC_BLSP1_QUP1_I2C_APPS_CMD_RCGR,
77                         GCC_BLSP1_QUP1_I2C_APPS_CFG_RCGR,
78                 },
79                 {
80                         GCC_BLSP1_QUP1_I2C_APPS_CBCR,
81                         GCC_BLSP1_QUP1_I2C_APPS_CMD_RCGR,
82                         GCC_BLSP1_QUP1_I2C_APPS_CFG_RCGR,
83                 },
84                 {
85                         GCC_BLSP1_QUP1_I2C_APPS_CBCR,
86                         GCC_BLSP1_QUP1_I2C_APPS_CMD_RCGR,
87                         GCC_BLSP1_QUP1_I2C_APPS_CFG_RCGR,
88                 },
89                 {
90                         GCC_BLSP1_QUP1_I2C_APPS_CBCR,
91                         GCC_BLSP1_QUP1_I2C_APPS_CMD_RCGR,
92                         GCC_BLSP1_QUP1_I2C_APPS_CFG_RCGR,
93                 },
94         };
95
96         /* uart_clock_config() does this, duplication should be ok... */
97         setbits_le32(GCC_CLK_BRANCH_ENA, BLSP1_AHB | BLSP1_SLEEP);
98
99         if (clk[id].cbcr == NULL)
100                 return -EINVAL;
101
102         /* Src Sel 1 (fepll 200), Src Div 10.5 */
103         write32(clk[id].cfg, (1u << 8) | (20u << 0));
104
105         write32(clk[id].cmd, BIT(0)); /* Update En */
106
107         for (i = 0; i < max_tries; i++) {
108                 if (read32(clk[id].cmd) & BIT(0)) {
109                         udelay(5);
110                         continue;
111                 }
112                 break;
113         }
114
115         if (i == max_tries) {
116                 printk(BIOS_ERR, "== %s failed ==\n", __func__);
117                 return -ETIMEDOUT;
118         }
119
120         write32(clk[id].cbcr, BIT(0));  /* Enable */
121 #endif
122
123         return 0;
124 }
125
126 blsp_return_t blsp_init(blsp_qup_id_t id, blsp_protocol_t protocol)
127 {
128         void *base = blsp_qup_base(id);
129
130         if (!base)
131                 return BLSP_ID_ERROR;
132
133         /* Configure Mini core to I2C core */
134         clrsetbits_le32(base, QUP_CONFIG_MINI_CORE_MSK,
135                                 QUP_CONFIG_MINI_CORE_I2C);
136
137         return BLSP_SUCCESS;
138 }