Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 30a34400 authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

Merge tag 'samsung-drivers-5.4' of...

Merge tag 'samsung-drivers-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux into arm/drivers

Samsung soc drivers changes for v5.4

Add Exynos Chipid driver for identification of product IDs and SoC
revisions.  The driver also exposes chipid regmap, later to be used by
Exynos Adaptive Supply Voltage driver (adjusting voltages to different
revisions of same SoC).

* tag 'samsung-drivers-5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux:
  soc: samsung: chipid: Convert exynos-chipid driver to use the regmap API
  soc: samsung: Add exynos chipid driver support

Link: https://lore.kernel.org/r/20190816163042.6604-1-krzk@kernel.org


Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parents 157eed91 40d8aff6
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -7,6 +7,11 @@ menuconfig SOC_SAMSUNG

if SOC_SAMSUNG

config EXYNOS_CHIPID
	bool "Exynos Chipid controller driver" if COMPILE_TEST
	depends on ARCH_EXYNOS || COMPILE_TEST
	select SOC_BUS

config EXYNOS_PMU
	bool "Exynos PMU controller driver" if COMPILE_TEST
	depends on ARCH_EXYNOS || ((ARM || ARM64) && COMPILE_TEST)
+2 −0
Original line number Diff line number Diff line
# SPDX-License-Identifier: GPL-2.0

obj-$(CONFIG_EXYNOS_CHIPID)	+= exynos-chipid.o
obj-$(CONFIG_EXYNOS_PMU)	+= exynos-pmu.o

obj-$(CONFIG_EXYNOS_PMU_ARM_DRIVERS)	+= exynos3250-pmu.o exynos4-pmu.o \
+101 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2019 Samsung Electronics Co., Ltd.
 *	      http://www.samsung.com/
 *
 * EXYNOS - CHIP ID support
 * Author: Pankaj Dubey <pankaj.dubey@samsung.com>
 * Author: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
 */

#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/of.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/soc/samsung/exynos-chipid.h>
#include <linux/sys_soc.h>

static const struct exynos_soc_id {
	const char *name;
	unsigned int id;
} soc_ids[] = {
	{ "EXYNOS3250", 0xE3472000 },
	{ "EXYNOS4210", 0x43200000 },	/* EVT0 revision */
	{ "EXYNOS4210", 0x43210000 },
	{ "EXYNOS4212", 0x43220000 },
	{ "EXYNOS4412", 0xE4412000 },
	{ "EXYNOS5250", 0x43520000 },
	{ "EXYNOS5260", 0xE5260000 },
	{ "EXYNOS5410", 0xE5410000 },
	{ "EXYNOS5420", 0xE5420000 },
	{ "EXYNOS5440", 0xE5440000 },
	{ "EXYNOS5800", 0xE5422000 },
	{ "EXYNOS7420", 0xE7420000 },
	{ "EXYNOS5433", 0xE5433000 },
};

static const char * __init product_id_to_soc_id(unsigned int product_id)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(soc_ids); i++)
		if ((product_id & EXYNOS_MASK) == soc_ids[i].id)
			return soc_ids[i].name;
	return NULL;
}

