1*c7941324Sskrll /* $NetBSD: sunxi_sid.c,v 1.8 2024/08/13 07:20:23 skrll Exp $ */ 24f0c0b5eSjmcneill 34f0c0b5eSjmcneill /*- 44f0c0b5eSjmcneill * Copyright (c) 2017 Jared McNeill <jmcneill@invisible.ca> 54f0c0b5eSjmcneill * All rights reserved. 64f0c0b5eSjmcneill * 74f0c0b5eSjmcneill * Redistribution and use in source and binary forms, with or without 84f0c0b5eSjmcneill * modification, are permitted provided that the following conditions 94f0c0b5eSjmcneill * are met: 104f0c0b5eSjmcneill * 1. Redistributions of source code must retain the above copyright 114f0c0b5eSjmcneill * notice, this list of conditions and the following disclaimer. 124f0c0b5eSjmcneill * 2. Redistributions in binary form must reproduce the above copyright 134f0c0b5eSjmcneill * notice, this list of conditions and the following disclaimer in the 144f0c0b5eSjmcneill * documentation and/or other materials provided with the distribution. 154f0c0b5eSjmcneill * 164f0c0b5eSjmcneill * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 174f0c0b5eSjmcneill * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 184f0c0b5eSjmcneill * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 194f0c0b5eSjmcneill * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 204f0c0b5eSjmcneill * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 214f0c0b5eSjmcneill * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 224f0c0b5eSjmcneill * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 234f0c0b5eSjmcneill * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 244f0c0b5eSjmcneill * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 254f0c0b5eSjmcneill * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 264f0c0b5eSjmcneill * SUCH DAMAGE. 274f0c0b5eSjmcneill */ 284f0c0b5eSjmcneill 294f0c0b5eSjmcneill #include <sys/cdefs.h> 30*c7941324Sskrll __KERNEL_RCSID(0, "$NetBSD: sunxi_sid.c,v 1.8 2024/08/13 07:20:23 skrll Exp $"); 314f0c0b5eSjmcneill 324f0c0b5eSjmcneill #include <sys/param.h> 334f0c0b5eSjmcneill #include <sys/bus.h> 344f0c0b5eSjmcneill #include <sys/device.h> 354f0c0b5eSjmcneill #include <sys/intr.h> 364f0c0b5eSjmcneill #include <sys/systm.h> 374f0c0b5eSjmcneill 384f0c0b5eSjmcneill #include <dev/fdt/fdtvar.h> 394f0c0b5eSjmcneill 404f0c0b5eSjmcneill #include <arm/sunxi/sunxi_sid.h> 414f0c0b5eSjmcneill 424f0c0b5eSjmcneill #define EFUSE_THERMAL_CALIB0 0x34 434f0c0b5eSjmcneill #define EFUSE_THERMAL_CALIB1 0x38 444f0c0b5eSjmcneill 454f0c0b5eSjmcneill struct sunxi_sid_config { 464f0c0b5eSjmcneill bus_size_t efuse_offset; 474f0c0b5eSjmcneill }; 484f0c0b5eSjmcneill 494f0c0b5eSjmcneill static const struct sunxi_sid_config sun4i_a10_sid_config = { 504f0c0b5eSjmcneill .efuse_offset = 0, 514f0c0b5eSjmcneill }; 524f0c0b5eSjmcneill 534f0c0b5eSjmcneill static const struct sunxi_sid_config sun8i_h3_sid_config = { 544f0c0b5eSjmcneill .efuse_offset = 0x200, 554f0c0b5eSjmcneill }; 564f0c0b5eSjmcneill 57646c0f59Sthorpej static const struct device_compatible_entry compat_data[] = { 58646c0f59Sthorpej { .compat = "allwinner,sun4i-a10-sid", .data = &sun4i_a10_sid_config }, 59646c0f59Sthorpej { .compat = "allwinner,sun7i-a20-sid", .data = &sun4i_a10_sid_config }, 60646c0f59Sthorpej { .compat = "allwinner,sun8i-h3-sid", .data = &sun8i_h3_sid_config }, 61646c0f59Sthorpej { .compat = "allwinner,sun8i-a83t-sid", .data = &sun8i_h3_sid_config }, 62*c7941324Sskrll { .compat = "allwinner,sun20i-d1-sid", .data = &sun8i_h3_sid_config }, 63646c0f59Sthorpej { .compat = "allwinner,sun50i-a64-sid", .data = &sun8i_h3_sid_config }, 64ec189949Sthorpej DEVICE_COMPAT_EOL 654f0c0b5eSjmcneill }; 664f0c0b5eSjmcneill 674f0c0b5eSjmcneill struct sunxi_sid_softc { 684f0c0b5eSjmcneill device_t sc_dev; 694f0c0b5eSjmcneill bus_space_tag_t sc_bst; 704f0c0b5eSjmcneill bus_space_handle_t sc_bsh; 714f0c0b5eSjmcneill const struct sunxi_sid_config *sc_conf; 724f0c0b5eSjmcneill }; 734f0c0b5eSjmcneill 744f0c0b5eSjmcneill static struct sunxi_sid_softc *sid_softc = NULL; 754f0c0b5eSjmcneill 764f0c0b5eSjmcneill #define EFUSE_READ(sc, reg) \ 774f0c0b5eSjmcneill bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (sc)->sc_conf->efuse_offset + (reg)) 784f0c0b5eSjmcneill #define EFUSE_WRITE(sc, reg, val) \ 794f0c0b5eSjmcneill bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (sc)->sc_conf->efuse_offset + (reg), (val)) 804f0c0b5eSjmcneill 814f0c0b5eSjmcneill static int 824f0c0b5eSjmcneill sunxi_sid_match(device_t parent, cfdata_t cf, void *aux) 834f0c0b5eSjmcneill { 844f0c0b5eSjmcneill struct fdt_attach_args * const faa = aux; 854f0c0b5eSjmcneill 866e54367aSthorpej return of_compatible_match(faa->faa_phandle, compat_data); 874f0c0b5eSjmcneill } 884f0c0b5eSjmcneill 894f0c0b5eSjmcneill static void 904f0c0b5eSjmcneill sunxi_sid_attach(device_t parent, device_t self, void *aux) 914f0c0b5eSjmcneill { 924f0c0b5eSjmcneill struct sunxi_sid_softc * const sc = device_private(self); 934f0c0b5eSjmcneill struct fdt_attach_args * const faa = aux; 944f0c0b5eSjmcneill const int phandle = faa->faa_phandle; 954f0c0b5eSjmcneill bus_addr_t addr; 964f0c0b5eSjmcneill bus_size_t size; 974f0c0b5eSjmcneill 984f0c0b5eSjmcneill if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { 994f0c0b5eSjmcneill aprint_error(": couldn't get registers\n"); 1004f0c0b5eSjmcneill return; 1014f0c0b5eSjmcneill } 1024f0c0b5eSjmcneill 1034f0c0b5eSjmcneill sc->sc_dev = self; 1044f0c0b5eSjmcneill sc->sc_bst = faa->faa_bst; 1054f0c0b5eSjmcneill if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { 1064f0c0b5eSjmcneill aprint_error(": couldn't map registers\n"); 1074f0c0b5eSjmcneill return; 1084f0c0b5eSjmcneill } 1096e54367aSthorpej sc->sc_conf = of_compatible_lookup(phandle, compat_data)->data; 1104f0c0b5eSjmcneill 1114f0c0b5eSjmcneill aprint_naive("\n"); 1124f0c0b5eSjmcneill aprint_normal(": Security ID EFUSE\n"); 1134f0c0b5eSjmcneill 1144f0c0b5eSjmcneill KASSERT(sid_softc == NULL); 1154f0c0b5eSjmcneill sid_softc = sc; 1164f0c0b5eSjmcneill } 1174f0c0b5eSjmcneill 1184f0c0b5eSjmcneill CFATTACH_DECL_NEW(sunxi_sid, sizeof(struct sunxi_sid_softc), 1194f0c0b5eSjmcneill sunxi_sid_match, sunxi_sid_attach, NULL, NULL); 1204f0c0b5eSjmcneill 1214f0c0b5eSjmcneill int 1224f0c0b5eSjmcneill sunxi_sid_read_tscalib(uint32_t *calib) 1234f0c0b5eSjmcneill { 1244f0c0b5eSjmcneill if (sid_softc == NULL) 1254f0c0b5eSjmcneill return ENXIO; 1264f0c0b5eSjmcneill 1274f0c0b5eSjmcneill calib[0] = EFUSE_READ(sid_softc, EFUSE_THERMAL_CALIB0); 1284f0c0b5eSjmcneill calib[1] = EFUSE_READ(sid_softc, EFUSE_THERMAL_CALIB1); 1294f0c0b5eSjmcneill return 0; 1304f0c0b5eSjmcneill } 131