unmaintained/bq-paella-downstream: cleanup, add various debug patches (MR 2081)

These are various debugging related patches that I have used over the time
when attempting to get new features working for the mainline kernel.
Given that the downstream kernel is just intended for debugging in this case,
it seems convenient to add them to pmaports so I don't need to go search for
them in case I need them again in the future.

[ci:skip-build] Already built on CI
This commit is contained in:
Minecrell 2021-02-14 17:09:12 +01:00 committed by Alexey Min
parent dfb394ab8b
commit aa1eefc44a
No known key found for this signature in database
GPG key ID: 0B19D2A65870B448
17 changed files with 418 additions and 6 deletions

View file

@ -0,0 +1,45 @@
CPR (Core Power Reduction) is Qualcomm's implementation of AVS (Adaptive Voltage Scaling).
Dynamic undervolting essentially. It depends on some calibration values encoded
in fuses. This patch dumps the fuse values in the downstream kernel which is useful
to check if the mainline driver is working correctly.
diff --git a/drivers/regulator/cpr-regulator.c b/drivers/regulator/cpr-regulator.c
index 8637d78c..880482b5 100644
--- a/drivers/regulator/cpr-regulator.c
+++ b/drivers/regulator/cpr-regulator.c
@@ -3350,6 +3350,26 @@ static int cpr_init_cpr_parameters(struct platform_device *pdev,
return 0;
}
+static void cpr_dump(struct cpr_regulator *cpr_vreg)
+{
+ int i;
+
+ cpr_info(cpr_vreg, "pvs_bin: %u, speed_bin: %u, pvs_version: %u\n",
+ cpr_vreg->pvs_bin, cpr_vreg->speed_bin, cpr_vreg->pvs_version);
+
+ for (i = CPR_FUSE_CORNER_MIN; i <= cpr_vreg->num_fuse_corners; i++) {
+ cpr_info(cpr_vreg, "FUSE[%d]: pvs_corner_v: %u, cpr_fuse_target_quot: %u, cpr_fuse_ro_sel: %u, fuse_ceiling_volt: %u, fuse_floor_volt: %u, step_quotient: %u\n",
+ i, cpr_vreg->pvs_corner_v[i], cpr_vreg->cpr_fuse_target_quot[i], cpr_vreg->cpr_fuse_ro_sel[i],
+ cpr_vreg->fuse_ceiling_volt[i], cpr_vreg->fuse_floor_volt[i],
+ cpr_vreg->step_quotient[i]);
+ }
+
+ for (i = CPR_CORNER_MIN; i <= cpr_vreg->num_corners; i++) {
+ cpr_info(cpr_vreg, "CORNER[%d]: ceiling_volt: %u, floor_volt: %u, last_volt: %u, open_loop_volt: %u, quot_adjust: %u\n",
+ i, cpr_vreg->ceiling_volt[i], cpr_vreg->floor_volt[i], cpr_vreg->last_volt[i], cpr_vreg->open_loop_volt[i], cpr_vreg->quot_adjust[i]);
+ }
+}
+
static int cpr_init_cpr(struct platform_device *pdev,
struct cpr_regulator *cpr_vreg)
{
@@ -3411,6 +3431,8 @@ static int cpr_init_cpr(struct platform_device *pdev,
if (rc)
return rc;
+ cpr_dump(cpr_vreg);
+
/* Get and Init interrupt */
cpr_vreg->cpr_irq = platform_get_irq(pdev, 0);
if (!cpr_vreg->cpr_irq) {

View file

@ -0,0 +1,95 @@
This change allows dumping the state of all GPIOs via debugfs. This is useful
for debugging sometimes. The code is mostly copied from the mainline driver
to allow comparison: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/pinctrl/qcom/pinctrl-msm.c
diff --git a/drivers/pinctrl/pinctrl-msm-tlmm.c b/drivers/pinctrl/pinctrl-msm-tlmm.c
index fc8076162a0..fa628ca0dc1 100644
--- a/drivers/pinctrl/pinctrl-msm-tlmm.c
+++ b/drivers/pinctrl/pinctrl-msm-tlmm.c
@@ -671,6 +671,78 @@ static int msm_tlmm_gp_dir_out(struct gpio_chip *gc, unsigned offset, int val)
return 0;
}
+#ifdef CONFIG_DEBUG_FS
+#include <linux/seq_file.h>
+
+/* GP PIN TYPE REG MASKS */
+#define TLMM_GP_DRV_SHFT 6
+#define TLMM_GP_DRV_MASK 0x7
+#define TLMM_GP_PULL_SHFT 0
+#define TLMM_GP_PULL_MASK 0x3
+#define TLMM_GP_DIR_SHFT 9
+#define TLMM_GP_DIR_MASK 1
+#define TLMM_GP_FUNC_SHFT 2
+#define TLMM_GP_FUNC_MASK 0xF
+#define GPIO_OUT_BIT 1
+#define GPIO_IN_BIT 0
+#define GPIO_OE_BIT 9
+
+static void msm_gpio_dbg_show_one(struct seq_file *s,
+ struct gpio_chip *gc,
+ unsigned offset,
+ unsigned gpio)
+{
+ struct msm_pintype_info *pinfo = gc_to_pintype(gc);
+ void __iomem *cfg_regp = TLMM_GP_CFG(pinfo, offset);
+ void __iomem *inout_regp = TLMM_GP_INOUT(pinfo, offset);
+
+ unsigned func;
+ int is_out;
+ int drive;
+ int pull;
+ int val;
+ u32 ctl_reg, io_reg;
+
+ static const char * const pulls_keeper[] = {
+ "no pull",
+ "pull down",
+ "keeper",
+ "pull up"
+ };
+
+ ctl_reg = readl_relaxed(cfg_regp);
+ io_reg = readl_relaxed(inout_regp);
+
+ is_out = !!(ctl_reg & BIT(GPIO_OE_BIT));
+ func = (ctl_reg >> TLMM_GP_FUNC_SHFT) & TLMM_GP_FUNC_MASK;
+ drive = (ctl_reg >> TLMM_GP_DRV_SHFT) & TLMM_GP_DRV_SHFT;
+ pull = (ctl_reg >> TLMM_GP_PULL_SHFT) & TLMM_GP_PULL_MASK;
+
+ if (is_out)
+ val = !!(io_reg & BIT(GPIO_OUT_BIT));
+ else
+ val = !!(io_reg & BIT(GPIO_IN_BIT));
+
+ seq_printf(s, " gpio%d: %-3s", offset, is_out ? "out" : "in");
+ seq_printf(s, " %-4s func%d", val ? "high" : "low", func);
+ seq_printf(s, " %dmA", rval_to_drv_str(drive));
+ seq_printf(s, " %s", pulls_keeper[pull]);
+ seq_puts(s, "\n");
+}
+
+static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)
+{
+ unsigned gpio = chip->base;
+ unsigned i;
+
+ for (i = 0; i < chip->ngpio; i++, gpio++)
+ msm_gpio_dbg_show_one(s, chip, i, gpio);
+}
+
+#else
+#define msm_gpio_dbg_show NULL
+#endif
+
static int msm_tlmm_gp_to_irq(struct gpio_chip *gc, unsigned offset)
{
struct msm_pintype_info *pinfo = gc_to_pintype(gc);
@@ -1073,6 +1145,7 @@ static struct msm_pintype_info tlmm_pininfo[] = {
.get = msm_tlmm_gp_get,
.set = msm_tlmm_gp_set,
.to_irq = msm_tlmm_gp_to_irq,
+ .dbg_show = msm_gpio_dbg_show,
},
.init_irq = msm_tlmm_gp_irq_init,
.irq_chip = &msm_tlmm_gp_irq,

View file

@ -0,0 +1,15 @@
This is useful for debugging GPS problems on some Qualcomm SoCs (e.g. msm8916),
since memshare is needed for that to work.
diff --git a/drivers/soc/qcom/memshare/msm_memshare.c b/drivers/soc/qcom/memshare/msm_memshare.c
index eafbbf42457..1185825b32b 100644
--- a/drivers/soc/qcom/memshare/msm_memshare.c
+++ b/drivers/soc/qcom/memshare/msm_memshare.c
@@ -10,6 +10,7 @@
* GNU General Public License for more details.
*
*/
+#define DEBUG
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/module.h>

View file

@ -0,0 +1,27 @@
gcc-wrapper.py is stupid, slow and requires Python 2. Basically it's just
supposed to make the build fail on certain hardcoded compile warnings.
diff --git a/Makefile b/Makefile
index 4994d640e19..ad01b820543 100644
--- a/Makefile
+++ b/Makefile
@@ -326,7 +326,7 @@ include $(srctree)/scripts/Kbuild.include
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
-REAL_CC = $(CROSS_COMPILE)gcc
+CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
AR = $(CROSS_COMPILE)ar
NM = $(CROSS_COMPILE)nm
@@ -340,10 +340,6 @@ DEPMOD = /sbin/depmod
PERL = perl
CHECK = sparse
-# Use the wrapper for the compiler. This wrapper scans for new
-# warnings and causes the build to stop upon encountering them.
-CC = $(srctree)/scripts/gcc-wrapper.py $(REAL_CC)
-
CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ \
-Wbitwise -Wno-return-void $(CF)
CFLAGS_MODULE =

View file

@ -0,0 +1,61 @@
Enable most of the relevant debug log messages in the smb1360 driver.
Those are useful to see how it behaves on downstream to check if the mainline driver
for it works correctly (see https://github.com/msm8916-mainline/linux/pull/155).
diff --git a/drivers/power/smb1360-charger-fg.c b/drivers/power/smb1360-charger-fg.c
index 249b9825550..d9fdb9fd1cd 100644
--- a/drivers/power/smb1360-charger-fg.c
+++ b/drivers/power/smb1360-charger-fg.c
@@ -9,6 +9,7 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
+#define DEBUG
#define pr_fmt(fmt) "SMB:%s: " fmt, __func__
#include <linux/i2c.h>
@@ -543,7 +544,7 @@ static int __smb1360_read(struct smb1360_chip *chip, int reg,
} else {
*val = ret;
}
- pr_debug("Reading 0x%02x=0x%02x\n", reg, *val);
+ //pr_debug("Reading 0x%02x=0x%02x\n", reg, *val);
return 0;
}
@@ -742,7 +743,7 @@ static int64_t float_decode(u16 reg)
mantissa = (reg & MANTISSA_MASK);
sign = !!(reg & SIGN_MASK);
- pr_debug("exponent=%d mantissa=%d sign=%d\n", exponent, mantissa, sign);
+ //pr_debug("exponent=%d mantissa=%d sign=%d\n", exponent, mantissa, sign);
mantissa_val = mantissa * MICRO_UNIT;
@@ -1139,6 +1140,10 @@ static enum power_supply_property smb1360_battery_properties[] = {
};
static int smb1360_get_prop_batt_present(struct smb1360_chip *chip)
+/* Disable pr_debug() for read routines, those spam too much */
+#pragma push_macro("pr_debug")
+#undef pr_debug
+#define pr_debug(fmt, ...)
{
return chip->batt_present;
}
@@ -1381,6 +1386,7 @@ static int smb1360_get_prop_current_now(struct smb1360_chip *chip)
}
static int smb1360_set_minimum_usb_current(struct smb1360_chip *chip)
+#pragma pop_macro("pr_debug")
{
int rc = 0;
@@ -2828,7 +2834,7 @@ static irqreturn_t smb1360_stat_handler(int irq, void *dev_id)
handlers[i].prev_val = handlers[i].val;
}
- pr_debug("handler count = %d\n", handler_count);
+ //pr_debug("handler count = %d\n", handler_count);
if (handler_count)
power_supply_changed(&chip->batt_psy);

View file

@ -0,0 +1,92 @@
Dump all known registers of the SMB1360 battery/charging chip.
The same output can be generated with the mainline driver which allows verifying
if all the registers are set correctly.
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index b8ae7ae0ef7..b88d1905a3c 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -1,6 +1,7 @@
ccflags-$(CONFIG_POWER_SUPPLY_DEBUG) := -DDEBUG
power_supply-y := power_supply_core.o
+power_supply-y += smb1360-dump.o
power_supply-$(CONFIG_SYSFS) += power_supply_sysfs.o
power_supply-$(CONFIG_LEDS_TRIGGERS) += power_supply_leds.o
diff --git a/drivers/power/smb1360-charger-fg.c b/drivers/power/smb1360-charger-fg.c
index 7931b6df9be..249b9825550 100644
--- a/drivers/power/smb1360-charger-fg.c
+++ b/drivers/power/smb1360-charger-fg.c
@@ -4347,12 +4347,50 @@ static int smb1360_hw_init(struct smb1360_chip *chip)
return rc;
}
+extern void smb1360_dump(struct i2c_client *client);
+extern void smb1360_dump_fg_scratch(struct i2c_client *fg_client);
+extern void smb1360_dump_fg(struct i2c_client *client);
+
+static void smb1360_dump_locked(struct smb1360_chip *chip)
+{
+ mutex_lock(&chip->read_write_lock);
+ smb1360_dump(chip->client);
+ mutex_unlock(&chip->read_write_lock);
+}
+
+static void smb1360_dump_fg_access(struct smb1360_chip *chip)
+{
+ int ret;
+
+ ret = smb1360_enable_fg_access(chip);
+ if (ret)
+ return;
+
+ mutex_lock(&chip->read_write_lock);
+ smb1360_dump_fg_scratch(chip->client);
+
+ /* Do cool hacks to access FG I2C address instead */
+ chip->fg_access_type = FG_ACCESS_CFG;
+ smb1360_select_fg_i2c_address(chip);
+
+ chip->client->addr = chip->fg_i2c_addr;
+ smb1360_dump_fg(chip->client);
+ chip->client->addr = chip->default_i2c_addr;
+ mutex_unlock(&chip->read_write_lock);
+
+ smb1360_disable_fg_access(chip);
+ smb1360_check_cycle_stretch(chip);
+}
+
static int smb1360_delayed_hw_init(struct smb1360_chip *chip)
{
int rc;
pr_debug("delayed hw init start!\n");
+ /* Dump initial FG registers */
+ smb1360_dump_fg_access(chip);
+
if (chip->otp_hard_jeita_config) {
rc = smb1360_hard_jeita_otp_init(chip);
if (rc) {
@@ -4386,6 +4424,10 @@ static int smb1360_delayed_hw_init(struct smb1360_chip *chip)
}
pr_debug("delayed hw init complete!\n");
+
+ /* Dump final registers */
+ smb1360_dump_locked(chip);
+ smb1360_dump_fg_access(chip);
return rc;
}
@@ -4945,6 +4987,9 @@ static int smb1360_probe(struct i2c_client *client,
INIT_WORK(&chip->jeita_hysteresis_work,
smb1360_jeita_hysteresis_work);
+ /* Dump initial registers */
+ smb1360_dump_locked(chip);
+
pr_debug("default_i2c_addr=%x\n", chip->default_i2c_addr);
smb1360_otp_backup_pool_init(chip);
rc = smb1360_hw_init(chip);

View file

@ -0,0 +1,16 @@
The smb1360 mainline driver does some rounding slightly differently.
Change the downstream driver accordingly, so register dumps can be compared more easily.
diff --git a/drivers/power/smb1360-charger-fg.c b/drivers/power/smb1360-charger-fg.c
index 7931b6df9be..90da1ad93b3 100644
--- a/drivers/power/smb1360-charger-fg.c
+++ b/drivers/power/smb1360-charger-fg.c
@@ -3653,7 +3653,7 @@ disable_fg_reset:
if (chip->soc_min != -EINVAL) {
if (is_between(chip->soc_min, 0, 100)) {
- reg = DIV_ROUND_UP(chip->soc_min * MAX_8_BITS,
+ reg = DIV_ROUND_CLOSEST(chip->soc_min * MAX_8_BITS,
100);
pr_debug("soc_min=%d reg=%x\n",
chip->soc_min, reg);