int __init exynos_chipid_early_init(void)
{
	struct soc_device_attribute *soc_dev_attr;
	struct soc_device *soc_dev;
	struct device_node *root;
	struct regmap *regmap;
	u32 product_id;
	u32 revision;
	int ret;

	regmap = syscon_regmap_lookup_by_compatible("samsung,exynos4210-chipid");
	if (IS_ERR(regmap)) {
		pr_err("Failed to get CHIPID regmap\n");
		return PTR_ERR(regmap);
	}

	ret = regmap_read(regmap, EXYNOS_CHIPID_REG_PRO_ID, &product_id);
	if (ret < 0)
		return ret;

	revision = product_id & EXYNOS_REV_MASK;

	soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
	if (!soc_dev_attr)
		return -ENOMEM;

	soc_dev_attr->family = "Samsung Exynos";

	root = of_find_node_by_path("/");
	of_property_read_string(root, "model", &soc_dev_attr->machine);
	of_node_put(root);

	soc_dev_attr->revision = kasprintf(GFP_KERNEL, "%x", revision);
	soc_dev_attr->soc_id = product_id_to_soc_id(product_id);
	if (!soc_dev_attr->soc_id) {
		pr_err("Unknown SoC\n");
		return -ENODEV;
	}

	/* please note that the actual registration will be deferred */
	soc_dev = soc_device_register(soc_dev_attr);
	if (IS_ERR(soc_dev)) {
		kfree(soc_dev_attr->revision);
		kfree(soc_dev_attr);
		return PTR_ERR(soc_dev);
	}

	/* it is too early to use dev_info() here (soc_dev is NULL) */
	pr_info("soc soc0: Exynos: CPU[%s] PRO_ID[0x%x] REV[0x%x] Detected\n",
		soc_dev_attr->soc_id, product_id, revision);

	return 0;
}
early_initcall(exynos_chipid_early_init);
+52 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
 *	      http://www.samsung.com/
 *
 * Exynos - CHIPID support
 */
#ifndef __LINUX_SOC_EXYNOS_CHIPID_H
#define __LINUX_SOC_EXYNOS_CHIPID_H

#define EXYNOS_CHIPID_REG_PRO_ID	0x00
#define EXYNOS_SUBREV_MASK		(0xf << 4)
#define EXYNOS_MAINREV_MASK		(0xf << 0)
#define EXYNOS_REV_MASK			(EXYNOS_SUBREV_MASK | \
					 EXYNOS_MAINREV_MASK)
#define EXYNOS_MASK			0xfffff000

#define EXYNOS_CHIPID_REG_PKG_ID	0x04
/* Bit field definitions for EXYNOS_CHIPID_REG_PKG_ID register */
#define EXYNOS5422_IDS_OFFSET		24
#define EXYNOS5422_IDS_MASK		0xff
#define EXYNOS5422_USESG_OFFSET	3
#define EXYNOS5422_USESG_MASK		0x01
#define EXYNOS5422_SG_OFFSET		0
#define EXYNOS5422_SG_MASK		0x07
#define EXYNOS5422_TABLE_OFFSET	8
#define EXYNOS5422_TABLE_MASK		0x03
#define EXYNOS5422_SG_A_OFFSET		17
#define EXYNOS5422_SG_A_MASK		0x0f
#define EXYNOS5422_SG_B_OFFSET		21
#define EXYNOS5422_SG_B_MASK		0x03
#define EXYNOS5422_SG_BSIGN_OFFSET	23
#define EXYNOS5422_SG_BSIGN_MASK	0x01
#define EXYNOS5422_BIN2_OFFSET		12
#define EXYNOS5422_BIN2_MASK		0x01

#define EXYNOS_CHIPID_REG_LOT_ID	0x14

#define EXYNOS_CHIPID_REG_AUX_INFO	0x1c
/* Bit field definitions for EXYNOS_CHIPID_REG_AUX_INFO register */
#define EXYNOS5422_TMCB_OFFSET		0
#define EXYNOS5422_TMCB_MASK		0x7f
#define EXYNOS5422_ARM_UP_OFFSET	8
#define EXYNOS5422_ARM_UP_MASK		0x03
#define EXYNOS5422_ARM_DN_OFFSET	10
#define EXYNOS5422_ARM_DN_MASK		0x03
#define EXYNOS5422_KFC_UP_OFFSET	12
#define EXYNOS5422_KFC_UP_MASK		0x03
#define EXYNOS5422_KFC_DN_OFFSET	14
#define EXYNOS5422_KFC_DN_MASK		0x03

#endif /*__LINUX_SOC_EXYNOS_CHIPID_H */