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

Commit 48e10548 authored by Srikanth Jampala's avatar Srikanth Jampala Committed by Herbert Xu
Browse files

crypto: cavium/nitrox - added support to identify the NITROX device partname.



Get the device partname based on it's capabilities like,
core frequency, number of cores and revision id.

Signed-off-by: default avatarSrikanth Jampala <Jampala.Srikanth@cavium.com>
Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
parent dfb89ab3
Loading
Loading
Loading
Loading
+111 −0
Original line number Diff line number Diff line
@@ -7,9 +7,16 @@

/* EMU clusters */
#define NR_CLUSTERS		4
/* Maximum cores per cluster,
 * varies based on partname
 */
#define AE_CORES_PER_CLUSTER	20
#define SE_CORES_PER_CLUSTER	16

#define AE_MAX_CORES	(AE_CORES_PER_CLUSTER * NR_CLUSTERS)
#define SE_MAX_CORES	(SE_CORES_PER_CLUSTER * NR_CLUSTERS)
#define ZIP_MAX_CORES	5

/* BIST registers */
#define EMU_BIST_STATUSX(_i)	(0x1402700 + ((_i) * 0x40000))
#define UCD_BIST_STATUS		0x12C0070
@@ -111,6 +118,9 @@
#define LBC_ELM_VF65_128_INT		0x120C000
#define LBC_ELM_VF65_128_INT_ENA_W1S	0x120F000

#define RST_BOOT	0x10C1600
#define FUS_DAT1	0x10C1408

/* PEM registers */
#define PEM0_INT 0x1080428

@@ -1082,4 +1092,105 @@ union lbc_inval_status {
	} s;
};

/**
 * struct rst_boot: RST Boot Register
 * @jtcsrdis: when set, internal CSR access via JTAG TAP controller
 *   is disabled
 * @jt_tst_mode: JTAG test mode
 * @io_supply: I/O power supply setting based on IO_VDD_SELECT pin:
 *    0x1 = 1.8V
 *    0x2 = 2.5V
 *    0x4 = 3.3V
 *    All other values are reserved
 * @pnr_mul: clock multiplier
 * @lboot: last boot cause mask, resets only with PLL_DC_OK
 * @rboot: determines whether core 0 remains in reset after
 *    chip cold or warm or soft reset
 * @rboot_pin: read only access to REMOTE_BOOT pin
 */
union rst_boot {
	u64 value;
	struct {
#if (defined(__BIG_ENDIAN_BITFIELD))
		u64 raz_63 : 1;
		u64 jtcsrdis : 1;
		u64 raz_59_61 : 3;
		u64 jt_tst_mode : 1;
		u64 raz_40_57 : 18;
		u64 io_supply : 3;
		u64 raz_30_36 : 7;
		u64 pnr_mul : 6;
		u64 raz_12_23 : 12;
		u64 lboot : 10;
		u64 rboot : 1;
		u64 rboot_pin : 1;
#else
		u64 rboot_pin : 1;
		u64 rboot : 1;
		u64 lboot : 10;
		u64 raz_12_23 : 12;
		u64 pnr_mul : 6;
		u64 raz_30_36 : 7;
		u64 io_supply : 3;
		u64 raz_40_57 : 18;
		u64 jt_tst_mode : 1;
		u64 raz_59_61 : 3;
		u64 jtcsrdis : 1;
		u64 raz_63 : 1;
#endif
	};
};

/**
 * struct fus_dat1: Fuse Data 1 Register
 * @pll_mul: main clock PLL multiplier hardware limit
 * @pll_half_dis: main clock PLL control
 * @efus_lck: efuse lockdown
 * @zip_info: ZIP information
 * @bar2_sz_conf: when zero, BAR2 size conforms to
 *    PCIe specification
 * @efus_ign: efuse ignore
 * @nozip: ZIP disable
 * @pll_alt_matrix: select alternate PLL matrix
 * @pll_bwadj_denom: select CLKF denominator for
 *    BWADJ value
 * @chip_id: chip ID
 */
union fus_dat1 {
	u64 value;
	struct {
#if (defined(__BIG_ENDIAN_BITFIELD))
		u64 raz_57_63 : 7;
		u64 pll_mul : 3;
		u64 pll_half_dis : 1;
		u64 raz_43_52 : 10;
		u64 efus_lck : 3;
		u64 raz_26_39 : 14;
		u64 zip_info : 5;
		u64 bar2_sz_conf : 1;
		u64 efus_ign : 1;
		u64 nozip : 1;
		u64 raz_11_17 : 7;
		u64 pll_alt_matrix : 1;
		u64 pll_bwadj_denom : 2;
		u64 chip_id : 8;
#else
		u64 chip_id : 8;
		u64 pll_bwadj_denom : 2;
		u64 pll_alt_matrix : 1;
		u64 raz_11_17 : 7;
		u64 nozip : 1;
		u64 efus_ign : 1;
		u64 bar2_sz_conf : 1;
		u64 zip_info : 5;
		u64 raz_26_39 : 14;
		u64 efus_lck : 3;
		u64 raz_43_52 : 10;
		u64 pll_half_dis : 1;
		u64 pll_mul : 3;
		u64 raz_57_63 : 7;
#endif
	};
};

#endif /* __NITROX_CSR_H */
+15 −2
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
#include <linux/dma-mapping.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/if.h>

