I'm using hardware surfaces and I get very bad flicker!
When you pass SDL_HWSURFACE to SDL_SetVideoMode(), SDL will try to give you direct access to the video framebuffer. If this succeeds, you're writing directly to visible video memory, and this usually results in flickering. You probably want to use SDL_SWSURFACE and then update dirty rectangles with SDL_UpdateRects(), or SDL_DOUBLEBUF and then update the entire screen with SDL_Flip() which will try to synchronize the update with the vertical retrace.
An excellent article by Bob Pendleton covering SDL hardware surfaces is available at the O'Reilly Network