Sagar Dharia | 7c927c0 | 2016-11-23 11:51:43 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (c) 2017, The Linux Foundation. All rights reserved. |
| 3 | * |
| 4 | * This program is free software; you can redistribute it and/or modify |
| 5 | * it under the terms of the GNU General Public License version 2 and |
| 6 | * only version 2 as published by the Free Software Foundation. |
| 7 | * |
| 8 | * This program is distributed in the hope that it will be useful, |
| 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 11 | * GNU General Public License for more details. |
| 12 | * |
| 13 | */ |
| 14 | |
| 15 | #ifndef _LINUX_QCOM_GENI_SE |
| 16 | #define _LINUX_QCOM_GENI_SE |
| 17 | #include <linux/io.h> |
Girish Mahadevan | ebeed35 | 2016-11-23 10:59:29 -0700 | [diff] [blame] | 18 | #include <linux/clk.h> |
| 19 | #include <linux/msm-bus.h> |
| 20 | #include <linux/msm-bus-board.h> |
| 21 | #include <linux/pm_runtime.h> |
Sagar Dharia | 7c927c0 | 2016-11-23 11:51:43 -0700 | [diff] [blame] | 22 | |
| 23 | enum se_xfer_mode { |
| 24 | INVALID, |
| 25 | FIFO_MODE, |
| 26 | GSI_DMA, |
| 27 | }; |
| 28 | |
| 29 | enum se_protocol_types { |
| 30 | NONE, |
| 31 | SPI, |
| 32 | UART, |
| 33 | I2C, |
| 34 | I3C |
| 35 | }; |
| 36 | |
Girish Mahadevan | ebeed35 | 2016-11-23 10:59:29 -0700 | [diff] [blame] | 37 | struct se_geni_rsc { |
| 38 | struct clk *se_clk; |
| 39 | struct clk *m_ahb_clk; |
| 40 | struct clk *s_ahb_clk; |
| 41 | struct msm_bus_client_handle *bus_bw; |
Girish Mahadevan | 3e694cc | 2017-04-19 16:50:03 -0600 | [diff] [blame] | 42 | unsigned int bus_mas; |
Girish Mahadevan | ebeed35 | 2016-11-23 10:59:29 -0700 | [diff] [blame] | 43 | unsigned long ab; |
| 44 | unsigned long ib; |
| 45 | struct pinctrl *geni_pinctrl; |
| 46 | struct pinctrl_state *geni_gpio_active; |
| 47 | struct pinctrl_state *geni_gpio_sleep; |
| 48 | }; |
| 49 | |
| 50 | #define PINCTRL_DEFAULT "default" |
| 51 | #define PINCTRL_SLEEP "sleep" |
| 52 | |
Girish Mahadevan | 2ef85af | 2017-02-14 14:42:22 -0700 | [diff] [blame] | 53 | /* Common SE registers */ |
Sagar Dharia | 7c927c0 | 2016-11-23 11:51:43 -0700 | [diff] [blame] | 54 | #define GENI_INIT_CFG_REVISION (0x0) |
| 55 | #define GENI_S_INIT_CFG_REVISION (0x4) |
| 56 | #define GENI_FORCE_DEFAULT_REG (0x20) |
| 57 | #define GENI_OUTPUT_CTRL (0x24) |
| 58 | #define GENI_CGC_CTRL (0x28) |
| 59 | #define SE_GENI_STATUS (0x40) |
| 60 | #define GENI_SER_M_CLK_CFG (0x48) |
| 61 | #define GENI_SER_S_CLK_CFG (0x4C) |
| 62 | #define GENI_CLK_CTRL_RO (0x60) |
| 63 | #define GENI_IF_DISABLE_RO (0x64) |
| 64 | #define GENI_FW_REVISION_RO (0x68) |
| 65 | #define GENI_FW_S_REVISION_RO (0x6C) |
| 66 | #define SE_GENI_CLK_SEL (0x7C) |
| 67 | #define SE_GENI_DMA_MODE_EN (0x258) |
| 68 | #define SE_GENI_TX_PACKING_CFG0 (0x260) |
| 69 | #define SE_GENI_TX_PACKING_CFG1 (0x264) |
| 70 | #define SE_GENI_RX_PACKING_CFG0 (0x284) |
| 71 | #define SE_GENI_RX_PACKING_CFG1 (0x288) |
| 72 | #define SE_GENI_M_CMD0 (0x600) |
| 73 | #define SE_GENI_M_CMD_CTRL_REG (0x604) |
| 74 | #define SE_GENI_M_IRQ_STATUS (0x610) |
| 75 | #define SE_GENI_M_IRQ_EN (0x614) |
| 76 | #define SE_GENI_M_IRQ_CLEAR (0x618) |
| 77 | #define SE_GENI_S_CMD0 (0x630) |
| 78 | #define SE_GENI_S_CMD_CTRL_REG (0x634) |
| 79 | #define SE_GENI_S_IRQ_STATUS (0x640) |
| 80 | #define SE_GENI_S_IRQ_EN (0x644) |
| 81 | #define SE_GENI_S_IRQ_CLEAR (0x648) |
| 82 | #define SE_GENI_TX_FIFOn (0x700) |
| 83 | #define SE_GENI_RX_FIFOn (0x780) |
| 84 | #define SE_GENI_TX_FIFO_STATUS (0x800) |
| 85 | #define SE_GENI_RX_FIFO_STATUS (0x804) |
| 86 | #define SE_GENI_TX_WATERMARK_REG (0x80C) |
| 87 | #define SE_GENI_RX_WATERMARK_REG (0x810) |
| 88 | #define SE_GENI_RX_RFR_WATERMARK_REG (0x814) |
Girish Mahadevan | 7115f4e | 2017-03-15 15:18:34 -0600 | [diff] [blame^] | 89 | #define SE_GENI_IOS (0x908) |
Sagar Dharia | 7c927c0 | 2016-11-23 11:51:43 -0700 | [diff] [blame] | 90 | #define SE_GENI_M_GP_LENGTH (0x910) |
| 91 | #define SE_GENI_S_GP_LENGTH (0x914) |
Girish Mahadevan | a95a361 | 2017-04-19 11:49:24 -0600 | [diff] [blame] | 92 | #define SE_GSI_EVENT_EN (0xE18) |
Sagar Dharia | 7c927c0 | 2016-11-23 11:51:43 -0700 | [diff] [blame] | 93 | #define SE_IRQ_EN (0xE1C) |
| 94 | #define SE_HW_PARAM_0 (0xE24) |
| 95 | #define SE_HW_PARAM_1 (0xE28) |
| 96 | #define SE_DMA_GENERAL_CFG (0xE30) |
| 97 | |
| 98 | /* GENI_OUTPUT_CTRL fields */ |
| 99 | #define DEFAULT_IO_OUTPUT_CTRL_MSK (GENMASK(6, 0)) |
| 100 | |
| 101 | /* GENI_FORCE_DEFAULT_REG fields */ |
| 102 | #define FORCE_DEFAULT (BIT(0)) |
| 103 | |
| 104 | /* GENI_CGC_CTRL fields */ |
| 105 | #define CFG_AHB_CLK_CGC_ON (BIT(0)) |
| 106 | #define CFG_AHB_WR_ACLK_CGC_ON (BIT(1)) |
| 107 | #define DATA_AHB_CLK_CGC_ON (BIT(2)) |
| 108 | #define SCLK_CGC_ON (BIT(3)) |
| 109 | #define TX_CLK_CGC_ON (BIT(4)) |
| 110 | #define RX_CLK_CGC_ON (BIT(5)) |
| 111 | #define EXT_CLK_CGC_ON (BIT(6)) |
| 112 | #define PROG_RAM_HCLK_OFF (BIT(8)) |
| 113 | #define PROG_RAM_SCLK_OFF (BIT(9)) |
| 114 | #define DEFAULT_CGC_EN (GENMASK(6, 0)) |
| 115 | |
| 116 | /* GENI_STATUS fields */ |
| 117 | #define M_GENI_CMD_ACTIVE (BIT(0)) |
| 118 | #define S_GENI_CMD_ACTIVE (BIT(12)) |
| 119 | |
| 120 | /* GENI_SER_M_CLK_CFG/GENI_SER_S_CLK_CFG */ |
| 121 | #define SER_CLK_EN (BIT(0)) |
| 122 | #define CLK_DIV_MSK (GENMASK(15, 4)) |
| 123 | #define CLK_DIV_SHFT (4) |
| 124 | |
| 125 | /* CLK_CTRL_RO fields */ |
| 126 | |
| 127 | /* IF_DISABLE_RO fields */ |
| 128 | |
| 129 | /* FW_REVISION_RO fields */ |
| 130 | #define FW_REV_PROTOCOL_MSK (GENMASK(15, 8)) |
| 131 | #define FW_REV_PROTOCOL_SHFT (8) |
| 132 | |
Girish Mahadevan | 2ef85af | 2017-02-14 14:42:22 -0700 | [diff] [blame] | 133 | /* GENI_CLK_SEL fields */ |
| 134 | #define CLK_SEL_MSK (GENMASK(2, 0)) |
| 135 | |
Sagar Dharia | 7c927c0 | 2016-11-23 11:51:43 -0700 | [diff] [blame] | 136 | /* SE_GENI_DMA_MODE_EN */ |
| 137 | #define GENI_DMA_MODE_EN (BIT(0)) |
| 138 | |
| 139 | /* GENI_M_CMD0 fields */ |
| 140 | #define M_OPCODE_MSK (GENMASK(31, 27)) |
| 141 | #define M_OPCODE_SHFT (27) |
| 142 | #define M_PARAMS_MSK (GENMASK(26, 0)) |
| 143 | |
| 144 | /* GENI_M_CMD_CTRL_REG */ |
| 145 | #define M_GENI_CMD_CANCEL BIT(2) |
| 146 | #define M_GENI_CMD_ABORT BIT(1) |
| 147 | #define M_GENI_DISABLE BIT(0) |
| 148 | |
| 149 | /* GENI_S_CMD0 fields */ |
| 150 | #define S_OPCODE_MSK (GENMASK(31, 27)) |
| 151 | #define S_OPCODE_SHFT (27) |
| 152 | #define S_PARAMS_MSK (GENMASK(26, 0)) |
| 153 | |
| 154 | /* GENI_S_CMD_CTRL_REG */ |
| 155 | #define S_GENI_CMD_CANCEL (BIT(2)) |
| 156 | #define S_GENI_CMD_ABORT (BIT(1)) |
| 157 | #define S_GENI_DISABLE (BIT(0)) |
| 158 | |
| 159 | /* GENI_M_IRQ_EN fields */ |
| 160 | #define M_CMD_DONE_EN (BIT(0)) |
| 161 | #define M_CMD_OVERRUN_EN (BIT(1)) |
| 162 | #define M_ILLEGAL_CMD_EN (BIT(2)) |
| 163 | #define M_CMD_FAILURE_EN (BIT(3)) |
| 164 | #define M_CMD_CANCEL_EN (BIT(4)) |
| 165 | #define M_CMD_ABORT_EN (BIT(5)) |
| 166 | #define M_TIMESTAMP_EN (BIT(6)) |
| 167 | #define M_RX_IRQ_EN (BIT(7)) |
| 168 | #define M_GP_SYNC_IRQ_0_EN (BIT(8)) |
| 169 | #define M_GP_IRQ_0_EN (BIT(9)) |
| 170 | #define M_GP_IRQ_1_EN (BIT(10)) |
| 171 | #define M_GP_IRQ_2_EN (BIT(11)) |
| 172 | #define M_GP_IRQ_3_EN (BIT(12)) |
| 173 | #define M_GP_IRQ_4_EN (BIT(13)) |
| 174 | #define M_GP_IRQ_5_EN (BIT(14)) |
| 175 | #define M_IO_DATA_DEASSERT_EN (BIT(22)) |
| 176 | #define M_IO_DATA_ASSERT_EN (BIT(23)) |
| 177 | #define M_RX_FIFO_RD_ERR_EN (BIT(24)) |
| 178 | #define M_RX_FIFO_WR_ERR_EN (BIT(25)) |
| 179 | #define M_RX_FIFO_WATERMARK_EN (BIT(26)) |
| 180 | #define M_RX_FIFO_LAST_EN (BIT(27)) |
| 181 | #define M_TX_FIFO_RD_ERR_EN (BIT(28)) |
| 182 | #define M_TX_FIFO_WR_ERR_EN (BIT(29)) |
| 183 | #define M_TX_FIFO_WATERMARK_EN (BIT(30)) |
| 184 | #define M_SEC_IRQ_EN (BIT(31)) |
| 185 | #define M_COMMON_GENI_M_IRQ_EN (GENMASK(3, 0) | M_TIMESTAMP_EN | \ |
| 186 | GENMASK(14, 8) | M_IO_DATA_DEASSERT_EN | \ |
| 187 | M_IO_DATA_ASSERT_EN | M_RX_FIFO_RD_ERR_EN | \ |
| 188 | M_RX_FIFO_WR_ERR_EN | M_TX_FIFO_RD_ERR_EN | \ |
| 189 | M_TX_FIFO_WR_ERR_EN | M_SEC_IRQ_EN) |
| 190 | |
| 191 | /* GENI_S_IRQ_EN fields */ |
| 192 | #define S_CMD_DONE_EN (BIT(0)) |
| 193 | #define S_CMD_OVERRUN_EN (BIT(1)) |
| 194 | #define S_ILLEGAL_CMD_EN (BIT(2)) |
| 195 | #define S_CMD_FAILURE_EN (BIT(3)) |
| 196 | #define S_CMD_CANCEL_EN (BIT(4)) |
| 197 | #define S_CMD_ABORT_EN (BIT(5)) |
| 198 | #define S_GP_SYNC_IRQ_0_EN (BIT(8)) |
| 199 | #define S_GP_IRQ_0_EN (BIT(9)) |
| 200 | #define S_GP_IRQ_1_EN (BIT(10)) |
| 201 | #define S_GP_IRQ_2_EN (BIT(11)) |
| 202 | #define S_GP_IRQ_3_EN (BIT(12)) |
| 203 | #define S_GP_IRQ_4_EN (BIT(13)) |
| 204 | #define S_GP_IRQ_5_EN (BIT(14)) |
| 205 | #define S_IO_DATA_DEASSERT_EN (BIT(22)) |
| 206 | #define S_IO_DATA_ASSERT_EN (BIT(23)) |
| 207 | #define S_RX_FIFO_RD_ERR_EN (BIT(24)) |
| 208 | #define S_RX_FIFO_WR_ERR_EN (BIT(25)) |
| 209 | #define S_RX_FIFO_WATERMARK_EN (BIT(26)) |
| 210 | #define S_RX_FIFO_LAST_EN (BIT(27)) |
| 211 | #define S_COMMON_GENI_S_IRQ_EN (GENMASK(3, 0) | GENMASK(14, 8) | \ |
| 212 | S_RX_FIFO_RD_ERR_EN | S_RX_FIFO_WR_ERR_EN) |
| 213 | |
| 214 | /* GENI_/TX/RX/RX_RFR/_WATERMARK_REG fields */ |
| 215 | #define WATERMARK_MSK (GENMASK(5, 0)) |
| 216 | |
| 217 | /* GENI_TX_FIFO_STATUS fields */ |
| 218 | #define TX_FIFO_WC (GENMASK(27, 0)) |
| 219 | |
| 220 | /* GENI_RX_FIFO_STATUS fields */ |
| 221 | #define RX_LAST (BIT(31)) |
| 222 | #define RX_LAST_BYTE_VALID_MSK (GENMASK(30, 28)) |
| 223 | #define RX_LAST_BYTE_VALID_SHFT (28) |
| 224 | #define RX_FIFO_WC_MSK (GENMASK(24, 0)) |
| 225 | |
Girish Mahadevan | a95a361 | 2017-04-19 11:49:24 -0600 | [diff] [blame] | 226 | /* SE_GSI_EVENT_EN fields */ |
| 227 | #define DMA_RX_EVENT_EN (BIT(0)) |
| 228 | #define DMA_TX_EVENT_EN (BIT(1)) |
| 229 | #define GENI_M_EVENT_EN (BIT(2)) |
| 230 | #define GENI_S_EVENT_EN (BIT(3)) |
| 231 | |
Girish Mahadevan | 7115f4e | 2017-03-15 15:18:34 -0600 | [diff] [blame^] | 232 | /* SE_GENI_IOS fields */ |
| 233 | #define IO2_DATA_IN (BIT(1)) |
| 234 | #define RX_DATA_IN (BIT(0)) |
| 235 | |
Sagar Dharia | 7c927c0 | 2016-11-23 11:51:43 -0700 | [diff] [blame] | 236 | /* SE_IRQ_EN fields */ |
| 237 | #define DMA_RX_IRQ_EN (BIT(0)) |
| 238 | #define DMA_TX_IRQ_EN (BIT(1)) |
| 239 | #define GENI_M_IRQ_EN (BIT(2)) |
| 240 | #define GENI_S_IRQ_EN (BIT(3)) |
| 241 | |
| 242 | /* SE_HW_PARAM_0 fields */ |
| 243 | #define TX_FIFO_WIDTH_MSK (GENMASK(29, 24)) |
| 244 | #define TX_FIFO_WIDTH_SHFT (24) |
| 245 | #define TX_FIFO_DEPTH_MSK (GENMASK(21, 16)) |
| 246 | #define TX_FIFO_DEPTH_SHFT (16) |
| 247 | |
| 248 | /* SE_HW_PARAM_1 fields */ |
| 249 | #define RX_FIFO_WIDTH_MSK (GENMASK(29, 24)) |
| 250 | #define RX_FIFO_WIDTH_SHFT (24) |
| 251 | #define RX_FIFO_DEPTH_MSK (GENMASK(21, 16)) |
| 252 | #define RX_FIFO_DEPTH_SHFT (16) |
| 253 | |
| 254 | /* SE_DMA_GENERAL_CFG */ |
| 255 | #define DMA_RX_CLK_CGC_ON (BIT(0)) |
| 256 | #define DMA_TX_CLK_CGC_ON (BIT(1)) |
| 257 | #define DMA_AHB_SLV_CFG_ON (BIT(2)) |
| 258 | #define AHB_SEC_SLV_CLK_CGC_ON (BIT(3)) |
| 259 | #define DUMMY_RX_NON_BUFFERABLE (BIT(4)) |
| 260 | #define RX_DMA_ZERO_PADDING_EN (BIT(5)) |
| 261 | #define RX_DMA_IRQ_DELAY_MSK (GENMASK(8, 6)) |
| 262 | #define RX_DMA_IRQ_DELAY_SHFT (6) |
| 263 | |
Girish Mahadevan | bd9b44f | 2017-04-11 13:11:10 -0600 | [diff] [blame] | 264 | static inline unsigned int geni_read_reg_nolog(void __iomem *base, int offset) |
| 265 | { |
| 266 | return readl_relaxed_no_log(base + offset); |
| 267 | } |
| 268 | |
| 269 | static inline void geni_write_reg_nolog(unsigned int value, void __iomem *base, |
| 270 | int offset) |
| 271 | { |
| 272 | return writel_relaxed_no_log(value, (base + offset)); |
| 273 | } |
| 274 | |
Sagar Dharia | 7c927c0 | 2016-11-23 11:51:43 -0700 | [diff] [blame] | 275 | static inline unsigned int geni_read_reg(void __iomem *base, int offset) |
| 276 | { |
| 277 | return readl_relaxed(base + offset); |
| 278 | } |
| 279 | |
| 280 | static inline void geni_write_reg(unsigned int value, void __iomem *base, |
| 281 | int offset) |
| 282 | { |
Girish Mahadevan | 7115f4e | 2017-03-15 15:18:34 -0600 | [diff] [blame^] | 283 | writel_relaxed(value, (base + offset)); |
Sagar Dharia | 7c927c0 | 2016-11-23 11:51:43 -0700 | [diff] [blame] | 284 | } |
| 285 | |
| 286 | static inline int get_se_proto(void __iomem *base) |
| 287 | { |
| 288 | int proto = 0; |
| 289 | |
| 290 | proto = ((geni_read_reg(base, GENI_FW_REVISION_RO) |
| 291 | & FW_REV_PROTOCOL_MSK) >> FW_REV_PROTOCOL_SHFT); |
| 292 | return proto; |
| 293 | } |
| 294 | |
| 295 | static inline int se_geni_irq_en(void __iomem *base, int mode) |
| 296 | { |
| 297 | int ret = 0; |
| 298 | unsigned int common_geni_m_irq_en; |
| 299 | unsigned int common_geni_s_irq_en; |
| 300 | int proto = get_se_proto(base); |
| 301 | |
| 302 | common_geni_m_irq_en = geni_read_reg(base, SE_GENI_M_IRQ_EN); |
| 303 | common_geni_s_irq_en = geni_read_reg(base, SE_GENI_S_IRQ_EN); |
| 304 | /* Common to all modes */ |
| 305 | common_geni_m_irq_en |= M_COMMON_GENI_M_IRQ_EN; |
| 306 | common_geni_s_irq_en |= S_COMMON_GENI_S_IRQ_EN; |
| 307 | |
| 308 | switch (mode) { |
| 309 | case FIFO_MODE: |
| 310 | { |
Girish Mahadevan | 2ef85af | 2017-02-14 14:42:22 -0700 | [diff] [blame] | 311 | if (proto != UART) { |
Sagar Dharia | 7c927c0 | 2016-11-23 11:51:43 -0700 | [diff] [blame] | 312 | common_geni_m_irq_en |= |
Girish Mahadevan | 2ef85af | 2017-02-14 14:42:22 -0700 | [diff] [blame] | 313 | (M_CMD_DONE_EN | M_TX_FIFO_WATERMARK_EN | |
| 314 | M_RX_FIFO_WATERMARK_EN | M_RX_FIFO_LAST_EN); |
Sagar Dharia | 7c927c0 | 2016-11-23 11:51:43 -0700 | [diff] [blame] | 315 | common_geni_s_irq_en |= S_CMD_DONE_EN; |
| 316 | } |
| 317 | break; |
| 318 | } |
| 319 | case GSI_DMA: |
| 320 | break; |
| 321 | default: |
| 322 | pr_err("%s: Invalid mode %d\n", __func__, mode); |
| 323 | ret = -ENXIO; |
| 324 | goto exit_irq_en; |
| 325 | } |
| 326 | |
| 327 | |
| 328 | geni_write_reg(common_geni_m_irq_en, base, SE_GENI_M_IRQ_EN); |
| 329 | geni_write_reg(common_geni_s_irq_en, base, SE_GENI_S_IRQ_EN); |
| 330 | exit_irq_en: |
| 331 | return ret; |
| 332 | } |
| 333 | |
| 334 | |
| 335 | static inline void se_set_rx_rfr_wm(void __iomem *base, unsigned int rx_wm, |
| 336 | unsigned int rx_rfr) |
| 337 | { |
| 338 | geni_write_reg(rx_wm, base, SE_GENI_RX_WATERMARK_REG); |
| 339 | geni_write_reg(rx_rfr, base, SE_GENI_RX_RFR_WATERMARK_REG); |
| 340 | } |
| 341 | |
| 342 | static inline int se_io_set_mode(void __iomem *base, int mode) |
| 343 | { |
| 344 | int ret = 0; |
| 345 | unsigned int io_mode = 0; |
| 346 | unsigned int geni_dma_mode = 0; |
Girish Mahadevan | a95a361 | 2017-04-19 11:49:24 -0600 | [diff] [blame] | 347 | unsigned int gsi_event_en = 0; |
Sagar Dharia | 7c927c0 | 2016-11-23 11:51:43 -0700 | [diff] [blame] | 348 | |
| 349 | io_mode = geni_read_reg(base, SE_IRQ_EN); |
| 350 | geni_dma_mode = geni_read_reg(base, SE_GENI_DMA_MODE_EN); |
Girish Mahadevan | a95a361 | 2017-04-19 11:49:24 -0600 | [diff] [blame] | 351 | gsi_event_en = geni_read_reg(base, SE_GSI_EVENT_EN); |
Sagar Dharia | 7c927c0 | 2016-11-23 11:51:43 -0700 | [diff] [blame] | 352 | |
| 353 | switch (mode) { |
| 354 | case FIFO_MODE: |
| 355 | { |
| 356 | io_mode |= (GENI_M_IRQ_EN | GENI_S_IRQ_EN); |
| 357 | io_mode |= (DMA_TX_IRQ_EN | DMA_RX_IRQ_EN); |
| 358 | geni_dma_mode &= ~GENI_DMA_MODE_EN; |
Girish Mahadevan | a95a361 | 2017-04-19 11:49:24 -0600 | [diff] [blame] | 359 | gsi_event_en = 0; |
Sagar Dharia | 7c927c0 | 2016-11-23 11:51:43 -0700 | [diff] [blame] | 360 | break; |
| 361 | |
| 362 | } |
Girish Mahadevan | a95a361 | 2017-04-19 11:49:24 -0600 | [diff] [blame] | 363 | case GSI_DMA: |
| 364 | geni_dma_mode |= GENI_DMA_MODE_EN; |
| 365 | io_mode &= ~(DMA_TX_IRQ_EN | DMA_RX_IRQ_EN); |
| 366 | gsi_event_en |= (DMA_RX_EVENT_EN | DMA_TX_EVENT_EN | |
| 367 | GENI_M_EVENT_EN | GENI_S_EVENT_EN); |
| 368 | break; |
Sagar Dharia | 7c927c0 | 2016-11-23 11:51:43 -0700 | [diff] [blame] | 369 | default: |
| 370 | ret = -ENXIO; |
| 371 | goto exit_set_mode; |
| 372 | } |
| 373 | geni_write_reg(io_mode, base, SE_IRQ_EN); |
| 374 | geni_write_reg(geni_dma_mode, base, SE_GENI_DMA_MODE_EN); |
Girish Mahadevan | a95a361 | 2017-04-19 11:49:24 -0600 | [diff] [blame] | 375 | geni_write_reg(gsi_event_en, base, SE_GSI_EVENT_EN); |
Sagar Dharia | 7c927c0 | 2016-11-23 11:51:43 -0700 | [diff] [blame] | 376 | exit_set_mode: |
| 377 | return ret; |
| 378 | } |
| 379 | |
| 380 | static inline void se_io_init(void __iomem *base) |
| 381 | { |
| 382 | unsigned int io_op_ctrl = 0; |
| 383 | unsigned int geni_cgc_ctrl; |
| 384 | unsigned int dma_general_cfg; |
| 385 | |
| 386 | geni_cgc_ctrl = geni_read_reg(base, GENI_CGC_CTRL); |
| 387 | dma_general_cfg = geni_read_reg(base, SE_DMA_GENERAL_CFG); |
| 388 | geni_cgc_ctrl |= DEFAULT_CGC_EN; |
| 389 | dma_general_cfg |= (AHB_SEC_SLV_CLK_CGC_ON | DMA_AHB_SLV_CFG_ON | |
| 390 | DMA_TX_CLK_CGC_ON | DMA_RX_CLK_CGC_ON); |
| 391 | io_op_ctrl |= DEFAULT_IO_OUTPUT_CTRL_MSK; |
| 392 | geni_write_reg(geni_cgc_ctrl, base, GENI_CGC_CTRL); |
| 393 | geni_write_reg(dma_general_cfg, base, SE_DMA_GENERAL_CFG); |
| 394 | |
| 395 | geni_write_reg(io_op_ctrl, base, GENI_OUTPUT_CTRL); |
| 396 | geni_write_reg(FORCE_DEFAULT, base, GENI_FORCE_DEFAULT_REG); |
| 397 | } |
| 398 | |
| 399 | static inline int geni_se_init(void __iomem *base, int mode, |
| 400 | unsigned int rx_wm, unsigned int rx_rfr) |
| 401 | { |
| 402 | int ret = 0; |
| 403 | |
| 404 | se_io_init(base); |
| 405 | ret = se_io_set_mode(base, mode); |
| 406 | if (ret) |
| 407 | goto exit_geni_se_init; |
| 408 | |
| 409 | se_set_rx_rfr_wm(base, rx_wm, rx_rfr); |
| 410 | ret = se_geni_irq_en(base, mode); |
| 411 | if (ret) |
| 412 | goto exit_geni_se_init; |
| 413 | |
| 414 | exit_geni_se_init: |
| 415 | return ret; |
| 416 | } |
| 417 | |
| 418 | static inline void geni_setup_m_cmd(void __iomem *base, u32 cmd, |
| 419 | u32 params) |
| 420 | { |
| 421 | u32 m_cmd = geni_read_reg(base, SE_GENI_M_CMD0); |
| 422 | |
| 423 | m_cmd &= ~(M_OPCODE_MSK | M_PARAMS_MSK); |
| 424 | m_cmd |= (cmd << M_OPCODE_SHFT); |
| 425 | m_cmd |= (params & M_PARAMS_MSK); |
| 426 | geni_write_reg(m_cmd, base, SE_GENI_M_CMD0); |
| 427 | } |
| 428 | |
| 429 | static inline void geni_setup_s_cmd(void __iomem *base, u32 cmd, |
| 430 | u32 params) |
| 431 | { |
| 432 | u32 s_cmd = geni_read_reg(base, SE_GENI_S_CMD0); |
| 433 | |
| 434 | s_cmd &= ~(S_OPCODE_MSK | S_PARAMS_MSK); |
| 435 | s_cmd |= (cmd << S_OPCODE_SHFT); |
| 436 | s_cmd |= (params & S_PARAMS_MSK); |
| 437 | geni_write_reg(s_cmd, base, SE_GENI_S_CMD0); |
| 438 | } |
| 439 | |
| 440 | static inline void geni_cancel_m_cmd(void __iomem *base) |
| 441 | { |
| 442 | geni_write_reg(M_GENI_CMD_CANCEL, base, SE_GENI_S_CMD_CTRL_REG); |
| 443 | } |
| 444 | |
| 445 | static inline void geni_cancel_s_cmd(void __iomem *base) |
| 446 | { |
| 447 | geni_write_reg(S_GENI_CMD_CANCEL, base, SE_GENI_S_CMD_CTRL_REG); |
| 448 | } |
| 449 | |
| 450 | static inline void geni_abort_m_cmd(void __iomem *base) |
| 451 | { |
| 452 | geni_write_reg(M_GENI_CMD_ABORT, base, SE_GENI_M_CMD_CTRL_REG); |
| 453 | } |
| 454 | |
Girish Mahadevan | 24f5659 | 2017-04-15 17:35:05 -0600 | [diff] [blame] | 455 | static inline void geni_abort_s_cmd(void __iomem *base) |
Sagar Dharia | 7c927c0 | 2016-11-23 11:51:43 -0700 | [diff] [blame] | 456 | { |
| 457 | geni_write_reg(S_GENI_CMD_ABORT, base, SE_GENI_S_CMD_CTRL_REG); |
| 458 | } |
| 459 | |
| 460 | static inline int get_tx_fifo_depth(void __iomem *base) |
| 461 | { |
| 462 | int tx_fifo_depth; |
| 463 | |
| 464 | tx_fifo_depth = ((geni_read_reg(base, SE_HW_PARAM_0) |
| 465 | & TX_FIFO_DEPTH_MSK) >> TX_FIFO_DEPTH_SHFT); |
| 466 | return tx_fifo_depth; |
| 467 | } |
| 468 | |
| 469 | static inline int get_tx_fifo_width(void __iomem *base) |
| 470 | { |
| 471 | int tx_fifo_width; |
| 472 | |
| 473 | tx_fifo_width = ((geni_read_reg(base, SE_HW_PARAM_0) |
| 474 | & TX_FIFO_WIDTH_MSK) >> TX_FIFO_WIDTH_SHFT); |
| 475 | return tx_fifo_width; |
| 476 | } |
| 477 | |
| 478 | static inline int get_rx_fifo_depth(void __iomem *base) |
| 479 | { |
| 480 | int rx_fifo_depth; |
| 481 | |
| 482 | rx_fifo_depth = ((geni_read_reg(base, SE_HW_PARAM_1) |
| 483 | & RX_FIFO_DEPTH_MSK) >> RX_FIFO_DEPTH_SHFT); |
| 484 | return rx_fifo_depth; |
| 485 | } |
| 486 | |
Girish Mahadevan | b1ab172 | 2017-04-27 16:39:11 -0600 | [diff] [blame] | 487 | static inline void se_get_packing_config(int bpw, int pack_words, |
| 488 | bool msb_to_lsb, unsigned long *cfg0, |
| 489 | unsigned long *cfg1) |
Sagar Dharia | 7c927c0 | 2016-11-23 11:51:43 -0700 | [diff] [blame] | 490 | { |
| 491 | u32 cfg[4] = {0}; |
Sagar Dharia | 7c927c0 | 2016-11-23 11:51:43 -0700 | [diff] [blame] | 492 | int len = ((bpw < 8) ? (bpw - 1) : 7); |
| 493 | int idx = ((msb_to_lsb == 1) ? len : 0); |
| 494 | int iter = (bpw * pack_words) >> 3; |
| 495 | int i; |
| 496 | |
| 497 | for (i = 0; i < iter; i++) { |
| 498 | cfg[i] = ((idx << 5) | (msb_to_lsb << 4) | (len << 1)); |
| 499 | idx += (len + 1); |
| 500 | if (i == iter - 1) |
| 501 | cfg[i] |= 1; |
| 502 | } |
Girish Mahadevan | b1ab172 | 2017-04-27 16:39:11 -0600 | [diff] [blame] | 503 | *cfg0 = cfg[0] | (cfg[1] << 10); |
| 504 | *cfg1 = cfg[2] | (cfg[3] << 10); |
| 505 | } |
| 506 | |
| 507 | static inline void se_config_packing(void __iomem *base, int bpw, |
| 508 | int pack_words, bool msb_to_lsb) |
| 509 | { |
| 510 | unsigned long cfg0, cfg1; |
| 511 | |
| 512 | se_get_packing_config(bpw, pack_words, msb_to_lsb, &cfg0, &cfg1); |
Sagar Dharia | 7c927c0 | 2016-11-23 11:51:43 -0700 | [diff] [blame] | 513 | geni_write_reg(cfg0, base, SE_GENI_TX_PACKING_CFG0); |
| 514 | geni_write_reg(cfg1, base, SE_GENI_TX_PACKING_CFG1); |
| 515 | geni_write_reg(cfg0, base, SE_GENI_RX_PACKING_CFG0); |
| 516 | geni_write_reg(cfg1, base, SE_GENI_RX_PACKING_CFG1); |
| 517 | } |
Girish Mahadevan | ebeed35 | 2016-11-23 10:59:29 -0700 | [diff] [blame] | 518 | |
| 519 | /* |
| 520 | * Power/Resource Management functions |
| 521 | */ |
| 522 | |
| 523 | static inline int se_geni_clks_off(struct se_geni_rsc *rsc) |
| 524 | { |
| 525 | int ret = 0; |
| 526 | |
| 527 | clk_disable_unprepare(rsc->se_clk); |
| 528 | clk_disable_unprepare(rsc->m_ahb_clk); |
| 529 | clk_disable_unprepare(rsc->s_ahb_clk); |
| 530 | return ret; |
| 531 | } |
| 532 | |
| 533 | static inline int se_geni_resources_off(struct se_geni_rsc *rsc) |
| 534 | { |
| 535 | int ret = 0; |
| 536 | |
| 537 | ret = pinctrl_select_state(rsc->geni_pinctrl, rsc->geni_gpio_sleep); |
| 538 | se_geni_clks_off(rsc); |
| 539 | if (rsc->bus_bw) |
| 540 | msm_bus_scale_update_bw(rsc->bus_bw, 0, 0); |
| 541 | return ret; |
| 542 | } |
| 543 | |
| 544 | static inline int se_geni_clks_on(struct se_geni_rsc *rsc) |
| 545 | { |
| 546 | int ret = 0; |
| 547 | |
| 548 | clk_prepare_enable(rsc->se_clk); |
| 549 | clk_prepare_enable(rsc->m_ahb_clk); |
| 550 | clk_prepare_enable(rsc->s_ahb_clk); |
| 551 | return ret; |
| 552 | } |
| 553 | |
| 554 | static inline int se_geni_resources_on(struct se_geni_rsc *rsc) |
| 555 | { |
| 556 | int ret = 0; |
| 557 | |
| 558 | if (rsc->bus_bw) |
| 559 | msm_bus_scale_update_bw(rsc->bus_bw, rsc->ab, rsc->ib); |
| 560 | se_geni_clks_on(rsc); |
| 561 | ret = pinctrl_select_state(rsc->geni_pinctrl, rsc->geni_gpio_active); |
| 562 | return ret; |
| 563 | } |
Sagar Dharia | 7c927c0 | 2016-11-23 11:51:43 -0700 | [diff] [blame] | 564 | #endif |