#define VERSION_LEN 32

@@ -48,15 +49,27 @@ struct nitrox_cmdq {
	dma_addr_t dma;
};

/**
 * struct nitrox_hw - NITROX hardware information
 * @partname: partname ex: CNN55xxx-xxx
 * @fw_name: firmware version
 * @freq: NITROX frequency
 * @vendor_id: vendor ID
 * @device_id: device ID
 * @revision_id: revision ID
 * @se_cores: number of symmetric cores
 * @ae_cores: number of asymmetric cores
 * @zip_cores: number of zip cores
 */
struct nitrox_hw {
	/* firmware version */
	char partname[IFNAMSIZ * 2];
	char fw_name[VERSION_LEN];

	int freq;
	u16 vendor_id;
	u16 device_id;
	u8 revision_id;

	/* CNN55XX cores */
	u8 se_cores;
	u8 ae_cores;
	u8 zip_cores;
+57 −0
Original line number Diff line number Diff line
@@ -4,6 +4,8 @@
#include "nitrox_dev.h"
#include "nitrox_csr.h"

#define PLL_REF_CLK 50

/**
 * emu_enable_cores - Enable EMU cluster cores.
 * @ndev: N5 device
@@ -410,3 +412,58 @@ void config_nps_core_vfcfg_mode(struct nitrox_device *ndev, enum vf_mode mode)

	nitrox_write_csr(ndev, NPS_CORE_GBL_VFCFG, vfcfg.value);
}

void nitrox_get_hwinfo(struct nitrox_device *ndev)
{
	union emu_fuse_map emu_fuse;
	union rst_boot rst_boot;
	union fus_dat1 fus_dat1;
	unsigned char name[IFNAMSIZ * 2] = {};
	int i, dead_cores;
	u64 offset;

	/* get core frequency */
	offset = RST_BOOT;
	rst_boot.value = nitrox_read_csr(ndev, offset);
	ndev->hw.freq = (rst_boot.pnr_mul + 3) * PLL_REF_CLK;

	for (i = 0; i < NR_CLUSTERS; i++) {
		offset = EMU_FUSE_MAPX(i);
		emu_fuse.value = nitrox_read_csr(ndev, offset);
		if (emu_fuse.s.valid) {
			dead_cores = hweight32(emu_fuse.s.ae_fuse);
			ndev->hw.ae_cores += AE_CORES_PER_CLUSTER - dead_cores;
			dead_cores = hweight16(emu_fuse.s.se_fuse);
			ndev->hw.se_cores += SE_CORES_PER_CLUSTER - dead_cores;
		}
	}
	/* find zip hardware availability */
	offset = FUS_DAT1;
	fus_dat1.value = nitrox_read_csr(ndev, offset);
	if (!fus_dat1.nozip) {
		dead_cores = hweight8(fus_dat1.zip_info);
		ndev->hw.zip_cores = ZIP_MAX_CORES - dead_cores;
	}

	/* determine the partname CNN55<cores>-<freq><pincount>-<rev>*/
	if (ndev->hw.ae_cores == AE_MAX_CORES) {
		switch (ndev->hw.se_cores) {
		case SE_MAX_CORES:
			i = snprintf(name, sizeof(name), "CNN5560");
			break;
		case 40:
			i = snprintf(name, sizeof(name), "CNN5560s");
			break;
		}
	} else if (ndev->hw.ae_cores == (AE_MAX_CORES / 2)) {
		i = snprintf(name, sizeof(name), "CNN5530");
	} else {
		i = snprintf(name, sizeof(name), "CNN5560i");
	}

	snprintf(name + i, sizeof(name) - i, "-%3dBG676-1.%u",
		 ndev->hw.freq, ndev->hw.revision_id);

	/* copy partname */
	strncpy(ndev->hw.partname, name, sizeof(ndev->hw.partname));
}
+1 −0
Original line number Diff line number Diff line
@@ -18,5 +18,6 @@ void invalidate_lbc(struct nitrox_device *ndev);
void enable_pkt_input_ring(struct nitrox_device *ndev, int ring);
void enable_pkt_solicit_port(struct nitrox_device *ndev, int port);
void config_nps_core_vfcfg_mode(struct nitrox_device *ndev, enum vf_mode mode);
void nitrox_get_hwinfo(struct nitrox_device *ndev);

#endif /* __NITROX_HAL_H */
+0 −20
Original line number Diff line number Diff line
@@ -291,26 +291,6 @@ static int nitrox_bist_check(struct nitrox_device *ndev)
	return 0;
}

static void nitrox_get_hwinfo(struct nitrox_device *ndev)
{
	union emu_fuse_map emu_fuse;
	u64 offset;
	int i;

	for (i = 0; i < NR_CLUSTERS; i++) {
		u8 dead_cores;

		offset = EMU_FUSE_MAPX(i);
		emu_fuse.value = nitrox_read_csr(ndev, offset);
		if (emu_fuse.s.valid) {
			dead_cores = hweight32(emu_fuse.s.ae_fuse);
			ndev->hw.ae_cores += AE_CORES_PER_CLUSTER - dead_cores;
			dead_cores = hweight16(emu_fuse.s.se_fuse);
			ndev->hw.se_cores += SE_CORES_PER_CLUSTER - dead_cores;
		}
	}
}

static int nitrox_pf_hw_init(struct nitrox_device *ndev)
{
	int err;