Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Copyright (C) 2006-2010 Freescale Semiconductor, Inc. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Authors: 	Shlomi Gridish <gridish@freescale.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * 		Li Yang <leoli@freescale.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * Based on cpm2_common.c from Dan Malek (dmalek@jlc.net)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)  * General Purpose functions for the global management of the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)  * QUICC Engine (QE).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/bitmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <linux/param.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #include <linux/iopoll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #include <linux/crc32.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/mod_devicetable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include <soc/fsl/qe/immap_qe.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include <soc/fsl/qe/qe.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) static void qe_snums_init(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) static int qe_sdma_init(void);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) static DEFINE_SPINLOCK(qe_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) DEFINE_SPINLOCK(cmxgcr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) EXPORT_SYMBOL(cmxgcr_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) /* We allocate this here because it is used almost exclusively for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40)  * the communication processor devices.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) struct qe_immap __iomem *qe_immr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) EXPORT_SYMBOL(qe_immr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) static u8 snums[QE_NUM_OF_SNUM];	/* Dynamically allocated SNUMs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) static DECLARE_BITMAP(snum_state, QE_NUM_OF_SNUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) static unsigned int qe_num_of_snum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) static phys_addr_t qebase = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) static struct device_node *qe_get_device_node(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	struct device_node *qe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	 * Newer device trees have an "fsl,qe" compatible property for the QE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	 * node, but we still need to support older device trees.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	qe = of_find_compatible_node(NULL, NULL, "fsl,qe");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	if (qe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		return qe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	return of_find_node_by_type(NULL, "qe");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) static phys_addr_t get_qe_base(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	struct device_node *qe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	struct resource res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 	if (qebase != -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		return qebase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	qe = qe_get_device_node();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	if (!qe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		return qebase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	ret = of_address_to_resource(qe, 0, &res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		qebase = res.start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	of_node_put(qe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	return qebase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) void qe_reset(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	if (qe_immr == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		qe_immr = ioremap(get_qe_base(), QE_IMMAP_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	qe_snums_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	qe_issue_cmd(QE_RESET, QE_CR_SUBBLOCK_INVALID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		     QE_CR_PROTOCOL_UNSPECIFIED, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	/* Reclaim the MURAM memory for our use. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	qe_muram_init();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	if (qe_sdma_init())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 		panic("sdma init failed!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) int qe_issue_cmd(u32 cmd, u32 device, u8 mcn_protocol, u32 cmd_input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	u8 mcn_shift = 0, dev_shift = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	spin_lock_irqsave(&qe_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	if (cmd == QE_RESET) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		qe_iowrite32be((u32)(cmd | QE_CR_FLG), &qe_immr->cp.cecr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		if (cmd == QE_ASSIGN_PAGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 			/* Here device is the SNUM, not sub-block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 			dev_shift = QE_CR_SNUM_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 		} else if (cmd == QE_ASSIGN_RISC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 			/* Here device is the SNUM, and mcnProtocol is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 			 * e_QeCmdRiscAssignment value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 			dev_shift = QE_CR_SNUM_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 			mcn_shift = QE_CR_MCN_RISC_ASSIGN_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 			if (device == QE_CR_SUBBLOCK_USB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 				mcn_shift = QE_CR_MCN_USB_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 			else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 				mcn_shift = QE_CR_MCN_NORMAL_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 		qe_iowrite32be(cmd_input, &qe_immr->cp.cecdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		qe_iowrite32be((cmd | QE_CR_FLG | ((u32)device << dev_shift) | (u32)mcn_protocol << mcn_shift),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 			       &qe_immr->cp.cecr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	/* wait for the QE_CR_FLG to clear */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	ret = readx_poll_timeout_atomic(qe_ioread32be, &qe_immr->cp.cecr, val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 					(val & QE_CR_FLG) == 0, 0, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	/* On timeout, ret is -ETIMEDOUT, otherwise it will be 0. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	spin_unlock_irqrestore(&qe_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	return ret == 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) EXPORT_SYMBOL(qe_issue_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) /* Set a baud rate generator. This needs lots of work. There are
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)  * 16 BRGs, which can be connected to the QE channels or output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)  * as clocks. The BRGs are in two different block of internal
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  * memory mapped space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  * The BRG clock is the QE clock divided by 2.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)  * It was set up long ago during the initial boot phase and is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)  * is given to us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)  * Baud rate clocks are zero-based in the driver code (as that maps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)  * to port numbers). Documentation uses 1-based numbering.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static unsigned int brg_clk = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) #define CLK_GRAN	(1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define CLK_GRAN_LIMIT	(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) unsigned int qe_get_brg_clk(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	struct device_node *qe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	u32 brg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	unsigned int mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	if (brg_clk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		return brg_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	qe = qe_get_device_node();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	if (!qe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 		return brg_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	if (!of_property_read_u32(qe, "brg-frequency", &brg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		brg_clk = brg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	of_node_put(qe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	/* round this if near to a multiple of CLK_GRAN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	mod = brg_clk % CLK_GRAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	if (mod) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		if (mod < CLK_GRAN_LIMIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 			brg_clk -= mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		else if (mod > (CLK_GRAN - CLK_GRAN_LIMIT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 			brg_clk += CLK_GRAN - mod;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	return brg_clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) EXPORT_SYMBOL(qe_get_brg_clk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #define PVR_VER_836x	0x8083
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #define PVR_VER_832x	0x8084
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) static bool qe_general4_errata(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #ifdef CONFIG_PPC32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	return pvr_version_is(PVR_VER_836x) || pvr_version_is(PVR_VER_832x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) /* Program the BRG to the given sampling rate and multiplier
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203)  * @brg: the BRG, QE_BRG1 - QE_BRG16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)  * @rate: the desired sampling rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205)  * @multiplier: corresponds to the value programmed in GUMR_L[RDCR] or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)  * GUMR_L[TDCR].  E.g., if this BRG is the RX clock, and GUMR_L[RDCR]=01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)  * then 'multiplier' should be 8.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	u32 divisor, tempval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	u32 div16 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	if ((brg < QE_BRG1) || (brg > QE_BRG16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	divisor = qe_get_brg_clk() / (rate * multiplier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		div16 = QE_BRGC_DIV16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		divisor /= 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	/* Errata QE_General4, which affects some MPC832x and MPC836x SOCs, says
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	   that the BRG divisor must be even if you're not using divide-by-16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	   mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 	if (qe_general4_errata())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		if (!div16 && (divisor & 1) && (divisor > 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 			divisor++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 		QE_BRGC_ENABLE | div16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 	qe_iowrite32be(tempval, &qe_immr->brg.brgc[brg - QE_BRG1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) EXPORT_SYMBOL(qe_setbrg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /* Convert a string to a QE clock source enum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)  * This function takes a string, typically from a property in the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)  * tree, and returns the corresponding "enum qe_clock" value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) enum qe_clock qe_clock_source(const char *source)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	if (strcasecmp(source, "none") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 		return QE_CLK_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	if (strcmp(source, "tsync_pin") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 		return QE_TSYNC_PIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	if (strcmp(source, "rsync_pin") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 		return QE_RSYNC_PIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	if (strncasecmp(source, "brg", 3) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 		i = simple_strtoul(source + 3, NULL, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 		if ((i >= 1) && (i <= 16))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 			return (QE_BRG1 - 1) + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 			return QE_CLK_DUMMY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 	if (strncasecmp(source, "clk", 3) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		i = simple_strtoul(source + 3, NULL, 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		if ((i >= 1) && (i <= 24))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 			return (QE_CLK1 - 1) + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 			return QE_CLK_DUMMY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	return QE_CLK_DUMMY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) EXPORT_SYMBOL(qe_clock_source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) /* Initialize SNUMs (thread serial numbers) according to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)  * QE Module Control chapter, SNUM table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static void qe_snums_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	static const u8 snum_init_76[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 		0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 		0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		0xD8, 0xD9, 0xE8, 0xE9, 0x44, 0x45, 0x4C, 0x4D,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		0x54, 0x55, 0x5C, 0x5D, 0x64, 0x65, 0x6C, 0x6D,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 		0x74, 0x75, 0x7C, 0x7D, 0x84, 0x85, 0x8C, 0x8D,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		0x94, 0x95, 0x9C, 0x9D, 0xA4, 0xA5, 0xAC, 0xAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		0xB4, 0xB5, 0xBC, 0xBD, 0xC4, 0xC5, 0xCC, 0xCD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 		0xD4, 0xD5, 0xDC, 0xDD, 0xE4, 0xE5, 0xEC, 0xED,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		0xF4, 0xF5, 0xFC, 0xFD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	static const u8 snum_init_46[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		0x04, 0x05, 0x0C, 0x0D, 0x14, 0x15, 0x1C, 0x1D,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		0x24, 0x25, 0x2C, 0x2D, 0x34, 0x35, 0x88, 0x89,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		0x98, 0x99, 0xA8, 0xA9, 0xB8, 0xB9, 0xC8, 0xC9,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 		0xD8, 0xD9, 0xE8, 0xE9, 0x08, 0x09, 0x18, 0x19,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		0x28, 0x29, 0x38, 0x39, 0x48, 0x49, 0x58, 0x59,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		0x68, 0x69, 0x78, 0x79, 0x80, 0x81,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	struct device_node *qe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	const u8 *snum_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	bitmap_zero(snum_state, QE_NUM_OF_SNUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 	qe_num_of_snum = 28; /* The default number of snum for threads is 28 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	qe = qe_get_device_node();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 	if (qe) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 		i = of_property_read_variable_u8_array(qe, "fsl,qe-snums",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 						       snums, 1, QE_NUM_OF_SNUM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 		if (i > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 			of_node_put(qe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 			qe_num_of_snum = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 		 * Fall back to legacy binding of using the value of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		 * fsl,qe-num-snums to choose one of the static arrays
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 		 * above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 		of_property_read_u32(qe, "fsl,qe-num-snums", &qe_num_of_snum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 		of_node_put(qe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 	if (qe_num_of_snum == 76) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 		snum_init = snum_init_76;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	} else if (qe_num_of_snum == 28 || qe_num_of_snum == 46) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 		snum_init = snum_init_46;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 		pr_err("QE: unsupported value of fsl,qe-num-snums: %u\n", qe_num_of_snum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	memcpy(snums, snum_init, qe_num_of_snum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) int qe_get_snum(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 	int snum = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 	spin_lock_irqsave(&qe_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	i = find_first_zero_bit(snum_state, qe_num_of_snum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 	if (i < qe_num_of_snum) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		set_bit(i, snum_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		snum = snums[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 	spin_unlock_irqrestore(&qe_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 	return snum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) EXPORT_SYMBOL(qe_get_snum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) void qe_put_snum(u8 snum)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	const u8 *p = memchr(snums, snum, qe_num_of_snum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	if (p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		clear_bit(p - snums, snum_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) EXPORT_SYMBOL(qe_put_snum);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) static int qe_sdma_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	struct sdma __iomem *sdma = &qe_immr->sdma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 	static s32 sdma_buf_offset = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	/* allocate 2 internal temporary buffers (512 bytes size each) for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	 * the SDMA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	if (sdma_buf_offset < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 		sdma_buf_offset = qe_muram_alloc(512 * 2, 4096);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		if (sdma_buf_offset < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	qe_iowrite32be((u32)sdma_buf_offset & QE_SDEBCR_BA_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		       &sdma->sdebcr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	qe_iowrite32be((QE_SDMR_GLB_1_MSK | (0x1 << QE_SDMR_CEN_SHIFT)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		       &sdma->sdmr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) /* The maximum number of RISCs we support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) #define MAX_QE_RISC     4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /* Firmware information stored here for qe_get_firmware_info() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) static struct qe_firmware_info qe_firmware_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)  * Set to 1 if QE firmware has been uploaded, and therefore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)  * qe_firmware_info contains valid data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) static int qe_firmware_uploaded;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399)  * Upload a QE microcode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)  * This function is a worker function for qe_upload_firmware().  It does
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)  * the actual uploading of the microcode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) static void qe_upload_microcode(const void *base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	const struct qe_microcode *ucode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	const __be32 *code = base + be32_to_cpu(ucode->code_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	if (ucode->major || ucode->minor || ucode->revision)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 		printk(KERN_INFO "qe-firmware: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 			"uploading microcode '%s' version %u.%u.%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 			ucode->id, ucode->major, ucode->minor, ucode->revision);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 		printk(KERN_INFO "qe-firmware: "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) 			"uploading microcode '%s'\n", ucode->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) 	/* Use auto-increment */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) 	qe_iowrite32be(be32_to_cpu(ucode->iram_offset) | QE_IRAM_IADD_AIE | QE_IRAM_IADD_BADDR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 		       &qe_immr->iram.iadd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 	for (i = 0; i < be32_to_cpu(ucode->count); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 		qe_iowrite32be(be32_to_cpu(code[i]), &qe_immr->iram.idata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	/* Set I-RAM Ready Register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 	qe_iowrite32be(QE_IRAM_READY, &qe_immr->iram.iready);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)  * Upload a microcode to the I-RAM at a specific address.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)  * See Documentation/powerpc/qe_firmware.rst for information on QE microcode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)  * uploading.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)  * Currently, only version 1 is supported, so the 'version' field must be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436)  * set to 1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)  * The SOC model and revision are not validated, they are only displayed for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)  * informational purposes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)  * 'calc_size' is the calculated size, in bytes, of the firmware structure and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442)  * all of the microcode structures, minus the CRC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444)  * 'length' is the size that the structure says it is, including the CRC.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) int qe_upload_firmware(const struct qe_firmware *firmware)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	unsigned int j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 	u32 crc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 	size_t calc_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 	size_t length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) 	const struct qe_header *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) 	if (!firmware) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 		printk(KERN_ERR "qe-firmware: invalid pointer\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	hdr = &firmware->header;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	length = be32_to_cpu(hdr->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	/* Check the magic */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	if ((hdr->magic[0] != 'Q') || (hdr->magic[1] != 'E') ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	    (hdr->magic[2] != 'F')) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		printk(KERN_ERR "qe-firmware: not a microcode\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 	/* Check the version */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 	if (hdr->version != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 		printk(KERN_ERR "qe-firmware: unsupported version\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	/* Validate some of the fields */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 	if ((firmware->count < 1) || (firmware->count > MAX_QE_RISC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 		printk(KERN_ERR "qe-firmware: invalid data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 	/* Validate the length and check if there's a CRC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	calc_size = struct_size(firmware, microcode, firmware->count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	for (i = 0; i < firmware->count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 		 * For situations where the second RISC uses the same microcode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 		 * as the first, the 'code_offset' and 'count' fields will be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 		 * zero, so it's okay to add those.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 		calc_size += sizeof(__be32) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 			be32_to_cpu(firmware->microcode[i].count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	/* Validate the length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	if (length != calc_size + sizeof(__be32)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		printk(KERN_ERR "qe-firmware: invalid length\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 		return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	/* Validate the CRC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 	crc = be32_to_cpu(*(__be32 *)((void *)firmware + calc_size));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	if (crc != crc32(0, firmware, calc_size)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 		printk(KERN_ERR "qe-firmware: firmware CRC is invalid\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 	 * If the microcode calls for it, split the I-RAM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	if (!firmware->split)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		qe_setbits_be16(&qe_immr->cp.cercr, QE_CP_CERCR_CIR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 	if (firmware->soc.model)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 		printk(KERN_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 			"qe-firmware: firmware '%s' for %u V%u.%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 			firmware->id, be16_to_cpu(firmware->soc.model),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 			firmware->soc.major, firmware->soc.minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 		printk(KERN_INFO "qe-firmware: firmware '%s'\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 			firmware->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	 * The QE only supports one microcode per RISC, so clear out all the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 	 * saved microcode information and put in the new.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	memset(&qe_firmware_info, 0, sizeof(qe_firmware_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	strlcpy(qe_firmware_info.id, firmware->id, sizeof(qe_firmware_info.id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 	qe_firmware_info.extended_modes = be64_to_cpu(firmware->extended_modes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 	memcpy(qe_firmware_info.vtraps, firmware->vtraps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		sizeof(firmware->vtraps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 	/* Loop through each microcode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 	for (i = 0; i < firmware->count; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		const struct qe_microcode *ucode = &firmware->microcode[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 		/* Upload a microcode if it's present */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		if (ucode->code_offset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 			qe_upload_microcode(firmware, ucode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		/* Program the traps for this processor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 		for (j = 0; j < 16; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 			u32 trap = be32_to_cpu(ucode->traps[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 			if (trap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 				qe_iowrite32be(trap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 					       &qe_immr->rsp[i].tibcr[j]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 		/* Enable traps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		qe_iowrite32be(be32_to_cpu(ucode->eccr),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 			       &qe_immr->rsp[i].eccr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	qe_firmware_uploaded = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) EXPORT_SYMBOL(qe_upload_firmware);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)  * Get info on the currently-loaded firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)  * This function also checks the device tree to see if the boot loader has
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564)  * uploaded a firmware already.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) struct qe_firmware_info *qe_get_firmware_info(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 	static int initialized;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	struct device_node *qe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	struct device_node *fw = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	const char *sprop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 	 * If we haven't checked yet, and a driver hasn't uploaded a firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	 * yet, then check the device tree for information.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	if (qe_firmware_uploaded)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 		return &qe_firmware_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 	if (initialized)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	initialized = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 	qe = qe_get_device_node();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 	if (!qe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	/* Find the 'firmware' child node */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 	fw = of_get_child_by_name(qe, "firmware");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 	of_node_put(qe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 	/* Did we find the 'firmware' node? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	if (!fw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	qe_firmware_uploaded = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	/* Copy the data into qe_firmware_info*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 	sprop = of_get_property(fw, "id", NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 	if (sprop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 		strlcpy(qe_firmware_info.id, sprop,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 			sizeof(qe_firmware_info.id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	of_property_read_u64(fw, "extended-modes",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 			     &qe_firmware_info.extended_modes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	of_property_read_u32_array(fw, "virtual-traps", qe_firmware_info.vtraps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 				   ARRAY_SIZE(qe_firmware_info.vtraps));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 	of_node_put(fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	return &qe_firmware_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) EXPORT_SYMBOL(qe_get_firmware_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) unsigned int qe_get_num_of_risc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	struct device_node *qe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	unsigned int num_of_risc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	qe = qe_get_device_node();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 	if (!qe)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 		return num_of_risc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	of_property_read_u32(qe, "fsl,qe-num-riscs", &num_of_risc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	of_node_put(qe);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	return num_of_risc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) EXPORT_SYMBOL(qe_get_num_of_risc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) unsigned int qe_get_num_of_snums(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	return qe_num_of_snum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) EXPORT_SYMBOL(qe_get_num_of_snums);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) static int __init qe_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 	struct device_node *np;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	np = of_find_compatible_node(NULL, NULL, "fsl,qe");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	if (!np)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 	qe_reset();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	of_node_put(np);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) subsys_initcall(qe_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) #if defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) static int qe_resume(struct platform_device *ofdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) 	if (!qe_alive_during_sleep())
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 		qe_reset();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) static int qe_probe(struct platform_device *ofdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) static const struct of_device_id qe_ids[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	{ .compatible = "fsl,qe", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 	{ },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) static struct platform_driver qe_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 		.name = "fsl-qe",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 		.of_match_table = qe_ids,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 	.probe = qe_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 	.resume = qe_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) builtin_platform_driver(qe_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) #endif /* defined(CONFIG_SUSPEND) && defined(CONFIG_PPC_85xx) */