Changes in 4.9.207 arm64: tegra: Fix 'active-low' warning for Jetson TX1 regulator usb: gadget: u_serial: add missing port entry locking tty: serial: fsl_lpuart: use the sg count from dma_map_sg tty: serial: msm_serial: Fix flow control serial: pl011: Fix DMA ->flush_buffer() serial: serial_core: Perform NULL checks for break_ctl ops serial: ifx6x60: add missed pm_runtime_disable autofs: fix a leak in autofs_expire_indirect() RDMA/hns: Correct the value of HNS_ROCE_HEM_CHUNK_LEN exportfs_decode_fh(): negative pinned may become positive without the parent locked audit_get_nd(): don't unlock parent too early NFC: nxp-nci: Fix NULL pointer dereference after I2C communication error Input: cyttsp4_core - fix use after free bug ALSA: pcm: Fix stream lock usage in snd_pcm_period_elapsed() rsxx: add missed destroy_workqueue calls in remove net: ep93xx_eth: fix mismatch of request_mem_region in remove serial: core: Allow processing sysrq at port unlock time cxgb4vf: fix memleak in mac_hlist initialization iwlwifi: mvm: Send non offchannel traffic via AP sta ARM: 8813/1: Make aligned 2-byte getuser()/putuser() atomic on ARMv6+ net/mlx5: Release resource on error flow extcon: max8997: Fix lack of path setting in USB device mode clk: rockchip: fix rk3188 sclk_smc gate data clk: rockchip: fix rk3188 sclk_mac_lbtest parameter ordering ARM: dts: rockchip: Fix rk3288-rock2 vcc_flash name dlm: fix missing idr_destroy for recover_idr MIPS: SiByte: Enable ZONE_DMA32 for LittleSur scsi: zfcp: drop default switch case which might paper over missing case pinctrl: qcom: ssbi-gpio: fix gpio-hog related boot issues Staging: iio: adt7316: Fix i2c data reading, set the data field regulator: Fix return value of _set_load() stub MIPS: OCTEON: octeon-platform: fix typing math-emu/soft-fp.h: (_FP_ROUND_ZERO) cast 0 to void to fix warning rtc: max8997: Fix the returned value in case of error in 'max8997_rtc_read_alarm()' rtc: dt-binding: abx80x: fix resistance scale ARM: dts: exynos: Use Samsung SoC specific compatible for DWC2 module media: pulse8-cec: return 0 when invalidating the logical address dmaengine: coh901318: Fix a double-lock bug dmaengine: coh901318: Remove unused variable usb: dwc3: don't log probe deferrals; but do log other error codes ACPI: fix acpi_find_child_device() invocation in acpi_preset_companion() dma-mapping: fix return type of dma_set_max_seg_size() altera-stapl: check for a null key before strcasecmp'ing it serial: imx: fix error handling in console_setup i2c: imx: don't print error message on probe defer dlm: NULL check before kmem_cache_destroy is not needed ARM: debug: enable UART1 for socfpga Cyclone5 nfsd: fix a warning in __cld_pipe_upcall() ARM: OMAP1/2: fix SoC name printing net/x25: fix called/calling length calculation in x25_parse_address_block net/x25: fix null_x25_address handling ARM: dts: mmp2: fix the gpio interrupt cell number ARM: dts: realview-pbx: Fix duplicate regulator nodes tcp: fix off-by-one bug on aborting window-probing socket tcp: fix SNMP TCP timeout under-estimation modpost: skip ELF local symbols during section mismatch check kbuild: fix single target build for external module mtd: fix mtd_oobavail() incoherent returned value ARM: dts: pxa: clean up USB controller nodes clk: sunxi-ng: h3/h5: Fix CSI_MCLK parent ARM: dts: realview: Fix some more duplicate regulator nodes dlm: fix invalid cluster name warning net/mlx4_core: Fix return codes of unsupported operations powerpc/math-emu: Update macros from GCC MIPS: OCTEON: cvmx_pko_mem_debug8: use oldest forward compatible definition nfsd: Return EPERM, not EACCES, in some SETATTR cases tty: Don't block on IO when ldisc change is pending media: stkwebcam: Bugfix for wrong return values mlx4: Use snprintf instead of complicated strcpy ARM: dts: sunxi: Fix PMU compatible strings sched/fair: Scale bandwidth quota and period without losing quota/period ratio precision fuse: verify nlink fuse: verify attributes ALSA: pcm: oss: Avoid potential buffer overflows Input: goodix - add upside-down quirk for Teclast X89 tablet coresight: etm4x: Fix input validation for sysfs. x86/PCI: Avoid AMD FCH XHCI USB PME# from D0 defect CIFS: Fix NULL-pointer dereference in smb2_push_mandatory_locks CIFS: Fix SMB2 oplock break processing tty: vt: keyboard: reject invalid keycodes can: slcan: Fix use-after-free Read in slcan_open jbd2: Fix possible overflow in jbd2_log_space_left() drm/i810: Prevent underflow in ioctl KVM: x86: do not modify masked bits of shared MSRs KVM: x86: fix presentation of TSX feature in ARCH_CAPABILITIES crypto: crypto4xx - fix double-free in crypto4xx_destroy_sdr crypto: ccp - fix uninitialized list head crypto: ecdh - fix big endian bug in ECC library crypto: user - fix memory leak in crypto_report spi: atmel: Fix CS high support RDMA/qib: Validate ->show()/store() callbacks before calling them thermal: Fix deadlock in thermal thermal_zone_device_check KVM: x86: fix out-of-bounds write in KVM_GET_EMULATED_CPUID (CVE-2019-19332) appletalk: Fix potential NULL pointer dereference in unregister_snap_client appletalk: Set error code if register_snap_client failed usb: gadget: configfs: Fix missing spin_lock_init() USB: uas: honor flag to avoid CAPACITY16 USB: uas: heed CAPACITY_HEURISTICS usb: Allow USB device to be warm reset in suspended state staging: rtl8188eu: fix interface sanity check staging: rtl8712: fix interface sanity check staging: gigaset: fix general protection fault on probe staging: gigaset: fix illegal free on probe errors staging: gigaset: add endpoint-type sanity check xhci: Increase STS_HALT timeout in xhci_suspend() ARM: dts: pandora-common: define wl1251 as child node of mmc3 iio: humidity: hdc100x: fix IIO_HUMIDITYRELATIVE channel reporting USB: atm: ueagle-atm: add missing endpoint check USB: idmouse: fix interface sanity checks USB: serial: io_edgeport: fix epic endpoint lookup USB: adutux: fix interface sanity check usb: core: urb: fix URB structure initialization function usb: mon: Fix a deadlock in usbmon between mmap and read mtd: spear_smi: Fix Write Burst mode virtio-balloon: fix managed page counts when migrating pages between zones btrfs: check page->mapping when loading free space cache btrfs: Remove btrfs_bio::flags member Btrfs: send, skip backreference walking for extents with many references btrfs: record all roots for rename exchange on a subvol rtlwifi: rtl8192de: Fix missing code to retrieve RX buffer address rtlwifi: rtl8192de: Fix missing callback that tests for hw release of buffer rtlwifi: rtl8192de: Fix missing enable interrupt flag lib: raid6: fix awk build warnings ALSA: hda - Fix pending unsol events at shutdown workqueue: Fix spurious sanity check failures in destroy_workqueue() workqueue: Fix pwq ref leak in rescuer_thread() ASoC: Jack: Fix NULL pointer dereference in snd_soc_jack_report blk-mq: avoid sysfs buffer overflow with too many CPU cores cgroup: pids: use atomic64_t for pids->limit ar5523: check NULL before memcpy() in ar5523_cmd() media: bdisp: fix memleak on release media: radio: wl1273: fix interrupt masking on release cpuidle: Do not unset the driver if it is there already PM / devfreq: Lock devfreq in trans_stat_show ACPI: OSL: only free map once in osl.c ACPI: bus: Fix NULL pointer check in acpi_bus_get_private_data() ACPI: PM: Avoid attaching ACPI PM domain to certain devices pinctrl: samsung: Fix device node refcount leaks in S3C24xx wakeup controller init pinctrl: samsung: Fix device node refcount leaks in init code mmc: host: omap_hsmmc: add code for special init of wl1251 to get rid of pandora_wl1251_init_card ppdev: fix PPGETTIME/PPSETTIME ioctls powerpc: Allow 64bit VDSO __kernel_sync_dicache to work across ranges >4GB video/hdmi: Fix AVI bar unpack quota: Check that quota is not dirty before release ext2: check err when partial != NULL quota: fix livelock in dquot_writeback_dquots scsi: zfcp: trace channel log even for FCP command responses usb: xhci: only set D3hot for pci device xhci: Fix memory leak in xhci_add_in_port() xhci: make sure interrupts are restored to correct state iio: adis16480: Add debugfs_reg_access entry Btrfs: fix negative subv_writers counter and data space leak after buffered write omap: pdata-quirks: remove openpandora quirks for mmc3 and wl1251 scsi: lpfc: Cap NPIV vports to 256 e100: Fix passing zero to 'PTR_ERR' warning in e100_load_ucode_wait x86/MCE/AMD: Turn off MC4_MISC thresholding on all family 0x15 models x86/MCE/AMD: Carve out the MC4_MISC thresholding quirk ath10k: fix fw crash by moving chip reset after napi disabled ARM: dts: omap3-tao3530: Fix incorrect MMC card detection GPIO polarity pinctrl: samsung: Fix device node refcount leaks in S3C64xx wakeup controller init scsi: qla2xxx: Fix DMA unmap leak scsi: qla2xxx: Fix session lookup in qlt_abort_work() scsi: qla2xxx: Fix qla24xx_process_bidir_cmd() scsi: qla2xxx: Always check the qla2x00_wait_for_hba_online() return value powerpc: Fix vDSO clock_getres() reiserfs: fix extended attributes on the root directory firmware: qcom: scm: Ensure 'a0' status code is treated as signed mm/shmem.c: cast the type of unmap_start to u64 ext4: fix a bug in ext4_wait_for_tail_page_commit blk-mq: make sure that line break can be printed workqueue: Fix missing kfree(rescuer) in destroy_workqueue() sunrpc: fix crash when cache_head become valid before update net/mlx5e: Fix SFF 8472 eeprom length kernel/module.c: wakeup processes in module_wq on module unload nvme: host: core: fix precedence of ternary operator net: bridge: deny dev_set_mac_address() when unregistering net: ethernet: ti: cpsw: fix extra rx interrupt openvswitch: support asymmetric conntrack tcp: md5: fix potential overestimation of TCP option space tipc: fix ordering of tipc module init and exit routine inet: protect against too small mtu values. tcp: fix rejected syncookies due to stale timestamps tcp: tighten acceptance of ACKs not matching a child socket tcp: Protect accesses to .ts_recent_stamp with {READ,WRITE}_ONCE() Revert "regulator: Defer init completion for a while after late_initcall" PCI: Fix Intel ACS quirk UPDCR register address PCI/MSI: Fix incorrect MSI-X masking on resume xtensa: fix TLB sanity checker CIFS: Respect O_SYNC and O_DIRECT flags during reconnect ARM: dts: s3c64xx: Fix init order of clock providers ARM: tegra: Fix FLOW_CTLR_HALT register clobbering by tegra_resume() vfio/pci: call irq_bypass_unregister_producer() before freeing irq dma-buf: Fix memory leak in sync_file_merge() dm btree: increase rebalance threshold in __rebalance2() scsi: iscsi: Fix a potential deadlock in the timeout handler drm/radeon: fix r1xx/r2xx register checker for POT textures xhci: fix USB3 device initiated resume race with roothub autosuspend net: stmmac: use correct DMA buffer size in the RX descriptor net: stmmac: don't stop NAPI processing when dropping a packet Linux 4.9.207 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
782 lines
18 KiB
C
782 lines
18 KiB
C
/*
|
|
* linux/arch/arm/mach-omap2/id.c
|
|
*
|
|
* OMAP2 CPU identification code
|
|
*
|
|
* Copyright (C) 2005 Nokia Corporation
|
|
* Written by Tony Lindgren <tony@atomide.com>
|
|
*
|
|
* Copyright (C) 2009-11 Texas Instruments
|
|
* Added OMAP4 support - Santosh Shilimkar <santosh.shilimkar@ti.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*/
|
|
|
|
#include <linux/module.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/init.h>
|
|
#include <linux/io.h>
|
|
#include <linux/random.h>
|
|
#include <linux/slab.h>
|
|
|
|
#ifdef CONFIG_SOC_BUS
|
|
#include <linux/sys_soc.h>
|
|
#endif
|
|
|
|
#include <asm/cputype.h>
|
|
|
|
#include "common.h"
|
|
|
|
#include "id.h"
|
|
|
|
#include "soc.h"
|
|
#include "control.h"
|
|
|
|
#define OMAP4_SILICON_TYPE_STANDARD 0x01
|
|
#define OMAP4_SILICON_TYPE_PERFORMANCE 0x02
|
|
|
|
#define OMAP_SOC_MAX_NAME_LENGTH 16
|
|
|
|
static unsigned int omap_revision;
|
|
static char soc_name[OMAP_SOC_MAX_NAME_LENGTH];
|
|
static char soc_rev[OMAP_SOC_MAX_NAME_LENGTH];
|
|
u32 omap_features;
|
|
|
|
unsigned int omap_rev(void)
|
|
{
|
|
return omap_revision;
|
|
}
|
|
EXPORT_SYMBOL(omap_rev);
|
|
|
|
int omap_type(void)
|
|
{
|
|
static u32 val = OMAP2_DEVICETYPE_MASK;
|
|
|
|
if (val < OMAP2_DEVICETYPE_MASK)
|
|
return val;
|
|
|
|
if (soc_is_omap24xx()) {
|
|
val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS);
|
|
} else if (soc_is_ti81xx()) {
|
|
val = omap_ctrl_readl(TI81XX_CONTROL_STATUS);
|
|
} else if (soc_is_am33xx() || soc_is_am43xx()) {
|
|
val = omap_ctrl_readl(AM33XX_CONTROL_STATUS);
|
|
} else if (soc_is_omap34xx()) {
|
|
val = omap_ctrl_readl(OMAP343X_CONTROL_STATUS);
|
|
} else if (soc_is_omap44xx()) {
|
|
val = omap_ctrl_readl(OMAP4_CTRL_MODULE_CORE_STATUS);
|
|
} else if (soc_is_omap54xx() || soc_is_dra7xx()) {
|
|
val = omap_ctrl_readl(OMAP5XXX_CONTROL_STATUS);
|
|
val &= OMAP5_DEVICETYPE_MASK;
|
|
val >>= 6;
|
|
goto out;
|
|
} else {
|
|
pr_err("Cannot detect omap type!\n");
|
|
goto out;
|
|
}
|
|
|
|
val &= OMAP2_DEVICETYPE_MASK;
|
|
val >>= 8;
|
|
|
|
out:
|
|
return val;
|
|
}
|
|
EXPORT_SYMBOL(omap_type);
|
|
|
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
#define OMAP_TAP_IDCODE 0x0204
|
|
#define OMAP_TAP_DIE_ID_0 0x0218
|
|
#define OMAP_TAP_DIE_ID_1 0x021C
|
|
#define OMAP_TAP_DIE_ID_2 0x0220
|
|
#define OMAP_TAP_DIE_ID_3 0x0224
|
|
|
|
#define OMAP_TAP_DIE_ID_44XX_0 0x0200
|
|
#define OMAP_TAP_DIE_ID_44XX_1 0x0208
|
|
#define OMAP_TAP_DIE_ID_44XX_2 0x020c
|
|
#define OMAP_TAP_DIE_ID_44XX_3 0x0210
|
|
|
|
#define read_tap_reg(reg) readl_relaxed(tap_base + (reg))
|
|
|
|
struct omap_id {
|
|
u16 hawkeye; /* Silicon type (Hawkeye id) */
|
|
u8 dev; /* Device type from production_id reg */
|
|
u32 type; /* Combined type id copied to omap_revision */
|
|
};
|
|
|
|
/* Register values to detect the OMAP version */
|
|
static struct omap_id omap_ids[] __initdata = {
|
|
{ .hawkeye = 0xb5d9, .dev = 0x0, .type = 0x24200024 },
|
|
{ .hawkeye = 0xb5d9, .dev = 0x1, .type = 0x24201024 },
|
|
{ .hawkeye = 0xb5d9, .dev = 0x2, .type = 0x24202024 },
|
|
{ .hawkeye = 0xb5d9, .dev = 0x4, .type = 0x24220024 },
|
|
{ .hawkeye = 0xb5d9, .dev = 0x8, .type = 0x24230024 },
|
|
{ .hawkeye = 0xb68a, .dev = 0x0, .type = 0x24300024 },
|
|
};
|
|
|
|
static void __iomem *tap_base;
|
|
static u16 tap_prod_id;
|
|
|
|
void omap_get_die_id(struct omap_die_id *odi)
|
|
{
|
|
if (soc_is_omap44xx() || soc_is_omap54xx() || soc_is_dra7xx()) {
|
|
odi->id_0 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_0);
|
|
odi->id_1 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_1);
|
|
odi->id_2 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_2);
|
|
odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_44XX_3);
|
|
|
|
return;
|
|
}
|
|
odi->id_0 = read_tap_reg(OMAP_TAP_DIE_ID_0);
|
|
odi->id_1 = read_tap_reg(OMAP_TAP_DIE_ID_1);
|
|
odi->id_2 = read_tap_reg(OMAP_TAP_DIE_ID_2);
|
|
odi->id_3 = read_tap_reg(OMAP_TAP_DIE_ID_3);
|
|
}
|
|
|
|
static int __init omap_feed_randpool(void)
|
|
{
|
|
struct omap_die_id odi;
|
|
|
|
/* Throw the die ID into the entropy pool at boot */
|
|
omap_get_die_id(&odi);
|
|
add_device_randomness(&odi, sizeof(odi));
|
|
return 0;
|
|
}
|
|
omap_device_initcall(omap_feed_randpool);
|
|
|
|
void __init omap2xxx_check_revision(void)
|
|
{
|
|
int i, j;
|
|
u32 idcode, prod_id;
|
|
u16 hawkeye;
|
|
u8 dev_type, rev;
|
|
struct omap_die_id odi;
|
|
|
|
idcode = read_tap_reg(OMAP_TAP_IDCODE);
|
|
prod_id = read_tap_reg(tap_prod_id);
|
|
hawkeye = (idcode >> 12) & 0xffff;
|
|
rev = (idcode >> 28) & 0x0f;
|
|
dev_type = (prod_id >> 16) & 0x0f;
|
|
omap_get_die_id(&odi);
|
|
|
|
pr_debug("OMAP_TAP_IDCODE 0x%08x REV %i HAWKEYE 0x%04x MANF %03x\n",
|
|
idcode, rev, hawkeye, (idcode >> 1) & 0x7ff);
|
|
pr_debug("OMAP_TAP_DIE_ID_0: 0x%08x\n", odi.id_0);
|
|
pr_debug("OMAP_TAP_DIE_ID_1: 0x%08x DEV_REV: %i\n",
|
|
odi.id_1, (odi.id_1 >> 28) & 0xf);
|
|
pr_debug("OMAP_TAP_DIE_ID_2: 0x%08x\n", odi.id_2);
|
|
pr_debug("OMAP_TAP_DIE_ID_3: 0x%08x\n", odi.id_3);
|
|
pr_debug("OMAP_TAP_PROD_ID_0: 0x%08x DEV_TYPE: %i\n",
|
|
prod_id, dev_type);
|
|
|
|
/* Check hawkeye ids */
|
|
for (i = 0; i < ARRAY_SIZE(omap_ids); i++) {
|
|
if (hawkeye == omap_ids[i].hawkeye)
|
|
break;
|
|
}
|
|
|
|
if (i == ARRAY_SIZE(omap_ids)) {
|
|
printk(KERN_ERR "Unknown OMAP CPU id\n");
|
|
return;
|
|
}
|
|
|
|
for (j = i; j < ARRAY_SIZE(omap_ids); j++) {
|
|
if (dev_type == omap_ids[j].dev)
|
|
break;
|
|
}
|
|
|
|
if (j == ARRAY_SIZE(omap_ids)) {
|
|
pr_err("Unknown OMAP device type. Handling it as OMAP%04x\n",
|
|
omap_ids[i].type >> 16);
|
|
j = i;
|
|
}
|
|
|
|
sprintf(soc_name, "OMAP%04x", omap_rev() >> 16);
|
|
sprintf(soc_rev, "ES%x", (omap_rev() >> 12) & 0xf);
|
|
|
|
pr_info("%s", soc_name);
|
|
if ((omap_rev() >> 8) & 0x0f)
|
|
pr_cont("%s", soc_rev);
|
|
pr_cont("\n");
|
|
}
|
|
|
|
#define OMAP3_SHOW_FEATURE(feat) \
|
|
if (omap3_has_ ##feat()) \
|
|
n += scnprintf(buf + n, sizeof(buf) - n, #feat " ");
|
|
|
|
static void __init omap3_cpuinfo(void)
|
|
{
|
|
const char *cpu_name;
|
|
char buf[64];
|
|
int n = 0;
|
|
|
|
memset(buf, 0, sizeof(buf));
|
|
|
|
/*
|
|
* OMAP3430 and OMAP3530 are assumed to be same.
|
|
*
|
|
* OMAP3525, OMAP3515 and OMAP3503 can be detected only based
|
|
* on available features. Upon detection, update the CPU id
|
|
* and CPU class bits.
|
|
*/
|
|
if (soc_is_omap3630()) {
|
|
cpu_name = "OMAP3630";
|
|
} else if (soc_is_am35xx()) {
|
|
cpu_name = (omap3_has_sgx()) ? "AM3517" : "AM3505";
|
|
} else if (soc_is_ti816x()) {
|
|
cpu_name = "TI816X";
|
|
} else if (soc_is_am335x()) {
|
|
cpu_name = "AM335X";
|
|
} else if (soc_is_am437x()) {
|
|
cpu_name = "AM437x";
|
|
} else if (soc_is_ti814x()) {
|
|
cpu_name = "TI814X";
|
|
} else if (omap3_has_iva() && omap3_has_sgx()) {
|
|
/* OMAP3430, OMAP3525, OMAP3515, OMAP3503 devices */
|
|
cpu_name = "OMAP3430/3530";
|
|
} else if (omap3_has_iva()) {
|
|
cpu_name = "OMAP3525";
|
|
} else if (omap3_has_sgx()) {
|
|
cpu_name = "OMAP3515";
|
|
} else {
|
|
cpu_name = "OMAP3503";
|
|
}
|
|
|
|
scnprintf(soc_name, sizeof(soc_name), "%s", cpu_name);
|
|
|
|
/* Print verbose information */
|
|
n += scnprintf(buf, sizeof(buf) - n, "%s %s (", soc_name, soc_rev);
|
|
|
|
OMAP3_SHOW_FEATURE(l2cache);
|
|
OMAP3_SHOW_FEATURE(iva);
|
|
OMAP3_SHOW_FEATURE(sgx);
|
|
OMAP3_SHOW_FEATURE(neon);
|
|
OMAP3_SHOW_FEATURE(isp);
|
|
OMAP3_SHOW_FEATURE(192mhz_clk);
|
|
if (*(buf + n - 1) == ' ')
|
|
n--;
|
|
n += scnprintf(buf + n, sizeof(buf) - n, ")\n");
|
|
pr_info("%s", buf);
|
|
}
|
|
|
|
#define OMAP3_CHECK_FEATURE(status,feat) \
|
|
if (((status & OMAP3_ ##feat## _MASK) \
|
|
>> OMAP3_ ##feat## _SHIFT) != FEAT_ ##feat## _NONE) { \
|
|
omap_features |= OMAP3_HAS_ ##feat; \
|
|
}
|
|
|
|
void __init omap3xxx_check_features(void)
|
|
{
|
|
u32 status;
|
|
|
|
omap_features = 0;
|
|
|
|
status = omap_ctrl_readl(OMAP3_CONTROL_OMAP_STATUS);
|
|
|
|
OMAP3_CHECK_FEATURE(status, L2CACHE);
|
|
OMAP3_CHECK_FEATURE(status, IVA);
|
|
OMAP3_CHECK_FEATURE(status, SGX);
|
|
OMAP3_CHECK_FEATURE(status, NEON);
|
|
OMAP3_CHECK_FEATURE(status, ISP);
|
|
if (soc_is_omap3630())
|
|
omap_features |= OMAP3_HAS_192MHZ_CLK;
|
|
if (soc_is_omap3430() || soc_is_omap3630())
|
|
omap_features |= OMAP3_HAS_IO_WAKEUP;
|
|
if (soc_is_omap3630() || omap_rev() == OMAP3430_REV_ES3_1 ||
|
|
omap_rev() == OMAP3430_REV_ES3_1_2)
|
|
omap_features |= OMAP3_HAS_IO_CHAIN_CTRL;
|
|
|
|
omap_features |= OMAP3_HAS_SDRC;
|
|
|
|
/*
|
|
* am35x fixups:
|
|
* - The am35x Chip ID register has bits 12, 7:5, and 3:2 marked as
|
|
* reserved and therefore return 0 when read. Unfortunately,
|
|
* OMAP3_CHECK_FEATURE() will interpret some of those zeroes to
|
|
* mean that a feature is present even though it isn't so clear
|
|
* the incorrectly set feature bits.
|
|
*/
|
|
if (soc_is_am35xx())
|
|
omap_features &= ~(OMAP3_HAS_IVA | OMAP3_HAS_ISP);
|
|
|
|
/*
|
|
* TODO: Get additional info (where applicable)
|
|
* e.g. Size of L2 cache.
|
|
*/
|
|
|
|
omap3_cpuinfo();
|
|
}
|
|
|
|
void __init omap4xxx_check_features(void)
|
|
{
|
|
u32 si_type;
|
|
|
|
si_type =
|
|
(read_tap_reg(OMAP4_CTRL_MODULE_CORE_STD_FUSE_PROD_ID_1) >> 16) & 0x03;
|
|
|
|
if (si_type == OMAP4_SILICON_TYPE_PERFORMANCE)
|
|
omap_features = OMAP4_HAS_PERF_SILICON;
|
|
}
|
|
|
|
void __init ti81xx_check_features(void)
|
|
{
|
|
omap_features = OMAP3_HAS_NEON;
|
|
omap3_cpuinfo();
|
|
}
|
|
|
|
void __init am33xx_check_features(void)
|
|
{
|
|
u32 status;
|
|
|
|
omap_features = OMAP3_HAS_NEON;
|
|
|
|
status = omap_ctrl_readl(AM33XX_DEV_FEATURE);
|
|
if (status & AM33XX_SGX_MASK)
|
|
omap_features |= OMAP3_HAS_SGX;
|
|
|
|
omap3_cpuinfo();
|
|
}
|
|
|
|
void __init omap3xxx_check_revision(void)
|
|
{
|
|
const char *cpu_rev;
|
|
u32 cpuid, idcode;
|
|
u16 hawkeye;
|
|
u8 rev;
|
|
|
|
/*
|
|
* We cannot access revision registers on ES1.0.
|
|
* If the processor type is Cortex-A8 and the revision is 0x0
|
|
* it means its Cortex r0p0 which is 3430 ES1.0.
|
|
*/
|
|
cpuid = read_cpuid_id();
|
|
if ((((cpuid >> 4) & 0xfff) == 0xc08) && ((cpuid & 0xf) == 0x0)) {
|
|
omap_revision = OMAP3430_REV_ES1_0;
|
|
cpu_rev = "1.0";
|
|
return;
|
|
}
|
|
|
|
/*
|
|
* Detection for 34xx ES2.0 and above can be done with just
|
|
* hawkeye and rev. See TRM 1.5.2 Device Identification.
|
|
* Note that rev does not map directly to our defined processor
|
|
* revision numbers as ES1.0 uses value 0.
|
|
*/
|
|
idcode = read_tap_reg(OMAP_TAP_IDCODE);
|
|
hawkeye = (idcode >> 12) & 0xffff;
|
|
rev = (idcode >> 28) & 0xff;
|
|
|
|
switch (hawkeye) {
|
|
case 0xb7ae:
|
|
/* Handle 34xx/35xx devices */
|
|
switch (rev) {
|
|
case 0: /* Take care of early samples */
|
|
case 1:
|
|
omap_revision = OMAP3430_REV_ES2_0;
|
|
cpu_rev = "2.0";
|
|
break;
|
|
case 2:
|
|
omap_revision = OMAP3430_REV_ES2_1;
|
|
cpu_rev = "2.1";
|
|
break;
|
|
case 3:
|
|
omap_revision = OMAP3430_REV_ES3_0;
|
|
cpu_rev = "3.0";
|
|
break;
|
|
case 4:
|
|
omap_revision = OMAP3430_REV_ES3_1;
|
|
cpu_rev = "3.1";
|
|
break;
|
|
case 7:
|
|
/* FALLTHROUGH */
|
|
default:
|
|
/* Use the latest known revision as default */
|
|
omap_revision = OMAP3430_REV_ES3_1_2;
|
|
cpu_rev = "3.1.2";
|
|
}
|
|
break;
|
|
case 0xb868:
|
|
/*
|
|
* Handle OMAP/AM 3505/3517 devices
|
|
*
|
|
* Set the device to be OMAP3517 here. Actual device
|
|
* is identified later based on the features.
|
|
*/
|
|
switch (rev) {
|
|
case 0:
|
|
omap_revision = AM35XX_REV_ES1_0;
|
|
cpu_rev = "1.0";
|
|
break;
|
|
case 1:
|
|
/* FALLTHROUGH */
|
|
default:
|
|
omap_revision = AM35XX_REV_ES1_1;
|
|
cpu_rev = "1.1";
|
|
}
|
|
break;
|
|
case 0xb891:
|
|
/* Handle 36xx devices */
|
|
|
|
switch(rev) {
|
|
case 0: /* Take care of early samples */
|
|
omap_revision = OMAP3630_REV_ES1_0;
|
|
cpu_rev = "1.0";
|
|
break;
|
|
case 1:
|
|
omap_revision = OMAP3630_REV_ES1_1;
|
|
cpu_rev = "1.1";
|
|
break;
|
|
case 2:
|
|
/* FALLTHROUGH */
|
|
default:
|
|
omap_revision = OMAP3630_REV_ES1_2;
|
|
cpu_rev = "1.2";
|
|
}
|
|
break;
|
|
case 0xb81e:
|
|
switch (rev) {
|
|
case 0:
|
|
omap_revision = TI8168_REV_ES1_0;
|
|
cpu_rev = "1.0";
|
|
break;
|
|
case 1:
|
|
omap_revision = TI8168_REV_ES1_1;
|
|
cpu_rev = "1.1";
|
|
break;
|
|
case 2:
|
|
omap_revision = TI8168_REV_ES2_0;
|
|
cpu_rev = "2.0";
|
|
break;
|
|
case 3:
|
|
/* FALLTHROUGH */
|
|
default:
|
|
omap_revision = TI8168_REV_ES2_1;
|
|
cpu_rev = "2.1";
|
|
}
|
|
break;
|
|
case 0xb944:
|
|
switch (rev) {
|
|
case 0:
|
|
omap_revision = AM335X_REV_ES1_0;
|
|
cpu_rev = "1.0";
|
|
break;
|
|
case 1:
|
|
omap_revision = AM335X_REV_ES2_0;
|
|
cpu_rev = "2.0";
|
|
break;
|
|
case 2:
|
|
/* FALLTHROUGH */
|
|
default:
|
|
omap_revision = AM335X_REV_ES2_1;
|
|
cpu_rev = "2.1";
|
|
break;
|
|
}
|
|
break;
|
|
case 0xb98c:
|
|
switch (rev) {
|
|
case 0:
|
|
omap_revision = AM437X_REV_ES1_0;
|
|
cpu_rev = "1.0";
|
|
break;
|
|
case 1:
|
|
omap_revision = AM437X_REV_ES1_1;
|
|
cpu_rev = "1.1";
|
|
break;
|
|
case 2:
|
|
/* FALLTHROUGH */
|
|
default:
|
|
omap_revision = AM437X_REV_ES1_2;
|
|
cpu_rev = "1.2";
|
|
break;
|
|
}
|
|
break;
|
|
case 0xb8f2:
|
|
case 0xb968:
|
|
switch (rev) {
|
|
case 0:
|
|
/* FALLTHROUGH */
|
|
case 1:
|
|
omap_revision = TI8148_REV_ES1_0;
|
|
cpu_rev = "1.0";
|
|
break;
|
|
case 2:
|
|
omap_revision = TI8148_REV_ES2_0;
|
|
cpu_rev = "2.0";
|
|
break;
|
|
case 3:
|
|
/* FALLTHROUGH */
|
|
default:
|
|
omap_revision = TI8148_REV_ES2_1;
|
|
cpu_rev = "2.1";
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
/* Unknown default to latest silicon rev as default */
|
|
omap_revision = OMAP3630_REV_ES1_2;
|
|
cpu_rev = "1.2";
|
|
pr_warn("Warning: unknown chip type: hawkeye %04x, assuming OMAP3630ES1.2\n",
|
|
hawkeye);
|
|
}
|
|
sprintf(soc_rev, "ES%s", cpu_rev);
|
|
}
|
|
|
|
void __init omap4xxx_check_revision(void)
|
|
{
|
|
u32 idcode;
|
|
u16 hawkeye;
|
|
u8 rev;
|
|
|
|
/*
|
|
* The IC rev detection is done with hawkeye and rev.
|
|
* Note that rev does not map directly to defined processor
|
|
* revision numbers as ES1.0 uses value 0.
|
|
*/
|
|
idcode = read_tap_reg(OMAP_TAP_IDCODE);
|
|
hawkeye = (idcode >> 12) & 0xffff;
|
|
rev = (idcode >> 28) & 0xf;
|
|
|
|
/*
|
|
* Few initial 4430 ES2.0 samples IDCODE is same as ES1.0
|
|
* Use ARM register to detect the correct ES version
|
|
*/
|
|
if (!rev && (hawkeye != 0xb94e) && (hawkeye != 0xb975)) {
|
|
idcode = read_cpuid_id();
|
|
rev = (idcode & 0xf) - 1;
|
|
}
|
|
|
|
switch (hawkeye) {
|
|
case 0xb852:
|
|
switch (rev) {
|
|
case 0:
|
|
omap_revision = OMAP4430_REV_ES1_0;
|
|
break;
|
|
case 1:
|
|
default:
|
|
omap_revision = OMAP4430_REV_ES2_0;
|
|
}
|
|
break;
|
|
case 0xb95c:
|
|
switch (rev) {
|
|
case 3:
|
|
omap_revision = OMAP4430_REV_ES2_1;
|
|
break;
|
|
case 4:
|
|
omap_revision = OMAP4430_REV_ES2_2;
|
|
break;
|
|
case 6:
|
|
default:
|
|
omap_revision = OMAP4430_REV_ES2_3;
|
|
}
|
|
break;
|
|
case 0xb94e:
|
|
switch (rev) {
|
|
case 0:
|
|
omap_revision = OMAP4460_REV_ES1_0;
|
|
break;
|
|
case 2:
|
|
default:
|
|
omap_revision = OMAP4460_REV_ES1_1;
|
|
break;
|
|
}
|
|
break;
|
|
case 0xb975:
|
|
switch (rev) {
|
|
case 0:
|
|
default:
|
|
omap_revision = OMAP4470_REV_ES1_0;
|
|
break;
|
|
}
|
|
break;
|
|
default:
|
|
/* Unknown default to latest silicon rev as default */
|
|
omap_revision = OMAP4430_REV_ES2_3;
|
|
}
|
|
|
|
sprintf(soc_name, "OMAP%04x", omap_rev() >> 16);
|
|
sprintf(soc_rev, "ES%d.%d", (omap_rev() >> 12) & 0xf,
|
|
(omap_rev() >> 8) & 0xf);
|
|
pr_info("%s %s\n", soc_name, soc_rev);
|
|
}
|
|
|
|
void __init omap5xxx_check_revision(void)
|
|
{
|
|
u32 idcode;
|
|
u16 hawkeye;
|
|
u8 rev;
|
|
|
|
idcode = read_tap_reg(OMAP_TAP_IDCODE);
|
|
hawkeye = (idcode >> 12) & 0xffff;
|
|
rev = (idcode >> 28) & 0xff;
|
|
switch (hawkeye) {
|
|
case 0xb942:
|
|
switch (rev) {
|
|
case 0:
|
|
/* No support for ES1.0 Test chip */
|
|
BUG();
|
|
case 1:
|
|
default:
|
|
omap_revision = OMAP5430_REV_ES2_0;
|
|
}
|
|
break;
|
|
|
|
case 0xb998:
|
|
switch (rev) {
|
|
case 0:
|
|
/* No support for ES1.0 Test chip */
|
|
BUG();
|
|
case 1:
|
|
default:
|
|
omap_revision = OMAP5432_REV_ES2_0;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
/* Unknown default to latest silicon rev as default*/
|
|
omap_revision = OMAP5430_REV_ES2_0;
|
|
}
|
|
|
|
sprintf(soc_name, "OMAP%04x", omap_rev() >> 16);
|
|
sprintf(soc_rev, "ES%d.0", (omap_rev() >> 12) & 0xf);
|
|
|
|
pr_info("%s %s\n", soc_name, soc_rev);
|
|
}
|
|
|
|
void __init dra7xxx_check_revision(void)
|
|
{
|
|
u32 idcode;
|
|
u16 hawkeye;
|
|
u8 rev;
|
|
|
|
idcode = read_tap_reg(OMAP_TAP_IDCODE);
|
|
hawkeye = (idcode >> 12) & 0xffff;
|
|
rev = (idcode >> 28) & 0xff;
|
|
switch (hawkeye) {
|
|
case 0xb990:
|
|
switch (rev) {
|
|
case 0:
|
|
omap_revision = DRA752_REV_ES1_0;
|
|
break;
|
|
case 1:
|
|
omap_revision = DRA752_REV_ES1_1;
|
|
break;
|
|
case 2:
|
|
default:
|
|
omap_revision = DRA752_REV_ES2_0;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case 0xb9bc:
|
|
switch (rev) {
|
|
case 0:
|
|
omap_revision = DRA722_REV_ES1_0;
|
|
break;
|
|
case 1:
|
|
default:
|
|
omap_revision = DRA722_REV_ES2_0;
|
|
break;
|
|
}
|
|
break;
|
|
|
|
default:
|
|
/* Unknown default to latest silicon rev as default*/
|
|
pr_warn("%s: unknown idcode=0x%08x (hawkeye=0x%08x,rev=0x%x)\n",
|
|
__func__, idcode, hawkeye, rev);
|
|
omap_revision = DRA752_REV_ES2_0;
|
|
}
|
|
|
|
sprintf(soc_name, "DRA%03x", omap_rev() >> 16);
|
|
sprintf(soc_rev, "ES%d.%d", (omap_rev() >> 12) & 0xf,
|
|
(omap_rev() >> 8) & 0xf);
|
|
|
|
pr_info("%s %s\n", soc_name, soc_rev);
|
|
}
|
|
|
|
/*
|
|
* Set up things for map_io and processor detection later on. Gets called
|
|
* pretty much first thing from board init. For multi-omap, this gets
|
|
* cpu_is_omapxxxx() working accurately enough for map_io. Then we'll try to
|
|
* detect the exact revision later on in omap2_detect_revision() once map_io
|
|
* is done.
|
|
*/
|
|
void __init omap2_set_globals_tap(u32 class, void __iomem *tap)
|
|
{
|
|
omap_revision = class;
|
|
tap_base = tap;
|
|
|
|
/* XXX What is this intended to do? */
|
|
if (soc_is_omap34xx())
|
|
tap_prod_id = 0x0210;
|
|
else
|
|
tap_prod_id = 0x0208;
|
|
}
|
|
|
|
#ifdef CONFIG_SOC_BUS
|
|
|
|
static const char * const omap_types[] = {
|
|
[OMAP2_DEVICE_TYPE_TEST] = "TST",
|
|
[OMAP2_DEVICE_TYPE_EMU] = "EMU",
|
|
[OMAP2_DEVICE_TYPE_SEC] = "HS",
|
|
[OMAP2_DEVICE_TYPE_GP] = "GP",
|
|
[OMAP2_DEVICE_TYPE_BAD] = "BAD",
|
|
};
|
|
|
|
static const char * __init omap_get_family(void)
|
|
{
|
|
if (soc_is_omap24xx())
|
|
return kasprintf(GFP_KERNEL, "OMAP2");
|
|
else if (soc_is_omap34xx())
|
|
return kasprintf(GFP_KERNEL, "OMAP3");
|
|
else if (soc_is_omap44xx())
|
|
return kasprintf(GFP_KERNEL, "OMAP4");
|
|
else if (soc_is_omap54xx())
|
|
return kasprintf(GFP_KERNEL, "OMAP5");
|
|
else if (soc_is_am33xx() || soc_is_am335x())
|
|
return kasprintf(GFP_KERNEL, "AM33xx");
|
|
else if (soc_is_am43xx())
|
|
return kasprintf(GFP_KERNEL, "AM43xx");
|
|
else if (soc_is_dra7xx())
|
|
return kasprintf(GFP_KERNEL, "DRA7");
|
|
else
|
|
return kasprintf(GFP_KERNEL, "Unknown");
|
|
}
|
|
|
|
static ssize_t omap_get_type(struct device *dev,
|
|
struct device_attribute *attr,
|
|
char *buf)
|
|
{
|
|
return sprintf(buf, "%s\n", omap_types[omap_type()]);
|
|
}
|
|
|
|
static struct device_attribute omap_soc_attr =
|
|
__ATTR(type, S_IRUGO, omap_get_type, NULL);
|
|
|
|
void __init omap_soc_device_init(void)
|
|
{
|
|
struct device *parent;
|
|
struct soc_device *soc_dev;
|
|
struct soc_device_attribute *soc_dev_attr;
|
|
|
|
soc_dev_attr = kzalloc(sizeof(*soc_dev_attr), GFP_KERNEL);
|
|
if (!soc_dev_attr)
|
|
return;
|
|
|
|
soc_dev_attr->machine = soc_name;
|
|
soc_dev_attr->family = omap_get_family();
|
|
soc_dev_attr->revision = soc_rev;
|
|
|
|
soc_dev = soc_device_register(soc_dev_attr);
|
|
if (IS_ERR(soc_dev)) {
|
|
kfree(soc_dev_attr);
|
|
return;
|
|
}
|
|
|
|
parent = soc_device_to_device(soc_dev);
|
|
device_create_file(parent, &omap_soc_attr);
|
|
}
|
|
#endif /* CONFIG_SOC_BUS */
|