From 1f5056275a6c026f308ac6f7ae52125c390d1d7c Mon Sep 17 00:00:00 2001 From: Alejandro Mery Date: Sat, 29 Sep 2012 12:49:47 +0200 Subject: [PATCH 01/14] pio: add missing copyright note and remove unused macro --- pio.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/pio.c b/pio.c index 8a39ee7..94bd005 100644 --- a/pio.c +++ b/pio.c @@ -1,3 +1,22 @@ +/* + * (C) Copyright 2011 Henrik Nordstrom + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + /* needs _BSD_SOURCE for htole and letoh */ #define _BSD_SOURCE @@ -14,8 +33,6 @@ #define PIO_REG_SIZE 0x228 /*0x300*/ #define PIO_PORT_SIZE 0x24 -#define errf(...) fprintf(stderr, __VA_ARGS__) - struct pio_status { int mul_sel; int pull; From bae6b6a93a7651608bd6a43ba35a2770509fbc21 Mon Sep 17 00:00:00 2001 From: Alejandro Mery Date: Sat, 29 Sep 2012 16:48:42 +0200 Subject: [PATCH 02/14] script: add script_find_section() helper --- script.c | 20 ++++++++++++++++++++ script.h | 4 ++++ 2 files changed, 24 insertions(+) diff --git a/script.c b/script.c index 3950470..b48ab48 100644 --- a/script.c +++ b/script.c @@ -90,6 +90,26 @@ void script_section_delete(struct script_section *section) list_remove(§ion->sections); } +struct script_section *script_find_section(struct script *script, + const char *name) +{ + struct list_entry *o; + struct script_section *section; + + assert(script); + assert(name); + + for (o = list_first(&script->sections); o; + o = list_next(&script->sections, o)) { + section = container_of(o, struct script_section, sections); + + if (strcmp(section->name, name) == 0) + return section; + } + + return NULL; +} + /* */ static inline void script_entry_append(struct script_section *section, diff --git a/script.h b/script.h index 1f7f199..aa14ecf 100644 --- a/script.h +++ b/script.h @@ -86,6 +86,10 @@ struct script_section *script_section_new(struct script *script, /** deletes a section recursvely and removes it from the script */ void script_section_delete(struct script_section *section); +/** find existing section */ +struct script_section *script_find_section(struct script *section, + const char *name); + /** deletes an entry and removes it from the section */ void script_entry_delete(struct script_entry *entry); From 987a169b75e9af25f7a8ef3a08bca173cda241be Mon Sep 17 00:00:00 2001 From: Alejandro Mery Date: Sat, 29 Sep 2012 18:42:17 +0200 Subject: [PATCH 03/14] fexc: add `uboot` output --- Makefile | 1 + fexc.c | 38 +++++++++++------ fexc.h | 1 + script_uboot.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++ script_uboot.h | 22 ++++++++++ 5 files changed, 157 insertions(+), 13 deletions(-) create mode 100644 script_uboot.c create mode 100644 script_uboot.h diff --git a/Makefile b/Makefile index 433f6f5..49a0660 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,7 @@ fex2bin bin2fex: fexc ln -s $< $@ fexc: fexc.h script.h script.c \ + script_uboot.h script_uboot.c \ script_bin.h script_bin.c \ script_fex.h script_fex.c diff --git a/fexc.c b/fexc.c index 3306cd0..c325735 100644 --- a/fexc.c +++ b/fexc.c @@ -32,6 +32,7 @@ enum script_format { FEX_SCRIPT_FORMAT, BIN_SCRIPT_FORMAT, + UBOOT_HEADER_FORMAT, }; /* @@ -145,6 +146,8 @@ static inline int script_parse(enum script_format format, bin_close: close(in); }; break; + case UBOOT_HEADER_FORMAT: /* not valid input */ + ; } return ret; } @@ -153,21 +156,24 @@ static inline int script_generate(enum script_format format, struct script *script) { int ret = 0; - switch (format) { - case FEX_SCRIPT_FORMAT: { + static int (*text_gen[3]) (FILE *, const char *, struct script *) = { + [FEX_SCRIPT_FORMAT] = script_generate_fex, + [UBOOT_HEADER_FORMAT] = script_generate_uboot, + }; + + if (text_gen[format]) { FILE *out = stdout; if (!filename) filename = ""; else if ((out = fopen(filename, "w")) == NULL) { pr_err("%s: %s\n", filename, strerror(errno)); - break; + goto done; } - ret = script_generate_fex(out, filename, script); + ret = text_gen[format](out, filename, script); fclose(out); - }; break; - case BIN_SCRIPT_FORMAT: { + } else { int out = 1; /* stdout */ size_t sections, entries, bin_size; void *bin; @@ -176,7 +182,7 @@ static inline int script_generate(enum script_format format, filename = ""; else if ((out = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) { pr_err("%s: %s\n", filename, strerror(errno)); - break; + goto done; } bin_size = script_bin_size(script, §ions, &entries); @@ -201,8 +207,8 @@ static inline int script_generate(enum script_format format, } free(bin); close(out); - }; break; } +done: return ret; } @@ -215,7 +221,7 @@ static inline void app_usage(const char *arg0, int mode) if (mode == 0) fputs("\ninfmt: fex, bin (default:fex)" - "\noutfmt: fex, bin (default:bin)\n", + "\noutfmt: fex, bin, uboot (default:bin)\n", stderr); } @@ -234,7 +240,7 @@ static inline int app_choose_mode(char *arg0) */ int main(int argc, char *argv[]) { - static const char *formats[] = { "fex", "bin", NULL }; + static const char *formats[] = { "fex", "bin", "uboot", NULL }; enum script_format infmt=FEX_SCRIPT_FORMAT; enum script_format outfmt=BIN_SCRIPT_FORMAT; const char *filename[] = { NULL /*stdin*/, NULL /*stdout*/}; @@ -246,8 +252,10 @@ int main(int argc, char *argv[]) int opt, ret = 1; int verbose = 0; - if (app_mode == 2) /* bin2fex */ - infmt = 1, outfmt = 0; + if (app_mode == 2) { /* bin2fex */ + infmt = BIN_SCRIPT_FORMAT; + outfmt = FEX_SCRIPT_FORMAT; + } while ((opt = getopt(argc, argv, opt_string)) != -1) { switch (opt) { @@ -257,7 +265,11 @@ int main(int argc, char *argv[]) if (strcmp(*f, optarg) == 0) break; } - if (!formats[infmt]) { + switch (infmt) { + case FEX_SCRIPT_FORMAT: + case BIN_SCRIPT_FORMAT: + break; + default: errf("%s: invalid format -- \"%s\"\n", argv[0], optarg); goto show_usage; diff --git a/fexc.h b/fexc.h index 2b33395..c5b32a9 100644 --- a/fexc.h +++ b/fexc.h @@ -25,5 +25,6 @@ #include "script.h" #include "script_bin.h" #include "script_fex.h" +#include "script_uboot.h" #endif diff --git a/script_uboot.c b/script_uboot.c new file mode 100644 index 0000000..dee697a --- /dev/null +++ b/script_uboot.c @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2012 Alejandro Mery + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include "common.h" + +#include +#include +#include + +#include "script.h" +#include "script_uboot.h" + +#define pr_info(...) errf("fexc-uboot: " __VA_ARGS__) +#define pr_err(...) errf("E: fexc-uboot: " __VA_ARGS__) + +#ifdef DEBUG +#define pr_debug(...) errf("D: fexc-uboot: " __VA_ARGS__) +#else +#define pr_debug(...) +#endif + +static inline void out_dram_member(FILE *out, const char *key, uint32_t val) +{ + const char *fmt; + if (strncmp(key, "tpr", 3) == 0 || + strncmp(key, "emr", 3) == 0) + fmt = "\t.%s = %#x,\n"; + else + fmt = "\t.%s = %u,\n"; + + fprintf(out, fmt, key, val); +} + +static int generate_dram_struct(FILE *out, struct script_section *sp) +{ + struct list_entry *le; + struct script_entry *ep; + struct script_single_entry *val; + const char *key; + int ret = 1; + + fprintf(out, "struct dram_para para = {\n"); + for (le = list_first(&sp->entries); le; + le = list_next(&sp->entries, le)) { + ep = container_of(le, struct script_entry, entries); + + if (strncmp(ep->name, "dram_", 5) != 0) + goto invalid_field; + + key = ep->name + 5; + if (strcmp(key, "") == 0) + goto invalid_field; + else if (strcmp(key, "baseaddr") == 0) + continue; /* skip */ + else if (strcmp(key, "clk") == 0) + key = "clock"; + + switch (ep->type) { + case SCRIPT_VALUE_TYPE_SINGLE_WORD: + val = container_of(ep, struct script_single_entry, entry); + if (val->value > 0) + out_dram_member(out, key, val->value); + /* pass through */ + case SCRIPT_VALUE_TYPE_NULL: + continue; + default: +invalid_field: + pr_err("dram_para: %s: invalid field\n", ep->name); + ret = 0; + } + + } + fprintf(out, "};\n"); + return ret; +} + +int script_generate_uboot(FILE *out, const char *UNUSED(filename), + struct script *script) +{ + struct script_section *section; + const char *section_name; + + fprintf(out, "/* this file is generated, don't edit it yourself */\n\n"); + + section_name = "dram_para"; + section = script_find_section(script, section_name); + if (!section) + goto missing_section; + generate_dram_struct(out, section); + + return 1; +missing_section: + pr_err("%s: critical section missing", section_name); + return 0; +} diff --git a/script_uboot.h b/script_uboot.h new file mode 100644 index 0000000..abfca14 --- /dev/null +++ b/script_uboot.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2012 Alejandro Mery + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef _SUBXI_TOOLS_SCRIPT_UBOOT_H +#define _SUBXI_TOOLS_SCRIPT_UBOOT_H + +int script_generate_uboot(FILE *out, const char *filename, struct script *script); + +#endif From 2534af5d7750f3d3b29f5384a3a1f9b3968e5e8e Mon Sep 17 00:00:00 2001 From: Alejandro Mery Date: Sat, 29 Sep 2012 20:25:50 +0200 Subject: [PATCH 04/14] fexc: change uboot output to generate a .c --- script_uboot.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/script_uboot.c b/script_uboot.c index dee697a..87cd295 100644 --- a/script_uboot.c +++ b/script_uboot.c @@ -32,11 +32,10 @@ #define pr_debug(...) #endif -static inline void out_dram_member(FILE *out, const char *key, uint32_t val) +static inline void out_u32_member(FILE *out, const char *key, int hexa, uint32_t val) { const char *fmt; - if (strncmp(key, "tpr", 3) == 0 || - strncmp(key, "emr", 3) == 0) + if (hexa) fmt = "\t.%s = %#x,\n"; else fmt = "\t.%s = %u,\n"; @@ -44,15 +43,18 @@ static inline void out_dram_member(FILE *out, const char *key, uint32_t val) fprintf(out, fmt, key, val); } +/* + * DRAM + */ static int generate_dram_struct(FILE *out, struct script_section *sp) { struct list_entry *le; struct script_entry *ep; struct script_single_entry *val; const char *key; - int ret = 1; + int ret = 1, hexa; - fprintf(out, "struct dram_para para = {\n"); + fprintf(out, "static struct dram_para dram_para = {\n"); for (le = list_first(&sp->entries); le; le = list_next(&sp->entries, le)) { ep = container_of(le, struct script_entry, entries); @@ -68,11 +70,17 @@ static int generate_dram_struct(FILE *out, struct script_section *sp) else if (strcmp(key, "clk") == 0) key = "clock"; + if (strncmp(key, "tpr", 3) == 0 || + strncmp(key, "emr", 3) == 0) + hexa = 1; + else + hexa = 0; + switch (ep->type) { case SCRIPT_VALUE_TYPE_SINGLE_WORD: val = container_of(ep, struct script_single_entry, entry); if (val->value > 0) - out_dram_member(out, key, val->value); + out_u32_member(out, key, hexa, val->value); /* pass through */ case SCRIPT_VALUE_TYPE_NULL: continue; @@ -93,7 +101,10 @@ int script_generate_uboot(FILE *out, const char *UNUSED(filename), struct script_section *section; const char *section_name; - fprintf(out, "/* this file is generated, don't edit it yourself */\n\n"); + fputs("/* this file is generated, don't edit it yourself */\n\n" + "#include \n" + "#include \n\n", + out); section_name = "dram_para"; section = script_find_section(script, section_name); @@ -101,6 +112,10 @@ int script_generate_uboot(FILE *out, const char *UNUSED(filename), goto missing_section; generate_dram_struct(out, section); + fputs("\nint sunxi_dram_init(void)\n" + "{\n\treturn DRAMC_init(&dram_para);\n}\n", + out); + return 1; missing_section: pr_err("%s: critical section missing", section_name); From acf7f5d982bfa45b4fe0715e9133444847b44818 Mon Sep 17 00:00:00 2001 From: Alejandro Mery Date: Sat, 29 Sep 2012 20:57:31 +0200 Subject: [PATCH 05/14] fexc: uboot: turn .chip_density into .density --- script_uboot.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/script_uboot.c b/script_uboot.c index 87cd295..e8973fb 100644 --- a/script_uboot.c +++ b/script_uboot.c @@ -69,6 +69,8 @@ static int generate_dram_struct(FILE *out, struct script_section *sp) continue; /* skip */ else if (strcmp(key, "clk") == 0) key = "clock"; + else if (strcmp(key, "chip_density") == 0) + key = "density"; if (strncmp(key, "tpr", 3) == 0 || strncmp(key, "emr", 3) == 0) From 397e2613c6ba2ce935e5ee8dd47a833ba9b8c85c Mon Sep 17 00:00:00 2001 From: Alejandro Mery Date: Sat, 29 Sep 2012 23:53:22 +0200 Subject: [PATCH 06/14] fexc: uboot: starting pmu_para based on [target] --- script_uboot.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 4 deletions(-) diff --git a/script_uboot.c b/script_uboot.c index e8973fb..ff0c301 100644 --- a/script_uboot.c +++ b/script_uboot.c @@ -63,7 +63,7 @@ static int generate_dram_struct(FILE *out, struct script_section *sp) goto invalid_field; key = ep->name + 5; - if (strcmp(key, "") == 0) + if (key[0] == '\0') goto invalid_field; else if (strcmp(key, "baseaddr") == 0) continue; /* skip */ @@ -94,6 +94,46 @@ invalid_field: } fprintf(out, "};\n"); + fputs("\nint sunxi_dram_init(void)\n" + "{\n\treturn DRAMC_init(&dram_para);\n}\n", + out); + + return ret; +} + +/* + * PMU + */ +static int generate_pmu_struct(FILE *out, struct script_section *sp) +{ + struct list_entry *le; + struct script_entry *ep; + struct script_single_entry *val; + int ret = 1; + + fputs("\nstatic struct pmu_para pmu_para = {\n", out); + for (le = list_first(&sp->entries); le; + le = list_next(&sp->entries, le)) { + ep = container_of(le, struct script_entry, entries); + + switch (ep->type) { + case SCRIPT_VALUE_TYPE_SINGLE_WORD: + val = container_of(ep, struct script_single_entry, entry); + if (val->value > 0) + out_u32_member(out, ep->name, 0, val->value); + /* pass through */ + case SCRIPT_VALUE_TYPE_NULL: + continue; + default: + pr_err("pmu_para: %s: invalid field\n", ep->name); + ret = 0; + } + + } + fputs("};\n", out); + fputs("\nint sunxi_pmu_init(void)\n" + "{\n\treturn PMU_init(&pmu_para);\n}\n", + out); return ret; } @@ -105,6 +145,7 @@ int script_generate_uboot(FILE *out, const char *UNUSED(filename), fputs("/* this file is generated, don't edit it yourself */\n\n" "#include \n" + "#include \n" "#include \n\n", out); @@ -114,9 +155,11 @@ int script_generate_uboot(FILE *out, const char *UNUSED(filename), goto missing_section; generate_dram_struct(out, section); - fputs("\nint sunxi_dram_init(void)\n" - "{\n\treturn DRAMC_init(&dram_para);\n}\n", - out); + section_name = "target"; + section = script_find_section(script, section_name); + if (!section) + goto missing_section; + generate_pmu_struct(out, section); return 1; missing_section: From e5aaf6dd195f2c3c04f33c94168ab960ec074854 Mon Sep 17 00:00:00 2001 From: Alejandro Mery Date: Sun, 30 Sep 2012 23:45:49 +0200 Subject: [PATCH 07/14] fexc: uboot: check for [pmu_para] too --- script_uboot.c | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/script_uboot.c b/script_uboot.c index ff0c301..9333316 100644 --- a/script_uboot.c +++ b/script_uboot.c @@ -104,9 +104,11 @@ invalid_field: /* * PMU */ -static int generate_pmu_struct(FILE *out, struct script_section *sp) +static int generate_pmu_struct(FILE *out, struct script_section *target, + struct script_section *pmu_para) { struct list_entry *le; + struct script_section *sp = target; struct script_entry *ep; struct script_single_entry *val; int ret = 1; @@ -135,13 +137,34 @@ static int generate_pmu_struct(FILE *out, struct script_section *sp) "{\n\treturn PMU_init(&pmu_para);\n}\n", out); return ret; + + (void) pmu_para; } int script_generate_uboot(FILE *out, const char *UNUSED(filename), struct script *script) { - struct script_section *section; - const char *section_name; + struct { + const char *name; + struct script_section *sp; + } sections[] = { + { "dram_para", NULL }, + { "target", NULL }, + { "pmu_para", NULL }, + }; + + for (unsigned i=0; i\n" @@ -149,20 +172,8 @@ int script_generate_uboot(FILE *out, const char *UNUSED(filename), "#include \n\n", out); - section_name = "dram_para"; - section = script_find_section(script, section_name); - if (!section) - goto missing_section; - generate_dram_struct(out, section); - - section_name = "target"; - section = script_find_section(script, section_name); - if (!section) - goto missing_section; - generate_pmu_struct(out, section); + generate_dram_struct(out, sections[0].sp); + generate_pmu_struct(out, sections[1].sp, sections[2].sp); return 1; -missing_section: - pr_err("%s: critical section missing", section_name); - return 0; } From 9abafdf6ad5933e48e74b330073011d273a99e33 Mon Sep 17 00:00:00 2001 From: Alejandro Mery Date: Mon, 1 Oct 2012 00:21:05 +0200 Subject: [PATCH 08/14] fexc: uboot: add certain entries of [pmu_para] to struct pmu_para --- script_uboot.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/script_uboot.c b/script_uboot.c index 9333316..cd6805d 100644 --- a/script_uboot.c +++ b/script_uboot.c @@ -43,6 +43,26 @@ static inline void out_u32_member(FILE *out, const char *key, int hexa, uint32_t fprintf(out, fmt, key, val); } +static inline void out_gpio_member(FILE *out, const char *key, + struct script_gpio_entry *gpio) +{ + fprintf(out, "\t.%s = ", key); + + if (gpio->port == 0xffff) + fprintf(out, "GPIO_AXP_CFG(%u", gpio->port_num); + else + fprintf(out, "GPIO_CFG(%u, %u", gpio->port, gpio->port_num); + + for (const int *p = gpio->data, *pe = p+4; p != pe; p++) { + if (*p == -1) + fputs(", 0xff", out); + else + fprintf(out, ", %u", *p); + } + + fputs("),\n", out); +} + /* * DRAM */ @@ -108,12 +128,15 @@ static int generate_pmu_struct(FILE *out, struct script_section *target, struct script_section *pmu_para) { struct list_entry *le; - struct script_section *sp = target; + struct script_section *sp; struct script_entry *ep; struct script_single_entry *val; + const char *key; int ret = 1; fputs("\nstatic struct pmu_para pmu_para = {\n", out); + + sp = target; for (le = list_first(&sp->entries); le; le = list_next(&sp->entries, le)) { ep = container_of(le, struct script_entry, entries); @@ -127,11 +150,46 @@ static int generate_pmu_struct(FILE *out, struct script_section *target, case SCRIPT_VALUE_TYPE_NULL: continue; default: - pr_err("pmu_para: %s: invalid field\n", ep->name); + pr_err("target: %s: invalid field\n", ep->name); ret = 0; } } + + sp = pmu_para; + for (le = list_first(&sp->entries); le; + le = list_next(&sp->entries, le)) { + ep = container_of(le, struct script_entry, entries); + + if (strncmp(ep->name, "pmu_", 4) != 0) + continue; + key = ep->name+4; + + if (strcmp(key, "used2") == 0 || + strcmp(key, "para") == 0 || + strcmp(key, "adpdet") == 0 || + strcmp(key, "shutdown_chgcur") == 0 || + strcmp(key, "shutdown_chgcur2") == 0 || + strcmp(key, "pwroff_vol") == 0 || + strcmp(key, "pwron_vol") == 0) { + + switch(ep->type) { + case SCRIPT_VALUE_TYPE_SINGLE_WORD: + val = container_of(ep, struct script_single_entry, entry); + out_u32_member(out, key, 0, val->value); + break; + case SCRIPT_VALUE_TYPE_NULL: + break; + case SCRIPT_VALUE_TYPE_GPIO: + out_gpio_member(out, key, + container_of(ep, struct script_gpio_entry, entry)); + break; + default: + pr_err("pmu_para: %s: invalid field\n", ep->name); + } + } + } + fputs("};\n", out); fputs("\nint sunxi_pmu_init(void)\n" "{\n\treturn PMU_init(&pmu_para);\n}\n", From bf4e4996d2d26b68beb8c208964ea5a619e5a71e Mon Sep 17 00:00:00 2001 From: Alejandro Mery Date: Mon, 1 Oct 2012 00:32:12 +0200 Subject: [PATCH 09/14] fexc: uboot: some refactoring --- script_uboot.c | 46 ++++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/script_uboot.c b/script_uboot.c index cd6805d..17a8c8b 100644 --- a/script_uboot.c +++ b/script_uboot.c @@ -32,7 +32,8 @@ #define pr_debug(...) #endif -static inline void out_u32_member(FILE *out, const char *key, int hexa, uint32_t val) +static inline void out_u32_member(FILE *out, const char *key, int hexa, + struct script_single_entry *val) { const char *fmt; if (hexa) @@ -40,7 +41,7 @@ static inline void out_u32_member(FILE *out, const char *key, int hexa, uint32_t else fmt = "\t.%s = %u,\n"; - fprintf(out, fmt, key, val); + fprintf(out, fmt, key, val->value); } static inline void out_gpio_member(FILE *out, const char *key, @@ -63,6 +64,11 @@ static inline void out_gpio_member(FILE *out, const char *key, fputs("),\n", out); } +static inline void out_null_member(FILE *out, const char *key) +{ + fprintf(out, "\t/* %s is NULL */\n", key); +} + /* * DRAM */ @@ -70,7 +76,6 @@ static int generate_dram_struct(FILE *out, struct script_section *sp) { struct list_entry *le; struct script_entry *ep; - struct script_single_entry *val; const char *key; int ret = 1, hexa; @@ -100,12 +105,15 @@ static int generate_dram_struct(FILE *out, struct script_section *sp) switch (ep->type) { case SCRIPT_VALUE_TYPE_SINGLE_WORD: - val = container_of(ep, struct script_single_entry, entry); - if (val->value > 0) - out_u32_member(out, key, hexa, val->value); - /* pass through */ + out_u32_member(out, key, hexa, + container_of(ep, struct script_single_entry, entry)); + break; case SCRIPT_VALUE_TYPE_NULL: - continue; + out_null_member(out, key); + break; + case SCRIPT_VALUE_TYPE_GPIO: + out_gpio_member(out, key, + container_of(ep, struct script_gpio_entry, entry)); default: invalid_field: pr_err("dram_para: %s: invalid field\n", ep->name); @@ -130,7 +138,6 @@ static int generate_pmu_struct(FILE *out, struct script_section *target, struct list_entry *le; struct script_section *sp; struct script_entry *ep; - struct script_single_entry *val; const char *key; int ret = 1; @@ -141,14 +148,20 @@ static int generate_pmu_struct(FILE *out, struct script_section *target, le = list_next(&sp->entries, le)) { ep = container_of(le, struct script_entry, entries); + key = ep->name; + switch (ep->type) { case SCRIPT_VALUE_TYPE_SINGLE_WORD: - val = container_of(ep, struct script_single_entry, entry); - if (val->value > 0) - out_u32_member(out, ep->name, 0, val->value); - /* pass through */ + out_u32_member(out, key, 0, + container_of(ep, struct script_single_entry, entry)); + break; case SCRIPT_VALUE_TYPE_NULL: - continue; + out_null_member(out, key); + break; + case SCRIPT_VALUE_TYPE_GPIO: + out_gpio_member(out, key, + container_of(ep, struct script_gpio_entry, entry)); + break; default: pr_err("target: %s: invalid field\n", ep->name); ret = 0; @@ -175,10 +188,11 @@ static int generate_pmu_struct(FILE *out, struct script_section *target, switch(ep->type) { case SCRIPT_VALUE_TYPE_SINGLE_WORD: - val = container_of(ep, struct script_single_entry, entry); - out_u32_member(out, key, 0, val->value); + out_u32_member(out, key, 0, + container_of(ep, struct script_single_entry, entry)); break; case SCRIPT_VALUE_TYPE_NULL: + out_null_member(out, key); break; case SCRIPT_VALUE_TYPE_GPIO: out_gpio_member(out, key, From d08be28bfa2ff5aedce2785ea65eefa67f0b7f27 Mon Sep 17 00:00:00 2001 From: Alejandro Mery Date: Mon, 1 Oct 2012 00:44:37 +0200 Subject: [PATCH 10/14] fexc: uboot: and some more refactoring --- script_uboot.c | 66 +++++++++++++++++++------------------------------- 1 file changed, 25 insertions(+), 41 deletions(-) diff --git a/script_uboot.c b/script_uboot.c index 17a8c8b..1b16cba 100644 --- a/script_uboot.c +++ b/script_uboot.c @@ -69,6 +69,27 @@ static inline void out_null_member(FILE *out, const char *key) fprintf(out, "\t/* %s is NULL */\n", key); } +static inline int out_member(FILE *out, const char *key, int mode, + struct script_entry *ep) +{ + switch (ep->type) { + case SCRIPT_VALUE_TYPE_SINGLE_WORD: + out_u32_member(out, key, mode, + container_of(ep, struct script_single_entry, entry)); + break; + case SCRIPT_VALUE_TYPE_NULL: + out_null_member(out, key); + break; + case SCRIPT_VALUE_TYPE_GPIO: + out_gpio_member(out, key, + container_of(ep, struct script_gpio_entry, entry)); + break; + default: + return 0; + } + return 1; +} + /* * DRAM */ @@ -103,18 +124,7 @@ static int generate_dram_struct(FILE *out, struct script_section *sp) else hexa = 0; - switch (ep->type) { - case SCRIPT_VALUE_TYPE_SINGLE_WORD: - out_u32_member(out, key, hexa, - container_of(ep, struct script_single_entry, entry)); - break; - case SCRIPT_VALUE_TYPE_NULL: - out_null_member(out, key); - break; - case SCRIPT_VALUE_TYPE_GPIO: - out_gpio_member(out, key, - container_of(ep, struct script_gpio_entry, entry)); - default: + if (!out_member(out, key, hexa, ep)) { invalid_field: pr_err("dram_para: %s: invalid field\n", ep->name); ret = 0; @@ -148,25 +158,10 @@ static int generate_pmu_struct(FILE *out, struct script_section *target, le = list_next(&sp->entries, le)) { ep = container_of(le, struct script_entry, entries); - key = ep->name; - - switch (ep->type) { - case SCRIPT_VALUE_TYPE_SINGLE_WORD: - out_u32_member(out, key, 0, - container_of(ep, struct script_single_entry, entry)); - break; - case SCRIPT_VALUE_TYPE_NULL: - out_null_member(out, key); - break; - case SCRIPT_VALUE_TYPE_GPIO: - out_gpio_member(out, key, - container_of(ep, struct script_gpio_entry, entry)); - break; - default: + if (!out_member(out, ep->name, 0, ep)) { pr_err("target: %s: invalid field\n", ep->name); ret = 0; } - } sp = pmu_para; @@ -186,20 +181,9 @@ static int generate_pmu_struct(FILE *out, struct script_section *target, strcmp(key, "pwroff_vol") == 0 || strcmp(key, "pwron_vol") == 0) { - switch(ep->type) { - case SCRIPT_VALUE_TYPE_SINGLE_WORD: - out_u32_member(out, key, 0, - container_of(ep, struct script_single_entry, entry)); - break; - case SCRIPT_VALUE_TYPE_NULL: - out_null_member(out, key); - break; - case SCRIPT_VALUE_TYPE_GPIO: - out_gpio_member(out, key, - container_of(ep, struct script_gpio_entry, entry)); - break; - default: + if (!out_member(out, key, 0, ep)) { pr_err("pmu_para: %s: invalid field\n", ep->name); + ret = 0; } } } From a9b99916301a6299d81f20e194df83826e0dfdb6 Mon Sep 17 00:00:00 2001 From: Alejandro Mery Date: Mon, 1 Oct 2012 10:34:56 +0200 Subject: [PATCH 11/14] fexc: script: add script_find_entry() helper --- script.c | 20 ++++++++++++++++++++ script.h | 5 ++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/script.c b/script.c index b48ab48..3a9c7e7 100644 --- a/script.c +++ b/script.c @@ -246,3 +246,23 @@ struct script_gpio_entry *script_gpio_entry_new(struct script_section *section, return entry; } + +struct script_entry *script_find_entry(struct script_section *section, + const char *name) +{ + struct list_entry *o; + struct script_entry *ep; + + assert(section); + assert(name); + + for (o = list_first(§ion->entries); o; + o = list_next(§ion->entries, o)) { + ep = container_of(o, struct script_entry, entries); + + if (strcmp(ep->name, name) == 0) + return ep; + } + + return NULL; +} diff --git a/script.h b/script.h index aa14ecf..0fa2134 100644 --- a/script.h +++ b/script.h @@ -87,7 +87,7 @@ struct script_section *script_section_new(struct script *script, void script_section_delete(struct script_section *section); /** find existing section */ -struct script_section *script_find_section(struct script *section, +struct script_section *script_find_section(struct script *script, const char *name); /** deletes an entry and removes it from the section */ @@ -110,4 +110,7 @@ struct script_gpio_entry *script_gpio_entry_new(struct script_section *script, unsigned port, unsigned num, int32_t data[4]); +/** find existing entry in a giving section */ +struct script_entry *script_find_entry(struct script_section *section, + const char *name); #endif From fe73a3794510994cedbc45e0283409c19f3bfe29 Mon Sep 17 00:00:00 2001 From: Alejandro Mery Date: Mon, 1 Oct 2012 10:35:48 +0200 Subject: [PATCH 12/14] fexc: uboot: ensure data from [pmu_para] is print in order --- script_uboot.c | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/script_uboot.c b/script_uboot.c index 1b16cba..079355c 100644 --- a/script_uboot.c +++ b/script_uboot.c @@ -32,6 +32,14 @@ #define pr_debug(...) #endif +struct members { + const char *name; + const char *translation; + int mode; +}; + +/* + */ static inline void out_u32_member(FILE *out, const char *key, int hexa, struct script_single_entry *val) { @@ -142,6 +150,16 @@ invalid_field: /* * PMU */ +static struct members pmu_members[] = { + { .name = "pmu_used2" }, + { .name = "pmu_para" }, + { .name = "pmu_adpdet" }, + { .name = "pmu_shutdown_chgcur" }, + { .name = "pmu_shutdown_chgcur2" }, + { .name = "pmu_pwroff_vol" }, + { .name = "pmu_pwron_vol" }, +}; + static int generate_pmu_struct(FILE *out, struct script_section *target, struct script_section *pmu_para) { @@ -164,27 +182,16 @@ static int generate_pmu_struct(FILE *out, struct script_section *target, } } - sp = pmu_para; - for (le = list_first(&sp->entries); le; - le = list_next(&sp->entries, le)) { - ep = container_of(le, struct script_entry, entries); - - if (strncmp(ep->name, "pmu_", 4) != 0) + for (const struct members *mp = pmu_members; + mp < pmu_members+ARRAY_SIZE(pmu_members); mp++) { + ep = script_find_entry(pmu_para, mp->name); + if (!ep) continue; - key = ep->name+4; - if (strcmp(key, "used2") == 0 || - strcmp(key, "para") == 0 || - strcmp(key, "adpdet") == 0 || - strcmp(key, "shutdown_chgcur") == 0 || - strcmp(key, "shutdown_chgcur2") == 0 || - strcmp(key, "pwroff_vol") == 0 || - strcmp(key, "pwron_vol") == 0) { - - if (!out_member(out, key, 0, ep)) { - pr_err("pmu_para: %s: invalid field\n", ep->name); - ret = 0; - } + key = (mp->translation) ? mp->translation : mp->name+4; + if (!out_member(out, key, mp->mode, ep)) { + pr_err("pmu_para: %s: invalid field\n", mp->name); + ret = 0; } } From 1ebf8d8e4bfeec1c1f3ec22e03b71353a2487b22 Mon Sep 17 00:00:00 2001 From: Alejandro Mery Date: Mon, 1 Oct 2012 10:56:20 +0200 Subject: [PATCH 13/14] fexc: uboot: use a table for dram_para too --- script_uboot.c | 58 ++++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/script_uboot.c b/script_uboot.c index 079355c..8d5a8ff 100644 --- a/script_uboot.c +++ b/script_uboot.c @@ -101,39 +101,45 @@ static inline int out_member(FILE *out, const char *key, int mode, /* * DRAM */ +static struct members dram_members[] = { + { .name="dram_clock" }, + { .name="dram_clk", .translation="clock" }, + { .name="dram_type" }, + { .name="dram_rank_num" }, + { .name="dram_density" }, + { .name="dram_chip_density", .translation="density" }, + { .name="dram_io_width" }, + { .name="dram_bus_width" }, + { .name="dram_cas" }, + { .name="dram_zq" }, + { .name="dram_odt_en" }, + { .name="dram_size" }, + { .name="dram_tpr0", .mode=1 }, + { .name="dram_tpr1", .mode=1 }, + { .name="dram_tpr2", .mode=1 }, + { .name="dram_tpr3", .mode=1 }, + { .name="dram_tpr4", .mode=1 }, + { .name="dram_tpr5", .mode=1 }, + { .name="dram_emr1", .mode=1 }, + { .name="dram_emr2", .mode=1 }, + { .name="dram_emr3", .mode=1 }, +}; + static int generate_dram_struct(FILE *out, struct script_section *sp) { - struct list_entry *le; struct script_entry *ep; const char *key; - int ret = 1, hexa; + int ret = 1; fprintf(out, "static struct dram_para dram_para = {\n"); - for (le = list_first(&sp->entries); le; - le = list_next(&sp->entries, le)) { - ep = container_of(le, struct script_entry, entries); + for (const struct members *mp = dram_members; + mp < dram_members+ARRAY_SIZE(dram_members); mp++) { + ep = script_find_entry(sp, mp->name); + if (!ep) + continue; - if (strncmp(ep->name, "dram_", 5) != 0) - goto invalid_field; - - key = ep->name + 5; - if (key[0] == '\0') - goto invalid_field; - else if (strcmp(key, "baseaddr") == 0) - continue; /* skip */ - else if (strcmp(key, "clk") == 0) - key = "clock"; - else if (strcmp(key, "chip_density") == 0) - key = "density"; - - if (strncmp(key, "tpr", 3) == 0 || - strncmp(key, "emr", 3) == 0) - hexa = 1; - else - hexa = 0; - - if (!out_member(out, key, hexa, ep)) { -invalid_field: + key = (mp->translation) ? mp->translation : mp->name+5; + if (!out_member(out, key, mp->mode, ep)) { pr_err("dram_para: %s: invalid field\n", ep->name); ret = 0; } From 35612471af30c2daeb8ccb3b42041d040517b57f Mon Sep 17 00:00:00 2001 From: Alejandro Mery Date: Mon, 1 Oct 2012 11:20:48 +0200 Subject: [PATCH 14/14] fexc: uboot: add iterator macro for struct members --- script_uboot.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/script_uboot.c b/script_uboot.c index 8d5a8ff..304c3a2 100644 --- a/script_uboot.c +++ b/script_uboot.c @@ -37,6 +37,8 @@ struct members { const char *translation; int mode; }; +#define foreach_member(I, T) for (const struct members *I = T; \ + I < T+ARRAY_SIZE(T); I++) /* */ @@ -132,8 +134,7 @@ static int generate_dram_struct(FILE *out, struct script_section *sp) int ret = 1; fprintf(out, "static struct dram_para dram_para = {\n"); - for (const struct members *mp = dram_members; - mp < dram_members+ARRAY_SIZE(dram_members); mp++) { + foreach_member(mp, dram_members) { ep = script_find_entry(sp, mp->name); if (!ep) continue; @@ -188,8 +189,7 @@ static int generate_pmu_struct(FILE *out, struct script_section *target, } } - for (const struct members *mp = pmu_members; - mp < pmu_members+ARRAY_SIZE(pmu_members); mp++) { + foreach_member(mp, pmu_members) { ep = script_find_entry(pmu_para, mp->name); if (!ep) continue;