root/arch/arm/mach-imx/anatop.c

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

DEFINITIONS

This source file includes following definitions.
  1. imx_anatop_enable_weak2p5
  2. imx_anatop_enable_fet_odrive
  3. imx_anatop_enable_2p5_pulldown
  4. imx_anatop_disconnect_high_snvs
  5. imx_anatop_pre_suspend
  6. imx_anatop_post_resume
  7. imx_anatop_usb_chrg_detect_disable
  8. imx_init_revision_from_anatop
  9. imx_anatop_init

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Copyright (C) 2013-2015 Freescale Semiconductor, Inc.
   4  * Copyright 2017-2018 NXP.
   5  */
   6 
   7 #include <linux/err.h>
   8 #include <linux/io.h>
   9 #include <linux/of.h>
  10 #include <linux/of_address.h>
  11 #include <linux/mfd/syscon.h>
  12 #include <linux/regmap.h>
  13 #include "common.h"
  14 #include "hardware.h"
  15 
  16 #define REG_SET         0x4
  17 #define REG_CLR         0x8
  18 
  19 #define ANADIG_REG_2P5          0x130
  20 #define ANADIG_REG_CORE         0x140
  21 #define ANADIG_ANA_MISC0        0x150
  22 #define ANADIG_USB1_CHRG_DETECT 0x1b0
  23 #define ANADIG_USB2_CHRG_DETECT 0x210
  24 #define ANADIG_DIGPROG          0x260
  25 #define ANADIG_DIGPROG_IMX6SL   0x280
  26 #define ANADIG_DIGPROG_IMX7D    0x800
  27 
  28 #define SRC_SBMR2               0x1c
  29 
  30 #define BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG    0x40000
  31 #define BM_ANADIG_REG_2P5_ENABLE_PULLDOWN       0x8
  32 #define BM_ANADIG_REG_CORE_FET_ODRIVE           0x20000000
  33 #define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG    0x1000
  34 /* Below MISC0_DISCON_HIGH_SNVS is only for i.MX6SL */
  35 #define BM_ANADIG_ANA_MISC0_DISCON_HIGH_SNVS    0x2000
  36 #define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B    0x80000
  37 #define BM_ANADIG_USB_CHRG_DETECT_EN_B          0x100000
  38 
  39 static struct regmap *anatop;
  40 
  41 static void imx_anatop_enable_weak2p5(bool enable)
  42 {
  43         u32 reg, val;
  44 
  45         regmap_read(anatop, ANADIG_ANA_MISC0, &val);
  46 
  47         /* can only be enabled when stop_mode_config is clear. */
  48         reg = ANADIG_REG_2P5;
  49         reg += (enable && (val & BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG) == 0) ?
  50                 REG_SET : REG_CLR;
  51         regmap_write(anatop, reg, BM_ANADIG_REG_2P5_ENABLE_WEAK_LINREG);
  52 }
  53 
  54 static void imx_anatop_enable_fet_odrive(bool enable)
  55 {
  56         regmap_write(anatop, ANADIG_REG_CORE + (enable ? REG_SET : REG_CLR),
  57                 BM_ANADIG_REG_CORE_FET_ODRIVE);
  58 }
  59 
  60 static inline void imx_anatop_enable_2p5_pulldown(bool enable)
  61 {
  62         regmap_write(anatop, ANADIG_REG_2P5 + (enable ? REG_SET : REG_CLR),
  63                 BM_ANADIG_REG_2P5_ENABLE_PULLDOWN);
  64 }
  65 
  66 static inline void imx_anatop_disconnect_high_snvs(bool enable)
  67 {
  68         regmap_write(anatop, ANADIG_ANA_MISC0 + (enable ? REG_SET : REG_CLR),
  69                 BM_ANADIG_ANA_MISC0_DISCON_HIGH_SNVS);
  70 }
  71 
  72 void imx_anatop_pre_suspend(void)
  73 {
  74         if (imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2)
  75                 imx_anatop_enable_2p5_pulldown(true);
  76         else
  77                 imx_anatop_enable_weak2p5(true);
  78 
  79         imx_anatop_enable_fet_odrive(true);
  80 
  81         if (cpu_is_imx6sl())
  82                 imx_anatop_disconnect_high_snvs(true);
  83 }
  84 
  85 void imx_anatop_post_resume(void)
  86 {
  87         if (imx_mmdc_get_ddr_type() == IMX_DDR_TYPE_LPDDR2)
  88                 imx_anatop_enable_2p5_pulldown(false);
  89         else
  90                 imx_anatop_enable_weak2p5(false);
  91 
  92         imx_anatop_enable_fet_odrive(false);
  93 
  94         if (cpu_is_imx6sl())
  95                 imx_anatop_disconnect_high_snvs(false);
  96 
  97 }
  98 
  99 static void imx_anatop_usb_chrg_detect_disable(void)
 100 {
 101         regmap_write(anatop, ANADIG_USB1_CHRG_DETECT,
 102                 BM_ANADIG_USB_CHRG_DETECT_EN_B
 103                 | BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
 104         regmap_write(anatop, ANADIG_USB2_CHRG_DETECT,
 105                 BM_ANADIG_USB_CHRG_DETECT_EN_B |
 106                 BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
 107 }
 108 
 109 void __init imx_init_revision_from_anatop(void)
 110 {
 111         struct device_node *np;
 112         void __iomem *anatop_base;
 113         unsigned int revision;
 114         u32 digprog;
 115         u16 offset = ANADIG_DIGPROG;
 116         u8 major_part, minor_part;
 117 
 118         np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
 119         anatop_base = of_iomap(np, 0);
 120         WARN_ON(!anatop_base);
 121         if (of_device_is_compatible(np, "fsl,imx6sl-anatop"))
 122                 offset = ANADIG_DIGPROG_IMX6SL;
 123         if (of_device_is_compatible(np, "fsl,imx7d-anatop"))
 124                 offset = ANADIG_DIGPROG_IMX7D;
 125         digprog = readl_relaxed(anatop_base + offset);
 126         iounmap(anatop_base);
 127 
 128         /*
 129          * On i.MX7D digprog value match linux version format, so
 130          * it needn't map again and we can use register value directly.
 131          */
 132         if (of_device_is_compatible(np, "fsl,imx7d-anatop")) {
 133                 revision = digprog & 0xff;
 134         } else {
 135                 /*
 136                  * MAJOR: [15:8], the major silicon revison;
 137                  * MINOR: [7: 0], the minor silicon revison;
 138                  *
 139                  * please refer to the i.MX RM for the detailed
 140                  * silicon revison bit define.
 141                  * format the major part and minor part to match the
 142                  * linux kernel soc version format.
 143                  */
 144                 major_part = (digprog >> 8) & 0xf;
 145                 minor_part = digprog & 0xf;
 146                 revision = ((major_part + 1) << 4) | minor_part;
 147 
 148                 if ((digprog >> 16) == MXC_CPU_IMX6ULL) {
 149                         void __iomem *src_base;
 150                         u32 sbmr2;
 151 
 152                         np = of_find_compatible_node(NULL, NULL,
 153                                                      "fsl,imx6ul-src");
 154                         src_base = of_iomap(np, 0);
 155                         WARN_ON(!src_base);
 156                         sbmr2 = readl_relaxed(src_base + SRC_SBMR2);
 157                         iounmap(src_base);
 158 
 159                         /* src_sbmr2 bit 6 is to identify if it is i.MX6ULZ */
 160                         if (sbmr2 & (1 << 6)) {
 161                                 digprog &= ~(0xff << 16);
 162                                 digprog |= (MXC_CPU_IMX6ULZ << 16);
 163                         }
 164                 }
 165         }
 166 
 167         mxc_set_cpu_type(digprog >> 16 & 0xff);
 168         imx_set_soc_revision(revision);
 169 }
 170 
 171 void __init imx_anatop_init(void)
 172 {
 173         anatop = syscon_regmap_lookup_by_compatible("fsl,imx6q-anatop");
 174         if (IS_ERR(anatop)) {
 175                 pr_err("%s: failed to find imx6q-anatop regmap!\n", __func__);
 176                 return;
 177         }
 178 
 179         imx_anatop_usb_chrg_detect_disable();
 180 }

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