dcp/afk: Retry harder to init afk endpoints/services

Extend start_interface() with the number of expected services so it can
stop when all services are initialized.

Fixes failed display init on some devices in stage 1 due to a too slow
IOP which does not manage to send service announce messages in 20
mailbox / ringbuffer query operations.

Proper fix for this is to let the endpoint implementations drive the
initialization via afk_epic_work() until the expected services are
found.

Signed-off-by: Janne Grunau <j@jannau.net>
This commit is contained in:
Janne Grunau 2023-10-12 22:29:51 +02:00 committed by Hector Martin
parent 1ea734296a
commit 9a277fadc9
6 changed files with 35 additions and 21 deletions

View file

@ -705,9 +705,10 @@ static const afk_epic_service_ops_t *afk_match_service(afk_epic_ep_t *ep, const
return NULL;
}
int afk_epic_start_interface(afk_epic_ep_t *epic, void *intf, size_t txsize, size_t rxsize)
int afk_epic_start_interface(afk_epic_ep_t *epic, void *intf, int expected, size_t txsize,
size_t rxsize)
{
int channels = 0;
int services = 0;
struct afk_qe *msg;
struct epic_announce *announce;
@ -721,7 +722,7 @@ int afk_epic_start_interface(afk_epic_ep_t *epic, void *intf, size_t txsize, siz
break;
}
for (int tries = 0; tries < 20; tries += 1) {
for (int tries = 0; tries < 500; tries += 1) {
s64 epic_unit = -1;
char *epic_name = NULL;
char *epic_class = NULL;
@ -810,11 +811,12 @@ int afk_epic_start_interface(afk_epic_ep_t *epic, void *intf, size_t txsize, siz
free(epic_name);
free(epic_class);
channels++;
afk_epic_rx_ack(epic);
if (++services >= expected)
break;
}
if (!channels) {
if (!services) {
printf("AFK[ep:%02x]: too many unexpected messages, giving up\n", epic->ep);
return -1;
}
@ -829,7 +831,7 @@ int afk_epic_start_interface(afk_epic_ep_t *epic, void *intf, size_t txsize, siz
return -1;
}
dprintf("AFK[ep:%02x]: started interface with %d services\n", epic->ep, channels);
dprintf("AFK[ep:%02x]: started interface with %d services\n", epic->ep, services);
return 0;
}

View file

@ -43,7 +43,8 @@ afk_epic_ep_t *afk_epic_start_ep(afk_epic_t *afk, int endpoint, const afk_epic_s
int afk_epic_shutdown_ep(afk_epic_ep_t *epic);
int afk_epic_work(afk_epic_t *afk, int endpoint);
int afk_epic_start_interface(afk_epic_ep_t *epic, void *intf, size_t insize, size_t outsize);
int afk_epic_start_interface(afk_epic_ep_t *epic, void *intf, int expected, size_t insize,
size_t outsize);
int afk_epic_command(afk_epic_ep_t *epic, int channel, u16 sub_type, void *txbuf, size_t txsize,
void *rxbuf, size_t *rxsize);

View file

@ -14,9 +14,11 @@
#include "../types.h"
#include "../utils.h"
#define DCP_DPAV_ENDPOINT 0x24
#define TXBUF_LEN 0x4000
#define RXBUF_LEN 0x4000
#define DCP_DPAV_ENDPOINT 0x24
#define DCP_DPAV_NUM_SERVICES 4
#define TXBUF_LEN 0x4000
#define RXBUF_LEN 0x4000
typedef struct dcp_dpav_if {
afk_epic_ep_t *epic;
@ -53,7 +55,8 @@ dcp_dpav_if_t *dcp_dpav_init(dcp_dev_t *dcp)
goto err_free;
}
int err = afk_epic_start_interface(dpav->epic, dpav, TXBUF_LEN, RXBUF_LEN);
int err =
afk_epic_start_interface(dpav->epic, dpav, DCP_DPAV_NUM_SERVICES, TXBUF_LEN, RXBUF_LEN);
if (err < 0) {
printf("dpav: failed to initialize DPAV interface\n");
goto err_shutdown;

View file

@ -13,9 +13,11 @@
#include "../types.h"
#include "../utils.h"
#define DCP_DPTX_PORT_ENDPOINT 0x2a
#define TXBUF_LEN 0x4000
#define RXBUF_LEN 0x4000
#define DCP_DPTX_PORT_ENDPOINT 0x2a
#define DCP_DPTX_PORT_NUM_SERVICES 2
#define TXBUF_LEN 0x4000
#define RXBUF_LEN 0x4000
struct dcpdptx_connection_cmd {
u32 unk;
@ -557,7 +559,8 @@ dcp_dptx_if_t *dcp_dptx_init(dcp_dev_t *dcp)
goto err_free;
}
int err = afk_epic_start_interface(dptx->epic, dptx, TXBUF_LEN, RXBUF_LEN);
int err = afk_epic_start_interface(dptx->epic, dptx, DCP_DPTX_PORT_NUM_SERVICES, TXBUF_LEN,
RXBUF_LEN);
if (err < 0) {
printf("dcp-dptx: failed to initialize DPTXRemotePort interface\n");
goto err_shutdown;

View file

@ -14,9 +14,11 @@
#include "../types.h"
#include "../utils.h"
#define DCP_SYSTEM_ENDPOINT 0x20
#define TXBUF_LEN 0x4000
#define RXBUF_LEN 0x4000
#define DCP_SYSTEM_ENDPOINT 0x20
#define DCP_SYSTEM_NUM_SERVICES 2
#define TXBUF_LEN 0x4000
#define RXBUF_LEN 0x4000
typedef struct dcp_system_if {
afk_epic_ep_t *epic;
@ -121,7 +123,8 @@ dcp_system_if_t *dcp_system_init(dcp_dev_t *dcp)
goto err_free;
}
int err = afk_epic_start_interface(system->epic, system, TXBUF_LEN, RXBUF_LEN);
int err = afk_epic_start_interface(system->epic, system, DCP_SYSTEM_NUM_SERVICES, TXBUF_LEN,
RXBUF_LEN);
if (err < 0 || !system->sys_service) {
printf("dcp-system: failed to initialize system-service\n");

View file

@ -8,7 +8,8 @@
#include "string.h"
#include "utils.h"
#define DCP_IBOOT_ENDPOINT 0x23
#define DCP_IBOOT_ENDPOINT 0x23
#define DCP_IBOOT_NUM_SERVICES 1
#define TXBUF_LEN 0x4000
#define RXBUF_LEN 0x4000
@ -137,7 +138,8 @@ dcp_iboot_if_t *dcp_ib_init(dcp_dev_t *dcp)
goto err_free;
}
int err = afk_epic_start_interface(iboot->epic, iboot, TXBUF_LEN, RXBUF_LEN);
int err =
afk_epic_start_interface(iboot->epic, iboot, DCP_IBOOT_NUM_SERVICES, TXBUF_LEN, RXBUF_LEN);
if (err < 0 || !iboot->enabled) {
printf("dcp-iboot: failed to initialize disp0 service\n");