qe: add ability to upload QE firmware
Subsystems (2)
PATCH v6 1/1 qe: add ability to upload QE firmware
Define the layout of a binary blob that contains a QE firmware and instructions on how to upload it. Add function qe_upload_firmware() to parse the blob and perform the actual upload. Fully define 'struct rsp' in immap_qe.h to include the actual RISC Special Registers. Added description of a new QE firmware node to booting-without-of.txt.
---
Updated w.r.t. comments from Anton V.
This patch is for Kumar's for-2.6.25 branch. This code is necessary for my QE UART driver.
Documentation/powerpc/00-INDEX | 3 + Documentation/powerpc/booting-without-of.txt | 33 +++- Documentation/powerpc/qe_firmware.txt | 295 ++++++++++++++++++++++++++ arch/powerpc/platforms/Kconfig | 1 + arch/powerpc/sysdev/qe_lib/qe.c | 248 ++++++++++++++++++++++ include/asm-powerpc/immap_qe.h | 34 +++- include/asm-powerpc/qe.h | 61 ++++++ 7 files changed, 671 insertions(+), 4 deletions(-) create mode 100644 Documentation/powerpc/qe_firmware.txt
Documentation/powerpc/00-INDEX +3 -0
@@ -28,3 +28,6 @@ sound.txt - info on sound support under Linux/PPC zImage_layout.txt - info on the kernel images for Linux/PPC +qe_firmware.txt + - describes the layout of firmware binaries for the Freescale QUICC + Engine and the code that parses and uploads the microcode therein.
Documentation/powerpc/booting-without-of.txt +31 -2
@@ -52,7 +52,10 @@ Table of Contents i) Freescale QUICC Engine module (QE) j) CFI or JEDEC memory-mapped NOR flash k) Global Utilities Block - l) Xilinx IP cores + l) Freescale Communications Processor Module + m) Chipselect/Local Bus + n) 4xx/Axon EMAC ethernet nodes + o) Xilinx IP cores VII - Specifying interrupt information for devices 1) interrupts property
@@ -1772,6 +1775,32 @@ platforms are moved over to use the flattened-device-tree model. }; }; + viii) Uploaded QE firmware + + If a new firwmare has been uploaded to the QE (usually by the + boot loader), then a 'firmware' child node should be added to the QE + node. This node provides information on the uploaded firmware that + device drivers may need. + + Required properties: + - id: The string name of the firmware. This is taken from the 'id' + member of the qe_firmware structure of the uploaded firmware. + Device drivers can search this string to determine if the + firmware they want is already present. + - extended-modes: The Extended Modes bitfield, taken from the + firmware binary. It is a 64-bit number represented + as an array of two 32-bit numbers. + - virtual-traps: The virtual traps, taken from the firmware binary. + It is an array of 8 32-bit numbers. + + Example: + + firmware { + id = "Soft-UART"; + extended-modes = <0 0>; + virtual-traps = <0 0 0 0 0 0 0 0>; + } + j) CFI or JEDEC memory-mapped NOR flash Flash chips (Memory Technology Devices) are often used for solid state
@@ -2254,7 +2283,7 @@ platforms are moved over to use the flattened-device-tree model. available. For Axon: 0x0000012a - l) Xilinx IP cores + o) Xilinx IP cores The Xilinx EDK toolchain ships with a set of IP cores (devices) for use in Xilinx Spartan and Virtex FPGAs. The devices cover the whole range
Documentation/powerpc/qe_firmware.txt new file +295 -0
295 lines not on this page · raw message
arch/powerpc/platforms/Kconfig +1 -0
@@ -265,6 +265,7 @@ config TAU_AVERAGE config QUICC_ENGINE bool select PPC_LIB_RHEAP + select CRC32 help The QUICC Engine (QE) is a new generation of communications coprocessors on Freescale embedded CPUs (akin to CPM in older chips).
arch/powerpc/sysdev/qe_lib/qe.c +248 -0
257 lines not on this page · raw message
include/asm-powerpc/immap_qe.h +32 -2
@@ -393,9 +393,39 @@ struct dbg {u8 res2[0x48 ]; } __attribute__ ((packed)); -/* RISC Special Registers (Trap and Breakpoint) */ +/* +* RISC Special Registers (Trap and Breakpoint). These are described in +* the QE Developer's Handbook. +*/ struct rsp { -u32 reg[0x40 ];/* 64 32-bit registers */ +__be32 tibcr[16 ];/* Trap/instruction breakpoint control regs */ +u8 res0[64 ]; +__be32 ibcr0; +__be32 ibs0; +__be32 ibcnr0; +u8 res1[4 ]; +__be32 ibcr1; +__be32 ibs1; +__be32 ibcnr1; +__be32 npcr; +__be32 dbcr; +__be32 dbar; +__be32 dbamr; +__be32 dbsr; +__be32 dbcnr; +u8 res2[12 ]; +__be32 dbdr_h; +__be32 dbdr_l; +__be32 dbdmr_h; +__be32 dbdmr_l; +__be32 bsr; +__be32 bor; +__be32 bior; +u8 res3[4 ]; +__be32 iatr[4 ]; +__be32 eccr;/* Exception control configuration register */ +__be32 eicr; +u8 res4[0x100 -0xf8 ]; } __attribute__ ((packed));struct qe_immap {
include/asm-powerpc/qe.h +61 -0
73 lines not on this page · raw message
Signature · 1 line
1.5.2.4
arch/powerpc/sysdev/qe_lib/qe.c void *qe_muram_addr(unsigned long offset) · line 572
Quoted 6 lines · On Mon, 7 Jan 2008 16:15:44 -0600 Timur Tabi <[email protected]> wrote:
arch/powerpc/sysdev/qe_lib/qe.c +4
-0+struct qe_firmware_info *qe_get_firmware_info (void ) +{ +/* Find the 'firmware' child node */ +while ((fw =of_get_next_child (qe, fw)))
If you use:
for_each_child_of_node(qe, fw)
You don't need to initialise 'fw' in its declararion.
arch/powerpc/sysdev/qe_lib/qe.c void *qe_muram_addr(unsigned long offset) · line 578
Quoted 3 lines
arch/powerpc/sysdev/qe_lib/qe.c +3
-0+/* Did we find the 'firmware' node? */ +if (!fw) { +of_node_put (fw);
This of_node_put is not necessary (as fw is NULL);
arch/powerpc/sysdev/qe_lib/qe.c void *qe_muram_addr(unsigned long offset) · line 596
Quoted 6 lines
arch/powerpc/sysdev/qe_lib/qe.c +6
-0+ prop =of_find_property (fw,"extended-modes" ,NULL ); +if (prop && (prop->length ==sizeof (u64))) { +const u64 *iprop = prop->value; + + qe_firmware_info.extended_modes = *iprop; + }
Why not:
const u64 *iprop; int len; iprop = of_get_property(fs, "extended-modes", &len); if (iprop && (len == sizeof(u64)) qe_firmware_info.extended_modes = *iprop;
arch/powerpc/sysdev/qe_lib/qe.c void *qe_muram_addr(unsigned long offset) · line 604
Quoted 7 lines
arch/powerpc/sysdev/qe_lib/qe.c +7
-0+ prop =of_find_property (fw,"virtual-traps" ,NULL ); +if (prop && (prop->length ==32 )) { +const u32 *iprop = prop->value; + +for (i =0 ; i <ARRAY_SIZE (qe_firmware_info.vtraps); i++) + qe_firmware_info.vtraps[i] = iprop[i]; + }
And similarly?
Signature · 3 lines
Cheers, Stephen Rothwell [email protected] http://www.canb.auug.org.au/~sfr/
Quoted 3 lines · Stephen Rothwell
If you use:
for_each_child_of_node(qe, fw)
You don't need to initialise 'fw' in its declararion.
I can't find for_each_child_of_node. It's not in Kumar's for-2.6.25 branch.
Quoted 5 lines
Why not:
const u64 *iprop; int len; iprop = of_get_property(fs, "extended-modes", &len);
Ok.
Signature · 2 lines
Timur Tabi Linux kernel developer at Freescale
Quoted 7 lines · On Tue, 08 Jan 2008 09:26:27 -0600 Timur Tabi <[email protected]> wrote:
Quoted 3 lines · Stephen Rothwell
If you use:
for_each_child_of_node(qe, fw)
You don't need to initialise 'fw' in its declararion.I can't find
for_each_child_of_node. It's not in Kumar's for-2.6.25 branch.
include/linux/of.h
josh
Quoted 7 lines · Stephen Rothwell
Why not:
const u64 *iprop; int len; iprop = of_get_property(fs, "extended-modes", &len); if (iprop && (len == sizeof(u64)) qe_firmware_info.extended_modes = *iprop;
Actually, I like my way better, because then I don't have to define 'len', and I don't have to define two integer property variables one for u32 and one for u64.
Besides, now that I'm at version 6, I'd rather not post updates for minor
stylistic changes.
Signature · 2 lines
Timur Tabi Linux kernel developer at Freescale