Commit a3c454e1 authored by Benjamin Herrenschmidt's avatar Benjamin Herrenschmidt Committed by Linus Torvalds

[PATCH] ppc64: Let OF initialize all displays in the system

This patch reworks the early boot calls to OF to initialize displays.

All present displays are now initialized in reverse order so the
OF console stays on the first one. Initializing them all is necessary
for dual head configurations as we need OF driver to properly setup
the secondary TMDS of the video card, XFree isn't able to do that
currently
parent 8661a5ff
...@@ -130,6 +130,7 @@ static interpret_func interpret_macio_props; ...@@ -130,6 +130,7 @@ static interpret_func interpret_macio_props;
struct prom_t prom; struct prom_t prom;
char *prom_display_paths[FB_MAX] __initdata = { 0, }; char *prom_display_paths[FB_MAX] __initdata = { 0, };
phandle prom_display_nodes[FB_MAX] __initdata;
unsigned int prom_num_displays = 0; unsigned int prom_num_displays = 0;
char *of_stdout_device = 0; char *of_stdout_device = 0;
...@@ -177,7 +178,7 @@ void prom_dump_lmb(void); ...@@ -177,7 +178,7 @@ void prom_dump_lmb(void);
extern unsigned long reloc_offset(void); extern unsigned long reloc_offset(void);
extern void enter_prom(void *dummy,...); extern void enter_prom(struct prom_args *args);
extern void copy_and_flush(unsigned long dest, unsigned long src, extern void copy_and_flush(unsigned long dest, unsigned long src,
unsigned long size, unsigned long offset); unsigned long size, unsigned long offset);
...@@ -1500,13 +1501,12 @@ prom_init(unsigned long r3, unsigned long r4, unsigned long pp, ...@@ -1500,13 +1501,12 @@ prom_init(unsigned long r3, unsigned long r4, unsigned long pp,
/* Default machine type. */ /* Default machine type. */
_systemcfg->platform = prom_find_machine_type(); _systemcfg->platform = prom_find_machine_type();
/* On pSeries, copy the CPU hold code */ /* On pSeries, copy the CPU hold code */
if (_systemcfg->platform == PLATFORM_PSERIES) if (_systemcfg->platform == PLATFORM_PSERIES)
copy_and_flush(0, KERNELBASE - offset, 0x100, 0); copy_and_flush(0, KERNELBASE - offset, 0x100, 0);
/* Start storing things at klimit */ /* Start storing things at klimit */
mem = RELOC(klimit) - offset; mem = RELOC(klimit) - offset;
/* Get the full OF pathname of the stdout device */ /* Get the full OF pathname of the stdout device */
p = (char *) mem; p = (char *) mem;
...@@ -1646,10 +1646,10 @@ check_display(unsigned long mem) ...@@ -1646,10 +1646,10 @@ check_display(unsigned long mem)
{ {
phandle node; phandle node;
ihandle ih; ihandle ih;
int i; int i, j;
unsigned long offset = reloc_offset(); unsigned long offset = reloc_offset();
struct prom_t *_prom = PTRRELOC(&prom); struct prom_t *_prom = PTRRELOC(&prom);
char type[64], *path; char type[16], *path;
static unsigned char default_colors[] = { static unsigned char default_colors[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xaa, 0x00, 0x00, 0xaa,
...@@ -1672,6 +1672,12 @@ check_display(unsigned long mem) ...@@ -1672,6 +1672,12 @@ check_display(unsigned long mem)
_prom->disp_node = 0; _prom->disp_node = 0;
prom_print(RELOC("Looking for displays\n"));
if (RELOC(of_stdout_device) != 0) {
prom_print(RELOC("OF stdout is : "));
prom_print(PTRRELOC(RELOC(of_stdout_device)));
prom_print(RELOC("\n"));
}
for (node = 0; prom_next_node(&node); ) { for (node = 0; prom_next_node(&node); ) {
type[0] = 0; type[0] = 0;
call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"), call_prom(RELOC("getprop"), 4, 1, node, RELOC("device_type"),
...@@ -1682,19 +1688,48 @@ check_display(unsigned long mem) ...@@ -1682,19 +1688,48 @@ check_display(unsigned long mem)
path = (char *) mem; path = (char *) mem;
memset(path, 0, 256); memset(path, 0, 256);
if ((long) call_prom(RELOC("package-to-path"), 3, 1, if ((long) call_prom(RELOC("package-to-path"), 3, 1,
node, path, 255) < 0) node, path, 250) < 0)
continue; continue;
prom_print(RELOC("opening display ")); prom_print(RELOC("found display : "));
prom_print(path);
prom_print(RELOC("\n"));
/*
* If this display is the device that OF is using for stdout,
* move it to the front of the list.
*/
mem += strlen(path) + 1;
i = RELOC(prom_num_displays);
RELOC(prom_num_displays) = i + 1;
if (RELOC(of_stdout_device) != 0 && i > 0
&& strcmp(PTRRELOC(RELOC(of_stdout_device)), path) == 0) {
for (; i > 0; --i) {
RELOC(prom_display_paths[i])
= RELOC(prom_display_paths[i-1]);
RELOC(prom_display_nodes[i])
= RELOC(prom_display_nodes[i-1]);
}
_prom->disp_node = (ihandle)(unsigned long)node;
}
RELOC(prom_display_paths[i]) = PTRUNRELOC(path);
RELOC(prom_display_nodes[i]) = node;
if (_prom->disp_node == 0)
_prom->disp_node = (ihandle)(unsigned long)node;
if (RELOC(prom_num_displays) >= FB_MAX)
break;
}
prom_print(RELOC("Opening displays...\n"));
for (j = RELOC(prom_num_displays) - 1; j >= 0; j--) {
path = PTRRELOC(RELOC(prom_display_paths[j]));
prom_print(RELOC("opening display : "));
prom_print(path); prom_print(path);
ih = (ihandle)call_prom(RELOC("open"), 1, 1, path); ih = (ihandle)call_prom(RELOC("open"), 1, 1, path);
if (ih == (ihandle)0 || ih == (ihandle)-1) { if (ih == (ihandle)0 || ih == (ihandle)-1) {
prom_print(RELOC("... failed\n")); prom_print(RELOC("... failed\n"));
continue; continue;
} }
prom_print(RELOC("... ok\n"));
if (_prom->disp_node == 0) prom_print(RELOC("... ok\n"));
_prom->disp_node = (ihandle)(unsigned long)node;
/* Setup a useable color table when the appropriate /* Setup a useable color table when the appropriate
* method is available. Should update this to set-colors */ * method is available. Should update this to set-colors */
...@@ -1711,26 +1746,8 @@ check_display(unsigned long mem) ...@@ -1711,26 +1746,8 @@ check_display(unsigned long mem)
clut[2]) != 0) clut[2]) != 0)
break; break;
#endif /* CONFIG_LOGO_LINUX_CLUT224 */ #endif /* CONFIG_LOGO_LINUX_CLUT224 */
/*
* If this display is the device that OF is using for stdout,
* move it to the front of the list.
*/
mem += strlen(path) + 1;
i = RELOC(prom_num_displays)++;
if (RELOC(of_stdout_device) != 0 && i > 0
&& strcmp(PTRRELOC(RELOC(of_stdout_device)), path) == 0) {
for (; i > 0; --i)
RELOC(prom_display_paths[i]) = RELOC(prom_display_paths[i-1]);
}
RELOC(prom_display_paths[i]) = PTRUNRELOC(path);
if (RELOC(prom_num_displays) >= FB_MAX)
break;
/* XXX Temporary workaround: only open the first display so we don't
* lose debug output
*/
break;
} }
return DOUBLEWORD_ALIGN(mem); return DOUBLEWORD_ALIGN(mem);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment