diff options
author | 2023-02-21 18:24:12 -0800 | |
---|---|---|
committer | 2023-02-21 18:24:12 -0800 | |
commit | 5b7c4cabbb65f5c469464da6c5f614cbd7f730f2 (patch) | |
tree | cc5c2d0a898769fd59549594fedb3ee6f84e59a0 /arch/arm/mach-omap2/id.c | |
download | linux-5b7c4cabbb65f5c469464da6c5f614cbd7f730f2.tar.gz linux-5b7c4cabbb65f5c469464da6c5f614cbd7f730f2.zip |
Merge tag 'net-next-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-nextgrafted
Pull networking updates from Jakub Kicinski:
"Core:
- Add dedicated kmem_cache for typical/small skb->head, avoid having
to access struct page at kfree time, and improve memory use.
- Introduce sysctl to set default RPS configuration for new netdevs.
- Define Netlink protocol specification format which can be used to
describe messages used by each family and auto-generate parsers.
Add tools for generating kernel data structures and uAPI headers.
- Expose all net/core sysctls inside netns.
- Remove 4s sleep in netpoll if carrier is instantly detected on
boot.
- Add configurable limit of MDB entries per port, and port-vlan.
- Continue populating drop reasons throughout the stack.
- Retire a handful of legacy Qdiscs and classifiers.
Protocols:
- Support IPv4 big TCP (TSO frames larger than 64kB).
- Add IP_LOCAL_PORT_RANGE socket option, to control local port range
on socket by socket basis.
- Track and report in procfs number of MPTCP sockets used.
- Support mixing IPv4 and IPv6 flows in the in-kernel MPTCP path
manager.
- IPv6: don't check net.ipv6.route.max_size and rely on garbage
collection to free memory (similarly to IPv4).
- Support Penultimate Segment Pop (PSP) flavor in SRv6 (RFC8986).
- ICMP: add per-rate limit counters.
- Add support for user scanning requests in ieee802154.
- Remove static WEP support.
- Support minimal Wi-Fi 7 Extremely High Throughput (EHT) rate
reporting.
- WiFi 7 EHT channel puncturing support (client & AP).
BPF:
- Add a rbtree data structure following the "next-gen data structure"
precedent set by recently added linked list, that is, by using
kfunc + kptr instead of adding a new BPF map type.
- Expose XDP hints via kfuncs with initial support for RX hash and
timestamp metadata.
- Add BPF_F_NO_TUNNEL_KEY extension to bpf_skb_set_tunnel_key to
better support decap on GRE tunnel devices not operating in collect
metadata.
- Improve x86 JIT's codegen for PROBE_MEM runtime error checks.
- Remove the need for trace_printk_lock for bpf_trace_printk and
bpf_trace_vprintk helpers.
- Extend libbpf's bpf_tracing.h support for tracing arguments of
kprobes/uprobes and syscall as a special case.
- Significantly reduce the search time for module symbols by
livepatch and BPF.
- Enable cpumasks to be used as kptrs, which is useful for tracing
programs tracking which tasks end up running on which CPUs in
different time intervals.
- Add support for BPF trampoline on s390x and riscv64.
- Add capability to export the XDP features supported by the NIC.
- Add __bpf_kfunc tag for marking kernel functions as kfuncs.
- Add cgroup.memory=nobpf kernel parameter option to disable BPF
memory accounting for container environments.
Netfilter:
- Remove the CLUSTERIP target. It has been marked as obsolete for
years, and we still have WARN splats wrt races of the out-of-band
/proc interface installed by this target.
- Add 'destroy' commands to nf_tables. They are identical to the
existing 'delete' commands, but do not return an error if the
referenced object (set, chain, rule...) did not exist.
Driver API:
- Improve cpumask_local_spread() locality to help NICs set the right
IRQ affinity on AMD platforms.
- Separate C22 and C45 MDIO bus transactions more clearly.
- Introduce new DCB table to control DSCP rewrite on egress.
- Support configuration of Physical Layer Collision Avoidance (PLCA)
Reconciliation Sublayer (RS) (802.3cg-2019). Modern version of
shared medium Ethernet.
- Support for MAC Merge layer (IEEE 802.3-2018 clause 99). Allowing
preemption of low priority frames by high priority frames.
- Add support for controlling MACSec offload using netlink SET.
- Rework devlink instance refcounts to allow registration and
de-registration under the instance lock. Split the code into
multiple files, drop some of the unnecessarily granular locks and
factor out common parts of netlink operation handling.
- Add TX frame aggregation parameters (for USB drivers).
- Add a new attr TCA_EXT_WARN_MSG to report TC (offload) warning
messages with notifications for debug.
- Allow offloading of UDP NEW connections via act_ct.
- Add support for per action HW stats in TC.
- Support hardware miss to TC action (continue processing in SW from
a specific point in the action chain).
- Warn if old Wireless Extension user space interface is used with
modern cfg80211/mac80211 drivers. Do not support Wireless
Extensions for Wi-Fi 7 devices at all. Everyone should switch to
using nl80211 interface instead.
- Improve the CAN bit timing configuration. Use extack to return
error messages directly to user space, update the SJW handling,
including the definition of a new default value that will benefit
CAN-FD controllers, by increasing their oscillator tolerance.
New hardware / drivers:
- Ethernet:
- nVidia BlueField-3 support (control traffic driver)
- Ethernet support for imx93 SoCs
- Motorcomm yt8531 gigabit Ethernet PHY
- onsemi NCN26000 10BASE-T1S PHY (with support for PLCA)
- Microchip LAN8841 PHY (incl. cable diagnostics and PTP)
- Amlogic gxl MDIO mux
- WiFi:
- RealTek RTL8188EU (rtl8xxxu)
- Qualcomm Wi-Fi 7 devices (ath12k)
- CAN:
- Renesas R-Car V4H
Drivers:
- Bluetooth:
- Set Per Platform Antenna Gain (PPAG) for Intel controllers.
- Ethernet NICs:
- Intel (1G, igc):
- support TSN / Qbv / packet scheduling features of i226 model
- Intel (100G, ice):
- use GNSS subsystem instead of TTY
- multi-buffer XDP support
- extend support for GPIO pins to E823 devices
- nVidia/Mellanox:
- update the shared buffer configuration on PFC commands
- implement PTP adjphase function for HW offset control
- TC support for Geneve and GRE with VF tunnel offload
- more efficient crypto key management method
- multi-port eswitch support
- Netronome/Corigine:
- add DCB IEEE support
- support IPsec offloading for NFP3800
- Freescale/NXP (enetc):
- support XDP_REDIRECT for XDP non-linear buffers
- improve reconfig, avoid link flap and waiting for idle
- support MAC Merge layer
- Other NICs:
- sfc/ef100: add basic devlink support for ef100
- ionic: rx_push mode operation (writing descriptors via MMIO)
- bnxt: use the auxiliary bus abstraction for RDMA
- r8169: disable ASPM and reset bus in case of tx timeout
- cpsw: support QSGMII mode for J721e CPSW9G
- cpts: support pulse-per-second output
- ngbe: add an mdio bus driver
- usbnet: optimize usbnet_bh() by avoiding unnecessary queuing
- r8152: handle devices with FW with NCM support
- amd-xgbe: support 10Mbps, 2.5GbE speeds and rx-adaptation
- virtio-net: support multi buffer XDP
- virtio/vsock: replace virtio_vsock_pkt with sk_buff
- tsnep: XDP support
- Ethernet high-speed switches:
- nVidia/Mellanox (mlxsw):
- add support for latency TLV (in FW control messages)
- Microchip (sparx5):
- separate explicit and implicit traffic forwarding rules, make
the implicit rules always active
- add support for egress DSCP rewrite
- IS0 VCAP support (Ingress Classification)
- IS2 VCAP filters (protos, L3 addrs, L4 ports, flags, ToS
etc.)
- ES2 VCAP support (Egress Access Control)
- support for Per-Stream Filtering and Policing (802.1Q,
8.6.5.1)
- Ethernet embedded switches:
- Marvell (mv88e6xxx):
- add MAB (port auth) offload support
- enable PTP receive for mv88e6390
- NXP (ocelot):
- support MAC Merge layer
- support for the the vsc7512 internal copper phys
- Microchip:
- lan9303: convert to PHYLINK
- lan966x: support TC flower filter statistics
- lan937x: PTP support for KSZ9563/KSZ8563 and LAN937x
- lan937x: support Credit Based Shaper configuration
- ksz9477: support Energy Efficient Ethernet
- other:
- qca8k: convert to regmap read/write API, use bulk operations
- rswitch: Improve TX timestamp accuracy
- Intel WiFi (iwlwifi):
- EHT (Wi-Fi 7) rate reporting
- STEP equalizer support: transfer some STEP (connection to radio
on platforms with integrated wifi) related parameters from the
BIOS to the firmware.
- Qualcomm 802.11ax WiFi (ath11k):
- IPQ5018 support
- Fine Timing Measurement (FTM) responder role support
- channel 177 support
- MediaTek WiFi (mt76):
- per-PHY LED support
- mt7996: EHT (Wi-Fi 7) support
- Wireless Ethernet Dispatch (WED) reset support
- switch to using page pool allocator
- RealTek WiFi (rtw89):
- support new version of Bluetooth co-existance
- Mobile:
- rmnet: support TX aggregation"
* tag 'net-next-6.3' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next: (1872 commits)
page_pool: add a comment explaining the fragment counter usage
net: ethtool: fix __ethtool_dev_mm_supported() implementation
ethtool: pse-pd: Fix double word in comments
xsk: add linux/vmalloc.h to xsk.c
sefltests: netdevsim: wait for devlink instance after netns removal
selftest: fib_tests: Always cleanup before exit
net/mlx5e: Align IPsec ASO result memory to be as required by hardware
net/mlx5e: TC, Set CT miss to the specific ct action instance
net/mlx5e: Rename CHAIN_TO_REG to MAPPED_OBJ_TO_REG
net/mlx5: Refactor tc miss handling to a single function
net/mlx5: Kconfig: Make tc offload depend on tc skb extension
net/sched: flower: Support hardware miss to tc action
net/sched: flower: Move filter handle initialization earlier
net/sched: cls_api: Support hardware miss to tc action
net/sched: Rename user cookie and act cookie
sfc: fix builds without CONFIG_RTC_LIB
sfc: clean up some inconsistent indentings
net/mlx4_en: Introduce flexible array to silence overflow warning
net: lan966x: Fix possible deadlock inside PTP
net/ulp: Remove redundant ->clone() test in inet_clone_ulp().
...
Diffstat (limited to 'arch/arm/mach-omap2/id.c')
-rw-r--r-- | arch/arm/mach-omap2/id.c | 805 |
1 files changed, 805 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c new file mode 100644 index 000000000..98999aa8c --- /dev/null +++ b/arch/arm/mach-omap2/id.c @@ -0,0 +1,805 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * 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> + */ + +#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; + +static 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()) { + if (omap3_has_iva() && omap3_has_sgx()) { + cpu_name = (omap3_has_isp()) ? "OMAP3630/DM3730" : "OMAP3621"; + } else if (omap3_has_iva()) { + cpu_name = "DM3725"; + } else if (omap3_has_sgx()) { + cpu_name = "OMAP3615/AM3715"; + } else { + cpu_name = (omap3_has_isp()) ? "AM3703" : "OMAP3611"; + } + } 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: + 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: + 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: + 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: + 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: + 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: + default: + omap_revision = AM437X_REV_ES1_2; + cpu_rev = "1.2"; + break; + } + break; + case 0xb8f2: + case 0xb968: + switch (rev) { + case 0: + 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: + 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, package; + struct omap_die_id odi; + + omap_get_die_id(&odi); + package = (odi.id_2 >> 16) & 0x3; + idcode = read_tap_reg(OMAP_TAP_IDCODE); + hawkeye = (idcode >> 12) & 0xffff; + rev = (idcode >> 28) & 0xff; + switch (hawkeye) { + case 0xbb50: + switch (rev) { + case 0: + default: + switch (package) { + case 0x2: + omap_revision = DRA762_ABZ_REV_ES1_0; + break; + case 0x3: + omap_revision = DRA762_ACD_REV_ES1_0; + break; + default: + omap_revision = DRA762_REV_ES1_0; + break; + } + break; + } + break; + + 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: + omap_revision = DRA722_REV_ES2_0; + break; + case 2: + default: + omap_revision = DRA722_REV_ES2_1; + 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 +type_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + return sprintf(buf, "%s\n", omap_types[omap_type()]); +} + +static DEVICE_ATTR_RO(type); + +static struct attribute *omap_soc_attrs[] = { + &dev_attr_type.attr, + NULL +}; + +ATTRIBUTE_GROUPS(omap_soc); + +void __init omap_soc_device_init(void) +{ + 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_attr->custom_attr_group = omap_soc_groups[0]; + + soc_dev = soc_device_register(soc_dev_attr); + if (IS_ERR(soc_dev)) { + kfree(soc_dev_attr); + return; + } +} +#endif /* CONFIG_SOC_BUS */ |