root/drivers/media/platform/qcom/camss/camss-csiphy-3ph-1-0.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. csiphy_hw_version_read
  2. csiphy_reset
  3. csiphy_isr
  4. csiphy_settle_cnt_calc
  5. csiphy_lanes_enable
  6. csiphy_lanes_disable

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * camss-csiphy-3ph-1-0.c
   4  *
   5  * Qualcomm MSM Camera Subsystem - CSIPHY Module 3phase v1.0
   6  *
   7  * Copyright (c) 2011-2015, The Linux Foundation. All rights reserved.
   8  * Copyright (C) 2016-2018 Linaro Ltd.
   9  */
  10 
  11 #include "camss-csiphy.h"
  12 
  13 #include <linux/delay.h>
  14 #include <linux/interrupt.h>
  15 #include <linux/io.h>
  16 
  17 #define CSIPHY_3PH_LNn_CFG1(n)                  (0x000 + 0x100 * (n))
  18 #define CSIPHY_3PH_LNn_CFG1_SWI_REC_DLY_PRG     (BIT(7) | BIT(6))
  19 #define CSIPHY_3PH_LNn_CFG2(n)                  (0x004 + 0x100 * (n))
  20 #define CSIPHY_3PH_LNn_CFG2_LP_REC_EN_INT       BIT(3)
  21 #define CSIPHY_3PH_LNn_CFG3(n)                  (0x008 + 0x100 * (n))
  22 #define CSIPHY_3PH_LNn_CFG4(n)                  (0x00c + 0x100 * (n))
  23 #define CSIPHY_3PH_LNn_CFG4_T_HS_CLK_MISS       0xa4
  24 #define CSIPHY_3PH_LNn_CFG5(n)                  (0x010 + 0x100 * (n))
  25 #define CSIPHY_3PH_LNn_CFG5_T_HS_DTERM          0x02
  26 #define CSIPHY_3PH_LNn_CFG5_HS_REC_EQ_FQ_INT    0x50
  27 #define CSIPHY_3PH_LNn_TEST_IMP(n)              (0x01c + 0x100 * (n))
  28 #define CSIPHY_3PH_LNn_TEST_IMP_HS_TERM_IMP     0xa
  29 #define CSIPHY_3PH_LNn_MISC1(n)                 (0x028 + 0x100 * (n))
  30 #define CSIPHY_3PH_LNn_MISC1_IS_CLKLANE         BIT(2)
  31 #define CSIPHY_3PH_LNn_CFG6(n)                  (0x02c + 0x100 * (n))
  32 #define CSIPHY_3PH_LNn_CFG6_SWI_FORCE_INIT_EXIT BIT(0)
  33 #define CSIPHY_3PH_LNn_CFG7(n)                  (0x030 + 0x100 * (n))
  34 #define CSIPHY_3PH_LNn_CFG7_SWI_T_INIT          0x2
  35 #define CSIPHY_3PH_LNn_CFG8(n)                  (0x034 + 0x100 * (n))
  36 #define CSIPHY_3PH_LNn_CFG8_SWI_SKIP_WAKEUP     BIT(0)
  37 #define CSIPHY_3PH_LNn_CFG8_SKEW_FILTER_ENABLE  BIT(1)
  38 #define CSIPHY_3PH_LNn_CFG9(n)                  (0x038 + 0x100 * (n))
  39 #define CSIPHY_3PH_LNn_CFG9_SWI_T_WAKEUP        0x1
  40 #define CSIPHY_3PH_LNn_CSI_LANE_CTRL15(n)       (0x03c + 0x100 * (n))
  41 #define CSIPHY_3PH_LNn_CSI_LANE_CTRL15_SWI_SOT_SYMBOL   0xb8
  42 
  43 #define CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(n)      (0x800 + 0x4 * (n))
  44 #define CSIPHY_3PH_CMN_CSI_COMMON_CTRL6_COMMON_PWRDN_B  BIT(0)
  45 #define CSIPHY_3PH_CMN_CSI_COMMON_CTRL6_SHOW_REV_ID     BIT(1)
  46 #define CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(n)    (0x8b0 + 0x4 * (n))
  47 
  48 static void csiphy_hw_version_read(struct csiphy_device *csiphy,
  49                                    struct device *dev)
  50 {
  51         u32 hw_version;
  52 
  53         writel(CSIPHY_3PH_CMN_CSI_COMMON_CTRL6_SHOW_REV_ID,
  54                csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(6));
  55 
  56         hw_version = readl_relaxed(csiphy->base +
  57                                    CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(12));
  58         hw_version |= readl_relaxed(csiphy->base +
  59                                    CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(13)) << 8;
  60         hw_version |= readl_relaxed(csiphy->base +
  61                                    CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(14)) << 16;
  62         hw_version |= readl_relaxed(csiphy->base +
  63                                    CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(15)) << 24;
  64 
  65         dev_err(dev, "CSIPHY 3PH HW Version = 0x%08x\n", hw_version);
  66 }
  67 
  68 /*
  69  * csiphy_reset - Perform software reset on CSIPHY module
  70  * @csiphy: CSIPHY device
  71  */
  72 static void csiphy_reset(struct csiphy_device *csiphy)
  73 {
  74         writel_relaxed(0x1, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(0));
  75         usleep_range(5000, 8000);
  76         writel_relaxed(0x0, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(0));
  77 }
  78 
  79 static irqreturn_t csiphy_isr(int irq, void *dev)
  80 {
  81         struct csiphy_device *csiphy = dev;
  82         int i;
  83 
  84         for (i = 0; i < 11; i++) {
  85                 int c = i + 22;
  86                 u8 val = readl_relaxed(csiphy->base +
  87                                        CSIPHY_3PH_CMN_CSI_COMMON_STATUSn(i));
  88 
  89                 writel_relaxed(val, csiphy->base +
  90                                     CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(c));
  91         }
  92 
  93         writel_relaxed(0x1, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(10));
  94         writel_relaxed(0x0, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(10));
  95 
  96         for (i = 22; i < 33; i++)
  97                 writel_relaxed(0x0, csiphy->base +
  98                                     CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(i));
  99 
 100         return IRQ_HANDLED;
 101 }
 102 
 103 /*
 104  * csiphy_settle_cnt_calc - Calculate settle count value
 105  *
 106  * Helper function to calculate settle count value. This is
 107  * based on the CSI2 T_hs_settle parameter which in turn
 108  * is calculated based on the CSI2 transmitter pixel clock
 109  * frequency.
 110  *
 111  * Return settle count value or 0 if the CSI2 pixel clock
 112  * frequency is not available
 113  */
 114 static u8 csiphy_settle_cnt_calc(u32 pixel_clock, u8 bpp, u8 num_lanes,
 115                                  u32 timer_clk_rate)
 116 {
 117         u32 mipi_clock; /* Hz */
 118         u32 ui; /* ps */
 119         u32 timer_period; /* ps */
 120         u32 t_hs_prepare_max; /* ps */
 121         u32 t_hs_settle; /* ps */
 122         u8 settle_cnt;
 123 
 124         mipi_clock = pixel_clock * bpp / (2 * num_lanes);
 125         ui = div_u64(1000000000000LL, mipi_clock);
 126         ui /= 2;
 127         t_hs_prepare_max = 85000 + 6 * ui;
 128         t_hs_settle = t_hs_prepare_max;
 129 
 130         timer_period = div_u64(1000000000000LL, timer_clk_rate);
 131         settle_cnt = t_hs_settle / timer_period - 6;
 132 
 133         return settle_cnt;
 134 }
 135 
 136 static void csiphy_lanes_enable(struct csiphy_device *csiphy,
 137                                 struct csiphy_config *cfg,
 138                                 u32 pixel_clock, u8 bpp, u8 lane_mask)
 139 {
 140         struct csiphy_lanes_cfg *c = &cfg->csi2->lane_cfg;
 141         u8 settle_cnt;
 142         u8 val, l = 0;
 143         int i;
 144 
 145         settle_cnt = csiphy_settle_cnt_calc(pixel_clock, bpp, c->num_data,
 146                                             csiphy->timer_clk_rate);
 147 
 148         val = BIT(c->clk.pos);
 149         for (i = 0; i < c->num_data; i++)
 150                 val |= BIT(c->data[i].pos * 2);
 151 
 152         writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(5));
 153 
 154         val = CSIPHY_3PH_CMN_CSI_COMMON_CTRL6_COMMON_PWRDN_B;
 155         writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(6));
 156 
 157         for (i = 0; i <= c->num_data; i++) {
 158                 if (i == c->num_data)
 159                         l = 7;
 160                 else
 161                         l = c->data[i].pos * 2;
 162 
 163                 val = CSIPHY_3PH_LNn_CFG1_SWI_REC_DLY_PRG;
 164                 val |= 0x17;
 165                 writel_relaxed(val, csiphy->base + CSIPHY_3PH_LNn_CFG1(l));
 166 
 167                 val = CSIPHY_3PH_LNn_CFG2_LP_REC_EN_INT;
 168                 writel_relaxed(val, csiphy->base + CSIPHY_3PH_LNn_CFG2(l));
 169 
 170                 val = settle_cnt;
 171                 writel_relaxed(val, csiphy->base + CSIPHY_3PH_LNn_CFG3(l));
 172 
 173                 val = CSIPHY_3PH_LNn_CFG5_T_HS_DTERM |
 174                         CSIPHY_3PH_LNn_CFG5_HS_REC_EQ_FQ_INT;
 175                 writel_relaxed(val, csiphy->base + CSIPHY_3PH_LNn_CFG5(l));
 176 
 177                 val = CSIPHY_3PH_LNn_CFG6_SWI_FORCE_INIT_EXIT;
 178                 writel_relaxed(val, csiphy->base + CSIPHY_3PH_LNn_CFG6(l));
 179 
 180                 val = CSIPHY_3PH_LNn_CFG7_SWI_T_INIT;
 181                 writel_relaxed(val, csiphy->base + CSIPHY_3PH_LNn_CFG7(l));
 182 
 183                 val = CSIPHY_3PH_LNn_CFG8_SWI_SKIP_WAKEUP |
 184                         CSIPHY_3PH_LNn_CFG8_SKEW_FILTER_ENABLE;
 185                 writel_relaxed(val, csiphy->base + CSIPHY_3PH_LNn_CFG8(l));
 186 
 187                 val = CSIPHY_3PH_LNn_CFG9_SWI_T_WAKEUP;
 188                 writel_relaxed(val, csiphy->base + CSIPHY_3PH_LNn_CFG9(l));
 189 
 190                 val = CSIPHY_3PH_LNn_TEST_IMP_HS_TERM_IMP;
 191                 writel_relaxed(val, csiphy->base + CSIPHY_3PH_LNn_TEST_IMP(l));
 192 
 193                 val = CSIPHY_3PH_LNn_CSI_LANE_CTRL15_SWI_SOT_SYMBOL;
 194                 writel_relaxed(val, csiphy->base +
 195                                     CSIPHY_3PH_LNn_CSI_LANE_CTRL15(l));
 196         }
 197 
 198         val = CSIPHY_3PH_LNn_CFG1_SWI_REC_DLY_PRG;
 199         writel_relaxed(val, csiphy->base + CSIPHY_3PH_LNn_CFG1(l));
 200 
 201         val = CSIPHY_3PH_LNn_CFG4_T_HS_CLK_MISS;
 202         writel_relaxed(val, csiphy->base + CSIPHY_3PH_LNn_CFG4(l));
 203 
 204         val = CSIPHY_3PH_LNn_MISC1_IS_CLKLANE;
 205         writel_relaxed(val, csiphy->base + CSIPHY_3PH_LNn_MISC1(l));
 206 
 207         val = 0xff;
 208         writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(11));
 209 
 210         val = 0xff;
 211         writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(12));
 212 
 213         val = 0xfb;
 214         writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(13));
 215 
 216         val = 0xff;
 217         writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(14));
 218 
 219         val = 0x7f;
 220         writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(15));
 221 
 222         val = 0xff;
 223         writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(16));
 224 
 225         val = 0xff;
 226         writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(17));
 227 
 228         val = 0xef;
 229         writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(18));
 230 
 231         val = 0xff;
 232         writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(19));
 233 
 234         val = 0xff;
 235         writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(20));
 236 
 237         val = 0xff;
 238         writel_relaxed(val, csiphy->base + CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(21));
 239 }
 240 
 241 static void csiphy_lanes_disable(struct csiphy_device *csiphy,
 242                                  struct csiphy_config *cfg)
 243 {
 244         writel_relaxed(0, csiphy->base +
 245                           CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(5));
 246 
 247         writel_relaxed(0, csiphy->base +
 248                           CSIPHY_3PH_CMN_CSI_COMMON_CTRLn(6));
 249 }
 250 
 251 const struct csiphy_hw_ops csiphy_ops_3ph_1_0 = {
 252         .hw_version_read = csiphy_hw_version_read,
 253         .reset = csiphy_reset,
 254         .lanes_enable = csiphy_lanes_enable,
 255         .lanes_disable = csiphy_lanes_disable,
 256         .isr = csiphy_isr,
 257 };

/* [<][>][^][v][top][bottom][index][help] */